about summary refs log tree commit diff
path: root/pkgs/os-specific
diff options
context:
space:
mode:
authorMartin Weinelt <mweinelt@users.noreply.github.com>2023-04-07 22:37:35 +0200
committerGitHub <noreply@github.com>2023-04-07 22:37:35 +0200
commit752fabf7560aed57324d9c1708b683144a0d34e2 (patch)
tree5e9cabefbaa9f530acd4398d8c8848d5208059d7 /pkgs/os-specific
parent90d0f41c2bfb5bc434bfe51b3735f1550b21c1d3 (diff)
parent0bf0d21e9b10694b003ea48cf92562373e7c0208 (diff)
Merge pull request #225160 from betaboon/ipu6-continuation
Ipu6 continuation
Diffstat (limited to 'pkgs/os-specific')
-rw-r--r--pkgs/os-specific/linux/firmware/ipu6-camera-bins/default.nix16
-rw-r--r--pkgs/os-specific/linux/ipu6-drivers/default.nix13
-rw-r--r--pkgs/os-specific/linux/ipu6-drivers/pr-84-unpatched-upstream-compatiblity.patch365
-rw-r--r--pkgs/os-specific/linux/v4l2-relayd/default.nix81
-rw-r--r--pkgs/os-specific/linux/v4l2-relayd/upstream-v4l2loopback-compatibility.patch16
-rw-r--r--pkgs/os-specific/linux/v4l2loopback/default.nix11
-rw-r--r--pkgs/os-specific/linux/v4l2loopback/revert-pr518.patch55
7 files changed, 547 insertions, 10 deletions
diff --git a/pkgs/os-specific/linux/firmware/ipu6-camera-bins/default.nix b/pkgs/os-specific/linux/firmware/ipu6-camera-bins/default.nix
index bad61f02ad942..7e0fb379107d2 100644
--- a/pkgs/os-specific/linux/firmware/ipu6-camera-bins/default.nix
+++ b/pkgs/os-specific/linux/firmware/ipu6-camera-bins/default.nix
@@ -1,6 +1,9 @@
 { lib
 , stdenv
 , fetchFromGitHub
+, autoPatchelfHook
+, expat
+, zlib
 
 # Pick one of
 # - ipu6 (Tiger Lake)
@@ -10,17 +13,24 @@
 
 stdenv.mkDerivation {
   pname = "${ipuVersion}-camera-bin";
-  version = "unstable-2022-11-12";
+  version = "unstable-2023-02-08";
 
   src = fetchFromGitHub {
     owner = "intel";
     repo = "ipu6-camera-bins";
-    rev = "4694ba7ee51652d29ef41e7fde846b83a2a1c53b";
-    hash = "sha256-XPT3dbV6Kl1/TEeiQESF4Q4s95hjtiv4VLlqlahQXqE=";
+    rev = "276859fc6de83918a32727d676985ec40f31af2b";
+    hash = "sha256-QnedM2UBbGyd2wIF762Mi+VkDZYtC6MifK4XGGxlUzw=";
   };
 
   sourceRoot = "source/${ipuVersion}";
 
+  nativeBuildInputs = [
+    autoPatchelfHook
+    stdenv.cc.cc.lib
+    expat
+    zlib
+  ];
+
   installPhase = ''
     runHook preInstall
 
diff --git a/pkgs/os-specific/linux/ipu6-drivers/default.nix b/pkgs/os-specific/linux/ipu6-drivers/default.nix
index 155e384a119db..5c3d20b7e54fd 100644
--- a/pkgs/os-specific/linux/ipu6-drivers/default.nix
+++ b/pkgs/os-specific/linux/ipu6-drivers/default.nix
@@ -7,15 +7,20 @@
 
 stdenv.mkDerivation rec {
   pname = "ipu6-drivers";
-  version = "unstable-2023-01-17";
+  version = "unstable-2023-02-20";
 
   src = fetchFromGitHub {
     owner = "intel";
     repo = pname;
-    rev = "f83b0747b297cc42325668aaf69471d89253b88e";
-    hash = "sha256-yl2ZtJUTh1/qmTA8USd+FBCUAY5qNdh4bSvFRPImQNI=";
+    rev = "dfedab03f3856010d37968cb384696038c73c984";
+    hash = "sha256-TKo04+fqY64SdDuWApuzRXBnaAW2DReubwFRsdfJMWM=";
   };
 
+  patches = [
+    # https://github.com/intel/ipu6-drivers/pull/84
+    ./pr-84-unpatched-upstream-compatiblity.patch
+  ];
+
   postPatch = ''
     cp --no-preserve=mode --recursive --verbose \
       ${ivsc-driver.src}/backport-include \
@@ -47,6 +52,6 @@ stdenv.mkDerivation rec {
     license = lib.licenses.gpl2;
     maintainers = with lib.maintainers; [ hexa ];
     platforms = [ "x86_64-linux" ];
-    broken = kernel.kernelOlder "5.15";
+    broken = kernel.kernelOlder "6.1.7";
   };
 }
diff --git a/pkgs/os-specific/linux/ipu6-drivers/pr-84-unpatched-upstream-compatiblity.patch b/pkgs/os-specific/linux/ipu6-drivers/pr-84-unpatched-upstream-compatiblity.patch
new file mode 100644
index 0000000000000..0c7179aa82b6b
--- /dev/null
+++ b/pkgs/os-specific/linux/ipu6-drivers/pr-84-unpatched-upstream-compatiblity.patch
@@ -0,0 +1,365 @@
+From 8f4346915bb7e3a3ad3eea2c24b6da09dac257b2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 29 Nov 2022 15:06:23 +0100
+Subject: [PATCH 1/4] sensors: Use clk-framework instead of a "clken" GPIO
+
+Use the clk-framework to get a clk-provider reference and use
+clk_prepare_enable() / clk_disable_unprepare() to control the clk.
+
+This replace modelling the clock as a "clken" GPIO, which is not a valid
+way to model it when the clk is e.g. generated by the clk-generator of
+a TPS68470 PMIC.
+
+This relies on the following upstream bugfix for the INT3472 clk provider:
+
+https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cf5ac2d45f6e4d11ad78e7b10ae9a4121ba5e995
+
+"platform/x86: int3472/discrete: Ensure the clk/power enable pins are in output mode"
+
+This patch is available since upstream kernel 6.1.7, so the new
+code is only enabled for LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 7)
+
+This allow susing the IPU6 sensor drivers with the upstream int3472
+driver with unmodified upstream kernels >= 6.1.7 .
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/media/i2c/hm11b1.c  | 18 ++++++++++++++++++
+ drivers/media/i2c/ov01a1s.c | 18 ++++++++++++++++++
+ 2 files changed, 36 insertions(+)
+
+diff --git a/drivers/media/i2c/hm11b1.c b/drivers/media/i2c/hm11b1.c
+index 1cc5cd761fbf..e14810bdd612 100644
+--- a/drivers/media/i2c/hm11b1.c
++++ b/drivers/media/i2c/hm11b1.c
+@@ -468,8 +468,13 @@ struct hm11b1 {
+ 	struct gpio_desc *reset_gpio;
+ 	/* GPIO for powerdown */
+ 	struct gpio_desc *powerdown_gpio;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	/* GPIO for clock enable */
+ 	struct gpio_desc *clken_gpio;
++#else
++	/* Clock provider */
++	struct clk *clk;
++#endif
+ 	/* GPIO for privacy LED */
+ 	struct gpio_desc *pled_gpio;
+ #endif
+@@ -508,7 +513,14 @@ static void hm11b1_set_power(struct hm11b1 *hm11b1, int on)
+ 		return;
+ 	gpiod_set_value_cansleep(hm11b1->reset_gpio, on);
+ 	gpiod_set_value_cansleep(hm11b1->powerdown_gpio, on);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	gpiod_set_value_cansleep(hm11b1->clken_gpio, on);
++#else
++	if (on)
++		clk_prepare_enable(hm11b1->clk);
++	else
++		clk_disable_unprepare(hm11b1->clk);
++#endif
+ 	gpiod_set_value_cansleep(hm11b1->pled_gpio, on);
+ 	msleep(20);
+ #elif IS_ENABLED(CONFIG_POWER_CTRL_LOGIC)
+@@ -1093,12 +1105,18 @@ static int hm11b1_parse_dt(struct hm11b1 *hm11b1)
+ 		return ret;
+ 	}
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	hm11b1->clken_gpio = devm_gpiod_get(dev, "clken", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(hm11b1->clken_gpio);
+ 	if (ret < 0) {
+ 		dev_err(dev, "error while getting clken_gpio gpio: %d\n", ret);
+ 		return ret;
+ 	}
++#else
++	hm11b1->clk = devm_clk_get_optional(dev, "clk");
++	if (IS_ERR(hm11b1->clk))
++		return dev_err_probe(dev, PTR_ERR(hm11b1->clk), "getting clk\n");
++#endif
+ 
+ 	hm11b1->pled_gpio = devm_gpiod_get(dev, "pled", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(hm11b1->pled_gpio);
+diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c
+index e4477625ce3b..628a1dd83ddf 100644
+--- a/drivers/media/i2c/ov01a1s.c
++++ b/drivers/media/i2c/ov01a1s.c
+@@ -317,8 +317,13 @@ struct ov01a1s {
+ 	struct gpio_desc *reset_gpio;
+ 	/* GPIO for powerdown */
+ 	struct gpio_desc *powerdown_gpio;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	/* GPIO for clock enable */
+ 	struct gpio_desc *clken_gpio;
++#else
++	/* Clock provider */
++	struct clk *clk;
++#endif
+ 	/* GPIO for privacy LED */
+ 	struct gpio_desc *pled_gpio;
+ #endif
+@@ -339,7 +344,14 @@ static void ov01a1s_set_power(struct ov01a1s *ov01a1s, int on)
+ 		return;
+ 	gpiod_set_value_cansleep(ov01a1s->reset_gpio, on);
+ 	gpiod_set_value_cansleep(ov01a1s->powerdown_gpio, on);
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	gpiod_set_value_cansleep(ov01a1s->clken_gpio, on);
++#else
++	if (on)
++		clk_prepare_enable(ov01a1s->clk);
++	else
++		clk_disable_unprepare(ov01a1s->clk);
++#endif
+ 	gpiod_set_value_cansleep(ov01a1s->pled_gpio, on);
+ 	msleep(20);
+ #elif IS_ENABLED(CONFIG_POWER_CTRL_LOGIC)
+@@ -945,12 +957,18 @@ static int ov01a1s_parse_dt(struct ov01a1s *ov01a1s)
+ 		return -EPROBE_DEFER;
+ 	}
+ 
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	ov01a1s->clken_gpio = devm_gpiod_get(dev, "clken", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(ov01a1s->clken_gpio);
+ 	if (ret < 0) {
+ 		dev_err(dev, "error while getting clken_gpio gpio: %d\n", ret);
+ 		return -EPROBE_DEFER;
+ 	}
++#else
++	ov01a1s->clk = devm_clk_get_optional(dev, "clk");
++	if (IS_ERR(ov01a1s->clk))
++		return dev_err_probe(dev, PTR_ERR(ov01a1s->clk), "getting clk\n");
++#endif
+ 
+ 	ov01a1s->pled_gpio = devm_gpiod_get(dev, "pled", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(ov01a1s->pled_gpio);
+
+From b04fdf6433f6b64840d46f92ddf3d6d18e86ede3 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 29 Nov 2022 23:37:50 +0100
+Subject: [PATCH 2/4] sensors: Make powerdown and reset signals active-low by
+ default
+
+The powerdown and reset functions should be set to 0, as in
+not-powered-down, not-in-reset when the sensor is turned on.
+
+Adjust the gpiod_set() value parameters for the powerdown_gpio
+and reset_gpio to !on to properly reflect this.
+
+Typical sensors however have a NRESET aka /RESET pin which needs
+to be driven low to put the device in reset and the have
+a powerup/enable pin rather then a powerdown pin. So at
+the physicical level the pins associated with the reset and
+powerdown functions need to be driven low to put the chip
+in reset / to power the chip down. Mark the pins as active-low
+in the added gpio-lookup table entries for these pin to
+reflect this.
+
+This double negation has 0 net effect, but it uses the GPIO
+subsystem functionality as intended (setting reset to 0
+on poweron makes lot more sense then setting it to 1 on poweron)
+and it aligns the use of these GPIOs with that of the mainline
+kernel allowing future use of the IPU6 driver with the
+mainline INT3472 driver without needing to patch the mainline
+kernel.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/media/i2c/hm11b1.c                                    | 4 ++--
+ drivers/media/i2c/ov01a1s.c                                   | 4 ++--
+ drivers/media/i2c/ov2740.c                                    | 2 +-
+ ...nt3472-support-independent-clock-and-LED-gpios-5.17+.patch | 4 ++--
+ patch/int3472-support-independent-clock-and-LED-gpios.patch   | 4 ++--
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/i2c/hm11b1.c b/drivers/media/i2c/hm11b1.c
+index e14810bdd612..652e8f177044 100644
+--- a/drivers/media/i2c/hm11b1.c
++++ b/drivers/media/i2c/hm11b1.c
+@@ -511,8 +511,8 @@ static void hm11b1_set_power(struct hm11b1 *hm11b1, int on)
+ #if IS_ENABLED(CONFIG_INTEL_SKL_INT3472)
+ 	if (!(hm11b1->reset_gpio && hm11b1->powerdown_gpio))
+ 		return;
+-	gpiod_set_value_cansleep(hm11b1->reset_gpio, on);
+-	gpiod_set_value_cansleep(hm11b1->powerdown_gpio, on);
++	gpiod_set_value_cansleep(hm11b1->reset_gpio, !on);
++	gpiod_set_value_cansleep(hm11b1->powerdown_gpio, !on);
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	gpiod_set_value_cansleep(hm11b1->clken_gpio, on);
+ #else
+diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c
+index 628a1dd83ddf..2ce81d04abf6 100644
+--- a/drivers/media/i2c/ov01a1s.c
++++ b/drivers/media/i2c/ov01a1s.c
+@@ -342,8 +342,8 @@ static void ov01a1s_set_power(struct ov01a1s *ov01a1s, int on)
+ #if IS_ENABLED(CONFIG_INTEL_SKL_INT3472)
+ 	if (!(ov01a1s->reset_gpio && ov01a1s->powerdown_gpio))
+ 		return;
+-	gpiod_set_value_cansleep(ov01a1s->reset_gpio, on);
+-	gpiod_set_value_cansleep(ov01a1s->powerdown_gpio, on);
++	gpiod_set_value_cansleep(ov01a1s->reset_gpio, !on);
++	gpiod_set_value_cansleep(ov01a1s->powerdown_gpio, !on);
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 7)
+ 	gpiod_set_value_cansleep(ov01a1s->clken_gpio, on);
+ #else
+diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
+index 67fb17e08e36..a8bb101776bd 100644
+--- a/drivers/media/i2c/ov2740.c
++++ b/drivers/media/i2c/ov2740.c
+@@ -596,7 +596,7 @@ static void ov2740_set_power(struct ov2740 *ov2740, int on)
+ {
+ 	if (!(ov2740->reset_gpio && ov2740->pled_gpio))
+ 		return;
+-	gpiod_set_value_cansleep(ov2740->reset_gpio, on);
++	gpiod_set_value_cansleep(ov2740->reset_gpio, !on);
+ 	gpiod_set_value_cansleep(ov2740->pled_gpio, on);
+ 	msleep(20);
+ }
+diff --git a/patch/int3472-support-independent-clock-and-LED-gpios-5.17+.patch b/patch/int3472-support-independent-clock-and-LED-gpios-5.17+.patch
+index 57373ac85f39..66ed770b68a0 100644
+--- a/patch/int3472-support-independent-clock-and-LED-gpios-5.17+.patch
++++ b/patch/int3472-support-independent-clock-and-LED-gpios-5.17+.patch
+@@ -65,7 +65,7 @@ index ed4c9d760757..f5857ec334fa 100644
+  	case INT3472_GPIO_TYPE_RESET:
+  		ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "reset",
+ -						     GPIO_ACTIVE_LOW);
+-+						     polarity);
+++						     polarity ^ GPIO_ACTIVE_LOW);
+  		if (ret)
+  			err_msg = "Failed to map reset pin to sensor\n";
+  
+@@ -73,7 +73,7 @@ index ed4c9d760757..f5857ec334fa 100644
+  	case INT3472_GPIO_TYPE_POWERDOWN:
+  		ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "powerdown",
+ -						     GPIO_ACTIVE_LOW);
+-+						     polarity);
+++						     polarity ^ GPIO_ACTIVE_LOW);
+  		if (ret)
+  			err_msg = "Failed to map powerdown pin to sensor\n";
+  
+diff --git a/patch/int3472-support-independent-clock-and-LED-gpios.patch b/patch/int3472-support-independent-clock-and-LED-gpios.patch
+index a2def0d76852..df70ce4a7117 100644
+--- a/patch/int3472-support-independent-clock-and-LED-gpios.patch
++++ b/patch/int3472-support-independent-clock-and-LED-gpios.patch
+@@ -65,7 +65,7 @@ index e59d79c7e82f..5cf6dd63d43f 100644
+  	case INT3472_GPIO_TYPE_RESET:
+  		ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "reset",
+ -						     GPIO_ACTIVE_LOW);
+-+						     polarity);
+++						     polarity ^ GPIO_ACTIVE_LOW);
+  		if (ret)
+  			err_msg = "Failed to map reset pin to sensor\n";
+  
+@@ -73,7 +73,7 @@ index e59d79c7e82f..5cf6dd63d43f 100644
+  	case INT3472_GPIO_TYPE_POWERDOWN:
+  		ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, "powerdown",
+ -						     GPIO_ACTIVE_LOW);
+-+						     polarity);
+++						     polarity ^ GPIO_ACTIVE_LOW);
+  		if (ret)
+  			err_msg = "Failed to map powerdown pin to sensor\n";
+  
+
+From 90d4b2d9cb07292c6a2580572252938a836f4a86 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 15 Dec 2022 16:00:31 +0100
+Subject: [PATCH 3/4] sensors: Make "pled" GPIO optional
+
+Starting with kernel 6.3 the mainline int3472 driver models the privacy
+LED device as a LED class device rather then as a GPIO.
+
+As part of these changed the v4l2-core subdev code in 6.3 turns
+the LED on/off on s_stream() on/off calls on the sensor v4l2-subdev,
+so sensor drivers don't have to take care of this themselves.
+
+Change the devm_gpiod_get() calls for the "pled" GPIO into
+devm_gpiod_get_optional() calls so that the sensor drivers
+can work with both older kernel (controlling the GPIO) and
+with newer kernels which don't have a "pled" GPIO.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/media/i2c/hm11b1.c  | 2 +-
+ drivers/media/i2c/ov01a1s.c | 2 +-
+ drivers/media/i2c/ov2740.c  | 4 +---
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/i2c/hm11b1.c b/drivers/media/i2c/hm11b1.c
+index 652e8f177044..6257f7987268 100644
+--- a/drivers/media/i2c/hm11b1.c
++++ b/drivers/media/i2c/hm11b1.c
+@@ -1118,7 +1118,7 @@ static int hm11b1_parse_dt(struct hm11b1 *hm11b1)
+ 		return dev_err_probe(dev, PTR_ERR(hm11b1->clk), "getting clk\n");
+ #endif
+ 
+-	hm11b1->pled_gpio = devm_gpiod_get(dev, "pled", GPIOD_OUT_HIGH);
++	hm11b1->pled_gpio = devm_gpiod_get_optional(dev, "pled", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(hm11b1->pled_gpio);
+ 	if (ret < 0) {
+ 		dev_err(dev, "error while getting pled gpio: %d\n", ret);
+diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c
+index 2ce81d04abf6..1bc6199713f3 100644
+--- a/drivers/media/i2c/ov01a1s.c
++++ b/drivers/media/i2c/ov01a1s.c
+@@ -970,7 +970,7 @@ static int ov01a1s_parse_dt(struct ov01a1s *ov01a1s)
+ 		return dev_err_probe(dev, PTR_ERR(ov01a1s->clk), "getting clk\n");
+ #endif
+ 
+-	ov01a1s->pled_gpio = devm_gpiod_get(dev, "pled", GPIOD_OUT_HIGH);
++	ov01a1s->pled_gpio = devm_gpiod_get_optional(dev, "pled", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(ov01a1s->pled_gpio);
+ 	if (ret < 0) {
+ 		dev_err(dev, "error while getting pled gpio: %d\n", ret);
+diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
+index a8bb101776bd..08f284d4aca1 100644
+--- a/drivers/media/i2c/ov2740.c
++++ b/drivers/media/i2c/ov2740.c
+@@ -594,8 +594,6 @@ static u64 to_pixels_per_line(u32 hts, u32 f_index)
+ 
+ static void ov2740_set_power(struct ov2740 *ov2740, int on)
+ {
+-	if (!(ov2740->reset_gpio && ov2740->pled_gpio))
+-		return;
+ 	gpiod_set_value_cansleep(ov2740->reset_gpio, !on);
+ 	gpiod_set_value_cansleep(ov2740->pled_gpio, on);
+ 	msleep(20);
+@@ -633,7 +631,7 @@ static int ov2740_parse_dt(struct ov2740 *ov2740)
+ 		return ret;
+ 	}
+ 
+-	ov2740->pled_gpio = devm_gpiod_get(dev, "pled", GPIOD_OUT_HIGH);
++	ov2740->pled_gpio = devm_gpiod_get_optional(dev, "pled", GPIOD_OUT_HIGH);
+ 	ret = PTR_ERR_OR_ZERO(ov2740->pled_gpio);
+ 	if (ret < 0) {
+ 		dev_err(dev, "error while getting pled gpio: %d\n", ret);
+
+From 5ed1980822f0cb4787d1346493d126aad1bf9210 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 29 Nov 2022 15:15:15 +0100
+Subject: [PATCH 4/4] ov01a1s: Drop unused link_freq variable
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Drop the unused link_freq variable, fixing this compiler warning:
+
+drivers/media/i2c/ov01a1s.c:994:13: warning: unused variable ‘link_freq’ [-Wunused-variable]
+  994 |         s64 link_freq;
+      |             ^~~~~~~~~
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ drivers/media/i2c/ov01a1s.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c
+index 1bc6199713f3..ab4ff255d4c1 100644
+--- a/drivers/media/i2c/ov01a1s.c
++++ b/drivers/media/i2c/ov01a1s.c
+@@ -988,7 +988,6 @@ static int ov01a1s_probe(struct i2c_client *client)
+ #if IS_ENABLED(CONFIG_INTEL_VSC)
+ 	struct vsc_mipi_config conf;
+ 	struct vsc_camera_status status;
+-	s64 link_freq;
+ #endif
+ 
+ 	ov01a1s = devm_kzalloc(&client->dev, sizeof(*ov01a1s), GFP_KERNEL);
diff --git a/pkgs/os-specific/linux/v4l2-relayd/default.nix b/pkgs/os-specific/linux/v4l2-relayd/default.nix
new file mode 100644
index 0000000000000..293210fa9f570
--- /dev/null
+++ b/pkgs/os-specific/linux/v4l2-relayd/default.nix
@@ -0,0 +1,81 @@
+{ lib
+, stdenv
+, fetchgit
+, autoreconfHook
+, coreutils
+, glib
+, gnugrep
+, gst_all_1
+, icamerasrc
+, libtool
+, makeWrapper
+, pkg-config
+, which
+}:
+let
+  gst = [
+    gst_all_1.gstreamer.out
+    gst_all_1.gst-plugins-bad
+    gst_all_1.gst-plugins-base
+    gst_all_1.gst-plugins-good
+    icamerasrc
+  ];
+in
+stdenv.mkDerivation rec {
+  pname = "v4l2-relayd-${icamerasrc.ipuVersion}";
+  version = "0.1.3";
+
+  src = fetchgit {
+    url = "https://git.launchpad.net/v4l2-relayd";
+    rev = "refs/tags/upstream/${version}";
+    hash = "sha256-oU6naDFZ0PQVHZ3brANfMULDqYMYxeJN+MCUCvN/DpU=";
+  };
+
+  patches = [
+    ./upstream-v4l2loopback-compatibility.patch
+  ];
+
+  nativeBuildInputs = [
+    autoreconfHook
+    libtool
+    makeWrapper
+    pkg-config
+    which
+  ];
+
+  buildInputs = [
+    glib
+  ] ++ gst;
+
+  preConfigure = "./autogen.sh --prefix=$out";
+
+  postInstall = ''
+    mkdir -p $out/lib/systemd/system $out/etc/default
+    cp data/systemd/v4l2-relayd.service $out/lib/systemd/system
+    cp data/etc/default/v4l2-relayd $out/etc/default
+
+    substituteInPlace $out/lib/systemd/system/v4l2-relayd.service \
+      --replace grep ${gnugrep}/bin/grep \
+      --replace cut ${coreutils}/bin/cut \
+      --replace /usr/bin/test ${coreutils}/bin/test \
+      --replace /usr/bin/v4l2-relayd $out/bin/v4l2-relayd \
+      --replace /etc/default $out/etc/default \
+      --replace "DeviceAllow=char-video4linux" ""
+
+    substituteInPlace $out/etc/default/v4l2-relayd \
+      --replace 'FORMAT=YUY2' 'FORMAT=NV12' \
+      --replace 'CARD_LABEL="Virtual Camera"' 'CARD_LABEL="Intel MIPI Camera"' \
+      --replace 'VIDEOSRC="videotestsrc"' 'VIDEOSRC="icamerasrc"'
+
+    wrapProgram $out/bin/v4l2-relayd \
+      --prefix GST_PLUGIN_PATH : ${lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" gst}
+  '';
+
+  meta = with lib; {
+    description = "Streaming relay for v4l2loopback using GStreamer";
+    homepage = "https://git.launchpad.net/v4l2-relayd";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ betaboon ];
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/os-specific/linux/v4l2-relayd/upstream-v4l2loopback-compatibility.patch b/pkgs/os-specific/linux/v4l2-relayd/upstream-v4l2loopback-compatibility.patch
new file mode 100644
index 0000000000000..6435352282560
--- /dev/null
+++ b/pkgs/os-specific/linux/v4l2-relayd/upstream-v4l2loopback-compatibility.patch
@@ -0,0 +1,16 @@
+diff --git a/src/v4l2-relayd.c b/src/v4l2-relayd.c
+index 21bb0d5..cfc9e27 100644
+--- a/src/v4l2-relayd.c
++++ b/src/v4l2-relayd.c
+@@ -27,7 +27,10 @@
+ #include <gst/app/gstappsrc.h>
+ #include <gst/video/video-info.h>
+ 
+-#define V4L2_EVENT_PRI_CLIENT_USAGE  V4L2_EVENT_PRIVATE_START
++#define V4L2LOOPBACK_EVENT_BASE (V4L2_EVENT_PRIVATE_START)
++#define V4L2LOOPBACK_EVENT_OFFSET 0x08E00000
++#define V4L2_EVENT_PRI_CLIENT_USAGE \
++	(V4L2LOOPBACK_EVENT_BASE + V4L2LOOPBACK_EVENT_OFFSET + 1)
+ 
+ struct v4l2_event_client_usage {
+   __u32 count;
diff --git a/pkgs/os-specific/linux/v4l2loopback/default.nix b/pkgs/os-specific/linux/v4l2loopback/default.nix
index 3bb1650e8c85a..2c1b4fbb4f4f6 100644
--- a/pkgs/os-specific/linux/v4l2loopback/default.nix
+++ b/pkgs/os-specific/linux/v4l2loopback/default.nix
@@ -2,15 +2,20 @@
 
 stdenv.mkDerivation rec {
   pname = "v4l2loopback";
-  version = "unstable-2022-08-05-${kernel.version}";
+  version = "unstable-2023-02-19-${kernel.version}";
 
   src = fetchFromGitHub {
     owner = "umlaeute";
     repo = "v4l2loopback";
-    rev = "76434ab6f71d5ecbff8a218ff6bed91ea2bf73b8";
-    sha256 = "sha256-TdZacRkFAO2HAEbljzXeJ241VcDqSwBECq3bnn7yvBY=";
+    rev = "fb410fc7af40e972058809a191fae9517b9313af";
+    hash = "sha256-gLFtR7s+3LUQ0BZxHbmaArHbufuphbtAX99nxJU3c84=";
   };
 
+  patches = [
+    # fix bug https://github.com/umlaeute/v4l2loopback/issues/535
+    ./revert-pr518.patch
+  ];
+
   hardeningDisable = [ "format" "pic" ];
 
   preBuild = ''
diff --git a/pkgs/os-specific/linux/v4l2loopback/revert-pr518.patch b/pkgs/os-specific/linux/v4l2loopback/revert-pr518.patch
new file mode 100644
index 0000000000000..d5d2564c32c42
--- /dev/null
+++ b/pkgs/os-specific/linux/v4l2loopback/revert-pr518.patch
@@ -0,0 +1,55 @@
+diff --git a/v4l2loopback.c b/v4l2loopback.c
+index 2ab1f76..2514f09 100644
+--- a/v4l2loopback.c
++++ b/v4l2loopback.c
+@@ -92,17 +92,6 @@ MODULE_LICENSE("GPL");
+ 		}                                                      \
+ 	} while (0)
+ 
+-/* TODO: Make sure that function is never interrupted. */
+-static inline int mod_inc(int *number, int mod)
+-{
+-	int result;
+-	result = (*number + 1) % mod;
+-	if (unlikely(result < 0))
+-		result += mod;
+-	*number = result;
+-	return result;
+-}
+-
+ static inline void v4l2l_get_timestamp(struct v4l2_buffer *b)
+ {
+ 	/* ktime_get_ts is considered deprecated, so use ktime_get_ts64 if possible */
+@@ -1424,8 +1413,9 @@ static int vidioc_reqbufs(struct file *file, void *fh,
+ 			i = dev->write_position;
+ 			list_for_each_entry(pos, &dev->outbufs_list,
+ 					    list_head) {
+-				dev->bufpos2index[mod_inc(&i, b->count)] =
++				dev->bufpos2index[i % b->count] =
+ 					pos->buffer.index;
++				++i;
+ 			}
+ 		}
+ 
+@@ -1489,9 +1479,10 @@ static void buffer_written(struct v4l2_loopback_device *dev,
+ 	del_timer_sync(&dev->timeout_timer);
+ 	spin_lock_bh(&dev->lock);
+ 
+-	dev->bufpos2index[mod_inc(&dev->write_position, dev->used_buffers)] =
++	dev->bufpos2index[dev->write_position % dev->used_buffers] =
+ 		buf->buffer.index;
+ 	list_move_tail(&buf->list_head, &dev->outbufs_list);
++	++dev->write_position;
+ 	dev->reread_count = 0;
+ 
+ 	check_timers(dev);
+@@ -1586,7 +1577,8 @@ static int get_capture_buffer(struct file *file)
+ 		if (dev->write_position >
+ 		    opener->read_position + dev->used_buffers)
+ 			opener->read_position = dev->write_position - 1;
+-		pos = mod_inc(&opener->read_position, dev->used_buffers);
++		pos = opener->read_position % dev->used_buffers;
++		++opener->read_position;
+ 	}
+ 	timeout_happened = dev->timeout_happened;
+ 	dev->timeout_happened = 0;