/drivers/staging/iio/dds/ad9951.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 241 lines · 181 code · 49 blank · 11 comment · 9 complexity · 9983eb70a7cb395d5b3af5449b3e8c55 MD5 · raw file

  1. /*
  2. * Driver for ADI Direct Digital Synthesis ad9951
  3. *
  4. * Copyright (c) 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 "../iio.h"
  18. #include "../sysfs.h"
  19. #define DRV_NAME "ad9951"
  20. #define CFR1 0x0
  21. #define CFR2 0x1
  22. #define AUTO_OSK (1)
  23. #define OSKEN (1 << 1)
  24. #define LOAD_ARR (1 << 2)
  25. #define AUTO_SYNC (1 << 7)
  26. #define LSB_FST (1)
  27. #define SDIO_IPT (1 << 1)
  28. #define CLR_PHA (1 << 2)
  29. #define SINE_OPT (1 << 4)
  30. #define ACLR_PHA (1 << 5)
  31. #define VCO_RANGE (1 << 2)
  32. #define CRS_OPT (1 << 1)
  33. #define HMANU_SYNC (1 << 2)
  34. #define HSPD_SYNC (1 << 3)
  35. /* Register format: 1 byte addr + value */
  36. struct ad9951_config {
  37. u8 asf[3];
  38. u8 arr[2];
  39. u8 ftw0[5];
  40. u8 ftw1[3];
  41. };
  42. struct ad9951_state {
  43. struct mutex lock;
  44. struct spi_device *sdev;
  45. };
  46. static ssize_t ad9951_set_parameter(struct device *dev,
  47. struct device_attribute *attr,
  48. const char *buf,
  49. size_t len)
  50. {
  51. struct spi_message msg;
  52. struct spi_transfer xfer;
  53. int ret;
  54. struct ad9951_config *config = (struct ad9951_config *)buf;
  55. struct iio_dev *idev = dev_get_drvdata(dev);
  56. struct ad9951_state *st = iio_priv(idev);
  57. xfer.len = 3;
  58. xfer.tx_buf = &config->asf[0];
  59. mutex_lock(&st->lock);
  60. spi_message_init(&msg);
  61. spi_message_add_tail(&xfer, &msg);
  62. ret = spi_sync(st->sdev, &msg);
  63. if (ret)
  64. goto error_ret;
  65. xfer.len = 2;
  66. xfer.tx_buf = &config->arr[0];
  67. spi_message_init(&msg);
  68. spi_message_add_tail(&xfer, &msg);
  69. ret = spi_sync(st->sdev, &msg);
  70. if (ret)
  71. goto error_ret;
  72. xfer.len = 5;
  73. xfer.tx_buf = &config->ftw0[0];
  74. spi_message_init(&msg);
  75. spi_message_add_tail(&xfer, &msg);
  76. ret = spi_sync(st->sdev, &msg);
  77. if (ret)
  78. goto error_ret;
  79. xfer.len = 3;
  80. xfer.tx_buf = &config->ftw1[0];
  81. spi_message_init(&msg);
  82. spi_message_add_tail(&xfer, &msg);
  83. ret = spi_sync(st->sdev, &msg);
  84. if (ret)
  85. goto error_ret;
  86. error_ret:
  87. mutex_unlock(&st->lock);
  88. return ret ? ret : len;
  89. }
  90. static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
  91. static void ad9951_init(struct ad9951_state *st)
  92. {
  93. struct spi_message msg;
  94. struct spi_transfer xfer;
  95. int ret;
  96. u8 cfr[5];
  97. cfr[0] = CFR1;
  98. cfr[1] = 0;
  99. cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA;
  100. cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR;
  101. cfr[4] = 0;
  102. mutex_lock(&st->lock);
  103. xfer.len = 5;
  104. xfer.tx_buf = &cfr;
  105. spi_message_init(&msg);
  106. spi_message_add_tail(&xfer, &msg);
  107. ret = spi_sync(st->sdev, &msg);
  108. if (ret)
  109. goto error_ret;
  110. cfr[0] = CFR2;
  111. cfr[1] = VCO_RANGE;
  112. cfr[2] = HSPD_SYNC;
  113. cfr[3] = 0;
  114. xfer.len = 4;
  115. xfer.tx_buf = &cfr;
  116. spi_message_init(&msg);
  117. spi_message_add_tail(&xfer, &msg);
  118. ret = spi_sync(st->sdev, &msg);
  119. if (ret)
  120. goto error_ret;
  121. error_ret:
  122. mutex_unlock(&st->lock);
  123. }
  124. static struct attribute *ad9951_attributes[] = {
  125. &iio_dev_attr_dds.dev_attr.attr,
  126. NULL,
  127. };
  128. static const struct attribute_group ad9951_attribute_group = {
  129. .name = DRV_NAME,
  130. .attrs = ad9951_attributes,
  131. };
  132. static const struct iio_info ad9951_info = {
  133. .attrs = &ad9951_attribute_group,
  134. .driver_module = THIS_MODULE,
  135. };
  136. static int __devinit ad9951_probe(struct spi_device *spi)
  137. {
  138. struct ad9951_state *st;
  139. struct iio_dev *idev;
  140. int ret = 0;
  141. idev = iio_allocate_device(sizeof(*st));
  142. if (idev == NULL) {
  143. ret = -ENOMEM;
  144. goto error_ret;
  145. }
  146. spi_set_drvdata(spi, idev);
  147. st = iio_priv(idev);
  148. mutex_init(&st->lock);
  149. st->sdev = spi;
  150. idev->dev.parent = &spi->dev;
  151. idev->info = &ad9951_info;
  152. idev->modes = INDIO_DIRECT_MODE;
  153. ret = iio_device_register(idev);
  154. if (ret)
  155. goto error_free_dev;
  156. spi->max_speed_hz = 2000000;
  157. spi->mode = SPI_MODE_3;
  158. spi->bits_per_word = 8;
  159. spi_setup(spi);
  160. ad9951_init(st);
  161. return 0;
  162. error_free_dev:
  163. iio_free_device(idev);
  164. error_ret:
  165. return ret;
  166. }
  167. static int __devexit ad9951_remove(struct spi_device *spi)
  168. {
  169. iio_device_unregister(spi_get_drvdata(spi));
  170. return 0;
  171. }
  172. static struct spi_driver ad9951_driver = {
  173. .driver = {
  174. .name = DRV_NAME,
  175. .owner = THIS_MODULE,
  176. },
  177. .probe = ad9951_probe,
  178. .remove = __devexit_p(ad9951_remove),
  179. };
  180. static __init int ad9951_spi_init(void)
  181. {
  182. return spi_register_driver(&ad9951_driver);
  183. }
  184. module_init(ad9951_spi_init);
  185. static __exit void ad9951_spi_exit(void)
  186. {
  187. spi_unregister_driver(&ad9951_driver);
  188. }
  189. module_exit(ad9951_spi_exit);
  190. MODULE_AUTHOR("Cliff Cai");
  191. MODULE_DESCRIPTION("Analog Devices ad9951 driver");
  192. MODULE_LICENSE("GPL v2");