int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;

	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		printk("Register INIT\n");
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
		
		
		if (NULL != s_ctrl->func_tbl->sensor_download_af_firmware)
			{
	 
 	               pr_err("+++++download af firmware+++++++++++ %s \n",__func__);

		      rc=s_ctrl->func_tbl->sensor_download_af_firmware(s_ctrl);
        		if(!rc)
        		{
        		  printk("%s:ov5640 AF FW download success\n",__func__);
			#ifdef CONFIG_OV5640	
        		  download_flag=1;   //download success is 1
        		 #endif
        		}
		}
		

		csi_config = 0;
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		printk("PERIODIC : %d\n", res);
		 printk("%s:sensor_name = %s, res = %d\n",__func__, s_ctrl->sensordata->sensor_name, res);

		msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
		msleep(30);
		if (!csi_config) {
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			printk("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			printk("CSI config is done\n");
			mb();
			msleep(30);
			csi_config = 1;
		}
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE,
			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);

		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(50);
	}
	return rc;
}
int32_t hi542_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;

	if (update_type == MSM_SENSOR_REG_INIT) {
		CDBG("Register INIT\n");
		printk("##### %s line%d: Register INIT\n",__func__,__LINE__);
		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
		msleep(66);
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		printk("##### %s line%d: begin to write init setting !\n",__func__,__LINE__);
		msm_sensor_write_init_settings(s_ctrl);
		printk("##### %s line%d: init setting end !\n",__func__,__LINE__);
		csi_config = 0;
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		CDBG("PERIODIC : %d\n", res);
		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
		msleep(66);
		msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
		msleep(100);
		if (!csi_config) {
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			CDBG("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			CDBG("CSI config is done\n");
			mb();
			msleep(30);
			csi_config = 1;
		}

		//zxj ++
		#ifdef ORIGINAL_VERSION
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE,
			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);
		#else
		printk("##### %s line%d: vfe_clk_rate = %d\n",__func__,__LINE__,vfe_clk_rate);
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &vfe_clk_rate);	
		#endif
		//zxj --
		
		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(100);
	}
	return rc;
}
Beispiel #3
0
int32_t mt9t113_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	pr_err("%s %d\n", __func__,update_type);
	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		//s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		/*uesd to write special initialization arrays of some sensors*/
		if(s_ctrl->func_tbl->sensor_write_init_settings)
		{
			s_ctrl->func_tbl->sensor_write_init_settings(s_ctrl);
		}
		else
		{
			msm_sensor_write_init_settings(s_ctrl);
		}
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
#if 0
		if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
			s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
			s_ctrl->curr_csi_params->csid_params.lane_assign =
				s_ctrl->sensordata->sensor_platform_info->
				csi_lane_params->csi_lane_assign;
			s_ctrl->curr_csi_params->csiphy_params.lane_mask =
				s_ctrl->sensordata->sensor_platform_info->
				csi_lane_params->csi_lane_mask;
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSID_CFG,
				&s_ctrl->curr_csi_params->csid_params);
			mb();
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIPHY_CFG,
				&s_ctrl->curr_csi_params->csiphy_params);
			mb();
			msleep(20);
		}
#endif
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(30);
	}
	pr_err("%s rc = %d\n", __func__,rc);
	return rc;
}
int32_t imx111_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	printk("%s: E: update_type=%d, res=%d\n", __func__, update_type, res);

	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		if (res == 0) {
			msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
				(struct msm_camera_i2c_reg_conf *)
				imx111_comm_confs[0].conf,
				imx111_comm_confs[0].size,
				imx111_comm_confs[0].data_type);
		} else {
			msm_sensor_write_res_settings(s_ctrl, res);
			if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
				s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
				s_ctrl->curr_csi_params->csid_params.lane_assign =
					s_ctrl->sensordata->sensor_platform_info->
					csi_lane_params->csi_lane_assign;
				s_ctrl->curr_csi_params->csiphy_params.lane_mask =
					s_ctrl->sensordata->sensor_platform_info->
					csi_lane_params->csi_lane_mask;
				v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
					NOTIFY_CSID_CFG,
					&s_ctrl->curr_csi_params->csid_params);
				mb();
				v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
					NOTIFY_CSIPHY_CFG,
					&s_ctrl->curr_csi_params->csiphy_params);
				mb();
				msleep(20);
			}

			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
				output_settings[res].op_pixel_clk);
			s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
			msleep(30);
		}
	}
	printk("%s: X", __func__);
	return rc;
}
Beispiel #5
0
static irqreturn_t msm_csid_irq(int irq_num, void *data)
{
	uint32_t irq;
	struct csid_device *csid_dev = data;
	if (!csid_dev||!csid_dev->base) {
		pr_err("%s:%d csid_dev NULL\n", __func__, __LINE__);
		return IRQ_HANDLED;
	}
	irq = msm_camera_io_r(csid_dev->base + CSID_IRQ_STATUS_ADDR);
	CDBG("%s CSID%d_IRQ_STATUS_ADDR = 0x%x\n",
		 __func__, csid_dev->pdev->id, irq);
	if (irq & (0x1 << CSID_RST_DONE_IRQ_BITSHIFT))
		complete(&csid_dev->reset_complete);

	if (irq & CSID_IRQ_UNBOUNDED_FRAME_MASK)
		pr_err("%s - received CSID_IRQ_UNBOUNDED_FRAME_MASK!\n",
				__func__);
	if (irq & CSID_IRQ_STREAM_UNDERFLOW_MASK) {
		pr_err("%s - received CSID_IRQ_STREAM_UNDERFLOW_MASK!\n",
				__func__);
		v4l2_subdev_notify(&csid_dev->subdev,
				NOTIFY_CSID_STREAM_UNDERFLOW_ERROR,
				(void *)NULL);
	}
	if (irq & CSID_IRQ_ECC_MASK) {
		pr_err("%s - received CSID_IRQ_ECC_MASK!\n",
				__func__);
		v4l2_subdev_notify(&csid_dev->subdev,
				NOTIFY_CSID_ECC_ERROR,
				(void *)NULL);
	}
	if (irq & CSID_IRQ_CRC_MASK) {
		pr_err("%s - received CSID_IRQ_CRC_MASK!\n",
				__func__);
		v4l2_subdev_notify(&csid_dev->subdev,
				NOTIFY_CSID_CRC_ERROR,
				(void *)NULL);
	}
	if (irq & CSID_IRQ_PHY_DL_OVERFLOW_MASK) {
		pr_err("%s - received CSID_IRQ_PHY_DL_OVERFLOW_MASK!\n",
				__func__);
		v4l2_subdev_notify(&csid_dev->subdev,
				NOTIFY_CSID_PHY_DL_OVERFLOW_ERROR,
				(void *)NULL);
	}

	msm_camera_io_w(irq, csid_dev->base + CSID_IRQ_CLEAR_CMD_ADDR);
	return IRQ_HANDLED;
}
Beispiel #6
0
int32_t hi351_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;

	if (update_type == MSM_SENSOR_REG_INIT) {
#if defined (LGE_CAMERA_ANTIBAND_50HZ)	//Flicker 50Hz
		pr_err("Register INIT with Flicker 50Hz Mode\n");
#else
		pr_err("Register INIT with Flicker 60Hz Mode\n");
#endif
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		PREV_EFFECT = -1;
		PREV_ISO = -1;
		PREV_WB = -1;
		PREV_FPS = -1;
		PREV_BESTSHOT = -1;
		DELAY_START = 0;
		hi351_reg_init(s_ctrl);
		csi_config = 0;
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		pr_err("PERIODIC : %d\n", res);
		if (!csi_config) {
			s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
			msleep(20);
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			pr_err("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			pr_err("CSI config is done\n");
			mb();
			msleep(50);
			csi_config = 1;
			s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		}
		hi351_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);

		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE,
			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);

	}
	return rc;
}
int32_t s5k5ca_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	printk("\n s5k5ca_sensor_setting() update_type:%d res:%d\n",update_type,res);

	if (update_type == MSM_SENSOR_REG_INIT) {
		//printk("PERIODIC : %d\n", res);
		s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
		//printk("CSI config in progress\n");
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_CSIC_CFG,
			s_ctrl->curr_csic_params);
		//printk("CSI config is done\n");
		mb();

		//printk("Register INIT\n");
		s_ctrl->curr_csi_params = NULL;
		rc=msm_sensor_enable_debugfs(s_ctrl);
		if( rc!=0 )
			printk("s5k5ca_sensor_setting()rc:%d",rc);
		rc=msm_sensor_write_init_settings(s_ctrl);
		if( rc!=0 )
			printk("s5k5ca_sensor_setting()rc:%d",rc);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		//CDBG("PERIODIC : %d\n", res);
		if((res==0) &&(night_mode_flag==msm_v4l2_best_shot_night))
			{
		rc=msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			&s5k5ca_confs_night_mode[0], res);	
		if( rc!=0 )
			printk("s5k5ca_sensor_setting()rc:%d",rc);
			}
		else
		rc=msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
		if( rc!=0 )
			printk("s5k5ca_sensor_setting()rc:%d",rc);
		if (res == MSM_SENSOR_RES_4)
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
					NOTIFY_PCLK_CHANGE,
					&vfe_clk);
	}
	return rc;
}
int32_t ov5693_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
		int update_type, int res)
{
	int32_t rc = 0;

	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
		// Software reset
		msm_camera_i2c_write(
				s_ctrl->sensor_i2c_client,
				0x103, 0x1,
				MSM_CAMERA_I2C_BYTE_DATA);

		msm_sensor_write_init_settings(s_ctrl);

		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x1,
			MSM_CAMERA_I2C_BYTE_DATA);

#if 0 // from QCT Reference driver
		ov5693_read_opt(s_ctrl);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x100, 0x0,
		  MSM_CAMERA_I2C_BYTE_DATA);
#endif

	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		msm_sensor_write_res_settings(s_ctrl, res);
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
	}
	return rc;
}
static int32_t ov10820_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		if (ov660_exists) {
			rc = ov660_set_sensor_mode(res, revision);
			if (rc < 0)
				return rc;
		}
		rc = msm_sensor_write_conf_array(
				s_ctrl->sensor_i2c_client,
				s_ctrl->msm_sensor_reg->mode_settings, res);
		if (rc < 0)
			return rc;
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
	}
	return rc;
}
int dw9714_get_otp_af(struct hisi_vcm_ctrl_t *vcm_ctrl, void *data)
{
	struct vcm_cfg_data *cdata = (struct vcm_cfg_data *)data;
	struct hisi_sd_req_sd vcm_req_sd = {0};
	char sd_name[DEV_NAME_SIZE]={0};
	struct hisi_sensor_ctrl_t *s_ctrl;
	int rc = 0;

	cam_debug("%s enter.", __func__);

	snprintf(sd_name, sizeof(sd_name), "hisi_sensor_%d", vcm_ctrl->index);
	vcm_req_sd.name = sd_name;
	v4l2_subdev_notify(&vcm_ctrl->hisi_sd.sd, HISI_SD_NOTIFY_GET_SD, &vcm_req_sd);

	s_ctrl = container_of(container_of(vcm_req_sd.subdev, struct hisi_sd_subdev, sd),
				struct hisi_sensor_ctrl_t, hisi_sd);

	if (s_ctrl->sensor->sensor_otp.af_otp.af_otp_succeed) {
		cam_info("%s succeed to get otp af.", __func__);
		memcpy(&cdata->cfg.af_otp, &s_ctrl->sensor->sensor_otp.af_otp,
			sizeof(struct hisi_sensor_af_otp));
		rc = 0;
	} else {
		cam_err("%s failed to get otp af.", __func__);
		memset(&cdata->cfg.af_otp, 0, sizeof(struct hisi_sensor_af_otp));
		rc = -1;
	}
	return rc;
}
int32_t imx111_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	pr_err("[rafal47] %s: update: %d, res : %d : Change camera mode\n", __func__, update_type, res);
//	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
//	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		if (res == 0) {
			msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
				(struct msm_camera_i2c_reg_conf *)
				imx111_comm_confs[0].conf,
				imx111_comm_confs[0].size,
				imx111_comm_confs[0].data_type);
         printk("[tykim] %s: csi_lane_assign not setting\n", __func__); /*                                                                     */
		} else {
			msm_sensor_write_res_settings(s_ctrl, res);
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
				output_settings[res].op_pixel_clk);
		}
	}
	printk("%s: X", __func__);
	return rc;
}
Beispiel #12
0
/* BEGIN Dom_Lin@pegatron [2011/02/04] [Enable back camera auto focus] */
void msm_sensor_send_stats_msg(struct msm_sensor_ctrl_t *s_ctrl, uint32_t id, uint8_t status)
{
	struct sensor_msg_stats msgStats;
	msgStats.id = id;
	msgStats.status = status;

	CDBG("+++\n");
	v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev, NOTIFY_SENSOR_MSG_STATS, &msgStats);
}
int32_t imx111_sensor_write_exp_gain1(struct msm_sensor_ctrl_t *s_ctrl,
		uint16_t gain, uint32_t line, int32_t luma_avg, uint16_t fgain)
{
	uint32_t fl_lines;
	uint8_t offset;
	fl_lines = s_ctrl->curr_frame_length_lines;
	fl_lines = (fl_lines * s_ctrl->fps_divider) / Q10;
	offset = s_ctrl->sensor_exp_gain_info->vert_offset;
	if (line > (fl_lines - offset))
		fl_lines = line + offset;

	CDBG("\n%s:Gain:%d, Linecount:%d\n", __func__, gain, line);
	if (s_ctrl->curr_res == 0) {
		msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
			(struct msm_camera_i2c_reg_conf *)
			imx111_comm_confs[1].conf,
			imx111_comm_confs[1].size,
			imx111_comm_confs[1].data_type);

		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_output_reg_addr->frame_length_lines,
			fl_lines, MSM_CAMERA_I2C_WORD_DATA);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
			line, MSM_CAMERA_I2C_WORD_DATA);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
			MSM_CAMERA_I2C_WORD_DATA);

		msm_camera_i2c_write_tbl(s_ctrl->sensor_i2c_client,
			(struct msm_camera_i2c_reg_conf *)
			imx111_comm_confs[2].conf,
			imx111_comm_confs[2].size,
			imx111_comm_confs[2].data_type);


		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[s_ctrl->curr_res].op_pixel_clk);
//		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
	} else {
		s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_output_reg_addr->frame_length_lines,
			fl_lines, MSM_CAMERA_I2C_WORD_DATA);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr,
			line, MSM_CAMERA_I2C_WORD_DATA);
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
			s_ctrl->sensor_exp_gain_info->global_gain_addr, gain,
			MSM_CAMERA_I2C_WORD_DATA);
		s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
	}

	return 0;
}
int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;

	printk("%s : E\n", __func__); // [email protected]
	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		CDBG("Register INIT\n");
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
		csi_config = 0;
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		CDBG("PERIODIC : %d\n", res);
		msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
		msleep(30);
		if (!csi_config) {
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			CDBG("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			CDBG("CSI config is done\n");
			mb();
			msleep(30);
			csi_config = 1;
		}
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE,
			&s_ctrl->sensordata->pdata->ioclk.vfe_clk_rate);

		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(50);
	}
	printk("%s : X\n", __func__); // [email protected]
	return rc;
}
Beispiel #15
0
int m5mols_start_capture(struct m5mols_info *info)
{
	unsigned int framesize = info->cap.buf_size - M5MOLS_JPEG_TAGS_SIZE;
	struct v4l2_subdev *sd = &info->sd;
	int ret;

	/*
	 * Synchronize the controls, set the capture frame resolution and color
	 * format. The frame capture is initiated during switching from Monitor
	 * to Capture mode.
	 */
	ret = m5mols_set_mode(info, REG_MONITOR);
	if (!ret)
		ret = m5mols_restore_controls(info);
	if (!ret)
		ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
	if (!ret)
		ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, info->resolution);
	if (!ret)
		ret = m5mols_write(sd, CAPP_JPEG_SIZE_MAX, framesize);
	if (!ret)
		ret = m5mols_set_mode(info, REG_CAPTURE);
	if (!ret)
		/* Wait until a frame is captured to ISP internal memory */
		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
	if (ret)
		return ret;

	/*
	 * Initiate the captured data transfer to a MIPI-CSI receiver.
	 */
	ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
	if (!ret)
		ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
	if (!ret) {
		bool captured = false;
		unsigned int size;

		/* Wait for the capture completion interrupt */
		ret = m5mols_wait_interrupt(sd, REG_INT_CAPTURE, 2000);
		if (!ret) {
			captured = true;
			ret = m5mols_capture_info(info);
		}
		size = captured ? info->cap.main : 0;
		v4l2_dbg(1, m5mols_debug, sd, "%s: size: %d, thumb.: %d B\n",
			 __func__, size, info->cap.thumb);

		v4l2_subdev_notify(sd, S5P_FIMC_TX_END_NOTIFY, &size);
	}

	return ret;
}
static void vfe_send_stats_msg(uint32_t buf_addr, uint32_t msg_id)
{
	struct isp_msg_stats msg_stats;

	msg_stats.frameCounter = vfe2x_ctrl->vfeFrameId;
	msg_stats.buffer       = buf_addr;
	msg_stats.id           = msg_id;

	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
				NOTIFY_VFE_MSG_STATS,
				&msg_stats);
}
static void vfe2x_send_isp_msg(
	struct vfe2x_ctrl_type *vctrl,
	uint32_t isp_msg_id)
{
	struct isp_msg_event isp_msg_evt;

	isp_msg_evt.msg_id = isp_msg_id;
	isp_msg_evt.sof_count = vfe2x_ctrl->vfeFrameId;
	v4l2_subdev_notify(&vctrl->subdev,
			NOTIFY_ISP_MSG_EVT,
			(void *)&isp_msg_evt);
}
Beispiel #18
0
int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		msm_sensor_write_res_settings(s_ctrl, res);
		if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
			s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
			s_ctrl->curr_csi_params->csid_params.lane_assign =
				s_ctrl->sensordata->sensor_platform_info->
				csi_lane_params->csi_lane_assign;
			s_ctrl->curr_csi_params->csiphy_params.lane_mask =
				s_ctrl->sensordata->sensor_platform_info->
				csi_lane_params->csi_lane_mask;
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSID_CFG,
				&s_ctrl->curr_csi_params->csid_params);
			mb();
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIPHY_CFG,
				&s_ctrl->curr_csi_params->csiphy_params);
			mb();
			msleep(20);
		}

		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(30);
	}
	return rc;
}
Beispiel #19
0
int32_t msm_sensor_setting2(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;

	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	if (csi_config == 0 || res == 0)
		msleep(66);
	else
		msleep(266);
	if (update_type == MSM_SENSOR_REG_INIT) {
		CDBG("Register INIT\n");
		s_ctrl->curr_csi_params = NULL;
		msm_camera_i2c_write(
				s_ctrl->sensor_i2c_client,
				0x103, 0x1,
				MSM_CAMERA_I2C_BYTE_DATA);
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
		csi_config = 0;
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		CDBG("PERIODIC : %d\n", res);
		msm_sensor_write_conf_array(
			s_ctrl->sensor_i2c_client,
			s_ctrl->msm_sensor_reg->mode_settings, res);
		msleep(30);
		if (!csi_config) {
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			CDBG("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			CDBG("CSI config is done\n");
			mb();
			msleep(30);
			csi_config = 1;
		msm_camera_i2c_write(
			s_ctrl->sensor_i2c_client,
			0x100, 0x1,
			MSM_CAMERA_I2C_BYTE_DATA);
		}
		msm_camera_i2c_write(
			s_ctrl->sensor_i2c_client,
			0x4800, 0x4,
			MSM_CAMERA_I2C_BYTE_DATA);
		msleep(266);
		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(50);
	}
	return rc;
}
static void vfe_send_outmsg(struct v4l2_subdev *sd, uint8_t msgid,
		uint32_t ch0_paddr, uint32_t ch1_paddr)
{
	struct isp_msg_output msg;

	msg.output_id = msgid;
	msg.buf.ch_paddr[0]     = ch0_paddr;
	msg.buf.ch_paddr[1]     = ch1_paddr;
	msg.frameCounter = vfe2x_ctrl->vfeFrameId;

	v4l2_subdev_notify(&vfe2x_ctrl->subdev,
			NOTIFY_VFE_MSG_OUT,
			&msg);
	return;
}
Beispiel #21
0
int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
		NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
		PIX_0, ISPIF_OFF_IMMEDIATELY));
printk("%s:[F_PANTECH_CAMERA] %d, %d res=%d\n", __func__, __LINE__,update_type,res);

   if (s_ctrl->func_tbl->sensor_stop_stream)
	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		msm_sensor_write_res_settings(s_ctrl, res);
		if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
printk("%s:[F_PANTECH_CAMERA] ==> MIPI setting  E %d\n", __func__, update_type);
			s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSID_CFG,
				&s_ctrl->curr_csi_params->csid_params);
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
						NOTIFY_CID_CHANGE, NULL);
			mb();
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIPHY_CFG,
				&s_ctrl->curr_csi_params->csiphy_params);
			mb();
			msleep(20);
printk("%s:[F_PANTECH_CAMERA] ==> MIPI setting  X %d\n", __func__, update_type);			
		}

		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
			PIX_0, ISPIF_ON_FRAME_BOUNDARY));

        if (s_ctrl->func_tbl->sensor_start_stream) {
			//printk("%s:kernal delay start %d x\n", __func__, __LINE__);
			msleep(30); // 02.03 bsy pink ¡þO?oA¡þO??
			//printk("%s: kernal delay end%d x\n", __func__, __LINE__);						
			s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		}

		msleep(30);
	}
	return rc;
}
Beispiel #22
0
static void vfe_send_outmsg(
	struct axi_ctrl_t *axi_ctrl, uint8_t msgid,
	uint32_t ch0_paddr, uint32_t ch1_paddr,
	uint32_t ch2_paddr, uint32_t image_mode)
{
	struct isp_msg_output msg;

	msg.output_id = msgid;
	msg.buf.image_mode = image_mode;
	msg.buf.ch_paddr[0]	= ch0_paddr;
	msg.buf.ch_paddr[1]	= ch1_paddr;
	msg.buf.ch_paddr[2]	= ch2_paddr;
	msg.frameCounter = axi_ctrl->share_ctrl->vfeFrameId;

	v4l2_subdev_notify(&axi_ctrl->subdev,
			NOTIFY_VFE_MSG_OUT,
			&msg);
	return;
}
Beispiel #23
0
int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
		NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
		PIX_0, ISPIF_OFF_IMMEDIATELY));
	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->curr_csi_params = NULL;
		msm_sensor_enable_debugfs(s_ctrl);

#if !defined(DVE005_CAMERA_DRV)
		msm_sensor_write_init_settings(s_ctrl);
#endif 
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
#if defined(DVE005_CAMERA_DRV)
		rc = s_ctrl->func_tbl->sensor_write_res_settings(s_ctrl, res);
#else 
		msm_sensor_write_res_settings(s_ctrl, res);
#endif 

		if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
			s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSID_CFG,
				&s_ctrl->curr_csi_params->csid_params);
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
						NOTIFY_CID_CHANGE, NULL);
			mb();
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIPHY_CFG,
				&s_ctrl->curr_csi_params->csiphy_params);
			mb();
			msleep(20);
		}

		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);
		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
			PIX_0, ISPIF_ON_FRAME_BOUNDARY));
		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
		msleep(30);
	}
	return rc;
}
Beispiel #24
0
static void vpe_send_outmsg(void)
{
	unsigned long flags;
	struct msm_vpe_resp rp;
	memset(&rp, 0, sizeof(rp));
	spin_lock_irqsave(&vpe_ctrl->lock, flags);
	if (vpe_ctrl->state == VPE_STATE_IDLE) {
		pr_err("%s VPE is in IDLE state. Ignore the ack msg", __func__);
		spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
		return;
	}
	rp.type = vpe_ctrl->pp_frame_info->pp_frame_cmd.path;
	rp.extdata = (void *)vpe_ctrl->pp_frame_info;
	rp.extlen = sizeof(*vpe_ctrl->pp_frame_info);
	vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
	vpe_ctrl->pp_frame_info = NULL;
	spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
	v4l2_subdev_notify(&vpe_ctrl->subdev,
		NOTIFY_VPE_MSG_EVT, (void *)&rp);
}
Beispiel #25
0
static int32_t ov2720_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
				int update_type, int rt)
{
	struct msm_camera_csid_params ov2720_csid_params;
	struct msm_camera_csiphy_params ov2720_csiphy_params;
	int32_t rc = 0;
	s_ctrl->func_tbl.sensor_stop_stream(s_ctrl);
	msleep(30);
	if (update_type == MSM_SENSOR_REG_INIT) {
		s_ctrl->config_csi_flag = 1;
		msm_sensor_enable_debugfs(s_ctrl);
		msm_sensor_write_b_init_settings(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		msm_sensor_write_b_res_settings(s_ctrl, rt);
		if (s_ctrl->config_csi_flag) {
			struct msm_camera_csid_vc_cfg ov2720_vccfg[] = {
				{0, CSI_RAW10, CSI_DECODE_10BIT},
				{1, CSI_EMBED_DATA, CSI_DECODE_8BIT},
			};
			ov2720_csid_params.lane_cnt = 2;
			ov2720_csid_params.lane_assign = 0xe4;
			ov2720_csid_params.lut_params.num_cid =
				ARRAY_SIZE(ov2720_vccfg);
			ov2720_csid_params.lut_params.vc_cfg =
				&ov2720_vccfg[0];
			ov2720_csiphy_params.lane_cnt = 2;
			ov2720_csiphy_params.settle_cnt = 0x1B;
			rc = msm_camio_csid_config(&ov2720_csid_params);
			v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
						NOTIFY_CID_CHANGE, NULL);
			mb();
			rc = msm_camio_csiphy_config(&ov2720_csiphy_params);
			mb();
			msleep(20);
			s_ctrl->config_csi_flag = 0;
		}
		s_ctrl->func_tbl.sensor_start_stream(s_ctrl);
		msleep(30);
	}
	return rc;
}
Beispiel #26
0
int32_t msm_sensor_setting3(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;
	static int csi_config;
	if (update_type == MSM_SENSOR_REG_INIT) {
		CDBG("Register INIT\n");
		s_ctrl->curr_csi_params = NULL;
		csi_config = 0;
		msm_camera_i2c_write(
			s_ctrl->sensor_i2c_client,
			0x0e, 0x08,
			MSM_CAMERA_I2C_BYTE_DATA);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
		CDBG("PERIODIC : %d\n", res);
		if (res == 0)
			return 0;
		if (!csi_config) {
			msm_sensor_write_conf_array(
				s_ctrl->sensor_i2c_client,
				s_ctrl->msm_sensor_reg->mode_settings, res);
			msleep(30);
			s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
			CDBG("CSI config in progress\n");
			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
				NOTIFY_CSIC_CFG,
				s_ctrl->curr_csic_params);
			CDBG("CSI config is done\n");
			mb();
			msleep(30);
			msm_camera_i2c_write(
					s_ctrl->sensor_i2c_client,
					0x0e, 0x00,
					MSM_CAMERA_I2C_BYTE_DATA);
			csi_config = 1;
		}
		msleep(50);
	}
	return rc;
}
int32_t as0260_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
			int update_type, int res)
{
	int32_t rc = 0;

	if (update_type == MSM_SENSOR_REG_INIT) {
		msm_sensor_write_init_settings(s_ctrl);
		if (s_ctrl->func_tbl->sensor_stop_stream)
			s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
	} else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {

 		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
			output_settings[res].op_pixel_clk);

		 as0260_sensor_write_res_settings(s_ctrl, res);
		 msleep(30);

	}
	SKYCDBG("%s: %d x\n", __func__, __LINE__);
	return rc;
}
Beispiel #28
0
static void vpe_send_outmsg(void)
{
    unsigned long flags;
    struct msm_vpe_resp rp;
    memset(&rp, 0, sizeof(rp));
    spin_lock_irqsave(&vpe_ctrl->lock, flags);
    if (vpe_ctrl->state == VPE_STATE_IDLE) {
        pr_info("%s VPE is in IDLE state. Ignore the ack msg", __func__);
        spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
        return;
    }
    rp.type = vpe_ctrl->pp_frame_info->pp_frame_cmd.dest_path;
    rp.extdata = (void *)vpe_ctrl->pp_frame_info;
    rp.extlen = sizeof(*vpe_ctrl->pp_frame_info);
    vpe_ctrl->state = VPE_STATE_INIT;   /* put it back to idle. */
    vpe_ctrl->pp_frame_info = NULL;
//HTC_START chris, 20120310 fix unknown reset which is caused by vpe clk disabled when vpe state is active.
    vpe_ctrl->vpe_event_done = 1;
    wake_up(&vpe_ctrl->vpe_event_queue);
//HTC_END
    spin_unlock_irqrestore(&vpe_ctrl->lock, flags);
    v4l2_subdev_notify(&vpe_ctrl->subdev,
                       NOTIFY_VPE_MSG_EVT, (void *)&rp);
}
/**
 * v4l2_subdev_notify_event() - Delivers event notification for subdevice
 * @sd: The subdev for which to deliver the event
 * @ev: The event to deliver
 *
 * Will deliver the specified event to all userspace event listeners which are
 * subscribed to the v42l subdev event queue as well as to the bridge driver
 * using the notify callback. The notification type for the notify callback
 * will be V4L2_DEVICE_NOTIFY_EVENT.
 */
void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
			      const struct v4l2_event *ev)
{
	v4l2_event_queue(sd->devnode, ev);
	v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev);
}
Beispiel #30
0
/*
 * V4L2 Subdevice IR Ops
 */
static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
				  bool *handled)
{
	struct cx23888_ir_state *state = to_state(sd);
	struct cx23885_dev *dev = state->dev;
	unsigned long flags;

	u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
	u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
	u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG);

	union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH];
	unsigned int i, j, k;
	u32 events, v;
	int tsr, rsr, rto, ror, tse, rse, rte, roe, kror;

	tsr = stats & STATS_TSR; /* Tx FIFO Service Request */
	rsr = stats & STATS_RSR; /* Rx FIFO Service Request */
	rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */
	ror = stats & STATS_ROR; /* Rx FIFO Over Run */

	tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */
	rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */
	rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */
	roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */

	*handled = false;
	v4l2_dbg(2, ir_888_debug, sd, "IRQ Status:  %s %s %s %s %s %s\n",
		 tsr ? "tsr" : "   ", rsr ? "rsr" : "   ",
		 rto ? "rto" : "   ", ror ? "ror" : "   ",
		 stats & STATS_TBY ? "tby" : "   ",
		 stats & STATS_RBY ? "rby" : "   ");

	v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n",
		 tse ? "tse" : "   ", rse ? "rse" : "   ",
		 rte ? "rte" : "   ", roe ? "roe" : "   ");

	/*
	 * Transmitter interrupt service
	 */
	if (tse && tsr) {
		/*
		 * TODO:
		 * Check the watermark threshold setting
		 * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo
		 * Push the data to the hardware FIFO.
		 * If there was nothing more to send in the tx_kfifo, disable
		 *	the TSR IRQ and notify the v4l2_device.
		 * If there was something in the tx_kfifo, check the tx_kfifo
		 *      level and notify the v4l2_device, if it is low.
		 */
		/* For now, inhibit TSR interrupt until Tx is implemented */
		irqenable_tx(dev, 0);
		events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ;
		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events);
		*handled = true;
	}

	/*
	 * Receiver interrupt service
	 */
	kror = 0;
	if ((rse && rsr) || (rte && rto)) {
		/*
		 * Receive data on RSR to clear the STATS_RSR.
		 * Receive data on RTO, since we may not have yet hit the RSR
		 * watermark when we receive the RTO.
		 */
		for (i = 0, v = FIFO_RX_NDV;
		     (v & FIFO_RX_NDV) && !kror; i = 0) {
			for (j = 0;
			     (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) {
				v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG);
				rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV;
				i++;
			}
			if (i == 0)
				break;
			j = i * sizeof(union cx23888_ir_fifo_rec);
			k = kfifo_in_locked(&state->rx_kfifo,
				      (unsigned char *) rx_data, j,
				      &state->rx_kfifo_lock);
			if (k != j)
				kror++; /* rx_kfifo over run */
		}
		*handled = true;
	}

	events = 0;
	v = 0;
	if (kror) {
		events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN;
		v4l2_err(sd, "IR receiver software FIFO overrun\n");
	}
	if (roe && ror) {
		/*
		 * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear
		 * the Rx FIFO Over Run status (STATS_ROR)
		 */
		v |= CNTRL_RFE;
		events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN;
		v4l2_err(sd, "IR receiver hardware FIFO overrun\n");
	}
	if (rte && rto) {
		/*
		 * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear
		 * the Rx Pulse Width Timer Time Out (STATS_RTO)
		 */
		v |= CNTRL_RXE;
		events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED;
	}
	if (v) {
		/* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */
		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v);
		cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
		*handled = true;
	}

	spin_lock_irqsave(&state->rx_kfifo_lock, flags);
	if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
		events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
	spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);

	if (events)
		v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
	return 0;
}