Linux kernel staging patches
 help / color / mirror / Atom feed
* [PATCH 0/2] media: hm1092: Intel IPU (ACPI) support on top of v6
       [not found] <20260801-hm1092-driver-v6-0-5979f223748a@gmail.com>
@ 2026-10-10  4:59 ` Jake Steinman
  2026-10-10  4:59   ` [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration Jake Steinman
  2026-10-10  4:59   ` [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats Jake Steinman
  0 siblings, 2 replies; 7+ messages in thread
From: Jake Steinman @ 2026-10-10  4:59 UTC (permalink / raw)
  To: Ramshouriesh R, Sakari Ailus
  Cc: Mauro Carvalho Chehab, Hans de Goede, Hans Verkuil,
	Bryan O'Donoghue, Vladimir Zapolskiy, Bingbu Cao,
	Greg Kroah-Hartman, linux-media, linux-staging, linux-kernel

Hi Ramshouriesh, Sakari,

These two patches make the HM1092 usable on Intel IPU laptops, where the
sensor is described in ACPI as HIMX1092. They apply on top of
"[PATCH v6 0/2] media: Add Himax HM1092 mono NIR sensor driver".

Patch 1 is for the sensor driver. v6 cannot bind on x86: there is no
ACPI match table, the 19.2 MHz clock these machines supply is rejected,
and the only mode is the 24 MHz one. The patch selects the configuration
from the clock rate and adds the 19.2 MHz / 648x368 / 180.48 MHz one.
The 24 MHz path is functionally unchanged. Ramshouriesh, feel free to
fold it into a v7 if you prefer that to a follow-up.

Patch 2 is independent of the sensor. The IPU7 capture nodes have no
pixel format for MEDIA_BUS_FMT_Y10_1X10, so no monochrome sensor can be
captured, whatever its driver.

Tested together on a Dell XPS 16 DA16260 (Panther Lake), kernel
7.3-rc5, with the ipu-bridge entry that is already in media/next:

  intel_ipu7_isys.isys intel_ipu7.isys.40: bind hm1092 17-0024 nlanes is 1 port is 2

  link_frequency  180480000
  pixel_rate      36096000
  exposure        min=2 max=719 default=360

  Y10   648x368, 1344 bytes per line, 10 frames, 4945920 bytes
  Y10P  648x368,  832 bytes per line, 10 frames, 3061760 bytes

  exposure 100: mean level  59
  exposure 700: mean level 198

Two things worth knowing when reviewing patch 1:

- The 19.2 MHz configuration reads X 0..1293 and Y 0..733, which is the
  full 1296x736 array including the dummy border. That is what the
  vendor sequence programs, so the crop rectangle reports it as is, and
  it lies outside the 1280x720 crop bounds v6 defines. I left the
  bounds alone. Say if you would rather have them widened.

- The 24 MHz configuration is compile-tested only here. I have no
  devicetree hardware with this sensor.

Regards,
Jake

Jake Steinman (2):
  media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz
    configuration
  media: staging/ipu7: Add 10-bit greyscale capture formats

 drivers/media/i2c/hm1092.c                   | 363 ++++++++++++++++---
 drivers/staging/media/ipu7/ipu7-isys-video.c |   4 +
 2 files changed, 321 insertions(+), 46 deletions(-)

-- 
2.56.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration
  2026-10-10  4:59 ` [PATCH 0/2] media: hm1092: Intel IPU (ACPI) support on top of v6 Jake Steinman
@ 2026-10-10  4:59   ` Jake Steinman
  2026-10-10  9:15     ` Eduard Kulyk
  2026-10-12 11:07     ` Uwe Kleine-König
  2026-10-10  4:59   ` [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats Jake Steinman
  1 sibling, 2 replies; 7+ messages in thread
From: Jake Steinman @ 2026-10-10  4:59 UTC (permalink / raw)
  To: Ramshouriesh R, Sakari Ailus
  Cc: Mauro Carvalho Chehab, Hans de Goede, Hans Verkuil,
	Bryan O'Donoghue, Vladimir Zapolskiy, Bingbu Cao,
	Greg Kroah-Hartman, linux-media, linux-staging, linux-kernel

The HM1092 is also the IR camera of Intel IPU6/IPU7 laptops. There it is
enumerated through ACPI as HIMX1092 and clocked at 19.2 MHz rather than
24 MHz. The driver cannot bind on those machines: it has no ACPI match
table and probe rejects any external clock other than 24 MHz.

Turn the single fixed mode into a table of configurations selected by
the external clock rate, each with its own init sequence, link
frequency, timings, readout window and exposure default. Add the
configuration the vendor Windows driver uses on the Intel platforms:
648x368, HTS 1620, VTS 740, with the PLL pre-divider at 10 and the
multiplier at 94, giving 19200000 * 94 / 10 = 180480000 Hz.

ipu-bridge lists both 180000000 and 180480000 for this sensor, so
matching any menu entry against the endpoint is no longer enough. Check
that the endpoint offers the link frequency of the selected
configuration.

The 24 MHz configuration is unchanged: same init sequence, timings,
controls and defaults.

Tested on a Dell XPS 16 DA16260 (Panther Lake, IPU7, 19.2 MHz clock
from INT3472): the sensor binds on CSI-2 port 2, streams 648x368 at
link frequency 180480000 and the exposure control changes the image
level. The 24 MHz configuration is compile-tested only.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jake Steinman <j@metarealtyinc.ca>
---
 drivers/media/i2c/hm1092.c | 363 ++++++++++++++++++++++++++++++++-----
 1 file changed, 317 insertions(+), 46 deletions(-)

diff --git a/drivers/media/i2c/hm1092.c b/drivers/media/i2c/hm1092.c
index eb3607a..ed6e14b 100644
--- a/drivers/media/i2c/hm1092.c
+++ b/drivers/media/i2c/hm1092.c
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
@@ -20,15 +21,19 @@
 /*
  * CSI-2 D-PHY link frequency (DDR, i.e. half the per-lane bit rate).
  *
- * The vendor Windows configuration supplies a 24 MHz EXTCLK and programs the
- * MIPI PLL pre-divider to 12 (0x030d = 0x0c) and multiplier to 90
- * (0x030f = 0x5a):
- *   link freq  = 24000000 * 90 / 12          = 180000000
- *   bit rate   = link freq * 2               = 360000000 bps
- *   pixel_rate = bit rate * 1 lane / 10 bpp  = 36000000 pixels/s
+ * Two vendor Windows configurations are known. Each pairs an EXTCLK rate with
+ * its own MIPI PLL pre-divider (0x030d) and multiplier (0x030f):
+ *
+ *   24 MHz EXTCLK, pre-divider 12, multiplier 90 (Qualcomm):
+ *     link freq  = 24000000 * 90 / 12          = 180000000
+ *     pixel_rate = link freq * 2 * 1 lane / 10 = 36000000 pixels/s
+ *
+ *   19.2 MHz EXTCLK, pre-divider 10, multiplier 94 (Intel IPU):
+ *     link freq  = 19200000 * 94 / 10          = 180480000
+ *     pixel_rate = link freq * 2 * 1 lane / 10 = 36096000 pixels/s
  */
-#define HM1092_LINK_FREQ		180000000ULL
-#define HM1092_MCLK			24000000
+#define HM1092_LINK_FREQ_180MHZ		180000000ULL
+#define HM1092_LINK_FREQ_180P48MHZ	180480000ULL
 #define HM1092_BITS_PER_SAMPLE		10
 
 #define HM1092_REG_STREAM		CCI_REG8(0x0100)
@@ -41,16 +46,14 @@
 /*
  * Exposure is a 16-bit value in lines and analogue gain an 8-bit register.
  * The register layout is not documented publicly; it was recovered from the
- * vendor Windows driver. The exposure default (500) was selected from
- * illuminated hardware tests and is also programmed by the init sequence at
- * 0x0202/0x0203.
+ * vendor Windows driver. The exposure default is per mode and matches what
+ * that mode's init sequence programs at 0x0202/0x0203.
  */
 #define HM1092_REG_EXPOSURE_H		CCI_REG8(0x0202)
 #define HM1092_REG_EXPOSURE_L		CCI_REG8(0x0203)
 #define HM1092_EXPOSURE_MIN		2
 #define HM1092_EXPOSURE_MARGIN		21
 #define HM1092_EXPOSURE_STEP		1
-#define HM1092_EXPOSURE_DEFAULT		500
 
 #define HM1092_REG_ANALOGUE_GAIN	CCI_REG8(0x0205)
 #define HM1092_ANALOGUE_GAIN_MIN	0
@@ -72,9 +75,9 @@
 /*
  * Pixel array geometry. The vendor specifies a 1280x720 active array; the
  * full array including the surrounding dummy/optical-black pixels is 1296x736
- * (8 pixels of margin on each side). The single fixed mode reads a window out
- * of the active array (X_ADDR [0x0030..0x04ad], Y_ADDR [0x0008..0x02d5]);
- * subsequent internal processing produces the 560x360 output.
+ * (8 pixels of margin on each side). Each mode reads a fixed window out of
+ * the array (X_ADDR/Y_ADDR registers 0x0344..0x034b, reported as the crop
+ * rectangle); subsequent internal processing produces the output size.
  */
 #define HM1092_NATIVE_WIDTH		1296U
 #define HM1092_NATIVE_HEIGHT		736U
@@ -82,12 +85,8 @@
 #define HM1092_ACTIVE_TOP		8U
 #define HM1092_ACTIVE_WIDTH		1280U
 #define HM1092_ACTIVE_HEIGHT		720U
-#define HM1092_CROP_LEFT		48U
-#define HM1092_CROP_TOP			8U
-#define HM1092_CROP_WIDTH		1150U
-#define HM1092_CROP_HEIGHT		718U
 
-static const struct cci_reg_sequence hm1092_init_regs[] = {
+static const struct cci_reg_sequence hm1092_560x360_regs[] = {
 	{ CCI_REG8(0x0103), 0x00 },
 	{ CCI_REG8(0x030a), 0x05 },
 	{ CCI_REG8(0x030d), 0x0c },
@@ -275,18 +274,265 @@ static const struct cci_reg_sequence hm1092_init_regs[] = {
 	{ CCI_REG8(0x0037), 0x30 },
 };
 
+/*
+ * Init sequence used with a 19.2 MHz EXTCLK, as found on Intel IPU laptops
+ * where the sensor is described in ACPI as HIMX1092. Recovered from the
+ * vendor Windows driver for those platforms; kept in the order that driver
+ * issues it, including its repeated writes.
+ */
+static const struct cci_reg_sequence hm1092_648x368_regs[] = {
+	{ CCI_REG8(0x0100), 0x00 },
+	{ CCI_REG8(0x0103), 0x00 },
+	{ CCI_REG8(0x0000), 0x00 },
+	{ CCI_REG8(0x0101), 0x00 },
+	{ CCI_REG8(0x0202), 0x02 },
+	{ CCI_REG8(0x0203), 0xe5 },
+	{ CCI_REG8(0x0307), 0x00 },
+	{ CCI_REG8(0x0309), 0x01 },
+	{ CCI_REG8(0x030a), 0x05 },
+	{ CCI_REG8(0x030d), 0x0a },
+	{ CCI_REG8(0x030f), 0x5e },
+	{ CCI_REG8(0x0310), 0x00 },
+	{ CCI_REG8(0x0340), 0x03 },
+	{ CCI_REG8(0x0341), 0x1e },
+	{ CCI_REG8(0x0342), 0x05 },
+	{ CCI_REG8(0x0343), 0xe4 },
+	{ CCI_REG8(0x0350), 0x53 },
+	{ CCI_REG8(0x0387), 0x01 },
+	{ CCI_REG8(0x3110), 0x02 },
+	{ CCI_REG8(0x3735), 0xe2 },
+	{ CCI_REG8(0x3704), 0x04 },
+	{ CCI_REG8(0x4001), 0x00 },
+	{ CCI_REG8(0x4002), 0x2b },
+	{ CCI_REG8(0x4024), 0x40 },
+	{ CCI_REG8(0x4131), 0x01 },
+	{ CCI_REG8(0x4132), 0x20 },
+	{ CCI_REG8(0x4265), 0x02 },
+	{ CCI_REG8(0x4b04), 0x01 },
+	{ CCI_REG8(0x4b0e), 0x0e },
+	{ CCI_REG8(0x4b18), 0x00 },
+	{ CCI_REG8(0x4b20), 0x9e },
+	{ CCI_REG8(0x4b31), 0x06 },
+	{ CCI_REG8(0x4b3b), 0x02 },
+	{ CCI_REG8(0x4b3e), 0x00 },
+	{ CCI_REG8(0x4b44), 0x0c },
+	{ CCI_REG8(0x4b45), 0x01 },
+	{ CCI_REG8(0x4b47), 0x00 },
+	{ CCI_REG8(0x5004), 0x40 },
+	{ CCI_REG8(0x5005), 0x28 },
+	{ CCI_REG8(0x5006), 0x40 },
+	{ CCI_REG8(0x5007), 0x28 },
+	{ CCI_REG8(0x5010), 0x20 },
+	{ CCI_REG8(0x5011), 0x00 },
+	{ CCI_REG8(0x5013), 0x03 },
+	{ CCI_REG8(0x5015), 0xb3 },
+	{ CCI_REG8(0x501d), 0x4c },
+	{ CCI_REG8(0x5098), 0x00 },
+	{ CCI_REG8(0x5099), 0x11 },
+	{ CCI_REG8(0x509b), 0x03 },
+	{ CCI_REG8(0x50a0), 0x30 },
+	{ CCI_REG8(0x50a2), 0x0b },
+	{ CCI_REG8(0x50a6), 0x00 },
+	{ CCI_REG8(0x50a7), 0x00 },
+	{ CCI_REG8(0x50aa), 0x22 },
+	{ CCI_REG8(0x50ab), 0x07 },
+	{ CCI_REG8(0x50ac), 0x24 },
+	{ CCI_REG8(0x50ad), 0x07 },
+	{ CCI_REG8(0x50ae), 0x20 },
+	{ CCI_REG8(0x50af), 0x40 },
+	{ CCI_REG8(0x50b3), 0x04 },
+	{ CCI_REG8(0x50b4), 0x00 },
+	{ CCI_REG8(0x50b7), 0x00 },
+	{ CCI_REG8(0x50b8), 0x70 },
+	{ CCI_REG8(0x50b9), 0xff },
+	{ CCI_REG8(0x50ba), 0xff },
+	{ CCI_REG8(0x50bb), 0x14 },
+	{ CCI_REG8(0x50cb), 0x21 },
+	{ CCI_REG8(0x50d5), 0xe0 },
+	{ CCI_REG8(0x50d7), 0x12 },
+	{ CCI_REG8(0x50dd), 0x00 },
+	{ CCI_REG8(0x50e8), 0x00 },
+	{ CCI_REG8(0x50ea), 0x74 },
+	{ CCI_REG8(0x50fa), 0x02 },
+	{ CCI_REG8(0x5100), 0x03 },
+	{ CCI_REG8(0x5101), 0x13 },
+	{ CCI_REG8(0x5102), 0x23 },
+	{ CCI_REG8(0x5103), 0x33 },
+	{ CCI_REG8(0x5104), 0x43 },
+	{ CCI_REG8(0x5105), 0x42 },
+	{ CCI_REG8(0x5106), 0x40 },
+	{ CCI_REG8(0x5118), 0x00 },
+	{ CCI_REG8(0x5119), 0x00 },
+	{ CCI_REG8(0x511a), 0x00 },
+	{ CCI_REG8(0x511b), 0x00 },
+	{ CCI_REG8(0x511c), 0x00 },
+	{ CCI_REG8(0x511d), 0x00 },
+	{ CCI_REG8(0x511e), 0x00 },
+	{ CCI_REG8(0x5130), 0x13 },
+	{ CCI_REG8(0x5131), 0x23 },
+	{ CCI_REG8(0x5132), 0x33 },
+	{ CCI_REG8(0x5133), 0x43 },
+	{ CCI_REG8(0x5134), 0x42 },
+	{ CCI_REG8(0x5135), 0x40 },
+	{ CCI_REG8(0x5136), 0x40 },
+	{ CCI_REG8(0x5148), 0x01 },
+	{ CCI_REG8(0x5149), 0x01 },
+	{ CCI_REG8(0x514a), 0x01 },
+	{ CCI_REG8(0x514b), 0x01 },
+	{ CCI_REG8(0x514c), 0x01 },
+	{ CCI_REG8(0x514d), 0x01 },
+	{ CCI_REG8(0x514e), 0x01 },
+	{ CCI_REG8(0x51c0), 0x00 },
+	{ CCI_REG8(0x51c1), 0x81 },
+	{ CCI_REG8(0x51c2), 0xec },
+	{ CCI_REG8(0x51c3), 0x00 },
+	{ CCI_REG8(0x51c4), 0x55 },
+	{ CCI_REG8(0x51c5), 0x44 },
+	{ CCI_REG8(0x51c6), 0x00 },
+	{ CCI_REG8(0x51c7), 0x81 },
+	{ CCI_REG8(0x51c8), 0xec },
+	{ CCI_REG8(0x51c9), 0x00 },
+	{ CCI_REG8(0x51ca), 0x55 },
+	{ CCI_REG8(0x51cb), 0x24 },
+	{ CCI_REG8(0x51cc), 0x00 },
+	{ CCI_REG8(0x51cd), 0x81 },
+	{ CCI_REG8(0x51ce), 0xec },
+	{ CCI_REG8(0x51cf), 0x00 },
+	{ CCI_REG8(0x51d0), 0x54 },
+	{ CCI_REG8(0x51d1), 0x24 },
+	{ CCI_REG8(0x51d2), 0x00 },
+	{ CCI_REG8(0x51d3), 0x81 },
+	{ CCI_REG8(0x51d4), 0xec },
+	{ CCI_REG8(0x51d5), 0x00 },
+	{ CCI_REG8(0x51d6), 0x53 },
+	{ CCI_REG8(0x51d7), 0x14 },
+	{ CCI_REG8(0x51d8), 0x00 },
+	{ CCI_REG8(0x51d9), 0x81 },
+	{ CCI_REG8(0x51da), 0xec },
+	{ CCI_REG8(0x51db), 0x00 },
+	{ CCI_REG8(0x51dc), 0x53 },
+	{ CCI_REG8(0x51dd), 0x14 },
+	{ CCI_REG8(0x51e0), 0x09 },
+	{ CCI_REG8(0x51e1), 0x03 },
+	{ CCI_REG8(0x51e2), 0x04 },
+	{ CCI_REG8(0x51e3), 0x03 },
+	{ CCI_REG8(0x51e4), 0x08 },
+	{ CCI_REG8(0x51e5), 0x07 },
+	{ CCI_REG8(0x51e6), 0x08 },
+	{ CCI_REG8(0x51e7), 0x07 },
+	{ CCI_REG8(0x51e8), 0x04 },
+	{ CCI_REG8(0x51e9), 0x46 },
+	{ CCI_REG8(0x51ea), 0x43 },
+	{ CCI_REG8(0x51eb), 0x62 },
+	{ CCI_REG8(0x51ec), 0x61 },
+	{ CCI_REG8(0x51ed), 0x00 },
+	{ CCI_REG8(0x51ee), 0x00 },
+	{ CCI_REG8(0x5200), 0x60 },
+	{ CCI_REG8(0x5201), 0x80 },
+	{ CCI_REG8(0x5202), 0x00 },
+	{ CCI_REG8(0x5203), 0x01 },
+	{ CCI_REG8(0x5206), 0x80 },
+	{ CCI_REG8(0x5208), 0x0b },
+	{ CCI_REG8(0x5209), 0x0c },
+	{ CCI_REG8(0x520c), 0x15 },
+	{ CCI_REG8(0x520d), 0x40 },
+	{ CCI_REG8(0x5214), 0x28 },
+	{ CCI_REG8(0x5215), 0x04 },
+	{ CCI_REG8(0x5216), 0x02 },
+	{ CCI_REG8(0x5217), 0x01 },
+	{ CCI_REG8(0x5218), 0x07 },
+	{ CCI_REG8(0x521e), 0x01 },
+	{ CCI_REG8(0x5282), 0xff },
+	{ CCI_REG8(0x5283), 0x03 },
+	{ CCI_REG8(0x0202), 0x01 },
+	{ CCI_REG8(0x0203), 0x68 },
+	{ CCI_REG8(0x0340), 0x02 },
+	{ CCI_REG8(0x0341), 0xe4 },
+	{ CCI_REG8(0x0342), 0x06 },
+	{ CCI_REG8(0x0343), 0x54 },
+	{ CCI_REG8(0x0344), 0x00 },
+	{ CCI_REG8(0x0345), 0x00 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x00 },
+	{ CCI_REG8(0x0348), 0x05 },
+	{ CCI_REG8(0x0349), 0x0d },
+	{ CCI_REG8(0x034a), 0x02 },
+	{ CCI_REG8(0x034b), 0xdd },
+	{ CCI_REG8(0x034c), 0x02 },
+	{ CCI_REG8(0x034d), 0x88 },
+	{ CCI_REG8(0x034e), 0x01 },
+	{ CCI_REG8(0x034f), 0x70 },
+	{ CCI_REG8(0x0383), 0x00 },
+	{ CCI_REG8(0x0387), 0x10 },
+	{ CCI_REG8(0x0390), 0x03 },
+	{ CCI_REG8(0x4800), 0xac },
+	{ CCI_REG8(0x0104), 0x01 },
+	{ CCI_REG8(0x0104), 0x00 },
+	{ CCI_REG8(0x4801), 0xae },
+	{ CCI_REG8(0x4b20), 0x9e },
+	{ CCI_REG8(0x0101), 0x03 },
+};
+
+/**
+ * struct hm1092_mode - sensor configuration, selected by the EXTCLK rate
+ * @mclk: EXTCLK rate the init sequence programs the PLL for
+ * @link_freq_index: index into hm1092_link_freq_menu
+ * @width: output width
+ * @height: output height
+ * @hts: horizontal total size, 0x0342/0x0343
+ * @vts: vertical total size, 0x0340/0x0341
+ * @exposure_def: exposure programmed by the init sequence
+ * @crop: readout window on the pixel array
+ * @regs: init sequence
+ * @num_regs: number of entries in @regs
+ */
 struct hm1092_mode {
+	unsigned long mclk;
+	unsigned int link_freq_index;
 	u32 width;
 	u32 height;
 	u32 hts;
 	u32 vts;
+	u32 exposure_def;
+	struct v4l2_rect crop;
+	const struct cci_reg_sequence *regs;
+	unsigned int num_regs;
 };
 
-static const struct hm1092_mode hm1092_mode_560x360 = {
-	.width = 560,
-	.height = 360,
-	.hts = 0x0650,
-	.vts = 0x02ee,
+static const struct hm1092_mode hm1092_modes[] = {
+	{
+		.mclk = 24000000,
+		.link_freq_index = 0,
+		.width = 560,
+		.height = 360,
+		.hts = 0x0650,
+		.vts = 0x02ee,
+		.exposure_def = 500,
+		.crop = {
+			.left = 48,
+			.top = 8,
+			.width = 1150,
+			.height = 718,
+		},
+		.regs = hm1092_560x360_regs,
+		.num_regs = ARRAY_SIZE(hm1092_560x360_regs),
+	}, {
+		.mclk = 19200000,
+		.link_freq_index = 1,
+		.width = 648,
+		.height = 368,
+		.hts = 0x0654,
+		.vts = 0x02e4,
+		.exposure_def = 360,
+		.crop = {
+			.left = 0,
+			.top = 0,
+			.width = 1294,
+			.height = 734,
+		},
+		.regs = hm1092_648x368_regs,
+		.num_regs = ARRAY_SIZE(hm1092_648x368_regs),
+	},
 };
 
 static const char * const hm1092_supply_names[] = {
@@ -309,7 +555,8 @@ static const char * const hm1092_test_pattern_menu[] = {
 };
 
 static const s64 hm1092_link_freq_menu[] = {
-	HM1092_LINK_FREQ,
+	HM1092_LINK_FREQ_180MHZ,
+	HM1092_LINK_FREQ_180P48MHZ,
 };
 
 struct hm1092 {
@@ -326,6 +573,7 @@ struct hm1092 {
 	struct v4l2_ctrl *hblank;
 	struct v4l2_ctrl *vblank;
 	struct v4l2_ctrl *exposure;
+	const struct hm1092_mode *mode;
 	u8 mipi_lanes;
 };
 
@@ -398,7 +646,7 @@ static const struct v4l2_ctrl_ops hm1092_ctrl_ops = {
 static int hm1092_init_controls(struct hm1092 *hm1092)
 {
 	struct v4l2_ctrl_handler *ctrl_hdlr = &hm1092->ctrl_handler;
-	const struct hm1092_mode *mode = &hm1092_mode_560x360;
+	const struct hm1092_mode *mode = hm1092->mode;
 	struct v4l2_fwnode_device_properties props;
 	s64 hblank, pixel_rate;
 	int ret;
@@ -412,11 +660,12 @@ static int hm1092_init_controls(struct hm1092 *hm1092)
 	hm1092->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
 						   &hm1092_ctrl_ops,
 						   V4L2_CID_LINK_FREQ,
-						   0, 0,
+						   ARRAY_SIZE(hm1092_link_freq_menu) - 1,
+						   mode->link_freq_index,
 						   hm1092_link_freq_menu);
 
-	pixel_rate = div_u64(HM1092_LINK_FREQ * 2 * hm1092->mipi_lanes,
-			     HM1092_BITS_PER_SAMPLE);
+	pixel_rate = div_u64(hm1092_link_freq_menu[mode->link_freq_index] * 2 *
+			     hm1092->mipi_lanes, HM1092_BITS_PER_SAMPLE);
 	hm1092->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops,
 					       V4L2_CID_PIXEL_RATE, 0,
 					       pixel_rate, 1, pixel_rate);
@@ -438,7 +687,7 @@ static int hm1092_init_controls(struct hm1092 *hm1092)
 					     mode->vts -
 					     HM1092_EXPOSURE_MARGIN,
 					     HM1092_EXPOSURE_STEP,
-					     HM1092_EXPOSURE_DEFAULT);
+					     mode->exposure_def);
 
 	v4l2_ctrl_new_std(ctrl_hdlr, &hm1092_ctrl_ops,
 			  V4L2_CID_ANALOGUE_GAIN,
@@ -480,10 +729,11 @@ err_free:
 	return ret;
 }
 
-static void hm1092_update_pad_format(struct v4l2_mbus_framefmt *fmt)
+static void hm1092_update_pad_format(const struct hm1092_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
 {
-	fmt->width = hm1092_mode_560x360.width;
-	fmt->height = hm1092_mode_560x360.height;
+	fmt->width = mode->width;
+	fmt->height = mode->height;
 	fmt->code = MEDIA_BUS_FMT_Y10_1X10;
 	fmt->field = V4L2_FIELD_NONE;
 	fmt->colorspace = V4L2_COLORSPACE_RAW;
@@ -503,8 +753,8 @@ static int hm1092_enable_streams(struct v4l2_subdev *sd,
 	if (ret)
 		return ret;
 
-	ret = cci_multi_reg_write(hm1092->regmap, hm1092_init_regs,
-				  ARRAY_SIZE(hm1092_init_regs), NULL);
+	ret = cci_multi_reg_write(hm1092->regmap, hm1092->mode->regs,
+				  hm1092->mode->num_regs, NULL);
 	if (ret) {
 		dev_err(hm1092->dev, "failed to write init registers\n");
 		goto out;
@@ -556,16 +806,18 @@ static int hm1092_enum_frame_size(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_state *state,
 				  struct v4l2_subdev_frame_size_enum *fse)
 {
+	const struct hm1092_mode *mode = to_hm1092(sd)->mode;
+
 	if (fse->index)
 		return -EINVAL;
 
 	if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
 		return -EINVAL;
 
-	fse->min_width = hm1092_mode_560x360.width;
-	fse->max_width = hm1092_mode_560x360.width;
-	fse->min_height = hm1092_mode_560x360.height;
-	fse->max_height = hm1092_mode_560x360.height;
+	fse->min_width = mode->width;
+	fse->max_width = mode->width;
+	fse->min_height = mode->height;
+	fse->max_height = mode->height;
 
 	return 0;
 }
@@ -576,10 +828,7 @@ static int hm1092_get_selection(struct v4l2_subdev *sd,
 {
 	switch (sel->target) {
 	case V4L2_SEL_TGT_CROP:
-		sel->r.left = HM1092_CROP_LEFT;
-		sel->r.top = HM1092_CROP_TOP;
-		sel->r.width = HM1092_CROP_WIDTH;
-		sel->r.height = HM1092_CROP_HEIGHT;
+		sel->r = to_hm1092(sd)->mode->crop;
 		return 0;
 	case V4L2_SEL_TGT_CROP_DEFAULT:
 	case V4L2_SEL_TGT_CROP_BOUNDS:
@@ -602,7 +851,8 @@ static int hm1092_get_selection(struct v4l2_subdev *sd,
 static int hm1092_init_state(struct v4l2_subdev *sd,
 			     struct v4l2_subdev_state *state)
 {
-	hm1092_update_pad_format(v4l2_subdev_state_get_format(state, 0));
+	hm1092_update_pad_format(to_hm1092(sd)->mode,
+				 v4l2_subdev_state_get_format(state, 0));
 
 	return 0;
 }
@@ -663,6 +913,14 @@ static int hm1092_check_hwcfg(struct hm1092 *hm1092)
 	if (ret)
 		goto out;
 
+	if (!(link_freq_bitmap & BIT(hm1092->mode->link_freq_index))) {
+		ret = dev_err_probe(dev, -EINVAL,
+				    "link frequency %lld not available for a %lu Hz external clock\n",
+				    hm1092_link_freq_menu[hm1092->mode->link_freq_index],
+				    hm1092->mode->mclk);
+		goto out;
+	}
+
 	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1) {
 		ret = dev_err_probe(dev, -EINVAL,
 				    "only 1 data lane is supported, got %u\n",
@@ -775,7 +1033,13 @@ static int hm1092_probe(struct i2c_client *client)
 				     "failed to get imaging clock\n");
 
 	freq = clk_get_rate(hm1092->img_clk);
-	if (freq != HM1092_MCLK)
+	for (unsigned int i = 0; i < ARRAY_SIZE(hm1092_modes); i++) {
+		if (hm1092_modes[i].mclk == freq) {
+			hm1092->mode = &hm1092_modes[i];
+			break;
+		}
+	}
+	if (!hm1092->mode)
 		return dev_err_probe(hm1092->dev, -EINVAL,
 				     "external clock %lu is not supported\n",
 				     freq);
@@ -841,6 +1105,12 @@ err_ctrls:
 static DEFINE_RUNTIME_DEV_PM_OPS(hm1092_pm_ops, hm1092_power_off,
 				 hm1092_power_on, NULL);
 
+static const struct acpi_device_id hm1092_acpi_ids[] = {
+	{ "HIMX1092" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, hm1092_acpi_ids);
+
 static const struct of_device_id hm1092_of_match[] = {
 	{ .compatible = "himax,hm1092" },
 	{ /* sentinel */ }
@@ -851,6 +1121,7 @@ static struct i2c_driver hm1092_i2c_driver = {
 	.driver = {
 		.name = "hm1092",
 		.pm = pm_ptr(&hm1092_pm_ops),
+		.acpi_match_table = hm1092_acpi_ids,
 		.of_match_table = hm1092_of_match,
 	},
 	.probe = hm1092_probe,
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats
  2026-10-10  4:59 ` [PATCH 0/2] media: hm1092: Intel IPU (ACPI) support on top of v6 Jake Steinman
  2026-10-10  4:59   ` [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration Jake Steinman
@ 2026-10-10  4:59   ` Jake Steinman
  2026-10-12 21:25     ` Sakari Ailus
  1 sibling, 1 reply; 7+ messages in thread
From: Jake Steinman @ 2026-10-10  4:59 UTC (permalink / raw)
  To: Ramshouriesh R, Sakari Ailus
  Cc: Mauro Carvalho Chehab, Hans de Goede, Hans Verkuil,
	Bryan O'Donoghue, Vladimir Zapolskiy, Bingbu Cao,
	Greg Kroah-Hartman, linux-media, linux-staging, linux-kernel

The CSI-2 receiver sub-device accepts MEDIA_BUS_FMT_Y10_1X10, but the
capture nodes have no pixel format that maps to it. Link validation
between the receiver and the capture node therefore always fails for a
monochrome sensor and nothing can be captured from it.

Add V4L2_PIX_FMT_Y10 and V4L2_PIX_FMT_Y10P. They use the same firmware
frame formats as the unpacked and packed 10-bit Bayer formats, as the
ipu6 driver already does.

Tested on Panther Lake with a Himax HM1092: both formats capture
648x368 frames, with 1344 and 832 bytes per line.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jake Steinman <j@metarealtyinc.ca>
---
 drivers/staging/media/ipu7/ipu7-isys-video.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c
index 8c67308..8a7c2af 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-video.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-video.c
@@ -54,6 +54,8 @@ const struct ipu7_isys_pixelformat ipu7_isys_pfmts[] = {
 	 IPU_INSYS_FRAME_FORMAT_RAW16},
 	{V4L2_PIX_FMT_SRGGB10, 16, 10, MEDIA_BUS_FMT_SRGGB10_1X10,
 	 IPU_INSYS_FRAME_FORMAT_RAW16},
+	{V4L2_PIX_FMT_Y10, 16, 10, MEDIA_BUS_FMT_Y10_1X10,
+	 IPU_INSYS_FRAME_FORMAT_RAW16},
 	{V4L2_PIX_FMT_SBGGR8, 8, 8, MEDIA_BUS_FMT_SBGGR8_1X8,
 	 IPU_INSYS_FRAME_FORMAT_RAW8},
 	{V4L2_PIX_FMT_SGBRG8, 8, 8, MEDIA_BUS_FMT_SGBRG8_1X8,
@@ -78,6 +80,8 @@ const struct ipu7_isys_pixelformat ipu7_isys_pfmts[] = {
 	 IPU_INSYS_FRAME_FORMAT_RAW10},
 	{V4L2_PIX_FMT_SRGGB10P, 10, 10, MEDIA_BUS_FMT_SRGGB10_1X10,
 	 IPU_INSYS_FRAME_FORMAT_RAW10},
+	{V4L2_PIX_FMT_Y10P, 10, 10, MEDIA_BUS_FMT_Y10_1X10,
+	 IPU_INSYS_FRAME_FORMAT_RAW10},
 	{V4L2_PIX_FMT_UYVY, 16, 16, MEDIA_BUS_FMT_UYVY8_1X16,
 	 IPU_INSYS_FRAME_FORMAT_UYVY},
 	{V4L2_PIX_FMT_YUYV, 16, 16, MEDIA_BUS_FMT_YUYV8_1X16,
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration
  2026-10-10  4:59   ` [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration Jake Steinman
@ 2026-10-10  9:15     ` Eduard Kulyk
  2026-10-12 11:07     ` Uwe Kleine-König
  1 sibling, 0 replies; 7+ messages in thread
From: Eduard Kulyk @ 2026-10-10  9:15 UTC (permalink / raw)
  To: j
  Cc: Ramshouriesh R, Sakari Ailus, Mauro Carvalho Chehab,
	Hans de Goede, Hans Verkuil, Bryan O'Donoghue,
	Vladimir Zapolskiy, Bingbu Cao, Greg Kroah-Hartman, linux-media,
	linux-staging, linux-kernel

Hi Jake,

Tested v6 plus this patch on a Dell Latitude 7350 (Meteor Lake, IPU6),
kernel 7.2.3, with an out-of-tree ipu-bridge that has the HIMX1092
entry. Patch 2 is not needed there, IPU6 already has Y10.

The sensor binds as hm1092 i2c-HIMX1092:00 and streams Y10 648x368
(1344 bytes per line) through IPU6 CSI2 4 at link frequency 180480000.

- v4l2-compliance 1.32.0 on the subdev: 46 tests, 0 failures,
  0 warnings
- 300 frames at 30.11 fps, 20 start/stop cycles without errors
- runtime PM: suspended when idle, active while streaming
- streams again after s2idle suspend/resume
- exposure and analogue gain behave as expected (analogue gain
  0/32/64/128/255 gives mean levels 16/31/45/73/113)
- IR flood LED (INT3472) off/on/off at exposure 700: mean levels
  9/117/9, clean IR image with the LED on
- the crop rectangle reads (0,0)/1294x734 against bounds
  (8,8)/1280x720, as you described

One issue, which I think comes from v6 rather than this patch:
digital_gain is advertised as 256..4095, but only the low 10 bits
seem to take effect. At exposure 100:

  256  -> 15     1024 -> 8 (black frame)
  512  -> 22     1280 -> 15
  768  -> 29     2048 -> 8 (black frame)
  1023 -> 36     4095 -> 35

So 1024 behaves like 0 and 1280 like 256. Perhaps the maximum should
be 0x3ff, but I don't have the datasheet to confirm.

Thanks a lot for your work on this. If you need anything else tested on
this machine, feel free to contact me.

Tested-by: Eduard Kulyk <kulikeduard89@gmail.com> # Dell Latitude 7350 (IPU6)

Regards,
Eduard

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration
  2026-10-10  4:59   ` [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration Jake Steinman
  2026-10-10  9:15     ` Eduard Kulyk
@ 2026-10-12 11:07     ` Uwe Kleine-König
  1 sibling, 0 replies; 7+ messages in thread
From: Uwe Kleine-König @ 2026-10-12 11:07 UTC (permalink / raw)
  To: Jake Steinman
  Cc: Ramshouriesh R, Sakari Ailus, Mauro Carvalho Chehab,
	Hans de Goede, Hans Verkuil, Bryan O'Donoghue,
	Vladimir Zapolskiy, Bingbu Cao, Greg Kroah-Hartman, linux-media,
	linux-staging, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 470 bytes --]

Hello,

On Sat, Oct 10, 2026 at 12:59:21AM -0400, Jake Steinman wrote:
>  #include <linux/i2c.h>
> +#include <linux/mod_devicetable.h>

Please don't add new usages of <linux/mod_devicetable.h>. The subsystem
headers provide their respective *_device_id structures already. So
<linux/i2c.h> already provides i2c_device_id (and of_device_id). If you
still think you need a specific header for these structures, please use
<linux/device-id/$subsystem.h>.

Best regards
Uwe

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats
  2026-10-10  4:59   ` [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats Jake Steinman
@ 2026-10-12 21:25     ` Sakari Ailus
  2026-10-12 23:30       ` Jake Steinman
  0 siblings, 1 reply; 7+ messages in thread
From: Sakari Ailus @ 2026-10-12 21:25 UTC (permalink / raw)
  To: Jake Steinman
  Cc: Ramshouriesh R, Mauro Carvalho Chehab, Hans de Goede,
	Hans Verkuil, Bryan O'Donoghue, Vladimir Zapolskiy,
	Bingbu Cao, Greg Kroah-Hartman, linux-media, linux-staging,
	linux-kernel

Hi Jake,

On Sat, Oct 10, 2026 at 12:59:22AM -0400, Jake Steinman wrote:
> The CSI-2 receiver sub-device accepts MEDIA_BUS_FMT_Y10_1X10, but the
> capture nodes have no pixel format that maps to it. Link validation
> between the receiver and the capture node therefore always fails for a
> monochrome sensor and nothing can be captured from it.
> 
> Add V4L2_PIX_FMT_Y10 and V4L2_PIX_FMT_Y10P. They use the same firmware
> frame formats as the unpacked and packed 10-bit Bayer formats, as the
> ipu6 driver already does.
> 
> Tested on Panther Lake with a Himax HM1092: both formats capture
> 648x368 frames, with 1344 and 832 bytes per line.
> 
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Jake Steinman <j@metarealtyinc.ca>
> ---
>  drivers/staging/media/ipu7/ipu7-isys-video.c | 4 ++++

We're about to remove the ipu7 staging driver, therefore I'm not taking
non-fix patches to it. Can you se the ipu6 driver instead?

-- 
Regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats
  2026-10-12 21:25     ` Sakari Ailus
@ 2026-10-12 23:30       ` Jake Steinman
  0 siblings, 0 replies; 7+ messages in thread
From: Jake Steinman @ 2026-10-12 23:30 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Ramshouriesh R, Mauro Carvalho Chehab, Hans de Goede,
	Hans Verkuil, Bryan O'Donoghue, Vladimir Zapolskiy,
	Bingbu Cao, Greg Kroah-Hartman, Eduard Kulyk, linux-media,
	linux-staging, linux-kernel

Hi Sakari,

On Mon, Oct 12, 2026, Sakari Ailus wrote:
> We're about to remove the ipu7 staging driver, therefore I'm not taking
> non-fix patches to it. Can you se the ipu6 driver instead?

Understood, I will drop this patch. The ipu6 driver already has Y10 and
Y10P, so nothing is needed there. I will retest the sensor patch on
Panther Lake with the ipu6 driver from media/next and send v2 with the
result.

Jake

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-10-12 23:30 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20260801-hm1092-driver-v6-0-5979f223748a@gmail.com>
2026-10-10  4:59 ` [PATCH 0/2] media: hm1092: Intel IPU (ACPI) support on top of v6 Jake Steinman
2026-10-10  4:59   ` [PATCH 1/2] media: i2c: hm1092: Add ACPI enumeration and the 19.2 MHz configuration Jake Steinman
2026-10-10  9:15     ` Eduard Kulyk
2026-10-12 11:07     ` Uwe Kleine-König
2026-10-10  4:59   ` [PATCH 2/2] media: staging/ipu7: Add 10-bit greyscale capture formats Jake Steinman
2026-10-12 21:25     ` Sakari Ailus
2026-10-12 23:30       ` Jake Steinman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox