diff options
-rw-r--r-- | sound/soc/sh/fsi.c | 53 |
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 | ||
347 | static u32 fsi_irq_get_status(struct fsi_master *master) | ||
348 | { | ||
349 | return fsi_master_read(master, INT_ST); | ||
350 | } | ||
351 | |||
352 | static void fsi_irq_clear_all_status(struct fsi_master *master) | ||
353 | { | ||
354 | fsi_master_write(master, INT_ST, 0x0000000); | ||
355 | } | ||
356 | |||
357 | static 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 | ************************************************************************/ | ||
347 | static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) | 376 | static 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 | ||
358 | static void fsi_irq_init(struct fsi_priv *fsi, int is_play) | 387 | static 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 | ||
379 | static void fsi_soft_all_reset(struct fsi_master *master) | 400 | static void fsi_soft_all_reset(struct fsi_master *master) |
@@ -559,7 +580,7 @@ static int fsi_data_pop(struct fsi_priv *fsi, int startup) | |||
559 | static irqreturn_t fsi_interrupt(int irq, void *data) | 580 | static 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 | } |