/drivers/staging/iio/resolver/ad2s120x.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 177 lines · 136 code · 26 blank · 15 comment · 9 complexity · b6cfebde4352d3323edb33e28910a036 MD5 · raw file

  1. /*
  2. * ad2s120x.c simple support for the ADI Resolver to Digital Converters: AD2S1200/1205
  3. *
  4. * Copyright (c) 2010-2010 Analog Devices Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. */
  11. #include <linux/types.h>
  12. #include <linux/mutex.h>
  13. #include <linux/device.h>
  14. #include <linux/spi/spi.h>
  15. #include <linux/slab.h>
  16. #include <linux/sysfs.h>
  17. #include <linux/delay.h>
  18. #include <linux/gpio.h>
  19. #include "../iio.h"
  20. #include "../sysfs.h"
  21. #define DRV_NAME "ad2s120x"
  22. /* input pin sample and rdvel is controlled by driver */
  23. #define AD2S120X_PN 2
  24. /* input clock on serial interface */
  25. #define AD2S120X_HZ 8192000
  26. /* clock period in nano second */
  27. #define AD2S120X_TSCLK (1000000000/AD2S120X_HZ)
  28. struct ad2s120x_state {
  29. struct mutex lock;
  30. struct spi_device *sdev;
  31. int sample;
  32. int rdvel;
  33. u8 rx[2] ____cacheline_aligned;
  34. };
  35. static ssize_t ad2s120x_show_val(struct device *dev,
  36. struct device_attribute *attr, char *buf)
  37. {
  38. int ret = 0;
  39. ssize_t len = 0;
  40. u16 pos;
  41. s16 vel;
  42. u8 status;
  43. struct ad2s120x_state *st = iio_priv(dev_get_drvdata(dev));
  44. struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
  45. mutex_lock(&st->lock);
  46. gpio_set_value(st->sample, 0);
  47. /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */
  48. udelay(1);
  49. gpio_set_value(st->sample, 1);
  50. gpio_set_value(st->rdvel, iattr->address);
  51. ret = spi_read(st->sdev, st->rx, 2);
  52. if (ret < 0)
  53. goto error_ret;
  54. status = st->rx[1];
  55. if (iattr->address)
  56. pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
  57. else {
  58. vel = (st->rx[0] & 0x80) ? 0xf000 : 0;
  59. vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4);
  60. }
  61. len = sprintf(buf, "%d %c%c%c%c ", iattr->address ? pos : vel,
  62. (status & 0x8) ? 'P' : 'V',
  63. (status & 0x4) ? 'd' : '_',
  64. (status & 0x2) ? 'l' : '_',
  65. (status & 0x1) ? '1' : '0');
  66. error_ret:
  67. /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */
  68. udelay(1);
  69. mutex_unlock(&st->lock);
  70. return ret ? ret : len;
  71. }
  72. static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_val, NULL, 1);
  73. static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_val, NULL, 0);
  74. static struct attribute *ad2s120x_attributes[] = {
  75. &iio_dev_attr_pos.dev_attr.attr,
  76. &iio_dev_attr_vel.dev_attr.attr,
  77. NULL,
  78. };
  79. static const struct attribute_group ad2s120x_attribute_group = {
  80. .attrs = ad2s120x_attributes,
  81. };
  82. static const struct iio_info ad2s120x_info = {
  83. .attrs = &ad2s120x_attribute_group,
  84. .driver_module = THIS_MODULE,
  85. };
  86. static int __devinit ad2s120x_probe(struct spi_device *spi)
  87. {
  88. struct ad2s120x_state *st;
  89. struct iio_dev *indio_dev;
  90. int pn, ret = 0;
  91. unsigned short *pins = spi->dev.platform_data;
  92. for (pn = 0; pn < AD2S120X_PN; pn++)
  93. if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
  94. pr_err("%s: request gpio pin %d failed\n",
  95. DRV_NAME, pins[pn]);
  96. goto error_ret;
  97. }
  98. indio_dev = iio_allocate_device(sizeof(*st));
  99. if (indio_dev == NULL) {
  100. ret = -ENOMEM;
  101. goto error_ret;
  102. }
  103. spi_set_drvdata(spi, indio_dev);
  104. st = iio_priv(indio_dev);
  105. mutex_init(&st->lock);
  106. st->sdev = spi;
  107. st->sample = pins[0];
  108. st->rdvel = pins[1];
  109. indio_dev->dev.parent = &spi->dev;
  110. indio_dev->info = &ad2s120x_info;
  111. indio_dev->modes = INDIO_DIRECT_MODE;
  112. ret = iio_device_register(indio_dev);
  113. if (ret)
  114. goto error_free_dev;
  115. spi->max_speed_hz = AD2S120X_HZ;
  116. spi->mode = SPI_MODE_3;
  117. spi_setup(spi);
  118. return 0;
  119. error_free_dev:
  120. iio_free_device(indio_dev);
  121. error_ret:
  122. for (--pn; pn >= 0; pn--)
  123. gpio_free(pins[pn]);
  124. return ret;
  125. }
  126. static int __devexit ad2s120x_remove(struct spi_device *spi)
  127. {
  128. iio_device_unregister(spi_get_drvdata(spi));
  129. return 0;
  130. }
  131. static struct spi_driver ad2s120x_driver = {
  132. .driver = {
  133. .name = DRV_NAME,
  134. .owner = THIS_MODULE,
  135. },
  136. .probe = ad2s120x_probe,
  137. .remove = __devexit_p(ad2s120x_remove),
  138. };
  139. static __init int ad2s120x_spi_init(void)
  140. {
  141. return spi_register_driver(&ad2s120x_driver);
  142. }
  143. module_init(ad2s120x_spi_init);
  144. static __exit void ad2s120x_spi_exit(void)
  145. {
  146. spi_unregister_driver(&ad2s120x_driver);
  147. }
  148. module_exit(ad2s120x_spi_exit);
  149. MODULE_AUTHOR("Graff Yang <graff.yang@gmail.com>");
  150. MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver");
  151. MODULE_LICENSE("GPL v2");