From: ddl Date: Thu, 4 Aug 2011 04:29:21 +0000 (+0800) Subject: camera: camera driver and all sensor driver support X-Git-Tag: firefly_0821_release~9780 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=c8d33ee4ce18f1245edf3a22bd332d984b73c903;p=firefly-linux-kernel-4.4.55.git camera: camera driver and all sensor driver support --- diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index c99dd2019b0a..551ef42ecb03 100755 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -817,7 +817,11 @@ config SOC_CAMERA_MT9T111 depends on SOC_CAMERA && I2C help This driver supports MT9T111 cameras from Micron. - +config SOC_CAMERA_MT9P111 + tristate "mt9p111 support" + depends on SOC_CAMERA && I2C + help + This driver supports MT9P111 cameras from Micron. config SOC_CAMERA_MT9D112 tristate "mt9d112 support" depends on SOC_CAMERA && I2C @@ -952,10 +956,10 @@ config OV5640_FIXEDFOCUS endchoice config SOC_CAMERA_S5K6AA - tristate "Samsung S5K6AA MIPI CSI-2 (importek mu736asa)" + tristate "Samsung S5K6AA camera support" depends on SOC_CAMERA && I2C help - This is a samsung S5K6AA mobile camera driver + This is a samsung S5K6AA camera driver config SOC_CAMERA_GT2005 tristate "GT2005 support" diff --git a/drivers/media/video/gc0308.c b/drivers/media/video/gc0308.c index 21acf25f2e7f..5a8eb3c35153 100755 --- a/drivers/media/video/gc0308.c +++ b/drivers/media/video/gc0308.c @@ -54,7 +54,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -90,6 +90,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + struct reginfo { u8 reg; @@ -1191,16 +1196,27 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), - //JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1220,8 +1236,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; - + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -1400,7 +1416,7 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra } #endif - +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) { int ret; @@ -1427,6 +1443,7 @@ static int sensor_check_array(struct i2c_client *client, struct reginfo *regarra return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1478,6 +1495,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; int ret; SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1508,10 +1526,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1561,9 +1584,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1573,16 +1597,18 @@ static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; //u8 reg_val; - + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } static struct reginfo sensor_power_down_sequence[]= @@ -1645,73 +1671,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct v4l2_queryctrl *qctrl; + struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1721,16 +1755,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1773,12 +1807,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1794,7 +1828,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1806,6 +1840,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); } @@ -1814,39 +1871,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2578,9 +2636,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2650,6 +2705,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2661,9 +2725,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2706,7 +2771,9 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/gc0309.c b/drivers/media/video/gc0309.c index 8d5b12bf9686..a36cb41c4071 100755 --- a/drivers/media/video/gc0309.c +++ b/drivers/media/video/gc0309.c @@ -29,7 +29,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING fmt , ## arg); } while (0) #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) #define _CONS(a,b) a##b @@ -53,8 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -//#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YVYU +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -90,6 +89,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) struct reginfo { @@ -1126,16 +1129,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1155,8 +1170,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; - + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -1206,10 +1221,13 @@ static int sensor_task_lock(struct i2c_client *client, int lock) preempt_enable(); } } -#endif return 0; sensor_task_lock_err: - return -1; + return -1; +#else + return 0; +#endif + } #if 0 @@ -1315,8 +1333,10 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra { int err = 0, cnt; int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK int j = 0; char valchk; +#endif cnt = 0; if (sensor_task_lock(client, 1) < 0) @@ -1350,6 +1370,7 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { int cnt; @@ -1368,6 +1389,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar } return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1418,13 +1440,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret; - SENSOR_DG("\n-------------%s..%s.. %d,val = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__,val); + SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); if (sensor_ioctrl(icd, Sensor_PowerDown, 0) < 0) { - SENSOR_DG("\n-------------%s..%s.. %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); ret = -ENODEV; goto sensor_INIT_ERR; } @@ -1439,7 +1461,6 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) ret = -ENODEV; goto sensor_INIT_ERR; } -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); mdelay(5); //delay 5 microseconds /* check if it is an sensor sensor */ ret = sensor_read(client, 0x00, &value); @@ -1448,7 +1469,7 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION ret = -ENODEV; goto sensor_INIT_ERR; } - SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + if (value == SENSOR_ID) { sensor->model = SENSOR_V4L2_IDENT; } else { @@ -1456,7 +1477,7 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION ret = -ENODEV; goto sensor_INIT_ERR; } -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + ret = sensor_write_array(client, sensor_init_data); if (ret != 0) { @@ -1464,11 +1485,16 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; + /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); if (qctrl) @@ -1509,7 +1535,7 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION if (qctrl) sensor->info_priv.focus = qctrl->default_value; #endif -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + #if CONFIG_SENSOR_Flash qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FLASH); if (qctrl) @@ -1517,9 +1543,10 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1528,15 +1555,19 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - SENSOR_DG("\n----------------------------%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + u8 reg_val; + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } @@ -1600,81 +1631,82 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); - if (sensor->info_priv.pixfmt != pix->pixelformat) { - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); winseqe_set_addr = sensor_ClrFmt_UYVY; break; } @@ -1683,17 +1715,17 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - - set_w = pix->width; - set_h = pix->height; - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + + set_w = mf->width; + set_h = mf->height; + if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { winseqe_set_addr = sensor_qcif; @@ -1724,19 +1756,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } - SENSOR_TR("------------------------------%s, %s ,%d,\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_On); + SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); + } + } else { /* ddl@rock-chips.com : Video */ + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); + } + } + #endif ret |= sensor_write_array(client, winseqe_set_addr); if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); + #if CONFIG_SENSOR_Flash + if (sensor_fmt_capturechk(sd,mf) == true) { + if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { + sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); + } + } + #endif goto sensor_s_fmt_end; } sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); if (sensor->info_priv.whiteBalance != 0) { @@ -1744,7 +1797,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1765,39 +1818,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2028,29 +2082,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2059,7 +2113,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2492,8 +2546,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, int ret; struct sensor *sensor = to_sensor(client); - SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); - /* We must have a parent by now. And it cannot be a wrong one. * So this entire test is completely redundant. */ if (!icd->dev.parent || @@ -2504,7 +2556,7 @@ static int sensor_video_probe(struct soc_camera_device *icd, ret = -ENODEV; goto sensor_video_probe_err; } - SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + /* soft reset */ ret = sensor_write(client, 0xfe, 0x80); if (ret != 0) @@ -2513,7 +2565,7 @@ static int sensor_video_probe(struct soc_camera_device *icd, return -ENODEV; } mdelay(5); //delay 5 microseconds -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + /* check if it is an sensor sensor */ ret = sensor_read(client, 0x00, &value); if (ret != 0) { @@ -2521,7 +2573,7 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION ret = -ENODEV; goto sensor_video_probe_err; } -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + if (value == SENSOR_ID) { sensor->model = SENSOR_V4L2_IDENT; SENSOR_TR("chip id:0x%x\n",value); @@ -2530,10 +2582,7 @@ SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION ret = -ENODEV; goto sensor_video_probe_err; } - - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); -SENSOR_DG("--------------------%s , %s, %d\n",SENSOR_NAME_STRING(),__FUNCTION__,__LINE__); + return 0; sensor_video_probe_err: @@ -2602,6 +2651,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2613,9 +2671,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2658,7 +2717,9 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/gc2015.c b/drivers/media/video/gc2015.c index 0a47fc97e5e3..4ffe4974be07 100755 --- a/drivers/media/video/gc2015.c +++ b/drivers/media/video/gc2015.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 1024 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 768 #define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -89,6 +89,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) struct reginfo { @@ -998,16 +1002,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1027,8 +1043,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; - + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -1187,8 +1203,10 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra { int err = 0, cnt; int i = 0; +#if CONFIG_SENSOR_I2C_RDWRCHK int j = 0; char valchk; +#endif cnt = 0; if (sensor_task_lock(client, 1) < 0) @@ -1222,6 +1240,7 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { int cnt; @@ -1240,6 +1259,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar } return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1290,6 +1310,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1346,10 +1367,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1399,9 +1425,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1411,15 +1438,18 @@ static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_ioctrl(icd, Sensor_PowerDown, 1); + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } @@ -1483,76 +1513,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - SENSOR_TR("sensor_s_fmt\n"); - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1562,16 +1597,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1626,12 +1661,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1647,7 +1682,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1659,7 +1694,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); if (sensor->info_priv.whiteBalance != 0) { @@ -1667,7 +1702,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1688,39 +1723,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -1951,29 +1987,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -1982,7 +2018,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2462,9 +2498,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2533,6 +2566,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2540,13 +2582,14 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_ext_ctrls = sensor_g_ext_controls, .s_ext_ctrls = sensor_s_ext_controls, .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, + .ioctl = sensor_ioctl, }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2589,7 +2632,9 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/gt2005.c b/drivers/media/video/gt2005.c index b260ddea4f3e..b7e436615d1f 100755 --- a/drivers/media/video/gt2005.c +++ b/drivers/media/video/gt2005.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -89,6 +89,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + struct reginfo { u16 reg; @@ -1944,16 +1949,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1973,8 +1990,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; - + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -2151,7 +2168,7 @@ sensor_write_array_end: return err; } - +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_check_array(struct i2c_client *client, struct reginfo *regarray) { int ret; @@ -2181,6 +2198,7 @@ static int sensor_check_array(struct i2c_client *client, struct reginfo *regarra return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -2232,6 +2250,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -2288,10 +2307,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -2341,9 +2365,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -2353,17 +2378,22 @@ static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { sensor_write(client, 0x30b0, 0x00); sensor_write(client, 0x30b1, 0x00); + } sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } @@ -2431,76 +2461,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; -#if CONFIG_SENSOR_Flash + const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; -#endif struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -2510,16 +2545,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -2568,13 +2603,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - ret = -1; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -2590,7 +2624,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -2602,6 +2636,29 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + if (sensor->info_priv.whiteBalance != 0) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + } + sensor->info_priv.snap2preview = true; + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + sensor->info_priv.video2preview = true; + } else if ((sensor->info_priv.snap2preview == true) || (sensor->info_priv.video2preview == true)) { + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); + sensor_set_effect(icd, qctrl,sensor->info_priv.effect); + qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); + sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); + msleep(600); + sensor->info_priv.video2preview = false; + sensor->info_priv.snap2preview = false; + } SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); } @@ -2610,39 +2667,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2873,29 +2931,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2904,7 +2962,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2912,12 +2970,8 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 } #endif #if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { if (value == 3) { /* ddl@rock-chips.com: torch */ sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ @@ -3388,9 +3442,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -3439,7 +3490,7 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { for (i = 0; i < icd->ops->num_controls; i++) { if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - memset(&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + memset((char*)&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); } } sensor->info_priv.flash = 0xff; @@ -3459,6 +3510,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -3470,9 +3530,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -3515,16 +3576,19 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif ret = sensor_video_probe(icd, client); - if (ret) { + if (ret < 0) { icd->ops = NULL; i2c_set_clientdata(client, NULL); kfree(sensor); + sensor = NULL; } SENSOR_DG("\n%s..%s..%d ret = %x \n",__FUNCTION__,__FILE__,__LINE__,ret); return ret; diff --git a/drivers/media/video/hi253.c b/drivers/media/video/hi253.c index ee2f503b270f..31ae238802f9 100755 --- a/drivers/media/video/hi253.c +++ b/drivers/media/video/hi253.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 1600 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 1200 #define SENSOR_INIT_WINSEQADR sensor_uxga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -89,7 +89,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) #define END_REG 0xff struct reginfo @@ -1872,16 +1875,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1901,7 +1916,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; @@ -2075,6 +2091,7 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { int cnt; @@ -2093,6 +2110,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar } return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -2143,6 +2161,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret; @@ -2191,10 +2210,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -2245,8 +2268,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -2255,7 +2280,7 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ @@ -2265,6 +2290,7 @@ static int sensor_deactivate(struct i2c_client *client) icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; return 0; } @@ -2328,75 +2354,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -2406,16 +2438,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg != END_REG)) { @@ -2471,12 +2503,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -2504,7 +2536,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2516,7 +2548,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2546,39 +2578,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2795,7 +2828,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v } #endif #if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct sensor *sensor = to_sensor(client); @@ -2809,29 +2842,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { *value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2840,7 +2873,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -3309,11 +3342,7 @@ static int sensor_video_probe(struct soc_camera_device *icd, ret = -ENODEV; goto sensor_video_probe_err; } - - - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - + return 0; sensor_video_probe_err: @@ -3382,6 +3411,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -3392,10 +3430,12 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .ioctl = sensor_ioctl, }; + static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -3438,7 +3478,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/hi704.c b/drivers/media/video/hi704.c index 92dbb886e277..5cd8e844a2e7 100755 --- a/drivers/media/video/hi704.c +++ b/drivers/media/video/hi704.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -88,7 +88,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) - +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) //lxh end of reg flag #define END_REG 0xff @@ -1329,16 +1332,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1358,7 +1373,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; @@ -1409,10 +1425,12 @@ static int sensor_task_lock(struct i2c_client *client, int lock) preempt_enable(); } } -#endif return 0; sensor_task_lock_err: - return -1; + return -1; +#else + return 0; +#endif } #if 0 @@ -1551,6 +1569,7 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { int cnt; @@ -1569,6 +1588,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar } return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1619,6 +1639,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret; @@ -1667,10 +1688,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1720,9 +1745,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1731,7 +1757,7 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ @@ -1741,6 +1767,7 @@ static int sensor_deactivate(struct i2c_client *client) icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; return 0; } @@ -1804,75 +1831,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1882,16 +1915,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg != END_REG)) { @@ -1923,12 +1956,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1944,7 +1977,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1956,7 +1989,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1968,7 +2001,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1998,39 +2031,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2247,7 +2281,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v } #endif #if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct sensor *sensor = to_sensor(client); @@ -2261,29 +2295,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2292,7 +2326,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2763,10 +2797,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2835,6 +2865,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2846,9 +2885,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2891,7 +2931,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/mt9p111.c b/drivers/media/video/mt9p111.c index 794bce5a8dc7..6a38b91ed05d 100644 --- a/drivers/media/video/mt9p111.c +++ b/drivers/media/video/mt9p111.c @@ -33,7 +33,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING fmt , ## arg); } while (0) #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) @@ -60,7 +60,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define YUV420_BUFFER_MAX_SIZE 7558272 /* 2592*1944*1.5*/ #define CONFIG_SENSOR_WhiteBalance 1 @@ -1719,12 +1719,12 @@ static struct reginfo sensor_Effect_Normal[] = {0x8404,0x06, BYTE_LEN, 0 }, {SEQUENCE_END, 0x00, 0, 0} }; - +#if 0 static struct reginfo sensor_Effect_WandB[] = { {SEQUENCE_END, 0x00, 0, 0} }; - +#endif static struct reginfo sensor_Effect_Sepia[] = { {0x098e,0xdc38, WORD_LEN, 0}, @@ -1742,6 +1742,7 @@ static struct reginfo sensor_Effect_Negative[] = {0x8404,0x06, BYTE_LEN, 0 }, {SEQUENCE_END, 0x00, 0, 0} }; +#if 0 static struct reginfo sensor_Effect_Bluish[] = { {SEQUENCE_END, 0x00, 0, 0} @@ -1751,7 +1752,7 @@ static struct reginfo sensor_Effect_Green[] = { {SEQUENCE_END, 0x00, 0, 0} }; - +#endif static struct reginfo sensor_Effect_Solarize[] = { {0x098e,0xdc38, WORD_LEN, 0}, @@ -2156,16 +2157,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; enum sensor_work_state { @@ -2202,7 +2215,7 @@ typedef struct sensor_info_priv_s int preview_w; int preview_h; struct reginfo *winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int enable; unsigned int funmodule_state; } sensor_info_priv_t; @@ -2355,7 +2368,7 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo int i=0; int sum =0; struct reginfo *tmpval = NULL; - u8 buf[1600]; + u8 *buf; struct i2c_msg msg[1]; tmpval = reg_info; @@ -2363,7 +2376,13 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo return -EINVAL; memset((char*)&msg[0],0,sizeof(struct i2c_msg)); - memset(buf,0,1600*sizeof(u8)); + buf = kmalloc((count*2+10)*sizeof(u8),GFP_KERNEL); + if (buf == NULL) { + SENSOR_TR("%s %s fail,because kmalloc failed",SENSOR_NAME_STRING(),__FUNCTION__); + err = -1; + goto sensor_write_Multiple_data_end; + } + memset(buf,0,sizeof(buf)); switch (reg_info->reg) { @@ -2431,6 +2450,11 @@ static int sensor_write_Multiple_data(struct i2c_client *client, struct reginfo } } } +sensor_write_Multiple_data_end: + if (buf) { + kfree(buf); + buf = NULL; + } return err; } @@ -2442,7 +2466,7 @@ static int sensor_read(struct i2c_client *client, u16 reg, u16 *val) struct i2c_msg msg[2]; buf[0] = reg >> 8; - buf[1] = reg & 0xFF; + buf[1] = reg & 0xFF; msg[0].addr = client->addr; msg[0].flags = client->flags; @@ -2504,7 +2528,6 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra num++; j++; } - //SENSOR_TR("%s ..%s..num =%d,regarray[%d].reg=0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__,num,i,regarray[i].reg); err = sensor_write_Multiple_data(client, ®array[i], num) ; if (err < 0) { @@ -2527,8 +2550,6 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra i=i+num; } - // SENSOR_TR("%s ..%s..quit\n",SENSOR_NAME_STRING(),__FUNCTION__); - sensor_write_array_end: sensor_task_lock(client,0); return err; @@ -2538,15 +2559,12 @@ sensor_write_array_end: static int sensor_write_init_data(struct i2c_client *client, struct reginfo *regarray) { int err = 0, cnt; - int i = 0,j=0; - int num = 0; - u16 temp = 0; + int i = 0; + int num = 0; #if CONFIG_SENSOR_I2C_RDWRCHK char valchk; #endif - cnt = 0; - - int ti=0; + int ti=0; int table[167] = { /*written data numbers every time*/ 3,1,1,3,1,1,1,1,11,2,2,13,1,1,1,2,11,2,2,13, 1,2,1,1,2,1,1,1,1,1,8,1,1,1,1,1,1,714,1,1, @@ -2559,10 +2577,9 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg 4,6,1,1,1,1,1 }; + cnt = 0; if (sensor_task_lock(client, 1) < 0) goto sensor_write_array_end; - - // SENSOR_TR("%s ..%s..\n",SENSOR_NAME_STRING(),__FUNCTION__); while (regarray[i].reg != SEQUENCE_END) { @@ -2570,7 +2587,6 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg num = table[ti]; ti++; } - // SENSOR_TR("%s ..%s..num =%d,regarray[%d].reg=0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__,num,i,regarray[i].reg); err = sensor_write_Multiple_data(client, ®array[i], num) ; if (err < 0) { @@ -2592,8 +2608,6 @@ static int sensor_write_init_data(struct i2c_client *client, struct reginfo *reg } i=i+num; } - // SENSOR_TR("%s ..%s..quit\n",SENSOR_NAME_STRING(),__FUNCTION__); - sensor_write_array_end: sensor_task_lock(client,0); return err; @@ -2850,9 +2864,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); +#if (ADJUST_OPTIMIZE_TIME_FALG == 0) const struct v4l2_queryctrl *qctrl; +#endif + const struct sensor_datafmt *fmt; int ret,pid = 0; int index =0 ; +#if (SENSOR_RESET_REG != SEQUENCE_END) + struct reginfo reg_info; +#endif SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -2868,7 +2888,6 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; #if (SENSOR_RESET_REG != SEQUENCE_END) - struct reginfo reg_info; reg_info.reg = SENSOR_RESET_REG; reg_info.val = SENSOR_RESET_VAL; reg_info.reg_len = SENSOR_RESET_REG_LEN; @@ -2903,11 +2922,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } SENSOR_DG("\n sensor_init_data..%s.\n",SENSOR_NAME_STRING()); - - // ret = sensor_write_array(client, sensor_init_data); + ret =sensor_write_init_data(client, sensor_init_data); - if (ret != 0) - { + if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; } @@ -2917,7 +2934,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) sensor->info_priv.capture_w = SENSOR_MAX_WIDTH; sensor->info_priv.capture_h = SENSOR_MAX_HEIGHT; sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ #if ADJUST_OPTIMIZE_TIME_FALG @@ -3119,56 +3142,53 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - - SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h) @@ -3427,35 +3447,32 @@ static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *r /*modify image with resolution 2592*1944;solve bug that the first 32 pixel data*/ /*in the first line have misplace with the last 32 pixel data in the last line*/ -static int sensor_cb(struct videobuf_buffer *vb) +static int sensor_cb(void *arg) { void __iomem *vbpmem; - struct videobuf_buffer *buffer = vb; + struct videobuf_buffer *buffer; char *imagey_addr =NULL; char *imageuv_addr = NULL; char *tempaddr = NULL; int tempsize = 0; - + buffer = (struct videobuf_buffer*)arg; if(buffer->width!=SENSOR_MAX_WIDTH||buffer->height!=SENSOR_MAX_HEIGHT||buffer==NULL) return -EINVAL; if (buffer->bsize< YUV420_BUFFER_MAX_SIZE) //yuv420 format size return -EINVAL; + vbpmem = ioremap(buffer->boff,buffer->bsize); - if(vbpmem == NULL) - { + if(vbpmem == NULL) { SENSOR_DG("\n%s..%s..ioremap fail\n",__FUNCTION__,SENSOR_NAME_STRING()); return -ENXIO; - } + } imagey_addr = (char*)vbpmem; // y data to be dealed with imageuv_addr = imagey_addr+buffer->width*buffer->height; - // SENSOR_DG("\n%s..%s..imagey_addr = 0x%x; imageuv_addr = 0x%x\n",__FUNCTION__,SENSOR_NAME_STRING(),imagey_addr,imageuv_addr); -// SENSOR_DG("\n%s..%s..buffer->bsize=%d\n",__FUNCTION__,SENSOR_NAME_STRING(),buffer->bsize); - tempaddr = imageuv_addr - 32; memcpy(tempaddr,imagey_addr,32); @@ -3473,12 +3490,12 @@ static int sensor_cb(struct videobuf_buffer *vb) } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; struct reginfo *winseqe_set_addr=NULL; int ret = 0, set_w,set_h,cnt; u16 seq_state=0; @@ -3487,15 +3504,22 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -3505,16 +3529,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h); @@ -3545,8 +3569,8 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n%s..%s..Capture icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); } else { SENSOR_DG("\n%s..%s..Video icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h); - sensor->info_priv.preview_w = pix->width; - sensor->info_priv.preview_h = pix->height; + sensor->info_priv.preview_w = mf->width; + sensor->info_priv.preview_h = mf->height; } } @@ -3578,7 +3602,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING()); goto sensor_s_fmt_end; } - SENSOR_DG("mt9p111 Preview 2 Capture again\n",cnt,seq_state); + SENSOR_DG("mt9p111 Preview 2 Capture again\n"); } SENSOR_DG("mt9p111 Preview 2 Capture count = %d;seq_state = 0x%x\n",cnt,seq_state); } while((seq_state != 0x07) && (time < 4)); @@ -3616,7 +3640,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.capture_h = set_h; sensor->info_priv.snap2preview = true; } else if (sensor->info_priv.snap2preview == true) { - if (winseqe_set_addr || ((sensor->info_priv.preview_w == pix->width) && (sensor->info_priv.preview_h == pix->height))) { + if (winseqe_set_addr || ((sensor->info_priv.preview_w == mf->width) && (sensor->info_priv.preview_h == mf->height))) { ret |= sensor_write_array(client, sensor_Capture2Preview); if (ret != 0) { SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING()); @@ -3641,54 +3665,48 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("%s flash off in preivew!\n", SENSOR_NAME_STRING()); } #endif - sensor->info_priv.preview_w = pix->width; - sensor->info_priv.preview_h = pix->height; + sensor->info_priv.preview_w = mf->width; + sensor->info_priv.preview_h = mf->height; sensor->info_priv.snap2preview = false; } else { - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - int ret = 0; - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - if (sensor_fmt_catch(pix->width, pix->height, &pix->width, &pix->height) == NULL) { - pix->width = 0; - pix->height = 0; - } - + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + return ret; } - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { struct i2c_client *client = sd->priv; @@ -3913,7 +3931,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v } #endif #if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct sensor *sensor = to_sensor(client); @@ -3927,29 +3945,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -3958,7 +3976,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -3966,12 +3984,8 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 } #endif #if CONFIG_SENSOR_Flash -static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct sensor *sensor = to_sensor(client); - const struct v4l2_queryctrl *qctrl_info; - +static int sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) +{ if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { if (value == 3) { /* ddl@rock-chips.com: torch */ sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ @@ -4545,7 +4559,9 @@ static int sensor_video_probe(struct soc_camera_device *icd, { int ret,pid = 0; struct sensor *sensor = to_sensor(client); - +#if (SENSOR_RESET_REG != SEQUENCE_END) + struct reginfo reg_info; +#endif /* We must have a parent by now. And it cannot be a wrong one. * So this entire test is completely redundant. */ if (!icd->dev.parent || @@ -4558,8 +4574,7 @@ static int sensor_video_probe(struct soc_camera_device *icd, } /* soft reset */ -#if (SENSOR_RESET_REG != SEQUENCE_END) - struct reginfo reg_info; +#if (SENSOR_RESET_REG != SEQUENCE_END) reg_info.reg = SENSOR_RESET_REG; reg_info.val = SENSOR_RESET_VAL; reg_info.reg_len = SENSOR_RESET_REG_LEN; @@ -4595,9 +4610,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -4609,6 +4621,9 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); +#if CONFIG_SENSOR_Flash + int i; +#endif int ret = 0; rk29_camera_sensor_cb_s *icd_cb =NULL; @@ -4640,12 +4655,11 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) /* ddl@rock-chips.com : if gpio_flash havn't been set in board-xxx.c, sensor driver must notify is not support flash control for this project */ #if CONFIG_SENSOR_Flash - int i; if (sensor->sensor_gpio_res) { if (sensor->sensor_gpio_res->gpio_flash == INVALID_GPIO) { for (i = 0; i < icd->ops->num_controls; i++) { if (V4L2_CID_FLASH == icd->ops->controls[i].id) { - memset(&icd->ops->controls[i],0x00,sizeof(struct v4l2_queryctrl)); + memset((char*)(icd->ops->controls+i),0x00,sizeof(struct v4l2_queryctrl)); } } sensor->info_priv.flash = 0xff; @@ -4671,7 +4685,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -4681,14 +4703,13 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_chip_ident = sensor_g_chip_ident, .ioctl = sensor_ioctl, }; - static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, .s_stream = sensor_s_stream, }; - static struct v4l2_subdev_ops sensor_subdev_ops = { .core = &sensor_subdev_core_ops, .video = &sensor_subdev_video_ops, @@ -4729,7 +4750,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/nt99250.c b/drivers/media/video/nt99250.c index 7f33b67e3ebb..a5776931de84 100755 --- a/drivers/media/video/nt99250.c +++ b/drivers/media/video/nt99250.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 600 #define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -89,6 +89,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + struct reginfo { u16 reg; @@ -1155,16 +1160,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1184,7 +1201,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; @@ -1362,6 +1380,7 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } +#if CONFIG_SENSOR_I2C_RDWRCHK static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { int cnt; @@ -1380,6 +1399,7 @@ static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regar } return 0; } +#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1430,6 +1450,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1441,7 +1462,9 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } /* soft reset */ - sensor_task_lock(client,1); + if (sensor_task_lock(client,1)<0) + goto sensor_INIT_ERR; + ret = sensor_write(client, 0x3021, 0x61); if (ret != 0) { @@ -1487,10 +1510,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1540,9 +1568,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1551,17 +1580,18 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - //u8 reg_val; - + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } @@ -1629,70 +1659,64 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - const struct v4l2_queryctrl *qctrl; - struct soc_camera_device *icd = client->dev.platform_data; - struct reginfo *winseqe_set_addr=NULL; - char readval; + struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - -u16 AE_reg, AGC_reg; - u8 temp_reg12,temp_reg13; - u16 shutter,reg_1, reg; + u8 reg_1, reg; + u16 shutter; //turn on scaler for preivew sensor_read(client ,0x3201, ®_1); @@ -1702,6 +1726,8 @@ u16 AE_reg, AGC_reg; sensor_write(client, 0x32f1, (reg|0x10) ); #if 0 //preview_fastmode + u16 AE_reg, AGC_reg; + u8 temp_reg12,temp_reg13 // turn off AE for preview sensor_read(client ,0x3201, &AE_reg); sensor_write(client, 0x3201, (AE_reg|0x20) ); @@ -1713,15 +1739,22 @@ u16 AE_reg, AGC_reg; sensor_read(client, 0x3013, &temp_reg13); shutter = (temp_reg13 & 0x00FF) | (temp_reg12 << 8); #endif - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1731,16 +1764,16 @@ u16 AE_reg, AGC_reg; } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1789,12 +1822,12 @@ u16 AE_reg, AGC_reg; winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1810,7 +1843,7 @@ u16 AE_reg, AGC_reg; if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1873,43 +1906,44 @@ u16 AE_reg, AGC_reg; SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; /*not support 720p video*/ - if(pix->height == 720 && pix->width == 1280){ - pix->height = 480; - pix->width = 640; + if(mf->height == 720 && mf->width == 1280){ + mf->height = 480; + mf->width = 640; } - return 0; + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2140,29 +2174,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2171,7 +2205,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2617,11 +2651,11 @@ static int sensor_video_probe(struct soc_camera_device *icd, /* soft reset */ ret = sensor_write(client, 0x3021, 0x61); - if (ret != 0) - { + if (ret != 0) { SENSOR_TR("soft reset %s failed\n",SENSOR_NAME_STRING()); - return -ENODEV; - } + ret = -ENODEV; + goto sensor_video_probe_err; + } mdelay(5); //delay 5 microseconds /* check if it is an sensor sensor */ @@ -2651,9 +2685,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2722,6 +2753,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2733,9 +2773,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2778,7 +2819,9 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c index 90978af1a8f2..f8368ab308eb 100755 --- a/drivers/media/video/ov2640.c +++ b/drivers/media/video/ov2640.c @@ -29,7 +29,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING fmt , ## arg); } while (0) #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) #define _CONS(a,b) a##b @@ -54,7 +54,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV//V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 1 @@ -1284,16 +1284,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1313,7 +1325,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; } sensor_info_priv_t; @@ -1557,6 +1569,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1615,10 +1628,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1757,75 +1774,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1835,16 +1858,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1899,12 +1922,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1920,7 +1943,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1932,7 +1955,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1944,7 +1967,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1973,41 +1996,41 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { struct i2c_client *client = sd->priv; @@ -2747,9 +2770,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2762,7 +2782,7 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - int ret = 0,i; + int ret = 0; SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); switch (cmd) @@ -2817,6 +2837,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2828,9 +2857,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2873,7 +2903,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov2655.c b/drivers/media/video/ov2655.c index ec94d6760e68..b0b191e5893b 100755 --- a/drivers/media/video/ov2655.c +++ b/drivers/media/video/ov2655.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -1402,17 +1402,28 @@ static struct soc_camera_ops sensor_ops = .num_controls = ARRAY_SIZE(sensor_controls), .num_menus = ARRAY_SIZE(sensor_menus), }; +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1432,7 +1443,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int funmodule_state; } sensor_info_priv_t; @@ -1679,6 +1690,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1735,10 +1747,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1886,75 +1902,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1964,16 +1986,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -2028,12 +2050,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -2049,7 +2071,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -2061,7 +2083,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); if (sensor->info_priv.whiteBalance != 0) { @@ -2069,7 +2091,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -2091,41 +2113,41 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { struct i2c_client *client = sd->priv; @@ -2865,9 +2887,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, ret = -ENODEV; goto sensor_video_probe_err; } - - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); return 0; sensor_video_probe_err: @@ -2933,6 +2952,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2942,11 +2970,11 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_chip_ident = sensor_g_chip_ident, .ioctl = sensor_ioctl, }; - static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2989,7 +3017,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index 5a45a36de5f6..28a91011ecc4 100755 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 600 #define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -434,7 +434,7 @@ static struct reginfo sensor_720p[]= {0x5061, 0x7d }, {0x5062, 0x7d }, {0x5063, 0x69 }, - {0x0100, 0x01 }, + {0x0100, 0x01 }, {0x0000 ,0x00} }; @@ -1198,8 +1198,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); static int sensor_resume(struct soc_camera_device *icd); static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +#if CONFIG_SENSOR_Effect static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +#if CONFIG_SENSOR_WhiteBalance static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif static int sensor_deactivate(struct i2c_client *client); static struct soc_camera_ops sensor_ops = @@ -1214,16 +1218,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1243,7 +1259,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int funmodule_state; } sensor_info_priv_t; @@ -1491,6 +1507,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1548,10 +1565,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1698,75 +1720,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -1776,16 +1804,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1846,12 +1874,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1867,7 +1895,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1879,7 +1907,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); if (sensor->info_priv.whiteBalance != 0) { @@ -1887,7 +1915,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1910,39 +1938,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2173,29 +2202,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2204,7 +2233,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2684,9 +2713,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2699,7 +2725,10 @@ static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - int ret = 0,i; + int ret = 0; +#if CONFIG_SENSOR_Flash + int i; +#endif SENSOR_DG("\n%s..%s..cmd:%x \n",SENSOR_NAME_STRING(),__FUNCTION__,cmd); switch (cmd) @@ -2753,7 +2782,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2761,15 +2798,15 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .g_ext_ctrls = sensor_g_ext_controls, .s_ext_ctrls = sensor_s_ext_controls, .g_chip_ident = sensor_g_chip_ident, - .ioctl = sensor_ioctl, + .ioctl = sensor_ioctl, }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; - static struct v4l2_subdev_ops sensor_subdev_ops = { .core = &sensor_subdev_core_ops, .video = &sensor_subdev_video_ops, @@ -2810,7 +2847,9 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + + sensor->info_priv.fmt = sensor_colour_fmts[0]; + #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov3640.c b/drivers/media/video/ov3640.c index 51f16390be05..3c373d9f1586 100755 --- a/drivers/media/video/ov3640.c +++ b/drivers/media/video/ov3640.c @@ -30,7 +30,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING fmt , ## arg); } while (0) #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) #define _CONS(a,b) a##b #define CONS(a,b) _CONS(a,b) @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_init_data -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -1964,18 +1964,29 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; - enum sensor_work_state { sensor_work_ready = 0, @@ -2007,7 +2018,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int enable; unsigned int funmodule_state; } sensor_info_priv_t; @@ -2581,6 +2592,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -2639,10 +2651,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -2778,77 +2795,82 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } - - -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; int isCapture = 0; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -2858,17 +2880,17 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; - isCapture = sensor_fmt_capturechk(sd, f); + set_w = mf->width; + set_h = mf->height; + isCapture = sensor_fmt_capturechk(sd, mf); if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[isCapture][0].reg) { @@ -2884,7 +2906,6 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } else if (((set_w <= 352) && (set_h<= 288)) && sensor_cif[isCapture][0].reg) { - //printk("===> isCapture: %d!\n", isCapture); winseqe_set_addr = sensor_cif[isCapture]; set_w = 352; set_h = 288; @@ -2930,19 +2951,15 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } - if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) - { - //srt --if capture,then should write sensor_qxga[1] first - - if((winseqe_set_addr != sensor_qxga[isCapture]) && isCapture) - { + if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr){ + //srt --if capture,then should write sensor_qxga[1] first + if((winseqe_set_addr != sensor_qxga[isCapture]) && isCapture) { SENSOR_DG("%s write sensor_qxga[1]\n", SENSOR_NAME_STRING()); ret = sensor_write_array(client, sensor_qxga[isCapture]); - if (ret != 0) - { + if (ret != 0) { SENSOR_TR("%s write sensor_qxga[1] failed\n", SENSOR_NAME_STRING()); return ret; } @@ -2958,7 +2975,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) #endif #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -2975,7 +2992,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -2985,7 +3002,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) goto sensor_s_fmt_end; } else { sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); if (sensor->info_priv.whiteBalance != 0) { @@ -2993,7 +3010,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -3010,45 +3027,42 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) mdelay(100); // by FAE. } SENSOR_DG("\n%s..%s.. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h,isCapture); - } - else - { + } else { SENSOR_TR("\n %s .. Current Format is validate. icd->width=%d..icd->height=%d..isCapture=%d\n",SENSOR_NAME_STRING(),set_w,set_h,isCapture); } - - //add by duanyp. Improve the green phenomenon when startup camera every time. - //mdelay(500); - + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -3892,18 +3906,21 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - #if CONFIG_SENSOR_Focus + #if CONFIG_SENSOR_Focus struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_format fmt; - #endif + struct v4l2_mbus_framefmt mf; + #endif if (enable == 1) { sensor->info_priv.enable = 1; #if CONFIG_SENSOR_Focus - fmt.fmt.pix.width = icd->user_width; - fmt.fmt.pix.height = icd->user_height; + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ - if (sensor_fmt_capturechk(sd, &fmt) == false) { + if (sensor_fmt_capturechk(sd, &mf) == false) { if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { if (sensor->sensor_wq != NULL) { mutex_lock(&sensor->wq_lock); @@ -3990,10 +4007,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, ret = -ENODEV; goto sensor_video_probe_err; } - - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -4059,7 +4072,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -4071,9 +4092,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, .s_stream = sensor_s_stream, }; @@ -4117,7 +4139,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov5640.c b/drivers/media/video/ov5640.c index 50d140e529a0..1c10f84067e2 100755 --- a/drivers/media/video/ov5640.c +++ b/drivers/media/video/ov5640.c @@ -53,8 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 600 #define SENSOR_INIT_WINSEQADR sensor_svga -//#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -722,14 +721,21 @@ static struct reginfo sensor_svga[] = {0x370c, 0x03}, {0x3a02, 0x03}, {0x3a03, 0xd8}, + {0x3a08 ,0x01},/// + {0x3a09, 0x27},/// + {0x3a0a, 0x00},/// + {0x3a0b, 0xf6},/// {0x3a0e, 0x03}, {0x3a0d, 0x04}, {0x3a14, 0x03}, {0x3a15, 0xd8}, {0x4004, 0x02}, + {0x3002, 0x1c},//// + {0x4713, 0x03},//// {0x3035, 0x21}, {0x3036, 0x46}, {0x4837, 0x22}, + {0x3824, 0x02},//// {0x5001, 0xa3}, {SEQUENCE_END, 0x00} }; @@ -1348,17 +1354,28 @@ static struct soc_camera_ops sensor_ops = .num_controls = ARRAY_SIZE(sensor_controls), .num_menus = ARRAY_SIZE(sensor_menus), }; +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; enum sensor_work_state { @@ -1391,7 +1408,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ struct reginfo *winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int enable; unsigned int funmodule_state; } sensor_info_priv_t; @@ -2193,6 +2210,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -2249,10 +2267,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -2392,74 +2414,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret = 0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -2469,16 +2498,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && (sensor_qcif[0].reg!=SEQUENCE_END)) { @@ -2557,12 +2586,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if (winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ sensor_parameter_record(client); /*#if CONFIG_SENSOR_Focus sensor_af_idlechk(client); @@ -2594,7 +2623,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -2605,7 +2634,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ sensor_ae_transfer(client); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2614,7 +2643,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_set_whiteBalance(icd, qctrl,sensor->info_priv.whiteBalance); } sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2636,38 +2665,39 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) { SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2945,8 +2975,10 @@ static int sensor_set_focus_absolute(struct soc_camera_device *icd, const struct int ret = 0; qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_ABSOLUTE); - if (!qctrl_info) - return -EINVAL; + if (!qctrl_info) { + ret = -EINVAL; + goto sensor_set_focus_absolute_end; + } if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { @@ -2972,8 +3004,10 @@ static int sensor_set_focus_relative(struct soc_camera_device *icd, const struct int ret = 0; qctrl_info = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_FOCUS_RELATIVE); - if (!qctrl_info) - return -EINVAL; + if (!qctrl_info) { + ret = -EINVAL; + goto sensor_set_focus_relative_end; + } if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) { if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) { @@ -3476,16 +3510,19 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable) struct sensor *sensor = to_sensor(client); #if CONFIG_SENSOR_Focus struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_format fmt; + struct v4l2_mbus_framefmt mf; #endif if (enable == 1) { sensor->info_priv.enable = 1; #if CONFIG_SENSOR_Focus - fmt.fmt.pix.width = icd->user_width; - fmt.fmt.pix.height = icd->user_height; + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ - if (sensor_fmt_capturechk(sd, &fmt) == false) { + if (sensor_fmt_capturechk(sd, &mf) == false) { if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { if (sensor->sensor_wq != NULL) { mutex_lock(&sensor->wq_lock); @@ -3573,9 +3610,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -3642,7 +3676,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -3654,9 +3696,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, .s_stream = sensor_s_stream, }; @@ -3700,7 +3743,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index 65cc68ad7642..134a1598e97b 100755 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 800 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 600 #define SENSOR_INIT_WINSEQADR sensor_svga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -3261,8 +3261,8 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); static int sensor_deactivate(struct i2c_client *client); -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f); -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f); +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); static struct soc_camera_ops sensor_ops = { @@ -3276,17 +3276,30 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; + enum sensor_work_state { sensor_work_ready = 0, @@ -3318,7 +3331,7 @@ typedef struct sensor_info_priv_s bool snap2preview; bool video2preview; struct reginfo *winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int enable; unsigned int funmodule_state; } sensor_info_priv_t; @@ -3825,7 +3838,7 @@ static int sensor_af_wq_function(struct i2c_client *client) struct af_cmdinfo cmdinfo; int ret=0, focus_pos = 0xfe; struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_format fmt; + struct v4l2_mbus_framefmt mf; SENSOR_DG("%s %s Enter\n",SENSOR_NAME_STRING(), __FUNCTION__); @@ -3836,9 +3849,12 @@ static int sensor_af_wq_function(struct i2c_client *client) } else { sensor->info_priv.funmodule_state |= SENSOR_AF_IS_OK; - fmt.fmt.pix.width = icd->user_width; - fmt.fmt.pix.height = icd->user_height; - if (sensor_fmt_videochk(NULL, &fmt) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; + if (sensor_fmt_videochk(NULL, &mf) == true) { /* ddl@rock-chips.com: focus mode fix const auto focus in video */ ret = sensor_af_const(client); } else { switch (sensor->info_priv.auto_focus) @@ -4091,6 +4107,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -4141,16 +4158,19 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } ret = sensor_write_array(client, sensor_init_data); - if (ret != 0) - { + if (ret != 0) { SENSOR_TR("error: %s initial failed\n",SENSOR_NAME_STRING()); goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -4288,76 +4308,81 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } - -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; + const struct sensor_datafmt *fmt; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret = 0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -4367,16 +4392,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -4455,12 +4480,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if (winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ sensor_parameter_record(client); #if CONFIG_SENSOR_Flash if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { @@ -4489,7 +4514,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -4501,7 +4526,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ sensor_ae_transfer(client); qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -4521,7 +4546,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); #if CONFIG_SENSOR_Focus @@ -4562,38 +4587,39 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -5444,16 +5470,21 @@ static int sensor_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); + #if CONFIG_SENSOR_Focus struct soc_camera_device *icd = client->dev.platform_data; - struct v4l2_format fmt; + struct v4l2_mbus_framefmt mf; + #endif if (enable == 1) { sensor->info_priv.enable = 1; #if CONFIG_SENSOR_Focus - fmt.fmt.pix.width = icd->user_width; - fmt.fmt.pix.height = icd->user_height; + mf.width = icd->user_width; + mf.height = icd->user_height; + mf.code = sensor->info_priv.fmt.code; + mf.colorspace = sensor->info_priv.fmt.colorspace; + mf.field = V4L2_FIELD_NONE; /* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */ - if (sensor_fmt_capturechk(sd, &fmt) == false) { + if (sensor_fmt_capturechk(sd, &mf) == false) { if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) { if (sensor->sensor_wq != NULL) { mutex_lock(&sensor->wq_lock); @@ -5541,9 +5572,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -5612,7 +5640,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -5624,12 +5660,12 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, .s_stream = sensor_s_stream, }; - static struct v4l2_subdev_ops sensor_subdev_ops = { .core = &sensor_subdev_core_ops, .video = &sensor_subdev_video_ops, @@ -5670,7 +5706,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/ov7675.c b/drivers/media/video/ov7675.c index 8417928571ee..7453d6d97499 100755 --- a/drivers/media/video/ov7675.c +++ b/drivers/media/video/ov7675.c @@ -54,7 +54,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -144,7 +144,7 @@ static struct reginfo sensor_init_data[] = {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, - {0x1e, 0x07}, //0x27 + {0x1e, 0x17}, //0x07//0x27 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, @@ -181,22 +181,22 @@ static struct reginfo sensor_init_data[] = {0x66, 0x05}, {0x94, 0x10}, {0x95, 0x12}, - {0x7a, 0x24}, - {0x7b, 0x04}, - {0x7c, 0x07}, - {0x7d, 0x12}, - {0x7e, 0x2f}, - {0x7f, 0x3f}, - {0x80, 0x4d}, - {0x81, 0x5a}, - {0x82, 0x69}, - {0x83, 0x74}, - {0x84, 0x7f}, - {0x85, 0x91}, - {0x86, 0x9e}, - {0x87, 0xbb}, - {0x88, 0xd2}, - {0x89, 0xe5}, + {0x7a, 0x20},// {0x7a, 0x24}, + {0x7b, 0x16},// {0x7b, 0x04}, + {0x7c, 0x23},// {0x7c, 0x07}, + {0x7d, 0x3c},// {0x7d, 0x12}, + {0x7e, 0x5c},// {0x7e, 0x2f}, + {0x7f, 0x69},// {0x7f, 0x3f}, + {0x80, 0x75},// {0x80, 0x4d}, + {0x81, 0x7e},// {0x81, 0x5a}, + {0x82, 0x88},// {0x82, 0x69}, + {0x83, 0x8f},// {0x83, 0x74}, + {0x84, 0x96},// {0x84, 0x7f}, + {0x85, 0xa3},// {0x85, 0x91}, + {0x86, 0xaf},// {0x86, 0x9e}, + {0x87, 0xc4},// {0x87, 0xbb}, + {0x88, 0xd7},// {0x88, 0xd2}, + {0x89, 0xe8},// {0x89, 0xe5}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x34}, @@ -228,7 +228,7 @@ static struct reginfo sensor_init_data[] = {0x75, 0x63}, {0x76, 0xe1}, {0x4c, 0x00}, - {0x77, 0x01}, + {0x77, 0x04},//0x01 {0x4b, 0x09}, {0xc9, 0x60}, {0x41, 0x38}, @@ -1103,16 +1103,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) + return NULL; +} -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1132,7 +1144,7 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; } sensor_info_priv_t; @@ -1214,7 +1226,7 @@ static int sensor_write(struct i2c_client *client, u8 reg, u8 val) while ((cnt-- > 0) && (err < 0)) { /* ddl@rock-chips.com : Transfer again if transent is failed */ err = i2c_transfer(client->adapter, msg, 1); - + udelay(50); if (err >= 0) { return 0; } else { @@ -1230,13 +1242,10 @@ static int sensor_write(struct i2c_client *client, u8 reg, u8 val) static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) { int err,cnt; - //u8 buf[2]; u8 buf[1]; struct i2c_msg msg[2]; - - //buf[0] = reg >> 8; + buf[0] = reg; - buf[1] = reg & 0xFF; msg[0].addr = client->addr; msg[0].flags = client->flags; @@ -1270,7 +1279,6 @@ static int sensor_read(struct i2c_client *client, u8 reg, u8 *val) } /* write a array of registers */ -#if 1 static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) { int err = 0, cnt; @@ -1311,27 +1319,24 @@ sensor_write_array_end: sensor_task_lock(client,0); return err; } -#else -static int sensor_write_array(struct i2c_client *client, struct reginfo *regarray) +static int sensor_readchk_array(struct i2c_client *client, struct reginfo *regarray) { - int err; + int cnt; int i = 0; - u8 val_read; + char valchk; + + cnt = 0; + valchk = 0; while (regarray[i].reg != 0) { - err = sensor_write(client, regarray[i].reg, regarray[i].val); - if (err != 0) - { - SENSOR_TR("%s..write failed current i = %d\n", SENSOR_NAME_STRING(),i); - return err; - } - err = sensor_read(client, regarray[i].reg, &val_read); - SENSOR_TR("%s..reg[0x%x]=0x%x,0x%x\n", SENSOR_NAME_STRING(),regarray[i].reg, val_read, regarray[i].val); + sensor_read(client, regarray[i].reg, &valchk); + if (valchk != regarray[i].val) + SENSOR_TR("%s Reg:0x%x read(0x%x, 0x%x) error\n",SENSOR_NAME_STRING(), regarray[i].reg, regarray[i].val, valchk); + i++; } return 0; } -#endif static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on) { struct soc_camera_link *icl = to_soc_camera_link(icd); @@ -1343,10 +1348,12 @@ static int sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd case Sensor_PowerDown: { if (icl->powerdown) { + if (on == 0) + mdelay(1); ret = icl->powerdown(icd->pdev, on); if (ret == RK29_CAM_IO_SUCCESS) { if (on == 0) { - mdelay(2); + mdelay(20); if (icl->reset) icl->reset(icd->pdev); } @@ -1382,6 +1389,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; int ret; SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1411,10 +1419,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - //icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1548,71 +1560,77 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; char readval; int ret=0, set_w,set_h; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { //winseqe_set_addr = sensor_ClrFmt_YUYV; sensor_read(client, 0x3a, &readval); @@ -1621,7 +1639,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_write(client,0x3d,readval&0xfe); break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { //winseqe_set_addr = sensor_ClrFmt_UYVY; sensor_read(client, 0x3a, &readval); @@ -1635,16 +1653,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1678,7 +1696,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } else if (((set_w <= 1280) && (set_h <= 1024)) && sensor_sxga[0].reg) { - winseqe_set_addr = sensor_sxga; + winseqe_set_addr = sensor_vga; //sensor_sxga; set_w = 1280; set_h = 1024; } @@ -1687,12 +1705,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -1708,7 +1726,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -1720,7 +1738,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1732,7 +1750,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -1762,39 +1780,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2144,10 +2163,9 @@ static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct soc_camera_device *icd = client->dev.platform_data; + struct soc_camera_device *icd = client->dev.platform_data; const struct v4l2_queryctrl *qctrl; - - + qctrl = soc_camera_find_qctrl(&sensor_ops, ctrl->id); if (!qctrl) @@ -2525,9 +2543,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2597,6 +2612,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2608,9 +2632,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2653,7 +2678,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/rk29_camera_oneframe.c b/drivers/media/video/rk29_camera_oneframe.c index f1e3350ca374..89a0ac76f93a 100755 --- a/drivers/media/video/rk29_camera_oneframe.c +++ b/drivers/media/video/rk29_camera_oneframe.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -47,7 +48,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING"rk29xx_camera: " fmt , ## arg); } while (0) #define RK29CAMERA_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define RK29CAMERA_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) +#define RK29CAMERA_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) // VIP Reg Offset #define RK29_VIP_AHBR_CTRL 0x00 @@ -130,7 +131,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CAM_IPPWORK_IS_EN() ((pcdev->host_width != pcdev->icd->user_width) || (pcdev->host_height != pcdev->icd->user_height)) //Configure Macro -#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 2) +#define RK29_CAM_VERSION_CODE KERNEL_VERSION(0, 1, 2) /* limit to rk29 hardware capabilities */ #define RK29_CAM_BUS_PARAM (SOCAM_MASTER |\ @@ -158,21 +159,13 @@ module_param(debug, int, S_IRUGO|S_IWUSR); extern void videobuf_dma_contig_free(struct videobuf_queue *q, struct videobuf_buffer *buf); extern dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); -extern void videobuf_queue_dma_contig_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, - struct device *dev, - spinlock_t *irqlock, - enum v4l2_buf_type type, - enum v4l2_field field, - unsigned int msize, - void *priv); /* buffer for one video frame */ struct rk29_buffer { /* common v4l buffer stuff -- must be first */ struct videobuf_buffer vb; - const struct soc_camera_data_format *fmt; + enum v4l2_mbus_pixelcode code; int inwork; }; enum rk29_camera_reg_state @@ -265,18 +258,18 @@ static int rk29_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, struct soc_camera_device *icd = vq->priv_data; struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct rk29_camera_dev *pcdev = ici->priv; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); + if (bytes_per_line < 0) + return bytes_per_line; + /* planar capture requires Y, U and V buffers to be page aligned */ - #if 0 - int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; - *size = PAGE_ALIGN(icd->user_width* icd->user_height * bytes_per_pixel); /* Y pages UV pages, yuv422*/ - pcdev->vipmem_bsize = PAGE_ALIGN(pcdev->host_width * pcdev->host_height * bytes_per_pixel); - #else - *size = PAGE_ALIGN((icd->user_width* icd->user_height * icd->current_fmt->depth + 7)>>3); /* Y pages UV pages, yuv422*/ - pcdev->vipmem_bsize = PAGE_ALIGN((pcdev->host_width * pcdev->host_height * icd->current_fmt->depth + 7)>>3); - #endif + *size = PAGE_ALIGN(bytes_per_line*icd->user_height); /* Y pages UV pages, yuv422*/ + pcdev->vipmem_bsize = PAGE_ALIGN(bytes_per_line * pcdev->host_height); + if (CAM_WORKQUEUE_IS_EN()) { if (CAM_IPPWORK_IS_EN()) { @@ -328,6 +321,10 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff struct soc_camera_device *icd = vq->priv_data; struct rk29_buffer *buf; int ret; + int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, + icd->current_fmt->host_fmt); + if (bytes_per_line < 0) + return bytes_per_line; buf = container_of(vb, struct rk29_buffer, vb); @@ -345,18 +342,18 @@ static int rk29_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buff BUG_ON(NULL == icd->current_fmt); - if (buf->fmt != icd->current_fmt || + if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { - buf->fmt = icd->current_fmt; + buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } - vb->size = (((vb->width * vb->height *buf->fmt->depth) + 7) >> 3) ; /* ddl@rock-chips.com : fmt->depth is coorect */ + vb->size = bytes_per_line*vb->height; /* ddl@rock-chips.com : fmt->depth is coorect */ if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; @@ -827,16 +824,38 @@ static void rk29_camera_remove_device(struct soc_camera_device *icd) return; } - static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) { unsigned long bus_flags, camera_flags, common_flags; unsigned int vip_ctrl_val = 0; - int ret = 0; + const struct soc_mbus_pixelfmt *fmt; + int ret = 0; RK29CAMERA_DG("%s..%d..\n",__FUNCTION__,__LINE__); + fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code); + if (!fmt) + return -EINVAL; + bus_flags = RK29_CAM_BUS_PARAM; + /* If requested data width is supported by the platform, use it */ + switch (fmt->bits_per_sample) { + case 10: + if (!(bus_flags & SOCAM_DATAWIDTH_10)) + return -EINVAL; + break; + case 9: + if (!(bus_flags & SOCAM_DATAWIDTH_9)) + return -EINVAL; + break; + case 8: + if (!(bus_flags & SOCAM_DATAWIDTH_8)) + return -EINVAL; + break; + default: + return -EINVAL; + } + if (icd->ops->query_bus_param) camera_flags = icd->ops->query_bus_param(icd); else @@ -852,12 +871,6 @@ static int rk29_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt if (ret < 0) goto RK29_CAMERA_SET_BUS_PARAM_END; - if (common_flags & SOCAM_DATAWIDTH_8) { - icd->buswidth = 8; - } else if (common_flags & SOCAM_DATAWIDTH_10) { - icd->buswidth = 10; - } - vip_ctrl_val = read_vip_reg(RK29_VIP_CTRL); if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) { vip_ctrl_val |= NEGATIVE_EDGE; @@ -907,36 +920,36 @@ static int rk29_camera_try_bus_param(struct soc_camera_device *icd, __u32 pixfmt camera_flags, bus_flags); return ret; } -static const struct soc_camera_data_format rk29_camera_formats[] = { - { - .name = "YUV420 NV12", - .depth = 12, - .fourcc = V4L2_PIX_FMT_NV12, - .colorspace = V4L2_COLORSPACE_JPEG, + +static const struct soc_mbus_pixelfmt rk29_camera_formats[] = { + { + .fourcc = V4L2_PIX_FMT_NV12, + .name = "YUV420 NV12", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, },{ - .name = "YUV422 NV16", - .depth = 16, - .fourcc = V4L2_PIX_FMT_NV16, - .colorspace = V4L2_COLORSPACE_JPEG, + .fourcc = V4L2_PIX_FMT_NV16, + .name = "YUV422 NV16", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, },{ - .name = "NV12(v0.0.1)", /* ddl@rock-chips.com: 0.0.1 driver */ - .depth = 12, - .fourcc = V4L2_PIX_FMT_YUV420, - .colorspace = V4L2_COLORSPACE_JPEG, + .fourcc = V4L2_PIX_FMT_YUV420, + .name = "NV12(v0.0.1)", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, },{ - .name = "NV16(v0.0.1)", - .depth = 16, - .fourcc = V4L2_PIX_FMT_YUV422P, - .colorspace = V4L2_COLORSPACE_JPEG, - },{ - .name = "Raw Bayer RGB 10 bit", - .depth = 16, - .fourcc = V4L2_PIX_FMT_SGRBG10, - .colorspace = V4L2_COLORSPACE_SRGB, + .fourcc = V4L2_PIX_FMT_YUV422P, + .name = "NV16(v0.0.1)", + .bits_per_sample = 8, + .packing = SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, } }; -static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, __u32 cam_pixfmt, struct v4l2_rect *rect) +static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_pixfmt, enum v4l2_mbus_pixelcode icd_code, struct v4l2_rect *rect) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct rk29_camera_dev *pcdev = ici->priv; @@ -958,22 +971,17 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p pcdev->frame_inval = RK29_CAM_FRAME_INVAL_INIT; pcdev->pixfmt = host_pixfmt; break; - case V4L2_PIX_FMT_SGRBG10: - vip_ctrl_val |= (VIP_RAW | VIP_SENSOR | VIP_DATA_LITTLEEND); - pcdev->frame_inval = RK29_CAM_FRAME_INVAL_DC; - pcdev->pixfmt = host_pixfmt; - break; default: /* ddl@rock-chips.com : vip output format is hold when pixfmt is invalidate */ vip_ctrl_val |= (read_vip_reg(RK29_VIP_CTRL) & VIPREGYUV422); break; } - switch (cam_pixfmt) + switch (icd_code) { - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: vip_ctrl_val |= SENSOR_UYVY; break; - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: vip_ctrl_val |= SENSOR_YUYV; break; default : @@ -1007,74 +1015,66 @@ static void rk29_camera_setup_format(struct soc_camera_device *icd, __u32 host_p static int rk29_camera_get_formats(struct soc_camera_device *icd, int idx, struct soc_camera_format_xlate *xlate) { + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->dev.parent; - int formats = 0, buswidth, ret; - - buswidth = 8; + int formats = 0, ret; + enum v4l2_mbus_pixelcode code; + const struct soc_mbus_pixelfmt *fmt; + + ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); + if (ret < 0) + /* No more formats */ + return 0; + + fmt = soc_mbus_get_fmtdesc(code); + if (!fmt) { + dev_err(dev, "Invalid format code #%u: %d\n", idx, code); + return 0; + } - ret = rk29_camera_try_bus_param(icd, buswidth); + ret = rk29_camera_try_bus_param(icd, fmt->bits_per_sample); if (ret < 0) return 0; - switch (icd->formats[idx].fourcc) { - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YUYV: + switch (code) { + case V4L2_MBUS_FMT_UYVY8_2X8: + case V4L2_MBUS_FMT_YUYV8_2X8: formats++; if (xlate) { xlate->host_fmt = &rk29_camera_formats[0]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - rk29_camera_formats[0].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + rk29_camera_formats[0].name,code); } formats++; if (xlate) { xlate->host_fmt = &rk29_camera_formats[1]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - rk29_camera_formats[1].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + rk29_camera_formats[1].name,code); } formats++; if (xlate) { xlate->host_fmt = &rk29_camera_formats[2]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - rk29_camera_formats[2].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + rk29_camera_formats[2].name,code); } formats++; if (xlate) { xlate->host_fmt = &rk29_camera_formats[3]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = buswidth; + xlate->code = code; xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - rk29_camera_formats[3].name, - icd->formats[idx].name); + dev_dbg(dev, "Providing format %s using code %d\n", + rk29_camera_formats[3].name,code);; } - break; - case V4L2_PIX_FMT_SGRBG10: - formats++; - if (xlate) { - xlate->host_fmt = &rk29_camera_formats[4]; - xlate->cam_fmt = icd->formats + idx; - xlate->buswidth = 10; - xlate++; - dev_dbg(dev, "Providing format %s using %s\n", - rk29_camera_formats[2].name, - icd->formats[idx].name); - } - break; + break; default: break; } @@ -1091,34 +1091,32 @@ static int rk29_camera_set_crop(struct soc_camera_device *icd, struct v4l2_crop *a) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct v4l2_format f; - struct v4l2_pix_format *pix = &f.fmt.pix; + struct v4l2_mbus_framefmt mf; + u32 fourcc = icd->current_fmt->host_fmt->fourcc; int ret; - f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_fmt, &f); + ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); if (ret < 0) return ret; - if ((pix->width < (a->c.left + a->c.width)) || (pix->height < (a->c.top + a->c.height))) { + if ((mf.width < (a->c.left + a->c.width)) || (mf.height < (a->c.top + a->c.height))) { - pix->width = a->c.left + a->c.width; - pix->height = a->c.top + a->c.height; + mf.width = a->c.left + a->c.width; + mf.height = a->c.top + a->c.height; - v4l_bound_align_image(&pix->width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1, - &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0, - icd->current_fmt->fourcc == V4L2_PIX_FMT_NV16 ?4 : 0); + v4l_bound_align_image(&mf.width, RK29_CAM_W_MIN, RK29_CAM_W_MAX, 1, + &mf.height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0, + fourcc == V4L2_PIX_FMT_NV16 ?4 : 0); - ret = v4l2_subdev_call(sd, video, s_fmt, &f); + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); if (ret < 0) return ret; } - rk29_camera_setup_format(icd, icd->current_fmt->fourcc, pix->pixelformat, &a->c); + rk29_camera_setup_format(icd, fourcc, mf.code, &a->c); - icd->user_width = pix->width; - icd->user_height = pix->height; + icd->user_width = mf.width; + icd->user_height = mf.height; return 0; } @@ -1128,12 +1126,11 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, { struct device *dev = icd->dev.parent; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - const struct soc_camera_data_format *cam_fmt = NULL; const struct soc_camera_format_xlate *xlate = NULL; struct soc_camera_host *ici =to_soc_camera_host(icd->dev.parent); struct rk29_camera_dev *pcdev = ici->priv; struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_format cam_f = *f; + struct v4l2_mbus_framefmt mf; struct v4l2_rect rect; int ret,usr_w,usr_h; int stream_on = 0; @@ -1148,8 +1145,7 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, ret = -EINVAL; goto RK29_CAMERA_SET_FMT_END; } - - cam_fmt = xlate->cam_fmt; + /* ddl@rock-chips.com: sensor init code transmit in here after open */ if (pcdev->icd_init == 0) { v4l2_subdev_call(sd,core, init, 0); @@ -1159,14 +1155,22 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, stream_on = read_vip_reg(RK29_VIP_CTRL); if (stream_on & ENABLE_CAPTURE) write_vip_reg(RK29_VIP_CTRL, (stream_on & (~ENABLE_CAPTURE))); - cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; - ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); - cam_f.fmt.pix.pixelformat = pix->pixelformat; - *pix = cam_f.fmt.pix; + + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); + + if (mf.code != xlate->code) + return -EINVAL; + #ifdef CONFIG_VIDEO_RK29_WORK_IPP - if ((pix->width != usr_w) || (pix->height != usr_h)) { - if (unlikely((pix->width <16) || (pix->width > 8190) || (pix->height < 16) || (pix->height > 8190))) { - RK29CAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",pix->width,pix->height); + if ((mf.width != usr_w) || (mf.height != usr_h)) { + if (unlikely((mf.width <16) || (mf.width > 8190) || (mf.height < 16) || (mf.height > 8190))) { + RK29CAMERA_TR("Senor and IPP both invalid source resolution(%dx%d)\n",mf.width,mf.height); ret = -EINVAL; goto RK29_CAMERA_SET_FMT_END; } @@ -1175,8 +1179,8 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, ret = -EINVAL; goto RK29_CAMERA_SET_FMT_END; } - pix->width = usr_w; - pix->height = usr_h; + mf.width = usr_w; + mf.height = usr_h; } #endif icd->sense = NULL; @@ -1184,18 +1188,22 @@ static int rk29_camera_set_fmt(struct soc_camera_device *icd, if (!ret) { rect.left = 0; rect.top = 0; - rect.width = cam_f.fmt.pix.width; - rect.height = cam_f.fmt.pix.height; - - RK29CAMERA_DG("%s..%s..%s icd width:%d host width:%d \n",__FUNCTION__,xlate->host_fmt->name, cam_fmt->name, - rect.width, pix->width); - rk29_camera_setup_format(icd, pix->pixelformat, cam_fmt->fourcc, &rect); - icd->buswidth = xlate->buswidth; - icd->current_fmt = xlate->host_fmt; + rect.width = mf.width; + rect.height = mf.height; + RK29CAMERA_DG("%s..%s..v4l2_mbus_code:%d icd:%dx%d host:%dx%d \n",__FUNCTION__,xlate->host_fmt->name, mf.code, + rect.width,rect.height, pix->width,pix->height); + rk29_camera_setup_format(icd, pix->pixelformat, mf.code, &rect); + if (CAM_IPPWORK_IS_EN()) { BUG_ON(pcdev->vipmem_phybase == 0); } + + pix->width = mf.width; + pix->height = mf.height; + pix->field = mf.field; + pix->colorspace = mf.colorspace; + icd->current_fmt = xlate; } RK29_CAMERA_SET_FMT_END: @@ -1234,10 +1242,10 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; __u32 pixfmt = pix->pixelformat; - enum v4l2_field field; int ret,usr_w,usr_h,i; bool is_capture = rk29_camera_fmt_capturechk(f); bool vipmem_is_overflow = false; + struct v4l2_mbus_framefmt mf; usr_w = pix->width; usr_h = pix->height; @@ -1245,7 +1253,7 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { - dev_err(ici->v4l2_dev.dev, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF, + dev_err(icd->dev.parent, "Format (%c%c%c%c) not found\n", pixfmt & 0xFF, (pixfmt >> 8) & 0xFF, (pixfmt >> 16) & 0xFF, (pixfmt >> 24) & 0xFF); ret = -EINVAL; RK29CAMERA_TR("%s(version:%c%c%c) support format:\n",rk29_cam_driver_description,(RK29_CAM_VERSION_CODE&0xff0000)>>16, @@ -1262,21 +1270,29 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, &pix->height, RK29_CAM_H_MIN, RK29_CAM_H_MAX, 0, pixfmt == V4L2_PIX_FMT_NV16 ? 4 : 0); - pix->bytesperline = pix->width * DIV_ROUND_UP(xlate->host_fmt->depth, 8); - pix->sizeimage = pix->height * pix->bytesperline; + pix->bytesperline = soc_mbus_bytes_per_line(pix->width, + xlate->host_fmt); + if (pix->bytesperline < 0) + return pix->bytesperline; - /* camera has to see its format, but the user the original one */ - pix->pixelformat = xlate->cam_fmt->fourcc; /* limit to sensor capabilities */ - ret = v4l2_subdev_call(sd, video, try_fmt, f); - pix->pixelformat = pixfmt; + mf.width = pix->width; + mf.height = pix->height; + mf.field = pix->field; + mf.colorspace = pix->colorspace; + mf.code = xlate->code; + + ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); + if (ret < 0) + goto RK29_CAMERA_TRY_FMT_END; + #ifdef CONFIG_VIDEO_RK29_WORK_IPP - if ((pix->width > usr_w) && (pix->height > usr_h)) { + if ((mf.width > usr_w) && (mf.height > usr_h)) { if (is_capture) { - vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size); + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size); } else { /* Assume preview buffer minimum is 4 */ - vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size); + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size); } if (vipmem_is_overflow == false) { pix->width = usr_w; @@ -1284,12 +1300,12 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, } else { RK29CAMERA_TR("vipmem for IPP is overflow, This resolution(%dx%d -> %dx%d) is invalidate!\n",pix->width,pix->height,usr_w,usr_h); } - } else if ((pix->width < usr_w) && (pix->height < usr_h)) { - if (((usr_w>>1) < pix->width) && ((usr_h>>1) < pix->height)) { + } else if ((mf.width < usr_w) && (mf.height < usr_h)) { + if (((usr_w>>1) < mf.width) && ((usr_h>>1) < mf.height)) { if (is_capture) { - vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3) > pcdev->vipmem_size); + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height) > pcdev->vipmem_size); } else { - vipmem_is_overflow = (PAGE_ALIGN((pix->width*pix->height*icd->current_fmt->depth+7)>>3)*4 > pcdev->vipmem_size); + vipmem_is_overflow = (PAGE_ALIGN(pix->bytesperline*pix->height)*4 > pcdev->vipmem_size); } if (vipmem_is_overflow == false) { pix->width = usr_w; @@ -1301,17 +1317,23 @@ static int rk29_camera_try_fmt(struct soc_camera_device *icd, RK29CAMERA_TR("The aspect ratio(%dx%d/%dx%d) is bigger than 2 !\n",pix->width,pix->height,usr_w,usr_h); } } - #endif - - field = pix->field; - - if (field == V4L2_FIELD_ANY) { - pix->field = V4L2_FIELD_NONE; - } else if (field != V4L2_FIELD_NONE) { - dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); - ret = -EINVAL; - goto RK29_CAMERA_TRY_FMT_END; - } + #else + pix->width = mf.width; + pix->height = mf.height; + #endif + pix->colorspace = mf.colorspace; + + switch (mf.field) { + case V4L2_FIELD_ANY: + case V4L2_FIELD_NONE: + pix->field = V4L2_FIELD_NONE; + break; + default: + /* TODO: support interlaced at least in pass-through mode */ + dev_err(icd->dev.parent, "Field type %d unsupported.\n", + mf.field); + goto RK29_CAMERA_TRY_FMT_END; + } RK29_CAMERA_TRY_FMT_END: if (ret) @@ -1446,7 +1468,7 @@ static void rk29_camera_reinit_work(struct work_struct *work) { struct device *control; struct v4l2_subdev *sd; - struct v4l2_format cam_f; + struct v4l2_mbus_framefmt mf; const struct soc_camera_format_xlate *xlate; int ret; @@ -1456,11 +1478,12 @@ static void rk29_camera_reinit_work(struct work_struct *work) sd = dev_get_drvdata(control); ret = v4l2_subdev_call(sd,core, init, 1); - cam_f.fmt.pix.width = rk29_camdev_info_ptr->icd->user_width; - cam_f.fmt.pix.height = rk29_camdev_info_ptr->icd->user_height; - xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->fourcc); - cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc; - ret |= v4l2_subdev_call(sd, video, s_fmt, &cam_f); + mf.width = rk29_camdev_info_ptr->icd->user_width; + mf.height = rk29_camdev_info_ptr->icd->user_height; + xlate = soc_camera_xlate_by_fourcc(rk29_camdev_info_ptr->icd, rk29_camdev_info_ptr->icd->current_fmt->host_fmt->fourcc); + mf.code = xlate->code; + + ret |= v4l2_subdev_call(sd, video, s_mbus_fmt, &mf); write_vip_reg(RK29_VIP_CTRL, (read_vip_reg(RK29_VIP_CTRL)|ENABLE_CAPTURE)); diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c index cddf4a8e3d0e..96ae6dffe480 100644 --- a/drivers/media/video/s5k6aa.c +++ b/drivers/media/video/s5k6aa.c @@ -57,7 +57,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -2932,15 +2932,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG} }; enum sensor_work_state { @@ -2977,7 +2990,7 @@ typedef struct sensor_info_priv_s int preview_w; int preview_h; struct reginfo *winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; unsigned int enable; unsigned int funmodule_state; } sensor_info_priv_t; @@ -3304,6 +3317,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; int ret; u16 pid = 0; @@ -3362,7 +3376,13 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) } sensor_task_lock(client,0); sensor->info_priv.winseqe_cur_addr = SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -3562,54 +3582,53 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *ret_h) @@ -3691,23 +3710,30 @@ static struct reginfo* sensor_fmt_catch(int set_w, int set_h, int *ret_w, int *r return winseqe_set_addr; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; - struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; + struct sensor *sensor = to_sensor(client); struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { winseqe_set_addr = sensor_ClrFmt_YUYV; break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { winseqe_set_addr = sensor_ClrFmt_UYVY; break; @@ -3717,22 +3743,22 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; winseqe_set_addr = sensor_fmt_catch(set_w, set_h, &set_w, &set_h); if ((winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) && winseqe_set_addr) { #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_On); SENSOR_DG("%s flash on in capture!\n", SENSOR_NAME_STRING()); @@ -3748,7 +3774,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) if (ret != 0) { SENSOR_TR("%s set format capability failed\n", SENSOR_NAME_STRING()); #if CONFIG_SENSOR_Flash - if (sensor_fmt_capturechk(sd,f) == true) { + if (sensor_fmt_capturechk(sd,mf) == true) { if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); SENSOR_TR("%s Capture format set fail, flash off !\n", SENSOR_NAME_STRING()); @@ -3766,47 +3792,39 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_TR("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - int ret = 0; - struct v4l2_pix_format *pix = &f->fmt.pix; - int set_w,set_h; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - set_w = pix->width; - set_h = pix->height; - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - if (sensor_fmt_catch(pix->width, pix->height, &pix->width, &pix->height) == NULL) { - pix->width = 0; - pix->height = 0; - } + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + return ret; } @@ -4561,9 +4579,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -4631,6 +4646,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -4642,12 +4666,12 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, - .s_stream = sensor_s_stream, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, + .s_stream = sensor_s_stream, }; - static struct v4l2_subdev_ops sensor_subdev_ops = { .core = &sensor_subdev_core_ops, .video = &sensor_subdev_video_ops, @@ -4688,7 +4712,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; ret = sensor_video_probe(icd, client); if (ret) { diff --git a/drivers/media/video/sid130B.c b/drivers/media/video/sid130B.c index e8dc7f8474bc..89cbcfa1e8e5 100755 --- a/drivers/media/video/sid130B.c +++ b/drivers/media/video/sid130B.c @@ -53,7 +53,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_UYVY +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_UYVY8_2X8 #define CONFIG_SENSOR_WhiteBalance 1 #define CONFIG_SENSOR_Brightness 0 @@ -89,6 +89,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + struct reginfo { u8 reg; @@ -1388,16 +1393,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } - -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) - -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; + +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; + + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1417,8 +1434,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; - + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -1663,6 +1680,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; char value; int ret,pid = 0; @@ -1732,10 +1750,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) goto sensor_INIT_ERR; } sensor_task_lock(client,0); - // icd->user_width = SENSOR_INIT_WIDTH; - //icd->user_height = SENSOR_INIT_HEIGHT; - sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1786,9 +1808,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1797,20 +1820,20 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - + struct sensor *sensor = to_sensor(client); + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - //sensor_task_lock(client, 1); - //sensor_write(client, 0x30b0, 0x00); - //sensor_write(client, 0x30b1, 0x00); - //sensor_task_lock(client, 0); + sensor_ioctrl(icd, Sensor_PowerDown, 1); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; + icd->user_height = SENSOR_INIT_HEIGHT; msleep(100); + + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; return 0; } @@ -1874,94 +1897,100 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct i2c_client *client = sd->priv; - struct soc_camera_device *icd = client->dev.platform_data; - struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; - - return 0; -} -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - bool ret = false; - - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { - ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { - ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { - ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { - ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); - return ret; -} - -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - bool ret = false; - - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { - ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { - ret = true; - } - - if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); - return ret; -} -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = sd->priv; + struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); + + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; + + return 0; +} +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1024) && (mf->height == 768)) { + ret = true; + } else if ((mf->width == 1280) && (mf->height == 1024)) { + ret = true; + } else if ((mf->width == 1600) && (mf->height == 1200)) { + ret = true; + } else if ((mf->width == 2048) && (mf->height == 1536)) { + ret = true; + } else if ((mf->width == 2592) && (mf->height == 1944)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} + +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + bool ret = false; + + if ((mf->width == 1280) && (mf->height == 720)) { + ret = true; + } else if ((mf->width == 1920) && (mf->height == 1080)) { + ret = true; + } + + if (ret == true) + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); + return ret; +} +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; const struct v4l2_queryctrl *qctrl; struct soc_camera_device *icd = client->dev.platform_data; struct reginfo *winseqe_set_addr=NULL; int ret=0, set_w,set_h; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) - { - case V4L2_PIX_FMT_YUYV: - { - winseqe_set_addr = sensor_ClrFmt_YUYV; - break; - } - case V4L2_PIX_FMT_UYVY: - { - winseqe_set_addr = sensor_ClrFmt_UYVY; - break; - } - default: - break; - } - if (winseqe_set_addr != NULL) { - sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); - } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); - } - } - - set_w = pix->width; - set_h = pix->height; + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) + { + case V4L2_MBUS_FMT_YUYV8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_YUYV; + break; + } + case V4L2_MBUS_FMT_UYVY8_2X8: + { + winseqe_set_addr = sensor_ClrFmt_UYVY; + break; + } + default: + break; + } + if (winseqe_set_addr != NULL) { + sensor_write_array(client, winseqe_set_addr); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); + } else { + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); + } + } + + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) &&( sensor_qcif[0].reg!=0xff)) { @@ -2016,7 +2045,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) { @@ -2049,7 +2078,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = (int)winseqe_set_addr; - if (sensor_fmt_capturechk(sd,f) == true) { /* ddl@rock-chips.com : Capture */ + if (sensor_fmt_capturechk(sd,mf) == true) { /* ddl@rock-chips.com : Capture */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2061,7 +2090,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } #endif sensor->info_priv.snap2preview = true; - } else if (sensor_fmt_videochk(sd,f) == true) { /* ddl@rock-chips.com : Video */ + } else if (sensor_fmt_videochk(sd,mf) == true) { /* ddl@rock-chips.com : Video */ #if CONFIG_SENSOR_Effect qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_EFFECT); sensor_set_effect(icd, qctrl,sensor->info_priv.effect); @@ -2090,37 +2119,40 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) -{ - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - return 0; +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) +{ + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) @@ -2337,7 +2369,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v } #endif #if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct sensor *sensor = to_sensor(client); @@ -2351,29 +2383,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2382,7 +2414,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2861,8 +2893,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } #endif - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); return 0; @@ -2932,6 +2962,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2942,10 +2981,11 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .ioctl = sensor_ioctl, }; -static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, +static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2988,7 +3028,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif diff --git a/drivers/media/video/siv120b.c b/drivers/media/video/siv120b.c index ade9562072ac..40eb75327829 100755 --- a/drivers/media/video/siv120b.c +++ b/drivers/media/video/siv120b.c @@ -30,7 +30,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); printk(KERN_WARNING fmt , ## arg); } while (0) #define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__) -#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__) +#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__) #define _CONS(a,b) a##b @@ -54,7 +54,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_INIT_WIDTH 640 /* Sensor pixel size for sensor_init_data array */ #define SENSOR_INIT_HEIGHT 480 #define SENSOR_INIT_WINSEQADR sensor_vga -#define SENSOR_INIT_PIXFMT V4L2_PIX_FMT_YUYV +#define SENSOR_INIT_PIXFMT V4L2_MBUS_FMT_YUYV8_2X8 #define CONFIG_SENSOR_WhiteBalance 0 #define CONFIG_SENSOR_Brightness 0 @@ -90,6 +90,10 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) struct reginfo { u8 reg; @@ -394,11 +398,13 @@ static struct reginfo sensor_qcif[] = static struct reginfo sensor_ClrFmt_YUYV[]= { + {0x00,0x00} }; static struct reginfo sensor_ClrFmt_UYVY[]= { + {0x00,0x00} }; @@ -787,6 +793,7 @@ static struct reginfo sensor_Effect_Negative[] = {0xb8,0x00}, }; +#if 0 static struct reginfo sensor_Effect_Bluish[] = { // Bluish -- aqua @@ -796,7 +803,7 @@ static struct reginfo sensor_Effect_Bluish[] = {0xb8,0x60}, }; - +#endif static struct reginfo sensor_Effect_Green[] = { // Greenish @@ -1167,8 +1174,12 @@ static int sensor_suspend(struct soc_camera_device *icd, pm_message_t pm_msg); static int sensor_resume(struct soc_camera_device *icd); static int sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags); static unsigned long sensor_query_bus_param(struct soc_camera_device *icd); +#if CONFIG_SENSOR_Effect static int sensor_set_effect(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif +#if CONFIG_SENSOR_WhiteBalance static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value); +#endif static int sensor_deactivate(struct i2c_client *client); static struct soc_camera_ops sensor_ops = @@ -1183,16 +1194,28 @@ static struct soc_camera_ops sensor_ops = .num_menus = ARRAY_SIZE(sensor_menus), }; -#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ - { .name = _name, .depth = _depth, .fourcc = _fourcc, \ - .colorspace = _colorspace } +/* only one fixed colorspace per pixelcode */ +struct sensor_datafmt { + enum v4l2_mbus_pixelcode code; + enum v4l2_colorspace colorspace; +}; -#define JPG_FMT(_name, _depth, _fourcc) \ - COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_JPEG) +/* Find a data format by a pixel code in an array */ +static const struct sensor_datafmt *sensor_find_datafmt( + enum v4l2_mbus_pixelcode code, const struct sensor_datafmt *fmt, + int n) +{ + int i; + for (i = 0; i < n; i++) + if (fmt[i].code == code) + return fmt + i; -static const struct soc_camera_data_format sensor_colour_formats[] = { - JPG_FMT(SENSOR_NAME_STRING(UYVY), 16, V4L2_PIX_FMT_UYVY), - JPG_FMT(SENSOR_NAME_STRING(YUYV), 16, V4L2_PIX_FMT_YUYV), + return NULL; +} + +static const struct sensor_datafmt sensor_colour_fmts[] = { + {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_JPEG}, + {V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG} }; typedef struct sensor_info_priv_s @@ -1212,7 +1235,8 @@ typedef struct sensor_info_priv_s unsigned char mirror; /* HFLIP */ unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; - unsigned int pixfmt; + struct sensor_datafmt fmt; + unsigned int funmodule_state; } sensor_info_priv_t; @@ -1440,6 +1464,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; + const struct sensor_datafmt *fmt; int ret, i; SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1460,7 +1485,7 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) // goto sensor_INIT_ERR; // } - mdelay(5); //delay 5 microseconds +// mdelay(5); //delay 5 microseconds for(i = 0; i < sizeof(sensor_init_data)/2;i++){ @@ -1477,11 +1502,15 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) // printk("read from reg[0x%x] 0x%x\n",sensor_init_data[i].reg,tmp); } sensor_task_lock(client,0); - - icd->user_width = SENSOR_INIT_WIDTH; - icd->user_height = SENSOR_INIT_HEIGHT; + sensor->info_priv.winseqe_cur_addr = (int)SENSOR_INIT_WINSEQADR; - sensor->info_priv.pixfmt = SENSOR_INIT_PIXFMT; + fmt = sensor_find_datafmt(SENSOR_INIT_PIXFMT,sensor_colour_fmts, ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + SENSOR_TR("error: %s initial array colour fmts is not support!!",SENSOR_NAME_STRING()); + ret = -EINVAL; + goto sensor_INIT_ERR; + } + sensor->info_priv.fmt = *fmt; /* sensor sensor information for initialization */ qctrl = soc_camera_find_qctrl(&sensor_ops, V4L2_CID_DO_WHITE_BALANCE); @@ -1531,9 +1560,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + sensor_task_lock(client,0); sensor_deactivate(client); return ret; } @@ -1541,6 +1572,7 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); @@ -1551,6 +1583,7 @@ static int sensor_deactivate(struct i2c_client *client) icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; return 0; } static struct reginfo sensor_power_down_sequence[]= @@ -1614,80 +1647,86 @@ static unsigned long sensor_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, flags); } -static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; - pix->width = icd->user_width; - pix->height = icd->user_height; - pix->pixelformat = sensor->info_priv.pixfmt; - pix->field = V4L2_FIELD_NONE; - pix->colorspace = V4L2_COLORSPACE_JPEG; + mf->width = icd->user_width; + mf->height = icd->user_height; + mf->code = sensor->info_priv.fmt.code; + mf->colorspace = sensor->info_priv.fmt.colorspace; + mf->field = V4L2_FIELD_NONE; return 0; } -static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_capturechk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1024) && (f->fmt.pix.height == 768)) { + if ((mf->width == 1024) && (mf->height == 768)) { ret = true; - } else if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 1024)) { + } else if ((mf->width == 1280) && (mf->height == 1024)) { ret = true; - } else if ((f->fmt.pix.width == 1600) && (f->fmt.pix.height == 1200)) { + } else if ((mf->width == 1600) && (mf->height == 1200)) { ret = true; - } else if ((f->fmt.pix.width == 2048) && (f->fmt.pix.height == 1536)) { + } else if ((mf->width == 2048) && (mf->height == 1536)) { ret = true; - } else if ((f->fmt.pix.width == 2592) && (f->fmt.pix.height == 1944)) { + } else if ((mf->width == 2592) && (mf->height == 1944)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is capture format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_format *f) +static bool sensor_fmt_videochk(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { bool ret = false; - if ((f->fmt.pix.width == 1280) && (f->fmt.pix.height == 720)) { + if ((mf->width == 1280) && (mf->height == 720)) { ret = true; - } else if ((f->fmt.pix.width == 1920) && (f->fmt.pix.height == 1080)) { + } else if ((mf->width == 1920) && (mf->height == 1080)) { ret = true; } if (ret == true) - SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, f->fmt.pix.width, f->fmt.pix.height); + SENSOR_DG("%s %dx%d is video format\n", __FUNCTION__, mf->width, mf->height); return ret; } -static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = sd->priv; struct sensor *sensor = to_sensor(client); - struct v4l2_pix_format *pix = &f->fmt.pix; + const struct sensor_datafmt *fmt; struct reginfo *winseqe_set_addr=NULL; char readval; int ret=0, set_w,set_h,i; - if (sensor->info_priv.pixfmt != pix->pixelformat) { - switch (pix->pixelformat) + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (!fmt) { + ret = -EINVAL; + goto sensor_s_fmt_end; + } + + if (sensor->info_priv.fmt.code != mf->code) { + switch (mf->code) { - case V4L2_PIX_FMT_YUYV: + case V4L2_MBUS_FMT_YUYV8_2X8: { - //winseqe_set_addr = sensor_ClrFmt_YUYV; + winseqe_set_addr = sensor_ClrFmt_YUYV; sensor_read(client, 0x3a, &readval); sensor_write(client,0x3a, readval&0xf7); sensor_read(client,0x3d,&readval); sensor_write(client,0x3d,readval&0xfe); break; } - case V4L2_PIX_FMT_UYVY: + case V4L2_MBUS_FMT_UYVY8_2X8: { - //winseqe_set_addr = sensor_ClrFmt_UYVY; + winseqe_set_addr = sensor_ClrFmt_UYVY; sensor_read(client, 0x3a, &readval); sensor_write(client,0x3a, readval|0x08); sensor_read(client,0x3d,&readval); @@ -1699,19 +1738,16 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) } if (winseqe_set_addr != NULL) { sensor_write_array(client, winseqe_set_addr); - sensor->info_priv.pixfmt = pix->pixelformat; - - SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + sensor->info_priv.fmt.code = mf->code; + sensor->info_priv.fmt.colorspace= mf->colorspace; + SENSOR_DG("%s v4l2_mbus_code:%d set success!\n", SENSOR_NAME_STRING(),mf->code); } else { - SENSOR_TR("%s Pixelformat(0x%x) is invalidate!\n", SENSOR_NAME_STRING(),pix->pixelformat); - // sensor->info_priv.pixfmt = pix->pixelformat; - - // SENSOR_DG("%s Pixelformat(0x%x) set success!\n", SENSOR_NAME_STRING(),pix->pixelformat); + SENSOR_TR("%s v4l2_mbus_code:%d is invalidate!\n", SENSOR_NAME_STRING(),mf->code); } } - set_w = pix->width; - set_h = pix->height; + set_w = mf->width; + set_h = mf->height; if (((set_w <= 176) && (set_h <= 144)) && sensor_qcif[0].reg) { @@ -1742,7 +1778,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) winseqe_set_addr = SENSOR_INIT_WINSEQADR; /* ddl@rock-chips.com : Sensor output smallest size if isn't support app */ set_w = SENSOR_INIT_WIDTH; set_h = SENSOR_INIT_HEIGHT; - SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,pix->width,pix->height); + SENSOR_TR("\n %s..%s Format is Invalidate. pix->width = %d.. pix->height = %d\n",SENSOR_NAME_STRING(),__FUNCTION__,mf->width,mf->height); } if ((int)winseqe_set_addr != sensor->info_priv.winseqe_cur_addr) @@ -1766,41 +1802,41 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h); } - pix->width = set_w; - pix->height = set_h; + mf->width = set_w; + mf->height = set_h; sensor_s_fmt_end: return ret; } -static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) +static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { - struct v4l2_pix_format *pix = &f->fmt.pix; - bool bayer = pix->pixelformat == V4L2_PIX_FMT_UYVY || - pix->pixelformat == V4L2_PIX_FMT_YUYV; - - /* - * With Bayer format enforce even side lengths, but let the user play - * with the starting pixel - */ - - if (pix->height > SENSOR_MAX_HEIGHT) - pix->height = SENSOR_MAX_HEIGHT; - else if (pix->height < SENSOR_MIN_HEIGHT) - pix->height = SENSOR_MIN_HEIGHT; - else if (bayer) - pix->height = ALIGN(pix->height, 2); - - if (pix->width > SENSOR_MAX_WIDTH) - pix->width = SENSOR_MAX_WIDTH; - else if (pix->width < SENSOR_MIN_WIDTH) - pix->width = SENSOR_MIN_WIDTH; - else if (bayer) - pix->width = ALIGN(pix->width, 2); - - return 0; + struct i2c_client *client = sd->priv; + struct sensor *sensor = to_sensor(client); + const struct sensor_datafmt *fmt; + int ret = 0; + + fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts, + ARRAY_SIZE(sensor_colour_fmts)); + if (fmt == NULL) { + fmt = &sensor->info_priv.fmt; + mf->code = fmt->code; + } + + if (mf->height > SENSOR_MAX_HEIGHT) + mf->height = SENSOR_MAX_HEIGHT; + else if (mf->height < SENSOR_MIN_HEIGHT) + mf->height = SENSOR_MIN_HEIGHT; + + if (mf->width > SENSOR_MAX_WIDTH) + mf->width = SENSOR_MAX_WIDTH; + else if (mf->width < SENSOR_MIN_WIDTH) + mf->width = SENSOR_MIN_WIDTH; + + mf->colorspace = fmt->colorspace; + + return ret; } - static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { struct i2c_client *client = sd->priv; @@ -2028,7 +2064,7 @@ static int sensor_set_whiteBalance(struct soc_camera_device *icd, const struct v } #endif #if CONFIG_SENSOR_DigitalZoom -static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int *value) +static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) { struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct sensor *sensor = to_sensor(client); @@ -2042,29 +2078,29 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 digitalzoom_cur = sensor->info_priv.digitalzoom; digitalzoom_total = qctrl_info->maximum; - if ((*value > 0) && (digitalzoom_cur >= digitalzoom_total)) + if ((value > 0) && (digitalzoom_cur >= digitalzoom_total)) { SENSOR_TR("%s digitalzoom is maximum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) + if ((value < 0) && (digitalzoom_cur <= qctrl_info->minimum)) { SENSOR_TR("%s digitalzoom is minimum - %x\n", SENSOR_NAME_STRING(), digitalzoom_cur); return -EINVAL; } - if ((*value > 0) && ((digitalzoom_cur + *value) > digitalzoom_total)) + if ((value > 0) && ((digitalzoom_cur + value) > digitalzoom_total)) { - *value = digitalzoom_total - digitalzoom_cur; + value = digitalzoom_total - digitalzoom_cur; } - if ((*value < 0) && ((digitalzoom_cur + *value) < 0)) + if ((value < 0) && ((digitalzoom_cur + value) < 0)) { - *value = 0 - digitalzoom_cur; + value = 0 - digitalzoom_cur; } - digitalzoom_cur += *value; + digitalzoom_cur += value; if (sensor_ZoomSeqe[digitalzoom_cur] != NULL) { @@ -2073,7 +2109,7 @@ static int sensor_set_digitalzoom(struct soc_camera_device *icd, const struct v4 SENSOR_TR("%s..%s WriteReg Fail.. \n",SENSOR_NAME_STRING(), __FUNCTION__); return -EINVAL; } - SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, *value); + SENSOR_DG("%s..%s : %x\n",SENSOR_NAME_STRING(),__FUNCTION__, value); return 0; } @@ -2543,9 +2579,6 @@ static int sensor_video_probe(struct soc_camera_device *icd, goto sensor_video_probe_err; } - icd->formats = sensor_colour_formats; - icd->num_formats = ARRAY_SIZE(sensor_colour_formats); - return 0; sensor_video_probe_err: @@ -2615,6 +2648,15 @@ sensor_ioctl_end: return ret; } +static int sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code) +{ + if (index >= ARRAY_SIZE(sensor_colour_fmts)) + return -EINVAL; + + *code = sensor_colour_fmts[index].code; + return 0; +} static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { .init = sensor_init, .g_ctrl = sensor_g_control, @@ -2626,9 +2668,10 @@ static struct v4l2_subdev_core_ops sensor_subdev_core_ops = { }; static struct v4l2_subdev_video_ops sensor_subdev_video_ops = { - .s_fmt = sensor_s_fmt, - .g_fmt = sensor_g_fmt, - .try_fmt = sensor_try_fmt, + .s_mbus_fmt = sensor_s_fmt, + .g_mbus_fmt = sensor_g_fmt, + .try_mbus_fmt = sensor_try_fmt, + .enum_mbus_fmt = sensor_enum_fmt, }; static struct v4l2_subdev_ops sensor_subdev_ops = { @@ -2671,7 +2714,7 @@ static int sensor_probe(struct i2c_client *client, /* Second stage probe - when a capture adapter is there */ icd->ops = &sensor_ops; - icd->y_skip_top = 0; + sensor->info_priv.fmt = sensor_colour_fmts[0]; #if CONFIG_SENSOR_I2C_NOSCHED atomic_set(&sensor->tasklock_cnt,0); #endif