aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/rcar/core.c')
-rw-r--r--sound/soc/sh/rcar/core.c243
1 files changed, 118 insertions, 125 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index ed76901f8202..19f78963e8b9 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -138,6 +138,17 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
138 return mod->ops->name; 138 return mod->ops->name;
139} 139}
140 140
141char *rsnd_mod_dma_name(struct rsnd_mod *mod)
142{
143 if (!mod || !mod->ops)
144 return "unknown";
145
146 if (!mod->ops->dma_name)
147 return mod->ops->name;
148
149 return mod->ops->dma_name(mod);
150}
151
141void rsnd_mod_init(struct rsnd_priv *priv, 152void rsnd_mod_init(struct rsnd_priv *priv,
142 struct rsnd_mod *mod, 153 struct rsnd_mod *mod,
143 struct rsnd_mod_ops *ops, 154 struct rsnd_mod_ops *ops,
@@ -153,26 +164,8 @@ void rsnd_mod_init(struct rsnd_priv *priv,
153/* 164/*
154 * rsnd_dma functions 165 * rsnd_dma functions
155 */ 166 */
156static void __rsnd_dma_start(struct rsnd_dma *dma);
157static void rsnd_dma_continue(struct rsnd_dma *dma)
158{
159 /* push next A or B plane */
160 dma->submit_loop = 1;
161 schedule_work(&dma->work);
162}
163
164void rsnd_dma_start(struct rsnd_dma *dma)
165{
166 /* push both A and B plane*/
167 dma->offset = 0;
168 dma->submit_loop = 2;
169 __rsnd_dma_start(dma);
170}
171
172void rsnd_dma_stop(struct rsnd_dma *dma) 167void rsnd_dma_stop(struct rsnd_dma *dma)
173{ 168{
174 dma->submit_loop = 0;
175 cancel_work_sync(&dma->work);
176 dmaengine_terminate_all(dma->chan); 169 dmaengine_terminate_all(dma->chan);
177} 170}
178 171
@@ -180,11 +173,7 @@ static void rsnd_dma_complete(void *data)
180{ 173{
181 struct rsnd_dma *dma = (struct rsnd_dma *)data; 174 struct rsnd_dma *dma = (struct rsnd_dma *)data;
182 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 175 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
183 struct rsnd_priv *priv = rsnd_mod_to_priv(rsnd_dma_to_mod(dma));
184 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 176 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
185 unsigned long flags;
186
187 rsnd_lock(priv, flags);
188 177
189 /* 178 /*
190 * Renesas sound Gen1 needs 1 DMAC, 179 * Renesas sound Gen1 needs 1 DMAC,
@@ -197,57 +186,41 @@ static void rsnd_dma_complete(void *data)
197 * rsnd_dai_pointer_update() will be called twice, 186 * rsnd_dai_pointer_update() will be called twice,
198 * ant it will breaks io->byte_pos 187 * ant it will breaks io->byte_pos
199 */ 188 */
200 if (dma->submit_loop)
201 rsnd_dma_continue(dma);
202
203 rsnd_unlock(priv, flags);
204 189
205 rsnd_dai_pointer_update(io, io->byte_per_period); 190 rsnd_dai_pointer_update(io, io->byte_per_period);
206} 191}
207 192
208static void __rsnd_dma_start(struct rsnd_dma *dma) 193void rsnd_dma_start(struct rsnd_dma *dma)
209{ 194{
210 struct rsnd_mod *mod = rsnd_dma_to_mod(dma); 195 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
211 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 196 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
212 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 197 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
213 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 198 struct snd_pcm_substream *substream = io->substream;
214 struct device *dev = rsnd_priv_to_dev(priv); 199 struct device *dev = rsnd_priv_to_dev(priv);
215 struct dma_async_tx_descriptor *desc; 200 struct dma_async_tx_descriptor *desc;
216 dma_addr_t buf;
217 size_t len = io->byte_per_period;
218 int i;
219 201
220 for (i = 0; i < dma->submit_loop; i++) { 202 desc = dmaengine_prep_dma_cyclic(dma->chan,
221 203 (dma->addr) ? dma->addr :
222 buf = runtime->dma_addr + 204 substream->runtime->dma_addr,
223 rsnd_dai_pointer_offset(io, dma->offset + len); 205 snd_pcm_lib_buffer_bytes(substream),
224 dma->offset = len; 206 snd_pcm_lib_period_bytes(substream),
225 207 dma->dir,
226 desc = dmaengine_prep_slave_single( 208 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
227 dma->chan, buf, len, dma->dir,
228 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
229 if (!desc) {
230 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
231 return;
232 }
233 209
234 desc->callback = rsnd_dma_complete; 210 if (!desc) {
235 desc->callback_param = dma; 211 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
212 return;
213 }
236 214
237 if (dmaengine_submit(desc) < 0) { 215 desc->callback = rsnd_dma_complete;
238 dev_err(dev, "dmaengine_submit() fail\n"); 216 desc->callback_param = dma;
239 return;
240 }
241 217
242 dma_async_issue_pending(dma->chan); 218 if (dmaengine_submit(desc) < 0) {
219 dev_err(dev, "dmaengine_submit() fail\n");
220 return;
243 } 221 }
244}
245
246static void rsnd_dma_do_work(struct work_struct *work)
247{
248 struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work);
249 222
250 __rsnd_dma_start(dma); 223 dma_async_issue_pending(dma->chan);
251} 224}
252 225
253int rsnd_dma_available(struct rsnd_dma *dma) 226int rsnd_dma_available(struct rsnd_dma *dma)
@@ -261,14 +234,27 @@ static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
261{ 234{
262 if (mod) 235 if (mod)
263 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d", 236 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
264 rsnd_mod_name(mod), rsnd_mod_id(mod)); 237 rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
265 else 238 else
266 return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem"); 239 return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");
267 240
268} 241}
269 242
270static void rsnd_dma_of_name(struct rsnd_dma *dma, 243static void rsnd_dma_of_name(struct rsnd_mod *mod_from,
271 int is_play, char *dma_name) 244 struct rsnd_mod *mod_to,
245 char *dma_name)
246{
247 int index = 0;
248
249 index = _rsnd_dma_of_name(dma_name + index, mod_from);
250 *(dma_name + index++) = '_';
251 index = _rsnd_dma_of_name(dma_name + index, mod_to);
252}
253
254static void rsnd_dma_of_path(struct rsnd_dma *dma,
255 int is_play,
256 struct rsnd_mod **mod_from,
257 struct rsnd_mod **mod_to)
272{ 258{
273 struct rsnd_mod *this = rsnd_dma_to_mod(dma); 259 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
274 struct rsnd_dai_stream *io = rsnd_mod_to_io(this); 260 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
@@ -276,7 +262,6 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
276 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 262 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
277 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 263 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
278 struct rsnd_mod *mod[MOD_MAX]; 264 struct rsnd_mod *mod[MOD_MAX];
279 struct rsnd_mod *src_mod, *dst_mod;
280 int i, index; 265 int i, index;
281 266
282 267
@@ -301,7 +286,13 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
301 mod[i] = src; 286 mod[i] = src;
302 src = NULL; 287 src = NULL;
303 } else { 288 } else {
304 mod[i] = dvc; 289 if ((!is_play) && (this == src))
290 this = dvc;
291
292 mod[i] = (is_play) ? src : dvc;
293 i++;
294 mod[i] = (is_play) ? dvc : src;
295 src = NULL;
305 dvc = NULL; 296 dvc = NULL;
306 } 297 }
307 298
@@ -313,17 +304,12 @@ static void rsnd_dma_of_name(struct rsnd_dma *dma,
313 } 304 }
314 305
315 if (is_play) { 306 if (is_play) {
316 src_mod = mod[index - 1]; 307 *mod_from = mod[index - 1];
317 dst_mod = mod[index]; 308 *mod_to = mod[index];
318 } else { 309 } else {
319 src_mod = mod[index]; 310 *mod_from = mod[index];
320 dst_mod = mod[index - 1]; 311 *mod_to = mod[index - 1];
321 } 312 }
322
323 index = 0;
324 index = _rsnd_dma_of_name(dma_name + index, src_mod);
325 *(dma_name + index++) = '_';
326 index = _rsnd_dma_of_name(dma_name + index, dst_mod);
327} 313}
328 314
329int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 315int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
@@ -331,6 +317,8 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
331{ 317{
332 struct device *dev = rsnd_priv_to_dev(priv); 318 struct device *dev = rsnd_priv_to_dev(priv);
333 struct dma_slave_config cfg; 319 struct dma_slave_config cfg;
320 struct rsnd_mod *mod_from;
321 struct rsnd_mod *mod_to;
334 char dma_name[DMA_NAME_SIZE]; 322 char dma_name[DMA_NAME_SIZE];
335 dma_cap_mask_t mask; 323 dma_cap_mask_t mask;
336 int ret; 324 int ret;
@@ -343,13 +331,18 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
343 dma_cap_zero(mask); 331 dma_cap_zero(mask);
344 dma_cap_set(DMA_SLAVE, mask); 332 dma_cap_set(DMA_SLAVE, mask);
345 333
346 if (dev->of_node) 334 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
347 rsnd_dma_of_name(dma, is_play, dma_name); 335 rsnd_dma_of_name(mod_from, mod_to, dma_name);
348 else 336
349 snprintf(dma_name, DMA_NAME_SIZE, 337 cfg.slave_id = id;
350 is_play ? "tx" : "rx"); 338 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
339 cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1);
340 cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0);
341 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
342 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
351 343
352 dev_dbg(dev, "dma name : %s\n", dma_name); 344 dev_dbg(dev, "dma : %s %pad -> %pad\n",
345 dma_name, &cfg.src_addr, &cfg.dst_addr);
353 346
354 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, 347 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
355 (void *)id, dev, 348 (void *)id, dev,
@@ -359,14 +352,12 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
359 return -EIO; 352 return -EIO;
360 } 353 }
361 354
362 rsnd_gen_dma_addr(priv, dma, &cfg, is_play, id);
363
364 ret = dmaengine_slave_config(dma->chan, &cfg); 355 ret = dmaengine_slave_config(dma->chan, &cfg);
365 if (ret < 0) 356 if (ret < 0)
366 goto rsnd_dma_init_err; 357 goto rsnd_dma_init_err;
367 358
368 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 359 dma->addr = is_play ? cfg.src_addr : cfg.dst_addr;
369 INIT_WORK(&dma->work, rsnd_dma_do_work); 360 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
370 361
371 return 0; 362 return 0;
372 363
@@ -633,40 +624,41 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
633 return -EINVAL; 624 return -EINVAL;
634 } 625 }
635 626
636 /* set clock inversion */
637 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
638 case SND_SOC_DAIFMT_NB_IF:
639 rdai->bit_clk_inv = 0;
640 rdai->frm_clk_inv = 1;
641 break;
642 case SND_SOC_DAIFMT_IB_NF:
643 rdai->bit_clk_inv = 1;
644 rdai->frm_clk_inv = 0;
645 break;
646 case SND_SOC_DAIFMT_IB_IF:
647 rdai->bit_clk_inv = 1;
648 rdai->frm_clk_inv = 1;
649 break;
650 case SND_SOC_DAIFMT_NB_NF:
651 default:
652 rdai->bit_clk_inv = 0;
653 rdai->frm_clk_inv = 0;
654 break;
655 }
656
657 /* set format */ 627 /* set format */
658 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 628 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
659 case SND_SOC_DAIFMT_I2S: 629 case SND_SOC_DAIFMT_I2S:
660 rdai->sys_delay = 0; 630 rdai->sys_delay = 0;
661 rdai->data_alignment = 0; 631 rdai->data_alignment = 0;
632 rdai->frm_clk_inv = 0;
662 break; 633 break;
663 case SND_SOC_DAIFMT_LEFT_J: 634 case SND_SOC_DAIFMT_LEFT_J:
664 rdai->sys_delay = 1; 635 rdai->sys_delay = 1;
665 rdai->data_alignment = 0; 636 rdai->data_alignment = 0;
637 rdai->frm_clk_inv = 1;
666 break; 638 break;
667 case SND_SOC_DAIFMT_RIGHT_J: 639 case SND_SOC_DAIFMT_RIGHT_J:
668 rdai->sys_delay = 1; 640 rdai->sys_delay = 1;
669 rdai->data_alignment = 1; 641 rdai->data_alignment = 1;
642 rdai->frm_clk_inv = 1;
643 break;
644 }
645
646 /* set clock inversion */
647 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
648 case SND_SOC_DAIFMT_NB_IF:
649 rdai->bit_clk_inv = rdai->bit_clk_inv;
650 rdai->frm_clk_inv = !rdai->frm_clk_inv;
651 break;
652 case SND_SOC_DAIFMT_IB_NF:
653 rdai->bit_clk_inv = !rdai->bit_clk_inv;
654 rdai->frm_clk_inv = rdai->frm_clk_inv;
655 break;
656 case SND_SOC_DAIFMT_IB_IF:
657 rdai->bit_clk_inv = !rdai->bit_clk_inv;
658 rdai->frm_clk_inv = !rdai->frm_clk_inv;
659 break;
660 case SND_SOC_DAIFMT_NB_NF:
661 default:
670 break; 662 break;
671 } 663 }
672 664
@@ -736,12 +728,13 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
736 struct device_node *dai_node, *dai_np; 728 struct device_node *dai_node, *dai_np;
737 struct device_node *ssi_node, *ssi_np; 729 struct device_node *ssi_node, *ssi_np;
738 struct device_node *src_node, *src_np; 730 struct device_node *src_node, *src_np;
731 struct device_node *dvc_node, *dvc_np;
739 struct device_node *playback, *capture; 732 struct device_node *playback, *capture;
740 struct rsnd_dai_platform_info *dai_info; 733 struct rsnd_dai_platform_info *dai_info;
741 struct rcar_snd_info *info = rsnd_priv_to_info(priv); 734 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
742 struct device *dev = &pdev->dev; 735 struct device *dev = &pdev->dev;
743 int nr, i; 736 int nr, i;
744 int dai_i, ssi_i, src_i; 737 int dai_i, ssi_i, src_i, dvc_i;
745 738
746 if (!of_data) 739 if (!of_data)
747 return; 740 return;
@@ -767,6 +760,7 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
767 760
768 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); 761 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
769 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 762 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
763 dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
770 764
771#define mod_parse(name) \ 765#define mod_parse(name) \
772if (name##_node) { \ 766if (name##_node) { \
@@ -802,6 +796,7 @@ if (name##_node) { \
802 796
803 mod_parse(ssi); 797 mod_parse(ssi);
804 mod_parse(src); 798 mod_parse(src);
799 mod_parse(dvc);
805 800
806 if (playback) 801 if (playback)
807 of_node_put(playback); 802 of_node_put(playback);
@@ -950,19 +945,17 @@ static struct snd_pcm_ops rsnd_pcm_ops = {
950 945
951static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) 946static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
952{ 947{
953 struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 948 struct snd_soc_dai *dai = rtd->cpu_dai;
954 struct rsnd_dai *rdai; 949 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
955 int i, ret; 950 int ret;
956 951
957 for_each_rsnd_dai(rdai, priv, i) { 952 ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd);
958 ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd); 953 if (ret)
959 if (ret) 954 return ret;
960 return ret;
961 955
962 ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd); 956 ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd);
963 if (ret) 957 if (ret)
964 return ret; 958 return ret;
965 }
966 959
967 return snd_pcm_lib_preallocate_pages_for_all( 960 return snd_pcm_lib_preallocate_pages_for_all(
968 rtd->pcm, 961 rtd->pcm,
@@ -1049,11 +1042,11 @@ static int rsnd_probe(struct platform_device *pdev)
1049 for_each_rsnd_dai(rdai, priv, i) { 1042 for_each_rsnd_dai(rdai, priv, i) {
1050 ret = rsnd_dai_call(probe, &rdai->playback, rdai); 1043 ret = rsnd_dai_call(probe, &rdai->playback, rdai);
1051 if (ret) 1044 if (ret)
1052 return ret; 1045 goto exit_snd_probe;
1053 1046
1054 ret = rsnd_dai_call(probe, &rdai->capture, rdai); 1047 ret = rsnd_dai_call(probe, &rdai->capture, rdai);
1055 if (ret) 1048 if (ret)
1056 return ret; 1049 goto exit_snd_probe;
1057 } 1050 }
1058 1051
1059 /* 1052 /*
@@ -1081,6 +1074,11 @@ static int rsnd_probe(struct platform_device *pdev)
1081 1074
1082exit_snd_soc: 1075exit_snd_soc:
1083 snd_soc_unregister_platform(dev); 1076 snd_soc_unregister_platform(dev);
1077exit_snd_probe:
1078 for_each_rsnd_dai(rdai, priv, i) {
1079 rsnd_dai_call(remove, &rdai->playback, rdai);
1080 rsnd_dai_call(remove, &rdai->capture, rdai);
1081 }
1084 1082
1085 return ret; 1083 return ret;
1086} 1084}
@@ -1089,21 +1087,16 @@ static int rsnd_remove(struct platform_device *pdev)
1089{ 1087{
1090 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 1088 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
1091 struct rsnd_dai *rdai; 1089 struct rsnd_dai *rdai;
1092 int ret, i; 1090 int ret = 0, i;
1093 1091
1094 pm_runtime_disable(&pdev->dev); 1092 pm_runtime_disable(&pdev->dev);
1095 1093
1096 for_each_rsnd_dai(rdai, priv, i) { 1094 for_each_rsnd_dai(rdai, priv, i) {
1097 ret = rsnd_dai_call(remove, &rdai->playback, rdai); 1095 ret |= rsnd_dai_call(remove, &rdai->playback, rdai);
1098 if (ret) 1096 ret |= rsnd_dai_call(remove, &rdai->capture, rdai);
1099 return ret;
1100
1101 ret = rsnd_dai_call(remove, &rdai->capture, rdai);
1102 if (ret)
1103 return ret;
1104 } 1097 }
1105 1098
1106 return 0; 1099 return ret;
1107} 1100}
1108 1101
1109static struct platform_driver rsnd_driver = { 1102static struct platform_driver rsnd_driver = {