+/*
+ * rt5625.c -- RT5625 ALSA SoC audio codec driver
+ *
+ * Copyright 2011 Realtek Semiconductor Corp.
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
-#include <linux/jiffies.h>
-#include <asm/delay.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 <asm/div64.h>
#include "rt5625.h"
-#if REALTEK_HWDEP
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-
+#define RT5625_PROC
+#ifdef RT5625_PROC
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/vmalloc.h>
+char debug_write_read = 0;
#endif
-#if 0
+#if 1
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...) do { } while (0)
#endif
-#define AUDIO_NAME "rt5625"
-#define RT5625_VERSION "0.03 alsa 1.0.21"
-#define ALSA_SOC_VERSION "1.0.21"
+static struct snd_soc_codec *rt5625_codec;
-#define RT5625_EQ_FUNC_ENA 0
+#define RT5625_REG_RW 1 /* for debug */
+//#define RT5625_DEMO 1 /* only for demo; please remove it */
-static void hp_depop_mode2(struct snd_soc_codec *codec);
-static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute);
+#define RT5625_F_SMT_PHO
+#define RT5625_PLY_BIT 0
+#define RT5625_PLY_MASK (0x1)
+#define RT5625_REC_BIT 1
+#define RT5625_REC_MASK (0x1 << RT5625_REC_BIT)
+#define RT5625_3G_BIT 2
+#define RT5625_3G_MASK (0x1 << RT5625_3G_BIT)
+#define RT5625_BT_BIT 3
+#define RT5625_BT_MASK (0x1 << RT5625_BT_BIT)
+#define RT5625_VOIP_BIT 4
+#define RT5625_VOIP_MASK (0x1 << RT5625_VOIP_BIT)
struct rt5625_priv {
unsigned int stereo_sysclk;
unsigned int voice_sysclk;
-};
-struct rt5625_init_reg {
- u8 reg_index;
- u16 reg_value;
+ int vodsp_fun;
+#ifdef RT5625_F_SMT_PHO
+ int app_bmp;/* bit{0, 1, 2, 3, 4} = {play, rec, 3g, bt, voip} */
+ int pll_sel;
+ int pll2_sel;
+ int dac_active;
+ int adc_active;
+ int headset;
+ int vodsp_fun_bak;
+#endif
};
-static struct rt5625_init_reg rt5625_init_list[] = {
-
- {RT5625_HP_OUT_VOL , 0x8888}, //default is -12db
- {RT5625_SPK_OUT_VOL , 0x8080}, //default is 0db
- {RT5625_DAC_AND_MIC_CTRL , 0xee03}, //DAC to hpmixer
- {RT5625_OUTPUT_MIXER_CTRL , 0x0748}, //all output from hpmixer
- {RT5625_MIC_CTRL , 0x0500}, //mic boost 20db
- {RT5625_ADC_REC_MIXER , 0x3f3f}, //record source from mic1
- {RT5625_GEN_CTRL_REG1 , 0x0c0a}, //speaker vdd ratio is 1
- {RT5625_ADC_REC_GAIN , 0xd5d5}, //gain 15db of ADC by default
-
+#ifdef RT5625_F_SMT_PHO
+static u16 rt5625_voip_back[][2] = {
+ {RT5625_VODSP_PDM_CTL, 0x0000},
+ {RT5625_F_DAC_ADC_VDAC, 0x0000},
};
+#define RT5625_VOIP_BK_NUM \
+ (sizeof(rt5625_voip_back) / sizeof(rt5625_voip_back[0]))
+#endif
-#define RT5625_INIT_REG_NUM ARRAY_SIZE(rt5625_init_list)
-
-#if (RT5625_EQ_FUNC_ENA==1)
-//*************************************************************************************************
-//eq table
-//*************************************************************************************************
-enum
-{
- NORMAL=0,
- CLUB,
- DANCE,
- LIVE,
- POP,
- ROCK,
- OPPO,
- TREBLE,
- BASS
+#ifdef RT5625_DEMO
+struct rt5625_init_reg {
+ u8 reg;
+ u16 val;
};
-typedef struct _HW_EQ_PRESET
-{
- u16 HwEqType;
- u16 EqValue[14];
- u16 HwEQCtrl;
-
-}HW_EQ_PRESET;
-
-
-HW_EQ_PRESET HwEq_Preset[]={
-/* 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0x6e*/
- {NORMAL,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x0000},
- {CLUB ,{0x1C10,0x0000,0xC1CC,0x1E5D,0x0699,0xCD48,0x188D,0x0699,0xC3B6,0x1CD0,0x0699,0x0436,0x0000},0x800E},
- {DANCE ,{0x1F2C,0x095B,0xC071,0x1F95,0x0616,0xC96E,0x1B11,0xFC91,0xDCF2,0x1194,0xFAF2,0x0436,0x0000},0x800F},
- {LIVE ,{0x1EB5,0xFCB6,0xC24A,0x1DF8,0x0E7C,0xC883,0x1C10,0x0699,0xDA41,0x1561,0x0295,0x0436,0x0000},0x800F},
- {POP ,{0x1EB5,0xFCB6,0xC1D4,0x1E5D,0x0E23,0xD92E,0x16E6,0xFCB6,0x0000,0x0969,0xF988,0x0436,0x0000},0x800F},
- {ROCK ,{0x1EB5,0xFCB6,0xC071,0x1F95,0x0424,0xC30A,0x1D27,0xF900,0x0C5D,0x0FC7,0x0E23,0x0436,0x0000},0x800F},
- {OPPO ,{0x0000,0x0000,0xCA4A,0x17F8,0x0FEC,0xCA4A,0x17F8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x800F},
- {TREBLE,{0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x188D,0x1699},0x8010},
- {BASS ,{0x1A43,0x0C00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},0x8001},
-
+static struct rt5625_init_reg init_list[] = {
+ {RT5625_HP_OUT_VOL , 0x8888}, //default is -12db
+ {RT5625_SPK_OUT_VOL , 0x8080}, //default is 0db
+ {RT5625_PHONEIN_VOL , 0xe800}, //phone differential
+ {RT5625_DAC_MIC_CTRL , 0xee01}, //DAC to hpmixer & spkmixer
+ {RT5625_OUTMIX_CTRL , 0x2bc8}, //spk from spkmixer; hp from hpmixer; aux from monomixer; classAB
+ {RT5625_ADC_REC_MIXER , 0x1f1f}, //record source from mic1 & mic2
+ {RT5625_GEN_CTRL1 , 0x0c08}, //speaker vdd ratio is 1; 1.25VDD ratio
};
+#define RT5625_INIT_REG_LEN ARRAY_SIZE(init_list)
+static int rt5625_reg_init(struct snd_soc_codec *codec)
+{
+ int i;
+ for (i = 0; i < RT5625_INIT_REG_LEN; i++)
+ snd_soc_write(codec, init_list[i].reg, init_list[i].val);
+ return 0;
+}
#endif
-//*************************************************************************************************
-//*************************************************************************************************
-
-/*
- * bit[0] for linein playback switch
- * bit[1] phone
- * bit[2] mic1
- * bit[3] mic2
- * bit[4] vopcm
- *
- */
-#define HPL_MIXER 0x80
-#define HPR_MIXER 0x82
-static unsigned int reg80 = 0, reg82 = 0;
-/*
- * bit[0][1][2] use for aec control
- * bit[3] for none
- * bit[4] for SPKL pga
- * bit[5] for SPKR pga
- * bit[6] for hpl pga
- * bit[7] for hpr pga
- * bit[8] for dump dsp
- * bit[12~15] for eq function
- */
- #define VIRTUAL_REG_FOR_MISC_FUNC 0x84
-static unsigned int reg84 = 0;
-
-
-static const u16 rt5625_reg[] = {
- 0x59b4, 0x8080, 0x8080, 0x8080, /*reg00-reg06*/
- 0xc800, 0xe808, 0x1010, 0x0808, /*reg08-reg0e*/
- 0xe0ef, 0xcbcb, 0x7f7f, 0x0000, /*reg10-reg16*/
- 0xe010, 0x0000, 0x8008, 0x2007, /*reg18-reg1e*/
- 0x0000, 0x0000, 0x00c0, 0xef00, /*reg20-reg26*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*reg28-reg2e*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*reg30-reg36*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*reg38-reg3e*/
- 0x0c0a, 0x0000, 0x0000, 0x0000, /*reg40-reg46*/
- 0x0029, 0x0000, 0xbe3e, 0x3e3e, /*reg48-reg4e*/
- 0x0000, 0x0000, 0x803a, 0x0000, /*reg50-reg56*/
- 0x0000, 0x0009, 0x0000, 0x3000, /*reg58-reg5e*/
- 0x3075, 0x1010, 0x3110, 0x0000, /*reg60-reg66*/
- 0x0553, 0x0000, 0x0000, 0x0000, /*reg68-reg6e*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*reg70-reg76*/
- 0x0000, 0x0000, 0x0000, 0x0000, /*reg78-reg7e*/
+static const u16 rt5625_reg[0x80] = {
+ [RT5625_RESET] = 0x59b4,
+ [RT5625_SPK_OUT_VOL] = 0x8080,
+ [RT5625_HP_OUT_VOL] = 0x8080,
+ [RT5625_AUX_OUT_VOL] = 0x8080,
+ [RT5625_PHONEIN_VOL] = 0xc800,
+ [RT5625_LINE_IN_VOL] = 0xe808,
+ [RT5625_DAC_VOL] = 0x1010,
+ [RT5625_MIC_VOL] = 0x0808,
+ [RT5625_DAC_MIC_CTRL] = 0xee0f,
+ [RT5625_ADC_REC_GAIN] = 0xcbcb,
+ [RT5625_ADC_REC_MIXER] = 0x7f7f,
+ [RT5625_VDAC_OUT_VOL] = 0xe010,
+ [RT5625_OUTMIX_CTRL] = 0x8008,
+ [RT5625_VODSP_CTL] = 0x2007,
+ [RT5625_DMIC_CTRL] = 0x00c0,
+ [RT5625_PD_CTRL] = 0xef00,
+ [RT5625_GEN_CTRL1] = 0x0c0a,
+ [RT5625_LDO_CTRL] = 0x0029,
+ [RT5625_GPIO_CONFIG] = 0xbe3e,
+ [RT5625_GPIO_POLAR] = 0x3e3e,
+ [RT5625_GPIO_STATUS] = 0x803a,
+ [RT5625_SOFT_VOL_CTRL] = 0x0009,
+ [RT5625_DAC_CLK_CTRL1] = 0x3075,
+ [RT5625_DAC_CLK_CTRL2] = 0x1010,
+ [RT5625_VDAC_CLK_CTRL1] = 0x3110,
+ [RT5625_PS_CTRL] = 0x0553,
+ [RT5625_VENDOR_ID1] = 0x10ec,
+ [RT5625_VENDOR_ID2] = 0x5c02,
};
-
-Voice_DSP_Reg VODSP_AEC_Init_Value[]=
-{
+rt5625_dsp_reg rt5625_dsp_init[] = {
{0x232C, 0x0025},
{0x230B, 0x0001},
{0x2308, 0x007F},
{0x2304, 0x00FA},
{0x2305, 0x0500},
{0x2306, 0x4000},
- {0x230D, 0x0900},
+ {0x230D, 0x0300},
{0x230E, 0x0280},
{0x2312, 0x00B1},
{0x2314, 0xC000},
{0x2316, 0x0041},
- {0x2317, 0x2200},
- {0x2318, 0x0C00},
+ {0x2317, 0x2800},
+ {0x2318, 0x0800},
{0x231D, 0x0050},
{0x231F, 0x4000},
{0x2330, 0x0008},
{0x22D4, 0x2800},
{0x22D5, 0x3000},
{0x2399, 0x2800},
- {0x230C, 0x0000}, //to enable VODSP AEC function
+ {0x230C, 0x0000},
};
-
-
-#define SET_VODSP_REG_INIT_NUM ARRAY_SIZE(VODSP_AEC_Init_Value)
-static struct snd_soc_device *rt5625_socdev;
-
-static inline unsigned int rt5625_read_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- u16 *cache = codec->reg_cache;
-
- if (reg > 0x7e)
+#define RT5625_DSP_INIT_NUM ARRAY_SIZE(rt5625_dsp_init)
+
+static int rt5625_volatile_register(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ switch (reg) {
+ case RT5625_RESET:
+ case RT5625_PD_CTRL:
+ case RT5625_GPIO_STATUS:
+ case RT5625_OTC_STATUS:
+ case RT5625_PRIV_DATA:
+ case RT5625_EQ_CTRL:
+ case RT5625_DSP_DATA:
+ case RT5625_DSP_CMD:
+ case RT5625_VENDOR_ID1:
+ case RT5625_VENDOR_ID2:
+ return 1;
+ default:
return 0;
- return cache[reg / 2];
+ }
}
-
-static unsigned int rt5625_read_hw_reg(struct snd_soc_codec *codec, unsigned int reg)
-{
- u8 data[2] = {0};
- unsigned int value = 0x0;
-
- data[0] = reg;
-
- i2c_master_reg8_recv(codec->control_data,reg,data,2,100 * 1000);
-
- value = (data[0]<<8) | data[1];
-
- DBG(KERN_INFO "rt5625_read ok, reg = %x, value = %x\n", reg, value);
-
- return value;
+static int rt5625_readable_register(
+ struct snd_soc_codec *codec, unsigned int reg)
+{
+ switch (reg) {
+ case RT5625_RESET:
+ case RT5625_SPK_OUT_VOL:
+ case RT5625_HP_OUT_VOL:
+ case RT5625_AUX_OUT_VOL:
+ case RT5625_PHONEIN_VOL:
+ case RT5625_LINE_IN_VOL:
+ case RT5625_DAC_VOL:
+ case RT5625_MIC_VOL:
+ case RT5625_DAC_MIC_CTRL:
+ case RT5625_ADC_REC_GAIN:
+ case RT5625_ADC_REC_MIXER:
+ case RT5625_VDAC_OUT_VOL:
+ case RT5625_VODSP_PDM_CTL:
+ case RT5625_OUTMIX_CTRL:
+ case RT5625_VODSP_CTL:
+ case RT5625_MIC_CTRL:
+ case RT5625_DMIC_CTRL:
+ case RT5625_PD_CTRL:
+ case RT5625_F_DAC_ADC_VDAC:
+ case RT5625_SDP_CTRL:
+ case RT5625_EXT_SDP_CTRL:
+ case RT5625_PWR_ADD1:
+ case RT5625_PWR_ADD2:
+ case RT5625_PWR_ADD3:
+ case RT5625_GEN_CTRL1:
+ case RT5625_GEN_CTRL2:
+ case RT5625_PLL_CTRL:
+ case RT5625_PLL2_CTRL:
+ case RT5625_LDO_CTRL:
+ case RT5625_GPIO_CONFIG:
+ case RT5625_GPIO_POLAR:
+ case RT5625_GPIO_STICKY:
+ case RT5625_GPIO_WAKEUP:
+ case RT5625_GPIO_STATUS:
+ case RT5625_GPIO_SHARING:
+ case RT5625_OTC_STATUS:
+ case RT5625_SOFT_VOL_CTRL:
+ case RT5625_GPIO_OUT_CTRL:
+ case RT5625_MISC_CTRL:
+ case RT5625_DAC_CLK_CTRL1:
+ case RT5625_DAC_CLK_CTRL2:
+ case RT5625_VDAC_CLK_CTRL1:
+ case RT5625_PS_CTRL:
+ case RT5625_PRIV_INDEX:
+ case RT5625_PRIV_DATA:
+ case RT5625_EQ_CTRL:
+ case RT5625_DSP_ADDR:
+ case RT5625_DSP_DATA:
+ case RT5625_DSP_CMD:
+ case RT5625_VENDOR_ID1:
+ case RT5625_VENDOR_ID2:
+ return 1;
+ default:
+ return 0;
+ }
}
-
-static unsigned int rt5625_read(struct snd_soc_codec *codec, unsigned int reg)
+static unsigned int rt5625_read(struct snd_soc_codec *codec,
+ unsigned int reg)
{
- if ((reg == 0x80)
- || (reg == 0x82)
- || (reg == 0x84))
- return (reg == 0x80) ? reg80 : ((reg == 0x82) ? reg82 : reg84);
-
- return rt5625_read_hw_reg(codec, reg);
-}
+ unsigned int val;
-
-static inline void rt5625_write_reg_cache(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value)
-{
- u16 *cache = codec->reg_cache;
- if (reg > 0x7E)
- return;
- cache[reg / 2] = value;
+ val = codec->hw_read(codec, reg);
+ return val;
}
static int rt5625_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
+ unsigned int val;
u8 data[3];
- unsigned int *regvalue = NULL;
data[0] = reg;
- data[1] = (value & 0xff00) >> 8;
- data[2] = value & 0x00ff;
+ data[1] = (value >> 8) & 0xff;
+ data[2] = value & 0xff;
- if ((reg == 0x80)
- || (reg == 0x82)
- || (reg == 0x84))
- {
- regvalue = ((reg == 0x80) ? ®80 : ((reg == 0x82) ? ®82 : ®84));
- *regvalue = value;
- DBG("rt5625_write ok, reg = %x, value = %x\n", reg, value);
- return 0;
- }
- rt5625_write_reg_cache(codec, reg, value);
-
- if (codec->hw_write(codec->control_data, data, 3) == 3)
- {
- DBG("rt5625_write ok, reg = %x, value = %x\n", reg, value);
- return 0;
- }
- else
- {
- printk("rt5625_write fail\n");
- return -EIO;
- }
+ val = codec->hw_write(codec->control_data, data, 3);
+ return val;
}
-int rt5625_write_mask(struct snd_soc_codec *codec, unsigned int reg,unsigned int value,unsigned int mask)
+static int rt5625_reset(struct snd_soc_codec *codec)
{
-
- unsigned char RetVal=0;
- unsigned int CodecData;
-
- DBG("rt5625_write_mask ok, reg = %x, value = %x ,mask= %x\n", reg, value,mask);
+ return snd_soc_write(codec, RT5625_RESET, 0);
+}
- if(!mask)
- return 0;
+/**
+ * rt5625_index_write - Write private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ * @value: Private register Data.
+ *
+ * Modify private register for advanced setting. It can be written through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_index_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ int ret;
- if(mask!=0xffff)
- {
- CodecData=rt5625_read(codec,reg);
- CodecData&=~mask;
- CodecData|=(value&mask);
- RetVal=rt5625_write(codec,reg,CodecData);
- }
- else
- {
- RetVal=rt5625_write(codec,reg,value);
+ ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_PRIV_DATA, value);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private value: %d\n", ret);
+ goto err;
}
+ return 0;
- return RetVal;
+err:
+ return ret;
}
-
-void rt5625_write_index(struct snd_soc_codec *codec, unsigned int reg,
- unsigned int value)
+/**
+ * rt5625_index_read - Read private register.
+ * @codec: SoC audio codec device.
+ * @reg: Private register index.
+ *
+ * Read advanced setting from private register. It can be read through
+ * private index (0x6a) and data (0x6c) register.
+ *
+ * Returns private register value or negative error code.
+ */
+static unsigned int rt5625_index_read(
+ struct snd_soc_codec *codec, unsigned int reg)
{
-
- rt5625_write(codec,0x6a,reg);
- rt5625_write(codec,0x6c,value);
-}
+ int ret;
-unsigned int rt5625_read_index(struct snd_soc_codec *codec, unsigned int reg)
-{
- unsigned int value = 0x0;
- rt5625_write(codec,0x6a,reg);
- value=rt5625_read(codec,0x6c);
-
- return value;
+ ret = snd_soc_write(codec, RT5625_PRIV_INDEX, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set private addr: %d\n", ret);
+ return ret;
+ }
+ return snd_soc_read(codec, RT5625_PRIV_DATA);
}
-void rt5625_write_index_mask(struct snd_soc_codec *codec, unsigned int reg,unsigned int value,unsigned int mask)
+/**
+ * rt5625_index_update_bits - update private register bits
+ * @codec: Audio codec
+ * @reg: Private register index.
+ * @mask: Register mask
+ * @value: New value
+ *
+ * Writes new register value.
+ *
+ * Returns 1 for change, 0 for no change, or negative error code.
+ */
+static int rt5625_index_update_bits(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int mask, unsigned int value)
{
-
-// unsigned char RetVal=0;
- unsigned int CodecData;
-
- DBG("rt5625_write_index_mask ok, reg = %x, value = %x ,mask= %x\n", reg, value,mask);
+ unsigned int old, new;
+ int change, ret;
- if(!mask)
- return;
-
- if(mask!=0xffff)
- {
- CodecData=rt5625_read_index(codec,reg);
- CodecData&=~mask;
- CodecData|=(value&mask);
- rt5625_write_index(codec,reg,CodecData);
- }
- else
- {
- rt5625_write_index(codec,reg,value);
+ ret = rt5625_index_read(codec, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read private reg: %d\n", ret);
+ goto err;
}
-}
-//#define rt5625_write_mask(c, reg, value, mask) snd_soc_update_bits(c, reg, mask, value)
+ old = ret;
+ new = (old & ~mask) | (value & mask);
+ change = old != new;
+ if (change) {
+ ret = rt5625_index_write(codec, reg, new);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "Failed to write private reg: %d\n", ret);
+ goto err;
+ }
+ }
+ return change;
-#define rt5625_reset(c) rt5625_write(c, RT5625_RESET, 0)
+err:
+ return ret;
+}
-/*read/write dsp reg*/
-static int rt5625_wait_vodsp_i2c_done(struct snd_soc_codec *codec)
+/**
+ * rt5625_dsp_done - Wait until DSP is ready.
+ * @codec: SoC Audio Codec device.
+ *
+ * To check voice DSP status and confirm it's ready for next work.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_dsp_done(struct snd_soc_codec *codec)
{
- unsigned int checkcount = 0, vodsp_data;
+ unsigned int count = 0, dsp_val;
- vodsp_data = rt5625_read(codec, RT5625_VODSP_REG_CMD);
- while(vodsp_data & VODSP_BUSY)
- {
- if(checkcount > 10)
+ dsp_val = snd_soc_read(codec, RT5625_DSP_CMD);
+ while(dsp_val & RT5625_DSP_BUSY_MASK) {
+ if(count > 10)
return -EBUSY;
- vodsp_data = rt5625_read(codec, RT5625_VODSP_REG_CMD);
- checkcount ++;
+ dsp_val = snd_soc_read(codec, RT5625_DSP_CMD);
+ count ++;
}
+
return 0;
}
-static int rt5625_write_vodsp_reg(struct snd_soc_codec *codec, unsigned int vodspreg, unsigned int value)
+/**
+ * rt5625_dsp_write - Write DSP register.
+ * @codec: SoC audio codec device.
+ * @reg: DSP register index.
+ * @value: DSP register Data.
+ *
+ * Modify voice DSP register for sound effect. The DSP can be controlled
+ * through DSP addr (0x70), data (0x72) and cmd (0x74) register. It has
+ * to wait until the DSP is ready.
+ *
+ * Returns 0 for success or negative error code.
+ */
+static int rt5625_dsp_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
{
- int ret = 0;
-
- if(ret != rt5625_wait_vodsp_i2c_done(codec))
- return -EBUSY;
+ int ret;
- rt5625_write(codec, RT5625_VODSP_REG_ADDR, vodspreg);
- rt5625_write(codec, RT5625_VODSP_REG_DATA, value);
- rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_WRITE_ENABLE | VODSP_CMD_MW);
+ ret = rt5625_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_DATA, value);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP data reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_CMD,
+ RT5625_DSP_W_EN | RT5625_DSP_CMD_MW);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
mdelay(10);
- return ret;
+ return 0;
+err:
+ return ret;
}
-static unsigned int rt5625_read_vodsp_reg(struct snd_soc_codec *codec, unsigned int vodspreg)
+/**
+ * rt5625_dsp_read - Read DSP register.
+ * @codec: SoC audio codec device.
+ * @reg: DSP register index.
+ *
+ * Read DSP setting value from voice DSP. The DSP can be controlled
+ * through DSP addr (0x70), data (0x72) and cmd (0x74) register. Each
+ * command has to wait until the DSP is ready.
+ *
+ * Returns DSP register value or negative error code.
+ */
+static unsigned int rt5625_dsp_read(
+ struct snd_soc_codec *codec, unsigned int reg)
{
+ unsigned int val_h, val_l;
int ret = 0;
- unsigned int nDataH, nDataL;
- unsigned int value;
- if(ret != rt5625_wait_vodsp_i2c_done(codec))
- return -EBUSY;
-
- rt5625_write(codec, RT5625_VODSP_REG_ADDR, vodspreg);
- rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_MR);
+ ret = rt5625_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_ADDR, reg);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_CMD,
+ RT5625_DSP_R_EN | RT5625_DSP_CMD_MR);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+
+ /* Read DSP high byte data */
+ ret = rt5625_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x26);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_CMD,
+ RT5625_DSP_R_EN | RT5625_DSP_CMD_RR);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+ ret = rt5625_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_read(codec, RT5625_DSP_DATA);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
+ goto err;
+ }
+ val_h = ret;
- if (ret != rt5625_wait_vodsp_i2c_done(codec))
- return -EBUSY;
- rt5625_write(codec, RT5625_VODSP_REG_ADDR, 0x26);
- rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_RR);
+ /* Read DSP low byte data */
+ ret = snd_soc_write(codec, RT5625_DSP_ADDR, 0x25);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP addr reg: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_write(codec, RT5625_DSP_CMD,
+ RT5625_DSP_R_EN | RT5625_DSP_CMD_RR);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to write DSP cmd reg: %d\n", ret);
+ goto err;
+ }
+ ret = rt5625_dsp_done(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "DSP is busy: %d\n", ret);
+ goto err;
+ }
+ ret = snd_soc_read(codec, RT5625_DSP_DATA);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to read DSP data reg: %d\n", ret);
+ goto err;
+ }
+ val_l = ret;
- if(ret != rt5625_wait_vodsp_i2c_done(codec))
- return -EBUSY;
- nDataH = rt5625_read(codec, RT5625_VODSP_REG_DATA);
- rt5625_write(codec, RT5625_VODSP_REG_ADDR, 0x25);
- rt5625_write(codec, RT5625_VODSP_REG_CMD, VODSP_READ_ENABLE | VODSP_CMD_RR);
+ return ((val_h & 0xff) << 8) |(val_l & 0xff);
- if(ret != rt5625_wait_vodsp_i2c_done(codec))
- return -EBUSY;
- nDataL = rt5625_read(codec, RT5625_VODSP_REG_DATA);
- value = ((nDataH & 0xff) << 8) |(nDataL & 0xff);
- DBG("%s vodspreg=0x%x, value=0x%x\n", __func__, vodspreg, value);
- return value;
+err:
+ return ret;
}
-static int rt5625_reg_init(struct snd_soc_codec *codec)
-{
- int i;
+/* ADCR function select */
+static const char *adcr_fun_sel[] = {
+ "Stereo ADC", "Voice ADC", "VoDSP", "PDM Slave"};
- for (i = 0; i < RT5625_INIT_REG_NUM; i++)
- rt5625_write(codec, rt5625_init_list[i].reg_index, rt5625_init_list[i].reg_value);
+static const struct soc_enum adcr_fun_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCR_F_SFT,
+ ARRAY_SIZE(adcr_fun_sel), adcr_fun_sel);
- return 0;
-}
+/* ADCL function select */
+static const char *adcl_fun_sel[] = {"Stereo ADC", "VoDSP"};
-//*************************************************************************************************
-//*************************************************************************************************
-#if (RT5625_EQ_FUNC_ENA==1)
-//eq function
-static void rt5625_update_eqmode(struct snd_soc_codec *codec, int mode)
-{
- u16 HwEqIndex=0;
+static const struct soc_enum adcl_fun_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_ADCL_F_SFT,
+ ARRAY_SIZE(adcl_fun_sel), adcl_fun_sel);
- if(mode==NORMAL)
- {
- /*clear EQ parameter*/
- for(HwEqIndex=0;HwEqIndex<=0x0C;HwEqIndex++)
- {
- rt5625_write_index(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]);
- }
-
- rt5625_write_mask(codec, 0x6e,0x0,EN_HW_EQ_BLK | EN_HW_EQ_HPF | EN_HW_EQ_BP3 | EN_HW_EQ_BP2 | EN_HW_EQ_BP1 | EN_HW_EQ_LPF); /*disable EQ block*/
- }
- else
- {
- /*Fill EQ parameter*/
- for(HwEqIndex=0;HwEqIndex<=0x0C;HwEqIndex++)
- {
- rt5625_write_index(codec, HwEqIndex, HwEq_Preset[mode].EqValue[HwEqIndex]);
- }
+/* Voice DSP */
+static const char *rt5625_aec_fun[] = {"Disable", "Enable"};
- //enable EQ block
- rt5625_write_mask(codec, 0x6e,HwEq_Preset[mode].HwEQCtrl,EN_HW_EQ_BLK | EN_HW_EQ_HPF | EN_HW_EQ_BP3 | EN_HW_EQ_BP2 | EN_HW_EQ_BP1 | EN_HW_EQ_LPF);
-
- //update EQ parameter
- rt5625_write_mask(codec, 0x6e,0x0080,0x0080);
- }
-}
+static const SOC_ENUM_SINGLE_DECL(rt5625_aec_fun_enum, 0, 0, rt5625_aec_fun);
+static const char *rt5625_dsp_lrck[] = {"8KHz", "16KHz"};
-static int rt5625_eq_sel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 Virtual_reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
- int rt5625_mode=((Virtual_reg)&0xf000)>>12;
-
- if ( rt5625_mode == ucontrol->value.integer.value[0])
- return 0;
+static const SOC_ENUM_SINGLE_DECL(rt5625_dsp_lrck_enum,
+ RT5625_VODSP_CTL, RT5625_DSP_LRCK_SFT, rt5625_dsp_lrck);
- rt5625_update_eqmode(codec, ucontrol->value.enumerated.item[0]);
+static const char *rt5625_bp_ctrl[] = {"Bypass", "Normal"};
- Virtual_reg &= 0x0fff;
- Virtual_reg |= (ucontrol->value.integer.value[0])<<12;
- rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, Virtual_reg);
-
- return 0;
-}
-#endif
-//*************************************************************************************************
-//*************************************************************************************************
-static const char *rt5625_aec_path_sel[] = {"aec func disable","aec func for pcm in/out",
- "aec func for iis in/out","aec func for analog in/out"}; /*0*/
-static const char *rt5625_spk_out_sel[] = {"Class AB", "Class D"}; /*1*/
-static const char *rt5625_spk_l_source_sel[] = {"LPRN", "LPRP", "LPLN", "MM"}; /*2*/
-static const char *rt5625_spkmux_source_sel[] = {"VMID", "HP Mixer",
- "SPK Mixer", "Mono Mixer"}; /*3*/
-static const char *rt5625_hplmux_source_sel[] = {"VMID","HPL Mixer"}; /*4*/
-static const char *rt5625_hprmux_source_sel[] = {"VMID","HPR Mixer"}; /*5*/
-static const char *rt5625_auxmux_source_sel[] = {"VMID", "HP Mixer",
- "SPK Mixer", "Mono Mixer"}; /*6*/
-static const char *rt5625_spkamp_ratio_sel[] = {"2.25 Vdd", "2.00 Vdd",
- "1.75 Vdd", "1.50 Vdd", "1.25 Vdd", "1.00 Vdd"}; /*7*/
-static const char *rt5625_mic1_boost_sel[] = {"Bypass", "+20db", "+30db", "+40db"}; /*8*/
-static const char *rt5625_mic2_boost_sel[] = {"Bypass", "+20db", "+30db", "+40db"}; /*9*/
-static const char *rt5625_dmic_boost_sel[] = {"Bypass", "+6db", "+12db", "+18db",
- "+24db", "+30db", "+36db", "+42db"}; /*10*/
-static const char *rt5625_adcr_func_sel[] = {"Stereo ADC", "Voice ADC",
- "VoDSP Interface", "PDM Slave Interface"}; /*11*/
-#if (RT5625_EQ_FUNC_ENA==1)
-static const char *rt5625_eq_sel[] = {"NORMAL", "CLUB","DANCE", "LIVE","POP", /*12*/
- "ROCK", "OPPO", "TREBLE", "BASS"};
-#endif
+static const SOC_ENUM_SINGLE_DECL(rt5625_bp_ctrl_enum,
+ RT5625_VODSP_CTL, RT5625_DSP_BP_SFT, rt5625_bp_ctrl);
-static const struct soc_enum rt5625_enum[] = {
-
-SOC_ENUM_SINGLE(VIRTUAL_REG_FOR_MISC_FUNC, 0, 4, rt5625_aec_path_sel), /*0*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 13, 2, rt5625_spk_out_sel), /*1*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 14, 4, rt5625_spk_l_source_sel), /*2*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 10, 4, rt5625_spkmux_source_sel),/*3*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 9, 2, rt5625_hplmux_source_sel), /*4*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 8, 2, rt5625_hprmux_source_sel),/*5*/
-SOC_ENUM_SINGLE(RT5625_OUTPUT_MIXER_CTRL, 6, 4, rt5625_auxmux_source_sel),/*6*/
-SOC_ENUM_SINGLE(RT5625_GEN_CTRL_REG1, 1, 6, rt5625_spkamp_ratio_sel), /*7*/
-SOC_ENUM_SINGLE(RT5625_MIC_CTRL, 10, 4, rt5625_mic1_boost_sel), /*8*/
-SOC_ENUM_SINGLE(RT5625_MIC_CTRL, 8, 4, rt5625_mic2_boost_sel), /*9*/
-SOC_ENUM_SINGLE(RT5625_DMIC_CTRL, 0, 8, rt5625_dmic_boost_sel), /*10*/
-SOC_ENUM_SINGLE(RT5625_DAC_ADC_VODAC_FUN_SEL, 4, 4, rt5625_adcr_func_sel), /*11*/
-#if (RT5625_EQ_FUNC_ENA==1)
-SOC_ENUM_SINGLE(VIRTUAL_REG_FOR_MISC_FUNC, 12, 9, rt5625_eq_sel), /*EQ mode select mode 12*/
-#endif
-};
+static const char *rt5625_pd_ctrl[] = {"Power down", "Normal"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_pd_ctrl_enum,
+ RT5625_VODSP_CTL, RT5625_DSP_PD_SFT, rt5625_pd_ctrl);
+
+static const char *rt5625_rst_ctrl[] = {"Reset", "Normal"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_rst_ctrl_enum,
+ RT5625_VODSP_CTL, RT5625_DSP_RST_SFT, rt5625_rst_ctrl);
+/* Speaker */
+static const char *rt5625_spk_out[] = {"Class AB", "Class D"};
+static const SOC_ENUM_SINGLE_DECL(rt5625_spk_out_enum,
+ RT5625_OUTMIX_CTRL, RT5625_SPK_T_SFT, rt5625_spk_out);
+static const char *rt5625_spkl_src[] = {"LPRN", "LPRP", "LPLN", "MM"};
-//*****************************************************************************
-//function:Enable the Voice PCM interface Path
-//*****************************************************************************
-static int ConfigPcmVoicePath(struct snd_soc_codec *codec,unsigned int bEnableVoicePath,unsigned int mode)
+static const SOC_ENUM_SINGLE_DECL(rt5625_spkl_src_enum,
+ RT5625_OUTMIX_CTRL, RT5625_SPKN_S_SFT, rt5625_spkl_src);
+
+static const char *rt5625_spkamp_ratio[] = {"2.25 Vdd", "2.00 Vdd",
+ "1.75 Vdd", "1.50 Vdd", "1.25 Vdd", "1.00 Vdd"};
+
+static const SOC_ENUM_SINGLE_DECL(rt5625_spkamp_ratio_enum,
+ RT5625_GEN_CTRL1, RT5625_SPK_R_SFT, rt5625_spkamp_ratio);
+
+/* Output/Input Mode */
+//static const char *rt5625_auxout_mode[] = {"Differential", "Single ended"};
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_auxout_mode_enum,
+// RT5625_OUTMIX_CTRL, RT5625_AUXOUT_MODE_SFT, rt5625_auxout_mode);
+
+//static const char *rt5625_input_mode[] = {"Single ended", "Differential"};
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_phone_mode_enum,
+// RT5625_PHONEIN_VOL, RT5625_PHO_DIFF_SFT, rt5625_input_mode);
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_mic1_mode_enum,
+// RT5625_MIC_VOL, RT5625_MIC1_DIFF_SFT, rt5625_input_mode);
+
+//static const SOC_ENUM_SINGLE_DECL(rt5625_mic2_mode_enum,
+// RT5625_MIC_VOL, RT5625_MIC2_DIFF_SFT, rt5625_input_mode);
+
+static int rt5625_adcr_fun_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val, mask, bitmask;
- if(bEnableVoicePath)
- {
- //Power on DAC reference
- rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD1,PWR_DAC_REF|PWR_VOICE_DF2SE,PWR_DAC_REF|PWR_VOICE_DF2SE);
- //Power on Voice DAC/ADC
- rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD2,PWR_VOICE_CLOCK,PWR_VOICE_CLOCK);
- //routing voice to HPMixer
- rt5625_write_mask(codec,RT5625_VOICE_DAC_OUT_VOL,0,M_V_DAC_TO_HP_MIXER);
-
- switch(mode)
- {
- case PCM_SLAVE_MODE_B: //8kHz sampling rate,16 bits PCM mode and Slave mode,PCM mode is B,MCLK=24.576MHz from Oscillator.
- //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08C00000,PSKEY_FORMAT=0x0060
-
- //Enable GPIO 1,3,4,5 to voice interface
- //Set I2S to Slave mode
- //Voice I2S SYSCLK Source select Main SYSCLK
- //Set voice I2S VBCLK Polarity to Invert
- //Set Data length to 16 bit
- //set Data Fomrat to PCM mode B
- //the register 0x36 value's should is 0xC083
- rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0xC083);
-
- //Set LRCK voice select divide 32
- //set voice blck select divide 6 and 8
- //voice filter clock divide 3 and 16
- //the register 0x64 value's should is 0x5524
- rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-
- break;
+ for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+ ;
+ if (ucontrol->value.enumerated.item[0] > e->max - 1)
+ return -EINVAL;
+ val = ucontrol->value.enumerated.item[0] << e->shift_l;
+ mask = (bitmask - 1) << e->shift_l;
+
+ snd_soc_update_bits(codec, RT5625_PD_CTRL,
+ RT5625_PWR_PR0, RT5625_PWR_PR0);
+ if ((rt5625->app_bmp & RT5625_3G_MASK) &&
+ rt5625->vodsp_fun == RT5625_AEC_EN) {
+ snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM);
+ } else if (rt5625->app_bmp & RT5625_VOIP_MASK &&
+ rt5625->vodsp_fun == RT5625_AEC_EN) {
+ snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_PDM);
+ } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+ snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCR_F_VADC);
+ } else {
+ snd_soc_update_bits(codec, e->reg, mask, val);
+ }
+ snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0);
- case PCM_SLAVE_MODE_A: //8kHz sampling rate,16 bits PCM and Slave mode,PCM mode is A,MCLK=24.576MHz from Oscillator.
- //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08C00004,PSKEY_FORMAT=0x0060
-
- //Enable GPIO 1,3,4,5 to voice interface
- //Set I2S to Slave mode
- //Voice I2S SYSCLK Source select Main SYSCLK
- //Set voice i2s VBCLK Polarity to Invert
- //Set Data length to 16 bit
- //set Data Fomrat to PCM mode A
- //the register 0x36 value's should is 0xC082
- rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0xC082);
-
- //Set LRCK voice select divide 64
- //set voice blck select divide 6 and 8
- //voice filter clock divide 3 and 16
- //the register 0x64 value's should is 0x5524
- rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-
- break;
+ return 0;
+}
- case PCM_MASTER_MODE_B: //8kHz sampling rate,16 bits PCM and Master mode,PCM mode is B,Clock from PLL OUT
- //CSR PSKEY_PCM_CONFIG32 (HEX) = 0x08000002,PSKEY_FORMAT=0x0060
-
- //Enable GPIO 1,3,4,5 to voice interface
- //Set I2S to master mode
- //Set voice i2s VBCLK Polarity to Invert
- //Set Data length to 16 bit
- //set Data Fomrat to PCM mode B
- //the register 0x36 value's should is 0x8083
- rt5625_write(codec,RT5625_EXTEND_SDP_CTRL,0x8083);
-
- //Set LRCK voice select divide 64
- //set voice blck select divide 6 and 8
- //voice filter clock divide 3 and 16
- //the register 0x64 value's should is 0x5524
- rt5625_write(codec,RT5625_VOICE_DAC_PCMCLK_CTRL1,0x5524);
-
- break;
+static int rt5625_adcl_fun_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val, mask, bitmask;
- default:
- //do nothing
- break;
+ for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
+ ;
+ if (ucontrol->value.enumerated.item[0] > e->max - 1)
+ return -EINVAL;
+ val = ucontrol->value.enumerated.item[0] << e->shift_l;
+ mask = (bitmask - 1) << e->shift_l;
+
+ snd_soc_update_bits(codec, RT5625_PD_CTRL,
+ RT5625_PWR_PR0, RT5625_PWR_PR0);
+ if ((rt5625->app_bmp & RT5625_3G_MASK) &&
+ rt5625->vodsp_fun == RT5625_AEC_EN) {
+ snd_soc_update_bits(codec, e->reg, mask, RT5625_ADCL_F_DSP);
+ } else {
+ snd_soc_update_bits(codec, e->reg, mask, val);
+ }
+ snd_soc_update_bits(codec, RT5625_PD_CTRL, RT5625_PWR_PR0, 0);
- }
- }
- else
- {
- //Power down Voice Different to sing-end power
- rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD1,0,PWR_VOICE_DF2SE);
- //Power down Voice DAC/ADC
- rt5625_write_mask(codec,RT5625_PWR_MANAG_ADD2,0,PWR_VOICE_CLOCK);
- //Disable Voice PCM interface
- rt5625_write_mask(codec,RT5625_EXTEND_SDP_CTRL,0,EXT_I2S_FUNC_ENABLE);
- }
-
return 0;
}
-static int init_vodsp_aec(struct snd_soc_codec *codec)
+static int rt5625_init_vodsp_aec(struct snd_soc_codec *codec)
{
- int i;
- int ret = 0;
+ int i, ret = 0;
/*disable LDO power*/
- rt5625_write_mask(codec, RT5625_LDO_CTRL,0,LDO_ENABLE);
+ snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+ RT5625_LDO_MASK, RT5625_LDO_DIS);
mdelay(20);
- rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_NO_PD_MODE_ENA,VODSP_NO_PD_MODE_ENA);
+ snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+ RT5625_DSP_PD_MASK, RT5625_DSP_PD_NOR);
/*enable LDO power and set output voltage to 1.2V*/
- rt5625_write_mask(codec, RT5625_LDO_CTRL,LDO_ENABLE|LDO_OUT_VOL_CTRL_1_20V,LDO_ENABLE|LDO_OUT_VOL_CTRL_MASK);
+ snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+ RT5625_LDO_MASK | RT5625_LDO_VC_MASK,
+ RT5625_LDO_EN | RT5625_LDO_VC_1_20V);
mdelay(20);
/*enable power of VODSP I2C interface*/
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD3, RT5625_P_DSP_IF |
+ RT5625_P_DSP_I2C, RT5625_P_DSP_IF | RT5625_P_DSP_I2C);
mdelay(1);
- rt5625_write_mask(codec, RT5625_VODSP_CTL,0,VODSP_NO_RST_MODE_ENA); /*Reset VODSP*/
+ /*Reset VODSP*/
+ snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+ RT5625_DSP_RST_MASK, RT5625_DSP_RST_EN);
mdelay(1);
- rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_NO_RST_MODE_ENA,VODSP_NO_RST_MODE_ENA); /*set VODSP to non-reset status*/
+ /*set VODSP to non-reset status*/
+ snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+ RT5625_DSP_RST_MASK, RT5625_DSP_RST_NOR);
mdelay(20);
/*initize AEC paramter*/
- for(i = 0; i < SET_VODSP_REG_INIT_NUM; i++)
- {
- ret = rt5625_write_vodsp_reg(codec, VODSP_AEC_Init_Value[i].VoiceDSPIndex,VODSP_AEC_Init_Value[i].VoiceDSPValue);
+ for(i = 0; i < RT5625_DSP_INIT_NUM; i++) {
+ ret = rt5625_dsp_write(codec, rt5625_dsp_init[i].index,
+ rt5625_dsp_init[i].value);
if(ret)
return -EIO;
}
-
- schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+ mdelay(10);
+ //printk("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C));
return 0;
}
-//***********************************************************************************************
-//function:Enable/Disable the vodsp interface Path
-//For system clock only suport specific clock,realtek suggest customer to use 24.576Mhz or 22.5792Mhz
-//clock fro MCLK(MCLK=48k*512 or 44.1k*512Mhz)
-//***********************************************************************************************
-static int set_vodsp_aec_path(struct snd_soc_codec *codec, unsigned int mode)
+static int rt5625_aec_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- switch(mode)
- {
-
- case PCM_IN_PCM_OUT:
- //set PCM format
- ConfigPcmVoicePath(codec,1,PCM_MASTER_MODE_B);
- //set AEC path
- rt5625_write_mask(codec, 0x26,0x0300,0x0300);
- rt5625_write_mask(codec, RT5625_VODSP_PDM_CTL,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_VOICE|VOICE_PCM_S_SEL_AEC_TXDP
- ,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|VOICE_PCM_S_SEL_MASK);
- rt5625_write_mask(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|VODAC_SOUR_SEL_VODSP_TXDC
- ,ADCR_FUNC_SEL_MASK|VODAC_SOUR_SEL_MASK);
- rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_LRCK_SEL_8K,VODSP_LRCK_SEL_MASK);
- rt5625_write_mask(codec, 0x26,0x0000,0x0300);
- //set input&output path and power
- rt5625_write_mask(codec, 0x3a,0x0c8f,0x0c8f);//power on related bit
- rt5625_write_mask(codec, 0x3c,0xa4cb,0xa4cb);//power on related bit
- rt5625_write_mask(codec, 0x3e,0x3302,0xf302);//power on related bit
-
- rt5625_write(codec, 0x10, 0xee0f);//mute DAC to hpmixer
- rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
- rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
- rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
- rt5625_write(codec, 0x14, 0x7f3f);//Mic1->ADCMixer_R
- rt5625_write(codec, 0x18, 0xa010);//VoDAC to speakerMixer,0db
- rt5625_write(codec, 0x1c, 0x8808);//speaker source from speakermixer
-
- rt5625_write_mask(codec, 0x02,0x0000,0x8080); //unmute speaker
+ ucontrol->value.integer.value[0] = rt5625->vodsp_fun;
+ return 0;
+}
- break;
-
-
- case ANALOG_IN_ANALOG_OUT:
- rt5625_write_mask(codec, 0x26,0x0300,0x0300);
- rt5625_write_mask(codec, RT5625_VODSP_PDM_CTL,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_ADCL|VOICE_PCM_S_SEL_AEC_TXDP
- ,VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|VOICE_PCM_S_SEL_MASK);
- rt5625_write_mask(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|VODAC_SOUR_SEL_VODSP_TXDC|DAC_FUNC_SEL_VODSP_TXDP|ADCL_FUNC_SEL_VODSP
- ,ADCR_FUNC_SEL_MASK|VODAC_SOUR_SEL_MASK|DAC_FUNC_SEL_MASK|ADCL_FUNC_SEL_MASK);
- rt5625_write_mask(codec, RT5625_VODSP_CTL,VODSP_LRCK_SEL_16K,VODSP_LRCK_SEL_MASK);
- rt5625_write_mask(codec, 0x26,0x0000,0x0300);
- //set input&output path and power
- rt5625_write_mask(codec, 0x3a,0xcc8f,0xcc8f);//power on related bit
- rt5625_write_mask(codec, 0x3c,0xa7cf,0xa7cf);//power on related bit
- rt5625_write_mask(codec, 0x3e,0xf312,0xf312);//power on related bit
-
- rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
- rt5625_write(codec, 0x08, 0xe800);//set phone in to differential mode
- rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
- rt5625_write(codec, 0x14, 0x773f);//Mic1->ADCMixer_R,phone in-->ADCMixer_L
- rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
- rt5625_write(codec, 0x1c, 0x88c8);//speaker from spkmixer,monoOut from monoMixer
- rt5625_write(codec, 0x18, 0xA010);//unmute VoDAC to spkmixer
- rt5625_write(codec, 0x10, 0xee0e);//unmute DAC to monoMixer
- rt5625_write(codec, 0x62, 0x2222);
- rt5625_write(codec, 0x64, 0x3122);
- rt5625_write_mask(codec, 0x02,0x0000,0x8080); //unmute speaker
- rt5625_write_mask(codec, 0x06,0x0000,0x8080); //unmute auxout
- break;
- case DAC_IN_ADC_OUT:
- rt5625_write_mask(codec, 0x26,0x0300,0x0300);
- rt5625_write_mask(codec,RT5625_DAC_ADC_VODAC_FUN_SEL,ADCR_FUNC_SEL_PDM|DAC_FUNC_SEL_VODSP_TXDC
- ,ADCR_FUNC_SEL_MASK|DAC_FUNC_SEL_MASK);
- rt5625_write_mask(codec,RT5625_VODSP_PDM_CTL,VODSP_SRC1_PWR|VODSP_SRC2_PWR|VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_SRC1|REC_S_SEL_SRC2,
- VODSP_SRC1_PWR|VODSP_SRC2_PWR|VODSP_RXDP_PWR|VODSP_RXDP_S_SEL_MASK|REC_S_SEL_MASK);
- rt5625_write_mask(codec,RT5625_VODSP_CTL,VODSP_LRCK_SEL_16K,VODSP_LRCK_SEL_MASK);
- rt5625_write_mask(codec, 0x26,0x0000,0x0300);
- //set input&output path and power
- rt5625_write_mask(codec, 0x3a,0xcc0f,0xcc0f);//power on related bit
- rt5625_write_mask(codec, 0x3c,0xa7cb,0xa7cb);//power on related bit
- rt5625_write_mask(codec, 0x3e,0x3302,0x3302);//power on related bit
-
- rt5625_write(codec, 0x0e, 0x8808);//set Mic1 to differential mode
- rt5625_write(codec, 0x22, 0x0000);//Mic boost 0db
- rt5625_write(codec, 0x14, 0x7f3f);//Mic1->ADCMixer_R
- rt5625_write(codec, 0x12, 0xCBD3);//ADC_Mixer_R boost 10.5 db
- rt5625_write(codec, 0x1c, 0x8808);//speaker out from spkMixer
- rt5625_write(codec, 0x10, 0xee0d);//unmute DAC to spkMixer
- rt5625_write(codec, 0x60, 0x3075);
- rt5625_write(codec, 0x62, 0x1010);
- rt5625_write_mask(codec, 0x02,0x0000,0x8080); //unmute speaker
+static int rt5625_aec_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- break;
+ if(ucontrol->value.integer.value[0] == rt5625->vodsp_fun)
+ return 0;
+ rt5625->vodsp_fun = ucontrol->value.integer.value[0];
- case VODSP_AEC_DISABLE:
- default:
- rt5625_write_mask(codec, 0x02,0x8080,0x8080);//mute speaker out
- rt5625_write_mask(codec, 0x06,0x8080,0x8080);//mute auxout
- rt5625_write(codec, 0x22, 0x0500);//Mic boost 20db by default
- rt5625_write(codec, 0x14, 0x3f3f);//record from Mic1 by default
- rt5625_write(codec, 0x12, 0xD5D5);//ADC_Mixer_R boost 15 db by default
- rt5625_write(codec, 0x1c, 0x0748);//all output from HPmixer by default
- rt5625_write(codec, 0x10, 0xee03);//DAC to HPmixer by default
- rt5625_write(codec, 0x18, 0xe010);//mute VoDAC to mixer by default
- rt5625_write_mask(codec, 0x26,0x0300,0x0300);
- /*set stereo DAC&Voice DAC&Stereo ADC function select to default*/
- rt5625_write(codec, RT5625_DAC_ADC_VODAC_FUN_SEL,0);
- /*set VODSP&PDM Control to default*/
- rt5625_write(codec, RT5625_VODSP_PDM_CTL,0);
- rt5625_write_mask(codec, 0x26,0x0000,0x0300);
- rt5625_write_mask(codec, 0x3e,0x0000,0xf312);//power down related bit
- rt5625_write_mask(codec, 0x3a,0x0000,0xcc8d);//power down related bit
- rt5625_write_mask(codec, 0x3c,0x0000,0x07cf);//power down related bit
-
-
- break;
- }
+ switch(rt5625->vodsp_fun) {
+ case RT5625_AEC_EN:
+ break;
+ case RT5625_AEC_DIS:
+ if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+ ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+ snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+ RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+ RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0);
+ snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+ RT5625_LDO_MASK, RT5625_LDO_DIS);
+ }
+ break;
+ default:
+ break;
+ }
return 0;
}
-static int enable_vodsp_aec(struct snd_soc_codec *codec, unsigned int VodspAEC_En, unsigned int AEC_mode)
+#ifdef RT5625_F_SMT_PHO
+static int rt5625_app_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- int ret = 0;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
-
- if (VodspAEC_En != 0)
- {
+ pr_info("App status: %x\n", rt5625->app_bmp);
- //enable power of VODSP I2C interface & VODSP interface
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);
- //enable power of VODSP I2S interface
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1,PWR_I2S_INTERFACE,PWR_I2S_INTERFACE);
- //select input/output of VODSP AEC
- set_vodsp_aec_path(codec, AEC_mode);
+ return 0;
+}
+static int rt5625_cap_voip_chk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i, upd;
+
+ /* VoIP start up if record & playback all turn on, or AEC *
+ * is disabled. otherwise, cheat dapm. */
+ if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+ (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+ /* backup registers for voip routing */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ rt5625_voip_back[i][1] =
+ snd_soc_read(codec, rt5625_voip_back[i][0]);
+ /* cheat dapm */
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2);
+ return 0;
}
- else
- {
- //disable VODSP AEC path
- set_vodsp_aec_path(codec, VODSP_AEC_DISABLE);
- //set VODSP AEC to power down mode
- rt5625_write_mask(codec, RT5625_VODSP_CTL,0,VODSP_NO_PD_MODE_ENA);
- //disable power of VODSP I2C interface & VODSP interface
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3,0,PWR_VODSP_INTERFACE|PWR_I2C_FOR_VODSP);
+
+ if (rt5625->headset) {
+ /* backup registers for voip routing */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ rt5625_voip_back[i][1] =
+ snd_soc_read(codec, rt5625_voip_back[i][0]);
+ /* cheat dapm */
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_REC_IIS_S_MASK, RT5625_REC_IIS_S_SRC2);
+ } else
+ rt5625->vodsp_fun = RT5625_AEC_EN;
+
+ upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
}
- return ret;
+ return 0;
}
-static void rt5625_aec_config(struct snd_soc_codec *codec, unsigned int mode)
+static int rt5625_cap_voip_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- DBG("rt5625_aec_config %d\n",mode);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i;
- if (mode == VODSP_AEC_DISABLE)
- {
- enable_vodsp_aec(codec,0, mode);
- /*disable LDO power*/
- rt5625_write_mask(codec, RT5625_LDO_CTRL,0,LDO_ENABLE);
- }
- else
- {
- init_vodsp_aec(codec);
-
- enable_vodsp_aec(codec,1, mode);
+ if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+ if (rt5625->headset) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO);
+ /* recover all changes by voip */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ snd_soc_write(codec, rt5625_voip_back[i][0],
+ rt5625_voip_back[i][1]);
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+ } else {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO);
+ rt5625->vodsp_fun = RT5625_AEC_EN;
+ /* Mic1 & Mic2 boost 0db */
+ snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+ RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+ RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+ /* Capture volume gain 9db */
+ snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+ RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+ }
+ } else {
+ /* recover all changes by voip */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ snd_soc_write(codec, rt5625_voip_back[i][0],
+ rt5625_voip_back[i][1]);
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+ if (rt5625->app_bmp & RT5625_3G_MASK &&
+ rt5625->vodsp_fun == RT5625_AEC_EN) {
+ /* Mic1 boost 0db */
+ snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+ RT5625_MIC1_BST_MASK, RT5625_MIC1_BST_BYPASS);
+ /* Capture volume gain 9db */
+ snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+ RT5625_G_ADCR_MASK, 0x11);
+ }
}
-}
-//****************************************************************************************************************
-//*
-//*function:disable rt5625's function.
-//*
-//*
-//****************************************************************************************************************
-static int rt5625_func_aec_disable(struct snd_soc_codec *codec,int mode)
-{
- switch(mode)
- {
- case RT5625_AEC_PCM_IN_OUT:
- case RT5625_AEC_IIS_IN_OUT:
- case RT5625_AEC_ANALOG_IN_OUT:
-
- rt5625_aec_config(codec,VODSP_AEC_DISABLE); //disable AEC function and path
-
- break;
-
- default:
+ return 0;
+}
- break;
+static int rt5625_hs_voip_chk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i, upd;
+
+ rt5625->headset = true;
+ if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+ (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+ /* backup registers for voip routing */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ rt5625_voip_back[i][1] =
+ snd_soc_read(codec, rt5625_voip_back[i][0]);
+ rt5625->vodsp_fun_bak = rt5625->vodsp_fun;
+ /* cheat dapm */
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR, RT5625_REC_IIS_S_ADC);
+ return 0;
+ }
+
+ upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
}
return 0;
}
-
-static int rt5625_get_dsp_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int rt5625_hs_voip_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- /*cause we choose bit[0][1] to store the mode type*/
- int mode = (rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC)) & 0x03;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i;
+
+ if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO,
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_L_PHO);
+ /* Mic1 & Mic2 boost 0db */
+ snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+ RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+ RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+ /* Capture volume gain 9db */
+ snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+ RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+ } else {
+ /* recover all changes by voip */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ snd_soc_write(codec, rt5625_voip_back[i][0],
+ rt5625_voip_back[i][1]);
+ rt5625->vodsp_fun = rt5625->vodsp_fun_bak;
+ if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM);
+ } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC);
+ } else {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC);
+ }
+ }
- ucontrol->value.integer.value[0] = mode;
return 0;
}
-
-static int rt5625_set_dsp_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int rt5625_voip_chk_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- u16 Virtual_reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
- int rt5625_mode=(Virtual_reg)&0x03;
-
- DBG("rt5625_mode=%d,value[0]=%ld,Virtual_reg=%x\n",rt5625_mode,ucontrol->value.integer.value[0],Virtual_reg);
-
- if ( rt5625_mode == ucontrol->value.integer.value[0])
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i, upd;
+
+ rt5625->headset = false;
+ /* voip start-up if record is on-going; otherwise, cheat dapm */
+ if ((rt5625->app_bmp & RT5625_REC_MASK) == 0 ||
+ (rt5625->app_bmp & RT5625_PLY_MASK) == 0) {
+ /* backup registers for voip routing */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ rt5625_voip_back[i][1] =
+ snd_soc_read(codec, rt5625_voip_back[i][0]);
+ rt5625->vodsp_fun_bak = rt5625->vodsp_fun;
+ /* cheat dapm */
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_RXDP_S_MASK | RT5625_REC_IIS_S_MASK | RT5625_RXDP_PWR,
+ RT5625_RXDP_S_SRC1 | RT5625_REC_IIS_S_SRC2);
return 0;
+ }
- switch(ucontrol->value.integer.value[0])
- {
- case RT5625_AEC_PCM_IN_OUT:
-
- rt5625_aec_config(codec,PCM_IN_PCM_OUT);//enable AEC PCM in/out function and path
+ upd = (rt5625->app_bmp & ~RT5625_VOIP_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_VOIP_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_BT_MASK);
+ }
- break;
+ return 0;
+}
- case RT5625_AEC_IIS_IN_OUT:
+static int rt5625_voip_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int i;
- rt5625_aec_config(codec,DAC_IN_ADC_OUT);//enable AEC IIS in/out function and path
+ if (rt5625->app_bmp & RT5625_VOIP_MASK) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO,
+ RT5625_M_RM_R_MIC2 | RT5625_M_RM_L_PHO);
+ /* Mic1 & Mic2 boost 0db */
+ snd_soc_update_bits(codec, RT5625_MIC_CTRL,
+ RT5625_MIC1_BST_MASK | RT5625_MIC2_BST_MASK,
+ RT5625_MIC1_BST_BYPASS | RT5625_MIC2_BST_BYPASS);
+ /* Capture volume gain 9db */
+ snd_soc_update_bits(codec, RT5625_ADC_REC_GAIN,
+ RT5625_G_ADCL_MASK | RT5625_G_ADCR_MASK, (0x11 << 8 ) | 0x11);
+ } else {
+ /* recover all changes by voip */
+ for(i = 0; i < RT5625_VOIP_BK_NUM; i++)
+ snd_soc_write(codec, rt5625_voip_back[i][0],
+ rt5625_voip_back[i][1]);
+ rt5625->vodsp_fun = rt5625->vodsp_fun_bak;
+ snd_soc_update_bits(codec, RT5625_VODSP_PDM_CTL,
+ RT5625_SRC1_PWR | RT5625_SRC2_PWR, 0);
+ if ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->vodsp_fun == RT5625_AEC_EN) {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_PDM);
+ } else if (rt5625->app_bmp & RT5625_BT_MASK) {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_VADC);
+ } else {
+ snd_soc_update_bits(codec, RT5625_F_DAC_ADC_VDAC,
+ RT5625_ADCR_F_MASK, RT5625_ADCR_F_ADC);
+ }
+ }
- break;
+ return 0;
+}
- case RT5625_AEC_ANALOG_IN_OUT:
-
- rt5625_aec_config(codec,ANALOG_IN_ANALOG_OUT);//enable AEC analog in/out function and path
-
- break;
+static int rt5625_voip_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- case RT5625_AEC_DISABLE:
-
- rt5625_func_aec_disable(codec,rt5625_mode); //disable previous select function.
-
- break;
+ ucontrol->value.integer.value[0] =
+ (rt5625->app_bmp & RT5625_VOIP_MASK) >> RT5625_VOIP_BIT;
- default:
+ return 0;
+}
- break;
- }
+static int rt5625_play_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- Virtual_reg &= 0xfffc;
- Virtual_reg |= (ucontrol->value.integer.value[0]);
- rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, Virtual_reg);
+ ucontrol->value.integer.value[0] =
+ (rt5625->app_bmp & RT5625_PLY_MASK) >> RT5625_PLY_BIT;
- DBG("2rt5625_mode=%d,value[0]=%ld,Virtual_reg=%x\n",rt5625_mode,ucontrol->value.integer.value[0],Virtual_reg);
return 0;
}
-static int rt5625_dump_dsp_reg(struct snd_soc_codec *codec)
+static int rt5625_play_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- int i;
-
- rt5625_write_mask(codec, RT5625_VODSP_CTL, VODSP_NO_PD_MODE_ENA,VODSP_NO_PD_MODE_ENA);
- for (i = 0; i < SET_VODSP_REG_INIT_NUM; i++) {
- rt5625_read_vodsp_reg(codec, VODSP_AEC_Init_Value[i].VoiceDSPIndex);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int upd;
+
+ upd = (rt5625->app_bmp & ~RT5625_PLY_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_PLY_BIT);
+ if (rt5625->app_bmp != upd)
+ rt5625->app_bmp = upd;
+
+ if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+ ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO);
}
+
return 0;
}
-
-static int rt5625_dump_dsp_put(struct snd_kcontrol *kcontrol,
+static int rt5625_rec_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- int mode = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] =
+ (rt5625->app_bmp & RT5625_REC_MASK) >> RT5625_REC_BIT;
- mode &= ~(0x01 << 8);
- mode |= (ucontrol->value.integer.value[0] << 8);
- rt5625_write(codec, VIRTUAL_REG_FOR_MISC_FUNC, mode);
- rt5625_dump_dsp_reg(codec);
-
return 0;
}
-static const struct snd_kcontrol_new rt5625_snd_controls[] = {
-SOC_ENUM_EXT("rt5625 aec mode sel", rt5625_enum[0], rt5625_get_dsp_mode, rt5625_set_dsp_mode),
-SOC_ENUM("SPK Amp Type", rt5625_enum[1]),
-SOC_ENUM("Left SPK Source", rt5625_enum[2]),
-SOC_ENUM("SPK Amp Ratio", rt5625_enum[7]),
-SOC_ENUM("Mic1 Boost", rt5625_enum[8]),
-SOC_ENUM("Mic2 Boost", rt5625_enum[9]),
-SOC_ENUM("Dmic Boost", rt5625_enum[10]),
-SOC_ENUM("ADCR Func", rt5625_enum[11]),
-SOC_DOUBLE("PCM Playback Volume", RT5625_STEREO_DAC_VOL, 8, 0, 63, 1),
-SOC_DOUBLE("LineIn Playback Volume", RT5625_LINE_IN_VOL, 8, 0, 31, 1),
-SOC_SINGLE("Phone Playback Volume", RT5625_PHONEIN_VOL, 8, 31, 1),
-SOC_SINGLE("Mic1 Playback Volume", RT5625_MIC_VOL, 8, 31, 1),
-SOC_SINGLE("Mic2 Playback Volume", RT5625_MIC_VOL, 0, 31, 1),
-SOC_DOUBLE("PCM Capture Volume", RT5625_ADC_REC_GAIN, 8, 0, 31, 1),
-SOC_DOUBLE("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("HPOUT Playback Volume", RT5625_HP_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("HPOUT Playback Switch", RT5625_HP_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("AUXOUT Playback Volume", RT5625_AUX_OUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("AUXOUT Playback Switch", RT5625_AUX_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("ADC Record Gain", RT5625_ADC_REC_GAIN, 8, 0, 31, 0),
-SOC_SINGLE_EXT("VoDSP Dump", VIRTUAL_REG_FOR_MISC_FUNC, 8, 1, 0,
- snd_soc_get_volsw, rt5625_dump_dsp_put),
-#if (RT5625_EQ_FUNC_ENA==1)
-SOC_ENUM_EXT("EQ Mode", rt5625_enum[12], snd_soc_get_enum_double, rt5625_eq_sel_put),
-#endif
-};
-
-static int rt5625_add_controls(struct snd_soc_codec *codec)
+static int rt5625_rec_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- int err, i;
-
- for (i = 0; i < ARRAY_SIZE(rt5625_snd_controls); i++){
- err = snd_ctl_add(codec->card,
- snd_soc_cnew(&rt5625_snd_controls[i],
- codec, NULL));
- if (err < 0)
- return err;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int upd;
+
+ upd = (rt5625->app_bmp & ~RT5625_REC_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_REC_BIT);
+ if (rt5625->app_bmp != upd)
+ rt5625->app_bmp = upd;
+
+ if (!(rt5625->app_bmp & RT5625_3G_MASK) ||
+ ((rt5625->app_bmp & RT5625_3G_MASK) && rt5625->headset)) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_PHO, RT5625_M_RM_L_PHO);
}
+
+
return 0;
}
-static void hp_depop_mode2(struct snd_soc_codec *codec)
+static int rt5625_bt_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD3, PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL,
- PWR_HP_R_OUT_VOL|PWR_HP_L_OUT_VOL);
- rt5625_write(codec, RT5625_MISC_CTRL,HP_DEPOP_MODE2_EN);
-
- DBG("delay 500 msec\n");
-
- schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_HP_OUT_AMP|PWR_HP_OUT_ENH_AMP,
- PWR_HP_OUT_AMP|PWR_HP_OUT_ENH_AMP);
- //rt5625_write_mask(codec, RT5625_MISC_CTRL, 0, HP_DEPOP_MODE2_EN);
+ ucontrol->value.integer.value[0] =
+ (rt5625->app_bmp & RT5625_BT_MASK) >> RT5625_BT_BIT;
+ return 0;
}
-//enable depop function for mute/unmute
-static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute)
+static int rt5625_bt_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- if(mute)
- {
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
- rt5625_write(codec, RT5625_MISC_CTRL,M_UM_DEPOP_EN|HP_R_M_UM_DEPOP_EN|HP_L_M_UM_DEPOP_EN);
- //Mute headphone right/left channel
- rt5625_write_mask(codec,RT5625_HP_OUT_VOL,RT_L_MUTE|RT_R_MUTE,RT_L_MUTE|RT_R_MUTE);
- mdelay(50);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int upd;
+
+ if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2);
}
- else
- {
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD1, PWR_SOFTGEN_EN, PWR_SOFTGEN_EN);
- rt5625_write(codec, RT5625_MISC_CTRL, M_UM_DEPOP_EN|HP_R_M_UM_DEPOP_EN|HP_L_M_UM_DEPOP_EN);
- //unMute headphone right/left channel
- rt5625_write_mask(codec,RT5625_HP_OUT_VOL,0,RT_L_MUTE|RT_R_MUTE);
- mdelay(50);
+
+ upd = (rt5625->app_bmp & ~RT5625_BT_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_BT_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_3G_MASK | RT5625_VOIP_MASK);
}
+ return 0;
}
+static int rt5625_3g_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] =
+ (rt5625->app_bmp & RT5625_3G_MASK) >> RT5625_3G_BIT;
-/*
- * _DAPM_ Controls
- */
- /*Left ADC Rec mixer*/
- /*Left ADC Rec mixer*/
-static const struct snd_kcontrol_new rt5625_left_adc_rec_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, 12, 1, 1),
-SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, 11, 1, 1),
-SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, 10, 1, 1),
-SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, 9, 1, 1),
-SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, 8, 1, 1),
+ return 0;
+}
-};
+static int rt5625_3g_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int upd;
+
+ rt5625->headset = false;
+ if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 | RT5625_M_RM_R_MIC2);
+ }
-/*Left ADC Rec mixer*/
-static const struct snd_kcontrol_new rt5625_right_adc_rec_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER, 3, 1, 1),
-SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER, 2, 1, 1),
-SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER, 1, 1, 1),
-SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER, 0, 1, 1),
-};
+ upd = (rt5625->app_bmp & ~RT5625_3G_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_3G_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK);
+ }
-/*Left hpmixer mixer*/
-static const struct snd_kcontrol_new rt5625_left_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, 15, 1, 1),
-SOC_DAPM_SINGLE("LineIn Playback Switch", HPL_MIXER, 0, 1, 0),
-SOC_DAPM_SINGLE("Phone Playback Switch", HPL_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", HPL_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", HPL_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", HPL_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("HIFI DAC Playback Switch", RT5625_DAC_AND_MIC_CTRL, 3, 1, 1),
+ return 0;
+}
-};
+static int rt5625_hs_3g_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int upd;
+
+ rt5625->headset = true;
+ if (!(rt5625->app_bmp & RT5625_REC_MASK)) {
+ snd_soc_update_bits(codec, RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2,
+ RT5625_M_RM_L_MIC1 | RT5625_M_RM_L_MIC2 |
+ RT5625_M_RM_R_MIC1 | RT5625_M_RM_R_MIC2);
+ }
+ upd = (rt5625->app_bmp & ~RT5625_3G_MASK) |
+ (ucontrol->value.integer.value[0] << RT5625_3G_BIT);
+ if (rt5625->app_bmp != upd) {
+ rt5625->app_bmp = upd;
+ rt5625->app_bmp &= ~(RT5625_BT_MASK | RT5625_VOIP_MASK);
+ }
-/*Right hpmixer mixer*/
-static const struct snd_kcontrol_new rt5625_right_hp_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN, 7, 1, 1),
-SOC_DAPM_SINGLE("LineIn Playback Switch", HPR_MIXER, 0, 1, 0),
-SOC_DAPM_SINGLE("Phone Playback Switch", HPR_MIXER, 1, 1, 0),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", HPR_MIXER, 2, 1, 0),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", HPR_MIXER, 3, 1, 0),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", HPR_MIXER, 4, 1, 0),
-SOC_DAPM_SINGLE("HIFI DAC Playback Switch", RT5625_DAC_AND_MIC_CTRL, 2, 1, 1),
+ return 0;
+}
-};
+static int rt5625_dump_dsp_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ int i;
+ u16 val;
-/*mono mixer*/
-static const struct snd_kcontrol_new rt5625_mono_mixer_controls[] = {
-SOC_DAPM_SINGLE("ADCL Playback Switch", RT5625_ADC_REC_GAIN, 14, 1, 1),
-SOC_DAPM_SINGLE("ADCR Playback Switch", RT5625_ADC_REC_GAIN, 6, 1, 1),
-SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, 13, 1, 1),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 9, 1, 1),
-SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_AND_MIC_CTRL, 0, 1, 1),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VOICE_DAC_OUT_VOL, 13, 1, 1),
-};
+ pr_info("\n[ RT5625 DSP Register ]\n");
+ for (i = 0; i < RT5625_DSP_INIT_NUM; i++) {
+ val = rt5625_dsp_read(codec, rt5625_dsp_init[i].index);
+ if (val) pr_info(" 0x%x: 0x%x\n",
+ rt5625_dsp_init[i].index, val);
+ }
+ return 0;
+}
-/*speaker mixer*/
-static const struct snd_kcontrol_new rt5625_spk_mixer_controls[] = {
-SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_AND_MIC_CTRL, 10, 1, 1),
-SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_AND_MIC_CTRL, 1, 1, 1),
-SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VOICE_DAC_OUT_VOL, 14, 1, 1),
-};
+static int rt5625_dac_active_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
-static int mixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+ ucontrol->value.integer.value[0] = rt5625->dac_active;
+ return 0;
+}
+
+static int rt5625_dac_active_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = w->codec;
- unsigned int l, r;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dapm_widget *w;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- DBG("enter %s\n", __func__);
+ if(ucontrol->value.integer.value[0] == rt5625->dac_active)
+ return 0;
+ rt5625->dac_active = ucontrol->value.integer.value[0];
- l= rt5625_read(codec, HPL_MIXER);
- r = rt5625_read(codec, HPR_MIXER);
-
- if ((l & 0x1) || (r & 0x1))
- rt5625_write_mask(codec, 0x0a, 0x0000, 0x8000);
- else
- rt5625_write_mask(codec, 0x0a, 0x8000, 0x8000);
+ /* playback is on-going; do nothing when turn off BT */
+ if (rt5625->dac_active == 0 && rt5625->app_bmp & RT5625_PLY_MASK)
+ return 0;
- if ((l & 0x2) || (r & 0x2))
- rt5625_write_mask(codec, 0x08, 0x0000, 0x8000);
- else
- rt5625_write_mask(codec, 0x08, 0x8000, 0x8000);
+ list_for_each_entry(w, &dapm->card->widgets, list)
+ {
+ if (!w->sname || w->dapm != dapm)
+ continue;
+ if (strstr(w->sname, "Playback")) {
+ pr_info("widget %s %s %s\n", w->name, w->sname,
+ rt5625->dac_active ? "active" : "inactive");
+ w->active = rt5625->dac_active;
+ }
+ }
- if ((l & 0x4) || (r & 0x4))
- rt5625_write_mask(codec, 0x10, 0x0000, 0x8000);
- else
- rt5625_write_mask(codec, 0x10, 0x8000, 0x8000);
+ if (!(rt5625->dac_active))
+ snd_soc_dapm_sync(dapm);
- if ((l & 0x8) || (r & 0x8))
- rt5625_write_mask(codec, 0x10, 0x0000, 0x0800);
- else
- rt5625_write_mask(codec, 0x10, 0x0800, 0x0800);
+ return 0;
+}
- if ((l & 0x10) || (r & 0x10))
- rt5625_write_mask(codec, 0x18, 0x0000, 0x8000);
- else
- rt5625_write_mask(codec, 0x18, 0x8000, 0x8000);
+static int rt5625_adc_active_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ ucontrol->value.integer.value[0] = rt5625->adc_active;
return 0;
}
+static int rt5625_adc_active_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dapm_widget *w;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
-/*
- * bit[0][1] use for aec control
- * bit[2][3] for ADCR func
- * bit[4] for SPKL pga
- * bit[5] for SPKR pga
- * bit[6] for hpl pga
- * bit[7] for hpr pga
- */
-static int spk_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
- {
- struct snd_soc_codec *codec = w->codec;
- int reg;
-
- DBG("enter %s\n", __func__);
- reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC) & (0x3 << 4);
- if ((reg >> 4) != 0x3 && reg != 0)
+ if(ucontrol->value.integer.value[0] == rt5625->adc_active)
return 0;
+ rt5625->adc_active = ucontrol->value.integer.value[0];
- switch (event)
+ /* record is on-going; do nothing when turn off BT */
+ if (rt5625->adc_active == 0 && rt5625->app_bmp & RT5625_REC_MASK)
+ return 0;
+
+ list_for_each_entry(w, &dapm->card->widgets, list)
{
- case SND_SOC_DAPM_POST_PMU:
- DBG("after virtual spk power up!\n");
- rt5625_write_mask(codec, 0x3e, 0x3000, 0x3000);
- rt5625_write_mask(codec, 0x02, 0x0000, 0x8080);
- rt5625_write_mask(codec, 0x3a, 0x0400, 0x0400);//power on spk amp
- break;
- case SND_SOC_DAPM_POST_PMD:
- DBG("aftet virtual spk power down!\n");
- rt5625_write_mask(codec, 0x3a, 0x0000, 0x0400);//power off spk amp
- rt5625_write_mask(codec, 0x02, 0x8080, 0x8080);
- rt5625_write_mask(codec, 0x3e, 0x0000, 0x3000);
- break;
- default:
- return 0;
+ if (!w->sname || w->dapm != dapm)
+ continue;
+ if (strstr(w->sname, "Capture")) {
+ pr_info("widget %s %s %s\n", w->name, w->sname,
+ rt5625->adc_active ? "active" : "inactive");
+ w->active = rt5625->adc_active;
+ }
}
- return 0;
-}
-
+ if (!(rt5625->adc_active))
+ snd_soc_dapm_sync(dapm);
+ return 0;
+}
-static int hp_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+static int rt5625_pll_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_codec *codec = w->codec;
- int reg;
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- DBG("enter %s\n", __func__);
+ ucontrol->value.integer.value[0] = rt5625->pll_sel;
+ return 0;
+}
- reg = rt5625_read(codec, VIRTUAL_REG_FOR_MISC_FUNC) & (0x3 << 6);
- if ((reg >> 6) != 0x3 && reg != 0)
- return 0;
-
- switch (event)
- {
- case SND_SOC_DAPM_POST_PMD:
- DBG("aftet virtual hp power down!\n");
+static int rt5625_pll_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
- hp_mute_unmute_depop(codec,1);//mute hp
- rt5625_write_mask(codec, 0x3a, 0x0000, 0x0300);
- rt5625_write_mask(codec, 0x3e, 0x0000, 0x0c00);
- break;
+ if(ucontrol->value.integer.value[0] == rt5625->pll_sel)
+ return 0;
+ rt5625->pll_sel = ucontrol->value.integer.value[0];
+
+ switch(rt5625->pll_sel) {
+ case RT5625_PLL_DIS:
+ pr_info("%s(): Disable\n", __func__);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_PLL1, 0);
+ snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0);
+ break;
- case SND_SOC_DAPM_POST_PMU:
+ case RT5625_PLL_112896_225792:
+ pr_info("%s(): 11.2896>22.5792\n", __func__);
+ snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000);
+ snd_soc_write(codec, RT5625_PLL_CTRL, 0x06a0);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_PLL1, RT5625_SCLK_PLL1);
+ snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210);
+ break;
- DBG("after virtual hp power up!\n");
- hp_depop_mode2(codec);
- hp_mute_unmute_depop(codec,0);//unmute hp
- break;
+ case RT5625_PLL_112896_24576:
+ pr_info("%s(): 11.2896->24.576\n", __func__);
+ snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000);
+ snd_soc_write(codec, RT5625_PLL_CTRL, 0x922f);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_PLL1, RT5625_SCLK_PLL1);
+ snd_soc_write(codec, RT5625_DAC_CLK_CTRL2, 0x0210);
+ break;
- default:
- return 0;
- }
+ default:
+ break;
+ }
return 0;
}
-
-
-static int aux_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+static int rt5625_pll2_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = rt5625->pll2_sel;
return 0;
}
-/*SPKOUT Mux*/
-static const struct snd_kcontrol_new rt5625_spkout_mux_out_controls =
-SOC_DAPM_ENUM("Route", rt5625_enum[3]);
+static int rt5625_pll2_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
-/*HPLOUT MUX*/
-static const struct snd_kcontrol_new rt5625_hplout_mux_out_controls =
-SOC_DAPM_ENUM("Route", rt5625_enum[4]);
+ if(ucontrol->value.integer.value[0] == rt5625->pll2_sel)
+ return 0;
+ rt5625->pll2_sel = ucontrol->value.integer.value[0];
+
+ if(rt5625->pll2_sel != RT5625_PLL_DIS) {
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_VSCLK_MASK, RT5625_VSCLK_PLL2);
+ snd_soc_write(codec, RT5625_PLL2_CTRL, RT5625_PLL2_EN);
+ snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1,
+ RT5625_VBCLK_DIV1_4);
+ snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+ RT5625_PCM_CS_MASK, RT5625_PCM_CS_VSCLK);
+ }
-/*HPROUT MUX*/
-static const struct snd_kcontrol_new rt5625_hprout_mux_out_controls =
-SOC_DAPM_ENUM("Route", rt5625_enum[5]);
-/*AUXOUT MUX*/
-static const struct snd_kcontrol_new rt5625_auxout_mux_out_controls =
-SOC_DAPM_ENUM("Route", rt5625_enum[6]);
+ return 0;
+}
-static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("Left LineIn"),
-SND_SOC_DAPM_INPUT("Right LineIn"),
-SND_SOC_DAPM_INPUT("Phone"),
-SND_SOC_DAPM_INPUT("Mic1"),
-SND_SOC_DAPM_INPUT("Mic2"),
-
-SND_SOC_DAPM_PGA("Mic1 Boost", RT5625_PWR_MANAG_ADD3, 1, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic2 Boost", RT5625_PWR_MANAG_ADD3, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback DAC", RT5625_PWR_MANAG_ADD2, 9, 0),
-SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback DAC", RT5625_PWR_MANAG_ADD2, 8, 0),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback DAC", RT5625_PWR_MANAG_ADD2, 10, 0),
-
-SND_SOC_DAPM_PGA("Left LineIn PGA", RT5625_PWR_MANAG_ADD3, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right LineIn PGA", RT5625_PWR_MANAG_ADD3, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Phone PGA", RT5625_PWR_MANAG_ADD3, 5, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic1 PGA", RT5625_PWR_MANAG_ADD3, 3, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Mic2 PGA", RT5625_PWR_MANAG_ADD3, 2, 0, NULL, 0),
-SND_SOC_DAPM_PGA("VoDAC PGA", RT5625_PWR_MANAG_ADD1, 7, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Left Rec Mixer", RT5625_PWR_MANAG_ADD2, 1, 0,
- &rt5625_left_adc_rec_mixer_controls[0], ARRAY_SIZE(rt5625_left_adc_rec_mixer_controls)),
-SND_SOC_DAPM_MIXER("Right Rec Mixer", RT5625_PWR_MANAG_ADD2, 0, 0,
- &rt5625_right_adc_rec_mixer_controls[0], ARRAY_SIZE(rt5625_right_adc_rec_mixer_controls)),
-SND_SOC_DAPM_MIXER_E("Left HP Mixer", RT5625_PWR_MANAG_ADD2, 5, 0,
- &rt5625_left_hp_mixer_controls[0], ARRAY_SIZE(rt5625_left_hp_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER_E("Right HP Mixer", RT5625_PWR_MANAG_ADD2, 4, 0,
- &rt5625_right_hp_mixer_controls[0], ARRAY_SIZE(rt5625_right_hp_mixer_controls),
- mixer_event, SND_SOC_DAPM_POST_REG),
-SND_SOC_DAPM_MIXER("MoNo Mixer", RT5625_PWR_MANAG_ADD2, 2, 0,
- &rt5625_mono_mixer_controls[0], ARRAY_SIZE(rt5625_mono_mixer_controls)),
-SND_SOC_DAPM_MIXER("SPK Mixer", RT5625_PWR_MANAG_ADD2, 3, 0,
- &rt5625_spk_mixer_controls[0], ARRAY_SIZE(rt5625_spk_mixer_controls)),
-SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("DAC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MUX("SPKOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_spkout_mux_out_controls),
-SND_SOC_DAPM_MUX("HPLOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_hplout_mux_out_controls),
-SND_SOC_DAPM_MUX("HPROUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_hprout_mux_out_controls),
-SND_SOC_DAPM_MUX("AUXOUT Mux", SND_SOC_NOPM, 0, 0, &rt5625_auxout_mux_out_controls),
-
-SND_SOC_DAPM_PGA_E("SPKL Out PGA", VIRTUAL_REG_FOR_MISC_FUNC, 4, 0, NULL, 0,
- spk_pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA_E("SPKR Out PGA", VIRTUAL_REG_FOR_MISC_FUNC, 5, 0, NULL, 0,
- spk_pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_PGA_E("HPL Out PGA",VIRTUAL_REG_FOR_MISC_FUNC, 6, 0, NULL, 0,
- hp_pga_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("HPR Out PGA",VIRTUAL_REG_FOR_MISC_FUNC, 7, 0, NULL, 0,
- hp_pga_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("AUX Out PGA",RT5625_PWR_MANAG_ADD3, 14, 0, NULL, 0,
- aux_pga_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_ADC("Left ADC", "Left ADC HiFi Capture", RT5625_PWR_MANAG_ADD2, 7, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Right ADC HiFi Capture", RT5625_PWR_MANAG_ADD2, 6, 0),
-SND_SOC_DAPM_OUTPUT("SPKL"),
-SND_SOC_DAPM_OUTPUT("SPKR"),
-SND_SOC_DAPM_OUTPUT("HPL"),
-SND_SOC_DAPM_OUTPUT("HPR"),
-SND_SOC_DAPM_OUTPUT("AUX"),
-SND_SOC_DAPM_MICBIAS("Mic1 Bias", RT5625_PWR_MANAG_ADD1, 3, 0),
-SND_SOC_DAPM_MICBIAS("Mic2 Bias", RT5625_PWR_MANAG_ADD1, 2, 0),
-};
+static const char *rt5625_pll_sel[] = {"Disable", "11.2896->22.5792", "11.2896->24.576"};
-static const struct snd_soc_dapm_route audio_map[] = {
- /*Input PGA*/
-
- {"Left LineIn PGA", NULL, "Left LineIn"},
- {"Right LineIn PGA", NULL, "Right LineIn"},
- {"Phone PGA", NULL, "Phone"},
- {"Mic1 Boost", NULL, "Mic1"},
- {"Mic2 Boost", NULL, "Mic2"},
- {"Mic1 PGA", NULL, "Mic1"},
- {"Mic2 PGA", NULL, "Mic2"},
- {"VoDAC PGA", NULL, "Voice DAC"},
-
- /*Left ADC mixer*/
- {"Left Rec Mixer", "LineIn Capture Switch", "Left LineIn"},
- {"Left Rec Mixer", "Phone Capture Switch", "Phone"},
- {"Left Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
- {"Left Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
- {"Left Rec Mixer", "HP Mixer Capture Switch", "Left HP Mixer"},
- {"Left Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
- {"Left Rec Mixer", "MoNo Mixer Capture Switch", "MoNo Mixer"},
-
- /*Right ADC Mixer*/
- {"Right Rec Mixer", "LineIn Capture Switch", "Right LineIn"},
- {"Right Rec Mixer", "Phone Capture Switch", "Phone"},
- {"Right Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
- {"Right Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
- {"Right Rec Mixer", "HP Mixer Capture Switch", "Right HP Mixer"},
- {"Right Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
- {"Right Rec Mixer", "MoNo Mixer Capture Switch", "MoNo Mixer"},
-
- /*HPL mixer*/
- {"Left HP Mixer", "ADC Playback Switch", "Left Rec Mixer"},
- {"Left HP Mixer", "LineIn Playback Switch", "Left LineIn PGA"},
- {"Left HP Mixer", "Phone Playback Switch", "Phone PGA"},
- {"Left HP Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
- {"Left HP Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
- {"Left HP Mixer", "HIFI DAC Playback Switch", "Left DAC"},
- {"Left HP Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
- /*HPR mixer*/
- {"Right HP Mixer", "ADC Playback Switch", "Right Rec Mixer"},
- {"Right HP Mixer", "LineIn Playback Switch", "Right LineIn PGA"},
- {"Right HP Mixer", "HIFI DAC Playback Switch", "Right DAC"},
- {"Right HP Mixer", "Phone Playback Switch", "Phone PGA"},
- {"Right HP Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
- {"Right HP Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
- {"Right HP Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
- /*DAC Mixer*/
- {"DAC Mixer", NULL, "Left DAC"},
- {"DAC Mixer", NULL, "Right DAC"},
-
- /*line mixer*/
- {"Line Mixer", NULL, "Left LineIn PGA"},
- {"Line Mixer", NULL, "Right LineIn PGA"},
-
- /*spk mixer*/
- {"SPK Mixer", "Line Mixer Playback Switch", "Line Mixer"},
- {"SPK Mixer", "Phone Playback Switch", "Phone PGA"},
- {"SPK Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
- {"SPK Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
- {"SPK Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
- {"SPK Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
- /*mono mixer*/
- {"MoNo Mixer", "Line Mixer Playback Switch", "Line Mixer"},
- {"MoNo Mixer", "ADCL Playback Switch","Left Rec Mixer"},
- {"MoNo Mixer", "ADCR Playback Switch","Right Rec Mixer"},
- {"MoNo Mixer", "Mic1 Playback Switch", "Mic1 PGA"},
- {"MoNo Mixer", "Mic2 Playback Switch", "Mic2 PGA"},
- {"MoNo Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
- {"MoNo Mixer", "Voice DAC Playback Switch", "VoDAC PGA"},
-
- /*hp mixer*/
- {"HP Mixer", NULL, "Left HP Mixer"},
- {"HP Mixer", NULL, "Right HP Mixer"},
-
- /*spkout mux*/
- {"SPKOUT Mux", "HP Mixer", "HP Mixer"},
- {"SPKOUT Mux", "SPK Mixer", "SPK Mixer"},
- {"SPKOUT Mux", "Mono Mixer", "MoNo Mixer"},
-
- /*hpl out mux*/
- {"HPLOUT Mux", "HPL Mixer", "Left HP Mixer"},
-
- /*hpr out mux*/
- {"HPROUT Mux", "HPR Mixer", "Right HP Mixer"},
+static const SOC_ENUM_SINGLE_DECL(rt5625_pll_sel_enum, 0, 0, rt5625_pll_sel);
- /*aux out mux*/
- {"AUXOUT Mux", "HP Mixer", "HP Mixer"},
- {"AUXOUT Mux", "SPK Mixer", "SPK Mixer"},
- {"AUXOUT Mux", "Mono Mixer", "MoNo Mixer"},
+static const char *rt5625_pll2_sel[] = {"Disable", "Enable"};
- /*spkl out pga*/
- {"SPKL Out PGA", NULL, "SPKOUT Mux"},
+static const SOC_ENUM_SINGLE_DECL(rt5625_pll2_sel_enum, 0, 0, rt5625_pll2_sel);
+#endif
- /*spkr out pga*/
- {"SPKR Out PGA", NULL, "SPKOUT Mux"},
-
- /*hpl out pga*/
- {"HPL Out PGA", NULL, "HPLOUT Mux"},
+static const char *rt5625_AUXOUT_mode[] = {"Differential mode", "Single-ended mode"};
+static const char *rt5625_Differential_Input_Control[] = {"Disable", "Enable"};
- /*hpr out pga*/
- {"HPR Out PGA", NULL, "HPROUT Mux"},
+static const struct soc_enum rt5625_differential_enum[] = {
+SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, 4, 2, rt5625_AUXOUT_mode), /*0*/
+SOC_ENUM_SINGLE(RT5625_PHONEIN_VOL, 13, 2, rt5625_Differential_Input_Control),/*1*/
+SOC_ENUM_SINGLE(RT5625_MIC_VOL, 15, 2, rt5625_Differential_Input_Control), /*2*/
+SOC_ENUM_SINGLE(RT5625_MIC_VOL, 7, 2, rt5625_Differential_Input_Control), /*3*/
+};
- /*aux out pga*/
- {"AUX Out PGA", NULL, "AUXOUT Mux"},
-
- /*left adc*/
- {"Left ADC", NULL, "Left Rec Mixer"},
-
- /*right adc*/
- {"Right ADC", NULL, "Right Rec Mixer"},
-
- /*output*/
- {"SPKL", NULL, "SPKL Out PGA"},
- {"SPKR", NULL, "SPKR Out PGA"},
- {"HPL", NULL, "HPL Out PGA"},
- {"HPR", NULL, "HPR Out PGA"},
- {"AUX", NULL, "AUX Out PGA"},
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -3525, 75, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dmic_bst_tlv, 0, 600, 0);
+/* {0, +20, +30, +40} dB */
+static unsigned int mic_bst_tlv[] = {
+ TLV_DB_RANGE_HEAD(2),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
};
+#ifdef RT5625_REG_RW
+#define REGVAL_MAX 0xffff
+static unsigned int regctl_addr = 0x3e;
+static int rt5625_regctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = REGVAL_MAX;
+ return 0;
+}
-static int rt5625_add_widgets(struct snd_soc_codec *codec)
+static int rt5625_regctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
- snd_soc_dapm_new_controls(codec, rt5625_dapm_widgets,
- ARRAY_SIZE(rt5625_dapm_widgets));
- snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
- snd_soc_dapm_new_widgets(codec);
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ ucontrol->value.integer.value[0] = regctl_addr;
+ ucontrol->value.integer.value[1] = snd_soc_read(codec, regctl_addr);
+ return 0;
+}
+static int rt5625_regctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ regctl_addr = ucontrol->value.integer.value[0];
+ if(ucontrol->value.integer.value[1] <= REGVAL_MAX)
+ snd_soc_write(codec, regctl_addr, ucontrol->value.integer.value[1]);
return 0;
}
+#endif
-struct _pll_div{
- u32 pll_in;
- u32 pll_out;
- u16 regvalue;
+static const struct snd_kcontrol_new rt5625_snd_controls[] = {
+ SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+ SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL,
+ RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+ SOC_ENUM("SPK Amp Type", rt5625_spk_out_enum),
+ SOC_ENUM("Left SPK Source", rt5625_spkl_src_enum),
+ SOC_ENUM("SPK Amp Ratio", rt5625_spkamp_ratio_enum),
+ //SOC_DOUBLE_TLV("Headphone Playback Volume", RT5625_HP_OUT_VOL,
+ // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+ //SOC_DOUBLE("Headphone Playback Switch", RT5625_HP_OUT_VOL,
+ // RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+ //SOC_ENUM("AUXOUT Mode Control", rt5625_auxout_mode_enum),
+ SOC_DOUBLE_TLV("AUXOUT Playback Volume", RT5625_AUX_OUT_VOL,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+ SOC_DOUBLE("AUXOUT Playback Switch", RT5625_AUX_OUT_VOL,
+ RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+ SOC_DOUBLE_TLV("PCM Playback Volume", RT5625_DAC_VOL,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 63, 1, dmic_bst_tlv),
+ //SOC_ENUM("Phone Mode Control", rt5625_phone_mode_enum),
+ SOC_SINGLE_TLV("Phone Playback Volume", RT5625_PHONEIN_VOL,
+ RT5625_L_VOL_SFT, 31, 1, in_vol_tlv),
+ //SOC_ENUM("MIC1 Mode Control", rt5625_mic1_mode_enum),
+ SOC_SINGLE_TLV("MIC1 Boost", RT5625_MIC_CTRL,
+ RT5625_MIC1_BST_SFT, 3, 0, mic_bst_tlv),
+ SOC_SINGLE_TLV("Mic1 Playback Volume", RT5625_MIC_VOL,
+ RT5625_L_VOL_SFT, 31, 1, in_vol_tlv),
+ //SOC_ENUM("MIC2 Mode Control", rt5625_mic2_mode_enum),
+ SOC_SINGLE_TLV("MIC2 Boost", RT5625_MIC_CTRL,
+ RT5625_MIC2_BST_SFT, 3, 0, mic_bst_tlv),
+ SOC_SINGLE_TLV("Mic2 Playback Volume", RT5625_MIC_VOL,
+ RT5625_R_VOL_SFT, 31, 1, in_vol_tlv),
+ SOC_SINGLE_TLV("Dmic Boost", RT5625_DMIC_CTRL,
+ RT5625_DIG_BST_SFT, 7, 0, dmic_bst_tlv),
+ SOC_DOUBLE_TLV("LineIn Playback Volume", RT5625_LINE_IN_VOL,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, in_vol_tlv),
+ SOC_DOUBLE_TLV("PCM Capture Volume", RT5625_ADC_REC_GAIN,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv),
+ //SOC_DOUBLE_TLV("ADC Record Gain", RT5625_ADC_REC_GAIN,
+ // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 0, adc_vol_tlv),
+ /* This item does'nt affect path connected; only for clock choosen */
+ SOC_ENUM_EXT("ADCR fun select Control", adcr_fun_sel_enum,
+ snd_soc_get_enum_double, rt5625_adcr_fun_sel_put),
+ SOC_ENUM_EXT("ADCL fun select Control", adcl_fun_sel_enum,
+ snd_soc_get_enum_double, rt5625_adcl_fun_sel_put),
+
+ /* Voice DSP */
+ SOC_ENUM_EXT("VoDSP AEC", rt5625_aec_fun_enum,
+ rt5625_aec_get, rt5625_aec_put),
+ SOC_ENUM("VoDSP LRCK Control", rt5625_dsp_lrck_enum),
+ SOC_ENUM("VoDSP BP Pin Control", rt5625_bp_ctrl_enum),
+ SOC_ENUM("VoDSP Power Down Pin Control", rt5625_pd_ctrl_enum),
+ SOC_ENUM("VoDSP Reset Pin Control", rt5625_rst_ctrl_enum),
+
+#ifdef RT5625_F_SMT_PHO
+ SOC_SINGLE_EXT("VoDSP Dump", 0, 0, 1, 0, rt5625_dump_dsp_get, NULL),
+ SOC_SINGLE_EXT("DAC Switch", 0, 0, 1, 0, rt5625_dac_active_get, rt5625_dac_active_put),
+ SOC_SINGLE_EXT("ADC Switch", 0, 0, 1, 0, rt5625_adc_active_get, rt5625_adc_active_put),
+ SOC_ENUM_EXT("PLL Switch", rt5625_pll_sel_enum, rt5625_pll_get, rt5625_pll_put),
+ SOC_ENUM_EXT("PLL2 Switch", rt5625_pll2_sel_enum, rt5625_pll2_get, rt5625_pll2_put),
+ SOC_SINGLE_EXT("VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_chk_put),
+ SOC_SINGLE_EXT("VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_voip_put),
+ SOC_SINGLE_EXT("Capture VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_chk_put),
+ SOC_SINGLE_EXT("Capture VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_cap_voip_put),
+ SOC_SINGLE_EXT("Headset VoIP Check", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_chk_put),
+ SOC_SINGLE_EXT("Headset VoIP Switch", 0, 0, 1, 0, rt5625_voip_get, rt5625_hs_voip_put),
+ SOC_SINGLE_EXT("Playback Switch", 0, 0, 1, 0, rt5625_play_get, rt5625_play_put),
+ SOC_SINGLE_EXT("Record Switch", 0, 0, 1, 0, rt5625_rec_get, rt5625_rec_put),
+ SOC_SINGLE_EXT("BT Switch", 0, 0, 1, 0, rt5625_bt_get, rt5625_bt_put),
+ SOC_SINGLE_EXT("3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_3g_put),
+ SOC_SINGLE_EXT("Headset 3G Switch", 0, 0, 1, 0, rt5625_3g_get, rt5625_hs_3g_put),
+ SOC_SINGLE_EXT("APP disp", 0, 0, 1, 0, rt5625_app_get, NULL),
+#endif
+ //SOC_DOUBLE_TLV("SPKOUT Playback Volume", RT5625_SPK_OUT_VOL,
+ // RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+ //SOC_DOUBLE("SPKOUT Playback Switch", RT5625_SPK_OUT_VOL,
+ // RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+ SOC_DOUBLE_TLV("HPOUT Playback Volume", RT5625_HP_OUT_VOL,
+ RT5625_L_VOL_SFT, RT5625_R_VOL_SFT, 31, 1, out_vol_tlv),
+ SOC_DOUBLE("HPOUT Playback Switch", RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE_SFT, RT5625_R_MUTE_SFT, 1, 1),
+ SOC_ENUM("AUXOUT mode switch", rt5625_differential_enum[0]),
+ SOC_ENUM("Phone Differential Input Control", rt5625_differential_enum[1]),
+ SOC_ENUM("MIC1 Differential Input Control", rt5625_differential_enum[2]),
+ SOC_ENUM("MIC2 Differential Input Control", rt5625_differential_enum[3]),
+
+#ifdef RT5625_REG_RW
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Register Control",
+ .info = rt5625_regctl_info,
+ .get = rt5625_regctl_get,
+ .put = rt5625_regctl_put,
+ },
+#endif
};
-/**************************************************************
- * watch out!
- * our codec support you to select different source as pll input, but if you
- * use both of the I2S audio interface and pcm interface instantially.
- * The two DAI must have the same pll setting params, so you have to offer
- * the same pll input, and set our codec's sysclk the same one, we suggest
- * 24576000.
- **************************************************************/
-static const struct _pll_div codec_master_pll1_div[] = {
-
- { 2048000, 8192000, 0x0ea0},
- { 3686400, 8192000, 0x4e27},
- { 12000000, 8192000, 0x456b},
- { 13000000, 8192000, 0x495f},
- { 13100000, 8192000, 0x0320},
- { 2048000, 11289600, 0xf637},
- { 3686400, 11289600, 0x2f22},
- { 12000000, 11289600, 0x3e2f},
- { 13000000, 11289600, 0x4d5b},
- { 13100000, 11289600, 0x363b},
- { 2048000, 16384000, 0x1ea0},
- { 3686400, 16384000, 0x9e27},
- { 12000000, 16384000, 0x452b},
- { 13000000, 16384000, 0x542f},
- { 13100000, 16384000, 0x03a0},
- { 2048000, 16934400, 0xe625},
- { 3686400, 16934400, 0x9126},
- { 12000000, 16934400, 0x4d2c},
- { 13000000, 16934400, 0x742f},
- { 13100000, 16934400, 0x3c27},
- { 2048000, 22579200, 0x2aa0},
- { 3686400, 22579200, 0x2f20},
- { 12000000, 22579200, 0x7e2f},
- { 13000000, 22579200, 0x742f},
- { 13100000, 22579200, 0x3c27},
- { 2048000, 24576000, 0x2ea0},
- { 3686400, 24576000, 0xee27},
- { 11289600, 24576000, 0x950F},
- { 12000000, 24576000, 0x2915},
- { 12288000, 24576000, 0x0600},
- { 13000000, 24576000, 0x772e},
- { 13100000, 24576000, 0x0d20},
- { 26000000, 24576000, 0x2027},
- { 26000000, 22579200, 0x392f},
- { 24576000, 22579200, 0x0921},
- { 24576000, 24576000, 0x02a0},
+ /*Left ADC Rec mixer*/
+static const struct snd_kcontrol_new rt5625_adcl_rec_mixer[] = {
+ SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MIC2_SFT, 1, 1),
+ SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_LINE_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_PHO_SFT, 1, 1),
+ SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_L_MM_SFT, 1, 1),
};
-static const struct _pll_div codec_bclk_pll1_div[] = {
+/*Right ADC Rec mixer*/
+static const struct snd_kcontrol_new rt5625_adcr_rec_mixer[] = {
+ SOC_DAPM_SINGLE("Mic1 Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_MIC1_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic2 Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_MIC2_SFT, 1, 1),
+ SOC_DAPM_SINGLE("LineIn Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_LINE_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Phone Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_PHO_SFT, 1, 1),
+ SOC_DAPM_SINGLE("HP Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("SPK Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("MoNo Mixer Capture Switch", RT5625_ADC_REC_MIXER,
+ RT5625_M_RM_R_MM_SFT, 1, 1),
+};
- { 256000, 4096000, 0x3ea0},
- { 352800, 5644800, 0x3ea0},
- { 512000, 8192000, 0x3ea0},
- { 705600, 11289600, 0x3ea0},
- { 1024000, 16384000, 0x3ea0},
- { 1411200, 22579200, 0x3ea0},
- { 1536000, 24576000, 0x3ea0},
- { 2048000, 16384000, 0x1ea0},
- { 2822400, 22579200, 0x1ea0},
- { 3072000, 24576000, 0x1ea0},
- { 705600, 11289600, 0x3ea0},
- { 705600, 8467200, 0x3ab0},
- { 2822400, 11289600, 0x1ee0},
- { 3072000, 12288000, 0x1ee0},
+/* HP Mixer for mono input */
+static const struct snd_kcontrol_new rt5625_hp_mixer[] = {
+ SOC_DAPM_SINGLE("LineIn Playback Switch", RT5625_LINE_IN_VOL,
+ RT5625_M_LI_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL,
+ RT5625_M_PHO_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC1_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC2_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+ RT5625_M_VDAC_HM_SFT, 1, 1),
};
-static const struct _pll_div codec_vbclk_pll1_div[] = {
+/* Left HP Mixer */
+static const struct snd_kcontrol_new rt5625_hpl_mixer[] = {
+ SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN,
+ RT5625_M_ADCL_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_DACL_HM_SFT, 1, 1),
+};
- { 256000, 4096000, 0x3ea0},
- { 352800, 5644800, 0x3ea0},
- { 512000, 8192000, 0x3ea0},
- { 705600, 11289600, 0x3ea0},
- { 1024000, 16384000, 0x3ea0},
- { 1411200, 22579200, 0x3ea0},
- { 1536000, 24576000, 0x3ea0},
- { 2048000, 16384000, 0x1ea0},
- { 2822400, 22579200, 0x1ea0},
- { 3072000, 24576000, 0x1ea0},
- { 705600, 11289600, 0x3ea0},
- { 705600, 8467200, 0x3ab0},
+/* Right HP Mixer */
+static const struct snd_kcontrol_new rt5625_hpr_mixer[] = {
+ SOC_DAPM_SINGLE("ADC Playback Switch", RT5625_ADC_REC_GAIN,
+ RT5625_M_ADCR_HM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_DACR_HM_SFT, 1, 1),
};
+/* Mono Mixer */
+static const struct snd_kcontrol_new rt5625_mono_mixer[] = {
+ SOC_DAPM_SINGLE("ADCL Playback Switch", RT5625_ADC_REC_GAIN,
+ RT5625_M_ADCL_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("ADCR Playback Switch", RT5625_ADC_REC_GAIN,
+ RT5625_M_ADCR_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL,
+ RT5625_M_LI_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC1_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC2_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_DAC_MM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+ RT5625_M_VDAC_MM_SFT, 1, 1),
+};
-struct _coeff_div_stereo {
- unsigned int mclk;
- unsigned int rate;
- unsigned int reg60;
- unsigned int reg62;
+/* Speaker Mixer */
+static const struct snd_kcontrol_new rt5625_spk_mixer[] = {
+ SOC_DAPM_SINGLE("Line Mixer Playback Switch", RT5625_LINE_IN_VOL,
+ RT5625_M_LI_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Phone Playback Switch", RT5625_PHONEIN_VOL,
+ RT5625_M_PHO_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic1 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC1_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Mic2 Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_MIC2_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("DAC Mixer Playback Switch", RT5625_DAC_MIC_CTRL,
+ RT5625_M_DAC_SM_SFT, 1, 1),
+ SOC_DAPM_SINGLE("Voice DAC Playback Switch", RT5625_VDAC_OUT_VOL,
+ RT5625_M_VDAC_SM_SFT, 1, 1),
};
-struct _coeff_div_voice {
- unsigned int mclk;
+static int rt5625_dac_func_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_REG:
+ snd_soc_update_bits(codec, RT5625_PD_CTRL,
+ RT5625_PWR_PR1, RT5625_PWR_PR1);
+ break;
+
+ case SND_SOC_DAPM_POST_REG:
+ snd_soc_update_bits(codec, RT5625_PD_CTRL,
+ RT5625_PWR_PR1, 0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5625_hpmix_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, RT5625_PWR_ADD2,
+ RT5625_P_HM_L | RT5625_P_HM_R, 0);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec, RT5625_PWR_ADD2,
+ RT5625_P_HM_L | RT5625_P_HM_R,
+ RT5625_P_HM_L | RT5625_P_HM_R);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+static int rt5625_vodsp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ //pr_info("%s(): PMD\n", __func__);
+ snd_soc_update_bits(codec, RT5625_VODSP_CTL,
+ RT5625_DSP_PD_MASK, RT5625_DSP_PD_EN);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+ RT5625_P_DSP_IF | RT5625_P_DSP_I2C, 0);
+ snd_soc_update_bits(codec, RT5625_LDO_CTRL,
+ RT5625_LDO_MASK, RT5625_LDO_DIS);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ //pr_info("%s(): PMU\n", __func__);
+ if(rt5625->vodsp_fun == RT5625_AEC_EN)
+ rt5625_init_vodsp_aec(codec);
+ //pr_info("[DSP poweron] 0x%04x: 0x%04x\n", 0x230C, rt5625_dsp_read(codec, 0x230C));
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+
+static void hp_depop_mode2(struct snd_soc_codec *codec)
+{
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_SG_EN, RT5625_P_SG_EN);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+ RT5625_P_HPL_VOL | RT5625_P_HPR_VOL,
+ RT5625_P_HPL_VOL | RT5625_P_HPR_VOL);
+ snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_HP_DEPOP_M2);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(500));
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_HPO_AMP | RT5625_P_HPO_ENH,
+ RT5625_P_HPO_AMP | RT5625_P_HPO_ENH);
+}
+
+/* enable depop function for mute/unmute */
+static void hp_mute_unmute_depop(struct snd_soc_codec *codec,int mute)
+{
+ if(mute) {
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_SG_EN, RT5625_P_SG_EN);
+ snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP |
+ RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP);
+ snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE,
+ RT5625_L_MUTE | RT5625_R_MUTE);
+ mdelay(50);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1, RT5625_P_SG_EN, 0);
+ } else {
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_SG_EN, RT5625_P_SG_EN);
+ snd_soc_write(codec, RT5625_MISC_CTRL, RT5625_MUM_DEPOP |
+ RT5625_HPR_MUM_DEPOP | RT5625_HPL_MUM_DEPOP);
+ snd_soc_update_bits(codec,RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE, 0);
+ mdelay(50);
+ }
+}
+
+static int rt5625_hp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMD:
+ hp_mute_unmute_depop(codec,1);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_HPO_AMP | RT5625_P_HPO_ENH, 0);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD3,
+ RT5625_P_HPL_VOL | RT5625_P_HPR_VOL, 0);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ hp_depop_mode2(codec);
+ hp_mute_unmute_depop(codec,0);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+/* DAC function select MUX */
+static const char *dac_fun_sel[] = {
+ "Stereo DAC", "SRC2 Out", "TxDP", "TxDC"};
+
+static const struct soc_enum dac_fun_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_DAC_F_SFT,
+ ARRAY_SIZE(dac_fun_sel), dac_fun_sel);
+
+static const struct snd_kcontrol_new dac_fun_sel_mux =
+ SOC_DAPM_ENUM("DAC Function Select Mux", dac_fun_sel_enum);
+
+/* Voice DAC source select MUX */
+static const char *vdac_src_sel[] = {
+ "Voice PCM", "SRC2 Out", "TxDP", "TxDC"};
+
+static const struct soc_enum vdac_src_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_F_DAC_ADC_VDAC, RT5625_VDAC_S_SFT,
+ ARRAY_SIZE(vdac_src_sel), vdac_src_sel);
+
+static const struct snd_kcontrol_new vdac_src_sel_mux =
+ SOC_DAPM_ENUM("Voice DAC Source Mux", vdac_src_sel_enum);
+
+/* SRC1 power switch */
+static const struct snd_kcontrol_new src1_pwr_sw_control =
+ SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+ RT5625_SRC1_PWR_SFT, 1, 0);
+
+/* SRC2 power switch */
+static const struct snd_kcontrol_new src2_pwr_sw_control =
+ SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+ RT5625_SRC2_PWR_SFT, 1, 0);
+
+/* SRC2 source select MUX */
+static const char *src2_src_sel[] = {"TxDP", "TxDC"};
+
+static const struct soc_enum src2_src_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_SRC2_S_SFT,
+ ARRAY_SIZE(src2_src_sel), src2_src_sel);
+
+static const struct snd_kcontrol_new src2_src_sel_mux =
+ SOC_DAPM_ENUM("SRC2 Source Mux", src2_src_sel_enum);
+
+/* VoDSP RxDP power switch */
+static const struct snd_kcontrol_new rxdp_pwr_sw_control =
+ SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+ RT5625_RXDP_PWR_SFT, 1, 0);
+/* VoDSP RxDC power switch */
+static const struct snd_kcontrol_new rxdc_pwr_sw_control =
+ SOC_DAPM_SINGLE("Switch", RT5625_VODSP_PDM_CTL,
+ RT5625_RXDC_PWR_SFT, 1, 0);
+
+/* VoDSP RxDP source select MUX */
+static const char *rxdp_src_sel[] = {"SRC1 Output", "ADCL to VoDSP",
+ "Voice to Stereo", "ADCR to VoDSP"};
+
+static const struct soc_enum rxdp_src_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_RXDP_S_SFT,
+ ARRAY_SIZE(rxdp_src_sel), rxdp_src_sel);
+
+static const struct snd_kcontrol_new rxdp_src_sel_mux =
+ SOC_DAPM_ENUM("RxDP Source Mux", rxdp_src_sel_enum);
+
+/* PCM source select MUX */
+static const char *pcm_src_sel[] = {"ADCR", "TxDP"};
+
+static const struct soc_enum pcm_src_sel_enum =
+ SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_PCM_S_SFT,
+ ARRAY_SIZE(pcm_src_sel), pcm_src_sel);
+
+static const struct snd_kcontrol_new pcm_src_sel_mux =
+ SOC_DAPM_ENUM("PCM Source Mux", pcm_src_sel_enum);
+
+/* Main stereo record I2S source select MUX */
+static const char *rec_iis_src_sel[] = {"ADC", "Voice to Stereo", "SRC2 Output"};
+
+static const struct soc_enum rec_iis_src_enum =
+ SOC_ENUM_SINGLE(RT5625_VODSP_PDM_CTL, RT5625_REC_IIS_S_SFT,
+ ARRAY_SIZE(rec_iis_src_sel), rec_iis_src_sel);
+
+static const struct snd_kcontrol_new rec_iis_src_mux =
+ SOC_DAPM_ENUM("REC I2S Source Mux", rec_iis_src_enum);
+
+/* SPK volume input select MUX */
+static const char *spkvol_input_sel[] = {"VMID", "HP Mixer", "SPK Mixer", "Mono Mixer"};
+
+static const struct soc_enum spkvol_input_enum =
+ SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_SPKVOL_S_SFT,
+ ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel);
+
+static const struct snd_kcontrol_new spkvol_input_mux =
+ SOC_DAPM_ENUM("SPK Vol Input Mux", spkvol_input_enum);
+
+/* HP volume input select MUX */
+static const char *hpvol_input_sel[] = {"VMID", "HP Mixer"};
+
+static const struct soc_enum hplvol_input_enum =
+ SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_L_S_SFT,
+ ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel);
+
+static const struct snd_kcontrol_new hplvol_input_mux =
+ SOC_DAPM_ENUM("HPL Vol Input Mux", hplvol_input_enum);
+
+static const struct soc_enum hprvol_input_enum =
+ SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_HPVOL_R_S_SFT,
+ ARRAY_SIZE(hpvol_input_sel), hpvol_input_sel);
+
+static const struct snd_kcontrol_new hprvol_input_mux =
+ SOC_DAPM_ENUM("HPR Vol Input Mux", hprvol_input_enum);
+
+/* AUX volume input select MUX */
+static const struct soc_enum auxvol_input_enum =
+ SOC_ENUM_SINGLE(RT5625_OUTMIX_CTRL, RT5625_AUXVOL_S_SFT,
+ ARRAY_SIZE(spkvol_input_sel), spkvol_input_sel);
+
+static const struct snd_kcontrol_new auxvol_input_mux =
+ SOC_DAPM_ENUM("AUX Vol Input Mux", auxvol_input_enum);
+
+static const struct snd_soc_dapm_widget rt5625_dapm_widgets[] = {
+ /* supply */
+ SND_SOC_DAPM_SUPPLY("IIS Interface", RT5625_PWR_ADD1,
+ RT5625_P_I2S_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("PLL1", RT5625_PWR_ADD2,
+ RT5625_P_PLL1_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("PLL2", RT5625_PWR_ADD2,
+ RT5625_P_PLL2_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_VMID("VMID"),
+ SND_SOC_DAPM_SUPPLY("DAC Ref", RT5625_PWR_ADD1,
+ RT5625_P_DAC_REF_BIT, 0, NULL, 0),
+ /* microphone bias */
+ SND_SOC_DAPM_MICBIAS("Mic1 Bias", RT5625_PWR_ADD1,
+ RT5625_P_MB1_BIT, 0),
+ SND_SOC_DAPM_MICBIAS("Mic2 Bias", RT5625_PWR_ADD1,
+ RT5625_P_MB2_BIT, 0),
+
+ /* Input */
+ SND_SOC_DAPM_INPUT("Left LineIn"),
+ SND_SOC_DAPM_INPUT("Right LineIn"),
+ SND_SOC_DAPM_INPUT("Phone"),
+ SND_SOC_DAPM_INPUT("Mic1"),
+ SND_SOC_DAPM_INPUT("Mic2"),
+
+ SND_SOC_DAPM_PGA("Mic1 Boost", RT5625_PWR_ADD3,
+ RT5625_P_MIC1_BST_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mic2 Boost", RT5625_PWR_ADD3,
+ RT5625_P_MIC2_BST_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Phone Rec Mixer", RT5625_PWR_ADD3,
+ RT5625_P_PH_ADMIX_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("Left Rec Mixer", RT5625_PWR_ADD2,
+ RT5625_P_ADCL_RM_BIT, 0, rt5625_adcl_rec_mixer,
+ ARRAY_SIZE(rt5625_adcl_rec_mixer)),
+ SND_SOC_DAPM_MIXER("Right Rec Mixer", RT5625_PWR_ADD2,
+ RT5625_P_ADCR_RM_BIT, 0, rt5625_adcr_rec_mixer,
+ ARRAY_SIZE(rt5625_adcr_rec_mixer)),
+
+ SND_SOC_DAPM_ADC("Left ADC", NULL, RT5625_PWR_ADD2,
+ RT5625_P_ADCL_BIT, 0),
+ SND_SOC_DAPM_ADC("Right ADC", NULL, RT5625_PWR_ADD2,
+ RT5625_P_ADCR_BIT, 0),
+ SND_SOC_DAPM_MUX("PCM src select Mux", SND_SOC_NOPM, 0, 0,
+ &pcm_src_sel_mux),
+ SND_SOC_DAPM_MUX("IIS src select Mux", SND_SOC_NOPM, 0, 0,
+ &rec_iis_src_mux),
+
+ /* Input Stream Audio Interface */
+ SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Voice Capture", 0, SND_SOC_NOPM, 0, 0),
+
+ /* Voice DSP */
+ SND_SOC_DAPM_MUX("SRC2 src select Mux", SND_SOC_NOPM, 0, 0,
+ &src2_src_sel_mux),
+ SND_SOC_DAPM_SWITCH("SRC1 Enable", SND_SOC_NOPM, 0, 0,
+ &src1_pwr_sw_control),
+ SND_SOC_DAPM_SWITCH("SRC2 Enable", SND_SOC_NOPM, 0, 0,
+ &src2_pwr_sw_control),
+ SND_SOC_DAPM_SWITCH("RxDP Enable", SND_SOC_NOPM, 0, 0,
+ &rxdp_pwr_sw_control),
+ SND_SOC_DAPM_SWITCH("RxDC Enable", SND_SOC_NOPM, 0, 0,
+ &rxdc_pwr_sw_control),
+
+ SND_SOC_DAPM_MUX("RxDP src select Mux", SND_SOC_NOPM, 0, 0,
+ &rxdp_src_sel_mux),
+
+ SND_SOC_DAPM_PGA("TxDP", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("TxDC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("PDM", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("RxDP", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("RxDC", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("Voice DSP", SND_SOC_NOPM,
+ 0, 0, NULL, 0, rt5625_vodsp_event,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+ /* Output */
+ /* Output Stream Audio Interface */
+ SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 HiFi Playback",
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Voice Playback",
+ 0, SND_SOC_NOPM, 0, 0),
+
+ /* DAC function select Mux */
+ SND_SOC_DAPM_MUX_E("DAC fun Mux", SND_SOC_NOPM, 0, 0,
+ &dac_fun_sel_mux, rt5625_dac_func_event,
+ SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
+ /* VDAC source select Mux */
+ SND_SOC_DAPM_MUX_E("VDAC src Mux", SND_SOC_NOPM, 0, 0,
+ &vdac_src_sel_mux, rt5625_dac_func_event,
+ SND_SOC_DAPM_PRE_REG | SND_SOC_DAPM_POST_REG),
+
+ SND_SOC_DAPM_DAC("Left DAC", NULL, RT5625_PWR_ADD2,
+ RT5625_P_DACL_BIT, 0),
+ SND_SOC_DAPM_DAC("Right DAC", NULL, RT5625_PWR_ADD2,
+ RT5625_P_DACR_BIT, 0),
+ SND_SOC_DAPM_DAC("Voice DAC", NULL, RT5625_PWR_ADD2,
+ RT5625_P_VDAC_BIT, 0),
+
+ SND_SOC_DAPM_PGA("Mic1 Volume", RT5625_PWR_ADD3,
+ RT5625_P_MIC1_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Mic2 Volume", RT5625_PWR_ADD3,
+ RT5625_P_MIC2_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Left LineIn Volume", RT5625_PWR_ADD3,
+ RT5625_P_LV_L_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right LineIn Volume", RT5625_PWR_ADD3,
+ RT5625_P_LV_R_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Phone Volume", RT5625_PWR_ADD3,
+ RT5625_P_PH_VOL_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_PGA("Left DAC To Mixer", RT5625_PWR_ADD1,
+ RT5625_P_DACL_MIX_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Right DAC To Mixer", RT5625_PWR_ADD1,
+ RT5625_P_DACR_MIX_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("Voice DAC To Mixer", RT5625_PWR_ADD1,
+ RT5625_P_VDAC_MIX_BIT, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("SPK Mixer", RT5625_PWR_ADD2,
+ RT5625_P_SM_BIT, 0, rt5625_spk_mixer,
+ ARRAY_SIZE(rt5625_spk_mixer)),
+ SND_SOC_DAPM_MIXER("Mono HP Mixer", SND_SOC_NOPM, 0, 0,
+ rt5625_hp_mixer, ARRAY_SIZE(rt5625_hp_mixer)),
+ SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
+ rt5625_hpl_mixer, ARRAY_SIZE(rt5625_hpl_mixer)),
+ SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
+ rt5625_hpr_mixer, ARRAY_SIZE(rt5625_hpr_mixer)),
+ SND_SOC_DAPM_MIXER("Mono Mixer", RT5625_PWR_ADD2,
+ RT5625_P_MM_BIT, 0, rt5625_mono_mixer,
+ ARRAY_SIZE(rt5625_mono_mixer)),
+
+ SND_SOC_DAPM_MIXER_E("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0,
+ rt5625_hpmix_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_MIXER("DAC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("SPK Vol Input Mux", SND_SOC_NOPM,
+ 0, 0, &spkvol_input_mux),
+ SND_SOC_DAPM_SUPPLY("SPKL Vol", RT5625_PWR_ADD3,
+ RT5625_P_SPKL_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("SPKR Vol", RT5625_PWR_ADD3,
+ RT5625_P_SPKR_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_MUX("HPL Vol Input Mux", RT5625_PWR_ADD3,
+ RT5625_P_HPL_VOL_BIT, 0, &hplvol_input_mux),
+ SND_SOC_DAPM_MUX("HPR Vol Input Mux", RT5625_PWR_ADD3,
+ RT5625_P_HPR_VOL_BIT, 0, &hprvol_input_mux),
+ SND_SOC_DAPM_MUX("AUX Vol Input Mux", RT5625_PWR_ADD3,
+ RT5625_P_AUX_VOL_BIT, 0, &auxvol_input_mux),
+
+ SND_SOC_DAPM_SUPPLY("SPK Amp", RT5625_PWR_ADD1,
+ RT5625_P_SPK_AMP_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("HP Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
+ rt5625_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_OUTPUT("SPKL"),
+ SND_SOC_DAPM_OUTPUT("SPKR"),
+ SND_SOC_DAPM_OUTPUT("HPL"),
+ SND_SOC_DAPM_OUTPUT("HPR"),
+ SND_SOC_DAPM_OUTPUT("AUX"),
+};
+
+static const struct snd_soc_dapm_route rt5625_dapm_routes[] = {
+ {"DAC Ref", NULL, "IIS Interface"},
+ {"DAC Ref", NULL, "PLL1"},
+ {"DAC Ref", NULL, "PLL2"},
+
+ /* Input */
+ {"Phone Rec Mixer", NULL, "Phone"},
+ {"Mic1 Boost", NULL, "Mic1"},
+ {"Mic2 Boost", NULL, "Mic2"},
+
+ {"Left Rec Mixer", "LineIn Capture Switch", "Left LineIn"},
+ {"Left Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"},
+ {"Left Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
+ {"Left Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
+ {"Left Rec Mixer", "HP Mixer Capture Switch", "Left HP Mixer"},
+ {"Left Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
+ {"Left Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"},
+
+ {"Right Rec Mixer", "LineIn Capture Switch", "Right LineIn"},
+ {"Right Rec Mixer", "Phone Capture Switch", "Phone Rec Mixer"},
+ {"Right Rec Mixer", "Mic1 Capture Switch", "Mic1 Boost"},
+ {"Right Rec Mixer", "Mic2 Capture Switch", "Mic2 Boost"},
+ {"Right Rec Mixer", "HP Mixer Capture Switch", "Right HP Mixer"},
+ {"Right Rec Mixer", "SPK Mixer Capture Switch", "SPK Mixer"},
+ {"Right Rec Mixer", "MoNo Mixer Capture Switch", "Mono Mixer"},
+
+ {"Left ADC", NULL, "DAC Ref"},
+ {"Left ADC", NULL, "Left Rec Mixer"},
+ {"Right ADC", NULL, "DAC Ref"},
+ {"Right ADC", NULL, "Right Rec Mixer"},
+
+ {"PCM src select Mux", "TxDP", "TxDP"},
+ {"PCM src select Mux", "ADCR", "Right ADC"},
+
+ {"IIS src select Mux", "ADC", "Left ADC"},
+ {"IIS src select Mux", "ADC", "Right ADC"},
+ {"IIS src select Mux", "Voice to Stereo", "AIF2RX"},
+ {"IIS src select Mux", "SRC2 Output", "SRC2 Enable"},
+
+ {"AIF2TX", NULL, "IIS Interface"},
+ {"AIF2TX", NULL, "PCM src select Mux"},
+ {"AIF1TX", NULL, "IIS Interface"},
+ {"AIF1TX", NULL, "IIS src select Mux"},
+
+ /* Output */
+ {"AIF1RX", NULL, "IIS Interface"},
+ {"AIF2RX", NULL, "IIS Interface"},
+
+ {"DAC fun Mux", "SRC2 Out", "SRC2 Enable"},
+ {"DAC fun Mux", "TxDP", "TxDP"},
+ {"DAC fun Mux", "TxDC", "TxDC"},
+ {"DAC fun Mux", "Stereo DAC", "AIF1RX"},
+
+ {"VDAC src Mux", "SRC2 Out", "SRC2 Enable"},
+ {"VDAC src Mux", "TxDP", "TxDP"},
+ {"VDAC src Mux", "TxDC", "TxDC"},
+ {"VDAC src Mux", "Voice PCM", "AIF2RX"},
+
+ {"Left DAC", NULL, "DAC Ref"},
+ {"Left DAC", NULL, "DAC fun Mux"},
+ {"Right DAC", NULL, "DAC Ref"},
+ {"Right DAC", NULL, "DAC fun Mux"},
+ {"Voice DAC", NULL, "DAC Ref"},
+ {"Voice DAC", NULL, "VDAC src Mux"},
+
+ {"Left LineIn Volume", NULL, "Left LineIn"},
+ {"Right LineIn Volume", NULL, "Right LineIn"},
+ {"Phone Volume", NULL, "Phone"},
+ {"Mic1 Volume", NULL, "Mic1 Boost"},
+ {"Mic2 Volume", NULL, "Mic2 Boost"},
+
+ {"Left DAC To Mixer", NULL, "Left DAC"},
+ {"Right DAC To Mixer", NULL, "Right DAC"},
+ {"Voice DAC To Mixer", NULL, "Voice DAC"},
+
+ {"DAC Mixer", NULL, "Left DAC To Mixer"},
+ {"DAC Mixer", NULL, "Right DAC To Mixer"},
+ {"Line Mixer", NULL, "Left LineIn Volume"},
+ {"Line Mixer", NULL, "Right LineIn Volume"},
+
+ {"Mono HP Mixer", "LineIn Playback Switch", "Line Mixer"},
+ {"Mono HP Mixer", "Phone Playback Switch", "Phone Volume"},
+ {"Mono HP Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+ {"Mono HP Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+ {"Mono HP Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+ {"Left HP Mixer", "ADC Playback Switch", "Left Rec Mixer"},
+ {"Left HP Mixer", "DAC Playback Switch", "Left DAC To Mixer"},
+ {"Right HP Mixer", "ADC Playback Switch", "Right Rec Mixer"},
+ {"Right HP Mixer", "DAC Playback Switch", "Right DAC To Mixer"},
+
+ {"SPK Mixer", "Line Mixer Playback Switch", "Line Mixer"},
+ {"SPK Mixer", "Phone Playback Switch", "Phone Volume"},
+ {"SPK Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+ {"SPK Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+ {"SPK Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
+ {"SPK Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+
+ {"Mono Mixer", "Line Mixer Playback Switch", "Line Mixer"},
+ {"Mono Mixer", "ADCL Playback Switch","Left Rec Mixer"},
+ {"Mono Mixer", "ADCR Playback Switch","Right Rec Mixer"},
+ {"Mono Mixer", "Mic1 Playback Switch", "Mic1 Volume"},
+ {"Mono Mixer", "Mic2 Playback Switch", "Mic2 Volume"},
+ {"Mono Mixer", "DAC Mixer Playback Switch", "DAC Mixer"},
+ {"Mono Mixer", "Voice DAC Playback Switch", "Voice DAC To Mixer"},
+
+ {"HP Mixer", NULL, "Mono HP Mixer"},
+ {"HP Mixer", NULL, "Left HP Mixer"},
+ {"HP Mixer", NULL, "Right HP Mixer"},
+
+ {"SPK Vol Input Mux", "VMID", "VMID"},
+ {"SPK Vol Input Mux", "HP Mixer", "HP Mixer"},
+ {"SPK Vol Input Mux", "SPK Mixer", "SPK Mixer"},
+ {"SPK Vol Input Mux", "Mono Mixer", "Mono Mixer"},
+ {"SPK Vol Input Mux", NULL, "SPKL Vol"},
+ {"SPK Vol Input Mux", NULL, "SPKR Vol"},
+
+ {"HPL Vol Input Mux", "HP Mixer", "HP Mixer"},
+ {"HPL Vol Input Mux", "VMID", "VMID"},
+ {"HP Amp", NULL, "HPL Vol Input Mux"},
+ {"HPR Vol Input Mux", "HP Mixer", "HP Mixer"},
+ {"HPR Vol Input Mux", "VMID", "VMID"},
+ {"HP Amp", NULL, "HPR Vol Input Mux"},
+
+ {"AUX Vol Input Mux", "VMID", "VMID"},
+ {"AUX Vol Input Mux", "HP Mixer", "HP Mixer"},
+ {"AUX Vol Input Mux", "SPK Mixer", "SPK Mixer"},
+ {"AUX Vol Input Mux", "Mono Mixer", "Mono Mixer"},
+
+ {"SPKL", NULL, "SPK Amp"},
+ {"SPKL", NULL, "SPK Vol Input Mux"},
+ {"SPKR", NULL, "SPK Amp"},
+ {"SPKR", NULL, "SPK Vol Input Mux"},
+ {"HPL", NULL, "HP Amp"},
+ {"HPR", NULL, "HP Amp"},
+ {"AUX", NULL, "AUX Vol Input Mux"},
+
+ /* Voice DSP */
+ {"SRC1 Enable", "Switch", "AIF1RX"},
+
+ {"RxDP src select Mux", "Voice to Stereo", "AIF2RX"},
+ {"RxDP src select Mux", "ADCL to VoDSP", "Left ADC"},
+ {"RxDP src select Mux", "SRC1 Output", "SRC1 Enable"},
+ {"RxDP src select Mux", "ADCR to VoDSP", "Right ADC"},
+
+ {"RxDP Enable", "Switch", "RxDP src select Mux"},
+ {"RxDC Enable", "Switch", "Left ADC"},
+
+ {"RxDP", NULL, "RxDP Enable"},
+ {"RxDC", NULL, "RxDC Enable"},
+ {"PDM", NULL, "Right ADC"},
+
+ {"Voice DSP", NULL, "RxDP"},
+ {"Voice DSP", NULL, "RxDC"},
+ {"Voice DSP", NULL, "PDM"},
+
+ {"TxDP", NULL, "Voice DSP"},
+ {"TxDC", NULL, "Voice DSP"},
+
+ {"SRC2 src select Mux", "TxDP", "TxDP"},
+ {"SRC2 src select Mux", "TxDC", "TxDC"},
+ {"SRC2 Enable", "Switch", "SRC2 src select Mux"},
+};
+
+struct _pll_div{
+ u32 pll_in;
+ u32 pll_out;
+ u16 regvalue;
+};
+
+/**************************************************************
+ * watch out!
+ * our codec support you to select different source as pll input, but if you
+ * use both of the I2S audio interface and pcm interface instantially.
+ * The two DAI must have the same pll setting params, so you have to offer
+ * the same pll input, and set our codec's sysclk the same one, we suggest
+ * 24576000.
+ **************************************************************/
+static const struct _pll_div codec_master_pll1_div[] = {
+ { 2048000, 8192000, 0x0ea0},
+ { 3686400, 8192000, 0x4e27},
+ { 12000000, 8192000, 0x456b},
+ { 13000000, 8192000, 0x495f},
+ { 13100000, 8192000, 0x0320},
+ { 2048000, 11289600, 0xf637},
+ { 3686400, 11289600, 0x2f22},
+ { 12000000, 11289600, 0x3e2f},
+ { 13000000, 11289600, 0x4d5b},
+ { 13100000, 11289600, 0x363b},
+ { 2048000, 16384000, 0x1ea0},
+ { 3686400, 16384000, 0x9e27},
+ { 12000000, 16384000, 0x452b},
+ { 13000000, 16384000, 0x542f},
+ { 13100000, 16384000, 0x03a0},
+ { 2048000, 16934400, 0xe625},
+ { 3686400, 16934400, 0x9126},
+ { 12000000, 16934400, 0x4d2c},
+ { 13000000, 16934400, 0x742f},
+ { 13100000, 16934400, 0x3c27},
+ { 2048000, 22579200, 0x2aa0},
+ { 3686400, 22579200, 0x2f20},
+ { 12000000, 22579200, 0x7e2f},
+ { 13000000, 22579200, 0x742f},
+ { 13100000, 22579200, 0x3c27},
+ { 2048000, 24576000, 0x2ea0},
+ { 3686400, 24576000, 0xee27},
+ { 11289600, 24576000, 0x950F},
+ { 12000000, 24576000, 0x2915},
+ { 12288000, 24576000, 0x0600},
+ { 13000000, 24576000, 0x772e},
+ { 13100000, 24576000, 0x0d20},
+ { 26000000, 24576000, 0x2027},
+ { 26000000, 22579200, 0x392f},
+ { 24576000, 22579200, 0x0921},
+ { 24576000, 24576000, 0x02a0},
+};
+
+static const struct _pll_div codec_bclk_pll1_div[] = {
+ { 256000, 4096000, 0x3ea0},
+ { 352800, 5644800, 0x3ea0},
+ { 512000, 8192000, 0x3ea0},
+ { 705600, 11289600, 0x3ea0},
+ { 1024000, 16384000, 0x3ea0},
+ { 1411200, 22579200, 0x3ea0},
+ { 1536000, 24576000, 0x3ea0},
+ { 2048000, 16384000, 0x1ea0},
+ { 2822400, 22579200, 0x1ea0},
+ { 3072000, 24576000, 0x1ea0},
+ { 705600, 11289600, 0x3ea0},
+ { 705600, 8467200, 0x3ab0},
+ { 2822400, 11289600, 0x1ee0},
+ { 3072000, 12288000, 0x1ee0},
+};
+
+static const struct _pll_div codec_vbclk_pll1_div[] = {
+ { 256000, 4096000, 0x3ea0},
+ { 352800, 5644800, 0x3ea0},
+ { 512000, 8192000, 0x3ea0},
+ { 705600, 11289600, 0x3ea0},
+ { 1024000, 16384000, 0x3ea0},
+ { 1411200, 22579200, 0x3ea0},
+ { 1536000, 24576000, 0x3ea0},
+ { 2048000, 16384000, 0x1ea0},
+ { 2822400, 22579200, 0x1ea0},
+ { 3072000, 24576000, 0x1ea0},
+ { 705600, 11289600, 0x3ea0},
+ { 705600, 8467200, 0x3ab0},
+};
+
+struct _coeff_div_stereo {
+ unsigned int mclk;
+ unsigned int rate;
+ unsigned int reg60;
+ unsigned int reg62;
+};
+
+struct _coeff_div_voice {
+ unsigned int mclk;
unsigned int rate;
unsigned int reg64;
};
+/* bclk is config to 32fs, if codec is choose to be slave mode,
+input bclk should be 32*fs */
static const struct _coeff_div_stereo coeff_div_stereo[] = {
-
- /*bclk is config to 32fs, if codec is choose to be slave mode , input bclk should be 32*fs */
- {24576000, 48000, 0x3174, 0x1010},
- {12288000, 48000, 0x1174, 0x0000},
- {18432000, 48000, 0x2174, 0x1111},
- {36864000, 48000, 0x2274, 0x2020},
- {49152000, 48000, 0xf074, 0x3030},
- {24576000, 48000, 0x3172, 0x1010},
- {24576000, 8000, 0xB274, 0x2424},
- {24576000, 16000, 0xB174, 0x2222},
- {24576000, 32000, 0xB074, 0x2121},
- {22579200, 11025, 0X3374, 0x1414},
- {22579200, 22050, 0X3274, 0x1212},
- {22579200, 44100, 0X3174, 0x1010},
- {0, 0, 0, 0},
+ {24576000, 48000, 0x3174, 0x1010},
+ {12288000, 48000, 0x1174, 0x0000},
+ {18432000, 48000, 0x2174, 0x1111},
+ {36864000, 48000, 0x2274, 0x2020},
+ {49152000, 48000, 0xf074, 0x3030},
+ {24576000, 48000, 0x3172, 0x1010},
+ {24576000, 8000, 0xB274, 0x2424},
+ {24576000, 16000, 0xB174, 0x2222},
+ {24576000, 32000, 0xB074, 0x2121},
+ {22579200, 11025, 0X3374, 0x1414},
+ {22579200, 22050, 0X3274, 0x1212},
+ {22579200, 44100, 0X3174, 0x1010},
+ {12288000, 8000, 0xB174, 0x2222},
+ {11289600, 44100, 0X3072, 0x0000},
};
+/* bclk is config to 32fs, if codec is choose to be slave mode,
+input bclk should be 32*fs */
static const struct _coeff_div_voice coeff_div_voice[] = {
-
- /*bclk is config to 32fs, if codec is choose to be slave mode , input bclk should be 32*fs */
- {24576000, 16000, 0x2622},
- {24576000, 8000, 0x2824},
- {0, 0, 0},
+ {24576000, 16000, 0x2622},
+ {24576000, 8000, 0x2824},
+ {2048000,8000,0x3000},
};
static int get_coeff(unsigned int mclk, unsigned int rate, int mode)
{
int i;
- DBG("get_coeff mclk = %d, rate = %d, mode = %d\n", mclk, rate, mode);
+ pr_info("mclk = %d, rate = %d, mode = %d\n", mclk, rate, mode);
- if (!mode) {
+ if (!mode)
for (i = 0; i < ARRAY_SIZE(coeff_div_stereo); i++) {
- if ((coeff_div_stereo[i].rate == rate) && (coeff_div_stereo[i].mclk == mclk))
+ if ((coeff_div_stereo[i].rate == rate) &&
+ (coeff_div_stereo[i].mclk == mclk))
return i;
}
- } else {
+ else
for (i = 0; i< ARRAY_SIZE(coeff_div_voice); i++) {
- if ((coeff_div_voice[i].rate == rate) && (coeff_div_voice[i].mclk == mclk))
+ if ((coeff_div_voice[i].rate == rate) &&
+ (coeff_div_voice[i].mclk == mclk))
return i;
}
- }
- printk("can't find a matched mclk and rate in %s\n",
+ pr_err("can't find a matched mclk and rate in %s\n",
(mode ? "coeff_div_voice[]" : "coeff_div_audio[]"));
return -EINVAL;
}
-static int rt5625_codec_set_dai_pll(struct snd_soc_dai *codec_dai,
- int pll_id, unsigned int freq_in, unsigned int freq_out)
+static int rt5625_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
{
- int i;
- int ret = -EINVAL;
- struct snd_soc_codec *codec = codec_dai->codec;
-
- DBG("enter %s pll_id = %d freq_in = %d freq_out = %d\n",
- __func__, pll_id, freq_in, freq_out);
+ struct snd_soc_codec *codec = dai->codec;
+ int i, ret = -EINVAL;
- if (pll_id < RT5625_PLL1_FROM_MCLK || pll_id > RT5625_PLL1_FROM_VBCLK)
+ if (pll_id < RT5625_PLL_MCLK || pll_id > RT5625_PLL_VBCLK)
return -EINVAL;
- if (!freq_in || !freq_out)
+ if (!freq_in || !freq_out) {
+ dev_info(dai->dev, "PLL is closed\n");
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_MASK, RT5625_SCLK_MCLK);
return 0;
+ }
- if (RT5625_PLL1_FROM_MCLK == pll_id) {
-
+ if (RT5625_PLL_MCLK == pll_id) {
+ for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++)
+ if ((freq_in == codec_master_pll1_div[i].pll_in) &&
+ (freq_out == codec_master_pll1_div[i].pll_out)) {
+ snd_soc_write(codec, RT5625_GEN_CTRL2,
+ RT5625_PLL1_S_MCLK);
+ snd_soc_write(codec, RT5625_PLL_CTRL,
+ codec_master_pll1_div[i].regvalue);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
+ ret = 0;
+ break;
+ }
+ } else if (RT5625_PLL_MCLK_TO_VSYSCLK == pll_id) {
for (i = 0; i < ARRAY_SIZE(codec_master_pll1_div); i ++)
{
if ((freq_in == codec_master_pll1_div[i].pll_in) && (freq_out == codec_master_pll1_div[i].pll_out))
{
- rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x0000); /*PLL source from MCLK*/
- rt5625_write(codec, RT5625_PLL_CTRL, codec_master_pll1_div[i].regvalue); /*set pll code*/
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000); /*enable pll1 power*/
- rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+ snd_soc_write(codec, RT5625_GEN_CTRL2, 0x0000); /*PLL source from MCLK*/
+ snd_soc_write(codec, RT5625_PLL_CTRL, codec_master_pll1_div[i].regvalue); /*set pll code*/
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1, 0x0030, 0x0030); /* Voice SYSCLK source from FLL1 */
ret = 0;
}
}
- } else if (RT5625_PLL1_FROM_BCLK == pll_id) {
-
+ }else if (RT5625_PLL_BCLK == pll_id) {
for (i = 0; i < ARRAY_SIZE(codec_bclk_pll1_div); i ++)
- {
- if ((freq_in == codec_bclk_pll1_div[i].pll_in) && (freq_out == codec_bclk_pll1_div[i].pll_out))
- {
- rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x2000); /*PLL source from BCLK*/
- rt5625_write(codec, RT5625_PLL_CTRL, codec_bclk_pll1_div[i].regvalue); /*set pll1 code*/
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000); /*enable pll1 power*/
- rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+ if ((freq_in == codec_bclk_pll1_div[i].pll_in) &&
+ (freq_out == codec_bclk_pll1_div[i].pll_out)) {
+ snd_soc_write(codec, RT5625_GEN_CTRL2,
+ RT5625_PLL1_S_BCLK);
+ snd_soc_write(codec, RT5625_PLL_CTRL,
+ codec_bclk_pll1_div[i].regvalue);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
ret = 0;
+ break;
}
- }
- } else if (RT5625_PLL1_FROM_VBCLK == pll_id) {
-
+ } else if (RT5625_PLL_VBCLK == pll_id) {
for (i = 0; i < ARRAY_SIZE(codec_vbclk_pll1_div); i ++)
- {
- if ((freq_in == codec_vbclk_pll1_div[i].pll_in) && (freq_out == codec_vbclk_pll1_div[i].pll_out))
- {
- rt5625_write(codec, RT5625_GEN_CTRL_REG2, 0x3000); /*PLL source from VBCLK*/
- rt5625_write(codec, RT5625_PLL_CTRL, codec_vbclk_pll1_div[i].regvalue); /*set pll1 code*/
- rt5625_write_mask(codec, RT5625_PWR_MANAG_ADD2, 0x8000, 0x8000); /*enable pll1 power*/
- rt5625_write_mask(codec, RT5625_GEN_CTRL_REG1, 0x8000, 0x8000);
+ if ((freq_in == codec_vbclk_pll1_div[i].pll_in) &&
+ (freq_out == codec_vbclk_pll1_div[i].pll_out)) {
+ snd_soc_write(codec, RT5625_GEN_CTRL2,
+ RT5625_PLL1_S_VBCLK);
+ snd_soc_write(codec, RT5625_PLL_CTRL,
+ codec_vbclk_pll1_div[i].regvalue);
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_MASK, RT5625_SCLK_PLL1);
ret = 0;
+ break;
}
- }
}
- return 0;
+
+ return ret;
}
-static int rt5625_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+static int rt5625_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct rt5625_priv * rt5625 = codec->private_data;
+ struct snd_soc_codec *codec = dai->codec;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ unsigned int val = 0;
- DBG("sysclk freq %u for audio i2s\n", freq);
-
- if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
+ switch (dai->id) {
+ case RT5625_AIF1:
+ if (freq == rt5625->stereo_sysclk)
+ return 0;
rt5625->stereo_sysclk = freq;
- return 0;
+ break;
+
+ case RT5625_AIF2:
+ if (freq == rt5625->voice_sysclk)
+ return 0;
+ rt5625->voice_sysclk = freq;
+ break;
+
+ default:
+ return -EINVAL;
}
-
- printk("unsupported sysclk freq %u for audio i2s\n", freq);
- rt5625->stereo_sysclk=24576000;
-
- return 0;
-}
-static int rt5625_voice_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- struct rt5625_priv * rt5625 = codec->private_data;
+ switch (clk_id) {
+ case RT5625_SCLK_S_MCLK:
+ break;
- DBG("sysclk freq %u for voice pcm\n", freq);
+ case RT5625_SCLK_S_PLL:
+ val |= RT5625_SCLK_PLL1;
+ break;
- if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
- rt5625->voice_sysclk = freq;
- return 0;
- }
+ default:
+ dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
+ return -EINVAL;
+ }
+ snd_soc_update_bits(codec, RT5625_GEN_CTRL1,
+ RT5625_SCLK_MASK, val);
- printk("unsupported sysclk freq %u for voice pcm\n", freq);
- rt5625->voice_sysclk = 24576000;
+ dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
return 0;
}
-
-static int rt5625_hifi_pcm_hw_params(struct snd_pcm_substream *substream,
+static int rt5625_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_device *socdev = rtd->socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
- struct rt5625_priv *rt5625 = codec->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ unsigned int iface = 0, rate = params_rate(params), coeff;
- unsigned int iface = rt5625_read(codec, RT5625_MAIN_SDP_CTRL) & 0xfff3;
- int rate = params_rate(params);
- int coeff = get_coeff(rt5625->stereo_sysclk, rate, 0);
-
- DBG("enter %s rate = %d \n", __func__, rate);
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ break;
- switch (params_format(params))
- {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- case SNDRV_PCM_FORMAT_S8:
- iface |= 0x000c;
- }
-
- rt5625_write(codec, RT5625_MAIN_SDP_CTRL, iface);
- rt5625_write_mask(codec, 0x3a, 0xc801, 0xc801); /*power i2s and dac ref*/
- if (coeff >= 0) {
- rt5625_write(codec, RT5625_STEREO_DAC_CLK_CTRL1, coeff_div_stereo[coeff].reg60);
- rt5625_write(codec, RT5625_STEREO_DAC_CLK_CTRL2, coeff_div_stereo[coeff].reg62);
+ case SNDRV_PCM_FORMAT_S20_3LE:
+ iface |= RT5625_I2S_DL_20;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE:
+ iface |= RT5625_I2S_DL_24;
+ break;
+
+ case SNDRV_PCM_FORMAT_S8:
+ iface |= RT5625_I2S_DL_8;
+ break;
+
+ default:
+ return -EINVAL;
}
-
- return 0;
-}
-static int rt5625_voice_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_device *socdev = rtd->socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
- struct rt5625_priv *rt5625 = codec->private_data;
- struct snd_soc_dapm_widget *w;
- unsigned int iface = rt5625_read(codec, RT5625_EXTEND_SDP_CTRL) & 0xfff3;
- int rate = params_rate(params);
- int coeff = get_coeff(rt5625->voice_sysclk, rate, 1);
+ switch (dai->id) {
+ case RT5625_AIF1:
+ coeff = get_coeff(rt5625->stereo_sysclk, rate, 0);
+ if (coeff < 0) {
+ dev_err(codec->dev, "Unsupported clock setting\n");
+ return -EINVAL;
+ }
+ snd_soc_write(codec, RT5625_DAC_CLK_CTRL1,
+ coeff_div_stereo[coeff].reg60);
+ snd_soc_write(codec, RT5625_DAC_CLK_CTRL2,
+ coeff_div_stereo[coeff].reg62);
+ snd_soc_update_bits(codec, RT5625_SDP_CTRL,
+ RT5625_I2S_DL_MASK, iface);
+ break;
- DBG("enter %s rate = %d \n", __func__, rate);
+ case RT5625_AIF2:
+ rate = 8000;
+ coeff = get_coeff(rt5625->voice_sysclk, rate, 1);
+ if (coeff < 0) {
+ dev_err(codec->dev, "Unsupported clock setting\n");
+ return -EINVAL;
+ }
+ snd_soc_write(codec, RT5625_VDAC_CLK_CTRL1,
+ coeff_div_voice[coeff].reg64);
+ iface |= 0x0100; //Voice SYSCLK source from FLL1
+ snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+ RT5625_I2S_DL_MASK, iface);
+ break;
- list_for_each_entry(w, &codec->dapm_widgets, list)
- {
- if (!w->sname)
- continue;
- if (!strcmp(w->name, "Right ADC"))
- strcpy(w->sname, "Right ADC Voice Capture");
+ default:
+ return -EINVAL;
}
-
- switch (params_format(params))
- {
- case SNDRV_PCM_FORMAT_S16_LE:
- break;
- case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= 0x0004;
- case SNDRV_PCM_FORMAT_S24_LE:
- iface |= 0x0008;
- case SNDRV_PCM_FORMAT_S8:
- iface |= 0x000c;
- }
- rt5625_write_mask(codec, 0x3a, 0x0801, 0x0801); /*power i2s and dac ref*/
- rt5625_write(codec, RT5625_EXTEND_SDP_CTRL, iface);
- if (coeff >= 0)
- rt5625_write(codec, RT5625_VOICE_DAC_PCMCLK_CTRL1, coeff_div_voice[coeff].reg64);
+
+#ifdef RT5625_F_SMT_PHO
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ rt5625->app_bmp |= RT5625_PLY_MASK;
+ else
+ rt5625->app_bmp |= RT5625_REC_MASK;
+#endif
return 0;
}
-
-static int rt5625_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+static int rt5625_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
+ struct snd_soc_codec *codec = dai->codec;
+ unsigned int iface = 0;
+ bool slave;
- struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = 0;
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ slave = false;
+ break;
- DBG("enter %s fmt = %d\n", __func__, fmt);
+ case SND_SOC_DAIFMT_CBS_CFS:
+ slave = true;
+ break;
- /*set master/slave interface*/
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK)
- {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0000;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface = 0x8000;
- break;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
- /*interface format*/
- switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK)
- {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0000;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0003;
- break;
- default:
- return -EINVAL;
- }
-
- /*clock inversion*/
- switch (fmt & SND_SOC_DAIFMT_INV_MASK)
- {
- case SND_SOC_DAIFMT_NB_NF:
- iface |= 0x0000;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- default:
- return -EINVAL;
- }
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ break;
- rt5625_write(codec, RT5625_MAIN_SDP_CTRL, iface);
- return 0;
-}
+ case SND_SOC_DAIFMT_LEFT_J:
+ iface |= RT5625_I2S_DF_LEFT;
+ break;
-static int rt5625_voice_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
-{
- struct snd_soc_codec *codec = codec_dai->codec;
- int iface;
+ case SND_SOC_DAIFMT_DSP_A:
+ iface |= RT5625_I2S_DF_PCM_A;
+ break;
- DBG("enter %s\n", __func__);
- /*set slave/master mode*/
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK)
- {
- case SND_SOC_DAIFMT_CBM_CFM:
- iface = 0x0000;
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- iface = 0x4000;
- break;
- default:
- return -EINVAL;
- }
+ case SND_SOC_DAIFMT_DSP_B:
+ iface |= RT5625_I2S_DF_PCM_B;
+ break;
- switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK)
- {
- case SND_SOC_DAIFMT_I2S:
- iface |= 0x0000;
- break;
- case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0001;
- break;
- case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x0002;
- break;
- case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x0003;
- break;
- default:
- return -EINVAL;
- }
-
- /*clock inversion*/
- switch (fmt & SND_SOC_DAIFMT_INV_MASK)
- {
- case SND_SOC_DAIFMT_NB_NF:
- iface |= 0x0000;
- break;
- case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0080;
- break;
- default:
- return -EINVAL;
+ default:
+ return -EINVAL;
}
- iface |= 0x8000; /*enable vopcm*/
- rt5625_write(codec, RT5625_EXTEND_SDP_CTRL, iface);
- return 0;
-}
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ iface |= RT5625_I2S_BP_INV;
+ break;
-static int rt5625_hifi_codec_mute(struct snd_soc_dai *dai, int mute)
-{
- struct snd_soc_codec *codec = dai->codec;
+ default:
+ return -EINVAL;
+ }
+ iface |= 0x8000; /*enable vopcm*/
+
+ switch (dai->id) {
+ case RT5625_AIF1:
+ if (slave)
+ iface |= RT5625_I2S_M_SLV;
+ snd_soc_update_bits(codec, RT5625_SDP_CTRL,
+ RT5625_I2S_M_MASK | RT5625_I2S_BP_MASK |
+ RT5625_I2S_DF_MASK, iface);
+ break;
- if (mute)
- rt5625_write_mask(codec, RT5625_STEREO_DAC_VOL, 0x8080, 0x8080);
- else
- rt5625_write_mask(codec, RT5625_STEREO_DAC_VOL, 0x0000, 0x8080);
+ case RT5625_AIF2:
+ if (slave)
+ iface |= RT5625_PCM_M_SLV;
+ snd_soc_update_bits(codec, RT5625_EXT_SDP_CTRL,
+ RT5625_PCM_M_MASK | RT5625_I2S_BP_MASK |
+ RT5625_I2S_DF_MASK, iface);
+ break;
+
+ default:
+ return -EINVAL;
+ }
return 0;
}
-static int rt5625_voice_codec_mute(struct snd_soc_dai *dai, int mute)
+#ifdef RT5625_F_SMT_PHO
+static int rt5625_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
{
- struct snd_soc_codec *codec = dai->codec;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct rt5625_priv *rt5625 = snd_soc_codec_get_drvdata(codec);
+ int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ if (capture)
+ rt5625->app_bmp |= RT5625_REC_MASK;
+ else
+ rt5625->app_bmp |= RT5625_PLY_MASK;
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ if (capture)
+ rt5625->app_bmp &= ~RT5625_REC_MASK;
+ else
+ rt5625->app_bmp &= ~RT5625_PLY_MASK;
+ rt5625->app_bmp &= ~RT5625_VOIP_MASK;
+ break;
+
+ default:
+ break;
+ }
- if (mute)
- rt5625_write_mask(codec, RT5625_VOICE_DAC_OUT_VOL, 0x1000, 0x1000);
- else
- rt5625_write_mask(codec, RT5625_VOICE_DAC_OUT_VOL, 0x0000, 0x1000);
return 0;
}
-
+#endif
static int rt5625_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
switch(level) {
case SND_SOC_BIAS_ON:
+#ifdef RT5625_DEMO
+ snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE, 0);
+ snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE, 0);
+#endif
break;
+
case SND_SOC_BIAS_PREPARE:
- rt5625_write(codec, 0x26, 0x0000);
- rt5625_write_mask(codec, 0x3c, 0x2000, 0x2000);
- rt5625_write_mask(codec, 0x3a, 0x000e, 0x000e);
+ snd_soc_write(codec, RT5625_PD_CTRL, 0x0000);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_MB1 | RT5625_P_MB2,
+ RT5625_P_MB1 | RT5625_P_MB2);
break;
+
case SND_SOC_BIAS_STANDBY:
+#ifdef RT5625_DEMO
+ snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE,
+ RT5625_L_MUTE | RT5625_R_MUTE);
+ snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE,
+ RT5625_L_MUTE | RT5625_R_MUTE);
+ snd_soc_update_bits(codec, RT5625_PWR_ADD1,
+ RT5625_P_MB1 | RT5625_P_MB2, 0);
+#endif
+ if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
+ snd_soc_write(codec, RT5625_PD_CTRL, 0);
+ snd_soc_write(codec, RT5625_PWR_ADD1,
+ RT5625_P_MAIN_BIAS);
+ snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF);
+ codec->cache_only = false;
+ snd_soc_cache_sync(codec);
+ }
break;
+
case SND_SOC_BIAS_OFF:
- rt5625_write_mask(codec, 0x04, 0x8080, 0x8080); /*mute hp*/
- rt5625_write_mask(codec, 0x02, 0x8080, 0x8080); /*mute spk*/
- rt5625_write(codec, 0x3e, 0x0000); //power off all bit
- rt5625_write(codec, 0x3a, 0x0000); //power off all bit
- rt5625_write(codec, 0x3c, 0x0000); //power off all bit
+#ifdef RT5625_DEMO
+ snd_soc_update_bits(codec, RT5625_HP_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE,
+ RT5625_L_MUTE | RT5625_R_MUTE);
+ snd_soc_update_bits(codec, RT5625_SPK_OUT_VOL,
+ RT5625_L_MUTE | RT5625_R_MUTE,
+ RT5625_L_MUTE | RT5625_R_MUTE);
+#endif
+ snd_soc_write(codec, RT5625_PWR_ADD1, 0x0000);
+ snd_soc_write(codec, RT5625_PWR_ADD2, 0x0000);
+ snd_soc_write(codec, RT5625_PWR_ADD3, 0x0000);
break;
}
- codec->bias_level = level;
+ codec->dapm.bias_level = level;
+
+ return 0;
+}
+
+#ifdef RT5625_PROC
+static int rt5625_proc_init(void);
+#endif
+
+static int rt5625_probe(struct snd_soc_codec *codec)
+{
+ int ret;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+ if (ret != 0) {
+ dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+ return ret;
+ }
+
+ #ifdef RT5625_PROC
+ rt5625_proc_init();
+ #endif
+
+ rt5625_reset(codec);
+ snd_soc_write(codec, RT5625_PD_CTRL, 0);
+ snd_soc_write(codec, RT5625_PWR_ADD1, RT5625_P_MAIN_BIAS);
+ snd_soc_write(codec, RT5625_PWR_ADD2, RT5625_P_VREF);
+#ifdef RT5625_DEMO
+ rt5625_reg_init(codec);
+#endif
+ codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
+ rt5625_codec = codec;
return 0;
}
+static int rt5625_remove(struct snd_soc_codec *codec)
+{
+ rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
-#define RT5625_STEREO_RATES SNDRV_PCM_RATE_8000_48000
+#ifdef CONFIG_PM
+static int rt5625_suspend(struct snd_soc_codec *codec, pm_message_t state)
+{
+ rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
+ return 0;
+}
-#define RT5626_VOICE_RATES SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000
+static int rt5625_resume(struct snd_soc_codec *codec)
+{
+ rt5625_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+ return 0;
+}
+#else
+#define rt5625_suspend NULL
+#define rt5625_resume NULL
+#endif
+#define RT5625_STEREO_RATES SNDRV_PCM_RATE_8000_48000
+#define RT5625_VOICE_RATES SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000
#define RT5625_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S8)
-static struct snd_soc_dai_ops rt5625_dai_ops_hifi = {
-
- .hw_params = rt5625_hifi_pcm_hw_params,
-// .digital_mute = rt5625_hifi_codec_mute,
- .set_fmt = rt5625_hifi_codec_set_dai_fmt,
- .set_pll = rt5625_codec_set_dai_pll,
- .set_sysclk = rt5625_hifi_codec_set_dai_sysclk,
-
-};
-
-
-static struct snd_soc_dai_ops rt5625_dai_ops_voice = {
-
- .hw_params = rt5625_voice_pcm_hw_params,
-// .digital_mute = rt5625_voice_codec_mute,
- .set_fmt = rt5625_voice_codec_set_dai_fmt,
- .set_pll = rt5625_codec_set_dai_pll,
- .set_sysclk = rt5625_voice_codec_set_dai_sysclk,
-
+struct snd_soc_dai_ops rt5625_aif_dai_ops = {
+#ifdef RT5625_F_SMT_PHO
+ .trigger = rt5625_trigger,
+#endif
+ .hw_params = rt5625_hw_params,
+ .set_fmt = rt5625_set_dai_fmt,
+ .set_sysclk = rt5625_set_dai_sysclk,
+ .set_pll = rt5625_set_dai_pll,
};
-
-
-struct snd_soc_dai rt5625_dai[] = {
- /*hifi codec dai*/
+struct snd_soc_dai_driver rt5625_dai[] = {
{
- .name = "RT5625 HiFi",
- .id = 1,
+ .name = "rt5625-aif1",
+ .id = RT5625_AIF1,
.playback = {
.stream_name = "HiFi Playback",
.channels_min = 1,
.rates = RT5625_STEREO_RATES,
.formats = RT5625_FORMATS,
},
-
- .ops = &rt5625_dai_ops_hifi,
+ .ops = &rt5625_aif_dai_ops,
},
-
- /*voice codec dai*/
{
- .name = "RT5625 Voice",
- .id = 2,
+ .name = "rt5625-aif2",
+ .id = RT5625_AIF2,
.playback = {
.stream_name = "Voice Playback",
.channels_min = 1,
- .channels_max = 1,
- .rates = RT5626_VOICE_RATES,
+ .channels_max = 2,
+ .rates = RT5625_VOICE_RATES,
.formats = RT5625_FORMATS,
},
.capture = {
.stream_name = "Voice Capture",
.channels_min = 1,
- .channels_max = 1,
- .rates = RT5626_VOICE_RATES,
+ .channels_max = 2,
+ .rates = RT5625_VOICE_RATES,
.formats = RT5625_FORMATS,
},
-
- .ops = &rt5625_dai_ops_voice,
-
+ .ops = &rt5625_aif_dai_ops,
},
};
-EXPORT_SYMBOL_GPL(rt5625_dai);
-
-
-static void rt5625_work(struct work_struct *work)
-{
- struct snd_soc_codec *codec =
- container_of(work, struct snd_soc_codec, delayed_work.work);
- rt5625_set_bias_level(codec, codec->bias_level);
-}
-
-
-#if defined(CONFIG_SND_HWDEP)
-
-#if REALTEK_HWDEP
-
-#define RT_CE_CODEC_HWDEP_NAME "rt56xx hwdep "
-
-
-static int rt56xx_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
- DBG("enter %s\n", __func__);
- return 0;
-}
-
-static int rt56xx_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
- DBG("enter %s\n", __func__);
- return 0;
-}
-
-
-static int rt56xx_hwdep_ioctl_common(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct rt56xx_cmd rt56xx;
- struct rt56xx_cmd __user *_rt56xx = arg;
- struct rt56xx_reg_state *buf;
- struct rt56xx_reg_state *p;
- struct snd_soc_codec *codec = hw->private_data;
-
- if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx)))
- return -EFAULT;
- buf = kmalloc(sizeof(*buf) * rt56xx.number, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- if (copy_from_user(buf, rt56xx.buf, sizeof(*buf) * rt56xx.number)) {
- goto err;
- }
- switch (cmd) {
- case RT_READ_CODEC_REG_IOCTL:
- for (p = buf; p < buf + rt56xx.number; p++)
- {
- p->reg_value = codec->read(codec, p->reg_index);
- }
- if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * rt56xx.number))
- goto err;
-
- break;
- case RT_WRITE_CODEC_REG_IOCTL:
- for (p = buf; p < buf + rt56xx.number; p++)
- codec->write(codec, p->reg_index, p->reg_value);
- break;
- }
-
- kfree(buf);
- return 0;
+static struct snd_soc_codec_driver soc_codec_dev_rt5625 = {
+ .probe = rt5625_probe,
+ .remove = rt5625_remove,
+ .suspend = rt5625_suspend,
+ .resume = rt5625_resume,
+ .set_bias_level = rt5625_set_bias_level,
+ .reg_cache_size = 0x80,
+ .reg_word_size = sizeof(u16),
+ .reg_cache_default = rt5625_reg,
+ .volatile_register = rt5625_volatile_register,
+ .readable_register = rt5625_readable_register,
+ .reg_cache_step = 1,
+ .controls = rt5625_snd_controls,
+ .num_controls = ARRAY_SIZE(rt5625_snd_controls),
+ .dapm_widgets = rt5625_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rt5625_dapm_widgets),
+ .dapm_routes = rt5625_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(rt5625_dapm_routes),
+};
-err:
- kfree(buf);
- return -EFAULT;
-
-}
+static const struct i2c_device_id rt5625_i2c_id[] = {
+ { "rt5625", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, rt5625_i2c_id);
-static int rt56xx_codec_dump_reg(struct snd_hwdep *hw, struct file *file, unsigned long arg)
+static int rt5625_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
{
- struct rt56xx_cmd rt56xx;
- struct rt56xx_cmd __user *_rt56xx = arg;
- struct rt56xx_reg_state *buf;
- struct snd_soc_codec *codec = hw->private_data;
- int number = codec->reg_cache_size;
- int i;
+ struct rt5625_priv *rt5625;
+ int ret;
- DBG("enter %s, number = %d\n", __func__, number);
- if (copy_from_user(&rt56xx, _rt56xx, sizeof(rt56xx)))
- return -EFAULT;
-
- buf = kmalloc(sizeof(*buf) * number, GFP_KERNEL);
- if (buf == NULL)
+ rt5625 = kzalloc(sizeof(struct rt5625_priv), GFP_KERNEL);
+ if (NULL == rt5625)
return -ENOMEM;
- for (i = 0; i < number; i++)
- {
- buf[i].reg_index = i << 1;
- buf[i].reg_value = codec->read(codec, buf[i].reg_index);
- }
- if (copy_to_user(rt56xx.buf, buf, sizeof(*buf) * i))
- goto err;
- rt56xx.number = number;
- if (copy_to_user(_rt56xx, &rt56xx, sizeof(rt56xx)))
- goto err;
- kfree(buf);
- return 0;
-err:
- kfree(buf);
- return -EFAULT;
-
-}
-
-static int rt56xx_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
-{
- if (cmd == RT_READ_ALL_CODEC_REG_IOCTL)
- {
- return rt56xx_codec_dump_reg(hw, file, arg);
- }
- else
- {
- return rt56xx_hwdep_ioctl_common(hw, file, cmd, arg);
- }
-}
-
-int realtek_ce_init_hwdep(struct snd_soc_codec *codec)
-{
- struct snd_hwdep *hw;
- struct snd_card *card = codec->card;
- int err;
-
- if ((err = snd_hwdep_new(card, RT_CE_CODEC_HWDEP_NAME, 0, &hw)) < 0)
- return err;
-
- strcpy(hw->name, RT_CE_CODEC_HWDEP_NAME);
- hw->private_data = codec;
- hw->ops.open = rt56xx_hwdep_open;
- hw->ops.release = rt56xx_hwdep_release;
- hw->ops.ioctl = rt56xx_hwdep_ioctl;
- return 0;
-}
-
-#endif
-
-#endif
+ i2c_set_clientdata(i2c, rt5625);
-static int rt5625_init(struct snd_soc_device *socdev)
-{
-
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret = 0;
-
- codec->name = "RT5625";
- codec->owner = THIS_MODULE;
- codec->read = rt5625_read;
- codec->write = rt5625_write;
- codec->set_bias_level = rt5625_set_bias_level;
- codec->dai= rt5625_dai;
- codec->num_dai = 2;
- codec->reg_cache_step = 2;
- codec->reg_cache_size = ARRAY_SIZE(rt5625_reg)*2;
- codec->reg_cache = kmemdup(rt5625_reg, sizeof(rt5625_reg), GFP_KERNEL);
- if (codec->reg_cache == NULL)
- return -ENOMEM;
-
- rt5625_reset(codec);
-
- ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
- if (ret < 0 )
- {
- printk(KERN_ERR "rt5625: failed to create pcms\n");
- goto pcm_err;
- }
-
- rt5625_write(codec, RT5625_PD_CTRL_STAT, 0);
- rt5625_write(codec, RT5625_PWR_MANAG_ADD1, PWR_MAIN_BIAS);
- rt5625_write(codec, RT5625_PWR_MANAG_ADD2, PWR_MIXER_VREF);
- rt5625_reg_init(codec);
- rt5625_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->bias_level = SND_SOC_BIAS_STANDBY;
- schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(80));
-
-#if (RT5625_EQ_FUNC_ENA==1)
- rt5625_update_eqmode(codec,POP);
-#endif
-
- rt5625_add_controls(codec);
- rt5625_add_widgets(codec);
-
- #if defined(CONFIG_SND_HWDEP)
-
- #if REALTEK_HWDEP
-
- realtek_ce_init_hwdep(codec);
-
- #endif
-
- #endif
-
- ret = snd_soc_init_card(socdev);
-
- if (ret < 0)
- {
- printk(KERN_ERR "rt5625: failed to register card\n");
- goto card_err;
- }
- DBG("rt5625: initial ok\n");
- return 0;
-
- card_err:
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
-
- pcm_err:
- kfree(codec->reg_cache);
- return ret;
-
-
-}
-
-
-static int rt5625_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
-{
- struct snd_soc_device *socdev = rt5625_socdev;
- struct snd_soc_codec *codec = socdev->card->codec;
- int ret;
-
- i2c_set_clientdata(i2c, codec);
- codec->control_data = i2c;
-
- ret = rt5625_init(socdev);
+ ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5625,
+ rt5625_dai, ARRAY_SIZE(rt5625_dai));
if (ret < 0)
- pr_err("failed to initialise rt5625\n");
+ kfree(rt5625);
return ret;
}
-static int rt5625_i2c_remove(struct i2c_client *client)
+static __devexit int rt5625_i2c_remove(struct i2c_client *i2c)
{
- struct snd_soc_codec *codec = i2c_get_clientdata(client);
- kfree(codec->reg_cache);
+ snd_soc_unregister_codec(&i2c->dev);
+ kfree(i2c_get_clientdata(i2c));
return 0;
}
-static const struct i2c_device_id rt5625_i2c_id[] = {
- {"rt5625", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, rt5625_i2c_id);
-static struct i2c_driver rt5625_i2c_driver = {
+struct i2c_driver rt5625_i2c_driver = {
.driver = {
- .name = "RT5625 I2C Codec",
+ .name = "rt5625",
.owner = THIS_MODULE,
},
- .probe = rt5625_i2c_probe,
- .remove = rt5625_i2c_remove,
+ .probe = rt5625_i2c_probe,
+ .remove = __devexit_p(rt5625_i2c_remove),
.id_table = rt5625_i2c_id,
};
-
-static int rt5625_add_i2c_device(struct platform_device *pdev,
- const struct rt5625_setup_data *setup)
+static int __init rt5625_modinit(void)
{
-#if 0
- struct i2c_board_info info;
- struct i2c_adapter *adapter;
- struct i2c_client *client;
-#endif
- int ret;
-
- ret = i2c_add_driver(&rt5625_i2c_driver);
- if (ret != 0) {
- dev_err(&pdev->dev, "can't add i2c driver\n");
- return ret;
- }
-#if 0
- memset(&info, 0, sizeof(struct i2c_board_info));
- info.addr = setup->i2c_address;
- strlcpy(info.type, "rt5625", I2C_NAME_SIZE);
-
- adapter = i2c_get_adapter(setup->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "can't get i2c adapter %d\n",
- setup->i2c_bus);
- goto err_driver;
- }
+ return i2c_add_driver(&rt5625_i2c_driver);
+}
+module_init(rt5625_modinit);
- client = i2c_new_device(adapter, &info);
- i2c_put_adapter(adapter);
- if (!client) {
- dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
- (unsigned int)info.addr);
- goto err_driver;
- }
-#endif
- return 0;
-#if 0
-err_driver:
+static void __exit rt5625_modexit(void)
+{
i2c_del_driver(&rt5625_i2c_driver);
- return -ENODEV;
-#endif
}
+module_exit(rt5625_modexit);
+MODULE_DESCRIPTION("ASoC RT5625 driver");
+MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
+MODULE_LICENSE("GPL");
-static int rt5625_probe(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct rt5625_setup_data *setup;
- struct snd_soc_codec *codec;
- struct rt5625_priv *rt5625;
- int ret;
- pr_info("RT5625 Audio Codec %s", RT5625_VERSION);
+#ifdef RT5625_PROC
- if(socdev->codec_data)
+static ssize_t rt5625_proc_write(struct file *file, const char __user *buffer,
+ unsigned long len, void *data)
+{
+ char *cookie_pot;
+ char *p;
+ int reg;
+ int value;
+
+ cookie_pot = (char *)vmalloc( len );
+ if (!cookie_pot)
{
- setup = socdev->codec_data;
- }
-
- codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
- if (codec == NULL)
- return -ENOMEM;
-
- rt5625 = kzalloc(sizeof(struct rt5625_priv), GFP_KERNEL);
- if (rt5625 == NULL) {
- kfree(codec);
return -ENOMEM;
- }
- codec->private_data = rt5625;
- socdev->card->codec = codec;
-
- mutex_init(&codec->mutex);
- INIT_LIST_HEAD(&codec->dapm_widgets);
- INIT_LIST_HEAD(&codec->dapm_paths);
- rt5625_socdev = socdev;
- INIT_DELAYED_WORK(&codec->delayed_work, rt5625_work);
-
- ret = -ENODEV;
-// if (setup->i2c_address)
+ }
+ else
{
- codec->hw_write = (hw_write_t)i2c_master_send;
- //codec->hw_read = (hw_read_t)i2c_master_recv;
- ret = rt5625_add_i2c_device(pdev, setup);
+ if (copy_from_user( cookie_pot, buffer, len ))
+ return -EFAULT;
}
- if (ret != 0) {
- kfree(codec->private_data);
- kfree(codec);
- socdev->card->codec = NULL;
- }
- return ret;
-}
-
-static int run_delayed_work(struct delayed_work *dwork)
-{
- int ret;
+ switch(cookie_pot[0])
+ {
+ case 'd':
+ case 'D':
+ debug_write_read ++;
+ debug_write_read %= 2;
+ if(debug_write_read != 0)
+ printk("Debug read and write reg on\n");
+ else
+ printk("Debug read and write reg off\n");
+ break;
+ case 'r':
+ case 'R':
+ printk("Read reg debug\n");
+ if(cookie_pot[1] ==':')
+ {
+ debug_write_read = 1;
+ strsep(&cookie_pot,":");
+ while((p=strsep(&cookie_pot,",")))
+ {
+ reg = simple_strtol(p,NULL,16);
+ value = rt5625_read(rt5625_codec,reg);
+ printk("rt5625_read:0x%04x = 0x%04x\n",reg,value);
+ }
+ debug_write_read = 0;
+ printk("\n");
+ }
+ else
+ {
+ printk("Error Read reg debug.\n");
+ printk("For example: echo r:22,23,24,25>rt5625_ts\n");
+ }
+ break;
+ case 'w':
+ case 'W':
+ printk("Write reg debug\n");
+ if(cookie_pot[1] ==':')
+ {
+ debug_write_read = 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);
+ rt5625_write(rt5625_codec,reg,value);
+ printk("rt5625_write:0x%04x = 0x%04x\n",reg,value);
+ }
+ debug_write_read = 0;
+ printk("\n");
+ }
+ else
+ {
+ printk("Error Write reg debug.\n");
+ printk("For example: w:22=0,23=0,24=0,25=0>rt5625_ts\n");
+ }
+ break;
+ case 'a':
+ printk("Dump reg \n");
- /* cancel any work waiting to be queued. */
- ret = cancel_delayed_work(dwork);
+ for(reg = 0; reg < 0x6e; reg+=2)
+ {
+ value = rt5625_read(rt5625_codec,reg);
+ printk("rt5625_read:0x%04x = 0x%04x\n",reg,value);
+ }
- /* if there was any work waiting then we run it now and
- * wait for it's completion */
- if (ret) {
- schedule_delayed_work(dwork, 0);
- flush_scheduled_work();
+ break;
+ default:
+ printk("Help for rt5625_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'>rt5625_ts\n");
+ printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rt5625_ts\n");
+ break;
}
- return ret;
-}
-
-
-static int rt5625_remove(struct platform_device *pdev)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
- if (codec->control_data)
- rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
- run_delayed_work(&codec->delayed_work);
- snd_soc_free_pcms(socdev);
- snd_soc_dapm_free(socdev);
- i2c_unregister_device(codec->control_data);
- i2c_del_driver(&rt5625_i2c_driver);
- kfree(codec->private_data);
- kfree(codec);
-
- return 0;
+ return len;
}
+static const struct file_operations rt5625_proc_fops = {
+ .owner = THIS_MODULE,
+};
-static int rt5625_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
- rt5625_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
- return 0;
-}
-
-static int rt5625_resume(struct platform_device *pdev)
+static int rt5625_proc_init(void)
{
- struct snd_soc_device *socdev = platform_get_drvdata(pdev);
- struct snd_soc_codec *codec = socdev->card->codec;
-
-
-// int i;
-// u8 data[3];
-// u16 *cache = codec->reg_cache;
-
-#if 1
- rt5625_reset(codec);
- rt5625_write(codec, RT5625_PD_CTRL_STAT, 0);
- rt5625_write(codec, RT5625_PWR_MANAG_ADD1, PWR_MAIN_BIAS);
- rt5625_write(codec, RT5625_PWR_MANAG_ADD2, PWR_MIXER_VREF);
- rt5625_reg_init(codec);
-#else
- /* Sync reg_cache with the hardware */
- for (i = 0; i < ARRAY_SIZE(rt5625_reg); i++) {
- if (i == RT5625_RESET)
- continue;
- data[0] = i << 1;
- data[1] = (0xff00 & cache[i]) >> 8;
- data[2] = 0x00ff & cache[i];
- codec->hw_write(codec->control_data, data, 3);
+ struct proc_dir_entry *rt5625_proc_entry;
+ rt5625_proc_entry = create_proc_entry("driver/rt5625_ts", 0777, NULL);
+ if(rt5625_proc_entry != NULL)
+ {
+ rt5625_proc_entry->write_proc = rt5625_proc_write;
+ return 0;
}
-
- rt5625_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-#endif
-
- /* charge rt5625 caps */
- if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
- rt5625_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
- codec->bias_level = SND_SOC_BIAS_ON;
- schedule_delayed_work(&codec->delayed_work,
- msecs_to_jiffies(100));
+ else
+ {
+ printk("create proc error !\n");
+ return -1;
}
-
- return 0;
}
-
-
-struct snd_soc_codec_device soc_codec_dev_rt5625 = {
- .probe = rt5625_probe,
- .remove = rt5625_remove,
- .suspend = rt5625_suspend,
- .resume = rt5625_resume,
-};
-
-EXPORT_SYMBOL_GPL(soc_codec_dev_rt5625);
-
-static int __init rt5625_modinit(void)
-{
- return snd_soc_register_dais(rt5625_dai, ARRAY_SIZE(rt5625_dai));
-}
-
-static void __exit rt5625_exit(void)
-{
- snd_soc_unregister_dais(rt5625_dai, ARRAY_SIZE(rt5625_dai));
-}
-
-module_init(rt5625_modinit);
-module_exit(rt5625_exit);
-MODULE_LICENSE("GPL");
+#endif
-#ifndef _RT5625_H
-#define _RT5625_H
-
-#define RT5625_RESET 0X00 //RESET CODEC TO DEFAULT
-#define RT5625_SPK_OUT_VOL 0X02 //SPEAKER OUT VOLUME
-#define RT5625_HP_OUT_VOL 0X04 //HEADPHONE OUTPUT VOLUME
-#define RT5625_AUX_OUT_VOL 0X06 //AUXOUT VOLUME
-#define RT5625_PHONEIN_VOL 0X08 //PHONE INPUT VOLUME
-#define RT5625_LINE_IN_VOL 0X0A //LINE IN VOLUME
-#define RT5625_STEREO_DAC_VOL 0X0C //STEREO DAC VOLUME
-#define RT5625_MIC_VOL 0X0E //MICROPHONE VOLUME
-#define RT5625_DAC_AND_MIC_CTRL 0X10 //STEREO DAC AND MIC ROUTING CONTROL
-#define RT5625_ADC_REC_GAIN 0X12 //ADC RECORD GAIN
-#define RT5625_ADC_REC_MIXER 0X14 //ADC RECORD MIXER CONTROL
-#define RT5625_VOICE_DAC_OUT_VOL 0X18 //VOICE DAC OUTPUT VOLUME
-#define RT5625_VODSP_PDM_CTL 0X1A //VODSP & PDM CONTROL
-#define RT5625_OUTPUT_MIXER_CTRL 0X1C //OUTPUT MIXER CONTROL
-#define RT5625_VODSP_CTL 0X1E //VODSP CONTROL
-#define RT5625_MIC_CTRL 0X22 //MICROPHONE CONTROL
-#define RT5625_DMIC_CTRL 0x24
-#define RT5625_PD_CTRL_STAT 0X26 //POWER DOWN CONTROL/STATUS
-#define RT5625_DAC_ADC_VODAC_FUN_SEL 0X2E //STEREO DAC,VOICE DAC,STEREO ADC FUNCTION SELECT
-#define RT5625_MAIN_SDP_CTRL 0X34 //MAIN SERIAL DATA PORT CONTROL(STEREO I2S)
-#define RT5625_EXTEND_SDP_CTRL 0X36 //EXTEND SERIAL DATA PORT CONTROL(VOICE I2S/PCM)
-#define RT5625_PWR_MANAG_ADD1 0X3A //POWER MANAGMENT ADDITION 1
-#define RT5625_PWR_MANAG_ADD2 0X3C //POWER MANAGMENT ADDITION 2
-#define RT5625_PWR_MANAG_ADD3 0X3E //POWER MANAGMENT ADDITION 3
-#define RT5625_GEN_CTRL_REG1 0X40 //GENERAL PURPOSE CONTROL REGISTER 1
-#define RT5625_GEN_CTRL_REG2 0X42 //GENERAL PURPOSE CONTROL REGISTER 2
-#define RT5625_PLL_CTRL 0X44 //PLL1 CONTROL
-#define RT5625_PLL2_CTRL 0X46 //PLL2 CONTROL
-#define RT5625_LDO_CTRL 0X48 //LDO CONTROL
-#define RT5625_GPIO_PIN_CONFIG 0X4C //GPIO PIN CONFIGURATION
-#define RT5625_GPIO_PIN_POLARITY 0X4E //GPIO PIN POLARITY
-#define RT5625_GPIO_PIN_STICKY 0X50 //GPIO PIN STICKY
-#define RT5625_GPIO_PIN_WAKEUP 0X52 //GPIO PIN WAKE UP
-#define RT5625_GPIO_PIN_STATUS 0X54 //GPIO PIN STATUS
-#define RT5625_GPIO_PIN_SHARING 0X56 //GPIO PIN SHARING
-#define RT5625_OVER_TEMP_CURR_STATUS 0X58 //OVER TEMPERATURE AND CURRENT STATUS
-#define RT5625_SOFT_VOL_CTRL 0X5A //SOFT VOLUME CONTROL SETTING
-#define RT5625_GPIO_OUT_CTRL 0X5C //GPIO OUTPUT PIN CONTRL
-#define RT5625_MISC_CTRL 0X5E //MISC CONTROL
-#define RT5625_STEREO_DAC_CLK_CTRL1 0X60 //STEREO DAC CLOCK CONTROL 1
-#define RT5625_STEREO_DAC_CLK_CTRL2 0X62 //STEREO DAC CLOCK CONTROL 2
-#define RT5625_VOICE_DAC_PCMCLK_CTRL1 0X64 //VOICE/PCM DAC CLOCK CONTROL 1
-#define RT5625_PSEDUEO_SPATIAL_CTRL 0X68 //PSEDUEO STEREO /SPATIAL EFFECT BLOCK CONTROL
-#define RT5625_PRIV_ADDR 0X6A //PRIVATE ADDRESS
-#define RT5625_PRIV_DATA 0X6C //PRIVATE DATA
-#define RT5625_EQ_CTRL_ADC_HPF 0X6E //EQ CONTROL AND STATUS /ADC HPF CONTROL
-#define RT5625_VODSP_REG_ADDR 0x70 //VODSP REGISTER ADDRESS
-#define RT5625_VODSP_REG_DATA 0x72 //VODSP REGISTER DATA
-#define RT5625_VODSP_REG_CMD 0x74 //VODSP REGISTER COMMAND
-
-
-/**************************************************************************************************
- *Bit define of Codec Register
- *************************************************************************************************/
-//global definition
-#define RT_L_MUTE (0x1<<15) //Mute Left Control
-#define RT_L_ZC (0x1<<14) //Mute Left Zero-Cross Detector Control
-#define RT_R_MUTE (0x1<<7) //Mute Right Control
-#define RT_R_ZC (0x1<<6) //Mute Right Zero-Cross Detector Control
-#define RT_M_HP_MIXER (0x1<<15) //Mute source to HP Mixer
-#define RT_M_SPK_MIXER (0x1<<14) //Mute source to Speaker Mixer
-#define RT_M_MONO_MIXER (0x1<<13) //Mute source to Mono Mixer
-
-//Phone Input Volume(0x08)
-#define M_PHONEIN_TO_HP_MIXER (0x1<<15) //Mute Phone In volume to HP mixer
-#define M_PHONEIN_TO_SPK_MIXER (0x1<<14) //Mute Phone In volume to speaker mixer
-
-
-//Mic Routing Control(0x10)
-#define M_MIC1_TO_HP_MIXER (0x1<<15) //Mute MIC1 to HP mixer
-#define M_MIC1_TO_SPK_MIXER (0x1<<14) //Mute MiC1 to SPK mixer
-#define M_MIC1_TO_MONO_MIXER (0x1<<13) //Mute MIC1 to MONO mixer
-#define M_MIC2_TO_HP_MIXER (0x1<<11) //Mute MIC2 to HP mixer
-#define M_MIC2_TO_SPK_MIXER (0x1<<10) //Mute MiC2 to SPK mixer
-#define M_MIC2_TO_MONO_MIXER (0x1<<9) //Mute MIC2 to MONO mixer
-#define M_DAC_TO_HPL_MIXER (0x1<<3) //Mute DAC to HP left mixer
-#define M_DAC_TO_HPR_MIXER (0x1<<2) //Mute DAC to HP right mixer
-#define M_DAC_TO_SPK_MIXER (0x1<<1) //Mute DAC to SPK mixer
-#define M_DAC_TO_MONO_MIXER (0x1<<0) //Mute DAC to MONO mixer
-
-
-
-//ADC Record Gain(0x12)
-#define M_ADC_L_TO_HP_MIXER (0x1<<15) //Mute left of ADC to HP Mixer
-#define M_ADC_L_TO_MONO_MIXER (0x1<<14) //Mute left of ADC to MONO Mixer
-#define ADC_L_ZC_DET (0x1<<13) //ADC Zero-Cross Detector Control
-#define ADC_L_GAIN_MASK (0x1f<<8) //ADC Record Gain Left channel Mask
-#define M_ADC_R_TO_HP_MIXER (0x1<<7) //Mute right of ADC to HP Mixer
-#define M_ADC_R_TO_MONO_MIXER (0x1<<6) //Mute right of ADC to MONO Mixer
-#define ADC_R_ZC_DET (0x1<<5) //ADC Zero-Cross Detector Control
-#define ADC_R_GAIN_MASK (0x1f<<0) //ADC Record Gain Right channel Mask
-
-//Voice DAC Output Volume(0x18)
-#define M_V_DAC_TO_HP_MIXER (0x1<<15)
-#define M_V_DAC_TO_SPK_MIXER (0x1<<14)
-#define M_V_DAC_TO_MONO_MIXER (0x1<<13)
-
-
-//AEC & PDM Control(0x1A)
-#define VODSP_SRC1_PWR (0x1<<15) //Enable SRC1 Power
-#define VODSP_SRC2_PWR (0x1<<13) //Enable SRC2 Power
-
-#define VODSP_SRC2_S_SEL_MASK (0x1<<12)
-#define VODSP_SRC2_S_SEL_TXDP (0x0<<12) //SRC2 source select AEC_TXDP
-#define VODSP_SRC2_S_SEL_TXDC (0x1<<12) //SRC2 source select AEC_TXDC
-
-#define VODSP_RXDP_PWR (0x1<<11) //Enable AEC RXDP Power
-
-#define VODSP_RXDP_S_SEL_MASK (0x3<<9)
-#define VODSP_RXDP_S_SEL_SRC1 (0x0<<9) //AEC RxDP source select SRC1 Output
-#define VODSP_RXDP_S_SEL_ADCL (0x1<<9) //AEC RxDP source select ADC Left to AEC Digital Path
-#define VODSP_RXDP_S_SEL_VOICE (0x2<<9) //AEC RxDP source select Voice to Stereo Digital Path
-#define VODSP_RXDP_S_SEL_ADCR (0x3<<9) //AEC RxDP source select ADC Right to AEC Digital Path
-
-#define VODSP_RXDC_PWR (0x1<<8) //Enable AEC RXDC Power
-
-#define VOICE_PCM_S_SEL_MASK (0x1<<7)
-#define VOICE_PCM_S_SEL_ADC_R (0x0<<7) //VSADC PCM interface source select ADC R
-#define VOICE_PCM_S_SEL_AEC_TXDP (0x1<<7) //VSADC PCM interface source select AEC_TXDP
-
-#define REC_S_SEL_MASK (0x3<<4)
-#define REC_S_SEL_ADC (0x0<<4) //Main Stereo Record I2S source select ADC L/R
-#define REC_S_SEL_VOICE (0x1<<4) //Main Stereo Record I2S source select Voice to Stereo Digital Path
-#define REC_S_SEL_SRC2 (0x2<<4) //Main Stereo Record I2S source select SRC2
-
-
-//Output Mixer Control(0x1C)
-#define SPKOUT_N_SOUR_MASK (0x3<<14)
-#define SPKOUT_N_SOUR_LN (0x2<<14)
-#define SPKOUT_N_SOUR_RP (0x1<<14)
-#define SPKOUT_N_SOUR_RN (0x0<<14)
-
-#define SPKOUT_SEL_CLASS_D (0x1<<13)
-#define SPKOUT_SEL_CLASS_AB (0x0<<13)
-
-#define SPK_CLASS_AB_S_AMP (0x0<<12)
-#define SPK_CALSS_AB_W_AMP (0x1<<12)
-
-#define SPKOUT_INPUT_SEL_MASK (0x3<<10)
-#define SPKOUT_INPUT_SEL_MONOMIXER (0x3<<10)
-#define SPKOUT_INPUT_SEL_SPKMIXER (0x2<<10)
-#define SPKOUT_INPUT_SEL_HPMIXER (0x1<<10)
-#define SPKOUT_INPUT_SEL_VMID (0x0<<10)
-
-#define HPL_INPUT_SEL_HPLMIXER (0x1<<9)
-#define HPR_INPUT_SEL_HPRMIXER (0x1<<8)
-
-#define AUXOUT_INPUT_SEL_MASK (0x3<<6)
-#define AUXOUT_INPUT_SEL_MONOMIXER (0x3<<6)
-#define AUXOUT_INPUT_SEL_SPKMIXER (0x2<<6)
-#define AUXOUT_INPUT_SEL_HPMIXER (0x1<<6)
-#define AUXOUT_INPUT_SEL_VMID (0x0<<6)
-
-
-//Voice DSP Control(0x1E)
-#define VODSP_SYSCLK_S_SEL_MASK (0x1<<15)
-#define VODSP_SYSCLK_S_SEL_M_CLK (0x0<<15)
-#define VODSP_SYSCLK_S_SEL_V_CLK (0x1<<15)
-
-#define VODSP_LRCK_SEL_MASK (0x1<<13)
-#define VODSP_LRCK_SEL_8K (0x0<<13)
-#define VODSP_LRCK_SEL_16K (0x1<<13)
-
-#define VODSP_TEST_MODE_ENA (0x1<<3)
-#define VODSP_NO_BP_MODE_ENA (0x1<<2)
-#define VODSP_NO_PD_MODE_ENA (0x1<<1)
-#define VODSP_NO_RST_MODE_ENA (0x1<<0)
-
-
-
-
-//Micphone Control define(0x22)
-#define MIC1 1
-#define MIC2 2
-#define MIC_BIAS_90_PRECNET_AVDD 1
-#define MIC_BIAS_75_PRECNET_AVDD 2
-
-#define MIC1_BOOST_CONTROL_MASK (0x3<<10)
-#define MIC1_BOOST_CONTROL_BYPASS (0x0<<10)
-#define MIC1_BOOST_CONTROL_20DB (0x1<<10)
-#define MIC1_BOOST_CONTROL_30DB (0x2<<10)
-#define MIC1_BOOST_CONTROL_40DB (0x3<<10)
-
-#define MIC2_BOOST_CONTROL_MASK (0x3<<8)
-#define MIC2_BOOST_CONTROL_BYPASS (0x0<<8)
-#define MIC2_BOOST_CONTROL_20DB (0x1<<8)
-#define MIC2_BOOST_CONTROL_30DB (0x2<<8)
-#define MIC2_BOOST_CONTROL_40DB (0x3<<8)
-
-#define MIC1_BIAS_VOLT_CTRL_MASK (0x1<<5)
-#define MIC1_BIAS_VOLT_CTRL_90P (0x0<<5)
-#define MIC1_BIAS_VOLT_CTRL_75P (0x1<<5)
-
-#define MIC2_BIAS_VOLT_CTRL_MASK (0x1<<4)
-#define MIC2_BIAS_VOLT_CTRL_90P (0x0<<4)
-#define MIC2_BIAS_VOLT_CTRL_75P (0x1<<4)
-
-//PowerDown control of register(0x26)
-//power management bits
-#define RT_PWR_PR7 (0x1<<15) //write this bit to power down the Speaker Amplifier
-#define RT_PWR_PR6 (0x1<<14) //write this bit to power down the Headphone Out and MonoOut
-#define RT_PWR_PR5 (0x1<<13) //write this bit to power down the internal clock(without PLL)
-#define RT_PWR_PR3 (0x1<<11) //write this bit to power down the mixer(vref/vrefout out off)
-#define RT_PWR_PR2 (0x1<<10) //write this bit to power down the mixer(vref/vrefout still on)
-#define RT_PWR_PR1 (0x1<<9) //write this bit to power down the dac
-#define RT_PWR_PR0 (0x1<<8) //write this bit to power down the adc
-#define RT_PWR_REF (0x1<<3) //read only
-#define RT_PWR_ANL (0x1<<2) //read only
-#define RT_PWR_DAC (0x1<<1) //read only
-#define RT_PWR_ADC (0x1) //read only
-
-
-//Stereo DAC/Voice DAC/Stereo ADC function(0x2E)
-#define DAC_FUNC_SEL_MASK (0x3<<12)
-#define DAC_FUNC_SEL_DAC (0x0<<12)
-#define DAC_FUNC_SEL_SRC2 (0x1<<12)
-#define DAC_FUNC_SEL_VODSP_TXDP (0x2<<12)
-#define DAC_FUNC_SEL_VODSP_TXDC (0x3<<12)
-
-#define VODAC_SOUR_SEL_MASK (0x7<<8)
-#define VODAC_SOUR_SEL_VOICE (0x0<<8)
-#define VODAC_SOUR_SEL_SRC2 (0x1<<8)
-#define VODAC_SOUR_SEL_VODSP_TXDP (0x2<<8)
-#define VODAC_SOUR_SEL_VODSP_TXDC (0x3<<8)
-
-#define ADCR_FUNC_SEL_MASK (0x3<<4)
-#define ADCR_FUNC_SEL_ADC (0x0<<4)
-#define ADCR_FUNC_SEL_VOADC (0x1<<4)
-#define ADCR_FUNC_SEL_VODSP (0x2<<4)
-#define ADCR_FUNC_SEL_PDM (0x3<<4)
-
-#define ADCL_FUNC_SEL_MASK (0x3<<0)
-#define ADCL_FUNC_SEL_ADC (0x0<<0)
-#define ADCL_FUNC_SEL_VODSP (0x1<<0)
-
-//Main Serial Data Port Control(0x34)
-#define MAIN_I2S_MODE_SEL (0x1<<15) //0:Master mode 1:Slave mode
-#define MAIN_I2S_SADLRCK_CTRL (0x1<<14) //0:Disable,ADC and DAC use the same fs,1:Enable
-
-#define MAIN_I2S_PCM_MODE (0x1<<6) //0:Normal SADLRCK/SDALRCK,1:Invert SADLRCK/SDALRCK
-//Data Length Slection
-#define MAIN_I2S_DL_MASK (0x3<<2) //main i2s Data Length mask
-#define MAIN_I2S_DL_16 (0x0<<2) //16 bits
-#define MAIN_I2S_DL_20 (0x1<<2) //20 bits
-#define MAIN_I2S_DL_24 (0x2<<2) //24 bits
-#define MAIN_I2S_DL_32 (0x3<<2) //8 bits
-
-//PCM Data Format Selection
-#define MAIN_I2S_DF_MASK (0x3) //main i2s Data Format mask
-#define MAIN_I2S_DF_I2S (0x0) //I2S FORMAT
-#define MAIN_I2S_DF_LEFT (0x1) //LEFT JUSTIFIED format
-#define MAIN_I2S_DF_PCM_A (0x2) //PCM Mode A
-#define MAIN_I2S_DF_PCM_B (0x3) //PCM Mode B
-
-//Extend Serial Data Port Control(0x36)
-#define EXT_I2S_FUNC_ENABLE (0x1<<15) //Enable PCM interface on GPIO 1,3,4,5 0:GPIO function,1:Voice PCM interface
-#define EXT_I2S_MODE_SEL (0x1<<14) //0:Master ,1:Slave
-#define EXT_I2S_AUTO_CLK_CTRL (0x1<<13) //0:Disable,1:Enable
-#define EXT_I2S_BCLK_POLARITY (0x1<<7) //0:Normal 1:Invert
-#define EXT_I2S_PCM_MODE (0x1<<6) //0:Normal VSLRCK,1:Invert VSLRCK
-//Data Length Slection
-#define EXT_I2S_DL_MASK (0x3<<2) //Extend i2s Data Length mask
-#define EXT_I2S_DL_32 (0x3<<2) //8 bits
-#define EXT_I2S_DL_24 (0x2<<2) //24 bits
-#define EXT_I2S_DL_20 (0x1<<2) //20 bits
-#define EXT_I2S_DL_16 (0x0<<2) //16 bits
-
-//Voice Data Format
-#define EXT_I2S_DF_MASK (0x3) //Extend i2s Data Format mask
-#define EXT_I2S_DF_I2S (0x0) //I2S FORMAT
-#define EXT_I2S_DF_LEFT (0x1) //LEFT JUSTIFIED format
-#define EXT_I2S_DF_PCM_A (0x2) //PCM Mode A
-#define EXT_I2S_DF_PCM_B (0x3) //PCM Mode B
-
-//Power managment addition 1 (0x3A),0:Disable,1:Enable
-#define PWR_DAC_DF2SE_L (0x1<<15)
-#define PWR_DAC_DF2SE_R (0x1<<14)
-#define PWR_ZC_DET_PD (0x1<<13)
-#define PWR_I2S_INTERFACE (0x1<<11)
-#define PWR_AMP_POWER (0x1<<10)
-#define PWR_HP_OUT_AMP (0x1<<9)
-#define PWR_HP_OUT_ENH_AMP (0x1<<8)
-#define PWR_VOICE_DF2SE (0x1<<7)
-#define PWR_SOFTGEN_EN (0x1<<6)
-#define PWR_MIC_BIAS1_DET (0x1<<5)
-#define PWR_MIC_BIAS2_DET (0x1<<4)
-#define PWR_MIC_BIAS1 (0x1<<3)
-#define PWR_MIC_BIAS2 (0x1<<2)
-#define PWR_MAIN_BIAS (0x1<<1)
-#define PWR_DAC_REF (0x1)
-
-
-//Power managment addition 2(0x3C),0:Disable,1:Enable
-#define PWR_PLL1 (0x1<<15)
-#define PWR_PLL2 (0x1<<14)
-#define PWR_MIXER_VREF (0x1<<13)
-#define PWR_TEMP_SENSOR (0x1<<12)
-#define PWR_AUX_ADC (0x1<<11)
-#define PWR_VOICE_CLOCK (0x1<<10)
-#define PWR_L_DAC_CLK (0x1<<9)
-#define PWR_R_DAC_CLK (0x1<<8)
-#define PWR_L_ADC_CLK (0x1<<7)
-#define PWR_R_ADC_CLK (0x1<<6)
-#define PWR_L_HP_MIXER (0x1<<5)
-#define PWR_R_HP_MIXER (0x1<<4)
-#define PWR_SPK_MIXER (0x1<<3)
-#define PWR_MONO_MIXER (0x1<<2)
-#define PWR_L_ADC_REC_MIXER (0x1<<1)
-#define PWR_R_ADC_REC_MIXER (0x1)
-
-
-//Power managment addition 3(0x3E),0:Disable,1:Enable
-#define PWR_OSC_EN (0x1<<15)
-#define PWR_AUXOUT_VOL (0x1<<14)
-#define PWR_SPK_OUT (0x1<<13)
-#define PWR_SPK_OUT_N (0x1<<12)
-#define PWR_HP_L_OUT_VOL (0x1<<11)
-#define PWR_HP_R_OUT_VOL (0x1<<10)
-#define PWR_VODSP_INTERFACE (0x1<<9)
-#define PWR_I2C_FOR_VODSP (0x1<<8)
-#define PWR_LINE_IN_L (0x1<<7)
-#define PWR_LINE_IN_R (0x1<<6)
-#define PWR_PHONE_VOL (0x1<<5)
-#define PWR_PHONE_ADMIXER (0x1<<4)
-#define PWR_MIC1_VOL_CTRL (0x1<<3)
-#define PWR_MIC2_VOL_CTRL (0x1<<2)
-#define PWR_MIC1_BOOST (0x1<<1)
-#define PWR_MIC2_BOOST (0x1)
-
-//General Purpose Control Register 1(0x40)
-#define GP_CLK_FROM_PLL (0x1<<15)
-#define GP_CLK_FROM_MCLK (0x0<<15)
-
-#define GP_DAC_HI_PA_ENA (0x1<<10) //Enable DAC High Pass Filter
-
-#define GP_EXTCLK_S_SEL_PLL2 (0x1<<6)
-#define GP_EXTCLK_S_SEL_PLL1 (0x0<<6)
-
-#define GP_EXTCLK_DIR_SEL_OUTPUT (0x1<<5)
-#define GP_EXTCLK_DIR_SEL_INTPUT (0x0<<5)
-
-#define GP_VOSYS_S_SEL_PLL2 (0x0<<4)
-#define GP_VOSYS_S_SEL_EXTCLK (0x1<<4)
-
-#define GP_SPK_AMP_CTRL_MASK (0x7<<1)
-#define GP_SPK_AMP_CTRL_RATIO_225 (0x0<<1) //2.25 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_200 (0x1<<1) //2.00 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_175 (0x2<<1) //1.75 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_150 (0x3<<1) //1.50 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_125 (0x4<<1) //1.25 Vdd
-#define GP_SPK_AMP_CTRL_RATIO_100 (0x5<<1) //1.00 Vdd
-
-//General Purpose Control Register 2(0x42)
-#define GP2_PLL1_SOUR_SEL_MASK (0x3<<12)
-#define GP2_PLL1_SOUR_SEL_MCLK (0x0<<12)
-#define GP2_PLL1_SOUR_SEL_BCLK (0x2<<12)
-#define GP2_PLL1_SOUR_SEL_VBCLK (0x3<<12)
-
-//PLL Control(0x44)
-#define PLL_M_CODE_MASK 0xF //PLL M code mask
-#define PLL_K_CODE_MASK (0x7<<4) //PLL K code mask
-#define PLL_BYPASS_N (0x1<<7) //bypass PLL N code
-#define PLL_N_CODE_MASK (0xFF<<8) //PLL N code mask
-
-#define PLL_CTRL_M_VAL(m) ((m)&0xf)
-#define PLL_CTRL_K_VAL(k) (((k)&0x7)<<4)
-#define PLL_CTRL_N_VAL(n) (((n)&0xff)<<8)
-
-//PLL2 CONTROL
-#define PLL2_ENA (0x1<<15)
-#define PLL_2_RATIO_8X (0x0)
-#define PLL_2_RATIO_16X (0x1)
-
-//LDO Control(0x48)
-#define LDO_ENABLE (0x1<<15)
-
-#define LDO_OUT_VOL_CTRL_MASK (0xf<<0)
-#define LDO_OUT_VOL_CTRL_1_55V (0xf<<0)
-#define LDO_OUT_VOL_CTRL_1_50V (0xe<<0)
-#define LDO_OUT_VOL_CTRL_1_45V (0xd<<0)
-#define LDO_OUT_VOL_CTRL_1_40V (0xc<<0)
-#define LDO_OUT_VOL_CTRL_1_35V (0xb<<0)
-#define LDO_OUT_VOL_CTRL_1_30V (0xa<<0)
-#define LDO_OUT_VOL_CTRL_1_25V (0x9<<0)
-#define LDO_OUT_VOL_CTRL_1_20V (0x8<<0)
-#define LDO_OUT_VOL_CTRL_1_15V (0x7<<0)
-#define LDO_OUT_VOL_CTRL_1_05V (0x6<<0)
-#define LDO_OUT_VOL_CTRL_1_00V (0x5<<0)
-#define LDO_OUT_VOL_CTRL_0_95V (0x4<<0)
-#define LDO_OUT_VOL_CTRL_0_90V (0x3<<0)
-#define LDO_OUT_VOL_CTRL_0_85V (0x2<<0)
-#define LDO_OUT_VOL_CTRL_0_80V (0x1<<0)
-#define LDO_OUT_VOL_CTRL_0_75V (0x0<<0)
-
-
-
-//GPIO Pin Configuration(0x4C)
-#define GPIO_1 (0x1<<1)
-#define GPIO_2 (0x1<<2)
-#define GPIO_3 (0x1<<3)
-#define GPIO_4 (0x1<<4)
-#define GPIO_5 (0x1<<5)
-
-
-////INTERRUPT CONTROL(0x5E)
-#define DISABLE_FAST_VREG (0x1<<15)
-
-#define AVC_TARTGET_SEL_MASK (0x3<<12)
-#define AVC_TARTGET_SEL_NONE (0x0<<12)
-#define AVC_TARTGET_SEL_R (0x1<<12)
-#define AVC_TARTGET_SEL_L (0x2<<12)
-#define AVC_TARTGET_SEL_BOTH (0x3<<12)
-
-#define HP_DEPOP_MODE2_EN (0x1<<8)
-#define HP_DEPOP_MODE1_EN (0x1<<9)
-#define HP_L_M_UM_DEPOP_EN (0x1<<7)
-#define HP_R_M_UM_DEPOP_EN (0x1<<6)
-#define M_UM_DEPOP_EN (0x1<<5)
-
-//Stereo DAC Clock Control 1(0x60)
-#define STEREO_BCLK_DIV1_MASK (0xF<<12)
-#define STEREO_BCLK_DIV1_1 (0x0<<12)
-#define STEREO_BCLK_DIV1_2 (0x1<<12)
-#define STEREO_BCLK_DIV1_3 (0x2<<12)
-#define STEREO_BCLK_DIV1_4 (0x3<<12)
-#define STEREO_BCLK_DIV1_5 (0x4<<12)
-#define STEREO_BCLK_DIV1_6 (0x5<<12)
-#define STEREO_BCLK_DIV1_7 (0x6<<12)
-#define STEREO_BCLK_DIV1_8 (0x7<<12)
-#define STEREO_BCLK_DIV1_9 (0x8<<12)
-#define STEREO_BCLK_DIV1_10 (0x9<<12)
-#define STEREO_BCLK_DIV1_11 (0xA<<12)
-#define STEREO_BCLK_DIV1_12 (0xB<<12)
-#define STEREO_BCLK_DIV1_13 (0xC<<12)
-#define STEREO_BCLK_DIV1_14 (0xD<<12)
-#define STEREO_BCLK_DIV1_15 (0xE<<12)
-#define STEREO_BCLK_DIV1_16 (0xF<<12)
-
-#define STEREO_BCLK_DIV2_MASK (0x7<<8)
-#define STEREO_BCLK_DIV2_2 (0x0<<8)
-#define STEREO_BCLK_DIV2_4 (0x1<<8)
-#define STEREO_BCLK_DIV2_8 (0x2<<8)
-#define STEREO_BCLK_DIV2_16 (0x3<<8)
-#define STEREO_BCLK_DIV2_32 (0x4<<8)
-
-#define STEREO_AD_LRCK_DIV1_MASK (0xF<<4)
-#define STEREO_AD_LRCK_DIV1_1 (0x0<<4)
-#define STEREO_AD_LRCK_DIV1_2 (0x1<<4)
-#define STEREO_AD_LRCK_DIV1_3 (0x2<<4)
-#define STEREO_AD_LRCK_DIV1_4 (0x3<<4)
-#define STEREO_AD_LRCK_DIV1_5 (0x4<<4)
-#define STEREO_AD_LRCK_DIV1_6 (0x5<<4)
-#define STEREO_AD_LRCK_DIV1_7 (0x6<<4)
-#define STEREO_AD_LRCK_DIV1_8 (0x7<<4)
-#define STEREO_AD_LRCK_DIV1_9 (0x8<<4)
-#define STEREO_AD_LRCK_DIV1_10 (0x9<<4)
-#define STEREO_AD_LRCK_DIV1_11 (0xA<<4)
-#define STEREO_AD_LRCK_DIV1_12 (0xB<<4)
-#define STEREO_AD_LRCK_DIV1_13 (0xC<<4)
-#define STEREO_AD_LRCK_DIV1_14 (0xD<<4)
-#define STEREO_AD_LRCK_DIV1_15 (0xE<<4)
-#define STEREO_AD_LRCK_DIV1_16 (0xF<<4)
-
-#define STEREO_AD_LRCK_DIV2_MASK (0x7<<1)
-#define STEREO_AD_LRCK_DIV2_2 (0x0<<1)
-#define STEREO_AD_LRCK_DIV2_4 (0x1<<1)
-#define STEREO_AD_LRCK_DIV2_8 (0x2<<1)
-#define STEREO_AD_LRCK_DIV2_16 (0x3<<1)
-#define STEREO_AD_LRCK_DIV2_32 (0x4<<1)
-
-#define STEREO_DA_LRCK_DIV_MASK (1)
-#define STEREO_DA_LRCK_DIV_32 (0)
-#define STEREO_DA_LRCK_DIV_64 (1)
-
-//Stereo DAC Clock Control 2(0x62)
-#define STEREO_DA_FILTER_DIV1_MASK (0xF<<12)
-#define STEREO_DA_FILTER_DIV1_1 (0x0<<12)
-#define STEREO_DA_FILTER_DIV1_2 (0x1<<12)
-#define STEREO_DA_FILTER_DIV1_3 (0x2<<12)
-#define STEREO_DA_FILTER_DIV1_4 (0x3<<12)
-#define STEREO_DA_FILTER_DIV1_5 (0x4<<12)
-#define STEREO_DA_FILTER_DIV1_6 (0x5<<12)
-#define STEREO_DA_FILTER_DIV1_7 (0x6<<12)
-#define STEREO_DA_FILTER_DIV1_8 (0x7<<12)
-#define STEREO_DA_FILTER_DIV1_9 (0x8<<12)
-#define STEREO_DA_FILTER_DIV1_10 (0x9<<12)
-#define STEREO_DA_FILTER_DIV1_11 (0xA<<12)
-#define STEREO_DA_FILTER_DIV1_12 (0xB<<12)
-#define STEREO_DA_FILTER_DIV1_13 (0xC<<12)
-#define STEREO_DA_FILTER_DIV1_14 (0xD<<12)
-#define STEREO_DA_FILTER_DIV1_15 (0xE<<12)
-#define STEREO_DA_FILTER_DIV1_16 (0xF<<12)
-
-#define STEREO_DA_FILTER_DIV2_MASK (0x7<<9)
-#define STEREO_DA_FILTER_DIV2_2 (0x0<<9)
-#define STEREO_DA_FILTER_DIV2_4 (0x1<<9)
-#define STEREO_DA_FILTER_DIV2_8 (0x2<<9)
-#define STEREO_DA_FILTER_DIV2_16 (0x3<<9)
-#define STEREO_DA_FILTER_DIV2_32 (0x4<<9)
-
-#define STEREO_AD_FILTER_DIV1_MASK (0xF<<4)
-#define STEREO_AD_FILTER_DIV1_1 (0x0<<4)
-#define STEREO_AD_FILTER_DIV1_2 (0x1<<4)
-#define STEREO_AD_FILTER_DIV1_3 (0x2<<4)
-#define STEREO_AD_FILTER_DIV1_4 (0x3<<4)
-#define STEREO_AD_FILTER_DIV1_5 (0x4<<4)
-#define STEREO_AD_FILTER_DIV1_6 (0x5<<4)
-#define STEREO_AD_FILTER_DIV1_7 (0x6<<4)
-#define STEREO_AD_FILTER_DIV1_8 (0x7<<4)
-#define STEREO_AD_FILTER_DIV1_9 (0x8<<4)
-#define STEREO_AD_FILTER_DIV1_10 (0x9<<4)
-#define STEREO_AD_FILTER_DIV1_11 (0xA<<4)
-#define STEREO_AD_FILTER_DIV1_12 (0xB<<4)
-#define STEREO_AD_FILTER_DIV1_13 (0xC<<4)
-#define STEREO_AD_FILTER_DIV1_14 (0xD<<4)
-#define STEREO_AD_FILTER_DIV1_15 (0xE<<4)
-#define STEREO_AD_FILTER_DIV1_16 (0xF<<4)
-
-#define STEREO_AD_FILTER_DIV2_MASK (0x7<<1)
-#define STEREO_AD_FILTER_DIV2_1 (0x0<<1)
-#define STEREO_AD_FILTER_DIV2_2 (0x1<<1)
-#define STEREO_AD_FILTER_DIV2_4 (0x2<<1)
-#define STEREO_AD_FILTER_DIV2_8 (0x3<<1)
-#define STEREO_AD_FILTER_DIV2_16 (0x4<<1)
-#define STEREO_AD_FILTER_DIV2_32 (0x5<<1)
-
-
-//Voice DAC PCM Clock Control 1(0x64)
-#define VOICE_BCLK_DIV1_MASK (0xF<<12)
-#define VOICE_BCLK_DIV1_1 (0x0<<12)
-#define VOICE_BCLK_DIV1_2 (0x1<<12)
-#define VOICE_BCLK_DIV1_3 (0x2<<12)
-#define VOICE_BCLK_DIV1_4 (0x3<<12)
-#define VOICE_BCLK_DIV1_5 (0x4<<12)
-#define VOICE_BCLK_DIV1_6 (0x5<<12)
-#define VOICE_BCLK_DIV1_7 (0x6<<12)
-#define VOICE_BCLK_DIV1_8 (0x7<<12)
-#define VOICE_BCLK_DIV1_9 (0x8<<12)
-#define VOICE_BCLK_DIV1_10 (0x9<<12)
-#define VOICE_BCLK_DIV1_11 (0xA<<12)
-#define VOICE_BCLK_DIV1_12 (0xB<<12)
-#define VOICE_BCLK_DIV1_13 (0xC<<12)
-#define VOICE_BCLK_DIV1_14 (0xD<<12)
-#define VOICE_BCLK_DIV1_15 (0xE<<12)
-#define VOICE_BCLK_DIV1_16 (0xF<<12)
-
-#define VOICE_BCLK_DIV2_MASK (0x7<<8)
-#define VOICE_BCLK_DIV2_2 (0x0<<8)
-#define VOICE_BCLK_DIV2_4 (0x1<<8)
-#define VOICE_BCLK_DIV2_8 (0x2<<8)
-#define VOICE_BCLK_DIV2_16 (0x3<<8)
-#define VOICE_BCLK_DIV2_32 (0x4<<8)
-
-#define VOICE_AD_LRCK_DIV1_MASK (0xF<<4)
-#define VOICE_AD_LRCK_DIV1_1 (0x0<<4)
-#define VOICE_AD_LRCK_DIV1_2 (0x1<<4)
-#define VOICE_AD_LRCK_DIV1_3 (0x2<<4)
-#define VOICE_AD_LRCK_DIV1_4 (0x3<<4)
-#define VOICE_AD_LRCK_DIV1_5 (0x4<<4)
-#define VOICE_AD_LRCK_DIV1_6 (0x5<<4)
-#define VOICE_AD_LRCK_DIV1_7 (0x6<<4)
-#define VOICE_AD_LRCK_DIV1_8 (0x7<<4)
-#define VOICE_AD_LRCK_DIV1_9 (0x8<<4)
-#define VOICE_AD_LRCK_DIV1_10 (0x9<<4)
-#define VOICE_AD_LRCK_DIV1_11 (0xA<<4)
-#define VOICE_AD_LRCK_DIV1_12 (0xB<<4)
-#define VOICE_AD_LRCK_DIV1_13 (0xC<<4)
-#define VOICE_AD_LRCK_DIV1_14 (0xD<<4)
-#define VOICE_AD_LRCK_DIV1_15 (0xE<<4)
-#define VOICE_AD_LRCK_DIV1_16 (0xF<<4)
-
-#define VOICE_AD_LRCK_DIV2_MASK (0x7<<1)
-#define VOICE_AD_LRCK_DIV2_2 (0x0<<1)
-#define VOICE_AD_LRCK_DIV2_4 (0x1<<1)
-#define VOICE_AD_LRCK_DIV2_8 (0x2<<1)
-#define VOICE_AD_LRCK_DIV2_16 (0x3<<1)
-#define VOICE_AD_LRCK_DIV2_32 (0x4<<1)
-
-#define VOICE_DA_LRCK_DIV_MASK (1)
-#define VOICE_DA_LRCK_DIV_32 (0)
-#define VOICE_DA_LRCK_DIV_64 (1)
-
-
-//Psedueo Stereo & Spatial Effect Block Control(0x68)
-#define SPATIAL_CTRL_EN (0x1<<15)
-#define ALL_PASS_FILTER_EN (0x1<<14)
-#define PSEUDO_STEREO_EN (0x1<<13)
-#define STEREO_EXPENSION_EN (0x1<<12)
-
-#define SPATIAL_3D_GAIN1_MASK (0x3<<10)
-#define SPATIAL_3D_GAIN1_1_0 (0x0<<10)
-#define SPATIAL_3D_GAIN1_1_5 (0x1<<10)
-#define SPATIAL_3D_GAIN1_2_0 (0x2<<10)
-
-#define SPATIAL_3D_RATIO1_MASK (0x3<<8)
-#define SPATIAL_3D_RATIO1_0_0 (0x0<<8)
-#define SPATIAL_3D_RATIO1_0_66 (0x1<<8)
-#define SPATIAL_3D_RATIO1_1_0 (0x2<<8)
-
-#define SPATIAL_3D_GAIN2_MASK (0x3<<6)
-#define SPATIAL_3D_GAIN2_1_0 (0x0<<6)
-#define SPATIAL_3D_GAIN2_1_5 (0x1<<6)
-#define SPATIAL_3D_GAIN2_2_0 (0x2<<6)
-
-#define SPATIAL_3D_RATIO2_MASK (0x3<<4)
-#define SPATIAL_3D_RATIO2_0_0 (0x0<<4)
-#define SPATIAL_3D_RATIO2_0_66 (0x1<<4)
-#define SPATIAL_3D_RATIO2_1_0 (0x2<<4)
-
-#define APF_MASK (0x3)
-#define APF_FOR_48K (0x3)
-#define APF_FOR_44_1K (0x2)
-#define APF_FOR_32K (0x1)
-
-//EQ Control and Status /ADC HPF Control(0x6E)
-#define EN_HW_EQ_BLK (0x1<<15) //HW EQ block control
-
-#define EQ_SOUR_SEL_DAC (0x0<<14)
-#define EQ_SOUR_SEL_ADC (0x1<<14)
-
-#define EQ_CHANGE_EN (0x1<<7) //EQ parameter update control
-#define EN_HW_EQ_HPF (0x1<<4) //EQ High Pass Filter Control
-#define EN_HW_EQ_BP3 (0x1<<3) //EQ Band-3 Control
-#define EN_HW_EQ_BP2 (0x1<<2) //EQ Band-2 Control
-#define EN_HW_EQ_BP1 (0x1<<1) //EQ Band-1 Control
-#define EN_HW_EQ_LPF (0x1<<0) //EQ Low Pass Filter Control
-
-
-//AEC register command(0x74)
-
-#define VODSP_BUSY (0x1<<15) //VODSP I2C busy flag
-
-#define VODSP_S_FROM_VODSP_RD (0x0<<14)
-#define VODSP_S_FROM_MX72 (0x1<<14)
-
-#define VODSP_CLK_SEL_MASK (0x3<<12) //VODSP CLK select Mask
-#define VODSP_CLK_SEL_12_288M (0x0<<12) //VODSP CLK select 12.288Mhz
-#define VODSP_CLK_SEL_6_144M (0x1<<12) //VODSP CLK select 6.144Mhz
-#define VODSP_CLK_SEL_3_072M (0x2<<12) //VODSP CLK select 3.072Mhz
-#define VODSP_CLK_SEL_2_048M (0x3<<12) //VODSP CLK select 2.0488Mhz
-
-#define VODSP_READ_ENABLE (0x1<<9) //VODSP Read Enable
-#define VODSP_WRITE_ENABLE (0x1<<8) //VODSP Write Enable
-
-#define VODSP_CMD_MASK (0xFF<<0)
-#define VODSP_CMD_MW (0x3B<<0) //Memory Write
-#define VODSP_CMD_MR (0x37<<0) //Memory Read
-#define VODSP_CMD_RR (0x60<<0) //Register Read
-#define VODSP_CMD_RW (0x68<<0) //Register Write
-
-
-/*************************************************************************************************
- *Index register of codec
- *************************************************************************************************/
-/*Index(0x20) for Auto Volume Control*/
-#define AVC_CH_SEL_MASK (0x1<<7)
-#define AVC_CH_SEL_L_CH (0x0<<7)
-#define AVC_CH_SEL_R_CH (0x1<<7)
-#define ENABLE_AVC_GAIN_CTRL (0x1<<15)
-//*************************************************************************************************
-//*************************************************************************************************
-
-#define REALTEK_HWDEP 0
-
-#if REALTEK_HWDEP
-
-struct rt56xx_reg_state
-{
- unsigned int reg_index;
- unsigned int reg_value;
+/*
+ * rt5625.h -- RT5625 ALSA SoC audio driver
+ *
+ * Copyright 2011 Realtek Microelectronics
+ * Author: Johnny Hsu <johnnyhsu@realtek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __RT5625_H__
+#define __RT5625_H__
+
+#define RT5625_RESET 0x00
+#define RT5625_SPK_OUT_VOL 0x02
+#define RT5625_HP_OUT_VOL 0x04
+#define RT5625_AUX_OUT_VOL 0x06
+#define RT5625_PHONEIN_VOL 0x08
+#define RT5625_LINE_IN_VOL 0x0a
+#define RT5625_DAC_VOL 0x0c
+#define RT5625_MIC_VOL 0x0e
+#define RT5625_DAC_MIC_CTRL 0x10
+#define RT5625_ADC_REC_GAIN 0x12
+#define RT5625_ADC_REC_MIXER 0x14
+#define RT5625_VDAC_OUT_VOL 0x18
+#define RT5625_VODSP_PDM_CTL 0x1a
+#define RT5625_OUTMIX_CTRL 0x1c
+#define RT5625_VODSP_CTL 0x1e
+#define RT5625_MIC_CTRL 0x22
+#define RT5625_DMIC_CTRL 0x24
+#define RT5625_PD_CTRL 0x26
+#define RT5625_F_DAC_ADC_VDAC 0x2e
+#define RT5625_SDP_CTRL 0x34
+#define RT5625_EXT_SDP_CTRL 0x36
+#define RT5625_PWR_ADD1 0x3a
+#define RT5625_PWR_ADD2 0x3c
+#define RT5625_PWR_ADD3 0x3e
+#define RT5625_GEN_CTRL1 0x40
+#define RT5625_GEN_CTRL2 0x42
+#define RT5625_PLL_CTRL 0x44
+#define RT5625_PLL2_CTRL 0x46
+#define RT5625_LDO_CTRL 0x48
+#define RT5625_GPIO_CONFIG 0x4c
+#define RT5625_GPIO_POLAR 0x4e
+#define RT5625_GPIO_STICKY 0x50
+#define RT5625_GPIO_WAKEUP 0x52
+#define RT5625_GPIO_STATUS 0x54
+#define RT5625_GPIO_SHARING 0x56
+#define RT5625_OTC_STATUS 0x58
+#define RT5625_SOFT_VOL_CTRL 0x5a
+#define RT5625_GPIO_OUT_CTRL 0x5c
+#define RT5625_MISC_CTRL 0x5e
+#define RT5625_DAC_CLK_CTRL1 0x60
+#define RT5625_DAC_CLK_CTRL2 0x62
+#define RT5625_VDAC_CLK_CTRL1 0x64
+#define RT5625_PS_CTRL 0x68
+#define RT5625_PRIV_INDEX 0x6a
+#define RT5625_PRIV_DATA 0x6c
+#define RT5625_EQ_CTRL 0x6e
+#define RT5625_DSP_ADDR 0x70
+#define RT5625_DSP_DATA 0x72
+#define RT5625_DSP_CMD 0x74
+#define RT5625_VENDOR_ID1 0x7c
+#define RT5625_VENDOR_ID2 0x7e
+
+/* global definition */
+#define RT5625_L_MUTE (0x1 << 15)
+#define RT5625_L_MUTE_SFT 15
+#define RT5625_L_ZC (0x1 << 14)
+#define RT5625_L_VOL_MASK (0x1f << 8)
+#define RT5625_L_HVOL_MASK (0x3f << 8)
+#define RT5625_L_VOL_SFT 8
+#define RT5625_R_MUTE (0x1 << 7)
+#define RT5625_R_MUTE_SFT 7
+#define RT5625_R_ZC (0x1 << 6)
+#define RT5625_R_VOL_MASK (0x1f)
+#define RT5625_R_HVOL_MASK (0x3f)
+#define RT5625_R_VOL_SFT 0
+#define RT5625_M_HPMIX (0x1 << 15)
+#define RT5625_M_SPKMIX (0x1 << 14)
+#define RT5625_M_MONOMIX (0x1 << 13)
+
+/* Phone Input (0x08) */
+#define RT5625_M_PHO_HM (0x1 << 15)
+#define RT5625_M_PHO_HM_SFT 15
+#define RT5625_M_PHO_SM (0x1 << 14)
+#define RT5625_M_PHO_SM_SFT 14
+#define RT5625_PHO_DIFF (0x1 << 13)
+#define RT5625_PHO_DIFF_SFT 13
+#define RT5625_PHO_DIFF_DIS (0x0 << 13)
+#define RT5625_PHO_DIFF_EN (0x1 << 13)
+
+/* Linein Volume (0x0a) */
+#define RT5625_M_LI_HM (0x1 << 15)
+#define RT5625_M_LI_HM_SFT 15
+#define RT5625_M_LI_SM (0x1 << 14)
+#define RT5625_M_LI_SM_SFT 14
+#define RT5625_M_LI_MM (0x1 << 13)
+#define RT5625_M_LI_MM_SFT 13
+
+/* MIC Input Volume (0x0e) */
+#define RT5625_MIC1_DIFF_MASK (0x1 << 15)
+#define RT5625_MIC1_DIFF_SFT 15
+#define RT5625_MIC1_DIFF_DIS (0x0 << 15)
+#define RT5625_MIC1_DIFF_EN (0x1 << 15)
+#define RT5625_MIC2_DIFF_MASK (0x1 << 7)
+#define RT5625_MIC2_DIFF_SFT 7
+#define RT5625_MIC2_DIFF_DIS (0x0 << 7)
+#define RT5625_MIC2_DIFF_EN (0x1 << 7)
+
+/* Stereo DAC and MIC Routing Control (0x10) */
+#define RT5625_M_MIC1_HM (0x1 << 15)
+#define RT5625_M_MIC1_HM_SFT 15
+#define RT5625_M_MIC1_SM (0x1 << 14)
+#define RT5625_M_MIC1_SM_SFT 14
+#define RT5625_M_MIC1_MM (0x1 << 13)
+#define RT5625_M_MIC1_MM_SFT 13
+#define RT5625_M_MIC2_HM (0x1 << 11)
+#define RT5625_M_MIC2_HM_SFT 11
+#define RT5625_M_MIC2_SM (0x1 << 10)
+#define RT5625_M_MIC2_SM_SFT 10
+#define RT5625_M_MIC2_MM (0x1 << 9)
+#define RT5625_M_MIC2_MM_SFT 9
+#define RT5625_M_DACL_HM (0x1 << 3)
+#define RT5625_M_DACL_HM_SFT 3
+#define RT5625_M_DACR_HM (0x1 << 2)
+#define RT5625_M_DACR_HM_SFT 2
+#define RT5625_M_DAC_SM (0x1 << 1)
+#define RT5625_M_DAC_SM_SFT 1
+#define RT5625_M_DAC_MM (0x1)
+#define RT5625_M_DAC_MM_SFT 0
+
+/* ADC Record Gain (0x12) */
+#define RT5625_M_ADCL_HM (0x1 << 15)
+#define RT5625_M_ADCL_HM_SFT 15
+#define RT5625_M_ADCL_MM (0x1 << 14)
+#define RT5625_M_ADCL_MM_SFT 14
+#define RT5625_ADCL_ZCD (0x1 << 13)
+#define RT5625_G_ADCL_MASK (0x1f << 8)
+#define RT5625_M_ADCR_HM (0x1 << 7)
+#define RT5625_M_ADCR_HM_SFT 7
+#define RT5625_M_ADCR_MM (0x1 << 6)
+#define RT5625_M_ADCR_MM_SFT 6
+#define RT5625_ADCR_ZCD (0x1 << 5)
+#define RT5625_G_ADCR_MASK (0x1f)
+
+/* ADC Record Mixer Control (0x14) */
+#define RT5625_M_RM_L_MIC1 (0x1 << 14)
+#define RT5625_M_RM_L_MIC1_SFT 14
+#define RT5625_M_RM_L_MIC2 (0x1 << 13)
+#define RT5625_M_RM_L_MIC2_SFT 13
+#define RT5625_M_RM_L_LINE (0x1 << 12)
+#define RT5625_M_RM_L_LINE_SFT 12
+#define RT5625_M_RM_L_PHO (0x1 << 11)
+#define RT5625_M_RM_L_PHO_SFT 11
+#define RT5625_M_RM_L_HM (0x1 << 10)
+#define RT5625_M_RM_L_HM_SFT 10
+#define RT5625_M_RM_L_SM (0x1 << 9)
+#define RT5625_M_RM_L_SM_SFT 9
+#define RT5625_M_RM_L_MM (0x1 << 8)
+#define RT5625_M_RM_L_MM_SFT 8
+#define RT5625_M_RM_R_MIC1 (0x1 << 6)
+#define RT5625_M_RM_R_MIC1_SFT 6
+#define RT5625_M_RM_R_MIC2 (0x1 << 5)
+#define RT5625_M_RM_R_MIC2_SFT 5
+#define RT5625_M_RM_R_LINE (0x1 << 4)
+#define RT5625_M_RM_R_LINE_SFT 4
+#define RT5625_M_RM_R_PHO (0x1 << 3)
+#define RT5625_M_RM_R_PHO_SFT 3
+#define RT5625_M_RM_R_HM (0x1 << 2)
+#define RT5625_M_RM_R_HM_SFT 2
+#define RT5625_M_RM_R_SM (0x1 << 1)
+#define RT5625_M_RM_R_SM_SFT 1
+#define RT5625_M_RM_R_MM (0x1)
+#define RT5625_M_RM_R_MM_SFT 0
+
+/* Voice DAC Volume (0x18) */
+#define RT5625_M_VDAC_HM (0x1 << 15)
+#define RT5625_M_VDAC_HM_SFT 15
+#define RT5625_M_VDAC_SM (0x1 << 14)
+#define RT5625_M_VDAC_SM_SFT 14
+#define RT5625_M_VDAC_MM (0x1 << 13)
+#define RT5625_M_VDAC_MM_SFT 13
+
+/* AEC & PDM Control (0x1a) */
+#define RT5625_SRC1_PWR (0x1 << 15)
+#define RT5625_SRC1_PWR_SFT 15
+#define RT5625_SRC2_PWR (0x1 << 13)
+#define RT5625_SRC2_PWR_SFT 13
+#define RT5625_SRC2_S_MASK (0x1 << 12)
+#define RT5625_SRC2_S_SFT 12
+#define RT5625_SRC2_S_TXDP (0x0 << 12)
+#define RT5625_SRC2_S_TXDC (0x1 << 12)
+#define RT5625_RXDP_PWR (0x1 << 11)
+#define RT5625_RXDP_PWR_SFT 11
+#define RT5625_RXDP_S_MASK (0x3 << 9)
+#define RT5625_RXDP_S_SFT 9
+#define RT5625_RXDP_S_SRC1 (0x0 << 9)
+#define RT5625_RXDP_S_ADCL (0x1 << 9)
+#define RT5625_RXDP_S_VOICE (0x2 << 9)
+#define RT5625_RXDP_S_ADCR (0x3 << 9)
+#define RT5625_RXDC_PWR (0x1 << 8)
+#define RT5625_RXDC_PWR_SFT 8
+#define RT5625_PCM_S_MASK (0x1 << 7)
+#define RT5625_PCM_S_SFT 7
+#define RT5625_PCM_S_ADCR (0x0 << 7)
+#define RT5625_PCM_S_TXDP (0x1 << 7)
+#define RT5625_REC_IIS_S_MASK (0x3 << 4)
+#define RT5625_REC_IIS_S_SFT 4
+#define RT5625_REC_IIS_S_ADC (0x0 << 4)
+#define RT5625_REC_IIS_S_VOICE (0x1 << 4)
+#define RT5625_REC_IIS_S_SRC2 (0x2 << 4)
+
+/* Output Mixer Control (0x1c) */
+#define RT5625_SPKN_S_MASK (0x3 << 14)
+#define RT5625_SPKN_S_SFT 14
+#define RT5625_SPKN_S_LN (0x2 << 14)
+#define RT5625_SPKN_S_RP (0x1 << 14)
+#define RT5625_SPKN_S_RN (0x0 << 14)
+#define RT5625_SPK_T_MASK (0x1 << 13)
+#define RT5625_SPK_T_SFT 13
+#define RT5625_SPK_T_CLS_D (0x1 << 13)
+#define RT5625_SPK_T_CLS_AB (0x0 << 13)
+#define RT5625_CLS_AB_MASK (0x1 << 12)
+#define RT5625_CLS_AB_SFT 12
+#define RT5625_CLS_AB_S_AMP (0x0 << 12)
+#define RT5625_CLS_AB_W_AMP (0x1 << 12)
+#define RT5625_SPKVOL_S_MASK (0x3 << 10)
+#define RT5625_SPKVOL_S_SFT 10
+#define RT5625_SPKVOL_S_MM (0x3 << 10)
+#define RT5625_SPKVOL_S_SM (0x2 << 10)
+#define RT5625_SPKVOL_S_HM (0x1 << 10)
+#define RT5625_SPKVOL_S_VMID (0x0 << 10)
+#define RT5625_HPVOL_L_S_MASK (0x1 << 9)
+#define RT5625_HPVOL_L_S_SFT 9
+#define RT5625_HPVOL_L_S_HM (0x1 << 9)
+#define RT5625_HPVOL_L_S_VMID (0x0 << 9)
+#define RT5625_HPVOL_R_S_MASK (0x1 << 8)
+#define RT5625_HPVOL_R_S_SFT 8
+#define RT5625_HPVOL_R_S_HM (0x1 << 8)
+#define RT5625_HPVOL_R_S_VMID (0x0 << 8)
+#define RT5625_AUXVOL_S_MASK (0x3 << 6)
+#define RT5625_AUXVOL_S_SFT 6
+#define RT5625_AUXVOL_S_MM (0x3 << 6)
+#define RT5625_AUXVOL_S_SM (0x2 << 6)
+#define RT5625_AUXVOL_S_HM (0x1 << 6)
+#define RT5625_AUXVOL_S_VMID (0x0 << 6)
+#define RT5625_AUXOUT_MODE (0x1 << 4)
+#define RT5625_AUXOUT_MODE_SFT 4
+#define RT5625_DACL_HP_MASK (0x1 << 1)
+#define RT5625_DACL_HP_SFT 1
+#define RT5625_DACL_HP_MUTE (0x0 << 1)
+#define RT5625_DACL_HP_ON (0x1 << 1)
+#define RT5625_DACR_HP_MASK (0x1)
+#define RT5625_DACR_HP_SFT 0
+#define RT5625_DACR_HP_MUTE (0x0)
+#define RT5625_DACR_HP_ON (0x1)
+
+/* VoDSP Control (0x1e) */
+#define RT5625_DSP_SCLK_S_MASK (0x1 << 15)
+#define RT5625_DSP_SCLK_S_SFT 15
+#define RT5625_DSP_SCLK_S_MCLK (0x0 << 15)
+#define RT5625_DSP_SCLK_S_VCLK (0x1 << 15)
+#define RT5625_DSP_LRCK_MASK (0x1 << 13)
+#define RT5625_DSP_LRCK_SFT 13
+#define RT5625_DSP_LRCK_8K (0x0 << 13)
+#define RT5625_DSP_LRCK_16K (0x1 << 13)
+#define RT5625_DSP_TP_MASK (0x1 << 3)
+#define RT5625_DSP_TP_SFT 3
+#define RT5625_DSP_TP_NOR (0x0 << 3)
+#define RT5625_DSP_TP_TEST (0x1 << 3)
+#define RT5625_DSP_BP_MASK (0x1 << 2)
+#define RT5625_DSP_BP_SFT 2
+#define RT5625_DSP_BP_EN (0x0 << 2)
+#define RT5625_DSP_BP_NOR (0x1 << 2)
+#define RT5625_DSP_PD_MASK (0x1 << 1)
+#define RT5625_DSP_PD_SFT 1
+#define RT5625_DSP_PD_EN (0x0 << 1)
+#define RT5625_DSP_PD_NOR (0x1 << 1)
+#define RT5625_DSP_RST_MASK (0x1)
+#define RT5625_DSP_RST_SFT 0
+#define RT5625_DSP_RST_EN (0x0)
+#define RT5625_DSP_RST_NOR (0x1)
+
+/* Microphone Control (0x22) */
+#define RT5625_MIC1_BST_MASK (0x3 << 10)
+#define RT5625_MIC1_BST_SFT 10
+#define RT5625_MIC1_BST_BYPASS (0x0 << 10)
+#define RT5625_MIC1_BST_20DB (0x1 << 10)
+#define RT5625_MIC1_BST_30DB (0x2 << 10)
+#define RT5625_MIC1_BST_40DB (0x3 << 10)
+#define RT5625_MIC2_BST_MASK (0x3 << 8)
+#define RT5625_MIC2_BST_SFT 8
+#define RT5625_MIC2_BST_BYPASS (0x0 << 8)
+#define RT5625_MIC2_BST_20DB (0x1 << 8)
+#define RT5625_MIC2_BST_30DB (0x2 << 8)
+#define RT5625_MIC2_BST_40DB (0x3 << 8)
+#define RT5625_MB1_OV_MASK (0x1 << 5)
+#define RT5625_MB1_OV_90P (0x0 << 5)
+#define RT5625_MB1_OV_75P (0x1 << 5)
+#define RT5625_MB2_OV_MASK (0x1 << 4)
+#define RT5625_MB2_OV_90P (0x0 << 4)
+#define RT5625_MB2_OV_75P (0x1 << 4)
+#define RT5625_SCD_THD_MASK (0x3)
+#define RT5625_SCD_THD_600UA (0x0)
+#define RT5625_SCD_THD_1500UA (0x1)
+#define RT5625_SCD_THD_2000UA (0x2)
+
+/* Digital Boost Control (0x24) */
+#define RT5625_DIG_BST_MASK (0x7)
+#define RT5625_DIG_BST_SFT 0
+
+/* Power Down Control/Status (0x26) */
+#define RT5625_PWR_PR7 (0x1 << 15)
+#define RT5625_PWR_PR6 (0x1 << 14)
+#define RT5625_PWR_PR5 (0x1 << 13)
+#define RT5625_PWR_PR3 (0x1 << 11)
+#define RT5625_PWR_PR2 (0x1 << 10)
+#define RT5625_PWR_PR1 (0x1 << 9)
+#define RT5625_PWR_PR0 (0x1 << 8)
+#define RT5625_PWR_REF_ST (0x1 << 3)
+#define RT5625_PWR_AM_ST (0x1 << 2)
+#define RT5625_PWR_DAC_ST (0x1 << 1)
+#define RT5625_PWR_ADC_ST (0x1)
+
+/* Stereo DAC/Voice DAC/Stereo ADC Function Select (0x2e) */
+#define RT5625_DAC_F_MASK (0x3 << 12)
+#define RT5625_DAC_F_SFT 12
+#define RT5625_DAC_F_DAC (0x0 << 12)
+#define RT5625_DAC_F_SRC2 (0x1 << 12)
+#define RT5625_DAC_F_TXDP (0x2 << 12)
+#define RT5625_DAC_F_TXDC (0x3 << 12)
+#define RT5625_VDAC_S_MASK (0x7 << 8)
+#define RT5625_VDAC_S_SFT 8
+#define RT5625_VDAC_S_VOICE (0x0 << 8)
+#define RT5625_VDAC_S_SRC2 (0x1 << 8)
+#define RT5625_VDAC_S_TXDP (0x2 << 8)
+#define RT5625_VDAC_S_TXDC (0x3 << 8)
+#define RT5625_ADCR_F_MASK (0x3 << 4)
+#define RT5625_ADCR_F_SFT 4
+#define RT5625_ADCR_F_ADC (0x0 << 4)
+#define RT5625_ADCR_F_VADC (0x1 << 4)
+#define RT5625_ADCR_F_DSP (0x2 << 4)
+#define RT5625_ADCR_F_PDM (0x3 << 4)
+#define RT5625_ADCL_F_MASK (0x1)
+#define RT5625_ADCL_F_SFT 0
+#define RT5625_ADCL_F_ADC (0x0)
+#define RT5625_ADCL_F_DSP (0x1)
+
+/* Main Serial Data Port Control (Stereo IIS) (0x34) */
+#define RT5625_I2S_M_MASK (0x1 << 15)
+#define RT5625_I2S_M_SFT 15
+#define RT5625_I2S_M_MST (0x0 << 15)
+#define RT5625_I2S_M_SLV (0x1 << 15)
+#define RT5625_I2S_SAD_MASK (0x1 << 14)
+#define RT5625_I2S_SAD_SFT 14
+#define RT5625_I2S_SAD_DIS (0x0 << 14)
+#define RT5625_I2S_SAD_EN (0x1 << 14)
+#define RT5625_I2S_S_MASK (0x1 << 8)
+#define RT5625_I2S_S_SFT 8
+#define RT5625_I2S_S_MSCLK (0x0 << 8)
+#define RT5625_I2S_S_VSCLK (0x1 << 8)
+#define RT5625_I2S_BP_MASK (0x1 << 7)
+#define RT5625_I2S_BP_SFT 7
+#define RT5625_I2S_BP_NOR (0x0 << 7)
+#define RT5625_I2S_BP_INV (0x1 << 7)
+#define RT5625_I2S_LRCK_MASK (0x1 << 6)
+#define RT5625_I2S_LRCK_SFT 6
+#define RT5625_I2S_LRCK_NOR (0x0 << 6)
+#define RT5625_I2S_LRCK_INV (0x1 << 6)
+#define RT5625_I2S_DL_MASK (0x3 << 2)
+#define RT5625_I2S_DL_SFT 2
+#define RT5625_I2S_DL_16 (0x0 << 2)
+#define RT5625_I2S_DL_20 (0x1 << 2)
+#define RT5625_I2S_DL_24 (0x2 << 2)
+#define RT5625_I2S_DL_8 (0x3 << 2)
+#define RT5625_I2S_DF_MASK (0x3)
+#define RT5625_I2S_DF_SFT 0
+#define RT5625_I2S_DF_I2S (0x0)
+#define RT5625_I2S_DF_LEFT (0x1)
+#define RT5625_I2S_DF_PCM_A (0x2)
+#define RT5625_I2S_DF_PCM_B (0x3)
+
+/* Extend Serial Data Port Control (0x36) */
+#define RT5625_PCM_F_MASK (0x1 << 15)
+#define RT5625_PCM_F_SFT 15
+#define RT5625_PCM_F_GPIO (0x0 << 15)
+#define RT5625_PCM_F_PCM (0x1 << 15)
+#define RT5625_PCM_M_MASK (0x1 << 14)
+#define RT5625_PCM_M_SFT 14
+#define RT5625_PCM_M_MST (0x0 << 14)
+#define RT5625_PCM_M_SLV (0x1 << 14)
+#define RT5625_PCM_CS_MASK (0x1 << 8)
+#define RT5625_PCM_CS_SFT 8
+#define RT5625_PCM_CS_SCLK (0x0 << 8)
+#define RT5625_PCM_CS_VSCLK (0x1 << 8)
+
+/* Power Management Addition 1 (0x3a) */
+#define RT5625_P_DACL_MIX (0x1 << 15)
+#define RT5625_P_DACL_MIX_BIT 15
+#define RT5625_P_DACR_MIX (0x1 << 14)
+#define RT5625_P_DACR_MIX_BIT 14
+#define RT5625_P_ZCD (0x1 << 13)
+#define RT5625_P_ZCD_BIT 13
+#define RT5625_P_I2S (0x1 << 11)
+#define RT5625_P_I2S_BIT 11
+#define RT5625_P_SPK_AMP (0x1 << 10)
+#define RT5625_P_SPK_AMP_BIT 10
+#define RT5625_P_HPO_AMP (0x1 << 9)
+#define RT5625_P_HPO_AMP_BIT 9
+#define RT5625_P_HPO_ENH (0x1 << 8)
+#define RT5625_P_HPO_ENH_BIT 8
+#define RT5625_P_VDAC_MIX (0x1 << 7)
+#define RT5625_P_VDAC_MIX_BIT 7
+#define RT5625_P_SG_EN (0x1 << 6)
+#define RT5625_P_SG_EN_BIT 6
+#define RT5625_P_MB1_SCD (0x1 << 5)
+#define RT5625_P_MB1_SCD_BIT 5
+#define RT5625_P_MB2_SCD (0x1 << 4)
+#define RT5625_P_MB2_SCD_BIT 4
+#define RT5625_P_MB1 (0x1 << 3)
+#define RT5625_P_MB1_BIT 3
+#define RT5625_P_MB2 (0x1 << 2)
+#define RT5625_P_MB2_BIT 2
+#define RT5625_P_MAIN_BIAS (0x1 << 1)
+#define RT5625_P_MAIN_BIAS_BIT 1
+#define RT5625_P_DAC_REF (0x1)
+#define RT5625_P_DAC_REF_BIT 0
+
+/* Power Management Addition 2 (0x3c) */
+#define RT5625_P_PLL1 (0x1 << 15)
+#define RT5625_P_PLL1_BIT 15
+#define RT5625_P_PLL2 (0x1 << 14)
+#define RT5625_P_PLL2_BIT 14
+#define RT5625_P_VREF (0x1 << 13)
+#define RT5625_P_VREF_BIT 13
+#define RT5625_P_OVT (0x1 << 12)
+#define RT5625_P_OVT_BIT 12
+#define RT5625_P_AUX_ADC (0x1 << 11)
+#define RT5625_P_AUX_ADC_BIT 11
+#define RT5625_P_VDAC (0x1 << 10)
+#define RT5625_P_VDAC_BIT 10
+#define RT5625_P_DACL (0x1 << 9)
+#define RT5625_P_DACL_BIT 9
+#define RT5625_P_DACR (0x1 << 8)
+#define RT5625_P_DACR_BIT 8
+#define RT5625_P_ADCL (0x1 << 7)
+#define RT5625_P_ADCL_BIT 7
+#define RT5625_P_ADCR (0x1 << 6)
+#define RT5625_P_ADCR_BIT 6
+#define RT5625_P_HM_L (0x1 << 5)
+#define RT5625_P_HM_L_BIT 5
+#define RT5625_P_HM_R (0x1 << 4)
+#define RT5625_P_HM_R_BIT 4
+#define RT5625_P_SM (0x1 << 3)
+#define RT5625_P_SM_BIT 3
+#define RT5625_P_MM (0x1 << 2)
+#define RT5625_P_MM_BIT 2
+#define RT5625_P_ADCL_RM (0x1 << 1)
+#define RT5625_P_ADCL_RM_BIT 1
+#define RT5625_P_ADCR_RM (0x1)
+#define RT5625_P_ADCR_RM_BIT 0
+
+/* Power Management Addition 3 (0x3e) */
+#define RT5625_P_OSC_EN (0x1 << 15)
+#define RT5625_P_OSC_EN_BIT 15
+#define RT5625_P_AUX_VOL (0x1 << 14)
+#define RT5625_P_AUX_VOL_BIT 14
+#define RT5625_P_SPKL_VOL (0x1 << 13)
+#define RT5625_P_SPKL_VOL_BIT 13
+#define RT5625_P_SPKR_VOL (0x1 << 12)
+#define RT5625_P_SPKR_VOL_BIT 12
+#define RT5625_P_HPL_VOL (0x1 << 11)
+#define RT5625_P_HPL_VOL_BIT 11
+#define RT5625_P_HPR_VOL (0x1 << 10)
+#define RT5625_P_HPR_VOL_BIT 10
+#define RT5625_P_DSP_IF (0x1 << 9)
+#define RT5625_P_DSP_IF_BIT 9
+#define RT5625_P_DSP_I2C (0x1 << 8)
+#define RT5625_P_DSP_I2C_BIT 8
+#define RT5625_P_LV_L (0x1 << 7)
+#define RT5625_P_LV_L_BIT 7
+#define RT5625_P_LV_R (0x1 << 6)
+#define RT5625_P_LV_R_BIT 6
+#define RT5625_P_PH_VOL (0x1 << 5)
+#define RT5625_P_PH_VOL_BIT 5
+#define RT5625_P_PH_ADMIX (0x1 << 4)
+#define RT5625_P_PH_ADMIX_BIT 4
+#define RT5625_P_MIC1_VOL (0x1 << 3)
+#define RT5625_P_MIC1_VOL_BIT 3
+#define RT5625_P_MIC2_VOL (0x1 << 2)
+#define RT5625_P_MIC2_VOL_BIT 2
+#define RT5625_P_MIC1_BST (0x1 << 1)
+#define RT5625_P_MIC1_BST_BIT 1
+#define RT5625_P_MIC2_BST (0x1)
+#define RT5625_P_MIC2_BST_BIT 0
+
+/* General Purpose Control Register 1 (0x40) */
+#define RT5625_SCLK_MASK (0x1 << 15)
+#define RT5625_SCLK_SFT 15
+#define RT5625_SCLK_MCLK (0x0 << 15)
+#define RT5625_SCLK_PLL1 (0x1 << 15)
+#define RT5625_VSCLK_MASK (0x1 << 4)
+#define RT5625_VSCLK_SFT 4
+#define RT5625_VSCLK_PLL2 (0x0<<4)
+#define RT5625_VSCLK_EXTCLK (0x1<<4)
+#define RT5625_SPK_R_MASK (0x7 << 1)
+#define RT5625_SPK_R_SFT 1
+#define RT5625_SPK_R_225V (0x0 << 1)
+#define RT5625_SPK_R_200V (0x1 << 1)
+#define RT5625_SPK_R_175V (0x2 << 1)
+#define RT5625_SPK_R_150V (0x3 << 1)
+#define RT5625_SPK_R_125V (0x4 << 1)
+#define RT5625_SPK_R_100V (0x5 << 1)
+
+/* General Purpose Control Register 2 (0x42) */
+#define RT5625_PLL1_S_MASK (0x3 << 12)
+#define RT5625_PLL1_S_SFT 12
+#define RT5625_PLL1_S_MCLK (0x0 << 12)
+#define RT5625_PLL1_S_BCLK (0x2 << 12)
+#define RT5625_PLL1_S_VBCLK (0x3 << 12)
+
+/* PLL2 Control (0x46) */
+#define RT5625_PLL2_MASK (0x1 << 15)
+#define RT5625_PLL2_DIS (0x0 << 15)
+#define RT5625_PLL2_EN (0x1 << 15)
+#define RT5625_PLL2_R_MASK (0x1)
+#define RT5625_PLL2_R_8X (0x0)
+#define RT5625_PLL2_R_16X (0x1)
+
+/* LDO Control (0x48) */
+#define RT5625_LDO_MASK (0x1 << 15)
+#define RT5625_LDO_DIS (0x0 << 15)
+#define RT5625_LDO_EN (0x1 << 15)
+#define RT5625_LDO_VC_MASK (0xf)
+#define RT5625_LDO_VC_1_55V (0xf<<0)
+#define RT5625_LDO_VC_1_50V (0xe<<0)
+#define RT5625_LDO_VC_1_45V (0xd<<0)
+#define RT5625_LDO_VC_1_40V (0xc<<0)
+#define RT5625_LDO_VC_1_35V (0xb<<0)
+#define RT5625_LDO_VC_1_30V (0xa<<0)
+#define RT5625_LDO_VC_1_25V (0x9<<0)
+#define RT5625_LDO_VC_1_20V (0x8<<0)
+#define RT5625_LDO_VC_1_15V (0x7<<0)
+#define RT5625_LDO_VC_1_05V (0x6<<0)
+#define RT5625_LDO_VC_1_00V (0x5<<0)
+#define RT5625_LDO_VC_0_95V (0x4<<0)
+#define RT5625_LDO_VC_0_90V (0x3<<0)
+#define RT5625_LDO_VC_0_85V (0x2<<0)
+#define RT5625_LDO_VC_0_80V (0x1<<0)
+#define RT5625_LDO_VC_0_75V (0x0<<0)
+
+/* GPIO Pin Configuration (0x4c) */
+#define RT5625_GPIO_5 (0x1 << 5)
+#define RT5625_GPIO_4 (0x1 << 4)
+#define RT5625_GPIO_3 (0x1 << 3)
+#define RT5625_GPIO_2 (0x1 << 2)
+#define RT5625_GPIO_1 (0x1 << 1)
+
+/* MISC Control (0x5e) */
+#define RT5625_FAST_VREF_MASK (0x1 << 15)
+#define RT5625_FAST_VREF_EN (0x0 << 15)
+#define RT5625_FAST_VREF_DIS (0x1 << 15)
+#define RT5625_HP_DEPOP_M2 (0x1 << 8)
+#define RT5625_HP_DEPOP_M1 (0x1 << 9)
+#define RT5625_HPL_MUM_DEPOP (0x1 << 7)
+#define RT5625_HPR_MUM_DEPOP (0x1 << 6)
+#define RT5625_MUM_DEPOP (0x1 << 5)
+
+/* Stereo DAC Clock Control 1 (0x60) */
+#define RT5625_BCLK_DIV1_MASK (0xf << 12)
+#define RT5625_BCLK_DIV1_1 (0x0 << 12)
+#define RT5625_BCLK_DIV1_2 (0x1 << 12)
+#define RT5625_BCLK_DIV1_3 (0x2 << 12)
+#define RT5625_BCLK_DIV1_4 (0x3 << 12)
+#define RT5625_BCLK_DIV1_5 (0x4 << 12)
+#define RT5625_BCLK_DIV1_6 (0x5 << 12)
+#define RT5625_BCLK_DIV1_7 (0x6 << 12)
+#define RT5625_BCLK_DIV1_8 (0x7 << 12)
+#define RT5625_BCLK_DIV1_9 (0x8 << 12)
+#define RT5625_BCLK_DIV1_10 (0x9 << 12)
+#define RT5625_BCLK_DIV1_11 (0xa << 12)
+#define RT5625_BCLK_DIV1_12 (0xb << 12)
+#define RT5625_BCLK_DIV1_13 (0xc << 12)
+#define RT5625_BCLK_DIV1_14 (0xd << 12)
+#define RT5625_BCLK_DIV1_15 (0xe << 12)
+#define RT5625_BCLK_DIV1_16 (0xf << 12)
+#define RT5625_BCLK_DIV2_MASK (0x7 << 8)
+#define RT5625_BCLK_DIV2_2 (0x0 << 8)
+#define RT5625_BCLK_DIV2_4 (0x1 << 8)
+#define RT5625_BCLK_DIV2_8 (0x2 << 8)
+#define RT5625_BCLK_DIV2_16 (0x3 << 8)
+#define RT5625_BCLK_DIV2_32 (0x4 << 8)
+#define RT5625_AD_LRCK_DIV1_MASK (0xf << 4)
+#define RT5625_AD_LRCK_DIV1_1 (0x0 << 4)
+#define RT5625_AD_LRCK_DIV1_2 (0x1 << 4)
+#define RT5625_AD_LRCK_DIV1_3 (0x2 << 4)
+#define RT5625_AD_LRCK_DIV1_4 (0x3 << 4)
+#define RT5625_AD_LRCK_DIV1_5 (0x4 << 4)
+#define RT5625_AD_LRCK_DIV1_6 (0x5 << 4)
+#define RT5625_AD_LRCK_DIV1_7 (0x6 << 4)
+#define RT5625_AD_LRCK_DIV1_8 (0x7 << 4)
+#define RT5625_AD_LRCK_DIV1_9 (0x8 << 4)
+#define RT5625_AD_LRCK_DIV1_10 (0x9 << 4)
+#define RT5625_AD_LRCK_DIV1_11 (0xa << 4)
+#define RT5625_AD_LRCK_DIV1_12 (0xb << 4)
+#define RT5625_AD_LRCK_DIV1_13 (0xc << 4)
+#define RT5625_AD_LRCK_DIV1_14 (0xd << 4)
+#define RT5625_AD_LRCK_DIV1_15 (0xe << 4)
+#define RT5625_AD_LRCK_DIV1_16 (0xf << 4)
+#define RT5625_AD_LRCK_DIV2_MASK (0x7 << 1)
+#define RT5625_AD_LRCK_DIV2_2 (0x0 << 1)
+#define RT5625_AD_LRCK_DIV2_4 (0x1 << 1)
+#define RT5625_AD_LRCK_DIV2_8 (0x2 << 1)
+#define RT5625_AD_LRCK_DIV2_16 (0x3 << 1)
+#define RT5625_AD_LRCK_DIV2_32 (0x4 << 1)
+#define RT5625_DA_LRCK_DIV_MASK (1)
+#define RT5625_DA_LRCK_DIV_32 (0)
+#define RT5625_DA_LRCK_DIV_64 (1)
+
+/* Stereo DAC Clock Control 2 (0x62) */
+#define RT5625_DF_DIV1_MASK (0xF << 12)
+#define RT5625_DF_DIV1_1 (0x0 << 12)
+#define RT5625_DF_DIV1_2 (0x1 << 12)
+#define RT5625_DF_DIV1_3 (0x2 << 12)
+#define RT5625_DF_DIV1_4 (0x3 << 12)
+#define RT5625_DF_DIV1_5 (0x4 << 12)
+#define RT5625_DF_DIV1_6 (0x5 << 12)
+#define RT5625_DF_DIV1_7 (0x6 << 12)
+#define RT5625_DF_DIV1_8 (0x7 << 12)
+#define RT5625_DF_DIV1_9 (0x8 << 12)
+#define RT5625_DF_DIV1_10 (0x9 << 12)
+#define RT5625_DF_DIV1_11 (0xA << 12)
+#define RT5625_DF_DIV1_12 (0xB << 12)
+#define RT5625_DF_DIV1_13 (0xC << 12)
+#define RT5625_DF_DIV1_14 (0xD << 12)
+#define RT5625_DF_DIV1_15 (0xE << 12)
+#define RT5625_DF_DIV1_16 (0xF << 12)
+#define RT5625_DF_DIV2_MASK (0x7 << 9)
+#define RT5625_DF_DIV2_2 (0x0 << 9)
+#define RT5625_DF_DIV2_4 (0x1 << 9)
+#define RT5625_DF_DIV2_8 (0x2 << 9)
+#define RT5625_DF_DIV2_16 (0x3 << 9)
+#define RT5625_DF_DIV2_32 (0x4 << 9)
+#define RT5625_AF_DIV1_MASK (0xF << 4)
+#define RT5625_AF_DIV1_1 (0x0 << 4)
+#define RT5625_AF_DIV1_2 (0x1 << 4)
+#define RT5625_AF_DIV1_3 (0x2 << 4)
+#define RT5625_AF_DIV1_4 (0x3 << 4)
+#define RT5625_AF_DIV1_5 (0x4 << 4)
+#define RT5625_AF_DIV1_6 (0x5 << 4)
+#define RT5625_AF_DIV1_7 (0x6 << 4)
+#define RT5625_AF_DIV1_8 (0x7 << 4)
+#define RT5625_AF_DIV1_9 (0x8 << 4)
+#define RT5625_AF_DIV1_10 (0x9 << 4)
+#define RT5625_AF_DIV1_11 (0xA << 4)
+#define RT5625_AF_DIV1_12 (0xB << 4)
+#define RT5625_AF_DIV1_13 (0xC << 4)
+#define RT5625_AF_DIV1_14 (0xD << 4)
+#define RT5625_AF_DIV1_15 (0xE << 4)
+#define RT5625_AF_DIV1_16 (0xF << 4)
+#define RT5625_AF_DIV2_MASK (0x7 << 1)
+#define RT5625_AF_DIV2_1 (0x0 << 1)
+#define RT5625_AF_DIV2_2 (0x1 << 1)
+#define RT5625_AF_DIV2_4 (0x2 << 1)
+#define RT5625_AF_DIV2_8 (0x3 << 1)
+#define RT5625_AF_DIV2_16 (0x4 << 1)
+#define RT5625_AF_DIV2_32 (0x5 << 1)
+
+/* Voice DAC PCM Clock Control 1 (0x64) */
+#define RT5625_VBCLK_DIV1_MASK (0xF << 12)
+#define RT5625_VBCLK_DIV1_1 (0x0 << 12)
+#define RT5625_VBCLK_DIV1_2 (0x1 << 12)
+#define RT5625_VBCLK_DIV1_3 (0x2 << 12)
+#define RT5625_VBCLK_DIV1_4 (0x3 << 12)
+#define RT5625_VBCLK_DIV1_5 (0x4 << 12)
+#define RT5625_VBCLK_DIV1_6 (0x5 << 12)
+#define RT5625_VBCLK_DIV1_7 (0x6 << 12)
+#define RT5625_VBCLK_DIV1_8 (0x7 << 12)
+#define RT5625_VBCLK_DIV1_9 (0x8 << 12)
+#define RT5625_VBCLK_DIV1_10 (0x9 << 12)
+#define RT5625_VBCLK_DIV1_11 (0xA << 12)
+#define RT5625_VBCLK_DIV1_12 (0xB << 12)
+#define RT5625_VBCLK_DIV1_13 (0xC << 12)
+#define RT5625_VBCLK_DIV1_14 (0xD << 12)
+#define RT5625_VBCLK_DIV1_15 (0xE << 12)
+#define RT5625_VBCLK_DIV1_16 (0xF << 12)
+#define RT5625_VBCLK_DIV2_MASK (0x7 << 8)
+#define RT5625_VBCLK_DIV2_2 (0x0 << 8)
+#define RT5625_VBCLK_DIV2_4 (0x1 << 8)
+#define RT5625_VBCLK_DIV2_8 (0x2 << 8)
+#define RT5625_VBCLK_DIV2_16 (0x3 << 8)
+#define RT5625_VBCLK_DIV2_32 (0x4 << 8)
+#define RT5625_AD_VLRCK_DIV1_MASK (0xF << 4)
+#define RT5625_AD_VLRCK_DIV1_1 (0x0 << 4)
+#define RT5625_AD_VLRCK_DIV1_2 (0x1 << 4)
+#define RT5625_AD_VLRCK_DIV1_3 (0x2 << 4)
+#define RT5625_AD_VLRCK_DIV1_4 (0x3 << 4)
+#define RT5625_AD_VLRCK_DIV1_5 (0x4 << 4)
+#define RT5625_AD_VLRCK_DIV1_6 (0x5 << 4)
+#define RT5625_AD_VLRCK_DIV1_7 (0x6 << 4)
+#define RT5625_AD_VLRCK_DIV1_8 (0x7 << 4)
+#define RT5625_AD_VLRCK_DIV1_9 (0x8 << 4)
+#define RT5625_AD_VLRCK_DIV1_10 (0x9 << 4)
+#define RT5625_AD_VLRCK_DIV1_11 (0xA << 4)
+#define RT5625_AD_VLRCK_DIV1_12 (0xB << 4)
+#define RT5625_AD_VLRCK_DIV1_13 (0xC << 4)
+#define RT5625_AD_VLRCK_DIV1_14 (0xD << 4)
+#define RT5625_AD_VLRCK_DIV1_15 (0xE << 4)
+#define RT5625_AD_VLRCK_DIV1_16 (0xF << 4)
+#define RT5625_AD_VLRCK_DIV2_MASK (0x7 << 1)
+#define RT5625_AD_VLRCK_DIV2_2 (0x0 << 1)
+#define RT5625_AD_VLRCK_DIV2_4 (0x1 << 1)
+#define RT5625_AD_VLRCK_DIV2_8 (0x2 << 1)
+#define RT5625_AD_VLRCK_DIV2_16 (0x3 << 1)
+#define RT5625_AD_VLRCK_DIV2_32 (0x4 << 1)
+#define RT5625_DA_VLRCK_DIV_MASK (1)
+#define RT5625_DA_VLRCK_DIV_32 (0)
+#define RT5625_DA_VLRCK_DIV_64 (1)
+
+/* Psedueo Stereo & Spatial Effect Block Control (0x68) */
+#define RT5625_SP_CTRL_EN (0x1 << 15)
+#define RT5625_APF_EN (0x1 << 14)
+#define RT5625_PS_EN (0x1 << 13)
+#define RT5625_STO_EXP_EN (0x1 << 12)
+#define RT5625_SP_3D_G1_MASK (0x3 << 10)
+#define RT5625_SP_3D_G1_1_0 (0x0 << 10)
+#define RT5625_SP_3D_G1_1_5 (0x1 << 10)
+#define RT5625_SP_3D_G1_2_0 (0x2 << 10)
+#define RT5625_SP_3D_R1_MASK (0x3 << 8)
+#define RT5625_SP_3D_R1_0_0 (0x0 << 8)
+#define RT5625_SP_3D_R1_0_66 (0x1 << 8)
+#define RT5625_SP_3D_R1_1_0 (0x2 << 8)
+#define RT5625_SP_3D_G2_MASK (0x3 << 6)
+#define RT5625_SP_3D_G2_1_0 (0x0 << 6)
+#define RT5625_SP_3D_G2_1_5 (0x1 << 6)
+#define RT5625_SP_3D_G2_2_0 (0x2 << 6)
+#define RT5625_SP_3D_R2_MASK (0x3 << 4)
+#define RT5625_SP_3D_R2_0_0 (0x0 << 4)
+#define RT5625_SP_3D_R2_0_66 (0x1 << 4)
+#define RT5625_SP_3D_R2_1_0 (0x2 << 4)
+#define RT5625_APF_MASK (0x3)
+#define RT5625_APF_48K (0x3)
+#define RT5625_APF_44_1K (0x2)
+#define RT5625_APF_32K (0x1)
+
+/* EQ Control and Status /ADC HPF Control (0x6E) */
+#define RT5625_EN_HW_EQ_BLK (0x1 << 15)
+#define RT5625_EQ_SRC_DAC (0x0 << 14)
+#define RT5625_EQ_SRC_ADC (0x1 << 14)
+#define RT5625_EQ_CHG_EN (0x1 << 7)
+#define RT5625_EN_HW_EQ_HPF (0x1 << 4)
+#define RT5625_EN_HW_EQ_BP3 (0x1 << 3)
+#define RT5625_EN_HW_EQ_BP2 (0x1 << 2)
+#define RT5625_EN_HW_EQ_BP1 (0x1 << 1)
+#define RT5625_EN_HW_EQ_LPF (0x1 << 0)
+
+/* VoDSP Register Command (0x74) */
+#define RT5625_DSP_BUSY_MASK (0x1 << 15)
+#define RT5625_DSP_DS_MASK (0x1 << 14)
+#define RT5625_DSP_DS_VODSP (0x0 << 14)
+#define RT5625_DSP_DS_REG72 (0x1 << 14)
+#define RT5625_DSP_CLK_MASK (0x3 << 12)
+#define RT5625_DSP_CLK_12_288M (0x0 << 12)
+#define RT5625_DSP_CLK_6_144M (0x1 << 12)
+#define RT5625_DSP_CLK_3_072M (0x2 << 12)
+#define RT5625_DSP_CLK_2_048M (0x3 << 12)
+#define RT5625_DSP_R_EN (0x1 << 9)
+#define RT5625_DSP_W_EN (0x1 << 8)
+#define RT5625_DSP_CMD_MASK (0xff)
+#define RT5625_DSP_CMD_SFT 0
+#define RT5625_DSP_CMD_MW (0x3B) /* Memory Write */
+#define RT5625_DSP_CMD_MR (0x37) /* Memory Read */
+#define RT5625_DSP_CMD_RR (0x60) /* Register Read */
+#define RT5625_DSP_CMD_RW (0x68) /* Register Write */
+
+
+/* Index(0x20) for Auto Volume Control */
+#define RT5625_AVC_CH_MASK (0x1 << 7)
+#define RT5625_AVC_CH_L_CH (0x0 << 7)
+#define RT5625_AVC_CH_R_CH (0x1 << 7)
+#define RT5625_AVC_GAIN_EN (0x1 << 15)
+
+
+
+enum {
+ RT5625_AIF1,
+ RT5625_AIF2,
};
-struct rt56xx_cmd
-{
- size_t number;
- struct rt56xx_reg_state __user *buf;
+/* System Clock Source */
+enum {
+ RT5625_SCLK_S_MCLK,
+ RT5625_SCLK_S_PLL,
};
-
-enum
-{
- RT_READ_CODEC_REG_IOCTL = _IOR('R', 0x01, struct rt56xx_cmd),
- RT_READ_ALL_CODEC_REG_IOCTL = _IOR('R', 0x02, struct rt56xx_cmd),
- RT_WRITE_CODEC_REG_IOCTL = _IOW('R', 0x03, struct rt56xx_cmd),
-};
-
-#endif
-
-
-enum pll_sel
-{
- RT5625_PLL1_FROM_MCLK = 0,
- RT5625_PLL1_FROM_BCLK,
- RT5625_PLL1_FROM_VBCLK,
+enum pll_sel {
+ RT5625_PLL_MCLK = 0,
+ RT5625_PLL_MCLK_TO_VSYSCLK,
+ RT5625_PLL_BCLK,
+ RT5625_PLL_VBCLK,
};
-enum AEC_MODE
-{
- PCM_IN_PCM_OUT = 0,
- ANALOG_IN_ANALOG_OUT,
- DAC_IN_ADC_OUT,
- VODSP_AEC_DISABLE
+enum {
+ RT5625_AEC_DIS,
+ RT5625_AEC_EN,
};
-enum
-{
- PCM_MASTER_MODE_A=0,
- PCM_MASTER_MODE_B,
- PCM_SLAVE_MODE_A,
- PCM_SLAVE_MODE_B,
+//#ifdef RT5625_F_SMT_PHO
+enum {
+ RT5625_PLL_DIS,
+ RT5625_PLL_112896_225792,
+ RT5625_PLL_112896_24576,
};
+//#endif
-
-enum RT5625_FUNC_SEL
-{
- RT5625_AEC_DISABLE =0,
- RT5625_AEC_PCM_IN_OUT,
- RT5625_AEC_IIS_IN_OUT,
- RT5625_AEC_ANALOG_IN_OUT,
-
-};
-
-
-struct rt5625_setup_data {
- int i2c_bus;
- int i2c_address;
-};
-
-typedef struct
-{
- unsigned short int VoiceDSPIndex;
- unsigned short int VoiceDSPValue;
-
-}Voice_DSP_Reg;
-
-extern struct snd_soc_dai rt5625_dai[];
-extern struct snd_soc_codec_device soc_codec_dev_rt5625;
+typedef struct {
+ unsigned short index;
+ unsigned short value;
+} rt5625_dsp_reg;
#endif