Beispiel #1
0
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;
}
Beispiel #2
0
/*
 * 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;
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #4
0
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;
}
Beispiel #7
0
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
0
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 {
Beispiel #13
0
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;
}
Beispiel #14
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;
}
Beispiel #15
0
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;
}
Beispiel #16
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;
}
Beispiel #17
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(&params, 0, sizeof(params));
	params.avail_min = 1;
	params.buffer_size = input_buffer_size;
	if ((err = snd_rawmidi_input_params(msynth->input_rfile.input, &params)) < 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;
}
Beispiel #18
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(&params, 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, &params)) < 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;
}
Beispiel #21
0
/* 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;
}
Beispiel #22
0
/* 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;
}
Beispiel #23
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)
		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;
}
Beispiel #24
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;

	/* 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;
}
Beispiel #25
0
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;
}
Beispiel #26
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;
}
Beispiel #27
0
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;
}
Beispiel #28
0
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;
}
Beispiel #29
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;
}
Beispiel #30
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;
}