2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 * Copyright (C) 2015 Imagination Technologies, Inc.
9 #include <linux/init.h>
10 #include <linux/module.h>
11 #include <linux/slab.h>
12 #include <linux/delay.h>
13 #include <linux/i2c.h>
14 #include <linux/platform_device.h>
16 #include <asm/mips-boards/sead3-addr.h>
18 #define PIC32_I2CxCON 0x0000
19 #define PIC32_I2CCON_ON (1<<15)
20 #define PIC32_I2CCON_ACKDT (1<<5)
21 #define PIC32_I2CCON_ACKEN (1<<4)
22 #define PIC32_I2CCON_RCEN (1<<3)
23 #define PIC32_I2CCON_PEN (1<<2)
24 #define PIC32_I2CCON_RSEN (1<<1)
25 #define PIC32_I2CCON_SEN (1<<0)
26 #define PIC32_I2CxCONCLR 0x0004
27 #define PIC32_I2CxCONSET 0x0008
28 #define PIC32_I2CxSTAT 0x0010
29 #define PIC32_I2CxSTATCLR 0x0014
30 #define PIC32_I2CSTAT_ACKSTAT (1<<15)
31 #define PIC32_I2CSTAT_TRSTAT (1<<14)
32 #define PIC32_I2CSTAT_BCL (1<<10)
33 #define PIC32_I2CSTAT_IWCOL (1<<7)
34 #define PIC32_I2CSTAT_I2COV (1<<6)
35 #define PIC32_I2CxBRG 0x0040
36 #define PIC32_I2CxTRN 0x0050
37 #define PIC32_I2CxRCV 0x0060
39 static DEFINE_SPINLOCK(pic32_bus_lock);
41 static void __iomem *bus_xfer = (void __iomem *)SEAD3_PIC32_REGISTERS;
42 static void __iomem *bus_status = (void __iomem *)SEAD3_PI_PIC32_USB_STATUS;
44 #define DELAY() udelay(100)
46 static inline unsigned int ioready(void)
48 return readl(bus_status) & SEAD3_PI_PIC32_USB_STATUS_IO_RDY;
51 static inline void wait_ioready(void)
53 do { } while (!ioready());
56 static inline void wait_ioclear(void)
58 do { } while (ioready());
61 static inline void check_ioclear(void)
65 (void) readl(bus_xfer);
71 static u32 pic32_bus_readl(u32 reg)
76 spin_lock_irqsave(&pic32_bus_lock, flags);
79 writel((0x01 << 24) | (reg & 0x00ffffff), bus_xfer);
82 status = readl(bus_xfer);
84 val = readl(bus_xfer);
87 spin_unlock_irqrestore(&pic32_bus_lock, flags);
92 static void pic32_bus_writel(u32 val, u32 reg)
97 spin_lock_irqsave(&pic32_bus_lock, flags);
100 writel((0x10 << 24) | (reg & 0x00ffffff), bus_xfer);
102 writel(val, bus_xfer);
105 status = readl(bus_xfer);
108 spin_unlock_irqrestore(&pic32_bus_lock, flags);
111 struct pic32_i2c_platform_data {
113 struct i2c_adapter adap;
119 static inline void pic32_i2c_start(struct pic32_i2c_platform_data *adap)
121 pic32_bus_writel(PIC32_I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
124 static inline void pic32_i2c_stop(struct pic32_i2c_platform_data *adap)
126 pic32_bus_writel(PIC32_I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
129 static inline void pic32_i2c_ack(struct pic32_i2c_platform_data *adap)
131 pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
132 pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
135 static inline void pic32_i2c_nack(struct pic32_i2c_platform_data *adap)
137 pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
138 pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
141 static inline int pic32_i2c_idle(struct pic32_i2c_platform_data *adap)
145 for (i = 0; i < adap->ctl_timeout; i++) {
146 if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
147 (PIC32_I2CCON_ACKEN | PIC32_I2CCON_RCEN |
148 PIC32_I2CCON_PEN | PIC32_I2CCON_RSEN |
149 PIC32_I2CCON_SEN)) == 0) &&
150 ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
151 (PIC32_I2CSTAT_TRSTAT)) == 0))
158 static inline u32 pic32_i2c_master_write(struct pic32_i2c_platform_data *adap,
161 pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
162 return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
166 static inline u32 pic32_i2c_master_read(struct pic32_i2c_platform_data *adap)
168 pic32_bus_writel(PIC32_I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
169 while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & PIC32_I2CCON_RCEN)
171 pic32_bus_writel(PIC32_I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
172 return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
175 static int pic32_i2c_address(struct pic32_i2c_platform_data *adap,
176 unsigned int addr, int rd)
178 pic32_i2c_idle(adap);
179 pic32_i2c_start(adap);
180 pic32_i2c_idle(adap);
186 if (pic32_i2c_master_write(adap, addr))
188 pic32_i2c_idle(adap);
189 if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
190 PIC32_I2CSTAT_ACKSTAT)
195 static int sead3_i2c_read(struct pic32_i2c_platform_data *adap,
196 unsigned char *buf, unsigned int len)
203 data = pic32_i2c_master_read(adap);
208 pic32_i2c_nack(adap);
211 pic32_i2c_stop(adap);
212 pic32_i2c_idle(adap);
216 static int sead3_i2c_write(struct pic32_i2c_platform_data *adap,
217 unsigned char *buf, unsigned int len)
225 if (pic32_i2c_master_write(adap, data))
227 pic32_i2c_idle(adap);
228 if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
229 PIC32_I2CSTAT_ACKSTAT)
234 pic32_i2c_stop(adap);
235 pic32_i2c_idle(adap);
239 static int sead3_pic32_platform_xfer(struct i2c_adapter *i2c_adap,
240 struct i2c_msg *msgs, int num)
242 struct pic32_i2c_platform_data *adap = i2c_adap->algo_data;
246 for (i = 0; i < num; i++) {
249 static char buf[__BUFSIZE];
253 b += sprintf(buf, " [%d bytes]", p->len);
254 if ((p->flags & I2C_M_RD) == 0) {
255 for (ii = 0; ii < p->len; ii++) {
256 if (b < &buf[__BUFSIZE-4]) {
257 b += sprintf(b, " %02x", p->buf[ii]);
266 for (i = 0; !err && i < num; i++) {
268 err = pic32_i2c_address(adap, p->addr, p->flags & I2C_M_RD);
271 if (p->flags & I2C_M_RD)
272 err = sead3_i2c_read(adap, p->buf, p->len);
274 err = sead3_i2c_write(adap, p->buf, p->len);
277 /* Return the number of messages processed, or the error code. */
284 static u32 sead3_pic32_platform_func(struct i2c_adapter *adap)
286 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
289 static const struct i2c_algorithm sead3_platform_algo = {
290 .master_xfer = sead3_pic32_platform_xfer,
291 .functionality = sead3_pic32_platform_func,
294 static void sead3_i2c_platform_setup(struct pic32_i2c_platform_data *priv)
296 pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
297 pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
298 pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONSET);
299 pic32_bus_writel(PIC32_I2CSTAT_BCL | PIC32_I2CSTAT_IWCOL,
300 priv->base + PIC32_I2CxSTATCLR);
303 static int sead3_i2c_platform_probe(struct platform_device *pdev)
305 struct pic32_i2c_platform_data *priv;
309 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315 priv = kzalloc(sizeof(struct pic32_i2c_platform_data), GFP_KERNEL);
321 priv->base = r->start;
327 priv->xfer_timeout = 200;
328 priv->ack_timeout = 200;
329 priv->ctl_timeout = 200;
331 priv->adap.nr = pdev->id;
332 priv->adap.algo = &sead3_platform_algo;
333 priv->adap.algo_data = priv;
334 priv->adap.dev.parent = &pdev->dev;
335 strlcpy(priv->adap.name, "SEAD3 PIC32", sizeof(priv->adap.name));
337 sead3_i2c_platform_setup(priv);
339 ret = i2c_add_numbered_adapter(&priv->adap);
341 platform_set_drvdata(pdev, priv);
351 static int sead3_i2c_platform_remove(struct platform_device *pdev)
353 struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
355 platform_set_drvdata(pdev, NULL);
356 i2c_del_adapter(&priv->adap);
362 static int sead3_i2c_platform_suspend(struct platform_device *pdev,
365 dev_dbg(&pdev->dev, "i2c_platform_disable\n");
369 static int sead3_i2c_platform_resume(struct platform_device *pdev)
371 struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
373 dev_dbg(&pdev->dev, "sead3_i2c_platform_setup\n");
374 sead3_i2c_platform_setup(priv);
379 #define sead3_i2c_platform_suspend NULL
380 #define sead3_i2c_platform_resume NULL
383 static struct platform_driver sead3_i2c_platform_driver = {
387 .probe = sead3_i2c_platform_probe,
388 .remove = sead3_i2c_platform_remove,
389 .suspend = sead3_i2c_platform_suspend,
390 .resume = sead3_i2c_platform_resume,
393 module_platform_driver(sead3_i2c_platform_driver);
395 MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
396 MODULE_DESCRIPTION("SEAD3 PIC32 I2C driver");
397 MODULE_LICENSE("GPL");