diff options
-rw-r--r-- | Documentation/devicetree/bindings/sound/designware-i2s.txt | 31 | ||||
-rw-r--r-- | sound/soc/dwc/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/dwc/designware_i2s.c | 311 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.c | 5 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.h | 3 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 4 | ||||
-rw-r--r-- | sound/soc/sh/fsi.c | 9 | ||||
-rw-r--r-- | sound/soc/soc-devres.c | 2 |
11 files changed, 285 insertions, 87 deletions
diff --git a/Documentation/devicetree/bindings/sound/designware-i2s.txt b/Documentation/devicetree/bindings/sound/designware-i2s.txt new file mode 100644 index 000000000000..7bb54247f8e8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/designware-i2s.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | DesignWare I2S controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Must be "snps,designware-i2s" | ||
5 | - reg : Must contain the I2S core's registers location and length | ||
6 | - clocks : Pairs of phandle and specifier referencing the controller's | ||
7 | clocks. The controller expects one clock: the clock used as the sampling | ||
8 | rate reference clock sample. | ||
9 | - clock-names : "i2sclk" for the sample rate reference clock. | ||
10 | - dmas: Pairs of phandle and specifier for the DMA channels that are used by | ||
11 | the core. The core expects one or two dma channels: one for transmit and | ||
12 | one for receive. | ||
13 | - dma-names : "tx" for the transmit channel, "rx" for the receive channel. | ||
14 | |||
15 | For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' | ||
16 | properties please check: | ||
17 | * resource-names.txt | ||
18 | * clock/clock-bindings.txt | ||
19 | * dma/dma.txt | ||
20 | |||
21 | Example: | ||
22 | |||
23 | soc_i2s: i2s@7ff90000 { | ||
24 | compatible = "snps,designware-i2s"; | ||
25 | reg = <0x0 0x7ff90000 0x0 0x1000>; | ||
26 | clocks = <&scpi_i2sclk 0>; | ||
27 | clock-names = "i2sclk"; | ||
28 | #sound-dai-cells = <0>; | ||
29 | dmas = <&dma0 5>; | ||
30 | dma-names = "tx"; | ||
31 | }; | ||
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig index e334900cf0b8..d50e08517dce 100644 --- a/sound/soc/dwc/Kconfig +++ b/sound/soc/dwc/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_DESIGNWARE_I2S | 1 | config SND_DESIGNWARE_I2S |
2 | tristate "Synopsys I2S Device Driver" | 2 | tristate "Synopsys I2S Device Driver" |
3 | depends on CLKDEV_LOOKUP | 3 | depends on CLKDEV_LOOKUP |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
4 | help | 5 | help |
5 | Say Y or M if you want to add support for I2S driver for | 6 | Say Y or M if you want to add support for I2S driver for |
6 | Synopsys desigwnware I2S device. The device supports upto | 7 | Synopsys desigwnware I2S device. The device supports upto |
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index 8d18bbda661b..a3e97b46b64e 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> | 23 | #include <sound/pcm_params.h> |
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | #include <sound/dmaengine_pcm.h> | ||
25 | 26 | ||
26 | /* common register for all channel */ | 27 | /* common register for all channel */ |
27 | #define IER 0x000 | 28 | #define IER 0x000 |
@@ -54,9 +55,39 @@ | |||
54 | #define I2S_COMP_VERSION 0x01F8 | 55 | #define I2S_COMP_VERSION 0x01F8 |
55 | #define I2S_COMP_TYPE 0x01FC | 56 | #define I2S_COMP_TYPE 0x01FC |
56 | 57 | ||
58 | /* | ||
59 | * Component parameter register fields - define the I2S block's | ||
60 | * configuration. | ||
61 | */ | ||
62 | #define COMP1_TX_WORDSIZE_3(r) (((r) & GENMASK(27, 25)) >> 25) | ||
63 | #define COMP1_TX_WORDSIZE_2(r) (((r) & GENMASK(24, 22)) >> 22) | ||
64 | #define COMP1_TX_WORDSIZE_1(r) (((r) & GENMASK(21, 19)) >> 19) | ||
65 | #define COMP1_TX_WORDSIZE_0(r) (((r) & GENMASK(18, 16)) >> 16) | ||
66 | #define COMP1_TX_CHANNELS(r) (((r) & GENMASK(10, 9)) >> 9) | ||
67 | #define COMP1_RX_CHANNELS(r) (((r) & GENMASK(8, 7)) >> 7) | ||
68 | #define COMP1_RX_ENABLED(r) (((r) & BIT(6)) >> 6) | ||
69 | #define COMP1_TX_ENABLED(r) (((r) & BIT(5)) >> 5) | ||
70 | #define COMP1_MODE_EN(r) (((r) & BIT(4)) >> 4) | ||
71 | #define COMP1_FIFO_DEPTH_GLOBAL(r) (((r) & GENMASK(3, 2)) >> 2) | ||
72 | #define COMP1_APB_DATA_WIDTH(r) (((r) & GENMASK(1, 0)) >> 0) | ||
73 | |||
74 | #define COMP2_RX_WORDSIZE_3(r) (((r) & GENMASK(12, 10)) >> 10) | ||
75 | #define COMP2_RX_WORDSIZE_2(r) (((r) & GENMASK(9, 7)) >> 7) | ||
76 | #define COMP2_RX_WORDSIZE_1(r) (((r) & GENMASK(5, 3)) >> 3) | ||
77 | #define COMP2_RX_WORDSIZE_0(r) (((r) & GENMASK(2, 0)) >> 0) | ||
78 | |||
79 | /* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */ | ||
80 | #define COMP_MAX_WORDSIZE (1 << 3) | ||
81 | #define COMP_MAX_DATA_WIDTH (1 << 2) | ||
82 | |||
57 | #define MAX_CHANNEL_NUM 8 | 83 | #define MAX_CHANNEL_NUM 8 |
58 | #define MIN_CHANNEL_NUM 2 | 84 | #define MIN_CHANNEL_NUM 2 |
59 | 85 | ||
86 | union dw_i2s_snd_dma_data { | ||
87 | struct i2s_dma_data pd; | ||
88 | struct snd_dmaengine_dai_dma_data dt; | ||
89 | }; | ||
90 | |||
60 | struct dw_i2s_dev { | 91 | struct dw_i2s_dev { |
61 | void __iomem *i2s_base; | 92 | void __iomem *i2s_base; |
62 | struct clk *clk; | 93 | struct clk *clk; |
@@ -65,8 +96,8 @@ struct dw_i2s_dev { | |||
65 | struct device *dev; | 96 | struct device *dev; |
66 | 97 | ||
67 | /* data related to DMA transfers b/w i2s and DMAC */ | 98 | /* data related to DMA transfers b/w i2s and DMAC */ |
68 | struct i2s_dma_data play_dma_data; | 99 | union dw_i2s_snd_dma_data play_dma_data; |
69 | struct i2s_dma_data capture_dma_data; | 100 | union dw_i2s_snd_dma_data capture_dma_data; |
70 | struct i2s_clk_config_data config; | 101 | struct i2s_clk_config_data config; |
71 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); | 102 | int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); |
72 | }; | 103 | }; |
@@ -153,7 +184,7 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream, | |||
153 | struct snd_soc_dai *cpu_dai) | 184 | struct snd_soc_dai *cpu_dai) |
154 | { | 185 | { |
155 | struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); | 186 | struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); |
156 | struct i2s_dma_data *dma_data = NULL; | 187 | union dw_i2s_snd_dma_data *dma_data = NULL; |
157 | 188 | ||
158 | if (!(dev->capability & DWC_I2S_RECORD) && | 189 | if (!(dev->capability & DWC_I2S_RECORD) && |
159 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) | 190 | (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) |
@@ -242,13 +273,21 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream, | |||
242 | 273 | ||
243 | config->sample_rate = params_rate(params); | 274 | config->sample_rate = params_rate(params); |
244 | 275 | ||
245 | if (!dev->i2s_clk_cfg) | 276 | if (dev->i2s_clk_cfg) { |
246 | return -EINVAL; | 277 | ret = dev->i2s_clk_cfg(config); |
278 | if (ret < 0) { | ||
279 | dev_err(dev->dev, "runtime audio clk config fail\n"); | ||
280 | return ret; | ||
281 | } | ||
282 | } else { | ||
283 | u32 bitclk = config->sample_rate * config->data_width * 2; | ||
247 | 284 | ||
248 | ret = dev->i2s_clk_cfg(config); | 285 | ret = clk_set_rate(dev->clk, bitclk); |
249 | if (ret < 0) { | 286 | if (ret) { |
250 | dev_err(dev->dev, "runtime audio clk config fail\n"); | 287 | dev_err(dev->dev, "Can't set I2S clock rate: %d\n", |
251 | return ret; | 288 | ret); |
289 | return ret; | ||
290 | } | ||
252 | } | 291 | } |
253 | 292 | ||
254 | return 0; | 293 | return 0; |
@@ -335,20 +374,162 @@ static int dw_i2s_resume(struct snd_soc_dai *dai) | |||
335 | #define dw_i2s_resume NULL | 374 | #define dw_i2s_resume NULL |
336 | #endif | 375 | #endif |
337 | 376 | ||
377 | /* | ||
378 | * The following tables allow a direct lookup of various parameters | ||
379 | * defined in the I2S block's configuration in terms of sound system | ||
380 | * parameters. Each table is sized to the number of entries possible | ||
381 | * according to the number of configuration bits describing an I2S | ||
382 | * block parameter. | ||
383 | */ | ||
384 | |||
385 | /* Maximum bit resolution of a channel - not uniformly spaced */ | ||
386 | static const u32 fifo_width[COMP_MAX_WORDSIZE] = { | ||
387 | 12, 16, 20, 24, 32, 0, 0, 0 | ||
388 | }; | ||
389 | |||
390 | /* Width of (DMA) bus */ | ||
391 | static const u32 bus_widths[COMP_MAX_DATA_WIDTH] = { | ||
392 | DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
393 | DMA_SLAVE_BUSWIDTH_2_BYTES, | ||
394 | DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
395 | DMA_SLAVE_BUSWIDTH_UNDEFINED | ||
396 | }; | ||
397 | |||
398 | /* PCM format to support channel resolution */ | ||
399 | static const u32 formats[COMP_MAX_WORDSIZE] = { | ||
400 | SNDRV_PCM_FMTBIT_S16_LE, | ||
401 | SNDRV_PCM_FMTBIT_S16_LE, | ||
402 | SNDRV_PCM_FMTBIT_S24_LE, | ||
403 | SNDRV_PCM_FMTBIT_S24_LE, | ||
404 | SNDRV_PCM_FMTBIT_S32_LE, | ||
405 | 0, | ||
406 | 0, | ||
407 | 0 | ||
408 | }; | ||
409 | |||
410 | static int dw_configure_dai(struct dw_i2s_dev *dev, | ||
411 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
412 | unsigned int rates) | ||
413 | { | ||
414 | /* | ||
415 | * Read component parameter registers to extract | ||
416 | * the I2S block's configuration. | ||
417 | */ | ||
418 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
419 | u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); | ||
420 | u32 idx; | ||
421 | |||
422 | if (COMP1_TX_ENABLED(comp1)) { | ||
423 | dev_dbg(dev->dev, " designware: play supported\n"); | ||
424 | idx = COMP1_TX_WORDSIZE_0(comp1); | ||
425 | if (WARN_ON(idx >= ARRAY_SIZE(formats))) | ||
426 | return -EINVAL; | ||
427 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
428 | dw_i2s_dai->playback.channels_max = | ||
429 | 1 << (COMP1_TX_CHANNELS(comp1) + 1); | ||
430 | dw_i2s_dai->playback.formats = formats[idx]; | ||
431 | dw_i2s_dai->playback.rates = rates; | ||
432 | } | ||
433 | |||
434 | if (COMP1_RX_ENABLED(comp1)) { | ||
435 | dev_dbg(dev->dev, "designware: record supported\n"); | ||
436 | idx = COMP2_RX_WORDSIZE_0(comp2); | ||
437 | if (WARN_ON(idx >= ARRAY_SIZE(formats))) | ||
438 | return -EINVAL; | ||
439 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
440 | dw_i2s_dai->capture.channels_max = | ||
441 | 1 << (COMP1_RX_CHANNELS(comp1) + 1); | ||
442 | dw_i2s_dai->capture.formats = formats[idx]; | ||
443 | dw_i2s_dai->capture.rates = rates; | ||
444 | } | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev, | ||
450 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
451 | struct resource *res, | ||
452 | const struct i2s_platform_data *pdata) | ||
453 | { | ||
454 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
455 | u32 idx = COMP1_APB_DATA_WIDTH(comp1); | ||
456 | int ret; | ||
457 | |||
458 | if (WARN_ON(idx >= ARRAY_SIZE(bus_widths))) | ||
459 | return -EINVAL; | ||
460 | |||
461 | ret = dw_configure_dai(dev, dw_i2s_dai, pdata->snd_rates); | ||
462 | if (ret < 0) | ||
463 | return ret; | ||
464 | |||
465 | /* Set DMA slaves info */ | ||
466 | dev->play_dma_data.pd.data = pdata->play_dma_data; | ||
467 | dev->capture_dma_data.pd.data = pdata->capture_dma_data; | ||
468 | dev->play_dma_data.pd.addr = res->start + I2S_TXDMA; | ||
469 | dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA; | ||
470 | dev->play_dma_data.pd.max_burst = 16; | ||
471 | dev->capture_dma_data.pd.max_burst = 16; | ||
472 | dev->play_dma_data.pd.addr_width = bus_widths[idx]; | ||
473 | dev->capture_dma_data.pd.addr_width = bus_widths[idx]; | ||
474 | dev->play_dma_data.pd.filter = pdata->filter; | ||
475 | dev->capture_dma_data.pd.filter = pdata->filter; | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int dw_configure_dai_by_dt(struct dw_i2s_dev *dev, | ||
481 | struct snd_soc_dai_driver *dw_i2s_dai, | ||
482 | struct resource *res) | ||
483 | { | ||
484 | u32 comp1 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_1); | ||
485 | u32 comp2 = i2s_read_reg(dev->i2s_base, I2S_COMP_PARAM_2); | ||
486 | u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1)); | ||
487 | u32 idx = COMP1_APB_DATA_WIDTH(comp1); | ||
488 | u32 idx2; | ||
489 | int ret; | ||
490 | |||
491 | if (WARN_ON(idx >= ARRAY_SIZE(bus_widths))) | ||
492 | return -EINVAL; | ||
493 | |||
494 | ret = dw_configure_dai(dev, dw_i2s_dai, SNDRV_PCM_RATE_8000_192000); | ||
495 | if (ret < 0) | ||
496 | return ret; | ||
497 | |||
498 | if (COMP1_TX_ENABLED(comp1)) { | ||
499 | idx2 = COMP1_TX_WORDSIZE_0(comp1); | ||
500 | |||
501 | dev->capability |= DWC_I2S_PLAY; | ||
502 | dev->play_dma_data.dt.addr = res->start + I2S_TXDMA; | ||
503 | dev->play_dma_data.dt.addr_width = bus_widths[idx]; | ||
504 | dev->play_dma_data.dt.chan_name = "TX"; | ||
505 | dev->play_dma_data.dt.fifo_size = fifo_depth * | ||
506 | (fifo_width[idx2]) >> 8; | ||
507 | dev->play_dma_data.dt.maxburst = 16; | ||
508 | } | ||
509 | if (COMP1_RX_ENABLED(comp1)) { | ||
510 | idx2 = COMP2_RX_WORDSIZE_0(comp2); | ||
511 | |||
512 | dev->capability |= DWC_I2S_RECORD; | ||
513 | dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA; | ||
514 | dev->capture_dma_data.dt.addr_width = bus_widths[idx]; | ||
515 | dev->capture_dma_data.dt.chan_name = "RX"; | ||
516 | dev->capture_dma_data.dt.fifo_size = fifo_depth * | ||
517 | (fifo_width[idx2] >> 8); | ||
518 | dev->capture_dma_data.dt.maxburst = 16; | ||
519 | } | ||
520 | |||
521 | return 0; | ||
522 | |||
523 | } | ||
524 | |||
338 | static int dw_i2s_probe(struct platform_device *pdev) | 525 | static int dw_i2s_probe(struct platform_device *pdev) |
339 | { | 526 | { |
340 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; | 527 | const struct i2s_platform_data *pdata = pdev->dev.platform_data; |
341 | struct dw_i2s_dev *dev; | 528 | struct dw_i2s_dev *dev; |
342 | struct resource *res; | 529 | struct resource *res; |
343 | int ret; | 530 | int ret; |
344 | unsigned int cap; | ||
345 | struct snd_soc_dai_driver *dw_i2s_dai; | 531 | struct snd_soc_dai_driver *dw_i2s_dai; |
346 | 532 | ||
347 | if (!pdata) { | ||
348 | dev_err(&pdev->dev, "Invalid platform data\n"); | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
352 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 533 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
353 | if (!dev) { | 534 | if (!dev) { |
354 | dev_warn(&pdev->dev, "kzalloc fail\n"); | 535 | dev_warn(&pdev->dev, "kzalloc fail\n"); |
@@ -356,83 +537,67 @@ static int dw_i2s_probe(struct platform_device *pdev) | |||
356 | } | 537 | } |
357 | 538 | ||
358 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); | 539 | dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); |
359 | if (!dw_i2s_dai) { | 540 | if (!dw_i2s_dai) |
360 | dev_err(&pdev->dev, "mem allocation failed for dai driver\n"); | ||
361 | return -ENOMEM; | 541 | return -ENOMEM; |
362 | } | ||
363 | 542 | ||
364 | dw_i2s_dai->ops = &dw_i2s_dai_ops; | 543 | dw_i2s_dai->ops = &dw_i2s_dai_ops; |
365 | dw_i2s_dai->suspend = dw_i2s_suspend; | 544 | dw_i2s_dai->suspend = dw_i2s_suspend; |
366 | dw_i2s_dai->resume = dw_i2s_resume; | 545 | dw_i2s_dai->resume = dw_i2s_resume; |
367 | 546 | ||
368 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 547 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
369 | if (!res) { | ||
370 | dev_err(&pdev->dev, "no i2s resource defined\n"); | ||
371 | return -ENODEV; | ||
372 | } | ||
373 | |||
374 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); | 548 | dev->i2s_base = devm_ioremap_resource(&pdev->dev, res); |
375 | if (IS_ERR(dev->i2s_base)) { | 549 | if (IS_ERR(dev->i2s_base)) |
376 | dev_err(&pdev->dev, "ioremap fail for i2s_region\n"); | ||
377 | return PTR_ERR(dev->i2s_base); | 550 | return PTR_ERR(dev->i2s_base); |
378 | } | ||
379 | 551 | ||
380 | cap = pdata->cap; | 552 | dev->dev = &pdev->dev; |
381 | dev->capability = cap; | 553 | if (pdata) { |
382 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | 554 | ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); |
555 | if (ret < 0) | ||
556 | return ret; | ||
557 | |||
558 | dev->capability = pdata->cap; | ||
559 | dev->i2s_clk_cfg = pdata->i2s_clk_cfg; | ||
560 | if (!dev->i2s_clk_cfg) { | ||
561 | dev_err(&pdev->dev, "no clock configure method\n"); | ||
562 | return -ENODEV; | ||
563 | } | ||
383 | 564 | ||
384 | /* Set DMA slaves info */ | 565 | dev->clk = devm_clk_get(&pdev->dev, NULL); |
566 | } else { | ||
567 | ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); | ||
568 | if (ret < 0) | ||
569 | return ret; | ||
385 | 570 | ||
386 | dev->play_dma_data.data = pdata->play_dma_data; | 571 | dev->clk = devm_clk_get(&pdev->dev, "i2sclk"); |
387 | dev->capture_dma_data.data = pdata->capture_dma_data; | 572 | } |
388 | dev->play_dma_data.addr = res->start + I2S_TXDMA; | ||
389 | dev->capture_dma_data.addr = res->start + I2S_RXDMA; | ||
390 | dev->play_dma_data.max_burst = 16; | ||
391 | dev->capture_dma_data.max_burst = 16; | ||
392 | dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
393 | dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
394 | dev->play_dma_data.filter = pdata->filter; | ||
395 | dev->capture_dma_data.filter = pdata->filter; | ||
396 | |||
397 | dev->clk = clk_get(&pdev->dev, NULL); | ||
398 | if (IS_ERR(dev->clk)) | 573 | if (IS_ERR(dev->clk)) |
399 | return PTR_ERR(dev->clk); | 574 | return PTR_ERR(dev->clk); |
400 | 575 | ||
401 | ret = clk_enable(dev->clk); | 576 | ret = clk_prepare_enable(dev->clk); |
402 | if (ret < 0) | 577 | if (ret < 0) |
403 | goto err_clk_put; | 578 | return ret; |
404 | |||
405 | if (cap & DWC_I2S_PLAY) { | ||
406 | dev_dbg(&pdev->dev, " designware: play supported\n"); | ||
407 | dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM; | ||
408 | dw_i2s_dai->playback.channels_max = pdata->channel; | ||
409 | dw_i2s_dai->playback.formats = pdata->snd_fmts; | ||
410 | dw_i2s_dai->playback.rates = pdata->snd_rates; | ||
411 | } | ||
412 | |||
413 | if (cap & DWC_I2S_RECORD) { | ||
414 | dev_dbg(&pdev->dev, "designware: record supported\n"); | ||
415 | dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM; | ||
416 | dw_i2s_dai->capture.channels_max = pdata->channel; | ||
417 | dw_i2s_dai->capture.formats = pdata->snd_fmts; | ||
418 | dw_i2s_dai->capture.rates = pdata->snd_rates; | ||
419 | } | ||
420 | 579 | ||
421 | dev->dev = &pdev->dev; | ||
422 | dev_set_drvdata(&pdev->dev, dev); | 580 | dev_set_drvdata(&pdev->dev, dev); |
423 | ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, | 581 | ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, |
424 | dw_i2s_dai, 1); | 582 | dw_i2s_dai, 1); |
425 | if (ret != 0) { | 583 | if (ret != 0) { |
426 | dev_err(&pdev->dev, "not able to register dai\n"); | 584 | dev_err(&pdev->dev, "not able to register dai\n"); |
427 | goto err_clk_disable; | 585 | goto err_clk_disable; |
428 | } | 586 | } |
429 | 587 | ||
588 | if (!pdata) { | ||
589 | ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); | ||
590 | if (ret) { | ||
591 | dev_err(&pdev->dev, | ||
592 | "Could not register PCM: %d\n", ret); | ||
593 | goto err_clk_disable; | ||
594 | } | ||
595 | } | ||
596 | |||
430 | return 0; | 597 | return 0; |
431 | 598 | ||
432 | err_clk_disable: | 599 | err_clk_disable: |
433 | clk_disable(dev->clk); | 600 | clk_disable_unprepare(dev->clk); |
434 | err_clk_put: | ||
435 | clk_put(dev->clk); | ||
436 | return ret; | 601 | return ret; |
437 | } | 602 | } |
438 | 603 | ||
@@ -440,18 +605,26 @@ static int dw_i2s_remove(struct platform_device *pdev) | |||
440 | { | 605 | { |
441 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); | 606 | struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); |
442 | 607 | ||
443 | snd_soc_unregister_component(&pdev->dev); | 608 | clk_disable_unprepare(dev->clk); |
444 | |||
445 | clk_put(dev->clk); | ||
446 | 609 | ||
447 | return 0; | 610 | return 0; |
448 | } | 611 | } |
449 | 612 | ||
613 | #ifdef CONFIG_OF | ||
614 | static const struct of_device_id dw_i2s_of_match[] = { | ||
615 | { .compatible = "snps,designware-i2s", }, | ||
616 | {}, | ||
617 | }; | ||
618 | |||
619 | MODULE_DEVICE_TABLE(of, dw_i2s_of_match); | ||
620 | #endif | ||
621 | |||
450 | static struct platform_driver dw_i2s_driver = { | 622 | static struct platform_driver dw_i2s_driver = { |
451 | .probe = dw_i2s_probe, | 623 | .probe = dw_i2s_probe, |
452 | .remove = dw_i2s_remove, | 624 | .remove = dw_i2s_remove, |
453 | .driver = { | 625 | .driver = { |
454 | .name = "designware-i2s", | 626 | .name = "designware-i2s", |
627 | .of_match_table = of_match_ptr(dw_i2s_of_match), | ||
455 | }, | 628 | }, |
456 | }; | 629 | }; |
457 | 630 | ||
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 026a80117540..c068494bae30 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c | |||
@@ -818,7 +818,6 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
818 | return -ENOMEM; | 818 | return -ENOMEM; |
819 | 819 | ||
820 | asrc_priv->pdev = pdev; | 820 | asrc_priv->pdev = pdev; |
821 | strncpy(asrc_priv->name, np->name, sizeof(asrc_priv->name) - 1); | ||
822 | 821 | ||
823 | /* Get the addresses and IRQ */ | 822 | /* Get the addresses and IRQ */ |
824 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 823 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -837,12 +836,12 @@ static int fsl_asrc_probe(struct platform_device *pdev) | |||
837 | 836 | ||
838 | irq = platform_get_irq(pdev, 0); | 837 | irq = platform_get_irq(pdev, 0); |
839 | if (irq < 0) { | 838 | if (irq < 0) { |
840 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 839 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
841 | return irq; | 840 | return irq; |
842 | } | 841 | } |
843 | 842 | ||
844 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, | 843 | ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, |
845 | asrc_priv->name, asrc_priv); | 844 | dev_name(&pdev->dev), asrc_priv); |
846 | if (ret) { | 845 | if (ret) { |
847 | dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); | 846 | dev_err(&pdev->dev, "failed to claim irq %u: %d\n", irq, ret); |
848 | return ret; | 847 | return ret; |
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index a3f211f53c23..4aed63c4b431 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h | |||
@@ -433,7 +433,6 @@ struct fsl_asrc_pair { | |||
433 | * @channel_avail: non-occupied channel numbers | 433 | * @channel_avail: non-occupied channel numbers |
434 | * @asrc_rate: default sample rate for ASoC Back-Ends | 434 | * @asrc_rate: default sample rate for ASoC Back-Ends |
435 | * @asrc_width: default sample width for ASoC Back-Ends | 435 | * @asrc_width: default sample width for ASoC Back-Ends |
436 | * @name: driver name | ||
437 | */ | 436 | */ |
438 | struct fsl_asrc { | 437 | struct fsl_asrc { |
439 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 438 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
@@ -452,8 +451,6 @@ struct fsl_asrc { | |||
452 | 451 | ||
453 | int asrc_rate; | 452 | int asrc_rate; |
454 | int asrc_width; | 453 | int asrc_width; |
455 | |||
456 | char name[32]; | ||
457 | }; | 454 | }; |
458 | 455 | ||
459 | extern struct snd_soc_platform_driver fsl_asrc_platform; | 456 | extern struct snd_soc_platform_driver fsl_asrc_platform; |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 1c08ab13637c..5c7597191e3f 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -774,7 +774,7 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
774 | 774 | ||
775 | irq = platform_get_irq(pdev, 0); | 775 | irq = platform_get_irq(pdev, 0); |
776 | if (irq < 0) { | 776 | if (irq < 0) { |
777 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 777 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
778 | return irq; | 778 | return irq; |
779 | } | 779 | } |
780 | 780 | ||
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 032d2d33619c..ec79c3d5e65e 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -612,7 +612,7 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
612 | 612 | ||
613 | irq = platform_get_irq(pdev, 0); | 613 | irq = platform_get_irq(pdev, 0); |
614 | if (irq < 0) { | 614 | if (irq < 0) { |
615 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 615 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
616 | return irq; | 616 | return irq; |
617 | } | 617 | } |
618 | 618 | ||
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index af0429421fc8..735e2eec52f7 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -1198,7 +1198,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1198 | 1198 | ||
1199 | irq = platform_get_irq(pdev, 0); | 1199 | irq = platform_get_irq(pdev, 0); |
1200 | if (irq < 0) { | 1200 | if (irq < 0) { |
1201 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 1201 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
1202 | return irq; | 1202 | return irq; |
1203 | } | 1203 | } |
1204 | 1204 | ||
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 059496ed9ad7..65400bef013c 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -1362,8 +1362,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | ssi_private->irq = platform_get_irq(pdev, 0); | 1364 | ssi_private->irq = platform_get_irq(pdev, 0); |
1365 | if (ssi_private->irq < 0) { | 1365 | if (!ssi_private->irq) { |
1366 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 1366 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
1367 | return ssi_private->irq; | 1367 | return ssi_private->irq; |
1368 | } | 1368 | } |
1369 | 1369 | ||
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 8869971d7884..d49f25f9efd3 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -820,12 +820,9 @@ static int fsi_clk_enable(struct device *dev, | |||
820 | return ret; | 820 | return ret; |
821 | } | 821 | } |
822 | 822 | ||
823 | if (clock->xck) | 823 | clk_enable(clock->xck); |
824 | clk_enable(clock->xck); | 824 | clk_enable(clock->ick); |
825 | if (clock->ick) | 825 | clk_enable(clock->div); |
826 | clk_enable(clock->ick); | ||
827 | if (clock->div) | ||
828 | clk_enable(clock->div); | ||
829 | 826 | ||
830 | clock->count++; | 827 | clock->count++; |
831 | } | 828 | } |
diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 057e5ef7dcce..a57921eeee81 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c | |||
@@ -60,7 +60,7 @@ static void devm_platform_release(struct device *dev, void *res) | |||
60 | /** | 60 | /** |
61 | * devm_snd_soc_register_platform - resource managed platform registration | 61 | * devm_snd_soc_register_platform - resource managed platform registration |
62 | * @dev: Device used to manage platform | 62 | * @dev: Device used to manage platform |
63 | * @platform: platform to register | 63 | * @platform_drv: platform to register |
64 | * | 64 | * |
65 | * Register a platform driver with automatic unregistration when the device is | 65 | * Register a platform driver with automatic unregistration when the device is |
66 | * unregistered. | 66 | * unregistered. |