xref: /openbmc/linux/sound/pci/aw2/aw2-saa7146.c (revision 25985edc)
1 /*****************************************************************************
2  *
3  * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and
4  * Jean-Christian Hassler <jhassler@free.fr>
5  *
6  * This file is part of the Audiowerk2 ALSA driver
7  *
8  * The Audiowerk2 ALSA driver is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2.
11  *
12  * The Audiowerk2 ALSA driver is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with the Audiowerk2 ALSA driver; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20  * USA.
21  *
22  *****************************************************************************/
23 
24 #define AW2_SAA7146_M
25 
26 #include <linux/init.h>
27 #include <linux/pci.h>
28 #include <linux/interrupt.h>
29 #include <linux/delay.h>
30 #include <asm/system.h>
31 #include <asm/io.h>
32 #include <sound/core.h>
33 #include <sound/initval.h>
34 #include <sound/pcm.h>
35 #include <sound/pcm_params.h>
36 
37 #include "saa7146.h"
38 #include "aw2-saa7146.h"
39 
40 #include "aw2-tsl.c"
41 
42 #define WRITEREG(value, addr) writel((value), chip->base_addr + (addr))
43 #define READREG(addr) readl(chip->base_addr + (addr))
44 
45 static struct snd_aw2_saa7146_cb_param
46  arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
47 static struct snd_aw2_saa7146_cb_param
48  arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
49 
50 static int snd_aw2_saa7146_get_limit(int size);
51 
52 /* chip-specific destructor */
53 int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip)
54 {
55 	/* disable all irqs */
56 	WRITEREG(0, IER);
57 
58 	/* reset saa7146 */
59 	WRITEREG((MRST_N << 16), MC1);
60 
61 	/* Unset base addr */
62 	chip->base_addr = NULL;
63 
64 	return 0;
65 }
66 
67 void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
68 			   void __iomem *pci_base_addr)
69 {
70 	/* set PCI burst/threshold
71 
72 	   Burst length definition
73 	   VALUE    BURST LENGTH
74 	   000      1 Dword
75 	   001      2 Dwords
76 	   010      4 Dwords
77 	   011      8 Dwords
78 	   100      16 Dwords
79 	   101      32 Dwords
80 	   110      64 Dwords
81 	   111      128 Dwords
82 
83 	   Threshold definition
84 	   VALUE    WRITE MODE              READ MODE
85 	   00       1 Dword of valid data   1 empty Dword
86 	   01       4 Dwords of valid data  4 empty Dwords
87 	   10       8 Dwords of valid data  8 empty Dwords
88 	   11       16 Dwords of valid data 16 empty Dwords */
89 
90 	unsigned int acon2;
91 	unsigned int acon1 = 0;
92 	int i;
93 
94 	/* Set base addr */
95 	chip->base_addr = pci_base_addr;
96 
97 	/* disable all irqs */
98 	WRITEREG(0, IER);
99 
100 	/* reset saa7146 */
101 	WRITEREG((MRST_N << 16), MC1);
102 
103 	/* enable audio interface */
104 #ifdef __BIG_ENDIAN
105 	acon1 |= A1_SWAP;
106 	acon1 |= A2_SWAP;
107 #endif
108 	/* WS0_CTRL, WS0_SYNC: input TSL1, I2S */
109 
110 	/* At initialization WS1 and WS2 are disabled (configured as input) */
111 	acon1 |= 0 * WS1_CTRL;
112 	acon1 |= 0 * WS2_CTRL;
113 
114 	/* WS4 is not used. So it must not restart A2.
115 	   This is why it is configured as output (force to low) */
116 	acon1 |= 3 * WS4_CTRL;
117 
118 	/* WS3_CTRL, WS3_SYNC: output TSL2, I2S */
119 	acon1 |= 2 * WS3_CTRL;
120 
121 	/* A1 and A2 are active and asynchronous */
122 	acon1 |= 3 * AUDIO_MODE;
123 	WRITEREG(acon1, ACON1);
124 
125 	/* The following comes from original windows driver.
126 	   It is needed to have a correct behavior of input and output
127 	   simultenously, but I don't know why ! */
128 	WRITEREG(3 * (BurstA1_in) + 3 * (ThreshA1_in) +
129 		 3 * (BurstA1_out) + 3 * (ThreshA1_out) +
130 		 3 * (BurstA2_out) + 3 * (ThreshA2_out), PCI_BT_A);
131 
132 	/* enable audio port pins */
133 	WRITEREG((EAP << 16) | EAP, MC1);
134 
135 	/* enable I2C */
136 	WRITEREG((EI2C << 16) | EI2C, MC1);
137 	/* enable interrupts */
138 	WRITEREG(A1_out | A2_out | A1_in | IIC_S | IIC_E, IER);
139 
140 	/* audio configuration */
141 	acon2 = A2_CLKSRC | BCLK1_OEN;
142 	WRITEREG(acon2, ACON2);
143 
144 	/* By default use analog input */
145 	snd_aw2_saa7146_use_digital_input(chip, 0);
146 
147 	/* TSL setup */
148 	for (i = 0; i < 8; ++i) {
149 		WRITEREG(tsl1[i], TSL1 + (i * 4));
150 		WRITEREG(tsl2[i], TSL2 + (i * 4));
151 	}
152 
153 }
154 
155 void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
156 				       int stream_number,
157 				       unsigned long dma_addr,
158 				       unsigned long period_size,
159 				       unsigned long buffer_size)
160 {
161 	unsigned long dw_page, dw_limit;
162 
163 	/* Configure DMA for substream
164 	   Configuration informations: ALSA has allocated continuous memory
165 	   pages. So we don't need to use MMU of saa7146.
166 	 */
167 
168 	/* No MMU -> nothing to do with PageA1, we only configure the limit of
169 	   PageAx_out register */
170 	/* Disable MMU */
171 	dw_page = (0L << 11);
172 
173 	/* Configure Limit for DMA access.
174 	   The limit register defines an address limit, which generates
175 	   an interrupt if passed by the actual PCI address pointer.
176 	   '0001' means an interrupt will be generated if the lower
177 	   6 bits (64 bytes) of the PCI address are zero. '0010'
178 	   defines a limit of 128 bytes, '0011' one of 256 bytes, and
179 	   so on up to 1 Mbyte defined by '1111'. This interrupt range
180 	   can be calculated as follows:
181 	   Range = 2^(5 + Limit) bytes.
182 	 */
183 	dw_limit = snd_aw2_saa7146_get_limit(period_size);
184 	dw_page |= (dw_limit << 4);
185 
186 	if (stream_number == 0) {
187 		WRITEREG(dw_page, PageA2_out);
188 
189 		/* Base address for DMA transfert. */
190 		/* This address has been reserved by ALSA. */
191 		/* This is a physical address */
192 		WRITEREG(dma_addr, BaseA2_out);
193 
194 		/* Define upper limit for DMA access */
195 		WRITEREG(dma_addr + buffer_size, ProtA2_out);
196 
197 	} else if (stream_number == 1) {
198 		WRITEREG(dw_page, PageA1_out);
199 
200 		/* Base address for DMA transfert. */
201 		/* This address has been reserved by ALSA. */
202 		/* This is a physical address */
203 		WRITEREG(dma_addr, BaseA1_out);
204 
205 		/* Define upper limit for DMA access */
206 		WRITEREG(dma_addr + buffer_size, ProtA1_out);
207 	} else {
208 		printk(KERN_ERR
209 		       "aw2: snd_aw2_saa7146_pcm_init_playback: "
210 		       "Substream number is not 0 or 1 -> not managed\n");
211 	}
212 }
213 
214 void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
215 				      int stream_number, unsigned long dma_addr,
216 				      unsigned long period_size,
217 				      unsigned long buffer_size)
218 {
219 	unsigned long dw_page, dw_limit;
220 
221 	/* Configure DMA for substream
222 	   Configuration informations: ALSA has allocated continuous memory
223 	   pages. So we don't need to use MMU of saa7146.
224 	 */
225 
226 	/* No MMU -> nothing to do with PageA1, we only configure the limit of
227 	   PageAx_out register */
228 	/* Disable MMU */
229 	dw_page = (0L << 11);
230 
231 	/* Configure Limit for DMA access.
232 	   The limit register defines an address limit, which generates
233 	   an interrupt if passed by the actual PCI address pointer.
234 	   '0001' means an interrupt will be generated if the lower
235 	   6 bits (64 bytes) of the PCI address are zero. '0010'
236 	   defines a limit of 128 bytes, '0011' one of 256 bytes, and
237 	   so on up to 1 Mbyte defined by '1111'. This interrupt range
238 	   can be calculated as follows:
239 	   Range = 2^(5 + Limit) bytes.
240 	 */
241 	dw_limit = snd_aw2_saa7146_get_limit(period_size);
242 	dw_page |= (dw_limit << 4);
243 
244 	if (stream_number == 0) {
245 		WRITEREG(dw_page, PageA1_in);
246 
247 		/* Base address for DMA transfert. */
248 		/* This address has been reserved by ALSA. */
249 		/* This is a physical address */
250 		WRITEREG(dma_addr, BaseA1_in);
251 
252 		/* Define upper limit for DMA access  */
253 		WRITEREG(dma_addr + buffer_size, ProtA1_in);
254 	} else {
255 		printk(KERN_ERR
256 		       "aw2: snd_aw2_saa7146_pcm_init_capture: "
257 		       "Substream number is not 0 -> not managed\n");
258 	}
259 }
260 
261 void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number,
262 						 snd_aw2_saa7146_it_cb
263 						 p_it_callback,
264 						 void *p_callback_param)
265 {
266 	if (stream_number < NB_STREAM_PLAYBACK) {
267 		arr_substream_it_playback_cb[stream_number].p_it_callback =
268 		    (snd_aw2_saa7146_it_cb) p_it_callback;
269 		arr_substream_it_playback_cb[stream_number].p_callback_param =
270 		    (void *)p_callback_param;
271 	}
272 }
273 
274 void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number,
275 						snd_aw2_saa7146_it_cb
276 						p_it_callback,
277 						void *p_callback_param)
278 {
279 	if (stream_number < NB_STREAM_CAPTURE) {
280 		arr_substream_it_capture_cb[stream_number].p_it_callback =
281 		    (snd_aw2_saa7146_it_cb) p_it_callback;
282 		arr_substream_it_capture_cb[stream_number].p_callback_param =
283 		    (void *)p_callback_param;
284 	}
285 }
286 
287 void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146 *chip,
288 						int stream_number)
289 {
290 	unsigned int acon1 = 0;
291 	/* In aw8 driver, dma transfert is always active. It is
292 	   started and stopped in a larger "space" */
293 	acon1 = READREG(ACON1);
294 	if (stream_number == 0) {
295 		WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
296 
297 		/* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
298 		acon1 |= 2 * WS2_CTRL;
299 		WRITEREG(acon1, ACON1);
300 
301 	} else if (stream_number == 1) {
302 		WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
303 
304 		/* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
305 		acon1 |= 1 * WS1_CTRL;
306 		WRITEREG(acon1, ACON1);
307 	}
308 }
309 
310 void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146 *chip,
311 					       int stream_number)
312 {
313 	unsigned int acon1 = 0;
314 	acon1 = READREG(ACON1);
315 	if (stream_number == 0) {
316 		/* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
317 		acon1 &= ~(3 * WS2_CTRL);
318 		WRITEREG(acon1, ACON1);
319 
320 		WRITEREG((TR_E_A2_OUT << 16), MC1);
321 	} else if (stream_number == 1) {
322 		/* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
323 		acon1 &= ~(3 * WS1_CTRL);
324 		WRITEREG(acon1, ACON1);
325 
326 		WRITEREG((TR_E_A1_OUT << 16), MC1);
327 	}
328 }
329 
330 void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146 *chip,
331 					       int stream_number)
332 {
333 	/* In aw8 driver, dma transfert is always active. It is
334 	   started and stopped in a larger "space" */
335 	if (stream_number == 0)
336 		WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
337 }
338 
339 void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip,
340 					      int stream_number)
341 {
342 	if (stream_number == 0)
343 		WRITEREG((TR_E_A1_IN << 16), MC1);
344 }
345 
346 irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id)
347 {
348 	unsigned int isr;
349 	unsigned int iicsta;
350 	struct snd_aw2_saa7146 *chip = dev_id;
351 
352 	isr = READREG(ISR);
353 	if (!isr)
354 		return IRQ_NONE;
355 
356 	WRITEREG(isr, ISR);
357 
358 	if (isr & (IIC_S | IIC_E)) {
359 		iicsta = READREG(IICSTA);
360 		WRITEREG(0x100, IICSTA);
361 	}
362 
363 	if (isr & A1_out) {
364 		if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
365 			arr_substream_it_playback_cb[1].
366 			    p_it_callback(arr_substream_it_playback_cb[1].
367 					  p_callback_param);
368 		}
369 	}
370 	if (isr & A2_out) {
371 		if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
372 			arr_substream_it_playback_cb[0].
373 			    p_it_callback(arr_substream_it_playback_cb[0].
374 					  p_callback_param);
375 		}
376 
377 	}
378 	if (isr & A1_in) {
379 		if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
380 			arr_substream_it_capture_cb[0].
381 			    p_it_callback(arr_substream_it_capture_cb[0].
382 					  p_callback_param);
383 		}
384 	}
385 	return IRQ_HANDLED;
386 }
387 
388 unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
389 						 int stream_number,
390 						 unsigned char *start_addr,
391 						 unsigned int buffer_size)
392 {
393 	long pci_adp = 0;
394 	size_t ptr = 0;
395 
396 	if (stream_number == 0) {
397 		pci_adp = READREG(PCI_ADP3);
398 		ptr = pci_adp - (long)start_addr;
399 
400 		if (ptr == buffer_size)
401 			ptr = 0;
402 	}
403 	if (stream_number == 1) {
404 		pci_adp = READREG(PCI_ADP1);
405 		ptr = pci_adp - (size_t) start_addr;
406 
407 		if (ptr == buffer_size)
408 			ptr = 0;
409 	}
410 	return ptr;
411 }
412 
413 unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
414 						int stream_number,
415 						unsigned char *start_addr,
416 						unsigned int buffer_size)
417 {
418 	size_t pci_adp = 0;
419 	size_t ptr = 0;
420 	if (stream_number == 0) {
421 		pci_adp = READREG(PCI_ADP2);
422 		ptr = pci_adp - (size_t) start_addr;
423 
424 		if (ptr == buffer_size)
425 			ptr = 0;
426 	}
427 	return ptr;
428 }
429 
430 void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
431 				       int use_digital)
432 {
433 	/* FIXME: switch between analog and digital input does not always work.
434 	   It can produce a kind of white noise. It seams that received data
435 	   are inverted sometime (endian inversion). Why ? I don't know, maybe
436 	   a problem of synchronization... However for the time being I have
437 	   not found the problem. Workaround: switch again (and again) between
438 	   digital and analog input until it works. */
439 	if (use_digital)
440 		WRITEREG(0x40, GPIO_CTRL);
441 	else
442 		WRITEREG(0x50, GPIO_CTRL);
443 }
444 
445 int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
446 {
447 	unsigned int reg_val = READREG(GPIO_CTRL);
448 	if ((reg_val & 0xFF) == 0x40)
449 		return 1;
450 	else
451 		return 0;
452 }
453 
454 
455 static int snd_aw2_saa7146_get_limit(int size)
456 {
457 	int limitsize = 32;
458 	int limit = 0;
459 	while (limitsize < size) {
460 		limitsize *= 2;
461 		limit++;
462 	}
463 	return limit;
464 }
465