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