15e862b95SAlbert ARIBAUD \(3ADEV\) /*
25e862b95SAlbert ARIBAUD \(3ADEV\) * LPC32xx I2C interface driver
35e862b95SAlbert ARIBAUD \(3ADEV\) *
41933af15SSylvain Lemieux * (C) Copyright 2014-2015 DENX Software Engineering GmbH
55e862b95SAlbert ARIBAUD \(3ADEV\) * Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr>
65e862b95SAlbert ARIBAUD \(3ADEV\) *
75e862b95SAlbert ARIBAUD \(3ADEV\) * SPDX-License-Identifier: GPL-2.0+
85e862b95SAlbert ARIBAUD \(3ADEV\) */
95e862b95SAlbert ARIBAUD \(3ADEV\)
105e862b95SAlbert ARIBAUD \(3ADEV\) #include <common.h>
115e862b95SAlbert ARIBAUD \(3ADEV\) #include <asm/io.h>
125e862b95SAlbert ARIBAUD \(3ADEV\) #include <i2c.h>
131221ce45SMasahiro Yamada #include <linux/errno.h>
145e862b95SAlbert ARIBAUD \(3ADEV\) #include <asm/arch/clk.h>
15fb057880SLiam Beguin #include <asm/arch/i2c.h>
16d61c7adbSLiam Beguin #include <dm.h>
17d61c7adbSLiam Beguin #include <mapmem.h>
185e862b95SAlbert ARIBAUD \(3ADEV\)
195e862b95SAlbert ARIBAUD \(3ADEV\) /*
205e862b95SAlbert ARIBAUD \(3ADEV\) * Provide default speed and slave if target did not
215e862b95SAlbert ARIBAUD \(3ADEV\) */
225e862b95SAlbert ARIBAUD \(3ADEV\)
235e862b95SAlbert ARIBAUD \(3ADEV\) #if !defined(CONFIG_SYS_I2C_LPC32XX_SPEED)
245e862b95SAlbert ARIBAUD \(3ADEV\) #define CONFIG_SYS_I2C_LPC32XX_SPEED 350000
255e862b95SAlbert ARIBAUD \(3ADEV\) #endif
265e862b95SAlbert ARIBAUD \(3ADEV\)
275e862b95SAlbert ARIBAUD \(3ADEV\) #if !defined(CONFIG_SYS_I2C_LPC32XX_SLAVE)
285e862b95SAlbert ARIBAUD \(3ADEV\) #define CONFIG_SYS_I2C_LPC32XX_SLAVE 0
295e862b95SAlbert ARIBAUD \(3ADEV\) #endif
305e862b95SAlbert ARIBAUD \(3ADEV\)
315e862b95SAlbert ARIBAUD \(3ADEV\) /* TX register fields */
325e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_TX_START 0x00000100
335e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_TX_STOP 0x00000200
345e862b95SAlbert ARIBAUD \(3ADEV\)
355e862b95SAlbert ARIBAUD \(3ADEV\) /* Control register values */
365e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_SOFT_RESET 0x00000100
375e862b95SAlbert ARIBAUD \(3ADEV\)
385e862b95SAlbert ARIBAUD \(3ADEV\) /* Status register values */
395e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_STAT_TFF 0x00000400
405e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_STAT_RFE 0x00000200
415e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_STAT_DRMI 0x00000008
425e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_STAT_NAI 0x00000004
435e862b95SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_I2C_STAT_TDI 0x00000001
445e862b95SAlbert ARIBAUD \(3ADEV\)
45d61c7adbSLiam Beguin #ifndef CONFIG_DM_I2C
46eddac8e9SLiam Beguin static struct lpc32xx_i2c_base *lpc32xx_i2c[] = {
47eddac8e9SLiam Beguin (struct lpc32xx_i2c_base *)I2C1_BASE,
48eddac8e9SLiam Beguin (struct lpc32xx_i2c_base *)I2C2_BASE,
49eddac8e9SLiam Beguin (struct lpc32xx_i2c_base *)(USB_BASE + 0x300)
505e862b95SAlbert ARIBAUD \(3ADEV\) };
51d61c7adbSLiam Beguin #endif
525e862b95SAlbert ARIBAUD \(3ADEV\)
535e862b95SAlbert ARIBAUD \(3ADEV\) /* Set I2C bus speed */
__i2c_set_bus_speed(struct lpc32xx_i2c_base * base,unsigned int speed,unsigned int chip)54eddac8e9SLiam Beguin static unsigned int __i2c_set_bus_speed(struct lpc32xx_i2c_base *base,
55eddac8e9SLiam Beguin unsigned int speed, unsigned int chip)
565e862b95SAlbert ARIBAUD \(3ADEV\) {
575e862b95SAlbert ARIBAUD \(3ADEV\) int half_period;
585e862b95SAlbert ARIBAUD \(3ADEV\)
595e862b95SAlbert ARIBAUD \(3ADEV\) if (speed == 0)
605e862b95SAlbert ARIBAUD \(3ADEV\) return -EINVAL;
615e862b95SAlbert ARIBAUD \(3ADEV\)
62ea16c6a1SVladimir Zapolskiy /* OTG I2C clock source and CLK registers are different */
63eddac8e9SLiam Beguin if (chip == 2) {
64ea16c6a1SVladimir Zapolskiy half_period = (get_periph_clk_rate() / speed) / 2;
65ea16c6a1SVladimir Zapolskiy if (half_period > 0xFF)
665e862b95SAlbert ARIBAUD \(3ADEV\) return -EINVAL;
67ea16c6a1SVladimir Zapolskiy } else {
68ea16c6a1SVladimir Zapolskiy half_period = (get_hclk_clk_rate() / speed) / 2;
69ea16c6a1SVladimir Zapolskiy if (half_period > 0x3FF)
70ea16c6a1SVladimir Zapolskiy return -EINVAL;
71ea16c6a1SVladimir Zapolskiy }
725e862b95SAlbert ARIBAUD \(3ADEV\)
73eddac8e9SLiam Beguin writel(half_period, &base->clk_hi);
74eddac8e9SLiam Beguin writel(half_period, &base->clk_lo);
755e862b95SAlbert ARIBAUD \(3ADEV\) return 0;
765e862b95SAlbert ARIBAUD \(3ADEV\) }
775e862b95SAlbert ARIBAUD \(3ADEV\)
785e862b95SAlbert ARIBAUD \(3ADEV\) /* I2C init called by cmd_i2c when doing 'i2c reset'. */
__i2c_init(struct lpc32xx_i2c_base * base,int requested_speed,int slaveadd,unsigned int chip)79eddac8e9SLiam Beguin static void __i2c_init(struct lpc32xx_i2c_base *base,
80eddac8e9SLiam Beguin int requested_speed, int slaveadd, unsigned int chip)
815e862b95SAlbert ARIBAUD \(3ADEV\) {
825e862b95SAlbert ARIBAUD \(3ADEV\) /* soft reset (auto-clears) */
83eddac8e9SLiam Beguin writel(LPC32XX_I2C_SOFT_RESET, &base->ctrl);
84ea16c6a1SVladimir Zapolskiy /* set HI and LO periods for half of the default speed */
85eddac8e9SLiam Beguin __i2c_set_bus_speed(base, requested_speed, chip);
865e862b95SAlbert ARIBAUD \(3ADEV\) }
875e862b95SAlbert ARIBAUD \(3ADEV\)
885e862b95SAlbert ARIBAUD \(3ADEV\) /* I2C probe called by cmd_i2c when doing 'i2c probe'. */
__i2c_probe_chip(struct lpc32xx_i2c_base * base,u8 dev)89eddac8e9SLiam Beguin static int __i2c_probe_chip(struct lpc32xx_i2c_base *base, u8 dev)
905e862b95SAlbert ARIBAUD \(3ADEV\) {
915e862b95SAlbert ARIBAUD \(3ADEV\) int stat;
925e862b95SAlbert ARIBAUD \(3ADEV\)
935e862b95SAlbert ARIBAUD \(3ADEV\) /* Soft-reset the controller */
94eddac8e9SLiam Beguin writel(LPC32XX_I2C_SOFT_RESET, &base->ctrl);
95eddac8e9SLiam Beguin while (readl(&base->ctrl) & LPC32XX_I2C_SOFT_RESET)
965e862b95SAlbert ARIBAUD \(3ADEV\) ;
975e862b95SAlbert ARIBAUD \(3ADEV\) /* Addre slave for write with start before and stop after */
985e862b95SAlbert ARIBAUD \(3ADEV\) writel((dev<<1) | LPC32XX_I2C_TX_START | LPC32XX_I2C_TX_STOP,
99eddac8e9SLiam Beguin &base->tx);
1005e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for end of transation */
101eddac8e9SLiam Beguin while (!((stat = readl(&base->stat)) & LPC32XX_I2C_STAT_TDI))
1025e862b95SAlbert ARIBAUD \(3ADEV\) ;
1035e862b95SAlbert ARIBAUD \(3ADEV\) /* was there no acknowledge? */
1045e862b95SAlbert ARIBAUD \(3ADEV\) return (stat & LPC32XX_I2C_STAT_NAI) ? -1 : 0;
1055e862b95SAlbert ARIBAUD \(3ADEV\) }
1065e862b95SAlbert ARIBAUD \(3ADEV\)
1075e862b95SAlbert ARIBAUD \(3ADEV\) /*
1085e862b95SAlbert ARIBAUD \(3ADEV\) * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
1095e862b95SAlbert ARIBAUD \(3ADEV\) * Begin write, send address byte(s), begin read, receive data bytes, end.
1105e862b95SAlbert ARIBAUD \(3ADEV\) */
__i2c_read(struct lpc32xx_i2c_base * base,u8 dev,uint addr,int alen,u8 * data,int length)111eddac8e9SLiam Beguin static int __i2c_read(struct lpc32xx_i2c_base *base, u8 dev, uint addr,
1125e862b95SAlbert ARIBAUD \(3ADEV\) int alen, u8 *data, int length)
1135e862b95SAlbert ARIBAUD \(3ADEV\) {
1145e862b95SAlbert ARIBAUD \(3ADEV\) int stat, wlen;
1155e862b95SAlbert ARIBAUD \(3ADEV\)
1165e862b95SAlbert ARIBAUD \(3ADEV\) /* Soft-reset the controller */
117eddac8e9SLiam Beguin writel(LPC32XX_I2C_SOFT_RESET, &base->ctrl);
118eddac8e9SLiam Beguin while (readl(&base->ctrl) & LPC32XX_I2C_SOFT_RESET)
1195e862b95SAlbert ARIBAUD \(3ADEV\) ;
1205e862b95SAlbert ARIBAUD \(3ADEV\) /* do we need to write an address at all? */
1215e862b95SAlbert ARIBAUD \(3ADEV\) if (alen) {
1225e862b95SAlbert ARIBAUD \(3ADEV\) /* Address slave in write mode */
123eddac8e9SLiam Beguin writel((dev<<1) | LPC32XX_I2C_TX_START, &base->tx);
1245e862b95SAlbert ARIBAUD \(3ADEV\) /* write address bytes */
1255e862b95SAlbert ARIBAUD \(3ADEV\) while (alen--) {
1265e862b95SAlbert ARIBAUD \(3ADEV\) /* compute address byte + stop for the last one */
1275e862b95SAlbert ARIBAUD \(3ADEV\) int a = (addr >> (8 * alen)) & 0xff;
1285e862b95SAlbert ARIBAUD \(3ADEV\) if (!alen)
1295e862b95SAlbert ARIBAUD \(3ADEV\) a |= LPC32XX_I2C_TX_STOP;
1305e862b95SAlbert ARIBAUD \(3ADEV\) /* Send address byte */
131eddac8e9SLiam Beguin writel(a, &base->tx);
1325e862b95SAlbert ARIBAUD \(3ADEV\) }
1335e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for end of transation */
134eddac8e9SLiam Beguin while (!((stat = readl(&base->stat)) & LPC32XX_I2C_STAT_TDI))
1355e862b95SAlbert ARIBAUD \(3ADEV\) ;
1365e862b95SAlbert ARIBAUD \(3ADEV\) /* clear end-of-transaction flag */
137eddac8e9SLiam Beguin writel(1, &base->stat);
1385e862b95SAlbert ARIBAUD \(3ADEV\) }
1395e862b95SAlbert ARIBAUD \(3ADEV\) /* do we have to read data at all? */
1405e862b95SAlbert ARIBAUD \(3ADEV\) if (length) {
1415e862b95SAlbert ARIBAUD \(3ADEV\) /* Address slave in read mode */
142eddac8e9SLiam Beguin writel(1 | (dev<<1) | LPC32XX_I2C_TX_START, &base->tx);
1435e862b95SAlbert ARIBAUD \(3ADEV\) wlen = length;
1445e862b95SAlbert ARIBAUD \(3ADEV\) /* get data */
1455e862b95SAlbert ARIBAUD \(3ADEV\) while (length | wlen) {
1465e862b95SAlbert ARIBAUD \(3ADEV\) /* read status for TFF and RFE */
147eddac8e9SLiam Beguin stat = readl(&base->stat);
1485e862b95SAlbert ARIBAUD \(3ADEV\) /* must we, can we write a trigger byte? */
1495e862b95SAlbert ARIBAUD \(3ADEV\) if ((wlen > 0)
1505e862b95SAlbert ARIBAUD \(3ADEV\) & (!(stat & LPC32XX_I2C_STAT_TFF))) {
1515e862b95SAlbert ARIBAUD \(3ADEV\) wlen--;
1525e862b95SAlbert ARIBAUD \(3ADEV\) /* write trigger byte + stop if last */
1535e862b95SAlbert ARIBAUD \(3ADEV\) writel(wlen ? 0 :
154eddac8e9SLiam Beguin LPC32XX_I2C_TX_STOP, &base->tx);
1555e862b95SAlbert ARIBAUD \(3ADEV\) }
1565e862b95SAlbert ARIBAUD \(3ADEV\) /* must we, can we read a data byte? */
1575e862b95SAlbert ARIBAUD \(3ADEV\) if ((length > 0)
1585e862b95SAlbert ARIBAUD \(3ADEV\) & (!(stat & LPC32XX_I2C_STAT_RFE))) {
1595e862b95SAlbert ARIBAUD \(3ADEV\) length--;
1605e862b95SAlbert ARIBAUD \(3ADEV\) /* read byte */
161eddac8e9SLiam Beguin *(data++) = readl(&base->rx);
1625e862b95SAlbert ARIBAUD \(3ADEV\) }
1635e862b95SAlbert ARIBAUD \(3ADEV\) }
1645e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for end of transation */
165eddac8e9SLiam Beguin while (!((stat = readl(&base->stat)) & LPC32XX_I2C_STAT_TDI))
1665e862b95SAlbert ARIBAUD \(3ADEV\) ;
1675e862b95SAlbert ARIBAUD \(3ADEV\) /* clear end-of-transaction flag */
168eddac8e9SLiam Beguin writel(1, &base->stat);
1693d2b6a2eSSylvain Lemieux }
1705e862b95SAlbert ARIBAUD \(3ADEV\) /* success */
1715e862b95SAlbert ARIBAUD \(3ADEV\) return 0;
1725e862b95SAlbert ARIBAUD \(3ADEV\) }
1735e862b95SAlbert ARIBAUD \(3ADEV\)
1745e862b95SAlbert ARIBAUD \(3ADEV\) /*
1755e862b95SAlbert ARIBAUD \(3ADEV\) * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
1765e862b95SAlbert ARIBAUD \(3ADEV\) * Begin write, send address byte(s), send data bytes, end.
1775e862b95SAlbert ARIBAUD \(3ADEV\) */
__i2c_write(struct lpc32xx_i2c_base * base,u8 dev,uint addr,int alen,u8 * data,int length)178eddac8e9SLiam Beguin static int __i2c_write(struct lpc32xx_i2c_base *base, u8 dev, uint addr,
1795e862b95SAlbert ARIBAUD \(3ADEV\) int alen, u8 *data, int length)
1805e862b95SAlbert ARIBAUD \(3ADEV\) {
1815e862b95SAlbert ARIBAUD \(3ADEV\) int stat;
1825e862b95SAlbert ARIBAUD \(3ADEV\)
1835e862b95SAlbert ARIBAUD \(3ADEV\) /* Soft-reset the controller */
184eddac8e9SLiam Beguin writel(LPC32XX_I2C_SOFT_RESET, &base->ctrl);
185eddac8e9SLiam Beguin while (readl(&base->ctrl) & LPC32XX_I2C_SOFT_RESET)
1865e862b95SAlbert ARIBAUD \(3ADEV\) ;
1875e862b95SAlbert ARIBAUD \(3ADEV\) /* do we need to write anything at all? */
1885e862b95SAlbert ARIBAUD \(3ADEV\) if (alen | length)
1895e862b95SAlbert ARIBAUD \(3ADEV\) /* Address slave in write mode */
190eddac8e9SLiam Beguin writel((dev<<1) | LPC32XX_I2C_TX_START, &base->tx);
19158243001SSylvain Lemieux else
19258243001SSylvain Lemieux return 0;
1935e862b95SAlbert ARIBAUD \(3ADEV\) /* write address bytes */
1945e862b95SAlbert ARIBAUD \(3ADEV\) while (alen) {
1955e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for transmit fifo not full */
196eddac8e9SLiam Beguin stat = readl(&base->stat);
1975e862b95SAlbert ARIBAUD \(3ADEV\) if (!(stat & LPC32XX_I2C_STAT_TFF)) {
1985e862b95SAlbert ARIBAUD \(3ADEV\) alen--;
1995e862b95SAlbert ARIBAUD \(3ADEV\) int a = (addr >> (8 * alen)) & 0xff;
2005e862b95SAlbert ARIBAUD \(3ADEV\) if (!(alen | length))
2015e862b95SAlbert ARIBAUD \(3ADEV\) a |= LPC32XX_I2C_TX_STOP;
2025e862b95SAlbert ARIBAUD \(3ADEV\) /* Send address byte */
203eddac8e9SLiam Beguin writel(a, &base->tx);
2045e862b95SAlbert ARIBAUD \(3ADEV\) }
2055e862b95SAlbert ARIBAUD \(3ADEV\) }
2065e862b95SAlbert ARIBAUD \(3ADEV\) while (length) {
2075e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for transmit fifo not full */
208eddac8e9SLiam Beguin stat = readl(&base->stat);
2095e862b95SAlbert ARIBAUD \(3ADEV\) if (!(stat & LPC32XX_I2C_STAT_TFF)) {
2105e862b95SAlbert ARIBAUD \(3ADEV\) /* compute data byte, add stop if length==0 */
2115e862b95SAlbert ARIBAUD \(3ADEV\) length--;
2125e862b95SAlbert ARIBAUD \(3ADEV\) int d = *(data++);
2135e862b95SAlbert ARIBAUD \(3ADEV\) if (!length)
2145e862b95SAlbert ARIBAUD \(3ADEV\) d |= LPC32XX_I2C_TX_STOP;
2155e862b95SAlbert ARIBAUD \(3ADEV\) /* Send data byte */
216eddac8e9SLiam Beguin writel(d, &base->tx);
2175e862b95SAlbert ARIBAUD \(3ADEV\) }
2185e862b95SAlbert ARIBAUD \(3ADEV\) }
2195e862b95SAlbert ARIBAUD \(3ADEV\) /* wait for end of transation */
220eddac8e9SLiam Beguin while (!((stat = readl(&base->stat)) & LPC32XX_I2C_STAT_TDI))
2215e862b95SAlbert ARIBAUD \(3ADEV\) ;
2225e862b95SAlbert ARIBAUD \(3ADEV\) /* clear end-of-transaction flag */
223eddac8e9SLiam Beguin writel(1, &base->stat);
2245e862b95SAlbert ARIBAUD \(3ADEV\) return 0;
2255e862b95SAlbert ARIBAUD \(3ADEV\) }
2265e862b95SAlbert ARIBAUD \(3ADEV\)
227d61c7adbSLiam Beguin #ifndef CONFIG_DM_I2C
lpc32xx_i2c_init(struct i2c_adapter * adap,int requested_speed,int slaveadd)228552531e4SLiam Beguin static void lpc32xx_i2c_init(struct i2c_adapter *adap,
229552531e4SLiam Beguin int requested_speed, int slaveadd)
230552531e4SLiam Beguin {
231eddac8e9SLiam Beguin __i2c_init(lpc32xx_i2c[adap->hwadapnr], requested_speed, slaveadd,
232eddac8e9SLiam Beguin adap->hwadapnr);
233552531e4SLiam Beguin }
234552531e4SLiam Beguin
lpc32xx_i2c_probe_chip(struct i2c_adapter * adap,u8 dev)235552531e4SLiam Beguin static int lpc32xx_i2c_probe_chip(struct i2c_adapter *adap, u8 dev)
236552531e4SLiam Beguin {
237eddac8e9SLiam Beguin return __i2c_probe_chip(lpc32xx_i2c[adap->hwadapnr], dev);
238552531e4SLiam Beguin }
239552531e4SLiam Beguin
lpc32xx_i2c_read(struct i2c_adapter * adap,u8 dev,uint addr,int alen,u8 * data,int length)240552531e4SLiam Beguin static int lpc32xx_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
241552531e4SLiam Beguin int alen, u8 *data, int length)
242552531e4SLiam Beguin {
243eddac8e9SLiam Beguin return __i2c_read(lpc32xx_i2c[adap->hwadapnr], dev, addr,
244eddac8e9SLiam Beguin alen, data, length);
245552531e4SLiam Beguin }
246552531e4SLiam Beguin
lpc32xx_i2c_write(struct i2c_adapter * adap,u8 dev,uint addr,int alen,u8 * data,int length)247552531e4SLiam Beguin static int lpc32xx_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,
248552531e4SLiam Beguin int alen, u8 *data, int length)
249552531e4SLiam Beguin {
250eddac8e9SLiam Beguin return __i2c_write(lpc32xx_i2c[adap->hwadapnr], dev, addr,
251eddac8e9SLiam Beguin alen, data, length);
252552531e4SLiam Beguin }
253552531e4SLiam Beguin
lpc32xx_i2c_set_bus_speed(struct i2c_adapter * adap,unsigned int speed)254552531e4SLiam Beguin static unsigned int lpc32xx_i2c_set_bus_speed(struct i2c_adapter *adap,
255552531e4SLiam Beguin unsigned int speed)
256552531e4SLiam Beguin {
257eddac8e9SLiam Beguin return __i2c_set_bus_speed(lpc32xx_i2c[adap->hwadapnr], speed,
258eddac8e9SLiam Beguin adap->hwadapnr);
259552531e4SLiam Beguin }
260552531e4SLiam Beguin
261552531e4SLiam Beguin U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_0, lpc32xx_i2c_init, lpc32xx_i2c_probe_chip,
2625e862b95SAlbert ARIBAUD \(3ADEV\) lpc32xx_i2c_read, lpc32xx_i2c_write,
2635e862b95SAlbert ARIBAUD \(3ADEV\) lpc32xx_i2c_set_bus_speed,
2645e862b95SAlbert ARIBAUD \(3ADEV\) CONFIG_SYS_I2C_LPC32XX_SPEED,
2655e862b95SAlbert ARIBAUD \(3ADEV\) CONFIG_SYS_I2C_LPC32XX_SLAVE,
2665e862b95SAlbert ARIBAUD \(3ADEV\) 0)
2675e862b95SAlbert ARIBAUD \(3ADEV\)
268552531e4SLiam Beguin U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_1, lpc32xx_i2c_init, lpc32xx_i2c_probe_chip,
2695e862b95SAlbert ARIBAUD \(3ADEV\) lpc32xx_i2c_read, lpc32xx_i2c_write,
2705e862b95SAlbert ARIBAUD \(3ADEV\) lpc32xx_i2c_set_bus_speed,
2715e862b95SAlbert ARIBAUD \(3ADEV\) CONFIG_SYS_I2C_LPC32XX_SPEED,
2725e862b95SAlbert ARIBAUD \(3ADEV\) CONFIG_SYS_I2C_LPC32XX_SLAVE,
2735e862b95SAlbert ARIBAUD \(3ADEV\) 1)
2741933af15SSylvain Lemieux
275552531e4SLiam Beguin U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_2, lpc32xx_i2c_init, NULL,
2761933af15SSylvain Lemieux lpc32xx_i2c_read, lpc32xx_i2c_write,
2771933af15SSylvain Lemieux lpc32xx_i2c_set_bus_speed,
2781933af15SSylvain Lemieux 100000,
2791933af15SSylvain Lemieux 0,
2801933af15SSylvain Lemieux 2)
281d61c7adbSLiam Beguin #else /* CONFIG_DM_I2C */
282d61c7adbSLiam Beguin static int lpc32xx_i2c_probe(struct udevice *bus)
283d61c7adbSLiam Beguin {
284d61c7adbSLiam Beguin struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
285*0f5b461bSLiam Beguin bus->seq = dev->index;
286d61c7adbSLiam Beguin
287d61c7adbSLiam Beguin __i2c_init(dev->base, dev->speed, 0, dev->index);
288d61c7adbSLiam Beguin return 0;
289d61c7adbSLiam Beguin }
290d61c7adbSLiam Beguin
291d61c7adbSLiam Beguin static int lpc32xx_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
292d61c7adbSLiam Beguin u32 chip_flags)
293d61c7adbSLiam Beguin {
294d61c7adbSLiam Beguin struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
295d61c7adbSLiam Beguin return __i2c_probe_chip(dev->base, chip_addr);
296d61c7adbSLiam Beguin }
297d61c7adbSLiam Beguin
298d61c7adbSLiam Beguin static int lpc32xx_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
299d61c7adbSLiam Beguin int nmsgs)
300d61c7adbSLiam Beguin {
301d61c7adbSLiam Beguin struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
302d61c7adbSLiam Beguin struct i2c_msg *dmsg, *omsg, dummy;
303d61c7adbSLiam Beguin uint i = 0, address = 0;
304d61c7adbSLiam Beguin
305d61c7adbSLiam Beguin memset(&dummy, 0, sizeof(struct i2c_msg));
306d61c7adbSLiam Beguin
307d61c7adbSLiam Beguin /* We expect either two messages (one with an offset and one with the
308d61c7adbSLiam Beguin * actual data) or one message (just data)
309d61c7adbSLiam Beguin */
310d61c7adbSLiam Beguin if (nmsgs > 2 || nmsgs == 0) {
311d61c7adbSLiam Beguin debug("%s: Only one or two messages are supported.", __func__);
312d61c7adbSLiam Beguin return -1;
313d61c7adbSLiam Beguin }
314d61c7adbSLiam Beguin
315d61c7adbSLiam Beguin omsg = nmsgs == 1 ? &dummy : msg;
316d61c7adbSLiam Beguin dmsg = nmsgs == 1 ? msg : msg + 1;
317d61c7adbSLiam Beguin
318d61c7adbSLiam Beguin /* the address is expected to be a uint, not a array. */
319d61c7adbSLiam Beguin address = omsg->buf[0];
320d61c7adbSLiam Beguin for (i = 1; i < omsg->len; i++)
321d61c7adbSLiam Beguin address = (address << 8) + omsg->buf[i];
322d61c7adbSLiam Beguin
323d61c7adbSLiam Beguin if (dmsg->flags & I2C_M_RD)
324d61c7adbSLiam Beguin return __i2c_read(dev->base, dmsg->addr, address,
325d61c7adbSLiam Beguin omsg->len, dmsg->buf, dmsg->len);
326d61c7adbSLiam Beguin else
327d61c7adbSLiam Beguin return __i2c_write(dev->base, dmsg->addr, address,
328d61c7adbSLiam Beguin omsg->len, dmsg->buf, dmsg->len);
329d61c7adbSLiam Beguin }
330d61c7adbSLiam Beguin
331d61c7adbSLiam Beguin static int lpc32xx_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
332d61c7adbSLiam Beguin {
333d61c7adbSLiam Beguin struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
334d61c7adbSLiam Beguin return __i2c_set_bus_speed(dev->base, speed, dev->index);
335d61c7adbSLiam Beguin }
336d61c7adbSLiam Beguin
337d61c7adbSLiam Beguin static int lpc32xx_i2c_reset(struct udevice *bus)
338d61c7adbSLiam Beguin {
339d61c7adbSLiam Beguin struct lpc32xx_i2c_dev *dev = dev_get_platdata(bus);
340d61c7adbSLiam Beguin
341d61c7adbSLiam Beguin __i2c_init(dev->base, dev->speed, 0, dev->index);
342d61c7adbSLiam Beguin return 0;
343d61c7adbSLiam Beguin }
344d61c7adbSLiam Beguin
345d61c7adbSLiam Beguin static const struct dm_i2c_ops lpc32xx_i2c_ops = {
346d61c7adbSLiam Beguin .xfer = lpc32xx_i2c_xfer,
347d61c7adbSLiam Beguin .probe_chip = lpc32xx_i2c_probe_chip,
348d61c7adbSLiam Beguin .deblock = lpc32xx_i2c_reset,
349d61c7adbSLiam Beguin .set_bus_speed = lpc32xx_i2c_set_bus_speed,
350d61c7adbSLiam Beguin };
351d61c7adbSLiam Beguin
352d61c7adbSLiam Beguin U_BOOT_DRIVER(i2c_lpc32xx) = {
353d61c7adbSLiam Beguin .id = UCLASS_I2C,
354d61c7adbSLiam Beguin .name = "i2c_lpc32xx",
355d61c7adbSLiam Beguin .probe = lpc32xx_i2c_probe,
356d61c7adbSLiam Beguin .ops = &lpc32xx_i2c_ops,
357d61c7adbSLiam Beguin };
358d61c7adbSLiam Beguin #endif /* CONFIG_DM_I2C */
359