/drivers/staging/iio/addac/adt7316-spi.c

https://bitbucket.org/wisechild/galaxy-nexus · C · 180 lines · 131 code · 33 blank · 16 comment · 7 complexity · 13484eec0955312ac08b585504574282 MD5 · raw file

  1. /*
  2. * API bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature
  3. * sensor, ADC and DAC
  4. *
  5. * Copyright 2010 Analog Devices Inc.
  6. *
  7. * Licensed under the GPL-2 or later.
  8. */
  9. #include <linux/device.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/spi/spi.h>
  14. #include "adt7316.h"
  15. #define ADT7316_SPI_MAX_FREQ_HZ 5000000
  16. #define ADT7316_SPI_CMD_READ 0x91
  17. #define ADT7316_SPI_CMD_WRITE 0x90
  18. /*
  19. * adt7316 register access by SPI
  20. */
  21. static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data)
  22. {
  23. struct spi_device *spi_dev = client;
  24. u8 cmd[2];
  25. int ret = 0;
  26. if (count > ADT7316_REG_MAX_ADDR)
  27. count = ADT7316_REG_MAX_ADDR;
  28. cmd[0] = ADT7316_SPI_CMD_WRITE;
  29. cmd[1] = reg;
  30. ret = spi_write(spi_dev, cmd, 2);
  31. if (ret < 0) {
  32. dev_err(&spi_dev->dev, "SPI fail to select reg\n");
  33. return ret;
  34. }
  35. cmd[0] = ADT7316_SPI_CMD_READ;
  36. ret = spi_write_then_read(spi_dev, cmd, 1, data, count);
  37. if (ret < 0) {
  38. dev_err(&spi_dev->dev, "SPI read data error\n");
  39. return ret;
  40. }
  41. return 0;
  42. }
  43. static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data)
  44. {
  45. struct spi_device *spi_dev = client;
  46. u8 buf[ADT7316_REG_MAX_ADDR + 2];
  47. int i, ret = 0;
  48. if (count > ADT7316_REG_MAX_ADDR)
  49. count = ADT7316_REG_MAX_ADDR;
  50. buf[0] = ADT7316_SPI_CMD_WRITE;
  51. buf[1] = reg;
  52. for (i = 0; i < count; i++)
  53. buf[i + 2] = data[i];
  54. ret = spi_write(spi_dev, buf, count + 2);
  55. if (ret < 0) {
  56. dev_err(&spi_dev->dev, "SPI write error\n");
  57. return ret;
  58. }
  59. return ret;
  60. }
  61. static int adt7316_spi_read(void *client, u8 reg, u8 *data)
  62. {
  63. return adt7316_spi_multi_read(client, reg, 1, data);
  64. }
  65. static int adt7316_spi_write(void *client, u8 reg, u8 val)
  66. {
  67. return adt7316_spi_multi_write(client, reg, 1, &val);
  68. }
  69. /*
  70. * device probe and remove
  71. */
  72. static int __devinit adt7316_spi_probe(struct spi_device *spi_dev)
  73. {
  74. struct adt7316_bus bus = {
  75. .client = spi_dev,
  76. .irq = spi_dev->irq,
  77. .irq_flags = IRQF_TRIGGER_LOW,
  78. .read = adt7316_spi_read,
  79. .write = adt7316_spi_write,
  80. .multi_read = adt7316_spi_multi_read,
  81. .multi_write = adt7316_spi_multi_write,
  82. };
  83. /* don't exceed max specified SPI CLK frequency */
  84. if (spi_dev->max_speed_hz > ADT7316_SPI_MAX_FREQ_HZ) {
  85. dev_err(&spi_dev->dev, "SPI CLK %d Hz?\n",
  86. spi_dev->max_speed_hz);
  87. return -EINVAL;
  88. }
  89. /* switch from default I2C protocol to SPI protocol */
  90. adt7316_spi_write(spi_dev, 0, 0);
  91. adt7316_spi_write(spi_dev, 0, 0);
  92. adt7316_spi_write(spi_dev, 0, 0);
  93. return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
  94. }
  95. static int __devexit adt7316_spi_remove(struct spi_device *spi_dev)
  96. {
  97. return adt7316_remove(&spi_dev->dev);
  98. }
  99. static const struct spi_device_id adt7316_spi_id[] = {
  100. { "adt7316", 0 },
  101. { "adt7317", 0 },
  102. { "adt7318", 0 },
  103. { "adt7516", 0 },
  104. { "adt7517", 0 },
  105. { "adt7519", 0 },
  106. { }
  107. };
  108. MODULE_DEVICE_TABLE(spi, adt7316_spi_id);
  109. #ifdef CONFIG_PM
  110. static int adt7316_spi_suspend(struct spi_device *spi_dev, pm_message_t message)
  111. {
  112. return adt7316_disable(&spi_dev->dev);
  113. }
  114. static int adt7316_spi_resume(struct spi_device *spi_dev)
  115. {
  116. return adt7316_enable(&spi_dev->dev);
  117. }
  118. #else
  119. # define adt7316_spi_suspend NULL
  120. # define adt7316_spi_resume NULL
  121. #endif
  122. static struct spi_driver adt7316_driver = {
  123. .driver = {
  124. .name = "adt7316",
  125. .bus = &spi_bus_type,
  126. .owner = THIS_MODULE,
  127. },
  128. .probe = adt7316_spi_probe,
  129. .remove = __devexit_p(adt7316_spi_remove),
  130. .suspend = adt7316_spi_suspend,
  131. .resume = adt7316_spi_resume,
  132. .id_table = adt7316_spi_id,
  133. };
  134. static __init int adt7316_spi_init(void)
  135. {
  136. return spi_register_driver(&adt7316_driver);
  137. }
  138. static __exit void adt7316_spi_exit(void)
  139. {
  140. spi_unregister_driver(&adt7316_driver);
  141. }
  142. MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
  143. MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
  144. "ADT7516/7/9 digital temperature sensor, ADC and DAC");
  145. MODULE_LICENSE("GPL v2");
  146. module_init(adt7316_spi_init);
  147. module_exit(adt7316_spi_exit);