aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi-ak4642.c24
-rw-r--r--sound/soc/sh/fsi-da7210.c13
-rw-r--r--sound/soc/sh/fsi-hdmi.c77
-rw-r--r--sound/soc/sh/fsi.c203
4 files changed, 217 insertions, 100 deletions
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index a14820ac9665..d6f4703b3c07 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -18,18 +18,26 @@ struct fsi_ak4642_data {
18 const char *cpu_dai; 18 const char *cpu_dai;
19 const char *codec; 19 const char *codec;
20 const char *platform; 20 const char *platform;
21 int id;
21}; 22};
22 23
23static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) 24static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
24{ 25{
25 struct snd_soc_dai *dai = rtd->codec_dai; 26 struct snd_soc_dai *codec = rtd->codec_dai;
27 struct snd_soc_dai *cpu = rtd->cpu_dai;
26 int ret; 28 int ret;
27 29
28 ret = snd_soc_dai_set_fmt(dai, SND_SOC_DAIFMT_CBM_CFM); 30 ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
31 SND_SOC_DAIFMT_CBM_CFM);
29 if (ret < 0) 32 if (ret < 0)
30 return ret; 33 return ret;
31 34
32 ret = snd_soc_dai_set_sysclk(dai, 0, 11289600, 0); 35 ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
36 if (ret < 0)
37 return ret;
38
39 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
40 SND_SOC_DAIFMT_CBS_CFS);
33 41
34 return ret; 42 return ret;
35} 43}
@@ -60,7 +68,7 @@ static int fsi_ak4642_probe(struct platform_device *pdev)
60 68
61 pdata = (struct fsi_ak4642_data *)id_entry->driver_data; 69 pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
62 70
63 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A); 71 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
64 if (!fsi_snd_device) 72 if (!fsi_snd_device)
65 goto out; 73 goto out;
66 74
@@ -93,6 +101,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = {
93 .cpu_dai = "fsia-dai", 101 .cpu_dai = "fsia-dai",
94 .codec = "ak4642-codec.0-0012", 102 .codec = "ak4642-codec.0-0012",
95 .platform = "sh_fsi.0", 103 .platform = "sh_fsi.0",
104 .id = FSI_PORT_A,
96}; 105};
97 106
98static struct fsi_ak4642_data fsi_b_ak4642 = { 107static struct fsi_ak4642_data fsi_b_ak4642 = {
@@ -101,6 +110,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = {
101 .cpu_dai = "fsib-dai", 110 .cpu_dai = "fsib-dai",
102 .codec = "ak4642-codec.0-0012", 111 .codec = "ak4642-codec.0-0012",
103 .platform = "sh_fsi.0", 112 .platform = "sh_fsi.0",
113 .id = FSI_PORT_B,
104}; 114};
105 115
106static struct fsi_ak4642_data fsi_a_ak4643 = { 116static struct fsi_ak4642_data fsi_a_ak4643 = {
@@ -109,6 +119,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = {
109 .cpu_dai = "fsia-dai", 119 .cpu_dai = "fsia-dai",
110 .codec = "ak4642-codec.0-0013", 120 .codec = "ak4642-codec.0-0013",
111 .platform = "sh_fsi.0", 121 .platform = "sh_fsi.0",
122 .id = FSI_PORT_A,
112}; 123};
113 124
114static struct fsi_ak4642_data fsi_b_ak4643 = { 125static struct fsi_ak4642_data fsi_b_ak4643 = {
@@ -117,6 +128,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = {
117 .cpu_dai = "fsib-dai", 128 .cpu_dai = "fsib-dai",
118 .codec = "ak4642-codec.0-0013", 129 .codec = "ak4642-codec.0-0013",
119 .platform = "sh_fsi.0", 130 .platform = "sh_fsi.0",
131 .id = FSI_PORT_B,
120}; 132};
121 133
122static struct fsi_ak4642_data fsi2_a_ak4642 = { 134static struct fsi_ak4642_data fsi2_a_ak4642 = {
@@ -125,6 +137,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = {
125 .cpu_dai = "fsia-dai", 137 .cpu_dai = "fsia-dai",
126 .codec = "ak4642-codec.0-0012", 138 .codec = "ak4642-codec.0-0012",
127 .platform = "sh_fsi2", 139 .platform = "sh_fsi2",
140 .id = FSI_PORT_A,
128}; 141};
129 142
130static struct fsi_ak4642_data fsi2_b_ak4642 = { 143static struct fsi_ak4642_data fsi2_b_ak4642 = {
@@ -133,6 +146,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = {
133 .cpu_dai = "fsib-dai", 146 .cpu_dai = "fsib-dai",
134 .codec = "ak4642-codec.0-0012", 147 .codec = "ak4642-codec.0-0012",
135 .platform = "sh_fsi2", 148 .platform = "sh_fsi2",
149 .id = FSI_PORT_B,
136}; 150};
137 151
138static struct fsi_ak4642_data fsi2_a_ak4643 = { 152static struct fsi_ak4642_data fsi2_a_ak4643 = {
@@ -141,6 +155,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = {
141 .cpu_dai = "fsia-dai", 155 .cpu_dai = "fsia-dai",
142 .codec = "ak4642-codec.0-0013", 156 .codec = "ak4642-codec.0-0013",
143 .platform = "sh_fsi2", 157 .platform = "sh_fsi2",
158 .id = FSI_PORT_A,
144}; 159};
145 160
146static struct fsi_ak4642_data fsi2_b_ak4643 = { 161static struct fsi_ak4642_data fsi2_b_ak4643 = {
@@ -149,6 +164,7 @@ static struct fsi_ak4642_data fsi2_b_ak4643 = {
149 .cpu_dai = "fsib-dai", 164 .cpu_dai = "fsib-dai",
150 .codec = "ak4642-codec.0-0013", 165 .codec = "ak4642-codec.0-0013",
151 .platform = "sh_fsi2", 166 .platform = "sh_fsi2",
167 .id = FSI_PORT_B,
152}; 168};
153 169
154static struct platform_device_id fsi_id_table[] = { 170static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index e8df9da92f71..dbafd7ac5590 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -15,11 +15,20 @@
15 15
16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd) 16static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
17{ 17{
18 struct snd_soc_dai *dai = rtd->codec_dai; 18 struct snd_soc_dai *codec = rtd->codec_dai;
19 struct snd_soc_dai *cpu = rtd->cpu_dai;
20 int ret;
19 21
20 return snd_soc_dai_set_fmt(dai, 22 ret = snd_soc_dai_set_fmt(codec,
21 SND_SOC_DAIFMT_I2S | 23 SND_SOC_DAIFMT_I2S |
22 SND_SOC_DAIFMT_CBM_CFM); 24 SND_SOC_DAIFMT_CBM_CFM);
25 if (ret < 0)
26 return ret;
27
28 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
29 SND_SOC_DAIFMT_CBS_CFS);
30
31 return ret;
23} 32}
24 33
25static struct snd_soc_dai_link fsi_da7210_dai = { 34static struct snd_soc_dai_link fsi_da7210_dai = {
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
index a52dd8ec71d3..9719985eb82d 100644
--- a/sound/soc/sh/fsi-hdmi.c
+++ b/sound/soc/sh/fsi-hdmi.c
@@ -12,31 +12,59 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14 14
15struct fsi_hdmi_data {
16 const char *cpu_dai;
17 const char *card;
18 int id;
19};
20
21static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
22{
23 struct snd_soc_dai *cpu = rtd->cpu_dai;
24 int ret;
25
26 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
27
28 return ret;
29}
30
15static struct snd_soc_dai_link fsi_dai_link = { 31static struct snd_soc_dai_link fsi_dai_link = {
16 .name = "HDMI", 32 .name = "HDMI",
17 .stream_name = "HDMI", 33 .stream_name = "HDMI",
18 .cpu_dai_name = "fsib-dai", /* fsi B */
19 .codec_dai_name = "sh_mobile_hdmi-hifi", 34 .codec_dai_name = "sh_mobile_hdmi-hifi",
20 .platform_name = "sh_fsi2", 35 .platform_name = "sh_fsi2",
21 .codec_name = "sh-mobile-hdmi", 36 .codec_name = "sh-mobile-hdmi",
37 .init = fsi_hdmi_dai_init,
22}; 38};
23 39
24static struct snd_soc_card fsi_soc_card = { 40static struct snd_soc_card fsi_soc_card = {
25 .name = "FSI (SH MOBILE HDMI)",
26 .dai_link = &fsi_dai_link, 41 .dai_link = &fsi_dai_link,
27 .num_links = 1, 42 .num_links = 1,
28}; 43};
29 44
30static struct platform_device *fsi_snd_device; 45static struct platform_device *fsi_snd_device;
31 46
32static int __init fsi_hdmi_init(void) 47static int fsi_hdmi_probe(struct platform_device *pdev)
33{ 48{
34 int ret = -ENOMEM; 49 int ret = -ENOMEM;
50 const struct platform_device_id *id_entry;
51 struct fsi_hdmi_data *pdata;
52
53 id_entry = pdev->id_entry;
54 if (!id_entry) {
55 dev_err(&pdev->dev, "unknown fsi hdmi\n");
56 return -ENODEV;
57 }
35 58
36 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B); 59 pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
60
61 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
37 if (!fsi_snd_device) 62 if (!fsi_snd_device)
38 goto out; 63 goto out;
39 64
65 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
66 fsi_soc_card.name = pdata->card;
67
40 platform_set_drvdata(fsi_snd_device, &fsi_soc_card); 68 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
41 ret = platform_device_add(fsi_snd_device); 69 ret = platform_device_add(fsi_snd_device);
42 70
@@ -47,9 +75,48 @@ out:
47 return ret; 75 return ret;
48} 76}
49 77
50static void __exit fsi_hdmi_exit(void) 78static int fsi_hdmi_remove(struct platform_device *pdev)
51{ 79{
52 platform_device_unregister(fsi_snd_device); 80 platform_device_unregister(fsi_snd_device);
81 return 0;
82}
83
84static struct fsi_hdmi_data fsi2_a_hdmi = {
85 .cpu_dai = "fsia-dai",
86 .card = "FSI2A (SH MOBILE HDMI)",
87 .id = FSI_PORT_A,
88};
89
90static struct fsi_hdmi_data fsi2_b_hdmi = {
91 .cpu_dai = "fsib-dai",
92 .card = "FSI2B (SH MOBILE HDMI)",
93 .id = FSI_PORT_B,
94};
95
96static struct platform_device_id fsi_id_table[] = {
97 /* FSI 2 */
98 { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
99 { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
100 {},
101};
102
103static struct platform_driver fsi_hdmi = {
104 .driver = {
105 .name = "fsi-hdmi-audio",
106 },
107 .probe = fsi_hdmi_probe,
108 .remove = fsi_hdmi_remove,
109 .id_table = fsi_id_table,
110};
111
112static int __init fsi_hdmi_init(void)
113{
114 return platform_driver_register(&fsi_hdmi);
115}
116
117static void __exit fsi_hdmi_exit(void)
118{
119 platform_driver_unregister(&fsi_hdmi);
53} 120}
54 121
55module_init(fsi_hdmi_init); 122module_init(fsi_hdmi_init);
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2b06402801ef..0c9997e2d8c0 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -78,6 +78,8 @@
78/* CKG1 */ 78/* CKG1 */
79#define ACKMD_MASK 0x00007000 79#define ACKMD_MASK 0x00007000
80#define BPFMD_MASK 0x00000700 80#define BPFMD_MASK 0x00000700
81#define DIMD (1 << 4)
82#define DOMD (1 << 0)
81 83
82/* A/B MST_CTLR */ 84/* A/B MST_CTLR */
83#define BP (1 << 4) /* Fix the signal of Biphase output */ 85#define BP (1 << 4) /* Fix the signal of Biphase output */
@@ -111,6 +113,8 @@
111 113
112#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 114#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
113 115
116typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
117
114/* 118/*
115 * FSI driver use below type name for variable 119 * FSI driver use below type name for variable
116 * 120 *
@@ -128,7 +132,6 @@ struct fsi_stream {
128 struct snd_pcm_substream *substream; 132 struct snd_pcm_substream *substream;
129 133
130 int fifo_max_num; 134 int fifo_max_num;
131 int chan_num;
132 135
133 int buff_offset; 136 int buff_offset;
134 int buff_len; 137 int buff_len;
@@ -143,6 +146,7 @@ struct fsi_priv {
143 void __iomem *base; 146 void __iomem *base;
144 struct fsi_master *master; 147 struct fsi_master *master;
145 148
149 int chan_num;
146 struct fsi_stream playback; 150 struct fsi_stream playback;
147 struct fsi_stream capture; 151 struct fsi_stream capture;
148 152
@@ -252,9 +256,8 @@ static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
252 return rtd->cpu_dai; 256 return rtd->cpu_dai;
253} 257}
254 258
255static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) 259static struct fsi_priv *fsi_get_priv_frm_dai(struct snd_soc_dai *dai)
256{ 260{
257 struct snd_soc_dai *dai = fsi_get_dai(substream);
258 struct fsi_master *master = snd_soc_dai_get_drvdata(dai); 261 struct fsi_master *master = snd_soc_dai_get_drvdata(dai);
259 262
260 if (dai->id == 0) 263 if (dai->id == 0)
@@ -263,11 +266,27 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
263 return &master->fsib; 266 return &master->fsib;
264} 267}
265 268
269static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
270{
271 return fsi_get_priv_frm_dai(fsi_get_dai(substream));
272}
273
274static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
275{
276 if (!master->info)
277 return NULL;
278
279 return master->info->set_rate;
280}
281
266static u32 fsi_get_info_flags(struct fsi_priv *fsi) 282static u32 fsi_get_info_flags(struct fsi_priv *fsi)
267{ 283{
268 int is_porta = fsi_is_port_a(fsi); 284 int is_porta = fsi_is_port_a(fsi);
269 struct fsi_master *master = fsi_get_master(fsi); 285 struct fsi_master *master = fsi_get_master(fsi);
270 286
287 if (!master->info)
288 return 0;
289
271 return is_porta ? master->info->porta_flags : 290 return is_porta ? master->info->porta_flags :
272 master->info->portb_flags; 291 master->info->portb_flags;
273} 292}
@@ -288,21 +307,6 @@ static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
288 return is_play ? &fsi->playback : &fsi->capture; 307 return is_play ? &fsi->playback : &fsi->capture;
289} 308}
290 309
291static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
292{
293 u32 mode;
294 u32 flags = fsi_get_info_flags(fsi);
295
296 mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
297
298 /* return
299 * 1 : master mode
300 * 0 : slave mode
301 */
302
303 return (mode & flags) != mode;
304}
305
306static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) 310static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
307{ 311{
308 int is_porta = fsi_is_port_a(fsi); 312 int is_porta = fsi_is_port_a(fsi);
@@ -357,7 +361,6 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 361static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
358{ 362{
359 u32 status; 363 u32 status;
360 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
361 int data_num; 364 int data_num;
362 365
363 status = is_play ? 366 status = is_play ?
@@ -365,7 +368,7 @@ static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
365 fsi_reg_read(fsi, DIFF_ST); 368 fsi_reg_read(fsi, DIFF_ST);
366 369
367 data_num = 0x1ff & (status >> 8); 370 data_num = 0x1ff & (status >> 8);
368 data_num *= io->chan_num; 371 data_num *= fsi->chan_num;
369 372
370 return data_num; 373 return data_num;
371} 374}
@@ -387,7 +390,7 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
387 struct snd_pcm_substream *substream = io->substream; 390 struct snd_pcm_substream *substream = io->substream;
388 struct snd_pcm_runtime *runtime = substream->runtime; 391 struct snd_pcm_runtime *runtime = substream->runtime;
389 392
390 return frames_to_bytes(runtime, 1) / io->chan_num; 393 return frames_to_bytes(runtime, 1) / fsi->chan_num;
391} 394}
392 395
393static void fsi_count_fifo_err(struct fsi_priv *fsi) 396static void fsi_count_fifo_err(struct fsi_priv *fsi)
@@ -580,10 +583,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
580 * 7 channels: 32 ( 32 x 7 = 224) 583 * 7 channels: 32 ( 32 x 7 = 224)
581 * 8 channels: 32 ( 32 x 8 = 256) 584 * 8 channels: 32 ( 32 x 8 = 256)
582 */ 585 */
583 for (i = 1; i < io->chan_num; i <<= 1) 586 for (i = 1; i < fsi->chan_num; i <<= 1)
584 io->fifo_max_num >>= 1; 587 io->fifo_max_num >>= 1;
585 dev_dbg(dai->dev, "%d channel %d store\n", 588 dev_dbg(dai->dev, "%d channel %d store\n",
586 io->chan_num, io->fifo_max_num); 589 fsi->chan_num, io->fifo_max_num);
587 590
588 /* 591 /*
589 * set interrupt generation factor 592 * set interrupt generation factor
@@ -659,7 +662,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
659 * data_num_max : number of FSI fifo free space 662 * data_num_max : number of FSI fifo free space
660 * data_num : number of ALSA residue data 663 * data_num : number of ALSA residue data
661 */ 664 */
662 data_num_max = io->fifo_max_num * io->chan_num; 665 data_num_max = io->fifo_max_num * fsi->chan_num;
663 data_num_max -= fsi_get_fifo_data_num(fsi, is_play); 666 data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
664 667
665 data_num = data_residue_num; 668 data_num = data_residue_num;
@@ -754,25 +757,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
754 struct snd_soc_dai *dai) 757 struct snd_soc_dai *dai)
755{ 758{
756 struct fsi_priv *fsi = fsi_get_priv(substream); 759 struct fsi_priv *fsi = fsi_get_priv(substream);
757 struct fsi_master *master = fsi_get_master(fsi);
758 struct fsi_stream *io;
759 u32 flags = fsi_get_info_flags(fsi); 760 u32 flags = fsi_get_info_flags(fsi);
760 u32 fmt;
761 u32 data; 761 u32 data;
762 int is_play = fsi_is_play(substream); 762 int is_play = fsi_is_play(substream);
763 int is_master;
764
765 io = fsi_get_stream(fsi, is_play);
766 763
767 pm_runtime_get_sync(dai->dev); 764 pm_runtime_get_sync(dai->dev);
768 765
769 /* CKG1 */
770 data = is_play ? (1 << 0) : (1 << 4);
771 is_master = fsi_is_master_mode(fsi, is_play);
772 if (is_master)
773 fsi_reg_mask_set(fsi, CKG1, data, data);
774 else
775 fsi_reg_mask_set(fsi, CKG1, data, 0);
776 766
777 /* clock inversion (CKG2) */ 767 /* clock inversion (CKG2) */
778 data = 0; 768 data = 0;
@@ -787,54 +777,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
787 777
788 fsi_reg_write(fsi, CKG2, data); 778 fsi_reg_write(fsi, CKG2, data);
789 779
790 /* do fmt, di fmt */
791 data = 0;
792 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
793 switch (fmt) {
794 case SH_FSI_FMT_MONO:
795 data = CR_MONO;
796 io->chan_num = 1;
797 break;
798 case SH_FSI_FMT_MONO_DELAY:
799 data = CR_MONO_D;
800 io->chan_num = 1;
801 break;
802 case SH_FSI_FMT_PCM:
803 data = CR_PCM;
804 io->chan_num = 2;
805 break;
806 case SH_FSI_FMT_I2S:
807 data = CR_I2S;
808 io->chan_num = 2;
809 break;
810 case SH_FSI_FMT_TDM:
811 io->chan_num = is_play ?
812 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
813 data = CR_TDM | (io->chan_num - 1);
814 break;
815 case SH_FSI_FMT_TDM_DELAY:
816 io->chan_num = is_play ?
817 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
818 data = CR_TDM_D | (io->chan_num - 1);
819 break;
820 case SH_FSI_FMT_SPDIF:
821 if (master->core->ver < 2) {
822 dev_err(dai->dev, "This FSI can not use SPDIF\n");
823 return -EINVAL;
824 }
825 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
826 io->chan_num = 2;
827 fsi_spdif_clk_ctrl(fsi, 1);
828 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
829 break;
830 default:
831 dev_err(dai->dev, "unknown format.\n");
832 return -EINVAL;
833 }
834 is_play ?
835 fsi_reg_write(fsi, DO_FMT, data) :
836 fsi_reg_write(fsi, DI_FMT, data);
837
838 /* irq clear */ 780 /* irq clear */
839 fsi_irq_disable(fsi, is_play); 781 fsi_irq_disable(fsi, is_play);
840 fsi_irq_clear_status(fsi); 782 fsi_irq_clear_status(fsi);
@@ -851,12 +793,12 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
851 struct fsi_priv *fsi = fsi_get_priv(substream); 793 struct fsi_priv *fsi = fsi_get_priv(substream);
852 int is_play = fsi_is_play(substream); 794 int is_play = fsi_is_play(substream);
853 struct fsi_master *master = fsi_get_master(fsi); 795 struct fsi_master *master = fsi_get_master(fsi);
854 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 796 set_rate_func set_rate;
855 797
856 fsi_irq_disable(fsi, is_play); 798 fsi_irq_disable(fsi, is_play);
857 fsi_clk_ctrl(fsi, 0); 799 fsi_clk_ctrl(fsi, 0);
858 800
859 set_rate = master->info->set_rate; 801 set_rate = fsi_get_info_set_rate(master);
860 if (set_rate && fsi->rate) 802 if (set_rate && fsi->rate)
861 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); 803 set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0);
862 fsi->rate = 0; 804 fsi->rate = 0;
@@ -889,18 +831,100 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
889 return ret; 831 return ret;
890} 832}
891 833
834static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
835{
836 u32 data = 0;
837
838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
839 case SND_SOC_DAIFMT_I2S:
840 data = CR_I2S;
841 fsi->chan_num = 2;
842 break;
843 case SND_SOC_DAIFMT_LEFT_J:
844 data = CR_PCM;
845 fsi->chan_num = 2;
846 break;
847 default:
848 return -EINVAL;
849 }
850
851 fsi_reg_write(fsi, DO_FMT, data);
852 fsi_reg_write(fsi, DI_FMT, data);
853
854 return 0;
855}
856
857static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
858{
859 struct fsi_master *master = fsi_get_master(fsi);
860 u32 data = 0;
861
862 if (master->core->ver < 2)
863 return -EINVAL;
864
865 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
866 fsi->chan_num = 2;
867 fsi_spdif_clk_ctrl(fsi, 1);
868 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
869
870 fsi_reg_write(fsi, DO_FMT, data);
871 fsi_reg_write(fsi, DI_FMT, data);
872
873 return 0;
874}
875
876static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
877{
878 struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
879 u32 flags = fsi_get_info_flags(fsi);
880 u32 data = 0;
881 int ret;
882
883 pm_runtime_get_sync(dai->dev);
884
885 /* set master/slave audio interface */
886 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
887 case SND_SOC_DAIFMT_CBM_CFM:
888 data = DIMD | DOMD;
889 break;
890 case SND_SOC_DAIFMT_CBS_CFS:
891 break;
892 default:
893 ret = -EINVAL;
894 goto set_fmt_exit;
895 }
896 fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data);
897
898 /* set format */
899 switch (flags & SH_FSI_FMT_MASK) {
900 case SH_FSI_FMT_DAI:
901 ret = fsi_set_fmt_dai(fsi, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
902 break;
903 case SH_FSI_FMT_SPDIF:
904 ret = fsi_set_fmt_spdif(fsi);
905 break;
906 default:
907 ret = -EINVAL;
908 }
909
910set_fmt_exit:
911 pm_runtime_put_sync(dai->dev);
912
913 return ret;
914}
915
892static int fsi_dai_hw_params(struct snd_pcm_substream *substream, 916static int fsi_dai_hw_params(struct snd_pcm_substream *substream,
893 struct snd_pcm_hw_params *params, 917 struct snd_pcm_hw_params *params,
894 struct snd_soc_dai *dai) 918 struct snd_soc_dai *dai)
895{ 919{
896 struct fsi_priv *fsi = fsi_get_priv(substream); 920 struct fsi_priv *fsi = fsi_get_priv(substream);
897 struct fsi_master *master = fsi_get_master(fsi); 921 struct fsi_master *master = fsi_get_master(fsi);
898 int (*set_rate)(struct device *dev, int is_porta, int rate, int enable); 922 set_rate_func set_rate;
899 int fsi_ver = master->core->ver; 923 int fsi_ver = master->core->ver;
900 long rate = params_rate(params); 924 long rate = params_rate(params);
901 int ret; 925 int ret;
902 926
903 set_rate = master->info->set_rate; 927 set_rate = fsi_get_info_set_rate(master);
904 if (!set_rate) 928 if (!set_rate)
905 return 0; 929 return 0;
906 930
@@ -975,6 +999,7 @@ static struct snd_soc_dai_ops fsi_dai_ops = {
975 .startup = fsi_dai_startup, 999 .startup = fsi_dai_startup,
976 .shutdown = fsi_dai_shutdown, 1000 .shutdown = fsi_dai_shutdown,
977 .trigger = fsi_dai_trigger, 1001 .trigger = fsi_dai_trigger,
1002 .set_fmt = fsi_dai_set_fmt,
978 .hw_params = fsi_dai_hw_params, 1003 .hw_params = fsi_dai_hw_params,
979}; 1004};
980 1005