aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-03 13:12:53 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-04-03 13:12:53 -0400
commit2735e6cd2b8d7cbf4c096b3cb19d637efb7a3ffc (patch)
tree9016804e806539a847a9325991856e2f8d16badd
parent85c9f9c5f9d09ea43daf4f1a8b81d3c7b7394d27 (diff)
parent167b5b93a4d53f29d4fda55f96116f525b2eb3d6 (diff)
Merge branch 'topic/omap' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into HEAD
-rw-r--r--sound/soc/omap/omap-dmic.c16
-rw-r--r--sound/soc/omap/omap-mcpdm.c80
-rw-r--r--sound/soc/omap/omap3pandora.c8
3 files changed, 62 insertions, 42 deletions
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index ba49ccd9eed9..8ebaf117d81f 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -493,19 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev)
493 goto err_put_clk; 493 goto err_put_clk;
494 } 494 }
495 495
496 if (!devm_request_mem_region(&pdev->dev, res->start, 496 dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
497 resource_size(res), pdev->name)) { 497 if (IS_ERR(dmic->io_base))
498 dev_err(dmic->dev, "memory region already claimed\n"); 498 return PTR_ERR(dmic->io_base);
499 ret = -ENODEV;
500 goto err_put_clk;
501 }
502
503 dmic->io_base = devm_ioremap(&pdev->dev, res->start,
504 resource_size(res));
505 if (!dmic->io_base) {
506 ret = -ENOMEM;
507 goto err_put_clk;
508 }
509 499
510 ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); 500 ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai);
511 if (ret) 501 if (ret)
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 5ca11bdac21e..e1d3998cb0a5 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -43,7 +43,10 @@
43#include "omap-mcpdm.h" 43#include "omap-mcpdm.h"
44#include "omap-pcm.h" 44#include "omap-pcm.h"
45 45
46#define OMAP44XX_MCPDM_L3_BASE 0x49032000 46struct mcpdm_link_config {
47 u32 link_mask; /* channel mask for the direction */
48 u32 threshold; /* FIFO threshold */
49};
47 50
48struct omap_mcpdm { 51struct omap_mcpdm {
49 struct device *dev; 52 struct device *dev;
@@ -53,16 +56,14 @@ struct omap_mcpdm {
53 56
54 struct mutex mutex; 57 struct mutex mutex;
55 58
56 /* channel data */ 59 /* Playback/Capture configuration */
57 u32 dn_channels; 60 struct mcpdm_link_config config[2];
58 u32 up_channels;
59
60 /* McPDM FIFO thresholds */
61 u32 dn_threshold;
62 u32 up_threshold;
63 61
64 /* McPDM dn offsets for rx1, and 2 channels */ 62 /* McPDM dn offsets for rx1, and 2 channels */
65 u32 dn_rx_offset; 63 u32 dn_rx_offset;
64
65 /* McPDM needs to be restarted due to runtime reconfiguration */
66 bool restart;
66}; 67};
67 68
68/* 69/*
@@ -130,11 +131,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
130static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) 131static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
131{ 132{
132 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 133 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
134 u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
133 135
134 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 136 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
135 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 137 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
136 138
137 ctrl |= mcpdm->dn_channels | mcpdm->up_channels; 139 ctrl |= link_mask;
138 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 140 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
139 141
140 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 142 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -148,11 +150,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
148static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) 150static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
149{ 151{
150 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); 152 u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
153 u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
151 154
152 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 155 ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
153 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 156 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
154 157
155 ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); 158 ctrl &= ~(link_mask);
156 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); 159 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
157 160
158 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); 161 ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -188,8 +191,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
188 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); 191 omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
189 } 192 }
190 193
191 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); 194 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
192 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); 195 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
196 omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
197 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
193 198
194 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, 199 omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
195 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); 200 MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
@@ -283,6 +288,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
283 if (omap_mcpdm_active(mcpdm)) { 288 if (omap_mcpdm_active(mcpdm)) {
284 omap_mcpdm_stop(mcpdm); 289 omap_mcpdm_stop(mcpdm);
285 omap_mcpdm_close_streams(mcpdm); 290 omap_mcpdm_close_streams(mcpdm);
291 mcpdm->config[0].link_mask = 0;
292 mcpdm->config[1].link_mask = 0;
286 } 293 }
287 } 294 }
288 295
@@ -296,6 +303,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
296 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 303 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
297 int stream = substream->stream; 304 int stream = substream->stream;
298 struct omap_pcm_dma_data *dma_data; 305 struct omap_pcm_dma_data *dma_data;
306 u32 threshold;
299 int channels; 307 int channels;
300 int link_mask = 0; 308 int link_mask = 0;
301 309
@@ -325,16 +333,32 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
325 333
326 dma_data = snd_soc_dai_get_dma_data(dai, substream); 334 dma_data = snd_soc_dai_get_dma_data(dai, substream);
327 335
336 threshold = mcpdm->config[stream].threshold;
328 /* Configure McPDM channels, and DMA packet size */ 337 /* Configure McPDM channels, and DMA packet size */
329 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 338 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
330 mcpdm->dn_channels = link_mask << 3; 339 link_mask <<= 3;
340
341 /* If capture is not running assume a stereo stream to come */
342 if (!mcpdm->config[!stream].link_mask)
343 mcpdm->config[!stream].link_mask = 0x3;
344
331 dma_data->packet_size = 345 dma_data->packet_size =
332 (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; 346 (MCPDM_DN_THRES_MAX - threshold) * channels;
333 } else { 347 } else {
334 mcpdm->up_channels = link_mask << 0; 348 /* If playback is not running assume a stereo stream to come */
335 dma_data->packet_size = mcpdm->up_threshold * channels; 349 if (!mcpdm->config[!stream].link_mask)
350 mcpdm->config[!stream].link_mask = (0x3 << 3);
351
352 dma_data->packet_size = threshold * channels;
336 } 353 }
337 354
355 /* Check if we need to restart McPDM with this stream */
356 if (mcpdm->config[stream].link_mask &&
357 mcpdm->config[stream].link_mask != link_mask)
358 mcpdm->restart = true;
359
360 mcpdm->config[stream].link_mask = link_mask;
361
338 return 0; 362 return 0;
339} 363}
340 364
@@ -346,6 +370,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
346 if (!omap_mcpdm_active(mcpdm)) { 370 if (!omap_mcpdm_active(mcpdm)) {
347 omap_mcpdm_start(mcpdm); 371 omap_mcpdm_start(mcpdm);
348 omap_mcpdm_reg_dump(mcpdm); 372 omap_mcpdm_reg_dump(mcpdm);
373 } else if (mcpdm->restart) {
374 omap_mcpdm_stop(mcpdm);
375 omap_mcpdm_start(mcpdm);
376 mcpdm->restart = false;
377 omap_mcpdm_reg_dump(mcpdm);
349 } 378 }
350 379
351 return 0; 380 return 0;
@@ -369,7 +398,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
369 pm_runtime_get_sync(mcpdm->dev); 398 pm_runtime_get_sync(mcpdm->dev);
370 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); 399 omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
371 400
372 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 401 ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
373 0, "McPDM", (void *)mcpdm); 402 0, "McPDM", (void *)mcpdm);
374 403
375 pm_runtime_put_sync(mcpdm->dev); 404 pm_runtime_put_sync(mcpdm->dev);
@@ -380,8 +409,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
380 } 409 }
381 410
382 /* Configure McPDM threshold values */ 411 /* Configure McPDM threshold values */
383 mcpdm->dn_threshold = 2; 412 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
384 mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; 413 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
414 MCPDM_UP_THRES_MAX - 3;
385 return ret; 415 return ret;
386} 416}
387 417
@@ -389,7 +419,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
389{ 419{
390 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); 420 struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
391 421
392 free_irq(mcpdm->irq, (void *)mcpdm);
393 pm_runtime_disable(mcpdm->dev); 422 pm_runtime_disable(mcpdm->dev);
394 423
395 return 0; 424 return 0;
@@ -465,14 +494,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
465 if (res == NULL) 494 if (res == NULL)
466 return -ENOMEM; 495 return -ENOMEM;
467 496
468 if (!devm_request_mem_region(&pdev->dev, res->start, 497 mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
469 resource_size(res), "McPDM")) 498 if (IS_ERR(mcpdm->io_base))
470 return -EBUSY; 499 return PTR_ERR(mcpdm->io_base);
471
472 mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
473 resource_size(res));
474 if (!mcpdm->io_base)
475 return -ENOMEM;
476 500
477 mcpdm->irq = platform_get_irq(pdev, 0); 501 mcpdm->irq = platform_get_irq(pdev, 0);
478 if (mcpdm->irq < 0) 502 if (mcpdm->irq < 0)
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 805512f2555a..9e46e1d8cb1b 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -80,12 +80,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream,
80static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, 80static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
81 struct snd_kcontrol *k, int event) 81 struct snd_kcontrol *k, int event)
82{ 82{
83 int ret;
84
83 /* 85 /*
84 * The PCM1773 DAC datasheet requires 1ms delay between switching 86 * The PCM1773 DAC datasheet requires 1ms delay between switching
85 * VCC power on/off and /PD pin high/low 87 * VCC power on/off and /PD pin high/low
86 */ 88 */
87 if (SND_SOC_DAPM_EVENT_ON(event)) { 89 if (SND_SOC_DAPM_EVENT_ON(event)) {
88 regulator_enable(omap3pandora_dac_reg); 90 ret = regulator_enable(omap3pandora_dac_reg);
91 if (ret) {
92 dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret);
93 return ret;
94 }
89 mdelay(1); 95 mdelay(1);
90 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 96 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
91 } else { 97 } else {