aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/sh/fsi.c115
1 files changed, 62 insertions, 53 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9c49c11c43c..7506ef6d287 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -92,6 +92,7 @@
92struct fsi_priv { 92struct fsi_priv {
93 void __iomem *base; 93 void __iomem *base;
94 struct snd_pcm_substream *substream; 94 struct snd_pcm_substream *substream;
95 struct fsi_master *master;
95 96
96 int fifo_max; 97 int fifo_max;
97 int chan; 98 int chan;
@@ -110,8 +111,6 @@ struct fsi_master {
110 struct sh_fsi_platform_info *info; 111 struct sh_fsi_platform_info *info;
111}; 112};
112 113
113static struct fsi_master *master;
114
115/************************************************************************ 114/************************************************************************
116 115
117 116
@@ -166,7 +165,7 @@ static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
166 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 165 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
167} 166}
168 167
169static int fsi_master_write(u32 reg, u32 data) 168static int fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
170{ 169{
171 if ((reg < MREG_START) || 170 if ((reg < MREG_START) ||
172 (reg > MREG_END)) 171 (reg > MREG_END))
@@ -175,7 +174,7 @@ static int fsi_master_write(u32 reg, u32 data)
175 return __fsi_reg_write((u32)(master->base + reg), data); 174 return __fsi_reg_write((u32)(master->base + reg), data);
176} 175}
177 176
178static u32 fsi_master_read(u32 reg) 177static u32 fsi_master_read(struct fsi_master *master, u32 reg)
179{ 178{
180 if ((reg < MREG_START) || 179 if ((reg < MREG_START) ||
181 (reg > MREG_END)) 180 (reg > MREG_END))
@@ -184,7 +183,8 @@ static u32 fsi_master_read(u32 reg)
184 return __fsi_reg_read((u32)(master->base + reg)); 183 return __fsi_reg_read((u32)(master->base + reg));
185} 184}
186 185
187static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 186static int fsi_master_mask_set(struct fsi_master *master,
187 u32 reg, u32 mask, u32 data)
188{ 188{
189 if ((reg < MREG_START) || 189 if ((reg < MREG_START) ||
190 (reg > MREG_END)) 190 (reg > MREG_END))
@@ -200,43 +200,29 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
200 200
201 201
202************************************************************************/ 202************************************************************************/
203static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 203static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
204{ 204{
205 struct snd_soc_pcm_runtime *rtd; 205 return fsi->master;
206 struct fsi_priv *fsi = NULL;
207
208 if (!substream || !master)
209 return NULL;
210
211 rtd = substream->private_data;
212 switch (rtd->dai->cpu_dai->id) {
213 case 0:
214 fsi = &master->fsia;
215 break;
216 case 1:
217 fsi = &master->fsib;
218 break;
219 }
220
221 return fsi;
222} 206}
223 207
224static int fsi_is_port_a(struct fsi_priv *fsi) 208static int fsi_is_port_a(struct fsi_priv *fsi)
225{ 209{
226 /* return 210 return fsi->master->base == fsi->base;
227 * 1 : port a 211}
228 * 0 : port b
229 */
230 212
231 if (fsi == &master->fsia) 213static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
232 return 1; 214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct snd_soc_dai_link *machine = rtd->dai;
217 struct snd_soc_dai *dai = machine->cpu_dai;
233 218
234 return 0; 219 return dai->private_data;
235} 220}
236 221
237static u32 fsi_get_info_flags(struct fsi_priv *fsi) 222static u32 fsi_get_info_flags(struct fsi_priv *fsi)
238{ 223{
239 int is_porta = fsi_is_port_a(fsi); 224 int is_porta = fsi_is_port_a(fsi);
225 struct fsi_master *master = fsi_get_master(fsi);
240 226
241 return is_porta ? master->info->porta_flags : 227 return is_porta ? master->info->porta_flags :
242 master->info->portb_flags; 228 master->info->portb_flags;
@@ -314,27 +300,30 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
314static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 300static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
315{ 301{
316 u32 data = fsi_port_ab_io_bit(fsi, is_play); 302 u32 data = fsi_port_ab_io_bit(fsi, is_play);
303 struct fsi_master *master = fsi_get_master(fsi);
317 304
318 fsi_master_mask_set(IMSK, data, data); 305 fsi_master_mask_set(master, IMSK, data, data);
319 fsi_master_mask_set(IEMSK, data, data); 306 fsi_master_mask_set(master, IEMSK, data, data);
320} 307}
321 308
322static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 309static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
323{ 310{
324 u32 data = fsi_port_ab_io_bit(fsi, is_play); 311 u32 data = fsi_port_ab_io_bit(fsi, is_play);
312 struct fsi_master *master = fsi_get_master(fsi);
325 313
326 fsi_master_mask_set(IMSK, data, 0); 314 fsi_master_mask_set(master, IMSK, data, 0);
327 fsi_master_mask_set(IEMSK, data, 0); 315 fsi_master_mask_set(master, IEMSK, data, 0);
328} 316}
329 317
330static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 318static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
331{ 319{
332 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 320 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
321 struct fsi_master *master = fsi_get_master(fsi);
333 322
334 if (enable) 323 if (enable)
335 fsi_master_mask_set(CLK_RST, val, val); 324 fsi_master_mask_set(master, CLK_RST, val, val);
336 else 325 else
337 fsi_master_mask_set(CLK_RST, val, 0); 326 fsi_master_mask_set(master, CLK_RST, val, 0);
338} 327}
339 328
340static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 329static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,23 +344,23 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
355 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 344 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
356 345
357 /* clear interrupt factor */ 346 /* clear interrupt factor */
358 fsi_master_mask_set(INT_ST, data, 0); 347 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
359} 348}
360 349
361static void fsi_soft_all_reset(void) 350static void fsi_soft_all_reset(struct fsi_master *master)
362{ 351{
363 u32 status = fsi_master_read(SOFT_RST); 352 u32 status = fsi_master_read(master, SOFT_RST);
364 353
365 /* port AB reset */ 354 /* port AB reset */
366 status &= 0x000000ff; 355 status &= 0x000000ff;
367 fsi_master_write(SOFT_RST, status); 356 fsi_master_write(master, SOFT_RST, status);
368 mdelay(10); 357 mdelay(10);
369 358
370 /* soft reset */ 359 /* soft reset */
371 status &= 0x000000f0; 360 status &= 0x000000f0;
372 fsi_master_write(SOFT_RST, status); 361 fsi_master_write(master, SOFT_RST, status);
373 status |= 0x00000001; 362 status |= 0x00000001;
374 fsi_master_write(SOFT_RST, status); 363 fsi_master_write(master, SOFT_RST, status);
375 mdelay(10); 364 mdelay(10);
376} 365}
377 366
@@ -517,12 +506,13 @@ static int fsi_data_pop(struct fsi_priv *fsi)
517 506
518static irqreturn_t fsi_interrupt(int irq, void *data) 507static irqreturn_t fsi_interrupt(int irq, void *data)
519{ 508{
520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 509 struct fsi_master *master = data;
521 u32 int_st = fsi_master_read(INT_ST); 510 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
511 u32 int_st = fsi_master_read(master, INT_ST);
522 512
523 /* clear irq status */ 513 /* clear irq status */
524 fsi_master_write(SOFT_RST, status); 514 fsi_master_write(master, SOFT_RST, status);
525 fsi_master_write(SOFT_RST, status | 0x00000010); 515 fsi_master_write(master, SOFT_RST, status | 0x00000010);
526 516
527 if (int_st & INT_A_OUT) 517 if (int_st & INT_A_OUT)
528 fsi_data_push(&master->fsia); 518 fsi_data_push(&master->fsia);
@@ -533,7 +523,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
533 if (int_st & INT_B_IN) 523 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib); 524 fsi_data_pop(&master->fsib);
535 525
536 fsi_master_write(INT_ST, 0x0000000); 526 fsi_master_write(master, INT_ST, 0x0000000);
537 527
538 return IRQ_HANDLED; 528 return IRQ_HANDLED;
539} 529}
@@ -548,7 +538,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
548static int fsi_dai_startup(struct snd_pcm_substream *substream, 538static int fsi_dai_startup(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai) 539 struct snd_soc_dai *dai)
550{ 540{
551 struct fsi_priv *fsi = fsi_get(substream); 541 struct fsi_priv *fsi = fsi_get_priv(substream);
552 const char *msg; 542 const char *msg;
553 u32 flags = fsi_get_info_flags(fsi); 543 u32 flags = fsi_get_info_flags(fsi);
554 u32 fmt; 544 u32 fmt;
@@ -667,7 +657,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
667static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 657static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai) 658 struct snd_soc_dai *dai)
669{ 659{
670 struct fsi_priv *fsi = fsi_get(substream); 660 struct fsi_priv *fsi = fsi_get_priv(substream);
671 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 661 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
672 662
673 fsi_irq_disable(fsi, is_play); 663 fsi_irq_disable(fsi, is_play);
@@ -679,7 +669,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 669static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
680 struct snd_soc_dai *dai) 670 struct snd_soc_dai *dai)
681{ 671{
682 struct fsi_priv *fsi = fsi_get(substream); 672 struct fsi_priv *fsi = fsi_get_priv(substream);
683 struct snd_pcm_runtime *runtime = substream->runtime; 673 struct snd_pcm_runtime *runtime = substream->runtime;
684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 674 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
685 int ret = 0; 675 int ret = 0;
@@ -760,7 +750,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
760static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 750static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
761{ 751{
762 struct snd_pcm_runtime *runtime = substream->runtime; 752 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsi_priv *fsi = fsi_get(substream); 753 struct fsi_priv *fsi = fsi_get_priv(substream);
764 long location; 754 long location;
765 755
766 location = (fsi->byte_offset - 1); 756 location = (fsi->byte_offset - 1);
@@ -870,10 +860,16 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
870************************************************************************/ 860************************************************************************/
871static int fsi_probe(struct platform_device *pdev) 861static int fsi_probe(struct platform_device *pdev)
872{ 862{
863 struct fsi_master *master;
873 struct resource *res; 864 struct resource *res;
874 unsigned int irq; 865 unsigned int irq;
875 int ret; 866 int ret;
876 867
868 if (0 != pdev->id) {
869 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
870 return -ENODEV;
871 }
872
877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 873 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
878 irq = platform_get_irq(pdev, 0); 874 irq = platform_get_irq(pdev, 0);
879 if (!res || !irq) { 875 if (!res || !irq) {
@@ -899,15 +895,19 @@ static int fsi_probe(struct platform_device *pdev)
899 master->irq = irq; 895 master->irq = irq;
900 master->info = pdev->dev.platform_data; 896 master->info = pdev->dev.platform_data;
901 master->fsia.base = master->base; 897 master->fsia.base = master->base;
898 master->fsia.master = master;
902 master->fsib.base = master->base + 0x40; 899 master->fsib.base = master->base + 0x40;
900 master->fsib.master = master;
903 901
904 pm_runtime_enable(&pdev->dev); 902 pm_runtime_enable(&pdev->dev);
905 pm_runtime_resume(&pdev->dev); 903 pm_runtime_resume(&pdev->dev);
906 904
907 fsi_soc_dai[0].dev = &pdev->dev; 905 fsi_soc_dai[0].dev = &pdev->dev;
906 fsi_soc_dai[0].private_data = &master->fsia;
908 fsi_soc_dai[1].dev = &pdev->dev; 907 fsi_soc_dai[1].dev = &pdev->dev;
908 fsi_soc_dai[1].private_data = &master->fsib;
909 909
910 fsi_soft_all_reset(); 910 fsi_soft_all_reset(master);
911 911
912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
913 if (ret) { 913 if (ret) {
@@ -937,6 +937,10 @@ exit:
937 937
938static int fsi_remove(struct platform_device *pdev) 938static int fsi_remove(struct platform_device *pdev)
939{ 939{
940 struct fsi_master *master;
941
942 master = fsi_get_master(fsi_soc_dai[0].private_data);
943
940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 944 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
941 snd_soc_unregister_platform(&fsi_soc_platform); 945 snd_soc_unregister_platform(&fsi_soc_platform);
942 946
@@ -946,7 +950,12 @@ static int fsi_remove(struct platform_device *pdev)
946 950
947 iounmap(master->base); 951 iounmap(master->base);
948 kfree(master); 952 kfree(master);
949 master = NULL; 953
954 fsi_soc_dai[0].dev = NULL;
955 fsi_soc_dai[0].private_data = NULL;
956 fsi_soc_dai[1].dev = NULL;
957 fsi_soc_dai[1].private_data = NULL;
958
950 return 0; 959 return 0;
951} 960}
952 961