ad7879-i2c.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * AD7879-1/AD7889-1 touchscreen (I2C bus)
  3. *
  4. * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <linux/input.h> /* BUS_I2C */
  9. #include <linux/i2c.h>
  10. #include <linux/module.h>
  11. #include <linux/types.h>
  12. #include <linux/pm.h>
  13. #include "ad7879.h"
  14. #define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */
  15. #ifdef CONFIG_PM
  16. static int ad7879_i2c_suspend(struct device *dev)
  17. {
  18. struct i2c_client *client = to_i2c_client(dev);
  19. struct ad7879 *ts = i2c_get_clientdata(client);
  20. ad7879_suspend(ts);
  21. return 0;
  22. }
  23. static int ad7879_i2c_resume(struct device *dev)
  24. {
  25. struct i2c_client *client = to_i2c_client(dev);
  26. struct ad7879 *ts = i2c_get_clientdata(client);
  27. ad7879_resume(ts);
  28. return 0;
  29. }
  30. static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume);
  31. #endif
  32. /* All registers are word-sized.
  33. * AD7879 uses a high-byte first convention.
  34. */
  35. static int ad7879_i2c_read(struct device *dev, u8 reg)
  36. {
  37. struct i2c_client *client = to_i2c_client(dev);
  38. return swab16(i2c_smbus_read_word_data(client, reg));
  39. }
  40. static int ad7879_i2c_multi_read(struct device *dev,
  41. u8 first_reg, u8 count, u16 *buf)
  42. {
  43. struct i2c_client *client = to_i2c_client(dev);
  44. u8 idx;
  45. i2c_smbus_read_i2c_block_data(client, first_reg, count * 2, (u8 *)buf);
  46. for (idx = 0; idx < count; ++idx)
  47. buf[idx] = swab16(buf[idx]);
  48. return 0;
  49. }
  50. static int ad7879_i2c_write(struct device *dev, u8 reg, u16 val)
  51. {
  52. struct i2c_client *client = to_i2c_client(dev);
  53. return i2c_smbus_write_word_data(client, reg, swab16(val));
  54. }
  55. static const struct ad7879_bus_ops ad7879_i2c_bus_ops = {
  56. .bustype = BUS_I2C,
  57. .read = ad7879_i2c_read,
  58. .multi_read = ad7879_i2c_multi_read,
  59. .write = ad7879_i2c_write,
  60. };
  61. static int __devinit ad7879_i2c_probe(struct i2c_client *client,
  62. const struct i2c_device_id *id)
  63. {
  64. struct ad7879 *ts;
  65. if (!i2c_check_functionality(client->adapter,
  66. I2C_FUNC_SMBUS_WORD_DATA)) {
  67. dev_err(&client->dev, "SMBUS Word Data not Supported\n");
  68. return -EIO;
  69. }
  70. ts = ad7879_probe(&client->dev, AD7879_DEVID, client->irq,
  71. &ad7879_i2c_bus_ops);
  72. if (IS_ERR(ts))
  73. return PTR_ERR(ts);
  74. i2c_set_clientdata(client, ts);
  75. return 0;
  76. }
  77. static int __devexit ad7879_i2c_remove(struct i2c_client *client)
  78. {
  79. struct ad7879 *ts = i2c_get_clientdata(client);
  80. ad7879_remove(ts);
  81. return 0;
  82. }
  83. static const struct i2c_device_id ad7879_id[] = {
  84. { "ad7879", 0 },
  85. { "ad7889", 0 },
  86. { }
  87. };
  88. MODULE_DEVICE_TABLE(i2c, ad7879_id);
  89. static struct i2c_driver ad7879_i2c_driver = {
  90. .driver = {
  91. .name = "ad7879",
  92. .owner = THIS_MODULE,
  93. #ifdef CONFIG_PM
  94. .pm = &ad7879_i2c_pm,
  95. #endif
  96. },
  97. .probe = ad7879_i2c_probe,
  98. .remove = __devexit_p(ad7879_i2c_remove),
  99. .id_table = ad7879_id,
  100. };
  101. static int __init ad7879_i2c_init(void)
  102. {
  103. return i2c_add_driver(&ad7879_i2c_driver);
  104. }
  105. module_init(ad7879_i2c_init);
  106. static void __exit ad7879_i2c_exit(void)
  107. {
  108. i2c_del_driver(&ad7879_i2c_driver);
  109. }
  110. module_exit(ad7879_i2c_exit);
  111. MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
  112. MODULE_DESCRIPTION("AD7879(-1) touchscreen I2C bus driver");
  113. MODULE_LICENSE("GPL");
  114. MODULE_ALIAS("i2c:ad7879");