aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/w1-eeprom/ds24xxx.c7
-rw-r--r--drivers/w1-eeprom/ds2502.c6
-rw-r--r--drivers/w1-eeprom/w1-eeprom-uclass.c31
-rw-r--r--drivers/w1/w1-uclass.c76
-rw-r--r--include/w1-eeprom.h2
-rw-r--r--include/w1.h17
6 files changed, 104 insertions, 35 deletions
diff --git a/drivers/w1-eeprom/ds24xxx.c b/drivers/w1-eeprom/ds24xxx.c
index d12fd57..4be378b 100644
--- a/drivers/w1-eeprom/ds24xxx.c
+++ b/drivers/w1-eeprom/ds24xxx.c
@@ -53,3 +53,10 @@ U_BOOT_DRIVER(ds24xxx) = {
.ops = &ds24xxx_ops,
.probe = ds24xxx_probe,
};
+
+u8 family_supported[] = {
+ W1_FAMILY_DS24B33,
+ W1_FAMILY_DS2431,
+};
+
+U_BOOT_W1_DEVICE(ds24xxx, family_supported);
diff --git a/drivers/w1-eeprom/ds2502.c b/drivers/w1-eeprom/ds2502.c
index b3d68d7..a67f5ed 100644
--- a/drivers/w1-eeprom/ds2502.c
+++ b/drivers/w1-eeprom/ds2502.c
@@ -243,3 +243,9 @@ U_BOOT_DRIVER(ds2502) = {
.ops = &ds2502_ops,
.probe = ds2502_probe,
};
+
+u8 family_supported[] = {
+ W1_FAMILY_DS2502,
+};
+
+U_BOOT_W1_DEVICE(ds2502, family_supported);
diff --git a/drivers/w1-eeprom/w1-eeprom-uclass.c b/drivers/w1-eeprom/w1-eeprom-uclass.c
index 97a9d43..7a02af3 100644
--- a/drivers/w1-eeprom/w1-eeprom-uclass.c
+++ b/drivers/w1-eeprom/w1-eeprom-uclass.c
@@ -37,37 +37,6 @@ int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset,
return ops->read_buf(dev, offset, buf, count);
}
-int w1_eeprom_register_new_device(u64 id)
-{
- u8 family = id & 0xff;
- int ret;
- struct udevice *dev;
-
- for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev);
- !ret && dev;
- uclass_next_device(&dev)) {
- if (ret || !dev) {
- debug("cannot find w1 eeprom dev\n");
- return ret;
- }
- if (dev_get_driver_data(dev) == family) {
- struct w1_device *w1;
-
- w1 = dev_get_parent_plat(dev);
- if (w1->id) /* device already in use */
- continue;
- w1->id = id;
- debug("%s: Match found: %s:%s %llx\n", __func__,
- dev->name, dev->driver->name, id);
- return 0;
- }
- }
-
- debug("%s: No matches found: error %d\n", __func__, ret);
-
- return ret;
-}
-
int w1_eeprom_get_id(struct udevice *dev, u64 *id)
{
struct w1_device *w1 = dev_get_parent_plat(dev);
diff --git a/drivers/w1/w1-uclass.c b/drivers/w1/w1-uclass.c
index 8bc6cb1..b989273 100644
--- a/drivers/w1/w1-uclass.c
+++ b/drivers/w1/w1-uclass.c
@@ -4,9 +4,11 @@
* Copyright (c) 2015 Free Electrons
* Copyright (c) 2015 NextThing Co.
* Copyright (c) 2018 Microchip Technology, Inc.
+ * Copyright (c) 2021 Bootlin
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
* Eugen Hristev <eugen.hristev@microchip.com>
+ * Kory Maincent <kory.maincent@bootlin.com>
*
*/
@@ -26,6 +28,76 @@ struct w1_bus {
u64 search_id;
};
+int w1_bus_find_dev(const struct udevice *bus, u64 id, struct udevice
+**devp)
+{
+ struct udevice *dev;
+ u8 family = id & 0xff;
+ int ret;
+
+ for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev);
+ !ret && dev;
+ uclass_next_device(&dev)) {
+ if (ret || !dev) {
+ debug("cannot find w1 eeprom dev\n");
+ return -ENODEV;
+ }
+
+ if (dev_get_driver_data(dev) == family) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+int w1_register_new_device(u64 id, struct udevice *bus)
+{
+ u8 family = id & 0xff;
+ int n_ents, ret = 0;
+ struct udevice *dev;
+
+ struct w1_driver_entry *start, *entry;
+
+ start = ll_entry_start(struct w1_driver_entry, w1_driver_entry);
+ n_ents = ll_entry_count(struct w1_driver_entry, w1_driver_entry);
+
+ for (entry = start; entry != start + n_ents; entry++) {
+ const u8 *match_family;
+ const struct driver *drv;
+ struct w1_device *w1;
+
+ for (match_family = entry->family; match_family;
+ match_family++) {
+ if (*match_family != family)
+ continue;
+
+ ret = w1_bus_find_dev(bus, id, &dev);
+
+ /* If nothing in the device tree, bind a device */
+ if (ret == -ENODEV) {
+ drv = entry->driver;
+ ret = device_bind(bus, drv, drv->name,
+ NULL, ofnode_null(), &dev);
+ if (ret)
+ return ret;
+ }
+
+ device_probe(dev);
+
+ w1 = dev_get_parent_plat(dev);
+ w1->id = id;
+
+ return 0;
+ }
+ }
+
+ debug("%s: No matches found: error %d\n", __func__, ret);
+
+ return ret;
+}
+
static int w1_enumerate(struct udevice *bus)
{
const struct w1_ops *ops = device_get_ops(bus);
@@ -97,8 +169,8 @@ static int w1_enumerate(struct udevice *bus)
debug("%s: Detected new device 0x%llx (family 0x%x)\n",
bus->name, rn, (u8)(rn & 0xff));
- /* attempt to register as w1-eeprom device */
- w1_eeprom_register_new_device(rn);
+ /* attempt to register as w1 device */
+ w1_register_new_device(rn, bus);
}
}
diff --git a/include/w1-eeprom.h b/include/w1-eeprom.h
index 2233736..b3cf77a 100644
--- a/include/w1-eeprom.h
+++ b/include/w1-eeprom.h
@@ -27,7 +27,5 @@ int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset,
int w1_eeprom_dm_init(void);
-int w1_eeprom_register_new_device(u64 id);
-
int w1_eeprom_get_id(struct udevice *dev, u64 *id);
#endif
diff --git a/include/w1.h b/include/w1.h
index 77f439e..b18078b 100644
--- a/include/w1.h
+++ b/include/w1.h
@@ -15,6 +15,23 @@ struct udevice;
#define W1_FAMILY_DS2502 0x09
#define W1_FAMILY_EEP_SANDBOX 0xfe
+struct w1_driver_entry {
+ struct driver *driver;
+ u8 *family;
+};
+
+/* U_BOOT_W1_DEVICE() tells U-Boot to create a one-wire device.
+ *
+ * @__name: Device name (C identifier, not a string. E.g. gpio7_at_ff7e0000)
+ * @__driver: Driver name (C identifier, not a string. E.g. gpio7_at_ff7e0000)
+ * @__family: Family code number of the one-wire
+ */
+#define U_BOOT_W1_DEVICE(__name, __family) \
+ ll_entry_declare(struct w1_driver_entry, __name, w1_driver_entry) = { \
+ .driver = llsym(struct driver, __name, driver), \
+ .family = __family, \
+ }
+
struct w1_device {
u64 id;
};