]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/i2c/chips/pca9535.c
h63xx: pca9535 support.
[linux-2.6-omap-h63xx.git] / drivers / i2c / chips / pca9535.c
1 /*
2  * drivers/i2c/chips/pca9535.c
3  *
4  * Driver for Philips PCA9535 16-bit low power I/O port with interrupt.
5  * Tested with OMAP-1510 based iPAQ h63xx series of mobile phones.
6  * (h6315, h6340 and h6365)
7  *
8  * Copyright (C) 2009 Mika Laitio
9  * Copyright (C) 2009 Husam Senussi
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *  
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *  
25  * Copyright (C) 2005 Husam Senussi
26  * Framework based on Pawel Kolodziejski's pca9535 driver in 
27  * handheld.org's 2.6.13 kernel. Driver updated by Mika Laitio.
28  */
29
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/slab.h>
33 #include <linux/i2c.h>
34 #include <linux/hwmon-sysfs.h>
35 #include <linux/hwmon.h>
36 #include <linux/err.h>
37
38 #include <asm/arch/pca9535.h>
39 #include <linux/delay.h>
40
41 #include <linux/interrupt.h>
42 #include <asm/mach-types.h>
43 #include <asm/irq.h>
44 #include <asm/mach/arch.h>
45 #include <asm/hardware.h>
46
47 EXPORT_SYMBOL(pca9535_gpio_read);
48 EXPORT_SYMBOL(pca9535_gpio_write);
49 EXPORT_SYMBOL(pca9535_gpio_direction);
50
51 static int pca9535_attach_adapter(struct i2c_adapter *adapter);
52 static int pca9535_detach_client(struct i2c_client *client);
53 static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one);
54 static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr);
55 static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 param);
56
57 enum pca9535_cmd
58 {
59         PCA9535_INPUT_0         = 0,
60         PCA9535_INPUT_1         = 1,
61         PCA9535_OUTPUT_0        = 2,
62         PCA9535_OUTPUT_1        = 3,
63         PCA9535_INVERT_0        = 4,
64         PCA9535_INVERT_1        = 5,
65         PCA9535_DIRECTION_0     = 6,
66         PCA9535_DIRECTION_1     = 7,
67 };
68
69 struct pca9535_data {
70         struct semaphore  lock;
71         struct i2c_client client;
72 };
73
74 static struct i2c_driver pca9535_driver = {
75         .driver = {
76                 .name   = "pca9535",
77         },
78         .attach_adapter         = pca9535_attach_adapter,
79         .detach_client          = pca9535_detach_client,
80 };
81
82 static struct i2c_client   *pca9535_i2c_client = NULL;
83 static struct pca9535_data pca9535_inited;
84
85 static unsigned short normal_i2c[] = { 0x20, I2C_CLIENT_END };
86
87 #define DRIVER_VERSION  "20 OCT 2005"
88 #define DRIVER_NAME     "PCA9535"
89
90 /* 
91  * sysfs callback function.
92  */ 
93 static ssize_t pca9535_show(struct device *dev, struct device_attribute *attr,
94                             char *buf)
95 {
96         struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
97         struct i2c_client *client = to_i2c_client(dev);
98         return sprintf(buf, "%02X\n", (pca9535_read_reg(client, psa->index) >> 8));
99 }
100
101 /* 
102  * sysfs callback function.
103  */ 
104 static ssize_t pca9535_store(struct device *dev, struct device_attribute *attr,
105                              const char *buf, size_t count)
106 {
107         struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
108         struct i2c_client *client = to_i2c_client(dev);
109         unsigned long val = simple_strtoul(buf, NULL, 0);
110         unsigned long old = pca9535_read_reg(client, psa->index);
111
112         if (val > 0xff)
113                 return -EINVAL;
114         
115         val = (old & 0xff) | (val << 8);
116         pca9535_write_reg(client, psa->index, val);
117         return count;
118 }
119
120 #define PCA9535_ENTRY_RO(name, cmd_idx) \
121         static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9535_show, NULL, cmd_idx)
122
123 #define PCA9535_ENTRY_RW(name, cmd_idx) \
124         static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9535_show, \
125                                   pca9535_store, cmd_idx)
126
127 PCA9535_ENTRY_RO(input0, PCA9535_INPUT_0);
128 PCA9535_ENTRY_RO(input1, PCA9535_INPUT_1);
129 PCA9535_ENTRY_RW(output0, PCA9535_OUTPUT_0);
130 PCA9535_ENTRY_RW(output1, PCA9535_OUTPUT_1);
131 PCA9535_ENTRY_RW(invert0, PCA9535_INVERT_0);
132 PCA9535_ENTRY_RW(invert1, PCA9535_INVERT_1);
133 PCA9535_ENTRY_RW(direction0, PCA9535_DIRECTION_0);
134 PCA9535_ENTRY_RW(direction1, PCA9535_DIRECTION_1);
135
136 static struct attribute *pca9535_attributes[] = {
137         &sensor_dev_attr_input0.dev_attr.attr,
138         &sensor_dev_attr_input1.dev_attr.attr,
139         &sensor_dev_attr_output0.dev_attr.attr,
140         &sensor_dev_attr_output1.dev_attr.attr,
141         &sensor_dev_attr_invert0.dev_attr.attr,
142         &sensor_dev_attr_invert1.dev_attr.attr,
143         &sensor_dev_attr_direction0.dev_attr.attr,
144         &sensor_dev_attr_direction1.dev_attr.attr,
145         NULL
146 };
147
148 static struct attribute_group pca9535_defattr_group = {
149         .attrs = pca9535_attributes,
150 };
151 //End of sysfs management code. 
152
153 I2C_CLIENT_INSMOD;
154
155 u32 pca9535_read_input(void)
156 {
157         return pca9535_read_reg(pca9535_i2c_client, 0);
158 }
159 EXPORT_SYMBOL(pca9535_read_input);
160
161 void pca9535_write_output(u16 param)
162 {
163         pca9535_write_reg(pca9535_i2c_client, 2, param);
164 }
165 EXPORT_SYMBOL(pca9535_write_output);
166
167 void pca9535_set_dir(u16 param)
168 {
169         pca9535_write_reg(pca9535_i2c_client, 6, param);
170 }
171 EXPORT_SYMBOL(pca9535_set_dir);
172
173 static int pca9535_attach_adapter(struct i2c_adapter *adapter)
174 {
175         return i2c_probe(adapter, &addr_data, pca9535_attach);
176 }
177
178 static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one)
179 {
180         struct i2c_client *new_client;
181         int err = 0;
182
183         new_client = &(pca9535_inited.client);
184         i2c_set_clientdata(new_client, 0);
185         new_client->addr = address;
186         new_client->adapter = adapter;
187         new_client->driver = &pca9535_driver;
188         strcpy(new_client->name, DRIVER_NAME);
189
190         if ((err = i2c_attach_client(new_client)))
191                 goto exit_free;
192
193         pca9535_i2c_client = new_client;
194         
195         init_MUTEX(&pca9535_inited.lock);
196         i2c_set_clientdata(pca9535_i2c_client, &pca9535_inited);
197         
198         sysfs_create_group(&pca9535_i2c_client->dev.kobj, &pca9535_defattr_group);
199         
200         printk("pca9535_attach() ok, address = %d, zero_or_minus_one = %d\n", address, zero_or_minus_one);
201         return 0;
202
203 exit_free:
204         printk("pca9535_attach() failed, error code = %d\n", err);
205         return err;
206 }
207
208 static int pca9535_detach_client(struct i2c_client *client)
209 {
210         int err;
211
212         if ((err = i2c_detach_client(client))) {
213                 dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
214                 return err;
215         }
216         pca9535_i2c_client = NULL;
217
218         return 0;
219 }
220
221 static int __init pca9535_init(void)
222 {
223         return i2c_add_driver(&pca9535_driver);
224 }
225
226 static void __exit pca9535_exit(void)
227 {
228         i2c_del_driver(&pca9535_driver);
229 }
230
231 /* 
232  * Reads the value of GPIO available via I2C.
233  */
234 int pca9535_gpio_read(int gpio){
235         unsigned char reg = 0;
236         unsigned long val = 0;
237
238         printk("9535_gpio_read() called\n");
239         if(!pca9535_i2c_client)
240                 return -ENODEV;
241
242         if(gpio < GPIO0 || gpio > GPIO17)
243                 return -EINVAL;
244
245         if(gpio >= GPIO0 && gpio <= GPIO7){
246                 reg      = PCA9535_INPUT_0;
247                 gpio    -= GPIO0;
248         }else if(gpio >= GPIO8 && gpio <= GPIO17){
249                 reg      = PCA9535_INPUT_1;
250                 gpio    -= GPIO8;
251         }
252
253         down(&pca9535_inited.lock);
254
255         // Read the existing values first
256         val = pca9535_read_reg(pca9535_i2c_client, reg) >> 8;
257         val = (val >> gpio) & 0x01;
258
259         up(&pca9535_inited.lock);
260
261         return val;
262 }
263
264 /* 
265  * Set the value of I2C GPIO.
266  */
267 int pca9535_gpio_write(int gpio, unsigned char value){
268         unsigned char in_reg  = 0;
269         unsigned char out_reg = 0;
270         unsigned long val = 0;
271         unsigned long old = 0;
272         int           ret = 0;
273
274         if(!pca9535_i2c_client)
275                 return -ENODEV;
276
277         if(gpio < GPIO0 || gpio > GPIO17)
278                 return -EINVAL;
279
280         if(gpio >= GPIO0 && gpio <= GPIO7){
281                 in_reg   = PCA9535_INPUT_0;
282                 out_reg  = PCA9535_OUTPUT_0;
283                 gpio    -= GPIO0;
284         }else if(gpio >= GPIO8 && gpio <= GPIO17){
285                 in_reg   = PCA9535_INPUT_1;
286                 out_reg  = PCA9535_OUTPUT_1;
287                 gpio    -= GPIO8;
288         }
289
290         down(&pca9535_inited.lock);
291
292         // Read the existing values first
293         val = pca9535_read_reg(pca9535_i2c_client, in_reg);
294         old = val >> 8;
295
296         switch(value){
297         case LOW:
298                 old |= (1 << gpio);
299                 break;
300         case HI:
301                 old &= ~(1 << gpio);
302                 break;
303         default:
304                 ret = -EINVAL;
305                 goto error;
306         }
307
308         val = (val & 0xff) | (old << 8);        
309
310         // write the values back to the register
311         pca9535_write_reg(pca9535_i2c_client, out_reg, val);
312 error:
313
314         up(&pca9535_inited.lock);
315         return ret;
316 }
317
318 /*
319  * Set the direction of I2C GPIO.
320  */ 
321 int pca9535_gpio_direction(int gpio, unsigned char direction){
322         unsigned char reg = 0;
323         unsigned long val = 0;
324         unsigned long old = 0;
325         int           ret = 0;
326
327         if(!pca9535_i2c_client)
328                 return -ENODEV;
329
330         if(gpio < GPIO0 || gpio > GPIO17)
331                 return -EINVAL;
332
333         if(gpio >= GPIO0 && gpio <= GPIO7){
334                 reg      = PCA9535_DIRECTION_0;
335                 gpio    -= GPIO0;
336         }else if(gpio >= GPIO8 && gpio <= GPIO17){
337                 reg      = PCA9535_DIRECTION_1;
338                 gpio    -= GPIO8;
339         }
340
341         down(&pca9535_inited.lock);
342
343         // Read the existing values first
344         old = pca9535_read_reg(pca9535_i2c_client, reg);
345         val = old >> 8;
346
347         switch(direction){
348         case GPIO_INPUT: 
349                 val |= (1 << gpio);
350                 break;
351         case GPIO_OUTPUT: 
352                 val &= ~(1 << gpio);
353                 break;
354         default:
355                 ret = -EINVAL;
356                 goto error;
357         }
358
359         val = (old & 0xff) | (val << 8);
360
361         // write the values back to the register
362         pca9535_write_reg(pca9535_i2c_client, reg, val);
363 error:
364
365         up(&pca9535_inited.lock);
366         return ret;
367 }
368
369 static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr)
370 {
371         char buffer[3];
372         int r;
373         u32 data;
374
375         buffer[0] = regaddr;
376         buffer[1] = 0;
377         buffer[2] = 0;
378
379         r = i2c_master_send(client, buffer, 1);
380         if (r != 1) {
381                 printk(KERN_ERR "pca9535: read failed, status %d\n", r);
382                 return 0xffffffff;
383         }
384
385         r = i2c_master_recv(client, buffer, 3);
386         if (r != 3) {
387                 printk(KERN_ERR "pca9535: read failed, status %d\n", r);
388                 return 0xffffffff;
389         }
390
391         data = buffer[1];
392         data |= buffer[2] << 8;
393         //printk(KERN_ERR "%s: reading %x in %x\n", __FUNCTION__, data, regaddr);
394
395         return data;
396 }
397
398 static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 data)
399 {
400         char buffer[3];
401         int r;
402
403         //printk(KERN_ERR "%s: writing %x in %x\n", __FUNCTION__, data, regaddr);
404         buffer[0] = regaddr;
405         buffer[1] = data >> 8;
406         buffer[2] = data & 0xff;
407
408         r = i2c_master_send(client, buffer, 3);
409         if (r != 3) {
410                 printk(KERN_ERR "pca9535: write failed, status %d\n", r);
411         }
412 }
413
414 MODULE_AUTHOR("Husam Senussi <husamsenussi@gmail.com>");
415 MODULE_DESCRIPTION("PCA9535 driver");
416 MODULE_LICENSE("GPL");
417
418 module_init(pca9535_init);
419 module_exit(pca9535_exit);