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