aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-20 06:00:43 -0400
commitd71f4cece4bd97d05592836202fc04ff2e7817e3 (patch)
tree6c877c7a938758b1323d9c97d46b9c536e618c69 /sound/soc/sh/fsi.c
parent19008bdacb9f7841166ebafe0aef361ee582ffbf (diff)
parentad8332c1302bcb4f80d593fd3eb477be9d7f5604 (diff)
Merge branch 'topic/asoc' into for-linus
Conflicts: sound/soc/codecs/ad1938.c
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c191
1 files changed, 135 insertions, 56 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 8dc966f45c36..3396a0db06ba 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -41,14 +41,19 @@
41#define MUTE_ST 0x0028 41#define MUTE_ST 0x0028
42#define REG_END MUTE_ST 42#define REG_END MUTE_ST
43 43
44
45#define CPU_INT_ST 0x01F4
46#define CPU_IEMSK 0x01F8
47#define CPU_IMSK 0x01FC
44#define INT_ST 0x0200 48#define INT_ST 0x0200
45#define IEMSK 0x0204 49#define IEMSK 0x0204
46#define IMSK 0x0208 50#define IMSK 0x0208
47#define MUTE 0x020C 51#define MUTE 0x020C
48#define CLK_RST 0x0210 52#define CLK_RST 0x0210
49#define SOFT_RST 0x0214 53#define SOFT_RST 0x0214
50#define MREG_START INT_ST 54#define FIFO_SZ 0x0218
51#define MREG_END SOFT_RST 55#define MREG_START CPU_INT_ST
56#define MREG_END FIFO_SZ
52 57
53/* DO_FMT */ 58/* DO_FMT */
54/* DI_FMT */ 59/* DI_FMT */
@@ -80,6 +85,17 @@
80#define INT_A_IN (1 << 4) 85#define INT_A_IN (1 << 4)
81#define INT_A_OUT (1 << 0) 86#define INT_A_OUT (1 << 0)
82 87
88/* SOFT_RST */
89#define PBSR (1 << 12) /* Port B Software Reset */
90#define PASR (1 << 8) /* Port A Software Reset */
91#define IR (1 << 4) /* Interrupt Reset */
92#define FSISR (1 << 0) /* Software Reset */
93
94/* FIFO_SZ */
95#define OUT_SZ_MASK 0x7
96#define BO_SZ_SHIFT 8
97#define AO_SZ_SHIFT 0
98
83#define FSI_RATES SNDRV_PCM_RATE_8000_96000 99#define FSI_RATES SNDRV_PCM_RATE_8000_96000
84 100
85#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 101#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
@@ -105,11 +121,18 @@ struct fsi_priv {
105 int periods; 121 int periods;
106}; 122};
107 123
124struct fsi_regs {
125 u32 int_st;
126 u32 iemsk;
127 u32 imsk;
128};
129
108struct fsi_master { 130struct fsi_master {
109 void __iomem *base; 131 void __iomem *base;
110 int irq; 132 int irq;
111 struct fsi_priv fsia; 133 struct fsi_priv fsia;
112 struct fsi_priv fsib; 134 struct fsi_priv fsib;
135 struct fsi_regs *regs;
113 struct sh_fsi_platform_info *info; 136 struct sh_fsi_platform_info *info;
114 spinlock_t lock; 137 spinlock_t lock;
115}; 138};
@@ -317,7 +340,7 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
317/************************************************************************ 340/************************************************************************
318 341
319 342
320 ctrl function 343 irq function
321 344
322 345
323************************************************************************/ 346************************************************************************/
@@ -326,8 +349,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
326 u32 data = fsi_port_ab_io_bit(fsi, is_play); 349 u32 data = fsi_port_ab_io_bit(fsi, is_play);
327 struct fsi_master *master = fsi_get_master(fsi); 350 struct fsi_master *master = fsi_get_master(fsi);
328 351
329 fsi_master_mask_set(master, IMSK, data, data); 352 fsi_master_mask_set(master, master->regs->imsk, data, data);
330 fsi_master_mask_set(master, IEMSK, data, data); 353 fsi_master_mask_set(master, master->regs->iemsk, data, data);
331} 354}
332 355
333static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 356static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -335,10 +358,39 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
335 u32 data = fsi_port_ab_io_bit(fsi, is_play); 358 u32 data = fsi_port_ab_io_bit(fsi, is_play);
336 struct fsi_master *master = fsi_get_master(fsi); 359 struct fsi_master *master = fsi_get_master(fsi);
337 360
338 fsi_master_mask_set(master, IMSK, data, 0); 361 fsi_master_mask_set(master, master->regs->imsk, data, 0);
339 fsi_master_mask_set(master, IEMSK, data, 0); 362 fsi_master_mask_set(master, master->regs->iemsk, data, 0);
363}
364
365static u32 fsi_irq_get_status(struct fsi_master *master)
366{
367 return fsi_master_read(master, master->regs->int_st);
368}
369
370static void fsi_irq_clear_all_status(struct fsi_master *master)
371{
372 fsi_master_write(master, master->regs->int_st, 0x0000000);
340} 373}
341 374
375static void fsi_irq_clear_status(struct fsi_priv *fsi)
376{
377 u32 data = 0;
378 struct fsi_master *master = fsi_get_master(fsi);
379
380 data |= fsi_port_ab_io_bit(fsi, 0);
381 data |= fsi_port_ab_io_bit(fsi, 1);
382
383 /* clear interrupt factor */
384 fsi_master_mask_set(master, master->regs->int_st, data, 0);
385}
386
387/************************************************************************
388
389
390 ctrl function
391
392
393************************************************************************/
342static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 394static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
343{ 395{
344 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 396 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
@@ -350,41 +402,61 @@ static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
350 fsi_master_mask_set(master, CLK_RST, val, 0); 402 fsi_master_mask_set(master, CLK_RST, val, 0);
351} 403}
352 404
353static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 405static void fsi_fifo_init(struct fsi_priv *fsi,
406 int is_play,
407 struct snd_soc_dai *dai)
354{ 408{
355 u32 data; 409 struct fsi_master *master = fsi_get_master(fsi);
356 u32 ctrl; 410 u32 ctrl, shift, i;
357 411
358 data = fsi_port_ab_io_bit(fsi, is_play); 412 /* get on-chip RAM capacity */
359 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 413 shift = fsi_master_read(master, FIFO_SZ);
414 shift >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
415 shift &= OUT_SZ_MASK;
416 fsi->fifo_max = 256 << shift;
417 dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
360 418
361 /* set IMSK */ 419 /*
362 fsi_irq_disable(fsi, is_play); 420 * The maximum number of sample data varies depending
421 * on the number of channels selected for the format.
422 *
423 * FIFOs are used in 4-channel units in 3-channel mode
424 * and in 8-channel units in 5- to 7-channel mode
425 * meaning that more FIFOs than the required size of DPRAM
426 * are used.
427 *
428 * ex) if 256 words of DP-RAM is connected
429 * 1 channel: 256 (256 x 1 = 256)
430 * 2 channels: 128 (128 x 2 = 256)
431 * 3 channels: 64 ( 64 x 3 = 192)
432 * 4 channels: 64 ( 64 x 4 = 256)
433 * 5 channels: 32 ( 32 x 5 = 160)
434 * 6 channels: 32 ( 32 x 6 = 192)
435 * 7 channels: 32 ( 32 x 7 = 224)
436 * 8 channels: 32 ( 32 x 8 = 256)
437 */
438 for (i = 1; i < fsi->chan; i <<= 1)
439 fsi->fifo_max >>= 1;
440 dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
441
442 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
363 443
364 /* set interrupt generation factor */ 444 /* set interrupt generation factor */
365 fsi_reg_write(fsi, ctrl, IRQ_HALF); 445 fsi_reg_write(fsi, ctrl, IRQ_HALF);
366 446
367 /* clear FIFO */ 447 /* clear FIFO */
368 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 448 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
369
370 /* clear interrupt factor */
371 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
372} 449}
373 450
374static void fsi_soft_all_reset(struct fsi_master *master) 451static void fsi_soft_all_reset(struct fsi_master *master)
375{ 452{
376 u32 status = fsi_master_read(master, SOFT_RST);
377
378 /* port AB reset */ 453 /* port AB reset */
379 status &= 0x000000ff; 454 fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0);
380 fsi_master_write(master, SOFT_RST, status);
381 mdelay(10); 455 mdelay(10);
382 456
383 /* soft reset */ 457 /* soft reset */
384 status &= 0x000000f0; 458 fsi_master_mask_set(master, SOFT_RST, FSISR, 0);
385 fsi_master_write(master, SOFT_RST, status); 459 fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR);
386 status |= 0x00000001;
387 fsi_master_write(master, SOFT_RST, status);
388 mdelay(10); 460 mdelay(10);
389} 461}
390 462
@@ -559,12 +631,11 @@ static int fsi_data_pop(struct fsi_priv *fsi, int startup)
559static irqreturn_t fsi_interrupt(int irq, void *data) 631static irqreturn_t fsi_interrupt(int irq, void *data)
560{ 632{
561 struct fsi_master *master = data; 633 struct fsi_master *master = data;
562 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010; 634 u32 int_st = fsi_irq_get_status(master);
563 u32 int_st = fsi_master_read(master, INT_ST);
564 635
565 /* clear irq status */ 636 /* clear irq status */
566 fsi_master_write(master, SOFT_RST, status); 637 fsi_master_mask_set(master, SOFT_RST, IR, 0);
567 fsi_master_write(master, SOFT_RST, status | 0x00000010); 638 fsi_master_mask_set(master, SOFT_RST, IR, IR);
568 639
569 if (int_st & INT_A_OUT) 640 if (int_st & INT_A_OUT)
570 fsi_data_push(&master->fsia, 0); 641 fsi_data_push(&master->fsia, 0);
@@ -575,7 +646,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
575 if (int_st & INT_B_IN) 646 if (int_st & INT_B_IN)
576 fsi_data_pop(&master->fsib, 0); 647 fsi_data_pop(&master->fsib, 0);
577 648
578 fsi_master_write(master, INT_ST, 0x0000000); 649 fsi_irq_clear_all_status(master);
579 650
580 return IRQ_HANDLED; 651 return IRQ_HANDLED;
581} 652}
@@ -669,29 +740,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
669 dev_err(dai->dev, "unknown format.\n"); 740 dev_err(dai->dev, "unknown format.\n");
670 return -EINVAL; 741 return -EINVAL;
671 } 742 }
672
673 switch (fsi->chan) {
674 case 1:
675 fsi->fifo_max = 256;
676 break;
677 case 2:
678 fsi->fifo_max = 128;
679 break;
680 case 3:
681 case 4:
682 fsi->fifo_max = 64;
683 break;
684 case 5:
685 case 6:
686 case 7:
687 case 8:
688 fsi->fifo_max = 32;
689 break;
690 default:
691 dev_err(dai->dev, "channel size error.\n");
692 return -EINVAL;
693 }
694
695 fsi_reg_write(fsi, reg, data); 743 fsi_reg_write(fsi, reg, data);
696 744
697 /* 745 /*
@@ -700,8 +748,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
700 if (is_master) 748 if (is_master)
701 fsi_clk_ctrl(fsi, 1); 749 fsi_clk_ctrl(fsi, 1);
702 750
703 /* irq setting */ 751 /* irq clear */
704 fsi_irq_init(fsi, is_play); 752 fsi_irq_disable(fsi, is_play);
753 fsi_irq_clear_status(fsi);
754
755 /* fifo init */
756 fsi_fifo_init(fsi, is_play, dai);
705 757
706 return ret; 758 return ret;
707} 759}
@@ -913,6 +965,7 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
913static int fsi_probe(struct platform_device *pdev) 965static int fsi_probe(struct platform_device *pdev)
914{ 966{
915 struct fsi_master *master; 967 struct fsi_master *master;
968 const struct platform_device_id *id_entry;
916 struct resource *res; 969 struct resource *res;
917 unsigned int irq; 970 unsigned int irq;
918 int ret; 971 int ret;
@@ -922,6 +975,12 @@ static int fsi_probe(struct platform_device *pdev)
922 return -ENODEV; 975 return -ENODEV;
923 } 976 }
924 977
978 id_entry = pdev->id_entry;
979 if (!id_entry) {
980 dev_err(&pdev->dev, "unknown fsi device\n");
981 return -ENODEV;
982 }
983
925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 984 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
926 irq = platform_get_irq(pdev, 0); 985 irq = platform_get_irq(pdev, 0);
927 if (!res || (int)irq <= 0) { 986 if (!res || (int)irq <= 0) {
@@ -950,6 +1009,7 @@ static int fsi_probe(struct platform_device *pdev)
950 master->fsia.master = master; 1009 master->fsia.master = master;
951 master->fsib.base = master->base + 0x40; 1010 master->fsib.base = master->base + 0x40;
952 master->fsib.master = master; 1011 master->fsib.master = master;
1012 master->regs = (struct fsi_regs *)id_entry->driver_data;
953 spin_lock_init(&master->lock); 1013 spin_lock_init(&master->lock);
954 1014
955 pm_runtime_enable(&pdev->dev); 1015 pm_runtime_enable(&pdev->dev);
@@ -962,7 +1022,8 @@ static int fsi_probe(struct platform_device *pdev)
962 1022
963 fsi_soft_all_reset(master); 1023 fsi_soft_all_reset(master);
964 1024
965 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 1025 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED,
1026 id_entry->name, master);
966 if (ret) { 1027 if (ret) {
967 dev_err(&pdev->dev, "irq request err\n"); 1028 dev_err(&pdev->dev, "irq request err\n");
968 goto exit_iounmap; 1029 goto exit_iounmap;
@@ -1029,6 +1090,23 @@ static struct dev_pm_ops fsi_pm_ops = {
1029 .runtime_resume = fsi_runtime_nop, 1090 .runtime_resume = fsi_runtime_nop,
1030}; 1091};
1031 1092
1093static struct fsi_regs fsi_regs = {
1094 .int_st = INT_ST,
1095 .iemsk = IEMSK,
1096 .imsk = IMSK,
1097};
1098
1099static struct fsi_regs fsi2_regs = {
1100 .int_st = CPU_INT_ST,
1101 .iemsk = CPU_IEMSK,
1102 .imsk = CPU_IMSK,
1103};
1104
1105static struct platform_device_id fsi_id_table[] = {
1106 { "sh_fsi", (kernel_ulong_t)&fsi_regs },
1107 { "sh_fsi2", (kernel_ulong_t)&fsi2_regs },
1108};
1109
1032static struct platform_driver fsi_driver = { 1110static struct platform_driver fsi_driver = {
1033 .driver = { 1111 .driver = {
1034 .name = "sh_fsi", 1112 .name = "sh_fsi",
@@ -1036,6 +1114,7 @@ static struct platform_driver fsi_driver = {
1036 }, 1114 },
1037 .probe = fsi_probe, 1115 .probe = fsi_probe,
1038 .remove = fsi_remove, 1116 .remove = fsi_remove,
1117 .id_table = fsi_id_table,
1039}; 1118};
1040 1119
1041static int __init fsi_mobile_init(void) 1120static int __init fsi_mobile_init(void)