1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2014 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <i2c.h>
10 
11 static int cur_busnum __attribute__((section(".data")));
12 
i2c_compat_get_device(uint chip_addr,int alen,struct udevice ** devp)13 static int i2c_compat_get_device(uint chip_addr, int alen,
14 				 struct udevice **devp)
15 {
16 	struct dm_i2c_chip *chip;
17 	int ret;
18 
19 	ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp);
20 	if (ret)
21 		return ret;
22 	chip = dev_get_parent_platdata(*devp);
23 	if (chip->offset_len != alen) {
24 		printf("I2C chip %x: requested alen %d does not match chip offset_len %d\n",
25 		       chip_addr, alen, chip->offset_len);
26 		return -EADDRNOTAVAIL;
27 	}
28 
29 	return 0;
30 }
31 
i2c_probe(uint8_t chip_addr)32 int i2c_probe(uint8_t chip_addr)
33 {
34 	struct udevice *bus, *dev;
35 	int ret;
36 
37 	ret = uclass_get_device_by_seq(UCLASS_I2C, cur_busnum, &bus);
38 	if (ret) {
39 		debug("Cannot find I2C bus %d: err=%d\n", cur_busnum, ret);
40 		return ret;
41 	}
42 
43 	if (!bus)
44 		return -ENOENT;
45 
46 	return dm_i2c_probe(bus, chip_addr, 0, &dev);
47 }
48 
i2c_read(uint8_t chip_addr,unsigned int addr,int alen,uint8_t * buffer,int len)49 int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
50 	     int len)
51 {
52 	struct udevice *dev;
53 	int ret;
54 
55 	ret = i2c_compat_get_device(chip_addr, alen, &dev);
56 	if (ret)
57 		return ret;
58 
59 	return dm_i2c_read(dev, addr, buffer, len);
60 }
61 
i2c_write(uint8_t chip_addr,unsigned int addr,int alen,uint8_t * buffer,int len)62 int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
63 	      int len)
64 {
65 	struct udevice *dev;
66 	int ret;
67 
68 	ret = i2c_compat_get_device(chip_addr, alen, &dev);
69 	if (ret)
70 		return ret;
71 
72 	return dm_i2c_write(dev, addr, buffer, len);
73 }
74 
i2c_get_bus_num_fdt(int node)75 int i2c_get_bus_num_fdt(int node)
76 {
77 	struct udevice *bus;
78 	int ret;
79 
80 	ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus);
81 	if (ret)
82 		return ret;
83 
84 	return bus->seq;
85 }
86 
i2c_get_bus_num(void)87 unsigned int i2c_get_bus_num(void)
88 {
89 	return cur_busnum;
90 }
91 
i2c_set_bus_num(unsigned int bus)92 int i2c_set_bus_num(unsigned int bus)
93 {
94 	cur_busnum = bus;
95 
96 	return 0;
97 }
98 
i2c_init(int speed,int slaveaddr)99 void i2c_init(int speed, int slaveaddr)
100 {
101 	/* Nothing to do here - the init happens through driver model */
102 }
103 
board_i2c_init(const void * blob)104 void board_i2c_init(const void *blob)
105 {
106 	/* Nothing to do here - the init happens through driver model */
107 }
108 
i2c_reg_read(uint8_t chip_addr,uint8_t offset)109 uint8_t i2c_reg_read(uint8_t chip_addr, uint8_t offset)
110 {
111 	struct udevice *dev;
112 	int ret;
113 
114 	ret = i2c_compat_get_device(chip_addr, 1, &dev);
115 	if (ret)
116 		return 0xff;
117 	return dm_i2c_reg_read(dev, offset);
118 }
119 
i2c_reg_write(uint8_t chip_addr,uint8_t offset,uint8_t val)120 void i2c_reg_write(uint8_t chip_addr, uint8_t offset, uint8_t val)
121 {
122 	struct udevice *dev;
123 	int ret;
124 
125 	ret = i2c_compat_get_device(chip_addr, 1, &dev);
126 	if (!ret)
127 		dm_i2c_reg_write(dev, offset, val);
128 }
129