diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/sh/fsi.c | 70 |
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 | ||
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; |
@@ -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); |