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