x9250.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. *
  4. * x9250.c -- Renesas X9250 potentiometers IIO driver
  5. *
  6. * Copyright 2023 CS GROUP France
  7. *
  8. * Author: Herve Codina <herve.codina@bootlin.com>
  9. */
  10. #include <linux/delay.h>
  11. #include <linux/gpio/consumer.h>
  12. #include <linux/iio/iio.h>
  13. #include <linux/limits.h>
  14. #include <linux/module.h>
  15. #include <linux/regulator/consumer.h>
  16. #include <linux/slab.h>
  17. #include <linux/spi/spi.h>
  18. struct x9250_cfg {
  19. const char *name;
  20. int kohms;
  21. };
  22. struct x9250 {
  23. struct spi_device *spi;
  24. const struct x9250_cfg *cfg;
  25. struct gpio_desc *wp_gpio;
  26. };
  27. #define X9250_ID 0x50
  28. #define X9250_CMD_RD_WCR(_p) (0x90 | (_p))
  29. #define X9250_CMD_WR_WCR(_p) (0xa0 | (_p))
  30. static int x9250_write8(struct x9250 *x9250, u8 cmd, u8 val)
  31. {
  32. u8 txbuf[3];
  33. txbuf[0] = X9250_ID;
  34. txbuf[1] = cmd;
  35. txbuf[2] = val;
  36. return spi_write_then_read(x9250->spi, txbuf, ARRAY_SIZE(txbuf), NULL, 0);
  37. }
  38. static int x9250_read8(struct x9250 *x9250, u8 cmd, u8 *val)
  39. {
  40. u8 txbuf[2];
  41. txbuf[0] = X9250_ID;
  42. txbuf[1] = cmd;
  43. return spi_write_then_read(x9250->spi, txbuf, ARRAY_SIZE(txbuf), val, 1);
  44. }
  45. #define X9250_CHANNEL(ch) { \
  46. .type = IIO_RESISTANCE, \
  47. .indexed = 1, \
  48. .output = 1, \
  49. .channel = (ch), \
  50. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  51. .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
  52. .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_RAW), \
  53. }
  54. static const struct iio_chan_spec x9250_channels[] = {
  55. X9250_CHANNEL(0),
  56. X9250_CHANNEL(1),
  57. X9250_CHANNEL(2),
  58. X9250_CHANNEL(3),
  59. };
  60. static int x9250_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  61. int *val, int *val2, long mask)
  62. {
  63. struct x9250 *x9250 = iio_priv(indio_dev);
  64. int ch = chan->channel;
  65. int ret;
  66. u8 v;
  67. switch (mask) {
  68. case IIO_CHAN_INFO_RAW:
  69. ret = x9250_read8(x9250, X9250_CMD_RD_WCR(ch), &v);
  70. if (ret)
  71. return ret;
  72. *val = v;
  73. return IIO_VAL_INT;
  74. case IIO_CHAN_INFO_SCALE:
  75. *val = 1000 * x9250->cfg->kohms;
  76. *val2 = U8_MAX;
  77. return IIO_VAL_FRACTIONAL;
  78. }
  79. return -EINVAL;
  80. }
  81. static int x9250_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  82. const int **vals, int *type, int *length, long mask)
  83. {
  84. static const int range[] = {0, 1, 255}; /* min, step, max */
  85. switch (mask) {
  86. case IIO_CHAN_INFO_RAW:
  87. *length = ARRAY_SIZE(range);
  88. *vals = range;
  89. *type = IIO_VAL_INT;
  90. return IIO_AVAIL_RANGE;
  91. }
  92. return -EINVAL;
  93. }
  94. static int x9250_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  95. int val, int val2, long mask)
  96. {
  97. struct x9250 *x9250 = iio_priv(indio_dev);
  98. int ch = chan->channel;
  99. int ret;
  100. if (mask != IIO_CHAN_INFO_RAW)
  101. return -EINVAL;
  102. if (val > U8_MAX || val < 0)
  103. return -EINVAL;
  104. gpiod_set_value_cansleep(x9250->wp_gpio, 0);
  105. ret = x9250_write8(x9250, X9250_CMD_WR_WCR(ch), val);
  106. gpiod_set_value_cansleep(x9250->wp_gpio, 1);
  107. return ret;
  108. }
  109. static const struct iio_info x9250_info = {
  110. .read_raw = x9250_read_raw,
  111. .read_avail = x9250_read_avail,
  112. .write_raw = x9250_write_raw,
  113. };
  114. enum x9250_type {
  115. X9250T,
  116. X9250U,
  117. };
  118. static const struct x9250_cfg x9250_cfg[] = {
  119. [X9250T] = { .name = "x9250t", .kohms = 100, },
  120. [X9250U] = { .name = "x9250u", .kohms = 50, },
  121. };
  122. static const char *const x9250_regulator_names[] = {
  123. "vcc",
  124. "avp",
  125. "avn",
  126. };
  127. static int x9250_probe(struct spi_device *spi)
  128. {
  129. struct iio_dev *indio_dev;
  130. struct x9250 *x9250;
  131. int ret;
  132. ret = devm_regulator_bulk_get_enable(&spi->dev, ARRAY_SIZE(x9250_regulator_names),
  133. x9250_regulator_names);
  134. if (ret)
  135. return dev_err_probe(&spi->dev, ret, "Failed to get regulators\n");
  136. /*
  137. * The x9250 needs a 5ms maximum delay after the power-supplies are set
  138. * before performing the first write (1ms for the first read).
  139. */
  140. usleep_range(5000, 6000);
  141. indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*x9250));
  142. if (!indio_dev)
  143. return -ENOMEM;
  144. x9250 = iio_priv(indio_dev);
  145. x9250->spi = spi;
  146. x9250->cfg = spi_get_device_match_data(spi);
  147. x9250->wp_gpio = devm_gpiod_get_optional(&spi->dev, "wp", GPIOD_OUT_LOW);
  148. if (IS_ERR(x9250->wp_gpio))
  149. return dev_err_probe(&spi->dev, PTR_ERR(x9250->wp_gpio),
  150. "failed to get wp gpio\n");
  151. indio_dev->info = &x9250_info;
  152. indio_dev->channels = x9250_channels;
  153. indio_dev->num_channels = ARRAY_SIZE(x9250_channels);
  154. indio_dev->name = x9250->cfg->name;
  155. return devm_iio_device_register(&spi->dev, indio_dev);
  156. }
  157. static const struct of_device_id x9250_of_match[] = {
  158. { .compatible = "renesas,x9250t", .data = &x9250_cfg[X9250T]},
  159. { .compatible = "renesas,x9250u", .data = &x9250_cfg[X9250U]},
  160. { }
  161. };
  162. MODULE_DEVICE_TABLE(of, x9250_of_match);
  163. static const struct spi_device_id x9250_id_table[] = {
  164. { "x9250t", (kernel_ulong_t)&x9250_cfg[X9250T] },
  165. { "x9250u", (kernel_ulong_t)&x9250_cfg[X9250U] },
  166. { }
  167. };
  168. MODULE_DEVICE_TABLE(spi, x9250_id_table);
  169. static struct spi_driver x9250_spi_driver = {
  170. .driver = {
  171. .name = "x9250",
  172. .of_match_table = x9250_of_match,
  173. },
  174. .id_table = x9250_id_table,
  175. .probe = x9250_probe,
  176. };
  177. module_spi_driver(x9250_spi_driver);
  178. MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
  179. MODULE_DESCRIPTION("X9250 ALSA SoC driver");
  180. MODULE_LICENSE("GPL");