Skip to content

Commit 2ad6f30

Browse files
Mylène Josserandbroonie
authored andcommitted
ASoC: sun4i-i2s: Add quirks to handle a31 compatible
Some SoCs have a reset line that must be asserted/deasserted. This patch adds a quirk to handle the new compatible "allwinner,sun6i-a31-i2s" which will deassert the reset line on probe function and assert it on remove's one. This new compatible is useful in case of A33 codec driver, for example. Signed-off-by: Mylène Josserand <[email protected]> Acked-by: Maxime Ripard <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 164e372 commit 2ad6f30

File tree

1 file changed

+55
-2
lines changed

1 file changed

+55
-2
lines changed

sound/soc/sunxi/sun4i-i2s.c

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
#include <linux/clk.h>
1515
#include <linux/dmaengine.h>
1616
#include <linux/module.h>
17+
#include <linux/of_device.h>
1718
#include <linux/platform_device.h>
1819
#include <linux/pm_runtime.h>
1920
#include <linux/regmap.h>
21+
#include <linux/reset.h>
2022

2123
#include <sound/dmaengine_pcm.h>
2224
#include <sound/pcm_params.h>
@@ -92,6 +94,7 @@ struct sun4i_i2s {
9294
struct clk *bus_clk;
9395
struct clk *mod_clk;
9496
struct regmap *regmap;
97+
struct reset_control *rst;
9598

9699
unsigned int mclk_freq;
97100

@@ -651,9 +654,22 @@ static int sun4i_i2s_runtime_suspend(struct device *dev)
651654
return 0;
652655
}
653656

657+
struct sun4i_i2s_quirks {
658+
bool has_reset;
659+
};
660+
661+
static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
662+
.has_reset = false,
663+
};
664+
665+
static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
666+
.has_reset = true,
667+
};
668+
654669
static int sun4i_i2s_probe(struct platform_device *pdev)
655670
{
656671
struct sun4i_i2s *i2s;
672+
const struct sun4i_i2s_quirks *quirks;
657673
struct resource *res;
658674
void __iomem *regs;
659675
int irq, ret;
@@ -674,6 +690,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
674690
return irq;
675691
}
676692

693+
quirks = of_device_get_match_data(&pdev->dev);
694+
if (!quirks) {
695+
dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
696+
return -ENODEV;
697+
}
698+
677699
i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
678700
if (IS_ERR(i2s->bus_clk)) {
679701
dev_err(&pdev->dev, "Can't get our bus clock\n");
@@ -692,7 +714,24 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
692714
dev_err(&pdev->dev, "Can't get our mod clock\n");
693715
return PTR_ERR(i2s->mod_clk);
694716
}
695-
717+
718+
if (quirks->has_reset) {
719+
i2s->rst = devm_reset_control_get(&pdev->dev, NULL);
720+
if (IS_ERR(i2s->rst)) {
721+
dev_err(&pdev->dev, "Failed to get reset control\n");
722+
return PTR_ERR(i2s->rst);
723+
}
724+
}
725+
726+
if (!IS_ERR(i2s->rst)) {
727+
ret = reset_control_deassert(i2s->rst);
728+
if (ret) {
729+
dev_err(&pdev->dev,
730+
"Failed to deassert the reset control\n");
731+
return -EINVAL;
732+
}
733+
}
734+
696735
i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
697736
i2s->playback_dma_data.maxburst = 4;
698737

@@ -727,23 +766,37 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
727766
sun4i_i2s_runtime_suspend(&pdev->dev);
728767
err_pm_disable:
729768
pm_runtime_disable(&pdev->dev);
769+
if (!IS_ERR(i2s->rst))
770+
reset_control_assert(i2s->rst);
730771

731772
return ret;
732773
}
733774

734775
static int sun4i_i2s_remove(struct platform_device *pdev)
735776
{
777+
struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
778+
736779
snd_dmaengine_pcm_unregister(&pdev->dev);
737780

738781
pm_runtime_disable(&pdev->dev);
739782
if (!pm_runtime_status_suspended(&pdev->dev))
740783
sun4i_i2s_runtime_suspend(&pdev->dev);
741784

785+
if (!IS_ERR(i2s->rst))
786+
reset_control_assert(i2s->rst);
787+
742788
return 0;
743789
}
744790

745791
static const struct of_device_id sun4i_i2s_match[] = {
746-
{ .compatible = "allwinner,sun4i-a10-i2s", },
792+
{
793+
.compatible = "allwinner,sun4i-a10-i2s",
794+
.data = &sun4i_a10_i2s_quirks,
795+
},
796+
{
797+
.compatible = "allwinner,sun6i-a31-i2s",
798+
.data = &sun6i_a31_i2s_quirks,
799+
},
747800
{}
748801
};
749802
MODULE_DEVICE_TABLE(of, sun4i_i2s_match);

0 commit comments

Comments
 (0)