Loading sound/soc/codecs/rt5645.c +137 −2 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,8 @@ #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) #define RT5645_HWEQ_NUM 57 static const struct regmap_range_cfg rt5645_ranges[] = { static const struct regmap_range_cfg rt5645_ranges[] = { { { .name = "PR", .name = "PR", Loading Loading @@ -224,6 +226,11 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, { 0xff, 0x6308 }, }; }; struct rt5645_eq_param_s { unsigned short reg; unsigned short val; }; static const char *const rt5645_supply_names[] = { static const char *const rt5645_supply_names[] = { "avdd", "avdd", "cpvdd", "cpvdd", Loading @@ -240,6 +247,7 @@ struct rt5645_priv { struct snd_soc_jack *btn_jack; struct snd_soc_jack *btn_jack; struct delayed_work jack_detect_work; struct delayed_work jack_detect_work; struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; struct rt5645_eq_param_s *eq_param; int codec_type; int codec_type; int sysclk; int sysclk; Loading Loading @@ -469,6 +477,94 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) ); ); /* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */ static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv, 0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0), 5, 5, TLV_DB_SCALE_ITEM(82, 0, 0), 6, 6, TLV_DB_SCALE_ITEM(158, 0, 0), 7, 7, TLV_DB_SCALE_ITEM(228, 0, 0) ); static int rt5645_hweq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s); return 0; } static int rt5645_hweq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); struct rt5645_eq_param_s *eq_param = (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg); eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val); } return 0; } static bool rt5645_validate_hweq(unsigned short reg) { if ((reg >= 0x1a4 && reg <= 0x1cd) | (reg >= 0x1e5 && reg <= 0x1f8) | (reg == RT5645_EQ_CTRL2)) return true; return false; } static int rt5645_hweq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); struct rt5645_eq_param_s *eq_param = (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { eq_param[i].reg = be16_to_cpu(eq_param[i].reg); eq_param[i].val = be16_to_cpu(eq_param[i].val); } /* The final setting of the table should be RT5645_EQ_CTRL2 */ for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) { if (eq_param[i].reg == 0) continue; else if (eq_param[i].reg != RT5645_EQ_CTRL2) return 0; else break; } for (i = 0; i < RT5645_HWEQ_NUM; i++) { if (!rt5645_validate_hweq(eq_param[i].reg) && eq_param[i].reg != 0) return 0; else if (eq_param[i].reg == 0) break; } memcpy(rt5645->eq_param, eq_param, RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s)); return 0; } #define RT5645_HWEQ(xname) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = rt5645_hweq_info, \ .get = rt5645_hweq_get, \ .put = rt5645_hweq_put \ } static const struct snd_kcontrol_new rt5645_snd_controls[] = { static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, Loading @@ -476,6 +572,10 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), /* ClassD modulator Speaker Gain Ratio */ SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO, RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv), /* Headphone Output Volume */ /* Headphone Output Volume */ SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), Loading Loading @@ -529,6 +629,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* I2S2 function select */ /* I2S2 function select */ SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 1, 1), 1, 1), RT5645_HWEQ("Speaker HWEQ"), }; }; /** /** Loading Loading @@ -619,6 +720,22 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, } } static int rt5645_enable_hweq(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { if (rt5645_validate_hweq(rt5645->eq_param[i].reg)) regmap_write(rt5645->regmap, rt5645->eq_param[i].reg, rt5645->eq_param[i].val); else break; } return 0; } /** /** * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters * @codec: SoC audio codec device. * @codec: SoC audio codec device. Loading Loading @@ -1523,6 +1640,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w, switch (event) { switch (event) { case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU: rt5645_enable_hweq(codec); snd_soc_update_bits(codec, RT5645_PWR_DIG1, snd_soc_update_bits(codec, RT5645_PWR_DIG1, RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D_L, RT5645_PWR_CLS_D_L, Loading @@ -1531,6 +1649,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w, break; break; case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD: snd_soc_write(codec, RT5645_EQ_CTRL2, 0); snd_soc_update_bits(codec, RT5645_PWR_DIG1, snd_soc_update_bits(codec, RT5645_PWR_DIG1, RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D_L, 0); RT5645_PWR_CLS_D_L, 0); Loading Loading @@ -2733,6 +2852,10 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, RT5645_PWR_ANLG1, snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_FV1 | RT5645_PWR_FV2, RT5645_PWR_FV1 | RT5645_PWR_FV2, RT5645_PWR_FV1 | RT5645_PWR_FV2); RT5645_PWR_FV1 | RT5645_PWR_FV2); if (rt5645->en_button_func && snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) queue_delayed_work(system_power_efficient_wq, &rt5645->jack_detect_work, msecs_to_jiffies(0)); break; break; case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF: Loading Loading @@ -3044,6 +3167,9 @@ static int rt5645_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm); } } rt5645->eq_param = devm_kzalloc(codec->dev, RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); return 0; return 0; } } Loading Loading @@ -3104,7 +3230,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = { .capture = { .capture = { .stream_name = "AIF1 Capture", .stream_name = "AIF1 Capture", .channels_min = 1, .channels_min = 1, .channels_max = 2, .channels_max = 4, .rates = RT5645_STEREO_RATES, .rates = RT5645_STEREO_RATES, .formats = RT5645_FORMATS, .formats = RT5645_FORMATS, }, }, Loading Loading @@ -3215,6 +3341,13 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"), DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"), }, }, }, }, { .ident = "Google Reks", .callback = strago_quirk_cb, .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Reks"), }, }, { } { } }; }; Loading @@ -3232,7 +3365,7 @@ static int buddy_quirk_cb(const struct dmi_system_id *id) return 1; return 1; } } static struct dmi_system_id dmi_platform_intel_broadwell[] __initdata = { static struct dmi_system_id dmi_platform_intel_broadwell[] = { { { .ident = "Chrome Buddy", .ident = "Chrome Buddy", .callback = buddy_quirk_cb, .callback = buddy_quirk_cb, Loading Loading @@ -3505,6 +3638,8 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c) RT5645_CBJ_MN_JD); RT5645_CBJ_MN_JD); regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, 0); 0); msleep(20); regmap_write(rt5645->regmap, RT5645_RESET, 0); } } static struct i2c_driver rt5645_i2c_driver = { static struct i2c_driver rt5645_i2c_driver = { Loading sound/soc/codecs/rt5645.h +14 −10 Original line number Original line Diff line number Diff line Loading @@ -621,14 +621,14 @@ #define RT5645_G_OM_L_SM_L_SFT 6 #define RT5645_G_OM_L_SM_L_SFT 6 #define RT5645_M_BST1_L_SM_L (0x1 << 5) #define RT5645_M_BST1_L_SM_L (0x1 << 5) #define RT5645_M_BST1_L_SM_L_SFT 5 #define RT5645_M_BST1_L_SM_L_SFT 5 #define RT5645_M_BST3_L_SM_L (0x1 << 4) #define RT5645_M_BST3_L_SM_L_SFT 4 #define RT5645_M_IN_L_SM_L (0x1 << 3) #define RT5645_M_IN_L_SM_L (0x1 << 3) #define RT5645_M_IN_L_SM_L_SFT 3 #define RT5645_M_IN_L_SM_L_SFT 3 #define RT5645_M_DAC_L1_SM_L (0x1 << 1) #define RT5645_M_DAC_L1_SM_L_SFT 1 #define RT5645_M_DAC_L2_SM_L (0x1 << 2) #define RT5645_M_DAC_L2_SM_L (0x1 << 2) #define RT5645_M_DAC_L2_SM_L_SFT 2 #define RT5645_M_DAC_L2_SM_L_SFT 2 #define RT5645_M_BST3_L_SM_L (0x1 << 4) #define RT5645_M_DAC_L1_SM_L (0x1 << 1) #define RT5645_M_BST3_L_SM_L_SFT 4 #define RT5645_M_DAC_L1_SM_L_SFT 1 /* SPK Right Mixer Control (0x47) */ /* SPK Right Mixer Control (0x47) */ #define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) #define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) Loading @@ -643,14 +643,14 @@ #define RT5645_G_OM_R_SM_R_SFT 6 #define RT5645_G_OM_R_SM_R_SFT 6 #define RT5645_M_BST2_R_SM_R (0x1 << 5) #define RT5645_M_BST2_R_SM_R (0x1 << 5) #define RT5645_M_BST2_R_SM_R_SFT 5 #define RT5645_M_BST2_R_SM_R_SFT 5 #define RT5645_M_BST3_R_SM_R (0x1 << 4) #define RT5645_M_BST3_R_SM_R_SFT 4 #define RT5645_M_IN_R_SM_R (0x1 << 3) #define RT5645_M_IN_R_SM_R (0x1 << 3) #define RT5645_M_IN_R_SM_R_SFT 3 #define RT5645_M_IN_R_SM_R_SFT 3 #define RT5645_M_DAC_R1_SM_R (0x1 << 1) #define RT5645_M_DAC_R1_SM_R_SFT 1 #define RT5645_M_DAC_R2_SM_R (0x1 << 2) #define RT5645_M_DAC_R2_SM_R (0x1 << 2) #define RT5645_M_DAC_R2_SM_R_SFT 2 #define RT5645_M_DAC_R2_SM_R_SFT 2 #define RT5645_M_BST3_R_SM_R (0x1 << 4) #define RT5645_M_DAC_R1_SM_R (0x1 << 1) #define RT5645_M_BST3_R_SM_R_SFT 4 #define RT5645_M_DAC_R1_SM_R_SFT 1 /* SPOLMIX Control (0x48) */ /* SPOLMIX Control (0x48) */ #define RT5645_M_DAC_L1_SPM_L (0x1 << 15) #define RT5645_M_DAC_L1_SPM_L (0x1 << 15) Loading @@ -670,13 +670,17 @@ #define RT5645_M_SV_R_SPM_R (0x1 << 0) #define RT5645_M_SV_R_SPM_R (0x1 << 0) #define RT5645_M_SV_R_SPM_R_SFT 0 #define RT5645_M_SV_R_SPM_R_SFT 0 /* SPOMIX Ratio Control (0x4a) */ #define RT5645_SPK_G_CLSD_MASK (0x7 << 0) #define RT5645_SPK_G_CLSD_SFT 0 /* Mono Output Mixer Control (0x4c) */ /* Mono Output Mixer Control (0x4c) */ #define RT5645_G_MONOMIX_MASK (0x1 << 10) #define RT5645_G_MONOMIX_SFT 10 #define RT5645_M_OV_L_MM (0x1 << 9) #define RT5645_M_OV_L_MM (0x1 << 9) #define RT5645_M_OV_L_MM_SFT 9 #define RT5645_M_OV_L_MM_SFT 9 #define RT5645_M_DAC_L2_MA (0x1 << 8) #define RT5645_M_DAC_L2_MA (0x1 << 8) #define RT5645_M_DAC_L2_MA_SFT 8 #define RT5645_M_DAC_L2_MA_SFT 8 #define RT5645_G_MONOMIX_MASK (0x1 << 10) #define RT5645_G_MONOMIX_SFT 10 #define RT5645_M_BST2_MM (0x1 << 4) #define RT5645_M_BST2_MM (0x1 << 4) #define RT5645_M_BST2_MM_SFT 4 #define RT5645_M_BST2_MM_SFT 4 #define RT5645_M_DAC_R1_MM (0x1 << 3) #define RT5645_M_DAC_R1_MM (0x1 << 3) Loading Loading
sound/soc/codecs/rt5645.c +137 −2 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,8 @@ #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) #define RT5645_HWEQ_NUM 57 static const struct regmap_range_cfg rt5645_ranges[] = { static const struct regmap_range_cfg rt5645_ranges[] = { { { .name = "PR", .name = "PR", Loading Loading @@ -224,6 +226,11 @@ static const struct reg_default rt5645_reg[] = { { 0xff, 0x6308 }, { 0xff, 0x6308 }, }; }; struct rt5645_eq_param_s { unsigned short reg; unsigned short val; }; static const char *const rt5645_supply_names[] = { static const char *const rt5645_supply_names[] = { "avdd", "avdd", "cpvdd", "cpvdd", Loading @@ -240,6 +247,7 @@ struct rt5645_priv { struct snd_soc_jack *btn_jack; struct snd_soc_jack *btn_jack; struct delayed_work jack_detect_work; struct delayed_work jack_detect_work; struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; struct rt5645_eq_param_s *eq_param; int codec_type; int codec_type; int sysclk; int sysclk; Loading Loading @@ -469,6 +477,94 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv, 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) ); ); /* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */ static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv, 0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0), 5, 5, TLV_DB_SCALE_ITEM(82, 0, 0), 6, 6, TLV_DB_SCALE_ITEM(158, 0, 0), 7, 7, TLV_DB_SCALE_ITEM(228, 0, 0) ); static int rt5645_hweq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s); return 0; } static int rt5645_hweq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); struct rt5645_eq_param_s *eq_param = (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg); eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val); } return 0; } static bool rt5645_validate_hweq(unsigned short reg) { if ((reg >= 0x1a4 && reg <= 0x1cd) | (reg >= 0x1e5 && reg <= 0x1f8) | (reg == RT5645_EQ_CTRL2)) return true; return false; } static int rt5645_hweq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); struct rt5645_eq_param_s *eq_param = (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { eq_param[i].reg = be16_to_cpu(eq_param[i].reg); eq_param[i].val = be16_to_cpu(eq_param[i].val); } /* The final setting of the table should be RT5645_EQ_CTRL2 */ for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) { if (eq_param[i].reg == 0) continue; else if (eq_param[i].reg != RT5645_EQ_CTRL2) return 0; else break; } for (i = 0; i < RT5645_HWEQ_NUM; i++) { if (!rt5645_validate_hweq(eq_param[i].reg) && eq_param[i].reg != 0) return 0; else if (eq_param[i].reg == 0) break; } memcpy(rt5645->eq_param, eq_param, RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s)); return 0; } #define RT5645_HWEQ(xname) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = rt5645_hweq_info, \ .get = rt5645_hweq_get, \ .put = rt5645_hweq_put \ } static const struct snd_kcontrol_new rt5645_snd_controls[] = { static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, Loading @@ -476,6 +572,10 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), /* ClassD modulator Speaker Gain Ratio */ SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO, RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv), /* Headphone Output Volume */ /* Headphone Output Volume */ SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), Loading Loading @@ -529,6 +629,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* I2S2 function select */ /* I2S2 function select */ SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 1, 1), 1, 1), RT5645_HWEQ("Speaker HWEQ"), }; }; /** /** Loading Loading @@ -619,6 +720,22 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source, } } static int rt5645_enable_hweq(struct snd_soc_codec *codec) { struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); int i; for (i = 0; i < RT5645_HWEQ_NUM; i++) { if (rt5645_validate_hweq(rt5645->eq_param[i].reg)) regmap_write(rt5645->regmap, rt5645->eq_param[i].reg, rt5645->eq_param[i].val); else break; } return 0; } /** /** * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters * @codec: SoC audio codec device. * @codec: SoC audio codec device. Loading Loading @@ -1523,6 +1640,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w, switch (event) { switch (event) { case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU: rt5645_enable_hweq(codec); snd_soc_update_bits(codec, RT5645_PWR_DIG1, snd_soc_update_bits(codec, RT5645_PWR_DIG1, RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D_L, RT5645_PWR_CLS_D_L, Loading @@ -1531,6 +1649,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w, break; break; case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD: snd_soc_write(codec, RT5645_EQ_CTRL2, 0); snd_soc_update_bits(codec, RT5645_PWR_DIG1, snd_soc_update_bits(codec, RT5645_PWR_DIG1, RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | RT5645_PWR_CLS_D_L, 0); RT5645_PWR_CLS_D_L, 0); Loading Loading @@ -2733,6 +2852,10 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, RT5645_PWR_ANLG1, snd_soc_update_bits(codec, RT5645_PWR_ANLG1, RT5645_PWR_FV1 | RT5645_PWR_FV2, RT5645_PWR_FV1 | RT5645_PWR_FV2, RT5645_PWR_FV1 | RT5645_PWR_FV2); RT5645_PWR_FV1 | RT5645_PWR_FV2); if (rt5645->en_button_func && snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) queue_delayed_work(system_power_efficient_wq, &rt5645->jack_detect_work, msecs_to_jiffies(0)); break; break; case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF: Loading Loading @@ -3044,6 +3167,9 @@ static int rt5645_probe(struct snd_soc_codec *codec) snd_soc_dapm_sync(dapm); snd_soc_dapm_sync(dapm); } } rt5645->eq_param = devm_kzalloc(codec->dev, RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); return 0; return 0; } } Loading Loading @@ -3104,7 +3230,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = { .capture = { .capture = { .stream_name = "AIF1 Capture", .stream_name = "AIF1 Capture", .channels_min = 1, .channels_min = 1, .channels_max = 2, .channels_max = 4, .rates = RT5645_STEREO_RATES, .rates = RT5645_STEREO_RATES, .formats = RT5645_FORMATS, .formats = RT5645_FORMATS, }, }, Loading Loading @@ -3215,6 +3341,13 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"), DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"), }, }, }, }, { .ident = "Google Reks", .callback = strago_quirk_cb, .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "Reks"), }, }, { } { } }; }; Loading @@ -3232,7 +3365,7 @@ static int buddy_quirk_cb(const struct dmi_system_id *id) return 1; return 1; } } static struct dmi_system_id dmi_platform_intel_broadwell[] __initdata = { static struct dmi_system_id dmi_platform_intel_broadwell[] = { { { .ident = "Chrome Buddy", .ident = "Chrome Buddy", .callback = buddy_quirk_cb, .callback = buddy_quirk_cb, Loading Loading @@ -3505,6 +3638,8 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c) RT5645_CBJ_MN_JD); RT5645_CBJ_MN_JD); regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, 0); 0); msleep(20); regmap_write(rt5645->regmap, RT5645_RESET, 0); } } static struct i2c_driver rt5645_i2c_driver = { static struct i2c_driver rt5645_i2c_driver = { Loading
sound/soc/codecs/rt5645.h +14 −10 Original line number Original line Diff line number Diff line Loading @@ -621,14 +621,14 @@ #define RT5645_G_OM_L_SM_L_SFT 6 #define RT5645_G_OM_L_SM_L_SFT 6 #define RT5645_M_BST1_L_SM_L (0x1 << 5) #define RT5645_M_BST1_L_SM_L (0x1 << 5) #define RT5645_M_BST1_L_SM_L_SFT 5 #define RT5645_M_BST1_L_SM_L_SFT 5 #define RT5645_M_BST3_L_SM_L (0x1 << 4) #define RT5645_M_BST3_L_SM_L_SFT 4 #define RT5645_M_IN_L_SM_L (0x1 << 3) #define RT5645_M_IN_L_SM_L (0x1 << 3) #define RT5645_M_IN_L_SM_L_SFT 3 #define RT5645_M_IN_L_SM_L_SFT 3 #define RT5645_M_DAC_L1_SM_L (0x1 << 1) #define RT5645_M_DAC_L1_SM_L_SFT 1 #define RT5645_M_DAC_L2_SM_L (0x1 << 2) #define RT5645_M_DAC_L2_SM_L (0x1 << 2) #define RT5645_M_DAC_L2_SM_L_SFT 2 #define RT5645_M_DAC_L2_SM_L_SFT 2 #define RT5645_M_BST3_L_SM_L (0x1 << 4) #define RT5645_M_DAC_L1_SM_L (0x1 << 1) #define RT5645_M_BST3_L_SM_L_SFT 4 #define RT5645_M_DAC_L1_SM_L_SFT 1 /* SPK Right Mixer Control (0x47) */ /* SPK Right Mixer Control (0x47) */ #define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) #define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) Loading @@ -643,14 +643,14 @@ #define RT5645_G_OM_R_SM_R_SFT 6 #define RT5645_G_OM_R_SM_R_SFT 6 #define RT5645_M_BST2_R_SM_R (0x1 << 5) #define RT5645_M_BST2_R_SM_R (0x1 << 5) #define RT5645_M_BST2_R_SM_R_SFT 5 #define RT5645_M_BST2_R_SM_R_SFT 5 #define RT5645_M_BST3_R_SM_R (0x1 << 4) #define RT5645_M_BST3_R_SM_R_SFT 4 #define RT5645_M_IN_R_SM_R (0x1 << 3) #define RT5645_M_IN_R_SM_R (0x1 << 3) #define RT5645_M_IN_R_SM_R_SFT 3 #define RT5645_M_IN_R_SM_R_SFT 3 #define RT5645_M_DAC_R1_SM_R (0x1 << 1) #define RT5645_M_DAC_R1_SM_R_SFT 1 #define RT5645_M_DAC_R2_SM_R (0x1 << 2) #define RT5645_M_DAC_R2_SM_R (0x1 << 2) #define RT5645_M_DAC_R2_SM_R_SFT 2 #define RT5645_M_DAC_R2_SM_R_SFT 2 #define RT5645_M_BST3_R_SM_R (0x1 << 4) #define RT5645_M_DAC_R1_SM_R (0x1 << 1) #define RT5645_M_BST3_R_SM_R_SFT 4 #define RT5645_M_DAC_R1_SM_R_SFT 1 /* SPOLMIX Control (0x48) */ /* SPOLMIX Control (0x48) */ #define RT5645_M_DAC_L1_SPM_L (0x1 << 15) #define RT5645_M_DAC_L1_SPM_L (0x1 << 15) Loading @@ -670,13 +670,17 @@ #define RT5645_M_SV_R_SPM_R (0x1 << 0) #define RT5645_M_SV_R_SPM_R (0x1 << 0) #define RT5645_M_SV_R_SPM_R_SFT 0 #define RT5645_M_SV_R_SPM_R_SFT 0 /* SPOMIX Ratio Control (0x4a) */ #define RT5645_SPK_G_CLSD_MASK (0x7 << 0) #define RT5645_SPK_G_CLSD_SFT 0 /* Mono Output Mixer Control (0x4c) */ /* Mono Output Mixer Control (0x4c) */ #define RT5645_G_MONOMIX_MASK (0x1 << 10) #define RT5645_G_MONOMIX_SFT 10 #define RT5645_M_OV_L_MM (0x1 << 9) #define RT5645_M_OV_L_MM (0x1 << 9) #define RT5645_M_OV_L_MM_SFT 9 #define RT5645_M_OV_L_MM_SFT 9 #define RT5645_M_DAC_L2_MA (0x1 << 8) #define RT5645_M_DAC_L2_MA (0x1 << 8) #define RT5645_M_DAC_L2_MA_SFT 8 #define RT5645_M_DAC_L2_MA_SFT 8 #define RT5645_G_MONOMIX_MASK (0x1 << 10) #define RT5645_G_MONOMIX_SFT 10 #define RT5645_M_BST2_MM (0x1 << 4) #define RT5645_M_BST2_MM (0x1 << 4) #define RT5645_M_BST2_MM_SFT 4 #define RT5645_M_BST2_MM_SFT 4 #define RT5645_M_DAC_R1_MM (0x1 << 3) #define RT5645_M_DAC_R1_MM (0x1 << 3) Loading