Commit 5ef5bee0 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v5.10-rc5' of...

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

ASoC: Fixes for v5.10

A small set of driver specific fixes, plus a new platform quirk from
Hans.
parents 402d5840 aa4cb898
...@@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = { ...@@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = {
{RT5682_DAC_ADC_DIG_VOL1, 0xa020}, {RT5682_DAC_ADC_DIG_VOL1, 0xa020},
{RT5682_I2C_CTRL, 0x000f}, {RT5682_I2C_CTRL, 0x000f},
{RT5682_PLL2_INTERNAL, 0x8266}, {RT5682_PLL2_INTERNAL, 0x8266},
{RT5682_SAR_IL_CMD_3, 0x8365},
}; };
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev) void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
......
...@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) ...@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
mem = wm_adsp_find_region(dsp, type); mem = wm_adsp_find_region(dsp, type);
if (!mem) { if (!mem) {
adsp_err(dsp, "No region of type: %x\n", type); adsp_err(dsp, "No region of type: %x\n", type);
ret = -EINVAL;
goto out_fw; goto out_fw;
} }
......
...@@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
.driver_data = (void *)(BYT_RT5640_IN1_MAP | .driver_data = (void *)(BYT_RT5640_IN1_MAP |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ /* HP Pavilion x2 10-n000nd */ { /* HP Pavilion x2 10-k0XX, 10-n0XX */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
}, },
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP | .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_JD_SRC_JD2_IN4N | BYT_RT5640_JD_SRC_JD2_IN4N |
...@@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF1 | BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{ /* HP Pavilion x2 10-p0XX */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
},
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
BYT_RT5640_JD_SRC_JD1_IN4P |
BYT_RT5640_OVCD_TH_1500UA |
BYT_RT5640_OVCD_SF_0P75 |
BYT_RT5640_MCLK_EN),
},
{ /* HP Stream 7 */ { /* HP Stream 7 */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
......
...@@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, ...@@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id;
int ret;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = regmap_fields_write(i2sctl->spken, id,
LPAIF_I2SCTL_SPKEN_ENABLE);
} else {
ret = regmap_fields_write(i2sctl->micen, id,
LPAIF_I2SCTL_MICEN_ENABLE);
}
if (ret)
dev_err(dai->dev, "error writing to i2sctl enable: %d\n", ret);
return ret;
}
static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai) int cmd, struct snd_soc_dai *dai)
{ {
...@@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
unsigned int id = dai->driver->id; unsigned int id = dai->driver->id;
int ret = -EINVAL; int ret = -EINVAL;
unsigned int val = 0;
ret = regmap_read(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
if (ret) {
dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
return ret;
}
if (val == LPAIF_I2SCTL_RESET_STATE) {
dev_err(dai->dev, "error in i2sctl register state\n");
return -ENOTRECOVERABLE;
}
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
...@@ -308,11 +298,14 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -308,11 +298,14 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
dev_err(dai->dev, "error writing to i2sctl reg: %d\n", dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret); ret);
ret = clk_enable(drvdata->mi2s_bit_clk[id]); if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) {
if (ret) { ret = clk_enable(drvdata->mi2s_bit_clk[id]);
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret); if (ret) {
clk_disable(drvdata->mi2s_osr_clk[id]); dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
return ret; clk_disable(drvdata->mi2s_osr_clk[id]);
return ret;
}
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE;
} }
break; break;
...@@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
if (ret) if (ret)
dev_err(dai->dev, "error writing to i2sctl reg: %d\n", dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret); ret);
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]); if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) {
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE;
}
break; break;
} }
...@@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { ...@@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
.startup = lpass_cpu_daiops_startup, .startup = lpass_cpu_daiops_startup,
.shutdown = lpass_cpu_daiops_shutdown, .shutdown = lpass_cpu_daiops_shutdown,
.hw_params = lpass_cpu_daiops_hw_params, .hw_params = lpass_cpu_daiops_hw_params,
.prepare = lpass_cpu_daiops_prepare,
.trigger = lpass_cpu_daiops_trigger, .trigger = lpass_cpu_daiops_trigger,
}; };
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops); EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
...@@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) ...@@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
struct lpass_variant *v = drvdata->variant; struct lpass_variant *v = drvdata->variant;
int i; int i;
for (i = 0; i < v->i2s_ports; ++i)
if (reg == LPAIF_I2SCTL_REG(v, i))
return true;
for (i = 0; i < v->irq_ports; ++i) for (i = 0; i < v->irq_ports; ++i)
if (reg == LPAIF_IRQSTAT_REG(v, i)) if (reg == LPAIF_IRQSTAT_REG(v, i))
return true; return true;
for (i = 0; i < v->rdma_channels; ++i) for (i = 0; i < v->rdma_channels; ++i)
if (reg == LPAIF_RDMACURR_REG(v, i)) if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
return true; return true;
for (i = 0; i < v->wrdma_channels; ++i) for (i = 0; i < v->wrdma_channels; ++i)
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start)) if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
return true; return true;
return false; return false;
...@@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) ...@@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
} }
drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE;
} }
/* Allocation for i2sctl regmap fields */ /* Allocation for i2sctl regmap fields */
......
...@@ -60,6 +60,13 @@ ...@@ -60,6 +60,13 @@
#define LPAIF_I2SCTL_BITWIDTH_24 1 #define LPAIF_I2SCTL_BITWIDTH_24 1
#define LPAIF_I2SCTL_BITWIDTH_32 2 #define LPAIF_I2SCTL_BITWIDTH_32 2
#define LPAIF_BIT_CLK_DISABLE 0
#define LPAIF_BIT_CLK_ENABLE 1
#define LPAIF_I2SCTL_RESET_STATE 0x003C0004
#define LPAIF_DMACTL_RESET_STATE 0x00200000
/* LPAIF IRQ */ /* LPAIF IRQ */
#define LPAIF_IRQ_REG_ADDR(v, addr, port) \ #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
(v->irq_reg_base + (addr) + v->irq_reg_stride * (port)) (v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
......
...@@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, ...@@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
struct regmap *map; struct regmap *map;
unsigned int dai_id = cpu_dai->driver->id; unsigned int dai_id = cpu_dai->driver->id;
component->id = dai_id;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
...@@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component, ...@@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
unsigned int reg_irqclr = 0, val_irqclr = 0; unsigned int reg_irqclr = 0, val_irqclr = 0;
unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0; unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
unsigned int dai_id = cpu_dai->driver->id; unsigned int dai_id = cpu_dai->driver->id;
unsigned int dma_ctrl_reg = 0;
ch = pcm_data->dma_ch; ch = pcm_data->dma_ch;
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
id = pcm_data->dma_ch; id = pcm_data->dma_ch;
if (dai_id == LPASS_DP_RX) if (dai_id == LPASS_DP_RX) {
dmactl = drvdata->hdmi_rd_dmactl; dmactl = drvdata->hdmi_rd_dmactl;
else map = drvdata->hdmiif_map;
} else {
dmactl = drvdata->rd_dmactl; dmactl = drvdata->rd_dmactl;
map = drvdata->lpaif_map;
}
} else { } else {
dmactl = drvdata->wr_dmactl; dmactl = drvdata->wr_dmactl;
id = pcm_data->dma_ch - v->wrdma_channel_start; id = pcm_data->dma_ch - v->wrdma_channel_start;
map = drvdata->lpaif_map;
}
ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
if (ret) {
dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
return ret;
} }
if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
dev_err(soc_runtime->dev, "error in rdmactl register state\n");
return -ENOTRECOVERABLE;
}
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
......
...@@ -68,6 +68,7 @@ struct lpass_data { ...@@ -68,6 +68,7 @@ struct lpass_data {
unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
int hdmi_port_enable; int hdmi_port_enable;
int bit_clk_state[LPASS_MAX_MI2S_PORTS];
/* low-power audio interface (LPAIF) registers */ /* low-power audio interface (LPAIF) registers */
void __iomem *lpaif; void __iomem *lpaif;
......
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