#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#include <mach/board.h>
-#include <linux/clk.h>
-#include <mach/iomux.h>
-
-#define RT3261_PROC
-#ifdef RT3261_PROC
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/vmalloc.h>
-#endif
//#define USE_INT_CLK
+#define DIFFERENTIAL 1
+#define SINGLE_END 0
+#define TWO_SPK 2
+#define ONE_SPK 1
+
+enum {
+ SPK_AMPLIFY_ZERO_POINT_FIVE_WATT=1,
+ SPK_AMPLIFY_ZERO_POINT_SIX_WATT,
+ SPK_AMPLIFY_ZERO_POINT_EIGHT_WATT,
+ SPK_AMPLIFY_ONE_WATT,
+};
+
+enum {
+ LR_NORMAL,
+ LR_SWAP,
+ LEFT_COPY_TO_RIGHT,
+ RIGHT_COPY_LEFT,
+};
static struct snd_soc_codec *rt3261_codec;
#if 0
-#define DBG(x...) printk(KERN_INFO x)
+#define DBG(x...) printk(KERN_DEBUG x)
#else
#define DBG(x...)
#endif
-//#define RTK_IOCTL
+#define RTK_IOCTL
#ifdef RTK_IOCTL
#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
#include "rt_codec_ioctl.h"
#define RT3261_REG_RW 1 /* for debug */
#define RT3261_DET_EXT_MIC 0
-#define VERSION "RT3261_V1.2.0"
+#define VERSION "RT3261_V1.3.0"
#if defined (CONFIG_SND_SOC_RT5623)
extern void rt5623_on(void);
};
static struct rt3261_init_reg init_list[] = {
- {RT3261_GEN_CTRL1 , 0x3f01},//fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1
+ {RT3261_GEN_CTRL1 , 0x3701},//fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1
{RT3261_ADDA_CLK1 , 0x1114},//73[2] = 1'b
{RT3261_MICBIAS , 0x3030},//93[5:4] = 11'b
{RT3261_CLS_D_OUT , 0xa000},//8d[11] = 0'b
{RT3261_OUTPUT , 0x8888},//unmute OUTVOLL/R
{RT3261_SPO_CLSD_RATIO , 0x0001},
{RT3261_I2S1_SDP , 0xd000},
+ {RT3261_GLB_CLK , 0x4000},//0424
+ //{0x90 , 0x636},//0424
+ {RT3261_CHARGE_PUMP , 0xe00},//0424
+ {RT3261_DEPOP_M3 , 0x636},//0424
+ {RT3261_DEPOP_M1 , 0x84},//0424
+ {RT3261_PWR_DIG1 , 0x8000},//0424
+ {RT3261_PWR_ANLG2 , 0x0800},
+ // huangcun 20130816 s
+#if 0
+ /*speaker*/
+ {RT3261_DSP_PATH2 , 0x0000},
+ {RT3261_PRIV_INDEX , 0x003f},//PR3d[14] = 0'b;
+ {RT3261_PRIV_DATA , 0x0000},
+ {RT3261_DAC2_CTRL , 0x0000},
+ {RT3261_MONO_DAC_MIXER, 0x4444},
+ {RT3261_SPK_L_MIXER, 0x003a},
+ {RT3261_SPK_R_MIXER, 0x003a},
+ {RT3261_SPO_L_MIXER, 0xc800},
+ /*headphone*/
+ {RT3261_OUT_L3_MIXER, 0x01fd},
+ {RT3261_OUT_R3_MIXER, 0x01fd},
+ {RT3261_HPO_MIXER, 0xc000},
+#endif
+#if 0
+ /*capture*/
+ {RT3261_IN1_IN2, 0x2080},//boost1 = 24db
+ {RT3261_REC_R2_MIXER, 0x007d},
+ {RT3261_MONO_ADC_MIXER,0x7030},
+ //{RT3261_GEN_CTRL1 , 0x2701},//regfa[13]=0
+ {RT3261_DSP_PATH2 , 0x0400},
+ {RT3261_DIG_INF_DATA, 0x0300},//right copy to left
+#endif
+#if 0
+ /*lin out*/
+ {RT3261_DSP_PATH2 , 0x0000},
+ {RT3261_PRIV_INDEX , 0x003f},//PR3d[14] = 0'b;
+ {RT3261_PRIV_DATA , 0x0000},
+ {RT3261_DAC2_CTRL , 0x0000},
+ {RT3261_MONO_DAC_MIXER, 0x4444},
+ {RT3261_OUT_L3_MIXER, 0x01fd},
+ {RT3261_OUT_R3_MIXER, 0x01fd},
+ {RT3261_LOUT_MIXER, 0xc000},
+#endif
+ // huangcun 20130816 e
};
#define RT3261_INIT_REG_LEN ARRAY_SIZE(init_list)
return 0;
}
+static int rt3261_customer_redefine(struct snd_soc_codec *codec, struct rt3261_priv *rt3261)
+{
+ if(rt3261->spk_num==TWO_SPK)
+ {
+ snd_soc_update_bits(codec, RT3261_SPO_L_MIXER,
+ RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L,
+ 1 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT);
+ snd_soc_update_bits(codec, RT3261_SPO_R_MIXER,
+ RT3261_M_SV_R_SPM_R, 0 << RT3261_M_SV_R_SPM_R_SFT);
+ }
+ else
+ {
+ snd_soc_update_bits(codec, RT3261_SPO_L_MIXER,
+ RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L,
+ 0 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT);
+ snd_soc_update_bits(codec, RT3261_SPO_R_MIXER,
+ RT3261_M_SV_R_SPM_R, 1 << RT3261_M_SV_R_SPM_R_SFT);
+ }
+
+
+ snd_soc_update_bits(codec, RT3261_IN3_IN4,
+ RT3261_IN_DF2, rt3261->modem_input_mode << RT3261_IN_SFT2);
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+ RT3261_LOUT_DF_MASK, rt3261->lout_to_modem_mode << RT3261_LOUT_DF);
+ snd_soc_update_bits(codec, RT3261_SPO_CLSD_RATIO,
+ RT3261_SPO_CLSD_RATIO_MASK, rt3261->spk_amplify);
+ snd_soc_update_bits(codec, RT3261_DIG_INF_DATA,
+ RT3261_IF1_DAC_SEL_MASK | RT3261_IF2_DAC_SEL_MASK,
+ (rt3261->playback_if1_data_control<<RT3261_IF1_DAC_SEL_SFT) | (rt3261->playback_if2_data_control<<RT3261_IF2_DAC_SEL_SFT));
+
+ return 0;
+}
+
+
static int rt3261_index_sync(struct snd_soc_codec *codec)
{
int i;
{
return snd_soc_write(codec, RT3261_RESET, 0);
}
-
+#if 0
static unsigned int rt3261_read(struct snd_soc_codec *codec,
unsigned int reg)
{
val = codec->hw_read(codec, reg);
return val;
}
-
+#endif
static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value, const void *data, int len)
{
+ struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
int ret;
if (!snd_soc_codec_volatile_register(codec, reg) &&
return 0;
}
- ret = i2c_master_normal_send(codec->control_data, data, len,400*1000);
- if (ret == len)
+ if (i2c_master_send(rt3261->i2c, data, len) == len)
return 0;
- if (ret < 0)
- return ret;
else
return -EIO;
}
data[2] = value & 0xff;
DBG("rt3261_write 0x%x = 0x%x\n",reg,value);
+
return do_hw_write(codec, reg, value, data, 3);
}
}
}
-void codec_set_spk(bool on)
-{
-
- struct snd_soc_codec *codec = rt3261_codec;
- DBG("%s: %d\n", __func__, on);
-
- if(!codec)
- return;
-
- if(on){
- DBG("snd_soc_dapm_enable_pin\n");
- snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk");
- }else{
- DBG("snd_soc_dapm_disable_pin\n");
- snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk");
- }
- snd_soc_dapm_sync(&codec->dapm);
-}
-
-
-
/**
* rt3261_headset_mic_detect - Detect headset.
* @codec: SoC audio codec device.
int sclk_src;
#endif
+ if(rt3261_codec == NULL){
+ return -1;
+ }
+
if(jack_insert) {
if (SND_SOC_BIAS_OFF == rt3261_codec->dapm.bias_level) {
snd_soc_write(rt3261_codec, RT3261_PWR_ANLG1, 0x2004);
RT3261_PWR_LDO2, RT3261_PWR_LDO2);
snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG2,
RT3261_PWR_MB1, RT3261_PWR_MB1);
- mdelay(400);
+ msleep(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,
return 0;
}
+static int rt3261_asrc_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+ DBG("%s\n", __FUNCTION__);
+ ucontrol->value.integer.value[0] = rt3261->asrc_en;
+
+ return 0;
+}
+
+static int rt3261_asrc_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+ DBG("%s\n", __FUNCTION__);
+ if (rt3261->asrc_en == ucontrol->value.integer.value[0])
+ return 0;
+
+ rt3261->asrc_en = ucontrol->value.integer.value[0];
+ switch (rt3261->asrc_en) {
+ case RT3261_ASRC_DIS://disable ASRC
+ DBG("%s disable\n", __FUNCTION__);
+ snd_soc_write(codec, RT3261_ASRC_1, 0x0);
+ snd_soc_write(codec, RT3261_ASRC_2, 0x0);
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x0); //bard 8-29
+ mutex_lock(&codec->mutex);
+ snd_soc_dapm_disable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4
+ snd_soc_dapm_disable_pin(&codec->dapm, "stereo filter"); //bard 9-4
+ snd_soc_dapm_sync(&codec->dapm); //bard 9-4
+ mutex_unlock(&codec->mutex);
+ break;
+
+ case RT3261_ASRC_EN://enable ASRC
+ DBG("%s enable\n", __FUNCTION__);
+ snd_soc_write(codec, RT3261_ASRC_1, 0x9800);
+ snd_soc_write(codec, RT3261_ASRC_2, 0xF800);
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x70); //bard 8-29
+ snd_soc_write(codec, RT3261_JD_CTRL, 0x03); //bard 8-29
+ //snd_soc_update_bits(codec, RT3261_PWR_DIG1, 0x0080, 0x0080);
+ //snd_soc_update_bits(codec, RT3261_PWR_DIG2, 0x8000, 0x8000);
+ mutex_lock(&codec->mutex);
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4
+ snd_soc_dapm_force_enable_pin(&codec->dapm, "stereo filter"); //bard 9-4
+ snd_soc_dapm_sync(&codec->dapm); //bard 9-4
+ mutex_unlock(&codec->mutex);
+ snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
//bard 8-9 s
-#if 0
static int rt3261_mic1_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- if(ucontrol->value.integer.value[0]) {
+ if(ucontrol->value.integer.value[0]==0) {
snd_soc_update_bits(codec, RT3261_REC_L2_MIXER,
RT3261_M_BST1_RM_L, 0);
snd_soc_update_bits(codec, RT3261_REC_R2_MIXER,
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- if(ucontrol->value.integer.value[0]) {
+ if(ucontrol->value.integer.value[0]==0) {
snd_soc_update_bits(codec, RT3261_REC_L2_MIXER,
RT3261_M_BST4_RM_L, 0);
snd_soc_update_bits(codec, RT3261_REC_R2_MIXER,
return 0;
}
-#endif
//bard 8-9 e
-void hp_amp_power(struct snd_soc_codec *codec, int on)
+void rt3261_hp_amp_power(struct snd_soc_codec *codec, int on)
{
static int hp_amp_power_count;
- printk("hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
+ DBG("rt3261_hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
// dump_reg(codec);
if(on) {
if(hp_amp_power_count <= 0) {
snd_soc_update_bits(codec, RT3261_PWR_DIG1,
RT3261_PWR_I2S1, RT3261_PWR_I2S1);
/* depop parameters */
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
+ snd_soc_write(codec, RT3261_DEPOP_M2, 0x3100); //bard 4-22
+ snd_soc_write(codec, RT3261_DEPOP_M1, 0x0009); //bard 4-22
+ msleep(50);
+/*
snd_soc_update_bits(codec, RT3261_DEPOP_M2,
RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_CP_MASK | RT3261_HP_SG_MASK | RT3261_HP_CB_MASK,
RT3261_HP_CP_PU | RT3261_HP_SG_DIS | RT3261_HP_CB_PU);
+*/
rt3261_index_write(codec, RT3261_HP_DCC_INT1, 0x9f00);
/* headphone amp power on */
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA , //bard 10-18
RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA); //bard 10-18
- msleep(50);
+ msleep(30); //bard 4-22
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_FV1 | RT3261_PWR_FV2,
RT3261_PWR_FV1 | RT3261_PWR_FV2);
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_CO_MASK | RT3261_HP_SG_MASK,
RT3261_HP_CO_EN | RT3261_HP_SG_EN);
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
}
hp_amp_power_count++;
} else {
if(ucontrol->value.integer.value[0]) {
/* headphone unmute sequence */
+
snd_soc_update_bits(codec, RT3261_DEPOP_M3,
RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK,
(RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ1_SFT) |
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK,
RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
- snd_soc_update_bits(codec, RT3261_HP_VOL,
- RT3261_L_MUTE | RT3261_R_MUTE, 0);
- msleep(100);
+ //snd_soc_update_bits(codec, RT3261_HP_VOL,
+ // RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
+ msleep(60); //bard 4-22
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK |
RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS |
*/
snd_soc_update_bits(codec, RT3261_HP_VOL,
RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
- msleep(30);
+ msleep(60);
+/*
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_R_SMT_MASK | RT3261_HP_L_SMT_MASK,
RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS);
+*/
}
return 0;
}
return 0;
}
+#else
+static int rt3261_modem_input_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
#endif
static int rt3261_dacr_sel_get(struct snd_kcontrol *kcontrol,
static const char *rt3261_dmic_mode[] = {"Disable", "DMIC1", "DMIC2"};
static const SOC_ENUM_SINGLE_DECL(rt3261_dmic_enum, 0, 0, rt3261_dmic_mode);
+/* ASRC */
+static const char *rt3261_asrc_mode[] = {"Disable", "Enable"};
+
+static const SOC_ENUM_SINGLE_DECL(rt3261_asrc_enum, 0, 0, rt3261_asrc_mode);
/* PR-3F */
static const char *rt3261_dacr_sel_mode[] = {"IF2_DAC", "IF2_ADC"};
//bard 8-9 s
-#if 0
static const char *rt3261_mic_mode[] = {"off", "on",};
-
static const SOC_ENUM_SINGLE_DECL(rt3261_mic_enum, 0, 0, rt3261_mic_mode);
-#endif
//bard 8-9 e
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
RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0,
rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv),
/* Headphone Output Volume */
+/*
SOC_DOUBLE("HP Playback Switch", RT3261_HP_VOL,
RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1),
+*/
SOC_DOUBLE_EXT_TLV("Headphone Playback Volume", RT3261_HP_VOL,
- RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_HP_VOL_RSCL_RANGE, 0,
+ RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0,
rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv),
/* OUTPUT Control */
SOC_DOUBLE("OUT Playback Switch", RT3261_OUTPUT,
/* DMIC */
SOC_ENUM_EXT("DMIC Switch", rt3261_dmic_enum,
rt3261_dmic_get, rt3261_dmic_put),
-
+ /* ASRC */
+ SOC_ENUM_EXT("ASRC Switch", rt3261_asrc_enum,
+ rt3261_asrc_get, rt3261_asrc_put),
/* PR-3F */
SOC_ENUM_EXT("DACR Select", rt3261_dacr_sel_enum,
rt3261_dacr_sel_get, rt3261_dacr_sel_put),
},
#endif
//bard 8-9 s
-#if 0
SOC_SINGLE_TLV("Main Mic Capture Volume", RT3261_IN1_IN2,
RT3261_BST_SFT1, 8, 0, bst_tlv),
SOC_SINGLE_TLV("Headset Mic Capture Volume", RT3261_IN3_IN4,
rt3261_mic1_get, rt3261_mic1_put),
SOC_ENUM_EXT("Headset Mic Capture Switch", rt3261_mic_enum,
rt3261_mic2_get, rt3261_mic2_put),
-#endif
//bard 8-9 e
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
SOC_ENUM("ADC IF1 Data Switch", rt3261_if1_adc_enum),
SOC_ENUM("DAC IF1 Data Switch", rt3261_if1_dac_enum),
static int rt3261_adc_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- struct snd_soc_codec *codec = w->codec;
- unsigned int val, mask;
+ //struct snd_soc_codec *codec = w->codec;
+ //unsigned int val, mask;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
//rt3261_index_update_bits(codec,
// RT3261_CHOP_DAC_ADC, 0x1000, 0x1000);
+ /*bard 3-26 r
val = snd_soc_read(codec, RT3261_MONO_ADC_MIXER);
mask = RT3261_M_MONO_ADC_L1 | RT3261_M_MONO_ADC_L2 |
RT3261_M_MONO_ADC_R1 | RT3261_M_MONO_ADC_R2;
if ((val & mask) ^ mask)
snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
RT3261_M_MAMIX_L | RT3261_M_MAMIX_R, 0);
+ */
break;
case SND_SOC_DAPM_POST_PMD:
+ /*bard 3-26 r
snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
RT3261_M_MAMIX_L | RT3261_M_MAMIX_R,
RT3261_M_MAMIX_L | RT3261_M_MAMIX_R);
+ */
//rt3261_index_update_bits(codec,
// RT3261_CHOP_DAC_ADC, 0x1000, 0x0000);
break;
return 0;
}
+//bard 3-26 s
+static int rt3261_mono_adcl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ //unsigned int val, mask;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+ RT3261_M_MAMIX_L, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+ RT3261_M_MAMIX_L,
+ RT3261_M_MAMIX_L);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt3261_mono_adcr_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ //unsigned int val, mask;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+ RT3261_M_MAMIX_R, 0);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+ RT3261_M_MAMIX_R,
+ RT3261_M_MAMIX_R);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+//bard 3-26 e
static int rt3261_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
{
#if 0
/* depop parameters */
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
snd_soc_update_bits(codec, RT3261_DEPOP_M2,
RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_CO_MASK | RT3261_HP_SG_MASK,
RT3261_HP_CO_EN | RT3261_HP_SG_EN);
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
#else
- hp_amp_power(codec, 1);
+ rt3261_hp_amp_power(codec, 1);
#endif
/* headphone unmute sequence */
snd_soc_update_bits(codec, RT3261_DEPOP_M3,
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK,
RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
+ //msleep(30);
snd_soc_update_bits(codec, RT3261_HP_VOL,
RT3261_L_MUTE | RT3261_R_MUTE, 0);
- msleep(100);
+ msleep(30); //bard 4-22
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK |
RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS |
RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
/*bard 10-18 r
snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET,
- RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS);
- msleep(90);
- */
+ RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS);*/
+ //msleep(90);
snd_soc_update_bits(codec, RT3261_HP_VOL,
RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
msleep(30);
RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA,
0);
#else
- hp_amp_power(codec, 0);
+ rt3261_hp_amp_power(codec, 0);
#endif
}
#else //one bit
static void rt3261_pmu_depop(struct snd_soc_codec *codec)
{
/* depop parameters */
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
snd_soc_update_bits(codec, RT3261_DEPOP_M2,
RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_CP_MASK | RT3261_HP_SG_MASK,
RT3261_HP_CP_PD | RT3261_HP_SG_EN);
+ rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
msleep(10);
snd_soc_update_bits(codec, RT3261_HP_VOL,
RT3261_L_MUTE | RT3261_R_MUTE, 0);
snd_soc_update_bits(codec, RT3261_HP_VOL,
RT3261_L_MUTE | RT3261_R_MUTE,
RT3261_L_MUTE | RT3261_R_MUTE);
- msleep(90);
snd_soc_update_bits(codec, RT3261_DEPOP_M1,
RT3261_HP_CB_MASK, RT3261_HP_CB_PD);
- msleep(30);
//rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0);
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
-
switch (event) {
case SND_SOC_DAPM_POST_PMU:
rt3261_pmu_depop(codec);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
- hp_amp_power(codec,1);
+ rt3261_hp_amp_power(codec,1);
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_LM, RT3261_PWR_LM); //bard 10-18
snd_soc_update_bits(codec, RT3261_OUTPUT,
RT3261_L_MUTE | RT3261_R_MUTE);
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_LM, 0); //bard 10-18
- hp_amp_power(codec,0);
+ rt3261_hp_amp_power(codec,0);
break;
default:
return 0;
}
+//bard 8-29 s
+static int rt3261_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if( rt3261->asrc_en == RT3261_ASRC_EN)
+ rt3261_update_eqmode(codec, 2);//BT_VOIP
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ rt3261_update_eqmode(codec, 0);//NORMAL
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+//bard 8-29 e
static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT3261_PWR_ANLG2,
RT3261_PWR_PLL_BIT, 0, NULL, 0),
SND_SOC_DAPM_PGA("INR VOL", RT3261_PWR_VOL,
RT3261_PWR_IN_R_BIT, 0, NULL, 0),
/* IN Mux */
+/*
SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt3261_inl_mux),
SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt3261_inr_mux),
+*/
/* REC Mixer */
SND_SOC_DAPM_MIXER("RECMIXL", RT3261_PWR_MIXER, RT3261_PWR_RM_L_BIT, 0,
rt3261_rec_l_mix, ARRAY_SIZE(rt3261_rec_l_mix)),
rt3261_sto_adc_r_mix, ARRAY_SIZE(rt3261_sto_adc_r_mix)),
SND_SOC_DAPM_SUPPLY("mono left filter", RT3261_PWR_DIG2,
RT3261_PWR_ADC_MF_L_BIT, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
- rt3261_mono_adc_l_mix, ARRAY_SIZE(rt3261_mono_adc_l_mix)),
+ SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
+ rt3261_mono_adc_l_mix, ARRAY_SIZE(rt3261_mono_adc_l_mix),
+ rt3261_mono_adcl_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26
SND_SOC_DAPM_SUPPLY("mono right filter", RT3261_PWR_DIG2,
RT3261_PWR_ADC_MF_R_BIT, 0, NULL, 0),
- SND_SOC_DAPM_MIXER("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
- rt3261_mono_adc_r_mix, ARRAY_SIZE(rt3261_mono_adc_r_mix)),
+ SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
+ rt3261_mono_adc_r_mix, ARRAY_SIZE(rt3261_mono_adc_r_mix),
+ rt3261_mono_adcr_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26
/* IF2 Mux */
SND_SOC_DAPM_MUX("IF2 ADC L Mux", SND_SOC_NOPM, 0, 0,
&rt3261_if2_adc_r_mux),
/* Digital Interface */
- SND_SOC_DAPM_SUPPLY("I2S1", RT3261_PWR_DIG1,
- RT3261_PWR_I2S1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("I2S1", SND_SOC_NOPM,
+ 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
/* Output Side */
/* DAC mixer before sound effect */
+#if 0 //org
SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix)),
SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix)),
+#else //bard 8-29
+ SND_SOC_DAPM_MIXER_E("DAC MIXL", SND_SOC_NOPM, 0, 0,
+ rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix),
+ rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_MIXER_E("DAC MIXR", SND_SOC_NOPM, 0, 0,
+ rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix),
+ rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+#endif
/* DAC2 channel Mux */
SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
static int get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+ struct snd_soc_codec *codec = rt3261_codec;
+ struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
if (sclk <= 0 || rate <= 0)
return -EINVAL;
-
+//bard 8-29 s
+ if (rt3261->asrc_en)
+ return 1;
+//bard 8-29 e
rate = rate << 8;
for (i = 0; i < ARRAY_SIZE(pd); i++)
if (sclk == rate * pd[i])
pre_div << RT3261_I2S_PD1_SFT;
snd_soc_update_bits(codec, RT3261_I2S1_SDP,
RT3261_I2S_DL_MASK, val_len);
- snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
+ //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
}
if (dai_sel & RT3261_U_IF2) {
- mask_clk = RT3261_I2S_BCLK_MS2_MASK | RT3261_I2S_PD2_MASK;
- val_clk = bclk_ms << RT3261_I2S_BCLK_MS2_SFT |
+ mask_clk |= RT3261_I2S_BCLK_MS2_MASK | RT3261_I2S_PD2_MASK;
+ val_clk |= bclk_ms << RT3261_I2S_BCLK_MS2_SFT |
pre_div << RT3261_I2S_PD2_SFT;
snd_soc_update_bits(codec, RT3261_I2S2_SDP,
RT3261_I2S_DL_MASK, val_len);
- snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
+ //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
}
+ if (rt3261->asrc_en)
+ snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114);
+ else
+ snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
return 0;
}
if (freq == rt3261->sysclk && clk_id == rt3261->sysclk_src)
return 0;
+ snd_soc_update_bits(codec, RT3261_PWR_ANLG2, RT3261_PWR_PLL, RT3261_PWR_PLL);
switch (clk_id) {
case RT3261_SCLK_S_MCLK:
break;
case SND_SOC_BIAS_PREPARE:
- /* headphone mute sequence */
- snd_soc_update_bits(codec, RT3261_DEPOP_M3,
- RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK,
- (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ1_SFT) |
- (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) |
- (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ3_SFT));
- rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00);
- snd_soc_update_bits(codec, RT3261_DEPOP_M1,
- RT3261_HP_SG_MASK, RT3261_HP_SG_EN);
- snd_soc_update_bits(codec, RT3261_DEPOP_M1,
- RT3261_RSTP_MASK, RT3261_RSTP_EN);
- snd_soc_update_bits(codec, RT3261_DEPOP_M1,
- RT3261_RSTP_MASK | RT3261_HP_L_SMT_MASK |
- RT3261_HP_R_SMT_MASK, RT3261_RSTP_DIS |
- RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
-
- snd_soc_update_bits(codec, RT3261_HP_VOL,
- RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
- msleep(30);
- snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);
-
+ //snd_soc_update_bits(codec, RT3261_HP_VOL,
+ // RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); //bard 12-7
snd_soc_update_bits(codec, RT3261_SPK_VOL,
RT3261_L_MUTE | RT3261_R_MUTE,
RT3261_L_MUTE | RT3261_R_MUTE);
RT3261_PWR_FV1 | RT3261_PWR_FV2,
RT3261_PWR_FV1 | RT3261_PWR_FV2);
snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3701);
+ snd_soc_update_bits(codec, RT3261_PWR_ANLG2,
+ RT3261_PWR_MB1 | RT3261_PWR_MB2,
+ RT3261_PWR_MB1 | RT3261_PWR_MB2);
codec->cache_only = false;
codec->cache_sync = 1;
snd_soc_cache_sync(codec);
break;
case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);
- snd_soc_write(codec, RT3261_DEPOP_M2, 0x1100);
+ //snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);//bard 4-22 r
+ //snd_soc_write(codec, RT3261_DEPOP_M2, 0x1100);//bard 4-22 r
snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3700);
snd_soc_write(codec, RT3261_PWR_DIG1, 0x0000);
snd_soc_write(codec, RT3261_PWR_DIG2, 0x0000);
return 0;
}
-
-static int rt3261_proc_init(void);
-
static int rt3261_probe(struct snd_soc_codec *codec)
{
struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
int ret;
- struct clk *iis_clk;
-
+#ifdef RTK_IOCTL
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+ struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
+#endif
+#endif
#if defined (CONFIG_SND_SOC_RT3224)
pr_info("Codec driver version %s, in fact you choose rt3224, no dsp!\n", VERSION);
#else
return ret;
}
codec->write = rt3261_write;
-
- #ifdef RT3261_PROC
- rt3261_proc_init();
- #endif
- #if defined (CONFIG_SND_SOC_RT5623)
+ #if 0//defined (CONFIG_SND_SOC_RT5623)
+ struct clk *iis_clk;
//for rt5623 MCLK use
- iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
+ iis_clk = clk_get_sys("rk_i2s.2", "i2s");
if (IS_ERR(iis_clk)) {
- printk("failed to get i2s clk\n");
+ DBG("failed to get i2s clk\n");
ret = PTR_ERR(iis_clk);
}else{
- printk("I2S2 got i2s clk ok!\n");
+ DBG("I2S2 got i2s clk ok!\n");
clk_enable(iis_clk);
clk_set_rate(iis_clk, 11289600);
rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK);
}
#endif
- rt3261_reset(codec);
+ ret=rt3261_reset(codec);
+ if (ret < 0)
+ {
+ return -ENODEV;
+ }
snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
RT3261_PWR_VREF1 | RT3261_PWR_MB |
RT3261_PWR_BG | RT3261_PWR_VREF2,
RT3261_PWR_HP_L | RT3261_PWR_HP_R,
0<<7 | 0<<6 );
rt3261_reg_init(codec);
+ rt3261_customer_redefine(codec, rt3261);
codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
rt3261->codec = codec;
- snd_soc_add_controls(codec, rt3261_snd_controls,
+ snd_soc_add_codec_controls(codec, rt3261_snd_controls,
ARRAY_SIZE(rt3261_snd_controls));
snd_soc_dapm_new_controls(&codec->dapm, rt3261_dapm_widgets,
ARRAY_SIZE(rt3261_dapm_widgets));
#ifdef RTK_IOCTL
#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
- struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
ioctl_ops->index_write = rt3261_index_write;
ioctl_ops->index_read = rt3261_index_read;
ioctl_ops->index_update_bits = rt3261_index_update_bits;
return ret;
}
rt3261_codec = codec;
+
return 0;
}
}
#ifdef CONFIG_PM
-static int rt3261_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int rt3261_suspend(struct snd_soc_codec *codec)
{
#if defined (CONFIG_SND_SOC_RT3261)
/* After opening LDO of DSP, then close LDO of codec.
* (3) DSP IIS interface power off
* (4) Toggle pin of codec LDO1 to power off
*/
- rt3261_dsp_suspend(codec, state);
+ rt3261_dsp_suspend(codec);
#endif
rt3261_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
};
MODULE_DEVICE_TABLE(i2c, rt3261_i2c_id);
-static int __devinit rt3261_i2c_probe(struct i2c_client *i2c,
+#ifdef CONFIG_OF
+/*
+dts:
+ rt3261: rt3261@1c {
+ compatible = "rt3261";
+ reg = <0x1c>;
+ codec-en-gpio = <&gpio3 GPIO_D7 GPIO_ACTIVE_HIGH>;
+ spk-num= <2>;
+ modem-input-mode = <1>;
+ lout-to-modem_mode = <1>;
+ spk-amplify = <2>;
+ playback-if1-data_control = <0>;
+ playback-if2-data_control = <0>;
+ };
+*/
+
+static int rt3261_parse_dt_property(struct device *dev,
+ struct rt3261_priv *rt3261)
+{
+ struct device_node *node = dev->of_node;
+ int ret;
+ enum of_gpio_flags flags;
+
+ DBG("%s()\n", __FUNCTION__);
+
+ if (!node)
+ return -ENODEV;
+
+ rt3261->codec_en_gpio = of_get_named_gpio_flags(node, "codec-en-gpio", 0, &flags);
+ if (rt3261->codec_en_gpio <= 0) {
+ DBG("%s() Can not read property codec-en-gpio\n", __FUNCTION__);
+ } else {
+ ret = devm_gpio_request(dev, rt3261->codec_en_gpio, "codec_en_gpio");
+ if(ret){
+ printk("%s() codec_en_gpio request ERROR", __FUNCTION__);
+ return ret;
+ }
+ ret = gpio_direction_output(rt3261->codec_en_gpio , !flags);
+ if(ret){
+ printk("%s() codec_en_gpio set ERROR", __FUNCTION__);
+ return ret;
+ }
+ }
+
+ ret = of_property_read_u32(node, "spk-num", &rt3261->spk_num);
+ if (ret < 0) {
+ DBG("%s() Can not read property spk-num\n", __FUNCTION__);
+ rt3261->spk_num = TWO_SPK;
+ }
+
+ ret = of_property_read_u32(node, "modem-input-mode", &rt3261->modem_input_mode);
+ if (ret < 0) {
+ DBG("%s() Can not read property modem-input-mode\n", __FUNCTION__);
+ rt3261->modem_input_mode = DIFFERENTIAL;
+ }
+
+ ret = of_property_read_u32(node, "lout-to-modem-mode", &rt3261->lout_to_modem_mode);
+ if (ret < 0) {
+ DBG("%s() Can not read property lout-to-modem-mode\n", __FUNCTION__);
+ rt3261->lout_to_modem_mode = DIFFERENTIAL;
+ }
+
+ ret = of_property_read_u32(node, "spk-amplify", &rt3261->spk_amplify);
+ if (ret < 0) {
+ DBG("%s() Can not read property spk-amplify\n", __FUNCTION__);
+ rt3261->spk_amplify = SPK_AMPLIFY_ZERO_POINT_SIX_WATT;
+ }
+
+ ret = of_property_read_u32(node, "playback-if1-data-control", &rt3261->playback_if1_data_control);
+ if (ret < 0) {
+ DBG("%s() Can not read property playback-if1-data-control\n", __FUNCTION__);
+ rt3261->playback_if1_data_control = LR_NORMAL;
+ }
+
+ ret = of_property_read_u32(node, "playback-if2-data-control", &rt3261->playback_if2_data_control);
+ if (ret < 0) {
+ DBG("%s() Can not read property playback-if2-data-control\n", __FUNCTION__);
+ rt3261->playback_if1_data_control = LR_NORMAL;
+ }
+ return 0;
+}
+#else
+static int rt3261_parse_dt_property(struct device *dev,
+ struct rt3261_priv *rt3261)
+{
+ return -ENOSYS;
+}
+#endif //#ifdef CONFIG_OF
+
+static int rt3261_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rt3261_priv *rt3261;
int ret;
- struct rt3261_platform_data *pdata = pdata = i2c->dev.platform_data;
+ char reg;
- rt3261 = kzalloc(sizeof(struct rt3261_priv), GFP_KERNEL);
+ reg = RT3261_VENDOR_ID;
+ ret = i2c_master_recv(i2c, ®, 1);
+ if (ret < 0){
+ printk("rt3261 && rt3224 probe error\n");
+ return ret;
+ }
+
+ rt3261 = devm_kzalloc(&i2c->dev,sizeof(struct rt3261_priv), GFP_KERNEL);
if (NULL == rt3261)
return -ENOMEM;
+ rt3261->i2c = i2c;
- rt3261->codec_en_gpio = pdata->codec_en_gpio;
- rt3261->io_init = pdata->io_init;
-
- 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);
+ ret = rt3261_parse_dt_property(&i2c->dev, rt3261);
+ if (ret < 0) {
+ printk("%s() parse device tree property error %d\n", __FUNCTION__, ret);
+ return ret;
+ }
#if defined (CONFIG_SND_SOC_RT5623)
rt3261->modem_is_open = 0;
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt3261,
rt3261_dai, ARRAY_SIZE(rt3261_dai));
- if (ret < 0)
- kfree(rt3261);
return ret;
}
-static int __devexit rt3261_i2c_remove(struct i2c_client *i2c)
+static int rt3261_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_codec(&i2c->dev);
kfree(i2c_get_clientdata(i2c));
.owner = THIS_MODULE,
},
.probe = rt3261_i2c_probe,
- .remove = __devexit_p(rt3261_i2c_remove),
+ .remove = rt3261_i2c_remove,
.shutdown = rt3261_i2c_shutdown,
.id_table = rt3261_i2c_id,
};
MODULE_DESCRIPTION("ASoC RT3261 driver");
MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
MODULE_LICENSE("GPL");
-
-
-#ifdef RT3261_PROC
-
-static ssize_t rt3261_proc_write(struct file *file, const char __user *buffer,
- unsigned long len, void *data)
-{
- char *cookie_pot;
- char *p;
- int reg;
- int i;
- int value;
- #if defined (CONFIG_SND_SOC_RT3261)
- struct rt3261_dsp_param param;
- #endif
-
- 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 'r':
- case 'R':
- printk("Read reg debug\n");
- if(cookie_pot[1] ==':')
- {
- strsep(&cookie_pot,":");
- while((p=strsep(&cookie_pot,",")))
- {
- reg = simple_strtol(p,NULL,16);
- value = rt3261_read(rt3261_codec,reg);
- printk("rt3261_read:0x%04x = 0x%04x\n",reg,value);
- }
- printk("\n");
- }
- else
- {
- printk("Error Read reg debug.\n");
- printk("For example: echo r:22,23,24,25>rt3261_ts\n");
- }
- break;
- case 'w':
- case 'W':
- printk("Write reg debug\n");
- if(cookie_pot[1] ==':')
- {
- strsep(&cookie_pot,":");
- while((p=strsep(&cookie_pot,"=")))
- {
- reg = simple_strtol(p,NULL,16);
- p=strsep(&cookie_pot,",");
- value = simple_strtol(p,NULL,16);
- rt3261_write(rt3261_codec,reg,value);
- printk("rt3261_write:0x%04x = 0x%04x\n",reg,value);
- }
- printk("\n");
- }
- else
- {
- printk("Error Write reg debug.\n");
- printk("For example: w:22=0,23=0,24=0,25=0>rt3261_ts\n");
- }
- break;
- case 'a':
- printk("Dump rt3261 index reg \n");
-
- for (i = 0; i < 0xb4; i++)
- {
- value = rt3261_index_read(rt3261_codec, i);
- printk("rt3261_index_read:0x%04x = 0x%04x\n",i,value);
- }
- break;
- #if defined (CONFIG_SND_SOC_RT3261)
- case 'b':
- param.cmd_fmt = 0x00e0;
- param.cmd = RT3261_DSP_CMD_MW;
- printk("Write dsp reg debug\n");
- if(cookie_pot[1] ==':')
- {
- strsep(&cookie_pot,":");
- while((p=strsep(&cookie_pot,"=")))
- {
- param.addr = simple_strtol(p,NULL,16);
- p=strsep(&cookie_pot,",");
- param.data = simple_strtol(p,NULL,16);
- rt3261_dsp_write(rt3261_codec,¶m);
- printk("rt3261_dsp_write:0x%04x = 0x%04x\n",param.addr,param.data);
- }
- printk("\n");
- }
- break;
- case 'c':
- printk("Read dsp reg debug\n");
- if(cookie_pot[1] ==':')
- {
- strsep(&cookie_pot,":");
- while((p=strsep(&cookie_pot,",")))
- {
- reg = simple_strtol(p,NULL,16);
- value = rt3261_dsp_read(rt3261_codec,reg);
- printk("rt3261_dsp_read:0x%04x = 0x%04x\n",reg,value);
- }
- printk("\n");
- }
- break;
- #endif
- default:
- printk("Help for rt3261_ts .\n-->The Cmd list: \n");
- printk("-->'d&&D' Open or Off the debug\n");
- printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>rt3261_ts\n");
- printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rt3261_ts\n");
- break;
- }
-
- return len;
-}
-
-static const struct file_operations rt3261_proc_fops = {
- .owner = THIS_MODULE,
-};
-
-static int rt3261_proc_init(void)
-{
- struct proc_dir_entry *rt3261_proc_entry;
- rt3261_proc_entry = create_proc_entry("driver/rt3261_ts", 0777, NULL);
- if(rt3261_proc_entry != NULL)
- {
- rt3261_proc_entry->write_proc = rt3261_proc_write;
- return 0;
- }
- else
- {
- printk("create proc error !\n");
- return -1;
- }
-}
-#endif