Merge branch 'master' of git://git.denx.de/u-boot-net
[oweals/u-boot.git] / drivers / i2c / s3c24x0_i2c.c
1 /*
2  * (C) Copyright 2002
3  * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 /* This code should work for both the S3C2400 and the S3C2410
9  * as they seem to have the same I2C controller inside.
10  * The different address mapping is handled by the s3c24xx.h files below.
11  */
12 #include <common.h>
13 #include <errno.h>
14 #include <dm.h>
15 #include <fdtdec.h>
16 #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
17 #include <asm/arch/clk.h>
18 #include <asm/arch/cpu.h>
19 #include <asm/arch/pinmux.h>
20 #else
21 #include <asm/arch/s3c24x0_cpu.h>
22 #endif
23 #include <asm/io.h>
24 #include <i2c.h>
25 #include "s3c24x0_i2c.h"
26
27 #ifndef CONFIG_SYS_I2C_S3C24X0_SLAVE
28 #define SYS_I2C_S3C24X0_SLAVE_ADDR      0
29 #else
30 #define SYS_I2C_S3C24X0_SLAVE_ADDR      CONFIG_SYS_I2C_S3C24X0_SLAVE
31 #endif
32
33 DECLARE_GLOBAL_DATA_PTR;
34
35 /*
36  * Wait til the byte transfer is completed.
37  *
38  * @param i2c- pointer to the appropriate i2c register bank.
39  * @return I2C_OK, if transmission was ACKED
40  *         I2C_NACK, if transmission was NACKED
41  *         I2C_NOK_TIMEOUT, if transaction did not complete in I2C_TIMEOUT_MS
42  */
43
44 static int WaitForXfer(struct s3c24x0_i2c *i2c)
45 {
46         ulong start_time = get_timer(0);
47
48         do {
49                 if (readl(&i2c->iiccon) & I2CCON_IRPND)
50                         return (readl(&i2c->iicstat) & I2CSTAT_NACK) ?
51                                 I2C_NACK : I2C_OK;
52         } while (get_timer(start_time) < I2C_TIMEOUT_MS);
53
54         return I2C_NOK_TOUT;
55 }
56
57 static void read_write_byte(struct s3c24x0_i2c *i2c)
58 {
59         clrbits_le32(&i2c->iiccon, I2CCON_IRPND);
60 }
61
62 static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
63 {
64         ulong freq, pres = 16, div;
65 #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
66         freq = get_i2c_clk();
67 #else
68         freq = get_PCLK();
69 #endif
70         /* calculate prescaler and divisor values */
71         if ((freq / pres / (16 + 1)) > speed)
72                 /* set prescaler to 512 */
73                 pres = 512;
74
75         div = 0;
76         while ((freq / pres / (div + 1)) > speed)
77                 div++;
78
79         /* set prescaler, divisor according to freq, also set ACKGEN, IRQ */
80         writel((div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0), &i2c->iiccon);
81
82         /* init to SLAVE REVEIVE and set slaveaddr */
83         writel(0, &i2c->iicstat);
84         writel(slaveadd, &i2c->iicadd);
85         /* program Master Transmit (and implicit STOP) */
86         writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);
87 }
88
89 static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
90 {
91         struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
92
93         i2c_bus->clock_frequency = speed;
94
95         i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
96                     SYS_I2C_S3C24X0_SLAVE_ADDR);
97
98         return 0;
99 }
100
101 /*
102  * cmd_type is 0 for write, 1 for read.
103  *
104  * addr_len can take any value from 0-255, it is only limited
105  * by the char, we could make it larger if needed. If it is
106  * 0 we skip the address write cycle.
107  */
108 static int i2c_transfer(struct s3c24x0_i2c *i2c,
109                         unsigned char cmd_type,
110                         unsigned char chip,
111                         unsigned char addr[],
112                         unsigned char addr_len,
113                         unsigned char data[],
114                         unsigned short data_len)
115 {
116         int i = 0, result;
117         ulong start_time = get_timer(0);
118
119         if (data == 0 || data_len == 0) {
120                 /*Don't support data transfer of no length or to address 0 */
121                 debug("i2c_transfer: bad call\n");
122                 return I2C_NOK;
123         }
124
125         while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
126                 if (get_timer(start_time) > I2C_TIMEOUT_MS)
127                         return I2C_NOK_TOUT;
128         }
129
130         writel(readl(&i2c->iiccon) | I2CCON_ACKGEN, &i2c->iiccon);
131
132         /* Get the slave chip address going */
133         writel(chip, &i2c->iicds);
134         if ((cmd_type == I2C_WRITE) || (addr && addr_len))
135                 writel(I2C_MODE_MT | I2C_TXRX_ENA | I2C_START_STOP,
136                        &i2c->iicstat);
137         else
138                 writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
139                        &i2c->iicstat);
140
141         /* Wait for chip address to transmit. */
142         result = WaitForXfer(i2c);
143         if (result != I2C_OK)
144                 goto bailout;
145
146         /* If register address needs to be transmitted - do it now. */
147         if (addr && addr_len) {
148                 while ((i < addr_len) && (result == I2C_OK)) {
149                         writel(addr[i++], &i2c->iicds);
150                         read_write_byte(i2c);
151                         result = WaitForXfer(i2c);
152                 }
153                 i = 0;
154                 if (result != I2C_OK)
155                         goto bailout;
156         }
157
158         switch (cmd_type) {
159         case I2C_WRITE:
160                 while ((i < data_len) && (result == I2C_OK)) {
161                         writel(data[i++], &i2c->iicds);
162                         read_write_byte(i2c);
163                         result = WaitForXfer(i2c);
164                 }
165                 break;
166
167         case I2C_READ:
168                 if (addr && addr_len) {
169                         /*
170                          * Register address has been sent, now send slave chip
171                          * address again to start the actual read transaction.
172                          */
173                         writel(chip, &i2c->iicds);
174
175                         /* Generate a re-START. */
176                         writel(I2C_MODE_MR | I2C_TXRX_ENA | I2C_START_STOP,
177                                 &i2c->iicstat);
178                         read_write_byte(i2c);
179                         result = WaitForXfer(i2c);
180
181                         if (result != I2C_OK)
182                                 goto bailout;
183                 }
184
185                 while ((i < data_len) && (result == I2C_OK)) {
186                         /* disable ACK for final READ */
187                         if (i == data_len - 1)
188                                 writel(readl(&i2c->iiccon)
189                                        & ~I2CCON_ACKGEN,
190                                        &i2c->iiccon);
191                         read_write_byte(i2c);
192                         result = WaitForXfer(i2c);
193                         data[i++] = readl(&i2c->iicds);
194                 }
195                 if (result == I2C_NACK)
196                         result = I2C_OK; /* Normal terminated read. */
197                 break;
198
199         default:
200                 debug("i2c_transfer: bad call\n");
201                 result = I2C_NOK;
202                 break;
203         }
204
205 bailout:
206         /* Send STOP. */
207         writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
208         read_write_byte(i2c);
209
210         return result;
211 }
212
213 static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
214 {
215         struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
216         uchar buf[1];
217         int ret;
218
219         buf[0] = 0;
220
221         /*
222          * What is needed is to send the chip address and verify that the
223          * address was <ACK>ed (i.e. there was a chip at that address which
224          * drove the data line low).
225          */
226         ret = i2c_transfer(i2c_bus->regs, I2C_READ, chip << 1, 0, 0, buf, 1);
227
228         return ret != I2C_OK;
229 }
230
231 static int s3c24x0_do_msg(struct s3c24x0_i2c_bus *i2c_bus, struct i2c_msg *msg,
232                           int seq)
233 {
234         struct s3c24x0_i2c *i2c = i2c_bus->regs;
235         bool is_read = msg->flags & I2C_M_RD;
236         uint status;
237         uint addr;
238         int ret, i;
239
240         if (!seq)
241                 setbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
242
243         /* Get the slave chip address going */
244         addr = msg->addr << 1;
245         writel(addr, &i2c->iicds);
246         status = I2C_TXRX_ENA | I2C_START_STOP;
247         if (is_read)
248                 status |= I2C_MODE_MR;
249         else
250                 status |= I2C_MODE_MT;
251         writel(status, &i2c->iicstat);
252         if (seq)
253                 read_write_byte(i2c);
254
255         /* Wait for chip address to transmit */
256         ret = WaitForXfer(i2c);
257         if (ret)
258                 goto err;
259
260         if (is_read) {
261                 for (i = 0; !ret && i < msg->len; i++) {
262                         /* disable ACK for final READ */
263                         if (i == msg->len - 1)
264                                 clrbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
265                         read_write_byte(i2c);
266                         ret = WaitForXfer(i2c);
267                         msg->buf[i] = readl(&i2c->iicds);
268                 }
269                 if (ret == I2C_NACK)
270                         ret = I2C_OK; /* Normal terminated read */
271         } else {
272                 for (i = 0; !ret && i < msg->len; i++) {
273                         writel(msg->buf[i], &i2c->iicds);
274                         read_write_byte(i2c);
275                         ret = WaitForXfer(i2c);
276                 }
277         }
278
279 err:
280         return ret;
281 }
282
283 static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
284                             int nmsgs)
285 {
286         struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
287         struct s3c24x0_i2c *i2c = i2c_bus->regs;
288         ulong start_time;
289         int ret, i;
290
291         start_time = get_timer(0);
292         while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
293                 if (get_timer(start_time) > I2C_TIMEOUT_MS) {
294                         debug("Timeout\n");
295                         return -ETIMEDOUT;
296                 }
297         }
298
299         for (ret = 0, i = 0; !ret && i < nmsgs; i++)
300                 ret = s3c24x0_do_msg(i2c_bus, &msg[i], i);
301
302         /* Send STOP */
303         writel(I2C_MODE_MR | I2C_TXRX_ENA, &i2c->iicstat);
304         read_write_byte(i2c);
305
306         return ret ? -EREMOTEIO : 0;
307 }
308
309 static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
310 {
311         const void *blob = gd->fdt_blob;
312         struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
313         int node;
314
315         node = dev_of_offset(dev);
316
317         i2c_bus->regs = (struct s3c24x0_i2c *)dev_get_addr(dev);
318
319         i2c_bus->id = pinmux_decode_periph_id(blob, node);
320
321         i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
322                                                   "clock-frequency", 100000);
323         i2c_bus->node = node;
324         i2c_bus->bus_num = dev->seq;
325
326         exynos_pinmux_config(i2c_bus->id, 0);
327
328         i2c_bus->active = true;
329
330         return 0;
331 }
332
333 static const struct dm_i2c_ops s3c_i2c_ops = {
334         .xfer           = s3c24x0_i2c_xfer,
335         .probe_chip     = s3c24x0_i2c_probe,
336         .set_bus_speed  = s3c24x0_i2c_set_bus_speed,
337 };
338
339 static const struct udevice_id s3c_i2c_ids[] = {
340         { .compatible = "samsung,s3c2440-i2c" },
341         { }
342 };
343
344 U_BOOT_DRIVER(i2c_s3c) = {
345         .name   = "i2c_s3c",
346         .id     = UCLASS_I2C,
347         .of_match = s3c_i2c_ids,
348         .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
349         .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
350         .ops    = &s3c_i2c_ops,
351 };