Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / iio / meter / ade7854-spi.c
1 /*
2  * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (SPI 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/spi/spi.h>
12 #include <linux/slab.h>
13
14 #include "../iio.h"
15 #include "ade7854.h"
16
17 static int ade7854_spi_write_reg_8(struct device *dev,
18                 u16 reg_address,
19                 u8 value)
20 {
21         int ret;
22         struct spi_message msg;
23         struct iio_dev *indio_dev = dev_get_drvdata(dev);
24         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
25         struct spi_transfer xfers[] = {
26                 {
27                         .tx_buf = st->tx,
28                         .bits_per_word = 8,
29                         .len = 4,
30                 }
31         };
32
33         mutex_lock(&st->buf_lock);
34         st->tx[0] = ADE7854_WRITE_REG;
35         st->tx[1] = (reg_address >> 8) & 0xFF;
36         st->tx[2] = reg_address & 0xFF;
37         st->tx[3] = value & 0xFF;
38
39         spi_message_init(&msg);
40         spi_message_add_tail(xfers, &msg);
41         ret = spi_sync(st->spi, &msg);
42         mutex_unlock(&st->buf_lock);
43
44         return ret;
45 }
46
47 static int ade7854_spi_write_reg_16(struct device *dev,
48                 u16 reg_address,
49                 u16 value)
50 {
51         int ret;
52         struct spi_message msg;
53         struct iio_dev *indio_dev = dev_get_drvdata(dev);
54         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
55         struct spi_transfer xfers[] = {
56                 {
57                         .tx_buf = st->tx,
58                         .bits_per_word = 8,
59                         .len = 5,
60                 }
61         };
62
63         mutex_lock(&st->buf_lock);
64         st->tx[0] = ADE7854_WRITE_REG;
65         st->tx[1] = (reg_address >> 8) & 0xFF;
66         st->tx[2] = reg_address & 0xFF;
67         st->tx[3] = (value >> 8) & 0xFF;
68         st->tx[4] = value & 0xFF;
69
70         spi_message_init(&msg);
71         spi_message_add_tail(xfers, &msg);
72         ret = spi_sync(st->spi, &msg);
73         mutex_unlock(&st->buf_lock);
74
75         return ret;
76 }
77
78 static int ade7854_spi_write_reg_24(struct device *dev,
79                 u16 reg_address,
80                 u32 value)
81 {
82         int ret;
83         struct spi_message msg;
84         struct iio_dev *indio_dev = dev_get_drvdata(dev);
85         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
86         struct spi_transfer xfers[] = {
87                 {
88                         .tx_buf = st->tx,
89                         .bits_per_word = 8,
90                         .len = 6,
91                 }
92         };
93
94         mutex_lock(&st->buf_lock);
95         st->tx[0] = ADE7854_WRITE_REG;
96         st->tx[1] = (reg_address >> 8) & 0xFF;
97         st->tx[2] = reg_address & 0xFF;
98         st->tx[3] = (value >> 16) & 0xFF;
99         st->tx[4] = (value >> 8) & 0xFF;
100         st->tx[5] = value & 0xFF;
101
102         spi_message_init(&msg);
103         spi_message_add_tail(xfers, &msg);
104         ret = spi_sync(st->spi, &msg);
105         mutex_unlock(&st->buf_lock);
106
107         return ret;
108 }
109
110 static int ade7854_spi_write_reg_32(struct device *dev,
111                 u16 reg_address,
112                 u32 value)
113 {
114         int ret;
115         struct spi_message msg;
116         struct iio_dev *indio_dev = dev_get_drvdata(dev);
117         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
118         struct spi_transfer xfers[] = {
119                 {
120                         .tx_buf = st->tx,
121                         .bits_per_word = 8,
122                         .len = 7,
123                 }
124         };
125
126         mutex_lock(&st->buf_lock);
127         st->tx[0] = ADE7854_WRITE_REG;
128         st->tx[1] = (reg_address >> 8) & 0xFF;
129         st->tx[2] = reg_address & 0xFF;
130         st->tx[3] = (value >> 24) & 0xFF;
131         st->tx[4] = (value >> 16) & 0xFF;
132         st->tx[5] = (value >> 8) & 0xFF;
133         st->tx[6] = value & 0xFF;
134
135         spi_message_init(&msg);
136         spi_message_add_tail(xfers, &msg);
137         ret = spi_sync(st->spi, &msg);
138         mutex_unlock(&st->buf_lock);
139
140         return ret;
141 }
142
143 static int ade7854_spi_read_reg_8(struct device *dev,
144                 u16 reg_address,
145                 u8 *val)
146 {
147         struct spi_message msg;
148         struct iio_dev *indio_dev = dev_get_drvdata(dev);
149         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
150         int ret;
151         struct spi_transfer xfers[] = {
152                 {
153                         .tx_buf = st->tx,
154                         .bits_per_word = 8,
155                         .len = 4,
156                 },
157         };
158
159         mutex_lock(&st->buf_lock);
160
161         st->tx[0] = ADE7854_READ_REG;
162         st->tx[1] = (reg_address >> 8) & 0xFF;
163         st->tx[2] = reg_address & 0xFF;
164         st->tx[3] = 0;
165
166         spi_message_init(&msg);
167         spi_message_add_tail(xfers, &msg);
168         ret = spi_sync(st->spi, &msg);
169         if (ret) {
170                 dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X",
171                                 reg_address);
172                 goto error_ret;
173         }
174         *val = st->rx[3];
175
176 error_ret:
177         mutex_unlock(&st->buf_lock);
178         return ret;
179 }
180
181 static int ade7854_spi_read_reg_16(struct device *dev,
182                 u16 reg_address,
183                 u16 *val)
184 {
185         struct spi_message msg;
186         struct iio_dev *indio_dev = dev_get_drvdata(dev);
187         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
188         int ret;
189         struct spi_transfer xfers[] = {
190                 {
191                         .tx_buf = st->tx,
192                         .bits_per_word = 8,
193                         .len = 5,
194                 },
195         };
196
197         mutex_lock(&st->buf_lock);
198         st->tx[0] = ADE7854_READ_REG;
199         st->tx[1] = (reg_address >> 8) & 0xFF;
200         st->tx[2] = reg_address & 0xFF;
201         st->tx[3] = 0;
202         st->tx[4] = 0;
203
204         spi_message_init(&msg);
205         spi_message_add_tail(xfers, &msg);
206         ret = spi_sync(st->spi, &msg);
207         if (ret) {
208                 dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X",
209                                 reg_address);
210                 goto error_ret;
211         }
212         *val = (st->rx[3] << 8) | st->rx[4];
213
214 error_ret:
215         mutex_unlock(&st->buf_lock);
216         return ret;
217 }
218
219 static int ade7854_spi_read_reg_24(struct device *dev,
220                 u16 reg_address,
221                 u32 *val)
222 {
223         struct spi_message msg;
224         struct iio_dev *indio_dev = dev_get_drvdata(dev);
225         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
226         int ret;
227         struct spi_transfer xfers[] = {
228                 {
229                         .tx_buf = st->tx,
230                         .bits_per_word = 8,
231                         .len = 6,
232                 },
233         };
234
235         mutex_lock(&st->buf_lock);
236
237         st->tx[0] = ADE7854_READ_REG;
238         st->tx[1] = (reg_address >> 8) & 0xFF;
239         st->tx[2] = reg_address & 0xFF;
240         st->tx[3] = 0;
241         st->tx[4] = 0;
242         st->tx[5] = 0;
243
244         spi_message_init(&msg);
245         spi_message_add_tail(xfers, &msg);
246         ret = spi_sync(st->spi, &msg);
247         if (ret) {
248                 dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X",
249                                 reg_address);
250                 goto error_ret;
251         }
252         *val = (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5];
253
254 error_ret:
255         mutex_unlock(&st->buf_lock);
256         return ret;
257 }
258
259 static int ade7854_spi_read_reg_32(struct device *dev,
260                 u16 reg_address,
261                 u32 *val)
262 {
263         struct spi_message msg;
264         struct iio_dev *indio_dev = dev_get_drvdata(dev);
265         struct ade7854_state *st = iio_dev_get_devdata(indio_dev);
266         int ret;
267         struct spi_transfer xfers[] = {
268                 {
269                         .tx_buf = st->tx,
270                         .bits_per_word = 8,
271                         .len = 7,
272                 },
273         };
274
275         mutex_lock(&st->buf_lock);
276
277         st->tx[0] = ADE7854_READ_REG;
278         st->tx[1] = (reg_address >> 8) & 0xFF;
279         st->tx[2] = reg_address & 0xFF;
280         st->tx[3] = 0;
281         st->tx[4] = 0;
282         st->tx[5] = 0;
283         st->tx[6] = 0;
284
285         spi_message_init(&msg);
286         spi_message_add_tail(xfers, &msg);
287         ret = spi_sync(st->spi, &msg);
288         if (ret) {
289                 dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X",
290                                 reg_address);
291                 goto error_ret;
292         }
293         *val = (st->rx[3] << 24) | (st->rx[4] << 16) | (st->rx[5] << 8) | st->rx[6];
294
295 error_ret:
296         mutex_unlock(&st->buf_lock);
297         return ret;
298 }
299
300 static int __devinit ade7854_spi_probe(struct spi_device *spi)
301 {
302         int ret;
303         struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL);
304         if (!st) {
305                 ret =  -ENOMEM;
306                 return ret;
307         }
308
309         spi_set_drvdata(spi, st);
310         st->read_reg_8 = ade7854_spi_read_reg_8;
311         st->read_reg_16 = ade7854_spi_read_reg_16;
312         st->read_reg_24 = ade7854_spi_read_reg_24;
313         st->read_reg_32 = ade7854_spi_read_reg_32;
314         st->write_reg_8 = ade7854_spi_write_reg_8;
315         st->write_reg_16 = ade7854_spi_write_reg_16;
316         st->write_reg_24 = ade7854_spi_write_reg_24;
317         st->write_reg_32 = ade7854_spi_write_reg_32;
318         st->irq = spi->irq;
319         st->spi = spi;
320
321         ret = ade7854_probe(st, &spi->dev);
322         if (ret) {
323                 kfree(st);
324                 return ret;
325         }
326
327         return 0;
328 }
329
330 static int ade7854_spi_remove(struct spi_device *spi)
331 {
332         ade7854_remove(spi_get_drvdata(spi));
333
334         return 0;
335 }
336
337 static struct spi_driver ade7854_driver = {
338         .driver = {
339                 .name = "ade7854",
340                 .owner = THIS_MODULE,
341         },
342         .probe = ade7854_spi_probe,
343         .remove = __devexit_p(ade7854_spi_remove),
344 };
345
346 static __init int ade7854_init(void)
347 {
348         return spi_register_driver(&ade7854_driver);
349 }
350 module_init(ade7854_init);
351
352 static __exit void ade7854_exit(void)
353 {
354         spi_unregister_driver(&ade7854_driver);
355 }
356 module_exit(ade7854_exit);
357
358 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
359 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC SPI Driver");
360 MODULE_LICENSE("GPL v2");