tsc2007_iio.c 3.4 KB

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