aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch407
1 files changed, 0 insertions, 407 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch b/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
deleted file mode 100644
index 5846e96af8..0000000000
--- a/target/linux/bcm27xx/patches-5.4/950-0456-media-ov5647-Add-basic-support-for-multiple-sensor-m.patch
+++ /dev/null
@@ -1,407 +0,0 @@
-From 9e584d9de3387588bf455d3c45ec6a092bfa4266 Mon Sep 17 00:00:00 2001
-From: David Plowman <david.plowman@raspberrypi.com>
-Date: Wed, 29 Jan 2020 15:30:53 +0000
-Subject: [PATCH] media: ov5647: Add basic support for multiple sensor
- modes.
-
-Specifically:
-
-Added a structure ov5647_mode and a list of supported_modes (though no
-actual new modes as yet). The state object points to the "current mode".
-
-ov5647_enum_mbus_code, ov5647_enum_frame_size, ov5647_set_fmt and
-ov5647_get_fmt all needed upgrading to cope with multiple modes.
-
-__sensor_init (which writes all the registers) is now called by
-ov5647_stream_on (once the mode is known) rather than by
-ov5647_sensor_power.
-
-Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
-Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
----
- drivers/media/i2c/ov5647.c | 268 ++++++++++++++++++++++++++++---------
- 1 file changed, 202 insertions(+), 66 deletions(-)
-
---- a/drivers/media/i2c/ov5647.c
-+++ b/drivers/media/i2c/ov5647.c
-@@ -86,13 +86,17 @@ struct regval_list {
- u8 data;
- };
-
-+struct ov5647_mode {
-+ struct v4l2_mbus_framefmt format;
-+ struct regval_list *reg_list;
-+ unsigned int num_regs;
-+};
-+
- struct ov5647 {
- struct v4l2_subdev sd;
- struct media_pad pad;
- struct mutex lock;
-- struct v4l2_mbus_framefmt format;
-- unsigned int width;
-- unsigned int height;
-+ const struct ov5647_mode *mode;
- int power_count;
- struct clk *xclk;
- struct gpio_desc *pwdn;
-@@ -207,6 +211,32 @@ static struct regval_list ov5647_640x480
- {0x0100, 0x01},
- };
-
-+static struct ov5647_mode supported_modes_8bit[] = {
-+ /*
-+ * Original 8-bit VGA mode
-+ * Uncentred crop (top left quarter) from 2x2 binned 1296x972 image.
-+ */
-+ {
-+ {
-+ .code = MEDIA_BUS_FMT_SBGGR8_1X8,
-+ .colorspace = V4L2_COLORSPACE_SRGB,
-+ .field = V4L2_FIELD_NONE,
-+ .width = 640,
-+ .height = 480
-+ },
-+ ov5647_640x480,
-+ ARRAY_SIZE(ov5647_640x480)
-+ },
-+ /* more modes below here... */
-+};
-+
-+static struct ov5647_mode supported_modes_10bit[] = {
-+ /* no 10-bit modes yet */
-+};
-+
-+/* Use original 8-bit VGA mode as default. */
-+#define OV5647_DEFAULT_MODE (&supported_modes_8bit[0])
-+
- static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val)
- {
- int ret;
-@@ -293,12 +323,55 @@ static int ov5647_set_virtual_channel(st
- return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6));
- }
-
-+static int __sensor_init(struct v4l2_subdev *sd)
-+{
-+ int ret;
-+ u8 resetval, rdval;
-+ struct i2c_client *client = v4l2_get_subdevdata(sd);
-+ struct ov5647 *state = to_state(sd);
-+
-+ ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ov5647_write_array(sd, state->mode->reg_list,
-+ state->mode->num_regs);
-+ if (ret < 0) {
-+ dev_err(&client->dev, "write sensor default regs error\n");
-+ return ret;
-+ }
-+
-+ ret = ov5647_set_virtual_channel(sd, 0);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (!(resetval & 0x01)) {
-+ dev_err(&client->dev, "Device was in SW standby");
-+ ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int ov5647_stream_on(struct v4l2_subdev *sd)
- {
-+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct ov5647 *ov5647 = to_state(sd);
- u8 val = MIPI_CTRL00_BUS_IDLE;
- int ret;
-
-+ ret = __sensor_init(sd);
-+ if (ret < 0) {
-+ dev_err(&client->dev, "sensor_init failed\n");
-+ return ret;
-+ }
-+
- if (ov5647->flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)
- val |= MIPI_CTRL00_CLOCK_LANE_GATE |
- MIPI_CTRL00_LINE_SYNC_ENABLE;
-@@ -347,44 +420,6 @@ static int set_sw_standby(struct v4l2_su
- return ov5647_write(sd, OV5647_SW_STANDBY, rdval);
- }
-
--static int __sensor_init(struct v4l2_subdev *sd)
--{
-- int ret;
-- u8 resetval, rdval;
-- struct i2c_client *client = v4l2_get_subdevdata(sd);
--
-- ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval);
-- if (ret < 0)
-- return ret;
--
-- ret = ov5647_write_array(sd, ov5647_640x480,
-- ARRAY_SIZE(ov5647_640x480));
-- if (ret < 0) {
-- dev_err(&client->dev, "write sensor default regs error\n");
-- return ret;
-- }
--
-- ret = ov5647_set_virtual_channel(sd, 0);
-- if (ret < 0)
-- return ret;
--
-- ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval);
-- if (ret < 0)
-- return ret;
--
-- if (!(resetval & 0x01)) {
-- dev_err(&client->dev, "Device was in SW standby");
-- ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01);
-- if (ret < 0)
-- return ret;
-- }
--
-- /*
-- * stream off to make the clock lane into LP-11 state.
-- */
-- return ov5647_stream_off(sd);
--}
--
- static int ov5647_sensor_power(struct v4l2_subdev *sd, int on)
- {
- int ret = 0;
-@@ -408,7 +443,7 @@ static int ov5647_sensor_power(struct v4
- }
-
- ret = ov5647_write_array(sd, sensor_oe_enable_regs,
-- ARRAY_SIZE(sensor_oe_enable_regs));
-+ ARRAY_SIZE(sensor_oe_enable_regs));
- if (ret < 0) {
- clk_disable_unprepare(ov5647->xclk);
- dev_err(&client->dev,
-@@ -416,7 +451,10 @@ static int ov5647_sensor_power(struct v4
- goto out;
- }
-
-- ret = __sensor_init(sd);
-+ /*
-+ * Ensure streaming off to make clock lane go into LP-11 state.
-+ */
-+ ret = ov5647_stream_off(sd);
- if (ret < 0) {
- clk_disable_unprepare(ov5647->xclk);
- dev_err(&client->dev,
-@@ -427,7 +465,7 @@ static int ov5647_sensor_power(struct v4
- dev_dbg(&client->dev, "OV5647 power off\n");
-
- ret = ov5647_write_array(sd, sensor_oe_disable_regs,
-- ARRAY_SIZE(sensor_oe_disable_regs));
-+ ARRAY_SIZE(sensor_oe_disable_regs));
-
- if (ret < 0)
- dev_dbg(&client->dev, "disable oe failed\n");
-@@ -489,10 +527,19 @@ static const struct v4l2_subdev_core_ops
-
- static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
- {
-+ struct ov5647 *state = to_state(sd);
-+ int ret = 0;
-+
-+ mutex_lock(&state->lock);
-+
- if (enable)
-- return ov5647_stream_on(sd);
-+ ret = ov5647_stream_on(sd);
- else
-- return ov5647_stream_off(sd);
-+ ret = ov5647_stream_off(sd);
-+
-+ mutex_unlock(&state->lock);
-+
-+ return ret;
- }
-
- static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = {
-@@ -503,38 +550,127 @@ static int ov5647_enum_mbus_code(struct
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_mbus_code_enum *code)
- {
-- if (code->index > 0)
-+ if (code->index == 0 && ARRAY_SIZE(supported_modes_8bit))
-+ code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-+ else if (code->index == 0 && ARRAY_SIZE(supported_modes_8bit) == 0 &&
-+ ARRAY_SIZE(supported_modes_10bit))
-+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-+ else if (code->index == 1 && ARRAY_SIZE(supported_modes_8bit) &&
-+ ARRAY_SIZE(supported_modes_10bit))
-+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-+ else
- return -EINVAL;
-
-- code->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-+ return 0;
-+}
-+
-+static int ov5647_enum_frame_size(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_pad_config *cfg,
-+ struct v4l2_subdev_frame_size_enum *fse)
-+{
-+ struct ov5647_mode *mode = NULL;
-+
-+ if (fse->code == MEDIA_BUS_FMT_SBGGR8_1X8) {
-+ if (fse->index >= ARRAY_SIZE(supported_modes_8bit))
-+ return -EINVAL;
-+ mode = &supported_modes_8bit[fse->index];
-+ } else if (fse->code == MEDIA_BUS_FMT_SBGGR10_1X10) {
-+ if (fse->index >= ARRAY_SIZE(supported_modes_10bit))
-+ return -EINVAL;
-+ mode = &supported_modes_10bit[fse->index];
-+ } else {
-+ return -EINVAL;
-+ }
-+
-+ fse->min_width = mode->format.width;
-+ fse->max_width = fse->min_width;
-+ fse->min_height = mode->format.height;
-+ fse->max_height = fse->min_height;
-+
-+ return 0;
-+}
-+
-+static int ov5647_set_fmt(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_pad_config *cfg,
-+ struct v4l2_subdev_format *format)
-+{
-+ struct v4l2_mbus_framefmt *fmt = &format->format;
-+ struct ov5647 *state = to_state(sd);
-+ struct v4l2_mbus_framefmt *framefmt;
-+ const struct ov5647_mode *mode_8bit, *mode_10bit, *mode = NULL;
-+
-+ if (format->pad != 0)
-+ return -EINVAL;
-+
-+ mutex_lock(&state->lock);
-+
-+ /*
-+ * Try to respect any given pixel format, otherwise try for a 10-bit
-+ * mode.
-+ */
-+ mode_8bit = v4l2_find_nearest_size(supported_modes_8bit,
-+ ARRAY_SIZE(supported_modes_8bit),
-+ format.width, format.height,
-+ format->format.width,
-+ format->format.height);
-+ mode_10bit = v4l2_find_nearest_size(supported_modes_10bit,
-+ ARRAY_SIZE(supported_modes_10bit),
-+ format.width, format.height,
-+ format->format.width,
-+ format->format.height);
-+ if (format->format.code == MEDIA_BUS_FMT_SBGGR8_1X8 && mode_8bit)
-+ mode = mode_8bit;
-+ else if (format->format.code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
-+ mode_10bit)
-+ mode = mode_10bit;
-+ else if (mode_10bit)
-+ mode = mode_10bit;
-+ else
-+ mode = mode_8bit;
-+
-+ if (!mode)
-+ return -EINVAL;
-+
-+ *fmt = mode->format;
-+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-+ framefmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
-+ *framefmt = format->format;
-+ } else {
-+ state->mode = mode;
-+ }
-+
-+ mutex_unlock(&state->lock);
-
- return 0;
- }
-
--static int ov5647_set_get_fmt(struct v4l2_subdev *sd,
-- struct v4l2_subdev_pad_config *cfg,
-- struct v4l2_subdev_format *format)
-+static int ov5647_get_fmt(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_pad_config *cfg,
-+ struct v4l2_subdev_format *format)
- {
- struct v4l2_mbus_framefmt *fmt = &format->format;
-+ struct ov5647 *state = to_state(sd);
-
- if (format->pad != 0)
- return -EINVAL;
-
-- /* Only one format is supported, so return that */
-- memset(fmt, 0, sizeof(*fmt));
-- fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
-- fmt->colorspace = V4L2_COLORSPACE_SRGB;
-- fmt->field = V4L2_FIELD_NONE;
-- fmt->width = 640;
-- fmt->height = 480;
-+ mutex_lock(&state->lock);
-+
-+ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
-+ *fmt = *v4l2_subdev_get_try_format(sd, cfg, format->pad);
-+ else
-+ *fmt = state->mode->format;
-+
-+ mutex_unlock(&state->lock);
-
- return 0;
- }
-
- static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = {
- .enum_mbus_code = ov5647_enum_mbus_code,
-- .set_fmt = ov5647_set_get_fmt,
-- .get_fmt = ov5647_set_get_fmt,
-+ .set_fmt = ov5647_set_fmt,
-+ .get_fmt = ov5647_get_fmt,
-+ .enum_frame_size = ov5647_enum_frame_size,
- };
-
- static const struct v4l2_subdev_ops ov5647_subdev_ops = {
-@@ -580,18 +716,15 @@ static int ov5647_open(struct v4l2_subde
- v4l2_subdev_get_try_format(sd, fh->pad, 0);
- struct v4l2_rect *crop =
- v4l2_subdev_get_try_crop(sd, fh->pad, 0);
-+ struct ov5647 *state = to_state(sd);
-
- crop->left = OV5647_COLUMN_START_DEF;
- crop->top = OV5647_ROW_START_DEF;
- crop->width = OV5647_WINDOW_WIDTH_DEF;
- crop->height = OV5647_WINDOW_HEIGHT_DEF;
-
-- format->code = MEDIA_BUS_FMT_SBGGR8_1X8;
--
-- format->width = OV5647_WINDOW_WIDTH_DEF;
-- format->height = OV5647_WINDOW_HEIGHT_DEF;
-- format->field = V4L2_FIELD_NONE;
-- format->colorspace = V4L2_COLORSPACE_SRGB;
-+ /* Set the default format to the same as the sensor. */
-+ *format = state->mode->format;
-
- return 0;
- }
-@@ -660,6 +793,9 @@ static int ov5647_probe(struct i2c_clien
-
- mutex_init(&sensor->lock);
-
-+ /* Set the default mode before we init the subdev */
-+ sensor->mode = OV5647_DEFAULT_MODE;
-+
- sd = &sensor->sd;
- v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
- sensor->sd.internal_ops = &ov5647_subdev_internal_ops;