cma3000_d0x.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * VTI CMA3000_D0x Accelerometer driver
  4. *
  5. * Copyright (C) 2010 Texas Instruments
  6. * Author: Hemanth V <hemanthv@ti.com>
  7. */
  8. #include <linux/export.h>
  9. #include <linux/types.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/delay.h>
  12. #include <linux/slab.h>
  13. #include <linux/input.h>
  14. #include <linux/input/cma3000.h>
  15. #include <linux/module.h>
  16. #include "cma3000_d0x.h"
  17. #define CMA3000_WHOAMI 0x00
  18. #define CMA3000_REVID 0x01
  19. #define CMA3000_CTRL 0x02
  20. #define CMA3000_STATUS 0x03
  21. #define CMA3000_RSTR 0x04
  22. #define CMA3000_INTSTATUS 0x05
  23. #define CMA3000_DOUTX 0x06
  24. #define CMA3000_DOUTY 0x07
  25. #define CMA3000_DOUTZ 0x08
  26. #define CMA3000_MDTHR 0x09
  27. #define CMA3000_MDFFTMR 0x0A
  28. #define CMA3000_FFTHR 0x0B
  29. #define CMA3000_RANGE2G (1 << 7)
  30. #define CMA3000_RANGE8G (0 << 7)
  31. #define CMA3000_BUSI2C (0 << 4)
  32. #define CMA3000_MODEMASK (7 << 1)
  33. #define CMA3000_GRANGEMASK (1 << 7)
  34. #define CMA3000_STATUS_PERR 1
  35. #define CMA3000_INTSTATUS_FFDET (1 << 2)
  36. /* Settling time delay in ms */
  37. #define CMA3000_SETDELAY 30
  38. /* Delay for clearing interrupt in us */
  39. #define CMA3000_INTDELAY 44
  40. /*
  41. * Bit weights in mg for bit 0, other bits need
  42. * multiply factor 2^n. Eight bit is the sign bit.
  43. */
  44. #define BIT_TO_2G 18
  45. #define BIT_TO_8G 71
  46. struct cma3000_accl_data {
  47. const struct cma3000_bus_ops *bus_ops;
  48. const struct cma3000_platform_data *pdata;
  49. struct device *dev;
  50. struct input_dev *input_dev;
  51. int bit_to_mg;
  52. int irq;
  53. int g_range;
  54. u8 mode;
  55. struct mutex mutex;
  56. bool opened;
  57. bool suspended;
  58. };
  59. #define CMA3000_READ(data, reg, msg) \
  60. (data->bus_ops->read(data->dev, reg, msg))
  61. #define CMA3000_SET(data, reg, val, msg) \
  62. ((data)->bus_ops->write(data->dev, reg, val, msg))
  63. /*
  64. * Conversion for each of the eight modes to g, depending
  65. * on G range i.e 2G or 8G. Some modes always operate in
  66. * 8G.
  67. */
  68. static int mode_to_mg[8][2] = {
  69. { 0, 0 },
  70. { BIT_TO_8G, BIT_TO_2G },
  71. { BIT_TO_8G, BIT_TO_2G },
  72. { BIT_TO_8G, BIT_TO_8G },
  73. { BIT_TO_8G, BIT_TO_8G },
  74. { BIT_TO_8G, BIT_TO_2G },
  75. { BIT_TO_8G, BIT_TO_2G },
  76. { 0, 0},
  77. };
  78. static void decode_mg(struct cma3000_accl_data *data, int *datax,
  79. int *datay, int *dataz)
  80. {
  81. /* Data in 2's complement, convert to mg */
  82. *datax = ((s8)*datax) * data->bit_to_mg;
  83. *datay = ((s8)*datay) * data->bit_to_mg;
  84. *dataz = ((s8)*dataz) * data->bit_to_mg;
  85. }
  86. static irqreturn_t cma3000_thread_irq(int irq, void *dev_id)
  87. {
  88. struct cma3000_accl_data *data = dev_id;
  89. int datax, datay, dataz, intr_status;
  90. u8 ctrl, mode, range;
  91. intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status");
  92. if (intr_status < 0)
  93. return IRQ_NONE;
  94. /* Check if free fall is detected, report immediately */
  95. if (intr_status & CMA3000_INTSTATUS_FFDET) {
  96. input_report_abs(data->input_dev, ABS_MISC, 1);
  97. input_sync(data->input_dev);
  98. } else {
  99. input_report_abs(data->input_dev, ABS_MISC, 0);
  100. }
  101. datax = CMA3000_READ(data, CMA3000_DOUTX, "X");
  102. datay = CMA3000_READ(data, CMA3000_DOUTY, "Y");
  103. dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z");
  104. ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl");
  105. mode = (ctrl & CMA3000_MODEMASK) >> 1;
  106. range = (ctrl & CMA3000_GRANGEMASK) >> 7;
  107. data->bit_to_mg = mode_to_mg[mode][range];
  108. /* Interrupt not for this device */
  109. if (data->bit_to_mg == 0)
  110. return IRQ_NONE;
  111. /* Decode register values to milli g */
  112. decode_mg(data, &datax, &datay, &dataz);
  113. input_report_abs(data->input_dev, ABS_X, datax);
  114. input_report_abs(data->input_dev, ABS_Y, datay);
  115. input_report_abs(data->input_dev, ABS_Z, dataz);
  116. input_sync(data->input_dev);
  117. return IRQ_HANDLED;
  118. }
  119. static int cma3000_reset(struct cma3000_accl_data *data)
  120. {
  121. int val;
  122. /* Reset sequence */
  123. CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset");
  124. CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset");
  125. CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset");
  126. /* Settling time delay */
  127. mdelay(10);
  128. val = CMA3000_READ(data, CMA3000_STATUS, "Status");
  129. if (val < 0) {
  130. dev_err(data->dev, "Reset failed\n");
  131. return val;
  132. }
  133. if (val & CMA3000_STATUS_PERR) {
  134. dev_err(data->dev, "Parity Error\n");
  135. return -EIO;
  136. }
  137. return 0;
  138. }
  139. static int cma3000_poweron(struct cma3000_accl_data *data)
  140. {
  141. const struct cma3000_platform_data *pdata = data->pdata;
  142. u8 ctrl = 0;
  143. int ret;
  144. if (data->g_range == CMARANGE_2G) {
  145. ctrl = (data->mode << 1) | CMA3000_RANGE2G;
  146. } else if (data->g_range == CMARANGE_8G) {
  147. ctrl = (data->mode << 1) | CMA3000_RANGE8G;
  148. } else {
  149. dev_info(data->dev,
  150. "Invalid G range specified, assuming 8G\n");
  151. ctrl = (data->mode << 1) | CMA3000_RANGE8G;
  152. }
  153. ctrl |= data->bus_ops->ctrl_mod;
  154. CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr,
  155. "Motion Detect Threshold");
  156. CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr,
  157. "Time register");
  158. CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr,
  159. "Free fall threshold");
  160. ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting");
  161. if (ret < 0)
  162. return -EIO;
  163. msleep(CMA3000_SETDELAY);
  164. return 0;
  165. }
  166. static int cma3000_poweroff(struct cma3000_accl_data *data)
  167. {
  168. int ret;
  169. ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting");
  170. msleep(CMA3000_SETDELAY);
  171. return ret;
  172. }
  173. static int cma3000_open(struct input_dev *input_dev)
  174. {
  175. struct cma3000_accl_data *data = input_get_drvdata(input_dev);
  176. guard(mutex)(&data->mutex);
  177. if (!data->suspended)
  178. cma3000_poweron(data);
  179. data->opened = true;
  180. return 0;
  181. }
  182. static void cma3000_close(struct input_dev *input_dev)
  183. {
  184. struct cma3000_accl_data *data = input_get_drvdata(input_dev);
  185. guard(mutex)(&data->mutex);
  186. if (!data->suspended)
  187. cma3000_poweroff(data);
  188. data->opened = false;
  189. }
  190. void cma3000_suspend(struct cma3000_accl_data *data)
  191. {
  192. guard(mutex)(&data->mutex);
  193. if (!data->suspended && data->opened)
  194. cma3000_poweroff(data);
  195. data->suspended = true;
  196. }
  197. EXPORT_SYMBOL(cma3000_suspend);
  198. void cma3000_resume(struct cma3000_accl_data *data)
  199. {
  200. guard(mutex)(&data->mutex);
  201. if (data->suspended && data->opened)
  202. cma3000_poweron(data);
  203. data->suspended = false;
  204. }
  205. EXPORT_SYMBOL(cma3000_resume);
  206. struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
  207. const struct cma3000_bus_ops *bops)
  208. {
  209. const struct cma3000_platform_data *pdata = dev_get_platdata(dev);
  210. struct cma3000_accl_data *data;
  211. struct input_dev *input_dev;
  212. int rev;
  213. int error;
  214. if (!pdata) {
  215. dev_err(dev, "platform data not found\n");
  216. error = -EINVAL;
  217. goto err_out;
  218. }
  219. /* if no IRQ return error */
  220. if (irq == 0) {
  221. error = -EINVAL;
  222. goto err_out;
  223. }
  224. data = kzalloc_obj(*data);
  225. input_dev = input_allocate_device();
  226. if (!data || !input_dev) {
  227. error = -ENOMEM;
  228. goto err_free_mem;
  229. }
  230. data->dev = dev;
  231. data->input_dev = input_dev;
  232. data->bus_ops = bops;
  233. data->pdata = pdata;
  234. data->irq = irq;
  235. mutex_init(&data->mutex);
  236. data->mode = pdata->mode;
  237. if (data->mode > CMAMODE_POFF) {
  238. data->mode = CMAMODE_MOTDET;
  239. dev_warn(dev,
  240. "Invalid mode specified, assuming Motion Detect\n");
  241. }
  242. data->g_range = pdata->g_range;
  243. if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) {
  244. dev_info(dev,
  245. "Invalid G range specified, assuming 8G\n");
  246. data->g_range = CMARANGE_8G;
  247. }
  248. input_dev->name = "cma3000-accelerometer";
  249. input_dev->id.bustype = bops->bustype;
  250. input_dev->open = cma3000_open;
  251. input_dev->close = cma3000_close;
  252. input_set_abs_params(input_dev, ABS_X,
  253. -data->g_range, data->g_range, pdata->fuzz_x, 0);
  254. input_set_abs_params(input_dev, ABS_Y,
  255. -data->g_range, data->g_range, pdata->fuzz_y, 0);
  256. input_set_abs_params(input_dev, ABS_Z,
  257. -data->g_range, data->g_range, pdata->fuzz_z, 0);
  258. input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
  259. input_set_drvdata(input_dev, data);
  260. error = cma3000_reset(data);
  261. if (error)
  262. goto err_free_mem;
  263. rev = CMA3000_READ(data, CMA3000_REVID, "Revid");
  264. if (rev < 0) {
  265. error = rev;
  266. goto err_free_mem;
  267. }
  268. pr_info("CMA3000 Accelerometer: Revision %x\n", rev);
  269. error = request_threaded_irq(irq, NULL, cma3000_thread_irq,
  270. pdata->irqflags | IRQF_ONESHOT,
  271. "cma3000_d0x", data);
  272. if (error) {
  273. dev_err(dev, "request_threaded_irq failed\n");
  274. goto err_free_mem;
  275. }
  276. error = input_register_device(data->input_dev);
  277. if (error) {
  278. dev_err(dev, "Unable to register input device\n");
  279. goto err_free_irq;
  280. }
  281. return data;
  282. err_free_irq:
  283. free_irq(irq, data);
  284. err_free_mem:
  285. input_free_device(input_dev);
  286. kfree(data);
  287. err_out:
  288. return ERR_PTR(error);
  289. }
  290. EXPORT_SYMBOL(cma3000_init);
  291. void cma3000_exit(struct cma3000_accl_data *data)
  292. {
  293. free_irq(data->irq, data);
  294. input_unregister_device(data->input_dev);
  295. kfree(data);
  296. }
  297. EXPORT_SYMBOL(cma3000_exit);
  298. MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver");
  299. MODULE_LICENSE("GPL");
  300. MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");