aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2010-08-10 19:35:25 -0400
committerBen Dooks <ben-linux@fluff.org>2010-08-10 19:35:25 -0400
commitf6e1901c4c596238abe6735bb20593f2734f757e (patch)
tree14515f05ce94045316c4d264f1e3bdfa9b0ddddf
parentd8a6206d4f65f979dc3fee0962af509040b342dc (diff)
parentededad3e6f2c7ccf0c721e71f2fd7b1ea56f520f (diff)
Merge branch 'for-2636/i2c/nuc' into next-i2c
-rw-r--r--arch/arm/mach-w90x900/include/mach/i2c.h9
-rw-r--r--drivers/i2c/busses/Kconfig7
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-nuc900.c709
4 files changed, 726 insertions, 0 deletions
diff --git a/arch/arm/mach-w90x900/include/mach/i2c.h b/arch/arm/mach-w90x900/include/mach/i2c.h
new file mode 100644
index 000000000000..9ffb12d06e91
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/i2c.h
@@ -0,0 +1,9 @@
1#ifndef __ASM_ARCH_NUC900_I2C_H
2#define __ASM_ARCH_NUC900_I2C_H
3
4struct nuc900_platform_i2c {
5 int bus_num;
6 unsigned long bus_freq;
7};
8
9#endif /* __ASM_ARCH_NUC900_I2C_H */
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 77eabae4df8a..21d88532d5b2 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -448,6 +448,13 @@ config I2C_NOMADIK
448 If you say yes to this option, support will be included for the 448 If you say yes to this option, support will be included for the
449 I2C interface from ST-Ericsson's Nomadik and Ux500 architectures. 449 I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
450 450
451config I2C_NUC900
452 tristate "NUC900 I2C Driver"
453 depends on ARCH_W90X900
454 help
455 Say Y here to include support for I2C controller in the
456 Winbond/Nuvoton NUC900 based System-on-Chip devices.
457
451config I2C_OCORES 458config I2C_OCORES
452 tristate "OpenCores I2C Controller" 459 tristate "OpenCores I2C Controller"
453 depends on EXPERIMENTAL 460 depends on EXPERIMENTAL
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 936880bd1dc5..c3ef49230cba 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
43obj-$(CONFIG_I2C_MPC) += i2c-mpc.o 43obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
44obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o 44obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
45obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o 45obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
46obj-$(CONFIG_I2C_NUC900) += i2c-nuc900.o
46obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o 47obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
47obj-$(CONFIG_I2C_OMAP) += i2c-omap.o 48obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
48obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o 49obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c
new file mode 100644
index 000000000000..92d770d7bbc2
--- /dev/null
+++ b/drivers/i2c/busses/i2c-nuc900.c
@@ -0,0 +1,709 @@
1/*
2 * linux/drivers/i2c/busses/i2c-nuc900.c
3 *
4 * Copyright (c) 2010 Nuvoton technology corporation.
5 *
6 * This driver based on S3C2410 I2C driver of Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.org>.
7 * Written by Wan ZongShun <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation;version 2 of the License.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17
18#include <linux/i2c.h>
19#include <linux/i2c-id.h>
20#include <linux/init.h>
21#include <linux/time.h>
22#include <linux/interrupt.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/err.h>
26#include <linux/platform_device.h>
27#include <linux/clk.h>
28#include <linux/cpufreq.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31
32#include <mach/mfp.h>
33#include <mach/i2c.h>
34
35/* nuc900 i2c registers offset */
36
37#define CSR 0x00
38#define DIVIDER 0x04
39#define CMDR 0x08
40#define SWR 0x0C
41#define RXR 0x10
42#define TXR 0x14
43
44/* nuc900 i2c CSR register bits */
45
46#define IRQEN 0x003
47#define I2CBUSY 0x400
48#define I2CSTART 0x018
49#define IRQFLAG 0x004
50#define ARBIT_LOST 0x200
51#define SLAVE_ACK 0x800
52
53/* nuc900 i2c CMDR register bits */
54
55#define I2C_CMD_START 0x10
56#define I2C_CMD_STOP 0x08
57#define I2C_CMD_READ 0x04
58#define I2C_CMD_WRITE 0x02
59#define I2C_CMD_NACK 0x01
60
61/* i2c controller state */
62
63enum nuc900_i2c_state {
64 STATE_IDLE,
65 STATE_START,
66 STATE_READ,
67 STATE_WRITE,
68 STATE_STOP
69};
70
71/* i2c controller private data */
72
73struct nuc900_i2c {
74 spinlock_t lock;
75 wait_queue_head_t wait;
76
77 struct i2c_msg *msg;
78 unsigned int msg_num;
79 unsigned int msg_idx;
80 unsigned int msg_ptr;
81 unsigned int irq;
82
83 enum nuc900_i2c_state state;
84
85 void __iomem *regs;
86 struct clk *clk;
87 struct device *dev;
88 struct resource *ioarea;
89 struct i2c_adapter adap;
90};
91
92/* nuc900_i2c_master_complete
93 *
94 * complete the message and wake up the caller, using the given return code,
95 * or zero to mean ok.
96*/
97
98static inline void nuc900_i2c_master_complete(struct nuc900_i2c *i2c, int ret)
99{
100 dev_dbg(i2c->dev, "master_complete %d\n", ret);
101
102 i2c->msg_ptr = 0;
103 i2c->msg = NULL;
104 i2c->msg_idx++;
105 i2c->msg_num = 0;
106 if (ret)
107 i2c->msg_idx = ret;
108
109 wake_up(&i2c->wait);
110}
111
112/* irq enable/disable functions */
113
114static inline void nuc900_i2c_disable_irq(struct nuc900_i2c *i2c)
115{
116 unsigned long tmp;
117
118 tmp = readl(i2c->regs + CSR);
119 writel(tmp & ~IRQEN, i2c->regs + CSR);
120}
121
122static inline void nuc900_i2c_enable_irq(struct nuc900_i2c *i2c)
123{
124 unsigned long tmp;
125
126 tmp = readl(i2c->regs + CSR);
127 writel(tmp | IRQEN, i2c->regs + CSR);
128}
129
130
131/* nuc900_i2c_message_start
132 *
133 * put the start of a message onto the bus
134*/
135
136static void nuc900_i2c_message_start(struct nuc900_i2c *i2c,
137 struct i2c_msg *msg)
138{
139 unsigned int addr = (msg->addr & 0x7f) << 1;
140
141 if (msg->flags & I2C_M_RD)
142 addr |= 0x1;
143 writel(addr & 0xff, i2c->regs + TXR);
144 writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR);
145}
146
147static inline void nuc900_i2c_stop(struct nuc900_i2c *i2c, int ret)
148{
149
150 dev_dbg(i2c->dev, "STOP\n");
151
152 /* stop the transfer */
153 i2c->state = STATE_STOP;
154 writel(I2C_CMD_STOP, i2c->regs + CMDR);
155
156 nuc900_i2c_master_complete(i2c, ret);
157 nuc900_i2c_disable_irq(i2c);
158}
159
160/* helper functions to determine the current state in the set of
161 * messages we are sending
162*/
163
164/* is_lastmsg()
165 *
166 * returns TRUE if the current message is the last in the set
167*/
168
169static inline int is_lastmsg(struct nuc900_i2c *i2c)
170{
171 return i2c->msg_idx >= (i2c->msg_num - 1);
172}
173
174/* is_msglast
175 *
176 * returns TRUE if we this is the last byte in the current message
177*/
178
179static inline int is_msglast(struct nuc900_i2c *i2c)
180{
181 return i2c->msg_ptr == i2c->msg->len-1;
182}
183
184/* is_msgend
185 *
186 * returns TRUE if we reached the end of the current message
187*/
188
189static inline int is_msgend(struct nuc900_i2c *i2c)
190{
191 return i2c->msg_ptr >= i2c->msg->len;
192}
193
194/* i2c_nuc900_irq_nextbyte
195 *
196 * process an interrupt and work out what to do
197 */
198
199static void i2c_nuc900_irq_nextbyte(struct nuc900_i2c *i2c,
200 unsigned long iicstat)
201{
202 unsigned char byte;
203
204 switch (i2c->state) {
205
206 case STATE_IDLE:
207 dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
208 break;
209
210 case STATE_STOP:
211 dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
212 nuc900_i2c_disable_irq(i2c);
213 break;
214
215 case STATE_START:
216 /* last thing we did was send a start condition on the
217 * bus, or started a new i2c message
218 */
219
220 if (iicstat & SLAVE_ACK &&
221 !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
222 /* ack was not received... */
223
224 dev_dbg(i2c->dev, "ack was not received\n");
225 nuc900_i2c_stop(i2c, -ENXIO);
226 break;
227 }
228
229 if (i2c->msg->flags & I2C_M_RD)
230 i2c->state = STATE_READ;
231 else
232 i2c->state = STATE_WRITE;
233
234 /* terminate the transfer if there is nothing to do
235 * as this is used by the i2c probe to find devices.
236 */
237
238 if (is_lastmsg(i2c) && i2c->msg->len == 0) {
239 nuc900_i2c_stop(i2c, 0);
240 break;
241 }
242
243 if (i2c->state == STATE_READ)
244 goto prepare_read;
245
246 /* fall through to the write state, as we will need to
247 * send a byte as well
248 */
249
250 case STATE_WRITE:
251 /* we are writing data to the device... check for the
252 * end of the message, and if so, work out what to do
253 */
254
255 if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
256 if (iicstat & SLAVE_ACK) {
257 dev_dbg(i2c->dev, "WRITE: No Ack\n");
258
259 nuc900_i2c_stop(i2c, -ECONNREFUSED);
260 break;
261 }
262 }
263
264retry_write:
265
266 if (!is_msgend(i2c)) {
267 byte = i2c->msg->buf[i2c->msg_ptr++];
268 writeb(byte, i2c->regs + TXR);
269 writel(I2C_CMD_WRITE, i2c->regs + CMDR);
270
271 } else if (!is_lastmsg(i2c)) {
272 /* we need to go to the next i2c message */
273
274 dev_dbg(i2c->dev, "WRITE: Next Message\n");
275
276 i2c->msg_ptr = 0;
277 i2c->msg_idx++;
278 i2c->msg++;
279
280 /* check to see if we need to do another message */
281 if (i2c->msg->flags & I2C_M_NOSTART) {
282
283 if (i2c->msg->flags & I2C_M_RD) {
284 /* cannot do this, the controller
285 * forces us to send a new START
286 * when we change direction
287 */
288
289 nuc900_i2c_stop(i2c, -EINVAL);
290 }
291
292 goto retry_write;
293 } else {
294 /* send the new start */
295 nuc900_i2c_message_start(i2c, i2c->msg);
296 i2c->state = STATE_START;
297 }
298
299 } else {
300 /* send stop */
301
302 nuc900_i2c_stop(i2c, 0);
303 }
304 break;
305
306 case STATE_READ:
307 /* we have a byte of data in the data register, do
308 * something with it, and then work out wether we are
309 * going to do any more read/write
310 */
311
312 byte = readb(i2c->regs + RXR);
313 i2c->msg->buf[i2c->msg_ptr++] = byte;
314
315prepare_read:
316 if (is_msglast(i2c)) {
317 /* last byte of buffer */
318
319 if (is_lastmsg(i2c))
320 writel(I2C_CMD_READ | I2C_CMD_NACK,
321 i2c->regs + CMDR);
322
323 } else if (is_msgend(i2c)) {
324 /* ok, we've read the entire buffer, see if there
325 * is anything else we need to do
326 */
327
328 if (is_lastmsg(i2c)) {
329 /* last message, send stop and complete */
330 dev_dbg(i2c->dev, "READ: Send Stop\n");
331
332 nuc900_i2c_stop(i2c, 0);
333 } else {
334 /* go to the next transfer */
335 dev_dbg(i2c->dev, "READ: Next Transfer\n");
336
337 i2c->msg_ptr = 0;
338 i2c->msg_idx++;
339 i2c->msg++;
340
341 writel(I2C_CMD_READ, i2c->regs + CMDR);
342 }
343
344 } else {
345 writel(I2C_CMD_READ, i2c->regs + CMDR);
346 }
347
348 break;
349 }
350}
351
352/* nuc900_i2c_irq
353 *
354 * top level IRQ servicing routine
355*/
356
357static irqreturn_t nuc900_i2c_irq(int irqno, void *dev_id)
358{
359 struct nuc900_i2c *i2c = dev_id;
360 unsigned long status;
361
362 status = readl(i2c->regs + CSR);
363 writel(status | IRQFLAG, i2c->regs + CSR);
364
365 if (status & ARBIT_LOST) {
366 /* deal with arbitration loss */
367 dev_err(i2c->dev, "deal with arbitration loss\n");
368 goto out;
369 }
370
371 if (i2c->state == STATE_IDLE) {
372 dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
373 goto out;
374 }
375
376 /* pretty much this leaves us with the fact that we've
377 * transmitted or received whatever byte we last sent
378 */
379
380 i2c_nuc900_irq_nextbyte(i2c, status);
381
382 out:
383 return IRQ_HANDLED;
384}
385
386
387/* nuc900_i2c_set_master
388 *
389 * get the i2c bus for a master transaction
390*/
391
392static int nuc900_i2c_set_master(struct nuc900_i2c *i2c)
393{
394 int timeout = 400;
395
396 while (timeout-- > 0) {
397 if (((readl(i2c->regs + SWR) & I2CSTART) == I2CSTART) &&
398 ((readl(i2c->regs + CSR) & I2CBUSY) == 0)) {
399 return 0;
400 }
401
402 msleep(1);
403 }
404
405 return -ETIMEDOUT;
406}
407
408/* nuc900_i2c_doxfer
409 *
410 * this starts an i2c transfer
411*/
412
413static int nuc900_i2c_doxfer(struct nuc900_i2c *i2c,
414 struct i2c_msg *msgs, int num)
415{
416 unsigned long iicstat, timeout;
417 int spins = 20;
418 int ret;
419
420 ret = nuc900_i2c_set_master(i2c);
421 if (ret != 0) {
422 dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
423 ret = -EAGAIN;
424 goto out;
425 }
426
427 spin_lock_irq(&i2c->lock);
428
429 i2c->msg = msgs;
430 i2c->msg_num = num;
431 i2c->msg_ptr = 0;
432 i2c->msg_idx = 0;
433 i2c->state = STATE_START;
434
435 nuc900_i2c_message_start(i2c, msgs);
436 spin_unlock_irq(&i2c->lock);
437
438 timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
439
440 ret = i2c->msg_idx;
441
442 /* having these next two as dev_err() makes life very
443 * noisy when doing an i2cdetect
444 */
445
446 if (timeout == 0)
447 dev_dbg(i2c->dev, "timeout\n");
448 else if (ret != num)
449 dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
450
451 /* ensure the stop has been through the bus */
452
453 dev_dbg(i2c->dev, "waiting for bus idle\n");
454
455 /* first, try busy waiting briefly */
456 do {
457 iicstat = readl(i2c->regs + CSR);
458 } while ((iicstat & I2CBUSY) && --spins);
459
460 /* if that timed out sleep */
461 if (!spins) {
462 msleep(1);
463 iicstat = readl(i2c->regs + CSR);
464 }
465
466 if (iicstat & I2CBUSY)
467 dev_warn(i2c->dev, "timeout waiting for bus idle\n");
468
469 out:
470 return ret;
471}
472
473/* nuc900_i2c_xfer
474 *
475 * first port of call from the i2c bus code when an message needs
476 * transferring across the i2c bus.
477*/
478
479static int nuc900_i2c_xfer(struct i2c_adapter *adap,
480 struct i2c_msg *msgs, int num)
481{
482 struct nuc900_i2c *i2c = (struct nuc900_i2c *)adap->algo_data;
483 int retry;
484 int ret;
485
486 nuc900_i2c_enable_irq(i2c);
487
488 for (retry = 0; retry < adap->retries; retry++) {
489
490 ret = nuc900_i2c_doxfer(i2c, msgs, num);
491
492 if (ret != -EAGAIN)
493 return ret;
494
495 dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
496
497 udelay(100);
498 }
499
500 return -EREMOTEIO;
501}
502
503/* declare our i2c functionality */
504static u32 nuc900_i2c_func(struct i2c_adapter *adap)
505{
506 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
507}
508
509/* i2c bus registration info */
510
511static const struct i2c_algorithm nuc900_i2c_algorithm = {
512 .master_xfer = nuc900_i2c_xfer,
513 .functionality = nuc900_i2c_func,
514};
515
516/* nuc900_i2c_probe
517 *
518 * called by the bus driver when a suitable device is found
519*/
520
521static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
522{
523 struct nuc900_i2c *i2c;
524 struct nuc900_platform_i2c *pdata;
525 struct resource *res;
526 int ret;
527
528 pdata = pdev->dev.platform_data;
529 if (!pdata) {
530 dev_err(&pdev->dev, "no platform data\n");
531 return -EINVAL;
532 }
533
534 i2c = kzalloc(sizeof(struct nuc900_i2c), GFP_KERNEL);
535 if (!i2c) {
536 dev_err(&pdev->dev, "no memory for state\n");
537 return -ENOMEM;
538 }
539
540 strlcpy(i2c->adap.name, "nuc900-i2c0", sizeof(i2c->adap.name));
541 i2c->adap.owner = THIS_MODULE;
542 i2c->adap.algo = &nuc900_i2c_algorithm;
543 i2c->adap.retries = 2;
544 i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
545
546 spin_lock_init(&i2c->lock);
547 init_waitqueue_head(&i2c->wait);
548
549 /* find the clock and enable it */
550
551 i2c->dev = &pdev->dev;
552 i2c->clk = clk_get(&pdev->dev, NULL);
553 if (IS_ERR(i2c->clk)) {
554 dev_err(&pdev->dev, "cannot get clock\n");
555 ret = -ENOENT;
556 goto err_noclk;
557 }
558
559 dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
560
561 clk_enable(i2c->clk);
562
563 /* map the registers */
564
565 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
566 if (res == NULL) {
567 dev_err(&pdev->dev, "cannot find IO resource\n");
568 ret = -ENOENT;
569 goto err_clk;
570 }
571
572 i2c->ioarea = request_mem_region(res->start, resource_size(res),
573 pdev->name);
574
575 if (i2c->ioarea == NULL) {
576 dev_err(&pdev->dev, "cannot request IO\n");
577 ret = -ENXIO;
578 goto err_clk;
579 }
580
581 i2c->regs = ioremap(res->start, resource_size(res));
582
583 if (i2c->regs == NULL) {
584 dev_err(&pdev->dev, "cannot map IO\n");
585 ret = -ENXIO;
586 goto err_ioarea;
587 }
588
589 dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
590 i2c->regs, i2c->ioarea, res);
591
592 /* setup info block for the i2c core */
593
594 i2c->adap.algo_data = i2c;
595 i2c->adap.dev.parent = &pdev->dev;
596
597 mfp_set_groupg(&pdev->dev);
598
599 clk_get_rate(i2c->clk);
600
601 ret = (i2c->clk.apbfreq)/(pdata->bus_freq * 5) - 1;
602 writel(ret & 0xffff, i2c->regs + DIVIDER);
603
604 /* find the IRQ for this unit (note, this relies on the init call to
605 * ensure no current IRQs pending
606 */
607
608 i2c->irq = ret = platform_get_irq(pdev, 0);
609 if (ret <= 0) {
610 dev_err(&pdev->dev, "cannot find IRQ\n");
611 goto err_iomap;
612 }
613
614 ret = request_irq(i2c->irq, nuc900_i2c_irq, IRQF_DISABLED | IRQF_SHARED,
615 dev_name(&pdev->dev), i2c);
616
617 if (ret != 0) {
618 dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
619 goto err_iomap;
620 }
621
622 /* Note, previous versions of the driver used i2c_add_adapter()
623 * to add the bus at any number. We now pass the bus number via
624 * the platform data, so if unset it will now default to always
625 * being bus 0.
626 */
627
628 i2c->adap.nr = pdata->bus_num;
629
630 ret = i2c_add_numbered_adapter(&i2c->adap);
631 if (ret < 0) {
632 dev_err(&pdev->dev, "failed to add bus to i2c core\n");
633 goto err_irq;
634 }
635
636 platform_set_drvdata(pdev, i2c);
637
638 dev_info(&pdev->dev, "%s: NUC900 I2C adapter\n",
639 dev_name(&i2c->adap.dev));
640 return 0;
641
642 err_irq:
643 free_irq(i2c->irq, i2c);
644
645 err_iomap:
646 iounmap(i2c->regs);
647
648 err_ioarea:
649 release_resource(i2c->ioarea);
650 kfree(i2c->ioarea);
651
652 err_clk:
653 clk_disable(i2c->clk);
654 clk_put(i2c->clk);
655
656 err_noclk:
657 kfree(i2c);
658 return ret;
659}
660
661/* nuc900_i2c_remove
662 *
663 * called when device is removed from the bus
664*/
665
666static int __devexit nuc900_i2c_remove(struct platform_device *pdev)
667{
668 struct nuc900_i2c *i2c = platform_get_drvdata(pdev);
669
670 i2c_del_adapter(&i2c->adap);
671 free_irq(i2c->irq, i2c);
672
673 clk_disable(i2c->clk);
674 clk_put(i2c->clk);
675
676 iounmap(i2c->regs);
677
678 release_resource(i2c->ioarea);
679 kfree(i2c->ioarea);
680 kfree(i2c);
681
682 return 0;
683}
684
685static struct platform_driver nuc900_i2c_driver = {
686 .probe = nuc900_i2c_probe,
687 .remove = __devexit_p(nuc900_i2c_remove),
688 .driver = {
689 .owner = THIS_MODULE,
690 .name = "nuc900-i2c0",
691 },
692};
693
694static int __init i2c_adap_nuc900_init(void)
695{
696 return platform_driver_register(&nuc900_i2c_driver);
697}
698
699static void __exit i2c_adap_nuc900_exit(void)
700{
701 platform_driver_unregister(&nuc900_i2c_driver);
702}
703subsys_initcall(i2c_adap_nuc900_init);
704module_exit(i2c_adap_nuc900_exit);
705
706MODULE_DESCRIPTION("NUC900 I2C Bus driver");
707MODULE_AUTHOR("Wan ZongShun, <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
708MODULE_LICENSE("GPL");
709MODULE_ALIAS("platform:nuc900-i2c0");