blob: abfcc2480cf63c1558b1a731dd74ecf6f44d29e2 [file] [log] [blame]
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001/*
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08002 * Renesas R-Car SRC support
Kuninori Morimoto07539c12013-07-21 21:36:35 -07003 *
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#include "rsnd.h"
12
Kuninori Morimoto8aefda52014-05-22 23:25:43 -070013#define SRC_NAME "src"
14
Kuninori Morimotocfcefe02015-01-08 01:52:36 +000015/* SRCx_STATUS */
16#define OUF_SRCO ((1 << 12) | (1 << 13))
17#define OUF_SRCI ((1 << 9) | (1 << 8))
18
19/* SCU_SYSTEM_STATUS0/1 */
20#define OUF_SRC(id) ((1 << (id + 16)) | (1 << id))
21
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080022struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
Kuninori Morimoto07539c12013-07-21 21:36:35 -070024 struct rsnd_mod mod;
Kuninori Morimoto232c00b2015-10-26 08:38:26 +000025 struct rsnd_dma *dma;
Kuninori Morimoto43cb6952015-04-01 04:15:16 +000026 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
27 struct rsnd_kctrl_cfg_s sync; /* sync convert */
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +000028 u32 convert_rate; /* sampling rate convert */
Kuninori Morimotocfcefe02015-01-08 01:52:36 +000029 int err;
Kuninori Morimoto07539c12013-07-21 21:36:35 -070030};
31
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080032#define RSND_SRC_NAME_SIZE 16
Kuninori Morimoto374a52812013-07-28 18:59:12 -070033
Kuninori Morimoto232c00b2015-10-26 08:38:26 +000034#define rsnd_src_to_dma(src) ((src)->dma)
Kuninori Morimotoda599fd2015-07-15 07:11:21 +000035#define rsnd_src_nr(priv) ((priv)->src_nr)
Kuninori Morimoto43cb6952015-04-01 04:15:16 +000036#define rsnd_enable_sync_convert(src) ((src)->sen.val)
Kuninori Morimoto82e76ed2015-02-20 10:30:22 +000037#define rsnd_src_of_node(priv) \
38 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
39
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080040#define rsnd_mod_to_src(_mod) \
41 container_of((_mod), struct rsnd_src, mod)
Kuninori Morimoto39cf3c42014-01-23 18:40:47 -080042
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080043#define for_each_rsnd_src(pos, priv, i) \
Kuninori Morimoto39cf3c42014-01-23 18:40:47 -080044 for ((i) = 0; \
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080045 ((i) < rsnd_src_nr(priv)) && \
46 ((pos) = (struct rsnd_src *)(priv)->src + i); \
Kuninori Morimoto39cf3c42014-01-23 18:40:47 -080047 i++)
48
49
Kuninori Morimotoef749402013-12-19 19:28:51 -080050/*
51 * image of SRC (Sampling Rate Converter)
52 *
53 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
54 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
55 * 44.1kHz <-> +-----+ +-----+ +-------+
56 * ...
57 *
58 */
Kuninori Morimoto374a52812013-07-28 18:59:12 -070059
Kuninori Morimoto41c62212014-01-23 18:39:56 -080060/*
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080061 * src.c is caring...
Kuninori Morimotoc926b742014-01-23 18:40:41 -080062 *
63 * Gen1
64 *
65 * [mem] -> [SRU] -> [SSI]
66 * |--------|
67 *
68 * Gen2
69 *
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080070 * [mem] -> [SRC] -> [SSIU] -> [SSI]
Kuninori Morimotoc926b742014-01-23 18:40:41 -080071 * |-----------------|
72 */
73
74/*
Kuninori Morimoto41c62212014-01-23 18:39:56 -080075 * How to use SRC bypass mode for debugging
76 *
77 * SRC has bypass mode, and it is useful for debugging.
78 * In Gen2 case,
79 * SRCm_MODE controls whether SRC is used or not
80 * SSI_MODE0 controls whether SSIU which receives SRC data
81 * is used or not.
82 * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC,
83 * but SRC bypass mode needs SSI_MODE0 only.
84 *
85 * This driver request
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080086 * struct rsnd_src_platform_info {
Kuninori Morimoto41c62212014-01-23 18:39:56 -080087 * u32 convert_rate;
Kuninori Morimoto29e69fd2014-05-08 01:59:26 -070088 * int dma_id;
Kuninori Morimoto41c62212014-01-23 18:39:56 -080089 * }
90 *
Kuninori Morimotoba9c9492014-03-03 20:51:21 -080091 * rsnd_src_convert_rate() indicates
Kuninori Morimoto41c62212014-01-23 18:39:56 -080092 * above convert_rate, and it controls
93 * whether SRC is used or not.
94 *
95 * ex) doesn't use SRC
Kuninori Morimoto29e69fd2014-05-08 01:59:26 -070096 * static struct rsnd_dai_platform_info rsnd_dai = {
97 * .playback = { .ssi = &rsnd_ssi[0], },
Kuninori Morimoto41c62212014-01-23 18:39:56 -080098 * };
99 *
100 * ex) uses SRC
Kuninori Morimoto29e69fd2014-05-08 01:59:26 -0700101 * static struct rsnd_src_platform_info rsnd_src[] = {
102 * RSND_SCU(48000, 0),
103 * ...
104 * };
105 * static struct rsnd_dai_platform_info rsnd_dai = {
106 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
Kuninori Morimoto41c62212014-01-23 18:39:56 -0800107 * };
108 *
109 * ex) uses SRC bypass mode
Kuninori Morimoto29e69fd2014-05-08 01:59:26 -0700110 * static struct rsnd_src_platform_info rsnd_src[] = {
111 * RSND_SCU(0, 0),
112 * ...
113 * };
114 * static struct rsnd_dai_platform_info rsnd_dai = {
115 * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] },
Kuninori Morimoto41c62212014-01-23 18:39:56 -0800116 * };
117 *
118 */
119
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800120/*
121 * Gen1/Gen2 common functions
122 */
Kuninori Morimoto379febf2015-07-15 07:12:18 +0000123static void rsnd_src_soft_reset(struct rsnd_mod *mod)
124{
125 rsnd_mod_write(mod, SRC_SWRSR, 0);
126 rsnd_mod_write(mod, SRC_SWRSR, 1);
127}
128
Kuninori Morimotod1ade512015-07-15 07:13:47 +0000129
130#define rsnd_src_initialize_lock(mod) __rsnd_src_initialize_lock(mod, 1)
131#define rsnd_src_initialize_unlock(mod) __rsnd_src_initialize_lock(mod, 0)
132static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable)
133{
134 rsnd_mod_write(mod, SRC_SRCIR, enable);
135}
136
Kuninori Morimoto9b99e9a2015-06-15 06:26:25 +0000137static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
138 struct rsnd_mod *mod)
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000139{
140 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000141 int is_play = rsnd_io_is_play(io);
142
143 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
144 mod,
145 is_play ? "rx" : "tx");
146}
147
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700148int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000149 struct rsnd_dai_stream *io,
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700150 int use_busif)
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800151{
Kuninori Morimotof708d942015-01-15 08:07:19 +0000152 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
Kuninori Morimoto374e5422014-03-02 23:43:03 -0800153 int ssi_id = rsnd_mod_id(ssi_mod);
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800154
155 /*
156 * SSI_MODE0
157 */
Kuninori Morimoto221bf522014-03-03 20:50:24 -0800158 rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700159 !use_busif << ssi_id);
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800160
161 /*
162 * SSI_MODE1
163 */
Kuninori Morimotob415b4d2015-10-22 03:15:46 +0000164 if (rsnd_ssi_is_pin_sharing(io)) {
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800165 int shift = -1;
Kuninori Morimoto374e5422014-03-02 23:43:03 -0800166 switch (ssi_id) {
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800167 case 1:
168 shift = 0;
169 break;
170 case 2:
171 shift = 2;
172 break;
173 case 4:
174 shift = 16;
175 break;
176 }
177
178 if (shift >= 0)
Kuninori Morimoto221bf522014-03-03 20:50:24 -0800179 rsnd_mod_bset(ssi_mod, SSI_MODE1,
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800180 0x3 << shift,
Kuninori Morimoto3ed64482015-01-15 08:04:51 +0000181 rsnd_rdai_is_clk_master(rdai) ?
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800182 0x2 << shift : 0x1 << shift);
183 }
184
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700185 /*
186 * DMA settings for SSIU
187 */
188 if (use_busif) {
Kuninori Morimoto46890322015-07-15 07:14:47 +0000189 u32 val = rsnd_get_dalign(ssi_mod, io);
Kuninori Morimoto1cc71952014-07-30 23:52:26 -0700190
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700191 rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
Kuninori Morimoto3023b382015-07-15 07:14:05 +0000192 rsnd_get_adinr_bit(ssi_mod, io));
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700193 rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1);
194 rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
Kuninori Morimoto1cc71952014-07-30 23:52:26 -0700195
Kuninori Morimotocdde84d2015-07-15 07:09:27 +0000196 rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700197 }
198
199 return 0;
200}
201
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000202int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
203 struct rsnd_dai_stream *io)
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700204{
205 /*
206 * DMA settings for SSIU
207 */
Kuninori Morimoto660cdce2014-11-27 08:03:39 +0000208 rsnd_mod_write(ssi_mod, SSI_CTRL, 0);
Kuninori Morimotod9288d02014-06-22 17:56:23 -0700209
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800210 return 0;
211}
212
Kuninori Morimotof708d942015-01-15 08:07:19 +0000213int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
Kuninori Morimotob8cc41e2014-03-03 20:50:08 -0800214{
215 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
216
Kuninori Morimotoc17dba82014-11-27 08:05:09 +0000217 if (rsnd_is_gen1(priv))
218 return 0;
219
220 /* enable SSI interrupt if Gen2 */
Kuninori Morimotoefa991d2015-07-15 07:09:47 +0000221 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
222 rsnd_ssi_is_dma_mode(ssi_mod) ?
223 0x0e000000 : 0x0f000000);
Kuninori Morimotob8cc41e2014-03-03 20:50:08 -0800224
225 return 0;
226}
227
Kuninori Morimotof708d942015-01-15 08:07:19 +0000228int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
Kuninori Morimotoc17dba82014-11-27 08:05:09 +0000229{
230 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
231
232 if (rsnd_is_gen1(priv))
233 return 0;
234
235 /* disable SSI interrupt if Gen2 */
Kuninori Morimotoefa991d2015-07-15 07:09:47 +0000236 rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
Kuninori Morimotoc17dba82014-11-27 08:05:09 +0000237
238 return 0;
239}
240
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000241static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
242 struct rsnd_src *src)
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000243{
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000244 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
245 u32 convert_rate;
246
247 if (!runtime)
248 return 0;
249
250 if (!rsnd_enable_sync_convert(src))
251 return src->convert_rate;
252
253 convert_rate = src->sync.val;
254
255 if (!convert_rate)
256 convert_rate = src->convert_rate;
257
258 if (!convert_rate)
259 convert_rate = runtime->rate;
260
261 return convert_rate;
262}
263
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800264unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
Kuninori Morimoto374e5422014-03-02 23:43:03 -0800265 struct rsnd_dai_stream *io,
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800266 struct snd_pcm_runtime *runtime)
267{
Kuninori Morimotob1eac432014-03-23 21:23:42 -0700268 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800269 struct rsnd_src *src;
Kuninori Morimotob1eac432014-03-23 21:23:42 -0700270 unsigned int rate = 0;
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800271
Kuninori Morimotob1eac432014-03-23 21:23:42 -0700272 if (src_mod) {
273 src = rsnd_mod_to_src(src_mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800274
Kuninori Morimotob1eac432014-03-23 21:23:42 -0700275 /*
276 * return convert rate if SRC is used,
277 * otherwise, return runtime->rate as usual
278 */
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000279 rate = rsnd_src_convert_rate(io, src);
Kuninori Morimotob1eac432014-03-23 21:23:42 -0700280 }
281
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800282 if (!rate)
283 rate = runtime->rate;
284
285 return rate;
286}
287
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000288static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
289 struct rsnd_dai_stream *io)
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800290{
291 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800292 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000293 u32 convert_rate = rsnd_src_convert_rate(io, src);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800294 u32 fsrate = 0;
295
296 if (convert_rate)
297 fsrate = 0x0400000 / convert_rate * runtime->rate;
298
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800299 /* Set channel number and output bit length */
Kuninori Morimoto3023b382015-07-15 07:14:05 +0000300 rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io));
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800301
302 /* Enable the initial value of IFS */
303 if (fsrate) {
304 rsnd_mod_write(mod, SRC_IFSCR, 1);
305
306 /* Set initial value of IFS */
307 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
308 }
309
310 /* use DMA transfer */
311 rsnd_mod_write(mod, SRC_BUSIF_MODE, 1);
312
313 return 0;
314}
315
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000316static int rsnd_src_hw_params(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000317 struct rsnd_dai_stream *io,
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000318 struct snd_pcm_substream *substream,
319 struct snd_pcm_hw_params *fe_params)
320{
321 struct rsnd_src *src = rsnd_mod_to_src(mod);
322 struct snd_soc_pcm_runtime *fe = substream->private_data;
323
324 /* default value (mainly for non-DT) */
325 src->convert_rate = src->info->convert_rate;
326
327 /*
328 * SRC assumes that it is used under DPCM if user want to use
329 * sampling rate convert. Then, SRC should be FE.
330 * And then, this function will be called *after* BE settings.
331 * this means, each BE already has fixuped hw_params.
332 * see
333 * dpcm_fe_dai_hw_params()
334 * dpcm_be_dai_hw_params()
335 */
336 if (fe->dai_link->dynamic) {
337 int stream = substream->stream;
338 struct snd_soc_dpcm *dpcm;
339 struct snd_pcm_hw_params *be_params;
340
341 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
342 be_params = &dpcm->hw_params;
343
344 if (params_rate(fe_params) != params_rate(be_params))
345 src->convert_rate = params_rate(be_params);
346 }
347 }
348
349 return 0;
350}
351
352static int rsnd_src_init(struct rsnd_mod *mod,
353 struct rsnd_priv *priv)
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800354{
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800355 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800356
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000357 rsnd_mod_power_on(mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800358
Kuninori Morimoto379febf2015-07-15 07:12:18 +0000359 rsnd_src_soft_reset(mod);
360
Kuninori Morimotod1ade512015-07-15 07:13:47 +0000361 rsnd_src_initialize_lock(mod);
362
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000363 src->err = 0;
364
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000365 /* reset sync convert_rate */
366 src->sync.val = 0;
367
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800368 return 0;
369}
370
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800371static int rsnd_src_quit(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000372 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000373 struct rsnd_priv *priv)
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800374{
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800375 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000376 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800377
Kuninori Morimotoc9929342015-10-22 03:15:04 +0000378 rsnd_mod_power_off(mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800379
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000380 if (src->err)
Kuninori Morimoto337b0b42015-01-15 08:08:57 +0000381 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
382 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000383
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000384 src->convert_rate = 0;
385
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000386 /* reset sync convert_rate */
387 src->sync.val = 0;
388
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800389 return 0;
390}
391
Kuninori Morimotof0ef0cb2014-11-27 08:07:28 +0000392static int rsnd_src_start(struct rsnd_mod *mod)
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800393{
Kuninori Morimotod1ade512015-07-15 07:13:47 +0000394 rsnd_src_initialize_unlock(mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800395
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800396 return 0;
397}
398
Kuninori Morimotof0ef0cb2014-11-27 08:07:28 +0000399static int rsnd_src_stop(struct rsnd_mod *mod)
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800400{
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000401 /* nothing to do */
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800402 return 0;
403}
404
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800405/*
406 * Gen1 functions
407 */
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000408static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io,
409 struct rsnd_mod *mod)
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700410{
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800411 struct src_route_config {
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700412 u32 mask;
413 int shift;
414 } routes[] = {
415 { 0xF, 0, }, /* 0 */
416 { 0xF, 4, }, /* 1 */
417 { 0xF, 8, }, /* 2 */
418 { 0x7, 12, }, /* 3 */
419 { 0x7, 16, }, /* 4 */
420 { 0x7, 20, }, /* 5 */
421 { 0x7, 24, }, /* 6 */
422 { 0x3, 28, }, /* 7 */
423 { 0x3, 30, }, /* 8 */
424 };
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700425 u32 mask;
426 u32 val;
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700427 int id;
428
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700429 id = rsnd_mod_id(mod);
Dan Carpenterb5f3d7a2013-11-08 12:46:10 +0300430 if (id < 0 || id >= ARRAY_SIZE(routes))
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700431 return -EIO;
432
433 /*
434 * SRC_ROUTE_SELECT
435 */
Kuninori Morimoto985a4f62015-01-15 08:06:49 +0000436 val = rsnd_io_is_play(io) ? 0x1 : 0x2;
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700437 val = val << routes[id].shift;
438 mask = routes[id].mask << routes[id].shift;
439
440 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
441
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800442 return 0;
443}
444
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000445static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
446 struct rsnd_mod *mod)
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800447{
448 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800449 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800450 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000451 u32 convert_rate = rsnd_src_convert_rate(io, src);
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800452 u32 mask;
453 u32 val;
454 int shift;
455 int id = rsnd_mod_id(mod);
456 int ret;
457
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700458 /*
459 * SRC_TIMING_SELECT
460 */
461 shift = (id % 4) * 8;
462 mask = 0x1F << shift;
Kuninori Morimotoef749402013-12-19 19:28:51 -0800463
464 /*
465 * ADG is used as source clock if SRC was used,
466 * then, SSI WS is used as destination clock.
467 * SSI WS is used as source clock if SRC is not used
468 * (when playback, source/destination become reverse when capture)
469 */
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800470 ret = 0;
471 if (convert_rate) {
472 /* use ADG */
Kuninori Morimotoef749402013-12-19 19:28:51 -0800473 val = 0;
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800474 ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
475 runtime->rate,
476 convert_rate);
477 } else if (8 == id) {
478 /* use SSI WS, but SRU8 is special */
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700479 val = id << shift;
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800480 } else {
481 /* use SSI WS */
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700482 val = (id + 1) << shift;
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800483 }
484
485 if (ret < 0)
486 return ret;
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700487
488 switch (id / 4) {
489 case 0:
490 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
491 break;
492 case 1:
493 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
494 break;
495 case 2:
496 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
497 break;
498 }
499
500 return 0;
501}
502
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000503static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
504 struct rsnd_dai_stream *io)
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700505{
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000506 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800507 int ret;
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700508
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000509 ret = rsnd_src_set_convert_rate(mod, io);
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800510 if (ret < 0)
511 return ret;
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700512
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800513 /* Select SRC mode (fixed value) */
514 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
Kuninori Morimotoef749402013-12-19 19:28:51 -0800515
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800516 /* Set the restriction value of the FS ratio (98%) */
517 rsnd_mod_write(mod, SRC_MNFSR,
518 rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700519
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000520 /* Gen1/Gen2 are not compatible */
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000521 if (rsnd_src_convert_rate(io, src))
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000522 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
523
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800524 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
Kuninori Morimotoef749402013-12-19 19:28:51 -0800525
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700526 return 0;
527}
528
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800529static int rsnd_src_init_gen1(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000530 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000531 struct rsnd_priv *priv)
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700532{
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700533 int ret;
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700534
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000535 ret = rsnd_src_init(mod, priv);
Kuninori Morimoto7b5ce972014-01-23 18:39:32 -0800536 if (ret < 0)
537 return ret;
538
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000539 ret = rsnd_src_set_route_gen1(io, mod);
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700540 if (ret < 0)
541 return ret;
542
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000543 ret = rsnd_src_set_convert_rate_gen1(mod, io);
Kuninori Morimoto374a52812013-07-28 18:59:12 -0700544 if (ret < 0)
545 return ret;
546
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000547 ret = rsnd_src_set_convert_timing_gen1(io, mod);
Kuninori Morimoto28dc4b62014-01-23 18:41:10 -0800548 if (ret < 0)
549 return ret;
550
Kuninori Morimotoa204d902014-01-23 18:38:33 -0800551 return 0;
552}
553
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800554static int rsnd_src_start_gen1(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000555 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000556 struct rsnd_priv *priv)
Kuninori Morimotoa204d902014-01-23 18:38:33 -0800557{
Kuninori Morimotoe7ce74e2014-01-23 18:38:50 -0800558 int id = rsnd_mod_id(mod);
Kuninori Morimotoa204d902014-01-23 18:38:33 -0800559
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800560 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id));
Kuninori Morimotoe7ce74e2014-01-23 18:38:50 -0800561
Kuninori Morimotof0ef0cb2014-11-27 08:07:28 +0000562 return rsnd_src_start(mod);
Kuninori Morimotoa204d902014-01-23 18:38:33 -0800563}
564
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800565static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000566 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000567 struct rsnd_priv *priv)
Kuninori Morimotoef749402013-12-19 19:28:51 -0800568{
Kuninori Morimotoe7ce74e2014-01-23 18:38:50 -0800569 int id = rsnd_mod_id(mod);
Kuninori Morimotoef749402013-12-19 19:28:51 -0800570
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800571 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0);
Kuninori Morimotoe7ce74e2014-01-23 18:38:50 -0800572
Kuninori Morimotof0ef0cb2014-11-27 08:07:28 +0000573 return rsnd_src_stop(mod);
Kuninori Morimotoef749402013-12-19 19:28:51 -0800574}
575
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800576static struct rsnd_mod_ops rsnd_src_gen1_ops = {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700577 .name = SRC_NAME,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000578 .dma_req = rsnd_src_dma_req,
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800579 .init = rsnd_src_init_gen1,
580 .quit = rsnd_src_quit,
581 .start = rsnd_src_start_gen1,
582 .stop = rsnd_src_stop_gen1,
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000583 .hw_params = rsnd_src_hw_params,
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700584};
585
Kuninori Morimoto1b7b08ef2014-01-23 18:41:36 -0800586/*
587 * Gen2 functions
588 */
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000589#define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1)
590#define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0)
591static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
592{
593 struct rsnd_src *src = rsnd_mod_to_src(mod);
594 u32 sys_int_val, int_val, sys_int_mask;
595 int irq = src->info->irq;
596 int id = rsnd_mod_id(mod);
597
598 sys_int_val =
599 sys_int_mask = OUF_SRC(id);
600 int_val = 0x3300;
601
602 /*
603 * IRQ is not supported on non-DT
604 * see
605 * rsnd_src_probe_gen2()
606 */
607 if ((irq <= 0) || !enable) {
608 sys_int_val = 0;
609 int_val = 0;
610 }
611
Kuninori Morimoto1a1bf582015-07-15 07:10:22 +0000612 /*
613 * WORKAROUND
614 *
615 * ignore over flow error when rsnd_enable_sync_convert()
616 */
617 if (rsnd_enable_sync_convert(src))
618 sys_int_val = sys_int_val & 0xffff;
619
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000620 rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
621 rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
622 rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
623}
624
625static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
626{
627 u32 val = OUF_SRC(rsnd_mod_id(mod));
628
629 rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val);
630 rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
631}
632
633static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
634{
Kuninori Morimoto1a1bf582015-07-15 07:10:22 +0000635 struct rsnd_src *src = rsnd_mod_to_src(mod);
636 u32 val0, val1;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000637 bool ret = false;
638
Kuninori Morimoto1a1bf582015-07-15 07:10:22 +0000639 val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
640
641 /*
642 * WORKAROUND
643 *
644 * ignore over flow error when rsnd_enable_sync_convert()
645 */
646 if (rsnd_enable_sync_convert(src))
647 val0 = val0 & 0xffff;
648
649 if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
650 (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1)) {
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000651 struct rsnd_src *src = rsnd_mod_to_src(mod);
652
653 src->err++;
654 ret = true;
655 }
656
657 /* clear error static */
658 rsnd_src_error_clear_gen2(mod);
659
660 return ret;
661}
662
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000663static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
664 struct rsnd_dai_stream *io)
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000665{
Kuninori Morimoto1a1bf582015-07-15 07:10:22 +0000666 struct rsnd_src *src = rsnd_mod_to_src(mod);
667 u32 val;
668
Kuninori Morimoto46890322015-07-15 07:14:47 +0000669 val = rsnd_get_dalign(mod, io);
670
671 rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);
672
Kuninori Morimoto1a1bf582015-07-15 07:10:22 +0000673 /*
674 * WORKAROUND
675 *
676 * Enable SRC output if you want to use sync convert together with DVC
677 */
678 val = (rsnd_io_to_mod_dvc(io) && !rsnd_enable_sync_convert(src)) ?
679 0x01 : 0x11;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000680
681 rsnd_mod_write(mod, SRC_CTRL, val);
682
683 rsnd_src_error_clear_gen2(mod);
684
685 rsnd_src_start(mod);
686
687 rsnd_src_irq_enable_gen2(mod);
688
689 return 0;
690}
691
692static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
693{
694 rsnd_src_irq_disable_gen2(mod);
695
696 rsnd_mod_write(mod, SRC_CTRL, 0);
697
698 rsnd_src_error_record_gen2(mod);
699
700 return rsnd_src_stop(mod);
701}
702
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000703static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
704 struct rsnd_dai_stream *io)
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000705{
Kuninori Morimoto02299d92015-05-21 03:50:23 +0000706 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000707
Kuninori Morimoto02299d92015-05-21 03:50:23 +0000708 spin_lock(&priv->lock);
709
710 /* ignore all cases if not working */
Kuninori Morimotod5bbe7d2015-06-15 06:27:47 +0000711 if (!rsnd_io_is_working(io))
Kuninori Morimoto02299d92015-05-21 03:50:23 +0000712 goto rsnd_src_interrupt_gen2_out;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000713
714 if (rsnd_src_error_record_gen2(mod)) {
715 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
Kuninori Morimoto639b2312015-03-19 04:14:04 +0000716 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000717 struct device *dev = rsnd_priv_to_dev(priv);
718
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000719 dev_dbg(dev, "%s[%d] restart\n",
720 rsnd_mod_name(mod), rsnd_mod_id(mod));
Kuninori Morimoto639b2312015-03-19 04:14:04 +0000721
722 _rsnd_src_stop_gen2(mod);
723 if (src->err < 1024)
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000724 _rsnd_src_start_gen2(mod, io);
Kuninori Morimoto639b2312015-03-19 04:14:04 +0000725 else
726 dev_warn(dev, "no more SRC restart\n");
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000727 }
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000728
Kuninori Morimoto02299d92015-05-21 03:50:23 +0000729rsnd_src_interrupt_gen2_out:
730 spin_unlock(&priv->lock);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000731}
732
733static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
734{
735 struct rsnd_mod *mod = data;
736
737 rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000738
739 return IRQ_HANDLED;
740}
741
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000742static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
743 struct rsnd_dai_stream *io)
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800744{
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700745 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
746 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700747 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
748 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000749 u32 convert_rate = rsnd_src_convert_rate(io, src);
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000750 u32 cr, route;
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700751 uint ratio;
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800752 int ret;
753
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700754 /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
Kuninori Morimotob167a572014-11-27 08:06:34 +0000755 if (!convert_rate)
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700756 ratio = 0;
Kuninori Morimotob167a572014-11-27 08:06:34 +0000757 else if (convert_rate > runtime->rate)
758 ratio = 100 * convert_rate / runtime->rate;
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700759 else
Kuninori Morimotob167a572014-11-27 08:06:34 +0000760 ratio = 100 * runtime->rate / convert_rate;
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700761
762 if (ratio > 600) {
763 dev_err(dev, "FSO/FSI ratio error\n");
764 return -EINVAL;
765 }
766
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000767 ret = rsnd_src_set_convert_rate(mod, io);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800768 if (ret < 0)
769 return ret;
770
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000771 cr = 0x00011110;
772 route = 0x0;
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000773 if (convert_rate) {
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000774 route = 0x1;
775
776 if (rsnd_enable_sync_convert(src)) {
777 cr |= 0x1;
778 route |= rsnd_io_is_play(io) ?
779 (0x1 << 24) : (0x1 << 25);
780 }
Kuninori Morimoto933cc8c2014-11-27 08:07:07 +0000781 }
782
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000783 rsnd_mod_write(mod, SRC_SRCCR, cr);
784 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
785
Kuninori Morimoto054cd7f2014-07-30 23:52:04 -0700786 switch (rsnd_mod_id(mod)) {
787 case 5:
788 case 6:
789 case 7:
790 case 8:
791 rsnd_mod_write(mod, SRC_BSDSR, 0x02400000);
792 break;
793 default:
794 rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
795 break;
796 }
797
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800798 rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
799
800 return 0;
801}
802
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000803static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io,
804 struct rsnd_mod *mod)
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800805{
806 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800807 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000808 u32 convert_rate = rsnd_src_convert_rate(io, src);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800809 int ret;
810
811 if (convert_rate)
Kuninori Morimotof708d942015-01-15 08:07:19 +0000812 ret = rsnd_adg_set_convert_clk_gen2(mod, io,
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800813 runtime->rate,
814 convert_rate);
815 else
Kuninori Morimotof708d942015-01-15 08:07:19 +0000816 ret = rsnd_adg_set_convert_timing_gen2(mod, io);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800817
818 return ret;
819}
820
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800821static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000822 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000823 struct rsnd_priv *priv)
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800824{
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800825 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800826 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000827 int irq = src->info->irq;
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800828 int ret;
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800829
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000830 if (irq > 0) {
831 /*
832 * IRQ is not supported on non-DT
833 * see
834 * rsnd_src_irq_enable_gen2()
835 */
836 ret = devm_request_irq(dev, irq,
837 rsnd_src_interrupt_gen2,
838 IRQF_SHARED,
839 dev_name(dev), mod);
840 if (ret)
Kuninori Morimotob543b522015-03-26 04:02:32 +0000841 return ret;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000842 }
843
Kuninori Morimoto81ecbb62015-10-26 08:39:20 +0000844 src->dma = rsnd_dma_attach(io, mod, src->info->dma_id);
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000845 if (IS_ERR(src->dma))
846 return PTR_ERR(src->dma);
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700847
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800848 return ret;
849}
850
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800851static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000852 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000853 struct rsnd_priv *priv)
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800854{
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000855 struct rsnd_src *src = rsnd_mod_to_src(mod);
856
857 rsnd_dma_quit(io, rsnd_src_to_dma(src));
Kuninori Morimoto76c6fb52014-03-03 20:50:41 -0800858
859 return 0;
860}
861
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800862static int rsnd_src_init_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000863 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000864 struct rsnd_priv *priv)
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800865{
866 int ret;
867
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000868 ret = rsnd_src_init(mod, priv);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800869 if (ret < 0)
870 return ret;
871
Kuninori Morimoto4e2639f2015-06-15 06:26:08 +0000872 ret = rsnd_src_set_convert_rate_gen2(mod, io);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800873 if (ret < 0)
874 return ret;
875
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000876 ret = rsnd_src_set_convert_timing_gen2(io, mod);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800877 if (ret < 0)
878 return ret;
879
880 return 0;
881}
882
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800883static int rsnd_src_start_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000884 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000885 struct rsnd_priv *priv)
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800886{
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000887 struct rsnd_src *src = rsnd_mod_to_src(mod);
888
889 rsnd_dma_start(io, rsnd_src_to_dma(src));
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800890
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000891 return _rsnd_src_start_gen2(mod, io);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800892}
893
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800894static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000895 struct rsnd_dai_stream *io,
Kuninori Morimoto690602f2015-01-15 08:07:47 +0000896 struct rsnd_priv *priv)
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800897{
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000898 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000899 int ret;
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800900
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000901 ret = _rsnd_src_stop_gen2(mod);
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800902
Kuninori Morimoto232c00b2015-10-26 08:38:26 +0000903 rsnd_dma_stop(io, rsnd_src_to_dma(src));
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800904
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000905 return ret;
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800906}
907
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000908static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
909 struct rsnd_mod *mod)
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000910{
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000911 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
912 struct rsnd_src *src = rsnd_mod_to_src(mod);
Kuninori Morimoto88c61cf2015-06-15 06:27:13 +0000913 u32 convert_rate = rsnd_src_convert_rate(io, src);
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000914 u32 fsrate;
915
916 if (!runtime)
917 return;
918
919 if (!convert_rate)
920 convert_rate = runtime->rate;
921
922 fsrate = 0x0400000 / convert_rate * runtime->rate;
923
924 /* update IFS */
925 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
926}
927
Kuninori Morimotob9bfe9d2015-09-10 06:49:12 +0000928static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
Kuninori Morimoto2c0fac12015-06-15 06:25:20 +0000929 struct rsnd_dai_stream *io,
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000930 struct snd_soc_pcm_runtime *rtd)
931{
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000932 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
933 struct rsnd_src *src = rsnd_mod_to_src(mod);
934 int ret;
935
936 /*
937 * enable SRC sync convert if possible
938 */
939
940 /*
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000941 * SRC sync convert needs clock master
942 */
943 if (!rsnd_rdai_is_clk_master(rdai))
944 return 0;
945
946 /*
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000947 * enable sync convert
948 */
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000949 ret = rsnd_kctrl_new_s(mod, io, rtd,
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000950 rsnd_io_is_play(io) ?
951 "SRC Out Rate Switch" :
952 "SRC In Rate Switch",
953 rsnd_src_reconvert_update,
954 &src->sen, 1);
955 if (ret < 0)
956 return ret;
957
Kuninori Morimotob65a7cc2015-06-15 06:27:28 +0000958 ret = rsnd_kctrl_new_s(mod, io, rtd,
Kuninori Morimoto43cb6952015-04-01 04:15:16 +0000959 rsnd_io_is_play(io) ?
960 "SRC Out Rate" :
961 "SRC In Rate",
962 rsnd_src_reconvert_update,
963 &src->sync, 192000);
964
965 return ret;
966}
967
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800968static struct rsnd_mod_ops rsnd_src_gen2_ops = {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -0700969 .name = SRC_NAME,
Kuninori Morimoto72adc612015-02-20 10:31:23 +0000970 .dma_req = rsnd_src_dma_req,
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800971 .probe = rsnd_src_probe_gen2,
972 .remove = rsnd_src_remove_gen2,
973 .init = rsnd_src_init_gen2,
974 .quit = rsnd_src_quit,
975 .start = rsnd_src_start_gen2,
976 .stop = rsnd_src_stop_gen2,
Kuninori Morimoto3b7843f2015-03-26 04:02:51 +0000977 .hw_params = rsnd_src_hw_params,
Kuninori Morimotob9bfe9d2015-09-10 06:49:12 +0000978 .pcm_new = rsnd_src_pcm_new_gen2,
Kuninori Morimoto629509c2014-01-23 18:42:00 -0800979};
980
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800981struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700982{
Kuninori Morimotoba9c9492014-03-03 20:51:21 -0800983 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
Takashi Iwai8b147192013-11-05 18:40:05 +0100984 id = 0;
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700985
Kuninori Morimotob76e2182015-09-10 07:02:21 +0000986 return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
Kuninori Morimoto07539c12013-07-21 21:36:35 -0700987}
988
Kuninori Morimoto90e8e502014-03-17 19:29:55 -0700989static void rsnd_of_parse_src(struct platform_device *pdev,
990 const struct rsnd_of_data *of_data,
991 struct rsnd_priv *priv)
992{
993 struct device_node *src_node;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000994 struct device_node *np;
Kuninori Morimoto90e8e502014-03-17 19:29:55 -0700995 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
996 struct rsnd_src_platform_info *src_info;
997 struct device *dev = &pdev->dev;
Kuninori Morimotocfcefe02015-01-08 01:52:36 +0000998 int nr, i;
Kuninori Morimoto90e8e502014-03-17 19:29:55 -0700999
1000 if (!of_data)
1001 return;
1002
Kuninori Morimoto82e76ed2015-02-20 10:30:22 +00001003 src_node = rsnd_src_of_node(priv);
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001004 if (!src_node)
1005 return;
1006
1007 nr = of_get_child_count(src_node);
1008 if (!nr)
Kuninori Morimotof451e482014-05-22 23:24:59 -07001009 goto rsnd_of_parse_src_end;
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001010
1011 src_info = devm_kzalloc(dev,
1012 sizeof(struct rsnd_src_platform_info) * nr,
1013 GFP_KERNEL);
1014 if (!src_info) {
1015 dev_err(dev, "src info allocation error\n");
Kuninori Morimotof451e482014-05-22 23:24:59 -07001016 goto rsnd_of_parse_src_end;
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001017 }
1018
1019 info->src_info = src_info;
1020 info->src_info_nr = nr;
Kuninori Morimotof451e482014-05-22 23:24:59 -07001021
Kuninori Morimotocfcefe02015-01-08 01:52:36 +00001022 i = 0;
1023 for_each_child_of_node(src_node, np) {
1024 src_info[i].irq = irq_of_parse_and_map(np, 0);
1025
1026 i++;
1027 }
1028
Kuninori Morimotof451e482014-05-22 23:24:59 -07001029rsnd_of_parse_src_end:
1030 of_node_put(src_node);
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001031}
1032
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001033int rsnd_src_probe(struct platform_device *pdev,
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001034 const struct rsnd_of_data *of_data,
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001035 struct rsnd_priv *priv)
1036{
Kuninori Morimoto5da39cf2014-02-24 22:15:00 -08001037 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001038 struct device *dev = rsnd_priv_to_dev(priv);
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001039 struct rsnd_src *src;
Kuninori Morimoto013f38f2014-01-23 18:38:26 -08001040 struct rsnd_mod_ops *ops;
Kuninori Morimotoef749402013-12-19 19:28:51 -08001041 struct clk *clk;
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001042 char name[RSND_SRC_NAME_SIZE];
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +00001043 int i, nr, ret;
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001044
Kuninori Morimoto033e7ed2014-05-22 23:25:37 -07001045 ops = NULL;
Kuninori Morimoto43624952015-10-14 08:56:07 +00001046 if (rsnd_is_gen1(priv)) {
Kuninori Morimoto033e7ed2014-05-22 23:25:37 -07001047 ops = &rsnd_src_gen1_ops;
Kuninori Morimoto43624952015-10-14 08:56:07 +00001048 dev_warn(dev, "Gen1 support will be removed soon\n");
1049 }
Kuninori Morimoto033e7ed2014-05-22 23:25:37 -07001050 if (rsnd_is_gen2(priv))
1051 ops = &rsnd_src_gen2_ops;
1052 if (!ops) {
1053 dev_err(dev, "unknown Generation\n");
1054 return -EIO;
1055 }
1056
Kuninori Morimoto90e8e502014-03-17 19:29:55 -07001057 rsnd_of_parse_src(pdev, of_data, priv);
1058
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001059 /*
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001060 * init SRC
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001061 */
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001062 nr = info->src_info_nr;
Kuninori Morimoto389933d2014-03-03 20:50:00 -08001063 if (!nr)
1064 return 0;
1065
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001066 src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
Kuninori Morimoto33363f72015-07-15 07:08:44 +00001067 if (!src)
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001068 return -ENOMEM;
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001069
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001070 priv->src_nr = nr;
1071 priv->src = src;
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001072
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001073 for_each_rsnd_src(src, priv, i) {
Kuninori Morimoto8aefda52014-05-22 23:25:43 -07001074 snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
1075 SRC_NAME, i);
Kuninori Morimotoef749402013-12-19 19:28:51 -08001076
1077 clk = devm_clk_get(dev, name);
1078 if (IS_ERR(clk))
1079 return PTR_ERR(clk);
1080
Kuninori Morimotoba9c9492014-03-03 20:51:21 -08001081 src->info = &info->src_info[i];
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001082
Kuninori Morimotob76e2182015-09-10 07:02:21 +00001083 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +00001084 if (ret)
1085 return ret;
Kuninori Morimoto374a52812013-07-28 18:59:12 -07001086 }
Kuninori Morimoto07539c12013-07-21 21:36:35 -07001087
1088 return 0;
1089}
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +00001090
1091void rsnd_src_remove(struct platform_device *pdev,
1092 struct rsnd_priv *priv)
1093{
1094 struct rsnd_src *src;
1095 int i;
1096
1097 for_each_rsnd_src(src, priv, i) {
Kuninori Morimotob76e2182015-09-10 07:02:21 +00001098 rsnd_mod_quit(rsnd_mod_get(src));
Kuninori Morimoto2f78dd72015-03-26 04:02:09 +00001099 }
1100}