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