1 /* 2 * Support for audio capture 3 * PCI function #1 of the cx2388x. 4 * 5 * (c) 2007 Trent Piepho <xyzzy@speakeasy.org> 6 * (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org> 7 * (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org> 8 * Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org> 9 * Based on dummy.c by Jaroslav Kysela <perex@perex.cz> 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 */ 21 22 #include "cx88.h" 23 #include "cx88-reg.h" 24 25 #include <linux/module.h> 26 #include <linux/init.h> 27 #include <linux/delay.h> 28 #include <linux/device.h> 29 #include <linux/interrupt.h> 30 #include <linux/vmalloc.h> 31 #include <linux/dma-mapping.h> 32 #include <linux/pci.h> 33 #include <linux/slab.h> 34 35 #include <sound/core.h> 36 #include <sound/pcm.h> 37 #include <sound/pcm_params.h> 38 #include <sound/control.h> 39 #include <sound/initval.h> 40 #include <sound/tlv.h> 41 #include <media/i2c/wm8775.h> 42 43 #define dprintk(level, fmt, arg...) do { \ 44 if (debug + 1 > level) \ 45 printk(KERN_DEBUG pr_fmt("%s: alsa: " fmt), \ 46 chip->core->name, ##arg); \ 47 } while (0) 48 49 /* 50 * Data type declarations - Can be moded to a header file later 51 */ 52 53 struct cx88_audio_buffer { 54 unsigned int bpl; 55 struct cx88_riscmem risc; 56 void *vaddr; 57 struct scatterlist *sglist; 58 int sglen; 59 int nr_pages; 60 }; 61 62 struct cx88_audio_dev { 63 struct cx88_core *core; 64 struct cx88_dmaqueue q; 65 66 /* pci i/o */ 67 struct pci_dev *pci; 68 69 /* audio controls */ 70 int irq; 71 72 struct snd_card *card; 73 74 spinlock_t reg_lock; 75 atomic_t count; 76 77 unsigned int dma_size; 78 unsigned int period_size; 79 unsigned int num_periods; 80 81 struct cx88_audio_buffer *buf; 82 83 struct snd_pcm_substream *substream; 84 }; 85 86 /* 87 * Module global static vars 88 */ 89 90 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 91 static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 92 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 93 94 module_param_array(enable, bool, NULL, 0444); 95 MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); 96 97 module_param_array(index, int, NULL, 0444); 98 MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); 99 100 /* 101 * Module macros 102 */ 103 104 MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); 105 MODULE_AUTHOR("Ricardo Cerqueira"); 106 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>"); 107 MODULE_LICENSE("GPL"); 108 MODULE_VERSION(CX88_VERSION); 109 110 MODULE_SUPPORTED_DEVICE("{{Conexant,23881},{{Conexant,23882},{{Conexant,23883}"); 111 static unsigned int debug; 112 module_param(debug, int, 0644); 113 MODULE_PARM_DESC(debug, "enable debug messages"); 114 115 /* 116 * Module specific functions 117 */ 118 119 /* 120 * BOARD Specific: Sets audio DMA 121 */ 122 123 static int _cx88_start_audio_dma(struct cx88_audio_dev *chip) 124 { 125 struct cx88_audio_buffer *buf = chip->buf; 126 struct cx88_core *core = chip->core; 127 const struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; 128 129 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ 130 cx_clear(MO_AUD_DMACNTRL, 0x11); 131 132 /* setup fifo + format - out channel */ 133 cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma); 134 135 /* sets bpl size */ 136 cx_write(MO_AUDD_LNGTH, buf->bpl); 137 138 /* reset counter */ 139 cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET); 140 atomic_set(&chip->count, 0); 141 142 dprintk(1, 143 "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d byte buffer\n", 144 buf->bpl, cx_read(audio_ch->cmds_start + 8) >> 1, 145 chip->num_periods, buf->bpl * chip->num_periods); 146 147 /* Enables corresponding bits at AUD_INT_STAT */ 148 cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | 149 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); 150 151 /* Clean any pending interrupt bits already set */ 152 cx_write(MO_AUD_INTSTAT, ~0); 153 154 /* enable audio irqs */ 155 cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT); 156 157 /* start dma */ 158 159 /* Enables Risc Processor */ 160 cx_set(MO_DEV_CNTRL2, (1 << 5)); 161 /* audio downstream FIFO and RISC enable */ 162 cx_set(MO_AUD_DMACNTRL, 0x11); 163 164 if (debug) 165 cx88_sram_channel_dump(chip->core, audio_ch); 166 167 return 0; 168 } 169 170 /* 171 * BOARD Specific: Resets audio DMA 172 */ 173 static int _cx88_stop_audio_dma(struct cx88_audio_dev *chip) 174 { 175 struct cx88_core *core = chip->core; 176 177 dprintk(1, "Stopping audio DMA\n"); 178 179 /* stop dma */ 180 cx_clear(MO_AUD_DMACNTRL, 0x11); 181 182 /* disable irqs */ 183 cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT); 184 cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | 185 AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1); 186 187 if (debug) 188 cx88_sram_channel_dump(chip->core, 189 &cx88_sram_channels[SRAM_CH25]); 190 191 return 0; 192 } 193 194 #define MAX_IRQ_LOOP 50 195 196 /* 197 * BOARD Specific: IRQ dma bits 198 */ 199 static const char *cx88_aud_irqs[32] = { 200 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ 201 NULL, /* reserved */ 202 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ 203 NULL, /* reserved */ 204 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ 205 NULL, /* reserved */ 206 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ 207 NULL, /* reserved */ 208 "opc_err", "par_err", "rip_err", /* 16-18 */ 209 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ 210 }; 211 212 /* 213 * BOARD Specific: Threats IRQ audio specific calls 214 */ 215 static void cx8801_aud_irq(struct cx88_audio_dev *chip) 216 { 217 struct cx88_core *core = chip->core; 218 u32 status, mask; 219 220 status = cx_read(MO_AUD_INTSTAT); 221 mask = cx_read(MO_AUD_INTMSK); 222 if (0 == (status & mask)) 223 return; 224 cx_write(MO_AUD_INTSTAT, status); 225 if (debug > 1 || (status & mask & ~0xff)) 226 cx88_print_irqbits("irq aud", 227 cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs), 228 status, mask); 229 /* risc op code error */ 230 if (status & AUD_INT_OPC_ERR) { 231 pr_warn("Audio risc op code error\n"); 232 cx_clear(MO_AUD_DMACNTRL, 0x11); 233 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]); 234 } 235 if (status & AUD_INT_DN_SYNC) { 236 dprintk(1, "Downstream sync error\n"); 237 cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET); 238 return; 239 } 240 /* risc1 downstream */ 241 if (status & AUD_INT_DN_RISCI1) { 242 atomic_set(&chip->count, cx_read(MO_AUDD_GPCNT)); 243 snd_pcm_period_elapsed(chip->substream); 244 } 245 /* FIXME: Any other status should deserve a special handling? */ 246 } 247 248 /* 249 * BOARD Specific: Handles IRQ calls 250 */ 251 static irqreturn_t cx8801_irq(int irq, void *dev_id) 252 { 253 struct cx88_audio_dev *chip = dev_id; 254 struct cx88_core *core = chip->core; 255 u32 status; 256 int loop, handled = 0; 257 258 for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { 259 status = cx_read(MO_PCI_INTSTAT) & 260 (core->pci_irqmask | PCI_INT_AUDINT); 261 if (status == 0) 262 goto out; 263 dprintk(3, "cx8801_irq loop %d/%d, status %x\n", 264 loop, MAX_IRQ_LOOP, status); 265 handled = 1; 266 cx_write(MO_PCI_INTSTAT, status); 267 268 if (status & core->pci_irqmask) 269 cx88_core_irq(core, status); 270 if (status & PCI_INT_AUDINT) 271 cx8801_aud_irq(chip); 272 } 273 274 if (loop == MAX_IRQ_LOOP) { 275 pr_err("IRQ loop detected, disabling interrupts\n"); 276 cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT); 277 } 278 279 out: 280 return IRQ_RETVAL(handled); 281 } 282 283 static int cx88_alsa_dma_init(struct cx88_audio_dev *chip, int nr_pages) 284 { 285 struct cx88_audio_buffer *buf = chip->buf; 286 struct page *pg; 287 int i; 288 289 buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); 290 if (!buf->vaddr) { 291 dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); 292 return -ENOMEM; 293 } 294 295 dprintk(1, "vmalloc is at addr %p, size=%d\n", 296 buf->vaddr, nr_pages << PAGE_SHIFT); 297 298 memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); 299 buf->nr_pages = nr_pages; 300 301 buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); 302 if (!buf->sglist) 303 goto vzalloc_err; 304 305 sg_init_table(buf->sglist, buf->nr_pages); 306 for (i = 0; i < buf->nr_pages; i++) { 307 pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); 308 if (!pg) 309 goto vmalloc_to_page_err; 310 sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); 311 } 312 return 0; 313 314 vmalloc_to_page_err: 315 vfree(buf->sglist); 316 buf->sglist = NULL; 317 vzalloc_err: 318 vfree(buf->vaddr); 319 buf->vaddr = NULL; 320 return -ENOMEM; 321 } 322 323 static int cx88_alsa_dma_map(struct cx88_audio_dev *dev) 324 { 325 struct cx88_audio_buffer *buf = dev->buf; 326 327 buf->sglen = dma_map_sg(&dev->pci->dev, buf->sglist, 328 buf->nr_pages, PCI_DMA_FROMDEVICE); 329 330 if (buf->sglen == 0) { 331 pr_warn("%s: cx88_alsa_map_sg failed\n", __func__); 332 return -ENOMEM; 333 } 334 return 0; 335 } 336 337 static int cx88_alsa_dma_unmap(struct cx88_audio_dev *dev) 338 { 339 struct cx88_audio_buffer *buf = dev->buf; 340 341 if (!buf->sglen) 342 return 0; 343 344 dma_unmap_sg(&dev->pci->dev, buf->sglist, buf->sglen, 345 PCI_DMA_FROMDEVICE); 346 buf->sglen = 0; 347 return 0; 348 } 349 350 static int cx88_alsa_dma_free(struct cx88_audio_buffer *buf) 351 { 352 vfree(buf->sglist); 353 buf->sglist = NULL; 354 vfree(buf->vaddr); 355 buf->vaddr = NULL; 356 return 0; 357 } 358 359 static int dsp_buffer_free(struct cx88_audio_dev *chip) 360 { 361 struct cx88_riscmem *risc = &chip->buf->risc; 362 363 WARN_ON(!chip->dma_size); 364 365 dprintk(2, "Freeing buffer\n"); 366 cx88_alsa_dma_unmap(chip); 367 cx88_alsa_dma_free(chip->buf); 368 if (risc->cpu) 369 pci_free_consistent(chip->pci, risc->size, 370 risc->cpu, risc->dma); 371 kfree(chip->buf); 372 373 chip->buf = NULL; 374 375 return 0; 376 } 377 378 /* 379 * ALSA PCM Interface 380 */ 381 382 /* 383 * Digital hardware definition 384 */ 385 #define DEFAULT_FIFO_SIZE 4096 386 static const struct snd_pcm_hardware snd_cx88_digital_hw = { 387 .info = SNDRV_PCM_INFO_MMAP | 388 SNDRV_PCM_INFO_INTERLEAVED | 389 SNDRV_PCM_INFO_BLOCK_TRANSFER | 390 SNDRV_PCM_INFO_MMAP_VALID, 391 .formats = SNDRV_PCM_FMTBIT_S16_LE, 392 393 .rates = SNDRV_PCM_RATE_48000, 394 .rate_min = 48000, 395 .rate_max = 48000, 396 .channels_min = 2, 397 .channels_max = 2, 398 /* 399 * Analog audio output will be full of clicks and pops if there 400 * are not exactly four lines in the SRAM FIFO buffer. 401 */ 402 .period_bytes_min = DEFAULT_FIFO_SIZE / 4, 403 .period_bytes_max = DEFAULT_FIFO_SIZE / 4, 404 .periods_min = 1, 405 .periods_max = 1024, 406 .buffer_bytes_max = (1024 * 1024), 407 }; 408 409 /* 410 * audio pcm capture open callback 411 */ 412 static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) 413 { 414 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); 415 struct snd_pcm_runtime *runtime = substream->runtime; 416 int err; 417 418 if (!chip) { 419 pr_err("BUG: cx88 can't find device struct. Can't proceed with open\n"); 420 return -ENODEV; 421 } 422 423 err = snd_pcm_hw_constraint_pow2(runtime, 0, 424 SNDRV_PCM_HW_PARAM_PERIODS); 425 if (err < 0) 426 goto _error; 427 428 chip->substream = substream; 429 430 runtime->hw = snd_cx88_digital_hw; 431 432 if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) { 433 unsigned int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4; 434 435 bpl &= ~7; /* must be multiple of 8 */ 436 runtime->hw.period_bytes_min = bpl; 437 runtime->hw.period_bytes_max = bpl; 438 } 439 440 return 0; 441 _error: 442 dprintk(1, "Error opening PCM!\n"); 443 return err; 444 } 445 446 /* 447 * audio close callback 448 */ 449 static int snd_cx88_close(struct snd_pcm_substream *substream) 450 { 451 return 0; 452 } 453 454 /* 455 * hw_params callback 456 */ 457 static int snd_cx88_hw_params(struct snd_pcm_substream *substream, 458 struct snd_pcm_hw_params *hw_params) 459 { 460 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); 461 462 struct cx88_audio_buffer *buf; 463 int ret; 464 465 if (substream->runtime->dma_area) { 466 dsp_buffer_free(chip); 467 substream->runtime->dma_area = NULL; 468 } 469 470 chip->period_size = params_period_bytes(hw_params); 471 chip->num_periods = params_periods(hw_params); 472 chip->dma_size = chip->period_size * params_periods(hw_params); 473 474 WARN_ON(!chip->dma_size); 475 WARN_ON(chip->num_periods & (chip->num_periods - 1)); 476 477 buf = kzalloc(sizeof(*buf), GFP_KERNEL); 478 if (!buf) 479 return -ENOMEM; 480 481 chip->buf = buf; 482 buf->bpl = chip->period_size; 483 484 ret = cx88_alsa_dma_init(chip, 485 (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); 486 if (ret < 0) 487 goto error; 488 489 ret = cx88_alsa_dma_map(chip); 490 if (ret < 0) 491 goto error; 492 493 ret = cx88_risc_databuffer(chip->pci, &buf->risc, buf->sglist, 494 chip->period_size, chip->num_periods, 1); 495 if (ret < 0) 496 goto error; 497 498 /* Loop back to start of program */ 499 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); 500 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 501 502 substream->runtime->dma_area = chip->buf->vaddr; 503 substream->runtime->dma_bytes = chip->dma_size; 504 substream->runtime->dma_addr = 0; 505 return 0; 506 507 error: 508 kfree(buf); 509 return ret; 510 } 511 512 /* 513 * hw free callback 514 */ 515 static int snd_cx88_hw_free(struct snd_pcm_substream *substream) 516 { 517 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); 518 519 if (substream->runtime->dma_area) { 520 dsp_buffer_free(chip); 521 substream->runtime->dma_area = NULL; 522 } 523 524 return 0; 525 } 526 527 /* 528 * prepare callback 529 */ 530 static int snd_cx88_prepare(struct snd_pcm_substream *substream) 531 { 532 return 0; 533 } 534 535 /* 536 * trigger callback 537 */ 538 static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) 539 { 540 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); 541 int err; 542 543 /* Local interrupts are already disabled by ALSA */ 544 spin_lock(&chip->reg_lock); 545 546 switch (cmd) { 547 case SNDRV_PCM_TRIGGER_START: 548 err = _cx88_start_audio_dma(chip); 549 break; 550 case SNDRV_PCM_TRIGGER_STOP: 551 err = _cx88_stop_audio_dma(chip); 552 break; 553 default: 554 err = -EINVAL; 555 break; 556 } 557 558 spin_unlock(&chip->reg_lock); 559 560 return err; 561 } 562 563 /* 564 * pointer callback 565 */ 566 static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) 567 { 568 struct cx88_audio_dev *chip = snd_pcm_substream_chip(substream); 569 struct snd_pcm_runtime *runtime = substream->runtime; 570 u16 count; 571 572 count = atomic_read(&chip->count); 573 574 // dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__, 575 // count, new, count & (runtime->periods-1), 576 // runtime->period_size * (count & (runtime->periods-1))); 577 return runtime->period_size * (count & (runtime->periods - 1)); 578 } 579 580 /* 581 * page callback (needed for mmap) 582 */ 583 static struct page *snd_cx88_page(struct snd_pcm_substream *substream, 584 unsigned long offset) 585 { 586 void *pageptr = substream->runtime->dma_area + offset; 587 588 return vmalloc_to_page(pageptr); 589 } 590 591 /* 592 * operators 593 */ 594 static const struct snd_pcm_ops snd_cx88_pcm_ops = { 595 .open = snd_cx88_pcm_open, 596 .close = snd_cx88_close, 597 .ioctl = snd_pcm_lib_ioctl, 598 .hw_params = snd_cx88_hw_params, 599 .hw_free = snd_cx88_hw_free, 600 .prepare = snd_cx88_prepare, 601 .trigger = snd_cx88_card_trigger, 602 .pointer = snd_cx88_pointer, 603 .page = snd_cx88_page, 604 }; 605 606 /* 607 * create a PCM device 608 */ 609 static int snd_cx88_pcm(struct cx88_audio_dev *chip, int device, 610 const char *name) 611 { 612 int err; 613 struct snd_pcm *pcm; 614 615 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); 616 if (err < 0) 617 return err; 618 pcm->private_data = chip; 619 strcpy(pcm->name, name); 620 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops); 621 622 return 0; 623 } 624 625 /* 626 * CONTROL INTERFACE 627 */ 628 static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol, 629 struct snd_ctl_elem_info *info) 630 { 631 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 632 info->count = 2; 633 info->value.integer.min = 0; 634 info->value.integer.max = 0x3f; 635 636 return 0; 637 } 638 639 static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol, 640 struct snd_ctl_elem_value *value) 641 { 642 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 643 struct cx88_core *core = chip->core; 644 int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f), 645 bal = cx_read(AUD_BAL_CTL); 646 647 value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol; 648 vol -= (bal & 0x3f); 649 value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol; 650 651 return 0; 652 } 653 654 static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol, 655 struct snd_ctl_elem_value *value) 656 { 657 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 658 struct cx88_core *core = chip->core; 659 u16 left = value->value.integer.value[0]; 660 u16 right = value->value.integer.value[1]; 661 int v, b; 662 663 /* Pass volume & balance onto any WM8775 */ 664 if (left >= right) { 665 v = left << 10; 666 b = left ? (0x8000 * right) / left : 0x8000; 667 } else { 668 v = right << 10; 669 b = right ? 0xffff - (0x8000 * left) / right : 0x8000; 670 } 671 wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v); 672 wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b); 673 } 674 675 /* OK - TODO: test it */ 676 static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, 677 struct snd_ctl_elem_value *value) 678 { 679 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 680 struct cx88_core *core = chip->core; 681 int left, right, v, b; 682 int changed = 0; 683 u32 old; 684 685 if (core->sd_wm8775) 686 snd_cx88_wm8775_volume_put(kcontrol, value); 687 688 left = value->value.integer.value[0] & 0x3f; 689 right = value->value.integer.value[1] & 0x3f; 690 b = right - left; 691 if (b < 0) { 692 v = 0x3f - left; 693 b = (-b) | 0x40; 694 } else { 695 v = 0x3f - right; 696 } 697 /* Do we really know this will always be called with IRQs on? */ 698 spin_lock_irq(&chip->reg_lock); 699 old = cx_read(AUD_VOL_CTL); 700 if (v != (old & 0x3f)) { 701 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v); 702 changed = 1; 703 } 704 if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) { 705 cx_write(AUD_BAL_CTL, b); 706 changed = 1; 707 } 708 spin_unlock_irq(&chip->reg_lock); 709 710 return changed; 711 } 712 713 static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0); 714 715 static const struct snd_kcontrol_new snd_cx88_volume = { 716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 717 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 718 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 719 .name = "Analog-TV Volume", 720 .info = snd_cx88_volume_info, 721 .get = snd_cx88_volume_get, 722 .put = snd_cx88_volume_put, 723 .tlv.p = snd_cx88_db_scale, 724 }; 725 726 static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol, 727 struct snd_ctl_elem_value *value) 728 { 729 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 730 struct cx88_core *core = chip->core; 731 u32 bit = kcontrol->private_value; 732 733 value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit); 734 return 0; 735 } 736 737 static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, 738 struct snd_ctl_elem_value *value) 739 { 740 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 741 struct cx88_core *core = chip->core; 742 u32 bit = kcontrol->private_value; 743 int ret = 0; 744 u32 vol; 745 746 spin_lock_irq(&chip->reg_lock); 747 vol = cx_read(AUD_VOL_CTL); 748 if (value->value.integer.value[0] != !(vol & bit)) { 749 vol ^= bit; 750 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); 751 /* Pass mute onto any WM8775 */ 752 if (core->sd_wm8775 && ((1 << 6) == bit)) 753 wm8775_s_ctrl(core, 754 V4L2_CID_AUDIO_MUTE, 0 != (vol & bit)); 755 ret = 1; 756 } 757 spin_unlock_irq(&chip->reg_lock); 758 return ret; 759 } 760 761 static const struct snd_kcontrol_new snd_cx88_dac_switch = { 762 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 763 .name = "Audio-Out Switch", 764 .info = snd_ctl_boolean_mono_info, 765 .get = snd_cx88_switch_get, 766 .put = snd_cx88_switch_put, 767 .private_value = (1 << 8), 768 }; 769 770 static const struct snd_kcontrol_new snd_cx88_source_switch = { 771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 772 .name = "Analog-TV Switch", 773 .info = snd_ctl_boolean_mono_info, 774 .get = snd_cx88_switch_get, 775 .put = snd_cx88_switch_put, 776 .private_value = (1 << 6), 777 }; 778 779 static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, 780 struct snd_ctl_elem_value *value) 781 { 782 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 783 struct cx88_core *core = chip->core; 784 s32 val; 785 786 val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS); 787 value->value.integer.value[0] = val ? 1 : 0; 788 return 0; 789 } 790 791 static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, 792 struct snd_ctl_elem_value *value) 793 { 794 struct cx88_audio_dev *chip = snd_kcontrol_chip(kcontrol); 795 struct cx88_core *core = chip->core; 796 797 wm8775_s_ctrl(core, V4L2_CID_AUDIO_LOUDNESS, 798 value->value.integer.value[0] != 0); 799 return 0; 800 } 801 802 static const struct snd_kcontrol_new snd_cx88_alc_switch = { 803 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 804 .name = "Line-In ALC Switch", 805 .info = snd_ctl_boolean_mono_info, 806 .get = snd_cx88_alc_get, 807 .put = snd_cx88_alc_put, 808 }; 809 810 /* 811 * Basic Flow for Sound Devices 812 */ 813 814 /* 815 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio 816 * Only boards with eeprom and byte 1 at eeprom=1 have it 817 */ 818 819 static const struct pci_device_id cx88_audio_pci_tbl[] = { 820 {0x14f1, 0x8801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 821 {0x14f1, 0x8811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 822 {0, } 823 }; 824 MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl); 825 826 /* 827 * Chip-specific destructor 828 */ 829 830 static int snd_cx88_free(struct cx88_audio_dev *chip) 831 { 832 if (chip->irq >= 0) 833 free_irq(chip->irq, chip); 834 835 cx88_core_put(chip->core, chip->pci); 836 837 pci_disable_device(chip->pci); 838 return 0; 839 } 840 841 /* 842 * Component Destructor 843 */ 844 static void snd_cx88_dev_free(struct snd_card *card) 845 { 846 struct cx88_audio_dev *chip = card->private_data; 847 848 snd_cx88_free(chip); 849 } 850 851 /* 852 * Alsa Constructor - Component probe 853 */ 854 855 static int devno; 856 static int snd_cx88_create(struct snd_card *card, struct pci_dev *pci, 857 struct cx88_audio_dev **rchip, 858 struct cx88_core **core_ptr) 859 { 860 struct cx88_audio_dev *chip; 861 struct cx88_core *core; 862 int err; 863 unsigned char pci_lat; 864 865 *rchip = NULL; 866 867 err = pci_enable_device(pci); 868 if (err < 0) 869 return err; 870 871 pci_set_master(pci); 872 873 chip = card->private_data; 874 875 core = cx88_core_get(pci); 876 if (!core) { 877 err = -EINVAL; 878 return err; 879 } 880 881 err = pci_set_dma_mask(pci, DMA_BIT_MASK(32)); 882 if (err) { 883 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n", core->name); 884 cx88_core_put(core, pci); 885 return err; 886 } 887 888 /* pci init */ 889 chip->card = card; 890 chip->pci = pci; 891 chip->irq = -1; 892 spin_lock_init(&chip->reg_lock); 893 894 chip->core = core; 895 896 /* get irq */ 897 err = request_irq(chip->pci->irq, cx8801_irq, 898 IRQF_SHARED, chip->core->name, chip); 899 if (err < 0) { 900 dprintk(0, "%s: can't get IRQ %d\n", 901 chip->core->name, chip->pci->irq); 902 return err; 903 } 904 905 /* print pci info */ 906 pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat); 907 908 dprintk(1, 909 "ALSA %s/%i: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", 910 core->name, devno, 911 pci_name(pci), pci->revision, pci->irq, 912 pci_lat, (unsigned long long)pci_resource_start(pci, 0)); 913 914 chip->irq = pci->irq; 915 synchronize_irq(chip->irq); 916 917 *rchip = chip; 918 *core_ptr = core; 919 920 return 0; 921 } 922 923 static int cx88_audio_initdev(struct pci_dev *pci, 924 const struct pci_device_id *pci_id) 925 { 926 struct snd_card *card; 927 struct cx88_audio_dev *chip; 928 struct cx88_core *core = NULL; 929 int err; 930 931 if (devno >= SNDRV_CARDS) 932 return (-ENODEV); 933 934 if (!enable[devno]) { 935 ++devno; 936 return (-ENOENT); 937 } 938 939 err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE, 940 sizeof(struct cx88_audio_dev), &card); 941 if (err < 0) 942 return err; 943 944 card->private_free = snd_cx88_dev_free; 945 946 err = snd_cx88_create(card, pci, &chip, &core); 947 if (err < 0) 948 goto error; 949 950 err = snd_cx88_pcm(chip, 0, "CX88 Digital"); 951 if (err < 0) 952 goto error; 953 954 err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip)); 955 if (err < 0) 956 goto error; 957 err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip)); 958 if (err < 0) 959 goto error; 960 err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip)); 961 if (err < 0) 962 goto error; 963 964 /* If there's a wm8775 then add a Line-In ALC switch */ 965 if (core->sd_wm8775) 966 snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip)); 967 968 strcpy(card->driver, "CX88x"); 969 sprintf(card->shortname, "Conexant CX%x", pci->device); 970 sprintf(card->longname, "%s at %#llx", 971 card->shortname, 972 (unsigned long long)pci_resource_start(pci, 0)); 973 strcpy(card->mixername, "CX88"); 974 975 dprintk(0, "%s/%i: ALSA support for cx2388x boards\n", 976 card->driver, devno); 977 978 err = snd_card_register(card); 979 if (err < 0) 980 goto error; 981 pci_set_drvdata(pci, card); 982 983 devno++; 984 return 0; 985 986 error: 987 snd_card_free(card); 988 return err; 989 } 990 991 /* 992 * ALSA destructor 993 */ 994 static void cx88_audio_finidev(struct pci_dev *pci) 995 { 996 struct snd_card *card = pci_get_drvdata(pci); 997 998 snd_card_free(card); 999 1000 devno--; 1001 } 1002 1003 /* 1004 * PCI driver definition 1005 */ 1006 1007 static struct pci_driver cx88_audio_pci_driver = { 1008 .name = "cx88_audio", 1009 .id_table = cx88_audio_pci_tbl, 1010 .probe = cx88_audio_initdev, 1011 .remove = cx88_audio_finidev, 1012 }; 1013 1014 module_pci_driver(cx88_audio_pci_driver); 1015