int snd_msnd_enable_irq(struct snd_msnd *dev) { unsigned long flags; if (dev->irq_ref++) return 0; snd_printdd(LOGNAME ": Enabling IRQ\n"); spin_lock_irqsave(&dev->lock, flags); if (snd_msnd_wait_TXDE(dev) == 0) { outb(inb(dev->io + HP_ICR) | HPICR_TREQ, dev->io + HP_ICR); if (dev->type == msndClassic) outb(dev->irqid, dev->io + HP_IRQM); outb(inb(dev->io + HP_ICR) & ~HPICR_TREQ, dev->io + HP_ICR); outb(inb(dev->io + HP_ICR) | HPICR_RREQ, dev->io + HP_ICR); enable_irq(dev->irq); snd_msnd_init_queue(dev->DSPQ, dev->dspq_data_buff, dev->dspq_buff_size); spin_unlock_irqrestore(&dev->lock, flags); return 0; } spin_unlock_irqrestore(&dev->lock, flags); snd_printd(KERN_ERR LOGNAME ": Enable IRQ failed\n"); return -EIO; }
/* * allocate an event cell. */ int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, struct file *file) { snd_seq_event_cell_t *cell; unsigned long flags; int err = -EAGAIN; if (pool == NULL) return -EINVAL; *cellp = NULL; spin_lock_irqsave(&pool->lock, flags); if (pool->ptr == NULL) { /* not initialized */ snd_printd("seq: pool is not initialized\n"); err = -EINVAL; goto __error; } while (pool->free == NULL && ! nonblock && ! pool->closing) { /* change semaphore to allow other clients to access device file */ if (file) up(&semaphore_of(file)); snd_seq_sleep_in_lock(&pool->output_sleep, &pool->lock); /* restore semaphore again */ if (file) down(&semaphore_of(file)); /* interrupted? */ if (signal_pending(current)) { err = -ERESTARTSYS; goto __error; } } if (pool->closing) { /* closing.. */ err = -ENOMEM; goto __error; } cell = pool->free; if (cell) { int used; pool->free = cell->next; atomic_inc(&pool->counter); used = atomic_read(&pool->counter); if (pool->max_used < used) pool->max_used = used; pool->event_alloc_success++; /* clear cell pointers */ cell->next = NULL; err = 0; } else pool->event_alloc_failures++; *cellp = cell; __error: spin_unlock_irqrestore(&pool->lock, flags); return err; }
/* * Send and receive a verb */ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, unsigned int *res) { struct hda_bus *bus = codec->bus; int err; if (cmd == ~0) return -1; if (res) *res = -1; again: snd_hda_power_up(codec); mutex_lock(&bus->cmd_mutex); err = bus->ops.command(bus, cmd); if (!err && res) *res = bus->ops.get_response(bus, codec->addr); mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); if (res && *res == -1 && bus->rirb_error) { if (bus->response_reset) { snd_printd("hda_codec: resetting BUS due to " "fatal communication error\n"); bus->ops.bus_reset(bus); } goto again; } /* clear reset-flag when the communication gets recovered */ if (!err) bus->response_reset = 0; return err; }
static int snd_us428ctls_mmap(snd_hwdep_t * hw, struct file *filp, struct vm_area_struct *area) { unsigned long size = (unsigned long)(area->vm_end - area->vm_start); usX2Ydev_t *us428 = (usX2Ydev_t*)hw->private_data; // FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs? // so as long as the device isn't fully initialised yet we return -EBUSY here. if (!(((usX2Ydev_t*)hw->private_data)->chip_status & USX2Y_STAT_CHIP_INIT)) return -EBUSY; /* if userspace tries to mmap beyond end of our buffer, fail */ if (size > ((PAGE_SIZE - 1 + sizeof(us428ctls_sharedmem_t)) / PAGE_SIZE) * PAGE_SIZE) { snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(us428ctls_sharedmem_t)); return -EINVAL; } if (!us428->us428ctls_sharedmem) { init_waitqueue_head(&us428->us428ctls_wait_queue_head); if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(us428ctls_sharedmem_t), GFP_KERNEL))) return -ENOMEM; memset(us428->us428ctls_sharedmem, -1, sizeof(us428ctls_sharedmem_t)); us428->us428ctls_sharedmem->CtlSnapShotLast = -2; } area->vm_ops = &us428ctls_vm_ops; area->vm_flags |= VM_RESERVED; area->vm_private_data = hw->private_data; return 0; }
/* * allocate an event cell. */ static int snd_seq_cell_alloc(struct snd_seq_pool *pool, struct snd_seq_event_cell **cellp, int nonblock, struct file *file) { struct snd_seq_event_cell *cell; unsigned long flags; int err = -EAGAIN; wait_queue_t wait; if (pool == NULL) return -EINVAL; *cellp = NULL; init_waitqueue_entry(&wait, current); spin_lock_irqsave(&pool->lock, flags); if (pool->ptr == NULL) { /* not initialized */ snd_printd("seq: pool is not initialized\n"); err = -EINVAL; goto __error; } while (pool->free == NULL && ! nonblock && ! pool->closing) { set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&pool->output_sleep, &wait); spin_unlock_irq(&pool->lock); schedule(); spin_lock_irq(&pool->lock); remove_wait_queue(&pool->output_sleep, &wait); /* interrupted? */ if (signal_pending(current)) { err = -ERESTARTSYS; goto __error; } } if (pool->closing) { /* closing.. */ err = -ENOMEM; goto __error; } cell = pool->free; if (cell) { int used; pool->free = cell->next; atomic_inc(&pool->counter); used = atomic_read(&pool->counter); if (pool->max_used < used) pool->max_used = used; pool->event_alloc_success++; /* clear cell pointers */ cell->next = NULL; err = 0; } else pool->event_alloc_failures++; *cellp = cell; __error: spin_unlock_irqrestore(&pool->lock, flags); return err; }
/* create new queue (constructor) */ static struct snd_seq_queue *queue_new(int owner, int locked) { struct snd_seq_queue *q; q = kzalloc(sizeof(*q), GFP_KERNEL); if (q == NULL) { snd_printd("malloc failed for snd_seq_queue_new()\n"); return NULL; } spin_lock_init(&q->owner_lock); spin_lock_init(&q->check_lock); mutex_init(&q->timer_mutex); snd_use_lock_init(&q->use_lock); q->queue = -1; q->tickq = snd_seq_prioq_new(); q->timeq = snd_seq_prioq_new(); q->timer = snd_seq_timer_new(); if (q->tickq == NULL || q->timeq == NULL || q->timer == NULL) { snd_seq_prioq_delete(&q->tickq); snd_seq_prioq_delete(&q->timeq); snd_seq_timer_delete(&q->timer); kfree(q); return NULL; } q->owner = owner; q->locked = locked; q->klocked = 0; return q; }
static void snd_nm256_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { struct nm256 *chip = ac97->private_data; int tries = 2; int idx = nm256_ac97_idx(reg); u32 base; if (idx < 0) return; base = chip->mixer_base; snd_nm256_ac97_ready(chip); /* Wait for the write to take, too. */ while (tries-- > 0) { snd_nm256_writew(chip, base + reg, val); msleep(1); /* a little delay here seems better.. */ if (snd_nm256_ac97_ready(chip)) { /* successful write: set cache */ chip->ac97_regs[idx] = val; return; } } snd_printd("nm256: ac97 codec not ready..\n"); }
static void snd_nm256_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { struct nm256 *chip = ac97->private_data; int tries = 2; int idx = nm256_ac97_idx(reg); u32 base; if (idx < 0) return; base = chip->mixer_base; snd_nm256_ac97_ready(chip); while (tries-- > 0) { snd_nm256_writew(chip, base + reg, val); msleep(1); if (snd_nm256_ac97_ready(chip)) { chip->ac97_regs[idx] = val; return; } } snd_printd("nm256: ac97 codec not ready..\n"); }
/* allocate room specified number of events */ int snd_seq_pool_init(struct snd_seq_pool *pool) { int cell; struct snd_seq_event_cell *cellptr; unsigned long flags; snd_assert(pool != NULL, return -EINVAL); if (pool->ptr) /* should be atomic? */ return 0; pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); if (pool->ptr == NULL) { snd_printd("seq: malloc for sequencer events failed\n"); return -ENOMEM; } /* add new cells to the free cell list */ spin_lock_irqsave(&pool->lock, flags); pool->free = NULL; for (cell = 0; cell < pool->size; cell++) { cellptr = pool->ptr + cell; cellptr->pool = pool; cellptr->next = pool->free; pool->free = cellptr; } pool->room = (pool->size + 1) / 2; /* init statistics */ pool->max_used = 0; pool->total_elements = pool->size; spin_unlock_irqrestore(&pool->lock, flags); return 0; }
static int event_process_midi(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop) { struct seq_midisynth *msynth = private_data; unsigned char msg[10]; /* buffer for constructing midi messages */ struct snd_rawmidi_substream *substream; int len; snd_assert(msynth != NULL, return -EINVAL); substream = msynth->output_rfile.output; if (substream == NULL) return -ENODEV; if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { /* special case, to save space */ if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) { /* invalid event */ snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); return 0; } snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); snd_midi_event_reset_decode(msynth->parser); } else { if (msynth->parser == NULL) return -EIO; len = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev); if (len < 0) return 0; if (dump_midi(substream, msg, len) < 0) snd_midi_event_reset_decode(msynth->parser); } return 0; }
/* create new fifo */ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) { struct snd_seq_fifo *f; f = kzalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) { snd_printd("malloc failed for snd_seq_fifo_new() \n"); return NULL; } f->pool = snd_seq_pool_new(poolsize); if (f->pool == NULL) { kfree(f); return NULL; } if (snd_seq_pool_init(f->pool) < 0) { snd_seq_pool_delete(&f->pool); kfree(f); return NULL; } spin_lock_init(&f->lock); snd_use_lock_init(&f->use_lock); init_waitqueue_head(&f->input_sleep); atomic_set(&f->overflow, 0); f->head = NULL; f->tail = NULL; f->cells = 0; return f; }
static int __devinit lx_init_get_version_features(struct lx6464es *chip) { u32 dsp_version; int err; snd_printdd("->lx_init_get_version_features\n"); err = lx_dsp_get_version(chip, &dsp_version); if (err == 0) { u32 freq; snd_printk(LXP "DSP version: V%02d.%02d #%d\n", (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff, dsp_version & 0xff); /* later: what firmware version do we expect? */ /* retrieve Play/Rec features */ /* done here because we may have to handle alternate * DSP files. */ /* later */ /* init the EtherSound sample rate */ err = lx_dsp_get_clock_frequency(chip, &freq); if (err == 0) chip->board_sample_rate = freq; snd_printd(LXP "actual clock frequency %d\n", freq); } else {
static int lx_hardware_open(struct lx6464es *chip, struct snd_pcm_substream *substream) { int err = 0; struct snd_pcm_runtime *runtime = substream->runtime; int channels = runtime->channels; int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); snd_pcm_uframes_t period_size = runtime->period_size; snd_printd(LXP "allocating pipe for %d channels\n", channels); err = lx_pipe_allocate(chip, 0, is_capture, channels); if (err < 0) { snd_printk(KERN_ERR LXP "allocating pipe failed\n"); return err; } err = lx_set_granularity(chip, period_size); if (err < 0) { snd_printk(KERN_ERR LXP "setting granularity to %ld failed\n", period_size); return err; } return 0; }
/* dequeue cell from prioq */ struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f) { struct snd_seq_event_cell *cell; unsigned long flags; if (f == NULL) { snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); return NULL; } spin_lock_irqsave(&f->lock, flags); cell = f->head; if (cell) { f->head = cell->next; /* reset tail if this was the last element */ if (f->tail == cell) f->tail = NULL; cell->next = NULL; f->cells--; } spin_unlock_irqrestore(&f->lock, flags); return cell; }
static int __devinit lx_init_xilinx_test(struct lx6464es *chip) { u32 reg; snd_printdd("->lx_init_xilinx_test\n"); /* TEST if we have access to Xilinx/MicroBlaze */ lx_dsp_reg_write(chip, eReg_CSM, 0); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg); /* PCI9056_SPACE0_REMAP */ lx_plx_reg_write(chip, ePLX_PCICR, 1); reg = lx_dsp_reg_read(chip, eReg_CSM); if (reg) { snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg); return -EAGAIN; /* seems to be appropriate */ } } snd_printd(LXP "Xilinx/MicroBlaze access test successful\n"); return 0; }
static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area) { unsigned long size = (unsigned long)(area->vm_end - area->vm_start); struct usX2Ydev *us428 = hw->private_data; // so as long as the device isn't fully initialised yet we return -EBUSY here. if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT)) return -EBUSY; /* if userspace tries to mmap beyond end of our buffer, fail */ if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) { snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem)); return -EINVAL; } if (!us428->us428ctls_sharedmem) { init_waitqueue_head(&us428->us428ctls_wait_queue_head); if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(struct us428ctls_sharedmem), GFP_KERNEL))) return -ENOMEM; memset(us428->us428ctls_sharedmem, -1, sizeof(struct us428ctls_sharedmem)); us428->us428ctls_sharedmem->CtlSnapShotLast = -2; } area->vm_ops = &us428ctls_vm_ops; area->vm_flags |= VM_RESERVED | VM_DONTEXPAND; area->vm_private_data = hw->private_data; return 0; }
/* open associated midi device for input */ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe *info) { int err; struct seq_midisynth *msynth = private_data; struct snd_rawmidi_runtime *runtime; struct snd_rawmidi_params params; /* open midi port */ if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) { snd_printd("midi input open failed!!!\n"); return err; } runtime = msynth->input_rfile.input->runtime; memset(¶ms, 0, sizeof(params)); params.avail_min = 1; params.buffer_size = input_buffer_size; if ((err = snd_rawmidi_input_params(msynth->input_rfile.input, ¶ms)) < 0) { snd_rawmidi_kernel_release(&msynth->input_rfile); return err; } snd_midi_event_reset_encode(msynth->parser); runtime->event = snd_midi_input_event; runtime->private_data = msynth; snd_rawmidi_kernel_read(msynth->input_rfile.input, NULL, 0); return 0; }
int hda_i915_init(bool is_broadwell) { int err = 0; if (is_broadwell) get_power = symbol_request(i915_bdw_request_power_well); else get_power = symbol_request(i915_request_power_well); if (!get_power) { snd_printk(KERN_WARNING "hda-i915: get_power symbol get fail\n"); return -ENODEV; } if (is_broadwell) put_power = symbol_request(i915_bdw_release_power_well); else put_power = symbol_request(i915_release_power_well); if (!put_power) { symbol_put(i915_request_power_well); get_power = NULL; return -ENODEV; } snd_printd("HDA driver get symbol successfully from i915 module\n"); return err; }
static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info) { int err; struct seq_midisynth *msynth = private_data; struct snd_rawmidi_params params; if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_OUTPUT, &msynth->output_rfile)) < 0) { snd_printd("midi output open failed!!!\n"); return err; } memset(¶ms, 0, sizeof(params)); params.avail_min = 1; params.buffer_size = output_buffer_size; params.no_active_sensing = 1; if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, ¶ms)) < 0) { snd_rawmidi_kernel_release(&msynth->output_rfile); return err; } snd_midi_event_reset_decode(msynth->parser); return 0; }
static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx, unsigned int count) { unsigned int size, res; size = viadev->idx_table[idx].size; res = viadev->idx_table[idx].offset + size - count; /* */ if (size < count) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count); res = viadev->lastpos; } else if (check_invalid_pos(viadev, res)) { #ifdef POINTER_DEBUG printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, " "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, " "count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count); #endif if (count && size < count) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr, " "using last valid pointer\n"); res = viadev->lastpos; } else { if (! count) /* */ res = viadev->idx_table[idx].offset; else /* */ res = viadev->idx_table[idx].offset + size; if (check_invalid_pos(viadev, res)) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), " "using last valid pointer\n"); res = viadev->lastpos; } } } viadev->lastpos = res; /* */ if (res >= viadev->bufsize) res -= viadev->bufsize; return res; }
/* peek at cell at the head of the prioq */ struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f) { if (f == NULL) { snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); return NULL; } return f->head; }
/* return number of events available in prioq */ int snd_seq_prioq_avail(struct snd_seq_prioq * f) { if (f == NULL) { snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n"); return 0; } return f->cells; }
int snd_hdmi_get_eld(struct hdmi_eld *eld, struct hda_codec *codec, hda_nid_t nid) { int i; int ret; int size; unsigned char *buf; if (!hdmi_eld_valid(codec, nid)) return -ENOENT; size = snd_hdmi_get_eld_size(codec, nid); if (size == 0) { /* wfg: workaround for ASUS P5E-VM HDMI board */ snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); size = 128; } if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); return -ERANGE; } if (!eld->lpcm_sad_ready) hdmi_update_lpcm_sad_eld(codec, nid, eld, size); codec->recv_dec_cap = 0; for (i = 0; i < eld->sad_count; i++) { if (eld->sad[i].format == AUDIO_CODING_TYPE_AC3) { codec->recv_dec_cap |= (1<<AUDIO_CODING_TYPE_AC3); } else if (eld->sad[i].format == AUDIO_CODING_TYPE_DTS) { codec->recv_dec_cap |= (1<<AUDIO_CODING_TYPE_DTS); } } buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; for (i = 0; i < size; i++) buf[i] = hdmi_get_eld_byte(codec, nid, i); ret = hdmi_update_eld(eld, buf, size); kfree(buf); return ret; }
static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx, unsigned int count) { unsigned int size, res; size = viadev->idx_table[idx].size; res = viadev->idx_table[idx].offset + size - count; /* check the validity of the calculated position */ if (size < count) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count); res = viadev->lastpos; } else if (check_invalid_pos(viadev, res)) { #ifdef POINTER_DEBUG printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, " "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, " "count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count); #endif if (count && size < count) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr, " "using last valid pointer\n"); res = viadev->lastpos; } else { if (! count) /* bogus count 0 on the DMA boundary? */ res = viadev->idx_table[idx].offset; else /* count register returns full size * when end of buffer is reached */ res = viadev->idx_table[idx].offset + size; if (check_invalid_pos(viadev, res)) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), " "using last valid pointer\n"); res = viadev->lastpos; } } } viadev->lastpos = res; /* remember the last position */ if (res >= viadev->bufsize) res -= viadev->bufsize; return res; }
int snd_opl3_create(struct snd_card *card, unsigned long l_port, unsigned long r_port, unsigned short hardware, int integrated, struct snd_opl3 ** ropl3) { struct snd_opl3 *opl3; int err; *ropl3 = NULL; if ((err = snd_opl3_new(card, hardware, &opl3)) < 0) return err; if (! integrated) { if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) { snd_mprintk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port); // MJR snd_device_free(card, opl3); return -EBUSY; } if (r_port != 0 && (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) { snd_mprintk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port); // MJR snd_device_free(card, opl3); return -EBUSY; } } opl3->l_port = l_port; opl3->r_port = r_port; switch (opl3->hardware) { /* some hardware doesn't support timers */ case OPL3_HW_OPL3_SV: case OPL3_HW_OPL3_CS: case OPL3_HW_OPL3_FM801: opl3->command = &snd_opl3_command; break; default: opl3->command = &snd_opl2_command; if ((err = snd_opl3_detect(opl3)) < 0) { snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n", opl3->l_port, opl3->r_port); snd_device_free(card, opl3); return err; } /* detect routine returns correct hardware type */ switch (opl3->hardware & OPL3_HW_MASK) { case OPL3_HW_OPL3: case OPL3_HW_OPL4: opl3->command = &snd_opl3_command; } } snd_opl3_init(opl3); *ropl3 = opl3; return 0; }
static int __devinit jazz16_detect_board(unsigned long port, unsigned long mpu_port) { int err; int val; struct snd_sb chip; if (!request_region(port, 0x10, "jazz16")) { snd_printk(KERN_ERR "I/O port region is already in use.\n"); return -EBUSY; } /* just to call snd_sbdsp_command/reset/get_byte() */ chip.port = port; err = snd_sbdsp_reset(&chip); if (err < 0) for (val = 0; val < 4; val++) { err = jazz16_configure_ports(port, mpu_port, val); if (err < 0) break; err = snd_sbdsp_reset(&chip); if (!err) break; } if (err < 0) { err = -ENODEV; goto err_unmap; } if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) { err = -EBUSY; goto err_unmap; } val = snd_sbdsp_get_byte(&chip); if (val >= 0x30) snd_sbdsp_get_byte(&chip); if ((val & 0xf0) != 0x10) { err = -ENODEV; goto err_unmap; } if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) { err = -EBUSY; goto err_unmap; } snd_sbdsp_get_byte(&chip); err = snd_sbdsp_get_byte(&chip); snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n", val, err); err = 0; err_unmap: release_region(port, 0x10); return err; }
static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip) { int i; for (i = 1000; i; i--) if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) return inb(ES1688P(chip, READ)); snd_printd("es1688 get byte failed: 0x%lx = 0x%x!!!\n", ES1688P(chip, DATA_AVAIL), inb(ES1688P(chip, DATA_AVAIL))); return -ENODEV; }
static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, struct usb_host_interface *alts, struct audioformat *fmt, int rate) { struct usb_device *dev = chip->dev; unsigned char data[4]; int err, crate; int clock = snd_usb_clock_find_source(chip, fmt->clock); if (clock < 0) return clock; if (!uac_clock_source_is_valid(chip, clock)) { /* TODO: should we try to find valid clock setups by ourself? */ snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n", dev->devnum, iface, fmt->altsetting, clock); return -ENXIO; } data[0] = rate; data[1] = rate >> 8; data[2] = rate >> 16; data[3] = rate >> 24; if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, UAC2_CS_CONTROL_SAM_FREQ << 8, snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", dev->devnum, iface, fmt->altsetting, rate); return err; } if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, UAC2_CS_CONTROL_SAM_FREQ << 8, snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { #ifdef CONFIG_DEBUG_PRINTK snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", dev->devnum, iface, fmt->altsetting); #else ; #endif return err; } crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); if (crate != rate) snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); return 0; }
int ksnd_pcm_prepare(ksnd_pcm_t *kpcm) { int err; snd_pcm_substream_t *substream = kpcm->substream; err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); if (err < 0) { snd_printd("alsa_prepare: SNDRV_PCM_IOCTL_PREPARE failed\n"); return err; } return 0; }
int snd_hdmi_get_eld(struct hdmi_eld *eld, struct hda_codec *codec, hda_nid_t nid) { int i; int ret; int size; unsigned char *buf; if (!hdmi_eld_valid(codec, nid)) return -ENOENT; size = snd_hdmi_get_eld_size(codec, nid); if (size == 0) { /* wfg: workaround for ASUS P5E-VM HDMI board */ snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); size = 128; } if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); return -ERANGE; } if (!eld->lpcm_sad_ready) { snd_printd("snd_hdmi_get_eld() lpcm_sad_ready= %d\n", (eld->lpcm_sad_ready?1:0)); hdmi_update_lpcm_sad_eld(codec, nid, eld, size); } buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; for (i = 0; i < size; i++) buf[i] = hdmi_get_eld_byte(codec, nid, i); ret = hdmi_update_eld(eld, buf, size); kfree(buf); return ret; }