]>
Commit | Line | Data |
---|---|---|
3dab3e0e NI |
1 | /* |
2 | * Copyright (C) 2011 Renesas Solutions Corp. | |
3 | * Copyright (C) 2011 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
3dab3e0e NI |
6 | */ |
7 | ||
8 | #include <common.h> | |
9 | #include <asm/io.h> | |
10 | ||
11 | /* Every register is 32bit aligned, but only 8bits in size */ | |
12 | #define ureg(name) u8 name; u8 __pad_##name##0; u16 __pad_##name##1; | |
13 | struct sh_i2c { | |
14 | ureg(icdr); | |
15 | ureg(iccr); | |
16 | ureg(icsr); | |
17 | ureg(icic); | |
18 | ureg(iccl); | |
19 | ureg(icch); | |
20 | }; | |
21 | #undef ureg | |
22 | ||
23 | static struct sh_i2c *base; | |
24 | ||
25 | /* ICCR */ | |
26 | #define SH_I2C_ICCR_ICE (1 << 7) | |
27 | #define SH_I2C_ICCR_RACK (1 << 6) | |
28 | #define SH_I2C_ICCR_RTS (1 << 4) | |
29 | #define SH_I2C_ICCR_BUSY (1 << 2) | |
30 | #define SH_I2C_ICCR_SCP (1 << 0) | |
31 | ||
32 | /* ICSR / ICIC */ | |
57d7c804 | 33 | #define SH_IC_BUSY (1 << 4) |
3dab3e0e NI |
34 | #define SH_IC_TACK (1 << 2) |
35 | #define SH_IC_WAIT (1 << 1) | |
36 | #define SH_IC_DTE (1 << 0) | |
37 | ||
b1af67fe TK |
38 | #ifdef CONFIG_SH_I2C_8BIT |
39 | /* store 8th bit of iccl and icch in ICIC register */ | |
40 | #define SH_I2C_ICIC_ICCLB8 (1 << 7) | |
41 | #define SH_I2C_ICIC_ICCHB8 (1 << 6) | |
42 | #endif | |
43 | ||
44 | static u16 iccl, icch; | |
3dab3e0e NI |
45 | |
46 | #define IRQ_WAIT 1000 | |
47 | ||
3dab3e0e NI |
48 | static void irq_dte(struct sh_i2c *base) |
49 | { | |
50 | int i; | |
51 | ||
52 | for (i = 0 ; i < IRQ_WAIT ; i++) { | |
53 | if (SH_IC_DTE & readb(&base->icsr)) | |
54 | break; | |
55 | udelay(10); | |
56 | } | |
57 | } | |
58 | ||
d042d712 TK |
59 | static int irq_dte_with_tack(struct sh_i2c *base) |
60 | { | |
61 | int i; | |
62 | ||
63 | for (i = 0 ; i < IRQ_WAIT ; i++) { | |
64 | if (SH_IC_DTE & readb(&base->icsr)) | |
65 | break; | |
66 | if (SH_IC_TACK & readb(&base->icsr)) | |
67 | return -1; | |
68 | udelay(10); | |
69 | } | |
70 | return 0; | |
71 | } | |
72 | ||
3dab3e0e NI |
73 | static void irq_busy(struct sh_i2c *base) |
74 | { | |
75 | int i; | |
76 | ||
77 | for (i = 0 ; i < IRQ_WAIT ; i++) { | |
78 | if (!(SH_IC_BUSY & readb(&base->icsr))) | |
79 | break; | |
80 | udelay(10); | |
81 | } | |
82 | } | |
83 | ||
d042d712 | 84 | static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop) |
3dab3e0e | 85 | { |
d042d712 | 86 | u8 icic = SH_IC_TACK; |
b1af67fe | 87 | |
f539094f TK |
88 | clrbits_8(&base->iccr, SH_I2C_ICCR_ICE); |
89 | setbits_8(&base->iccr, SH_I2C_ICCR_ICE); | |
3dab3e0e | 90 | |
b1af67fe TK |
91 | writeb(iccl & 0xff, &base->iccl); |
92 | writeb(icch & 0xff, &base->icch); | |
93 | #ifdef CONFIG_SH_I2C_8BIT | |
94 | if (iccl > 0xff) | |
95 | icic |= SH_I2C_ICIC_ICCLB8; | |
96 | if (icch > 0xff) | |
97 | icic |= SH_I2C_ICIC_ICCHB8; | |
98 | #endif | |
99 | writeb(icic, &base->icic); | |
3dab3e0e NI |
100 | |
101 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); | |
102 | irq_dte(base); | |
103 | ||
f539094f | 104 | clrbits_8(&base->icsr, SH_IC_TACK); |
3dab3e0e | 105 | writeb(id << 1, &base->icdr); |
d042d712 TK |
106 | if (irq_dte_with_tack(base) != 0) |
107 | return -1; | |
3dab3e0e NI |
108 | |
109 | writeb(reg, &base->icdr); | |
110 | if (stop) | |
111 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr); | |
112 | ||
d042d712 TK |
113 | if (irq_dte_with_tack(base) != 0) |
114 | return -1; | |
115 | return 0; | |
3dab3e0e NI |
116 | } |
117 | ||
118 | static void i2c_finish(struct sh_i2c *base) | |
119 | { | |
120 | writeb(0, &base->icsr); | |
f539094f | 121 | clrbits_8(&base->iccr, SH_I2C_ICCR_ICE); |
3dab3e0e NI |
122 | } |
123 | ||
0e5fb33c | 124 | static int i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val) |
3dab3e0e | 125 | { |
0e5fb33c TK |
126 | int ret = -1; |
127 | if (i2c_set_addr(base, id, reg, 0) != 0) | |
128 | goto exit0; | |
3dab3e0e NI |
129 | udelay(10); |
130 | ||
131 | writeb(val, &base->icdr); | |
0e5fb33c TK |
132 | if (irq_dte_with_tack(base) != 0) |
133 | goto exit0; | |
3dab3e0e NI |
134 | |
135 | writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr); | |
0e5fb33c TK |
136 | if (irq_dte_with_tack(base) != 0) |
137 | goto exit0; | |
3dab3e0e | 138 | irq_busy(base); |
0e5fb33c TK |
139 | ret = 0; |
140 | exit0: | |
3dab3e0e | 141 | i2c_finish(base); |
0e5fb33c | 142 | return ret; |
3dab3e0e NI |
143 | } |
144 | ||
0e5fb33c | 145 | static int i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) |
3dab3e0e | 146 | { |
0e5fb33c | 147 | int ret = -1; |
3dab3e0e | 148 | |
3ce2703d | 149 | #if defined(CONFIG_SH73A0) |
0e5fb33c TK |
150 | if (i2c_set_addr(base, id, reg, 0) != 0) |
151 | goto exit0; | |
3ce2703d | 152 | #else |
0e5fb33c TK |
153 | if (i2c_set_addr(base, id, reg, 1) != 0) |
154 | goto exit0; | |
3dab3e0e | 155 | udelay(100); |
3ce2703d | 156 | #endif |
3dab3e0e NI |
157 | |
158 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr); | |
159 | irq_dte(base); | |
160 | ||
161 | writeb(id << 1 | 0x01, &base->icdr); | |
0e5fb33c TK |
162 | if (irq_dte_with_tack(base) != 0) |
163 | goto exit0; | |
3dab3e0e NI |
164 | |
165 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr); | |
0e5fb33c TK |
166 | if (irq_dte_with_tack(base) != 0) |
167 | goto exit0; | |
3dab3e0e | 168 | |
0e5fb33c | 169 | ret = readb(&base->icdr) & 0xff; |
3dab3e0e NI |
170 | |
171 | writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr); | |
172 | readb(&base->icdr); /* Dummy read */ | |
173 | irq_busy(base); | |
0e5fb33c | 174 | exit0: |
3dab3e0e NI |
175 | i2c_finish(base); |
176 | ||
177 | return ret; | |
178 | } | |
179 | ||
180 | #ifdef CONFIG_I2C_MULTI_BUS | |
181 | static unsigned int current_bus; | |
182 | ||
183 | /** | |
184 | * i2c_set_bus_num - change active I2C bus | |
185 | * @bus: bus index, zero based | |
186 | * @returns: 0 on success, non-0 on failure | |
187 | */ | |
188 | int i2c_set_bus_num(unsigned int bus) | |
189 | { | |
190 | if ((bus < 0) || (bus >= CONFIG_SYS_MAX_I2C_BUS)) { | |
191 | printf("Bad bus: %d\n", bus); | |
192 | return -1; | |
193 | } | |
194 | ||
195 | switch (bus) { | |
196 | case 0: | |
197 | base = (void *)CONFIG_SH_I2C_BASE0; | |
198 | break; | |
199 | case 1: | |
200 | base = (void *)CONFIG_SH_I2C_BASE1; | |
201 | break; | |
020ec727 TK |
202 | #ifdef CONFIG_SH_I2C_BASE2 |
203 | case 2: | |
204 | base = (void *)CONFIG_SH_I2C_BASE2; | |
205 | break; | |
206 | #endif | |
207 | #ifdef CONFIG_SH_I2C_BASE3 | |
208 | case 3: | |
209 | base = (void *)CONFIG_SH_I2C_BASE3; | |
210 | break; | |
211 | #endif | |
212 | #ifdef CONFIG_SH_I2C_BASE4 | |
213 | case 4: | |
214 | base = (void *)CONFIG_SH_I2C_BASE4; | |
215 | break; | |
216 | #endif | |
3dab3e0e NI |
217 | default: |
218 | return -1; | |
219 | } | |
220 | current_bus = bus; | |
221 | ||
222 | return 0; | |
223 | } | |
224 | ||
225 | /** | |
226 | * i2c_get_bus_num - returns index of active I2C bus | |
227 | */ | |
228 | unsigned int i2c_get_bus_num(void) | |
229 | { | |
230 | return current_bus; | |
231 | } | |
232 | #endif | |
233 | ||
234 | #define SH_I2C_ICCL_CALC(clk, date, t_low, t_high) \ | |
235 | ((clk / rate) * (t_low / t_low + t_high)) | |
236 | #define SH_I2C_ICCH_CALC(clk, date, t_low, t_high) \ | |
237 | ((clk / rate) * (t_high / t_low + t_high)) | |
238 | ||
239 | void i2c_init(int speed, int slaveaddr) | |
240 | { | |
241 | int num, denom, tmp; | |
242 | ||
243 | #ifdef CONFIG_I2C_MULTI_BUS | |
244 | current_bus = 0; | |
245 | #endif | |
246 | base = (struct sh_i2c *)CONFIG_SH_I2C_BASE0; | |
247 | ||
248 | /* | |
249 | * Calculate the value for iccl. From the data sheet: | |
250 | * iccl = (p-clock / transfer-rate) * (L / (L + H)) | |
251 | * where L and H are the SCL low and high ratio. | |
252 | */ | |
253 | num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_LOW; | |
254 | denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW); | |
255 | tmp = num * 10 / denom; | |
256 | if (tmp % 10 >= 5) | |
b1af67fe | 257 | iccl = (u16)((num/denom) + 1); |
3dab3e0e | 258 | else |
b1af67fe | 259 | iccl = (u16)(num/denom); |
3dab3e0e NI |
260 | |
261 | /* Calculate the value for icch. From the data sheet: | |
262 | icch = (p clock / transfer rate) * (H / (L + H)) */ | |
263 | num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH; | |
264 | tmp = num * 10 / denom; | |
265 | if (tmp % 10 >= 5) | |
b1af67fe | 266 | icch = (u16)((num/denom) + 1); |
3dab3e0e | 267 | else |
b1af67fe | 268 | icch = (u16)(num/denom); |
3dab3e0e NI |
269 | } |
270 | ||
271 | /* | |
272 | * i2c_read: - Read multiple bytes from an i2c device | |
273 | * | |
274 | * The higher level routines take into account that this function is only | |
275 | * called with len < page length of the device (see configuration file) | |
276 | * | |
277 | * @chip: address of the chip which is to be read | |
278 | * @addr: i2c data address within the chip | |
279 | * @alen: length of the i2c data address (1..2 bytes) | |
280 | * @buffer: where to write the data | |
281 | * @len: how much byte do we want to read | |
282 | * @return: 0 in case of success | |
283 | */ | |
284 | int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) | |
285 | { | |
0e5fb33c | 286 | int ret; |
3dab3e0e | 287 | int i = 0; |
0e5fb33c TK |
288 | for (i = 0 ; i < len ; i++) { |
289 | ret = i2c_raw_read(base, chip, addr + i); | |
290 | if (ret < 0) | |
291 | return -1; | |
292 | buffer[i] = ret & 0xff; | |
293 | } | |
3dab3e0e NI |
294 | return 0; |
295 | } | |
296 | ||
297 | /* | |
298 | * i2c_write: - Write multiple bytes to an i2c device | |
299 | * | |
300 | * The higher level routines take into account that this function is only | |
301 | * called with len < page length of the device (see configuration file) | |
302 | * | |
303 | * @chip: address of the chip which is to be written | |
304 | * @addr: i2c data address within the chip | |
305 | * @alen: length of the i2c data address (1..2 bytes) | |
306 | * @buffer: where to find the data to be written | |
307 | * @len: how much byte do we want to read | |
308 | * @return: 0 in case of success | |
309 | */ | |
310 | int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) | |
311 | { | |
312 | int i = 0; | |
313 | for (i = 0; i < len ; i++) | |
0e5fb33c TK |
314 | if (i2c_raw_write(base, chip, addr + i, buffer[i]) != 0) |
315 | return -1; | |
3dab3e0e NI |
316 | return 0; |
317 | } | |
318 | ||
319 | /* | |
320 | * i2c_probe: - Test if a chip answers for a given i2c address | |
321 | * | |
322 | * @chip: address of the chip which is searched for | |
323 | * @return: 0 if a chip was found, -1 otherwhise | |
324 | */ | |
325 | int i2c_probe(u8 chip) | |
326 | { | |
d042d712 TK |
327 | int ret; |
328 | ||
329 | ret = i2c_set_addr(base, chip, 0, 1); | |
330 | i2c_finish(base); | |
331 | return ret; | |
3dab3e0e | 332 | } |