aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2016-11-25 07:34:40 -0500
committerMark Brown <broonie@kernel.org>2016-11-30 13:06:51 -0500
commit4a15b24a65f13778f7616ad0a65be78d8ec0b45a (patch)
tree6ae66439832fbe7b0ac5ea5aac8de2b46d47db1a
parentdac5f86bc9e60eae87a28512f025362d1e2574e3 (diff)
ASoC: sun4i-codec: Add support for H3 codec
The codec on the H3 is similar to the one found on the A31. One key difference is the analog path controls are routed through the PRCM block. This is supported by the sun8i-codec-analog driver, and tied into this codec driver with the audio card's aux_dev. In addition, the H3 has no HP (headphone) and HBIAS support, and no MIC3 input. The FIFO related registers are slightly rearranged. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/sun4i-codec.txt3
-rw-r--r--sound/soc/sunxi/sun4i-codec.c71
2 files changed, 74 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
index f7a548b604fc..3033bd8aab0f 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
@@ -6,6 +6,7 @@ Required properties:
6 - "allwinner,sun6i-a31-codec" 6 - "allwinner,sun6i-a31-codec"
7 - "allwinner,sun7i-a20-codec" 7 - "allwinner,sun7i-a20-codec"
8 - "allwinner,sun8i-a23-codec" 8 - "allwinner,sun8i-a23-codec"
9 - "allwinner,sun8i-h3-codec"
9- reg: must contain the registers location and length 10- reg: must contain the registers location and length
10- interrupts: must contain the codec interrupt 11- interrupts: must contain the codec interrupt
11- dmas: DMA channels for tx and rx dma. See the DMA client binding, 12- dmas: DMA channels for tx and rx dma. See the DMA client binding,
@@ -23,6 +24,7 @@ Optional properties:
23Required properties for the following compatibles: 24Required properties for the following compatibles:
24 - "allwinner,sun6i-a31-codec" 25 - "allwinner,sun6i-a31-codec"
25 - "allwinner,sun8i-a23-codec" 26 - "allwinner,sun8i-a23-codec"
27 - "allwinner,sun8i-h3-codec"
26- resets: phandle to the reset control for this device 28- resets: phandle to the reset control for this device
27- allwinner,audio-routing: A list of the connections between audio components. 29- allwinner,audio-routing: A list of the connections between audio components.
28 Each entry is a pair of strings, the first being the 30 Each entry is a pair of strings, the first being the
@@ -52,6 +54,7 @@ Required properties for the following compatibles:
52 54
53Required properties for the following compatibles: 55Required properties for the following compatibles:
54 - "allwinner,sun8i-a23-codec" 56 - "allwinner,sun8i-a23-codec"
57 - "allwinner,sun8i-h3-codec"
55- allwinner,codec-analog-controls: A phandle to the codec analog controls 58- allwinner,codec-analog-controls: A phandle to the codec analog controls
56 block in the PRCM. 59 block in the PRCM.
57 60
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index ada5fa055950..848af01692a0 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -217,6 +217,13 @@
217#define SUN8I_A23_CODEC_DAC_TXCNT (0x1c) 217#define SUN8I_A23_CODEC_DAC_TXCNT (0x1c)
218#define SUN8I_A23_CODEC_ADC_RXCNT (0x20) 218#define SUN8I_A23_CODEC_ADC_RXCNT (0x20)
219 219
220/* TX FIFO moved on H3 */
221#define SUN8I_H3_CODEC_DAC_TXDATA (0x20)
222#define SUN8I_H3_CODEC_DAC_DBG (0x48)
223#define SUN8I_H3_CODEC_ADC_DBG (0x4c)
224
225/* TODO H3 DAP (Digital Audio Processing) bits */
226
220struct sun4i_codec { 227struct sun4i_codec {
221 struct device *dev; 228 struct device *dev;
222 struct regmap *regmap; 229 struct regmap *regmap;
@@ -1293,6 +1300,44 @@ static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
1293 return card; 1300 return card;
1294}; 1301};
1295 1302
1303static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev)
1304{
1305 struct snd_soc_card *card;
1306 int ret;
1307
1308 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1309 if (!card)
1310 return ERR_PTR(-ENOMEM);
1311
1312 aux_dev.codec_of_node = of_parse_phandle(dev->of_node,
1313 "allwinner,codec-analog-controls",
1314 0);
1315 if (!aux_dev.codec_of_node) {
1316 dev_err(dev, "Can't find analog controls for codec.\n");
1317 return ERR_PTR(-EINVAL);
1318 };
1319
1320 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1321 if (!card->dai_link)
1322 return ERR_PTR(-ENOMEM);
1323
1324 card->dev = dev;
1325 card->name = "H3 Audio Codec";
1326 card->dapm_widgets = sun6i_codec_card_dapm_widgets;
1327 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1328 card->dapm_routes = sun8i_codec_card_routes;
1329 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
1330 card->aux_dev = &aux_dev;
1331 card->num_aux_devs = 1;
1332 card->fully_routed = true;
1333
1334 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1335 if (ret)
1336 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1337
1338 return card;
1339};
1340
1296static const struct regmap_config sun4i_codec_regmap_config = { 1341static const struct regmap_config sun4i_codec_regmap_config = {
1297 .reg_bits = 32, 1342 .reg_bits = 32,
1298 .reg_stride = 4, 1343 .reg_stride = 4,
@@ -1321,6 +1366,13 @@ static const struct regmap_config sun8i_a23_codec_regmap_config = {
1321 .max_register = SUN8I_A23_CODEC_ADC_RXCNT, 1366 .max_register = SUN8I_A23_CODEC_ADC_RXCNT,
1322}; 1367};
1323 1368
1369static const struct regmap_config sun8i_h3_codec_regmap_config = {
1370 .reg_bits = 32,
1371 .reg_stride = 4,
1372 .val_bits = 32,
1373 .max_register = SUN8I_H3_CODEC_ADC_DBG,
1374};
1375
1324struct sun4i_codec_quirks { 1376struct sun4i_codec_quirks {
1325 const struct regmap_config *regmap_config; 1377 const struct regmap_config *regmap_config;
1326 const struct snd_soc_codec_driver *codec; 1378 const struct snd_soc_codec_driver *codec;
@@ -1369,6 +1421,21 @@ static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = {
1369 .has_reset = true, 1421 .has_reset = true,
1370}; 1422};
1371 1423
1424static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = {
1425 .regmap_config = &sun8i_h3_codec_regmap_config,
1426 /*
1427 * TODO Share the codec structure with A23 for now.
1428 * This should be split out when adding digital audio
1429 * processing support for the H3.
1430 */
1431 .codec = &sun8i_a23_codec_codec,
1432 .create_card = sun8i_h3_codec_create_card,
1433 .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
1434 .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
1435 .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
1436 .has_reset = true,
1437};
1438
1372static const struct of_device_id sun4i_codec_of_match[] = { 1439static const struct of_device_id sun4i_codec_of_match[] = {
1373 { 1440 {
1374 .compatible = "allwinner,sun4i-a10-codec", 1441 .compatible = "allwinner,sun4i-a10-codec",
@@ -1386,6 +1453,10 @@ static const struct of_device_id sun4i_codec_of_match[] = {
1386 .compatible = "allwinner,sun8i-a23-codec", 1453 .compatible = "allwinner,sun8i-a23-codec",
1387 .data = &sun8i_a23_codec_quirks, 1454 .data = &sun8i_a23_codec_quirks,
1388 }, 1455 },
1456 {
1457 .compatible = "allwinner,sun8i-h3-codec",
1458 .data = &sun8i_h3_codec_quirks,
1459 },
1389 {} 1460 {}
1390}; 1461};
1391MODULE_DEVICE_TABLE(of, sun4i_codec_of_match); 1462MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);