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