gp2ap002a00f.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc.
  3. *
  4. * Author: Courtney Cavin <courtney.cavin@sonyericsson.com>
  5. * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2, as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/i2c.h>
  12. #include <linux/irq.h>
  13. #include <linux/slab.h>
  14. #include <linux/input.h>
  15. #include <linux/module.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/gpio.h>
  18. #include <linux/delay.h>
  19. #include <linux/input/gp2ap002a00f.h>
  20. struct gp2a_data {
  21. struct input_dev *input;
  22. const struct gp2a_platform_data *pdata;
  23. struct i2c_client *i2c_client;
  24. };
  25. enum gp2a_addr {
  26. GP2A_ADDR_PROX = 0x0,
  27. GP2A_ADDR_GAIN = 0x1,
  28. GP2A_ADDR_HYS = 0x2,
  29. GP2A_ADDR_CYCLE = 0x3,
  30. GP2A_ADDR_OPMOD = 0x4,
  31. GP2A_ADDR_CON = 0x6
  32. };
  33. enum gp2a_controls {
  34. /* Software Shutdown control: 0 = shutdown, 1 = normal operation */
  35. GP2A_CTRL_SSD = 0x01
  36. };
  37. static int gp2a_report(struct gp2a_data *dt)
  38. {
  39. int vo = gpio_get_value(dt->pdata->vout_gpio);
  40. input_report_switch(dt->input, SW_FRONT_PROXIMITY, !vo);
  41. input_sync(dt->input);
  42. return 0;
  43. }
  44. static irqreturn_t gp2a_irq(int irq, void *handle)
  45. {
  46. struct gp2a_data *dt = handle;
  47. gp2a_report(dt);
  48. return IRQ_HANDLED;
  49. }
  50. static int gp2a_enable(struct gp2a_data *dt)
  51. {
  52. return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
  53. GP2A_CTRL_SSD);
  54. }
  55. static int gp2a_disable(struct gp2a_data *dt)
  56. {
  57. return i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_OPMOD,
  58. 0x00);
  59. }
  60. static int gp2a_device_open(struct input_dev *dev)
  61. {
  62. struct gp2a_data *dt = input_get_drvdata(dev);
  63. int error;
  64. error = gp2a_enable(dt);
  65. if (error < 0) {
  66. dev_err(&dt->i2c_client->dev,
  67. "unable to activate, err %d\n", error);
  68. return error;
  69. }
  70. gp2a_report(dt);
  71. return 0;
  72. }
  73. static void gp2a_device_close(struct input_dev *dev)
  74. {
  75. struct gp2a_data *dt = input_get_drvdata(dev);
  76. int error;
  77. error = gp2a_disable(dt);
  78. if (error < 0)
  79. dev_err(&dt->i2c_client->dev,
  80. "unable to deactivate, err %d\n", error);
  81. }
  82. static int gp2a_initialize(struct gp2a_data *dt)
  83. {
  84. int error;
  85. error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_GAIN,
  86. 0x08);
  87. if (error < 0)
  88. return error;
  89. error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_HYS,
  90. 0xc2);
  91. if (error < 0)
  92. return error;
  93. error = i2c_smbus_write_byte_data(dt->i2c_client, GP2A_ADDR_CYCLE,
  94. 0x04);
  95. if (error < 0)
  96. return error;
  97. error = gp2a_disable(dt);
  98. return error;
  99. }
  100. static int gp2a_probe(struct i2c_client *client,
  101. const struct i2c_device_id *id)
  102. {
  103. const struct gp2a_platform_data *pdata = dev_get_platdata(&client->dev);
  104. struct gp2a_data *dt;
  105. int error;
  106. if (!pdata)
  107. return -EINVAL;
  108. if (pdata->hw_setup) {
  109. error = pdata->hw_setup(client);
  110. if (error < 0)
  111. return error;
  112. }
  113. error = gpio_request_one(pdata->vout_gpio, GPIOF_IN, GP2A_I2C_NAME);
  114. if (error)
  115. goto err_hw_shutdown;
  116. dt = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
  117. if (!dt) {
  118. error = -ENOMEM;
  119. goto err_free_gpio;
  120. }
  121. dt->pdata = pdata;
  122. dt->i2c_client = client;
  123. error = gp2a_initialize(dt);
  124. if (error < 0)
  125. goto err_free_mem;
  126. dt->input = input_allocate_device();
  127. if (!dt->input) {
  128. error = -ENOMEM;
  129. goto err_free_mem;
  130. }
  131. input_set_drvdata(dt->input, dt);
  132. dt->input->open = gp2a_device_open;
  133. dt->input->close = gp2a_device_close;
  134. dt->input->name = GP2A_I2C_NAME;
  135. dt->input->id.bustype = BUS_I2C;
  136. dt->input->dev.parent = &client->dev;
  137. input_set_capability(dt->input, EV_SW, SW_FRONT_PROXIMITY);
  138. error = request_threaded_irq(client->irq, NULL, gp2a_irq,
  139. IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  140. IRQF_ONESHOT,
  141. GP2A_I2C_NAME, dt);
  142. if (error) {
  143. dev_err(&client->dev, "irq request failed\n");
  144. goto err_free_input_dev;
  145. }
  146. error = input_register_device(dt->input);
  147. if (error) {
  148. dev_err(&client->dev, "device registration failed\n");
  149. goto err_free_irq;
  150. }
  151. device_init_wakeup(&client->dev, pdata->wakeup);
  152. i2c_set_clientdata(client, dt);
  153. return 0;
  154. err_free_irq:
  155. free_irq(client->irq, dt);
  156. err_free_input_dev:
  157. input_free_device(dt->input);
  158. err_free_mem:
  159. kfree(dt);
  160. err_free_gpio:
  161. gpio_free(pdata->vout_gpio);
  162. err_hw_shutdown:
  163. if (pdata->hw_shutdown)
  164. pdata->hw_shutdown(client);
  165. return error;
  166. }
  167. static int gp2a_remove(struct i2c_client *client)
  168. {
  169. struct gp2a_data *dt = i2c_get_clientdata(client);
  170. const struct gp2a_platform_data *pdata = dt->pdata;
  171. device_init_wakeup(&client->dev, false);
  172. free_irq(client->irq, dt);
  173. input_unregister_device(dt->input);
  174. kfree(dt);
  175. gpio_free(pdata->vout_gpio);
  176. if (pdata->hw_shutdown)
  177. pdata->hw_shutdown(client);
  178. return 0;
  179. }
  180. static int __maybe_unused gp2a_suspend(struct device *dev)
  181. {
  182. struct i2c_client *client = to_i2c_client(dev);
  183. struct gp2a_data *dt = i2c_get_clientdata(client);
  184. int retval = 0;
  185. if (device_may_wakeup(&client->dev)) {
  186. enable_irq_wake(client->irq);
  187. } else {
  188. mutex_lock(&dt->input->mutex);
  189. if (dt->input->users)
  190. retval = gp2a_disable(dt);
  191. mutex_unlock(&dt->input->mutex);
  192. }
  193. return retval;
  194. }
  195. static int __maybe_unused gp2a_resume(struct device *dev)
  196. {
  197. struct i2c_client *client = to_i2c_client(dev);
  198. struct gp2a_data *dt = i2c_get_clientdata(client);
  199. int retval = 0;
  200. if (device_may_wakeup(&client->dev)) {
  201. disable_irq_wake(client->irq);
  202. } else {
  203. mutex_lock(&dt->input->mutex);
  204. if (dt->input->users)
  205. retval = gp2a_enable(dt);
  206. mutex_unlock(&dt->input->mutex);
  207. }
  208. return retval;
  209. }
  210. static SIMPLE_DEV_PM_OPS(gp2a_pm, gp2a_suspend, gp2a_resume);
  211. static const struct i2c_device_id gp2a_i2c_id[] = {
  212. { GP2A_I2C_NAME, 0 },
  213. { }
  214. };
  215. MODULE_DEVICE_TABLE(i2c, gp2a_i2c_id);
  216. static struct i2c_driver gp2a_i2c_driver = {
  217. .driver = {
  218. .name = GP2A_I2C_NAME,
  219. .pm = &gp2a_pm,
  220. },
  221. .probe = gp2a_probe,
  222. .remove = gp2a_remove,
  223. .id_table = gp2a_i2c_id,
  224. };
  225. module_i2c_driver(gp2a_i2c_driver);
  226. MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>");
  227. MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
  228. MODULE_LICENSE("GPL v2");