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