Commit 2735e6cd authored by Mark Brown's avatar Mark Brown

Merge branch 'topic/omap' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into HEAD

parents 85c9f9c5 167b5b93
...@@ -493,19 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) ...@@ -493,19 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
goto err_put_clk; goto err_put_clk;
} }
if (!devm_request_mem_region(&pdev->dev, res->start, dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
resource_size(res), pdev->name)) { if (IS_ERR(dmic->io_base))
dev_err(dmic->dev, "memory region already claimed\n"); return PTR_ERR(dmic->io_base);
ret = -ENODEV;
goto err_put_clk;
}
dmic->io_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!dmic->io_base) {
ret = -ENOMEM;
goto err_put_clk;
}
ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai);
if (ret) if (ret)
......
...@@ -43,7 +43,10 @@ ...@@ -43,7 +43,10 @@
#include "omap-mcpdm.h" #include "omap-mcpdm.h"
#include "omap-pcm.h" #include "omap-pcm.h"
#define OMAP44XX_MCPDM_L3_BASE 0x49032000 struct mcpdm_link_config {
u32 link_mask; /* channel mask for the direction */
u32 threshold; /* FIFO threshold */
};
struct omap_mcpdm { struct omap_mcpdm {
struct device *dev; struct device *dev;
...@@ -53,16 +56,14 @@ struct omap_mcpdm { ...@@ -53,16 +56,14 @@ struct omap_mcpdm {
struct mutex mutex; struct mutex mutex;
/* channel data */ /* Playback/Capture configuration */
u32 dn_channels; struct mcpdm_link_config config[2];
u32 up_channels;
/* McPDM FIFO thresholds */
u32 dn_threshold;
u32 up_threshold;
/* McPDM dn offsets for rx1, and 2 channels */ /* McPDM dn offsets for rx1, and 2 channels */
u32 dn_rx_offset; u32 dn_rx_offset;
/* McPDM needs to be restarted due to runtime reconfiguration */
bool restart;
}; };
/* /*
...@@ -130,11 +131,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {} ...@@ -130,11 +131,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
{ {
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
ctrl |= mcpdm->dn_channels | mcpdm->up_channels; ctrl |= link_mask;
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
...@@ -148,11 +150,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) ...@@ -148,11 +150,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
{ {
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); ctrl &= ~(link_mask);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
...@@ -188,8 +191,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) ...@@ -188,8 +191,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
} }
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
...@@ -283,6 +288,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, ...@@ -283,6 +288,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
if (omap_mcpdm_active(mcpdm)) { if (omap_mcpdm_active(mcpdm)) {
omap_mcpdm_stop(mcpdm); omap_mcpdm_stop(mcpdm);
omap_mcpdm_close_streams(mcpdm); omap_mcpdm_close_streams(mcpdm);
mcpdm->config[0].link_mask = 0;
mcpdm->config[1].link_mask = 0;
} }
} }
...@@ -296,6 +303,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -296,6 +303,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
int stream = substream->stream; int stream = substream->stream;
struct omap_pcm_dma_data *dma_data; struct omap_pcm_dma_data *dma_data;
u32 threshold;
int channels; int channels;
int link_mask = 0; int link_mask = 0;
...@@ -325,16 +333,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -325,16 +333,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
dma_data = snd_soc_dai_get_dma_data(dai, substream); dma_data = snd_soc_dai_get_dma_data(dai, substream);
threshold = mcpdm->config[stream].threshold;
/* Configure McPDM channels, and DMA packet size */ /* Configure McPDM channels, and DMA packet size */
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
mcpdm->dn_channels = link_mask << 3; link_mask <<= 3;
/* If capture is not running assume a stereo stream to come */
if (!mcpdm->config[!stream].link_mask)
mcpdm->config[!stream].link_mask = 0x3;
dma_data->packet_size = dma_data->packet_size =
(MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; (MCPDM_DN_THRES_MAX - threshold) * channels;
} else { } else {
mcpdm->up_channels = link_mask << 0; /* If playback is not running assume a stereo stream to come */
dma_data->packet_size = mcpdm->up_threshold * channels; if (!mcpdm->config[!stream].link_mask)
mcpdm->config[!stream].link_mask = (0x3 << 3);
dma_data->packet_size = threshold * channels;
} }
/* Check if we need to restart McPDM with this stream */
if (mcpdm->config[stream].link_mask &&
mcpdm->config[stream].link_mask != link_mask)
mcpdm->restart = true;
mcpdm->config[stream].link_mask = link_mask;
return 0; return 0;
} }
...@@ -346,6 +370,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, ...@@ -346,6 +370,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
if (!omap_mcpdm_active(mcpdm)) { if (!omap_mcpdm_active(mcpdm)) {
omap_mcpdm_start(mcpdm); omap_mcpdm_start(mcpdm);
omap_mcpdm_reg_dump(mcpdm); omap_mcpdm_reg_dump(mcpdm);
} else if (mcpdm->restart) {
omap_mcpdm_stop(mcpdm);
omap_mcpdm_start(mcpdm);
mcpdm->restart = false;
omap_mcpdm_reg_dump(mcpdm);
} }
return 0; return 0;
...@@ -369,7 +398,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) ...@@ -369,7 +398,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
pm_runtime_get_sync(mcpdm->dev); pm_runtime_get_sync(mcpdm->dev);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
0, "McPDM", (void *)mcpdm); 0, "McPDM", (void *)mcpdm);
pm_runtime_put_sync(mcpdm->dev); pm_runtime_put_sync(mcpdm->dev);
...@@ -380,8 +409,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) ...@@ -380,8 +409,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
} }
/* Configure McPDM threshold values */ /* Configure McPDM threshold values */
mcpdm->dn_threshold = 2; mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
MCPDM_UP_THRES_MAX - 3;
return ret; return ret;
} }
...@@ -389,7 +419,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) ...@@ -389,7 +419,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
{ {
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
free_irq(mcpdm->irq, (void *)mcpdm);
pm_runtime_disable(mcpdm->dev); pm_runtime_disable(mcpdm->dev);
return 0; return 0;
...@@ -465,14 +494,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) ...@@ -465,14 +494,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
if (res == NULL) if (res == NULL)
return -ENOMEM; return -ENOMEM;
if (!devm_request_mem_region(&pdev->dev, res->start, mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
resource_size(res), "McPDM")) if (IS_ERR(mcpdm->io_base))
return -EBUSY; return PTR_ERR(mcpdm->io_base);
mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!mcpdm->io_base)
return -ENOMEM;
mcpdm->irq = platform_get_irq(pdev, 0); mcpdm->irq = platform_get_irq(pdev, 0);
if (mcpdm->irq < 0) if (mcpdm->irq < 0)
......
...@@ -80,12 +80,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream, ...@@ -80,12 +80,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event) struct snd_kcontrol *k, int event)
{ {
int ret;
/* /*
* The PCM1773 DAC datasheet requires 1ms delay between switching * The PCM1773 DAC datasheet requires 1ms delay between switching
* VCC power on/off and /PD pin high/low * VCC power on/off and /PD pin high/low
*/ */
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
regulator_enable(omap3pandora_dac_reg); ret = regulator_enable(omap3pandora_dac_reg);
if (ret) {
dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret);
return ret;
}
mdelay(1); mdelay(1);
gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
} else { } else {
......
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