From: lw@rock-chips.com Date: Thu, 15 Dec 2011 03:05:07 +0000 (+0800) Subject: A22:modify camera driver according to android4.0 X-Git-Tag: firefly_0821_release~9710^2~17 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=df99b47217b7d49a20ea03cba38faa7c784babde;p=firefly-linux-kernel-4.4.55.git A22:modify camera driver according to android4.0 --- diff --git a/arch/arm/mach-rk29/board-rk29-a22.c b/arch/arm/mach-rk29/board-rk29-a22.c index cd29b7d38624..0accc992cf11 100755 --- a/arch/arm/mach-rk29/board-rk29-a22.c +++ b/arch/arm/mach-rk29/board-rk29-a22.c @@ -97,6 +97,13 @@ #define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_0 RK29_CAM_POWERDNACTIVE_H #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_0 RK29_CAM_FLASHACTIVE_H +#define CONFIG_SENSOR_QCIF_FPS_FIXED_0 8 +#define CONFIG_SENSOR_QVGA_FPS_FIXED_0 8 +#define CONFIG_SENSOR_CIF_FPS_FIXED_0 8 +#define CONFIG_SENSOR_VGA_FPS_FIXED_0 8 +#define CONFIG_SENSOR_480P_FPS_FIXED_0 8 +#define CONFIG_SENSOR_SVGA_FPS_FIXED_0 8 +#define CONFIG_SENSOR_720P_FPS_FIXED_0 8 #define CONFIG_SENSOR_1 RK29_CAM_SENSOR_GC0309 /* front camera sensor */ #define CONFIG_SENSOR_IIC_ADDR_1 0x42 #define CONFIG_SENSOR_IIC_ADAPTER_ID_1 1 @@ -109,6 +116,13 @@ #define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L #define CONFIG_SENSOR_POWERDNACTIVE_LEVEL_1 RK29_CAM_POWERDNACTIVE_H #define CONFIG_SENSOR_FLASHACTIVE_LEVEL_1 RK29_CAM_FLASHACTIVE_L +#define CONFIG_SENSOR_QCIF_FPS_FIXED_1 18 +#define CONFIG_SENSOR_QVGA_FPS_FIXED_1 18 +#define CONFIG_SENSOR_CIF_FPS_FIXED_1 18 +#define CONFIG_SENSOR_VGA_FPS_FIXED_1 18 +#define CONFIG_SENSOR_480P_FPS_FIXED_1 18 +#define CONFIG_SENSOR_SVGA_FPS_FIXED_1 18 +#define CONFIG_SENSOR_720P_FPS_FIXED_1 18 /*---------------- Camera Sensor Configuration End------------------------*/ #include "../../../drivers/media/video/rk29_camera.c" #endif diff --git a/drivers/media/video/mt9t111.c b/drivers/media/video/mt9t111.c index 2f590d8dd4ae..63cfb5fb4378 100755 --- a/drivers/media/video/mt9t111.c +++ b/drivers/media/video/mt9t111.c @@ -58,7 +58,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 @@ -6165,17 +6165,31 @@ 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 { sensor_work_ready = 0, @@ -6211,7 +6225,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; @@ -6680,10 +6694,11 @@ sensor_power_end: } static int sensor_init(struct v4l2_subdev *sd, u32 val) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); 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,pid = 0; #if (SENSOR_RESET_REG != SEQUENCE_END) struct reginfo reg_info; @@ -6744,8 +6759,14 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) sensor->info_priv.preview_h = SENSOR_INIT_HEIGHT; 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; + sensor->info_priv.winseqe_cur_addr = 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); if (qctrl) @@ -6896,54 +6917,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 i2c_client *client = v4l2_get_subdevdata(sd); 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 ((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) @@ -7170,25 +7190,32 @@ 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 i2c_client *client = v4l2_get_subdevdata(sd); + 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; struct reginfo *winseqe_set_addr=NULL; int ret = 0, set_w,set_h; //u16 seq_state=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; @@ -7198,16 +7225,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); @@ -7220,11 +7247,12 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor->info_priv.winseqe_cur_addr = winseqe_set_addr; if ((winseqe_set_addr[0].reg==SEQUENCE_PROPERTY) && (winseqe_set_addr[0].val==SEQUENCE_CAPTURE)) { - } else { - sensor->info_priv.preview_w = pix->width; - sensor->info_priv.preview_h = pix->height; + + } else { + sensor->info_priv.preview_w = mf->width; + sensor->info_priv.preview_h = mf->height; } - } + } if (winseqe_set_addr && (winseqe_set_addr[0].reg==SEQUENCE_PROPERTY) && (winseqe_set_addr[0].val==SEQUENCE_CAPTURE)) { @@ -7255,7 +7283,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))) { #if CONFIG_SENSOR_Flash if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) { sensor_ioctrl(icd, Sensor_Flash, Flash_Off); @@ -7276,48 +7304,47 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) sensor_ioctrl(icd, Sensor_Flash, Flash_Off); } #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. mf->width = %d.. mf->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 - */ + struct i2c_client *client = v4l2_get_subdevdata(sd); + 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 (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; + 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; + if (sensor_fmt_catch(mf->width, mf->height, &mf->width, &mf->height) == NULL) { + mf->width = 0; + mf->height = 0; } return ret; @@ -7325,7 +7352,7 @@ static int sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f) static int sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) return -EINVAL; @@ -7717,7 +7744,7 @@ static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l #endif static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); const struct v4l2_queryctrl *qctrl; SENSOR_DG("\n%s..%s.. \n",__FUNCTION__,SENSOR_NAME_STRING()); @@ -7777,7 +7804,7 @@ static int sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); struct soc_camera_device *icd = client->dev.platform_data; const struct v4l2_queryctrl *qctrl; @@ -8093,7 +8120,7 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; int i, error_cnt=0, error_idx=-1; @@ -8120,7 +8147,7 @@ static int sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; int i, error_cnt=0, error_idx=-1; @@ -8144,7 +8171,7 @@ static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control static int sensor_s_stream(struct v4l2_subdev *sd, int enable) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct sensor *sensor = to_sensor(client); if (enable == 1) { @@ -8211,9 +8238,8 @@ 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: @@ -8222,7 +8248,7 @@ sensor_video_probe_err: } static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { - struct i2c_client *client = sd->priv; + struct i2c_client *client = v4l2_get_subdevdata(sd); struct soc_camera_device *icd = client->dev.platform_data; struct sensor *sensor = to_sensor(client); int ret = 0; @@ -8280,7 +8306,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, @@ -8290,11 +8324,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, .s_stream = sensor_s_stream, }; @@ -8338,7 +8372,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