1/*
2 * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/irq.h>
11#include <linux/delay.h>
12#include <linux/mutex.h>
13#include <linux/device.h>
14#include <linux/kernel.h>
15#include <linux/spi/spi.h>
16#include <linux/slab.h>
17#include <linux/sysfs.h>
18#include <linux/list.h>
19#include <linux/module.h>
20
21#include "../iio.h"
22#include "../sysfs.h"
23#include "../buffer.h"
24
25#include "adis16204.h"
26
27#define DRIVER_NAME		"adis16204"
28
29/**
30 * adis16204_spi_write_reg_8() - write single byte to a register
31 * @dev: device associated with child of actual device (iio_dev or iio_trig)
32 * @reg_address: the address of the register to be written
33 * @val: the value to write
34 **/
35static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev,
36		u8 reg_address,
37		u8 val)
38{
39	int ret;
40	struct adis16204_state *st = iio_priv(indio_dev);
41
42	mutex_lock(&st->buf_lock);
43	st->tx[0] = ADIS16204_WRITE_REG(reg_address);
44	st->tx[1] = val;
45
46	ret = spi_write(st->us, st->tx, 2);
47	mutex_unlock(&st->buf_lock);
48
49	return ret;
50}
51
52/**
53 * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
54 * @indio_dev: iio device associated with child of actual device
55 * @reg_address: the address of the lower of the two registers. Second register
56 *               is assumed to have address one greater.
57 * @val: value to be written
58 **/
59static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev,
60		u8 lower_reg_address,
61		u16 value)
62{
63	int ret;
64	struct spi_message msg;
65	struct adis16204_state *st = iio_priv(indio_dev);
66	struct spi_transfer xfers[] = {
67		{
68			.tx_buf = st->tx,
69			.bits_per_word = 8,
70			.len = 2,
71			.cs_change = 1,
72		}, {
73			.tx_buf = st->tx + 2,
74			.bits_per_word = 8,
75			.len = 2,
76			.cs_change = 1,
77		},
78	};
79
80	mutex_lock(&st->buf_lock);
81	st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address);
82	st->tx[1] = value & 0xFF;
83	st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1);
84	st->tx[3] = (value >> 8) & 0xFF;
85
86	spi_message_init(&msg);
87	spi_message_add_tail(&xfers[0], &msg);
88	spi_message_add_tail(&xfers[1], &msg);
89	ret = spi_sync(st->us, &msg);
90	mutex_unlock(&st->buf_lock);
91
92	return ret;
93}
94
95/**
96 * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
97 * @indio_dev: iio device associated with child of actual device
98 * @reg_address: the address of the lower of the two registers. Second register
99 *               is assumed to have address one greater.
100 * @val: somewhere to pass back the value read
101 **/
102static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev,
103				     u8 lower_reg_address,
104				     u16 *val)
105{
106	struct spi_message msg;
107	struct adis16204_state *st = iio_priv(indio_dev);
108	int ret;
109	struct spi_transfer xfers[] = {
110		{
111			.tx_buf = st->tx,
112			.bits_per_word = 8,
113			.len = 2,
114			.cs_change = 1,
115			.delay_usecs = 20,
116		}, {
117			.rx_buf = st->rx,
118			.bits_per_word = 8,
119			.len = 2,
120			.delay_usecs = 20,
121		},
122	};
123
124	mutex_lock(&st->buf_lock);
125	st->tx[0] = ADIS16204_READ_REG(lower_reg_address);
126	st->tx[1] = 0;
127
128	spi_message_init(&msg);
129	spi_message_add_tail(&xfers[0], &msg);
130	spi_message_add_tail(&xfers[1], &msg);
131	ret = spi_sync(st->us, &msg);
132	if (ret) {
133		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
134				lower_reg_address);
135		goto error_ret;
136	}
137	*val = (st->rx[0] << 8) | st->rx[1];
138
139error_ret:
140	mutex_unlock(&st->buf_lock);
141	return ret;
142}
143
144static int adis16204_check_status(struct iio_dev *indio_dev)
145{
146	u16 status;
147	int ret;
148
149	ret = adis16204_spi_read_reg_16(indio_dev,
150					ADIS16204_DIAG_STAT, &status);
151	if (ret < 0) {
152		dev_err(&indio_dev->dev, "Reading status failed\n");
153		goto error_ret;
154	}
155	ret = status & 0x1F;
156
157	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
158		dev_err(&indio_dev->dev, "Self test failure\n");
159	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
160		dev_err(&indio_dev->dev, "SPI failure\n");
161	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
162		dev_err(&indio_dev->dev, "Flash update failed\n");
163	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
164		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
165	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
166		dev_err(&indio_dev->dev, "Power supply below 2.975V\n");
167
168error_ret:
169	return ret;
170}
171
172static ssize_t adis16204_read_14bit_signed(struct device *dev,
173		struct device_attribute *attr,
174		char *buf)
175{
176	struct iio_dev *indio_dev = dev_get_drvdata(dev);
177	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
178	s16 val = 0;
179	ssize_t ret;
180
181	mutex_lock(&indio_dev->mlock);
182
183	ret = adis16204_spi_read_reg_16(indio_dev,
184					this_attr->address, (u16 *)&val);
185	if (!ret) {
186		if (val & ADIS16204_ERROR_ACTIVE)
187			adis16204_check_status(indio_dev);
188
189		val = ((s16)(val << 2) >> 2);
190		ret = sprintf(buf, "%d\n", val);
191	}
192
193	mutex_unlock(&indio_dev->mlock);
194
195	return ret;
196}
197
198static int adis16204_reset(struct iio_dev *indio_dev)
199{
200	int ret;
201	ret = adis16204_spi_write_reg_8(indio_dev,
202			ADIS16204_GLOB_CMD,
203			ADIS16204_GLOB_CMD_SW_RESET);
204	if (ret)
205		dev_err(&indio_dev->dev, "problem resetting device");
206
207	return ret;
208}
209
210static ssize_t adis16204_write_reset(struct device *dev,
211		struct device_attribute *attr,
212		const char *buf, size_t len)
213{
214	struct iio_dev *indio_dev = dev_get_drvdata(dev);
215
216	if (len < 1)
217		return -EINVAL;
218	switch (buf[0]) {
219	case '1':
220	case 'y':
221	case 'Y':
222		return adis16204_reset(indio_dev);
223	}
224	return -EINVAL;
225}
226
227int adis16204_set_irq(struct iio_dev *indio_dev, bool enable)
228{
229	int ret = 0;
230	u16 msc;
231
232	ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc);
233	if (ret)
234		goto error_ret;
235
236	msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH;
237	msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2;
238	if (enable)
239		msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN;
240	else
241		msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
242
243	ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc);
244
245error_ret:
246	return ret;
247}
248
249static int adis16204_self_test(struct iio_dev *indio_dev)
250{
251	int ret;
252	ret = adis16204_spi_write_reg_16(indio_dev,
253			ADIS16204_MSC_CTRL,
254			ADIS16204_MSC_CTRL_SELF_TEST_EN);
255	if (ret) {
256		dev_err(&indio_dev->dev, "problem starting self test");
257		goto err_ret;
258	}
259
260	adis16204_check_status(indio_dev);
261
262err_ret:
263	return ret;
264}
265
266static int adis16204_initial_setup(struct iio_dev *indio_dev)
267{
268	int ret;
269
270	/* Disable IRQ */
271	ret = adis16204_set_irq(indio_dev, false);
272	if (ret) {
273		dev_err(&indio_dev->dev, "disable irq failed");
274		goto err_ret;
275	}
276
277	/* Do self test */
278	ret = adis16204_self_test(indio_dev);
279	if (ret) {
280		dev_err(&indio_dev->dev, "self test failure");
281		goto err_ret;
282	}
283
284	/* Read status register to check the result */
285	ret = adis16204_check_status(indio_dev);
286	if (ret) {
287		adis16204_reset(indio_dev);
288		dev_err(&indio_dev->dev, "device not playing ball -> reset");
289		msleep(ADIS16204_STARTUP_DELAY);
290		ret = adis16204_check_status(indio_dev);
291		if (ret) {
292			dev_err(&indio_dev->dev, "giving up");
293			goto err_ret;
294		}
295	}
296
297err_ret:
298	return ret;
299}
300
301/* Unique to this driver currently */
302#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr)			\
303	IIO_DEVICE_ATTR(in_accel_xy, S_IRUGO, _show, NULL, _addr)
304#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr)		\
305	IIO_DEVICE_ATTR(in_accel_xypeak, S_IRUGO, _show, NULL, _addr)
306
307static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed,
308		ADIS16204_XY_RSS_OUT);
309static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed,
310		ADIS16204_XY_PEAK_OUT);
311static IIO_CONST_ATTR(in_accel_xy_scale, "0.017125");
312
313static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
314
315enum adis16204_channel {
316	in_supply,
317	in_aux,
318	temp,
319	accel_x,
320	accel_y,
321};
322
323static u8 adis16204_addresses[5][3] = {
324	[in_supply] = { ADIS16204_SUPPLY_OUT },
325	[in_aux] = { ADIS16204_AUX_ADC },
326	[temp] = { ADIS16204_TEMP_OUT },
327	[accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL,
328		      ADIS16204_X_PEAK_OUT },
329	[accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL,
330		      ADIS16204_Y_PEAK_OUT },
331};
332
333static int adis16204_read_raw(struct iio_dev *indio_dev,
334			      struct iio_chan_spec const *chan,
335			      int *val, int *val2,
336			      long mask)
337{
338	int ret;
339	int bits;
340	u8 addr;
341	s16 val16;
342	int addrind;
343
344	switch (mask) {
345	case 0:
346		mutex_lock(&indio_dev->mlock);
347		addr = adis16204_addresses[chan->address][0];
348		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
349		if (ret) {
350			mutex_unlock(&indio_dev->mlock);
351			return ret;
352		}
353
354		if (val16 & ADIS16204_ERROR_ACTIVE) {
355			ret = adis16204_check_status(indio_dev);
356			if (ret) {
357				mutex_unlock(&indio_dev->mlock);
358				return ret;
359			}
360		}
361		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
362		if (chan->scan_type.sign == 's')
363			val16 = (s16)(val16 <<
364				      (16 - chan->scan_type.realbits)) >>
365				(16 - chan->scan_type.realbits);
366		*val = val16;
367		mutex_unlock(&indio_dev->mlock);
368		return IIO_VAL_INT;
369	case IIO_CHAN_INFO_SCALE:
370		switch (chan->type) {
371		case IIO_VOLTAGE:
372			*val = 0;
373			if (chan->channel == 0)
374				*val2 = 1220;
375			else
376				*val2 = 610;
377			return IIO_VAL_INT_PLUS_MICRO;
378		case IIO_TEMP:
379			*val = 0;
380			*val2 = -470000;
381			return IIO_VAL_INT_PLUS_MICRO;
382		case IIO_ACCEL:
383			*val = 0;
384			if (chan->channel == 'x')
385				*val2 = 17125;
386			else
387				*val2 = 8407;
388			return IIO_VAL_INT_PLUS_MICRO;
389		default:
390			return -EINVAL;
391		}
392		break;
393	case IIO_CHAN_INFO_OFFSET:
394		*val = 25;
395		return IIO_VAL_INT;
396	case IIO_CHAN_INFO_CALIBBIAS:
397	case IIO_CHAN_INFO_PEAK:
398		if (mask == IIO_CHAN_INFO_CALIBBIAS) {
399			bits = 12;
400			addrind = 1;
401		} else { /* PEAK_SEPARATE */
402			bits = 14;
403			addrind = 2;
404		}
405		mutex_lock(&indio_dev->mlock);
406		addr = adis16204_addresses[chan->address][addrind];
407		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
408		if (ret) {
409			mutex_unlock(&indio_dev->mlock);
410			return ret;
411		}
412		val16 &= (1 << bits) - 1;
413		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
414		*val = val16;
415		mutex_unlock(&indio_dev->mlock);
416		return IIO_VAL_INT;
417	}
418	return -EINVAL;
419}
420
421static int adis16204_write_raw(struct iio_dev *indio_dev,
422			       struct iio_chan_spec const *chan,
423			       int val,
424			       int val2,
425			       long mask)
426{
427	int bits;
428	s16 val16;
429	u8 addr;
430	switch (mask) {
431	case IIO_CHAN_INFO_CALIBBIAS:
432		switch (chan->type) {
433		case IIO_ACCEL:
434			bits = 12;
435			break;
436		default:
437			return -EINVAL;
438		};
439		val16 = val & ((1 << bits) - 1);
440		addr = adis16204_addresses[chan->address][1];
441		return adis16204_spi_write_reg_16(indio_dev, addr, val16);
442	}
443	return -EINVAL;
444}
445
446static struct iio_chan_spec adis16204_channels[] = {
447	IIO_CHAN(IIO_VOLTAGE, 0, 0, 0, "supply", 0, 0,
448		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
449		 in_supply, ADIS16204_SCAN_SUPPLY,
450		 IIO_ST('u', 12, 16, 0), 0),
451	IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0,
452		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT,
453		 in_aux, ADIS16204_SCAN_AUX_ADC,
454		 IIO_ST('u', 12, 16, 0), 0),
455	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
456		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
457		 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT,
458		 temp, ADIS16204_SCAN_TEMP,
459		 IIO_ST('u', 12, 16, 0), 0),
460	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
461		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
462		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
463		 IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
464		 accel_x, ADIS16204_SCAN_ACC_X,
465		 IIO_ST('s', 14, 16, 0), 0),
466	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
467		 IIO_CHAN_INFO_SCALE_SEPARATE_BIT |
468		 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT |
469		 IIO_CHAN_INFO_PEAK_SEPARATE_BIT,
470		 accel_y, ADIS16204_SCAN_ACC_Y,
471		 IIO_ST('s', 14, 16, 0), 0),
472	IIO_CHAN_SOFT_TIMESTAMP(5),
473};
474
475static struct attribute *adis16204_attributes[] = {
476	&iio_dev_attr_reset.dev_attr.attr,
477	&iio_dev_attr_in_accel_xy.dev_attr.attr,
478	&iio_dev_attr_in_accel_xypeak.dev_attr.attr,
479	&iio_const_attr_in_accel_xy_scale.dev_attr.attr,
480	NULL
481};
482
483static const struct attribute_group adis16204_attribute_group = {
484	.attrs = adis16204_attributes,
485};
486
487static const struct iio_info adis16204_info = {
488	.attrs = &adis16204_attribute_group,
489	.read_raw = &adis16204_read_raw,
490	.write_raw = &adis16204_write_raw,
491	.driver_module = THIS_MODULE,
492};
493
494static int __devinit adis16204_probe(struct spi_device *spi)
495{
496	int ret;
497	struct adis16204_state *st;
498	struct iio_dev *indio_dev;
499
500	/* setup the industrialio driver allocated elements */
501	indio_dev = iio_allocate_device(sizeof(*st));
502	if (indio_dev == NULL) {
503		ret = -ENOMEM;
504		goto error_ret;
505	}
506	st = iio_priv(indio_dev);
507	/* this is only used for removal purposes */
508	spi_set_drvdata(spi, indio_dev);
509	st->us = spi;
510	mutex_init(&st->buf_lock);
511
512	indio_dev->name = spi->dev.driver->name;
513	indio_dev->dev.parent = &spi->dev;
514	indio_dev->info = &adis16204_info;
515	indio_dev->channels = adis16204_channels;
516	indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
517	indio_dev->modes = INDIO_DIRECT_MODE;
518
519	ret = adis16204_configure_ring(indio_dev);
520	if (ret)
521		goto error_free_dev;
522
523	ret = iio_buffer_register(indio_dev,
524				  adis16204_channels,
525				  ARRAY_SIZE(adis16204_channels));
526	if (ret) {
527		printk(KERN_ERR "failed to initialize the ring\n");
528		goto error_unreg_ring_funcs;
529	}
530
531	if (spi->irq) {
532		ret = adis16204_probe_trigger(indio_dev);
533		if (ret)
534			goto error_uninitialize_ring;
535	}
536
537	/* Get the device into a sane initial state */
538	ret = adis16204_initial_setup(indio_dev);
539	if (ret)
540		goto error_remove_trigger;
541	ret = iio_device_register(indio_dev);
542	if (ret)
543		goto error_remove_trigger;
544
545	return 0;
546
547error_remove_trigger:
548	adis16204_remove_trigger(indio_dev);
549error_uninitialize_ring:
550	iio_buffer_unregister(indio_dev);
551error_unreg_ring_funcs:
552	adis16204_unconfigure_ring(indio_dev);
553error_free_dev:
554	iio_free_device(indio_dev);
555error_ret:
556	return ret;
557}
558
559static int adis16204_remove(struct spi_device *spi)
560{
561	struct iio_dev *indio_dev = spi_get_drvdata(spi);
562
563	iio_device_unregister(indio_dev);
564	adis16204_remove_trigger(indio_dev);
565	iio_buffer_unregister(indio_dev);
566	adis16204_unconfigure_ring(indio_dev);
567	iio_free_device(indio_dev);
568
569	return 0;
570}
571
572static struct spi_driver adis16204_driver = {
573	.driver = {
574		.name = "adis16204",
575		.owner = THIS_MODULE,
576	},
577	.probe = adis16204_probe,
578	.remove = __devexit_p(adis16204_remove),
579};
580module_spi_driver(adis16204_driver);
581
582MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
583MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder");
584MODULE_LICENSE("GPL v2");
585MODULE_ALIAS("spi:adis16204");
586