* [PATCH v3 2/6] clk: rockchip: rst-rk3588: Add reset line for HDMI Receiver
From: Shreeya Patel @ 2024-03-27 22:50 UTC (permalink / raw)
To: heiko, mchehab, robh, krzysztof.kozlowski+dt, conor+dt,
mturquette, sboyd, p.zabel, jose.abreu, nelson.costa,
dmitry.osipenko, sebastian.reichel, shawn.wen, nicolas.dufresne,
hverkuil, hverkuil-cisco
Cc: kernel, linux-kernel, linux-media, devicetree, linux-arm-kernel,
linux-rockchip, linux-clk, linux-arm, Shreeya Patel
In-Reply-To: <20240327225057.672304-1-shreeya.patel@collabora.com>
Export hdmirx_biu reset line required by the Synopsys
DesignWare HDMIRX Controller.
Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
---
Changes in v3 :-
- No change
Changes in v2 :-
- Improve the subject line and commit message description.
drivers/clk/rockchip/rst-rk3588.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/rockchip/rst-rk3588.c b/drivers/clk/rockchip/rst-rk3588.c
index e855bb8d5413..c4ebc01f1c9c 100644
--- a/drivers/clk/rockchip/rst-rk3588.c
+++ b/drivers/clk/rockchip/rst-rk3588.c
@@ -577,6 +577,7 @@ static const int rk3588_register_offset[] = {
/* SOFTRST_CON59 */
RK3588_CRU_RESET_OFFSET(SRST_A_HDCP1_BIU, 59, 6),
+ RK3588_CRU_RESET_OFFSET(SRST_A_HDMIRX_BIU, 59, 7),
RK3588_CRU_RESET_OFFSET(SRST_A_VO1_BIU, 59, 8),
RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_BIU, 59, 9),
RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_S_BIU, 59, 10),
--
2.39.2
^ permalink raw reply related
* [PATCH v3 1/6] dt-bindings: reset: Define reset id used for HDMI Receiver
From: Shreeya Patel @ 2024-03-27 22:50 UTC (permalink / raw)
To: heiko, mchehab, robh, krzysztof.kozlowski+dt, conor+dt,
mturquette, sboyd, p.zabel, jose.abreu, nelson.costa,
dmitry.osipenko, sebastian.reichel, shawn.wen, nicolas.dufresne,
hverkuil, hverkuil-cisco
Cc: kernel, linux-kernel, linux-media, devicetree, linux-arm-kernel,
linux-rockchip, linux-clk, linux-arm, Shreeya Patel
In-Reply-To: <20240327225057.672304-1-shreeya.patel@collabora.com>
Add reset id used for HDMI Receiver in RK3588 SoCs
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
---
Changes in v3 :-
- Add an Acked-by
Changes in v2 :-
- Move the dt-binding include file changes in a separate patch
- Improve the subject and commit message description
include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/dt-bindings/reset/rockchip,rk3588-cru.h b/include/dt-bindings/reset/rockchip,rk3588-cru.h
index d4264db2a07f..e2fe4bd5f7f0 100644
--- a/include/dt-bindings/reset/rockchip,rk3588-cru.h
+++ b/include/dt-bindings/reset/rockchip,rk3588-cru.h
@@ -751,4 +751,6 @@
#define SRST_P_TRNG_CHK 658
#define SRST_TRNG_S 659
+#define SRST_A_HDMIRX_BIU 660
+
#endif
--
2.39.2
^ permalink raw reply related
* [PATCH v3 0/6] Add Synopsys DesignWare HDMI RX Controller
From: Shreeya Patel @ 2024-03-27 22:50 UTC (permalink / raw)
To: heiko, mchehab, robh, krzysztof.kozlowski+dt, conor+dt,
mturquette, sboyd, p.zabel, jose.abreu, nelson.costa,
dmitry.osipenko, sebastian.reichel, shawn.wen, nicolas.dufresne,
hverkuil, hverkuil-cisco
Cc: kernel, linux-kernel, linux-media, devicetree, linux-arm-kernel,
linux-rockchip, linux-clk, linux-arm, Shreeya Patel
This series implements support for the Synopsys DesignWare
HDMI RX Controller, being compliant with standard HDMI 1.4b
and HDMI 2.0.
Features that are currently supported by the HDMI RX driver
have been tested on rock5b board using a HDMI to micro-HDMI cable.
It is recommended to use a good quality cable as there were
multiple issues seen during testing the driver.
Please note the below information :-
* While testing the driver on rock5b we noticed that the binary BL31
from Rockchip contains some unknown code to get the HDMI-RX PHY
access working. With TF-A BL31, the HDMI-RX PHY doesn't work as
expected since there are no interrupts seen for rk_hdmirx-hdmi
leading to some failures in the driver [0].
* We have tested the working of OBS studio with HDMIRX driver and
there were no issues seen.
* We also tested and verified the support for interlaced video.
[0] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/trusted-firmware-a/-/issues/1
To test the HDMI RX Controller driver, following example commands can be used :-
root@debian-rockchip-rock5b-rk3588:~# v4l2-ctl --verbose -d /dev/video0 \
--set-fmt-video=width=1920,height=1080,pixelformat='BGR3' --stream-mmap=4 \
--stream-skip=3 --stream-count=100 --stream-to=/home/hdmiin4k.raw --stream-poll
root@debian-rockchip-rock5b-rk3588:~# ffmpeg -f rawvideo -vcodec rawvideo \
-s 1920x1080 -r 60 -pix_fmt bgr24 -i /home/hdmiin4k.raw output.mkv
Following is the v4l2-compliance test result :-
root@debian-rockchip-rock5b-rk3588:~# v4l2-compliance -d /dev/video0
v4l2-compliance 1.27.0-5174, 64 bits, 64-bit time_t
v4l2-compliance SHA: d700deb14368 2024-01-18 12:19:05
Compliance test for snps_hdmirx device /dev/video0:
Driver Info:
Driver name : snps_hdmirx
Card type : snps_hdmirx
Bus info : platform: snps_hdmirx
Driver version : 6.8.0
Capabilities : 0x84201000
Video Capture Multiplanar
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04201000
Video Capture Multiplanar
Streaming
Extended Pix Format
Required ioctls:
test VIDIOC_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/video0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
test VIDIOC_LOG_STATUS: OK
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 1 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK
test VIDIOC_DV_TIMINGS_CAP: OK
test VIDIOC_G/S_EDID: OK
Control ioctls (Input 0):
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 2 Private Controls: 0
Format ioctls (Input 0):
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
test VIDIOC_G/S_PARM: OK
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK
test VIDIOC_TRY_FMT: OK
test VIDIOC_S_FMT: OK
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls (Input 0):
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls (Input 0):
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
test CREATE_BUFS maximum buffers: OK
test VIDIOC_EXPBUF: OK
test Requests: OK (Not Supported)
Total for snps_hdmirx device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0
Changes in v3 :-
- Use v4l2-common helpers in the HDMIRX driver
- Rename cma node and phandle names
- Elaborate the comment to explain 160MiB calculation
- Move &hdmi_receiver_cma to the rock5b dts file
- Add information about interlaced video testing in the
cover-letter
Changes in v2 :-
- Fix checkpatch --strict warnings
- Move the dt-binding include file changes in a separate patch
- Add a description for the hardware in the dt-bindings file
- Rename resets, vo1 grf and HPD properties
- Add a proper description for grf and vo1-grf phandles in the
bindings
- Rename the HDMI RX node name to hdmi-receiver
- Include gpio header file in binding example to fix the
dt_binding_check failure
- Move hdmirx_cma node to the rk3588.dtsi file
- Add an entry to MAINTAINERS file for the HDMIRX driver
Shreeya Patel (6):
dt-bindings: reset: Define reset id used for HDMI Receiver
clk: rockchip: rst-rk3588: Add reset line for HDMI Receiver
dt-bindings: media: Document HDMI RX Controller
arm64: dts: rockchip: Add device tree support for HDMI RX Controller
media: platform: synopsys: Add support for hdmi input driver
MAINTAINERS: Add entry for Synopsys DesignWare HDMI RX Driver
.../bindings/media/snps,dw-hdmi-rx.yaml | 132 +
MAINTAINERS | 8 +
.../boot/dts/rockchip/rk3588-pinctrl.dtsi | 41 +
.../boot/dts/rockchip/rk3588-rock-5b.dts | 19 +
arch/arm64/boot/dts/rockchip/rk3588.dtsi | 56 +
drivers/clk/rockchip/rst-rk3588.c | 1 +
drivers/media/platform/Kconfig | 1 +
drivers/media/platform/Makefile | 1 +
drivers/media/platform/synopsys/Kconfig | 3 +
drivers/media/platform/synopsys/Makefile | 2 +
.../media/platform/synopsys/hdmirx/Kconfig | 18 +
.../media/platform/synopsys/hdmirx/Makefile | 4 +
.../platform/synopsys/hdmirx/snps_hdmirx.c | 2726 +++++++++++++++++
.../platform/synopsys/hdmirx/snps_hdmirx.h | 394 +++
.../synopsys/hdmirx/snps_hdmirx_cec.c | 289 ++
.../synopsys/hdmirx/snps_hdmirx_cec.h | 46 +
.../dt-bindings/reset/rockchip,rk3588-cru.h | 2 +
17 files changed, 3743 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/snps,dw-hdmi-rx.yaml
create mode 100644 drivers/media/platform/synopsys/Kconfig
create mode 100644 drivers/media/platform/synopsys/Makefile
create mode 100644 drivers/media/platform/synopsys/hdmirx/Kconfig
create mode 100644 drivers/media/platform/synopsys/hdmirx/Makefile
create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.c
create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx.h
create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.c
create mode 100644 drivers/media/platform/synopsys/hdmirx/snps_hdmirx_cec.h
--
2.39.2
^ permalink raw reply
* Re: [PATCH] media: dt-bindings: ovti,ov2680: Document clock/data-lanes
From: Sakari Ailus @ 2024-03-27 22:30 UTC (permalink / raw)
To: Fabio Estevam
Cc: rmfrfs, robh, krzysztof.kozlowski+dt, conor+dt, linux-media,
devicetree, Fabio Estevam
In-Reply-To: <CAOMZO5AYjNPWZfy_dN12K9JNwWaWThpMs0W-FzETF5k8fobgeg@mail.gmail.com>
On Wed, Mar 27, 2024 at 11:50:26AM -0300, Fabio Estevam wrote:
> Hi Sakari,
>
> On Wed, Mar 27, 2024 at 6:58 AM Sakari Ailus
> <sakari.ailus@linux.intel.com> wrote:
>
> > If there's a single possible configuration only, is this needed? There's no
> > information here which the driver would need.
>
> Good point.
>
> In this case, the correct fix would be to remove 'clock-lanes' and
> 'data-lanes' from imx7s-warp.dts.
Agreed.
--
Sakari Ailus
^ permalink raw reply
* [PATCH 09/23] media: i2c: imx258: Add support for running on 2 CSI data lanes
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x, Luigi311
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Extends the driver to also support 2 data lanes.
Frame rates are obviously more restricted on 2 lanes, but some
hardware simply hasn't wired more up.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Luigi311 <git@luigi311.com>
---
drivers/media/i2c/imx258.c | 214 ++++++++++++++++++++++++++++++++-----
1 file changed, 190 insertions(+), 24 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 6ee7de079454..c65b9aad3b0a 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -86,12 +86,18 @@ struct imx258_reg_list {
const struct imx258_reg *regs;
};
+enum {
+ IMX258_2_LANE_MODE,
+ IMX258_4_LANE_MODE,
+ IMX258_LANE_CONFIGS,
+};
+
/* Link frequency config */
struct imx258_link_freq_config {
u32 pixels_per_line;
/* PLL registers for this link frequency */
- struct imx258_reg_list reg_list;
+ struct imx258_reg_list reg_list[IMX258_LANE_CONFIGS];
};
/* Mode : resolution and related config&values */
@@ -111,8 +117,34 @@ struct imx258_mode {
struct imx258_reg_list reg_list;
};
-/* 4208x3120 needs 1267Mbps/lane, 4 lanes */
-static const struct imx258_reg mipi_1267mbps_19_2mhz[] = {
+/*
+ * 4208x3120 @ 30 fps needs 1267Mbps/lane, 4 lanes.
+ * To avoid further computation of clock settings, adopt the same per
+ * lane data rate when using 2 lanes, thus allowing a maximum of 15fps.
+ */
+static const struct imx258_reg mipi_1267mbps_19_2mhz_2l[] = {
+ { 0x0136, 0x13 },
+ { 0x0137, 0x33 },
+ { 0x0301, 0x0A },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x03 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0xC6 },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+
+ { 0x0114, 0x01 },
+ { 0x0820, 0x09 },
+ { 0x0821, 0xa6 },
+ { 0x0822, 0x66 },
+ { 0x0823, 0x66 },
+};
+
+static const struct imx258_reg mipi_1267mbps_19_2mhz_4l[] = {
{ 0x0136, 0x13 },
{ 0x0137, 0x33 },
{ 0x0301, 0x05 },
@@ -126,16 +158,18 @@ static const struct imx258_reg mipi_1267mbps_19_2mhz[] = {
{ 0x030E, 0x00 },
{ 0x030F, 0xD8 },
{ 0x0310, 0x00 },
+
+ { 0x0114, 0x03 },
{ 0x0820, 0x13 },
{ 0x0821, 0x4C },
{ 0x0822, 0xCC },
{ 0x0823, 0xCC },
};
-static const struct imx258_reg mipi_1272mbps_24mhz[] = {
+static const struct imx258_reg mipi_1272mbps_24mhz_2l[] = {
{ 0x0136, 0x18 },
{ 0x0137, 0x00 },
- { 0x0301, 0x05 },
+ { 0x0301, 0x0a },
{ 0x0303, 0x02 },
{ 0x0305, 0x04 },
{ 0x0306, 0x00 },
@@ -146,13 +180,59 @@ static const struct imx258_reg mipi_1272mbps_24mhz[] = {
{ 0x030E, 0x00 },
{ 0x030F, 0xD8 },
{ 0x0310, 0x00 },
+
+ { 0x0114, 0x01 },
{ 0x0820, 0x13 },
{ 0x0821, 0x4C },
{ 0x0822, 0xCC },
{ 0x0823, 0xCC },
};
-static const struct imx258_reg mipi_640mbps_19_2mhz[] = {
+static const struct imx258_reg mipi_1272mbps_24mhz_4l[] = {
+ { 0x0136, 0x18 },
+ { 0x0137, 0x00 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x04 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0xD4 },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+
+ { 0x0114, 0x03 },
+ { 0x0820, 0x13 },
+ { 0x0821, 0xE0 },
+ { 0x0822, 0x00 },
+ { 0x0823, 0x00 },
+};
+
+static const struct imx258_reg mipi_640mbps_19_2mhz_2l[] = {
+ { 0x0136, 0x13 },
+ { 0x0137, 0x33 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x03 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0x64 },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+
+ { 0x0114, 0x01 },
+ { 0x0820, 0x05 },
+ { 0x0821, 0x00 },
+ { 0x0822, 0x00 },
+ { 0x0823, 0x00 },
+};
+
+static const struct imx258_reg mipi_640mbps_19_2mhz_4l[] = {
{ 0x0136, 0x13 },
{ 0x0137, 0x33 },
{ 0x0301, 0x05 },
@@ -166,13 +246,37 @@ static const struct imx258_reg mipi_640mbps_19_2mhz[] = {
{ 0x030E, 0x00 },
{ 0x030F, 0xD8 },
{ 0x0310, 0x00 },
+
+ { 0x0114, 0x03 },
+ { 0x0820, 0x0A },
+ { 0x0821, 0x00 },
+ { 0x0822, 0x00 },
+ { 0x0823, 0x00 },
+};
+
+static const struct imx258_reg mipi_642mbps_24mhz_2l[] = {
+ { 0x0136, 0x18 },
+ { 0x0137, 0x00 },
+ { 0x0301, 0x0A },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x04 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0x6B },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+
+ { 0x0114, 0x01 },
{ 0x0820, 0x0A },
{ 0x0821, 0x00 },
{ 0x0822, 0x00 },
{ 0x0823, 0x00 },
};
-static const struct imx258_reg mipi_642mbps_24mhz[] = {
+static const struct imx258_reg mipi_642mbps_24mhz_4l[] = {
{ 0x0136, 0x18 },
{ 0x0137, 0x00 },
{ 0x0301, 0x05 },
@@ -186,6 +290,8 @@ static const struct imx258_reg mipi_642mbps_24mhz[] = {
{ 0x030E, 0x00 },
{ 0x030F, 0xD8 },
{ 0x0310, 0x00 },
+
+ { 0x0114, 0x03 },
{ 0x0820, 0x0A },
{ 0x0821, 0x00 },
{ 0x0822, 0x00 },
@@ -240,7 +346,6 @@ static const struct imx258_reg mode_common_regs[] = {
{ 0x5F05, 0xED },
{ 0x0112, 0x0A },
{ 0x0113, 0x0A },
- { 0x0114, 0x03 },
{ 0x0342, 0x14 },
{ 0x0343, 0xE8 },
{ 0x0344, 0x00 },
@@ -359,11 +464,13 @@ enum {
/*
* pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
- * data rate => double data rate; number of lanes => 4; bits per pixel => 10
+ * data rate => double data rate;
+ * number of lanes => (configurable 2 or 4);
+ * bits per pixel => 10
*/
-static u64 link_freq_to_pixel_rate(u64 f)
+static u64 link_freq_to_pixel_rate(u64 f, unsigned int nlanes)
{
- f *= 2 * 4;
+ f *= 2 * nlanes;
do_div(f, 10);
return f;
@@ -393,15 +500,27 @@ static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz),
- .regs = mipi_1267mbps_19_2mhz,
+ [IMX258_2_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz_2l),
+ .regs = mipi_1267mbps_19_2mhz_2l,
+ },
+ [IMX258_4_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz_4l),
+ .regs = mipi_1267mbps_19_2mhz_4l,
+ },
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz),
- .regs = mipi_640mbps_19_2mhz,
+ [IMX258_2_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz_2l),
+ .regs = mipi_640mbps_19_2mhz_2l,
+ },
+ [IMX258_4_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz_4l),
+ .regs = mipi_640mbps_19_2mhz_4l,
+ },
}
},
};
@@ -410,15 +529,27 @@ static const struct imx258_link_freq_config link_freq_configs_24[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz),
- .regs = mipi_1272mbps_24mhz,
+ [IMX258_2_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz_2l),
+ .regs = mipi_1272mbps_24mhz_2l,
+ },
+ [IMX258_4_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz_4l),
+ .regs = mipi_1272mbps_24mhz_4l,
+ },
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz),
- .regs = mipi_642mbps_24mhz,
+ [IMX258_2_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz_2l),
+ .regs = mipi_642mbps_24mhz_2l,
+ },
+ [IMX258_4_LANE_MODE] = {
+ .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz_4l),
+ .regs = mipi_642mbps_24mhz_4l,
+ },
}
},
};
@@ -477,6 +608,7 @@ struct imx258 {
const struct imx258_link_freq_config *link_freq_configs;
const s64 *link_freq_menu_items;
+ unsigned int nlanes;
/*
* Mutex for serialized access:
@@ -782,7 +914,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
- pixel_rate = link_freq_to_pixel_rate(link_freq);
+ pixel_rate = link_freq_to_pixel_rate(link_freq, imx258->nlanes);
__v4l2_ctrl_s_ctrl_int64(imx258->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
vblank_def = imx258->cur_mode->vts_def -
@@ -811,11 +943,13 @@ static int imx258_start_streaming(struct imx258 *imx258)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
const struct imx258_reg_list *reg_list;
+ const struct imx258_link_freq_config *link_freq_cfg;
int ret, link_freq_index;
/* Setup PLL */
link_freq_index = imx258->cur_mode->link_freq_index;
- reg_list = &imx258->link_freq_configs[link_freq_index].reg_list;
+ link_freq_cfg = &imx258->link_freq_configs[link_freq_index];
+ reg_list = &link_freq_cfg->reg_list[imx258->nlanes == 2 ? 0 : 1];
ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
if (ret) {
dev_err(&client->dev, "%s failed to set plls\n", __func__);
@@ -1033,9 +1167,11 @@ static int imx258_init_controls(struct imx258 *imx258)
vflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
pixel_rate_max =
- link_freq_to_pixel_rate(imx258->link_freq_menu_items[0]);
+ link_freq_to_pixel_rate(imx258->link_freq_menu_items[0],
+ imx258->nlanes);
pixel_rate_min =
- link_freq_to_pixel_rate(imx258->link_freq_menu_items[1]);
+ link_freq_to_pixel_rate(imx258->link_freq_menu_items[1],
+ imx258->nlanes);
/* By default, PIXEL_RATE is read only */
imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
V4L2_CID_PIXEL_RATE,
@@ -1132,6 +1268,10 @@ static int imx258_get_regulators(struct imx258 *imx258,
static int imx258_probe(struct i2c_client *client)
{
struct imx258 *imx258;
+ struct fwnode_handle *endpoint;
+ struct v4l2_fwnode_endpoint ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
int ret;
u32 val = 0;
@@ -1172,13 +1312,35 @@ static int imx258_probe(struct i2c_client *client)
return -EINVAL;
}
+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+ if (!endpoint) {
+ dev_err(&client->dev, "Endpoint node not found\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
+ fwnode_handle_put(endpoint);
+ if (ret) {
+ dev_err(&client->dev, "Parsing endpoint node failed\n");
+ return ret;
+ }
+
+ /* Get number of data lanes */
+ imx258->nlanes = ep.bus.mipi_csi2.num_data_lanes;
+ if (imx258->nlanes != 2 && imx258->nlanes != 4) {
+ dev_err(&client->dev, "Invalid data lanes: %u\n",
+ imx258->nlanes);
+ ret = -EINVAL;
+ goto error_endpoint_free;
+ }
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
/* Will be powered off via pm_runtime_idle */
ret = imx258_power_on(&client->dev);
if (ret)
- return ret;
+ goto error_endpoint_free;
/* Check module identity */
ret = imx258_identify_module(imx258);
@@ -1211,6 +1373,7 @@ static int imx258_probe(struct i2c_client *client)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
+ v4l2_fwnode_endpoint_free(&ep);
return 0;
@@ -1223,6 +1386,9 @@ static int imx258_probe(struct i2c_client *client)
error_identify:
imx258_power_off(&client->dev);
+error_endpoint_free:
+ v4l2_fwnode_endpoint_free(&ep);
+
return ret;
}
--
2.42.0
^ permalink raw reply related
* [PATCH 10/23] media: i2c: imx258: Follow normal V4L2 behaviours for clipping exposure
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
V4L2 sensor drivers are expected are expected to clip the supported
exposure range based on the VBLANK configured.
IMX258 wasn't doing that as register 0x350 (FRM_LENGTH_CTL)
switches it to a mode where frame length tracks coarse exposure time.
Disable this mode and clip the range for V4L2_CID_EXPOSURE appropriately
based on V4L2_CID_VBLANK.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
drivers/media/i2c/imx258.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index c65b9aad3b0a..1f5fb980cfbe 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -37,10 +37,11 @@
/* Exposure control */
#define IMX258_REG_EXPOSURE 0x0202
+#define IMX258_EXPOSURE_OFFSET 10
#define IMX258_EXPOSURE_MIN 4
#define IMX258_EXPOSURE_STEP 1
#define IMX258_EXPOSURE_DEFAULT 0x640
-#define IMX258_EXPOSURE_MAX 65535
+#define IMX258_EXPOSURE_MAX (IMX258_VTS_MAX - IMX258_EXPOSURE_OFFSET)
/* Analog gain control */
#define IMX258_REG_ANALOG_GAIN 0x0204
@@ -371,7 +372,7 @@ static const struct imx258_reg mode_common_regs[] = {
{ 0x303A, 0x00 },
{ 0x303B, 0x10 },
{ 0x300D, 0x00 },
- { 0x0350, 0x01 },
+ { 0x0350, 0x00 },
{ 0x0204, 0x00 },
{ 0x0205, 0x00 },
{ 0x020E, 0x01 },
@@ -741,6 +742,19 @@ static int imx258_update_digital_gain(struct imx258 *imx258, u32 len, u32 val)
return 0;
}
+static void imx258_adjust_exposure_range(struct imx258 *imx258)
+{
+ int exposure_max, exposure_def;
+
+ /* Honour the VBLANK limits when setting exposure. */
+ exposure_max = imx258->cur_mode->height + imx258->vblank->val -
+ IMX258_EXPOSURE_OFFSET;
+ exposure_def = min(exposure_max, imx258->exposure->val);
+ __v4l2_ctrl_modify_range(imx258->exposure, imx258->exposure->minimum,
+ exposure_max, imx258->exposure->step,
+ exposure_def);
+}
+
static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx258 *imx258 =
@@ -748,6 +762,13 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
int ret = 0;
+ /*
+ * The VBLANK control may change the limits of usable exposure, so check
+ * and adjust if necessary.
+ */
+ if (ctrl->id == V4L2_CID_VBLANK)
+ imx258_adjust_exposure_range(imx258);
+
/*
* Applying V4L2 control value only happens
* when power is up for streaming
--
2.42.0
^ permalink raw reply related
* [PATCH 08/23] media: i2c: imx258: Add support for 24MHz clock
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x, Luigi311
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
There's no reason why only a clock of 19.2MHz is supported.
Indeed this isn't even a frequency listed in the datasheet.
Add support for 24MHz as well.
The PLL settings result in slightly different link frequencies,
so parameterise those.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Luigi311 <git@luigi311.com>
---
drivers/media/i2c/imx258.c | 133 +++++++++++++++++++++++++++++--------
1 file changed, 107 insertions(+), 26 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 351add1bc5d5..6ee7de079454 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -76,9 +76,6 @@
#define REG_CONFIG_MIRROR_FLIP 0x03
#define REG_CONFIG_FLIP_TEST_PATTERN 0x02
-/* Input clock frequency in Hz */
-#define IMX258_INPUT_CLOCK_FREQ 19200000
-
struct imx258_reg {
u16 address;
u8 val;
@@ -115,7 +112,9 @@ struct imx258_mode {
};
/* 4208x3120 needs 1267Mbps/lane, 4 lanes */
-static const struct imx258_reg mipi_data_rate_1267mbps[] = {
+static const struct imx258_reg mipi_1267mbps_19_2mhz[] = {
+ { 0x0136, 0x13 },
+ { 0x0137, 0x33 },
{ 0x0301, 0x05 },
{ 0x0303, 0x02 },
{ 0x0305, 0x03 },
@@ -133,7 +132,29 @@ static const struct imx258_reg mipi_data_rate_1267mbps[] = {
{ 0x0823, 0xCC },
};
-static const struct imx258_reg mipi_data_rate_640mbps[] = {
+static const struct imx258_reg mipi_1272mbps_24mhz[] = {
+ { 0x0136, 0x18 },
+ { 0x0137, 0x00 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x04 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0xD4 },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+ { 0x0820, 0x13 },
+ { 0x0821, 0x4C },
+ { 0x0822, 0xCC },
+ { 0x0823, 0xCC },
+};
+
+static const struct imx258_reg mipi_640mbps_19_2mhz[] = {
+ { 0x0136, 0x13 },
+ { 0x0137, 0x33 },
{ 0x0301, 0x05 },
{ 0x0303, 0x02 },
{ 0x0305, 0x03 },
@@ -151,9 +172,27 @@ static const struct imx258_reg mipi_data_rate_640mbps[] = {
{ 0x0823, 0x00 },
};
+static const struct imx258_reg mipi_642mbps_24mhz[] = {
+ { 0x0136, 0x18 },
+ { 0x0137, 0x00 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x04 },
+ { 0x0306, 0x00 },
+ { 0x0307, 0x6B },
+ { 0x0309, 0x0A },
+ { 0x030B, 0x01 },
+ { 0x030D, 0x02 },
+ { 0x030E, 0x00 },
+ { 0x030F, 0xD8 },
+ { 0x0310, 0x00 },
+ { 0x0820, 0x0A },
+ { 0x0821, 0x00 },
+ { 0x0822, 0x00 },
+ { 0x0823, 0x00 },
+};
+
static const struct imx258_reg mode_common_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
{ 0x3051, 0x00 },
{ 0x3052, 0x00 },
{ 0x4E21, 0x14 },
@@ -313,10 +352,6 @@ static const char * const imx258_supply_name[] = {
#define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name)
-/* Configurations for supported link frequencies */
-#define IMX258_LINK_FREQ_634MHZ 633600000ULL
-#define IMX258_LINK_FREQ_320MHZ 320000000ULL
-
enum {
IMX258_LINK_FREQ_1267MBPS,
IMX258_LINK_FREQ_640MBPS,
@@ -335,25 +370,55 @@ static u64 link_freq_to_pixel_rate(u64 f)
}
/* Menu items for LINK_FREQ V4L2 control */
-static const s64 link_freq_menu_items[] = {
+/* Configurations for supported link frequencies */
+#define IMX258_LINK_FREQ_634MHZ 633600000ULL
+#define IMX258_LINK_FREQ_320MHZ 320000000ULL
+
+static const s64 link_freq_menu_items_19_2[] = {
IMX258_LINK_FREQ_634MHZ,
IMX258_LINK_FREQ_320MHZ,
};
+/* Configurations for supported link frequencies */
+#define IMX258_LINK_FREQ_636MHZ 636000000ULL
+#define IMX258_LINK_FREQ_321MHZ 321000000ULL
+
+static const s64 link_freq_menu_items_24[] = {
+ IMX258_LINK_FREQ_636MHZ,
+ IMX258_LINK_FREQ_321MHZ,
+};
+
/* Link frequency configs */
-static const struct imx258_link_freq_config link_freq_configs[] = {
+static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_data_rate_1267mbps),
- .regs = mipi_data_rate_1267mbps,
+ .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz),
+ .regs = mipi_1267mbps_19_2mhz,
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_data_rate_640mbps),
- .regs = mipi_data_rate_640mbps,
+ .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz),
+ .regs = mipi_640mbps_19_2mhz,
+ }
+ },
+};
+
+static const struct imx258_link_freq_config link_freq_configs_24[] = {
+ [IMX258_LINK_FREQ_1267MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz),
+ .regs = mipi_1272mbps_24mhz,
+ }
+ },
+ [IMX258_LINK_FREQ_640MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .reg_list = {
+ .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz),
+ .regs = mipi_642mbps_24mhz,
}
},
};
@@ -410,6 +475,9 @@ struct imx258 {
/* Current mode */
const struct imx258_mode *cur_mode;
+ const struct imx258_link_freq_config *link_freq_configs;
+ const s64 *link_freq_menu_items;
+
/*
* Mutex for serialized access:
* Protect sensor module set pad format and start/stop streaming safely.
@@ -713,7 +781,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
imx258->cur_mode = mode;
__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
- link_freq = link_freq_menu_items[mode->link_freq_index];
+ link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
pixel_rate = link_freq_to_pixel_rate(link_freq);
__v4l2_ctrl_s_ctrl_int64(imx258->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
@@ -727,7 +795,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
vblank_def);
__v4l2_ctrl_s_ctrl(imx258->vblank, vblank_def);
h_blank =
- link_freq_configs[mode->link_freq_index].pixels_per_line
+ imx258->link_freq_configs[mode->link_freq_index].pixels_per_line
- imx258->cur_mode->width;
__v4l2_ctrl_modify_range(imx258->hblank, h_blank,
h_blank, 1, h_blank);
@@ -747,7 +815,7 @@ static int imx258_start_streaming(struct imx258 *imx258)
/* Setup PLL */
link_freq_index = imx258->cur_mode->link_freq_index;
- reg_list = &link_freq_configs[link_freq_index].reg_list;
+ reg_list = &imx258->link_freq_configs[link_freq_index].reg_list;
ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
if (ret) {
dev_err(&client->dev, "%s failed to set plls\n", __func__);
@@ -946,9 +1014,9 @@ static int imx258_init_controls(struct imx258 *imx258)
imx258->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx258_ctrl_ops,
V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(link_freq_menu_items) - 1,
+ ARRAY_SIZE(link_freq_menu_items_19_2) - 1,
0,
- link_freq_menu_items);
+ imx258->link_freq_menu_items);
if (imx258->link_freq)
imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
@@ -964,8 +1032,10 @@ static int imx258_init_controls(struct imx258 *imx258)
if (vflip)
vflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
- pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
+ pixel_rate_max =
+ link_freq_to_pixel_rate(imx258->link_freq_menu_items[0]);
+ pixel_rate_min =
+ link_freq_to_pixel_rate(imx258->link_freq_menu_items[1]);
/* By default, PIXEL_RATE is read only */
imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
V4L2_CID_PIXEL_RATE,
@@ -1086,8 +1156,19 @@ static int imx258_probe(struct i2c_client *client)
} else {
val = clk_get_rate(imx258->clk);
}
- if (val != IMX258_INPUT_CLOCK_FREQ) {
- dev_err(&client->dev, "input clock frequency not supported\n");
+
+ switch (val) {
+ case 19200000:
+ imx258->link_freq_configs = link_freq_configs_19_2;
+ imx258->link_freq_menu_items = link_freq_menu_items_19_2;
+ break;
+ case 24000000:
+ imx258->link_freq_configs = link_freq_configs_24;
+ imx258->link_freq_menu_items = link_freq_menu_items_24;
+ break;
+ default:
+ dev_err(&client->dev, "input clock frequency of %u not supported\n",
+ val);
return -EINVAL;
}
--
2.42.0
^ permalink raw reply related
* [PATCH 07/23] media: i2c: imx258: Split out common registers from the mode based ones
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Out of all the registers that are defined for each mode, only around
10 differ between the modes.
Split the table into common and mode specific ones.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
drivers/media/i2c/imx258.c | 236 ++++---------------------------------
1 file changed, 21 insertions(+), 215 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 321b504c6a48..351add1bc5d5 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -151,7 +151,7 @@ static const struct imx258_reg mipi_data_rate_640mbps[] = {
{ 0x0823, 0x00 },
};
-static const struct imx258_reg mode_4208x3120_regs[] = {
+static const struct imx258_reg mode_common_regs[] = {
{ 0x0136, 0x13 },
{ 0x0137, 0x33 },
{ 0x3051, 0x00 },
@@ -216,27 +216,17 @@ static const struct imx258_reg mode_4208x3120_regs[] = {
{ 0x0383, 0x01 },
{ 0x0385, 0x01 },
{ 0x0387, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0401, 0x00 },
{ 0x0404, 0x00 },
- { 0x0405, 0x10 },
{ 0x0408, 0x00 },
{ 0x0409, 0x00 },
{ 0x040A, 0x00 },
{ 0x040B, 0x00 },
{ 0x040C, 0x10 },
{ 0x040D, 0x70 },
- { 0x040E, 0x0C },
- { 0x040F, 0x30 },
{ 0x3038, 0x00 },
{ 0x303A, 0x00 },
{ 0x303B, 0x10 },
{ 0x300D, 0x00 },
- { 0x034C, 0x10 },
- { 0x034D, 0x70 },
- { 0x034E, 0x0C },
- { 0x034F, 0x30 },
{ 0x0350, 0x01 },
{ 0x0204, 0x00 },
{ 0x0205, 0x00 },
@@ -266,234 +256,43 @@ static const struct imx258_reg mode_4208x3120_regs[] = {
{ 0x0220, 0x00 },
};
+static const struct imx258_reg mode_4208x3120_regs[] = {
+ { 0x0900, 0x00 },
+ { 0x0901, 0x11 },
+ { 0x0401, 0x00 },
+ { 0x0405, 0x10 },
+ { 0x040E, 0x0C },
+ { 0x040F, 0x30 },
+ { 0x034C, 0x10 },
+ { 0x034D, 0x70 },
+ { 0x034E, 0x0C },
+ { 0x034F, 0x30 },
+};
+
static const struct imx258_reg mode_2104_1560_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x3051, 0x00 },
- { 0x3052, 0x00 },
- { 0x4E21, 0x14 },
- { 0x6B11, 0xCF },
- { 0x7FF0, 0x08 },
- { 0x7FF1, 0x0F },
- { 0x7FF2, 0x08 },
- { 0x7FF3, 0x1B },
- { 0x7FF4, 0x23 },
- { 0x7FF5, 0x60 },
- { 0x7FF6, 0x00 },
- { 0x7FF7, 0x01 },
- { 0x7FF8, 0x00 },
- { 0x7FF9, 0x78 },
- { 0x7FFA, 0x00 },
- { 0x7FFB, 0x00 },
- { 0x7FFC, 0x00 },
- { 0x7FFD, 0x00 },
- { 0x7FFE, 0x00 },
- { 0x7FFF, 0x03 },
- { 0x7F76, 0x03 },
- { 0x7F77, 0xFE },
- { 0x7FA8, 0x03 },
- { 0x7FA9, 0xFE },
- { 0x7B24, 0x81 },
- { 0x7B25, 0x00 },
- { 0x6564, 0x07 },
- { 0x6B0D, 0x41 },
- { 0x653D, 0x04 },
- { 0x6B05, 0x8C },
- { 0x6B06, 0xF9 },
- { 0x6B08, 0x65 },
- { 0x6B09, 0xFC },
- { 0x6B0A, 0xCF },
- { 0x6B0B, 0xD2 },
- { 0x6700, 0x0E },
- { 0x6707, 0x0E },
- { 0x9104, 0x00 },
- { 0x4648, 0x7F },
- { 0x7420, 0x00 },
- { 0x7421, 0x1C },
- { 0x7422, 0x00 },
- { 0x7423, 0xD7 },
- { 0x5F04, 0x00 },
- { 0x5F05, 0xED },
- { 0x0112, 0x0A },
- { 0x0113, 0x0A },
- { 0x0114, 0x03 },
- { 0x0342, 0x14 },
- { 0x0343, 0xE8 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x10 },
- { 0x0349, 0x6F },
- { 0x034A, 0x0C },
- { 0x034B, 0x2F },
- { 0x0381, 0x01 },
- { 0x0383, 0x01 },
- { 0x0385, 0x01 },
- { 0x0387, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x12 },
{ 0x0401, 0x01 },
- { 0x0404, 0x00 },
{ 0x0405, 0x20 },
- { 0x0408, 0x00 },
- { 0x0409, 0x00 },
- { 0x040A, 0x00 },
- { 0x040B, 0x00 },
- { 0x040C, 0x10 },
- { 0x040D, 0x70 },
{ 0x040E, 0x06 },
{ 0x040F, 0x18 },
- { 0x3038, 0x00 },
- { 0x303A, 0x00 },
- { 0x303B, 0x10 },
- { 0x300D, 0x00 },
{ 0x034C, 0x08 },
{ 0x034D, 0x38 },
{ 0x034E, 0x06 },
{ 0x034F, 0x18 },
- { 0x0350, 0x01 },
- { 0x0204, 0x00 },
- { 0x0205, 0x00 },
- { 0x020E, 0x01 },
- { 0x020F, 0x00 },
- { 0x0210, 0x01 },
- { 0x0211, 0x00 },
- { 0x0212, 0x01 },
- { 0x0213, 0x00 },
- { 0x0214, 0x01 },
- { 0x0215, 0x00 },
- { 0x7BCD, 0x01 },
- { 0x94DC, 0x20 },
- { 0x94DD, 0x20 },
- { 0x94DE, 0x20 },
- { 0x95DC, 0x20 },
- { 0x95DD, 0x20 },
- { 0x95DE, 0x20 },
- { 0x7FB0, 0x00 },
- { 0x9010, 0x3E },
- { 0x9419, 0x50 },
- { 0x941B, 0x50 },
- { 0x9519, 0x50 },
- { 0x951B, 0x50 },
- { 0x3030, 0x00 },
- { 0x3032, 0x00 },
- { 0x0220, 0x00 },
};
static const struct imx258_reg mode_1048_780_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x3051, 0x00 },
- { 0x3052, 0x00 },
- { 0x4E21, 0x14 },
- { 0x6B11, 0xCF },
- { 0x7FF0, 0x08 },
- { 0x7FF1, 0x0F },
- { 0x7FF2, 0x08 },
- { 0x7FF3, 0x1B },
- { 0x7FF4, 0x23 },
- { 0x7FF5, 0x60 },
- { 0x7FF6, 0x00 },
- { 0x7FF7, 0x01 },
- { 0x7FF8, 0x00 },
- { 0x7FF9, 0x78 },
- { 0x7FFA, 0x00 },
- { 0x7FFB, 0x00 },
- { 0x7FFC, 0x00 },
- { 0x7FFD, 0x00 },
- { 0x7FFE, 0x00 },
- { 0x7FFF, 0x03 },
- { 0x7F76, 0x03 },
- { 0x7F77, 0xFE },
- { 0x7FA8, 0x03 },
- { 0x7FA9, 0xFE },
- { 0x7B24, 0x81 },
- { 0x7B25, 0x00 },
- { 0x6564, 0x07 },
- { 0x6B0D, 0x41 },
- { 0x653D, 0x04 },
- { 0x6B05, 0x8C },
- { 0x6B06, 0xF9 },
- { 0x6B08, 0x65 },
- { 0x6B09, 0xFC },
- { 0x6B0A, 0xCF },
- { 0x6B0B, 0xD2 },
- { 0x6700, 0x0E },
- { 0x6707, 0x0E },
- { 0x9104, 0x00 },
- { 0x4648, 0x7F },
- { 0x7420, 0x00 },
- { 0x7421, 0x1C },
- { 0x7422, 0x00 },
- { 0x7423, 0xD7 },
- { 0x5F04, 0x00 },
- { 0x5F05, 0xED },
- { 0x0112, 0x0A },
- { 0x0113, 0x0A },
- { 0x0114, 0x03 },
- { 0x0342, 0x14 },
- { 0x0343, 0xE8 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x10 },
- { 0x0349, 0x6F },
- { 0x034A, 0x0C },
- { 0x034B, 0x2F },
- { 0x0381, 0x01 },
- { 0x0383, 0x01 },
- { 0x0385, 0x01 },
- { 0x0387, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x14 },
{ 0x0401, 0x01 },
- { 0x0404, 0x00 },
{ 0x0405, 0x40 },
- { 0x0408, 0x00 },
- { 0x0409, 0x00 },
- { 0x040A, 0x00 },
- { 0x040B, 0x00 },
- { 0x040C, 0x10 },
- { 0x040D, 0x70 },
{ 0x040E, 0x03 },
{ 0x040F, 0x0C },
- { 0x3038, 0x00 },
- { 0x303A, 0x00 },
- { 0x303B, 0x10 },
- { 0x300D, 0x00 },
{ 0x034C, 0x04 },
{ 0x034D, 0x18 },
{ 0x034E, 0x03 },
{ 0x034F, 0x0C },
- { 0x0350, 0x01 },
- { 0x0204, 0x00 },
- { 0x0205, 0x00 },
- { 0x020E, 0x01 },
- { 0x020F, 0x00 },
- { 0x0210, 0x01 },
- { 0x0211, 0x00 },
- { 0x0212, 0x01 },
- { 0x0213, 0x00 },
- { 0x0214, 0x01 },
- { 0x0215, 0x00 },
- { 0x7BCD, 0x00 },
- { 0x94DC, 0x20 },
- { 0x94DD, 0x20 },
- { 0x94DE, 0x20 },
- { 0x95DC, 0x20 },
- { 0x95DD, 0x20 },
- { 0x95DE, 0x20 },
- { 0x7FB0, 0x00 },
- { 0x9010, 0x3E },
- { 0x9419, 0x50 },
- { 0x941B, 0x50 },
- { 0x9519, 0x50 },
- { 0x951B, 0x50 },
- { 0x3030, 0x00 },
- { 0x3032, 0x00 },
- { 0x0220, 0x00 },
};
static const char * const imx258_test_pattern_menu[] = {
@@ -955,6 +754,13 @@ static int imx258_start_streaming(struct imx258 *imx258)
return ret;
}
+ ret = imx258_write_regs(imx258, mode_common_regs,
+ ARRAY_SIZE(mode_common_regs));
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set common regs\n", __func__);
+ return ret;
+ }
+
/* Apply default values of current mode */
reg_list = &imx258->cur_mode->reg_list;
ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
--
2.42.0
^ permalink raw reply related
* [PATCH 06/23] media: i2c: imx258: Make V4L2_CID_VBLANK configurable.
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
The values and ranges of V4L2_CID_VBLANK are all computed,
so there is no reason for it to be a read only control.
Remove the register values from the mode lists, add the
handler, and remove the read only flag.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx258.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 495eaada2945..321b504c6a48 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -30,6 +30,8 @@
#define IMX258_VTS_30FPS_VGA 0x034c
#define IMX258_VTS_MAX 0xffff
+#define IMX258_REG_VTS 0x0340
+
/* HBLANK control - read only */
#define IMX258_PPL_DEFAULT 5352
@@ -202,8 +204,6 @@ static const struct imx258_reg mode_4208x3120_regs[] = {
{ 0x0114, 0x03 },
{ 0x0342, 0x14 },
{ 0x0343, 0xE8 },
- { 0x0340, 0x0C },
- { 0x0341, 0x50 },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
@@ -319,8 +319,6 @@ static const struct imx258_reg mode_2104_1560_regs[] = {
{ 0x0114, 0x03 },
{ 0x0342, 0x14 },
{ 0x0343, 0xE8 },
- { 0x0340, 0x06 },
- { 0x0341, 0x38 },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
@@ -436,8 +434,6 @@ static const struct imx258_reg mode_1048_780_regs[] = {
{ 0x0114, 0x03 },
{ 0x0342, 0x14 },
{ 0x0343, 0xE8 },
- { 0x0340, 0x03 },
- { 0x0341, 0x4C },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
@@ -800,6 +796,11 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
BIT(IMX258_HDR_RATIO_MAX));
}
break;
+ case V4L2_CID_VBLANK:
+ ret = imx258_write_reg(imx258, IMX258_REG_VTS,
+ IMX258_REG_VALUE_16BIT,
+ imx258->cur_mode->height + ctrl->val);
+ break;
default:
dev_info(&client->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
@@ -1174,9 +1175,6 @@ static int imx258_init_controls(struct imx258 *imx258)
IMX258_VTS_MAX - imx258->cur_mode->height, 1,
vblank_def);
- if (imx258->vblank)
- imx258->vblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
imx258->hblank = v4l2_ctrl_new_std(
ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_HBLANK,
IMX258_PPL_DEFAULT - imx258->cur_mode->width,
--
2.42.0
^ permalink raw reply related
* [PATCH 04/23] media: i2c: imx258: Remove redundant I2C writes.
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
Registers 0x0202 and 0x0203 are written via the control handler
for V4L2_CID_EXPOSURE, so are not needed from the mode lists.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
drivers/media/i2c/imx258.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 0ae4371940ca..df7ed4716762 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -237,8 +237,6 @@ static const struct imx258_reg mode_4208x3120_regs[] = {
{ 0x034E, 0x0C },
{ 0x034F, 0x30 },
{ 0x0350, 0x01 },
- { 0x0202, 0x0C },
- { 0x0203, 0x46 },
{ 0x0204, 0x00 },
{ 0x0205, 0x00 },
{ 0x020E, 0x01 },
@@ -356,8 +354,6 @@ static const struct imx258_reg mode_2104_1560_regs[] = {
{ 0x034E, 0x06 },
{ 0x034F, 0x18 },
{ 0x0350, 0x01 },
- { 0x0202, 0x06 },
- { 0x0203, 0x2E },
{ 0x0204, 0x00 },
{ 0x0205, 0x00 },
{ 0x020E, 0x01 },
@@ -475,8 +471,6 @@ static const struct imx258_reg mode_1048_780_regs[] = {
{ 0x034E, 0x03 },
{ 0x034F, 0x0C },
{ 0x0350, 0x01 },
- { 0x0202, 0x03 },
- { 0x0203, 0x42 },
{ 0x0204, 0x00 },
{ 0x0205, 0x00 },
{ 0x020E, 0x01 },
--
2.42.0
^ permalink raw reply related
* [PATCH 05/23] media: i2c: imx258: Add regulator control
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x, Luigi311
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
The device tree bindings define the relevant regulators for the
sensor, so update the driver to request the regulators and control
them at the appropriate times.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Luigi311 <git@luigi311.com>
---
drivers/media/i2c/imx258.c | 42 +++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index df7ed4716762..495eaada2945 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -7,6 +7,7 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -507,6 +508,16 @@ static const char * const imx258_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
+/* regulator supplies */
+static const char * const imx258_supply_name[] = {
+ /* Supplies can be enabled in any order */
+ "vana", /* Analog (2.8V) supply */
+ "vdig", /* Digital Core (1.2V) supply */
+ "vif", /* IF (1.8V) supply */
+};
+
+#define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name)
+
/* Configurations for supported link frequencies */
#define IMX258_LINK_FREQ_634MHZ 633600000ULL
#define IMX258_LINK_FREQ_320MHZ 320000000ULL
@@ -611,6 +622,7 @@ struct imx258 {
struct mutex mutex;
struct clk *clk;
+ struct regulator_bulk_data supplies[IMX258_NUM_SUPPLIES];
};
static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd)
@@ -995,9 +1007,19 @@ static int imx258_power_on(struct device *dev)
struct imx258 *imx258 = to_imx258(sd);
int ret;
+ ret = regulator_bulk_enable(IMX258_NUM_SUPPLIES,
+ imx258->supplies);
+ if (ret) {
+ dev_err(dev, "%s: failed to enable regulators\n",
+ __func__);
+ return ret;
+ }
+
ret = clk_prepare_enable(imx258->clk);
- if (ret)
+ if (ret) {
dev_err(dev, "failed to enable clock\n");
+ regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
+ }
return ret;
}
@@ -1008,6 +1030,7 @@ static int imx258_power_off(struct device *dev)
struct imx258 *imx258 = to_imx258(sd);
clk_disable_unprepare(imx258->clk);
+ regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
return 0;
}
@@ -1220,6 +1243,18 @@ static void imx258_free_controls(struct imx258 *imx258)
mutex_destroy(&imx258->mutex);
}
+static int imx258_get_regulators(struct imx258 *imx258,
+ struct i2c_client *client)
+{
+ unsigned int i;
+
+ for (i = 0; i < IMX258_NUM_SUPPLIES; i++)
+ imx258->supplies[i].supply = imx258_supply_name[i];
+
+ return devm_regulator_bulk_get(&client->dev,
+ IMX258_NUM_SUPPLIES, imx258->supplies);
+}
+
static int imx258_probe(struct i2c_client *client)
{
struct imx258 *imx258;
@@ -1230,6 +1265,11 @@ static int imx258_probe(struct i2c_client *client)
if (!imx258)
return -ENOMEM;
+ ret = imx258_get_regulators(imx258, client);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "failed to get regulators\n");
+
imx258->clk = devm_clk_get_optional(&client->dev, NULL);
if (IS_ERR(imx258->clk))
return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
--
2.42.0
^ permalink raw reply related
* [PATCH 03/23] media: i2c: imx258: Disable digital cropping on binned modes
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
The binned modes set DIG_CROP_X_OFFSET and DIG_CROP_IMAGE_WIDTH
to less than the full image, even though the image being captured
is meant to be a scaled version of the full array size.
Reduce X_OFFSET to 0, and increase IMAGE_WIDTH to the full array.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx258.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 4a7048d834c6..0ae4371940ca 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -340,11 +340,11 @@ static const struct imx258_reg mode_2104_1560_regs[] = {
{ 0x0404, 0x00 },
{ 0x0405, 0x20 },
{ 0x0408, 0x00 },
- { 0x0409, 0x02 },
+ { 0x0409, 0x00 },
{ 0x040A, 0x00 },
{ 0x040B, 0x00 },
{ 0x040C, 0x10 },
- { 0x040D, 0x6A },
+ { 0x040D, 0x70 },
{ 0x040E, 0x06 },
{ 0x040F, 0x18 },
{ 0x3038, 0x00 },
@@ -459,11 +459,11 @@ static const struct imx258_reg mode_1048_780_regs[] = {
{ 0x0404, 0x00 },
{ 0x0405, 0x40 },
{ 0x0408, 0x00 },
- { 0x0409, 0x06 },
+ { 0x0409, 0x00 },
{ 0x040A, 0x00 },
{ 0x040B, 0x00 },
{ 0x040C, 0x10 },
- { 0x040D, 0x64 },
+ { 0x040D, 0x70 },
{ 0x040E, 0x03 },
{ 0x040F, 0x0C },
{ 0x3038, 0x00 },
--
2.42.0
^ permalink raw reply related
* [PATCH 01/23] media: i2c: imx258: Remove unused defines
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
The IMX258_FLL_* defines are unused. Remove them.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
drivers/media/i2c/imx258.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index a577afb530b7..2dbafd21dd70 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -29,12 +29,6 @@
#define IMX258_VTS_30FPS_VGA 0x034c
#define IMX258_VTS_MAX 0xffff
-/*Frame Length Line*/
-#define IMX258_FLL_MIN 0x08a6
-#define IMX258_FLL_MAX 0xffff
-#define IMX258_FLL_STEP 1
-#define IMX258_FLL_DEFAULT 0x0c98
-
/* HBLANK control - read only */
#define IMX258_PPL_DEFAULT 5352
--
2.42.0
^ permalink raw reply related
* [PATCH 00/23] v2: imx258 improvement series
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x, Luigi311
From: Luigi311 <git@luigi311.com>
v2 changes:
- Add use macros patch
- Add support for powerdown gpio patch
- Add support for reset gpio patch
- Dropped Add support for long exposure modes patch
- Implemented feedback from Jacopo Mondi
- media: i2c: imx258: Add regulator control
- media: i2c: imx258: Add support for 24MHz clock
- media: i2c: imx258: Add support for running on 2 CSI data lanes
- media: i2c: imx258: Add get_selection for pixel array information
- media: i2c: imx258: Issue reset before starting streaming
- media: i2c: imx258: Set pixel_rate range to the same as the value
- dt-bindings: media: imx258: Add alternate compatible strings
- media: i2c: imx258: Change register settings for variants of the sensor
- media: i2c: imx258: Make HFLIP and VFLIP controls writable
This adds a few more patches and drops one. The long exposure mode patch was
dropped due to the bug that Jacopo found. The powerdown and reset gpio patches
were added as that fixes support for the Pinephone Pro, without them the sensor
doesnt initialize correctly.
Tested on a Pinephone Pro by forcing 24 mhz clock and was able to access all 3
resolutions. The two lower resolutions had some artifacts but that is expected
as more changes are required to fix them for the Pinephone Pro specifically,
kept all registers the same as Dave's original patch since that works on
dedicated imx258 hardware and the artifacts are PPP specific so it shouldnt be
a regression.
v1
This is a set of patches for imx258 that allow it to work with alternate clock
frequencies, over either 2 or 4 lanes, and generally adding flexibility to the
driver.
Tested with an IMX258 module from Soho Enterprises that has a 24MHz oscillator.
Both 2 and 4 lane configurations work with correct link frequencies and pixel
rates.
Jacopo has tested on a PinePhone Pro which has an ~19.2MHz clock fed from the SoC,
He confirms that the two lower resolution modes work, but not the full res mode.
Comparing to the BSP it looks like they have some weird clock configuration in
the 4208x3120 mode (nominally 1224Mb/s/lane instead of 1267).
As it has never previously worked directly with the mainline driver this isn't a
regression but may indicate that there is a need for support of additional link
frequencies in the future.
The last patch that makes HFLIP and VFLIP configurable may be contentious as I've
retained the default configuration of inverted from the original driver. I know
this was discussed recently, but I can't recall the final outcome.
I am relying on someone from Intel testing this out, as correcting the cropping
and supporting flips has changed the Bayer order. Seeing as this is all above
board in V4L2 terms I really hope that the layers above it behave themselves.
Cheers
Dave
Dave Stevenson (20):
media: i2c: imx258: Remove unused defines
media: i2c: imx258: Make image geometry meet sensor requirements
media: i2c: imx258: Disable digital cropping on binned modes
media: i2c: imx258: Remove redundant I2C writes.
media: i2c: imx258: Add regulator control
media: i2c: imx258: Make V4L2_CID_VBLANK configurable.
media: i2c: imx258: Split out common registers from the mode based
ones
media: i2c: imx258: Add support for 24MHz clock
media: i2c: imx258: Add support for running on 2 CSI data lanes
media: i2c: imx258: Follow normal V4L2 behaviours for clipping
exposure
media: i2c: imx258: Add get_selection for pixel array information
media: i2c: imx258: Allow configuration of clock lane behaviour
media: i2c: imx258: Correct max FRM_LENGTH_LINES value
media: i2c: imx258: Issue reset before starting streaming
media: i2c: imx258: Set pixel_rate range to the same as the value
media: i2c: imx258: Support faster pixel rate on binned modes
dt-bindings: media: imx258: Rename to include vendor prefix
dt-bindings: media: imx258: Add alternate compatible strings
media: i2c: imx258: Change register settings for variants of the
sensor
media: i2c: imx258: Make HFLIP and VFLIP controls writable
Luigi311 (3):
drivers: media: i2c: imx258: Use macros
drivers: media: i2c: imx258: Add support for powerdown gpio
drivers: media: i2c: imx258: Add support for reset gpio
.../i2c/{imx258.yaml => sony,imx258.yaml} | 12 +-
MAINTAINERS | 2 +-
drivers/media/i2c/imx258.c | 1147 +++++++++++------
3 files changed, 744 insertions(+), 417 deletions(-)
rename Documentation/devicetree/bindings/media/i2c/{imx258.yaml => sony,imx258.yaml} (88%)
--
2.42.0
^ permalink raw reply
* [PATCH 02/23] media: i2c: imx258: Make image geometry meet sensor requirements
From: git @ 2024-03-27 22:20 UTC (permalink / raw)
To: linux-media
Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
linux-kernel, x
In-Reply-To: <20240327222035.47208-1-git@luigi311.com>
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
The output image is defined as being 4208x3118 pixels in size.
Y_ADD_STA register was set to 0, and Y_ADD_END to 3118, giving
3119 lines total.
The datasheet lists a requirement for Y_ADD_STA to be a multiple
of a power of 2 depending on binning/scaling mode (2 for full pixel,
4 for x2-bin/scale, 8 for (x2-bin)+(x2-subsample) or x4-bin, or 16
for (x4-bin)+(x2-subsample)).
(Y_ADD_END – Y_ADD_STA + 1) also has to be a similar power of 2.
The current configuration for the full res modes breaks that second
requirement, and we can't increase Y_ADD_STA to 1 to retain exactly
the same field of view as that then breaks the first requirement.
For the binned modes, they are worse off as 3118 is not a multiple of
4.
Increase the main mode to 4208x3120 so that it is the same FOV as the
binned modes, with Y_ADD_STA at 0.
Fix Y_ADD_STA and Y_ADD_END for the binned modes so that they meet the
sensor requirements.
This does change the Bayer order as the default configuration is for
H&V flips to be enabled, so readout is from Y_STA_END to Y_ADD_STA,
and this patch has changed Y_STA_END.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
---
drivers/media/i2c/imx258.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index 2dbafd21dd70..4a7048d834c6 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -111,7 +111,7 @@ struct imx258_mode {
struct imx258_reg_list reg_list;
};
-/* 4208x3118 needs 1267Mbps/lane, 4 lanes */
+/* 4208x3120 needs 1267Mbps/lane, 4 lanes */
static const struct imx258_reg mipi_data_rate_1267mbps[] = {
{ 0x0301, 0x05 },
{ 0x0303, 0x02 },
@@ -148,7 +148,7 @@ static const struct imx258_reg mipi_data_rate_640mbps[] = {
{ 0x0823, 0x00 },
};
-static const struct imx258_reg mode_4208x3118_regs[] = {
+static const struct imx258_reg mode_4208x3120_regs[] = {
{ 0x0136, 0x13 },
{ 0x0137, 0x33 },
{ 0x3051, 0x00 },
@@ -210,7 +210,7 @@ static const struct imx258_reg mode_4208x3118_regs[] = {
{ 0x0348, 0x10 },
{ 0x0349, 0x6F },
{ 0x034A, 0x0C },
- { 0x034B, 0x2E },
+ { 0x034B, 0x2F },
{ 0x0381, 0x01 },
{ 0x0383, 0x01 },
{ 0x0385, 0x01 },
@@ -329,7 +329,7 @@ static const struct imx258_reg mode_2104_1560_regs[] = {
{ 0x0348, 0x10 },
{ 0x0349, 0x6F },
{ 0x034A, 0x0C },
- { 0x034B, 0x2E },
+ { 0x034B, 0x2F },
{ 0x0381, 0x01 },
{ 0x0383, 0x01 },
{ 0x0385, 0x01 },
@@ -448,7 +448,7 @@ static const struct imx258_reg mode_1048_780_regs[] = {
{ 0x0348, 0x10 },
{ 0x0349, 0x6F },
{ 0x034A, 0x0C },
- { 0x034B, 0x2E },
+ { 0x034B, 0x2F },
{ 0x0381, 0x01 },
{ 0x0383, 0x01 },
{ 0x0385, 0x01 },
@@ -562,12 +562,12 @@ static const struct imx258_link_freq_config link_freq_configs[] = {
static const struct imx258_mode supported_modes[] = {
{
.width = 4208,
- .height = 3118,
+ .height = 3120,
.vts_def = IMX258_VTS_30FPS,
.vts_min = IMX258_VTS_30FPS,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mode_4208x3118_regs),
- .regs = mode_4208x3118_regs,
+ .num_of_regs = ARRAY_SIZE(mode_4208x3120_regs),
+ .regs = mode_4208x3120_regs,
},
.link_freq_index = IMX258_LINK_FREQ_1267MBPS,
},
@@ -707,7 +707,7 @@ static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
/* Initialize try_fmt */
try_fmt->width = supported_modes[0].width;
try_fmt->height = supported_modes[0].height;
- try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ try_fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
try_fmt->field = V4L2_FIELD_NONE;
return 0;
@@ -819,7 +819,7 @@ static int imx258_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index > 0)
return -EINVAL;
- code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
return 0;
}
@@ -831,7 +831,7 @@ static int imx258_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+ if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10)
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
@@ -847,7 +847,7 @@ static void imx258_update_pad_format(const struct imx258_mode *mode,
{
fmt->format.width = mode->width;
fmt->format.height = mode->height;
- fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
fmt->format.field = V4L2_FIELD_NONE;
}
@@ -894,7 +894,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
mutex_lock(&imx258->mutex);
/* Only one raw bayer(GBRG) order is supported */
- fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
mode = v4l2_find_nearest_size(supported_modes,
ARRAY_SIZE(supported_modes), width, height,
--
2.42.0
^ permalink raw reply related
* Re: [PATCH] of: module: prevent NULL pointer dereference in vsnprintf()
From: Saravana Kannan @ 2024-03-27 22:04 UTC (permalink / raw)
To: Sergey Shtylyov; +Cc: Rob Herring, Frank Rowand, devicetree, lvc-project
In-Reply-To: <1d211023-3923-685b-20f0-f3f90ea56e1f@omp.ru>
On Wed, Mar 27, 2024 at 9:52 AM Sergey Shtylyov <s.shtylyov@omp.ru> wrote:
>
> In of_modalias(), we can get passed the str and len parameters which would
> cause a kernel oops in vsnprintf() since it only allows passing a NULL ptr
> when the length is also 0. Also, we need to filter out the negative values
> of the len parameter as these will result in a really huge buffer since
> snprintf() takes size_t parameter while ours is ssize_t...
>
> Found by Linux Verification Center (linuxtesting.org) with the Svace static
> analysis tool.
>
> Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
>
> ---
> The patch is against the for-next branch of Rob Herring's linux-git repo...
>
> drivers/of/module.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> Index: linux/drivers/of/module.c
> ===================================================================
> --- linux.orig/drivers/of/module.c
> +++ linux/drivers/of/module.c
> @@ -16,6 +16,14 @@ ssize_t of_modalias(const struct device_
> ssize_t csize;
> ssize_t tsize;
>
> + /*
> + * Prevent a kernel oops in vsnprintf() -- it only allows passing a
> + * NULL ptr when the length is also 0. Also filter out the negative
> + * lengths...
> + */
> + if ((len > 0 && !str) || len < 0)
> + return -EINVAL;
> +
Even if vsnprintf() didn't oops, the input doesn't make sense. So, I
think the comment should just say that. Or maybe just delete the
comment since it'd be redundant at that point.
Not a strong opinion.
Acked-by: Saravana Kannan <saravanak@google.com>
-Saravana
> /* Name & Type */
> /* %p eats all alphanum characters, so %c must be used here */
> csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
^ permalink raw reply
* Re: [PATCH] of: module: prevent NULL pointer dereference in vsnprintf()
From: Rob Herring @ 2024-03-27 22:04 UTC (permalink / raw)
To: Sergey Shtylyov
Cc: lvc-project, Rob Herring, Saravana Kannan, Frank Rowand,
devicetree
In-Reply-To: <1d211023-3923-685b-20f0-f3f90ea56e1f@omp.ru>
On Wed, 27 Mar 2024 19:52:49 +0300, Sergey Shtylyov wrote:
> In of_modalias(), we can get passed the str and len parameters which would
> cause a kernel oops in vsnprintf() since it only allows passing a NULL ptr
> when the length is also 0. Also, we need to filter out the negative values
> of the len parameter as these will result in a really huge buffer since
> snprintf() takes size_t parameter while ours is ssize_t...
>
> Found by Linux Verification Center (linuxtesting.org) with the Svace static
> analysis tool.
>
> Signed-off-by: Sergey Shtylyov <s.shtylyov@omp.ru>
>
> ---
> The patch is against the for-next branch of Rob Herring's linux-git repo...
>
> drivers/of/module.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
Applied, thanks!
^ permalink raw reply
* [PATCH v5 7/7] iio: accel: adxl345: Add spi-3wire option
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Add a setup function implementation to the spi module to enable spi-3wire
as option when specified in the device-tree.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345.h | 2 ++
drivers/iio/accel/adxl345_spi.c | 12 +++++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 4ea9341d4..e6bc3591c 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -30,6 +30,8 @@
#define ADXL345_POWER_CTL_MEASURE BIT(3)
#define ADXL345_POWER_CTL_STANDBY 0x00
+#define ADXL345_DATA_FORMAT_SPI_3WIRE BIT(6) /* 3-wire SPI mode */
+
#define ADXL345_DATA_FORMAT_RANGE GENMASK(1, 0) /* Set the g range */
#define ADXL345_DATA_FORMAT_JUSTIFY BIT(2) /* Left-justified (MSB) mode */
#define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
index 1c0513bd3..f145d5c1d 100644
--- a/drivers/iio/accel/adxl345_spi.c
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -20,6 +20,16 @@ static const struct regmap_config adxl345_spi_regmap_config = {
.read_flag_mask = BIT(7) | BIT(6),
};
+static int adxl345_spi_setup(struct device *dev, struct regmap *regmap)
+{
+ struct spi_device *spi = container_of(dev, struct spi_device, dev);
+
+ if (spi->mode & SPI_3WIRE)
+ return regmap_write(regmap, ADXL345_REG_DATA_FORMAT,
+ ADXL345_DATA_FORMAT_SPI_3WIRE);
+ return 0;
+}
+
static int adxl345_spi_probe(struct spi_device *spi)
{
struct regmap *regmap;
@@ -33,7 +43,7 @@ static int adxl345_spi_probe(struct spi_device *spi)
if (IS_ERR(regmap))
return dev_err_probe(&spi->dev, PTR_ERR(regmap), "Error initializing regmap\n");
- return adxl345_core_probe(&spi->dev, regmap, NULL);
+ return adxl345_core_probe(&spi->dev, regmap, adxl345_spi_setup);
}
static const struct adxl345_chip_info adxl345_spi_info = {
--
2.25.1
^ permalink raw reply related
* [PATCH v5 6/7] iio: accel: adxl345: Add comment to probe
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Add a comment to the probe() function to describe the passed function
pointer setup in particular.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345_core.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 40aab7683..0046e8d19 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -168,6 +168,16 @@ static void adxl345_powerdown(void *regmap)
regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
}
+/**
+ * adxl345_core_probe() - probe and setup for the adxl345 accelerometer,
+ * also covers the adlx375 accelerometer
+ * @dev: Driver model representation of the device
+ * @regmap: Regmap instance for the device
+ * @setup: Setup routine to be executed right before the standard device
+ * setup
+ *
+ * Return: 0 on success, negative errno on error
+ */
int adxl345_core_probe(struct device *dev, struct regmap *regmap,
int (*setup)(struct device*, struct regmap*))
{
--
2.25.1
^ permalink raw reply related
* [PATCH v5 5/7] iio: accel: adxl345: Pass function pointer to core
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Add a function pointer argument to the probe function in the core module
to provide a way to pre-configure the bus.
The passed setup function can be prepared in the bus specific spi or the
i2c module, or NULL otherwise. It shall then be executed in the bus
independent core module.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345.h | 3 ++-
drivers/iio/accel/adxl345_core.c | 10 +++++++++-
drivers/iio/accel/adxl345_i2c.c | 2 +-
drivers/iio/accel/adxl345_spi.c | 2 +-
4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 564f7baf1..4ea9341d4 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -65,6 +65,7 @@ struct adxl345_chip_info {
int uscale;
};
-int adxl345_core_probe(struct device *dev, struct regmap *regmap);
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+ int (*setup)(struct device*, struct regmap*));
#endif /* _ADXL345_H_ */
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index c7c1156e8..40aab7683 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -168,13 +168,21 @@ static void adxl345_powerdown(void *regmap)
regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
}
-int adxl345_core_probe(struct device *dev, struct regmap *regmap)
+int adxl345_core_probe(struct device *dev, struct regmap *regmap,
+ int (*setup)(struct device*, struct regmap*))
{
struct adxl345_data *data;
struct iio_dev *indio_dev;
u32 regval;
int ret;
+ /* Perform optional initial bus specific configuration */
+ if (setup) {
+ ret = setup(dev, regmap);
+ if (ret)
+ return ret;
+ }
+
ret = regmap_read(regmap, ADXL345_REG_DEVID, ®val);
if (ret < 0)
return dev_err_probe(dev, ret, "Error reading device ID\n");
diff --git a/drivers/iio/accel/adxl345_i2c.c b/drivers/iio/accel/adxl345_i2c.c
index a3084b0a8..4065b8f7c 100644
--- a/drivers/iio/accel/adxl345_i2c.c
+++ b/drivers/iio/accel/adxl345_i2c.c
@@ -27,7 +27,7 @@ static int adxl345_i2c_probe(struct i2c_client *client)
if (IS_ERR(regmap))
return dev_err_probe(&client->dev, PTR_ERR(regmap), "Error initializing regmap\n");
- return adxl345_core_probe(&client->dev, regmap);
+ return adxl345_core_probe(&client->dev, regmap, NULL);
}
static const struct adxl345_chip_info adxl345_i2c_info = {
diff --git a/drivers/iio/accel/adxl345_spi.c b/drivers/iio/accel/adxl345_spi.c
index 93ca349f1..1c0513bd3 100644
--- a/drivers/iio/accel/adxl345_spi.c
+++ b/drivers/iio/accel/adxl345_spi.c
@@ -33,7 +33,7 @@ static int adxl345_spi_probe(struct spi_device *spi)
if (IS_ERR(regmap))
return dev_err_probe(&spi->dev, PTR_ERR(regmap), "Error initializing regmap\n");
- return adxl345_core_probe(&spi->dev, regmap);
+ return adxl345_core_probe(&spi->dev, regmap, NULL);
}
static const struct adxl345_chip_info adxl345_spi_info = {
--
2.25.1
^ permalink raw reply related
* [PATCH v5 4/7] dt-bindings: iio: accel: adxl345: Add spi-3wire
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Add spi-3wire because the device allows to be configured for spi 3-wire
communication.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
index 07cacc3f6..280ed479e 100644
--- a/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
+++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
@@ -32,6 +32,8 @@ properties:
spi-cpol: true
+ spi-3wire: true
+
interrupts:
maxItems: 1
--
2.25.1
^ permalink raw reply related
* [PATCH v5 3/7] iio: accel: adxl345: Move defines to header
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Move defines to the header file. This keeps the defines block together in
one location, when extended by new shared defines which then have to be
in the header file.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345.h | 37 ++++++++++++++++++++++++++++++++
drivers/iio/accel/adxl345_core.c | 36 -------------------------------
2 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/drivers/iio/accel/adxl345.h b/drivers/iio/accel/adxl345.h
index 284bd387c..564f7baf1 100644
--- a/drivers/iio/accel/adxl345.h
+++ b/drivers/iio/accel/adxl345.h
@@ -8,6 +8,43 @@
#ifndef _ADXL345_H_
#define _ADXL345_H_
+#include <linux/iio/iio.h>
+
+#define ADXL345_REG_DEVID 0x00
+#define ADXL345_REG_OFSX 0x1E
+#define ADXL345_REG_OFSY 0x1F
+#define ADXL345_REG_OFSZ 0x20
+#define ADXL345_REG_OFS_AXIS(index) (ADXL345_REG_OFSX + (index))
+#define ADXL345_REG_BW_RATE 0x2C
+#define ADXL345_REG_POWER_CTL 0x2D
+#define ADXL345_REG_DATA_FORMAT 0x31
+#define ADXL345_REG_DATAX0 0x32
+#define ADXL345_REG_DATAY0 0x34
+#define ADXL345_REG_DATAZ0 0x36
+#define ADXL345_REG_DATA_AXIS(index) \
+ (ADXL345_REG_DATAX0 + (index) * sizeof(__le16))
+
+#define ADXL345_BW_RATE GENMASK(3, 0)
+#define ADXL345_BASE_RATE_NANO_HZ 97656250LL
+
+#define ADXL345_POWER_CTL_MEASURE BIT(3)
+#define ADXL345_POWER_CTL_STANDBY 0x00
+
+#define ADXL345_DATA_FORMAT_RANGE GENMASK(1, 0) /* Set the g range */
+#define ADXL345_DATA_FORMAT_JUSTIFY BIT(2) /* Left-justified (MSB) mode */
+#define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */
+#define ADXL345_DATA_FORMAT_SELF_TEST BIT(7) /* Enable a self test */
+#define ADXL345_DATA_FORMAT_MSK (ADXL345_DATA_FORMAT_RANGE | \
+ ADXL345_DATA_FORMAT_JUSTIFY | \
+ ADXL345_DATA_FORMAT_FULL_RES | \
+ ADXL345_DATA_FORMAT_SELF_TEST)
+#define ADXL345_DATA_FORMAT_2G 0
+#define ADXL345_DATA_FORMAT_4G 1
+#define ADXL345_DATA_FORMAT_8G 2
+#define ADXL345_DATA_FORMAT_16G 3
+
+#define ADXL345_DEVID 0xE5
+
/*
* In full-resolution mode, scale factor is maintained at ~4 mg/LSB
* in all g ranges.
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 5c24ef9ca..c7c1156e8 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -17,42 +17,6 @@
#include "adxl345.h"
-#define ADXL345_REG_DEVID 0x00
-#define ADXL345_REG_OFSX 0x1e
-#define ADXL345_REG_OFSY 0x1f
-#define ADXL345_REG_OFSZ 0x20
-#define ADXL345_REG_OFS_AXIS(index) (ADXL345_REG_OFSX + (index))
-#define ADXL345_REG_BW_RATE 0x2C
-#define ADXL345_REG_POWER_CTL 0x2D
-#define ADXL345_REG_DATA_FORMAT 0x31
-#define ADXL345_REG_DATAX0 0x32
-#define ADXL345_REG_DATAY0 0x34
-#define ADXL345_REG_DATAZ0 0x36
-#define ADXL345_REG_DATA_AXIS(index) \
- (ADXL345_REG_DATAX0 + (index) * sizeof(__le16))
-
-#define ADXL345_BW_RATE GENMASK(3, 0)
-#define ADXL345_BASE_RATE_NANO_HZ 97656250LL
-
-#define ADXL345_POWER_CTL_MEASURE BIT(3)
-#define ADXL345_POWER_CTL_STANDBY 0x00
-
-#define ADXL345_DATA_FORMAT_RANGE GENMASK(1, 0) /* Set the g range */
-#define ADXL345_DATA_FORMAT_JUSTIFY BIT(2) /* Left-justified (MSB) mode */
-#define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */
-#define ADXL345_DATA_FORMAT_SELF_TEST BIT(7) /* Enable a self test */
-#define ADXL345_DATA_FORMAT_MSK (ADXL345_DATA_FORMAT_RANGE | \
- ADXL345_DATA_FORMAT_JUSTIFY | \
- ADXL345_DATA_FORMAT_FULL_RES | \
- ADXL345_DATA_FORMAT_SELF_TEST)
-
-#define ADXL345_DATA_FORMAT_2G 0
-#define ADXL345_DATA_FORMAT_4G 1
-#define ADXL345_DATA_FORMAT_8G 2
-#define ADXL345_DATA_FORMAT_16G 3
-
-#define ADXL345_DEVID 0xE5
-
struct adxl345_data {
const struct adxl345_chip_info *info;
struct regmap *regmap;
--
2.25.1
^ permalink raw reply related
* [PATCH v5 2/7] iio: accel: adxl345: Group bus configuration
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
In the probe function group bus configuration and the indio_dev
initialization to improve readability.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345_core.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 35df5e372..5c24ef9ca 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -229,18 +229,18 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap)
if (!data->info)
return -ENODEV;
- /* Enable full-resolution mode */
- ret = regmap_update_bits(regmap, ADXL345_REG_DATA_FORMAT,
- ADXL345_DATA_FORMAT_MSK, ADXL345_DATA_FORMAT_FULL_RES);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to set data range\n");
-
indio_dev->name = data->info->name;
indio_dev->info = &adxl345_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = adxl345_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
+ /* Enable full-resolution mode */
+ ret = regmap_update_bits(regmap, ADXL345_REG_DATA_FORMAT,
+ ADXL345_DATA_FORMAT_MSK, ADXL345_DATA_FORMAT_FULL_RES);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to set data range\n");
+
/* Enable measurement mode */
ret = adxl345_powerup(data->regmap);
if (ret < 0)
--
2.25.1
^ permalink raw reply related
* [PATCH v5 1/7] iio: accel: adxl345: Make data_range obsolete
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
In-Reply-To: <20240327220320.15509-1-l.rubusch@gmail.com>
Replace write() data_format by regmap_update_bits(), because bus specific
pre-configuration may have happened before on the same register. For
further updates to the data_format register then bus pre-configuration
needs to be masked out.
Remove the data_range field from the struct adxl345_data, because it is
not used anymore.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
drivers/iio/accel/adxl345_core.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 8bd30a23e..35df5e372 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -37,7 +37,15 @@
#define ADXL345_POWER_CTL_MEASURE BIT(3)
#define ADXL345_POWER_CTL_STANDBY 0x00
+#define ADXL345_DATA_FORMAT_RANGE GENMASK(1, 0) /* Set the g range */
+#define ADXL345_DATA_FORMAT_JUSTIFY BIT(2) /* Left-justified (MSB) mode */
#define ADXL345_DATA_FORMAT_FULL_RES BIT(3) /* Up to 13-bits resolution */
+#define ADXL345_DATA_FORMAT_SELF_TEST BIT(7) /* Enable a self test */
+#define ADXL345_DATA_FORMAT_MSK (ADXL345_DATA_FORMAT_RANGE | \
+ ADXL345_DATA_FORMAT_JUSTIFY | \
+ ADXL345_DATA_FORMAT_FULL_RES | \
+ ADXL345_DATA_FORMAT_SELF_TEST)
+
#define ADXL345_DATA_FORMAT_2G 0
#define ADXL345_DATA_FORMAT_4G 1
#define ADXL345_DATA_FORMAT_8G 2
@@ -48,7 +56,6 @@
struct adxl345_data {
const struct adxl345_chip_info *info;
struct regmap *regmap;
- u8 data_range;
};
#define ADXL345_CHANNEL(index, axis) { \
@@ -218,15 +225,14 @@ int adxl345_core_probe(struct device *dev, struct regmap *regmap)
data = iio_priv(indio_dev);
data->regmap = regmap;
- /* Enable full-resolution mode */
- data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
data->info = device_get_match_data(dev);
if (!data->info)
return -ENODEV;
- ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
- data->data_range);
- if (ret < 0)
+ /* Enable full-resolution mode */
+ ret = regmap_update_bits(regmap, ADXL345_REG_DATA_FORMAT,
+ ADXL345_DATA_FORMAT_MSK, ADXL345_DATA_FORMAT_FULL_RES);
+ if (ret)
return dev_err_probe(dev, ret, "Failed to set data range\n");
indio_dev->name = data->info->name;
--
2.25.1
^ permalink raw reply related
* [PATCH v5 0/7] iio: accel: adxl345: Add spi-3wire feature
From: Lothar Rubusch @ 2024-03-27 22:03 UTC (permalink / raw)
To: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt
Cc: linux-iio, devicetree, linux-kernel, eraretuya, l.rubusch
Pass a function setup() as pointer from SPI/I2C specific modules to the
core module. Implement setup() to pass the spi-3wire bus option, if
declared in the device-tree.
In the core module, then update data_format register configuration bits
instead of overwriting it. The changes allow to remove a data_range field.
Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
V1 -> V2: split into spi-3wire and refactoring
V2 -> V3: split further, focus on needed changesets
V3 -> V4: drop "Remove single info instances";
split "Group bus configuration" into separat
comment patch; reorder patch set
V4 -> V5: Refrase comments; Align comments to 75; rebuild FORMAT_MASK by
available flags; fix indention
Lothar Rubusch (7):
iio: accel: adxl345: Make data_range obsolete
iio: accel: adxl345: Group bus configuration
iio: accel: adxl345: Move defines to header
dt-bindings: iio: accel: adxl345: Add spi-3wire
iio: accel: adxl345: Pass function pointer to core
iio: accel: adxl345: Add comment to probe
iio: accel: adxl345: Add spi-3wire option
.../bindings/iio/accel/adi,adxl345.yaml | 2 +
drivers/iio/accel/adxl345.h | 42 ++++++++++++-
drivers/iio/accel/adxl345_core.c | 62 ++++++++-----------
drivers/iio/accel/adxl345_i2c.c | 2 +-
drivers/iio/accel/adxl345_spi.c | 12 +++-
5 files changed, 80 insertions(+), 40 deletions(-)
--
2.25.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox