4 * Platform driver for the PCA9564 I2C controller.
6 * Copyright (C) 2008 Pengutronix
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <linux/delay.h>
18 #include <linux/jiffies.h>
19 #include <linux/errno.h>
20 #include <linux/i2c.h>
21 #include <linux/interrupt.h>
22 #include <linux/platform_device.h>
23 #include <linux/i2c-algo-pca.h>
24 #include <linux/i2c-pca-platform.h>
25 #include <linux/gpio.h>
30 struct i2c_pca_pf_data
{
31 void __iomem
*reg_base
;
32 int irq
; /* if 0, use polling */
34 wait_queue_head_t wait
;
35 struct i2c_adapter adap
;
36 struct i2c_algo_pca_data algo_data
;
37 unsigned long io_base
;
38 unsigned long io_size
;
41 /* Read/Write functions for different register alignments */
43 static int i2c_pca_pf_readbyte8(void *pd
, int reg
)
45 struct i2c_pca_pf_data
*i2c
= pd
;
46 return ioread8(i2c
->reg_base
+ reg
);
49 static int i2c_pca_pf_readbyte16(void *pd
, int reg
)
51 struct i2c_pca_pf_data
*i2c
= pd
;
52 return ioread8(i2c
->reg_base
+ reg
* 2);
55 static int i2c_pca_pf_readbyte32(void *pd
, int reg
)
57 struct i2c_pca_pf_data
*i2c
= pd
;
58 return ioread8(i2c
->reg_base
+ reg
* 4);
61 static void i2c_pca_pf_writebyte8(void *pd
, int reg
, int val
)
63 struct i2c_pca_pf_data
*i2c
= pd
;
64 iowrite8(val
, i2c
->reg_base
+ reg
);
67 static void i2c_pca_pf_writebyte16(void *pd
, int reg
, int val
)
69 struct i2c_pca_pf_data
*i2c
= pd
;
70 iowrite8(val
, i2c
->reg_base
+ reg
* 2);
73 static void i2c_pca_pf_writebyte32(void *pd
, int reg
, int val
)
75 struct i2c_pca_pf_data
*i2c
= pd
;
76 iowrite8(val
, i2c
->reg_base
+ reg
* 4);
80 static int i2c_pca_pf_waitforcompletion(void *pd
)
82 struct i2c_pca_pf_data
*i2c
= pd
;
84 unsigned long timeout
;
87 ret
= wait_event_interruptible_timeout(i2c
->wait
,
88 i2c
->algo_data
.read_byte(i2c
, I2C_PCA_CON
)
89 & I2C_PCA_CON_SI
, i2c
->adap
.timeout
);
92 timeout
= jiffies
+ i2c
->adap
.timeout
;
93 while (((i2c
->algo_data
.read_byte(i2c
, I2C_PCA_CON
)
94 & I2C_PCA_CON_SI
) == 0)
95 && (ret
= time_before(jiffies
, timeout
)))
102 static void i2c_pca_pf_dummyreset(void *pd
)
104 struct i2c_pca_pf_data
*i2c
= pd
;
105 printk(KERN_WARNING
"%s: No reset-pin found. Chip may get stuck!\n",
109 static void i2c_pca_pf_resetchip(void *pd
)
111 struct i2c_pca_pf_data
*i2c
= pd
;
113 gpio_set_value(i2c
->gpio
, 0);
115 gpio_set_value(i2c
->gpio
, 1);
118 static irqreturn_t
i2c_pca_pf_handler(int this_irq
, void *dev_id
)
120 struct i2c_pca_pf_data
*i2c
= dev_id
;
122 if ((i2c
->algo_data
.read_byte(i2c
, I2C_PCA_CON
) & I2C_PCA_CON_SI
) == 0)
125 wake_up_interruptible(&i2c
->wait
);
131 static int __devinit
i2c_pca_pf_probe(struct platform_device
*pdev
)
133 struct i2c_pca_pf_data
*i2c
;
134 struct resource
*res
;
135 struct i2c_pca9564_pf_platform_data
*platform_data
=
136 pdev
->dev
.platform_data
;
140 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
141 irq
= platform_get_irq(pdev
, 0);
142 /* If irq is 0, we do polling. */
149 if (!request_mem_region(res
->start
, resource_size(res
), res
->name
)) {
154 i2c
= kzalloc(sizeof(struct i2c_pca_pf_data
), GFP_KERNEL
);
160 init_waitqueue_head(&i2c
->wait
);
162 i2c
->reg_base
= ioremap(res
->start
, resource_size(res
));
163 if (!i2c
->reg_base
) {
167 i2c
->io_base
= res
->start
;
168 i2c
->io_size
= resource_size(res
);
171 i2c
->adap
.nr
= pdev
->id
>= 0 ? pdev
->id
: 0;
172 i2c
->adap
.owner
= THIS_MODULE
;
173 snprintf(i2c
->adap
.name
, sizeof(i2c
->adap
.name
),
174 "PCA9564/PCA9665 at 0x%08lx",
175 (unsigned long) res
->start
);
176 i2c
->adap
.algo_data
= &i2c
->algo_data
;
177 i2c
->adap
.dev
.parent
= &pdev
->dev
;
180 i2c
->adap
.timeout
= platform_data
->timeout
;
181 i2c
->algo_data
.i2c_clock
= platform_data
->i2c_clock_speed
;
182 i2c
->gpio
= platform_data
->gpio
;
184 i2c
->adap
.timeout
= HZ
;
185 i2c
->algo_data
.i2c_clock
= 59000;
189 i2c
->algo_data
.data
= i2c
;
190 i2c
->algo_data
.wait_for_completion
= i2c_pca_pf_waitforcompletion
;
191 i2c
->algo_data
.reset_chip
= i2c_pca_pf_dummyreset
;
193 switch (res
->flags
& IORESOURCE_MEM_TYPE_MASK
) {
194 case IORESOURCE_MEM_32BIT
:
195 i2c
->algo_data
.write_byte
= i2c_pca_pf_writebyte32
;
196 i2c
->algo_data
.read_byte
= i2c_pca_pf_readbyte32
;
198 case IORESOURCE_MEM_16BIT
:
199 i2c
->algo_data
.write_byte
= i2c_pca_pf_writebyte16
;
200 i2c
->algo_data
.read_byte
= i2c_pca_pf_readbyte16
;
202 case IORESOURCE_MEM_8BIT
:
204 i2c
->algo_data
.write_byte
= i2c_pca_pf_writebyte8
;
205 i2c
->algo_data
.read_byte
= i2c_pca_pf_readbyte8
;
209 /* Use gpio_is_valid() when in mainline */
210 if (i2c
->gpio
> -1) {
211 ret
= gpio_request(i2c
->gpio
, i2c
->adap
.name
);
213 gpio_direction_output(i2c
->gpio
, 1);
214 i2c
->algo_data
.reset_chip
= i2c_pca_pf_resetchip
;
216 printk(KERN_WARNING
"%s: Registering gpio failed!\n",
223 ret
= request_irq(irq
, i2c_pca_pf_handler
,
224 IRQF_TRIGGER_FALLING
, i2c
->adap
.name
, i2c
);
229 if (i2c_pca_add_numbered_bus(&i2c
->adap
) < 0) {
234 platform_set_drvdata(pdev
, i2c
);
236 printk(KERN_INFO
"%s registered.\n", i2c
->adap
.name
);
245 gpio_free(i2c
->gpio
);
247 iounmap(i2c
->reg_base
);
251 release_mem_region(res
->start
, resource_size(res
));
253 printk(KERN_ERR
"Registering PCA9564/PCA9665 FAILED! (%d)\n", ret
);
257 static int __devexit
i2c_pca_pf_remove(struct platform_device
*pdev
)
259 struct i2c_pca_pf_data
*i2c
= platform_get_drvdata(pdev
);
260 platform_set_drvdata(pdev
, NULL
);
262 i2c_del_adapter(&i2c
->adap
);
265 free_irq(i2c
->irq
, i2c
);
268 gpio_free(i2c
->gpio
);
270 iounmap(i2c
->reg_base
);
271 release_mem_region(i2c
->io_base
, i2c
->io_size
);
277 static struct platform_driver i2c_pca_pf_driver
= {
278 .probe
= i2c_pca_pf_probe
,
279 .remove
= __devexit_p(i2c_pca_pf_remove
),
281 .name
= "i2c-pca-platform",
282 .owner
= THIS_MODULE
,
286 static int __init
i2c_pca_pf_init(void)
288 return platform_driver_register(&i2c_pca_pf_driver
);
291 static void __exit
i2c_pca_pf_exit(void)
293 platform_driver_unregister(&i2c_pca_pf_driver
);
296 MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
297 MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
298 MODULE_LICENSE("GPL");
300 module_init(i2c_pca_pf_init
);
301 module_exit(i2c_pca_pf_exit
);