mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
rk610 codec: add function codec_set_spk for hdmi, add some Machine resume cannot work test inter face
This commit is contained in:
@@ -30,6 +30,18 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include "rk610_codec.h"
|
||||
|
||||
#define RK610_PROC
|
||||
#ifdef RK610_PROC
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#endif
|
||||
|
||||
//if you find resume rk610 cannot work,you can try RESUME_PROBLEM 1.
|
||||
//if rk610 Normal working on RESUME_PROBLEM 1, you must detect Machine other driver queue.
|
||||
//you can look soc-core.c the resume source.s
|
||||
#define RESUME_PROBLEM 0
|
||||
|
||||
#ifdef CONFIG_ARCH_RK30
|
||||
#define RK610_SPK_CTRL_PIN RK30_PIN4_PC6
|
||||
#else
|
||||
@@ -41,7 +53,7 @@
|
||||
/*
|
||||
* Debug
|
||||
*/
|
||||
#if 0
|
||||
#if 1
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
@@ -89,8 +101,30 @@ struct rk610_codec_priv {
|
||||
|
||||
struct delayed_work rk610_delayed_work;
|
||||
unsigned int spk_ctrl_io;
|
||||
bool hdmi_ndet;
|
||||
#if RESUME_PROBLEM
|
||||
int rk610_workstatus;
|
||||
#endif
|
||||
};
|
||||
|
||||
void codec_set_spk(bool on)
|
||||
{
|
||||
struct rk610_codec_priv *rk610_codec;
|
||||
if(!rk610_codec_codec)
|
||||
return;
|
||||
|
||||
rk610_codec=snd_soc_codec_get_drvdata(rk610_codec_codec);
|
||||
if(!rk610_codec)
|
||||
return;
|
||||
|
||||
rk610_codec->hdmi_ndet = on;
|
||||
if(on)
|
||||
gpio_set_value(RK610_SPK_CTRL_PIN, GPIO_HIGH);
|
||||
else
|
||||
gpio_set_value(RK610_SPK_CTRL_PIN, GPIO_LOW);
|
||||
}
|
||||
EXPORT_SYMBOL(codec_set_spk);
|
||||
|
||||
/*
|
||||
* read rk610 register cache
|
||||
*/
|
||||
@@ -292,6 +326,49 @@ static struct snd_pcm_hw_constraint_list constraints_12 = {
|
||||
.list = rates_12,
|
||||
};
|
||||
|
||||
static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
|
||||
DBG("Enter::%s----%d now_level =%d old_level = %d\n",__FUNCTION__,__LINE__,level,codec->dapm.bias_level);
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
break;
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* VREF, VMID=2x50k, digital enabled */
|
||||
// rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
#if RESUME_PROBLEM
|
||||
if(rk610_codec->rk610_workstatus == SND_SOC_DAPM_STREAM_RESUME)
|
||||
{
|
||||
DBG("rk610 is resume,have not into standby\n");
|
||||
rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
printk("rk610 standby\n");
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_OFF:
|
||||
printk("rk610 power off\n");
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
codec->dapm.bias_level = level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that this should be called from init rather than from hw_params.
|
||||
*/
|
||||
@@ -340,6 +417,7 @@ static int rk610_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
|
||||
u16 iface = 0;
|
||||
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
@@ -453,7 +531,7 @@ static int rk610_codec_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
// struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
|
||||
struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
|
||||
DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
|
||||
|
||||
if (mute)
|
||||
@@ -486,46 +564,13 @@ static int rk610_codec_mute(struct snd_soc_dai *dai, int mute)
|
||||
#endif
|
||||
// schedule_delayed_work(&rk610_codec->rk610_delayed_work, 0);
|
||||
// rk610_codec_reg_read();
|
||||
spk_ctrl_fun(GPIO_HIGH);
|
||||
if(rk610_codec->hdmi_ndet)
|
||||
spk_ctrl_fun(GPIO_HIGH);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk610_codec_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level);
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
break;
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* VREF, VMID=2x50k, digital enabled */
|
||||
// rk610_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
printk("rk610 standby\n");
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1D, 0xFE);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_OFF:
|
||||
printk("rk610 power off\n");
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1D, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1E, 0xFF);
|
||||
rk610_codec_write(codec, ACCELCODEC_R1F, 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
codec->dapm.bias_level = level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk610_delayedwork_fun(struct work_struct *work)
|
||||
{
|
||||
struct snd_soc_codec *codec = rk610_codec_codec;
|
||||
@@ -580,23 +625,15 @@ static int rk610_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
|
||||
|
||||
static int rk610_codec_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
int i;
|
||||
u8 data[2];
|
||||
struct i2c_client *i2c;
|
||||
u16 *cache = codec->reg_cache;
|
||||
struct rk610_codec_priv *rk610_codec =snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
/* Sync reg_cache with the hardware */
|
||||
/*
|
||||
for (i = 0; i < RK610_CODEC_NUM_REG; i++) {
|
||||
data[0] = cache[i] & 0x00ff;
|
||||
i2c = (struct i2c_client *)codec->control_data;
|
||||
i2c->addr = (i2c->addr & 0x60)|i;
|
||||
codec->hw_write(codec->control_data, data, 1);
|
||||
}
|
||||
*/
|
||||
rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
|
||||
|
||||
// rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
#if RESUME_PROBLEM
|
||||
rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_RESUME;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -670,11 +707,18 @@ void rk610_codec_reg_set(void)
|
||||
// #endif
|
||||
}
|
||||
|
||||
#ifdef RK610_PROC
|
||||
static int RK610_PROC_init(void);
|
||||
#endif
|
||||
|
||||
static int rk610_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct rk610_codec_priv *rk610_codec = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
#ifdef RK610_PROC
|
||||
RK610_PROC_init();
|
||||
#endif
|
||||
rk610_codec_codec = codec;
|
||||
DBG("[%s] start\n", __FUNCTION__);
|
||||
ret = snd_soc_codec_set_cache_io(codec, 8, 16, rk610_codec->control_type);
|
||||
@@ -706,7 +750,11 @@ static int rk610_codec_probe(struct snd_soc_codec *codec)
|
||||
#else
|
||||
rk610_codec->spk_ctrl_io = 0;
|
||||
#endif
|
||||
|
||||
rk610_codec->hdmi_ndet = true;
|
||||
#if RESUME_PROBLEM
|
||||
rk610_codec->rk610_workstatus = SND_SOC_DAPM_STREAM_NOP;
|
||||
#endif
|
||||
|
||||
rk610_control_init_codec();
|
||||
rk610_codec_reg_set();
|
||||
// rk610_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||
@@ -808,3 +856,52 @@ MODULE_DESCRIPTION("ASoC RK610 CODEC driver");
|
||||
MODULE_AUTHOR("rk@rock-chips.com");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
//=====================================================================
|
||||
//Proc
|
||||
#ifdef RK610_PROC
|
||||
static ssize_t RK610_PROC_write(struct file *file, const char __user *buffer,
|
||||
unsigned long len, void *data)
|
||||
{
|
||||
char *cookie_pot;
|
||||
|
||||
cookie_pot = (char *)vmalloc( len );
|
||||
if (!cookie_pot)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (copy_from_user( cookie_pot, buffer, len ))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
switch(cookie_pot[0])
|
||||
{
|
||||
case 'p':
|
||||
spk_ctrl_fun(GPIO_HIGH);
|
||||
break;
|
||||
case 'o':
|
||||
spk_ctrl_fun(GPIO_LOW);
|
||||
break;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int RK610_PROC_init(void)
|
||||
{
|
||||
struct proc_dir_entry *RK610_PROC_entry;
|
||||
RK610_PROC_entry = create_proc_entry("driver/rk610_ts", 0777, NULL);
|
||||
if(RK610_PROC_entry != NULL)
|
||||
{
|
||||
RK610_PROC_entry->write_proc = RK610_PROC_write;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("create proc error !\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user