Merge tag 'v2.6.39-rc7'
[pandora-kernel.git] / drivers / staging / iio / meter / ade7854-i2c.c
1 /*
2  * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (I2C Bus)
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/i2c.h>
12 #include <linux/slab.h>
13
14 #include "../iio.h"
15 #include "ade7854.h"
16
17 static int ade7854_i2c_write_reg_8(struct device *dev,
18                 u16 reg_address,
19                 u8 value)
20 {
21         int ret;
22         struct iio_dev *indio_dev = dev_get_drvdata(dev);
23         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
24
25         mutex_lock(&st->buf_lock);
26         st->tx[0] = (reg_address >> 8) & 0xFF;
27         st->tx[1] = reg_address & 0xFF;
28         st->tx[2] = value;
29
30         ret = i2c_master_send(st->i2c, st->tx, 3);
31         mutex_unlock(&st->buf_lock);
32
33         return ret;
34 }
35
36 static int ade7854_i2c_write_reg_16(struct device *dev,
37                 u16 reg_address,
38                 u16 value)
39 {
40         int ret;
41         struct iio_dev *indio_dev = dev_get_drvdata(dev);
42         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
43
44         mutex_lock(&st->buf_lock);
45         st->tx[0] = (reg_address >> 8) & 0xFF;
46         st->tx[1] = reg_address & 0xFF;
47         st->tx[2] = (value >> 8) & 0xFF;
48         st->tx[3] = value & 0xFF;
49
50         ret = i2c_master_send(st->i2c, st->tx, 4);
51         mutex_unlock(&st->buf_lock);
52
53         return ret;
54 }
55
56 static int ade7854_i2c_write_reg_24(struct device *dev,
57                 u16 reg_address,
58                 u32 value)
59 {
60         int ret;
61         struct iio_dev *indio_dev = dev_get_drvdata(dev);
62         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
63
64         mutex_lock(&st->buf_lock);
65         st->tx[0] = (reg_address >> 8) & 0xFF;
66         st->tx[1] = reg_address & 0xFF;
67         st->tx[2] = (value >> 16) & 0xFF;
68         st->tx[3] = (value >> 8) & 0xFF;
69         st->tx[4] = value & 0xFF;
70
71         ret = i2c_master_send(st->i2c, st->tx, 5);
72         mutex_unlock(&st->buf_lock);
73
74         return ret;
75 }
76
77 static int ade7854_i2c_write_reg_32(struct device *dev,
78                 u16 reg_address,
79                 u32 value)
80 {
81         int ret;
82         struct iio_dev *indio_dev = dev_get_drvdata(dev);
83         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
84
85         mutex_lock(&st->buf_lock);
86         st->tx[0] = (reg_address >> 8) & 0xFF;
87         st->tx[1] = reg_address & 0xFF;
88         st->tx[2] = (value >> 24) & 0xFF;
89         st->tx[3] = (value >> 16) & 0xFF;
90         st->tx[4] = (value >> 8) & 0xFF;
91         st->tx[5] = value & 0xFF;
92
93         ret = i2c_master_send(st->i2c, st->tx, 6);
94         mutex_unlock(&st->buf_lock);
95
96         return ret;
97 }
98
99 static int ade7854_i2c_read_reg_8(struct device *dev,
100                 u16 reg_address,
101                 u8 *val)
102 {
103         struct iio_dev *indio_dev = dev_get_drvdata(dev);
104         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
105         int ret;
106
107         mutex_lock(&st->buf_lock);
108         st->tx[0] = (reg_address >> 8) & 0xFF;
109         st->tx[1] = reg_address & 0xFF;
110
111         ret = i2c_master_send(st->i2c, st->tx, 2);
112         if (ret)
113                 goto out;
114
115         ret = i2c_master_recv(st->i2c, st->rx, 1);
116         if (ret)
117                 goto out;
118
119         *val = st->rx[0];
120 out:
121         mutex_unlock(&st->buf_lock);
122         return ret;
123 }
124
125 static int ade7854_i2c_read_reg_16(struct device *dev,
126                 u16 reg_address,
127                 u16 *val)
128 {
129         struct iio_dev *indio_dev = dev_get_drvdata(dev);
130         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
131         int ret;
132
133         mutex_lock(&st->buf_lock);
134         st->tx[0] = (reg_address >> 8) & 0xFF;
135         st->tx[1] = reg_address & 0xFF;
136
137         ret = i2c_master_send(st->i2c, st->tx, 2);
138         if (ret)
139                 goto out;
140
141         ret = i2c_master_recv(st->i2c, st->rx, 2);
142         if (ret)
143                 goto out;
144
145         *val = (st->rx[0] << 8) | st->rx[1];
146 out:
147         mutex_unlock(&st->buf_lock);
148         return ret;
149 }
150
151 static int ade7854_i2c_read_reg_24(struct device *dev,
152                 u16 reg_address,
153                 u32 *val)
154 {
155         struct iio_dev *indio_dev = dev_get_drvdata(dev);
156         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
157         int ret;
158
159         mutex_lock(&st->buf_lock);
160         st->tx[0] = (reg_address >> 8) & 0xFF;
161         st->tx[1] = reg_address & 0xFF;
162
163         ret = i2c_master_send(st->i2c, st->tx, 2);
164         if (ret)
165                 goto out;
166
167         ret = i2c_master_recv(st->i2c, st->rx, 3);
168         if (ret)
169                 goto out;
170
171         *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
172 out:
173         mutex_unlock(&st->buf_lock);
174         return ret;
175 }
176
177 static int ade7854_i2c_read_reg_32(struct device *dev,
178                 u16 reg_address,
179                 u32 *val)
180 {
181         struct iio_dev *indio_dev = dev_get_drvdata(dev);
182         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
183         int ret;
184
185         mutex_lock(&st->buf_lock);
186         st->tx[0] = (reg_address >> 8) & 0xFF;
187         st->tx[1] = reg_address & 0xFF;
188
189         ret = i2c_master_send(st->i2c, st->tx, 2);
190         if (ret)
191                 goto out;
192
193         ret = i2c_master_recv(st->i2c, st->rx, 3);
194         if (ret)
195                 goto out;
196
197         *val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
198 out:
199         mutex_unlock(&st->buf_lock);
200         return ret;
201 }
202
203 static int __devinit ade7854_i2c_probe(struct i2c_client *client,
204                 const struct i2c_device_id *id)
205 {
206         int ret;
207         struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL);
208         if (!st) {
209                 ret =  -ENOMEM;
210                 return ret;
211         }
212
213         i2c_set_clientdata(client, st);
214         st->read_reg_8 = ade7854_i2c_read_reg_8;
215         st->read_reg_16 = ade7854_i2c_read_reg_16;
216         st->read_reg_24 = ade7854_i2c_read_reg_24;
217         st->read_reg_32 = ade7854_i2c_read_reg_32;
218         st->write_reg_8 = ade7854_i2c_write_reg_8;
219         st->write_reg_16 = ade7854_i2c_write_reg_16;
220         st->write_reg_24 = ade7854_i2c_write_reg_24;
221         st->write_reg_32 = ade7854_i2c_write_reg_32;
222         st->i2c = client;
223         st->irq = client->irq;
224
225         ret = ade7854_probe(st, &client->dev);
226         if (ret) {
227                 kfree(st);
228                 return ret;
229         }
230
231         return ret;
232 }
233
234 static int __devexit ade7854_i2c_remove(struct i2c_client *client)
235 {
236         return ade7854_remove(i2c_get_clientdata(client));
237 }
238
239 static const struct i2c_device_id ade7854_id[] = {
240         { "ade7854", 0 },
241         { "ade7858", 0 },
242         { "ade7868", 0 },
243         { "ade7878", 0 },
244         { }
245 };
246 MODULE_DEVICE_TABLE(i2c, ade7854_id);
247
248 static struct i2c_driver ade7854_i2c_driver = {
249         .driver = {
250                 .name = "ade7854",
251         },
252         .probe    = ade7854_i2c_probe,
253         .remove   = __devexit_p(ade7854_i2c_remove),
254         .id_table = ade7854_id,
255 };
256
257 static __init int ade7854_i2c_init(void)
258 {
259         return i2c_add_driver(&ade7854_i2c_driver);
260 }
261 module_init(ade7854_i2c_init);
262
263 static __exit void ade7854_i2c_exit(void)
264 {
265         i2c_del_driver(&ade7854_i2c_driver);
266 }
267 module_exit(ade7854_i2c_exit);
268
269
270 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
271 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC I2C Driver");
272 MODULE_LICENSE("GPL v2");