1/* 2 * Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope 3 * 4 * Written by: Matthias Brugger <m_brugger@web.de> 5 * 6 * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits 7 * 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. 12 * 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. 17 * 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. 22 */ 23 24/* 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. 27 * 28 * It should be added to iio subsystem when this has left staging. 29 * 30 */ 31 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> 39 40#include <linux/interrupt.h> 41#include <linux/sysfs.h> 42#include <linux/stat.h> 43#include <linux/delay.h> 44 45#include <linux/gpio.h> 46 47#include <linux/spi/spi.h> 48#include <linux/workqueue.h> 49 50#include "adis16255.h" 51 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 64 65/* 66 * data structure for every sensor 67 * 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 75 */ 76struct spi_adis16255_data { 77 struct device dev; 78 struct spi_device *spi; 79 s16 data; 80 int irq; 81 u8 negative; 82 char direction; 83}; 84 85/*-------------------------------------------------------------------------*/ 86 87static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis, 88 u8 adr, 89 u8 *rbuf) 90{ 91 struct spi_device *spi = spiadis->spi; 92 struct spi_message msg; 93 struct spi_transfer xfer1, xfer2; 94 u8 *buf, *rx; 95 int ret; 96 97 buf = kzalloc(4, GFP_KERNEL); 98 if (buf == NULL) 99 return -ENOMEM; 100 101 rx = kzalloc(4, GFP_KERNEL); 102 if (rx == NULL) { 103 ret = -ENOMEM; 104 goto err_buf; 105 } 106 107 buf[0] = adr; 108 109 spi_message_init(&msg); 110 memset(&xfer1, 0, sizeof(xfer1)); 111 memset(&xfer2, 0, sizeof(xfer2)); 112 113 xfer1.tx_buf = buf; 114 xfer1.rx_buf = buf + 2; 115 xfer1.len = 2; 116 xfer1.delay_usecs = 9; 117 118 xfer2.tx_buf = rx + 2; 119 xfer2.rx_buf = rx; 120 xfer2.len = 2; 121 122 spi_message_add_tail(&xfer1, &msg); 123 spi_message_add_tail(&xfer2, &msg); 124 125 ret = spi_sync(spi, &msg); 126 if (ret == 0) { 127 rbuf[0] = rx[0]; 128 rbuf[1] = rx[1]; 129 } 130 131 kfree(rx); 132err_buf: 133 kfree(buf); 134 135 return ret; 136} 137 138static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis, 139 u8 adr1, 140 u8 adr2, 141 u8 *wbuf) 142{ 143 struct spi_device *spi = spiadis->spi; 144 struct spi_message msg; 145 struct spi_transfer xfer1, xfer2; 146 u8 *buf, *rx; 147 int ret; 148 149 buf = kmalloc(4, GFP_KERNEL); 150 if (buf == NULL) 151 return -ENOMEM; 152 153 rx = kzalloc(4, GFP_KERNEL); 154 if (rx == NULL) { 155 ret = -ENOMEM; 156 goto err_buf; 157 } 158 159 spi_message_init(&msg); 160 memset(&xfer1, 0, sizeof(xfer1)); 161 memset(&xfer2, 0, sizeof(xfer2)); 162 163 buf[0] = adr1 | 0x80; 164 buf[1] = *wbuf; 165 166 buf[2] = adr2 | 0x80; 167 buf[3] = *(wbuf + 1); 168 169 xfer1.tx_buf = buf; 170 xfer1.rx_buf = rx; 171 xfer1.len = 2; 172 xfer1.delay_usecs = 9; 173 174 xfer2.tx_buf = buf+2; 175 xfer2.rx_buf = rx+2; 176 xfer2.len = 2; 177 178 spi_message_add_tail(&xfer1, &msg); 179 spi_message_add_tail(&xfer2, &msg); 180 181 ret = spi_sync(spi, &msg); 182 if (ret != 0) 183 dev_warn(&spi->dev, "write data to %#x %#x failed\n", 184 buf[0], buf[2]); 185 186 kfree(rx); 187err_buf: 188 kfree(buf); 189 return ret; 190} 191 192/*-------------------------------------------------------------------------*/ 193 194static irqreturn_t adis_irq_thread(int irq, void *dev_id) 195{ 196 struct spi_adis16255_data *spiadis = dev_id; 197 int status; 198 u16 value = 0; 199 200 status = spi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value); 201 if (status != 0) { 202 dev_warn(&spiadis->spi->dev, "SPI FAILED\n"); 203 goto exit; 204 } 205 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 */ 211 if (value & 0x2000) 212 value = value | 0xe000; 213 214 if (likely(spiadis->negative)) 215 value = -value; 216 217 spiadis->data = (s16) value; 218 } 219 220exit: 221 return IRQ_HANDLED; 222} 223 224/*-------------------------------------------------------------------------*/ 225 226ssize_t adis16255_show_data(struct device *device, 227 struct device_attribute *da, 228 char *buf) 229{ 230 struct spi_adis16255_data *spiadis = dev_get_drvdata(device); 231 return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data); 232} 233DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL); 234 235ssize_t adis16255_show_direction(struct device *device, 236 struct device_attribute *da, 237 char *buf) 238{ 239 struct spi_adis16255_data *spiadis = dev_get_drvdata(device); 240 return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction); 241} 242DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL); 243 244ssize_t adis16255_show_sample_rate(struct device *device, 245 struct device_attribute *da, 246 char *buf) 247{ 248 struct spi_adis16255_data *spiadis = dev_get_drvdata(device); 249 int status = 0; 250 u16 value = 0; 251 int ts = 0; 252 253 status = spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB, 254 (u8 *)&value); 255 if (status != 0) 256 return -EINVAL; 257 258 if (value & 0x80) { 259 /* timebase = 60.54 ms */ 260 ts = 60540 * ((0x7f & value) + 1); 261 } else { 262 /* timebase = 1.953 ms */ 263 ts = 1953 * ((0x7f & value) + 1); 264 } 265 266 return snprintf(buf, PAGE_SIZE, "%d\n", (1000*1000)/ts); 267} 268DEVICE_ATTR(sample_rate, S_IRUGO , adis16255_show_sample_rate, NULL); 269 270static struct attribute *adis16255_attributes[] = { 271 &dev_attr_data.attr, 272 &dev_attr_direction.attr, 273 &dev_attr_sample_rate.attr, 274 NULL 275}; 276 277static const struct attribute_group adis16255_attr_group = { 278 .attrs = adis16255_attributes, 279}; 280 281/*-------------------------------------------------------------------------*/ 282 283static int spi_adis16255_shutdown(struct spi_adis16255_data *spiadis) 284{ 285 u16 value = 0; 286 /* turn sensor off */ 287 spi_adis16255_write_data(spiadis, 288 ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, 289 (u8 *)&value); 290 spi_adis16255_write_data(spiadis, 291 ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, 292 (u8 *)&value); 293 return 0; 294} 295 296static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis) 297{ 298 int status = 0; 299 u16 value = 0; 300 301 status = spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE, 302 (u8 *)&value); 303 if (status != 0) 304 goto err; 305 if (value != 0x0800) { 306 dev_warn(&spiadis->spi->dev, "Scale factor is none default " 307 "value (%.4x)\n", value); 308 } 309 310 /* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */ 311 value = 0x0001; 312 status = spi_adis16255_write_data(spiadis, 313 ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, 314 (u8 *)&value); 315 if (status != 0) 316 goto err; 317 318 /* start internal self-test */ 319 value = 0x0400; 320 status = spi_adis16255_write_data(spiadis, 321 ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, 322 (u8 *)&value); 323 if (status != 0) 324 goto err; 325 326 /* wait 35 ms to finish self-test */ 327 msleep(35); 328 329 value = 0x0000; 330 status = spi_adis16255_read_data(spiadis, ADIS_STATUS, 331 (u8 *)&value); 332 if (status != 0) 333 goto err; 334 335 if (value & 0x23) { 336 if (value & 0x20) { 337 dev_warn(&spiadis->spi->dev, "self-test error\n"); 338 status = -ENODEV; 339 goto err; 340 } else if (value & 0x3) { 341 dev_warn(&spiadis->spi->dev, "Sensor voltage " 342 "out of range.\n"); 343 status = -ENODEV; 344 goto err; 345 } 346 } 347 348 /* set interrupt to active high on DIO0 when data ready */ 349 value = 0x0006; 350 status = spi_adis16255_write_data(spiadis, 351 ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, 352 (u8 *)&value); 353 if (status != 0) 354 goto err; 355 return status; 356 357err: 358 spi_adis16255_shutdown(spiadis); 359 return status; 360} 361 362/*-------------------------------------------------------------------------*/ 363 364static int __devinit spi_adis16255_probe(struct spi_device *spi) 365{ 366 367 struct adis16255_init_data *init_data = spi->dev.platform_data; 368 struct spi_adis16255_data *spiadis; 369 int status = 0; 370 371 spiadis = kzalloc(sizeof(*spiadis), GFP_KERNEL); 372 if (!spiadis) 373 return -ENOMEM; 374 375 spiadis->spi = spi; 376 spiadis->direction = init_data->direction; 377 378 if (init_data->negative) 379 spiadis->negative = 1; 380 381 status = gpio_request(init_data->irq, "adis16255"); 382 if (status != 0) 383 goto err; 384 385 status = gpio_direction_input(init_data->irq); 386 if (status != 0) 387 goto gpio_err; 388 389 spiadis->irq = gpio_to_irq(init_data->irq); 390 391 status = request_threaded_irq(spiadis->irq, 392 NULL, adis_irq_thread, 393 IRQF_DISABLED, "adis-driver", spiadis); 394 395 if (status != 0) { 396 dev_err(&spi->dev, "IRQ request failed\n"); 397 goto gpio_err; 398 } 399 400 dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", init_data->irq, spiadis->irq); 401 402 dev_set_drvdata(&spi->dev, spiadis); 403 status = sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group); 404 if (status != 0) 405 goto irq_err; 406 407 status = spi_adis16255_bringup(spiadis); 408 if (status != 0) 409 goto irq_err; 410 411 dev_info(&spi->dev, "spi_adis16255 driver added!\n"); 412 413 return status; 414 415irq_err: 416 free_irq(spiadis->irq, spiadis); 417gpio_err: 418 gpio_free(init_data->irq); 419err: 420 kfree(spiadis); 421 return status; 422} 423 424static int __devexit spi_adis16255_remove(struct spi_device *spi) 425{ 426 struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev); 427 428 spi_adis16255_shutdown(spiadis); 429 430 free_irq(spiadis->irq, spiadis); 431 gpio_free(irq_to_gpio(spiadis->irq)); 432 433 sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group); 434 435 kfree(spiadis); 436 437 dev_info(&spi->dev, "spi_adis16255 driver removed!\n"); 438 return 0; 439} 440 441static struct spi_driver spi_adis16255_drv = { 442 .driver = { 443 .name = "spi_adis16255", 444 .owner = THIS_MODULE, 445 }, 446 .probe = spi_adis16255_probe, 447 .remove = __devexit_p(spi_adis16255_remove), 448}; 449 450/*-------------------------------------------------------------------------*/ 451 452static int __init spi_adis16255_init(void) 453{ 454 return spi_register_driver(&spi_adis16255_drv); 455} 456module_init(spi_adis16255_init); 457 458static void __exit spi_adis16255_exit(void) 459{ 460 spi_unregister_driver(&spi_adis16255_drv); 461} 462module_exit(spi_adis16255_exit); 463 464MODULE_AUTHOR("Matthias Brugger"); 465MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor"); 466MODULE_LICENSE("GPL"); 467