drv2665.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * DRV2665 haptics driver family
  3. *
  4. * Author: Dan Murphy <dmurphy@ti.com>
  5. *
  6. * Copyright: (C) 2015 Texas Instruments, Inc.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. #include <linux/i2c.h>
  18. #include <linux/input.h>
  19. #include <linux/module.h>
  20. #include <linux/regmap.h>
  21. #include <linux/slab.h>
  22. #include <linux/delay.h>
  23. #include <linux/regulator/consumer.h>
  24. /* Contol registers */
  25. #define DRV2665_STATUS 0x00
  26. #define DRV2665_CTRL_1 0x01
  27. #define DRV2665_CTRL_2 0x02
  28. #define DRV2665_FIFO 0x0b
  29. /* Status Register */
  30. #define DRV2665_FIFO_FULL BIT(0)
  31. #define DRV2665_FIFO_EMPTY BIT(1)
  32. /* Control 1 Register */
  33. #define DRV2665_25_VPP_GAIN 0x00
  34. #define DRV2665_50_VPP_GAIN 0x01
  35. #define DRV2665_75_VPP_GAIN 0x02
  36. #define DRV2665_100_VPP_GAIN 0x03
  37. #define DRV2665_DIGITAL_IN 0xfc
  38. #define DRV2665_ANALOG_IN BIT(2)
  39. /* Control 2 Register */
  40. #define DRV2665_BOOST_EN BIT(1)
  41. #define DRV2665_STANDBY BIT(6)
  42. #define DRV2665_DEV_RST BIT(7)
  43. #define DRV2665_5_MS_IDLE_TOUT 0x00
  44. #define DRV2665_10_MS_IDLE_TOUT 0x04
  45. #define DRV2665_15_MS_IDLE_TOUT 0x08
  46. #define DRV2665_20_MS_IDLE_TOUT 0x0c
  47. /**
  48. * struct drv2665_data -
  49. * @input_dev - Pointer to the input device
  50. * @client - Pointer to the I2C client
  51. * @regmap - Register map of the device
  52. * @work - Work item used to off load the enable/disable of the vibration
  53. * @regulator - Pointer to the regulator for the IC
  54. */
  55. struct drv2665_data {
  56. struct input_dev *input_dev;
  57. struct i2c_client *client;
  58. struct regmap *regmap;
  59. struct work_struct work;
  60. struct regulator *regulator;
  61. };
  62. /* 8kHz Sine wave to stream to the FIFO */
  63. static const u8 drv2665_sine_wave_form[] = {
  64. 0x00, 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
  65. 0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
  66. 0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
  67. 0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
  68. };
  69. static const struct reg_default drv2665_reg_defs[] = {
  70. { DRV2665_STATUS, 0x02 },
  71. { DRV2665_CTRL_1, 0x28 },
  72. { DRV2665_CTRL_2, 0x40 },
  73. { DRV2665_FIFO, 0x00 },
  74. };
  75. static void drv2665_worker(struct work_struct *work)
  76. {
  77. struct drv2665_data *haptics =
  78. container_of(work, struct drv2665_data, work);
  79. unsigned int read_buf;
  80. int error;
  81. error = regmap_read(haptics->regmap, DRV2665_STATUS, &read_buf);
  82. if (error) {
  83. dev_err(&haptics->client->dev,
  84. "Failed to read status: %d\n", error);
  85. return;
  86. }
  87. if (read_buf & DRV2665_FIFO_EMPTY) {
  88. error = regmap_bulk_write(haptics->regmap,
  89. DRV2665_FIFO,
  90. drv2665_sine_wave_form,
  91. ARRAY_SIZE(drv2665_sine_wave_form));
  92. if (error) {
  93. dev_err(&haptics->client->dev,
  94. "Failed to write FIFO: %d\n", error);
  95. return;
  96. }
  97. }
  98. }
  99. static int drv2665_haptics_play(struct input_dev *input, void *data,
  100. struct ff_effect *effect)
  101. {
  102. struct drv2665_data *haptics = input_get_drvdata(input);
  103. schedule_work(&haptics->work);
  104. return 0;
  105. }
  106. static void drv2665_close(struct input_dev *input)
  107. {
  108. struct drv2665_data *haptics = input_get_drvdata(input);
  109. int error;
  110. cancel_work_sync(&haptics->work);
  111. error = regmap_update_bits(haptics->regmap,
  112. DRV2665_CTRL_2, DRV2665_STANDBY, 1);
  113. if (error)
  114. dev_err(&haptics->client->dev,
  115. "Failed to enter standby mode: %d\n", error);
  116. }
  117. static const struct reg_sequence drv2665_init_regs[] = {
  118. { DRV2665_CTRL_2, 0 | DRV2665_10_MS_IDLE_TOUT },
  119. { DRV2665_CTRL_1, DRV2665_25_VPP_GAIN },
  120. };
  121. static int drv2665_init(struct drv2665_data *haptics)
  122. {
  123. int error;
  124. error = regmap_register_patch(haptics->regmap,
  125. drv2665_init_regs,
  126. ARRAY_SIZE(drv2665_init_regs));
  127. if (error) {
  128. dev_err(&haptics->client->dev,
  129. "Failed to write init registers: %d\n",
  130. error);
  131. return error;
  132. }
  133. return 0;
  134. }
  135. static const struct regmap_config drv2665_regmap_config = {
  136. .reg_bits = 8,
  137. .val_bits = 8,
  138. .max_register = DRV2665_FIFO,
  139. .reg_defaults = drv2665_reg_defs,
  140. .num_reg_defaults = ARRAY_SIZE(drv2665_reg_defs),
  141. .cache_type = REGCACHE_NONE,
  142. };
  143. static int drv2665_probe(struct i2c_client *client,
  144. const struct i2c_device_id *id)
  145. {
  146. struct drv2665_data *haptics;
  147. int error;
  148. haptics = devm_kzalloc(&client->dev, sizeof(*haptics), GFP_KERNEL);
  149. if (!haptics)
  150. return -ENOMEM;
  151. haptics->regulator = devm_regulator_get(&client->dev, "vbat");
  152. if (IS_ERR(haptics->regulator)) {
  153. error = PTR_ERR(haptics->regulator);
  154. dev_err(&client->dev,
  155. "unable to get regulator, error: %d\n", error);
  156. return error;
  157. }
  158. haptics->input_dev = devm_input_allocate_device(&client->dev);
  159. if (!haptics->input_dev) {
  160. dev_err(&client->dev, "Failed to allocate input device\n");
  161. return -ENOMEM;
  162. }
  163. haptics->input_dev->name = "drv2665:haptics";
  164. haptics->input_dev->dev.parent = client->dev.parent;
  165. haptics->input_dev->close = drv2665_close;
  166. input_set_drvdata(haptics->input_dev, haptics);
  167. input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);
  168. error = input_ff_create_memless(haptics->input_dev, NULL,
  169. drv2665_haptics_play);
  170. if (error) {
  171. dev_err(&client->dev, "input_ff_create() failed: %d\n",
  172. error);
  173. return error;
  174. }
  175. INIT_WORK(&haptics->work, drv2665_worker);
  176. haptics->client = client;
  177. i2c_set_clientdata(client, haptics);
  178. haptics->regmap = devm_regmap_init_i2c(client, &drv2665_regmap_config);
  179. if (IS_ERR(haptics->regmap)) {
  180. error = PTR_ERR(haptics->regmap);
  181. dev_err(&client->dev, "Failed to allocate register map: %d\n",
  182. error);
  183. return error;
  184. }
  185. error = drv2665_init(haptics);
  186. if (error) {
  187. dev_err(&client->dev, "Device init failed: %d\n", error);
  188. return error;
  189. }
  190. error = input_register_device(haptics->input_dev);
  191. if (error) {
  192. dev_err(&client->dev, "couldn't register input device: %d\n",
  193. error);
  194. return error;
  195. }
  196. return 0;
  197. }
  198. static int __maybe_unused drv2665_suspend(struct device *dev)
  199. {
  200. struct drv2665_data *haptics = dev_get_drvdata(dev);
  201. int ret = 0;
  202. mutex_lock(&haptics->input_dev->mutex);
  203. if (haptics->input_dev->users) {
  204. ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
  205. DRV2665_STANDBY, 1);
  206. if (ret) {
  207. dev_err(dev, "Failed to set standby mode\n");
  208. regulator_disable(haptics->regulator);
  209. goto out;
  210. }
  211. ret = regulator_disable(haptics->regulator);
  212. if (ret) {
  213. dev_err(dev, "Failed to disable regulator\n");
  214. regmap_update_bits(haptics->regmap,
  215. DRV2665_CTRL_2,
  216. DRV2665_STANDBY, 0);
  217. }
  218. }
  219. out:
  220. mutex_unlock(&haptics->input_dev->mutex);
  221. return ret;
  222. }
  223. static int __maybe_unused drv2665_resume(struct device *dev)
  224. {
  225. struct drv2665_data *haptics = dev_get_drvdata(dev);
  226. int ret = 0;
  227. mutex_lock(&haptics->input_dev->mutex);
  228. if (haptics->input_dev->users) {
  229. ret = regulator_enable(haptics->regulator);
  230. if (ret) {
  231. dev_err(dev, "Failed to enable regulator\n");
  232. goto out;
  233. }
  234. ret = regmap_update_bits(haptics->regmap, DRV2665_CTRL_2,
  235. DRV2665_STANDBY, 0);
  236. if (ret) {
  237. dev_err(dev, "Failed to unset standby mode\n");
  238. regulator_disable(haptics->regulator);
  239. goto out;
  240. }
  241. }
  242. out:
  243. mutex_unlock(&haptics->input_dev->mutex);
  244. return ret;
  245. }
  246. static SIMPLE_DEV_PM_OPS(drv2665_pm_ops, drv2665_suspend, drv2665_resume);
  247. static const struct i2c_device_id drv2665_id[] = {
  248. { "drv2665", 0 },
  249. { }
  250. };
  251. MODULE_DEVICE_TABLE(i2c, drv2665_id);
  252. #ifdef CONFIG_OF
  253. static const struct of_device_id drv2665_of_match[] = {
  254. { .compatible = "ti,drv2665", },
  255. { }
  256. };
  257. MODULE_DEVICE_TABLE(of, drv2665_of_match);
  258. #endif
  259. static struct i2c_driver drv2665_driver = {
  260. .probe = drv2665_probe,
  261. .driver = {
  262. .name = "drv2665-haptics",
  263. .of_match_table = of_match_ptr(drv2665_of_match),
  264. .pm = &drv2665_pm_ops,
  265. },
  266. .id_table = drv2665_id,
  267. };
  268. module_i2c_driver(drv2665_driver);
  269. MODULE_DESCRIPTION("TI DRV2665 haptics driver");
  270. MODULE_LICENSE("GPL");
  271. MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");