aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/sh/fsi.c70
1 files changed, 55 insertions, 15 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index a1ce6089177c..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;
@@ -803,10 +846,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
803 if (!set_rate) 846 if (!set_rate)
804 return -EIO; 847 return -EIO;
805 848
806 /* clock stop */
807 pm_runtime_put_sync(dai->dev);
808 fsi_clk_ctrl(fsi, 0);
809
810 ret = set_rate(fsi_is_port_a(fsi), params_rate(params)); 849 ret = set_rate(fsi_is_port_a(fsi), params_rate(params));
811 if (ret > 0) { 850 if (ret > 0) {
812 u32 data = 0; 851 u32 data = 0;
@@ -865,7 +904,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
865 fsi_clk_ctrl(fsi, 1); 904 fsi_clk_ctrl(fsi, 1);
866 ret = 0; 905 ret = 0;
867 } 906 }
868 pm_runtime_get_sync(dai->dev);
869 907
870 return ret; 908 return ret;
871 909
@@ -1048,11 +1086,6 @@ static int fsi_probe(struct platform_device *pdev)
1048 unsigned int irq; 1086 unsigned int irq;
1049 int ret; 1087 int ret;
1050 1088
1051 if (0 != pdev->id) {
1052 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
1053 return -ENODEV;
1054 }
1055
1056 id_entry = pdev->id_entry; 1089 id_entry = pdev->id_entry;
1057 if (!id_entry) { 1090 if (!id_entry) {
1058 dev_err(&pdev->dev, "unknown fsi device\n"); 1091 dev_err(&pdev->dev, "unknown fsi device\n");
@@ -1081,14 +1114,21 @@ static int fsi_probe(struct platform_device *pdev)
1081 goto exit_kfree; 1114 goto exit_kfree;
1082 } 1115 }
1083 1116
1117 /* master setting */
1084 master->irq = irq; 1118 master->irq = irq;
1085 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 */
1086 master->fsia.base = master->base; 1124 master->fsia.base = master->base;
1087 master->fsia.master = master; 1125 master->fsia.master = master;
1126 master->fsia.mst_ctrl = A_MST_CTLR;
1127
1128 /* FSI B setting */
1088 master->fsib.base = master->base + 0x40; 1129 master->fsib.base = master->base + 0x40;
1089 master->fsib.master = master; 1130 master->fsib.master = master;
1090 master->core = (struct fsi_core *)id_entry->driver_data; 1131 master->fsib.mst_ctrl = B_MST_CTLR;
1091 spin_lock_init(&master->lock);
1092 1132
1093 pm_runtime_enable(&pdev->dev); 1133 pm_runtime_enable(&pdev->dev);
1094 pm_runtime_resume(&pdev->dev); 1134 pm_runtime_resume(&pdev->dev);