From b1c92931e19ebaf06bcc844d9526597a88d10567 Mon Sep 17 00:00:00 2001 From: yj Date: Fri, 2 Aug 2013 14:33:14 +0800 Subject: [PATCH] codec: 3028a & 3026, change str 3028 to 3026 --- arch/arm/configs/rk3026_tb_defconfig | 2 +- arch/arm/configs/rk3028a_tb_defconfig | 2 +- arch/arm/mach-rk3026/board-rk3026-tb.c | 18 +- arch/arm/mach-rk3026/board-rk3028a-tb.c | 18 +- sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/rk3028_codec.c | 2174 ----------------------- sound/soc/codecs/rk3028_codec.h | 547 ------ sound/soc/rk29/Kconfig | 6 +- sound/soc/rk29/Makefile | 4 +- sound/soc/rk29/rk_rk3028.c | 308 ---- 11 files changed, 28 insertions(+), 3057 deletions(-) delete mode 100644 sound/soc/codecs/rk3028_codec.c delete mode 100644 sound/soc/codecs/rk3028_codec.h delete mode 100644 sound/soc/rk29/rk_rk3028.c diff --git a/arch/arm/configs/rk3026_tb_defconfig b/arch/arm/configs/rk3026_tb_defconfig index 1d10f3c628b2..da7ef4e6f194 100644 --- a/arch/arm/configs/rk3026_tb_defconfig +++ b/arch/arm/configs/rk3026_tb_defconfig @@ -327,7 +327,7 @@ CONFIG_SND_RK29_SOC=y CONFIG_SND_I2SO_USE_DOUBLE_CHANNELS=y CONFIG_SND_I2S_DMA_EVENT_STATIC=y CONFIG_SND_RK_SOC_HDMI_I2S=y -CONFIG_SND_RK_SOC_RK3028=y +CONFIG_SND_RK_SOC_RK3026=y CONFIG_SND_RK29_CODEC_SOC_SLAVE=y CONFIG_UHID=y CONFIG_HID_A4TECH=y diff --git a/arch/arm/configs/rk3028a_tb_defconfig b/arch/arm/configs/rk3028a_tb_defconfig index 46f93fb8c85e..b1a437bafa72 100644 --- a/arch/arm/configs/rk3028a_tb_defconfig +++ b/arch/arm/configs/rk3028a_tb_defconfig @@ -328,7 +328,7 @@ CONFIG_SND_RK29_SOC=y CONFIG_SND_I2SO_USE_DOUBLE_CHANNELS=y CONFIG_SND_I2S_DMA_EVENT_STATIC=y CONFIG_SND_RK_SOC_HDMI_I2S=y -CONFIG_SND_RK_SOC_RK3028=y +CONFIG_SND_RK_SOC_RK3026=y CONFIG_SND_RK29_CODEC_SOC_SLAVE=y CONFIG_UHID=y CONFIG_HID_A4TECH=y diff --git a/arch/arm/mach-rk3026/board-rk3026-tb.c b/arch/arm/mach-rk3026/board-rk3026-tb.c index 857892beaf1b..4c698a9f3145 100755 --- a/arch/arm/mach-rk3026/board-rk3026-tb.c +++ b/arch/arm/mach-rk3026/board-rk3026-tb.c @@ -51,8 +51,8 @@ #include "../../../drivers/spi/rk29_spim.h" #endif -#ifdef CONFIG_SND_SOC_RK3028 -#include "../../../sound/soc/codecs/rk3028_codec.h" +#ifdef CONFIG_SND_SOC_RK3026 +#include "../../../sound/soc/codecs/rk3026_codec.h" #endif #if defined(CONFIG_RK_HDMI) @@ -936,8 +936,8 @@ void __sramfunc board_pmu_resume(void) #endif } -#ifdef CONFIG_SND_SOC_RK3028 -struct rk3028_codec_pdata rk3028_codec_pdata_info={ +#ifdef CONFIG_SND_SOC_RK3026 +struct rk3026_codec_pdata rk3026_codec_pdata_info={ .spk_ctl_gpio = INVALID_GPIO, .hp_ctl_gpio = RK2928_PIN1_PA0, }; @@ -950,12 +950,12 @@ static struct resource resources_acodec[] = { }, }; -static struct platform_device rk3028_codec = { - .name = "rk3028-codec", +static struct platform_device rk3026_codec = { + .name = "rk3026-codec", .id = -1, .resource = resources_acodec, .dev = { - .platform_data = &rk3028_codec_pdata_info, + .platform_data = &rk3026_codec_pdata_info, } }; #endif @@ -1059,8 +1059,8 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_WIFI_CONTROL_FUNC &rk29sdk_wifi_device, #endif -#ifdef CONFIG_SND_SOC_RK3028 - &rk3028_codec, +#ifdef CONFIG_SND_SOC_RK3026 + &rk3026_codec, #endif }; diff --git a/arch/arm/mach-rk3026/board-rk3028a-tb.c b/arch/arm/mach-rk3026/board-rk3028a-tb.c index 1cdbb622ab1e..1af1cc13c9d1 100755 --- a/arch/arm/mach-rk3026/board-rk3028a-tb.c +++ b/arch/arm/mach-rk3026/board-rk3028a-tb.c @@ -51,8 +51,8 @@ #include "../../../drivers/spi/rk29_spim.h" #endif -#ifdef CONFIG_SND_SOC_RK3028 -#include "../../../sound/soc/codecs/rk3028_codec.h" +#ifdef CONFIG_SND_SOC_RK3026 +#include "../../../sound/soc/codecs/rk3026_codec.h" #endif #if defined(CONFIG_RK_HDMI) @@ -794,8 +794,8 @@ static struct platform_device device_ion = { }; #endif -#ifdef CONFIG_SND_SOC_RK3028 -struct rk3028_codec_pdata rk3028_codec_pdata_info={ +#ifdef CONFIG_SND_SOC_RK3026 +struct rk3026_codec_pdata rk3026_codec_pdata_info={ .spk_ctl_gpio = INVALID_GPIO, .hp_ctl_gpio = RK2928_PIN3_PD4, }; @@ -808,12 +808,12 @@ static struct resource resources_acodec[] = { }, }; -static struct platform_device rk3028_codec = { - .name = "rk3028-codec", +static struct platform_device rk3026_codec = { + .name = "rk3026-codec", .id = -1, .resource = resources_acodec, .dev = { - .platform_data = &rk3028_codec_pdata_info, + .platform_data = &rk3026_codec_pdata_info, } }; #endif @@ -1127,8 +1127,8 @@ static struct platform_device *devices[] __initdata = { #ifdef CONFIG_RFKILL_RK &device_rfkill_rk, #endif -#ifdef CONFIG_SND_SOC_RK3028 - &rk3028_codec, +#ifdef CONFIG_SND_SOC_RK3026 + &rk3026_codec, #endif }; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 34469b9e1494..fc59e4e4dabe 100755 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -467,6 +467,6 @@ config SND_SOC_RK2928 tristate depends on ARCH_RK2928 -config SND_SOC_RK3028 +config SND_SOC_RK3026 tristate depends on ARCH_RK3026 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 40c605a36a57..964bd7baf7f5 100755 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -100,7 +100,7 @@ snd-soc-rt5640-objs := rt5640.o rt5640-dsp.o rt5640_ioctl.o rt56xx_ioctl.o snd-soc-rt3261-objs := rt3261.o rt3261-dsp.o rt3261_ioctl.o rt_codec_ioctl.o snd-soc-rt3224-objs := rt3261.o rt3261_ioctl.o rt_codec_ioctl.o snd-soc-rk2928-objs := rk2928_codec.o -snd-soc-rk3028-objs := rk3028_codec.o +snd-soc-rk3026-objs := rk3026_codec.o snd-soc-rt5639-objs := rt5639.o rt5639_ioctl.o rt56xx_ioctl.o # Amp @@ -212,7 +212,7 @@ obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o obj-$(CONFIG_SND_SOC_RK610) += snd-soc-rk610.o obj-$(CONFIG_SND_SOC_RK616) += snd-soc-rk616.o obj-$(CONFIG_SND_SOC_RK2928) += snd-soc-rk2928.o -obj-$(CONFIG_SND_SOC_RK3028) += snd-soc-rk3028.o +obj-$(CONFIG_SND_SOC_RK3026) += snd-soc-rk3026.o # Amp obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o diff --git a/sound/soc/codecs/rk3028_codec.c b/sound/soc/codecs/rk3028_codec.c deleted file mode 100644 index be8ecf7bc3e6..000000000000 --- a/sound/soc/codecs/rk3028_codec.c +++ /dev/null @@ -1,2174 +0,0 @@ -/* - * rk3028.c -- RK3028 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: chenjq - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "rk3028_codec.h" - - -#ifdef CONFIG_RK_HEADSET_DET -#include "../../../drivers/headset_observe/rk_headset.h" -#endif - -#if 0 -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* volume setting - * 0: -39dB - * 26: 0dB - * 31: 6dB - * Step: 1.5dB -*/ -#define OUT_VOLUME 26//0~31 - - -struct rk3028_codec_priv { - struct snd_soc_codec *codec; - - unsigned int stereo_sysclk; - unsigned int rate; - - int playback_active; - int capture_active; - - int spk_ctl_gpio; - int hp_ctl_gpio; - - long int playback_path; - long int capture_path; - long int voice_call_path; - - int regbase; - int regbase_phy; - int regsize_phy; - struct clk *pclk; -}; - -static struct rk3028_codec_priv *rk3028_priv = NULL; - -#define RK3028_CODEC_ALL 0 -#define RK3028_CODEC_PLAYBACK 1 -#define RK3028_CODEC_CAPTURE 2 - -#define RK3028_CODEC_WORK_NULL 0 -#define RK3028_CODEC_WORK_POWER_DOWN 1 -#define RK3028_CODEC_WORK_POWER_UP 2 - -static struct workqueue_struct *rk3028_codec_workq; - -static void rk3028_codec_capture_work(struct work_struct *work); -static DECLARE_DELAYED_WORK(capture_delayed_work, rk3028_codec_capture_work); -static int rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; -static bool rk3028_for_mid = 1, is_hdmi_in = false; - -static int rk3028_get_parameter(void) -{ - int val; - char *command_line = strstr(saved_command_line, "ap_has_alsa="); - - if (command_line == NULL) { - printk("%s : Can not get ap_has_alsa from kernel command line!\n", __func__); - return 0; - } - - command_line += 12; - - val = simple_strtol(command_line, NULL, 10); - if (val == 0 || val == 1) { - rk3028_for_mid = (val ? 0 : 1); - printk("%s : THIS IS FOR %s\n", __func__, rk3028_for_mid ? "mid" : "phone"); - } else { - printk("%s : get ap_has_alsa error, val = %d\n", __func__, val); - } - - return 0; -} - -static const unsigned int rk3028_reg_defaults[RK3028_PGAR_AGC_CTL5+1] = { - [RK3028_RESET] = 0x0003, - [RK3028_ADC_INT_CTL1] = 0x0050, - [RK3028_ADC_INT_CTL2] = 0x000e, - [RK3028_DAC_INT_CTL1] = 0x0050, - [RK3028_DAC_INT_CTL2] = 0x000e, - [RK3028_ADC_MIC_CTL] = 0x0000, - [RK3028_BST_CTL] = 0x000, - [RK3028_ALC_MUNIN_CTL] = 0x0044, - [RK3028_BSTL_ALCL_CTL] = 0x000c, - [RK3028_ALCR_GAIN_CTL] = 0x000C, - [RK3028_ADC_ENABLE] = 0x0000, - [RK3028_DAC_CTL] = 0x0000, - [RK3028_DAC_ENABLE] = 0x0000, - [RK3028_HPMIX_CTL] = 0x0000, - [RK3028_HPMIX_S_SELECT] = 0x0000, - [RK3028_HPOUT_CTL] = 0x0000, - [RK3028_HPOUTL_GAIN] = 0x0000, - [RK3028_HPOUTR_GAIN] = 0x0000, - [RK3028_SELECT_CURRENT] = 0x001e, - [RK3028_PGAL_AGC_CTL1] = 0x0000, - [RK3028_PGAL_AGC_CTL2] = 0x0046, - [RK3028_PGAL_AGC_CTL3] = 0x0041, - [RK3028_PGAL_AGC_CTL4] = 0x002c, - [RK3028_PGAL_ASR_CTL] = 0x0000, - [RK3028_PGAL_AGC_MAX_H] = 0x0026, - [RK3028_PGAL_AGC_MAX_L] = 0x0040, - [RK3028_PGAL_AGC_MIN_H] = 0x0036, - [RK3028_PGAL_AGC_MIN_L] = 0x0020, - [RK3028_PGAL_AGC_CTL5] = 0x0038, - [RK3028_PGAR_AGC_CTL1] = 0x0000, - [RK3028_PGAR_AGC_CTL2] = 0x0046, - [RK3028_PGAR_AGC_CTL3] = 0x0041, - [RK3028_PGAR_AGC_CTL4] = 0x002c, - [RK3028_PGAR_ASR_CTL] = 0x0000, - [RK3028_PGAR_AGC_MAX_H] = 0x0026, - [RK3028_PGAR_AGC_MAX_L] = 0x0040, - [RK3028_PGAR_AGC_MIN_H] = 0x0036, - [RK3028_PGAR_AGC_MIN_L] = 0x0020, - [RK3028_PGAR_AGC_CTL5] = 0x0038, -}; - -static struct rk3028_init_bit_typ rk3028_init_bit_list[] = { - {RK3028_HPOUT_CTL, RK3028_HPOUTL_EN, RK3028_HPOUTL_WORK}, - {RK3028_HPOUT_CTL, RK3028_HPOUTR_EN, RK3028_HPOUTR_WORK}, - {RK3028_HPMIX_CTL, RK3028_HPMIXR_EN, RK3028_HPMIXR_WORK2}, - {RK3028_HPMIX_CTL, RK3028_HPMIXL_EN, RK3028_HPMIXR_WORK2}, - -}; -#define RK3028_INIT_BIT_LIST_LEN ARRAY_SIZE(rk3028_init_bit_list) - -static int rk3028_init_bit_register(unsigned int reg, int i) -{ - for (; i < RK3028_INIT_BIT_LIST_LEN; i++) { - if (rk3028_init_bit_list[i].reg == reg) - return i; - } - - return -1; -} - -static unsigned int rk3028_codec_read(struct snd_soc_codec *codec, unsigned int reg); - -static unsigned int rk3028_set_init_value(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - unsigned int read_value, power_bit, set_bit; - int i; - - // read codec init register - i = rk3028_init_bit_register(reg, 0); - - // set codec init bit - // widget init bit should be setted 0 after widget power up or unmute, - // and should be setted 1 after widget power down or mute. - if (i >= 0) { - read_value = rk3028_codec_read(codec, reg); - while (i >= 0) { - power_bit = rk3028_init_bit_list[i].power_bit; - set_bit = rk3028_init_bit_list[i].init_bit; - - if ((read_value & power_bit) != (value & power_bit)) - { - if (value & power_bit) - { - writel_relaxed(value, rk3028_priv->regbase+reg); - writel_relaxed((value & set_bit), rk3028_priv->regbase+reg); - } - else - { - writel_relaxed((value & ~set_bit), rk3028_priv->regbase+reg); - writel_relaxed(value, rk3028_priv->regbase+reg); - - } - } - - i = rk3028_init_bit_register(reg, ++i); - } - } - - return i; -} - -static int rk3028_volatile_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3028_RESET: - return 1; - default: - return 0; - } -} - -static int rk3028_codec_register(struct snd_soc_codec *codec, unsigned int reg) -{ - switch (reg) { - case RK3028_RESET: - case RK3028_ADC_INT_CTL1: - case RK3028_ADC_INT_CTL2: - case RK3028_DAC_INT_CTL1: - case RK3028_DAC_INT_CTL2: - case RK3028_ADC_MIC_CTL: - case RK3028_BST_CTL: - case RK3028_ALC_MUNIN_CTL: - case RK3028_BSTL_ALCL_CTL: - case RK3028_ALCR_GAIN_CTL: - case RK3028_ADC_ENABLE: - case RK3028_DAC_CTL: - case RK3028_DAC_ENABLE: - case RK3028_HPMIX_CTL: - case RK3028_HPMIX_S_SELECT: - case RK3028_HPOUT_CTL: - case RK3028_HPOUTL_GAIN: - case RK3028_HPOUTR_GAIN: - case RK3028_SELECT_CURRENT: - case RK3028_PGAL_AGC_CTL1: - case RK3028_PGAL_AGC_CTL2: - case RK3028_PGAL_AGC_CTL3: - case RK3028_PGAL_AGC_CTL4: - case RK3028_PGAL_ASR_CTL: - case RK3028_PGAL_AGC_MAX_H: - case RK3028_PGAL_AGC_MAX_L: - case RK3028_PGAL_AGC_MIN_H: - case RK3028_PGAL_AGC_MIN_L: - case RK3028_PGAL_AGC_CTL5: - case RK3028_PGAR_AGC_CTL1: - case RK3028_PGAR_AGC_CTL2: - case RK3028_PGAR_AGC_CTL3: - case RK3028_PGAR_AGC_CTL4: - case RK3028_PGAR_ASR_CTL: - case RK3028_PGAR_AGC_MAX_H: - case RK3028_PGAR_AGC_MAX_L: - case RK3028_PGAR_AGC_MIN_H: - case RK3028_PGAR_AGC_MIN_L: - case RK3028_PGAR_AGC_CTL5: - return 1; - default: - return 0; - } -} - -static inline unsigned int rk3028_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3028_codec_register(codec, reg) ) - return cache[reg]; - - printk("%s : reg error!\n", __func__); - - return -EINVAL; -} - -static inline void rk3028_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - unsigned int *cache = codec->reg_cache; - - if (rk3028_codec_register(codec, reg)) { - cache[reg] = value; - return; - } - - printk("%s : reg error!\n", __func__); -} - -static unsigned int rk3028_codec_read(struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int value; - - if (!rk3028_priv) { - printk("%s : rk3028 is NULL\n", __func__); - return -EINVAL; - } - - if (!rk3028_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } -#if 0 - if (rk3028_volatile_register(codec, reg) == 0) { - value = rk3028_read_reg_cache(codec, reg); - } else { - value = readl_relaxed(rk3028_priv->regbase+reg); - } -#endif - value = readl_relaxed(rk3028_priv->regbase+reg); - DBG("%s : reg = 0x%x, val= 0x%x\n", __func__, reg, value); - - return value; -} - -static int rk3028_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -{ - int new_value; - - if (!rk3028_priv) { - printk("%s : rk3028 is NULL\n", __func__); - return -EINVAL; - } else if (!rk3028_codec_register(codec, reg)) { - printk("%s : reg error!\n", __func__); - return -EINVAL; - } - - new_value = rk3028_set_init_value(codec, reg, value); - - if (new_value == -1) - writel_relaxed(value, rk3028_priv->regbase+reg); - - rk3028_write_reg_cache(codec, reg, value); - - DBG("%s : reg = 0x%x, val = 0x%x, new_value=%d\n", __func__, reg, value,new_value); - return 0; -} - -static int rk3028_hw_write(const struct i2c_client *client, const char *buf, int count) -{ - unsigned int reg, value; - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (count == 3) { - reg = (unsigned int)buf[0]; - value = (buf[1] & 0xff00) | (0x00ff & buf[2]); - writel_relaxed(value, rk3028_priv->regbase+reg); - } else { - printk("%s : i2c len error\n", __func__); - } - - return count; -} - -static int rk3028_reset(struct snd_soc_codec *codec) -{ - writel_relaxed(0xfc, rk3028_priv->regbase+RK3028_RESET); - mdelay(10); - writel_relaxed(0x43, rk3028_priv->regbase+RK3028_RESET); - mdelay(10); - - memcpy(codec->reg_cache, rk3028_reg_defaults, - sizeof(rk3028_reg_defaults)); - - return 0; -} - -int rk3028_headset_mic_detect(bool headset_status) -{ -#if 0 - struct snd_soc_codec *codec = rk3028_priv->codec; - - DBG("%s\n", __func__); - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - if (headset_status) { - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_MICBIAS2_PWRD | RK3028_MICBIAS2_V_MASK, - RK3028_MICBIAS2_V_1_7); - } else {// headset is out, disable MIC2 && MIC1 Bias - DBG("%s : headset is out,disable Mic2 Bias\n", __func__); - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_MICBIAS2_PWRD | RK3028_MICBIAS2_V_MASK, - RK3028_MICBIAS2_V_1_0|RK3028_MICBIAS2_PWRD); - } -#endif - return 0; -} -EXPORT_SYMBOL(rk3028_headset_mic_detect); - -bool get_hdmi_state(void) -{ - return is_hdmi_in; -} - -#ifdef CONFIG_MACH_RK_FAC -void rk3028_codec_set_spk(bool on) -{ - struct snd_soc_codec *codec = rk3028_priv->codec; - - DBG("%s : %s\n", __func__, on ? "enable spk" : "disable spk"); - - if(rk3028_hdmi_ctrl) - { - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return; - } - - if (on) { - if (rk3028_for_mid) - { - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_MSK, RK3028_HPOUTL_MUTE_DIS); - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTR_MUTE_MSK, RK3028_HPOUTR_MUTE_DIS); - } - else - { - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - } - } else { - if (rk3028_priv->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3028_priv->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3028_priv->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_LOW); - } - - if (rk3028_for_mid) - { - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_MSK, RK3028_HPOUTL_MUTE_EN); - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTR_MUTE_MSK, RK3028_HPOUTR_MUTE_EN); - } - else - { - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - } - } - snd_soc_dapm_sync(&codec->dapm); - - is_hdmi_in = on ? 0 : 1; - } -} -EXPORT_SYMBOL_GPL(rk3028_codec_set_spk); -#else -void codec_set_spk(bool on) -{ - struct snd_soc_codec *codec = rk3028_priv->codec; - - DBG("%s : %s\n", __func__, on ? "enable spk" : "disable spk"); - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return; - } - - if (on) { - if (rk3028_for_mid) - { - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_MSK, 1); - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTR_MUTE_MSK, RK3028_HPOUTR_MUTE_DIS); - } - else - { - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - } - } else { - if (rk3028_priv->spk_ctl_gpio != INVALID_GPIO) { - DBG("%s : set spk ctl gpio LOW\n", __func__); - gpio_set_value(rk3028_priv->spk_ctl_gpio, GPIO_LOW); - } - - if (rk3028_priv->hp_ctl_gpio != INVALID_GPIO) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_LOW); - } - - if (rk3028_for_mid) - { - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_MSK, RK3028_HPOUTL_MUTE_EN); - snd_soc_update_bits(codec, RK3028_HPOUT_CTL, - RK3028_HPOUTR_MUTE_MSK, RK3028_HPOUTR_MUTE_EN); - } - else - { - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - } - } - snd_soc_dapm_sync(&codec->dapm); - - is_hdmi_in = on ? 0 : 1; -} -EXPORT_SYMBOL_GPL(codec_set_spk); -#endif - -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -3900, 150, 0); -static const DECLARE_TLV_DB_SCALE(pga_vol_tlv, -1800, 150, 0); -static const DECLARE_TLV_DB_SCALE(bst_vol_tlv, 0, 2000, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_max_vol_tlv, -1350, 600, 0); -static const DECLARE_TLV_DB_SCALE(pga_agc_min_vol_tlv, -1800, 600, 0); - -static const char *rk3028_input_mode[] = {"Single-Ended","Differential"}; - -static const char *rk3028_micbias_ratio[] = {"1.0 Vref", "1.1 Vref", - "1.2 Vref", "1.3 Vref", "1.4 Vref", "1.5 Vref", "1.6 Vref", "1.7 Vref",}; - -static const char *rk3028_dis_en_sel[] = {"Disable", "Enable"}; - -static const char *rk3028_pga_agc_way[] = {"Normal", "Jack"}; - -static const char *rk3028_agc_backup_way[] = {"Normal", "Jack1", "Jack2", "Jack3"}; - -static const char *rk3028_pga_agc_hold_time[] = {"0ms", "2ms", - "4ms", "8ms", "16ms", "32ms", "64ms", "128ms", "256ms", "512ms", "1s"}; - -static const char *rk3028_pga_agc_ramp_up_time[] = {"Normal:500us Jack:125us", - "Normal:1ms Jack:250us", "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", - "Normal:8ms Jack:2ms", "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", - "Normal:64ms Jack:16ms", "Normal:128ms Jack:32ms", "Normal:256ms Jack:64ms", - "Normal:512ms Jack:128ms"}; - -static const char *rk3028_pga_agc_ramp_down_time[] = {"Normal:125us Jack:32us", - "Normal:250us Jack:64us", "Normal:500us Jack:125us", "Normal:1ms Jack:250us", - "Normal:2ms Jack:500us", "Normal:4ms Jack:1ms", "Normal:8ms Jack:2ms", - "Normal:16ms Jack:4ms", "Normal:32ms Jack:8ms", "Normal:64ms Jack:16ms", - "Normal:128ms Jack:32ms"}; - -static const char *rk3028_pga_agc_mode[] = {"Normal", "Limiter"}; - -static const char *rk3028_pga_agc_recovery_mode[] = {"Right Now", "After AGC to Limiter"}; - -static const char *rk3028_pga_agc_noise_gate_threhold[] = {"-39dB", "-45dB", "-51dB", - "-57dB", "-63dB", "-69dB", "-75dB", "-81dB"}; - -static const char *rk3028_pga_agc_update_gain[] = {"Right Now", "After 1st Zero Cross"}; - -static const char *rk3028_pga_agc_approximate_sample_rate[] = {"96KHZ","48KHz","441KHZ", "32KHz", - "24KHz", "16KHz", "12KHz", "8KHz"}; - -static const struct soc_enum rk3028_bst_enum[] = { -SOC_ENUM_SINGLE(RK3028_BSTL_ALCL_CTL, RK3028_BSTL_MODE_SFT, 2, rk3028_input_mode), -}; - - -static const struct soc_enum rk3028_micbias_enum[] = { -SOC_ENUM_SINGLE(RK3028_ADC_MIC_CTL, RK3028_MICBIAS_VOL_SHT, 8, rk3028_micbias_ratio), -}; - -static const struct soc_enum rk3028_agcl_enum[] = { -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL1, RK3028_PGA_AGC_BK_WAY_SFT, 4, rk3028_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL1, RK3028_PGA_AGC_WAY_SFT, 2, rk3028_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL1, RK3028_PGA_AGC_HOLD_T_SFT, 11, rk3028_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL2, RK3028_PGA_AGC_GRU_T_SFT, 11, rk3028_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL2, RK3028_PGA_AGC_GRD_T_SFT, 11, rk3028_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_MODE_SFT, 2, rk3028_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_ZO_SFT, 2, rk3028_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_REC_MODE_SFT, 2, rk3028_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_FAST_D_SFT, 2, rk3028_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_NG_SFT, 2, rk3028_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL3, RK3028_PGA_AGC_NG_THR_SFT, 8, rk3028_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL4, RK3028_PGA_AGC_ZO_MODE_SFT, 2, rk3028_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3028_PGAL_ASR_CTL, RK3028_PGA_SLOW_CLK_SFT, 2, rk3028_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3028_PGAL_ASR_CTL, RK3028_PGA_ASR_SFT, 8, rk3028_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3028_PGAL_AGC_CTL5, RK3028_PGA_AGC_SFT, 2, rk3028_dis_en_sel),/*14*/ -}; - -static const struct soc_enum rk3028_agcr_enum[] = { -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL1, RK3028_PGA_AGC_BK_WAY_SFT, 4, rk3028_agc_backup_way),/*0*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL1, RK3028_PGA_AGC_WAY_SFT, 2, rk3028_pga_agc_way),/*1*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL1, RK3028_PGA_AGC_HOLD_T_SFT, 11, rk3028_pga_agc_hold_time),/*2*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL2, RK3028_PGA_AGC_GRU_T_SFT, 11, rk3028_pga_agc_ramp_up_time),/*3*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL2, RK3028_PGA_AGC_GRD_T_SFT, 11, rk3028_pga_agc_ramp_down_time),/*4*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_MODE_SFT, 2, rk3028_pga_agc_mode),/*5*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_ZO_SFT, 2, rk3028_dis_en_sel),/*6*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_REC_MODE_SFT, 2, rk3028_pga_agc_recovery_mode),/*7*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_FAST_D_SFT, 2, rk3028_dis_en_sel),/*8*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_NG_SFT, 2, rk3028_dis_en_sel),/*9*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL3, RK3028_PGA_AGC_NG_THR_SFT, 8, rk3028_pga_agc_noise_gate_threhold),/*10*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL4, RK3028_PGA_AGC_ZO_MODE_SFT, 2, rk3028_pga_agc_update_gain),/*11*/ -SOC_ENUM_SINGLE(RK3028_PGAR_ASR_CTL, RK3028_PGA_SLOW_CLK_SFT, 2, rk3028_dis_en_sel),/*12*/ -SOC_ENUM_SINGLE(RK3028_PGAR_ASR_CTL, RK3028_PGA_ASR_SFT, 8, rk3028_pga_agc_approximate_sample_rate),/*13*/ -SOC_ENUM_SINGLE(RK3028_PGAR_AGC_CTL5, RK3028_PGA_AGC_SFT, 2, rk3028_dis_en_sel),/*14*/ -}; - -static const struct snd_kcontrol_new rk3028_snd_controls[] = { - //Add for set voice volume - SOC_DOUBLE_R_TLV("Speaker Playback Volume", RK3028_HPOUTL_GAIN, - RK3028_HPOUTR_GAIN, RK3028_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Speaker Playback Switch", RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_SHT, RK3028_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Headphone Playback Volume", RK3028_HPOUTL_GAIN, - RK3028_HPOUTR_GAIN, RK3028_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Headphone Playback Switch", RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_SHT, RK3028_HPOUTR_MUTE_SHT, 1, 0), - SOC_DOUBLE_R_TLV("Earpiece Playback Volume", RK3028_HPOUTL_GAIN, - RK3028_HPOUTR_GAIN, RK3028_HPOUT_GAIN_SFT, 31, 0, out_vol_tlv), - SOC_DOUBLE("Earpiece Playback Switch", RK3028_HPOUT_CTL, - RK3028_HPOUTL_MUTE_SHT, RK3028_HPOUTR_MUTE_SHT, 1, 0), - - - //Add for set capture mute - SOC_SINGLE_TLV("Main Mic Capture Volume", RK3028_BST_CTL, - RK3028_BSTL_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Main Mic Capture Switch", RK3028_BST_CTL, - RK3028_BSTL_MUTE_SHT, 1, 0), - SOC_SINGLE_TLV("Headset Mic Capture Volume", RK3028_BST_CTL, - RK3028_BSTR_GAIN_SHT, 1, 0, bst_vol_tlv), - SOC_SINGLE("Headset Mic Capture Switch", RK3028_BST_CTL, - RK3028_BSTR_MUTE_SHT, 1, 0), - - SOC_ENUM("BST_L Mode", rk3028_bst_enum[0]), - - SOC_ENUM("Micbias Voltage", rk3028_micbias_enum[0]), - SOC_ENUM("PGAL AGC Back Way", rk3028_agcl_enum[0]), - SOC_ENUM("PGAL AGC Way", rk3028_agcl_enum[1]), - SOC_ENUM("PGAL AGC Hold Time", rk3028_agcl_enum[2]), - SOC_ENUM("PGAL AGC Ramp Up Time", rk3028_agcl_enum[3]), - SOC_ENUM("PGAL AGC Ramp Down Time", rk3028_agcl_enum[4]), - SOC_ENUM("PGAL AGC Mode", rk3028_agcl_enum[5]), - SOC_ENUM("PGAL AGC Gain Update Zero Enable", rk3028_agcl_enum[6]), - SOC_ENUM("PGAL AGC Gain Recovery LPGA VOL", rk3028_agcl_enum[7]), - SOC_ENUM("PGAL AGC Fast Decrement Enable", rk3028_agcl_enum[8]), - SOC_ENUM("PGAL AGC Noise Gate Enable", rk3028_agcl_enum[9]), - SOC_ENUM("PGAL AGC Noise Gate Threhold", rk3028_agcl_enum[10]), - SOC_ENUM("PGAL AGC Upate Gain", rk3028_agcl_enum[11]), - SOC_ENUM("PGAL AGC Slow Clock Enable", rk3028_agcl_enum[12]), - SOC_ENUM("PGAL AGC Approximate Sample Rate", rk3028_agcl_enum[13]), - SOC_ENUM("PGAL AGC Enable", rk3028_agcl_enum[14]), - - SOC_SINGLE_TLV("PGAL AGC Volume", RK3028_PGAL_AGC_CTL4, - RK3028_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 5 is 1 - - SOC_SINGLE("PGAL AGC Max Level High 8 Bits", RK3028_PGAL_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Max Level Low 8 Bits", RK3028_PGAL_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level High 8 Bits", RK3028_PGAL_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAL AGC Min Level Low 8 Bits", RK3028_PGAL_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAL AGC Max Gain", RK3028_PGAL_AGC_CTL5, - RK3028_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - SOC_SINGLE_TLV("PGAL AGC Min Gain", RK3028_PGAL_AGC_CTL5, - RK3028_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x0a bit 5 is 1 - - SOC_ENUM("PGAR AGC Back Way", rk3028_agcr_enum[0]), - SOC_ENUM("PGAR AGC Way", rk3028_agcr_enum[1]), - SOC_ENUM("PGAR AGC Hold Time", rk3028_agcr_enum[2]), - SOC_ENUM("PGAR AGC Ramp Up Time", rk3028_agcr_enum[3]), - SOC_ENUM("PGAR AGC Ramp Down Time", rk3028_agcr_enum[4]), - SOC_ENUM("PGAR AGC Mode", rk3028_agcr_enum[5]), - SOC_ENUM("PGAR AGC Gain Update Zero Enable", rk3028_agcr_enum[6]), - SOC_ENUM("PGAR AGC Gain Recovery LPGA VOL", rk3028_agcr_enum[7]), - SOC_ENUM("PGAR AGC Fast Decrement Enable", rk3028_agcr_enum[8]), - SOC_ENUM("PGAR AGC Noise Gate Enable", rk3028_agcr_enum[9]), - SOC_ENUM("PGAR AGC Noise Gate Threhold", rk3028_agcr_enum[10]), - SOC_ENUM("PGAR AGC Upate Gain", rk3028_agcr_enum[11]), - SOC_ENUM("PGAR AGC Slow Clock Enable", rk3028_agcr_enum[12]), - SOC_ENUM("PGAR AGC Approximate Sample Rate", rk3028_agcr_enum[13]), - SOC_ENUM("PGAR AGC Enable", rk3028_agcr_enum[14]), - - SOC_SINGLE_TLV("PGAR AGC Volume", RK3028_PGAR_AGC_CTL4, - RK3028_PGA_AGC_VOL_SFT, 31, 0, pga_vol_tlv),//AGC disable and 0x0a bit 4 is 1 - - SOC_SINGLE("PGAR AGC Max Level High 8 Bits", RK3028_PGAR_AGC_MAX_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Max Level Low 8 Bits", RK3028_PGAR_AGC_MAX_L, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level High 8 Bits", RK3028_PGAR_AGC_MIN_H, - 0, 255, 0), - SOC_SINGLE("PGAR AGC Min Level Low 8 Bits", RK3028_PGAR_AGC_MIN_L, - 0, 255, 0), - - SOC_SINGLE_TLV("PGAR AGC Max Gain", RK3028_PGAR_AGC_CTL5, - RK3028_PGA_AGC_MAX_G_SFT, 7, 0, pga_agc_max_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - SOC_SINGLE_TLV("PGAR AGC Min Gain", RK3028_PGAR_AGC_CTL5, - RK3028_PGA_AGC_MIN_G_SFT, 7, 0, pga_agc_min_vol_tlv),//AGC enable and 0x06 bit 4 is 1 - -}; - -//For tiny alsa playback/capture/voice call path -static const char *rk3028_playback_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", //0-6 - "RING_SPK", "RING_HP", "RING_HP_NO_MIC", "RING_SPK_HP"};//7-10 - -static const char *rk3028_capture_path_mode[] = {"MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; - -static const char *rk3028_voice_call_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"};//0-5 - -static const SOC_ENUM_SINGLE_DECL(rk3028_playback_path_type, 0, 0, rk3028_playback_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3028_capture_path_type, 0, 0, rk3028_capture_path_mode); - -static const SOC_ENUM_SINGLE_DECL(rk3028_voice_call_path_type, 0, 0, rk3028_voice_call_path_mode); - -static int rk3028_playback_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : playback_path = %ld\n",__func__,ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3028_priv->playback_path; - - return 0; -} - -static int rk3028_playback_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3028_priv->playback_path == ucontrol->value.integer.value[0]){ - printk("%s : playback_path is not changed!\n",__func__); - //return 0; - } - - rk3028_priv->playback_path = ucontrol->value.integer.value[0]; - - DBG("%s : set playback_path = %ld, hdmi %s\n", __func__, - rk3028_priv->playback_path, get_hdmi_state() ? "in" : "out"); - - if(get_hdmi_state()) - return 0; - - switch (rk3028_priv->playback_path) { - case OFF: - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_sync(&codec->dapm); - break; - case RCV: - break; - case SPK_PATH: - case RING_SPK: - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_sync(&codec->dapm); - break; - case HP_PATH: - case HP_NO_MIC: - case RING_HP: - case RING_HP_NO_MIC: - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_sync(&codec->dapm); - break; - case BT: - break; - case SPK_HP: - case RING_SPK_HP: - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_sync(&codec->dapm); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int rk3028_capture_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : capture_path = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3028_priv->capture_path; - - return 0; -} - -static int rk3028_capture_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3028_priv->capture_path == ucontrol->value.integer.value[0]){ - printk("%s : capture_path is not changed!\n", __func__); - //return 0; - } - - rk3028_priv->capture_path = ucontrol->value.integer.value[0]; - - DBG("%s : set capture_path = %ld\n", __func__, rk3028_priv->capture_path); - - switch (rk3028_priv->capture_path) { - case MIC_OFF: - snd_soc_dapm_disable_pin(&codec->dapm, "Mic Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Headset Jack"); - snd_soc_dapm_sync(&codec->dapm); - break; - case Main_Mic: - snd_soc_dapm_enable_pin(&codec->dapm, "Mic Jack"); - snd_soc_dapm_disable_pin(&codec->dapm,"Headset Jack"); - snd_soc_dapm_sync(&codec->dapm); - break; - case Hands_Free_Mic: - snd_soc_dapm_enable_pin(&codec->dapm, "Headset Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Mic Jack"); - snd_soc_dapm_sync(&codec->dapm); - break; - case BT_Sco_Mic: - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int rk3028_voice_call_path_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : playback_path = %ld\n", __func__, - ucontrol->value.integer.value[0]); - - ucontrol->value.integer.value[0] = rk3028_priv->voice_call_path; - - return 0; -} - -static int rk3028_voice_call_path_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return -EINVAL; - } - - if (rk3028_priv->voice_call_path == ucontrol->value.integer.value[0]){ - printk("%s : playback_path is not changed!\n",__func__); - //return 0; - } - - rk3028_priv->voice_call_path = ucontrol->value.integer.value[0]; - - DBG("%s : set playback_path = %ld\n", __func__, - rk3028_priv->voice_call_path); - - switch (rk3028_priv->voice_call_path) { - case OFF: - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_sync(&codec->dapm); - break; - case RCV: - break; - case SPK_PATH: - snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_sync(&codec->dapm); - break; - case HP_PATH: - case HP_NO_MIC: - snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk"); - snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); - snd_soc_dapm_sync(&codec->dapm); - break; - case BT: - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_kcontrol_new rk3028_snd_path_controls[] = { - SOC_ENUM_EXT("Playback Path", rk3028_playback_path_type, - rk3028_playback_path_get, rk3028_playback_path_put), - - SOC_ENUM_EXT("Capture MIC Path", rk3028_capture_path_type, - rk3028_capture_path_get, rk3028_capture_path_put), - - SOC_ENUM_EXT("Voice Call Path", rk3028_voice_call_path_type, - rk3028_voice_call_path_get, rk3028_voice_call_path_put), -}; - -static int rk3028_dacl_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_WORK,0); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_EN | RK3028_DACL_CLK_EN, - RK3028_DACL_EN | RK3028_DACL_CLK_EN); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_WORK, RK3028_DACL_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_EN | RK3028_DACL_CLK_EN,0); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3028_dacr_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACR_WORK,0); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACR_EN | RK3028_DACR_CLK_EN, - RK3028_DACR_EN | RK3028_DACR_CLK_EN); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACR_WORK, RK3028_DACR_WORK); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACR_EN | RK3028_DACR_CLK_EN,0); - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACR_WORK, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3028_adcl_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCL_CLK_EN | RK3028_ADCL_AMP_EN , - RK3028_ADCL_CLK_EN | RK3028_ADCL_AMP_EN ); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCL_CLK_EN | RK3028_ADCL_AMP_EN,0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3028_adcr_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCR_CLK_EN | RK3028_ADCR_AMP_EN , - RK3028_ADCR_CLK_EN | RK3028_ADCR_AMP_EN ); - break; - - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCR_CLK_EN | RK3028_ADCR_AMP_EN,0); - break; - - default: - return 0; - } - - return 0; -} - -/* HPmix */ -static const struct snd_kcontrol_new rk3028_hpmixl[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXL_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXL_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACL Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXL_SEL_DACL_SFT, 1, 0), -}; - -static const struct snd_kcontrol_new rk3028_hpmixr[] = { - SOC_DAPM_SINGLE("ALCR Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXR_SEL_ALCR_SFT, 1, 0), - SOC_DAPM_SINGLE("ALCL Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXR_SEL_ALCL_SFT, 1, 0), - SOC_DAPM_SINGLE("DACR Switch", RK3028_HPMIX_S_SELECT, - RK3028_HPMIXR_SEL_DACR_SFT, 1, 0), -}; - -static int rk3028_hpmixl_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_HPMIX_CTL, - RK3028_HPMIXL_WORK2, RK3028_HPMIXL_WORK2); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3028_HPMIX_CTL, - RK3028_HPMIXL_WORK2, 0); - break; - - default: - return 0; - } - - return 0; -} - -static int rk3028_hpmixr_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_POST_PMU: - snd_soc_update_bits(codec, RK3028_HPMIX_CTL, - RK3028_HPMIXR_WORK2, RK3028_HPMIXR_WORK2); - break; - - case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(codec, RK3028_HPMIX_CTL, - RK3028_HPMIXR_WORK2, 0); - break; - - default: - return 0; - } - - return 0; -} - -/* HP MUX */ - -static const char *hpl_sel[] = {"HPMIXL", "DACL"}; - -static const struct soc_enum hpl_sel_enum = - SOC_ENUM_SINGLE(RK3028_HPMIX_S_SELECT, RK3028_HPMIXL_BYPASS_SFT, - ARRAY_SIZE(hpl_sel), hpl_sel); - -static const struct snd_kcontrol_new hpl_sel_mux = - SOC_DAPM_ENUM("HPL select Mux", hpl_sel_enum); - -static const char *hpr_sel[] = {"HPMIXR", "DACR"}; - -static const struct soc_enum hpr_sel_enum = - SOC_ENUM_SINGLE(RK3028_HPMIX_S_SELECT, RK3028_HPMIXR_BYPASS_SFT, - ARRAY_SIZE(hpr_sel), hpr_sel); - -static const struct snd_kcontrol_new hpr_sel_mux = - SOC_DAPM_ENUM("HPR select Mux", hpr_sel_enum); - -/* IN_L MUX */ -static const char *lnl_sel[] = {"NO","BSTL", "LINEL","NOUSE"}; - -static const struct soc_enum lnl_sel_enum = - SOC_ENUM_SINGLE(RK3028_ALC_MUNIN_CTL, RK3028_MUXINL_F_SHT, - ARRAY_SIZE(lnl_sel), lnl_sel); - -static const struct snd_kcontrol_new lnl_sel_mux = - SOC_DAPM_ENUM("MUXIN_L select", lnl_sel_enum); - -/* IN_R MUX */ -static const char *lnr_sel[] = {"NO","BSTR", "LINER","NOUSE"}; - -static const struct soc_enum lnr_sel_enum = - SOC_ENUM_SINGLE(RK3028_ALC_MUNIN_CTL, RK3028_MUXINR_F_SHT, - ARRAY_SIZE(lnr_sel), lnr_sel); - -static const struct snd_kcontrol_new lnr_sel_mux = - SOC_DAPM_ENUM("MUXIN_R select", lnr_sel_enum); - - -static const struct snd_soc_dapm_widget rk3028_dapm_widgets[] = { - - /* microphone bias */ - SND_SOC_DAPM_MICBIAS("Mic Bias", RK3028_ADC_MIC_CTL, - RK3028_MICBIAS_VOL_ENABLE, 0), - - /* DACs */ - SND_SOC_DAPM_ADC_E("DACL", NULL, SND_SOC_NOPM, - 0, 0, rk3028_dacl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("DACR", NULL, SND_SOC_NOPM, - 0, 0, rk3028_dacr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* ADCs */ - SND_SOC_DAPM_ADC_E("ADCL", NULL, SND_SOC_NOPM, - 0, 0, rk3028_adcl_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_ADC_E("ADCR", NULL, SND_SOC_NOPM, - 0, 0, rk3028_adcr_event, - SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), - - /* PGA */ - SND_SOC_DAPM_PGA("BSTL", RK3028_BST_CTL, - RK3028_BSTL_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("BSTR", RK3028_BST_CTL, - RK3028_BSTR_PWRD_SFT, 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCL", RK3028_ALC_MUNIN_CTL, - RK3028_ALCL_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("ALCR", RK3028_ALC_MUNIN_CTL, - RK3028_ALCR_PWR_SHT , 0, NULL, 0), - SND_SOC_DAPM_PGA("HPL", RK3028_HPOUT_CTL, - RK3028_HPOUTL_PWR_SHT, 0, NULL, 0), - SND_SOC_DAPM_PGA("HPR", RK3028_HPOUT_CTL, - RK3028_HPOUTR_PWR_SHT, 0, NULL, 0), - - /* MIXER */ - SND_SOC_DAPM_MIXER_E("HPMIXL", RK3028_HPMIX_CTL, - RK3028_HPMIXL_SFT, 0, rk3028_hpmixl, - ARRAY_SIZE(rk3028_hpmixl),rk3028_hpmixl_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_MIXER_E("HPMIXR", RK3028_HPMIX_CTL, - RK3028_HPMIXR_SFT, 0, rk3028_hpmixr, - ARRAY_SIZE(rk3028_hpmixr),rk3028_hpmixr_event, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - - /* MUX */ - SND_SOC_DAPM_MUX("IN_R Mux", SND_SOC_NOPM, 0, 0, - &lnr_sel_mux), - SND_SOC_DAPM_MUX("IN_L Mux", SND_SOC_NOPM, 0, 0, - &lnl_sel_mux), - SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, - &hpl_sel_mux), - SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, - &hpr_sel_mux), - - /* Audio Interface */ - SND_SOC_DAPM_AIF_IN("I2S DAC", "HiFi Playback", 0, - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_AIF_OUT("I2S ADC", "HiFi Capture", 0, - SND_SOC_NOPM, 0, 0), - - /* Input */ - SND_SOC_DAPM_INPUT("LINEL"), - SND_SOC_DAPM_INPUT("LINER"), - SND_SOC_DAPM_INPUT("MICP"), - SND_SOC_DAPM_INPUT("MICN"), - - /* Output */ - SND_SOC_DAPM_OUTPUT("HPOUTL"), - SND_SOC_DAPM_OUTPUT("HPOUTR"), - -}; - -static const struct snd_soc_dapm_route rk3028_dapm_routes[] = { - /* Input */ - {"BSTR", NULL, "MICP"}, - {"BSTL", NULL, "MICP"}, - {"BSTL", NULL, "MICN"}, - - {"IN_R Mux", "LINER", "LINER"}, - {"IN_R Mux", "BSTR", "BSTR"}, - {"IN_L Mux", "LINEL", "LINEL"}, - {"IN_L Mux", "BSTL", "BSTL"}, - - {"ALCL", NULL, "IN_L Mux"}, - {"ALCR", NULL, "IN_R Mux"}, - - - {"ADCR", NULL, "ALCR"}, - {"ADCL", NULL, "ALCL"}, - - {"I2S ADC", NULL, "ADCR"}, - {"I2S ADC", NULL, "ADCL"}, - - /* Output */ - - {"DACR", NULL, "I2S DAC"}, - {"DACL", NULL, "I2S DAC"}, - - {"HPMIXR", "ALCR Switch", "ALCR"}, - {"HPMIXR", "ALCL Switch", "ALCL"}, - {"HPMIXR", "DACR Switch", "DACR"}, - - {"HPMIXL", "ALCR Switch", "ALCR"}, - {"HPMIXL", "ALCL Switch", "ALCL"}, - {"HPMIXL", "DACL Switch", "DACL"}, - - - {"HPR Mux", "DACR", "DACR"}, - {"HPR Mux", "HPMIXR", "HPMIXR"}, - {"HPL Mux", "DACL", "DACL"}, - {"HPL Mux", "HPMIXL", "HPMIXL"}, - - {"HPR", NULL, "HPR Mux"}, - {"HPL", NULL, "HPL Mux"}, - - {"HPOUTR", NULL, "HPR"}, - {"HPOUTL", NULL, "HPL"}, -}; - -static int rk3028_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - DBG("%s level=%d\n",__func__,level); - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_ADC_CURRENT_ENABLE, RK3028_ADC_CURRENT_ENABLE); - snd_soc_update_bits(codec, RK3028_DAC_CTL, - RK3028_CURRENT_EN, RK3028_CURRENT_EN); - /* set power */ - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCL_REF_VOL_EN | RK3028_ADCL_REF_VOL_EN, - RK3028_ADCL_REF_VOL_EN | RK3028_ADCL_REF_VOL_EN); - - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_ADCL_ZERO_DET_EN | RK3028_ADCR_ZERO_DET_EN, - RK3028_ADCL_ZERO_DET_EN | RK3028_ADCR_ZERO_DET_EN); - - snd_soc_update_bits(codec, RK3028_DAC_CTL, - RK3028_REF_VOL_DACL_EN | RK3028_REF_VOL_DACR_EN, - RK3028_REF_VOL_DACL_EN | RK3028_REF_VOL_DACR_EN ); - - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_REF_VOL_EN | RK3028_DACR_REF_VOL_EN, - RK3028_DACL_REF_VOL_EN | RK3028_DACR_REF_VOL_EN ); - } - break; - - case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, RK3028_DAC_ENABLE, - RK3028_DACL_REF_VOL_EN | RK3028_DACR_REF_VOL_EN,0); - snd_soc_update_bits(codec, RK3028_DAC_CTL, - RK3028_REF_VOL_DACL_EN | RK3028_REF_VOL_DACR_EN,0); - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_ADCL_ZERO_DET_EN | RK3028_ADCR_ZERO_DET_EN,0); - snd_soc_update_bits(codec, RK3028_ADC_ENABLE, - RK3028_ADCL_REF_VOL_EN | RK3028_ADCL_REF_VOL_EN, 0); - snd_soc_update_bits(codec, RK3028_ADC_MIC_CTL, - RK3028_ADC_CURRENT_ENABLE, 0); - snd_soc_update_bits(codec, RK3028_DAC_CTL, - RK3028_CURRENT_EN, 0); - break; - } - codec->dapm.bias_level = level; - - return 0; -} - -static int rk3028_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct rk3028_codec_priv *rk3028 = rk3028_priv; - - if (!rk3028) { - printk("%s : rk3028 is NULL\n", __func__); - return -EINVAL; - } - - rk3028->stereo_sysclk = freq; - - return 0; -} - -static int rk3028_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - adc_aif2 |= RK3028_I2S_MODE_SLV; - break; - case SND_SOC_DAIFMT_CBM_CFM: - adc_aif2 |= RK3028_I2S_MODE_MST; - break; - default: - printk("%s : set master mask failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - adc_aif1 |= RK3028_ADC_DF_PCM; - dac_aif1 |= RK3028_DAC_DF_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: - break; - case SND_SOC_DAIFMT_I2S: - adc_aif1 |= RK3028_ADC_DF_I2S; - dac_aif1 |= RK3028_DAC_DF_I2S; - break; - case SND_SOC_DAIFMT_RIGHT_J: - adc_aif1 |= RK3028_ADC_DF_RJ; - dac_aif1 |= RK3028_DAC_DF_RJ; - break; - case SND_SOC_DAIFMT_LEFT_J: - adc_aif1 |= RK3028_ADC_DF_LJ; - dac_aif1 |= RK3028_DAC_DF_LJ; - break; - default: - printk("%s : set format failed!\n", __func__); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - adc_aif1 |= RK3028_ALRCK_POL_DIS; - adc_aif2 |= RK3028_ABCLK_POL_DIS; - dac_aif1 |= RK3028_DLRCK_POL_DIS; - dac_aif2 |= RK3028_DBCLK_POL_DIS; - break; - case SND_SOC_DAIFMT_IB_IF: - adc_aif1 |= RK3028_ALRCK_POL_EN; - adc_aif2 |= RK3028_ABCLK_POL_EN; - dac_aif1 |= RK3028_DLRCK_POL_EN; - dac_aif2 |= RK3028_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_IB_NF: - adc_aif1 |= RK3028_ALRCK_POL_DIS; - adc_aif2 |= RK3028_ABCLK_POL_EN; - dac_aif1 |= RK3028_DLRCK_POL_DIS; - dac_aif2 |= RK3028_DBCLK_POL_EN; - break; - case SND_SOC_DAIFMT_NB_IF: - adc_aif1 |= RK3028_ALRCK_POL_EN; - adc_aif2 |= RK3028_ABCLK_POL_DIS; - dac_aif1 |= RK3028_DLRCK_POL_EN; - dac_aif2 |= RK3028_DBCLK_POL_DIS; - break; - default: - printk("%s : set dai format failed!\n", __func__); - return -EINVAL; - } - - snd_soc_update_bits(codec, RK3028_ADC_INT_CTL1, - RK3028_ALRCK_POL_MASK | RK3028_ADC_DF_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3028_ADC_INT_CTL2, - RK3028_ABCLK_POL_MASK | RK3028_I2S_MODE_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3028_DAC_INT_CTL1, - RK3028_DLRCK_POL_MASK | RK3028_DAC_DF_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3028_DAC_INT_CTL2, - RK3028_DBCLK_POL_MASK, dac_aif2); - - return 0; -} - -static int rk3028_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_codec *codec =rtd->codec; - struct rk3028_codec_priv *rk3028 = rk3028_priv; - unsigned int rate = params_rate(params); - unsigned int div; - unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; - - if (!rk3028) { - printk("%s : rk3028 is NULL\n", __func__); - return -EINVAL; - } - - // bclk = codec_clk / 4 - // lrck = bclk / (wl * 2) - div = (((rk3028->stereo_sysclk / 4) / rate) / 2); - - if ((rk3028->stereo_sysclk % (4 * rate * 2) > 0) || - (div != 16 && div != 20 && div != 24 && div != 32)) { - printk("%s : need PLL\n", __func__); - return -EINVAL; - } - - switch (div) { - case 16: - adc_aif2 |= RK3028_ADC_WL_16; - dac_aif2 |= RK3028_DAC_WL_16; - break; - case 20: - adc_aif2 |= RK3028_ADC_WL_20; - dac_aif2 |= RK3028_DAC_WL_20; - break; - case 24: - adc_aif2 |= RK3028_ADC_WL_24; - dac_aif2 |= RK3028_DAC_WL_24; - break; - case 32: - adc_aif2 |= RK3028_ADC_WL_32; - dac_aif2 |= RK3028_DAC_WL_32; - break; - default: - return -EINVAL; - } - - - DBG("%s : MCLK = %dHz, sample rate = %dHz, div = %d\n", __func__, - rk3028->stereo_sysclk, rate, div); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - adc_aif1 |= RK3028_ADC_VWL_16; - dac_aif1 |= RK3028_DAC_VWL_16; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - adc_aif1 |= RK3028_ADC_VWL_20; - dac_aif1 |= RK3028_DAC_VWL_20; - break; - case SNDRV_PCM_FORMAT_S24_LE: - adc_aif1 |= RK3028_ADC_VWL_24; - dac_aif1 |= RK3028_DAC_VWL_24; - break; - case SNDRV_PCM_FORMAT_S32_LE: - adc_aif1 |= RK3028_ADC_VWL_32; - dac_aif1 |= RK3028_DAC_VWL_32; - break; - default: - return -EINVAL; - } - - switch (params_channels(params)) { - case RK3028_MONO: - adc_aif1 |= RK3028_ADC_TYPE_MONO; - break; - case RK3028_STEREO: - adc_aif1 |= RK3028_ADC_TYPE_STEREO; - break; - default: - return -EINVAL; - } - - adc_aif1 |= RK3028_ADC_SWAP_DIS; - adc_aif2 |= RK3028_ADC_RST_DIS; - dac_aif1 |= RK3028_DAC_SWAP_DIS; - dac_aif2 |= RK3028_DAC_RST_DIS; - - rk3028->rate = rate; - - snd_soc_update_bits(codec, RK3028_ADC_INT_CTL1, - RK3028_ADC_VWL_MASK | RK3028_ADC_SWAP_MASK | - RK3028_ADC_TYPE_MASK, adc_aif1); - snd_soc_update_bits(codec, RK3028_ADC_INT_CTL2, - RK3028_ADC_WL_MASK | RK3028_ADC_RST_MASK, adc_aif2); - snd_soc_update_bits(codec, RK3028_DAC_INT_CTL1, - RK3028_DAC_VWL_MASK | RK3028_DAC_SWAP_MASK, dac_aif1); - snd_soc_update_bits(codec, RK3028_DAC_INT_CTL2, - RK3028_DAC_WL_MASK | RK3028_DAC_RST_MASK, dac_aif2); - - return 0; -} - -static int rk3028_digital_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int is_hp_pd; - - - is_hp_pd = (RK3028_HPOUTL_MSK | RK3028_HPOUTR_MSK) & snd_soc_read(codec, RK3028_HPOUT_CTL); - - if (mute) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - if (rk3028_priv && rk3028_priv->hp_ctl_gpio != INVALID_GPIO && - is_hp_pd) { - DBG("%s : set hp ctl gpio LOW\n", __func__); - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_LOW); - } - - } else { - if (rk3028_priv && rk3028_priv->hp_ctl_gpio != INVALID_GPIO && - is_hp_pd) { - msleep(10); - DBG("%s : set hp ctl gpio HIGH\n", __func__); - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_HIGH); - } - } - return 0; -} - -static struct rk3028_reg_val_typ playback_power_up_list[] = { -#if 0 - {0xbc,0x01}, - {0xbc,0x21}, - {0xbc,0x28}, -#endif - {0xa0,0x40}, - {0xa0,0x62}, - {0xa4,0x88}, - {0xa4,0xcc}, - {0xa4,0xee}, - {0xa4,0xff}, - {0xa8,0x44}, - {0xb0,0x92}, - {0xb0,0xdb}, - {0xac,0xff},//DAC - {0xa8,0x55}, - {0xa8,0x77}, - {0xb0,0xff}, - {0xb4,0x1a}, - {0xb8,0x1a}, - -}; -#define RK3028_CODEC_PLAYBACK_POWER_UP_LIST_LEN ARRAY_SIZE(playback_power_up_list) - -static struct rk3028_reg_val_typ playback_power_down_list[] = { - {0xb4,0x00}, - {0xb8,0x00}, - {0xa0,0x62}, - {0xb0,0xdb}, - {0xa8,0x44}, - {0xac,0x00}, - {0xb0,0x92}, - {0xb0,0x00}, - {0xa8,0x00}, - {0xa4,0x00}, - {0xa0,0x40}, - {0xa0,0x00}, - {0xbc,0x08}, - -}; -#define RK3028_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN ARRAY_SIZE(playback_power_down_list) - -static struct rk3028_reg_val_typ capture_power_up_list[] = { - {0x88, 0x80}, - {0x88, 0xc0}, - {0x88, 0xc7}, - {0x9c, 0x88}, - {0x8c, 0x44}, - {0x90, 0x66}, - {0x9c, 0xcc}, - {0x9c, 0xee}, - {0x8c, 0x55}, - {0x90, 0x77}, - {0x94, 0x3f}, - {0x98, 0x3f}, - {0x88, 0xf7}, -}; -#define RK3028_CODEC_CAPTURE_POWER_UP_LIST_LEN ARRAY_SIZE(capture_power_up_list) - -static struct rk3028_reg_val_typ capture_power_down_list[] = { - {0x9c, 0xcc}, - {0x90, 0x66}, - {0x8c, 0x44}, - {0x9c, 0x88}, - {0x88, 0xc7}, - {0x88, 0xc0}, - {0x88, 0x80}, -}; -#define RK3028_CODEC_CAPTURE_POWER_DOWN_LIST_LEN ARRAY_SIZE(capture_power_down_list) - -static int rk3028_codec_power_up(int type) -{ - struct snd_soc_codec *codec = rk3028_priv->codec; - int i; - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return -EINVAL; - } - - printk("%s : power up %s%s\n", __func__, - type == RK3028_CODEC_PLAYBACK ? "playback" : "", - type == RK3028_CODEC_CAPTURE ? "capture" : ""); - - if (type == RK3028_CODEC_PLAYBACK) { - for (i = 0; i < RK3028_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_up_list[i].reg, - playback_power_up_list[i].value); - } - //codec_set_spk(!get_hdmi_state()); - } else if (type == RK3028_CODEC_CAPTURE) { - for (i = 0; i < RK3028_CODEC_CAPTURE_POWER_UP_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_up_list[i].reg, - capture_power_up_list[i].value); - } - } - - return 0; -} - -static int rk3028_codec_power_down(int type) -{ - struct snd_soc_codec *codec = rk3028_priv->codec; - int i; - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return -EINVAL; - } - -// if (rk3028_priv->playback_active <= 0 && rk3028_priv->capture_active <= 0) -// type = RK3028_CODEC_ALL; - - printk("%s : power down %s%s%s\n", __func__, - type == RK3028_CODEC_PLAYBACK ? "playback" : "", - type == RK3028_CODEC_CAPTURE ? "capture" : "", - type == RK3028_CODEC_ALL ? "all" : ""); - - if (type == RK3028_CODEC_CAPTURE) { - for (i = 0; i < RK3028_CODEC_CAPTURE_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, capture_power_down_list[i].reg, - capture_power_down_list[i].value); - } - } else if (type == RK3028_CODEC_PLAYBACK) { - for (i = 0; i < RK3028_CODEC_PLAYBACK_POWER_DOWN_LIST_LEN; i++) { - snd_soc_write(codec, playback_power_down_list[i].reg, - playback_power_down_list[i].value); - } - } else if (type == RK3028_CODEC_ALL) { - rk3028_reset(codec); - } - - return 0; -} - -static void rk3028_codec_capture_work(struct work_struct *work) -{ - DBG("%s : rk3028_codec_work_capture_type = %d\n", __func__, - rk3028_codec_work_capture_type); - - switch (rk3028_codec_work_capture_type) { - case RK3028_CODEC_WORK_POWER_DOWN: - rk3028_codec_power_down(RK3028_CODEC_CAPTURE); - break; - case RK3028_CODEC_WORK_POWER_UP: - rk3028_codec_power_up(RK3028_CODEC_CAPTURE); - break; - default: - break; - } - - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; -} - -static int rk3028_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rk3028_codec_priv *rk3028 = rk3028_priv; - bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk3028->playback_active > 0 ; - bool is_codec_capture_running = rk3028->capture_active > 0; - - if (!rk3028_for_mid) - { - DBG("%s immediately return for phone\n",__func__); - return 0; - } - - if (!rk3028) { - printk("%s : rk3028 is NULL\n", __func__); - return -EINVAL; - } - - DBG("%s : substream->stream : %s \n", __func__, - playback ? "PLAYBACK":"CAPTURE"); - - if (playback) - rk3028->playback_active++; - else - rk3028->capture_active++; - - if (playback) { - if (rk3028->playback_active > 0) { - if (!is_codec_playback_running) - rk3028_codec_power_up(RK3028_CODEC_PLAYBACK); - else - DBG(" Warning : playback has been opened, so return! \n"); - } - } else {//capture - if (rk3028->capture_active > 0 && !is_codec_capture_running) { - if (rk3028_codec_work_capture_type != RK3028_CODEC_WORK_POWER_UP) { - cancel_delayed_work_sync(&capture_delayed_work); - if (rk3028_codec_work_capture_type == RK3028_CODEC_WORK_NULL) { - rk3028_codec_power_up(RK3028_CODEC_CAPTURE); - } else { - DBG(" Warning : capture being closed, so interrupt the shutdown process ! \n"); - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; - } - } else { - DBG("Warning : capture being opened, so return ! \n"); - } - } - } - - return 0; -} - -static void rk3028_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rk3028_codec_priv *rk3028 = rk3028_priv; - bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - bool is_codec_playback_running = rk3028->playback_active > 0; - bool is_codec_capture_running = rk3028->capture_active > 0; - - if (!rk3028_for_mid) - { - DBG("%s immediately return for phone\n", __func__); - return; - } - - if (!rk3028) { - printk("%s : rk3028 is NULL\n", __func__); - return; - } - - DBG("%s : substream->stream : %s \n", __func__, - playback ? "PLAYBACK":"CAPTURE"); - - if (playback) - rk3028->playback_active--; - else - rk3028->capture_active--; - - if (playback) { - if (rk3028->playback_active <= 0) { - if (is_codec_playback_running == true) - rk3028_codec_power_down(RK3028_CODEC_PLAYBACK); - else - DBG(" Warning : playback has been closed, so return !\n"); - } - } else {//capture - if (rk3028->capture_active <= 0) { - if ((rk3028_codec_work_capture_type != RK3028_CODEC_WORK_POWER_DOWN) && - (is_codec_capture_running == true)) { - cancel_delayed_work_sync(&capture_delayed_work); - /* - * If rk3028_codec_work_capture_type is NULL means codec already power down, - * so power up codec. - * If rk3028_codec_work_capture_type is RK3028_CODEC_WORK_POWER_UP it means - * codec haven't be powered up, so we don't need to power down codec. - * If is playback call power down, power down immediatly, because audioflinger - * already has delay 3s. - */ - if (rk3028_codec_work_capture_type == RK3028_CODEC_WORK_NULL) { - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_POWER_DOWN; - queue_delayed_work(rk3028_codec_workq, &capture_delayed_work,msecs_to_jiffies(3000)); - } else { - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; - DBG(" Warning : capture being opened, so interrupt the open process ! \n"); - } - } else { - DBG(" Warning : capture has been closed or it being closed, so return !\n"); - } - } - } - -} - -#define RK3028_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3028_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_96000) - -#define RK3028_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops rk3028_dai_ops = { - .hw_params = rk3028_hw_params, - .set_fmt = rk3028_set_dai_fmt, - .set_sysclk = rk3028_set_dai_sysclk, - .digital_mute = rk3028_digital_mute, - .startup = rk3028_startup, - .shutdown = rk3028_shutdown, -}; - -static struct snd_soc_dai_driver rk3028_dai[] = { - { - .name = "rk3028-hifi", - .id = RK3028_HIFI, - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 2, - .channels_max = 2, - .rates = RK3028_PLAYBACK_RATES, - .formats = RK3028_FORMATS, - }, - .capture = { - .stream_name = "HiFi Capture", - .channels_min = 2, - .channels_max = 2, - .rates = RK3028_CAPTURE_RATES, - .formats = RK3028_FORMATS, - }, - .ops = &rk3028_dai_ops, - }, - { - .name = "rk3028-voice", - .id = RK3028_VOICE, - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 2, - .rates = RK3028_PLAYBACK_RATES, - .formats = RK3028_FORMATS, - }, - .capture = { - .stream_name = "Voice Capture", - .channels_min = 1, - .channels_max = 2, - .rates = RK3028_CAPTURE_RATES, - .formats = RK3028_FORMATS, - }, - .ops = &rk3028_dai_ops, - }, - -}; - -static int rk3028_suspend(struct snd_soc_codec *codec, pm_message_t state) -{ - if (rk3028_for_mid) - { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3028_codec_work_capture_type != RK3028_CODEC_WORK_NULL) { - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; - } - rk3028_codec_power_down(RK3028_CODEC_ALL); - } - else - rk3028_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int rk3028_resume(struct snd_soc_codec *codec) -{ - if (!rk3028_for_mid) - rk3028_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - return 0; -} - -static int rk3028_probe(struct snd_soc_codec *codec) -{ - struct rk3028_codec_priv *rk3028; - struct rk3028_codec_pdata *rk3028_plt = codec->dev->platform_data; - struct platform_device *pdev = to_platform_device(codec->dev); - struct resource *res, *mem; - int ret; - unsigned int val; - - - DBG("%s\n", __func__); - - rk3028 = kzalloc(sizeof(struct rk3028_codec_priv), GFP_KERNEL); - if (!rk3028) { - printk("%s : rk3028 priv kzalloc failed!\n", __func__); - return -ENOMEM; - } - - rk3028->codec = codec; - - res = pdev->resource; - rk3028->regbase_phy = res->start; - rk3028->regsize_phy = (res->end - res->start) + 1; - - mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name); - if (!mem) - { - dev_err(&pdev->dev, "failed to request mem region for rk2928 codec\n"); - ret = -ENOENT; - goto err__; - } - - rk3028->regbase = (int)ioremap(res->start, (res->end - res->start) + 1); - if (!rk3028->regbase) { - dev_err(&pdev->dev, "cannot ioremap acodec registers\n"); - ret = -ENXIO; - goto err__; - } - - rk3028->pclk = clk_get(NULL,"pclk_acodec"); - if(IS_ERR(rk3028->pclk)) - { - dev_err(&pdev->dev, "Unable to get acodec hclk\n"); - ret = -ENXIO; - goto err__; - } - clk_enable(rk3028->pclk); - - rk3028_priv = rk3028; - - if (rk3028_priv && rk3028_plt->spk_ctl_gpio) { - gpio_request(rk3028_plt->spk_ctl_gpio, NULL); - gpio_direction_output(rk3028_plt->spk_ctl_gpio, GPIO_LOW); - rk3028->spk_ctl_gpio = rk3028_plt->spk_ctl_gpio; - rk3028->hp_ctl_gpio = rk3028_plt->hp_ctl_gpio; - } else { - printk("%s : rk3028 or pdata or spk_ctl_gpio is NULL!\n", __func__); - rk3028->spk_ctl_gpio = INVALID_GPIO; - } - - if (rk3028_priv && rk3028_plt->hp_ctl_gpio) { - gpio_request(rk3028_plt->hp_ctl_gpio, NULL); - gpio_direction_output(rk3028_plt->hp_ctl_gpio, GPIO_LOW); - rk3028->hp_ctl_gpio = rk3028_plt->hp_ctl_gpio; - } else { - printk("%s : rk3028 or pdata or hp_ctl_gpio is NULL!\n", __func__); - rk3028->hp_ctl_gpio = INVALID_GPIO; - } - - if (rk3028_for_mid) - { - rk3028->playback_active = 0; - rk3028->capture_active = 0; - - rk3028_codec_workq = create_freezable_workqueue("rk3028-codec"); - - if (rk3028_codec_workq == NULL) { - printk("%s : create work FAIL! rk3028_codec_workq is NULL!\n", __func__); - ret = -ENOMEM; - goto err__; - } - } - - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); - if (ret != 0) { - printk("%s : Failed to set cache I/O: %d\n", __func__, ret); - goto err__; - } - - codec->hw_read = rk3028_codec_read; - codec->hw_write = (hw_write_t)rk3028_hw_write; - codec->read = rk3028_codec_read; - codec->write = rk3028_codec_write; - - val = snd_soc_read(codec, RK3028_RESET); - if (val != rk3028_reg_defaults[RK3028_RESET]) { - printk("%s : codec register 0: %x is not a 0x00000003\n", __func__, val); - ret = -ENODEV; - goto err__; - } - - rk3028_reset(codec); - - if (!rk3028_for_mid) - { - codec->dapm.bias_level = SND_SOC_BIAS_OFF; - rk3028_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - } - - return 0; - -err__: - release_mem_region(res->start,(res->end - res->start) + 1); - kfree(rk3028); - rk3028 = NULL; - rk3028_priv = NULL; - - return ret; -} - -/* power down chip */ -static int rk3028_remove(struct snd_soc_codec *codec) -{ - DBG("%s\n", __func__); - - if (!rk3028_priv) { - printk("%s : rk3028_priv is NULL\n", __func__); - return 0; - } - - if (rk3028_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3028_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3028_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - if (rk3028_for_mid) - { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3028_codec_work_capture_type != RK3028_CODEC_WORK_NULL) { - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; - } - } - - snd_soc_write(codec, RK3028_RESET, 0xfc); - mdelay(10); - snd_soc_write(codec, RK3028_RESET, 0x3); - mdelay(10); - - if (rk3028_priv) - kfree(rk3028_priv); - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_rk3028 = { - .probe = rk3028_probe, - .remove = rk3028_remove, - .suspend = rk3028_suspend, - .resume = rk3028_resume, - .set_bias_level = rk3028_set_bias_level, - .reg_cache_size = ARRAY_SIZE(rk3028_reg_defaults), - .reg_word_size = sizeof(unsigned int), - .reg_cache_default = rk3028_reg_defaults, - .volatile_register = rk3028_volatile_register, - .readable_register = rk3028_codec_register, - .reg_cache_step = sizeof(unsigned int), - .controls = rk3028_snd_controls, - .num_controls = ARRAY_SIZE(rk3028_snd_controls), - .dapm_widgets = rk3028_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(rk3028_dapm_widgets), - .dapm_routes = rk3028_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(rk3028_dapm_routes), -}; - -static __devinit int rk3028_platform_probe(struct platform_device *pdev) -{ - DBG("%s\n", __func__); - - return snd_soc_register_codec(&pdev->dev, - &soc_codec_dev_rk3028, rk3028_dai, ARRAY_SIZE(rk3028_dai)); -} - -static __devexit int rk3028_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_codec(&pdev->dev); - return 0; -} - -void rk3028_platform_shutdown(struct platform_device *pdev) -{ - - DBG("%s\n", __func__); - - if (!rk3028_priv || !rk3028_priv->codec) { - printk("%s : rk3028_priv or rk3028_priv->codec is NULL\n", __func__); - return; - } - - if (rk3028_priv->spk_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3028_priv->spk_ctl_gpio, GPIO_LOW); - - if (rk3028_priv->hp_ctl_gpio != INVALID_GPIO) - gpio_set_value(rk3028_priv->hp_ctl_gpio, GPIO_LOW); - - mdelay(10); - - if (rk3028_for_mid) { - cancel_delayed_work_sync(&capture_delayed_work); - - if (rk3028_codec_work_capture_type != RK3028_CODEC_WORK_NULL) { - rk3028_codec_work_capture_type = RK3028_CODEC_WORK_NULL; - } - } - - writel_relaxed(0xfc, rk3028_priv->regbase+RK3028_RESET); - mdelay(10); - writel_relaxed(0x03, rk3028_priv->regbase+RK3028_RESET); - - if (rk3028_priv) - kfree(rk3028_priv); -} - -static struct platform_driver rk3028_codec_driver = { - .driver = { - .name = "rk3028-codec", - .owner = THIS_MODULE, - }, - .probe = rk3028_platform_probe, - .remove = __devexit_p(rk3028_platform_remove), - .shutdown = rk3028_platform_shutdown, -}; - - -static __init int rk3028_modinit(void) -{ - rk3028_get_parameter(); - return platform_driver_register(&rk3028_codec_driver); -} -module_init(rk3028_modinit); - -static __exit void rk3028_exit(void) -{ - platform_driver_unregister(&rk3028_codec_driver); -} -module_exit(rk3028_exit); - -MODULE_DESCRIPTION("ASoC RK3028 driver"); -MODULE_AUTHOR("yj "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/rk3028_codec.h b/sound/soc/codecs/rk3028_codec.h deleted file mode 100644 index f445027699ba..000000000000 --- a/sound/soc/codecs/rk3028_codec.h +++ /dev/null @@ -1,547 +0,0 @@ -/* - * rk3028.h -- RK3028 CODEC ALSA SoC audio driver - * - * Copyright 2013 Rockship - * Author: chenjq - * - */ - -#ifndef __RK3028_CODEC_H__ -#define __RK3028_CODEC_H__ - - - -/* codec register */ -#define RK3028_CODEC_BASE (0x0) - -#define RK3028_RESET (RK3028_CODEC_BASE + 0x00) -#define RK3028_ADC_INT_CTL1 (RK3028_CODEC_BASE + 0x08) -#define RK3028_ADC_INT_CTL2 (RK3028_CODEC_BASE + 0x0c) -#define RK3028_DAC_INT_CTL1 (RK3028_CODEC_BASE + 0x10) -#define RK3028_DAC_INT_CTL2 (RK3028_CODEC_BASE + 0x14) -#define RK3028_ADC_MIC_CTL (RK3028_CODEC_BASE + 0x88) -#define RK3028_BST_CTL (RK3028_CODEC_BASE + 0x8c) -#define RK3028_ALC_MUNIN_CTL (RK3028_CODEC_BASE + 0x90) -#define RK3028_BSTL_ALCL_CTL (RK3028_CODEC_BASE + 0x94) -#define RK3028_ALCR_GAIN_CTL (RK3028_CODEC_BASE + 0x98) -#define RK3028_ADC_ENABLE (RK3028_CODEC_BASE + 0x9c) -#define RK3028_DAC_CTL (RK3028_CODEC_BASE + 0xa0) -#define RK3028_DAC_ENABLE (RK3028_CODEC_BASE + 0xa4) -#define RK3028_HPMIX_CTL (RK3028_CODEC_BASE + 0xa8) -#define RK3028_HPMIX_S_SELECT (RK3028_CODEC_BASE + 0xac) -#define RK3028_HPOUT_CTL (RK3028_CODEC_BASE + 0xB0) -#define RK3028_HPOUTL_GAIN (RK3028_CODEC_BASE + 0xB4) -#define RK3028_HPOUTR_GAIN (RK3028_CODEC_BASE + 0xB8) -#define RK3028_SELECT_CURRENT (RK3028_CODEC_BASE + 0xBC) -#define RK3028_PGAL_AGC_CTL1 (RK3028_CODEC_BASE + 0xc0) -#define RK3028_PGAL_AGC_CTL2 (RK3028_CODEC_BASE + 0xc4) -#define RK3028_PGAL_AGC_CTL3 (RK3028_CODEC_BASE + 0xc8) -#define RK3028_PGAL_AGC_CTL4 (RK3028_CODEC_BASE + 0xcc) -#define RK3028_PGAL_ASR_CTL (RK3028_CODEC_BASE + 0xd0) -#define RK3028_PGAL_AGC_MAX_H (RK3028_CODEC_BASE + 0xd4) -#define RK3028_PGAL_AGC_MAX_L (RK3028_CODEC_BASE + 0xd8) -#define RK3028_PGAL_AGC_MIN_H (RK3028_CODEC_BASE + 0xdc) -#define RK3028_PGAL_AGC_MIN_L (RK3028_CODEC_BASE + 0xe0) -#define RK3028_PGAL_AGC_CTL5 (RK3028_CODEC_BASE + 0xe4) -#define RK3028_PGAR_AGC_CTL1 (RK3028_CODEC_BASE + 0x100) -#define RK3028_PGAR_AGC_CTL2 (RK3028_CODEC_BASE + 0x104) -#define RK3028_PGAR_AGC_CTL3 (RK3028_CODEC_BASE + 0x108) -#define RK3028_PGAR_AGC_CTL4 (RK3028_CODEC_BASE + 0x10c) -#define RK3028_PGAR_ASR_CTL (RK3028_CODEC_BASE + 0x110) -#define RK3028_PGAR_AGC_MAX_H (RK3028_CODEC_BASE + 0x114) -#define RK3028_PGAR_AGC_MAX_L (RK3028_CODEC_BASE + 0x118) -#define RK3028_PGAR_AGC_MIN_H (RK3028_CODEC_BASE + 0x11c) -#define RK3028_PGAR_AGC_MIN_L (RK3028_CODEC_BASE + 0x120) -#define RK3028_PGAR_AGC_CTL5 (RK3028_CODEC_BASE + 0x124) - -/* ADC Interface Control 1 (0x08) */ -#define RK3028_ALRCK_POL_MASK (0x1 << 7) -#define RK3028_ALRCK_POL_SFT 7 -#define RK3028_ALRCK_POL_EN (0x1 << 7) -#define RK3028_ALRCK_POL_DIS (0x0 << 7) - -#define RK3028_ADC_VWL_MASK (0x3 << 5) -#define RK3028_ADC_VWL_SFT 5 -#define RK3028_ADC_VWL_32 (0x3 << 5) -#define RK3028_ADC_VWL_24 (0x2 << 5) -#define RK3028_ADC_VWL_20 (0x1 << 5) -#define RK3028_ADC_VWL_16 (0x0 << 5) - -#define RK3028_ADC_DF_MASK (0x3 << 3) -#define RK3028_ADC_DF_SFT 3 -#define RK3028_ADC_DF_PCM (0x3 << 3) -#define RK3028_ADC_DF_I2S (0x2 << 3) -#define RK3028_ADC_DF_LJ (0x1 << 3) -#define RK3028_ADC_DF_RJ (0x0 << 3) - -#define RK3028_ADC_SWAP_MASK (0x1 << 1) -#define RK3028_ADC_SWAP_SFT 1 -#define RK3028_ADC_SWAP_EN (0x1 << 1) -#define RK3028_ADC_SWAP_DIS (0x0 << 1) - -#define RK3028_ADC_TYPE_MASK 0x1 -#define RK3028_ADC_TYPE_SFT 0 -#define RK3028_ADC_TYPE_MONO 0x1 -#define RK3028_ADC_TYPE_STEREO 0x0 - -/* ADC Interface Control 2 (0x0c) */ -#define RK3028_I2S_MODE_MASK (0x1 << 4) -#define RK3028_I2S_MODE_SFT (4) -#define RK3028_I2S_MODE_MST (0x1 << 4) -#define RK3028_I2S_MODE_SLV (0x0 << 4) - -#define RK3028_ADC_WL_MASK (0x3 << 2) -#define RK3028_ADC_WL_SFT (2) -#define RK3028_ADC_WL_32 (0x3 << 2) -#define RK3028_ADC_WL_24 (0x2 << 2) -#define RK3028_ADC_WL_20 (0x1 << 2) -#define RK3028_ADC_WL_16 (0x0 << 2) - -#define RK3028_ADC_RST_MASK (0x1 << 1) -#define RK3028_ADC_RST_SFT 91) -#define RK3028_ADC_RST_DIS (0x1 << 1) -#define RK3028_ADC_RST_EN (0x0 << 1) - -#define RK3028_ABCLK_POL_MASK 0x1 -#define RK3028_ABCLK_POL_SFT 0 -#define RK3028_ABCLK_POL_EN 0x1 -#define RK3028_ABCLK_POL_DIS 0x0 - -/* DAC Interface Control 1 (0x10) */ -#define RK3028_DLRCK_POL_MASK (0x1 << 7) -#define RK3028_DLRCK_POL_SFT 7 -#define RK3028_DLRCK_POL_EN (0x1 << 7) -#define RK3028_DLRCK_POL_DIS (0x0 << 7) - -#define RK3028_DAC_VWL_MASK (0x3 << 5) -#define RK3028_DAC_VWL_SFT 5 -#define RK3028_DAC_VWL_32 (0x3 << 5) -#define RK3028_DAC_VWL_24 (0x2 << 5) -#define RK3028_DAC_VWL_20 (0x1 << 5) -#define RK3028_DAC_VWL_16 (0x0 << 5) - -#define RK3028_DAC_DF_MASK (0x3 << 3) -#define RK3028_DAC_DF_SFT 3 -#define RK3028_DAC_DF_PCM (0x3 << 3) -#define RK3028_DAC_DF_I2S (0x2 << 3) -#define RK3028_DAC_DF_LJ (0x1 << 3) -#define RK3028_DAC_DF_RJ (0x0 << 3) - -#define RK3028_DAC_SWAP_MASK (0x1 << 2) -#define RK3028_DAC_SWAP_SFT 2 -#define RK3028_DAC_SWAP_EN (0x1 << 2) -#define RK3028_DAC_SWAP_DIS (0x0 << 2) - -/* DAC Interface Control 2 (0x14) */ -#define RK3028_DAC_WL_MASK (0x3 << 2) -#define RK3028_DAC_WL_SFT 2 -#define RK3028_DAC_WL_32 (0x3 << 2) -#define RK3028_DAC_WL_24 (0x2 << 2) -#define RK3028_DAC_WL_20 (0x1 << 2) -#define RK3028_DAC_WL_16 (0x0 << 2) - -#define RK3028_DAC_RST_MASK (0x1 << 1) -#define RK3028_DAC_RST_SFT 1 -#define RK3028_DAC_RST_DIS (0x1 << 1) -#define RK3028_DAC_RST_EN (0x0 << 1) - -#define RK3028_DBCLK_POL_MASK 0x1 -#define RK3028_DBCLK_POL_SFT 0 -#define RK3028_DBCLK_POL_EN 0x1 -#define RK3028_DBCLK_POL_DIS 0x0 - -/* ADC & MICBIAS (0x88) */ -#define RK3028_ADC_CURRENT_ENABLE (0x1 << 7) -#define RK3028_ADC_CURRENT_DISABLE (0x0 << 7) - -#define RK3028_MICBIAS_VOL_ENABLE (0x1 << 6) -#define RK3028_MICBIAS_VOL_DISABLE (0x0 << 6) - -#define RK3028_ADCL_ZERO_DET_EN (0x1 << 5) -#define RK3028_ADCL_ZERO_DET_DIS (0x0 << 5) - -#define RK3028_ADCR_ZERO_DET_EN (0x1 << 4) -#define RK3028_ADCR_ZERO_DET_DIS (0x0 << 4) - -#define RK3028_MICBIAS_VOL_SHT 0 -#define RK3028_MICBIAS_VOL_MSK 7 -#define RK3028_MICBIAS_VOL_MIN (0x0 << 0) -#define RK3028_MICBIAS_VOL_MAX (0x7 << 0) - -/* BST_L BST_R CONTROL (0x8C) */ -#define RK3028_BSTL_PWRD_SFT (6) -#define RK3028_BSTL_EN (0x1 << 6) -#define RK3028_BSTL_DIS (0x0 << 6) -#define RK3028_BSTL_GAIN_SHT (5) -#define RK3028_BSTL_GAIN_20 (0x1 << 5) -#define RK3028_BSTL_GAIN_0 (0x0 << 5) -#define RK3028_BSTL_MUTE_SHT (4) - -#define RK3028_BSTR_PWRD_SFT (2) -#define RK3028_BSTR_EN (0x1 << 2) -#define RK3028_BSTR_DIS (0x0 << 2) -#define RK3028_BSTR_GAIN_SHT (1) -#define RK3028_BSTR_GAIN_20 (0x1 << 1) -#define RK3028_BSTR_GAIN_0 (0x0 << 1) -#define RK3028_BSTR_MUTE_SHT (0) - - -/* MUXINL ALCL MUXINR ALCR (0x90) */ -#define RK3028_MUXINL_F_SHT (6) -#define RK3028_MUXINL_F_INL (0x02 << 6) -#define RK3028_MUXINL_F_BSTL (0x01 << 6) -#define RK3028_ALCL_PWR_SHT (5) -#define RK3028_ALCL_EN (0x1 << 5) -#define RK3028_ALCL_DIS (0x0 << 5) -#define RK3028_ALCL_MUTE_SHT (4) -#define RK3028_MUXINR_F_SHT (2) -#define RK3028_MUXINR_F_INR (0x02 << 2) -#define RK3028_MUXINR_F_BSTR (0x01 << 2) -#define RK3028_ALCR_PWR_SHT (1) -#define RK3028_ALCR_EN (0x1 << 1) -#define RK3028_ALCR_DIS (0x0 << 1) -#define RK3028_ALCR_MUTE_SHT (0) - -/* BST_L MODE & ALC_L GAIN (0x94) */ -#define RK3028_BSTL_MODE_SFT (5) -#define RK3028_BSTL_MODE_SINGLE (0x1 << 5) -#define RK3028_BSTL_MODE_DIFF (0x0 << 5) - -#define RK3028_ALCL_GAIN_SHT (0) -#define RK3028_ALCL_GAIN_MSK (0x1f) - -/* ALC_R GAIN (0x98) */ -#define RK3028_ALCR_GAIN_SHT (0) -#define RK3028_ALCR_GAIN_MSK (0x1f) - -/* ADC control (0x9C) */ -#define RK3028_ADCL_REF_VOL_EN (0x1 << 7) -#define RK3028_ADCL_REF_VOL_DIS (0x0 << 7) - -#define RK3028_ADCL_CLK_EN (0x1 << 6) -#define RK3028_ADCL_CLK_DIS (0x0 << 6) - -#define RK3028_ADCL_AMP_EN (0x1 << 5) -#define RK3028_ADCL_AMP_DIS (0x0 << 5) - -#define RK3028_ADCL_RST_EN (0x1 << 4) -#define RK3028_ADCL_RST_DIS (0x0 << 4) - -#define RK3028_ADCR_REF_VOL_EN (0x1 << 3) -#define RK3028_ADCR_REF_VOL_DIS (0x0 << 3) - -#define RK3028_ADCR_CLK_EN (0x1 << 2) -#define RK3028_ADCR_CLK_DIS (0x0 << 2) - -#define RK3028_ADCR_AMP_EN (0x1 << 1) -#define RK3028_ADCR_AMP_DIS (0x0 << 1) - -#define RK3028_ADCR_RST_EN (0x1 << 0) -#define RK3028_ADCR_RST_DIS (0x0 << 0) - -/* DAC & VOUT Control (0xa0) */ -#define RK3028_CURRENT_EN (0x1 << 6) -#define RK3028_CURRENT_DIS (0x0 << 6) -#define RK3028_REF_VOL_DACL_EN (0x1 << 5) -#define RK3028_REF_VOL_DACL_DIS (0x0 << 5) -#define RK3028_ZO_DET_VOUTL_EN (0x1 << 4) -#define RK3028_ZO_DET_VOUTL_DIS (0x0 << 4) -#define RK3028_DET_ERAPHONE_DIS (0x0 << 3) -#define RK3028_DET_ERAPHONE_EN (0x1 << 3) -#define RK3028_REF_VOL_DACR_EN (0x1 << 1) -#define RK3028_REF_VOL_DACR_DIS (0x0 << 1) -#define RK3028_ZO_DET_VOUTR_EN (0x1 << 0) -#define RK3028_ZO_DET_VOUTR_DIS (0x0 << 0) - -/* DAC control (0xa4) */ -#define RK3028_DACL_REF_VOL_EN (0x1 << 7) -#define RK3028_DACL_REF_VOL_DIS (0x0 << 7) - -#define RK3028_DACL_CLK_EN (0x1 << 6) -#define RK3028_DACL_CLK_DIS (0x0 << 6) - -#define RK3028_DACL_EN (0x1 << 5) -#define RK3028_DACL_DIS (0x0 << 5) - -#define RK3028_DACL_INIT (0x0 << 4) -#define RK3028_DACL_WORK (0x1 << 4) - -#define RK3028_DACR_REF_VOL_EN (0x1 << 3) -#define RK3028_DACR_REF_VOL_DIS (0x0 << 3) - -#define RK3028_DACR_CLK_EN (0x1 << 2) -#define RK3028_DACR_CLK_DIS (0x0 << 2) - -#define RK3028_DACR_EN (0x1 << 1) -#define RK3028_DACR_DIS (0x0 << 1) - -#define RK3028_DACR_INIT (0x0 << 0) -#define RK3028_DACR_WORK (0x1 << 0) - -/* HPMIXL HPMIXR Control (0xa8) */ -#define RK3028_HPMIXL_SFT (6) -#define RK3028_HPMIXL_EN (0x1 << 6) -#define RK3028_HPMIXL_DIS (0x0 << 6) -#define RK3028_HPMIXL_INIT1 (0x0 << 5) -#define RK3028_HPMIXL_WORK1 (0x1 << 5) -#define RK3028_HPMIXL_INIT2 (0x0 << 4) -#define RK3028_HPMIXL_WORK2 (0x1 << 4) -#define RK3028_HPMIXR_SFT (6) -#define RK3028_HPMIXR_EN (0x1 << 2) -#define RK3028_HPMIXR_DIS (0x0 << 2) -#define RK3028_HPMIXR_INIT1 (0x0 << 1) -#define RK3028_HPMIXR_WORK1 (0x1 << 1) -#define RK3028_HPMIXR_INIT2 (0x0 << 0) -#define RK3028_HPMIXR_WORK2 (0x1 << 0) - -/* HPMIXL Control (0xac) */ -#define RK3028_HPMIXL_BYPASS_SFT (0x1 << 7) -#define RK3028_HPMIXL_SEL_ALCL_SFT (0x1 << 6) -#define RK3028_HPMIXL_SEL_ALCR_SFT (0x1 << 5) -#define RK3028_HPMIXL_SEL_DACL_SFT (0x1 << 4) -#define RK3028_HPMIXR_BYPASS_SFT (0x1 << 3) -#define RK3028_HPMIXR_SEL_ALCL_SFT (0x1 << 2) -#define RK3028_HPMIXR_SEL_ALCR_SFT (0x1 << 1) -#define RK3028_HPMIXR_SEL_DACR_SFT (0x1 << 0) - -/* HPOUT Control (0xb0) */ -#define RK3028_HPOUTL_PWR_SHT (7) -#define RK3028_HPOUTL_MSK (0x1 << 7) -#define RK3028_HPOUTL_EN (0x1 << 7) -#define RK3028_HPOUTL_DIS (0x0 << 7) -#define RK3028_HPOUTL_INIT_MSK (0x1 << 6) -#define RK3028_HPOUTL_INIT (0x0 << 6) -#define RK3028_HPOUTL_WORK (0x1 << 6) -#define RK3028_HPOUTL_MUTE_SHT (5) -#define RK3028_HPOUTL_MUTE_MSK (0x1 << 5) -#define RK3028_HPOUTL_MUTE_EN (0x0 << 5) -#define RK3028_HPOUTL_MUTE_DIS (0x1 << 5) -#define RK3028_HPOUTR_PWR_SHT (4) -#define RK3028_HPOUTR_MSK (0x1 << 4) -#define RK3028_HPOUTR_EN (0x1 << 4) -#define RK3028_HPOUTR_DIS (0x0 << 4) -#define RK3028_HPOUTR_INIT_MSK (0x1 << 3) -#define RK3028_HPOUTR_WORK (0x1 << 3) -#define RK3028_HPOUTR_INIT (0x0 << 3) -#define RK3028_HPOUTR_MUTE_SHT (2) -#define RK3028_HPOUTR_MUTE_MSK (0x1 << 2) -#define RK3028_HPOUTR_MUTE_EN (0x0 << 2) -#define RK3028_HPOUTR_MUTE_DIS (0x1 << 2) - -#define RK3028_HPVREF_PWR_SHT (1) -#define RK3028_HPVREF_EN (0x1 << 1) -#define RK3028_HPVREF_DIS (0x0 << 1) -#define RK3028_HPVREF_WORK (0x1 << 0) -#define RK3028_HPVREF_INIT (0x0 << 0) - -/* HPOUT GAIN (0xb4 0xb8) */ -#define RK3028_HPOUT_GAIN_SFT (0) - -/* SELECT CURR prechagrge/discharge (0xbc) */ -#define RK3028_PRE_HPOUT (0x1 << 5) -#define RK3028_DIS_HPOUT (0x0 << 5) -#define RK3028_CUR_10UA_EN (0x0 << 4) -#define RK3028_CUR_10UA_DIS (0x1 << 4) -#define RK3028_CUR_I_EN (0x0 << 3) -#define RK3028_CUR_I_DIS (0x1 << 3) -#define RK3028_CUR_2I_EN (0x0 << 2) -#define RK3028_CUR_2I_DIS (0x1 << 2) -#define RK3028_CUR_4I_EN (0x0 << 0) -#define RK3028_CUR_4I_DIS (0x3 << 0) - -/* PGA AGC control 1 (0xc0 0x100) */ -#define RK3028_PGA_AGC_WAY_MASK (0x1 << 6) -#define RK3028_PGA_AGC_WAY_SFT 6 -#define RK3028_PGA_AGC_WAY_JACK (0x1 << 6) -#define RK3028_PGA_AGC_WAY_NOR (0x0 << 6) - -#define RK3028_PGA_AGC_BK_WAY_SFT 4 -#define RK3028_PGA_AGC_BK_WAY_JACK1 (0x1 << 4) -#define RK3028_PGA_AGC_BK_WAY_NOR (0x0 << 4) -#define RK3028_PGA_AGC_BK_WAY_JACK2 (0x2 << 4) -#define RK3028_PGA_AGC_BK_WAY_JACK3 (0x3 << 4) - -#define RK3028_PGA_AGC_HOLD_T_MASK 0xf -#define RK3028_PGA_AGC_HOLD_T_SFT 0 -#define RK3028_PGA_AGC_HOLD_T_1024 0xa -#define RK3028_PGA_AGC_HOLD_T_512 0x9 -#define RK3028_PGA_AGC_HOLD_T_256 0x8 -#define RK3028_PGA_AGC_HOLD_T_128 0x7 -#define RK3028_PGA_AGC_HOLD_T_64 0x6 -#define RK3028_PGA_AGC_HOLD_T_32 0x5 -#define RK3028_PGA_AGC_HOLD_T_16 0x4 -#define RK3028_PGA_AGC_HOLD_T_8 0x3 -#define RK3028_PGA_AGC_HOLD_T_4 0x2 -#define RK3028_PGA_AGC_HOLD_T_2 0x1 -#define RK3028_PGA_AGC_HOLD_T_0 0x0 - -/* PGA AGC control 2 (0xc4 0x104) */ -#define RK3028_PGA_AGC_GRU_T_MASK (0xf << 4) -#define RK3028_PGA_AGC_GRU_T_SFT 4 -#define RK3028_PGA_AGC_GRU_T_512 (0xa << 4) -#define RK3028_PGA_AGC_GRU_T_256 (0x9 << 4) -#define RK3028_PGA_AGC_GRU_T_128 (0x8 << 4) -#define RK3028_PGA_AGC_GRU_T_64 (0x7 << 4) -#define RK3028_PGA_AGC_GRU_T_32 (0x6 << 4) -#define RK3028_PGA_AGC_GRU_T_16 (0x5 << 4) -#define RK3028_PGA_AGC_GRU_T_8 (0x4 << 4) -#define RK3028_PGA_AGC_GRU_T_4 (0x3 << 4) -#define RK3028_PGA_AGC_GRU_T_2 (0x2 << 4) -#define RK3028_PGA_AGC_GRU_T_1 (0x1 << 4) -#define RK3028_PGA_AGC_GRU_T_0_5 (0x0 << 4) - -#define RK3028_PGA_AGC_GRD_T_MASK 0xf -#define RK3028_PGA_AGC_GRD_T_SFT 0 -#define RK3028_PGA_AGC_GRD_T_128_32 0xa -#define RK3028_PGA_AGC_GRD_T_64_16 0x9 -#define RK3028_PGA_AGC_GRD_T_32_8 0x8 -#define RK3028_PGA_AGC_GRD_T_16_4 0x7 -#define RK3028_PGA_AGC_GRD_T_8_2 0x6 -#define RK3028_PGA_AGC_GRD_T_4_1 0x5 -#define RK3028_PGA_AGC_GRD_T_2_0_512 0x4 -#define RK3028_PGA_AGC_GRD_T_1_0_256 0x3 -#define RK3028_PGA_AGC_GRD_T_0_500_128 0x2 -#define RK3028_PGA_AGC_GRD_T_0_250_64 0x1 -#define RK3028_PGA_AGC_GRD_T_0_125_32 0x0 - -/* PGA AGC control 3 (0xc8 0x108) */ -#define RK3028_PGA_AGC_MODE_MASK (0x1 << 7) -#define RK3028_PGA_AGC_MODE_SFT 7 -#define RK3028_PGA_AGC_MODE_LIMIT (0x1 << 7) -#define RK3028_PGA_AGC_MODE_NOR (0x0 << 7) - -#define RK3028_PGA_AGC_ZO_MASK (0x1 << 6) -#define RK3028_PGA_AGC_ZO_SFT 6 -#define RK3028_PGA_AGC_ZO_EN (0x1 << 6) -#define RK3028_PGA_AGC_ZO_DIS (0x0 << 6) - -#define RK3028_PGA_AGC_REC_MODE_MASK (0x1 << 5) -#define RK3028_PGA_AGC_REC_MODE_SFT 5 -#define RK3028_PGA_AGC_REC_MODE_AC (0x1 << 5) -#define RK3028_PGA_AGC_REC_MODE_RN (0x0 << 5) - -#define RK3028_PGA_AGC_FAST_D_MASK (0x1 << 4) -#define RK3028_PGA_AGC_FAST_D_SFT 4 -#define RK3028_PGA_AGC_FAST_D_EN (0x1 << 4) -#define RK3028_PGA_AGC_FAST_D_DIS (0x0 << 4) - -#define RK3028_PGA_AGC_NG_MASK (0x1 << 3) -#define RK3028_PGA_AGC_NG_SFT 3 -#define RK3028_PGA_AGC_NG_EN (0x1 << 3) -#define RK3028_PGA_AGC_NG_DIS (0x0 << 3) - -#define RK3028_PGA_AGC_NG_THR_MASK 0x7 -#define RK3028_PGA_AGC_NG_THR_SFT 0 -#define RK3028_PGA_AGC_NG_THR_N81DB 0x7 -#define RK3028_PGA_AGC_NG_THR_N75DB 0x6 -#define RK3028_PGA_AGC_NG_THR_N69DB 0x5 -#define RK3028_PGA_AGC_NG_THR_N63DB 0x4 -#define RK3028_PGA_AGC_NG_THR_N57DB 0x3 -#define RK3028_PGA_AGC_NG_THR_N51DB 0x2 -#define RK3028_PGA_AGC_NG_THR_N45DB 0x1 -#define RK3028_PGA_AGC_NG_THR_N39DB 0x0 - -/* PGA AGC Control 4 (0xcc 0x10c) */ -#define RK3028_PGA_AGC_ZO_MODE_MASK (0x1 << 5) -#define RK3028_PGA_AGC_ZO_MODE_SFT 5 -#define RK3028_PGA_AGC_ZO_MODE_UWRC (0x1 << 5) -#define RK3028_PGA_AGC_ZO_MODE_UARC (0x0 << 5) - -#define RK3028_PGA_AGC_VOL_MASK 0x1f -#define RK3028_PGA_AGC_VOL_SFT 0 - -/* PGA ASR Control (0xd0 0x110) */ -#define RK3028_PGA_SLOW_CLK_MASK (0x1 << 3) -#define RK3028_PGA_SLOW_CLK_SFT 3 -#define RK3028_PGA_SLOW_CLK_EN (0x1 << 3) -#define RK3028_PGA_SLOW_CLK_DIS (0x0 << 3) - -#define RK3028_PGA_ASR_MASK 0x7 -#define RK3028_PGA_ASR_SFT 0 -#define RK3028_PGA_ASR_8KHz 0x7 -#define RK3028_PGA_ASR_12KHz 0x6 -#define RK3028_PGA_ASR_16KHz 0x5 -#define RK3028_PGA_ASR_24KHz 0x4 -#define RK3028_PGA_ASR_32KHz 0x3 -#define RK3028_PGA_ASR_441KHz 0x2 -#define RK3028_PGA_ASR_48KHz 0x1 -#define RK3028_PGA_ASR_96KHz 0x0 - -/* PGA AGC Control 5 (0xe4 0x124) */ -#define RK3028_PGA_AGC_MASK (0x1 << 6) -#define RK3028_PGA_AGC_SFT 6 -#define RK3028_PGA_AGC_EN (0x1 << 6) -#define RK3028_PGA_AGC_DIS (0x0 << 6) - -#define RK3028_PGA_AGC_MAX_G_MASK (0x7 << 3) -#define RK3028_PGA_AGC_MAX_G_SFT 3 -#define RK3028_PGA_AGC_MAX_G_28_5DB (0x7 << 3) -#define RK3028_PGA_AGC_MAX_G_22_5DB (0x6 << 3) -#define RK3028_PGA_AGC_MAX_G_16_5DB (0x5 << 3) -#define RK3028_PGA_AGC_MAX_G_10_5DB (0x4 << 3) -#define RK3028_PGA_AGC_MAX_G_4_5DB (0x3 << 3) -#define RK3028_PGA_AGC_MAX_G_N1_5DB (0x2 << 3) -#define RK3028_PGA_AGC_MAX_G_N7_5DB (0x1 << 3) -#define RK3028_PGA_AGC_MAX_G_N13_5DB (0x0 << 3) - -#define RK3028_PGA_AGC_MIN_G_MASK 0x7 -#define RK3028_PGA_AGC_MIN_G_SFT 0 -#define RK3028_PGA_AGC_MIN_G_24DB 0x7 -#define RK3028_PGA_AGC_MIN_G_18DB 0x6 -#define RK3028_PGA_AGC_MIN_G_12DB 0x5 -#define RK3028_PGA_AGC_MIN_G_6DB 0x4 -#define RK3028_PGA_AGC_MIN_G_0DB 0x3 -#define RK3028_PGA_AGC_MIN_G_N6DB 0x2 -#define RK3028_PGA_AGC_MIN_G_N12DB 0x1 -#define RK3028_PGA_AGC_MIN_G_N18DB 0x0 - -enum { - RK3028_HIFI, - RK3028_VOICE, -}; - -enum { - RK3028_MONO = 1, - RK3028_STEREO, -}; - -enum { - OFF, - RCV, - SPK_PATH, - HP_PATH, - HP_NO_MIC, - BT, - SPK_HP, - RING_SPK, - RING_HP, - RING_HP_NO_MIC, - RING_SPK_HP, -}; - -enum { - MIC_OFF, - Main_Mic, - Hands_Free_Mic, - BT_Sco_Mic, -}; - -struct rk3028_reg_val_typ { - unsigned int reg; - unsigned int value; -}; - -struct rk3028_init_bit_typ { - unsigned int reg; - unsigned int power_bit; - unsigned int init_bit; -}; - -bool get_hdmi_state(void); - -struct rk3028_codec_pdata { - int spk_ctl_gpio; - int hp_ctl_gpio; -}; - -#endif //__RK3028_CODEC_H__ diff --git a/sound/soc/rk29/Kconfig b/sound/soc/rk29/Kconfig index 368fbd38149d..eb3d83d94cbc 100755 --- a/sound/soc/rk29/Kconfig +++ b/sound/soc/rk29/Kconfig @@ -295,15 +295,15 @@ config SND_RK_SOC_RK2928 Say Y if you want to add support for SoC audio on rockchip with the RK2928 internal codec. -config SND_RK_SOC_RK3028 +config SND_RK_SOC_RK3026 tristate "SoC I2S Audio support for rockchip - RK3026&R3028A" depends on SND_RK29_SOC && ARCH_RK3026 select SND_RK29_SOC_I2S - select SND_SOC_RK3028 + select SND_SOC_RK3026 select SND_RK29_CODEC_SOC_SLAVE help Say Y if you want to add support for SoC audio on rockchip - with the RK3028 internal codec. + with the RK3026 internal codec. if SND_RK29_SOC_I2S_2CH || SND_RK29_SOC_I2S_8CH || SND_RK_SOC_I2S2_2CH choice diff --git a/sound/soc/rk29/Makefile b/sound/soc/rk29/Makefile index 399329409b98..7bbd6adf6b1b 100755 --- a/sound/soc/rk29/Makefile +++ b/sound/soc/rk29/Makefile @@ -32,7 +32,7 @@ snd-soc-rk616-objs := rk_rk616.o snd-soc-aic3262-objs := rk29_aic3262.o snd-soc-rk2928-objs := rk2928-card.o snd-soc-es8323-objs := rk29_es8323.o -snd-soc-rk3028-objs := rk_rk3028.o +snd-soc-rk3026-objs := rk_rk3026.o snd-soc-hdmi-i2s-objs := rk_hdmi_i2s.o snd-soc-hdmi-spdif-objs := rk_hdmi_spdif.o @@ -58,4 +58,4 @@ obj-$(CONFIG_SND_RK_SOC_HDMI_I2S) += snd-soc-hdmi-i2s.o obj-$(CONFIG_SND_RK_SOC_HDMI_SPDIF) += snd-soc-hdmi-spdif.o obj-$(CONFIG_SND_RK_SOC_RK2928) += snd-soc-rk2928.o obj-$(CONFIG_SND_RK29_SOC_ES8323) += snd-soc-es8323.o -obj-$(CONFIG_SND_RK_SOC_RK3028) += snd-soc-rk3028.o +obj-$(CONFIG_SND_RK_SOC_RK3026) += snd-soc-rk3026.o diff --git a/sound/soc/rk29/rk_rk3028.c b/sound/soc/rk29/rk_rk3028.c deleted file mode 100644 index b6aa4db09f59..000000000000 --- a/sound/soc/rk29/rk_rk3028.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * rk_rk3028.c -- SoC audio for rockchip - * - * Driver for rockchip rk3028 audio - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "../codecs/rk3028_codec.h" -#include "rk29_pcm.h" -#include "rk29_i2s.h" - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif - -static const struct snd_soc_dapm_widget rk_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_MIC("Headset Jack", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_HP("Headphone Jack", NULL), -}; - -static const struct snd_soc_dapm_route rk_audio_map[]={ - - /* Mic Jack --> MIC_IN*/ - {"Mic Bias", NULL, "Mic Jack"}, - {"MICP", NULL, "Mic Bias"}, - {"MICN", NULL, "Mic Bias"}, - - // HP MIC - {"Mic Bias", NULL, "Headset Jack"}, - - {"Ext Spk", NULL, "HPOUTR"}, - {"Ext Spk", NULL, "HPOUTL"}, - - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "HPOUTL"}, -} ; - -static const struct snd_kcontrol_new rk_controls[] = { - SOC_DAPM_PIN_SWITCH("Mic Jack"), - SOC_DAPM_PIN_SWITCH("Headset Jack"), - SOC_DAPM_PIN_SWITCH("Ext Spk"), - SOC_DAPM_PIN_SWITCH("Headphone Jack"), -}; - -static int rk3028_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - snd_soc_add_controls(codec, rk_controls, - ARRAY_SIZE(rk_controls)); - - /* Add specific widgets */ - snd_soc_dapm_new_controls(dapm, rk_dapm_widgets, - ARRAY_SIZE(rk_dapm_widgets)); - /* Set up specific audio path audio_mapnects */ - snd_soc_dapm_add_routes(dapm, rk_audio_map, ARRAY_SIZE(rk_audio_map)); - - snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - snd_soc_dapm_enable_pin(dapm, "Headset Jack"); - snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int rk_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 0; - int ret; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - /* set codec DAI configuration */ - #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - #endif - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); - #endif - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - #endif - #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - #endif - if (ret < 0) - return ret; - - switch(params_rate(params)) { - case 8000: - case 16000: - case 24000: - case 32000: - case 48000: - pll_out = 12288000; - break; - case 11025: - case 22050: - case 44100: - pll_out = 11289600; - break; - default: - DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params)); - return -EINVAL; - break; - } - - #if defined(CONFIG_RK3028_USE_MCLK_12M) - /* MCLK must be 12M when HDMI is in */ - if (get_hdmi_state() && pll_out != 12000000) { - DBG("%s : HDMI is in, don't set sys clk\n",__FUNCTION__); - return 0; - } - #endif - - DBG("Enter:%s, %d, rate=%d\n", __FUNCTION__, __LINE__, params_rate(params)); - - /*Set the system clk for codec*/ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN); - if (ret < 0) { - DBG("rk_hifi_hw_params:failed to set the sysclk for codec side\n"); - return ret; - } - - snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1); - snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3); - - DBG("Enter:%s, %d, pll_out/4/params_rate(params) = %d \n", __FUNCTION__, __LINE__, (pll_out/4)/params_rate(params)); - - return 0; -} - -static int rk_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 0; - int ret; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); - - switch(params_rate(params)) { - case 8000: - case 16000: - case 24000: - case 32000: - case 48000: - pll_out = 12288000; - break; - case 11025: - case 22050: - case 44100: - pll_out = 11289600; - break; - default: - DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params)); - return -EINVAL; - break; - } - - /* MCLK must be 12M when HDMI is in */ - #if defined(CONFIG_RK3028_USE_MCLK_12M) - if (get_hdmi_state() && pll_out != 12000000) { - DBG("%s : HDMI is in, don't set sys clk\n",__FUNCTION__); - return 0; - } - #endif - - //snd_soc_dai_set_pll(codec_dai, RT5625_PLL_MCLK_TO_VSYSCLK, 0, pll_out, 24576000); - - /*Set the system clk for codec*/ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN); - - if (ret < 0) { - printk("rk_voice_hw_params:failed to set the sysclk for codec side\n"); - return ret; - } - - ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); - - return 0; -} - -static struct snd_soc_ops rk3028_hifi_ops = { - .hw_params = rk_hifi_hw_params, -}; - -static struct snd_soc_ops rk3028_voice_ops = { - .hw_params = rk_voice_hw_params, -}; - -static struct snd_soc_dai_link rk_dai[] = { - { - .name = "RK3028 I2S1", - .stream_name = "RK3028 PCM", - .codec_name = "rk3028-codec", - .platform_name = "rockchip-audio", -#if defined(CONFIG_SND_RK29_SOC_I2S_8CH) - .cpu_dai_name = "rk29_i2s.0", -#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH) - .cpu_dai_name = "rk29_i2s.1", -#endif - .codec_dai_name = "rk3028-hifi", - .init = rk3028_init, - .ops = &rk3028_hifi_ops, - }, - { - .name = "RK3028 I2S2", - .stream_name = "RK3028 PCM", - .codec_name = "rk3028-codec", - .platform_name = "rockchip-audio", -#if defined(CONFIG_SND_RK29_SOC_I2S_8CH) - .cpu_dai_name = "rk29_i2s.0", -#elif defined(CONFIG_SND_RK29_SOC_I2S_2CH) - .cpu_dai_name = "rk29_i2s.1", -#endif - .codec_dai_name = "rk3028-voice", - .ops = &rk3028_voice_ops, - }, -}; - -static struct snd_soc_card snd_soc_card_rk = { - .name = "RK_RK3028", - .dai_link = rk_dai, - .num_links = 2, -}; - -static struct platform_device *rk_snd_device; - -static int __init audio_card_init(void) -{ - int ret =0; - - DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); - - rk_snd_device = platform_device_alloc("soc-audio", -1); - if (!rk_snd_device) { - printk("platform device allocation failed\n"); - return -ENOMEM; - } - - platform_set_drvdata(rk_snd_device, &snd_soc_card_rk); - ret = platform_device_add(rk_snd_device); - if (ret) { - printk("platform device add failed\n"); - - platform_device_put(rk_snd_device); - return ret; - } - - return ret; -} - -static void __exit audio_card_exit(void) -{ - platform_device_unregister(rk_snd_device); -} - -module_init(audio_card_init); -module_exit(audio_card_exit); -/* Module information */ -MODULE_AUTHOR("rockchip"); -MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface"); -MODULE_LICENSE("GPL"); -- 2.34.1