Linux Audio

Check our new training course

Loading...
v4.17
  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
 44static struct snd_aw2_saa7146_cb_param
 45 arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
 46static struct snd_aw2_saa7146_cb_param
 47 arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
 48
 49static int snd_aw2_saa7146_get_limit(int size);
 50
 51/* chip-specific destructor */
 52int 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
 66void 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
154void 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
212void 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
258void 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
271void 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
284void 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
307void 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
327void 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
336void 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
343irqreturn_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
385unsigned 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
410unsigned 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
427void 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
442int 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
452static 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}
v3.1
  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
 45static struct snd_aw2_saa7146_cb_param
 46 arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
 47static struct snd_aw2_saa7146_cb_param
 48 arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
 49
 50static int snd_aw2_saa7146_get_limit(int size);
 51
 52/* chip-specific destructor */
 53int 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
 67void 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
155void 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
214void 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
261void 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
274void 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
287void 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
310void 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
330void 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
339void 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
346irqreturn_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
388unsigned 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
413unsigned 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
430void 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
445int 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
455static 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}