mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
phonepad: update the headset driver from huawei project, make some code in
rt3261.c depend on CONFIG_SND_SOC_RT5623.
This commit is contained in:
@@ -49,9 +49,10 @@
|
||||
#define DBG(x...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define HOOK_ADC_SAMPLE_TIME 700
|
||||
#define HOOK_LEVEL_HIGH 409 //1V*1024/2.5
|
||||
#define HOOK_ADC_SAMPLE_TIME 100
|
||||
#define HOOK_LEVEL_HIGH 600 //1V*1024/2.5
|
||||
#define HOOK_LEVEL_LOW 204 //0.5V*1024/2.5
|
||||
#define HOOK_DEFAULT_VAL 1024
|
||||
|
||||
#define BIT_HEADSET (1 << 0)
|
||||
#define BIT_HEADSET_NO_MIC (1 << 1)
|
||||
@@ -61,16 +62,24 @@
|
||||
|
||||
#define HEADSET_IN 1
|
||||
#define HEADSET_OUT 0
|
||||
#define HOOK_DOWN 0
|
||||
#define HOOK_UP 1
|
||||
#define HOOK_DOWN 1
|
||||
#define HOOK_UP 0
|
||||
#define enable 1
|
||||
#define disable 0
|
||||
|
||||
#define HEADSET_TIMER 1
|
||||
#define HOOK_TIMER 2
|
||||
|
||||
#define WAIT 2
|
||||
#define BUSY 1
|
||||
#define IDLE 0
|
||||
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
extern int wm8994_set_status(void);
|
||||
extern int wm8994_headset_mic_detect(bool headset_status);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SND_SOC_RT3261
|
||||
extern int rt3261_headset_mic_detect(int jack_insert);
|
||||
#endif
|
||||
|
||||
/* headset private data */
|
||||
@@ -79,8 +88,8 @@ struct headset_priv {
|
||||
struct rk_headset_pdata *pdata;
|
||||
unsigned int headset_status:1;
|
||||
unsigned int hook_status:1;
|
||||
unsigned int isMic:1;
|
||||
unsigned int isHook_irq:1;
|
||||
int isMic;
|
||||
unsigned int heatset_irq_working;// headset interrupt working will not check hook key
|
||||
int cur_headset_status;
|
||||
|
||||
unsigned int irq[2];
|
||||
@@ -92,7 +101,7 @@ struct headset_priv {
|
||||
unsigned char *keycodes;
|
||||
struct adc_client *client;
|
||||
struct timer_list hook_timer;
|
||||
int adc_callback_status;
|
||||
unsigned int hook_time;//ms
|
||||
};
|
||||
static struct headset_priv *headset_info;
|
||||
|
||||
@@ -102,45 +111,17 @@ int Headset_isMic(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(Headset_isMic);
|
||||
|
||||
//1
|
||||
static irqreturn_t headset_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
DBG("---headset_interrupt---\n");
|
||||
schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(50));
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int headset_change_irqtype(int type,unsigned int irq_type)
|
||||
{
|
||||
int ret = 0;
|
||||
DBG("--------%s----------\n",__FUNCTION__);
|
||||
free_irq(headset_info->irq[type],NULL);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case HEADSET:
|
||||
ret = request_irq(headset_info->irq[type], headset_interrupt, irq_type, "headset_hook", NULL);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret<0)
|
||||
{
|
||||
DBG("headset_change_irqtype: request irq failed\n");
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void headsetobserve_work(struct work_struct *work)
|
||||
{
|
||||
int i,level = 0;
|
||||
struct rk_headset_pdata *pdata = headset_info->pdata;
|
||||
static unsigned int old_status = 0;
|
||||
DBG("---headsetobserve_work---\n");
|
||||
mutex_lock(&headset_info->mutex_lock[HEADSET]);
|
||||
|
||||
int i,level = 0;
|
||||
int adc_value = 0;
|
||||
if(headset_info->heatset_irq_working == BUSY || headset_info->heatset_irq_working == WAIT)
|
||||
return IRQ_HANDLED;
|
||||
DBG("In the headset_interrupt for read headset level\n");
|
||||
headset_info->heatset_irq_working = BUSY;
|
||||
for(i=0; i<3; i++)
|
||||
{
|
||||
level = gpio_get_value(pdata->Headset_gpio);
|
||||
@@ -156,7 +137,7 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
if(level < 0)
|
||||
{
|
||||
printk("%s:get pin level err!\n",__FUNCTION__);
|
||||
goto RE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
old_status = headset_info->headset_status;
|
||||
@@ -180,201 +161,253 @@ static void headsetobserve_work(struct work_struct *work)
|
||||
}
|
||||
if(old_status == headset_info->headset_status)
|
||||
{
|
||||
DBG("old_status == headset_info->headset_status\n");
|
||||
goto RE_ERROR;
|
||||
DBG("Read Headset IO level old status == now status\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch(pdata->headset_in_type)
|
||||
DBG("(headset in is %s)headset status is %s\n",
|
||||
pdata->headset_in_type?"high level":"low level",
|
||||
headset_info->headset_status?"in":"out");
|
||||
if(headset_info->headset_status == HEADSET_IN)
|
||||
{
|
||||
case HEADSET_IN_HIGH:
|
||||
if(level > 0)
|
||||
{//in--High level
|
||||
DBG("--- HEADSET_IN_HIGH headset in HIGH---\n");
|
||||
headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
|
||||
|
||||
del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
|
||||
// headset_info->headset_timer.expires = jiffies + 500;
|
||||
headset_info->headset_timer.expires = jiffies + 10;
|
||||
add_timer(&headset_info->headset_timer);
|
||||
}
|
||||
else if(level == 0)
|
||||
{//out--Low level
|
||||
DBG("---HEADSET_IN_HIGH headset out HIGH---\n");
|
||||
|
||||
del_timer(&headset_info->hook_timer);
|
||||
headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case HEADSET_IN_LOW:
|
||||
if(level == 0)
|
||||
{//in--High level
|
||||
DBG("---HEADSET_IN_LOW headset in LOW ---\n");
|
||||
headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
|
||||
#if 0
|
||||
while(1)
|
||||
{
|
||||
if(adc_sync_read(headset_info->client) > HOOK_DEFAULT_VAL
|
||||
|| adc_sync_read(headset_info->client) < 0)
|
||||
{
|
||||
printk("headset is showly inside\n");
|
||||
}
|
||||
else
|
||||
break;
|
||||
msleep(50);
|
||||
|
||||
del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
|
||||
// headset_info->headset_timer.expires = jiffies + 500;
|
||||
headset_info->headset_timer.expires = jiffies + 10;
|
||||
add_timer(&headset_info->headset_timer);
|
||||
if(pdata->headset_in_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;
|
||||
if(headset_info->headset_status == HEADSET_OUT)
|
||||
goto out1;
|
||||
msleep(5);
|
||||
}
|
||||
else if(level > 0)
|
||||
{//out--High level
|
||||
DBG("---HEADSET_IN_LOW headset out LOW ---\n");
|
||||
|
||||
del_timer(&headset_info->hook_timer);
|
||||
headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
|
||||
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);
|
||||
#endif
|
||||
if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
|
||||
{
|
||||
// wait for find Hook key
|
||||
//#ifdef CONFIG_SND_SOC_RT5625
|
||||
CHECK_AGAIN:
|
||||
//headset_info->isMic = rt5625_headset_mic_detect(true);
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
wm8994_headset_mic_detect(true);
|
||||
#endif
|
||||
#ifdef CONFIG_SND_SOC_RT3261
|
||||
rt3261_headset_mic_detect(true);
|
||||
#endif
|
||||
//mdelay(400);
|
||||
adc_value = adc_sync_read(headset_info->client);
|
||||
if(adc_value >= 0 && adc_value < HOOK_LEVEL_LOW)
|
||||
{
|
||||
headset_info->isMic= 0;//No microphone
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
wm8994_headset_mic_detect(false);
|
||||
#endif
|
||||
#ifdef CONFIG_SND_SOC_RT3261
|
||||
rt3261_headset_mic_detect(false);
|
||||
#endif
|
||||
printk("headset->isMic = %d\n",headset_info->isMic);
|
||||
}
|
||||
else if(adc_value >= HOOK_LEVEL_HIGH)
|
||||
{
|
||||
headset_info->isMic = 1;//have mic
|
||||
printk("headset->isMic = %d\n",headset_info->isMic);
|
||||
}
|
||||
if(headset_info->isMic < 0)
|
||||
{
|
||||
printk("codec is error\n");
|
||||
headset_info->heatset_irq_working = WAIT;
|
||||
if(pdata->headset_in_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);
|
||||
schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
//adc_value = adc_sync_read(headset_info->client);
|
||||
printk("headset adc value = %d\n",adc_value);
|
||||
if(headset_info->isMic) {
|
||||
if(adc_value > HOOK_DEFAULT_VAL || adc_value < HOOK_LEVEL_HIGH)
|
||||
goto CHECK_AGAIN;
|
||||
mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1000));
|
||||
}
|
||||
//#endif
|
||||
headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBG("---- ERROR: on headset headset_in_type error -----\n");
|
||||
break;
|
||||
else
|
||||
{
|
||||
headset_info->isMic= 0;//No microphone
|
||||
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)
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
|
||||
else
|
||||
irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
|
||||
}
|
||||
|
||||
else if(headset_info->headset_status == HEADSET_OUT)
|
||||
{
|
||||
headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
|
||||
del_timer(&headset_info->hook_timer);
|
||||
if(headset_info->isMic)
|
||||
{
|
||||
headset_info->hook_status = HOOK_UP;
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
//rt5625_headset_mic_detect(false);
|
||||
wm8994_headset_mic_detect(false);
|
||||
#endif
|
||||
#ifdef CONFIG_SND_SOC_RT3261
|
||||
rt3261_headset_mic_detect(false);
|
||||
#endif
|
||||
}
|
||||
if(pdata->headset_in_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);
|
||||
}
|
||||
|
||||
RE_ERROR:
|
||||
mutex_unlock(&headset_info->mutex_lock[HEADSET]);
|
||||
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);
|
||||
|
||||
// schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));
|
||||
out:
|
||||
headset_info->heatset_irq_working = IDLE;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int headset_change_irqtype(int type,unsigned int irq_type)
|
||||
{
|
||||
int ret = 0;
|
||||
free_irq(headset_info->irq[type],NULL);
|
||||
|
||||
DBG("%s: type is %s irqtype is %s\n",__FUNCTION__, type?"hook":"headset",(irq_type == IRQF_TRIGGER_RISING)?"RISING":"FALLING");
|
||||
// DBG("%s: type is %s irqtype is %s\n",__FUNCTION__, type?"hook":"headset",(irq_type == IRQF_TRIGGER_LOW)?"LOW":"HIGH");
|
||||
switch(type)
|
||||
{
|
||||
case HEADSET:
|
||||
ret = request_threaded_irq(headset_info->irq[type],NULL, headset_interrupt, irq_type, "headset_input", NULL);
|
||||
if (ret<0)
|
||||
DBG("headset_change_irqtype: request irq failed\n");
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
//2
|
||||
static void headsetobserve_work(struct work_struct *work)
|
||||
{
|
||||
struct rk_headset_pdata *pdata = headset_info->pdata;
|
||||
DBG("In the headsetobserve_work headset_status is %s\n",headset_info->headset_status?"in":"out");
|
||||
|
||||
if(headset_info->heatset_irq_working == WAIT && headset_info->headset_status == HEADSET_IN)
|
||||
{
|
||||
printk("wait for codec\n");
|
||||
headset_info->heatset_irq_working = IDLE;
|
||||
headset_info->headset_status = HEADSET_OUT;
|
||||
|
||||
free_irq(headset_info->irq[HEADSET],NULL);
|
||||
msleep(100);
|
||||
if(pdata->headset_in_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;
|
||||
if(request_threaded_irq(headset_info->irq[HEADSET], NULL,headset_interrupt, headset_info->irq_type[HEADSET], "headset_input", NULL) < 0)
|
||||
printk("headset request_threaded_irq error\n");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if(pdata->headset_in_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)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);
|
||||
|
||||
if(pdata->headset_in_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)
|
||||
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);
|
||||
*/
|
||||
}
|
||||
//4
|
||||
static void hook_adc_callback(struct adc_client *client, void *client_param, int result)
|
||||
{
|
||||
int level = 0;
|
||||
int level = result;
|
||||
struct headset_priv *headset = (struct headset_priv *)client_param;
|
||||
struct rk_headset_pdata *pdata = headset_info->pdata;
|
||||
struct rk_headset_pdata *pdata = headset->pdata;
|
||||
static unsigned int old_status = HOOK_UP;
|
||||
|
||||
DBG("---hook_adc_callback---, result = %d, flag = %d\n", result, headset->adc_callback_status);
|
||||
|
||||
level = result;
|
||||
DBG("hook_adc_callback read adc value: %d\n",level);
|
||||
|
||||
if(level < 0)
|
||||
{
|
||||
printk("%s:get adc level err!\n",__FUNCTION__);
|
||||
printk("%s:get adc level err = %d!\n",__FUNCTION__,level);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(headset->adc_callback_status)
|
||||
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)
|
||||
{
|
||||
|
||||
case HEADSET_TIMER:
|
||||
|
||||
if(level >= 0 && level < HOOK_LEVEL_LOW)
|
||||
{
|
||||
headset->isMic= 0;//No microphone
|
||||
headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
|
||||
printk("headset->isMic = %d\n",headset->isMic);
|
||||
}
|
||||
else if(level >= HOOK_LEVEL_HIGH)
|
||||
{
|
||||
headset->isMic = 1;//have mic
|
||||
DBG("enable headset_hook irq\n");
|
||||
headset_info->cur_headset_status = BIT_HEADSET;
|
||||
mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(HOOK_ADC_SAMPLE_TIME));
|
||||
printk("headset->isMic = %d\n",headset->isMic);
|
||||
}
|
||||
DBG("Headset is out or waiting for headset is in or out,after same time check HOOK key\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case HOOK_TIMER:
|
||||
mutex_lock(&headset_info->mutex_lock[HOOK]);
|
||||
if(headset_info->headset_status == HEADSET_OUT)
|
||||
{
|
||||
DBG("Headset is out\n");
|
||||
goto RE_ERROR;
|
||||
}
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
if(wm8994_set_status() != 0)
|
||||
{
|
||||
DBG("wm8994 is not set on heatset channel or suspend\n");
|
||||
goto RE_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
old_status = headset_info->hook_status;
|
||||
if(level >= HOOK_LEVEL_HIGH)
|
||||
headset_info->hook_status = HOOK_UP;
|
||||
else if(level < HOOK_LEVEL_LOW && level >= 0)
|
||||
headset_info->hook_status = HOOK_DOWN;
|
||||
if(old_status == headset_info->hook_status)
|
||||
{
|
||||
DBG("old_status == headset_info->hook_status\n");
|
||||
goto RE_ERROR;
|
||||
}
|
||||
|
||||
if(level < HOOK_LEVEL_LOW && level >= 0)
|
||||
{
|
||||
DBG("---HOOK Down ---\n");
|
||||
//headset_change_irqtype(HOOK,IRQF_TRIGGER_RISING);//
|
||||
input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status);
|
||||
input_sync(headset_info->input_dev);
|
||||
}
|
||||
else if(level >= HOOK_LEVEL_HIGH)
|
||||
{
|
||||
DBG("---HOOK Up ---\n");
|
||||
//headset_change_irqtype(HOOK,IRQF_TRIGGER_FALLING);//
|
||||
input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status);
|
||||
input_sync(headset_info->input_dev);
|
||||
}
|
||||
mutex_unlock(&headset_info->mutex_lock[HOOK]);
|
||||
break;
|
||||
default:
|
||||
printk("adc callback flag status error!!! default case\n");
|
||||
break;
|
||||
old_status = headset->hook_status;
|
||||
if(level < HOOK_LEVEL_LOW && level >= 0)
|
||||
headset->hook_status = HOOK_DOWN;
|
||||
else if(level > HOOK_LEVEL_HIGH && level < HOOK_DEFAULT_VAL)
|
||||
headset->hook_status = HOOK_UP;
|
||||
else{
|
||||
DBG("hook_adc_callback read adc value.........outside showly....: %d\n",level);
|
||||
del_timer(&headset->hook_timer);
|
||||
mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(500));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
RE_ERROR:
|
||||
mutex_unlock(&headset_info->mutex_lock[HOOK]);
|
||||
|
||||
if(old_status == headset->hook_status)
|
||||
{
|
||||
// DBG("Hook adc read old_status == headset->hook_status hook_time = %d\n",headset->hook_time);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG("HOOK status is %s , adc value = %d hook_time = %d\n",headset->hook_status?"down":"up",level,headset->hook_time);
|
||||
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))
|
||||
DBG("headset is out,HOOK status must discard\n");
|
||||
else
|
||||
{
|
||||
if(headset->hook_status==HOOK_DOWN)
|
||||
DBG("hook_adc_callback read adc ------------HOOK_DOWN\n");
|
||||
else
|
||||
DBG("hook_adc_callback read adc ------------HOOK_UP\n");
|
||||
input_report_key(headset->input_dev,pdata->hook_key_code,headset->hook_status);
|
||||
input_sync(headset->input_dev);
|
||||
}
|
||||
}
|
||||
|
||||
//3
|
||||
static void hook_timer_callback(unsigned long arg)
|
||||
{
|
||||
struct headset_priv *headset = (struct headset_priv *)(arg);
|
||||
DBG("hook_timer_callback\n");
|
||||
// DBG("hook_timer_callback\n");
|
||||
if(headset->headset_status == HEADSET_OUT
|
||||
|| headset->heatset_irq_working == BUSY
|
||||
|| headset->heatset_irq_working == WAIT)
|
||||
return;
|
||||
adc_async_read(headset->client);
|
||||
headset->adc_callback_status = HOOK_TIMER;
|
||||
mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(HOOK_ADC_SAMPLE_TIME));
|
||||
}
|
||||
|
||||
static void headset_timer_callback(unsigned long arg)
|
||||
{
|
||||
struct headset_priv *headset = (struct headset_priv *)(arg);
|
||||
//struct rk_headset_pdata *pdata = headset->pdata;
|
||||
//int i,level = 0;
|
||||
|
||||
DBG("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);
|
||||
|
||||
if(headset->headset_status == HEADSET_OUT)
|
||||
{
|
||||
printk("Headset is out\n");
|
||||
goto out;
|
||||
}
|
||||
#ifdef CONFIG_SND_SOC_WM8994
|
||||
if(wm8994_set_status() != 0)
|
||||
{
|
||||
// printk("wait wm8994 set the MICB2\n");
|
||||
// headset_info->headset_timer.expires = jiffies + 500;
|
||||
headset_info->headset_timer.expires = jiffies + 10;
|
||||
add_timer(&headset_info->headset_timer);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
adc_async_read(headset->client);
|
||||
headset->adc_callback_status = HEADSET_TIMER;
|
||||
out:
|
||||
return;
|
||||
mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(headset->hook_time));
|
||||
}
|
||||
|
||||
static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf)
|
||||
@@ -416,12 +449,14 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
if (headset == NULL) {
|
||||
dev_err(&pdev->dev, "failed to allocate driver data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
headset_info = headset;
|
||||
headset->pdata = pdev->dev.platform_data;
|
||||
pdata = headset->pdata;
|
||||
headset->headset_status = HEADSET_OUT;
|
||||
headset->heatset_irq_working = IDLE;
|
||||
headset->hook_status = HOOK_UP;
|
||||
headset->adc_callback_status = HEADSET_TIMER;
|
||||
headset->hook_time = HOOK_ADC_SAMPLE_TIME;
|
||||
headset->cur_headset_status = 0;
|
||||
headset->sdev.name = "h2w";
|
||||
headset->sdev.print_name = h2w_print_name;
|
||||
@@ -429,15 +464,13 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
goto failed_free;
|
||||
|
||||
mutex_init(&headset->mutex_lock[HEADSET]);
|
||||
mutex_init(&headset->mutex_lock[HOOK]);
|
||||
// mutex_init(&headset->mutex_lock[HEADSET]);
|
||||
// mutex_init(&headset->mutex_lock[HOOK]);
|
||||
|
||||
INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET], headsetobserve_work);
|
||||
|
||||
headset->isMic = 0;
|
||||
setup_timer(&headset->headset_timer, headset_timer_callback, (unsigned long)headset);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Create and register the input driver.
|
||||
headset->input_dev = input_allocate_device();
|
||||
if (!headset->input_dev) {
|
||||
@@ -460,22 +493,39 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
goto failed_free_dev;
|
||||
}
|
||||
|
||||
|
||||
// headset->input_dev->keycode = headset->keycodes;
|
||||
// headset->input_dev->keycodesize = sizeof(unsigned char);
|
||||
// headset->input_dev->keycodemax = 2;
|
||||
|
||||
// set_bit(KEY_MEDIA, headset->input_dev->keybit);
|
||||
// clear_bit(0, headset->input_dev->keybit);
|
||||
input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code);
|
||||
// input_set_capability(headset->input_dev, EV_SW, SW_HEADPHONE_INSERT);
|
||||
// input_set_capability(headset->input_dev, EV_KEY, KEY_END);
|
||||
//------------------------------------------------------------------
|
||||
if (pdata->Headset_gpio) {
|
||||
ret = pdata->headset_io_init(pdata->Headset_gpio, pdata->headset_gpio_info.iomux_name, pdata->headset_gpio_info.iomux_mode);
|
||||
if (ret)
|
||||
goto failed_free;
|
||||
|
||||
// headset->input_dev->evbit[0] = BIT_MASK(EV_KEY);
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT;
|
||||
else
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT;
|
||||
ret = request_threaded_irq(headset->irq[HEADSET], NULL,headset_interrupt, headset->irq_type[HEADSET], "headset_input", NULL);
|
||||
if (ret)
|
||||
goto failed_free;
|
||||
enable_irq_wake(headset->irq[HEADSET]);
|
||||
}
|
||||
else
|
||||
goto failed_free;
|
||||
//------------------------------------------------------------------
|
||||
if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
|
||||
{
|
||||
headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset);
|
||||
if(!headset->client) {
|
||||
printk("hook adc register error\n");
|
||||
ret = -EINVAL;
|
||||
goto failed_free;
|
||||
}
|
||||
setup_timer(&headset->hook_timer,hook_timer_callback, (unsigned long)headset);
|
||||
printk("headset adc default value = %d\n",adc_sync_read(headset->client));
|
||||
}
|
||||
|
||||
headset_info = headset;
|
||||
schedule_delayed_work(&headset->h_delayed_work[HEADSET], msecs_to_jiffies(500));
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
hs_early_suspend.suspend = NULL;
|
||||
hs_early_suspend.resume = headset_early_resume;
|
||||
@@ -483,42 +533,6 @@ static int rockchip_headsetobserve_probe(struct platform_device *pdev)
|
||||
register_early_suspend(&hs_early_suspend);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------
|
||||
if (pdata->Headset_gpio) {
|
||||
|
||||
ret = pdata->headset_io_init(pdata->Headset_gpio, pdata->headset_gpio_info.iomux_name, pdata->headset_gpio_info.iomux_mode);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
|
||||
headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
|
||||
|
||||
if(pdata->headset_in_type == HEADSET_IN_HIGH)
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_RISING;
|
||||
else
|
||||
headset->irq_type[HEADSET] = IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(headset->irq[HEADSET], headset_interrupt, headset->irq_type[HEADSET], "headset_input", NULL);
|
||||
if (ret)
|
||||
goto failed_free_dev;
|
||||
enable_irq_wake(headset->irq[HEADSET]);
|
||||
}
|
||||
else
|
||||
goto failed_free_dev;
|
||||
//------------------------------------------------------------------
|
||||
|
||||
if(pdata->Hook_adc_chn>=0 && 2>=pdata->Hook_adc_chn)
|
||||
{
|
||||
printk("hook adc register\n");
|
||||
headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset);
|
||||
if(!headset->client) {
|
||||
printk("hook adc register error\n");
|
||||
ret = -EINVAL;
|
||||
goto failed_free_dev;
|
||||
}
|
||||
setup_timer(&headset->hook_timer,
|
||||
hook_timer_callback, (unsigned long)headset);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
return 0;
|
||||
|
||||
failed_free_dev:
|
||||
@@ -533,21 +547,24 @@ failed_free:
|
||||
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[HEADSET]);
|
||||
del_timer(&headset_info->hook_timer);
|
||||
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[HEADSET]);
|
||||
if(headset_info->isMic)
|
||||
mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1500));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rockchip_headsetobserve_driver = {
|
||||
.probe = rockchip_headsetobserve_probe,
|
||||
// .resume = rockchip_headsetobserve_resume,
|
||||
// .suspend = rockchip_headsetobserve_suspend,
|
||||
.resume = rockchip_headsetobserve_resume,
|
||||
.suspend = rockchip_headsetobserve_suspend,
|
||||
.driver = {
|
||||
.name = "rk_headsetdet",
|
||||
.owner = THIS_MODULE,
|
||||
@@ -559,6 +576,7 @@ static int __init rockchip_headsetobserve_init(void)
|
||||
platform_driver_register(&rockchip_headsetobserve_driver);
|
||||
return 0;
|
||||
}
|
||||
module_init(rockchip_headsetobserve_init);
|
||||
late_initcall(rockchip_headsetobserve_init);
|
||||
MODULE_DESCRIPTION("Rockchip Headset Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
@@ -62,8 +62,10 @@ static struct snd_soc_codec *rt3261_codec;
|
||||
|
||||
#define VERSION "RT3261_V1.0.0"
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
extern void rt5623_on(void);
|
||||
extern void rt5623_off(void);
|
||||
#endif
|
||||
|
||||
struct rt3261_init_reg {
|
||||
u8 reg;
|
||||
@@ -482,7 +484,7 @@ static int rt3261_readable_register(
|
||||
}
|
||||
|
||||
/**
|
||||
* rt3261_headset_detect - Detect headset.
|
||||
* rt3261_headset_mic_detect - Detect headset.
|
||||
* @codec: SoC audio codec device.
|
||||
* @jack_insert: Jack insert or not.
|
||||
*
|
||||
@@ -490,43 +492,44 @@ static int rt3261_readable_register(
|
||||
*
|
||||
* Returns detect status.
|
||||
*/
|
||||
int rt3261_headset_detect(struct snd_soc_codec *codec, int jack_insert)
|
||||
int rt3261_headset_mic_detect(int jack_insert)
|
||||
{
|
||||
int jack_type;
|
||||
int sclk_src;
|
||||
|
||||
if(jack_insert) {
|
||||
if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
|
||||
snd_soc_write(codec, RT3261_PWR_ANLG1, 0x2004);
|
||||
snd_soc_write(codec, RT3261_MICBIAS, 0x3830);
|
||||
snd_soc_write(codec, RT3261_GEN_CTRL1 , 0x3701);
|
||||
if (SND_SOC_BIAS_OFF == rt3261_codec->dapm.bias_level) {
|
||||
snd_soc_write(rt3261_codec, RT3261_PWR_ANLG1, 0x2004);
|
||||
snd_soc_write(rt3261_codec, RT3261_MICBIAS, 0x3830);
|
||||
snd_soc_write(rt3261_codec, RT3261_GEN_CTRL1 , 0x3701);
|
||||
}
|
||||
sclk_src = snd_soc_read(codec, RT3261_GLB_CLK) &
|
||||
sclk_src = snd_soc_read(rt3261_codec, RT3261_GLB_CLK) &
|
||||
RT3261_SCLK_SRC_MASK;
|
||||
snd_soc_update_bits(codec, RT3261_GLB_CLK,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_GLB_CLK,
|
||||
RT3261_SCLK_SRC_MASK, 0x3 << RT3261_SCLK_SRC_SFT);
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG1,
|
||||
RT3261_PWR_LDO2, RT3261_PWR_LDO2);
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG2,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG2,
|
||||
RT3261_PWR_MB1, RT3261_PWR_MB1);
|
||||
snd_soc_update_bits(codec, RT3261_MICBIAS,
|
||||
mdelay(400);
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_MICBIAS,
|
||||
RT3261_MIC1_OVCD_MASK | RT3261_MIC1_OVTH_MASK |
|
||||
RT3261_PWR_CLK25M_MASK | RT3261_PWR_MB_MASK,
|
||||
RT3261_MIC1_OVCD_EN | RT3261_MIC1_OVTH_600UA |
|
||||
RT3261_PWR_MB_PU | RT3261_PWR_CLK25M_PU);
|
||||
snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_GEN_CTRL1,
|
||||
0x1, 0x1);
|
||||
msleep(100);
|
||||
if (snd_soc_read(codec, RT3261_IRQ_CTRL2) & 0x8)
|
||||
if (snd_soc_read(rt3261_codec, RT3261_IRQ_CTRL2) & 0x8)
|
||||
jack_type = RT3261_HEADPHO_DET;
|
||||
else
|
||||
jack_type = RT3261_HEADSET_DET;
|
||||
snd_soc_update_bits(codec, RT3261_IRQ_CTRL2,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_IRQ_CTRL2,
|
||||
RT3261_MB1_OC_CLR, 0);
|
||||
snd_soc_update_bits(codec, RT3261_GLB_CLK,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_GLB_CLK,
|
||||
RT3261_SCLK_SRC_MASK, sclk_src);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, RT3261_MICBIAS,
|
||||
snd_soc_update_bits(rt3261_codec, RT3261_MICBIAS,
|
||||
RT3261_MIC1_OVCD_MASK,
|
||||
RT3261_MIC1_OVCD_DIS);
|
||||
|
||||
@@ -535,7 +538,7 @@ int rt3261_headset_detect(struct snd_soc_codec *codec, int jack_insert)
|
||||
|
||||
return jack_type;
|
||||
}
|
||||
EXPORT_SYMBOL(rt3261_headset_detect);
|
||||
EXPORT_SYMBOL(rt3261_headset_mic_detect);
|
||||
|
||||
static const char *rt3261_dacr2_src[] = { "TxDC_R", "TxDP_R" };
|
||||
|
||||
@@ -765,6 +768,7 @@ static int rt3261_hp_mute_put(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
static int rt3261_modem_input_switch_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@@ -791,6 +795,7 @@ static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* IN1/IN2 Input Type */
|
||||
static const char *rt3261_input_mode[] = {
|
||||
@@ -851,9 +856,11 @@ static const char *rt3261_hp_mute_mode[] = {"off", "on",};
|
||||
|
||||
static const SOC_ENUM_SINGLE_DECL(rt3261_hp_mute_enum, 0, 0, rt3261_hp_mute_mode);
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
static const char *rt3261_modem_input_switch_mode[] = {"off", "on",};
|
||||
|
||||
static const SOC_ENUM_SINGLE_DECL(rt3261_modem_input_switch_enum, 0, 0, rt3261_modem_input_switch_mode);
|
||||
#endif
|
||||
|
||||
#ifdef RT3261_REG_RW
|
||||
#define REGVAL_MAX 0xffff
|
||||
@@ -1010,8 +1017,10 @@ static const struct snd_kcontrol_new rt3261_snd_controls[] = {
|
||||
SOC_ENUM_EXT("HP mute Switch", rt3261_hp_mute_enum,
|
||||
rt3261_hp_mute_get, rt3261_hp_mute_put),
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
SOC_ENUM_EXT("Modem Input Switch", rt3261_modem_input_switch_enum,
|
||||
rt3261_modem_input_switch_get, rt3261_modem_input_switch_put),
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2863,14 +2872,9 @@ static int rt3261_set_bias_level(struct snd_soc_codec *codec,
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG2,
|
||||
RT3261_PWR_MB1 | RT3261_PWR_MB2,
|
||||
RT3261_PWR_MB1 | RT3261_PWR_MB2);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG2,
|
||||
RT3261_PWR_MB1 | RT3261_PWR_MB2, 0);
|
||||
if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
|
||||
RT3261_PWR_VREF1 | RT3261_PWR_MB |
|
||||
@@ -2930,6 +2934,7 @@ static int rt3261_probe(struct snd_soc_codec *codec)
|
||||
rt3261_proc_init();
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
//for rt5623 MCLK use
|
||||
iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
|
||||
if (IS_ERR(iis_clk)) {
|
||||
@@ -2942,6 +2947,7 @@ static int rt3261_probe(struct snd_soc_codec *codec)
|
||||
rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK);
|
||||
clk_put(iis_clk);
|
||||
}
|
||||
#endif
|
||||
|
||||
rt3261_reset(codec);
|
||||
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
|
||||
@@ -3144,7 +3150,9 @@ static int __devinit rt3261_i2c_probe(struct i2c_client *i2c,
|
||||
if(rt3261->io_init)
|
||||
rt3261->io_init(pdata->codec_en_gpio, pdata->codec_en_gpio_info.iomux_name, pdata->codec_en_gpio_info.iomux_mode);
|
||||
|
||||
#if defined (CONFIG_SND_SOC_RT5623)
|
||||
rt3261->modem_is_open = 0;
|
||||
#endif
|
||||
|
||||
i2c_set_clientdata(i2c, rt3261);
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
@@ -2069,7 +2069,7 @@ enum {
|
||||
#define RT3261_HEADSET_DET BIT(1)
|
||||
#define RT3261_HEADPHO_DET BIT(2)
|
||||
|
||||
int rt3261_headset_detect(struct snd_soc_codec *codec, int jack_insert);
|
||||
int rt3261_headset_mic_detect(int jack_insert);
|
||||
|
||||
/* System Clock Source */
|
||||
enum {
|
||||
|
||||
@@ -169,6 +169,53 @@ static int rt3261_voice_hw_params(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIC("Mic Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("Headset Jack", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[]={
|
||||
|
||||
/* Mic Jack --> MIC_IN*/
|
||||
{"micbias1", NULL, "Mic Jack"},
|
||||
{"MIC1", NULL, "micbias1"},
|
||||
|
||||
// HP MIC
|
||||
{"micbias1", NULL, "Headset Jack"},
|
||||
{"MIC3", NULL, "micbias1"},
|
||||
} ;
|
||||
|
||||
static const struct snd_kcontrol_new rk_controls[] = {
|
||||
SOC_DAPM_PIN_SWITCH("Mic Jack"),
|
||||
SOC_DAPM_PIN_SWITCH("Headset Jack"),
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a rt3261 as connected on a rockchip board.
|
||||
*/
|
||||
static int rk29_rt3261_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
snd_soc_add_controls(codec, rk_controls,
|
||||
ARRAY_SIZE(rk_controls));
|
||||
|
||||
/* Add specific widgets */
|
||||
snd_soc_dapm_new_controls(dapm, rt3261_dapm_widgets,
|
||||
ARRAY_SIZE(rt3261_dapm_widgets));
|
||||
/* Set up specific audio path audio_mapnects */
|
||||
snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
|
||||
|
||||
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
|
||||
snd_soc_dapm_enable_pin(dapm, "Headset Jack");
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops rk29_ops = {
|
||||
.hw_params = rk29_hw_params,
|
||||
};
|
||||
@@ -185,6 +232,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
|
||||
.platform_name = "rockchip-audio",
|
||||
.cpu_dai_name = "rk29_i2s.0",
|
||||
.codec_dai_name = "rt3261-aif1",
|
||||
.init = rk29_rt3261_init,
|
||||
.ops = &rk29_ops,
|
||||
},
|
||||
{
|
||||
@@ -194,6 +242,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
|
||||
.platform_name = "rockchip-audio",
|
||||
.cpu_dai_name = "rk29_i2s.0",
|
||||
.codec_dai_name = "rt3261-aif2",
|
||||
.init = rk29_rt3261_init,
|
||||
.ops = &rt3261_voice_ops,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user