~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/aw2/aw2-saa7146.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /sound/pci/aw2/aw2-saa7146.c (Version linux-6.11-rc3) and /sound/pci/aw2/aw2-saa7146.c (Version linux-5.2.21)


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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php