2 * Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope
4 * Written by: Matthias Brugger <m_brugger@web.de>
6 * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the
20 * Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * The driver just has a bare interface to the sysfs (sample rate in Hz,
26 * orientation (x, y, z) and gyroscope data in °/sec.
28 * It should be added to iio subsystem when this has left staging.
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/device.h>
35 #include <linux/list.h>
36 #include <linux/errno.h>
37 #include <linux/mutex.h>
38 #include <linux/slab.h>
40 #include <linux/interrupt.h>
41 #include <linux/sysfs.h>
42 #include <linux/stat.h>
43 #include <linux/delay.h>
45 #include <linux/gpio.h>
47 #include <linux/spi/spi.h>
48 #include <linux/workqueue.h>
50 #include "adis16255.h"
52 #define ADIS_STATUS 0x3d
53 #define ADIS_SMPL_PRD_MSB 0x37
54 #define ADIS_SMPL_PRD_LSB 0x36
55 #define ADIS_MSC_CTRL_MSB 0x35
56 #define ADIS_MSC_CTRL_LSB 0x34
57 #define ADIS_GPIO_CTRL 0x33
58 #define ADIS_ALM_SMPL1 0x25
59 #define ADIS_ALM_MAG1 0x21
60 #define ADIS_GYRO_SCALE 0x17
61 #define ADIS_GYRO_OUT 0x05
62 #define ADIS_SUPPLY_OUT 0x03
63 #define ADIS_ENDURANCE 0x01
66 * data structure for every sensor
68 * @dev: Driver model representation of the device.
69 * @spi: Pointer to the spi device which will manage i/o to spi bus.
70 * @data: Last read data from device.
71 * @irq_adis: GPIO Number of IRQ signal
72 * @irq: irq line manage by kernel
73 * @negative: indicates if sensor is upside down (negative == 1)
74 * @direction: indicates axis (x, y, z) the sensor is meassuring
76 struct spi_adis16255_data
{
78 struct spi_device
*spi
;
85 /*-------------------------------------------------------------------------*/
87 static int spi_adis16255_read_data(struct spi_adis16255_data
*spiadis
,
91 struct spi_device
*spi
= spiadis
->spi
;
92 struct spi_message msg
;
93 struct spi_transfer xfer1
, xfer2
;
97 buf
= kzalloc(4, GFP_KERNEL
);
101 rx
= kzalloc(4, GFP_KERNEL
);
109 spi_message_init(&msg
);
110 memset(&xfer1
, 0, sizeof(xfer1
));
111 memset(&xfer2
, 0, sizeof(xfer2
));
114 xfer1
.rx_buf
= buf
+ 2;
116 xfer1
.delay_usecs
= 9;
118 xfer2
.tx_buf
= rx
+ 2;
122 spi_message_add_tail(&xfer1
, &msg
);
123 spi_message_add_tail(&xfer2
, &msg
);
125 ret
= spi_sync(spi
, &msg
);
138 static int spi_adis16255_write_data(struct spi_adis16255_data
*spiadis
,
143 struct spi_device
*spi
= spiadis
->spi
;
144 struct spi_message msg
;
145 struct spi_transfer xfer1
, xfer2
;
149 buf
= kmalloc(4, GFP_KERNEL
);
153 rx
= kzalloc(4, GFP_KERNEL
);
159 spi_message_init(&msg
);
160 memset(&xfer1
, 0, sizeof(xfer1
));
161 memset(&xfer2
, 0, sizeof(xfer2
));
163 buf
[0] = adr1
| 0x80;
166 buf
[2] = adr2
| 0x80;
167 buf
[3] = *(wbuf
+ 1);
172 xfer1
.delay_usecs
= 9;
174 xfer2
.tx_buf
= buf
+2;
178 spi_message_add_tail(&xfer1
, &msg
);
179 spi_message_add_tail(&xfer2
, &msg
);
181 ret
= spi_sync(spi
, &msg
);
183 dev_warn(&spi
->dev
, "write data to %#x %#x failed\n",
192 /*-------------------------------------------------------------------------*/
194 static irqreturn_t
adis_irq_thread(int irq
, void *dev_id
)
196 struct spi_adis16255_data
*spiadis
= dev_id
;
200 status
= spi_adis16255_read_data(spiadis
, ADIS_GYRO_OUT
, (u8
*)&value
);
202 dev_warn(&spiadis
->spi
->dev
, "SPI FAILED\n");
206 /* perform on new data only... */
207 if (value
& 0x8000) {
208 /* delete error and new data bit */
209 value
= value
& 0x3fff;
210 /* set negative value */
212 value
= value
| 0xe000;
214 if (likely(spiadis
->negative
))
217 spiadis
->data
= (s16
) value
;
224 /*-------------------------------------------------------------------------*/
226 ssize_t
adis16255_show_data(struct device
*device
,
227 struct device_attribute
*da
,
230 struct spi_adis16255_data
*spiadis
= dev_get_drvdata(device
);
231 return snprintf(buf
, PAGE_SIZE
, "%d\n", spiadis
->data
);
233 DEVICE_ATTR(data
, S_IRUGO
, adis16255_show_data
, NULL
);
235 ssize_t
adis16255_show_direction(struct device
*device
,
236 struct device_attribute
*da
,
239 struct spi_adis16255_data
*spiadis
= dev_get_drvdata(device
);
240 return snprintf(buf
, PAGE_SIZE
, "%c\n", spiadis
->direction
);
242 DEVICE_ATTR(direction
, S_IRUGO
, adis16255_show_direction
, NULL
);
244 ssize_t
adis16255_show_sample_rate(struct device
*device
,
245 struct device_attribute
*da
,
248 struct spi_adis16255_data
*spiadis
= dev_get_drvdata(device
);
253 status
= spi_adis16255_read_data(spiadis
, ADIS_SMPL_PRD_MSB
,
259 /* timebase = 60.54 ms */
260 ts
= 60540 * ((0x7f & value
) + 1);
262 /* timebase = 1.953 ms */
263 ts
= 1953 * ((0x7f & value
) + 1);
266 return snprintf(buf
, PAGE_SIZE
, "%d\n", (1000*1000)/ts
);
268 DEVICE_ATTR(sample_rate
, S_IRUGO
, adis16255_show_sample_rate
, NULL
);
270 static struct attribute
*adis16255_attributes
[] = {
272 &dev_attr_direction
.attr
,
273 &dev_attr_sample_rate
.attr
,
277 static const struct attribute_group adis16255_attr_group
= {
278 .attrs
= adis16255_attributes
,
281 /*-------------------------------------------------------------------------*/
283 static int spi_adis16255_shutdown(struct spi_adis16255_data
*spiadis
)
286 /* turn sensor off */
287 spi_adis16255_write_data(spiadis
,
288 ADIS_SMPL_PRD_MSB
, ADIS_SMPL_PRD_LSB
,
290 spi_adis16255_write_data(spiadis
,
291 ADIS_MSC_CTRL_MSB
, ADIS_MSC_CTRL_LSB
,
296 static int spi_adis16255_bringup(struct spi_adis16255_data
*spiadis
)
301 status
= spi_adis16255_read_data(spiadis
, ADIS_GYRO_SCALE
,
305 if (value
!= 0x0800) {
306 dev_warn(&spiadis
->spi
->dev
, "Scale factor is none default"
307 "value (%.4x)\n", value
);
310 /* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */
312 status
= spi_adis16255_write_data(spiadis
,
313 ADIS_SMPL_PRD_MSB
, ADIS_SMPL_PRD_LSB
,
318 /* start internal self-test */
320 status
= spi_adis16255_write_data(spiadis
,
321 ADIS_MSC_CTRL_MSB
, ADIS_MSC_CTRL_LSB
,
326 /* wait 35 ms to finish self-test */
330 status
= spi_adis16255_read_data(spiadis
, ADIS_STATUS
,
337 dev_warn(&spiadis
->spi
->dev
, "self-test error\n");
340 } else if (value
& 0x3) {
341 dev_warn(&spiadis
->spi
->dev
, "Sensor voltage"
348 /* set interrupt to active high on DIO0 when data ready */
350 status
= spi_adis16255_write_data(spiadis
,
351 ADIS_MSC_CTRL_MSB
, ADIS_MSC_CTRL_LSB
,
358 spi_adis16255_shutdown(spiadis
);
362 /*-------------------------------------------------------------------------*/
364 static int __devinit
spi_adis16255_probe(struct spi_device
*spi
)
367 struct adis16255_init_data
*init_data
= spi
->dev
.platform_data
;
368 struct spi_adis16255_data
*spiadis
;
371 spiadis
= kzalloc(sizeof(*spiadis
), GFP_KERNEL
);
376 spiadis
->direction
= init_data
->direction
;
378 if (init_data
->negative
)
379 spiadis
->negative
= 1;
381 status
= gpio_request(init_data
->irq
, "adis16255");
385 status
= gpio_direction_input(init_data
->irq
);
389 spiadis
->irq
= gpio_to_irq(init_data
->irq
);
391 status
= request_threaded_irq(spiadis
->irq
,
392 NULL
, adis_irq_thread
,
393 IRQF_DISABLED
, "adis-driver", spiadis
);
396 dev_err(&spi
->dev
, "IRQ request failed\n");
400 dev_dbg(&spi
->dev
, "GPIO %d IRQ %d\n", init_data
->irq
, spiadis
->irq
);
402 dev_set_drvdata(&spi
->dev
, spiadis
);
403 status
= sysfs_create_group(&spi
->dev
.kobj
, &adis16255_attr_group
);
407 status
= spi_adis16255_bringup(spiadis
);
411 dev_info(&spi
->dev
, "spi_adis16255 driver added!\n");
416 free_irq(spiadis
->irq
, spiadis
);
418 gpio_free(init_data
->irq
);
424 static int __devexit
spi_adis16255_remove(struct spi_device
*spi
)
426 struct spi_adis16255_data
*spiadis
= dev_get_drvdata(&spi
->dev
);
428 spi_adis16255_shutdown(spiadis
);
430 free_irq(spiadis
->irq
, spiadis
);
431 gpio_free(irq_to_gpio(spiadis
->irq
));
433 sysfs_remove_group(&spiadis
->spi
->dev
.kobj
, &adis16255_attr_group
);
437 dev_info(&spi
->dev
, "spi_adis16255 driver removed!\n");
441 static struct spi_driver spi_adis16255_drv
= {
443 .name
= "spi_adis16255",
444 .owner
= THIS_MODULE
,
446 .probe
= spi_adis16255_probe
,
447 .remove
= __devexit_p(spi_adis16255_remove
),
450 /*-------------------------------------------------------------------------*/
452 static int __init
spi_adis16255_init(void)
454 return spi_register_driver(&spi_adis16255_drv
);
456 module_init(spi_adis16255_init
);
458 static void __exit
spi_adis16255_exit(void)
460 spi_unregister_driver(&spi_adis16255_drv
);
462 module_exit(spi_adis16255_exit
);
464 MODULE_AUTHOR("Matthias Brugger");
465 MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor");
466 MODULE_LICENSE("GPL");