diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2010-07-29 03:48:32 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-07-29 13:28:49 -0400 |
commit | 3bc280708e7b9a84cc6307c1f9acca57e0fafaac (patch) | |
tree | 80bae87e4b1cd98ba26bb9e6f69b58082a28ffc7 /sound/soc | |
parent | 265c770d03e1e3f9958172d6a7cae59e68b86db2 (diff) |
ASoC: fsi: Add new funtion for SPDIF
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')
-rw-r--r-- | sound/soc/sh/fsi.c | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 4b09b3dfcc00..58c6bec642de 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -30,9 +30,11 @@ | |||
30 | #define DIDT 0x0020 | 30 | #define DIDT 0x0020 |
31 | #define DODT 0x0024 | 31 | #define DODT 0x0024 |
32 | #define MUTE_ST 0x0028 | 32 | #define MUTE_ST 0x0028 |
33 | #define REG_END MUTE_ST | 33 | #define OUT_SEL 0x0030 |
34 | 34 | #define REG_END OUT_SEL | |
35 | 35 | ||
36 | #define A_MST_CTLR 0x0180 | ||
37 | #define B_MST_CTLR 0x01A0 | ||
36 | #define CPU_INT_ST 0x01F4 | 38 | #define CPU_INT_ST 0x01F4 |
37 | #define CPU_IEMSK 0x01F8 | 39 | #define CPU_IEMSK 0x01F8 |
38 | #define CPU_IMSK 0x01FC | 40 | #define CPU_IMSK 0x01FC |
@@ -43,7 +45,7 @@ | |||
43 | #define CLK_RST 0x0210 | 45 | #define CLK_RST 0x0210 |
44 | #define SOFT_RST 0x0214 | 46 | #define SOFT_RST 0x0214 |
45 | #define FIFO_SZ 0x0218 | 47 | #define FIFO_SZ 0x0218 |
46 | #define MREG_START CPU_INT_ST | 48 | #define MREG_START A_MST_CTLR |
47 | #define MREG_END FIFO_SZ | 49 | #define MREG_END FIFO_SZ |
48 | 50 | ||
49 | /* DO_FMT */ | 51 | /* DO_FMT */ |
@@ -54,6 +56,7 @@ | |||
54 | #define CR_I2S (0x3 << 4) | 56 | #define CR_I2S (0x3 << 4) |
55 | #define CR_TDM (0x4 << 4) | 57 | #define CR_TDM (0x4 << 4) |
56 | #define CR_TDM_D (0x5 << 4) | 58 | #define CR_TDM_D (0x5 << 4) |
59 | #define CR_SPDIF 0x00100120 | ||
57 | 60 | ||
58 | /* DOFF_CTL */ | 61 | /* DOFF_CTL */ |
59 | /* DIFF_CTL */ | 62 | /* DIFF_CTL */ |
@@ -69,6 +72,10 @@ | |||
69 | #define ACKMD_MASK 0x00007000 | 72 | #define ACKMD_MASK 0x00007000 |
70 | #define BPFMD_MASK 0x00000700 | 73 | #define BPFMD_MASK 0x00000700 |
71 | 74 | ||
75 | /* A/B MST_CTLR */ | ||
76 | #define BP (1 << 4) /* Fix the signal of Biphase output */ | ||
77 | #define SE (1 << 0) /* Fix the master clock */ | ||
78 | |||
72 | /* CLK_RST */ | 79 | /* CLK_RST */ |
73 | #define B_CLK 0x00000010 | 80 | #define B_CLK 0x00000010 |
74 | #define A_CLK 0x00000001 | 81 | #define A_CLK 0x00000001 |
@@ -113,6 +120,8 @@ struct fsi_priv { | |||
113 | int period_len; | 120 | int period_len; |
114 | int buffer_len; | 121 | int buffer_len; |
115 | int periods; | 122 | int periods; |
123 | |||
124 | u32 mst_ctrl; | ||
116 | }; | 125 | }; |
117 | 126 | ||
118 | struct fsi_core { | 127 | struct fsi_core { |
@@ -395,6 +404,29 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi) | |||
395 | /************************************************************************ | 404 | /************************************************************************ |
396 | 405 | ||
397 | 406 | ||
407 | SPDIF master clock function | ||
408 | |||
409 | These functions are used later FSI2 | ||
410 | ************************************************************************/ | ||
411 | static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | ||
412 | { | ||
413 | struct fsi_master *master = fsi_get_master(fsi); | ||
414 | u32 val = BP | SE; | ||
415 | |||
416 | if (master->core->ver < 2) { | ||
417 | pr_err("fsi: register access err (%s)\n", __func__); | ||
418 | return; | ||
419 | } | ||
420 | |||
421 | if (enable) | ||
422 | fsi_master_mask_set(master, fsi->mst_ctrl, val, val); | ||
423 | else | ||
424 | fsi_master_mask_set(master, fsi->mst_ctrl, val, 0); | ||
425 | } | ||
426 | |||
427 | /************************************************************************ | ||
428 | |||
429 | |||
398 | ctrl function | 430 | ctrl function |
399 | 431 | ||
400 | 432 | ||
@@ -671,6 +703,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
671 | { | 703 | { |
672 | struct fsi_priv *fsi = fsi_get_priv(substream); | 704 | struct fsi_priv *fsi = fsi_get_priv(substream); |
673 | u32 flags = fsi_get_info_flags(fsi); | 705 | u32 flags = fsi_get_info_flags(fsi); |
706 | struct fsi_master *master = fsi_get_master(fsi); | ||
674 | u32 fmt; | 707 | u32 fmt; |
675 | u32 reg; | 708 | u32 reg; |
676 | u32 data; | 709 | u32 data; |
@@ -732,6 +765,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
732 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); | 765 | SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); |
733 | data = CR_TDM_D | (fsi->chan - 1); | 766 | data = CR_TDM_D | (fsi->chan - 1); |
734 | break; | 767 | break; |
768 | case SH_FSI_FMT_SPDIF: | ||
769 | if (master->core->ver < 2) { | ||
770 | dev_err(dai->dev, "This FSI can not use SPDIF\n"); | ||
771 | return -EINVAL; | ||
772 | } | ||
773 | data = CR_SPDIF; | ||
774 | fsi->chan = 2; | ||
775 | fsi_spdif_clk_ctrl(fsi, 1); | ||
776 | fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010); | ||
777 | break; | ||
735 | default: | 778 | default: |
736 | dev_err(dai->dev, "unknown format.\n"); | 779 | dev_err(dai->dev, "unknown format.\n"); |
737 | return -EINVAL; | 780 | return -EINVAL; |
@@ -1071,14 +1114,21 @@ static int fsi_probe(struct platform_device *pdev) | |||
1071 | goto exit_kfree; | 1114 | goto exit_kfree; |
1072 | } | 1115 | } |
1073 | 1116 | ||
1117 | /* master setting */ | ||
1074 | master->irq = irq; | 1118 | master->irq = irq; |
1075 | master->info = pdev->dev.platform_data; | 1119 | master->info = pdev->dev.platform_data; |
1120 | master->core = (struct fsi_core *)id_entry->driver_data; | ||
1121 | spin_lock_init(&master->lock); | ||
1122 | |||
1123 | /* FSI A setting */ | ||
1076 | master->fsia.base = master->base; | 1124 | master->fsia.base = master->base; |
1077 | master->fsia.master = master; | 1125 | master->fsia.master = master; |
1126 | master->fsia.mst_ctrl = A_MST_CTLR; | ||
1127 | |||
1128 | /* FSI B setting */ | ||
1078 | master->fsib.base = master->base + 0x40; | 1129 | master->fsib.base = master->base + 0x40; |
1079 | master->fsib.master = master; | 1130 | master->fsib.master = master; |
1080 | master->core = (struct fsi_core *)id_entry->driver_data; | 1131 | master->fsib.mst_ctrl = B_MST_CTLR; |
1081 | spin_lock_init(&master->lock); | ||
1082 | 1132 | ||
1083 | pm_runtime_enable(&pdev->dev); | 1133 | pm_runtime_enable(&pdev->dev); |
1084 | pm_runtime_resume(&pdev->dev); | 1134 | pm_runtime_resume(&pdev->dev); |