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