Commit f2d4c127 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/pxa' and 'asoc/topic/qcom' into asoc-next

...@@ -52,7 +52,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, ...@@ -52,7 +52,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int freq_out, sspa_mclk, sysclk; int freq_out, sspa_mclk, sysclk;
int sspa_div;
if (params_rate(params) > 11025) { if (params_rate(params) > 11025) {
freq_out = params_rate(params) * 512; freq_out = params_rate(params) * 512;
...@@ -63,7 +62,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, ...@@ -63,7 +62,6 @@ static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
sysclk = params_rate(params) * 512; sysclk = params_rate(params) * 512;
sspa_mclk = params_rate(params) * 64; sspa_mclk = params_rate(params) * 64;
} }
sspa_div = freq_out / sspa_mclk;
snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0); snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk); snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
......
...@@ -11,21 +11,24 @@ config SND_SOC_LPASS_CPU ...@@ -11,21 +11,24 @@ config SND_SOC_LPASS_CPU
config SND_SOC_LPASS_PLATFORM config SND_SOC_LPASS_PLATFORM
tristate tristate
depends on HAS_DMA
select REGMAP_MMIO select REGMAP_MMIO
config SND_SOC_LPASS_IPQ806X config SND_SOC_LPASS_IPQ806X
tristate tristate
depends on HAS_DMA
select SND_SOC_LPASS_CPU select SND_SOC_LPASS_CPU
select SND_SOC_LPASS_PLATFORM select SND_SOC_LPASS_PLATFORM
config SND_SOC_LPASS_APQ8016 config SND_SOC_LPASS_APQ8016
tristate tristate
depends on HAS_DMA
select SND_SOC_LPASS_CPU select SND_SOC_LPASS_CPU
select SND_SOC_LPASS_PLATFORM select SND_SOC_LPASS_PLATFORM
config SND_SOC_STORM config SND_SOC_STORM
tristate "ASoC I2S support for Storm boards" tristate "ASoC I2S support for Storm boards"
depends on SND_SOC_QCOM depends on SND_SOC_QCOM && HAS_DMA
select SND_SOC_LPASS_IPQ806X select SND_SOC_LPASS_IPQ806X
select SND_SOC_MAX98357A select SND_SOC_MAX98357A
help help
...@@ -34,7 +37,7 @@ config SND_SOC_STORM ...@@ -34,7 +37,7 @@ config SND_SOC_STORM
config SND_SOC_APQ8016_SBC config SND_SOC_APQ8016_SBC
tristate "SoC Audio support for APQ8016 SBC platforms" tristate "SoC Audio support for APQ8016 SBC platforms"
depends on SND_SOC_QCOM depends on SND_SOC_QCOM && HAS_DMA
select SND_SOC_LPASS_APQ8016 select SND_SOC_LPASS_APQ8016
help help
Support for Qualcomm Technologies LPASS audio block in Support for Qualcomm Technologies LPASS audio block in
......
...@@ -30,6 +30,7 @@ struct apq8016_sbc_data { ...@@ -30,6 +30,7 @@ struct apq8016_sbc_data {
struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ struct snd_soc_dai_link dai_link[]; /* dynamically allocated */
}; };
#define MIC_CTRL_TER_WS_SLAVE_SEL BIT(21)
#define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17) #define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17)
#define MIC_CTRL_TLMM_SCLK_EN BIT(1) #define MIC_CTRL_TLMM_SCLK_EN BIT(1)
#define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16)) #define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16))
...@@ -53,6 +54,12 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) ...@@ -53,6 +54,12 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd)
MIC_CTRL_TLMM_SCLK_EN, MIC_CTRL_TLMM_SCLK_EN,
pdata->mic_iomux); pdata->mic_iomux);
break; break;
case MI2S_TERTIARY:
writel(readl(pdata->mic_iomux) | MIC_CTRL_TER_WS_SLAVE_SEL |
MIC_CTRL_TLMM_SCLK_EN,
pdata->mic_iomux);
break;
default: default:
dev_err(card->dev, "unsupported cpu dai configuration\n"); dev_err(card->dev, "unsupported cpu dai configuration\n");
...@@ -126,9 +133,6 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) ...@@ -126,9 +133,6 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
} }
link->platform_of_node = link->cpu_of_node; link->platform_of_node = link->cpu_of_node;
/* For now we only support playback */
link->playback_only = true;
ret = of_property_read_string(np, "link-name", &link->name); ret = of_property_read_string(np, "link-name", &link->name);
if (ret) { if (ret) {
dev_err(card->dev, "error getting codec dai_link name\n"); dev_err(card->dev, "error getting codec dai_link name\n");
......
...@@ -133,23 +133,36 @@ static struct snd_soc_dai_driver apq8016_lpass_cpu_dai_driver[] = { ...@@ -133,23 +133,36 @@ static struct snd_soc_dai_driver apq8016_lpass_cpu_dai_driver[] = {
}, },
}; };
static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata) static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata,
int direction)
{ {
struct lpass_variant *v = drvdata->variant; struct lpass_variant *v = drvdata->variant;
int chan = find_first_zero_bit(&drvdata->rdma_ch_bit_map, int chan = 0;
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
v->rdma_channels); v->rdma_channels);
if (chan >= v->rdma_channels) if (chan >= v->rdma_channels)
return -EBUSY; return -EBUSY;
} else {
chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
v->wrdma_channel_start +
v->wrdma_channels,
v->wrdma_channel_start);
if (chan >= v->wrdma_channel_start + v->wrdma_channels)
return -EBUSY;
}
set_bit(chan, &drvdata->rdma_ch_bit_map); set_bit(chan, &drvdata->dma_ch_bit_map);
return chan; return chan;
} }
static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan) static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
{ {
clear_bit(chan, &drvdata->rdma_ch_bit_map); clear_bit(chan, &drvdata->dma_ch_bit_map);
return 0; return 0;
} }
...@@ -212,7 +225,11 @@ static struct lpass_variant apq8016_data = { ...@@ -212,7 +225,11 @@ static struct lpass_variant apq8016_data = {
.rdma_reg_base = 0x8400, .rdma_reg_base = 0x8400,
.rdma_reg_stride = 0x1000, .rdma_reg_stride = 0x1000,
.rdma_channels = 2, .rdma_channels = 2,
.rdmactl_audif_start = 1, .dmactl_audif_start = 1,
.wrdma_reg_base = 0xB000,
.wrdma_reg_stride = 0x1000,
.wrdma_channel_start = 5,
.wrdma_channels = 2,
.dai_driver = apq8016_lpass_cpu_dai_driver, .dai_driver = apq8016_lpass_cpu_dai_driver,
.num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver), .num_dai = ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
.init = apq8016_lpass_init, .init = apq8016_lpass_init,
......
...@@ -120,6 +120,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, ...@@ -120,6 +120,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
switch (channels) { switch (channels) {
case 1: case 1:
regval |= LPAIF_I2SCTL_SPKMODE_SD0; regval |= LPAIF_I2SCTL_SPKMODE_SD0;
...@@ -146,6 +147,34 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, ...@@ -146,6 +147,34 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
__func__, channels); __func__, channels);
return -EINVAL; return -EINVAL;
} }
} else {
switch (channels) {
case 1:
regval |= LPAIF_I2SCTL_MICMODE_SD0;
regval |= LPAIF_I2SCTL_MICMONO_MONO;
break;
case 2:
regval |= LPAIF_I2SCTL_MICMODE_SD0;
regval |= LPAIF_I2SCTL_MICMONO_STEREO;
break;
case 4:
regval |= LPAIF_I2SCTL_MICMODE_QUAD01;
regval |= LPAIF_I2SCTL_MICMONO_STEREO;
break;
case 6:
regval |= LPAIF_I2SCTL_MICMODE_6CH;
regval |= LPAIF_I2SCTL_MICMONO_STEREO;
break;
case 8:
regval |= LPAIF_I2SCTL_MICMODE_8CH;
regval |= LPAIF_I2SCTL_MICMONO_STEREO;
break;
default:
dev_err(dai->dev, "%s() invalid channels given: %u\n",
__func__, channels);
return -EINVAL;
}
}
ret = regmap_write(drvdata->lpaif_map, ret = regmap_write(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
...@@ -188,10 +217,19 @@ static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream, ...@@ -188,10 +217,19 @@ static int lpass_cpu_daiops_prepare(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);
int ret; int ret;
unsigned int val, mask;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
val = LPAIF_I2SCTL_SPKEN_ENABLE;
mask = LPAIF_I2SCTL_SPKEN_MASK;
} else {
val = LPAIF_I2SCTL_MICEN_ENABLE;
mask = LPAIF_I2SCTL_MICEN_MASK;
}
ret = regmap_update_bits(drvdata->lpaif_map, ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE); mask, val);
if (ret) if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret); __func__, ret);
...@@ -204,16 +242,24 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -204,16 +242,24 @@ static int lpass_cpu_daiops_trigger(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);
int ret = -EINVAL; int ret = -EINVAL;
unsigned int val, mask;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
val = LPAIF_I2SCTL_SPKEN_ENABLE;
mask = LPAIF_I2SCTL_SPKEN_MASK;
} else {
val = LPAIF_I2SCTL_MICEN_ENABLE;
mask = LPAIF_I2SCTL_MICEN_MASK;
}
ret = regmap_update_bits(drvdata->lpaif_map, ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, LPAIF_I2SCTL_REG(drvdata->variant,
dai->driver->id), dai->driver->id),
LPAIF_I2SCTL_SPKEN_MASK, mask, val);
LPAIF_I2SCTL_SPKEN_ENABLE);
if (ret) if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret); __func__, ret);
...@@ -221,11 +267,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, ...@@ -221,11 +267,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
val = LPAIF_I2SCTL_SPKEN_DISABLE;
mask = LPAIF_I2SCTL_SPKEN_MASK;
} else {
val = LPAIF_I2SCTL_MICEN_DISABLE;
mask = LPAIF_I2SCTL_MICEN_MASK;
}
ret = regmap_update_bits(drvdata->lpaif_map, ret = regmap_update_bits(drvdata->lpaif_map,
LPAIF_I2SCTL_REG(drvdata->variant, LPAIF_I2SCTL_REG(drvdata->variant,
dai->driver->id), dai->driver->id),
LPAIF_I2SCTL_SPKEN_MASK, mask, val);
LPAIF_I2SCTL_SPKEN_DISABLE);
if (ret) if (ret)
dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
__func__, ret); __func__, ret);
...@@ -294,6 +347,17 @@ static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg) ...@@ -294,6 +347,17 @@ static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
return true; return true;
} }
for (i = 0; i < v->wrdma_channels; ++i) {
if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start))
return true;
}
return false; return false;
} }
...@@ -327,6 +391,19 @@ static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg) ...@@ -327,6 +391,19 @@ static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
return true; return true;
} }
for (i = 0; i < v->wrdma_channels; ++i) {
if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
return true;
if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start))
return true;
}
return false; return false;
} }
...@@ -344,6 +421,10 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) ...@@ -344,6 +421,10 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
if (reg == LPAIF_RDMACURR_REG(v, i)) if (reg == LPAIF_RDMACURR_REG(v, i))
return true; return true;
for (i = 0; i < v->wrdma_channels; ++i)
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
return true;
return false; return false;
} }
...@@ -398,8 +479,9 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) ...@@ -398,8 +479,9 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
return PTR_ERR((void const __force *)drvdata->lpaif); return PTR_ERR((void const __force *)drvdata->lpaif);
} }
lpass_cpu_regmap_config.max_register = LPAIF_RDMAPER_REG(variant, lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant,
variant->rdma_channels); variant->wrdma_channels +
variant->wrdma_channel_start);
drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif, drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif,
&lpass_cpu_regmap_config); &lpass_cpu_regmap_config);
......
...@@ -63,9 +63,12 @@ static struct snd_soc_dai_driver ipq806x_lpass_cpu_dai_driver = { ...@@ -63,9 +63,12 @@ static struct snd_soc_dai_driver ipq806x_lpass_cpu_dai_driver = {
.ops = &asoc_qcom_lpass_cpu_dai_ops, .ops = &asoc_qcom_lpass_cpu_dai_ops,
}; };
static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata) static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir)
{ {
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
return IPQ806X_LPAIF_RDMA_CHAN_MI2S; return IPQ806X_LPAIF_RDMA_CHAN_MI2S;
else /* Capture currently not implemented */
return -EINVAL;
} }
static int ipq806x_lpass_free_dma_channel(struct lpass_data *drvdata, int chan) static int ipq806x_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
...@@ -83,6 +86,10 @@ static struct lpass_variant ipq806x_data = { ...@@ -83,6 +86,10 @@ static struct lpass_variant ipq806x_data = {
.rdma_reg_base = 0x6000, .rdma_reg_base = 0x6000,
.rdma_reg_stride = 0x1000, .rdma_reg_stride = 0x1000,
.rdma_channels = 4, .rdma_channels = 4,
.wrdma_reg_base = 0xB000,
.wrdma_reg_stride = 0x1000,
.wrdma_channel_start = 5,
.wrdma_channels = 4,
.dai_driver = &ipq806x_lpass_cpu_dai_driver, .dai_driver = &ipq806x_lpass_cpu_dai_driver,
.num_dai = 1, .num_dai = 1,
.alloc_dma_channel = ipq806x_lpass_alloc_dma_channel, .alloc_dma_channel = ipq806x_lpass_alloc_dma_channel,
......
...@@ -47,6 +47,28 @@ ...@@ -47,6 +47,28 @@
#define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT) #define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
#define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT) #define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
#define LPAIF_I2SCTL_MICEN_MASK GENMASK(8, 8)
#define LPAIF_I2SCTL_MICEN_SHIFT 8
#define LPAIF_I2SCTL_MICEN_DISABLE (0 << LPAIF_I2SCTL_MICEN_SHIFT)
#define LPAIF_I2SCTL_MICEN_ENABLE (1 << LPAIF_I2SCTL_MICEN_SHIFT)
#define LPAIF_I2SCTL_MICMODE_MASK GENMASK(7, 4)
#define LPAIF_I2SCTL_MICMODE_SHIFT 4
#define LPAIF_I2SCTL_MICMODE_NONE (0 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_SD0 (1 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_SD1 (2 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_SD2 (3 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_SD3 (4 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_QUAD01 (5 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_QUAD23 (6 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_6CH (7 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MICMODE_8CH (8 << LPAIF_I2SCTL_MICMODE_SHIFT)
#define LPAIF_I2SCTL_MIMONO_MASK GENMASK(3, 3)
#define LPAIF_I2SCTL_MICMONO_SHIFT 3
#define LPAIF_I2SCTL_MICMONO_STEREO (0 << LPAIF_I2SCTL_MICMONO_SHIFT)
#define LPAIF_I2SCTL_MICMONO_MONO (1 << LPAIF_I2SCTL_MICMONO_SHIFT)
#define LPAIF_I2SCTL_WSSRC_MASK 0x0004 #define LPAIF_I2SCTL_WSSRC_MASK 0x0004
#define LPAIF_I2SCTL_WSSRC_SHIFT 2 #define LPAIF_I2SCTL_WSSRC_SHIFT 2
#define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT) #define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT)
...@@ -90,37 +112,65 @@ ...@@ -90,37 +112,65 @@
#define LPAIF_RDMAPER_REG(v, chan) LPAIF_RDMA_REG_ADDR(v, 0x10, (chan)) #define LPAIF_RDMAPER_REG(v, chan) LPAIF_RDMA_REG_ADDR(v, 0x10, (chan))
#define LPAIF_RDMAPERCNT_REG(v, chan) LPAIF_RDMA_REG_ADDR(v, 0x14, (chan)) #define LPAIF_RDMAPERCNT_REG(v, chan) LPAIF_RDMA_REG_ADDR(v, 0x14, (chan))
#define LPAIF_RDMACTL_BURSTEN_MASK 0x800 #define LPAIF_WRDMA_REG_ADDR(v, addr, chan) \
#define LPAIF_RDMACTL_BURSTEN_SHIFT 11 (v->wrdma_reg_base + (addr) + \
#define LPAIF_RDMACTL_BURSTEN_SINGLE (0 << LPAIF_RDMACTL_BURSTEN_SHIFT) v->wrdma_reg_stride * (chan - v->wrdma_channel_start))
#define LPAIF_RDMACTL_BURSTEN_INCR4 (1 << LPAIF_RDMACTL_BURSTEN_SHIFT)
#define LPAIF_WRDMACTL_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x00, (chan))
#define LPAIF_RDMACTL_WPSCNT_MASK 0x700 #define LPAIF_WRDMABASE_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x04, (chan))
#define LPAIF_RDMACTL_WPSCNT_SHIFT 8 #define LPAIF_WRDMABUFF_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x08, (chan))
#define LPAIF_RDMACTL_WPSCNT_ONE (0 << LPAIF_RDMACTL_WPSCNT_SHIFT) #define LPAIF_WRDMACURR_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x0C, (chan))
#define LPAIF_RDMACTL_WPSCNT_TWO (1 << LPAIF_RDMACTL_WPSCNT_SHIFT) #define LPAIF_WRDMAPER_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x10, (chan))
#define LPAIF_RDMACTL_WPSCNT_THREE (2 << LPAIF_RDMACTL_WPSCNT_SHIFT) #define LPAIF_WRDMAPERCNT_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x14, (chan))
#define LPAIF_RDMACTL_WPSCNT_FOUR (3 << LPAIF_RDMACTL_WPSCNT_SHIFT)
#define LPAIF_RDMACTL_WPSCNT_SIX (5 << LPAIF_RDMACTL_WPSCNT_SHIFT) #define __LPAIF_DMA_REG(v, chan, dir, reg) \
#define LPAIF_RDMACTL_WPSCNT_EIGHT (7 << LPAIF_RDMACTL_WPSCNT_SHIFT) (dir == SNDRV_PCM_STREAM_PLAYBACK) ? \
LPAIF_RDMA##reg##_REG(v, chan) : \
#define LPAIF_RDMACTL_AUDINTF_MASK 0x0F0 LPAIF_WRDMA##reg##_REG(v, chan)
#define LPAIF_RDMACTL_AUDINTF_SHIFT 4
#define LPAIF_DMACTL_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, CTL)
#define LPAIF_RDMACTL_FIFOWM_MASK 0x00E #define LPAIF_DMABASE_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, BASE)
#define LPAIF_RDMACTL_FIFOWM_SHIFT 1 #define LPAIF_DMABUFF_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, BUFF)
#define LPAIF_RDMACTL_FIFOWM_1 (0 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMACURR_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, CURR)
#define LPAIF_RDMACTL_FIFOWM_2 (1 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMAPER_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, PER)
#define LPAIF_RDMACTL_FIFOWM_3 (2 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMAPERCNT_REG(v, chan, dir) __LPAIF_DMA_REG(v, chan, dir, PERCNT)
#define LPAIF_RDMACTL_FIFOWM_4 (3 << LPAIF_RDMACTL_FIFOWM_SHIFT)
#define LPAIF_RDMACTL_FIFOWM_5 (4 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMACTL_BURSTEN_MASK 0x800
#define LPAIF_RDMACTL_FIFOWM_6 (5 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMACTL_BURSTEN_SHIFT 11
#define LPAIF_RDMACTL_FIFOWM_7 (6 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMACTL_BURSTEN_SINGLE (0 << LPAIF_DMACTL_BURSTEN_SHIFT)
#define LPAIF_RDMACTL_FIFOWM_8 (7 << LPAIF_RDMACTL_FIFOWM_SHIFT) #define LPAIF_DMACTL_BURSTEN_INCR4 (1 << LPAIF_DMACTL_BURSTEN_SHIFT)
#define LPAIF_RDMACTL_ENABLE_MASK 0x1 #define LPAIF_DMACTL_WPSCNT_MASK 0x700
#define LPAIF_RDMACTL_ENABLE_SHIFT 0 #define LPAIF_DMACTL_WPSCNT_SHIFT 8
#define LPAIF_RDMACTL_ENABLE_OFF (0 << LPAIF_RDMACTL_ENABLE_SHIFT) #define LPAIF_DMACTL_WPSCNT_ONE (0 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_RDMACTL_ENABLE_ON (1 << LPAIF_RDMACTL_ENABLE_SHIFT) #define LPAIF_DMACTL_WPSCNT_TWO (1 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_DMACTL_WPSCNT_THREE (2 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_DMACTL_WPSCNT_FOUR (3 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_DMACTL_WPSCNT_SIX (5 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_DMACTL_WPSCNT_EIGHT (7 << LPAIF_DMACTL_WPSCNT_SHIFT)
#define LPAIF_DMACTL_AUDINTF_MASK 0x0F0
#define LPAIF_DMACTL_AUDINTF_SHIFT 4
#define LPAIF_DMACTL_AUDINTF(id) (id << LPAIF_DMACTL_AUDINTF_SHIFT)
#define LPAIF_DMACTL_FIFOWM_MASK 0x00E
#define LPAIF_DMACTL_FIFOWM_SHIFT 1
#define LPAIF_DMACTL_FIFOWM_1 (0 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_2 (1 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_3 (2 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_4 (3 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_5 (4 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_6 (5 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_7 (6 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_FIFOWM_8 (7 << LPAIF_DMACTL_FIFOWM_SHIFT)
#define LPAIF_DMACTL_ENABLE_MASK 0x1
#define LPAIF_DMACTL_ENABLE_SHIFT 0
#define LPAIF_DMACTL_ENABLE_OFF (0 << LPAIF_DMACTL_ENABLE_SHIFT)
#define LPAIF_DMACTL_ENABLE_ON (1 << LPAIF_DMACTL_ENABLE_SHIFT)
#define LPAIF_DMACTL_DYNCLK_MASK BIT(12)
#define LPAIF_DMACTL_DYNCLK_SHIFT 12
#define LPAIF_DMACTL_DYNCLK_OFF (0 << LPAIF_DMACTL_DYNCLK_SHIFT)
#define LPAIF_DMACTL_DYNCLK_ON (1 << LPAIF_DMACTL_DYNCLK_SHIFT)
#endif /* __LPASS_LPAIF_REG_H__ */ #endif /* __LPASS_LPAIF_REG_H__ */
This diff is collapsed.
...@@ -50,7 +50,7 @@ struct lpass_data { ...@@ -50,7 +50,7 @@ struct lpass_data {
struct lpass_variant *variant; struct lpass_variant *variant;
/* bit map to keep track of static channel allocations */ /* bit map to keep track of static channel allocations */
unsigned long rdma_ch_bit_map; unsigned long dma_ch_bit_map;
/* used it for handling interrupt per dma channel */ /* used it for handling interrupt per dma channel */
struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS]; struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS];
...@@ -71,16 +71,20 @@ struct lpass_variant { ...@@ -71,16 +71,20 @@ struct lpass_variant {
u32 rdma_reg_base; u32 rdma_reg_base;
u32 rdma_reg_stride; u32 rdma_reg_stride;
u32 rdma_channels; u32 rdma_channels;
u32 wrdma_reg_base;
u32 wrdma_reg_stride;
u32 wrdma_channels;
/** /**
* on SOCs like APQ8016 the channel control bits start * on SOCs like APQ8016 the channel control bits start
* at different offset to ipq806x * at different offset to ipq806x
**/ **/
u32 rdmactl_audif_start; u32 dmactl_audif_start;
u32 wrdma_channel_start;
/* SOC specific intialization like clocks */ /* SOC specific intialization like clocks */
int (*init)(struct platform_device *pdev); int (*init)(struct platform_device *pdev);
int (*exit)(struct platform_device *pdev); int (*exit)(struct platform_device *pdev);
int (*alloc_dma_channel)(struct lpass_data *data); int (*alloc_dma_channel)(struct lpass_data *data, int direction);
int (*free_dma_channel)(struct lpass_data *data, int ch); int (*free_dma_channel)(struct lpass_data *data, int ch);
/* SOC specific dais */ /* SOC specific dais */
......
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