Commit f66229aa authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-v5.17-2' of...

Merge tag 'asoc-v5.17-2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v5.17

A few more updates for v5.17, nothing hugely stand out in the few days
since the initial pull request was sent.
parents 2e88c6a8 f517ba49
......@@ -2744,10 +2744,16 @@ EXPORT_SYMBOL_GPL(cs_dsp_stop);
static int cs_dsp_halo_start_core(struct cs_dsp *dsp)
{
return regmap_update_bits(dsp->regmap,
dsp->base + HALO_CCM_CORE_CONTROL,
HALO_CORE_RESET | HALO_CORE_EN,
HALO_CORE_RESET | HALO_CORE_EN);
int ret;
ret = regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL,
HALO_CORE_RESET | HALO_CORE_EN,
HALO_CORE_RESET | HALO_CORE_EN);
if (ret)
return ret;
return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL,
HALO_CORE_RESET, 0);
}
static void cs_dsp_halo_stop_core(struct cs_dsp *dsp)
......
......@@ -40,6 +40,9 @@
#define CS35L41_PROTECT_REL_ERR_IGN 0x00002034
#define CS35L41_GPIO_PAD_CONTROL 0x0000242C
#define CS35L41_JTAG_CONTROL 0x00002438
#define CS35L41_PWRMGT_CTL 0x00002900
#define CS35L41_WAKESRC_CTL 0x00002904
#define CS35L41_PWRMGT_STS 0x00002908
#define CS35L41_PLL_CLK_CTRL 0x00002C04
#define CS35L41_DSP_CLK_CTRL 0x00002C08
#define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C
......@@ -635,6 +638,8 @@
#define CS35L41_INPUT_DSP_TX1 0x32
#define CS35L41_INPUT_DSP_TX2 0x33
#define CS35L41_WR_PEND_STS_MASK 0x2
#define CS35L41_PLL_CLK_SEL_MASK 0x07
#define CS35L41_PLL_CLK_SEL_SHIFT 0
#define CS35L41_PLL_CLK_EN_MASK 0x10
......@@ -762,6 +767,8 @@ struct cs35l41_otp_map_element_t {
extern struct regmap_config cs35l41_regmap_i2c;
extern struct regmap_config cs35l41_regmap_spi;
int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap);
int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap);
int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap);
int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid);
int cs35l41_set_channels(struct device *dev, struct regmap *reg,
......
......@@ -293,8 +293,8 @@ static const struct snd_soc_ops acp_card_rt5682s_ops = {
/* Declare RT1019 codec components */
SND_SOC_DAILINK_DEF(rt1019,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"),
COMP_CODEC("i2c-10EC1019:02", "rt1019-aif")));
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
static const struct snd_soc_dapm_route rt1019_map_lr[] = {
{ "Left Spk", NULL, "Left SPO" },
......@@ -303,11 +303,11 @@ static const struct snd_soc_dapm_route rt1019_map_lr[] = {
static struct snd_soc_codec_conf rt1019_conf[] = {
{
.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
.dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
.name_prefix = "Left",
},
{
.dlc = COMP_CODEC_CONF("i2c-10EC1019:02"),
.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
.name_prefix = "Right",
},
};
......
......@@ -438,7 +438,6 @@ static int ak4375_power_on(struct ak4375_priv *ak4375)
return 0;
}
#ifdef CONFIG_PM
static int __maybe_unused ak4375_runtime_suspend(struct device *dev)
{
struct ak4375_priv *ak4375 = dev_get_drvdata(dev);
......@@ -463,7 +462,6 @@ static int __maybe_unused ak4375_runtime_resume(struct device *dev)
return regcache_sync(ak4375->regmap);
}
#endif /* CONFIG_PM */
static const struct snd_soc_component_driver soc_codec_dev_ak4375 = {
.controls = ak4375_snd_controls,
......
......@@ -22,6 +22,8 @@
static const struct i2c_device_id cs35l41_id_i2c[] = {
{ "cs35l40", 0 },
{ "cs35l41", 0 },
{ "cs35l51", 0 },
{ "cs35l53", 0 },
{}
};
......@@ -84,6 +86,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match);
static struct i2c_driver cs35l41_i2c_driver = {
.driver = {
.name = "cs35l41",
.pm = &cs35l41_pm_ops,
.of_match_table = of_match_ptr(cs35l41_of_match),
.acpi_match_table = ACPI_PTR(cs35l41_acpi_match),
},
......
......@@ -20,6 +20,11 @@ static const struct reg_default cs35l41_reg[] = {
{ CS35L41_PWR_CTRL2, 0x00000000 },
{ CS35L41_PWR_CTRL3, 0x01000010 },
{ CS35L41_GPIO_PAD_CONTROL, 0x00000000 },
{ CS35L41_GLOBAL_CLK_CTRL, 0x00000003 },
{ CS35L41_TST_FS_MON0, 0x00020016 },
{ CS35L41_BSTCVRT_COEFF, 0x00002424 },
{ CS35L41_BSTCVRT_SLOPE_LBST, 0x00007500 },
{ CS35L41_BSTCVRT_PEAK_CUR, 0x0000004A },
{ CS35L41_SP_ENABLES, 0x00000000 },
{ CS35L41_SP_RATE_CTRL, 0x00000028 },
{ CS35L41_SP_FORMAT, 0x18180200 },
......@@ -48,11 +53,16 @@ static const struct reg_default cs35l41_reg[] = {
{ CS35L41_WKFET_CFG, 0x00000111 },
{ CS35L41_NG_CFG, 0x00000033 },
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 },
{ CS35L41_IRQ1_MASK1, 0xFFFFFFFF },
{ CS35L41_IRQ1_MASK2, 0xFFFFFFFF },
{ CS35L41_IRQ1_MASK3, 0xFFFF87FF },
{ CS35L41_IRQ1_MASK4, 0xFEFFFFFF },
{ CS35L41_GPIO1_CTRL1, 0xE1000001 },
{ CS35L41_GPIO2_CTRL1, 0xE1000001 },
{ CS35L41_MIXER_NGATE_CFG, 0x00000000 },
{ CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 },
{ CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 },
{ CS35L41_DSP1_CCM_CORE_CTRL, 0x00000101 },
};
static bool cs35l41_readable_reg(struct device *dev, unsigned int reg)
......@@ -80,10 +90,14 @@ static bool cs35l41_readable_reg(struct device *dev, unsigned int reg)
case CS35L41_PROTECT_REL_ERR_IGN:
case CS35L41_GPIO_PAD_CONTROL:
case CS35L41_JTAG_CONTROL:
case CS35L41_PWRMGT_CTL:
case CS35L41_WAKESRC_CTL:
case CS35L41_PWRMGT_STS:
case CS35L41_PLL_CLK_CTRL:
case CS35L41_DSP_CLK_CTRL:
case CS35L41_GLOBAL_CLK_CTRL:
case CS35L41_DATA_FS_SEL:
case CS35L41_TST_FS_MON0:
case CS35L41_MDSYNC_EN:
case CS35L41_MDSYNC_TX_ID:
case CS35L41_MDSYNC_PWR_CTRL:
......@@ -342,7 +356,10 @@ static bool cs35l41_readable_reg(struct device *dev, unsigned int reg)
static bool cs35l41_precious_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case CS35L41_TEST_KEY_CTL:
case CS35L41_USER_KEY_CTL:
case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31:
case CS35L41_TST_FS_MON0:
case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068:
case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532:
case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114:
......@@ -359,6 +376,12 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
case CS35L41_SFT_RESET:
case CS35L41_FABID:
case CS35L41_REVID:
case CS35L41_OTPID:
case CS35L41_TEST_KEY_CTL:
case CS35L41_USER_KEY_CTL:
case CS35L41_PWRMGT_CTL:
case CS35L41_WAKESRC_CTL:
case CS35L41_PWRMGT_STS:
case CS35L41_DTEMP_EN:
case CS35L41_IRQ1_STATUS:
case CS35L41_IRQ1_STATUS1:
......@@ -369,17 +392,6 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
case CS35L41_IRQ1_RAW_STATUS2:
case CS35L41_IRQ1_RAW_STATUS3:
case CS35L41_IRQ1_RAW_STATUS4:
case CS35L41_IRQ1_FRC1:
case CS35L41_IRQ1_FRC2:
case CS35L41_IRQ1_FRC3:
case CS35L41_IRQ1_FRC4:
case CS35L41_IRQ1_EDGE1:
case CS35L41_IRQ1_EDGE4:
case CS35L41_IRQ1_POL1:
case CS35L41_IRQ1_POL2:
case CS35L41_IRQ1_POL3:
case CS35L41_IRQ1_POL4:
case CS35L41_IRQ1_DB3:
case CS35L41_IRQ2_STATUS:
case CS35L41_IRQ2_STATUS1:
case CS35L41_IRQ2_STATUS2:
......@@ -389,54 +401,7 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
case CS35L41_IRQ2_RAW_STATUS2:
case CS35L41_IRQ2_RAW_STATUS3:
case CS35L41_IRQ2_RAW_STATUS4:
case CS35L41_IRQ2_FRC1:
case CS35L41_IRQ2_FRC2:
case CS35L41_IRQ2_FRC3:
case CS35L41_IRQ2_FRC4:
case CS35L41_IRQ2_EDGE1:
case CS35L41_IRQ2_EDGE4:
case CS35L41_IRQ2_POL1:
case CS35L41_IRQ2_POL2:
case CS35L41_IRQ2_POL3:
case CS35L41_IRQ2_POL4:
case CS35L41_IRQ2_DB3:
case CS35L41_GPIO_STATUS1:
case CS35L41_OTP_TRIM_1:
case CS35L41_OTP_TRIM_2:
case CS35L41_OTP_TRIM_3:
case CS35L41_OTP_TRIM_4:
case CS35L41_OTP_TRIM_5:
case CS35L41_OTP_TRIM_6:
case CS35L41_OTP_TRIM_7:
case CS35L41_OTP_TRIM_8:
case CS35L41_OTP_TRIM_9:
case CS35L41_OTP_TRIM_10:
case CS35L41_OTP_TRIM_11:
case CS35L41_OTP_TRIM_12:
case CS35L41_OTP_TRIM_13:
case CS35L41_OTP_TRIM_14:
case CS35L41_OTP_TRIM_15:
case CS35L41_OTP_TRIM_16:
case CS35L41_OTP_TRIM_17:
case CS35L41_OTP_TRIM_18:
case CS35L41_OTP_TRIM_19:
case CS35L41_OTP_TRIM_20:
case CS35L41_OTP_TRIM_21:
case CS35L41_OTP_TRIM_22:
case CS35L41_OTP_TRIM_23:
case CS35L41_OTP_TRIM_24:
case CS35L41_OTP_TRIM_25:
case CS35L41_OTP_TRIM_26:
case CS35L41_OTP_TRIM_27:
case CS35L41_OTP_TRIM_28:
case CS35L41_OTP_TRIM_29:
case CS35L41_OTP_TRIM_30:
case CS35L41_OTP_TRIM_31:
case CS35L41_OTP_TRIM_32:
case CS35L41_OTP_TRIM_33:
case CS35L41_OTP_TRIM_34:
case CS35L41_OTP_TRIM_35:
case CS35L41_OTP_TRIM_36:
case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8:
case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068:
case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046:
......@@ -445,7 +410,11 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022:
case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045:
case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114:
case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS:
case CS35L41_DSP1_SCRATCH1:
case CS35L41_DSP1_SCRATCH2:
case CS35L41_DSP1_SCRATCH3:
case CS35L41_DSP1_SCRATCH4:
case CS35L41_DSP1_CCM_CLK_OVERRIDE ... CS35L41_DSP1_WDT_STATUS:
case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31:
return true;
default:
......@@ -660,8 +629,6 @@ static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM]
};
static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
{ 0x00000040, 0x00005555 },
{ 0x00000040, 0x0000AAAA },
{ 0x00003854, 0x05180240 },
{ CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
{ 0x00004310, 0x00000000 },
......@@ -674,38 +641,28 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
{ CS35L41_IRQ2_DB3, 0x00000000 },
{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
{ 0x00000040, 0x0000CCCC },
{ 0x00000040, 0x00003333 },
{ CS35L41_PWR_CTRL2, 0x00000000 },
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 },
};
static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
{ 0x00000040, 0x00005555 },
{ 0x00000040, 0x0000AAAA },
{ CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
{ 0x00004310, 0x00000000 },
{ CS35L41_VPVBST_FS_SEL, 0x00000000 },
{ CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 },
{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
{ 0x00000040, 0x0000CCCC },
{ 0x00000040, 0x00003333 },
{ CS35L41_PWR_CTRL2, 0x00000000 },
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 },
};
static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
{ 0x00000040, 0x00005555 },
{ 0x00000040, 0x0000AAAA },
{ CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 },
{ 0x00004310, 0x00000000 },
{ CS35L41_VPVBST_FS_SEL, 0x00000000 },
{ CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 },
{ CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
{ CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
{ 0x00000040, 0x0000CCCC },
{ 0x00000040, 0x00003333 },
{ CS35L41_PWR_CTRL2, 0x00000000 },
{ CS35L41_AMP_GAIN_CTRL, 0x00000000 },
};
......@@ -793,6 +750,39 @@ static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id)
return NULL;
}
int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap)
{
static const struct reg_sequence unlock[] = {
{ CS35L41_TEST_KEY_CTL, 0x00000055 },
{ CS35L41_TEST_KEY_CTL, 0x000000AA },
};
int ret;
ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock));
if (ret)
dev_err(dev, "Failed to unlock test key: %d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(cs35l41_test_key_unlock);
int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap)
{
static const struct reg_sequence unlock[] = {
{ CS35L41_TEST_KEY_CTL, 0x000000CC },
{ CS35L41_TEST_KEY_CTL, 0x00000033 },
};
int ret;
ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock));
if (ret)
dev_err(dev, "Failed to lock test key: %d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(cs35l41_test_key_lock);
/* Must be called with the TEST_KEY unlocked */
int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap)
{
const struct cs35l41_otp_map_element_t *otp_map_match;
......@@ -831,17 +821,6 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap)
bit_offset = otp_map_match->bit_offset;
word_offset = otp_map_match->word_offset;
ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000055);
if (ret) {
dev_err(dev, "Write Unlock key failed 1/2: %d\n", ret);
goto err_otp_unpack;
}
ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000AA);
if (ret) {
dev_err(dev, "Write Unlock key failed 2/2: %d\n", ret);
goto err_otp_unpack;
}
for (i = 0; i < otp_map_match->num_elements; i++) {
dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n",
bit_offset, word_offset, bit_sum % 32);
......@@ -877,16 +856,6 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap)
}
}
ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000CC);
if (ret) {
dev_err(dev, "Write Lock key failed 1/2: %d\n", ret);
goto err_otp_unpack;
}
ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000033);
if (ret) {
dev_err(dev, "Write Lock key failed 2/2: %d\n", ret);
goto err_otp_unpack;
}
ret = 0;
err_otp_unpack:
......@@ -896,6 +865,7 @@ int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap)
}
EXPORT_SYMBOL_GPL(cs35l41_otp_unpack);
/* Must be called with the TEST_KEY unlocked */
int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid)
{
char *rev;
......
......@@ -20,6 +20,8 @@
static const struct spi_device_id cs35l41_id_spi[] = {
{ "cs35l40", 0 },
{ "cs35l41", 0 },
{ "cs35l51", 0 },
{ "cs35l53", 0 },
{}
};
......@@ -82,6 +84,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match);
static struct spi_driver cs35l41_spi_driver = {
.driver = {
.name = "cs35l41",
.pm = &cs35l41_pm_ops,
.of_match_table = of_match_ptr(cs35l41_of_match),
.acpi_match_table = ACPI_PTR(cs35l41_acpi_match),
},
......
This diff is collapsed.
......@@ -21,6 +21,8 @@
#define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
#define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
extern const struct dev_pm_ops cs35l41_pm_ops;
enum cs35l41_cspl_mbox_status {
CSPL_MBOX_STS_RUNNING = 0,
CSPL_MBOX_STS_PAUSED = 1,
......@@ -33,6 +35,8 @@ enum cs35l41_cspl_mbox_cmd {
CSPL_MBOX_CMD_RESUME = 2,
CSPL_MBOX_CMD_REINIT = 3,
CSPL_MBOX_CMD_STOP_PRE_REINIT = 4,
CSPL_MBOX_CMD_HIBERNATE = 5,
CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6,
CSPL_MBOX_CMD_UNKNOWN_CMD = -1,
CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
};
......
......@@ -626,6 +626,16 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
ARRAY_SIZE(cs4265_dai));
}
static int cs4265_i2c_remove(struct i2c_client *i2c)
{
struct cs4265_private *cs4265 = i2c_get_clientdata(i2c);
if (cs4265->reset_gpio)
gpiod_set_value_cansleep(cs4265->reset_gpio, 0);
return 0;
}
static const struct of_device_id cs4265_of_match[] = {
{ .compatible = "cirrus,cs4265", },
{ }
......@@ -645,6 +655,7 @@ static struct i2c_driver cs4265_i2c_driver = {
},
.id_table = cs4265_id,
.probe = cs4265_i2c_probe,
.remove = cs4265_i2c_remove,
};
module_i2c_driver(cs4265_i2c_driver);
......
......@@ -2160,7 +2160,11 @@ static bool rt5640_jack_inserted(struct snd_soc_component *component)
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
int val;
val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);
if (rt5640->jd_gpio)
val = gpiod_get_value(rt5640->jd_gpio) ? RT5640_JD_STATUS : 0;
else
val = snd_soc_component_read(component, RT5640_INT_IRQ_ST);
dev_dbg(component->dev, "irq status %#04x\n", val);
if (rt5640->jd_inverted)
......@@ -2298,7 +2302,7 @@ EXPORT_SYMBOL_GPL(rt5640_detect_headset);
static void rt5640_jack_work(struct work_struct *work)
{
struct rt5640_priv *rt5640 =
container_of(work, struct rt5640_priv, jack_work);
container_of(work, struct rt5640_priv, jack_work.work);
struct snd_soc_component *component = rt5640->component;
int status;
......@@ -2381,7 +2385,7 @@ static void rt5640_jack_work(struct work_struct *work)
* disabled the OVCD IRQ, the IRQ pin will stay high and as
* we react to edges, we miss the unplug event -> recheck.
*/
queue_work(system_long_wq, &rt5640->jack_work);
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
}
}
......@@ -2390,7 +2394,17 @@ static irqreturn_t rt5640_irq(int irq, void *data)
struct rt5640_priv *rt5640 = data;
if (rt5640->jack)
queue_work(system_long_wq, &rt5640->jack_work);
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
return IRQ_HANDLED;
}
static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data)
{
struct rt5640_priv *rt5640 = data;
queue_delayed_work(system_long_wq, &rt5640->jack_work,
msecs_to_jiffies(JACK_SETTLE_TIME));
return IRQ_HANDLED;
}
......@@ -2399,7 +2413,7 @@ static void rt5640_cancel_work(void *data)
{
struct rt5640_priv *rt5640 = data;
cancel_work_sync(&rt5640->jack_work);
cancel_delayed_work_sync(&rt5640->jack_work);
cancel_delayed_work_sync(&rt5640->bp_work);
}
......@@ -2439,7 +2453,12 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
if (!rt5640->jack)
return;
free_irq(rt5640->irq, rt5640);
if (rt5640->jd_gpio_irq_requested)
free_irq(rt5640->jd_gpio_irq, rt5640);
if (rt5640->irq_requested)
free_irq(rt5640->irq, rt5640);
rt5640_cancel_work(rt5640);
if (rt5640->jack->status & SND_JACK_MICROPHONE) {
......@@ -2448,11 +2467,15 @@ static void rt5640_disable_jack_detect(struct snd_soc_component *component)
snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0);
}
rt5640->jd_gpio_irq_requested = false;
rt5640->irq_requested = false;
rt5640->jd_gpio = NULL;
rt5640->jack = NULL;
}
static void rt5640_enable_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack)
struct snd_soc_jack *jack,
struct rt5640_set_jack_data *jack_data)
{
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
int ret;
......@@ -2496,19 +2519,37 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component,
rt5640_enable_micbias1_ovcd_irq(component);
}
if (jack_data && jack_data->codec_irq_override)
rt5640->irq = jack_data->codec_irq_override;
if (jack_data && jack_data->jd_gpio) {
rt5640->jd_gpio = jack_data->jd_gpio;
rt5640->jd_gpio_irq = gpiod_to_irq(rt5640->jd_gpio);
ret = request_irq(rt5640->jd_gpio_irq, rt5640_jd_gpio_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"rt5640-jd-gpio", rt5640);
if (ret) {
dev_warn(component->dev, "Failed to request jd GPIO IRQ %d: %d\n",
rt5640->jd_gpio_irq, ret);
rt5640_disable_jack_detect(component);
return;
}
rt5640->jd_gpio_irq_requested = true;
}
ret = request_irq(rt5640->irq, rt5640_irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"rt5640", rt5640);
if (ret) {
dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret);
rt5640->irq = -ENXIO;
/* Undo above settings */
rt5640_disable_jack_detect(component);
return;
}
rt5640->irq_requested = true;
/* sync initial jack state */
queue_work(system_long_wq, &rt5640->jack_work);
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
}
static void rt5640_enable_hda_jack_detect(
......@@ -2546,7 +2587,7 @@ static void rt5640_enable_hda_jack_detect(
}
/* sync initial jack state */
queue_work(system_long_wq, &rt5640->jack_work);
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
}
static int rt5640_set_jack(struct snd_soc_component *component,
......@@ -2558,7 +2599,7 @@ static int rt5640_set_jack(struct snd_soc_component *component,
if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)
rt5640_enable_hda_jack_detect(component, jack);
else
rt5640_enable_jack_detect(component, jack);
rt5640_enable_jack_detect(component, jack, data);
} else {
rt5640_disable_jack_detect(component);
}
......@@ -2737,7 +2778,7 @@ static int rt5640_resume(struct snd_soc_component *component)
regcache_cache_only(rt5640->regmap, false);
regcache_sync(rt5640->regmap);
if (rt5640->jd_src) {
if (rt5640->jack) {
if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER)
snd_soc_component_update_bits(component,
RT5640_DUMMY2, 0x1100, 0x1100);
......@@ -2745,7 +2786,7 @@ static int rt5640_resume(struct snd_soc_component *component)
snd_soc_component_write(component, RT5640_DUMMY2,
0x4001);
queue_work(system_long_wq, &rt5640->jack_work);
queue_delayed_work(system_long_wq, &rt5640->jack_work, 0);
}
return 0;
......@@ -2950,7 +2991,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
rt5640->hp_mute = true;
rt5640->irq = i2c->irq;
INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work);
INIT_WORK(&rt5640->jack_work, rt5640_jack_work);
INIT_DELAYED_WORK(&rt5640->jack_work, rt5640_jack_work);
/* Make sure work is stopped on probe-error / remove */
ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
......
......@@ -2124,6 +2124,7 @@ struct rt5640_priv {
int ldo1_en; /* GPIO for LDO1_EN */
int irq;
int jd_gpio_irq;
int sysclk;
int sysclk_src;
int lrck[RT5640_AIFS];
......@@ -2136,6 +2137,8 @@ struct rt5640_priv {
bool hp_mute;
bool asrc_en;
bool irq_requested;
bool jd_gpio_irq_requested;
/* Jack and button detect data */
bool ovcd_irq_enabled;
......@@ -2145,14 +2148,20 @@ struct rt5640_priv {
int release_count;
int poll_count;
struct delayed_work bp_work;
struct work_struct jack_work;
struct delayed_work jack_work;
struct snd_soc_jack *jack;
struct gpio_desc *jd_gpio;
unsigned int jd_src;
bool jd_inverted;
unsigned int ovcd_th;
unsigned int ovcd_sf;
};
struct rt5640_set_jack_data {
int codec_irq_override;
struct gpio_desc *jd_gpio;
};
int rt5640_dmic_enable(struct snd_soc_component *component,
bool dmic1_data_pin, bool dmic2_data_pin);
int rt5640_sel_asrc_clk_src(struct snd_soc_component *component,
......
......@@ -341,7 +341,7 @@ struct wcd9335_codec {
int reset_gpio;
struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
unsigned int rx_port_value;
unsigned int rx_port_value[WCD9335_RX_MAX];
unsigned int tx_port_value;
int hph_l_gain;
int hph_r_gain;
......@@ -1269,10 +1269,11 @@ static const struct snd_kcontrol_new sb_tx8_mux =
static int slim_rx_mux_get(struct snd_kcontrol *kc,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc);
struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev);
struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc);
struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev);
u32 port_id = w->shift;
ucontrol->value.enumerated.item[0] = wcd->rx_port_value;
ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id];
return 0;
}
......@@ -1286,9 +1287,9 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc,
struct snd_soc_dapm_update *update = NULL;
u32 port_id = w->shift;
wcd->rx_port_value = ucontrol->value.enumerated.item[0];
wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
switch (wcd->rx_port_value) {
switch (wcd->rx_port_value[port_id]) {
case 0:
list_del_init(&wcd->rx_chs[port_id].list);
break;
......@@ -1309,11 +1310,11 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc,
&wcd->dai[AIF4_PB].slim_ch_list);
break;
default:
dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value);
dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value[port_id]);
goto err;
}
snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value,
snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id],
e, update);
return 0;
......
......@@ -896,11 +896,12 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
struct wm_adsp *dsp = &dsps[mc->shift - 1];
char preload[32];
snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
if (dsp->preloaded == ucontrol->value.integer.value[0])
return 0;
dsp->preloaded = ucontrol->value.integer.value[0];
snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
if (ucontrol->value.integer.value[0])
if (ucontrol->value.integer.value[0] || dsp->toggle_preload)
snd_soc_component_force_enable_pin(component, preload);
else
snd_soc_component_disable_pin(component, preload);
......@@ -909,6 +910,13 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
flush_work(&dsp->boot_work);
dsp->preloaded = ucontrol->value.integer.value[0];
if (dsp->toggle_preload) {
snd_soc_component_disable_pin(component, preload);
snd_soc_dapm_sync(dapm);
}
return 0;
}
EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
......
......@@ -41,6 +41,14 @@ struct wm_adsp {
struct list_head compr_list;
struct list_head buffer_list;
/*
* Flag indicating the preloader widget only needs power toggled
* on state change rather than held on for the duration of the
* preload, useful for devices that can retain firmware memory
* across power down.
*/
bool toggle_preload;
};
#define WM_ADSP1(wname, num) \
......
......@@ -19,6 +19,7 @@
#include "fsl_asrc.h"
#define IDEAL_RATIO_DECIMAL_DEPTH 26
#define DIVIDER_NUM 64
#define pair_err(fmt, ...) \
dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
......@@ -101,6 +102,55 @@ static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = {
},
};
/*
* According to RM, the divider range is 1 ~ 8,
* prescaler is power of 2 from 1 ~ 128.
*/
static int asrc_clk_divider[DIVIDER_NUM] = {
1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */
2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */
3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */
4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */
5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */
6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */
7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */
8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */
};
/*
* Check if the divider is available for internal ratio mode
*/
static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div)
{
u32 rem, i;
u64 n;
if (div)
*div = 0;
if (clk_rate == 0 || rate == 0)
return false;
n = clk_rate;
rem = do_div(n, rate);
if (div)
*div = n;
if (rem != 0)
return false;
for (i = 0; i < DIVIDER_NUM; i++) {
if (n == asrc_clk_divider[i])
break;
}
if (i == DIVIDER_NUM)
return false;
return true;
}
/**
* fsl_asrc_sel_proc - Select the pre-processing and post-processing options
* @inrate: input sample rate
......@@ -330,12 +380,12 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
enum asrc_word_width input_word_width;
enum asrc_word_width output_word_width;
u32 inrate, outrate, indiv, outdiv;
u32 clk_index[2], div[2], rem[2];
u32 clk_index[2], div[2];
u64 clk_rate;
int in, out, channels;
int pre_proc, post_proc;
struct clk *clk;
bool ideal;
bool ideal, div_avail;
if (!config) {
pair_err("invalid pair config\n");
......@@ -415,8 +465,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
clk_rate = clk_get_rate(clk);
rem[IN] = do_div(clk_rate, inrate);
div[IN] = (u32)clk_rate;
div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]);
/*
* The divider range is [1, 1024], defined by the hardware. For non-
......@@ -425,7 +474,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
* only result in different converting speeds. So remainder does not
* matter, as long as we keep the divider within its valid range.
*/
if (div[IN] == 0 || (!ideal && (div[IN] > 1024 || rem[IN] != 0))) {
if (div[IN] == 0 || (!ideal && !div_avail)) {
pair_err("failed to support input sample rate %dHz by asrck_%x\n",
inrate, clk_index[ideal ? OUT : IN]);
return -EINVAL;
......@@ -436,13 +485,12 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)
clk = asrc_priv->asrck_clk[clk_index[OUT]];
clk_rate = clk_get_rate(clk);
if (ideal && use_ideal_rate)
rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE);
div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]);
else
rem[OUT] = do_div(clk_rate, outrate);
div[OUT] = clk_rate;
div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]);
/* Output divider has the same limitation as the input one */
if (div[OUT] == 0 || (!ideal && (div[OUT] > 1024 || rem[OUT] != 0))) {
if (div[OUT] == 0 || (!ideal && !div_avail)) {
pair_err("failed to support output sample rate %dHz by asrck_%x\n",
outrate, clk_index[OUT]);
return -EINVAL;
......@@ -621,8 +669,7 @@ static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
clk_index = asrc_priv->clk_map[j][i];
clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]);
/* Only match a perfect clock source with no remainder */
if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
(clk_rate % rate[j]) == 0)
if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL))
break;
}
......
......@@ -120,7 +120,7 @@ struct imx_card_data {
static struct imx_akcodec_fs_mul ak4458_fs_mul[] = {
/* Normal, < 32kHz */
{ .rmin = 8000, .rmax = 24000, .wmin = 1024, .wmax = 1024, },
{ .rmin = 8000, .rmax = 24000, .wmin = 256, .wmax = 1024, },
/* Normal, 32kHz */
{ .rmin = 32000, .rmax = 32000, .wmin = 256, .wmax = 1024, },
/* Normal */
......@@ -151,8 +151,8 @@ static struct imx_akcodec_fs_mul ak4497_fs_mul[] = {
* Table 7 - mapping multiplier and speed mode
* Tables 8 & 9 - mapping speed mode and LRCK fs
*/
{ .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, }, /* Normal, <= 32kHz */
{ .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, }, /* Normal */
{ .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1024, }, /* Normal, <= 32kHz */
{ .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 512, }, /* Normal */
{ .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, }, /* Double */
{ .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, }, /* Quad */
{ .rmin = 352800, .rmax = 384000, .wmin = 128, .wmax = 128, }, /* Oct */
......@@ -164,7 +164,7 @@ static struct imx_akcodec_fs_mul ak4497_fs_mul[] = {
* (Table 4 from datasheet)
*/
static struct imx_akcodec_fs_mul ak5558_fs_mul[] = {
{ .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, },
{ .rmin = 8000, .rmax = 32000, .wmin = 512, .wmax = 1024, },
{ .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, },
{ .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, },
{ .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, },
......@@ -247,13 +247,14 @@ static bool codec_is_akcodec(unsigned int type)
}
static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
struct snd_pcm_hw_params *params,
int slots, int slot_width)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card);
const struct imx_card_plat_data *plat_data = data->plat_data;
struct dai_link_data *link_data = &data->link_data[rtd->num];
unsigned int width = link_data->slots * link_data->slot_width;
unsigned int width = slots * slot_width;
unsigned int rate = params_rate(params);
int i;
......@@ -349,7 +350,7 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream,
/* Set MCLK freq */
if (codec_is_akcodec(plat_data->type))
mclk_freq = akcodec_get_mclk_rate(substream, params);
mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width);
else
mclk_freq = params_rate(params) * slots * slot_width;
/* Use the maximum freq from DSD512 (512*44100 = 22579200) */
......@@ -553,8 +554,23 @@ static int imx_card_parse_of(struct imx_card_data *data)
link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1;
/* sai may support mclk/bclk = 1 */
if (of_find_property(np, "fsl,mclk-equal-bclk", NULL))
if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) {
link_data->one2one_ratio = true;
} else {
int i;
/*
* i.MX8MQ don't support one2one ratio, then
* with ak4497 only 16bit case is supported.
*/
for (i = 0; i < ARRAY_SIZE(ak4497_fs_mul); i++) {
if (ak4497_fs_mul[i].rmin == 705600 &&
ak4497_fs_mul[i].rmax == 768000) {
ak4497_fs_mul[i].wmin = 32;
ak4497_fs_mul[i].wmax = 32;
}
}
}
}
link->cpus->of_node = args.np;
......
......@@ -40,6 +40,8 @@ enum {
BYT_RT5640_NO_INTERNAL_MIC_MAP,
};
#define RT5640_JD_SRC_EXT_GPIO 0x0f
enum {
BYT_RT5640_JD_SRC_GPIO1 = (RT5640_JD_SRC_GPIO1 << 4),
BYT_RT5640_JD_SRC_JD1_IN4P = (RT5640_JD_SRC_JD1_IN4P << 4),
......@@ -47,6 +49,7 @@ enum {
BYT_RT5640_JD_SRC_GPIO2 = (RT5640_JD_SRC_GPIO2 << 4),
BYT_RT5640_JD_SRC_GPIO3 = (RT5640_JD_SRC_GPIO3 << 4),
BYT_RT5640_JD_SRC_GPIO4 = (RT5640_JD_SRC_GPIO4 << 4),
BYT_RT5640_JD_SRC_EXT_GPIO = (RT5640_JD_SRC_EXT_GPIO << 4)
};
enum {
......@@ -79,6 +82,7 @@ enum {
#define BYT_RT5640_LINEOUT_AS_HP2 BIT(26)
#define BYT_RT5640_HSMIC2_ON_IN1 BIT(27)
#define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28)
#define BYT_RT5640_USE_AMCR0F28 BIT(29)
#define BYTCR_INPUT_DEFAULTS \
(BYT_RT5640_IN3_MAP | \
......@@ -93,6 +97,7 @@ enum {
struct byt_rt5640_private {
struct snd_soc_jack jack;
struct snd_soc_jack jack2;
struct rt5640_set_jack_data jack_data;
struct gpio_desc *hsmic_detect;
struct clk *mclk;
struct device *codec_dev;
......@@ -597,7 +602,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_OVCD_TH_2000UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
BYT_RT5640_MCLK_EN |
BYT_RT5640_USE_AMCR0F28),
},
{
.matches = {
......@@ -624,6 +630,19 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF2 |
BYT_RT5640_MCLK_EN),
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
},
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_JD_SRC_EXT_GPIO |
BYT_RT5640_OVCD_TH_2000UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN |
BYT_RT5640_USE_AMCR0F28),
},
{ /* Chuwi Vi8 (CWI506) */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
......@@ -1080,9 +1099,11 @@ static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
}
if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
props[cnt++] = PROPERTY_ENTRY_U32(
"realtek,jack-detect-source",
BYT_RT5640_JDSRC(byt_rt5640_quirk));
if (BYT_RT5640_JDSRC(byt_rt5640_quirk) != RT5640_JD_SRC_EXT_GPIO) {
props[cnt++] = PROPERTY_ENTRY_U32(
"realtek,jack-detect-source",
BYT_RT5640_JDSRC(byt_rt5640_quirk));
}
props[cnt++] = PROPERTY_ENTRY_U32(
"realtek,over-current-threshold-microamp",
......@@ -1109,6 +1130,51 @@ static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
return ret;
}
/* Some Android devs specify IRQs/GPIOS in a special AMCR0F28 ACPI device */
static const struct acpi_gpio_params amcr0f28_jd_gpio = { 1, 0, false };
static const struct acpi_gpio_mapping amcr0f28_gpios[] = {
{ "rt5640-jd-gpios", &amcr0f28_jd_gpio, 1 },
{ }
};
static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card)
{
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
struct rt5640_set_jack_data *data = &priv->jack_data;
struct acpi_device *adev;
int ret = 0;
adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1);
if (!adev) {
dev_err(card->dev, "error cannot find AMCR0F28 adev\n");
return -ENOENT;
}
data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0);
if (data->codec_irq_override < 0) {
ret = data->codec_irq_override;
dev_err(card->dev, "error %d getting codec IRQ\n", ret);
goto put_adev;
}
if (BYT_RT5640_JDSRC(byt_rt5640_quirk) == RT5640_JD_SRC_EXT_GPIO) {
acpi_dev_add_driver_gpios(adev, amcr0f28_gpios);
data->jd_gpio = devm_fwnode_gpiod_get(card->dev, acpi_fwnode_handle(adev),
"rt5640-jd", GPIOD_IN, "rt5640-jd");
acpi_dev_remove_driver_gpios(adev);
if (IS_ERR(data->jd_gpio)) {
ret = PTR_ERR(data->jd_gpio);
dev_err(card->dev, "error %d getting jd GPIO\n", ret);
}
}
put_adev:
acpi_dev_put(adev);
return ret;
}
static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
{
struct snd_soc_card *card = runtime->card;
......@@ -1244,7 +1310,14 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
}
snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
KEY_PLAYPAUSE);
snd_soc_component_set_jack(component, &priv->jack, NULL);
if (byt_rt5640_quirk & BYT_RT5640_USE_AMCR0F28) {
ret = byt_rt5640_get_amcr0f28_settings(card);
if (ret)
return ret;
}
snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data);
}
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
......@@ -1448,7 +1521,8 @@ static int byt_rt5640_resume(struct snd_soc_card *card)
for_each_card_components(card, component) {
if (!strcmp(component->name, byt_rt5640_codec_name)) {
dev_dbg(component->dev, "re-enabling jack detect after resume\n");
snd_soc_component_set_jack(component, &priv->jack, NULL);
snd_soc_component_set_jack(component, &priv->jack,
&priv->jack_data);
break;
}
}
......
......@@ -56,7 +56,7 @@ struct soc_tplg {
const struct firmware *fw;
/* runtime FW parsing */
const u8 *pos; /* read postion */
const u8 *pos; /* read position */
const u8 *hdr_pos; /* header position */
unsigned int pass; /* pass number */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment