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)
if (ret)
goto out_unlock;
/* restore settings */
gc0310_res = gc0310_res_preview;
N_RES = N_RES_PREVIEW;
/* restore value of all ctrls */
ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
......@@ -296,76 +292,50 @@ static int gc0310_s_power(struct v4l2_subdev *sd, int on)
return gc0310_init(sd);
}
/* TODO: remove it. */
static int startup(struct v4l2_subdev *sd)
static struct v4l2_mbus_framefmt *
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);
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = 0;
if (which == V4L2_SUBDEV_FORMAT_TRY)
return v4l2_subdev_get_try_format(&dev->sd, state, pad);
ret = gc0310_write_reg_array(client, dev->res->regs, dev->res->reg_count);
if (ret) {
dev_err(&client->dev, "gc0310 write register err.\n");
return ret;
}
return &dev->mode.fmt;
}
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,
struct v4l2_subdev_state *sd_state,
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 camera_mipi_info *gc0310_info = NULL;
struct gc0310_resolution *res;
int ret = 0;
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);
struct gc0310_device *dev = to_gc0310_sensor(sd);
struct v4l2_mbus_framefmt *fmt;
int ret;
res = v4l2_find_nearest_size(gc0310_res_preview,
ARRAY_SIZE(gc0310_res_preview), width,
height, fmt->width, fmt->height);
if (!res)
res = &gc0310_res_preview[N_RES - 1];
fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
gc0310_fill_format(fmt);
fmt->width = res->width;
fmt->height = res->height;
dev->res = res;
format->format = *fmt;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
sd_state->pads->try_fmt = *fmt;
mutex_unlock(&dev->input_lock);
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
return 0;
}
mutex_lock(&dev->input_lock);
/* s_power has not been called yet for std v4l2 clients (camorama) */
power_up(sd);
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:
ret = gc0310_write_reg_array(client, gc0310_VGA_30fps, ARRAY_SIZE(gc0310_VGA_30fps));
mutex_unlock(&dev->input_lock);
return ret;
}
......@@ -373,19 +343,11 @@ static int gc0310_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{
struct v4l2_mbus_framefmt *fmt = &format->format;
struct gc0310_device *dev = to_gc0310_sensor(sd);
struct v4l2_mbus_framefmt *fmt;
if (format->pad)
return -EINVAL;
if (!fmt)
return -EINVAL;
fmt->width = dev->res->width;
fmt->height = dev->res->height;
fmt->code = MEDIA_BUS_FMT_SGRBG8_1X8;
fmt = gc0310_get_pad_format(dev, sd_state, format->pad, format->which);
format->format = *fmt;
return 0;
}
......@@ -518,10 +480,8 @@ static int gc0310_s_config(struct v4l2_subdev *sd,
static int gc0310_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *interval)
{
struct gc0310_device *dev = to_gc0310_sensor(sd);
interval->interval.numerator = 1;
interval->interval.denominator = dev->res->fps;
interval->interval.denominator = GC0310_FPS;
return 0;
}
......@@ -530,7 +490,8 @@ static int gc0310_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
if (code->index >= MAX_FMTS)
/* We support only a single format */
if (code->index)
return -EINVAL;
code->code = MEDIA_BUS_FMT_SGRBG8_1X8;
......@@ -541,27 +502,21 @@ static int gc0310_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{
int index = fse->index;
if (index >= N_RES)
/* We support only a single resolution */
if (fse->index)
return -EINVAL;
fse->min_width = gc0310_res[index].width;
fse->min_height = gc0310_res[index].height;
fse->max_width = gc0310_res[index].width;
fse->max_height = gc0310_res[index].height;
fse->min_width = GC0310_NATIVE_WIDTH;
fse->max_width = GC0310_NATIVE_WIDTH;
fse->min_height = GC0310_NATIVE_HEIGHT;
fse->max_height = GC0310_NATIVE_HEIGHT;
return 0;
}
static int gc0310_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
{
struct gc0310_device *dev = to_gc0310_sensor(sd);
mutex_lock(&dev->input_lock);
*frames = dev->res->skip_frames;
mutex_unlock(&dev->input_lock);
*frames = GC0310_SKIP_FRAMES;
return 0;
}
......@@ -638,9 +593,8 @@ static int gc0310_probe(struct i2c_client *client)
return -ENOMEM;
mutex_init(&dev->input_lock);
dev->res = &gc0310_res_preview[0];
v4l2_i2c_subdev_init(&dev->sd, client, &gc0310_ops);
gc0310_fill_format(&dev->mode.fmt);
pdata = gmin_camera_platform_data(&dev->sd,
ATOMISP_INPUT_FORMAT_RAW_8,
......@@ -660,7 +614,6 @@ static int gc0310_probe(struct i2c_client *client)
dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
dev->pad.flags = MEDIA_PAD_FL_SOURCE;
dev->format.code = MEDIA_BUS_FMT_SGRBG8_1X8;
dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = gc0310_init_controls(dev);
......
......@@ -33,30 +33,14 @@
#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
/*
* 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
#define GC0310_FOCAL_LENGTH_NUM 278 /* 2.78mm */
/*
* 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_RESET_RELATED 0xFE
......@@ -101,37 +85,21 @@
#define GC0310_START_STREAMING 0x94 /* 8-bit enable */
#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.
*/
struct gc0310_device {
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_mbus_framefmt format;
struct mutex input_lock;
struct camera_sensor_platform_data *platform_data;
struct gc0310_resolution *res;
u8 type;
bool power_on;
struct gc0310_mode {
struct v4l2_mbus_framefmt fmt;
} mode;
struct gc0310_ctrls {
struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *exposure;
......@@ -337,26 +305,4 @@ static struct gc0310_reg const gc0310_VGA_30fps[] = {
{ 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
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