1 // SPDX-License-Identifier:	GPL-2.0+
2 /*
3  *
4  * Copyright (c) 2015 Free Electrons
5  * Copyright (c) 2015 NextThing Co.
6  * Copyright (c) 2018 Microchip Technology, Inc.
7  *
8  * Maxime Ripard <maxime.ripard@free-electrons.com>
9  * Eugen Hristev <eugen.hristev@microchip.com>
10  *
11  */
12 
13 #include <common.h>
14 #include <dm.h>
15 #include <w1.h>
16 #include <w1-eeprom.h>
17 
18 #include <dm/device-internal.h>
19 
20 int w1_eeprom_read_buf(struct udevice *dev, unsigned int offset,
21 		       u8 *buf, unsigned int count)
22 {
23 	const struct w1_eeprom_ops *ops = device_get_ops(dev);
24 	u64 id = 0;
25 	int ret;
26 
27 	if (!ops->read_buf)
28 		return -ENOSYS;
29 
30 	ret = w1_eeprom_get_id(dev, &id);
31 	if (ret)
32 		return ret;
33 	if (!id)
34 		return -ENODEV;
35 
36 	return ops->read_buf(dev, offset, buf, count);
37 }
38 
39 int w1_eeprom_register_new_device(u64 id)
40 {
41 	u8 family = id & 0xff;
42 	int ret;
43 	struct udevice *dev;
44 
45 	for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev);
46 	     !ret && dev;
47 	     uclass_next_device(&dev)) {
48 		if (ret || !dev) {
49 			debug("cannot find w1 eeprom dev\n");
50 			return ret;
51 		}
52 		if (dev_get_driver_data(dev) == family) {
53 			struct w1_device *w1;
54 
55 			w1 = dev_get_parent_platdata(dev);
56 			if (w1->id) /* device already in use */
57 				continue;
58 			w1->id = id;
59 			debug("%s: Match found: %s:%s %llx\n", __func__,
60 			      dev->name, dev->driver->name, id);
61 			return 0;
62 		}
63 	}
64 
65 	debug("%s: No matches found: error %d\n", __func__, ret);
66 
67 	return ret;
68 }
69 
70 int w1_eeprom_get_id(struct udevice *dev, u64 *id)
71 {
72 	struct w1_device *w1 = dev_get_parent_platdata(dev);
73 
74 	if (!w1)
75 		return -ENODEV;
76 	*id = w1->id;
77 
78 	return 0;
79 }
80 
81 UCLASS_DRIVER(w1_eeprom) = {
82 	.name		= "w1_eeprom",
83 	.id		= UCLASS_W1_EEPROM,
84 	.flags		= DM_UC_FLAG_SEQ_ALIAS,
85 #if CONFIG_IS_ENABLED(OF_CONTROL)
86 	.post_bind	= dm_scan_fdt_dev,
87 #endif
88 };
89 
90 int w1_eeprom_dm_init(void)
91 {
92 	struct udevice *dev;
93 	struct uclass *uc;
94 	int ret;
95 
96 	ret = uclass_get(UCLASS_W1_EEPROM, &uc);
97 	if (ret) {
98 		debug("W1_EEPROM uclass not available\n");
99 		return ret;
100 	}
101 
102 	uclass_foreach_dev(dev, uc) {
103 		ret = device_probe(dev);
104 		if (ret == -ENODEV) {	/* No such device. */
105 			debug("W1_EEPROM not available.\n");
106 			continue;
107 		}
108 
109 		if (ret) {		/* Other error. */
110 			printf("W1_EEPROM probe failed, error %d\n", ret);
111 			continue;
112 		}
113 	}
114 
115 	return 0;
116 }
117