]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/mfd/da9052-i2c.c
mx53: CPU HW idle state set to WAIT_CLOCKED
[linux-imx.git] / drivers / mfd / da9052-i2c.c
1 /*
2  * Copyright(c) 2009 Dialog Semiconductor Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * da9052-i2c.c: I2C SSC (Synchronous Serial Communication) driver for DA9052
10  */
11
12 #include <linux/device.h>
13 #include <linux/mfd/core.h>
14 #include <linux/i2c.h>
15 #include <linux/mfd/da9052/da9052.h>
16 #include <linux/mfd/da9052/reg.h>
17
18 static struct da9052 *da9052_i2c;
19
20 #define I2C_CONNECTED 0
21
22 static int da9052_i2c_is_connected(void)
23 {
24         struct da9052_ssc_msg msg;
25         int retries = 10, ret = -1;
26
27         msg.addr = DA9052_INTERFACE_REG;
28         do {
29                 /* Test i2c connectivity by reading the GPIO_0-1 register */
30                 if (0 != da9052_i2c_read(da9052_i2c, &msg)) {
31                         printk(KERN_INFO"da9052_i2c_is_connected - i2c read failed.....\n");
32                 } else {
33                         printk(KERN_INFO"da9052_i2c_is_connected - i2c read success....\n");
34                         ret = 0;
35                 }
36         } while (ret != 0 && retries--);
37
38         return ret;
39 }
40
41 static int __devinit da9052_i2c_probe(struct i2c_client *client,
42         const struct i2c_device_id *id)
43 {
44         struct i2c_adapter *adapter;
45         // printk("\n\tEntered da9052_i2c_is_probe.............\n");
46
47         da9052_i2c = kzalloc(sizeof(struct da9052), GFP_KERNEL);
48
49         if (!da9052_i2c)
50                 return -ENOMEM;
51
52         /* Get the bus driver handler */
53         adapter = to_i2c_adapter(client->dev.parent);
54
55         /* Check i2c bus driver supports byte data transfer */
56         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
57                 dev_info(&client->dev,\
58                 "Error in %s:i2c_check_functionality\n", __func__);
59                 return -ENODEV;;
60         }
61
62         /* Store handle to i2c client */
63         da9052_i2c->i2c_client = client;
64         da9052_i2c->irq = client->irq;
65
66         da9052_i2c->dev = &client->dev;
67
68         /* Initialize i2c data structure here*/
69         da9052_i2c->adapter = adapter;
70
71         /* host i2c driver looks only first 7 bits for the slave address */
72         da9052_i2c->slave_addr = DA9052_I2C_ADDR >> 1;
73
74         /* Store the i2c client data */
75         i2c_set_clientdata(client, da9052_i2c);
76
77          /* Validate I2C connectivity */
78         if ( I2C_CONNECTED  == da9052_i2c_is_connected()) {
79                 /* I2C is connected */
80                 da9052_i2c->connecting_device = I2C;
81                 if( 0!= da9052_ssc_init(da9052_i2c) )
82                         return -ENODEV;
83         }
84         else {
85                 return -ENODEV;
86         }
87
88         //printk("Exiting da9052_i2c_probe.....\n");
89
90         return 0;
91 }
92
93 static int da9052_i2c_remove(struct i2c_client *client)
94 {
95
96         struct da9052 *da9052 = i2c_get_clientdata(client);
97
98         mfd_remove_devices(da9052->dev);
99         kfree(da9052);
100         return 0;
101 }
102
103 int da9052_i2c_write(struct da9052 *da9052, struct da9052_ssc_msg *msg)
104 {
105         struct i2c_msg i2cmsg;
106         unsigned char buf[2] = {0};
107         int ret = 0;
108
109         /* Copy the ssc msg to local character buffer */
110         buf[0] = msg->addr;
111         buf[1] = msg->data;
112
113         /*Construct a i2c msg for a da9052 driver ssc message request */
114         i2cmsg.addr  = da9052->slave_addr;
115         i2cmsg.len   = 2;
116         i2cmsg.buf   = buf;
117
118         /* To write the data on I2C set flag to zero */
119         i2cmsg.flags = 0;
120
121         /* Start the i2c transfer by calling host i2c driver function */
122         ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
123
124         if (ret < 0) {
125                 dev_info(&da9052->i2c_client->dev,\
126                 "_%s:master_xfer Failed!!\n", __func__);
127                 return ret;
128         }
129
130         return 0;
131 }
132
133 int da9052_i2c_read(struct da9052 *da9052, struct da9052_ssc_msg *msg)
134 {
135
136         /*Get the da9052_i2c client details*/
137         unsigned char buf[2] = {0, 0};
138         struct i2c_msg i2cmsg[2];
139         int ret = 0;
140
141         /* Copy SSC Msg to local character buffer */
142         buf[0] = msg->addr;
143
144         /*Construct a i2c msg for a da9052 driver ssc message request */
145         i2cmsg[0].addr  = da9052->slave_addr ;
146         i2cmsg[0].len   = 1;
147         i2cmsg[0].buf   = &buf[0];
148
149         /*To write the data on I2C set flag to zero */
150         i2cmsg[0].flags = 0;
151
152         /* Read the data from da9052*/
153         /*Construct a i2c msg for a da9052 driver ssc message request */
154         i2cmsg[1].addr  = da9052->slave_addr ;
155         i2cmsg[1].len   = 1;
156         i2cmsg[1].buf   = &buf[1];
157
158         /*To read the data on I2C set flag to I2C_M_RD */
159         i2cmsg[1].flags = I2C_M_RD;
160
161         /* Start the i2c transfer by calling host i2c driver function */
162         ret = i2c_transfer(da9052->adapter, i2cmsg, 2);
163         if (ret < 0) {
164                 dev_info(&da9052->i2c_client->dev,\
165                 "2 - %s:master_xfer Failed!!\n", __func__);
166                 return ret;
167         }
168
169         msg->data = *i2cmsg[1].buf;
170
171         return 0;
172 }
173
174 int da9052_i2c_write_many(struct da9052 *da9052,
175         struct da9052_ssc_msg *sscmsg, int msg_no)
176 {
177
178         struct i2c_msg i2cmsg;
179         unsigned char data_buf[MAX_READ_WRITE_CNT+1];
180         struct da9052_ssc_msg ctrlb_msg;
181         struct da9052_ssc_msg *msg_queue = sscmsg;
182         int ret = 0;
183         /* Flag to check if requested registers are contiguous */
184         unsigned char cont_data = 1;
185         unsigned char cnt = 0;
186
187         /* Check if requested registers are contiguous */
188         for (cnt = 1; cnt < msg_no; cnt++) {
189                 if ((msg_queue[cnt].addr - msg_queue[cnt-1].addr) != 1) {
190                         /* Difference is not 1, i.e. non-contiguous registers */
191                         cont_data = 0;
192                         break;
193                 }
194         }
195
196         if (cont_data == 0) {
197                 /* Requested registers are non-contiguous */
198                 for (cnt = 0; cnt < msg_no; cnt++) {
199                         ret = da9052->write(da9052, &msg_queue[cnt]);
200                         if (ret != 0)
201                                 return ret;
202                 }
203                 return 0;
204         }
205         /*
206         *  Requested registers are contiguous
207         * or PAGE WRITE sequence of I2C transactions is as below
208         * (slave_addr + reg_addr + data_1 + data_2 + ...)
209         * First read current WRITE MODE via CONTROL_B register of DA9052
210         */
211         ctrlb_msg.addr = DA9052_CONTROLB_REG;
212         ctrlb_msg.data = 0x0;
213         ret = da9052->read(da9052, &ctrlb_msg);
214
215         if (ret != 0)
216                 return ret;
217
218         /* Check if PAGE WRITE mode is set */
219         if (ctrlb_msg.data & DA9052_CONTROLB_WRITEMODE) {
220                 /* REPEAT WRITE mode is configured */
221                 /* Now set DA9052 into PAGE WRITE mode */
222                 ctrlb_msg.data &= ~DA9052_CONTROLB_WRITEMODE;
223                 ret = da9052->write(da9052, &ctrlb_msg);
224
225                 if (ret != 0)
226                         return ret;
227         }
228
229          /* Put first register address */
230         data_buf[0] = msg_queue[0].addr;
231
232         for (cnt = 0; cnt < msg_no; cnt++)
233                 data_buf[cnt+1] = msg_queue[cnt].data;
234
235         /* Construct a i2c msg for PAGE WRITE */
236         i2cmsg.addr  = da9052->slave_addr ;
237         /* First register address + all data*/
238         i2cmsg.len   = (msg_no + 1);
239         i2cmsg.buf   = data_buf;
240
241         /*To write the data on I2C set flag to zero */
242         i2cmsg.flags = 0;
243
244         /* Start the i2c transfer by calling host i2c driver function */
245         ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
246         if (ret < 0) {
247                 dev_info(&da9052->i2c_client->dev,\
248                 "1 - i2c_transfer function falied in [%s]!!!\n", __func__);
249                 return ret;
250         }
251
252         return 0;
253 }
254
255 int da9052_i2c_read_many(struct da9052 *da9052,
256         struct da9052_ssc_msg *sscmsg, int msg_no)
257 {
258
259         struct i2c_msg i2cmsg;
260         unsigned char data_buf[MAX_READ_WRITE_CNT];
261         struct da9052_ssc_msg *msg_queue = sscmsg;
262         int ret = 0;
263         /* Flag to check if requested registers are contiguous */
264         unsigned char cont_data = 1;
265         unsigned char cnt = 0;
266
267         /* Check if requested registers are contiguous */
268         for (cnt = 1; cnt < msg_no; cnt++) {
269                 if ((msg_queue[cnt].addr - msg_queue[cnt-1].addr) != 1) {
270                         /* Difference is not 1, i.e. non-contiguous registers */
271                         cont_data = 0;
272                         break;
273                 }
274         }
275
276         if (cont_data == 0) {
277                 /* Requested registers are non-contiguous */
278                 for (cnt = 0; cnt < msg_no; cnt++) {
279                         ret = da9052->read(da9052, &msg_queue[cnt]);
280                         if (ret != 0) {
281                                 dev_info(&da9052->i2c_client->dev,\
282                                 "Error in %s", __func__);
283                                 return ret;
284                         }
285                 }
286                 return 0;
287         }
288
289         /*
290         * We want to perform PAGE READ via I2C
291         * For PAGE READ sequence of I2C transactions is as below
292         * (slave_addr + reg_addr) + (slave_addr + data_1 + data_2 + ...)
293         */
294         /* Copy address of first register */
295         data_buf[0] = msg_queue[0].addr;
296
297         /* Construct a i2c msg for first transaction of PAGE READ i.e. write */
298         i2cmsg.addr  = da9052->slave_addr ;
299         i2cmsg.len   = 1;
300         i2cmsg.buf   = data_buf;
301
302         /*To write the data on I2C set flag to zero */
303         i2cmsg.flags = 0;
304
305         /* Start the i2c transfer by calling host i2c driver function */
306         ret = i2c_transfer(da9052->adapter, &i2cmsg, 1);
307         if (ret < 0) {
308                 dev_info(&da9052->i2c_client->dev,\
309                 "1 - i2c_transfer function falied in [%s]!!!\n", __func__);
310                 return ret;
311         }
312
313         /* Now Read the data from da9052 */
314         /* Construct a i2c msg for second transaction of PAGE READ i.e. read */
315         i2cmsg.addr  = da9052->slave_addr ;
316         i2cmsg.len   = msg_no;
317         i2cmsg.buf   = data_buf;
318
319         /*To read the data on I2C set flag to I2C_M_RD */
320         i2cmsg.flags = I2C_M_RD;
321
322         /* Start the i2c transfer by calling host i2c driver function */
323         ret = i2c_transfer(da9052->adapter,
324                 &i2cmsg, 1);
325         if (ret < 0) {
326                 dev_info(&da9052->i2c_client->dev,\
327                 "2 - i2c_transfer function falied in [%s]!!!\n", __func__);
328                 return ret;
329         }
330
331         /* Gather READ data */
332         for (cnt = 0; cnt < msg_no; cnt++)
333                 sscmsg[cnt].data = data_buf[cnt];
334
335         return 0;
336 }
337
338 static struct i2c_device_id da9052_ssc_id[] = {
339         { DA9052_SSC_I2C_DEVICE_NAME, 0},
340         {}
341 };
342
343 static struct i2c_driver da9052_i2c_driver =  {
344         .driver = {
345                 .name   = DA9052_SSC_I2C_DEVICE_NAME,
346                 .owner  = THIS_MODULE,
347         },
348         .probe  = da9052_i2c_probe,
349         .remove = da9052_i2c_remove,
350         .id_table       = da9052_ssc_id,
351 };
352
353 static int __init da9052_i2c_init(void)
354 {
355         int ret = 0;
356        // printk("\n\nEntered da9052_i2c_init................\n\n");
357         ret = i2c_add_driver(&da9052_i2c_driver);
358         if (ret != 0) {
359                 printk(KERN_ERR "Unable to register %s\n", DA9052_SSC_I2C_DEVICE_NAME);
360                 return ret;
361         }
362         return 0;
363 }
364 subsys_initcall(da9052_i2c_init);
365
366 static void  __exit da9052_i2c_exit(void)
367 {
368         i2c_del_driver(&da9052_i2c_driver);
369 }
370 module_exit(da9052_i2c_exit);
371
372 MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>");
373 MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC");
374 MODULE_LICENSE("GPL v2");
375 MODULE_ALIAS("platform:" DA9052_SSC_I2C_DEVICE_NAME);