Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aw2-saa7146.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2008 Cedric Bregardis <[email protected]> and
4  * Jean-Christian Hassler <[email protected]>
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/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 */
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 
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 */
138 
139  /* audio configuration */
140  acon2 = A2_CLKSRC | BCLK1_OEN;
141  WRITEREG(acon2, ACON2);
142 
143  /* By default use analog input */
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 
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 {
208  "aw2: snd_aw2_saa7146_pcm_init_playback: "
209  "Substream number is not 0 or 1 -> not managed\n");
210  }
211 }
212 
214  int stream_number, unsigned long dma_addr,
215  unsigned long period_size,
216  unsigned long buffer_size)
217 {
218  unsigned long dw_page, dw_limit;
219 
220  /* Configure DMA for substream
221  Configuration informations: ALSA has allocated continuous memory
222  pages. So we don't need to use MMU of saa7146.
223  */
224 
225  /* No MMU -> nothing to do with PageA1, we only configure the limit of
226  PageAx_out register */
227  /* Disable MMU */
228  dw_page = (0L << 11);
229 
230  /* Configure Limit for DMA access.
231  The limit register defines an address limit, which generates
232  an interrupt if passed by the actual PCI address pointer.
233  '0001' means an interrupt will be generated if the lower
234  6 bits (64 bytes) of the PCI address are zero. '0010'
235  defines a limit of 128 bytes, '0011' one of 256 bytes, and
236  so on up to 1 Mbyte defined by '1111'. This interrupt range
237  can be calculated as follows:
238  Range = 2^(5 + Limit) bytes.
239  */
240  dw_limit = snd_aw2_saa7146_get_limit(period_size);
241  dw_page |= (dw_limit << 4);
242 
243  if (stream_number == 0) {
244  WRITEREG(dw_page, PageA1_in);
245 
246  /* Base address for DMA transfert. */
247  /* This address has been reserved by ALSA. */
248  /* This is a physical address */
249  WRITEREG(dma_addr, BaseA1_in);
250 
251  /* Define upper limit for DMA access */
252  WRITEREG(dma_addr + buffer_size, ProtA1_in);
253  } else {
255  "aw2: snd_aw2_saa7146_pcm_init_capture: "
256  "Substream number is not 0 -> not managed\n");
257  }
258 }
259 
263  void *p_callback_param)
264 {
265  if (stream_number < NB_STREAM_PLAYBACK) {
266  arr_substream_it_playback_cb[stream_number].p_it_callback =
267  (snd_aw2_saa7146_it_cb) p_it_callback;
268  arr_substream_it_playback_cb[stream_number].p_callback_param =
269  (void *)p_callback_param;
270  }
271 }
272 
276  void *p_callback_param)
277 {
278  if (stream_number < NB_STREAM_CAPTURE) {
279  arr_substream_it_capture_cb[stream_number].p_it_callback =
280  (snd_aw2_saa7146_it_cb) p_it_callback;
281  arr_substream_it_capture_cb[stream_number].p_callback_param =
282  (void *)p_callback_param;
283  }
284 }
285 
287  int stream_number)
288 {
289  unsigned int acon1 = 0;
290  /* In aw8 driver, dma transfert is always active. It is
291  started and stopped in a larger "space" */
292  acon1 = READREG(ACON1);
293  if (stream_number == 0) {
294  WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
295 
296  /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
297  acon1 |= 2 * WS2_CTRL;
298  WRITEREG(acon1, ACON1);
299 
300  } else if (stream_number == 1) {
301  WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
302 
303  /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
304  acon1 |= 1 * WS1_CTRL;
305  WRITEREG(acon1, ACON1);
306  }
307 }
308 
310  int stream_number)
311 {
312  unsigned int acon1 = 0;
313  acon1 = READREG(ACON1);
314  if (stream_number == 0) {
315  /* WS2_CTRL, WS2_SYNC: output TSL2, I2S */
316  acon1 &= ~(3 * WS2_CTRL);
317  WRITEREG(acon1, ACON1);
318 
319  WRITEREG((TR_E_A2_OUT << 16), MC1);
320  } else if (stream_number == 1) {
321  /* WS1_CTRL, WS1_SYNC: output TSL1, I2S */
322  acon1 &= ~(3 * WS1_CTRL);
323  WRITEREG(acon1, ACON1);
324 
325  WRITEREG((TR_E_A1_OUT << 16), MC1);
326  }
327 }
328 
330  int stream_number)
331 {
332  /* In aw8 driver, dma transfert is always active. It is
333  started and stopped in a larger "space" */
334  if (stream_number == 0)
335  WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
336 }
337 
339  int stream_number)
340 {
341  if (stream_number == 0)
342  WRITEREG((TR_E_A1_IN << 16), MC1);
343 }
344 
346 {
347  unsigned int isr;
348  unsigned int iicsta;
349  struct snd_aw2_saa7146 *chip = dev_id;
350 
351  isr = READREG(ISR);
352  if (!isr)
353  return IRQ_NONE;
354 
355  WRITEREG(isr, ISR);
356 
357  if (isr & (IIC_S | IIC_E)) {
358  iicsta = READREG(IICSTA);
359  WRITEREG(0x100, IICSTA);
360  }
361 
362  if (isr & A1_out) {
363  if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
364  arr_substream_it_playback_cb[1].
365  p_it_callback(arr_substream_it_playback_cb[1].
366  p_callback_param);
367  }
368  }
369  if (isr & A2_out) {
370  if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
371  arr_substream_it_playback_cb[0].
372  p_it_callback(arr_substream_it_playback_cb[0].
373  p_callback_param);
374  }
375 
376  }
377  if (isr & A1_in) {
378  if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
379  arr_substream_it_capture_cb[0].
380  p_it_callback(arr_substream_it_capture_cb[0].
381  p_callback_param);
382  }
383  }
384  return IRQ_HANDLED;
385 }
386 
388  int stream_number,
389  unsigned char *start_addr,
390  unsigned int buffer_size)
391 {
392  long pci_adp = 0;
393  size_t ptr = 0;
394 
395  if (stream_number == 0) {
396  pci_adp = READREG(PCI_ADP3);
397  ptr = pci_adp - (long)start_addr;
398 
399  if (ptr == buffer_size)
400  ptr = 0;
401  }
402  if (stream_number == 1) {
403  pci_adp = READREG(PCI_ADP1);
404  ptr = pci_adp - (size_t) start_addr;
405 
406  if (ptr == buffer_size)
407  ptr = 0;
408  }
409  return ptr;
410 }
411 
413  int stream_number,
414  unsigned char *start_addr,
415  unsigned int buffer_size)
416 {
417  size_t pci_adp = 0;
418  size_t ptr = 0;
419  if (stream_number == 0) {
420  pci_adp = READREG(PCI_ADP2);
421  ptr = pci_adp - (size_t) start_addr;
422 
423  if (ptr == buffer_size)
424  ptr = 0;
425  }
426  return ptr;
427 }
428 
430  int use_digital)
431 {
432  /* FIXME: switch between analog and digital input does not always work.
433  It can produce a kind of white noise. It seams that received data
434  are inverted sometime (endian inversion). Why ? I don't know, maybe
435  a problem of synchronization... However for the time being I have
436  not found the problem. Workaround: switch again (and again) between
437  digital and analog input until it works. */
438  if (use_digital)
439  WRITEREG(0x40, GPIO_CTRL);
440  else
441  WRITEREG(0x50, GPIO_CTRL);
442 }
443 
445 {
446  unsigned int reg_val = READREG(GPIO_CTRL);
447  if ((reg_val & 0xFF) == 0x40)
448  return 1;
449  else
450  return 0;
451 }
452 
453 
454 static int snd_aw2_saa7146_get_limit(int size)
455 {
456  int limitsize = 32;
457  int limit = 0;
458  while (limitsize < size) {
459  limitsize *= 2;
460  limit++;
461  }
462  return limit;
463 }