* [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
@ 2025-06-18 9:58 Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 01/19] media: mc: Add INTERNAL pad flag Cosmin Tanislav
` (18 more replies)
0 siblings, 19 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
This series adds new drivers for multiple Maxim GMSL2 and GMSL3 devices,
replacing the few GMSL2 drivers already in upstream, and introducing a
common framework that can be used to implement such GMSL chips, which
avoids code duplication while also adding support for previously
unsupported features.
While the normally acceptable and polite way would be to extend the
current mainline drivers, the choice was made here to add a totally new
set of drivers. The current drivers support only a small subset of the
possible features, and only a few devices, so the end result after
extending them would in any case be essentially fully rewritten, new
drivers.
This series depends on support for internal pads, for which a patch has
been added.
The previous version is at:
https://lore.kernel.org/lkml/20250512212832.3674722-1-demonsingur@gmail.com
The following deserializers are supported:
* MAX96712 (already exists in staging)
* MAX96714 (already exists)
* MAX96714F (already exists)
* MAX96714R (GMSL2)
* MAX96716 (GMSL2)
* MAX96724 (already exists as part of existing MAX96712 driver)
* MAX96724F (GMSL2)
* MAX96724R (GMSL2)
* MAX9296A (GMSL2)
* MAX96792A (GMSL3)
The following serializers are supported:
* MAX96717 (already exists)
* MAX9295A (GMSL2)
* MAX96793 (GMSL3)
Known backward compatibility breakages:
* No default routing. Default routing has been intentionally ommitted
as the devices support quite complex routing and it would be
unfeasible to provide sane defaults for multi-link deserialziers.
It is expected that userspace programs would set appropritate
routing.
The following list enumerates new features that are supported by the
common framework and their respective chip-specific drivers:
* Full Streams API support. Most deserializers have support for more
than one link, and more than one PHY. Streams support allows
configuration of routing between these links and PHYs.
* .get_frame_desc() support. Both the serializers and deserializers
implement this to query and provide frame descriptor data. This is
used in features explained in-depth below.
* .get_mbus_config() support. The deserializers implement this to allow
upstream devices to query the link frequency of its pads.
* Address translation with I2C ATR for the serializers.
* I2C ATR translation - some deserializers cannot do muxing since I2C
communication channel masking is not available per-link, and the only
other way to select links is to turn them off, causing link resets.
For such cases, I2C ATR is used to change the address of the
serializers at probe time.
* Automatic GMSL link version negotiation between GMSL3, GMSL2 6Gbps, GMSL2
3Gbps.
* Automatic stream id selection for deserializers which need serializers to
stream on unique stream ids.
* Automatic VC remapping on the deserializers. VCs are picked so that
if they were unique on the sink pad, they will end up as unique on
the source pad they are routed to too, prioritizing using the same
VC ID as the sink pad, to facilitate the possibility of using tunnel
mode.
* Automatic pixel mode / tunnel mode selection. Tunnel mode is used
when VC IDs do not need to be changed and all hardware supports
tunnel mode, otherwise, pixel mode is used. The serializers are
automatically switched between the two by using a private API.
* Automatic double mode selection. In pixel mode, double mode can be
used to pack two pixels into a single data unit, optimizing bandwidth
usage. The serializers are automatically set up to support the double
modes determined by the deserializers using a private API.
* Automatic data padding. In pixel mode, if the data being transferred
uses two different BPPs, data needs to be padded. The serializers
automatically set this up depending on the configured double mode
settings and incoming data types.
* Logging. Both the deserializers and serializers implement the V4L2
.log_status() ops to allow debugging of the internal state and
important chip status registers.
* PHY modes. Deserializer chips commonly have more than a single PHY.
The firmware ports are parsed to determine the modes in which to
configure the PHYs (2x4, 4x2, 1x4+2x2, 2x2+1x4, and variations using
fewer lanes).
* Serializer pinctrl. Serializers implement pinctrl to allow setting
configs which would otherwise be inaccessible through GPIO: TX/RX via
GMSL link, pull-up & pull-down (with strength), open-drain &
push-pull, slew rate, RCLK pin selection.
* TPG with selectable formats, resolutions and framerates for both
serializers and deserializers.
The drivers have been tested on the following hardware combinations, but
further testing is welcome to ensure no / minimal breakage:
* Raspberry Pi 5 + MAX9296A + 2xMAX96717 + 2xIMX219
* Raspberry Pi 5 + MAX96714 + 1xMAX96717 + 1xIMX219
* Raspberry Pi 5 + MAX96716A + 2xMAX96717 + 2xIMX219
* Raspberry Pi 5 + MAX96712 + 4xMAX96717 + 4xIMX219
* Raspberry Pi 5 + MAX96724 + 4xMAX96717 + 4xIMX219
* Raspberry Pi 5 + MAX96792A + 1xMAX96793 + 1xMAX96717 + 2xIMX219
* Raspberry Pi 5 + MAX96792A + 2xMAX96717 + 2xIMX219
* Renesas V4H + MAX96712 + 2xMAX96717 + 2xIMX219
Analog Devices is taking responsibility for the maintenance of these
drivers and common framework, and plans to add support for new
broad-market chips on top of them.
Special thanks go to Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
for testing the drivers, helping debug and coming up with ideas /
implementations for various features.
V4:
* max_des: fix infinite version loop
* max_des: fix pipe link id when there are more pipes than links
* max_des: implement setting pipe link
* max_des: do not pass routing to phy update
* max_des: move GMSL version strings to max_serdes
* max_des: split finding existing VC remap from adding a new one
* max_des: add tracking for in-use pipes
* max_des: skip unused pipes when finding / setting pixel/tunnel mode
* max_des: simplify remap code
* max_des: split set_pipe_phy() into set_pipe_tunnel_phy()
* max_ser: clean up i2c_xlates printing
* max_ser: fix changing serializer address
* max_ser: move non-continuous mode check into max96717 driver
* max96724: use regmap_set_bits for STREAM_SEL_ALL
* max96724: match surrounding indent for MAX96724_PHY1_ALT_CLOCK
* max96724: fix setting invalid PHY to 1 when PHY 0 is in 4-lane mode
* max96724: remove support for setting pipe phy from max96712
* max96724: fix setting double mode on pipes 4-7
* max96724: drop powerdown gpios
* max96717: use gpio_chip's set_rv
* max9296a: switch versions to unsigned int
* max9296a: remove parantheses from MAX9296A_MIPI_PHY18/20
* max9296a: fix printing of PHY packet counts
* max9296a: fix phy_hw_ids size
* remove usage of cammel case in defines
* move field_get/prep to max_serdes.h
* rework stream id setup
* rework tunnel/pixel mode finding
* rework bpps retrieval
* pass whole subdev state around
* add helper for retrieving a route's hw components / frame desc
* update pipe enable based on active routes
* add support for tunnel-only chips and VC remaps in tunnel mode
* simplify max_get_streams_masks()
* add support for TPG
V3:
* dt-bindings: drop reflow text patches
* dt-bindings: max96717: move pinctrl configuration into main file
* dt-bindings: max96717: allow a single level of pins configuration
* dt-bindings: max96717: use regex for matching pins nodes
* dt-bindings: max96717: drop extra allOf in pinctrl configuration
* dt-bindings: max96717: fix i2c-atr channel name regex
* dt-bindings: max96717: limit pinctrl functions to gpio / rclkout
* dt-bindings: max96717: limit pins for gpio / rclkout
* dt-bindings: max96717: add description for bias-pull-up/down
* dt-bindings: max96717: require pins and function properties
* dt-bindings: max96717: turn single compatible strings into an enum
* dt-bindings: max9296a: include indices in port descriptions
* dt-bindings: max9296a: remove property-less schema from input ports
* dt-bindings: max9296a: use ATR for MAX96716A too, removing MUX entirely
* dt-bindings: max96712: include indices in port descriptions
* dt-bindings: max96712: deprecate enable-gpios in favor of powerdown-gpios
* dt-bindings: max96712: switch from MUX to ATR
* dt-bindings: max96714: add support for MAX96714R
* max_des: fix POC NULL check
* max_des: remove index var in POC enable
* max_des: fix writing empty remaps
* max_des: skip mode setting in tunnel mode
* max_des: remove a duplicate source->sd NULL check
* max_des: set pipe tunnel mode even for disabled links
* max_ser: apply TX ID changes irrespective of serializer ID
* max9296a: fix typo in BACKTOP22
* max9296a: make register macros more consistent
* max9296a: switch MAX96716 from MUX to ATR
* max9296a: deduplicate max9296a_phy_id() logic
* max9296a: use proper PHY id in remaps
* max9296a: fix DPLL reset clear
* max9296a: limit MAX96714F to GMSL2 3Gbps
* max9296a: add support for MAX96714R
* max9296a: do not write GMSL3 link select registers in GMSL2 devices
* max9296a: use field_prep when setting RX_RATE
* max9296a: simplify setting SEL_STREAM for MAX96714
* max9296a: max96716_set_pipe_phy -> max96716a_set_pipe_phy
* max9296a: fix off-by-one in lane polarity when using
polarity_on_physical_lanes
* max96724: fix typo in BACKTOP22
* max96724: switch from MUX to ATR
* max96724: add support for powerdown GPIO
* max96724: remove support for tunneling from MAX96712
* max96724: only set tunnel-related bits when in tunnel mode
* max96724: add support for MAX96724F/R
* max96724: oneshot reset links after link selection
* remove GMSL2 version defaults, set all supported versions explicitly
* reorder GMSL versions to start from 0
* add support for GMSL2 3Gbps
* support GMSL version finding for devices using MUX / GATE
* add support for deserializers which don't have individual control
of each link's GMSL version
* add support for deserializers that need unique stream ids across all
serializers
* select_link_version -> set_link_version
* select_resets_link -> use_atr
V2:
* add missing compatible for MAX96717F
* fix embarrassing dt-bindings mistakes
* move MAX9296A/MAX96716/MAX96792A to a separate file as they have two
links / PHYs, and adding those conditionally seems impossible
Cosmin Tanislav (18):
dt-bindings: media: i2c: max96717: add myself as maintainer
dt-bindings: media: i2c: max96717: add support for I2C ATR
dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf
dt-bindings: media: i2c: max96717: add support for MAX9295A
dt-bindings: media: i2c: max96717: add support for MAX96793
dt-bindings: media: i2c: max96712: add myself as maintainer
dt-bindings: media: i2c: max96712: use pattern properties for ports
dt-bindings: media: i2c: max96712: add support for I2C ATR
dt-bindings: media: i2c: max96712: add support for POC supplies
dt-bindings: media: i2c: max96712: add support for MAX96724F/R
dt-bindings: media: i2c: max96714: add myself as maintainer
dt-bindings: media: i2c: max96714: add support for MAX96714R
dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A
media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
arm64: defconfig: disable deprecated MAX96712 driver
staging: media: remove MAX96712 driver
media: i2c: remove MAX96717 driver
media: i2c: remove MAX96714 driver
Sakari Ailus (1):
media: mc: Add INTERNAL pad flag
.../bindings/media/i2c/maxim,max9296a.yaml | 242 ++
.../bindings/media/i2c/maxim,max96712.yaml | 70 +-
.../bindings/media/i2c/maxim,max96714.yaml | 6 +-
.../bindings/media/i2c/maxim,max96717.yaml | 160 +-
.../media/mediactl/media-types.rst | 8 +
MAINTAINERS | 13 +-
arch/arm64/configs/defconfig | 1 -
drivers/media/i2c/Kconfig | 34 +-
drivers/media/i2c/Makefile | 3 +-
drivers/media/i2c/max96714.c | 1024 ------
drivers/media/i2c/max96717.c | 1103 ------
drivers/media/i2c/maxim-serdes/Kconfig | 53 +
drivers/media/i2c/maxim-serdes/Makefile | 6 +
drivers/media/i2c/maxim-serdes/max9296a.c | 1338 +++++++
drivers/media/i2c/maxim-serdes/max96717.c | 1647 +++++++++
drivers/media/i2c/maxim-serdes/max96724.c | 1155 ++++++
drivers/media/i2c/maxim-serdes/max_des.c | 3108 +++++++++++++++++
drivers/media/i2c/maxim-serdes/max_des.h | 152 +
drivers/media/i2c/maxim-serdes/max_ser.c | 2032 +++++++++++
drivers/media/i2c/maxim-serdes/max_ser.h | 144 +
drivers/media/i2c/maxim-serdes/max_serdes.c | 415 +++
drivers/media/i2c/maxim-serdes/max_serdes.h | 166 +
drivers/media/mc/mc-entity.c | 10 +-
drivers/staging/media/Kconfig | 2 -
drivers/staging/media/Makefile | 1 -
drivers/staging/media/max96712/Kconfig | 14 -
drivers/staging/media/max96712/Makefile | 2 -
drivers/staging/media/max96712/max96712.c | 487 ---
include/uapi/linux/media.h | 1 +
29 files changed, 10702 insertions(+), 2695 deletions(-)
create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
delete mode 100644 drivers/media/i2c/max96714.c
delete mode 100644 drivers/media/i2c/max96717.c
create mode 100644 drivers/media/i2c/maxim-serdes/Kconfig
create mode 100644 drivers/media/i2c/maxim-serdes/Makefile
create mode 100644 drivers/media/i2c/maxim-serdes/max9296a.c
create mode 100644 drivers/media/i2c/maxim-serdes/max96717.c
create mode 100644 drivers/media/i2c/maxim-serdes/max96724.c
create mode 100644 drivers/media/i2c/maxim-serdes/max_des.c
create mode 100644 drivers/media/i2c/maxim-serdes/max_des.h
create mode 100644 drivers/media/i2c/maxim-serdes/max_ser.c
create mode 100644 drivers/media/i2c/maxim-serdes/max_ser.h
create mode 100644 drivers/media/i2c/maxim-serdes/max_serdes.c
create mode 100644 drivers/media/i2c/maxim-serdes/max_serdes.h
delete mode 100644 drivers/staging/media/max96712/Kconfig
delete mode 100644 drivers/staging/media/max96712/Makefile
delete mode 100644 drivers/staging/media/max96712/max96712.c
--
2.49.0
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH v4 01/19] media: mc: Add INTERNAL pad flag
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 02/19] dt-bindings: media: i2c: max96717: add myself as maintainer Cosmin Tanislav
` (17 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
From: Sakari Ailus <sakari.ailus@linux.intel.com>
Internal source pads will be used as routing endpoints in V4L2
[GS]_ROUTING IOCTLs, to indicate that the stream begins in the entity.
Internal source pads are pads that have both SINK and INTERNAL flags set.
Also prevent creating links to pads that have been flagged as internal and
initialising SOURCE pads with INTERNAL flag set.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
.../userspace-api/media/mediactl/media-types.rst | 8 ++++++++
drivers/media/mc/mc-entity.c | 10 ++++++++--
include/uapi/linux/media.h | 1 +
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst
index 6332e8395263..f55ef055bcf8 100644
--- a/Documentation/userspace-api/media/mediactl/media-types.rst
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -361,6 +361,7 @@ Types and flags used to represent the media graph elements
.. _MEDIA-PAD-FL-SINK:
.. _MEDIA-PAD-FL-SOURCE:
.. _MEDIA-PAD-FL-MUST-CONNECT:
+.. _MEDIA-PAD-FL-INTERNAL:
.. flat-table:: Media pad flags
:header-rows: 0
@@ -381,6 +382,13 @@ Types and flags used to represent the media graph elements
enabled links even when this flag isn't set; the absence of the flag
doesn't imply there is none.
+ * - ``MEDIA_PAD_FL_INTERNAL``
+ - The internal flag indicates an internal pad that has no external
+ connections. Such a pad shall not be connected with a link.
+
+ The internal flag may currently be present only in a source pad where
+ it indicates that the :ref:``stream <media-glossary-stream>``
+ originates from within the entity.
One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
must be set for every pad.
diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c
index 045590905582..d1feacc60807 100644
--- a/drivers/media/mc/mc-entity.c
+++ b/drivers/media/mc/mc-entity.c
@@ -213,7 +213,9 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
iter->index = i++;
if (hweight32(iter->flags & (MEDIA_PAD_FL_SINK |
- MEDIA_PAD_FL_SOURCE)) != 1) {
+ MEDIA_PAD_FL_SOURCE)) != 1 ||
+ (iter->flags & MEDIA_PAD_FL_INTERNAL &&
+ !(iter->flags & MEDIA_PAD_FL_SINK))) {
ret = -EINVAL;
break;
}
@@ -1118,7 +1120,8 @@ int media_get_pad_index(struct media_entity *entity, u32 pad_type,
for (i = 0; i < entity->num_pads; i++) {
if ((entity->pads[i].flags &
- (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE)) != pad_type)
+ (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE |
+ MEDIA_PAD_FL_INTERNAL)) != pad_type)
continue;
if (entity->pads[i].sig_type == sig_type)
@@ -1148,6 +1151,9 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
return -EINVAL;
if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK)))
return -EINVAL;
+ if (WARN_ON(source->pads[source_pad].flags & MEDIA_PAD_FL_INTERNAL) ||
+ WARN_ON(sink->pads[sink_pad].flags & MEDIA_PAD_FL_INTERNAL))
+ return -EINVAL;
link = media_add_link(&source->links);
if (link == NULL)
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 1c80b1d6bbaf..80cfd12a43fc 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -208,6 +208,7 @@ struct media_entity_desc {
#define MEDIA_PAD_FL_SINK (1U << 0)
#define MEDIA_PAD_FL_SOURCE (1U << 1)
#define MEDIA_PAD_FL_MUST_CONNECT (1U << 2)
+#define MEDIA_PAD_FL_INTERNAL (1U << 3)
struct media_pad_desc {
__u32 entity; /* entity ID */
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 02/19] dt-bindings: media: i2c: max96717: add myself as maintainer
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 01/19] media: mc: Add INTERNAL pad flag Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 03/19] dt-bindings: media: i2c: max96717: add support for I2C ATR Cosmin Tanislav
` (16 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
Analog Devices is taking responsability for the maintenance of the Maxim
GMSL2/3 devices.
Add myself to the maintainers list and to the device tree bindings.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml | 1 +
MAINTAINERS | 1 +
2 files changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
index d1e8ba6e368e..15ab37702a92 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -9,6 +9,7 @@ title: MAX96717 CSI-2 to GMSL2 Serializer
maintainers:
- Julien Massot <julien.massot@collabora.com>
+ - Cosmin Tanislav <cosmin.tanislav@analog.com>
description:
The MAX96717 serializer converts MIPI CSI-2 D-PHY formatted input
diff --git a/MAINTAINERS b/MAINTAINERS
index e8f3dc93a569..01363fbcb9b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14742,6 +14742,7 @@ F: drivers/media/i2c/max96714.c
MAX96717 GMSL2 SERIALIZER DRIVER
M: Julien Massot <julien.massot@collabora.com>
+M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 03/19] dt-bindings: media: i2c: max96717: add support for I2C ATR
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 01/19] media: mc: Add INTERNAL pad flag Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 02/19] dt-bindings: media: i2c: max96717: add myself as maintainer Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf Cosmin Tanislav
` (15 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96717 is capable of address translation for the connected I2C slaves.
Add support for I2C ATR while keeping I2C gate for compatibility to
support this usecase.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/media/i2c/maxim,max96717.yaml | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
index 15ab37702a92..167c3dd50683 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -92,6 +92,30 @@ properties:
incoming GMSL2 link. Therefore, it supports an i2c-gate
subnode to configure a sensor.
+ i2c-alias-pool:
+ maxItems: 2
+
+ i2c-atr:
+ type: object
+ additionalProperties: false
+
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ '^i2c@[01]$':
+ $ref: /schemas/i2c/i2c-controller.yaml#
+ unevaluatedProperties: false
+ properties:
+ reg:
+ items:
+ minimum: 0
+ maximum: 1
+
required:
- compatible
- reg
@@ -99,6 +123,21 @@ required:
additionalProperties: false
+allOf:
+ - $ref: /schemas/i2c/i2c-atr.yaml#
+
+ - anyOf:
+ - oneOf:
+ - required: [i2c-atr]
+ - required: [i2c-gate]
+
+ - not:
+ required: [i2c-atr, i2c-gate]
+
+dependentRequired:
+ i2c-atr: [i2c-alias-pool]
+ i2c-alias-pool: [i2c-atr]
+
examples:
- |
#include <dt-bindings/gpio/gpio.h>
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (2 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 03/19] dt-bindings: media: i2c: max96717: add support for I2C ATR Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-24 18:58 ` Linus Walleij
2025-06-27 19:38 ` Rob Herring
2025-06-18 9:58 ` [PATCH v4 05/19] dt-bindings: media: i2c: max96717: add support for MAX9295A Cosmin Tanislav
` (14 subsequent siblings)
18 siblings, 2 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96717 is capable of configuring various pin properties.
Add pinctrl/pinconf properties to support this usecase.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
---
.../bindings/media/i2c/maxim,max96717.yaml | 110 ++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
index 167c3dd50683..5998e2518be9 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -121,6 +121,116 @@ required:
- reg
- ports
+patternProperties:
+ '-pins$':
+ type: object
+ additionalProperties: false
+
+ properties:
+ function:
+ enum: [gpio, rclkout]
+
+ pins: true
+ drive-open-drain: true
+ drive-push-pull: true
+ bias-disable: true
+ output-disable: true
+ output-enable: true
+ output-low: true
+ output-high: true
+ input-enable: true
+
+ slew-rate:
+ description: |
+ Slew rate.
+ 0 - Fastest
+ 1 - Fast
+ 2 - Slow
+ 3 - Slowest
+ maximum: 3
+
+ bias-pull-up:
+ oneOf:
+ - type: boolean
+ description: Enable regular 40kOhm pull-up
+ - enum: [ 40000, 1000000 ]
+ description: Enable either the 40kOhm or the 1MOhm pull-up
+
+ bias-pull-down:
+ oneOf:
+ - type: boolean
+ description: Enable regular 40kOhm pull-down
+ - enum: [ 40000, 1000000 ]
+ description: Enable either the 40kOhm or the 1MOhm pull-down
+
+ maxim,jitter-compensation:
+ type: boolean
+ description: Enables jitter compensation.
+
+ maxim,gmsl-tx:
+ type: boolean
+ description: Enable transmitting pin value to GMSL link.
+
+ maxim,gmsl-rx:
+ type: boolean
+ description: Enable receiving pin value from GMSL link.
+
+ maxim,gmsl-tx-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Identifier used while transmitting value to GMSL link.
+ Default value matches the pin number.
+ minimum: 0
+ maximum: 31
+
+ maxim,gmsl-rx-id:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Identifier used while receiving value from GMSL link.
+ Default value matches the pin number.
+ minimum: 0
+ maximum: 31
+
+ maxim,rclkout-clock:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Clock value.
+ 0 - XTAL / 1 = 25MHz
+ 1 - XTAL / 2 = 12.5MHz
+ 2 - XTAL / 4 = 6.25MHz
+ 3 - Reference PLL output
+ minimum: 0
+ maximum: 3
+
+ required:
+ - pins
+ - function
+
+ allOf:
+ - $ref: /schemas/pinctrl/pincfg-node.yaml#
+ - $ref: /schemas/pinctrl/pinmux-node.yaml#
+
+ - if:
+ properties:
+ function:
+ const: gpio
+ then:
+ properties:
+ pins:
+ items:
+ enum: [mfp0, mfp1, mfp2, mfp3, mfp4, mfp5, mfp6, mfp7,
+ mfp8, mfp9, mfp10]
+
+ - if:
+ properties:
+ function:
+ const: rclkout
+ then:
+ properties:
+ pins:
+ items:
+ enum: [mfp0, mfp1, mfp2, mfp3, mfp4, mfp7, mfp8]
+
additionalProperties: false
allOf:
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 05/19] dt-bindings: media: i2c: max96717: add support for MAX9295A
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (3 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793 Cosmin Tanislav
` (13 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX9295A is an older variant of the MAX96717 which does not support
tunnel mode.
Document the compatibility.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../devicetree/bindings/media/i2c/maxim,max96717.yaml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
index 5998e2518be9..ab46a5f0bd7e 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -25,12 +25,17 @@ description:
The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
forward direction and 187.5Mbps in the reverse direction.
+
MAX96717F only supports a fixed rate of 3Gbps in the forward direction.
+ MAX9295A only supports pixel mode.
+
properties:
compatible:
oneOf:
- - const: maxim,max96717f
+ - enum:
+ - maxim,max9295a
+ - maxim,max96717f
- items:
- enum:
- maxim,max96717
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (4 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 05/19] dt-bindings: media: i2c: max96717: add support for MAX9295A Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-24 16:14 ` Martin Hecht
2025-06-18 9:58 ` [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer Cosmin Tanislav
` (12 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96793 is a newer variant of the MAX96717 which also supports GMSL3
links.
Document this compatibility.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../devicetree/bindings/media/i2c/maxim,max96717.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
index ab46a5f0bd7e..23f611177a87 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -30,6 +30,8 @@ description:
MAX9295A only supports pixel mode.
+ MAX96793 also supports GMSL3 mode.
+
properties:
compatible:
oneOf:
@@ -39,6 +41,7 @@ properties:
- items:
- enum:
- maxim,max96717
+ - maxim,max96793
- const: maxim,max96717f
'#gpio-cells':
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (5 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793 Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-19 10:31 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports Cosmin Tanislav
` (11 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
Analog Devices is taking responsability for the maintenance of the Maxim
GMSL2/3 devices.
Add myself to the maintainers list and to the device tree bindings.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml | 1 +
MAINTAINERS | 1 +
2 files changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
index 26f85151afbd..efdece2b33b9 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
@@ -9,6 +9,7 @@ title: Quad GMSL2 to CSI-2 Deserializer with GMSL1 Compatibility
maintainers:
- Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+ - Cosmin Tanislav <cosmin.tanislav@analog.com>
description: |
The MAX96712 deserializer converts GMSL2 or GMSL1 serial inputs into MIPI
diff --git a/MAINTAINERS b/MAINTAINERS
index 01363fbcb9b3..77adb1f7ac9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14728,6 +14728,7 @@ F: drivers/media/i2c/max9286.c
MAX96712 QUAD GMSL2 DESERIALIZER DRIVER
M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
+M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (6 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-19 11:17 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 09/19] dt-bindings: media: i2c: max96712: add support for I2C ATR Cosmin Tanislav
` (10 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The MAX96712 and MAX96724 support up to 4 separate PHYs, depending on
the selected PHY configuration. Use patternProperties to document this.
The input ports are all the same, use patternProperties for them.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/media/i2c/maxim,max96712.yaml | 29 +++++++------------
1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
index efdece2b33b9..f712d7cfc35f 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
@@ -40,27 +40,15 @@ properties:
ports:
$ref: /schemas/graph.yaml#/properties/ports
- properties:
- port@0:
+ patternProperties:
+ '^port@[0-3]$':
$ref: /schemas/graph.yaml#/properties/port
- description: GMSL Input 0
+ description: GMSL Input ports 0-3
- port@1:
- $ref: /schemas/graph.yaml#/properties/port
- description: GMSL Input 1
-
- port@2:
- $ref: /schemas/graph.yaml#/properties/port
- description: GMSL Input 2
-
- port@3:
- $ref: /schemas/graph.yaml#/properties/port
- description: GMSL Input 3
-
- port@4:
+ '^port@[4-7]$':
$ref: /schemas/graph.yaml#/$defs/port-base
unevaluatedProperties: false
- description: CSI-2 Output
+ description: CSI-2 Output port 0-3
properties:
endpoint:
@@ -78,8 +66,11 @@ properties:
- data-lanes
- bus-type
- required:
- - port@4
+ anyOf:
+ - required: [port@4]
+ - required: [port@5]
+ - required: [port@6]
+ - required: [port@7]
required:
- compatible
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 09/19] dt-bindings: media: i2c: max96712: add support for I2C ATR
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (7 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies Cosmin Tanislav
` (9 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96712 and MAX96724 have more than one GMSL2 link, and each link is
capable of connecting to a separate serializer. If these serializers
have the same CFG pins configuration, they will also have the same I2C
address, causing conflicts unless the deserializer changes the address
of the connected serializers.
The MAX96712 and MAX96724 support changing the I2C address of the
connected serializers.
Document this capability.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/media/i2c/maxim,max96712.yaml | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
index f712d7cfc35f..758c0223977d 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
@@ -37,6 +37,30 @@ properties:
enable-gpios: true
+ i2c-alias-pool:
+ maxItems: 4
+
+ i2c-atr:
+ type: object
+ additionalProperties: false
+
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ '^i2c@[0-3]$':
+ $ref: /schemas/i2c/i2c-controller.yaml#
+ unevaluatedProperties: false
+ properties:
+ reg:
+ items:
+ minimum: 0
+ maximum: 3
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
@@ -79,6 +103,13 @@ required:
additionalProperties: false
+allOf:
+ - $ref: /schemas/i2c/i2c-atr.yaml#
+
+dependentRequired:
+ i2c-atr: [i2c-alias-pool]
+ i2c-alias-pool: [i2c-atr]
+
examples:
- |
#include <dt-bindings/gpio/gpio.h>
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (8 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 09/19] dt-bindings: media: i2c: max96712: add support for I2C ATR Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-19 13:32 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R Cosmin Tanislav
` (8 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The GMSL links can carry power to the serializer when using coaxial
cables.
Document this capability.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../devicetree/bindings/media/i2c/maxim,max96712.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
index 758c0223977d..b345305acc4c 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
@@ -96,6 +96,10 @@ properties:
- required: [port@6]
- required: [port@7]
+patternProperties:
+ '^port[0-3]-poc-supply$':
+ description: Regulator providing Power over Coax for GMSL ports
+
required:
- compatible
- reg
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (9 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-19 13:33 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 12/19] dt-bindings: media: i2c: max96714: add myself as maintainer Cosmin Tanislav
` (7 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96724F/MAX96724R are a lower capability variant of the MAX96724 which
only support a fixed rate of 3Gbps in the forward direction.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../devicetree/bindings/media/i2c/maxim,max96712.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
index b345305acc4c..5dcafd46344c 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
@@ -24,12 +24,17 @@ description: |
MAX96712 can be paired with first-generation 3.12Gbps or 1.5Gbps GMSL1
serializers or operate up to 3.12Gbps with GMSL2 serializers in GMSL1 mode.
+ MAX96724F and MAX96724R only support a fixed rate of 3Gbps in the forward
+ direction.
+
properties:
compatible:
items:
- enum:
- maxim,max96712
- maxim,max96724
+ - maxim,max96724f
+ - maxim,max96724r
reg:
description: I2C device address
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 12/19] dt-bindings: media: i2c: max96714: add myself as maintainer
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (10 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 13/19] dt-bindings: media: i2c: max96714: add support for MAX96714R Cosmin Tanislav
` (6 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
Analog Devices is taking responsability for the maintenance of the Maxim
GMSL2/3 devices.
Add myself to the maintainers list and to the device tree bindings.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml | 1 +
MAINTAINERS | 1 +
2 files changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
index 3ace50e11921..f53c72e5c572 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
@@ -8,6 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Maxim MAX96714 GMSL2 to CSI-2 Deserializer
maintainers:
+ - Cosmin Tanislav <cosmin.tanislav@analog.com>
- Julien Massot <julien.massot@collabora.com>
description:
diff --git a/MAINTAINERS b/MAINTAINERS
index 77adb1f7ac9c..423ef18ca693 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14736,6 +14736,7 @@ F: drivers/staging/media/max96712/max96712.c
MAX96714 GMSL2 DESERIALIZER DRIVER
M: Julien Massot <julien.massot@collabora.com>
+M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 13/19] dt-bindings: media: i2c: max96714: add support for MAX96714R
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (11 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 12/19] dt-bindings: media: i2c: max96714: add myself as maintainer Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A Cosmin Tanislav
` (5 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
MAX96714R is a lower capability variant of the MAX96714 which only
supports a fixed rate of 3Gbps in the forward direction.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../devicetree/bindings/media/i2c/maxim,max96714.yaml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
index f53c72e5c572..1c97624833eb 100644
--- a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
@@ -23,7 +23,9 @@ description:
The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
forward direction and 187.5Mbps in the reverse direction.
- MAX96714F only supports a fixed rate of 3Gbps in the forward direction.
+
+ MAX96714F and MAX96714R only support a fixed rate of 3Gbps in the forward
+ direction.
properties:
compatible:
@@ -32,6 +34,7 @@ properties:
- items:
- enum:
- maxim,max96714
+ - maxim,max96714r
- const: maxim,max96714f
reg:
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (12 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 13/19] dt-bindings: media: i2c: max96714: add support for MAX96714R Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 13:00 ` Rob Herring (Arm)
2025-06-18 9:58 ` [PATCH v4 16/19] arm64: defconfig: disable deprecated MAX96712 driver Cosmin Tanislav
` (4 subsequent siblings)
18 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The MAX9296A deserializer converts single or dual serial inputs to MIPI
CSI-2 outputs. The GMSL2 links operate at a fixed rate of 3Gbps or 6Gbps
in the forward direction and 187.5Mbps in the reverse direction.
In GMSL1 mode, each serial link can be paired with 3.12Gbps or 1.5Gbps
GMSL1 serializers or operate up to 4.5Gbps with GMSL2 serializers with
GMSL1 backward compatibility. The MAX9296A supports mixed GMSL2 and
GMSL1 links. The serial inputs operate independently, allowing videos
with different timings and resolutions to be received on each input.
MAX96716A supports both tunnel and pixel mode.
MAX96792A supports both tunnel and pixel mode, and has two GMSL3 links.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
---
.../bindings/media/i2c/maxim,max9296a.yaml | 242 ++++++++++++++++++
MAINTAINERS | 6 +
2 files changed, 248 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
new file mode 100644
index 000000000000..c0a8916353f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
@@ -0,0 +1,242 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Collabora Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/maxim,max9296a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX9296A GMSL2 to CSI-2 Deserializer
+
+maintainers:
+ - Cosmin Tanislav <cosmin.tanislav@analog.com>
+
+description: >
+ The MAX9296A deserializer converts single or dual serial inputs to
+ MIPI CSI-2 outputs. The GMSL2 links operate at a fixed rate of 3Gbps
+ or 6Gbps in the forward direction and 187.5Mbps in the reverse
+ direction. In GMSL1 mode, each serial link can be paired with 3.12Gbps
+ or 1.5Gbps GMSL1 serializers or operate up to 4.5Gbps with GMSL2
+ serializers with GMSL1 backward compatibility. The MAX9296A supports
+ mixed GMSL2 and GMSL1 links. The serial inputs operate independently,
+ allowing videos with different timings and resolutions to be received
+ on each input.
+
+ MAX96716A supports both tunnel and pixel mode.
+
+ MAX96792A supports both tunnel and pixel mode, and has two GMSL3 links.
+
+properties:
+ compatible:
+ enum:
+ - maxim,max9296a
+ - maxim,max96716a
+ - maxim,max96792a
+
+ reg:
+ maxItems: 1
+
+ powerdown-gpios:
+ maxItems: 1
+ description: Specifier for the GPIO connected to the PWDNB pin.
+
+ port0-poc-supply:
+ description: Regulator providing Power over Coax for GMSL port 0
+
+ port1-poc-supply:
+ description: Regulator providing Power over Coax for GMSL port 1
+
+ i2c-alias-pool:
+ maxItems: 2
+
+ i2c-atr:
+ type: object
+ additionalProperties: false
+
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ '^i2c@[0-1]$':
+ $ref: /schemas/i2c/i2c-controller.yaml#
+ unevaluatedProperties: false
+ properties:
+ reg:
+ items:
+ minimum: 0
+ maximum: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ patternProperties:
+ '^port@[0-1]$':
+ $ref: /schemas/graph.yaml#/properties/port
+ description: GMSL Input ports 0-1
+
+ '^port@[2-3]$':
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: CSI-2 Output ports 0-1
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+
+ link-frequencies:
+ maxItems: 1
+
+ required:
+ - data-lanes
+
+ anyOf:
+ - required:
+ - port@2
+ - required:
+ - port@3
+
+required:
+ - compatible
+ - reg
+ - ports
+
+additionalProperties: false
+
+allOf:
+ - $ref: /schemas/i2c/i2c-atr.yaml#
+
+dependentRequired:
+ i2c-atr: [i2c-alias-pool]
+ i2c-alias-pool: [i2c-atr]
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/media/video-interfaces.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deserializer@28 {
+ compatible = "maxim,max9296a";
+ reg = <0x28>;
+ powerdown-gpios = <&main_gpio0 37 GPIO_ACTIVE_LOW>;
+
+ i2c-alias-pool = <0x40 0x41>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ des_gmsl_in_0: endpoint {
+ remote-endpoint = <&ser_0_gmsl_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ des_gmsl_in_1: endpoint {
+ remote-endpoint = <&ser_1_gmsl_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ des_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <400000000>;
+ remote-endpoint = <&csi_in>;
+ };
+ };
+ };
+
+ i2c-atr {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+
+ serializer@40 {
+ compatible = "maxim,max96717";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ ser_0_csi_in: endpoint {
+ data-lanes = <1 2>;
+ remote-endpoint = <&sensor_0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ ser_0_gmsl_out: endpoint {
+ remote-endpoint = <&des_gmsl_in_0>;
+ };
+ };
+ };
+ };
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ serializer@40 {
+ compatible = "maxim,max96717";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ ser_1_csi_in: endpoint {
+ data-lanes = <1 2>;
+ remote-endpoint = <&sensor_1_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ ser_1_gmsl_out: endpoint {
+ remote-endpoint = <&des_gmsl_in_1>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 423ef18ca693..5c8fc3374179 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14764,6 +14764,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/proximity/maxbotix,mb1232.yaml
F: drivers/iio/proximity/mb1232.c
+MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS
+M: Cosmin Tanislav <cosmin.tanislav@analog.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
+
MAXIM MAX11205 DRIVER
M: Ramona Bolboaca <ramona.bolboaca@analog.com>
L: linux-iio@vger.kernel.org
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 16/19] arm64: defconfig: disable deprecated MAX96712 driver
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (13 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 17/19] staging: media: remove " Cosmin Tanislav
` (3 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The staging MAX96712 driver will be removed as its functionality has
been moved to the MAX96724 driver which makes use of the Maxim
GMSL2/3 deserializer framework.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
---
arch/arm64/configs/defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 897fc686e6a9..6f4254f562da 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1300,7 +1300,6 @@ CONFIG_GREYBUS=m
CONFIG_GREYBUS_BEAGLEPLAY=m
CONFIG_STAGING=y
CONFIG_STAGING_MEDIA=y
-CONFIG_VIDEO_MAX96712=m
CONFIG_VIDEO_MESON_VDEC=m
CONFIG_SND_BCM2835=m
CONFIG_CHROME_PLATFORMS=y
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 17/19] staging: media: remove MAX96712 driver
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (14 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 16/19] arm64: defconfig: disable deprecated MAX96712 driver Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 18/19] media: i2c: remove MAX96717 driver Cosmin Tanislav
` (2 subsequent siblings)
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
Remove the staging MAX96712 driver.
Its functionality has been moved to the MAX96724 driver which makes use
of the Maxim GMSL2/3 deserializer framework.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
---
MAINTAINERS | 1 -
drivers/staging/media/Kconfig | 2 -
drivers/staging/media/Makefile | 1 -
drivers/staging/media/max96712/Kconfig | 14 -
drivers/staging/media/max96712/Makefile | 2 -
drivers/staging/media/max96712/max96712.c | 487 ----------------------
6 files changed, 507 deletions(-)
delete mode 100644 drivers/staging/media/max96712/Kconfig
delete mode 100644 drivers/staging/media/max96712/Makefile
delete mode 100644 drivers/staging/media/max96712/max96712.c
diff --git a/MAINTAINERS b/MAINTAINERS
index fe5f239d7087..39020eaac338 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14732,7 +14732,6 @@ M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
-F: drivers/staging/media/max96712/max96712.c
MAX96714 GMSL2 DESERIALIZER DRIVER
M: Julien Massot <julien.massot@collabora.com>
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index b44214854399..fe29821f64a3 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -28,8 +28,6 @@ source "drivers/staging/media/imx/Kconfig"
source "drivers/staging/media/ipu3/Kconfig"
-source "drivers/staging/media/max96712/Kconfig"
-
source "drivers/staging/media/meson/vdec/Kconfig"
source "drivers/staging/media/rkvdec/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index ad4e9619a9e0..1a562b3b6881 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,7 +2,6 @@
obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += deprecated/atmel/
obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
-obj-$(CONFIG_VIDEO_MAX96712) += max96712/
obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/
obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/
obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive/
diff --git a/drivers/staging/media/max96712/Kconfig b/drivers/staging/media/max96712/Kconfig
deleted file mode 100644
index 117fadf81bd0..000000000000
--- a/drivers/staging/media/max96712/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config VIDEO_MAX96712
- tristate "Maxim MAX96712 Quad GMSL2 Deserializer support"
- depends on I2C
- depends on OF_GPIO
- depends on VIDEO_DEV
- select V4L2_FWNODE
- select VIDEO_V4L2_SUBDEV_API
- select MEDIA_CONTROLLER
- help
- This driver supports the Maxim MAX96712 Quad GMSL2 Deserializer.
-
- To compile this driver as a module, choose M here: the
- module will be called max96712.
diff --git a/drivers/staging/media/max96712/Makefile b/drivers/staging/media/max96712/Makefile
deleted file mode 100644
index 70c1974ce3f0..000000000000
--- a/drivers/staging/media/max96712/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_VIDEO_MAX96712) += max96712.o
diff --git a/drivers/staging/media/max96712/max96712.c b/drivers/staging/media/max96712/max96712.c
deleted file mode 100644
index 0751b2e04895..000000000000
--- a/drivers/staging/media/max96712/max96712.c
+++ /dev/null
@@ -1,487 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Maxim MAX96712 Quad GMSL2 Deserializer Driver
- *
- * Copyright (C) 2021 Renesas Electronics Corporation
- * Copyright (C) 2021 Niklas Söderlund
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/of_graph.h>
-#include <linux/regmap.h>
-
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fwnode.h>
-#include <media/v4l2-subdev.h>
-
-#define DEBUG_EXTRA_REG 0x09
-#define DEBUG_EXTRA_PCLK_25MHZ 0x00
-#define DEBUG_EXTRA_PCLK_75MHZ 0x01
-
-enum max96712_pattern {
- MAX96712_PATTERN_CHECKERBOARD = 0,
- MAX96712_PATTERN_GRADIENT,
-};
-
-struct max96712_info {
- unsigned int dpllfreq;
- bool have_debug_extra;
-};
-
-struct max96712_priv {
- struct i2c_client *client;
- struct regmap *regmap;
- struct gpio_desc *gpiod_pwdn;
-
- const struct max96712_info *info;
-
- bool cphy;
- struct v4l2_mbus_config_mipi_csi2 mipi;
-
- struct v4l2_subdev sd;
- struct v4l2_ctrl_handler ctrl_handler;
- struct media_pad pads[1];
-
- enum max96712_pattern pattern;
-};
-
-static int max96712_write(struct max96712_priv *priv, unsigned int reg, u8 val)
-{
- int ret;
-
- ret = regmap_write(priv->regmap, reg, val);
- if (ret)
- dev_err(&priv->client->dev, "write 0x%04x failed\n", reg);
-
- return ret;
-}
-
-static int max96712_update_bits(struct max96712_priv *priv, unsigned int reg,
- u8 mask, u8 val)
-{
- int ret;
-
- ret = regmap_update_bits(priv->regmap, reg, mask, val);
- if (ret)
- dev_err(&priv->client->dev, "update 0x%04x failed\n", reg);
-
- return ret;
-}
-
-static int max96712_write_bulk(struct max96712_priv *priv, unsigned int reg,
- const void *val, size_t val_count)
-{
- int ret;
-
- ret = regmap_bulk_write(priv->regmap, reg, val, val_count);
- if (ret)
- dev_err(&priv->client->dev, "bulk write 0x%04x failed\n", reg);
-
- return ret;
-}
-
-static int max96712_write_bulk_value(struct max96712_priv *priv,
- unsigned int reg, unsigned int val,
- size_t val_count)
-{
- unsigned int i;
- u8 values[4];
-
- for (i = 1; i <= val_count; i++)
- values[i - 1] = (val >> ((val_count - i) * 8)) & 0xff;
-
- return max96712_write_bulk(priv, reg, &values, val_count);
-}
-
-static void max96712_reset(struct max96712_priv *priv)
-{
- max96712_update_bits(priv, 0x13, 0x40, 0x40);
- msleep(20);
-}
-
-static void max96712_mipi_enable(struct max96712_priv *priv, bool enable)
-{
- if (enable) {
- max96712_update_bits(priv, 0x40b, 0x02, 0x02);
- max96712_update_bits(priv, 0x8a0, 0x80, 0x80);
- } else {
- max96712_update_bits(priv, 0x8a0, 0x80, 0x00);
- max96712_update_bits(priv, 0x40b, 0x02, 0x00);
- }
-}
-
-static void max96712_mipi_configure(struct max96712_priv *priv)
-{
- unsigned int i;
- u8 phy5 = 0;
-
- max96712_mipi_enable(priv, false);
-
- /* Select 2x4 mode. */
- max96712_write(priv, 0x8a0, 0x04);
-
- /* TODO: Add support for 2-lane and 1-lane configurations. */
- if (priv->cphy) {
- /* Configure a 3-lane C-PHY using PHY0 and PHY1. */
- max96712_write(priv, 0x94a, 0xa0);
-
- /* Configure C-PHY timings. */
- max96712_write(priv, 0x8ad, 0x3f);
- max96712_write(priv, 0x8ae, 0x7d);
- } else {
- /* Configure a 4-lane D-PHY using PHY0 and PHY1. */
- max96712_write(priv, 0x94a, 0xc0);
- }
-
- /* Configure lane mapping for PHY0 and PHY1. */
- /* TODO: Add support for lane swapping. */
- max96712_write(priv, 0x8a3, 0xe4);
-
- /* Configure lane polarity for PHY0 and PHY1. */
- for (i = 0; i < priv->mipi.num_data_lanes + 1; i++)
- if (priv->mipi.lane_polarities[i])
- phy5 |= BIT(i == 0 ? 5 : i < 3 ? i - 1 : i);
- max96712_write(priv, 0x8a5, phy5);
-
- /* Set link frequency for PHY0 and PHY1. */
- max96712_update_bits(priv, 0x415, 0x3f,
- ((priv->info->dpllfreq / 100) & 0x1f) | BIT(5));
- max96712_update_bits(priv, 0x418, 0x3f,
- ((priv->info->dpllfreq / 100) & 0x1f) | BIT(5));
-
- /* Enable PHY0 and PHY1 */
- max96712_update_bits(priv, 0x8a2, 0xf0, 0x30);
-}
-
-static void max96712_pattern_enable(struct max96712_priv *priv, bool enable)
-{
- const u32 h_active = 1920;
- const u32 h_fp = 88;
- const u32 h_sw = 44;
- const u32 h_bp = 148;
- const u32 h_tot = h_active + h_fp + h_sw + h_bp;
-
- const u32 v_active = 1080;
- const u32 v_fp = 4;
- const u32 v_sw = 5;
- const u32 v_bp = 36;
- const u32 v_tot = v_active + v_fp + v_sw + v_bp;
-
- if (!enable) {
- max96712_write(priv, 0x1051, 0x00);
- return;
- }
-
- /* Set PCLK to 75MHz if device have DEBUG_EXTRA register. */
- if (priv->info->have_debug_extra)
- max96712_write(priv, DEBUG_EXTRA_REG, DEBUG_EXTRA_PCLK_75MHZ);
-
- /* Configure Video Timing Generator for 1920x1080 @ 30 fps. */
- max96712_write_bulk_value(priv, 0x1052, 0, 3);
- max96712_write_bulk_value(priv, 0x1055, v_sw * h_tot, 3);
- max96712_write_bulk_value(priv, 0x1058,
- (v_active + v_fp + + v_bp) * h_tot, 3);
- max96712_write_bulk_value(priv, 0x105b, 0, 3);
- max96712_write_bulk_value(priv, 0x105e, h_sw, 2);
- max96712_write_bulk_value(priv, 0x1060, h_active + h_fp + h_bp, 2);
- max96712_write_bulk_value(priv, 0x1062, v_tot, 2);
- max96712_write_bulk_value(priv, 0x1064,
- h_tot * (v_sw + v_bp) + (h_sw + h_bp), 3);
- max96712_write_bulk_value(priv, 0x1067, h_active, 2);
- max96712_write_bulk_value(priv, 0x1069, h_fp + h_sw + h_bp, 2);
- max96712_write_bulk_value(priv, 0x106b, v_active, 2);
-
- /* Generate VS, HS and DE in free-running mode. */
- max96712_write(priv, 0x1050, 0xfb);
-
- /* Configure Video Pattern Generator. */
- if (priv->pattern == MAX96712_PATTERN_CHECKERBOARD) {
- /* Set checkerboard pattern size. */
- max96712_write(priv, 0x1074, 0x3c);
- max96712_write(priv, 0x1075, 0x3c);
- max96712_write(priv, 0x1076, 0x3c);
-
- /* Set checkerboard pattern colors. */
- max96712_write_bulk_value(priv, 0x106e, 0xfecc00, 3);
- max96712_write_bulk_value(priv, 0x1071, 0x006aa7, 3);
-
- /* Generate checkerboard pattern. */
- max96712_write(priv, 0x1051, 0x10);
- } else {
- /* Set gradient increment. */
- max96712_write(priv, 0x106d, 0x10);
-
- /* Generate gradient pattern. */
- max96712_write(priv, 0x1051, 0x20);
- }
-}
-
-static int max96712_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct max96712_priv *priv = v4l2_get_subdevdata(sd);
-
- if (enable) {
- max96712_pattern_enable(priv, true);
- max96712_mipi_enable(priv, true);
- } else {
- max96712_mipi_enable(priv, false);
- max96712_pattern_enable(priv, false);
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_video_ops max96712_video_ops = {
- .s_stream = max96712_s_stream,
-};
-
-static int max96712_init_state(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state)
-{
- static const struct v4l2_mbus_framefmt default_fmt = {
- .width = 1920,
- .height = 1080,
- .code = MEDIA_BUS_FMT_RGB888_1X24,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .field = V4L2_FIELD_NONE,
- .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
- .quantization = V4L2_QUANTIZATION_DEFAULT,
- .xfer_func = V4L2_XFER_FUNC_DEFAULT,
- };
- struct v4l2_mbus_framefmt *fmt;
-
- fmt = v4l2_subdev_state_get_format(state, 0);
- *fmt = default_fmt;
-
- return 0;
-}
-
-static const struct v4l2_subdev_internal_ops max96712_internal_ops = {
- .init_state = max96712_init_state,
-};
-
-static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
- .get_fmt = v4l2_subdev_get_fmt,
- .set_fmt = v4l2_subdev_get_fmt,
-};
-
-static const struct v4l2_subdev_ops max96712_subdev_ops = {
- .video = &max96712_video_ops,
- .pad = &max96712_pad_ops,
-};
-
-static const char * const max96712_test_pattern[] = {
- "Checkerboard",
- "Gradient",
-};
-
-static int max96712_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct max96712_priv *priv =
- container_of(ctrl->handler, struct max96712_priv, ctrl_handler);
-
- switch (ctrl->id) {
- case V4L2_CID_TEST_PATTERN:
- priv->pattern = ctrl->val ?
- MAX96712_PATTERN_GRADIENT :
- MAX96712_PATTERN_CHECKERBOARD;
- break;
- }
- return 0;
-}
-
-static const struct v4l2_ctrl_ops max96712_ctrl_ops = {
- .s_ctrl = max96712_s_ctrl,
-};
-
-static int max96712_v4l2_register(struct max96712_priv *priv)
-{
- long pixel_rate;
- int ret;
-
- priv->sd.internal_ops = &max96712_internal_ops;
- v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
- priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
-
- v4l2_ctrl_handler_init(&priv->ctrl_handler, 2);
-
- /*
- * TODO: Once V4L2_CID_LINK_FREQ is changed from a menu control to an
- * INT64 control it should be used here instead of V4L2_CID_PIXEL_RATE.
- */
- pixel_rate = priv->info->dpllfreq / priv->mipi.num_data_lanes * 1000000;
- v4l2_ctrl_new_std(&priv->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
- pixel_rate, pixel_rate, 1, pixel_rate);
-
- v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &max96712_ctrl_ops,
- V4L2_CID_TEST_PATTERN,
- ARRAY_SIZE(max96712_test_pattern) - 1,
- 0, 0, max96712_test_pattern);
-
- priv->sd.ctrl_handler = &priv->ctrl_handler;
- ret = priv->ctrl_handler.error;
- if (ret)
- goto error;
-
- priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&priv->sd.entity, 1, priv->pads);
- if (ret)
- goto error;
-
- v4l2_set_subdevdata(&priv->sd, priv);
-
- priv->sd.state_lock = priv->ctrl_handler.lock;
- ret = v4l2_subdev_init_finalize(&priv->sd);
- if (ret)
- goto error;
-
- ret = v4l2_async_register_subdev(&priv->sd);
- if (ret < 0) {
- dev_err(&priv->client->dev, "Unable to register subdevice\n");
- goto error;
- }
-
- return 0;
-error:
- v4l2_ctrl_handler_free(&priv->ctrl_handler);
-
- return ret;
-}
-
-static int max96712_parse_dt(struct max96712_priv *priv)
-{
- struct fwnode_handle *ep;
- struct v4l2_fwnode_endpoint v4l2_ep = {
- .bus_type = V4L2_MBUS_UNKNOWN,
- };
- unsigned int supported_lanes;
- int ret;
-
- ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&priv->client->dev), 4,
- 0, 0);
- if (!ep) {
- dev_err(&priv->client->dev, "Not connected to subdevice\n");
- return -EINVAL;
- }
-
- ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
- fwnode_handle_put(ep);
- if (ret) {
- dev_err(&priv->client->dev, "Could not parse v4l2 endpoint\n");
- return -EINVAL;
- }
-
- switch (v4l2_ep.bus_type) {
- case V4L2_MBUS_CSI2_DPHY:
- supported_lanes = 4;
- priv->cphy = false;
- break;
- case V4L2_MBUS_CSI2_CPHY:
- supported_lanes = 3;
- priv->cphy = true;
- break;
- default:
- dev_err(&priv->client->dev, "Unsupported bus-type %u\n",
- v4l2_ep.bus_type);
- return -EINVAL;
- }
-
- if (v4l2_ep.bus.mipi_csi2.num_data_lanes != supported_lanes) {
- dev_err(&priv->client->dev, "Only %u data lanes supported\n",
- supported_lanes);
- return -EINVAL;
- }
-
- priv->mipi = v4l2_ep.bus.mipi_csi2;
-
- return 0;
-}
-
-static const struct regmap_config max96712_i2c_regmap = {
- .reg_bits = 16,
- .val_bits = 8,
- .max_register = 0x1f00,
-};
-
-static int max96712_probe(struct i2c_client *client)
-{
- struct max96712_priv *priv;
- int ret;
-
- priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->info = of_device_get_match_data(&client->dev);
-
- priv->client = client;
-
- priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
- priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
- GPIOD_OUT_HIGH);
- if (IS_ERR(priv->gpiod_pwdn))
- return PTR_ERR(priv->gpiod_pwdn);
-
- gpiod_set_consumer_name(priv->gpiod_pwdn, "max96712-pwdn");
- gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
-
- if (priv->gpiod_pwdn)
- usleep_range(4000, 5000);
-
- max96712_reset(priv);
-
- ret = max96712_parse_dt(priv);
- if (ret)
- return ret;
-
- max96712_mipi_configure(priv);
-
- return max96712_v4l2_register(priv);
-}
-
-static void max96712_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct max96712_priv *priv = container_of(sd, struct max96712_priv, sd);
-
- v4l2_async_unregister_subdev(&priv->sd);
-
- gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
-}
-
-static const struct max96712_info max96712_info_max96712 = {
- .dpllfreq = 1000,
- .have_debug_extra = true,
-};
-
-static const struct max96712_info max96712_info_max96724 = {
- .dpllfreq = 1200,
-};
-
-static const struct of_device_id max96712_of_table[] = {
- { .compatible = "maxim,max96712", .data = &max96712_info_max96712 },
- { .compatible = "maxim,max96724", .data = &max96712_info_max96724 },
- { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, max96712_of_table);
-
-static struct i2c_driver max96712_i2c_driver = {
- .driver = {
- .name = "max96712",
- .of_match_table = of_match_ptr(max96712_of_table),
- },
- .probe = max96712_probe,
- .remove = max96712_remove,
-};
-
-module_i2c_driver(max96712_i2c_driver);
-
-MODULE_DESCRIPTION("Maxim MAX96712 Quad GMSL2 Deserializer Driver");
-MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
-MODULE_LICENSE("GPL");
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 18/19] media: i2c: remove MAX96717 driver
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (15 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 17/19] staging: media: remove " Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 19/19] media: i2c: remove MAX96714 driver Cosmin Tanislav
[not found] ` <20250618095858.2145209-16-demonsingur@gmail.com>
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The previous MAX96717 driver has been removed and its functionality has
been moved to a MAX96717 driver which makes use of the Maxim GMSL2/3
serializer framework.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
---
MAINTAINERS | 1 -
drivers/media/i2c/Kconfig | 17 -
drivers/media/i2c/Makefile | 1 -
drivers/media/i2c/max96717.c | 1103 ----------------------------------
4 files changed, 1122 deletions(-)
delete mode 100644 drivers/media/i2c/max96717.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 39020eaac338..c001a342afda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14747,7 +14747,6 @@ M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
-F: drivers/media/i2c/max96717.c
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <peda@axentia.se>
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 2147c429c9a7..da811020b655 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -1682,23 +1682,6 @@ config VIDEO_MAX96714
To compile this driver as a module, choose M here: the
module will be called max96714.
-config VIDEO_MAX96717
- tristate "Maxim MAX96717 GMSL2 Serializer support"
- depends on OF && I2C && VIDEO_DEV && COMMON_CLK
- select I2C_MUX
- select MEDIA_CONTROLLER
- select GPIOLIB
- select V4L2_CCI_I2C
- select V4L2_FWNODE
- select VIDEO_V4L2_SUBDEV_API
- help
- Device driver for the Maxim MAX96717 GMSL2 Serializer.
- MAX96717 serializers convert video on a MIPI CSI-2
- input to a GMSL2 output.
-
- To compile this driver as a module, choose M here: the
- module will be called max96717.
-
source "drivers/media/i2c/maxim-serdes/Kconfig"
endmenu
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 25a0093d40ec..29ac7ea2bfa0 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -69,7 +69,6 @@ obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
obj-$(CONFIG_VIDEO_MAX96714) += max96714.o
-obj-$(CONFIG_VIDEO_MAX96717) += max96717.o
obj-$(CONFIG_VIDEO_MAXIM_SERDES) += maxim-serdes/
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
diff --git a/drivers/media/i2c/max96717.c b/drivers/media/i2c/max96717.c
deleted file mode 100644
index a503a55fe8af..000000000000
--- a/drivers/media/i2c/max96717.c
+++ /dev/null
@@ -1,1103 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Maxim GMSL2 Serializer Driver
- *
- * Copyright (C) 2024 Collabora Ltd.
- */
-
-#include <linux/bitfield.h>
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/gpio/driver.h>
-#include <linux/i2c-mux.h>
-#include <linux/i2c.h>
-#include <linux/property.h>
-#include <linux/regmap.h>
-
-#include <media/v4l2-cci.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fwnode.h>
-#include <media/v4l2-subdev.h>
-
-#define MAX96717_DEVICE_ID 0xbf
-#define MAX96717F_DEVICE_ID 0xc8
-#define MAX96717_PORTS 2
-#define MAX96717_PAD_SINK 0
-#define MAX96717_PAD_SOURCE 1
-#define MAX96717_CSI_NLANES 4
-
-#define MAX96717_DEFAULT_CLKOUT_RATE 24000000UL
-
-/* DEV */
-#define MAX96717_REG3 CCI_REG8(0x3)
-#define MAX96717_RCLKSEL GENMASK(1, 0)
-#define RCLKSEL_REF_PLL CCI_REG8(0x3)
-#define MAX96717_REG6 CCI_REG8(0x6)
-#define RCLKEN BIT(5)
-#define MAX96717_DEV_ID CCI_REG8(0xd)
-#define MAX96717_DEV_REV CCI_REG8(0xe)
-#define MAX96717_DEV_REV_MASK GENMASK(3, 0)
-
-/* VID_TX Z */
-#define MAX96717_VIDEO_TX0 CCI_REG8(0x110)
-#define MAX96717_VIDEO_AUTO_BPP BIT(3)
-#define MAX96717_VIDEO_TX2 CCI_REG8(0x112)
-#define MAX96717_VIDEO_PCLKDET BIT(7)
-
-/* VTX_Z */
-#define MAX96717_VTX0 CCI_REG8(0x24e)
-#define MAX96717_VTX1 CCI_REG8(0x24f)
-#define MAX96717_PATTERN_CLK_FREQ GENMASK(3, 1)
-#define MAX96717_VTX_VS_DLY CCI_REG24(0x250)
-#define MAX96717_VTX_VS_HIGH CCI_REG24(0x253)
-#define MAX96717_VTX_VS_LOW CCI_REG24(0x256)
-#define MAX96717_VTX_V2H CCI_REG24(0x259)
-#define MAX96717_VTX_HS_HIGH CCI_REG16(0x25c)
-#define MAX96717_VTX_HS_LOW CCI_REG16(0x25e)
-#define MAX96717_VTX_HS_CNT CCI_REG16(0x260)
-#define MAX96717_VTX_V2D CCI_REG24(0x262)
-#define MAX96717_VTX_DE_HIGH CCI_REG16(0x265)
-#define MAX96717_VTX_DE_LOW CCI_REG16(0x267)
-#define MAX96717_VTX_DE_CNT CCI_REG16(0x269)
-#define MAX96717_VTX29 CCI_REG8(0x26b)
-#define MAX96717_VTX_MODE GENMASK(1, 0)
-#define MAX96717_VTX_GRAD_INC CCI_REG8(0x26c)
-#define MAX96717_VTX_CHKB_COLOR_A CCI_REG24(0x26d)
-#define MAX96717_VTX_CHKB_COLOR_B CCI_REG24(0x270)
-#define MAX96717_VTX_CHKB_RPT_CNT_A CCI_REG8(0x273)
-#define MAX96717_VTX_CHKB_RPT_CNT_B CCI_REG8(0x274)
-#define MAX96717_VTX_CHKB_ALT CCI_REG8(0x275)
-
-/* GPIO */
-#define MAX96717_NUM_GPIO 11
-#define MAX96717_GPIO_REG_A(gpio) CCI_REG8(0x2be + (gpio) * 3)
-#define MAX96717_GPIO_OUT BIT(4)
-#define MAX96717_GPIO_IN BIT(3)
-#define MAX96717_GPIO_RX_EN BIT(2)
-#define MAX96717_GPIO_TX_EN BIT(1)
-#define MAX96717_GPIO_OUT_DIS BIT(0)
-
-/* FRONTTOP */
-/* MAX96717 only have CSI port 'B' */
-#define MAX96717_FRONTOP0 CCI_REG8(0x308)
-#define MAX96717_START_PORT_B BIT(5)
-
-/* MIPI_RX */
-#define MAX96717_MIPI_RX1 CCI_REG8(0x331)
-#define MAX96717_MIPI_LANES_CNT GENMASK(5, 4)
-#define MAX96717_MIPI_RX2 CCI_REG8(0x332) /* phy1 Lanes map */
-#define MAX96717_PHY2_LANES_MAP GENMASK(7, 4)
-#define MAX96717_MIPI_RX3 CCI_REG8(0x333) /* phy2 Lanes map */
-#define MAX96717_PHY1_LANES_MAP GENMASK(3, 0)
-#define MAX96717_MIPI_RX4 CCI_REG8(0x334) /* phy1 lane polarities */
-#define MAX96717_PHY1_LANES_POL GENMASK(6, 4)
-#define MAX96717_MIPI_RX5 CCI_REG8(0x335) /* phy2 lane polarities */
-#define MAX96717_PHY2_LANES_POL GENMASK(2, 0)
-
-/* MIPI_RX_EXT */
-#define MAX96717_MIPI_RX_EXT11 CCI_REG8(0x383)
-#define MAX96717_TUN_MODE BIT(7)
-
-/* REF_VTG */
-#define REF_VTG0 CCI_REG8(0x3f0)
-#define REFGEN_PREDEF_EN BIT(6)
-#define REFGEN_PREDEF_FREQ_MASK GENMASK(5, 4)
-#define REFGEN_PREDEF_FREQ_ALT BIT(3)
-#define REFGEN_RST BIT(1)
-#define REFGEN_EN BIT(0)
-
-/* MISC */
-#define PIO_SLEW_1 CCI_REG8(0x570)
-
-enum max96717_vpg_mode {
- MAX96717_VPG_DISABLED = 0,
- MAX96717_VPG_CHECKERBOARD = 1,
- MAX96717_VPG_GRADIENT = 2,
-};
-
-struct max96717_priv {
- struct i2c_client *client;
- struct regmap *regmap;
- struct i2c_mux_core *mux;
- struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
- struct v4l2_subdev sd;
- struct media_pad pads[MAX96717_PORTS];
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_async_notifier notifier;
- struct v4l2_subdev *source_sd;
- u16 source_sd_pad;
- u64 enabled_source_streams;
- u8 pll_predef_index;
- struct clk_hw clk_hw;
- struct gpio_chip gpio_chip;
- enum max96717_vpg_mode pattern;
-};
-
-static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct max96717_priv, sd);
-}
-
-static inline struct max96717_priv *clk_hw_to_max96717(struct clk_hw *hw)
-{
- return container_of(hw, struct max96717_priv, clk_hw);
-}
-
-static int max96717_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
-{
- return 0;
-}
-
-static int max96717_i2c_mux_init(struct max96717_priv *priv)
-{
- priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
- 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
- max96717_i2c_mux_select, NULL);
- if (!priv->mux)
- return -ENOMEM;
-
- return i2c_mux_add_adapter(priv->mux, 0, 0);
-}
-
-static inline int max96717_start_csi(struct max96717_priv *priv, bool start)
-{
- return cci_update_bits(priv->regmap, MAX96717_FRONTOP0,
- MAX96717_START_PORT_B,
- start ? MAX96717_START_PORT_B : 0, NULL);
-}
-
-static int max96717_apply_patgen_timing(struct max96717_priv *priv,
- struct v4l2_subdev_state *state)
-{
- struct v4l2_mbus_framefmt *fmt =
- v4l2_subdev_state_get_format(state, MAX96717_PAD_SOURCE);
- const u32 h_active = fmt->width;
- const u32 h_fp = 88;
- const u32 h_sw = 44;
- const u32 h_bp = 148;
- u32 h_tot;
- const u32 v_active = fmt->height;
- const u32 v_fp = 4;
- const u32 v_sw = 5;
- const u32 v_bp = 36;
- u32 v_tot;
- int ret = 0;
-
- h_tot = h_active + h_fp + h_sw + h_bp;
- v_tot = v_active + v_fp + v_sw + v_bp;
-
- /* 75 Mhz pixel clock */
- cci_update_bits(priv->regmap, MAX96717_VTX1,
- MAX96717_PATTERN_CLK_FREQ, 0xa, &ret);
-
- dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
- fmt->width);
-
- cci_write(priv->regmap, MAX96717_VTX_VS_DLY, 0, &ret);
- cci_write(priv->regmap, MAX96717_VTX_VS_HIGH, v_sw * h_tot, &ret);
- cci_write(priv->regmap, MAX96717_VTX_VS_LOW,
- (v_active + v_fp + v_bp) * h_tot, &ret);
- cci_write(priv->regmap, MAX96717_VTX_HS_HIGH, h_sw, &ret);
- cci_write(priv->regmap, MAX96717_VTX_HS_LOW, h_active + h_fp + h_bp,
- &ret);
- cci_write(priv->regmap, MAX96717_VTX_V2D,
- h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
- cci_write(priv->regmap, MAX96717_VTX_HS_CNT, v_tot, &ret);
- cci_write(priv->regmap, MAX96717_VTX_DE_HIGH, h_active, &ret);
- cci_write(priv->regmap, MAX96717_VTX_DE_LOW, h_fp + h_sw + h_bp,
- &ret);
- cci_write(priv->regmap, MAX96717_VTX_DE_CNT, v_active, &ret);
- /* B G R */
- cci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_A, 0xfecc00, &ret);
- /* B G R */
- cci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_B, 0x006aa7, &ret);
- cci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_A, 0x3c, &ret);
- cci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_B, 0x3c, &ret);
- cci_write(priv->regmap, MAX96717_VTX_CHKB_ALT, 0x3c, &ret);
- cci_write(priv->regmap, MAX96717_VTX_GRAD_INC, 0x10, &ret);
-
- return ret;
-}
-
-static int max96717_apply_patgen(struct max96717_priv *priv,
- struct v4l2_subdev_state *state)
-{
- unsigned int val;
- int ret = 0;
-
- if (priv->pattern)
- ret = max96717_apply_patgen_timing(priv, state);
-
- cci_write(priv->regmap, MAX96717_VTX0, priv->pattern ? 0xfb : 0,
- &ret);
-
- val = FIELD_PREP(MAX96717_VTX_MODE, priv->pattern);
- cci_update_bits(priv->regmap, MAX96717_VTX29, MAX96717_VTX_MODE,
- val, &ret);
- return ret;
-}
-
-static int max96717_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct max96717_priv *priv =
- container_of(ctrl->handler, struct max96717_priv, ctrl_handler);
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_TEST_PATTERN:
- if (priv->enabled_source_streams)
- return -EBUSY;
- priv->pattern = ctrl->val;
- break;
- default:
- return -EINVAL;
- }
-
- /* Use bpp from bpp register */
- ret = cci_update_bits(priv->regmap, MAX96717_VIDEO_TX0,
- MAX96717_VIDEO_AUTO_BPP,
- priv->pattern ? 0 : MAX96717_VIDEO_AUTO_BPP,
- NULL);
-
- /*
- * Pattern generator doesn't work with tunnel mode.
- * Needs RGB color format and deserializer tunnel mode must be disabled.
- */
- return cci_update_bits(priv->regmap, MAX96717_MIPI_RX_EXT11,
- MAX96717_TUN_MODE,
- priv->pattern ? 0 : MAX96717_TUN_MODE, &ret);
-}
-
-static const char * const max96717_test_pattern[] = {
- "Disabled",
- "Checkerboard",
- "Gradient"
-};
-
-static const struct v4l2_ctrl_ops max96717_ctrl_ops = {
- .s_ctrl = max96717_s_ctrl,
-};
-
-static int max96717_gpiochip_get(struct gpio_chip *gpiochip,
- unsigned int offset)
-{
- struct max96717_priv *priv = gpiochip_get_data(gpiochip);
- u64 val;
- int ret;
-
- ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset),
- &val, NULL);
- if (ret)
- return ret;
-
- if (val & MAX96717_GPIO_OUT_DIS)
- return !!(val & MAX96717_GPIO_IN);
- else
- return !!(val & MAX96717_GPIO_OUT);
-}
-
-static int max96717_gpiochip_set(struct gpio_chip *gpiochip,
- unsigned int offset, int value)
-{
- struct max96717_priv *priv = gpiochip_get_data(gpiochip);
-
- return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
- MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
-}
-
-static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,
- unsigned int offset)
-{
- struct max96717_priv *priv = gpiochip_get_data(gpiochip);
- u64 val;
- int ret;
-
- ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset), &val, NULL);
- if (ret < 0)
- return ret;
-
- return !!(val & MAX96717_GPIO_OUT_DIS);
-}
-
-static int max96717_gpio_direction_out(struct gpio_chip *gpiochip,
- unsigned int offset, int value)
-{
- struct max96717_priv *priv = gpiochip_get_data(gpiochip);
-
- return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
- MAX96717_GPIO_OUT_DIS | MAX96717_GPIO_OUT,
- value ? MAX96717_GPIO_OUT : 0, NULL);
-}
-
-static int max96717_gpio_direction_in(struct gpio_chip *gpiochip,
- unsigned int offset)
-{
- struct max96717_priv *priv = gpiochip_get_data(gpiochip);
-
- return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
- MAX96717_GPIO_OUT_DIS, MAX96717_GPIO_OUT_DIS,
- NULL);
-}
-
-static int max96717_gpiochip_probe(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct gpio_chip *gc = &priv->gpio_chip;
- int i, ret = 0;
-
- gc->label = dev_name(dev);
- gc->parent = dev;
- gc->owner = THIS_MODULE;
- gc->ngpio = MAX96717_NUM_GPIO;
- gc->base = -1;
- gc->can_sleep = true;
- gc->get_direction = max96717_gpio_get_direction;
- gc->direction_input = max96717_gpio_direction_in;
- gc->direction_output = max96717_gpio_direction_out;
- gc->set_rv = max96717_gpiochip_set;
- gc->get = max96717_gpiochip_get;
- gc->of_gpio_n_cells = 2;
-
- /* Disable GPIO forwarding */
- for (i = 0; i < gc->ngpio; i++)
- cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(i),
- MAX96717_GPIO_RX_EN | MAX96717_GPIO_TX_EN,
- 0, &ret);
-
- if (ret)
- return ret;
-
- ret = devm_gpiochip_add_data(dev, gc, priv);
- if (ret) {
- dev_err(dev, "Unable to create gpio_chip\n");
- return ret;
- }
-
- return 0;
-}
-
-static int _max96717_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_krouting *routing)
-{
- static const struct v4l2_mbus_framefmt format = {
- .width = 1280,
- .height = 1080,
- .code = MEDIA_BUS_FMT_Y8_1X8,
- .field = V4L2_FIELD_NONE,
- };
- int ret;
-
- ret = v4l2_subdev_routing_validate(sd, routing,
- V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
- if (ret)
- return ret;
-
- ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int max96717_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- enum v4l2_subdev_format_whence which,
- struct v4l2_subdev_krouting *routing)
-{
- struct max96717_priv *priv = sd_to_max96717(sd);
-
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
- return -EBUSY;
-
- return _max96717_set_routing(sd, state, routing);
-}
-
-static int max96717_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct max96717_priv *priv = sd_to_max96717(sd);
- struct v4l2_mbus_framefmt *fmt;
- u64 stream_source_mask;
-
- if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
- priv->enabled_source_streams)
- return -EBUSY;
-
- /* No transcoding, source and sink formats must match. */
- if (format->pad == MAX96717_PAD_SOURCE)
- return v4l2_subdev_get_fmt(sd, state, format);
-
- /* Set sink format */
- fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
- if (!fmt)
- return -EINVAL;
-
- *fmt = format->format;
-
- /* Propagate to source format */
- fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
- format->stream);
- if (!fmt)
- return -EINVAL;
- *fmt = format->format;
-
- stream_source_mask = BIT(format->stream);
-
- return v4l2_subdev_state_xlate_streams(state, MAX96717_PAD_SOURCE,
- MAX96717_PAD_SINK,
- &stream_source_mask);
-}
-
-static int max96717_init_state(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state)
-{
- struct v4l2_subdev_route routes[] = {
- {
- .sink_pad = MAX96717_PAD_SINK,
- .sink_stream = 0,
- .source_pad = MAX96717_PAD_SOURCE,
- .source_stream = 0,
- .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
- },
- };
- struct v4l2_subdev_krouting routing = {
- .num_routes = ARRAY_SIZE(routes),
- .routes = routes,
- };
-
- return _max96717_set_routing(sd, state, &routing);
-}
-
-static bool max96717_pipe_pclkdet(struct max96717_priv *priv)
-{
- u64 val = 0;
-
- cci_read(priv->regmap, MAX96717_VIDEO_TX2, &val, NULL);
-
- return val & MAX96717_VIDEO_PCLKDET;
-}
-
-static int max96717_log_status(struct v4l2_subdev *sd)
-{
- struct max96717_priv *priv = sd_to_max96717(sd);
- struct device *dev = &priv->client->dev;
-
- dev_info(dev, "Serializer: max96717\n");
- dev_info(dev, "Pipe: pclkdet:%d\n", max96717_pipe_pclkdet(priv));
-
- return 0;
-}
-
-static int max96717_enable_streams(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state, u32 pad,
- u64 streams_mask)
-{
- struct max96717_priv *priv = sd_to_max96717(sd);
- u64 sink_streams;
- int ret;
-
- if (!priv->enabled_source_streams)
- max96717_start_csi(priv, true);
-
- ret = max96717_apply_patgen(priv, state);
- if (ret)
- goto stop_csi;
-
- if (!priv->pattern) {
- sink_streams =
- v4l2_subdev_state_xlate_streams(state,
- MAX96717_PAD_SOURCE,
- MAX96717_PAD_SINK,
- &streams_mask);
-
- ret = v4l2_subdev_enable_streams(priv->source_sd,
- priv->source_sd_pad,
- sink_streams);
- if (ret)
- goto stop_csi;
- }
-
- priv->enabled_source_streams |= streams_mask;
-
- return 0;
-
-stop_csi:
- if (!priv->enabled_source_streams)
- max96717_start_csi(priv, false);
-
- return ret;
-}
-
-static int max96717_disable_streams(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state, u32 pad,
- u64 streams_mask)
-{
- struct max96717_priv *priv = sd_to_max96717(sd);
- u64 sink_streams;
-
- /*
- * Stop the CSI receiver first then the source,
- * otherwise the device may become unresponsive
- * while holding the I2C bus low.
- */
- priv->enabled_source_streams &= ~streams_mask;
- if (!priv->enabled_source_streams)
- max96717_start_csi(priv, false);
-
- if (!priv->pattern) {
- int ret;
-
- sink_streams =
- v4l2_subdev_state_xlate_streams(state,
- MAX96717_PAD_SOURCE,
- MAX96717_PAD_SINK,
- &streams_mask);
-
- ret = v4l2_subdev_disable_streams(priv->source_sd,
- priv->source_sd_pad,
- sink_streams);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops max96717_pad_ops = {
- .enable_streams = max96717_enable_streams,
- .disable_streams = max96717_disable_streams,
- .set_routing = max96717_set_routing,
- .get_fmt = v4l2_subdev_get_fmt,
- .set_fmt = max96717_set_fmt,
-};
-
-static const struct v4l2_subdev_core_ops max96717_subdev_core_ops = {
- .log_status = max96717_log_status,
-};
-
-static const struct v4l2_subdev_internal_ops max96717_internal_ops = {
- .init_state = max96717_init_state,
-};
-
-static const struct v4l2_subdev_ops max96717_subdev_ops = {
- .core = &max96717_subdev_core_ops,
- .pad = &max96717_pad_ops,
-};
-
-static const struct media_entity_operations max96717_entity_ops = {
- .link_validate = v4l2_subdev_link_validate,
-};
-
-static int max96717_notify_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *source_subdev,
- struct v4l2_async_connection *asd)
-{
- struct max96717_priv *priv = sd_to_max96717(notifier->sd);
- struct device *dev = &priv->client->dev;
- int ret;
-
- ret = media_entity_get_fwnode_pad(&source_subdev->entity,
- source_subdev->fwnode,
- MEDIA_PAD_FL_SOURCE);
- if (ret < 0) {
- dev_err(dev, "Failed to find pad for %s\n",
- source_subdev->name);
- return ret;
- }
-
- priv->source_sd = source_subdev;
- priv->source_sd_pad = ret;
-
- ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad,
- &priv->sd.entity, 0,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
- if (ret) {
- dev_err(dev, "Unable to link %s:%u -> %s:0\n",
- source_subdev->name, priv->source_sd_pad,
- priv->sd.name);
- return ret;
- }
-
- return 0;
-}
-
-static const struct v4l2_async_notifier_operations max96717_notify_ops = {
- .bound = max96717_notify_bound,
-};
-
-static int max96717_v4l2_notifier_register(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct v4l2_async_connection *asd;
- struct fwnode_handle *ep_fwnode;
- int ret;
-
- ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
- MAX96717_PAD_SINK, 0, 0);
- if (!ep_fwnode) {
- dev_err(dev, "No graph endpoint\n");
- return -ENODEV;
- }
-
- v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
-
- asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode,
- struct v4l2_async_connection);
-
- fwnode_handle_put(ep_fwnode);
-
- if (IS_ERR(asd)) {
- dev_err(dev, "Failed to add subdev: %ld", PTR_ERR(asd));
- v4l2_async_nf_cleanup(&priv->notifier);
- return PTR_ERR(asd);
- }
-
- priv->notifier.ops = &max96717_notify_ops;
-
- ret = v4l2_async_nf_register(&priv->notifier);
- if (ret) {
- dev_err(dev, "Failed to register subdev_notifier");
- v4l2_async_nf_cleanup(&priv->notifier);
- return ret;
- }
-
- return 0;
-}
-
-static int max96717_subdev_init(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- int ret;
-
- v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96717_subdev_ops);
- priv->sd.internal_ops = &max96717_internal_ops;
-
- v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
- priv->sd.ctrl_handler = &priv->ctrl_handler;
-
- v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,
- &max96717_ctrl_ops,
- V4L2_CID_TEST_PATTERN,
- ARRAY_SIZE(max96717_test_pattern) - 1,
- 0, 0, max96717_test_pattern);
- if (priv->ctrl_handler.error) {
- ret = priv->ctrl_handler.error;
- goto err_free_ctrl;
- }
-
- priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
- priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
- priv->sd.entity.ops = &max96717_entity_ops;
-
- priv->pads[MAX96717_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- priv->pads[MAX96717_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
- ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);
- if (ret) {
- dev_err_probe(dev, ret, "Failed to init pads\n");
- goto err_free_ctrl;
- }
-
- ret = v4l2_subdev_init_finalize(&priv->sd);
- if (ret) {
- dev_err_probe(dev, ret,
- "v4l2 subdev init finalized failed\n");
- goto err_entity_cleanup;
- }
- ret = max96717_v4l2_notifier_register(priv);
- if (ret) {
- dev_err_probe(dev, ret,
- "v4l2 subdev notifier register failed\n");
- goto err_free_state;
- }
-
- ret = v4l2_async_register_subdev(&priv->sd);
- if (ret) {
- dev_err_probe(dev, ret, "v4l2_async_register_subdev error\n");
- goto err_unreg_notif;
- }
-
- return 0;
-
-err_unreg_notif:
- v4l2_async_nf_unregister(&priv->notifier);
- v4l2_async_nf_cleanup(&priv->notifier);
-err_free_state:
- v4l2_subdev_cleanup(&priv->sd);
-err_entity_cleanup:
- media_entity_cleanup(&priv->sd.entity);
-err_free_ctrl:
- v4l2_ctrl_handler_free(&priv->ctrl_handler);
-
- return ret;
-}
-
-static void max96717_subdev_uninit(struct max96717_priv *priv)
-{
- v4l2_async_unregister_subdev(&priv->sd);
- v4l2_async_nf_unregister(&priv->notifier);
- v4l2_async_nf_cleanup(&priv->notifier);
- v4l2_subdev_cleanup(&priv->sd);
- media_entity_cleanup(&priv->sd.entity);
- v4l2_ctrl_handler_free(&priv->ctrl_handler);
-}
-
-struct max96717_pll_predef_freq {
- unsigned long freq;
- bool is_alt;
- u8 val;
-};
-
-static const struct max96717_pll_predef_freq max96717_predef_freqs[] = {
- { 13500000, true, 0 }, { 19200000, false, 0 },
- { 24000000, true, 1 }, { 27000000, false, 1 },
- { 37125000, false, 2 }, { 74250000, false, 3 },
-};
-
-static unsigned long
-max96717_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-{
- struct max96717_priv *priv = clk_hw_to_max96717(hw);
-
- return max96717_predef_freqs[priv->pll_predef_index].freq;
-}
-
-static unsigned int max96717_clk_find_best_index(struct max96717_priv *priv,
- unsigned long rate)
-{
- unsigned int i, idx = 0;
- unsigned long diff_new, diff_old = U32_MAX;
-
- for (i = 0; i < ARRAY_SIZE(max96717_predef_freqs); i++) {
- diff_new = abs(rate - max96717_predef_freqs[i].freq);
- if (diff_new < diff_old) {
- diff_old = diff_new;
- idx = i;
- }
- }
-
- return idx;
-}
-
-static long max96717_clk_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
-{
- struct max96717_priv *priv = clk_hw_to_max96717(hw);
- struct device *dev = &priv->client->dev;
- unsigned int idx;
-
- idx = max96717_clk_find_best_index(priv, rate);
-
- if (rate != max96717_predef_freqs[idx].freq) {
- dev_warn(dev, "Request CLK freq:%lu, found CLK freq:%lu\n",
- rate, max96717_predef_freqs[idx].freq);
- }
-
- return max96717_predef_freqs[idx].freq;
-}
-
-static int max96717_clk_set_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long parent_rate)
-{
- struct max96717_priv *priv = clk_hw_to_max96717(hw);
- unsigned int val, idx;
- int ret = 0;
-
- idx = max96717_clk_find_best_index(priv, rate);
-
- val = FIELD_PREP(REFGEN_PREDEF_FREQ_MASK,
- max96717_predef_freqs[idx].val);
-
- if (max96717_predef_freqs[idx].is_alt)
- val |= REFGEN_PREDEF_FREQ_ALT;
-
- val |= REFGEN_RST | REFGEN_PREDEF_EN;
-
- cci_write(priv->regmap, REF_VTG0, val, &ret);
- cci_update_bits(priv->regmap, REF_VTG0, REFGEN_RST | REFGEN_EN,
- REFGEN_EN, &ret);
- if (ret)
- return ret;
-
- priv->pll_predef_index = idx;
-
- return 0;
-}
-
-static int max96717_clk_prepare(struct clk_hw *hw)
-{
- struct max96717_priv *priv = clk_hw_to_max96717(hw);
-
- return cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN,
- RCLKEN, NULL);
-}
-
-static void max96717_clk_unprepare(struct clk_hw *hw)
-{
- struct max96717_priv *priv = clk_hw_to_max96717(hw);
-
- cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN, 0, NULL);
-}
-
-static const struct clk_ops max96717_clk_ops = {
- .prepare = max96717_clk_prepare,
- .unprepare = max96717_clk_unprepare,
- .set_rate = max96717_clk_set_rate,
- .recalc_rate = max96717_clk_recalc_rate,
- .round_rate = max96717_clk_round_rate,
-};
-
-static int max96717_register_clkout(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct clk_init_data init = { .ops = &max96717_clk_ops };
- int ret;
-
- init.name = kasprintf(GFP_KERNEL, "max96717.%s.clk_out", dev_name(dev));
- if (!init.name)
- return -ENOMEM;
-
- /* RCLKSEL Reference PLL output */
- ret = cci_update_bits(priv->regmap, MAX96717_REG3, MAX96717_RCLKSEL,
- MAX96717_RCLKSEL, NULL);
- /* MFP4 fastest slew rate */
- cci_update_bits(priv->regmap, PIO_SLEW_1, BIT(5) | BIT(4), 0, &ret);
- if (ret)
- goto free_init_name;
-
- priv->clk_hw.init = &init;
-
- /* Initialize to 24 MHz */
- ret = max96717_clk_set_rate(&priv->clk_hw,
- MAX96717_DEFAULT_CLKOUT_RATE, 0);
- if (ret < 0)
- goto free_init_name;
-
- ret = devm_clk_hw_register(dev, &priv->clk_hw);
- kfree(init.name);
- if (ret)
- return dev_err_probe(dev, ret, "Cannot register clock HW\n");
-
- ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
- &priv->clk_hw);
- if (ret)
- return dev_err_probe(dev, ret,
- "Cannot add OF clock provider\n");
-
- return 0;
-
-free_init_name:
- kfree(init.name);
- return ret;
-}
-
-static int max96717_init_csi_lanes(struct max96717_priv *priv)
-{
- struct v4l2_mbus_config_mipi_csi2 *mipi = &priv->mipi_csi2;
- unsigned long lanes_used = 0;
- unsigned int nlanes, lane, val = 0;
- int ret;
-
- nlanes = mipi->num_data_lanes;
-
- ret = cci_update_bits(priv->regmap, MAX96717_MIPI_RX1,
- MAX96717_MIPI_LANES_CNT,
- FIELD_PREP(MAX96717_MIPI_LANES_CNT,
- nlanes - 1), NULL);
-
- /* lanes polarity */
- for (lane = 0; lane < nlanes + 1; lane++) {
- if (!mipi->lane_polarities[lane])
- continue;
- /* Clock lane */
- if (lane == 0)
- val |= BIT(2);
- else if (lane < 3)
- val |= BIT(lane - 1);
- else
- val |= BIT(lane);
- }
-
- cci_update_bits(priv->regmap, MAX96717_MIPI_RX5,
- MAX96717_PHY2_LANES_POL,
- FIELD_PREP(MAX96717_PHY2_LANES_POL, val), &ret);
-
- cci_update_bits(priv->regmap, MAX96717_MIPI_RX4,
- MAX96717_PHY1_LANES_POL,
- FIELD_PREP(MAX96717_PHY1_LANES_POL,
- val >> 3), &ret);
- /* lanes mapping */
- for (lane = 0, val = 0; lane < nlanes; lane++) {
- val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
- lanes_used |= BIT(mipi->data_lanes[lane] - 1);
- }
-
- /*
- * Unused lanes need to be mapped as well to not have
- * the same lanes mapped twice.
- */
- for (; lane < MAX96717_CSI_NLANES; lane++) {
- unsigned int idx = find_first_zero_bit(&lanes_used,
- MAX96717_CSI_NLANES);
-
- val |= idx << (lane * 2);
- lanes_used |= BIT(idx);
- }
-
- cci_update_bits(priv->regmap, MAX96717_MIPI_RX3,
- MAX96717_PHY1_LANES_MAP,
- FIELD_PREP(MAX96717_PHY1_LANES_MAP, val), &ret);
-
- return cci_update_bits(priv->regmap, MAX96717_MIPI_RX2,
- MAX96717_PHY2_LANES_MAP,
- FIELD_PREP(MAX96717_PHY2_LANES_MAP, val >> 4),
- &ret);
-}
-
-static int max96717_hw_init(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- u64 dev_id, val;
- int ret;
-
- ret = cci_read(priv->regmap, MAX96717_DEV_ID, &dev_id, NULL);
- if (ret)
- return dev_err_probe(dev, ret,
- "Fail to read the device id\n");
-
- if (dev_id != MAX96717_DEVICE_ID && dev_id != MAX96717F_DEVICE_ID)
- return dev_err_probe(dev, -EOPNOTSUPP,
- "Unsupported device id got %x\n", (u8)dev_id);
-
- ret = cci_read(priv->regmap, MAX96717_DEV_REV, &val, NULL);
- if (ret)
- return dev_err_probe(dev, ret,
- "Fail to read device revision");
-
- dev_dbg(dev, "Found %x (rev %lx)\n", (u8)dev_id,
- (u8)val & MAX96717_DEV_REV_MASK);
-
- ret = cci_read(priv->regmap, MAX96717_MIPI_RX_EXT11, &val, NULL);
- if (ret)
- return dev_err_probe(dev, ret,
- "Fail to read mipi rx extension");
-
- if (!(val & MAX96717_TUN_MODE))
- return dev_err_probe(dev, -EOPNOTSUPP,
- "Only supporting tunnel mode");
-
- return max96717_init_csi_lanes(priv);
-}
-
-static int max96717_parse_dt(struct max96717_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
- struct fwnode_handle *ep_fwnode;
- unsigned char num_data_lanes;
- int ret;
-
- ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
- MAX96717_PAD_SINK, 0, 0);
- if (!ep_fwnode)
- return dev_err_probe(dev, -ENOENT, "no endpoint found\n");
-
- ret = v4l2_fwnode_endpoint_parse(ep_fwnode, &vep);
-
- fwnode_handle_put(ep_fwnode);
-
- if (ret < 0)
- return dev_err_probe(dev, ret, "Failed to parse sink endpoint");
-
- num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
- if (num_data_lanes < 1 || num_data_lanes > MAX96717_CSI_NLANES)
- return dev_err_probe(dev, -EINVAL,
- "Invalid data lanes must be 1 to 4\n");
-
- priv->mipi_csi2 = vep.bus.mipi_csi2;
-
- return 0;
-}
-
-static int max96717_probe(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- struct max96717_priv *priv;
- int ret;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->client = client;
- priv->regmap = devm_cci_regmap_init_i2c(client, 16);
- if (IS_ERR(priv->regmap)) {
- ret = PTR_ERR(priv->regmap);
- return dev_err_probe(dev, ret, "Failed to init regmap\n");
- }
-
- ret = max96717_parse_dt(priv);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to parse the dt\n");
-
- ret = max96717_hw_init(priv);
- if (ret)
- return dev_err_probe(dev, ret,
- "Failed to initialize the hardware\n");
-
- ret = max96717_gpiochip_probe(priv);
- if (ret)
- return dev_err_probe(&client->dev, ret,
- "Failed to init gpiochip\n");
-
- ret = max96717_register_clkout(priv);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to register clkout\n");
-
- ret = max96717_subdev_init(priv);
- if (ret)
- return dev_err_probe(dev, ret,
- "Failed to initialize v4l2 subdev\n");
-
- ret = max96717_i2c_mux_init(priv);
- if (ret) {
- dev_err_probe(dev, ret, "failed to add remote i2c adapter\n");
- max96717_subdev_uninit(priv);
- }
-
- return ret;
-}
-
-static void max96717_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct max96717_priv *priv = sd_to_max96717(sd);
-
- max96717_subdev_uninit(priv);
- i2c_mux_del_adapters(priv->mux);
-}
-
-static const struct of_device_id max96717_of_ids[] = {
- { .compatible = "maxim,max96717f" },
- { }
-};
-MODULE_DEVICE_TABLE(of, max96717_of_ids);
-
-static struct i2c_driver max96717_i2c_driver = {
- .driver = {
- .name = "max96717",
- .of_match_table = max96717_of_ids,
- },
- .probe = max96717_probe,
- .remove = max96717_remove,
-};
-
-module_i2c_driver(max96717_i2c_driver);
-
-MODULE_DESCRIPTION("Maxim GMSL2 MAX96717 Serializer Driver");
-MODULE_AUTHOR("Julien Massot <julien.massot@collabora.com>");
-MODULE_LICENSE("GPL");
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH v4 19/19] media: i2c: remove MAX96714 driver
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
` (16 preceding siblings ...)
2025-06-18 9:58 ` [PATCH v4 18/19] media: i2c: remove MAX96717 driver Cosmin Tanislav
@ 2025-06-18 9:58 ` Cosmin Tanislav
[not found] ` <20250618095858.2145209-16-demonsingur@gmail.com>
18 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-18 9:58 UTC (permalink / raw)
To: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav, Cosmin Tanislav
The previous MAX96714 driver has been removed and its functionality has
been moved to the MAX9296A driver which makes use of the Maxim GMSL2/3
serializer framework.
Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
---
MAINTAINERS | 1 -
drivers/media/i2c/Kconfig | 17 -
drivers/media/i2c/Makefile | 1 -
drivers/media/i2c/max96714.c | 1024 ----------------------------------
4 files changed, 1043 deletions(-)
delete mode 100644 drivers/media/i2c/max96714.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c001a342afda..462e7d346331 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14739,7 +14739,6 @@ M: Cosmin Tanislav <cosmin.tanislav@analog.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
-F: drivers/media/i2c/max96714.c
MAX96717 GMSL2 SERIALIZER DRIVER
M: Julien Massot <julien.massot@collabora.com>
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index da811020b655..fccdb9c7d982 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -1665,23 +1665,6 @@ config VIDEO_DS90UB960
Device driver for the Texas Instruments DS90UB960
FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer.
-config VIDEO_MAX96714
- tristate "Maxim MAX96714 GMSL2 deserializer"
- depends on OF && I2C && VIDEO_DEV
- select I2C_MUX
- select MEDIA_CONTROLLER
- select GPIOLIB
- select V4L2_CCI_I2C
- select V4L2_FWNODE
- select VIDEO_V4L2_SUBDEV_API
- help
- Device driver for the Maxim MAX96714 GMSL2 Deserializer.
- MAX96714 deserializers convert a GMSL2 input to MIPI CSI-2
- output.
-
- To compile this driver as a module, choose M here: the
- module will be called max96714.
-
source "drivers/media/i2c/maxim-serdes/Kconfig"
endmenu
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 29ac7ea2bfa0..347d2dc0a796 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -68,7 +68,6 @@ obj-$(CONFIG_VIDEO_LT6911UXE) += lt6911uxe.o
obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
-obj-$(CONFIG_VIDEO_MAX96714) += max96714.o
obj-$(CONFIG_VIDEO_MAXIM_SERDES) += maxim-serdes/
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
diff --git a/drivers/media/i2c/max96714.c b/drivers/media/i2c/max96714.c
deleted file mode 100644
index 3cc1b1ae47d1..000000000000
--- a/drivers/media/i2c/max96714.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Maxim GMSL2 Deserializer Driver
- *
- * Copyright (C) 2024 Collabora Ltd.
- */
-
-#include <linux/bitfield.h>
-#include <linux/bitops.h>
-#include <linux/gpio/consumer.h>
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-#include <linux/module.h>
-#include <linux/property.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-
-#include <media/v4l2-cci.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fwnode.h>
-#include <media/v4l2-subdev.h>
-
-#define MAX96714_DEVICE_ID 0xc9
-#define MAX96714F_DEVICE_ID 0xca
-#define MAX96714_NPORTS 2
-#define MAX96714_PAD_SINK 0
-#define MAX96714_PAD_SOURCE 1
-#define MAX96714_CSI_NLANES 4
-
-/* DEV */
-#define MAX96714_REG13 CCI_REG8(0x0d)
-#define MAX96714_DEV_REV CCI_REG8(0x0e)
-#define MAX96714_DEV_REV_MASK GENMASK(3, 0)
-#define MAX96714_LINK_LOCK CCI_REG8(0x13)
-#define MAX96714_LINK_LOCK_BIT BIT(3)
-#define MAX96714_IO_CHK0 CCI_REG8(0x38)
-#define MAX96714_PATTERN_CLK_FREQ GENMASK(1, 0)
-/* VID_RX */
-#define MAX96714_VIDEO_RX8 CCI_REG8(0x11a)
-#define MAX96714_VID_LOCK BIT(6)
-
-/* VRX_PATGEN_0 */
-#define MAX96714_PATGEN_0 CCI_REG8(0x240)
-#define MAX96714_PATGEN_1 CCI_REG8(0x241)
-#define MAX96714_PATGEN_MODE GENMASK(5, 4)
-#define MAX96714_PATGEN_VS_DLY CCI_REG24(0x242)
-#define MAX96714_PATGEN_VS_HIGH CCI_REG24(0x245)
-#define MAX96714_PATGEN_VS_LOW CCI_REG24(0x248)
-#define MAX96714_PATGEN_V2H CCI_REG24(0x24b)
-#define MAX96714_PATGEN_HS_HIGH CCI_REG16(0x24e)
-#define MAX96714_PATGEN_HS_LOW CCI_REG16(0x250)
-#define MAX96714_PATGEN_HS_CNT CCI_REG16(0x252)
-#define MAX96714_PATGEN_V2D CCI_REG24(0x254)
-#define MAX96714_PATGEN_DE_HIGH CCI_REG16(0x257)
-#define MAX96714_PATGEN_DE_LOW CCI_REG16(0x259)
-#define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25b)
-#define MAX96714_PATGEN_GRAD_INC CCI_REG8(0x25d)
-#define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25e)
-#define MAX96714_PATGEN_CHKB_COLOR_B CCI_REG24(0x261)
-#define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264)
-#define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265)
-#define MAX96714_PATGEN_CHKB_ALT CCI_REG8(0x266)
-/* BACKTOP */
-#define MAX96714_BACKTOP25 CCI_REG8(0x320)
-#define CSI_DPLL_FREQ_MASK GENMASK(4, 0)
-
-/* MIPI_PHY */
-#define MAX96714_MIPI_PHY0 CCI_REG8(0x330)
-#define MAX96714_FORCE_CSI_OUT BIT(7)
-#define MAX96714_MIPI_STDBY_N CCI_REG8(0x332)
-#define MAX96714_MIPI_STDBY_MASK GENMASK(5, 4)
-#define MAX96714_MIPI_LANE_MAP CCI_REG8(0x333)
-#define MAX96714_MIPI_POLARITY CCI_REG8(0x335)
-#define MAX96714_MIPI_POLARITY_MASK GENMASK(5, 0)
-
-/* MIPI_TX */
-#define MAX96714_MIPI_LANE_CNT CCI_REG8(0x44a)
-#define MAX96714_CSI2_LANE_CNT_MASK GENMASK(7, 6)
-#define MAX96714_MIPI_TX52 CCI_REG8(0x474)
-#define MAX96714_TUN_EN BIT(0)
-
-#define MHZ(v) ((u32)((v) * 1000000U))
-
-enum max96714_vpg_mode {
- MAX96714_VPG_DISABLED = 0,
- MAX96714_VPG_CHECKERBOARD = 1,
- MAX96714_VPG_GRADIENT = 2,
-};
-
-struct max96714_rxport {
- struct {
- struct v4l2_subdev *sd;
- u16 pad;
- struct fwnode_handle *ep_fwnode;
- } source;
- struct regulator *poc;
-};
-
-struct max96714_txport {
- struct v4l2_fwnode_endpoint vep;
-};
-
-struct max96714_priv {
- struct i2c_client *client;
- struct regmap *regmap;
- struct gpio_desc *pd_gpio;
- struct max96714_rxport rxport;
- struct i2c_mux_core *mux;
- u64 enabled_source_streams;
- struct v4l2_subdev sd;
- struct media_pad pads[MAX96714_NPORTS];
- struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_async_notifier notifier;
- s64 tx_link_freq;
- enum max96714_vpg_mode pattern;
-};
-
-static inline struct max96714_priv *sd_to_max96714(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct max96714_priv, sd);
-}
-
-static int max96714_enable_tx_port(struct max96714_priv *priv)
-{
- return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
- MAX96714_MIPI_STDBY_MASK,
- MAX96714_MIPI_STDBY_MASK, NULL);
-}
-
-static int max96714_disable_tx_port(struct max96714_priv *priv)
-{
- return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
- MAX96714_MIPI_STDBY_MASK, 0, NULL);
-}
-
-static bool max96714_tx_port_enabled(struct max96714_priv *priv)
-{
- u64 val;
-
- cci_read(priv->regmap, MAX96714_MIPI_STDBY_N, &val, NULL);
-
- return val & MAX96714_MIPI_STDBY_MASK;
-}
-
-static int max96714_apply_patgen_timing(struct max96714_priv *priv,
- struct v4l2_subdev_state *state)
-{
- struct v4l2_mbus_framefmt *fmt =
- v4l2_subdev_state_get_format(state, MAX96714_PAD_SOURCE);
- const u32 h_active = fmt->width;
- const u32 h_fp = 88;
- const u32 h_sw = 44;
- const u32 h_bp = 148;
- u32 h_tot;
- const u32 v_active = fmt->height;
- const u32 v_fp = 4;
- const u32 v_sw = 5;
- const u32 v_bp = 36;
- u32 v_tot;
- int ret = 0;
-
- h_tot = h_active + h_fp + h_sw + h_bp;
- v_tot = v_active + v_fp + v_sw + v_bp;
-
- /* 75 Mhz pixel clock */
- cci_update_bits(priv->regmap, MAX96714_IO_CHK0,
- MAX96714_PATTERN_CLK_FREQ, 1, &ret);
-
- dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
- fmt->width);
-
- cci_write(priv->regmap, MAX96714_PATGEN_VS_DLY, 0, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_VS_HIGH, v_sw * h_tot, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_VS_LOW,
- (v_active + v_fp + v_bp) * h_tot, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_HS_HIGH, h_sw, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_HS_LOW, h_active + h_fp + h_bp,
- &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_V2D,
- h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_HS_CNT, v_tot, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_DE_HIGH, h_active, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_DE_LOW, h_fp + h_sw + h_bp,
- &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_DE_CNT, v_active, &ret);
- /* B G R */
- cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_A, 0xfecc00, &ret);
- /* B G R */
- cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_B, 0x006aa7, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_A, 0x3c, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_B, 0x3c, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_CHKB_ALT, 0x3c, &ret);
- cci_write(priv->regmap, MAX96714_PATGEN_GRAD_INC, 0x10, &ret);
-
- return ret;
-}
-
-static int max96714_apply_patgen(struct max96714_priv *priv,
- struct v4l2_subdev_state *state)
-{
- unsigned int val;
- int ret = 0;
-
- if (priv->pattern)
- ret = max96714_apply_patgen_timing(priv, state);
-
- cci_write(priv->regmap, MAX96714_PATGEN_0, priv->pattern ? 0xfb : 0,
- &ret);
-
- val = FIELD_PREP(MAX96714_PATGEN_MODE, priv->pattern);
- cci_update_bits(priv->regmap, MAX96714_PATGEN_1, MAX96714_PATGEN_MODE,
- val, &ret);
- return ret;
-}
-
-static int max96714_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct max96714_priv *priv =
- container_of(ctrl->handler, struct max96714_priv, ctrl_handler);
- int ret;
-
- switch (ctrl->id) {
- case V4L2_CID_TEST_PATTERN:
- if (priv->enabled_source_streams)
- return -EBUSY;
- priv->pattern = ctrl->val;
- break;
- default:
- return -EINVAL;
- }
-
- ret = cci_update_bits(priv->regmap, MAX96714_MIPI_PHY0,
- MAX96714_FORCE_CSI_OUT,
- priv->pattern ? MAX96714_FORCE_CSI_OUT : 0, NULL);
-
- /* Pattern generator doesn't work with tunnel mode */
- return cci_update_bits(priv->regmap, MAX96714_MIPI_TX52,
- MAX96714_TUN_EN,
- priv->pattern ? 0 : MAX96714_TUN_EN, &ret);
-}
-
-static const char * const max96714_test_pattern[] = {
- "Disabled",
- "Checkerboard",
- "Gradient"
-};
-
-static const struct v4l2_ctrl_ops max96714_ctrl_ops = {
- .s_ctrl = max96714_s_ctrl,
-};
-
-static int max96714_enable_streams(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- u32 source_pad, u64 streams_mask)
-{
- struct max96714_priv *priv = sd_to_max96714(sd);
- u64 sink_streams;
- int ret;
-
- if (!priv->enabled_source_streams)
- max96714_enable_tx_port(priv);
-
- ret = max96714_apply_patgen(priv, state);
- if (ret)
- goto err;
-
- if (!priv->pattern) {
- if (!priv->rxport.source.sd) {
- ret = -ENODEV;
- goto err;
- }
-
- sink_streams =
- v4l2_subdev_state_xlate_streams(state,
- MAX96714_PAD_SOURCE,
- MAX96714_PAD_SINK,
- &streams_mask);
-
- ret = v4l2_subdev_enable_streams(priv->rxport.source.sd,
- priv->rxport.source.pad,
- sink_streams);
- if (ret)
- goto err;
- }
-
- priv->enabled_source_streams |= streams_mask;
-
- return 0;
-
-err:
- if (!priv->enabled_source_streams)
- max96714_disable_tx_port(priv);
-
- return ret;
-}
-
-static int max96714_disable_streams(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- u32 source_pad, u64 streams_mask)
-{
- struct max96714_priv *priv = sd_to_max96714(sd);
- u64 sink_streams;
-
- if (!priv->pattern) {
- int ret;
-
- sink_streams =
- v4l2_subdev_state_xlate_streams(state,
- MAX96714_PAD_SOURCE,
- MAX96714_PAD_SINK,
- &streams_mask);
-
- ret = v4l2_subdev_disable_streams(priv->rxport.source.sd,
- priv->rxport.source.pad,
- sink_streams);
- if (ret)
- return ret;
- }
-
- priv->enabled_source_streams &= ~streams_mask;
-
- if (!priv->enabled_source_streams)
- max96714_disable_tx_port(priv);
-
- return 0;
-}
-
-static int max96714_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct max96714_priv *priv = sd_to_max96714(sd);
- struct v4l2_mbus_framefmt *fmt;
-
- if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
- priv->enabled_source_streams)
- return -EBUSY;
-
- /* No transcoding, source and sink formats must match. */
- if (format->pad == MAX96714_PAD_SOURCE)
- return v4l2_subdev_get_fmt(sd, state, format);
-
- fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
- if (!fmt)
- return -EINVAL;
-
- *fmt = format->format;
-
- fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
- format->stream);
- if (!fmt)
- return -EINVAL;
-
- *fmt = format->format;
-
- return 0;
-}
-
-static int _max96714_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- enum v4l2_subdev_format_whence which,
- struct v4l2_subdev_krouting *routing)
-{
- static const struct v4l2_mbus_framefmt format = {
- .width = 1280,
- .height = 1080,
- .code = MEDIA_BUS_FMT_Y8_1X8,
- .field = V4L2_FIELD_NONE,
- };
- int ret;
-
- /*
- * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
- * frame desc is made dynamically allocated.
- */
- if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
- return -EINVAL;
-
- ret = v4l2_subdev_routing_validate(sd, routing,
- V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
- if (ret)
- return ret;
-
- return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
-}
-
-static int max96714_set_routing(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state,
- enum v4l2_subdev_format_whence which,
- struct v4l2_subdev_krouting *routing)
-{
- struct max96714_priv *priv = sd_to_max96714(sd);
-
- if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
- return -EBUSY;
-
- return _max96714_set_routing(sd, state, which, routing);
-}
-
-static int max96714_init_state(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *state)
-{
- struct v4l2_subdev_route routes[] = {
- {
- .sink_pad = MAX96714_PAD_SINK,
- .sink_stream = 0,
- .source_pad = MAX96714_PAD_SOURCE,
- .source_stream = 0,
- .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
- }
- };
- struct v4l2_subdev_krouting routing = {
- .num_routes = ARRAY_SIZE(routes),
- .routes = routes,
- };
-
- return _max96714_set_routing(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE,
- &routing);
-}
-
-static const struct v4l2_subdev_pad_ops max96714_pad_ops = {
- .enable_streams = max96714_enable_streams,
- .disable_streams = max96714_disable_streams,
-
- .set_routing = max96714_set_routing,
- .get_fmt = v4l2_subdev_get_fmt,
- .set_fmt = max96714_set_fmt,
-};
-
-static bool max96714_link_locked(struct max96714_priv *priv)
-{
- u64 val = 0;
-
- cci_read(priv->regmap, MAX96714_LINK_LOCK, &val, NULL);
-
- return val & MAX96714_LINK_LOCK_BIT;
-}
-
-static void max96714_link_status(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
-
- dev_info(dev, "Link locked:%d\n", max96714_link_locked(priv));
-}
-
-static bool max96714_pipe_locked(struct max96714_priv *priv)
-{
- u64 val;
-
- cci_read(priv->regmap, MAX96714_VIDEO_RX8, &val, NULL);
-
- return val & MAX96714_VID_LOCK;
-}
-
-static void max96714_pipe_status(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
-
- dev_info(dev, "Pipe vidlock:%d\n", max96714_pipe_locked(priv));
-}
-
-static void max96714_csi_status(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- u64 freq = 0;
-
- cci_read(priv->regmap, MAX96714_BACKTOP25, &freq, NULL);
- freq = FIELD_GET(CSI_DPLL_FREQ_MASK, freq);
-
- dev_info(dev, "CSI controller DPLL freq:%u00MHz CSIPHY enabled:%d\n",
- (u8)freq, max96714_tx_port_enabled(priv));
-}
-
-static int max96714_log_status(struct v4l2_subdev *sd)
-{
- struct max96714_priv *priv = sd_to_max96714(sd);
- struct device *dev = &priv->client->dev;
-
- dev_info(dev, "Deserializer: max96714\n");
-
- max96714_link_status(priv);
- max96714_pipe_status(priv);
- max96714_csi_status(priv);
-
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops max96714_subdev_core_ops = {
- .log_status = max96714_log_status,
-};
-
-static const struct v4l2_subdev_video_ops max96714_video_ops = {
- .s_stream = v4l2_subdev_s_stream_helper,
-};
-
-static const struct v4l2_subdev_internal_ops max96714_internal_ops = {
- .init_state = max96714_init_state,
-};
-
-static const struct v4l2_subdev_ops max96714_subdev_ops = {
- .video = &max96714_video_ops,
- .core = &max96714_subdev_core_ops,
- .pad = &max96714_pad_ops,
-};
-
-static const struct media_entity_operations max96714_entity_ops = {
- .link_validate = v4l2_subdev_link_validate,
-};
-
-static int max96714_notify_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *subdev,
- struct v4l2_async_connection *asd)
-{
- struct max96714_priv *priv = sd_to_max96714(notifier->sd);
- struct device *dev = &priv->client->dev;
- int ret;
-
- ret = media_entity_get_fwnode_pad(&subdev->entity,
- priv->rxport.source.ep_fwnode,
- MEDIA_PAD_FL_SOURCE);
- if (ret < 0) {
- dev_err(dev, "Failed to find pad for %s\n", subdev->name);
- return ret;
- }
-
- priv->rxport.source.sd = subdev;
- priv->rxport.source.pad = ret;
-
- ret = media_create_pad_link(&priv->rxport.source.sd->entity,
- priv->rxport.source.pad, &priv->sd.entity,
- MAX96714_PAD_SINK,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
- if (ret) {
- dev_err(dev, "Unable to link %s:%u -> %s:%u\n",
- priv->rxport.source.sd->name, priv->rxport.source.pad,
- priv->sd.name, MAX96714_PAD_SINK);
- return ret;
- }
-
- return 0;
-}
-
-static const struct v4l2_async_notifier_operations max96714_notify_ops = {
- .bound = max96714_notify_bound,
-};
-
-static int max96714_v4l2_notifier_register(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct max96714_rxport *rxport = &priv->rxport;
- struct v4l2_async_connection *asd;
- int ret;
-
- if (!rxport->source.ep_fwnode)
- return 0;
-
- v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
-
- asd = v4l2_async_nf_add_fwnode(&priv->notifier,
- rxport->source.ep_fwnode,
- struct v4l2_async_connection);
- if (IS_ERR(asd)) {
- dev_err(dev, "Failed to add subdev: %pe", asd);
- v4l2_async_nf_cleanup(&priv->notifier);
- return PTR_ERR(asd);
- }
-
- priv->notifier.ops = &max96714_notify_ops;
-
- ret = v4l2_async_nf_register(&priv->notifier);
- if (ret) {
- dev_err(dev, "Failed to register subdev_notifier");
- v4l2_async_nf_cleanup(&priv->notifier);
- return ret;
- }
-
- return 0;
-}
-
-static int max96714_create_subdev(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- int ret;
-
- v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96714_subdev_ops);
- priv->sd.internal_ops = &max96714_internal_ops;
-
- v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
- priv->sd.ctrl_handler = &priv->ctrl_handler;
-
- v4l2_ctrl_new_int_menu(&priv->ctrl_handler, NULL, V4L2_CID_LINK_FREQ,
- 0, 0, &priv->tx_link_freq);
- v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,
- &max96714_ctrl_ops,
- V4L2_CID_TEST_PATTERN,
- ARRAY_SIZE(max96714_test_pattern) - 1,
- 0, 0, max96714_test_pattern);
- if (priv->ctrl_handler.error) {
- ret = priv->ctrl_handler.error;
- goto err_free_ctrl;
- }
-
- priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
- priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
- priv->sd.entity.ops = &max96714_entity_ops;
-
- priv->pads[MAX96714_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- priv->pads[MAX96714_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
- ret = media_entity_pads_init(&priv->sd.entity,
- MAX96714_NPORTS,
- priv->pads);
- if (ret)
- goto err_free_ctrl;
-
- priv->sd.state_lock = priv->sd.ctrl_handler->lock;
-
- ret = v4l2_subdev_init_finalize(&priv->sd);
- if (ret)
- goto err_entity_cleanup;
-
- ret = max96714_v4l2_notifier_register(priv);
- if (ret) {
- dev_err(dev, "v4l2 subdev notifier register failed: %d\n", ret);
- goto err_subdev_cleanup;
- }
-
- ret = v4l2_async_register_subdev(&priv->sd);
- if (ret) {
- dev_err(dev, "v4l2_async_register_subdev error: %d\n", ret);
- goto err_unreg_notif;
- }
-
- return 0;
-
-err_unreg_notif:
- v4l2_async_nf_unregister(&priv->notifier);
- v4l2_async_nf_cleanup(&priv->notifier);
-err_subdev_cleanup:
- v4l2_subdev_cleanup(&priv->sd);
-err_entity_cleanup:
- media_entity_cleanup(&priv->sd.entity);
-err_free_ctrl:
- v4l2_ctrl_handler_free(&priv->ctrl_handler);
-
- return ret;
-};
-
-static void max96714_destroy_subdev(struct max96714_priv *priv)
-{
- v4l2_async_nf_unregister(&priv->notifier);
- v4l2_async_nf_cleanup(&priv->notifier);
- v4l2_async_unregister_subdev(&priv->sd);
-
- v4l2_subdev_cleanup(&priv->sd);
-
- media_entity_cleanup(&priv->sd.entity);
- v4l2_ctrl_handler_free(&priv->ctrl_handler);
-}
-
-static int max96714_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
-{
- return 0;
-}
-
-static int max96714_i2c_mux_init(struct max96714_priv *priv)
-{
- priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
- 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
- max96714_i2c_mux_select, NULL);
- if (!priv->mux)
- return -ENOMEM;
-
- return i2c_mux_add_adapter(priv->mux, 0, 0);
-}
-
-static int max96714_init_tx_port(struct max96714_priv *priv)
-{
- struct v4l2_mbus_config_mipi_csi2 *mipi;
- unsigned long lanes_used = 0;
- unsigned int val, lane;
- int ret;
-
- ret = max96714_disable_tx_port(priv);
-
- mipi = &priv->mipi_csi2;
- val = div_u64(priv->tx_link_freq * 2, MHZ(100));
-
- cci_update_bits(priv->regmap, MAX96714_BACKTOP25,
- CSI_DPLL_FREQ_MASK, val, &ret);
-
- val = FIELD_PREP(MAX96714_CSI2_LANE_CNT_MASK, mipi->num_data_lanes - 1);
- cci_update_bits(priv->regmap, MAX96714_MIPI_LANE_CNT,
- MAX96714_CSI2_LANE_CNT_MASK, val, &ret);
-
- /* lanes polarity */
- val = 0;
- for (lane = 0; lane < mipi->num_data_lanes + 1; lane++) {
- if (!mipi->lane_polarities[lane])
- continue;
- if (lane == 0)
- /* clock lane */
- val |= BIT(5);
- else if (lane < 3)
- /* Lane D0 and D1 */
- val |= BIT(lane - 1);
- else
- /* D2 and D3 */
- val |= BIT(lane);
- }
-
- cci_update_bits(priv->regmap, MAX96714_MIPI_POLARITY,
- MAX96714_MIPI_POLARITY_MASK, val, &ret);
-
- /* lanes mapping */
- val = 0;
- for (lane = 0; lane < mipi->num_data_lanes; lane++) {
- val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
- lanes_used |= BIT(mipi->data_lanes[lane] - 1);
- }
-
- /*
- * Unused lanes need to be mapped as well to not have
- * the same lanes mapped twice.
- */
- for (; lane < MAX96714_CSI_NLANES; lane++) {
- unsigned int idx = find_first_zero_bit(&lanes_used,
- MAX96714_CSI_NLANES);
-
- val |= idx << (lane * 2);
- lanes_used |= BIT(idx);
- }
-
- return cci_write(priv->regmap, MAX96714_MIPI_LANE_MAP, val, &ret);
-}
-
-static int max96714_rxport_enable_poc(struct max96714_priv *priv)
-{
- struct max96714_rxport *rxport = &priv->rxport;
-
- if (!rxport->poc)
- return 0;
-
- return regulator_enable(rxport->poc);
-}
-
-static int max96714_rxport_disable_poc(struct max96714_priv *priv)
-{
- struct max96714_rxport *rxport = &priv->rxport;
-
- if (!rxport->poc)
- return 0;
-
- return regulator_disable(rxport->poc);
-}
-
-static int max96714_parse_dt_txport(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY };
- struct fwnode_handle *ep_fwnode;
- u32 num_data_lanes;
- int ret;
-
- ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
- MAX96714_PAD_SOURCE, 0, 0);
- if (!ep_fwnode)
- return -EINVAL;
-
- ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &vep);
- fwnode_handle_put(ep_fwnode);
- if (ret) {
- dev_err(dev, "tx: failed to parse endpoint data\n");
- return -EINVAL;
- }
-
- if (vep.nr_of_link_frequencies != 1) {
- ret = -EINVAL;
- goto err_free_vep;
- }
-
- priv->tx_link_freq = vep.link_frequencies[0];
- /* Min 50MHz, Max 1250MHz, 50MHz step */
- if (priv->tx_link_freq < MHZ(50) || priv->tx_link_freq > MHZ(1250) ||
- (u32)priv->tx_link_freq % MHZ(50)) {
- dev_err(dev, "tx: invalid link frequency\n");
- ret = -EINVAL;
- goto err_free_vep;
- }
-
- num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
- if (num_data_lanes < 1 || num_data_lanes > MAX96714_CSI_NLANES) {
- dev_err(dev,
- "tx: invalid number of data lanes must be 1 to 4\n");
- ret = -EINVAL;
- goto err_free_vep;
- }
-
- priv->mipi_csi2 = vep.bus.mipi_csi2;
-
-err_free_vep:
- v4l2_fwnode_endpoint_free(&vep);
-
- return ret;
-}
-
-static int max96714_parse_dt_rxport(struct max96714_priv *priv)
-{
- static const char *poc_name = "port0-poc";
- struct max96714_rxport *rxport = &priv->rxport;
- struct device *dev = &priv->client->dev;
- struct fwnode_handle *ep_fwnode;
- int ret;
-
- ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
- MAX96714_PAD_SINK, 0, 0);
- if (!ep_fwnode)
- return -ENOENT;
-
- rxport->source.ep_fwnode = fwnode_graph_get_remote_endpoint(ep_fwnode);
- fwnode_handle_put(ep_fwnode);
-
- if (!rxport->source.ep_fwnode) {
- dev_err(dev, "rx: no remote endpoint\n");
- return -EINVAL;
- }
-
- rxport->poc = devm_regulator_get_optional(dev, poc_name);
- if (IS_ERR(rxport->poc)) {
- ret = PTR_ERR(rxport->poc);
- if (ret == -ENODEV) {
- rxport->poc = NULL;
- } else {
- dev_err(dev, "rx: failed to get POC supply: %d\n", ret);
- goto err_put_source_ep_fwnode;
- }
- }
-
- return 0;
-
-err_put_source_ep_fwnode:
- fwnode_handle_put(rxport->source.ep_fwnode);
- return ret;
-}
-
-static int max96714_parse_dt(struct max96714_priv *priv)
-{
- int ret;
-
- ret = max96714_parse_dt_txport(priv);
- if (ret)
- return ret;
-
- ret = max96714_parse_dt_rxport(priv);
- /*
- * The deserializer can create a test pattern even if the
- * rx port is not connected to a serializer.
- */
- if (ret && ret == -ENOENT)
- ret = 0;
-
- return ret;
-}
-
-static int max96714_enable_core_hw(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
- u64 val;
- int ret;
-
- if (priv->pd_gpio) {
- /* wait min 2 ms for reset to complete */
- gpiod_set_value_cansleep(priv->pd_gpio, 1);
- fsleep(2000);
- gpiod_set_value_cansleep(priv->pd_gpio, 0);
- /* wait min 2 ms for power up to finish */
- fsleep(2000);
- }
-
- ret = cci_read(priv->regmap, MAX96714_REG13, &val, NULL);
- if (ret) {
- dev_err_probe(dev, ret, "Cannot read first register, abort\n");
- goto err_pd_gpio;
- }
-
- if (val != MAX96714_DEVICE_ID && val != MAX96714F_DEVICE_ID) {
- dev_err(dev, "Unsupported device id expected %x got %x\n",
- MAX96714F_DEVICE_ID, (u8)val);
- ret = -EOPNOTSUPP;
- goto err_pd_gpio;
- }
-
- ret = cci_read(priv->regmap, MAX96714_DEV_REV, &val, NULL);
- if (ret)
- goto err_pd_gpio;
-
- dev_dbg(dev, "Found %x (rev %lx)\n", MAX96714F_DEVICE_ID,
- (u8)val & MAX96714_DEV_REV_MASK);
-
- ret = cci_read(priv->regmap, MAX96714_MIPI_TX52, &val, NULL);
- if (ret)
- goto err_pd_gpio;
-
- if (!(val & MAX96714_TUN_EN)) {
- dev_err(dev, "Only supporting tunnel mode");
- ret = -EOPNOTSUPP;
- goto err_pd_gpio;
- }
-
- return 0;
-
-err_pd_gpio:
- gpiod_set_value_cansleep(priv->pd_gpio, 1);
- return ret;
-}
-
-static void max96714_disable_core_hw(struct max96714_priv *priv)
-{
- gpiod_set_value_cansleep(priv->pd_gpio, 1);
-}
-
-static int max96714_get_hw_resources(struct max96714_priv *priv)
-{
- struct device *dev = &priv->client->dev;
-
- priv->regmap = devm_cci_regmap_init_i2c(priv->client, 16);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
-
- priv->pd_gpio =
- devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH);
- if (IS_ERR(priv->pd_gpio))
- return dev_err_probe(dev, PTR_ERR(priv->pd_gpio),
- "Cannot get powerdown GPIO\n");
- return 0;
-}
-
-static int max96714_probe(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- struct max96714_priv *priv;
- int ret;
-
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->client = client;
-
- ret = max96714_get_hw_resources(priv);
- if (ret)
- return ret;
-
- ret = max96714_enable_core_hw(priv);
- if (ret)
- return ret;
-
- ret = max96714_parse_dt(priv);
- if (ret)
- goto err_disable_core_hw;
-
- max96714_init_tx_port(priv);
-
- ret = max96714_rxport_enable_poc(priv);
- if (ret)
- goto err_free_ports;
-
- ret = max96714_i2c_mux_init(priv);
- if (ret)
- goto err_disable_poc;
-
- ret = max96714_create_subdev(priv);
- if (ret)
- goto err_del_mux;
-
- return 0;
-
-err_del_mux:
- i2c_mux_del_adapters(priv->mux);
-err_disable_poc:
- max96714_rxport_disable_poc(priv);
-err_free_ports:
- fwnode_handle_put(priv->rxport.source.ep_fwnode);
-err_disable_core_hw:
- max96714_disable_core_hw(priv);
-
- return ret;
-}
-
-static void max96714_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct max96714_priv *priv = sd_to_max96714(sd);
-
- max96714_destroy_subdev(priv);
- i2c_mux_del_adapters(priv->mux);
- max96714_rxport_disable_poc(priv);
- fwnode_handle_put(priv->rxport.source.ep_fwnode);
- max96714_disable_core_hw(priv);
- gpiod_set_value_cansleep(priv->pd_gpio, 1);
-}
-
-static const struct of_device_id max96714_of_ids[] = {
- { .compatible = "maxim,max96714f" },
- { }
-};
-MODULE_DEVICE_TABLE(of, max96714_of_ids);
-
-static struct i2c_driver max96714_i2c_driver = {
- .driver = {
- .name = "max96714",
- .of_match_table = max96714_of_ids,
- },
- .probe = max96714_probe,
- .remove = max96714_remove,
-};
-
-module_i2c_driver(max96714_i2c_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Maxim Integrated GMSL2 Deserializers Driver");
-MODULE_AUTHOR("Julien Massot <julien.massot@collabora.com>");
--
2.49.0
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A
2025-06-18 9:58 ` [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A Cosmin Tanislav
@ 2025-06-18 13:00 ` Rob Herring (Arm)
0 siblings, 0 replies; 31+ messages in thread
From: Rob Herring (Arm) @ 2025-06-18 13:00 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Julien Massot, Tomi Valkeinen, Mauro Carvalho Chehab,
linux-staging, linux-arm-kernel, Linus Walleij, devicetree,
Niklas Söderlund, linux-kernel, Sakari Ailus,
Cosmin Tanislav, Greg Kroah-Hartman, linux-media, linux-gpio,
Laurent Pinchart
On Wed, 18 Jun 2025 12:58:50 +0300, Cosmin Tanislav wrote:
> The MAX9296A deserializer converts single or dual serial inputs to MIPI
> CSI-2 outputs. The GMSL2 links operate at a fixed rate of 3Gbps or 6Gbps
> in the forward direction and 187.5Mbps in the reverse direction.
> In GMSL1 mode, each serial link can be paired with 3.12Gbps or 1.5Gbps
> GMSL1 serializers or operate up to 4.5Gbps with GMSL2 serializers with
> GMSL1 backward compatibility. The MAX9296A supports mixed GMSL2 and
> GMSL1 links. The serial inputs operate independently, allowing videos
> with different timings and resolutions to be received on each input.
>
> MAX96716A supports both tunnel and pixel mode.
> MAX96792A supports both tunnel and pixel mode, and has two GMSL3 links.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../bindings/media/i2c/maxim,max9296a.yaml | 242 ++++++++++++++++++
> MAINTAINERS | 6 +
> 2 files changed, 248 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max9296a.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/media/i2c/maxim,max9296a.example.dtb: serializer@40 (maxim,max96717): compatible: 'oneOf' conditional failed, one must be fixed:
['maxim,max96717'] is too short
'maxim,max96717' is not one of ['maxim,max9295a', 'maxim,max96717f']
from schema $id: http://devicetree.org/schemas/media/i2c/maxim,max96717.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/media/i2c/maxim,max9296a.example.dtb: serializer@40 (maxim,max96717): compatible: 'oneOf' conditional failed, one must be fixed:
['maxim,max96717'] is too short
'maxim,max96717' is not one of ['maxim,max9295a', 'maxim,max96717f']
from schema $id: http://devicetree.org/schemas/media/i2c/maxim,max96717.yaml#
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250618095858.2145209-15-demonsingur@gmail.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer
2025-06-18 9:58 ` [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer Cosmin Tanislav
@ 2025-06-19 10:31 ` Niklas Söderlund
0 siblings, 0 replies; 31+ messages in thread
From: Niklas Söderlund @ 2025-06-19 10:31 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring, Julien Massot,
Sakari Ailus, Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
Thanks for your patch.
On 2025-06-18 12:58:43 +0300, Cosmin Tanislav wrote:
> Analog Devices is taking responsability for the maintenance of the Maxim
> GMSL2/3 devices.
> Add myself to the maintainers list and to the device tree bindings.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml | 1 +
> MAINTAINERS | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> index 26f85151afbd..efdece2b33b9 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> @@ -9,6 +9,7 @@ title: Quad GMSL2 to CSI-2 Deserializer with GMSL1 Compatibility
>
> maintainers:
> - Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> + - Cosmin Tanislav <cosmin.tanislav@analog.com>
>
> description: |
> The MAX96712 deserializer converts GMSL2 or GMSL1 serial inputs into MIPI
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 01363fbcb9b3..77adb1f7ac9c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14728,6 +14728,7 @@ F: drivers/media/i2c/max9286.c
>
> MAX96712 QUAD GMSL2 DESERIALIZER DRIVER
> M: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> +M: Cosmin Tanislav <cosmin.tanislav@analog.com>
> L: linux-media@vger.kernel.org
> S: Maintained
> F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> --
> 2.49.0
>
--
Kind Regards,
Niklas Söderlund
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports
2025-06-18 9:58 ` [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports Cosmin Tanislav
@ 2025-06-19 11:17 ` Niklas Söderlund
0 siblings, 0 replies; 31+ messages in thread
From: Niklas Söderlund @ 2025-06-19 11:17 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring, Julien Massot,
Sakari Ailus, Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
Thanks for your work.
On 2025-06-18 12:58:44 +0300, Cosmin Tanislav wrote:
> The MAX96712 and MAX96724 support up to 4 separate PHYs, depending on
> the selected PHY configuration. Use patternProperties to document this.
>
> The input ports are all the same, use patternProperties for them.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> .../bindings/media/i2c/maxim,max96712.yaml | 29 +++++++------------
> 1 file changed, 10 insertions(+), 19 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> index efdece2b33b9..f712d7cfc35f 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> @@ -40,27 +40,15 @@ properties:
> ports:
> $ref: /schemas/graph.yaml#/properties/ports
>
> - properties:
> - port@0:
> + patternProperties:
> + '^port@[0-3]$':
> $ref: /schemas/graph.yaml#/properties/port
> - description: GMSL Input 0
> + description: GMSL Input ports 0-3
>
> - port@1:
> - $ref: /schemas/graph.yaml#/properties/port
> - description: GMSL Input 1
> -
> - port@2:
> - $ref: /schemas/graph.yaml#/properties/port
> - description: GMSL Input 2
> -
> - port@3:
> - $ref: /schemas/graph.yaml#/properties/port
> - description: GMSL Input 3
> -
> - port@4:
> + '^port@[4-7]$':
> $ref: /schemas/graph.yaml#/$defs/port-base
> unevaluatedProperties: false
> - description: CSI-2 Output
> + description: CSI-2 Output port 0-3
>
> properties:
> endpoint:
> @@ -78,8 +66,11 @@ properties:
> - data-lanes
> - bus-type
>
> - required:
> - - port@4
> + anyOf:
> + - required: [port@4]
> + - required: [port@5]
> + - required: [port@6]
> + - required: [port@7]
>
> required:
> - compatible
> --
> 2.49.0
>
--
Kind Regards,
Niklas Söderlund
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies
2025-06-18 9:58 ` [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies Cosmin Tanislav
@ 2025-06-19 13:32 ` Niklas Söderlund
0 siblings, 0 replies; 31+ messages in thread
From: Niklas Söderlund @ 2025-06-19 13:32 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring, Julien Massot,
Sakari Ailus, Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
Thanks for your work.
On 2025-06-18 12:58:46 +0300, Cosmin Tanislav wrote:
> The GMSL links can carry power to the serializer when using coaxial
> cables.
>
> Document this capability.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> .../devicetree/bindings/media/i2c/maxim,max96712.yaml | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> index 758c0223977d..b345305acc4c 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> @@ -96,6 +96,10 @@ properties:
> - required: [port@6]
> - required: [port@7]
>
> +patternProperties:
> + '^port[0-3]-poc-supply$':
> + description: Regulator providing Power over Coax for GMSL ports
> +
> required:
> - compatible
> - reg
> --
> 2.49.0
>
--
Kind Regards,
Niklas Söderlund
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R
2025-06-18 9:58 ` [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R Cosmin Tanislav
@ 2025-06-19 13:33 ` Niklas Söderlund
0 siblings, 0 replies; 31+ messages in thread
From: Niklas Söderlund @ 2025-06-19 13:33 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring, Julien Massot,
Sakari Ailus, Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hello Cosmin,
Thanks for your work.
On 2025-06-18 12:58:47 +0300, Cosmin Tanislav wrote:
> MAX96724F/MAX96724R are a lower capability variant of the MAX96724 which
> only support a fixed rate of 3Gbps in the forward direction.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
> ---
> .../devicetree/bindings/media/i2c/maxim,max96712.yaml | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> index b345305acc4c..5dcafd46344c 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
> @@ -24,12 +24,17 @@ description: |
> MAX96712 can be paired with first-generation 3.12Gbps or 1.5Gbps GMSL1
> serializers or operate up to 3.12Gbps with GMSL2 serializers in GMSL1 mode.
>
> + MAX96724F and MAX96724R only support a fixed rate of 3Gbps in the forward
> + direction.
> +
> properties:
> compatible:
> items:
> - enum:
> - maxim,max96712
> - maxim,max96724
> + - maxim,max96724f
> + - maxim,max96724r
>
> reg:
> description: I2C device address
> --
> 2.49.0
>
--
Kind Regards,
Niklas Söderlund
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 15/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
[not found] ` <20250618095858.2145209-16-demonsingur@gmail.com>
@ 2025-06-19 18:30 ` Jakub Kostiw
[not found] ` <aFpnU8EHGt14UMHC@kekkonen.localdomain>
1 sibling, 0 replies; 31+ messages in thread
From: Jakub Kostiw @ 2025-06-19 18:30 UTC (permalink / raw)
To: Cosmin Tanislav, Tomi Valkeinen, Mauro Carvalho Chehab,
Rob Herring, Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
I have tested V4 on Raspberry Pi 5 (v6.15) and I think that I might have
found some issues.
MAX96714+MAX96717+IMX219:
Streaming to memory works as expected, however I have encountered issues
when I was testing
this with libcamera (streams + meta pad).
To make things work in the first place (tested on V3) I had to create 2
streams - one for image
and one for metadata. Essentialy what I did was setting up routes as
follows (for both serializer
and deserializer):
Image stream: [0/0 -> 1/0]
Meta stream: [0/1 -> 1/1]
With that and some extra adjustments on libcamera side I was able to get
video stream.
Now, above fails on V4. I belive that this is to due with following line:
max_ser.c:
> + ret = max_validate_tpg_routing(routing);
> + if (ret)
> + return ret;
Routing fails here as (I believe) tpg routing is checked even if tpg is not being routed.
After I commented out this check all worked as before. This was not a problem for deserializer
as such check does not exist there.
Perhaps this check should be conducted only when is_tpg is true?
MAX96724+MAX96717+IMX219:
This setup was also tested by me on V3 (streaming to memory only) and worked as expected. With V4
however, after setting up the pipeline, I am unable to get video stream. No error is reported.
I doubled checked my setup with V3 and it worked flawlessly (with the same configuration scripts).
Streaming simply hangs after VIDIOC_STREAMON. I am able to quickly test V3 and V4 so I can provide
you some further information if needed.
--
Regards
Jakub
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 15/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
[not found] ` <aFpnU8EHGt14UMHC@kekkonen.localdomain>
@ 2025-06-24 15:34 ` Cosmin Tanislav
2025-06-28 18:10 ` Sakari Ailus
0 siblings, 1 reply; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-24 15:34 UTC (permalink / raw)
To: Sakari Ailus
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Laurent Pinchart,
Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
On 6/24/25 11:52 AM, Sakari Ailus wrote:
> Hi Cosmin,
>
> Thanks for the set.
>
> This patch is pretty massive. Could you split it into the serialiser and
> deserialiser frameworks and then invididual drivers using it (six-ish
> patches in total)?
>
I'll try to split it up for easier review, thanks.
I'll strip some of the context so I can answer easier.
The comments I stripped out are things I'll do without discussion.
...
>> +struct max9296a_chip_info {
>> + unsigned int max_register;
>> + unsigned int versions;
>> + unsigned int modes;
>> + unsigned int num_pipes;
>> + unsigned int pipe_hw_ids[MAX9296A_PIPES_NUM];
>> + unsigned int phy_hw_ids[MAX9296A_PHYS_NUM];
>> + unsigned int num_phys;
>> + unsigned int num_links;
>> + struct max_phys_configs phys_configs;
>> + bool use_atr;
>> + bool has_per_link_reset;
>> + bool phy0_lanes_0_1_on_second_phy;
>> + bool polarity_on_physical_lanes;
>> + bool needs_single_link_version;
>> + bool needs_unique_stream_id;
>> + bool supports_cphy;
>> + bool supports_phy_log;
>> + bool adjust_rlms;
>> + bool fix_tx_ids;
>> +
>> + enum max_gmsl_mode tpg_mode;
>> +
>> + int (*set_pipe_stream_id)(struct max_des *des, struct max_des_pipe
*pipe,
>> + unsigned int stream_id);
>> + int (*set_pipe_enable)(struct max_des *des, struct max_des_pipe *pipe,
>> + bool enable);
>> + int (*set_pipe_link)(struct max_des *des, struct max_des_pipe *pipe,
>> + struct max_des_link *link);
>> + int (*set_pipe_tunnel_phy)(struct max_des *des, struct
max_des_pipe *pipe,
>> + struct max_des_phy *phy);
>> + int (*set_pipe_tunnel_enable)(struct max_des *des, struct
max_des_pipe *pipe,
>> + bool enable);
>
> Given this many callbacks, having an operations struct for them seems
> appropriate.
>
Are you proposing adding another struct just to put these ops inside?
What I could do is use the existing struct max_des_ops and assign the
appropriate members in it, and then put whatever is left that's not
needed for the common framework in struct max9296a_chip_info, and add
a pointer to the struct max_des_ops instance it struct
max9296a_chip_info.
...
>> +static int max9296a_log_phy_status(struct max_des *des,
>> + struct max_des_phy *phy, const char *name)
>> +{
>> + struct max9296a_priv *priv = des_to_priv(des);
>> + unsigned int index = phy->index;
>> + unsigned int val;
>> + int ret;
>> +
>> + if (!priv->info->supports_phy_log)
>> + return 0;
>> +
>> + ret = regmap_read(priv->regmap, MAX9296A_MIPI_PHY18, &val);
>> + if (ret)
>> + return ret;
>> +
>> + pr_info("%s: \tcsi2_pkt_cnt: %lu\n", name,
>> + field_get(MAX9296A_MIPI_PHY18_CSI2_TX_PKT_CNT(index), val));
>> +
>> + ret = regmap_read(priv->regmap, MAX9296A_MIPI_PHY20(index), &val);
>> + if (ret)
>> + return ret;
>> +
>> + pr_info("%s: \tphy_pkt_cnt: %u\n", name, val);
>
> dev_info()?
>
I initially used pr_info() with the subdev name passed from core
framwork to be consistent with the rest of the prints which use
v4l2_info().
I'll see how using dev_info() looks like, it would be nice if it would
match the v4l2_info() format, even though v4l2-ctl --log-status doesn't
care since all it looks for is `START STATUS`.
>> +
>> + return 0;
>> +}
>> +
>> +static int max9296a_set_enable(struct max_des *des, bool enable)
>> +{
>> + struct max9296a_priv *priv = des_to_priv(des);
>> +
>> + return regmap_assign_bits(priv->regmap, MAX9296A_BACKTOP12,
>> + MAX9296A_BACKTOP12_CSI_OUT_EN, enable);
>> +}
>> +
>> +static int max9296a_init_phy(struct max_des *des, struct
max_des_phy *phy)
>> +{
>> + struct max9296a_priv *priv = des_to_priv(des);
>> + bool is_cphy = phy->bus_type == V4L2_MBUS_CSI2_CPHY;
>> + unsigned int num_data_lanes = phy->mipi.num_data_lanes;
>> + unsigned int dpll_freq = phy->link_frequency * 2;
>> + unsigned int num_hw_data_lanes;
>> + unsigned int hw_index = max9296a_phy_id(priv, phy);
>> + unsigned int index = phy->index;
>> + unsigned int used_data_lanes = 0;
>> + unsigned int val;
>
> For register values, please use a type that explicitly specifies the
number
> of bits, e.g. u32.
>
I used the type of the argument received by the regmap methods.
...
>> +static int max9296a_reset_link(struct max9296a_priv *priv, unsigned
int index)
>> +{
>> + unsigned int reg, mask;
>> +
>> + if (index == 0) {
>> + reg = MAX9296A_CTRL0;
>> + mask = MAX9296A_CTRL0_RESET_ONESHOT;
>> + } else {
>> + reg = MAX9296A_CTRL2;
>> + mask = MAX9296A_CTRL2_RESET_ONESHOT_B;
>> + }
>
> I might use an array for this.
>
> Is index guaranteed to be 0 or 1?
>
Should be, yes, but using an array for just two indices would cause a
bit of indirection when looking at the code. If it was more I would have
used one.
>> +
>> + return regmap_set_bits(priv->regmap, reg, mask);
>> +}
>> +
>> +static int max9296a_init_link_rlms(struct max9296a_priv *priv,
>> + struct max_des_link *link)
>> +{
>> + unsigned int index = link->index;
>> + int ret;
>> +
>> + /*
>> + * These settings are described as required on datasheet page 53
>> + * for MAX96714.
>> + */
>> +
>> + ret = regmap_write(priv->regmap, MAX9296A_RLMS3E(index), 0xfd);
>> + if (ret)
>> + return ret;
>
> You could also do:
>
> if (!ret)
> ret = ...;
>
> And return ret at the end. It's one line less per call. Up to you.
>
>> +
>> + ret = regmap_write(priv->regmap, MAX9296A_RLMS3F(index), 0x3d);
>
> What are these magic numbers? Could we have human-readable names for
them?
>
> The register names seem pretty opaque, too. Some explanation here would
> seem reasonable.
>
They're extracted from the datasheet of MAX96714, the values are
undocumented, but they're necessary to "optimize performance" of the
GMSL link. I'll add a comment stating the datasheet page and section.
...
>> diff --git a/drivers/media/i2c/maxim-serdes/max_des.c
b/drivers/media/i2c/maxim-serdes/max_des.c
>> new file mode 100644
>> index 000000000000..6a45f42fe033
>> --- /dev/null
>> +++ b/drivers/media/i2c/maxim-serdes/max_des.c
>> @@ -0,0 +1,3108 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Maxim GMSL2 Deserializer Driver
>
> How about naming the file maxim-deserialiser? I'd use e.g. "maxim_des"
> prefix for the functions. Just "max" is quite generic.
>
max_des seems explicit enough. The max naming comes from the common
prefix in the name of the chips, eg: MAX96724, MAX96717, not from Maxim.
If I intended it to come from maxim, I would have obviously used maxim_,
since that's what vendor-prefixes.yaml specifies.
Although they were initially made by Maxim, Analog Devices bought Maxim,
so using maxim_ would make as much sense as using adi_.
Switching to maxim_ would only lengthen the name of the functions,
types, symbols, macros, etc, and at least register/masks macros are
already extremely long.
...
>> +static int max_des_parse_src_dt_endpoint(struct max_des_priv *priv,
>> + struct max_des_phy *phy,
>> + struct fwnode_handle *fwnode)
>> +{
>> + struct max_des *des = priv->des;
>> + u32 pad = max_des_phy_to_pad(des, phy);
>> + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type =
V4L2_MBUS_UNKNOWN };
>> + struct v4l2_mbus_config_mipi_csi2 *mipi = &v4l2_ep.bus.mipi_csi2;
>> + enum v4l2_mbus_type bus_type;
>> + struct fwnode_handle *ep;
>> + u64 link_frequency;
>> + unsigned int i;
>> + int ret;
>> +
>> + ep = fwnode_graph_get_endpoint_by_id(fwnode, pad, 0, 0);
>> + if (!ep)
>> + return 0;
>> +
>> + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &v4l2_ep);
>> + fwnode_handle_put(ep);
>> + if (ret) {
>> + dev_err(priv->dev, "Could not parse endpoint on port %u\n", pad);
>> + return ret;
>> + }
>> +
>> + bus_type = v4l2_ep.bus_type;
>> + if (bus_type != V4L2_MBUS_CSI2_DPHY &&
>> + bus_type != V4L2_MBUS_CSI2_CPHY) {
>> + v4l2_fwnode_endpoint_free(&v4l2_ep);
>> + dev_err(priv->dev, "Unsupported bus-type %u on port %u\n",
>> + pad, bus_type);
>> + return -EINVAL;
>> + }
>> +
>> + ret = 0;
>
> ret is already 0 here.
>
>> + if (v4l2_ep.nr_of_link_frequencies == 0)
>> + link_frequency = MAX_DES_LINK_FREQUENCY_DEFAULT;
>
> Isn't this required in DT?
>
Required from a schema standpoint or a code standpoint?
Code:
rval = fwnode_property_count_u64(fwnode, "link-frequencies");
if (rval > 0) {
}
No rval <= 0 case.
And I don't think I made it required in the schema.
...
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793
2025-06-18 9:58 ` [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793 Cosmin Tanislav
@ 2025-06-24 16:14 ` Martin Hecht
2025-06-24 16:20 ` Cosmin Tanislav
0 siblings, 1 reply; 31+ messages in thread
From: Martin Hecht @ 2025-06-24 16:14 UTC (permalink / raw)
To: Cosmin Tanislav, Tomi Valkeinen, Mauro Carvalho Chehab,
Rob Herring, Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
I'm preparing a test with Alvium + max96717 + max96716. I can't see away
to overwrite cfg settings to force pixel mode or tunnel mode. Any plans
to add this? Sometimes it is required to force the other mode than set
by pin-strapping.
BR Martin
On 6/18/25 11:58, Cosmin Tanislav wrote:
> MAX96793 is a newer variant of the MAX96717 which also supports GMSL3
> links.
>
> Document this compatibility.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../devicetree/bindings/media/i2c/maxim,max96717.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> index ab46a5f0bd7e..23f611177a87 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> @@ -30,6 +30,8 @@ description:
>
> MAX9295A only supports pixel mode.
>
> + MAX96793 also supports GMSL3 mode.
> +
> properties:
> compatible:
> oneOf:
> @@ -39,6 +41,7 @@ properties:
> - items:
> - enum:
> - maxim,max96717
> + - maxim,max96793
> - const: maxim,max96717f
>
> '#gpio-cells':
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793
2025-06-24 16:14 ` Martin Hecht
@ 2025-06-24 16:20 ` Cosmin Tanislav
0 siblings, 0 replies; 31+ messages in thread
From: Cosmin Tanislav @ 2025-06-24 16:20 UTC (permalink / raw)
To: Martin Hecht, Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman, Linus Walleij
Cc: open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
On 6/24/25 7:14 PM, Martin Hecht wrote:
> Hi Cosmin,
>
> I'm preparing a test with Alvium + max96717 + max96716. I can't see away
> to overwrite cfg settings to force pixel mode or tunnel mode. Any plans
> to add this? Sometimes it is required to force the other mode than set
> by pin-strapping.
>
> BR Martin
>
Hi Martin.
Pixel/tunnel mode is chosen automatically based on HW capabilities
routing, formats, etc.
I don't plan on adding a way to force it, since the presumption
is that the serdes framework will pick the best use case available, as
long as all the data can make its way to the PHY.
Forcing pixel/tunnel mode shouldn't be done via device-tree since it's
not related to the way hardware is wired up to the rest of the system.
> On 6/18/25 11:58, Cosmin Tanislav wrote:
>> MAX96793 is a newer variant of the MAX96717 which also supports GMSL3
>> links.
>>
>> Document this compatibility.
>>
>> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
>> Acked-by: Rob Herring (Arm) <robh@kernel.org>
>> ---
>> .../devicetree/bindings/media/i2c/maxim,max96717.yaml | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/media/i2c/
>> maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/
>> maxim,max96717.yaml
>> index ab46a5f0bd7e..23f611177a87 100644
>> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
>> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
>> @@ -30,6 +30,8 @@ description:
>> MAX9295A only supports pixel mode.
>> + MAX96793 also supports GMSL3 mode.
>> +
>> properties:
>> compatible:
>> oneOf:
>> @@ -39,6 +41,7 @@ properties:
>> - items:
>> - enum:
>> - maxim,max96717
>> + - maxim,max96793
>> - const: maxim,max96717f
>> '#gpio-cells':
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf
2025-06-18 9:58 ` [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf Cosmin Tanislav
@ 2025-06-24 18:58 ` Linus Walleij
2025-06-27 19:38 ` Rob Herring
1 sibling, 0 replies; 31+ messages in thread
From: Linus Walleij @ 2025-06-24 18:58 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Sakari Ailus,
Laurent Pinchart, Greg Kroah-Hartman,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
thanks for your patch! Overall this looks good!
On Wed, Jun 18, 2025 at 11:59 AM Cosmin Tanislav <demonsingur@gmail.com> wrote:
> MAX96717 is capable of configuring various pin properties.
>
> Add pinctrl/pinconf properties to support this usecase.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
(...)
> + slew-rate:
> + description: |
> + Slew rate.
> + 0 - Fastest
> + 1 - Fast
> + 2 - Slow
> + 3 - Slowest
> + maximum: 3
Would be great to have some SI units on this? Like how many milliseconds
etc.
> + maxim,jitter-compensation:
> + type: boolean
> + description: Enables jitter compensation.
What does that mean?
> + maxim,gmsl-tx:
> + type: boolean
> + description: Enable transmitting pin value to GMSL link.
> +
> + maxim,gmsl-rx:
> + type: boolean
> + description: Enable receiving pin value from GMSL link.
> +
> + maxim,gmsl-tx-id:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Identifier used while transmitting value to GMSL link.
> + Default value matches the pin number.
> + minimum: 0
> + maximum: 31
> +
> + maxim,gmsl-rx-id:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Identifier used while receiving value from GMSL link.
> + Default value matches the pin number.
> + minimum: 0
> + maximum: 31
Maybe add some words about what an GMSL link is somewhere?
> + maxim,rclkout-clock:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description: |
> + Clock value.
> + 0 - XTAL / 1 = 25MHz
> + 1 - XTAL / 2 = 12.5MHz
> + 2 - XTAL / 4 = 6.25MHz
> + 3 - Reference PLL output
> + minimum: 0
> + maximum: 3
I'm no expert but isn't this something the clock framework has some standard
binding for? assigned-clock-rates?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf
2025-06-18 9:58 ` [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf Cosmin Tanislav
2025-06-24 18:58 ` Linus Walleij
@ 2025-06-27 19:38 ` Rob Herring
1 sibling, 0 replies; 31+ messages in thread
From: Rob Herring @ 2025-06-27 19:38 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Niklas Söderlund,
Julien Massot, Sakari Ailus, Laurent Pinchart, Greg Kroah-Hartman,
Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
On Wed, Jun 18, 2025 at 12:58:40PM +0300, Cosmin Tanislav wrote:
> MAX96717 is capable of configuring various pin properties.
>
> Add pinctrl/pinconf properties to support this usecase.
>
> Signed-off-by: Cosmin Tanislav <demonsingur@gmail.com>
> ---
> .../bindings/media/i2c/maxim,max96717.yaml | 110 ++++++++++++++++++
> 1 file changed, 110 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> index 167c3dd50683..5998e2518be9 100644
> --- a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
> @@ -121,6 +121,116 @@ required:
> - reg
> - ports
>
> +patternProperties:
> + '-pins$':
> + type: object
> + additionalProperties: false
> +
> + properties:
> + function:
> + enum: [gpio, rclkout]
> +
> + pins: true
> + drive-open-drain: true
> + drive-push-pull: true
> + bias-disable: true
> + output-disable: true
> + output-enable: true
> + output-low: true
> + output-high: true
> + input-enable: true
> +
> + slew-rate:
> + description: |
> + Slew rate.
> + 0 - Fastest
> + 1 - Fast
> + 2 - Slow
> + 3 - Slowest
> + maximum: 3
> +
> + bias-pull-up:
> + oneOf:
> + - type: boolean
> + description: Enable regular 40kOhm pull-up
> + - enum: [ 40000, 1000000 ]
> + description: Enable either the 40kOhm or the 1MOhm pull-up
> +
> + bias-pull-down:
> + oneOf:
> + - type: boolean
> + description: Enable regular 40kOhm pull-down
> + - enum: [ 40000, 1000000 ]
> + description: Enable either the 40kOhm or the 1MOhm pull-down
> +
> + maxim,jitter-compensation:
> + type: boolean
> + description: Enables jitter compensation.
> +
> + maxim,gmsl-tx:
> + type: boolean
> + description: Enable transmitting pin value to GMSL link.
> +
> + maxim,gmsl-rx:
> + type: boolean
> + description: Enable receiving pin value from GMSL link.
> +
> + maxim,gmsl-tx-id:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Identifier used while transmitting value to GMSL link.
> + Default value matches the pin number.
> + minimum: 0
The minimum is already 0 being unsigned. Elsewhere too.
With that,
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH v4 15/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
2025-06-24 15:34 ` Cosmin Tanislav
@ 2025-06-28 18:10 ` Sakari Ailus
0 siblings, 0 replies; 31+ messages in thread
From: Sakari Ailus @ 2025-06-28 18:10 UTC (permalink / raw)
To: Cosmin Tanislav
Cc: Tomi Valkeinen, Mauro Carvalho Chehab, Rob Herring,
Niklas Söderlund, Julien Massot, Laurent Pinchart,
Greg Kroah-Hartman, Linus Walleij,
open list:MAXIM GMSL2 SERIALIZERS AND DESERIALIZERS,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list, moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
open list:STAGING SUBSYSTEM,
open list:GPIO SUBSYSTEM:Keyword:(devm_)?gpio_(request|free|direction|get|set),
Cosmin Tanislav
Hi Cosmin,
On 6/24/25 18:34, Cosmin Tanislav wrote:
> On 6/24/25 11:52 AM, Sakari Ailus wrote:
> >> +struct max9296a_chip_info {
> >> + unsigned int max_register;
> >> + unsigned int versions;
> >> + unsigned int modes;
> >> + unsigned int num_pipes;
> >> + unsigned int pipe_hw_ids[MAX9296A_PIPES_NUM];
> >> + unsigned int phy_hw_ids[MAX9296A_PHYS_NUM];
> >> + unsigned int num_phys;
> >> + unsigned int num_links;
> >> + struct max_phys_configs phys_configs;
> >> + bool use_atr;
> >> + bool has_per_link_reset;
> >> + bool phy0_lanes_0_1_on_second_phy;
> >> + bool polarity_on_physical_lanes;
> >> + bool needs_single_link_version;
> >> + bool needs_unique_stream_id;
> >> + bool supports_cphy;
> >> + bool supports_phy_log;
> >> + bool adjust_rlms;
> >> + bool fix_tx_ids;
> >> +
> >> + enum max_gmsl_mode tpg_mode;
> >> +
> >> + int (*set_pipe_stream_id)(struct max_des *des, struct
> max_des_pipe *pipe,
> >> + unsigned int stream_id);
> >> + int (*set_pipe_enable)(struct max_des *des, struct max_des_pipe
> *pipe,
> >> + bool enable);
> >> + int (*set_pipe_link)(struct max_des *des, struct max_des_pipe
> *pipe,
> >> + struct max_des_link *link);
> >> + int (*set_pipe_tunnel_phy)(struct max_des *des, struct
> max_des_pipe *pipe,
> >> + struct max_des_phy *phy);
> >> + int (*set_pipe_tunnel_enable)(struct max_des *des, struct
> max_des_pipe *pipe,
> >> + bool enable);
> >
> > Given this many callbacks, having an operations struct for them seems
> > appropriate.
> >
>
> Are you proposing adding another struct just to put these ops inside?
>
> What I could do is use the existing struct max_des_ops and assign the
> appropriate members in it, and then put whatever is left that's not
> needed for the common framework in struct max9296a_chip_info, and add
> a pointer to the struct max_des_ops instance it struct
> max9296a_chip_info.
Ah, I missed this wasn't specific to a device. Please ignore the comment.
...
> >> +static int max9296a_log_phy_status(struct max_des *des,
> >> + struct max_des_phy *phy, const char *name)
> >> +{
> >> + struct max9296a_priv *priv = des_to_priv(des);
> >> + unsigned int index = phy->index;
> >> + unsigned int val;
> >> + int ret;
> >> +
> >> + if (!priv->info->supports_phy_log)
> >> + return 0;
> >> +
> >> + ret = regmap_read(priv->regmap, MAX9296A_MIPI_PHY18, &val);
> >> + if (ret)
> >> + return ret;
> >> +
> >> + pr_info("%s: \tcsi2_pkt_cnt: %lu\n", name,
> >> + field_get(MAX9296A_MIPI_PHY18_CSI2_TX_PKT_CNT(index), val));
> >> +
> >> + ret = regmap_read(priv->regmap, MAX9296A_MIPI_PHY20(index), &val);
> >> + if (ret)
> >> + return ret;
> >> +
> >> + pr_info("%s: \tphy_pkt_cnt: %u\n", name, val);
> >
> > dev_info()?
> >
>
> I initially used pr_info() with the subdev name passed from core
> framwork to be consistent with the rest of the prints which use
> v4l2_info().
>
> I'll see how using dev_info() looks like, it would be nice if it would
> match the v4l2_info() format, even though v4l2-ctl --log-status doesn't
> care since all it looks for is `START STATUS`.
Ok. Up to you.
...
> >> +static int max9296a_init_phy(struct max_des *des, struct
> max_des_phy *phy)
> >> +{
> >> + struct max9296a_priv *priv = des_to_priv(des);
> >> + bool is_cphy = phy->bus_type == V4L2_MBUS_CSI2_CPHY;
> >> + unsigned int num_data_lanes = phy->mipi.num_data_lanes;
> >> + unsigned int dpll_freq = phy->link_frequency * 2;
> >> + unsigned int num_hw_data_lanes;
> >> + unsigned int hw_index = max9296a_phy_id(priv, phy);
> >> + unsigned int index = phy->index;
> >> + unsigned int used_data_lanes = 0;
> >> + unsigned int val;
> >
> > For register values, please use a type that explicitly specifies the
> number
> > of bits, e.g. u32.
> >
>
> I used the type of the argument received by the regmap methods.
Ack.
>
> ...
>
> >> +static int max9296a_reset_link(struct max9296a_priv *priv, unsigned
> int index)
> >> +{
> >> + unsigned int reg, mask;
> >> +
> >> + if (index == 0) {
> >> + reg = MAX9296A_CTRL0;
> >> + mask = MAX9296A_CTRL0_RESET_ONESHOT;
> >> + } else {
> >> + reg = MAX9296A_CTRL2;
> >> + mask = MAX9296A_CTRL2_RESET_ONESHOT_B;
> >> + }
> >
> > I might use an array for this.
> >
> > Is index guaranteed to be 0 or 1?
> >
>
> Should be, yes, but using an array for just two indices would cause a
> bit of indirection when looking at the code. If it was more I would have
> used one.
Ack.
>
> >> +
> >> + return regmap_set_bits(priv->regmap, reg, mask);
> >> +}
> >> +
> >> +static int max9296a_init_link_rlms(struct max9296a_priv *priv,
> >> + struct max_des_link *link)
> >> +{
> >> + unsigned int index = link->index;
> >> + int ret;
> >> +
> >> + /*
> >> + * These settings are described as required on datasheet page 53
> >> + * for MAX96714.
> >> + */
> >> +
> >> + ret = regmap_write(priv->regmap, MAX9296A_RLMS3E(index), 0xfd);
> >> + if (ret)
> >> + return ret;
> >
> > You could also do:
> >
> > if (!ret)
> > ret = ...;
> >
> > And return ret at the end. It's one line less per call. Up to you.
> >
> >> +
> >> + ret = regmap_write(priv->regmap, MAX9296A_RLMS3F(index), 0x3d);
> >
> > What are these magic numbers? Could we have human-readable names for
> them?
> >
> > The register names seem pretty opaque, too. Some explanation here would
> > seem reasonable.
> >
>
> They're extracted from the datasheet of MAX96714, the values are
> undocumented, but they're necessary to "optimize performance" of the
> GMSL link. I'll add a comment stating the datasheet page and section.
Ack, sounds good.
>
> ...
>
> >> diff --git a/drivers/media/i2c/maxim-serdes/max_des.c b/drivers/
> media/i2c/maxim-serdes/max_des.c
> >> new file mode 100644
> >> index 000000000000..6a45f42fe033
> >> --- /dev/null
> >> +++ b/drivers/media/i2c/maxim-serdes/max_des.c
> >> @@ -0,0 +1,3108 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +/*
> >> + * Maxim GMSL2 Deserializer Driver
> >
> > How about naming the file maxim-deserialiser? I'd use e.g. "maxim_des"
> > prefix for the functions. Just "max" is quite generic.
> >
>
> max_des seems explicit enough. The max naming comes from the common
> prefix in the name of the chips, eg: MAX96724, MAX96717, not from Maxim.
Yeah, the prefix Maxim uses for their chips is a bit unfortunate in
naming context. I guess it's ok as it's not part of the UAPI.
>
> If I intended it to come from maxim, I would have obviously used maxim_,
> since that's what vendor-prefixes.yaml specifies.
>
> Although they were initially made by Maxim, Analog Devices bought Maxim,
> so using maxim_ would make as much sense as using adi_.
>
> Switching to maxim_ would only lengthen the name of the functions,
> types, symbols, macros, etc, and at least register/masks macros are
> already extremely long.
>
> ...
>
> >> +static int max_des_parse_src_dt_endpoint(struct max_des_priv *priv,
> >> + struct max_des_phy *phy,
> >> + struct fwnode_handle *fwnode)
> >> +{
> >> + struct max_des *des = priv->des;
> >> + u32 pad = max_des_phy_to_pad(des, phy);
> >> + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type =
> V4L2_MBUS_UNKNOWN };
> >> + struct v4l2_mbus_config_mipi_csi2 *mipi = &v4l2_ep.bus.mipi_csi2;
> >> + enum v4l2_mbus_type bus_type;
> >> + struct fwnode_handle *ep;
> >> + u64 link_frequency;
> >> + unsigned int i;
> >> + int ret;
> >> +
> >> + ep = fwnode_graph_get_endpoint_by_id(fwnode, pad, 0, 0);
> >> + if (!ep)
> >> + return 0;
> >> +
> >> + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &v4l2_ep);
> >> + fwnode_handle_put(ep);
> >> + if (ret) {
> >> + dev_err(priv->dev, "Could not parse endpoint on port %u\n",
> pad);
> >> + return ret;
> >> + }
> >> +
> >> + bus_type = v4l2_ep.bus_type;
> >> + if (bus_type != V4L2_MBUS_CSI2_DPHY &&
> >> + bus_type != V4L2_MBUS_CSI2_CPHY) {
> >> + v4l2_fwnode_endpoint_free(&v4l2_ep);
> >> + dev_err(priv->dev, "Unsupported bus-type %u on port %u\n",
> >> + pad, bus_type);
> >> + return -EINVAL;
> >> + }
> >> +
> >> + ret = 0;
> >
> > ret is already 0 here.
> >
> >> + if (v4l2_ep.nr_of_link_frequencies == 0)
> >> + link_frequency = MAX_DES_LINK_FREQUENCY_DEFAULT;
> >
> > Isn't this required in DT?
> >
>
> Required from a schema standpoint or a code standpoint?
>
> Code:
>
> rval = fwnode_property_count_u64(fwnode, "link-frequencies");
> if (rval > 0) {
> }
>
> No rval <= 0 case.
>
> And I don't think I made it required in the schema.
I'd do that. The device requires this configuration to operate anyway.
Also the concern of EMI may be lesser in environments serdes devices are
used but I wouldn't say it's not there.
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2025-06-28 19:26 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-18 9:58 [PATCH v4 00/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 01/19] media: mc: Add INTERNAL pad flag Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 02/19] dt-bindings: media: i2c: max96717: add myself as maintainer Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 03/19] dt-bindings: media: i2c: max96717: add support for I2C ATR Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 04/19] dt-bindings: media: i2c: max96717: add support for pinctrl/pinconf Cosmin Tanislav
2025-06-24 18:58 ` Linus Walleij
2025-06-27 19:38 ` Rob Herring
2025-06-18 9:58 ` [PATCH v4 05/19] dt-bindings: media: i2c: max96717: add support for MAX9295A Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 06/19] dt-bindings: media: i2c: max96717: add support for MAX96793 Cosmin Tanislav
2025-06-24 16:14 ` Martin Hecht
2025-06-24 16:20 ` Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 07/19] dt-bindings: media: i2c: max96712: add myself as maintainer Cosmin Tanislav
2025-06-19 10:31 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 08/19] dt-bindings: media: i2c: max96712: use pattern properties for ports Cosmin Tanislav
2025-06-19 11:17 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 09/19] dt-bindings: media: i2c: max96712: add support for I2C ATR Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 10/19] dt-bindings: media: i2c: max96712: add support for POC supplies Cosmin Tanislav
2025-06-19 13:32 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 11/19] dt-bindings: media: i2c: max96712: add support for MAX96724F/R Cosmin Tanislav
2025-06-19 13:33 ` Niklas Söderlund
2025-06-18 9:58 ` [PATCH v4 12/19] dt-bindings: media: i2c: max96714: add myself as maintainer Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 13/19] dt-bindings: media: i2c: max96714: add support for MAX96714R Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 14/19] dt-bindings: media: i2c: add MAX9296A, MAX96716A, MAX96792A Cosmin Tanislav
2025-06-18 13:00 ` Rob Herring (Arm)
2025-06-18 9:58 ` [PATCH v4 16/19] arm64: defconfig: disable deprecated MAX96712 driver Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 17/19] staging: media: remove " Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 18/19] media: i2c: remove MAX96717 driver Cosmin Tanislav
2025-06-18 9:58 ` [PATCH v4 19/19] media: i2c: remove MAX96714 driver Cosmin Tanislav
[not found] ` <20250618095858.2145209-16-demonsingur@gmail.com>
2025-06-19 18:30 ` [PATCH v4 15/19] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers Jakub Kostiw
[not found] ` <aFpnU8EHGt14UMHC@kekkonen.localdomain>
2025-06-24 15:34 ` Cosmin Tanislav
2025-06-28 18:10 ` Sakari Ailus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).