tsc2007_iio.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016 Golden Delicious Comp. GmbH&Co. KG
  4. * Nikolaus Schaller <[email protected]>
  5. */
  6. #include <linux/i2c.h>
  7. #include <linux/iio/iio.h>
  8. #include "tsc2007.h"
  9. struct tsc2007_iio {
  10. struct tsc2007 *ts;
  11. };
  12. #define TSC2007_CHAN_IIO(_chan, _name, _type, _chan_info) \
  13. { \
  14. .datasheet_name = _name, \
  15. .type = _type, \
  16. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
  17. BIT(_chan_info), \
  18. .indexed = 1, \
  19. .channel = _chan, \
  20. }
  21. static const struct iio_chan_spec tsc2007_iio_channel[] = {
  22. TSC2007_CHAN_IIO(0, "x", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
  23. TSC2007_CHAN_IIO(1, "y", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
  24. TSC2007_CHAN_IIO(2, "z1", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
  25. TSC2007_CHAN_IIO(3, "z2", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
  26. TSC2007_CHAN_IIO(4, "adc", IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
  27. TSC2007_CHAN_IIO(5, "rt", IIO_VOLTAGE, IIO_CHAN_INFO_RAW), /* Ohms? */
  28. TSC2007_CHAN_IIO(6, "pen", IIO_PRESSURE, IIO_CHAN_INFO_RAW),
  29. TSC2007_CHAN_IIO(7, "temp0", IIO_TEMP, IIO_CHAN_INFO_RAW),
  30. TSC2007_CHAN_IIO(8, "temp1", IIO_TEMP, IIO_CHAN_INFO_RAW),
  31. };
  32. static int tsc2007_read_raw(struct iio_dev *indio_dev,
  33. struct iio_chan_spec const *chan,
  34. int *val, int *val2, long mask)
  35. {
  36. struct tsc2007_iio *iio = iio_priv(indio_dev);
  37. struct tsc2007 *tsc = iio->ts;
  38. int adc_chan = chan->channel;
  39. int ret = 0;
  40. if (adc_chan >= ARRAY_SIZE(tsc2007_iio_channel))
  41. return -EINVAL;
  42. if (mask != IIO_CHAN_INFO_RAW)
  43. return -EINVAL;
  44. mutex_lock(&tsc->mlock);
  45. switch (chan->channel) {
  46. case 0:
  47. *val = tsc2007_xfer(tsc, READ_X);
  48. break;
  49. case 1:
  50. *val = tsc2007_xfer(tsc, READ_Y);
  51. break;
  52. case 2:
  53. *val = tsc2007_xfer(tsc, READ_Z1);
  54. break;
  55. case 3:
  56. *val = tsc2007_xfer(tsc, READ_Z2);
  57. break;
  58. case 4:
  59. *val = tsc2007_xfer(tsc, (ADC_ON_12BIT | TSC2007_MEASURE_AUX));
  60. break;
  61. case 5: {
  62. struct ts_event tc;
  63. tc.x = tsc2007_xfer(tsc, READ_X);
  64. tc.z1 = tsc2007_xfer(tsc, READ_Z1);
  65. tc.z2 = tsc2007_xfer(tsc, READ_Z2);
  66. *val = tsc2007_calculate_resistance(tsc, &tc);
  67. break;
  68. }
  69. case 6:
  70. *val = tsc2007_is_pen_down(tsc);
  71. break;
  72. case 7:
  73. *val = tsc2007_xfer(tsc,
  74. (ADC_ON_12BIT | TSC2007_MEASURE_TEMP0));
  75. break;
  76. case 8:
  77. *val = tsc2007_xfer(tsc,
  78. (ADC_ON_12BIT | TSC2007_MEASURE_TEMP1));
  79. break;
  80. }
  81. /* Prepare for next touch reading - power down ADC, enable PENIRQ */
  82. tsc2007_xfer(tsc, PWRDOWN);
  83. mutex_unlock(&tsc->mlock);
  84. ret = IIO_VAL_INT;
  85. return ret;
  86. }
  87. static const struct iio_info tsc2007_iio_info = {
  88. .read_raw = tsc2007_read_raw,
  89. };
  90. int tsc2007_iio_configure(struct tsc2007 *ts)
  91. {
  92. struct iio_dev *indio_dev;
  93. struct tsc2007_iio *iio;
  94. int error;
  95. indio_dev = devm_iio_device_alloc(&ts->client->dev, sizeof(*iio));
  96. if (!indio_dev) {
  97. dev_err(&ts->client->dev, "iio_device_alloc failed\n");
  98. return -ENOMEM;
  99. }
  100. iio = iio_priv(indio_dev);
  101. iio->ts = ts;
  102. indio_dev->name = "tsc2007";
  103. indio_dev->info = &tsc2007_iio_info;
  104. indio_dev->modes = INDIO_DIRECT_MODE;
  105. indio_dev->channels = tsc2007_iio_channel;
  106. indio_dev->num_channels = ARRAY_SIZE(tsc2007_iio_channel);
  107. error = devm_iio_device_register(&ts->client->dev, indio_dev);
  108. if (error) {
  109. dev_err(&ts->client->dev,
  110. "iio_device_register() failed: %d\n", error);
  111. return error;
  112. }
  113. return 0;
  114. }