Loading Documentation/devicetree/bindings/sound/rt5677.txt +2 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ Required properties: Optional properties: - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. - realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin. - realtek,in1-differential - realtek,in2-differential Loading Loading @@ -70,6 +71,7 @@ rt5677 { realtek,pow-ldo2-gpio = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,reset-gpio = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_LOW>; realtek,in1-differential = "true"; realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */ realtek,jd2-gpio = <3>; /* Enables Jack detection for GPIO6 */ Loading sound/soc/codecs/rt5677.c +135 −8 Original line number Diff line number Diff line Loading @@ -1060,6 +1060,7 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int asrc5_mask = 0, asrc5_value = 0; unsigned int asrc6_mask = 0, asrc6_value = 0; unsigned int asrc7_mask = 0, asrc7_value = 0; unsigned int asrc8_mask = 0, asrc8_value = 0; switch (clk_src) { case RT5677_CLK_SEL_SYS: Loading Loading @@ -1196,10 +1197,108 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec, regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask, asrc7_value); /* ASRC 8 */ if (filter_mask & RT5677_I2S1_SOURCE) { asrc8_mask |= RT5677_I2S1_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S1_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S1_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S2_SOURCE) { asrc8_mask |= RT5677_I2S2_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S2_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S2_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S3_SOURCE) { asrc8_mask |= RT5677_I2S3_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S3_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S3_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S4_SOURCE) { asrc8_mask |= RT5677_I2S4_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S4_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S4_CLK_SEL_SFT); } if (asrc8_mask) regmap_update_bits(rt5677->regmap, RT5677_ASRC_8, asrc8_mask, asrc8_value); return 0; } EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src); static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); unsigned int asrc_setting; switch (source->shift) { case 11: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO1_CLK_SEL_MASK) >> RT5677_AD_STO1_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 10: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO2_CLK_SEL_MASK) >> RT5677_AD_STO2_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 9: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO3_CLK_SEL_MASK) >> RT5677_AD_STO3_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 8: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO4_CLK_SEL_MASK) >> RT5677_AD_STO4_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 7: regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_MONOL_CLK_SEL_MASK) >> RT5677_AD_MONOL_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 6: regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_MONOR_CLK_SEL_MASK) >> RT5677_AD_MONOR_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; default: break; } return 0; } /* Digital Mixer */ static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, Loading Loading @@ -3057,12 +3156,12 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc }, { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc }, { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc }, { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc }, { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc }, { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc }, { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", rt5677_dmic_use_asrc }, { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", rt5677_dmic_use_asrc }, { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", rt5677_dmic_use_asrc }, { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", rt5677_dmic_use_asrc }, { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", rt5677_dmic_use_asrc }, { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", rt5677_dmic_use_asrc }, { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, { "I2S3", NULL, "I2S3 ASRC", can_use_asrc}, Loading Loading @@ -4667,6 +4766,8 @@ static int rt5677_remove(struct snd_soc_codec *codec) regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 0); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 0); return 0; } Loading @@ -4682,6 +4783,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec) if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 0); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 0); } return 0; Loading @@ -4692,10 +4795,13 @@ static int rt5677_resume(struct snd_soc_codec *codec) struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); if (!rt5677->dsp_vad_en) { if (gpio_is_valid(rt5677->pow_ldo2)) { if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 1); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 1); if (gpio_is_valid(rt5677->pow_ldo2) || gpio_is_valid(rt5677->reset_pin)) msleep(10); } regcache_cache_only(rt5677->regmap, false); regcache_sync(rt5677->regmap); Loading Loading @@ -4933,6 +5039,8 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) rt5677->pow_ldo2 = of_get_named_gpio(np, "realtek,pow-ldo2-gpio", 0); rt5677->reset_pin = of_get_named_gpio(np, "realtek,reset-gpio", 0); /* * POW_LDO2 is optional (it may be statically tied on the board). Loading @@ -4943,6 +5051,9 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) if (!gpio_is_valid(rt5677->pow_ldo2) && (rt5677->pow_ldo2 != -ENOENT)) return rt5677->pow_ldo2; if (!gpio_is_valid(rt5677->reset_pin) && (rt5677->reset_pin != -ENOENT)) return rt5677->reset_pin; of_property_read_u8_array(np, "realtek,gpio-config", rt5677->pdata.gpio_config, RT5677_GPIO_NUM); Loading Loading @@ -5044,6 +5155,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, } } else { rt5677->pow_ldo2 = -EINVAL; rt5677->reset_pin = -EINVAL; } if (gpio_is_valid(rt5677->pow_ldo2)) { Loading @@ -5055,6 +5167,21 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, rt5677->pow_ldo2, ret); return ret; } } if (gpio_is_valid(rt5677->reset_pin)) { ret = devm_gpio_request_one(&i2c->dev, rt5677->reset_pin, GPIOF_OUT_INIT_HIGH, "RT5677 RESET"); if (ret < 0) { dev_err(&i2c->dev, "Failed to request RESET %d: %d\n", rt5677->reset_pin, ret); return ret; } } if (gpio_is_valid(rt5677->pow_ldo2) || gpio_is_valid(rt5677->reset_pin)) { /* Wait a while until I2C bus becomes available. The datasheet * does not specify the exact we should wait but startup * sequence mentiones at least a few milliseconds. Loading sound/soc/codecs/rt5677.h +15 −0 Original line number Diff line number Diff line Loading @@ -1446,6 +1446,16 @@ #define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8) #define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8 /* ASRC Control 8 (0x8a) */ #define RT5677_I2S1_CLK_SEL_MASK (0xf << 12) #define RT5677_I2S1_CLK_SEL_SFT 12 #define RT5677_I2S2_CLK_SEL_MASK (0xf << 8) #define RT5677_I2S2_CLK_SEL_SFT 8 #define RT5677_I2S3_CLK_SEL_MASK (0xf << 4) #define RT5677_I2S3_CLK_SEL_SFT 4 #define RT5677_I2S4_CLK_SEL_MASK (0xf) #define RT5677_I2S4_CLK_SEL_SFT 0 /* VAD Function Control 4 (0x9f) */ #define RT5677_VAD_SRC_MASK (0x7 << 8) #define RT5677_VAD_SRC_SFT 8 Loading Loading @@ -1744,6 +1754,10 @@ enum { RT5677_AD_MONO_R_FILTER = (0x1 << 12), RT5677_DSP_OB_0_3_FILTER = (0x1 << 13), RT5677_DSP_OB_4_7_FILTER = (0x1 << 14), RT5677_I2S1_SOURCE = (0x1 << 15), RT5677_I2S2_SOURCE = (0x1 << 16), RT5677_I2S3_SOURCE = (0x1 << 17), RT5677_I2S4_SOURCE = (0x1 << 18), }; struct rt5677_priv { Loading @@ -1762,6 +1776,7 @@ struct rt5677_priv { int pll_in; int pll_out; int pow_ldo2; /* POW_LDO2 pin */ int reset_pin; /* RESET pin */ enum rt5677_type type; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio_chip; Loading sound/soc/codecs/sgtl5000.c +46 −7 Original line number Diff line number Diff line Loading @@ -1090,6 +1090,19 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg) } } /* * This precalculated table contains all (vag_val * 100 / lo_calcntrl) results * to select an appropriate lo_vol_* in SGTL5000_CHIP_LINE_OUT_VOL * The calculatation was done for all possible register values which * is the array index and the following formula: 10^((idx−15)/40) * 100 */ static const u8 vol_quot_table[] = { 42, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188, 200, 211, 224, 237, 251 }; /* * sgtl5000 has 3 internal power supplies: * 1. VAG, normally set to vdda/2 Loading @@ -1110,6 +1123,10 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) u16 ana_pwr; u16 lreg_ctrl; int vag; int lo_vag; int vol_quot; int lo_vol; size_t i; struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer); Loading Loading @@ -1197,23 +1214,45 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT); /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ vag = vddio / 2; if (vag <= SGTL5000_LINE_OUT_GND_BASE) vag = 0; else if (vag >= SGTL5000_LINE_OUT_GND_BASE + lo_vag = vddio / 2; if (lo_vag <= SGTL5000_LINE_OUT_GND_BASE) lo_vag = 0; else if (lo_vag >= SGTL5000_LINE_OUT_GND_BASE + SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX) vag = SGTL5000_LINE_OUT_GND_MAX; lo_vag = SGTL5000_LINE_OUT_GND_MAX; else vag = (vag - SGTL5000_LINE_OUT_GND_BASE) / lo_vag = (lo_vag - SGTL5000_LINE_OUT_GND_BASE) / SGTL5000_LINE_OUT_GND_STP; snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, SGTL5000_LINE_OUT_CURRENT_MASK | SGTL5000_LINE_OUT_GND_MASK, vag << SGTL5000_LINE_OUT_GND_SHIFT | lo_vag << SGTL5000_LINE_OUT_GND_SHIFT | SGTL5000_LINE_OUT_CURRENT_360u << SGTL5000_LINE_OUT_CURRENT_SHIFT); /* * Set lineout output level in range (0..31) * the same value is used for right and left channel * * Searching for a suitable index solving this formula: * idx = 40 * log10(vag_val / lo_cagcntrl) + 15 */ vol_quot = (vag * 100) / lo_vag; lo_vol = 0; for (i = 0; i < ARRAY_SIZE(vol_quot_table); i++) { if (vol_quot >= vol_quot_table[i]) lo_vol = i; else break; } snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL, SGTL5000_LINE_OUT_VOL_RIGHT_MASK | SGTL5000_LINE_OUT_VOL_LEFT_MASK, lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT | lo_vol << SGTL5000_LINE_OUT_VOL_LEFT_SHIFT); return 0; } Loading sound/soc/samsung/Kconfig +10 −5 Original line number Diff line number Diff line Loading @@ -174,7 +174,8 @@ config SND_SOC_SMDK_WM8994_PCM config SND_SOC_SPEYSIDE tristate "Audio support for Wolfson Speyside" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C && SPI_MASTER depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM8996 select SND_SOC_WM9081 Loading @@ -183,13 +184,15 @@ config SND_SOC_SPEYSIDE config SND_SOC_TOBERMORY tristate "Audio support for Wolfson Tobermory" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT && I2C depends on SND_SOC_SAMSUNG && INPUT && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM8962 config SND_SOC_BELLS tristate "Audio support for Wolfson Bells" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && MFD_ARIZONA && I2C && SPI_MASTER depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM5102 select SND_SOC_WM5110 Loading @@ -199,14 +202,16 @@ config SND_SOC_BELLS config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C depends on SND_SOC_SAMSUNG && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM5100 select SND_SOC_WM9081 config SND_SOC_LITTLEMILL tristate "Audio support for Wolfson Littlemill" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C depends on SND_SOC_SAMSUNG && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select MFD_WM8994 select SND_SOC_WM8994 Loading Loading
Documentation/devicetree/bindings/sound/rt5677.txt +2 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ Required properties: Optional properties: - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. - realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin. - realtek,in1-differential - realtek,in2-differential Loading Loading @@ -70,6 +71,7 @@ rt5677 { realtek,pow-ldo2-gpio = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; realtek,reset-gpio = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_LOW>; realtek,in1-differential = "true"; realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */ realtek,jd2-gpio = <3>; /* Enables Jack detection for GPIO6 */ Loading
sound/soc/codecs/rt5677.c +135 −8 Original line number Diff line number Diff line Loading @@ -1060,6 +1060,7 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec, unsigned int asrc5_mask = 0, asrc5_value = 0; unsigned int asrc6_mask = 0, asrc6_value = 0; unsigned int asrc7_mask = 0, asrc7_value = 0; unsigned int asrc8_mask = 0, asrc8_value = 0; switch (clk_src) { case RT5677_CLK_SEL_SYS: Loading Loading @@ -1196,10 +1197,108 @@ int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec, regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask, asrc7_value); /* ASRC 8 */ if (filter_mask & RT5677_I2S1_SOURCE) { asrc8_mask |= RT5677_I2S1_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S1_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S1_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S2_SOURCE) { asrc8_mask |= RT5677_I2S2_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S2_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S2_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S3_SOURCE) { asrc8_mask |= RT5677_I2S3_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S3_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S3_CLK_SEL_SFT); } if (filter_mask & RT5677_I2S4_SOURCE) { asrc8_mask |= RT5677_I2S4_CLK_SEL_MASK; asrc8_value = (asrc8_value & ~RT5677_I2S4_CLK_SEL_MASK) | ((clk_src - 1) << RT5677_I2S4_CLK_SEL_SFT); } if (asrc8_mask) regmap_update_bits(rt5677->regmap, RT5677_ASRC_8, asrc8_mask, asrc8_value); return 0; } EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src); static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); unsigned int asrc_setting; switch (source->shift) { case 11: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO1_CLK_SEL_MASK) >> RT5677_AD_STO1_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 10: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO2_CLK_SEL_MASK) >> RT5677_AD_STO2_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 9: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO3_CLK_SEL_MASK) >> RT5677_AD_STO3_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 8: regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_STO4_CLK_SEL_MASK) >> RT5677_AD_STO4_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 7: regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_MONOL_CLK_SEL_MASK) >> RT5677_AD_MONOL_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; case 6: regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting); asrc_setting = (asrc_setting & RT5677_AD_MONOR_CLK_SEL_MASK) >> RT5677_AD_MONOR_CLK_SEL_SFT; if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC && asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC) return 1; break; default: break; } return 0; } /* Digital Mixer */ static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, Loading Loading @@ -3057,12 +3156,12 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = { }; static const struct snd_soc_dapm_route rt5677_dapm_routes[] = { { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", can_use_asrc }, { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", can_use_asrc }, { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", can_use_asrc }, { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", can_use_asrc }, { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", can_use_asrc }, { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", can_use_asrc }, { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC", rt5677_dmic_use_asrc }, { "Stereo2 DMIC Mux", NULL, "DMIC STO2 ASRC", rt5677_dmic_use_asrc }, { "Stereo3 DMIC Mux", NULL, "DMIC STO3 ASRC", rt5677_dmic_use_asrc }, { "Stereo4 DMIC Mux", NULL, "DMIC STO4 ASRC", rt5677_dmic_use_asrc }, { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC", rt5677_dmic_use_asrc }, { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC", rt5677_dmic_use_asrc }, { "I2S1", NULL, "I2S1 ASRC", can_use_asrc}, { "I2S2", NULL, "I2S2 ASRC", can_use_asrc}, { "I2S3", NULL, "I2S3 ASRC", can_use_asrc}, Loading Loading @@ -4667,6 +4766,8 @@ static int rt5677_remove(struct snd_soc_codec *codec) regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 0); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 0); return 0; } Loading @@ -4682,6 +4783,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec) if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 0); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 0); } return 0; Loading @@ -4692,10 +4795,13 @@ static int rt5677_resume(struct snd_soc_codec *codec) struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); if (!rt5677->dsp_vad_en) { if (gpio_is_valid(rt5677->pow_ldo2)) { if (gpio_is_valid(rt5677->pow_ldo2)) gpio_set_value_cansleep(rt5677->pow_ldo2, 1); if (gpio_is_valid(rt5677->reset_pin)) gpio_set_value_cansleep(rt5677->reset_pin, 1); if (gpio_is_valid(rt5677->pow_ldo2) || gpio_is_valid(rt5677->reset_pin)) msleep(10); } regcache_cache_only(rt5677->regmap, false); regcache_sync(rt5677->regmap); Loading Loading @@ -4933,6 +5039,8 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) rt5677->pow_ldo2 = of_get_named_gpio(np, "realtek,pow-ldo2-gpio", 0); rt5677->reset_pin = of_get_named_gpio(np, "realtek,reset-gpio", 0); /* * POW_LDO2 is optional (it may be statically tied on the board). Loading @@ -4943,6 +5051,9 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) if (!gpio_is_valid(rt5677->pow_ldo2) && (rt5677->pow_ldo2 != -ENOENT)) return rt5677->pow_ldo2; if (!gpio_is_valid(rt5677->reset_pin) && (rt5677->reset_pin != -ENOENT)) return rt5677->reset_pin; of_property_read_u8_array(np, "realtek,gpio-config", rt5677->pdata.gpio_config, RT5677_GPIO_NUM); Loading Loading @@ -5044,6 +5155,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, } } else { rt5677->pow_ldo2 = -EINVAL; rt5677->reset_pin = -EINVAL; } if (gpio_is_valid(rt5677->pow_ldo2)) { Loading @@ -5055,6 +5167,21 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, rt5677->pow_ldo2, ret); return ret; } } if (gpio_is_valid(rt5677->reset_pin)) { ret = devm_gpio_request_one(&i2c->dev, rt5677->reset_pin, GPIOF_OUT_INIT_HIGH, "RT5677 RESET"); if (ret < 0) { dev_err(&i2c->dev, "Failed to request RESET %d: %d\n", rt5677->reset_pin, ret); return ret; } } if (gpio_is_valid(rt5677->pow_ldo2) || gpio_is_valid(rt5677->reset_pin)) { /* Wait a while until I2C bus becomes available. The datasheet * does not specify the exact we should wait but startup * sequence mentiones at least a few milliseconds. Loading
sound/soc/codecs/rt5677.h +15 −0 Original line number Diff line number Diff line Loading @@ -1446,6 +1446,16 @@ #define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8) #define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8 /* ASRC Control 8 (0x8a) */ #define RT5677_I2S1_CLK_SEL_MASK (0xf << 12) #define RT5677_I2S1_CLK_SEL_SFT 12 #define RT5677_I2S2_CLK_SEL_MASK (0xf << 8) #define RT5677_I2S2_CLK_SEL_SFT 8 #define RT5677_I2S3_CLK_SEL_MASK (0xf << 4) #define RT5677_I2S3_CLK_SEL_SFT 4 #define RT5677_I2S4_CLK_SEL_MASK (0xf) #define RT5677_I2S4_CLK_SEL_SFT 0 /* VAD Function Control 4 (0x9f) */ #define RT5677_VAD_SRC_MASK (0x7 << 8) #define RT5677_VAD_SRC_SFT 8 Loading Loading @@ -1744,6 +1754,10 @@ enum { RT5677_AD_MONO_R_FILTER = (0x1 << 12), RT5677_DSP_OB_0_3_FILTER = (0x1 << 13), RT5677_DSP_OB_4_7_FILTER = (0x1 << 14), RT5677_I2S1_SOURCE = (0x1 << 15), RT5677_I2S2_SOURCE = (0x1 << 16), RT5677_I2S3_SOURCE = (0x1 << 17), RT5677_I2S4_SOURCE = (0x1 << 18), }; struct rt5677_priv { Loading @@ -1762,6 +1776,7 @@ struct rt5677_priv { int pll_in; int pll_out; int pow_ldo2; /* POW_LDO2 pin */ int reset_pin; /* RESET pin */ enum rt5677_type type; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio_chip; Loading
sound/soc/codecs/sgtl5000.c +46 −7 Original line number Diff line number Diff line Loading @@ -1090,6 +1090,19 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg) } } /* * This precalculated table contains all (vag_val * 100 / lo_calcntrl) results * to select an appropriate lo_vol_* in SGTL5000_CHIP_LINE_OUT_VOL * The calculatation was done for all possible register values which * is the array index and the following formula: 10^((idx−15)/40) * 100 */ static const u8 vol_quot_table[] = { 42, 45, 47, 50, 53, 56, 60, 63, 67, 71, 75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188, 200, 211, 224, 237, 251 }; /* * sgtl5000 has 3 internal power supplies: * 1. VAG, normally set to vdda/2 Loading @@ -1110,6 +1123,10 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) u16 ana_pwr; u16 lreg_ctrl; int vag; int lo_vag; int vol_quot; int lo_vol; size_t i; struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); vdda = regulator_get_voltage(sgtl5000->supplies[VDDA].consumer); Loading Loading @@ -1197,23 +1214,45 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT); /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ vag = vddio / 2; if (vag <= SGTL5000_LINE_OUT_GND_BASE) vag = 0; else if (vag >= SGTL5000_LINE_OUT_GND_BASE + lo_vag = vddio / 2; if (lo_vag <= SGTL5000_LINE_OUT_GND_BASE) lo_vag = 0; else if (lo_vag >= SGTL5000_LINE_OUT_GND_BASE + SGTL5000_LINE_OUT_GND_STP * SGTL5000_LINE_OUT_GND_MAX) vag = SGTL5000_LINE_OUT_GND_MAX; lo_vag = SGTL5000_LINE_OUT_GND_MAX; else vag = (vag - SGTL5000_LINE_OUT_GND_BASE) / lo_vag = (lo_vag - SGTL5000_LINE_OUT_GND_BASE) / SGTL5000_LINE_OUT_GND_STP; snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, SGTL5000_LINE_OUT_CURRENT_MASK | SGTL5000_LINE_OUT_GND_MASK, vag << SGTL5000_LINE_OUT_GND_SHIFT | lo_vag << SGTL5000_LINE_OUT_GND_SHIFT | SGTL5000_LINE_OUT_CURRENT_360u << SGTL5000_LINE_OUT_CURRENT_SHIFT); /* * Set lineout output level in range (0..31) * the same value is used for right and left channel * * Searching for a suitable index solving this formula: * idx = 40 * log10(vag_val / lo_cagcntrl) + 15 */ vol_quot = (vag * 100) / lo_vag; lo_vol = 0; for (i = 0; i < ARRAY_SIZE(vol_quot_table); i++) { if (vol_quot >= vol_quot_table[i]) lo_vol = i; else break; } snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_VOL, SGTL5000_LINE_OUT_VOL_RIGHT_MASK | SGTL5000_LINE_OUT_VOL_LEFT_MASK, lo_vol << SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT | lo_vol << SGTL5000_LINE_OUT_VOL_LEFT_SHIFT); return 0; } Loading
sound/soc/samsung/Kconfig +10 −5 Original line number Diff line number Diff line Loading @@ -174,7 +174,8 @@ config SND_SOC_SMDK_WM8994_PCM config SND_SOC_SPEYSIDE tristate "Audio support for Wolfson Speyside" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C && SPI_MASTER depends on SND_SOC_SAMSUNG && I2C && SPI_MASTER depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM8996 select SND_SOC_WM9081 Loading @@ -183,13 +184,15 @@ config SND_SOC_SPEYSIDE config SND_SOC_TOBERMORY tristate "Audio support for Wolfson Tobermory" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT && I2C depends on SND_SOC_SAMSUNG && INPUT && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM8962 config SND_SOC_BELLS tristate "Audio support for Wolfson Bells" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && MFD_ARIZONA && I2C && SPI_MASTER depends on SND_SOC_SAMSUNG && MFD_ARIZONA && I2C && SPI_MASTER depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM5102 select SND_SOC_WM5110 Loading @@ -199,14 +202,16 @@ config SND_SOC_BELLS config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C depends on SND_SOC_SAMSUNG && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select SND_SOC_WM5100 select SND_SOC_WM9081 config SND_SOC_LITTLEMILL tristate "Audio support for Wolfson Littlemill" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C depends on SND_SOC_SAMSUNG && I2C depends on MACH_WLF_CRAGG_6410 || COMPILE_TEST select SND_SAMSUNG_I2S select MFD_WM8994 select SND_SOC_WM8994 Loading