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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.