1 /* 2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> 3 * Driver p16v chips 4 * Version: 0.25 5 * 6 * FEATURES currently supported: 7 * Output fixed at S32_LE, 2 channel to hw:0,0 8 * Rates: 44.1, 48, 96, 192. 9 * 10 * Changelog: 11 * 0.8 12 * Use separate card based buffer for periods table. 13 * 0.9 14 * Use 2 channel output streams instead of 8 channel. 15 * (8 channel output streams might be good for ASIO type output) 16 * Corrected speaker output, so Front -> Front etc. 17 * 0.10 18 * Fixed missed interrupts. 19 * 0.11 20 * Add Sound card model number and names. 21 * Add Analog volume controls. 22 * 0.12 23 * Corrected playback interrupts. Now interrupt per period, instead of half period. 24 * 0.13 25 * Use single trigger for multichannel. 26 * 0.14 27 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo. 28 * 0.15 29 * Force buffer_size / period_size == INTEGER. 30 * 0.16 31 * Update p16v.c to work with changed alsa api. 32 * 0.17 33 * Update p16v.c to work with changed alsa api. Removed boot_devs. 34 * 0.18 35 * Merging with snd-emu10k1 driver. 36 * 0.19 37 * One stereo channel at 24bit now works. 38 * 0.20 39 * Added better register defines. 40 * 0.21 41 * Integrated with snd-emu10k1 driver. 42 * 0.22 43 * Removed #if 0 ... #endif 44 * 0.23 45 * Implement different capture rates. 46 * 0.24 47 * Implement different capture source channels. 48 * e.g. When HD Capture source is set to SPDIF, 49 * setting HD Capture channel to 0 captures from CDROM digital input. 50 * setting HD Capture channel to 1 captures from SPDIF in. 51 * 0.25 52 * Include capture buffer sizes. 53 * 54 * BUGS: 55 * Some stability problems when unloading the snd-p16v kernel module. 56 * -- 57 * 58 * TODO: 59 * SPDIF out. 60 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz. 61 * Currently capture fixed at 48000Hz. 62 * 63 * -- 64 * GENERAL INFO: 65 * Model: SB0240 66 * P16V Chip: CA0151-DBS 67 * Audigy 2 Chip: CA0102-IAT 68 * AC97 Codec: STAC 9721 69 * ADC: Philips 1361T (Stereo 24bit) 70 * DAC: CS4382-K (8-channel, 24bit, 192Khz) 71 * 72 * This code was initally based on code from ALSA's emu10k1x.c which is: 73 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> 74 * 75 * This program is free software; you can redistribute it and/or modify 76 * it under the terms of the GNU General Public License as published by 77 * the Free Software Foundation; either version 2 of the License, or 78 * (at your option) any later version. 79 * 80 * This program is distributed in the hope that it will be useful, 81 * but WITHOUT ANY WARRANTY; without even the implied warranty of 82 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 83 * GNU General Public License for more details. 84 * 85 * You should have received a copy of the GNU General Public License 86 * along with this program; if not, write to the Free Software 87 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 88 * 89 */ 90 #include <sound/driver.h> 91 #include <linux/delay.h> 92 #include <linux/init.h> 93 #include <linux/interrupt.h> 94 #include <linux/pci.h> 95 #include <linux/slab.h> 96 #include <linux/moduleparam.h> 97 #include <sound/core.h> 98 #include <sound/initval.h> 99 #include <sound/pcm.h> 100 #include <sound/ac97_codec.h> 101 #include <sound/info.h> 102 #include <sound/emu10k1.h> 103 #include "p16v.h" 104 105 #define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */ 106 #define PCM_FRONT_CHANNEL 0 107 #define PCM_REAR_CHANNEL 1 108 #define PCM_CENTER_LFE_CHANNEL 2 109 #define PCM_UNKNOWN_CHANNEL 3 110 #define CONTROL_FRONT_CHANNEL 0 111 #define CONTROL_REAR_CHANNEL 3 112 #define CONTROL_CENTER_LFE_CHANNEL 1 113 #define CONTROL_UNKNOWN_CHANNEL 2 114 115 /* Card IDs: 116 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350 117 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1 Model:SB0240 118 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum Model:SB msb0240230009266 119 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E 120 * 121 */ 122 123 /* hardware definition */ 124 static snd_pcm_hardware_t snd_p16v_playback_hw = { 125 .info = (SNDRV_PCM_INFO_MMAP | 126 SNDRV_PCM_INFO_INTERLEAVED | 127 SNDRV_PCM_INFO_BLOCK_TRANSFER | 128 SNDRV_PCM_INFO_MMAP_VALID), 129 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ 130 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 131 .rate_min = 44100, 132 .rate_max = 192000, 133 .channels_min = 8, 134 .channels_max = 8, 135 .buffer_bytes_max = ((65536 - 64) * 8), 136 .period_bytes_min = 64, 137 .period_bytes_max = (65536 - 64), 138 .periods_min = 2, 139 .periods_max = 8, 140 .fifo_size = 0, 141 }; 142 143 static snd_pcm_hardware_t snd_p16v_capture_hw = { 144 .info = (SNDRV_PCM_INFO_MMAP | 145 SNDRV_PCM_INFO_INTERLEAVED | 146 SNDRV_PCM_INFO_BLOCK_TRANSFER | 147 SNDRV_PCM_INFO_MMAP_VALID), 148 .formats = SNDRV_PCM_FMTBIT_S32_LE, 149 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 150 .rate_min = 44100, 151 .rate_max = 192000, 152 .channels_min = 2, 153 .channels_max = 2, 154 .buffer_bytes_max = (65536 - 64), 155 .period_bytes_min = 64, 156 .period_bytes_max = (65536 - 128) >> 1, /* size has to be N*64 bytes */ 157 .periods_min = 2, 158 .periods_max = 2, 159 .fifo_size = 0, 160 }; 161 162 static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime) 163 { 164 emu10k1_pcm_t *epcm = runtime->private_data; 165 166 if (epcm) { 167 //snd_printk("epcm free: %p\n", epcm); 168 kfree(epcm); 169 } 170 } 171 172 /* open_playback callback */ 173 static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id) 174 { 175 emu10k1_t *emu = snd_pcm_substream_chip(substream); 176 emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]); 177 emu10k1_pcm_t *epcm; 178 snd_pcm_runtime_t *runtime = substream->runtime; 179 int err; 180 181 epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); 182 //snd_printk("epcm kcalloc: %p\n", epcm); 183 184 if (epcm == NULL) 185 return -ENOMEM; 186 epcm->emu = emu; 187 epcm->substream = substream; 188 //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); 189 190 runtime->private_data = epcm; 191 runtime->private_free = snd_p16v_pcm_free_substream; 192 193 runtime->hw = snd_p16v_playback_hw; 194 195 channel->emu = emu; 196 channel->number = channel_id; 197 198 channel->use=1; 199 //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use); 200 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); 201 //channel->interrupt = snd_p16v_pcm_channel_interrupt; 202 channel->epcm=epcm; 203 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 204 return err; 205 206 return 0; 207 } 208 /* open_capture callback */ 209 static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id) 210 { 211 emu10k1_t *emu = snd_pcm_substream_chip(substream); 212 emu10k1_voice_t *channel = &(emu->p16v_capture_voice); 213 emu10k1_pcm_t *epcm; 214 snd_pcm_runtime_t *runtime = substream->runtime; 215 int err; 216 217 epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); 218 //snd_printk("epcm kcalloc: %p\n", epcm); 219 220 if (epcm == NULL) 221 return -ENOMEM; 222 epcm->emu = emu; 223 epcm->substream = substream; 224 //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id); 225 226 runtime->private_data = epcm; 227 runtime->private_free = snd_p16v_pcm_free_substream; 228 229 runtime->hw = snd_p16v_capture_hw; 230 231 channel->emu = emu; 232 channel->number = channel_id; 233 234 channel->use=1; 235 //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use); 236 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel); 237 //channel->interrupt = snd_p16v_pcm_channel_interrupt; 238 channel->epcm=epcm; 239 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 240 return err; 241 242 return 0; 243 } 244 245 246 /* close callback */ 247 static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream) 248 { 249 emu10k1_t *emu = snd_pcm_substream_chip(substream); 250 //snd_pcm_runtime_t *runtime = substream->runtime; 251 //emu10k1_pcm_t *epcm = runtime->private_data; 252 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; 253 /* FIXME: maybe zero others */ 254 return 0; 255 } 256 257 /* close callback */ 258 static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream) 259 { 260 emu10k1_t *emu = snd_pcm_substream_chip(substream); 261 //snd_pcm_runtime_t *runtime = substream->runtime; 262 //emu10k1_pcm_t *epcm = runtime->private_data; 263 emu->p16v_capture_voice.use=0; 264 /* FIXME: maybe zero others */ 265 return 0; 266 } 267 268 static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream) 269 { 270 return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL); 271 } 272 273 static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream) 274 { 275 // Only using channel 0 for now, but the card has 2 channels. 276 return snd_p16v_pcm_open_capture_channel(substream, 0); 277 } 278 279 /* hw_params callback */ 280 static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream, 281 snd_pcm_hw_params_t * hw_params) 282 { 283 int result; 284 result = snd_pcm_lib_malloc_pages(substream, 285 params_buffer_bytes(hw_params)); 286 return result; 287 } 288 289 /* hw_params callback */ 290 static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream, 291 snd_pcm_hw_params_t * hw_params) 292 { 293 int result; 294 result = snd_pcm_lib_malloc_pages(substream, 295 params_buffer_bytes(hw_params)); 296 return result; 297 } 298 299 300 /* hw_free callback */ 301 static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream) 302 { 303 int result; 304 result = snd_pcm_lib_free_pages(substream); 305 return result; 306 } 307 308 /* hw_free callback */ 309 static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream) 310 { 311 int result; 312 result = snd_pcm_lib_free_pages(substream); 313 return result; 314 } 315 316 317 /* prepare playback callback */ 318 static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream) 319 { 320 emu10k1_t *emu = snd_pcm_substream_chip(substream); 321 snd_pcm_runtime_t *runtime = substream->runtime; 322 int channel = substream->pcm->device - emu->p16v_device_offset; 323 u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel)); 324 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); 325 int i; 326 u32 tmp; 327 328 //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1)); 329 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base); 330 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->p16v_buffer.addr, emu->p16v_buffer.area, emu->p16v_buffer.bytes); 331 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); 332 switch (runtime->rate) { 333 case 44100: 334 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080); 335 break; 336 case 96000: 337 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040); 338 break; 339 case 192000: 340 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020); 341 break; 342 case 48000: 343 default: 344 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000); 345 break; 346 } 347 /* FIXME: Check emu->buffer.size before actually writing to it. */ 348 for(i=0; i < runtime->periods; i++) { 349 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); 350 table_base[(i*2)+1]=period_size_bytes<<16; 351 } 352 353 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel)); 354 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19); 355 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0); 356 snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr); 357 //snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes 358 snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes 359 snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0); 360 snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0); 361 snd_emu10k1_ptr20_write(emu, 0x08, channel, 0); 362 363 return 0; 364 } 365 366 /* prepare capture callback */ 367 static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream) 368 { 369 emu10k1_t *emu = snd_pcm_substream_chip(substream); 370 snd_pcm_runtime_t *runtime = substream->runtime; 371 int channel = substream->pcm->device - emu->p16v_device_offset; 372 u32 tmp; 373 //printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, frames_to_bytes(runtime, 1)); 374 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); 375 switch (runtime->rate) { 376 case 44100: 377 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800); 378 break; 379 case 96000: 380 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400); 381 break; 382 case 192000: 383 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200); 384 break; 385 case 48000: 386 default: 387 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000); 388 break; 389 } 390 /* FIXME: Check emu->buffer.size before actually writing to it. */ 391 snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); 392 snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); 393 snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes 394 snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); 395 //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ 396 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); 397 398 return 0; 399 } 400 401 static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb) 402 { 403 unsigned long flags; 404 unsigned int enable; 405 406 spin_lock_irqsave(&emu->emu_lock, flags); 407 enable = inl(emu->port + INTE2) | intrenb; 408 outl(enable, emu->port + INTE2); 409 spin_unlock_irqrestore(&emu->emu_lock, flags); 410 } 411 412 static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb) 413 { 414 unsigned long flags; 415 unsigned int disable; 416 417 spin_lock_irqsave(&emu->emu_lock, flags); 418 disable = inl(emu->port + INTE2) & (~intrenb); 419 outl(disable, emu->port + INTE2); 420 spin_unlock_irqrestore(&emu->emu_lock, flags); 421 } 422 423 /* trigger_playback callback */ 424 static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream, 425 int cmd) 426 { 427 emu10k1_t *emu = snd_pcm_substream_chip(substream); 428 snd_pcm_runtime_t *runtime; 429 emu10k1_pcm_t *epcm; 430 int channel; 431 int result = 0; 432 struct list_head *pos; 433 snd_pcm_substream_t *s; 434 u32 basic = 0; 435 u32 inte = 0; 436 int running=0; 437 438 switch (cmd) { 439 case SNDRV_PCM_TRIGGER_START: 440 running=1; 441 break; 442 case SNDRV_PCM_TRIGGER_STOP: 443 default: 444 running=0; 445 break; 446 } 447 snd_pcm_group_for_each(pos, substream) { 448 s = snd_pcm_group_substream_entry(pos); 449 runtime = s->runtime; 450 epcm = runtime->private_data; 451 channel = substream->pcm->device-emu->p16v_device_offset; 452 //snd_printk("p16v channel=%d\n",channel); 453 epcm->running = running; 454 basic |= (0x1<<channel); 455 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel); 456 snd_pcm_trigger_done(s, substream); 457 } 458 //snd_printk("basic=0x%x, inte=0x%x\n",basic, inte); 459 460 switch (cmd) { 461 case SNDRV_PCM_TRIGGER_START: 462 snd_p16v_intr_enable(emu, inte); 463 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic)); 464 break; 465 case SNDRV_PCM_TRIGGER_STOP: 466 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic)); 467 snd_p16v_intr_disable(emu, inte); 468 break; 469 default: 470 result = -EINVAL; 471 break; 472 } 473 return result; 474 } 475 476 /* trigger_capture callback */ 477 static int snd_p16v_pcm_trigger_capture(snd_pcm_substream_t *substream, 478 int cmd) 479 { 480 emu10k1_t *emu = snd_pcm_substream_chip(substream); 481 snd_pcm_runtime_t *runtime = substream->runtime; 482 emu10k1_pcm_t *epcm = runtime->private_data; 483 int channel = 0; 484 int result = 0; 485 u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP; 486 487 switch (cmd) { 488 case SNDRV_PCM_TRIGGER_START: 489 snd_p16v_intr_enable(emu, inte); 490 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel)); 491 epcm->running = 1; 492 break; 493 case SNDRV_PCM_TRIGGER_STOP: 494 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel)); 495 snd_p16v_intr_disable(emu, inte); 496 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel)); 497 epcm->running = 0; 498 break; 499 default: 500 result = -EINVAL; 501 break; 502 } 503 return result; 504 } 505 506 /* pointer_playback callback */ 507 static snd_pcm_uframes_t 508 snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream) 509 { 510 emu10k1_t *emu = snd_pcm_substream_chip(substream); 511 snd_pcm_runtime_t *runtime = substream->runtime; 512 emu10k1_pcm_t *epcm = runtime->private_data; 513 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; 514 int channel = substream->pcm->device - emu->p16v_device_offset; 515 if (!epcm->running) 516 return 0; 517 518 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel); 519 ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel); 520 ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel); 521 if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel); 522 ptr2 = bytes_to_frames(runtime, ptr1); 523 ptr2+= (ptr4 >> 3) * runtime->period_size; 524 ptr=ptr2; 525 if (ptr >= runtime->buffer_size) 526 ptr -= runtime->buffer_size; 527 528 return ptr; 529 } 530 531 /* pointer_capture callback */ 532 static snd_pcm_uframes_t 533 snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream) 534 { 535 emu10k1_t *emu = snd_pcm_substream_chip(substream); 536 snd_pcm_runtime_t *runtime = substream->runtime; 537 emu10k1_pcm_t *epcm = runtime->private_data; 538 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; 539 int channel = 0; 540 541 if (!epcm->running) 542 return 0; 543 544 ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel); 545 ptr2 = bytes_to_frames(runtime, ptr1); 546 ptr=ptr2; 547 if (ptr >= runtime->buffer_size) { 548 ptr -= runtime->buffer_size; 549 printk("buffer capture limited!\n"); 550 } 551 //printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate); 552 553 return ptr; 554 } 555 556 /* operators */ 557 static snd_pcm_ops_t snd_p16v_playback_front_ops = { 558 .open = snd_p16v_pcm_open_playback_front, 559 .close = snd_p16v_pcm_close_playback, 560 .ioctl = snd_pcm_lib_ioctl, 561 .hw_params = snd_p16v_pcm_hw_params_playback, 562 .hw_free = snd_p16v_pcm_hw_free_playback, 563 .prepare = snd_p16v_pcm_prepare_playback, 564 .trigger = snd_p16v_pcm_trigger_playback, 565 .pointer = snd_p16v_pcm_pointer_playback, 566 }; 567 568 static snd_pcm_ops_t snd_p16v_capture_ops = { 569 .open = snd_p16v_pcm_open_capture, 570 .close = snd_p16v_pcm_close_capture, 571 .ioctl = snd_pcm_lib_ioctl, 572 .hw_params = snd_p16v_pcm_hw_params_capture, 573 .hw_free = snd_p16v_pcm_hw_free_capture, 574 .prepare = snd_p16v_pcm_prepare_capture, 575 .trigger = snd_p16v_pcm_trigger_capture, 576 .pointer = snd_p16v_pcm_pointer_capture, 577 }; 578 579 580 int snd_p16v_free(emu10k1_t *chip) 581 { 582 // release the data 583 if (chip->p16v_buffer.area) { 584 snd_dma_free_pages(&chip->p16v_buffer); 585 //snd_printk("period lables free: %p\n", &chip->p16v_buffer); 586 } 587 return 0; 588 } 589 590 static void snd_p16v_pcm_free(snd_pcm_t *pcm) 591 { 592 emu10k1_t *emu = pcm->private_data; 593 //snd_printk("snd_p16v_pcm_free pcm: called\n"); 594 snd_pcm_lib_preallocate_free_for_all(pcm); 595 emu->pcm = NULL; 596 } 597 598 int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm) 599 { 600 snd_pcm_t *pcm; 601 snd_pcm_substream_t *substream; 602 int err; 603 int capture=1; 604 605 //snd_printk("snd_p16v_pcm called. device=%d\n", device); 606 emu->p16v_device_offset = device; 607 if (rpcm) 608 *rpcm = NULL; 609 610 if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) 611 return err; 612 613 pcm->private_data = emu; 614 pcm->private_free = snd_p16v_pcm_free; 615 // Single playback 8 channel device. 616 // Single capture 2 channel device. 617 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops); 618 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops); 619 620 pcm->info_flags = 0; 621 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 622 strcpy(pcm->name, "p16v"); 623 emu->pcm = pcm; 624 625 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 626 substream; 627 substream = substream->next) { 628 if ((err = snd_pcm_lib_preallocate_pages(substream, 629 SNDRV_DMA_TYPE_DEV, 630 snd_dma_pci_data(emu->pci), 631 ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) 632 return err; 633 //snd_printk("preallocate playback substream: err=%d\n", err); 634 } 635 636 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; 637 substream; 638 substream = substream->next) { 639 if ((err = snd_pcm_lib_preallocate_pages(substream, 640 SNDRV_DMA_TYPE_DEV, 641 snd_dma_pci_data(emu->pci), 642 65536 - 64, 65536 - 64)) < 0) 643 return err; 644 //snd_printk("preallocate capture substream: err=%d\n", err); 645 } 646 647 if (rpcm) 648 *rpcm = pcm; 649 650 return 0; 651 } 652 653 static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 654 { 655 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 656 uinfo->count = 2; 657 uinfo->value.integer.min = 0; 658 uinfo->value.integer.max = 255; 659 return 0; 660 } 661 662 static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol, 663 snd_ctl_elem_value_t * ucontrol, int reg, int high_low) 664 { 665 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 666 u32 value; 667 668 value = snd_emu10k1_ptr20_read(emu, reg, high_low); 669 if (high_low == 1) { 670 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */ 671 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */ 672 } else { 673 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */ 674 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */ 675 } 676 return 0; 677 } 678 679 static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol, 680 snd_ctl_elem_value_t * ucontrol) 681 { 682 int high_low = 0; 683 int reg = PLAYBACK_VOLUME_MIXER7; 684 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 685 } 686 687 static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol, 688 snd_ctl_elem_value_t * ucontrol) 689 { 690 int high_low = 1; 691 int reg = PLAYBACK_VOLUME_MIXER7; 692 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 693 } 694 static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol, 695 snd_ctl_elem_value_t * ucontrol) 696 { 697 int high_low = 0; 698 int reg = PLAYBACK_VOLUME_MIXER8; 699 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 700 } 701 static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol, 702 snd_ctl_elem_value_t * ucontrol) 703 { 704 int high_low = 1; 705 int reg = PLAYBACK_VOLUME_MIXER8; 706 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 707 } 708 709 static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol, 710 snd_ctl_elem_value_t * ucontrol) 711 { 712 int high_low = 0; 713 int reg = PLAYBACK_VOLUME_MIXER9; 714 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 715 } 716 717 static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol, 718 snd_ctl_elem_value_t * ucontrol) 719 { 720 int high_low = 1; 721 int reg = PLAYBACK_VOLUME_MIXER9; 722 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 723 } 724 static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol, 725 snd_ctl_elem_value_t * ucontrol) 726 { 727 int high_low = 1; 728 int reg = PLAYBACK_VOLUME_MIXER10; 729 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 730 } 731 732 static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol, 733 snd_ctl_elem_value_t * ucontrol) 734 { 735 int high_low = 0; 736 int reg = PLAYBACK_VOLUME_MIXER10; 737 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low); 738 } 739 740 static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol, 741 snd_ctl_elem_value_t * ucontrol, int reg, int high_low) 742 { 743 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 744 u32 value; 745 value = snd_emu10k1_ptr20_read(emu, reg, 0); 746 //value = value & 0xffff; 747 if (high_low == 1) { 748 value &= 0xffff; 749 value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16); 750 } else { 751 value &= 0xffff0000; 752 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) ); 753 } 754 snd_emu10k1_ptr20_write(emu, reg, 0, value); 755 return 1; 756 } 757 758 static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol, 759 snd_ctl_elem_value_t * ucontrol) 760 { 761 int high_low = 0; 762 int reg = PLAYBACK_VOLUME_MIXER7; 763 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 764 } 765 766 static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol, 767 snd_ctl_elem_value_t * ucontrol) 768 { 769 int high_low = 1; 770 int reg = PLAYBACK_VOLUME_MIXER7; 771 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 772 } 773 774 static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol, 775 snd_ctl_elem_value_t * ucontrol) 776 { 777 int high_low = 0; 778 int reg = PLAYBACK_VOLUME_MIXER8; 779 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 780 } 781 782 static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol, 783 snd_ctl_elem_value_t * ucontrol) 784 { 785 int high_low = 1; 786 int reg = PLAYBACK_VOLUME_MIXER8; 787 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 788 } 789 790 static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol, 791 snd_ctl_elem_value_t * ucontrol) 792 { 793 int high_low = 0; 794 int reg = PLAYBACK_VOLUME_MIXER9; 795 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 796 } 797 798 static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol, 799 snd_ctl_elem_value_t * ucontrol) 800 { 801 int high_low = 1; 802 int reg = PLAYBACK_VOLUME_MIXER9; 803 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 804 } 805 806 static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol, 807 snd_ctl_elem_value_t * ucontrol) 808 { 809 int high_low = 1; 810 int reg = PLAYBACK_VOLUME_MIXER10; 811 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 812 } 813 814 static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol, 815 snd_ctl_elem_value_t * ucontrol) 816 { 817 int high_low = 0; 818 int reg = PLAYBACK_VOLUME_MIXER10; 819 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low); 820 } 821 822 static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = 823 { 824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 825 .name = "HD Analog Front Playback Volume", 826 .info = snd_p16v_volume_info, 827 .get = snd_p16v_volume_get_analog_front, 828 .put = snd_p16v_volume_put_analog_front 829 }; 830 831 static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = 832 { 833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 834 .name = "HD Analog Center/LFE Playback Volume", 835 .info = snd_p16v_volume_info, 836 .get = snd_p16v_volume_get_analog_center_lfe, 837 .put = snd_p16v_volume_put_analog_center_lfe 838 }; 839 840 static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = 841 { 842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 843 .name = "HD Analog Unknown Playback Volume", 844 .info = snd_p16v_volume_info, 845 .get = snd_p16v_volume_get_analog_unknown, 846 .put = snd_p16v_volume_put_analog_unknown 847 }; 848 849 static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = 850 { 851 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 852 .name = "HD Analog Rear Playback Volume", 853 .info = snd_p16v_volume_info, 854 .get = snd_p16v_volume_get_analog_rear, 855 .put = snd_p16v_volume_put_analog_rear 856 }; 857 858 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = 859 { 860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 861 .name = "HD SPDIF Front Playback Volume", 862 .info = snd_p16v_volume_info, 863 .get = snd_p16v_volume_get_spdif_front, 864 .put = snd_p16v_volume_put_spdif_front 865 }; 866 867 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = 868 { 869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 870 .name = "HD SPDIF Center/LFE Playback Volume", 871 .info = snd_p16v_volume_info, 872 .get = snd_p16v_volume_get_spdif_center_lfe, 873 .put = snd_p16v_volume_put_spdif_center_lfe 874 }; 875 876 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = 877 { 878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 879 .name = "HD SPDIF Unknown Playback Volume", 880 .info = snd_p16v_volume_info, 881 .get = snd_p16v_volume_get_spdif_unknown, 882 .put = snd_p16v_volume_put_spdif_unknown 883 }; 884 885 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = 886 { 887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 888 .name = "HD SPDIF Rear Playback Volume", 889 .info = snd_p16v_volume_info, 890 .get = snd_p16v_volume_get_spdif_rear, 891 .put = snd_p16v_volume_put_spdif_rear 892 }; 893 894 static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 895 { 896 static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" }; 897 898 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 899 uinfo->count = 1; 900 uinfo->value.enumerated.items = 8; 901 if (uinfo->value.enumerated.item > 7) 902 uinfo->value.enumerated.item = 7; 903 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 904 return 0; 905 } 906 907 static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol, 908 snd_ctl_elem_value_t * ucontrol) 909 { 910 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 911 912 ucontrol->value.enumerated.item[0] = emu->p16v_capture_source; 913 return 0; 914 } 915 916 static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol, 917 snd_ctl_elem_value_t * ucontrol) 918 { 919 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 920 unsigned int val; 921 int change = 0; 922 u32 mask; 923 u32 source; 924 925 val = ucontrol->value.enumerated.item[0] ; 926 change = (emu->p16v_capture_source != val); 927 if (change) { 928 emu->p16v_capture_source = val; 929 source = (val << 28) | (val << 24) | (val << 20) | (val << 16); 930 mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff; 931 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask); 932 } 933 return change; 934 } 935 936 static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = 937 { 938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 939 .name = "HD source Capture", 940 .info = snd_p16v_capture_source_info, 941 .get = snd_p16v_capture_source_get, 942 .put = snd_p16v_capture_source_put 943 }; 944 945 static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) 946 { 947 static char *texts[4] = { "0", "1", "2", "3", }; 948 949 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 950 uinfo->count = 1; 951 uinfo->value.enumerated.items = 4; 952 if (uinfo->value.enumerated.item > 3) 953 uinfo->value.enumerated.item = 3; 954 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 955 return 0; 956 } 957 958 static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol, 959 snd_ctl_elem_value_t * ucontrol) 960 { 961 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 962 963 ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel; 964 return 0; 965 } 966 967 static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol, 968 snd_ctl_elem_value_t * ucontrol) 969 { 970 emu10k1_t *emu = snd_kcontrol_chip(kcontrol); 971 unsigned int val; 972 int change = 0; 973 u32 tmp; 974 975 val = ucontrol->value.enumerated.item[0] ; 976 change = (emu->p16v_capture_channel != val); 977 if (change) { 978 emu->p16v_capture_channel = val; 979 tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc; 980 snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val); 981 } 982 return change; 983 } 984 985 static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = 986 { 987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 988 .name = "HD channel Capture", 989 .info = snd_p16v_capture_channel_info, 990 .get = snd_p16v_capture_channel_get, 991 .put = snd_p16v_capture_channel_put 992 }; 993 994 int snd_p16v_mixer(emu10k1_t *emu) 995 { 996 int err; 997 snd_kcontrol_t *kctl; 998 snd_card_t *card = emu->card; 999 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL) 1000 return -ENOMEM; 1001 if ((err = snd_ctl_add(card, kctl))) 1002 return err; 1003 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL) 1004 return -ENOMEM; 1005 if ((err = snd_ctl_add(card, kctl))) 1006 return err; 1007 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL) 1008 return -ENOMEM; 1009 if ((err = snd_ctl_add(card, kctl))) 1010 return err; 1011 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL) 1012 return -ENOMEM; 1013 if ((err = snd_ctl_add(card, kctl))) 1014 return err; 1015 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL) 1016 return -ENOMEM; 1017 if ((err = snd_ctl_add(card, kctl))) 1018 return err; 1019 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL) 1020 return -ENOMEM; 1021 if ((err = snd_ctl_add(card, kctl))) 1022 return err; 1023 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL) 1024 return -ENOMEM; 1025 if ((err = snd_ctl_add(card, kctl))) 1026 return err; 1027 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL) 1028 return -ENOMEM; 1029 if ((err = snd_ctl_add(card, kctl))) 1030 return err; 1031 if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL) 1032 return -ENOMEM; 1033 if ((err = snd_ctl_add(card, kctl))) 1034 return err; 1035 if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL) 1036 return -ENOMEM; 1037 if ((err = snd_ctl_add(card, kctl))) 1038 return err; 1039 return 0; 1040 } 1041 1042