xref: /linux/drivers/i2c/busses/i2c-mpc.c (revision 14b42963f64b98ab61fa9723c03d71aa5ef4f862)
1 /*
2  * (C) Copyright 2003-2004
3  * Humboldt Solutions Ltd, adrian@humboldt.co.uk.
4 
5  * This is a combined i2c adapter and algorithm driver for the
6  * MPC107/Tsi107 PowerPC northbridge and processors that include
7  * the same I2C unit (8240, 8245, 85xx).
8  *
9  * Release 0.8
10  *
11  * This file is licensed under the terms of the GNU General Public
12  * License version 2. This program is licensed "as is" without any
13  * warranty of any kind, whether express or implied.
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/sched.h>
19 #include <linux/init.h>
20 #include <linux/pci.h>
21 #include <linux/platform_device.h>
22 
23 #include <asm/io.h>
24 #include <linux/fsl_devices.h>
25 #include <linux/i2c.h>
26 #include <linux/interrupt.h>
27 #include <linux/delay.h>
28 
29 #define MPC_I2C_ADDR  0x00
30 #define MPC_I2C_FDR 	0x04
31 #define MPC_I2C_CR	0x08
32 #define MPC_I2C_SR	0x0c
33 #define MPC_I2C_DR	0x10
34 #define MPC_I2C_DFSRR 0x14
35 #define MPC_I2C_REGION 0x20
36 
37 #define CCR_MEN  0x80
38 #define CCR_MIEN 0x40
39 #define CCR_MSTA 0x20
40 #define CCR_MTX  0x10
41 #define CCR_TXAK 0x08
42 #define CCR_RSTA 0x04
43 
44 #define CSR_MCF  0x80
45 #define CSR_MAAS 0x40
46 #define CSR_MBB  0x20
47 #define CSR_MAL  0x10
48 #define CSR_SRW  0x04
49 #define CSR_MIF  0x02
50 #define CSR_RXAK 0x01
51 
52 struct mpc_i2c {
53 	void __iomem *base;
54 	u32 interrupt;
55 	wait_queue_head_t queue;
56 	struct i2c_adapter adap;
57 	int irq;
58 	u32 flags;
59 };
60 
61 static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
62 {
63 	writeb(x, i2c->base + MPC_I2C_CR);
64 }
65 
66 static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs *regs)
67 {
68 	struct mpc_i2c *i2c = dev_id;
69 	if (readb(i2c->base + MPC_I2C_SR) & CSR_MIF) {
70 		/* Read again to allow register to stabilise */
71 		i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
72 		writeb(0, i2c->base + MPC_I2C_SR);
73 		wake_up_interruptible(&i2c->queue);
74 	}
75 	return IRQ_HANDLED;
76 }
77 
78 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
79 {
80 	unsigned long orig_jiffies = jiffies;
81 	u32 x;
82 	int result = 0;
83 
84 	if (i2c->irq == 0)
85 	{
86 		while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
87 			schedule();
88 			if (time_after(jiffies, orig_jiffies + timeout)) {
89 				pr_debug("I2C: timeout\n");
90 				result = -EIO;
91 				break;
92 			}
93 		}
94 		x = readb(i2c->base + MPC_I2C_SR);
95 		writeb(0, i2c->base + MPC_I2C_SR);
96 	} else {
97 		/* Interrupt mode */
98 		result = wait_event_interruptible_timeout(i2c->queue,
99 			(i2c->interrupt & CSR_MIF), timeout * HZ);
100 
101 		if (unlikely(result < 0))
102 			pr_debug("I2C: wait interrupted\n");
103 		else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
104 			pr_debug("I2C: wait timeout\n");
105 			result = -ETIMEDOUT;
106 		}
107 
108 		x = i2c->interrupt;
109 		i2c->interrupt = 0;
110 	}
111 
112 	if (result < 0)
113 		return result;
114 
115 	if (!(x & CSR_MCF)) {
116 		pr_debug("I2C: unfinished\n");
117 		return -EIO;
118 	}
119 
120 	if (x & CSR_MAL) {
121 		pr_debug("I2C: MAL\n");
122 		return -EIO;
123 	}
124 
125 	if (writing && (x & CSR_RXAK)) {
126 		pr_debug("I2C: No RXAK\n");
127 		/* generate stop */
128 		writeccr(i2c, CCR_MEN);
129 		return -EIO;
130 	}
131 	return 0;
132 }
133 
134 static void mpc_i2c_setclock(struct mpc_i2c *i2c)
135 {
136 	/* Set clock and filters */
137 	if (i2c->flags & FSL_I2C_DEV_SEPARATE_DFSRR) {
138 		writeb(0x31, i2c->base + MPC_I2C_FDR);
139 		writeb(0x10, i2c->base + MPC_I2C_DFSRR);
140 	} else if (i2c->flags & FSL_I2C_DEV_CLOCK_5200)
141 		writeb(0x3f, i2c->base + MPC_I2C_FDR);
142 	else
143 		writel(0x1031, i2c->base + MPC_I2C_FDR);
144 }
145 
146 static void mpc_i2c_start(struct mpc_i2c *i2c)
147 {
148 	/* Clear arbitration */
149 	writeb(0, i2c->base + MPC_I2C_SR);
150 	/* Start with MEN */
151 	writeccr(i2c, CCR_MEN);
152 }
153 
154 static void mpc_i2c_stop(struct mpc_i2c *i2c)
155 {
156 	writeccr(i2c, CCR_MEN);
157 }
158 
159 static int mpc_write(struct mpc_i2c *i2c, int target,
160 		     const u8 * data, int length, int restart)
161 {
162 	int i;
163 	unsigned timeout = i2c->adap.timeout;
164 	u32 flags = restart ? CCR_RSTA : 0;
165 
166 	/* Start with MEN */
167 	if (!restart)
168 		writeccr(i2c, CCR_MEN);
169 	/* Start as master */
170 	writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
171 	/* Write target byte */
172 	writeb((target << 1), i2c->base + MPC_I2C_DR);
173 
174 	if (i2c_wait(i2c, timeout, 1) < 0)
175 		return -1;
176 
177 	for (i = 0; i < length; i++) {
178 		/* Write data byte */
179 		writeb(data[i], i2c->base + MPC_I2C_DR);
180 
181 		if (i2c_wait(i2c, timeout, 1) < 0)
182 			return -1;
183 	}
184 
185 	return 0;
186 }
187 
188 static int mpc_read(struct mpc_i2c *i2c, int target,
189 		    u8 * data, int length, int restart)
190 {
191 	unsigned timeout = i2c->adap.timeout;
192 	int i;
193 	u32 flags = restart ? CCR_RSTA : 0;
194 
195 	/* Start with MEN */
196 	if (!restart)
197 		writeccr(i2c, CCR_MEN);
198 	/* Switch to read - restart */
199 	writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);
200 	/* Write target address byte - this time with the read flag set */
201 	writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);
202 
203 	if (i2c_wait(i2c, timeout, 1) < 0)
204 		return -1;
205 
206 	if (length) {
207 		if (length == 1)
208 			writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);
209 		else
210 			writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA);
211 		/* Dummy read */
212 		readb(i2c->base + MPC_I2C_DR);
213 	}
214 
215 	for (i = 0; i < length; i++) {
216 		if (i2c_wait(i2c, timeout, 0) < 0)
217 			return -1;
218 
219 		/* Generate txack on next to last byte */
220 		if (i == length - 2)
221 			writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);
222 		/* Generate stop on last byte */
223 		if (i == length - 1)
224 			writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);
225 		data[i] = readb(i2c->base + MPC_I2C_DR);
226 	}
227 
228 	return length;
229 }
230 
231 static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
232 {
233 	struct i2c_msg *pmsg;
234 	int i;
235 	int ret = 0;
236 	unsigned long orig_jiffies = jiffies;
237 	struct mpc_i2c *i2c = i2c_get_adapdata(adap);
238 
239 	mpc_i2c_start(i2c);
240 
241 	/* Allow bus up to 1s to become not busy */
242 	while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
243 		if (signal_pending(current)) {
244 			pr_debug("I2C: Interrupted\n");
245 			return -EINTR;
246 		}
247 		if (time_after(jiffies, orig_jiffies + HZ)) {
248 			pr_debug("I2C: timeout\n");
249 			return -EIO;
250 		}
251 		schedule();
252 	}
253 
254 	for (i = 0; ret >= 0 && i < num; i++) {
255 		pmsg = &msgs[i];
256 		pr_debug("Doing %s %d bytes to 0x%02x - %d of %d messages\n",
257 			 pmsg->flags & I2C_M_RD ? "read" : "write",
258 			 pmsg->len, pmsg->addr, i + 1, num);
259 		if (pmsg->flags & I2C_M_RD)
260 			ret =
261 			    mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
262 		else
263 			ret =
264 			    mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
265 	}
266 	mpc_i2c_stop(i2c);
267 	return (ret < 0) ? ret : num;
268 }
269 
270 static u32 mpc_functionality(struct i2c_adapter *adap)
271 {
272 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
273 }
274 
275 static struct i2c_algorithm mpc_algo = {
276 	.master_xfer = mpc_xfer,
277 	.functionality = mpc_functionality,
278 };
279 
280 static struct i2c_adapter mpc_ops = {
281 	.owner = THIS_MODULE,
282 	.name = "MPC adapter",
283 	.id = I2C_HW_MPC107,
284 	.algo = &mpc_algo,
285 	.class = I2C_CLASS_HWMON,
286 	.timeout = 1,
287 	.retries = 1
288 };
289 
290 static int fsl_i2c_probe(struct platform_device *pdev)
291 {
292 	int result = 0;
293 	struct mpc_i2c *i2c;
294 	struct fsl_i2c_platform_data *pdata;
295 	struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
296 
297 	pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
298 
299 	if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) {
300 		return -ENOMEM;
301 	}
302 
303 	i2c->irq = platform_get_irq(pdev, 0);
304 	if (i2c->irq < 0) {
305 		result = -ENXIO;
306 		goto fail_get_irq;
307 	}
308 	i2c->flags = pdata->device_flags;
309 	init_waitqueue_head(&i2c->queue);
310 
311 	i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
312 
313 	if (!i2c->base) {
314 		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
315 		result = -ENOMEM;
316 		goto fail_map;
317 	}
318 
319 	if (i2c->irq != 0)
320 		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
321 					  IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
322 			printk(KERN_ERR
323 			       "i2c-mpc - failed to attach interrupt\n");
324 			goto fail_irq;
325 		}
326 
327 	mpc_i2c_setclock(i2c);
328 	platform_set_drvdata(pdev, i2c);
329 
330 	i2c->adap = mpc_ops;
331 	i2c_set_adapdata(&i2c->adap, i2c);
332 	i2c->adap.dev.parent = &pdev->dev;
333 	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
334 		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
335 		goto fail_add;
336 	}
337 
338 	return result;
339 
340       fail_add:
341 	if (i2c->irq != 0)
342 		free_irq(i2c->irq, NULL);
343       fail_irq:
344 	iounmap(i2c->base);
345       fail_map:
346       fail_get_irq:
347 	kfree(i2c);
348 	return result;
349 };
350 
351 static int fsl_i2c_remove(struct platform_device *pdev)
352 {
353 	struct mpc_i2c *i2c = platform_get_drvdata(pdev);
354 
355 	i2c_del_adapter(&i2c->adap);
356 	platform_set_drvdata(pdev, NULL);
357 
358 	if (i2c->irq != 0)
359 		free_irq(i2c->irq, i2c);
360 
361 	iounmap(i2c->base);
362 	kfree(i2c);
363 	return 0;
364 };
365 
366 /* Structure for a device driver */
367 static struct platform_driver fsl_i2c_driver = {
368 	.probe = fsl_i2c_probe,
369 	.remove = fsl_i2c_remove,
370 	.driver	= {
371 		.owner = THIS_MODULE,
372 		.name = "fsl-i2c",
373 	},
374 };
375 
376 static int __init fsl_i2c_init(void)
377 {
378 	return platform_driver_register(&fsl_i2c_driver);
379 }
380 
381 static void __exit fsl_i2c_exit(void)
382 {
383 	platform_driver_unregister(&fsl_i2c_driver);
384 }
385 
386 module_init(fsl_i2c_init);
387 module_exit(fsl_i2c_exit);
388 
389 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
390 MODULE_DESCRIPTION
391     ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
392 MODULE_LICENSE("GPL");
393