24
24
#include <sound/pcm_params.h>
25
25
#include <sound/soc.h>
26
26
#include <sound/dmaengine_pcm.h>
27
-
28
- /* common register for all channel */
29
- #define IER 0x000
30
- #define IRER 0x004
31
- #define ITER 0x008
32
- #define CER 0x00C
33
- #define CCR 0x010
34
- #define RXFFR 0x014
35
- #define TXFFR 0x018
36
-
37
- /* I2STxRxRegisters for all channels */
38
- #define LRBR_LTHR (x ) (0x40 * x + 0x020)
39
- #define RRBR_RTHR (x ) (0x40 * x + 0x024)
40
- #define RER (x ) (0x40 * x + 0x028)
41
- #define TER (x ) (0x40 * x + 0x02C)
42
- #define RCR (x ) (0x40 * x + 0x030)
43
- #define TCR (x ) (0x40 * x + 0x034)
44
- #define ISR (x ) (0x40 * x + 0x038)
45
- #define IMR (x ) (0x40 * x + 0x03C)
46
- #define ROR (x ) (0x40 * x + 0x040)
47
- #define TOR (x ) (0x40 * x + 0x044)
48
- #define RFCR (x ) (0x40 * x + 0x048)
49
- #define TFCR (x ) (0x40 * x + 0x04C)
50
- #define RFF (x ) (0x40 * x + 0x050)
51
- #define TFF (x ) (0x40 * x + 0x054)
52
-
53
- /* I2SCOMPRegisters */
54
- #define I2S_COMP_PARAM_2 0x01F0
55
- #define I2S_COMP_PARAM_1 0x01F4
56
- #define I2S_COMP_VERSION 0x01F8
57
- #define I2S_COMP_TYPE 0x01FC
58
-
59
- /*
60
- * Component parameter register fields - define the I2S block's
61
- * configuration.
62
- */
63
- #define COMP1_TX_WORDSIZE_3 (r ) (((r) & GENMASK(27, 25)) >> 25)
64
- #define COMP1_TX_WORDSIZE_2 (r ) (((r) & GENMASK(24, 22)) >> 22)
65
- #define COMP1_TX_WORDSIZE_1 (r ) (((r) & GENMASK(21, 19)) >> 19)
66
- #define COMP1_TX_WORDSIZE_0 (r ) (((r) & GENMASK(18, 16)) >> 16)
67
- #define COMP1_TX_CHANNELS (r ) (((r) & GENMASK(10, 9)) >> 9)
68
- #define COMP1_RX_CHANNELS (r ) (((r) & GENMASK(8, 7)) >> 7)
69
- #define COMP1_RX_ENABLED (r ) (((r) & BIT(6)) >> 6)
70
- #define COMP1_TX_ENABLED (r ) (((r) & BIT(5)) >> 5)
71
- #define COMP1_MODE_EN (r ) (((r) & BIT(4)) >> 4)
72
- #define COMP1_FIFO_DEPTH_GLOBAL (r ) (((r) & GENMASK(3, 2)) >> 2)
73
- #define COMP1_APB_DATA_WIDTH (r ) (((r) & GENMASK(1, 0)) >> 0)
74
-
75
- #define COMP2_RX_WORDSIZE_3 (r ) (((r) & GENMASK(12, 10)) >> 10)
76
- #define COMP2_RX_WORDSIZE_2 (r ) (((r) & GENMASK(9, 7)) >> 7)
77
- #define COMP2_RX_WORDSIZE_1 (r ) (((r) & GENMASK(5, 3)) >> 3)
78
- #define COMP2_RX_WORDSIZE_0 (r ) (((r) & GENMASK(2, 0)) >> 0)
79
-
80
- /* Number of entries in WORDSIZE and DATA_WIDTH parameter registers */
81
- #define COMP_MAX_WORDSIZE (1 << 3)
82
- #define COMP_MAX_DATA_WIDTH (1 << 2)
83
-
84
- #define MAX_CHANNEL_NUM 8
85
- #define MIN_CHANNEL_NUM 2
86
-
87
- union dw_i2s_snd_dma_data {
88
- struct i2s_dma_data pd ;
89
- struct snd_dmaengine_dai_dma_data dt ;
90
- };
91
-
92
- struct dw_i2s_dev {
93
- void __iomem * i2s_base ;
94
- struct clk * clk ;
95
- int active ;
96
- unsigned int capability ;
97
- unsigned int quirks ;
98
- unsigned int i2s_reg_comp1 ;
99
- unsigned int i2s_reg_comp2 ;
100
- struct device * dev ;
101
- u32 ccr ;
102
- u32 xfer_resolution ;
103
- u32 fifo_th ;
104
-
105
- /* data related to DMA transfers b/w i2s and DMAC */
106
- union dw_i2s_snd_dma_data play_dma_data ;
107
- union dw_i2s_snd_dma_data capture_dma_data ;
108
- struct i2s_clk_config_data config ;
109
- int (* i2s_clk_cfg )(struct i2s_clk_config_data * config );
110
- };
27
+ #include "local.h"
111
28
112
29
static inline void i2s_write_reg (void __iomem * io_base , int reg , u32 val )
113
30
{
@@ -181,6 +98,52 @@ static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
181
98
}
182
99
}
183
100
101
+ static irqreturn_t i2s_irq_handler (int irq , void * dev_id )
102
+ {
103
+ struct dw_i2s_dev * dev = dev_id ;
104
+ bool irq_valid = false;
105
+ u32 isr [4 ];
106
+ int i ;
107
+
108
+ for (i = 0 ; i < 4 ; i ++ )
109
+ isr [i ] = i2s_read_reg (dev -> i2s_base , ISR (i ));
110
+
111
+ i2s_clear_irqs (dev , SNDRV_PCM_STREAM_PLAYBACK );
112
+ i2s_clear_irqs (dev , SNDRV_PCM_STREAM_CAPTURE );
113
+
114
+ for (i = 0 ; i < 4 ; i ++ ) {
115
+ /*
116
+ * Check if TX fifo is empty. If empty fill FIFO with samples
117
+ * NOTE: Only two channels supported
118
+ */
119
+ if ((isr [i ] & ISR_TXFE ) && (i == 0 ) && dev -> use_pio ) {
120
+ dw_pcm_push_tx (dev );
121
+ irq_valid = true;
122
+ }
123
+
124
+ /* Data available. Record mode not supported in PIO mode */
125
+ if (isr [i ] & ISR_RXDA )
126
+ irq_valid = true;
127
+
128
+ /* Error Handling: TX */
129
+ if (isr [i ] & ISR_TXFO ) {
130
+ dev_err (dev -> dev , "TX overrun (ch_id=%d)\n" , i );
131
+ irq_valid = true;
132
+ }
133
+
134
+ /* Error Handling: TX */
135
+ if (isr [i ] & ISR_RXFO ) {
136
+ dev_err (dev -> dev , "RX overrun (ch_id=%d)\n" , i );
137
+ irq_valid = true;
138
+ }
139
+ }
140
+
141
+ if (irq_valid )
142
+ return IRQ_HANDLED ;
143
+ else
144
+ return IRQ_NONE ;
145
+ }
146
+
184
147
static void i2s_start (struct dw_i2s_dev * dev ,
185
148
struct snd_pcm_substream * substream )
186
149
{
@@ -640,7 +603,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
640
603
const struct i2s_platform_data * pdata = pdev -> dev .platform_data ;
641
604
struct dw_i2s_dev * dev ;
642
605
struct resource * res ;
643
- int ret ;
606
+ int ret , irq ;
644
607
struct snd_soc_dai_driver * dw_i2s_dai ;
645
608
const char * clk_id ;
646
609
@@ -665,6 +628,16 @@ static int dw_i2s_probe(struct platform_device *pdev)
665
628
666
629
dev -> dev = & pdev -> dev ;
667
630
631
+ irq = platform_get_irq (pdev , 0 );
632
+ if (irq >= 0 ) {
633
+ ret = devm_request_irq (& pdev -> dev , irq , i2s_irq_handler , 0 ,
634
+ pdev -> name , dev );
635
+ if (ret < 0 ) {
636
+ dev_err (& pdev -> dev , "failed to request irq\n" );
637
+ return ret ;
638
+ }
639
+ }
640
+
668
641
dev -> i2s_reg_comp1 = I2S_COMP_PARAM_1 ;
669
642
dev -> i2s_reg_comp2 = I2S_COMP_PARAM_2 ;
670
643
if (pdata ) {
@@ -711,12 +684,24 @@ static int dw_i2s_probe(struct platform_device *pdev)
711
684
712
685
if (!pdata ) {
713
686
ret = devm_snd_dmaengine_pcm_register (& pdev -> dev , NULL , 0 );
714
- if (ret ) {
687
+ if (ret == - EPROBE_DEFER ) {
688
+ dev_err (& pdev -> dev ,
689
+ "failed to register PCM, deferring probe\n" );
690
+ return ret ;
691
+ } else if (ret ) {
715
692
dev_err (& pdev -> dev ,
716
- "Could not register PCM: %d\n" , ret );
717
- goto err_clk_disable ;
693
+ "Could not register DMA PCM: %d\n"
694
+ "falling back to PIO mode\n" , ret );
695
+ ret = dw_pcm_register (pdev );
696
+ if (ret ) {
697
+ dev_err (& pdev -> dev ,
698
+ "Could not register PIO PCM: %d\n" ,
699
+ ret );
700
+ goto err_clk_disable ;
701
+ }
718
702
}
719
703
}
704
+
720
705
pm_runtime_enable (& pdev -> dev );
721
706
return 0 ;
722
707
0 commit comments