static int sensor_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = to_sd(ctrl); u32 cmd = ctrl->id; s32 value = ctrl->val; int ret = 0; switch (cmd) { case V4L2_CID_SENSOR_SET_AE_TARGET: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_ae_target(sd, value); break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x1_2: case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x3_4: case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x1_2: case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x3_4: case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x1_2: case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x3_4: case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x1_2: case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x3_4: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_ae_weight(sd, cmd, value); break; case V4L2_CID_SENSOR_SET_RG_WEIGHT: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_rg_weight(sd, value); break; case V4L2_CID_SENSOR_SET_AE_SPEED: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_ae_speed(sd, value); break; case V4L2_CID_SENSOR_SET_SHUTTER: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_shutter(sd, value); break; case V4L2_CID_SENSOR_SET_GAIN: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_gain(sd, value); break; case V4L2_CID_SENSOR_SET_BIT_CONVERTING: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_bit_converting(sd, value); break; case V4L2_CID_SENSOR_SET_AUTO_EXPOSURE: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_auto_exposure(sd, value); break; case V4L2_CID_SENSOR_SET_FRAME_RATE: sensor_dbg("ctrl.id = %x, val=%x", cmd, value); ret = sensor_ctrl_frame_rate(sd, value); break; default : sensor_err("Unknown CID(%x)", cmd); ret = -1; break; } return ret; }
static int aksensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct aksensor_priv *priv = container_of(sd, struct aksensor_priv, subdev); // struct v4l2_pix_format *pix = &f->fmt.pix; T_BOOL bRet = AK_FALSE; int ret = -EINVAL; sensor_dbg("entry %s\n", __func__); //切换模式前必须设置一次mode if ( V4L2_BUF_TYPE_PRIVATE == mf->reserved[0]) { g_mode = mf->reserved[1]; } priv->win.width = mf->width; priv->win.height =mf->height; sensor_dbg("---%s. g_mode=%d mf->width=%d mf->height=%d\n", __func__, g_mode, mf->width, mf->height); switch (g_mode) { case CAMERA_WMODE_PREV: if (cur_sensor_info->handler->cam_set_to_prev_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_prev_func(mf->width, mf->height); break; case CAMERA_WMODE_CAP: if (cur_sensor_info->handler->cam_set_to_cap_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_cap_func(mf->width, mf->height); break; case CAMERA_WMODE_REC: if (cur_sensor_info->handler->cam_set_to_record_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_record_func(mf->width, mf->height); break; default : if (cur_sensor_info->handler->cam_set_to_record_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_record_func(mf->width, mf->height); break; } if ( bRet ) ret = 0; SENDBG("leave %s\n", __func__); return ret; }
static int sensor_ctrl_frame_rate(struct v4l2_subdev *sd, int val) { struct sensor_info *info = to_sensor(sd); u8 *value = (u8 *)&val; int ret = 0; sensor_dbg("val = %d", val); if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_DURATION_MSB, value[1]); if (ret < 0) { sensor_err("Failed to add request(MSB)"); goto ret; } ret = sensor_add_request(sd, SENSOR_REG_VIS_DURATION_LSB, value[0]); if (ret < 0) { sensor_err("Failed to add request(LSB)"); goto ret; } } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_DURATION_MSB, (u8)value[1], I2C_8BIT); if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); goto ret; } ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_DURATION_LSB, (u8)value[0], I2C_8BIT); if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); goto ret; } } ret: return ret; }
static int sensor_ctrl_rg_weight(struct v4l2_subdev *sd, int val) { struct sensor_info *info = to_sensor(sd); u8 *value = (u8 *)&val; int ret = 0; sensor_dbg("val = %d", val); if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_GAIN_RED, value[1]); if (ret < 0) { sensor_err("Failed to add request(RED)"); goto ret; } ret = sensor_add_request(sd, SENSOR_REG_VIS_GAIN_GREEN, value[0]); if (ret < 0) { sensor_err("Failed to add request(GREEN)"); goto ret; } } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_GAIN_RED, (u8)value[1], I2C_8BIT); if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); goto ret; } ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_GAIN_GREEN, (u8)value[0], I2C_8BIT); if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); goto ret; } } ret: return ret; }
/** * @brief: query v4l2 sub-device ctroller function * * @author: caolianming * @date: 2014-01-09 * @param [in] *sd: v4l2_subdev struct, v4l2 sub-device info * @param [in] *qc: v4l2_queryctrl struct */ static int aksensor_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) { int ret = 0; sensor_dbg("entry %s\n", __func__); //if (cur_sensor_info->ctrls) // ret = cur_sensor_info->ctrls->ops->queryctrl(ctrl); return ret; }
/* * i2c_driver function */ static int aksensor_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct aksensor_priv *priv; struct soc_camera_link *icl = soc_camera_i2c_to_link(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int i, ret; SENDBG("entry %s\n", __func__); if (!icl || !icl->priv) { dev_err(&client->dev, "AKSENSOR: missing platform data!\n"); return -EINVAL; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&adapter->dev, "I2C-Adapter doesn't support " "I2C_FUNC_SMBUS_BYTE_DATA\n"); return -EIO; } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { return -ENOMEM; } priv->info = icl->priv; v4l2_i2c_subdev_init(&priv->subdev, client, &aksensor_subdev_ops); ret = aksensor_video_probe(client); if (ret) { kfree(priv); return ret; } v4l2_ctrl_handler_init(&priv->hdl, cur_sensor_info->nr_ctrls); for (i = 0; i < cur_sensor_info->nr_ctrls; i++) v4l2_ctrl_new_custom(&priv->hdl, &cur_sensor_info->ctrls[i], NULL); priv->subdev.ctrl_handler = &priv->hdl; if (priv->hdl.error) { int err = priv->hdl.error; v4l2_ctrl_handler_free(&priv->hdl); kfree(priv); return err; } // init sensor resolution, default VGA for (i = 0; i < cur_sensor_info->num_resolution; i++) if (!strcmp(cur_sensor_info->resolution[i].name, "VGA")) { priv->win.width = cur_sensor_info->resolution[i].width; priv->win.height = cur_sensor_info->resolution[i].height; } sensor_dbg("%s: priv->win.width=%d priv->win.height=%d\n", __func__, priv->win.width, priv->win.height); return ret; }
static void sensor_handler(void *data, int arg) { struct v4l2_subdev *sd = data; struct sensor_info *info = to_sensor(sd); sensor_dbg("%s: irq(%d), info->status(%d)", __func__, arg, info->status); switch (arg) { case FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART: sensor_dbg("Flite frame start"); tasklet_schedule(&info->tasklet_flite_str); break; case FLITE_REG_CISTATUS_IRQ_SRC_FRMEND: sensor_dbg("Flite frame end"); schedule_work(&info->work); break; default : sensor_err("unknown irq(%d)", arg); break; } }
static int aksensor_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct aksensor_priv *priv = to_aksensor(client); sensor_dbg("entry %s\n", __func__); a->c.left = 0; a->c.top = 0; a->c.width = priv->win.width; a->c.height = priv->win.height; return 0; }
static int aksensor_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { // struct v4l2_ctrl v4l2ctrl; sensor_dbg("entry %s\n", __func__); #if 0 if (cur_sensor_info->ctrls) { cur_sensor_info->ctrls->ops->g_volatile_ctrl(&v4l2ctrl); ctrl->id = v4l2ctrl.id; ctrl->val = v4l2ctrl.val; } #endif return 0; }
static int aksensor_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct aksensor_priv *priv = to_aksensor(client); int i; sensor_dbg("entry %s. priv=%p\n", __func__, priv); for (i = 0; i < cur_sensor_info->num_resolution; ++i) { if (!strcmp(cur_sensor_info->resolution[i].name, "720P")) break; } // the resolution is 720P or larger if (i == cur_sensor_info->num_resolution) --i; a->bounds.width = cur_sensor_info->resolution[i].width; a->bounds.height = cur_sensor_info->resolution[i].height; a->bounds.left = 0; a->bounds.top = 0; a->defrect.width = priv->win.width; a->defrect.height = priv->win.height; a->defrect.left = 0; a->defrect.top = 0; a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; a->pixelaspect.numerator = 1; a->pixelaspect.denominator = 1; sensor_dbg("%s.\n" " a->bounds.width=%d, a->bounds.height=%d\n" " a->defrect.width=%d, a->defrect.height=%d\n", __func__, a->bounds.width, a->bounds.height, a->defrect.width, a->defrect.height); return 0; }
/** * @brief: query v4l2 sub-device ctroller function * * @author: caolianming * @date: 2014-01-09 * @param [in] *sd: v4l2_subdev struct, v4l2 sub-device info * @param [in] *ctrl: v4l2_control struct */ static int aksensor_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { int ret = 0; struct v4l2_ctrl v4l2ctrl; sensor_dbg("entry %s ctrl->id=%d, ctrl->value=%d\n", __func__, ctrl->id, ctrl->value); if (cur_sensor_info->ctrls) { v4l2ctrl.id = ctrl->id; v4l2ctrl.val = ctrl->value; ret = cur_sensor_info->ctrls->ops->s_ctrl(&v4l2ctrl); } return ret; }
static int sensor_ctrl_auto_exposure(struct v4l2_subdev *sd, int val) { struct sensor_info *info = to_sensor(sd); u8 *value = (u8 *)&val; int ret = 0; sensor_dbg("val = %d", val); if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_OFF, value[0]); if (ret < 0) sensor_err("Failed to add request"); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_OFF, (u8)value[0], I2C_8BIT); if (ret < 0) sensor_err("file to write reg(ret = %d)", ret); } return ret; }
static void tasklet_func_flite_end(unsigned long data) { struct sensor_info *info = (struct sensor_info *)data; struct sensor_req_list *req = NULL; int ret = 0; req = sensor_get_request(&info->sd); while (req) { sensor_dbg("addr(%.8x), val(%x)", req->addr, req->value); ret = vision_sensor_write_reg(&info->sd, req->addr, (u8)req->value, I2C_8BIT); kfree(req); req = NULL; if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); break; } req = sensor_get_request(&info->sd); } }
static void sensor_irq_work(struct work_struct *work) { struct sensor_info *info = container_of(work, struct sensor_info, work); struct sensor_req_list *req = NULL; int ret = 0; req = sensor_get_request(&info->sd); while (req) { sensor_dbg("addr(%.8x), val(%x)", req->addr, req->value); ret = vision_sensor_write_reg(&info->sd, req->addr, (u8)req->value, I2C_8BIT); kfree(req); req = NULL; if (ret < 0) { sensor_err("file to write reg(ret = %d)", ret); break; } req = sensor_get_request(&info->sd); } }
static int aksensor_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct aksensor_priv *priv = to_aksensor(client); int ret = -EINVAL; T_BOOL bRet = AK_FALSE; sensor_dbg("entry %s\n", __func__); priv->win.width = a->c.width; priv->win.height =a->c.height; switch (g_mode) { case CAMERA_WMODE_PREV: if (cur_sensor_info->handler->cam_set_to_prev_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_prev_func(a->c.width, a->c.height); break; case CAMERA_WMODE_CAP: if (cur_sensor_info->handler->cam_set_to_cap_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_cap_func(a->c.width, a->c.height); break; case CAMERA_WMODE_REC: if (cur_sensor_info->handler->cam_set_to_record_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_record_func(a->c.width, a->c.height); break; default : if (cur_sensor_info->handler->cam_set_to_record_func != NULL) bRet = cur_sensor_info->handler->cam_set_to_record_func(a->c.width, a->c.height); break; } if ( bRet ) ret = 0; return ret; }
static int sensor_ctrl_ae_weight(struct v4l2_subdev *sd, int cmd, int val) { struct sensor_info *info = to_sensor(sd); u8 *value = (u8 *)&val; int ret = 0; sensor_dbg("cmd = %x val = %d", cmd, val); switch (cmd) { case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x1_2: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x1_2, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x1_2, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_1x3_4: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x3_4, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_1x3_4, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x1_2: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x1_2, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x1_2, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_2x3_4: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x3_4, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_2x3_4, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x1_2: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x1_2, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x1_2, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_3x3_4: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x3_4, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_3x3_4, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x1_2: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x1_2, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x1_2, (u8)value[0], I2C_8BIT); } break; case V4L2_CID_SENSOR_SET_AE_WEIGHT_4x3_4: if (info->status == STATUS_STREAMING) { ret = sensor_add_request(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x3_4, value[0]); } else { ret = vision_sensor_write_reg(sd, SENSOR_REG_VIS_AE_WINDOW_WEIGHT_4x3_4, (u8)value[0], I2C_8BIT); } break; default : sensor_err("Unknown CID"); ret = -EINVAL; break; } if (ret < 0) sensor_err("Failed to set ae weight(CID:%x)", cmd); return ret; }