]>
Commit | Line | Data |
---|---|---|
1536a968 KM |
1 | /* |
2 | * Renesas R-Car | |
3 | * | |
4 | * Copyright (C) 2013 Renesas Solutions Corp. | |
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | */ | |
11 | #ifndef RSND_H | |
12 | #define RSND_H | |
13 | ||
14 | #include <linux/clk.h> | |
15 | #include <linux/device.h> | |
0a4d94c0 | 16 | #include <linux/dma-mapping.h> |
1536a968 KM |
17 | #include <linux/io.h> |
18 | #include <linux/list.h> | |
19 | #include <linux/module.h> | |
90e8e50f KM |
20 | #include <linux/of_device.h> |
21 | #include <linux/of_irq.h> | |
0a4d94c0 KM |
22 | #include <linux/sh_dma.h> |
23 | #include <linux/workqueue.h> | |
1536a968 KM |
24 | #include <sound/soc.h> |
25 | #include <sound/pcm_params.h> | |
26 | ||
2ea2cc86 KM |
27 | #define RSND_GEN1_SRU 0 |
28 | #define RSND_GEN1_ADG 1 | |
29 | #define RSND_GEN1_SSI 2 | |
30 | ||
31 | #define RSND_GEN2_SCU 0 | |
32 | #define RSND_GEN2_ADG 1 | |
33 | #define RSND_GEN2_SSIU 2 | |
34 | #define RSND_GEN2_SSI 3 | |
35 | ||
36 | #define RSND_BASE_MAX 4 | |
dcc448e6 | 37 | |
1536a968 KM |
38 | /* |
39 | * pseudo register | |
40 | * | |
41 | * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different. | |
42 | * This driver uses pseudo register in order to hide it. | |
43 | * see gen1/gen2 for detail | |
44 | */ | |
3337744a | 45 | enum rsnd_reg { |
d444080e | 46 | /* SCU (SRC/SSIU/MIX/CTU/DVC) */ |
186fadc1 | 47 | RSND_REG_SSI_MODE, /* Gen2 only */ |
07539c1d KM |
48 | RSND_REG_SSI_MODE0, |
49 | RSND_REG_SSI_MODE1, | |
b4c83b17 KM |
50 | RSND_REG_SSI_MODE2, |
51 | RSND_REG_SSI_CONTROL, | |
d444080e KM |
52 | RSND_REG_SSI_CTRL, /* Gen2 only */ |
53 | RSND_REG_SSI_BUSIF_MODE, /* Gen2 only */ | |
54 | RSND_REG_SSI_BUSIF_ADINR, /* Gen2 only */ | |
55 | RSND_REG_SSI_BUSIF_DALIGN, /* Gen2 only */ | |
56 | RSND_REG_SSI_INT_ENABLE, /* Gen2 only */ | |
bf4e8d7c KM |
57 | RSND_REG_SRC_I_BUSIF_MODE, |
58 | RSND_REG_SRC_O_BUSIF_MODE, | |
ef749400 KM |
59 | RSND_REG_SRC_ROUTE_MODE0, |
60 | RSND_REG_SRC_SWRSR, | |
61 | RSND_REG_SRC_SRCIR, | |
690ef81e | 62 | RSND_REG_SRC_ADINR, |
ef749400 KM |
63 | RSND_REG_SRC_IFSCR, |
64 | RSND_REG_SRC_IFSVR, | |
65 | RSND_REG_SRC_SRCCR, | |
d444080e KM |
66 | RSND_REG_SRC_CTRL, /* Gen2 only */ |
67 | RSND_REG_SRC_BSDSR, /* Gen2 only */ | |
68 | RSND_REG_SRC_BSISR, /* Gen2 only */ | |
69 | RSND_REG_SRC_INT_ENABLE0, /* Gen2 only */ | |
70 | RSND_REG_SRC_BUSIF_DALIGN, /* Gen2 only */ | |
71 | RSND_REG_SRCIN_TIMSEL0, /* Gen2 only */ | |
72 | RSND_REG_SRCIN_TIMSEL1, /* Gen2 only */ | |
73 | RSND_REG_SRCIN_TIMSEL2, /* Gen2 only */ | |
74 | RSND_REG_SRCIN_TIMSEL3, /* Gen2 only */ | |
75 | RSND_REG_SRCIN_TIMSEL4, /* Gen2 only */ | |
76 | RSND_REG_SRCOUT_TIMSEL0, /* Gen2 only */ | |
77 | RSND_REG_SRCOUT_TIMSEL1, /* Gen2 only */ | |
78 | RSND_REG_SRCOUT_TIMSEL2, /* Gen2 only */ | |
79 | RSND_REG_SRCOUT_TIMSEL3, /* Gen2 only */ | |
80 | RSND_REG_SRCOUT_TIMSEL4, /* Gen2 only */ | |
cfcefe01 | 81 | RSND_REG_SCU_SYS_STATUS0, |
d444080e | 82 | RSND_REG_SCU_SYS_STATUS1, /* Gen2 only */ |
cfcefe01 | 83 | RSND_REG_SCU_SYS_INT_EN0, |
d444080e KM |
84 | RSND_REG_SCU_SYS_INT_EN1, /* Gen2 only */ |
85 | RSND_REG_CMD_CTRL, /* Gen2 only */ | |
a504b1ee | 86 | RSND_REG_CMD_BUSIF_DALIGN, /* Gen2 only */ |
bff58ea4 | 87 | RSND_REG_CMD_ROUTE_SLCT, |
d444080e | 88 | RSND_REG_CMDOUT_TIMSEL, /* Gen2 only */ |
bd9a603f | 89 | RSND_REG_CTU_SWRSR, |
9269e3c3 KM |
90 | RSND_REG_CTU_CTUIR, |
91 | RSND_REG_CTU_ADINR, | |
dc037afd KM |
92 | RSND_REG_CTU_CPMDR, |
93 | RSND_REG_CTU_SCMDR, | |
94 | RSND_REG_CTU_SV00R, | |
95 | RSND_REG_CTU_SV01R, | |
96 | RSND_REG_CTU_SV02R, | |
97 | RSND_REG_CTU_SV03R, | |
98 | RSND_REG_CTU_SV04R, | |
99 | RSND_REG_CTU_SV05R, | |
100 | RSND_REG_CTU_SV06R, | |
101 | RSND_REG_CTU_SV07R, | |
102 | RSND_REG_CTU_SV10R, | |
103 | RSND_REG_CTU_SV11R, | |
104 | RSND_REG_CTU_SV12R, | |
105 | RSND_REG_CTU_SV13R, | |
106 | RSND_REG_CTU_SV14R, | |
107 | RSND_REG_CTU_SV15R, | |
108 | RSND_REG_CTU_SV16R, | |
109 | RSND_REG_CTU_SV17R, | |
110 | RSND_REG_CTU_SV20R, | |
111 | RSND_REG_CTU_SV21R, | |
112 | RSND_REG_CTU_SV22R, | |
113 | RSND_REG_CTU_SV23R, | |
114 | RSND_REG_CTU_SV24R, | |
115 | RSND_REG_CTU_SV25R, | |
116 | RSND_REG_CTU_SV26R, | |
117 | RSND_REG_CTU_SV27R, | |
118 | RSND_REG_CTU_SV30R, | |
119 | RSND_REG_CTU_SV31R, | |
120 | RSND_REG_CTU_SV32R, | |
121 | RSND_REG_CTU_SV33R, | |
122 | RSND_REG_CTU_SV34R, | |
123 | RSND_REG_CTU_SV35R, | |
124 | RSND_REG_CTU_SV36R, | |
125 | RSND_REG_CTU_SV37R, | |
70fb1052 KM |
126 | RSND_REG_MIX_SWRSR, |
127 | RSND_REG_MIX_MIXIR, | |
128 | RSND_REG_MIX_ADINR, | |
129 | RSND_REG_MIX_MIXMR, | |
130 | RSND_REG_MIX_MVPDR, | |
131 | RSND_REG_MIX_MDBAR, | |
132 | RSND_REG_MIX_MDBBR, | |
133 | RSND_REG_MIX_MDBCR, | |
134 | RSND_REG_MIX_MDBDR, | |
135 | RSND_REG_MIX_MDBER, | |
bff58ea4 KM |
136 | RSND_REG_DVC_SWRSR, |
137 | RSND_REG_DVC_DVUIR, | |
138 | RSND_REG_DVC_ADINR, | |
139 | RSND_REG_DVC_DVUCR, | |
140 | RSND_REG_DVC_ZCMCR, | |
141 | RSND_REG_DVC_VOL0R, | |
142 | RSND_REG_DVC_VOL1R, | |
42ab9a79 KM |
143 | RSND_REG_DVC_VOL2R, |
144 | RSND_REG_DVC_VOL3R, | |
145 | RSND_REG_DVC_VOL4R, | |
146 | RSND_REG_DVC_VOL5R, | |
147 | RSND_REG_DVC_VOL6R, | |
148 | RSND_REG_DVC_VOL7R, | |
bff58ea4 | 149 | RSND_REG_DVC_DVUER, |
d444080e KM |
150 | RSND_REG_DVC_VRCTR, /* Gen2 only */ |
151 | RSND_REG_DVC_VRPDR, /* Gen2 only */ | |
152 | RSND_REG_DVC_VRDBR, /* Gen2 only */ | |
07539c1d | 153 | |
dfc9403b KM |
154 | /* ADG */ |
155 | RSND_REG_BRRA, | |
156 | RSND_REG_BRRB, | |
157 | RSND_REG_SSICKR, | |
d444080e | 158 | RSND_REG_DIV_EN, /* Gen2 only */ |
dfc9403b KM |
159 | RSND_REG_AUDIO_CLK_SEL0, |
160 | RSND_REG_AUDIO_CLK_SEL1, | |
d444080e | 161 | RSND_REG_AUDIO_CLK_SEL2, /* Gen2 only */ |
dfc9403b | 162 | |
ae5c3223 KM |
163 | /* SSI */ |
164 | RSND_REG_SSICR, | |
165 | RSND_REG_SSISR, | |
166 | RSND_REG_SSITDR, | |
167 | RSND_REG_SSIRDR, | |
168 | RSND_REG_SSIWSR, | |
169 | ||
3337744a KM |
170 | RSND_REG_MAX, |
171 | }; | |
172 | ||
1536a968 | 173 | struct rsnd_priv; |
cdaa3cdf | 174 | struct rsnd_mod; |
1536a968 KM |
175 | struct rsnd_dai; |
176 | struct rsnd_dai_stream; | |
177 | ||
3337744a KM |
178 | /* |
179 | * R-Car basic functions | |
180 | */ | |
181 | #define rsnd_mod_read(m, r) \ | |
182 | rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r) | |
183 | #define rsnd_mod_write(m, r, d) \ | |
184 | rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d) | |
7b47ab47 KM |
185 | #define rsnd_mod_force_write(m, r, d) \ |
186 | rsnd_force_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d) | |
3337744a KM |
187 | #define rsnd_mod_bset(m, r, s, d) \ |
188 | rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d) | |
189 | ||
3337744a KM |
190 | u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); |
191 | void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |
192 | enum rsnd_reg reg, u32 data); | |
7b47ab47 KM |
193 | void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod, |
194 | enum rsnd_reg reg, u32 data); | |
3337744a KM |
195 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
196 | u32 mask, u32 data); | |
3023b384 | 197 | u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
bfe1360d | 198 | u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
4689032b | 199 | u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); |
3337744a | 200 | |
0a4d94c0 KM |
201 | /* |
202 | * R-Car DMA | |
203 | */ | |
355cb84f KM |
204 | int rsnd_dma_attach(struct rsnd_dai_stream *io, |
205 | struct rsnd_mod *mod, struct rsnd_mod **dma_mod, int id); | |
2ea6b074 | 206 | int rsnd_dma_probe(struct rsnd_priv *priv); |
72adc61f KM |
207 | struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, |
208 | struct rsnd_mod *mod, char *name); | |
0a4d94c0 | 209 | |
cdaa3cdf KM |
210 | /* |
211 | * R-Car sound mod | |
212 | */ | |
a126021d | 213 | enum rsnd_mod_type { |
940e9479 KM |
214 | RSND_MOD_AUDMAPP, |
215 | RSND_MOD_AUDMA, | |
216 | RSND_MOD_DVC, | |
70fb1052 | 217 | RSND_MOD_MIX, |
9269e3c3 | 218 | RSND_MOD_CTU, |
1b2ca0ad | 219 | RSND_MOD_CMD, |
8048b91f | 220 | RSND_MOD_SRC, |
b4c83b17 KM |
221 | RSND_MOD_SSIM3, /* SSI multi 3 */ |
222 | RSND_MOD_SSIM2, /* SSI multi 2 */ | |
223 | RSND_MOD_SSIM1, /* SSI multi 1 */ | |
224 | RSND_MOD_SSIP, /* SSI parent */ | |
a126021d | 225 | RSND_MOD_SSI, |
cdf310ce | 226 | RSND_MOD_SSIU, |
a126021d KM |
227 | RSND_MOD_MAX, |
228 | }; | |
cdaa3cdf KM |
229 | |
230 | struct rsnd_mod_ops { | |
231 | char *name; | |
9b99e9a7 KM |
232 | struct dma_chan* (*dma_req)(struct rsnd_dai_stream *io, |
233 | struct rsnd_mod *mod); | |
7681f6ac | 234 | int (*probe)(struct rsnd_mod *mod, |
2c0fac19 | 235 | struct rsnd_dai_stream *io, |
690602fc | 236 | struct rsnd_priv *priv); |
7681f6ac | 237 | int (*remove)(struct rsnd_mod *mod, |
2c0fac19 | 238 | struct rsnd_dai_stream *io, |
690602fc | 239 | struct rsnd_priv *priv); |
cdaa3cdf | 240 | int (*init)(struct rsnd_mod *mod, |
2c0fac19 | 241 | struct rsnd_dai_stream *io, |
690602fc | 242 | struct rsnd_priv *priv); |
cdaa3cdf | 243 | int (*quit)(struct rsnd_mod *mod, |
2c0fac19 | 244 | struct rsnd_dai_stream *io, |
690602fc | 245 | struct rsnd_priv *priv); |
cdaa3cdf | 246 | int (*start)(struct rsnd_mod *mod, |
2c0fac19 | 247 | struct rsnd_dai_stream *io, |
690602fc | 248 | struct rsnd_priv *priv); |
cdaa3cdf | 249 | int (*stop)(struct rsnd_mod *mod, |
2c0fac19 | 250 | struct rsnd_dai_stream *io, |
690602fc | 251 | struct rsnd_priv *priv); |
bff58ea4 | 252 | int (*pcm_new)(struct rsnd_mod *mod, |
2c0fac19 | 253 | struct rsnd_dai_stream *io, |
bff58ea4 | 254 | struct snd_soc_pcm_runtime *rtd); |
3b7843ff | 255 | int (*hw_params)(struct rsnd_mod *mod, |
2c0fac19 | 256 | struct rsnd_dai_stream *io, |
3b7843ff KM |
257 | struct snd_pcm_substream *substream, |
258 | struct snd_pcm_hw_params *hw_params); | |
97463e19 | 259 | int (*fallback)(struct rsnd_mod *mod, |
2c0fac19 | 260 | struct rsnd_dai_stream *io, |
690602fc | 261 | struct rsnd_priv *priv); |
cdaa3cdf KM |
262 | }; |
263 | ||
4686a0ad | 264 | struct rsnd_dai_stream; |
cdaa3cdf KM |
265 | struct rsnd_mod { |
266 | int id; | |
a126021d | 267 | enum rsnd_mod_type type; |
cdaa3cdf | 268 | struct rsnd_mod_ops *ops; |
2099bc8e | 269 | struct rsnd_priv *priv; |
85642952 | 270 | struct clk *clk; |
5ba17b42 KM |
271 | u32 *(*get_status)(struct rsnd_dai_stream *io, |
272 | struct rsnd_mod *mod, | |
273 | enum rsnd_mod_type type); | |
274 | u32 status; | |
cdaa3cdf | 275 | }; |
417f9642 KM |
276 | /* |
277 | * status | |
278 | * | |
ea96380b | 279 | * 0xH0000CB0 |
3b7843ff | 280 | * |
5451ea44 KM |
281 | * B 0: init 1: quit |
282 | * C 0: start 1: stop | |
283 | * | |
284 | * H is always called (see __rsnd_mod_call) | |
ea96380b | 285 | * H 0: probe 1: remove |
5451ea44 KM |
286 | * H 0: pcm_new |
287 | * H 0: fallback | |
288 | * H 0: hw_params | |
417f9642 | 289 | */ |
5451ea44 KM |
290 | #define __rsnd_mod_shift_init 4 |
291 | #define __rsnd_mod_shift_quit 4 | |
292 | #define __rsnd_mod_shift_start 8 | |
293 | #define __rsnd_mod_shift_stop 8 | |
ea96380b KM |
294 | #define __rsnd_mod_shift_probe 28 /* always called */ |
295 | #define __rsnd_mod_shift_remove 28 /* always called */ | |
5451ea44 KM |
296 | #define __rsnd_mod_shift_pcm_new 28 /* always called */ |
297 | #define __rsnd_mod_shift_fallback 28 /* always called */ | |
298 | #define __rsnd_mod_shift_hw_params 28 /* always called */ | |
299 | ||
ea96380b KM |
300 | #define __rsnd_mod_add_probe 0 |
301 | #define __rsnd_mod_add_remove 0 | |
5451ea44 KM |
302 | #define __rsnd_mod_add_init 1 |
303 | #define __rsnd_mod_add_quit -1 | |
304 | #define __rsnd_mod_add_start 1 | |
305 | #define __rsnd_mod_add_stop -1 | |
306 | #define __rsnd_mod_add_pcm_new 0 | |
307 | #define __rsnd_mod_add_fallback 0 | |
308 | #define __rsnd_mod_add_hw_params 0 | |
417f9642 KM |
309 | |
310 | #define __rsnd_mod_call_probe 0 | |
ea96380b | 311 | #define __rsnd_mod_call_remove 0 |
417f9642 KM |
312 | #define __rsnd_mod_call_init 0 |
313 | #define __rsnd_mod_call_quit 1 | |
314 | #define __rsnd_mod_call_start 0 | |
315 | #define __rsnd_mod_call_stop 1 | |
316 | #define __rsnd_mod_call_pcm_new 0 | |
317 | #define __rsnd_mod_call_fallback 0 | |
3b7843ff | 318 | #define __rsnd_mod_call_hw_params 0 |
cdaa3cdf | 319 | |
2099bc8e | 320 | #define rsnd_mod_to_priv(mod) ((mod)->priv) |
72413c10 | 321 | #define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) |
c9929345 KM |
322 | #define rsnd_mod_power_on(mod) clk_enable((mod)->clk) |
323 | #define rsnd_mod_power_off(mod) clk_disable((mod)->clk) | |
b76e218a | 324 | #define rsnd_mod_get(ip) (&(ip)->mod) |
cdaa3cdf | 325 | |
2099bc8e KM |
326 | int rsnd_mod_init(struct rsnd_priv *priv, |
327 | struct rsnd_mod *mod, | |
5ba17b42 KM |
328 | struct rsnd_mod_ops *ops, |
329 | struct clk *clk, | |
330 | u32* (*get_status)(struct rsnd_dai_stream *io, | |
331 | struct rsnd_mod *mod, | |
332 | enum rsnd_mod_type type), | |
333 | enum rsnd_mod_type type, | |
334 | int id); | |
2f78dd7f | 335 | void rsnd_mod_quit(struct rsnd_mod *mod); |
cdaa3cdf | 336 | char *rsnd_mod_name(struct rsnd_mod *mod); |
9b99e9a7 KM |
337 | struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io, |
338 | struct rsnd_mod *mod); | |
f501b7a4 KM |
339 | void rsnd_mod_interrupt(struct rsnd_mod *mod, |
340 | void (*callback)(struct rsnd_mod *mod, | |
341 | struct rsnd_dai_stream *io)); | |
5ba17b42 KM |
342 | u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io, |
343 | struct rsnd_mod *mod, | |
344 | enum rsnd_mod_type type); | |
345 | ||
89b66174 KM |
346 | void rsnd_parse_connect_common(struct rsnd_dai *rdai, |
347 | struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), | |
348 | struct device_node *node, | |
349 | struct device_node *playback, | |
350 | struct device_node *capture); | |
cdaa3cdf | 351 | |
750fd445 KM |
352 | void rsnd_set_slot(struct rsnd_dai *rdai, |
353 | int slots, int slots_total); | |
c140284b KM |
354 | int rsnd_get_slot(struct rsnd_dai_stream *io); |
355 | int rsnd_get_slot_width(struct rsnd_dai_stream *io); | |
750fd445 | 356 | int rsnd_get_slot_num(struct rsnd_dai_stream *io); |
8ec85e7f | 357 | |
1536a968 KM |
358 | /* |
359 | * R-Car sound DAI | |
360 | */ | |
361 | #define RSND_DAI_NAME_SIZE 16 | |
362 | struct rsnd_dai_stream { | |
f8c3c309 | 363 | char name[RSND_DAI_NAME_SIZE]; |
1536a968 | 364 | struct snd_pcm_substream *substream; |
a126021d | 365 | struct rsnd_mod *mod[RSND_MOD_MAX]; |
389933d9 | 366 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ |
54cb5562 | 367 | struct rsnd_dai *rdai; |
5ba17b42 | 368 | u32 parent_ssi_status; |
1536a968 KM |
369 | int byte_pos; |
370 | int period_pos; | |
371 | int byte_per_period; | |
372 | int next_period_byte; | |
373 | }; | |
5cbbadd3 KM |
374 | #define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) |
375 | #define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) | |
e7d850dd | 376 | #define rsnd_io_to_mod_ssip(io) rsnd_io_to_mod((io), RSND_MOD_SSIP) |
5cbbadd3 | 377 | #define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC) |
9269e3c3 | 378 | #define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU) |
70fb1052 | 379 | #define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX) |
5cbbadd3 | 380 | #define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC) |
a504b1ee | 381 | #define rsnd_io_to_mod_cmd(io) rsnd_io_to_mod((io), RSND_MOD_CMD) |
54cb5562 | 382 | #define rsnd_io_to_rdai(io) ((io)->rdai) |
1b13d118 | 383 | #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) |
985a4f6e | 384 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) |
9d0e202f KM |
385 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ |
386 | (io)->substream->runtime : NULL) | |
d5bbe7de | 387 | int rsnd_io_is_working(struct rsnd_dai_stream *io); |
985a4f6e | 388 | |
1536a968 KM |
389 | struct rsnd_dai { |
390 | char name[RSND_DAI_NAME_SIZE]; | |
1536a968 KM |
391 | struct rsnd_dai_stream playback; |
392 | struct rsnd_dai_stream capture; | |
1b13d118 | 393 | struct rsnd_priv *priv; |
1536a968 | 394 | |
8ec85e7f | 395 | int slots; |
750fd445 | 396 | int slots_num; |
8ec85e7f | 397 | |
a3737731 DC |
398 | unsigned int clk_master:1; |
399 | unsigned int bit_clk_inv:1; | |
400 | unsigned int frm_clk_inv:1; | |
401 | unsigned int sys_delay:1; | |
402 | unsigned int data_alignment:1; | |
1536a968 KM |
403 | }; |
404 | ||
ecba9e72 | 405 | #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) |
3ed6448c | 406 | #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) |
1b13d118 | 407 | #define rsnd_rdai_to_priv(rdai) ((rdai)->priv) |
1536a968 | 408 | #define for_each_rsnd_dai(rdai, priv, i) \ |
00463c11 | 409 | for (i = 0; \ |
ecba9e72 | 410 | (i < rsnd_rdai_nr(priv)) && \ |
710d0889 | 411 | ((rdai) = rsnd_rdai_get(priv, i)); \ |
00463c11 | 412 | i++) |
1536a968 | 413 | |
710d0889 KM |
414 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); |
415 | ||
75defee0 KM |
416 | bool rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); |
417 | void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io); | |
1536a968 | 418 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); |
27924f32 KM |
419 | int rsnd_dai_connect(struct rsnd_mod *mod, |
420 | struct rsnd_dai_stream *io, | |
421 | enum rsnd_mod_type type); | |
94e2710c KM |
422 | #define rsnd_dai_of_node(priv) \ |
423 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dai") | |
1536a968 | 424 | |
3337744a KM |
425 | /* |
426 | * R-Car Gen1/Gen2 | |
427 | */ | |
2ea6b074 | 428 | int rsnd_gen_probe(struct rsnd_priv *priv); |
3337744a KM |
429 | void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, |
430 | struct rsnd_mod *mod, | |
431 | enum rsnd_reg reg); | |
c5212b45 | 432 | phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id); |
ad32d0c7 | 433 | |
dfc9403b KM |
434 | /* |
435 | * R-Car ADG | |
436 | */ | |
437 | int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); | |
438 | int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); | |
2ea6b074 KM |
439 | int rsnd_adg_probe(struct rsnd_priv *priv); |
440 | void rsnd_adg_remove(struct rsnd_priv *priv); | |
629509c5 | 441 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, |
629509c5 KM |
442 | struct rsnd_dai_stream *io, |
443 | unsigned int src_rate, | |
444 | unsigned int dst_rate); | |
445 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | |
629509c5 | 446 | struct rsnd_dai_stream *io); |
f708d944 | 447 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, |
bff58ea4 | 448 | struct rsnd_dai_stream *io); |
dfc9403b | 449 | |
1536a968 KM |
450 | /* |
451 | * R-Car sound priv | |
452 | */ | |
453 | struct rsnd_priv { | |
454 | ||
9f464f8e | 455 | struct platform_device *pdev; |
1536a968 | 456 | spinlock_t lock; |
c51eb1c6 | 457 | unsigned long flags; |
2ea2cc86 KM |
458 | #define RSND_GEN_MASK (0xF << 0) |
459 | #define RSND_GEN1 (1 << 0) | |
460 | #define RSND_GEN2 (2 << 0) | |
1536a968 | 461 | |
3337744a KM |
462 | /* |
463 | * below value will be filled on rsnd_gen_probe() | |
464 | */ | |
465 | void *gen; | |
466 | ||
dfc9403b KM |
467 | /* |
468 | * below value will be filled on rsnd_adg_probe() | |
469 | */ | |
470 | void *adg; | |
471 | ||
288f392e KM |
472 | /* |
473 | * below value will be filled on rsnd_dma_probe() | |
474 | */ | |
475 | void *dma; | |
476 | ||
ae5c3223 KM |
477 | /* |
478 | * below value will be filled on rsnd_ssi_probe() | |
479 | */ | |
dd27d808 KM |
480 | void *ssi; |
481 | int ssi_nr; | |
ae5c3223 | 482 | |
c7f69ab5 KM |
483 | /* |
484 | * below value will be filled on rsnd_ssiu_probe() | |
485 | */ | |
486 | void *ssiu; | |
487 | int ssiu_nr; | |
488 | ||
78edead4 KM |
489 | /* |
490 | * below value will be filled on rsnd_src_probe() | |
491 | */ | |
492 | void *src; | |
493 | int src_nr; | |
494 | ||
9269e3c3 KM |
495 | /* |
496 | * below value will be filled on rsnd_ctu_probe() | |
497 | */ | |
498 | void *ctu; | |
499 | int ctu_nr; | |
500 | ||
70fb1052 KM |
501 | /* |
502 | * below value will be filled on rsnd_mix_probe() | |
503 | */ | |
504 | void *mix; | |
505 | int mix_nr; | |
506 | ||
bff58ea4 KM |
507 | /* |
508 | * below value will be filled on rsnd_dvc_probe() | |
509 | */ | |
510 | void *dvc; | |
511 | int dvc_nr; | |
512 | ||
1b2ca0ad KM |
513 | /* |
514 | * below value will be filled on rsnd_cmd_probe() | |
515 | */ | |
516 | void *cmd; | |
517 | int cmd_nr; | |
518 | ||
1536a968 KM |
519 | /* |
520 | * below value will be filled on rsnd_dai_probe() | |
521 | */ | |
522 | struct snd_soc_dai_driver *daidrv; | |
523 | struct rsnd_dai *rdai; | |
ecba9e72 | 524 | int rdai_nr; |
1536a968 KM |
525 | }; |
526 | ||
9f464f8e KM |
527 | #define rsnd_priv_to_pdev(priv) ((priv)->pdev) |
528 | #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) | |
1536a968 | 529 | |
348d592c KM |
530 | #define rsnd_is_gen1(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN1) |
531 | #define rsnd_is_gen2(priv) (((priv)->flags & RSND_GEN_MASK) == RSND_GEN2) | |
532 | ||
170a2497 KM |
533 | /* |
534 | * rsnd_kctrl | |
535 | */ | |
536 | struct rsnd_kctrl_cfg { | |
537 | unsigned int max; | |
538 | unsigned int size; | |
539 | u32 *val; | |
540 | const char * const *texts; | |
b65a7ccc KM |
541 | void (*update)(struct rsnd_dai_stream *io, struct rsnd_mod *mod); |
542 | struct rsnd_dai_stream *io; | |
d1f83d6e KM |
543 | struct snd_card *card; |
544 | struct snd_kcontrol *kctrl; | |
170a2497 KM |
545 | }; |
546 | ||
42ab9a79 | 547 | #define RSND_DVC_CHANNELS 8 |
170a2497 KM |
548 | struct rsnd_kctrl_cfg_m { |
549 | struct rsnd_kctrl_cfg cfg; | |
550 | u32 val[RSND_DVC_CHANNELS]; | |
551 | }; | |
552 | ||
553 | struct rsnd_kctrl_cfg_s { | |
554 | struct rsnd_kctrl_cfg cfg; | |
555 | u32 val; | |
556 | }; | |
557 | ||
d1f83d6e KM |
558 | void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); |
559 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) | |
560 | ||
170a2497 | 561 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
b65a7ccc | 562 | struct rsnd_dai_stream *io, |
170a2497 KM |
563 | struct snd_soc_pcm_runtime *rtd, |
564 | const unsigned char *name, | |
b65a7ccc KM |
565 | void (*update)(struct rsnd_dai_stream *io, |
566 | struct rsnd_mod *mod), | |
170a2497 | 567 | struct rsnd_kctrl_cfg_m *_cfg, |
42ab9a79 | 568 | int ch_size, |
170a2497 KM |
569 | u32 max); |
570 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | |
b65a7ccc | 571 | struct rsnd_dai_stream *io, |
170a2497 KM |
572 | struct snd_soc_pcm_runtime *rtd, |
573 | const unsigned char *name, | |
b65a7ccc KM |
574 | void (*update)(struct rsnd_dai_stream *io, |
575 | struct rsnd_mod *mod), | |
170a2497 KM |
576 | struct rsnd_kctrl_cfg_s *_cfg, |
577 | u32 max); | |
578 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | |
b65a7ccc | 579 | struct rsnd_dai_stream *io, |
170a2497 KM |
580 | struct snd_soc_pcm_runtime *rtd, |
581 | const unsigned char *name, | |
582 | struct rsnd_kctrl_cfg_s *_cfg, | |
b65a7ccc KM |
583 | void (*update)(struct rsnd_dai_stream *io, |
584 | struct rsnd_mod *mod), | |
170a2497 KM |
585 | const char * const *texts, |
586 | u32 max); | |
587 | ||
78edead4 KM |
588 | /* |
589 | * R-Car SSI | |
590 | */ | |
2ea6b074 KM |
591 | int rsnd_ssi_probe(struct rsnd_priv *priv); |
592 | void rsnd_ssi_remove(struct rsnd_priv *priv); | |
78edead4 | 593 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
78edead4 | 594 | int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); |
b415b4d3 | 595 | int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); |
b4c83b17 | 596 | u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io); |
b415b4d3 KM |
597 | |
598 | #define rsnd_ssi_is_pin_sharing(io) \ | |
599 | __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) | |
600 | int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); | |
78edead4 | 601 | |
94e2710c KM |
602 | #define rsnd_ssi_of_node(priv) \ |
603 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") | |
b4c83b17 KM |
604 | void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, |
605 | struct device_node *playback, | |
606 | struct device_node *capture); | |
94e2710c | 607 | |
c7f69ab5 KM |
608 | /* |
609 | * R-Car SSIU | |
610 | */ | |
611 | int rsnd_ssiu_attach(struct rsnd_dai_stream *io, | |
612 | struct rsnd_mod *mod); | |
2ea6b074 KM |
613 | int rsnd_ssiu_probe(struct rsnd_priv *priv); |
614 | void rsnd_ssiu_remove(struct rsnd_priv *priv); | |
c7f69ab5 | 615 | |
07539c1d | 616 | /* |
ba9c949f | 617 | * R-Car SRC |
07539c1d | 618 | */ |
2ea6b074 KM |
619 | int rsnd_src_probe(struct rsnd_priv *priv); |
620 | void rsnd_src_remove(struct rsnd_priv *priv); | |
ba9c949f KM |
621 | struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); |
622 | unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |
374e5426 | 623 | struct rsnd_dai_stream *io, |
ef749400 | 624 | struct snd_pcm_runtime *runtime); |
94e2710c KM |
625 | #define rsnd_src_of_node(priv) \ |
626 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") | |
89b66174 KM |
627 | #define rsnd_parse_connect_src(rdai, playback, capture) \ |
628 | rsnd_parse_connect_common(rdai, rsnd_src_mod_get, \ | |
629 | rsnd_src_of_node(rsnd_rdai_to_priv(rdai)), \ | |
630 | playback, capture) | |
ef749400 | 631 | |
9269e3c3 KM |
632 | /* |
633 | * R-Car CTU | |
634 | */ | |
2ea6b074 KM |
635 | int rsnd_ctu_probe(struct rsnd_priv *priv); |
636 | void rsnd_ctu_remove(struct rsnd_priv *priv); | |
9269e3c3 | 637 | struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); |
94e2710c KM |
638 | #define rsnd_ctu_of_node(priv) \ |
639 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ctu") | |
89b66174 KM |
640 | #define rsnd_parse_connect_ctu(rdai, playback, capture) \ |
641 | rsnd_parse_connect_common(rdai, rsnd_ctu_mod_get, \ | |
642 | rsnd_ctu_of_node(rsnd_rdai_to_priv(rdai)), \ | |
643 | playback, capture) | |
9269e3c3 | 644 | |
70fb1052 KM |
645 | /* |
646 | * R-Car MIX | |
647 | */ | |
2ea6b074 KM |
648 | int rsnd_mix_probe(struct rsnd_priv *priv); |
649 | void rsnd_mix_remove(struct rsnd_priv *priv); | |
70fb1052 | 650 | struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id); |
94e2710c KM |
651 | #define rsnd_mix_of_node(priv) \ |
652 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,mix") | |
89b66174 KM |
653 | #define rsnd_parse_connect_mix(rdai, playback, capture) \ |
654 | rsnd_parse_connect_common(rdai, rsnd_mix_mod_get, \ | |
655 | rsnd_mix_of_node(rsnd_rdai_to_priv(rdai)), \ | |
656 | playback, capture) | |
70fb1052 | 657 | |
bff58ea4 KM |
658 | /* |
659 | * R-Car DVC | |
660 | */ | |
2ea6b074 KM |
661 | int rsnd_dvc_probe(struct rsnd_priv *priv); |
662 | void rsnd_dvc_remove(struct rsnd_priv *priv); | |
bff58ea4 | 663 | struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); |
94e2710c KM |
664 | #define rsnd_dvc_of_node(priv) \ |
665 | of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc") | |
89b66174 KM |
666 | #define rsnd_parse_connect_dvc(rdai, playback, capture) \ |
667 | rsnd_parse_connect_common(rdai, rsnd_dvc_mod_get, \ | |
668 | rsnd_dvc_of_node(rsnd_rdai_to_priv(rdai)), \ | |
669 | playback, capture) | |
bff58ea4 | 670 | |
1b2ca0ad KM |
671 | /* |
672 | * R-Car CMD | |
673 | */ | |
2ea6b074 KM |
674 | int rsnd_cmd_probe(struct rsnd_priv *priv); |
675 | void rsnd_cmd_remove(struct rsnd_priv *priv); | |
1b2ca0ad KM |
676 | int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id); |
677 | struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id); | |
678 | ||
f1df1229 KM |
679 | #ifdef DEBUG |
680 | void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type); | |
681 | #define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI) | |
682 | #define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC) | |
683 | #define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC) | |
684 | #else | |
685 | #define rsnd_mod_confirm_ssi(mssi) | |
686 | #define rsnd_mod_confirm_src(msrc) | |
687 | #define rsnd_mod_confirm_dvc(mdvc) | |
688 | #endif | |
689 | ||
1536a968 | 690 | #endif |