Commit Graph

34 Commits

Author SHA1 Message Date
Dave Stevenson
d938877cb1 media: i2c: imx290: Fix clock setup register assignments
When the clock setups were added for the alternate external clocks,
the settings for 2 lane 720p and 4 lane 1080p were transposed.
2 lane 720p still worked, but 4 lane 1080p didn't.

Correct the assignments.

Fixes: 6b0c094a5b (media: i2c: imx290: Add support for 74.25MHz clock")

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:34 +00:00
Dave Stevenson
6b9f591bbd media: i2c: imx290: Fix the pixel rate at 148.5Mpix/s
Whilst the datasheet lists the link frequency changing between
1080p and 720p modes, reality is that with the default blanking
we have
(1920 + 280) * (1080 + 45) * 60fps = 148.5MPix/s
and
(1280 + 2020) * (720 + 30) * 60fps = 148.5MPix/s
and this reflects reality whether in 10 or 12 bit readout modes.

How this relates to link frequency is unclear as it differs
from the datasheet, but all exposure and frame rate calcs need
the pixel rate to be correct, so make it so.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:34 +00:00
Dave Stevenson
1c136467f7 media: i2c: imx290: Support 60fps in 2 lane operation
Commit "97589ad61c73 media: i2c: imx290: Add support for 2 data lanes"
added support for running in two lane mode (instead of 4), but
without changing the link frequency that resulted in a max of 30fps.

Commit "98e0500eadb7 media: i2c: imx290: Add configurable link frequency
and pixel rate" then doubled the link frequency when in 2 lane mode,
but didn't undo the correction for running at only 30fps, just extending
horizontal blanking instead.
It also didn't update the CSI timing registers in accordance with the
datasheet.

Remove the 30fps limit on 2 lane by correcting the register config
in accordance with the datasheet for 60fps operation over 2 lanes.
Frame rate control (via V4L2_CID_VBLANK or HBLANK) can still reduce
the frame rate on 2 lanes back to 30fps.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:34 +00:00
David Plowman
c32705cb75 media: i2c: imx290: Handle exposure correctly when vblank changes
When vblank changes we must modify the exposure range. Also, with this
sensor, the effective exposure time implicitly changes when vblank
does, so we have to reset it after every vblank update.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
2021-11-29 16:25:23 +00:00
David Plowman
d25db7c33f media: i2c: imx290: Fix up exposure calcuations and ranges
Should now correspond exactly to the datasheet.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
2021-11-29 16:25:23 +00:00
David Plowman
1e4e967771 media: i2c: imx290: Fix number of controls in v4l2_ctrl_handler_init
The number is only a hint, but may as well be correct.

Fixes: 471e0029e9 ("media: i2c: imx290: Convert HMAX setting into V4L2_CID_HBLANK")
Fixes: be0b9b7ad1 ("media: i2c: imx290: Add support for V4L2_CID_VBLANK")
Fixes: 8483f0d759 ("media: i2c: imx290: Add exposure control to the driver.")
Fixes: 9764f3459c ("media: i2c: imx290: Add H and V flip controls")
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
2021-11-29 16:25:22 +00:00
David Plowman
317312baf4 media: i2c: imx290: Replace V4L2_CID_GAIN with V4L2_CID_ANALOGUE_GAIN
Most software (including libcamera) requires V4L2_CID_ANALOGUE_GAIN,
not V4L2_CID_GAIN.

The range for the control is 0 to 100 for which the sensor uses only
analogue gain; higher values would involve digital gain which this
control should not apply.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
2021-11-29 16:25:22 +00:00
Dave Stevenson
fb83458aa4 media: i2c: imx290: Set the colorspace fields in the format
The colorspace fields were left untouched in imx290_set_fmt
which lead to a v4l2-compliance failure.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:10 +00:00
Dave Stevenson
037c8b5f59 media: i2c: imx290: Add support for g_selection to report cropping
Userspace needs to know the cropping arrangements for each mode,
so expose this through g_selection.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:10 +00:00
Dave Stevenson
acc1e6f2c6 media: i2c: imx290: Explicitly set v&h blank on mode change
__v4l2_ctrl_modify_range only updates the current value should
it be invalid within the new range. That can leave modes producing
odd frame rates.

Explicitly update the HBLANK and VBLANK values so that on mode
change we revert to the default frame rate for the mode.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:10 +00:00
Dave Stevenson
0ea72859d8 media: i2c: imx290: Switch set_hmax to use imx290_write_buffered_reg
imx290_set_hmax was using two independent writes to set up hmax,
when all other multi-register writes were using imx290_write_buffered_reg
which claims the group hold first.

Switch imx290_set_hmax to using imx290_write_buffered_reg too.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:08 +00:00
Dave Stevenson
82cd6e3eec media : i2c: imx290: Add support for the mono sensor variant.
The IMX290 module is available as either mono or colour (Bayer).

Update the driver so that it can advertise the correct mono
formats instead of the colour ones.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:08 +00:00
Dave Stevenson
2f81b2c5fd media: i2c: imx290: Add H and V flip controls
The sensor supports horizontal and vertical flips, so support them
through V4L2_CID_HFLIP and V4L2_CID_VFLIP.

This sensor does NOT change the Bayer order when changing the
direction of readout, therefore no special handling is required for
that.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:08 +00:00
Dave Stevenson
5105d23732 media: i2c: imx290: Add exposure control to the driver.
Adds support for V4L2_CID_EXPOSURE so that userspace can control
the sensor exposure time.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:08 +00:00
Dave Stevenson
4b140b0ee8 media: i2c: imx290: Add support for V4L2_CID_VBLANK
In order to calculate framerate and durations userspace needs
the vertical blanking information. This can be configurable,
and indeed the datasheet lists different values for VBLANK for
the 1080p and 720p modes.

Add the new control, and adopt the datasheet values for each mode.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:08 +00:00
Dave Stevenson
0564c0339c media: i2c: imx290: Convert HMAX setting into V4L2_CID_HBLANK
Userspace needs to know HBLANK if it is to work out exposure times
and frame rates, therefore convert it to map onto V4L2_CID_HBLANK

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:07 +00:00
Dave Stevenson
6d1935f651 media: i2c: imx290: Correct range for V4L2_CID_GAIN to 0-238
The datasheet lists the gain as being 0.0 to 72.0dB in 0.3dB steps, which
makes 238 steps total.
Correct the 0-72 range defined in the driver.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:07 +00:00
Dave Stevenson
a047d425af media: i2c: imx290: Add support for 74.25MHz clock
The existing driver only supported a clock of 37.125MHz, but the
sensor also supports 74.25MHz.

Add the relevant register modifications to support this alternate
clock frequency.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
2021-11-29 16:25:07 +00:00
Andrey Konovalov
a3c027bcea media: i2c: imx290: set the format before VIDIOC_SUBDEV_G_FMT is called
Commit d46cfdc86c upstream.

With the current driver 'media-ctl -p' issued right after the imx290 driver
is loaded prints:
pad0: Source
             [fmt:unknown/0x0]

The format value of zero is due to the current_format field of the imx290
struct not being initialized yet.

As imx290_entity_init_cfg() calls imx290_set_fmt(), the current_mode field
is also initialized, so the line which set current_mode to a default value
in driver's probe() function is no longer needed.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-11-29 16:25:07 +00:00
Tomi Valkeinen
0d346d2a6f media: v4l2-subdev: add subdev-wide state struct
We have 'struct v4l2_subdev_pad_config' which contains configuration for
a single pad used for the TRY functionality, and an array of those
structs is passed to various v4l2_subdev_pad_ops.

I was working on subdev internal routing between pads, and realized that
there's no way to add TRY functionality for routes, which is not pad
specific configuration. Adding a separate struct for try-route config
wouldn't work either, as e.g. set-fmt needs to know the try-route
configuration to propagate the settings.

This patch adds a new struct, 'struct v4l2_subdev_state' (which at the
moment only contains the v4l2_subdev_pad_config array) and the new
struct is used in most of the places where v4l2_subdev_pad_config was
used. All v4l2_subdev_pad_ops functions taking v4l2_subdev_pad_config
are changed to instead take v4l2_subdev_state.

The changes to drivers/media/v4l2-core/v4l2-subdev.c and
include/media/v4l2-subdev.h were written by hand, and all the driver
changes were done with the semantic patch below. The spatch needs to be
applied to a select list of directories. I used the following shell
commands to apply the spatch:

dirs="drivers/media/i2c drivers/media/platform drivers/media/usb drivers/media/test-drivers/vimc drivers/media/pci drivers/staging/media"
for dir in $dirs; do spatch -j8 --dir --include-headers --no-show-diff --in-place --sp-file v4l2-subdev-state.cocci $dir; done

Note that Coccinelle chokes on a few drivers (gcc extensions?). With
minor changes we can make Coccinelle run fine, and these changes can be
reverted after spatch. The diff for these changes is:

For drivers/media/i2c/s5k5baf.c:

	@@ -1481,7 +1481,7 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
	 				&s5k5baf_cis_rect,
	 				v4l2_subdev_get_try_crop(sd, cfg, PAD_CIS),
	 				v4l2_subdev_get_try_compose(sd, cfg, PAD_CIS),
	-				v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT)
	+				v4l2_subdev_get_try_crop(sd, cfg, PAD_OUT),
	 			};
	 		s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
	 		return 0;

For drivers/media/platform/s3c-camif/camif-capture.c:

	@@ -1230,7 +1230,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
	 		*mf = camif->mbus_fmt;
	 		break;

	-	case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
	+	case CAMIF_SD_PAD_SOURCE_C:
	 		/* crop rectangle at camera interface input */
	 		mf->width = camif->camif_crop.width;
	 		mf->height = camif->camif_crop.height;
	@@ -1332,7 +1332,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
	 		}
	 		break;

	-	case CAMIF_SD_PAD_SOURCE_C...CAMIF_SD_PAD_SOURCE_P:
	+	case CAMIF_SD_PAD_SOURCE_C:
	 		/* Pixel format can be only changed on the sink pad. */
	 		mf->code = camif->mbus_fmt.code;
	 		mf->width = crop->width;

The semantic patch is:

// <smpl>

// Change function parameter

@@
identifier func;
identifier cfg;
@@

 func(...,
-   struct v4l2_subdev_pad_config *cfg
+   struct v4l2_subdev_state *sd_state
    , ...)
 {
 <...
- cfg
+ sd_state
 ...>
 }

// Change function declaration parameter

@@
identifier func;
identifier cfg;
type T;
@@
T func(...,
-   struct v4l2_subdev_pad_config *cfg
+   struct v4l2_subdev_state *sd_state
    , ...);

// Change function return value

@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
 *func(...)
 {
    ...
 }

// Change function declaration return value

@@
identifier func;
@@
- struct v4l2_subdev_pad_config
+ struct v4l2_subdev_state
 *func(...);

// Some drivers pass a local pad_cfg for a single pad to a called function. Wrap it
// inside a pad_state.

@@
identifier func;
identifier pad_cfg;
@@
func(...)
{
    ...
    struct v4l2_subdev_pad_config pad_cfg;
+   struct v4l2_subdev_state pad_state = { .pads = &pad_cfg };

    <+...

(
    v4l2_subdev_call
|
    sensor_call
|
    isi_try_fse
|
    isc_try_fse
|
    saa_call_all
)
    (...,
-   &pad_cfg
+   &pad_state
    ,...)

    ...+>
}

// If the function uses fields from pad_config, access via state->pads

@@
identifier func;
identifier state;
@@
 func(...,
    struct v4l2_subdev_state *state
    , ...)
 {
    <...
(
-   state->try_fmt
+   state->pads->try_fmt
|
-   state->try_crop
+   state->pads->try_crop
|
-   state->try_compose
+   state->pads->try_compose
)
    ...>
}

// If the function accesses the filehandle, use fh->state instead

@@
struct v4l2_subdev_fh *fh;
@@
-    fh->pad
+    fh->state

@@
struct v4l2_subdev_fh fh;
@@
-    fh.pad
+    fh.state

// Start of vsp1 specific

@@
@@
struct vsp1_entity {
    ...
-    struct v4l2_subdev_pad_config *config;
+    struct v4l2_subdev_state *config;
    ...
};

@@
symbol entity;
@@
vsp1_entity_init(...)
{
    ...
    entity->config =
-    v4l2_subdev_alloc_pad_config
+    v4l2_subdev_alloc_state
    (&entity->subdev);
    ...
}

@@
symbol entity;
@@
vsp1_entity_destroy(...)
{
    ...
-   v4l2_subdev_free_pad_config
+   v4l2_subdev_free_state
    (entity->config);
    ...
}

@exists@
identifier func =~ "(^vsp1.*)|(hsit_set_format)|(sru_enum_frame_size)|(sru_set_format)|(uif_get_selection)|(uif_set_selection)|(uds_enum_frame_size)|(uds_set_format)|(brx_set_format)|(brx_get_selection)|(histo_get_selection)|(histo_set_selection)|(brx_set_selection)";
symbol config;
@@
func(...) {
    ...
-    struct v4l2_subdev_pad_config *config;
+    struct v4l2_subdev_state *config;
    ...
}

// End of vsp1 specific

// Start of rcar specific

@@
identifier sd;
identifier pad_cfg;
@@
 rvin_try_format(...)
 {
    ...
-   struct v4l2_subdev_pad_config *pad_cfg;
+   struct v4l2_subdev_state *sd_state;
    ...
-   pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+   sd_state = v4l2_subdev_alloc_state(sd);
    <...
-   pad_cfg
+   sd_state
    ...>
-   v4l2_subdev_free_pad_config(pad_cfg);
+   v4l2_subdev_free_state(sd_state);
    ...
 }

// End of rcar specific

// Start of rockchip specific

@@
identifier func =~ "(rkisp1_rsz_get_pad_fmt)|(rkisp1_rsz_get_pad_crop)|(rkisp1_rsz_register)";
symbol rsz;
symbol pad_cfg;
@@

 func(...)
 {
+   struct v4l2_subdev_state state = { .pads = rsz->pad_cfg };
    ...
-   rsz->pad_cfg
+   &state
    ...
 }

@@
identifier func =~ "(rkisp1_isp_get_pad_fmt)|(rkisp1_isp_get_pad_crop)";
symbol isp;
symbol pad_cfg;
@@

 func(...)
 {
+   struct v4l2_subdev_state state = { .pads = isp->pad_cfg };
    ...
-   isp->pad_cfg
+   &state
    ...
 }

@@
symbol rkisp1;
symbol isp;
symbol pad_cfg;
@@

 rkisp1_isp_register(...)
 {
+   struct v4l2_subdev_state state = { .pads = rkisp1->isp.pad_cfg };
    ...
-   rkisp1->isp.pad_cfg
+   &state
    ...
 }

// End of rockchip specific

// Start of tegra-video specific

@@
identifier sd;
identifier pad_cfg;
@@
 __tegra_channel_try_format(...)
 {
    ...
-   struct v4l2_subdev_pad_config *pad_cfg;
+   struct v4l2_subdev_state *sd_state;
    ...
-   pad_cfg = v4l2_subdev_alloc_pad_config(sd);
+   sd_state = v4l2_subdev_alloc_state(sd);
    <...
-   pad_cfg
+   sd_state
    ...>
-   v4l2_subdev_free_pad_config(pad_cfg);
+   v4l2_subdev_free_state(sd_state);
    ...
 }

@@
identifier sd_state;
@@
 __tegra_channel_try_format(...)
 {
    ...
    struct v4l2_subdev_state *sd_state;
    <...
-   sd_state->try_crop
+   sd_state->pads->try_crop
    ...>
 }

// End of tegra-video specific

// </smpl>

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-06-17 10:01:27 +02:00
Mauro Carvalho Chehab
739d9c6415 media: i2c: imx290: use pm_runtime_resume_and_get()
Commit dd8088d5a8 ("PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter")
added pm_runtime_resume_and_get() in order to automatically handle
dev->power.usage_count decrement on errors.

Use the new API, in order to cleanup the error check logic.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2021-05-19 09:51:40 +02:00
Krzysztof Kozlowski
b50ce25de7 media: i2c: imx290: simplify getting state container
The pointer to 'struct v4l2_subdev' is stored in drvdata via
v4l2_i2c_subdev_init() so there is no point of a dance like:

    struct i2c_client *client = to_i2c_client(struct device *dev)
    struct v4l2_subdev *sd = i2c_get_clientdata(client);

This allows to remove local variable 'client' and few pointer
dereferences.  White at it, use 'dev' directly instead of 'imx290->dev'.

Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-11-16 10:31:11 +01:00
Andrey Konovalov
8e5652ae8d media: i2c: imx290: replace msleep(10) with usleep_range(10000, 11000)
This fixes checkpatch warnings of "msleep < 20ms can sleep for up to 20ms".

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-07-19 14:08:30 +02:00
Andrey Konovalov
a270675875 media: i2c: imx290: set bus_type before calling v4l2_fwnode_endpoint_alloc_parse()
The bus_type field of v4l2_fwnode_endpoint structure passed as the argument
to v4l2_fwnode_endpoint_alloc_parse() function must be initiaized.
Set it to V4L2_MBUS_CSI2_DPHY, and check for -ENXIO which is returned
when the requested media bus type doesn't match the fwnode.

Also remove v4l2_fwnode_endpoint field from struct imx290 as it is only
needed in the probe function: use the local variable for this purpose.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:18:53 +02:00
Manivannan Sadhasivam
6544af9b04 media: i2c: imx290: Move the settle time delay out of loop
The 10ms settle time is needed only at the end of all consecutive
register writes. So move the delay to outside of the for loop of
imx290_set_register_array().

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:18:33 +02:00
Manivannan Sadhasivam
3b867fb641 media: i2c: imx290: Add support to enumerate all frame sizes
Add support to enumerate all frame sizes supported by IMX290. This is
required for using with userspace tools such as libcamera.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:18:18 +02:00
Manivannan Sadhasivam
c566ac01ce media: i2c: imx290: Add RAW12 mode support
IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and
12 bit formats. Since the driver already supports RAW10 mode, let's add
the missing RAW12 mode as well.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:18:03 +02:00
Manivannan Sadhasivam
a58df1f9e4 media: i2c: imx290: Add support for test pattern generation
Add support for generating following test patterns by IMX290:

* Sequence Pattern 1
* Horizontal Color-bar Chart
* Vertical Color-bar Chart
* Sequence Pattern 2
* Gradation Pattern 1
* Gradation Pattern 2
* 000/555h Toggle Pattern

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:17:46 +02:00
Manivannan Sadhasivam
98e0500ead media: i2c: imx290: Add configurable link frequency and pixel rate
IMX290 operates with multiple link frequency and pixel rate combinations.
The initial driver used a single setting for both but since we now have
the lane count support in place, let's add configurable link frequency
and pixel rate.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:17:28 +02:00
Manivannan Sadhasivam
97589ad61c media: i2c: imx290: Add support for 2 data lanes
The IMX290 sensor can output frames with 2/4 CSI2 data lanes. This commit
adds support for 2 lane mode in addition to the 4 lane and also
configuring the data lane settings in the driver based on system
configuration.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:16:48 +02:00
Andrey Konovalov
3909a92d7d media: i2c: imx290: fix reset GPIO pin handling
According to https://www.kernel.org/doc/Documentation/gpio/consumer.txt,

- all of the gpiod_set_value_xxx() functions operate with the *logical*
value. So in imx290_power_on() the reset signal should be cleared
(de-asserted) with gpiod_set_value_cansleep(imx290->rst_gpio, 0), and in
imx290_power_off() the value of 1 must be used to apply/assert the reset
to the sensor. In the device tree the reset pin is described as
GPIO_ACTIVE_LOW, and gpiod_set_value_xxx() functions take this into
account,

- when devm_gpiod_get_optional() is called with GPIOD_ASIS, the GPIO is
not initialized, and the direction must be set later; using a GPIO
without setting its direction first is illegal and will result in undefined
behavior. Fix this by using GPIOD_OUT_HIGH instead of GPIOD_ASIS (this
asserts the reset signal to the sensor initially).

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:16:23 +02:00
Andrey Konovalov
8d2d1bedb1 media: i2c: imx290: fix the order of the args in SET_RUNTIME_PM_OPS()
The macro is defined as SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn),
so imx290_power_off must be the 1st arg, and imx290_power_on the 2nd.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:16:07 +02:00
Andrey Konovalov
d46cfdc86c media: i2c: imx290: set the format before VIDIOC_SUBDEV_G_FMT is called
With the current driver 'media-ctl -p' issued right after the imx290 driver
is loaded prints:
pad0: Source
             [fmt:unknown/0x0]

The format value of zero is due to the current_format field of the imx290
struct not being initialized yet.

As imx290_entity_init_cfg() calls imx290_set_fmt(), the current_mode field
is also initialized, so the line which set current_mode to a default value
in driver's probe() function is no longer needed.

Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
2020-06-23 15:15:47 +02:00
Manivannan Sadhasivam
828dbc2992 media: i2c: Add IMX290 CMOS image sensor driver
Add driver for Sony IMX290 CMOS image sensor driver. The driver only
supports I2C interface for programming and MIPI CSI-2 for sensor output.

[Sakari Ailus: Rewrapped a few lines over 80 chars a little.]

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2019-10-24 18:48:03 -03:00