From 574ff444b9fcc2554e381054f5052cb9c0e91de7 Mon Sep 17 00:00:00 2001
From: Li Xu
Date: Tue, 5 Sep 2017 20:33:04 -0500
Subject: ASoC: cs43130: Add break keyword to switch case
Add break keyword to all switch case unless the case is returning.
Also remove gpio check for consistency.
Signed-off-by: Li Xu
Signed-off-by: Mark Brown
---
sound/soc/codecs/cs43130.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c
index 643e37fc..5ba0edc 100644
--- a/sound/soc/codecs/cs43130.c
+++ b/sound/soc/codecs/cs43130.c
@@ -909,6 +909,7 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,
CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<
CS43130_DSD_SRC_SHIFT);
+ break;
}
if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)
@@ -1039,6 +1040,7 @@ static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,
else
regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq,
ARRAY_SIZE(pcm_ch_dis_seq));
+ break;
}
return snd_soc_put_enum_double(kcontrol, ucontrol);
@@ -1152,6 +1154,7 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
case CS4399_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, dsd_seq,
ARRAY_SIZE(dsd_seq));
+ break;
}
break;
case SND_SOC_DAPM_POST_PMU:
@@ -1162,6 +1165,7 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
case CS4399_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, unmute_seq,
ARRAY_SIZE(unmute_seq));
+ break;
}
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1184,6 +1188,7 @@ static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,
regmap_update_bits(cs43130->regmap,
CS43130_DSD_PATH_CTL_1,
CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ break;
}
break;
default:
@@ -1206,6 +1211,7 @@ static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
case CS4399_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, pcm_seq,
ARRAY_SIZE(pcm_seq));
+ break;
}
break;
case SND_SOC_DAPM_POST_PMU:
@@ -1216,6 +1222,7 @@ static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
case CS4399_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, unmute_seq,
ARRAY_SIZE(unmute_seq));
+ break;
}
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1238,6 +1245,7 @@ static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,
regmap_update_bits(cs43130->regmap,
CS43130_PCM_PATH_CTL_1,
CS43130_MUTE_MASK, CS43130_MUTE_EN);
+ break;
}
break;
default:
@@ -1277,6 +1285,7 @@ static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
case CS43198_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, pop_free_seq2,
ARRAY_SIZE(pop_free_seq2));
+ break;
}
break;
case SND_SOC_DAPM_POST_PMU:
@@ -1301,6 +1310,7 @@ static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
case CS43198_CHIP_ID:
usleep_range(12000, 12010);
regmap_write(cs43130->regmap, CS43130_DXD13, 0);
+ break;
}
regmap_write(cs43130->regmap, CS43130_DXD1, 0);
@@ -1311,6 +1321,7 @@ static int cs43130_dac_event(struct snd_soc_dapm_widget *w,
case CS4399_CHIP_ID:
regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq,
ARRAY_SIZE(dac_postpmd_seq));
+ break;
}
break;
default:
@@ -2133,6 +2144,7 @@ exit:
cs43130_hpload_proc(cs43130, hp_dis_cal_seq2,
ARRAY_SIZE(hp_dis_cal_seq2),
CS43130_HPLOAD_OFF_INT, ac_idx);
+ break;
}
regmap_multi_reg_write(cs43130->regmap, hp_cln_seq,
@@ -2543,6 +2555,7 @@ static int cs43130_i2c_probe(struct i2c_client *client,
digital_hp_routes;
soc_codec_dev_cs43130.component_driver.num_dapm_routes =
ARRAY_SIZE(digital_hp_routes);
+ break;
}
ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130,
@@ -2586,8 +2599,7 @@ static int cs43130_i2c_remove(struct i2c_client *client)
device_remove_file(&client->dev, &dev_attr_hpload_ac_r);
}
- if (cs43130->reset_gpio)
- gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
+ gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
pm_runtime_disable(&client->dev);
regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);
--
cgit v1.1
From 72d7a16bb07582f8416bbcdc65fe2a1e63f11294 Mon Sep 17 00:00:00 2001
From: Jean Delvare
Date: Fri, 15 Sep 2017 10:27:10 +0200
Subject: ASoC: rt5645: Make a few struct const
These dmi_system_id structures and associated platform data are
never modified so they can be marked const.
Signed-off-by: Jean Delvare
Cc: Bard Liao
Cc: Oder Chiou
Cc: Liam Girdwood
Cc: Mark Brown
Cc: Jaroslav Kysela
Cc: Takashi Iwai
--
sound/soc/codecs/rt5645.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5645.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index a98647a..4b2dbf0 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3637,14 +3637,14 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = {
{}
};
-static struct rt5645_platform_data general_platform_data2 = {
+static const struct rt5645_platform_data general_platform_data2 = {
.dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
.dmic2_data_pin = RT5645_DMIC2_DISABLE,
.jd_mode = 3,
.inv_jd1_1 = true,
};
-static struct dmi_system_id dmi_platform_asus_t100ha[] = {
+static const struct dmi_system_id dmi_platform_asus_t100ha[] = {
{
.ident = "ASUS T100HAN",
.matches = {
@@ -3655,11 +3655,11 @@ static struct dmi_system_id dmi_platform_asus_t100ha[] = {
{ }
};
-static struct rt5645_platform_data minix_z83_4_platform_data = {
+static const struct rt5645_platform_data minix_z83_4_platform_data = {
.jd_mode = 3,
};
-static struct dmi_system_id dmi_platform_minix_z83_4[] = {
+static const struct dmi_system_id dmi_platform_minix_z83_4[] = {
{
.ident = "MINIX Z83-4",
.matches = {
--
cgit v1.1
From 0607aa3cd824bddf85fa5174fe4be34af5a429fb Mon Sep 17 00:00:00 2001
From: Colin Ian King
Date: Mon, 18 Sep 2017 10:48:43 +0100
Subject: ASoC: hdmi-codec: use sizeof_field rather than declaring hcp
Use FIELD_SIZEOF rather than declaring and initializing hcp. Remove
unused variables. Cleans up clang warning:
warning: Value stored to 'hcp' during its initialization is never read
Signed-off-by: Colin Ian King
Signed-off-by: Mark Brown
---
sound/soc/codecs/hdmi-codec.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 3abf825..5672e51 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -303,11 +303,8 @@ enum {
static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
-
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
- uinfo->count = sizeof(hcp->eld);
+ uinfo->count = FIELD_SIZEOF(struct hdmi_codec_priv, eld);
return 0;
}
--
cgit v1.1
From 457c25efc592bb5539e18161c505f7a865013fb7 Mon Sep 17 00:00:00 2001
From: Oder Chiou
Date: Mon, 18 Sep 2017 18:14:26 +0800
Subject: ASoC: rt5663: Add the function of impedance sensing
Support the function of impedance sensing. It could be set the matrix row
number of the impedance sensing table and the related parameters in the
DTS.
Signed-off-by: Oder Chiou
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5663.c | 218 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 214 insertions(+), 4 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index ab9e0eb..767f219 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -38,6 +38,16 @@ enum {
CODEC_VER_0,
};
+struct impedance_mapping_table {
+ unsigned int imp_min;
+ unsigned int imp_max;
+ unsigned int vol;
+ unsigned int dc_offset_l_manual;
+ unsigned int dc_offset_r_manual;
+ unsigned int dc_offset_l_manual_mic;
+ unsigned int dc_offset_r_manual_mic;
+};
+
struct rt5663_priv {
struct snd_soc_codec *codec;
struct rt5663_platform_data pdata;
@@ -45,6 +55,7 @@ struct rt5663_priv {
struct delayed_work jack_detect_work;
struct snd_soc_jack *hs_jack;
struct timer_list btn_check_timer;
+ struct impedance_mapping_table *imp_table;
int codec_ver;
int sysclk;
@@ -1575,6 +1586,9 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
rt5663->jack_type = SND_JACK_HEADSET;
rt5663_enable_push_button_irq(codec, true);
+ if (rt5663->pdata.impedance_sensing_num)
+ break;
+
if (rt5663->pdata.dc_offset_l_manual_mic) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
rt5663->pdata.dc_offset_l_manual_mic >>
@@ -1596,6 +1610,9 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
default:
rt5663->jack_type = SND_JACK_HEADPHONE;
+ if (rt5663->pdata.impedance_sensing_num)
+ break;
+
if (rt5663->pdata.dc_offset_l_manual) {
regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
rt5663->pdata.dc_offset_l_manual >> 16);
@@ -1623,6 +1640,177 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
return rt5663->jack_type;
}
+static int rt5663_impedance_sensing(struct snd_soc_codec *codec)
+{
+ struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+ unsigned int value, i, reg84, reg26, reg2fa, reg91, reg10, reg80;
+
+ for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
+ if (rt5663->imp_table[i].vol == 7)
+ break;
+ }
+
+ if (rt5663->jack_type == SND_JACK_HEADSET) {
+ snd_soc_write(codec, RT5663_MIC_DECRO_2,
+ rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_3,
+ rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
+ snd_soc_write(codec, RT5663_MIC_DECRO_5,
+ rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_6,
+ rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
+ } else {
+ snd_soc_write(codec, RT5663_MIC_DECRO_2,
+ rt5663->imp_table[i].dc_offset_l_manual >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_3,
+ rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
+ snd_soc_write(codec, RT5663_MIC_DECRO_5,
+ rt5663->imp_table[i].dc_offset_r_manual >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_6,
+ rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
+ }
+
+ reg84 = snd_soc_read(codec, RT5663_ASRC_2);
+ reg26 = snd_soc_read(codec, RT5663_STO1_ADC_MIXER);
+ reg2fa = snd_soc_read(codec, RT5663_DUMMY_1);
+ reg91 = snd_soc_read(codec, RT5663_HP_CHARGE_PUMP_1);
+ reg10 = snd_soc_read(codec, RT5663_RECMIX);
+ reg80 = snd_soc_read(codec, RT5663_GLB_CLK);
+
+ snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, 0);
+ snd_soc_write(codec, RT5663_ASRC_2, 0);
+ snd_soc_write(codec, RT5663_STO1_ADC_MIXER, 0x4040);
+ snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+ RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK |
+ RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
+ RT5663_PWR_VREF1 | RT5663_PWR_VREF2);
+ usleep_range(10000, 10005);
+ snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+ RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK,
+ RT5663_PWR_FV1 | RT5663_PWR_FV2);
+ snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK,
+ RT5663_SCLK_SRC_RCCLK);
+ snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+ RT5663_DIG_25M_CLK_EN);
+ snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0);
+ snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00);
+ snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc);
+ snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, 0x1232);
+ snd_soc_write(codec, RT5663_HP_LOGIC_2, 0x0005);
+ snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0030);
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0x0003);
+ snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+ RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F,
+ RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F);
+ snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+ RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
+ RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
+ RT5663_PWR_ADC_R1,
+ RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
+ RT5663_PWR_LDO_DACREF_ON | RT5663_PWR_ADC_L1 |
+ RT5663_PWR_ADC_R1);
+ msleep(40);
+ snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+ RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2,
+ RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2);
+ msleep(30);
+ snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
+ snd_soc_write(codec, RT5663_STO_DAC_MIXER, 0);
+ snd_soc_write(codec, RT5663_BYPASS_STO_DAC, 0x000c);
+ snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
+ snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224);
+ snd_soc_write(codec, RT5663_HP_OUT_EN, 0x8088);
+ snd_soc_write(codec, RT5663_CHOP_ADC, 0x3000);
+ snd_soc_write(codec, RT5663_ADDA_RST, 0xc000);
+ snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0x3320);
+ snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c9);
+ snd_soc_write(codec, RT5663_DUMMY_1, 0x004c);
+ snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7733);
+ snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
+ snd_soc_write(codec, RT5663_STO_DRE_9, 0x0007);
+ snd_soc_write(codec, RT5663_STO_DRE_10, 0x0007);
+ snd_soc_write(codec, RT5663_DUMMY_2, 0x02a4);
+ snd_soc_write(codec, RT5663_RECMIX, 0x0005);
+ snd_soc_write(codec, RT5663_HP_IMP_SEN_1, 0x4334);
+ snd_soc_update_bits(codec, RT5663_IRQ_3, 0x0004, 0x0004);
+ snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x2200);
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000);
+ snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x6200);
+
+ for (i = 0; i < 100; i++) {
+ msleep(20);
+ if (snd_soc_read(codec, RT5663_INT_ST_1) & 0x2)
+ break;
+ }
+
+ value = snd_soc_read(codec, RT5663_HP_IMP_SEN_4);
+
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0);
+ snd_soc_write(codec, RT5663_INT_ST_1, 0);
+ snd_soc_write(codec, RT5663_HP_LOGIC_1, 0);
+ snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK,
+ RT5663_DIG_25M_CLK_DIS);
+ snd_soc_write(codec, RT5663_GLB_CLK, reg80);
+ snd_soc_write(codec, RT5663_RECMIX, reg10);
+ snd_soc_write(codec, RT5663_DUMMY_2, 0x00a4);
+ snd_soc_write(codec, RT5663_DUMMY_1, reg2fa);
+ snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c8);
+ snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0xb320);
+ snd_soc_write(codec, RT5663_ADDA_RST, 0xe400);
+ snd_soc_write(codec, RT5663_CHOP_ADC, 0x2000);
+ snd_soc_write(codec, RT5663_HP_OUT_EN, 0x0008);
+ snd_soc_update_bits(codec, RT5663_PWR_ANLG_2,
+ RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2, 0);
+ snd_soc_update_bits(codec, RT5663_PWR_DIG_1,
+ RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 |
+ RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 |
+ RT5663_PWR_ADC_R1, 0);
+ snd_soc_update_bits(codec, RT5663_PWR_DIG_2,
+ RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F, 0);
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
+ snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
+ snd_soc_write(codec, RT5663_HP_LOGIC_2, 0);
+ snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, reg91);
+ snd_soc_update_bits(codec, RT5663_PWR_ANLG_1,
+ RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK, 0);
+ snd_soc_write(codec, RT5663_STO1_ADC_MIXER, reg26);
+ snd_soc_write(codec, RT5663_ASRC_2, reg84);
+
+ for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) {
+ if (value >= rt5663->imp_table[i].imp_min &&
+ value <= rt5663->imp_table[i].imp_max)
+ break;
+ }
+
+ snd_soc_update_bits(codec, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK,
+ rt5663->imp_table[i].vol);
+ snd_soc_update_bits(codec, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK,
+ rt5663->imp_table[i].vol);
+
+ if (rt5663->jack_type == SND_JACK_HEADSET) {
+ snd_soc_write(codec, RT5663_MIC_DECRO_2,
+ rt5663->imp_table[i].dc_offset_l_manual_mic >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_3,
+ rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff);
+ snd_soc_write(codec, RT5663_MIC_DECRO_5,
+ rt5663->imp_table[i].dc_offset_r_manual_mic >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_6,
+ rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff);
+ } else {
+ snd_soc_write(codec, RT5663_MIC_DECRO_2,
+ rt5663->imp_table[i].dc_offset_l_manual >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_3,
+ rt5663->imp_table[i].dc_offset_l_manual & 0xffff);
+ snd_soc_write(codec, RT5663_MIC_DECRO_5,
+ rt5663->imp_table[i].dc_offset_r_manual >> 16);
+ snd_soc_write(codec, RT5663_MIC_DECRO_6,
+ rt5663->imp_table[i].dc_offset_r_manual & 0xffff);
+ }
+
+ return 0;
+}
+
static int rt5663_button_detect(struct snd_soc_codec *codec)
{
int btn_type, val;
@@ -1701,6 +1889,8 @@ static void rt5663_jack_detect_work(struct work_struct *work)
break;
case CODEC_VER_0:
report = rt5663_jack_detect(rt5663->codec, 1);
+ if (rt5663->pdata.impedance_sensing_num)
+ rt5663_impedance_sensing(rt5663->codec);
break;
default:
dev_err(codec->dev, "Unknown CODEC Version\n");
@@ -1796,10 +1986,6 @@ static const struct snd_kcontrol_new rt5663_v2_specific_controls[] = {
};
static const struct snd_kcontrol_new rt5663_specific_controls[] = {
- /* Headphone Output Volume */
- SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9,
- RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1,
- rt5663_hp_vol_tlv),
/* Mic Boost Volume*/
SOC_SINGLE_TLV("IN1 Capture Volume", RT5663_CBJ_2,
RT5663_GAIN_BST1_SHIFT, 8, 0, in_bst_tlv),
@@ -1807,6 +1993,13 @@ static const struct snd_kcontrol_new rt5663_specific_controls[] = {
SOC_ENUM("IF1 ADC Data Swap", rt5663_if1_adc_enum),
};
+static const struct snd_kcontrol_new rt5663_hpvol_controls[] = {
+ /* Headphone Output Volume */
+ SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9,
+ RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1,
+ rt5663_hp_vol_tlv),
+};
+
static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w,
struct snd_soc_dapm_widget *sink)
{
@@ -2889,6 +3082,10 @@ static int rt5663_probe(struct snd_soc_codec *codec)
ARRAY_SIZE(rt5663_specific_dapm_routes));
snd_soc_add_codec_controls(codec, rt5663_specific_controls,
ARRAY_SIZE(rt5663_specific_controls));
+
+ if (!rt5663->imp_table)
+ snd_soc_add_codec_controls(codec, rt5663_hpvol_controls,
+ ARRAY_SIZE(rt5663_hpvol_controls));
break;
}
@@ -3177,6 +3374,8 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev)
{
+ int table_size;
+
device_property_read_u32(dev, "realtek,dc_offset_l_manual",
&rt5663->pdata.dc_offset_l_manual);
device_property_read_u32(dev, "realtek,dc_offset_r_manual",
@@ -3185,6 +3384,17 @@ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev)
&rt5663->pdata.dc_offset_l_manual_mic);
device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic",
&rt5663->pdata.dc_offset_r_manual_mic);
+ device_property_read_u32(dev, "realtek,impedance_sensing_num",
+ &rt5663->pdata.impedance_sensing_num);
+
+ if (rt5663->pdata.impedance_sensing_num) {
+ table_size = sizeof(struct impedance_mapping_table) *
+ rt5663->pdata.impedance_sensing_num;
+ rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL);
+ device_property_read_u32_array(dev,
+ "realtek,impedance_sensing_table",
+ (u32 *)rt5663->imp_table, table_size);
+ }
return 0;
}
--
cgit v1.1
From d10a7d3e2af98e639e74c64185f910915a560f07 Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart
Date: Fri, 8 Sep 2017 00:13:03 -0500
Subject: ASoC: max98090: reduce verbosity on PLL unlock
'commit b8a3ee820f7b ("ASoC: max98090: Add recovery for PLL lock failure")'
enabled a workaround PLL unlocked issues, but generates annoying
dev_info "PLL unlocked" messages at a 10ms rate, usually on startup.
Move to dev_info_ratelimited. This issue doesn't seem to impact audio
functionality. This trace is commented out in the GalliumOS patches,
it's better to keep it to check on potential quality issues
Tested on Lenovo 100s (Baytrail Chromebook)
Signed-off-by: Pierre-Louis Bossart
Acked-By: Vinod Koul
Signed-off-by: Mark Brown
---
sound/soc/codecs/max98090.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 13bcfb1..f5075d1 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2115,7 +2115,7 @@ static void max98090_pll_work(struct work_struct *work)
if (!snd_soc_codec_is_active(codec))
return;
- dev_info(codec->dev, "PLL unlocked\n");
+ dev_info_ratelimited(codec->dev, "PLL unlocked\n");
/* Toggle shutdown OFF then ON */
snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
--
cgit v1.1
From a10953f5d33b2334c8fb1799084ab49347a59821 Mon Sep 17 00:00:00 2001
From: "Fang, Yang A"
Date: Fri, 8 Sep 2017 00:13:07 -0500
Subject: ASoC: ts3a227e: add acpi table
This patch adds the acpi match table for the ts3a227e audio accessory
detection device. This enables headset features like jack plug/unplug
notifications, mic presence, and button pressed events.
Signed-off-by: Fang, Yang A
Signed-off-by: Thierry Escande
Signed-off-by: Pierre-Louis Bossart
Acked-By: Vinod Koul
Signed-off-by: Mark Brown
---
sound/soc/codecs/ts3a227e.c | 10 ++++++++++
1 file changed, 10 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c
index 4356843..738e04b 100644
--- a/sound/soc/codecs/ts3a227e.c
+++ b/sound/soc/codecs/ts3a227e.c
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
@@ -374,11 +375,20 @@ static const struct of_device_id ts3a227e_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ts3a227e_of_match);
+#ifdef CONFIG_ACPI
+static struct acpi_device_id ts3a227e_acpi_match[] = {
+ { "104C227E", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, ts3a227e_acpi_match);
+#endif
+
static struct i2c_driver ts3a227e_driver = {
.driver = {
.name = "ts3a227e",
.pm = &ts3a227e_pm,
.of_match_table = of_match_ptr(ts3a227e_of_match),
+ .acpi_match_table = ACPI_PTR(ts3a227e_acpi_match),
},
.probe = ts3a227e_i2c_probe,
.id_table = ts3a227e_i2c_ids,
--
cgit v1.1
From 9e3f9f36a6f40bb6ba9b3844d709314121e4c106 Mon Sep 17 00:00:00 2001
From: Charles Keepax
Date: Mon, 4 Sep 2017 16:41:48 +0100
Subject: ASoC: arizona: Add new common Arizona init function
Currently the driver has quite a few small initialisation functions, in
preparation for some refactoring add a new function arizona_init_common.
This will be used bus probe level initialisation that is common across
Arizona devices. For now just move the notifier chain initialisation in
there.
Signed-off-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/arizona.c | 7 ++-----
sound/soc/codecs/arizona.h | 3 ++-
sound/soc/codecs/cs47l24.c | 3 ++-
sound/soc/codecs/wm5102.c | 3 ++-
sound/soc/codecs/wm5110.c | 3 ++-
sound/soc/codecs/wm8997.c | 4 ++--
sound/soc/codecs/wm8998.c | 3 ++-
7 files changed, 14 insertions(+), 12 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index a1149f6..ba5f57a 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -293,16 +293,13 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
}
EXPORT_SYMBOL_GPL(arizona_init_gpio);
-int arizona_init_notifiers(struct snd_soc_codec *codec)
+int arizona_init_common(struct arizona *arizona)
{
- struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
- struct arizona *arizona = priv->arizona;
-
BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
return 0;
}
-EXPORT_SYMBOL_GPL(arizona_init_notifiers);
+EXPORT_SYMBOL_GPL(arizona_init_common);
const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
"None",
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 1822e3b..292073c 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -313,7 +313,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source,
int arizona_init_spk(struct snd_soc_codec *codec);
int arizona_init_gpio(struct snd_soc_codec *codec);
int arizona_init_mono(struct snd_soc_codec *codec);
-int arizona_init_notifiers(struct snd_soc_codec *codec);
+
+int arizona_init_common(struct arizona *arizona);
int arizona_init_spk_irqs(struct arizona *arizona);
int arizona_free_spk_irqs(struct arizona *arizona);
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index e09fc8f..fdcc731 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -1130,7 +1130,6 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
arizona_init_gpio(codec);
arizona_init_mono(codec);
- arizona_init_notifiers(codec);
ret = wm_adsp2_codec_probe(&priv->core.adsp[1], codec);
if (ret)
@@ -1288,6 +1287,8 @@ static int cs47l24_probe(struct platform_device *pdev)
return ret;
}
+ arizona_init_common(arizona);
+
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 72486bf..8354bdf 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1951,7 +1951,6 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
return ret;
arizona_init_gpio(codec);
- arizona_init_notifiers(codec);
snd_soc_component_disable_pin(component, "HAPTICS");
@@ -2098,6 +2097,8 @@ static int wm5102_probe(struct platform_device *pdev)
return ret;
}
+ arizona_init_common(arizona);
+
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 858a24f..0437df6 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -2290,7 +2290,6 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
arizona_init_gpio(codec);
arizona_init_mono(codec);
- arizona_init_notifiers(codec);
for (i = 0; i < WM5110_NUM_ADSP; ++i) {
ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec);
@@ -2454,6 +2453,8 @@ static int wm5110_probe(struct platform_device *pdev)
return ret;
}
+ arizona_init_common(arizona);
+
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index 49401a8..91c3c3e 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1068,8 +1068,6 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
if (ret < 0)
return ret;
- arizona_init_notifiers(codec);
-
snd_soc_component_disable_pin(component, "HAPTICS");
priv->core.arizona->dapm = dapm;
@@ -1168,6 +1166,8 @@ static int wm8997_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
+ arizona_init_common(arizona);
+
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
return ret;
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 44f4471..27a8e1e 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -1330,7 +1330,6 @@ static int wm8998_codec_probe(struct snd_soc_codec *codec)
return ret;
arizona_init_gpio(codec);
- arizona_init_notifiers(codec);
snd_soc_component_disable_pin(component, "HAPTICS");
@@ -1423,6 +1422,8 @@ static int wm8998_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
+ arizona_init_common(arizona);
+
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
return ret;
--
cgit v1.1
From 0a229b15d99e0a9761f9672f4ff7efeb18ce0ea1 Mon Sep 17 00:00:00 2001
From: Charles Keepax
Date: Mon, 4 Sep 2017 16:41:49 +0100
Subject: ASoC: arizona: Add handling for audio related device tree entries
Currently all the audio related device tree entries are handled by the
MFD code, for most parts of the Arizona driver we group the device
tree handling with the component that uses it and should do so here as
well.
Add handling in the ASoC code for the audio device tree entries, a
later patch removes the MFD side handling but there is no harm in it
being duplicated temporarily.
Signed-off-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/arizona.c | 136 +++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/arizona.h | 2 +
sound/soc/codecs/cs47l24.c | 8 +++
sound/soc/codecs/wm5102.c | 8 +++
sound/soc/codecs/wm5110.c | 8 +++
sound/soc/codecs/wm8997.c | 8 +++
sound/soc/codecs/wm8998.c | 8 +++
7 files changed, 178 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ba5f57a..e696738 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -295,8 +296,78 @@ EXPORT_SYMBOL_GPL(arizona_init_gpio);
int arizona_init_common(struct arizona *arizona)
{
+ struct arizona_pdata *pdata = &arizona->pdata;
+ unsigned int val, mask;
+ int i;
+
BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
+ for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
+ /* Default is 0 so noop with defaults */
+ if (pdata->out_mono[i])
+ val = ARIZONA_OUT1_MONO;
+ else
+ val = 0;
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
+ ARIZONA_OUT1_MONO, val);
+ }
+
+ for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
+ if (pdata->spk_mute[i])
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
+ ARIZONA_SPK1_MUTE_ENDIAN_MASK |
+ ARIZONA_SPK1_MUTE_SEQ1_MASK,
+ pdata->spk_mute[i]);
+
+ if (pdata->spk_fmt[i])
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
+ ARIZONA_SPK1_FMT_MASK,
+ pdata->spk_fmt[i]);
+ }
+
+ for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
+ /* Default for both is 0 so noop with defaults */
+ val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
+ if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
+ val |= 1 << ARIZONA_IN1_MODE_SHIFT;
+
+ switch (arizona->type) {
+ case WM8998:
+ case WM1814:
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
+ ARIZONA_IN1L_SRC_SE_MASK,
+ (pdata->inmode[i] & ARIZONA_INMODE_SE)
+ << ARIZONA_IN1L_SRC_SE_SHIFT);
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
+ ARIZONA_IN1R_SRC_SE_MASK,
+ (pdata->inmode[i] & ARIZONA_INMODE_SE)
+ << ARIZONA_IN1R_SRC_SE_SHIFT);
+
+ mask = ARIZONA_IN1_DMIC_SUP_MASK |
+ ARIZONA_IN1_MODE_MASK;
+ break;
+ default:
+ if (pdata->inmode[i] & ARIZONA_INMODE_SE)
+ val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
+
+ mask = ARIZONA_IN1_DMIC_SUP_MASK |
+ ARIZONA_IN1_MODE_MASK |
+ ARIZONA_IN1_SINGLE_ENDED_MASK;
+ break;
+ }
+
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_IN1L_CONTROL + (i * 8),
+ mask, val);
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(arizona_init_common);
@@ -2692,6 +2763,71 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
+int arizona_of_get_audio_pdata(struct arizona *arizona)
+{
+ struct arizona_pdata *pdata = &arizona->pdata;
+ struct device_node *np = arizona->dev->of_node;
+ struct property *prop;
+ const __be32 *cur;
+ u32 val;
+ u32 pdm_val[ARIZONA_MAX_PDM_SPK];
+ int ret;
+ int count = 0;
+
+ count = 0;
+ of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
+ if (count == ARRAY_SIZE(pdata->inmode))
+ break;
+
+ pdata->inmode[count] = val;
+ count++;
+ }
+
+ count = 0;
+ of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
+ if (count == ARRAY_SIZE(pdata->dmic_ref))
+ break;
+
+ pdata->dmic_ref[count] = val;
+ count++;
+ }
+
+ count = 0;
+ of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
+ if (count == ARRAY_SIZE(pdata->out_mono))
+ break;
+
+ pdata->out_mono[count] = !!val;
+ count++;
+ }
+
+ count = 0;
+ of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
+ if (count == ARRAY_SIZE(pdata->max_channels_clocked))
+ break;
+
+ pdata->max_channels_clocked[count] = val;
+ count++;
+ }
+
+ ret = of_property_read_u32_array(np, "wlf,spk-fmt",
+ pdm_val, ARRAY_SIZE(pdm_val));
+
+ if (ret >= 0)
+ for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
+ pdata->spk_fmt[count] = pdm_val[count];
+
+ ret = of_property_read_u32_array(np, "wlf,spk-mute",
+ pdm_val, ARRAY_SIZE(pdm_val));
+
+ if (ret >= 0)
+ for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
+ pdata->spk_mute[count] = pdm_val[count];
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
+
MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
MODULE_AUTHOR("Mark Brown ");
MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 292073c..2d198fb 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -351,4 +351,6 @@ static inline int arizona_unregister_notifier(struct snd_soc_codec *codec,
return blocking_notifier_chain_unregister(&arizona->notifier, nb);
}
+int arizona_of_get_audio_pdata(struct arizona *arizona);
+
#endif
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index fdcc731..0fe7d7a 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -1229,6 +1229,14 @@ static int cs47l24_probe(struct platform_device *pdev)
if (!cs47l24)
return -ENOMEM;
+ if (IS_ENABLED(CONFIG_OF)) {
+ if (!dev_get_platdata(arizona->dev)) {
+ ret = arizona_of_get_audio_pdata(arizona);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
platform_set_drvdata(pdev, cs47l24);
cs47l24->core.arizona = arizona;
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 8354bdf..5a917dd 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -2042,6 +2042,14 @@ static int wm5102_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, wm5102);
+ if (IS_ENABLED(CONFIG_OF)) {
+ if (!dev_get_platdata(arizona->dev)) {
+ ret = arizona_of_get_audio_pdata(arizona);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
mutex_init(&arizona->dac_comp_lock);
wm5102->core.arizona = arizona;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 0437df6..ba1e90c 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -2397,6 +2397,14 @@ static int wm5110_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, wm5110);
+ if (IS_ENABLED(CONFIG_OF)) {
+ if (!dev_get_platdata(arizona->dev)) {
+ ret = arizona_of_get_audio_pdata(arizona);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
wm5110->core.arizona = arizona;
wm5110->core.num_inputs = 8;
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index 91c3c3e..c5aef9e 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1134,6 +1134,14 @@ static int wm8997_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, wm8997);
+ if (IS_ENABLED(CONFIG_OF)) {
+ if (!dev_get_platdata(arizona->dev)) {
+ ret = arizona_of_get_audio_pdata(arizona);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
wm8997->core.arizona = arizona;
wm8997->core.num_inputs = 4;
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 27a8e1e..c59caaa 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -1398,6 +1398,14 @@ static int wm8998_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, wm8998);
+ if (IS_ENABLED(CONFIG_OF)) {
+ if (!dev_get_platdata(arizona->dev)) {
+ ret = arizona_of_get_audio_pdata(arizona);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
wm8998->core.arizona = arizona;
wm8998->core.num_inputs = 3; /* IN1L, IN1R, IN2 */
--
cgit v1.1
From 9bd400cadae05a26c3a22dd8393081cb96d0e26a Mon Sep 17 00:00:00 2001
From: Robert Jarzmik
Date: Wed, 13 Sep 2017 21:37:19 +0200
Subject: ASoC: wm9713: add ac97 new bus support
Add support for the new ac97 bus model, where devices are automatically
discovered on AC-Links.
Signed-off-by: Robert Jarzmik
Acked-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/Kconfig | 3 ++-
sound/soc/codecs/wm9713.c | 39 +++++++++++++++++++++++++++------------
2 files changed, 29 insertions(+), 13 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index c367d11..807901c 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -216,7 +216,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM9090 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
- select SND_SOC_WM9713 if SND_SOC_AC97_BUS
+ select SND_SOC_WM9713 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
@@ -1136,6 +1136,7 @@ config SND_SOC_WM9712
config SND_SOC_WM9713
tristate
select REGMAP_AC97
+ select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_ZX_AUD96P22
tristate "ZTE ZX AUD96P22 CODEC"
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 7e48221..df72206 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -17,12 +17,15 @@
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -38,6 +41,7 @@ struct wm9713_priv {
u32 pll_in; /* PLL input frequency */
unsigned int hp_mixer[2];
struct mutex lock;
+ struct wm97xx_platform_data *mfd_pdata;
};
#define HPL_MIXER 0
@@ -1205,17 +1209,23 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)
static int wm9713_soc_probe(struct snd_soc_codec *codec)
{
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
- struct regmap *regmap;
+ struct regmap *regmap = NULL;
- wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
- WM9713_VENDOR_ID_MASK);
- if (IS_ERR(wm9713->ac97))
- return PTR_ERR(wm9713->ac97);
-
- regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
- if (IS_ERR(regmap)) {
- snd_soc_free_ac97_codec(wm9713->ac97);
- return PTR_ERR(regmap);
+ if (wm9713->mfd_pdata) {
+ wm9713->ac97 = wm9713->mfd_pdata->ac97;
+ regmap = wm9713->mfd_pdata->regmap;
+ } else {
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ wm9713->ac97 = snd_soc_new_ac97_codec(codec, WM9713_VENDOR_ID,
+ WM9713_VENDOR_ID_MASK);
+ if (IS_ERR(wm9713->ac97))
+ return PTR_ERR(wm9713->ac97);
+ regmap = regmap_init_ac97(wm9713->ac97, &wm9713_regmap_config);
+ if (IS_ERR(regmap)) {
+ snd_soc_free_ac97_codec(wm9713->ac97);
+ return PTR_ERR(regmap);
+ }
+#endif
}
snd_soc_codec_init_regmap(codec, regmap);
@@ -1228,10 +1238,14 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
static int wm9713_soc_remove(struct snd_soc_codec *codec)
{
+#ifdef CONFIG_SND_SOC_AC97_BUS
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
- snd_soc_codec_exit_regmap(codec);
- snd_soc_free_ac97_codec(wm9713->ac97);
+ if (!wm9713->mfd_pdata) {
+ snd_soc_codec_exit_regmap(codec);
+ snd_soc_free_ac97_codec(wm9713->ac97);
+ }
+#endif
return 0;
}
@@ -1262,6 +1276,7 @@ static int wm9713_probe(struct platform_device *pdev)
mutex_init(&wm9713->lock);
+ wm9713->mfd_pdata = dev_get_platdata(&pdev->dev);
platform_set_drvdata(pdev, wm9713);
return snd_soc_register_codec(&pdev->dev,
--
cgit v1.1
From 2ed1a8e0ce8db6d36f849526db61ce3c85a9f8d1 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik
Date: Wed, 13 Sep 2017 21:37:20 +0200
Subject: ASoC: wm9712: add ac97 new bus support
Add support for the new ac97 bus model, where devices are automatically
discovered on AC-Links.
Signed-off-by: Robert Jarzmik
Signed-off-by: Mark Brown
---
sound/soc/codecs/Kconfig | 3 ++-
sound/soc/codecs/wm9712.c | 44 ++++++++++++++++++++++++++++++--------------
2 files changed, 32 insertions(+), 15 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 807901c..655388d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -215,7 +215,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM9081 if I2C
select SND_SOC_WM9090 if I2C
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
- select SND_SOC_WM9712 if SND_SOC_AC97_BUS
+ select SND_SOC_WM9712 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
select SND_SOC_WM9713 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
help
Normally ASoC codec drivers are only built if a machine driver which
@@ -1132,6 +1132,7 @@ config SND_SOC_WM9705
config SND_SOC_WM9712
tristate
select REGMAP_AC97
+ select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9713
tristate
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1a3e179..1e228bf 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
#include
#include
@@ -19,6 +20,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -30,6 +33,7 @@ struct wm9712_priv {
struct snd_ac97 *ac97;
unsigned int hp_mixer[2];
struct mutex lock;
+ struct wm97xx_platform_data *mfd_pdata;
};
static const struct reg_default wm9712_reg_defaults[] = {
@@ -636,18 +640,25 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
struct regmap *regmap;
int ret;
- wm9712->ac97 = snd_soc_new_ac97_codec(codec, WM9712_VENDOR_ID,
- WM9712_VENDOR_ID_MASK);
- if (IS_ERR(wm9712->ac97)) {
- ret = PTR_ERR(wm9712->ac97);
- dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
- return ret;
- }
-
- regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- goto err_free_ac97_codec;
+ if (wm9712->mfd_pdata) {
+ wm9712->ac97 = wm9712->mfd_pdata->ac97;
+ regmap = wm9712->mfd_pdata->regmap;
+ } else {
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ wm9712->ac97 = snd_soc_new_ac97_codec(codec, WM9712_VENDOR_ID,
+ WM9712_VENDOR_ID_MASK);
+ if (IS_ERR(wm9712->ac97)) {
+ ret = PTR_ERR(wm9712->ac97);
+ dev_err(codec->dev,
+ "Failed to register AC97 codec: %d\n", ret);
+ return ret;
+ }
+
+ regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ goto err_free_ac97_codec;
+#endif
}
snd_soc_codec_init_regmap(codec, regmap);
@@ -663,10 +674,14 @@ err_free_ac97_codec:
static int wm9712_soc_remove(struct snd_soc_codec *codec)
{
+#ifdef CONFIG_SND_SOC_AC97_BUS
struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
- snd_soc_codec_exit_regmap(codec);
- snd_soc_free_ac97_codec(wm9712->ac97);
+ if (!wm9712->mfd_pdata) {
+ snd_soc_codec_exit_regmap(codec);
+ snd_soc_free_ac97_codec(wm9712->ac97);
+ }
+#endif
return 0;
}
@@ -697,6 +712,7 @@ static int wm9712_probe(struct platform_device *pdev)
mutex_init(&wm9712->lock);
+ wm9712->mfd_pdata = dev_get_platdata(&pdev->dev);
platform_set_drvdata(pdev, wm9712);
return snd_soc_register_codec(&pdev->dev,
--
cgit v1.1
From c6e46e52b7b3301dda529830226e578cf773151c Mon Sep 17 00:00:00 2001
From: Robert Jarzmik
Date: Wed, 13 Sep 2017 21:37:21 +0200
Subject: ASoC: wm9705: add private structure
Add a private data structure. This is a preparation for a codec which
would need an another data on top of snd_ac97, which will be the case
when an MFD wm97xx device will probe wm9705.
Signed-off-by: Robert Jarzmik
Acked-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm9705.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index f6d5c0f..08477d0 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -24,6 +24,10 @@
#define WM9705_VENDOR_ID 0x574d4c05
#define WM9705_VENDOR_ID_MASK 0xffffffff
+struct wm9705_priv {
+ struct snd_ac97 *ac97;
+};
+
static const struct reg_default wm9705_reg_defaults[] = {
{ 0x02, 0x8000 },
{ 0x04, 0x8000 },
@@ -292,10 +296,10 @@ static int wm9705_soc_suspend(struct snd_soc_codec *codec)
static int wm9705_soc_resume(struct snd_soc_codec *codec)
{
- struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+ struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
int ret;
- ret = snd_ac97_reset(ac97, true, WM9705_VENDOR_ID,
+ ret = snd_ac97_reset(wm9705->ac97, true, WM9705_VENDOR_ID,
WM9705_VENDOR_ID_MASK);
if (ret < 0)
return ret;
@@ -311,38 +315,38 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)
static int wm9705_soc_probe(struct snd_soc_codec *codec)
{
- struct snd_ac97 *ac97;
+ struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
struct regmap *regmap;
int ret;
- ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
- WM9705_VENDOR_ID_MASK);
- if (IS_ERR(ac97)) {
+ wm9705->ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
+ WM9705_VENDOR_ID_MASK);
+ if (IS_ERR(wm9705->ac97)) {
dev_err(codec->dev, "Failed to register AC97 codec\n");
- return PTR_ERR(ac97);
+ return PTR_ERR(wm9705->ac97);
}
- regmap = regmap_init_ac97(ac97, &wm9705_regmap_config);
+ regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
goto err_free_ac97_codec;
}
- snd_soc_codec_set_drvdata(codec, ac97);
+ snd_soc_codec_set_drvdata(codec, wm9705->ac97);
snd_soc_codec_init_regmap(codec, regmap);
return 0;
err_free_ac97_codec:
- snd_soc_free_ac97_codec(ac97);
+ snd_soc_free_ac97_codec(wm9705->ac97);
return ret;
}
static int wm9705_soc_remove(struct snd_soc_codec *codec)
{
- struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
+ struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
snd_soc_codec_exit_regmap(codec);
- snd_soc_free_ac97_codec(ac97);
+ snd_soc_free_ac97_codec(wm9705->ac97);
return 0;
}
@@ -364,6 +368,14 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm9705 = {
static int wm9705_probe(struct platform_device *pdev)
{
+ struct wm9705_priv *wm9705;
+
+ wm9705 = devm_kzalloc(&pdev->dev, sizeof(*wm9705), GFP_KERNEL);
+ if (wm9705 == NULL)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, wm9705);
+
return snd_soc_register_codec(&pdev->dev,
&soc_codec_dev_wm9705, wm9705_dai, ARRAY_SIZE(wm9705_dai));
}
--
cgit v1.1
From aaafcfed9290349555a326fff1147460a54c34f2 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik
Date: Wed, 13 Sep 2017 21:37:22 +0200
Subject: ASoC: wm9705: add ac97 new bus support
Add support for the new ac97 bus model, where devices are automatically
discovered on AC-Links.
Signed-off-by: Robert Jarzmik
Acked-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/Kconfig | 3 ++-
sound/soc/codecs/wm9705.c | 42 +++++++++++++++++++++++++++++-------------
2 files changed, 31 insertions(+), 14 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 655388d..0838ae7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -214,7 +214,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM8998 if MFD_WM8998
select SND_SOC_WM9081 if I2C
select SND_SOC_WM9090 if I2C
- select SND_SOC_WM9705 if SND_SOC_AC97_BUS
+ select SND_SOC_WM9705 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
select SND_SOC_WM9712 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
select SND_SOC_WM9713 if (SND_SOC_AC97_BUS || SND_SOC_AC97_BUS_NEW)
help
@@ -1128,6 +1128,7 @@ config SND_SOC_WM9090
config SND_SOC_WM9705
tristate
select REGMAP_AC97
+ select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9712
tristate
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 08477d0..68c204e 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -11,6 +11,7 @@
#include
#include
+#include
#include
#include
#include
@@ -18,6 +19,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -26,6 +29,7 @@
struct wm9705_priv {
struct snd_ac97 *ac97;
+ struct wm97xx_platform_data *mfd_pdata;
};
static const struct reg_default wm9705_reg_defaults[] = {
@@ -319,17 +323,24 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
struct regmap *regmap;
int ret;
- wm9705->ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
- WM9705_VENDOR_ID_MASK);
- if (IS_ERR(wm9705->ac97)) {
- dev_err(codec->dev, "Failed to register AC97 codec\n");
- return PTR_ERR(wm9705->ac97);
- }
-
- regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
- if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- goto err_free_ac97_codec;
+ if (wm9705->mfd_pdata) {
+ wm9705->ac97 = wm9705->mfd_pdata->ac97;
+ regmap = wm9705->mfd_pdata->regmap;
+ } else {
+#ifdef CONFIG_SND_SOC_AC97_BUS
+ wm9705->ac97 = snd_soc_new_ac97_codec(codec, WM9705_VENDOR_ID,
+ WM9705_VENDOR_ID_MASK);
+ if (IS_ERR(wm9705->ac97)) {
+ dev_err(codec->dev, "Failed to register AC97 codec\n");
+ return PTR_ERR(wm9705->ac97);
+ }
+
+ regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ goto err_free_ac97_codec;
+ }
+#endif
}
snd_soc_codec_set_drvdata(codec, wm9705->ac97);
@@ -343,10 +354,14 @@ err_free_ac97_codec:
static int wm9705_soc_remove(struct snd_soc_codec *codec)
{
+#ifdef CONFIG_SND_SOC_AC97_BUS
struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
- snd_soc_codec_exit_regmap(codec);
- snd_soc_free_ac97_codec(wm9705->ac97);
+ if (!wm9705->mfd_pdata) {
+ snd_soc_codec_exit_regmap(codec);
+ snd_soc_free_ac97_codec(wm9705->ac97);
+ }
+#endif
return 0;
}
@@ -374,6 +389,7 @@ static int wm9705_probe(struct platform_device *pdev)
if (wm9705 == NULL)
return -ENOMEM;
+ wm9705->mfd_pdata = dev_get_platdata(&pdev->dev);
platform_set_drvdata(pdev, wm9705);
return snd_soc_register_codec(&pdev->dev,
--
cgit v1.1
From 57f7feff2912d6996b5f3fcac084308ce195127c Mon Sep 17 00:00:00 2001
From: Colin Ian King
Date: Tue, 19 Sep 2017 22:50:00 +0100
Subject: ASoC: rl6231: make arrays div and pd static const, reduces object
code size
Don't populate the read-only arrays div and pd on the stack,
instead make them static const. Makes the object code smaller by 210 bytes:
Before:
text data bss dec hex filename
2869 720 0 3589 e05 sound/soc/codecs/rl6231.o
After:
text data bss dec hex filename
2495 880 0 3375 d2f sound/soc/codecs/rl6231.o
Signed-off-by: Colin Ian King
Signed-off-by: Mark Brown
---
sound/soc/codecs/rl6231.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c
index 7b447d0..974a904 100644
--- a/sound/soc/codecs/rl6231.c
+++ b/sound/soc/codecs/rl6231.c
@@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(rl6231_get_pre_div);
*/
int rl6231_calc_dmic_clk(int rate)
{
- int div[] = {2, 3, 4, 6, 8, 12};
+ static const int div[] = {2, 3, 4, 6, 8, 12};
int i;
if (rate < 1000000 * div[0]) {
@@ -189,7 +189,8 @@ EXPORT_SYMBOL_GPL(rl6231_pll_calc);
int rl6231_get_clk_info(int sclk, int rate)
{
- int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+ int i;
+ static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;
--
cgit v1.1
From 5aa3b03ad0712e3964a0ae2788f61f08da814bfe Mon Sep 17 00:00:00 2001
From: Mark Brown
Date: Wed, 20 Sep 2017 12:35:37 +0100
Subject: ASoC: wm9712: Add missing brace
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm9712.c | 1 +
1 file changed, 1 insertion(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1e228bf..9db5c77 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -658,6 +658,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
goto err_free_ac97_codec;
+ }
#endif
}
--
cgit v1.1
From 3d345b5f7b2f613b6965fc3fc68de9f439752ffe Mon Sep 17 00:00:00 2001
From: Fabio Estevam
Date: Tue, 19 Sep 2017 19:59:04 -0300
Subject: ASoC: tfa9879: Add device tree bindings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Even though the tfa9879 driver can probe via device tree trough the
I2C core code, it is preferable to have explicit device tree
bindings instead [1], so add this support.
[1] https://www.spinics.net/lists/devicetree/msg195176.html
Signed-off-by: Fabio Estevam
Reviewed-by: Ćukasz Majewski
Signed-off-by: Mark Brown
---
sound/soc/codecs/tfa9879.c | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c
index 95e0a7a..f8dd67c 100644
--- a/sound/soc/codecs/tfa9879.c
+++ b/sound/soc/codecs/tfa9879.c
@@ -312,9 +312,15 @@ static const struct i2c_device_id tfa9879_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tfa9879_i2c_id);
+static const struct of_device_id tfa9879_of_match[] = {
+ { .compatible = "nxp,tfa9879", },
+ { }
+};
+
static struct i2c_driver tfa9879_i2c_driver = {
.driver = {
.name = "tfa9879",
+ .of_match_table = tfa9879_of_match,
},
.probe = tfa9879_i2c_probe,
.remove = tfa9879_i2c_remove,
--
cgit v1.1
From a029ef45179d72945c7ae0a11f97e8012a5574ac Mon Sep 17 00:00:00 2001
From: Takashi Iwai
Date: Thu, 7 Sep 2017 10:59:16 +0200
Subject: ASoC: tas571x: Kill BUG_ON() usage
Don't use BUG_ON() for a non-critical sanity check on production
systems. This patch replaces with a softer WARN_ON() and an error
path.
Signed-off-by: Takashi Iwai
Signed-off-by: Mark Brown
---
sound/soc/codecs/tas571x.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index 810369f..a094999 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -697,7 +697,8 @@ static int tas571x_i2c_probe(struct i2c_client *client,
return PTR_ERR(priv->mclk);
}
- BUG_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES);
+ if (WARN_ON(priv->chip->num_supply_names > TAS571X_MAX_SUPPLIES))
+ return -EINVAL;
for (i = 0; i < priv->chip->num_supply_names; i++)
priv->supplies[i].supply = priv->chip->supply_names[i];
--
cgit v1.1
From 85e7dd3f871b988702973c80d9ef128e10dd3dad Mon Sep 17 00:00:00 2001
From: Charles Keepax
Date: Mon, 4 Sep 2017 16:41:53 +0100
Subject: ASoC: arizona: Add support for setting the output volume limits
The output volume limits allow signals to be limited to specific levels
appropriate for the hardware attached. As this is a property of the
hardware itself these will be configured through device tree.
Signed-off-by: Charles Keepax
Acked-by: Lee Jones
Signed-off-by: Mark Brown
---
sound/soc/codecs/arizona.c | 25 +++++++++++++++++++++++++
sound/soc/codecs/arizona.h | 1 +
sound/soc/codecs/cs47l24.c | 3 +++
sound/soc/codecs/wm5102.c | 3 +++
sound/soc/codecs/wm5110.c | 3 +++
sound/soc/codecs/wm8997.c | 3 +++
6 files changed, 38 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index e696738..b3375e1 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -372,6 +372,22 @@ int arizona_init_common(struct arizona *arizona)
}
EXPORT_SYMBOL_GPL(arizona_init_common);
+int arizona_init_vol_limit(struct arizona *arizona)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(arizona->pdata.out_vol_limit); ++i) {
+ if (arizona->pdata.out_vol_limit[i])
+ regmap_update_bits(arizona->regmap,
+ ARIZONA_DAC_VOLUME_LIMIT_1L + i * 4,
+ ARIZONA_OUT1L_VOL_LIM_MASK,
+ arizona->pdata.out_vol_limit[i]);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_init_vol_limit);
+
const char * const arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
"None",
"Tone Generator 1",
@@ -2810,6 +2826,15 @@ int arizona_of_get_audio_pdata(struct arizona *arizona)
count++;
}
+ count = 0;
+ of_property_for_each_u32(np, "wlf,out-volume-limit", prop, cur, val) {
+ if (count == ARRAY_SIZE(pdata->out_vol_limit))
+ break;
+
+ pdata->out_vol_limit[count] = val;
+ count++;
+ }
+
ret = of_property_read_u32_array(np, "wlf,spk-fmt",
pdm_val, ARRAY_SIZE(pdm_val));
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 2d198fb..dfdf6d8 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -315,6 +315,7 @@ int arizona_init_gpio(struct snd_soc_codec *codec);
int arizona_init_mono(struct snd_soc_codec *codec);
int arizona_init_common(struct arizona *arizona);
+int arizona_init_vol_limit(struct arizona *arizona);
int arizona_init_spk_irqs(struct arizona *arizona);
int arizona_free_spk_irqs(struct arizona *arizona);
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 0fe7d7a..94c0209 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -1297,6 +1297,9 @@ static int cs47l24_probe(struct platform_device *pdev)
arizona_init_common(arizona);
+ ret = arizona_init_vol_limit(arizona);
+ if (ret < 0)
+ goto err_dsp_irq;
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 5a917dd..4f0481d3 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -2107,6 +2107,9 @@ static int wm5102_probe(struct platform_device *pdev)
arizona_init_common(arizona);
+ ret = arizona_init_vol_limit(arizona);
+ if (ret < 0)
+ goto err_dsp_irq;
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index ba1e90c..6ed1e1f 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -2463,6 +2463,9 @@ static int wm5110_probe(struct platform_device *pdev)
arizona_init_common(arizona);
+ ret = arizona_init_vol_limit(arizona);
+ if (ret < 0)
+ goto err_dsp_irq;
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
goto err_dsp_irq;
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
index c5aef9e..77f5127 100644
--- a/sound/soc/codecs/wm8997.c
+++ b/sound/soc/codecs/wm8997.c
@@ -1176,6 +1176,9 @@ static int wm8997_probe(struct platform_device *pdev)
arizona_init_common(arizona);
+ ret = arizona_init_vol_limit(arizona);
+ if (ret < 0)
+ return ret;
ret = arizona_init_spk_irqs(arizona);
if (ret < 0)
return ret;
--
cgit v1.1
From d24e95f8757e9df5d7a9f56448e609cabe611d0a Mon Sep 17 00:00:00 2001
From: Charles Keepax
Date: Mon, 25 Sep 2017 12:55:07 +0100
Subject: ASoC: wm8998: Correct handling of input muxes
Currently, wm8998 has two input mux controls on IN1 and attempts to
switch these together when the A position is configured to be in digital
mode. This is because the digital mode requires pins from both the L and
R channels. However, this doesn't work as intended because whilst the
registers on the chip are changed the corresponding DAPM
representation is only updated for the mux actually being changed by the
user. The DAPM graph being out of sync with the hardware can cause some
odd issues with incorrect things being powered etc.
To avoid this issue and simplify the code somewhat, simply let the user
set the muxes as they desire. If they set an invalid configuration they
might not get audio from the DMIC but most of the chip requires you to
set a valid audio route to get audio.
Signed-off-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm8998.c | 84 +++++++++++------------------------------------
1 file changed, 19 insertions(+), 65 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 44f4471..4b64bb4 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -101,7 +101,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
return 0;
}
-static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
+static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
@@ -109,84 +109,38 @@ static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = wm8998->core.arizona;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int mux, inmode;
- unsigned int mode_val, src_val;
+ unsigned int mode_reg, mode_index;
+ unsigned int mux, inmode, src_val, mode_val;
mux = ucontrol->value.enumerated.item[0];
if (mux > 1)
return -EINVAL;
- /* L and R registers have same shift and mask */
- inmode = arizona->pdata.inmode[2 * mux];
- src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
- if (inmode & ARIZONA_INMODE_SE)
- src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
-
- switch (arizona->pdata.inmode[0]) {
- case ARIZONA_INMODE_DMIC:
- if (mux)
- mode_val = 0; /* B always analogue */
- else
- mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
-
- snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
- ARIZONA_IN1_MODE_MASK, mode_val);
-
- /* IN1A is digital so L and R must change together */
- /* src_val setting same for both registers */
- snd_soc_update_bits(codec,
- ARIZONA_ADC_DIGITAL_VOLUME_1L,
- ARIZONA_IN1L_SRC_MASK |
- ARIZONA_IN1L_SRC_SE_MASK, src_val);
- snd_soc_update_bits(codec,
- ARIZONA_ADC_DIGITAL_VOLUME_1R,
- ARIZONA_IN1R_SRC_MASK |
- ARIZONA_IN1R_SRC_SE_MASK, src_val);
+ switch (e->reg) {
+ case ARIZONA_ADC_DIGITAL_VOLUME_2L:
+ mode_reg = ARIZONA_IN2L_CONTROL;
+ mode_index = 1 + (2 * mux);
break;
default:
- /* both analogue */
- snd_soc_update_bits(codec,
- e->reg,
- ARIZONA_IN1L_SRC_MASK |
- ARIZONA_IN1L_SRC_SE_MASK,
- src_val);
+ mode_reg = ARIZONA_IN1L_CONTROL;
+ mode_index = (2 * mux);
break;
}
- return snd_soc_dapm_mux_update_power(dapm, kcontrol,
- ucontrol->value.enumerated.item[0],
- e, NULL);
-}
-
-static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
- struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
- struct arizona *arizona = wm8998->core.arizona;
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int mux, inmode, src_val, mode_val;
-
- mux = ucontrol->value.enumerated.item[0];
- if (mux > 1)
- return -EINVAL;
-
- inmode = arizona->pdata.inmode[1 + (2 * mux)];
+ inmode = arizona->pdata.inmode[mode_index];
if (inmode & ARIZONA_INMODE_DMIC)
- mode_val = 1 << ARIZONA_IN2_MODE_SHIFT;
+ mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
else
mode_val = 0;
- src_val = mux << ARIZONA_IN2L_SRC_SHIFT;
+ src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
if (inmode & ARIZONA_INMODE_SE)
- src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT;
+ src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
- snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL,
- ARIZONA_IN2_MODE_MASK, mode_val);
+ snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
- snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L,
- ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK,
+ snd_soc_update_bits(codec, e->reg,
+ ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
src_val);
return snd_soc_dapm_mux_update_power(dapm, kcontrol,
@@ -216,14 +170,14 @@ static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
static const struct snd_kcontrol_new wm8998_in1mux[2] = {
SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
- snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put),
SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
- snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put),
};
static const struct snd_kcontrol_new wm8998_in2mux =
SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
- snd_soc_dapm_get_enum_double, wm8998_in2mux_put);
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put);
static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
--
cgit v1.1
From 8e1b1785489b8b53b4ff934e0ad9259952817f5b Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart
Date: Thu, 7 Sep 2017 20:12:54 -0500
Subject: ASoC: rt5670: refactor DMI quirks and fix Dell Venue settings
Additional checks exposed a mistake in the quirk for the Dell Venue
Pro 5855 (Dmic2 instead of Dmic1). Rather than adding quirk tables,
merge all quirks in a single table and use flags to differentiate
platforms. Also add a parameter override to help support additional
platforms using this codec
CC: Bard Liao
Signed-off-by: Pierre-Louis Bossart
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5670.c | 124 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 105 insertions(+), 19 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 9545764..be945b3 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -34,6 +34,24 @@
#include "rt5670.h"
#include "rt5670-dsp.h"
+#define RT5670_DEV_GPIO BIT(0)
+#define RT5670_IN2_DIFF BIT(1)
+#define RT5670_DMIC_EN BIT(2)
+#define RT5670_DMIC1_IN2P BIT(3)
+#define RT5670_DMIC1_GPIO6 BIT(4)
+#define RT5670_DMIC1_GPIO7 BIT(5)
+#define RT5670_DMIC2_INR BIT(6)
+#define RT5670_DMIC2_GPIO8 BIT(7)
+#define RT5670_DMIC3_GPIO5 BIT(8)
+#define RT5670_JD_MODE1 BIT(9)
+#define RT5670_JD_MODE2 BIT(10)
+#define RT5670_JD_MODE3 BIT(11)
+
+static unsigned long rt5670_quirk;
+static unsigned int quirk_override;
+module_param_named(quirk, quirk_override, uint, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
#define RT5670_DEVICE_ID 0x6271
#define RT5670_PR_RANGE_BASE (0xff + 1)
@@ -2808,56 +2826,84 @@ static const struct acpi_device_id rt5670_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
#endif
-static const struct dmi_system_id dmi_platform_intel_braswell[] = {
+static int rt5670_quirk_cb(const struct dmi_system_id *id)
+{
+ rt5670_quirk = (unsigned long)id->driver_data;
+ return 1;
+}
+
+static const struct dmi_system_id dmi_platform_intel_quirks[] = {
{
+ .callback = rt5670_quirk_cb,
.ident = "Intel Braswell",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC1_IN2P |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE1),
},
{
+ .callback = rt5670_quirk_cb,
.ident = "Dell Wyse 3040",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Wyse 3040"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC1_IN2P |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE1),
},
{
+ .callback = rt5670_quirk_cb,
.ident = "Lenovo Thinkpad Tablet 10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad 10"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC1_IN2P |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE1),
},
{
+ .callback = rt5670_quirk_cb,
.ident = "Lenovo Thinkpad Tablet 10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Tablet B"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC1_IN2P |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE1),
},
- {}
-};
-
-static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode2[] = {
{
+ .callback = rt5670_quirk_cb,
.ident = "Lenovo Thinkpad Tablet 10",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Miix 2 10"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC1_IN2P |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE2),
},
- {}
-};
-
-static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode3[] = {
{
+ .callback = rt5670_quirk_cb,
.ident = "Dell Venue 8 Pro 5855",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5855"),
},
+ .driver_data = (unsigned long *)(RT5670_DMIC_EN |
+ RT5670_DMIC2_INR |
+ RT5670_DEV_GPIO |
+ RT5670_JD_MODE3),
},
{}
};
@@ -2881,21 +2927,61 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
if (pdata)
rt5670->pdata = *pdata;
- if (dmi_check_system(dmi_platform_intel_braswell)) {
- rt5670->pdata.dmic_en = true;
- rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
+ dmi_check_system(dmi_platform_intel_quirks);
+ if (quirk_override) {
+ dev_info(&i2c->dev, "Overriding quirk 0x%x => 0x%x\n",
+ (unsigned int)rt5670_quirk, quirk_override);
+ rt5670_quirk = quirk_override;
+ }
+
+ if (rt5670_quirk & RT5670_DEV_GPIO) {
rt5670->pdata.dev_gpio = true;
- rt5670->pdata.jd_mode = 1;
- } else if (dmi_check_system(dmi_platform_intel_bytcht_jdmode2)) {
+ dev_info(&i2c->dev, "quirk dev_gpio\n");
+ }
+ if (rt5670_quirk & RT5670_IN2_DIFF) {
+ rt5670->pdata.in2_diff = true;
+ dev_info(&i2c->dev, "quirk IN2_DIFF\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC_EN) {
rt5670->pdata.dmic_en = true;
+ dev_info(&i2c->dev, "quirk DMIC enabled\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC1_IN2P) {
rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
- rt5670->pdata.dev_gpio = true;
+ dev_info(&i2c->dev, "quirk DMIC1 on IN2P pin\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC1_GPIO6) {
+ rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO6;
+ dev_info(&i2c->dev, "quirk DMIC1 on GPIO6 pin\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC1_GPIO7) {
+ rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_GPIO7;
+ dev_info(&i2c->dev, "quirk DMIC1 on GPIO7 pin\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC2_INR) {
+ rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_IN3N;
+ dev_info(&i2c->dev, "quirk DMIC2 on INR pin\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC2_GPIO8) {
+ rt5670->pdata.dmic2_data_pin = RT5670_DMIC_DATA_GPIO8;
+ dev_info(&i2c->dev, "quirk DMIC2 on GPIO8 pin\n");
+ }
+ if (rt5670_quirk & RT5670_DMIC3_GPIO5) {
+ rt5670->pdata.dmic3_data_pin = RT5670_DMIC_DATA_GPIO5;
+ dev_info(&i2c->dev, "quirk DMIC3 on GPIO5 pin\n");
+ }
+
+ if (rt5670_quirk & RT5670_JD_MODE1) {
+ rt5670->pdata.jd_mode = 1;
+ dev_info(&i2c->dev, "quirk JD mode 1\n");
+ }
+ if (rt5670_quirk & RT5670_JD_MODE2) {
rt5670->pdata.jd_mode = 2;
- } else if (dmi_check_system(dmi_platform_intel_bytcht_jdmode3)) {
- rt5670->pdata.dmic_en = true;
- rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
- rt5670->pdata.dev_gpio = true;
+ dev_info(&i2c->dev, "quirk JD mode 2\n");
+ }
+ if (rt5670_quirk & RT5670_JD_MODE3) {
rt5670->pdata.jd_mode = 3;
+ dev_info(&i2c->dev, "quirk JD mode 3\n");
}
rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
--
cgit v1.1
From f53ee247ad546183fc13739adafc5579b9f0ebc0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20T=C3=AAtu?=
Date: Fri, 22 Sep 2017 17:44:28 -0400
Subject: ASoC: msm8916-wcd-digital: fix RX2 MIX1 and RX3 MIX1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The kcontrol for the third input (rxN_mix1_inp3) of both RX2
and RX3 mixers are not using the correct control register. This simple
patch fixes this.
Signed-off-by: Jean-François TĂȘtu
Signed-off-by: Mark Brown
---
sound/soc/codecs/msm8916-wcd-digital.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index 66df8f8..a10a724 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -238,7 +238,7 @@ static const struct soc_enum rx_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
static const struct soc_enum rx2_mix1_inp_enum[] = {
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text),
- SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
+ SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text),
};
/* RX2 MIX2 */
@@ -249,7 +249,7 @@ static const struct soc_enum rx2_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
static const struct soc_enum rx3_mix1_inp_enum[] = {
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text),
- SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
+ SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
};
/* DEC */
--
cgit v1.1
From 4eee20246c0fa77a7a7b189ac806d5f78d675546 Mon Sep 17 00:00:00 2001
From: Ryan Lee
Date: Thu, 14 Sep 2017 17:30:38 -0700
Subject: ASoC: max98927: Added support for DSP_A and DSP_B format
Signed-off-by: Ryan Lee
Signed-off-by: Mark Brown
---
sound/soc/codecs/max98927.c | 35 ++++++++++++++++++++---------------
sound/soc/codecs/max98927.h | 6 ++++--
2 files changed, 24 insertions(+), 17 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index d9dbbe7..6f7b3ef 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -1,7 +1,7 @@
/*
* max98927.c -- MAX98927 ALSA Soc Audio driver
*
- * Copyright (C) 2016 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
* Author: Ryan Lee
*
* This program is free software; you can redistribute it and/or modify it
@@ -146,6 +146,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
unsigned int mode = 0;
unsigned int format = 0;
+ bool use_pdm = false;
unsigned int invert = 0;
dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
@@ -187,22 +188,27 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
- max98927->iface |= SND_SOC_DAIFMT_I2S;
format = MAX98927_PCM_FORMAT_I2S;
break;
case SND_SOC_DAIFMT_LEFT_J:
- max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
format = MAX98927_PCM_FORMAT_LJ;
break;
+ case SND_SOC_DAIFMT_DSP_A:
+ format = MAX98927_PCM_FORMAT_TDM_MODE1;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ format = MAX98927_PCM_FORMAT_TDM_MODE0;
+ break;
case SND_SOC_DAIFMT_PDM:
- max98927->iface |= SND_SOC_DAIFMT_PDM;
+ use_pdm = true;
break;
default:
return -EINVAL;
}
+ max98927->iface = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
- /* pcm channel configuration */
- if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
+ if (!use_pdm) {
+ /* pcm channel configuration */
regmap_update_bits(max98927->regmap,
MAX98927_R0018_PCM_RX_EN_A,
MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN,
@@ -217,13 +223,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
MAX98927_R003B_SPK_SRC_SEL,
MAX98927_SPK_SRC_MASK, 0);
- } else
regmap_update_bits(max98927->regmap,
- MAX98927_R0018_PCM_RX_EN_A,
- MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
-
- /* pdm channel configuration */
- if (max98927->iface & SND_SOC_DAIFMT_PDM) {
+ MAX98927_R0035_PDM_RX_CTRL,
+ MAX98927_PDM_RX_EN_MASK, 0);
+ } else {
+ /* pdm channel configuration */
regmap_update_bits(max98927->regmap,
MAX98927_R0035_PDM_RX_CTRL,
MAX98927_PDM_RX_EN_MASK, 1);
@@ -231,10 +235,11 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
regmap_update_bits(max98927->regmap,
MAX98927_R003B_SPK_SRC_SEL,
MAX98927_SPK_SRC_MASK, 3);
- } else
+
regmap_update_bits(max98927->regmap,
- MAX98927_R0035_PDM_RX_CTRL,
- MAX98927_PDM_RX_EN_MASK, 0);
+ MAX98927_R0018_PCM_RX_EN_A,
+ MAX98927_PCM_RX_CH0_EN | MAX98927_PCM_RX_CH1_EN, 0);
+ }
return 0;
}
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index ece6a60..bf7a6f92 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -1,7 +1,7 @@
/*
* max98927.h -- MAX98927 ALSA Soc Audio driver
*
- * Copyright 2013-15 Maxim Integrated Products
+ * Copyright (C) 2016-2017 Maxim Integrated Products
* Author: Ryan Lee
*
* This program is free software; you can redistribute it and/or modify it
@@ -161,7 +161,9 @@
#define MAX98927_PCM_MODE_CFG_FORMAT_SHIFT (3)
#define MAX98927_PCM_FORMAT_I2S (0x0 << 0)
#define MAX98927_PCM_FORMAT_LJ (0x1 << 0)
-
+#define MAX98927_PCM_FORMAT_TDM_MODE0 (0x3 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE1 (0x4 << 0)
+#define MAX98927_PCM_FORMAT_TDM_MODE2 (0x5 << 0)
#define MAX98927_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
#define MAX98927_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
#define MAX98927_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
--
cgit v1.1
From d4a8bce81cbd53420988f5db0d096ad04960f189 Mon Sep 17 00:00:00 2001
From: Ryan Lee
Date: Thu, 14 Sep 2017 17:30:39 -0700
Subject: ASoC: max98927: Added max98927_dai_tdm_slot function
Signed-off-by: Ryan Lee
Signed-off-by: Mark Brown
---
sound/soc/codecs/max98927.c | 120 ++++++++++++++++++++++++++++++++++++++------
sound/soc/codecs/max98927.h | 1 +
2 files changed, 105 insertions(+), 16 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
index 6f7b3ef..a1d3935 100644
--- a/sound/soc/codecs/max98927.c
+++ b/sound/soc/codecs/max98927.c
@@ -250,6 +250,21 @@ static const int rate_table[] = {
13000000, 19200000,
};
+/* BCLKs per LRCLK */
+static const int bclk_sel_table[] = {
+ 32, 48, 64, 96, 128, 192, 256, 384, 512,
+};
+
+static int max98927_get_bclk_sel(int bclk)
+{
+ int i;
+ /* match BCLKs per LRCLK */
+ for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) {
+ if (bclk_sel_table[i] == bclk)
+ return i + 2;
+ }
+ return 0;
+}
static int max98927_set_clock(struct max98927_priv *max98927,
struct snd_pcm_hw_params *params)
{
@@ -275,23 +290,20 @@ static int max98927_set_clock(struct max98927_priv *max98927,
i << MAX98927_PCM_MASTER_MODE_MCLK_RATE_SHIFT);
}
- switch (blr_clk_ratio) {
- case 32:
- value = 2;
- break;
- case 48:
- value = 3;
- break;
- case 64:
- value = 4;
- break;
- default:
- return -EINVAL;
+ if (!max98927->tdm_mode) {
+ /* BCLK configuration */
+ value = max98927_get_bclk_sel(blr_clk_ratio);
+ if (!value) {
+ dev_err(codec->dev, "format unsupported %d\n",
+ params_format(params));
+ return -EINVAL;
+ }
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0022_PCM_CLK_SETUP,
+ MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+ value);
}
- regmap_update_bits(max98927->regmap,
- MAX98927_R0022_PCM_CLK_SETUP,
- MAX98927_PCM_CLK_SETUP_BSEL_MASK,
- value);
return 0;
}
@@ -391,6 +403,78 @@ err:
return -EINVAL;
}
+static int max98927_dai_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
+ int bsel = 0;
+ unsigned int chan_sz = 0;
+
+ max98927->tdm_mode = true;
+
+ /* BCLK configuration */
+ bsel = max98927_get_bclk_sel(slots * slot_width);
+ if (bsel == 0) {
+ dev_err(codec->dev, "BCLK %d not supported\n",
+ slots * slot_width);
+ return -EINVAL;
+ }
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0022_PCM_CLK_SETUP,
+ MAX98927_PCM_CLK_SETUP_BSEL_MASK,
+ bsel);
+
+ /* Channel size configuration */
+ switch (slot_width) {
+ case 16:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_16;
+ break;
+ case 24:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_24;
+ break;
+ case 32:
+ chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32;
+ break;
+ default:
+ dev_err(codec->dev, "format unsupported %d\n",
+ slot_width);
+ return -EINVAL;
+ }
+
+ regmap_update_bits(max98927->regmap,
+ MAX98927_R0020_PCM_MODE_CFG,
+ MAX98927_PCM_MODE_CFG_CHANSZ_MASK, chan_sz);
+
+ /* Rx slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R0018_PCM_RX_EN_A,
+ rx_mask & 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R0019_PCM_RX_EN_B,
+ (rx_mask & 0xFF00) >> 8);
+
+ /* Tx slot configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001A_PCM_TX_EN_A,
+ tx_mask & 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R001B_PCM_TX_EN_B,
+ (tx_mask & 0xFF00) >> 8);
+
+ /* Tx slot Hi-Z configuration */
+ regmap_write(max98927->regmap,
+ MAX98927_R001C_PCM_TX_HIZ_CTRL_A,
+ ~tx_mask & 0xFF);
+ regmap_write(max98927->regmap,
+ MAX98927_R001D_PCM_TX_HIZ_CTRL_B,
+ (~tx_mask & 0xFF00) >> 8);
+
+ return 0;
+}
+
#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -410,6 +494,7 @@ static const struct snd_soc_dai_ops max98927_dai_ops = {
.set_sysclk = max98927_dai_set_sysclk,
.set_fmt = max98927_dai_set_fmt,
.hw_params = max98927_dai_hw_params,
+ .set_tdm_slot = max98927_dai_tdm_slot,
};
static int max98927_dac_event(struct snd_soc_dapm_widget *w,
@@ -419,6 +504,9 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w,
struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ max98927->tdm_mode = 0;
+ break;
case SND_SOC_DAPM_POST_PMU:
regmap_update_bits(max98927->regmap,
MAX98927_R003A_AMP_EN,
diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
index bf7a6f92..9ea8397 100644
--- a/sound/soc/codecs/max98927.h
+++ b/sound/soc/codecs/max98927.h
@@ -270,5 +270,6 @@ struct max98927_priv {
unsigned int iface;
unsigned int master;
unsigned int digital_gain;
+ bool tdm_mode;
};
#endif
--
cgit v1.1
From d0817657f615ecdf1c7beceade20c7d368003875 Mon Sep 17 00:00:00 2001
From: Bard Liao
Date: Wed, 13 Sep 2017 14:50:17 +0800
Subject: ASoC: rt5670: add set_bclk_ratio in dai ops
We need to set a specific bit for 50 bclk rate. So add set_bclk_ratio
function to set the bit.
Signed-off-by: Bard Liao
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5670.c | 19 +++++++++++++++++++
sound/soc/codecs/rt5670.h | 4 ++++
2 files changed, 23 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index be945b3..c5094b4 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -2600,6 +2600,24 @@ static int rt5670_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
return 0;
}
+static int rt5670_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+ struct snd_soc_codec *codec = dai->codec;
+
+ dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio);
+ if (dai->id != RT5670_AIF1)
+ return 0;
+
+ if ((ratio % 50) == 0)
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+ RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_50FS);
+ else
+ snd_soc_update_bits(codec, RT5670_GEN_CTRL3,
+ RT5670_TDM_DATA_MODE_SEL, RT5670_TDM_DATA_MODE_NOR);
+
+ return 0;
+}
+
static int rt5670_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
@@ -2730,6 +2748,7 @@ static const struct snd_soc_dai_ops rt5670_aif_dai_ops = {
.set_fmt = rt5670_set_dai_fmt,
.set_tdm_slot = rt5670_set_tdm_slot,
.set_pll = rt5670_set_dai_pll,
+ .set_bclk_ratio = rt5670_set_bclk_ratio,
};
static struct snd_soc_dai_driver rt5670_dai[] = {
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 5ba485c..265df80 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1816,6 +1816,10 @@
#define RT5670_ZCD_HP_DIS (0x0 << 15)
#define RT5670_ZCD_HP_EN (0x1 << 15)
+/* General Control 3 (0xfc) */
+#define RT5670_TDM_DATA_MODE_SEL (0x1 << 11)
+#define RT5670_TDM_DATA_MODE_NOR (0x0 << 11)
+#define RT5670_TDM_DATA_MODE_50FS (0x1 << 11)
/* Codec Private Register definition */
/* 3D Speaker Control (0x63) */
--
cgit v1.1
From d430a7e3abbf98b4bcb16522cab8e4591775883e Mon Sep 17 00:00:00 2001
From: Damien Riegel
Date: Wed, 13 Sep 2017 16:43:55 -0400
Subject: ASoC: codecs: msm8916-wcd-analog: use btn0 released detection
msm8916-wcd-analog uses button0 to differentiate between headphone and
headset. Under some circumstances, button pressed and released
interrupts are not fired as the driver expects it.
For instance, with some connectors, there are spurious button-pressed
interrupts when unplugging a headphone, without the corresponding
button-released interrupt. But the codec always alternates between
button pressed and released interrupts, it cannot fire two interrupts of
the same kind in a row. That means that when the headphone is plugged
back, only a button-released interrupt will be fired instead of pressed
then released. This causes the driver to report headphone as headset.
By changing the logic and relying on button 0 release interrupt, the
driver could be made more robust for connectors that differ from the one
used on the Dragonboard's audio mezzanine.
Signed-off-by: Damien Riegel
Signed-off-by: Mark Brown
---
sound/soc/codecs/msm8916-wcd-analog.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 549c269..f562f2d 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -285,7 +285,7 @@ struct pm8916_wcd_analog_priv {
u16 codec_version;
bool mbhc_btn_enabled;
/* special event to detect accessory type */
- bool mbhc_btn0_pressed;
+ int mbhc_btn0_released;
bool detect_accessory_type;
struct clk *mclk;
struct snd_soc_codec *codec;
@@ -483,7 +483,7 @@ static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
- wcd->mbhc_btn0_pressed = false;
+ wcd->mbhc_btn0_released = false;
wcd->detect_accessory_type = true;
}
@@ -950,7 +950,7 @@ static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg)
/* check if its BTN0 thats released */
if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK))
- priv->mbhc_btn0_pressed = false;
+ priv->mbhc_btn0_released = true;
} else {
snd_soc_jack_report(priv->jack, 0, btn_mask);
@@ -983,9 +983,7 @@ static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg)
break;
case 0x0:
/* handle BTN_0 specially for type detection */
- if (priv->detect_accessory_type)
- priv->mbhc_btn0_pressed = true;
- else
+ if (!priv->detect_accessory_type)
snd_soc_jack_report(priv->jack,
SND_JACK_BTN_0, btn_mask);
break;
@@ -1029,19 +1027,19 @@ static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg)
* both press and release event received then its
* a headset.
*/
- if (priv->mbhc_btn0_pressed)
+ if (priv->mbhc_btn0_released)
snd_soc_jack_report(priv->jack,
- SND_JACK_HEADPHONE, hs_jack_mask);
+ SND_JACK_HEADSET, hs_jack_mask);
else
snd_soc_jack_report(priv->jack,
- SND_JACK_HEADSET, hs_jack_mask);
+ SND_JACK_HEADPHONE, hs_jack_mask);
priv->detect_accessory_type = false;
} else { /* removal */
snd_soc_jack_report(priv->jack, 0, hs_jack_mask);
priv->detect_accessory_type = true;
- priv->mbhc_btn0_pressed = false;
+ priv->mbhc_btn0_released = false;
}
return IRQ_HANDLED;
--
cgit v1.1
From 46d69e141d479585c105a4d5b2337cd2ce6967e5 Mon Sep 17 00:00:00 2001
From: Nicolas Dechesne
Date: Tue, 3 Oct 2017 11:49:51 +0200
Subject: ASoC: codecs: msm8916-wcd-analog: fix module autoload
If the driver is built as a module, autoload won't work because the module
alias information is not filled. So user-space can't match the registered
device with the corresponding module.
Export the module alias information using the MODULE_DEVICE_TABLE() macro.
Before this patch:
$ modinfo snd_soc_msm8916_analog | grep alias
$
After this patch:
$ modinfo snd_soc_msm8916_analog | grep alias
alias: of:N*T*Cqcom,pm8916-wcd-analog-codecC*
alias: of:N*T*Cqcom,pm8916-wcd-analog-codec
Signed-off-by: Nicolas Dechesne
Signed-off-by: Mark Brown
---
sound/soc/codecs/msm8916-wcd-analog.c | 2 ++
1 file changed, 2 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index f562f2d..3593c57 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -1239,6 +1239,8 @@ static const struct of_device_id pm8916_wcd_analog_spmi_match_table[] = {
{ }
};
+MODULE_DEVICE_TABLE(of, pm8916_wcd_analog_spmi_match_table);
+
static struct platform_driver pm8916_wcd_analog_spmi_driver = {
.driver = {
.name = "qcom,pm8916-wcd-spmi-codec",
--
cgit v1.1
From 79f01fe6262b0fbba4c558dfe3dd61b3c511a61a Mon Sep 17 00:00:00 2001
From: Damien Riegel
Date: Tue, 3 Oct 2017 09:27:35 -0400
Subject: ASoC: codecs: msm8916-wcd-analog: configure micbias in mbhc setup
The very first time a headset is plugged in, detection is unreliable
because bias hasn't been configured yet, it's done once a mechanical
insertion interrupt has been triggered, so following insertions (and
thus detections) are not affected.
To fix the very first detection, the bias must also be configured in the
function that setup the MBHC. Move pm8916_wcd_setup_mbhc after
pm8916_mbhc_configure_bias to avoid a forward declaration.
Signed-off-by: Damien Riegel
Acked-by: Srinivas Kandagatla
Signed-off-by: Mark Brown
---
sound/soc/codecs/msm8916-wcd-analog.c | 94 +++++++++++++++++++----------------
1 file changed, 50 insertions(+), 44 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 3593c57..8db5824 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -443,50 +443,6 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct
wcd->micbias1_cap_mode);
}
-static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
-{
- struct snd_soc_codec *codec = wcd->codec;
- u32 plug_type = 0;
- u32 int_en_mask;
-
- snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
- CDC_A_MBHC_DET_CTL_L_DET_EN |
- CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
- CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
- CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
-
- if (wcd->hphl_jack_type_normally_open)
- plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
-
- if (wcd->gnd_jack_type_normally_open)
- plug_type |= CDC_A_GND_PLUG_TYPE_NO;
-
- snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
- CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
- CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
- plug_type |
- CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
-
-
- snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
- CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
- CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
-
- /* enable MBHC clock */
- snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
- DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
- DIG_CLK_CTL_D_MBHC_CLK_EN);
-
- int_en_mask = MBHC_SWITCH_INT;
- if (wcd->mbhc_btn_enabled)
- int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
-
- snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
- snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
- wcd->mbhc_btn0_released = false;
- wcd->detect_accessory_type = true;
-}
-
static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
bool micbias2_enabled)
{
@@ -534,6 +490,56 @@ static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv,
return 0;
}
+static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd)
+{
+ struct snd_soc_codec *codec = wcd->codec;
+ bool micbias_enabled = false;
+ u32 plug_type = 0;
+ u32 int_en_mask;
+
+ snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1,
+ CDC_A_MBHC_DET_CTL_L_DET_EN |
+ CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION |
+ CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO |
+ CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN);
+
+ if (wcd->hphl_jack_type_normally_open)
+ plug_type |= CDC_A_HPHL_PLUG_TYPE_NO;
+
+ if (wcd->gnd_jack_type_normally_open)
+ plug_type |= CDC_A_GND_PLUG_TYPE_NO;
+
+ snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2,
+ CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 |
+ CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD |
+ plug_type |
+ CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN);
+
+
+ snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER,
+ CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS |
+ CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS);
+
+ /* enable MBHC clock */
+ snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL,
+ DIG_CLK_CTL_D_MBHC_CLK_EN_MASK,
+ DIG_CLK_CTL_D_MBHC_CLK_EN);
+
+ if (snd_soc_read(codec, CDC_A_MICB_2_EN) & CDC_A_MICB_2_EN_ENABLE)
+ micbias_enabled = true;
+
+ pm8916_mbhc_configure_bias(wcd, micbias_enabled);
+
+ int_en_mask = MBHC_SWITCH_INT;
+ if (wcd->mbhc_btn_enabled)
+ int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET;
+
+ snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0);
+ snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask);
+ wcd->mbhc_btn0_released = false;
+ wcd->detect_accessory_type = true;
+}
+
static int pm8916_wcd_analog_enable_micbias_int2(struct
snd_soc_dapm_widget
*w, struct snd_kcontrol
--
cgit v1.1
From 664611e7e02f76fbc5470ef545b2657ed25c292b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20T=C3=AAtu?=
Date: Fri, 29 Sep 2017 16:19:44 -0400
Subject: ASoC: codecs: msm8916-wcd-analog: fix micbias level
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The macro used to set the microphone bias level causes the
snd_soc_write() call to overwrite other fields in the CDC_A_MICB_1_VAL
register. The macro also does not return the proper level value
to use. This fixes this by preserving all bits from the register
that are not the level while setting the level.
Signed-off-by: Jean-François TĂȘtu
Acked-by: Srinivas Kandagatla
Signed-off-by: Mark Brown
---
sound/soc/codecs/msm8916-wcd-analog.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 549c269..a42f8eb 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -104,7 +104,7 @@
#define CDC_A_MICB_1_VAL (0xf141)
#define MICB_MIN_VAL 1600
#define MICB_STEP_SIZE 50
-#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE)
+#define MICB_VOLTAGE_REGVAL(v) (((v - MICB_MIN_VAL)/MICB_STEP_SIZE) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3)
#define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3)
@@ -349,8 +349,9 @@ static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
| MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
if (wcd->micbias_mv) {
- snd_soc_write(codec, CDC_A_MICB_1_VAL,
- MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
+ snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
+ MICB_1_VAL_MICB_OUT_VAL_MASK,
+ MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
/*
* Special headset needs MICBIAS as 2.7V so wait for
* 50 msec for the MICBIAS to reach 2.7 volts.
--
cgit v1.1
From d6e18b8295593d8f59e92f6634577cbacae14629 Mon Sep 17 00:00:00 2001
From: Axel Lin
Date: Fri, 13 Oct 2017 09:21:01 +0800
Subject: ASoC: max98925: Return proper error if revision mismatch
Return proper error instead of 0 if the revision does not match.
Signed-off-by: Axel Lin
Signed-off-by: Mark Brown
---
sound/soc/codecs/max98925.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c
index 327eaa2..921f95f 100644
--- a/sound/soc/codecs/max98925.c
+++ b/sound/soc/codecs/max98925.c
@@ -579,7 +579,7 @@ static int max98925_i2c_probe(struct i2c_client *i2c,
ret = PTR_ERR(max98925->regmap);
dev_err(&i2c->dev,
"Failed to allocate regmap: %d\n", ret);
- goto err_out;
+ return ret;
}
if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {
@@ -596,16 +596,20 @@ static int max98925_i2c_probe(struct i2c_client *i2c,
}
max98925->i_slot = value;
}
- ret = regmap_read(max98925->regmap,
- MAX98925_REV_VERSION, ®);
- if ((ret < 0) ||
- ((reg != MAX98925_VERSION) &&
- (reg != MAX98925_VERSION1))) {
- dev_err(&i2c->dev,
- "device initialization error (%d 0x%02X)\n",
+
+ ret = regmap_read(max98925->regmap, MAX98925_REV_VERSION, ®);
+ if (ret < 0) {
+ dev_err(&i2c->dev, "Read revision failed\n");
+ return ret;
+ }
+
+ if ((reg != MAX98925_VERSION) && (reg != MAX98925_VERSION1)) {
+ ret = -ENODEV;
+ dev_err(&i2c->dev, "Invalid revision (%d 0x%02X)\n",
ret, reg);
- goto err_out;
+ return ret;
}
+
dev_info(&i2c->dev, "device version 0x%02X\n", reg);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98925,
@@ -613,7 +617,6 @@ static int max98925_i2c_probe(struct i2c_client *i2c,
if (ret < 0)
dev_err(&i2c->dev,
"Failed to register codec: %d\n", ret);
-err_out:
return ret;
}
--
cgit v1.1
From 6bd25aae3a9bc7ed3d24f2b3d4cd711fadc5d32e Mon Sep 17 00:00:00 2001
From: Robert Jarzmik
Date: Sat, 14 Oct 2017 22:14:02 +0200
Subject: ASoC: wm97xx: fix compilation corner case
When the old AC97 is not used, CONFIG_SND_SOC_AC97_BUS is not
defined. As a consequence, in the error path, snd_soc_free_ac97_codec()
is not defined and triggers a compilation error.
Fix it for wm9705 and wm9712, as wm9713 is correctly written.
Signed-off-by: Robert Jarzmik
Acked-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm9705.c | 8 ++------
sound/soc/codecs/wm9712.c | 7 ++-----
2 files changed, 4 insertions(+), 11 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 68c204e..2c09f71 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -321,7 +321,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
{
struct wm9705_priv *wm9705 = snd_soc_codec_get_drvdata(codec);
struct regmap *regmap;
- int ret;
if (wm9705->mfd_pdata) {
wm9705->ac97 = wm9705->mfd_pdata->ac97;
@@ -337,8 +336,8 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
regmap = regmap_init_ac97(wm9705->ac97, &wm9705_regmap_config);
if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- goto err_free_ac97_codec;
+ snd_soc_free_ac97_codec(wm9705->ac97);
+ return PTR_ERR(regmap);
}
#endif
}
@@ -347,9 +346,6 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
snd_soc_codec_init_regmap(codec, regmap);
return 0;
-err_free_ac97_codec:
- snd_soc_free_ac97_codec(wm9705->ac97);
- return ret;
}
static int wm9705_soc_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 9db5c77..4f6d1a4 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -656,8 +656,8 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
regmap = regmap_init_ac97(wm9712->ac97, &wm9712_regmap_config);
if (IS_ERR(regmap)) {
- ret = PTR_ERR(regmap);
- goto err_free_ac97_codec;
+ snd_soc_free_ac97_codec(wm9712->ac97);
+ return PTR_ERR(regmap);
}
#endif
}
@@ -668,9 +668,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
snd_soc_update_bits(codec, AC97_VIDEO, 0x3000, 0x3000);
return 0;
-err_free_ac97_codec:
- snd_soc_free_ac97_codec(wm9712->ac97);
- return ret;
}
static int wm9712_soc_remove(struct snd_soc_codec *codec)
--
cgit v1.1
From fe01e5e8fae91b235ecf928f6bf0a90c17d74e36 Mon Sep 17 00:00:00 2001
From: Bard Liao
Date: Mon, 16 Oct 2017 19:15:15 +0800
Subject: ASoC: rt5659: move set_sysclk to codec level
Move set_sysclk to codec level and people can use it at both
codec and dai level.
Signed-off-by: Bard Liao
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5659.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index fa66b11..09cfddb 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -3385,10 +3385,9 @@ static int rt5659_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
-static int rt5659_set_dai_sysclk(struct snd_soc_dai *dai,
- int clk_id, unsigned int freq, int dir)
+static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
+ int source, unsigned int freq, int dir)
{
- struct snd_soc_codec *codec = dai->codec;
struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
unsigned int reg_val = 0;
@@ -3414,7 +3413,8 @@ static int rt5659_set_dai_sysclk(struct snd_soc_dai *dai,
rt5659->sysclk = freq;
rt5659->sysclk_src = clk_id;
- dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
+ dev_dbg(codec->dev, "Sysclk is %dHz and clock id is %d\n",
+ freq, clk_id);
return 0;
}
@@ -3666,7 +3666,6 @@ static int rt5659_resume(struct snd_soc_codec *codec)
static const struct snd_soc_dai_ops rt5659_aif_dai_ops = {
.hw_params = rt5659_hw_params,
.set_fmt = rt5659_set_dai_fmt,
- .set_sysclk = rt5659_set_dai_sysclk,
.set_tdm_slot = rt5659_set_tdm_slot,
.set_pll = rt5659_set_dai_pll,
.set_bclk_ratio = rt5659_set_bclk_ratio,
@@ -3747,6 +3746,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
.dapm_routes = rt5659_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
},
+ .set_sysclk = rt5659_set_codec_sysclk,
};
--
cgit v1.1
From c8a04b5de4bbdd0c7553aaa315c72722b10f0207 Mon Sep 17 00:00:00 2001
From: Bard Liao
Date: Mon, 16 Oct 2017 19:15:16 +0800
Subject: ASoC: rt5659: move set_pll to codec level
Move set_pll function to codec level and people can use it at both
codec and dai level.
Signed-off-by: Bard Liao
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5659.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 09cfddb..07e7757 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -3419,15 +3419,15 @@ static int rt5659_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id,
return 0;
}
-static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
- unsigned int freq_in, unsigned int freq_out)
+static int rt5659_set_codec_pll(struct snd_soc_codec *codec, int pll_id,
+ int source, unsigned int freq_in,
+ unsigned int freq_out)
{
- struct snd_soc_codec *codec = dai->codec;
struct rt5659_priv *rt5659 = snd_soc_codec_get_drvdata(codec);
struct rl6231_pll_code pll_code;
int ret;
- if (Source == rt5659->pll_src && freq_in == rt5659->pll_in &&
+ if (source == rt5659->pll_src && freq_in == rt5659->pll_in &&
freq_out == rt5659->pll_out)
return 0;
@@ -3441,7 +3441,7 @@ static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
return 0;
}
- switch (Source) {
+ switch (source) {
case RT5659_PLL1_S_MCLK:
snd_soc_update_bits(codec, RT5659_GLB_CLK,
RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_MCLK);
@@ -3459,7 +3459,7 @@ static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
RT5659_PLL1_SRC_MASK, RT5659_PLL1_SRC_BCLK3);
break;
default:
- dev_err(codec->dev, "Unknown PLL Source %d\n", Source);
+ dev_err(codec->dev, "Unknown PLL source %d\n", source);
return -EINVAL;
}
@@ -3481,7 +3481,7 @@ static int rt5659_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int Source,
rt5659->pll_in = freq_in;
rt5659->pll_out = freq_out;
- rt5659->pll_src = Source;
+ rt5659->pll_src = source;
return 0;
}
@@ -3667,7 +3667,6 @@ static const struct snd_soc_dai_ops rt5659_aif_dai_ops = {
.hw_params = rt5659_hw_params,
.set_fmt = rt5659_set_dai_fmt,
.set_tdm_slot = rt5659_set_tdm_slot,
- .set_pll = rt5659_set_dai_pll,
.set_bclk_ratio = rt5659_set_bclk_ratio,
};
@@ -3747,6 +3746,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = {
.num_dapm_routes = ARRAY_SIZE(rt5659_dapm_routes),
},
.set_sysclk = rt5659_set_codec_sysclk,
+ .set_pll = rt5659_set_codec_pll,
};
--
cgit v1.1
From be96fc54d2ed8eae6683b71d2dc5d1a939a10a1e Mon Sep 17 00:00:00 2001
From: Carlo Caione
Date: Wed, 18 Oct 2017 18:06:31 +0100
Subject: ASoC: rt5651: Convert rt5651 micbias1 to a supply widget
MICBIAS widget type has been deprecated. Convert it to a SUPPLY widget.
Signed-off-by: Carlo Caione
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index da60b28..28f7210 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -883,8 +883,8 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
/* micbias */
SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
RT5651_PWR_LDO_BIT, 0, NULL, 0),
- SND_SOC_DAPM_MICBIAS("micbias1", RT5651_PWR_ANLG2,
- RT5651_PWR_MB1_BIT, 0),
+ SND_SOC_DAPM_SUPPLY("micbias1", RT5651_PWR_ANLG2,
+ RT5651_PWR_MB1_BIT, 0, NULL, 0),
/* Input Lines */
SND_SOC_DAPM_INPUT("MIC1"),
SND_SOC_DAPM_INPUT("MIC2"),
--
cgit v1.1
From 60d5a1a47b9a8381c08d2263b11ac9c757c87746 Mon Sep 17 00:00:00 2001
From: Carlo Caione
Date: Fri, 20 Oct 2017 12:18:55 +0100
Subject: ASoC: rt5651: Enable jack detection on JD* pins
Enable jack detection for the RT5651 codec on the JD* pins.
Signed-off-by: Carlo Caione
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 168 +++++++++++++++++++++++++++++++++++++++++++++-
sound/soc/codecs/rt5651.h | 4 ++
2 files changed, 170 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index da60b28..2f0d005 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "rl6231.h"
#include "rt5651.h"
@@ -880,6 +881,9 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
RT5651_PWR_PLL_BIT, 0, NULL, 0),
/* Input Side */
+ SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
+ RT5651_PWM_JD_M_BIT, 0, NULL, 0),
+
/* micbias */
SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1528,6 +1532,8 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
static int rt5651_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
@@ -1556,8 +1562,13 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
- snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
- snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
+ if (rt5651->pdata.jd_src) {
+ snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
+ snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
+ } else {
+ snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
+ snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
+ }
break;
default:
@@ -1570,6 +1581,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
static int rt5651_probe(struct snd_soc_codec *codec)
{
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
rt5651->codec = codec;
@@ -1585,6 +1597,15 @@ static int rt5651_probe(struct snd_soc_codec *codec)
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (rt5651->pdata.jd_src) {
+ snd_soc_dapm_force_enable_pin(dapm, "JD Power");
+ snd_soc_dapm_force_enable_pin(dapm, "LDO");
+ snd_soc_dapm_sync(dapm);
+
+ regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
+ 0x38, 0x38);
+ }
+
return 0;
}
@@ -1728,6 +1749,93 @@ static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
return 0;
}
+static irqreturn_t rt5651_irq(int irq, void *data)
+{
+ struct rt5651_priv *rt5651 = data;
+
+ queue_delayed_work(system_power_efficient_wq,
+ &rt5651->jack_detect_work, msecs_to_jiffies(250));
+
+ return IRQ_HANDLED;
+}
+
+static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ int jack_type;
+
+ if (jack_insert) {
+ snd_soc_dapm_force_enable_pin(dapm, "LDO");
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_update_bits(codec, RT5651_MICBIAS,
+ RT5651_MIC1_OVCD_MASK |
+ RT5651_MIC1_OVTH_MASK |
+ RT5651_PWR_CLK12M_MASK |
+ RT5651_PWR_MB_MASK,
+ RT5651_MIC1_OVCD_EN |
+ RT5651_MIC1_OVTH_600UA |
+ RT5651_PWR_MB_PU |
+ RT5651_PWR_CLK12M_PU);
+ msleep(100);
+ if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
+ jack_type = SND_JACK_HEADPHONE;
+ else
+ jack_type = SND_JACK_HEADSET;
+ snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
+ RT5651_MB1_OC_CLR, 0);
+ } else { /* jack out */
+ jack_type = 0;
+
+ snd_soc_update_bits(codec, RT5651_MICBIAS,
+ RT5651_MIC1_OVCD_MASK,
+ RT5651_MIC1_OVCD_DIS);
+ }
+
+ return jack_type;
+}
+
+static void rt5651_jack_detect_work(struct work_struct *work)
+{
+ struct rt5651_priv *rt5651 =
+ container_of(work, struct rt5651_priv, jack_detect_work.work);
+
+ int report, val = 0;
+
+ if (!rt5651->codec)
+ return;
+
+ switch (rt5651->pdata.jd_src) {
+ case RT5651_JD1_1:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
+ break;
+ case RT5651_JD1_2:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
+ break;
+ case RT5651_JD2:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
+ break;
+ default:
+ break;
+ }
+
+ report = rt5651_jack_detect(rt5651->codec, !val);
+
+ snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
+}
+
+int rt5651_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack)
+{
+ struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+
+ rt5651->hp_jack = hp_jack;
+ rt5651_irq(0, rt5651);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
+
static int rt5651_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -1779,6 +1887,59 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
rt5651->hp_mute = 1;
+ if (rt5651->pdata.jd_src) {
+
+ /* IRQ output on GPIO1 */
+ regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
+ RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
+
+ switch (rt5651->pdata.jd_src) {
+ case RT5651_JD1_1:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD1_1);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD1_1_IRQ_EN,
+ RT5651_JD1_1_IRQ_EN);
+ break;
+ case RT5651_JD1_2:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD1_2);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD1_2_IRQ_EN,
+ RT5651_JD1_2_IRQ_EN);
+ break;
+ case RT5651_JD2:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD2);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD2_IRQ_EN,
+ RT5651_JD2_IRQ_EN);
+ break;
+ case RT5651_JD_NULL:
+ break;
+ default:
+ dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
+ break;
+ }
+ }
+
+ INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
+
+ if (i2c->irq) {
+ ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
+ rt5651_irq,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT, "rt5651", rt5651);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
+ return ret;
+ }
+ }
+
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
rt5651_dai, ARRAY_SIZE(rt5651_dai));
@@ -1787,6 +1948,9 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
static int rt5651_i2c_remove(struct i2c_client *i2c)
{
+ struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
+
+ cancel_delayed_work_sync(&rt5651->jack_detect_work);
snd_soc_unregister_codec(&i2c->dev);
return 0;
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 1bd33cf..4f8b202 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -2062,6 +2062,8 @@ struct rt5651_priv {
struct snd_soc_codec *codec;
struct rt5651_platform_data pdata;
struct regmap *regmap;
+ struct snd_soc_jack *hp_jack;
+ struct delayed_work jack_detect_work;
int sysclk;
int sysclk_src;
@@ -2077,4 +2079,6 @@ struct rt5651_priv {
bool hp_mute;
};
+int rt5651_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack);
#endif /* __RT5651_H__ */
--
cgit v1.1
From 7211ec6392c8650ebc804023178c245464417ed2 Mon Sep 17 00:00:00 2001
From: Kees Cook
Date: Wed, 25 Oct 2017 08:09:27 -0700
Subject: ALSA: Convert timers to use timer_setup()
In preparation for unconditionally passing the struct timer_list
pointer to all timer callbacks, switch to using the new timer_setup()
and from_timer() to pass the timer pointer explicitly. These are all the
"mechanical" changes remaining in the sound subsystem.
Signed-off-by: Kees Cook
Acked-by: Mark Brown
Signed-off-by: Takashi Iwai
---
sound/soc/codecs/rt5645.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index a98647a..735f2d0 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -3340,9 +3340,9 @@ static irqreturn_t rt5645_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static void rt5645_btn_check_callback(unsigned long data)
+static void rt5645_btn_check_callback(struct timer_list *t)
{
- struct rt5645_priv *rt5645 = (struct rt5645_priv *)data;
+ struct rt5645_priv *rt5645 = from_timer(rt5645, t, btn_check_timer);
queue_delayed_work(system_power_efficient_wq,
&rt5645->jack_detect_work, msecs_to_jiffies(5));
@@ -3934,8 +3934,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
}
- setup_timer(&rt5645->btn_check_timer,
- rt5645_btn_check_callback, (unsigned long)rt5645);
+ timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0);
INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
--
cgit v1.1
From 80bbe4a30bc6b119df86c280c91cde2034309bf1 Mon Sep 17 00:00:00 2001
From: Carlo Caione
Date: Fri, 20 Oct 2017 12:18:55 +0100
Subject: ASoC: rt5651: Enable jack detection on JD* pins
Enable jack detection for the RT5651 codec on the JD* pins.
Signed-off-by: Carlo Caione
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 168 +++++++++++++++++++++++++++++++++++++++++++++-
sound/soc/codecs/rt5651.h | 4 ++
2 files changed, 170 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 28f7210..91f2543 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "rl6231.h"
#include "rt5651.h"
@@ -880,6 +881,9 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
RT5651_PWR_PLL_BIT, 0, NULL, 0),
/* Input Side */
+ SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
+ RT5651_PWM_JD_M_BIT, 0, NULL, 0),
+
/* micbias */
SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1528,6 +1532,8 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
static int rt5651_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
@@ -1556,8 +1562,13 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
- snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
- snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
+ if (rt5651->pdata.jd_src) {
+ snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
+ snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
+ } else {
+ snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
+ snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
+ }
break;
default:
@@ -1570,6 +1581,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
static int rt5651_probe(struct snd_soc_codec *codec)
{
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
rt5651->codec = codec;
@@ -1585,6 +1597,15 @@ static int rt5651_probe(struct snd_soc_codec *codec)
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
+ if (rt5651->pdata.jd_src) {
+ snd_soc_dapm_force_enable_pin(dapm, "JD Power");
+ snd_soc_dapm_force_enable_pin(dapm, "LDO");
+ snd_soc_dapm_sync(dapm);
+
+ regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
+ 0x38, 0x38);
+ }
+
return 0;
}
@@ -1728,6 +1749,93 @@ static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
return 0;
}
+static irqreturn_t rt5651_irq(int irq, void *data)
+{
+ struct rt5651_priv *rt5651 = data;
+
+ queue_delayed_work(system_power_efficient_wq,
+ &rt5651->jack_detect_work, msecs_to_jiffies(250));
+
+ return IRQ_HANDLED;
+}
+
+static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ int jack_type;
+
+ if (jack_insert) {
+ snd_soc_dapm_force_enable_pin(dapm, "LDO");
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_update_bits(codec, RT5651_MICBIAS,
+ RT5651_MIC1_OVCD_MASK |
+ RT5651_MIC1_OVTH_MASK |
+ RT5651_PWR_CLK12M_MASK |
+ RT5651_PWR_MB_MASK,
+ RT5651_MIC1_OVCD_EN |
+ RT5651_MIC1_OVTH_600UA |
+ RT5651_PWR_MB_PU |
+ RT5651_PWR_CLK12M_PU);
+ msleep(100);
+ if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
+ jack_type = SND_JACK_HEADPHONE;
+ else
+ jack_type = SND_JACK_HEADSET;
+ snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
+ RT5651_MB1_OC_CLR, 0);
+ } else { /* jack out */
+ jack_type = 0;
+
+ snd_soc_update_bits(codec, RT5651_MICBIAS,
+ RT5651_MIC1_OVCD_MASK,
+ RT5651_MIC1_OVCD_DIS);
+ }
+
+ return jack_type;
+}
+
+static void rt5651_jack_detect_work(struct work_struct *work)
+{
+ struct rt5651_priv *rt5651 =
+ container_of(work, struct rt5651_priv, jack_detect_work.work);
+
+ int report, val = 0;
+
+ if (!rt5651->codec)
+ return;
+
+ switch (rt5651->pdata.jd_src) {
+ case RT5651_JD1_1:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
+ break;
+ case RT5651_JD1_2:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
+ break;
+ case RT5651_JD2:
+ val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
+ break;
+ default:
+ break;
+ }
+
+ report = rt5651_jack_detect(rt5651->codec, !val);
+
+ snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
+}
+
+int rt5651_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack)
+{
+ struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
+
+ rt5651->hp_jack = hp_jack;
+ rt5651_irq(0, rt5651);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
+
static int rt5651_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -1779,6 +1887,59 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
rt5651->hp_mute = 1;
+ if (rt5651->pdata.jd_src) {
+
+ /* IRQ output on GPIO1 */
+ regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
+ RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
+
+ switch (rt5651->pdata.jd_src) {
+ case RT5651_JD1_1:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD1_1);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD1_1_IRQ_EN,
+ RT5651_JD1_1_IRQ_EN);
+ break;
+ case RT5651_JD1_2:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD1_2);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD1_2_IRQ_EN,
+ RT5651_JD1_2_IRQ_EN);
+ break;
+ case RT5651_JD2:
+ regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
+ RT5651_JD_TRG_SEL_MASK,
+ RT5651_JD_TRG_SEL_JD2);
+ regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
+ RT5651_JD2_IRQ_EN,
+ RT5651_JD2_IRQ_EN);
+ break;
+ case RT5651_JD_NULL:
+ break;
+ default:
+ dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
+ break;
+ }
+ }
+
+ INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
+
+ if (i2c->irq) {
+ ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
+ rt5651_irq,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT, "rt5651", rt5651);
+ if (ret) {
+ dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
+ return ret;
+ }
+ }
+
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
rt5651_dai, ARRAY_SIZE(rt5651_dai));
@@ -1787,6 +1948,9 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
static int rt5651_i2c_remove(struct i2c_client *i2c)
{
+ struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
+
+ cancel_delayed_work_sync(&rt5651->jack_detect_work);
snd_soc_unregister_codec(&i2c->dev);
return 0;
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 1bd33cf..4f8b202 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -2062,6 +2062,8 @@ struct rt5651_priv {
struct snd_soc_codec *codec;
struct rt5651_platform_data pdata;
struct regmap *regmap;
+ struct snd_soc_jack *hp_jack;
+ struct delayed_work jack_detect_work;
int sysclk;
int sysclk_src;
@@ -2077,4 +2079,6 @@ struct rt5651_priv {
bool hp_mute;
};
+int rt5651_set_jack_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *hp_jack);
#endif /* __RT5651_H__ */
--
cgit v1.1
From b4435130bc19cd54631588355b16326aeb760e34 Mon Sep 17 00:00:00 2001
From: Carlo Caione
Date: Fri, 20 Oct 2017 12:18:58 +0100
Subject: ASoC: rt5651: Rework quirk logic
Rework a bit the quirk logic in the codec driver to simplify the
DMI-based quirk assignment for non-DT platforms.
Signed-off-by: Carlo Caione
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 91f2543..f01d411 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -31,6 +32,10 @@
#include "rl6231.h"
#include "rt5651.h"
+#define RT5651_JD_MAP(quirk) ((quirk) & GENMASK(7, 0))
+#define RT5651_IN2_DIFF BIT(16)
+#define RT5651_DMIC_EN BIT(17)
+
#define RT5651_DEVICE_ID_VALUE 0x6281
#define RT5651_PR_RANGE_BASE (0xff + 1)
@@ -38,6 +43,8 @@
#define RT5651_PR_BASE (RT5651_PR_RANGE_BASE + (0 * RT5651_PR_SPACING))
+static unsigned long rt5651_quirk;
+
static const struct regmap_range_cfg rt5651_ranges[] = {
{ .name = "PR", .range_min = RT5651_PR_BASE,
.range_max = RT5651_PR_BASE + 0xb4,
@@ -1739,16 +1746,36 @@ static const struct i2c_device_id rt5651_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id);
+static int rt5651_quirk_cb(const struct dmi_system_id *id)
+{
+ rt5651_quirk = (unsigned long) id->driver_data;
+ return 1;
+}
+
+static const struct dmi_system_id rt5651_quirk_table[] = {
+ {}
+};
+
static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
{
- rt5651->pdata.in2_diff = of_property_read_bool(np,
- "realtek,in2-differential");
- rt5651->pdata.dmic_en = of_property_read_bool(np,
- "realtek,dmic-en");
+ if (of_property_read_bool(np, "realtek,in2-differential"))
+ rt5651_quirk |= RT5651_IN2_DIFF;
+ if (of_property_read_bool(np, "realtek,dmic-en"))
+ rt5651_quirk |= RT5651_DMIC_EN;
return 0;
}
+static void rt5651_set_pdata(struct rt5651_priv *rt5651)
+{
+ if (rt5651_quirk & RT5651_IN2_DIFF)
+ rt5651->pdata.in2_diff = true;
+ if (rt5651_quirk & RT5651_DMIC_EN)
+ rt5651->pdata.dmic_en = true;
+ if (RT5651_JD_MAP(rt5651_quirk))
+ rt5651->pdata.jd_src = RT5651_JD_MAP(rt5651_quirk);
+}
+
static irqreturn_t rt5651_irq(int irq, void *data)
{
struct rt5651_priv *rt5651 = data;
@@ -1854,6 +1881,10 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
rt5651->pdata = *pdata;
else if (i2c->dev.of_node)
rt5651_parse_dt(rt5651, i2c->dev.of_node);
+ else
+ dmi_check_system(rt5651_quirk_table);
+
+ rt5651_set_pdata(rt5651);
rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap);
if (IS_ERR(rt5651->regmap)) {
--
cgit v1.1
From f85353fdd49fe0087438ef7d7475a832d16276c4 Mon Sep 17 00:00:00 2001
From: Carlo Caione
Date: Fri, 20 Oct 2017 12:18:59 +0100
Subject: ASoC: rt5651: Enable JD1_1 quirk for KIANO laptopt
The KIANO SlimNote 14.2 laptop uses the JD1_1 input pin for jack
detection. Set the correct quirk in the codec driver.
Signed-off-by: Carlo Caione
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index f01d411..831b297 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -1753,6 +1753,14 @@ static int rt5651_quirk_cb(const struct dmi_system_id *id)
}
static const struct dmi_system_id rt5651_quirk_table[] = {
+ {
+ .callback = rt5651_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
+ },
+ .driver_data = (unsigned long *) RT5651_JD1_1,
+ },
{}
};
--
cgit v1.1
From 82ab86e82911107ead6fc7cd73568f75bc266a57 Mon Sep 17 00:00:00 2001
From: Mark Brown
Date: Mon, 30 Oct 2017 19:40:25 +0000
Subject: Revert "ASoC: rt5651: Enable jack detection on JD* pins"
This reverts commit 60d5a1a47b9a8381c08d2263b11ac9c757c87746.
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5651.c | 168 +---------------------------------------------
sound/soc/codecs/rt5651.h | 4 --
2 files changed, 2 insertions(+), 170 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 2f0d005..da60b28 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include "rl6231.h"
#include "rt5651.h"
@@ -881,9 +880,6 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
RT5651_PWR_PLL_BIT, 0, NULL, 0),
/* Input Side */
- SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
- RT5651_PWM_JD_M_BIT, 0, NULL, 0),
-
/* micbias */
SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1532,8 +1528,6 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
static int rt5651_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
- struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
switch (level) {
case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
@@ -1562,13 +1556,8 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
- if (rt5651->pdata.jd_src) {
- snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
- snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
- } else {
- snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
- snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
- }
+ snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
+ snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
break;
default:
@@ -1581,7 +1570,6 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
static int rt5651_probe(struct snd_soc_codec *codec)
{
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
rt5651->codec = codec;
@@ -1597,15 +1585,6 @@ static int rt5651_probe(struct snd_soc_codec *codec)
snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
- if (rt5651->pdata.jd_src) {
- snd_soc_dapm_force_enable_pin(dapm, "JD Power");
- snd_soc_dapm_force_enable_pin(dapm, "LDO");
- snd_soc_dapm_sync(dapm);
-
- regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
- 0x38, 0x38);
- }
-
return 0;
}
@@ -1749,93 +1728,6 @@ static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
return 0;
}
-static irqreturn_t rt5651_irq(int irq, void *data)
-{
- struct rt5651_priv *rt5651 = data;
-
- queue_delayed_work(system_power_efficient_wq,
- &rt5651->jack_detect_work, msecs_to_jiffies(250));
-
- return IRQ_HANDLED;
-}
-
-static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
-{
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
- int jack_type;
-
- if (jack_insert) {
- snd_soc_dapm_force_enable_pin(dapm, "LDO");
- snd_soc_dapm_sync(dapm);
-
- snd_soc_update_bits(codec, RT5651_MICBIAS,
- RT5651_MIC1_OVCD_MASK |
- RT5651_MIC1_OVTH_MASK |
- RT5651_PWR_CLK12M_MASK |
- RT5651_PWR_MB_MASK,
- RT5651_MIC1_OVCD_EN |
- RT5651_MIC1_OVTH_600UA |
- RT5651_PWR_MB_PU |
- RT5651_PWR_CLK12M_PU);
- msleep(100);
- if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
- jack_type = SND_JACK_HEADPHONE;
- else
- jack_type = SND_JACK_HEADSET;
- snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
- RT5651_MB1_OC_CLR, 0);
- } else { /* jack out */
- jack_type = 0;
-
- snd_soc_update_bits(codec, RT5651_MICBIAS,
- RT5651_MIC1_OVCD_MASK,
- RT5651_MIC1_OVCD_DIS);
- }
-
- return jack_type;
-}
-
-static void rt5651_jack_detect_work(struct work_struct *work)
-{
- struct rt5651_priv *rt5651 =
- container_of(work, struct rt5651_priv, jack_detect_work.work);
-
- int report, val = 0;
-
- if (!rt5651->codec)
- return;
-
- switch (rt5651->pdata.jd_src) {
- case RT5651_JD1_1:
- val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
- break;
- case RT5651_JD1_2:
- val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
- break;
- case RT5651_JD2:
- val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
- break;
- default:
- break;
- }
-
- report = rt5651_jack_detect(rt5651->codec, !val);
-
- snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
-}
-
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *hp_jack)
-{
- struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
-
- rt5651->hp_jack = hp_jack;
- rt5651_irq(0, rt5651);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
-
static int rt5651_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
@@ -1887,59 +1779,6 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
rt5651->hp_mute = 1;
- if (rt5651->pdata.jd_src) {
-
- /* IRQ output on GPIO1 */
- regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
- RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
-
- switch (rt5651->pdata.jd_src) {
- case RT5651_JD1_1:
- regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
- RT5651_JD_TRG_SEL_MASK,
- RT5651_JD_TRG_SEL_JD1_1);
- regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
- RT5651_JD1_1_IRQ_EN,
- RT5651_JD1_1_IRQ_EN);
- break;
- case RT5651_JD1_2:
- regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
- RT5651_JD_TRG_SEL_MASK,
- RT5651_JD_TRG_SEL_JD1_2);
- regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
- RT5651_JD1_2_IRQ_EN,
- RT5651_JD1_2_IRQ_EN);
- break;
- case RT5651_JD2:
- regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
- RT5651_JD_TRG_SEL_MASK,
- RT5651_JD_TRG_SEL_JD2);
- regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
- RT5651_JD2_IRQ_EN,
- RT5651_JD2_IRQ_EN);
- break;
- case RT5651_JD_NULL:
- break;
- default:
- dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
- break;
- }
- }
-
- INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
-
- if (i2c->irq) {
- ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
- rt5651_irq,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT, "rt5651", rt5651);
- if (ret) {
- dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
- return ret;
- }
- }
-
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
rt5651_dai, ARRAY_SIZE(rt5651_dai));
@@ -1948,9 +1787,6 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
static int rt5651_i2c_remove(struct i2c_client *i2c)
{
- struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
-
- cancel_delayed_work_sync(&rt5651->jack_detect_work);
snd_soc_unregister_codec(&i2c->dev);
return 0;
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 4f8b202..1bd33cf 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -2062,8 +2062,6 @@ struct rt5651_priv {
struct snd_soc_codec *codec;
struct rt5651_platform_data pdata;
struct regmap *regmap;
- struct snd_soc_jack *hp_jack;
- struct delayed_work jack_detect_work;
int sysclk;
int sysclk_src;
@@ -2079,6 +2077,4 @@ struct rt5651_priv {
bool hp_mute;
};
-int rt5651_set_jack_detect(struct snd_soc_codec *codec,
- struct snd_soc_jack *hp_jack);
#endif /* __RT5651_H__ */
--
cgit v1.1
From 50f510a33c7c906f8f75b02e3d1104984ebf6f78 Mon Sep 17 00:00:00 2001
From: Bard Liao
Date: Mon, 30 Oct 2017 15:26:05 +0800
Subject: ASoC: rt5645: remove unexisting route on new rt5645
"SPOL MIX DAC R1 Switch" and "SPOL MIX SPKVOL R Switch" are only
exist in the early version of rt5645.
Signed-off-by: Bard Liao
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5645.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 4b2dbf0..23cc2cb 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -432,6 +432,7 @@ struct rt5645_priv {
int jack_type;
bool en_button_func;
bool hp_on;
+ int v_id;
};
static int rt5645_reset(struct snd_soc_codec *codec)
@@ -2516,9 +2517,7 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
{ "SPKVOL L", "Switch", "SPK MIXL" },
{ "SPKVOL R", "Switch", "SPK MIXR" },
- { "SPOL MIX", "DAC R1 Switch", "DAC R1" },
{ "SPOL MIX", "DAC L1 Switch", "DAC L1" },
- { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" },
{ "SPOL MIX", "SPKVOL L Switch", "SPKVOL L" },
{ "SPOR MIX", "DAC R1 Switch", "DAC R1" },
{ "SPOR MIX", "SPKVOL R Switch", "SPKVOL R" },
@@ -2707,6 +2706,11 @@ static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
{ "DAC R2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 R Mux" },
};
+static const struct snd_soc_dapm_route rt5645_old_dapm_routes[] = {
+ { "SPOL MIX", "DAC R1 Switch", "DAC R1" },
+ { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" },
+};
+
static int rt5645_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
@@ -3363,6 +3367,11 @@ static int rt5645_probe(struct snd_soc_codec *codec)
snd_soc_dapm_add_routes(dapm,
rt5645_specific_dapm_routes,
ARRAY_SIZE(rt5645_specific_dapm_routes));
+ if (rt5645->v_id < 3) {
+ snd_soc_dapm_add_routes(dapm,
+ rt5645_old_dapm_routes,
+ ARRAY_SIZE(rt5645_old_dapm_routes));
+ }
break;
case CODEC_TYPE_RT5650:
snd_soc_dapm_new_controls(dapm,
@@ -3803,6 +3812,9 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
regmap_write(rt5645->regmap, RT5645_RESET, 0);
+ regmap_read(regmap, RT5645_VENDOR_ID, &val);
+ rt5645->v_id = val & 0xff;
+
ret = regmap_register_patch(rt5645->regmap, init_list,
ARRAY_SIZE(init_list));
if (ret != 0)
--
cgit v1.1
From eaf8abcfb21ecb5f6460d0505b03da4c3b7eee98 Mon Sep 17 00:00:00 2001
From: Charles Keepax
Date: Wed, 1 Nov 2017 11:03:25 +0000
Subject: ASoC: wm8741: Use snd_soc_update_bits rather than hard coding
Signed-off-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm8741.c | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index b8c1940..3c96af0 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -196,7 +196,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
- u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
+ unsigned int iface;
int i;
/* The set of sample rates that can be supported depends on the
@@ -223,15 +223,16 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
/* bit size */
switch (params_width(params)) {
case 16:
+ iface = 0x0;
break;
case 20:
- iface |= 0x0001;
+ iface = 0x1;
break;
case 24:
- iface |= 0x0002;
+ iface = 0x2;
break;
case 32:
- iface |= 0x0003;
+ iface = 0x3;
break;
default:
dev_dbg(codec->dev, "wm8741_hw_params: Unsupported bit size param = %d",
@@ -242,7 +243,9 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
dev_dbg(codec->dev, "wm8741_hw_params: bit size param = %d, rate param = %d",
params_width(params), params_rate(params));
- snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
+ snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
+ iface);
+
return 0;
}
@@ -295,7 +298,7 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
struct snd_soc_codec *codec = codec_dai->codec;
- u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1C3;
+ unsigned int iface;
/* check master/slave audio interface */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -308,18 +311,19 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
- iface |= 0x0008;
+ iface = 0x08;
break;
case SND_SOC_DAIFMT_RIGHT_J:
+ iface = 0x00;
break;
case SND_SOC_DAIFMT_LEFT_J:
- iface |= 0x0004;
+ iface = 0x04;
break;
case SND_SOC_DAIFMT_DSP_A:
- iface |= 0x000C;
+ iface = 0x0C;
break;
case SND_SOC_DAIFMT_DSP_B:
- iface |= 0x001C;
+ iface = 0x1C;
break;
default:
return -EINVAL;
@@ -330,13 +334,13 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_IF:
- iface |= 0x0010;
+ iface |= 0x10;
break;
case SND_SOC_DAIFMT_IB_NF:
- iface |= 0x0020;
+ iface |= 0x20;
break;
case SND_SOC_DAIFMT_NB_IF:
- iface |= 0x0030;
+ iface |= 0x30;
break;
default:
return -EINVAL;
@@ -347,7 +351,10 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
fmt & SND_SOC_DAIFMT_FORMAT_MASK,
((fmt & SND_SOC_DAIFMT_INV_MASK)));
- snd_soc_write(codec, WM8741_FORMAT_CONTROL, iface);
+ snd_soc_update_bits(codec, WM8741_FORMAT_CONTROL,
+ WM8741_BCP_MASK | WM8741_LRP_MASK | WM8741_FMT_MASK,
+ iface);
+
return 0;
}
--
cgit v1.1
From 28aef24d726f8d503fde24ccf8a14b214355cfb5 Mon Sep 17 00:00:00 2001
From: "oder_chiou@realtek.com"
Date: Thu, 2 Nov 2017 19:21:16 +0800
Subject: ASoC: rt5514: The ACPI also should use the function rt5514_parse_dp()
The patch fixed that the ACPI cannot access the device property from the
function rt5514_parse_dp().
Signed-off-by: Oder Chiou
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5514.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index d7956ab..2a5b5d7 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -1143,7 +1143,7 @@ static const struct acpi_device_id rt5514_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5514_acpi_match);
#endif
-static int rt5514_parse_dt(struct rt5514_priv *rt5514, struct device *dev)
+static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev)
{
device_property_read_u32(dev, "realtek,dmic-init-delay-ms",
&rt5514->pdata.dmic_init_delay);
@@ -1183,8 +1183,8 @@ static int rt5514_i2c_probe(struct i2c_client *i2c,
if (pdata)
rt5514->pdata = *pdata;
- else if (i2c->dev.of_node)
- rt5514_parse_dt(rt5514, &i2c->dev);
+ else
+ rt5514_parse_dp(rt5514, &i2c->dev);
rt5514->i2c_regmap = devm_regmap_init_i2c(i2c, &rt5514_i2c_regmap);
if (IS_ERR(rt5514->i2c_regmap)) {
--
cgit v1.1
From 81b3cc55afc3cde54df98f93fbd4704fab7cc0e0 Mon Sep 17 00:00:00 2001
From: Sergej Sawazki
Date: Fri, 3 Nov 2017 19:34:28 +0100
Subject: ASoC: wm8741: Fix setting BCLK and LRCLK polarity
After checking the code and the datasheet, it seems like we are handling
the clock inversion (SND_SOC_DAIFMT_NB_IF and SND_SOC_DAIFMT_IB_IF) not
correctly.
>From the datasheet (Table 58):
R5 Format Control, BITS[5:4], [BCP:LRP]:
(0) 00 = normal BCLK, normal LRCLK
(1) 01 = normal BCLK, inverted LRCLK <-- Fix this
(2) 10 = inverted BCLK, normal LRCLK
(3) 11 = inverted BCLK, inverted LRCLK <-- Fix this
Signed-off-by: Sergej Sawazki
Acked-by: Charles Keepax
Signed-off-by: Mark Brown
---
sound/soc/codecs/wm8741.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 3c96af0..a394dbe 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -333,13 +333,13 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
- case SND_SOC_DAIFMT_IB_IF:
+ case SND_SOC_DAIFMT_NB_IF:
iface |= 0x10;
break;
case SND_SOC_DAIFMT_IB_NF:
iface |= 0x20;
break;
- case SND_SOC_DAIFMT_NB_IF:
+ case SND_SOC_DAIFMT_IB_IF:
iface |= 0x30;
break;
default:
--
cgit v1.1
From da924c3a0d3f45bf8c46e83a7aa1b75b86f1e7a0 Mon Sep 17 00:00:00 2001
From: Mark Brown
Date: Thu, 7 Sep 2017 14:22:48 +0100
Subject: ASoC: pcm512x: Scrub my work address from the driver
It's difficult for me to handle upstream mail that ends up in my work
account and this was done outside of work anyway so replace my work
address with my usual address for upstream stuff.
Signed-off-by: Mark Brown
---
sound/soc/codecs/pcm512x-i2c.c | 4 ++--
sound/soc/codecs/pcm512x-spi.c | 2 +-
sound/soc/codecs/pcm512x.c | 4 ++--
sound/soc/codecs/pcm512x.h | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/pcm512x-i2c.c b/sound/soc/codecs/pcm512x-i2c.c
index dbff416..5f9c069 100644
--- a/sound/soc/codecs/pcm512x-i2c.c
+++ b/sound/soc/codecs/pcm512x-i2c.c
@@ -1,7 +1,7 @@
/*
* Driver for the PCM512x CODECs
*
- * Author: Mark Brown
+ * Author: Mark Brown
* Copyright 2014 Linaro Ltd
*
* This program is free software; you can redistribute it and/or
@@ -75,5 +75,5 @@ static struct i2c_driver pcm512x_i2c_driver = {
module_i2c_driver(pcm512x_i2c_driver);
MODULE_DESCRIPTION("ASoC PCM512x codec driver - I2C");
-MODULE_AUTHOR("Mark Brown ");
+MODULE_AUTHOR("Mark Brown ");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c
index 712ed65..25c6351 100644
--- a/sound/soc/codecs/pcm512x-spi.c
+++ b/sound/soc/codecs/pcm512x-spi.c
@@ -1,7 +1,7 @@
/*
* Driver for the PCM512x CODECs
*
- * Author: Mark Brown
+ * Author: Mark Brown
* Copyright 2014 Linaro Ltd
*
* This program is free software; you can redistribute it and/or
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 68feae2..e0f3556 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -1,7 +1,7 @@
/*
* Driver for the PCM512x CODECs
*
- * Author: Mark Brown
+ * Author: Mark Brown
* Copyright 2014 Linaro Ltd
*
* This program is free software; you can redistribute it and/or
@@ -1602,5 +1602,5 @@ const struct dev_pm_ops pcm512x_pm_ops = {
EXPORT_SYMBOL_GPL(pcm512x_pm_ops);
MODULE_DESCRIPTION("ASoC PCM512x codec driver");
-MODULE_AUTHOR("Mark Brown ");
+MODULE_AUTHOR("Mark Brown ");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h
index b7c3102..d70d9c0 100644
--- a/sound/soc/codecs/pcm512x.h
+++ b/sound/soc/codecs/pcm512x.h
@@ -1,7 +1,7 @@
/*
* Driver for the PCM512x CODECs
*
- * Author: Mark Brown
+ * Author: Mark Brown
* Copyright 2014 Linaro Ltd
*
* This program is free software; you can redistribute it and/or
--
cgit v1.1
From c4a71ff78e668a75a4a3cfd9ebbfbd5cbe8da5fb Mon Sep 17 00:00:00 2001
From: Oder Chiou
Date: Wed, 8 Nov 2017 19:21:47 +0800
Subject: ASoC: rt5514-spi: Let the buf_size to align with period_bytes
The patch lets the buf_size to align with period_bytes to prevent the
buffer reading over the real size of the DSP buffer and also avoid to
calculate the wrong size of remaining data.
Signed-off-by: Oder Chiou
Signed-off-by: Mark Brown
---
sound/soc/codecs/rt5514-spi.c | 9 +++++++++
1 file changed, 9 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index 12f2ecf..0896817 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -147,8 +147,13 @@ done:
static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
{
+ size_t period_bytes;
u8 buf[8];
+ if (!rt5514_dsp->substream)
+ return;
+
+ period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
rt5514_dsp->get_size = 0;
/**
@@ -176,6 +181,10 @@ static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base;
+ if (rt5514_dsp->buf_size % period_bytes)
+ rt5514_dsp->buf_size = (rt5514_dsp->buf_size / period_bytes) *
+ period_bytes;
+
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
--
cgit v1.1
From 70e97a2d9c5266487dfec4cade28f8e587927f04 Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty"
Date: Tue, 7 Nov 2017 16:16:24 +0530
Subject: ASoC: hdac_hdmi: Fix static checker warning for sprintf usage
Use snprintf instead of sprintf to shut the warning.
Signed-off-by: Subhransu S. Prusty
Signed-off-by: Guneshwor Singh
Acked-By: Vinod Koul
Signed-off-by: Mark Brown
---
sound/soc/codecs/hdac_hdmi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index e824d47..6f3ff15 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -942,7 +942,8 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev,
if (!se)
return -ENOMEM;
- sprintf(kc_name, "Pin %d port %d Input", pin->nid, port->id);
+ snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input",
+ pin->nid, port->id);
kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL);
if (!kc->name)
return -ENOMEM;
--
cgit v1.1
From eb50fa1739a63cc4b202b40a62d71055a2d7b80c Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty"
Date: Tue, 7 Nov 2017 16:16:25 +0530
Subject: ASoC: hdac_hdmi: Fix possible NULL pointer dereference
Pointers hdac_hdmi_pcm and hda_device_id can be NULL, so add check for
valid pointer to avoid NULL pointer dereference.
Signed-off-by: Subhransu S. Prusty
Signed-off-by: Guneshwor Singh
Acked-By: Vinod Koul
Signed-off-by: Mark Brown
---
sound/soc/codecs/hdac_hdmi.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 6f3ff15..0c0aa61 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1895,6 +1895,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx,
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port;
+ if (!pcm)
+ return;
+
if (list_empty(&pcm->port_list))
return;
@@ -1913,6 +1916,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
struct hdac_hdmi_priv *hdmi = edev->private_data;
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
+ if (!pcm)
+ return false;
+
if (list_empty(&pcm->port_list))
return false;
@@ -1926,6 +1932,9 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx)
struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);
struct hdac_hdmi_port *port;
+ if (!pcm)
+ return 0;
+
if (list_empty(&pcm->port_list))
return 0;
@@ -1979,6 +1988,9 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;
hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;
+ if (!hdac_id)
+ return -ENODEV;
+
if (hdac_id->driver_data)
hdmi_priv->drv_data =
(struct hdac_hdmi_drv_data *)hdac_id->driver_data;
--
cgit v1.1
From 1c0a7de226660b0306b54aaf2cb52312e74723eb Mon Sep 17 00:00:00 2001
From: "Subhransu S. Prusty"
Date: Tue, 7 Nov 2017 16:16:26 +0530
Subject: ASoC: hdac_hdmi: Fix possible memory leak on parse and map nid
failure
During failure, widgets in cvt_list and pin_list are not freed. So fix
the possible memory leak by freeing them when failure occurs.
Signed-off-by: Subhransu S. Prusty
Signed-off-by: Guneshwor Singh
Acked-By: Vinod Koul
Signed-off-by: Mark Brown
---
sound/soc/codecs/hdac_hdmi.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
(limited to 'sound/soc/codecs')
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 0c0aa61..f3b4f4d 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1453,6 +1453,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
int i, num_nodes;
struct hdac_device *hdac = &edev->hdac;
struct hdac_hdmi_priv *hdmi = edev->private_data;
+ struct hdac_hdmi_cvt *temp_cvt, *cvt_next;
+ struct hdac_hdmi_pin *temp_pin, *pin_next;
int ret;
hdac_hdmi_skl_enable_all_pins(hdac);
@@ -1482,32 +1484,54 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev,
case AC_WID_AUD_OUT:
ret = hdac_hdmi_add_cvt(edev, nid);
if (ret < 0)
- return ret;
+ goto free_widgets;
break;
case AC_WID_PIN:
ret = hdac_hdmi_add_pin(edev, nid);
if (ret < 0)
- return ret;
+ goto free_widgets;
break;
}
}
hdac->end_nid = nid;
- if (!hdmi->num_pin || !hdmi->num_cvt)
- return -EIO;
+ if (!hdmi->num_pin || !hdmi->num_cvt) {
+ ret = -EIO;
+ goto free_widgets;
+ }
ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt);
if (ret) {
dev_err(&hdac->dev, "Failed to create dais with err: %d\n",
ret);
- return ret;
+ goto free_widgets;
}
*num_dais = hdmi->num_cvt;
+ ret = hdac_hdmi_init_dai_map(edev);
+ if (ret < 0)
+ goto free_widgets;
- return hdac_hdmi_init_dai_map(edev);
+ return ret;
+
+free_widgets:
+ list_for_each_entry_safe(temp_cvt, cvt_next, &hdmi->cvt_list, head) {
+ list_del(&temp_cvt->head);
+ kfree(temp_cvt->name);
+ kfree(temp_cvt);
+ }
+
+ list_for_each_entry_safe(temp_pin, pin_next, &hdmi->pin_list, head) {
+ for (i = 0; i < temp_pin->num_ports; i++)
+ temp_pin->ports[i].pin = NULL;
+ kfree(temp_pin->ports);
+ list_del(&temp_pin->head);
+ kfree(temp_pin);
+ }
+
+ return ret;
}
static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
--
cgit v1.1
From dc10622bb32f08383cf5a9942a91042d8f38bf3d Mon Sep 17 00:00:00 2001
From: "Gustavo A. R. Silva"