Commit e5879d98 authored by Mark Brown's avatar Mark Brown

Merge branch 'for-5.10' of...

Merge branch 'for-5.10' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-5.11
parents 645be01d f9d8ae0b
...@@ -8,10 +8,16 @@ Required properties: ...@@ -8,10 +8,16 @@ Required properties:
- reg : The I2C address of the device. - reg : The I2C address of the device.
Optional properties:
- realtek,power-up-delay-ms
Set a delay time for flush work to be completed,
this value is adjustable depending on platform.
Example: Example:
rt1015: codec@28 { rt1015: codec@28 {
compatible = "realtek,rt1015"; compatible = "realtek,rt1015";
reg = <0x28>; reg = <0x28>;
realtek,power-up-delay-ms = <50>;
}; };
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/sound/rt1015.h -- Platform data for RT1015
*
* Copyright 2020 Realtek Microelectronics
*/
#ifndef __LINUX_SND_RT1015_H
#define __LINUX_SND_RT1015_H
struct rt1015_platform_data {
unsigned int power_up_delay_ms;
};
#endif
...@@ -232,6 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci, ...@@ -232,6 +232,7 @@ static int snd_acp3x_probe(struct pci_dev *pci,
break; break;
default: default:
dev_info(&pci->dev, "ACP audio mode : %d\n", val); dev_info(&pci->dev, "ACP audio mode : %d\n", val);
break;
} }
pm_runtime_set_autosuspend_delay(&pci->dev, 2000); pm_runtime_set_autosuspend_delay(&pci->dev, 2000);
pm_runtime_use_autosuspend(&pci->dev); pm_runtime_use_autosuspend(&pci->dev);
......
...@@ -224,7 +224,7 @@ static int snd_rn_acp_probe(struct pci_dev *pci, ...@@ -224,7 +224,7 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
handle = ACPI_HANDLE(&pci->dev); handle = ACPI_HANDLE(&pci->dev);
ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
if (ACPI_FAILURE(ret)) { if (ACPI_FAILURE(ret)) {
ret = -EINVAL; ret = -ENODEV;
goto de_init; goto de_init;
} }
if (!dmic_status) { if (!dmic_status) {
......
...@@ -487,7 +487,6 @@ static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream, ...@@ -487,7 +487,6 @@ static int mchp_spdiftx_hw_params(struct snd_pcm_substream *substream,
} }
mchp_spdiftx_channel_status_write(dev); mchp_spdiftx_channel_status_write(dev);
spin_unlock_irqrestore(&ctrl->lock, flags); spin_unlock_irqrestore(&ctrl->lock, flags);
mr |= SPDIFTX_MR_VALID1 | SPDIFTX_MR_VALID2;
if (dev->gclk_enabled) { if (dev->gclk_enabled) {
clk_disable_unprepare(dev->gclk); clk_disable_unprepare(dev->gclk);
......
...@@ -27,10 +27,15 @@ ...@@ -27,10 +27,15 @@
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include <sound/rt1015.h>
#include "rl6231.h" #include "rl6231.h"
#include "rt1015.h" #include "rt1015.h"
static const struct rt1015_platform_data i2s_default_platform_data = {
.power_up_delay_ms = 50,
};
static const struct reg_default rt1015_reg[] = { static const struct reg_default rt1015_reg[] = {
{ 0x0000, 0x0000 }, { 0x0000, 0x0000 },
{ 0x0004, 0xa000 }, { 0x0004, 0xa000 },
...@@ -561,7 +566,7 @@ static void rt1015_flush_work(struct work_struct *work) ...@@ -561,7 +566,7 @@ static void rt1015_flush_work(struct work_struct *work)
struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv, struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv,
flush_work.work); flush_work.work);
struct snd_soc_component *component = rt1015->component; struct snd_soc_component *component = rt1015->component;
unsigned int val, i = 0, count = 20; unsigned int val, i = 0, count = 200;
while (i < count) { while (i < count) {
usleep_range(1000, 1500); usleep_range(1000, 1500);
...@@ -684,6 +689,7 @@ static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w, ...@@ -684,6 +689,7 @@ static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
if (rt1015->hw_config == RT1015_HW_28) if (rt1015->hw_config == RT1015_HW_28)
schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10)); schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10));
msleep(rt1015->pdata.power_up_delay_ms);
break; break;
default: default:
break; break;
...@@ -1163,9 +1169,16 @@ static struct acpi_device_id rt1015_acpi_match[] = { ...@@ -1163,9 +1169,16 @@ static struct acpi_device_id rt1015_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt1015_acpi_match); MODULE_DEVICE_TABLE(acpi, rt1015_acpi_match);
#endif #endif
static void rt1015_parse_dt(struct rt1015_priv *rt1015, struct device *dev)
{
device_property_read_u32(dev, "realtek,power-up-delay-ms",
&rt1015->pdata.power_up_delay_ms);
}
static int rt1015_i2c_probe(struct i2c_client *i2c, static int rt1015_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct rt1015_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct rt1015_priv *rt1015; struct rt1015_priv *rt1015;
int ret; int ret;
unsigned int val; unsigned int val;
...@@ -1177,6 +1190,13 @@ static int rt1015_i2c_probe(struct i2c_client *i2c, ...@@ -1177,6 +1190,13 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, rt1015); i2c_set_clientdata(i2c, rt1015);
rt1015->pdata = i2s_default_platform_data;
if (pdata)
rt1015->pdata = *pdata;
else
rt1015_parse_dt(rt1015, &i2c->dev);
rt1015->regmap = devm_regmap_init_i2c(i2c, &rt1015_regmap); rt1015->regmap = devm_regmap_init_i2c(i2c, &rt1015_regmap);
if (IS_ERR(rt1015->regmap)) { if (IS_ERR(rt1015->regmap)) {
ret = PTR_ERR(rt1015->regmap); ret = PTR_ERR(rt1015->regmap);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#ifndef __RT1015_H__ #ifndef __RT1015_H__
#define __RT1015_H__ #define __RT1015_H__
#include <sound/rt1015.h>
#define RT1015_DEVICE_ID_VAL 0x1011 #define RT1015_DEVICE_ID_VAL 0x1011
#define RT1015_DEVICE_ID_VAL2 0x1015 #define RT1015_DEVICE_ID_VAL2 0x1015
...@@ -422,6 +423,7 @@ enum { ...@@ -422,6 +423,7 @@ enum {
struct rt1015_priv { struct rt1015_priv {
struct snd_soc_component *component; struct snd_soc_component *component;
struct rt1015_platform_data pdata;
struct regmap *regmap; struct regmap *regmap;
int sysclk; int sysclk;
int sysclk_src; int sysclk_src;
......
...@@ -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)
......
...@@ -618,7 +618,7 @@ static const char * const sb_tx8_mux_text[] = { ...@@ -618,7 +618,7 @@ static const char * const sb_tx8_mux_text[] = {
"ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
}; };
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0); static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0);
......
...@@ -551,7 +551,7 @@ struct wcd_iir_filter_ctl { ...@@ -551,7 +551,7 @@ struct wcd_iir_filter_ctl {
struct soc_bytes_ext bytes_ext; struct soc_bytes_ext bytes_ext;
}; };
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0); static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0);
......
...@@ -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"),
......
...@@ -700,6 +700,8 @@ static int kabylake_set_bias_level(struct snd_soc_card *card, ...@@ -700,6 +700,8 @@ static int kabylake_set_bias_level(struct snd_soc_card *card,
switch (level) { switch (level) {
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (dapm->bias_level == SND_SOC_BIAS_ON) { if (dapm->bias_level == SND_SOC_BIAS_ON) {
if (!__clk_is_enabled(priv->mclk))
return 0;
dev_dbg(card->dev, "Disable mclk"); dev_dbg(card->dev, "Disable mclk");
clk_disable_unprepare(priv->mclk); clk_disable_unprepare(priv->mclk);
} else { } else {
......
...@@ -487,9 +487,9 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -487,9 +487,9 @@ static int kmb_dai_hw_params(struct snd_pcm_substream *substream,
kmb_i2s->xfer_resolution = 0x02; kmb_i2s->xfer_resolution = 0x02;
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case SNDRV_PCM_FORMAT_S24_LE:
config->data_width = 24; config->data_width = 32;
kmb_i2s->ccr = 0x08; kmb_i2s->ccr = 0x14;
kmb_i2s->xfer_resolution = 0x04; kmb_i2s->xfer_resolution = 0x05;
break; break;
case SNDRV_PCM_FORMAT_S32_LE: case SNDRV_PCM_FORMAT_S32_LE:
config->data_width = 32; config->data_width = 32;
......
...@@ -808,7 +808,7 @@ static ssize_t mtk_btcvsd_snd_write(struct mtk_btcvsd_snd *bt, ...@@ -808,7 +808,7 @@ static ssize_t mtk_btcvsd_snd_write(struct mtk_btcvsd_snd *bt,
spin_unlock_irqrestore(&bt->tx_lock, flags); spin_unlock_irqrestore(&bt->tx_lock, flags);
if (!avail) { if (!avail) {
int ret = wait_for_bt_irq(bt, bt->rx); int ret = wait_for_bt_irq(bt, bt->tx);
if (ret) if (ret)
return written_size; return written_size;
......
...@@ -80,6 +80,12 @@ static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream, ...@@ -80,6 +80,12 @@ static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret); dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret);
return ret; return ret;
} }
ret = clk_prepare(drvdata->mi2s_bit_clk[dai->driver->id]);
if (ret) {
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
return ret;
}
return 0; return 0;
} }
...@@ -88,9 +94,8 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, ...@@ -88,9 +94,8 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
{ {
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
clk_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
} }
static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
...@@ -258,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, ...@@ -258,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)
{ {
...@@ -287,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -287,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:
...@@ -303,11 +298,14 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -303,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_prepare_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_unprepare(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;
...@@ -324,6 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -324,6 +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);
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;
} }
...@@ -335,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { ...@@ -335,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);
...@@ -453,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) ...@@ -453,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;
...@@ -855,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) ...@@ -855,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;
...@@ -122,8 +123,10 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, ...@@ -122,8 +123,10 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
else else
dma_ch = 0; dma_ch = 0;
if (dma_ch < 0) if (dma_ch < 0) {
kfree(data);
return dma_ch; return dma_ch;
}
if (cpu_dai->driver->id == LPASS_DP_RX) { if (cpu_dai->driver->id == LPASS_DP_RX) {
map = drvdata->hdmiif_map; map = drvdata->hdmiif_map;
...@@ -147,6 +150,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, ...@@ -147,6 +150,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
ret = snd_pcm_hw_constraint_integer(runtime, ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS); SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0) { if (ret < 0) {
kfree(data);
dev_err(soc_runtime->dev, "setting constraints failed: %d\n", dev_err(soc_runtime->dev, "setting constraints failed: %d\n",
ret); ret);
return -EINVAL; return -EINVAL;
...@@ -448,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component, ...@@ -448,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:
......
...@@ -189,7 +189,7 @@ static struct lpass_variant sc7180_data = { ...@@ -189,7 +189,7 @@ static struct lpass_variant sc7180_data = {
.micmode = REG_FIELD_ID(0x1000, 4, 8, 3, 0x1000), .micmode = REG_FIELD_ID(0x1000, 4, 8, 3, 0x1000),
.micmono = REG_FIELD_ID(0x1000, 3, 3, 3, 0x1000), .micmono = REG_FIELD_ID(0x1000, 3, 3, 3, 0x1000),
.wssrc = REG_FIELD_ID(0x1000, 2, 2, 3, 0x1000), .wssrc = REG_FIELD_ID(0x1000, 2, 2, 3, 0x1000),
.bitwidth = REG_FIELD_ID(0x1000, 0, 0, 3, 0x1000), .bitwidth = REG_FIELD_ID(0x1000, 0, 1, 3, 0x1000),
.rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000), .rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000),
.rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000), .rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000),
......
...@@ -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