xref: /openbmc/u-boot/drivers/i2c/i2c-uclass.c (revision c6202d857ebce5d6c8f0ec1d8d30352195546280)
1*c6202d85SSimon Glass /*
2*c6202d85SSimon Glass  * Copyright (c) 2014 Google, Inc
3*c6202d85SSimon Glass  *
4*c6202d85SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
5*c6202d85SSimon Glass  */
6*c6202d85SSimon Glass 
7*c6202d85SSimon Glass #include <common.h>
8*c6202d85SSimon Glass #include <dm.h>
9*c6202d85SSimon Glass #include <errno.h>
10*c6202d85SSimon Glass #include <fdtdec.h>
11*c6202d85SSimon Glass #include <i2c.h>
12*c6202d85SSimon Glass #include <malloc.h>
13*c6202d85SSimon Glass #include <dm/device-internal.h>
14*c6202d85SSimon Glass #include <dm/lists.h>
15*c6202d85SSimon Glass #include <dm/root.h>
16*c6202d85SSimon Glass 
17*c6202d85SSimon Glass DECLARE_GLOBAL_DATA_PTR;
18*c6202d85SSimon Glass 
19*c6202d85SSimon Glass #define I2C_MAX_OFFSET_LEN	4
20*c6202d85SSimon Glass 
21*c6202d85SSimon Glass /**
22*c6202d85SSimon Glass  * i2c_setup_offset() - Set up a new message with a chip offset
23*c6202d85SSimon Glass  *
24*c6202d85SSimon Glass  * @chip:	Chip to use
25*c6202d85SSimon Glass  * @offset:	Byte offset within chip
26*c6202d85SSimon Glass  * @offset_buf:	Place to put byte offset
27*c6202d85SSimon Glass  * @msg:	Message buffer
28*c6202d85SSimon Glass  * @return 0 if OK, -EADDRNOTAVAIL if the offset length is 0. In that case the
29*c6202d85SSimon Glass  * message is still set up but will not contain an offset.
30*c6202d85SSimon Glass  */
31*c6202d85SSimon Glass static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset,
32*c6202d85SSimon Glass 			    uint8_t offset_buf[], struct i2c_msg *msg)
33*c6202d85SSimon Glass {
34*c6202d85SSimon Glass 	int offset_len;
35*c6202d85SSimon Glass 
36*c6202d85SSimon Glass 	msg->addr = chip->chip_addr;
37*c6202d85SSimon Glass 	msg->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
38*c6202d85SSimon Glass 	msg->len = chip->offset_len;
39*c6202d85SSimon Glass 	msg->buf = offset_buf;
40*c6202d85SSimon Glass 	if (!chip->offset_len)
41*c6202d85SSimon Glass 		return -EADDRNOTAVAIL;
42*c6202d85SSimon Glass 	assert(chip->offset_len <= I2C_MAX_OFFSET_LEN);
43*c6202d85SSimon Glass 	offset_len = chip->offset_len;
44*c6202d85SSimon Glass 	while (offset_len--)
45*c6202d85SSimon Glass 		*offset_buf++ = offset >> (8 * offset_len);
46*c6202d85SSimon Glass 
47*c6202d85SSimon Glass 	return 0;
48*c6202d85SSimon Glass }
49*c6202d85SSimon Glass 
50*c6202d85SSimon Glass static int i2c_read_bytewise(struct udevice *dev, uint offset,
51*c6202d85SSimon Glass 			     uint8_t *buffer, int len)
52*c6202d85SSimon Glass {
53*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
54*c6202d85SSimon Glass 	struct udevice *bus = dev_get_parent(dev);
55*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
56*c6202d85SSimon Glass 	struct i2c_msg msg[2], *ptr;
57*c6202d85SSimon Glass 	uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
58*c6202d85SSimon Glass 	int ret;
59*c6202d85SSimon Glass 	int i;
60*c6202d85SSimon Glass 
61*c6202d85SSimon Glass 	for (i = 0; i < len; i++) {
62*c6202d85SSimon Glass 		if (i2c_setup_offset(chip, offset + i, offset_buf, msg))
63*c6202d85SSimon Glass 			return -EINVAL;
64*c6202d85SSimon Glass 		ptr = msg + 1;
65*c6202d85SSimon Glass 		ptr->addr = chip->chip_addr;
66*c6202d85SSimon Glass 		ptr->flags = msg->flags | I2C_M_RD;
67*c6202d85SSimon Glass 		ptr->len = 1;
68*c6202d85SSimon Glass 		ptr->buf = &buffer[i];
69*c6202d85SSimon Glass 		ptr++;
70*c6202d85SSimon Glass 
71*c6202d85SSimon Glass 		ret = ops->xfer(bus, msg, ptr - msg);
72*c6202d85SSimon Glass 		if (ret)
73*c6202d85SSimon Glass 			return ret;
74*c6202d85SSimon Glass 	}
75*c6202d85SSimon Glass 
76*c6202d85SSimon Glass 	return 0;
77*c6202d85SSimon Glass }
78*c6202d85SSimon Glass 
79*c6202d85SSimon Glass static int i2c_write_bytewise(struct udevice *dev, uint offset,
80*c6202d85SSimon Glass 			     const uint8_t *buffer, int len)
81*c6202d85SSimon Glass {
82*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
83*c6202d85SSimon Glass 	struct udevice *bus = dev_get_parent(dev);
84*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
85*c6202d85SSimon Glass 	struct i2c_msg msg[1];
86*c6202d85SSimon Glass 	uint8_t buf[I2C_MAX_OFFSET_LEN + 1];
87*c6202d85SSimon Glass 	int ret;
88*c6202d85SSimon Glass 	int i;
89*c6202d85SSimon Glass 
90*c6202d85SSimon Glass 	for (i = 0; i < len; i++) {
91*c6202d85SSimon Glass 		if (i2c_setup_offset(chip, offset + i, buf, msg))
92*c6202d85SSimon Glass 			return -EINVAL;
93*c6202d85SSimon Glass 		buf[msg->len++] = buffer[i];
94*c6202d85SSimon Glass 
95*c6202d85SSimon Glass 		ret = ops->xfer(bus, msg, 1);
96*c6202d85SSimon Glass 		if (ret)
97*c6202d85SSimon Glass 			return ret;
98*c6202d85SSimon Glass 	}
99*c6202d85SSimon Glass 
100*c6202d85SSimon Glass 	return 0;
101*c6202d85SSimon Glass }
102*c6202d85SSimon Glass 
103*c6202d85SSimon Glass int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
104*c6202d85SSimon Glass {
105*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
106*c6202d85SSimon Glass 	struct udevice *bus = dev_get_parent(dev);
107*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
108*c6202d85SSimon Glass 	struct i2c_msg msg[2], *ptr;
109*c6202d85SSimon Glass 	uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
110*c6202d85SSimon Glass 	int msg_count;
111*c6202d85SSimon Glass 
112*c6202d85SSimon Glass 	if (!ops->xfer)
113*c6202d85SSimon Glass 		return -ENOSYS;
114*c6202d85SSimon Glass 	if (chip->flags & DM_I2C_CHIP_RD_ADDRESS)
115*c6202d85SSimon Glass 		return i2c_read_bytewise(dev, offset, buffer, len);
116*c6202d85SSimon Glass 	ptr = msg;
117*c6202d85SSimon Glass 	if (!i2c_setup_offset(chip, offset, offset_buf, ptr))
118*c6202d85SSimon Glass 		ptr++;
119*c6202d85SSimon Glass 
120*c6202d85SSimon Glass 	if (len) {
121*c6202d85SSimon Glass 		ptr->addr = chip->chip_addr;
122*c6202d85SSimon Glass 		ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
123*c6202d85SSimon Glass 		ptr->flags |= I2C_M_RD;
124*c6202d85SSimon Glass 		ptr->len = len;
125*c6202d85SSimon Glass 		ptr->buf = buffer;
126*c6202d85SSimon Glass 		ptr++;
127*c6202d85SSimon Glass 	}
128*c6202d85SSimon Glass 	msg_count = ptr - msg;
129*c6202d85SSimon Glass 
130*c6202d85SSimon Glass 	return ops->xfer(bus, msg, msg_count);
131*c6202d85SSimon Glass }
132*c6202d85SSimon Glass 
133*c6202d85SSimon Glass int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len)
134*c6202d85SSimon Glass {
135*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
136*c6202d85SSimon Glass 	struct udevice *bus = dev_get_parent(dev);
137*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
138*c6202d85SSimon Glass 	struct i2c_msg msg[1];
139*c6202d85SSimon Glass 
140*c6202d85SSimon Glass 	if (!ops->xfer)
141*c6202d85SSimon Glass 		return -ENOSYS;
142*c6202d85SSimon Glass 
143*c6202d85SSimon Glass 	if (chip->flags & DM_I2C_CHIP_WR_ADDRESS)
144*c6202d85SSimon Glass 		return i2c_write_bytewise(dev, offset, buffer, len);
145*c6202d85SSimon Glass 	/*
146*c6202d85SSimon Glass 	 * The simple approach would be to send two messages here: one to
147*c6202d85SSimon Glass 	 * set the offset and one to write the bytes. However some drivers
148*c6202d85SSimon Glass 	 * will not be expecting this, and some chips won't like how the
149*c6202d85SSimon Glass 	 * driver presents this on the I2C bus.
150*c6202d85SSimon Glass 	 *
151*c6202d85SSimon Glass 	 * The API does not support separate offset and data. We could extend
152*c6202d85SSimon Glass 	 * it with a flag indicating that there is data in the next message
153*c6202d85SSimon Glass 	 * that needs to be processed in the same transaction. We could
154*c6202d85SSimon Glass 	 * instead add an additional buffer to each message. For now, handle
155*c6202d85SSimon Glass 	 * this in the uclass since it isn't clear what the impact on drivers
156*c6202d85SSimon Glass 	 * would be with this extra complication. Unfortunately this means
157*c6202d85SSimon Glass 	 * copying the message.
158*c6202d85SSimon Glass 	 *
159*c6202d85SSimon Glass 	 * Use the stack for small messages, malloc() for larger ones. We
160*c6202d85SSimon Glass 	 * need to allow space for the offset (up to 4 bytes) and the message
161*c6202d85SSimon Glass 	 * itself.
162*c6202d85SSimon Glass 	 */
163*c6202d85SSimon Glass 	if (len < 64) {
164*c6202d85SSimon Glass 		uint8_t buf[I2C_MAX_OFFSET_LEN + len];
165*c6202d85SSimon Glass 
166*c6202d85SSimon Glass 		i2c_setup_offset(chip, offset, buf, msg);
167*c6202d85SSimon Glass 		msg->len += len;
168*c6202d85SSimon Glass 		memcpy(buf + chip->offset_len, buffer, len);
169*c6202d85SSimon Glass 
170*c6202d85SSimon Glass 		return ops->xfer(bus, msg, 1);
171*c6202d85SSimon Glass 	} else {
172*c6202d85SSimon Glass 		uint8_t *buf;
173*c6202d85SSimon Glass 		int ret;
174*c6202d85SSimon Glass 
175*c6202d85SSimon Glass 		buf = malloc(I2C_MAX_OFFSET_LEN + len);
176*c6202d85SSimon Glass 		if (!buf)
177*c6202d85SSimon Glass 			return -ENOMEM;
178*c6202d85SSimon Glass 		i2c_setup_offset(chip, offset, buf, msg);
179*c6202d85SSimon Glass 		msg->len += len;
180*c6202d85SSimon Glass 		memcpy(buf + chip->offset_len, buffer, len);
181*c6202d85SSimon Glass 
182*c6202d85SSimon Glass 		ret = ops->xfer(bus, msg, 1);
183*c6202d85SSimon Glass 		free(buf);
184*c6202d85SSimon Glass 		return ret;
185*c6202d85SSimon Glass 	}
186*c6202d85SSimon Glass }
187*c6202d85SSimon Glass 
188*c6202d85SSimon Glass /**
189*c6202d85SSimon Glass  * i2c_probe_chip() - probe for a chip on a bus
190*c6202d85SSimon Glass  *
191*c6202d85SSimon Glass  * @bus:	Bus to probe
192*c6202d85SSimon Glass  * @chip_addr:	Chip address to probe
193*c6202d85SSimon Glass  * @flags:	Flags for the chip
194*c6202d85SSimon Glass  * @return 0 if found, -ENOSYS if the driver is invalid, -EREMOTEIO if the chip
195*c6202d85SSimon Glass  * does not respond to probe
196*c6202d85SSimon Glass  */
197*c6202d85SSimon Glass static int i2c_probe_chip(struct udevice *bus, uint chip_addr,
198*c6202d85SSimon Glass 			  enum dm_i2c_chip_flags chip_flags)
199*c6202d85SSimon Glass {
200*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
201*c6202d85SSimon Glass 	struct i2c_msg msg[1];
202*c6202d85SSimon Glass 	int ret;
203*c6202d85SSimon Glass 
204*c6202d85SSimon Glass 	if (ops->probe_chip) {
205*c6202d85SSimon Glass 		ret = ops->probe_chip(bus, chip_addr, chip_flags);
206*c6202d85SSimon Glass 		if (!ret || ret != -ENOSYS)
207*c6202d85SSimon Glass 			return ret;
208*c6202d85SSimon Glass 	}
209*c6202d85SSimon Glass 
210*c6202d85SSimon Glass 	if (!ops->xfer)
211*c6202d85SSimon Glass 		return -ENOSYS;
212*c6202d85SSimon Glass 
213*c6202d85SSimon Glass 	/* Probe with a zero-length message */
214*c6202d85SSimon Glass 	msg->addr = chip_addr;
215*c6202d85SSimon Glass 	msg->flags = chip_flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
216*c6202d85SSimon Glass 	msg->len = 0;
217*c6202d85SSimon Glass 	msg->buf = NULL;
218*c6202d85SSimon Glass 
219*c6202d85SSimon Glass 	return ops->xfer(bus, msg, 1);
220*c6202d85SSimon Glass }
221*c6202d85SSimon Glass 
222*c6202d85SSimon Glass static int i2c_bind_driver(struct udevice *bus, uint chip_addr,
223*c6202d85SSimon Glass 			   struct udevice **devp)
224*c6202d85SSimon Glass {
225*c6202d85SSimon Glass 	struct dm_i2c_chip chip;
226*c6202d85SSimon Glass 	char name[30], *str;
227*c6202d85SSimon Glass 	struct udevice *dev;
228*c6202d85SSimon Glass 	int ret;
229*c6202d85SSimon Glass 
230*c6202d85SSimon Glass 	snprintf(name, sizeof(name), "generic_%x", chip_addr);
231*c6202d85SSimon Glass 	str = strdup(name);
232*c6202d85SSimon Glass 	ret = device_bind_driver(bus, "i2c_generic_chip_drv", str, &dev);
233*c6202d85SSimon Glass 	debug("%s:  device_bind_driver: ret=%d\n", __func__, ret);
234*c6202d85SSimon Glass 	if (ret)
235*c6202d85SSimon Glass 		goto err_bind;
236*c6202d85SSimon Glass 
237*c6202d85SSimon Glass 	/* Tell the device what we know about it */
238*c6202d85SSimon Glass 	memset(&chip, '\0', sizeof(chip));
239*c6202d85SSimon Glass 	chip.chip_addr = chip_addr;
240*c6202d85SSimon Glass 	chip.offset_len = 1;	/* we assume */
241*c6202d85SSimon Glass 	ret = device_probe_child(dev, &chip);
242*c6202d85SSimon Glass 	debug("%s:  device_probe_child: ret=%d\n", __func__, ret);
243*c6202d85SSimon Glass 	if (ret)
244*c6202d85SSimon Glass 		goto err_probe;
245*c6202d85SSimon Glass 
246*c6202d85SSimon Glass 	*devp = dev;
247*c6202d85SSimon Glass 	return 0;
248*c6202d85SSimon Glass 
249*c6202d85SSimon Glass err_probe:
250*c6202d85SSimon Glass 	device_unbind(dev);
251*c6202d85SSimon Glass err_bind:
252*c6202d85SSimon Glass 	free(str);
253*c6202d85SSimon Glass 	return ret;
254*c6202d85SSimon Glass }
255*c6202d85SSimon Glass 
256*c6202d85SSimon Glass int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
257*c6202d85SSimon Glass {
258*c6202d85SSimon Glass 	struct udevice *dev;
259*c6202d85SSimon Glass 
260*c6202d85SSimon Glass 	debug("%s: Searching bus '%s' for address %02x: ", __func__,
261*c6202d85SSimon Glass 	      bus->name, chip_addr);
262*c6202d85SSimon Glass 	for (device_find_first_child(bus, &dev); dev;
263*c6202d85SSimon Glass 			device_find_next_child(&dev)) {
264*c6202d85SSimon Glass 		struct dm_i2c_chip store;
265*c6202d85SSimon Glass 		struct dm_i2c_chip *chip = dev_get_parentdata(dev);
266*c6202d85SSimon Glass 		int ret;
267*c6202d85SSimon Glass 
268*c6202d85SSimon Glass 		if (!chip) {
269*c6202d85SSimon Glass 			chip = &store;
270*c6202d85SSimon Glass 			i2c_chip_ofdata_to_platdata(gd->fdt_blob,
271*c6202d85SSimon Glass 						    dev->of_offset, chip);
272*c6202d85SSimon Glass 		}
273*c6202d85SSimon Glass 		if (chip->chip_addr == chip_addr) {
274*c6202d85SSimon Glass 			ret = device_probe(dev);
275*c6202d85SSimon Glass 			debug("found, ret=%d\n", ret);
276*c6202d85SSimon Glass 			if (ret)
277*c6202d85SSimon Glass 				return ret;
278*c6202d85SSimon Glass 			*devp = dev;
279*c6202d85SSimon Glass 			return 0;
280*c6202d85SSimon Glass 		}
281*c6202d85SSimon Glass 	}
282*c6202d85SSimon Glass 	debug("not found\n");
283*c6202d85SSimon Glass 	return i2c_bind_driver(bus, chip_addr, devp);
284*c6202d85SSimon Glass }
285*c6202d85SSimon Glass 
286*c6202d85SSimon Glass int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
287*c6202d85SSimon Glass {
288*c6202d85SSimon Glass 	struct udevice *bus;
289*c6202d85SSimon Glass 	int ret;
290*c6202d85SSimon Glass 
291*c6202d85SSimon Glass 	ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
292*c6202d85SSimon Glass 	if (ret) {
293*c6202d85SSimon Glass 		debug("Cannot find I2C bus %d\n", busnum);
294*c6202d85SSimon Glass 		return ret;
295*c6202d85SSimon Glass 	}
296*c6202d85SSimon Glass 	ret = i2c_get_chip(bus, chip_addr, devp);
297*c6202d85SSimon Glass 	if (ret) {
298*c6202d85SSimon Glass 		debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
299*c6202d85SSimon Glass 		      busnum);
300*c6202d85SSimon Glass 		return ret;
301*c6202d85SSimon Glass 	}
302*c6202d85SSimon Glass 
303*c6202d85SSimon Glass 	return 0;
304*c6202d85SSimon Glass }
305*c6202d85SSimon Glass 
306*c6202d85SSimon Glass int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
307*c6202d85SSimon Glass 	      struct udevice **devp)
308*c6202d85SSimon Glass {
309*c6202d85SSimon Glass 	int ret;
310*c6202d85SSimon Glass 
311*c6202d85SSimon Glass 	*devp = NULL;
312*c6202d85SSimon Glass 
313*c6202d85SSimon Glass 	/* First probe that chip */
314*c6202d85SSimon Glass 	ret = i2c_probe_chip(bus, chip_addr, chip_flags);
315*c6202d85SSimon Glass 	debug("%s: bus='%s', address %02x, ret=%d\n", __func__, bus->name,
316*c6202d85SSimon Glass 	      chip_addr, ret);
317*c6202d85SSimon Glass 	if (ret)
318*c6202d85SSimon Glass 		return ret;
319*c6202d85SSimon Glass 
320*c6202d85SSimon Glass 	/* The chip was found, see if we have a driver, and probe it */
321*c6202d85SSimon Glass 	ret = i2c_get_chip(bus, chip_addr, devp);
322*c6202d85SSimon Glass 	debug("%s:  i2c_get_chip: ret=%d\n", __func__, ret);
323*c6202d85SSimon Glass 
324*c6202d85SSimon Glass 	return ret;
325*c6202d85SSimon Glass }
326*c6202d85SSimon Glass 
327*c6202d85SSimon Glass int i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
328*c6202d85SSimon Glass {
329*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
330*c6202d85SSimon Glass 	struct dm_i2c_bus *i2c = bus->uclass_priv;
331*c6202d85SSimon Glass 	int ret;
332*c6202d85SSimon Glass 
333*c6202d85SSimon Glass 	/*
334*c6202d85SSimon Glass 	 * If we have a method, call it. If not then the driver probably wants
335*c6202d85SSimon Glass 	 * to deal with speed changes on the next transfer. It can easily read
336*c6202d85SSimon Glass 	 * the current speed from this uclass
337*c6202d85SSimon Glass 	 */
338*c6202d85SSimon Glass 	if (ops->set_bus_speed) {
339*c6202d85SSimon Glass 		ret = ops->set_bus_speed(bus, speed);
340*c6202d85SSimon Glass 		if (ret)
341*c6202d85SSimon Glass 			return ret;
342*c6202d85SSimon Glass 	}
343*c6202d85SSimon Glass 	i2c->speed_hz = speed;
344*c6202d85SSimon Glass 
345*c6202d85SSimon Glass 	return 0;
346*c6202d85SSimon Glass }
347*c6202d85SSimon Glass 
348*c6202d85SSimon Glass /*
349*c6202d85SSimon Glass  * i2c_get_bus_speed:
350*c6202d85SSimon Glass  *
351*c6202d85SSimon Glass  *  Returns speed of selected I2C bus in Hz
352*c6202d85SSimon Glass  */
353*c6202d85SSimon Glass int i2c_get_bus_speed(struct udevice *bus)
354*c6202d85SSimon Glass {
355*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
356*c6202d85SSimon Glass 	struct dm_i2c_bus *i2c = bus->uclass_priv;
357*c6202d85SSimon Glass 
358*c6202d85SSimon Glass 	if (!ops->get_bus_speed)
359*c6202d85SSimon Glass 		return i2c->speed_hz;
360*c6202d85SSimon Glass 
361*c6202d85SSimon Glass 	return ops->get_bus_speed(bus);
362*c6202d85SSimon Glass }
363*c6202d85SSimon Glass 
364*c6202d85SSimon Glass int i2c_set_chip_flags(struct udevice *dev, uint flags)
365*c6202d85SSimon Glass {
366*c6202d85SSimon Glass 	struct udevice *bus = dev->parent;
367*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
368*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
369*c6202d85SSimon Glass 	int ret;
370*c6202d85SSimon Glass 
371*c6202d85SSimon Glass 	if (ops->set_flags) {
372*c6202d85SSimon Glass 		ret = ops->set_flags(dev, flags);
373*c6202d85SSimon Glass 		if (ret)
374*c6202d85SSimon Glass 			return ret;
375*c6202d85SSimon Glass 	}
376*c6202d85SSimon Glass 	chip->flags = flags;
377*c6202d85SSimon Glass 
378*c6202d85SSimon Glass 	return 0;
379*c6202d85SSimon Glass }
380*c6202d85SSimon Glass 
381*c6202d85SSimon Glass int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
382*c6202d85SSimon Glass {
383*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
384*c6202d85SSimon Glass 
385*c6202d85SSimon Glass 	*flagsp = chip->flags;
386*c6202d85SSimon Glass 
387*c6202d85SSimon Glass 	return 0;
388*c6202d85SSimon Glass }
389*c6202d85SSimon Glass 
390*c6202d85SSimon Glass int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
391*c6202d85SSimon Glass {
392*c6202d85SSimon Glass 	struct dm_i2c_chip *chip = dev_get_parentdata(dev);
393*c6202d85SSimon Glass 
394*c6202d85SSimon Glass 	if (offset_len > I2C_MAX_OFFSET_LEN)
395*c6202d85SSimon Glass 		return -EINVAL;
396*c6202d85SSimon Glass 	chip->offset_len = offset_len;
397*c6202d85SSimon Glass 
398*c6202d85SSimon Glass 	return 0;
399*c6202d85SSimon Glass }
400*c6202d85SSimon Glass 
401*c6202d85SSimon Glass int i2c_deblock(struct udevice *bus)
402*c6202d85SSimon Glass {
403*c6202d85SSimon Glass 	struct dm_i2c_ops *ops = i2c_get_ops(bus);
404*c6202d85SSimon Glass 
405*c6202d85SSimon Glass 	/*
406*c6202d85SSimon Glass 	 * We could implement a software deblocking here if we could get
407*c6202d85SSimon Glass 	 * access to the GPIOs used by I2C, and switch them to GPIO mode
408*c6202d85SSimon Glass 	 * and then back to I2C. This is somewhat beyond our powers in
409*c6202d85SSimon Glass 	 * driver model at present, so for now just fail.
410*c6202d85SSimon Glass 	 *
411*c6202d85SSimon Glass 	 * See https://patchwork.ozlabs.org/patch/399040/
412*c6202d85SSimon Glass 	 */
413*c6202d85SSimon Glass 	if (!ops->deblock)
414*c6202d85SSimon Glass 		return -ENOSYS;
415*c6202d85SSimon Glass 
416*c6202d85SSimon Glass 	return ops->deblock(bus);
417*c6202d85SSimon Glass }
418*c6202d85SSimon Glass 
419*c6202d85SSimon Glass int i2c_chip_ofdata_to_platdata(const void *blob, int node,
420*c6202d85SSimon Glass 				struct dm_i2c_chip *chip)
421*c6202d85SSimon Glass {
422*c6202d85SSimon Glass 	chip->offset_len = 1;	/* default */
423*c6202d85SSimon Glass 	chip->flags = 0;
424*c6202d85SSimon Glass 	chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1);
425*c6202d85SSimon Glass 	if (chip->chip_addr == -1) {
426*c6202d85SSimon Glass 		debug("%s: I2C Node '%s' has no 'reg' property\n", __func__,
427*c6202d85SSimon Glass 		      fdt_get_name(blob, node, NULL));
428*c6202d85SSimon Glass 		return -EINVAL;
429*c6202d85SSimon Glass 	}
430*c6202d85SSimon Glass 
431*c6202d85SSimon Glass 	return 0;
432*c6202d85SSimon Glass }
433*c6202d85SSimon Glass 
434*c6202d85SSimon Glass static int i2c_post_probe(struct udevice *dev)
435*c6202d85SSimon Glass {
436*c6202d85SSimon Glass 	struct dm_i2c_bus *i2c = dev->uclass_priv;
437*c6202d85SSimon Glass 
438*c6202d85SSimon Glass 	i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
439*c6202d85SSimon Glass 				     "clock-frequency", 100000);
440*c6202d85SSimon Glass 
441*c6202d85SSimon Glass 	return i2c_set_bus_speed(dev, i2c->speed_hz);
442*c6202d85SSimon Glass }
443*c6202d85SSimon Glass 
444*c6202d85SSimon Glass int i2c_post_bind(struct udevice *dev)
445*c6202d85SSimon Glass {
446*c6202d85SSimon Glass 	/* Scan the bus for devices */
447*c6202d85SSimon Glass 	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
448*c6202d85SSimon Glass }
449*c6202d85SSimon Glass 
450*c6202d85SSimon Glass UCLASS_DRIVER(i2c) = {
451*c6202d85SSimon Glass 	.id		= UCLASS_I2C,
452*c6202d85SSimon Glass 	.name		= "i2c",
453*c6202d85SSimon Glass 	.per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
454*c6202d85SSimon Glass 	.post_bind	= i2c_post_bind,
455*c6202d85SSimon Glass 	.post_probe	= i2c_post_probe,
456*c6202d85SSimon Glass };
457*c6202d85SSimon Glass 
458*c6202d85SSimon Glass UCLASS_DRIVER(i2c_generic) = {
459*c6202d85SSimon Glass 	.id		= UCLASS_I2C_GENERIC,
460*c6202d85SSimon Glass 	.name		= "i2c_generic",
461*c6202d85SSimon Glass };
462*c6202d85SSimon Glass 
463*c6202d85SSimon Glass U_BOOT_DRIVER(i2c_generic_chip_drv) = {
464*c6202d85SSimon Glass 	.name		= "i2c_generic_chip_drv",
465*c6202d85SSimon Glass 	.id		= UCLASS_I2C_GENERIC,
466*c6202d85SSimon Glass };
467