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; }
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; }