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