^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* arch/arm/mach-rockchip/rk28_headset.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009 Rockchip Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This software is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * License version 2, as published by the Free Software Foundation, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * may be copied, distributed, and modified under those terms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/hrtimer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/wakelock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "rk_headset.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifdef CONFIG_HAS_EARLYSUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/earlysuspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DBG(x...) printk(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DBG(x...) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define BIT_HEADSET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define BIT_HEADSET_NO_MIC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define HEADSET 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define HOOK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define HEADSET_IN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define HEADSET_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define HOOK_DOWN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define HOOK_UP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define enable 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define disable 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) extern void rk2928_codec_set_spk(bool on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifdef CONFIG_SND_SOC_WM8994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) extern int wm8994_set_status(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* headset private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct headset_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct rk_headset_pdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) unsigned int headset_status : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int hook_status : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) unsigned int isMic : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) unsigned int isHook_irq : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int cur_headset_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) unsigned int irq[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned int irq_type[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct delayed_work h_delayed_work[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct mutex mutex_lock[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct timer_list headset_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned char *keycodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static struct headset_priv *headset_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #ifdef CONFIG_MODEM_MIC_SWITCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define HP_MIC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MAIN_MIC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void Modem_Mic_switch(int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (value == HP_MIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) gpio_set_value(headset_info->pdata->mic_switch_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) headset_info->pdata->hp_mic_io_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) else if (value == MAIN_MIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) gpio_set_value(headset_info->pdata->mic_switch_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) headset_info->pdata->main_mic_io_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) void Modem_Mic_release(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (headset_info->cur_headset_status == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) gpio_set_value(headset_info->pdata->mic_switch_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) headset_info->pdata->hp_mic_io_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) gpio_set_value(headset_info->pdata->mic_switch_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) headset_info->pdata->main_mic_io_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int read_gpio(int gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int i, level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) level = gpio_get_value(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (level < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) pr_warn("%s:get pin level again,pin=%d,i=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __func__, gpio, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (level < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) pr_err("%s:get pin level err!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static irqreturn_t headset_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) DBG("---headset_interrupt---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) schedule_delayed_work(&headset_info->h_delayed_work[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) msecs_to_jiffies(50));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static irqreturn_t hook_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) DBG("---Hook_interrupt---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* disable_irq_nosync(headset_info->irq[HOOK]); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) schedule_delayed_work(&headset_info->h_delayed_work[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void headsetobserve_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int level2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct rk_headset_pdata *pdata = headset_info->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static unsigned int old_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) printk("---headsetobserve_work---\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_lock(&headset_info->mutex_lock[HEADSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) level = read_gpio(pdata->headset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (level < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) level2 = read_gpio(pdata->headset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (level2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (level2 != level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) old_status = headset_info->headset_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (pdata->headset_insert_type == HEADSET_IN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) headset_info->headset_status = level ? HEADSET_IN : HEADSET_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) headset_info->headset_status = level ? HEADSET_OUT : HEADSET_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (old_status == headset_info->headset_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pr_warn("old_status == headset_info->headset_status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) DBG("(headset in is %s)headset status is %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) pdata->headset_insert_type ? "high level" : "low level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) headset_info->headset_status ? "in" : "out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (headset_info->headset_status == HEADSET_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (pdata->headset_insert_type == HEADSET_IN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) irq_set_irq_type(headset_info->irq[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) IRQF_TRIGGER_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) irq_set_irq_type(headset_info->irq[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) IRQF_TRIGGER_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (pdata->hook_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Start the timer, wait for switch to the headphone channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) del_timer(&headset_info->headset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) headset_info->headset_timer.expires = jiffies + 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) add_timer(&headset_info->headset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } else if (headset_info->headset_status == HEADSET_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) headset_info->hook_status = HOOK_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (headset_info->isHook_irq == enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) DBG("disable headset_hook irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) headset_info->isHook_irq = disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) disable_irq(headset_info->irq[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) headset_info->cur_headset_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (pdata->headset_insert_type == HEADSET_IN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) irq_set_irq_type(headset_info->irq[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) IRQF_TRIGGER_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) irq_set_irq_type(headset_info->irq[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) IRQF_TRIGGER_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (headset_info->cur_headset_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) extcon_set_state_sync(headset_info->edev, EXTCON_JACK_HEADPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) extcon_set_state_sync(headset_info->edev, EXTCON_JACK_HEADPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) DBG("headset_info->cur_headset_status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) headset_info->cur_headset_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mutex_unlock(&headset_info->mutex_lock[HEADSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void hook_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct rk_headset_pdata *pdata = headset_info->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static unsigned int old_status = HOOK_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) mutex_lock(&headset_info->mutex_lock[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (headset_info->headset_status == HEADSET_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) DBG("Headset is out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) goto RE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) level = read_gpio(pdata->hook_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (level < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto RE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) old_status = headset_info->hook_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) DBG("Hook_work -- level = %d\n", level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) headset_info->hook_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) pdata->hook_down_type == HOOK_DOWN_HIGH ? HOOK_UP :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) HOOK_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) else if (level > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) headset_info->hook_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) pdata->hook_down_type == HOOK_DOWN_HIGH ? HOOK_DOWN :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) HOOK_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (old_status == headset_info->hook_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) DBG("old_status == headset_info->hook_status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto RE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) DBG("Hook_work -- level = %d hook status is %s\n", level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) headset_info->hook_status ? "key down" : "key up");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (headset_info->hook_status == HOOK_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (pdata->hook_down_type == HOOK_DOWN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) IRQF_TRIGGER_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) IRQF_TRIGGER_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (pdata->hook_down_type == HOOK_DOWN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) IRQF_TRIGGER_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) IRQF_TRIGGER_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) input_report_key(headset_info->input_dev, HOOK_KEY_CODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) headset_info->hook_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) input_sync(headset_info->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) RE_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_unlock(&headset_info->mutex_lock[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void headset_timer_callback(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct headset_priv *headset = from_timer(headset, t, headset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct rk_headset_pdata *pdata = headset->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pr_info("headset_timer_callback, headset->headset_status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) headset->headset_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (headset->headset_status == HEADSET_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pr_info("Headset is out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) level = read_gpio(pdata->hook_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (level < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if ((level > 0 && pdata->hook_down_type == HOOK_DOWN_LOW) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (level == 0 && pdata->hook_down_type == HOOK_DOWN_HIGH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) headset->isMic = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) enable_irq(headset_info->irq[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) headset->isHook_irq = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) headset_info->hook_status = HOOK_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (pdata->hook_down_type == HOOK_DOWN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) IRQF_TRIGGER_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) irq_set_irq_type(headset_info->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) IRQF_TRIGGER_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) headset->isMic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) pr_info("headset->isMic = %d\n", headset->isMic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) headset_info->cur_headset_status = headset_info->isMic ? 1 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (headset->isMic == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) extcon_set_state_sync(headset_info->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) EXTCON_JACK_MICROPHONE, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) extcon_set_state_sync(headset_info->edev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) EXTCON_JACK_MICROPHONE, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) DBG("headset_info->cur_headset_status = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) headset_info->cur_headset_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #ifdef CONFIG_HAS_EARLYSUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static void headset_early_resume(struct early_suspend *h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) schedule_delayed_work(&headset_info->h_delayed_work[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) //DBG(">>>>>headset_early_resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static struct early_suspend hs_early_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int rk_hskey_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) //struct rk28_adckey *adckey = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) //DBG("===========rk_Hskey_open===========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void rk_hskey_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) //DBG("===========rk_Hskey_close===========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) //struct rk28_adckey *adckey = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static const unsigned int headset_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) EXTCON_JACK_MICROPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) EXTCON_JACK_HEADPHONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int rk_headset_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct rk_headset_pdata *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct headset_priv *headset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) headset = devm_kzalloc(&pdev->dev, sizeof(*headset), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!headset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(&pdev->dev, "failed to allocate driver data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) headset_info = headset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) headset->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) headset->headset_status = HEADSET_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) headset->hook_status = HOOK_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) headset->isHook_irq = disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) headset->cur_headset_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) headset->edev = devm_extcon_dev_allocate(&pdev->dev, headset_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (IS_ERR(headset->edev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dev_err(&pdev->dev, "failed to allocate extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ret = devm_extcon_dev_register(&pdev->dev, headset->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dev_err(&pdev->dev, "extcon_dev_register() failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mutex_init(&headset->mutex_lock[HEADSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mutex_init(&headset->mutex_lock[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) headsetobserve_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], hook_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) headset->isMic = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) timer_setup(&headset->headset_timer, headset_timer_callback, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Create and register the input driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) headset->input_dev = devm_input_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!headset->input_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_err(&pdev->dev, "failed to allocate input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) headset->input_dev->name = pdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) headset->input_dev->open = rk_hskey_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) headset->input_dev->close = rk_hskey_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) headset->input_dev->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* input_dev->phys = KEY_PHYS_NAME; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) headset->input_dev->id.vendor = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) headset->input_dev->id.product = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) headset->input_dev->id.version = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Register the input device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret = input_register_device(headset->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_err(&pdev->dev, "failed to register input device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) input_set_capability(headset->input_dev, EV_KEY, HOOK_KEY_CODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #ifdef CONFIG_HAS_EARLYSUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) hs_early_suspend.suspend = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) hs_early_suspend.resume = headset_early_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) hs_early_suspend.level = ~0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) register_early_suspend(&hs_early_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (pdata->headset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (pdata->headset_insert_type == HEADSET_IN_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) headset->irq_type[HEADSET] = IRQF_TRIGGER_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) headset->irq_type[HEADSET] = IRQF_TRIGGER_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = devm_request_irq(&pdev->dev, headset->irq[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) headset_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) headset->irq_type[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "headset_input", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (pdata->headset_wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) enable_irq_wake(headset->irq[HEADSET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev_err(&pdev->dev, "failed init headset, please full headset_gpio function in board\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (pdata->hook_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) headset->irq[HOOK] = gpio_to_irq(pdata->hook_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) headset->irq_type[HOOK] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) pdata->hook_down_type == HOOK_DOWN_HIGH ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) IRQF_TRIGGER_RISING :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) IRQF_TRIGGER_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ret = devm_request_irq(&pdev->dev, headset->irq[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) hook_interrupt, headset->irq_type[HOOK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) "headset_hook", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) disable_irq(headset->irq[HOOK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) schedule_delayed_work(&headset->h_delayed_work[HEADSET],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) msecs_to_jiffies(500));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dev_err(&pdev->dev, "failed to headset probe ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(rk_headset_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) MODULE_LICENSE("GPL");