Loading Documentation/devicetree/bindings/sound/renesas,rsnd.txt +7 −3 Original line number Diff line number Diff line Renesas R-Car sound Required properties: - compatible : "renesas,rcar_sound-gen1" if generation1 - compatible : "renesas,rcar_sound-<soctype>", fallbacks "renesas,rcar_sound-gen1" if generation1, and "renesas,rcar_sound-gen2" if generation2 Examples with soctypes are: - "renesas,rcar_sound-r8a7790" (R-Car H2) - "renesas,rcar_sound-r8a7791" (R-Car M2-W) - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 Loading Loading @@ -35,9 +39,9 @@ DAI subnode properties: Example: rcar_sound: rcar_sound@0xffd90000 { rcar_sound: rcar_sound@ec500000 { #sound-dai-cells = <1>; compatible = "renesas,rcar_sound-gen2"; compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ Loading Documentation/devicetree/bindings/sound/rt5631.txt 0 → 100644 +48 −0 Original line number Diff line number Diff line ALC5631/RT5631 audio CODEC This device supports I2C only. Required properties: - compatible : "realtek,alc5631" or "realtek,rt5631" - reg : the I2C address of the device. Pins on the device (for linking into audio routes): * SPK_OUT_R_P * SPK_OUT_R_N * SPK_OUT_L_P * SPK_OUT_L_N * HP_OUT_L * HP_OUT_R * AUX_OUT2_LP * AUX_OUT2_RN * AUX_OUT1_LP * AUX_OUT1_RN * AUX_IN_L_JD * AUX_IN_R_JD * MONO_IN_P * MONO_IN_N * MIC1_P * MIC1_N * MIC2_P * MIC2_N * MONO_OUT_P * MONO_OUT_N * MICBIAS1 * MICBIAS2 Example: alc5631: alc5631@1a { compatible = "realtek,alc5631"; reg = <0x1a>; }; or rt5631: rt5631@1a { compatible = "realtek,rt5631"; reg = <0x1a>; }; include/sound/rcar_snd.h +4 −4 Original line number Diff line number Diff line Loading @@ -36,14 +36,14 @@ #define RSND_SSI_CLK_PIN_SHARE (1 << 31) #define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */ #define RSND_SSI(_dma_id, _pio_irq, _flags) \ { .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } #define RSND_SSI(_dma_id, _irq, _flags) \ { .dma_id = _dma_id, .irq = _irq, .flags = _flags } #define RSND_SSI_UNUSED \ { .dma_id = -1, .pio_irq = -1, .flags = 0 } { .dma_id = -1, .irq = -1, .flags = 0 } struct rsnd_ssi_platform_info { int dma_id; int pio_irq; int irq; u32 flags; }; Loading sound/soc/codecs/Kconfig +2 −1 Original line number Diff line number Diff line Loading @@ -501,7 +501,8 @@ config SND_SOC_RT286 depends on I2C config SND_SOC_RT5631 tristate tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C config SND_SOC_RT5640 tristate Loading sound/soc/codecs/rt286.c +172 −59 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/dmi.h> #include <linux/acpi.h> #include <sound/core.h> #include <sound/pcm.h> Loading @@ -36,11 +37,13 @@ struct rt286_priv { struct regmap *regmap; struct snd_soc_codec *codec; struct rt286_platform_data pdata; struct i2c_client *i2c; struct snd_soc_jack *jack; struct delayed_work jack_detect_work; int sys_clk; int clk_id; struct reg_default *index_cache; }; Loading Loading @@ -298,7 +301,6 @@ static int rt286_support_power_controls[] = { static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) { unsigned int val, buf; int i; *hp = false; *mic = false; Loading @@ -309,67 +311,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) if (*hp) { /* power on HV,VERF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x0); RT286_DC_GAIN, 0x200, 0x200); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "HV"); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "VREF"); /* power LDO1 */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x4, 0x4); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "LDO1"); snd_soc_dapm_sync(&rt286->codec->dapm); regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); msleep(50); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xfcc0, 0xd400); msleep(300); regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); msleep(200); i = 40; while (((val & 0x0800) == 0) && (i > 0)) { if (0x0070 == (val & 0x0070)) { *mic = true; } else { regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xfcc0, 0xe400); msleep(300); regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); i--; msleep(20); } if (0x0400 == (val & 0x0700)) { *mic = false; regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); /* power off HV,VERF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0000); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x0000); } else if ((0x0200 == (val & 0x0700)) || (0x0100 == (val & 0x0700))) { if (0x0070 == (val & 0x0070)) *mic = true; regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); } else { else *mic = false; } regmap_update_bits(rt286->regmap, RT286_MISC_CTRL1, 0x0060, 0x0000); } else { regmap_update_bits(rt286->regmap, RT286_MISC_CTRL1, 0x0060, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); RT286_DC_GAIN, 0x200, 0x0); } else { *mic = false; regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); } } else { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); Loading @@ -378,6 +357,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) *mic = buf & 0x80000000; } snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV"); snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF"); if (!*hp) snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1"); snd_soc_dapm_sync(&rt286->codec->dapm); return 0; } Loading Loading @@ -415,6 +400,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) } EXPORT_SYMBOL_GPL(rt286_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); if (rt286->clk_id == RT286_SCLK_S_MCLK) return 1; else return 0; } static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); Loading Loading @@ -568,7 +564,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w, return 0; } static int rt286_vref_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, RT286_CBJ_CTRL1, 0x0400, 0x0000); mdelay(50); break; default: return 0; } return 0; } static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08); break; case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30); break; default: return 0; } return 0; } static int rt286_mic1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); snd_soc_update_bits(codec, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, RT286_A_BIAS_CTRL3, 0xc000, 0x0000); snd_soc_update_bits(codec, RT286_A_BIAS_CTRL2, 0xc000, 0x0000); break; default: return 0; } return 0; } static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1, 12, 1, NULL, 0), SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1, 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1, 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM, 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), /* Input Lines */ SND_SOC_DAPM_INPUT("DMIC1 Pin"), SND_SOC_DAPM_INPUT("DMIC2 Pin"), Loading Loading @@ -642,6 +715,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt286_dapm_routes[] = { {"ADC 0", NULL, "MCLK MODE", is_mclk_mode}, {"ADC 1", NULL, "MCLK MODE", is_mclk_mode}, {"Front", NULL, "MCLK MODE", is_mclk_mode}, {"Surround", NULL, "MCLK MODE", is_mclk_mode}, {"HP Power", NULL, "LDO1"}, {"HP Power", NULL, "LDO2"}, {"MIC1", NULL, "LDO1"}, {"MIC1", NULL, "LDO2"}, {"MIC1", NULL, "HV"}, {"MIC1", NULL, "VREF"}, {"MIC1", NULL, "MIC1 Input Buffer"}, {"SPO", NULL, "LDO1"}, {"SPO", NULL, "LDO2"}, {"SPO", NULL, "HV"}, {"SPO", NULL, "VREF"}, {"DMIC1", NULL, "DMIC1 Pin"}, {"DMIC2", NULL, "DMIC2 Pin"}, {"DMIC1", NULL, "DMIC Receiver"}, Loading Loading @@ -880,6 +972,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai, } rt286->sys_clk = freq; rt286->clk_id = clk_id; return 0; } Loading Loading @@ -915,13 +1008,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: mdelay(10); snd_soc_update_bits(codec, RT286_CBJ_CTRL1, 0x0400, 0x0400); snd_soc_update_bits(codec, RT286_DC_GAIN, 0x200, 0x0); break; case SND_SOC_BIAS_STANDBY: snd_soc_write(codec, RT286_SET_AUDIO_POWER, AC_PWRST_D3); snd_soc_update_bits(codec, RT286_DC_GAIN, 0x200, 0x0); RT286_CBJ_CTRL1, 0x0400, 0x0000); break; default: Loading Loading @@ -962,6 +1060,7 @@ static int rt286_probe(struct snd_soc_codec *codec) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); rt286->codec = codec; codec->dapm.bias_level = SND_SOC_BIAS_OFF; if (rt286->i2c->irq) { Loading Loading @@ -1107,6 +1206,16 @@ static const struct acpi_device_id rt286_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); static struct dmi_system_id force_combo_jack_table[] = { { .ident = "Intel Wilson Beach", .matches = { DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS") } }, { } }; static int rt286_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { Loading Loading @@ -1142,6 +1251,9 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (pdata) rt286->pdata = *pdata; if (dmi_check_system(force_combo_jack_table)) rt286->pdata.cbj_en = true; regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); for (i = 0; i < RT286_POWER_REG_LEN; i++) Loading @@ -1152,7 +1264,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (!rt286->pdata.cbj_en) { regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xf000, 0xb000); } else { Loading @@ -1169,8 +1280,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c, mdelay(10); /*Power down LDO2*/ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); /* Power down LDO, VREF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0); regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); /* Set depop parameter */ regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); Loading Loading
Documentation/devicetree/bindings/sound/renesas,rsnd.txt +7 −3 Original line number Diff line number Diff line Renesas R-Car sound Required properties: - compatible : "renesas,rcar_sound-gen1" if generation1 - compatible : "renesas,rcar_sound-<soctype>", fallbacks "renesas,rcar_sound-gen1" if generation1, and "renesas,rcar_sound-gen2" if generation2 Examples with soctypes are: - "renesas,rcar_sound-r8a7790" (R-Car H2) - "renesas,rcar_sound-r8a7791" (R-Car M2-W) - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 Loading Loading @@ -35,9 +39,9 @@ DAI subnode properties: Example: rcar_sound: rcar_sound@0xffd90000 { rcar_sound: rcar_sound@ec500000 { #sound-dai-cells = <1>; compatible = "renesas,rcar_sound-gen2"; compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ Loading
Documentation/devicetree/bindings/sound/rt5631.txt 0 → 100644 +48 −0 Original line number Diff line number Diff line ALC5631/RT5631 audio CODEC This device supports I2C only. Required properties: - compatible : "realtek,alc5631" or "realtek,rt5631" - reg : the I2C address of the device. Pins on the device (for linking into audio routes): * SPK_OUT_R_P * SPK_OUT_R_N * SPK_OUT_L_P * SPK_OUT_L_N * HP_OUT_L * HP_OUT_R * AUX_OUT2_LP * AUX_OUT2_RN * AUX_OUT1_LP * AUX_OUT1_RN * AUX_IN_L_JD * AUX_IN_R_JD * MONO_IN_P * MONO_IN_N * MIC1_P * MIC1_N * MIC2_P * MIC2_N * MONO_OUT_P * MONO_OUT_N * MICBIAS1 * MICBIAS2 Example: alc5631: alc5631@1a { compatible = "realtek,alc5631"; reg = <0x1a>; }; or rt5631: rt5631@1a { compatible = "realtek,rt5631"; reg = <0x1a>; };
include/sound/rcar_snd.h +4 −4 Original line number Diff line number Diff line Loading @@ -36,14 +36,14 @@ #define RSND_SSI_CLK_PIN_SHARE (1 << 31) #define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */ #define RSND_SSI(_dma_id, _pio_irq, _flags) \ { .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } #define RSND_SSI(_dma_id, _irq, _flags) \ { .dma_id = _dma_id, .irq = _irq, .flags = _flags } #define RSND_SSI_UNUSED \ { .dma_id = -1, .pio_irq = -1, .flags = 0 } { .dma_id = -1, .irq = -1, .flags = 0 } struct rsnd_ssi_platform_info { int dma_id; int pio_irq; int irq; u32 flags; }; Loading
sound/soc/codecs/Kconfig +2 −1 Original line number Diff line number Diff line Loading @@ -501,7 +501,8 @@ config SND_SOC_RT286 depends on I2C config SND_SOC_RT5631 tristate tristate "Realtek ALC5631/RT5631 CODEC" depends on I2C config SND_SOC_RT5640 tristate Loading
sound/soc/codecs/rt286.c +172 −59 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/dmi.h> #include <linux/acpi.h> #include <sound/core.h> #include <sound/pcm.h> Loading @@ -36,11 +37,13 @@ struct rt286_priv { struct regmap *regmap; struct snd_soc_codec *codec; struct rt286_platform_data pdata; struct i2c_client *i2c; struct snd_soc_jack *jack; struct delayed_work jack_detect_work; int sys_clk; int clk_id; struct reg_default *index_cache; }; Loading Loading @@ -298,7 +301,6 @@ static int rt286_support_power_controls[] = { static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) { unsigned int val, buf; int i; *hp = false; *mic = false; Loading @@ -309,67 +311,44 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) if (*hp) { /* power on HV,VERF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x0); RT286_DC_GAIN, 0x200, 0x200); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "HV"); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "VREF"); /* power LDO1 */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x4, 0x4); snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, "LDO1"); snd_soc_dapm_sync(&rt286->codec->dapm); regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); msleep(50); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xfcc0, 0xd400); msleep(300); regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); msleep(200); i = 40; while (((val & 0x0800) == 0) && (i > 0)) { if (0x0070 == (val & 0x0070)) { *mic = true; } else { regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xfcc0, 0xe400); msleep(300); regmap_read(rt286->regmap, RT286_CBJ_CTRL2, &val); i--; msleep(20); } if (0x0400 == (val & 0x0700)) { *mic = false; regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); /* power off HV,VERF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0000); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x0000); } else if ((0x0200 == (val & 0x0700)) || (0x0100 == (val & 0x0700))) { if (0x0070 == (val & 0x0070)) *mic = true; regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); } else { else *mic = false; } regmap_update_bits(rt286->regmap, RT286_MISC_CTRL1, 0x0060, 0x0000); } else { regmap_update_bits(rt286->regmap, RT286_MISC_CTRL1, 0x0060, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0x0030, 0x0020); regmap_update_bits(rt286->regmap, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); RT286_DC_GAIN, 0x200, 0x0); } else { *mic = false; regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); } } else { regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); Loading @@ -378,6 +357,12 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) *mic = buf & 0x80000000; } snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV"); snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF"); if (!*hp) snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1"); snd_soc_dapm_sync(&rt286->codec->dapm); return 0; } Loading Loading @@ -415,6 +400,17 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) } EXPORT_SYMBOL_GPL(rt286_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); if (rt286->clk_id == RT286_SCLK_S_MCLK) return 1; else return 0; } static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); Loading Loading @@ -568,7 +564,84 @@ static int rt286_adc_event(struct snd_soc_dapm_widget *w, return 0; } static int rt286_vref_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, RT286_CBJ_CTRL1, 0x0400, 0x0000); mdelay(50); break; default: return 0; } return 0; } static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x08); break; case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, RT286_POWER_CTRL2, 0x38, 0x30); break; default: return 0; } return 0; } static int rt286_mic1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; switch (event) { case SND_SOC_DAPM_PRE_PMU: snd_soc_update_bits(codec, RT286_A_BIAS_CTRL3, 0xc000, 0x8000); snd_soc_update_bits(codec, RT286_A_BIAS_CTRL2, 0xc000, 0x8000); break; case SND_SOC_DAPM_POST_PMD: snd_soc_update_bits(codec, RT286_A_BIAS_CTRL3, 0xc000, 0x0000); snd_soc_update_bits(codec, RT286_A_BIAS_CTRL2, 0xc000, 0x0000); break; default: return 0; } return 0; } static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1, 12, 1, NULL, 0), SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1, 0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1, 13, 1, rt286_ldo2_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("MCLK MODE", RT286_PLL_CTRL1, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM, 0, 0, rt286_mic1_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), /* Input Lines */ SND_SOC_DAPM_INPUT("DMIC1 Pin"), SND_SOC_DAPM_INPUT("DMIC2 Pin"), Loading Loading @@ -642,6 +715,25 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt286_dapm_routes[] = { {"ADC 0", NULL, "MCLK MODE", is_mclk_mode}, {"ADC 1", NULL, "MCLK MODE", is_mclk_mode}, {"Front", NULL, "MCLK MODE", is_mclk_mode}, {"Surround", NULL, "MCLK MODE", is_mclk_mode}, {"HP Power", NULL, "LDO1"}, {"HP Power", NULL, "LDO2"}, {"MIC1", NULL, "LDO1"}, {"MIC1", NULL, "LDO2"}, {"MIC1", NULL, "HV"}, {"MIC1", NULL, "VREF"}, {"MIC1", NULL, "MIC1 Input Buffer"}, {"SPO", NULL, "LDO1"}, {"SPO", NULL, "LDO2"}, {"SPO", NULL, "HV"}, {"SPO", NULL, "VREF"}, {"DMIC1", NULL, "DMIC1 Pin"}, {"DMIC2", NULL, "DMIC2 Pin"}, {"DMIC1", NULL, "DMIC Receiver"}, Loading Loading @@ -880,6 +972,7 @@ static int rt286_set_dai_sysclk(struct snd_soc_dai *dai, } rt286->sys_clk = freq; rt286->clk_id = clk_id; return 0; } Loading Loading @@ -915,13 +1008,18 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: mdelay(10); snd_soc_update_bits(codec, RT286_CBJ_CTRL1, 0x0400, 0x0400); snd_soc_update_bits(codec, RT286_DC_GAIN, 0x200, 0x0); break; case SND_SOC_BIAS_STANDBY: snd_soc_write(codec, RT286_SET_AUDIO_POWER, AC_PWRST_D3); snd_soc_update_bits(codec, RT286_DC_GAIN, 0x200, 0x0); RT286_CBJ_CTRL1, 0x0400, 0x0000); break; default: Loading Loading @@ -962,6 +1060,7 @@ static int rt286_probe(struct snd_soc_codec *codec) { struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); rt286->codec = codec; codec->dapm.bias_level = SND_SOC_BIAS_OFF; if (rt286->i2c->irq) { Loading Loading @@ -1107,6 +1206,16 @@ static const struct acpi_device_id rt286_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, rt286_acpi_match); static struct dmi_system_id force_combo_jack_table[] = { { .ident = "Intel Wilson Beach", .matches = { DMI_MATCH(DMI_BOARD_NAME, "Wilson Beach SDS") } }, { } }; static int rt286_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { Loading Loading @@ -1142,6 +1251,9 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (pdata) rt286->pdata = *pdata; if (dmi_check_system(force_combo_jack_table)) rt286->pdata.cbj_en = true; regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); for (i = 0; i < RT286_POWER_REG_LEN; i++) Loading @@ -1152,7 +1264,6 @@ static int rt286_i2c_probe(struct i2c_client *i2c, if (!rt286->pdata.cbj_en) { regmap_write(rt286->regmap, RT286_CBJ_CTRL2, 0x0000); regmap_write(rt286->regmap, RT286_MIC1_DET_CTRL, 0x0816); regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); regmap_update_bits(rt286->regmap, RT286_CBJ_CTRL1, 0xf000, 0xb000); } else { Loading @@ -1169,8 +1280,10 @@ static int rt286_i2c_probe(struct i2c_client *i2c, mdelay(10); /*Power down LDO2*/ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0x8, 0x0); regmap_write(rt286->regmap, RT286_MISC_CTRL1, 0x0000); /* Power down LDO, VREF */ regmap_update_bits(rt286->regmap, RT286_POWER_CTRL2, 0xc, 0x0); regmap_update_bits(rt286->regmap, RT286_POWER_CTRL1, 0x1001, 0x1001); /* Set depop parameter */ regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL2, 0x403a, 0x401a); Loading