/* Selects the video input and output according to the current settings. */ void ivtv_video_set_io(struct ivtv *itv) { int inp = itv->active_input; u32 input; u32 type; v4l2_subdev_call(itv->sd_video, video, s_routing, itv->card->video_inputs[inp].video_input, 0, 0); type = itv->card->video_inputs[inp].video_type; if (type == IVTV_CARD_INPUT_VID_TUNER) { input = 0; /* Tuner */ } else if (type < IVTV_CARD_INPUT_COMPOSITE1) { input = 2; /* S-Video */ } else { input = 1; /* Composite */ } if (itv->card->hw_video & IVTV_HW_GPIO) ivtv_call_hw(itv, IVTV_HW_GPIO, video, s_routing, input, 0, 0); if (itv->card->hw_video & IVTV_HW_UPD64031A) { if (type == IVTV_CARD_INPUT_VID_TUNER || type >= IVTV_CARD_INPUT_COMPOSITE1) { /* Composite: GR on, connect to 3DYCS */ input = UPD64031A_GR_ON | UPD64031A_3DYCS_COMPOSITE; } else { /* S-Video: GR bypassed, turn it off */ input = UPD64031A_GR_OFF | UPD64031A_3DYCS_DISABLE; } input |= itv->card->gr_config; ivtv_call_hw(itv, IVTV_HW_UPD64031A, video, s_routing, input, 0, 0); } if (itv->card->hw_video & IVTV_HW_UPD6408X) { input = UPD64083_YCS_MODE; if (type > IVTV_CARD_INPUT_VID_TUNER && type < IVTV_CARD_INPUT_COMPOSITE1) { /* S-Video uses YCNR mode and internal Y-ADC, the upd64031a is not used. */ input |= UPD64083_YCNR_MODE; } else if (itv->card->hw_video & IVTV_HW_UPD64031A) { /* Use upd64031a output for tuner and composite(CX23416GYC only) inputs */ if (type == IVTV_CARD_INPUT_VID_TUNER || itv->card->type == IVTV_CARD_CX23416GYC) { input |= UPD64083_EXT_Y_ADC; } } ivtv_call_hw(itv, IVTV_HW_UPD6408X, video, s_routing, input, 0, 0); } }
/* Try to restart the card & restore previous settings */ static int ivtv_firmware_restart(struct ivtv *itv) { int rc = 0; v4l2_std_id std; if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) /* Display test image during restart */ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, SAA7127_INPUT_TYPE_TEST_IMAGE, itv->card->video_outputs[itv->active_output].video_output, 0); mutex_lock(&itv->udma.lock); rc = ivtv_firmware_init(itv); if (rc) { mutex_unlock(&itv->udma.lock); return rc; } /* Allow settings to reload */ ivtv_mailbox_cache_invalidate(itv); /* Restore encoder video standard */ std = itv->std; itv->std = 0; ivtv_s_std_enc(itv, &std); if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { ivtv_init_mpeg_decoder(itv); /* Restore decoder video standard */ std = itv->std_out; itv->std_out = 0; ivtv_s_std_dec(itv, &std); /* Restore framebuffer if active */ if (itv->ivtvfb_restore) itv->ivtvfb_restore(itv); /* Restore alpha settings */ ivtv_set_osd_alpha(itv); /* Restore normal output */ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, SAA7127_INPUT_TYPE_NORMAL, itv->card->video_outputs[itv->active_output].video_output, 0); } mutex_unlock(&itv->udma.lock); return rc; }
int ivtv_firmware_restart(struct ivtv *itv) { int rc = 0; v4l2_std_id std; if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) /* */ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, SAA7127_INPUT_TYPE_TEST_IMAGE, itv->card->video_outputs[itv->active_output].video_output, 0); mutex_lock(&itv->udma.lock); rc = ivtv_firmware_init(itv); if (rc) { mutex_unlock(&itv->udma.lock); return rc; } /* */ ivtv_mailbox_cache_invalidate(itv); /* */ std = itv->std; itv->std = 0; ivtv_s_std_enc(itv, &std); if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { ivtv_init_mpeg_decoder(itv); /* */ std = itv->std_out; itv->std_out = 0; ivtv_s_std_dec(itv, &std); /* */ if (itv->ivtvfb_restore) itv->ivtvfb_restore(itv); /* */ ivtv_set_osd_alpha(itv); /* */ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, SAA7127_INPUT_TYPE_NORMAL, itv->card->video_outputs[itv->active_output].video_output, 0); } mutex_unlock(&itv->udma.lock); return rc; }
/* Selects the audio input and output according to the current settings. */ void ivtv_audio_set_io(struct ivtv *itv) { const struct ivtv_card_audio_input *in; u32 input, output = 0; /* Determine which input to use */ if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) in = &itv->card->radio_input; else in = &itv->card->audio_inputs[itv->audio_input]; /* handle muxer chips */ input = in->muxer_input; if (itv->card->hw_muxer & IVTV_HW_M52790) output = M52790_OUT_STEREO; v4l2_subdev_call(itv->sd_muxer, audio, s_routing, input, output, 0); input = in->audio_input; output = 0; if (itv->card->hw_audio & IVTV_HW_MSP34XX) output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, input, output, 0); }
int ivtv_v4l2_close(struct file *filp) { struct ivtv_open_id *id = filp->private_data; struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[id->type]; IVTV_DEBUG_FILE("close %s\n", s->name); v4l2_prio_close(&itv->prio, &id->prio); /* Easy case first: this stream was never claimed by us */ if (s->id != id->open_id) { kfree(id); return 0; } /* 'Unclaim' this stream */ /* Stop radio */ mutex_lock(&itv->serialize_lock); if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { /* Closing radio device, return to TV mode */ ivtv_mute(itv); /* Mark that the radio is no longer in use */ clear_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); /* Switch tuner to TV */ ivtv_call_all(itv, core, s_std, itv->std); /* Select correct audio input (i.e. TV tuner or Line in) */ ivtv_audio_set_io(itv); if (itv->hw_flags & IVTV_HW_SAA711X) { ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, SAA7115_FREQ_32_11_MHZ, 0); } if (atomic_read(&itv->capturing) > 0) { /* Undo video mute */ ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, itv->params.video_mute | (itv->params.video_mute_yuv << 8)); } /* Done! Unmute and continue. */ ivtv_unmute(itv); ivtv_release_stream(s); } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); /* If all output streams are closed, and if the user doesn't have IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */ if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) { /* disable CC on TV-out */ ivtv_disable_cc(itv); } } else { ivtv_stop_capture(id, 0); } kfree(id); mutex_unlock(&itv->serialize_lock); return 0; }
static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc) { struct v4l2_sliced_vbi_data data; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return; data.id = V4L2_SLICED_CAPTION_525; data.field = 0; data.line = (mode & 1) ? 21 : 0; data.data[0] = cc->odd[0]; data.data[1] = cc->odd[1]; ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); data.field = 1; data.line = (mode & 2) ? 21 : 0; data.data[0] = cc->even[0]; data.data[1] = cc->even[1]; ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); }
static void ivtv_set_vps(struct ivtv *itv, int enabled) { struct v4l2_sliced_vbi_data data; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return; data.id = V4L2_SLICED_VPS; data.field = 0; data.line = enabled ? 16 : 0; data.data[2] = itv->vbi.vps_payload.data[0]; data.data[8] = itv->vbi.vps_payload.data[1]; data.data[9] = itv->vbi.vps_payload.data[2]; data.data[10] = itv->vbi.vps_payload.data[3]; data.data[11] = itv->vbi.vps_payload.data[4]; ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); }
static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) { struct v4l2_sliced_vbi_data data; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return; if ((itv->std & V4L2_STD_625_50) && !enabled) { enabled = 1; mode = 0x08; } data.id = V4L2_SLICED_WSS_625; data.field = 0; data.line = enabled ? 23 : 0; data.data[0] = mode & 0xff; data.data[1] = (mode >> 8) & 0xff; ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data); }
static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode) { struct v4l2_sliced_vbi_data data; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return; /* When using a 50 Hz system, always turn on the wide screen signal with 4x3 ratio as the default. Turning this signal on and off can confuse certain TVs. As far as I can tell there is no reason not to transmit this signal. */ if ((itv->std_out & V4L2_STD_625_50) && !enabled) { enabled = 1; mode = 0x08; /* 4x3 full format */ } data.id = V4L2_SLICED_WSS_625; data.field = 0; data.line = enabled ? 23 : 0; data.data[0] = mode & 0xff; data.data[1] = (mode >> 8) & 0xff; ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data); }
static int ivtv_open(struct file *filp) { struct video_device *vdev = video_devdata(filp); struct ivtv_stream *s = video_get_drvdata(vdev); struct ivtv *itv = s->itv; struct ivtv_open_id *item; int res = 0; IVTV_DEBUG_FILE("open %s\n", s->name); if (ivtv_init_on_first_open(itv)) { IVTV_ERR("Failed to initialize on device %s\n", video_device_node_name(vdev)); return -ENXIO; } #ifdef CONFIG_VIDEO_ADV_DEBUG /* Unless ivtv_fw_debug is set, error out if firmware dead. */ if (ivtv_fw_debug) { IVTV_WARN("Opening %s with dead firmware lockout disabled\n", video_device_node_name(vdev)); IVTV_WARN("Selected firmware errors will be ignored\n"); } else { #else if (1) { #endif res = ivtv_firmware_check(itv, "ivtv_serialized_open"); if (res == -EAGAIN) res = ivtv_firmware_check(itv, "ivtv_serialized_open"); if (res < 0) return -EIO; } if (s->type == IVTV_DEC_STREAM_TYPE_MPG && test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) return -EBUSY; if (s->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) return -EBUSY; if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { if (read_reg(0x82c) == 0) { IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); /* return -ENODEV; */ } ivtv_udma_alloc(itv); } /* Allocate memory */ item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); if (NULL == item) { IVTV_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; } v4l2_fh_init(&item->fh, &s->vdev); item->itv = itv; item->type = s->type; filp->private_data = &item->fh; v4l2_fh_add(&item->fh); if (item->type == IVTV_ENC_STREAM_TYPE_RAD && v4l2_fh_is_singular_file(filp)) { if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { if (atomic_read(&itv->capturing) > 0) { /* switching to radio while capture is in progress is not polite */ v4l2_fh_del(&item->fh); v4l2_fh_exit(&item->fh); kfree(item); return -EBUSY; } } /* Mark that the radio is being used. */ set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); /* We have the radio */ ivtv_mute(itv); /* Switch tuner to radio */ ivtv_call_all(itv, tuner, s_radio); /* Select the correct audio input (i.e. radio tuner) */ ivtv_audio_set_io(itv); if (itv->hw_flags & IVTV_HW_SAA711X) { ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL); } /* Done! Unmute and continue. */ ivtv_unmute(itv); } /* YUV or MPG Decoding Mode? */ if (s->type == IVTV_DEC_STREAM_TYPE_MPG) { clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); /* For yuv, we need to know the dma size before we start */ itv->dma_data_req_size = 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); itv->yuv_info.stream_size = 0; } return 0; } int ivtv_v4l2_open(struct file *filp) { struct video_device *vdev = video_devdata(filp); int res; if (mutex_lock_interruptible(vdev->lock)) return -ERESTARTSYS; res = ivtv_open(filp); mutex_unlock(vdev->lock); return res; } void ivtv_mute(struct ivtv *itv) { if (atomic_read(&itv->capturing)) ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1); IVTV_DEBUG_INFO("Mute\n"); } void ivtv_unmute(struct ivtv *itv) { if (atomic_read(&itv->capturing)) { ivtv_msleep_timeout(100, 0); ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12); ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0); } IVTV_DEBUG_INFO("Unmute\n"); }
static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) { struct ivtv *itv = s->itv; struct ivtv_open_id *item; IVTV_DEBUG_FILE("open %s\n", s->name); if (s->type == IVTV_DEC_STREAM_TYPE_MPG && test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) return -EBUSY; if (s->type == IVTV_DEC_STREAM_TYPE_YUV && test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) return -EBUSY; if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { if (read_reg(0x82c) == 0) { IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); /* return -ENODEV; */ } ivtv_udma_alloc(itv); } /* Allocate memory */ item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); if (NULL == item) { IVTV_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; } item->itv = itv; item->type = s->type; v4l2_prio_open(&itv->prio, &item->prio); item->open_id = itv->open_id++; filp->private_data = item; if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { /* Try to claim this stream */ if (ivtv_claim_stream(item, item->type)) { /* No, it's already in use */ kfree(item); return -EBUSY; } if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { if (atomic_read(&itv->capturing) > 0) { /* switching to radio while capture is in progress is not polite */ ivtv_release_stream(s); kfree(item); return -EBUSY; } } /* Mark that the radio is being used. */ set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags); /* We have the radio */ ivtv_mute(itv); /* Switch tuner to radio */ ivtv_call_all(itv, tuner, s_radio); /* Select the correct audio input (i.e. radio tuner) */ ivtv_audio_set_io(itv); if (itv->hw_flags & IVTV_HW_SAA711X) { ivtv_call_hw(itv, IVTV_HW_SAA711X, video, s_crystal_freq, SAA7115_FREQ_32_11_MHZ, SAA7115_FREQ_FL_APLL); } /* Done! Unmute and continue. */ ivtv_unmute(itv); } /* YUV or MPG Decoding Mode? */ if (s->type == IVTV_DEC_STREAM_TYPE_MPG) { clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); } else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); /* For yuv, we need to know the dma size before we start */ itv->dma_data_req_size = 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); itv->yuv_info.stream_size = 0; } return 0; }