First hack to test the touch sensor. Sets some defaults. Read registers back with...
[freerunner-navigation-board:mpr121.git] / kernel / mpr121.c
1 /*  Copyright (c) 2010  Christoph Mair <christoph.mair@gmail.com>
2
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation; either version 2 of the License, or
6     (at your option) any later version.
7
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/i2c.h>
22 #include <linux/delay.h>
23 #include <linux/slab.h>
24
25
26 #define MPR121_I2C_ADDRESS              0x5A
27
28 #define MPR121_CLIENT_NAME              "mpr121"
29
30
31 static const unsigned short normal_i2c[] = { MPR121_I2C_ADDRESS,
32                                                         I2C_CLIENT_END };
33
34 /* Each client has this additional data */
35 struct mpr121_data {
36         struct i2c_client *client;
37 };
38
39
40 static s32 mpr121_quick_init(struct i2c_client *client)
41 {
42   
43         u8 block1[8] = { 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0xFF, 0x02 };
44         u8 block2[24] = { 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A, 0x0F, 0x0A };
45         u8 block3[1] = { 0x04 };
46         u8 block4[1] = { 0x0B };
47         u8 block5[3] = { 0x9C, 0x65, 0x8C };
48         u8 block6[1] = { 0x0C };
49         printk(KERN_INFO "mpr121_quick_init");
50         i2c_smbus_write_block_data(client, 0x2A, sizeof(block1), block1);
51         i2c_smbus_write_block_data(client, 0x41, sizeof(block2), block2);
52         i2c_smbus_write_block_data(client, 0x5D, sizeof(block3), block3);
53         i2c_smbus_write_block_data(client, 0x7B, sizeof(block4), block4);
54         i2c_smbus_write_block_data(client, 0x7D, sizeof(block5), block5);
55         i2c_smbus_write_block_data(client, 0x5E, sizeof(block6), block6);
56         printk(KERN_INFO "mpr121_quick_init done");
57         return 0;
58 }
59
60
61
62 static struct attribute *mpr121_attributes[] = {
63         NULL
64 };
65
66 static const struct attribute_group mpr121_attr_group = {
67         .attrs = mpr121_attributes,
68 };
69
70
71 static int mpr121_init_client(struct i2c_client *client)
72 {
73         struct mpr121_data *data = i2c_get_clientdata(client);
74         data->client = client;
75         mpr121_quick_init(client);
76         dev_info(&data->client->dev, "MPR121 initialized.\n");
77         return 0;
78 }
79
80 static int mpr121_probe(struct i2c_client *client,
81                          const struct i2c_device_id *id)
82 {
83         struct mpr121_data *data;
84         int err = 0;
85
86         printk(KERN_INFO "mpr121 probe");
87         
88         if (client->addr != MPR121_I2C_ADDRESS) {
89                 err = -ENOMEM;
90                 goto exit;
91         }
92         
93         data = kzalloc(sizeof(struct mpr121_data), GFP_KERNEL);
94         if (!data) {
95                 err = -ENOMEM;
96                 goto exit;
97         }
98
99         i2c_set_clientdata(client, data);
100
101         /* Initialize the MPR121 chip */
102         err = mpr121_init_client(client);
103         if (err != 0)
104                 goto exit_free;
105
106         /* Register sysfs hooks */
107         err = sysfs_create_group(&client->dev.kobj, &mpr121_attr_group);
108         if (err)
109                 goto exit_free;
110
111         dev_info(&data->client->dev, "Succesfully initialized mpr121!\n");
112         goto exit;
113
114 exit_free:
115         kfree(data);
116 exit:
117         return err;
118 }
119
120 static int mpr121_remove(struct i2c_client *client)
121 {
122         sysfs_remove_group(&client->dev.kobj, &mpr121_attr_group);
123         kfree(i2c_get_clientdata(client));
124         return 0;
125 }
126
127 static const struct i2c_device_id mpr121_id[] = {
128         { "mpr121", 0 },
129         { }
130 };
131
132 static struct i2c_driver mpr121_driver = {
133         .driver = {
134                 .owner = THIS_MODULE,
135                 .name   = "mpr121"
136         },
137         .id_table       = mpr121_id,
138         .probe          = mpr121_probe,
139         .remove         = mpr121_remove,
140         .id_table       = mpr121_id
141 };
142
143 static int __init mpr121_init(void)
144 {
145         return i2c_add_driver(&mpr121_driver);
146 }
147
148 static void __exit mpr121_exit(void)
149 {
150         i2c_del_driver(&mpr121_driver);
151 }
152
153
154 MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
155 MODULE_DESCRIPTION("MPR121 driver");
156 MODULE_LICENSE("GPL");
157
158 module_init(mpr121_init);
159 module_exit(mpr121_exit);