static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
{
	int err;
	struct pcxhr_rmh rmh;
	struct pcxhr_pipe *pipe = &chip->playback_pipe;
	int left, right;

	if (chip->digital_playback_active[idx][0])
		left = chip->digital_playback_volume[idx][0];
	else
		left = PCXHR_DIGITAL_LEVEL_MIN;
	if (chip->digital_playback_active[idx][1])
		right = chip->digital_playback_volume[idx][1];
	else
		right = PCXHR_DIGITAL_LEVEL_MIN;

	pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
	
	pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
	
	rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
	rmh.cmd[2]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
	rmh.cmd[2] |= (left << 10);
	rmh.cmd[3]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
	rmh.cmd[3] |= right;
	rmh.cmd_len = 4;

	err = pcxhr_send_msg(chip->mgr, &rmh);
	if (err < 0) {
		snd_printk(KERN_DEBUG "error update_playback_stream_level "
			   "card(%d) err(%x)\n", chip->chip_idx, err);
		return -EINVAL;
	}
	return 0;
}
/*
 *  allocate a playback/capture pipe (pcmp0/pcmc0)
 */
static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe,
				    int is_capture, int pin)
{
	int stream_count, audio_count;
	int err;
	struct pcxhr_rmh rmh;

	if (is_capture) {
		stream_count = 1;
		if (mgr->mono_capture)
			audio_count = 1;
		else
			audio_count = 2;
	} else {
		stream_count = PCXHR_PLAYBACK_STREAMS;
		audio_count = 2;	/* always stereo */
	}
	snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p');
	pipe->is_capture = is_capture;
	pipe->first_audio = pin;
	/* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
	pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
	pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); 
	err = pcxhr_send_msg(mgr, &rmh);
	if (err < 0) {
		snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err );
		return err;
	}
	pipe->status = PCXHR_PIPE_DEFINED;

	return 0;
}
static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
{
	struct pcxhr_rmh rmh;
	int capture_mask = 0;
	int playback_mask = 0;
	int err = 0;

	if (pipe->is_capture)
		capture_mask  = (1 << pipe->first_audio);
	else
		playback_mask = (1 << pipe->first_audio);

	/* stop one pipe */
	err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
	if (err < 0)
		snd_printk(KERN_ERR "error stopping pipe!\n");
	/* release the pipe */
	pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
	pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0);
	err = pcxhr_send_msg(mgr, &rmh);
	if (err < 0)
		snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err);
	pipe->status = PCXHR_PIPE_UNDEFINED;
	return err;
}
예제 #4
0
파일: pcxhr_mixer.c 프로젝트: 3null/linux
static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
					 int capture, int channel)
{
	int err;
	struct pcxhr_rmh rmh;
	struct pcxhr_pipe *pipe;

	if (capture)
		pipe = &chip->capture_pipe[0];
	else
		pipe = &chip->playback_pipe;

	pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
	/* add channel mask */
	pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
				  1 << (channel + pipe->first_audio));
	/* TODO : if mask (3 << pipe->first_audio) is used, left and right
	 * channel will be programmed to the same params */
	if (capture) {
		rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
		/* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
		 * (capture pipe level) */
		rmh.cmd[2] = chip->digital_capture_volume[channel];
	} else {
		rmh.cmd[0] |=	VALID_AUDIO_IO_MONITOR_LEVEL |
				VALID_AUDIO_IO_MUTE_MONITOR_1;
		/* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
		 * not yet handled (playback pipe level)
		 */
		rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
		if (chip->monitoring_active[channel] == 0)
			rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
	}
	rmh.cmd_len = 3;

	err = pcxhr_send_msg(chip->mgr, &rmh);
	if (err < 0) {
		dev_dbg(chip->card->dev,
			"error update_audio_level(%d) err=%x\n",
			   chip->chip_idx, err);
		return -EINVAL;
	}
	return 0;
}
static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
					 int capture, int channel)
{
	int err;
	struct pcxhr_rmh rmh;
	struct pcxhr_pipe *pipe;

	if (capture)
		pipe = &chip->capture_pipe[0];
	else
		pipe = &chip->playback_pipe;

	pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
	
	pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
				  1 << (channel + pipe->first_audio));
	if (capture) {
		rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
		rmh.cmd[2] = chip->digital_capture_volume[channel];
	} else {
		rmh.cmd[0] |=	VALID_AUDIO_IO_MONITOR_LEVEL |
				VALID_AUDIO_IO_MUTE_MONITOR_1;
		rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
		if (chip->monitoring_active[channel] == 0)
			rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
	}
	rmh.cmd_len = 3;

	err = pcxhr_send_msg(chip->mgr, &rmh);
	if (err < 0) {
		snd_printk(KERN_DEBUG "error update_audio_level(%d) err=%x\n",
			   chip->chip_idx, err);
		return -EINVAL;
	}
	return 0;
}