PageRenderTime 39ms CodeModel.GetById 3ms app.highlight 33ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/iio/meter/ade7854-spi.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t
C | 370 lines | 315 code | 48 blank | 7 comment | 7 complexity | 39a5cf0e206a0a483a84293b87ef3e47 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  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
 17static 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_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	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
 45static 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_priv(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
 74static 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_priv(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
104static 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_priv(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
135static 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_priv(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
172error_ret:
173	mutex_unlock(&st->buf_lock);
174	return ret;
175}
176
177static 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_priv(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
213error_ret:
214	mutex_unlock(&st->buf_lock);
215	return ret;
216}
217
218static 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_priv(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
255error_ret:
256	mutex_unlock(&st->buf_lock);
257	return ret;
258}
259
260static 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_priv(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
297error_ret:
298	mutex_unlock(&st->buf_lock);
299	return ret;
300}
301
302static int __devinit ade7854_spi_probe(struct spi_device *spi)
303{
304	int ret;
305	struct ade7854_state *st;
306	struct iio_dev *indio_dev;
307
308	indio_dev = iio_allocate_device(sizeof(*st));
309	if (indio_dev == NULL)
310		return -ENOMEM;
311	st = iio_priv(indio_dev);
312	spi_set_drvdata(spi, indio_dev);
313	st->read_reg_8 = ade7854_spi_read_reg_8;
314	st->read_reg_16 = ade7854_spi_read_reg_16;
315	st->read_reg_24 = ade7854_spi_read_reg_24;
316	st->read_reg_32 = ade7854_spi_read_reg_32;
317	st->write_reg_8 = ade7854_spi_write_reg_8;
318	st->write_reg_16 = ade7854_spi_write_reg_16;
319	st->write_reg_24 = ade7854_spi_write_reg_24;
320	st->write_reg_32 = ade7854_spi_write_reg_32;
321	st->irq = spi->irq;
322	st->spi = spi;
323
324
325	ret = ade7854_probe(indio_dev, &spi->dev);
326	if (ret)
327		iio_free_device(indio_dev);
328
329	return 0;
330}
331
332static int ade7854_spi_remove(struct spi_device *spi)
333{
334	ade7854_remove(spi_get_drvdata(spi));
335
336	return 0;
337}
338static const struct spi_device_id ade7854_id[] = {
339	{ "ade7854", 0 },
340	{ "ade7858", 0 },
341	{ "ade7868", 0 },
342	{ "ade7878", 0 },
343	{ }
344};
345
346static 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
356static __init int ade7854_init(void)
357{
358	return spi_register_driver(&ade7854_driver);
359}
360module_init(ade7854_init);
361
362static __exit void ade7854_exit(void)
363{
364	spi_unregister_driver(&ade7854_driver);
365}
366module_exit(ade7854_exit);
367
368MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
369MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 SPI Driver");
370MODULE_LICENSE("GPL v2");