aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-07-29 03:48:32 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-07-29 13:28:49 -0400
commit3bc280708e7b9a84cc6307c1f9acca57e0fafaac (patch)
tree80bae87e4b1cd98ba26bb9e6f69b58082a28ffc7 /sound/soc/sh/fsi.c
parent265c770d03e1e3f9958172d6a7cae59e68b86db2 (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/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c60
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
118struct fsi_core { 127struct 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
409These functions are used later FSI2
410************************************************************************/
411static 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);