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);
* 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>
*
*/
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);
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);
}
}
#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;
};