// SPDX-License-Identifier: GPL-2.0
+#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_intel.h>
#include <sound/core.h>
#include <sound/intel-dsp-config.h>
#include <sound/intel-nhlt.h>
module_param(dsp_driver, int, 0444);
MODULE_PARM_DESC(dsp_driver, "Force the DSP driver for Intel DSP (0=auto, 1=legacy, 2=SST, 3=SOF)");
-#define FLAG_SST BIT(0)
-#define FLAG_SOF BIT(1)
-#define FLAG_SOF_ONLY_IF_DMIC BIT(16)
+#define FLAG_SST BIT(0)
+#define FLAG_SOF BIT(1)
+#define FLAG_SST_ONLY_IF_DMIC BIT(15)
+#define FLAG_SOF_ONLY_IF_DMIC BIT(16)
+#define FLAG_SOF_ONLY_IF_SOUNDWIRE BIT(17)
+
+#define FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE (FLAG_SOF_ONLY_IF_DMIC | \
+ FLAG_SOF_ONLY_IF_SOUNDWIRE)
struct config_entry {
u32 flags;
{}
}
},
+ {
+ .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
+ .device = 0x9d70,
+ },
#endif
/* Kabylake-LP */
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
{}
}
},
+ {
+ .flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
+ .device = 0x9d71,
+ },
#endif
/*
}
},
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x9dc8,
},
#endif
}
},
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0xa348,
},
#endif
+ #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE)
/* Cometlake-LP */
- #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP)
{
.flags = FLAG_SOF,
.device = 0x02c8,
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "09C6")
+ },
+ },
+ {
+ /* early version of SKU 09C6 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0983")
+ },
+ },
{}
}
},
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x02c8,
},
- #endif
/* Cometlake-H */
- #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_H)
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF,
+ .device = 0x06c8,
+ .dmi_table = (const struct dmi_system_id []) {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F"),
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990"),
+ },
+ },
+ {}
+ }
+ },
+ {
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x06c8,
},
#endif
}
},
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x34c8,
},
#endif
{}
}
},
-
{
- .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
+ .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0xa0c8,
},
#endif
return ret;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+ struct sdw_intel_acpi_info info;
+ acpi_handle handle;
+ int ret;
+
+ handle = ACPI_HANDLE(&pci->dev);
+
+ ret = sdw_intel_acpi_scan(handle, &info);
+ if (ret < 0)
+ return ret;
+
+ return info.link_mask;
+}
+#else
+static int snd_intel_dsp_check_soundwire(struct pci_dev *pci)
+{
+ return 0;
+}
+#endif
+
int snd_intel_dsp_driver_probe(struct pci_dev *pci)
{
const struct config_entry *cfg;
return SND_INTEL_DSP_DRIVER_ANY;
if (cfg->flags & FLAG_SOF) {
- if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC) {
+ if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
+ snd_intel_dsp_check_soundwire(pci) > 0) {
+ dev_info(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n");
+ return SND_INTEL_DSP_DRIVER_SOF;
+ }
+ if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
+ snd_intel_dsp_check_dmic(pci)) {
+ dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
+ return SND_INTEL_DSP_DRIVER_SOF;
+ }
+ if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE))
+ return SND_INTEL_DSP_DRIVER_SOF;
+ }
+
+
+ if (cfg->flags & FLAG_SST) {
+ if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) {
if (snd_intel_dsp_check_dmic(pci)) {
- dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n");
- return SND_INTEL_DSP_DRIVER_SOF;
+ dev_info(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n");
+ return SND_INTEL_DSP_DRIVER_SST;
}
} else {
- return SND_INTEL_DSP_DRIVER_SOF;
+ return SND_INTEL_DSP_DRIVER_SST;
}
}
- if (cfg->flags & FLAG_SST)
- return SND_INTEL_DSP_DRIVER_SST;
-
return SND_INTEL_DSP_DRIVER_LEGACY;
}
EXPORT_SYMBOL_GPL(snd_intel_dsp_driver_probe);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel DSP config driver");
+MODULE_IMPORT_NS(SOUNDWIRE_INTEL_INIT);
#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)
+ #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)
+ #define RT5670_GPIO1_IS_EXT_SPK_EN BIT(12)
static unsigned long rt5670_quirk;
static unsigned int quirk_override;
snd_soc_component_update_bits(component, RT5670_CJ_CTRL2,
RT5670_CBJ_MN_JD, 0);
msleep(300);
- val = snd_soc_component_read32(component, RT5670_CJ_CTRL3) & 0x7;
+ val = snd_soc_component_read(component, RT5670_CJ_CTRL3) & 0x7;
if (val == 0x1 || val == 0x2) {
rt5670->jack_type = SND_JACK_HEADSET;
/* for push button */
snd_soc_component_update_bits(component, RT5670_INT_IRQ_ST, 0x8, 0x8);
snd_soc_component_update_bits(component, RT5670_IL_CMD, 0x40, 0x40);
- snd_soc_component_read32(component, RT5670_IL_CMD);
+ snd_soc_component_read(component, RT5670_IL_CMD);
} else {
snd_soc_component_update_bits(component, RT5670_GEN_CTRL3, 0x4, 0x4);
rt5670->jack_type = SND_JACK_HEADPHONE;
{
int btn_type, val;
- val = snd_soc_component_read32(component, RT5670_IL_CMD);
+ val = snd_soc_component_read(component, RT5670_IL_CMD);
btn_type = val & 0xff80;
snd_soc_component_write(component, RT5670_IL_CMD, val);
if (btn_type != 0) {
msleep(20);
- val = snd_soc_component_read32(component, RT5670_IL_CMD);
+ val = snd_soc_component_read(component, RT5670_IL_CMD);
snd_soc_component_write(component, RT5670_IL_CMD, val);
}
int val, btn_type, report = jack->status;
if (rt5670->pdata.jd_mode == 1) /* 2 port */
- val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
+ val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0070;
else
- val = snd_soc_component_read32(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;
+ val = snd_soc_component_read(rt5670->component, RT5670_A_JD_CTRL1) & 0x0020;
switch (val) {
/* jack in */
break;
}
btn_type = 0;
- if (snd_soc_component_read32(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
+ if (snd_soc_component_read(rt5670->component, RT5670_INT_IRQ_ST) & 0x4) {
/* button pressed */
report = SND_JACK_HEADSET;
btn_type = rt5670_button_detect(rt5670->component);
EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
- static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
+ static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -6562, 0);
static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
- static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0);
+ static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -1762, 3000);
static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
/* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
return 0;
}
- val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
+ val = (snd_soc_component_read(component, reg) >> shift) & 0xf;
switch (val) {
case 1:
case 2:
return 0;
}
+ static int rt5670_spk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+ {
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
+
+ if (!rt5670->pdata.gpio1_is_ext_spk_en)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+ RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_HI);
+ break;
+
+ case SND_SOC_DAPM_PRE_PMD:
+ regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+ RT5670_GP1_OUT_MASK, RT5670_GP1_OUT_LO);
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 0;
+ }
+
static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
};
static const struct snd_soc_dapm_widget rt5672_specific_dapm_widgets[] = {
- SND_SOC_DAPM_PGA("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("SPO Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
+ rt5670_spk_event, SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_OUTPUT("SPOLP"),
SND_SOC_DAPM_OUTPUT("SPOLN"),
SND_SOC_DAPM_OUTPUT("SPORP"),
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
struct rt5670_priv *rt5670 = snd_soc_component_get_drvdata(component);
- switch (snd_soc_component_read32(component, RT5670_RESET) & RT5670_ID_MASK) {
+ switch (snd_soc_component_read(component, RT5670_RESET) & RT5670_ID_MASK) {
case RT5670_ID_5670:
case RT5670_ID_5671:
snd_soc_dapm_new_controls(dapm,
},
{
.callback = rt5670_quirk_cb,
- .ident = "Lenovo Thinkpad Tablet 10",
+ .ident = "Lenovo Miix 2 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_GPIO1_IS_EXT_SPK_EN |
RT5670_JD_MODE2),
},
{
rt5670->pdata.dev_gpio = true;
dev_info(&i2c->dev, "quirk dev_gpio\n");
}
+ if (rt5670_quirk & RT5670_GPIO1_IS_EXT_SPK_EN) {
+ rt5670->pdata.gpio1_is_ext_spk_en = true;
+ dev_info(&i2c->dev, "quirk GPIO1 is external speaker enable\n");
+ }
if (rt5670_quirk & RT5670_IN2_DIFF) {
rt5670->pdata.in2_diff = true;
dev_info(&i2c->dev, "quirk IN2_DIFF\n");
RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
}
+ if (rt5670->pdata.gpio1_is_ext_spk_en) {
+ regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
+ RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_GPIO1);
+ regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
+ RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
+ }
+
if (rt5670->pdata.jd_mode) {
regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
{
int btn_type, val;
- val = snd_soc_component_read32(component, RT5682_4BTN_IL_CMD_1);
+ val = snd_soc_component_read(component, RT5682_4BTN_IL_CMD_1);
btn_type = val & 0xfff0;
snd_soc_component_write(component, RT5682_4BTN_IL_CMD_1, val);
dev_dbg(component->dev, "%s btn_type=%x\n", __func__, btn_type);
RT5682_PWR_ANLG_1, RT5682_PWR_FV2, RT5682_PWR_FV2);
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_3,
RT5682_PWR_CBJ, RT5682_PWR_CBJ);
-
+ snd_soc_component_update_bits(component,
+ RT5682_HP_CHARGE_PUMP_1,
+ RT5682_OSW_L_MASK | RT5682_OSW_R_MASK, 0);
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
RT5682_TRIG_JD_MASK, RT5682_TRIG_JD_HIGH);
count = 0;
- val = snd_soc_component_read32(component, RT5682_CBJ_CTRL_2)
+ val = snd_soc_component_read(component, RT5682_CBJ_CTRL_2)
& RT5682_JACK_TYPE_MASK;
while (val == 0 && count < 50) {
usleep_range(10000, 15000);
- val = snd_soc_component_read32(component,
+ val = snd_soc_component_read(component,
RT5682_CBJ_CTRL_2) & RT5682_JACK_TYPE_MASK;
count++;
}
rt5682->jack_type = SND_JACK_HEADPHONE;
break;
}
+
+ snd_soc_component_update_bits(component,
+ RT5682_HP_CHARGE_PUMP_1,
+ RT5682_OSW_L_MASK | RT5682_OSW_R_MASK,
+ RT5682_OSW_L_EN | RT5682_OSW_R_EN);
} else {
rt5682_enable_push_button_irq(component, false);
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
mutex_lock(&rt5682->calibrate_mutex);
- val = snd_soc_component_read32(rt5682->component, RT5682_AJD1_CTRL)
+ val = snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL)
& RT5682_JDH_RS_MASK;
if (!val) {
/* jack in */
if (rt5682->is_sdw)
return 0;
- val = snd_soc_component_read32(component, RT5682_GPIO_CTRL_1) &
+ val = snd_soc_component_read(component, RT5682_GPIO_CTRL_1) &
RT5682_GP4_PIN_MASK;
if (w->shift == RT5682_PWR_ADC_S1F_BIT &&
val == RT5682_GP4_PIN_ADCDAT2)
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
- val = snd_soc_component_read32(component, RT5682_GLB_CLK);
+ val = snd_soc_component_read(component, RT5682_GLB_CLK);
val &= RT5682_SCLK_SRC_MASK;
if (val == RT5682_SCLK_SRC_PLL1)
return 1;
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
- val = snd_soc_component_read32(component, RT5682_GLB_CLK);
+ val = snd_soc_component_read(component, RT5682_GLB_CLK);
val &= RT5682_SCLK_SRC_MASK;
if (val == RT5682_SCLK_SRC_PLL2)
return 1;
return 0;
}
- val = (snd_soc_component_read32(component, reg) >> shift) & 0xf;
+ val = (snd_soc_component_read(component, reg) >> shift) & 0xf;
switch (val) {
case RT5682_CLK_SEL_I2S1_ASRC:
case RT5682_CLK_SEL_I2S2_ASRC:
{
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
struct rl6231_pll_code pll_code, pll2f_code, pll2b_code;
- unsigned int pll2_fout1;
+ unsigned int pll2_fout1, pll2_ps_val;
int ret;
if (source == rt5682->pll_src[pll_id] &&
pll2b_code.n_code);
snd_soc_component_write(component, RT5682_PLL2_CTRL_3,
pll2f_code.n_code << RT5682_PLL2F_N_SFT);
+
+ if (freq_out == 22579200)
+ pll2_ps_val = 1 << RT5682_PLL2B_SEL_PS_SFT;
+ else
+ pll2_ps_val = 1 << RT5682_PLL2B_PS_BYP_SFT;
snd_soc_component_update_bits(component, RT5682_PLL2_CTRL_4,
+ RT5682_PLL2B_SEL_PS_MASK | RT5682_PLL2B_PS_BYP_MASK |
RT5682_PLL2B_M_BP_MASK | RT5682_PLL2F_M_BP_MASK | 0xf,
+ pll2_ps_val |
(pll2b_code.m_bp ? 1 : 0) << RT5682_PLL2B_M_BP_SFT |
(pll2f_code.m_bp ? 1 : 0) << RT5682_PLL2F_M_BP_SFT |
0xf);
#ifdef CONFIG_COMMON_CLK
#define CLK_PLL2_FIN 48000000
-#define CLK_PLL2_FOUT 24576000
#define CLK_48 48000
+#define CLK_44 44100
static bool rt5682_clk_check(struct rt5682_priv *rt5682)
{
struct rt5682_priv *rt5682 =
container_of(hw, struct rt5682_priv,
dai_clks_hw[RT5682_DAI_WCLK_IDX]);
+ struct snd_soc_component *component = rt5682->component;
+ const char * const clk_name = __clk_get_name(hw->clk);
if (!rt5682_clk_check(rt5682))
return 0;
/*
- * Only accept to set wclk rate to 48kHz temporarily.
+ * Only accept to set wclk rate to 44.1k or 48kHz.
*/
- return CLK_48;
+ if (rt5682->lrck[RT5682_AIF1] != CLK_48 &&
+ rt5682->lrck[RT5682_AIF1] != CLK_44) {
+ dev_warn(component->dev, "%s: clk %s only support %d or %d Hz output\n",
+ __func__, clk_name, CLK_44, CLK_48);
+ return 0;
+ }
+
+ return rt5682->lrck[RT5682_AIF1];
}
static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate,
struct rt5682_priv *rt5682 =
container_of(hw, struct rt5682_priv,
dai_clks_hw[RT5682_DAI_WCLK_IDX]);
+ struct snd_soc_component *component = rt5682->component;
+ const char * const clk_name = __clk_get_name(hw->clk);
if (!rt5682_clk_check(rt5682))
return -EINVAL;
/*
- * Only accept to set wclk rate to 48kHz temporarily.
+ * Only accept to set wclk rate to 44.1k or 48kHz.
+ * It will force to 48kHz if not both.
*/
- return CLK_48;
+ if (rate != CLK_48 && rate != CLK_44) {
+ dev_warn(component->dev, "%s: clk %s only support %d or %d Hz output\n",
+ __func__, clk_name, CLK_44, CLK_48);
+ rate = CLK_48;
+ }
+
+ return rate;
}
static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk *parent_clk;
const char * const clk_name = __clk_get_name(hw->clk);
int pre_div;
+ unsigned int clk_pll2_out;
if (!rt5682_clk_check(rt5682))
return -EINVAL;
clk_name, CLK_PLL2_FIN);
/*
- * It's a temporary limitation. Only accept to set wclk rate to 48kHz.
- * It will force wclk to 48kHz even it's not.
- */
- if (rate != CLK_48) {
- dev_warn(component->dev, "clk %s only support %d Hz output\n",
- clk_name, CLK_48);
- rate = CLK_48;
- }
-
- /*
- * To achieve the rate conversion from 48MHz to 48kHz, PLL2 is needed.
+ * To achieve the rate conversion from 48MHz to 44.1k or 48kHz,
+ * PLL2 is needed.
*/
+ clk_pll2_out = rate * 512;
rt5682_set_component_pll(component, RT5682_PLL2, RT5682_PLL2_S_MCLK,
- CLK_PLL2_FIN, CLK_PLL2_FOUT);
+ CLK_PLL2_FIN, clk_pll2_out);
rt5682_set_component_sysclk(component, RT5682_SCLK_S_PLL2, 0,
- CLK_PLL2_FOUT, SND_SOC_CLOCK_IN);
+ clk_pll2_out, SND_SOC_CLOCK_IN);
+
+ rt5682->lrck[RT5682_AIF1] = rate;
pre_div = rl6231_get_clk_info(rt5682->sysclk, rate);
struct snd_soc_component *component = rt5682->component;
unsigned int bclks_per_wclk;
- snd_soc_component_read(component, RT5682_TDM_TCON_CTRL,
- &bclks_per_wclk);
+ bclks_per_wclk = snd_soc_component_read(component, RT5682_TDM_TCON_CTRL);
switch (bclks_per_wclk & RT5682_TDM_BCLK_MS1_MASK) {
case RT5682_TDM_BCLK_MS1_256:
endif ## SND_SOC_SOF_HDA_LINK || SND_SOC_SOF_BAYTRAIL
- if (SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK)
+ if (SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK)
config SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH
tristate "CML_LP with DA7219 and MAX98357A in I2S Mode"
Say Y if you have such a device.
If unsure select "N".
- endif ## SND_SOC_SOF_COMETLAKE_LP && SND_SOC_SOF_HDA_LINK
+ endif ## SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK
if SND_SOC_SOF_JASPERLAKE
depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST
depends on SOUNDWIRE
depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC
+ select SND_SOC_MAX98373_SDW
select SND_SOC_RT700_SDW
select SND_SOC_RT711_SDW
select SND_SOC_RT1308_SDW
select SND_SOC_DMIC
help
Add support for Intel SoundWire-based platforms connected to
- RT700, RT711, RT1308 and RT715
+ MAX98373, RT700, RT711, RT1308 and RT715
If unsure select "N".
endif
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
/*
- * Default mode for SSP configuration is TDM 4 slot
+ * Default mode for SSP configuration is TDM 4 slot. One board/design,
+ * the Lenovo Miix 2 10 uses not 1 but 2 codecs connected to SSP2. The
+ * second piggy-backed, output-only codec is inside the keyboard-dock
+ * (which has extra speakers). Unlike the main rt5672 codec, we cannot
+ * configure this codec, it is hard coded to use 2 channel 24 bit I2S.
+ * Since we only support 2 channels anyways, there is no need for TDM
+ * on any cht-bsw-rt5672 designs. So we simply use I2S 2ch everywhere.
*/
- ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0),
- SND_SOC_DAIFMT_DSP_B |
- SND_SOC_DAIFMT_IB_NF |
+ ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0) {
- dev_err(rtd->dev, "can't set format to TDM %d\n", ret);
- return ret;
- }
-
- /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
- ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24);
- if (ret < 0) {
- dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret);
+ dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
return ret;
}
return 0;
}
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
+/* use space before codec name to simplify card ID, and simplify driver name */
+#define CARD_NAME "bytcht rt5672" /* card name will be 'sof-bytcht rt5672' */
+#define DRIVER_NAME "SOF"
+#else
+#define CARD_NAME "cht-bsw-rt5672"
+#define DRIVER_NAME NULL /* card name will be used for driver name */
+#endif
+
/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
- .name = "cht-bsw-rt5672",
+ .name = CARD_NAME,
+ .driver_name = DRIVER_NAME,
.owner = THIS_MODULE,
.dai_link = cht_dailink,
.num_links = ARRAY_SIZE(cht_dailink),
config SND_SOC_QDSP6
tristate "SoC ALSA audio driver for QDSP6"
- depends on QCOM_APR && HAS_DMA
+ depends on QCOM_APR
select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_CORE
select SND_SOC_QDSP6_AFE
config SND_SOC_SDM845
tristate "SoC Machine driver for SDM845 boards"
- depends on QCOM_APR && CROS_EC && I2C && SOUNDWIRE
+ depends on QCOM_APR && I2C && SOUNDWIRE
select SND_SOC_QDSP6
select SND_SOC_QCOM_COMMON
select SND_SOC_RT5663
select SND_SOC_MAX98927
- select SND_SOC_CROS_EC_CODEC
+ imply SND_SOC_CROS_EC_CODEC
help
To add support for audio on Qualcomm Technologies Inc.
SDM845 SoC-based systems.