static int snd_cx18_mixer_tv_vol_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl); struct cx18 *cx = to_cx18(cxsc->v4l2_dev); struct v4l2_control vctrl; int ret; vctrl.id = V4L2_CID_AUDIO_VOLUME; vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); snd_cx18_lock(cxsc); /* Fetch current state */ ret = v4l2_g_ctrl(cx->sd_av->ctrl_handler, &vctrl); if (ret || (cx18_av_vol_to_dB(vctrl.value) != uctl->value.integer.value[0])) { /* Set, if needed */ vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); ret = v4l2_s_ctrl(cx->sd_av->ctrl_handler, &vctrl); if (!ret) ret = 1; /* Indicate control was changed w/o error */ } snd_cx18_unlock(cxsc); return ret; }
static int snd_cx18_pcm_capture_open(struct snd_pcm_substream *substream) { struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; struct cx18 *cx = to_cx18(v4l2_dev); struct cx18_stream *s; struct cx18_open_id item; int ret; /* Instruct the cx18 to start sending packets */ snd_cx18_lock(cxsc); s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; item.cx = cx; item.type = s->type; item.open_id = cx->open_id++; /* See if the stream is available */ if (cx18_claim_stream(&item, item.type)) { /* No, it's already in use */ snd_cx18_unlock(cxsc); return -EBUSY; } if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) || test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) { /* We're already streaming. No additional action required */ snd_cx18_unlock(cxsc); return 0; } runtime->hw = snd_cx18_hw_capture; snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); cxsc->capture_pcm_substream = substream; runtime->private_data = cx; cx->pcm_announce_callback = cx18_alsa_announce_pcm_data; /* Not currently streaming, so start it up */ set_bit(CX18_F_S_STREAMING, &s->s_flags); ret = cx18_start_v4l2_encode_stream(s); snd_cx18_unlock(cxsc); return ret; }
static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); int ret; snd_cx18_lock(cxsc); ret = snd_pcm_lib_ioctl(substream, cmd, arg); snd_cx18_unlock(cxsc); return ret; }
static int snd_cx18_mixer_tv_vol_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *uctl) { struct snd_cx18_card *cxsc = snd_kcontrol_chip(kctl); struct cx18 *cx = to_cx18(cxsc->v4l2_dev); struct v4l2_control vctrl; int ret; vctrl.id = V4L2_CID_AUDIO_VOLUME; vctrl.value = dB_to_cx18_av_vol(uctl->value.integer.value[0]); snd_cx18_lock(cxsc); ret = v4l2_g_ctrl(cx->sd_av->ctrl_handler, &vctrl); snd_cx18_unlock(cxsc); if (!ret) uctl->value.integer.value[0] = cx18_av_vol_to_dB(vctrl.value); return ret; }
static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) { struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); struct v4l2_device *v4l2_dev = cxsc->v4l2_dev; struct cx18 *cx = to_cx18(v4l2_dev); struct cx18_stream *s; /* Instruct the cx18 to stop sending packets */ snd_cx18_lock(cxsc); s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM]; cx18_stop_v4l2_encode_stream(s, 0); clear_bit(CX18_F_S_STREAMING, &s->s_flags); cx18_release_stream(s); cx->pcm_announce_callback = NULL; snd_cx18_unlock(cxsc); return 0; }