diff options
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r-- | sound/soc/sh/fsi.c | 94 |
1 files changed, 45 insertions, 49 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 7c93b7c2fdbd..7dec144b8466 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -364,8 +364,9 @@ static u32 fsi_get_info_flags(struct fsi_priv *fsi) | |||
364 | master->info->portb_flags; | 364 | master->info->portb_flags; |
365 | } | 365 | } |
366 | 366 | ||
367 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) | 367 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io) |
368 | { | 368 | { |
369 | int is_play = fsi_stream_is_play(fsi, io); | ||
369 | int is_porta = fsi_is_port_a(fsi); | 370 | int is_porta = fsi_is_port_a(fsi); |
370 | u32 shift; | 371 | u32 shift; |
371 | 372 | ||
@@ -434,15 +435,14 @@ static inline int fsi_stream_is_play(struct fsi_priv *fsi, | |||
434 | } | 435 | } |
435 | 436 | ||
436 | static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi, | 437 | static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi, |
437 | int is_play) | 438 | struct snd_pcm_substream *substream) |
438 | { | 439 | { |
439 | return is_play ? &fsi->playback : &fsi->capture; | 440 | return fsi_is_play(substream) ? &fsi->playback : &fsi->capture; |
440 | } | 441 | } |
441 | 442 | ||
442 | static int fsi_stream_is_working(struct fsi_priv *fsi, | 443 | static int fsi_stream_is_working(struct fsi_priv *fsi, |
443 | int is_play) | 444 | struct fsi_stream *io) |
444 | { | 445 | { |
445 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
446 | struct fsi_master *master = fsi_get_master(fsi); | 446 | struct fsi_master *master = fsi_get_master(fsi); |
447 | unsigned long flags; | 447 | unsigned long flags; |
448 | int ret; | 448 | int ret; |
@@ -460,10 +460,9 @@ static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io) | |||
460 | } | 460 | } |
461 | 461 | ||
462 | static void fsi_stream_init(struct fsi_priv *fsi, | 462 | static void fsi_stream_init(struct fsi_priv *fsi, |
463 | int is_play, | 463 | struct fsi_stream *io, |
464 | struct snd_pcm_substream *substream) | 464 | struct snd_pcm_substream *substream) |
465 | { | 465 | { |
466 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
467 | struct snd_pcm_runtime *runtime = substream->runtime; | 466 | struct snd_pcm_runtime *runtime = substream->runtime; |
468 | struct fsi_master *master = fsi_get_master(fsi); | 467 | struct fsi_master *master = fsi_get_master(fsi); |
469 | unsigned long flags; | 468 | unsigned long flags; |
@@ -480,9 +479,8 @@ static void fsi_stream_init(struct fsi_priv *fsi, | |||
480 | spin_unlock_irqrestore(&master->lock, flags); | 479 | spin_unlock_irqrestore(&master->lock, flags); |
481 | } | 480 | } |
482 | 481 | ||
483 | static void fsi_stream_quit(struct fsi_priv *fsi, int is_play) | 482 | static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io) |
484 | { | 483 | { |
485 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
486 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | 484 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); |
487 | struct fsi_master *master = fsi_get_master(fsi); | 485 | struct fsi_master *master = fsi_get_master(fsi); |
488 | unsigned long flags; | 486 | unsigned long flags; |
@@ -557,18 +555,18 @@ static int fsi_stream_remove(struct fsi_priv *fsi) | |||
557 | * irq function | 555 | * irq function |
558 | */ | 556 | */ |
559 | 557 | ||
560 | static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) | 558 | static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io) |
561 | { | 559 | { |
562 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); | 560 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, io)); |
563 | struct fsi_master *master = fsi_get_master(fsi); | 561 | struct fsi_master *master = fsi_get_master(fsi); |
564 | 562 | ||
565 | fsi_core_mask_set(master, imsk, data, data); | 563 | fsi_core_mask_set(master, imsk, data, data); |
566 | fsi_core_mask_set(master, iemsk, data, data); | 564 | fsi_core_mask_set(master, iemsk, data, data); |
567 | } | 565 | } |
568 | 566 | ||
569 | static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) | 567 | static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io) |
570 | { | 568 | { |
571 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); | 569 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, io)); |
572 | struct fsi_master *master = fsi_get_master(fsi); | 570 | struct fsi_master *master = fsi_get_master(fsi); |
573 | 571 | ||
574 | fsi_core_mask_set(master, imsk, data, 0); | 572 | fsi_core_mask_set(master, imsk, data, 0); |
@@ -585,8 +583,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi) | |||
585 | u32 data = 0; | 583 | u32 data = 0; |
586 | struct fsi_master *master = fsi_get_master(fsi); | 584 | struct fsi_master *master = fsi_get_master(fsi); |
587 | 585 | ||
588 | data |= AB_IO(1, fsi_get_port_shift(fsi, 0)); | 586 | data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback)); |
589 | data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); | 587 | data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture)); |
590 | 588 | ||
591 | /* clear interrupt factor */ | 589 | /* clear interrupt factor */ |
592 | fsi_core_mask_set(master, int_st, data, 0); | 590 | fsi_core_mask_set(master, int_st, data, 0); |
@@ -695,15 +693,16 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
695 | 693 | ||
696 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) | 694 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) |
697 | #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) | 695 | #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) |
698 | static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) | 696 | static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, struct fsi_stream *io, |
697 | int enable) | ||
699 | { | 698 | { |
700 | struct fsi_master *master = fsi_get_master(fsi); | 699 | struct fsi_master *master = fsi_get_master(fsi); |
701 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; | 700 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; |
702 | 701 | ||
703 | if (enable) | 702 | if (enable) |
704 | fsi_irq_enable(fsi, is_play); | 703 | fsi_irq_enable(fsi, io); |
705 | else | 704 | else |
706 | fsi_irq_disable(fsi, is_play); | 705 | fsi_irq_disable(fsi, io); |
707 | 706 | ||
708 | if (fsi_is_clk_master(fsi)) | 707 | if (fsi_is_clk_master(fsi)) |
709 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 708 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); |
@@ -885,17 +884,17 @@ static irqreturn_t fsi_interrupt(int irq, void *data) | |||
885 | * dai ops | 884 | * dai ops |
886 | */ | 885 | */ |
887 | static void fsi_fifo_init(struct fsi_priv *fsi, | 886 | static void fsi_fifo_init(struct fsi_priv *fsi, |
888 | int is_play, | 887 | struct fsi_stream *io, |
889 | struct device *dev) | 888 | struct device *dev) |
890 | { | 889 | { |
891 | struct fsi_master *master = fsi_get_master(fsi); | 890 | struct fsi_master *master = fsi_get_master(fsi); |
892 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | 891 | int is_play = fsi_stream_is_play(fsi, io); |
893 | u32 shift, i; | 892 | u32 shift, i; |
894 | int frame_capa; | 893 | int frame_capa; |
895 | 894 | ||
896 | /* get on-chip RAM capacity */ | 895 | /* get on-chip RAM capacity */ |
897 | shift = fsi_master_read(master, FIFO_SZ); | 896 | shift = fsi_master_read(master, FIFO_SZ); |
898 | shift >>= fsi_get_port_shift(fsi, is_play); | 897 | shift >>= fsi_get_port_shift(fsi, io); |
899 | shift &= FIFO_SZ_MASK; | 898 | shift &= FIFO_SZ_MASK; |
900 | frame_capa = 256 << shift; | 899 | frame_capa = 256 << shift; |
901 | dev_dbg(dev, "fifo = %d words\n", frame_capa); | 900 | dev_dbg(dev, "fifo = %d words\n", frame_capa); |
@@ -940,7 +939,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi, | |||
940 | } | 939 | } |
941 | 940 | ||
942 | static int fsi_hw_startup(struct fsi_priv *fsi, | 941 | static int fsi_hw_startup(struct fsi_priv *fsi, |
943 | int is_play, | 942 | struct fsi_stream *io, |
944 | struct device *dev) | 943 | struct device *dev) |
945 | { | 944 | { |
946 | struct fsi_master *master = fsi_get_master(fsi); | 945 | struct fsi_master *master = fsi_get_master(fsi); |
@@ -989,11 +988,11 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
989 | } | 988 | } |
990 | 989 | ||
991 | /* irq clear */ | 990 | /* irq clear */ |
992 | fsi_irq_disable(fsi, is_play); | 991 | fsi_irq_disable(fsi, io); |
993 | fsi_irq_clear_status(fsi); | 992 | fsi_irq_clear_status(fsi); |
994 | 993 | ||
995 | /* fifo init */ | 994 | /* fifo init */ |
996 | fsi_fifo_init(fsi, is_play, dev); | 995 | fsi_fifo_init(fsi, io, dev); |
997 | 996 | ||
998 | return 0; | 997 | return 0; |
999 | } | 998 | } |
@@ -1009,9 +1008,8 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
1009 | struct snd_soc_dai *dai) | 1008 | struct snd_soc_dai *dai) |
1010 | { | 1009 | { |
1011 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1010 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1012 | int is_play = fsi_is_play(substream); | ||
1013 | 1011 | ||
1014 | return fsi_hw_startup(fsi, is_play, dai->dev); | 1012 | return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev); |
1015 | } | 1013 | } |
1016 | 1014 | ||
1017 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | 1015 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, |
@@ -1027,20 +1025,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1027 | struct snd_soc_dai *dai) | 1025 | struct snd_soc_dai *dai) |
1028 | { | 1026 | { |
1029 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1027 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1030 | struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream)); | 1028 | struct fsi_stream *io = fsi_stream_get(fsi, substream); |
1031 | int is_play = fsi_is_play(substream); | ||
1032 | int ret = 0; | 1029 | int ret = 0; |
1033 | 1030 | ||
1034 | switch (cmd) { | 1031 | switch (cmd) { |
1035 | case SNDRV_PCM_TRIGGER_START: | 1032 | case SNDRV_PCM_TRIGGER_START: |
1036 | fsi_stream_init(fsi, is_play, substream); | 1033 | fsi_stream_init(fsi, io, substream); |
1037 | ret = fsi_stream_transfer(io); | 1034 | ret = fsi_stream_transfer(io); |
1038 | if (0 == ret) | 1035 | if (0 == ret) |
1039 | fsi_port_start(fsi, is_play); | 1036 | fsi_port_start(fsi, io); |
1040 | break; | 1037 | break; |
1041 | case SNDRV_PCM_TRIGGER_STOP: | 1038 | case SNDRV_PCM_TRIGGER_STOP: |
1042 | fsi_port_stop(fsi, is_play); | 1039 | fsi_port_stop(fsi, io); |
1043 | fsi_stream_quit(fsi, is_play); | 1040 | fsi_stream_quit(fsi, io); |
1044 | break; | 1041 | break; |
1045 | } | 1042 | } |
1046 | 1043 | ||
@@ -1206,7 +1203,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream) | |||
1206 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) | 1203 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) |
1207 | { | 1204 | { |
1208 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1205 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1209 | struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream)); | 1206 | struct fsi_stream *io = fsi_stream_get(fsi, substream); |
1210 | int samples_pos = io->buff_sample_pos - 1; | 1207 | int samples_pos = io->buff_sample_pos - 1; |
1211 | 1208 | ||
1212 | if (samples_pos < 0) | 1209 | if (samples_pos < 0) |
@@ -1433,30 +1430,29 @@ static int fsi_remove(struct platform_device *pdev) | |||
1433 | } | 1430 | } |
1434 | 1431 | ||
1435 | static void __fsi_suspend(struct fsi_priv *fsi, | 1432 | static void __fsi_suspend(struct fsi_priv *fsi, |
1436 | int is_play, | 1433 | struct fsi_stream *io, |
1437 | struct device *dev) | 1434 | struct device *dev) |
1438 | { | 1435 | { |
1439 | if (!fsi_stream_is_working(fsi, is_play)) | 1436 | if (!fsi_stream_is_working(fsi, io)) |
1440 | return; | 1437 | return; |
1441 | 1438 | ||
1442 | fsi_port_stop(fsi, is_play); | 1439 | fsi_port_stop(fsi, io); |
1443 | fsi_hw_shutdown(fsi, dev); | 1440 | fsi_hw_shutdown(fsi, dev); |
1444 | } | 1441 | } |
1445 | 1442 | ||
1446 | static void __fsi_resume(struct fsi_priv *fsi, | 1443 | static void __fsi_resume(struct fsi_priv *fsi, |
1447 | int is_play, | 1444 | struct fsi_stream *io, |
1448 | struct device *dev) | 1445 | struct device *dev) |
1449 | { | 1446 | { |
1450 | if (!fsi_stream_is_working(fsi, is_play)) | 1447 | if (!fsi_stream_is_working(fsi, io)) |
1451 | return; | 1448 | return; |
1452 | 1449 | ||
1453 | fsi_hw_startup(fsi, is_play, dev); | 1450 | fsi_hw_startup(fsi, io, dev); |
1454 | 1451 | ||
1455 | if (fsi_is_clk_master(fsi) && fsi->rate) | 1452 | if (fsi_is_clk_master(fsi) && fsi->rate) |
1456 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | 1453 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); |
1457 | 1454 | ||
1458 | fsi_port_start(fsi, is_play); | 1455 | fsi_port_start(fsi, io); |
1459 | |||
1460 | } | 1456 | } |
1461 | 1457 | ||
1462 | static int fsi_suspend(struct device *dev) | 1458 | static int fsi_suspend(struct device *dev) |
@@ -1465,11 +1461,11 @@ static int fsi_suspend(struct device *dev) | |||
1465 | struct fsi_priv *fsia = &master->fsia; | 1461 | struct fsi_priv *fsia = &master->fsia; |
1466 | struct fsi_priv *fsib = &master->fsib; | 1462 | struct fsi_priv *fsib = &master->fsib; |
1467 | 1463 | ||
1468 | __fsi_suspend(fsia, 1, dev); | 1464 | __fsi_suspend(fsia, &fsia->playback, dev); |
1469 | __fsi_suspend(fsia, 0, dev); | 1465 | __fsi_suspend(fsia, &fsia->capture, dev); |
1470 | 1466 | ||
1471 | __fsi_suspend(fsib, 1, dev); | 1467 | __fsi_suspend(fsib, &fsib->playback, dev); |
1472 | __fsi_suspend(fsib, 0, dev); | 1468 | __fsi_suspend(fsib, &fsib->capture, dev); |
1473 | 1469 | ||
1474 | return 0; | 1470 | return 0; |
1475 | } | 1471 | } |
@@ -1480,11 +1476,11 @@ static int fsi_resume(struct device *dev) | |||
1480 | struct fsi_priv *fsia = &master->fsia; | 1476 | struct fsi_priv *fsia = &master->fsia; |
1481 | struct fsi_priv *fsib = &master->fsib; | 1477 | struct fsi_priv *fsib = &master->fsib; |
1482 | 1478 | ||
1483 | __fsi_resume(fsia, 1, dev); | 1479 | __fsi_resume(fsia, &fsia->playback, dev); |
1484 | __fsi_resume(fsia, 0, dev); | 1480 | __fsi_resume(fsia, &fsia->capture, dev); |
1485 | 1481 | ||
1486 | __fsi_resume(fsib, 1, dev); | 1482 | __fsi_resume(fsib, &fsib->playback, dev); |
1487 | __fsi_resume(fsib, 0, dev); | 1483 | __fsi_resume(fsib, &fsib->capture, dev); |
1488 | 1484 | ||
1489 | return 0; | 1485 | return 0; |
1490 | } | 1486 | } |