aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/sh/fsi.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index db91349b6806..7c295df6e855 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -322,7 +322,7 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
322/************************************************************************ 322/************************************************************************
323 323
324 324
325 ctrl function 325 irq function
326 326
327 327
328************************************************************************/ 328************************************************************************/
@@ -344,6 +344,35 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
344 fsi_master_mask_set(master, IEMSK, data, 0); 344 fsi_master_mask_set(master, IEMSK, data, 0);
345} 345}
346 346
347static u32 fsi_irq_get_status(struct fsi_master *master)
348{
349 return fsi_master_read(master, INT_ST);
350}
351
352static void fsi_irq_clear_all_status(struct fsi_master *master)
353{
354 fsi_master_write(master, INT_ST, 0x0000000);
355}
356
357static void fsi_irq_clear_status(struct fsi_priv *fsi)
358{
359 u32 data = 0;
360 struct fsi_master *master = fsi_get_master(fsi);
361
362 data |= fsi_port_ab_io_bit(fsi, 0);
363 data |= fsi_port_ab_io_bit(fsi, 1);
364
365 /* clear interrupt factor */
366 fsi_master_mask_set(master, INT_ST, data, 0);
367}
368
369/************************************************************************
370
371
372 ctrl function
373
374
375************************************************************************/
347static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 376static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
348{ 377{
349 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 378 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
@@ -355,25 +384,17 @@ static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
355 fsi_master_mask_set(master, CLK_RST, val, 0); 384 fsi_master_mask_set(master, CLK_RST, val, 0);
356} 385}
357 386
358static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 387static void fsi_fifo_init(struct fsi_priv *fsi, int is_play)
359{ 388{
360 u32 data;
361 u32 ctrl; 389 u32 ctrl;
362 390
363 data = fsi_port_ab_io_bit(fsi, is_play);
364 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 391 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
365 392
366 /* set IMSK */
367 fsi_irq_disable(fsi, is_play);
368
369 /* set interrupt generation factor */ 393 /* set interrupt generation factor */
370 fsi_reg_write(fsi, ctrl, IRQ_HALF); 394 fsi_reg_write(fsi, ctrl, IRQ_HALF);
371 395
372 /* clear FIFO */ 396 /* clear FIFO */
373 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 397 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
374
375 /* clear interrupt factor */
376 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
377} 398}
378 399
379static void fsi_soft_all_reset(struct fsi_master *master) 400static void fsi_soft_all_reset(struct fsi_master *master)
@@ -559,7 +580,7 @@ static int fsi_data_pop(struct fsi_priv *fsi, int startup)
559static irqreturn_t fsi_interrupt(int irq, void *data) 580static irqreturn_t fsi_interrupt(int irq, void *data)
560{ 581{
561 struct fsi_master *master = data; 582 struct fsi_master *master = data;
562 u32 int_st = fsi_master_read(master, INT_ST); 583 u32 int_st = fsi_irq_get_status(master);
563 584
564 /* clear irq status */ 585 /* clear irq status */
565 fsi_master_mask_set(master, SOFT_RST, IR, 0); 586 fsi_master_mask_set(master, SOFT_RST, IR, 0);
@@ -574,7 +595,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
574 if (int_st & INT_B_IN) 595 if (int_st & INT_B_IN)
575 fsi_data_pop(&master->fsib, 0); 596 fsi_data_pop(&master->fsib, 0);
576 597
577 fsi_master_write(master, INT_ST, 0x0000000); 598 fsi_irq_clear_all_status(master);
578 599
579 return IRQ_HANDLED; 600 return IRQ_HANDLED;
580} 601}
@@ -699,8 +720,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
699 if (is_master) 720 if (is_master)
700 fsi_clk_ctrl(fsi, 1); 721 fsi_clk_ctrl(fsi, 1);
701 722
702 /* irq setting */ 723 /* irq clear */
703 fsi_irq_init(fsi, is_play); 724 fsi_irq_disable(fsi, is_play);
725 fsi_irq_clear_status(fsi);
726
727 /* fifo init */
728 fsi_fifo_init(fsi, is_play);
704 729
705 return ret; 730 return ret;
706} 731}