1 /*
2 * Copyright (C) 2009 Rockchip Corporation.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/fs.h>
17 #include <linux/interrupt.h>
18 #include <linux/workqueue.h>
19 #include <linux/irq.h>
20 #include <linux/delay.h>
21 #include <linux/types.h>
22 #include <linux/input.h>
23 #include <linux/platform_device.h>
24 #include <linux/mutex.h>
25 #include <linux/errno.h>
26 #include <linux/err.h>
27 #include <linux/hrtimer.h>
28 #include <linux/extcon-provider.h>
29 #include <linux/debugfs.h>
30 #include <linux/wakelock.h>
31 #include <linux/pm.h>
32 #include <linux/i2c.h>
33 #include <linux/spi/spi.h>
34 #include <linux/iio/consumer.h>
35 #include <linux/wakelock.h>
36 #include <linux/gpio.h>
37
38 #include <asm/atomic.h>
39
40 #include "rk_headset.h"
41
42 /* Debug */
43 #if 0
44 #define DBG(x...) printk(x)
45 #else
46 #define DBG(x...) do { } while (0)
47 #endif
48
49 #define HOOK_ADC_SAMPLE_TIME 100
50
51 #define HOOK_LEVEL_HIGH 410 //1V*1024/2.5
52 #define HOOK_LEVEL_LOW 204 //0.5V*1024/2.5
53 #define HOOK_DEFAULT_VAL 1024
54
55 #define BIT_HEADSET BIT(0)
56 #define BIT_HEADSET_NO_MIC BIT(1)
57
58 #define HEADSET 0
59 #define HOOK 1
60
61 #define HEADSET_IN 1
62 #define HEADSET_OUT 0
63 #define HOOK_DOWN 1
64 #define HOOK_UP 0
65 #define enable 1
66 #define disable 0
67
68 #define HEADSET_TIMER 1
69 #define HOOK_TIMER 2
70
71 #define WAIT 2
72 #define BUSY 1
73 #define IDLE 0
74
75 #ifdef CONFIG_SND_SOC_WM8994
76 extern int wm8994_headset_mic_detect(bool headset_status);
77 #endif
78 #ifdef CONFIG_SND_SOC_RT5631_PHONE
79 extern int rt5631_headset_mic_detect(bool headset_status);
80 #endif
81 #if defined(CONFIG_SND_SOC_RT3261) || defined(CONFIG_SND_SOC_RT3224)
82 extern int rt3261_headset_mic_detect(int jack_insert);
83 #endif
84
85
86 /* headset private data */
87 struct headset_priv {
88 struct input_dev *input_dev;
89 struct rk_headset_pdata *pdata;
90 unsigned int headset_status : 1;
91 unsigned int hook_status : 1;
92 int isMic;
93 struct iio_channel *chan;
94 /* headset interrupt working will not check hook key */
95 unsigned int heatset_irq_working;
96 int cur_headset_status;
97 unsigned int irq[2];
98 struct delayed_work h_delayed_work[2];
99 struct extcon_dev *edev;
100 struct mutex mutex_lock[2];
101 unsigned char *keycodes;
102 struct delayed_work hook_work;
103 /* ms */
104 unsigned int hook_time;
105 };
106
107 static struct headset_priv *headset_info;
108
headset_interrupt(int irq,void * dev_id)109 static irqreturn_t headset_interrupt(int irq, void *dev_id)
110 {
111 struct rk_headset_pdata *pdata = headset_info->pdata;
112 static unsigned int old_status = 0;
113 int i, level = 0;
114
115 disable_irq_nosync(headset_info->irq[HEADSET]);
116 if (headset_info->heatset_irq_working == BUSY ||
117 headset_info->heatset_irq_working == WAIT)
118 return IRQ_HANDLED;
119 DBG("In the headset_interrupt\n");
120 headset_info->heatset_irq_working = BUSY;
121 msleep(150);
122 for (i = 0; i < 3; i++) {
123 level = gpio_get_value(pdata->headset_gpio);
124 if (level < 0) {
125 pr_err("%s:get pin level again,pin=%d,i=%d\n",
126 __func__, pdata->headset_gpio, i);
127 msleep(1);
128 continue;
129 }
130 break;
131 }
132 if (level < 0) {
133 pr_err("%s:get pin level err!\n", __func__);
134 goto out;
135 } else {
136 pr_err("%s:get pin level again, pin=%d,i=%d\n",
137 __func__, pdata->headset_gpio, i);
138 }
139
140 old_status = headset_info->headset_status;
141 switch (pdata->headset_insert_type) {
142 case HEADSET_IN_HIGH:
143 if (level > 0)
144 headset_info->headset_status = HEADSET_IN;
145 else if (level == 0)
146 headset_info->headset_status = HEADSET_OUT;
147 break;
148 case HEADSET_IN_LOW:
149 if (level == 0)
150 headset_info->headset_status = HEADSET_IN;
151 else if (level > 0)
152 headset_info->headset_status = HEADSET_OUT;
153 break;
154 default:
155 DBG("---- ERROR: on headset headset_insert_type error -----\n");
156 break;
157 }
158 if (old_status == headset_info->headset_status) {
159 DBG("Read Headset IO level old status == now status =%d\n",
160 headset_info->headset_status);
161 goto out;
162 }
163
164 pr_info("(headset in is %s)headset status is %s\n",
165 pdata->headset_insert_type ? "high level" : "low level",
166 headset_info->headset_status ? "in" : "out");
167
168 if (headset_info->headset_status == HEADSET_IN) {
169 if (pdata->chan != 0) {
170 /* detect Hook key */
171 schedule_delayed_work(
172 &headset_info->h_delayed_work[HOOK],
173 msecs_to_jiffies(200));
174 } else {
175 headset_info->isMic = 0;
176 headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
177 extcon_set_state_sync(headset_info->edev,
178 EXTCON_JACK_HEADPHONE, true);
179 DBG("headset notice android headset status = %d\n",
180 headset_info->cur_headset_status);
181 }
182 if (pdata->headset_insert_type == HEADSET_IN_HIGH)
183 irq_set_irq_type(headset_info->irq[HEADSET],
184 IRQF_TRIGGER_FALLING);
185 else
186 irq_set_irq_type(headset_info->irq[HEADSET],
187 IRQF_TRIGGER_RISING);
188 } else if (headset_info->headset_status == HEADSET_OUT) {
189 headset_info->cur_headset_status = HEADSET_OUT;
190 cancel_delayed_work(&headset_info->hook_work);
191 if (headset_info->isMic) {
192 if (headset_info->hook_status == HOOK_DOWN) {
193 headset_info->hook_status = HOOK_UP;
194 input_report_key(headset_info->input_dev, HOOK_KEY_CODE, headset_info->hook_status);
195 input_sync(headset_info->input_dev);
196 }
197 #ifdef CONFIG_SND_SOC_WM8994
198 //rt5625_headset_mic_detect(false);
199 wm8994_headset_mic_detect(false);
200 #endif
201 #if defined(CONFIG_SND_SOC_RT3261) || defined(CONFIG_SND_SOC_RT3224)
202 rt3261_headset_mic_detect(false);
203 #endif
204 #ifdef CONFIG_SND_SOC_RT5631_PHONE
205 rt5631_headset_mic_detect(false);
206 #endif
207 headset_info->isMic = 0;
208 }
209
210 if (pdata->headset_insert_type == HEADSET_IN_HIGH)
211 irq_set_irq_type(headset_info->irq[HEADSET],
212 IRQF_TRIGGER_RISING);
213 else
214 irq_set_irq_type(headset_info->irq[HEADSET],
215 IRQF_TRIGGER_FALLING);
216 extcon_set_state_sync(headset_info->edev, EXTCON_JACK_HEADPHONE,
217 false);
218 extcon_set_state_sync(headset_info->edev,
219 EXTCON_JACK_MICROPHONE, false);
220 DBG("headset notice android headset status = %d\n",
221 headset_info->cur_headset_status);
222 }
223 /*rk_send_wakeup_key(); */
224 out:
225 headset_info->heatset_irq_working = IDLE;
226 enable_irq(headset_info->irq[HEADSET]);
227 return IRQ_HANDLED;
228 }
229
230 #if 0
231 static int headset_change_irqtype(int type, unsigned int irq_type)
232 {
233 int ret = 0;
234
235 free_irq(headset_info->irq[type], NULL);
236
237 DBG("%s: type is %s irqtype is %s\n", __func__,
238 type ? "hook" : "headset",
239 (irq_type == IRQF_TRIGGER_RISING) ? "RISING" : "FALLING");
240 // DBG("%s: type is %s irqtype is %s\n",__func__, type?"hook":"headset",(irq_type == IRQF_TRIGGER_LOW)?"LOW":"HIGH");
241 switch (type) {
242 case HEADSET:
243 ret =
244 request_threaded_irq(headset_info->irq[type], NULL,
245 headset_interrupt, irq_type,
246 "headset_input", NULL);
247 if (ret < 0)
248 DBG("headset_change_irqtype: request irq failed\n");
249 break;
250 default:
251 ret = -1;
252 break;
253 }
254 return ret;
255 }
256 #endif
257
hook_once_work(struct work_struct * work)258 static void hook_once_work(struct work_struct *work)
259 {
260 int ret, val;
261
262 #ifdef CONFIG_SND_SOC_WM8994
263 wm8994_headset_mic_detect(true);
264 #endif
265
266 #if defined(CONFIG_SND_SOC_RT3261) || defined(CONFIG_SND_SOC_RT3224)
267 rt3261_headset_mic_detect(true);
268 #endif
269
270 #ifdef CONFIG_SND_SOC_RT5631_PHONE
271 rt5631_headset_mic_detect(true);
272 #endif
273 ret = iio_read_channel_raw(headset_info->chan, &val);
274 if (ret < 0)
275 pr_err("read hook_once_work adc channel() error: %d\n", ret);
276 else
277 DBG("hook_once_work read adc value: %d\n", val);
278
279 if (val >= 0 && val < HOOK_LEVEL_LOW) {
280 headset_info->isMic = 0;
281 #ifdef CONFIG_SND_SOC_WM8994
282 wm8994_headset_mic_detect(false);
283 #endif
284
285 #if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
286 rt3261_headset_mic_detect(false);
287 #endif
288
289 #ifdef CONFIG_SND_SOC_RT5631_PHONE
290 rt5631_headset_mic_detect(false);
291 #endif
292 } else if (val >= HOOK_LEVEL_HIGH) {
293 headset_info->isMic = 1;
294 schedule_delayed_work(&headset_info->hook_work,
295 msecs_to_jiffies(100));
296 }
297 headset_info->cur_headset_status =
298 headset_info->isMic ? BIT_HEADSET : BIT_HEADSET_NO_MIC;
299 if (headset_info->cur_headset_status) {
300 if (headset_info->isMic) {
301 extcon_set_state_sync(headset_info->edev,
302 EXTCON_JACK_MICROPHONE, true);
303 } else {
304 extcon_set_state_sync(headset_info->edev,
305 EXTCON_JACK_HEADPHONE, true);
306 }
307 }
308 DBG("%s notice android headset status = %d\n", __func__,
309 headset_info->cur_headset_status);
310 }
311
hook_work_callback(struct work_struct * work)312 static void hook_work_callback(struct work_struct *work)
313 {
314 int ret, val;
315 struct headset_priv *headset = headset_info;
316 struct rk_headset_pdata *pdata = headset->pdata;
317 static unsigned int old_status = HOOK_UP;
318
319 ret = iio_read_channel_raw(headset->chan, &val);
320 if (ret < 0) {
321 pr_err("read hook adc channel() error: %d\n", ret);
322 goto out;
323 } else {
324 DBG("hook_work_callback read adc value=%d\n", val);
325 }
326
327 if (headset->headset_status == HEADSET_OUT ||
328 headset->heatset_irq_working == BUSY ||
329 headset->heatset_irq_working == WAIT ||
330 (pdata->headset_insert_type ?
331 gpio_get_value(pdata->headset_gpio) == 0 :
332 gpio_get_value(pdata->headset_gpio) > 0)) {
333 DBG("Headset is out or waiting for headset is in or out, after same time check HOOK key\n");
334 goto out;
335 }
336 old_status = headset->hook_status;
337 if (val < HOOK_LEVEL_LOW && val >= 0)
338 headset->hook_status = HOOK_DOWN;
339 else if (val > HOOK_LEVEL_HIGH && val < HOOK_DEFAULT_VAL)
340 headset->hook_status = HOOK_UP;
341 DBG("HOOK status is %s , adc value = %d hook_time = %d\n",
342 headset->hook_status ? "down" : "up", val, headset->hook_time);
343 if (old_status == headset->hook_status) {
344 DBG("Hook adc read old_status == headset->hook_status=%d hook_time = %d\n",
345 headset->hook_status, headset->hook_time);
346 goto status_error;
347 }
348 if (headset->headset_status == HEADSET_OUT ||
349 headset->heatset_irq_working == BUSY ||
350 headset->heatset_irq_working == WAIT ||
351 (pdata->headset_insert_type ?
352 gpio_get_value(pdata->headset_gpio) == 0 :
353 gpio_get_value(pdata->headset_gpio) > 0)) {
354 printk("headset is out, HOOK status must discard\n");
355 goto out;
356 } else {
357 input_report_key(headset->input_dev,
358 HOOK_KEY_CODE, headset->hook_status);
359 input_sync(headset->input_dev);
360 }
361 status_error:
362 schedule_delayed_work(&headset_info->hook_work, msecs_to_jiffies(100));
363 out:;
364 }
365
rk_hskey_open(struct input_dev * dev)366 static int rk_hskey_open(struct input_dev *dev)
367 {
368 return 0;
369 }
370
rk_hskey_close(struct input_dev * dev)371 static void rk_hskey_close(struct input_dev *dev)
372 {
373 }
374
375 static const unsigned int headset_cable[] = {
376 EXTCON_JACK_MICROPHONE,
377 EXTCON_JACK_HEADPHONE,
378 EXTCON_NONE,
379 };
380
rk_headset_adc_probe(struct platform_device * pdev,struct rk_headset_pdata * pdata)381 int rk_headset_adc_probe(struct platform_device *pdev,
382 struct rk_headset_pdata *pdata)
383 {
384 int ret;
385 struct headset_priv *headset;
386
387 headset = devm_kzalloc(&pdev->dev, sizeof(*headset), GFP_KERNEL);
388 if (!headset) {
389 dev_err(&pdev->dev, "failed to allocate driver data\n");
390 ret = -ENOMEM;
391 goto failed;
392 }
393 headset_info = headset;
394 headset->pdata = pdata;
395 headset->headset_status = HEADSET_OUT;
396 headset->heatset_irq_working = IDLE;
397 headset->hook_status = HOOK_UP;
398 headset->hook_time = HOOK_ADC_SAMPLE_TIME;
399 headset->cur_headset_status = 0;
400 headset->edev = devm_extcon_dev_allocate(&pdev->dev, headset_cable);
401 if (IS_ERR(headset->edev)) {
402 dev_err(&pdev->dev, "failed to allocate extcon device\n");
403 ret = -ENOMEM;
404 goto failed;
405 }
406 ret = devm_extcon_dev_register(&pdev->dev, headset->edev);
407 if (ret < 0) {
408 dev_err(&pdev->dev, "extcon_dev_register() failed: %d\n", ret);
409 goto failed;
410 }
411 INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], hook_once_work);
412 headset->isMic = 0;
413 //------------------------------------------------------------------
414 // Create and register the input driver
415 headset->input_dev = devm_input_allocate_device(&pdev->dev);
416 if (!headset->input_dev) {
417 dev_err(&pdev->dev, "failed to allocate input device\n");
418 ret = -ENOMEM;
419 goto failed;
420 }
421 headset->input_dev->name = pdev->name;
422 headset->input_dev->open = rk_hskey_open;
423 headset->input_dev->close = rk_hskey_close;
424 headset->input_dev->dev.parent = &pdev->dev;
425 //input_dev->phys = KEY_PHYS_NAME;
426 headset->input_dev->id.vendor = 0x0001;
427 headset->input_dev->id.product = 0x0001;
428 headset->input_dev->id.version = 0x0100;
429 // Register the input device
430 ret = input_register_device(headset->input_dev);
431 if (ret) {
432 dev_err(&pdev->dev, "failed to register input device\n");
433 goto failed;
434 }
435 input_set_capability(headset->input_dev, EV_KEY, HOOK_KEY_CODE);
436 if (pdata->headset_gpio) {
437 unsigned long irq_type;
438
439 headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio);
440 if (pdata->headset_insert_type == HEADSET_IN_HIGH)
441 irq_type = IRQF_TRIGGER_HIGH;
442 else
443 irq_type = IRQF_TRIGGER_LOW;
444 irq_type |= IRQF_NO_SUSPEND | IRQF_ONESHOT;
445 ret =
446 devm_request_threaded_irq(&pdev->dev, headset->irq[HEADSET],
447 NULL, headset_interrupt,
448 irq_type, "headset_input",
449 NULL);
450 if (ret)
451 goto failed;
452 if (pdata->headset_wakeup)
453 enable_irq_wake(headset->irq[HEADSET]);
454 } else {
455 dev_err(&pdev->dev, "failed init headset,please full hook_io_init function in board\n");
456 ret = -EEXIST;
457 goto failed;
458 }
459 if (pdata->chan) {
460 headset->chan = pdata->chan;
461 INIT_DELAYED_WORK(&headset->hook_work, hook_work_callback);
462 }
463 return 0;
464 failed:
465 dev_err(&pdev->dev, "failed headset adc probe ret=%d\n", ret);
466 return ret;
467 }
468 EXPORT_SYMBOL_GPL(rk_headset_adc_probe);
469
rk_headset_adc_suspend(struct platform_device * pdev,pm_message_t state)470 int rk_headset_adc_suspend(struct platform_device *pdev, pm_message_t state)
471 {
472 DBG("%s----%d\n", __func__, __LINE__);
473 // disable_irq(headset_info->irq[HEADSET]);
474 // del_timer(&headset_info->hook_timer);
475 return 0;
476 }
477 EXPORT_SYMBOL_GPL(rk_headset_adc_suspend);
478
rk_headset_adc_resume(struct platform_device * pdev)479 int rk_headset_adc_resume(struct platform_device *pdev)
480 {
481 DBG("%s----%d\n", __func__, __LINE__);
482 // enable_irq(headset_info->irq[HEADSET]);
483 // if(headset_info->isMic)
484 // mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1500));
485 return 0;
486 }
487 EXPORT_SYMBOL_GPL(rk_headset_adc_resume);
488
489 MODULE_LICENSE("GPL");
490