summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMarcus Cooper <codekipper@gmail.com>2016-12-20 09:49:14 -0500
committerMark Brown <broonie@kernel.org>2016-12-31 13:54:31 -0500
commit7762681a3ada5fca6017e75ea7f9cdac08fc50b9 (patch)
tree1bcb5654b941e324a5ead76e69b77c33f708e3e4 /sound
parent96e53c41e1f81c9e9d1ce38d3f28b95668b71dcf (diff)
ASoC: sun4i-spdif: Add quirks to the spdif driver
It has been seen that some newer SoCs have a different TX FIFO address and we already have the difference with the A31 requiring a reset. Add a quirks structure so that these can be managed easily. Signed-off-by: Marcus Cooper <codekipper@gmail.com> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sunxi/sun4i-spdif.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c
index 048de15d6937..fec62ee1fc72 100644
--- a/sound/soc/sunxi/sun4i-spdif.c
+++ b/sound/soc/sunxi/sun4i-spdif.c
@@ -403,9 +403,29 @@ static struct snd_soc_dai_driver sun4i_spdif_dai = {
403 .name = "spdif", 403 .name = "spdif",
404}; 404};
405 405
406struct sun4i_spdif_quirks {
407 unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
408 bool has_reset;
409};
410
411static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = {
412 .reg_dac_txdata = SUN4I_SPDIF_TXFIFO,
413};
414
415static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = {
416 .reg_dac_txdata = SUN4I_SPDIF_TXFIFO,
417 .has_reset = true,
418};
419
406static const struct of_device_id sun4i_spdif_of_match[] = { 420static const struct of_device_id sun4i_spdif_of_match[] = {
407 { .compatible = "allwinner,sun4i-a10-spdif", }, 421 {
408 { .compatible = "allwinner,sun6i-a31-spdif", }, 422 .compatible = "allwinner,sun4i-a10-spdif",
423 .data = &sun4i_a10_spdif_quirks,
424 },
425 {
426 .compatible = "allwinner,sun6i-a31-spdif",
427 .data = &sun6i_a31_spdif_quirks,
428 },
409 { /* sentinel */ } 429 { /* sentinel */ }
410}; 430};
411MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); 431MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match);
@@ -438,6 +458,7 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
438{ 458{
439 struct sun4i_spdif_dev *host; 459 struct sun4i_spdif_dev *host;
440 struct resource *res; 460 struct resource *res;
461 const struct sun4i_spdif_quirks *quirks;
441 int ret; 462 int ret;
442 void __iomem *base; 463 void __iomem *base;
443 464
@@ -459,6 +480,12 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
459 if (IS_ERR(base)) 480 if (IS_ERR(base))
460 return PTR_ERR(base); 481 return PTR_ERR(base);
461 482
483 quirks = of_device_get_match_data(&pdev->dev);
484 if (quirks == NULL) {
485 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
486 return -ENODEV;
487 }
488
462 host->regmap = devm_regmap_init_mmio(&pdev->dev, base, 489 host->regmap = devm_regmap_init_mmio(&pdev->dev, base,
463 &sun4i_spdif_regmap_config); 490 &sun4i_spdif_regmap_config);
464 491
@@ -476,14 +503,13 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
476 goto err_disable_apb_clk; 503 goto err_disable_apb_clk;
477 } 504 }
478 505
479 host->dma_params_tx.addr = res->start + SUN4I_SPDIF_TXFIFO; 506 host->dma_params_tx.addr = res->start + quirks->reg_dac_txdata;
480 host->dma_params_tx.maxburst = 8; 507 host->dma_params_tx.maxburst = 8;
481 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 508 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
482 509
483 platform_set_drvdata(pdev, host); 510 platform_set_drvdata(pdev, host);
484 511
485 if (of_device_is_compatible(pdev->dev.of_node, 512 if (quirks->has_reset) {
486 "allwinner,sun6i-a31-spdif")) {
487 host->rst = devm_reset_control_get_optional(&pdev->dev, NULL); 513 host->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
488 if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) { 514 if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) {
489 ret = -EPROBE_DEFER; 515 ret = -EPROBE_DEFER;