diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2010-12-03 03:37:55 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-12-03 07:24:02 -0500 |
commit | e8c8b6318c3dad742d03b5fff5360729f7ac2e5a (patch) | |
tree | 577fbaf20de7116f3d74b9da48d28f2e2d68580e /sound/soc/sh/fsi.c | |
parent | 2b0e73025f74699e9cc9df60649fcc14cd02481b (diff) |
ASoC: sh: fsi: remove runtime register check from fsi_reg_xxx
Current FSI driver was checking register range on fsi_reg_xxx function.
This runtime check was added to avoid an illegal access
from wrong/mistake implementation.
But it is useless check under the correct implementation.
This patch escape runtime check by using macro technique.
If there is wrong implementation, it will be compile error.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r-- | sound/soc/sh/fsi.c | 101 |
1 files changed, 45 insertions, 56 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3927ee598912..66abb6ec0442 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -19,19 +19,19 @@ | |||
19 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
20 | #include <sound/sh_fsi.h> | 20 | #include <sound/sh_fsi.h> |
21 | 21 | ||
22 | #define DO_FMT 0x0000 | 22 | /* PortA/PortB register */ |
23 | #define DOFF_CTL 0x0004 | 23 | #define REG_DO_FMT 0x0000 |
24 | #define DOFF_ST 0x0008 | 24 | #define REG_DOFF_CTL 0x0004 |
25 | #define DI_FMT 0x000C | 25 | #define REG_DOFF_ST 0x0008 |
26 | #define DIFF_CTL 0x0010 | 26 | #define REG_DI_FMT 0x000C |
27 | #define DIFF_ST 0x0014 | 27 | #define REG_DIFF_CTL 0x0010 |
28 | #define CKG1 0x0018 | 28 | #define REG_DIFF_ST 0x0014 |
29 | #define CKG2 0x001C | 29 | #define REG_CKG1 0x0018 |
30 | #define DIDT 0x0020 | 30 | #define REG_CKG2 0x001C |
31 | #define DODT 0x0024 | 31 | #define REG_DIDT 0x0020 |
32 | #define MUTE_ST 0x0028 | 32 | #define REG_DODT 0x0024 |
33 | #define OUT_SEL 0x0030 | 33 | #define REG_MUTE_ST 0x0028 |
34 | #define REG_END OUT_SEL | 34 | #define REG_OUT_SEL 0x0030 |
35 | 35 | ||
36 | #define A_MST_CTLR 0x0180 | 36 | #define A_MST_CTLR 0x0180 |
37 | #define B_MST_CTLR 0x01A0 | 37 | #define B_MST_CTLR 0x01A0 |
@@ -191,35 +191,14 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) | |||
191 | __fsi_reg_write(reg, val); | 191 | __fsi_reg_write(reg, val); |
192 | } | 192 | } |
193 | 193 | ||
194 | static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) | 194 | #define fsi_reg_write(p, r, d)\ |
195 | { | 195 | __fsi_reg_write((u32)(p->base + REG_##r), d) |
196 | if (reg > REG_END) { | ||
197 | pr_err("fsi: register access err (%s)\n", __func__); | ||
198 | return; | ||
199 | } | ||
200 | 196 | ||
201 | __fsi_reg_write((u32)(fsi->base + reg), data); | 197 | #define fsi_reg_read(p, r)\ |
202 | } | 198 | __fsi_reg_read((u32)(p->base + REG_##r)) |
203 | |||
204 | static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) | ||
205 | { | ||
206 | if (reg > REG_END) { | ||
207 | pr_err("fsi: register access err (%s)\n", __func__); | ||
208 | return 0; | ||
209 | } | ||
210 | 199 | ||
211 | return __fsi_reg_read((u32)(fsi->base + reg)); | 200 | #define fsi_reg_mask_set(p, r, m, d)\ |
212 | } | 201 | __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d) |
213 | |||
214 | static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) | ||
215 | { | ||
216 | if (reg > REG_END) { | ||
217 | pr_err("fsi: register access err (%s)\n", __func__); | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); | ||
222 | } | ||
223 | 202 | ||
224 | static u32 fsi_master_read(struct fsi_master *master, u32 reg) | 203 | static u32 fsi_master_read(struct fsi_master *master, u32 reg) |
225 | { | 204 | { |
@@ -369,11 +348,13 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) | |||
369 | static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) | 348 | static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) |
370 | { | 349 | { |
371 | u32 status; | 350 | u32 status; |
372 | u32 reg = is_play ? DOFF_ST : DIFF_ST; | ||
373 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 351 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
374 | int data_num; | 352 | int data_num; |
375 | 353 | ||
376 | status = fsi_reg_read(fsi, reg); | 354 | status = is_play ? |
355 | fsi_reg_read(fsi, DOFF_ST) : | ||
356 | fsi_reg_read(fsi, DIFF_ST); | ||
357 | |||
377 | data_num = 0x1ff & (status >> 8); | 358 | data_num = 0x1ff & (status >> 8); |
378 | data_num *= io->chan_num; | 359 | data_num *= io->chan_num; |
379 | 360 | ||
@@ -541,7 +522,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi, | |||
541 | { | 522 | { |
542 | struct fsi_master *master = fsi_get_master(fsi); | 523 | struct fsi_master *master = fsi_get_master(fsi); |
543 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 524 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
544 | u32 ctrl, shift, i; | 525 | u32 shift, i; |
545 | 526 | ||
546 | /* get on-chip RAM capacity */ | 527 | /* get on-chip RAM capacity */ |
547 | shift = fsi_master_read(master, FIFO_SZ); | 528 | shift = fsi_master_read(master, FIFO_SZ); |
@@ -574,13 +555,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi, | |||
574 | dev_dbg(dai->dev, "%d channel %d store\n", | 555 | dev_dbg(dai->dev, "%d channel %d store\n", |
575 | io->chan_num, io->fifo_max_num); | 556 | io->chan_num, io->fifo_max_num); |
576 | 557 | ||
577 | ctrl = is_play ? DOFF_CTL : DIFF_CTL; | 558 | /* |
578 | 559 | * set interrupt generation factor | |
579 | /* set interrupt generation factor */ | 560 | * clear FIFO |
580 | fsi_reg_write(fsi, ctrl, IRQ_HALF); | 561 | */ |
581 | 562 | if (is_play) { | |
582 | /* clear FIFO */ | 563 | fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); |
583 | fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); | 564 | fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR); |
565 | } else { | ||
566 | fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF); | ||
567 | fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR); | ||
568 | } | ||
584 | } | 569 | } |
585 | 570 | ||
586 | static void fsi_soft_all_reset(struct fsi_master *master) | 571 | static void fsi_soft_all_reset(struct fsi_master *master) |
@@ -601,7 +586,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) | |||
601 | struct snd_pcm_substream *substream = NULL; | 586 | struct snd_pcm_substream *substream = NULL; |
602 | int is_play = fsi_stream_is_play(stream); | 587 | int is_play = fsi_stream_is_play(stream); |
603 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 588 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
604 | u32 status_reg = is_play ? DOFF_ST : DIFF_ST; | ||
605 | int data_residue_num; | 589 | int data_residue_num; |
606 | int data_num; | 590 | int data_num; |
607 | int data_num_max; | 591 | int data_num_max; |
@@ -692,14 +676,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) | |||
692 | /* check fifo status */ | 676 | /* check fifo status */ |
693 | if (!startup) { | 677 | if (!startup) { |
694 | struct snd_soc_dai *dai = fsi_get_dai(substream); | 678 | struct snd_soc_dai *dai = fsi_get_dai(substream); |
695 | u32 status = fsi_reg_read(fsi, status_reg); | 679 | u32 status = is_play ? |
680 | fsi_reg_read(fsi, DOFF_ST) : | ||
681 | fsi_reg_read(fsi, DIFF_ST); | ||
696 | 682 | ||
697 | if (status & ERR_OVER) | 683 | if (status & ERR_OVER) |
698 | dev_err(dai->dev, "over run\n"); | 684 | dev_err(dai->dev, "over run\n"); |
699 | if (status & ERR_UNDER) | 685 | if (status & ERR_UNDER) |
700 | dev_err(dai->dev, "under run\n"); | 686 | dev_err(dai->dev, "under run\n"); |
701 | } | 687 | } |
702 | fsi_reg_write(fsi, status_reg, 0); | 688 | |
689 | is_play ? | ||
690 | fsi_reg_write(fsi, DOFF_ST, 0) : | ||
691 | fsi_reg_write(fsi, DIFF_ST, 0); | ||
703 | 692 | ||
704 | /* re-enable irq */ | 693 | /* re-enable irq */ |
705 | fsi_irq_enable(fsi, is_play); | 694 | fsi_irq_enable(fsi, is_play); |
@@ -756,7 +745,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
756 | struct fsi_stream *io; | 745 | struct fsi_stream *io; |
757 | u32 flags = fsi_get_info_flags(fsi); | 746 | u32 flags = fsi_get_info_flags(fsi); |
758 | u32 fmt; | 747 | u32 fmt; |
759 | u32 reg; | ||
760 | u32 data; | 748 | u32 data; |
761 | int is_play = fsi_is_play(substream); | 749 | int is_play = fsi_is_play(substream); |
762 | int is_master; | 750 | int is_master; |
@@ -788,7 +776,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
788 | 776 | ||
789 | /* do fmt, di fmt */ | 777 | /* do fmt, di fmt */ |
790 | data = 0; | 778 | data = 0; |
791 | reg = is_play ? DO_FMT : DI_FMT; | ||
792 | fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); | 779 | fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); |
793 | switch (fmt) { | 780 | switch (fmt) { |
794 | case SH_FSI_FMT_MONO: | 781 | case SH_FSI_FMT_MONO: |
@@ -831,7 +818,9 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
831 | dev_err(dai->dev, "unknown format.\n"); | 818 | dev_err(dai->dev, "unknown format.\n"); |
832 | return -EINVAL; | 819 | return -EINVAL; |
833 | } | 820 | } |
834 | fsi_reg_write(fsi, reg, data); | 821 | is_play ? |
822 | fsi_reg_write(fsi, DO_FMT, data) : | ||
823 | fsi_reg_write(fsi, DI_FMT, data); | ||
835 | 824 | ||
836 | /* irq clear */ | 825 | /* irq clear */ |
837 | fsi_irq_disable(fsi, is_play); | 826 | fsi_irq_disable(fsi, is_play); |