mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
kernel 3.10 headset : headset driver support
This commit is contained in:
2
drivers/Kconfig
Normal file → Executable file
2
drivers/Kconfig
Normal file → Executable file
@@ -170,4 +170,6 @@ source "drivers/reset/Kconfig"
|
||||
|
||||
source "drivers/gator/Kconfig"
|
||||
|
||||
source "drivers/headset_observe/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
1
drivers/Makefile
Normal file → Executable file
1
drivers/Makefile
Normal file → Executable file
@@ -155,3 +155,4 @@ obj-$(CONFIG_IPACK_BUS) += ipack/
|
||||
obj-$(CONFIG_NTB) += ntb/
|
||||
|
||||
obj-$(CONFIG_GATOR) += gator/
|
||||
obj-y += headset_observe/
|
||||
@@ -4,15 +4,12 @@
|
||||
|
||||
menu "Headset device support"
|
||||
|
||||
config RK_HEADSET_DET
|
||||
tristate "RK headset detect support"
|
||||
config RK_HEADSET
|
||||
tristate "Rockchips HeadSet support"
|
||||
---help---
|
||||
Universal headphone driver(write begin rk29)
|
||||
|
||||
config RK_HEADSET_IRQ_HOOK_ADC_DET
|
||||
tristate "RK headset irq hook adc detect support"
|
||||
---help---
|
||||
if you use headset irq and hook adc detect, choose it
|
||||
Rockchips HeadSet support:
|
||||
support hook interrupt mode.
|
||||
support hook adc mode.
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
obj-$(CONFIG_RK_HEADSET_DET) += rk_headset.o
|
||||
obj-$(CONFIG_RK_HEADSET_IRQ_HOOK_ADC_DET) += rk_headset_irq_hook_adc.o
|
||||
obj-$(CONFIG_RK_HEADSET) += rockchip_headset_core.o rk_headset.o rk_headset_irq_hook_adc.o
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -35,11 +34,13 @@
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include "rk_headset.h"
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/slab.h>
|
||||
#endif
|
||||
|
||||
/* Debug */
|
||||
#if 0
|
||||
@@ -94,33 +95,18 @@ static struct headset_priv *headset_info;
|
||||
void Modem_Mic_switch(int value)
|
||||
{
|
||||
if(value == HP_MIC)
|
||||
gpio_set_value(headset_info->pdata->Sw_mic_gpio, headset_info->pdata->Hp_mic_io_value);
|
||||
gpio_set_value(headset_info->pdata->mic_switch_gpio, headset_info->pdata->hp_mic_io_value);
|
||||
else if(value == MAIN_MIC)
|
||||
gpio_set_value(headset_info->pdata->Sw_mic_gpio,headset_info->pdata->Main_mic_io_value);
|
||||
gpio_set_value(headset_info->pdata->mic_switch_gpio,headset_info->pdata->main_mic_io_value);
|
||||
}
|
||||
void Modem_Mic_release(void)
|
||||
{
|
||||
if(headset_info->cur_headset_status == 1)
|
||||
gpio_set_value(headset_info->pdata->Sw_mic_gpio, headset_info->pdata->Hp_mic_io_value);
|
||||
gpio_set_value(headset_info->pdata->mic_switch_gpio, headset_info->pdata->hp_mic_io_value);
|
||||
else
|
||||
gpio_set_value(headset_info->pdata->Sw_mic_gpio,headset_info->pdata->Main_mic_io_value);
|
||||
gpio_set_value(headset_info->pdata->mic_switch_gpio,headset_info->pdata->main_mic_io_value);
|
||||
}
|
||||
#endif
|
||||
int Headset_isMic(void)
|
||||
{
|
||||
return headset_info->isMic;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(Headset_isMic);
|
||||
|
||||
int Headset_status(void)
|
||||
{
|
||||
if(headset_info->cur_headset_status == BIT_HEADSET_NO_MIC ||
|
||||
headset_info->cur_headset_status == BIT_HEADSET )
|
||||
return HEADSET_IN;
|
||||
else
|
||||
return HEADSET_OUT;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(Headset_status);
|
||||
|
||||
static int read_gpio(int gpio)
|
||||
{
|
||||
@@ -150,7 +136,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t Hook_interrupt(int irq, void *dev_id)
|
||||
static irqreturn_t hook_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
DBG("---Hook_interrupt---\n");
|
||||
// disable_irq_nosync(headset_info->irq[HOOK]);
|
||||
@@ -167,17 +153,17 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
DBG("---headsetobserve_work---\n");
|
||||
mutex_lock(&headset_info->mutex_lock[HEADSET]);
|
||||
|
||||
level = read_gpio(pdata->Headset_gpio);
|
||||
level = read_gpio(pdata->headset_gpio);
|
||||
if(level < 0)
|
||||
goto out;
|
||||
msleep(100);
|
||||
level2 = read_gpio(pdata->Headset_gpio);
|
||||
level2 = read_gpio(pdata->headset_gpio);
|
||||
if(level2 < 0)
|
||||
goto out;
|
||||
if(level2 != level)
|
||||
goto out;
|
||||
old_status = headset_info->headset_status;
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
headset_info->headset_status = level?HEADSET_IN:HEADSET_OUT;
|
||||
else
|
||||
headset_info->headset_status = level?HEADSET_OUT:HEADSET_IN;
|
||||
@@ -188,17 +174,17 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
DBG("(headset in is %s)headset status is %s\n",
|
||||
pdata->headset_in_type?"high level":"low level",
|
||||
pdata->headset_insert_type?"high level":"low level",
|
||||
headset_info->headset_status?"in":"out");
|
||||
|
||||
if(headset_info->headset_status == HEADSET_IN)
|
||||
{
|
||||
headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
|
||||
if (pdata->Hook_gpio) {
|
||||
if (pdata->hook_gpio) {
|
||||
del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
|
||||
headset_info->headset_timer.expires = jiffies + 100;
|
||||
add_timer(&headset_info->headset_timer);
|
||||
@@ -218,12 +204,12 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
//#if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SOC_RK3028)
|
||||
//rk2928_codec_set_spk(HEADSET_OUT);
|
||||
//#endif
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
|
||||
}
|
||||
rk28_send_wakeup_key();
|
||||
// rk28_send_wakeup_key();
|
||||
switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
|
||||
#if defined(CONFIG_SND_RK_SOC_RK2928) || defined(CONFIG_SND_RK29_SOC_RK610)
|
||||
if (headset_info->headset_status == HEADSET_OUT)
|
||||
@@ -239,7 +225,7 @@ out:
|
||||
mutex_unlock(&headset_info->mutex_lock[HEADSET]);
|
||||
}
|
||||
|
||||
static void Hook_work(struct work_struct *work)
|
||||
static void hook_work(struct work_struct *work)
|
||||
{
|
||||
int level = 0;
|
||||
struct rk_headset_pdata *pdata = headset_info->pdata;
|
||||
@@ -259,7 +245,7 @@ static void Hook_work(struct work_struct *work)
|
||||
}
|
||||
#endif
|
||||
|
||||
level = read_gpio(pdata->Hook_gpio);
|
||||
level = read_gpio(pdata->hook_gpio);
|
||||
if(level < 0)
|
||||
goto RE_ERROR;
|
||||
|
||||
@@ -267,9 +253,9 @@ static void Hook_work(struct work_struct *work)
|
||||
DBG("Hook_work -- level = %d\n",level);
|
||||
|
||||
if(level == 0)
|
||||
headset_info->hook_status = pdata->Hook_down_type == HOOK_DOWN_HIGH?HOOK_UP:HOOK_DOWN;
|
||||
headset_info->hook_status = pdata->hook_down_type == HOOK_DOWN_HIGH?HOOK_UP:HOOK_DOWN;
|
||||
else if(level > 0)
|
||||
headset_info->hook_status = pdata->Hook_down_type == HOOK_DOWN_HIGH?HOOK_DOWN:HOOK_UP;
|
||||
headset_info->hook_status = pdata->hook_down_type == HOOK_DOWN_HIGH?HOOK_DOWN:HOOK_UP;
|
||||
|
||||
if(old_status == headset_info->hook_status)
|
||||
{
|
||||
@@ -279,19 +265,19 @@ static void Hook_work(struct work_struct *work)
|
||||
DBG("Hook_work -- level = %d hook status is %s\n",level,headset_info->hook_status?"key down":"key up");
|
||||
if(headset_info->hook_status == HOOK_DOWN)
|
||||
{
|
||||
if(pdata->Hook_down_type == HOOK_DOWN_HIGH)
|
||||
if(pdata->hook_down_type == HOOK_DOWN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pdata->Hook_down_type == HOOK_DOWN_HIGH)
|
||||
if(pdata->hook_down_type == HOOK_DOWN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING);
|
||||
}
|
||||
input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status);
|
||||
input_report_key(headset_info->input_dev,HOOK_KEY_CODE,headset_info->hook_status);
|
||||
input_sync(headset_info->input_dev);
|
||||
RE_ERROR:
|
||||
mutex_unlock(&headset_info->mutex_lock[HOOK]);
|
||||
@@ -320,21 +306,21 @@ static void headset_timer_callback(unsigned long arg)
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
level = read_gpio(pdata->Hook_gpio);
|
||||
level = read_gpio(pdata->hook_gpio);
|
||||
if(level < 0)
|
||||
goto out;
|
||||
if((level > 0 && pdata->Hook_down_type == HOOK_DOWN_LOW)
|
||||
|| (level == 0 && pdata->Hook_down_type == HOOK_DOWN_HIGH))
|
||||
if((level > 0 && pdata->hook_down_type == HOOK_DOWN_LOW)
|
||||
|| (level == 0 && pdata->hook_down_type == HOOK_DOWN_HIGH))
|
||||
{
|
||||
headset->isMic = 1;//have mic
|
||||
DBG("enable headset_hook irq\n");
|
||||
enable_irq(headset_info->irq[HOOK]);
|
||||
headset->isHook_irq = enable;
|
||||
headset_info->hook_status = HOOK_UP;
|
||||
if(pdata->Hook_down_type == HOOK_DOWN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING);
|
||||
if(pdata->hook_down_type == HOOK_DOWN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_RISING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HOOK],IRQF_TRIGGER_FALLING);
|
||||
|
||||
}
|
||||
else
|
||||
@@ -347,7 +333,7 @@ static void headset_timer_callback(unsigned long arg)
|
||||
if(headset_info->cur_headset_status == 1)
|
||||
gpio_set_value(pdata->Sw_mic_gpio, pdata->Hp_mic_io_value);
|
||||
#endif
|
||||
rk28_send_wakeup_key();
|
||||
// rk28_send_wakeup_key();
|
||||
switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
|
||||
|
||||
DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);
|
||||
@@ -371,33 +357,32 @@ static void headset_early_resume(struct early_suspend *h)
|
||||
static struct early_suspend hs_early_suspend;
|
||||
#endif
|
||||
|
||||
static int rk_Hskey_open(struct input_dev *dev)
|
||||
static int rk_hskey_open(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
// DBG("===========rk_Hskey_open===========\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk_Hskey_close(struct input_dev *dev)
|
||||
static void rk_hskey_close(struct input_dev *dev)
|
||||
{
|
||||
// DBG("===========rk_Hskey_close===========\n");
|
||||
// struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
int rk_headset_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
struct headset_priv *headset;
|
||||
struct rk_headset_pdata *pdata;
|
||||
|
||||
headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL);
|
||||
if (headset == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
headset->pdata = pdev->dev.platform_data;
|
||||
pdata = headset->pdata;
|
||||
}
|
||||
|
||||
headset->pdata = pdata;
|
||||
headset->headset_status = HEADSET_OUT;
|
||||
headset->hook_status = HOOK_UP;
|
||||
headset->isHook_irq = disable;
|
||||
@@ -412,7 +397,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
mutex_init(&headset->mutex_lock[HOOK]);
|
||||
|
||||
INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET], headsetobserve_work);
|
||||
INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], Hook_work);
|
||||
INIT_DELAYED_WORK(&headset->h_delayed_work[HOOK], hook_work);
|
||||
|
||||
headset->isMic = 0;
|
||||
setup_timer(&headset->headset_timer, headset_timer_callback, (unsigned long)headset);
|
||||
@@ -425,8 +410,8 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
goto failed_free;
|
||||
}
|
||||
headset->input_dev->name = pdev->name;
|
||||
headset->input_dev->open = rk_Hskey_open;
|
||||
headset->input_dev->close = rk_Hskey_close;
|
||||
headset->input_dev->open = rk_hskey_open;
|
||||
headset->input_dev->close = rk_hskey_close;
|
||||
headset->input_dev->dev.parent = &pdev->dev;
|
||||
//input_dev->phys = KEY_PHYS_NAME;
|
||||
headset->input_dev->id.vendor = 0x0001;
|
||||
@@ -438,7 +423,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev, "failed to register input device\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code);
|
||||
input_set_capability(headset->input_dev, EV_KEY,HOOK_KEY_CODE);
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
hs_early_suspend.suspend = NULL;
|
||||
@@ -447,18 +432,15 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
register_early_suspend(&hs_early_suspend);
|
||||
#endif
|
||||
//------------------------------------------------------------------
|
||||
if (pdata->Headset_gpio) {
|
||||
if(pdata->Headset_gpio == NULL){
|
||||
if (pdata->headset_gpio) {
|
||||
if(!pdata->headset_gpio){
|
||||
dev_err(&pdev->dev,"failed init headset,please full hook_io_init function in board\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
ret = pdata->headset_io_init(pdata->Headset_gpio);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_RISING;
|
||||
else
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_FALLING;
|
||||
@@ -470,18 +452,11 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
else
|
||||
goto failed_free_dev;
|
||||
//------------------------------------------------------------------
|
||||
if (pdata->Hook_gpio) {
|
||||
if(pdata->hook_io_init == NULL){
|
||||
dev_err(&pdev->dev,"failed init hook,please full hook_io_init function in board\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
ret = pdata->hook_io_init(pdata->Hook_gpio);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
headset->irq[HOOK] = gpio_to_irq(pdata->Hook_gpio);
|
||||
headset->irq_type[HOOK] = pdata->Hook_down_type == HOOK_DOWN_HIGH ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
|
||||
if (pdata->hook_gpio) {
|
||||
headset->irq[HOOK] = gpio_to_irq(pdata->hook_gpio);
|
||||
headset->irq_type[HOOK] = pdata->hook_down_type == HOOK_DOWN_HIGH ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
|
||||
|
||||
ret = request_irq(headset->irq[HOOK], Hook_interrupt, headset->irq_type[HOOK] , "headset_hook", NULL);
|
||||
ret = request_irq(headset->irq[HOOK], hook_interrupt, headset->irq_type[HOOK] , "headset_hook", NULL);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
disable_irq(headset->irq[HOOK]);
|
||||
@@ -500,39 +475,5 @@ failed_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
disable_irq(headset_info->irq[HEADSET]);
|
||||
disable_irq(headset_info->irq[HOOK]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_resume(struct platform_device *pdev)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
enable_irq(headset_info->irq[HEADSET]);
|
||||
enable_irq(headset_info->irq[HOOK]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rockchip_headsetobserve_driver = {
|
||||
.probe = rockchip_headsetobserve_probe,
|
||||
// .resume = rockchip_headsetobserve_resume,
|
||||
// .suspend = rockchip_headsetobserve_suspend,
|
||||
.driver = {
|
||||
.name = "rk_headsetdet",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rockchip_headsetobserve_init(void)
|
||||
{
|
||||
platform_driver_register(&rockchip_headsetobserve_driver);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(rockchip_headsetobserve_init);
|
||||
MODULE_DESCRIPTION("Rockchip Headset Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -7,24 +7,26 @@
|
||||
#define HOOK_DOWN_HIGH 0x00000001
|
||||
#define HOOK_DOWN_LOW 0x00000000
|
||||
|
||||
struct io_info{
|
||||
char iomux_name[50];
|
||||
int iomux_mode;
|
||||
};
|
||||
|
||||
|
||||
struct rk_headset_pdata{
|
||||
unsigned int Hook_gpio;//Detection Headset--Must be set
|
||||
unsigned int Sw_mic_gpio;
|
||||
unsigned int Hp_mic_io_value;
|
||||
unsigned int Main_mic_io_value;
|
||||
unsigned int Hook_adc_chn; //adc channel
|
||||
unsigned int Hook_down_type; //Hook key down status
|
||||
int hook_key_code;
|
||||
unsigned int Headset_gpio;//Detection Headset--Must be set
|
||||
unsigned int headset_in_type;// Headphones into the state level--Must be set
|
||||
int (*headset_io_init)(int);
|
||||
int (*hook_io_init)(int);
|
||||
//heaset about
|
||||
unsigned int headset_gpio;
|
||||
unsigned int headset_insert_type;// Headphones into the state level
|
||||
//hook about
|
||||
int hook_adc_chn; //adc channel
|
||||
unsigned int hook_gpio;
|
||||
unsigned int hook_down_type; //Hook key down status
|
||||
#ifdef CONFIG_MODEM_MIC_SWITCH
|
||||
//mic about
|
||||
unsigned int mic_switch_gpio;
|
||||
unsigned int hp_mic_io_value;
|
||||
unsigned int main_mic_io_value;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define HOOK_KEY_CODE KEY_MEDIA
|
||||
|
||||
extern int rk_headset_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata);
|
||||
extern int rk_headset_adc_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata);
|
||||
extern int rk_headset_adc_suspend(struct platform_device *pdev, pm_message_t state);
|
||||
extern int rk_headset_adc_resume(struct platform_device *pdev);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* arch/arm/mach-rockchip/rk28_headset.c
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2009 Rockchip Corporation.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
@@ -14,7 +13,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysdev.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -35,13 +33,16 @@
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include "rk_headset.h"
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/slab.h>
|
||||
#endif
|
||||
#include <linux/adc.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include "rk_headset.h"
|
||||
|
||||
/* Debug */
|
||||
#if 1
|
||||
@@ -109,12 +110,6 @@ struct headset_priv {
|
||||
};
|
||||
static struct headset_priv *headset_info;
|
||||
|
||||
int Headset_isMic(void)
|
||||
{
|
||||
return headset_info->isMic;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(Headset_isMic);
|
||||
|
||||
//1
|
||||
static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
@@ -130,10 +125,10 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
msleep(150);
|
||||
for(i=0; i<3; i++)
|
||||
{
|
||||
level = gpio_get_value(pdata->Headset_gpio);
|
||||
level = gpio_get_value(pdata->headset_gpio);
|
||||
if(level < 0)
|
||||
{
|
||||
printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->Headset_gpio,i);
|
||||
printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->headset_gpio,i);
|
||||
msleep(1);
|
||||
continue;
|
||||
}
|
||||
@@ -147,7 +142,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
old_status = headset_info->headset_status;
|
||||
switch(pdata->headset_in_type)
|
||||
switch(pdata->headset_insert_type)
|
||||
{
|
||||
case HEADSET_IN_HIGH:
|
||||
if(level > 0)
|
||||
@@ -162,7 +157,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
headset_info->headset_status = HEADSET_OUT;
|
||||
break;
|
||||
default:
|
||||
DBG("---- ERROR: on headset headset_in_type error -----\n");
|
||||
DBG("---- ERROR: on headset headset_insert_type error -----\n");
|
||||
break;
|
||||
}
|
||||
if(old_status == headset_info->headset_status)
|
||||
@@ -172,7 +167,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
DBG("(headset in is %s)headset status is %s\n",
|
||||
pdata->headset_in_type?"high level":"low level",
|
||||
pdata->headset_insert_type?"high level":"low level",
|
||||
headset_info->headset_status?"in":"out");
|
||||
if(headset_info->headset_status == HEADSET_IN)
|
||||
{
|
||||
@@ -188,16 +183,16 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
break;
|
||||
msleep(50);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_IN:HEADSET_OUT;
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
old_status = headset_info->headset_status = gpio_get_value(pdata->headset_gpio)?HEADSET_IN:HEADSET_OUT;
|
||||
else
|
||||
old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_OUT:HEADSET_IN;
|
||||
old_status = headset_info->headset_status = gpio_get_value(pdata->headset_gpio)?HEADSET_OUT:HEADSET_IN;
|
||||
if(headset_info->headset_status == HEADSET_OUT)
|
||||
goto out1;
|
||||
msleep(5);
|
||||
}
|
||||
#endif
|
||||
if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
|
||||
if(pdata->hook_adc_chn>=0 && 3>=pdata->hook_adc_chn)
|
||||
{
|
||||
// wait for find Hook key
|
||||
//#ifdef CONFIG_SND_SOC_RT5625
|
||||
@@ -234,7 +229,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
printk("codec is error\n");
|
||||
headset_info->heatset_irq_working = WAIT;
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_LOW|IRQF_ONESHOT);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_HIGH|IRQF_ONESHOT);
|
||||
@@ -258,7 +253,7 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
|
||||
}
|
||||
printk("headset->isMic = %d\n",headset_info->isMic);
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
|
||||
@@ -281,13 +276,13 @@ static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
rt5631_headset_mic_detect(false);
|
||||
#endif
|
||||
}
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
|
||||
}
|
||||
|
||||
rk28_send_wakeup_key();
|
||||
// rk28_send_wakeup_key();
|
||||
switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
|
||||
DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status);
|
||||
|
||||
@@ -332,7 +327,7 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
|
||||
free_irq(headset_info->irq[HEADSET],NULL);
|
||||
msleep(100);
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
headset_info->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT;
|
||||
else
|
||||
headset_info->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT;
|
||||
@@ -341,14 +336,14 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_IN)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_IN)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);
|
||||
else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_IN)
|
||||
else if(pdata->headset_insert_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_IN)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_OUT)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_OUT)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);
|
||||
else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_OUT)
|
||||
else if(pdata->headset_insert_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_OUT)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);
|
||||
*/
|
||||
}
|
||||
@@ -371,7 +366,7 @@ static void hook_adc_callback(struct adc_client *client, void *client_param, int
|
||||
if(headset->headset_status == HEADSET_OUT
|
||||
|| headset->heatset_irq_working == BUSY
|
||||
|| headset->heatset_irq_working == WAIT
|
||||
|| pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0)
|
||||
|| pdata->headset_insert_type?gpio_get_value(pdata->headset_gpio) == 0:gpio_get_value(pdata->headset_gpio) > 0)
|
||||
{
|
||||
DBG("Headset is out or waiting for headset is in or out,after same time check HOOK key\n");
|
||||
return;
|
||||
@@ -399,11 +394,11 @@ static void hook_adc_callback(struct adc_client *client, void *client_param, int
|
||||
if(headset->headset_status == HEADSET_OUT
|
||||
|| headset->heatset_irq_working == BUSY
|
||||
|| headset->heatset_irq_working == WAIT
|
||||
|| (pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0))
|
||||
|| (pdata->headset_insert_type?gpio_get_value(pdata->headset_gpio) == 0:gpio_get_value(pdata->headset_gpio) > 0))
|
||||
DBG("headset is out,HOOK status must discard\n");
|
||||
else
|
||||
{
|
||||
input_report_key(headset->input_dev,pdata->hook_key_code,headset->hook_status);
|
||||
input_report_key(headset->input_dev,HOOK_KEY_CODE,headset->hook_status);
|
||||
input_sync(headset->input_dev);
|
||||
}
|
||||
}
|
||||
@@ -435,25 +430,24 @@ static void headset_early_resume(struct early_suspend *h)
|
||||
static struct early_suspend hs_early_suspend;
|
||||
#endif
|
||||
|
||||
static int rk_Hskey_open(struct input_dev *dev)
|
||||
static int rk_hskey_open(struct input_dev *dev)
|
||||
{
|
||||
//struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
// DBG("===========rk_Hskey_open===========\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk_Hskey_close(struct input_dev *dev)
|
||||
static void rk_hskey_close(struct input_dev *dev)
|
||||
{
|
||||
// DBG("===========rk_Hskey_close===========\n");
|
||||
// struct rk28_adckey *adckey = input_get_drvdata(dev);
|
||||
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
int rk_headset_adc_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
struct headset_priv *headset;
|
||||
struct rk_headset_pdata *pdata;
|
||||
|
||||
headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL);
|
||||
if (headset == NULL) {
|
||||
@@ -461,8 +455,7 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
headset_info = headset;
|
||||
headset->pdata = pdev->dev.platform_data;
|
||||
pdata = headset->pdata;
|
||||
headset->pdata = pdata;
|
||||
headset->headset_status = HEADSET_OUT;
|
||||
headset->heatset_irq_working = IDLE;
|
||||
headset->hook_status = HOOK_UP;
|
||||
@@ -489,8 +482,8 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
goto failed_free;
|
||||
}
|
||||
headset->input_dev->name = pdev->name;
|
||||
headset->input_dev->open = rk_Hskey_open;
|
||||
headset->input_dev->close = rk_Hskey_close;
|
||||
headset->input_dev->open = rk_hskey_open;
|
||||
headset->input_dev->close = rk_hskey_close;
|
||||
headset->input_dev->dev.parent = &pdev->dev;
|
||||
//input_dev->phys = KEY_PHYS_NAME;
|
||||
headset->input_dev->id.vendor = 0x0001;
|
||||
@@ -503,20 +496,17 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code);
|
||||
input_set_capability(headset->input_dev, EV_KEY, HOOK_KEY_CODE);
|
||||
//------------------------------------------------------------------
|
||||
if (pdata->Headset_gpio) {
|
||||
if(pdata->Headset_gpio == NULL){
|
||||
if (pdata->headset_gpio) {
|
||||
if(!pdata->headset_gpio){
|
||||
dev_err(&pdev->dev,"failed init headset,please full hook_io_init function in board\n");
|
||||
goto failed_free_dev;
|
||||
}
|
||||
ret = pdata->headset_io_init(pdata->Headset_gpio);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->headset_gpio);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
if(pdata->headset_insert_type == HEADSET_IN_HIGH)
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT;
|
||||
else
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT;
|
||||
@@ -528,9 +518,9 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
else
|
||||
goto failed_free_dev;
|
||||
//------------------------------------------------------------------
|
||||
if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
|
||||
if(pdata->hook_adc_chn>=0 && 3>=pdata->hook_adc_chn)
|
||||
{
|
||||
headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset);
|
||||
headset->client = adc_register(pdata->hook_adc_chn, hook_adc_callback, (void *)headset);
|
||||
if(!headset->client) {
|
||||
printk("hook adc register error\n");
|
||||
ret = -EINVAL;
|
||||
@@ -558,7 +548,7 @@ failed_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
int rk_headset_adc_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
// disable_irq(headset_info->irq[HEADSET]);
|
||||
@@ -566,7 +556,7 @@ static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_mess
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_headsetobserve_resume(struct platform_device *pdev)
|
||||
int rk_headset_adc_resume(struct platform_device *pdev)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
// enable_irq(headset_info->irq[HEADSET]);
|
||||
@@ -575,22 +565,4 @@ static int rockchip_headsetobserve_resume(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rockchip_headsetobserve_driver = {
|
||||
.probe = rockchip_headsetobserve_probe,
|
||||
.resume = rockchip_headsetobserve_resume,
|
||||
.suspend = rockchip_headsetobserve_suspend,
|
||||
.driver = {
|
||||
.name = "rk_headsetdet",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rockchip_headsetobserve_init(void)
|
||||
{
|
||||
platform_driver_register(&rockchip_headsetobserve_driver);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(rockchip_headsetobserve_init);
|
||||
MODULE_DESCRIPTION("Rockchip Headset Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
222
drivers/headset_observe/rockchip_headset_core.c
Executable file
222
drivers/headset_observe/rockchip_headset_core.c
Executable file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Rockchip Corporation.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include "rk_headset.h"
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
/* Debug */
|
||||
#if 0
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
rockchip_headset {
|
||||
compatible = "rockchip_headset";
|
||||
headset_gpio = ;
|
||||
headset_insert_type = ; // 0 = low 1 = high
|
||||
hook_gpio = ;
|
||||
hook_down_type = ; //interrupt hook key down status
|
||||
hook_adc_chn = ;//adc channel
|
||||
mic_switch_gpio = ;
|
||||
hp_mic_io_value = ;
|
||||
main_mic_io_value = ;
|
||||
hook_key_code = KEY_MEDIA;
|
||||
};
|
||||
*/
|
||||
struct rk_headset_pdata *pdata_info;
|
||||
|
||||
static int rockchip_headset_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct rk_headset_pdata *pdata;
|
||||
int ret;
|
||||
enum of_gpio_flags flags;
|
||||
|
||||
pdata = kzalloc(sizeof(struct rk_headset_pdata), GFP_KERNEL);
|
||||
if (pdata == NULL) {
|
||||
printk("%s failed to allocate driver data\n",__FUNCTION__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(pdata,0,sizeof(struct rk_headset_pdata));
|
||||
pdata_info = pdata;
|
||||
//headset
|
||||
ret = of_get_named_gpio_flags(node, "headset_gpio", 0, &flags);
|
||||
if (ret < 0) {
|
||||
printk("%s() Can not read property headset_gpio\n", __FUNCTION__);
|
||||
goto err;
|
||||
} else {
|
||||
pdata->headset_gpio = ret;
|
||||
ret = devm_gpio_request(&pdev->dev, pdata->headset_gpio, "headset_gpio");
|
||||
if(ret < 0){
|
||||
printk("%s() devm_gpio_request headset_gpio request ERROR\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
//gpio_pull_updown(pdata->headset_gpio, PullDisable);
|
||||
ret = gpio_direction_input(pdata->headset_gpio);
|
||||
if(ret < 0){
|
||||
printk("%s() gpio_direction_input headset_gpio set ERROR\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "headset_insert_type", &pdata->headset_insert_type);
|
||||
if (ret < 0) {
|
||||
DBG("%s() have not set headset_insert_type,set >headset< insert type low level default\n", __FUNCTION__);
|
||||
pdata->headset_insert_type = 0;
|
||||
}
|
||||
//hook
|
||||
ret = of_get_named_gpio_flags(node, "hook_gpio", 0, &pdata->hook_gpio);
|
||||
if (ret < 0) {
|
||||
DBG("%s() Can not read property hook_gpio\n", __FUNCTION__);
|
||||
pdata->hook_gpio = 0;
|
||||
//adc mode
|
||||
ret = of_property_read_u32(node, "hook_adc_chn", &pdata->hook_adc_chn);
|
||||
if (ret < 0) {
|
||||
DBG("%s() have not set hook_adc_chn\n", __FUNCTION__);
|
||||
pdata->hook_adc_chn = -1;
|
||||
}
|
||||
} else {
|
||||
ret = of_property_read_u32(node, "hook_down_type", &pdata->hook_down_type);
|
||||
if (ret < 0) {
|
||||
DBG("%s() have not set hook_down_type,set >hook< insert type low level default\n", __FUNCTION__);
|
||||
pdata->hook_down_type = 0;
|
||||
}
|
||||
ret = devm_gpio_request(&pdev->dev, pdata->hook_gpio, "hook_gpio");
|
||||
if(ret < 0){
|
||||
printk("%s() devm_gpio_request hook_gpio request ERROR\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
//gpio_pull_updown(pdata->hook_gpio, PullDisable);
|
||||
ret = gpio_direction_input(pdata->hook_gpio);
|
||||
if(ret < 0){
|
||||
printk("%s() gpio_direction_input hook_gpio set ERROR\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_MODEM_MIC_SWITCH
|
||||
//mic
|
||||
ret = of_get_named_gpio_flags(node, "mic_switch_gpio", 0, &flags);
|
||||
if (ret < 0) {
|
||||
DBG("%s() Can not read property mic_switch_gpio\n", __FUNCTION__);
|
||||
} else {
|
||||
pdata->headset_gpio = ret;
|
||||
ret = of_property_read_u32(node, "hp_mic_io_value", &pdata->hp_mic_io_value);
|
||||
if (ret < 0) {
|
||||
DBG("%s() have not set hp_mic_io_value ,so default set pull down low level\n", __FUNCTION__);
|
||||
pdata->hp_mic_io_value = 0;
|
||||
}
|
||||
ret = of_property_read_u32(node, "main_mic_io_value", &pdata->main_mic_io_value);
|
||||
if (ret < 0) {
|
||||
DBG("%s() have not set main_mic_io_value ,so default set pull down low level\n", __FUNCTION__);
|
||||
pdata->main_mic_io_value = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(pdata->hook_adc_chn >= 0)
|
||||
{//hook adc mode
|
||||
printk("%s() headset have hook adc mode\n",__FUNCTION__);
|
||||
ret = rk_headset_adc_probe(pdev,pdata);
|
||||
if(ret < 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//hook interrupt mode and not hook
|
||||
printk("%s() headset have %s mode\n",__FUNCTION__,pdata->hook_gpio?"interrupt hook":"no hook");
|
||||
ret = rk_headset_probe(pdev,pdata);
|
||||
if(ret < 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
kfree(pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_headset_remove(struct platform_device *pdev)
|
||||
{
|
||||
if(pdata_info)
|
||||
kfree(pdata_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_headset_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
if(pdata_info->hook_adc_chn >= 0)
|
||||
{
|
||||
return rk_headset_adc_suspend(pdev,state);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_headset_resume(struct platform_device *pdev)
|
||||
{
|
||||
DBG("%s----%d\n",__FUNCTION__,__LINE__);
|
||||
if(pdata_info->hook_adc_chn >= 0)
|
||||
{
|
||||
return rk_headset_adc_resume(pdev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id rockchip_headset_of_match[] = {
|
||||
{ .compatible = "rockchip_headset", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_headset_of_match);
|
||||
|
||||
static struct platform_driver rockchip_headset_driver = {
|
||||
.probe = rockchip_headset_probe,
|
||||
.remove = rockchip_headset_remove,
|
||||
.resume = rockchip_headset_resume,
|
||||
.suspend = rockchip_headset_suspend,
|
||||
.driver = {
|
||||
.name = "rockchip_headset",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(rockchip_headset_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rockchip_headset_init(void)
|
||||
{
|
||||
platform_driver_register(&rockchip_headset_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rockchip_headset_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rockchip_headset_driver);
|
||||
}
|
||||
|
||||
late_initcall(rockchip_headset_init);
|
||||
MODULE_DESCRIPTION("Rockchip Headset Core Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user