blob: 42f6dcb27bf57fe927dfecdc4fcefa3856a1e9d8 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/***********************************************************************
2* Copyright (C) 2016, Sanechips Corporation.
3*
4* File Name: zx29-keypad-int.c
5* File Mark:
6* Description:
7* Others:
8* Version: v1.0
9* Author: qihongfang yuxiang lvfei ZhouTianbao
10* Date: 2017-2-28
11*
12* History 1:
13* Date:
14* Version:
15* Author:
16* Modification:
17**********************************************************************/
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/input.h>
23#include <linux/errno.h>
24#include <linux/io.h>
25#include <linux/pm_runtime.h>
26#include <linux/slab.h>
27#include <asm/irq.h>
28#include <linux/workqueue.h>
29
30#include <linux/gpio.h>
31#include <mach/gpio.h>
32#include <mach/pcu.h>
33#include <linux/irq.h>
34#include <linux/gpio_keys.h>
35#include <linux/delay.h>
36#include <linux/wakelock.h>
37
38#include <mach/irqs.h>
39#include <linux/mfd/zx234290.h>
40#include <linux/kthread.h>
41#include <linux/soc/zte/pm/drv_idle.h>
42
43/**********************************************************************/
44//#define ERROR_REGISTER_IRQ -100
45
46#define KEY_STATUS_UP 0
47#define KEY_STATUS_DOWN 1 /*input×ÓϵͳÖÐvalueΪ1Êǰ´ÏÂ*/
48
49#define KEY_DELAY_TIME 30 /* ms */
50#define KEY_NUM 30
51
52static struct input_dev *button_dev = NULL;
53
54typedef struct _zx234290_keypad
55{
56 struct zx234290 *zx234290;
57}zx234290_keypad_data;
58
59static zx234290_keypad_data zx234290_keypad;
60
61static spinlock_t kpd_lock;
62static volatile unsigned int key_active_count = 0;
63static struct wake_lock keypad_wake_lock;
64static struct semaphore kpd_sem;
65
66//#ifdef KPD_DEBUG
67struct key_info
68{
69 unsigned int index;
70 unsigned int code;
71 int value;
72};
73struct key_info key_info_tab[KEY_NUM]=
74{
75 {0},
76};
77static unsigned int key_info_idx = 0;
78static unsigned int key_info_counter = 0;
79//#endif
80
81static int zx29_kpd_queue(unsigned int code, int value)
82{
83 key_info_tab[key_info_idx].code = code;
84 key_info_tab[key_info_idx].value= value;
85 key_info_tab[key_info_idx].index = key_info_counter;
86 key_info_idx++;
87 key_info_counter++;
88 if(key_info_idx >= KEY_NUM)
89 {
90 key_info_idx = 0;
91 }
92 return 0;
93}
94
95static void zx29_key_set_active(void)
96{
97 spin_lock(&kpd_lock);
98
99 if(key_active_count == 0)
100 {
101 zx_cpuidle_set_busy(IDLE_FLAG_KPD);
102 wake_lock(&keypad_wake_lock);
103 }
104 key_active_count++;
105
106 spin_unlock(&kpd_lock);
107}
108
109static void zx29_key_set_idle(void)
110{
111 spin_lock(&kpd_lock);
112
113 key_active_count--;
114 if(key_active_count == 0)
115 {
116 wake_unlock(&keypad_wake_lock);
117 zx_cpuidle_set_free(IDLE_FLAG_KPD);
118 }
119
120 spin_unlock(&kpd_lock);
121}
122
123/*******************************************************************************
124* Function: zx29_kpd_get_keystate
125* Description: Test key state
126* Parameters:
127* Input:
128* Output:
129* Returns: 0: key down µÍµçƽ(press) 1: key up ¸ßµçƽ(release)
130* Others:
131* zx29_gpio_config(unsigned int gpio, unsigned int value) ÉèÖø´ÓÃ
132* value: 0:GPIO 1:FUNCTION
133********************************************************************************/
134
135static int zx29_kpd_get_keystate(int gpioNum,unsigned int gpio_sel_gpio,unsigned int gpio_sel_int)
136{
137 unsigned int gpio_state = GPIO_HIGH;
138 int irq;
139
140 zx29_gpio_config(gpioNum, gpio_sel_gpio);
141 irq = gpio_to_irq(gpioNum);
142 //pcu_clr_irq_pending(irq);
143 zx29_gpio_set_direction(gpioNum, GPIO_IN);
144 msleep(KEY_DELAY_TIME);
145 gpio_state = gpio_get_value(gpioNum);
146 /* msleep(30); */
147 zx29_gpio_config(gpioNum, gpio_sel_int);/******qhf***int****/
148 //pcu_clr_irq_pending(irq);
149
150 //printk(KERN_INFO "gpio state=%d.\n",gpio_state);
151
152 return gpio_state; /* 0: µÍµçƽ(press), 1:¸ßµçƽ(release) */
153
154}
155
156static irqreturn_t zx29_kpd_pwron_inform(int irq, void *dev_id)
157{
158 up(&kpd_sem);
159 return IRQ_HANDLED;
160}
161
162/*******************************************************************************
163* Function: zx29_kpd_pwron_thread
164* Description:
165* Parameters:
166* Input:
167* Output:
168* Returns:
169* Others:
170********************************************************************************/
171#define USE_EXT_DEV
172#ifdef USE_EXT_DEV
173//extern struct input_dev *button5x6_dev;
174extern struct input_dev *input_dev_table[32];
175#endif
176int zx29_kpd_pwron_thread(void *dev_id)
177{
178 struct gpio_keys_button *buttons = (struct gpio_keys_button *)dev_id;
179 int ret = 0;
180 unsigned char status = 0;
181
182 struct sched_param param;
183 param.sched_priority = 33;
184 sched_setscheduler(current, SCHED_FIFO, &param);
185
186 while (!kthread_should_stop()) {
187 down(&kpd_sem);
188
189 zx29_key_set_active();
190
191 msleep(10);
192 ret = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status);
193 if(ret)
194 {
195 printk(KERN_INFO "kpd read reg return=%d.\n", ret);
196 }
197 else if((status >> ZX234290_STATUSA_POWERON_LSH) & 0x1)
198 {
199#ifdef USE_EXT_DEV
200 if (input_dev_table[1]) {
201 set_bit(buttons->code, input_dev_table[1]->keybit);
202 input_report_key(input_dev_table[1], buttons->code, KEY_STATUS_DOWN);
203 input_sync(input_dev_table[1]);
204 }
205#endif
206 input_report_key(button_dev, buttons->code, KEY_STATUS_DOWN);
207 input_sync(button_dev);
208
209 zx29_kpd_queue(buttons->code, KEY_STATUS_DOWN);
210 printk(KERN_INFO "kpd down code=%d .\n",buttons->code);
211
212 while(1)
213 {
214 msleep(60);
215
216 ret = zx234290_i2c_read_simple(ZX234290_REG_ADDR_STSA, &status);
217 if(ret)
218 {
219 printk(KERN_INFO "kpd read reg return=%d.\n", ret);
220 break;
221 }
222 //printk(KERN_INFO "kpd reg status=%d.\n", status);
223
224 if(((status>>ZX234290_STATUSA_POWERON_LSH)&0x1) == 0x0)
225 {
226#ifdef USE_EXT_DEV
227 if (input_dev_table[1]) {
228 input_report_key(input_dev_table[1], buttons->code, KEY_STATUS_UP);
229 input_sync(input_dev_table[1]);
230 }
231#endif
232 input_report_key(button_dev, buttons->code, KEY_STATUS_UP);
233 input_sync(button_dev);
234
235 zx29_kpd_queue(buttons->code, KEY_STATUS_UP);
236 printk(KERN_INFO "kpd up code=%d.\n",buttons->code);
237 break;
238 }
239 }
240 }
241 else
242 {
243 printk(KERN_INFO "kpd power key noise.\n");
244 }
245
246 zx29_key_set_idle();
247 }
248
249 return 0;
250}
251
252static irqreturn_t zx29_kpd_irq_thread(int irq, void *dev_id)
253{
254 struct gpio_keys_button *buttons = (struct gpio_keys_button *)dev_id;
255 int gpio_val = 0;
256 int state;
257
258 zx29_key_set_active();
259
260 //printk(KERN_INFO "handle irq=%d.\n",irq);
261 gpio_val = zx29_kpd_get_keystate(buttons->gpio,buttons->gpio_sel_gpio,buttons->gpio_sel_int);
262 state = !!gpio_val ^ !!buttons->active_low;
263
264 zx29_gpio_set_inttype(buttons->gpio,
265 (gpio_val ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH));
266 //pcu_int_clear(irq);
267 //pcu_clr_irq_pending(irq);
268
269#ifdef USE_EXT_DEV
270 if (input_dev_table[1]) {
271 set_bit(buttons->code, input_dev_table[1]->keybit);
272 input_report_key(input_dev_table[1], buttons->code, state);
273 input_sync(input_dev_table[1]);
274 }
275#endif
276
277 input_report_key(button_dev, buttons->code, state); //Éϱ¨key ¼üÖµ
278 //key_info_tab[key_num].lastStatus = state;
279 input_sync(button_dev);
280 zx29_kpd_queue(buttons->code, state);
281 printk(KERN_INFO "kpd %s code=%d, irq=%d.\n",
282 (state ? "down" : "up"),
283 buttons->code,
284 irq);
285
286 //enable_irq(irq); //´ò¿ªÖжÏ
287
288 zx29_key_set_idle();
289 return IRQ_HANDLED;
290}
291
292/*******************************************************************************
293* Function: zx29_kpd_irq_handler
294* Description: clear irq , wake thread irq
295* Parameters:
296* Input:
297* Output:
298********************************************************************************/
299static irqreturn_t zx29_kpd_irq_handler(int irq, void *dev_id)
300{
301 //disable_irq_nosync(irq);
302 //pcu_int_clear(irq);
303 pcu_clr_irq_pending(irq);
304
305 //printk(KERN_INFO "kpd handler irq=%d.\n", irq);
306
307 return IRQ_WAKE_THREAD;
308}
309
310/*******************************************************************************
311* Function: zx29_kpd_request_irqs
312* Description:
313* Parameters:
314* Input:
315* Output:
316********************************************************************************/
317static int zx29_kpd_request_irqs(struct gpio_keys_platform_data *pdata )
318{
319 int ret = -1;
320 struct gpio_keys_button *buttons = pdata->buttons;
321 int keypad_num = pdata->nbuttons;
322 int irq_num = 0;
323
324 for(keypad_num = 0; keypad_num < pdata->nbuttons; keypad_num++)
325 {
326 if(buttons[keypad_num].use_pmu_pwron == 0)
327 {
328 ret = gpio_request(buttons[keypad_num].gpio, buttons[keypad_num].desc);
329 if (ret < 0) {
330 printk(KERN_ERR "kpd request gpio%d failed.\n", buttons[keypad_num].gpio);
331 break;
332 }
333 zx29_gpio_config(buttons[keypad_num].gpio,buttons[keypad_num].gpio_sel_int);
334 /* some switch may be active before booting. use level irq to avoid lack of falling edge. */
335 zx29_gpio_set_inttype(buttons[keypad_num].gpio,
336 (buttons[keypad_num].active_low ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH));
337 zx29_gpio_pd_pu_set(buttons[keypad_num].gpio, 0);
338
339 msleep(1); /* wait for stable input */
340
341 irq_num = gpio_to_irq(buttons[keypad_num].gpio);
342 /*
343 if(irq_num > 0){
344 printk(KERN_INFO "zx29_kpd_request_irqs error irq_num=%d.\n",irq_num);
345 }
346 */
347
348 /* pcu_clr_irq_pending(irq_num); */
349 ret = request_threaded_irq(irq_num, NULL, zx29_kpd_irq_thread, IRQF_ONESHOT/*IRQF_TRIGGER_HIGH | IRQF_NO_THREAD*/,
350 buttons[keypad_num].desc, &buttons[keypad_num]);
351 irq_set_irq_wake(irq_num, 1);
352 }
353 else
354 {
355 sema_init(&kpd_sem, 0);
356 kthread_run(zx29_kpd_pwron_thread, &buttons[keypad_num], "kpd_pwron_thread");
357
358 irq_num = ENT_ZX234290_IRQ_BASE + ZX234290_INT_PWRON;
359 ret = request_threaded_irq(irq_num, NULL, zx29_kpd_pwron_inform, 0,
360 buttons[keypad_num].desc, &buttons[keypad_num]);
361 }
362 if(ret)
363 {
364 return ret;
365 }
366 printk(KERN_INFO "kpd request_irq irq_num=%d.\n", irq_num);
367 }
368
369 return ret;
370}
371
372/*******************************************************************************
373* Function: zx29_kpd_probe
374* Description:
375* Parameters:
376* Input:
377* Output:
378* Returns:
379********************************************************************************/
380static int zx29_kpd_probe(struct platform_device *pdev)
381{
382 int error = -1;
383 static int i = 0;
384 struct input_handle *handle;
385 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
386 struct gpio_keys_button *buttons = pdata->buttons;
387 zx234290_keypad.zx234290 = dev_get_drvdata(pdev->dev.parent);
388
389 button_dev = input_allocate_device();
390 if(!button_dev)
391 {
392 printk("allocate_device error.\n");
393 return error;
394 }
395 button_dev->name = pdev->name;
396 button_dev->evbit[0] = BIT_MASK(EV_KEY)|BIT_MASK(EV_REP);
397
398 for(i=0; i < pdata->nbuttons; i++)
399 {
400 set_bit(buttons[i].code,button_dev->keybit);
401 }
402
403 error = input_register_device(button_dev);
404 if(error)
405 {
406 printk("register device error\n");
407 goto err_free_dev;
408 }
409 handle = container_of(button_dev->h_list.next, struct input_handle, d_node);
410 /* printk(KERN_INFO "%s registered evdev %s/%p.\n", __FUNCTION__, handle->name, handle->private); */
411
412 platform_set_drvdata(pdev, button_dev);
413
414 spin_lock_init(&kpd_lock);
415 wake_lock_init(&keypad_wake_lock, WAKE_LOCK_SUSPEND, "keypad");
416 zx29_kpd_request_irqs(pdata);
417
418 return 0;
419
420err_free_dev:
421 input_free_device(button_dev);
422 return error;
423}
424
425
426/*******************************************************************************
427* Function: zx29_kpd_remove
428* Description:
429* Parameters:
430* Input:
431* Output:
432* Returns:
433********************************************************************************/
434static int zx29_kpd_remove(struct platform_device *pdev)
435{
436 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
437 struct gpio_keys_button *buttons = pdata->buttons;
438 static struct input_dev *button_dev = NULL;
439 int i = 0;
440 int irq_num;
441
442 for(i = 0; i < pdata->nbuttons; i++){
443 irq_num = gpio_to_irq(buttons[i].gpio);
444 if(irq_num < 0){
445 printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
446 }
447
448 free_irq(irq_num,NULL);
449 gpio_free(buttons[i].gpio);
450 }
451 button_dev = (struct input_dev *)platform_get_drvdata(pdev);
452 input_free_device(button_dev);
453 button_dev = NULL;
454
455 zx234290_keypad.zx234290 = NULL;
456
457 wake_lock_destroy(&keypad_wake_lock);
458
459 return 0;
460}
461
462static int zx29_kpd_resume(struct platform_device *pdev)
463{
464 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
465 struct gpio_keys_button *buttons = pdata->buttons;
466 int i = 0;
467 int irq_num = 0;
468
469 for(i = 0; i < pdata->nbuttons; i++){
470
471 irq_num = gpio_to_irq(buttons[i].gpio);
472 if(irq_num < 0){
473 printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
474 }
475 if(irq_num != 0){
476 enable_irq(irq_num);
477 }
478
479 }
480 printk(KERN_INFO "%s\n", __FUNCTION__);
481 return 0;
482}
483
484static int zx29_kpd_suspend(struct platform_device *pdev, pm_message_t state)
485{
486 struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
487 struct gpio_keys_button *buttons = pdata->buttons;
488 int i = 0;
489 int irq_num = 0;
490
491 for(i = 0; i < pdata->nbuttons; i++){
492 irq_num = gpio_to_irq(buttons[i].gpio);
493 if(irq_num < 0){
494 printk(KERN_INFO "%s error keypad_num=%d.\n", __FUNCTION__, i);
495 }
496 if(irq_num != 0){
497 disable_irq(irq_num);
498 }
499
500 }
501 printk(KERN_INFO "%s\n", __FUNCTION__);
502 return 0;
503}
504
505static struct platform_driver zx29_kpd_driver =
506{
507 .probe = zx29_kpd_probe,
508 .remove = zx29_kpd_remove,
509 .driver =
510 {
511 .name = "zx29_keypad_int",
512 .owner = THIS_MODULE,
513 },
514 //.resume = zx29_kpd_resume,
515 //.suspend = zx29_kpd_suspend,
516};
517
518static int __init zx29_kpd_init(void)
519{
520 return platform_driver_register(&zx29_kpd_driver);
521}
522
523static void __exit zx29_kpd_exit(void)
524{
525 platform_driver_unregister(&zx29_kpd_driver);
526}
527
528module_init(zx29_kpd_init);
529module_exit(zx29_kpd_exit);
530
531MODULE_AUTHOR("Sanechips");
532MODULE_DESCRIPTION("Sanechips Keypad Driver");
533MODULE_LICENSE("GPL");
534