Commit 9783b96a authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

media: atomisp: gc0310: Modernize and simply set_fmt(), get_fmt(), etc.

There only is 1 supported resolution allowing significant simplification
of the code; and also bring the code up2date with current subdev fmt
handling practices.
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 2b2297b1
...@@ -132,10 +132,6 @@ static int gc0310_init(struct v4l2_subdev *sd) ...@@ -132,10 +132,6 @@ static int gc0310_init(struct v4l2_subdev *sd)
if (ret) if (ret)
goto out_unlock; goto out_unlock;
/* restore settings */
gc0310_res = gc0310_res_preview;
N_RES = N_RES_PREVIEW;
/* restore value of all ctrls */ /* restore value of all ctrls */
ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler); ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
...@@ -296,76 +292,50 @@ static int gc0310_s_power(struct v4l2_subdev *sd, int on) ...@@ -296,76 +292,50 @@ static int gc0310_s_power(struct v4l2_subdev *sd, int on)
return gc0310_init(sd); return gc0310_init(sd);
} }
/* TODO: remove it. */ static struct v4l2_mbus_framefmt *
static int startup(struct v4l2_subdev *sd) gc0310_get_pad_format(struct gc0310_device *dev,
struct v4l2_subdev_state *state,
unsigned int pad, enum v4l2_subdev_format_whence which)
{ {
struct gc0310_device *dev = to_gc0310_sensor(sd); if (which == V4L2_SUBDEV_FORMAT_TRY)
struct i2c_client *client = v4l2_get_subdevdata(sd); return v4l2_subdev_get_try_format(&dev->sd, state, pad);
int ret = 0;
ret = gc0310_write_reg_array(client, dev->res->regs, dev->res->reg_count); return &dev->mode.fmt;
if (ret) { }
dev_err(&client->dev, "gc0310 write register err.\n");
return ret;
}
return ret; /* The GC0310 currently only supports 1 fixed fmt */
static void gc0310_fill_format(struct v4l2_mbus_framefmt *fmt)
{
memset(fmt, 0, sizeof(*fmt));
fmt->width = GC0310_NATIVE_WIDTH;
fmt->height = GC0310_NATIVE_HEIGHT;
fmt->field = V4L2_FIELD_NONE;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
} }
static int gc0310_set_fmt(struct v4l2_subdev *sd, static int gc0310_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format) struct v4l2_subdev_format *format)
{ {
struct v4l2_mbus_framefmt *fmt = &format->format;
struct gc0310_device *dev = to_gc0310_sensor(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct camera_mipi_info *gc0310_info = NULL; struct gc0310_device *dev = to_gc0310_sensor(sd);
struct gc0310_resolution *res; struct v4l2_mbus_framefmt *fmt;
int ret = 0; int ret;
if (format->pad)
return -EINVAL;
if (!fmt)
return -EINVAL;
gc0310_info = v4l2_get_subdev_hostdata(sd);
if (!gc0310_info)
return -EINVAL;
mutex_lock(&dev->input_lock);
res = v4l2_find_nearest_size(gc0310_res_preview, fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
ARRAY_SIZE(gc0310_res_preview), width, gc0310_fill_format(fmt);
height, fmt->width, fmt->height);
if (!res)
res = &gc0310_res_preview[N_RES - 1];
fmt->width = res->width; format->format = *fmt;
fmt->height = res->height;
dev->res = res;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8; if (format->which == V4L2_SUBDEV_FORMAT_TRY)
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
mutex_unlock(&dev->input_lock);
return 0; return 0;
}
mutex_lock(&dev->input_lock);
/* s_power has not been called yet for std v4l2 clients (camorama) */ /* s_power has not been called yet for std v4l2 clients (camorama) */
power_up(sd); power_up(sd);
ret = gc0310_write_reg_array(client, gc0310_VGA_30fps, ARRAY_SIZE(gc0310_VGA_30fps));
dev_dbg(&client->dev, "%s: before gc0310_write_reg_array %s\n",
__func__, dev->res->desc);
ret = startup(sd);
if (ret) {
dev_err(&client->dev, "gc0310 startup err\n");
goto err;
}
err:
mutex_unlock(&dev->input_lock); mutex_unlock(&dev->input_lock);
return ret; return ret;
} }
...@@ -373,19 +343,11 @@ static int gc0310_get_fmt(struct v4l2_subdev *sd, ...@@ -373,19 +343,11 @@ static int gc0310_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format) struct v4l2_subdev_format *format)
{ {
struct v4l2_mbus_framefmt *fmt = &format->format;
struct gc0310_device *dev = to_gc0310_sensor(sd); struct gc0310_device *dev = to_gc0310_sensor(sd);
struct v4l2_mbus_framefmt *fmt;
if (format->pad) fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
return -EINVAL; format->format = *fmt;
if (!fmt)
return -EINVAL;
fmt->width = dev->res->width;
fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
return 0; return 0;
} }
...@@ -518,10 +480,8 @@ static int gc0310_s_config(struct v4l2_subdev *sd, ...@@ -518,10 +480,8 @@ static int gc0310_s_config(struct v4l2_subdev *sd,
static int gc0310_g_frame_interval(struct v4l2_subdev *sd, static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval) struct v4l2_subdev_frame_interval *interval)
{ {
struct gc0310_device *dev = to_gc0310_sensor(sd);
interval->interval.numerator = 1; interval->interval.numerator = 1;
interval->interval.denominator = dev->res->fps; interval->interval.denominator = GC0310_FPS;
return 0; return 0;
} }
...@@ -530,7 +490,8 @@ static int gc0310_enum_mbus_code(struct v4l2_subdev *sd, ...@@ -530,7 +490,8 @@ static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code) struct v4l2_subdev_mbus_code_enum *code)
{ {
if (code->index >= MAX_FMTS) /* We support only a single format */
if (code->index)
return -EINVAL; return -EINVAL;
code->code = MEDIA_BUS_FMT_SGRBG8_1X8; code->code = MEDIA_BUS_FMT_SGRBG8_1X8;
...@@ -541,27 +502,21 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd, ...@@ -541,27 +502,21 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state, struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse) struct v4l2_subdev_frame_size_enum *fse)
{ {
int index = fse->index; /* We support only a single resolution */
if (fse->index)
if (index >= N_RES)
return -EINVAL; return -EINVAL;
fse->min_width = gc0310_res[index].width; fse->min_width = GC0310_NATIVE_WIDTH;
fse->min_height = gc0310_res[index].height; fse->max_width = GC0310_NATIVE_WIDTH;
fse->max_width = gc0310_res[index].width; fse->min_height = GC0310_NATIVE_HEIGHT;
fse->max_height = gc0310_res[index].height; fse->max_height = GC0310_NATIVE_HEIGHT;
return 0; return 0;
} }
static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
{ {
struct gc0310_device *dev = to_gc0310_sensor(sd); *frames = GC0310_SKIP_FRAMES;
mutex_lock(&dev->input_lock);
*frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
return 0; return 0;
} }
...@@ -638,9 +593,8 @@ static int gc0310_probe(struct i2c_client *client) ...@@ -638,9 +593,8 @@ static int gc0310_probe(struct i2c_client *client)
return -ENOMEM; return -ENOMEM;
mutex_init(&dev->input_lock); mutex_init(&dev->input_lock);
dev->res = &gc0310_res_preview[0];
v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops); v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
gc0310_fill_format(&dev->mode.fmt);
pdata = gmin_camera_platform_data(&dev->sd, pdata = gmin_camera_platform_data(&dev->sd,
ATOMISP_INPUT_FORMAT_RAW_8, ATOMISP_INPUT_FORMAT_RAW_8,
...@@ -660,7 +614,6 @@ static int gc0310_probe(struct i2c_client *client) ...@@ -660,7 +614,6 @@ static int gc0310_probe(struct i2c_client *client)
dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
dev->pad.flags = MEDIA_PAD_FL_SOURCE; dev->pad.flags = MEDIA_PAD_FL_SOURCE;
dev->format.code = MEDIA_BUS_FMT_SGRBG8_1X8;
dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = gc0310_init_controls(dev); ret = gc0310_init_controls(dev);
......
...@@ -33,30 +33,14 @@ ...@@ -33,30 +33,14 @@
#include "../include/linux/atomisp_platform.h" #include "../include/linux/atomisp_platform.h"
#define GC0310_FOCAL_LENGTH_NUM 278 /*2.78mm*/ #define GC0310_NATIVE_WIDTH 656
#define GC0310_NATIVE_HEIGHT 496
#define MAX_FMTS 1 #define GC0310_FPS 30
#define GC0310_SKIP_FRAMES 3
/* #define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */
* focal length bits definition:
* bits 31-16: numerator, bits 15-0: denominator
*/
#define GC0310_FOCAL_LENGTH_DEFAULT 0x1160064
/*
* current f-number bits definition:
* bits 31-16: numerator, bits 15-0: denominator
*/
#define GC0310_F_NUMBER_DEFAULT 0x1a000a
/*
* f-number range bits definition:
* bits 31-24: max f-number numerator
* bits 23-16: max f-number denominator
* bits 15-8: min f-number numerator
* bits 7-0: min f-number denominator
*/
#define GC0310_F_NUMBER_RANGE 0x1a0a1a0a
#define GC0310_ID 0xa310 #define GC0310_ID 0xa310
#define GC0310_RESET_RELATED 0xFE #define GC0310_RESET_RELATED 0xFE
...@@ -101,37 +85,21 @@ ...@@ -101,37 +85,21 @@
#define GC0310_START_STREAMING 0x94 /* 8-bit enable */ #define GC0310_START_STREAMING 0x94 /* 8-bit enable */
#define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */ #define GC0310_STOP_STREAMING 0x0 /* 8-bit disable */
#define GC0310_BIN_FACTOR_MAX 3
struct gc0310_resolution {
u8 *desc;
const struct gc0310_reg *regs;
int reg_count;
int res;
int width;
int height;
int fps;
int pix_clk_freq;
u32 skip_frames;
u16 pixels_per_line;
u16 lines_per_frame;
bool used;
};
/* /*
* gc0310 device structure. * gc0310 device structure.
*/ */
struct gc0310_device { struct gc0310_device {
struct v4l2_subdev sd; struct v4l2_subdev sd;
struct media_pad pad; struct media_pad pad;
struct v4l2_mbus_framefmt format;
struct mutex input_lock; struct mutex input_lock;
struct camera_sensor_platform_data *platform_data; struct camera_sensor_platform_data *platform_data;
struct gc0310_resolution *res;
u8 type;
bool power_on; bool power_on;
struct gc0310_mode {
struct v4l2_mbus_framefmt fmt;
} mode;
struct gc0310_ctrls { struct gc0310_ctrls {
struct v4l2_ctrl_handler handler; struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *exposure; struct v4l2_ctrl *exposure;
...@@ -337,26 +305,4 @@ static struct gc0310_reg const gc0310_VGA_30fps[] = { ...@@ -337,26 +305,4 @@ static struct gc0310_reg const gc0310_VGA_30fps[] = {
{ 0xfe, 0x00 }, { 0xfe, 0x00 },
}; };
static struct gc0310_resolution gc0310_res_preview[] = {
{
.desc = "gc0310_VGA_30fps",
.width = 656, // 648,
.height = 496, // 488,
.fps = 30,
//.pix_clk_freq = 73,
.used = 0,
#if 0
.pixels_per_line = 0x0314,
.lines_per_frame = 0x0213,
#endif
.skip_frames = 2,
.regs = gc0310_VGA_30fps,
.reg_count = ARRAY_SIZE(gc0310_VGA_30fps),
},
};
#define N_RES_PREVIEW (ARRAY_SIZE(gc0310_res_preview))
static struct gc0310_resolution *gc0310_res = gc0310_res_preview;
static unsigned long N_RES = N_RES_PREVIEW;
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment