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