aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar/ssi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/rcar/ssi.c')
-rw-r--r--sound/soc/sh/rcar/ssi.c89
1 files changed, 17 insertions, 72 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 4b7e20603dd7..36654bd4e428 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -171,7 +171,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
171 u32 cr; 171 u32 cr;
172 172
173 if (0 == ssi->usrcnt) { 173 if (0 == ssi->usrcnt) {
174 clk_enable(ssi->clk); 174 clk_prepare_enable(ssi->clk);
175 175
176 if (rsnd_dai_is_clk_master(rdai)) { 176 if (rsnd_dai_is_clk_master(rdai)) {
177 if (rsnd_ssi_clk_from_parent(ssi)) 177 if (rsnd_ssi_clk_from_parent(ssi))
@@ -230,7 +230,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
230 rsnd_ssi_master_clk_stop(ssi); 230 rsnd_ssi_master_clk_stop(ssi);
231 } 231 }
232 232
233 clk_disable(ssi->clk); 233 clk_disable_unprepare(ssi->clk);
234 } 234 }
235 235
236 dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); 236 dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod));
@@ -240,10 +240,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
240 * SSI mod common functions 240 * SSI mod common functions
241 */ 241 */
242static int rsnd_ssi_init(struct rsnd_mod *mod, 242static int rsnd_ssi_init(struct rsnd_mod *mod,
243 struct rsnd_dai *rdai, 243 struct rsnd_dai *rdai)
244 struct rsnd_dai_stream *io)
245{ 244{
246 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 245 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
246 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
247 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 247 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
248 u32 cr; 248 u32 cr;
249 249
@@ -287,14 +287,13 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
287 ssi->cr_own = cr; 287 ssi->cr_own = cr;
288 ssi->err = -1; /* ignore 1st error */ 288 ssi->err = -1; /* ignore 1st error */
289 289
290 rsnd_src_ssi_mode_init(mod, rdai, io); 290 rsnd_src_ssi_mode_init(mod, rdai);
291 291
292 return 0; 292 return 0;
293} 293}
294 294
295static int rsnd_ssi_quit(struct rsnd_mod *mod, 295static int rsnd_ssi_quit(struct rsnd_mod *mod,
296 struct rsnd_dai *rdai, 296 struct rsnd_dai *rdai)
297 struct rsnd_dai_stream *io)
298{ 297{
299 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 298 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
300 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 299 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
@@ -359,8 +358,7 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
359} 358}
360 359
361static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, 360static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
362 struct rsnd_dai *rdai, 361 struct rsnd_dai *rdai)
363 struct rsnd_dai_stream *io)
364{ 362{
365 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 363 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
366 struct device *dev = rsnd_priv_to_dev(priv); 364 struct device *dev = rsnd_priv_to_dev(priv);
@@ -379,15 +377,15 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
379} 377}
380 378
381static int rsnd_ssi_pio_start(struct rsnd_mod *mod, 379static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
382 struct rsnd_dai *rdai, 380 struct rsnd_dai *rdai)
383 struct rsnd_dai_stream *io)
384{ 381{
385 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 382 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
383 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
386 384
387 /* enable PIO IRQ */ 385 /* enable PIO IRQ */
388 ssi->cr_etc = UIEN | OIEN | DIEN; 386 ssi->cr_etc = UIEN | OIEN | DIEN;
389 387
390 rsnd_src_enable_ssi_irq(mod, rdai, io); 388 rsnd_src_enable_ssi_irq(mod, rdai);
391 389
392 rsnd_ssi_hw_start(ssi, rdai, io); 390 rsnd_ssi_hw_start(ssi, rdai, io);
393 391
@@ -395,8 +393,7 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
395} 393}
396 394
397static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, 395static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
398 struct rsnd_dai *rdai, 396 struct rsnd_dai *rdai)
399 struct rsnd_dai_stream *io)
400{ 397{
401 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 398 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
402 399
@@ -417,25 +414,17 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
417}; 414};
418 415
419static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, 416static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
420 struct rsnd_dai *rdai, 417 struct rsnd_dai *rdai)
421 struct rsnd_dai_stream *io)
422{ 418{
423 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 419 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
424 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 420 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
425 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
426 struct device *dev = rsnd_priv_to_dev(priv); 421 struct device *dev = rsnd_priv_to_dev(priv);
427 int dma_id = ssi->info->dma_id; 422 int dma_id = ssi->info->dma_id;
428 int is_play;
429 int ret; 423 int ret;
430 424
431 if (info->dai_info)
432 is_play = rsnd_info_is_playback(priv, ssi);
433 else
434 is_play = rsnd_ssi_is_play(&ssi->mod);
435
436 ret = rsnd_dma_init( 425 ret = rsnd_dma_init(
437 priv, rsnd_mod_to_dma(mod), 426 priv, rsnd_mod_to_dma(mod),
438 is_play, 427 rsnd_info_is_playback(priv, ssi),
439 dma_id); 428 dma_id);
440 429
441 if (ret < 0) 430 if (ret < 0)
@@ -445,8 +434,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
445} 434}
446 435
447static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, 436static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
448 struct rsnd_dai *rdai, 437 struct rsnd_dai *rdai)
449 struct rsnd_dai_stream *io)
450{ 438{
451 rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); 439 rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod));
452 440
@@ -454,11 +442,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
454} 442}
455 443
456static int rsnd_ssi_dma_start(struct rsnd_mod *mod, 444static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
457 struct rsnd_dai *rdai, 445 struct rsnd_dai *rdai)
458 struct rsnd_dai_stream *io)
459{ 446{
460 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 447 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
461 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); 448 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
449 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
462 450
463 /* enable DMA transfer */ 451 /* enable DMA transfer */
464 ssi->cr_etc = DMEN; 452 ssi->cr_etc = DMEN;
@@ -475,8 +463,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
475} 463}
476 464
477static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, 465static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
478 struct rsnd_dai *rdai, 466 struct rsnd_dai *rdai)
479 struct rsnd_dai_stream *io)
480{ 467{
481 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 468 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
482 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); 469 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
@@ -512,41 +499,6 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = {
512/* 499/*
513 * ssi mod function 500 * ssi mod function
514 */ 501 */
515struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
516 int dai_id, int is_play)
517{
518 struct rsnd_dai_platform_info *dai_info = NULL;
519 struct rsnd_dai_path_info *path_info = NULL;
520 struct rsnd_ssi_platform_info *target_info = NULL;
521 struct rsnd_ssi *ssi;
522 int i, has_play;
523
524 if (priv->rdai)
525 dai_info = priv->rdai[dai_id].info;
526 if (dai_info)
527 path_info = (is_play) ? &dai_info->playback : &dai_info->capture;
528 if (path_info)
529 target_info = path_info->ssi;
530
531 is_play = !!is_play;
532
533 for_each_rsnd_ssi(ssi, priv, i) {
534 if (target_info == ssi->info)
535 return &ssi->mod;
536
537 /* for compatible */
538 if (rsnd_ssi_dai_id(ssi) != dai_id)
539 continue;
540
541 has_play = rsnd_ssi_is_play(&ssi->mod);
542
543 if (is_play == has_play)
544 return &ssi->mod;
545 }
546
547 return NULL;
548}
549
550struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) 502struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
551{ 503{
552 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 504 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
@@ -562,13 +514,6 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
562 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); 514 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
563} 515}
564 516
565int rsnd_ssi_is_play(struct rsnd_mod *mod)
566{
567 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
568
569 return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
570}
571
572static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) 517static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
573{ 518{
574 if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) 519 if (!rsnd_ssi_is_pin_sharing(&ssi->mod))