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
{
@@ -145,51 +62,115 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
145
62
}
146
63
}
147
64
148
- static void i2s_start (struct dw_i2s_dev * dev ,
149
- struct snd_pcm_substream * substream )
65
+ static inline void i2s_disable_irqs (struct dw_i2s_dev * dev , u32 stream ,
66
+ int chan_nr )
67
+ {
68
+ u32 i , irq ;
69
+
70
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK ) {
71
+ for (i = 0 ; i < (chan_nr / 2 ); i ++ ) {
72
+ irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
73
+ i2s_write_reg (dev -> i2s_base , IMR (i ), irq | 0x30 );
74
+ }
75
+ } else {
76
+ for (i = 0 ; i < (chan_nr / 2 ); i ++ ) {
77
+ irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
78
+ i2s_write_reg (dev -> i2s_base , IMR (i ), irq | 0x03 );
79
+ }
80
+ }
81
+ }
82
+
83
+ static inline void i2s_enable_irqs (struct dw_i2s_dev * dev , u32 stream ,
84
+ int chan_nr )
150
85
{
151
- struct i2s_clk_config_data * config = & dev -> config ;
152
86
u32 i , irq ;
153
- i2s_write_reg (dev -> i2s_base , IER , 1 );
154
87
155
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
156
- for (i = 0 ; i < (config -> chan_nr / 2 ); i ++ ) {
88
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK ) {
89
+ for (i = 0 ; i < (chan_nr / 2 ); i ++ ) {
157
90
irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
158
91
i2s_write_reg (dev -> i2s_base , IMR (i ), irq & ~0x30 );
159
92
}
160
- i2s_write_reg (dev -> i2s_base , ITER , 1 );
161
93
} else {
162
- for (i = 0 ; i < (config -> chan_nr / 2 ); i ++ ) {
94
+ for (i = 0 ; i < (chan_nr / 2 ); i ++ ) {
163
95
irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
164
96
i2s_write_reg (dev -> i2s_base , IMR (i ), irq & ~0x03 );
165
97
}
166
- i2s_write_reg (dev -> i2s_base , IRER , 1 );
98
+ }
99
+ }
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
+ }
167
139
}
168
140
141
+ if (irq_valid )
142
+ return IRQ_HANDLED ;
143
+ else
144
+ return IRQ_NONE ;
145
+ }
146
+
147
+ static void i2s_start (struct dw_i2s_dev * dev ,
148
+ struct snd_pcm_substream * substream )
149
+ {
150
+ struct i2s_clk_config_data * config = & dev -> config ;
151
+
152
+ i2s_write_reg (dev -> i2s_base , IER , 1 );
153
+ i2s_enable_irqs (dev , substream -> stream , config -> chan_nr );
154
+
155
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
156
+ i2s_write_reg (dev -> i2s_base , ITER , 1 );
157
+ else
158
+ i2s_write_reg (dev -> i2s_base , IRER , 1 );
159
+
169
160
i2s_write_reg (dev -> i2s_base , CER , 1 );
170
161
}
171
162
172
163
static void i2s_stop (struct dw_i2s_dev * dev ,
173
164
struct snd_pcm_substream * substream )
174
165
{
175
- u32 i = 0 , irq ;
176
166
177
167
i2s_clear_irqs (dev , substream -> stream );
178
- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
168
+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
179
169
i2s_write_reg (dev -> i2s_base , ITER , 0 );
180
-
181
- for (i = 0 ; i < 4 ; i ++ ) {
182
- irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
183
- i2s_write_reg (dev -> i2s_base , IMR (i ), irq | 0x30 );
184
- }
185
- } else {
170
+ else
186
171
i2s_write_reg (dev -> i2s_base , IRER , 0 );
187
172
188
- for (i = 0 ; i < 4 ; i ++ ) {
189
- irq = i2s_read_reg (dev -> i2s_base , IMR (i ));
190
- i2s_write_reg (dev -> i2s_base , IMR (i ), irq | 0x03 );
191
- }
192
- }
173
+ i2s_disable_irqs (dev , substream -> stream , 8 );
193
174
194
175
if (!dev -> active ) {
195
176
i2s_write_reg (dev -> i2s_base , CER , 0 );
@@ -223,7 +204,7 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream,
223
204
224
205
static void dw_i2s_config (struct dw_i2s_dev * dev , int stream )
225
206
{
226
- u32 ch_reg , irq ;
207
+ u32 ch_reg ;
227
208
struct i2s_clk_config_data * config = & dev -> config ;
228
209
229
210
@@ -235,16 +216,12 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
235
216
dev -> xfer_resolution );
236
217
i2s_write_reg (dev -> i2s_base , TFCR (ch_reg ),
237
218
dev -> fifo_th - 1 );
238
- irq = i2s_read_reg (dev -> i2s_base , IMR (ch_reg ));
239
- i2s_write_reg (dev -> i2s_base , IMR (ch_reg ), irq & ~0x30 );
240
219
i2s_write_reg (dev -> i2s_base , TER (ch_reg ), 1 );
241
220
} else {
242
221
i2s_write_reg (dev -> i2s_base , RCR (ch_reg ),
243
222
dev -> xfer_resolution );
244
223
i2s_write_reg (dev -> i2s_base , RFCR (ch_reg ),
245
224
dev -> fifo_th - 1 );
246
- irq = i2s_read_reg (dev -> i2s_base , IMR (ch_reg ));
247
- i2s_write_reg (dev -> i2s_base , IMR (ch_reg ), irq & ~0x03 );
248
225
i2s_write_reg (dev -> i2s_base , RER (ch_reg ), 1 );
249
226
}
250
227
@@ -278,7 +255,7 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
278
255
break ;
279
256
280
257
default :
281
- dev_err (dev -> dev , "designware-i2s: unsuppted PCM fmt" );
258
+ dev_err (dev -> dev , "designware-i2s: unsupported PCM fmt" );
282
259
return - EINVAL ;
283
260
}
284
261
@@ -626,7 +603,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
626
603
const struct i2s_platform_data * pdata = pdev -> dev .platform_data ;
627
604
struct dw_i2s_dev * dev ;
628
605
struct resource * res ;
629
- int ret ;
606
+ int ret , irq ;
630
607
struct snd_soc_dai_driver * dw_i2s_dai ;
631
608
const char * clk_id ;
632
609
@@ -651,6 +628,16 @@ static int dw_i2s_probe(struct platform_device *pdev)
651
628
652
629
dev -> dev = & pdev -> dev ;
653
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
+
654
641
dev -> i2s_reg_comp1 = I2S_COMP_PARAM_1 ;
655
642
dev -> i2s_reg_comp2 = I2S_COMP_PARAM_2 ;
656
643
if (pdata ) {
@@ -697,12 +684,24 @@ static int dw_i2s_probe(struct platform_device *pdev)
697
684
698
685
if (!pdata ) {
699
686
ret = devm_snd_dmaengine_pcm_register (& pdev -> dev , NULL , 0 );
700
- 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 ) {
701
692
dev_err (& pdev -> dev ,
702
- "Could not register PCM: %d\n" , ret );
703
- 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
+ }
704
702
}
705
703
}
704
+
706
705
pm_runtime_enable (& pdev -> dev );
707
706
return 0 ;
708
707
0 commit comments