aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/slp_s5k4ecgx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/slp_s5k4ecgx.c')
-rw-r--r--drivers/media/video/slp_s5k4ecgx.c2335
1 files changed, 0 insertions, 2335 deletions
diff --git a/drivers/media/video/slp_s5k4ecgx.c b/drivers/media/video/slp_s5k4ecgx.c
deleted file mode 100644
index c78ca71..0000000
--- a/drivers/media/video/slp_s5k4ecgx.c
+++ /dev/null
@@ -1,2335 +0,0 @@
-/*
- * Driver for S5K4ECGX from Samsung Electronics
- *
- * 5Mp CMOS Image Sensor SoC with an Embedded Image Processor
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <media/v4l2-device.h>
-#include <linux/delay.h>
-#include <linux/version.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <linux/workqueue.h>
-#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
-#include <linux/videodev2_exynos_media.h>
-#include <linux/videodev2_exynos_camera.h>
-#endif
-#include <media/s5k4ecgx_platform.h>
-
-#include "slp_s5k4ecgx.h"
-
-#ifdef S5K4ECGX_USLEEP
-#include <linux/hrtimer.h>
-#endif
-
-#define S5K4ECGX_BURST_MODE
-#ifdef S5K4ECGX_BURST_MODE
- static u16 addr, value;
-
- static int len;
- static u8 buf[SZ_4K] = {0,};
-#else
- static u8 buf[4] = {0,};
-#endif
-
-/* 5M mem size */
-#define S5K4ECGX_INTLV_DATA_MAXSIZE (5 << 20)
-
-static const struct s5k4ecgx_framesize preview_frmsizes[] = {
- { S5K4ECGX_PREVIEW_640, 640, 480 },
- { S5K4ECGX_PREVIEW_176, 640, 480 },
- { S5K4ECGX_PREVIEW_320, 320, 240 },
- { S5K4ECGX_PREVIEW_720, 720, 480 },
- { S5K4ECGX_PREVIEW_800, 800, 480 },
- { S5K4ECGX_PREVIEW_1280, 1280, 720 },
-};
-
-static const struct s5k4ecgx_framesize capture_frmsizes[] = {
- { S5K4ECGX_CAPTURE_5MP, 2560, 1920 },
- { S5K4ECGX_CAPTURE_3MP, 2048, 1536 },
- { S5K4ECGX_CAPTURE_2MP, 1600, 1200 },
- { S5K4ECGX_CAPTURE_1MP, 1280, 960 },
- { S5K4ECGX_CAPTURE_XGA, 1024, 768 },
- { S5K4ECGX_CAPTURE_VGA, 640, 480 },
-};
-
-#define CHECK_ERR(x) if (unlikely((x) < 0)) { \
- cam_err("i2c failed, err %d\n", x); \
- return x; \
- }
-
-#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
-
-#ifdef S5K4ECGX_USLEEP
-/*
- * Use msleep() if the sleep time is over 1000 us.
-*/
-static void s5k4ecgx_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);
-}
-#endif
-
-static void s5k4ecgx_cam_delay(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
-
- if (state->scene_mode == SCENE_MODE_NIGHTSHOT ||
- state->scene_mode == SCENE_MODE_FIREWORKS)
- msleep(250);
- else
- msleep(200);
-}
-
-static inline int s5k4ecgx_read(struct i2c_client *client,
- u16 subaddr, u16 *data)
-{
- u8 buf[2];
- int err = 0;
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .len = 2,
- .buf = buf,
- };
-
- *(u16 *)buf = cpu_to_be16(subaddr);
-
- err = i2c_transfer(client->adapter, &msg, 1);
- if (unlikely(err < 0))
- cam_err("ERR: %d register read fail\n", __LINE__);
-
- msg.flags = I2C_M_RD;
-
- err = i2c_transfer(client->adapter, &msg, 1);
- if (unlikely(err < 0))
- cam_err("ERR: %d register read fail\n", __LINE__);
-
- *data = ((buf[0] << 8) | buf[1]);
-
- return err;
-}
-
-static inline int s5k4ecgx_write(struct i2c_client *client,
- u32 packet)
-{
- u8 buf[4];
- int err = 0, retry_count = 5;
-
- struct i2c_msg msg = {
- .addr = client->addr,
- .flags = 0,
- .buf = buf,
- .len = 4,
- };
-
- if (!client->adapter) {
- cam_err("ERR - can't search i2c client adapter\n");
- return -EIO;
- }
-
- while (retry_count--) {
- *(u32 *)buf = cpu_to_be32(packet);
- err = i2c_transfer(client->adapter, &msg, 1);
- if (likely(err == 1))
- break;
- mdelay(10);
- }
-
- if (unlikely(err < 0)) {
- cam_err("ERR - 0x%08x write failed err=%d\n",
- (u32)packet, err);
- return err;
- }
-
- return (err != 1) ? -1 : 0;
-}
-
-/*
-* Read a register.
-*/
-static int s5k4ecgx_read_reg(struct v4l2_subdev *sd,
- u16 page, u16 addr, u16 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- u32 page_cmd = (0x002C << 16) | page;
- u32 addr_cmd = (0x002E << 16) | addr;
- int err = 0;
-
- cam_dbg("page_cmd=0x%X, addr_cmd=0x%X\n", page_cmd, addr_cmd);
-
- err = s5k4ecgx_write(client, page_cmd);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, addr_cmd);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, val);
- CHECK_ERR(err);
-
- return 0;
-}
-
-/* program multiple registers */
-static int s5k4ecgx_write_regs(struct v4l2_subdev *sd,
- const u32 *packet, u32 num)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int ret = -EAGAIN;
- u32 temp = 0;
- u16 delay = 0;
- int retry_count = 5;
-
- struct i2c_msg msg = {
- msg.addr = client->addr,
- msg.flags = 0,
- msg.len = 4,
- msg.buf = buf,
- };
-
- while (num--) {
- temp = *packet++;
-
- if ((temp & S5K4ECGX_DELAY) == S5K4ECGX_DELAY) {
- delay = temp & 0xFFFF;
- cam_dbg("line(%d):delay(0x%x):delay(%d)\n",
- __LINE__, delay, delay);
- msleep(delay);
- continue;
- }
-
-#ifdef S5K4ECGX_BURST_MODE
- addr = temp >> 16;
- value = temp & 0xFFFF;
-
- switch (addr) {
- case 0x0F12:
- if (len == 0) {
- buf[len++] = addr >> 8;
- buf[len++] = addr & 0xFF;
- }
- buf[len++] = value >> 8;
- buf[len++] = value & 0xFF;
-
- if ((*packet >> 16) != addr) {
- msg.len = len;
- goto s5k4ecgx_burst_write;
- }
- break;
-
- case 0xFFFF:
- break;
-
- default:
- msg.len = 4;
- *(u32 *)buf = cpu_to_be32(temp);
- goto s5k4ecgx_burst_write;
- }
-
- continue;
-#else
- *(u32 *)buf = cpu_to_be32(temp);
-#endif
-
-#ifdef S5K4ECGX_BURST_MODE
-s5k4ecgx_burst_write:
- len = 0;
-#endif
- retry_count = 5;
-
- while (retry_count--) {
- ret = i2c_transfer(client->adapter, &msg, 1);
- if (likely(ret == 1))
- break;
- mdelay(10);
- }
-
- if (unlikely(ret < 0)) {
- cam_err("ERR - 0x%08x write failed err=%d\n", \
- (u32)packet, ret);
- break;
- }
- }
-
- if (unlikely(ret < 0)) {
- cam_err("fail to write registers!!\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int camera_flash_manual_ctrl(struct v4l2_subdev *sd, int mode)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int ret = 0;
- cam_dbg(" E\n");
- if (mode == CAM_FLASH_ON) {
- /* FLASH mode */
- ret = state->pdata->flash_ctrl(CAM_FLASH_ON);
- state->preflash = PREFLASH_ON;
- } else if (mode == CAM_FLASH_TORCH) {
- /* TORCH mode */
- ret = state->pdata->flash_ctrl(CAM_FLASH_TORCH);
- state->preflash = PREFLASH_ON;
- } else {
- ret = state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- }
- return ret;
-}
-
-static int s5k4ecgx_get_exif(struct v4l2_subdev *sd)
-{
- return 0;
-}
-
-static int s5k4ecgx_get_lux(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int msb = 0;
- int lsb = 0;
- int cur_lux = 0;
- bool lowlight = false;
- int err = 0;
- cam_dbg(" E\n");
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2C18);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&lsb);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&msb);
- CHECK_ERR(err);
-
- cur_lux = (msb << 16) | lsb;
-
- if (cur_lux >= 0x32)
- lowlight = false;
- else
- lowlight = true;
-
- state->lowlight = lowlight;
-
- cam_info("%s, s5k4ecgx_status.lowlight is %d\n", __func__,
- state->lowlight);
- /*this value is under 0x0032 in low light condition */
- return err;
-}
-
-static int s5k4ecgx_ae_stable(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct s5k4ecgx_state *state = to_state(sd);
- int val = 0;
- int err = 0;
- int cnt;
- do {
- if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_info("af_start_preflash: AF is cancelled!\n");
- state->focus.status = CAMERA_AF_STATUS_MAX;
- break;
- }
-
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2C74);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&val);
- CHECK_ERR(err);
-
- if (val == 0x1)
- break;
-
- s5k4ecgx_usleep(10*1000);
-
- } while (cnt < 40);
- cam_info("%s, ret value is %d\n", __func__,
- val);
-
- return err;
-}
-
-static int s5k4ecgx_set_awb_lock(struct v4l2_subdev *sd, int val)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
- cam_info(" E\n");
-
- if (val == state->awb_lock)
- return 0;
-
- if (val)
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_lock_EVT1,\
- sizeof(s5k4ecgx_awb_lock_EVT1) / \
- sizeof(s5k4ecgx_awb_lock_EVT1[0]));
- else
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_unlock_EVT1,\
- sizeof(s5k4ecgx_awb_unlock_EVT1) / \
- sizeof(s5k4ecgx_awb_unlock_EVT1[0]));
-
- CHECK_ERR(err);
- state->awb_lock = val;
- cam_info("awb %s\n", val ? "lock" : "unlock");
- return err;
-}
-
-static int s5k4ecgx_set_ae_lock(struct v4l2_subdev *sd, int val)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
- cam_info(" E\n");
-
- if (val == state->ae_lock)
- return 0;
-
- if (val)
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_lock_EVT1,\
- sizeof(s5k4ecgx_ae_lock_EVT1) / \
- sizeof(s5k4ecgx_ae_lock_EVT1[0]));
- else
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_unlock_EVT1,\
- sizeof(s5k4ecgx_ae_unlock_EVT1) / \
- sizeof(s5k4ecgx_ae_unlock_EVT1[0]));
-
- CHECK_ERR(err);
- state->ae_lock = val;
- cam_info("ae %s\n", val ? "lock" : "unlock");
- return err;
-}
-
-static int s5k4ecgx_check_dataline(struct v4l2_subdev *sd, s32 val)
-{
- cam_info("DTP %s\n", val ? "ON" : "OFF");
- return 0;
-}
-
-static int s5k4ecgx_debug_sensor_status(struct v4l2_subdev *sd)
-{
- return 0;
-}
-
-static int s5k4ecgx_check_sensor_status(struct v4l2_subdev *sd)
-{
- return 0;
-}
-
-static inline int s5k4ecgx_check_esd(struct v4l2_subdev *sd)
-{
- return 0;
-}
-
-static int s5k4ecgx_set_preview_start(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -EINVAL;
-
- cam_info(" E\n");
-
- if ((state->runmode == RUNMODE_NOTREADY) ||
- (state->runmode == RUNMODE_CAPTURING)) {
- cam_err("%s: ERROR - Invalid runmode\n", __func__);
- return -EPERM;
- }
-
- state->focus.status = CAMERA_AF_STATUS_MAX;
-
- if (state->runmode == RUNMODE_CAPTURE_STOP) {
- if (state->preflash != PREFLASH_OFF) {
- err = state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- }
- /* AE/AWB unlock */
- err = s5k4ecgx_set_ae_lock(sd, false);
- err = s5k4ecgx_set_awb_lock(sd, false);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Preview_Return_EVT1,\
- sizeof(s5k4ecgx_Preview_Return_EVT1) / \
- sizeof(s5k4ecgx_Preview_Return_EVT1[0]));
- } else {
- switch (state->preview_frmsizes->index) {
- case S5K4ECGX_PREVIEW_1280:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_1280_Preview_EVT1,\
- sizeof(s5k4ecgx_1280_Preview_EVT1) / \
- sizeof(s5k4ecgx_1280_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_1280\n");
- break;
- case S5K4ECGX_PREVIEW_800:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_800_Preview_EVT1,\
- sizeof(s5k4ecgx_800_Preview_EVT1) / \
- sizeof(s5k4ecgx_800_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_800\n");
- break;
- case S5K4ECGX_PREVIEW_720:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_720_Preview_EVT1,\
- sizeof(s5k4ecgx_720_Preview_EVT1) / \
- sizeof(s5k4ecgx_720_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_720\n");
- break;
- case S5K4ECGX_PREVIEW_320:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_320_Preview_EVT1,\
- sizeof(s5k4ecgx_320_Preview_EVT1) / \
- sizeof(s5k4ecgx_320_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_320\n");
- break;
- case S5K4ECGX_PREVIEW_176:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_176_Preview_EVT1,\
- sizeof(s5k4ecgx_176_Preview_EVT1) / \
- sizeof(s5k4ecgx_176_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_640\n");
- break;
- case S5K4ECGX_PREVIEW_640:
- default:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_640_Preview_EVT1,\
- sizeof(s5k4ecgx_640_Preview_EVT1) / \
- sizeof(s5k4ecgx_640_Preview_EVT1[0]));
- cam_info("S5K4ECGX_PREVIEW_640\n");
- break;
- }
-
- if (state->check_dataline)
- err = s5k4ecgx_check_dataline(sd, 1);
- }
-
- if (unlikely(err)) {
- cam_err("fail to make preview\n");
- return err;
- }
-
- state->runmode = RUNMODE_RUNNING;
-
- return 0;
-}
-
-static int s5k4ecgx_set_preview_stop(struct v4l2_subdev *sd)
-{
- int err = 0;
- cam_info("do nothing.\n");
-
- return err;
-}
-
-static int s5k4ecgx_check_capture_status(struct v4l2_subdev *sd)
-{
- int cnt = 0;
- int status = 0;
- int err = 0;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- msleep(20);
- while (cnt < 150) {
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E0244);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)
- &status);
- CHECK_ERR(err);
-
- if (!status)
- break;
- msleep(20);
- cnt++;
- }
- if (cnt)
- pr_info("[s5k4ecgx] wait time for capture frame : %dms\n",
- cnt * 10);
- if (status)
- pr_info("[s5k4ecgx] take picture failed.\n");
-
- return 0;
-}
-
-static int s5k4ecgx_set_capture_start(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -EINVAL;
- cam_info(" E\n");
- /* check lowlight */
- if (state->lowlight) {
- /* check scene mode */
- if (state->scene_mode != SCENE_MODE_NIGHTSHOT &&
- state->scene_mode != SCENE_MODE_FIREWORKS) {
- /*low light capture start */
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_Low_Cap_On_EVT1, \
- sizeof(s5k4ecgx_Low_Cap_On_EVT1) / \
- sizeof(s5k4ecgx_Low_Cap_On_EVT1[0]));
- cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Low_Cap_On_EVT1\n");
-
- /* check flash on */
- if (state->flash_mode == FLASH_MODE_AUTO ||
- state->flash_mode == FLASH_MODE_ON) {
- /* AE/AWB unlock */
- err = s5k4ecgx_set_ae_lock(sd, false);
- CHECK_ERR(err);
- err = s5k4ecgx_set_awb_lock(sd, false);
- CHECK_ERR(err);
- /* Main flash on */
- state->pdata->flash_ctrl(CAM_FLASH_ON);
- state->preflash = PREFLASH_ON;
- /* 200ms AE delay */
- msleep(200);
- } else
- s5k4ecgx_cam_delay(sd);
- }
- } else {
- /* check flash on */
- if (state->flash_mode == FLASH_MODE_ON) {
- /* AE/AWB unlock */
- err = s5k4ecgx_set_ae_lock(sd, false);
- CHECK_ERR(err);
- err = s5k4ecgx_set_awb_lock(sd, false);
- CHECK_ERR(err);
- /* Main flash on */
- state->pdata->flash_ctrl(CAM_FLASH_ON);
- state->preflash = PREFLASH_ON;
- /* 200ms AE delay */
- msleep(200);
- }
- }
-
- /*capture start*/
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Capture_Start_EVT1, \
- sizeof(s5k4ecgx_Capture_Start_EVT1) / \
- sizeof(s5k4ecgx_Capture_Start_EVT1[0]));
- cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Capture_Start_EVT1\n");
-
- state->runmode = RUNMODE_CAPTURING;
-
- /*capture delay*/
- err = s5k4ecgx_check_capture_status(sd);
-
- /* FIX later - temp code*/
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
-
- if (unlikely(err)) {
- cam_err("failed to make capture\n");
- return err;
- }
-
- s5k4ecgx_get_exif(sd);
-
- return err;
-}
-
-static int s5k4ecgx_set_sensor_mode(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct s5k4ecgx_state *state = to_state(sd);
-
- if ((ctrl->value != SENSOR_CAMERA) &&
- (ctrl->value != SENSOR_MOVIE)) {
- cam_err("ERR: Not support.(%d)\n", ctrl->value);
- return -EINVAL;
- }
-
- state->sensor_mode = ctrl->value;
-
- return 0;
-}
-
-static int s5k4ecgx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
-{
- cam_dbg("E\n");
- return 0;
-}
-
-static int s5k4ecgx_enum_framesizes(struct v4l2_subdev *sd, \
- struct v4l2_frmsizeenum *fsize)
-{
- struct s5k4ecgx_state *state = to_state(sd);
-
- cam_dbg("s5k4ecgx_enum_framesizes E\n");
-
- /*
- * Return the actual output settings programmed to the camera
- *
- * The camera interface should read this value, this is the resolution
- * at which the sensor would provide framedata to the camera i/f
- * In case of image capture,
- * this returns the default camera resolution (VGA)
- */
- if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) {
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = state->capture_frmsizes->width;
- fsize->discrete.height = state->capture_frmsizes->height;
- } else {
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = state->preview_frmsizes->width;
- fsize->discrete.height = state->preview_frmsizes->height;
- }
-
- cam_info("width - %d , height - %d\n",
- fsize->discrete.width, fsize->discrete.height);
-
- return 0;
-}
-
-static int s5k4ecgx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
-{
- int err = 0;
-
- cam_dbg("E\n");
-
- return err;
-}
-
-static int s5k4ecgx_set_fmt_size(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
- cam_info("s5k4ecgx_set_fmt_size E\n");
-
- if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) {
- switch (state->capture_frmsizes->index) {
- case S5K4ECGX_CAPTURE_5MP:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_5M_Capture_EVT1,\
- sizeof(s5k4ecgx_5M_Capture_EVT1) /
- sizeof(s5k4ecgx_5M_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_5MP\n");
- break;
- case S5K4ECGX_CAPTURE_3MP:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_3M_Capture_EVT1,
- sizeof(s5k4ecgx_3M_Capture_EVT1) /
- sizeof(s5k4ecgx_3M_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_3MP\n");
- break;
- case S5K4ECGX_CAPTURE_2MP:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_2M_Capture_EVT1,
- sizeof(s5k4ecgx_2M_Capture_EVT1) /
- sizeof(s5k4ecgx_2M_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_2MP\n");
- break;
- case S5K4ECGX_CAPTURE_1MP:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_1M_Capture_EVT1,
- sizeof(s5k4ecgx_1M_Capture_EVT1) /
- sizeof(s5k4ecgx_1M_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_1MP\n");
- break;
- case S5K4ECGX_CAPTURE_XGA:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_XGA_Capture_EVT1,
- sizeof(s5k4ecgx_XGA_Capture_EVT1) /
- sizeof(s5k4ecgx_XGA_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_XGA\n");
- break;
- case S5K4ECGX_CAPTURE_VGA:
- err = s5k4ecgx_write_regs(sd,
- s5k4ecgx_VGA_Capture_EVT1,
- sizeof(s5k4ecgx_VGA_Capture_EVT1) /
- sizeof(s5k4ecgx_VGA_Capture_EVT1[0]));
- cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_VGA\n");
- break;
- default:
- cam_err("ERR: Invalid capture size\n");
- break;
- }
- }
-
- if (unlikely(err < 0)) {
- cam_err("i2c_write for set framerate\n");
- return -EIO;
- }
-
- return err;
-}
-
-static int s5k4ecgx_s_fmt(struct v4l2_subdev *sd, \
- struct v4l2_mbus_framefmt *ffmt)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- u32 num_entries = 0;
- u32 i;
- u32 err = 0;
- u32 width, height = 0;
-
- cam_info("s5k4ecgx_s_fmt E\n");
- /*
- * Just copying the requested format as of now.
- * We need to check here what are the formats the camera support, and
- * set the most appropriate one according to the request from FIMC
- */
-
- width = state->req_fmt.width = ffmt->width;
- height = state->req_fmt.height = ffmt->height;
-
- if (ffmt->colorspace == V4L2_COLORSPACE_JPEG)
- state->req_fmt.priv = V4L2_PIX_FMT_MODE_CAPTURE;
- else
- state->req_fmt.priv = V4L2_PIX_FMT_MODE_PREVIEW;
-
- switch (state->req_fmt.priv) {
- case V4L2_PIX_FMT_MODE_PREVIEW:
- cam_info("V4L2_PIX_FMT_MODE_PREVIEW\n");
- num_entries = ARRAY_SIZE(preview_frmsizes);
- for (i = 0; i < num_entries; i++) {
- if (width == preview_frmsizes[i].width &&
- height == preview_frmsizes[i].height) {
- state->preview_frmsizes = &preview_frmsizes[i];
- break;
- }
- if (i == (num_entries - 1))
- state->preview_frmsizes = &preview_frmsizes[0];
- }
- break;
-
- case V4L2_PIX_FMT_MODE_CAPTURE:
- cam_info("V4L2_PIX_FMT_MODE_CAPTURE\n");
- num_entries = ARRAY_SIZE(capture_frmsizes);
- for (i = 0; i < num_entries; i++) {
- if (width == capture_frmsizes[i].width && \
- height == capture_frmsizes[i].height) {
- state->capture_frmsizes = &capture_frmsizes[i];
- break;
- }
- }
- break;
-
- default:
- cam_err
- ("ERR(EINVAL) : Invalid capture size width(%d), height(%d)\n",\
- ffmt->width, ffmt->height);
- return -EINVAL;
- }
-
- /*set frame size of preview or capture*/
- err = s5k4ecgx_set_fmt_size(sd);
-
- return err;
-}
-
-static int s5k4ecgx_set_frame_rate(struct v4l2_subdev *sd, u32 fps)
-{
- int err = 0;
-
- cam_info("frame rate %d\n\n", fps);
-
- switch (fps) {
- case 7:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_7_EVT1,
- sizeof(s5k4ecgx_FPS_7_EVT1) / \
- sizeof(s5k4ecgx_FPS_7_EVT1[0]));
- break;
- case 15:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_15_EVT1,
- sizeof(s5k4ecgx_FPS_15_EVT1) / \
- sizeof(s5k4ecgx_FPS_15_EVT1[0]));
-
- break;
- case 20:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_20_EVT1,
- sizeof(s5k4ecgx_FPS_20_EVT1) / \
- sizeof(s5k4ecgx_FPS_20_EVT1[0]));
-
- break;
- case 24:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_24_EVT1,
- sizeof(s5k4ecgx_FPS_24_EVT1) / \
- sizeof(s5k4ecgx_FPS_24_EVT1[0]));
- break;
- case 30:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_30_EVT1,
- sizeof(s5k4ecgx_FPS_30_EVT1) / \
- sizeof(s5k4ecgx_FPS_30_EVT1[0]));
- break;
- default:
- cam_err("ERR: Invalid framerate\n");
- break;
- }
-
- if (unlikely(err < 0)) {
- cam_err("i2c_write for set framerate\n");
- return -EIO;
- }
-
- return err;
-}
-
-static int s5k4ecgx_g_parm(struct v4l2_subdev *sd,\
- struct v4l2_streamparm *parms)
-{
- int err = 0;
-
- cam_dbg("E\n");
-
- return err;
-}
-
-static int s5k4ecgx_s_parm(struct v4l2_subdev *sd, \
- struct v4l2_streamparm *parms)
-{
- int err = 0;
- u32 fps = 0;
- u32 denom = parms->parm.capture.timeperframe.denominator;
- u32 numer = parms->parm.capture.timeperframe.numerator;
- struct s5k4ecgx_state *state = to_state(sd);
-
- cam_dbg("E\n");
-
- if (denom >= 1 && numer == 1)
- fps = denom / numer;
- else if (denom == 1 && numer == 0)
- fps = 0;
-
- if (fps != state->set_fps) {
- if (fps < 0 && fps > 30) {
- cam_err("invalid frame rate %d\n", fps);
- fps = 30;
- }
- state->req_fps = fps;
-
- if (state->initialized) {
- err = s5k4ecgx_set_frame_rate(sd, state->req_fps);
- if (err >= 0)
- state->set_fps = state->req_fps;
- }
-
- }
-
- return err;
-}
-
-static int s5k4ecgx_control_stream(struct v4l2_subdev *sd, int cmd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- switch (cmd) {
- case STREAM_START:
- cam_warn("WARN: do nothing\n");
- break;
-
- case STREAM_STOP:
- cam_dbg("stream stop!!!\n");
- if (state->runmode == RUNMODE_CAPTURING)
- state->runmode = RUNMODE_CAPTURE_STOP;
-
- break;
-
- default:
- cam_err("ERR: Invalid cmd\n");
- break;
- }
-
- if (unlikely(err))
- cam_err("failed to stream start(stop)\n");
-
- return err;
-}
-
-static int s5k4ecgx_init(struct v4l2_subdev *sd, u32 val)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -EINVAL;
-
- cam_dbg("E\n");
-
- /* set initial regster value */
- if (state->sensor_mode == SENSOR_CAMERA) {
- cam_info("load camera common setting\n");
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1,
- sizeof(s5k4ecgx_init_reg1_EVT1) / \
- sizeof(s5k4ecgx_init_reg1_EVT1[0]));
-
- msleep(20);
-
- err |= s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1,
- sizeof(s5k4ecgx_init_reg2_EVT1) / \
- sizeof(s5k4ecgx_init_reg2_EVT1[0]));
- } else {
- cam_info("load recording setting\n");
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1,
- sizeof(s5k4ecgx_init_reg1_EVT1) / \
- sizeof(s5k4ecgx_init_reg1_EVT1[0]));
-
- msleep(20);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1,
- sizeof(s5k4ecgx_init_reg2_EVT1) / \
- sizeof(s5k4ecgx_init_reg2_EVT1[0]));
- }
-
- if (unlikely(err)) {
- cam_err("failed to init\n");
- return err;
- }
-
- state->runmode = RUNMODE_INIT;
-
- /* We stop stream-output from sensor when starting camera. */
- err = s5k4ecgx_control_stream(sd, STREAM_STOP);
- if (unlikely(err < 0))
- return err;
- msleep(150);
-
- state->initialized = 1;
-
- return 0;
-}
-
-static int s5k4ecgx_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- cam_info("stream mode = %d\n", enable);
-
- switch (enable) {
- case STREAM_MODE_CAM_OFF:
- if (state->sensor_mode == SENSOR_CAMERA) {
- if (state->check_dataline)
- err = s5k4ecgx_check_dataline(sd, 0);
- else
- err = s5k4ecgx_control_stream(sd, STREAM_STOP);
- }
- break;
-
- case STREAM_MODE_CAM_ON:
- /* The position of this code need to be adjusted later */
- if ((state->sensor_mode == SENSOR_CAMERA)
- && (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE))
- err = s5k4ecgx_set_capture_start(sd);
- else
- err = s5k4ecgx_set_preview_start(sd);
- break;
-
- case STREAM_MODE_MOVIE_ON:
- cam_dbg("do nothing(movie on)!!\n");
- break;
-
- case STREAM_MODE_MOVIE_OFF:
- cam_dbg("do nothing(movie off)!!\n");
- break;
-
- default:
- cam_err("ERR: Invalid stream mode\n");
- break;
- }
-
- if (unlikely(err < 0)) {
- cam_err("ERR: faild\n");
- return err;
- }
-
- return 0;
-}
-
-static int s5k4ecgx_get_af_1stsearch(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int af_status = -1;
- int err = 0;
- int ret = 0;
- cam_info("- Start\n");
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2EEE);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status);
- CHECK_ERR(err);
-
- switch (af_status & 0xff) {
- case AF_PROGRESS_1ST:
- ret = CAMERA_AF_STATUS_IN_PROGRESS;
- break;
-
- case AF_SUCCESS_1ST:
- ret = CAMERA_AF_STATUS_SUCCESS;
- break;
-
- case AF_FAIL_1ST:
- default:
- ret = CAMERA_AF_STATUS_FAIL;
- break;
- }
-
- ctrl->value = ret;
- cam_info("- END%d\n", ret);
- return ret;
-}
-
-static int s5k4ecgx_get_af_2ndsearch(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int af_status = -1;
- int err = 0;
- int ret = 0;
- cam_info(" E\n");
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2207);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status);
- CHECK_ERR(err);
-
- switch (af_status & 0xff) {
- case AF_SUCCESS_2ND:
- ret = CAMERA_AF_STATUS_SUCCESS;
- break;
-
- case AF_PROGRESS_2ND:
- default:
- ret = CAMERA_AF_STATUS_IN_PROGRESS;
- break;
- }
-
- ctrl->value = ret;
- cam_info(" - END%d\n", ret);
- return ret;
-}
-
-static int s5k4ecgx_get_af_result(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int status = 0;
- cam_info(" - START\n");
- if (state->focus.first == true) {
- state->focus.first = false;
- s5k4ecgx_cam_delay(sd);
- }
-
- /* 1st search af */
- s5k4ecgx_cam_delay(sd);
-
- status = s5k4ecgx_get_af_1stsearch(sd, ctrl);
-
- if (status != CAMERA_AF_STATUS_SUCCESS) {
- state->focus.status = status;
- if (status == CAMERA_AF_STATUS_FAIL)
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- return status;
- }
-
- /* 2nd search af */
- s5k4ecgx_cam_delay(sd);
-
- status = s5k4ecgx_get_af_2ndsearch(sd, ctrl);
-
- state->focus.status = status;
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
-
- cam_info("af_status = %d\n", status);
- cam_info(" - END\n");
- return 0;
-}
-
-
-static int s5k4ecgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- /* V4L2_CID_PRIVATE_BASE==0x08000000 */
- /* V4L2_CID_CAMERA_CLASS_BASE==0x009a0900 */
- /* V4L2_CID_BASE==0x00980900 */
-
- if (ctrl->id > V4L2_CID_PRIVATE_BASE)
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n",\
- ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
- else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE)
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\
- ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value);
- else
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \
- ctrl->id - V4L2_CID_BASE, ctrl->value);
-
- mutex_lock(&state->ctrl_lock);
-
- switch (ctrl->id) {
- case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT:
- ctrl->value = state->focus.status;
- break;
-
- case V4L2_CID_CAM_JPEG_MEMSIZE:
- ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE;
- break;
-
- case V4L2_CID_CAM_JPEG_MAIN_SIZE:
- ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE;
- break;
-
- case V4L2_CID_CAM_JPEG_MAIN_OFFSET:
- ctrl->value = 0;
- break;
-
- case V4L2_CID_CAM_JPEG_THUMB_SIZE:
- ctrl->value = 0;
- break;
-
- case V4L2_CID_CAM_JPEG_THUMB_OFFSET:
- ctrl->value = 0;
- break;
-
- case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET:
- ctrl->value = 0;
- break;
-
- case V4L2_CID_CAMERA_EXIF_FLASH:
- ctrl->value = state->exif.flash;
- break;
-
- case V4L2_CID_CAMERA_ISO:
- ctrl->value = state->exif.iso;
- break;
-
- case V4L2_CID_CAMERA_EXIF_ISO:
- ctrl->value = state->exif.iso;
- break;
-
- case V4L2_CID_CAMERA_EXIF_TV:
- ctrl->value = state->exif.tv;
- break;
-
- case V4L2_CID_CAMERA_EXIF_BV:
- ctrl->value = state->exif.bv;
- break;
-
- case V4L2_CID_CAMERA_EXIF_EBV:
- ctrl->value = state->exif.ebv;
- break;
-
- case V4L2_CID_WHITE_BALANCE_PRESET:
- ctrl->value = state->wb_mode;
- break;
-
- default:
- cam_err("no such control id %d\n",
- ctrl->id - V4L2_CID_PRIVATE_BASE);
- break;
- }
-
- mutex_unlock(&state->ctrl_lock);
-
- return err;
-}
-
-static int s5k4ecgx_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- int err;
- struct s5k4ecgx_state *state = to_state(sd);
- cam_dbg("E, value %d\n", ctrl->value);
-
-retry:
- switch (ctrl->value) {
- case ISO_AUTO:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_Auto_EVT1, \
- sizeof(s5k4ecgx_ISO_Auto_EVT1) / \
- sizeof(s5k4ecgx_ISO_Auto_EVT1[0]));
- break;
-
- case ISO_50:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_50_EVT1, \
- sizeof(s5k4ecgx_ISO_50_EVT1) / \
- sizeof(s5k4ecgx_ISO_50_EVT1[0]));
- break;
-
- case ISO_100:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_100_EVT1, \
- sizeof(s5k4ecgx_ISO_100_EVT1) / \
- sizeof(s5k4ecgx_ISO_100_EVT1[0]));
- break;
-
- case ISO_200:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_200_EVT1, \
- sizeof(s5k4ecgx_ISO_200_EVT1) / \
- sizeof(s5k4ecgx_ISO_200_EVT1[0]));
- break;
-
- case ISO_400:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_400_EVT1, \
- sizeof(s5k4ecgx_ISO_400_EVT1) / \
- sizeof(s5k4ecgx_ISO_400_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", ctrl->value);
- ctrl->value = ISO_AUTO;
- goto retry;
- }
-
- state->exif.iso = ctrl->value;
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_metering(struct v4l2_subdev *sd, int val)
-{
- int err;
- cam_dbg("E, value %d\n", val);
-
-retry:
- switch (val) {
- case METERING_CENTER:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Center_EVT1, \
- sizeof(s5k4ecgx_Metering_Center_EVT1) / \
- sizeof(s5k4ecgx_Metering_Center_EVT1[0]));
- break;
-
- case METERING_SPOT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Spot_EVT1, \
- sizeof(s5k4ecgx_Metering_Spot_EVT1) / \
- sizeof(s5k4ecgx_Metering_Spot_EVT1[0]));
- break;
-
- case METERING_MATRIX:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Matrix_EVT1, \
- sizeof(s5k4ecgx_Metering_Matrix_EVT1) / \
- sizeof(s5k4ecgx_Metering_Matrix_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = METERING_CENTER;
- goto retry;
- }
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_exposure(struct v4l2_subdev *sd, \
- struct v4l2_control *ctrl)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -EINVAL;
-
- cam_dbg("E\n");
-
- if (state->check_dataline)
- return 0;
-
- switch (ctrl->value) {
- case 0:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_4_EVT1, \
- sizeof(s5k4ecgx_EV_Minus_4_EVT1) / \
- sizeof(s5k4ecgx_EV_Minus_4_EVT1[0]));
- break;
- case 1:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_3_EVT1, \
- sizeof(s5k4ecgx_EV_Minus_3_EVT1) / \
- sizeof(s5k4ecgx_EV_Minus_3_EVT1[0]));
-
- break;
- case 2:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_2_EVT1, \
- sizeof(s5k4ecgx_EV_Minus_2_EVT1) / \
- sizeof(s5k4ecgx_EV_Minus_2_EVT1[0]));
- break;
- case 3:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_1_EVT1, \
- sizeof(s5k4ecgx_EV_Minus_1_EVT1) / \
- sizeof(s5k4ecgx_EV_Minus_1_EVT1[0]));
- break;
- case 4:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Default_EVT1, \
- sizeof(s5k4ecgx_EV_Default_EVT1) / \
- sizeof(s5k4ecgx_EV_Default_EVT1[0]));
- break;
- case 5:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_1_EVT1, \
- sizeof(s5k4ecgx_EV_Plus_1_EVT1) / \
- sizeof(s5k4ecgx_EV_Plus_1_EVT1[0]));
- break;
- case 6:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_2_EVT1, \
- sizeof(s5k4ecgx_EV_Plus_2_EVT1) / \
- sizeof(s5k4ecgx_EV_Plus_2_EVT1[0]));
- break;
- case 7:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_3_EVT1, \
- sizeof(s5k4ecgx_EV_Plus_3_EVT1) / \
- sizeof(s5k4ecgx_EV_Plus_3_EVT1[0]));
- break;
- case 8:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_4_EVT1, \
- sizeof(s5k4ecgx_EV_Plus_4_EVT1) / \
- sizeof(s5k4ecgx_EV_Plus_4_EVT1[0]));
- break;
- default:
- cam_err("ERR: invalid brightness(%d)\n", ctrl->value);
- return err;
- break;
- }
-
- if (unlikely(err < 0)) {
- cam_err("ERR: i2c_write for set brightness\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int s5k4ecgx_set_whitebalance(struct v4l2_subdev *sd, int val)
-{
- int err;
- struct s5k4ecgx_state *state = to_state(sd);
- cam_dbg("E, value %d\n", val);
-
-retry:
- switch (val) {
- case WHITE_BALANCE_AUTO:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Auto_EVT1, \
- sizeof(s5k4ecgx_WB_Auto_EVT1) / \
- sizeof(s5k4ecgx_WB_Auto_EVT1[0]));
- break;
-
- case WHITE_BALANCE_SUNNY:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Sunny_EVT1, \
- sizeof(s5k4ecgx_WB_Sunny_EVT1) / \
- sizeof(s5k4ecgx_WB_Sunny_EVT1[0]));
- break;
-
- case WHITE_BALANCE_CLOUDY:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Cloudy_EVT1, \
- sizeof(s5k4ecgx_WB_Cloudy_EVT1) / \
- sizeof(s5k4ecgx_WB_Cloudy_EVT1[0]));
- break;
-
- case WHITE_BALANCE_TUNGSTEN:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Tungsten_EVT1, \
- sizeof(s5k4ecgx_WB_Tungsten_EVT1) / \
- sizeof(s5k4ecgx_WB_Tungsten_EVT1[0]));
- break;
-
- case WHITE_BALANCE_FLUORESCENT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Fluorescent_EVT1, \
- sizeof(s5k4ecgx_WB_Fluorescent_EVT1) / \
- sizeof(s5k4ecgx_WB_Fluorescent_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = WHITE_BALANCE_AUTO;
- goto retry;
- }
-
- state->wb_mode = val;
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_scene_mode(struct v4l2_subdev *sd, int val)
-{
- int err;
- cam_dbg("E, value %d\n", val);
-
-retry:
- switch (val) {
- case SCENE_MODE_NONE:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Default_EVT1, \
- sizeof(s5k4ecgx_Scene_Default_EVT1) / \
- sizeof(s5k4ecgx_Scene_Default_EVT1[0]));
- break;
-
- case SCENE_MODE_PORTRAIT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Portrait_EVT1, \
- sizeof(s5k4ecgx_Scene_Portrait_EVT1) / \
- sizeof(s5k4ecgx_Scene_Portrait_EVT1[0]));
- break;
-
- case SCENE_MODE_LANDSCAPE:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Landscape_EVT1, \
- sizeof(s5k4ecgx_Scene_Landscape_EVT1) / \
- sizeof(s5k4ecgx_Scene_Landscape_EVT1[0]));
- break;
-
- case SCENE_MODE_SPORTS:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sports_EVT1, \
- sizeof(s5k4ecgx_Scene_Sports_EVT1) / \
- sizeof(s5k4ecgx_Scene_Sports_EVT1[0]));
- break;
-
- case SCENE_MODE_PARTY_INDOOR:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Party_Indoor_EVT1,\
- sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1) / \
- sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1[0]));
- break;
-
- case SCENE_MODE_BEACH_SNOW:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Beach_Snow_EVT1, \
- sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1) / \
- sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1[0]));
- break;
-
- case SCENE_MODE_SUNSET:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sunset_EVT1, \
- sizeof(s5k4ecgx_Scene_Sunset_EVT1) / \
- sizeof(s5k4ecgx_Scene_Sunset_EVT1[0]));
- break;
-
- case SCENE_MODE_DUSK_DAWN:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Duskdawn_EVT1, \
- sizeof(s5k4ecgx_Scene_Duskdawn_EVT1) / \
- sizeof(s5k4ecgx_Scene_Duskdawn_EVT1[0]));
- break;
-
- case SCENE_MODE_FALL_COLOR:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fall_Color_EVT1, \
- sizeof(s5k4ecgx_Scene_Fall_Color_EVT1) / \
- sizeof(s5k4ecgx_Scene_Fall_Color_EVT1[0]));
- break;
-
- case SCENE_MODE_NIGHTSHOT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Nightshot_EVT1, \
- sizeof(s5k4ecgx_Scene_Nightshot_EVT1) / \
- sizeof(s5k4ecgx_Scene_Nightshot_EVT1[0]));
- break;
-
- case SCENE_MODE_BACK_LIGHT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Backlight_EVT1, \
- sizeof(s5k4ecgx_Scene_Backlight_EVT1) / \
- sizeof(s5k4ecgx_Scene_Backlight_EVT1[0]));
- break;
-
- case SCENE_MODE_FIREWORKS:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fireworks_EVT1, \
- sizeof(s5k4ecgx_Scene_Fireworks_EVT1) / \
- sizeof(s5k4ecgx_Scene_Fireworks_EVT1[0]));
- break;
-
- case SCENE_MODE_TEXT:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Text_EVT1, \
- sizeof(s5k4ecgx_Scene_Text_EVT1) / \
- sizeof(s5k4ecgx_Scene_Text_EVT1[0]));
- break;
-
- case SCENE_MODE_CANDLE_LIGHT:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_Scene_Candle_Light_EVT1, \
- sizeof(s5k4ecgx_Scene_Candle_Light_EVT1) / \
- sizeof(s5k4ecgx_Scene_Candle_Light_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = SCENE_MODE_NONE;
- goto retry;
- }
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_effect(struct v4l2_subdev *sd, int val)
-{
- int err;
- cam_dbg("E, value %d\n", val);
-
-retry:
- switch (val) {
- case IMAGE_EFFECT_NONE:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Normal_EVT1, \
- sizeof(s5k4ecgx_Effect_Normal_EVT1) / \
- sizeof(s5k4ecgx_Effect_Normal_EVT1[0]));
- break;
-
- case IMAGE_EFFECT_SEPIA:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Sepia_EVT1, \
- sizeof(s5k4ecgx_Effect_Sepia_EVT1) / \
- sizeof(s5k4ecgx_Effect_Sepia_EVT1[0]));
- break;
-
- case IMAGE_EFFECT_BNW:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_Effect_Black_White_EVT1, \
- sizeof(s5k4ecgx_Effect_Black_White_EVT1) / \
- sizeof(s5k4ecgx_Effect_Black_White_EVT1[0]));
- break;
-
- case IMAGE_EFFECT_NEGATIVE:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Negative_EVT1, \
- sizeof(s5k4ecgx_Effect_Negative_EVT1) / \
- sizeof(s5k4ecgx_Effect_Negative_EVT1[0]));
- break;
-
- case IMAGE_EFFECT_AQUA:
- err = s5k4ecgx_write_regs(sd, \
- s5k4ecgx_Effect_Solarization_EVT1, \
- sizeof(s5k4ecgx_Effect_Solarization_EVT1) / \
- sizeof(s5k4ecgx_Effect_Solarization_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = IMAGE_EFFECT_NONE;
- goto retry;
- }
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_wdr(struct v4l2_subdev *sd, int val)
-{
- int err;
- cam_dbg("E, value %d\n", val);
-
-retry:
- switch (val) {
- case WDR_OFF:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_off_EVT1, \
- sizeof(s5k4ecgx_WDR_off_EVT1) / \
- sizeof(s5k4ecgx_WDR_off_EVT1[0]));
- break;
-
- case WDR_ON:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_on_EVT1, \
- sizeof(s5k4ecgx_WDR_on_EVT1) / \
- sizeof(s5k4ecgx_WDR_on_EVT1[0]));
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = WDR_OFF;
- goto retry;
- }
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_set_jpeg_quality(struct v4l2_subdev *sd, int val)
-{
- int err = -1;
- cam_dbg("E, value %d\n", val);
-
- if (val <= 65) /* Normal */
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_Low_EVT1,\
- sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1) / \
- sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1[0]));
- else if (val <= 75) /* Fine */
- err = s5k4ecgx_write_regs
- (sd, s5k4ecgx_Jpeg_Quality_Normal_EVT1,\
- sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1) / \
- sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1[0]));
- else /* Superfine */
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_High_EVT1,\
- sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1) / \
- sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1[0]));
-
- CHECK_ERR(err);
-
- cam_dbg("X\n");
- return 0;
-}
-
-static int s5k4ecgx_return_focus(struct v4l2_subdev *sd)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -EINVAL;
-
- cam_info("E\n");
-
- switch (state->focus.mode) {
- case FOCUS_MODE_MACRO:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0]));
-
- break;
-
- default:
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0]));
-
- break;
- }
-
- CHECK_ERR(err);
- return 0;
-}
-
-/* PX: Stop AF */
-static int s5k4ecgx_stop_af(struct v4l2_subdev *sd, s32 touch)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- cam_info("E\n");
- mutex_lock(&state->af_lock);
-
- switch (state->focus.status) {
- case CAMERA_AF_STATUS_FAIL:
- case CAMERA_AF_STATUS_SUCCESS:
- cam_dbg("Stop AF, focus mode %d, AF result %d\n",
- state->focus.mode, state->focus.status);
-
- err = s5k4ecgx_set_ae_lock(sd, false);
- err = s5k4ecgx_set_awb_lock(sd, false);
- if (unlikely(err)) {
- cam_err("%s: ERROR, fail to set lock\n", __func__);
- goto err_out;
- }
- state->focus.status = CAMERA_AF_STATUS_MAX;
- state->preflash = PREFLASH_NONE;
- break;
-
- case CAMERA_AF_STATUS_MAX:
- break;
-
- default:
- cam_err("%s: WARNING, unnecessary calling. AF status=%d\n",
- __func__, state->focus.status);
- /* Return 0. */
- goto err_out;
- break;
- }
-
- if (!touch) {
- /* We move lens to default position if af is cancelled.*/
- err = s5k4ecgx_return_focus(sd);
- if (unlikely(err)) {
- cam_err("%s: ERROR, fail to af_norma_mode (%d)\n",
- __func__, err);
- goto err_out;
- }
- }
-
- mutex_unlock(&state->af_lock);
- cam_info("X\n");
- return 0;
-
-err_out:
- mutex_unlock(&state->af_lock);
- return err;
-}
-
-static int s5k4ecgx_set_af_mode(struct v4l2_subdev *sd, int val)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = -1;
- u32 af_cancel = 0;
- cam_info(" - value %d\n", val);
-
- mutex_lock(&state->af_lock);
-
-retry:
- af_cancel = (u32)val & FOCUS_MODE_DEFAULT;
- switch (val) {
- case FOCUS_MODE_AUTO:
- case FOCUS_MODE_INFINITY:
- state->focus.mode = val;
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\
- sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \
- sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0]));
-
- break;
-
- case FOCUS_MODE_MACRO:
- state->focus.mode = val;
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0]));
-
- s5k4ecgx_cam_delay(sd);
-
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\
- sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \
- sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0]));
-
- break;
-
- default:
- cam_warn("invalid value, %d\n", val);
- val = FOCUS_MODE_AUTO;
- goto retry;
- }
-
- state->focus.mode = val;
- mutex_unlock(&state->af_lock);
-
- if (af_cancel)
- s5k4ecgx_stop_af(sd, 0);
-
- return 0;
-
- CHECK_ERR(err);
- return 0;
-}
-
-/* PX: Do AF */
-static int s5k4ecgx_do_af(struct v4l2_subdev *sd)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct s5k4ecgx_state *state = to_state(sd);
- u16 read_value = 0;
- u32 count = 0;
- int err = 0;
-
- cam_info("E\n");
-
- /* AE, AWB Lock */
- err = s5k4ecgx_set_ae_lock(sd, true);
- CHECK_ERR(err);
- err = s5k4ecgx_set_awb_lock(sd, true);
- CHECK_ERR(err);
-
- /* AF start */
- err = s5k4ecgx_write_regs(sd, s5k4ecgx_Single_AF_Start_EVT1,\
- sizeof(s5k4ecgx_Single_AF_Start_EVT1) / \
- sizeof(s5k4ecgx_Single_AF_Start_EVT1[0]));
- CHECK_ERR(err);
-
- /* 1 frame delay */
- s5k4ecgx_cam_delay(sd);
-
- /* AF Searching */
- cam_dbg("AF 1st search\n");
-
- /*1st search*/
- for (count = 0; count < FIRST_AF_SEARCH_COUNT; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_dbg("do_af: AF is cancelled while doing(1st)\n");
- state->focus.status = CAMERA_AF_STATUS_MAX;
- goto check_done;
- }
-
- /* 1 frame delay */
- s5k4ecgx_cam_delay(sd);
-
- read_value = 0x0;
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2EEE);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, &read_value);
- CHECK_ERR(err);
- cam_info("1st AF status(%02d) = 0x%04X\n",
- count, read_value);
-
- if ((read_value & 0xff) != AF_PROGRESS_1ST)
- break;
- }
-
- if ((read_value & 0xff) != AF_SUCCESS_1ST) {
- cam_err("%s: ERROR, 1st AF failed. count=%d, read_val=0x%X\n\n",
- __func__, count, read_value);
- state->focus.status = CAMERA_AF_STATUS_FAIL;
- goto check_done;
- }
-
- /*2nd search*/
- cam_dbg("AF 2nd search\n");
- for (count = 0; count < SECOND_AF_SEARCH_COUNT; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_dbg("do_af: AF is cancelled while doing(2nd)\n");
- state->focus.status = CAMERA_AF_STATUS_MAX;
- goto check_done;
- }
-
- read_value = 0x0;
- err = s5k4ecgx_write(client, 0x002C7000);
- CHECK_ERR(err);
- err = s5k4ecgx_write(client, 0x002E2207);
- CHECK_ERR(err);
- err = s5k4ecgx_read(client, 0x0F12, &read_value);
- CHECK_ERR(err);
- cam_info("2nd AF status(%02d) = 0x%04X\n",
- count, read_value);
- if ((read_value & 0xff) == AF_SUCCESS_2ND)
- break;
- }
-
- if (count >= SECOND_AF_SEARCH_COUNT) {
- /* 0x01XX means "Not Finish". */
- cam_err("%s: ERROR, 2nd AF failed. read_val=0x%X\n\n",
- __func__, read_value & 0xff);
- state->focus.status = CAMERA_AF_STATUS_FAIL;
- goto check_done;
- }
-
- cam_info("AF Success!\n");
- state->focus.status = CAMERA_AF_STATUS_SUCCESS;
-
-check_done:
- /* restore write mode */
-
- /* We only unlocked AE,AWB in case of being cancelled.
- * But we now unlock it unconditionally if AF is started,
- */
- if (state->focus.status == CAMERA_AF_STATUS_MAX) {
- cam_dbg("%s: Single AF cancelled.\n", __func__);
- /* AE, AWB Lock */
- err = s5k4ecgx_set_ae_lock(sd, false);
- CHECK_ERR(err);
- err = s5k4ecgx_set_awb_lock(sd, false);
- CHECK_ERR(err);
- } else {
- state->focus.start = AUTO_FOCUS_OFF;
- cam_dbg("%s: Single AF finished\n", __func__);
- }
-
- if ((state->preflash == PREFLASH_ON) &&
- (state->sensor_mode == SENSOR_CAMERA)) {
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- if (state->focus.status == CAMERA_AF_STATUS_MAX)
- state->preflash = PREFLASH_NONE;
- }
-
- /* Notice: we here turn touch flag off set previously
- * when doing Touch AF. */
-
- return 0;
-}
-
-static void s5k4ecgx_af_worker(struct work_struct *work)
-{
- struct s5k4ecgx_state *state = container_of(work, \
- struct s5k4ecgx_state, af_work);
- struct v4l2_subdev *sd = &state->sd;
- int err = -EINVAL;
-
- cam_info("E\n");
-
- mutex_lock(&state->af_lock);
-
- /* 1. Check Low Light */
- err = s5k4ecgx_get_lux(sd);
-
- /* 2. Turn on Pre Flash */
- switch (state->flash_mode) {
- case FLASH_MODE_AUTO:
- if (!state->lowlight) {
- /* flash not needed */
- break;
- }
-
- case FLASH_MODE_ON:
- state->pdata->flash_ctrl(CAM_FLASH_TORCH);
- state->preflash = PREFLASH_ON;
- break;
-
- case FLASH_MODE_OFF:
- default:
- break;
- }
-
- if (state->preflash == PREFLASH_ON) {
- /* 3. Waiting until AE Stable */
- err = s5k4ecgx_ae_stable(sd);
- } else if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_info("af_start_preflash: AF is cancelled!\n");
- state->focus.status = CAMERA_AF_STATUS_MAX;
- }
-
- if (state->focus.status == CAMERA_AF_STATUS_MAX) {
- if (state->preflash == PREFLASH_ON) {
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- }
- goto out;
- }
-
- s5k4ecgx_do_af(sd);
-
-out:
- mutex_unlock(&state->af_lock);
- cam_info("X\n");
- return;
-}
-
-static int s5k4ecgx_set_af(struct v4l2_subdev *sd, s32 val)
-{
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- cam_info("%s: %s, focus mode %d\n", __func__,
- val ? "start" : "stop", state->focus.mode);
-
- if (unlikely((u32)val >= AUTO_FOCUS_MAX)) {
- cam_err("%s: ERROR, invalid value(%d)\n", __func__, val);
- return -EINVAL;
- }
-
-/* need to check the AF scenario with SLP team - temp code */
-/*
- if (state->focus.start == val)
- return 0;
-*/
- state->focus.start = val;
-
- if (val == AUTO_FOCUS_ON) {
- err = queue_work(state->workqueue, &state->af_work);
- if (likely(err))
- state->focus.status = CAMERA_AF_STATUS_IN_PROGRESS;
- else
- cam_warn("WARNING, AF is still processing. So new AF cannot start\n");
- } else {
- /* Cancel AF */
- /* 1. AE/AWB UnLock */
- err = s5k4ecgx_set_ae_lock(sd, false);
- CHECK_ERR(err);
- err = s5k4ecgx_set_awb_lock(sd, false);
- CHECK_ERR(err);
- /* 2. Turn off on pre flash */
- state->pdata->flash_ctrl(CAM_FLASH_OFF);
- state->preflash = PREFLASH_OFF;
- /* 3. Cancel AF mode */
- err = s5k4ecgx_set_af_mode(sd, state->focus.mode);
- cam_info("set_af: AF cancel requested!\n");
- }
-
- cam_info("X\n");
- return 0;
-}
-
-static int s5k4ecgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
- struct s5k4ecgx_state *state = to_state(sd);
- int err = 0;
-
- /* V4L2_CID_PRIVATE_BASE == 0x08000000 */
- /* V4L2_CID_CAMERA_CLASS_BASE == 0x009a0900 */
- /* V4L2_CID_BASE == 0x00980900 */
-
- if (ctrl->id > V4L2_CID_PRIVATE_BASE)
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n", \
- ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
- else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE)
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\
- ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value);
- else
- cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \
- ctrl->id - V4L2_CID_BASE, ctrl->value);
-
- if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE)
- && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE)
- && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE))
- && (!state->initialized)) {
- cam_warn("camera isn't initialized\n");
- return 0;
- }
-
- if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS)
- mutex_lock(&state->ctrl_lock);
-
- switch (ctrl->id) {
- case V4L2_CID_CAM_JPEG_QUALITY:
- err = s5k4ecgx_set_jpeg_quality(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_ISO:
- err = s5k4ecgx_set_iso(sd, ctrl);
- break;
-
- case V4L2_CID_CAMERA_METERING:
- if (state->sensor_mode == SENSOR_CAMERA)
- err = s5k4ecgx_set_metering(sd, ctrl->value);
- break;
-
- case V4L2_CID_EXPOSURE:
- err = s5k4ecgx_set_exposure(sd, ctrl);
- cam_dbg("V4L2_CID_EXPOSURE [%d]\n", ctrl->value);
- break;
-
- case V4L2_CID_WHITE_BALANCE_PRESET:
- case V4L2_CID_CAMERA_WHITE_BALANCE:
- err = s5k4ecgx_set_whitebalance(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_SCENE_MODE:
- state->scene_mode = ctrl->value;
- err = s5k4ecgx_set_scene_mode(sd, ctrl->value);
- break;
-
- case V4L2_CID_COLORFX:
- err = s5k4ecgx_set_effect(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_WDR:
- err = s5k4ecgx_set_wdr(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_FLASH_MODE:
- state->flash_mode = ctrl->value;
- break;
-
- case V4L2_CID_FOCUS_AUTO_MODE:
- case V4L2_CID_CAMERA_FOCUS_MODE:
- err = s5k4ecgx_set_af_mode(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_SET_AUTO_FOCUS:
- err = s5k4ecgx_set_af(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_CHECK_DATALINE:
- state->check_dataline = ctrl->value;
- cam_dbg("check_dataline = %d\n", state->check_dataline);
- err = 0;
- break;
-
- case V4L2_CID_CAMERA_SENSOR_MODE:
- err = s5k4ecgx_set_sensor_mode(sd, ctrl);
- cam_dbg("sensor_mode = %d\n", ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
- cam_dbg("do nothing\n");
- break;
-
- case V4L2_CID_CAMERA_CHECK_ESD:
- err = s5k4ecgx_check_esd(sd);
- break;
-
- case V4L2_CID_CAMERA_FRAME_RATE:
- err = s5k4ecgx_set_frame_rate(sd, ctrl->value);
- break;
-
- case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS:
- s5k4ecgx_debug_sensor_status(sd);
- err = s5k4ecgx_check_sensor_status(sd);
- break;
-
- default:
- cam_err("ERR(ENOIOCTLCMD)\n");
- /* no errors return.*/
- break;
- }
-
- if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS)
- mutex_unlock(&state->ctrl_lock);
-
- cam_dbg("X\n");
- return err;
-}
-
-static const struct v4l2_subdev_core_ops s5k4ecgx_core_ops = {
- .init = s5k4ecgx_init, /* initializing API */
- .g_ctrl = s5k4ecgx_g_ctrl,
- .s_ctrl = s5k4ecgx_s_ctrl,
-};
-
-static const struct v4l2_subdev_video_ops s5k4ecgx_video_ops = {
- .s_mbus_fmt = s5k4ecgx_s_fmt,
- .s_stream = s5k4ecgx_s_stream,
- .enum_framesizes = s5k4ecgx_enum_framesizes,
- .g_parm = s5k4ecgx_g_parm,
- .s_parm = s5k4ecgx_s_parm,
-};
-
-static const struct v4l2_subdev_ops s5k4ecgx_ops = {
- .core = &s5k4ecgx_core_ops,
- .video = &s5k4ecgx_video_ops,
-};
-
-/*
- * s5k4ecgx_probe
- * Fetching platform data is being done with s_config subdev call.
- * In probe routine, we just register subdev device
- */
-static int s5k4ecgx_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct s5k4ecgx_state *state = NULL;
- struct v4l2_subdev *sd = NULL;
- struct s5k4ecgx_platform_data *pdata = NULL;
- cam_dbg("E\n");
-
- state = kzalloc(sizeof(struct s5k4ecgx_state), GFP_KERNEL);
- if (state == NULL)
- return -ENOMEM;
-
- sd = &state->sd;
- strcpy(sd->name, S5K4ECGX_DRIVER_NAME);
-
- state->runmode = RUNMODE_NOTREADY;
- state->initialized = 0;
- state->req_fps = state->set_fps = 0;
- state->sensor_mode = SENSOR_CAMERA;
- state->zoom = 0;
- state->flash_mode = FLASH_MODE_BASE;
- state->lowlight = 0;
- state->awb_lock = 0;
- state->ae_lock = 0;
- state->preflash = PREFLASH_NONE;
-
- pdata = client->dev.platform_data;
-
- if (!pdata) {
- cam_err("no platform data\n");
- return -ENODEV;
- }
-
- /* Registering subdev */
- v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
-
- mutex_init(&state->ctrl_lock);
- mutex_init(&state->af_lock);
-
- state->workqueue = create_workqueue("cam_workqueue");
- if (unlikely(!state->workqueue)) {
- dev_err(&client->dev, "probe, fail to create workqueue\n");
- goto err_out;
- }
- INIT_WORK(&state->af_work, s5k4ecgx_af_worker);
-
- /*
- * Assign default format and resolution
- * Use configured default information in platform data
- * or without them, use default information in driver
- */
-
- /*S5K4ECGX_PREVIEW_VGA*/
- state->preview_frmsizes = &preview_frmsizes[0];
- /*S5K4ECGX_CAPTURE_5MP */
- state->capture_frmsizes = &capture_frmsizes[0];
- cam_dbg("preview_width: %d , preview_height: %d, "
- "capture_width: %d, capture_height: %d",
- state->preview_frmsizes->width, state->preview_frmsizes->height,
- state->capture_frmsizes->width, state->capture_frmsizes->height);
-
- state->req_fmt.width = state->preview_frmsizes->width;
- state->req_fmt.height = state->preview_frmsizes->height;
-
- state->pdata = pdata;
-
- if (!pdata->pixelformat)
- state->req_fmt.pixelformat = DEFAULT_FMT;
- else
- state->req_fmt.pixelformat = pdata->pixelformat;
-
- cam_dbg("probed!!\n");
-
- return 0;
-
-err_out:
- kfree(state);
- return -ENOMEM;
-}
-
-static int s5k4ecgx_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct s5k4ecgx_state *state = to_state(sd);
-
- cam_dbg("E\n");
-
- destroy_workqueue(state->workqueue);
-
- state->initialized = 0;
-
- v4l2_device_unregister_subdev(sd);
-
- mutex_destroy(&state->ctrl_lock);
- mutex_destroy(&state->af_lock);
-
- kfree(to_state(sd));
-
- return 0;
-}
-
-static const struct i2c_device_id s5k4ecgx_id[] = {
- { S5K4ECGX_DRIVER_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, s5k4ecgx_id);
-
-static struct i2c_driver s5k4ecgx_i2c_driver = {
- .driver = {
- .name = S5K4ECGX_DRIVER_NAME,
- },
- .probe = s5k4ecgx_probe,
- .remove = s5k4ecgx_remove,
- .id_table = s5k4ecgx_id,
-};
-
-static int __init s5k4ecgx_mod_init(void)
-{
- cam_dbg("E\n");
- return i2c_add_driver(&s5k4ecgx_i2c_driver);
-}
-
-static void __exit s5k4ecgx_mod_exit(void)
-{
- cam_dbg("E\n");
- i2c_del_driver(&s5k4ecgx_i2c_driver);
-}
-module_init(s5k4ecgx_mod_init);
-module_exit(s5k4ecgx_mod_exit);
-
-MODULE_DESCRIPTION("S5K4ECGX MIPI sensor driver");
-MODULE_AUTHOR("seungwoolee<samuell.lee@samsung.com>");
-MODULE_AUTHOR("jinsookim<js1002.kim@samsung.com>");
-MODULE_LICENSE("GPL");