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
18static 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
43static 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
69static 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
96static 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
124static 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
157error_ret:
158	mutex_unlock(&st->buf_lock);
159	return ret;
160}
161
162static 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
194error_ret:
195	mutex_unlock(&st->buf_lock);
196	return ret;
197}
198
199static 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
232error_ret:
233	mutex_unlock(&st->buf_lock);
234	return ret;
235}
236
237static 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
270error_ret:
271	mutex_unlock(&st->buf_lock);
272	return ret;
273}
274
275static 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 == NULL)
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
299static int ade7854_spi_remove(struct spi_device *spi)
300{
301	ade7854_remove(spi_get_drvdata(spi));
302
303	return 0;
304}
305static const struct spi_device_id ade7854_id[] = {
306	{ "ade7854", 0 },
307	{ "ade7858", 0 },
308	{ "ade7868", 0 },
309	{ "ade7878", 0 },
310	{ }
311};
312MODULE_DEVICE_TABLE(spi, ade7854_id);
313
314static struct spi_driver ade7854_driver = {
315	.driver = {
316		.name = "ade7854",
317		.owner = THIS_MODULE,
318	},
319	.probe = ade7854_spi_probe,
320	.remove = ade7854_spi_remove,
321	.id_table = ade7854_id,
322};
323module_spi_driver(ade7854_driver);
324
325MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
326MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 SPI Driver");
327MODULE_LICENSE("GPL v2");
328