aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-12-19 22:28:51 -0500
committerMark Brown <broonie@linaro.org>2013-12-31 08:35:31 -0500
commitef749400434cefd14fe02fe3de9e9f0125b2256d (patch)
tree2cd4dbdb054ad59d84e5eaefb75484aa6be8ac96
parentadcf7d5e7605e8134a99d415b7afd13f03c4bf23 (diff)
ASoC: rsnd: add SRC (Sampling Rate Converter) support
This patch adds SRC support to Renesas sound driver. SRC converts sampling rate between codec <-> cpu. It needs special codec chip, or very simple DA/AD converter to use it. This patch was tested via ak4554 codec, and supports Gen1 only at this point. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--include/sound/rcar_snd.h1
-rw-r--r--sound/soc/sh/rcar/adg.c73
-rw-r--r--sound/soc/sh/rcar/gen.c10
-rw-r--r--sound/soc/sh/rcar/rsnd.h18
-rw-r--r--sound/soc/sh/rcar/scu.c152
-rw-r--r--sound/soc/sh/rcar/ssi.c2
6 files changed, 248 insertions, 8 deletions
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
index a818ff76b138..e147498abe50 100644
--- a/include/sound/rcar_snd.h
+++ b/include/sound/rcar_snd.h
@@ -58,6 +58,7 @@ struct rsnd_ssi_platform_info {
58 58
59struct rsnd_scu_platform_info { 59struct rsnd_scu_platform_info {
60 u32 flags; 60 u32 flags;
61 u32 convert_rate; /* sampling rate convert */
61}; 62};
62 63
63/* 64/*
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 2e71a7bda4c2..a53235c4d1b0 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -30,6 +30,79 @@ struct rsnd_adg {
30 i++, (pos) = adg->clk[i]) 30 i++, (pos) = adg->clk[i])
31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
32 32
33static int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
34 struct rsnd_mod *mod,
35 unsigned int src_rate,
36 unsigned int dst_rate)
37{
38 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
39 struct device *dev = rsnd_priv_to_dev(priv);
40 int idx, sel, div, shift;
41 u32 mask, val;
42 int id = rsnd_mod_id(mod);
43 unsigned int sel_rate [] = {
44 clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */
45 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
46 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
47 0, /* 011: MLBCLK (not used) */
48 adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */
49 adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */
50 };
51
52 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
53 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) {
54 for (div = 128, idx = 0;
55 div <= 2048;
56 div *= 2, idx++) {
57 if (src_rate == sel_rate[sel] / div) {
58 val = (idx << 4) | sel;
59 goto find_rate;
60 }
61 }
62 }
63 dev_err(dev, "can't find convert src clk\n");
64 return -EINVAL;
65
66find_rate:
67 shift = (id % 4) * 8;
68 mask = 0xFF << shift;
69 val = val << shift;
70
71 dev_dbg(dev, "adg convert src clk = %02x\n", val);
72
73 switch (id / 4) {
74 case 0:
75 rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val);
76 break;
77 case 1:
78 rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val);
79 break;
80 case 2:
81 rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val);
82 break;
83 }
84
85 /*
86 * Gen1 doesn't need dst_rate settings,
87 * since it uses SSI WS pin.
88 * see also rsnd_src_set_route_if_gen1()
89 */
90
91 return 0;
92}
93
94int rsnd_adg_set_convert_clk(struct rsnd_priv *priv,
95 struct rsnd_mod *mod,
96 unsigned int src_rate,
97 unsigned int dst_rate)
98{
99 if (rsnd_is_gen1(priv))
100 return rsnd_adg_set_convert_clk_gen1(priv, mod,
101 src_rate, dst_rate);
102
103 return -EINVAL;
104}
105
33static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) 106static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
34{ 107{
35 int id = rsnd_mod_id(mod); 108 int id = rsnd_mod_id(mod);
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 862758d3ec06..add088bd4b2a 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -318,13 +318,23 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
318 RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), 318 RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0),
319 RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), 319 RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4),
320 RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4), 320 RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4),
321 RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8),
322 RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40),
323 RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40),
321 RSND_GEN1_M_REG(gen, SRU, SRC_ADINR, 0x214, 0x40), 324 RSND_GEN1_M_REG(gen, SRU, SRC_ADINR, 0x214, 0x40),
325 RSND_GEN1_M_REG(gen, SRU, SRC_IFSCR, 0x21c, 0x40),
326 RSND_GEN1_M_REG(gen, SRU, SRC_IFSVR, 0x220, 0x40),
327 RSND_GEN1_M_REG(gen, SRU, SRC_SRCCR, 0x224, 0x40),
328 RSND_GEN1_M_REG(gen, SRU, SRC_MNFSR, 0x228, 0x40),
322 329
323 RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00), 330 RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00),
324 RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04), 331 RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04),
325 RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08), 332 RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08),
326 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 333 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c),
327 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 334 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10),
335 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18),
336 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c),
337 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20),
328 338
329 RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40), 339 RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40),
330 RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40), 340 RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40),
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 3774dfcfaf0f..4ca66cd899c8 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -41,7 +41,14 @@ enum rsnd_reg {
41 RSND_REG_SSI_MODE1, 41 RSND_REG_SSI_MODE1,
42 RSND_REG_BUSIF_MODE, 42 RSND_REG_BUSIF_MODE,
43 RSND_REG_INT_ENABLE, /* for Gen2 */ 43 RSND_REG_INT_ENABLE, /* for Gen2 */
44 RSND_REG_SRC_ROUTE_MODE0,
45 RSND_REG_SRC_SWRSR,
46 RSND_REG_SRC_SRCIR,
44 RSND_REG_SRC_ADINR, 47 RSND_REG_SRC_ADINR,
48 RSND_REG_SRC_IFSCR,
49 RSND_REG_SRC_IFSVR,
50 RSND_REG_SRC_SRCCR,
51 RSND_REG_SRC_MNFSR,
45 52
46 /* ADG */ 53 /* ADG */
47 RSND_REG_BRRA, 54 RSND_REG_BRRA,
@@ -50,6 +57,9 @@ enum rsnd_reg {
50 RSND_REG_AUDIO_CLK_SEL0, 57 RSND_REG_AUDIO_CLK_SEL0,
51 RSND_REG_AUDIO_CLK_SEL1, 58 RSND_REG_AUDIO_CLK_SEL1,
52 RSND_REG_AUDIO_CLK_SEL2, 59 RSND_REG_AUDIO_CLK_SEL2,
60 RSND_REG_AUDIO_CLK_SEL3, /* for Gen1 */
61 RSND_REG_AUDIO_CLK_SEL4, /* for Gen1 */
62 RSND_REG_AUDIO_CLK_SEL5, /* for Gen1 */
53 63
54 /* SSI */ 64 /* SSI */
55 RSND_REG_SSICR, 65 RSND_REG_SSICR,
@@ -227,6 +237,10 @@ int rsnd_adg_probe(struct platform_device *pdev,
227 struct rsnd_priv *priv); 237 struct rsnd_priv *priv);
228void rsnd_adg_remove(struct platform_device *pdev, 238void rsnd_adg_remove(struct platform_device *pdev,
229 struct rsnd_priv *priv); 239 struct rsnd_priv *priv);
240int rsnd_adg_set_convert_clk(struct rsnd_priv *priv,
241 struct rsnd_mod *mod,
242 unsigned int src_rate,
243 unsigned int dst_rate);
230 244
231/* 245/*
232 * R-Car sound priv 246 * R-Car sound priv
@@ -280,6 +294,10 @@ void rsnd_scu_remove(struct platform_device *pdev,
280 struct rsnd_priv *priv); 294 struct rsnd_priv *priv);
281struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); 295struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id);
282bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod); 296bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod);
297unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
298 struct rsnd_mod *ssi_mod,
299 struct snd_pcm_runtime *runtime);
300
283#define rsnd_scu_nr(priv) ((priv)->scu_nr) 301#define rsnd_scu_nr(priv) ((priv)->scu_nr)
284 302
285/* 303/*
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
index 5f4f57206faf..1406dd8d9ed2 100644
--- a/sound/soc/sh/rcar/scu.c
+++ b/sound/soc/sh/rcar/scu.c
@@ -13,9 +13,13 @@
13struct rsnd_scu { 13struct rsnd_scu {
14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */ 14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */
15 struct rsnd_mod mod; 15 struct rsnd_mod mod;
16 struct clk *clk;
16}; 17};
17 18
18#define rsnd_scu_mode_flags(p) ((p)->info->flags) 19#define rsnd_scu_mode_flags(p) ((p)->info->flags)
20#define rsnd_scu_convert_rate(p) ((p)->info->convert_rate)
21
22#define RSND_SCU_NAME_SIZE 16
19 23
20/* 24/*
21 * ADINR 25 * ADINR
@@ -26,6 +30,15 @@ struct rsnd_scu {
26#define OTBL_18 (6 << 16) 30#define OTBL_18 (6 << 16)
27#define OTBL_16 (8 << 16) 31#define OTBL_16 (8 << 16)
28 32
33/*
34 * image of SRC (Sampling Rate Converter)
35 *
36 * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+
37 * 48kHz <-> | SRC | <------> | SSI | <-----> | codec |
38 * 44.1kHz <-> +-----+ +-----+ +-------+
39 * ...
40 *
41 */
29 42
30#define rsnd_mod_to_scu(_mod) \ 43#define rsnd_mod_to_scu(_mod) \
31 container_of((_mod), struct rsnd_scu, mod) 44 container_of((_mod), struct rsnd_scu, mod)
@@ -56,7 +69,7 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
56 { 0x3, 28, }, /* 7 */ 69 { 0x3, 28, }, /* 7 */
57 { 0x3, 30, }, /* 8 */ 70 { 0x3, 30, }, /* 8 */
58 }; 71 };
59 72 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
60 u32 mask; 73 u32 mask;
61 u32 val; 74 u32 val;
62 int shift; 75 int shift;
@@ -86,9 +99,18 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
86 */ 99 */
87 shift = (id % 4) * 8; 100 shift = (id % 4) * 8;
88 mask = 0x1F << shift; 101 mask = 0x1F << shift;
89 if (8 == id) /* SRU8 is very special */ 102
103 /*
104 * ADG is used as source clock if SRC was used,
105 * then, SSI WS is used as destination clock.
106 * SSI WS is used as source clock if SRC is not used
107 * (when playback, source/destination become reverse when capture)
108 */
109 if (rsnd_scu_convert_rate(scu)) /* use ADG */
110 val = 0;
111 else if (8 == id) /* use SSI WS, but SRU8 is special */
90 val = id << shift; 112 val = id << shift;
91 else 113 else /* use SSI WS */
92 val = (id + 1) << shift; 114 val = (id + 1) << shift;
93 115
94 switch (id / 4) { 116 switch (id / 4) {
@@ -106,14 +128,45 @@ static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv,
106 return 0; 128 return 0;
107} 129}
108 130
109static int rsnd_scu_rate_ctrl(struct rsnd_priv *priv, 131unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv,
132 struct rsnd_mod *ssi_mod,
133 struct snd_pcm_runtime *runtime)
134{
135 struct rsnd_scu *scu;
136 unsigned int rate;
137
138 /* this function is assuming SSI id = SCU id here */
139 scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod)));
140
141 /*
142 * return convert rate if SRC is used,
143 * otherwise, return runtime->rate as usual
144 */
145 rate = rsnd_scu_convert_rate(scu);
146 if (!rate)
147 rate = runtime->rate;
148
149 return rate;
150}
151
152static int rsnd_scu_convert_rate_ctrl(struct rsnd_priv *priv,
110 struct rsnd_mod *mod, 153 struct rsnd_mod *mod,
111 struct rsnd_dai *rdai, 154 struct rsnd_dai *rdai,
112 struct rsnd_dai_stream *io) 155 struct rsnd_dai_stream *io)
113{ 156{
114 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 157 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
158 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
159 u32 convert_rate = rsnd_scu_convert_rate(scu);
115 u32 adinr = runtime->channels; 160 u32 adinr = runtime->channels;
116 161
162 /* set/clear soft reset */
163 rsnd_mod_write(mod, SRC_SWRSR, 0);
164 rsnd_mod_write(mod, SRC_SWRSR, 1);
165
166 /* Initialize the operation of the SRC internal circuits */
167 rsnd_mod_write(mod, SRC_SRCIR, 1);
168
169 /* Set channel number and output bit length */
117 switch (runtime->sample_bits) { 170 switch (runtime->sample_bits) {
118 case 16: 171 case 16:
119 adinr |= OTBL_16; 172 adinr |= OTBL_16;
@@ -124,9 +177,42 @@ static int rsnd_scu_rate_ctrl(struct rsnd_priv *priv,
124 default: 177 default:
125 return -EIO; 178 return -EIO;
126 } 179 }
127
128 rsnd_mod_write(mod, SRC_ADINR, adinr); 180 rsnd_mod_write(mod, SRC_ADINR, adinr);
129 181
182 if (convert_rate) {
183 u32 fsrate = 0x0400000 / convert_rate * runtime->rate;
184 int ret;
185
186 /* Enable the initial value of IFS */
187 rsnd_mod_write(mod, SRC_IFSCR, 1);
188
189 /* Set initial value of IFS */
190 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
191
192 /* Select SRC mode (fixed value) */
193 rsnd_mod_write(mod, SRC_SRCCR, 0x00010110);
194
195 /* Set the restriction value of the FS ratio (98%) */
196 rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98);
197
198 if (rsnd_is_gen1(priv)) {
199 /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
200 }
201
202 /* set convert clock */
203 ret = rsnd_adg_set_convert_clk(priv, mod,
204 runtime->rate,
205 convert_rate);
206 if (ret < 0)
207 return ret;
208 }
209
210 /* Cancel the initialization and operate the SRC function */
211 rsnd_mod_write(mod, SRC_SRCIR, 0);
212
213 /* use DMA transfer */
214 rsnd_mod_write(mod, BUSIF_MODE, 1);
215
130 return 0; 216 return 0;
131} 217}
132 218
@@ -135,6 +221,7 @@ static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
135 struct rsnd_dai *rdai, 221 struct rsnd_dai *rdai,
136 struct rsnd_dai_stream *io) 222 struct rsnd_dai_stream *io)
137{ 223{
224 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
138 int id = rsnd_mod_id(mod); 225 int id = rsnd_mod_id(mod);
139 u32 val; 226 u32 val;
140 227
@@ -143,7 +230,28 @@ static int rsnd_scu_transfer_start(struct rsnd_priv *priv,
143 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val); 230 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val);
144 } 231 }
145 232
146 rsnd_mod_write(mod, BUSIF_MODE, 1); 233 if (rsnd_scu_convert_rate(scu))
234 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
235
236 return 0;
237}
238
239static int rsnd_scu_transfer_stop(struct rsnd_priv *priv,
240 struct rsnd_mod *mod,
241 struct rsnd_dai *rdai,
242 struct rsnd_dai_stream *io)
243{
244 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
245 int id = rsnd_mod_id(mod);
246 u32 mask;
247
248 if (rsnd_is_gen1(priv)) {
249 mask = (1 << id);
250 rsnd_mod_bset(mod, SRC_ROUTE_CTRL, mask, 0);
251 }
252
253 if (rsnd_scu_convert_rate(scu))
254 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0);
147 255
148 return 0; 256 return 0;
149} 257}
@@ -161,6 +269,7 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
161 struct rsnd_dai_stream *io) 269 struct rsnd_dai_stream *io)
162{ 270{
163 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 271 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
272 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
164 struct device *dev = rsnd_priv_to_dev(priv); 273 struct device *dev = rsnd_priv_to_dev(priv);
165 int ret; 274 int ret;
166 275
@@ -175,13 +284,15 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
175 return 0; 284 return 0;
176 } 285 }
177 286
287 clk_enable(scu->clk);
288
178 /* it use DMA transter */ 289 /* it use DMA transter */
179 290
180 ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io); 291 ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io);
181 if (ret < 0) 292 if (ret < 0)
182 return ret; 293 return ret;
183 294
184 ret = rsnd_scu_rate_ctrl(priv, mod, rdai, io); 295 ret = rsnd_scu_convert_rate_ctrl(priv, mod, rdai, io);
185 if (ret < 0) 296 if (ret < 0)
186 return ret; 297 return ret;
187 298
@@ -194,9 +305,27 @@ static int rsnd_scu_start(struct rsnd_mod *mod,
194 return 0; 305 return 0;
195} 306}
196 307
308static int rsnd_scu_stop(struct rsnd_mod *mod,
309 struct rsnd_dai *rdai,
310 struct rsnd_dai_stream *io)
311{
312 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
313 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
314
315 if (!rsnd_scu_hpbif_is_enable(mod))
316 return 0;
317
318 rsnd_scu_transfer_stop(priv, mod, rdai, io);
319
320 clk_disable(scu->clk);
321
322 return 0;
323}
324
197static struct rsnd_mod_ops rsnd_scu_ops = { 325static struct rsnd_mod_ops rsnd_scu_ops = {
198 .name = "scu", 326 .name = "scu",
199 .start = rsnd_scu_start, 327 .start = rsnd_scu_start,
328 .stop = rsnd_scu_stop,
200}; 329};
201 330
202struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) 331struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
@@ -212,6 +341,8 @@ int rsnd_scu_probe(struct platform_device *pdev,
212{ 341{
213 struct device *dev = rsnd_priv_to_dev(priv); 342 struct device *dev = rsnd_priv_to_dev(priv);
214 struct rsnd_scu *scu; 343 struct rsnd_scu *scu;
344 struct clk *clk;
345 char name[RSND_SCU_NAME_SIZE];
215 int i, nr; 346 int i, nr;
216 347
217 /* 348 /*
@@ -228,9 +359,16 @@ int rsnd_scu_probe(struct platform_device *pdev,
228 priv->scu = scu; 359 priv->scu = scu;
229 360
230 for_each_rsnd_scu(scu, priv, i) { 361 for_each_rsnd_scu(scu, priv, i) {
362 snprintf(name, RSND_SCU_NAME_SIZE, "scu.%d", i);
363
364 clk = devm_clk_get(dev, name);
365 if (IS_ERR(clk))
366 return PTR_ERR(clk);
367
231 rsnd_mod_init(priv, &scu->mod, 368 rsnd_mod_init(priv, &scu->mod,
232 &rsnd_scu_ops, i); 369 &rsnd_scu_ops, i);
233 scu->info = &info->scu_info[i]; 370 scu->info = &info->scu_info[i];
371 scu->clk = clk;
234 372
235 dev_dbg(dev, "SCU%d probed\n", i); 373 dev_dbg(dev, "SCU%d probed\n", i);
236 } 374 }
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 2db9711549f5..b7cd06be9436 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -200,7 +200,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
200 1, 2, 4, 8, 16, 6, 12, 200 1, 2, 4, 8, 16, 6, 12,
201 }; 201 };
202 unsigned int main_rate; 202 unsigned int main_rate;
203 unsigned int rate = runtime->rate; 203 unsigned int rate = rsnd_scu_get_ssi_rate(priv, &ssi->mod, runtime);
204 204
205 /* 205 /*
206 * Find best clock, and try to start ADG 206 * Find best clock, and try to start ADG