1/* 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 3 * Routines for control of ESS ES1688/688/488 chip 4 * 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21 22#include <sound/driver.h> 23#include <linux/init.h> 24#include <linux/interrupt.h> 25#include <linux/delay.h> 26#include <linux/slab.h> 27#include <linux/ioport.h> 28#include <sound/core.h> 29#include <sound/es1688.h> 30#include <sound/initval.h> 31 32#include <asm/io.h> 33#include <asm/dma.h> 34 35MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); 36MODULE_DESCRIPTION("ESS ESx688 lowlevel module"); 37MODULE_LICENSE("GPL"); 38 39static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val) 40{ 41 int i; 42 43 for (i = 10000; i; i--) 44 if ((inb(ES1688P(chip, STATUS)) & 0x80) == 0) { 45 outb(val, ES1688P(chip, COMMAND)); 46 return 1; 47 } 48#ifdef CONFIG_SND_DEBUG 49 printk("snd_es1688_dsp_command: timeout (0x%x)\n", val); 50#endif 51 return 0; 52} 53 54static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip) 55{ 56 int i; 57 58 for (i = 1000; i; i--) 59 if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) 60 return inb(ES1688P(chip, READ)); 61 snd_printd("es1688 get byte failed: 0x%lx = 0x%x!!!\n", ES1688P(chip, DATA_AVAIL), inb(ES1688P(chip, DATA_AVAIL))); 62 return -ENODEV; 63} 64 65static int snd_es1688_write(struct snd_es1688 *chip, 66 unsigned char reg, unsigned char data) 67{ 68 if (!snd_es1688_dsp_command(chip, reg)) 69 return 0; 70 return snd_es1688_dsp_command(chip, data); 71} 72 73static int snd_es1688_read(struct snd_es1688 *chip, unsigned char reg) 74{ 75 /* Read a byte from an extended mode register of ES1688 */ 76 if (!snd_es1688_dsp_command(chip, 0xc0)) 77 return -1; 78 if (!snd_es1688_dsp_command(chip, reg)) 79 return -1; 80 return snd_es1688_dsp_get_byte(chip); 81} 82 83void snd_es1688_mixer_write(struct snd_es1688 *chip, 84 unsigned char reg, unsigned char data) 85{ 86 outb(reg, ES1688P(chip, MIXER_ADDR)); 87 udelay(10); 88 outb(data, ES1688P(chip, MIXER_DATA)); 89 udelay(10); 90} 91 92static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned char reg) 93{ 94 unsigned char result; 95 96 outb(reg, ES1688P(chip, MIXER_ADDR)); 97 udelay(10); 98 result = inb(ES1688P(chip, MIXER_DATA)); 99 udelay(10); 100 return result; 101} 102 103static int snd_es1688_reset(struct snd_es1688 *chip) 104{ 105 int i; 106 107 outb(3, ES1688P(chip, RESET)); /* valid only for ESS chips, SB -> 1 */ 108 udelay(10); 109 outb(0, ES1688P(chip, RESET)); 110 udelay(30); 111 for (i = 0; i < 1000 && !(inb(ES1688P(chip, DATA_AVAIL)) & 0x80); i++); 112 if (inb(ES1688P(chip, READ)) != 0xaa) { 113 snd_printd("ess_reset at 0x%lx: failed!!!\n", chip->port); 114 return -ENODEV; 115 } 116 snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ 117 return 0; 118} 119 120static int snd_es1688_probe(struct snd_es1688 *chip) 121{ 122 unsigned long flags; 123 unsigned short major, minor, hw; 124 int i; 125 126 /* 127 * initialization sequence 128 */ 129 130 spin_lock_irqsave(&chip->reg_lock, flags); /* Some ESS1688 cards need this */ 131 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 132 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 133 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 134 inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */ 135 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 136 inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */ 137 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 138 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 139 inb(ES1688P(chip, ENABLE2)); /* ENABLE2 */ 140 inb(ES1688P(chip, ENABLE1)); /* ENABLE1 */ 141 inb(ES1688P(chip, ENABLE0)); /* ENABLE0 */ 142 143 if (snd_es1688_reset(chip) < 0) { 144 snd_printdd("ESS: [0x%lx] reset failed... 0x%x\n", chip->port, inb(ES1688P(chip, READ))); 145 spin_unlock_irqrestore(&chip->reg_lock, flags); 146 return -ENODEV; 147 } 148 snd_es1688_dsp_command(chip, 0xe7); /* return identification */ 149 150 for (i = 1000, major = minor = 0; i; i--) { 151 if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) { 152 if (major == 0) { 153 major = inb(ES1688P(chip, READ)); 154 } else { 155 minor = inb(ES1688P(chip, READ)); 156 } 157 } 158 } 159 160 spin_unlock_irqrestore(&chip->reg_lock, flags); 161 162 snd_printdd("ESS: [0x%lx] found.. major = 0x%x, minor = 0x%x\n", chip->port, major, minor); 163 164 chip->version = (major << 8) | minor; 165 if (!chip->version) 166 return -ENODEV; /* probably SB */ 167 168 hw = ES1688_HW_AUTO; 169 switch (chip->version & 0xfff0) { 170 case 0x4880: 171 snd_printk("[0x%lx] ESS: AudioDrive ES488 detected, but driver is in another place\n", chip->port); 172 return -ENODEV; 173 case 0x6880: 174 hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688; 175 break; 176 default: 177 snd_printk("[0x%lx] ESS: unknown AudioDrive chip with version 0x%x (Jazz16 soundcard?)\n", chip->port, chip->version); 178 return -ENODEV; 179 } 180 181 spin_lock_irqsave(&chip->reg_lock, flags); 182 snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */ 183 snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */ 184 spin_unlock_irqrestore(&chip->reg_lock, flags); 185 186 /* enable joystick, but disable OPL3 */ 187 spin_lock_irqsave(&chip->mixer_lock, flags); 188 snd_es1688_mixer_write(chip, 0x40, 0x01); 189 spin_unlock_irqrestore(&chip->mixer_lock, flags); 190 191 return 0; 192} 193 194static int snd_es1688_init(struct snd_es1688 * chip, int enable) 195{ 196 static int irqs[16] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, 0, 3, -1, -1, -1, -1, -1}; 197 unsigned long flags; 198 int cfg, irq_bits, dma, dma_bits, tmp, tmp1; 199 200 /* ok.. setup MPU-401 port and joystick and OPL3 */ 201 cfg = 0x01; /* enable joystick, but disable OPL3 */ 202 if (enable && chip->mpu_port >= 0x300 && chip->mpu_irq > 0 && chip->hardware != ES1688_HW_688) { 203 tmp = (chip->mpu_port & 0x0f0) >> 4; 204 if (tmp <= 3) { 205 switch (chip->mpu_irq) { 206 case 9: 207 tmp1 = 4; 208 break; 209 case 5: 210 tmp1 = 5; 211 break; 212 case 7: 213 tmp1 = 6; 214 break; 215 case 10: 216 tmp1 = 7; 217 break; 218 default: 219 tmp1 = 0; 220 } 221 if (tmp1) { 222 cfg |= (tmp << 3) | (tmp1 << 5); 223 } 224 } 225 } 226 spin_lock_irqsave(&chip->reg_lock, flags); 227 snd_es1688_mixer_write(chip, 0x40, cfg); 228 spin_unlock_irqrestore(&chip->reg_lock, flags); 229 /* --- */ 230 spin_lock_irqsave(&chip->reg_lock, flags); 231 snd_es1688_read(chip, 0xb1); 232 snd_es1688_read(chip, 0xb2); 233 spin_unlock_irqrestore(&chip->reg_lock, flags); 234 if (enable) { 235 cfg = 0xf0; /* enable only DMA counter interrupt */ 236 irq_bits = irqs[chip->irq & 0x0f]; 237 if (irq_bits < 0) { 238 snd_printk("[0x%lx] ESS: bad IRQ %d for ES1688 chip!!\n", chip->port, chip->irq); 239 return -EINVAL; 240 } 241 spin_lock_irqsave(&chip->reg_lock, flags); 242 snd_es1688_write(chip, 0xb1, cfg | (irq_bits << 2)); 243 spin_unlock_irqrestore(&chip->reg_lock, flags); 244 cfg = 0xf0; /* extended mode DMA enable */ 245 dma = chip->dma8; 246 if (dma > 3 || dma == 2) { 247 snd_printk("[0x%lx] ESS: bad DMA channel %d for ES1688 chip!!\n", chip->port, dma); 248 return -EINVAL; 249 } else { 250 dma_bits = dma; 251 if (dma != 3) 252 dma_bits++; 253 } 254 spin_lock_irqsave(&chip->reg_lock, flags); 255 snd_es1688_write(chip, 0xb2, cfg | (dma_bits << 2)); 256 spin_unlock_irqrestore(&chip->reg_lock, flags); 257 } else { 258 spin_lock_irqsave(&chip->reg_lock, flags); 259 snd_es1688_write(chip, 0xb1, 0x10); /* disable IRQ */ 260 snd_es1688_write(chip, 0xb2, 0x00); /* disable DMA */ 261 spin_unlock_irqrestore(&chip->reg_lock, flags); 262 } 263 spin_lock_irqsave(&chip->reg_lock, flags); 264 snd_es1688_read(chip, 0xb1); 265 snd_es1688_read(chip, 0xb2); 266 snd_es1688_reset(chip); 267 spin_unlock_irqrestore(&chip->reg_lock, flags); 268 return 0; 269} 270 271/* 272 273 */ 274 275static struct snd_ratnum clocks[2] = { 276 { 277 .num = 795444, 278 .den_min = 1, 279 .den_max = 128, 280 .den_step = 1, 281 }, 282 { 283 .num = 397722, 284 .den_min = 1, 285 .den_max = 128, 286 .den_step = 1, 287 } 288}; 289 290static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = { 291 .nrats = 2, 292 .rats = clocks, 293}; 294 295static void snd_es1688_set_rate(struct snd_es1688 *chip, struct snd_pcm_substream *substream) 296{ 297 struct snd_pcm_runtime *runtime = substream->runtime; 298 unsigned int bits, divider; 299 300 if (runtime->rate_num == clocks[0].num) 301 bits = 256 - runtime->rate_den; 302 else 303 bits = 128 - runtime->rate_den; 304 /* set filter register */ 305 divider = 256 - 7160000*20/(8*82*runtime->rate); 306 /* write result to hardware */ 307 snd_es1688_write(chip, 0xa1, bits); 308 snd_es1688_write(chip, 0xa2, divider); 309} 310 311static int snd_es1688_ioctl(struct snd_pcm_substream *substream, 312 unsigned int cmd, void *arg) 313{ 314 return snd_pcm_lib_ioctl(substream, cmd, arg); 315} 316 317static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char value) 318{ 319 int val; 320 321 if (cmd == SNDRV_PCM_TRIGGER_STOP) { 322 value = 0x00; 323 } else if (cmd != SNDRV_PCM_TRIGGER_START) { 324 return -EINVAL; 325 } 326 spin_lock(&chip->reg_lock); 327 chip->trigger_value = value; 328 val = snd_es1688_read(chip, 0xb8); 329 if ((val < 0) || (val & 0x0f) == value) { 330 spin_unlock(&chip->reg_lock); 331 return -EINVAL; /* something is wrong */ 332 } 333 snd_es1688_write(chip, 0xb8, (val & 0xf0) | value); 334 spin_unlock(&chip->reg_lock); 335 return 0; 336} 337 338static int snd_es1688_hw_params(struct snd_pcm_substream *substream, 339 struct snd_pcm_hw_params *hw_params) 340{ 341 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 342} 343 344static int snd_es1688_hw_free(struct snd_pcm_substream *substream) 345{ 346 return snd_pcm_lib_free_pages(substream); 347} 348 349static int snd_es1688_playback_prepare(struct snd_pcm_substream *substream) 350{ 351 unsigned long flags; 352 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 353 struct snd_pcm_runtime *runtime = substream->runtime; 354 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 355 unsigned int count = snd_pcm_lib_period_bytes(substream); 356 357 chip->dma_size = size; 358 spin_lock_irqsave(&chip->reg_lock, flags); 359 snd_es1688_reset(chip); 360 snd_es1688_set_rate(chip, substream); 361 snd_es1688_write(chip, 0xb8, 4); /* auto init DMA mode */ 362 snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels)); 363 snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */ 364 if (runtime->channels == 1) { 365 if (snd_pcm_format_width(runtime->format) == 8) { 366 /* 8. bit mono */ 367 snd_es1688_write(chip, 0xb6, 0x80); 368 snd_es1688_write(chip, 0xb7, 0x51); 369 snd_es1688_write(chip, 0xb7, 0xd0); 370 } else { 371 /* 16. bit mono */ 372 snd_es1688_write(chip, 0xb6, 0x00); 373 snd_es1688_write(chip, 0xb7, 0x71); 374 snd_es1688_write(chip, 0xb7, 0xf4); 375 } 376 } else { 377 if (snd_pcm_format_width(runtime->format) == 8) { 378 /* 8. bit stereo */ 379 snd_es1688_write(chip, 0xb6, 0x80); 380 snd_es1688_write(chip, 0xb7, 0x51); 381 snd_es1688_write(chip, 0xb7, 0x98); 382 } else { 383 /* 16. bit stereo */ 384 snd_es1688_write(chip, 0xb6, 0x00); 385 snd_es1688_write(chip, 0xb7, 0x71); 386 snd_es1688_write(chip, 0xb7, 0xbc); 387 } 388 } 389 snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50); 390 snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50); 391 snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON); 392 spin_unlock_irqrestore(&chip->reg_lock, flags); 393 /* --- */ 394 count = -count; 395 snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); 396 spin_lock_irqsave(&chip->reg_lock, flags); 397 snd_es1688_write(chip, 0xa4, (unsigned char) count); 398 snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8)); 399 spin_unlock_irqrestore(&chip->reg_lock, flags); 400 return 0; 401} 402 403static int snd_es1688_playback_trigger(struct snd_pcm_substream *substream, 404 int cmd) 405{ 406 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 407 return snd_es1688_trigger(chip, cmd, 0x05); 408} 409 410static int snd_es1688_capture_prepare(struct snd_pcm_substream *substream) 411{ 412 unsigned long flags; 413 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 414 struct snd_pcm_runtime *runtime = substream->runtime; 415 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 416 unsigned int count = snd_pcm_lib_period_bytes(substream); 417 418 chip->dma_size = size; 419 spin_lock_irqsave(&chip->reg_lock, flags); 420 snd_es1688_reset(chip); 421 snd_es1688_set_rate(chip, substream); 422 snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF); 423 snd_es1688_write(chip, 0xb8, 0x0e); /* auto init DMA mode */ 424 snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels)); 425 snd_es1688_write(chip, 0xb9, 2); /* demand mode (4 bytes/request) */ 426 if (runtime->channels == 1) { 427 if (snd_pcm_format_width(runtime->format) == 8) { 428 /* 8. bit mono */ 429 snd_es1688_write(chip, 0xb7, 0x51); 430 snd_es1688_write(chip, 0xb7, 0xd0); 431 } else { 432 /* 16. bit mono */ 433 snd_es1688_write(chip, 0xb7, 0x71); 434 snd_es1688_write(chip, 0xb7, 0xf4); 435 } 436 } else { 437 if (snd_pcm_format_width(runtime->format) == 8) { 438 /* 8. bit stereo */ 439 snd_es1688_write(chip, 0xb7, 0x51); 440 snd_es1688_write(chip, 0xb7, 0x98); 441 } else { 442 /* 16. bit stereo */ 443 snd_es1688_write(chip, 0xb7, 0x71); 444 snd_es1688_write(chip, 0xb7, 0xbc); 445 } 446 } 447 snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50); 448 snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50); 449 spin_unlock_irqrestore(&chip->reg_lock, flags); 450 /* --- */ 451 count = -count; 452 snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); 453 spin_lock_irqsave(&chip->reg_lock, flags); 454 snd_es1688_write(chip, 0xa4, (unsigned char) count); 455 snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8)); 456 spin_unlock_irqrestore(&chip->reg_lock, flags); 457 return 0; 458} 459 460static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream, 461 int cmd) 462{ 463 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 464 return snd_es1688_trigger(chip, cmd, 0x0f); 465} 466 467static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id) 468{ 469 struct snd_es1688 *chip = dev_id; 470 471 if (chip->trigger_value == 0x05) /* ok.. playback is active */ 472 snd_pcm_period_elapsed(chip->playback_substream); 473 if (chip->trigger_value == 0x0f) /* ok.. capture is active */ 474 snd_pcm_period_elapsed(chip->capture_substream); 475 476 inb(ES1688P(chip, DATA_AVAIL)); /* ack interrupt */ 477 return IRQ_HANDLED; 478} 479 480static snd_pcm_uframes_t snd_es1688_playback_pointer(struct snd_pcm_substream *substream) 481{ 482 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 483 size_t ptr; 484 485 if (chip->trigger_value != 0x05) 486 return 0; 487 ptr = snd_dma_pointer(chip->dma8, chip->dma_size); 488 return bytes_to_frames(substream->runtime, ptr); 489} 490 491static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *substream) 492{ 493 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 494 size_t ptr; 495 496 if (chip->trigger_value != 0x0f) 497 return 0; 498 ptr = snd_dma_pointer(chip->dma8, chip->dma_size); 499 return bytes_to_frames(substream->runtime, ptr); 500} 501 502/* 503 504 */ 505 506static struct snd_pcm_hardware snd_es1688_playback = 507{ 508 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 509 SNDRV_PCM_INFO_MMAP_VALID), 510 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 511 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 512 .rate_min = 4000, 513 .rate_max = 48000, 514 .channels_min = 1, 515 .channels_max = 2, 516 .buffer_bytes_max = 65536, 517 .period_bytes_min = 64, 518 .period_bytes_max = 65536, 519 .periods_min = 1, 520 .periods_max = 1024, 521 .fifo_size = 0, 522}; 523 524static struct snd_pcm_hardware snd_es1688_capture = 525{ 526 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 527 SNDRV_PCM_INFO_MMAP_VALID), 528 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, 529 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, 530 .rate_min = 4000, 531 .rate_max = 48000, 532 .channels_min = 1, 533 .channels_max = 2, 534 .buffer_bytes_max = 65536, 535 .period_bytes_min = 64, 536 .period_bytes_max = 65536, 537 .periods_min = 1, 538 .periods_max = 1024, 539 .fifo_size = 0, 540}; 541 542/* 543 544 */ 545 546static int snd_es1688_playback_open(struct snd_pcm_substream *substream) 547{ 548 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 549 struct snd_pcm_runtime *runtime = substream->runtime; 550 551 if (chip->capture_substream != NULL) 552 return -EAGAIN; 553 chip->playback_substream = substream; 554 runtime->hw = snd_es1688_playback; 555 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 556 &hw_constraints_clocks); 557 return 0; 558} 559 560static int snd_es1688_capture_open(struct snd_pcm_substream *substream) 561{ 562 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 563 struct snd_pcm_runtime *runtime = substream->runtime; 564 565 if (chip->playback_substream != NULL) 566 return -EAGAIN; 567 chip->capture_substream = substream; 568 runtime->hw = snd_es1688_capture; 569 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 570 &hw_constraints_clocks); 571 return 0; 572} 573 574static int snd_es1688_playback_close(struct snd_pcm_substream *substream) 575{ 576 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 577 578 chip->playback_substream = NULL; 579 return 0; 580} 581 582static int snd_es1688_capture_close(struct snd_pcm_substream *substream) 583{ 584 struct snd_es1688 *chip = snd_pcm_substream_chip(substream); 585 586 chip->capture_substream = NULL; 587 return 0; 588} 589 590static int snd_es1688_free(struct snd_es1688 *chip) 591{ 592 if (chip->res_port) { 593 snd_es1688_init(chip, 0); 594 release_and_free_resource(chip->res_port); 595 } 596 if (chip->irq >= 0) 597 free_irq(chip->irq, (void *) chip); 598 if (chip->dma8 >= 0) { 599 disable_dma(chip->dma8); 600 free_dma(chip->dma8); 601 } 602 kfree(chip); 603 return 0; 604} 605 606static int snd_es1688_dev_free(struct snd_device *device) 607{ 608 struct snd_es1688 *chip = device->device_data; 609 return snd_es1688_free(chip); 610} 611 612static const char *snd_es1688_chip_id(struct snd_es1688 *chip) 613{ 614 static char tmp[16]; 615 sprintf(tmp, "ES%s688 rev %i", chip->hardware == ES1688_HW_688 ? "" : "1", chip->version & 0x0f); 616 return tmp; 617} 618 619int snd_es1688_create(struct snd_card *card, 620 unsigned long port, 621 unsigned long mpu_port, 622 int irq, 623 int mpu_irq, 624 int dma8, 625 unsigned short hardware, 626 struct snd_es1688 **rchip) 627{ 628 static struct snd_device_ops ops = { 629 .dev_free = snd_es1688_dev_free, 630 }; 631 632 struct snd_es1688 *chip; 633 int err; 634 635 *rchip = NULL; 636 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 637 if (chip == NULL) 638 return -ENOMEM; 639 chip->irq = -1; 640 chip->dma8 = -1; 641 642 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 643 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 644 snd_es1688_free(chip); 645 return -EBUSY; 646 } 647 if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { 648 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 649 snd_es1688_free(chip); 650 return -EBUSY; 651 } 652 chip->irq = irq; 653 if (request_dma(dma8, "ES1688")) { 654 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 655 snd_es1688_free(chip); 656 return -EBUSY; 657 } 658 chip->dma8 = dma8; 659 660 spin_lock_init(&chip->reg_lock); 661 spin_lock_init(&chip->mixer_lock); 662 chip->card = card; 663 chip->port = port; 664 mpu_port &= ~0x000f; 665 if (mpu_port < 0x300 || mpu_port > 0x330) 666 mpu_port = 0; 667 chip->mpu_port = mpu_port; 668 chip->mpu_irq = mpu_irq; 669 chip->hardware = hardware; 670 671 if ((err = snd_es1688_probe(chip)) < 0) { 672 snd_es1688_free(chip); 673 return err; 674 } 675 if ((err = snd_es1688_init(chip, 1)) < 0) { 676 snd_es1688_free(chip); 677 return err; 678 } 679 680 /* Register device */ 681 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 682 snd_es1688_free(chip); 683 return err; 684 } 685 686 *rchip = chip; 687 return 0; 688} 689 690static struct snd_pcm_ops snd_es1688_playback_ops = { 691 .open = snd_es1688_playback_open, 692 .close = snd_es1688_playback_close, 693 .ioctl = snd_es1688_ioctl, 694 .hw_params = snd_es1688_hw_params, 695 .hw_free = snd_es1688_hw_free, 696 .prepare = snd_es1688_playback_prepare, 697 .trigger = snd_es1688_playback_trigger, 698 .pointer = snd_es1688_playback_pointer, 699}; 700 701static struct snd_pcm_ops snd_es1688_capture_ops = { 702 .open = snd_es1688_capture_open, 703 .close = snd_es1688_capture_close, 704 .ioctl = snd_es1688_ioctl, 705 .hw_params = snd_es1688_hw_params, 706 .hw_free = snd_es1688_hw_free, 707 .prepare = snd_es1688_capture_prepare, 708 .trigger = snd_es1688_capture_trigger, 709 .pointer = snd_es1688_capture_pointer, 710}; 711 712int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) 713{ 714 struct snd_pcm *pcm; 715 int err; 716 717 if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) 718 return err; 719 720 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); 721 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1688_capture_ops); 722 723 pcm->private_data = chip; 724 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 725 sprintf(pcm->name, snd_es1688_chip_id(chip)); 726 chip->pcm = pcm; 727 728 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 729 snd_dma_isa_data(), 730 64*1024, 64*1024); 731 732 if (rpcm) 733 *rpcm = pcm; 734 return 0; 735} 736 737/* 738 * MIXER part 739 */ 740 741static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 742{ 743 static char *texts[9] = { 744 "Mic", "Mic Master", "CD", "AOUT", 745 "Mic1", "Mix", "Line", "Master" 746 }; 747 748 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 749 uinfo->count = 1; 750 uinfo->value.enumerated.items = 8; 751 if (uinfo->value.enumerated.item > 7) 752 uinfo->value.enumerated.item = 7; 753 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 754 return 0; 755} 756 757static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 758{ 759 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 760 ucontrol->value.enumerated.item[0] = snd_es1688_mixer_read(chip, ES1688_REC_DEV) & 7; 761 return 0; 762} 763 764static int snd_es1688_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 765{ 766 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 767 unsigned long flags; 768 unsigned char oval, nval; 769 int change; 770 771 if (ucontrol->value.enumerated.item[0] > 8) 772 return -EINVAL; 773 spin_lock_irqsave(&chip->reg_lock, flags); 774 oval = snd_es1688_mixer_read(chip, ES1688_REC_DEV); 775 nval = (ucontrol->value.enumerated.item[0] & 7) | (oval & ~15); 776 change = nval != oval; 777 if (change) 778 snd_es1688_mixer_write(chip, ES1688_REC_DEV, nval); 779 spin_unlock_irqrestore(&chip->reg_lock, flags); 780 return change; 781} 782 783#define ES1688_SINGLE(xname, xindex, reg, shift, mask, invert) \ 784{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 785 .info = snd_es1688_info_single, \ 786 .get = snd_es1688_get_single, .put = snd_es1688_put_single, \ 787 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 788 789static int snd_es1688_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 790{ 791 int mask = (kcontrol->private_value >> 16) & 0xff; 792 793 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; 794 uinfo->count = 1; 795 uinfo->value.integer.min = 0; 796 uinfo->value.integer.max = mask; 797 return 0; 798} 799 800static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 801{ 802 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 803 unsigned long flags; 804 int reg = kcontrol->private_value & 0xff; 805 int shift = (kcontrol->private_value >> 8) & 0xff; 806 int mask = (kcontrol->private_value >> 16) & 0xff; 807 int invert = (kcontrol->private_value >> 24) & 0xff; 808 809 spin_lock_irqsave(&chip->reg_lock, flags); 810 ucontrol->value.integer.value[0] = (snd_es1688_mixer_read(chip, reg) >> shift) & mask; 811 spin_unlock_irqrestore(&chip->reg_lock, flags); 812 if (invert) 813 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 814 return 0; 815} 816 817static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 818{ 819 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 820 unsigned long flags; 821 int reg = kcontrol->private_value & 0xff; 822 int shift = (kcontrol->private_value >> 8) & 0xff; 823 int mask = (kcontrol->private_value >> 16) & 0xff; 824 int invert = (kcontrol->private_value >> 24) & 0xff; 825 int change; 826 unsigned char oval, nval; 827 828 nval = (ucontrol->value.integer.value[0] & mask); 829 if (invert) 830 nval = mask - nval; 831 nval <<= shift; 832 spin_lock_irqsave(&chip->reg_lock, flags); 833 oval = snd_es1688_mixer_read(chip, reg); 834 nval = (oval & ~(mask << shift)) | nval; 835 change = nval != oval; 836 if (change) 837 snd_es1688_mixer_write(chip, reg, nval); 838 spin_unlock_irqrestore(&chip->reg_lock, flags); 839 return change; 840} 841 842#define ES1688_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 843{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 844 .info = snd_es1688_info_double, \ 845 .get = snd_es1688_get_double, .put = snd_es1688_put_double, \ 846 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 847 848static int snd_es1688_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 849{ 850 int mask = (kcontrol->private_value >> 24) & 0xff; 851 852 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; 853 uinfo->count = 2; 854 uinfo->value.integer.min = 0; 855 uinfo->value.integer.max = mask; 856 return 0; 857} 858 859static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 860{ 861 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 862 unsigned long flags; 863 int left_reg = kcontrol->private_value & 0xff; 864 int right_reg = (kcontrol->private_value >> 8) & 0xff; 865 int shift_left = (kcontrol->private_value >> 16) & 0x07; 866 int shift_right = (kcontrol->private_value >> 19) & 0x07; 867 int mask = (kcontrol->private_value >> 24) & 0xff; 868 int invert = (kcontrol->private_value >> 22) & 1; 869 unsigned char left, right; 870 871 spin_lock_irqsave(&chip->reg_lock, flags); 872 if (left_reg < 0xa0) 873 left = snd_es1688_mixer_read(chip, left_reg); 874 else 875 left = snd_es1688_read(chip, left_reg); 876 if (left_reg != right_reg) { 877 if (right_reg < 0xa0) 878 right = snd_es1688_mixer_read(chip, right_reg); 879 else 880 right = snd_es1688_read(chip, right_reg); 881 } else 882 right = left; 883 spin_unlock_irqrestore(&chip->reg_lock, flags); 884 ucontrol->value.integer.value[0] = (left >> shift_left) & mask; 885 ucontrol->value.integer.value[1] = (right >> shift_right) & mask; 886 if (invert) { 887 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0]; 888 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1]; 889 } 890 return 0; 891} 892 893static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 894{ 895 struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol); 896 unsigned long flags; 897 int left_reg = kcontrol->private_value & 0xff; 898 int right_reg = (kcontrol->private_value >> 8) & 0xff; 899 int shift_left = (kcontrol->private_value >> 16) & 0x07; 900 int shift_right = (kcontrol->private_value >> 19) & 0x07; 901 int mask = (kcontrol->private_value >> 24) & 0xff; 902 int invert = (kcontrol->private_value >> 22) & 1; 903 int change; 904 unsigned char val1, val2, oval1, oval2; 905 906 val1 = ucontrol->value.integer.value[0] & mask; 907 val2 = ucontrol->value.integer.value[1] & mask; 908 if (invert) { 909 val1 = mask - val1; 910 val2 = mask - val2; 911 } 912 val1 <<= shift_left; 913 val2 <<= shift_right; 914 spin_lock_irqsave(&chip->reg_lock, flags); 915 if (left_reg != right_reg) { 916 if (left_reg < 0xa0) 917 oval1 = snd_es1688_mixer_read(chip, left_reg); 918 else 919 oval1 = snd_es1688_read(chip, left_reg); 920 if (right_reg < 0xa0) 921 oval2 = snd_es1688_mixer_read(chip, right_reg); 922 else 923 oval2 = snd_es1688_read(chip, right_reg); 924 val1 = (oval1 & ~(mask << shift_left)) | val1; 925 val2 = (oval2 & ~(mask << shift_right)) | val2; 926 change = val1 != oval1 || val2 != oval2; 927 if (change) { 928 if (left_reg < 0xa0) 929 snd_es1688_mixer_write(chip, left_reg, val1); 930 else 931 snd_es1688_write(chip, left_reg, val1); 932 if (right_reg < 0xa0) 933 snd_es1688_mixer_write(chip, right_reg, val1); 934 else 935 snd_es1688_write(chip, right_reg, val1); 936 } 937 } else { 938 if (left_reg < 0xa0) 939 oval1 = snd_es1688_mixer_read(chip, left_reg); 940 else 941 oval1 = snd_es1688_read(chip, left_reg); 942 val1 = (oval1 & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2; 943 change = val1 != oval1; 944 if (change) { 945 if (left_reg < 0xa0) 946 snd_es1688_mixer_write(chip, left_reg, val1); 947 else 948 snd_es1688_write(chip, left_reg, val1); 949 } 950 951 } 952 spin_unlock_irqrestore(&chip->reg_lock, flags); 953 return change; 954} 955 956static struct snd_kcontrol_new snd_es1688_controls[] = { 957ES1688_DOUBLE("Master Playback Volume", 0, ES1688_MASTER_DEV, ES1688_MASTER_DEV, 4, 0, 15, 0), 958ES1688_DOUBLE("PCM Playback Volume", 0, ES1688_PCM_DEV, ES1688_PCM_DEV, 4, 0, 15, 0), 959ES1688_DOUBLE("Line Playback Volume", 0, ES1688_LINE_DEV, ES1688_LINE_DEV, 4, 0, 15, 0), 960ES1688_DOUBLE("CD Playback Volume", 0, ES1688_CD_DEV, ES1688_CD_DEV, 4, 0, 15, 0), 961ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0), 962ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0), 963ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0), 964ES1688_SINGLE("PC Speaker Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0), 965ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0), 966ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1), 967{ 968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 969 .name = "Capture Source", 970 .info = snd_es1688_info_mux, 971 .get = snd_es1688_get_mux, 972 .put = snd_es1688_put_mux, 973}, 974}; 975 976#define ES1688_INIT_TABLE_SIZE (sizeof(snd_es1688_init_table)/2) 977 978static unsigned char snd_es1688_init_table[][2] = { 979 { ES1688_MASTER_DEV, 0 }, 980 { ES1688_PCM_DEV, 0 }, 981 { ES1688_LINE_DEV, 0 }, 982 { ES1688_CD_DEV, 0 }, 983 { ES1688_FM_DEV, 0 }, 984 { ES1688_MIC_DEV, 0 }, 985 { ES1688_AUX_DEV, 0 }, 986 { ES1688_SPEAKER_DEV, 0 }, 987 { ES1688_RECLEV_DEV, 0 }, 988 { ES1688_REC_DEV, 0x17 } 989}; 990 991int snd_es1688_mixer(struct snd_es1688 *chip) 992{ 993 struct snd_card *card; 994 unsigned int idx; 995 int err; 996 unsigned char reg, val; 997 998 snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); 999 1000 card = chip->card; 1001 1002 strcpy(card->mixername, snd_es1688_chip_id(chip)); 1003 1004 for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { 1005 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es1688_controls[idx], chip))) < 0) 1006 return err; 1007 } 1008 for (idx = 0; idx < ES1688_INIT_TABLE_SIZE; idx++) { 1009 reg = snd_es1688_init_table[idx][0]; 1010 val = snd_es1688_init_table[idx][1]; 1011 if (reg < 0xa0) 1012 snd_es1688_mixer_write(chip, reg, val); 1013 else 1014 snd_es1688_write(chip, reg, val); 1015 } 1016 return 0; 1017} 1018 1019EXPORT_SYMBOL(snd_es1688_mixer_write); 1020EXPORT_SYMBOL(snd_es1688_create); 1021EXPORT_SYMBOL(snd_es1688_pcm); 1022EXPORT_SYMBOL(snd_es1688_mixer); 1023 1024/* 1025 * INIT part 1026 */ 1027 1028static int __init alsa_es1688_init(void) 1029{ 1030 return 0; 1031} 1032 1033static void __exit alsa_es1688_exit(void) 1034{ 1035} 1036 1037module_init(alsa_es1688_init) 1038module_exit(alsa_es1688_exit) 1039