Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: rsnd: add R-Car Gen4 Sound support

This patch is tested on V4H White Hawk + ARD-AUDIO-DA7212

Signed-off-by: Linh Phung <linh.phung.jy@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o7qe5ej5.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Kuninori Morimoto and committed by
Mark Brown
c2bc6527 f76fec60

+140 -6
+10
sound/soc/sh/rcar/adg.c
··· 57 57 i++) 58 58 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 59 59 60 + static const char * const clkin_name_gen4[] = { 61 + [CLKA] = "clkin", 62 + }; 63 + 60 64 static const char * const clkin_name_gen2[] = { 61 65 [CLKA] = "clk_a", 62 66 [CLKB] = "clk_b", ··· 439 435 440 436 clkin_name = clkin_name_gen2; 441 437 clkin_size = ARRAY_SIZE(clkin_name_gen2); 438 + if (rsnd_is_gen4(priv)) { 439 + clkin_name = clkin_name_gen4; 440 + clkin_size = ARRAY_SIZE(clkin_name_gen4); 441 + } 442 442 443 443 for (i = 0; i < clkin_size; i++) { 444 444 clk = devm_clk_get(dev, clkin_name[i]); ··· 576 568 577 569 clkout_name = clkout_name_gen2; 578 570 clkout_size = ARRAY_SIZE(clkout_name_gen2); 571 + if (rsnd_is_gen4(priv)) 572 + clkout_size = 1; /* reuse clkout_name_gen2[] */ 579 573 580 574 /* 581 575 * ADG supports BRRA/BRRB output only.
+3 -2
sound/soc/sh/rcar/core.c
··· 102 102 { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, 103 103 { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, 104 104 { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN3 }, 105 + { .compatible = "renesas,rcar_sound-gen4", .data = (void *)RSND_GEN4 }, 105 106 /* Special Handling */ 106 107 { .compatible = "renesas,rcar_sound-r8a77990", .data = (void *)(RSND_GEN3 | RSND_SOC_E) }, 107 108 {}, ··· 1468 1467 if (is_graph) { 1469 1468 for_each_endpoint_of_node(dai_node, dai_np) { 1470 1469 __rsnd_dai_probe(priv, dai_np, dai_i); 1471 - if (rsnd_is_gen3(priv)) { 1470 + if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) { 1472 1471 rdai = rsnd_rdai_get(priv, dai_i); 1473 1472 1474 1473 rsnd_parse_connect_graph(priv, &rdai->playback, dai_np); ··· 1479 1478 } else { 1480 1479 for_each_child_of_node(dai_node, dai_np) { 1481 1480 __rsnd_dai_probe(priv, dai_np, dai_i); 1482 - if (rsnd_is_gen3(priv)) { 1481 + if (rsnd_is_gen3(priv) || rsnd_is_gen4(priv)) { 1483 1482 rdai = rsnd_rdai_get(priv, dai_i); 1484 1483 1485 1484 rsnd_parse_connect_simple(priv, &rdai->playback, dai_np);
+37 -1
sound/soc/sh/rcar/dma.c
··· 653 653 dma_addrs[is_ssi][is_play][use_src + use_cmd].in_addr; 654 654 } 655 655 656 + /* 657 + * Gen4 DMA read/write register offset 658 + * 659 + * ex) R-Car V4H case 660 + * mod / SYS-DMAC in / SYS-DMAC out 661 + * SSI_SDMC: 0xec400000 / 0xec400000 / 0xec400000 662 + */ 663 + #define RDMA_SSI_SDMC(addr, i) (addr + (0x8000 * i)) 664 + static dma_addr_t 665 + rsnd_gen4_dma_addr(struct rsnd_dai_stream *io, struct rsnd_mod *mod, 666 + int is_play, int is_from) 667 + { 668 + struct rsnd_priv *priv = rsnd_io_to_priv(io); 669 + phys_addr_t addr = rsnd_gen_get_phy_addr(priv, RSND_GEN4_SDMC); 670 + int id = rsnd_mod_id(mod); 671 + int busif = rsnd_mod_id_sub(mod); 672 + 673 + /* 674 + * SSI0 only is supported 675 + */ 676 + if (id != 0) { 677 + struct device *dev = rsnd_priv_to_dev(priv); 678 + 679 + dev_err(dev, "This driver doesn't support non SSI0"); 680 + return -EINVAL; 681 + } 682 + 683 + return RDMA_SSI_SDMC(addr, busif); 684 + } 685 + 656 686 static dma_addr_t rsnd_dma_addr(struct rsnd_dai_stream *io, 657 687 struct rsnd_mod *mod, 658 688 int is_play, int is_from) ··· 697 667 */ 698 668 if (rsnd_is_gen1(priv)) 699 669 return 0; 670 + else if (rsnd_is_gen4(priv)) 671 + return rsnd_gen4_dma_addr(io, mod, is_play, is_from); 700 672 else 701 673 return rsnd_gen2_dma_addr(io, mod, is_play, is_from); 702 674 } ··· 923 891 return 0; /* it will be PIO mode */ 924 892 } 925 893 894 + /* for Gen4 doesn't have DMA-pp */ 895 + if (rsnd_is_gen4(priv)) 896 + goto audmapp_end; 897 + 926 898 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp"); 927 899 if (!res) { 928 900 dev_err(dev, "lack of audmapp in DT\n"); ··· 938 902 dmac->ppbase = devm_ioremap_resource(dev, res); 939 903 if (IS_ERR(dmac->ppbase)) 940 904 return PTR_ERR(dmac->ppbase); 941 - 905 + audmapp_end: 942 906 priv->dma = dmac; 943 907 944 908 /* dummy mem mod for debug */
+70
sound/soc/sh/rcar/gen.c
··· 216 216 } 217 217 218 218 /* 219 + * Gen4 220 + */ 221 + static int rsnd_gen4_probe(struct rsnd_priv *priv) 222 + { 223 + static const struct rsnd_regmap_field_conf conf_ssiu[] = { 224 + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE0, 0x850), 225 + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE2, 0x858), 226 + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE4, 0x890), 227 + RSND_GEN_S_REG(SSI_SYS_INT_ENABLE6, 0x898), 228 + RSND_GEN_S_REG(SSI_SYS_STATUS0, 0x840), 229 + RSND_GEN_S_REG(SSI_SYS_STATUS2, 0x848), 230 + RSND_GEN_S_REG(SSI_SYS_STATUS4, 0x880), 231 + RSND_GEN_S_REG(SSI_SYS_STATUS6, 0x888), 232 + 233 + RSND_GEN_S_REG(SSI_BUSIF0_MODE, 0x0), 234 + RSND_GEN_S_REG(SSI_BUSIF0_ADINR, 0x4), 235 + RSND_GEN_S_REG(SSI_BUSIF0_DALIGN, 0x8), 236 + RSND_GEN_S_REG(SSI_BUSIF1_MODE, 0x20), 237 + RSND_GEN_S_REG(SSI_BUSIF1_ADINR, 0x24), 238 + RSND_GEN_S_REG(SSI_BUSIF1_DALIGN, 0x28), 239 + RSND_GEN_S_REG(SSI_BUSIF2_MODE, 0x40), 240 + RSND_GEN_S_REG(SSI_BUSIF2_ADINR, 0x44), 241 + RSND_GEN_S_REG(SSI_BUSIF2_DALIGN, 0x48), 242 + RSND_GEN_S_REG(SSI_BUSIF3_MODE, 0x60), 243 + RSND_GEN_S_REG(SSI_BUSIF3_ADINR, 0x64), 244 + RSND_GEN_S_REG(SSI_BUSIF3_DALIGN, 0x68), 245 + RSND_GEN_S_REG(SSI_BUSIF4_MODE, 0x500), 246 + RSND_GEN_S_REG(SSI_BUSIF4_ADINR, 0x504), 247 + RSND_GEN_S_REG(SSI_BUSIF4_DALIGN, 0x508), 248 + RSND_GEN_S_REG(SSI_BUSIF5_MODE, 0x520), 249 + RSND_GEN_S_REG(SSI_BUSIF5_ADINR, 0x524), 250 + RSND_GEN_S_REG(SSI_BUSIF5_DALIGN, 0x528), 251 + RSND_GEN_S_REG(SSI_BUSIF6_MODE, 0x540), 252 + RSND_GEN_S_REG(SSI_BUSIF6_ADINR, 0x544), 253 + RSND_GEN_S_REG(SSI_BUSIF6_DALIGN, 0x548), 254 + RSND_GEN_S_REG(SSI_BUSIF7_MODE, 0x560), 255 + RSND_GEN_S_REG(SSI_BUSIF7_ADINR, 0x564), 256 + RSND_GEN_S_REG(SSI_BUSIF7_DALIGN, 0x568), 257 + RSND_GEN_S_REG(SSI_CTRL, 0x010), 258 + RSND_GEN_S_REG(SSI_INT_ENABLE, 0x018), 259 + RSND_GEN_S_REG(SSI_MODE, 0x00c), 260 + RSND_GEN_S_REG(SSI_MODE2, 0xa0c), 261 + }; 262 + static const struct rsnd_regmap_field_conf conf_adg[] = { 263 + RSND_GEN_S_REG(BRRA, 0x00), 264 + RSND_GEN_S_REG(BRRB, 0x04), 265 + RSND_GEN_S_REG(BRGCKR, 0x08), 266 + RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 267 + }; 268 + static const struct rsnd_regmap_field_conf conf_ssi[] = { 269 + RSND_GEN_S_REG(SSICR, 0x00), 270 + RSND_GEN_S_REG(SSISR, 0x04), 271 + RSND_GEN_S_REG(SSITDR, 0x08), 272 + RSND_GEN_S_REG(SSIRDR, 0x0c), 273 + RSND_GEN_S_REG(SSIWSR, 0x20), 274 + }; 275 + static const struct rsnd_regmap_field_conf conf_sdmc[] = { 276 + RSND_GEN_M_REG(SSI_BUSIF, 0x0, 0x8000), 277 + }; 278 + int ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_ADG, "adg", conf_adg); 279 + int ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SSIU, "ssiu", conf_ssiu); 280 + int ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SSI, "ssi", conf_ssi); 281 + int ret_sdmc = rsnd_gen_regmap_init(priv, 10, RSND_GEN4_SDMC, "sdmc", conf_sdmc); 282 + 283 + return ret_adg | ret_ssiu | ret_ssi | ret_sdmc; 284 + } 285 + 286 + /* 219 287 * Gen2 220 288 */ 221 289 static int rsnd_gen2_probe(struct rsnd_priv *priv) ··· 552 484 else if (rsnd_is_gen2(priv) || 553 485 rsnd_is_gen3(priv)) 554 486 ret = rsnd_gen2_probe(priv); 487 + else if (rsnd_is_gen4(priv)) 488 + ret = rsnd_gen4_probe(priv); 555 489 556 490 if (ret < 0) 557 491 dev_err(dev, "unknown generation R-Car sound device\n");
+8
sound/soc/sh/rcar/rsnd.h
··· 31 31 #define RSND_GEN2_SSIU 2 32 32 #define RSND_GEN2_SSI 3 33 33 34 + #define RSND_GEN4_ADG 0 35 + #define RSND_GEN4_SSIU 1 36 + #define RSND_GEN4_SSI 2 37 + #define RSND_GEN4_SDMC 3 38 + 34 39 #define RSND_BASE_MAX 4 35 40 36 41 /* ··· 202 197 SSI_SYS_INT_ENABLE5, 203 198 SSI_SYS_INT_ENABLE6, 204 199 SSI_SYS_INT_ENABLE7, 200 + SSI_BUSIF, 205 201 HDMI0_SEL, 206 202 HDMI1_SEL, 207 203 SSI9_BUSIF0_MODE, ··· 635 629 #define RSND_GEN1 (1 << 0) 636 630 #define RSND_GEN2 (2 << 0) 637 631 #define RSND_GEN3 (3 << 0) 632 + #define RSND_GEN4 (4 << 0) 638 633 #define RSND_SOC_MASK (0xFF << 4) 639 634 #define RSND_SOC_E (1 << 4) /* E1/E2/E3 */ 640 635 ··· 710 703 #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) 711 704 #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) 712 705 #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) 706 + #define rsnd_is_gen4(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN4) 713 707 #define rsnd_is_e3(priv) (((priv)->flags & \ 714 708 (RSND_GEN_MASK | RSND_SOC_MASK)) == \ 715 709 (RSND_GEN3 | RSND_SOC_E))
+12 -3
sound/soc/sh/rcar/ssiu.c
··· 29 29 i++) 30 30 31 31 /* 32 - * SSI Gen2 Gen3 33 - * 0 BUSIF0-3 BUSIF0-7 32 + * SSI Gen2 Gen3 Gen4 33 + * 0 BUSIF0-3 BUSIF0-7 BUSIF0-7 34 34 * 1 BUSIF0-3 BUSIF0-7 35 35 * 2 BUSIF0-3 BUSIF0-7 36 36 * 3 BUSIF0 BUSIF0-7 ··· 40 40 * 7 BUSIF0 BUSIF0 41 41 * 8 BUSIF0 BUSIF0 42 42 * 9 BUSIF0-3 BUSIF0-7 43 - * total 22 52 43 + * total 22 52 8 44 44 */ 45 45 static const int gen2_id[] = { 0, 4, 8, 12, 13, 14, 15, 16, 17, 18 }; 46 46 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 }; 47 + static const int gen4_id[] = { 0 }; 47 48 48 49 /* enable busif buffer over/under run interrupt. */ 49 50 #define rsnd_ssiu_busif_err_irq_enable(mod) rsnd_ssiu_busif_err_irq_ctrl(mod, 1) ··· 153 152 /* clear status */ 154 153 rsnd_ssiu_busif_err_status_clear(mod); 155 154 155 + /* Gen4 doesn't have SSI_MODE */ 156 + if (rsnd_is_gen4(priv)) 157 + goto ssi_mode_setting_end; 158 + 156 159 /* 157 160 * SSI_MODE0 158 161 */ ··· 211 206 rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1); 212 207 rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2); 213 208 209 + ssi_mode_setting_end: 214 210 /* 215 211 * Enable busif buffer over/under run interrupt. 216 212 * It will be handled from ssi.c ··· 559 553 } else if (rsnd_is_gen3(priv)) { 560 554 list = gen3_id; 561 555 nr = ARRAY_SIZE(gen3_id); 556 + } else if (rsnd_is_gen4(priv)) { 557 + list = gen4_id; 558 + nr = ARRAY_SIZE(gen4_id); 562 559 } else { 563 560 dev_err(dev, "unknown SSIU\n"); 564 561 return -ENODEV;