PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/arch/arm/mach-msm/lge/lge_gpio_h2w.c

https://bitbucket.org/Lloir/lge-kernel-jb
C | 491 lines | 370 code | 91 blank | 30 comment | 61 complexity | e7556a04a675b6345f743c4dc301a79e MD5 | raw file
  1. /*
  2. * H2W device detection driver.
  3. *
  4. * Copyright (C) 2008 LGE Corporation.
  5. * Copyright (C) 2008 Google, Inc.
  6. *
  7. * Authors:
  8. * kiwone seo <gentleseo@lge.com>
  9. *
  10. * This software is licensed under the terms of the GNU General Public
  11. * License version 2, as published by the Free Software Foundation, and
  12. * may be copied, distributed, and modified under those terms.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. */
  19. #include <linux/module.h>
  20. #include <linux/sysdev.h>
  21. #include <linux/fs.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/workqueue.h>
  24. #include <linux/irq.h>
  25. #include <linux/delay.h>
  26. #include <linux/types.h>
  27. #include <linux/input.h>
  28. #include <linux/platform_device.h>
  29. #include <linux/mutex.h>
  30. #include <linux/errno.h>
  31. #include <linux/err.h>
  32. #include <linux/hrtimer.h>
  33. #include <linux/switch.h>
  34. #include <linux/input.h>
  35. #include <linux/debugfs.h>
  36. #include <asm/gpio.h>
  37. #include <asm/atomic.h>
  38. #include <mach/board.h>
  39. #include <mach/vreg.h>
  40. #include <mach/board_lge.h>
  41. #define DEBUG_H2W
  42. #ifdef DEBUG_H2W
  43. #define H2W_DBG(fmt, arg...) printk(KERN_INFO "[H2W] %s " fmt "\n", __FUNCTION__, ## arg)
  44. #else
  45. #define H2W_DBG(fmt, arg...) do {} while (0)
  46. #endif
  47. static struct workqueue_struct *g_detection_work_queue;
  48. static void detection_work(struct work_struct *work);
  49. static DECLARE_WORK(g_detection_work, detection_work);
  50. static int ip_dev_reg;
  51. #ifdef CONFIG_LGE_DIAGTEST
  52. extern uint8_t if_condition_is_on_key_buffering;
  53. extern uint8_t lgf_factor_key_test_rsp(char);
  54. #endif
  55. enum {
  56. NO_DEVICE = 0,
  57. LGE_HEADSET = 1,
  58. LGE_NO_MIC_HEADSET = 2,
  59. };
  60. struct h2w_info {
  61. struct switch_dev sdev;
  62. struct input_dev *input;
  63. int gpio_detect;
  64. int gpio_button_detect;
  65. int gpio_mic_mode;
  66. atomic_t btn_state;
  67. int ignore_btn;
  68. unsigned int irq;
  69. unsigned int irq_btn;
  70. struct hrtimer timer;
  71. ktime_t debounce_time;
  72. struct hrtimer btn_timer;
  73. ktime_t btn_debounce_time;
  74. };
  75. static struct h2w_info *hi;
  76. static ssize_t gpio_h2w_print_name(struct switch_dev *sdev, char *buf)
  77. {
  78. switch (switch_get_state(&hi->sdev)) {
  79. case NO_DEVICE:
  80. return sprintf(buf, "No Device\n");
  81. case LGE_HEADSET:
  82. return sprintf(buf, "Headset\n");
  83. case LGE_NO_MIC_HEADSET:
  84. return sprintf(buf, "Headset_no_mic\n");
  85. }
  86. return -EINVAL;
  87. }
  88. static void button_pressed(void)
  89. {
  90. H2W_DBG("button_pressed\n");
  91. atomic_set(&hi->btn_state, 1);
  92. input_report_key(hi->input, KEY_MEDIA, 1);
  93. input_sync(hi->input);
  94. #ifdef CONFIG_LGE_DIAGTEST
  95. if(if_condition_is_on_key_buffering == 1)
  96. lgf_factor_key_test_rsp((u8)KEY_MEDIA);
  97. #endif
  98. }
  99. static void button_released(void)
  100. {
  101. H2W_DBG("button_released\n");
  102. atomic_set(&hi->btn_state, 0);
  103. input_report_key(hi->input, KEY_MEDIA, 0);
  104. input_sync(hi->input);
  105. }
  106. static void insert_headset(void)
  107. {
  108. unsigned long irq_flags;
  109. H2W_DBG("");
  110. hi->ignore_btn = !gpio_get_value(hi->gpio_button_detect);
  111. H2W_DBG("hi->ignore_btn = %d\n", hi->ignore_btn);
  112. if(hi->ignore_btn)
  113. {
  114. H2W_DBG("insert_headset_no-mic-headset \n");
  115. switch_set_state(&hi->sdev, LGE_NO_MIC_HEADSET);
  116. //kiwone, 2009.12.24 , to fix bug
  117. //no mic headset insert->no mic headset eject->4pole headset insert->button key do not work.
  118. /* Enable button irq */
  119. local_irq_save(irq_flags);
  120. enable_irq(hi->irq_btn);
  121. set_irq_wake(hi->irq_btn, 1);
  122. local_irq_restore(irq_flags);
  123. hi->debounce_time = ktime_set(0, 20000000); /* 20 ms */
  124. }
  125. else
  126. {
  127. H2W_DBG("insert_headset_headset \n");
  128. switch_set_state(&hi->sdev, LGE_HEADSET);
  129. /* Enable button irq */
  130. local_irq_save(irq_flags);
  131. enable_irq(hi->irq_btn);
  132. set_irq_wake(hi->irq_btn, 1);
  133. local_irq_restore(irq_flags);
  134. hi->debounce_time = ktime_set(0, 20000000); /* 20 ms */
  135. }
  136. }
  137. static void remove_headset(void)
  138. {
  139. unsigned long irq_flags;
  140. H2W_DBG("");
  141. input_report_switch(hi->input, SW_HEADPHONE_INSERT, 0);
  142. gpio_set_value(hi->gpio_mic_mode, 0);
  143. switch_set_state(&hi->sdev, NO_DEVICE);
  144. input_sync(hi->input);
  145. /* Disable button */
  146. local_irq_save(irq_flags);
  147. disable_irq(hi->irq_btn);
  148. set_irq_wake(hi->irq_btn, 0);
  149. local_irq_restore(irq_flags);
  150. if (atomic_read(&hi->btn_state))
  151. button_released();
  152. hi->debounce_time = ktime_set(0, 100000000); /* 100 ms */
  153. }
  154. static void detection_work(struct work_struct *work)
  155. {
  156. int cable_in1;
  157. H2W_DBG("");
  158. if (gpio_get_value(hi->gpio_detect) == 0) {
  159. /* Headset not plugged in */
  160. if (switch_get_state(&hi->sdev) == LGE_HEADSET
  161. || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET
  162. )
  163. remove_headset();
  164. H2W_DBG("detection_work-remove_headset \n");
  165. return;
  166. }
  167. msleep(100);
  168. cable_in1 = gpio_get_value(hi->gpio_detect);
  169. if (cable_in1 == 1) {
  170. if (switch_get_state(&hi->sdev) == NO_DEVICE)
  171. {
  172. H2W_DBG("detection_work-insert_headset \n");
  173. insert_headset();
  174. }
  175. }
  176. }
  177. static enum hrtimer_restart button_event_timer_func(struct hrtimer *data)
  178. {
  179. H2W_DBG("");
  180. if (switch_get_state(&hi->sdev) == LGE_HEADSET
  181. //kiwone, 2009.12.24, to fix bug
  182. // 4 pole headset eject->button key is detected
  183. && (1 == gpio_get_value(hi->gpio_detect))
  184. ) {
  185. H2W_DBG("button_event_timer_func\n");
  186. if (gpio_get_value(hi->gpio_button_detect)) {
  187. H2W_DBG("button_event_timer_func:1\n");
  188. if (hi->ignore_btn)
  189. hi->ignore_btn = 0;
  190. else if (atomic_read(&hi->btn_state))
  191. button_released();
  192. } else {
  193. H2W_DBG("button_event_timer_func:2\n");
  194. if (!hi->ignore_btn && !atomic_read(&hi->btn_state))
  195. button_pressed();
  196. }
  197. }
  198. return HRTIMER_NORESTART;
  199. }
  200. static enum hrtimer_restart detect_event_timer_func(struct hrtimer *data)
  201. {
  202. H2W_DBG("");
  203. queue_work(g_detection_work_queue, &g_detection_work);
  204. return HRTIMER_NORESTART;
  205. }
  206. static irqreturn_t detect_irq_handler(int irq, void *dev_id)
  207. {
  208. int value1, value2;
  209. int retry_limit = 10;
  210. H2W_DBG("");
  211. set_irq_type(hi->irq_btn, IRQF_TRIGGER_LOW);
  212. do {
  213. value1 = gpio_get_value(hi->gpio_detect);
  214. set_irq_type(hi->irq, value1 ?
  215. IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
  216. value2 = gpio_get_value(hi->gpio_detect);
  217. } while (value1 != value2 && retry_limit-- > 0);
  218. H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit));
  219. if (switch_get_state(&hi->sdev) == NO_DEVICE) {
  220. if (switch_get_state(&hi->sdev) == LGE_HEADSET
  221. || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET
  222. )
  223. hi->ignore_btn = 1;
  224. gpio_set_value(hi->gpio_mic_mode, 1);
  225. /* Do the rest of the work in timer context */
  226. hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL);
  227. H2W_DBG("detect_irq_handler-no_device \n");
  228. }
  229. else if(switch_get_state(&hi->sdev) == LGE_HEADSET
  230. || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET
  231. ){
  232. /* Do the rest of the work in timer context */
  233. hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL);
  234. H2W_DBG("detect_irq_handler_headset_no_mic \n");
  235. }
  236. return IRQ_HANDLED;
  237. }
  238. static irqreturn_t button_irq_handler(int irq, void *dev_id)
  239. {
  240. int value1, value2;
  241. int retry_limit = 10;
  242. H2W_DBG("button_irq_handler\n");
  243. do {
  244. value1 = gpio_get_value(hi->gpio_button_detect);
  245. H2W_DBG("button_irq_handler : value1 = %d\n", value1);
  246. set_irq_type(hi->irq_btn, value1 ?
  247. IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
  248. value2 = gpio_get_value(hi->gpio_button_detect);
  249. H2W_DBG("button_irq_handler : value2 = %d\n", value2);
  250. } while (value1 != value2 && retry_limit-- > 0);
  251. H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit));
  252. hrtimer_start(&hi->btn_timer, hi->btn_debounce_time, HRTIMER_MODE_REL);
  253. return IRQ_HANDLED;
  254. }
  255. static int gpio_h2w_probe(struct platform_device *pdev)
  256. {
  257. int ret;
  258. struct gpio_h2w_platform_data *pdata = pdev->dev.platform_data;
  259. H2W_DBG("H2W: Registering H2W (headset) driver\n");
  260. hi = kzalloc(sizeof(struct h2w_info), GFP_KERNEL);
  261. if (!hi)
  262. return -ENOMEM;
  263. atomic_set(&hi->btn_state, 0);
  264. hi->ignore_btn = 0;
  265. hi->debounce_time = ktime_set(0, 100000000); /* 100 ms */
  266. hi->btn_debounce_time = ktime_set(0, 10000000); /* 10 ms */
  267. hi->gpio_detect = pdata->gpio_detect;
  268. hi->gpio_button_detect = pdata->gpio_button_detect;
  269. hi->gpio_mic_mode = pdata->gpio_mic_mode;
  270. hi->sdev.name = "h2w_headset";
  271. hi->sdev.print_name = gpio_h2w_print_name;
  272. ret = switch_dev_register(&hi->sdev);
  273. if (ret < 0)
  274. goto err_switch_dev_register;
  275. g_detection_work_queue = create_workqueue("detection");
  276. if (g_detection_work_queue == NULL) {
  277. ret = -ENOMEM;
  278. goto err_create_work_queue;
  279. }
  280. gpio_tlmm_config(GPIO_CFG(hi->gpio_detect, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  281. ret = gpio_request(hi->gpio_detect, "h2w_detect");
  282. if (ret < 0)
  283. goto err_request_detect_gpio;
  284. gpio_tlmm_config(GPIO_CFG(hi->gpio_button_detect, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  285. ret = gpio_request(hi->gpio_button_detect, "h2w_button");
  286. if (ret < 0)
  287. goto err_request_button_gpio;
  288. gpio_tlmm_config(GPIO_CFG(hi->gpio_mic_mode, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
  289. ret = gpio_request(hi->gpio_mic_mode, "h2w_mic_mode");
  290. if (ret < 0)
  291. goto err_request_mic_mode_gpio;
  292. ret = gpio_direction_input(hi->gpio_detect);
  293. if (ret < 0)
  294. goto err_set_detect_gpio;
  295. ret = gpio_direction_input(hi->gpio_button_detect);
  296. if (ret < 0)
  297. goto err_set_button_gpio;
  298. hi->irq = gpio_to_irq(hi->gpio_detect);
  299. if (hi->irq < 0) {
  300. ret = hi->irq;
  301. goto err_get_h2w_detect_irq_num_failed;
  302. }
  303. hi->irq_btn = gpio_to_irq(hi->gpio_button_detect);
  304. if (hi->irq_btn < 0) {
  305. ret = hi->irq_btn;
  306. goto err_get_button_irq_num_failed;
  307. }
  308. hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  309. hi->timer.function = detect_event_timer_func;
  310. hrtimer_init(&hi->btn_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  311. hi->btn_timer.function = button_event_timer_func;
  312. ret = request_irq(hi->irq, detect_irq_handler,
  313. IRQF_TRIGGER_HIGH, "h2w_detect", NULL);
  314. if (ret < 0)
  315. goto err_request_detect_irq;
  316. /* Disable button until plugged in */
  317. set_irq_flags(hi->irq_btn, IRQF_VALID | IRQF_NOAUTOEN);
  318. ret = request_irq(hi->irq_btn, button_irq_handler,
  319. IRQF_TRIGGER_LOW, "h2w_button", NULL);
  320. if (ret < 0)
  321. goto err_request_h2w_headset_button_irq;
  322. ret = set_irq_wake(hi->irq, 1);
  323. if (ret < 0)
  324. goto err_request_input_dev;
  325. hi->input = input_allocate_device();
  326. if (!hi->input) {
  327. ret = -ENOMEM;
  328. goto err_request_input_dev;
  329. }
  330. hi->input->name = "h2w headset";
  331. hi->input->evbit[0] = BIT_MASK(EV_KEY);
  332. hi->input->keybit[BIT_WORD(KEY_MEDIA)] = BIT_MASK(KEY_MEDIA);
  333. ret = input_register_device(hi->input);
  334. if (ret < 0)
  335. goto err_register_input_dev;
  336. ip_dev_reg = 1;
  337. /* check the inital state of headset */
  338. queue_work(g_detection_work_queue, &g_detection_work);
  339. return 0;
  340. err_register_input_dev:
  341. input_free_device(hi->input);
  342. err_request_input_dev:
  343. free_irq(hi->irq_btn, 0);
  344. err_request_h2w_headset_button_irq:
  345. free_irq(hi->irq, 0);
  346. err_request_detect_irq:
  347. err_get_button_irq_num_failed:
  348. err_get_h2w_detect_irq_num_failed:
  349. err_set_button_gpio:
  350. err_set_detect_gpio:
  351. gpio_free(hi->gpio_button_detect);
  352. err_request_button_gpio:
  353. gpio_free(hi->gpio_detect);
  354. err_request_mic_mode_gpio:
  355. gpio_free(hi->gpio_mic_mode);
  356. err_request_detect_gpio:
  357. destroy_workqueue(g_detection_work_queue);
  358. err_create_work_queue:
  359. switch_dev_unregister(&hi->sdev);
  360. err_switch_dev_register:
  361. printk(KERN_ERR "H2W: Failed to register driver\n");
  362. return ret;
  363. }
  364. static int gpio_h2w_remove(struct platform_device *pdev)
  365. {
  366. H2W_DBG("");
  367. if (switch_get_state(&hi->sdev))
  368. remove_headset();
  369. input_unregister_device(hi->input);
  370. gpio_free(hi->gpio_button_detect);
  371. gpio_free(hi->gpio_detect);
  372. free_irq(hi->irq_btn, 0);
  373. free_irq(hi->irq, 0);
  374. destroy_workqueue(g_detection_work_queue);
  375. switch_dev_unregister(&hi->sdev);
  376. ip_dev_reg = 0;
  377. return 0;
  378. }
  379. static struct platform_driver gpio_h2w_driver = {
  380. .probe = gpio_h2w_probe,
  381. .remove = gpio_h2w_remove,
  382. .driver = {
  383. .name = "gpio-h2w",
  384. .owner = THIS_MODULE,
  385. },
  386. };
  387. static int __init gpio_h2w_init(void)
  388. {
  389. H2W_DBG("");
  390. return platform_driver_register(&gpio_h2w_driver);
  391. }
  392. static void __exit gpio_h2w_exit(void)
  393. {
  394. platform_driver_unregister(&gpio_h2w_driver);
  395. }
  396. module_init(gpio_h2w_init);
  397. module_exit(gpio_h2w_exit);
  398. MODULE_AUTHOR("Kiwone,Seo <gentleseo@lge.com>");
  399. MODULE_DESCRIPTION("LGE 2 Wire detection driver");
  400. MODULE_LICENSE("GPL");