diff options
Diffstat (limited to 'drivers/media/video/s5k5bafx-v2.c')
-rw-r--r-- | drivers/media/video/s5k5bafx-v2.c | 323 |
1 files changed, 188 insertions, 135 deletions
diff --git a/drivers/media/video/s5k5bafx-v2.c b/drivers/media/video/s5k5bafx-v2.c index 24b0ef1..903214b 100644 --- a/drivers/media/video/s5k5bafx-v2.c +++ b/drivers/media/video/s5k5bafx-v2.c @@ -24,9 +24,7 @@ #include "s5k5bafx-v2.h" #ifdef CONFIG_CPU_FREQ #include <mach/cpufreq.h> -#endif -#ifdef S5K5BAFX_USLEEP -#include <linux/hrtimer.h> +#include <linux/cpufreq.h> #endif static const struct s5k5bafx_fps s5k5bafx_framerates[] = { @@ -67,37 +65,33 @@ static const struct s5k5bafx_regs reg_datas = { }, .preview_start = S5K5BAFX_REGSET_TABLE(s5k5bafx_preview), .capture_start = S5K5BAFX_REGSET_TABLE(s5k5bafx_capture), - .init = S5K5BAFX_REGSET_TABLE(s5k5bafx_common), - .init_vt = S5K5BAFX_REGSET_TABLE(s5k5bafx_vt_common), - .init_vt_wifi = S5K5BAFX_REGSET_TABLE(s5k5bafx_vt_wifi_common), -#if defined(CONFIG_TARGET_LOCALE_KOR) || \ - defined(CONFIG_TARGET_LOCALE_NAATT) || \ - defined(CONFIG_MACH_P8LTE) - .init_recording = S5K5BAFX_REGSET_TABLE(s5k5bafx_recording_60Hz_common), -#else - .init_recording = S5K5BAFX_REGSET_TABLE(s5k5bafx_recording_50Hz_common), + .init = { + S5K5BAFX_REGSET(CAM_VT_MODE_NONE, + s5k5bafx_common), + S5K5BAFX_REGSET(CAM_VT_MODE_3G, + s5k5bafx_vt_common), + S5K5BAFX_REGSET(CAM_VT_MODE_VOIP, + s5k5bafx_vt_wifi_common), +#ifdef CONFIG_MACH_U1 + S5K5BAFX_REGSET(CAM_VT_MODE_FD, + s5k5bafx_FD_common), #endif + }, + .init_recording = { + S5K5BAFX_REGSET(ANTI_BANDING_AUTO, + s5k5bafx_recording_50Hz_common), + S5K5BAFX_REGSET(ANTI_BANDING_50HZ, + s5k5bafx_recording_50Hz_common), + S5K5BAFX_REGSET(ANTI_BANDING_60HZ, + s5k5bafx_recording_60Hz_common), + }, .stream_stop = S5K5BAFX_REGSET_TABLE(s5k5bafx_stream_stop), +#ifdef SUPPORT_FACTORY_TEST .dtp_on = S5K5BAFX_REGSET_TABLE(s5k5bafx_pattern_on), .dtp_off = S5K5BAFX_REGSET_TABLE(s5k5bafx_pattern_off), +#endif }; -/** - * Use msleep() if the sleep time is over 1000 us. - */ -static void __used s5k5bafx_usleep(u32 usecs) -{ - ktime_t expires; - u64 add_time = (u64)usecs * 1000; - - if (unlikely(!usecs)) - return; - - expires = ktime_add_ns(ktime_get(), add_time); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_hrtimeout(&expires, HRTIMER_MODE_ABS); -} - static inline int s5k5bafx_read(struct i2c_client *client, u16 subaddr, u16 *data) { @@ -434,7 +428,7 @@ static int s5k5bafx_write_regs_from_sd(struct v4l2_subdev *sd, u8 s_name[]) if ((temp & S5K5BAFX_DELAY) == S5K5BAFX_DELAY) { delay = temp & 0xFFFF; - debug_msleep(sd, delay); + msleep_debug(sd, delay); continue; } @@ -513,7 +507,7 @@ static int s5k5bafx_write_regs(struct v4l2_subdev *sd, if ((temp & S5K5BAFX_DELAY) == S5K5BAFX_DELAY) { delay = temp & 0xFFFF; - debug_msleep(sd, delay); + msleep_debug(sd, delay); continue; } @@ -572,9 +566,10 @@ s5k5bafx_burst_write: } #ifdef S5K5BAFX_USLEEP - if (unlikely(state->vt_mode)) + if (unlikely(state->vt_mode)) { if (!(num%200)) - s5k5bafx_usleep(3); + usleep_range(3, 5) + } #endif } @@ -764,7 +759,7 @@ static int s5k5bafx_set_preview_start(struct v4l2_subdev *sd) if (state->check_dataline) err = s5k5bafx_check_dataline(sd, 1); #endif - CHECK_ERR_MSG(err, "fail to make preview\n") + CHECK_ERR_MSG(err, "fail to make preview\n"); return 0; } @@ -843,12 +838,8 @@ static int s5k5bafx_init_regs(struct v4l2_subdev *sd) return 0; } -#ifdef NEW_CAM_DRV static int s5k5bafx_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) -#else -static int s5k5bafx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -#endif { cam_trace("E\n"); return 0; @@ -897,12 +888,8 @@ static int s5k5bafx_enum_frameintervals(struct v4l2_subdev *sd, } #endif -#ifdef NEW_CAM_DRV static int s5k5bafx_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) -#else -static int s5k5bafx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -#endif { int err = 0; @@ -911,12 +898,8 @@ static int s5k5bafx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) return err; } -#ifdef NEW_CAM_DRV static int s5k5bafx_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) -#else -static int s5k5bafx_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) -#endif { struct s5k5bafx_state *state = to_state(sd); u32 *width = NULL, *height = NULL; @@ -927,12 +910,8 @@ static int s5k5bafx_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) * We need to check here what are the formats the camera support, and * set the most appropriate one according to the request from FIMC */ -#ifdef NEW_CAM_DRV v4l2_fill_pix_format(&state->req_fmt, fmt); state->req_fmt.priv = fmt->field; -#else - memcpy(&state->req_fmt, &fmt->fmt.pix, sizeof(fmt->fmt.pix)); -#endif switch (state->req_fmt.priv) { case V4L2_PIX_FMT_MODE_PREVIEW: @@ -991,6 +970,82 @@ static int s5k5bafx_set_frame_rate(struct v4l2_subdev *sd, u32 fps) return 0; } +static int s5k5bafx_set_exposure(struct v4l2_subdev *sd, s32 val) +{ + struct s5k5bafx_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("set_exposure: val=%d\n", val); + +#ifdef SUPPORT_FACTORY_TEST + if (state->check_dataline) + return 0; +#endif + if ((val < EV_MINUS_4) || (val >= EV_MAX_V4L2)) { + cam_err("%s: ERROR, invalid value(%d)\n", __func__, val); + return -EINVAL; + } + + err = s5k5bafx_set_from_table(sd, "ev", state->regs->ev, + ARRAY_SIZE(state->regs->ev), GET_EV_INDEX(val)); + CHECK_ERR_MSG(err, "i2c_write for set brightness\n") + + return 0; +} + +static int s5k5bafx_set_blur(struct v4l2_subdev *sd, s32 val) +{ + struct s5k5bafx_state *state = to_state(sd); + int err = -EINVAL; + + cam_info("set_blur: val=%d\n", val); + +#ifdef SUPPORT_FACTORY_TEST + if (state->check_dataline) + return 0; +#endif + if (unlikely(val < BLUR_LEVEL_0 || val >= BLUR_LEVEL_MAX)) { + cam_err("%s: ERROR, Invalid blur(%d)\n", __func__, val); + return -EINVAL; + } + + err = s5k5bafx_set_from_table(sd, "blur", state->regs->blur, + ARRAY_SIZE(state->regs->blur), val); + CHECK_ERR_MSG(err, "i2c_write for set blur\n") + + return 0; +} + +static int s5k5bafx_set_vtmode(struct v4l2_subdev *sd, s32 val) +{ + struct s5k5bafx_state *state = to_state(sd); + + cam_dbg("set_vtmode %d\n", val); + + if (unlikely((u32)val >= CAM_VT_MODE_MAX)) { + cam_err("vt_mode: not supported (%d)\n", val); + state->vt_mode = CAM_VT_MODE_NONE; + } else + state->vt_mode = val; + + return 0; +} + +static int s5k5bafx_set_antibanding(struct v4l2_subdev *sd, s32 val) +{ + struct s5k5bafx_state *state = to_state(sd); + + cam_dbg("set_antibanding [%d],[%d]\n", state->anti_banding, val); + + if (unlikely((u32)val >= ANTI_BANDING_MAX)) { + cam_err("antibanding: not supported (%d)\n", val); + state->anti_banding = ANTI_BANDING_AUTO; + } else + state->anti_banding = val; + + return 0; +} + static int s5k5bafx_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { int err = 0; @@ -1077,7 +1132,7 @@ static int s5k5bafx_wait_steamoff(struct v4l2_subdev *sd) if (state->pdata->streamoff_delay > elapsed_msec) { cam_info("stream-off: %dms + %dms\n", elapsed_msec, state->pdata->streamoff_delay - elapsed_msec); - debug_msleep(sd, state->pdata->streamoff_delay - elapsed_msec); + msleep_debug(sd, state->pdata->streamoff_delay - elapsed_msec); } else cam_info("stream-off: %dms\n", elapsed_msec); @@ -1091,7 +1146,7 @@ static int s5k5bafx_control_stream(struct v4l2_subdev *sd, u32 cmd) struct s5k5bafx_state *state = to_state(sd); int err = -EINVAL; - if (unlikely(cmd != STREAM_STOP)) + if (unlikely(!state->pdata->is_mipi || (cmd != STREAM_STOP))) return 0; cam_info("STREAM STOP!!\n"); @@ -1103,7 +1158,7 @@ static int s5k5bafx_control_stream(struct v4l2_subdev *sd, u32 cmd) do_gettimeofday(&state->stream_time.before_time); state->need_wait_streamoff = 1; #else - debug_msleep(sd, state->pdata->streamoff_delay); + msleep_debug(sd, state->pdata->streamoff_delay); #endif return 0; } @@ -1129,32 +1184,25 @@ static int s5k5bafx_init(struct v4l2_subdev *sd, u32 val) #endif /* set initial regster value */ if (state->sensor_mode == SENSOR_CAMERA) { - if (!state->vt_mode) { - cam_info("load camera common setting\n"); - err = s5k5bafx_set_from_table(sd, "init", - &state->regs->init, 1, 0); - } else { - if (state->vt_mode == 1) { - cam_info("load camera VT call setting\n"); - err = s5k5bafx_set_from_table(sd, "init_vt", - &state->regs->init_vt, 1, 0); - } else { - cam_info("load camera WIFI VT call setting\n"); - err = s5k5bafx_set_from_table(sd, - "init_vt_wifi", - &state->regs->init_vt_wifi, 1, 0); - } - } + cam_info("load camera common (vt %d)\n", *state->init_mode); + err = s5k5bafx_set_from_table(sd, "init", + state->regs->init, ARRAY_SIZE(state->regs->init), + *state->init_mode); } else { - cam_info("load recording setting\n"); + cam_info("load recording (anti %d)\n", state->anti_banding); err = s5k5bafx_set_from_table(sd, "init_recording", - &state->regs->init_recording, 1, 0); + state->regs->init_recording, + ARRAY_SIZE(state->regs->init_recording), + state->anti_banding); } #if defined(CONFIG_USE_SW_I2C) && defined(CONFIG_CPU_FREQ) exynos_cpufreq_lock_free(DVFS_LOCK_ID_CAM); #endif CHECK_ERR_MSG(err, "failed to initialize camera device\n"); + if (state->pdata->init_streamoff) + s5k5bafx_control_stream(sd, STREAM_STOP); + state->initialized = 1; if (state->req_fps >= 0) { @@ -1224,6 +1272,14 @@ static int s5k5bafx_s_config(struct v4l2_subdev *sd, else state->req_fmt.pixelformat = state->pdata->pixelformat; +#if defined(CONFIG_TARGET_LOCALE_KOR) || \ + defined(CONFIG_TARGET_LOCALE_NAATT) || \ + defined(CONFIG_MACH_P8LTE) + s5k5bafx_set_antibanding(sd, ANTI_BANDING_60HZ); +#endif + + state->init_mode = &state->vt_mode; + #ifdef CONFIG_LOAD_FILE err = loadFile(); CHECK_ERR_MSG(err, "failed to load file ERR=%d\n", err) @@ -1303,52 +1359,6 @@ static int s5k5bafx_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static int s5k5bafx_set_exposure(struct v4l2_subdev *sd, s32 val) -{ - struct s5k5bafx_state *state = to_state(sd); - int err = -EINVAL; - - cam_info("set_exposure: val=%d\n", val); - -#ifdef SUPPORT_FACTORY_TEST - if (state->check_dataline) - return 0; -#endif - if ((val < EV_MINUS_4) || (val >= EV_MAX_V4L2)) { - cam_err("%s: ERROR, invalid value(%d)\n", __func__, val); - return -EINVAL; - } - - err = s5k5bafx_set_from_table(sd, "ev", state->regs->ev, - ARRAY_SIZE(state->regs->ev), GET_EV_INDEX(val)); - CHECK_ERR_MSG(err, "i2c_write for set brightness\n") - - return 0; -} - -static int s5k5bafx_set_blur(struct v4l2_subdev *sd, s32 val) -{ - struct s5k5bafx_state *state = to_state(sd); - int err = -EINVAL; - - cam_info("set_blur: val=%d\n", val); - -#ifdef SUPPORT_FACTORY_TEST - if (state->check_dataline) - return 0; -#endif - if (unlikely(val < BLUR_LEVEL_0 || val >= BLUR_LEVEL_MAX)) { - cam_err("%s: ERROR, Invalid blur(%d)\n", __func__, val); - return -EINVAL; - } - - err = s5k5bafx_set_from_table(sd, "blur", state->regs->blur, - ARRAY_SIZE(state->regs->blur), val); - CHECK_ERR_MSG(err, "i2c_write for set blur\n") - - return 0; -} - #if (0) static int s5k5bafx_check_dataline_stop(struct v4l2_subdev *sd) { @@ -1413,7 +1423,7 @@ static int s5k5bafx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) break; case V4L2_CID_CAMERA_VT_MODE: - state->vt_mode = ctrl->value; + err = s5k5bafx_set_vtmode(sd, ctrl->value); break; case V4L2_CID_CAMERA_SENSOR_MODE: @@ -1430,6 +1440,10 @@ static int s5k5bafx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) err = s5k5bafx_check_sensor_status(sd); break; + case V4L2_CID_CAMERA_ANTI_BANDING: + err = s5k5bafx_set_antibanding(sd, ctrl->value); + break; + #ifdef SUPPORT_FACTORY_TEST case V4L2_CID_CAMERA_CHECK_DATALINE: state->check_dataline = ctrl->value; @@ -1453,33 +1467,19 @@ static int s5k5bafx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static const struct v4l2_subdev_core_ops s5k5bafx_core_ops = { .init = s5k5bafx_init, /* initializing API */ -#if 0 - .queryctrl = s5k5bafx_queryctrl, - .querymenu = s5k5bafx_querymenu, -#endif .g_ctrl = s5k5bafx_g_ctrl, .s_ctrl = s5k5bafx_s_ctrl, }; static const struct v4l2_subdev_video_ops s5k5bafx_video_ops = { /*.s_crystal_freq = s5k5bafx_s_crystal_freq,*/ -#ifdef NEW_CAM_DRV .g_mbus_fmt = s5k5bafx_g_mbus_fmt, .s_mbus_fmt = s5k5bafx_s_mbus_fmt, -#else - .g_fmt = s5k5bafx_g_fmt, - .s_fmt = s5k5bafx_s_fmt, -#endif .s_stream = s5k5bafx_s_stream, .enum_framesizes = s5k5bafx_enum_framesizes, /*.enum_frameintervals = s5k5bafx_enum_frameintervals,*/ -#ifdef NEW_CAM_DRV /* .enum_mbus_fmt = s5k5bafx_enum_mbus_fmt, */ .try_mbus_fmt = s5k5bafx_try_mbus_fmt, -#else - /*.enum_fmt = s5k5bafx_enum_fmt,*/ - .try_fmt = s5k5bafx_try_fmt, -#endif .g_parm = s5k5bafx_g_parm, .s_parm = s5k5bafx_s_parm, }; @@ -1489,6 +1489,7 @@ static const struct v4l2_subdev_ops s5k5bafx_ops = { .video = &s5k5bafx_video_ops, }; +#if !defined(CONFIG_MACH_PX) ssize_t s5k5bafx_camera_type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1498,7 +1499,54 @@ ssize_t s5k5bafx_camera_type_show(struct device *dev, return sprintf(buf, "%s\n", cam_type); } -static DEVICE_ATTR(camera_type, S_IRUGO, s5k5bafx_camera_type_show, NULL); +static DEVICE_ATTR(front_camtype, S_IRUGO, s5k5bafx_camera_type_show, NULL); + +ssize_t s5k5bafx_startup_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + cam_info("%s\n", __func__); + + return sprintf(buf, "%d\n", SMARTSTAY_STARTUP_TIME); +} + +static DEVICE_ATTR(startup_time, S_IRUGO, s5k5bafx_startup_time_show, NULL); + +static struct device *s5k5bafx_sysdev; + +static int s5k5bafx_create_sysfs(void) +{ + cam_dbg("%s\n", __func__); + + s5k5bafx_sysdev = device_create(camera_class, NULL, + MKDEV(CAM_MAJOR, 1), NULL, "front"); + if (IS_ERR(s5k5bafx_sysdev)) { + cam_err("failed to create device s5k5bafx_dev!\n"); + return 0; + } + + if (device_create_file(s5k5bafx_sysdev, &dev_attr_front_camtype) < 0) { + cam_err("failed to create device file, %s\n", + dev_attr_front_camtype.attr.name); + } + + if (device_create_file(s5k5bafx_sysdev, &dev_attr_startup_time) < 0) { + cam_err("failed to create device file, %s\n", + dev_attr_startup_time.attr.name); + } + + return 0; +} + +static int s5k5bafx_remove_sysfs(void) +{ + device_remove_file(s5k5bafx_sysdev, &dev_attr_front_camtype); + device_remove_file(s5k5bafx_sysdev, &dev_attr_startup_time); + device_destroy(camera_class, s5k5bafx_sysdev->devt); + s5k5bafx_sysdev = NULL; + + return 0; +} +#endif /* !CONFIG_MACH_PX */ /* * s5k5bafx_probe @@ -1546,7 +1594,6 @@ static int s5k5bafx_remove(struct i2c_client *client) state->initialized = 0; - device_remove_file(&client->dev, &dev_attr_camera_type); v4l2_device_unregister_subdev(sd); #ifdef S5K5BAFX_BURST_MODE kfree(state->burst_buf); @@ -1580,13 +1627,19 @@ static struct i2c_driver v4l2_i2c_driver = { static int __init v4l2_i2c_drv_init(void) { - pr_info("%s: %s called\n", __func__, S5K5BAFX_DRIVER_NAME); /* dslim*/ + pr_debug("%s: init\n", S5K5BAFX_DRIVER_NAME); +#if !defined(CONFIG_MACH_PX) + s5k5bafx_create_sysfs(); +#endif return i2c_add_driver(&v4l2_i2c_driver); } static void __exit v4l2_i2c_drv_cleanup(void) { - pr_info("%s: %s called\n", __func__, S5K5BAFX_DRIVER_NAME); /* dslim*/ + pr_debug("%s: clean\n", S5K5BAFX_DRIVER_NAME); +#if !defined(CONFIG_MACH_PX) + s5k5bafx_remove_sysfs(); +#endif i2c_del_driver(&v4l2_i2c_driver); } |