aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-03-29 16:06:51 -0400
committerRalf Baechle <ralf@linux-mips.org>2015-04-01 11:22:08 -0400
commit968c94bcd891075ac06dd2f669c557f58a6523fc (patch)
tree57bce00ca18f083e653f7afd0c5a19fbbb838f1a
parente598e47144e41e8429bf127266bc3e8017d1a5f4 (diff)
MIPS: SEAD3: Nuke I2C driver that never was wired up in Makefile.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/mti-sead3/sead3-i2c-drv.c397
1 files changed, 0 insertions, 397 deletions
diff --git a/arch/mips/mti-sead3/sead3-i2c-drv.c b/arch/mips/mti-sead3/sead3-i2c-drv.c
deleted file mode 100644
index a43b0503097c..000000000000
--- a/arch/mips/mti-sead3/sead3-i2c-drv.c
+++ /dev/null
@@ -1,397 +0,0 @@
1/*
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
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 * Copyright (C) 2015 Imagination Technologies, Inc.
8 */
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>
15
16#include <asm/mips-boards/sead3-addr.h>
17
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
38
39static DEFINE_SPINLOCK(pic32_bus_lock);
40
41static void __iomem *bus_xfer = (void __iomem *)SEAD3_PIC32_REGISTERS;
42static void __iomem *bus_status = (void __iomem *)SEAD3_PI_PIC32_USB_STATUS;
43
44#define DELAY() udelay(100)
45
46static inline unsigned int ioready(void)
47{
48 return readl(bus_status) & SEAD3_PI_PIC32_USB_STATUS_IO_RDY;
49}
50
51static inline void wait_ioready(void)
52{
53 do { } while (!ioready());
54}
55
56static inline void wait_ioclear(void)
57{
58 do { } while (ioready());
59}
60
61static inline void check_ioclear(void)
62{
63 if (ioready()) {
64 do {
65 (void) readl(bus_xfer);
66 DELAY();
67 } while (ioready());
68 }
69}
70
71static u32 pic32_bus_readl(u32 reg)
72{
73 unsigned long flags;
74 u32 status, val;
75
76 spin_lock_irqsave(&pic32_bus_lock, flags);
77
78 check_ioclear();
79 writel((0x01 << 24) | (reg & 0x00ffffff), bus_xfer);
80 DELAY();
81 wait_ioready();
82 status = readl(bus_xfer);
83 DELAY();
84 val = readl(bus_xfer);
85 wait_ioclear();
86
87 spin_unlock_irqrestore(&pic32_bus_lock, flags);
88
89 return val;
90}
91
92static void pic32_bus_writel(u32 val, u32 reg)
93{
94 unsigned long flags;
95 u32 status;
96
97 spin_lock_irqsave(&pic32_bus_lock, flags);
98
99 check_ioclear();
100 writel((0x10 << 24) | (reg & 0x00ffffff), bus_xfer);
101 DELAY();
102 writel(val, bus_xfer);
103 DELAY();
104 wait_ioready();
105 status = readl(bus_xfer);
106 wait_ioclear();
107
108 spin_unlock_irqrestore(&pic32_bus_lock, flags);
109}
110
111struct pic32_i2c_platform_data {
112 u32 base;
113 struct i2c_adapter adap;
114 u32 xfer_timeout;
115 u32 ack_timeout;
116 u32 ctl_timeout;
117};
118
119static inline void pic32_i2c_start(struct pic32_i2c_platform_data *adap)
120{
121 pic32_bus_writel(PIC32_I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
122}
123
124static inline void pic32_i2c_stop(struct pic32_i2c_platform_data *adap)
125{
126 pic32_bus_writel(PIC32_I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
127}
128
129static inline void pic32_i2c_ack(struct pic32_i2c_platform_data *adap)
130{
131 pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
132 pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
133}
134
135static inline void pic32_i2c_nack(struct pic32_i2c_platform_data *adap)
136{
137 pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
138 pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
139}
140
141static inline int pic32_i2c_idle(struct pic32_i2c_platform_data *adap)
142{
143 int i;
144
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))
152 return 0;
153 udelay(1);
154 }
155 return -ETIMEDOUT;
156}
157
158static inline u32 pic32_i2c_master_write(struct pic32_i2c_platform_data *adap,
159 u32 byte)
160{
161 pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
162 return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
163 PIC32_I2CSTAT_IWCOL;
164}
165
166static inline u32 pic32_i2c_master_read(struct pic32_i2c_platform_data *adap)
167{
168 pic32_bus_writel(PIC32_I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
169 while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & PIC32_I2CCON_RCEN)
170 ;
171 pic32_bus_writel(PIC32_I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
172 return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
173}
174
175static int pic32_i2c_address(struct pic32_i2c_platform_data *adap,
176 unsigned int addr, int rd)
177{
178 pic32_i2c_idle(adap);
179 pic32_i2c_start(adap);
180 pic32_i2c_idle(adap);
181
182 addr <<= 1;
183 if (rd)
184 addr |= 1;
185
186 if (pic32_i2c_master_write(adap, addr))
187 return -EIO;
188 pic32_i2c_idle(adap);
189 if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
190 PIC32_I2CSTAT_ACKSTAT)
191 return -EIO;
192 return 0;
193}
194
195static int sead3_i2c_read(struct pic32_i2c_platform_data *adap,
196 unsigned char *buf, unsigned int len)
197{
198 u32 data;
199 int i;
200
201 i = 0;
202 while (i < len) {
203 data = pic32_i2c_master_read(adap);
204 buf[i++] = data;
205 if (i < len)
206 pic32_i2c_ack(adap);
207 else
208 pic32_i2c_nack(adap);
209 }
210
211 pic32_i2c_stop(adap);
212 pic32_i2c_idle(adap);
213 return 0;
214}
215
216static int sead3_i2c_write(struct pic32_i2c_platform_data *adap,
217 unsigned char *buf, unsigned int len)
218{
219 int i;
220 u32 data;
221
222 i = 0;
223 while (i < len) {
224 data = buf[i];
225 if (pic32_i2c_master_write(adap, data))
226 return -EIO;
227 pic32_i2c_idle(adap);
228 if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
229 PIC32_I2CSTAT_ACKSTAT)
230 return -EIO;
231 i++;
232 }
233
234 pic32_i2c_stop(adap);
235 pic32_i2c_idle(adap);
236 return 0;
237}
238
239static int sead3_pic32_platform_xfer(struct i2c_adapter *i2c_adap,
240 struct i2c_msg *msgs, int num)
241{
242 struct pic32_i2c_platform_data *adap = i2c_adap->algo_data;
243 struct i2c_msg *p;
244 int i, err = 0;
245
246 for (i = 0; i < num; i++) {
247#define __BUFSIZE 80
248 int ii;
249 static char buf[__BUFSIZE];
250 char *b = buf;
251
252 p = &msgs[i];
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]);
258 } else {
259 strcat(b, "...");
260 break;
261 }
262 }
263 }
264 }
265
266 for (i = 0; !err && i < num; i++) {
267 p = &msgs[i];
268 err = pic32_i2c_address(adap, p->addr, p->flags & I2C_M_RD);
269 if (err || !p->len)
270 continue;
271 if (p->flags & I2C_M_RD)
272 err = sead3_i2c_read(adap, p->buf, p->len);
273 else
274 err = sead3_i2c_write(adap, p->buf, p->len);
275 }
276
277 /* Return the number of messages processed, or the error code. */
278 if (err == 0)
279 err = num;
280
281 return err;
282}
283
284static u32 sead3_pic32_platform_func(struct i2c_adapter *adap)
285{
286 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
287}
288
289static const struct i2c_algorithm sead3_platform_algo = {
290 .master_xfer = sead3_pic32_platform_xfer,
291 .functionality = sead3_pic32_platform_func,
292};
293
294static void sead3_i2c_platform_setup(struct pic32_i2c_platform_data *priv)
295{
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);
301}
302
303static int sead3_i2c_platform_probe(struct platform_device *pdev)
304{
305 struct pic32_i2c_platform_data *priv;
306 struct resource *r;
307 int ret;
308
309 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
310 if (!r) {
311 ret = -ENODEV;
312 goto out;
313 }
314
315 priv = kzalloc(sizeof(struct pic32_i2c_platform_data), GFP_KERNEL);
316 if (!priv) {
317 ret = -ENOMEM;
318 goto out;
319 }
320
321 priv->base = r->start;
322 if (!priv->base) {
323 ret = -EBUSY;
324 goto out_mem;
325 }
326
327 priv->xfer_timeout = 200;
328 priv->ack_timeout = 200;
329 priv->ctl_timeout = 200;
330
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));
336
337 sead3_i2c_platform_setup(priv);
338
339 ret = i2c_add_numbered_adapter(&priv->adap);
340 if (ret == 0) {
341 platform_set_drvdata(pdev, priv);
342 return 0;
343 }
344
345out_mem:
346 kfree(priv);
347out:
348 return ret;
349}
350
351static int sead3_i2c_platform_remove(struct platform_device *pdev)
352{
353 struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
354
355 platform_set_drvdata(pdev, NULL);
356 i2c_del_adapter(&priv->adap);
357 kfree(priv);
358 return 0;
359}
360
361#ifdef CONFIG_PM
362static int sead3_i2c_platform_suspend(struct platform_device *pdev,
363 pm_message_t state)
364{
365 dev_dbg(&pdev->dev, "i2c_platform_disable\n");
366 return 0;
367}
368
369static int sead3_i2c_platform_resume(struct platform_device *pdev)
370{
371 struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
372
373 dev_dbg(&pdev->dev, "sead3_i2c_platform_setup\n");
374 sead3_i2c_platform_setup(priv);
375
376 return 0;
377}
378#else
379#define sead3_i2c_platform_suspend NULL
380#define sead3_i2c_platform_resume NULL
381#endif
382
383static struct platform_driver sead3_i2c_platform_driver = {
384 .driver = {
385 .name = "sead3-i2c",
386 },
387 .probe = sead3_i2c_platform_probe,
388 .remove = sead3_i2c_platform_remove,
389 .suspend = sead3_i2c_platform_suspend,
390 .resume = sead3_i2c_platform_resume,
391};
392
393module_platform_driver(sead3_i2c_platform_driver);
394
395MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
396MODULE_DESCRIPTION("SEAD3 PIC32 I2C driver");
397MODULE_LICENSE("GPL");