aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sunxi/sun4i-codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sunxi/sun4i-codec.c')
-rw-r--r--sound/soc/sunxi/sun4i-codec.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 735115244b17..6379efd21f00 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -30,6 +30,7 @@
30#include <linux/of_platform.h> 30#include <linux/of_platform.h>
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/regmap.h> 32#include <linux/regmap.h>
33#include <linux/reset.h>
33#include <linux/gpio/consumer.h> 34#include <linux/gpio/consumer.h>
34 35
35#include <sound/core.h> 36#include <sound/core.h>
@@ -217,6 +218,7 @@ struct sun4i_codec {
217 struct regmap *regmap; 218 struct regmap *regmap;
218 struct clk *clk_apb; 219 struct clk *clk_apb;
219 struct clk *clk_module; 220 struct clk *clk_module;
221 struct reset_control *rst;
220 struct gpio_desc *gpio_pa; 222 struct gpio_desc *gpio_pa;
221 223
222 /* ADC_FIFOC register is at different offset on different SoCs */ 224 /* ADC_FIFOC register is at different offset on different SoCs */
@@ -1232,6 +1234,7 @@ struct sun4i_codec_quirks {
1232 struct reg_field reg_adc_fifoc; /* used for regmap_field */ 1234 struct reg_field reg_adc_fifoc; /* used for regmap_field */
1233 unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ 1235 unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
1234 unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */ 1236 unsigned int reg_adc_rxdata; /* RX FIFO offset for DMA config */
1237 bool has_reset;
1235}; 1238};
1236 1239
1237static const struct sun4i_codec_quirks sun4i_codec_quirks = { 1240static const struct sun4i_codec_quirks sun4i_codec_quirks = {
@@ -1327,6 +1330,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
1327 return PTR_ERR(scodec->clk_module); 1330 return PTR_ERR(scodec->clk_module);
1328 } 1331 }
1329 1332
1333 if (quirks->has_reset) {
1334 scodec->rst = devm_reset_control_get(&pdev->dev, NULL);
1335 if (IS_ERR(scodec->rst)) {
1336 dev_err(&pdev->dev, "Failed to get reset control\n");
1337 return PTR_ERR(scodec->rst);
1338 }
1339 };
1340
1330 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa", 1341 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
1331 GPIOD_OUT_LOW); 1342 GPIOD_OUT_LOW);
1332 if (IS_ERR(scodec->gpio_pa)) { 1343 if (IS_ERR(scodec->gpio_pa)) {
@@ -1353,6 +1364,16 @@ static int sun4i_codec_probe(struct platform_device *pdev)
1353 return -EINVAL; 1364 return -EINVAL;
1354 } 1365 }
1355 1366
1367 /* Deassert the reset control */
1368 if (scodec->rst) {
1369 ret = reset_control_deassert(scodec->rst);
1370 if (ret) {
1371 dev_err(&pdev->dev,
1372 "Failed to deassert the reset control\n");
1373 goto err_clk_disable;
1374 }
1375 }
1376
1356 /* DMA configuration for TX FIFO */ 1377 /* DMA configuration for TX FIFO */
1357 scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata; 1378 scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
1358 scodec->playback_dma_data.maxburst = 8; 1379 scodec->playback_dma_data.maxburst = 8;
@@ -1367,7 +1388,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
1367 &sun4i_codec_dai, 1); 1388 &sun4i_codec_dai, 1);
1368 if (ret) { 1389 if (ret) {
1369 dev_err(&pdev->dev, "Failed to register our codec\n"); 1390 dev_err(&pdev->dev, "Failed to register our codec\n");
1370 goto err_clk_disable; 1391 goto err_assert_reset;
1371 } 1392 }
1372 1393
1373 ret = devm_snd_soc_register_component(&pdev->dev, 1394 ret = devm_snd_soc_register_component(&pdev->dev,
@@ -1404,6 +1425,9 @@ static int sun4i_codec_probe(struct platform_device *pdev)
1404 1425
1405err_unregister_codec: 1426err_unregister_codec:
1406 snd_soc_unregister_codec(&pdev->dev); 1427 snd_soc_unregister_codec(&pdev->dev);
1428err_assert_reset:
1429 if (scodec->rst)
1430 reset_control_assert(scodec->rst);
1407err_clk_disable: 1431err_clk_disable:
1408 clk_disable_unprepare(scodec->clk_apb); 1432 clk_disable_unprepare(scodec->clk_apb);
1409 return ret; 1433 return ret;
@@ -1416,6 +1440,8 @@ static int sun4i_codec_remove(struct platform_device *pdev)
1416 1440
1417 snd_soc_unregister_card(card); 1441 snd_soc_unregister_card(card);
1418 snd_soc_unregister_codec(&pdev->dev); 1442 snd_soc_unregister_codec(&pdev->dev);
1443 if (scodec->rst)
1444 reset_control_assert(scodec->rst);
1419 clk_disable_unprepare(scodec->clk_apb); 1445 clk_disable_unprepare(scodec->clk_apb);
1420 1446
1421 return 0; 1447 return 0;