From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom
---
kernel/sound/soc/codecs/rk3308_codec.c | 731 ++++++++++++++++----------------------------------------
1 files changed, 211 insertions(+), 520 deletions(-)
diff --git a/kernel/sound/soc/codecs/rk3308_codec.c b/kernel/sound/soc/codecs/rk3308_codec.c
index a6ce7f0..c78752d 100644
--- a/kernel/sound/soc/codecs/rk3308_codec.c
+++ b/kernel/sound/soc/codecs/rk3308_codec.c
@@ -44,7 +44,6 @@
#include <sound/tlv.h>
#include "rk3308_codec.h"
-#include "rk3308_codec_provider.h"
#if defined(CONFIG_DEBUG_FS)
#include <linux/fs.h>
@@ -96,6 +95,7 @@
#define ACODEC_VERSION_A 0xa
#define ACODEC_VERSION_B 0xb
+#define ACODEC_VERSION_C 0xc
enum {
ACODEC_TO_I2S2_8CH = 0,
@@ -194,14 +194,6 @@
int ext_micbias;
int pm_state;
- /* AGC L/R Off/on */
- unsigned int agc_l[ADC_LR_GROUP_MAX];
- unsigned int agc_r[ADC_LR_GROUP_MAX];
-
- /* AGC L/R Approximate Sample Rate */
- unsigned int agc_asr_l[ADC_LR_GROUP_MAX];
- unsigned int agc_asr_r[ADC_LR_GROUP_MAX];
-
/* ADC MIC Mute/Work */
unsigned int mic_mute_l[ADC_LR_GROUP_MAX];
unsigned int mic_mute_r[ADC_LR_GROUP_MAX];
@@ -232,12 +224,6 @@
#endif
};
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_gain_tlv,
- -1800, 150, 2850);
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_max_gain_tlv,
- -1350, 600, 2850);
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_min_gain_tlv,
- -1800, 600, 2400);
static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv,
-1800, 150, 2850);
static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_lineout_gain_tlv,
@@ -263,6 +249,8 @@
static int check_micbias(int micbias);
+static void rk3308_codec_dac_mclk_enable(struct rk3308_codec_priv *rk3308);
+
static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308,
int micbias);
static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308);
@@ -279,14 +267,6 @@
struct snd_ctl_elem_value *ucontrol);
static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol,
@@ -353,18 +333,6 @@
SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text),
};
-/* ALC AGC Switch */
-static const struct soc_enum rk3308_agc_enum_array[] = {
- SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text),
- SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(offon_text), offon_text),
-};
-
/* ADC MIC Mute/Work Switch */
static const struct soc_enum rk3308_mic_mute_enum_array[] = {
SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text),
@@ -375,40 +343,6 @@
SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(mute_text), mute_text),
SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(mute_text), mute_text),
SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(mute_text), mute_text),
-};
-
-/* ALC AGC Approximate Sample Rate */
-#define AGC_ASR_NUM 8
-
-#define AGC_ASR_96KHZ 0
-#define AGC_ASR_48KHZ 1
-#define AGC_ASR_44_1KHZ 2
-#define AGC_ASR_32KHZ 3
-#define AGC_ASR_24KHZ 4
-#define AGC_ASR_16KHZ 5
-#define AGC_ASR_12KHZ 6
-#define AGC_ASR_8KHZ 7
-
-static const char *agc_asr_text[AGC_ASR_NUM] = {
- [AGC_ASR_96KHZ] = "96KHz",
- [AGC_ASR_48KHZ] = "48KHz",
- [AGC_ASR_44_1KHZ] = "44.1KHz",
- [AGC_ASR_32KHZ] = "32KHz",
- [AGC_ASR_24KHZ] = "24KHz",
- [AGC_ASR_16KHZ] = "16KHz",
- [AGC_ASR_12KHZ] = "12KHz",
- [AGC_ASR_8KHZ] = "8KHz",
-};
-
-static const struct soc_enum rk3308_agc_asr_enum_array[] = {
- SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
- SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
};
static const struct snd_kcontrol_new mic_gains_a[] = {
@@ -548,201 +482,6 @@
};
static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = {
- /* ALC AGC Group */
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Volume",
- RK3308_ALC_L_DIG_CON03(0),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Volume",
- RK3308_ALC_R_DIG_CON03(0),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Volume",
- RK3308_ALC_L_DIG_CON03(1),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Volume",
- RK3308_ALC_R_DIG_CON03(1),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Volume",
- RK3308_ALC_L_DIG_CON03(2),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Volume",
- RK3308_ALC_R_DIG_CON03(2),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Volume",
- RK3308_ALC_L_DIG_CON03(3),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Volume",
- RK3308_ALC_R_DIG_CON03(3),
- RK3308_AGC_PGA_GAIN_SFT,
- RK3308_AGC_PGA_GAIN_MIN,
- RK3308_AGC_PGA_GAIN_MAX,
- 0, rk3308_codec_alc_agc_grp_gain_tlv),
-
- /* ALC AGC MAX */
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Max Volume",
- RK3308_ALC_L_DIG_CON09(0),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Max Volume",
- RK3308_ALC_R_DIG_CON09(0),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Max Volume",
- RK3308_ALC_L_DIG_CON09(1),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Max Volume",
- RK3308_ALC_R_DIG_CON09(1),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Max Volume",
- RK3308_ALC_L_DIG_CON09(2),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Max Volume",
- RK3308_ALC_R_DIG_CON09(2),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Max Volume",
- RK3308_ALC_L_DIG_CON09(3),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Max Volume",
- RK3308_ALC_R_DIG_CON09(3),
- RK3308_AGC_MAX_GAIN_PGA_SFT,
- RK3308_AGC_MAX_GAIN_PGA_MIN,
- RK3308_AGC_MAX_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
- /* ALC AGC MIN */
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Min Volume",
- RK3308_ALC_L_DIG_CON09(0),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Min Volume",
- RK3308_ALC_R_DIG_CON09(0),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Min Volume",
- RK3308_ALC_L_DIG_CON09(1),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Min Volume",
- RK3308_ALC_R_DIG_CON09(1),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Min Volume",
- RK3308_ALC_L_DIG_CON09(2),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Min Volume",
- RK3308_ALC_R_DIG_CON09(2),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Min Volume",
- RK3308_ALC_L_DIG_CON09(3),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
- SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Min Volume",
- RK3308_ALC_R_DIG_CON09(3),
- RK3308_AGC_MIN_GAIN_PGA_SFT,
- RK3308_AGC_MIN_GAIN_PGA_MIN,
- RK3308_AGC_MIN_GAIN_PGA_MAX,
- 0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
- /* ALC AGC Switch */
- SOC_ENUM_EXT("ALC AGC Group 0 Left Switch", rk3308_agc_enum_array[0],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 0 Right Switch", rk3308_agc_enum_array[1],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 1 Left Switch", rk3308_agc_enum_array[2],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 1 Right Switch", rk3308_agc_enum_array[3],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 2 Left Switch", rk3308_agc_enum_array[4],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 2 Right Switch", rk3308_agc_enum_array[5],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 3 Left Switch", rk3308_agc_enum_array[6],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
- SOC_ENUM_EXT("ALC AGC Group 3 Right Switch", rk3308_agc_enum_array[7],
- rk3308_codec_agc_get, rk3308_codec_agc_put),
-
- /* ALC AGC Approximate Sample Rate */
- SOC_ENUM_EXT("AGC Group 0 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[0],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 0 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[1],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 1 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[2],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 1 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[3],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 2 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[4],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 2 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[5],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 3 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[6],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
- SOC_ENUM_EXT("AGC Group 3 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[7],
- rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-
/* ADC MICBIAS Voltage */
SOC_ENUM_EXT("ADC MICBIAS Voltage", rk3308_micbias_volts_enum_array[0],
rk3308_codec_micbias_volts_get, rk3308_codec_micbias_volts_put),
@@ -879,156 +618,6 @@
RK3308_DAC_R_HPMIX_GAIN_MAX,
0, rk3308_codec_dac_hpmix_gain_tlv),
};
-
-static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-
- if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
- dev_err(rk3308->plat_dev,
- "%s: Invalid ADC grp: %d\n", __func__, e->reg);
- return -EINVAL;
- }
-
- if (e->shift_l)
- ucontrol->value.integer.value[0] = rk3308->agc_r[e->reg];
- else
- ucontrol->value.integer.value[0] = rk3308->agc_l[e->reg];
-
- return 0;
-}
-
-static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int value = ucontrol->value.integer.value[0];
- int grp = e->reg;
-
- if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
- dev_err(rk3308->plat_dev,
- "%s: Invalid ADC grp: %d\n", __func__, e->reg);
- return -EINVAL;
- }
-
- if (value) {
- /* ALC AGC On */
- if (e->shift_l) {
- /* ALC AGC Right On */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp),
- RK3308_AGC_FUNC_SEL_MSK,
- RK3308_AGC_FUNC_SEL_EN);
- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
- RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
- RK3308_ADC_ALCR_CON_GAIN_PGAR_EN);
-
- rk3308->agc_r[e->reg] = 1;
- } else {
- /* ALC AGC Left On */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp),
- RK3308_AGC_FUNC_SEL_MSK,
- RK3308_AGC_FUNC_SEL_EN);
- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
- RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK,
- RK3308_ADC_ALCL_CON_GAIN_PGAL_EN);
-
- rk3308->agc_l[e->reg] = 1;
- }
- } else {
- /* ALC AGC Off */
- if (e->shift_l) {
- /* ALC AGC Right Off */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp),
- RK3308_AGC_FUNC_SEL_MSK,
- RK3308_AGC_FUNC_SEL_DIS);
- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
- RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
- RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS);
-
- rk3308->agc_r[e->reg] = 0;
- } else {
- /* ALC AGC Left Off */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp),
- RK3308_AGC_FUNC_SEL_MSK,
- RK3308_AGC_FUNC_SEL_DIS);
- regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
- RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK,
- RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS);
-
- rk3308->agc_l[e->reg] = 0;
- }
- }
-
- return 0;
-}
-
-static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int value;
- int grp = e->reg;
-
- if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
- dev_err(rk3308->plat_dev,
- "%s: Invalid ADC grp: %d\n", __func__, e->reg);
- return -EINVAL;
- }
-
- if (e->shift_l) {
- regmap_read(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), &value);
- rk3308->agc_asr_r[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT;
- ucontrol->value.integer.value[0] = rk3308->agc_asr_r[e->reg];
- } else {
- regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), &value);
- rk3308->agc_asr_l[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT;
- ucontrol->value.integer.value[0] = rk3308->agc_asr_l[e->reg];
- }
-
- return 0;
-}
-
-static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
- struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int value;
- int grp = e->reg;
-
- if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
- dev_err(rk3308->plat_dev,
- "%s: Invalid ADC grp: %d\n", __func__, e->reg);
- return -EINVAL;
- }
-
- value = ucontrol->value.integer.value[0] << RK3308_AGC_APPROX_RATE_SFT;
-
- if (e->shift_l) {
- /* ALC AGC Right Approximate Sample Rate */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp),
- RK3308_AGC_APPROX_RATE_MSK,
- value);
- rk3308->agc_asr_r[e->reg] = ucontrol->value.integer.value[0];
- } else {
- /* ALC AGC Left Approximate Sample Rate */
- regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp),
- RK3308_AGC_APPROX_RATE_MSK,
- value);
- rk3308->agc_asr_l[e->reg] = ucontrol->value.integer.value[0];
- }
-
- return 0;
-}
static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1487,15 +1076,25 @@
case SND_SOC_DAIFMT_CBS_CFS:
adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE;
adc_aif2 |= RK3308_ADC_MODE_SLAVE;
- dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE;
- dac_aif2 |= RK3308_DAC_MODE_SLAVE;
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ dac_aif2 |= RK3308BS_DAC_IO_MODE_SLAVE;
+ dac_aif2 |= RK3308BS_DAC_MODE_SLAVE;
+ } else {
+ dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE;
+ dac_aif2 |= RK3308_DAC_MODE_SLAVE;
+ }
is_master = 0;
break;
case SND_SOC_DAIFMT_CBM_CFM:
adc_aif2 |= RK3308_ADC_IO_MODE_MASTER;
adc_aif2 |= RK3308_ADC_MODE_MASTER;
- dac_aif2 |= RK3308_DAC_IO_MODE_MASTER;
- dac_aif2 |= RK3308_DAC_MODE_MASTER;
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ dac_aif2 |= RK3308BS_DAC_IO_MODE_MASTER;
+ dac_aif2 |= RK3308BS_DAC_MODE_MASTER;
+ } else {
+ dac_aif2 |= RK3308_DAC_IO_MODE_MASTER;
+ dac_aif2 |= RK3308_DAC_MODE_MASTER;
+ }
is_master = 1;
break;
default:
@@ -1589,11 +1188,19 @@
RK3308_DAC_I2S_LRC_POL_MSK |
RK3308_DAC_I2S_MODE_MSK,
dac_aif1);
- regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+ RK3308BS_DAC_IO_MODE_MSK |
+ RK3308BS_DAC_MODE_MSK |
+ RK3308_DAC_I2S_BIT_CLK_POL_MSK,
+ dac_aif2);
+ } else {
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
RK3308_DAC_IO_MODE_MSK |
RK3308_DAC_MODE_MSK |
RK3308_DAC_I2S_BIT_CLK_POL_MSK,
dac_aif2);
+ }
return 0;
}
@@ -1729,18 +1336,20 @@
int dgain;
if (mute) {
- for (dgain = 0x2; dgain <= 0x7; dgain++) {
- /*
- * Keep the max -> min digital CIC interpolation
- * filter gain step by step.
- *
- * loud: 0x2; whisper: 0x7
- */
- regmap_update_bits(rk3308->regmap,
- RK3308_DAC_DIG_CON04,
- RK3308_DAC_CIC_IF_GAIN_MSK,
- dgain);
- usleep_range(200, 300); /* estimated value */
+ if (rk3308->codec_ver <= ACODEC_VERSION_B) {
+ for (dgain = 0x2; dgain <= 0x7; dgain++) {
+ /*
+ * Keep the max -> min digital CIC interpolation
+ * filter gain step by step.
+ *
+ * loud: 0x2; whisper: 0x7
+ */
+ regmap_update_bits(rk3308->regmap,
+ RK3308_DAC_DIG_CON04,
+ RK3308_DAC_CIC_IF_GAIN_MSK,
+ dgain);
+ usleep_range(200, 300); /* estimated value */
+ }
}
#if !DEBUG_POP_ALWAYS
@@ -1757,18 +1366,20 @@
if (rk3308->delay_start_play_ms)
msleep(rk3308->delay_start_play_ms);
#endif
- for (dgain = 0x7; dgain >= 0x2; dgain--) {
- /*
- * Keep the min -> max digital CIC interpolation
- * filter gain step by step
- *
- * loud: 0x2; whisper: 0x7
- */
- regmap_update_bits(rk3308->regmap,
- RK3308_DAC_DIG_CON04,
- RK3308_DAC_CIC_IF_GAIN_MSK,
- dgain);
- usleep_range(200, 300); /* estimated value */
+ if (rk3308->codec_ver <= ACODEC_VERSION_B) {
+ for (dgain = 0x7; dgain >= 0x2; dgain--) {
+ /*
+ * Keep the min -> max digital CIC interpolation
+ * filter gain step by step
+ *
+ * loud: 0x2; whisper: 0x7
+ */
+ regmap_update_bits(rk3308->regmap,
+ RK3308_DAC_DIG_CON04,
+ RK3308_DAC_CIC_IF_GAIN_MSK,
+ dgain);
+ usleep_range(200, 300); /* estimated value */
+ }
}
}
}
@@ -1856,6 +1467,14 @@
static int rk3308_codec_dac_lineout_enable(struct rk3308_codec_priv *rk3308)
{
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+ RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL |
+ RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL);
+
+ udelay(20);
+
/* Step 07 */
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
RK3308_DAC_L_LINEOUT_EN |
@@ -1892,11 +1511,22 @@
RK3308_DAC_L_LINEOUT_DIS |
RK3308_DAC_R_LINEOUT_DIS);
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+ RK3308_DAC_L_SEL_DC_FROM_INTERNAL |
+ RK3308_DAC_R_SEL_DC_FROM_INTERNAL);
+
return 0;
}
static int rk3308_codec_dac_hpout_enable(struct rk3308_codec_priv *rk3308)
{
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK |
+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
+ RK3308_DAC_HPOUT_POP_SOUND_L_WORK |
+ RK3308_DAC_HPOUT_POP_SOUND_R_WORK);
udelay(20);
/* Step 07 */
@@ -1952,6 +1582,12 @@
RK3308_DAC_L_HPOUT_MUTE |
RK3308_DAC_R_HPOUT_MUTE);
+ udelay(20);
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+ RK3308_DAC_HPOUT_POP_SOUND_L_MSK |
+ RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
+ RK3308_DAC_HPOUT_POP_SOUND_L_DIS |
+ RK3308_DAC_HPOUT_POP_SOUND_R_DIS);
return 0;
}
@@ -2075,7 +1711,7 @@
udelay(20);
- if (rk3308->codec_ver == ACODEC_VERSION_B &&
+ if (rk3308->codec_ver >= ACODEC_VERSION_B &&
(rk3308->dac_output == DAC_LINEOUT ||
rk3308->dac_output == DAC_LINEOUT_HPOUT)) {
/* Step 04 */
@@ -2146,13 +1782,22 @@
udelay(20);
}
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/* Step 10 */
- regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+ if (rk3308->dac_output == DAC_HPOUT) {
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+ RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+ RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+ RK3308_DAC_L_SEL_DC_FROM_INTERNAL |
+ RK3308_DAC_R_SEL_DC_FROM_INTERNAL);
+ } else {
+ /* LINEOUT and LINEOUT + HPOUT */
+ regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL |
RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL);
+ }
udelay(20);
}
@@ -2352,7 +1997,7 @@
RK3308_DAC_HPOUT_POP_SOUND_R_INIT);
/* Step 15 */
- if (rk3308->codec_ver == ACODEC_VERSION_B &&
+ if (rk3308->codec_ver >= ACODEC_VERSION_B &&
(rk3308->dac_output == DAC_LINEOUT ||
rk3308->dac_output == DAC_LINEOUT_HPOUT)) {
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
@@ -2422,7 +2067,7 @@
RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
RK3308_DAC_HPOUT_POP_SOUND_R_INIT);
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 2. Configure ACODEC_DAC_ANA_CON15[1:0] and
* ACODEC_DAC_ANA_CON15[5:4] to 0x1, to setup dc voltage of
@@ -2443,7 +2088,7 @@
RK3308_ADC_CURRENT_CHARGE_MSK,
RK3308_ADC_SEL_I(0x1));
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 4. Configure the register ACODEC_ADC_ANA_CON14[3:0] to
* 4’b0001.
@@ -2462,7 +2107,7 @@
regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
RK3308_ADC_REF_EN, RK3308_ADC_REF_EN);
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 7. Configure the register ACODEC_ADC_ANA_CON14[4] to 0x1 to
* setup reference voltage
@@ -2484,7 +2129,7 @@
udelay(200);
}
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 9. Change the register ACODEC_ADC_ANA_CON14[3:0] from the 0x1
* to 0xf step by step or configure the
@@ -2509,13 +2154,19 @@
regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
RK3308_ADC_CURRENT_CHARGE_MSK, 0x7c);
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 12. Configure the register ACODEC_DAC_ANA_CON14[6:0] to the
* appropriate value(expect 0x0) for reducing power.
*/
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14,
RK3308_DAC_CURRENT_CHARGE_MSK, 0xf);
+ }
+
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ /* Using large driver strength for HPOUT and LINEOUT */
+ regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON07, 0x11);
+ regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON08, 0x11);
}
return 0;
@@ -2537,7 +2188,7 @@
RK3308_ADC_CURRENT_CHARGE_MSK,
RK3308_ADC_SEL_I(0x1));
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 2. Configure the register ACODEC_DAC_ANA_CON14[3:0] to
* 4’b0001.
@@ -2552,7 +2203,7 @@
RK3308_ADC_REF_EN,
RK3308_ADC_REF_DIS);
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/* 4. Configure the register ACODEC_DAC_ANA_CON14[7] to 0x0 */
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14,
RK3308_DAC_VCM_LINEOUT_EN,
@@ -2571,7 +2222,7 @@
udelay(200);
}
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/*
* 6. Change the register ACODEC_DAC_ANA_CON14[3:0] from the 0x1
* to 0xf step by step or configure the
@@ -2600,6 +2251,9 @@
static int rk3308_codec_headset_detect_enable(struct rk3308_codec_priv *rk3308)
{
+ if (rk3308->codec_ver == ACODEC_VERSION_C)
+ rk3308_codec_dac_mclk_enable(rk3308);
+
/*
* Set ACODEC_DAC_ANA_CON0[1] to 0x1, to enable the headset insert
* detection
@@ -2792,7 +2446,7 @@
static bool handle_loopback(struct rk3308_codec_priv *rk3308)
{
/* The version B doesn't need to handle loopback. */
- if (rk3308->codec_ver == ACODEC_VERSION_B)
+ if (rk3308->codec_ver >= ACODEC_VERSION_B)
return false;
switch (rk3308->loopback_grp) {
@@ -3426,6 +3080,9 @@
static void rk3308_codec_dac_mclk_disable(struct rk3308_codec_priv *rk3308)
{
+ if (!rk3308->no_hp_det && rk3308->codec_ver == ACODEC_VERSION_C)
+ return;
+
regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
RK3308_DAC_MCLK_MSK,
RK3308_DAC_MCLK_DIS);
@@ -3849,31 +3506,49 @@
RK3308_ADC_CH2_ALC_GAIN_0DB);
}
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ /* recover ADC digtial volume to 0dB */
+ for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+ /* DIG_VOL: -97dB ~ +32dB */
+ regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON05(grp),
+ RK3308_ADC_DIG_VOL_CON_L(RK3308_ADC_DIG_VOL_0DB));
+ regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON06(grp),
+ RK3308_ADC_DIG_VOL_CON_R(RK3308_ADC_DIG_VOL_0DB));
+ }
+ }
+
/* Prepare DAC gains */
/* Step 15, set HPMIX default gains */
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12,
RK3308_DAC_L_HPMIX_GAIN_MSK |
RK3308_DAC_R_HPMIX_GAIN_MSK,
- RK3308_DAC_L_HPMIX_GAIN_NDB_6 |
- RK3308_DAC_R_HPMIX_GAIN_NDB_6);
+ RK3308_DAC_L_HPMIX_GAIN_0DB |
+ RK3308_DAC_R_HPMIX_GAIN_0DB);
/* Step 18, set HPOUT default gains */
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05,
RK3308_DAC_L_HPOUT_GAIN_MSK,
- RK3308_DAC_L_HPOUT_GAIN_NDB_39);
+ RK3308_DAC_L_HPOUT_GAIN_0DB);
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06,
RK3308_DAC_R_HPOUT_GAIN_MSK,
- RK3308_DAC_R_HPOUT_GAIN_NDB_39);
+ RK3308_DAC_R_HPOUT_GAIN_0DB);
/* Using the same gain to HPOUT LR channels */
- rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_NDB_39;
+ rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_0DB;
+ rk3308->hpout_r_dgain = RK3308_DAC_R_HPOUT_GAIN_0DB;
/* Step 19, set LINEOUT default gains */
regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
RK3308_DAC_L_LINEOUT_GAIN_MSK |
RK3308_DAC_R_LINEOUT_GAIN_MSK,
- RK3308_DAC_L_LINEOUT_GAIN_NDB_6 |
- RK3308_DAC_R_LINEOUT_GAIN_NDB_6);
+ RK3308_DAC_L_LINEOUT_GAIN_0DB |
+ RK3308_DAC_R_LINEOUT_GAIN_0DB);
+
+ if (rk3308->codec_ver == ACODEC_VERSION_C) {
+ /* recover DAC digtial gain to 0dB */
+ regmap_write(rk3308->regmap, RK3308BS_DAC_DIG_CON04,
+ RK3308BS_DAC_DIG_GAIN(RK3308BS_DAC_DIG_0DB));
+ }
return 0;
}
@@ -3935,7 +3610,7 @@
{
int ret;
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
ret = snd_soc_add_component_controls(rk3308->component,
mic_gains_b,
ARRAY_SIZE(mic_gains_b));
@@ -4020,13 +3695,8 @@
{
int grp;
- for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+ for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++)
rk3308->hpf_cutoff[grp] = 0;
- rk3308->agc_l[grp] = 0;
- rk3308->agc_r[grp] = 0;
- rk3308->agc_asr_l[grp] = AGC_ASR_96KHZ;
- rk3308->agc_asr_r[grp] = AGC_ASR_96KHZ;
- }
rk3308_codec_dapm_mic_gains(rk3308);
@@ -4089,6 +3759,28 @@
regcache_sync(rk3308->regmap);
}
+static int rk3308_codec_set_jack(struct snd_soc_component *component,
+ struct snd_soc_jack *jack, void *data)
+{
+ struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+ /* Return directly if the DUT don't need to support headphone detection */
+ if (rk3308->no_hp_det)
+ return 0;
+
+ rk3308->hpdet_jack = jack;
+
+ /* To detect jack once during startup */
+ disable_irq_nosync(rk3308->irq);
+ queue_delayed_work(system_power_efficient_wq,
+ &rk3308->hpdet_work, msecs_to_jiffies(10));
+
+ dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n",
+ __func__);
+
+ return 0;
+}
+
static const struct snd_soc_component_driver soc_codec_dev_rk3308 = {
.probe = rk3308_probe,
.remove = rk3308_remove,
@@ -4097,6 +3789,7 @@
.set_bias_level = rk3308_set_bias_level,
.controls = rk3308_codec_dapm_controls,
.num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls),
+ .set_jack = rk3308_codec_set_jack,
};
static const struct reg_default rk3308_codec_reg_defaults[] = {
@@ -4118,12 +3811,15 @@
{
struct rk3308_codec_priv *rk3308 =
container_of(work, struct rk3308_codec_priv, hpdet_work.work);
- unsigned int val;
+ unsigned int val, headphone_con = RK3308_CODEC_HEADPHONE_CON;
int need_poll = 0, need_irq = 0;
int need_report = 0, report_type = 0;
int dac_output = DAC_LINEOUT;
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver == ACODEC_VERSION_C)
+ headphone_con = RK3308BS_CODEC_HEADPHONE_CON;
+
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
/* Check headphone plugged/unplugged directly. */
regmap_read(rk3308->detect_grf,
DETECT_GRF_ACODEC_HPDET_STATUS, &val);
@@ -4164,7 +3860,7 @@
}
/* Check headphone unplugged via poll. */
- regmap_read(rk3308->regmap, RK3308_DAC_DIG_CON14, &val);
+ regmap_read(rk3308->regmap, headphone_con, &val);
if (rk3308->hp_jack_reversed) {
if (!val) {
@@ -4259,26 +3955,6 @@
&rk3308->hpdet_work, msecs_to_jiffies(10));
return IRQ_HANDLED;
-}
-
-void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_component *component,
- struct snd_soc_jack *hpdet_jack);
-EXPORT_SYMBOL_GPL(rk3308_codec_set_jack_detect_cb);
-
-static void rk3308_codec_set_jack_detect(struct snd_soc_component *component,
- struct snd_soc_jack *hpdet_jack)
-{
- struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-
- rk3308->hpdet_jack = hpdet_jack;
-
- /* To detect jack once during startup */
- disable_irq_nosync(rk3308->irq);
- queue_delayed_work(system_power_efficient_wq,
- &rk3308->hpdet_work, msecs_to_jiffies(10));
-
- dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n",
- __func__);
}
static const struct regmap_config rk3308_codec_regmap_config = {
@@ -4721,6 +4397,16 @@
return 0;
}
+static void rk3308_codec_sysfs_exit(struct rk3308_codec_priv *rk3308)
+{
+ struct device *dev = &rk3308->dev;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(acodec_attrs); i++)
+ device_remove_file(dev, &acodec_attrs[i]);
+ device_unregister(dev);
+}
+
#if defined(CONFIG_DEBUG_FS)
static int rk3308_codec_debugfs_reg_show(struct seq_file *s, void *v)
{
@@ -4808,6 +4494,9 @@
case 0x3308:
rk3308->codec_ver = ACODEC_VERSION_B;
break;
+ case 0x3308c:
+ rk3308->codec_ver = ACODEC_VERSION_C;
+ break;
default:
pr_err("Unknown chip_id: %d / 0x%x\n", chip_id, chip_id);
return -EFAULT;
@@ -4836,6 +4525,10 @@
return PTR_ERR(rk3308->grf);
}
+ ret = rk3308_codec_get_version(rk3308);
+ if (ret < 0)
+ return dev_err_probe(&pdev->dev, ret, "Failed to get acodec version\n");
+
ret = rk3308_codec_sysfs_init(pdev, rk3308);
if (ret < 0) {
dev_err(&pdev->dev, "Sysfs init failed\n");
@@ -4857,7 +4550,7 @@
if (IS_ERR(rk3308->reset)) {
ret = PTR_ERR(rk3308->reset);
if (ret != -ENOENT)
- return ret;
+ goto out_sysfs;
dev_dbg(&pdev->dev, "No reset control found\n");
rk3308->reset = NULL;
@@ -4870,7 +4563,7 @@
} else if (IS_ERR(rk3308->hp_ctl_gpio)) {
ret = PTR_ERR(rk3308->hp_ctl_gpio);
dev_err(&pdev->dev, "Unable to claim gpio hp-ctl\n");
- return ret;
+ goto out_sysfs;
}
rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk-ctl",
@@ -4881,7 +4574,7 @@
} else if (IS_ERR(rk3308->spk_ctl_gpio)) {
ret = PTR_ERR(rk3308->spk_ctl_gpio);
dev_err(&pdev->dev, "Unable to claim gpio spk-ctl\n");
- return ret;
+ goto out_sysfs;
}
rk3308->pa_drv_gpio = devm_gpiod_get_optional(&pdev->dev, "pa-drv",
@@ -4892,7 +4585,7 @@
} else if (IS_ERR(rk3308->pa_drv_gpio)) {
ret = PTR_ERR(rk3308->pa_drv_gpio);
dev_err(&pdev->dev, "Unable to claim gpio pa-drv\n");
- return ret;
+ goto out_sysfs;
}
if (rk3308->pa_drv_gpio) {
@@ -4914,37 +4607,40 @@
rk3308->pclk = devm_clk_get(&pdev->dev, "acodec");
if (IS_ERR(rk3308->pclk)) {
dev_err(&pdev->dev, "Can't get acodec pclk\n");
- return PTR_ERR(rk3308->pclk);
+ ret = PTR_ERR(rk3308->pclk);
+ goto out_sysfs;
}
rk3308->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
if (IS_ERR(rk3308->mclk_rx)) {
dev_err(&pdev->dev, "Can't get acodec mclk_rx\n");
- return PTR_ERR(rk3308->mclk_rx);
+ ret = PTR_ERR(rk3308->mclk_rx);
+ goto out_sysfs;
}
rk3308->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
if (IS_ERR(rk3308->mclk_tx)) {
dev_err(&pdev->dev, "Can't get acodec mclk_tx\n");
- return PTR_ERR(rk3308->mclk_tx);
+ ret = PTR_ERR(rk3308->mclk_tx);
+ goto out_sysfs;
}
ret = clk_prepare_enable(rk3308->pclk);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret);
- return ret;
+ goto out_sysfs;
}
ret = clk_prepare_enable(rk3308->mclk_rx);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable i2s mclk_rx: %d\n", ret);
- return ret;
+ goto out_pclk;
}
ret = clk_prepare_enable(rk3308->mclk_tx);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to enable i2s mclk_tx: %d\n", ret);
- return ret;
+ goto out_mclk_rx;
}
rk3308_codec_check_micbias(rk3308, np);
@@ -4979,28 +4675,21 @@
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "Failed to read loopback property: %d\n",
ret);
- return ret;
+ goto failed;
}
ret = rk3308_codec_adc_grps_route(rk3308, np);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to route ADC groups: %d\n",
ret);
- return ret;
+ goto failed;
}
ret = rk3308_codec_setup_en_always_adcs(rk3308, np);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to setup enabled always ADCs: %d\n",
ret);
- return ret;
- }
-
- ret = rk3308_codec_get_version(rk3308);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to get acodec version: %d\n",
- ret);
- return ret;
+ goto failed;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -5022,7 +4711,7 @@
if (!rk3308->no_hp_det) {
int index = 0;
- if (rk3308->codec_ver == ACODEC_VERSION_B)
+ if (rk3308->codec_ver >= ACODEC_VERSION_B)
index = 1;
rk3308->irq = platform_get_irq(pdev, index);
@@ -5043,13 +4732,14 @@
goto failed;
}
- if (rk3308->codec_ver == ACODEC_VERSION_B) {
+ if (rk3308->codec_ver >= ACODEC_VERSION_B) {
rk3308->detect_grf =
syscon_regmap_lookup_by_phandle(np, "rockchip,detect-grf");
if (IS_ERR(rk3308->detect_grf)) {
dev_err(&pdev->dev,
"Missing 'rockchip,detect-grf' property\n");
- return PTR_ERR(rk3308->detect_grf);
+ ret = PTR_ERR(rk3308->detect_grf);
+ goto failed;
}
/* Configure filter count and enable hpdet irq. */
@@ -5061,8 +4751,6 @@
(HPDET_BOTH_NEG_POS << 16) |
HPDET_BOTH_NEG_POS);
}
-
- rk3308_codec_set_jack_detect_cb = rk3308_codec_set_jack_detect;
}
if (rk3308->codec_ver == ACODEC_VERSION_A)
@@ -5086,10 +4774,13 @@
return ret;
failed:
- clk_disable_unprepare(rk3308->mclk_rx);
clk_disable_unprepare(rk3308->mclk_tx);
+out_mclk_rx:
+ clk_disable_unprepare(rk3308->mclk_rx);
+out_pclk:
clk_disable_unprepare(rk3308->pclk);
- device_unregister(&rk3308->dev);
+out_sysfs:
+ rk3308_codec_sysfs_exit(rk3308);
return ret;
}
--
Gitblit v1.6.2