aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel <pavel@ucw.cz>2018-10-28 15:52:09 +0100
committerPavel <pavel@ucw.cz>2019-01-07 11:23:40 +0100
commit69b1dc946d3f760f700af7b3e3552bf4afd036d5 (patch)
tree8cc5db77f5568819ba58f9e21efe208977042b0f
parentf92729ff3e9e44a5fb158cb156a16ee608cafb27 (diff)
downloadlinux-k-69b1dc946d3f760f700af7b3e3552bf4afd036d5.tar.gz
n900: camera -- attempt to understand et8ek8 modes. Not too
successful.
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_driver.c255
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_mode.c114
-rw-r--r--drivers/media/i2c/et8ek8/et8ek8_reg.h18
3 files changed, 352 insertions, 35 deletions
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index 37ef38947e018..72e89ac5561f4 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -58,6 +58,8 @@ struct et8ek8_sensor {
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *exposure_abs;
+ u32 cur_exposure;
struct v4l2_ctrl *pixel_rate;
struct et8ek8_reglist *current_reglist;
@@ -355,13 +357,14 @@ static int et8ek8_i2c_write_reg(struct i2c_client *client, u16 data_length,
et8ek8_i2c_create_msg(client, data_length, reg, val, &msg, data);
r = i2c_transfer(client->adapter, &msg, 1);
- if (r < 0) {
+
+ if (r < 0)
dev_err(&client->dev,
"wrote 0x%x to offset 0x%x error %d\n", val, reg, r);
- return r;
- }
+ else
+ r = 0; /* on success i2c_transfer() returns messages trasfered */
- return 0;
+ return r;
}
static struct et8ek8_reglist *et8ek8_reglist_find_type(
@@ -554,6 +557,65 @@ static int et8ek8_reglist_import(struct i2c_client *client,
return 0;
}
+typedef unsigned int fixpoint8; /* .8 fixed point format. */
+
+/*
+ * Return time of one row in microseconds
+ * If the sensor is not set to any mode, return zero.
+ */
+fixpoint8 et8ek8_get_row_time(struct et8ek8_sensor *sensor)
+{
+ unsigned int clock; /* Pixel clock in Hz>>10 fixed point */
+ fixpoint8 rt; /* Row time in .8 fixed point */
+
+ if (!sensor->current_reglist)
+ return 0;
+
+ clock = sensor->current_reglist->mode.pixel_clock;
+ clock = (clock + (1 << 9)) >> 10;
+ rt = sensor->current_reglist->mode.width * (1000000 >> 2);
+ rt = (rt + (clock >> 1)) / clock;
+
+ return rt;
+}
+
+/*
+ * Convert exposure time `us' to rows. Modify `us' to make it to
+ * correspond to the actual exposure time.
+ */
+static int et8ek8_exposure_us_to_rows(struct et8ek8_sensor *sensor, u32 *us)
+{
+ unsigned int rows; /* Exposure value as written to HW (ie. rows) */
+ fixpoint8 rt; /* Row time in .8 fixed point */
+
+ /* Assume that the maximum exposure time is at most ~8 s,
+ * and the maximum width (with blanking) ~8000 pixels.
+ * The formula here is in principle as simple as
+ * rows = exptime / 1e6 / width * pixel_clock
+ * but to get accurate results while coping with value ranges,
+ * have to do some fixed point math.
+ */
+
+ rt = et8ek8_get_row_time(sensor);
+ rows = ((*us << 8) + (rt >> 1)) / rt;
+
+ if (rows > sensor->current_reglist->mode.max_exp)
+ rows = sensor->current_reglist->mode.max_exp;
+
+ /* Set the exposure time to the rounded value */
+ *us = (rt * rows + (1 << 7)) >> 8;
+
+ return rows;
+}
+
+/*
+ * Convert exposure time in rows to microseconds
+ */
+static int et8ek8_exposure_rows_to_us(struct et8ek8_sensor *sensor, int rows)
+{
+ return (et8ek8_get_row_time(sensor) * rows + (1 << 7)) >> 8;
+}
+
/* Called to change the V4L2 gain control value. This function
* rounds and clamps the given value and updates the V4L2 control value.
* If power is on, also updates the sensor analog and digital gains.
@@ -645,18 +707,24 @@ static int et8ek8_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct et8ek8_sensor *sensor =
container_of(ctrl->handler, struct et8ek8_sensor, ctrl_handler);
+ u32 val = ctrl->val;
switch (ctrl->id) {
case V4L2_CID_GAIN:
return et8ek8_set_gain(sensor, ctrl->val);
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
+ printk("Set Absolute exposure %d\n", val);
+ val = et8ek8_exposure_us_to_rows(sensor, &val);
+ /* Fall through */
+
case V4L2_CID_EXPOSURE:
{
- struct i2c_client *client =
- v4l2_get_subdevdata(&sensor->subdev);
-
+ struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
+ sensor->cur_exposure = val;
+ printk("Set exposure %d\n", val);
return et8ek8_i2c_write_reg(client, ET8EK8_REG_16BIT, 0x1243,
- ctrl->val);
+ val);
}
case V4L2_CID_TEST_PATTERN:
@@ -670,8 +738,32 @@ static int et8ek8_set_ctrl(struct v4l2_ctrl *ctrl)
}
}
+static int et8ek8_get_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct et8ek8_sensor *sensor =
+ container_of(ctrl->handler, struct et8ek8_sensor, ctrl_handler);
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
+ ctrl->val = et8ek8_exposure_rows_to_us(sensor, sensor->cur_exposure);
+ printk("Get absolute exposure %d\n", ctrl->val);
+ return 0;
+
+ case V4L2_CID_EXPOSURE:
+ ctrl->val = sensor->cur_exposure;
+ printk("Get exposure %d\n", ctrl->val);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+
static const struct v4l2_ctrl_ops et8ek8_ctrl_ops = {
.s_ctrl = et8ek8_set_ctrl,
+ .g_volatile_ctrl = et8ek8_get_ctrl,
+
};
static const char * const et8ek8_test_pattern_menu[] = {
@@ -702,9 +794,17 @@ static int et8ek8_init_controls(struct et8ek8_sensor *sensor)
u32 min = 1, max = max_rows;
sensor->exposure =
- v4l2_ctrl_new_std(&sensor->ctrl_handler,
- &et8ek8_ctrl_ops, V4L2_CID_EXPOSURE,
- min, max, min, max);
+ v4l2_ctrl_new_std(&sensor->ctrl_handler, &et8ek8_ctrl_ops,
+ V4L2_CID_EXPOSURE, min, max, min, max);
+ //sensor->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ min = et8ek8_exposure_rows_to_us(sensor, 1);
+ max = et8ek8_exposure_rows_to_us(sensor, max);
+
+ sensor->exposure_abs =
+ v4l2_ctrl_new_std(&sensor->ctrl_handler, &et8ek8_ctrl_ops,
+ V4L2_CID_EXPOSURE_ABSOLUTE, min, max, min, max);
+ //sensor->exposure_abs->flags |= V4L2_CTRL_FLAG_VOLATILE;
}
/* V4L2_CID_PIXEL_RATE */
@@ -734,7 +834,10 @@ static void et8ek8_update_controls(struct et8ek8_sensor *sensor)
u32 min, max, pixel_rate;
static const int S = 8;
+ printk("Updating controls for %d x %d @ %d mode -- %s\n", mode->width, mode->height, mode->pixel_clock, mode->name);
+
ctrl = sensor->exposure;
+ printk("Updating controls for %d x %d @ %d mode -- %s\n", mode->width, mode->height, mode->pixel_clock, mode->name);
min = 1;
max = mode->max_exp;
@@ -746,11 +849,137 @@ static void et8ek8_update_controls(struct et8ek8_sensor *sensor)
*/
pixel_rate = ((mode->pixel_clock + (1 << S) - 1) >> S) + mode->width;
pixel_rate = mode->window_width * (pixel_rate - 1) / mode->width;
+ __v4l2_ctrl_modify_range(sensor->exposure, min, max, min, max);
- __v4l2_ctrl_modify_range(ctrl, min, max, min, max);
+ min = et8ek8_exposure_rows_to_us(sensor, 1);
+ max = et8ek8_exposure_rows_to_us(sensor, max);
+ __v4l2_ctrl_modify_range(sensor->exposure_abs, min, max, min, max);
+
__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate, pixel_rate << S);
}
+static int read_8(struct i2c_client *client, unsigned long addr)
+{
+ int val;
+ et8ek8_i2c_read_reg(client, ET8EK8_REG_8BIT, addr, &val);
+ return val;
+}
+
+static int read_16(struct i2c_client *client, unsigned long addr)
+{
+ return read_8(client, addr);
+}
+
+static void assert_value(struct i2c_client *client, unsigned long addr, unsigned long val)
+{
+ unsigned long val2 = read_8(client, addr);
+ if (val != val2)
+ printk("et8ek8: assertion check %lx / should be %lx is %lx\n", addr, val, val2);
+}
+
+static void assert(struct i2c_client *client, int v, char *msg)
+{
+ if (!v)
+ printk("et8ek8: assertion: %s\n", msg);
+}
+
+static void assert_eq(struct i2c_client *client, int v1, int v2, char *msg)
+{
+ if (v1 != v2)
+ printk("et8ek8: assertion: %d == %d %s\n", v1, v2, msg);
+}
+
+static void et8ek8_check(struct et8ek8_sensor *sensor)
+{
+ /*
+ 1239 4F # CKVAR_DIV
+ 1238 02 # CKVAR_DIV[8] CKREF_DIV
+ 123B 70 # MRCK_DIV LVDSCK_DIV
+ 123A 05 # VCO_DIV SPCK_DIV
+ 121B 63 # PIC_SIZE MONI_MODE
+ 1220 85 # H_COUNT
+ 1221 00 # H_COUNT[10:8]
+ 1222 58 # V_COUNT
+ 1223 00 # V_COUNT[12:8]
+ 121D 63 # H_SIZE H_INTERMIT
+ 125D 83 # CCP_LVDS_MODE/ _/ _/ _/ _/ CCP_COMP_MODE[2-0]
+ */
+ struct et8ek8_reglist *r = sensor->current_reglist;
+ struct v4l2_subdev *subdev = &sensor->subdev;
+ struct i2c_client *client = v4l2_get_subdevdata(subdev);
+ int vco;
+
+ printk("Mode validation:\n");
+
+ assert_value(client, 0x1220, (r->mode.width / 24) & 0xff);
+ assert_value(client, 0x1221, (r->mode.width / 24) >> 8);
+
+ assert_value(client, 0x1222, (r->mode.height / 24) & 0xff);
+ assert_value(client, 0x1223, (r->mode.height / 24) >> 8);
+
+ {
+ int ckref_div = read_16(client, 0x1238) & 0xf;
+ int ckvar_div = ((read_16(client, 0x1238) & 0x80) >> 7) | (read_16(client, 0x1239) << 1);
+ int vco_div = read_16(client, 0x123A) >> 4;
+ int spck_div = read_16(client, 0x123A) & 0xf;
+ int mrck_div = read_16(client, 0x123B) >> 4;
+ int lvdsck_div = read_16(client, 0x123B) & 0xf;
+ int ccp2, spck;
+
+ vco = (r->mode.ext_clock * ckvar_div) / (ckref_div + 1);
+ printk("Vco is %d, %d %d %d\n", vco, r->mode.ext_clock, ckvar_div, ckref_div);
+ ccp2 = vco / ((lvdsck_div + 1) * (vco_div + 1));
+ spck = vco / ((spck_div + 1) * (vco_div + 1));
+
+ assert_eq(client, r->mode.pixel_clock, spck, "spck");
+ }
+
+ assert_eq(client, r->mode.max_exp, r->mode.height - 4, "max_exp");
+
+ assert(client, !(r->mode.sensor_window_width % r->mode.window_width), "window_width");
+ switch(r->mode.sensor_window_width / r->mode.window_width) {
+ case 1: assert_value(client, 0x121d, 0x64);
+ break;
+ case 2: assert_value(client, 0x121d, 0x63);
+ break;
+ case 3: assert_value(client, 0x121d, 0x62);
+ break;
+ default:
+ assert(client, 0, "bad window_width");
+ }
+
+ assert(client, !(r->mode.sensor_window_height % r->mode.window_height), "window_width");
+ switch(r->mode.sensor_window_height / r->mode.window_height) {
+ case 1: assert_value(client, 0x121b, 0x64);
+ break;
+ case 2: assert_value(client, 0x121b, 0x63);
+ break;
+ case 3: assert_value(client, 0x121b, 0x62);
+ break;
+ default:
+ assert(client, 0, "bad window_height");
+ }
+
+ //assert(r->mode.height * r->mode.width * fps == r->mode.pixel_clock);
+
+ switch (r->mode.bus_format) {
+ case MEDIA_BUS_FMT_SGRBG10_1X10:
+ assert_value(client, 0x125D, 0x88);
+ assert_eq(client, vco, r->mode.pixel_clock * 8, "vco_clock");
+ break;
+ case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
+ assert_value(client, 0x125D, 0x83);
+ assert_eq(client, vco, r->mode.pixel_clock * 6, "vco_clock");
+ break;
+ default:
+ assert(client, 0, "unexpected bus format");
+
+ /* There are more possibilities, see
+ https://github.com/maemo-foss/omap3camera-firmware/blob/master/makemodes-et8ek8.pl
+ */
+ }
+}
+
static int et8ek8_configure(struct et8ek8_sensor *sensor)
{
struct v4l2_subdev *subdev = &sensor->subdev;
@@ -803,6 +1032,8 @@ static int et8ek8_s_stream(struct v4l2_subdev *subdev, int streaming)
if (ret < 0)
return ret;
+ et8ek8_check(sensor);
+
return et8ek8_stream_on(sensor);
}
diff --git a/drivers/media/i2c/et8ek8/et8ek8_mode.c b/drivers/media/i2c/et8ek8/et8ek8_mode.c
index a79882a83885b..981eb37f8b447 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_mode.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_mode.c
@@ -22,6 +22,11 @@
* Stingray sensor mode settings for Scooby
*/
+/* https://github.com/maemo-foss/omap3camera-firmware/blob/master/makemodes-et8ek8.pl
+
+ /data/l/maemo/kernel-power/kernel-power-2.6.28/drivers/media/video/et8ek8-modes.h
+*/
+
/* Mode1_poweron_Mode2_16VGA_2592x1968_12.07fps */
static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
/* (without the +1)
@@ -39,18 +44,20 @@ static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
*/
.type = ET8EK8_REGLIST_POWERON,
.mode = {
- .sensor_width = 2592,
- .sensor_height = 1968,
+ .name = "mode1_poweron_mode2_16vga_2592x1968_12_07fps",
+
+ .sensor_width = 259,
+ .sensor_height = 196,
.sensor_window_origin_x = 0,
.sensor_window_origin_y = 0,
- .sensor_window_width = 2592,
- .sensor_window_height = 1968,
- .width = 3288,
- .height = 2016,
+ .sensor_window_width = 259,
+ .sensor_window_height = 196,
+ .width = 328,
+ .height = 201,
.window_origin_x = 0,
.window_origin_y = 0,
- .window_width = 2592,
- .window_height = 1968,
+ .window_width = 259,
+ .window_height = 196,
.pixel_clock = 80000000,
.ext_clock = 9600000,
.timeperframe = {
@@ -108,6 +115,65 @@ static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
{ ET8EK8_REG_8BIT, 0x1648, 0x00 },
{ ET8EK8_REG_8BIT, 0x113E, 0x01 },
{ ET8EK8_REG_8BIT, 0x113F, 0x22 },
+ /* Settings from here on seem to for the 2592x1968 mode. */
+ { ET8EK8_REG_8BIT, 0x1239, 0x64 },
+ { ET8EK8_REG_8BIT, 0x1238, 0x02 },
+ { ET8EK8_REG_8BIT, 0x123B, 0x70 },
+ { ET8EK8_REG_8BIT, 0x123A, 0x07 },
+ { ET8EK8_REG_8BIT, 0x121B, 0x64 },
+ { ET8EK8_REG_8BIT, 0x121D, 0x64 },
+ { ET8EK8_REG_8BIT, 0x1221, 0x00 },
+ { ET8EK8_REG_8BIT, 0x1220, 0x89 },
+ { ET8EK8_REG_8BIT, 0x1223, 0x00 },
+ { ET8EK8_REG_8BIT, 0x1222, 0x54 },
+ { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/ */
+ { ET8EK8_REG_TERM, 0, 0}
+ }
+};
+
+static struct et8ek8_reglist mode2_16vga_2592x1968_12_07fps = {
+/* (without the +1)
+ * SPCK = 80 MHz
+ * CCP2 = 640 MHz
+ * VCO = 640 MHz
+ * VCOUNT = 84 (2016)
+ * HCOUNT = 137 (3288)
+ * CKREF_DIV = 2
+ * CKVAR_DIV = 200
+ * VCO_DIV = 0
+ * SPCK_DIV = 7
+ * MRCK_DIV = 7
+ * LVDSCK_DIV = 0
+ */
+ .type = ET8EK8_REGLIST_MODE,
+ .mode = {
+ .name = "mode2_16vga_2592x1968_12_07fps",
+
+ .sensor_width = 2592,
+ .sensor_height = 1968,
+ .sensor_window_origin_x = 0,
+ .sensor_window_origin_y = 0,
+ .sensor_window_width = 2592,
+ .sensor_window_height = 1968,
+ .width = 3288,
+ .height = 2016,
+ .window_origin_x = 0,
+ .window_origin_y = 0,
+ .window_width = 2592,
+ .window_height = 1968,
+ .pixel_clock = 80000000,
+ .ext_clock = 9600000,
+ .timeperframe = {
+ .numerator = 100,
+ .denominator = 1207
+ },
+ .max_exp = 2012,
+ /* .max_gain = 0, */
+ .bus_format = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .sensitivity = 65536
+ },
+ .regs = {
+ /* Settings from here on seem to for the 2592x1968 mode. */
{ ET8EK8_REG_8BIT, 0x1239, 0x64 },
{ ET8EK8_REG_8BIT, 0x1238, 0x02 },
{ ET8EK8_REG_8BIT, 0x123B, 0x70 },
@@ -123,6 +189,7 @@ static struct et8ek8_reglist mode1_poweron_mode2_16vga_2592x1968_12_07fps = {
}
};
+
/* Mode1_16VGA_2592x1968_13.12fps_DPCM10-8 */
static struct et8ek8_reglist mode1_16vga_2592x1968_13_12fps_dpcm10_8 = {
/* (without the +1)
@@ -140,6 +207,7 @@ static struct et8ek8_reglist mode1_16vga_2592x1968_13_12fps_dpcm10_8 = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode1_16vga_2592x1968_13_12fps_dpcm10_8",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -196,6 +264,7 @@ static struct et8ek8_reglist mode3_4vga_1296x984_29_99fps_dpcm10_8 = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode3_4vga_1296x984_29_99fps_dpcm10_8",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -252,6 +321,7 @@ static struct et8ek8_reglist mode4_svga_864x656_29_88fps = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode4_svga_864x656_29_88fps",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -308,6 +378,7 @@ static struct et8ek8_reglist mode5_vga_648x492_29_93fps = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode5_vga_648x492_29_93fps",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -364,6 +435,7 @@ static struct et8ek8_reglist mode2_16vga_2592x1968_3_99fps = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode2_16vga_2592x1968_3_99fps",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -398,6 +470,7 @@ static struct et8ek8_reglist mode2_16vga_2592x1968_3_99fps = {
{ ET8EK8_REG_8BIT, 0x1220, 0x89 },
{ ET8EK8_REG_8BIT, 0x1223, 0x00 },
{ ET8EK8_REG_8BIT, 0x1222, 0xFE },
+ { ET8EK8_REG_8BIT, 0x125D, 0x88 }, /* CCP_LVDS_MODE/ */
{ ET8EK8_REG_TERM, 0, 0}
}
};
@@ -419,6 +492,7 @@ static struct et8ek8_reglist mode_648x492_5fps = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode_648x492_5fps",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -475,6 +549,7 @@ static struct et8ek8_reglist mode3_4vga_1296x984_5fps = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode3_4vga_1296x984_5fps",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -531,6 +606,7 @@ static struct et8ek8_reglist mode_4vga_1296x984_25fps_dpcm10_8 = {
*/
.type = ET8EK8_REGLIST_MODE,
.mode = {
+ .name = "mode_4vga_1296x984_25fps_dpcm10_8",
.sensor_width = 2592,
.sensor_height = 1968,
.sensor_window_origin_x = 0,
@@ -573,15 +649,23 @@ static struct et8ek8_reglist mode_4vga_1296x984_25fps_dpcm10_8 = {
struct et8ek8_meta_reglist meta_reglist = {
.version = "V14 03-June-2008",
.reglist = {
+ /* power on mode; strange & special */
{ .ptr = &mode1_poweron_mode2_16vga_2592x1968_12_07fps },
- { .ptr = &mode1_16vga_2592x1968_13_12fps_dpcm10_8 },
- { .ptr = &mode3_4vga_1296x984_29_99fps_dpcm10_8 },
- { .ptr = &mode4_svga_864x656_29_88fps },
- { .ptr = &mode5_vga_648x492_29_93fps },
- { .ptr = &mode2_16vga_2592x1968_3_99fps },
- { .ptr = &mode_648x492_5fps },
- { .ptr = &mode3_4vga_1296x984_5fps },
+ /* dpcm10/8 modes */
+#if 0
+ { .ptr = &mode1_16vga_2592x1968_13_12fps_dpcm10_8 }, /* No luck */
+ { .ptr = &mode3_4vga_1296x984_29_99fps_dpcm10_8 }, /* No luck */
{ .ptr = &mode_4vga_1296x984_25fps_dpcm10_8 },
+#endif
+ /* "normal" modes */
+#if 1
+// { .ptr = &mode2_16vga_2592x1968_12_07fps }, /* My hacks. */
+ { .ptr = &mode4_svga_864x656_29_88fps }, /* Works, AFAICT */
+ { .ptr = &mode5_vga_648x492_29_93fps }, /* Seems to work with camera.py 640 */
+ { .ptr = &mode2_16vga_2592x1968_3_99fps }, /* Does not seem to work: scrolling */
+// { .ptr = &mode_648x492_5fps }, /* Seems to work with /my/v4l-utils/camera.py 640 ; can't get it to work in raw mode */
+ { .ptr = &mode3_4vga_1296x984_5fps }, /* Works, AFAICT */
+#endif
{ .ptr = NULL }
}
};
diff --git a/drivers/media/i2c/et8ek8/et8ek8_reg.h b/drivers/media/i2c/et8ek8/et8ek8_reg.h
index 07f1873a9c3d3..60ab3050ebb49 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_reg.h
+++ b/drivers/media/i2c/et8ek8/et8ek8_reg.h
@@ -37,19 +37,21 @@ struct et8ek8_mode {
u16 sensor_window_height;
/* Image data coming from sensor (after scaling) */
- u16 width;
+ u16 width; /* u */
u16 height;
u16 window_origin_x;
u16 window_origin_y;
- u16 window_width;
- u16 window_height;
+ u16 window_width; /* u */
+ u16 window_height; /* u */
- u32 pixel_clock; /* in Hz */
- u32 ext_clock; /* in Hz */
- struct v4l2_fract timeperframe;
- u32 max_exp; /* Maximum exposure value */
- u32 bus_format; /* MEDIA_BUS_FMT_ */
+ u32 pixel_clock; /* u in Hz */
+ u32 ext_clock; /* u in Hz */
+ struct v4l2_fract timeperframe; /* u */
+ u32 max_exp; /* u Maximum exposure value */
+ u32 bus_format; /* u MEDIA_BUS_FMT_ */
u32 sensitivity; /* 16.16 fixed point */
+
+ char *name;
};
#define ET8EK8_REG_8BIT 1