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_setup_v4l2_decode_stream(struct ivtv_stream *s) { u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv *itv = s->itv; int datatype; u16 width; u16 height; if (s->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); width = itv->cxhdl.width; height = itv->cxhdl.height; /* set audio mode to left/stereo for dual/stereo mode. */ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); /* set number of internal decoder buffers */ ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0); /* prebuffering */ ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1); /* extract from user packets */ ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1); itv->vbi.dec_start = data[0]; IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n", itv->vbi.dec_start, data[1]); /* set decoder source settings */ /* Data type: 0 = mpeg from host, 1 = yuv from encoder, 2 = yuv_from_host */ switch (s->type) { case IVTV_DEC_STREAM_TYPE_YUV: if (itv->output_mode == OUT_PASSTHROUGH) { datatype = 1; } else { /* Fake size to avoid switching video standard */ datatype = 2; width = 720; height = itv->is_out_50hz ? 576 : 480; } IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); break; case IVTV_DEC_STREAM_TYPE_MPG: default: datatype = 0; break; } if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, width, height, itv->cxhdl.audio_properties)) { IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } /* Decoder sometimes dies here, so wait a moment */ ivtv_msleep_timeout(10, 0); /* Known failure point for firmware, so check */ return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream"); }
static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) { u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv *itv = s->itv; int datatype; u16 width; u16 height; if (s->vdev == NULL) return -EINVAL; IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); width = itv->cxhdl.width; height = itv->cxhdl.height; /* */ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); /* */ ivtv_vapi(itv, CX2341X_DEC_SET_DISPLAY_BUFFERS, 1, 0); /* */ ivtv_vapi(itv, CX2341X_DEC_SET_PREBUFFERING, 1, 1); /* */ ivtv_vapi_result(itv, data, CX2341X_DEC_EXTRACT_VBI, 1, 1); itv->vbi.dec_start = data[0]; IVTV_DEBUG_INFO("Decoder VBI RE-Insert start 0x%08x size 0x%08x\n", itv->vbi.dec_start, data[1]); /* */ /* */ switch (s->type) { case IVTV_DEC_STREAM_TYPE_YUV: if (itv->output_mode == OUT_PASSTHROUGH) { datatype = 1; } else { /* */ datatype = 2; width = 720; height = itv->is_out_50hz ? 576 : 480; } IVTV_DEBUG_INFO("Setup DEC YUV Stream data[0] = %d\n", datatype); break; case IVTV_DEC_STREAM_TYPE_MPG: default: datatype = 0; break; } if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, width, height, itv->cxhdl.audio_properties)) { IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); } /* */ ivtv_msleep_timeout(10, 0); /* */ return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream"); }