Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
[oweals/u-boot.git] / drivers / i2c / ihs_i2c.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2013
4  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
5  */
6
7 #include <common.h>
8 #include <i2c.h>
9 #ifdef CONFIG_DM_I2C
10 #include <dm.h>
11 #include <regmap.h>
12 #else
13 #include <gdsys_fpga.h>
14 #endif
15 #include <log.h>
16 #include <asm/unaligned.h>
17 #include <linux/bitops.h>
18 #include <linux/delay.h>
19
20 #ifdef CONFIG_DM_I2C
21 struct ihs_i2c_priv {
22         uint speed;
23         struct regmap *map;
24 };
25
26 struct ihs_i2c_regs {
27         u16 interrupt_status;
28         u16 interrupt_enable_control;
29         u16 write_mailbox_ext;
30         u16 write_mailbox;
31         u16 read_mailbox_ext;
32         u16 read_mailbox;
33 };
34
35 #define ihs_i2c_set(map, member, val) \
36         regmap_set(map, struct ihs_i2c_regs, member, val)
37
38 #define ihs_i2c_get(map, member, valp) \
39         regmap_get(map, struct ihs_i2c_regs, member, valp)
40
41 #else /* !CONFIG_DM_I2C */
42 DECLARE_GLOBAL_DATA_PTR;
43
44 #ifdef CONFIG_SYS_I2C_IHS_DUAL
45
46 #define I2C_SET_REG(fld, val) \
47         do { \
48                 if (I2C_ADAP_HWNR & 0x10) \
49                         FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
50                 else \
51                         FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
52         } while (0)
53 #else
54 #define I2C_SET_REG(fld, val) \
55                 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
56 #endif
57
58 #ifdef CONFIG_SYS_I2C_IHS_DUAL
59 #define I2C_GET_REG(fld, val) \
60         do {                                    \
61                 if (I2C_ADAP_HWNR & 0x10) \
62                         FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
63                 else \
64                         FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
65         } while (0)
66 #else
67 #define I2C_GET_REG(fld, val) \
68                 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
69 #endif
70 #endif /* CONFIG_DM_I2C */
71
72 enum {
73         I2CINT_ERROR_EV = BIT(13),
74         I2CINT_TRANSMIT_EV = BIT(14),
75         I2CINT_RECEIVE_EV = BIT(15),
76 };
77
78 enum {
79         I2CMB_READ = 0 << 10,
80         I2CMB_WRITE = 1 << 10,
81         I2CMB_1BYTE = 0 << 11,
82         I2CMB_2BYTE = 1 << 11,
83         I2CMB_DONT_HOLD_BUS = 0 << 13,
84         I2CMB_HOLD_BUS = 1 << 13,
85         I2CMB_NATIVE = 2 << 14,
86 };
87
88 enum {
89         I2COP_WRITE = 0,
90         I2COP_READ = 1,
91 };
92
93 #ifdef CONFIG_DM_I2C
94 static int wait_for_int(struct udevice *dev, int read)
95 #else
96 static int wait_for_int(bool read)
97 #endif
98 {
99         u16 val;
100         uint ctr = 0;
101 #ifdef CONFIG_DM_I2C
102         struct ihs_i2c_priv *priv = dev_get_priv(dev);
103 #endif
104
105 #ifdef CONFIG_DM_I2C
106         ihs_i2c_get(priv->map, interrupt_status, &val);
107 #else
108         I2C_GET_REG(interrupt_status, &val);
109 #endif
110         /* Wait until error or receive/transmit interrupt was raised */
111         while (!(val & (I2CINT_ERROR_EV
112                | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
113                 udelay(10);
114                 if (ctr++ > 5000) {
115                         debug("%s: timed out\n", __func__);
116                         return -ETIMEDOUT;
117                 }
118 #ifdef CONFIG_DM_I2C
119                 ihs_i2c_get(priv->map, interrupt_status, &val);
120 #else
121                 I2C_GET_REG(interrupt_status, &val);
122 #endif
123         }
124
125         return (val & I2CINT_ERROR_EV) ? -EIO : 0;
126 }
127
128 #ifdef CONFIG_DM_I2C
129 static int ihs_i2c_transfer(struct udevice *dev, uchar chip,
130                             uchar *buffer, int len, int read, bool is_last)
131 #else
132 static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
133                             bool is_last)
134 #endif
135 {
136         u16 val;
137         u16 data;
138         int res;
139 #ifdef CONFIG_DM_I2C
140         struct ihs_i2c_priv *priv = dev_get_priv(dev);
141 #endif
142
143         /* Clear interrupt status */
144         data = I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV;
145 #ifdef CONFIG_DM_I2C
146         ihs_i2c_set(priv->map, interrupt_status, data);
147         ihs_i2c_get(priv->map, interrupt_status, &val);
148 #else
149         I2C_SET_REG(interrupt_status, data);
150         I2C_GET_REG(interrupt_status, &val);
151 #endif
152
153         /* If we want to write and have data, write the bytes to the mailbox */
154         if (!read && len) {
155                 val = buffer[0];
156
157                 if (len > 1)
158                         val |= buffer[1] << 8;
159 #ifdef CONFIG_DM_I2C
160                 ihs_i2c_set(priv->map, write_mailbox_ext, val);
161 #else
162                 I2C_SET_REG(write_mailbox_ext, val);
163 #endif
164         }
165
166         data = I2CMB_NATIVE
167                | (read ? 0 : I2CMB_WRITE)
168                | (chip << 1)
169                | ((len > 1) ? I2CMB_2BYTE : 0)
170                | (is_last ? 0 : I2CMB_HOLD_BUS);
171
172 #ifdef CONFIG_DM_I2C
173         ihs_i2c_set(priv->map, write_mailbox, data);
174 #else
175         I2C_SET_REG(write_mailbox, data);
176 #endif
177
178 #ifdef CONFIG_DM_I2C
179         res = wait_for_int(dev, read);
180 #else
181         res = wait_for_int(read);
182 #endif
183         if (res) {
184                 if (res == -ETIMEDOUT)
185                         debug("%s: time out while waiting for event\n", __func__);
186
187                 return res;
188         }
189
190         /* If we want to read, get the bytes from the mailbox */
191         if (read) {
192 #ifdef CONFIG_DM_I2C
193                 ihs_i2c_get(priv->map, read_mailbox_ext, &val);
194 #else
195                 I2C_GET_REG(read_mailbox_ext, &val);
196 #endif
197                 buffer[0] = val & 0xff;
198                 if (len > 1)
199                         buffer[1] = val >> 8;
200         }
201
202         return 0;
203 }
204
205 #ifdef CONFIG_DM_I2C
206 static int ihs_i2c_send_buffer(struct udevice *dev, uchar chip, u8 *data, int len, bool hold_bus, int read)
207 #else
208 static int ihs_i2c_send_buffer(uchar chip, u8 *data, int len, bool hold_bus,
209                                int read)
210 #endif
211 {
212         int res;
213
214         while (len) {
215                 int transfer = min(len, 2);
216                 bool is_last = len <= transfer;
217
218 #ifdef CONFIG_DM_I2C
219                 res = ihs_i2c_transfer(dev, chip, data, transfer, read,
220                                        hold_bus ? false : is_last);
221 #else
222                 res = ihs_i2c_transfer(chip, data, transfer, read,
223                                        hold_bus ? false : is_last);
224 #endif
225                 if (res)
226                         return res;
227
228                 data += transfer;
229                 len -= transfer;
230         }
231
232         return 0;
233 }
234
235 #ifdef CONFIG_DM_I2C
236 static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen,
237                            bool hold_bus)
238 #else
239 static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
240 #endif
241 {
242 #ifdef CONFIG_DM_I2C
243         return ihs_i2c_send_buffer(dev, chip, addr, alen, hold_bus, I2COP_WRITE);
244 #else
245         return ihs_i2c_send_buffer(chip, addr, alen, hold_bus, I2COP_WRITE);
246 #endif
247 }
248
249 #ifdef CONFIG_DM_I2C
250 static int ihs_i2c_access(struct udevice *dev, uchar chip, u8 *addr,
251                           int alen, uchar *buffer, int len, int read)
252 #else
253 static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
254                           int alen, uchar *buffer, int len, int read)
255 #endif
256 {
257         int res;
258
259         /* Don't hold the bus if length of data to send/receive is zero */
260         if (len <= 0)
261                 return -EINVAL;
262
263 #ifdef CONFIG_DM_I2C
264         res = ihs_i2c_address(dev, chip, addr, alen, len);
265 #else
266         res = ihs_i2c_address(chip, addr, alen, len);
267 #endif
268         if (res)
269                 return res;
270
271 #ifdef CONFIG_DM_I2C
272         return ihs_i2c_send_buffer(dev, chip, buffer, len, false, read);
273 #else
274         return ihs_i2c_send_buffer(chip, buffer, len, false, read);
275 #endif
276 }
277
278 #ifdef CONFIG_DM_I2C
279
280 int ihs_i2c_probe(struct udevice *bus)
281 {
282         struct ihs_i2c_priv *priv = dev_get_priv(bus);
283
284         regmap_init_mem(dev_ofnode(bus), &priv->map);
285
286         return 0;
287 }
288
289 static int ihs_i2c_set_bus_speed(struct udevice *bus, uint speed)
290 {
291         struct ihs_i2c_priv *priv = dev_get_priv(bus);
292
293         if (speed != priv->speed && priv->speed != 0)
294                 return -EINVAL;
295
296         priv->speed = speed;
297
298         return 0;
299 }
300
301 static int ihs_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
302 {
303         struct i2c_msg *dmsg, *omsg, dummy;
304
305         memset(&dummy, 0, sizeof(struct i2c_msg));
306
307         /* We expect either two messages (one with an offset and one with the
308          * actucal data) or one message (just data)
309          */
310         if (nmsgs > 2 || nmsgs == 0) {
311                 debug("%s: Only one or two messages are supported\n", __func__);
312                 return -ENOTSUPP;
313         }
314
315         omsg = nmsgs == 1 ? &dummy : msg;
316         dmsg = nmsgs == 1 ? msg : msg + 1;
317
318         if (dmsg->flags & I2C_M_RD)
319                 return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
320                                       omsg->len, dmsg->buf, dmsg->len,
321                                       I2COP_READ);
322         else
323                 return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
324                                       omsg->len, dmsg->buf, dmsg->len,
325                                       I2COP_WRITE);
326 }
327
328 static int ihs_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
329                               u32 chip_flags)
330 {
331         uchar buffer[2];
332         int res;
333
334         res = ihs_i2c_transfer(bus, chip_addr, buffer, 0, I2COP_READ, true);
335         if (res)
336                 return res;
337
338         return 0;
339 }
340
341 static const struct dm_i2c_ops ihs_i2c_ops = {
342         .xfer           = ihs_i2c_xfer,
343         .probe_chip     = ihs_i2c_probe_chip,
344         .set_bus_speed  = ihs_i2c_set_bus_speed,
345 };
346
347 static const struct udevice_id ihs_i2c_ids[] = {
348         { .compatible = "gdsys,ihs_i2cmaster", },
349         { /* sentinel */ }
350 };
351
352 U_BOOT_DRIVER(i2c_ihs) = {
353         .name = "i2c_ihs",
354         .id = UCLASS_I2C,
355         .of_match = ihs_i2c_ids,
356         .probe = ihs_i2c_probe,
357         .priv_auto_alloc_size = sizeof(struct ihs_i2c_priv),
358         .ops = &ihs_i2c_ops,
359 };
360
361 #else /* CONFIG_DM_I2C */
362
363 static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
364 {
365 #ifdef CONFIG_SYS_I2C_INIT_BOARD
366         /*
367          * Call board specific i2c bus reset routine before accessing the
368          * environment, which might be in a chip on that bus. For details
369          * about this problem see doc/I2C_Edge_Conditions.
370          */
371         i2c_init_board();
372 #endif
373 }
374
375 static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
376 {
377         uchar buffer[2];
378         int res;
379
380         res = ihs_i2c_transfer(chip, buffer, 0, I2COP_READ, true);
381         if (res)
382                 return res;
383
384         return 0;
385 }
386
387 static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
388                         int alen, uchar *buffer, int len)
389 {
390         u8 addr_bytes[4];
391
392         put_unaligned_le32(addr, addr_bytes);
393
394         return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
395                               I2COP_READ);
396 }
397
398 static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
399                          int alen, uchar *buffer, int len)
400 {
401         u8 addr_bytes[4];
402
403         put_unaligned_le32(addr, addr_bytes);
404
405         return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
406                               I2COP_WRITE);
407 }
408
409 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
410                                           unsigned int speed)
411 {
412         if (speed != adap->speed)
413                 return -EINVAL;
414         return speed;
415 }
416
417 /*
418  * Register IHS i2c adapters
419  */
420 #ifdef CONFIG_SYS_I2C_IHS_CH0
421 U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe,
422                          ihs_i2c_read, ihs_i2c_write,
423                          ihs_i2c_set_bus_speed,
424                          CONFIG_SYS_I2C_IHS_SPEED_0,
425                          CONFIG_SYS_I2C_IHS_SLAVE_0, 0)
426 #ifdef CONFIG_SYS_I2C_IHS_DUAL
427 U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe,
428                          ihs_i2c_read, ihs_i2c_write,
429                          ihs_i2c_set_bus_speed,
430                          CONFIG_SYS_I2C_IHS_SPEED_0_1,
431                          CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16)
432 #endif
433 #endif
434 #ifdef CONFIG_SYS_I2C_IHS_CH1
435 U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe,
436                          ihs_i2c_read, ihs_i2c_write,
437                          ihs_i2c_set_bus_speed,
438                          CONFIG_SYS_I2C_IHS_SPEED_1,
439                          CONFIG_SYS_I2C_IHS_SLAVE_1, 1)
440 #ifdef CONFIG_SYS_I2C_IHS_DUAL
441 U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe,
442                          ihs_i2c_read, ihs_i2c_write,
443                          ihs_i2c_set_bus_speed,
444                          CONFIG_SYS_I2C_IHS_SPEED_1_1,
445                          CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17)
446 #endif
447 #endif
448 #ifdef CONFIG_SYS_I2C_IHS_CH2
449 U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe,
450                          ihs_i2c_read, ihs_i2c_write,
451                          ihs_i2c_set_bus_speed,
452                          CONFIG_SYS_I2C_IHS_SPEED_2,
453                          CONFIG_SYS_I2C_IHS_SLAVE_2, 2)
454 #ifdef CONFIG_SYS_I2C_IHS_DUAL
455 U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe,
456                          ihs_i2c_read, ihs_i2c_write,
457                          ihs_i2c_set_bus_speed,
458                          CONFIG_SYS_I2C_IHS_SPEED_2_1,
459                          CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18)
460 #endif
461 #endif
462 #ifdef CONFIG_SYS_I2C_IHS_CH3
463 U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe,
464                          ihs_i2c_read, ihs_i2c_write,
465                          ihs_i2c_set_bus_speed,
466                          CONFIG_SYS_I2C_IHS_SPEED_3,
467                          CONFIG_SYS_I2C_IHS_SLAVE_3, 3)
468 #ifdef CONFIG_SYS_I2C_IHS_DUAL
469 U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
470                          ihs_i2c_read, ihs_i2c_write,
471                          ihs_i2c_set_bus_speed,
472                          CONFIG_SYS_I2C_IHS_SPEED_3_1,
473                          CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19)
474 #endif
475 #endif
476 #endif /* CONFIG_DM_I2C */