cst816s_tpkey_acts.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright (c) 2017 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief TP Keyboard driver for Actions SoC
  9. */
  10. #include <errno.h>
  11. #include <kernel.h>
  12. #include <string.h>
  13. #include <stdbool.h>
  14. #include <init.h>
  15. #include <irq.h>
  16. #include <drivers/adc.h>
  17. #include <drivers/input/input_dev.h>
  18. #include <sys/util.h>
  19. #include <sys/byteorder.h>
  20. #include <board.h>
  21. #include <soc_pmu.h>
  22. #include <logging/log.h>
  23. #include <device.h>
  24. #include <drivers/gpio.h>
  25. #include <soc.h>
  26. #include <string.h>
  27. #include <drivers/i2c.h>
  28. #include <board_cfg.h>
  29. LOG_MODULE_REGISTER(tpkey, 4);
  30. #define tp_slaver_addr (0x2A >> 1) // 0x15
  31. #define REG_LEN_1B 1
  32. #define REG_LEN_2B 2
  33. #define POINT_REPORT_MODE 1
  34. #define GESTURE_REPORT_MODE 2
  35. #define GESTURE_AND_POINT_REPORT_MODE 3
  36. static const struct gpio_cfg reset_gpio_cfg = CONFIG_TPKEY_RESET_GPIO;
  37. static const struct gpio_cfg power_gpio_cfg = CONFIG_TPKEY_POWER_GPIO;
  38. static const struct gpio_cfg isr_gpio_cfg = CONFIG_TPKEY_ISR_GPIO;
  39. struct acts_tpkey_data {
  40. input_notify_t notify;
  41. const struct device *i2c_dev;
  42. const struct device *gpio_dev;
  43. const struct device *this_dev;
  44. struct gpio_callback key_gpio_cb;
  45. struct k_work init_timer;
  46. bool inited;
  47. #ifdef CONFIG_PM_DEVICE
  48. uint32_t pm_state;
  49. #endif
  50. };
  51. struct acts_tpkey_config {
  52. uint16_t poll_interval_ms;
  53. uint32_t poll_total_ms;
  54. };
  55. uint16_t tp_crc[2] __attribute((used)) = {0};
  56. static struct acts_tpkey_data tpkey_acts_ddata;
  57. static void _cst816s_read_touch(const struct device *i2c_dev, struct input_value *val);
  58. extern int tpkey_put_point(struct input_value *value, uint32_t timestamp);
  59. extern int tpkey_get_last_point(struct input_value *value, uint32_t timestamp);
  60. #define mode_pin (GPIO_INPUT | GPIO_INT_DEBOUNCE)
  61. static void _cst816s_poweron(const struct device *dev, bool is_on)
  62. {
  63. const struct device *gpios_power = device_get_binding(power_gpio_cfg.gpio_dev_name);
  64. gpio_pin_configure(gpios_power, power_gpio_cfg.gpion, GPIO_OUTPUT| GPIO_PULL_UP);
  65. gpio_pin_set_raw(gpios_power, power_gpio_cfg.gpion, is_on ? 0 : 1);
  66. printk("power_gpio_cfg.gpion %d \n",power_gpio_cfg.gpion);
  67. }
  68. static void _tpkey_irq_callback(const struct device *port, struct gpio_callback *cb, uint32_t pins)
  69. {
  70. struct acts_tpkey_data *tpkey = &tpkey_acts_ddata;
  71. struct input_value val;
  72. sys_trace_void(SYS_TRACE_ID_TP_IRQ);
  73. #if 0
  74. static int time_stame = 0;
  75. printk("irq duration : %d \n",k_cyc_to_ns_floor32(k_cycle_get_32() - time_stame));
  76. time_stame = k_cycle_get_32();
  77. #endif
  78. if(tpkey->inited) {
  79. _cst816s_read_touch(tpkey->i2c_dev, &val);
  80. }
  81. sys_trace_end_call(SYS_TRACE_ID_TP_IRQ);
  82. }
  83. static void _cst816s_irq_config(const struct device *dev, bool is_on)
  84. {
  85. struct acts_tpkey_data *tpkey = dev->data;
  86. gpio_pin_configure(tpkey->gpio_dev , isr_gpio_cfg.gpion, mode_pin);
  87. gpio_init_callback(&tpkey->key_gpio_cb , _tpkey_irq_callback, BIT(isr_gpio_cfg.gpion));
  88. if (is_on) {
  89. gpio_add_callback(tpkey->gpio_dev , &tpkey->key_gpio_cb);
  90. } else {
  91. gpio_remove_callback(tpkey->gpio_dev , &tpkey->key_gpio_cb);
  92. }
  93. printk("isr_gpio_cfg.gpion %d \n",isr_gpio_cfg.gpion);
  94. }
  95. static void _cst816s_reset(const struct device *dev)
  96. {
  97. const struct device *gpios_reset = device_get_binding(reset_gpio_cfg.gpio_dev_name);
  98. gpio_pin_configure(gpios_reset , reset_gpio_cfg.gpion, GPIO_OUTPUT | GPIO_PULL_UP);
  99. gpio_pin_set_raw(gpios_reset , reset_gpio_cfg.gpion, 1);
  100. k_msleep(50);
  101. gpio_pin_set_raw(gpios_reset , reset_gpio_cfg.gpion, 0);
  102. k_msleep(100);
  103. gpio_pin_set_raw(gpios_reset , reset_gpio_cfg.gpion, 1);
  104. k_msleep(10);
  105. }
  106. static int i2c_async_write_cb(void *cb_data, struct i2c_msg *msgs,
  107. uint8_t num_msgs, bool is_err)
  108. {
  109. if (is_err) {
  110. LOG_ERR("i2c write err\n");
  111. }
  112. return 0;
  113. }
  114. static int i2c_async_read_cb(void *cb_data, struct i2c_msg *msgs,
  115. uint8_t num_msgs, bool is_err)
  116. {
  117. if (!is_err) {
  118. struct input_value val;
  119. //int temp_read = k_cycle_get_32();
  120. val.point.loc_x = (((uint16_t)(msgs->buf[2]&0x0f))<<8) | msgs->buf[3];
  121. val.point.loc_y = (((uint16_t)(msgs->buf[4]&0x0f))<<8) | msgs->buf[5];
  122. val.point.pessure_value = msgs->buf[1];
  123. val.point.gesture = msgs->buf[0];
  124. tpkey_put_point(&val, k_cycle_get_32());
  125. #if 0
  126. printk("finger_num = %d, gesture = %d,local:(%d,%d)\n",
  127. msgs->buf[1], val.point.gesture,val.point.loc_x, val.point.loc_y);
  128. #endif
  129. } else {
  130. LOG_ERR("i2c read err\n");
  131. }
  132. return 0;
  133. }
  134. static void _cst816s_read_touch(const struct device *i2c_dev, struct input_value *val)
  135. {
  136. static uint8_t write_cmd[1] = {0};
  137. static uint8_t read_cmd[6] = {0};
  138. int ret = 0;
  139. sys_trace_void(SYS_TRACE_ID_TP_READ);
  140. write_cmd[0] = 0x01;
  141. ret = i2c_write_async(i2c_dev, write_cmd, 1, tp_slaver_addr, i2c_async_write_cb, NULL);
  142. if (ret == -1)
  143. goto exit;
  144. ret = i2c_read_async(i2c_dev, read_cmd, 6, tp_slaver_addr, i2c_async_read_cb, NULL);
  145. if (ret == -1)
  146. goto exit;
  147. exit:
  148. sys_trace_end_call(SYS_TRACE_ID_TP_READ);
  149. }
  150. static void _cst816s_enter_low_power_mode(const struct device *dev, bool low_power)
  151. {
  152. uint8_t cmd[6] = {0};
  153. cmd[0] = 0xfe;
  154. if (low_power) {
  155. cmd[1] = 0;
  156. } else {
  157. cmd[1] = 1;
  158. }
  159. i2c_write(tpkey_acts_ddata.i2c_dev, cmd, 2, tp_slaver_addr);
  160. }
  161. static void _cst816s_set_report_mode(const struct device *dev, int mode)
  162. {
  163. uint8_t cmd[6] = {0};
  164. cmd[0] = 0xFA;
  165. if (mode == POINT_REPORT_MODE) {
  166. cmd[1] = 0x60;
  167. } else if (mode == GESTURE_REPORT_MODE) {
  168. cmd[1] = 0x11;
  169. } else if (mode == GESTURE_AND_POINT_REPORT_MODE) {
  170. cmd[1] = 0x71;
  171. }
  172. i2c_write(tpkey_acts_ddata.i2c_dev, cmd, 2, tp_slaver_addr);
  173. }
  174. #if 0
  175. static void _cst816s_turn_off_auto_reset()
  176. {
  177. uint8_t cmd[6] = {0};
  178. cmd[0] = 0xfb;
  179. cmd[1] = 0;
  180. i2c_write(tpkey_acts_ddata.i2c_dev, cmd, 2, tp_slaver_addr);
  181. cmd[0] = 0xfc;
  182. cmd[1] = 0;
  183. i2c_write(tpkey_acts_ddata.i2c_dev, cmd, 2, tp_slaver_addr);
  184. }
  185. #endif
  186. static const struct acts_tpkey_config _tpkey_acts_cdata = {
  187. .poll_interval_ms = 0,
  188. .poll_total_ms = 0,
  189. };
  190. static void _tpkey_acts_enable(const struct device *dev)
  191. {
  192. struct acts_tpkey_data *tpkey = dev->data;
  193. //const struct acts_tpkey_config *cfg = dev->config;
  194. printk("isr_gpio_cfg.gpion %x ",isr_gpio_cfg.gpion);
  195. gpio_pin_interrupt_configure(tpkey->gpio_dev , isr_gpio_cfg.gpion, GPIO_INT_EDGE_FALLING);//GPIO_INT_DISABLE
  196. }
  197. static void _tpkey_acts_disable(const struct device *dev)
  198. {
  199. struct acts_tpkey_data *tpkey = dev->data;
  200. //const struct acts_tpkey_config *cfg = dev->config;
  201. gpio_pin_interrupt_configure(tpkey->gpio_dev , isr_gpio_cfg.gpion, GPIO_INT_DISABLE);//GPIO_INT_DISABLE
  202. LOG_DBG("disable tpkey");
  203. }
  204. static void _tpkey_acts_inquiry(const struct device *dev, struct input_value *val)
  205. {
  206. //struct acts_tpkey_data *tpkey = dev->data;
  207. tpkey_get_last_point(val, k_cycle_get_32());
  208. }
  209. static void _tpkey_acts_register_notify(const struct device *dev, input_notify_t notify)
  210. {
  211. struct acts_tpkey_data *tpkey = dev->data;
  212. LOG_DBG("register notify 0x%x", (uint32_t)notify);
  213. tpkey->notify = notify;
  214. }
  215. static void _tpkey_acts_unregister_notify(const struct device *dev, input_notify_t notify)
  216. {
  217. struct acts_tpkey_data *tpkey = dev->data;
  218. LOG_DBG("unregister notify 0x%x", (uint32_t)notify);
  219. tpkey->notify = NULL;
  220. }
  221. static void _tpkey_init_work(struct k_work *work)
  222. {
  223. struct acts_tpkey_data *tpkey = &tpkey_acts_ddata;
  224. _cst816s_poweron(tpkey->this_dev, true);
  225. _cst816s_reset(tpkey->this_dev);
  226. k_msleep(50);
  227. _cst816s_irq_config(tpkey->this_dev, true);
  228. //_cst816s_enter_low_power_mode(tpkey->this_dev,false);
  229. _cst816s_set_report_mode(tpkey->this_dev,POINT_REPORT_MODE);
  230. }
  231. static int _tpkey_acts_init(const struct device *dev)
  232. {
  233. struct acts_tpkey_data *tpkey = dev->data;
  234. tpkey->this_dev = (struct device *)dev;
  235. tpkey->i2c_dev = (struct device *)device_get_binding(CONFIG_TPKEY_I2C_NAME);
  236. if (!tpkey->i2c_dev) {
  237. printk("can not access right i2c device\n");
  238. return -1;
  239. }
  240. tpkey->gpio_dev = device_get_binding(isr_gpio_cfg.gpio_dev_name);
  241. tpkey->inited = true;
  242. k_work_init(&tpkey->init_timer, _tpkey_init_work);
  243. k_work_submit(&tpkey->init_timer);
  244. return 0;
  245. }
  246. static bool low_power_mode = false;
  247. void tpkey_acts_dump(void)
  248. {
  249. struct acts_tpkey_data *tpkey = &tpkey_acts_ddata;
  250. _cst816s_reset(tpkey->this_dev);
  251. k_busy_wait(30*1000);
  252. if (low_power_mode) {
  253. _cst816s_enter_low_power_mode(tpkey->this_dev,false);
  254. low_power_mode = false;
  255. } else {
  256. low_power_mode = true;
  257. _cst816s_enter_low_power_mode(tpkey->this_dev,true);
  258. }
  259. }
  260. static const struct input_dev_driver_api _tpkey_acts_driver_api = {
  261. .enable = _tpkey_acts_enable,
  262. .disable = _tpkey_acts_disable,
  263. .inquiry = _tpkey_acts_inquiry,
  264. .register_notify = _tpkey_acts_register_notify,
  265. .unregister_notify = _tpkey_acts_unregister_notify,
  266. };
  267. #ifdef CONFIG_PM_DEVICE
  268. static void _cst816s_suspend(const struct device *dev)
  269. {
  270. struct acts_tpkey_data *tpkey = (struct acts_tpkey_data *)dev->data;
  271. _cst816s_irq_config(tpkey->this_dev, false);
  272. _cst816s_poweron(tpkey->this_dev, false);
  273. printk("ok\n");
  274. }
  275. static void _cst816s_resume(const struct device *dev)
  276. {
  277. struct acts_tpkey_data *tpkey = (struct acts_tpkey_data *)dev->data;
  278. k_work_submit(&tpkey->init_timer);
  279. }
  280. static int _cst816s_pm_control(const struct device *dev, enum pm_device_action action)
  281. {
  282. int ret = 0;
  283. //struct acts_tpkey_data *data = (struct acts_tpkey_data *)dev->data;
  284. switch (action) {
  285. case PM_DEVICE_ACTION_SUSPEND:
  286. _cst816s_suspend(dev);
  287. break;
  288. case PM_DEVICE_ACTION_RESUME:
  289. _cst816s_resume(dev);
  290. break;
  291. default:
  292. break;
  293. }
  294. return ret;
  295. }
  296. #else /* CONFIG_PM_DEVICE */
  297. static int _cst816s_pm_control(const struct device *dev, uint32_t ctrl_command,
  298. void *context, device_pm_cb cb, void *arg)
  299. {
  300. }
  301. #endif
  302. #if IS_ENABLED(CONFIG_TPKEY)
  303. DEVICE_DEFINE(tpkey, CONFIG_TPKEY_DEV_NAME, _tpkey_acts_init,
  304. _cst816s_pm_control, &tpkey_acts_ddata, &_tpkey_acts_cdata, POST_KERNEL,
  305. 60, &_tpkey_acts_driver_api);
  306. #endif