cyttsp_i2c.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * cyttsp_i2c.c
  4. * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver.
  5. * For use with Cypress Txx3xx parts.
  6. * Supported parts include:
  7. * CY8CTST341
  8. * CY8CTMA340
  9. *
  10. * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
  11. * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
  12. *
  13. * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
  14. */
  15. #include "cyttsp_core.h"
  16. #include <linux/i2c.h>
  17. #include <linux/input.h>
  18. #define CY_I2C_NAME "cyttsp-i2c"
  19. #define CY_I2C_DATA_SIZE 128
  20. static int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf,
  21. u16 addr, u8 length, void *values)
  22. {
  23. struct i2c_client *client = to_i2c_client(dev);
  24. u8 client_addr = client->addr | ((addr >> 8) & 0x1);
  25. u8 addr_lo = addr & 0xFF;
  26. struct i2c_msg msgs[] = {
  27. {
  28. .addr = client_addr,
  29. .flags = 0,
  30. .len = 1,
  31. .buf = &addr_lo,
  32. },
  33. {
  34. .addr = client_addr,
  35. .flags = I2C_M_RD,
  36. .len = length,
  37. .buf = values,
  38. },
  39. };
  40. int retval;
  41. retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  42. if (retval < 0)
  43. return retval;
  44. return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
  45. }
  46. static int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
  47. u16 addr, u8 length, const void *values)
  48. {
  49. struct i2c_client *client = to_i2c_client(dev);
  50. u8 client_addr = client->addr | ((addr >> 8) & 0x1);
  51. u8 addr_lo = addr & 0xFF;
  52. struct i2c_msg msgs[] = {
  53. {
  54. .addr = client_addr,
  55. .flags = 0,
  56. .len = length + 1,
  57. .buf = xfer_buf,
  58. },
  59. };
  60. int retval;
  61. xfer_buf[0] = addr_lo;
  62. memcpy(&xfer_buf[1], values, length);
  63. retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
  64. if (retval < 0)
  65. return retval;
  66. return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
  67. }
  68. static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
  69. .bustype = BUS_I2C,
  70. .write = cyttsp_i2c_write_block_data,
  71. .read = cyttsp_i2c_read_block_data,
  72. };
  73. static int cyttsp_i2c_probe(struct i2c_client *client)
  74. {
  75. struct cyttsp *ts;
  76. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  77. dev_err(&client->dev, "I2C functionality not Supported\n");
  78. return -EIO;
  79. }
  80. ts = cyttsp_probe(&cyttsp_i2c_bus_ops, &client->dev, client->irq,
  81. CY_I2C_DATA_SIZE);
  82. if (IS_ERR(ts))
  83. return PTR_ERR(ts);
  84. i2c_set_clientdata(client, ts);
  85. return 0;
  86. }
  87. static const struct i2c_device_id cyttsp_i2c_id[] = {
  88. { CY_I2C_NAME },
  89. { }
  90. };
  91. MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);
  92. static const struct of_device_id cyttsp_of_i2c_match[] = {
  93. { .compatible = "cypress,cy8ctma340", },
  94. { .compatible = "cypress,cy8ctst341", },
  95. { /* sentinel */ }
  96. };
  97. MODULE_DEVICE_TABLE(of, cyttsp_of_i2c_match);
  98. static struct i2c_driver cyttsp_i2c_driver = {
  99. .driver = {
  100. .name = CY_I2C_NAME,
  101. .pm = pm_sleep_ptr(&cyttsp_pm_ops),
  102. .of_match_table = cyttsp_of_i2c_match,
  103. },
  104. .probe = cyttsp_i2c_probe,
  105. .id_table = cyttsp_i2c_id,
  106. };
  107. module_i2c_driver(cyttsp_i2c_driver);
  108. MODULE_LICENSE("GPL");
  109. MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver");
  110. MODULE_AUTHOR("Cypress");