コード例 #1
0
static void unicam_videobuf_queue(struct vb2_buffer *vb)
{
	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct unicam_camera_dev *unicam_dev = ici->priv;
	struct unicam_camera_buffer *buf = to_unicam_camera_vb(vb);
	unsigned long flags;

	dprintk("-enter");
	dprintk("vb=0x%p vbuf=0x%p pbuf=0x%p size=%lu", vb,
		vb2_plane_vaddr(vb, 0), (void *)vb2_dma_contig_plane_dma_addr(vb,
									   0),
		vb2_get_plane_payload(vb, 0));

	spin_lock_irqsave(&unicam_dev->lock, flags);
	list_add_tail(&buf->queue, &unicam_dev->capture);

	if (!unicam_dev->active) {
		unicam_dev->active = vb;
		/* use this buffer to trigger capture */
		/* Configure HW only is streamon has been done
		 * else only update active, HW would be configured
		 * by streamon  */
		if(unicam_dev->streaming){
			unicam_camera_update_buf(unicam_dev);
			if (unicam_dev->if_params.if_mode ==
				V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)
				unicam_camera_capture(unicam_dev);
		}
	}
	spin_unlock_irqrestore(&unicam_dev->lock, flags);
	dprintk("-exit");
}
コード例 #2
0
static int unicam_camera_set_crop(struct soc_camera_device *icd,
				struct v4l2_crop *crop)
{
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct unicam_camera_dev *unicam_dev = ici->priv;

	if(crop == NULL)
		return -EINVAL;
	unicam_dev->crop = *crop;
	return 0;
#if 0
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
	pr_info("Configuring crop to %d %d\n", crop->c.width, crop->c.height);
	pr_info("Configuring top left to %d %d\n", crop->c.top, crop->c.left);
	 v4l2_subdev_call(sd, video, s_stream, 0);
	spin_lock_irqsave(&unicam_dev->lock, flags);
	unicam_dev->crop = *crop;
	if(unicam_dev->streaming){
		pr_info("Stopping stream\n");
		unicam_stop();
	}
	/* Configure new crop parameters */
	mm_csi0_set_windowing_vertical(unicam_dev->crop.c.top,
			(unicam_dev->crop.c.top + unicam_dev->crop.c.height));
	mm_csi0_cfg_pipeline_unpack(PIX_UNPACK_NONE);
	mm_csi0_cfg_pipeline_dpcm_dec(DPCM_DEC_NONE);
	mm_csi0_set_windowing_horizontal(unicam_dev->crop.c.left,
			(unicam_dev->crop.c.left + unicam_dev->crop.c.width));
	mm_csi0_cfg_pipeline_dpcm_enc(DPCM_ENC_NONE);
	mm_csi0_cfg_pipeline_pack(PIX_PACK_NONE);
	mm_csi0_start_rx();

	/* Re-configure buffer parameters */
	unicam_camera_update_buf(unicam_dev);
	/* set data capture */
	if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) {
		idesc.fsi = 1;
		idesc.fei = 1;
		idesc.lci = 0;
		idesc.die = 1;
		idesc.dataline = 2;
		mm_csi0_config_int(&idesc, IMAGE_BUFFER);
		mm_csi0_config_int(&idesc, DATA_BUFFER);
		unicam_camera_capture(unicam_dev);
	} else {
		idesc.fsi = 0;
		idesc.fei = 0;
		idesc.lci = unicam_dev->icd->user_height;
		idesc.die = 0;
		idesc.dataline = 0;
		mm_csi0_config_int(&idesc, IMAGE_BUFFER);
	}

	spin_unlock_irqrestore(&unicam_dev->lock, flags);
	 v4l2_subdev_call(sd, video, s_stream, 1);
	return 0;
#endif
}
コード例 #3
0
static void unicam_videobuf_queue(struct vb2_buffer *vb)
{
	struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct unicam_camera_dev *unicam_dev = ici->priv;
	struct unicam_camera_buffer *buf = to_unicam_camera_vb(vb);
	unsigned long flags;
	struct int_desc idesc;

	pr_debug("-enter");
	pr_debug("vb=0x%p pbuf=0x%p size=%lu", vb,
			(void *)vb2_plane_dma_addr(vb, 0),
			vb2_get_plane_payload(vb, 0));
	/* pr_info("Q 0x%x\n", vb2_plane_paddr(vb, 0)); */
	spin_lock_irqsave(&unicam_dev->lock, flags);
	list_add_tail(&buf->queue, &unicam_dev->capture);
	if(unicam_dev->cap_mode && unicam_dev->cap_done){
		pr_info("Cap mode and already captured\n");
		spin_unlock_irqrestore(&unicam_dev->lock, flags);
		return;
	}
	if ((!unicam_dev->active)) {
		unicam_dev->active = vb;
		unicam_camera_update_buf(unicam_dev);
		if (atomic_read(&unicam_dev->streaming)) {
			mm_csi0_start_rx();
		/* set data capture */
			if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) {
				idesc.fsi = 1;
				idesc.fei = 1;
				idesc.lci = 0;
				idesc.die = 1;
				idesc.dataline = 2;
				mm_csi0_config_int(&idesc, IMAGE_BUFFER);
				mm_csi0_config_int(&idesc, DATA_BUFFER);
				unicam_camera_capture(unicam_dev);
			} else {
				idesc.fsi = 0;
				idesc.fei = 0;
				idesc.lci = unicam_dev->icd->user_height;
				idesc.die = 0;
				idesc.dataline = 0;
				mm_csi0_config_int(&idesc, IMAGE_BUFFER);
			}
		}
	}
	spin_unlock_irqrestore(&unicam_dev->lock, flags);
	pr_debug("-exit");
}
コード例 #4
0
int unicam_videobuf_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
	struct unicam_camera_dev *unicam_dev = ici->priv;
	struct v4l2_subdev_sensor_interface_parms if_params;
	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
	int ret;
	int thumb;
	unsigned long flags;

	CSL_CAM_INTF_CFG_st_t csl_cam_intf_cfg_st;
	CSL_CAM_LANE_CONTROL_st_t cslCamLaneCtrl_st;
	CSL_CAM_PIPELINE_st_t cslCamPipeline;
	CSL_CAM_IMAGE_ID_st_t cslCamImageCtrl;
	CSL_CAM_DATA_st_t cslCamDataCtrl;
	CSL_CAM_FRAME_st_t cslCamFrame;

	dprintk("-enter");
	iprintk("enabling csi");

	spin_lock_irqsave(&unicam_dev->lock, flags);
	unicam_dev->stopping = false;
	spin_unlock_irqrestore(&unicam_dev->lock, flags);
	if (csl_cam_init()) {
		dev_err(unicam_dev->dev, "error initializing csl camera\n");
		return -1;
	}

	ret = v4l2_subdev_call(sd, video, s_stream, 1);
	if (ret < 0 && ret != -ENOIOCTLCMD) {
		dev_err(unicam_dev->dev, "error on s_stream(%d)\n", ret);
		spin_lock_irqsave(&unicam_dev->lock, flags);
		unicam_dev->active = NULL;
		unicam_dev->stopping = true;
		spin_unlock_irqrestore(&unicam_dev->lock, flags);
		if (csl_cam_exit())
			dev_err(unicam_dev->dev, "csl_cam_exit(): FAILED\n");
		return ret;
	}

	/* get the sensor interface information */
	ret = v4l2_subdev_call(sd, sensor, g_interface_parms, &if_params);
	if (ret < 0) {
		dev_err(unicam_dev->dev, "error on g_inferface_params(%d)\n",
			ret);
		return ret;
	}

	unicam_dev->if_params = if_params;

	/* set camera interface parameters */
	memset(&csl_cam_intf_cfg_st, 0, sizeof(CSL_CAM_INTF_CFG_st_t));

	/* we only support serial and csi2 sensor */
	if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL)
	    && (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)) {
		csl_cam_intf_cfg_st.intf = CSL_CAM_INTF_CSI;
	} else if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL)
	    && (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1)) {
		csl_cam_intf_cfg_st.intf = CSL_CAM_INTF_CCP;
	} else {
		dev_err(unicam_dev->dev,
			"CSI2 iface only supported,requested iface %d mode=%d\n",
			unicam_dev->if_params.if_type,
			unicam_dev->if_params.if_mode);
		return -EINVAL;
	}

	if (unicam_dev->if_params.parms.serial.channel == 0)
		csl_cam_intf_cfg_st.afe_port = CSL_CAM_PORT_AFE_0;
	else if (unicam_dev->if_params.parms.serial.channel == 1)
		csl_cam_intf_cfg_st.afe_port = CSL_CAM_PORT_AFE_1;
	else {
		dev_err(unicam_dev->dev,
			"receiver only supports two channels, request channel=%d\n",
			unicam_dev->if_params.parms.serial.channel);
		return -EINVAL;
	}

	csl_cam_intf_cfg_st.frame_time_out = 1000;

	/* open camera interface */
	csl_cam_intf_cfg_st.p_cpi_intf_st = NULL;

	if ((unicam_dev->if_params.if_type == V4L2_SUBDEV_SENSOR_SERIAL)
	    && (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)) {
		if (unicam_dev->if_params.parms.serial.lanes == 1)
			csl_cam_intf_cfg_st.input_mode =
				CSL_CAM_INPUT_SINGLE_LANE;
		else if (unicam_dev->if_params.parms.serial.lanes == 2)
			csl_cam_intf_cfg_st.input_mode =
				CSL_CAM_INPUT_DUAL_LANE;
		else {
			dev_err(unicam_dev->dev,
				"receiver only supports max 2 lanes, requested lanes(%d)\n",
				unicam_dev->if_params.parms.serial.lanes);
			return -EINVAL;
		}
	} else {
		 csl_cam_intf_cfg_st.input_mode = CSL_CAM_INPUT_MODE_DATA_CLOCK;
	}

	if (csl_cam_open(&csl_cam_intf_cfg_st, &unicam_dev->cslCamHandle)) {
		dev_err(unicam_dev->dev, "%s: csl_cam_open(): ERROR\n",
			__func__);
		return -1;
	}

	/* set data lane timing */
	cslCamLaneCtrl_st.lane_select = CSL_CAM_DATA_LANE_0;
	cslCamLaneCtrl_st.lane_control = CSL_CAM_LANE_HS_TERM_TIME;
	cslCamLaneCtrl_st.param =
	    unicam_dev->if_params.parms.serial.hs_term_time;

	dprintk("hs_term_time is set to = %d\n", cslCamLaneCtrl_st.param);

	if (csl_cam_set_lane_control
	    (unicam_dev->cslCamHandle, &cslCamLaneCtrl_st)) {
		dev_err(unicam_dev->dev,
			"csl_cam_set_lane_control(): FAILED\n");
		return -1;
	}

	if (unicam_dev->if_params.parms.serial.hs_settle_time != 0) {
		cslCamLaneCtrl_st.lane_select = CSL_CAM_DATA_LANE_0;
		cslCamLaneCtrl_st.lane_control = CSL_CAM_LANE_HS_SETTLE_TIME;
		cslCamLaneCtrl_st.param =
			unicam_dev->if_params.parms.serial.hs_settle_time;
		dprintk("hs_settle_time is set to = %d\n",
					cslCamLaneCtrl_st.param);
		if (csl_cam_set_lane_control
		    (unicam_dev->cslCamHandle, &cslCamLaneCtrl_st)) {
			dev_err(unicam_dev->dev,
				"csl_cam_set_lane_control(): FAILED\n");
			return -1;
		}
	}

	/* pipelince decode */
	cslCamPipeline.decode = CSL_CAM_DEC_NONE;
	cslCamPipeline.unpack = CSL_CAM_PIXEL_NONE;
	cslCamPipeline.pack = CSL_CAM_PIXEL_NONE;
	cslCamPipeline.dec_adv_predictor = FALSE;

	cslCamPipeline.encode = CSL_CAM_ENC_NONE;
	cslCamPipeline.enc_adv_predictor = FALSE;
	cslCamPipeline.encode_blk_size = 0x0000;

	/* set pipeline */
	if (csl_cam_set_pipeline_control
	    (unicam_dev->cslCamHandle, &cslCamPipeline)) {
		dev_err(unicam_dev->dev,
			"csl_cam_set_pipeline_control(): FAILE\n");
		return -1;
	}

	/* set image identifier (CSI mode only) */
	memset(&cslCamImageCtrl, 0, sizeof(CSL_CAM_IMAGE_ID_st_t));

	/* if thumbnail is supported we expect
	 * thumbnail to be in image ptr format of thumbnails is yuv422
	 * format is checked in try format.
	 * in case where thumbnail is not supported we get jpeg
	 * image in data pointer. so we set the id as 0
	 */

	thumb = 0;
	ret =
	    v4l2_subdev_call(sd, core, ioctl, VIDIOC_THUMB_SUPPORTED,
			     (void *)&thumb);
	if (ret < 0)
		dev_warn(unicam_dev->dev,
			 "sensor returns error(%d) for VIDIOC_THUMB_SUPPORTED\n",
			 ret);

	if ((icd->current_fmt->code == V4L2_MBUS_FMT_JPEG_1X8)
	    && (thumb == 0))
		cslCamImageCtrl.image_data_id0 = 0x0;
		/* thumbnail not supported */
	else
		cslCamImageCtrl.image_data_id0 = 0x1E;

	if (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1)
		cslCamImageCtrl.image_data_id0 = 0x0;	/* CCP2 channel ID 0 */


	if (csl_cam_set_image_type_control
	    (unicam_dev->cslCamHandle, &cslCamImageCtrl)) {
		dev_err(unicam_dev->dev,
			"csl_cam_set_image_type_control(): FAILED\n");
		return -1;
	}

	/* set data capture */
	cslCamDataCtrl.int_enable = (CSL_CAM_INTERRUPT_t) (CSL_CAM_INT_DISABLE);
	if (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) {
		cslCamDataCtrl.line_count = 2;
		cslCamDataCtrl.fsp_decode_enable = FALSE;
	} else {
		cslCamDataCtrl.line_count = 0;
		cslCamDataCtrl.fsp_decode_enable = TRUE;
	}
	cslCamDataCtrl.data_id = 0x00;
	cslCamDataCtrl.data_size = CSL_CAM_PIXEL_8BIT;

	if (csl_cam_set_data_type_control
	    (unicam_dev->cslCamHandle, &cslCamDataCtrl)) {
		dev_err(unicam_dev->dev,
			"csl_cam_set_data_type_control(): FAILED\n");
		return -1;
	}

	/* start receiver */
	if (csl_cam_rx_start(unicam_dev->cslCamHandle)) {
		dev_err(unicam_dev->dev, "csl_cam_rx_start(): FAILED\n");
		return -1;
	}

	/* Enabling sensor after enabling unicam */
/*
	ret = v4l2_subdev_call(sd, video, s_stream, 1);
	if (ret < 0 && ret != -ENOIOCTLCMD) {
		dev_err(unicam_dev->dev, "error on s_stream(%d)\n", ret);
		return ret;
	}
*/
	if (unicam_dev->if_params.if_mode ==
		V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI1) {
		cslCamFrame.int_enable = CSL_CAM_INT_LINE_COUNT;
		/* CSL_CAM_INT_FRAME_END | CSL_CAM_INT_FRAME_START;
		//CSL_CAM_INT_LINE_COUNT;
		cslCamFrame.int_line_count =
		(unicam_dev->icd->user_height - 1);*/
		cslCamFrame.int_line_count = (unicam_dev->icd->user_height);
		cslCamFrame.capture_mode = CSL_CAM_CAPTURE_MODE_NORMAL;
		/* CSL_CAM_CAPTURE_MODE_NORMAL */
		if (csl_cam_set_frame_control(
			unicam_dev->cslCamHandle, &cslCamFrame)) {
			dev_err(unicam_dev->dev,
			"csl_cam_set_frame_control(): FAILED\n");
			return -1;
		}

	}
	/* Configure HW if buffer is queued ahead of streamon */
	spin_lock_irqsave(&unicam_dev->lock, flags);
	if(unicam_dev->active){
		unicam_camera_update_buf(unicam_dev);
		if (unicam_dev->if_params.if_mode ==
			V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2)
			unicam_camera_capture(unicam_dev);
	}
	unicam_dev->streaming = 1;
	spin_unlock_irqrestore(&unicam_dev->lock, flags);

	csl_cam_register_display(unicam_dev->cslCamHandle);
	dprintk("-exit");
	return 0;
}