1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun // 3*4882a593Smuzhiyun // Renesas R-Car 4*4882a593Smuzhiyun // 5*4882a593Smuzhiyun // Copyright (C) 2013 Renesas Solutions Corp. 6*4882a593Smuzhiyun // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #ifndef RSND_H 9*4882a593Smuzhiyun #define RSND_H 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include <linux/clk.h> 12*4882a593Smuzhiyun #include <linux/device.h> 13*4882a593Smuzhiyun #include <linux/dma-mapping.h> 14*4882a593Smuzhiyun #include <linux/io.h> 15*4882a593Smuzhiyun #include <linux/list.h> 16*4882a593Smuzhiyun #include <linux/module.h> 17*4882a593Smuzhiyun #include <linux/of_device.h> 18*4882a593Smuzhiyun #include <linux/of_graph.h> 19*4882a593Smuzhiyun #include <linux/of_irq.h> 20*4882a593Smuzhiyun #include <linux/sh_dma.h> 21*4882a593Smuzhiyun #include <linux/workqueue.h> 22*4882a593Smuzhiyun #include <sound/soc.h> 23*4882a593Smuzhiyun #include <sound/pcm_params.h> 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #define RSND_GEN1_SRU 0 26*4882a593Smuzhiyun #define RSND_GEN1_ADG 1 27*4882a593Smuzhiyun #define RSND_GEN1_SSI 2 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define RSND_GEN2_SCU 0 30*4882a593Smuzhiyun #define RSND_GEN2_ADG 1 31*4882a593Smuzhiyun #define RSND_GEN2_SSIU 2 32*4882a593Smuzhiyun #define RSND_GEN2_SSI 3 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun #define RSND_BASE_MAX 4 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun /* 37*4882a593Smuzhiyun * pseudo register 38*4882a593Smuzhiyun * 39*4882a593Smuzhiyun * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different. 40*4882a593Smuzhiyun * This driver uses pseudo register in order to hide it. 41*4882a593Smuzhiyun * see gen1/gen2 for detail 42*4882a593Smuzhiyun */ 43*4882a593Smuzhiyun enum rsnd_reg { 44*4882a593Smuzhiyun /* SCU (MIX/CTU/DVC) */ 45*4882a593Smuzhiyun SRC_I_BUSIF_MODE, 46*4882a593Smuzhiyun SRC_O_BUSIF_MODE, 47*4882a593Smuzhiyun SRC_ROUTE_MODE0, 48*4882a593Smuzhiyun SRC_SWRSR, 49*4882a593Smuzhiyun SRC_SRCIR, 50*4882a593Smuzhiyun SRC_ADINR, 51*4882a593Smuzhiyun SRC_IFSCR, 52*4882a593Smuzhiyun SRC_IFSVR, 53*4882a593Smuzhiyun SRC_SRCCR, 54*4882a593Smuzhiyun SRC_CTRL, 55*4882a593Smuzhiyun SRC_BSDSR, 56*4882a593Smuzhiyun SRC_BSISR, 57*4882a593Smuzhiyun SRC_INT_ENABLE0, 58*4882a593Smuzhiyun SRC_BUSIF_DALIGN, 59*4882a593Smuzhiyun SRCIN_TIMSEL0, 60*4882a593Smuzhiyun SRCIN_TIMSEL1, 61*4882a593Smuzhiyun SRCIN_TIMSEL2, 62*4882a593Smuzhiyun SRCIN_TIMSEL3, 63*4882a593Smuzhiyun SRCIN_TIMSEL4, 64*4882a593Smuzhiyun SRCOUT_TIMSEL0, 65*4882a593Smuzhiyun SRCOUT_TIMSEL1, 66*4882a593Smuzhiyun SRCOUT_TIMSEL2, 67*4882a593Smuzhiyun SRCOUT_TIMSEL3, 68*4882a593Smuzhiyun SRCOUT_TIMSEL4, 69*4882a593Smuzhiyun SCU_SYS_STATUS0, 70*4882a593Smuzhiyun SCU_SYS_STATUS1, 71*4882a593Smuzhiyun SCU_SYS_INT_EN0, 72*4882a593Smuzhiyun SCU_SYS_INT_EN1, 73*4882a593Smuzhiyun CMD_CTRL, 74*4882a593Smuzhiyun CMD_BUSIF_MODE, 75*4882a593Smuzhiyun CMD_BUSIF_DALIGN, 76*4882a593Smuzhiyun CMD_ROUTE_SLCT, 77*4882a593Smuzhiyun CMDOUT_TIMSEL, 78*4882a593Smuzhiyun CTU_SWRSR, 79*4882a593Smuzhiyun CTU_CTUIR, 80*4882a593Smuzhiyun CTU_ADINR, 81*4882a593Smuzhiyun CTU_CPMDR, 82*4882a593Smuzhiyun CTU_SCMDR, 83*4882a593Smuzhiyun CTU_SV00R, 84*4882a593Smuzhiyun CTU_SV01R, 85*4882a593Smuzhiyun CTU_SV02R, 86*4882a593Smuzhiyun CTU_SV03R, 87*4882a593Smuzhiyun CTU_SV04R, 88*4882a593Smuzhiyun CTU_SV05R, 89*4882a593Smuzhiyun CTU_SV06R, 90*4882a593Smuzhiyun CTU_SV07R, 91*4882a593Smuzhiyun CTU_SV10R, 92*4882a593Smuzhiyun CTU_SV11R, 93*4882a593Smuzhiyun CTU_SV12R, 94*4882a593Smuzhiyun CTU_SV13R, 95*4882a593Smuzhiyun CTU_SV14R, 96*4882a593Smuzhiyun CTU_SV15R, 97*4882a593Smuzhiyun CTU_SV16R, 98*4882a593Smuzhiyun CTU_SV17R, 99*4882a593Smuzhiyun CTU_SV20R, 100*4882a593Smuzhiyun CTU_SV21R, 101*4882a593Smuzhiyun CTU_SV22R, 102*4882a593Smuzhiyun CTU_SV23R, 103*4882a593Smuzhiyun CTU_SV24R, 104*4882a593Smuzhiyun CTU_SV25R, 105*4882a593Smuzhiyun CTU_SV26R, 106*4882a593Smuzhiyun CTU_SV27R, 107*4882a593Smuzhiyun CTU_SV30R, 108*4882a593Smuzhiyun CTU_SV31R, 109*4882a593Smuzhiyun CTU_SV32R, 110*4882a593Smuzhiyun CTU_SV33R, 111*4882a593Smuzhiyun CTU_SV34R, 112*4882a593Smuzhiyun CTU_SV35R, 113*4882a593Smuzhiyun CTU_SV36R, 114*4882a593Smuzhiyun CTU_SV37R, 115*4882a593Smuzhiyun MIX_SWRSR, 116*4882a593Smuzhiyun MIX_MIXIR, 117*4882a593Smuzhiyun MIX_ADINR, 118*4882a593Smuzhiyun MIX_MIXMR, 119*4882a593Smuzhiyun MIX_MVPDR, 120*4882a593Smuzhiyun MIX_MDBAR, 121*4882a593Smuzhiyun MIX_MDBBR, 122*4882a593Smuzhiyun MIX_MDBCR, 123*4882a593Smuzhiyun MIX_MDBDR, 124*4882a593Smuzhiyun MIX_MDBER, 125*4882a593Smuzhiyun DVC_SWRSR, 126*4882a593Smuzhiyun DVC_DVUIR, 127*4882a593Smuzhiyun DVC_ADINR, 128*4882a593Smuzhiyun DVC_DVUCR, 129*4882a593Smuzhiyun DVC_ZCMCR, 130*4882a593Smuzhiyun DVC_VOL0R, 131*4882a593Smuzhiyun DVC_VOL1R, 132*4882a593Smuzhiyun DVC_VOL2R, 133*4882a593Smuzhiyun DVC_VOL3R, 134*4882a593Smuzhiyun DVC_VOL4R, 135*4882a593Smuzhiyun DVC_VOL5R, 136*4882a593Smuzhiyun DVC_VOL6R, 137*4882a593Smuzhiyun DVC_VOL7R, 138*4882a593Smuzhiyun DVC_DVUER, 139*4882a593Smuzhiyun DVC_VRCTR, 140*4882a593Smuzhiyun DVC_VRPDR, 141*4882a593Smuzhiyun DVC_VRDBR, 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* ADG */ 144*4882a593Smuzhiyun BRRA, 145*4882a593Smuzhiyun BRRB, 146*4882a593Smuzhiyun BRGCKR, 147*4882a593Smuzhiyun DIV_EN, 148*4882a593Smuzhiyun AUDIO_CLK_SEL0, 149*4882a593Smuzhiyun AUDIO_CLK_SEL1, 150*4882a593Smuzhiyun AUDIO_CLK_SEL2, 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun /* SSIU */ 153*4882a593Smuzhiyun SSI_MODE, 154*4882a593Smuzhiyun SSI_MODE0, 155*4882a593Smuzhiyun SSI_MODE1, 156*4882a593Smuzhiyun SSI_MODE2, 157*4882a593Smuzhiyun SSI_CONTROL, 158*4882a593Smuzhiyun SSI_CTRL, 159*4882a593Smuzhiyun SSI_BUSIF0_MODE, 160*4882a593Smuzhiyun SSI_BUSIF1_MODE, 161*4882a593Smuzhiyun SSI_BUSIF2_MODE, 162*4882a593Smuzhiyun SSI_BUSIF3_MODE, 163*4882a593Smuzhiyun SSI_BUSIF4_MODE, 164*4882a593Smuzhiyun SSI_BUSIF5_MODE, 165*4882a593Smuzhiyun SSI_BUSIF6_MODE, 166*4882a593Smuzhiyun SSI_BUSIF7_MODE, 167*4882a593Smuzhiyun SSI_BUSIF0_ADINR, 168*4882a593Smuzhiyun SSI_BUSIF1_ADINR, 169*4882a593Smuzhiyun SSI_BUSIF2_ADINR, 170*4882a593Smuzhiyun SSI_BUSIF3_ADINR, 171*4882a593Smuzhiyun SSI_BUSIF4_ADINR, 172*4882a593Smuzhiyun SSI_BUSIF5_ADINR, 173*4882a593Smuzhiyun SSI_BUSIF6_ADINR, 174*4882a593Smuzhiyun SSI_BUSIF7_ADINR, 175*4882a593Smuzhiyun SSI_BUSIF0_DALIGN, 176*4882a593Smuzhiyun SSI_BUSIF1_DALIGN, 177*4882a593Smuzhiyun SSI_BUSIF2_DALIGN, 178*4882a593Smuzhiyun SSI_BUSIF3_DALIGN, 179*4882a593Smuzhiyun SSI_BUSIF4_DALIGN, 180*4882a593Smuzhiyun SSI_BUSIF5_DALIGN, 181*4882a593Smuzhiyun SSI_BUSIF6_DALIGN, 182*4882a593Smuzhiyun SSI_BUSIF7_DALIGN, 183*4882a593Smuzhiyun SSI_INT_ENABLE, 184*4882a593Smuzhiyun SSI_SYS_STATUS0, 185*4882a593Smuzhiyun SSI_SYS_STATUS1, 186*4882a593Smuzhiyun SSI_SYS_STATUS2, 187*4882a593Smuzhiyun SSI_SYS_STATUS3, 188*4882a593Smuzhiyun SSI_SYS_STATUS4, 189*4882a593Smuzhiyun SSI_SYS_STATUS5, 190*4882a593Smuzhiyun SSI_SYS_STATUS6, 191*4882a593Smuzhiyun SSI_SYS_STATUS7, 192*4882a593Smuzhiyun SSI_SYS_INT_ENABLE0, 193*4882a593Smuzhiyun SSI_SYS_INT_ENABLE1, 194*4882a593Smuzhiyun SSI_SYS_INT_ENABLE2, 195*4882a593Smuzhiyun SSI_SYS_INT_ENABLE3, 196*4882a593Smuzhiyun SSI_SYS_INT_ENABLE4, 197*4882a593Smuzhiyun SSI_SYS_INT_ENABLE5, 198*4882a593Smuzhiyun SSI_SYS_INT_ENABLE6, 199*4882a593Smuzhiyun SSI_SYS_INT_ENABLE7, 200*4882a593Smuzhiyun HDMI0_SEL, 201*4882a593Smuzhiyun HDMI1_SEL, 202*4882a593Smuzhiyun SSI9_BUSIF0_MODE, 203*4882a593Smuzhiyun SSI9_BUSIF1_MODE, 204*4882a593Smuzhiyun SSI9_BUSIF2_MODE, 205*4882a593Smuzhiyun SSI9_BUSIF3_MODE, 206*4882a593Smuzhiyun SSI9_BUSIF4_MODE, 207*4882a593Smuzhiyun SSI9_BUSIF5_MODE, 208*4882a593Smuzhiyun SSI9_BUSIF6_MODE, 209*4882a593Smuzhiyun SSI9_BUSIF7_MODE, 210*4882a593Smuzhiyun SSI9_BUSIF0_ADINR, 211*4882a593Smuzhiyun SSI9_BUSIF1_ADINR, 212*4882a593Smuzhiyun SSI9_BUSIF2_ADINR, 213*4882a593Smuzhiyun SSI9_BUSIF3_ADINR, 214*4882a593Smuzhiyun SSI9_BUSIF4_ADINR, 215*4882a593Smuzhiyun SSI9_BUSIF5_ADINR, 216*4882a593Smuzhiyun SSI9_BUSIF6_ADINR, 217*4882a593Smuzhiyun SSI9_BUSIF7_ADINR, 218*4882a593Smuzhiyun SSI9_BUSIF0_DALIGN, 219*4882a593Smuzhiyun SSI9_BUSIF1_DALIGN, 220*4882a593Smuzhiyun SSI9_BUSIF2_DALIGN, 221*4882a593Smuzhiyun SSI9_BUSIF3_DALIGN, 222*4882a593Smuzhiyun SSI9_BUSIF4_DALIGN, 223*4882a593Smuzhiyun SSI9_BUSIF5_DALIGN, 224*4882a593Smuzhiyun SSI9_BUSIF6_DALIGN, 225*4882a593Smuzhiyun SSI9_BUSIF7_DALIGN, 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun /* SSI */ 228*4882a593Smuzhiyun SSICR, 229*4882a593Smuzhiyun SSISR, 230*4882a593Smuzhiyun SSITDR, 231*4882a593Smuzhiyun SSIRDR, 232*4882a593Smuzhiyun SSIWSR, 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun REG_MAX, 235*4882a593Smuzhiyun }; 236*4882a593Smuzhiyun #define SRCIN_TIMSEL(i) (SRCIN_TIMSEL0 + (i)) 237*4882a593Smuzhiyun #define SRCOUT_TIMSEL(i) (SRCOUT_TIMSEL0 + (i)) 238*4882a593Smuzhiyun #define CTU_SVxxR(i, j) (CTU_SV00R + (i * 8) + (j)) 239*4882a593Smuzhiyun #define DVC_VOLxR(i) (DVC_VOL0R + (i)) 240*4882a593Smuzhiyun #define AUDIO_CLK_SEL(i) (AUDIO_CLK_SEL0 + (i)) 241*4882a593Smuzhiyun #define SSI_BUSIF_MODE(i) (SSI_BUSIF0_MODE + (i)) 242*4882a593Smuzhiyun #define SSI_BUSIF_ADINR(i) (SSI_BUSIF0_ADINR + (i)) 243*4882a593Smuzhiyun #define SSI_BUSIF_DALIGN(i) (SSI_BUSIF0_DALIGN + (i)) 244*4882a593Smuzhiyun #define SSI9_BUSIF_MODE(i) (SSI9_BUSIF0_MODE + (i)) 245*4882a593Smuzhiyun #define SSI9_BUSIF_ADINR(i) (SSI9_BUSIF0_ADINR + (i)) 246*4882a593Smuzhiyun #define SSI9_BUSIF_DALIGN(i) (SSI9_BUSIF0_DALIGN + (i)) 247*4882a593Smuzhiyun #define SSI_SYS_STATUS(i) (SSI_SYS_STATUS0 + (i)) 248*4882a593Smuzhiyun #define SSI_SYS_INT_ENABLE(i) (SSI_SYS_INT_ENABLE0 + (i)) 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun struct rsnd_priv; 252*4882a593Smuzhiyun struct rsnd_mod; 253*4882a593Smuzhiyun struct rsnd_dai; 254*4882a593Smuzhiyun struct rsnd_dai_stream; 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun /* 257*4882a593Smuzhiyun * R-Car basic functions 258*4882a593Smuzhiyun */ 259*4882a593Smuzhiyun u32 rsnd_mod_read(struct rsnd_mod *mod, enum rsnd_reg reg); 260*4882a593Smuzhiyun void rsnd_mod_write(struct rsnd_mod *mod, enum rsnd_reg reg, u32 data); 261*4882a593Smuzhiyun void rsnd_mod_bset(struct rsnd_mod *mod, enum rsnd_reg reg, u32 mask, u32 data); 262*4882a593Smuzhiyun u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 263*4882a593Smuzhiyun u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 264*4882a593Smuzhiyun u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod); 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun /* 267*4882a593Smuzhiyun * R-Car DMA 268*4882a593Smuzhiyun */ 269*4882a593Smuzhiyun int rsnd_dma_attach(struct rsnd_dai_stream *io, 270*4882a593Smuzhiyun struct rsnd_mod *mod, struct rsnd_mod **dma_mod); 271*4882a593Smuzhiyun int rsnd_dma_probe(struct rsnd_priv *priv); 272*4882a593Smuzhiyun struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 273*4882a593Smuzhiyun struct rsnd_mod *mod, char *name); 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* 276*4882a593Smuzhiyun * R-Car sound mod 277*4882a593Smuzhiyun */ 278*4882a593Smuzhiyun enum rsnd_mod_type { 279*4882a593Smuzhiyun RSND_MOD_AUDMAPP, 280*4882a593Smuzhiyun RSND_MOD_AUDMA, 281*4882a593Smuzhiyun RSND_MOD_DVC, 282*4882a593Smuzhiyun RSND_MOD_MIX, 283*4882a593Smuzhiyun RSND_MOD_CTU, 284*4882a593Smuzhiyun RSND_MOD_CMD, 285*4882a593Smuzhiyun RSND_MOD_SRC, 286*4882a593Smuzhiyun RSND_MOD_SSIM3, /* SSI multi 3 */ 287*4882a593Smuzhiyun RSND_MOD_SSIM2, /* SSI multi 2 */ 288*4882a593Smuzhiyun RSND_MOD_SSIM1, /* SSI multi 1 */ 289*4882a593Smuzhiyun RSND_MOD_SSIP, /* SSI parent */ 290*4882a593Smuzhiyun RSND_MOD_SSI, 291*4882a593Smuzhiyun RSND_MOD_SSIU, 292*4882a593Smuzhiyun RSND_MOD_MAX, 293*4882a593Smuzhiyun }; 294*4882a593Smuzhiyun 295*4882a593Smuzhiyun struct rsnd_mod_ops { 296*4882a593Smuzhiyun char *name; 297*4882a593Smuzhiyun struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io, 298*4882a593Smuzhiyun struct rsnd_mod *mod); 299*4882a593Smuzhiyun int (*probe)(struct rsnd_mod *mod, 300*4882a593Smuzhiyun struct rsnd_dai_stream *io, 301*4882a593Smuzhiyun struct rsnd_priv *priv); 302*4882a593Smuzhiyun int (*remove)(struct rsnd_mod *mod, 303*4882a593Smuzhiyun struct rsnd_dai_stream *io, 304*4882a593Smuzhiyun struct rsnd_priv *priv); 305*4882a593Smuzhiyun int (*init)(struct rsnd_mod *mod, 306*4882a593Smuzhiyun struct rsnd_dai_stream *io, 307*4882a593Smuzhiyun struct rsnd_priv *priv); 308*4882a593Smuzhiyun int (*quit)(struct rsnd_mod *mod, 309*4882a593Smuzhiyun struct rsnd_dai_stream *io, 310*4882a593Smuzhiyun struct rsnd_priv *priv); 311*4882a593Smuzhiyun int (*start)(struct rsnd_mod *mod, 312*4882a593Smuzhiyun struct rsnd_dai_stream *io, 313*4882a593Smuzhiyun struct rsnd_priv *priv); 314*4882a593Smuzhiyun int (*stop)(struct rsnd_mod *mod, 315*4882a593Smuzhiyun struct rsnd_dai_stream *io, 316*4882a593Smuzhiyun struct rsnd_priv *priv); 317*4882a593Smuzhiyun int (*irq)(struct rsnd_mod *mod, 318*4882a593Smuzhiyun struct rsnd_dai_stream *io, 319*4882a593Smuzhiyun struct rsnd_priv *priv, int enable); 320*4882a593Smuzhiyun int (*pcm_new)(struct rsnd_mod *mod, 321*4882a593Smuzhiyun struct rsnd_dai_stream *io, 322*4882a593Smuzhiyun struct snd_soc_pcm_runtime *rtd); 323*4882a593Smuzhiyun int (*hw_params)(struct rsnd_mod *mod, 324*4882a593Smuzhiyun struct rsnd_dai_stream *io, 325*4882a593Smuzhiyun struct snd_pcm_substream *substream, 326*4882a593Smuzhiyun struct snd_pcm_hw_params *hw_params); 327*4882a593Smuzhiyun int (*pointer)(struct rsnd_mod *mod, 328*4882a593Smuzhiyun struct rsnd_dai_stream *io, 329*4882a593Smuzhiyun snd_pcm_uframes_t *pointer); 330*4882a593Smuzhiyun int (*fallback)(struct rsnd_mod *mod, 331*4882a593Smuzhiyun struct rsnd_dai_stream *io, 332*4882a593Smuzhiyun struct rsnd_priv *priv); 333*4882a593Smuzhiyun int (*prepare)(struct rsnd_mod *mod, 334*4882a593Smuzhiyun struct rsnd_dai_stream *io, 335*4882a593Smuzhiyun struct rsnd_priv *priv); 336*4882a593Smuzhiyun int (*cleanup)(struct rsnd_mod *mod, 337*4882a593Smuzhiyun struct rsnd_dai_stream *io, 338*4882a593Smuzhiyun struct rsnd_priv *priv); 339*4882a593Smuzhiyun int (*hw_free)(struct rsnd_mod *mod, 340*4882a593Smuzhiyun struct rsnd_dai_stream *io, 341*4882a593Smuzhiyun struct snd_pcm_substream *substream); 342*4882a593Smuzhiyun u32 *(*get_status)(struct rsnd_mod *mod, 343*4882a593Smuzhiyun struct rsnd_dai_stream *io, 344*4882a593Smuzhiyun enum rsnd_mod_type type); 345*4882a593Smuzhiyun int (*id)(struct rsnd_mod *mod); 346*4882a593Smuzhiyun int (*id_sub)(struct rsnd_mod *mod); 347*4882a593Smuzhiyun int (*id_cmd)(struct rsnd_mod *mod); 348*4882a593Smuzhiyun }; 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun struct rsnd_dai_stream; 351*4882a593Smuzhiyun struct rsnd_mod { 352*4882a593Smuzhiyun int id; 353*4882a593Smuzhiyun enum rsnd_mod_type type; 354*4882a593Smuzhiyun struct rsnd_mod_ops *ops; 355*4882a593Smuzhiyun struct rsnd_priv *priv; 356*4882a593Smuzhiyun struct clk *clk; 357*4882a593Smuzhiyun u32 status; 358*4882a593Smuzhiyun }; 359*4882a593Smuzhiyun /* 360*4882a593Smuzhiyun * status 361*4882a593Smuzhiyun * 362*4882a593Smuzhiyun * 0xH0000CB0 363*4882a593Smuzhiyun * 364*4882a593Smuzhiyun * B 0: init 1: quit 365*4882a593Smuzhiyun * C 0: start 1: stop 366*4882a593Smuzhiyun * D 0: hw_params 1: hw_free 367*4882a593Smuzhiyun * 368*4882a593Smuzhiyun * H is always called (see __rsnd_mod_call) 369*4882a593Smuzhiyun * H 0: probe 1: remove 370*4882a593Smuzhiyun * H 0: pcm_new 371*4882a593Smuzhiyun * H 0: fallback 372*4882a593Smuzhiyun * H 0: pointer 373*4882a593Smuzhiyun * H 0: prepare 374*4882a593Smuzhiyun * H 0: cleanup 375*4882a593Smuzhiyun */ 376*4882a593Smuzhiyun #define __rsnd_mod_shift_init 4 377*4882a593Smuzhiyun #define __rsnd_mod_shift_quit 4 378*4882a593Smuzhiyun #define __rsnd_mod_shift_start 8 379*4882a593Smuzhiyun #define __rsnd_mod_shift_stop 8 380*4882a593Smuzhiyun #define __rsnd_mod_shift_hw_params 12 381*4882a593Smuzhiyun #define __rsnd_mod_shift_hw_free 12 382*4882a593Smuzhiyun #define __rsnd_mod_shift_probe 28 /* always called */ 383*4882a593Smuzhiyun #define __rsnd_mod_shift_remove 28 /* always called */ 384*4882a593Smuzhiyun #define __rsnd_mod_shift_irq 28 /* always called */ 385*4882a593Smuzhiyun #define __rsnd_mod_shift_pcm_new 28 /* always called */ 386*4882a593Smuzhiyun #define __rsnd_mod_shift_fallback 28 /* always called */ 387*4882a593Smuzhiyun #define __rsnd_mod_shift_pointer 28 /* always called */ 388*4882a593Smuzhiyun #define __rsnd_mod_shift_prepare 28 /* always called */ 389*4882a593Smuzhiyun #define __rsnd_mod_shift_cleanup 28 /* always called */ 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun #define __rsnd_mod_add_probe 0 392*4882a593Smuzhiyun #define __rsnd_mod_add_remove 0 393*4882a593Smuzhiyun #define __rsnd_mod_add_prepare 0 394*4882a593Smuzhiyun #define __rsnd_mod_add_cleanup 0 395*4882a593Smuzhiyun #define __rsnd_mod_add_init 1 396*4882a593Smuzhiyun #define __rsnd_mod_add_quit -1 397*4882a593Smuzhiyun #define __rsnd_mod_add_start 1 398*4882a593Smuzhiyun #define __rsnd_mod_add_stop -1 399*4882a593Smuzhiyun #define __rsnd_mod_add_hw_params 1 400*4882a593Smuzhiyun #define __rsnd_mod_add_hw_free -1 401*4882a593Smuzhiyun #define __rsnd_mod_add_irq 0 402*4882a593Smuzhiyun #define __rsnd_mod_add_pcm_new 0 403*4882a593Smuzhiyun #define __rsnd_mod_add_fallback 0 404*4882a593Smuzhiyun #define __rsnd_mod_add_pointer 0 405*4882a593Smuzhiyun 406*4882a593Smuzhiyun #define __rsnd_mod_call_probe 0 407*4882a593Smuzhiyun #define __rsnd_mod_call_remove 0 408*4882a593Smuzhiyun #define __rsnd_mod_call_prepare 0 409*4882a593Smuzhiyun #define __rsnd_mod_call_cleanup 0 410*4882a593Smuzhiyun #define __rsnd_mod_call_init 0 411*4882a593Smuzhiyun #define __rsnd_mod_call_quit 1 412*4882a593Smuzhiyun #define __rsnd_mod_call_start 0 413*4882a593Smuzhiyun #define __rsnd_mod_call_stop 1 414*4882a593Smuzhiyun #define __rsnd_mod_call_irq 0 415*4882a593Smuzhiyun #define __rsnd_mod_call_pcm_new 0 416*4882a593Smuzhiyun #define __rsnd_mod_call_fallback 0 417*4882a593Smuzhiyun #define __rsnd_mod_call_hw_params 0 418*4882a593Smuzhiyun #define __rsnd_mod_call_pointer 0 419*4882a593Smuzhiyun #define __rsnd_mod_call_hw_free 1 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun #define rsnd_mod_to_priv(mod) ((mod)->priv) 422*4882a593Smuzhiyun #define rsnd_mod_power_on(mod) clk_enable((mod)->clk) 423*4882a593Smuzhiyun #define rsnd_mod_power_off(mod) clk_disable((mod)->clk) 424*4882a593Smuzhiyun #define rsnd_mod_get(ip) (&(ip)->mod) 425*4882a593Smuzhiyun 426*4882a593Smuzhiyun int rsnd_mod_init(struct rsnd_priv *priv, 427*4882a593Smuzhiyun struct rsnd_mod *mod, 428*4882a593Smuzhiyun struct rsnd_mod_ops *ops, 429*4882a593Smuzhiyun struct clk *clk, 430*4882a593Smuzhiyun enum rsnd_mod_type type, 431*4882a593Smuzhiyun int id); 432*4882a593Smuzhiyun void rsnd_mod_quit(struct rsnd_mod *mod); 433*4882a593Smuzhiyun struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, 434*4882a593Smuzhiyun struct rsnd_mod *mod); 435*4882a593Smuzhiyun void rsnd_mod_interrupt(struct rsnd_mod *mod, 436*4882a593Smuzhiyun void (*callback)(struct rsnd_mod *mod, 437*4882a593Smuzhiyun struct rsnd_dai_stream *io)); 438*4882a593Smuzhiyun u32 *rsnd_mod_get_status(struct rsnd_mod *mod, 439*4882a593Smuzhiyun struct rsnd_dai_stream *io, 440*4882a593Smuzhiyun enum rsnd_mod_type type); 441*4882a593Smuzhiyun int rsnd_mod_id(struct rsnd_mod *mod); 442*4882a593Smuzhiyun int rsnd_mod_id_raw(struct rsnd_mod *mod); 443*4882a593Smuzhiyun int rsnd_mod_id_sub(struct rsnd_mod *mod); 444*4882a593Smuzhiyun char *rsnd_mod_name(struct rsnd_mod *mod); 445*4882a593Smuzhiyun struct rsnd_mod *rsnd_mod_next(int *iterator, 446*4882a593Smuzhiyun struct rsnd_dai_stream *io, 447*4882a593Smuzhiyun enum rsnd_mod_type *array, 448*4882a593Smuzhiyun int array_size); 449*4882a593Smuzhiyun #define for_each_rsnd_mod(iterator, pos, io) \ 450*4882a593Smuzhiyun for (iterator = 0; \ 451*4882a593Smuzhiyun (pos = rsnd_mod_next(&iterator, io, NULL, 0)); iterator++) 452*4882a593Smuzhiyun #define for_each_rsnd_mod_arrays(iterator, pos, io, array, size) \ 453*4882a593Smuzhiyun for (iterator = 0; \ 454*4882a593Smuzhiyun (pos = rsnd_mod_next(&iterator, io, array, size)); iterator++) 455*4882a593Smuzhiyun #define for_each_rsnd_mod_array(iterator, pos, io, array) \ 456*4882a593Smuzhiyun for_each_rsnd_mod_arrays(iterator, pos, io, array, ARRAY_SIZE(array)) 457*4882a593Smuzhiyun 458*4882a593Smuzhiyun void rsnd_parse_connect_common(struct rsnd_dai *rdai, 459*4882a593Smuzhiyun struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), 460*4882a593Smuzhiyun struct device_node *node, 461*4882a593Smuzhiyun struct device_node *playback, 462*4882a593Smuzhiyun struct device_node *capture); 463*4882a593Smuzhiyun 464*4882a593Smuzhiyun int rsnd_channel_normalization(int chan); 465*4882a593Smuzhiyun #define rsnd_runtime_channel_original(io) \ 466*4882a593Smuzhiyun rsnd_runtime_channel_original_with_params(io, NULL) 467*4882a593Smuzhiyun int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io, 468*4882a593Smuzhiyun struct snd_pcm_hw_params *params); 469*4882a593Smuzhiyun #define rsnd_runtime_channel_after_ctu(io) \ 470*4882a593Smuzhiyun rsnd_runtime_channel_after_ctu_with_params(io, NULL) 471*4882a593Smuzhiyun int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io, 472*4882a593Smuzhiyun struct snd_pcm_hw_params *params); 473*4882a593Smuzhiyun #define rsnd_runtime_channel_for_ssi(io) \ 474*4882a593Smuzhiyun rsnd_runtime_channel_for_ssi_with_params(io, NULL) 475*4882a593Smuzhiyun int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, 476*4882a593Smuzhiyun struct snd_pcm_hw_params *params); 477*4882a593Smuzhiyun int rsnd_runtime_is_multi_ssi(struct rsnd_dai_stream *io); 478*4882a593Smuzhiyun int rsnd_runtime_is_tdm(struct rsnd_dai_stream *io); 479*4882a593Smuzhiyun int rsnd_runtime_is_tdm_split(struct rsnd_dai_stream *io); 480*4882a593Smuzhiyun 481*4882a593Smuzhiyun /* 482*4882a593Smuzhiyun * DT 483*4882a593Smuzhiyun */ 484*4882a593Smuzhiyun #define rsnd_parse_of_node(priv, node) \ 485*4882a593Smuzhiyun of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, node) 486*4882a593Smuzhiyun #define RSND_NODE_DAI "rcar_sound,dai" 487*4882a593Smuzhiyun #define RSND_NODE_SSI "rcar_sound,ssi" 488*4882a593Smuzhiyun #define RSND_NODE_SSIU "rcar_sound,ssiu" 489*4882a593Smuzhiyun #define RSND_NODE_SRC "rcar_sound,src" 490*4882a593Smuzhiyun #define RSND_NODE_CTU "rcar_sound,ctu" 491*4882a593Smuzhiyun #define RSND_NODE_MIX "rcar_sound,mix" 492*4882a593Smuzhiyun #define RSND_NODE_DVC "rcar_sound,dvc" 493*4882a593Smuzhiyun 494*4882a593Smuzhiyun /* 495*4882a593Smuzhiyun * R-Car sound DAI 496*4882a593Smuzhiyun */ 497*4882a593Smuzhiyun #define RSND_DAI_NAME_SIZE 16 498*4882a593Smuzhiyun struct rsnd_dai_stream { 499*4882a593Smuzhiyun char name[RSND_DAI_NAME_SIZE]; 500*4882a593Smuzhiyun struct snd_pcm_substream *substream; 501*4882a593Smuzhiyun struct rsnd_mod *mod[RSND_MOD_MAX]; 502*4882a593Smuzhiyun struct rsnd_mod *dma; 503*4882a593Smuzhiyun struct rsnd_dai *rdai; 504*4882a593Smuzhiyun struct device *dmac_dev; /* for IPMMU */ 505*4882a593Smuzhiyun u32 converted_rate; /* converted sampling rate */ 506*4882a593Smuzhiyun int converted_chan; /* converted channels */ 507*4882a593Smuzhiyun u32 parent_ssi_status; 508*4882a593Smuzhiyun u32 flags; 509*4882a593Smuzhiyun }; 510*4882a593Smuzhiyun 511*4882a593Smuzhiyun /* flags */ 512*4882a593Smuzhiyun #define RSND_STREAM_HDMI0 (1 << 0) /* for HDMI0 */ 513*4882a593Smuzhiyun #define RSND_STREAM_HDMI1 (1 << 1) /* for HDMI1 */ 514*4882a593Smuzhiyun #define RSND_STREAM_TDM_SPLIT (1 << 2) /* for TDM split mode */ 515*4882a593Smuzhiyun 516*4882a593Smuzhiyun #define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) 517*4882a593Smuzhiyun #define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) 518*4882a593Smuzhiyun #define rsnd_io_to_mod_ssiu(io) rsnd_io_to_mod((io), RSND_MOD_SSIU) 519*4882a593Smuzhiyun #define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP) 520*4882a593Smuzhiyun #define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC) 521*4882a593Smuzhiyun #define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) 522*4882a593Smuzhiyun #define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) 523*4882a593Smuzhiyun #define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC) 524*4882a593Smuzhiyun #define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD) 525*4882a593Smuzhiyun #define rsnd_io_to_rdai(io) ((io)->rdai) 526*4882a593Smuzhiyun #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) 527*4882a593Smuzhiyun #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) 528*4882a593Smuzhiyun #define rsnd_io_to_runtime(io) ((io)->substream ? \ 529*4882a593Smuzhiyun (io)->substream->runtime : NULL) 530*4882a593Smuzhiyun #define rsnd_io_converted_rate(io) ((io)->converted_rate) 531*4882a593Smuzhiyun #define rsnd_io_converted_chan(io) ((io)->converted_chan) 532*4882a593Smuzhiyun int rsnd_io_is_working(struct rsnd_dai_stream *io); 533*4882a593Smuzhiyun 534*4882a593Smuzhiyun struct rsnd_dai { 535*4882a593Smuzhiyun char name[RSND_DAI_NAME_SIZE]; 536*4882a593Smuzhiyun struct rsnd_dai_stream playback; 537*4882a593Smuzhiyun struct rsnd_dai_stream capture; 538*4882a593Smuzhiyun struct rsnd_priv *priv; 539*4882a593Smuzhiyun struct snd_pcm_hw_constraint_list constraint; 540*4882a593Smuzhiyun 541*4882a593Smuzhiyun int max_channels; /* 2ch - 16ch */ 542*4882a593Smuzhiyun int ssi_lane; /* 1lane - 4lane */ 543*4882a593Smuzhiyun int chan_width; /* 16/24/32 bit width */ 544*4882a593Smuzhiyun 545*4882a593Smuzhiyun unsigned int clk_master:1; 546*4882a593Smuzhiyun unsigned int bit_clk_inv:1; 547*4882a593Smuzhiyun unsigned int frm_clk_inv:1; 548*4882a593Smuzhiyun unsigned int sys_delay:1; 549*4882a593Smuzhiyun unsigned int data_alignment:1; 550*4882a593Smuzhiyun }; 551*4882a593Smuzhiyun 552*4882a593Smuzhiyun #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) 553*4882a593Smuzhiyun #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) 554*4882a593Smuzhiyun #define rsnd_rdai_to_priv(rdai) ((rdai)->priv) 555*4882a593Smuzhiyun #define for_each_rsnd_dai(rdai, priv, i) \ 556*4882a593Smuzhiyun for (i = 0; \ 557*4882a593Smuzhiyun (i < rsnd_rdai_nr(priv)) && \ 558*4882a593Smuzhiyun ((rdai) = rsnd_rdai_get(priv, i)); \ 559*4882a593Smuzhiyun i++) 560*4882a593Smuzhiyun 561*4882a593Smuzhiyun struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); 562*4882a593Smuzhiyun 563*4882a593Smuzhiyun #define rsnd_rdai_channels_set(rdai, max_channels) \ 564*4882a593Smuzhiyun rsnd_rdai_channels_ctrl(rdai, max_channels) 565*4882a593Smuzhiyun #define rsnd_rdai_channels_get(rdai) \ 566*4882a593Smuzhiyun rsnd_rdai_channels_ctrl(rdai, 0) 567*4882a593Smuzhiyun int rsnd_rdai_channels_ctrl(struct rsnd_dai *rdai, 568*4882a593Smuzhiyun int max_channels); 569*4882a593Smuzhiyun 570*4882a593Smuzhiyun #define rsnd_rdai_ssi_lane_set(rdai, ssi_lane) \ 571*4882a593Smuzhiyun rsnd_rdai_ssi_lane_ctrl(rdai, ssi_lane) 572*4882a593Smuzhiyun #define rsnd_rdai_ssi_lane_get(rdai) \ 573*4882a593Smuzhiyun rsnd_rdai_ssi_lane_ctrl(rdai, 0) 574*4882a593Smuzhiyun int rsnd_rdai_ssi_lane_ctrl(struct rsnd_dai *rdai, 575*4882a593Smuzhiyun int ssi_lane); 576*4882a593Smuzhiyun 577*4882a593Smuzhiyun #define rsnd_rdai_width_set(rdai, width) \ 578*4882a593Smuzhiyun rsnd_rdai_width_ctrl(rdai, width) 579*4882a593Smuzhiyun #define rsnd_rdai_width_get(rdai) \ 580*4882a593Smuzhiyun rsnd_rdai_width_ctrl(rdai, 0) 581*4882a593Smuzhiyun int rsnd_rdai_width_ctrl(struct rsnd_dai *rdai, int width); 582*4882a593Smuzhiyun void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); 583*4882a593Smuzhiyun int rsnd_dai_connect(struct rsnd_mod *mod, 584*4882a593Smuzhiyun struct rsnd_dai_stream *io, 585*4882a593Smuzhiyun enum rsnd_mod_type type); 586*4882a593Smuzhiyun 587*4882a593Smuzhiyun /* 588*4882a593Smuzhiyun * R-Car Gen1/Gen2 589*4882a593Smuzhiyun */ 590*4882a593Smuzhiyun int rsnd_gen_probe(struct rsnd_priv *priv); 591*4882a593Smuzhiyun void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 592*4882a593Smuzhiyun struct rsnd_mod *mod, 593*4882a593Smuzhiyun enum rsnd_reg reg); 594*4882a593Smuzhiyun phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); 595*4882a593Smuzhiyun 596*4882a593Smuzhiyun /* 597*4882a593Smuzhiyun * R-Car ADG 598*4882a593Smuzhiyun */ 599*4882a593Smuzhiyun int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate); 600*4882a593Smuzhiyun int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); 601*4882a593Smuzhiyun int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); 602*4882a593Smuzhiyun int rsnd_adg_probe(struct rsnd_priv *priv); 603*4882a593Smuzhiyun void rsnd_adg_remove(struct rsnd_priv *priv); 604*4882a593Smuzhiyun int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod, 605*4882a593Smuzhiyun struct rsnd_dai_stream *io, 606*4882a593Smuzhiyun unsigned int in_rate, 607*4882a593Smuzhiyun unsigned int out_rate); 608*4882a593Smuzhiyun int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, 609*4882a593Smuzhiyun struct rsnd_dai_stream *io); 610*4882a593Smuzhiyun #define rsnd_adg_clk_enable(priv) rsnd_adg_clk_control(priv, 1) 611*4882a593Smuzhiyun #define rsnd_adg_clk_disable(priv) rsnd_adg_clk_control(priv, 0) 612*4882a593Smuzhiyun void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable); 613*4882a593Smuzhiyun 614*4882a593Smuzhiyun /* 615*4882a593Smuzhiyun * R-Car sound priv 616*4882a593Smuzhiyun */ 617*4882a593Smuzhiyun struct rsnd_priv { 618*4882a593Smuzhiyun 619*4882a593Smuzhiyun struct platform_device *pdev; 620*4882a593Smuzhiyun spinlock_t lock; 621*4882a593Smuzhiyun unsigned long flags; 622*4882a593Smuzhiyun #define RSND_GEN_MASK (0xF << 0) 623*4882a593Smuzhiyun #define RSND_GEN1 (1 << 0) 624*4882a593Smuzhiyun #define RSND_GEN2 (2 << 0) 625*4882a593Smuzhiyun #define RSND_GEN3 (3 << 0) 626*4882a593Smuzhiyun #define RSND_SOC_MASK (0xFF << 4) 627*4882a593Smuzhiyun #define RSND_SOC_E (1 << 4) /* E1/E2/E3 */ 628*4882a593Smuzhiyun 629*4882a593Smuzhiyun /* 630*4882a593Smuzhiyun * below value will be filled on rsnd_gen_probe() 631*4882a593Smuzhiyun */ 632*4882a593Smuzhiyun void *gen; 633*4882a593Smuzhiyun 634*4882a593Smuzhiyun /* 635*4882a593Smuzhiyun * below value will be filled on rsnd_adg_probe() 636*4882a593Smuzhiyun */ 637*4882a593Smuzhiyun void *adg; 638*4882a593Smuzhiyun 639*4882a593Smuzhiyun /* 640*4882a593Smuzhiyun * below value will be filled on rsnd_dma_probe() 641*4882a593Smuzhiyun */ 642*4882a593Smuzhiyun void *dma; 643*4882a593Smuzhiyun 644*4882a593Smuzhiyun /* 645*4882a593Smuzhiyun * below value will be filled on rsnd_ssi_probe() 646*4882a593Smuzhiyun */ 647*4882a593Smuzhiyun void *ssi; 648*4882a593Smuzhiyun int ssi_nr; 649*4882a593Smuzhiyun 650*4882a593Smuzhiyun /* 651*4882a593Smuzhiyun * below value will be filled on rsnd_ssiu_probe() 652*4882a593Smuzhiyun */ 653*4882a593Smuzhiyun void *ssiu; 654*4882a593Smuzhiyun int ssiu_nr; 655*4882a593Smuzhiyun 656*4882a593Smuzhiyun /* 657*4882a593Smuzhiyun * below value will be filled on rsnd_src_probe() 658*4882a593Smuzhiyun */ 659*4882a593Smuzhiyun void *src; 660*4882a593Smuzhiyun int src_nr; 661*4882a593Smuzhiyun 662*4882a593Smuzhiyun /* 663*4882a593Smuzhiyun * below value will be filled on rsnd_ctu_probe() 664*4882a593Smuzhiyun */ 665*4882a593Smuzhiyun void *ctu; 666*4882a593Smuzhiyun int ctu_nr; 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun /* 669*4882a593Smuzhiyun * below value will be filled on rsnd_mix_probe() 670*4882a593Smuzhiyun */ 671*4882a593Smuzhiyun void *mix; 672*4882a593Smuzhiyun int mix_nr; 673*4882a593Smuzhiyun 674*4882a593Smuzhiyun /* 675*4882a593Smuzhiyun * below value will be filled on rsnd_dvc_probe() 676*4882a593Smuzhiyun */ 677*4882a593Smuzhiyun void *dvc; 678*4882a593Smuzhiyun int dvc_nr; 679*4882a593Smuzhiyun 680*4882a593Smuzhiyun /* 681*4882a593Smuzhiyun * below value will be filled on rsnd_cmd_probe() 682*4882a593Smuzhiyun */ 683*4882a593Smuzhiyun void *cmd; 684*4882a593Smuzhiyun int cmd_nr; 685*4882a593Smuzhiyun 686*4882a593Smuzhiyun /* 687*4882a593Smuzhiyun * below value will be filled on rsnd_dai_probe() 688*4882a593Smuzhiyun */ 689*4882a593Smuzhiyun struct snd_soc_dai_driver *daidrv; 690*4882a593Smuzhiyun struct rsnd_dai *rdai; 691*4882a593Smuzhiyun int rdai_nr; 692*4882a593Smuzhiyun }; 693*4882a593Smuzhiyun 694*4882a593Smuzhiyun #define rsnd_priv_to_pdev(priv) ((priv)->pdev) 695*4882a593Smuzhiyun #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) 696*4882a593Smuzhiyun 697*4882a593Smuzhiyun #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) 698*4882a593Smuzhiyun #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) 699*4882a593Smuzhiyun #define rsnd_is_gen3(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN3) 700*4882a593Smuzhiyun #define rsnd_is_e3(priv) (((priv)->flags & \ 701*4882a593Smuzhiyun (RSND_GEN_MASK | RSND_SOC_MASK)) == \ 702*4882a593Smuzhiyun (RSND_GEN3 | RSND_SOC_E)) 703*4882a593Smuzhiyun 704*4882a593Smuzhiyun #define rsnd_flags_has(p, f) ((p)->flags & (f)) 705*4882a593Smuzhiyun #define rsnd_flags_set(p, f) ((p)->flags |= (f)) 706*4882a593Smuzhiyun #define rsnd_flags_del(p, f) ((p)->flags &= ~(f)) 707*4882a593Smuzhiyun 708*4882a593Smuzhiyun /* 709*4882a593Smuzhiyun * rsnd_kctrl 710*4882a593Smuzhiyun */ 711*4882a593Smuzhiyun struct rsnd_kctrl_cfg { 712*4882a593Smuzhiyun unsigned int max; 713*4882a593Smuzhiyun unsigned int size; 714*4882a593Smuzhiyun u32 *val; 715*4882a593Smuzhiyun const char * const *texts; 716*4882a593Smuzhiyun int (*accept)(struct rsnd_dai_stream *io); 717*4882a593Smuzhiyun void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod); 718*4882a593Smuzhiyun struct rsnd_dai_stream *io; 719*4882a593Smuzhiyun struct snd_card *card; 720*4882a593Smuzhiyun struct snd_kcontrol *kctrl; 721*4882a593Smuzhiyun struct rsnd_mod *mod; 722*4882a593Smuzhiyun }; 723*4882a593Smuzhiyun 724*4882a593Smuzhiyun #define RSND_MAX_CHANNELS 8 725*4882a593Smuzhiyun struct rsnd_kctrl_cfg_m { 726*4882a593Smuzhiyun struct rsnd_kctrl_cfg cfg; 727*4882a593Smuzhiyun u32 val[RSND_MAX_CHANNELS]; 728*4882a593Smuzhiyun }; 729*4882a593Smuzhiyun 730*4882a593Smuzhiyun struct rsnd_kctrl_cfg_s { 731*4882a593Smuzhiyun struct rsnd_kctrl_cfg cfg; 732*4882a593Smuzhiyun u32 val; 733*4882a593Smuzhiyun }; 734*4882a593Smuzhiyun #define rsnd_kctrl_size(x) ((x).cfg.size) 735*4882a593Smuzhiyun #define rsnd_kctrl_max(x) ((x).cfg.max) 736*4882a593Smuzhiyun #define rsnd_kctrl_valm(x, i) ((x).val[i]) /* = (x).cfg.val[i] */ 737*4882a593Smuzhiyun #define rsnd_kctrl_vals(x) ((x).val) /* = (x).cfg.val[0] */ 738*4882a593Smuzhiyun 739*4882a593Smuzhiyun int rsnd_kctrl_accept_anytime(struct rsnd_dai_stream *io); 740*4882a593Smuzhiyun int rsnd_kctrl_accept_runtime(struct rsnd_dai_stream *io); 741*4882a593Smuzhiyun struct rsnd_kctrl_cfg *rsnd_kctrl_init_m(struct rsnd_kctrl_cfg_m *cfg); 742*4882a593Smuzhiyun struct rsnd_kctrl_cfg *rsnd_kctrl_init_s(struct rsnd_kctrl_cfg_s *cfg); 743*4882a593Smuzhiyun int rsnd_kctrl_new(struct rsnd_mod *mod, 744*4882a593Smuzhiyun struct rsnd_dai_stream *io, 745*4882a593Smuzhiyun struct snd_soc_pcm_runtime *rtd, 746*4882a593Smuzhiyun const unsigned char *name, 747*4882a593Smuzhiyun int (*accept)(struct rsnd_dai_stream *io), 748*4882a593Smuzhiyun void (*update)(struct rsnd_dai_stream *io, 749*4882a593Smuzhiyun struct rsnd_mod *mod), 750*4882a593Smuzhiyun struct rsnd_kctrl_cfg *cfg, 751*4882a593Smuzhiyun const char * const *texts, 752*4882a593Smuzhiyun int size, 753*4882a593Smuzhiyun u32 max); 754*4882a593Smuzhiyun 755*4882a593Smuzhiyun #define rsnd_kctrl_new_m(mod, io, rtd, name, accept, update, cfg, size, max) \ 756*4882a593Smuzhiyun rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_m(cfg), \ 757*4882a593Smuzhiyun NULL, size, max) 758*4882a593Smuzhiyun 759*4882a593Smuzhiyun #define rsnd_kctrl_new_s(mod, io, rtd, name, accept, update, cfg, max) \ 760*4882a593Smuzhiyun rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \ 761*4882a593Smuzhiyun NULL, 1, max) 762*4882a593Smuzhiyun 763*4882a593Smuzhiyun #define rsnd_kctrl_new_e(mod, io, rtd, name, accept, update, cfg, texts, size) \ 764*4882a593Smuzhiyun rsnd_kctrl_new(mod, io, rtd, name, accept, update, rsnd_kctrl_init_s(cfg), \ 765*4882a593Smuzhiyun texts, 1, size) 766*4882a593Smuzhiyun 767*4882a593Smuzhiyun extern const char * const volume_ramp_rate[]; 768*4882a593Smuzhiyun #define VOLUME_RAMP_MAX_DVC (0x17 + 1) 769*4882a593Smuzhiyun #define VOLUME_RAMP_MAX_MIX (0x0a + 1) 770*4882a593Smuzhiyun 771*4882a593Smuzhiyun /* 772*4882a593Smuzhiyun * R-Car SSI 773*4882a593Smuzhiyun */ 774*4882a593Smuzhiyun int rsnd_ssi_probe(struct rsnd_priv *priv); 775*4882a593Smuzhiyun void rsnd_ssi_remove(struct rsnd_priv *priv); 776*4882a593Smuzhiyun struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 777*4882a593Smuzhiyun int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); 778*4882a593Smuzhiyun u32 rsnd_ssi_multi_secondaries_runtime(struct rsnd_dai_stream *io); 779*4882a593Smuzhiyun 780*4882a593Smuzhiyun #define rsnd_ssi_is_pin_sharing(io) \ 781*4882a593Smuzhiyun __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) 782*4882a593Smuzhiyun int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 783*4882a593Smuzhiyun 784*4882a593Smuzhiyun #define rsnd_ssi_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SSI) 785*4882a593Smuzhiyun void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, 786*4882a593Smuzhiyun struct device_node *playback, 787*4882a593Smuzhiyun struct device_node *capture); 788*4882a593Smuzhiyun unsigned int rsnd_ssi_clk_query(struct rsnd_dai *rdai, 789*4882a593Smuzhiyun int param1, int param2, int *idx); 790*4882a593Smuzhiyun 791*4882a593Smuzhiyun /* 792*4882a593Smuzhiyun * R-Car SSIU 793*4882a593Smuzhiyun */ 794*4882a593Smuzhiyun int rsnd_ssiu_attach(struct rsnd_dai_stream *io, 795*4882a593Smuzhiyun struct rsnd_mod *mod); 796*4882a593Smuzhiyun int rsnd_ssiu_probe(struct rsnd_priv *priv); 797*4882a593Smuzhiyun void rsnd_ssiu_remove(struct rsnd_priv *priv); 798*4882a593Smuzhiyun void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai, 799*4882a593Smuzhiyun struct device_node *playback, 800*4882a593Smuzhiyun struct device_node *capture); 801*4882a593Smuzhiyun #define rsnd_ssiu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SSIU) 802*4882a593Smuzhiyun 803*4882a593Smuzhiyun /* 804*4882a593Smuzhiyun * R-Car SRC 805*4882a593Smuzhiyun */ 806*4882a593Smuzhiyun int rsnd_src_probe(struct rsnd_priv *priv); 807*4882a593Smuzhiyun void rsnd_src_remove(struct rsnd_priv *priv); 808*4882a593Smuzhiyun struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 809*4882a593Smuzhiyun 810*4882a593Smuzhiyun #define rsnd_src_get_in_rate(priv, io) rsnd_src_get_rate(priv, io, 1) 811*4882a593Smuzhiyun #define rsnd_src_get_out_rate(priv, io) rsnd_src_get_rate(priv, io, 0) 812*4882a593Smuzhiyun unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, 813*4882a593Smuzhiyun struct rsnd_dai_stream *io, 814*4882a593Smuzhiyun int is_in); 815*4882a593Smuzhiyun 816*4882a593Smuzhiyun #define rsnd_src_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SRC) 817*4882a593Smuzhiyun #define rsnd_parse_connect_src(rdai, playback, capture) \ 818*4882a593Smuzhiyun rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \ 819*4882a593Smuzhiyun rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \ 820*4882a593Smuzhiyun playback, capture) 821*4882a593Smuzhiyun 822*4882a593Smuzhiyun /* 823*4882a593Smuzhiyun * R-Car CTU 824*4882a593Smuzhiyun */ 825*4882a593Smuzhiyun int rsnd_ctu_probe(struct rsnd_priv *priv); 826*4882a593Smuzhiyun void rsnd_ctu_remove(struct rsnd_priv *priv); 827*4882a593Smuzhiyun struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); 828*4882a593Smuzhiyun #define rsnd_ctu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_CTU) 829*4882a593Smuzhiyun #define rsnd_parse_connect_ctu(rdai, playback, capture) \ 830*4882a593Smuzhiyun rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \ 831*4882a593Smuzhiyun rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \ 832*4882a593Smuzhiyun playback, capture) 833*4882a593Smuzhiyun 834*4882a593Smuzhiyun /* 835*4882a593Smuzhiyun * R-Car MIX 836*4882a593Smuzhiyun */ 837*4882a593Smuzhiyun int rsnd_mix_probe(struct rsnd_priv *priv); 838*4882a593Smuzhiyun void rsnd_mix_remove(struct rsnd_priv *priv); 839*4882a593Smuzhiyun struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); 840*4882a593Smuzhiyun #define rsnd_mix_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_MIX) 841*4882a593Smuzhiyun #define rsnd_parse_connect_mix(rdai, playback, capture) \ 842*4882a593Smuzhiyun rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \ 843*4882a593Smuzhiyun rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \ 844*4882a593Smuzhiyun playback, capture) 845*4882a593Smuzhiyun 846*4882a593Smuzhiyun /* 847*4882a593Smuzhiyun * R-Car DVC 848*4882a593Smuzhiyun */ 849*4882a593Smuzhiyun int rsnd_dvc_probe(struct rsnd_priv *priv); 850*4882a593Smuzhiyun void rsnd_dvc_remove(struct rsnd_priv *priv); 851*4882a593Smuzhiyun struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); 852*4882a593Smuzhiyun #define rsnd_dvc_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_DVC) 853*4882a593Smuzhiyun #define rsnd_parse_connect_dvc(rdai, playback, capture) \ 854*4882a593Smuzhiyun rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \ 855*4882a593Smuzhiyun rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \ 856*4882a593Smuzhiyun playback, capture) 857*4882a593Smuzhiyun 858*4882a593Smuzhiyun /* 859*4882a593Smuzhiyun * R-Car CMD 860*4882a593Smuzhiyun */ 861*4882a593Smuzhiyun int rsnd_cmd_probe(struct rsnd_priv *priv); 862*4882a593Smuzhiyun void rsnd_cmd_remove(struct rsnd_priv *priv); 863*4882a593Smuzhiyun int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); 864*4882a593Smuzhiyun 865*4882a593Smuzhiyun void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); 866*4882a593Smuzhiyun #ifdef DEBUG 867*4882a593Smuzhiyun #define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) 868*4882a593Smuzhiyun #define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC) 869*4882a593Smuzhiyun #define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC) 870*4882a593Smuzhiyun #else 871*4882a593Smuzhiyun #define rsnd_mod_confirm_ssi(mssi) 872*4882a593Smuzhiyun #define rsnd_mod_confirm_src(msrc) 873*4882a593Smuzhiyun #define rsnd_mod_confirm_dvc(mdvc) 874*4882a593Smuzhiyun #endif 875*4882a593Smuzhiyun 876*4882a593Smuzhiyun /* 877*4882a593Smuzhiyun * If you don't need interrupt status debug message, 878*4882a593Smuzhiyun * define RSND_DEBUG_NO_IRQ_STATUS as 1 on top of src.c/ssi.c 879*4882a593Smuzhiyun * 880*4882a593Smuzhiyun * #define RSND_DEBUG_NO_IRQ_STATUS 1 881*4882a593Smuzhiyun */ 882*4882a593Smuzhiyun #define rsnd_dbg_irq_status(dev, param...) \ 883*4882a593Smuzhiyun if (!IS_BUILTIN(RSND_DEBUG_NO_IRQ_STATUS)) \ 884*4882a593Smuzhiyun dev_dbg(dev, param) 885*4882a593Smuzhiyun 886*4882a593Smuzhiyun /* 887*4882a593Smuzhiyun * If you don't need rsnd_dai_call debug message, 888*4882a593Smuzhiyun * define RSND_DEBUG_NO_DAI_CALL as 1 on top of core.c 889*4882a593Smuzhiyun * 890*4882a593Smuzhiyun * #define RSND_DEBUG_NO_DAI_CALL 1 891*4882a593Smuzhiyun */ 892*4882a593Smuzhiyun #define rsnd_dbg_dai_call(dev, param...) \ 893*4882a593Smuzhiyun if (!IS_BUILTIN(RSND_DEBUG_NO_DAI_CALL)) \ 894*4882a593Smuzhiyun dev_dbg(dev, param) 895*4882a593Smuzhiyun 896*4882a593Smuzhiyun #endif 897