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