|
@@ -1,4 +1,4 @@
|
|
|
-From 3b09d327318b99c630c758d32d28aff5ca65c072 Mon Sep 17 00:00:00 2001
|
|
|
+From 32471cc9c5d98f0d10dbea253304e0f96abb2916 Mon Sep 17 00:00:00 2001
|
|
|
From: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
|
Date: Mon, 12 Oct 2020 21:04:11 +0300
|
|
|
Subject: [PATCH] ipu3-cio2: Use unsigned values where appropriate
|
|
@@ -316,7 +316,7 @@ index 146492383aa5..7650d7998a3f 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From c6fc4d5d0b225173cfbe1df908c8950c3f40f0bc Mon Sep 17 00:00:00 2001
|
|
|
+From 34c2da7111d19237998a6420189f5896d0b7e037 Mon Sep 17 00:00:00 2001
|
|
|
From: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
|
Date: Mon, 12 Oct 2020 21:04:12 +0300
|
|
|
Subject: [PATCH] ipu3-cio2: Remove explicit type from frame size checks
|
|
@@ -350,7 +350,7 @@ index 1fcd131482e0..b2679ff185fc 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 74f14515d35868f08cb32111ae06c33d0a7eda81 Mon Sep 17 00:00:00 2001
|
|
|
+From c0d5f91f3262dfcad057817b7cc92e27f4bc82b5 Mon Sep 17 00:00:00 2001
|
|
|
From: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
|
Date: Mon, 12 Oct 2020 21:04:13 +0300
|
|
|
Subject: [PATCH] ipu3-cio2: Rename CIO2_IMAGE_MAX_LENGTH as
|
|
@@ -409,7 +409,7 @@ index 7650d7998a3f..ccf0b85ae36f 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 656111f0523d4ab97cac8437c1617a241bece72e Mon Sep 17 00:00:00 2001
|
|
|
+From dc6a77ee8a8ad188cc3bd63231b7759ce6e95503 Mon Sep 17 00:00:00 2001
|
|
|
From: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
|
|
|
Date: Tue, 13 Oct 2020 17:25:35 +0300
|
|
|
Subject: [PATCH] ipu3-cio2: Check receved the size against payload size, not
|
|
@@ -463,7 +463,7 @@ index 51c4dd6a8f9a..c557d189200b 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 02ff48a15f0e0da02d088fc4c7ec959b97d6016d Mon Sep 17 00:00:00 2001
|
|
|
+From fbffeecd2e7454f14fae4c13b486dc136b49a750 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 10 Oct 2020 23:42:09 +0100
|
|
|
Subject: [PATCH] software_node: Fix refcounts in
|
|
@@ -511,7 +511,7 @@ index 010828fc785b..615a0c93e116 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 012323f01e585cb17073d859cba7392a9119c613 Mon Sep 17 00:00:00 2001
|
|
|
+From 025f45ed28564cdef6c7fe699432e1ae1f20a487 Mon Sep 17 00:00:00 2001
|
|
|
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
|
|
Date: Wed, 30 Dec 2020 22:44:05 +0200
|
|
|
Subject: [PATCH] media: ipu3-cio2: Add headers that ipu3-cio2.h is direct user
|
|
@@ -563,7 +563,7 @@ index ccf0b85ae36f..62187ab5ae43 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 02efb9f2e40c323cf51d9b3807e2dbea40f08d26 Mon Sep 17 00:00:00 2001
|
|
|
+From 17f9b714c6c43dd36f96013e97ed6d47230df117 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 24 Oct 2020 22:42:28 +0100
|
|
|
Subject: [PATCH] device property: Return true in fwnode_device_is_available
|
|
@@ -608,7 +608,7 @@ index 4c43d30145c6..bc9c634df6df 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 41d95371ec70fb792fdf404e09c7bc422116741d Mon Sep 17 00:00:00 2001
|
|
|
+From 7e8095e7a5754ab247ef6d7e3d459fd7b0de7b7a Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 21 Nov 2020 22:06:38 +0000
|
|
|
Subject: [PATCH] device property: Call fwnode_graph_get_endpoint_by_id() for
|
|
@@ -652,7 +652,7 @@ index bc9c634df6df..ddba75d90af2 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 077ca29de10ed13810d77e4b5283b2b71141b685 Mon Sep 17 00:00:00 2001
|
|
|
+From b80bff10119170d8dab3cda43a71624a18ec5ae8 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sun, 25 Oct 2020 22:49:08 +0000
|
|
|
Subject: [PATCH] software_node: Enforce parent before child ordering of nodes
|
|
@@ -755,7 +755,7 @@ index 615a0c93e116..ade49173ff8d 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 9cfcb92a9d56040c58453f7ff517112103f96a96 Mon Sep 17 00:00:00 2001
|
|
|
+From 7670dadea357641b8b9e5ed804e18b412fe334fc Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Wed, 21 Oct 2020 22:25:03 +0100
|
|
|
Subject: [PATCH] software_node: unregister software_nodes in reverse order
|
|
@@ -810,7 +810,7 @@ index ade49173ff8d..1f43c51b431e 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From b07d850a68e50eaa31b6d51d3a235c6a3d027f7c Mon Sep 17 00:00:00 2001
|
|
|
+From c6b79e9a2a765592e11723d61a12e3c30f8c4650 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Tue, 22 Dec 2020 13:09:05 +0000
|
|
|
Subject: [PATCH] device property: Define format macros for ports and endpoints
|
|
@@ -851,7 +851,7 @@ index 9506f8ec0974..72d36d46287d 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 048747fc7cf291e76bc88d36ce7e174dbe67c86d Mon Sep 17 00:00:00 2001
|
|
|
+From 56e57aa31cd20535fc3e3f685848da6b8ba7a469 Mon Sep 17 00:00:00 2001
|
|
|
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
|
|
Date: Tue, 15 Sep 2020 15:47:46 +0100
|
|
|
Subject: [PATCH] software_node: Add support for fwnode_graph*() family of
|
|
@@ -1019,7 +1019,7 @@ index 1f43c51b431e..2ff504aca0be 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From e5a525987762827d42408d301651ddd7dee58a13 Mon Sep 17 00:00:00 2001
|
|
|
+From f70bc3eb837b1ad8c95150b96a9768d28d4848cd Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 10 Oct 2020 23:07:22 +0100
|
|
|
Subject: [PATCH] lib/test_printf.c: Use helper function to unwind array of
|
|
@@ -1057,7 +1057,7 @@ index 7ac87f18a10f..7d60f24240a4 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 7db14aecb682f2821c02420dc3356f311591ff12 Mon Sep 17 00:00:00 2001
|
|
|
+From ecbb6f67417898624be3b3aded3aceb893025bfd Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 10 Oct 2020 23:11:36 +0100
|
|
|
Subject: [PATCH] ipu3-cio2: Add T: entry to MAINTAINERS
|
|
@@ -1088,7 +1088,7 @@ index 281de213ef47..5a1c6e959aa8 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 5cd26f650205295b0162859db1855119daa50b30 Mon Sep 17 00:00:00 2001
|
|
|
+From 231bcccd03410528c1c5971204f344ff289f9c29 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 10 Oct 2020 22:47:21 +0100
|
|
|
Subject: [PATCH] ipu3-cio2: Rename ipu3-cio2.c
|
|
@@ -1123,7 +1123,7 @@ rename to drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 173774fc8274db26b11e9518948d7dc2fbd2a286 Mon Sep 17 00:00:00 2001
|
|
|
+From c2a6d9ea77c97c0810deca4efa0e20632a0d1580 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Wed, 21 Oct 2020 21:53:05 +0100
|
|
|
Subject: [PATCH] media: v4l2-core: v4l2-async: Check sd->fwnode->secondary in
|
|
@@ -1164,7 +1164,7 @@ index e3ab003a6c85..9dd896d085ec 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 54866c066f7eb157f72611427af44096d6ed388e Mon Sep 17 00:00:00 2001
|
|
|
+From e2a35c5d387c7e8341afd52bf41a42c3cc9a8615 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sun, 15 Nov 2020 08:15:34 +0000
|
|
|
Subject: [PATCH] ACPI / bus: Add acpi_dev_get_next_match_dev() and helper
|
|
@@ -1273,7 +1273,7 @@ index 6d1879bf9440..02a716a0af5d 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 3a8c20986a3b297f30269464f628439b23b0ed7e Mon Sep 17 00:00:00 2001
|
|
|
+From 356810b8ffa42d22eeaf19b694e6d225b74580f1 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 19 Dec 2020 23:55:04 +0000
|
|
|
Subject: [PATCH] media: v4l2-fwnode: Include v4l2_fwnode_bus_type
|
|
@@ -1350,7 +1350,7 @@ index ed0840f3d5df..6ca337c28b3c 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From d3d67a61296add16ecd644971ec0ac25a6ba1022 Mon Sep 17 00:00:00 2001
|
|
|
+From f9f3ecfc891d1671fd45426e3194d774887da80b Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Wed, 21 Oct 2020 21:53:44 +0100
|
|
|
Subject: [PATCH] ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver
|
|
@@ -1948,7 +1948,7 @@ index 62187ab5ae43..dc3e343a37fb 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 66c0bc2e1a548ce3d1f6e7b3356c29c702c137ac Mon Sep 17 00:00:00 2001
|
|
|
+From b138b0799d6b023a33cdd69b2ff6ddcf2b7f189c Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Wed, 2 Dec 2020 12:38:10 +0000
|
|
|
Subject: [PATCH] acpi: utils: move acpi_lpss_dep() to utils
|
|
@@ -2050,7 +2050,7 @@ index ddca1550cce6..78b38775f18b 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 19bdf96ef080ad643ced9c7810156857d30d21ee Mon Sep 17 00:00:00 2001
|
|
|
+From 84b2fdfd7ba36a7525ff97cd4d4080471cdcba06 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Thu, 26 Nov 2020 21:12:41 +0000
|
|
|
Subject: [PATCH] acpi: utils: Add function to fetch dependent acpi_devices
|
|
@@ -2136,7 +2136,7 @@ index 02a716a0af5d..33deb22294f2 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From ec31436438fd065f39e144fbd8652d292bf07f05 Mon Sep 17 00:00:00 2001
|
|
|
+From cad6e20a6ceacb6f120f20fddd9cadc0355802d7 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Mon, 16 Nov 2020 21:38:49 +0000
|
|
|
Subject: [PATCH] i2c: i2c-core-base: Use format macro in i2c_dev_set_name()
|
|
@@ -2204,7 +2204,7 @@ index 56622658b215..65acae61dc5c 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 8b7807ff6bca711e87af1b6e5b11f0495f36c6ef Mon Sep 17 00:00:00 2001
|
|
|
+From f2760c77484f8bfd90fbae8a1dc6ae2107cb2c6e Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Wed, 2 Dec 2020 16:41:42 +0000
|
|
|
Subject: [PATCH] i2c: i2c-core-acpi: Add i2c_acpi_dev_name()
|
|
@@ -2262,7 +2262,7 @@ index 65acae61dc5c..b82aac05b17f 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From df44db561d8855d0255503e20268c08c01c3c5ee Mon Sep 17 00:00:00 2001
|
|
|
+From 869d5dd9d5828a4728ea0204e09f7ff80d56c82e Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Mon, 16 Nov 2020 00:16:56 +0000
|
|
|
Subject: [PATCH] gpio: gpiolib-acpi: Export acpi_get_gpiod()
|
|
@@ -2326,7 +2326,7 @@ index 5b1dc1ad4fb3..47ae139e8781 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 89313343dd227867456401fe62cf944058e47534 Mon Sep 17 00:00:00 2001
|
|
|
+From 8780e6b11b5d4b1a493e89cf9d4ecb4334845227 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sat, 12 Dec 2020 23:56:59 +0000
|
|
|
Subject: [PATCH] mfd: Remove tps68470 MFD driver
|
|
@@ -2359,10 +2359,10 @@ index 56bbcb2ce61b..e27d8ef3a32c 100644
|
|
|
This config adds ACPI operation region support for TI TPS68470 PMIC.
|
|
|
TPS68470 device is an advanced power management unit that powers
|
|
|
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
|
|
|
-index f20ac3d69424..751b7a733bff 100644
|
|
|
+index 14751c7ccd1f..442b2cc5e2f0 100644
|
|
|
--- a/drivers/gpio/Kconfig
|
|
|
+++ b/drivers/gpio/Kconfig
|
|
|
-@@ -1320,7 +1320,6 @@ config GPIO_TPS65912
|
|
|
+@@ -1321,7 +1321,6 @@ config GPIO_TPS65912
|
|
|
|
|
|
config GPIO_TPS68470
|
|
|
bool "TPS68470 GPIO"
|
|
@@ -2517,7 +2517,7 @@ index 4a4df4ffd18c..000000000000
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From c8f82a485887fff61743f6612812d7b66e9ebe6d Mon Sep 17 00:00:00 2001
|
|
|
+From 75ad8c2f266e8802fa95c3d59bf702af6019b41f Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Fri, 15 Jan 2021 12:37:31 +0000
|
|
|
Subject: [PATCH] platform: x86: Add intel_skl_int3472 driver
|
|
@@ -3486,7 +3486,7 @@ index 000000000000..3fe27ec0caff
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 0564d5c307f712e18fffa6816cb0853c1e6a1224 Mon Sep 17 00:00:00 2001
|
|
|
+From 12d4fe655786e70db9868cd005c28e6d5361d6b1 Mon Sep 17 00:00:00 2001
|
|
|
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
|
|
|
Date: Fri, 11 Dec 2020 21:17:35 +0100
|
|
|
Subject: [PATCH] PCI: ACPI: Fix up ACPI companion lookup for device 0 on the
|
|
@@ -3556,7 +3556,7 @@ index 745a4e0c4994..87e45a800919 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 8fea36502f89e914226e1159c094b83d9ec3d226 Mon Sep 17 00:00:00 2001
|
|
|
+From bd5f7d894a6956b9f9abf41ee22d1fcb485d5f5d Mon Sep 17 00:00:00 2001
|
|
|
From: Jake Day <jake@ninebysix.com>
|
|
|
Date: Fri, 25 Sep 2020 10:24:53 -0400
|
|
|
Subject: [PATCH] media: i2c: Add support for the OV5693 image sensor
|
|
@@ -6913,7 +6913,7 @@ index 000000000000..9a508e1f3624
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From 73624b0f335955c8cc097bdbdffe954bc5466c75 Mon Sep 17 00:00:00 2001
|
|
|
+From d830bae59cb11cbc0f97dde540b14b931ed1c0b3 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sun, 17 Jan 2021 19:08:18 +0000
|
|
|
Subject: [PATCH] media: i2c: Add reset pin toggling to ov5693
|
|
@@ -6954,7 +6954,7 @@ index 32485e4ed42b..f9ced52ad37a 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
-From f3982cd7cf3ec7bca291cfc821c4d5dedd94d7ac Mon Sep 17 00:00:00 2001
|
|
|
+From 7fb8c70cd22feb2ba77480f58d09ea44aff1c767 Mon Sep 17 00:00:00 2001
|
|
|
From: Daniel Scally <djrscally@gmail.com>
|
|
|
Date: Sun, 17 Jan 2021 21:39:15 +0000
|
|
|
Subject: [PATCH] media: i2c: Fix misnamed variable in power_down() for ov5693
|
|
@@ -6983,3 +6983,4728 @@ index f9ced52ad37a..9fd44a3d1d85 100644
|
|
|
--
|
|
|
2.30.1
|
|
|
|
|
|
+From 2e833ff778b536f2f6a401c979662122bf9e1277 Mon Sep 17 00:00:00 2001
|
|
|
+From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
|
|
|
+Date: Fri, 22 Jan 2021 20:58:13 +0100
|
|
|
+Subject: [PATCH] cio2-bridge: Parse sensor orientation and rotation
|
|
|
+MIME-Version: 1.0
|
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
|
+Content-Transfer-Encoding: 8bit
|
|
|
+
|
|
|
+The sensor orientation is read from the _PLC ACPI buffer and converted
|
|
|
+to a v4l2 format.
|
|
|
+
|
|
|
+See https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
|
|
|
+page 351 for a definition of the Panel property.
|
|
|
+
|
|
|
+The sensor rotation is read from the SSDB ACPI buffer and converted into
|
|
|
+degrees.
|
|
|
+
|
|
|
+Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/pci/intel/ipu3/cio2-bridge.c | 45 ++++++++++++++++++++--
|
|
|
+ drivers/media/pci/intel/ipu3/cio2-bridge.h | 3 ++
|
|
|
+ 2 files changed, 44 insertions(+), 4 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
+index 143f3c0f445e..806d4e5fc177 100644
|
|
|
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
+@@ -29,6 +29,7 @@ static const struct cio2_sensor_config cio2_supported_sensors[] = {
|
|
|
+ static const struct cio2_property_names prop_names = {
|
|
|
+ .clock_frequency = "clock-frequency",
|
|
|
+ .rotation = "rotation",
|
|
|
++ .orientation = "orientation",
|
|
|
+ .bus_type = "bus-type",
|
|
|
+ .data_lanes = "data-lanes",
|
|
|
+ .remote_endpoint = "remote-endpoint",
|
|
|
+@@ -72,11 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
++static u32 cio2_bridge_parse_rotation(u8 rotation)
|
|
|
++{
|
|
|
++ if (rotation == 1)
|
|
|
++ return 180;
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++
|
|
|
++static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
|
|
|
++{
|
|
|
++ switch (panel) {
|
|
|
++ case 4:
|
|
|
++ return V4L2_FWNODE_ORIENTATION_FRONT;
|
|
|
++ case 5:
|
|
|
++ return V4L2_FWNODE_ORIENTATION_BACK;
|
|
|
++ default:
|
|
|
++ return V4L2_FWNODE_ORIENTATION_EXTERNAL;
|
|
|
++ }
|
|
|
++}
|
|
|
++
|
|
|
+ static void cio2_bridge_create_fwnode_properties(
|
|
|
+ struct cio2_sensor *sensor,
|
|
|
+ struct cio2_bridge *bridge,
|
|
|
+ const struct cio2_sensor_config *cfg)
|
|
|
+ {
|
|
|
++ u32 rotation;
|
|
|
++ enum v4l2_fwnode_orientation orientation;
|
|
|
++
|
|
|
++ rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
|
|
|
++ orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
|
|
|
++
|
|
|
+ sensor->prop_names = prop_names;
|
|
|
+
|
|
|
+ sensor->local_ref[0].node = &sensor->swnodes[SWNODE_CIO2_ENDPOINT];
|
|
|
+@@ -85,9 +111,12 @@ static void cio2_bridge_create_fwnode_properties(
|
|
|
+ sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
|
|
|
+ sensor->prop_names.clock_frequency,
|
|
|
+ sensor->ssdb.mclkspeed);
|
|
|
+- sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
|
|
|
++ sensor->dev_properties[1] = PROPERTY_ENTRY_U32(
|
|
|
+ sensor->prop_names.rotation,
|
|
|
+- sensor->ssdb.degree);
|
|
|
++ rotation);
|
|
|
++ sensor->dev_properties[2] = PROPERTY_ENTRY_U32(
|
|
|
++ sensor->prop_names.orientation,
|
|
|
++ orientation);
|
|
|
+
|
|
|
+ sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
|
|
|
+ sensor->prop_names.bus_type,
|
|
|
+@@ -159,6 +188,7 @@ static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
|
|
|
+ for (i = 0; i < bridge->n_sensors; i++) {
|
|
|
+ sensor = &bridge->sensors[i];
|
|
|
+ software_node_unregister_nodes(sensor->swnodes);
|
|
|
++ ACPI_FREE(sensor->pld);
|
|
|
+ acpi_dev_put(sensor->adev);
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -170,6 +200,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
|
|
|
+ struct fwnode_handle *fwnode;
|
|
|
+ struct cio2_sensor *sensor;
|
|
|
+ struct acpi_device *adev;
|
|
|
++ acpi_status status;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
|
|
|
+@@ -193,11 +224,15 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
|
|
|
+ if (ret)
|
|
|
+ goto err_put_adev;
|
|
|
+
|
|
|
++ status = acpi_get_physical_device_location(adev->handle, &sensor->pld);
|
|
|
++ if (ACPI_FAILURE(status))
|
|
|
++ goto err_put_adev;
|
|
|
++
|
|
|
+ if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
|
|
|
+ dev_err(&adev->dev,
|
|
|
+ "Number of lanes in SSDB is invalid\n");
|
|
|
+ ret = -EINVAL;
|
|
|
+- goto err_put_adev;
|
|
|
++ goto err_free_pld;
|
|
|
+ }
|
|
|
+
|
|
|
+ cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
|
|
|
+@@ -205,7 +240,7 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
|
|
|
+
|
|
|
+ ret = software_node_register_nodes(sensor->swnodes);
|
|
|
+ if (ret)
|
|
|
+- goto err_put_adev;
|
|
|
++ goto err_free_pld;
|
|
|
+
|
|
|
+ fwnode = software_node_fwnode(&sensor->swnodes[SWNODE_SENSOR_HID]);
|
|
|
+ if (!fwnode) {
|
|
|
+@@ -225,6 +260,8 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
|
|
|
+
|
|
|
+ err_free_swnodes:
|
|
|
+ software_node_unregister_nodes(sensor->swnodes);
|
|
|
++err_free_pld:
|
|
|
++ ACPI_FREE(sensor->pld);
|
|
|
+ err_put_adev:
|
|
|
+ acpi_dev_put(sensor->adev);
|
|
|
+ err_out:
|
|
|
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
+index dd0ffcafa489..924d99d20328 100644
|
|
|
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
+@@ -80,6 +80,7 @@ struct cio2_sensor_ssdb {
|
|
|
+ struct cio2_property_names {
|
|
|
+ char clock_frequency[16];
|
|
|
+ char rotation[9];
|
|
|
++ char orientation[12];
|
|
|
+ char bus_type[9];
|
|
|
+ char data_lanes[11];
|
|
|
+ char remote_endpoint[16];
|
|
|
+@@ -106,6 +107,8 @@ struct cio2_sensor {
|
|
|
+ struct cio2_node_names node_names;
|
|
|
+
|
|
|
+ struct cio2_sensor_ssdb ssdb;
|
|
|
++ struct acpi_pld_info *pld;
|
|
|
++
|
|
|
+ struct cio2_property_names prop_names;
|
|
|
+ struct property_entry ep_properties[5];
|
|
|
+ struct property_entry dev_properties[3];
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From e767277317119f90d0841ac9c3bdce118a461e6a Mon Sep 17 00:00:00 2001
|
|
|
+From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
|
|
|
+Date: Fri, 22 Jan 2021 21:23:47 +0100
|
|
|
+Subject: [PATCH] ov5693: Add orientation and rotation controls
|
|
|
+MIME-Version: 1.0
|
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
|
+Content-Transfer-Encoding: 8bit
|
|
|
+
|
|
|
+ Parse orientation and rotation from fwnodes and initialize the
|
|
|
+ respective controls.
|
|
|
+
|
|
|
+Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 11 +++++++++++
|
|
|
+ 1 file changed, 11 insertions(+)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 9fd44a3d1d85..1a85800df7ed 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -31,6 +31,7 @@
|
|
|
+ #include <linux/i2c.h>
|
|
|
+ #include <linux/moduleparam.h>
|
|
|
+ #include <media/v4l2-device.h>
|
|
|
++#include <media/v4l2-fwnode.h>
|
|
|
+ #include <linux/io.h>
|
|
|
+ #include <linux/acpi.h>
|
|
|
+ #include <linux/regulator/consumer.h>
|
|
|
+@@ -1608,6 +1609,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
|
|
|
+ const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
|
|
|
++ struct v4l2_fwnode_device_properties props;
|
|
|
+ struct v4l2_ctrl *ctrl;
|
|
|
+ unsigned int i;
|
|
|
+ int ret;
|
|
|
+@@ -1663,6 +1665,15 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ if (ov5693->hblank)
|
|
|
+ ov5693->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
+
|
|
|
++ /* set properties from fwnode (e.g. rotation, orientation) */
|
|
|
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
|
|
++ if (ret)
|
|
|
++ return ret;
|
|
|
++
|
|
|
++ ret = v4l2_ctrl_new_fwnode_properties(&ov5693->ctrl_handler, ops, &props);
|
|
|
++ if (ret)
|
|
|
++ return ret;
|
|
|
++
|
|
|
+ /* Use same lock for controls as for everything else. */
|
|
|
+ ov5693->ctrl_handler.lock = &ov5693->input_lock;
|
|
|
+ ov5693->sd.ctrl_handler = &ov5693->ctrl_handler;
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 0823b3b1fd4f8ce2897681f9e9493a8e3c3ae952 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 23 Jan 2021 00:28:32 +0000
|
|
|
+Subject: [PATCH] platform: x86: Stylistic updates for intel-skl-int3472
|
|
|
+
|
|
|
+This commit makes a bunch of stylistic updates, minor changes and other
|
|
|
+stuff that's part of the improvements pass I'm doing to the code after
|
|
|
+taking into account feedback from the list.
|
|
|
+
|
|
|
+It also alters the ACPI buffer fetching code to be more generalisable so
|
|
|
+I can re-use it to fetch the clock frequency.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ .../platform/x86/intel_skl_int3472_common.c | 37 ++++---
|
|
|
+ .../platform/x86/intel_skl_int3472_common.h | 7 +-
|
|
|
+ .../platform/x86/intel_skl_int3472_discrete.c | 101 +++++++++---------
|
|
|
+ .../platform/x86/intel_skl_int3472_tps68470.c | 16 +--
|
|
|
+ 4 files changed, 89 insertions(+), 72 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_common.c b/drivers/platform/x86/intel_skl_int3472_common.c
|
|
|
+index 08cb9d3c06aa..549d211979e1 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_common.c
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_common.c
|
|
|
+@@ -7,41 +7,52 @@
|
|
|
+
|
|
|
+ #include "intel_skl_int3472_common.h"
|
|
|
+
|
|
|
+-int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
|
|
|
+- struct int3472_cldb *cldb)
|
|
|
++union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
|
|
|
++ char *id)
|
|
|
+ {
|
|
|
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
|
+ acpi_handle handle = adev->handle;
|
|
|
+ union acpi_object *obj;
|
|
|
+ acpi_status status;
|
|
|
+- int ret = 0;
|
|
|
+
|
|
|
+- status = acpi_evaluate_object(handle, "CLDB", NULL, &buffer);
|
|
|
++ status = acpi_evaluate_object(handle, id, NULL, &buffer);
|
|
|
+ if (ACPI_FAILURE(status))
|
|
|
+- return -ENODEV;
|
|
|
++ return ERR_PTR(-ENODEV);
|
|
|
+
|
|
|
+ obj = buffer.pointer;
|
|
|
+ if (!obj) {
|
|
|
+- dev_err(&adev->dev, "ACPI device has no CLDB object\n");
|
|
|
+- return -ENODEV;
|
|
|
++ dev_err(&adev->dev, "ACPI device has no %s object\n", id);
|
|
|
++ return ERR_PTR(-ENODEV);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (obj->type != ACPI_TYPE_BUFFER) {
|
|
|
+- dev_err(&adev->dev, "CLDB object is not an ACPI buffer\n");
|
|
|
+- ret = -EINVAL;
|
|
|
+- goto out_free_buff;
|
|
|
++ dev_err(&adev->dev, "%s object is not an ACPI buffer\n", id);
|
|
|
++ kfree(obj);
|
|
|
++ return ERR_PTR(-EINVAL);
|
|
|
+ }
|
|
|
+
|
|
|
++ return obj;
|
|
|
++}
|
|
|
++
|
|
|
++int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
|
|
|
++{
|
|
|
++ union acpi_object *obj;
|
|
|
++ int ret = 0;
|
|
|
++
|
|
|
++ obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
|
|
|
++ if (IS_ERR(obj))
|
|
|
++ return PTR_ERR(obj);
|
|
|
++
|
|
|
+ if (obj->buffer.length > sizeof(*cldb)) {
|
|
|
+ dev_err(&adev->dev, "The CLDB buffer is too large\n");
|
|
|
+ ret = -EINVAL;
|
|
|
+- goto out_free_buff;
|
|
|
++ goto out_free_obj;
|
|
|
+ }
|
|
|
+
|
|
|
+ memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
|
|
|
+
|
|
|
+-out_free_buff:
|
|
|
+- kfree(buffer.pointer);
|
|
|
++out_free_obj:
|
|
|
++ kfree(obj);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_common.h b/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
+index 4ac6bb2b223f..e1083bb67dc6 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
+@@ -29,7 +29,7 @@
|
|
|
+
|
|
|
+ #define INT3472_GPIO_FUNCTION_REMAP(_PIN, _FUNCTION) \
|
|
|
+ (const struct int3472_gpio_function_remap) { \
|
|
|
+- .documented = _PIN, \
|
|
|
++ .documented = _PIN, \
|
|
|
+ .actual = _FUNCTION \
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -95,5 +95,6 @@ struct int3472_sensor_config {
|
|
|
+ int skl_int3472_discrete_probe(struct platform_device *pdev);
|
|
|
+ int skl_int3472_discrete_remove(struct platform_device *pdev);
|
|
|
+ int skl_int3472_tps68470_probe(struct i2c_client *client);
|
|
|
+-int skl_int3472_get_cldb_buffer(struct acpi_device *adev,
|
|
|
+- struct int3472_cldb *cldb);
|
|
|
++union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
|
|
|
++ char *id);
|
|
|
++int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
+index ea7e57f3e3f0..42ae8396eb64 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
+@@ -12,12 +12,12 @@
|
|
|
+
|
|
|
+ #include "intel_skl_int3472_common.h"
|
|
|
+
|
|
|
+-/* 79234640-9e10-4fea-a5c1b5aa8b19756f */
|
|
|
++/* 79234640-9e10-4fea-a5c1-b5aa8b19756f */
|
|
|
+ static const guid_t int3472_gpio_guid =
|
|
|
+ GUID_INIT(0x79234640, 0x9e10, 0x4fea,
|
|
|
+ 0xa5, 0xc1, 0xb5, 0xaa, 0x8b, 0x19, 0x75, 0x6f);
|
|
|
+
|
|
|
+-/* 822ace8f-2814-4174-a56b5f029fe079ee */
|
|
|
++/* 822ace8f-2814-4174-a56b-5f029fe079ee */
|
|
|
+ static const guid_t cio2_sensor_module_guid =
|
|
|
+ GUID_INIT(0x822ace8f, 0x2814, 0x4174,
|
|
|
+ 0xa5, 0x6b, 0x5f, 0x02, 0x9f, 0xe0, 0x79, 0xee);
|
|
|
+@@ -94,7 +94,7 @@ static const struct clk_ops skl_int3472_clock_ops = {
|
|
|
+ };
|
|
|
+
|
|
|
+ static struct int3472_sensor_config *
|
|
|
+-int3472_get_sensor_module_config(struct int3472_device *int3472)
|
|
|
++skl_int3472_get_sensor_module_config(struct int3472_device *int3472)
|
|
|
+ {
|
|
|
+ unsigned int i = ARRAY_SIZE(int3472_sensor_configs);
|
|
|
+ struct int3472_sensor_config *ret;
|
|
|
+@@ -131,9 +131,9 @@ int3472_get_sensor_module_config(struct int3472_device *int3472)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
|
|
|
+- struct acpi_resource *ares,
|
|
|
+- char *func, u32 polarity)
|
|
|
++static int skl_int3472_map_gpio_to_sensor(struct int3472_device *int3472,
|
|
|
++ struct acpi_resource *ares,
|
|
|
++ char *func, u32 polarity)
|
|
|
+ {
|
|
|
+ char *path = ares->data.gpio.resource_source.string_ptr;
|
|
|
+ struct int3472_sensor_config *sensor_config;
|
|
|
+@@ -143,7 +143,7 @@ static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
|
|
|
+ acpi_status status;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- sensor_config = int3472_get_sensor_module_config(int3472);
|
|
|
++ sensor_config = skl_int3472_get_sensor_module_config(int3472);
|
|
|
+ if (!IS_ERR(sensor_config) && sensor_config->function_maps) {
|
|
|
+ unsigned int i = 0;
|
|
|
+
|
|
|
+@@ -186,17 +186,19 @@ static int int3472_map_gpio_to_sensor(struct int3472_device *int3472,
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int int3472_register_clock(struct int3472_device *int3472,
|
|
|
+- struct acpi_resource *ares)
|
|
|
++static int skl_int3472_register_clock(struct int3472_device *int3472,
|
|
|
++ struct acpi_resource *ares)
|
|
|
+ {
|
|
|
+ char *path = ares->data.gpio.resource_source.string_ptr;
|
|
|
+- struct clk_init_data init = { };
|
|
|
++ struct clk_init_data init = { 0 };
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+- init.name = kasprintf(GFP_KERNEL, "%s-clk", acpi_dev_name(int3472->adev));
|
|
|
++ init.name = kasprintf(GFP_KERNEL, "%s-clk",
|
|
|
++ acpi_dev_name(int3472->adev));
|
|
|
+ init.ops = &skl_int3472_clock_ops;
|
|
|
+
|
|
|
+- int3472->clock.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
|
|
|
++ int3472->clock.gpio = acpi_get_gpiod(path,
|
|
|
++ ares->data.gpio.pin_table[0]);
|
|
|
+ if (IS_ERR(int3472->clock.gpio)) {
|
|
|
+ ret = PTR_ERR(int3472->clock.gpio);
|
|
|
+ goto out_free_init_name;
|
|
|
+@@ -226,17 +228,16 @@ static int int3472_register_clock(struct int3472_device *int3472,
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int int3472_register_regulator(struct int3472_device *int3472,
|
|
|
+- struct acpi_resource *ares)
|
|
|
++static int skl_int3472_register_regulator(struct int3472_device *int3472,
|
|
|
++ struct acpi_resource *ares)
|
|
|
+ {
|
|
|
+ char *path = ares->data.gpio.resource_source.string_ptr;
|
|
|
+ struct int3472_sensor_config *sensor_config;
|
|
|
+ struct regulator_init_data init_data = { };
|
|
|
+- struct int3472_gpio_regulator *regulator;
|
|
|
+ struct regulator_config cfg = { };
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- sensor_config = int3472_get_sensor_module_config(int3472);
|
|
|
++ sensor_config = skl_int3472_get_sensor_module_config(int3472);
|
|
|
+ if (IS_ERR_OR_NULL(sensor_config)) {
|
|
|
+ dev_err(&int3472->pdev->dev, "No sensor module config\n");
|
|
|
+ return PTR_ERR(sensor_config);
|
|
|
+@@ -252,26 +253,29 @@ static int int3472_register_regulator(struct int3472_device *int3472,
|
|
|
+ init_data.num_consumer_supplies = 1;
|
|
|
+ init_data.consumer_supplies = &sensor_config->supply_map;
|
|
|
+
|
|
|
+- snprintf(int3472->regulator.regulator_name, GPIO_REGULATOR_NAME_LENGTH,
|
|
|
+- "int3472-discrete-regulator");
|
|
|
+- snprintf(int3472->regulator.supply_name, GPIO_REGULATOR_SUPPLY_NAME_LENGTH,
|
|
|
+- "supply-0");
|
|
|
++ snprintf(int3472->regulator.regulator_name,
|
|
|
++ GPIO_REGULATOR_NAME_LENGTH, "int3472-discrete-regulator");
|
|
|
++ snprintf(int3472->regulator.supply_name,
|
|
|
++ GPIO_REGULATOR_SUPPLY_NAME_LENGTH, "supply-0");
|
|
|
+
|
|
|
+- int3472->regulator.rdesc = INT3472_REGULATOR(int3472->regulator.regulator_name,
|
|
|
+- int3472->regulator.supply_name,
|
|
|
+- &int3472_gpio_regulator_ops);
|
|
|
++ int3472->regulator.rdesc = INT3472_REGULATOR(
|
|
|
++ int3472->regulator.regulator_name,
|
|
|
++ int3472->regulator.supply_name,
|
|
|
++ &int3472_gpio_regulator_ops);
|
|
|
+
|
|
|
+- int3472->regulator.gpio = acpi_get_gpiod(path, ares->data.gpio.pin_table[0]);
|
|
|
++ int3472->regulator.gpio = acpi_get_gpiod(path,
|
|
|
++ ares->data.gpio.pin_table[0]);
|
|
|
+ if (IS_ERR(int3472->regulator.gpio)) {
|
|
|
+- ret = PTR_ERR(int3472->regulator.gpio);
|
|
|
+- goto err_free_regulator;
|
|
|
++ dev_err(&int3472->pdev->dev, "Failed to get GPIO line\n");
|
|
|
++ return PTR_ERR(int3472->regulator.gpio);
|
|
|
+ }
|
|
|
+
|
|
|
+ cfg.dev = &int3472->adev->dev;
|
|
|
+ cfg.init_data = &init_data;
|
|
|
+ cfg.ena_gpiod = int3472->regulator.gpio;
|
|
|
+
|
|
|
+- int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc, &cfg);
|
|
|
++ int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
|
|
|
++ &cfg);
|
|
|
+ if (IS_ERR(int3472->regulator.rdev)) {
|
|
|
+ ret = PTR_ERR(int3472->regulator.rdev);
|
|
|
+ goto err_free_gpio;
|
|
|
+@@ -280,15 +284,13 @@ static int int3472_register_regulator(struct int3472_device *int3472,
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ err_free_gpio:
|
|
|
+- gpiod_put(regulator->gpio);
|
|
|
+-err_free_regulator:
|
|
|
+- kfree(regulator);
|
|
|
++ gpiod_put(int3472->regulator.gpio);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+- * int3472_handle_gpio_resources: maps PMIC resources to consuming sensor
|
|
|
++ * skl_int3472_handle_gpio_resources: maps PMIC resources to consuming sensor
|
|
|
+ * @ares: A pointer to a &struct acpi_resource
|
|
|
+ * @data: A pointer to a &struct int3472_device
|
|
|
+ *
|
|
|
+@@ -305,8 +307,9 @@ static int int3472_register_regulator(struct int3472_device *int3472,
|
|
|
+ *
|
|
|
+ * There are some known platform specific quirks where that does not quite
|
|
|
+ * hold up; for example where a pin with type 0x01 (Power down) is mapped to
|
|
|
+- * a sensor pin that performs a reset function. These will be handled by the
|
|
|
+- * mapping sub-functions.
|
|
|
++ * a sensor pin that performs a reset function or entries in _CRS and _DSM that
|
|
|
++ * do not actually correspond to a physical connection. These will be handled by
|
|
|
++ * the mapping sub-functions.
|
|
|
+ *
|
|
|
+ * GPIOs will either be mapped directly to the sensor device or else used
|
|
|
+ * to create clocks and regulators via the usual frameworks.
|
|
|
+@@ -317,8 +320,8 @@ static int int3472_register_regulator(struct int3472_device *int3472,
|
|
|
+ * * -ENODEV - If the resource has no corresponding _DSM entry
|
|
|
+ * * -Other - Errors propagated from one of the sub-functions.
|
|
|
+ */
|
|
|
+-static int int3472_handle_gpio_resources(struct acpi_resource *ares,
|
|
|
+- void *data)
|
|
|
++static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
|
|
|
++ void *data)
|
|
|
+ {
|
|
|
+ struct int3472_device *int3472 = data;
|
|
|
+ union acpi_object *obj;
|
|
|
+@@ -345,30 +348,30 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
|
|
|
+
|
|
|
+ switch (obj->integer.value & 0xff) {
|
|
|
+ case INT3472_GPIO_TYPE_RESET:
|
|
|
+- ret = int3472_map_gpio_to_sensor(int3472, ares, "reset",
|
|
|
+- GPIO_ACTIVE_LOW);
|
|
|
++ ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "reset",
|
|
|
++ GPIO_ACTIVE_LOW);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&int3472->pdev->dev,
|
|
|
+ "Failed to map reset pin to sensor\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ case INT3472_GPIO_TYPE_POWERDOWN:
|
|
|
+- ret = int3472_map_gpio_to_sensor(int3472, ares, "powerdown",
|
|
|
+- GPIO_ACTIVE_LOW);
|
|
|
++ ret = skl_int3472_map_gpio_to_sensor(int3472, ares, "powerdown",
|
|
|
++ GPIO_ACTIVE_LOW);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&int3472->pdev->dev,
|
|
|
+ "Failed to map powerdown pin to sensor\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ case INT3472_GPIO_TYPE_CLK_ENABLE:
|
|
|
+- ret = int3472_register_clock(int3472, ares);
|
|
|
++ ret = skl_int3472_register_clock(int3472, ares);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&int3472->pdev->dev,
|
|
|
+ "Failed to map clock to sensor\n");
|
|
|
+
|
|
|
+ break;
|
|
|
+ case INT3472_GPIO_TYPE_POWER_ENABLE:
|
|
|
+- ret = int3472_register_regulator(int3472, ares);
|
|
|
++ ret = skl_int3472_register_regulator(int3472, ares);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&int3472->pdev->dev,
|
|
|
+ "Failed to map regulator to sensor\n");
|
|
|
+@@ -376,8 +379,9 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
|
|
|
+
|
|
|
+ break;
|
|
|
+ case INT3472_GPIO_TYPE_PRIVACY_LED:
|
|
|
+- ret = int3472_map_gpio_to_sensor(int3472, ares, "indicator-led",
|
|
|
+- GPIO_ACTIVE_HIGH);
|
|
|
++ ret = skl_int3472_map_gpio_to_sensor(int3472, ares,
|
|
|
++ "indicator-led",
|
|
|
++ GPIO_ACTIVE_HIGH);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&int3472->pdev->dev,
|
|
|
+ "Failed to map indicator led to sensor\n");
|
|
|
+@@ -396,7 +400,7 @@ static int int3472_handle_gpio_resources(struct acpi_resource *ares,
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int int3472_parse_crs(struct int3472_device *int3472)
|
|
|
++static int skl_int3472_parse_crs(struct int3472_device *int3472)
|
|
|
+ {
|
|
|
+ struct list_head resource_list;
|
|
|
+ int ret = 0;
|
|
|
+@@ -404,7 +408,8 @@ static int int3472_parse_crs(struct int3472_device *int3472)
|
|
|
+ INIT_LIST_HEAD(&resource_list);
|
|
|
+
|
|
|
+ ret = acpi_dev_get_resources(int3472->adev, &resource_list,
|
|
|
+- int3472_handle_gpio_resources, int3472);
|
|
|
++ skl_int3472_handle_gpio_resources,
|
|
|
++ int3472);
|
|
|
+
|
|
|
+ if (!ret) {
|
|
|
+ gpiod_add_lookup_table(&int3472->gpios);
|
|
|
+@@ -423,7 +428,7 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
|
|
|
+ struct int3472_cldb cldb;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+- ret = skl_int3472_get_cldb_buffer(adev, &cldb);
|
|
|
++ ret = skl_int3472_fill_cldb(adev, &cldb);
|
|
|
+ if (ret || cldb.control_logic_type != 1)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+@@ -444,10 +449,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
|
|
|
+ ret = -ENODEV;
|
|
|
+ goto err_free_int3472;
|
|
|
+ }
|
|
|
+- int3472->sensor_name = i2c_acpi_dev_name(int3472->sensor);
|
|
|
++ int3472->sensor_name = kasprintf(GFP_KERNEL, I2C_DEV_NAME_FORMAT, acpi_dev_name(int3472->sensor));
|
|
|
+ int3472->gpios.dev_id = int3472->sensor_name;
|
|
|
+
|
|
|
+- ret = int3472_parse_crs(int3472);
|
|
|
++ ret = skl_int3472_parse_crs(int3472);
|
|
|
+ if (ret) {
|
|
|
+ skl_int3472_discrete_remove(pdev);
|
|
|
+ goto err_return_ret;
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_tps68470.c b/drivers/platform/x86/intel_skl_int3472_tps68470.c
|
|
|
+index 3fe27ec0caff..40629291b339 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_tps68470.c
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_tps68470.c
|
|
|
+@@ -87,20 +87,20 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Check CLDB buffer against the PMIC's adev. If present, then we check
|
|
|
+- * the value of control_logic_type field and follow one of the following
|
|
|
+- * scenarios:
|
|
|
++ * the value of control_logic_type field and follow one of the
|
|
|
++ * following scenarios:
|
|
|
+ *
|
|
|
+- * 1. No CLDB - likely ACPI tables designed for ChromeOS. We create
|
|
|
+- * platform devices for the GPIOs and OpRegion drivers.
|
|
|
++ * 1. No CLDB - likely ACPI tables designed for ChromeOS. We
|
|
|
++ * create platform devices for the GPIOs and OpRegion drivers.
|
|
|
+ *
|
|
|
+- * 2. CLDB, with control_logic_type = 2 - probably ACPI tables made
|
|
|
+- * for Windows 2-in-1 platforms. Register pdevs for GPIO, Clock and
|
|
|
+- * Regulator drivers to bind to.
|
|
|
++ * 2. CLDB, with control_logic_type = 2 - probably ACPI tables
|
|
|
++ * made for Windows 2-in-1 platforms. Register pdevs for GPIO,
|
|
|
++ * Clock and Regulator drivers to bind to.
|
|
|
+ *
|
|
|
+ * 3. Any other value in control_logic_type, we should never have
|
|
|
+ * gotten to this point; crash and burn.
|
|
|
+ */
|
|
|
+- ret = skl_int3472_get_cldb_buffer(adev, &cldb);
|
|
|
++ ret = skl_int3472_fill_cldb(adev, &cldb);
|
|
|
+ if (!ret && cldb.control_logic_type != 2)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From e3cde392d3facfbf24232e866f644db25c012f5b Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 23 Jan 2021 00:30:15 +0000
|
|
|
+Subject: [PATCH] platform: x86: Add recalc_rate opp to int3472-discrete clock
|
|
|
+
|
|
|
+This commit adds the recalc_rate opp to the clock registered by
|
|
|
+int3472-discrete so that sensor drivers calling clk_get_rate() will get a
|
|
|
+valid value returned.
|
|
|
+
|
|
|
+The value is simply read from the sensor's SSDB buffer, and so we pass
|
|
|
+CLK_GET_RATE_NOCACHE
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ .../platform/x86/intel_skl_int3472_common.h | 6 +++
|
|
|
+ .../platform/x86/intel_skl_int3472_discrete.c | 37 ++++++++++++++++++-
|
|
|
+ 2 files changed, 41 insertions(+), 2 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_common.h b/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
+index e1083bb67dc6..860c849b7769 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_common.h
|
|
|
+@@ -17,6 +17,8 @@
|
|
|
+ #define GPIO_REGULATOR_NAME_LENGTH 27
|
|
|
+ #define GPIO_REGULATOR_SUPPLY_NAME_LENGTH 9
|
|
|
+
|
|
|
++#define CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET 86
|
|
|
++
|
|
|
+ #define INT3472_REGULATOR(_NAME, _SUPPLY, _OPS) \
|
|
|
+ (const struct regulator_desc) { \
|
|
|
+ .name = _NAME, \
|
|
|
+@@ -36,6 +38,9 @@
|
|
|
+ #define to_int3472_clk(hw) \
|
|
|
+ container_of(hw, struct int3472_gpio_clock, clk_hw)
|
|
|
+
|
|
|
++#define to_int3472_device(clk) \
|
|
|
++ container_of(clk, struct int3472_device, clock)
|
|
|
++
|
|
|
+ struct int3472_cldb {
|
|
|
+ u8 version;
|
|
|
+ /*
|
|
|
+@@ -62,6 +67,7 @@ struct int3472_gpio_regulator {
|
|
|
+ struct int3472_gpio_clock {
|
|
|
+ struct clk *clk;
|
|
|
+ struct clk_hw clk_hw;
|
|
|
++ struct clk_lookup *cl;
|
|
|
+ struct gpio_desc *gpio;
|
|
|
+ };
|
|
|
+
|
|
|
+diff --git a/drivers/platform/x86/intel_skl_int3472_discrete.c b/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
+index 42ae8396eb64..98eb1ec3399e 100644
|
|
|
+--- a/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
++++ b/drivers/platform/x86/intel_skl_int3472_discrete.c
|
|
|
+@@ -86,11 +86,41 @@ static void skl_int3472_clk_unprepare(struct clk_hw *hw)
|
|
|
+ /* Likewise, nothing to do here... */
|
|
|
+ }
|
|
|
+
|
|
|
++static unsigned int skl_int3472_get_clk_frequency(struct int3472_device *int3472)
|
|
|
++{
|
|
|
++ union acpi_object *obj;
|
|
|
++ unsigned int ret = 0;
|
|
|
++
|
|
|
++ obj = skl_int3472_get_acpi_buffer(int3472->sensor, "SSDB");
|
|
|
++ if (IS_ERR(obj))
|
|
|
++ goto out_free_buff; /* report rate as 0 on error */
|
|
|
++
|
|
|
++ if (obj->buffer.length < CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET + sizeof(u32)) {
|
|
|
++ dev_err(&int3472->pdev->dev, "The buffer is too small\n");
|
|
|
++ goto out_free_buff;
|
|
|
++ }
|
|
|
++
|
|
|
++ ret = *(u32*)(obj->buffer.pointer + CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET);
|
|
|
++
|
|
|
++out_free_buff:
|
|
|
++ kfree(obj);
|
|
|
++ return ret;
|
|
|
++}
|
|
|
++
|
|
|
++static unsigned long skl_int3472_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
|
|
++{
|
|
|
++ struct int3472_gpio_clock *clk = to_int3472_clk(hw);
|
|
|
++ struct int3472_device *int3472 = to_int3472_device(clk);
|
|
|
++
|
|
|
++ return skl_int3472_get_clk_frequency(int3472);
|
|
|
++}
|
|
|
++
|
|
|
+ static const struct clk_ops skl_int3472_clock_ops = {
|
|
|
+ .prepare = skl_int3472_clk_prepare,
|
|
|
+ .unprepare = skl_int3472_clk_unprepare,
|
|
|
+ .enable = skl_int3472_clk_enable,
|
|
|
+ .disable = skl_int3472_clk_disable,
|
|
|
++ .recalc_rate = skl_int3472_clk_recalc_rate,
|
|
|
+ };
|
|
|
+
|
|
|
+ static struct int3472_sensor_config *
|
|
|
+@@ -196,6 +226,7 @@ static int skl_int3472_register_clock(struct int3472_device *int3472,
|
|
|
+ init.name = kasprintf(GFP_KERNEL, "%s-clk",
|
|
|
+ acpi_dev_name(int3472->adev));
|
|
|
+ init.ops = &skl_int3472_clock_ops;
|
|
|
++ init.flags |= CLK_GET_RATE_NOCACHE;
|
|
|
+
|
|
|
+ int3472->clock.gpio = acpi_get_gpiod(path,
|
|
|
+ ares->data.gpio.pin_table[0]);
|
|
|
+@@ -212,8 +243,9 @@ static int skl_int3472_register_clock(struct int3472_device *int3472,
|
|
|
+ goto err_put_gpio;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = clk_register_clkdev(int3472->clock.clk, "xvclk", int3472->sensor_name);
|
|
|
+- if (ret)
|
|
|
++ int3472->clock.cl = clkdev_create(int3472->clock.clk, "xvclk",
|
|
|
++ int3472->sensor_name);
|
|
|
++ if (IS_ERR_OR_NULL(int3472->clock.cl))
|
|
|
+ goto err_unregister_clk;
|
|
|
+
|
|
|
+ goto out_free_init_name;
|
|
|
+@@ -483,6 +515,7 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
|
|
|
+ if (!IS_ERR_OR_NULL(int3472->clock.clk)) {
|
|
|
+ gpiod_put(int3472->clock.gpio);
|
|
|
+ clk_unregister(int3472->clock.clk);
|
|
|
++ clkdev_drop(int3472->clock.cl);
|
|
|
+ }
|
|
|
+
|
|
|
+ acpi_dev_put(int3472->sensor);
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 1d1a0b5731f637597568a2e8cce2758e14b3c2ca Mon Sep 17 00:00:00 2001
|
|
|
+From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= <me@fabwu.ch>
|
|
|
+Date: Sun, 24 Jan 2021 11:07:42 +0100
|
|
|
+Subject: [PATCH] cio2-bridge: Use macros and add warnings
|
|
|
+MIME-Version: 1.0
|
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
|
+Content-Transfer-Encoding: 8bit
|
|
|
+
|
|
|
+Use macros for the _PLD panel as defined in the ACPI spec 6.3 and emit
|
|
|
+a warning if we see an unknown value.
|
|
|
+
|
|
|
+Signed-off-by: Fabian Wüthrich <me@fabwu.ch>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/pci/intel/ipu3/cio2-bridge.c | 33 ++++++++++++++++------
|
|
|
+ drivers/media/pci/intel/ipu3/cio2-bridge.h | 13 +++++++++
|
|
|
+ 2 files changed, 37 insertions(+), 9 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.c b/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
+index 806d4e5fc177..3c373ad1c0b0 100644
|
|
|
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.c
|
|
|
+@@ -73,21 +73,36 @@ static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static u32 cio2_bridge_parse_rotation(u8 rotation)
|
|
|
++static u32 cio2_bridge_parse_rotation(struct cio2_sensor *sensor)
|
|
|
+ {
|
|
|
+- if (rotation == 1)
|
|
|
++ switch (sensor->ssdb.degree) {
|
|
|
++ case CIO2_SENSOR_ROTATION_NORMAL:
|
|
|
++ return 0;
|
|
|
++ case CIO2_SENSOR_ROTATION_INVERTED:
|
|
|
+ return 180;
|
|
|
+- return 0;
|
|
|
++ default:
|
|
|
++ dev_warn(&sensor->adev->dev,
|
|
|
++ "Unknown rotation %d. Assume 0 degree rotation\n",
|
|
|
++ sensor->ssdb.degree);
|
|
|
++ return 0;
|
|
|
++ }
|
|
|
+ }
|
|
|
+
|
|
|
+-static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(u8 panel)
|
|
|
++static enum v4l2_fwnode_orientation cio2_bridge_parse_orientation(struct cio2_sensor *sensor)
|
|
|
+ {
|
|
|
+- switch (panel) {
|
|
|
+- case 4:
|
|
|
++ switch (sensor->pld->panel) {
|
|
|
++ case CIO2_PLD_PANEL_FRONT:
|
|
|
+ return V4L2_FWNODE_ORIENTATION_FRONT;
|
|
|
+- case 5:
|
|
|
++ case CIO2_PLD_PANEL_BACK:
|
|
|
+ return V4L2_FWNODE_ORIENTATION_BACK;
|
|
|
++ case CIO2_PLD_PANEL_TOP:
|
|
|
++ case CIO2_PLD_PANEL_LEFT:
|
|
|
++ case CIO2_PLD_PANEL_RIGHT:
|
|
|
++ case CIO2_PLD_PANEL_UNKNOWN:
|
|
|
++ return V4L2_FWNODE_ORIENTATION_EXTERNAL;
|
|
|
+ default:
|
|
|
++ dev_warn(&sensor->adev->dev, "Unknown _PLD panel value %d\n",
|
|
|
++ sensor->pld->panel);
|
|
|
+ return V4L2_FWNODE_ORIENTATION_EXTERNAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -100,8 +115,8 @@ static void cio2_bridge_create_fwnode_properties(
|
|
|
+ u32 rotation;
|
|
|
+ enum v4l2_fwnode_orientation orientation;
|
|
|
+
|
|
|
+- rotation = cio2_bridge_parse_rotation(sensor->ssdb.degree);
|
|
|
+- orientation = cio2_bridge_parse_orientation(sensor->pld->panel);
|
|
|
++ rotation = cio2_bridge_parse_rotation(sensor);
|
|
|
++ orientation = cio2_bridge_parse_orientation(sensor);
|
|
|
+
|
|
|
+ sensor->prop_names = prop_names;
|
|
|
+
|
|
|
+diff --git a/drivers/media/pci/intel/ipu3/cio2-bridge.h b/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
+index 924d99d20328..e1e388cc9f45 100644
|
|
|
+--- a/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
++++ b/drivers/media/pci/intel/ipu3/cio2-bridge.h
|
|
|
+@@ -12,6 +12,19 @@
|
|
|
+ #define CIO2_MAX_LANES 4
|
|
|
+ #define MAX_NUM_LINK_FREQS 3
|
|
|
+
|
|
|
++/* Values are estimated guesses as we don't have a spec */
|
|
|
++#define CIO2_SENSOR_ROTATION_NORMAL 0
|
|
|
++#define CIO2_SENSOR_ROTATION_INVERTED 1
|
|
|
++
|
|
|
++/* Panel position defined in _PLD section of ACPI Specification 6.3 */
|
|
|
++#define CIO2_PLD_PANEL_TOP 0
|
|
|
++#define CIO2_PLD_PANEL_BOTTOM 1
|
|
|
++#define CIO2_PLD_PANEL_LEFT 2
|
|
|
++#define CIO2_PLD_PANEL_RIGHT 3
|
|
|
++#define CIO2_PLD_PANEL_FRONT 4
|
|
|
++#define CIO2_PLD_PANEL_BACK 5
|
|
|
++#define CIO2_PLD_PANEL_UNKNOWN 6
|
|
|
++
|
|
|
+ #define CIO2_SENSOR_CONFIG(_HID, _NR, ...) \
|
|
|
+ (const struct cio2_sensor_config) { \
|
|
|
+ .hid = _HID, \
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From b070306c3889044cba1bd72c52cc818b642003a5 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Mon, 8 Feb 2021 21:44:38 +0000
|
|
|
+Subject: [PATCH] media: i2c: Tidy up ov5693_init_controls()
|
|
|
+
|
|
|
+The ov5693 driver initialises a bunch of v4l2 controls and throws away
|
|
|
+the pointers. This seems weird, let's not do that.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 46 ++++++++++++++++++++++----------------
|
|
|
+ drivers/media/i2c/ov5693.h | 12 +++++++++-
|
|
|
+ 2 files changed, 38 insertions(+), 20 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 1a85800df7ed..a9747ab783d7 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1610,7 +1610,6 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
|
|
|
+ const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
|
|
|
+ struct v4l2_fwnode_device_properties props;
|
|
|
+- struct v4l2_ctrl *ctrl;
|
|
|
+ unsigned int i;
|
|
|
+ int ret;
|
|
|
+ int hblank;
|
|
|
+@@ -1628,15 +1627,17 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ NULL);
|
|
|
+
|
|
|
+ /* link freq */
|
|
|
+- ctrl = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler, NULL,
|
|
|
+- V4L2_CID_LINK_FREQ,
|
|
|
+- 0, 0, link_freq_menu_items);
|
|
|
+- if (ctrl)
|
|
|
+- ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
++ ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler,
|
|
|
++ NULL, V4L2_CID_LINK_FREQ,
|
|
|
++ 0, 0, link_freq_menu_items);
|
|
|
++ if (ov5693->ctrls.link_freq)
|
|
|
++ ov5693->ctrls.link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
+
|
|
|
+ /* pixel rate */
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
|
|
|
+- 0, OV5693_PIXEL_RATE, 1, OV5693_PIXEL_RATE);
|
|
|
++ ov5693->ctrls.pixel_rate = v4l2_ctrl_new_std(&ov5693->ctrl_handler, NULL,
|
|
|
++ V4L2_CID_PIXEL_RATE, 0,
|
|
|
++ OV5693_PIXEL_RATE, 1,
|
|
|
++ OV5693_PIXEL_RATE);
|
|
|
+
|
|
|
+ if (ov5693->ctrl_handler.error) {
|
|
|
+ ov5693_remove(client);
|
|
|
+@@ -1645,25 +1646,32 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+
|
|
|
+ /* Exposure */
|
|
|
+
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
|
|
|
+- 512);
|
|
|
++ ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_EXPOSURE, 16,
|
|
|
++ 1048575, 16, 512);
|
|
|
+
|
|
|
+ /* Gain */
|
|
|
+
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_ANALOGUE_GAIN, 1, 1023, 1, 128);
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_DIGITAL_GAIN, 1, 3999, 1, 1000);
|
|
|
++ ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler,
|
|
|
++ ops, V4L2_CID_ANALOGUE_GAIN,
|
|
|
++ 1, 1023, 1, 128);
|
|
|
++ ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_DIGITAL_GAIN, 1,
|
|
|
++ 3999, 1, 1000);
|
|
|
+
|
|
|
+ /* Flip */
|
|
|
+
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
|
|
|
+- v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
|
|
|
++ ov5693->ctrls.hflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
|
|
|
++ ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
|
|
|
+
|
|
|
+ hblank = OV5693_PPL_DEFAULT - ov5693->mode->width;
|
|
|
+- ov5693->hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
+- V4L2_CID_HBLANK, hblank, hblank,
|
|
|
+- 1, hblank);
|
|
|
+- if (ov5693->hblank)
|
|
|
+- ov5693->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
++ ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_HBLANK, hblank, hblank,
|
|
|
++ 1, hblank);
|
|
|
++ if (ov5693->ctrls.hblank)
|
|
|
++ ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
+
|
|
|
+ /* set properties from fwnode (e.g. rotation, orientation) */
|
|
|
+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 9a508e1f3624..26819cf3f4d2 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -270,7 +270,17 @@ struct ov5693_device {
|
|
|
+
|
|
|
+ bool has_vcm;
|
|
|
+
|
|
|
+- struct v4l2_ctrl *hblank;
|
|
|
++ struct ov5693_v4l2_ctrls {
|
|
|
++ struct v4l2_ctrl *link_freq;
|
|
|
++ struct v4l2_ctrl *pixel_rate;
|
|
|
++ struct v4l2_ctrl *exposure;
|
|
|
++ struct v4l2_ctrl *analogue_gain;
|
|
|
++ struct v4l2_ctrl *digital_gain;
|
|
|
++ struct v4l2_ctrl *hflip;
|
|
|
++ struct v4l2_ctrl *vflip;
|
|
|
++ struct v4l2_ctrl *hblank;
|
|
|
++ } ctrls;
|
|
|
++
|
|
|
+ };
|
|
|
+
|
|
|
+ enum ov5693_tok_type {
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 77dd02990795cbc0eeb69d29a234ecef694612b9 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Mon, 8 Feb 2021 21:46:49 +0000
|
|
|
+Subject: [PATCH] media: i2c: Remove OV5693_PPL_DEFAULT
|
|
|
+
|
|
|
+No need for this macro, the PPL setting is against the mode structs.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 4 +---
|
|
|
+ 1 file changed, 1 insertion(+), 3 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index a9747ab783d7..7fb368eec327 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -105,8 +105,6 @@ MODULE_PARM_DESC(up_delay,
|
|
|
+ #define OV5693_PIXEL_ARRAY_WIDTH 2592U
|
|
|
+ #define OV5693_PIXEL_ARRAY_HEIGHT 1944U
|
|
|
+
|
|
|
+-#define OV5693_PPL_DEFAULT 2800
|
|
|
+-
|
|
|
+ static int vcm_ad_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
|
|
|
+ {
|
|
|
+ int err;
|
|
|
+@@ -1666,7 +1664,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ ov5693->ctrls.vflip = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
|
|
|
+
|
|
|
+- hblank = OV5693_PPL_DEFAULT - ov5693->mode->width;
|
|
|
++ hblank = ov5693->mode->pixels_per_line - ov5693->mode->width;
|
|
|
+ ov5693->ctrls.hblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
+ V4L2_CID_HBLANK, hblank, hblank,
|
|
|
+ 1, hblank);
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 9c063797defadfe3580002f79d5503c4a697d1a4 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Mon, 8 Feb 2021 22:53:02 +0000
|
|
|
+Subject: [PATCH] media: i2c: Add vblank control to ov5693 driver
|
|
|
+
|
|
|
+The latest libcamera requires a V4L2_CID_VBLANK control in each sensor
|
|
|
+driver; add a skeleton one to the ov5693 to fulfill the requirement.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 12 ++++++++++++
|
|
|
+ drivers/media/i2c/ov5693.h | 3 +++
|
|
|
+ 2 files changed, 15 insertions(+)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 7fb368eec327..1950d7ac2d54 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -946,6 +946,10 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ return ov5693_flip_horz_configure(dev, !!ctrl->val);
|
|
|
+ case V4L2_CID_VFLIP:
|
|
|
+ return ov5693_flip_vert_configure(dev, !!ctrl->val);
|
|
|
++ case V4L2_CID_VBLANK:
|
|
|
++ ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
|
|
|
++ dev->mode->height + ctrl->val);
|
|
|
++ break;
|
|
|
+ default:
|
|
|
+ ret = -EINVAL;
|
|
|
+ }
|
|
|
+@@ -1611,6 +1615,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ unsigned int i;
|
|
|
+ int ret;
|
|
|
+ int hblank;
|
|
|
++ int vblank_max, vblank_min, vblank_def;
|
|
|
+
|
|
|
+ ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
|
|
|
+ ARRAY_SIZE(ov5693_controls));
|
|
|
+@@ -1671,6 +1676,13 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ if (ov5693->ctrls.hblank)
|
|
|
+ ov5693->ctrls.hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
|
+
|
|
|
++ vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode->height;
|
|
|
++ vblank_def = ov5693->mode->lines_per_frame - ov5693->mode->height;
|
|
|
++ vblank_min = ov5693->mode->lines_per_frame - ov5693->mode->height;
|
|
|
++ ov5693->ctrls.vblank = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
++ V4L2_CID_VBLANK, vblank_min,
|
|
|
++ vblank_max, 1, vblank_def);
|
|
|
++
|
|
|
+ /* set properties from fwnode (e.g. rotation, orientation) */
|
|
|
+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
|
|
+ if (ret)
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 26819cf3f4d2..9d7eed97963b 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -131,6 +131,8 @@
|
|
|
+ /*High 8-bit, and low 8-bit HTS address is 0x380f*/
|
|
|
+ #define OV5693_TIMING_VTS_L 0x380f
|
|
|
+
|
|
|
++#define OV5693_TIMING_MAX_VTS 0xffff
|
|
|
++
|
|
|
+ #define OV5693_MWB_RED_GAIN_H 0x3400
|
|
|
+ #define OV5693_MWB_GREEN_GAIN_H 0x3402
|
|
|
+ #define OV5693_MWB_BLUE_GAIN_H 0x3404
|
|
|
+@@ -279,6 +281,7 @@ struct ov5693_device {
|
|
|
+ struct v4l2_ctrl *hflip;
|
|
|
+ struct v4l2_ctrl *vflip;
|
|
|
+ struct v4l2_ctrl *hblank;
|
|
|
++ struct v4l2_ctrl *vblank;
|
|
|
+ } ctrls;
|
|
|
+
|
|
|
+ };
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From b32056993cea983468fc25d3e64e06e37f4c40a6 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Wed, 10 Feb 2021 00:36:32 +0000
|
|
|
+Subject: [PATCH] media: i2c: update exposure control for ov5693
|
|
|
+
|
|
|
+The exposure control for ov5693 currently is in units of 1/16th of a line,
|
|
|
+but I think the framework expects it in units of lines. Set the control to
|
|
|
+work in lines and simply apply the multiplication when configuring the chip
|
|
|
+registers instead.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 23 ++++++++++++++++++++---
|
|
|
+ 1 file changed, 20 insertions(+), 3 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 1950d7ac2d54..cea767230aa9 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -801,6 +801,12 @@ static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
++ /*
|
|
|
++ * The control for exposure seems to be in units of lines, but the chip
|
|
|
++ * datasheet specifies exposure is in units of 1/16th of a line.
|
|
|
++ */
|
|
|
++ exposure = exposure * 16;
|
|
|
++
|
|
|
+ ov5693_get_exposure(sensor);
|
|
|
+ ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
|
|
|
+@@ -910,6 +916,16 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
++ /* If VBLANK is altered we need to update exposure to compensate */
|
|
|
++ if (ctrl->id == V4L2_CID_VBLANK) {
|
|
|
++ int exposure_max;
|
|
|
++ exposure_max = dev->mode->lines_per_frame - 8;
|
|
|
++ __v4l2_ctrl_modify_range(dev->ctrls.exposure, dev->ctrls.exposure->minimum,
|
|
|
++ exposure_max, dev->ctrls.exposure->step,
|
|
|
++ dev->ctrls.exposure->val < exposure_max ?
|
|
|
++ dev->ctrls.exposure->val : exposure_max);
|
|
|
++ }
|
|
|
++
|
|
|
+ switch (ctrl->id) {
|
|
|
+ case V4L2_CID_FOCUS_ABSOLUTE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
|
|
|
+@@ -1616,6 +1632,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ int ret;
|
|
|
+ int hblank;
|
|
|
+ int vblank_max, vblank_min, vblank_def;
|
|
|
++ int exposure_max;
|
|
|
+
|
|
|
+ ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
|
|
|
+ ARRAY_SIZE(ov5693_controls));
|
|
|
+@@ -1648,10 +1665,10 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Exposure */
|
|
|
+-
|
|
|
++ exposure_max = ov5693->mode->lines_per_frame - 8;
|
|
|
+ ov5693->ctrls.exposure = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
+- V4L2_CID_EXPOSURE, 16,
|
|
|
+- 1048575, 16, 512);
|
|
|
++ V4L2_CID_EXPOSURE, 1,
|
|
|
++ exposure_max, 1, 123);
|
|
|
+
|
|
|
+ /* Gain */
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 6233e6bbe8f499ba8b4c31f9df53daa1d221d303 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Wed, 10 Feb 2021 00:39:42 +0000
|
|
|
+Subject: [PATCH] media: i2c: Fix incorrect bit-setting
|
|
|
+
|
|
|
+The bitmask macros to set the exposure for the ov5693 are not quite right.
|
|
|
+Update them so that they're setting the correct bits in the registers.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 6 +++---
|
|
|
+ 1 file changed, 3 insertions(+), 3 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index cea767230aa9..f681dbfcec56 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -63,11 +63,11 @@ MODULE_PARM_DESC(up_delay,
|
|
|
+ /* Exposure/gain */
|
|
|
+
|
|
|
+ #define OV5693_EXPOSURE_CTRL_HH_REG 0x3500
|
|
|
+-#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(18, 16)) >> 16)
|
|
|
++#define OV5693_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(14, 12)) >> 12)
|
|
|
+ #define OV5693_EXPOSURE_CTRL_H_REG 0x3501
|
|
|
+-#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
|
|
|
++#define OV5693_EXPOSURE_CTRL_H(v) (((v) & GENMASK(11, 4)) >> 4)
|
|
|
+ #define OV5693_EXPOSURE_CTRL_L_REG 0x3502
|
|
|
+-#define OV5693_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
|
|
|
++#define OV5693_EXPOSURE_CTRL_L(v) (((v) & GENMASK(3, 0)) << 4)
|
|
|
+ #define OV5693_EXPOSURE_GAIN_MANUAL_REG 0x3509
|
|
|
+
|
|
|
+ #define OV5693_GAIN_CTRL_H_REG 0x3504
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From c8f37984c1cddea585f2acf6c71b878a92d451d4 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Wed, 10 Feb 2021 16:25:48 +0000
|
|
|
+Subject: [PATCH] media: i2c: Don't set stream on during mode config
|
|
|
+
|
|
|
+Currently the register lists for the ov5693 include setting stream on.
|
|
|
+That register shouldn't be set until the control is called, so remove
|
|
|
+this setting from all of the modes.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.h | 16 ----------------
|
|
|
+ 1 file changed, 16 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 9d7eed97963b..965208078c2b 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -581,7 +581,6 @@ static struct ov5693_reg const ov5693_654x496[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -626,7 +625,6 @@ static struct ov5693_reg const ov5693_1296x976[] = {
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+ {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+
|
|
|
+ };
|
|
|
+@@ -656,7 +654,6 @@ static struct ov5693_reg const ov5693_336x256[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -683,7 +680,6 @@ static struct ov5693_reg const ov5693_368x304[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -715,7 +711,6 @@ static struct ov5693_reg const ov5693_192x160[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -742,7 +737,6 @@ static struct ov5693_reg const ov5693_736x496[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+@@ -771,7 +765,6 @@ static struct ov5693_reg const ov5693_736x496[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x01},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+ */
|
|
|
+@@ -802,7 +795,6 @@ static struct ov5693_reg const ov5693_976x556[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -841,7 +833,6 @@ static struct ov5693_reg const ov5693_1296x736[] = {
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+ {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -868,7 +859,6 @@ static struct ov5693_reg const ov5693_1636p_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+@@ -904,7 +894,6 @@ static struct ov5693_reg const ov5693_1616x1216_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+ {OV5693_8BIT, 0x5041, 0x84},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -935,7 +924,6 @@ static struct ov5693_reg const ov5693_1940x1096[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -1029,7 +1017,6 @@ static struct ov5693_reg const ov5693_2592x1944_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+@@ -1073,7 +1060,6 @@ static struct ov5693_reg const ov5693_1424x1168_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+ {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+@@ -1114,7 +1100,6 @@ static struct ov5693_reg const ov5693_736x496_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+ {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -1141,7 +1126,6 @@ static struct ov5693_reg const ov5693_2576x1936_30fps[] = {
|
|
|
+ {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+ {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+ {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_8BIT, 0x0100, 0x01},
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 0249d4e96dc77cedc82269d535ccb68a0ce3fc40 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Wed, 10 Feb 2021 16:35:24 +0000
|
|
|
+Subject: [PATCH] media: i2c: Update gain control for ov5693
|
|
|
+
|
|
|
+The gain control of the ov5693 driver is setting the wrong bits and
|
|
|
+defining an invalid maximum value; change (and use) the bitshifting
|
|
|
+macros and update the control's ranges.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 18 +++++++++++-------
|
|
|
+ 1 file changed, 11 insertions(+), 7 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index f681dbfcec56..51eb3b05d121 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -71,9 +71,9 @@ MODULE_PARM_DESC(up_delay,
|
|
|
+ #define OV5693_EXPOSURE_GAIN_MANUAL_REG 0x3509
|
|
|
+
|
|
|
+ #define OV5693_GAIN_CTRL_H_REG 0x3504
|
|
|
+-#define OV5693_GAIN_CTRL_H(v) (((v) & GENMASK(9, 8)) >> 8)
|
|
|
++#define OV5693_GAIN_CTRL_H(v) ((v >> 4) & GENMASK(2, 0))
|
|
|
+ #define OV5693_GAIN_CTRL_L_REG 0x3505
|
|
|
+-#define OV5693_GAIN_CTRL_L(v) ((v) & GENMASK(7, 0))
|
|
|
++#define OV5693_GAIN_CTRL_L(v) ((v << 4) & GENMASK(7, 4))
|
|
|
+
|
|
|
+ #define OV5693_FORMAT1_REG 0x3820
|
|
|
+ #define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
|
|
|
+@@ -889,9 +889,13 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- /* Analog gain */
|
|
|
++ /*
|
|
|
++ * As with exposure, the lowest 4 bits are fractional bits. Setting
|
|
|
++ * those is not supported, so we have a tiny bit of bit shifting to
|
|
|
++ * do.
|
|
|
++ */
|
|
|
+ ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+- OV5693_AGC_L, gain & 0xff);
|
|
|
++ OV5693_AGC_L, OV5693_GAIN_CTRL_L(gain));
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_AGC_L);
|
|
|
+@@ -899,7 +903,7 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+- OV5693_AGC_H, (gain >> 8) & 0xff);
|
|
|
++ OV5693_AGC_H, OV5693_GAIN_CTRL_H(gain));
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_AGC_H);
|
|
|
+@@ -1674,10 +1678,10 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+
|
|
|
+ ov5693->ctrls.analogue_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler,
|
|
|
+ ops, V4L2_CID_ANALOGUE_GAIN,
|
|
|
+- 1, 1023, 1, 128);
|
|
|
++ 1, 127, 1, 8);
|
|
|
+ ov5693->ctrls.digital_gain = v4l2_ctrl_new_std(&ov5693->ctrl_handler, ops,
|
|
|
+ V4L2_CID_DIGITAL_GAIN, 1,
|
|
|
+- 3999, 1, 1000);
|
|
|
++ 4095, 1, 1024);
|
|
|
+
|
|
|
+ /* Flip */
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 4655f5f33e843e03296049fc6efa10f4310eceb3 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Wed, 10 Feb 2021 23:44:39 +0000
|
|
|
+Subject: [PATCH] media: i2c: Fixup gain read
|
|
|
+
|
|
|
+This function reads the bits from the gain registers poorly. Update
|
|
|
+it to do that properly (although, it probably just needs to be deleted)
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 17 +++++++++++------
|
|
|
+ 1 file changed, 11 insertions(+), 6 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 51eb3b05d121..952558c4f33b 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -770,30 +770,35 @@ static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
|
|
|
+
|
|
|
+ static int ov5693_get_exposure(struct ov5693_device *sensor)
|
|
|
+ {
|
|
|
+- u16 reg_v, reg_v2;
|
|
|
++ u32 exposure = 0;
|
|
|
++ u16 tmp;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ /* get exposure */
|
|
|
+ ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_L,
|
|
|
+- ®_v);
|
|
|
++ &tmp);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
++ exposure |= ((tmp >> 4) & 0b1111);
|
|
|
++
|
|
|
+ ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_M,
|
|
|
+- ®_v2);
|
|
|
++ &tmp);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+- reg_v += reg_v2 << 8;
|
|
|
++ exposure |= (tmp << 4);
|
|
|
+ ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_H,
|
|
|
+- ®_v2);
|
|
|
++ &tmp);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+- printk("exposure set to: %u\n", reg_v + (((u32)reg_v2 << 16)));
|
|
|
++ exposure |= (tmp << 12);
|
|
|
++
|
|
|
++ printk("exposure set to: %u\n", exposure);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 8ac23f62d38472adff45eae9c562023b5289cb53 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Thu, 11 Feb 2021 00:40:10 +0000
|
|
|
+Subject: [PATCH] media: i2c: Update controls on stream
|
|
|
+
|
|
|
+Currently the ov5693 driver throws away control setting by simply loading
|
|
|
+each mode's default registers. Instead, re-set the user defined controls
|
|
|
+during stream with __v4l2_ctrl_handler_setup()
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 6 ++++++
|
|
|
+ 1 file changed, 6 insertions(+)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 952558c4f33b..dd31083eeb7b 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1492,6 +1492,12 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
++ ret = __v4l2_ctrl_handler_setup(&dev->ctrl_handler);
|
|
|
++ if (ret) {
|
|
|
++ power_down(sd);
|
|
|
++ return ret;
|
|
|
++ }
|
|
|
++
|
|
|
+ ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
|
|
|
+ enable ? OV5693_START_STREAMING :
|
|
|
+ OV5693_STOP_STREAMING);
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 7e8aa95e23d65abe33ca4d80f50fcf47a96ee313 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Thu, 11 Feb 2021 23:29:15 +0000
|
|
|
+Subject: [PATCH] media: i2c: Correct link frequency value
|
|
|
+
|
|
|
+The link frequency is given by vts * hts * fps * bits / lanes / 2. In the
|
|
|
+case of the ov5693 driver that works out to 400MHz, not 640Mhz. Correct
|
|
|
+the macro.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.h | 6 +++---
|
|
|
+ 1 file changed, 3 insertions(+), 3 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 965208078c2b..7f1d31a82d3d 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -186,13 +186,13 @@
|
|
|
+ #define OV5693_OTP_MODE_READ 1
|
|
|
+
|
|
|
+ /* link freq and pixel rate required for IPU3 */
|
|
|
+-#define OV5693_LINK_FREQ_640MHZ 640000000
|
|
|
++#define OV5693_LINK_FREQ_400MHZ 400000000
|
|
|
+ /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
|
|
|
+ * To avoid integer overflow, dividing by bits_per_sample first.
|
|
|
+ */
|
|
|
+-#define OV5693_PIXEL_RATE (OV5693_LINK_FREQ_640MHZ / 10) * 2 * 2
|
|
|
++#define OV5693_PIXEL_RATE (OV5693_LINK_FREQ_400MHZ / 10) * 2 * 2
|
|
|
+ static const s64 link_freq_menu_items[] = {
|
|
|
+- OV5693_LINK_FREQ_640MHZ
|
|
|
++ OV5693_LINK_FREQ_400MHZ
|
|
|
+ };
|
|
|
+
|
|
|
+ #define OV5693_NUM_SUPPLIES 2
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 061cbcd2070ab1907d0702ff358255514a1efc47 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Mon, 25 Jan 2021 23:12:09 +0000
|
|
|
+Subject: [PATCH] media: i2c: Cleanup ov5693 driver
|
|
|
+
|
|
|
+This commit performs some cleanup to the ov5693 driver:
|
|
|
+
|
|
|
+1. Superfluous words in variable names dropped; "i2c_client" becomes
|
|
|
+ "client", "input_lock" becomes "lock"
|
|
|
+2. ov5693_configure_gpios() is does error handling properly, and uses
|
|
|
+ gpiod_get_optional()
|
|
|
+3. The name of the struct ov5693_device variable in each functions, which
|
|
|
+ previously was a mix of dev, sensor or ov5693, is standardised to the
|
|
|
+ latter.
|
|
|
+4. The list of headers is alphabetised (and probably also needs trimming)
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 309 +++++++++++++++++++------------------
|
|
|
+ drivers/media/i2c/ov5693.h | 5 +-
|
|
|
+ 2 files changed, 165 insertions(+), 149 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index dd31083eeb7b..0643390c872a 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -16,25 +16,25 @@
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
++#include <linux/acpi.h>
|
|
|
+ #include <linux/clk.h>
|
|
|
+-#include <linux/module.h>
|
|
|
+-#include <linux/types.h>
|
|
|
+-#include <linux/kernel.h>
|
|
|
+-#include <linux/mm.h>
|
|
|
+-#include <linux/string.h>
|
|
|
++#include <linux/delay.h>
|
|
|
++#include <linux/device.h>
|
|
|
+ #include <linux/errno.h>
|
|
|
++#include <linux/i2c.h>
|
|
|
+ #include <linux/init.h>
|
|
|
++#include <linux/io.h>
|
|
|
++#include <linux/kernel.h>
|
|
|
+ #include <linux/kmod.h>
|
|
|
+-#include <linux/device.h>
|
|
|
+-#include <linux/delay.h>
|
|
|
+-#include <linux/slab.h>
|
|
|
+-#include <linux/i2c.h>
|
|
|
++#include <linux/module.h>
|
|
|
+ #include <linux/moduleparam.h>
|
|
|
++#include <linux/mm.h>
|
|
|
++#include <linux/regulator/consumer.h>
|
|
|
++#include <linux/slab.h>
|
|
|
++#include <linux/string.h>
|
|
|
++#include <linux/types.h>
|
|
|
+ #include <media/v4l2-device.h>
|
|
|
+ #include <media/v4l2-fwnode.h>
|
|
|
+-#include <linux/io.h>
|
|
|
+-#include <linux/acpi.h>
|
|
|
+-#include <linux/regulator/consumer.h>
|
|
|
+
|
|
|
+ #include "ov5693.h"
|
|
|
+ #include "ad5823.h"
|
|
|
+@@ -485,12 +485,12 @@ static int ov5693_read_otp_reg_array(struct i2c_client *client, u16 size,
|
|
|
+ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
|
|
|
+ {
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ int ret;
|
|
|
+ int i;
|
|
|
+ u8 *b = buf;
|
|
|
+
|
|
|
+- dev->otp_size = 0;
|
|
|
++ ov5693->otp_size = 0;
|
|
|
+ for (i = 1; i < OV5693_OTP_BANK_MAX; i++) {
|
|
|
+ /*set bank NO and OTP read mode. */
|
|
|
+ ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_OTP_BANK_REG,
|
|
|
+@@ -529,7 +529,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
|
|
|
+ //Intel OTP map, try to read 320byts first.
|
|
|
+ if (i == 21) {
|
|
|
+ if ((*b) == 0) {
|
|
|
+- dev->otp_size = 320;
|
|
|
++ ov5693->otp_size = 320;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* (*b) != 0 */
|
|
|
+@@ -538,7 +538,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
|
|
|
+ } else if (i ==
|
|
|
+ 24) { //if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
|
|
|
+ if ((*b) == 0) {
|
|
|
+- dev->otp_size = 32;
|
|
|
++ ov5693->otp_size = 32;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* (*b) != 0 */
|
|
|
+@@ -547,11 +547,11 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
|
|
|
+ } else if (i ==
|
|
|
+ 27) { //if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
|
|
|
+ if ((*b) == 0) {
|
|
|
+- dev->otp_size = 32;
|
|
|
++ ov5693->otp_size = 32;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* (*b) != 0 */
|
|
|
+- dev->otp_size = 0; // no OTP data.
|
|
|
++ ov5693->otp_size = 0; // no OTP data.
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -598,20 +598,20 @@ static void *ov5693_otp_read(struct v4l2_subdev *sd)
|
|
|
+ return buf;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int ov5693_update_bits(struct ov5693_device *sensor, u16 address,
|
|
|
++static int ov5693_update_bits(struct ov5693_device *ov5693, u16 address,
|
|
|
+ u16 mask, u16 bits)
|
|
|
+ {
|
|
|
+ u16 value = 0;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT, address, &value);
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT, address, &value);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ value &= ~mask;
|
|
|
+ value |= bits;
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT, address, value);
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT, address, value);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+@@ -620,13 +620,13 @@ static int ov5693_update_bits(struct ov5693_device *sensor, u16 address,
|
|
|
+
|
|
|
+ /* Flip */
|
|
|
+
|
|
|
+-static int ov5693_flip_vert_configure(struct ov5693_device *sensor, bool enable)
|
|
|
++static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, bool enable)
|
|
|
+ {
|
|
|
+ u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN |
|
|
|
+ OV5693_FORMAT1_FLIP_VERT_SENSOR_EN;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- ret = ov5693_update_bits(sensor, OV5693_FORMAT1_REG, bits,
|
|
|
++ ret = ov5693_update_bits(ov5693, OV5693_FORMAT1_REG, bits,
|
|
|
+ enable ? bits : 0);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+@@ -634,13 +634,13 @@ static int ov5693_flip_vert_configure(struct ov5693_device *sensor, bool enable)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int ov5693_flip_horz_configure(struct ov5693_device *sensor, bool enable)
|
|
|
++static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, bool enable)
|
|
|
+ {
|
|
|
+ u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN |
|
|
|
+ OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- ret = ov5693_update_bits(sensor, OV5693_FORMAT2_REG, bits,
|
|
|
++ ret = ov5693_update_bits(ov5693, OV5693_FORMAT2_REG, bits,
|
|
|
+ enable ? bits : 0);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+@@ -721,14 +721,14 @@ static int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+
|
|
|
+ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ dev_dbg(&client->dev, "%s: FOCUS_POS: 0x%x\n", __func__, value);
|
|
|
+ value = clamp(value, 0, OV5693_VCM_MAX_FOCUS_POS);
|
|
|
+- if (dev->vcm == VCM_DW9714) {
|
|
|
+- if (dev->vcm_update) {
|
|
|
++ if (ov5693->vcm == VCM_DW9714) {
|
|
|
++ if (ov5693->vcm_update) {
|
|
|
+ ret = vcm_dw_i2c_write(client, VCM_PROTECTION_OFF);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+@@ -738,17 +738,17 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+ ret = vcm_dw_i2c_write(client, VCM_PROTECTION_ON);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+- dev->vcm_update = false;
|
|
|
++ ov5693->vcm_update = false;
|
|
|
+ }
|
|
|
+ ret = vcm_dw_i2c_write(client,
|
|
|
+ vcm_val(value, VCM_DEFAULT_S));
|
|
|
+- } else if (dev->vcm == VCM_AD5823) {
|
|
|
++ } else if (ov5693->vcm == VCM_AD5823) {
|
|
|
+ ad5823_t_focus_abs(sd, value);
|
|
|
+ }
|
|
|
+ if (ret == 0) {
|
|
|
+- dev->number_of_steps = value - dev->focus;
|
|
|
+- dev->focus = value;
|
|
|
+- dev->timestamp_t_focus_abs = ktime_get();
|
|
|
++ ov5693->number_of_steps = value - ov5693->focus;
|
|
|
++ ov5693->focus = value;
|
|
|
++ ov5693->timestamp_t_focus_abs = ktime_get();
|
|
|
+ } else
|
|
|
+ dev_err(&client->dev,
|
|
|
+ "%s: i2c failed. ret %d\n", __func__, ret);
|
|
|
+@@ -758,9 +758,9 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+
|
|
|
+ static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+- return ov5693_t_focus_abs(sd, dev->focus + value);
|
|
|
++ return ov5693_t_focus_abs(sd, ov5693->focus + value);
|
|
|
+ }
|
|
|
+
|
|
|
+ #define DELAY_PER_STEP_NS 1000000
|
|
|
+@@ -768,14 +768,14 @@ static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
|
|
|
+
|
|
|
+ /* Exposure */
|
|
|
+
|
|
|
+-static int ov5693_get_exposure(struct ov5693_device *sensor)
|
|
|
++static int ov5693_get_exposure(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+ u32 exposure = 0;
|
|
|
+ u16 tmp;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ /* get exposure */
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_L,
|
|
|
+ &tmp);
|
|
|
+ if (ret)
|
|
|
+@@ -783,14 +783,14 @@ static int ov5693_get_exposure(struct ov5693_device *sensor)
|
|
|
+
|
|
|
+ exposure |= ((tmp >> 4) & 0b1111);
|
|
|
+
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_M,
|
|
|
+ &tmp);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ exposure |= (tmp << 4);
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_H,
|
|
|
+ &tmp);
|
|
|
+ if (ret)
|
|
|
+@@ -802,7 +802,7 @@ static int ov5693_get_exposure(struct ov5693_device *sensor)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
|
|
|
++static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+@@ -812,40 +812,40 @@ static int ov5693_exposure_configure(struct ov5693_device *sensor, u32 exposure)
|
|
|
+ */
|
|
|
+ exposure = exposure * 16;
|
|
|
+
|
|
|
+- ov5693_get_exposure(sensor);
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ov5693_get_exposure(ov5693);
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_CTRL_H_REG, OV5693_EXPOSURE_CTRL_H(exposure));
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_CTRL_L_REG, OV5693_EXPOSURE_CTRL_L(exposure));
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+- ov5693_get_exposure(sensor);
|
|
|
++ ov5693_get_exposure(ov5693);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Gain */
|
|
|
+
|
|
|
+-static int ov5693_get_gain(struct ov5693_device *sensor, u32 *gain)
|
|
|
++static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain)
|
|
|
+ {
|
|
|
+ u16 gain_l, gain_h;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_GAIN_CTRL_L_REG,
|
|
|
+ &gain_l);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+- ret = ov5693_read_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_GAIN_CTRL_H_REG,
|
|
|
+ &gain_h);
|
|
|
+ if (ret)
|
|
|
+@@ -856,33 +856,33 @@ static int ov5693_get_gain(struct ov5693_device *sensor, u32 *gain)
|
|
|
+
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+-static int ov5693_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
++static int ov5693_gain_configure(struct ov5693_device *ov5693, u32 gain)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* A 1.0 gain is 0x400 */
|
|
|
+ gain = (gain * 1024)/1000;
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
|
|
|
+ OV5693_MWB_RED_GAIN_H, gain);
|
|
|
+ if (ret) {
|
|
|
+- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
++ dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_MWB_RED_GAIN_H);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
|
|
|
+ OV5693_MWB_GREEN_GAIN_H, gain);
|
|
|
+ if (ret) {
|
|
|
+- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
++ dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_MWB_RED_GAIN_H);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_16BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_16BIT,
|
|
|
+ OV5693_MWB_BLUE_GAIN_H, gain);
|
|
|
+ if (ret) {
|
|
|
+- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
++ dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_MWB_RED_GAIN_H);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+@@ -890,7 +890,7 @@ static int ov5693_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
++static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+@@ -899,18 +899,18 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
+ * those is not supported, so we have a tiny bit of bit shifting to
|
|
|
+ * do.
|
|
|
+ */
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_AGC_L, OV5693_GAIN_CTRL_L(gain));
|
|
|
+ if (ret) {
|
|
|
+- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
++ dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_AGC_L);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_AGC_H, OV5693_GAIN_CTRL_H(gain));
|
|
|
+ if (ret) {
|
|
|
+- dev_err(&sensor->i2c_client->dev, "%s: write %x error, aborted\n",
|
|
|
++ dev_err(&ov5693->client->dev, "%s: write %x error, aborted\n",
|
|
|
+ __func__, OV5693_AGC_H);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+@@ -920,60 +920,60 @@ static int ov5693_analog_gain_configure(struct ov5693_device *sensor, u32 gain)
|
|
|
+
|
|
|
+ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev =
|
|
|
++ struct ov5693_device *ov5693 =
|
|
|
+ container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
|
|
|
++ struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ /* If VBLANK is altered we need to update exposure to compensate */
|
|
|
+ if (ctrl->id == V4L2_CID_VBLANK) {
|
|
|
+ int exposure_max;
|
|
|
+- exposure_max = dev->mode->lines_per_frame - 8;
|
|
|
+- __v4l2_ctrl_modify_range(dev->ctrls.exposure, dev->ctrls.exposure->minimum,
|
|
|
+- exposure_max, dev->ctrls.exposure->step,
|
|
|
+- dev->ctrls.exposure->val < exposure_max ?
|
|
|
+- dev->ctrls.exposure->val : exposure_max);
|
|
|
++ exposure_max = ov5693->mode->lines_per_frame - 8;
|
|
|
++ __v4l2_ctrl_modify_range(ov5693->ctrls.exposure, ov5693->ctrls.exposure->minimum,
|
|
|
++ exposure_max, ov5693->ctrls.exposure->step,
|
|
|
++ ov5693->ctrls.exposure->val < exposure_max ?
|
|
|
++ ov5693->ctrls.exposure->val : exposure_max);
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (ctrl->id) {
|
|
|
+ case V4L2_CID_FOCUS_ABSOLUTE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+- ret = ov5693_t_focus_abs(&dev->sd, ctrl->val);
|
|
|
++ ret = ov5693_t_focus_abs(&ov5693->sd, ctrl->val);
|
|
|
+ break;
|
|
|
+ case V4L2_CID_FOCUS_RELATIVE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_FOCUS_RELATIVE:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+- ret = ov5693_t_focus_rel(&dev->sd, ctrl->val);
|
|
|
++ ret = ov5693_t_focus_rel(&ov5693->sd, ctrl->val);
|
|
|
+ break;
|
|
|
+ case V4L2_CID_EXPOSURE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+- ret = ov5693_exposure_configure(dev, ctrl->val);
|
|
|
++ ret = ov5693_exposure_configure(ov5693, ctrl->val);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_ANALOGUE_GAIN:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_ANALOGUE_GAIN:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+- ret = ov5693_analog_gain_configure(dev, ctrl->val);
|
|
|
++ ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_DIGITAL_GAIN:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_DIGITAL_GAIN:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+- ret = ov5693_gain_configure(dev, ctrl->val);
|
|
|
++ ret = ov5693_gain_configure(ov5693, ctrl->val);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_HFLIP:
|
|
|
+- return ov5693_flip_horz_configure(dev, !!ctrl->val);
|
|
|
++ return ov5693_flip_horz_configure(ov5693, !!ctrl->val);
|
|
|
+ case V4L2_CID_VFLIP:
|
|
|
+- return ov5693_flip_vert_configure(dev, !!ctrl->val);
|
|
|
++ return ov5693_flip_vert_configure(ov5693, !!ctrl->val);
|
|
|
+ case V4L2_CID_VBLANK:
|
|
|
+ ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
|
|
|
+- dev->mode->height + ctrl->val);
|
|
|
++ ov5693->mode->height + ctrl->val);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ret = -EINVAL;
|
|
|
+@@ -983,16 +983,16 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+
|
|
|
+ static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev =
|
|
|
++ struct ov5693_device *ov5693 =
|
|
|
+ container_of(ctrl->handler, struct ov5693_device, ctrl_handler);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ switch (ctrl->id) {
|
|
|
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
|
|
|
+- ret = ov5693_q_exposure(&dev->sd, &ctrl->val);
|
|
|
++ ret = ov5693_q_exposure(&ov5693->sd, &ctrl->val);
|
|
|
+ break;
|
|
|
+ case V4L2_CID_AUTOGAIN:
|
|
|
+- ret = ov5693_get_gain(dev, &ctrl->val);
|
|
|
++ ret = ov5693_get_gain(ov5693, &ctrl->val);
|
|
|
+ break;
|
|
|
+ case V4L2_CID_FOCUS_ABSOLUTE:
|
|
|
+ /* NOTE: there was atomisp-specific function ov5693_q_focus_abs() */
|
|
|
+@@ -1034,12 +1034,12 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+-static int ov5693_isp_configure(struct ov5693_device *sensor)
|
|
|
++static int ov5693_isp_configure(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ /* Enable lens correction. */
|
|
|
+- ret = ov5693_write_reg(sensor->i2c_client, OV5693_8BIT,
|
|
|
++ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_ISP_CTRL0_REG, 0x86);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+@@ -1049,18 +1049,18 @@ static int ov5693_isp_configure(struct ov5693_device *sensor)
|
|
|
+
|
|
|
+ static int ov5693_init(struct v4l2_subdev *sd)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- if (!dev->has_vcm)
|
|
|
++ if (!ov5693->has_vcm)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ dev_info(&client->dev, "%s\n", __func__);
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
+- dev->vcm_update = false;
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
++ ov5693->vcm_update = false;
|
|
|
+
|
|
|
+- if (dev->vcm == VCM_AD5823) {
|
|
|
++ if (ov5693->vcm == VCM_AD5823) {
|
|
|
+ ret = vcm_ad_i2c_wr8(client, 0x01, 0x01); /* vcm init test */
|
|
|
+ if (ret)
|
|
|
+ dev_err(&client->dev,
|
|
|
+@@ -1079,16 +1079,16 @@ static int ov5693_init(struct v4l2_subdev *sd)
|
|
|
+ }
|
|
|
+
|
|
|
+ /*change initial focus value for ad5823*/
|
|
|
+- if (dev->vcm == VCM_AD5823) {
|
|
|
+- dev->focus = AD5823_INIT_FOCUS_POS;
|
|
|
++ if (ov5693->vcm == VCM_AD5823) {
|
|
|
++ ov5693->focus = AD5823_INIT_FOCUS_POS;
|
|
|
+ ov5693_t_focus_abs(sd, AD5823_INIT_FOCUS_POS);
|
|
|
+ } else {
|
|
|
+- dev->focus = 0;
|
|
|
++ ov5693->focus = 0;
|
|
|
+ ov5693_t_focus_abs(sd, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+- ov5693_isp_configure(dev);
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ ov5693_isp_configure(ov5693);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+@@ -1096,32 +1096,32 @@ static int ov5693_init(struct v4l2_subdev *sd)
|
|
|
+ static int __power_up(struct v4l2_subdev *sd)
|
|
|
+ {
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- struct ov5693_device *sensor = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- ret = clk_prepare_enable(sensor->clk);
|
|
|
++ ret = clk_prepare_enable(ov5693->clk);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "Error enabling clock\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (sensor->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(sensor->indicator_led, 1);
|
|
|
++ if (ov5693->indicator_led)
|
|
|
++ gpiod_set_value_cansleep(ov5693->indicator_led, 1);
|
|
|
+
|
|
|
+ ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES,
|
|
|
+- sensor->supplies);
|
|
|
++ ov5693->supplies);
|
|
|
+ if (ret)
|
|
|
+ goto fail_power;
|
|
|
+
|
|
|
+- gpiod_set_value_cansleep(sensor->reset, 0);
|
|
|
++ gpiod_set_value_cansleep(ov5693->reset, 0);
|
|
|
+
|
|
|
+ __cci_delay(up_delay);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ fail_power:
|
|
|
+- if (sensor->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(sensor->indicator_led, 0);
|
|
|
++ if (ov5693->indicator_led)
|
|
|
++ gpiod_set_value_cansleep(ov5693->indicator_led, 0);
|
|
|
+ dev_err(&client->dev, "sensor power-up failed\n");
|
|
|
+
|
|
|
+ return ret;
|
|
|
+@@ -1129,17 +1129,17 @@ static int __power_up(struct v4l2_subdev *sd)
|
|
|
+
|
|
|
+ static int power_down(struct v4l2_subdev *sd)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+- dev->focus = OV5693_INVALID_CONFIG;
|
|
|
++ ov5693->focus = OV5693_INVALID_CONFIG;
|
|
|
+
|
|
|
+- gpiod_set_value_cansleep(dev->reset, 1);
|
|
|
++ gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
+
|
|
|
+- clk_disable_unprepare(dev->clk);
|
|
|
++ clk_disable_unprepare(ov5693->clk);
|
|
|
+
|
|
|
+- if (dev->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(dev->indicator_led, 0);
|
|
|
+- return regulator_bulk_disable(OV5693_NUM_SUPPLIES, dev->supplies);
|
|
|
++ if (ov5693->indicator_led)
|
|
|
++ gpiod_set_value_cansleep(ov5693->indicator_led, 0);
|
|
|
++ return regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
|
|
|
+ }
|
|
|
+
|
|
|
+ static int power_up(struct v4l2_subdev *sd)
|
|
|
+@@ -1265,7 +1265,7 @@ static int get_resolution_index(int w, int h)
|
|
|
+ /* TODO: remove it. */
|
|
|
+ static int startup(struct v4l2_subdev *sd)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+@@ -1282,7 +1282,7 @@ static int startup(struct v4l2_subdev *sd)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = ov5693_write_reg_array(client, ov5693_res[dev->fmt_idx].regs);
|
|
|
++ ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
+ return ret;
|
|
|
+@@ -1296,7 +1296,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ struct v4l2_subdev_format *format)
|
|
|
+ {
|
|
|
+ struct v4l2_mbus_framefmt *fmt = &format->format;
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret = 0;
|
|
|
+ int idx;
|
|
|
+@@ -1307,7 +1307,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ if (!fmt)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
+ idx = nearest_resolution_index(fmt->width, fmt->height);
|
|
|
+ if (idx == -1) {
|
|
|
+ /* return the largest resolution */
|
|
|
+@@ -1325,8 +1325,8 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ goto mutex_unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+- dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
|
|
|
+- if (dev->fmt_idx == -1) {
|
|
|
++ ov5693->fmt_idx = get_resolution_index(fmt->width, fmt->height);
|
|
|
++ if (ov5693->fmt_idx == -1) {
|
|
|
+ dev_err(&client->dev, "get resolution fail\n");
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto mutex_unlock;
|
|
|
+@@ -1339,9 +1339,9 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+ ov5693_init(sd);
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
+ ret = startup(sd);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&client->dev, " startup() FAILED!\n");
|
|
|
+@@ -1353,8 +1353,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ goto mutex_unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+-
|
|
|
+-
|
|
|
+ /*
|
|
|
+ * After sensor settings are set to HW, sometimes stream is started.
|
|
|
+ * This would cause ISP timeout because ISP is not ready to receive
|
|
|
+@@ -1366,19 +1364,19 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ dev_warn(&client->dev, "ov5693 stream off err\n");
|
|
|
+
|
|
|
+ mutex_unlock:
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ static const struct v4l2_rect *
|
|
|
+-__ov5693_get_pad_crop(struct ov5693_device *dev, struct v4l2_subdev_pad_config *cfg,
|
|
|
++__ov5693_get_pad_crop(struct ov5693_device *ov5693, struct v4l2_subdev_pad_config *cfg,
|
|
|
+ unsigned int pad, enum v4l2_subdev_format_whence which)
|
|
|
+ {
|
|
|
+ switch (which) {
|
|
|
+ case V4L2_SUBDEV_FORMAT_TRY:
|
|
|
+- return v4l2_subdev_get_try_crop(&dev->sd, cfg, pad);
|
|
|
++ return v4l2_subdev_get_try_crop(&ov5693->sd, cfg, pad);
|
|
|
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
|
|
|
+- return &dev->mode->crop;
|
|
|
++ return &ov5693->mode->crop;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+@@ -1389,12 +1387,12 @@ static int ov5693_get_selection(struct v4l2_subdev *sd,
|
|
|
+ {
|
|
|
+ switch (sel->target) {
|
|
|
+ case V4L2_SEL_TGT_CROP: {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
+- sel->r = *__ov5693_get_pad_crop(dev, cfg, sel->pad,
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
++ sel->r = *__ov5693_get_pad_crop(ov5693, cfg, sel->pad,
|
|
|
+ sel->which);
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+@@ -1424,7 +1422,7 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
|
|
|
+ struct v4l2_subdev_format *format)
|
|
|
+ {
|
|
|
+ struct v4l2_mbus_framefmt *fmt = &format->format;
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+ if (format->pad)
|
|
|
+ return -EINVAL;
|
|
|
+@@ -1432,8 +1430,8 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
|
|
|
+ if (!fmt)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+- fmt->width = ov5693_res[dev->fmt_idx].width;
|
|
|
+- fmt->height = ov5693_res[dev->fmt_idx].height;
|
|
|
++ fmt->width = ov5693_res[ov5693->fmt_idx].width;
|
|
|
++ fmt->height = ov5693_res[ov5693->fmt_idx].height;
|
|
|
+ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+@@ -1481,7 +1479,7 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
++ mutex_lock(&dev->lock);
|
|
|
+
|
|
|
+ /* power_on() here before streaming for regular PCs. */
|
|
|
+ if (enable) {
|
|
|
+@@ -1507,26 +1505,26 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
|
|
|
+ power_down(sd);
|
|
|
+
|
|
|
+ out:
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&dev->lock);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+- mutex_lock(&dev->input_lock);
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
+ ret = power_up(sd);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "ov5693 power-up err.\n");
|
|
|
+ goto fail_power_on;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (!dev->vcm)
|
|
|
+- dev->vcm = vcm_detect(client);
|
|
|
++ if (!ov5693->vcm)
|
|
|
++ ov5693->vcm = vcm_detect(client);
|
|
|
+
|
|
|
+ /* config & detect sensor */
|
|
|
+ ret = ov5693_detect(client);
|
|
|
+@@ -1535,7 +1533,7 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ goto fail_power_on;
|
|
|
+ }
|
|
|
+
|
|
|
+- dev->otp_data = ov5693_otp_read(sd);
|
|
|
++ ov5693->otp_data = ov5693_otp_read(sd);
|
|
|
+
|
|
|
+ /* turn off sensor, after probed */
|
|
|
+ ret = power_down(sd);
|
|
|
+@@ -1543,24 +1541,24 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ dev_err(&client->dev, "ov5693 power-off err.\n");
|
|
|
+ goto fail_power_on;
|
|
|
+ }
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ fail_power_on:
|
|
|
+ power_down(sd);
|
|
|
+ dev_err(&client->dev, "sensor power-gating failed\n");
|
|
|
+- mutex_unlock(&dev->input_lock);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
|
|
|
+ struct v4l2_subdev_frame_interval *interval)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+ interval->interval.numerator = 1;
|
|
|
+- interval->interval.denominator = ov5693_res[dev->fmt_idx].fps;
|
|
|
++ interval->interval.denominator = ov5693_res[ov5693->fmt_idx].fps;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+@@ -1725,7 +1723,7 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* Use same lock for controls as for everything else. */
|
|
|
+- ov5693->ctrl_handler.lock = &ov5693->input_lock;
|
|
|
++ ov5693->ctrl_handler.lock = &ov5693->lock;
|
|
|
+ ov5693->sd.ctrl_handler = &ov5693->ctrl_handler;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+@@ -1733,21 +1731,38 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+
|
|
|
+ static int ov5693_configure_gpios(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+- ov5693->reset = gpiod_get_index(&ov5693->i2c_client->dev, "reset", 0,
|
|
|
++ int ret;
|
|
|
++
|
|
|
++ ov5693->reset = gpiod_get_optional(&ov5693->client->dev, "reset",
|
|
|
+ GPIOD_OUT_HIGH);
|
|
|
+ if (IS_ERR(ov5693->reset)) {
|
|
|
+- dev_err(&ov5693->i2c_client->dev, "Couldn't find reset GPIO\n");
|
|
|
+- return -EINVAL;
|
|
|
++ dev_err(&ov5693->client->dev, "Couldn't find reset GPIO\n");
|
|
|
++ return PTR_ERR(ov5693->reset);
|
|
|
++ }
|
|
|
++
|
|
|
++ ov5693->powerdown = gpiod_get_optional(&ov5693->client->dev, "powerdown",
|
|
|
++ GPIOD_OUT_HIGH);
|
|
|
++ if (IS_ERR(ov5693->powerdown)) {
|
|
|
++ dev_err(&ov5693->client->dev, "Couldn't find powerdown GPIO\n");
|
|
|
++ ret = PTR_ERR(ov5693->powerdown);
|
|
|
++ goto err_put_reset;
|
|
|
+ }
|
|
|
+
|
|
|
+- ov5693->indicator_led = gpiod_get_index_optional(&ov5693->i2c_client->dev, "indicator-led", 0,
|
|
|
++ ov5693->indicator_led = gpiod_get_optional(&ov5693->client->dev, "indicator-led",
|
|
|
+ GPIOD_OUT_HIGH);
|
|
|
+ if (IS_ERR(ov5693->indicator_led)) {
|
|
|
+- dev_err(&ov5693->i2c_client->dev, "Couldn't find indicator-led GPIO\n");
|
|
|
+- return -EINVAL;
|
|
|
++ dev_err(&ov5693->client->dev, "Couldn't find indicator-led GPIO\n");
|
|
|
++ ret = PTR_ERR(ov5693->indicator_led);
|
|
|
++ goto err_put_powerdown;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
++err_put_reset:
|
|
|
++ gpiod_put(ov5693->reset);
|
|
|
++err_put_powerdown:
|
|
|
++ gpiod_put(ov5693->powerdown);
|
|
|
++
|
|
|
++ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ static int ov5693_get_regulators(struct ov5693_device *ov5693)
|
|
|
+@@ -1757,7 +1772,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
|
|
|
+ for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
|
|
|
+ ov5693->supplies[i].supply = ov5693_supply_names[i];
|
|
|
+
|
|
|
+- return regulator_bulk_get(&ov5693->i2c_client->dev,
|
|
|
++ return regulator_bulk_get(&ov5693->client->dev,
|
|
|
+ OV5693_NUM_SUPPLIES,
|
|
|
+ ov5693->supplies);
|
|
|
+ }
|
|
|
+@@ -1773,13 +1788,13 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ if (!ov5693)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+- ov5693->i2c_client = client;
|
|
|
++ ov5693->client = client;
|
|
|
+
|
|
|
+ /* check if VCM device exists */
|
|
|
+ /* TODO: read from SSDB */
|
|
|
+ ov5693->has_vcm = false;
|
|
|
+
|
|
|
+- mutex_init(&ov5693->input_lock);
|
|
|
++ mutex_init(&ov5693->lock);
|
|
|
+
|
|
|
+ v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 7f1d31a82d3d..70ccb3aae4c7 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -241,14 +241,15 @@ enum vcm_type {
|
|
|
+ * ov5693 device structure.
|
|
|
+ */
|
|
|
+ struct ov5693_device {
|
|
|
+- struct i2c_client *i2c_client;
|
|
|
++ struct i2c_client *client;
|
|
|
+ struct v4l2_subdev sd;
|
|
|
+ struct media_pad pad;
|
|
|
+ struct v4l2_mbus_framefmt format;
|
|
|
+- struct mutex input_lock;
|
|
|
++ struct mutex lock;
|
|
|
+ struct v4l2_ctrl_handler ctrl_handler;
|
|
|
+
|
|
|
+ struct gpio_desc *reset;
|
|
|
++ struct gpio_desc *powerdown;
|
|
|
+ struct gpio_desc *indicator_led;
|
|
|
+ struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
|
|
|
+ struct clk *clk;
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 1bb274c64997c78a292658d4b62e4b025271737d Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Thu, 28 Jan 2021 12:04:38 +0000
|
|
|
+Subject: [PATCH] media: i2c: Add pm_runtime support to ov5693 driver
|
|
|
+
|
|
|
+The ov5693 driver currently uses hacky and horrible power up/down methods
|
|
|
+called directly in s_stream. Add pm_runtime support and use that in
|
|
|
+s_stream instead. Replace all other uses of the power+up/down() calls with
|
|
|
+the single ov5693_sensor_stream() for now.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 183 +++++++++++++++++++++++++++++--------
|
|
|
+ drivers/media/i2c/ov5693.h | 1 +
|
|
|
+ 2 files changed, 146 insertions(+), 38 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 0643390c872a..f2eaa5f71a31 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -29,6 +29,7 @@
|
|
|
+ #include <linux/module.h>
|
|
|
+ #include <linux/moduleparam.h>
|
|
|
+ #include <linux/mm.h>
|
|
|
++#include <linux/pm_runtime.h>
|
|
|
+ #include <linux/regulator/consumer.h>
|
|
|
+ #include <linux/slab.h>
|
|
|
+ #include <linux/string.h>
|
|
|
+@@ -935,6 +936,10 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ ov5693->ctrls.exposure->val : exposure_max);
|
|
|
+ }
|
|
|
+
|
|
|
++ /* Only apply changes to the controls if the device is powered up */
|
|
|
++ if (!pm_runtime_get_if_in_use(&ov5693->client->dev))
|
|
|
++ return 0;
|
|
|
++
|
|
|
+ switch (ctrl->id) {
|
|
|
+ case V4L2_CID_FOCUS_ABSOLUTE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
|
|
|
+@@ -950,27 +955,23 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+ ret = ov5693_exposure_configure(ov5693, ctrl->val);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_ANALOGUE_GAIN:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_ANALOGUE_GAIN:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+ ret = ov5693_analog_gain_configure(ov5693, ctrl->val);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_DIGITAL_GAIN:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_DIGITAL_GAIN:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+ ret = ov5693_gain_configure(ov5693, ctrl->val);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+ break;
|
|
|
+ case V4L2_CID_HFLIP:
|
|
|
+- return ov5693_flip_horz_configure(ov5693, !!ctrl->val);
|
|
|
++ ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val);
|
|
|
++ break;
|
|
|
+ case V4L2_CID_VFLIP:
|
|
|
+- return ov5693_flip_vert_configure(ov5693, !!ctrl->val);
|
|
|
++ ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val);
|
|
|
++ break;
|
|
|
+ case V4L2_CID_VBLANK:
|
|
|
+ ret = ov5693_write_reg(client, OV5693_16BIT, OV5693_TIMING_VTS_H,
|
|
|
+ ov5693->mode->height + ctrl->val);
|
|
|
+@@ -978,6 +979,9 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ default:
|
|
|
+ ret = -EINVAL;
|
|
|
+ }
|
|
|
++
|
|
|
++ pm_runtime_put(&ov5693->client->dev);
|
|
|
++
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -1093,6 +1097,106 @@ static int ov5693_init(struct v4l2_subdev *sd)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
++static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
|
|
|
++{
|
|
|
++ return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_STREAM,
|
|
|
++ standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING);
|
|
|
++}
|
|
|
++
|
|
|
++static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
|
|
|
++{
|
|
|
++ gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
++ gpiod_set_value_cansleep(ov5693->powerdown, 1);
|
|
|
++
|
|
|
++ regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
|
|
|
++
|
|
|
++ clk_disable_unprepare(ov5693->clk);
|
|
|
++ gpiod_set_value_cansleep(ov5693->indicator_led, 0);
|
|
|
++}
|
|
|
++
|
|
|
++
|
|
|
++static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
|
|
|
++{
|
|
|
++ int ret = 0;
|
|
|
++
|
|
|
++ gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
++ gpiod_set_value_cansleep(ov5693->powerdown, 1);
|
|
|
++
|
|
|
++ ret = clk_prepare_enable(ov5693->clk);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&ov5693->client->dev, "Failed to enable clk\n");
|
|
|
++ goto fail_power;
|
|
|
++ }
|
|
|
++
|
|
|
++ ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&ov5693->client->dev, "Failed to enable regulators\n");
|
|
|
++ goto fail_power;
|
|
|
++ }
|
|
|
++
|
|
|
++ gpiod_set_value_cansleep(ov5693->reset, 0);
|
|
|
++ gpiod_set_value_cansleep(ov5693->powerdown, 0);
|
|
|
++ gpiod_set_value_cansleep(ov5693->indicator_led, 1);
|
|
|
++
|
|
|
++ usleep_range(20000, 25000);
|
|
|
++
|
|
|
++ return 0;
|
|
|
++
|
|
|
++fail_power:
|
|
|
++ ov5693_sensor_powerdown(ov5693);
|
|
|
++ return ret;
|
|
|
++}
|
|
|
++
|
|
|
++static int __maybe_unused ov5693_sensor_suspend(struct device *dev)
|
|
|
++{
|
|
|
++ struct i2c_client *client = i2c_verify_client(dev);
|
|
|
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
++ int ret;
|
|
|
++
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
++
|
|
|
++ if (ov5693->streaming) {
|
|
|
++ ret = ov5693_sw_standby(ov5693, true);
|
|
|
++ if (ret)
|
|
|
++ goto out_unlock;
|
|
|
++ }
|
|
|
++
|
|
|
++ ov5693_sensor_powerdown(ov5693);
|
|
|
++
|
|
|
++out_unlock:
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
++ return ret;
|
|
|
++}
|
|
|
++
|
|
|
++static int __maybe_unused ov5693_sensor_resume(struct device *dev)
|
|
|
++{
|
|
|
++ struct i2c_client *client = i2c_verify_client(dev);
|
|
|
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
++ int ret;
|
|
|
++
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
++
|
|
|
++ ret = ov5693_sensor_powerup(ov5693);
|
|
|
++ if (ret)
|
|
|
++ goto out_unlock;
|
|
|
++
|
|
|
++ if (ov5693->streaming) {
|
|
|
++ ret = ov5693_sw_standby(ov5693, false);
|
|
|
++ if (ret)
|
|
|
++ goto err_power;
|
|
|
++ }
|
|
|
++
|
|
|
++ goto out_unlock;
|
|
|
++
|
|
|
++err_power:
|
|
|
++ ov5693_sensor_powerdown(ov5693);
|
|
|
++out_unlock:
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
++ return ret;
|
|
|
++}
|
|
|
++
|
|
|
+ static int __power_up(struct v4l2_subdev *sd)
|
|
|
+ {
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+@@ -1134,6 +1238,7 @@ static int power_down(struct v4l2_subdev *sd)
|
|
|
+ ov5693->focus = OV5693_INVALID_CONFIG;
|
|
|
+
|
|
|
+ gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
++ gpiod_set_value_cansleep(ov5693->powerdown, 1);
|
|
|
+
|
|
|
+ clk_disable_unprepare(ov5693->clk);
|
|
|
+
|
|
|
+@@ -1333,7 +1438,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ }
|
|
|
+
|
|
|
+ for (cnt = 0; cnt < OV5693_POWER_UP_RETRY_NUM; cnt++) {
|
|
|
+- ret = power_up(sd);
|
|
|
++ ret = ov5693_sensor_powerup(ov5693);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "power up failed\n");
|
|
|
+ continue;
|
|
|
+@@ -1475,38 +1580,34 @@ static int ov5693_detect(struct i2c_client *client)
|
|
|
+
|
|
|
+ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable)
|
|
|
+ {
|
|
|
+- struct ov5693_device *dev = to_ov5693_sensor(sd);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
++ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+- mutex_lock(&dev->lock);
|
|
|
+-
|
|
|
+- /* power_on() here before streaming for regular PCs. */
|
|
|
+ if (enable) {
|
|
|
+- ret = power_up(sd);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "sensor power-up error\n");
|
|
|
+- goto out;
|
|
|
+- }
|
|
|
++ ret = pm_runtime_get_sync(&ov5693->client->dev);
|
|
|
++ if (ret < 0)
|
|
|
++ goto err_power_down;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = __v4l2_ctrl_handler_setup(&dev->ctrl_handler);
|
|
|
+- if (ret) {
|
|
|
+- power_down(sd);
|
|
|
+- return ret;
|
|
|
+- }
|
|
|
++ ret = __v4l2_ctrl_handler_setup(&ov5693->ctrl_handler);
|
|
|
++ if (ret)
|
|
|
++ goto err_power_down;
|
|
|
+
|
|
|
+- ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
|
|
|
+- enable ? OV5693_START_STREAMING :
|
|
|
+- OV5693_STOP_STREAMING);
|
|
|
++ mutex_lock(&ov5693->lock);
|
|
|
++ ret = ov5693_sw_standby(ov5693, !enable);
|
|
|
++ mutex_unlock(&ov5693->lock);
|
|
|
++
|
|
|
++ if (ret)
|
|
|
++ goto err_power_down;
|
|
|
++ ov5693->streaming = !!enable;
|
|
|
+
|
|
|
+ /* power_off() here after streaming for regular PCs. */
|
|
|
+ if (!enable)
|
|
|
+- power_down(sd);
|
|
|
+-
|
|
|
+-out:
|
|
|
+- mutex_unlock(&dev->lock);
|
|
|
++ pm_runtime_put(&ov5693->client->dev);
|
|
|
+
|
|
|
++ return 0;
|
|
|
++err_power_down:
|
|
|
++ pm_runtime_put_noidle(&ov5693->client->dev);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -1517,7 +1618,7 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ mutex_lock(&ov5693->lock);
|
|
|
+- ret = power_up(sd);
|
|
|
++ ret = ov5693_sensor_powerup(ov5693);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "ov5693 power-up err.\n");
|
|
|
+ goto fail_power_on;
|
|
|
+@@ -1536,17 +1637,14 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ ov5693->otp_data = ov5693_otp_read(sd);
|
|
|
+
|
|
|
+ /* turn off sensor, after probed */
|
|
|
+- ret = power_down(sd);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "ov5693 power-off err.\n");
|
|
|
+- goto fail_power_on;
|
|
|
+- }
|
|
|
++ ov5693_sensor_powerdown(ov5693);
|
|
|
++
|
|
|
+ mutex_unlock(&ov5693->lock);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ fail_power_on:
|
|
|
+- power_down(sd);
|
|
|
++ ov5693_sensor_powerdown(ov5693);
|
|
|
+ dev_err(&client->dev, "sensor power-gating failed\n");
|
|
|
+ mutex_unlock(&ov5693->lock);
|
|
|
+ return ret;
|
|
|
+@@ -1830,6 +1928,9 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ if (ret)
|
|
|
+ ov5693_remove(client);
|
|
|
+
|
|
|
++ pm_runtime_enable(&client->dev);
|
|
|
++ pm_runtime_set_suspended(&client->dev);
|
|
|
++
|
|
|
+ ret = v4l2_async_register_subdev_sensor_common(&ov5693->sd);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "failed to register V4L2 subdev: %d", ret);
|
|
|
+@@ -1839,6 +1940,7 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ media_entity_cleanup:
|
|
|
++ pm_runtime_disable(&client->dev);
|
|
|
+ media_entity_cleanup(&ov5693->sd.entity);
|
|
|
+ out_put_reset:
|
|
|
+ gpiod_put(ov5693->reset);
|
|
|
+@@ -1848,6 +1950,10 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
++static const struct dev_pm_ops ov5693_pm_ops = {
|
|
|
++ SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL)
|
|
|
++};
|
|
|
++
|
|
|
+ static const struct acpi_device_id ov5693_acpi_match[] = {
|
|
|
+ {"INT33BE"},
|
|
|
+ {},
|
|
|
+@@ -1858,6 +1964,7 @@ static struct i2c_driver ov5693_driver = {
|
|
|
+ .driver = {
|
|
|
+ .name = "ov5693",
|
|
|
+ .acpi_match_table = ov5693_acpi_match,
|
|
|
++ .pm = &ov5693_pm_ops,
|
|
|
+ },
|
|
|
+ .probe_new = ov5693_probe,
|
|
|
+ .remove = ov5693_remove,
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 70ccb3aae4c7..b78d3b474a43 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -256,6 +256,7 @@ struct ov5693_device {
|
|
|
+
|
|
|
+ /* Current mode */
|
|
|
+ const struct ov5693_resolution *mode;
|
|
|
++ bool streaming;
|
|
|
+
|
|
|
+ struct camera_sensor_platform_data *platform_data;
|
|
|
+ ktime_t timestamp_t_focus_abs;
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 14139a66573795862858f43042067bab217e3a8d Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Thu, 28 Jan 2021 12:07:36 +0000
|
|
|
+Subject: [PATCH] media: i2c: Remove old power methods from ov5693
|
|
|
+
|
|
|
+Now that we have replaced the power_up/down() methods with a unified
|
|
|
+function and pm_runtime support, we can remove these old methods from the
|
|
|
+driver entirely along with some macros and a header.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 114 -------------------------------------
|
|
|
+ 1 file changed, 114 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index f2eaa5f71a31..ce26ce86fbd5 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -27,7 +27,6 @@
|
|
|
+ #include <linux/kernel.h>
|
|
|
+ #include <linux/kmod.h>
|
|
|
+ #include <linux/module.h>
|
|
|
+-#include <linux/moduleparam.h>
|
|
|
+ #include <linux/mm.h>
|
|
|
+ #include <linux/pm_runtime.h>
|
|
|
+ #include <linux/regulator/consumer.h>
|
|
|
+@@ -40,27 +39,6 @@
|
|
|
+ #include "ov5693.h"
|
|
|
+ #include "ad5823.h"
|
|
|
+
|
|
|
+-#define __cci_delay(t) \
|
|
|
+- do { \
|
|
|
+- if ((t) < 10) { \
|
|
|
+- usleep_range((t) * 1000, ((t) + 1) * 1000); \
|
|
|
+- } else { \
|
|
|
+- msleep((t)); \
|
|
|
+- } \
|
|
|
+- } while (0)
|
|
|
+-
|
|
|
+-/* Value 30ms reached through experimentation on byt ecs.
|
|
|
+- * The DS specifies a much lower value but when using a smaller value
|
|
|
+- * the I2C bus sometimes locks up permanently when starting the camera.
|
|
|
+- * This issue could not be reproduced on cht, so we can reduce the
|
|
|
+- * delay value to a lower value when insmod.
|
|
|
+- */
|
|
|
+-static uint up_delay = 30;
|
|
|
+-module_param(up_delay, uint, 0644);
|
|
|
+-MODULE_PARM_DESC(up_delay,
|
|
|
+- "Delay prior to the first CCI transaction for ov5693");
|
|
|
+-
|
|
|
+-
|
|
|
+ /* Exposure/gain */
|
|
|
+
|
|
|
+ #define OV5693_EXPOSURE_CTRL_HH_REG 0x3500
|
|
|
+@@ -1197,93 +1175,6 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int __power_up(struct v4l2_subdev *sd)
|
|
|
+-{
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- int ret;
|
|
|
+-
|
|
|
+- ret = clk_prepare_enable(ov5693->clk);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "Error enabling clock\n");
|
|
|
+- return -EINVAL;
|
|
|
+- }
|
|
|
+-
|
|
|
+- if (ov5693->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(ov5693->indicator_led, 1);
|
|
|
+-
|
|
|
+- ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES,
|
|
|
+- ov5693->supplies);
|
|
|
+- if (ret)
|
|
|
+- goto fail_power;
|
|
|
+-
|
|
|
+- gpiod_set_value_cansleep(ov5693->reset, 0);
|
|
|
+-
|
|
|
+- __cci_delay(up_delay);
|
|
|
+-
|
|
|
+- return 0;
|
|
|
+-
|
|
|
+-fail_power:
|
|
|
+- if (ov5693->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(ov5693->indicator_led, 0);
|
|
|
+- dev_err(&client->dev, "sensor power-up failed\n");
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int power_down(struct v4l2_subdev *sd)
|
|
|
+-{
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+-
|
|
|
+- ov5693->focus = OV5693_INVALID_CONFIG;
|
|
|
+-
|
|
|
+- gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
+- gpiod_set_value_cansleep(ov5693->powerdown, 1);
|
|
|
+-
|
|
|
+- clk_disable_unprepare(ov5693->clk);
|
|
|
+-
|
|
|
+- if (ov5693->indicator_led)
|
|
|
+- gpiod_set_value_cansleep(ov5693->indicator_led, 0);
|
|
|
+- return regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies);
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int power_up(struct v4l2_subdev *sd)
|
|
|
+-{
|
|
|
+- static const int retry_count = 4;
|
|
|
+- int i, ret;
|
|
|
+-
|
|
|
+- for (i = 0; i < retry_count; i++) {
|
|
|
+- ret = __power_up(sd);
|
|
|
+- if (!ret)
|
|
|
+- return 0;
|
|
|
+-
|
|
|
+- power_down(sd);
|
|
|
+- }
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ov5693_s_power(struct v4l2_subdev *sd, int on)
|
|
|
+-{
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- int ret;
|
|
|
+-
|
|
|
+- dev_info(&client->dev, "%s: on %d\n", __func__, on);
|
|
|
+-
|
|
|
+- if (on == 0)
|
|
|
+- return power_down(sd);
|
|
|
+-
|
|
|
+- /* on == 1 */
|
|
|
+- ret = power_up(sd);
|
|
|
+- if (!ret) {
|
|
|
+- ret = ov5693_init(sd);
|
|
|
+- /* restore settings */
|
|
|
+- ov5693_res = ov5693_res_video;
|
|
|
+- N_RES = N_RES_VIDEO;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+ /*
|
|
|
+ * distance - calculate the distance
|
|
|
+ * @res: resolution
|
|
|
+@@ -1694,10 +1585,6 @@ static const struct v4l2_subdev_video_ops ov5693_video_ops = {
|
|
|
+ .g_frame_interval = ov5693_g_frame_interval,
|
|
|
+ };
|
|
|
+
|
|
|
+-static const struct v4l2_subdev_core_ops ov5693_core_ops = {
|
|
|
+- .s_power = ov5693_s_power,
|
|
|
+-};
|
|
|
+-
|
|
|
+ static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
|
|
|
+ .enum_mbus_code = ov5693_enum_mbus_code,
|
|
|
+ .enum_frame_size = ov5693_enum_frame_size,
|
|
|
+@@ -1707,7 +1594,6 @@ static const struct v4l2_subdev_pad_ops ov5693_pad_ops = {
|
|
|
+ };
|
|
|
+
|
|
|
+ static const struct v4l2_subdev_ops ov5693_ops = {
|
|
|
+- .core = &ov5693_core_ops,
|
|
|
+ .video = &ov5693_video_ops,
|
|
|
+ .pad = &ov5693_pad_ops,
|
|
|
+ };
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 5011775be888a29eaaf4100b229a80271cfc78da Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Thu, 28 Jan 2021 12:14:00 +0000
|
|
|
+Subject: [PATCH] media: i2c: Trim unused headers from ov5693
|
|
|
+
|
|
|
+The ov5693 driver includes a ton of unecessary headers,
|
|
|
+trim the list down.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 8 --------
|
|
|
+ 1 file changed, 8 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index ce26ce86fbd5..b3b391a49fdb 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -20,19 +20,11 @@
|
|
|
+ #include <linux/clk.h>
|
|
|
+ #include <linux/delay.h>
|
|
|
+ #include <linux/device.h>
|
|
|
+-#include <linux/errno.h>
|
|
|
+ #include <linux/i2c.h>
|
|
|
+-#include <linux/init.h>
|
|
|
+-#include <linux/io.h>
|
|
|
+-#include <linux/kernel.h>
|
|
|
+-#include <linux/kmod.h>
|
|
|
+ #include <linux/module.h>
|
|
|
+-#include <linux/mm.h>
|
|
|
+ #include <linux/pm_runtime.h>
|
|
|
+ #include <linux/regulator/consumer.h>
|
|
|
+ #include <linux/slab.h>
|
|
|
+-#include <linux/string.h>
|
|
|
+-#include <linux/types.h>
|
|
|
+ #include <media/v4l2-device.h>
|
|
|
+ #include <media/v4l2-fwnode.h>
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From d9137b83092e75131784f32b2f43be8c2be1a13f Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 13 Feb 2021 21:39:35 +0000
|
|
|
+Subject: [PATCH] media: i2c: Remove VCM stuff
|
|
|
+
|
|
|
+This all needs binning, since we have no idea if it's right. It needs to
|
|
|
+be moved to a driver for the VCM device I guess.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 325 +------------------------------------
|
|
|
+ 1 file changed, 1 insertion(+), 324 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index b3b391a49fdb..2c82b6578de9 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -76,72 +76,6 @@
|
|
|
+ #define OV5693_PIXEL_ARRAY_WIDTH 2592U
|
|
|
+ #define OV5693_PIXEL_ARRAY_HEIGHT 1944U
|
|
|
+
|
|
|
+-static int vcm_ad_i2c_wr8(struct i2c_client *client, u8 reg, u8 val)
|
|
|
+-{
|
|
|
+- int err;
|
|
|
+- struct i2c_msg msg;
|
|
|
+- u8 buf[2];
|
|
|
+-
|
|
|
+- buf[0] = reg;
|
|
|
+- buf[1] = val;
|
|
|
+-
|
|
|
+- msg.addr = VCM_ADDR;
|
|
|
+- msg.flags = 0;
|
|
|
+- msg.len = 2;
|
|
|
+- msg.buf = &buf[0];
|
|
|
+-
|
|
|
+- err = i2c_transfer(client->adapter, &msg, 1);
|
|
|
+- if (err != 1) {
|
|
|
+- dev_err(&client->dev, "%s: vcm i2c fail, err code = %d\n",
|
|
|
+- __func__, err);
|
|
|
+- return -EIO;
|
|
|
+- }
|
|
|
+- return 0;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ad5823_i2c_write(struct i2c_client *client, u8 reg, u8 val)
|
|
|
+-{
|
|
|
+- struct i2c_msg msg;
|
|
|
+- u8 buf[2];
|
|
|
+-
|
|
|
+- buf[0] = reg;
|
|
|
+- buf[1] = val;
|
|
|
+- msg.addr = AD5823_VCM_ADDR;
|
|
|
+- msg.flags = 0;
|
|
|
+- msg.len = 0x02;
|
|
|
+- msg.buf = &buf[0];
|
|
|
+-
|
|
|
+- if (i2c_transfer(client->adapter, &msg, 1) != 1)
|
|
|
+- return -EIO;
|
|
|
+- return 0;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ad5823_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
|
|
|
+-{
|
|
|
+- struct i2c_msg msg[2];
|
|
|
+- u8 buf[2];
|
|
|
+-
|
|
|
+- buf[0] = reg;
|
|
|
+- buf[1] = 0;
|
|
|
+-
|
|
|
+- msg[0].addr = AD5823_VCM_ADDR;
|
|
|
+- msg[0].flags = 0;
|
|
|
+- msg[0].len = 0x01;
|
|
|
+- msg[0].buf = &buf[0];
|
|
|
+-
|
|
|
+- msg[1].addr = 0x0c;
|
|
|
+- msg[1].flags = I2C_M_RD;
|
|
|
+- msg[1].len = 0x01;
|
|
|
+- msg[1].buf = &buf[1];
|
|
|
+- *val = 0;
|
|
|
+- if (i2c_transfer(client->adapter, msg, 2) != 2)
|
|
|
+- return -EIO;
|
|
|
+- *val = buf[1];
|
|
|
+- return 0;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static const u32 ov5693_embedded_effective_size = 28;
|
|
|
+-
|
|
|
+ /* i2c read/write stuff */
|
|
|
+ static int ov5693_read_reg(struct i2c_client *client,
|
|
|
+ u16 data_length, u16 reg, u16 *val)
|
|
|
+@@ -215,69 +149,6 @@ static int ov5693_i2c_write(struct i2c_client *client, u16 len, u8 *data)
|
|
|
+ return ret == num_msg ? 0 : -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
|
|
|
+-{
|
|
|
+- struct i2c_msg msg;
|
|
|
+- const int num_msg = 1;
|
|
|
+- int ret;
|
|
|
+- __be16 val;
|
|
|
+-
|
|
|
+- val = cpu_to_be16(data);
|
|
|
+- msg.addr = VCM_ADDR;
|
|
|
+- msg.flags = 0;
|
|
|
+- msg.len = OV5693_16BIT;
|
|
|
+- msg.buf = (void *)&val;
|
|
|
+-
|
|
|
+- ret = i2c_transfer(client->adapter, &msg, 1);
|
|
|
+-
|
|
|
+- return ret == num_msg ? 0 : -EIO;
|
|
|
+-}
|
|
|
+-
|
|
|
+-/*
|
|
|
+- * Theory: per datasheet, the two VCMs both allow for a 2-byte read.
|
|
|
+- * The DW9714 doesn't actually specify what this does (it has a
|
|
|
+- * two-byte write-only protocol, but specifies the read sequence as
|
|
|
+- * legal), but it returns the same data (zeroes) always, after an
|
|
|
+- * undocumented initial NAK. The AD5823 has a one-byte address
|
|
|
+- * register to which all writes go, and subsequent reads will cycle
|
|
|
+- * through the 8 bytes of registers. Notably, the default values (the
|
|
|
+- * device is always power-cycled affirmatively, so we can rely on
|
|
|
+- * these) in AD5823 are not pairwise repetitions of the same 16 bit
|
|
|
+- * word. So all we have to do is sequentially read two bytes at a
|
|
|
+- * time and see if we detect a difference in any of the first four
|
|
|
+- * pairs.
|
|
|
+- */
|
|
|
+-static int vcm_detect(struct i2c_client *client)
|
|
|
+-{
|
|
|
+- int i, ret;
|
|
|
+- struct i2c_msg msg;
|
|
|
+- u16 data0 = 0, data;
|
|
|
+-
|
|
|
+- for (i = 0; i < 4; i++) {
|
|
|
+- msg.addr = VCM_ADDR;
|
|
|
+- msg.flags = I2C_M_RD;
|
|
|
+- msg.len = sizeof(data);
|
|
|
+- msg.buf = (u8 *)&data;
|
|
|
+- ret = i2c_transfer(client->adapter, &msg, 1);
|
|
|
+-
|
|
|
+- /*
|
|
|
+- * DW9714 always fails the first read and returns
|
|
|
+- * zeroes for subsequent ones
|
|
|
+- */
|
|
|
+- if (i == 0 && ret == -EREMOTEIO) {
|
|
|
+- data0 = 0;
|
|
|
+- continue;
|
|
|
+- }
|
|
|
+-
|
|
|
+- if (i == 0)
|
|
|
+- data0 = data;
|
|
|
+-
|
|
|
+- if (data != data0)
|
|
|
+- return VCM_AD5823;
|
|
|
+- }
|
|
|
+- return ret == 1 ? VCM_DW9714 : ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+ static int ov5693_write_reg(struct i2c_client *client, u16 data_length,
|
|
|
+ u16 reg, u16 val)
|
|
|
+ {
|
|
|
+@@ -654,89 +525,6 @@ static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val)
|
|
|
+-{
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- int ret = -EINVAL;
|
|
|
+- u8 vcm_code;
|
|
|
+-
|
|
|
+- ret = ad5823_i2c_read(client, AD5823_REG_VCM_CODE_MSB, &vcm_code);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- /* set reg VCM_CODE_MSB Bit[1:0] */
|
|
|
+- vcm_code = (vcm_code & VCM_CODE_MSB_MASK) |
|
|
|
+- ((val >> 8) & ~VCM_CODE_MSB_MASK);
|
|
|
+- ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB, vcm_code);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- /* set reg VCM_CODE_LSB Bit[7:0] */
|
|
|
+- ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_LSB, (val & 0xff));
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- /* set required vcm move time */
|
|
|
+- vcm_code = AD5823_RESONANCE_PERIOD / AD5823_RESONANCE_COEF
|
|
|
+- - AD5823_HIGH_FREQ_RANGE;
|
|
|
+- ret = ad5823_i2c_write(client, AD5823_REG_VCM_MOVE_TIME, vcm_code);
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+-{
|
|
|
+- value = min(value, AD5823_MAX_FOCUS_POS);
|
|
|
+- return ad5823_t_focus_vcm(sd, value);
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
|
|
|
+-{
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- int ret = 0;
|
|
|
+-
|
|
|
+- dev_dbg(&client->dev, "%s: FOCUS_POS: 0x%x\n", __func__, value);
|
|
|
+- value = clamp(value, 0, OV5693_VCM_MAX_FOCUS_POS);
|
|
|
+- if (ov5693->vcm == VCM_DW9714) {
|
|
|
+- if (ov5693->vcm_update) {
|
|
|
+- ret = vcm_dw_i2c_write(client, VCM_PROTECTION_OFF);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+- ret = vcm_dw_i2c_write(client, DIRECT_VCM);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+- ret = vcm_dw_i2c_write(client, VCM_PROTECTION_ON);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+- ov5693->vcm_update = false;
|
|
|
+- }
|
|
|
+- ret = vcm_dw_i2c_write(client,
|
|
|
+- vcm_val(value, VCM_DEFAULT_S));
|
|
|
+- } else if (ov5693->vcm == VCM_AD5823) {
|
|
|
+- ad5823_t_focus_abs(sd, value);
|
|
|
+- }
|
|
|
+- if (ret == 0) {
|
|
|
+- ov5693->number_of_steps = value - ov5693->focus;
|
|
|
+- ov5693->focus = value;
|
|
|
+- ov5693->timestamp_t_focus_abs = ktime_get();
|
|
|
+- } else
|
|
|
+- dev_err(&client->dev,
|
|
|
+- "%s: i2c failed. ret %d\n", __func__, ret);
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
|
|
|
+-{
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+-
|
|
|
+- return ov5693_t_focus_abs(sd, ov5693->focus + value);
|
|
|
+-}
|
|
|
+-
|
|
|
+-#define DELAY_PER_STEP_NS 1000000
|
|
|
+-#define DELAY_MAX_PER_STEP_NS (1000000 * 1023)
|
|
|
+-
|
|
|
+ /* Exposure */
|
|
|
+
|
|
|
+ static int ov5693_get_exposure(struct ov5693_device *ov5693)
|
|
|
+@@ -911,16 +699,6 @@ static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ switch (ctrl->id) {
|
|
|
+- case V4L2_CID_FOCUS_ABSOLUTE:
|
|
|
+- dev_dbg(&client->dev, "%s: CID_FOCUS_ABSOLUTE:%d.\n",
|
|
|
+- __func__, ctrl->val);
|
|
|
+- ret = ov5693_t_focus_abs(&ov5693->sd, ctrl->val);
|
|
|
+- break;
|
|
|
+- case V4L2_CID_FOCUS_RELATIVE:
|
|
|
+- dev_dbg(&client->dev, "%s: CID_FOCUS_RELATIVE:%d.\n",
|
|
|
+- __func__, ctrl->val);
|
|
|
+- ret = ov5693_t_focus_rel(&ov5693->sd, ctrl->val);
|
|
|
+- break;
|
|
|
+ case V4L2_CID_EXPOSURE:
|
|
|
+ dev_dbg(&client->dev, "%s: CID_EXPOSURE:%d.\n",
|
|
|
+ __func__, ctrl->val);
|
|
|
+@@ -983,90 +761,6 @@ static const struct v4l2_ctrl_ops ov5693_ctrl_ops = {
|
|
|
+ .g_volatile_ctrl = ov5693_g_volatile_ctrl
|
|
|
+ };
|
|
|
+
|
|
|
+-static const struct v4l2_ctrl_config ov5693_controls[] = {
|
|
|
+- {
|
|
|
+- .ops = &ov5693_ctrl_ops,
|
|
|
+- .id = V4L2_CID_FOCUS_ABSOLUTE,
|
|
|
+- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
|
+- .name = "focus move absolute",
|
|
|
+- .min = 0,
|
|
|
+- .max = OV5693_VCM_MAX_FOCUS_POS,
|
|
|
+- .step = 1,
|
|
|
+- .def = 0,
|
|
|
+- .flags = 0,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .ops = &ov5693_ctrl_ops,
|
|
|
+- .id = V4L2_CID_FOCUS_RELATIVE,
|
|
|
+- .type = V4L2_CTRL_TYPE_INTEGER,
|
|
|
+- .name = "focus move relative",
|
|
|
+- .min = OV5693_VCM_MAX_FOCUS_NEG,
|
|
|
+- .max = OV5693_VCM_MAX_FOCUS_POS,
|
|
|
+- .step = 1,
|
|
|
+- .def = 0,
|
|
|
+- .flags = 0,
|
|
|
+- },
|
|
|
+-};
|
|
|
+-
|
|
|
+-static int ov5693_isp_configure(struct ov5693_device *ov5693)
|
|
|
+-{
|
|
|
+- int ret;
|
|
|
+-
|
|
|
+- /* Enable lens correction. */
|
|
|
+- ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+- OV5693_ISP_CTRL0_REG, 0x86);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- return 0;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int ov5693_init(struct v4l2_subdev *sd)
|
|
|
+-{
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- int ret;
|
|
|
+-
|
|
|
+- if (!ov5693->has_vcm)
|
|
|
+- return 0;
|
|
|
+-
|
|
|
+- dev_info(&client->dev, "%s\n", __func__);
|
|
|
+- mutex_lock(&ov5693->lock);
|
|
|
+- ov5693->vcm_update = false;
|
|
|
+-
|
|
|
+- if (ov5693->vcm == VCM_AD5823) {
|
|
|
+- ret = vcm_ad_i2c_wr8(client, 0x01, 0x01); /* vcm init test */
|
|
|
+- if (ret)
|
|
|
+- dev_err(&client->dev,
|
|
|
+- "vcm reset failed\n");
|
|
|
+- /*change the mode*/
|
|
|
+- ret = ad5823_i2c_write(client, AD5823_REG_VCM_CODE_MSB,
|
|
|
+- AD5823_RING_CTRL_ENABLE);
|
|
|
+- if (ret)
|
|
|
+- dev_err(&client->dev,
|
|
|
+- "vcm enable ringing failed\n");
|
|
|
+- ret = ad5823_i2c_write(client, AD5823_REG_MODE,
|
|
|
+- AD5823_ARC_RES1);
|
|
|
+- if (ret)
|
|
|
+- dev_err(&client->dev,
|
|
|
+- "vcm change mode failed\n");
|
|
|
+- }
|
|
|
+-
|
|
|
+- /*change initial focus value for ad5823*/
|
|
|
+- if (ov5693->vcm == VCM_AD5823) {
|
|
|
+- ov5693->focus = AD5823_INIT_FOCUS_POS;
|
|
|
+- ov5693_t_focus_abs(sd, AD5823_INIT_FOCUS_POS);
|
|
|
+- } else {
|
|
|
+- ov5693->focus = 0;
|
|
|
+- ov5693_t_focus_abs(sd, 0);
|
|
|
+- }
|
|
|
+-
|
|
|
+- ov5693_isp_configure(ov5693);
|
|
|
+- mutex_unlock(&ov5693->lock);
|
|
|
+-
|
|
|
+- return 0;
|
|
|
+-}
|
|
|
+-
|
|
|
+ static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
|
|
|
+ {
|
|
|
+ return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_STREAM,
|
|
|
+@@ -1327,9 +1021,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+- mutex_unlock(&ov5693->lock);
|
|
|
+- ov5693_init(sd);
|
|
|
+- mutex_lock(&ov5693->lock);
|
|
|
+ ret = startup(sd);
|
|
|
+ if (ret)
|
|
|
+ dev_err(&client->dev, " startup() FAILED!\n");
|
|
|
+@@ -1507,9 +1198,6 @@ static int ov5693_s_config(struct v4l2_subdev *sd, int irq)
|
|
|
+ goto fail_power_on;
|
|
|
+ }
|
|
|
+
|
|
|
+- if (!ov5693->vcm)
|
|
|
+- ov5693->vcm = vcm_detect(client);
|
|
|
+-
|
|
|
+ /* config & detect sensor */
|
|
|
+ ret = ov5693_detect(client);
|
|
|
+ if (ret) {
|
|
|
+@@ -1617,24 +1305,17 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(&ov5693->sd);
|
|
|
+ const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops;
|
|
|
+ struct v4l2_fwnode_device_properties props;
|
|
|
+- unsigned int i;
|
|
|
+ int ret;
|
|
|
+ int hblank;
|
|
|
+ int vblank_max, vblank_min, vblank_def;
|
|
|
+ int exposure_max;
|
|
|
+
|
|
|
+- ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler,
|
|
|
+- ARRAY_SIZE(ov5693_controls));
|
|
|
++ ret = v4l2_ctrl_handler_init(&ov5693->ctrl_handler, 8);
|
|
|
+ if (ret) {
|
|
|
+ ov5693_remove(client);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- for (i = 0; i < ARRAY_SIZE(ov5693_controls); i++)
|
|
|
+- v4l2_ctrl_new_custom(&ov5693->ctrl_handler,
|
|
|
+- &ov5693_controls[i],
|
|
|
+- NULL);
|
|
|
+-
|
|
|
+ /* link freq */
|
|
|
+ ov5693->ctrls.link_freq = v4l2_ctrl_new_int_menu(&ov5693->ctrl_handler,
|
|
|
+ NULL, V4L2_CID_LINK_FREQ,
|
|
|
+@@ -1766,10 +1447,6 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+
|
|
|
+ ov5693->client = client;
|
|
|
+
|
|
|
+- /* check if VCM device exists */
|
|
|
+- /* TODO: read from SSDB */
|
|
|
+- ov5693->has_vcm = false;
|
|
|
+-
|
|
|
+ mutex_init(&ov5693->lock);
|
|
|
+
|
|
|
+ v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops);
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 260af2d112381bd949f9900f141a1e7ef78951d7 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 13 Feb 2021 22:16:08 +0000
|
|
|
+Subject: [PATCH] media: i2c: Tidy up ov5693 sensor init
|
|
|
+
|
|
|
+The initialisation of a mode when the sensor is activated is a bit messy,
|
|
|
+so lets tidy that up a bit to bring it in line with other drivers.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 100 ++++++++++++++++---------------------
|
|
|
+ 1 file changed, 42 insertions(+), 58 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 2c82b6578de9..313bc9177328 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -767,6 +767,42 @@ static int ov5693_sw_standby(struct ov5693_device *ov5693, bool standby)
|
|
|
+ standby ? OV5693_STOP_STREAMING : OV5693_START_STREAMING);
|
|
|
+ }
|
|
|
+
|
|
|
++static int ov5693_sw_reset(struct ov5693_device *ov5693)
|
|
|
++{
|
|
|
++ return ov5693_write_reg(ov5693->client, OV5693_8BIT, OV5693_SW_RESET,
|
|
|
++ 0x01);
|
|
|
++}
|
|
|
++
|
|
|
++static int ov5693_sensor_init(struct ov5693_device *ov5693)
|
|
|
++{
|
|
|
++ struct i2c_client *client = ov5693->client;
|
|
|
++ int ret = 0;
|
|
|
++
|
|
|
++ ret = ov5693_sw_reset(ov5693);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&client->dev, "ov5693 reset err.\n");
|
|
|
++ return ret;
|
|
|
++ }
|
|
|
++
|
|
|
++ ret = ov5693_write_reg_array(client, ov5693_global_setting);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
++ return ret;
|
|
|
++ }
|
|
|
++
|
|
|
++ ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
++ return ret;
|
|
|
++ }
|
|
|
++
|
|
|
++ ret = ov5693_sw_standby(ov5693, true);
|
|
|
++ if (ret)
|
|
|
++ dev_err(&client->dev, "ov5693 stream off error\n");
|
|
|
++
|
|
|
++ return ret;
|
|
|
++}
|
|
|
++
|
|
|
+ static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+ gpiod_set_value_cansleep(ov5693->reset, 1);
|
|
|
+@@ -846,6 +882,12 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
|
|
|
+ if (ret)
|
|
|
+ goto out_unlock;
|
|
|
+
|
|
|
++ ret = ov5693_sensor_init(ov5693);
|
|
|
++ if (ret) {
|
|
|
++ dev_err(&client->dev, "ov5693 sensor init failure\n");
|
|
|
++ goto err_power;
|
|
|
++ }
|
|
|
++
|
|
|
+ if (ov5693->streaming) {
|
|
|
+ ret = ov5693_sw_standby(ov5693, false);
|
|
|
+ if (ret)
|
|
|
+@@ -944,35 +986,6 @@ static int get_resolution_index(int w, int h)
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+-/* TODO: remove it. */
|
|
|
+-static int startup(struct v4l2_subdev *sd)
|
|
|
+-{
|
|
|
+- struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+- int ret = 0;
|
|
|
+-
|
|
|
+- ret = ov5693_write_reg(client, OV5693_8BIT,
|
|
|
+- OV5693_SW_RESET, 0x01);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "ov5693 reset err.\n");
|
|
|
+- return ret;
|
|
|
+- }
|
|
|
+-
|
|
|
+- ret = ov5693_write_reg_array(client, ov5693_global_setting);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
+- return ret;
|
|
|
+- }
|
|
|
+-
|
|
|
+- ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
+- return ret;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ struct v4l2_subdev_pad_config *cfg,
|
|
|
+ struct v4l2_subdev_format *format)
|
|
|
+@@ -982,7 +995,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
+ int ret = 0;
|
|
|
+ int idx;
|
|
|
+- int cnt;
|
|
|
+
|
|
|
+ if (format->pad)
|
|
|
+ return -EINVAL;
|
|
|
+@@ -1014,34 +1026,6 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ goto mutex_unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+- for (cnt = 0; cnt < OV5693_POWER_UP_RETRY_NUM; cnt++) {
|
|
|
+- ret = ov5693_sensor_powerup(ov5693);
|
|
|
+- if (ret) {
|
|
|
+- dev_err(&client->dev, "power up failed\n");
|
|
|
+- continue;
|
|
|
+- }
|
|
|
+-
|
|
|
+- ret = startup(sd);
|
|
|
+- if (ret)
|
|
|
+- dev_err(&client->dev, " startup() FAILED!\n");
|
|
|
+- else
|
|
|
+- break;
|
|
|
+- }
|
|
|
+- if (cnt == OV5693_POWER_UP_RETRY_NUM) {
|
|
|
+- dev_err(&client->dev, "power up failed, gave up\n");
|
|
|
+- goto mutex_unlock;
|
|
|
+- }
|
|
|
+-
|
|
|
+- /*
|
|
|
+- * After sensor settings are set to HW, sometimes stream is started.
|
|
|
+- * This would cause ISP timeout because ISP is not ready to receive
|
|
|
+- * data yet. So add stop streaming here.
|
|
|
+- */
|
|
|
+- ret = ov5693_write_reg(client, OV5693_8BIT, OV5693_SW_STREAM,
|
|
|
+- OV5693_STOP_STREAMING);
|
|
|
+- if (ret)
|
|
|
+- dev_warn(&client->dev, "ov5693 stream off err\n");
|
|
|
+-
|
|
|
+ mutex_unlock:
|
|
|
+ mutex_unlock(&ov5693->lock);
|
|
|
+ return ret;
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From e3683a5e3542eeff0cc582088ca06c448546bc7f Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Fri, 12 Feb 2021 16:14:04 +0000
|
|
|
+Subject: [PATCH] media: i2c: cleanup macros in ov5693.h
|
|
|
+
|
|
|
+Lots of orphaned or duplicated macros in this header file. Clean
|
|
|
+those up a bit so it's less ugly.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.h | 89 +-------------------------------------
|
|
|
+ 1 file changed, 2 insertions(+), 87 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index b78d3b474a43..6502777eb5f3 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -37,68 +37,23 @@
|
|
|
+ */
|
|
|
+ #define ENABLE_NON_PREVIEW 1
|
|
|
+
|
|
|
+-#define OV5693_POWER_UP_RETRY_NUM 5
|
|
|
+-
|
|
|
+ /* Defines for register writes and register array processing */
|
|
|
+-#define I2C_MSG_LENGTH 0x2
|
|
|
+-#define I2C_RETRY_COUNT 5
|
|
|
+-
|
|
|
+-#define OV5693_FOCAL_LENGTH_NUM 334 /*3.34mm*/
|
|
|
+-#define OV5693_FOCAL_LENGTH_DEM 100
|
|
|
+-#define OV5693_F_NUMBER_DEFAULT_NUM 24
|
|
|
+-#define OV5693_F_NUMBER_DEM 10
|
|
|
++#define I2C_MSG_LENGTH 0x2
|
|
|
+
|
|
|
+ #define MAX_FMTS 1
|
|
|
+
|
|
|
+-/* sensor_mode_data read_mode adaptation */
|
|
|
+-#define OV5693_READ_MODE_BINNING_ON 0x0400
|
|
|
+-#define OV5693_READ_MODE_BINNING_OFF 0x00
|
|
|
+-#define OV5693_INTEGRATION_TIME_MARGIN 8
|
|
|
+-
|
|
|
+-#define OV5693_MAX_EXPOSURE_VALUE 0xFFF1
|
|
|
+-#define OV5693_MAX_GAIN_VALUE 0xFF
|
|
|
+-
|
|
|
+-/*
|
|
|
+- * focal length bits definition:
|
|
|
+- * bits 31-16: numerator, bits 15-0: denominator
|
|
|
+- */
|
|
|
+-#define OV5693_FOCAL_LENGTH_DEFAULT 0x1B70064
|
|
|
+-
|
|
|
+-/*
|
|
|
+- * current f-number bits definition:
|
|
|
+- * bits 31-16: numerator, bits 15-0: denominator
|
|
|
+- */
|
|
|
+-#define OV5693_F_NUMBER_DEFAULT 0x18000a
|
|
|
+-
|
|
|
+-/*
|
|
|
+- * f-number range bits definition:
|
|
|
+- * bits 31-24: max f-number numerator
|
|
|
+- * bits 23-16: max f-number denominator
|
|
|
+- * bits 15-8: min f-number numerator
|
|
|
+- * bits 7-0: min f-number denominator
|
|
|
+- */
|
|
|
+-#define OV5693_F_NUMBER_RANGE 0x180a180a
|
|
|
+ #define OV5693_ID 0x5690
|
|
|
+
|
|
|
+-#define OV5693_FINE_INTG_TIME_MIN 0
|
|
|
+-#define OV5693_FINE_INTG_TIME_MAX_MARGIN 0
|
|
|
+-#define OV5693_COARSE_INTG_TIME_MIN 1
|
|
|
+-#define OV5693_COARSE_INTG_TIME_MAX_MARGIN 6
|
|
|
+-
|
|
|
+-#define OV5693_BIN_FACTOR_MAX 4
|
|
|
+ /*
|
|
|
+ * OV5693 System control registers
|
|
|
+ */
|
|
|
+-#define OV5693_SW_SLEEP 0x0100
|
|
|
+ #define OV5693_SW_RESET 0x0103
|
|
|
+ #define OV5693_SW_STREAM 0x0100
|
|
|
+
|
|
|
+ #define OV5693_SC_CMMN_CHIP_ID_H 0x300A
|
|
|
+ #define OV5693_SC_CMMN_CHIP_ID_L 0x300B
|
|
|
+-#define OV5693_SC_CMMN_SCCB_ID 0x300C
|
|
|
+ #define OV5693_SC_CMMN_SUB_ID 0x302A /* process, version*/
|
|
|
+-/*Bit[7:4] Group control, Bit[3:0] Group ID*/
|
|
|
+-#define OV5693_GROUP_ACCESS 0x3208
|
|
|
++
|
|
|
+ /*
|
|
|
+ *Bit[3:0] Bit[19:16] of exposure,
|
|
|
+ *remaining 16 bits lies in Reg0x3501&Reg0x3502
|
|
|
+@@ -110,18 +65,6 @@
|
|
|
+ #define OV5693_AGC_H 0x350A
|
|
|
+ #define OV5693_AGC_L 0x350B /*Bit[7:0] of gain*/
|
|
|
+
|
|
|
+-#define OV5693_HORIZONTAL_START_H 0x3800 /*Bit[11:8]*/
|
|
|
+-#define OV5693_HORIZONTAL_START_L 0x3801 /*Bit[7:0]*/
|
|
|
+-#define OV5693_VERTICAL_START_H 0x3802 /*Bit[11:8]*/
|
|
|
+-#define OV5693_VERTICAL_START_L 0x3803 /*Bit[7:0]*/
|
|
|
+-#define OV5693_HORIZONTAL_END_H 0x3804 /*Bit[11:8]*/
|
|
|
+-#define OV5693_HORIZONTAL_END_L 0x3805 /*Bit[7:0]*/
|
|
|
+-#define OV5693_VERTICAL_END_H 0x3806 /*Bit[11:8]*/
|
|
|
+-#define OV5693_VERTICAL_END_L 0x3807 /*Bit[7:0]*/
|
|
|
+-#define OV5693_HORIZONTAL_OUTPUT_SIZE_H 0x3808 /*Bit[3:0]*/
|
|
|
+-#define OV5693_HORIZONTAL_OUTPUT_SIZE_L 0x3809 /*Bit[7:0]*/
|
|
|
+-#define OV5693_VERTICAL_OUTPUT_SIZE_H 0x380a /*Bit[3:0]*/
|
|
|
+-#define OV5693_VERTICAL_OUTPUT_SIZE_L 0x380b /*Bit[7:0]*/
|
|
|
+ /*High 8-bit, and low 8-bit HTS address is 0x380d*/
|
|
|
+ #define OV5693_TIMING_HTS_H 0x380C
|
|
|
+ /*High 8-bit, and low 8-bit HTS address is 0x380d*/
|
|
|
+@@ -141,34 +84,6 @@
|
|
|
+ #define OV5693_START_STREAMING 0x01
|
|
|
+ #define OV5693_STOP_STREAMING 0x00
|
|
|
+
|
|
|
+-#define VCM_ADDR 0x0c
|
|
|
+-#define VCM_CODE_MSB 0x04
|
|
|
+-
|
|
|
+-#define OV5693_INVALID_CONFIG 0xffffffff
|
|
|
+-
|
|
|
+-#define OV5693_VCM_SLEW_STEP 0x30F0
|
|
|
+-#define OV5693_VCM_SLEW_STEP_MAX 0x7
|
|
|
+-#define OV5693_VCM_SLEW_STEP_MASK 0x7
|
|
|
+-#define OV5693_VCM_CODE 0x30F2
|
|
|
+-#define OV5693_VCM_SLEW_TIME 0x30F4
|
|
|
+-#define OV5693_VCM_SLEW_TIME_MAX 0xffff
|
|
|
+-#define OV5693_VCM_ENABLE 0x8000
|
|
|
+-
|
|
|
+-#define OV5693_VCM_MAX_FOCUS_NEG -1023
|
|
|
+-#define OV5693_VCM_MAX_FOCUS_POS 1023
|
|
|
+-
|
|
|
+-#define DLC_ENABLE 1
|
|
|
+-#define DLC_DISABLE 0
|
|
|
+-#define VCM_PROTECTION_OFF 0xeca3
|
|
|
+-#define VCM_PROTECTION_ON 0xdc51
|
|
|
+-#define VCM_DEFAULT_S 0x0
|
|
|
+-#define vcm_step_s(a) (u8)(a & 0xf)
|
|
|
+-#define vcm_step_mclk(a) (u8)((a >> 4) & 0x3)
|
|
|
+-#define vcm_dlc_mclk(dlc, mclk) (u16)((dlc << 3) | mclk | 0xa104)
|
|
|
+-#define vcm_tsrc(tsrc) (u16)(tsrc << 3 | 0xf200)
|
|
|
+-#define vcm_val(data, s) (u16)(data << 4 | s)
|
|
|
+-#define DIRECT_VCM vcm_dlc_mclk(0, 0)
|
|
|
+-
|
|
|
+ /* Defines for OTP Data Registers */
|
|
|
+ #define OV5693_FRAME_OFF_NUM 0x4202
|
|
|
+ #define OV5693_OTP_BYTE_MAX 32 //change to 32 as needed by otpdata
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 2cb9a2fe394eea0b1aa79effb5a6a6fd6c04664f Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Fri, 12 Feb 2021 16:19:09 +0000
|
|
|
+Subject: [PATCH] media: i2c: use devm_kzalloc() to initialise ov5693
|
|
|
+
|
|
|
+There's a memory leak in probe because we're not using devres; swtich
|
|
|
+so that we are.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 2 +-
|
|
|
+ 1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 313bc9177328..d092ed698eb3 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1425,7 +1425,7 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+
|
|
|
+ dev_info(&client->dev, "%s() called", __func__);
|
|
|
+
|
|
|
+- ov5693 = kzalloc(sizeof(*ov5693), GFP_KERNEL);
|
|
|
++ ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL);
|
|
|
+ if (!ov5693)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From c3881f7d460ab00663028af4fc1ebf3d18545664 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Fri, 12 Feb 2021 16:26:21 +0000
|
|
|
+Subject: [PATCH] media: i2c: Check for supported clk rate in probe
|
|
|
+
|
|
|
+The ov5693 driver is configured to support a 19.2MHz external clock only.
|
|
|
+Check that we do indeed have that value and if not, exit with -EINVAL.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 8 ++++++++
|
|
|
+ drivers/media/i2c/ov5693.h | 2 ++
|
|
|
+ 2 files changed, 10 insertions(+)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index d092ed698eb3..8082d37841da 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1421,6 +1421,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
|
|
|
+ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ {
|
|
|
+ struct ov5693_device *ov5693;
|
|
|
++ u32 clk_rate;
|
|
|
+ int ret = 0;
|
|
|
+
|
|
|
+ dev_info(&client->dev, "%s() called", __func__);
|
|
|
+@@ -1441,6 +1442,13 @@ static int ov5693_probe(struct i2c_client *client)
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
++ clk_rate = clk_get_rate(ov5693->clk);
|
|
|
++ if (clk_rate != OV5693_XVCLK_FREQ) {
|
|
|
++ dev_err(&client->dev, "Unsupported clk freq %u, expected %u\n",
|
|
|
++ clk_rate, OV5693_XVCLK_FREQ);
|
|
|
++ return -EINVAL;
|
|
|
++ }
|
|
|
++
|
|
|
+ ret = ov5693_configure_gpios(ov5693);
|
|
|
+ if (ret)
|
|
|
+ goto out_free;
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 6502777eb5f3..0dfbbe9a0ff2 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -100,6 +100,8 @@
|
|
|
+ #define OV5693_OTP_READ_ONETIME 16
|
|
|
+ #define OV5693_OTP_MODE_READ 1
|
|
|
+
|
|
|
++#define OV5693_XVCLK_FREQ 19200000
|
|
|
++
|
|
|
+ /* link freq and pixel rate required for IPU3 */
|
|
|
+ #define OV5693_LINK_FREQ_400MHZ 400000000
|
|
|
+ /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 8c9c4147b12bf81ca8ac1c2250fed0fb399546fb Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 13 Feb 2021 23:17:50 +0000
|
|
|
+Subject: [PATCH] media: i2c: Use devres to fetch gpios
|
|
|
+
|
|
|
+Use devres; it'll simplify error handling through this function
|
|
|
+and probe.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 22 +++++-----------------
|
|
|
+ 1 file changed, 5 insertions(+), 17 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 8082d37841da..c580159079d2 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1270,8 +1270,6 @@ static int ov5693_remove(struct i2c_client *client)
|
|
|
+
|
|
|
+ dev_info(&client->dev, "%s...\n", __func__);
|
|
|
+
|
|
|
+- gpiod_put(ov5693->reset);
|
|
|
+- gpiod_put(ov5693->indicator_led);
|
|
|
+ while (i--)
|
|
|
+ regulator_put(ov5693->supplies[i].consumer);
|
|
|
+
|
|
|
+@@ -1372,38 +1370,28 @@ static int ov5693_init_controls(struct ov5693_device *ov5693)
|
|
|
+
|
|
|
+ static int ov5693_configure_gpios(struct ov5693_device *ov5693)
|
|
|
+ {
|
|
|
+- int ret;
|
|
|
+-
|
|
|
+- ov5693->reset = gpiod_get_optional(&ov5693->client->dev, "reset",
|
|
|
++ ov5693->reset = devm_gpiod_get_optional(&ov5693->client->dev, "reset",
|
|
|
+ GPIOD_OUT_HIGH);
|
|
|
+ if (IS_ERR(ov5693->reset)) {
|
|
|
+ dev_err(&ov5693->client->dev, "Couldn't find reset GPIO\n");
|
|
|
+ return PTR_ERR(ov5693->reset);
|
|
|
+ }
|
|
|
+
|
|
|
+- ov5693->powerdown = gpiod_get_optional(&ov5693->client->dev, "powerdown",
|
|
|
++ ov5693->powerdown = devm_gpiod_get_optional(&ov5693->client->dev, "powerdown",
|
|
|
+ GPIOD_OUT_HIGH);
|
|
|
+ if (IS_ERR(ov5693->powerdown)) {
|
|
|
+ dev_err(&ov5693->client->dev, "Couldn't find powerdown GPIO\n");
|
|
|
+- ret = PTR_ERR(ov5693->powerdown);
|
|
|
+- goto err_put_reset;
|
|
|
++ return PTR_ERR(ov5693->powerdown);
|
|
|
+ }
|
|
|
+
|
|
|
+- ov5693->indicator_led = gpiod_get_optional(&ov5693->client->dev, "indicator-led",
|
|
|
++ ov5693->indicator_led = devm_gpiod_get_optional(&ov5693->client->dev, "indicator-led",
|
|
|
+ GPIOD_OUT_HIGH);
|
|
|
+ if (IS_ERR(ov5693->indicator_led)) {
|
|
|
+ dev_err(&ov5693->client->dev, "Couldn't find indicator-led GPIO\n");
|
|
|
+- ret = PTR_ERR(ov5693->indicator_led);
|
|
|
+- goto err_put_powerdown;
|
|
|
++ return PTR_ERR(ov5693->indicator_led);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+-err_put_reset:
|
|
|
+- gpiod_put(ov5693->reset);
|
|
|
+-err_put_powerdown:
|
|
|
+- gpiod_put(ov5693->powerdown);
|
|
|
+-
|
|
|
+- return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ static int ov5693_get_regulators(struct ov5693_device *ov5693)
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From c3291b3ac09027634975e779df81fda093a35db8 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sat, 13 Feb 2021 23:20:47 +0000
|
|
|
+Subject: [PATCH] media: i2c: Use devres to fetch regulators
|
|
|
+
|
|
|
+As before, use devres to simplify error handling and driver removal
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 6 +-----
|
|
|
+ 1 file changed, 1 insertion(+), 5 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index c580159079d2..9f61b470f8ba 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -1266,13 +1266,9 @@ static int ov5693_remove(struct i2c_client *client)
|
|
|
+ {
|
|
|
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
|
|
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- unsigned int i = OV5693_NUM_SUPPLIES;
|
|
|
+
|
|
|
+ dev_info(&client->dev, "%s...\n", __func__);
|
|
|
+
|
|
|
+- while (i--)
|
|
|
+- regulator_put(ov5693->supplies[i].consumer);
|
|
|
+-
|
|
|
+ v4l2_async_unregister_subdev(sd);
|
|
|
+
|
|
|
+ media_entity_cleanup(&ov5693->sd.entity);
|
|
|
+@@ -1401,7 +1397,7 @@ static int ov5693_get_regulators(struct ov5693_device *ov5693)
|
|
|
+ for (i = 0; i < OV5693_NUM_SUPPLIES; i++)
|
|
|
+ ov5693->supplies[i].supply = ov5693_supply_names[i];
|
|
|
+
|
|
|
+- return regulator_bulk_get(&ov5693->client->dev,
|
|
|
++ return devm_regulator_bulk_get(&ov5693->client->dev,
|
|
|
+ OV5693_NUM_SUPPLIES,
|
|
|
+ ov5693->supplies);
|
|
|
+ }
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From 28c672a3b4746e7423a3995361e0f78c2618b045 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sun, 14 Feb 2021 12:39:14 +0000
|
|
|
+Subject: [PATCH] media: i2c: remove debug print
|
|
|
+
|
|
|
+The exposure configure function has a debug print. It's working fine,
|
|
|
+so bin it.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 37 -------------------------------------
|
|
|
+ 1 file changed, 37 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 9f61b470f8ba..622a7ddf4063 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -526,41 +526,6 @@ static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Exposure */
|
|
|
+-
|
|
|
+-static int ov5693_get_exposure(struct ov5693_device *ov5693)
|
|
|
+-{
|
|
|
+- u32 exposure = 0;
|
|
|
+- u16 tmp;
|
|
|
+- int ret = 0;
|
|
|
+-
|
|
|
+- /* get exposure */
|
|
|
+- ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+- OV5693_EXPOSURE_L,
|
|
|
+- &tmp);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- exposure |= ((tmp >> 4) & 0b1111);
|
|
|
+-
|
|
|
+- ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+- OV5693_EXPOSURE_M,
|
|
|
+- &tmp);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- exposure |= (tmp << 4);
|
|
|
+- ret = ov5693_read_reg(ov5693->client, OV5693_8BIT,
|
|
|
+- OV5693_EXPOSURE_H,
|
|
|
+- &tmp);
|
|
|
+- if (ret)
|
|
|
+- return ret;
|
|
|
+-
|
|
|
+- exposure |= (tmp << 12);
|
|
|
+-
|
|
|
+- printk("exposure set to: %u\n", exposure);
|
|
|
+- return ret;
|
|
|
+-}
|
|
|
+-
|
|
|
+ static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+@@ -571,7 +536,6 @@ static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
|
|
|
+ */
|
|
|
+ exposure = exposure * 16;
|
|
|
+
|
|
|
+- ov5693_get_exposure(ov5693);
|
|
|
+ ret = ov5693_write_reg(ov5693->client, OV5693_8BIT,
|
|
|
+ OV5693_EXPOSURE_CTRL_HH_REG, OV5693_EXPOSURE_CTRL_HH(exposure));
|
|
|
+ if (ret)
|
|
|
+@@ -586,7 +550,6 @@ static int ov5693_exposure_configure(struct ov5693_device *ov5693, u32 exposure)
|
|
|
+ OV5693_EXPOSURE_CTRL_L_REG, OV5693_EXPOSURE_CTRL_L(exposure));
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+- ov5693_get_exposure(ov5693);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From af898b2bae16e9e8afaf7408a2dc7ecf503ac2f2 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sun, 14 Feb 2021 14:32:50 +0000
|
|
|
+Subject: [PATCH] media: i2c: Remove unused resolutions from ov5693
|
|
|
+
|
|
|
+The list of resolutions in here is really unmaintanably long. For now just
|
|
|
+bin all of the ones that are not part of ov5693_res_video, which is the
|
|
|
+only array of resolutions in use anyway.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.h | 357 +------------------------------------
|
|
|
+ 1 file changed, 1 insertion(+), 356 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 0dfbbe9a0ff2..29e6735112da 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -474,34 +474,7 @@ static struct ov5693_reg const ov5693_global_setting[] = {
|
|
|
+ };
|
|
|
+
|
|
|
+ #if ENABLE_NON_PREVIEW
|
|
|
+-/*
|
|
|
+- * 654x496 30fps 17ms VBlanking 2lane 10Bit (Scaling)
|
|
|
+- */
|
|
|
+-static struct ov5693_reg const ov5693_654x496[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x3d},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe6},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc7},
|
|
|
+- {OV5693_8BIT, 0x3803, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3806, 0x07},
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa3},
|
|
|
+- {OV5693_8BIT, 0x3808, 0x02},
|
|
|
+- {OV5693_8BIT, 0x3809, 0x90},
|
|
|
+- {OV5693_8BIT, 0x380a, 0x01},
|
|
|
+- {OV5693_8BIT, 0x380b, 0xf0},
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07},
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0},
|
|
|
+- {OV5693_8BIT, 0x3811, 0x08},
|
|
|
+- {OV5693_8BIT, 0x3813, 0x02},
|
|
|
+- {OV5693_8BIT, 0x3814, 0x31},
|
|
|
+- {OV5693_8BIT, 0x3815, 0x31},
|
|
|
+- {OV5693_8BIT, 0x3820, 0x04},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
++
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 1296x976 30fps 17ms VBlanking 2lane 10Bit (Scaling)
|
|
|
+@@ -660,62 +633,10 @@ static struct ov5693_reg const ov5693_736x496[] = {
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+
|
|
|
+-/*
|
|
|
+-static struct ov5693_reg const ov5693_736x496[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x7b},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe6},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3803, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3806, 0x07},
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa3},
|
|
|
+- {OV5693_8BIT, 0x3808, 0x02},
|
|
|
+- {OV5693_8BIT, 0x3809, 0xe0},
|
|
|
+- {OV5693_8BIT, 0x380a, 0x01},
|
|
|
+- {OV5693_8BIT, 0x380b, 0xf0},
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0d},
|
|
|
+- {OV5693_8BIT, 0x380d, 0xb0},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x05},
|
|
|
+- {OV5693_8BIT, 0x380f, 0xf2},
|
|
|
+- {OV5693_8BIT, 0x3811, 0x08},
|
|
|
+- {OV5693_8BIT, 0x3813, 0x02},
|
|
|
+- {OV5693_8BIT, 0x3814, 0x31},
|
|
|
+- {OV5693_8BIT, 0x3815, 0x31},
|
|
|
+- {OV5693_8BIT, 0x3820, 0x01},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1f},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+-*/
|
|
|
+ /*
|
|
|
+ * 976x556 30fps 8.8ms VBlanking 2lane 10Bit (Scaling)
|
|
|
+ */
|
|
|
+ #if ENABLE_NON_PREVIEW
|
|
|
+-static struct ov5693_reg const ov5693_976x556[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x7b},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe2},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3803, 0xf0},
|
|
|
+- {OV5693_8BIT, 0x3806, 0x06},
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa7},
|
|
|
+- {OV5693_8BIT, 0x3808, 0x03},
|
|
|
+- {OV5693_8BIT, 0x3809, 0xd0},
|
|
|
+- {OV5693_8BIT, 0x380a, 0x02},
|
|
|
+- {OV5693_8BIT, 0x380b, 0x2C},
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07},
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0},
|
|
|
+- {OV5693_8BIT, 0x3811, 0x10},
|
|
|
+- {OV5693_8BIT, 0x3813, 0x02},
|
|
|
+- {OV5693_8BIT, 0x3814, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3815, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x80},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+
|
|
|
+ /*DS from 2624x1492*/
|
|
|
+ static struct ov5693_reg const ov5693_1296x736[] = {
|
|
|
+@@ -782,40 +703,6 @@ static struct ov5693_reg const ov5693_1636p_30fps[] = {
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+
|
|
|
+-static struct ov5693_reg const ov5693_1616x1216_30fps[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x7b},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x80},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe2},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3800, 0x00}, /*{3800,3801} Array X start*/
|
|
|
+- {OV5693_8BIT, 0x3801, 0x08}, /* 04 //{3800,3801} Array X start*/
|
|
|
+- {OV5693_8BIT, 0x3802, 0x00}, /*{3802,3803} Array Y start*/
|
|
|
+- {OV5693_8BIT, 0x3803, 0x04}, /* 00 //{3802,3803} Array Y start*/
|
|
|
+- {OV5693_8BIT, 0x3804, 0x0a}, /*{3804,3805} Array X end*/
|
|
|
+- {OV5693_8BIT, 0x3805, 0x37}, /* 3b //{3804,3805} Array X end*/
|
|
|
+- {OV5693_8BIT, 0x3806, 0x07}, /*{3806,3807} Array Y end*/
|
|
|
+- {OV5693_8BIT, 0x3807, 0x9f}, /* a3 //{3806,3807} Array Y end*/
|
|
|
+- {OV5693_8BIT, 0x3808, 0x06}, /*{3808,3809} Final output H size*/
|
|
|
+- {OV5693_8BIT, 0x3809, 0x50}, /*{3808,3809} Final output H size*/
|
|
|
+- {OV5693_8BIT, 0x380a, 0x04}, /*{380a,380b} Final output V size*/
|
|
|
+- {OV5693_8BIT, 0x380b, 0xc0}, /*{380a,380b} Final output V size*/
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a}, /*{380c,380d} HTS*/
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80}, /*{380c,380d} HTS*/
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07}, /*{380e,380f} VTS*/
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0}, /* bc //{380e,380f} VTS*/
|
|
|
+- {OV5693_8BIT, 0x3810, 0x00}, /*{3810,3811} windowing X offset*/
|
|
|
+- {OV5693_8BIT, 0x3811, 0x10}, /*{3810,3811} windowing X offset*/
|
|
|
+- {OV5693_8BIT, 0x3812, 0x00}, /*{3812,3813} windowing Y offset*/
|
|
|
+- {OV5693_8BIT, 0x3813, 0x06}, /*{3812,3813} windowing Y offset*/
|
|
|
+- {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/
|
|
|
+- {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/
|
|
|
+- {OV5693_8BIT, 0x3820, 0x00}, /*FLIP/Binnning control*/
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/
|
|
|
+- {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_8BIT, 0x5041, 0x84},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+-
|
|
|
+ /*
|
|
|
+ * 1940x1096 30fps 8.8ms VBlanking 2lane 10bit (Scaling)
|
|
|
+ */
|
|
|
+@@ -878,37 +765,6 @@ static struct ov5693_reg const ov5693_2592x1456_30fps[] = {
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+
|
|
|
+-static struct ov5693_reg const ov5693_2576x1456_30fps[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x7b},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe2},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3800, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3801, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3802, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3803, 0xf0},
|
|
|
+- {OV5693_8BIT, 0x3804, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x3805, 0x3f},
|
|
|
+- {OV5693_8BIT, 0x3806, 0x06},
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa4},
|
|
|
+- {OV5693_8BIT, 0x3808, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x3809, 0x10},
|
|
|
+- {OV5693_8BIT, 0x380a, 0x05},
|
|
|
+- {OV5693_8BIT, 0x380b, 0xb0},
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07},
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0},
|
|
|
+- {OV5693_8BIT, 0x3811, 0x18},
|
|
|
+- {OV5693_8BIT, 0x3813, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3814, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3815, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+-
|
|
|
+ /*
|
|
|
+ * 2592x1944 30fps 0.6ms VBlanking 2lane 10Bit
|
|
|
+ */
|
|
|
+@@ -940,49 +796,6 @@ static struct ov5693_reg const ov5693_2592x1944_30fps[] = {
|
|
|
+ };
|
|
|
+ #endif
|
|
|
+
|
|
|
+-/*
|
|
|
+- * 11:9 Full FOV Output, expected FOV Res: 2346x1920
|
|
|
+- * ISP Effect Res: 1408x1152
|
|
|
+- * Sensor out: 1424x1168, DS From: 2380x1952
|
|
|
+- *
|
|
|
+- * WA: Left Offset: 8, Hor scal: 64
|
|
|
+- */
|
|
|
+-#if ENABLE_NON_PREVIEW
|
|
|
+-static struct ov5693_reg const ov5693_1424x1168_30fps[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x3b}, /* long exposure[15:8] */
|
|
|
+- {OV5693_8BIT, 0x3502, 0x80}, /* long exposure[7:0] */
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe2},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3800, 0x00}, /* TIMING_X_ADDR_START */
|
|
|
+- {OV5693_8BIT, 0x3801, 0x50}, /* 80 */
|
|
|
+- {OV5693_8BIT, 0x3802, 0x00}, /* TIMING_Y_ADDR_START */
|
|
|
+- {OV5693_8BIT, 0x3803, 0x02}, /* 2 */
|
|
|
+- {OV5693_8BIT, 0x3804, 0x09}, /* TIMING_X_ADDR_END */
|
|
|
+- {OV5693_8BIT, 0x3805, 0xdd}, /* 2525 */
|
|
|
+- {OV5693_8BIT, 0x3806, 0x07}, /* TIMING_Y_ADDR_END */
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa1}, /* 1953 */
|
|
|
+- {OV5693_8BIT, 0x3808, 0x05}, /* TIMING_X_OUTPUT_SIZE */
|
|
|
+- {OV5693_8BIT, 0x3809, 0x90}, /* 1424 */
|
|
|
+- {OV5693_8BIT, 0x380a, 0x04}, /* TIMING_Y_OUTPUT_SIZE */
|
|
|
+- {OV5693_8BIT, 0x380b, 0x90}, /* 1168 */
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a}, /* TIMING_HTS */
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07}, /* TIMING_VTS */
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0},
|
|
|
+- {OV5693_8BIT, 0x3810, 0x00}, /* TIMING_ISP_X_WIN */
|
|
|
+- {OV5693_8BIT, 0x3811, 0x02}, /* 2 */
|
|
|
+- {OV5693_8BIT, 0x3812, 0x00}, /* TIMING_ISP_Y_WIN */
|
|
|
+- {OV5693_8BIT, 0x3813, 0x00}, /* 0 */
|
|
|
+- {OV5693_8BIT, 0x3814, 0x11}, /* TIME_X_INC */
|
|
|
+- {OV5693_8BIT, 0x3815, 0x11}, /* TIME_Y_INC */
|
|
|
+- {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_8BIT, 0x5041, 0x84}, /* scale is auto enabled */
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+-#endif
|
|
|
+-
|
|
|
+ /*
|
|
|
+ * 3:2 Full FOV Output, expected FOV Res: 2560x1706
|
|
|
+ * ISP Effect Res: 720x480
|
|
|
+@@ -1022,173 +835,6 @@ static struct ov5693_reg const ov5693_736x496_30fps[] = {
|
|
|
+ {OV5693_TOK_TERM, 0, 0}
|
|
|
+ };
|
|
|
+
|
|
|
+-static struct ov5693_reg const ov5693_2576x1936_30fps[] = {
|
|
|
+- {OV5693_8BIT, 0x3501, 0x7b},
|
|
|
+- {OV5693_8BIT, 0x3502, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3708, 0xe2},
|
|
|
+- {OV5693_8BIT, 0x3709, 0xc3},
|
|
|
+- {OV5693_8BIT, 0x3803, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3806, 0x07},
|
|
|
+- {OV5693_8BIT, 0x3807, 0xa3},
|
|
|
+- {OV5693_8BIT, 0x3808, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x3809, 0x10},
|
|
|
+- {OV5693_8BIT, 0x380a, 0x07},
|
|
|
+- {OV5693_8BIT, 0x380b, 0x90},
|
|
|
+- {OV5693_8BIT, 0x380c, 0x0a},
|
|
|
+- {OV5693_8BIT, 0x380d, 0x80},
|
|
|
+- {OV5693_8BIT, 0x380e, 0x07},
|
|
|
+- {OV5693_8BIT, 0x380f, 0xc0},
|
|
|
+- {OV5693_8BIT, 0x3811, 0x18},
|
|
|
+- {OV5693_8BIT, 0x3813, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3814, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3815, 0x11},
|
|
|
+- {OV5693_8BIT, 0x3820, 0x00},
|
|
|
+- {OV5693_8BIT, 0x3821, 0x1e},
|
|
|
+- {OV5693_8BIT, 0x5002, 0x00},
|
|
|
+- {OV5693_TOK_TERM, 0, 0}
|
|
|
+-};
|
|
|
+-
|
|
|
+-static struct ov5693_resolution ov5693_res_preview[] = {
|
|
|
+- {
|
|
|
+- .desc = "ov5693_736x496_30fps",
|
|
|
+- .width = 736,
|
|
|
+- .height = 496,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_736x496_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_1616x1216_30fps",
|
|
|
+- .width = 1616,
|
|
|
+- .height = 1216,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_1616x1216_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_5M_30fps",
|
|
|
+- .width = 2576,
|
|
|
+- .height = 1456,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_2576x1456_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_5M_30fps",
|
|
|
+- .width = 2576,
|
|
|
+- .height = 1936,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_2576x1936_30fps,
|
|
|
+- },
|
|
|
+-};
|
|
|
+-
|
|
|
+-#define N_RES_PREVIEW (ARRAY_SIZE(ov5693_res_preview))
|
|
|
+-
|
|
|
+-/*
|
|
|
+- * Disable non-preview configurations until the configuration selection is
|
|
|
+- * improved.
|
|
|
+- */
|
|
|
+-#if ENABLE_NON_PREVIEW
|
|
|
+-struct ov5693_resolution ov5693_res_still[] = {
|
|
|
+- {
|
|
|
+- .desc = "ov5693_736x496_30fps",
|
|
|
+- .width = 736,
|
|
|
+- .height = 496,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_736x496_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_1424x1168_30fps",
|
|
|
+- .width = 1424,
|
|
|
+- .height = 1168,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_1424x1168_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_1616x1216_30fps",
|
|
|
+- .width = 1616,
|
|
|
+- .height = 1216,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_1616x1216_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_5M_30fps",
|
|
|
+- .width = 2592,
|
|
|
+- .height = 1456,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_2592x1456_30fps,
|
|
|
+- },
|
|
|
+- {
|
|
|
+- .desc = "ov5693_5M_30fps",
|
|
|
+- .width = 2592,
|
|
|
+- .height = 1944,
|
|
|
+- .pix_clk_freq = 160,
|
|
|
+- .fps = 30,
|
|
|
+- .used = 0,
|
|
|
+- .pixels_per_line = 2688,
|
|
|
+- .lines_per_frame = 1984,
|
|
|
+- .bin_factor_x = 1,
|
|
|
+- .bin_factor_y = 1,
|
|
|
+- .bin_mode = 0,
|
|
|
+- .regs = ov5693_2592x1944_30fps,
|
|
|
+- },
|
|
|
+-};
|
|
|
+-
|
|
|
+-#define N_RES_STILL (ARRAY_SIZE(ov5693_res_still))
|
|
|
+-
|
|
|
+ struct ov5693_resolution ov5693_res_video[] = {
|
|
|
+ {
|
|
|
+ .desc = "ov5693_736x496_30fps",
|
|
|
+@@ -1343,4 +989,3 @@ struct ov5693_resolution ov5693_res_video[] = {
|
|
|
+
|
|
|
+ static struct ov5693_resolution *ov5693_res = ov5693_res_video;
|
|
|
+ static unsigned long N_RES = N_RES_VIDEO;
|
|
|
+-#endif
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|
|
|
+From b048c8cca08fbe28af012cd2d0bd305579bc0d40 Mon Sep 17 00:00:00 2001
|
|
|
+From: Daniel Scally <djrscally@gmail.com>
|
|
|
+Date: Sun, 14 Feb 2021 14:45:58 +0000
|
|
|
+Subject: [PATCH] media: i2c: update set_fmt() for ov5693
|
|
|
+
|
|
|
+The set_fmt() function is a bit messy still, using home grown solutions to
|
|
|
+find the closest supported resolution instead of the v4l2 helpers. It also
|
|
|
+fails to update control ranges to account for the new mode (though this is
|
|
|
+moot currently as they're all the same, but the probably shouldn't be).
|
|
|
+
|
|
|
+Fix it up a little.
|
|
|
+
|
|
|
+Signed-off-by: Daniel Scally <djrscally@gmail.com>
|
|
|
+Patchset: cameras
|
|
|
+---
|
|
|
+ drivers/media/i2c/ov5693.c | 148 ++++++++++---------------------------
|
|
|
+ drivers/media/i2c/ov5693.h | 5 +-
|
|
|
+ 2 files changed, 40 insertions(+), 113 deletions(-)
|
|
|
+
|
|
|
+diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
|
|
|
+index 622a7ddf4063..09c84006d5c9 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.c
|
|
|
++++ b/drivers/media/i2c/ov5693.c
|
|
|
+@@ -753,7 +753,7 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+- ret = ov5693_write_reg_array(client, ov5693_res[ov5693->fmt_idx].regs);
|
|
|
++ ret = ov5693_write_reg_array(client, ov5693->mode->regs);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&client->dev, "ov5693 write register err.\n");
|
|
|
+ return ret;
|
|
|
+@@ -866,128 +866,56 @@ static int __maybe_unused ov5693_sensor_resume(struct device *dev)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+-/*
|
|
|
+- * distance - calculate the distance
|
|
|
+- * @res: resolution
|
|
|
+- * @w: width
|
|
|
+- * @h: height
|
|
|
+- *
|
|
|
+- * Get the gap between res_w/res_h and w/h.
|
|
|
+- * distance = (res_w/res_h - w/h) / (w/h) * 8192
|
|
|
+- * res->width/height smaller than w/h wouldn't be considered.
|
|
|
+- * The gap of ratio larger than 1/8 wouldn't be considered.
|
|
|
+- * Returns the value of gap or -1 if fail.
|
|
|
+- */
|
|
|
+-#define LARGEST_ALLOWED_RATIO_MISMATCH 1024
|
|
|
+-static int distance(struct ov5693_resolution *res, u32 w, u32 h)
|
|
|
+-{
|
|
|
+- int ratio;
|
|
|
+- int distance;
|
|
|
+-
|
|
|
+- if (w == 0 || h == 0 ||
|
|
|
+- res->width < w || res->height < h)
|
|
|
+- return -1;
|
|
|
+-
|
|
|
+- ratio = res->width << 13;
|
|
|
+- ratio /= w;
|
|
|
+- ratio *= h;
|
|
|
+- ratio /= res->height;
|
|
|
+-
|
|
|
+- distance = abs(ratio - 8192);
|
|
|
+-
|
|
|
+- if (distance > LARGEST_ALLOWED_RATIO_MISMATCH)
|
|
|
+- return -1;
|
|
|
+-
|
|
|
+- return distance;
|
|
|
+-}
|
|
|
+-
|
|
|
+-/* Return the nearest higher resolution index
|
|
|
+- * Firstly try to find the approximate aspect ratio resolution
|
|
|
+- * If we find multiple same AR resolutions, choose the
|
|
|
+- * minimal size.
|
|
|
+- */
|
|
|
+-static int nearest_resolution_index(int w, int h)
|
|
|
+-{
|
|
|
+- int i;
|
|
|
+- int idx = -1;
|
|
|
+- int dist;
|
|
|
+- int min_dist = INT_MAX;
|
|
|
+- int min_res_w = INT_MAX;
|
|
|
+- struct ov5693_resolution *tmp_res = NULL;
|
|
|
+-
|
|
|
+- for (i = 0; i < N_RES; i++) {
|
|
|
+- tmp_res = &ov5693_res[i];
|
|
|
+- dist = distance(tmp_res, w, h);
|
|
|
+- if (dist == -1)
|
|
|
+- continue;
|
|
|
+- if (dist < min_dist) {
|
|
|
+- min_dist = dist;
|
|
|
+- idx = i;
|
|
|
+- min_res_w = ov5693_res[i].width;
|
|
|
+- continue;
|
|
|
+- }
|
|
|
+- if (dist == min_dist && ov5693_res[i].width < min_res_w)
|
|
|
+- idx = i;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return idx;
|
|
|
+-}
|
|
|
+-
|
|
|
+-static int get_resolution_index(int w, int h)
|
|
|
+-{
|
|
|
+- int i;
|
|
|
+-
|
|
|
+- for (i = 0; i < N_RES; i++) {
|
|
|
+- if (w != ov5693_res[i].width)
|
|
|
+- continue;
|
|
|
+- if (h != ov5693_res[i].height)
|
|
|
+- continue;
|
|
|
+-
|
|
|
+- return i;
|
|
|
+- }
|
|
|
+-
|
|
|
+- return -1;
|
|
|
+-}
|
|
|
+-
|
|
|
+ static int ov5693_set_fmt(struct v4l2_subdev *sd,
|
|
|
+ struct v4l2_subdev_pad_config *cfg,
|
|
|
+ struct v4l2_subdev_format *format)
|
|
|
+ {
|
|
|
+- struct v4l2_mbus_framefmt *fmt = &format->format;
|
|
|
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+- struct i2c_client *client = v4l2_get_subdevdata(sd);
|
|
|
++ const struct ov5693_resolution *mode;
|
|
|
++ int exposure_max;
|
|
|
+ int ret = 0;
|
|
|
+- int idx;
|
|
|
++ int hblank;
|
|
|
+
|
|
|
+ if (format->pad)
|
|
|
+ return -EINVAL;
|
|
|
+- if (!fmt)
|
|
|
+- return -EINVAL;
|
|
|
+
|
|
|
+ mutex_lock(&ov5693->lock);
|
|
|
+- idx = nearest_resolution_index(fmt->width, fmt->height);
|
|
|
+- if (idx == -1) {
|
|
|
+- /* return the largest resolution */
|
|
|
+- fmt->width = ov5693_res[N_RES - 1].width;
|
|
|
+- fmt->height = ov5693_res[N_RES - 1].height;
|
|
|
+- } else {
|
|
|
+- fmt->width = ov5693_res[idx].width;
|
|
|
+- fmt->height = ov5693_res[idx].height;
|
|
|
+- }
|
|
|
+
|
|
|
+- fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
|
|
|
++ mode = v4l2_find_nearest_size(ov5693_res_video, ARRAY_SIZE(ov5693_res_video),
|
|
|
++ width, height, format->format.width,
|
|
|
++ format->format.height);
|
|
|
++
|
|
|
++ if (!mode)
|
|
|
++ return -EINVAL;
|
|
|
++
|
|
|
++ format->format.width = mode->width;
|
|
|
++ format->format.height = mode->height;
|
|
|
++ format->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
|
|
|
++
|
|
|
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
|
|
|
+- cfg->try_fmt = *fmt;
|
|
|
+- ret = 0;
|
|
|
++ *v4l2_subdev_get_try_format(sd, cfg, format->pad) = format->format;
|
|
|
+ goto mutex_unlock;
|
|
|
+ }
|
|
|
+
|
|
|
+- ov5693->fmt_idx = get_resolution_index(fmt->width, fmt->height);
|
|
|
+- if (ov5693->fmt_idx == -1) {
|
|
|
+- dev_err(&client->dev, "get resolution fail\n");
|
|
|
+- ret = -EINVAL;
|
|
|
+- goto mutex_unlock;
|
|
|
+- }
|
|
|
++ ov5693->mode = mode;
|
|
|
++
|
|
|
++ /* Update limits and set FPS to default */
|
|
|
++ __v4l2_ctrl_modify_range(ov5693->ctrls.vblank,
|
|
|
++ mode->lines_per_frame - mode->height,
|
|
|
++ OV5693_TIMING_MAX_VTS - mode->height,
|
|
|
++ 1, mode->lines_per_frame - mode->height);
|
|
|
++ __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank,
|
|
|
++ mode->lines_per_frame - mode->height);
|
|
|
++
|
|
|
++ hblank = mode->pixels_per_line - mode->width;
|
|
|
++ __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1, hblank);
|
|
|
++
|
|
|
++ exposure_max = mode->lines_per_frame - 8;
|
|
|
++ __v4l2_ctrl_modify_range(ov5693->ctrls.exposure,
|
|
|
++ ov5693->ctrls.exposure->minimum, exposure_max,
|
|
|
++ ov5693->ctrls.exposure->step,
|
|
|
++ ov5693->ctrls.exposure->val < exposure_max ?
|
|
|
++ ov5693->ctrls.exposure->val : exposure_max);
|
|
|
+
|
|
|
+ mutex_unlock:
|
|
|
+ mutex_unlock(&ov5693->lock);
|
|
|
+@@ -1056,8 +984,8 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
|
|
|
+ if (!fmt)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+- fmt->width = ov5693_res[ov5693->fmt_idx].width;
|
|
|
+- fmt->height = ov5693_res[ov5693->fmt_idx].height;
|
|
|
++ fmt->width = ov5693->mode->width;
|
|
|
++ fmt->height = ov5693->mode->height;
|
|
|
+ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+@@ -1174,7 +1102,7 @@ static int ov5693_g_frame_interval(struct v4l2_subdev *sd,
|
|
|
+ struct ov5693_device *ov5693 = to_ov5693_sensor(sd);
|
|
|
+
|
|
|
+ interval->interval.numerator = 1;
|
|
|
+- interval->interval.denominator = ov5693_res[ov5693->fmt_idx].fps;
|
|
|
++ interval->interval.denominator = ov5693->mode->fps;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+diff --git a/drivers/media/i2c/ov5693.h b/drivers/media/i2c/ov5693.h
|
|
|
+index 29e6735112da..0377853f8b2b 100644
|
|
|
+--- a/drivers/media/i2c/ov5693.h
|
|
|
++++ b/drivers/media/i2c/ov5693.h
|
|
|
+@@ -127,8 +127,8 @@ struct ov5693_resolution {
|
|
|
+ u8 *desc;
|
|
|
+ const struct ov5693_reg *regs;
|
|
|
+ int res;
|
|
|
+- int width;
|
|
|
+- int height;
|
|
|
++ u32 width;
|
|
|
++ u32 height;
|
|
|
+ int fps;
|
|
|
+ int pix_clk_freq;
|
|
|
+ u16 pixels_per_line;
|
|
|
+@@ -178,7 +178,6 @@ struct ov5693_device {
|
|
|
+ struct camera_sensor_platform_data *platform_data;
|
|
|
+ ktime_t timestamp_t_focus_abs;
|
|
|
+ int vt_pix_clk_freq_mhz;
|
|
|
+- int fmt_idx;
|
|
|
+ int run_mode;
|
|
|
+ int otp_size;
|
|
|
+ u8 *otp_data;
|
|
|
+--
|
|
|
+2.30.1
|
|
|
+
|