diff options
author | Marcus Cooper <codekipper@gmail.com> | 2016-12-20 09:49:14 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-12-31 13:54:31 -0500 |
commit | 7762681a3ada5fca6017e75ea7f9cdac08fc50b9 (patch) | |
tree | 1bcb5654b941e324a5ead76e69b77c33f708e3e4 /sound | |
parent | 96e53c41e1f81c9e9d1ce38d3f28b95668b71dcf (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.c | 36 |
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 | ||
406 | struct sun4i_spdif_quirks { | ||
407 | unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ | ||
408 | bool has_reset; | ||
409 | }; | ||
410 | |||
411 | static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { | ||
412 | .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, | ||
413 | }; | ||
414 | |||
415 | static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { | ||
416 | .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, | ||
417 | .has_reset = true, | ||
418 | }; | ||
419 | |||
406 | static const struct of_device_id sun4i_spdif_of_match[] = { | 420 | static 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 | }; |
411 | MODULE_DEVICE_TABLE(of, sun4i_spdif_of_match); | 431 | MODULE_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; |