]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
3dab3e0e | 2 | /* |
b55b8eef NI |
3 | * Copyright (C) 2011, 2013 Renesas Solutions Corp. |
4 | * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <[email protected]> | |
3dab3e0e | 5 | * |
28527096 | 6 | * NOTE: This driver should be converted to driver model before June 2017. |
2799a69e | 7 | * Please see doc/driver-model/i2c-howto.rst for instructions. |
3dab3e0e NI |
8 | */ |
9 | ||
2035d77d | 10 | #include <i2c.h> |
f7ae49fc | 11 | #include <log.h> |
401d1c4f | 12 | #include <asm/global_data.h> |
3dab3e0e | 13 | #include <asm/io.h> |
c05ed00a | 14 | #include <linux/delay.h> |
3dab3e0e | 15 | |
b55b8eef NI |
16 | DECLARE_GLOBAL_DATA_PTR; |
17 | ||
3dab3e0e NI |
18 | /* Every register is 32bit aligned, but only 8bits in size */ |
19 | #define ureg(name) u8 name; u8 __pad_##name##0; u16 __pad_##name##1; | |
20 | struct sh_i2c { | |
21 | ureg(icdr); | |
22 | ureg(iccr); | |
23 | ureg(icsr); | |
24 | ureg(icic); | |
25 | ureg(iccl); | |
26 | ureg(icch); | |
27 | }; | |
28 | #undef ureg | |
29 | ||
3dab3e0e NI |
30 | /* ICCR */ |
31 | #define SH_I2C_ICCR_ICE (1 << 7) | |
32 | #define SH_I2C_ICCR_RACK (1 << 6) | |
33 | #define SH_I2C_ICCR_RTS (1 << 4) | |
34 | #define SH_I2C_ICCR_BUSY (1 << 2) | |
35 | #define SH_I2C_ICCR_SCP (1 << 0) | |
36 | ||
37 | /* ICSR / ICIC */ | |
57d7c804 | 38 | #define SH_IC_BUSY (1 << 4) |
3dab3e0e NI |
39 | #define SH_IC_TACK (1 << 2) |
40 | #define SH_IC_WAIT (1 << 1) | |
41 | #define SH_IC_DTE (1 << 0) | |
42 | ||
b1af67fe TK |
43 | #ifdef CONFIG_SH_I2C_8BIT |
44 | /* store 8th bit of iccl and icch in ICIC register */ | |
45 | #define SH_I2C_ICIC_ICCLB8 (1 << 7) | |
46 | #define SH_I2C_ICIC_ICCHB8 (1 << 6) | |
47 | #endif | |
48 | ||
2035d77d NI |
49 | static const struct sh_i2c *i2c_dev[CONFIG_SYS_I2C_SH_NUM_CONTROLLERS] = { |
50 | (struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE0, | |
51 | #ifdef CONFIG_SYS_I2C_SH_BASE1 | |
52 | (struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE1, | |
53 | #endif | |
54 | #ifdef CONFIG_SYS_I2C_SH_BASE2 | |
55 | (struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE2, | |
56 | #endif | |
57 | #ifdef CONFIG_SYS_I2C_SH_BASE3 | |
58 | (struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE3, | |
59 | #endif | |
60 | #ifdef CONFIG_SYS_I2C_SH_BASE4 | |
61 | (struct sh_i2c *)CONFIG_SYS_I2C_SH_BASE4, | |
62 | #endif | |
63 | }; | |
64 | ||
b1af67fe | 65 | static u16 iccl, icch; |
3dab3e0e NI |
66 | |
67 | #define IRQ_WAIT 1000 | |
68 | ||
2035d77d | 69 | static void sh_irq_dte(struct sh_i2c *dev) |
3dab3e0e NI |
70 | { |
71 | int i; | |
72 | ||
2035d77d NI |
73 | for (i = 0; i < IRQ_WAIT; i++) { |
74 | if (SH_IC_DTE & readb(&dev->icsr)) | |
3dab3e0e NI |
75 | break; |
76 | udelay(10); | |
77 | } | |
78 | } | |
79 | ||
2035d77d | 80 | static int sh_irq_dte_with_tack(struct sh_i2c *dev) |
d042d712 TK |
81 | { |
82 | int i; | |
83 | ||
2035d77d NI |
84 | for (i = 0; i < IRQ_WAIT; i++) { |
85 | if (SH_IC_DTE & readb(&dev->icsr)) | |
d042d712 | 86 | break; |
2035d77d | 87 | if (SH_IC_TACK & readb(&dev->icsr)) |
d042d712 TK |
88 | return -1; |
89 | udelay(10); | |
90 | } | |
91 | return 0; | |
92 | } | |
93 | ||
2035d77d | 94 | static void sh_irq_busy(struct sh_i2c *dev) |
3dab3e0e NI |
95 | { |
96 | int i; | |
97 | ||
2035d77d NI |
98 | for (i = 0; i < IRQ_WAIT; i++) { |
99 | if (!(SH_IC_BUSY & readb(&dev->icsr))) | |
3dab3e0e NI |
100 | break; |
101 | udelay(10); | |
102 | } | |
103 | } | |
104 | ||
2035d77d | 105 | static int sh_i2c_set_addr(struct sh_i2c *dev, u8 chip, u8 addr, int stop) |
3dab3e0e | 106 | { |
d042d712 | 107 | u8 icic = SH_IC_TACK; |
b1af67fe | 108 | |
2035d77d NI |
109 | debug("%s: chip: %x, addr: %x iccl: %x, icch %x\n", |
110 | __func__, chip, addr, iccl, icch); | |
111 | clrbits_8(&dev->iccr, SH_I2C_ICCR_ICE); | |
112 | setbits_8(&dev->iccr, SH_I2C_ICCR_ICE); | |
3dab3e0e | 113 | |
2035d77d NI |
114 | writeb(iccl & 0xff, &dev->iccl); |
115 | writeb(icch & 0xff, &dev->icch); | |
b1af67fe TK |
116 | #ifdef CONFIG_SH_I2C_8BIT |
117 | if (iccl > 0xff) | |
118 | icic |= SH_I2C_ICIC_ICCLB8; | |
119 | if (icch > 0xff) | |
120 | icic |= SH_I2C_ICIC_ICCHB8; | |
121 | #endif | |
2035d77d | 122 | writeb(icic, &dev->icic); |
3dab3e0e | 123 | |
2035d77d NI |
124 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &dev->iccr); |
125 | sh_irq_dte(dev); | |
3dab3e0e | 126 | |
2035d77d NI |
127 | clrbits_8(&dev->icsr, SH_IC_TACK); |
128 | writeb(chip << 1, &dev->icdr); | |
129 | if (sh_irq_dte_with_tack(dev) != 0) | |
d042d712 | 130 | return -1; |
3dab3e0e | 131 | |
2035d77d | 132 | writeb(addr, &dev->icdr); |
3dab3e0e | 133 | if (stop) |
2035d77d | 134 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &dev->iccr); |
3dab3e0e | 135 | |
2035d77d | 136 | if (sh_irq_dte_with_tack(dev) != 0) |
d042d712 TK |
137 | return -1; |
138 | return 0; | |
3dab3e0e NI |
139 | } |
140 | ||
2035d77d | 141 | static void sh_i2c_finish(struct sh_i2c *dev) |
3dab3e0e | 142 | { |
2035d77d NI |
143 | writeb(0, &dev->icsr); |
144 | clrbits_8(&dev->iccr, SH_I2C_ICCR_ICE); | |
3dab3e0e NI |
145 | } |
146 | ||
2035d77d NI |
147 | static int |
148 | sh_i2c_raw_write(struct sh_i2c *dev, u8 chip, uint addr, u8 val) | |
3dab3e0e | 149 | { |
0e5fb33c | 150 | int ret = -1; |
2035d77d | 151 | if (sh_i2c_set_addr(dev, chip, addr, 0) != 0) |
0e5fb33c | 152 | goto exit0; |
3dab3e0e NI |
153 | udelay(10); |
154 | ||
2035d77d NI |
155 | writeb(val, &dev->icdr); |
156 | if (sh_irq_dte_with_tack(dev) != 0) | |
0e5fb33c | 157 | goto exit0; |
3dab3e0e | 158 | |
2035d77d NI |
159 | writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &dev->iccr); |
160 | if (sh_irq_dte_with_tack(dev) != 0) | |
0e5fb33c | 161 | goto exit0; |
2035d77d | 162 | sh_irq_busy(dev); |
0e5fb33c | 163 | ret = 0; |
2035d77d | 164 | |
0e5fb33c | 165 | exit0: |
2035d77d | 166 | sh_i2c_finish(dev); |
0e5fb33c | 167 | return ret; |
3dab3e0e NI |
168 | } |
169 | ||
2035d77d | 170 | static int sh_i2c_raw_read(struct sh_i2c *dev, u8 chip, u8 addr) |
3dab3e0e | 171 | { |
0e5fb33c | 172 | int ret = -1; |
3dab3e0e | 173 | |
2035d77d | 174 | if (sh_i2c_set_addr(dev, chip, addr, 1) != 0) |
0e5fb33c | 175 | goto exit0; |
3dab3e0e NI |
176 | udelay(100); |
177 | ||
2035d77d NI |
178 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &dev->iccr); |
179 | sh_irq_dte(dev); | |
3dab3e0e | 180 | |
2035d77d NI |
181 | writeb(chip << 1 | 0x01, &dev->icdr); |
182 | if (sh_irq_dte_with_tack(dev) != 0) | |
0e5fb33c | 183 | goto exit0; |
3dab3e0e | 184 | |
2035d77d NI |
185 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &dev->iccr); |
186 | if (sh_irq_dte_with_tack(dev) != 0) | |
0e5fb33c | 187 | goto exit0; |
3dab3e0e | 188 | |
2035d77d NI |
189 | ret = readb(&dev->icdr) & 0xff; |
190 | ||
191 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &dev->iccr); | |
192 | readb(&dev->icdr); /* Dummy read */ | |
193 | sh_irq_busy(dev); | |
3dab3e0e | 194 | |
0e5fb33c | 195 | exit0: |
2035d77d | 196 | sh_i2c_finish(dev); |
3dab3e0e NI |
197 | |
198 | return ret; | |
199 | } | |
200 | ||
2035d77d NI |
201 | static void |
202 | sh_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) | |
3dab3e0e NI |
203 | { |
204 | int num, denom, tmp; | |
205 | ||
b55b8eef NI |
206 | /* No i2c support prior to relocation */ |
207 | if (!(gd->flags & GD_FLG_RELOC)) | |
208 | return; | |
209 | ||
3dab3e0e NI |
210 | /* |
211 | * Calculate the value for iccl. From the data sheet: | |
212 | * iccl = (p-clock / transfer-rate) * (L / (L + H)) | |
213 | * where L and H are the SCL low and high ratio. | |
214 | */ | |
215 | num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_LOW; | |
216 | denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); | |
217 | tmp = num * 10 / denom; | |
218 | if (tmp % 10 >= 5) | |
b1af67fe | 219 | iccl = (u16)((num/denom) + 1); |
3dab3e0e | 220 | else |
b1af67fe | 221 | iccl = (u16)(num/denom); |
3dab3e0e NI |
222 | |
223 | /* Calculate the value for icch. From the data sheet: | |
224 | icch = (p clock / transfer rate) * (H / (L + H)) */ | |
225 | num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; | |
226 | tmp = num * 10 / denom; | |
227 | if (tmp % 10 >= 5) | |
b1af67fe | 228 | icch = (u16)((num/denom) + 1); |
3dab3e0e | 229 | else |
b1af67fe | 230 | icch = (u16)(num/denom); |
2035d77d NI |
231 | |
232 | debug("clock: %d, speed %d, iccl: %x, icch: %x\n", | |
233 | CONFIG_SH_I2C_CLOCK, speed, iccl, icch); | |
3dab3e0e NI |
234 | } |
235 | ||
2035d77d NI |
236 | static int sh_i2c_read(struct i2c_adapter *adap, uint8_t chip, |
237 | uint addr, int alen, u8 *data, int len) | |
3dab3e0e | 238 | { |
2035d77d NI |
239 | int ret, i; |
240 | struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr]; | |
241 | ||
242 | for (i = 0; i < len; i++) { | |
243 | ret = sh_i2c_raw_read(dev, chip, addr + i); | |
0e5fb33c TK |
244 | if (ret < 0) |
245 | return -1; | |
2035d77d NI |
246 | |
247 | data[i] = ret & 0xff; | |
248 | debug("%s: data[%d]: %02x\n", __func__, i, data[i]); | |
0e5fb33c | 249 | } |
2035d77d | 250 | |
3dab3e0e NI |
251 | return 0; |
252 | } | |
253 | ||
2035d77d NI |
254 | static int sh_i2c_write(struct i2c_adapter *adap, uint8_t chip, uint addr, |
255 | int alen, u8 *data, int len) | |
3dab3e0e | 256 | { |
2035d77d NI |
257 | struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr]; |
258 | int i; | |
259 | ||
260 | for (i = 0; i < len; i++) { | |
261 | debug("%s: data[%d]: %02x\n", __func__, i, data[i]); | |
262 | if (sh_i2c_raw_write(dev, chip, addr + i, data[i]) != 0) | |
0e5fb33c | 263 | return -1; |
2035d77d | 264 | } |
3dab3e0e NI |
265 | return 0; |
266 | } | |
267 | ||
2035d77d NI |
268 | static int |
269 | sh_i2c_probe(struct i2c_adapter *adap, u8 dev) | |
3dab3e0e | 270 | { |
7a657689 TK |
271 | u8 dummy[1]; |
272 | ||
273 | return sh_i2c_read(adap, dev, 0, 0, dummy, sizeof dummy); | |
2035d77d | 274 | } |
d042d712 | 275 | |
2035d77d NI |
276 | static unsigned int sh_i2c_set_bus_speed(struct i2c_adapter *adap, |
277 | unsigned int speed) | |
278 | { | |
279 | struct sh_i2c *dev = (struct sh_i2c *)i2c_dev[adap->hwadapnr]; | |
280 | ||
281 | sh_i2c_finish(dev); | |
282 | sh_i2c_init(adap, speed, 0); | |
283 | ||
284 | return 0; | |
3dab3e0e | 285 | } |
2035d77d NI |
286 | |
287 | /* | |
288 | * Register RCAR i2c adapters | |
289 | */ | |
290 | U_BOOT_I2C_ADAP_COMPLETE(sh_0, sh_i2c_init, sh_i2c_probe, sh_i2c_read, | |
6aa07543 | 291 | sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 0) |
2035d77d NI |
292 | #ifdef CONFIG_SYS_I2C_SH_BASE1 |
293 | U_BOOT_I2C_ADAP_COMPLETE(sh_1, sh_i2c_init, sh_i2c_probe, sh_i2c_read, | |
6aa07543 | 294 | sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 1) |
2035d77d NI |
295 | #endif |
296 | #ifdef CONFIG_SYS_I2C_SH_BASE2 | |
297 | U_BOOT_I2C_ADAP_COMPLETE(sh_2, sh_i2c_init, sh_i2c_probe, sh_i2c_read, | |
6aa07543 | 298 | sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 2) |
2035d77d NI |
299 | #endif |
300 | #ifdef CONFIG_SYS_I2C_SH_BASE3 | |
301 | U_BOOT_I2C_ADAP_COMPLETE(sh_3, sh_i2c_init, sh_i2c_probe, sh_i2c_read, | |
6aa07543 | 302 | sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 3) |
2035d77d NI |
303 | #endif |
304 | #ifdef CONFIG_SYS_I2C_SH_BASE4 | |
305 | U_BOOT_I2C_ADAP_COMPLETE(sh_4, sh_i2c_init, sh_i2c_probe, sh_i2c_read, | |
6aa07543 | 306 | sh_i2c_write, sh_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, 0, 4) |
2035d77d | 307 | #endif |