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