diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2018-09-18 10:35:27 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-09-29 03:22:35 +0300 |
commit | c924ee25aa0e837bf4ae207e9959babe23a372d6 (patch) | |
tree | 96f4a40580f9118f6e25a962c2c44c11251128bb /drivers | |
parent | e1721ba0e68ebe8ef88e375301b53077d66c0448 (diff) | |
download | u-boot-c924ee25aa0e837bf4ae207e9959babe23a372d6.tar.xz |
W1-EEPROM: Add an W1-EEPROM uclass for 1 wire EEPROMs
We might want to access data stored onto one wire EEPROMs.
Create a framework to provide a consistent API.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
[eugen.hristev@microchip.com: reworked patch]
Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/Kconfig | 2 | ||||
-rw-r--r-- | drivers/Makefile | 1 | ||||
-rw-r--r-- | drivers/w1-eeprom/Kconfig | 17 | ||||
-rw-r--r-- | drivers/w1-eeprom/Makefile | 2 | ||||
-rw-r--r-- | drivers/w1-eeprom/w1-eeprom-uclass.c | 116 |
5 files changed, 138 insertions, 0 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 6f91eac8a9..e4396b44c4 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -108,6 +108,8 @@ source "drivers/video/Kconfig" source "drivers/w1/Kconfig" +source "drivers/w1-eeprom/Kconfig" + source "drivers/watchdog/Kconfig" config PHYS_TO_BUS diff --git a/drivers/Makefile b/drivers/Makefile index 4ca07c38a0..1d5905fe73 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -106,6 +106,7 @@ obj-y += soc/ obj-y += thermal/ obj-y += axi/ obj-$(CONFIG_W1) += w1/ +obj-$(CONFIG_W1_EEPROM) += w1-eeprom/ obj-$(CONFIG_MACH_PIC32) += ddr/microchip/ endif diff --git a/drivers/w1-eeprom/Kconfig b/drivers/w1-eeprom/Kconfig new file mode 100644 index 0000000000..d5ddc8076a --- /dev/null +++ b/drivers/w1-eeprom/Kconfig @@ -0,0 +1,17 @@ +# +# EEPROM subsystem configuration +# + +menu "1-wire EEPROM support" + +config W1_EEPROM + bool "Enable support for EEPROMs on 1wire interface" + depends on DM + help + Support for the EEPROMs connected on 1-wire Dallas protocol interface + +if W1_EEPROM + +endif + +endmenu diff --git a/drivers/w1-eeprom/Makefile b/drivers/w1-eeprom/Makefile new file mode 100644 index 0000000000..b72950e968 --- /dev/null +++ b/drivers/w1-eeprom/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_W1_EEPROM) += w1-eeprom-uclass.o + diff --git a/drivers/w1-eeprom/w1-eeprom-uclass.c b/drivers/w1-eeprom/w1-eeprom-uclass.c new file mode 100644 index 0000000000..7b0579344c --- /dev/null +++ b/drivers/w1-eeprom/w1-eeprom-uclass.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * + * Copyright (c) 2015 Free Electrons + * Copyright (c) 2015 NextThing Co. + * Copyright (c) 2018 Microchip Technology, Inc. + * + * Maxime Ripard <maxime.ripard@free-electrons.com> + * Eugen Hristev <eugen.hristev@microchip.com> + * + */ + +#include <common.h> +#include <dm.h> +#include <w1.h> +#include <w1-eeprom.h> + +#include <dm/device-internal.h> + +int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset, + u8 *buf, unsigned int count) +{ + const struct w1_eeprom_ops *ops = device_get_ops(dev); + u64 id = 0; + int ret; + + if (!ops->read_buf) + return -ENOSYS; + + ret = w1_eeprom_get_id(dev, &id); + if (ret) + return ret; + if (!id) + return -ENODEV; + + 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_platdata(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_platdata(dev); + + if (!w1) + return -ENODEV; + *id = w1->id; + + return 0; +} + +UCLASS_DRIVER(w1_eeprom) = { + .name = "w1_eeprom", + .id = UCLASS_W1_EEPROM, + .flags = DM_UC_FLAG_SEQ_ALIAS, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .post_bind = dm_scan_fdt_dev, +#endif +}; + +int w1_eeprom_dm_init(void) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_W1_EEPROM, &uc); + if (ret) { + debug("W1_EEPROM uclass not available\n"); + return ret; + } + + uclass_foreach_dev(dev, uc) { + ret = device_probe(dev); + if (ret == -ENODEV) { /* No such device. */ + debug("W1_EEPROM not available.\n"); + continue; + } + + if (ret) { /* Other error. */ + printf("W1_EEPROM probe failed, error %d\n", ret); + continue; + } + } + + return 0; +} |