diff --git a/patches/5.10/0001-surface3-oemb.patch b/patches/5.10/0001-surface3-oemb.patch index c12faf343..e7d85ce5c 100644 --- a/patches/5.10/0001-surface3-oemb.patch +++ b/patches/5.10/0001-surface3-oemb.patch @@ -1,4 +1,4 @@ -From f696bf9c577af759678b5296ac4b944dbb188c9e Mon Sep 17 00:00:00 2001 +From 22340c14d342f06a997d3b5a89af9346de0a7435 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 18 Oct 2020 16:42:44 +0900 Subject: [PATCH] (surface3-oemb) add DMI matches for Surface 3 with broken DMI diff --git a/patches/5.10/0002-wifi.patch b/patches/5.10/0002-wifi.patch index db1b1e580..cac58ea2f 100644 --- a/patches/5.10/0002-wifi.patch +++ b/patches/5.10/0002-wifi.patch @@ -1,4 +1,4 @@ -From 7142aae4519bf0728c574940e21cc7ab2c4a9e0f Mon Sep 17 00:00:00 2001 +From 7b93499e4902acda6934cfb5f959f5e94e7f8044 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Thu, 24 Sep 2020 18:02:06 +0900 Subject: [PATCH] mwifiex: pcie: skip cancel_work_sync() on reset failure path @@ -156,7 +156,7 @@ index 843d57eda820..5ed613d65709 100644 -- 2.30.1 -From 8ee97a2be558e3ee3fbdcee4c3934ffc46df6a66 Mon Sep 17 00:00:00 2001 +From f5aa70330a4efb8cf636143ef9aa7e4904ad5127 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Mon, 28 Sep 2020 17:46:49 +0900 Subject: [PATCH] mwifiex: pcie: add DMI-based quirk impl for Surface devices @@ -364,7 +364,7 @@ index 000000000000..5326ae7e5671 -- 2.30.1 -From 012378c78ce0aa9f54e6233fb03f15ab662b4bff Mon Sep 17 00:00:00 2001 +From 24b69b7365838ea8b0d5f82ad3f180fa090012ed Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Tue, 29 Sep 2020 17:25:22 +0900 Subject: [PATCH] mwifiex: pcie: add reset_d3cold quirk for Surface gen4+ @@ -565,7 +565,7 @@ index 5326ae7e5671..8b9dcb5070d8 100644 -- 2.30.1 -From e0e72a8bd4641edbd1f4f3c386f8573b3359a713 Mon Sep 17 00:00:00 2001 +From 874ad16a7ebce9ad8c0e35108b9f2b2f0acb6356 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Tue, 29 Sep 2020 17:32:22 +0900 Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3 @@ -744,7 +744,7 @@ index 8b9dcb5070d8..3ef7440418e3 100644 -- 2.30.1 -From 7690864649999f7373e5800a04b4b053efb9232a Mon Sep 17 00:00:00 2001 +From fa1e5b2ce0632c6b9d95c7f6cd0b24791b5c9365 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Wed, 30 Sep 2020 18:08:24 +0900 Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI @@ -806,7 +806,7 @@ index f0a6fa0a7ae5..34dcd84f02a6 100644 -- 2.30.1 -From 9db151b0136ea9d7d9170020e0c74d45fa17a824 Mon Sep 17 00:00:00 2001 +From 919301a63938bca88969a454f0abdc3db27f1ad3 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Thu, 24 Sep 2020 01:56:34 +0900 Subject: [PATCH] mwifiex: pcie: use shutdown_sw()/reinit_sw() on @@ -948,7 +948,7 @@ index 94561ddaf126..7b25335f1df3 100644 -- 2.30.1 -From 3b864ce43d794995d3f3ea182ad5bff74be4a573 Mon Sep 17 00:00:00 2001 +From ebac0bf11dff3fa948916a759bae904fd960d05b Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Mon, 24 Aug 2020 17:11:35 +0900 Subject: [PATCH] mwifiex: pcie: add enable_device_dump module parameter @@ -997,7 +997,7 @@ index 7b25335f1df3..f7e0b86eb553 100644 -- 2.30.1 -From 31ab9786797227365c34354d842efe0aaf6e62dd Mon Sep 17 00:00:00 2001 +From 142fdbb7737b947c70e064ba916d24e895d8cb2a Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:11:49 +0900 Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+ @@ -1152,7 +1152,7 @@ index 3ef7440418e3..a95ebac06e13 100644 -- 2.30.1 -From 9c5b054473350dae8139e9b5c1ceea86b0560264 Mon Sep 17 00:00:00 2001 +From c0e83e93479fc6f348e1ec300412cc0971cc0427 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:25:48 +0900 Subject: [PATCH] mwifiex: add allow_ps_mode module parameter @@ -1214,7 +1214,7 @@ index a6b9dc6700b1..943bc1e8ceae 100644 -- 2.30.1 -From 635922ff9b7d620d892a0bf5757dbc852d432a2e Mon Sep 17 00:00:00 2001 +From 189cb0a5ea576d49e36b52ecf8316a2ceb5361c8 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:38:48 +0900 Subject: [PATCH] mwifiex: print message when changing ps_mode @@ -1249,7 +1249,7 @@ index 943bc1e8ceae..a2eb8df8d385 100644 -- 2.30.1 -From c53651a257e2f7af1daa566df43e7724ac75e04f Mon Sep 17 00:00:00 2001 +From d56d58a5b0ee3636946447789c88ce474b7b1006 Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Sun, 4 Oct 2020 00:59:37 +0900 Subject: [PATCH] mwifiex: disable ps_mode explicitly by default instead diff --git a/patches/5.10/0003-ipts.patch b/patches/5.10/0003-ipts.patch index 3e9383092..998218231 100644 --- a/patches/5.10/0003-ipts.patch +++ b/patches/5.10/0003-ipts.patch @@ -1,4 +1,4 @@ -From b0ddc5d69f3ed78e7689a7d1e143567fbc16e55e Mon Sep 17 00:00:00 2001 +From da1f68432e7f4aaf42d07ac2a84d379cd1de4f4c Mon Sep 17 00:00:00 2001 From: Dorian Stoll Date: Thu, 30 Jul 2020 13:21:53 +0200 Subject: [PATCH] misc: mei: Add missing IPTS device IDs @@ -36,7 +36,7 @@ index 1de9ef7a272b..e12484840f88 100644 -- 2.30.1 -From 23313b15879627928315f6d97d1002264dc511f7 Mon Sep 17 00:00:00 2001 +From 8dacfcecc5c09994fbc750d50e063a5e2db72c65 Mon Sep 17 00:00:00 2001 From: Dorian Stoll Date: Thu, 6 Aug 2020 11:20:41 +0200 Subject: [PATCH] misc: Add support for Intel Precise Touch & Stylus diff --git a/patches/5.10/0004-surface-gpe.patch b/patches/5.10/0004-surface-gpe.patch index 9bc615abb..ed5129469 100644 --- a/patches/5.10/0004-surface-gpe.patch +++ b/patches/5.10/0004-surface-gpe.patch @@ -1,4 +1,4 @@ -From ae725f58a769c0b98d72e612af0657fd21801ef4 Mon Sep 17 00:00:00 2001 +From e8a3fc1564b60e6a55a0ee1616731d584feeabaf Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sun, 16 Aug 2020 23:39:56 +0200 Subject: [PATCH] platform/x86: Add Driver to set up lid GPEs on MS Surface diff --git a/patches/5.10/0005-surface-sam-over-hid.patch b/patches/5.10/0005-surface-sam-over-hid.patch index 325f0c5ee..b3033c560 100644 --- a/patches/5.10/0005-surface-sam-over-hid.patch +++ b/patches/5.10/0005-surface-sam-over-hid.patch @@ -1,4 +1,4 @@ -From 7fcb1bb56b0aeef64bb650f5cd7e40d56c1b8a06 Mon Sep 17 00:00:00 2001 +From b5f61c00e82a5552d5c48a538442c103d730b1fe Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 25 Jul 2020 17:19:53 +0200 Subject: [PATCH] i2c: acpi: Implement RawBytes read access @@ -110,7 +110,7 @@ index 37c510d9347a..aed579942436 100644 -- 2.30.1 -From 636027109cba56a411620d37a35fb9b56d6ec302 Mon Sep 17 00:00:00 2001 +From 3e4f517c369e8356fea37f130ff284343ca5cd15 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sun, 6 Sep 2020 04:01:19 +0200 Subject: [PATCH] platform/x86: Add driver for Surface Book 1 dGPU switch diff --git a/patches/5.10/0006-surface-sam.patch b/patches/5.10/0006-surface-sam.patch index 986f3a5cf..00928e88f 100644 --- a/patches/5.10/0006-surface-sam.patch +++ b/patches/5.10/0006-surface-sam.patch @@ -1,4 +1,4 @@ -From ba3917a0ce79087cc77219c47d2aa9fb9b7f0b9b Mon Sep 17 00:00:00 2001 +From 96a6523e58defc8462ccb29cff2b9d07b21c8ed5 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 17 Aug 2020 01:23:20 +0200 Subject: [PATCH] Add file2alias support for Surface Aggregator Module devices @@ -99,7 +99,7 @@ index 2417dd1dee33..a6c583362b92 100644 -- 2.30.1 -From 18dfadbd32eae7eb88d5062564daf977c62d9c67 Mon Sep 17 00:00:00 2001 +From 23b5e1e8212af0785a88344444b01d0040d6ab7f Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 17 Aug 2020 01:44:30 +0200 Subject: [PATCH] platform/x86: Add support for Surface System Aggregator diff --git a/patches/5.10/0007-surface-hotplug.patch b/patches/5.10/0007-surface-hotplug.patch index 33e6ae957..a34c23971 100644 --- a/patches/5.10/0007-surface-hotplug.patch +++ b/patches/5.10/0007-surface-hotplug.patch @@ -1,4 +1,4 @@ -From 97b4cb5fe354ae2aa11a51bf0add7434f65da636 Mon Sep 17 00:00:00 2001 +From c210052439b7cbd1ddc4d25703087ad25cc240c7 Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 9 Nov 2020 14:23:00 +0100 Subject: [PATCH] PCI: Run platform power transition on initial D0 entry @@ -58,7 +58,7 @@ index 6427cbd0a5be..3200afed2604 100644 -- 2.30.1 -From e99a49e3321f5f210825bd1cd35b04f9aff73a92 Mon Sep 17 00:00:00 2001 +From 924f1ae4e5c625f6fddb4bbed1b915d9ef6dd12a Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Sat, 31 Oct 2020 20:46:33 +0100 Subject: [PATCH] PCI: Add sysfs attribute for PCI device power state @@ -131,7 +131,7 @@ index d15c881e2e7e..b15f754e6346 100644 -- 2.30.1 -From 0702027c25539792b81325e843377c54010d8d56 Mon Sep 17 00:00:00 2001 +From 6e3cc9d0f7e5541b219240ba4344444e25a0a99d Mon Sep 17 00:00:00 2001 From: Maximilian Luz Date: Mon, 14 Dec 2020 20:50:59 +0100 Subject: [PATCH] platform/x86: Add Surface Hotplug driver diff --git a/patches/5.10/0008-surface-typecover.patch b/patches/5.10/0008-surface-typecover.patch index 2a36afd44..d9c1f9a4d 100644 --- a/patches/5.10/0008-surface-typecover.patch +++ b/patches/5.10/0008-surface-typecover.patch @@ -1,4 +1,4 @@ -From e1b4a113984cf38f01c2a0e2bbf4e8192664ce0d Mon Sep 17 00:00:00 2001 +From 9929845c4ef162a6bc28f16e211a8b5781a39a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Thu, 5 Nov 2020 13:09:45 +0100 Subject: [PATCH] hid/multitouch: Turn off Type Cover keyboard backlight when diff --git a/patches/5.10/0009-surface-sensors.patch b/patches/5.10/0009-surface-sensors.patch index e850c098d..d23215b3c 100644 --- a/patches/5.10/0009-surface-sensors.patch +++ b/patches/5.10/0009-surface-sensors.patch @@ -1,4 +1,4 @@ -From 46132805b14e21b99d61fb2f35b459c638c87dca Mon Sep 17 00:00:00 2001 +From 1f0b9f668442306f8624e69a4066c81918e87ad1 Mon Sep 17 00:00:00 2001 From: Max Leiter Date: Sat, 19 Dec 2020 17:50:55 -0800 Subject: [PATCH] iio:light:apds9960 add detection for MSHW0184 ACPI device in diff --git a/patches/5.10/0010-cameras.patch b/patches/5.10/0010-cameras.patch index 64148940d..9858fd494 100644 --- a/patches/5.10/0010-cameras.patch +++ b/patches/5.10/0010-cameras.patch @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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" 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 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 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 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?= +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 +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?= +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 +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 + #include + #include ++#include + #include + #include + #include +@@ -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 +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 +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 +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 +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?= +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 + #include +-#include +-#include +-#include +-#include +-#include ++#include ++#include + #include ++#include + #include ++#include ++#include + #include +-#include +-#include +-#include +-#include ++#include + #include ++#include ++#include ++#include ++#include ++#include + #include + #include +-#include +-#include +-#include + + #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 +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 +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 + #include + #include ++#include + #include + #include + #include +@@ -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 +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 +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 + #include + #include +-#include + #include + #include + #include +@@ -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 +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 +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 + #include + #include +-#include + #include +-#include +-#include +-#include +-#include + #include +-#include + #include + #include + #include +-#include +-#include + #include + #include + +-- +2.30.1 + +From d9137b83092e75131784f32b2f43be8c2be1a13f Mon Sep 17 00:00:00 2001 +From: Daniel Scally +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 + diff --git a/pkg/arch/kernel/PKGBUILD b/pkg/arch/kernel/PKGBUILD index 681e67c7d..ce8dc4ca4 100644 --- a/pkg/arch/kernel/PKGBUILD +++ b/pkg/arch/kernel/PKGBUILD @@ -47,16 +47,16 @@ sha256sums=('8d2c3d8fc7b382c3db6b8bacbc7785e164150b952e706350f2a5a88d42939cb4' '47a5c0cbe4f75e77fe64953b516a6a9f277c1dfb812e31edf5cb25feb1b3819a' '3fbd134c61de6f4fa86567bb0faf02c4eb2c54111b6dc45367b8f6e9ef06556e' '8cd2b019aac6d3807a5cdcbbbe0aad81e63193ff3e8dffd7a79d4a1421b858f6' - 'eca6f81db4efc8d71a4f5dbaf1d6ca5b46202cb9a8ef5a7eff6b0bbe26a34a82' - 'a10905d215739fa148870e0a8fff03f3d101f48d1f7b8028e5460adfd1b8ac25' - '84438dad91d0375bf1c80859081e6b10d5fe9ce3127fed654d64a56aad820b13' - '34aab05229d9fb782ac8dad4ac411cfd7a4f24509ba385461997e1d40000153c' - 'e04a672f6bec169d37ee6584c5f1aa252277af1cd38b322eb70602e5bcaeae4d' - '8510597e396b72f898e58abcb77b6d356627720741a76d2551aeb0df4af5919f' - 'a6653fdaa655ee61dbc8118458a844fc9261ef2f2733b8ad83adda02cfbd65b2' - 'a9f815bc52a2610b3f0b8f878f564acab1d437ac20b7d83790cc7f67d644522f' - '16a0d17039426b4c5fb27fb13de0a4dc0b5fb42cacc5100c99b610b0571b8a86' - '3645b929503176a4ea671d47ac2b3a5bf6f2bd517b54d848d93934b049a9d0aa') + '3b0c98c7692bfd4c0d7d445dea512f7324ce8fb50950e34083c6bb5af4012b5f' + '1e9f900c6751a63fec52df04cba9ced1534b23bbaa930badf90c588bdae2dd0f' + '039f9d4091011fa9cc958572cbe9950b5eff42b34b00b3486bda2f85fb8833c6' + 'c47bdb34f113e0b1dfd8b4f6e6dbf6770386b55636d082b388645a55dbc76368' + '4d511f15b66e0de7bd3dcd1995b4c1b5f5ff0eb9c1ed489cb0c6d83d296e660a' + '7eb592269821aa028e5ae94d3e8a537b1c7ede50bea3afff5f5f8450f9ee8e87' + '09100432b00cfa9d1af9a45aa283e7272ab5984d0ef02395838a478671eb85f6' + 'de6b091ea03d0abf8b222ba492aeba7e2dd698461f8fed76bb824fd8159e93bf' + 'f3fc8a8d4e0504105abf17984234252893e324ed65410c0a60521ed7efe09a20' + 'ecad3021e4eef96f4fadb4a9794df3532ad3fdafffe64165b9b6a03b2a690494') export KBUILD_BUILD_HOST=archlinux