All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes
@ 2023-01-23 12:51 Hans de Goede
  2023-01-23 12:51 ` [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency Hans de Goede
                   ` (57 more replies)
  0 siblings, 58 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi All,

Here is another set of patches resulting from my continued work
on cleaning up / improving the atomisp driver.

The main changes here are power-management related, divided
into 2 sets:

1. Move the pm of the core atomisp device to its own custom PM
   domain. We turn the ISP on/off through the P-Unit and when
   off the PCI subsystem resume method complains about the PCI
   config space not being reachable. Changing to a custom PM
   domain fixes the logs getting filled with PCI subsys errors
   on every open of a /dev/video# node

2. Except for devices shipped with Android as factory image,
   all the DSDTs I have seen have proper ACPI pm code for
   the sensors. So we really should be using ACPI pm for this.

   This series contains a lot of ov2680 patches, including
   reworking the controls (so that control changes can be
   delayed to stream on time instead of directly trying to do
   i2c writes to the turned off sensor). Basically modernizing
   the ov2680 driver a lot (there are still some atomisp-isms left).

   And then finally after all the ov2680 cleanups it moves
   the ov2680 code over to using runtime-pm + ACPI pm,
   dropping all the direct PMIC + clk poking done by the
   atomisp_gmin_platform code.

Besides that this also contains quite a few other fixes / cleanups
for things which I encountered during the way and it contains the
start of making the ov2722 driver work. With the changes present
in that driver I get a working (but very dark) stream. I expect
that once I add a proper exposure control this will start working
better.

Regards,

Hans


Arnd Bergmann (1):
  media: atomisp: fix videobuf2 Kconfig depenendency

Brent Pappas (3):
  media: atomisp: pci: Replace bytes macros with functions
  media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD
    macros with functions
  media: atomisp: pci: sh_css: Inline single invocation of macro
    STATS_ENABLED()

Hans Verkuil (1):
  media: atomisp: use vb2_start_streaming_called()

Hans de Goede (52):
  media: atomisp: Remove atomisp_sw_contex struct
  media: atomisp: Move power-management over to a custom pm-domain
  media: atomisp: Silence "isys dma store at addr, val" debug messages
  media: atomisp: Remove non working doorbell check from
    punit_ddr_dvfs_enable()
  media: atomisp: Remove useless msleep(10) before power-on on BYT
  media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl
  media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl
  media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT
  media: atomisp: Remove no longer used binning info from sensor
    resolution info
  media: atomisp: Propagate set_fmt() errors in queue_setup()
  media: atomisp: Remove deferred firmware loading support
  media: atomisp: Check buffer index is in range inside
    atomisp_qbuf_wrapper()
  media: atomisp: Drop atomisp_init_pipe()
  media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls
  media: atomisp: Only set default_run_mode on first open of a
    stream/asd
  media: atomisp: Do not turn off sensor when the atomisp-sub-dev does
    not own it
  media: atomisp: Allow sensor drivers without a s_power callback
  media: atomisp: Fix regulator registers on BYT devices with CRC PMIC
  media: atomisp: Remove atomisp_gmin_find_subdev()
  media: atomisp: Add atomisp_register_sensor_no_gmin() helper
  media: atomisp: Fix WARN() when the vb2 start_streaming callback fails
  media: atomisp: Drop ffmt local var from atomisp_set_fmt()
  media: atomisp: Stop overriding padding w/h to 12 on BYT
  media: atomisp: Put sensor ACPI devices in D3 before disable ACPI
    power-resources
  media: atomisp: Remove isp_subdev_link_setup()
  media: Add ovxxxx_16bit_addr_reg_helpers.h
  media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h
  media: atomisp: ov2680: Rework flip ctrls
  media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support
  media: atomisp: ov2680: Add exposure and gain controls
  media: atomisp: ov2680: Add test pattern control
  media: atomisp: ov2680: Fix window settings and enable window for all
    resolutions
  media: atomisp: ov2680: Make setting the modes algorithm based
  media: atomisp: ov2680: Use defines for fps, lines-per-frame and
    skip-frames
  media: atomisp: ov2680: Drop unused res member from struct
    ov2680_device
  media: atomisp: ov2680: Fix ov2680_enum_frame_interval()
  media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from
    set_fmt()
  media: atomisp: ov2680: Drop struct ov2680_resolution /
    ov2680_res_preview
  media: atomisp: ov2680: Fix frame_size list
  media: atomisp: ov2680: Remove unused data-types and defines from
    ov2680.h
  media: atomisp: ov2680: Drop MAX_FMTS define
  media: atomisp: ov2680: Consistently indent define values
  media: atomisp: ov2680: Cleanup includes
  media: atomisp: ov2680: Delay power-on till streaming is started
  media: atomisp: ov2680: Add runtime-pm support
  media: atomisp: ov2680: s/dev/sensor/
  media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct
  media: atomisp: ov2680: Switch over to ACPI powermanagement
  media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe
    failure
  media: atomisp: ov2722: Fix GPIO1 polarity
  media: atomisp: ov2722: Don't take the input_lock for try_fmt calls.
  media: atomisp: ov2722: Power on sensor from set_fmt() callback

 drivers/staging/media/atomisp/Kconfig         |    2 +-
 .../media/atomisp/i2c/atomisp-gc0310.c        |  249 ----
 .../media/atomisp/i2c/atomisp-gc2235.c        |  176 ---
 .../media/atomisp/i2c/atomisp-mt9m114.c       |  206 ---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 1273 +++++------------
 .../media/atomisp/i2c/atomisp-ov2722.c        |  195 +--
 drivers/staging/media/atomisp/i2c/gc0310.h    |   10 -
 drivers/staging/media/atomisp/i2c/gc2235.h    |   31 -
 drivers/staging/media/atomisp/i2c/mt9m114.h   |   15 -
 drivers/staging/media/atomisp/i2c/ov2680.h    |  842 ++---------
 drivers/staging/media/atomisp/i2c/ov2722.h    |   36 +-
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c |  195 ---
 .../staging/media/atomisp/i2c/ov5693/ov5693.h |   61 -
 .../media/atomisp/include/linux/atomisp.h     |   50 -
 .../include/linux/atomisp_gmin_platform.h     |    2 -
 .../atomisp/include/linux/atomisp_platform.h  |   11 +-
 drivers/staging/media/atomisp/notes.txt       |    6 -
 .../staging/media/atomisp/pci/atomisp_cmd.c   |   90 +-
 .../staging/media/atomisp/pci/atomisp_cmd.h   |    9 +-
 .../staging/media/atomisp/pci/atomisp_fops.c  |   89 +-
 .../staging/media/atomisp/pci/atomisp_fops.h  |    3 +-
 .../media/atomisp/pci/atomisp_gmin_platform.c |  118 +-
 .../media/atomisp/pci/atomisp_internal.h      |    7 +-
 .../staging/media/atomisp/pci/atomisp_ioctl.c |   50 +-
 .../media/atomisp/pci/atomisp_subdev.c        |  169 +--
 .../media/atomisp/pci/atomisp_subdev.h        |   13 -
 .../staging/media/atomisp/pci/atomisp_v4l2.c  |  165 +--
 .../css_2401_system/host/isys_dma_private.h   |    2 -
 .../pci/hive_isp_css_common/host/vmem.c       |   20 +-
 drivers/staging/media/atomisp/pci/sh_css.c    |    7 +-
 .../staging/media/atomisp/pci/sh_css_params.c |   38 +-
 include/media/ovxxxx_16bit_addr_reg_helpers.h |   93 ++
 32 files changed, 862 insertions(+), 3371 deletions(-)
 create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h

-- 
2.39.0


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

* [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:12   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 02/57] media: atomisp: use vb2_start_streaming_called() Hans de Goede
                   ` (56 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Arnd Bergmann

From: Arnd Bergmann <arnd@arndb.de>

The recent conversion missed the Kconfig bit, so it can now
end up in a link error on randconfig builds:

ld.lld: error: undefined symbol: vb2_vmalloc_memops
>>> referenced by atomisp_fops.c
>>>               drivers/staging/media/atomisp/pci/atomisp_fops.o:(atomisp_open) in archive vmlinux.a

Fixes: cb48ae89be3b ("media: atomisp: Convert to videobuf2")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20230104082212.3770415-1-arnd@kernel.org
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig
index 2c8d7fdcc5f7..c9bff98e5309 100644
--- a/drivers/staging/media/atomisp/Kconfig
+++ b/drivers/staging/media/atomisp/Kconfig
@@ -14,7 +14,7 @@ config VIDEO_ATOMISP
 	depends on VIDEO_DEV && INTEL_ATOMISP
 	depends on PMIC_OPREGION
 	select IOSF_MBI
-	select VIDEOBUF_VMALLOC
+	select VIDEOBUF2_VMALLOC
 	select VIDEO_V4L2_SUBDEV_API
 	help
 	  Say Y here if your platform supports Intel Atom SoC
-- 
2.39.0


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

* [PATCH 02/57] media: atomisp: use vb2_start_streaming_called()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
  2023-01-23 12:51 ` [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct Hans de Goede
                   ` (55 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Hans Verkuil, Hans Verkuil

From: Hans Verkuil <hverkuil@xs4all.nl>

Don't touch q->start_streaming_called directly, use the
vb2_start_streaming_called() function instead.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Link: https://lore.kernel.org/r/bc6c24ec-72ea-64a1-9061-311cc7339827@xs4all.nl
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index cb01ba65c88f..4f35e8f8250a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -636,10 +636,10 @@ static int atomisp_enum_input(struct file *file, void *fh,
 static unsigned int
 atomisp_subdev_streaming_count(struct atomisp_sub_device *asd)
 {
-	return asd->video_out_preview.vb_queue.start_streaming_called
-	       + asd->video_out_capture.vb_queue.start_streaming_called
-	       + asd->video_out_video_capture.vb_queue.start_streaming_called
-	       + asd->video_out_vf.vb_queue.start_streaming_called;
+	return vb2_start_streaming_called(&asd->video_out_preview.vb_queue) +
+	       vb2_start_streaming_called(&asd->video_out_capture.vb_queue) +
+	       vb2_start_streaming_called(&asd->video_out_video_capture.vb_queue) +
+	       vb2_start_streaming_called(&asd->video_out_vf.vb_queue);
 }
 
 unsigned int atomisp_streaming_count(struct atomisp_device *isp)
-- 
2.39.0


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

* [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
  2023-01-23 12:51 ` [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency Hans de Goede
  2023-01-23 12:51 ` [PATCH 02/57] media: atomisp: use vb2_start_streaming_called() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:14   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 04/57] media: atomisp: Move power-management over to a custom pm-domain Hans de Goede
                   ` (54 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Remove the atomisp_sw_contex struct, it has only 1 member: running_freq,
instead store running_freq directly.

While at it also change running_freq from an int to an unsigned int,
all values stored in it are unsigned and it is compared to the also
unsigned new_freq variable.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_cmd.c      | 4 ++--
 drivers/staging/media/atomisp/pci/atomisp_fops.c     | 2 +-
 drivers/staging/media/atomisp/pci/atomisp_internal.h | 6 +-----
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index d8c7e7367386..5cea1df48b7d 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -280,14 +280,14 @@ int atomisp_freq_scaling(struct atomisp_device *isp,
 done:
 	dev_dbg(isp->dev, "DFS target frequency=%d.\n", new_freq);
 
-	if ((new_freq == isp->sw_contex.running_freq) && !force)
+	if ((new_freq == isp->running_freq) && !force)
 		return 0;
 
 	dev_dbg(isp->dev, "Programming DFS frequency to %d\n", new_freq);
 
 	ret = write_target_freq_to_hw(isp, new_freq);
 	if (!ret) {
-		isp->sw_contex.running_freq = new_freq;
+		isp->running_freq = new_freq;
 		trace_ipu_pstate(new_freq, -1);
 	}
 	return ret;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index acea7492847d..4643bb0db995 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -681,7 +681,7 @@ static void atomisp_dev_init_struct(struct atomisp_device *isp)
 	 * For Merrifield, frequency is scalable.
 	 * After boot-up, the default frequency is 200MHz.
 	 */
-	isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
+	isp->running_freq = ISP_FREQ_200MHZ;
 }
 
 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index 653e6d74a966..675007d7d9af 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -194,10 +194,6 @@ struct atomisp_regs {
 	u32 csi_access_viol;
 };
 
-struct atomisp_sw_contex {
-	int running_freq;
-};
-
 #define ATOMISP_DEVICE_STREAMING_DISABLED	0
 #define ATOMISP_DEVICE_STREAMING_ENABLED	1
 #define ATOMISP_DEVICE_STREAMING_STOPPING	2
@@ -242,7 +238,6 @@ struct atomisp_device {
 	struct v4l2_subdev *motor;
 
 	struct atomisp_regs saved_regs;
-	struct atomisp_sw_contex sw_contex;
 	struct atomisp_css_env css_env;
 
 	/* isp timeout status flag */
@@ -257,6 +252,7 @@ struct atomisp_device {
 	unsigned int mipi_frame_size;
 	const struct atomisp_dfs_config *dfs;
 	unsigned int hpll_freq;
+	unsigned int running_freq;
 
 	bool css_initialized;
 };
-- 
2.39.0


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

* [PATCH 04/57] media: atomisp: Move power-management over to a custom pm-domain
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (2 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages Hans de Goede
                   ` (53 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The atomisp does not use standard PCI power-management through the
PCI config space. Instead this driver directly tells the P-Unit to
disable the ISP over the IOSF. The standard PCI subsystem pm_ops will
try to access the config space before (resume) / after (suspend) this
driver has turned the ISP on / off, resulting in the following errors:

 Unable to change power state from D0 to D3hot, device inaccessible
 Unable to change power state from D3cold to D0, device inaccessible

Getting logged into dmesg a whole bunch of time during boot as well as
every time the camera is used.

To avoid these errors use a custom pm_domain instead of standard driver
pm-callbacks so that all the PCI subsys suspend / resume handling is
skipped and call pci_save_state() / pci_restore_state() ourselves.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/pci/atomisp_internal.h      |  1 +
 .../staging/media/atomisp/pci/atomisp_v4l2.c  | 44 ++++++++++++++-----
 2 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
index 675007d7d9af..fa38d91420cf 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
@@ -210,6 +210,7 @@ struct atomisp_device {
 	void __iomem *base;
 	const struct firmware *firmware;
 
+	struct dev_pm_domain pm_domain;
 	struct pm_qos_request pm_qos;
 	s32 max_isr_latency;
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index e786b81921da..e994a4a5284e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -19,6 +19,7 @@
  */
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_qos.h>
 #include <linux/timer.h>
@@ -524,7 +525,7 @@ static int atomisp_save_iunit_reg(struct atomisp_device *isp)
 	return 0;
 }
 
-static int __maybe_unused atomisp_restore_iunit_reg(struct atomisp_device *isp)
+static int atomisp_restore_iunit_reg(struct atomisp_device *isp)
 {
 	struct pci_dev *pdev = to_pci_dev(isp->dev);
 
@@ -662,6 +663,7 @@ static void punit_ddr_dvfs_enable(bool enable)
 
 static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
 {
+	struct pci_dev *pdev = to_pci_dev(isp->dev);
 	unsigned long timeout;
 	u32 val = enable ? MRFLD_ISPSSPM0_IUNIT_POWER_ON :
 			   MRFLD_ISPSSPM0_IUNIT_POWER_OFF;
@@ -703,6 +705,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
 		tmp = (tmp >> MRFLD_ISPSSPM0_ISPSSS_OFFSET) & MRFLD_ISPSSPM0_ISPSSC_MASK;
 		if (tmp == val) {
 			trace_ipu_cstate(enable);
+			pdev->current_state = enable ? PCI_D0 : PCI_D3cold;
 			return 0;
 		}
 
@@ -743,6 +746,7 @@ int atomisp_power_off(struct device *dev)
 	pci_write_config_dword(pdev, MRFLD_PCI_CSI_CONTROL, reg);
 
 	cpu_latency_qos_update_request(&isp->pm_qos, PM_QOS_DEFAULT_VALUE);
+	pci_save_state(pdev);
 	return atomisp_mrfld_power(isp, false);
 }
 
@@ -756,6 +760,7 @@ int atomisp_power_on(struct device *dev)
 	if (ret)
 		return ret;
 
+	pci_restore_state(to_pci_dev(dev));
 	cpu_latency_qos_update_request(&isp->pm_qos, isp->max_isr_latency);
 
 	/*restore register values for iUnit and iUnitPHY registers*/
@@ -767,7 +772,7 @@ int atomisp_power_on(struct device *dev)
 	return atomisp_css_init(isp);
 }
 
-static int __maybe_unused atomisp_suspend(struct device *dev)
+static int atomisp_suspend(struct device *dev)
 {
 	struct atomisp_device *isp = (struct atomisp_device *)
 				     dev_get_drvdata(dev);
@@ -790,10 +795,12 @@ static int __maybe_unused atomisp_suspend(struct device *dev)
 	}
 	spin_unlock_irqrestore(&isp->lock, flags);
 
+	pm_runtime_resume(dev);
+
 	return atomisp_power_off(dev);
 }
 
-static int __maybe_unused atomisp_resume(struct device *dev)
+static int atomisp_resume(struct device *dev)
 {
 	return atomisp_power_on(dev);
 }
@@ -1603,6 +1610,26 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 	/* save the iunit context only once after all the values are init'ed. */
 	atomisp_save_iunit_reg(isp);
 
+	/*
+	 * The atomisp does not use standard PCI power-management through the
+	 * PCI config space. Instead this driver directly tells the P-Unit to
+	 * disable the ISP over the IOSF. The standard PCI subsystem pm_ops will
+	 * try to access the config space before (resume) / after (suspend) this
+	 * driver has turned the ISP on / off, resulting in the following errors:
+	 *
+	 * "Unable to change power state from D0 to D3hot, device inaccessible"
+	 * "Unable to change power state from D3cold to D0, device inaccessible"
+	 *
+	 * To avoid these errors override the pm_domain so that all the PCI
+	 * subsys suspend / resume handling is skipped.
+	 */
+	isp->pm_domain.ops.runtime_suspend = atomisp_power_off;
+	isp->pm_domain.ops.runtime_resume = atomisp_power_on;
+	isp->pm_domain.ops.suspend = atomisp_suspend;
+	isp->pm_domain.ops.resume = atomisp_resume;
+
+	dev_pm_domain_set(&pdev->dev, &isp->pm_domain);
+
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_allow(&pdev->dev);
 
@@ -1645,6 +1672,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 request_irq_fail:
 	hmm_cleanup();
 	pm_runtime_get_noresume(&pdev->dev);
+	dev_pm_domain_set(&pdev->dev, NULL);
 	atomisp_unregister_entities(isp);
 register_entities_fail:
 	atomisp_uninitialize_modules(isp);
@@ -1697,6 +1725,7 @@ static void atomisp_pci_remove(struct pci_dev *pdev)
 
 	pm_runtime_forbid(&pdev->dev);
 	pm_runtime_get_noresume(&pdev->dev);
+	dev_pm_domain_set(&pdev->dev, NULL);
 	cpu_latency_qos_remove_request(&isp->pm_qos);
 
 	atomisp_msi_irq_uninit(isp);
@@ -1721,17 +1750,8 @@ static const struct pci_device_id atomisp_pci_tbl[] = {
 
 MODULE_DEVICE_TABLE(pci, atomisp_pci_tbl);
 
-static const struct dev_pm_ops atomisp_pm_ops = {
-	.runtime_suspend = atomisp_power_off,
-	.runtime_resume = atomisp_power_on,
-	.suspend = atomisp_suspend,
-	.resume = atomisp_resume,
-};
 
 static struct pci_driver atomisp_pci_driver = {
-	.driver = {
-		.pm = &atomisp_pm_ops,
-	},
 	.name = "atomisp-isp2",
 	.id_table = atomisp_pci_tbl,
 	.probe = atomisp_pci_probe,
-- 
2.39.0


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

* [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (3 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 04/57] media: atomisp: Move power-management over to a custom pm-domain Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:18   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 06/57] media: atomisp: Remove non working doorbell check from punit_ddr_dvfs_enable() Hans de Goede
                   ` (52 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

These are clearly debug messages, printing these all the time is not
useful.

Silence these by simply removing them altogether.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/pci/css_2401_system/host/isys_dma_private.h   | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
index a313e1dc7c71..d65fe9ec9049 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
@@ -34,8 +34,6 @@ void isys2401_dma_reg_store(const isys2401_dma_ID_t	dma_id,
 
 	reg_loc = ISYS2401_DMA_BASE[dma_id] + (reg * sizeof(hrt_data));
 
-	ia_css_print("isys dma store at addr(0x%x) val(%u)\n", reg_loc,
-		     (unsigned int)value);
 	ia_css_device_store_uint32(reg_loc, value);
 }
 
-- 
2.39.0


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

* [PATCH 06/57] media: atomisp: Remove non working doorbell check from punit_ddr_dvfs_enable()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (4 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT Hans de Goede
                   ` (51 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

punit_ddr_dvfs_enable() is only used on CHT devices and there dmesg
gets filled with: "DDR DVFS, door bell is not cleared within 3ms"
messages, so clearly the doorbell checking is not working.

This check was added by:
https://github.com/intel/ProductionKernelQuilts/blob/master/uefi/cht-m1stable/patches/cam-0340-atomisp-add-door-bell-for-ddr-dvfs-on-cht.patch

Which commit message says: "PUNIT interface added to check Req_ACK
of freq status". This suggests that the doorbell mechanism may only
be available with certain PUNIT fw versions and it seems that
many CHT devices do not have this fw version; that or the doorbell
mechanism is not working for other reasons.

Revert cam-0340-atomisp-add-door-bell-for-ddr-dvfs-on-cht.patch,
replacing the doorbell check with a msleep(20) this fixes dmesg
getting filled with error messages.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/pci/atomisp_v4l2.c    | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index e994a4a5284e..9eea8ffbc3d6 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -638,27 +638,16 @@ static int atomisp_mrfld_pre_power_down(struct atomisp_device *isp)
 */
 static void punit_ddr_dvfs_enable(bool enable)
 {
-	int door_bell = 1 << 8;
-	int max_wait = 30;
 	int reg;
 
 	iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSDVFS, &reg);
 	if (enable) {
 		reg &= ~(MRFLD_BIT0 | MRFLD_BIT1);
 	} else {
-		reg |= (MRFLD_BIT1 | door_bell);
+		reg |= MRFLD_BIT1;
 		reg &= ~(MRFLD_BIT0);
 	}
 	iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, MRFLD_ISPSSDVFS, reg);
-
-	/* Check Req_ACK to see freq status, wait until door_bell is cleared */
-	while ((reg & door_bell) && max_wait--) {
-		iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSDVFS, &reg);
-		usleep_range(100, 500);
-	}
-
-	if (max_wait == -1)
-		pr_info("DDR DVFS, door bell is not cleared within 3ms\n");
 }
 
 static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
@@ -671,8 +660,10 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
 	dev_dbg(isp->dev, "IUNIT power-%s.\n", enable ? "on" : "off");
 
 	/* WA for P-Unit, if DVFS enabled, ISP timeout observed */
-	if (IS_CHT && enable)
+	if (IS_CHT && enable) {
 		punit_ddr_dvfs_enable(false);
+		msleep(20);
+	}
 
 	/*
 	 * FIXME:WA for ECS28A, with this sleep, CTS
-- 
2.39.0


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

* [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (5 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 06/57] media: atomisp: Remove non working doorbell check from punit_ddr_dvfs_enable() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:40   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl Hans de Goede
                   ` (50 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On BYT on poweron/runtime-resume the code is doing:

1. Do nothing
2. msleep(10)
3. Start actual poweron sequence

Since the runtime resume can happen at any moment, waiting 10ms
after it does not really make any sense.

According to both the comment and to:
https://github.com/intel/ProductionKernelQuilts/blob/master/uefi/cht-m1stable/patches/cam-0341-atomisp-WA-sleep-10ms-when-power-up-ISP-on-byt.patch

Which is the patch which originally added this this was added
as a workaround for a single test failing on a single model
tablet/laptop. So lets just drop this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 9eea8ffbc3d6..aa05c69a5c6b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -665,14 +665,6 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
 		msleep(20);
 	}
 
-	/*
-	 * FIXME:WA for ECS28A, with this sleep, CTS
-	 * android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceAbort
-	 * PASS, no impact on other platforms
-	 */
-	if (IS_BYT && enable)
-		msleep(10);
-
 	/* Write to ISPSSPM0 bit[1:0] to power on/off the IUNIT */
 	iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0,
 			val, MRFLD_ISPSSPM0_ISPSSC_MASK);
-- 
2.39.0


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

* [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (6 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:30   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl Hans de Goede
                   ` (49 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

This ioctl simply returns a couple of fixed sensor parameters.

With libcamera these fixed parameters are instead stored in a table
with sensor-name to parameters mappings (camera_sensor_properties.cpp),
so these custom ioctl is not necessary; and it currently has no users.

Remove the ioctl and also remove the custom v4l2-ctrls underpinning
the ioctl.

This is part of a patch-series which tries to remove atomisp specific /
custom code from the sensor drivers, with as end goal to make the atomisp
drivers regular camera sensor drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-gc0310.c        | 63 ------------------
 .../media/atomisp/i2c/atomisp-gc2235.c        | 63 ------------------
 .../media/atomisp/i2c/atomisp-mt9m114.c       | 64 -------------------
 .../media/atomisp/i2c/atomisp-ov2680.c        | 64 -------------------
 .../media/atomisp/i2c/atomisp-ov2722.c        | 63 ------------------
 drivers/staging/media/atomisp/i2c/gc0310.h    |  3 -
 drivers/staging/media/atomisp/i2c/gc2235.h    |  3 -
 drivers/staging/media/atomisp/i2c/mt9m114.h   |  3 -
 drivers/staging/media/atomisp/i2c/ov2680.h    |  3 -
 drivers/staging/media/atomisp/i2c/ov2722.h    |  3 -
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c | 63 ------------------
 .../media/atomisp/include/linux/atomisp.h     | 20 ------
 .../staging/media/atomisp/pci/atomisp_cmd.c   | 36 -----------
 .../staging/media/atomisp/pci/atomisp_cmd.h   |  3 -
 .../staging/media/atomisp/pci/atomisp_ioctl.c |  7 --
 15 files changed, 461 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index 87a634bf9ff5..a9c4724a9358 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -241,27 +241,6 @@ static int gc0310_write_reg_array(struct i2c_client *client,
 	return __gc0310_flush_reg_array(client, &ctrl);
 }
 
-static int gc0310_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (GC0310_FOCAL_LENGTH_NUM << 16) | GC0310_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int gc0310_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/*const f number for imx*/
-	*val = (GC0310_F_NUMBER_DEFAULT_NUM << 16) | GC0310_F_NUMBER_DEM;
-	return 0;
-}
-
-static int gc0310_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (GC0310_F_NUMBER_DEFAULT_NUM << 24) |
-	       (GC0310_F_NUMBER_DEM << 16) |
-	       (GC0310_F_NUMBER_DEFAULT_NUM << 8) | GC0310_F_NUMBER_DEM;
-	return 0;
-}
-
 static int gc0310_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
 {
 	struct gc0310_device *dev = to_gc0310_sensor(sd);
@@ -596,15 +575,6 @@ static int gc0310_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = gc0310_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = gc0310_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = gc0310_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = gc0310_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_BIN_FACTOR_HORZ:
 		ret = gc0310_g_bin_factor_x(&dev->sd, &ctrl->val);
 		break;
@@ -655,39 +625,6 @@ static const struct v4l2_ctrl_config gc0310_controls[] = {
 		.step = 1,
 		.def = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "focal length",
-		.min = GC0310_FOCAL_LENGTH_DEFAULT,
-		.max = GC0310_FOCAL_LENGTH_DEFAULT,
-		.step = 0x01,
-		.def = GC0310_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number",
-		.min = GC0310_F_NUMBER_DEFAULT,
-		.max = GC0310_F_NUMBER_DEFAULT,
-		.step = 0x01,
-		.def = GC0310_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number range",
-		.min = GC0310_F_NUMBER_RANGE,
-		.max = GC0310_F_NUMBER_RANGE,
-		.step = 0x01,
-		.def = GC0310_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_BIN_FACTOR_HORZ,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 4d5a7e335f85..e6df10bcab8c 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -220,27 +220,6 @@ static int gc2235_write_reg_array(struct i2c_client *client,
 	return __gc2235_flush_reg_array(client, &ctrl);
 }
 
-static int gc2235_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (GC2235_FOCAL_LENGTH_NUM << 16) | GC2235_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int gc2235_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/* const f number for imx */
-	*val = (GC2235_F_NUMBER_DEFAULT_NUM << 16) | GC2235_F_NUMBER_DEM;
-	return 0;
-}
-
-static int gc2235_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (GC2235_F_NUMBER_DEFAULT_NUM << 24) |
-	       (GC2235_F_NUMBER_DEM << 16) |
-	       (GC2235_F_NUMBER_DEFAULT_NUM << 8) | GC2235_F_NUMBER_DEM;
-	return 0;
-}
-
 static int gc2235_get_intg_factor(struct i2c_client *client,
 				  struct camera_mipi_info *info,
 				  const struct gc2235_resolution *res)
@@ -467,15 +446,6 @@ static int gc2235_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = gc2235_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = gc2235_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = gc2235_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = gc2235_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -499,39 +469,6 @@ static struct v4l2_ctrl_config gc2235_controls[] = {
 		.def = 0x00,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "focal length",
-		.min = GC2235_FOCAL_LENGTH_DEFAULT,
-		.max = GC2235_FOCAL_LENGTH_DEFAULT,
-		.step = 0x01,
-		.def = GC2235_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number",
-		.min = GC2235_F_NUMBER_DEFAULT,
-		.max = GC2235_F_NUMBER_DEFAULT,
-		.step = 0x01,
-		.def = GC2235_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number range",
-		.min = GC2235_F_NUMBER_RANGE,
-		.max = GC2235_F_NUMBER_RANGE,
-		.step = 0x01,
-		.def = GC2235_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 };
 
 static int __gc2235_init(struct v4l2_subdev *sd)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index a0e8e94b2412..eb34b5cadb33 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -841,28 +841,6 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
-/* TODO: Update to SOC functions, remove exposure and gain */
-static int mt9m114_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (MT9M114_FOCAL_LENGTH_NUM << 16) | MT9M114_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int mt9m114_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/* const f number for mt9m114 */
-	*val = (MT9M114_F_NUMBER_DEFAULT_NUM << 16) | MT9M114_F_NUMBER_DEM;
-	return 0;
-}
-
-static int mt9m114_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (MT9M114_F_NUMBER_DEFAULT_NUM << 24) |
-	       (MT9M114_F_NUMBER_DEM << 16) |
-	       (MT9M114_F_NUMBER_DEFAULT_NUM << 8) | MT9M114_F_NUMBER_DEM;
-	return 0;
-}
-
 /* Horizontal flip the image. */
 static int mt9m114_g_hflip(struct v4l2_subdev *sd, s32 *val)
 {
@@ -1271,15 +1249,6 @@ static int mt9m114_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_HFLIP:
 		ret = mt9m114_g_hflip(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = mt9m114_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = mt9m114_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = mt9m114_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = mt9m114_g_exposure(&dev->sd, &ctrl->val);
 		break;
@@ -1331,39 +1300,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = {
 		.step = 1,
 		.def = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.name = "focal length",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.min = MT9M114_FOCAL_LENGTH_DEFAULT,
-		.max = MT9M114_FOCAL_LENGTH_DEFAULT,
-		.step = 1,
-		.def = MT9M114_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.name = "f-number",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.min = MT9M114_F_NUMBER_DEFAULT,
-		.max = MT9M114_F_NUMBER_DEFAULT,
-		.step = 1,
-		.def = MT9M114_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.name = "f-number range",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.min = MT9M114_F_NUMBER_RANGE,
-		.max = MT9M114_F_NUMBER_RANGE,
-		.step = 1,
-		.def = MT9M114_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_EXPOSURE_ABSOLUTE,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index fa1de45b7a2d..39f86c7fd12e 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -119,28 +119,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
 	return 0;
 }
 
-static int ov2680_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV2680_FOCAL_LENGTH_NUM << 16) | OV2680_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int ov2680_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/* const f number for ov2680 */
-
-	*val = (OV2680_F_NUMBER_DEFAULT_NUM << 16) | OV2680_F_NUMBER_DEM;
-	return 0;
-}
-
-static int ov2680_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV2680_F_NUMBER_DEFAULT_NUM << 24) |
-	       (OV2680_F_NUMBER_DEM << 16) |
-	       (OV2680_F_NUMBER_DEFAULT_NUM << 8) | OV2680_F_NUMBER_DEM;
-	return 0;
-}
-
 static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
 {
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
@@ -517,15 +495,6 @@ static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = ov2680_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = ov2680_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = ov2680_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = ov2680_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_BIN_FACTOR_HORZ:
 		ret = ov2680_g_bin_factor_x(&dev->sd, &ctrl->val);
 		break;
@@ -556,39 +525,6 @@ static const struct v4l2_ctrl_config ov2680_controls[] = {
 		.def = 0x00,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "focal length",
-		.min = OV2680_FOCAL_LENGTH_DEFAULT,
-		.max = OV2680_FOCAL_LENGTH_DEFAULT,
-		.step = 0x01,
-		.def = OV2680_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number",
-		.min = OV2680_F_NUMBER_DEFAULT,
-		.max = OV2680_F_NUMBER_DEFAULT,
-		.step = 0x01,
-		.def = OV2680_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number range",
-		.min = OV2680_F_NUMBER_RANGE,
-		.max = OV2680_F_NUMBER_RANGE,
-		.step = 0x01,
-		.def = OV2680_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_BIN_FACTOR_HORZ,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 887b6f99f6ca..47eefaccbe0b 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -261,27 +261,6 @@ static int ov2722_write_reg_array(struct i2c_client *client,
 	return __ov2722_flush_reg_array(client, &ctrl);
 }
 
-static int ov2722_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV2722_FOCAL_LENGTH_NUM << 16) | OV2722_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int ov2722_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/*const f number for imx*/
-	*val = (OV2722_F_NUMBER_DEFAULT_NUM << 16) | OV2722_F_NUMBER_DEM;
-	return 0;
-}
-
-static int ov2722_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV2722_F_NUMBER_DEFAULT_NUM << 24) |
-	       (OV2722_F_NUMBER_DEM << 16) |
-	       (OV2722_F_NUMBER_DEFAULT_NUM << 8) | OV2722_F_NUMBER_DEM;
-	return 0;
-}
-
 static int ov2722_get_intg_factor(struct i2c_client *client,
 				  struct camera_mipi_info *info,
 				  const struct ov2722_resolution *res)
@@ -547,15 +526,6 @@ static int ov2722_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = ov2722_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = ov2722_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = ov2722_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = ov2722_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_LINK_FREQ:
 		val = dev->res->mipi_freq;
 		if (val == 0)
@@ -586,39 +556,6 @@ static const struct v4l2_ctrl_config ov2722_controls[] = {
 		.def = 0x00,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "focal length",
-		.min = OV2722_FOCAL_LENGTH_DEFAULT,
-		.max = OV2722_FOCAL_LENGTH_DEFAULT,
-		.step = 0x01,
-		.def = OV2722_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number",
-		.min = OV2722_F_NUMBER_DEFAULT,
-		.max = OV2722_F_NUMBER_DEFAULT,
-		.step = 0x01,
-		.def = OV2722_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number range",
-		.min = OV2722_F_NUMBER_RANGE,
-		.max = OV2722_F_NUMBER_RANGE,
-		.step = 0x01,
-		.def = OV2722_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_LINK_FREQ,
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index 4b9ce681bd93..52b4c07e5cf0 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -38,9 +38,6 @@
 #define I2C_RETRY_COUNT		5
 
 #define GC0310_FOCAL_LENGTH_NUM	278	/*2.78mm*/
-#define GC0310_FOCAL_LENGTH_DEM	100
-#define GC0310_F_NUMBER_DEFAULT_NUM	26
-#define GC0310_F_NUMBER_DEM	10
 
 #define MAX_FMTS		1
 
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index 806be5dff7a5..dd2d44b40e22 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -44,9 +44,6 @@
 #define I2C_RETRY_COUNT		5
 
 #define GC2235_FOCAL_LENGTH_NUM	278	/*2.78mm*/
-#define GC2235_FOCAL_LENGTH_DEM	100
-#define GC2235_F_NUMBER_DEFAULT_NUM	26
-#define GC2235_F_NUMBER_DEM	10
 
 #define MAX_FMTS		1
 
diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h
index bcce18b65fa6..831875071cbb 100644
--- a/drivers/staging/media/atomisp/i2c/mt9m114.h
+++ b/drivers/staging/media/atomisp/i2c/mt9m114.h
@@ -136,9 +136,6 @@
 #define MT9M114_BPAT_BGBGGRGR	BIT(3)
 
 #define MT9M114_FOCAL_LENGTH_NUM	208	/*2.08mm*/
-#define MT9M114_FOCAL_LENGTH_DEM	100
-#define MT9M114_F_NUMBER_DEFAULT_NUM	24
-#define MT9M114_F_NUMBER_DEM	10
 #define MT9M114_WAIT_STAT_TIMEOUT	100
 #define MT9M114_FLICKER_MODE_50HZ	1
 #define MT9M114_FLICKER_MODE_60HZ	2
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 7ab337b859ad..2bc350c67711 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -37,9 +37,6 @@
 #define I2C_RETRY_COUNT		5
 
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
-#define OV2680_FOCAL_LENGTH_DEM	100
-#define OV2680_F_NUMBER_DEFAULT_NUM	24
-#define OV2680_F_NUMBER_DEM	10
 
 #define OV2680_BIN_FACTOR_MAX 4
 
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index d6e2510bc01c..d4cd6f27ee8d 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -39,9 +39,6 @@
 #define I2C_RETRY_COUNT		5
 
 #define OV2722_FOCAL_LENGTH_NUM	278	/*2.78mm*/
-#define OV2722_FOCAL_LENGTH_DEM	100
-#define OV2722_F_NUMBER_DEFAULT_NUM	26
-#define OV2722_F_NUMBER_DEM	10
 
 #define MAX_FMTS		1
 
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index c1cd631455e6..9adaf2fc940a 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -415,27 +415,6 @@ static int ov5693_write_reg_array(struct i2c_client *client,
 	return __ov5693_flush_reg_array(client, &ctrl);
 }
 
-static int ov5693_g_focal(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV5693_FOCAL_LENGTH_NUM << 16) | OV5693_FOCAL_LENGTH_DEM;
-	return 0;
-}
-
-static int ov5693_g_fnumber(struct v4l2_subdev *sd, s32 *val)
-{
-	/*const f number for imx*/
-	*val = (OV5693_F_NUMBER_DEFAULT_NUM << 16) | OV5693_F_NUMBER_DEM;
-	return 0;
-}
-
-static int ov5693_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
-{
-	*val = (OV5693_F_NUMBER_DEFAULT_NUM << 24) |
-	       (OV5693_F_NUMBER_DEM << 16) |
-	       (OV5693_F_NUMBER_DEFAULT_NUM << 8) | OV5693_F_NUMBER_DEM;
-	return 0;
-}
-
 static int ov5693_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
 {
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
@@ -1107,15 +1086,6 @@ static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = ov5693_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_FOCAL_ABSOLUTE:
-		ret = ov5693_g_focal(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_ABSOLUTE:
-		ret = ov5693_g_fnumber(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_FNUMBER_RANGE:
-		ret = ov5693_g_fnumber_range(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_FOCUS_ABSOLUTE:
 		ret = ov5693_q_focus_abs(&dev->sd, &ctrl->val);
 		break;
@@ -1152,39 +1122,6 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
 		.def = 0x00,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FOCAL_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "focal length",
-		.min = OV5693_FOCAL_LENGTH_DEFAULT,
-		.max = OV5693_FOCAL_LENGTH_DEFAULT,
-		.step = 0x01,
-		.def = OV5693_FOCAL_LENGTH_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number",
-		.min = OV5693_F_NUMBER_DEFAULT,
-		.max = OV5693_F_NUMBER_DEFAULT,
-		.step = 0x01,
-		.def = OV5693_F_NUMBER_DEFAULT,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_FNUMBER_RANGE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "f-number range",
-		.min = OV5693_F_NUMBER_RANGE,
-		.max = OV5693_F_NUMBER_RANGE,
-		.step = 0x01,
-		.def = OV5693_F_NUMBER_RANGE,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_FOCUS_ABSOLUTE,
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index 3f602b5aaff9..e70e57695300 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -586,20 +586,6 @@ struct atomisp_shading_table {
 	__u16 *data[ATOMISP_NUM_SC_COLORS];
 };
 
-struct atomisp_makernote_info {
-	/* bits 31-16: numerator, bits 15-0: denominator */
-	unsigned int focal_length;
-	/* bits 31-16: numerator, bits 15-0: denominator*/
-	unsigned int f_number_curr;
-	/*
-	* 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
-	*/
-	unsigned int f_number_range;
-};
-
 /* parameter for MACC */
 #define ATOMISP_NUM_MACC_AXES           16
 struct atomisp_macc_table {
@@ -914,8 +900,6 @@ struct atomisp_sensor_ae_bracketing_lut {
 	_IOR('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table)
 #define ATOMISP_IOC_S_ISP_GDC_TAB \
 	_IOW('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table)
-#define ATOMISP_IOC_ISP_MAKERNOTE \
-	_IOWR('v', BASE_VIDIOC_PRIVATE + 11, struct atomisp_makernote_info)
 
 /* macc parameter control*/
 #define ATOMISP_IOC_G_ISP_MACC \
@@ -1093,10 +1077,6 @@ struct atomisp_sensor_ae_bracketing_lut {
  * Exposure, Flash and privacy (indicator) light controls, to be upstreamed */
 #define V4L2_CID_CAMERA_LASTP1             (V4L2_CID_CAMERA_CLASS_BASE + 1024)
 
-#define V4L2_CID_FOCAL_ABSOLUTE            (V4L2_CID_CAMERA_LASTP1 + 0)
-#define V4L2_CID_FNUMBER_ABSOLUTE          (V4L2_CID_CAMERA_LASTP1 + 1)
-#define V4L2_CID_FNUMBER_RANGE             (V4L2_CID_CAMERA_LASTP1 + 2)
-
 /* Flash related CIDs, see also:
  * http://linuxtv.org/downloads/v4l-dvb-apis/extended-controls.html\
  * #flash-controls */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 5cea1df48b7d..b167ee32a952 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -5492,42 +5492,6 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
 	return ret;
 }
 
-int atomisp_exif_makernote(struct atomisp_sub_device *asd,
-			   struct atomisp_makernote_info *config)
-{
-	struct v4l2_control ctrl;
-	struct atomisp_device *isp = asd->isp;
-
-	ctrl.id = V4L2_CID_FOCAL_ABSOLUTE;
-	if (v4l2_g_ctrl
-	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
-		dev_warn(isp->dev, "failed to g_ctrl for focal length\n");
-		return -EINVAL;
-	} else {
-		config->focal_length = ctrl.value;
-	}
-
-	ctrl.id = V4L2_CID_FNUMBER_ABSOLUTE;
-	if (v4l2_g_ctrl
-	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
-		dev_warn(isp->dev, "failed to g_ctrl for f-number\n");
-		return -EINVAL;
-	} else {
-		config->f_number_curr = ctrl.value;
-	}
-
-	ctrl.id = V4L2_CID_FNUMBER_RANGE;
-	if (v4l2_g_ctrl
-	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
-		dev_warn(isp->dev, "failed to g_ctrl for f number range\n");
-		return -EINVAL;
-	} else {
-		config->f_number_range = ctrl.value;
-	}
-
-	return 0;
-}
-
 int atomisp_offline_capture_configure(struct atomisp_sub_device *asd,
 				      struct atomisp_cont_capture_conf *cvf_config)
 {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index b8911491581a..99bbab402c9c 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -273,9 +273,6 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
 int atomisp_offline_capture_configure(struct atomisp_sub_device *asd,
 				      struct atomisp_cont_capture_conf *cvf_config);
 
-int atomisp_exif_makernote(struct atomisp_sub_device *asd,
-			   struct atomisp_makernote_info *config);
-
 void atomisp_free_internal_buffers(struct atomisp_sub_device *asd);
 
 int atomisp_s_ae_window(struct atomisp_sub_device *asd,
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 4f35e8f8250a..faf65387df56 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1631,7 +1631,6 @@ static int atomisp_g_ctrl(struct file *file, void *fh,
 	switch (control->id) {
 	case V4L2_CID_IRIS_ABSOLUTE:
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
-	case V4L2_CID_FNUMBER_ABSOLUTE:
 	case V4L2_CID_2A_STATUS:
 	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
 	case V4L2_CID_EXPOSURE:
@@ -1828,7 +1827,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
 		case V4L2_CID_EXPOSURE_ABSOLUTE:
 		case V4L2_CID_EXPOSURE_AUTO:
 		case V4L2_CID_IRIS_ABSOLUTE:
-		case V4L2_CID_FNUMBER_ABSOLUTE:
 		case V4L2_CID_BIN_FACTOR_HORZ:
 		case V4L2_CID_BIN_FACTOR_VERT:
 		case V4L2_CID_3A_LOCK:
@@ -1940,7 +1938,6 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
 		case V4L2_CID_EXPOSURE_AUTO:
 		case V4L2_CID_EXPOSURE_METERING:
 		case V4L2_CID_IRIS_ABSOLUTE:
-		case V4L2_CID_FNUMBER_ABSOLUTE:
 		case V4L2_CID_VCM_TIMING:
 		case V4L2_CID_VCM_SLEW:
 		case V4L2_CID_3A_LOCK:
@@ -2276,10 +2273,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
 		err = atomisp_fixed_pattern_table(asd, arg);
 		break;
 
-	case ATOMISP_IOC_ISP_MAKERNOTE:
-		err = atomisp_exif_makernote(asd, arg);
-		break;
-
 	case ATOMISP_IOC_G_SENSOR_MODE_DATA:
 		err = atomisp_get_sensor_mode_data(asd, arg);
 		break;
-- 
2.39.0


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

* [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (7 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:31   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT Hans de Goede
                   ` (48 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

This ioctl returns a number of fixed sensor parameters +
a number of mode-specific parameters.

With libcamera these fixed parameters are instead stored in a table
with sensor-name to parameters mappings (camera_sensor_properties.cpp);
and the variable parameters can be derived from the set fmt.

So this custom ioctl is not necessary; and it currently has no users.

Remove the ioctl and all the sensor drivers xxxx_get_intg_factor()
helpers which return this info.

This is part of a patch-series which tries to remove atomisp specific /
custom code from the sensor drivers, with as end goal to make the atomisp
drivers regular camera sensor drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-gc0310.c        | 140 ------------------
 .../media/atomisp/i2c/atomisp-gc2235.c        | 113 --------------
 .../media/atomisp/i2c/atomisp-mt9m114.c       |  96 ------------
 .../media/atomisp/i2c/atomisp-ov2680.c        |  82 ----------
 .../media/atomisp/i2c/atomisp-ov2722.c        | 111 --------------
 drivers/staging/media/atomisp/i2c/gc0310.h    |   1 -
 drivers/staging/media/atomisp/i2c/gc2235.h    |   1 -
 drivers/staging/media/atomisp/i2c/ov2722.h    |   1 -
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c |  86 -----------
 .../staging/media/atomisp/i2c/ov5693/ov5693.h |   1 -
 .../media/atomisp/include/linux/atomisp.h     |  26 ----
 .../atomisp/include/linux/atomisp_platform.h  |   1 -
 drivers/staging/media/atomisp/notes.txt       |   6 -
 .../staging/media/atomisp/pci/atomisp_cmd.c   |  19 ---
 .../staging/media/atomisp/pci/atomisp_cmd.h   |   3 -
 .../staging/media/atomisp/pci/atomisp_ioctl.c |   4 -
 16 files changed, 691 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index a9c4724a9358..4968ec51ff1b 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -259,140 +259,6 @@ static int gc0310_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
 	return 0;
 }
 
-static int gc0310_get_intg_factor(struct i2c_client *client,
-				  struct camera_mipi_info *info,
-				  const struct gc0310_resolution *res)
-{
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct gc0310_device *dev = to_gc0310_sensor(sd);
-	struct atomisp_sensor_mode_data *buf = &info->data;
-	u16 val;
-	u8 reg_val;
-	int ret;
-	unsigned int hori_blanking;
-	unsigned int vert_blanking;
-	unsigned int sh_delay;
-
-	if (!info)
-		return -EINVAL;
-
-	/* pixel clock calculattion */
-	dev->vt_pix_clk_freq_mhz = 14400000; // 16.8MHz
-	buf->vt_pix_clk_freq_mhz = dev->vt_pix_clk_freq_mhz;
-	dev_dbg(&client->dev, "vt_pix_clk_freq_mhz=%d\n", buf->vt_pix_clk_freq_mhz);
-
-	/* get integration time */
-	buf->coarse_integration_time_min = GC0310_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    GC0310_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = GC0310_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    GC0310_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = GC0310_FINE_INTG_TIME_MIN;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	/* Getting crop_horizontal_start */
-	ret =  gc0310_read_reg(client, GC0310_8BIT,
-			       GC0310_H_CROP_START_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret =  gc0310_read_reg(client, GC0310_8BIT,
-			       GC0310_H_CROP_START_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_start = val | (reg_val & 0xFF);
-	dev_dbg(&client->dev, "crop_horizontal_start=%d\n", buf->crop_horizontal_start);
-
-	/* Getting crop_vertical_start */
-	ret =  gc0310_read_reg(client, GC0310_8BIT,
-			       GC0310_V_CROP_START_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret =  gc0310_read_reg(client, GC0310_8BIT,
-			       GC0310_V_CROP_START_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_start = val | (reg_val & 0xFF);
-	dev_dbg(&client->dev, "crop_vertical_start=%d\n", buf->crop_vertical_start);
-
-	/* Getting output_width */
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_H_OUTSIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_H_OUTSIZE_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = val | (reg_val & 0xFF);
-	dev_dbg(&client->dev, "output_width=%d\n", buf->output_width);
-
-	/* Getting output_height */
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_V_OUTSIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_V_OUTSIZE_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = val | (reg_val & 0xFF);
-	dev_dbg(&client->dev, "output_height=%d\n", buf->output_height);
-
-	buf->crop_horizontal_end = buf->crop_horizontal_start + buf->output_width - 1;
-	buf->crop_vertical_end = buf->crop_vertical_start + buf->output_height - 1;
-	dev_dbg(&client->dev, "crop_horizontal_end=%d\n", buf->crop_horizontal_end);
-	dev_dbg(&client->dev, "crop_vertical_end=%d\n", buf->crop_vertical_end);
-
-	/* Getting line_length_pck */
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_H_BLANKING_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_H_BLANKING_L, &reg_val);
-	if (ret)
-		return ret;
-	hori_blanking = val | (reg_val & 0xFF);
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_SH_DELAY, &reg_val);
-	if (ret)
-		return ret;
-	sh_delay = reg_val;
-	buf->line_length_pck = buf->output_width + hori_blanking + sh_delay + 4;
-	dev_dbg(&client->dev, "hori_blanking=%d sh_delay=%d line_length_pck=%d\n", hori_blanking,
-		sh_delay, buf->line_length_pck);
-
-	/* Getting frame_length_lines */
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_V_BLANKING_H, &reg_val);
-	if (ret)
-		return ret;
-	val = (reg_val & 0xFF) << 8;
-	ret = gc0310_read_reg(client, GC0310_8BIT,
-			      GC0310_V_BLANKING_L, &reg_val);
-	if (ret)
-		return ret;
-	vert_blanking = val | (reg_val & 0xFF);
-	buf->frame_length_lines = buf->output_height + vert_blanking;
-	dev_dbg(&client->dev, "vert_blanking=%d frame_length_lines=%d\n", vert_blanking,
-		buf->frame_length_lines);
-
-	buf->binning_factor_x = res->bin_factor_x ?
-				res->bin_factor_x : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				res->bin_factor_y : 1;
-	return 0;
-}
-
 static int gc0310_set_gain(struct v4l2_subdev *sd, int gain)
 
 {
@@ -889,12 +755,6 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd,
 		goto err;
 	}
 
-	ret = gc0310_get_intg_factor(client, gc0310_info, dev->res);
-	if (ret) {
-		dev_err(&client->dev, "failed to get integration_factor\n");
-		goto err;
-	}
-
 err:
 	mutex_unlock(&dev->input_lock);
 	return ret;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index e6df10bcab8c..cb4c79b483ca 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -220,114 +220,6 @@ static int gc2235_write_reg_array(struct i2c_client *client,
 	return __gc2235_flush_reg_array(client, &ctrl);
 }
 
-static int gc2235_get_intg_factor(struct i2c_client *client,
-				  struct camera_mipi_info *info,
-				  const struct gc2235_resolution *res)
-{
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct gc2235_device *dev = to_gc2235_sensor(sd);
-	struct atomisp_sensor_mode_data *buf = &info->data;
-	u16 reg_val, reg_val_h;
-	int ret;
-
-	if (!info)
-		return -EINVAL;
-
-	/* pixel clock calculattion */
-	buf->vt_pix_clk_freq_mhz = dev->vt_pix_clk_freq_mhz = 30000000;
-
-	/* get integration time */
-	buf->coarse_integration_time_min = GC2235_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    GC2235_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = GC2235_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    GC2235_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = GC2235_FINE_INTG_TIME_MIN;
-	buf->frame_length_lines = res->lines_per_frame;
-	buf->line_length_pck = res->pixels_per_line;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	ret =  gc2235_read_reg(client, GC2235_8BIT,
-			       GC2235_H_CROP_START_H, &reg_val_h);
-	ret =  gc2235_read_reg(client, GC2235_8BIT,
-			       GC2235_H_CROP_START_L, &reg_val);
-	if (ret)
-		return ret;
-
-	buf->crop_horizontal_start = (reg_val_h << 8) | reg_val;
-
-	ret =  gc2235_read_reg(client, GC2235_8BIT,
-			       GC2235_V_CROP_START_H, &reg_val_h);
-	ret =  gc2235_read_reg(client, GC2235_8BIT,
-			       GC2235_V_CROP_START_L, &reg_val);
-	if (ret)
-		return ret;
-
-	buf->crop_vertical_start = (reg_val_h << 8) | reg_val;
-
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_H_OUTSIZE_H, &reg_val_h);
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_H_OUTSIZE_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = (reg_val_h << 8) | reg_val;
-
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_V_OUTSIZE_H, &reg_val_h);
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_V_OUTSIZE_L, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = (reg_val_h << 8) | reg_val;
-
-	buf->crop_horizontal_end = buf->crop_horizontal_start +
-				   buf->output_width - 1;
-	buf->crop_vertical_end = buf->crop_vertical_start +
-				 buf->output_height - 1;
-
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_HB_H, &reg_val_h);
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_HB_L, &reg_val);
-	if (ret)
-		return ret;
-
-#if 0
-	u16 dummy = (reg_val_h << 8) | reg_val;
-#endif
-
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_SH_DELAY_H, &reg_val_h);
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_SH_DELAY_L, &reg_val);
-
-#if 0
-	buf->line_length_pck = buf->output_width + 16 + dummy +
-			       (((u16)reg_val_h << 8) | (u16)reg_val) + 4;
-#endif
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_VB_H, &reg_val_h);
-	ret = gc2235_read_reg(client, GC2235_8BIT,
-			      GC2235_VB_L, &reg_val);
-	if (ret)
-		return ret;
-
-#if 0
-	buf->frame_length_lines = buf->output_height + 32 +
-				  (((u16)reg_val_h << 8) | (u16)reg_val);
-#endif
-	buf->binning_factor_x = res->bin_factor_x ?
-				res->bin_factor_x : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				res->bin_factor_y : 1;
-	return 0;
-}
-
 static long __gc2235_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -680,11 +572,6 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
 		goto err;
 	}
 
-	ret = gc2235_get_intg_factor(client, gc2235_info,
-				     dev->res);
-	if (ret)
-		dev_err(&client->dev, "failed to get integration_factor\n");
-
 err:
 	mutex_unlock(&dev->input_lock);
 	return ret;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index eb34b5cadb33..1df38f5fe1f4 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -612,96 +612,6 @@ static int mt9m114_res2size(struct v4l2_subdev *sd, int *h_size, int *v_size)
 	return 0;
 }
 
-static int mt9m114_get_intg_factor(struct i2c_client *client,
-				   struct camera_mipi_info *info,
-				   const struct mt9m114_res_struct *res)
-{
-	struct atomisp_sensor_mode_data *buf;
-	u32 reg_val;
-	int ret;
-
-	if (!info)
-		return -EINVAL;
-
-	buf = &info->data;
-
-	ret =  mt9m114_read_reg(client, MISENSOR_32BIT,
-				REG_PIXEL_CLK, &reg_val);
-	if (ret)
-		return ret;
-	buf->vt_pix_clk_freq_mhz = reg_val;
-
-	/* get integration time */
-	buf->coarse_integration_time_min = MT9M114_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    MT9M114_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = MT9M114_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    MT9M114_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = MT9M114_FINE_INTG_TIME_MIN;
-
-	buf->frame_length_lines = res->lines_per_frame;
-	buf->line_length_pck = res->pixels_per_line;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	ret =  mt9m114_read_reg(client, MISENSOR_16BIT,
-				REG_H_START, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_start = reg_val;
-
-	ret =  mt9m114_read_reg(client, MISENSOR_16BIT,
-				REG_V_START, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_start = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_H_END, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_end = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_V_END, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_end = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_WIDTH, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_HEIGHT, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_TIMING_HTS, &reg_val);
-	if (ret)
-		return ret;
-	buf->line_length_pck = reg_val;
-
-	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
-			       REG_TIMING_VTS, &reg_val);
-	if (ret)
-		return ret;
-	buf->frame_length_lines = reg_val;
-
-	buf->binning_factor_x = res->bin_factor_x ?
-				res->bin_factor_x : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				res->bin_factor_y : 1;
-	return 0;
-}
-
 static int mt9m114_get_fmt(struct v4l2_subdev *sd,
 			   struct v4l2_subdev_state *sd_state,
 			   struct v4l2_subdev_format *format)
@@ -823,12 +733,6 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
 			mt9m114_res[index].used = false;
 		}
 	}
-	ret = mt9m114_get_intg_factor(c, mt9m114_info,
-				      &mt9m114_res[res->res]);
-	if (ret) {
-		dev_err(&c->dev, "failed to get integration_factor\n");
-		return -EINVAL;
-	}
 	/*
 	 * mt9m114 - we don't poll for context switch
 	 * because it does not happen with streaming disabled.
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 39f86c7fd12e..9379c25205b4 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -140,82 +140,6 @@ static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
 	return 0;
 }
 
-static int ov2680_get_intg_factor(struct i2c_client *client,
-				  struct camera_mipi_info *info,
-				  const struct ov2680_resolution *res)
-{
-	struct atomisp_sensor_mode_data *buf = &info->data;
-	unsigned int pix_clk_freq_hz;
-	u32 reg_val;
-	int ret;
-
-	dev_dbg(&client->dev,  "++++ov2680_get_intg_factor\n");
-	if (!info)
-		return -EINVAL;
-
-	/* pixel clock */
-	pix_clk_freq_hz = res->pix_clk_freq * 1000000;
-
-	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
-
-	/* get integration time */
-	buf->coarse_integration_time_min = OV2680_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    OV2680_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = OV2680_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    OV2680_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = OV2680_FINE_INTG_TIME_MIN;
-	buf->frame_length_lines = res->lines_per_frame;
-	buf->line_length_pck = res->pixels_per_line;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	ret =  ov2680_read_reg(client, 2,
-			       OV2680_HORIZONTAL_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_start = reg_val;
-
-	ret =  ov2680_read_reg(client, 2,
-			       OV2680_VERTICAL_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_start = reg_val;
-
-	ret = ov2680_read_reg(client, 2,
-			      OV2680_HORIZONTAL_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_end = reg_val;
-
-	ret = ov2680_read_reg(client, 2,
-			      OV2680_VERTICAL_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_end = reg_val;
-
-	ret = ov2680_read_reg(client, 2,
-			      OV2680_HORIZONTAL_OUTPUT_SIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = reg_val;
-
-	ret = ov2680_read_reg(client, 2,
-			      OV2680_VERTICAL_OUTPUT_SIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = reg_val;
-
-	buf->binning_factor_x = res->bin_factor_x ?
-				(res->bin_factor_x * 2) : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				(res->bin_factor_y * 2) : 1;
-	return 0;
-}
-
 static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -818,12 +742,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		goto err;
 	}
 
-	ret = ov2680_get_intg_factor(client, ov2680_info, res);
-	if (ret) {
-		dev_err(&client->dev, "failed to get integration factor\n");
-		goto err;
-	}
-
 	/*
 	 * recall flip functions to avoid flip registers
 	 * were overridden by default setting
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 47eefaccbe0b..d819ab5de28a 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -261,113 +261,6 @@ static int ov2722_write_reg_array(struct i2c_client *client,
 	return __ov2722_flush_reg_array(client, &ctrl);
 }
 
-static int ov2722_get_intg_factor(struct i2c_client *client,
-				  struct camera_mipi_info *info,
-				  const struct ov2722_resolution *res)
-{
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct ov2722_device *dev = NULL;
-	struct atomisp_sensor_mode_data *buf = &info->data;
-	const unsigned int ext_clk_freq_hz = 19200000;
-	const unsigned int pll_invariant_div = 10;
-	unsigned int pix_clk_freq_hz;
-	u16 pre_pll_clk_div;
-	u16 pll_multiplier;
-	u16 op_pix_clk_div;
-	u16 reg_val;
-	int ret;
-
-	if (!info)
-		return -EINVAL;
-
-	dev = to_ov2722_sensor(sd);
-
-	/* pixel clock calculattion */
-	ret =  ov2722_read_reg(client, OV2722_8BIT,
-			       OV2722_SC_CMMN_PLL_CTRL3, &pre_pll_clk_div);
-	if (ret)
-		return ret;
-
-	ret =  ov2722_read_reg(client, OV2722_8BIT,
-			       OV2722_SC_CMMN_PLL_MULTIPLIER, &pll_multiplier);
-	if (ret)
-		return ret;
-
-	ret =  ov2722_read_reg(client, OV2722_8BIT,
-			       OV2722_SC_CMMN_PLL_DEBUG_OPT, &op_pix_clk_div);
-	if (ret)
-		return ret;
-
-	pre_pll_clk_div = (pre_pll_clk_div & 0x70) >> 4;
-	if (!pre_pll_clk_div)
-		return -EINVAL;
-
-	pll_multiplier = pll_multiplier & 0x7f;
-	op_pix_clk_div = op_pix_clk_div & 0x03;
-	pix_clk_freq_hz = ext_clk_freq_hz / pre_pll_clk_div * pll_multiplier
-			  * op_pix_clk_div / pll_invariant_div;
-
-	dev->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
-	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
-
-	/* get integration time */
-	buf->coarse_integration_time_min = OV2722_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    OV2722_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = OV2722_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    OV2722_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = OV2722_FINE_INTG_TIME_MIN;
-	buf->frame_length_lines = res->lines_per_frame;
-	buf->line_length_pck = res->pixels_per_line;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	ret =  ov2722_read_reg(client, OV2722_16BIT,
-			       OV2722_H_CROP_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_start = reg_val;
-
-	ret =  ov2722_read_reg(client, OV2722_16BIT,
-			       OV2722_V_CROP_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_start = reg_val;
-
-	ret = ov2722_read_reg(client, OV2722_16BIT,
-			      OV2722_H_CROP_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_end = reg_val;
-
-	ret = ov2722_read_reg(client, OV2722_16BIT,
-			      OV2722_V_CROP_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_end = reg_val;
-
-	ret = ov2722_read_reg(client, OV2722_16BIT,
-			      OV2722_H_OUTSIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = reg_val;
-
-	ret = ov2722_read_reg(client, OV2722_16BIT,
-			      OV2722_V_OUTSIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = reg_val;
-
-	buf->binning_factor_x = res->bin_factor_x ?
-				res->bin_factor_x : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				res->bin_factor_y : 1;
-	return 0;
-}
-
 static long __ov2722_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -812,10 +705,6 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
 		}
 	}
 
-	ret = ov2722_get_intg_factor(client, ov2722_info, dev->res);
-	if (ret)
-		dev_err(&client->dev, "failed to get integration_factor\n");
-
 err:
 	mutex_unlock(&dev->input_lock);
 	return ret;
diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index 52b4c07e5cf0..2a559b0d474d 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -146,7 +146,6 @@ struct gc0310_device {
 	struct v4l2_ctrl_handler ctrl_handler;
 
 	struct camera_sensor_platform_data *platform_data;
-	int vt_pix_clk_freq_mhz;
 	struct gc0310_resolution *res;
 	u8 type;
 	bool power_on;
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index dd2d44b40e22..8e33eb166bed 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -158,7 +158,6 @@ struct gc2235_device {
 	struct gc2235_resolution *res;
 
 	struct camera_sensor_platform_data *platform_data;
-	int vt_pix_clk_freq_mhz;
 	u8 type;
 };
 
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index d4cd6f27ee8d..5802cdb0e90c 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -201,7 +201,6 @@ struct ov2722_device {
 	struct ov2722_resolution *res;
 
 	struct camera_sensor_platform_data *platform_data;
-	int vt_pix_clk_freq_mhz;
 	int run_mode;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index 9adaf2fc940a..e65759499d81 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -433,84 +433,6 @@ static int ov5693_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
 	return 0;
 }
 
-static int ov5693_get_intg_factor(struct i2c_client *client,
-				  struct camera_mipi_info *info,
-				  const struct ov5693_resolution *res)
-{
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct ov5693_device *dev = to_ov5693_sensor(sd);
-	struct atomisp_sensor_mode_data *buf = &info->data;
-	unsigned int pix_clk_freq_hz;
-	u16 reg_val;
-	int ret;
-
-	if (!info)
-		return -EINVAL;
-
-	/* pixel clock */
-	pix_clk_freq_hz = res->pix_clk_freq * 1000000;
-
-	dev->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
-	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
-
-	/* get integration time */
-	buf->coarse_integration_time_min = OV5693_COARSE_INTG_TIME_MIN;
-	buf->coarse_integration_time_max_margin =
-	    OV5693_COARSE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_min = OV5693_FINE_INTG_TIME_MIN;
-	buf->fine_integration_time_max_margin =
-	    OV5693_FINE_INTG_TIME_MAX_MARGIN;
-
-	buf->fine_integration_time_def = OV5693_FINE_INTG_TIME_MIN;
-	buf->frame_length_lines = res->lines_per_frame;
-	buf->line_length_pck = res->pixels_per_line;
-	buf->read_mode = res->bin_mode;
-
-	/* get the cropping and output resolution to ISP for this mode. */
-	ret =  ov5693_read_reg(client, OV5693_16BIT,
-			       OV5693_HORIZONTAL_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_start = reg_val;
-
-	ret =  ov5693_read_reg(client, OV5693_16BIT,
-			       OV5693_VERTICAL_START_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_start = reg_val;
-
-	ret = ov5693_read_reg(client, OV5693_16BIT,
-			      OV5693_HORIZONTAL_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_horizontal_end = reg_val;
-
-	ret = ov5693_read_reg(client, OV5693_16BIT,
-			      OV5693_VERTICAL_END_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->crop_vertical_end = reg_val;
-
-	ret = ov5693_read_reg(client, OV5693_16BIT,
-			      OV5693_HORIZONTAL_OUTPUT_SIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_width = reg_val;
-
-	ret = ov5693_read_reg(client, OV5693_16BIT,
-			      OV5693_VERTICAL_OUTPUT_SIZE_H, &reg_val);
-	if (ret)
-		return ret;
-	buf->output_height = reg_val;
-
-	buf->binning_factor_x = res->bin_factor_x ?
-				res->bin_factor_x : 1;
-	buf->binning_factor_y = res->bin_factor_y ?
-				res->bin_factor_y : 1;
-	return 0;
-}
-
 static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -1596,18 +1518,10 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
 	if (ret)
 		dev_warn(&client->dev, "ov5693 stream off err\n");
 
-	ret = ov5693_get_intg_factor(client, ov5693_info,
-				     &ov5693_res[dev->fmt_idx]);
-	if (ret) {
-		dev_err(&client->dev, "failed to get integration_factor\n");
-		goto err;
-	}
-
 	ov5693_info->metadata_width = fmt->width * 10 / 8;
 	ov5693_info->metadata_height = 1;
 	ov5693_info->metadata_effective_width = &ov5693_embedded_effective_size;
 
-err:
 	mutex_unlock(&dev->input_lock);
 	return ret;
 }
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index a1366666f49c..c9b9dc780f96 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -228,7 +228,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;
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index e70e57695300..d6da776e9bf4 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -636,28 +636,6 @@ struct atomisp_overlay {
 	unsigned int overlay_start_y;
 };
 
-/* Sensor resolution specific data for AE calculation.*/
-struct atomisp_sensor_mode_data {
-	unsigned int coarse_integration_time_min;
-	unsigned int coarse_integration_time_max_margin;
-	unsigned int fine_integration_time_min;
-	unsigned int fine_integration_time_max_margin;
-	unsigned int fine_integration_time_def;
-	unsigned int frame_length_lines;
-	unsigned int line_length_pck;
-	unsigned int read_mode;
-	unsigned int vt_pix_clk_freq_mhz;
-	unsigned int crop_horizontal_start; /* Sensor crop start cord. (x0,y0)*/
-	unsigned int crop_vertical_start;
-	unsigned int crop_horizontal_end; /* Sensor crop end cord. (x1,y1)*/
-	unsigned int crop_vertical_end;
-	unsigned int output_width; /* input size to ISP after binning/scaling */
-	unsigned int output_height;
-	u8 binning_factor_x; /* horizontal binning factor used */
-	u8 binning_factor_y; /* vertical binning factor used */
-	u16 hts;
-};
-
 struct atomisp_exposure {
 	unsigned int integration_time[8];
 	unsigned int shutter_speed[8];
@@ -945,10 +923,6 @@ struct atomisp_sensor_ae_bracketing_lut {
 #define ATOMISP_IOC_CAMERA_BRIDGE \
 	_IOWR('v', BASE_VIDIOC_PRIVATE + 19, struct atomisp_bc_video_package)
 
-/* Sensor resolution specific info for AE */
-#define ATOMISP_IOC_G_SENSOR_MODE_DATA \
-	_IOR('v', BASE_VIDIOC_PRIVATE + 20, struct atomisp_sensor_mode_data)
-
 #define ATOMISP_IOC_S_EXPOSURE \
 	_IOW('v', BASE_VIDIOC_PRIVATE + 21, struct atomisp_exposure)
 
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
index 0253661d4332..559a497975c5 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
@@ -210,7 +210,6 @@ struct camera_mipi_info {
 	unsigned int                    num_lanes;
 	enum atomisp_input_format       input_format;
 	enum atomisp_bayer_order        raw_bayer_order;
-	struct atomisp_sensor_mode_data data;
 	enum atomisp_input_format       metadata_format;
 	u32                             metadata_width;
 	u32                             metadata_height;
diff --git a/drivers/staging/media/atomisp/notes.txt b/drivers/staging/media/atomisp/notes.txt
index d3cf6ed547ae..c04c283ff438 100644
--- a/drivers/staging/media/atomisp/notes.txt
+++ b/drivers/staging/media/atomisp/notes.txt
@@ -36,12 +36,6 @@ a camera_mipi_info struct. This struct is allocated/managed by
 the core atomisp code. The most important parts of the struct
 are filled by the atomisp core itself, like e.g. the port number.
 
-The sensor drivers on a set_fmt call do fill in camera_mipi_info.data
-which is a atomisp_sensor_mode_data struct. This gets filled from
-a function called <sensor_name>_get_intg_factor(). This struct is not
-used by the atomisp code at all. It is returned to userspace by
-a ATOMISP_IOC_G_SENSOR_MODE_DATA and the Android userspace does use this.
-
 Other members of camera_mipi_info which are set by some drivers are:
 -metadata_width, metadata_height, metadata_effective_width, set by
  the ov5693 driver (and used by the atomisp core)
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index b167ee32a952..01c9845b9f28 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -4211,25 +4211,6 @@ int atomisp_digital_zoom(struct atomisp_sub_device *asd, int flag,
 	return 0;
 }
 
-/*
- * Function to get sensor specific info for current resolution,
- * which will be used for auto exposure conversion.
- */
-int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
-				 struct atomisp_sensor_mode_data *config)
-{
-	struct camera_mipi_info *mipi_info;
-	struct atomisp_device *isp = asd->isp;
-
-	mipi_info = atomisp_to_sensor_mipi_info(
-			isp->inputs[asd->input_curr].camera);
-	if (!mipi_info)
-		return -EINVAL;
-
-	memcpy(config, &mipi_info->data, sizeof(*config));
-	return 0;
-}
-
 static void __atomisp_update_stream_env(struct atomisp_sub_device *asd,
 					u16 stream_index, struct atomisp_input_stream_info *stream_info)
 {
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index 99bbab402c9c..a10577df10cb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -258,9 +258,6 @@ int atomisp_makeup_css_parameters(struct atomisp_sub_device *asd,
 int atomisp_compare_grid(struct atomisp_sub_device *asd,
 			 struct atomisp_grid_info *atomgrid);
 
-int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
-				 struct atomisp_sensor_mode_data *config);
-
 /* This function looks up the closest available resolution. */
 int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
 		    bool *res_overflow);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index faf65387df56..d202b2b9ae18 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -2273,10 +2273,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
 		err = atomisp_fixed_pattern_table(asd, arg);
 		break;
 
-	case ATOMISP_IOC_G_SENSOR_MODE_DATA:
-		err = atomisp_get_sensor_mode_data(asd, arg);
-		break;
-
 	case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
 		if (motor)
 			err = v4l2_subdev_call(motor, core, ioctl, cmd, arg);
-- 
2.39.0


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

* [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (8 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:33   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info Hans de Goede
                   ` (47 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The bin-factor-x and bin-factor-y ctrls are only used internally to
get a single value to pass to atomisp_css_input_set_binning_factor(),
which is supposed to tune the lens-shading correction for the binning
factor. But all sensor drivers return either 0 or 1 for this,
with 0 meaning unset and 1 meaning no-binning. Even though some modes
do actually do binning ...

Also note that the removed atomisp_get_sensor_bin_factor() would fall
back to 0 if either the x and y factor differ or if the ctrls are not
implemented (not all sensor drivers implement them).

Simply always pass 0 to atomisp_css_input_set_binning_factor().

This is part of a patch-series which tries to remove atomisp specific /
custom code from the sensor drivers, with as end goal to make the atomisp
drivers regular camera sensor drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-gc0310.c        | 46 -----------------
 .../media/atomisp/i2c/atomisp-mt9m114.c       | 46 -----------------
 .../media/atomisp/i2c/atomisp-ov2680.c        | 49 -------------------
 .../media/atomisp/i2c/ov5693/atomisp-ov5693.c | 46 -----------------
 .../media/atomisp/include/linux/atomisp.h     |  4 --
 .../staging/media/atomisp/pci/atomisp_ioctl.c | 20 --------
 .../media/atomisp/pci/atomisp_subdev.c        | 36 +-------------
 7 files changed, 1 insertion(+), 246 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index 4968ec51ff1b..0d90683ed227 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -241,24 +241,6 @@ static int gc0310_write_reg_array(struct i2c_client *client,
 	return __gc0310_flush_reg_array(client, &ctrl);
 }
 
-static int gc0310_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
-{
-	struct gc0310_device *dev = to_gc0310_sensor(sd);
-
-	*val = dev->res->bin_factor_x;
-
-	return 0;
-}
-
-static int gc0310_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
-{
-	struct gc0310_device *dev = to_gc0310_sensor(sd);
-
-	*val = dev->res->bin_factor_y;
-
-	return 0;
-}
-
 static int gc0310_set_gain(struct v4l2_subdev *sd, int gain)
 
 {
@@ -441,12 +423,6 @@ static int gc0310_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = gc0310_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_BIN_FACTOR_HORZ:
-		ret = gc0310_g_bin_factor_x(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_BIN_FACTOR_VERT:
-		ret = gc0310_g_bin_factor_y(&dev->sd, &ctrl->val);
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -491,28 +467,6 @@ static const struct v4l2_ctrl_config gc0310_controls[] = {
 		.step = 1,
 		.def = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_HORZ,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "horizontal binning factor",
-		.min = 0,
-		.max = GC0310_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_VERT,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "vertical binning factor",
-		.min = 0,
-		.max = GC0310_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
 };
 
 static int gc0310_init(struct v4l2_subdev *sd)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index 1df38f5fe1f4..0e5a981dd331 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -1016,24 +1016,6 @@ static int mt9m114_s_exposure_selection(struct v4l2_subdev *sd,
 	return 0;
 }
 
-static int mt9m114_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
-{
-	struct mt9m114_device *dev = to_mt9m114_sensor(sd);
-
-	*val = mt9m114_res[dev->res].bin_factor_x;
-
-	return 0;
-}
-
-static int mt9m114_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
-{
-	struct mt9m114_device *dev = to_mt9m114_sensor(sd);
-
-	*val = mt9m114_res[dev->res].bin_factor_y;
-
-	return 0;
-}
-
 static int mt9m114_s_ev(struct v4l2_subdev *sd, s32 val)
 {
 	struct i2c_client *c = v4l2_get_subdevdata(sd);
@@ -1159,12 +1141,6 @@ static int mt9m114_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ZONE_NUM:
 		ret = mt9m114_g_exposure_zone_num(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_BIN_FACTOR_HORZ:
-		ret = mt9m114_g_bin_factor_x(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_BIN_FACTOR_VERT:
-		ret = mt9m114_g_bin_factor_y(&dev->sd, &ctrl->val);
-		break;
 	case V4L2_CID_EXPOSURE:
 		ret = mt9m114_g_ev(&dev->sd, &ctrl->val);
 		break;
@@ -1237,28 +1213,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = {
 		.def = 1,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_HORZ,
-		.name = "horizontal binning factor",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.min = 0,
-		.max = MT9M114_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_VERT,
-		.name = "vertical binning factor",
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.min = 0,
-		.max = MT9M114_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_EXPOSURE,
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 9379c25205b4..88fdeb828c6c 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -119,27 +119,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
 	return 0;
 }
 
-static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_x\n");
-	*val = dev->res->bin_factor_x;
-
-	return 0;
-}
-
-static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	*val = dev->res->bin_factor_y;
-	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_y\n");
-	return 0;
-}
-
 static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -419,12 +398,6 @@ static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
 		ret = ov2680_q_exposure(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_BIN_FACTOR_HORZ:
-		ret = ov2680_g_bin_factor_x(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_BIN_FACTOR_VERT:
-		ret = ov2680_g_bin_factor_y(&dev->sd, &ctrl->val);
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -449,28 +422,6 @@ static const struct v4l2_ctrl_config ov2680_controls[] = {
 		.def = 0x00,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_HORZ,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "horizontal binning factor",
-		.min = 0,
-		.max = OV2680_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_VERT,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "vertical binning factor",
-		.min = 0,
-		.max = OV2680_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
 	{
 		.ops = &ctrl_ops,
 		.id = V4L2_CID_VFLIP,
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index e65759499d81..da8c3b1d3bcd 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -415,24 +415,6 @@ static int ov5693_write_reg_array(struct i2c_client *client,
 	return __ov5693_flush_reg_array(client, &ctrl);
 }
 
-static int ov5693_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
-{
-	struct ov5693_device *dev = to_ov5693_sensor(sd);
-
-	*val = ov5693_res[dev->fmt_idx].bin_factor_x;
-
-	return 0;
-}
-
-static int ov5693_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
-{
-	struct ov5693_device *dev = to_ov5693_sensor(sd);
-
-	*val = ov5693_res[dev->fmt_idx].bin_factor_y;
-
-	return 0;
-}
-
 static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 				  int gain, int digitgain)
 
@@ -1014,12 +996,6 @@ static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_FOCUS_STATUS:
 		ret = ov5693_q_focus_status(&dev->sd, &ctrl->val);
 		break;
-	case V4L2_CID_BIN_FACTOR_HORZ:
-		ret = ov5693_g_bin_factor_x(&dev->sd, &ctrl->val);
-		break;
-	case V4L2_CID_BIN_FACTOR_VERT:
-		ret = ov5693_g_bin_factor_y(&dev->sd, &ctrl->val);
-		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -1099,28 +1075,6 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
 		.def = 0,
 		.flags = 0,
 	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_HORZ,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "horizontal binning factor",
-		.min = 0,
-		.max = OV5693_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_BIN_FACTOR_VERT,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "vertical binning factor",
-		.min = 0,
-		.max = OV5693_BIN_FACTOR_MAX,
-		.step = 1,
-		.def = 0,
-		.flags = 0,
-	},
 };
 
 static int ov5693_init(struct v4l2_subdev *sd)
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index d6da776e9bf4..63b1bcd35399 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -1071,10 +1071,6 @@ struct atomisp_sensor_ae_bracketing_lut {
 /* Query Focus Status */
 #define V4L2_CID_FOCUS_STATUS              (V4L2_CID_CAMERA_LASTP1 + 14)
 
-/* Query sensor's binning factor */
-#define V4L2_CID_BIN_FACTOR_HORZ	   (V4L2_CID_CAMERA_LASTP1 + 15)
-#define V4L2_CID_BIN_FACTOR_VERT	   (V4L2_CID_CAMERA_LASTP1 + 16)
-
 /* number of frames to skip at stream start */
 #define V4L2_CID_G_SKIP_FRAMES		   (V4L2_CID_CAMERA_LASTP1 + 17)
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index d202b2b9ae18..9cb9685d91bb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -172,24 +172,6 @@ static struct v4l2_queryctrl ci_v4l2_controls[] = {
 		.step = 1,
 		.default_value = 1,
 	},
-	{
-		.id = V4L2_CID_BIN_FACTOR_HORZ,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Horizontal binning factor",
-		.minimum = 0,
-		.maximum = 10,
-		.step = 1,
-		.default_value = 0,
-	},
-	{
-		.id = V4L2_CID_BIN_FACTOR_VERT,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "Vertical binning factor",
-		.minimum = 0,
-		.maximum = 10,
-		.step = 1,
-		.default_value = 0,
-	},
 	{
 		.id = V4L2_CID_2A_STATUS,
 		.type = V4L2_CTRL_TYPE_BITMASK,
@@ -1827,8 +1809,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
 		case V4L2_CID_EXPOSURE_ABSOLUTE:
 		case V4L2_CID_EXPOSURE_AUTO:
 		case V4L2_CID_IRIS_ABSOLUTE:
-		case V4L2_CID_BIN_FACTOR_HORZ:
-		case V4L2_CID_BIN_FACTOR_VERT:
 		case V4L2_CID_3A_LOCK:
 		case V4L2_CID_TEST_PATTERN:
 		case V4L2_CID_TEST_PATTERN_COLOR_R:
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index cadc468b4c2f..fc9e07bf63ae 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -574,40 +574,6 @@ static int isp_subdev_set_selection(struct v4l2_subdev *sd,
 					    sel->target, sel->flags, &sel->r);
 }
 
-static int atomisp_get_sensor_bin_factor(struct atomisp_sub_device *asd)
-{
-	struct v4l2_control ctrl = {0};
-	struct atomisp_device *isp = asd->isp;
-	int hbin, vbin;
-	int ret;
-
-	if (isp->inputs[asd->input_curr].type == FILE_INPUT ||
-	    isp->inputs[asd->input_curr].type == TEST_PATTERN)
-		return 0;
-
-	ctrl.id = V4L2_CID_BIN_FACTOR_HORZ;
-	ret =
-	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
-			&ctrl);
-	hbin = ctrl.value;
-	ctrl.id = V4L2_CID_BIN_FACTOR_VERT;
-	ret |=
-	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
-			&ctrl);
-	vbin = ctrl.value;
-
-	/*
-	 * ISP needs to know binning factor from sensor.
-	 * In case horizontal and vertical sensor's binning factors
-	 * are different or sensor does not support binning factor CID,
-	 * ISP will apply default 0 value.
-	 */
-	if (ret || hbin != vbin)
-		hbin = 0;
-
-	return hbin;
-}
-
 void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
 			     struct v4l2_subdev_state *sd_state,
 			     uint32_t which,
@@ -645,7 +611,7 @@ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
 							 ATOMISP_INPUT_STREAM_GENERAL, ffmt);
 			atomisp_css_input_set_binning_factor(isp_sd,
 							     ATOMISP_INPUT_STREAM_GENERAL,
-							     atomisp_get_sensor_bin_factor(isp_sd));
+							     0);
 			atomisp_css_input_set_bayer_order(isp_sd, ATOMISP_INPUT_STREAM_GENERAL,
 							  fc->bayer_order);
 			atomisp_css_input_set_format(isp_sd, ATOMISP_INPUT_STREAM_GENERAL,
-- 
2.39.0


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

* [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (9 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:33   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup() Hans de Goede
                   ` (46 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Remove the no longer used bin_factor_x, bin_factor_y and bin_mode members
from the resolution info inside various atomisp camera sensor drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/gc0310.h    |  6 --
 drivers/staging/media/atomisp/i2c/gc2235.h    | 27 ---------
 drivers/staging/media/atomisp/i2c/mt9m114.h   | 12 ----
 drivers/staging/media/atomisp/i2c/ov2680.h    | 39 ------------
 drivers/staging/media/atomisp/i2c/ov2722.h    | 30 ----------
 .../staging/media/atomisp/i2c/ov5693/ov5693.h | 60 -------------------
 6 files changed, 174 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
index 2a559b0d474d..cae480ae6fba 100644
--- a/drivers/staging/media/atomisp/i2c/gc0310.h
+++ b/drivers/staging/media/atomisp/i2c/gc0310.h
@@ -123,9 +123,6 @@ struct gc0310_resolution {
 	u32 skip_frames;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 	bool used;
 };
 
@@ -386,9 +383,6 @@ static struct gc0310_resolution gc0310_res_preview[] = {
 		.pixels_per_line = 0x0314,
 		.lines_per_frame = 0x0213,
 #endif
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 2,
 		.regs = gc0310_VGA_30fps,
 	},
diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
index 8e33eb166bed..55ea422291ba 100644
--- a/drivers/staging/media/atomisp/i2c/gc2235.h
+++ b/drivers/staging/media/atomisp/i2c/gc2235.h
@@ -134,9 +134,6 @@ struct gc2235_resolution {
 	u32 skip_frames;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 	bool used;
 };
 
@@ -536,9 +533,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1068,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1600_900_30fps,
 	},
@@ -552,9 +546,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1368,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1616_1082_30fps,
 	},
@@ -567,9 +558,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1368,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1616_1216_30fps,
 	},
@@ -593,9 +581,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1068,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1600_900_30fps,
 	},
@@ -608,9 +593,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1368,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1616_1082_30fps,
 	},
@@ -623,9 +605,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2132,
 		.lines_per_frame = 1368,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1616_1216_30fps,
 	},
@@ -644,9 +623,6 @@ static struct gc2235_resolution gc2235_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 1828,
 		.lines_per_frame = 888,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_1296_736_30fps,
 	},
@@ -659,9 +635,6 @@ static struct gc2235_resolution gc2235_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 1492,
 		.lines_per_frame = 792,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = gc2235_960_640_30fps,
 	},
diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h
index 831875071cbb..b0cd1b724394 100644
--- a/drivers/staging/media/atomisp/i2c/mt9m114.h
+++ b/drivers/staging/media/atomisp/i2c/mt9m114.h
@@ -316,9 +316,6 @@ struct mt9m114_res_struct {
 	struct regval_list *regs;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 };
 
 /* 2 bytes used for address: 256 bytes total */
@@ -350,9 +347,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
 
 		.pixels_per_line = 0x0640,
 		.lines_per_frame = 0x0307,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 	},
 	{
 		.desc	= "848P",
@@ -366,9 +360,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
 
 		.pixels_per_line = 0x0640,
 		.lines_per_frame = 0x03E8,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 	},
 	{
 		.desc	= "960P",
@@ -382,9 +373,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
 
 		.pixels_per_line = 0x0644, /* consistent with regs arrays */
 		.lines_per_frame = 0x03E5, /* consistent with regs arrays */
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 	},
 };
 
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 2bc350c67711..596e14453fb3 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -147,9 +147,6 @@ struct ov2680_resolution {
 	u32 skip_frames;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 };
 
 struct ov2680_format {
@@ -758,9 +755,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.fps = 30,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_1616x1216_30fps,
 	},
@@ -771,9 +765,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.fps = 30,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_1616x1082_30fps,
 	},
@@ -784,9 +775,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_1616x916_30fps,
 	},
@@ -797,9 +785,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_1456x1096_30fps,
 	},
@@ -810,9 +795,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_1296x976_30fps,
 	},
@@ -823,9 +805,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_720p_30fps,
 	},
@@ -836,9 +815,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_800x600_30fps,
 	},
@@ -849,9 +825,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_720x592_30fps,
 	},
@@ -862,9 +835,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_656x496_30fps,
 	},
@@ -875,9 +845,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_QVGA_30fps,
 	},
@@ -888,9 +855,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_CIF_30fps,
 	},
@@ -901,9 +865,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
 		.pix_clk_freq = 66,
 		.pixels_per_line = 1698,//1704,
 		.lines_per_frame = 1294,
-		.bin_factor_x = 0,
-		.bin_factor_y = 0,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2680_QCIF_30fps,
 	},
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index 5802cdb0e90c..020743a944c4 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -177,9 +177,6 @@ struct ov2722_resolution {
 	u32 skip_frames;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 	bool used;
 	int mipi_freq;
 };
@@ -1109,9 +1106,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2260,
 		.lines_per_frame = 1244,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1632_1092_30fps,
 		.mipi_freq = 422400,
@@ -1125,9 +1119,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2260,
 		.lines_per_frame = 1244,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1452_1092_30fps,
 		.mipi_freq = 422400,
@@ -1141,9 +1132,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
 		.used = 0,
 		.pixels_per_line = 2068,
 		.lines_per_frame = 1114,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1080p_30fps,
 		.mipi_freq = 345600,
@@ -1167,9 +1155,6 @@ struct ov2722_resolution ov2722_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2260,
 		.lines_per_frame = 1244,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1632_1092_30fps,
 		.mipi_freq = 422400,
@@ -1183,9 +1168,6 @@ struct ov2722_resolution ov2722_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2260,
 		.lines_per_frame = 1244,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1452_1092_30fps,
 		.mipi_freq = 422400,
@@ -1199,9 +1181,6 @@ struct ov2722_resolution ov2722_res_still[] = {
 		.used = 0,
 		.pixels_per_line = 2068,
 		.lines_per_frame = 1114,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1080p_30fps,
 		.mipi_freq = 345600,
@@ -1220,9 +1199,6 @@ struct ov2722_resolution ov2722_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2048,
 		.lines_per_frame = 1184,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_QVGA_30fps,
 		.mipi_freq = 364800,
@@ -1236,9 +1212,6 @@ struct ov2722_resolution ov2722_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2048,
 		.lines_per_frame = 1184,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_480P_30fps,
 	},
@@ -1251,9 +1224,6 @@ struct ov2722_resolution ov2722_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2068,
 		.lines_per_frame = 1114,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.skip_frames = 3,
 		.regs = ov2722_1080p_30fps,
 		.mipi_freq = 345600,
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index c9b9dc780f96..5e17eaf8fd6e 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -198,9 +198,6 @@ struct ov5693_resolution {
 	int pix_clk_freq;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
-	u8 bin_factor_x;
-	u8 bin_factor_y;
-	u8 bin_mode;
 	bool used;
 };
 
@@ -1109,9 +1106,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
 		.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,
 	},
 	{
@@ -1123,9 +1117,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
 		.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,
 	},
 	{
@@ -1137,9 +1128,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
 		.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,
 	},
 	{
@@ -1151,9 +1139,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
 		.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,
 	},
 };
@@ -1175,9 +1160,6 @@ struct ov5693_resolution ov5693_res_still[] = {
 		.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,
 	},
 	{
@@ -1189,9 +1171,6 @@ struct ov5693_resolution ov5693_res_still[] = {
 		.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,
 	},
 	{
@@ -1203,9 +1182,6 @@ struct ov5693_resolution ov5693_res_still[] = {
 		.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,
 	},
 	{
@@ -1217,9 +1193,6 @@ struct ov5693_resolution ov5693_res_still[] = {
 		.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,
 	},
 	{
@@ -1231,9 +1204,6 @@ struct ov5693_resolution ov5693_res_still[] = {
 		.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,
 	},
 };
@@ -1250,9 +1220,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 1,
 		.regs = ov5693_736x496,
 	},
 	{
@@ -1264,9 +1231,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 1,
 		.regs = ov5693_336x256,
 	},
 	{
@@ -1278,9 +1242,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 1,
 		.regs = ov5693_368x304,
 	},
 	{
@@ -1292,9 +1253,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 1,
 		.regs = ov5693_192x160,
 	},
 	{
@@ -1306,9 +1264,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 0,
 		.regs = ov5693_1296x736,
 	},
 	{
@@ -1320,9 +1275,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 2,
-		.bin_factor_y = 2,
-		.bin_mode = 0,
 		.regs = ov5693_1296x976,
 	},
 	{
@@ -1334,9 +1286,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.regs = ov5693_1636p_30fps,
 	},
 	{
@@ -1348,9 +1297,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.used = 0,
 		.pixels_per_line = 2688,
 		.lines_per_frame = 1984,
-		.bin_factor_x = 1,
-		.bin_factor_y = 1,
-		.bin_mode = 0,
 		.regs = ov5693_1940x1096,
 	},
 	{
@@ -1362,9 +1308,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.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,
 	},
 	{
@@ -1376,9 +1319,6 @@ struct ov5693_resolution ov5693_res_video[] = {
 		.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,
 	},
 };
-- 
2.39.0


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

* [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (10 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:35   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 13/57] media: atomisp: Remove deferred firmware loading support Hans de Goede
                   ` (45 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

If set_fmt() fails make queue_setup() actually return the error instead of
returning 0.

This fixes the following oops on set_fmt() failures:

[ 1060.378662] ------------[ cut here ]------------
[ 1060.378805] WARNING: CPU: 0 PID: 2080 at drivers/media/common/videobuf2/videobuf2-core.c:840 vb2_core_reqbufs+0x3f7/0x430 [videobuf2_common]
...
[ 1060.381414] RIP: 0010:vb2_core_reqbufs+0x3f7/0x430 [videobuf2_common]
...
[ 1060.382066]  vb2_ioctl_reqbufs+0x9d/0xe0 [videobuf2_v4l2]
[ 1060.382181]  __video_do_ioctl+0x18e/0x3c0 [videodev]

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_fops.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 4643bb0db995..682239ea042f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -80,7 +80,7 @@ static int atomisp_queue_setup(struct vb2_queue *vq,
 
 out:
 	mutex_unlock(&pipe->asd->isp->mutex);
-	return 0;
+	return ret;
 }
 
 static int atomisp_buf_init(struct vb2_buffer *vb)
-- 
2.39.0


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

* [PATCH 13/57] media: atomisp: Remove deferred firmware loading support
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (11 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:37   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper() Hans de Goede
                   ` (44 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Make atomisp behave like any othet drivers and have it load the firmware
at probe time (as it was already doing by default).

The deferred firmware loading support needlessly complicates the
v4l2_file_operations.open callback (atomisp_open()), getting in
the way of allowing multiple opens like a normal v4l2 device would.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/pci/atomisp_fops.c  | 25 -----------
 .../staging/media/atomisp/pci/atomisp_fops.h  |  2 -
 .../staging/media/atomisp/pci/atomisp_v4l2.c  | 42 +++++++------------
 3 files changed, 14 insertions(+), 55 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 682239ea042f..036ad339b344 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -757,25 +757,6 @@ static int atomisp_open(struct file *file)
 	mutex_lock(&isp->mutex);
 
 	asd->subdev.devnode = vdev;
-	/* Deferred firmware loading case. */
-	if (isp->css_env.isp_css_fw.bytes == 0) {
-		dev_err(isp->dev, "Deferred firmware load.\n");
-		isp->firmware = atomisp_load_firmware(isp);
-		if (!isp->firmware) {
-			dev_err(isp->dev, "Failed to load ISP firmware.\n");
-			ret = -ENOENT;
-			goto error;
-		}
-		ret = atomisp_css_load_firmware(isp);
-		if (ret) {
-			dev_err(isp->dev, "Failed to init css.\n");
-			goto error;
-		}
-		/* No need to keep FW in memory anymore. */
-		release_firmware(isp->firmware);
-		isp->firmware = NULL;
-		isp->css_env.isp_css_fw.data = NULL;
-	}
 
 	if (!isp->input_cnt) {
 		dev_err(isp->dev, "no camera attached\n");
@@ -901,12 +882,6 @@ static int atomisp_release(struct file *file)
 
 	atomisp_destroy_pipes_stream_force(asd);
 
-	if (defer_fw_load) {
-		ia_css_unload_firmware();
-		isp->css_env.isp_css_fw.data = NULL;
-		isp->css_env.isp_css_fw.bytes = 0;
-	}
-
 	ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
 		dev_warn(isp->dev, "Failed to power-off flash\n");
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp_fops.h
index 10e43126b693..2efc5245e571 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h
@@ -33,6 +33,4 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd);
 
 extern const struct v4l2_file_operations atomisp_fops;
 
-extern bool defer_fw_load;
-
 #endif /* __ATOMISP_FOPS_H__ */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index aa05c69a5c6b..2a949d3dc5d1 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -58,12 +58,6 @@ static uint skip_fwload;
 module_param(skip_fwload, uint, 0644);
 MODULE_PARM_DESC(skip_fwload, "Skip atomisp firmware load");
 
-/* memory optimization: deferred firmware loading */
-bool defer_fw_load;
-module_param(defer_fw_load, bool, 0644);
-MODULE_PARM_DESC(defer_fw_load,
-		 "Defer FW loading until device is opened (default:disable)");
-
 /* cross componnet debug message flag */
 int dbg_level;
 module_param(dbg_level, int, 0644);
@@ -1514,21 +1508,17 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 	isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY;
 
 	/* Load isp firmware from user space */
-	if (!defer_fw_load) {
-		isp->firmware = atomisp_load_firmware(isp);
-		if (!isp->firmware) {
-			err = -ENOENT;
-			dev_dbg(&pdev->dev, "Firmware load failed\n");
-			goto load_fw_fail;
-		}
+	isp->firmware = atomisp_load_firmware(isp);
+	if (!isp->firmware) {
+		err = -ENOENT;
+		dev_dbg(&pdev->dev, "Firmware load failed\n");
+		goto load_fw_fail;
+	}
 
-		err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
-		if (err) {
-			dev_dbg(&pdev->dev, "Firmware version check failed\n");
-			goto fw_validation_fail;
-		}
-	} else {
-		dev_info(&pdev->dev, "Firmware load will be deferred\n");
+	err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
+	if (err) {
+		dev_dbg(&pdev->dev, "Firmware version check failed\n");
+		goto fw_validation_fail;
 	}
 
 	pci_set_master(pdev);
@@ -1628,14 +1618,10 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 	}
 
 	/* Load firmware into ISP memory */
-	if (!defer_fw_load) {
-		err = atomisp_css_load_firmware(isp);
-		if (err) {
-			dev_err(&pdev->dev, "Failed to init css.\n");
-			goto css_init_fail;
-		}
-	} else {
-		dev_dbg(&pdev->dev, "Skip css init.\n");
+	err = atomisp_css_load_firmware(isp);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to init css.\n");
+		goto css_init_fail;
 	}
 	/* Clear FW image from memory */
 	release_firmware(isp->firmware);
-- 
2.39.0


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

* [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (12 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 13/57] media: atomisp: Remove deferred firmware loading support Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 14:38   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe() Hans de Goede
                   ` (43 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Check buffer index is in range inside atomisp_qbuf_wrapper() before
using it do index pipe->frame_request_config_id[].

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 9cb9685d91bb..d0dd3dbd6f6a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1056,6 +1056,9 @@ static int atomisp_qbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer
 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
 
 	/* FIXME this abuse of buf->reserved2 comes from the original atomisp buffer handling */
+	if (buf->index >= vdev->queue->num_buffers)
+		return -EINVAL;
+
 	if (!atomisp_is_vf_pipe(pipe) &&
 	    (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
 		/* this buffer will have a per-frame parameter */
-- 
2.39.0


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

* [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (13 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 15:30   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls Hans de Goede
                   ` (42 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

atomisp_init_pipe() does 3 things:

1. Init a bunch of list-heads / locks
2. Init the vb_queue for the videodev (aka pipe)
3. zero the per-frame parameters related variables of the pipe

1. and 2. really should not be done at file-open time, but once at probe.
Currently the code is getting away with doing this on every videodev-open
because only 1 open is allowed at a time.

1. is already done at probe time by atomisp_init_subdev_pipe(), move 2. to
atomisp_init_subdev_pipe() so that it is also done once at probe.

As for 3. The per-frame parameters can only be set from a qbuf ioctl,
which can only happen after a reqbufs ioctl and atomisp_buf_cleanup
already zeros the per-frame parameters when the buffers are released,
so 3. is not necessary at all.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/pci/atomisp_fops.c  | 40 +--------------
 .../staging/media/atomisp/pci/atomisp_fops.h  |  1 +
 .../media/atomisp/pci/atomisp_subdev.c        | 49 +++++++++++++++----
 3 files changed, 41 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 036ad339b344..7f4934ff9cab 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -624,7 +624,7 @@ static void atomisp_buf_cleanup(struct vb2_buffer *vb)
 	hmm_free(frame->data);
 }
 
-static const struct vb2_ops atomisp_vb2_ops = {
+const struct vb2_ops atomisp_vb2_ops = {
 	.queue_setup		= atomisp_queue_setup,
 	.buf_init		= atomisp_buf_init,
 	.buf_cleanup		= atomisp_buf_cleanup,
@@ -633,40 +633,6 @@ static const struct vb2_ops atomisp_vb2_ops = {
 	.stop_streaming		= atomisp_stop_streaming,
 };
 
-static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
-{
-	int ret;
-
-	/* init locks */
-	spin_lock_init(&pipe->irq_lock);
-	mutex_init(&pipe->vb_queue_mutex);
-
-	/* Init videobuf2 queue structure */
-	pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR;
-	pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame);
-	pipe->vb_queue.ops = &atomisp_vb2_ops;
-	pipe->vb_queue.mem_ops = &vb2_vmalloc_memops;
-	pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	ret = vb2_queue_init(&pipe->vb_queue);
-	if (ret)
-		return ret;
-
-	pipe->vdev.queue = &pipe->vb_queue;
-	pipe->vdev.queue->lock = &pipe->vb_queue_mutex;
-
-	INIT_LIST_HEAD(&pipe->activeq);
-	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
-	INIT_LIST_HEAD(&pipe->per_frame_params);
-	memset(pipe->frame_request_config_id, 0,
-	       VIDEO_MAX_FRAME * sizeof(unsigned int));
-	memset(pipe->frame_params, 0,
-	       VIDEO_MAX_FRAME *
-	       sizeof(struct atomisp_css_params_with_list *));
-
-	return 0;
-}
-
 static void atomisp_dev_init_struct(struct atomisp_device *isp)
 {
 	unsigned int i;
@@ -773,10 +739,6 @@ static int atomisp_open(struct file *file)
 		return -EBUSY;
 	}
 
-	ret = atomisp_init_pipe(pipe);
-	if (ret)
-		goto error;
-
 	if (atomisp_dev_users(isp)) {
 		dev_dbg(isp->dev, "skip init isp in open\n");
 		goto init_subdev;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp_fops.h
index 2efc5245e571..883c1851c1c9 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h
@@ -31,6 +31,7 @@ unsigned int atomisp_sub_dev_users(struct atomisp_sub_device *asd);
 
 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd);
 
+extern const struct vb2_ops atomisp_vb2_ops;
 extern const struct v4l2_file_operations atomisp_fops;
 
 #endif /* __ATOMISP_FOPS_H__ */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index fc9e07bf63ae..c32db4ffb778 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -25,9 +25,11 @@
 
 #include <media/v4l2-event.h>
 #include <media/v4l2-mediabus.h>
+#include <media/videobuf2-vmalloc.h>
 #include "atomisp_cmd.h"
 #include "atomisp_common.h"
 #include "atomisp_compat.h"
+#include "atomisp_fops.h"
 #include "atomisp_internal.h"
 
 const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
@@ -1023,14 +1025,31 @@ static const struct v4l2_ctrl_config ctrl_depth_mode = {
 	.def = 0,
 };
 
-static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
-				     struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
+static int atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
+				    struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
 {
+	int ret;
+
 	pipe->type = buf_type;
 	pipe->asd = asd;
 	pipe->isp = asd->isp;
 	spin_lock_init(&pipe->irq_lock);
 	mutex_init(&pipe->vb_queue_mutex);
+
+	/* Init videobuf2 queue structure */
+	pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR;
+	pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame);
+	pipe->vb_queue.ops = &atomisp_vb2_ops;
+	pipe->vb_queue.mem_ops = &vb2_vmalloc_memops;
+	pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	ret = vb2_queue_init(&pipe->vb_queue);
+	if (ret)
+		return ret;
+
+	pipe->vdev.queue = &pipe->vb_queue;
+	pipe->vdev.queue->lock = &pipe->vb_queue_mutex;
+
 	INIT_LIST_HEAD(&pipe->buffers_in_css);
 	INIT_LIST_HEAD(&pipe->activeq);
 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
@@ -1040,6 +1059,8 @@ static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
 	memset(pipe->frame_params,
 	       0, VIDEO_MAX_FRAME *
 	       sizeof(struct atomisp_css_params_with_list *));
+
+	return 0;
 }
 
 /*
@@ -1085,17 +1106,25 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
 	if (ret < 0)
 		return ret;
 
-	atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
-				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
+				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret)
+		return ret;
 
-	atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
-				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
+				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret)
+		return ret;
 
-	atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
-				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
+				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret)
+		return ret;
 
-	atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
-				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
+				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret)
+		return ret;
 
 	ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE",
 				 ATOMISP_RUN_MODE_STILL_CAPTURE);
-- 
2.39.0


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

* [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (14 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:41   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd Hans de Goede
                   ` (41 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The memory for all of struct atomisp_video_pipe is kzalloc()-ed in
atomisp_subdev_init() so there is no need to memset parts of
struct atomisp_video_pipe to 0.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_subdev.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index c32db4ffb778..eb8f319fca5c 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -1054,11 +1054,6 @@ static int atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
 	INIT_LIST_HEAD(&pipe->activeq);
 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
 	INIT_LIST_HEAD(&pipe->per_frame_params);
-	memset(pipe->frame_request_config_id,
-	       0, VIDEO_MAX_FRAME * sizeof(unsigned int));
-	memset(pipe->frame_params,
-	       0, VIDEO_MAX_FRAME *
-	       sizeof(struct atomisp_css_params_with_list *));
 
 	return 0;
 }
-- 
2.39.0


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

* [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (15 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:42   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 18/57] media: atomisp: Do not turn off sensor when the atomisp-sub-dev does not own it Hans de Goede
                   ` (40 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Calling v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode) when
the stream is already active (through another /dev/video# node) causes
the stream to stop.

Move the call to set the default run-mode so that it is only done
on the first open of one of the 4 /dev/video# nodes of one of
the 2 streams (atomisp-sub-devices / asd-s).

Fixes: 2c45e343c581 ("media: atomisp: set per-device's default mode")
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_fops.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 7f4934ff9cab..78af97a64362 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -764,13 +764,13 @@ static int atomisp_open(struct file *file)
 		goto done;
 
 	atomisp_subdev_init_struct(asd);
+	/* Ensure that a mode is set */
+	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
 
 done:
 	pipe->users++;
 	mutex_unlock(&isp->mutex);
 
-	/* Ensure that a mode is set */
-	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
 
 	return 0;
 
-- 
2.39.0


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

* [PATCH 18/57] media: atomisp: Do not turn off sensor when the atomisp-sub-dev does not own it
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (16 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback Hans de Goede
                   ` (39 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The atomisp driver creates 8 /dev/video# device nodes. 4 nodes (preview /
video / viewfinder / capture) for each of 2 possible streams aka
atomisp-sub-device-s (asd-s).

Both streams start with asd->input_curr set to 0 (to the first sensor),
opening + releasing a file-handle on one of the nodes of an asd,
while streaming from the other asd causes the sensor to get turned off,
leading to the stream failing.

The atomisp-code already tracks which asd "owns" a specific sensor,
use this to only turn the sensor off if it is owned by the asd.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_fops.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 78af97a64362..833c7aac8f0a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -828,13 +828,17 @@ static int atomisp_release(struct file *file)
 
 	atomisp_css_free_stat_buffers(asd);
 	atomisp_free_internal_buffers(asd);
-	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
-			       core, s_power, 0);
-	if (ret)
-		dev_warn(isp->dev, "Failed to power-off sensor\n");
 
-	/* clear the asd field to show this camera is not used */
-	isp->inputs[asd->input_curr].asd = NULL;
+	if (isp->inputs[asd->input_curr].asd == asd) {
+		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
+				       core, s_power, 0);
+		if (ret)
+			dev_warn(isp->dev, "Failed to power-off sensor\n");
+
+		/* clear the asd field to show this camera is not used */
+		isp->inputs[asd->input_curr].asd = NULL;
+	}
+
 	spin_lock_irqsave(&isp->lock, flags);
 	asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
 	spin_unlock_irqrestore(&isp->lock, flags);
-- 
2.39.0


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

* [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (17 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 18/57] media: atomisp: Do not turn off sensor when the atomisp-sub-dev does not own it Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:49   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC Hans de Goede
                   ` (38 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The s_power callback for v4l2-subdevs has been deprecated, allow sensor
drivers without a s_power callback to work by ignoring the -ENOIOCTLCMD
return value.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_fops.c  | 2 +-
 drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
index 833c7aac8f0a..ce01479bdd68 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
@@ -832,7 +832,7 @@ static int atomisp_release(struct file *file)
 	if (isp->inputs[asd->input_curr].asd == asd) {
 		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
 				       core, s_power, 0);
-		if (ret)
+		if (ret && ret != -ENOIOCTLCMD)
 			dev_warn(isp->dev, "Failed to power-off sensor\n");
 
 		/* clear the asd field to show this camera is not used */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index d0dd3dbd6f6a..77856cbc5ba7 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -700,7 +700,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
 	    asd->input_curr != input) {
 		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
 				       core, s_power, 0);
-		if (ret)
+		if (ret && ret != -ENOIOCTLCMD)
 			dev_warn(isp->dev,
 				 "Failed to power-off sensor\n");
 		/* clear the asd field to show this camera is not used */
@@ -709,7 +709,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
 
 	/* powe on the new sensor */
 	ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
-	if (ret) {
+	if (ret && ret != -ENOIOCTLCMD) {
 		dev_err(isp->dev, "Failed to power-on sensor\n");
 		return ret;
 	}
-- 
2.39.0


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

* [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (18 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:51   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev() Hans de Goede
                   ` (37 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The Crystal Cove PMIC used on some BYT/CHT devices has different revisions
when paired with Bay Trail (BYT) vs Cherry Trail (CHT) SoCs.

The current hardcoded values are only valid for CHT devices, change
the code so that it uses the correct register values on both BYT and CHT.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/pci/atomisp_gmin_platform.c | 22 +++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index 3d41fab661cf..6116d3c62315 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -57,8 +57,10 @@ enum clock_rate {
 #define LDO_1P8V_OFF	0x58 /* ... bottom bit is "enabled" */
 
 /* CRYSTAL COVE PMIC register set */
-#define CRYSTAL_1P8V_REG	0x57
-#define CRYSTAL_2P8V_REG	0x5d
+#define CRYSTAL_BYT_1P8V_REG	0x5d
+#define CRYSTAL_BYT_2P8V_REG	0x66
+#define CRYSTAL_CHT_1P8V_REG	0x57
+#define CRYSTAL_CHT_2P8V_REG	0x5d
 #define CRYSTAL_ON		0x63
 #define CRYSTAL_OFF		0x62
 
@@ -843,6 +845,7 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
 	struct gmin_subdev *gs = find_gmin_subdev(subdev);
 	int ret;
 	int value;
+	int reg;
 
 	if (!gs || gs->v1p8_on == on)
 		return 0;
@@ -898,10 +901,15 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
 				     LDO10_REG, value, 0xff);
 		break;
 	case PMIC_CRYSTALCOVE:
+		if (IS_ISP2401)
+			reg = CRYSTAL_CHT_1P8V_REG;
+		else
+			reg = CRYSTAL_BYT_1P8V_REG;
+
 		value = on ? CRYSTAL_ON : CRYSTAL_OFF;
 
 		ret = gmin_i2c_write(subdev->dev, gs->pwm_i2c_addr,
-				     CRYSTAL_1P8V_REG, value, 0xff);
+				     reg, value, 0xff);
 		break;
 	default:
 		dev_err(subdev->dev, "Couldn't set power mode for v1p8\n");
@@ -918,6 +926,7 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
 	struct gmin_subdev *gs = find_gmin_subdev(subdev);
 	int ret;
 	int value;
+	int reg;
 
 	if (WARN_ON(!gs))
 		return -ENODEV;
@@ -974,10 +983,15 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
 				     LDO9_REG, value, 0xff);
 		break;
 	case PMIC_CRYSTALCOVE:
+		if (IS_ISP2401)
+			reg = CRYSTAL_CHT_2P8V_REG;
+		else
+			reg = CRYSTAL_BYT_2P8V_REG;
+
 		value = on ? CRYSTAL_ON : CRYSTAL_OFF;
 
 		ret = gmin_i2c_write(subdev->dev, gs->pwm_i2c_addr,
-				     CRYSTAL_2P8V_REG, value, 0xff);
+				     reg, value, 0xff);
 		break;
 	default:
 		dev_err(subdev->dev, "Couldn't set power mode for v2p8\n");
-- 
2.39.0


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

* [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (19 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:53   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper Hans de Goede
                   ` (36 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

atomisp_gmin_find_subdev() can be used to lookup a subdev
given its i2c-adapter + i2c-client-address.

But the only caller of it reads this from the intel_v4l2_subdev_table
struct and that same struct already contains a pointer to the v4l2_subdev.

So this function is not necessary, drop it and modify its only caller
to directly take the subdev from the intel_v4l2_subdev_table struct.

Also drop struct intel_v4l2_subdev_i2c_board_info since that now no
longer is used.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../include/linux/atomisp_gmin_platform.h     |  2 -
 .../atomisp/include/linux/atomisp_platform.h  |  6 ---
 .../media/atomisp/pci/atomisp_gmin_platform.c | 27 ----------
 .../staging/media/atomisp/pci/atomisp_v4l2.c  | 54 +++----------------
 4 files changed, 7 insertions(+), 82 deletions(-)

diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
index 5463d11d4295..64bd54835c32 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
@@ -21,8 +21,6 @@
 int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 				struct camera_sensor_platform_data *plat_data,
 				enum intel_v4l2_subdev_type type);
-struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
-	struct i2c_board_info *board_info);
 int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd);
 int gmin_get_var_int(struct device *dev, bool is_gmin,
 		     const char *var, int def);
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
index 559a497975c5..82973aa0e1eb 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
@@ -125,13 +125,7 @@ struct intel_v4l2_subdev_id {
 	enum atomisp_camera_port    port;
 };
 
-struct intel_v4l2_subdev_i2c_board_info {
-	struct i2c_board_info board_info;
-	int i2c_adapter_id;
-};
-
 struct intel_v4l2_subdev_table {
-	struct intel_v4l2_subdev_i2c_board_info v4l2_subdev;
 	enum intel_v4l2_subdev_type type;
 	enum atomisp_camera_port port;
 	struct v4l2_subdev *subdev;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index 6116d3c62315..234088711f29 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -147,7 +147,6 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 				enum intel_v4l2_subdev_type type)
 {
 	int i;
-	struct i2c_board_info *bi;
 	struct gmin_subdev *gs;
 	struct i2c_client *client = v4l2_get_subdevdata(subdev);
 	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
@@ -181,36 +180,10 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 	pdata.subdevs[i].type = type;
 	pdata.subdevs[i].port = gs->csi_port;
 	pdata.subdevs[i].subdev = subdev;
-	pdata.subdevs[i].v4l2_subdev.i2c_adapter_id = client->adapter->nr;
-
-	/* Convert i2c_client to i2c_board_info */
-	bi = &pdata.subdevs[i].v4l2_subdev.board_info;
-	memcpy(bi->type, client->name, I2C_NAME_SIZE);
-	bi->flags = client->flags;
-	bi->addr = client->addr;
-	bi->irq = client->irq;
-	bi->platform_data = plat_data;
-
 	return 0;
 }
 EXPORT_SYMBOL_GPL(atomisp_register_i2c_module);
 
-struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
-	struct i2c_board_info *board_info)
-{
-	int i;
-
-	for (i = 0; i < MAX_SUBDEVS && pdata.subdevs[i].type; i++) {
-		struct intel_v4l2_subdev_table *sd = &pdata.subdevs[i];
-
-		if (sd->v4l2_subdev.i2c_adapter_id == adapter->nr &&
-		    sd->v4l2_subdev.board_info.addr == board_info->addr)
-			return sd->subdev;
-	}
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(atomisp_gmin_find_subdev);
-
 int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd)
 {
 	int i, j;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
index 2a949d3dc5d1..ba628f7cf385 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
@@ -937,45 +937,9 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
 	/* FIXME: should, instead, use I2C probe */
 
 	for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) {
-		struct v4l2_subdev *subdev;
-		struct i2c_board_info *board_info =
-			    &subdevs->v4l2_subdev.board_info;
-		struct i2c_adapter *adapter =
-		    i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id);
-
-		dev_info(isp->dev, "Probing Subdev %s\n", board_info->type);
-
-		if (!adapter) {
-			dev_err(isp->dev,
-				"Failed to find i2c adapter for subdev %s\n",
-				board_info->type);
-			break;
-		}
-
-		/* In G-Min, the sensor devices will already be probed
-		 * (via ACPI) and registered, do not create new
-		 * ones */
-		subdev = atomisp_gmin_find_subdev(adapter, board_info);
-		if (!subdev) {
-			dev_warn(isp->dev, "Subdev %s not found\n",
-				 board_info->type);
-			continue;
-		}
-		ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdev);
-		if (ret) {
-			dev_warn(isp->dev, "Subdev %s detection fail\n",
-				 board_info->type);
+		ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdevs->subdev);
+		if (ret)
 			continue;
-		}
-
-		if (!subdev) {
-			dev_warn(isp->dev, "Subdev %s detection fail\n",
-				 board_info->type);
-			continue;
-		}
-
-		dev_info(isp->dev, "Subdev %s successfully register\n",
-			 board_info->type);
 
 		switch (subdevs->type) {
 		case RAW_CAMERA:
@@ -992,7 +956,7 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
 
 			isp->inputs[isp->input_cnt].type = subdevs->type;
 			isp->inputs[isp->input_cnt].port = subdevs->port;
-			isp->inputs[isp->input_cnt].camera = subdev;
+			isp->inputs[isp->input_cnt].camera = subdevs->subdev;
 			isp->inputs[isp->input_cnt].sensor_index = 0;
 			/*
 			 * initialize the subdev frame size, then next we can
@@ -1004,22 +968,18 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
 			break;
 		case CAMERA_MOTOR:
 			if (isp->motor) {
-				dev_warn(isp->dev,
-					 "too many atomisp motors, ignored %s\n",
-					 board_info->type);
+				dev_warn(isp->dev, "too many atomisp motors\n");
 				continue;
 			}
-			isp->motor = subdev;
+			isp->motor = subdevs->subdev;
 			break;
 		case LED_FLASH:
 		case XENON_FLASH:
 			if (isp->flash) {
-				dev_warn(isp->dev,
-					 "too many atomisp flash devices, ignored %s\n",
-					 board_info->type);
+				dev_warn(isp->dev, "too many atomisp flash devices\n");
 				continue;
 			}
-			isp->flash = subdev;
+			isp->flash = subdevs->subdev;
 			break;
 		default:
 			dev_dbg(isp->dev, "unknown subdev probed\n");
-- 
2.39.0


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

* [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (20 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:55   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails Hans de Goede
                   ` (35 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The DSDT of all Windows BYT / CHT devices which I have seen has proper
ACPI powermagement for the clk and regulators used by the sensors.

So there is no need for the whole custom atomisp_gmin custom code to
disable the ACPI pm and directly poke at the PMIC for this.

Add new atomisp_register_sensor_no_gmin() + atomisp_unregister_subdev()
helpers which allow registering a sensor with the atomisp code without
using any of the atomisp_gmin power-management code.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../atomisp/include/linux/atomisp_platform.h  |  4 ++
 .../media/atomisp/pci/atomisp_gmin_platform.c | 61 +++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
index 82973aa0e1eb..539b21d39d3b 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
@@ -211,6 +211,10 @@ struct camera_mipi_info {
 };
 
 const struct atomisp_platform_data *atomisp_get_platform_data(void);
+int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
+				    enum atomisp_input_format format,
+				    enum atomisp_bayer_order bayer_order);
+void atomisp_unregister_subdev(struct v4l2_subdev *subdev);
 
 /* API from old platform_camera.h, new CPUID implementation */
 #define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index 234088711f29..1e943c423893 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -1082,6 +1082,67 @@ static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag)
 	return 0;
 }
 
+int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
+				    enum atomisp_input_format format,
+				    enum atomisp_bayer_order bayer_order)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+	int i, ret, clock_num, port = 0;
+
+	if (adev) {
+		/* Get ACPI _PR0 derived clock to determine the csi_port default */
+		if (acpi_device_power_manageable(adev)) {
+			clock_num = atomisp_get_acpi_power(&client->dev);
+
+			/* Compare clock to CsiPort 1 pmc-clock used in the CHT/BYT reference designs */
+			if (IS_ISP2401)
+				port = clock_num == 4 ? 1 : 0;
+			else
+				port = clock_num == 0 ? 1 : 0;
+		}
+
+		port = gmin_get_var_int(&client->dev, false, "CsiPort", port);
+		lanes = gmin_get_var_int(&client->dev, false, "CsiLanes", lanes);
+	}
+
+	for (i = 0; i < MAX_SUBDEVS; i++)
+		if (!pdata.subdevs[i].type)
+			break;
+
+	if (i >= MAX_SUBDEVS) {
+		dev_err(&client->dev, "Error too many subdevs already registered\n");
+		return -ENOMEM;
+	}
+
+	ret = camera_sensor_csi_alloc(subdev, port, lanes, format, bayer_order);
+	if (ret)
+		return ret;
+
+	pdata.subdevs[i].type = RAW_CAMERA;
+	pdata.subdevs[i].port = port;
+	pdata.subdevs[i].subdev = subdev;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(atomisp_register_sensor_no_gmin);
+
+void atomisp_unregister_subdev(struct v4l2_subdev *subdev)
+{
+	int i;
+
+	for (i = 0; i < MAX_SUBDEVS; i++) {
+		if (pdata.subdevs[i].subdev != subdev)
+			continue;
+
+		camera_sensor_csi_free(subdev);
+		pdata.subdevs[i].subdev = NULL;
+		pdata.subdevs[i].type = 0;
+		pdata.subdevs[i].port = 0;
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(atomisp_unregister_subdev);
+
 static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev,
 	char *camera_module)
 {
-- 
2.39.0


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

* [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (21 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:56   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 24/57] media: atomisp: Drop ffmt local var from atomisp_set_fmt() Hans de Goede
                   ` (34 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The videobuf2-core expects buffers to be put back in the queued state
when the vb2 start_streaming callback fails. But the atomisp
atomisp_flush_video_pipe() would unconditionally return them to the core
in an error state.

This triggers the following warning in the videobuf2-core:

drivers/media/common/videobuf2/videobuf2-core.c:1652:
	/*
	 * If done_list is not empty, then start_streaming() didn't call
	 * vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED) but STATE_ERROR or
	 * STATE_DONE.
	 */
	WARN_ON(!list_empty(&q->done_list));

Fix this by adding a state argument to atomisp_flush_video_pipe() and use
VB2_BUF_STATE_QUEUED as state when atomisp_start_streaming() fails.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_cmd.c | 17 +++++++++--------
 drivers/staging/media/atomisp/pci/atomisp_cmd.h |  3 ++-
 .../staging/media/atomisp/pci/atomisp_ioctl.c   |  4 ++--
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 01c9845b9f28..b9e7ad57040e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -679,7 +679,8 @@ void atomisp_buffer_done(struct ia_css_frame *frame, enum vb2_buffer_state state
 	vb2_buffer_done(&frame->vb.vb2_buf, state);
 }
 
-void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_frames)
+void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, enum vb2_buffer_state state,
+			      bool warn_on_css_frames)
 {
 	struct ia_css_frame *frame, *_frame;
 	unsigned long irqflags;
@@ -689,15 +690,15 @@ void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_
 	list_for_each_entry_safe(frame, _frame, &pipe->buffers_in_css, queue) {
 		if (warn_on_css_frames)
 			dev_warn(pipe->isp->dev, "Warning: CSS frames queued on flush\n");
-		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
+		atomisp_buffer_done(frame, state);
 	}
 
 	list_for_each_entry_safe(frame, _frame, &pipe->activeq, queue)
-		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
+		atomisp_buffer_done(frame, state);
 
 	list_for_each_entry_safe(frame, _frame, &pipe->buffers_waiting_for_param, queue) {
 		pipe->frame_request_config_id[frame->vb.vb2_buf.index] = 0;
-		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
+		atomisp_buffer_done(frame, state);
 	}
 
 	spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
@@ -706,10 +707,10 @@ void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_
 /* Returns queued buffers back to video-core */
 void atomisp_flush_bufs_and_wakeup(struct atomisp_sub_device *asd)
 {
-	atomisp_flush_video_pipe(&asd->video_out_capture, false);
-	atomisp_flush_video_pipe(&asd->video_out_vf, false);
-	atomisp_flush_video_pipe(&asd->video_out_preview, false);
-	atomisp_flush_video_pipe(&asd->video_out_video_capture, false);
+	atomisp_flush_video_pipe(&asd->video_out_capture, VB2_BUF_STATE_ERROR, false);
+	atomisp_flush_video_pipe(&asd->video_out_vf, VB2_BUF_STATE_ERROR, false);
+	atomisp_flush_video_pipe(&asd->video_out_preview, VB2_BUF_STATE_ERROR, false);
+	atomisp_flush_video_pipe(&asd->video_out_video_capture, VB2_BUF_STATE_ERROR, false);
 }
 
 /* clean out the parameters that did not apply */
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index a10577df10cb..733b9f8cd06f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -57,7 +57,8 @@ struct atomisp_video_pipe *atomisp_to_video_pipe(struct video_device *dev);
 int atomisp_reset(struct atomisp_device *isp);
 int atomisp_buffers_in_css(struct atomisp_video_pipe *pipe);
 void atomisp_buffer_done(struct ia_css_frame *frame, enum vb2_buffer_state state);
-void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_frames);
+void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, enum vb2_buffer_state state,
+			      bool warn_on_css_frames);
 void atomisp_flush_bufs_and_wakeup(struct atomisp_sub_device *asd);
 void atomisp_clear_css_buffer_counters(struct atomisp_sub_device *asd);
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 77856cbc5ba7..c15bb0b7458b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -1339,7 +1339,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
 
 	ret = atomisp_css_start(asd, css_pipe_id, false);
 	if (ret) {
-		atomisp_flush_video_pipe(pipe, true);
+		atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);
 		goto out_unlock;
 	}
 
@@ -1515,7 +1515,7 @@ void atomisp_stop_streaming(struct vb2_queue *vq)
 	css_pipe_id = atomisp_get_css_pipe_id(asd);
 	atomisp_css_stop(asd, css_pipe_id, false);
 
-	atomisp_flush_video_pipe(pipe, true);
+	atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true);
 
 	atomisp_subdev_cleanup_pending_events(asd);
 stopsensor:
-- 
2.39.0


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

* [PATCH 24/57] media: atomisp: Drop ffmt local var from atomisp_set_fmt()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (22 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT Hans de Goede
                   ` (33 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

ffmt is a local variable pointing to a substruct of another local
variable which really just makes the code harder to read / follow,
so drop it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_cmd.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index b9e7ad57040e..eb05288d8fb1 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -4992,7 +4992,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 	struct v4l2_subdev_format vformat = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
-	struct v4l2_mbus_framefmt *ffmt = &vformat.format;
 	struct v4l2_rect isp_sink_crop;
 	u16 source_pad = atomisp_subdev_source_pad(vdev);
 	struct v4l2_subdev_fh fh;
@@ -5031,17 +5030,17 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 	/* Ensure that the resolution is equal or below the maximum supported */
 
 	vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	v4l2_fill_mbus_format(ffmt, &f->fmt.pix, format_bridge->mbus_code);
-	ffmt->height += padding_h;
-	ffmt->width += padding_w;
+	v4l2_fill_mbus_format(&vformat.format, &f->fmt.pix, format_bridge->mbus_code);
+	vformat.format.height += padding_h;
+	vformat.format.width += padding_w;
 
 	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
 			       set_fmt, NULL, &vformat);
 	if (ret)
 		return ret;
 
-	f->fmt.pix.width = ffmt->width - padding_w;
-	f->fmt.pix.height = ffmt->height - padding_h;
+	f->fmt.pix.width = vformat.format.width - padding_w;
+	f->fmt.pix.height = vformat.format.height - padding_h;
 
 	snr_fmt = f->fmt.pix;
 	backup_fmt = snr_fmt;
-- 
2.39.0


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

* [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (23 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 24/57] media: atomisp: Drop ffmt local var from atomisp_set_fmt() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 17:59   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 26/57] media: atomisp: Put sensor ACPI devices in D3 before disable ACPI power-resources Hans de Goede
                   ` (32 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

atomisp_set_fmt() first does:

	v4l2_fill_mbus_format(&vformat.format, ...);
        vformat.format.height += padding_h;
        vformat.format.width += padding_w;

        ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
                               set_fmt, NULL, &vformat);
        if (ret)
                return ret;

	f->fmt.pix.width = vformat.format.width - padding_w;
	f->fmt.pix.height = vformat.format.height - padding_h;

this happens with the original padding w/h = 16 values and then later
on it calls:

                ret = atomisp_set_fmt_to_snr(vdev, &s_fmt,
                                             f->fmt.pix.pixelformat, padding_w,
                                             padding_h, dvs_env_w, dvs_env_h);

Which repeats the above structure. If at that point padding w/h are
changed to 12 then it will now request a different output-size of
the sensor driver.

The sensor drivers so far have actually been ignoring this since they use
v4l2_find_nearest_size() on a fixed resolution list and the nearest
resolution will be the one from the earlier calls where padding w/h
was 16.

But there really is no reason for sensor drivers to use a fixed
resolution list. They make lower resolutions using cropping so they
can make any resolution as long as width/height are even numbers.

Dropping the fixed-resolution list limit from sensors on BYT results
in trying to start streaming failing because the resolution set to
the sensor now no longer matches with the resolution used during
the initial part of the configuration done by atomisp_set_fmt().

Drop the BYT specific overriding of the padding_w/h to 12, so that
the padding in the first and second s_fmt calls made to the sensor
matches, to fix stream start failing when the fixed resolution list
is dropped.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_cmd.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index eb05288d8fb1..47f18ac5e40e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -5163,9 +5163,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 	if (!atomisp_subdev_format_conversion(asd, source_pad)) {
 		padding_w = 0;
 		padding_h = 0;
-	} else if (IS_BYT) {
-		padding_w = 12;
-		padding_h = 12;
 	}
 
 	/* construct resolution supported by isp */
-- 
2.39.0


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

* [PATCH 26/57] media: atomisp: Put sensor ACPI devices in D3 before disable ACPI power-resources
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (24 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 12:51 ` [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup() Hans de Goede
                   ` (31 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The device core will call ACPI to turn the device (i2c_client) for a sensor
on / put it in D0 before calling its probe() method.

This takes a reference on all of the ACPI power-resources belonging to
the device. Since the atomisp_gmin_platform code disables ACPI
power-resource management and does its own pm, this reference never gets
released.

This is a problem for ACPI power-resources which are shared with other
devices since those now never get turned off again (nor back on again).

Explicitly put the device in D3 before disabling the ACPI power-resource
management.

Note that atomisp_register_i2c_module() runs near the end of the sensor
driver's probe() function, after the driver is done with probing the hw.
So the power-resouces (the same resources as directly controlled by
the atomisp platform code) getting turned off (a second time, as they are
already off) is not a problem.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
index 1e943c423893..2b9d68141520 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
@@ -159,6 +159,14 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 	 * tickled during suspend/resume.  This has caused power and
 	 * performance issues on multiple devices.
 	 */
+
+	/*
+	 * Turn off the device before disabling ACPI power resources
+	 * (the sensor driver has already probed it at this point).
+	 * This avoids leaking the reference count of the (possibly shared)
+	 * ACPI power resources which were enabled/referenced before probe().
+	 */
+	acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
 	adev->power.flags.power_resources = 0;
 
 	for (i = 0; i < MAX_SUBDEVS; i++)
-- 
2.39.0


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

* [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (25 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 26/57] media: atomisp: Put sensor ACPI devices in D3 before disable ACPI power-resources Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:02   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
                   ` (30 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Looking at isp_subdev_link_setup(), this function can never work,
it does a switch-case like this:

 switch (local->index | is_media_entity_v4l2_subdev(remote->entity))

with cases like this:

 case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN

where ATOMISP_SUBDEV_PAD_SINK matches an index (0-4) and
MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN is 0x00020000, but
is_media_entity_v4l2_subdev(remote->entity) does not return
MEDIA_ENT_F_* values, it return a bool, so 0 or 1 which means
that non of the cases can ever match the input value.

Looking at the rest of the function all it ever does (if it
would actually hit one of the cases) is set the atomisp_sub_device
struct's input member.

And checking the rest of the atomisp code that member is never
read. Also userspace does not actually setup media-controller
links when using the atomisp /dev/video$ nodes since all the links
are fixed. So isp_subdev_link_setup() never runs.

Remove the unnecessary and broken isp_subdev_link_setup() function
and also remove the unused atomisp_sub_device struct's input member.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/pci/atomisp_subdev.c        | 79 -------------------
 .../media/atomisp/pci/atomisp_subdev.h        | 13 ---
 2 files changed, 92 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
index eb8f319fca5c..52d1936b8c87 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
@@ -714,85 +714,8 @@ static void isp_subdev_init_params(struct atomisp_sub_device *asd)
 	}
 }
 
-/*
-* isp_subdev_link_setup - Setup isp subdev connections
-* @entity: ispsubdev media entity
-* @local: Pad at the local end of the link
-* @remote: Pad at the remote end of the link
-* @flags: Link flags
-*
-* return -EINVAL or zero on success
-*/
-static int isp_subdev_link_setup(struct media_entity *entity,
-				 const struct media_pad *local,
-				 const struct media_pad *remote, u32 flags)
-{
-	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
-	struct atomisp_device *isp = isp_sd->isp;
-	unsigned int i;
-
-	switch (local->index | is_media_entity_v4l2_subdev(remote->entity)) {
-	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN:
-		/* Read from the sensor CSI2-ports. */
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
-			break;
-		}
-
-		if (isp_sd->input != ATOMISP_SUBDEV_INPUT_NONE)
-			return -EBUSY;
-
-		for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
-			if (remote->entity != &isp->csi2_port[i].subdev.entity)
-				continue;
-
-			isp_sd->input = ATOMISP_SUBDEV_INPUT_CSI2_PORT1 + i;
-			return 0;
-		}
-
-		return -EINVAL;
-
-	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_OLD_BASE:
-		/* read from memory */
-		if (flags & MEDIA_LNK_FL_ENABLED) {
-			if (isp_sd->input >= ATOMISP_SUBDEV_INPUT_CSI2_PORT1 &&
-			    isp_sd->input < (ATOMISP_SUBDEV_INPUT_CSI2_PORT1
-					     + ATOMISP_CAMERA_NR_PORTS))
-				return -EBUSY;
-			isp_sd->input = ATOMISP_SUBDEV_INPUT_MEMORY;
-		} else {
-			if (isp_sd->input == ATOMISP_SUBDEV_INPUT_MEMORY)
-				isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
-		}
-		break;
-
-	case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW | MEDIA_ENT_F_OLD_BASE:
-		/* always write to memory */
-		break;
-
-	case ATOMISP_SUBDEV_PAD_SOURCE_VF | MEDIA_ENT_F_OLD_BASE:
-		/* always write to memory */
-		break;
-
-	case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE | MEDIA_ENT_F_OLD_BASE:
-		/* always write to memory */
-		break;
-
-	case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO | MEDIA_ENT_F_OLD_BASE:
-		/* always write to memory */
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 /* media operations */
 static const struct media_entity_operations isp_subdev_media_ops = {
-	.link_setup = isp_subdev_link_setup,
 	.link_validate = v4l2_subdev_link_validate,
 	/*	 .set_power = v4l2_subdev_set_power,	*/
 };
@@ -1071,8 +994,6 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
 	struct media_entity *me = &sd->entity;
 	int ret;
 
-	asd->input = ATOMISP_SUBDEV_INPUT_NONE;
-
 	v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
 	sprintf(sd->name, "ATOMISP_SUBDEV_%d", asd->index);
 	v4l2_set_subdevdata(sd, asd);
diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
index bd2872cbb50c..daa6077a83bd 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
@@ -30,18 +30,6 @@
 
 /* EXP_ID's ranger is 1 ~ 250 */
 #define ATOMISP_MAX_EXP_ID     (250)
-enum atomisp_subdev_input_entity {
-	ATOMISP_SUBDEV_INPUT_NONE,
-	ATOMISP_SUBDEV_INPUT_MEMORY,
-	ATOMISP_SUBDEV_INPUT_CSI2,
-	/*
-	 * The following enum for CSI2 port must go together in one row.
-	 * Otherwise it breaks the code logic.
-	 */
-	ATOMISP_SUBDEV_INPUT_CSI2_PORT1,
-	ATOMISP_SUBDEV_INPUT_CSI2_PORT2,
-	ATOMISP_SUBDEV_INPUT_CSI2_PORT3,
-};
 
 #define ATOMISP_SUBDEV_PAD_SINK			0
 /* capture output for still frames */
@@ -267,7 +255,6 @@ struct atomisp_sub_device {
 	struct atomisp_pad_format fmt[ATOMISP_SUBDEV_PADS_NUM];
 	u16 capture_pad; /* main capture pad; defines much of isp config */
 
-	enum atomisp_subdev_input_entity input;
 	unsigned int output;
 	struct atomisp_video_pipe video_out_capture; /* capture output */
 	struct atomisp_video_pipe video_out_vf;      /* viewfinder output */
-- 
2.39.0


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

* [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (26 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:09   ` Andy Shevchenko
                     ` (4 more replies)
  2023-01-23 12:51 ` [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
                   ` (29 subsequent siblings)
  57 siblings, 5 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,

as well as various "atomisp" sensor drivers in drivers/staging, *all*
use register access helpers with the following function prototypes:

int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
                    unsigned int len, u32 *val);

int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
                     unsigned int len, u32 val);

To read/write registers on Omnivision OVxxxx image sensors wich expect
a 16 bit register address in big-endian format and which have 1-3 byte
wide registers, in big-endian format (for the higher width registers).

Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
versions of these register access helpers, so that this code duplication
can be removed.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h

diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
new file mode 100644
index 000000000000..e2ffee3d797a
--- /dev/null
+++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * I2C register access helpers for Omnivision OVxxxx image sensors which expect
+ * a 16 bit register address in big-endian format and which have 1-3 byte
+ * wide registers, in big-endian format (for the higher width registers).
+ *
+ * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
+ * Copyright (C) 2018 Linaro Ltd
+ */
+#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
+#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
+
+#include <asm/unaligned.h>
+#include <linux/dev_printk.h>
+#include <linux/i2c.h>
+
+static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
+				  unsigned int len, u32 *val)
+{
+	struct i2c_msg msgs[2];
+	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
+	u8 data_buf[4] = { 0, };
+	int ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = ARRAY_SIZE(addr_buf);
+	msgs[0].buf = addr_buf;
+
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_buf[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs)) {
+		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
+		return -EIO;
+	}
+
+	*val = get_unaligned_be32(data_buf);
+
+	return 0;
+}
+
+#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
+#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
+#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
+
+static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
+				   unsigned int len, u32 val)
+{
+	u8 buf[6];
+	int ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	put_unaligned_be16(reg, buf);
+	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
+	ret = i2c_master_send(client, buf, len + 2);
+	if (ret != len + 2) {
+		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
+#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
+#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
+
+static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
+{
+	u32 readval;
+	int ret;
+
+	ret = ovxxxx_read_reg8(client, reg, &readval);
+	if (ret < 0)
+		return ret;
+
+	readval &= ~mask;
+	val &= mask;
+	val |= readval;
+
+	return ovxxxx_write_reg8(client, reg, val);
+}
+
+#endif
-- 
2.39.0


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

* [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (27 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:13   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls Hans de Goede
                   ` (28 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Use the new ovxxxx_16bit_addr_reg_helpers.h instead of duplicating
the ovxxxx sensor I2C register access helpers found in many different
sensor drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 122 ++++--------------
 drivers/staging/media/atomisp/i2c/ov2680.h    |   4 -
 2 files changed, 25 insertions(+), 101 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 88fdeb828c6c..85b9410f655e 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -30,6 +30,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/moduleparam.h>
+#include <media/ovxxxx_16bit_addr_reg_helpers.h>
 #include <media/v4l2-device.h>
 #include <linux/io.h>
 #include <linux/acpi.h>
@@ -46,64 +47,6 @@ static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = {
 	atomisp_bayer_order_rggb,
 };
 
-/* i2c read/write stuff */
-static int ov2680_read_reg(struct i2c_client *client,
-			   int len, u16 reg, u32 *val)
-{
-	struct i2c_msg msgs[2];
-	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
-	u8 data_buf[4] = { 0, };
-	int ret;
-
-	if (len > 4)
-		return -EINVAL;
-
-	msgs[0].addr = client->addr;
-	msgs[0].flags = 0;
-	msgs[0].len = ARRAY_SIZE(addr_buf);
-	msgs[0].buf = addr_buf;
-
-	msgs[1].addr = client->addr;
-	msgs[1].flags = I2C_M_RD;
-	msgs[1].len = len;
-	msgs[1].buf = &data_buf[4 - len];
-
-	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-	if (ret != ARRAY_SIZE(msgs)) {
-		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
-		return -EIO;
-	}
-
-	*val = get_unaligned_be32(data_buf);
-
-	return 0;
-}
-
-static int ov2680_write_reg(struct i2c_client *client, unsigned int len,
-			    u16 reg, u16 val)
-{
-	u8 buf[6];
-	int ret;
-
-	if (len == 2)
-		put_unaligned_be16(val, buf + 2);
-	else if (len == 1)
-		buf[2] = val;
-	else
-		return -EINVAL;
-
-	put_unaligned_be16(reg, buf);
-
-	ret = i2c_master_send(client, buf, len + 2);
-	if (ret != len + 2) {
-		dev_err(&client->dev, "write error %d reg 0x%04x, val 0x%02x: buf sent: %*ph\n",
-			ret, reg, val, len + 2, &buf);
-		return -EIO;
-	}
-
-	return 0;
-}
-
 static int ov2680_write_reg_array(struct i2c_client *client,
 				  const struct ov2680_reg *reglist)
 {
@@ -111,7 +54,7 @@ static int ov2680_write_reg_array(struct i2c_client *client,
 	int ret;
 
 	for (; next->reg != 0; next++) {
-		ret = ov2680_write_reg(client, 1, next->reg, next->val);
+		ret = ovxxxx_write_reg8(client, next->reg, next->val);
 		if (ret)
 			return ret;
 	}
@@ -135,8 +78,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 	vts = dev->res->lines_per_frame;
 
 	/* group hold */
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_GROUP_ACCESS, 0x00);
+	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x00);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_GROUP_ACCESS);
@@ -147,7 +89,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 	if (coarse_itg > vts - OV2680_INTEGRATION_TIME_MARGIN)
 		vts = (u16)coarse_itg + OV2680_INTEGRATION_TIME_MARGIN;
 
-	ret = ov2680_write_reg(client, 2, OV2680_TIMING_VTS_H, vts);
+	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_TIMING_VTS_H);
@@ -158,24 +100,21 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 
 	/* Lower four bit should be 0*/
 	exp_val = coarse_itg << 4;
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_EXPOSURE_L, exp_val & 0xFF);
+	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_L, exp_val & 0xFF);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_EXPOSURE_L);
 		return ret;
 	}
 
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_EXPOSURE_M, (exp_val >> 8) & 0xFF);
+	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_M, (exp_val >> 8) & 0xFF);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_EXPOSURE_M);
 		return ret;
 	}
 
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_EXPOSURE_H, (exp_val >> 16) & 0x0F);
+	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_H, (exp_val >> 16) & 0x0F);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_EXPOSURE_H);
@@ -183,7 +122,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 	}
 
 	/* Analog gain */
-	ret = ov2680_write_reg(client, 2, OV2680_AGC_H, gain);
+	ret = ovxxxx_write_reg16(client, OV2680_AGC_H, gain);
 	if (ret) {
 		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
 			__func__, OV2680_AGC_H);
@@ -191,8 +130,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 	}
 	/* Digital gain */
 	if (digitgain) {
-		ret = ov2680_write_reg(client, 2,
-				       OV2680_MWB_RED_GAIN_H, digitgain);
+		ret = ovxxxx_write_reg16(client, OV2680_MWB_RED_GAIN_H, digitgain);
 		if (ret) {
 			dev_err(&client->dev,
 				"%s: write 0x%02x: error, aborted\n",
@@ -200,8 +138,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 			return ret;
 		}
 
-		ret = ov2680_write_reg(client, 2,
-				       OV2680_MWB_GREEN_GAIN_H, digitgain);
+		ret = ovxxxx_write_reg16(client, OV2680_MWB_GREEN_GAIN_H, digitgain);
 		if (ret) {
 			dev_err(&client->dev,
 				"%s: write 0x%02x: error, aborted\n",
@@ -209,8 +146,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 			return ret;
 		}
 
-		ret = ov2680_write_reg(client, 2,
-				       OV2680_MWB_BLUE_GAIN_H, digitgain);
+		ret = ovxxxx_write_reg16(client, OV2680_MWB_BLUE_GAIN_H, digitgain);
 		if (ret) {
 			dev_err(&client->dev,
 				"%s: write 0x%02x: error, aborted\n",
@@ -220,14 +156,12 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 	}
 
 	/* End group */
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_GROUP_ACCESS, 0x10);
+	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x10);
 	if (ret)
 		return ret;
 
 	/* Delay launch group */
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_GROUP_ACCESS, 0xa0);
+	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0xa0);
 	if (ret)
 		return ret;
 	return ret;
@@ -294,7 +228,7 @@ static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value)
 	int ret;
 
 	/* get exposure */
-	ret = ov2680_read_reg(client, 3, OV2680_EXPOSURE_H, &reg_val);
+	ret = ovxxxx_read_reg24(client, OV2680_EXPOSURE_H, &reg_val);
 	if (ret)
 		return ret;
 
@@ -312,7 +246,7 @@ static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value)
 	u8 index;
 
 	dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
-	ret = ov2680_read_reg(client, 1, OV2680_FLIP_REG, &val);
+	ret = ovxxxx_read_reg8(client, OV2680_FLIP_REG, &val);
 	if (ret)
 		return ret;
 	if (value)
@@ -320,8 +254,7 @@ static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value)
 	else
 		val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE;
 
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_FLIP_REG, val);
+	ret = ovxxxx_write_reg8(client, OV2680_FLIP_REG, val);
 	if (ret)
 		return ret;
 	index = (v_flag > 0 ? OV2680_FLIP_BIT : 0) | (h_flag > 0 ? OV2680_MIRROR_BIT :
@@ -343,7 +276,7 @@ static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
 
 	dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
 
-	ret = ov2680_read_reg(client, 1, OV2680_MIRROR_REG, &val);
+	ret = ovxxxx_read_reg8(client, OV2680_MIRROR_REG, &val);
 	if (ret)
 		return ret;
 	if (value)
@@ -351,8 +284,7 @@ static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
 	else
 		val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE;
 
-	ret = ov2680_write_reg(client, 1,
-			       OV2680_MIRROR_REG, val);
+	ret = ovxxxx_write_reg8(client, OV2680_MIRROR_REG, val);
 	if (ret)
 		return ret;
 	index = (v_flag > 0 ? OV2680_FLIP_BIT : 0) | (h_flag > 0 ? OV2680_MIRROR_BIT :
@@ -449,7 +381,7 @@ static int ov2680_init_registers(struct v4l2_subdev *sd)
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
 
-	ret = ov2680_write_reg(client, 1, OV2680_SW_RESET, 0x01);
+	ret = ovxxxx_write_reg8(client, OV2680_SW_RESET, 0x01);
 	ret |= ov2680_write_reg_array(client, ov2680_global_setting);
 
 	return ret;
@@ -687,7 +619,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	if (dev->exposure > vts - OV2680_INTEGRATION_TIME_MARGIN)
 		vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN;
 
-	ret = ov2680_write_reg(client, 2, OV2680_TIMING_VTS_H, vts);
+	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
 	if (ret) {
 		dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
 		goto err;
@@ -739,14 +671,12 @@ static int ov2680_detect(struct i2c_client *client)
 	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
 		return -ENODEV;
 
-	ret = ov2680_read_reg(client, 1,
-			      OV2680_SC_CMMN_CHIP_ID_H, &high);
+	ret = ovxxxx_read_reg8(client, OV2680_SC_CMMN_CHIP_ID_H, &high);
 	if (ret) {
 		dev_err(&client->dev, "sensor_id_high = 0x%x\n", high);
 		return -ENODEV;
 	}
-	ret = ov2680_read_reg(client, 1,
-			      OV2680_SC_CMMN_CHIP_ID_L, &low);
+	ret = ovxxxx_read_reg8(client, OV2680_SC_CMMN_CHIP_ID_L, &low);
 	id = ((((u16)high) << 8) | (u16)low);
 
 	if (id != OV2680_ID) {
@@ -754,8 +684,7 @@ static int ov2680_detect(struct i2c_client *client)
 		return -ENODEV;
 	}
 
-	ret = ov2680_read_reg(client, 1,
-			      OV2680_SC_CMMN_SUB_ID, &high);
+	ret = ovxxxx_read_reg8(client, OV2680_SC_CMMN_SUB_ID, &high);
 	revision = (u8)high & 0x0f;
 
 	dev_info(&client->dev, "sensor_revision id = 0x%x, rev= %d\n",
@@ -776,9 +705,8 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 	else
 		dev_dbg(&client->dev, "ov2680_s_stream off\n");
 
-	ret = ov2680_write_reg(client, 1, OV2680_SW_STREAM,
-			       enable ? OV2680_START_STREAMING :
-			       OV2680_STOP_STREAMING);
+	ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM,
+				enable ? OV2680_START_STREAMING : OV2680_STOP_STREAMING);
 
 	//otp valid at stream on state
 	//if(!dev->otp_data)
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 596e14453fb3..f4760a70055d 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -32,10 +32,6 @@
 
 #include "../include/linux/atomisp_platform.h"
 
-/* Defines for register writes and register array processing */
-#define I2C_MSG_LENGTH		0x2
-#define I2C_RETRY_COUNT		5
-
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
 
 #define OV2680_BIN_FACTOR_MAX 4
-- 
2.39.0


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

* [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (28 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:33   ` Andy Shevchenko
  2023-01-29  0:36   ` kernel test robot
  2023-01-23 12:51 ` [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support Hans de Goede
                   ` (27 subsequent siblings)
  57 siblings, 2 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Rework the flip ctrls to be more like those of mainline (non staging)
drivers.

This is modelled after the main ov2680 and ov5693 drivers. This also
introduces __ov2680_get_pad_format() to make the ov2680 code more compliant
with the mainline v4l2-subdev APIs.

Note the OV2680_FLIP_REG and OV2680_MIRROR_REG defines are renamed to
OV2680_REG_FORMAT1 and OV2680_REG_FORMAT2 to match the datasheet.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 285 ++++++++----------
 drivers/staging/media/atomisp/i2c/ov2680.h    |  29 +-
 2 files changed, 155 insertions(+), 159 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 85b9410f655e..df92b35ce062 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -38,8 +38,6 @@
 
 #include "ov2680.h"
 
-static int h_flag;
-static int v_flag;
 static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = {
 	atomisp_bayer_order_bggr,
 	atomisp_bayer_order_grbg,
@@ -237,82 +235,80 @@ static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value)
 	return 0;
 }
 
-static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value)
+static void ov2680_set_bayer_order(struct ov2680_device *sensor, struct v4l2_mbus_framefmt *fmt)
+{
+	static const int ov2680_hv_flip_bayer_order[] = {
+		MEDIA_BUS_FMT_SBGGR10_1X10,
+		MEDIA_BUS_FMT_SGRBG10_1X10,
+		MEDIA_BUS_FMT_SGBRG10_1X10,
+		MEDIA_BUS_FMT_SRGGB10_1X10,
+	};
+	struct camera_mipi_info *ov2680_info;
+	int hv_flip = 0;
+
+	if (sensor->ctrls.vflip->val)
+		hv_flip += 1;
+
+	if (sensor->ctrls.hflip->val)
+		hv_flip += 2;
+
+	fmt->code = ov2680_hv_flip_bayer_order[hv_flip];
+
+	/* TODO atomisp specific custom API, should be removed */
+	ov2680_info = v4l2_get_subdev_hostdata(&sensor->sd);
+	if (ov2680_info)
+		ov2680_info->raw_bayer_order = ov2680_bayer_order_mapping[hv_flip];
+}
+
+static int ov2680_set_vflip(struct ov2680_device *sensor, s32 val)
 {
-	struct camera_mipi_info *ov2680_info = NULL;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
-	u32 val;
-	u8 index;
 
-	dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
-	ret = ovxxxx_read_reg8(client, OV2680_FLIP_REG, &val);
-	if (ret)
-		return ret;
-	if (value)
-		val |= OV2680_FLIP_MIRROR_BIT_ENABLE;
-	else
-		val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE;
+	if (sensor->is_streaming)
+		return -EBUSY;
 
-	ret = ovxxxx_write_reg8(client, OV2680_FLIP_REG, val);
-	if (ret)
+	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_FORMAT1, BIT(2),
+			     val ? BIT(2) : 0);
+	if (ret < 0)
 		return ret;
-	index = (v_flag > 0 ? OV2680_FLIP_BIT : 0) | (h_flag > 0 ? OV2680_MIRROR_BIT :
-		0);
-	ov2680_info = v4l2_get_subdev_hostdata(sd);
-	if (ov2680_info) {
-		ov2680_info->raw_bayer_order = ov2680_bayer_order_mapping[index];
-	}
-	return ret;
+
+	ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
+	return 0;
 }
 
-static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value)
+static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val)
 {
-	struct camera_mipi_info *ov2680_info = NULL;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
-	u32 val;
-	u8 index;
 
-	dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value);
+	if (sensor->is_streaming)
+		return -EBUSY;
 
-	ret = ovxxxx_read_reg8(client, OV2680_MIRROR_REG, &val);
-	if (ret)
+	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_FORMAT2, BIT(2),
+			     val ? BIT(2) : 0);
+	if (ret < 0)
 		return ret;
-	if (value)
-		val |= OV2680_FLIP_MIRROR_BIT_ENABLE;
-	else
-		val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE;
 
-	ret = ovxxxx_write_reg8(client, OV2680_MIRROR_REG, val);
-	if (ret)
-		return ret;
-	index = (v_flag > 0 ? OV2680_FLIP_BIT : 0) | (h_flag > 0 ? OV2680_MIRROR_BIT :
-		0);
-	ov2680_info = v4l2_get_subdev_hostdata(sd);
-	if (ov2680_info) {
-		ov2680_info->raw_bayer_order = ov2680_bayer_order_mapping[index];
-	}
-	return ret;
+	ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
+	return 0;
 }
 
 static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct ov2680_device *dev =
-	    container_of(ctrl->handler, struct ov2680_device, ctrl_handler);
-	struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
-	int ret = 0;
+	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
+	int ret;
+
+	if (!sensor->power_on) {
+		ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
+		return 0;
+	}
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
-		dev_dbg(&client->dev, "%s: CID_VFLIP:%d.\n",
-			__func__, ctrl->val);
-		ret = ov2680_v_flip(&dev->sd, ctrl->val);
+		ret = ov2680_set_vflip(sensor, ctrl->val);
 		break;
 	case V4L2_CID_HFLIP:
-		dev_dbg(&client->dev, "%s: CID_HFLIP:%d.\n",
-			__func__, ctrl->val);
-		ret = ov2680_h_flip(&dev->sd, ctrl->val);
+		ret = ov2680_set_hflip(sensor, ctrl->val);
 		break;
 	default:
 		ret = -EINVAL;
@@ -322,13 +318,12 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 
 static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct ov2680_device *dev =
-	    container_of(ctrl->handler, struct ov2680_device, ctrl_handler);
+	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
 	int ret = 0;
 
 	switch (ctrl->id) {
 	case V4L2_CID_EXPOSURE_ABSOLUTE:
-		ret = ov2680_q_exposure(&dev->sd, &ctrl->val);
+		ret = ov2680_q_exposure(sd, &ctrl->val);
 		break;
 	default:
 		ret = -EINVAL;
@@ -337,45 +332,11 @@ static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 	return ret;
 }
 
-static const struct v4l2_ctrl_ops ctrl_ops = {
+static const struct v4l2_ctrl_ops ov2680_ctrl_ops = {
 	.s_ctrl = ov2680_s_ctrl,
 	.g_volatile_ctrl = ov2680_g_volatile_ctrl
 };
 
-static const struct v4l2_ctrl_config ov2680_controls[] = {
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_EXPOSURE_ABSOLUTE,
-		.type = V4L2_CTRL_TYPE_INTEGER,
-		.name = "exposure",
-		.min = 0x0,
-		.max = 0xffff,
-		.step = 0x01,
-		.def = 0x00,
-		.flags = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_VFLIP,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.name = "Flip",
-		.min = 0,
-		.max = 1,
-		.step = 1,
-		.def = 0,
-	},
-	{
-		.ops = &ctrl_ops,
-		.id = V4L2_CID_HFLIP,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.name = "Mirror",
-		.min = 0,
-		.max = 1,
-		.step = 1,
-		.def = 0,
-	},
-};
-
 static int ov2680_init_registers(struct v4l2_subdev *sd)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -506,8 +467,6 @@ static int power_down(struct v4l2_subdev *sd)
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret = 0;
 
-	h_flag = 0;
-	v_flag = 0;
 	if (!dev->platform_data) {
 		dev_err(&client->dev,
 			"no camera_sensor_platform_data");
@@ -558,14 +517,35 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on)
 	return ret;
 }
 
+static struct v4l2_mbus_framefmt *
+__ov2680_get_pad_format(struct ov2680_device *sensor,
+			struct v4l2_subdev_state *state,
+			unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return v4l2_subdev_get_try_format(&sensor->sd, state, pad);
+
+	return &sensor->mode.fmt;
+}
+
+static void ov2680_fill_format(struct ov2680_device *sensor,
+			       struct v4l2_mbus_framefmt *fmt,
+			       unsigned int width, unsigned int height)
+{
+	memset(fmt, 0, sizeof(*fmt));
+	fmt->width = width;
+	fmt->height = height;
+	fmt->field = V4L2_FIELD_NONE;
+	ov2680_set_bayer_order(sensor, fmt);
+}
+
 static int ov2680_set_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
 {
-	struct v4l2_mbus_framefmt *fmt = &format->format;
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct camera_mipi_info *ov2680_info = NULL;
+	struct v4l2_mbus_framefmt *fmt;
 	struct ov2680_resolution *res;
 	int vts, ret = 0;
 
@@ -574,30 +554,19 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		(format->which == V4L2_SUBDEV_FORMAT_TRY) ? "try" : "set",
 		format->pad, fmt);
 
-	if (format->pad)
-		return -EINVAL;
-
-	if (!fmt)
-		return -EINVAL;
-
-	ov2680_info = v4l2_get_subdev_hostdata(sd);
-	if (!ov2680_info)
-		return -EINVAL;
-
-	res = v4l2_find_nearest_size(ov2680_res_preview,
-				     ARRAY_SIZE(ov2680_res_preview), width,
-				     height, fmt->width, fmt->height);
+	res = v4l2_find_nearest_size(ov2680_res_preview, ARRAY_SIZE(ov2680_res_preview),
+				     width, height,
+				     format->format.width, format->format.height);
 	if (!res)
 		res = &ov2680_res_preview[N_RES_PREVIEW - 1];
 
-	fmt->width = res->width;
-	fmt->height = res->height;
+	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
+	ov2680_fill_format(dev, fmt, res->width, res->height);
+
+	format->format = *fmt;
 
-	fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
-		sd_state->pads->try_fmt = *fmt;
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
 		return 0;
-	}
 
 	dev_dbg(&client->dev, "%s: %dx%d\n",
 		__func__, fmt->width, fmt->height);
@@ -629,10 +598,9 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	 * recall flip functions to avoid flip registers
 	 * were overridden by default setting
 	 */
-	if (h_flag)
-		ov2680_h_flip(sd, h_flag);
-	if (v_flag)
-		ov2680_v_flip(sd, v_flag);
+	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
+	if (ret < 0)
+		goto err;
 
 	dev->res = res;
 err:
@@ -644,19 +612,11 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
 {
-	struct v4l2_mbus_framefmt *fmt = &format->format;
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct v4l2_mbus_framefmt *fmt;
 
-	if (format->pad)
-		return -EINVAL;
-
-	if (!fmt)
-		return -EINVAL;
-
-	fmt->width = dev->res->width;
-	fmt->height = dev->res->height;
-	fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
-
+	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
+	format->format = *fmt;
 	return 0;
 }
 
@@ -707,6 +667,11 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 
 	ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM,
 				enable ? OV2680_START_STREAMING : OV2680_STOP_STREAMING);
+	if (ret == 0) {
+		dev->is_streaming = enable;
+		v4l2_ctrl_activate(dev->ctrls.vflip, !enable);
+		v4l2_ctrl_activate(dev->ctrls.hflip, !enable);
+	}
 
 	//otp valid at stream on state
 	//if(!dev->otp_data)
@@ -867,6 +832,29 @@ static const struct v4l2_subdev_ops ov2680_ops = {
 	.sensor = &ov2680_sensor_ops,
 };
 
+static int ov2680_init_controls(struct ov2680_device *sensor)
+{
+	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
+	struct ov2680_ctrls *ctrls = &sensor->ctrls;
+	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+
+	v4l2_ctrl_handler_init(hdl, 2);
+
+	hdl->lock = &sensor->input_lock;
+
+	ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+	ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+	if (hdl->error)
+		return hdl->error;
+
+	sensor->sd.ctrl_handler = hdl;
+	return 0;
+}
+
 static void ov2680_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -878,7 +866,7 @@ static void ov2680_remove(struct i2c_client *client)
 
 	v4l2_device_unregister_subdev(sd);
 	media_entity_cleanup(&dev->sd.entity);
-	v4l2_ctrl_handler_free(&dev->ctrl_handler);
+	v4l2_ctrl_handler_free(&dev->ctrls.handler);
 	kfree(dev);
 }
 
@@ -887,7 +875,6 @@ static int ov2680_probe(struct i2c_client *client)
 	struct ov2680_device *dev;
 	int ret;
 	void *pdata;
-	unsigned int i;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -895,6 +882,7 @@ static int ov2680_probe(struct i2c_client *client)
 
 	mutex_init(&dev->input_lock);
 
+	dev->client = client;
 	dev->res = &ov2680_res_preview[0];
 	dev->exposure = dev->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
 	dev->gain = 250; /* 0-2047 */
@@ -912,40 +900,31 @@ static int ov2680_probe(struct i2c_client *client)
 	if (ret)
 		goto out_free;
 
-	ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
-	if (ret)
-		goto out_free;
-
 	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
 	dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
-	ret =
-	    v4l2_ctrl_handler_init(&dev->ctrl_handler,
-				   ARRAY_SIZE(ov2680_controls));
+
+	ret = ov2680_init_controls(dev);
 	if (ret) {
 		ov2680_remove(client);
 		return ret;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(ov2680_controls); i++)
-		v4l2_ctrl_new_custom(&dev->ctrl_handler, &ov2680_controls[i],
-				     NULL);
-
-	if (dev->ctrl_handler.error) {
+	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
+	if (ret) {
 		ov2680_remove(client);
-		return dev->ctrl_handler.error;
+		return ret;
 	}
 
-	/* Use same lock for controls as for everything else. */
-	dev->ctrl_handler.lock = &dev->input_lock;
-	dev->sd.ctrl_handler = &dev->ctrl_handler;
+	ov2680_fill_format(dev, &dev->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
 
-	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
+	ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
 	if (ret) {
 		ov2680_remove(client);
-		dev_dbg(&client->dev, "+++ remove ov2680\n");
+		return ret;
 	}
-	return ret;
+
+	return 0;
 out_free:
 	dev_dbg(&client->dev, "+++ out free\n");
 	v4l2_device_unregister_subdev(&dev->sd);
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index f4760a70055d..43bbc9368422 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -32,6 +32,9 @@
 
 #include "../include/linux/atomisp_platform.h"
 
+#define OV2680_NATIVE_WIDTH			1616
+#define OV2680_NATIVE_HEIGHT			1216
+
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
 
 #define OV2680_BIN_FACTOR_MAX 4
@@ -112,11 +115,8 @@
 #define OV2680_FRAME_OFF_NUM						0x4202
 
 /*Flip/Mirror*/
-#define OV2680_FLIP_REG				0x3820
-#define OV2680_MIRROR_REG			0x3821
-#define OV2680_FLIP_BIT				1
-#define OV2680_MIRROR_BIT			2
-#define OV2680_FLIP_MIRROR_BIT_ENABLE		4
+#define OV2680_REG_FORMAT1			0x3820
+#define OV2680_REG_FORMAT2			0x3821
 
 #define OV2680_MWB_RED_GAIN_H			0x5004/*0x3400*/
 #define OV2680_MWB_GREEN_GAIN_H			0x5006/*0x3402*/
@@ -158,13 +158,24 @@ struct ov2680_device {
 	struct v4l2_subdev sd;
 	struct media_pad pad;
 	struct mutex input_lock;
-	struct v4l2_ctrl_handler ctrl_handler;
+	struct i2c_client *client;
 	struct ov2680_resolution *res;
 	struct camera_sensor_platform_data *platform_data;
 	bool power_on;
+	bool is_streaming;
 	u16 exposure;
 	u16 gain;
 	u16 digitgain;
+
+	struct ov2680_mode {
+		struct v4l2_mbus_framefmt fmt;
+	} mode;
+
+	struct ov2680_ctrls {
+		struct v4l2_ctrl_handler handler;
+		struct v4l2_ctrl *hflip;
+		struct v4l2_ctrl *vflip;
+	} ctrls;
 };
 
 /**
@@ -182,6 +193,12 @@ struct ov2680_reg {
 
 #define to_ov2680_sensor(x) container_of(x, struct ov2680_device, sd)
 
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct ov2680_device,
+			     ctrls.handler)->sd;
+}
+
 #define OV2680_MAX_WRITE_BUF_SIZE	30
 
 struct ov2680_write_buffer {
-- 
2.39.0


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

* [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (29 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:35   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls Hans de Goede
                   ` (26 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Exposure and gain control should use standard v4l2 controls,
not a custom ioctl.

The next patch in this series will re-add support as standard controls,
this is split into 2 patches for easier reviewing.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 209 +-----------------
 drivers/staging/media/atomisp/i2c/ov2680.h    |   3 -
 2 files changed, 2 insertions(+), 210 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index df92b35ce062..d508c02444eb 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -60,181 +60,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
 	return 0;
 }
 
-static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
-				  int gain, int digitgain)
-
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	u16 vts;
-	int ret, exp_val;
-
-	dev_dbg(&client->dev,
-		"+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",
-		coarse_itg, gain, digitgain);
-
-	vts = dev->res->lines_per_frame;
-
-	/* group hold */
-	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x00);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_GROUP_ACCESS);
-		return ret;
-	}
-
-	/* Increase the VTS to match exposure + MARGIN */
-	if (coarse_itg > vts - OV2680_INTEGRATION_TIME_MARGIN)
-		vts = (u16)coarse_itg + OV2680_INTEGRATION_TIME_MARGIN;
-
-	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_TIMING_VTS_H);
-		return ret;
-	}
-
-	/* set exposure */
-
-	/* Lower four bit should be 0*/
-	exp_val = coarse_itg << 4;
-	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_L, exp_val & 0xFF);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_EXPOSURE_L);
-		return ret;
-	}
-
-	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_M, (exp_val >> 8) & 0xFF);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_EXPOSURE_M);
-		return ret;
-	}
-
-	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_H, (exp_val >> 16) & 0x0F);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_EXPOSURE_H);
-		return ret;
-	}
-
-	/* Analog gain */
-	ret = ovxxxx_write_reg16(client, OV2680_AGC_H, gain);
-	if (ret) {
-		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
-			__func__, OV2680_AGC_H);
-		return ret;
-	}
-	/* Digital gain */
-	if (digitgain) {
-		ret = ovxxxx_write_reg16(client, OV2680_MWB_RED_GAIN_H, digitgain);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s: write 0x%02x: error, aborted\n",
-				__func__, OV2680_MWB_RED_GAIN_H);
-			return ret;
-		}
-
-		ret = ovxxxx_write_reg16(client, OV2680_MWB_GREEN_GAIN_H, digitgain);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s: write 0x%02x: error, aborted\n",
-				__func__, OV2680_MWB_RED_GAIN_H);
-			return ret;
-		}
-
-		ret = ovxxxx_write_reg16(client, OV2680_MWB_BLUE_GAIN_H, digitgain);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s: write 0x%02x: error, aborted\n",
-				__func__, OV2680_MWB_RED_GAIN_H);
-			return ret;
-		}
-	}
-
-	/* End group */
-	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x10);
-	if (ret)
-		return ret;
-
-	/* Delay launch group */
-	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0xa0);
-	if (ret)
-		return ret;
-	return ret;
-}
-
-static int ov2680_set_exposure(struct v4l2_subdev *sd, int exposure,
-			       int gain, int digitgain)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	int ret = 0;
-
-	mutex_lock(&dev->input_lock);
-
-	dev->exposure = exposure;
-	dev->gain = gain;
-	dev->digitgain = digitgain;
-
-	if (dev->power_on)
-		ret = __ov2680_set_exposure(sd, exposure, gain, digitgain);
-
-	mutex_unlock(&dev->input_lock);
-
-	return ret;
-}
-
-static long ov2680_s_exposure(struct v4l2_subdev *sd,
-			      struct atomisp_exposure *exposure)
-{
-	u16 coarse_itg = exposure->integration_time[0];
-	u16 analog_gain = exposure->gain[0];
-	u16 digital_gain = exposure->gain[1];
-
-	/* we should not accept the invalid value below */
-	if (analog_gain == 0) {
-		struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-		v4l2_err(client, "%s: invalid value\n", __func__);
-		return -EINVAL;
-	}
-
-	return ov2680_set_exposure(sd, coarse_itg, analog_gain, digital_gain);
-}
-
-static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case ATOMISP_IOC_S_EXPOSURE:
-		return ov2680_s_exposure(sd, arg);
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*
- * This returns the exposure time being used. This should only be used
- * for filling in EXIF data, not for actual image processing.
- */
-static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	u32 reg_val;
-	int ret;
-
-	/* get exposure */
-	ret = ovxxxx_read_reg24(client, OV2680_EXPOSURE_H, &reg_val);
-	if (ret)
-		return ret;
-
-	/* Lower four bits are not part of the exposure val (always 0) */
-	*value = reg_val >> 4;
-	return 0;
-}
-
 static void ov2680_set_bayer_order(struct ov2680_device *sensor, struct v4l2_mbus_framefmt *fmt)
 {
 	static const int ov2680_hv_flip_bayer_order[] = {
@@ -316,25 +141,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 	return ret;
 }
 
-static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
-	int ret = 0;
-
-	switch (ctrl->id) {
-	case V4L2_CID_EXPOSURE_ABSOLUTE:
-		ret = ov2680_q_exposure(sd, &ctrl->val);
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
 static const struct v4l2_ctrl_ops ov2680_ctrl_ops = {
 	.s_ctrl = ov2680_s_ctrl,
-	.g_volatile_ctrl = ov2680_g_volatile_ctrl
 };
 
 static int ov2680_init_registers(struct v4l2_subdev *sd)
@@ -443,10 +251,6 @@ static int power_up(struct v4l2_subdev *sd)
 	if (ret)
 		goto fail_init_registers;
 
-	ret = __ov2680_set_exposure(sd, dev->exposure, dev->gain, dev->digitgain);
-	if (ret)
-		goto fail_init_registers;
-
 	dev->power_on = true;
 	return 0;
 
@@ -547,7 +351,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *fmt;
 	struct ov2680_resolution *res;
-	int vts, ret = 0;
+	int ret = 0;
 
 	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
 		__func__,
@@ -582,13 +386,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		goto err;
 	}
 
-	vts = dev->res->lines_per_frame;
-
-	/* If necessary increase the VTS to match exposure + MARGIN */
-	if (dev->exposure > vts - OV2680_INTEGRATION_TIME_MARGIN)
-		vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN;
-
-	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
+	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, dev->res->lines_per_frame);
 	if (ret) {
 		dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
 		goto err;
@@ -814,7 +612,6 @@ static const struct v4l2_subdev_sensor_ops ov2680_sensor_ops = {
 
 static const struct v4l2_subdev_core_ops ov2680_core_ops = {
 	.s_power = ov2680_s_power,
-	.ioctl = ov2680_ioctl,
 };
 
 static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
@@ -884,8 +681,6 @@ static int ov2680_probe(struct i2c_client *client)
 
 	dev->client = client;
 	dev->res = &ov2680_res_preview[0];
-	dev->exposure = dev->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
-	dev->gain = 250; /* 0-2047 */
 	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
 
 	pdata = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 43bbc9368422..45eb1f93b847 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -163,9 +163,6 @@ struct ov2680_device {
 	struct camera_sensor_platform_data *platform_data;
 	bool power_on;
 	bool is_streaming;
-	u16 exposure;
-	u16 gain;
-	u16 digitgain;
 
 	struct ov2680_mode {
 		struct v4l2_mbus_framefmt fmt;
-- 
2.39.0


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

* [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (30 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:43   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 33/57] media: atomisp: ov2680: Add test pattern control Hans de Goede
                   ` (25 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Add exposure and gain controls. This allows controlling
the exposure and gain through standard v4l2 IOCTLs.

Note the register defines for the exposure and gain registers
are renamed to match the datasheet.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 27 +++++++++++++++----
 drivers/staging/media/atomisp/i2c/ov2680.h    |  9 +++----
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index d508c02444eb..14002a1c22d2 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -117,6 +117,16 @@ static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val)
 	return 0;
 }
 
+static int ov2680_exposure_set(struct ov2680_device *sensor, u32 exp)
+{
+	return ovxxxx_write_reg24(sensor->client, OV2680_REG_EXPOSURE_PK_HIGH, exp << 4);
+}
+
+static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
+{
+	return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
+}
+
 static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
@@ -135,6 +145,12 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_HFLIP:
 		ret = ov2680_set_hflip(sensor, ctrl->val);
 		break;
+	case V4L2_CID_EXPOSURE:
+		ret = ov2680_exposure_set(sensor, ctrl->val);
+		break;
+	case V4L2_CID_GAIN:
+		ret = ov2680_gain_set(sensor, ctrl->val);
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -392,10 +408,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		goto err;
 	}
 
-	/*
-	 * recall flip functions to avoid flip registers
-	 * were overridden by default setting
-	 */
+	/* Restore value of all ctrls */
 	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
 	if (ret < 0)
 		goto err;
@@ -634,13 +647,17 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
 	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
 	struct ov2680_ctrls *ctrls = &sensor->ctrls;
 	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+	int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
 
-	v4l2_ctrl_handler_init(hdl, 2);
+	v4l2_ctrl_handler_init(hdl, 4);
 
 	hdl->lock = &sensor->input_lock;
 
 	ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
 	ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+					    0, exp_max, 1, exp_max);
+	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
 
 	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 45eb1f93b847..e3ad20a7ffd5 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -90,11 +90,8 @@
 
 #define OV2680_GROUP_ACCESS							0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
 
-#define OV2680_EXPOSURE_H							0x3500 /*Bit[3:0] Bit[19:16] of exposure, remaining 16 bits lies in Reg0x3501&Reg0x3502*/
-#define OV2680_EXPOSURE_M							0x3501
-#define OV2680_EXPOSURE_L							0x3502
-#define OV2680_AGC_H								0x350A /*Bit[1:0] means Bit[9:8] of gain*/
-#define OV2680_AGC_L								0x350B /*Bit[7:0] of gain*/
+#define OV2680_REG_EXPOSURE_PK_HIGH		0x3500
+#define OV2680_REG_GAIN_PK			0x350a
 
 #define OV2680_HORIZONTAL_START_H					0x3800 /*Bit[11:8]*/
 #define OV2680_HORIZONTAL_START_L					0x3801 /*Bit[7:0]*/
@@ -172,6 +169,8 @@ struct ov2680_device {
 		struct v4l2_ctrl_handler handler;
 		struct v4l2_ctrl *hflip;
 		struct v4l2_ctrl *vflip;
+		struct v4l2_ctrl *exposure;
+		struct v4l2_ctrl *gain;
 	} ctrls;
 };
 
-- 
2.39.0


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

* [PATCH 33/57] media: atomisp: ov2680: Add test pattern control
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (31 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:46   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions Hans de Goede
                   ` (24 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Add a test pattern control. This is a 1:1 copy of the test pattern
control in the main drivers/media/i2c/ov2680.c driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 33 +++++++++++++++++++
 drivers/staging/media/atomisp/i2c/ov2680.h    |  3 ++
 2 files changed, 36 insertions(+)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 14002a1c22d2..6ca2a5bb0700 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -127,6 +127,24 @@ static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
 	return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
 }
 
+static int ov2680_test_pattern_set(struct ov2680_device *sensor, int value)
+{
+	int ret;
+
+	if (!value)
+		return ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), 0);
+
+	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, 0x03, value - 1);
+	if (ret < 0)
+		return ret;
+
+	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
@@ -151,6 +169,9 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_GAIN:
 		ret = ov2680_gain_set(sensor, ctrl->val);
 		break;
+	case V4L2_CID_TEST_PATTERN:
+		ret = ov2680_test_pattern_set(sensor, ctrl->val);
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -644,6 +665,13 @@ static const struct v4l2_subdev_ops ov2680_ops = {
 
 static int ov2680_init_controls(struct ov2680_device *sensor)
 {
+	static const char * const test_pattern_menu[] = {
+		"Disabled",
+		"Color Bars",
+		"Random Data",
+		"Square",
+		"Black Image",
+	};
 	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
 	struct ov2680_ctrls *ctrls = &sensor->ctrls;
 	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
@@ -658,6 +686,11 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
 	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
 					    0, exp_max, 1, exp_max);
 	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
+	ctrls->test_pattern =
+		v4l2_ctrl_new_std_menu_items(hdl,
+					     &ov2680_ctrl_ops, V4L2_CID_TEST_PATTERN,
+					     ARRAY_SIZE(test_pattern_menu) - 1,
+					     0, 0, test_pattern_menu);
 
 	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
 	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index e3ad20a7ffd5..45526477b612 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -120,6 +120,8 @@
 #define OV2680_MWB_BLUE_GAIN_H			0x5008/*0x3404*/
 #define OV2680_MWB_GAIN_MAX				0x0fff
 
+#define OV2680_REG_ISP_CTRL00			0x5080
+
 #define OV2680_START_STREAMING			0x01
 #define OV2680_STOP_STREAMING			0x00
 
@@ -171,6 +173,7 @@ struct ov2680_device {
 		struct v4l2_ctrl *vflip;
 		struct v4l2_ctrl *exposure;
 		struct v4l2_ctrl *gain;
+		struct v4l2_ctrl *test_pattern;
 	} ctrls;
 };
 
-- 
2.39.0


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

* [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (32 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 33/57] media: atomisp: ov2680: Add test pattern control Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:48   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based Hans de Goede
                   ` (23 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

By default the ov2680 automatically sets the window to match the outputsize
and automatically adjusts it to keep the bayer pattern stable when enabling
hflip/vflip.

This does not work for the 1616x1216 mode because there is no room to
adjust the window there. To make flipping work in the 1616 wide modes the
register lists for those modes set bit 0 of 0x5708 (manual_win_en) to 1 and
ov2680_set_bayer_order() updates the bayer-order on the pad to match.

But ov2680_set_bayer_order() is always called, so when enabling flipping
on modes with a width of less then 1616 now results in the wrong bayer
order being reported on the pad since the sensor is auto-adjusting
the window in this case.

Specify the correct (== output-size) window-size in all resolutions
register-list and always set the manual_win_en bit, so that the bayer order
is changed on hflip/vflip enable on all resolutions.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/ov2680.h | 76 +++++++++++-----------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 45526477b612..54978ff9348c 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -316,11 +316,11 @@ static struct ov2680_reg const ov2680_QCIF_30fps[] = {
 	{0x4008, 0x00},
 	{0x4009, 0x03},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x00},
+	{0x5705, 0xc0},
+	{0x5706, 0x00},
+	{0x5707, 0xa0},
 	{0x3820, 0xc2},
 	{0x3821, 0x01},
 	// {0x5090, 0x0c},
@@ -355,11 +355,11 @@ static struct ov2680_reg const ov2680_CIF_30fps[] = {
 	{0x4008, 0x00},
 	{0x4009, 0x03},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x01},
+	{0x5705, 0x70},
+	{0x5706, 0x01},
+	{0x5707, 0x30},
 	{0x3820, 0xc2},
 	{0x3821, 0x01},
 	// {0x5090, 0x0c},
@@ -394,11 +394,11 @@ static struct ov2680_reg const ov2680_QVGA_30fps[] = {
 	{0x4008, 0x00},
 	{0x4009, 0x03},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x01},
+	{0x5705, 0x50},
+	{0x5706, 0x01},
+	{0x5707, 0x00},
 	{0x3820, 0xc2},
 	{0x3821, 0x01},
 	// {0x5090, 0x0c},
@@ -433,11 +433,11 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = {
 	{0x4008, 0x00},
 	{0x4009, 0x03},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x02},
+	{0x5705, 0x90},
+	{0x5706, 0x01},
+	{0x5707, 0xf0},
 	{0x3820, 0xc2},
 	{0x3821, 0x01},
 	// {0x5090, 0x0c},
@@ -471,7 +471,7 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = {
 	{0x3815, 0x31},
 	{0x4008, 0x00},
 	{0x4009, 0x03},
-	{0x5708, 0x00},
+	{0x5708, 0x01},
 	{0x5704, 0x02},
 	{0x5705, 0xd0}, // X_WIN;
 	{0x5706, 0x02},
@@ -510,7 +510,7 @@ static struct ov2680_reg const ov2680_800x600_30fps[] = {
 	{0x3813, 0x00},
 	{0x3814, 0x31},
 	{0x3815, 0x31},
-	{0x5708, 0x00},
+	{0x5708, 0x01},
 	{0x5704, 0x03},
 	{0x5705, 0x20},
 	{0x5706, 0x02},
@@ -552,11 +552,11 @@ static struct ov2680_reg const ov2680_720p_30fps[] = {
 	{0x4008, 0x02},
 	{0x4009, 0x09},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x05},
+	{0x5705, 0x10},
+	{0x5706, 0x02},
+	{0x5707, 0xe0},
 	{0x3820, 0xc0},
 	{0x3821, 0x00},
 	// {0x5090, 0x0c},
@@ -591,11 +591,11 @@ static struct ov2680_reg const ov2680_1296x976_30fps[] = {
 	{0x4008, 0x02},
 	{0x4009, 0x09},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x05},
+	{0x5705, 0x10},
+	{0x5706, 0x03},
+	{0x5707, 0xd0},
 	{0x3820, 0xc0},
 	{0x3821, 0x00}, //mirror/flip
 	// {0x5090, 0x0c},
@@ -630,11 +630,11 @@ static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
 	{0x4008, 0x02},
 	{0x4009, 0x09},
 	{0x5081, 0x41},
-	{0x5708, 0x00}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x10},
-	{0x5705, 0xa0},
-	{0x5706, 0x0c},
-	{0x5707, 0x78},
+	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
+	{0x5704, 0x05},
+	{0x5705, 0xb0},
+	{0x5706, 0x04},
+	{0x5707, 0x48},
 	{0x3820, 0xc0},
 	{0x3821, 0x00},
 	// {0x5090, 0x0c},
@@ -752,7 +752,7 @@ static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
 	{0x5704, 0x06},
 	{0x5705, 0x50},
 	{0x5706, 0x04},
-	{0x5707, 0xcc},
+	{0x5707, 0xc0},
 	{0x3820, 0xc0},
 	{0x3821, 0x00},
 	// {0x5090, 0x0C},
-- 
2.39.0


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

* [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (33 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:37   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames Hans de Goede
                   ` (22 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Instead of using a long fixed register settings list for each resolution,
calculate the register settings based on the requested width + height.

This will allow future enhancements like adding hblank and vblank controls
and adding selection support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 137 ++++++++++++++++--
 drivers/staging/media/atomisp/i2c/ov2680.h    |  41 +++++-
 2 files changed, 164 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 6ca2a5bb0700..6693f042f4f2 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -380,6 +380,131 @@ static void ov2680_fill_format(struct ov2680_device *sensor,
 	ov2680_set_bayer_order(sensor, fmt);
 }
 
+static void ov2680_calc_mode(struct ov2680_device *sensor, int width, int height)
+{
+	int orig_width = width;
+	int orig_height = height;
+
+	if (width  <= (OV2680_NATIVE_WIDTH / 2) &&
+	    height <= (OV2680_NATIVE_HEIGHT / 2)) {
+		sensor->mode.binning = true;
+		width *= 2;
+		height *= 2;
+	} else {
+		sensor->mode.binning = false;
+	}
+
+	sensor->mode.h_start = ((OV2680_NATIVE_WIDTH - width) / 2) & ~1;
+	sensor->mode.v_start = ((OV2680_NATIVE_HEIGHT - height) / 2) & ~1;
+	sensor->mode.h_end = min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1,
+				 OV2680_NATIVE_WIDTH - 1);
+	sensor->mode.v_end = min(sensor->mode.v_start + height + OV2680_END_MARGIN - 1,
+				 OV2680_NATIVE_HEIGHT - 1);
+	sensor->mode.h_output_size = orig_width;
+	sensor->mode.v_output_size = orig_height;
+	sensor->mode.hts = OV2680_PIXELS_PER_LINE;
+	sensor->mode.vts = OV2680_LINES_PER_FRAME;
+}
+
+static int ov2680_set_mode(struct ov2680_device *sensor, int width, int height)
+{
+	struct i2c_client *client = sensor->client;
+	u8 pll_div, unknown, inc, fmt1, fmt2;
+	int ret;
+
+	ov2680_calc_mode(sensor, width, height);
+
+	if (sensor->mode.binning) {
+		pll_div = 1;
+		unknown = 0x23;
+		inc = 0x31;
+		fmt1 = 0xc2;
+		fmt2 = 0x01;
+	} else {
+		pll_div = 0;
+		unknown = 0x21;
+		inc = 0x11;
+		fmt1 = 0xc0;
+		fmt2 = 0x00;
+	}
+
+	ret = ovxxxx_write_reg8(client, 0x3086, pll_div);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg8(client, 0x370a, unknown);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_HORIZONTAL_START_H, sensor->mode.h_start);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_VERTICAL_START_H, sensor->mode.v_start);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_HORIZONTAL_END_H, sensor->mode.h_end);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_VERTICAL_END_H, sensor->mode.v_end);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_HORIZONTAL_OUTPUT_SIZE_H,
+				 sensor->mode.h_output_size);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_VERTICAL_OUTPUT_SIZE_H,
+				 sensor->mode.v_output_size);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_HTS_H, sensor->mode.hts);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_VTS_H, sensor->mode.vts);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_ISP_X_WIN_H, 0);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_ISP_Y_WIN_H, 0);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg8(client, OV2680_X_INC, inc);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg8(client, OV2680_Y_INC, inc);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_X_WIN_H, sensor->mode.h_output_size);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg16(client, OV2680_Y_WIN_H, sensor->mode.v_output_size);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg8(client, OV2680_REG_FORMAT1, fmt1);
+	if (ret)
+		return ret;
+
+	ret = ovxxxx_write_reg8(client, OV2680_REG_FORMAT2, fmt2);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int ov2680_set_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
@@ -416,18 +541,10 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 
 	/* s_power has not been called yet for std v4l2 clients (camorama) */
 	power_up(sd);
-	ret = ov2680_write_reg_array(client, dev->res->regs);
-	if (ret) {
-		dev_err(&client->dev,
-			"ov2680 write resolution register err: %d\n", ret);
-		goto err;
-	}
 
-	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, dev->res->lines_per_frame);
-	if (ret) {
-		dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
+	ret = ov2680_set_mode(dev, fmt->width, fmt->height);
+	if (ret < 0)
 		goto err;
-	}
 
 	/* Restore value of all ctrls */
 	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 54978ff9348c..9bbb34dd95a5 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -35,6 +35,13 @@
 #define OV2680_NATIVE_WIDTH			1616
 #define OV2680_NATIVE_HEIGHT			1216
 
+/* 1704 * 1294 * 30fps = 66MHz pixel clock */
+#define OV2680_PIXELS_PER_LINE			1704
+#define OV2680_LINES_PER_FRAME			1294
+
+/* If possible send 16 extra rows / lines to the ISP as padding */
+#define OV2680_END_MARGIN			16
+
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
 
 #define OV2680_BIN_FACTOR_MAX 4
@@ -105,10 +112,17 @@
 #define OV2680_HORIZONTAL_OUTPUT_SIZE_L				0x3809 /*Bit[7:0]*/
 #define OV2680_VERTICAL_OUTPUT_SIZE_H				0x380a /*Bit[3:0]*/
 #define OV2680_VERTICAL_OUTPUT_SIZE_L				0x380b /*Bit[7:0]*/
-#define OV2680_TIMING_HTS_H							0x380C  /*High 8-bit, and low 8-bit HTS address is 0x380d*/
-#define OV2680_TIMING_HTS_L							0x380D  /*High 8-bit, and low 8-bit HTS address is 0x380d*/
-#define OV2680_TIMING_VTS_H							0x380e  /*High 8-bit, and low 8-bit HTS address is 0x380f*/
-#define OV2680_TIMING_VTS_L							0x380f  /*High 8-bit, and low 8-bit HTS address is 0x380f*/
+#define OV2680_HTS_H				0x380c
+#define OV2680_HTS_L				0x380d
+#define OV2680_VTS_H				0x380e
+#define OV2680_VTS_L				0x380f
+#define OV2680_ISP_X_WIN_H			0x3810
+#define OV2680_ISP_X_WIN_L			0x3811
+#define OV2680_ISP_Y_WIN_H			0x3812
+#define OV2680_ISP_Y_WIN_L			0x3813
+#define OV2680_X_INC				0x3814
+#define OV2680_Y_INC				0x3815
+
 #define OV2680_FRAME_OFF_NUM						0x4202
 
 /*Flip/Mirror*/
@@ -122,6 +136,12 @@
 
 #define OV2680_REG_ISP_CTRL00			0x5080
 
+#define OV2680_X_WIN_H				0x5704
+#define OV2680_X_WIN_L				0x5705
+#define OV2680_Y_WIN_H				0x5706
+#define OV2680_Y_WIN_L				0x5707
+#define OV2680_WIN_CONTROL			0x5708
+
 #define OV2680_START_STREAMING			0x01
 #define OV2680_STOP_STREAMING			0x00
 
@@ -165,6 +185,15 @@ struct ov2680_device {
 
 	struct ov2680_mode {
 		struct v4l2_mbus_framefmt fmt;
+		bool binning;
+		u16 h_start;
+		u16 v_start;
+		u16 h_end;
+		u16 v_end;
+		u16 h_output_size;
+		u16 v_output_size;
+		u16 hts;
+		u16 vts;
 	} mode;
 
 	struct ov2680_ctrls {
@@ -246,6 +275,8 @@ static struct ov2680_reg const ov2680_global_setting[] = {
 	{0x3819, 0x04},
 	{0x4000, 0x81},
 	{0x4001, 0x40},
+	{0x4008, 0x00},
+	{0x4009, 0x03},
 	{0x4602, 0x02},
 	{0x481f, 0x36},
 	{0x4825, 0x36},
@@ -258,6 +289,8 @@ static struct ov2680_reg const ov2680_global_setting[] = {
 	{0x5008, 0x04},
 	{0x5009, 0x00},
 	{0x5080, 0x00},
+	{0x5081, 0x41},
+	{0x5708, 0x01},  //add for full size flip off and mirror off 2014/09/11
 	{0x3701, 0x64},  //add on 14/05/13
 	{0x3784, 0x0c},  //based OV2680_R1A_AM10.ovt add on 14/06/13
 	{0x5780, 0x3e},  //based OV2680_R1A_AM10.ovt,Adjust DPC setting (57xx) on 14/06/13
-- 
2.39.0


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

* [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (34 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:40   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device Hans de Goede
                   ` (21 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The fps, lines-per-frame and skip-frames values are the same for all
resolutions, use defines for these.

The ov2680_res_preview[] incorrectly sets fps to 60 for some low-res
modes, this is incorrect with the current fixed (resolution independent)
lines-per-frame value.

Note this not drop the now no longer used fps, lines-per-frame and
skip-frames struct ov2680_resolution members. The entire struct is going
away in the next patches so that would just cause unnecessary changes.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/i2c/atomisp-ov2680.c   | 16 ++++------------
 drivers/staging/media/atomisp/i2c/ov2680.h       |  2 ++
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 6693f042f4f2..dee6eb3d8c63 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -685,11 +685,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 static int ov2680_g_frame_interval(struct v4l2_subdev *sd,
 				   struct v4l2_subdev_frame_interval *interval)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-
 	interval->interval.numerator = 1;
-	interval->interval.denominator = dev->res->fps;
-
+	interval->interval.denominator = OV2680_FPS;
 	return 0;
 }
 
@@ -733,8 +730,8 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
 	    fie->which > V4L2_SUBDEV_FORMAT_ACTIVE)
 		return -EINVAL;
 
-	fract.denominator = ov2680_res_preview[fie->index].fps;
 	fract.numerator = 1;
+	fract.denominator = OV2680_FPS;
 
 	fie->interval = fract;
 
@@ -743,12 +740,7 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
 
 static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-
-	mutex_lock(&dev->input_lock);
-	*frames = dev->res->skip_frames;
-	mutex_unlock(&dev->input_lock);
-
+	*frames = OV2680_SKIP_FRAMES;
 	return 0;
 }
 
@@ -792,7 +784,7 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
 	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
 	struct ov2680_ctrls *ctrls = &sensor->ctrls;
 	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
-	int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
+	int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN;
 
 	v4l2_ctrl_handler_init(hdl, 4);
 
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 9bbb34dd95a5..4c1d20f514b2 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -38,6 +38,8 @@
 /* 1704 * 1294 * 30fps = 66MHz pixel clock */
 #define OV2680_PIXELS_PER_LINE			1704
 #define OV2680_LINES_PER_FRAME			1294
+#define OV2680_FPS				30
+#define OV2680_SKIP_FRAMES			3
 
 /* If possible send 16 extra rows / lines to the ISP as padding */
 #define OV2680_END_MARGIN			16
-- 
2.39.0


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

* [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (35 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:39   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval() Hans de Goede
                   ` (20 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The res member of struct ov2680_device isn't read anywhere anymore,
drop it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 5 -----
 drivers/staging/media/atomisp/i2c/ov2680.h         | 1 -
 2 files changed, 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index dee6eb3d8c63..09c260ac93bf 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -548,10 +548,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 
 	/* Restore value of all ctrls */
 	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
-	if (ret < 0)
-		goto err;
-
-	dev->res = res;
 err:
 	mutex_unlock(&dev->input_lock);
 	return ret;
@@ -839,7 +835,6 @@ static int ov2680_probe(struct i2c_client *client)
 	mutex_init(&dev->input_lock);
 
 	dev->client = client;
-	dev->res = &ov2680_res_preview[0];
 	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
 
 	pdata = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 4c1d20f514b2..e9d0c84705fb 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -180,7 +180,6 @@ struct ov2680_device {
 	struct media_pad pad;
 	struct mutex input_lock;
 	struct i2c_client *client;
-	struct ov2680_resolution *res;
 	struct camera_sensor_platform_data *platform_data;
 	bool power_on;
 	bool is_streaming;
-- 
2.39.0


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

* [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (36 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:42   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt() Hans de Goede
                   ` (19 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Fix and simplify ov2680_enum_frame_interval(), the index is not
an index into ov2680_res_preview[], so using N_PREVIEW is wrong.

Instead it is an index indexing the different framerates for
the resolution specified in fie->width, fie->height.

Since the ov2680 code only supports a single fixed 30 fps,
index must always be 0 and we don't need to check the other
fie input values.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/i2c/atomisp-ov2680.c    | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 09c260ac93bf..75d09c44202c 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -718,19 +718,12 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
 				      struct v4l2_subdev_state *sd_state,
 				      struct v4l2_subdev_frame_interval_enum *fie)
 {
-	struct v4l2_fract fract;
-
-	if (fie->index >= N_RES_PREVIEW ||
-	    fie->width > ov2680_res_preview[0].width ||
-	    fie->height > ov2680_res_preview[0].height ||
-	    fie->which > V4L2_SUBDEV_FORMAT_ACTIVE)
+	/* Only 1 framerate */
+	if (fie->index)
 		return -EINVAL;
 
-	fract.numerator = 1;
-	fract.denominator = OV2680_FPS;
-
-	fie->interval = fract;
-
+	fie->interval.numerator = 1;
+	fie->interval.denominator = OV2680_FPS;
 	return 0;
 }
 
-- 
2.39.0


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

* [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (37 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:43   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview Hans de Goede
                   ` (18 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Since we now calculate timings baded on the desired width and height,
any width and height are valid as long as they don't exceed the sensor's
dimensions.

Drop the v4l2_find_nearest_size() call and instead clamp the requested
width and height.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 75d09c44202c..3d5e18fb45ee 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -512,7 +512,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *fmt;
-	struct ov2680_resolution *res;
+	unsigned int width, height;
 	int ret = 0;
 
 	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
@@ -520,14 +520,11 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		(format->which == V4L2_SUBDEV_FORMAT_TRY) ? "try" : "set",
 		format->pad, fmt);
 
-	res = v4l2_find_nearest_size(ov2680_res_preview, ARRAY_SIZE(ov2680_res_preview),
-				     width, height,
-				     format->format.width, format->format.height);
-	if (!res)
-		res = &ov2680_res_preview[N_RES_PREVIEW - 1];
+	width = min_t(unsigned int, ALIGN(format->format.width, 2), OV2680_NATIVE_WIDTH);
+	height = min_t(unsigned int, ALIGN(format->format.height, 2), OV2680_NATIVE_HEIGHT);
 
 	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
-	ov2680_fill_format(dev, fmt, res->width, res->height);
+	ov2680_fill_format(dev, fmt, width, height);
 
 	format->format = *fmt;
 
-- 
2.39.0


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

* [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (38 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt() Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:44   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list Hans de Goede
                   ` (17 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Drop struct ov2680_resolution and the ov2680_res_preview[] array,
this is now only used in ov2680_enum_frame_size() and only
the width + height are used there.

Replace this with a new struct v4l2_frmsize_discrete ov2680_frame_sizes[]
array.

No functional changes.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        |  24 +-
 drivers/staging/media/atomisp/i2c/ov2680.h    | 610 ------------------
 2 files changed, 19 insertions(+), 615 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 3d5e18fb45ee..432539dd274c 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -698,15 +698,29 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_state *sd_state,
 				  struct v4l2_subdev_frame_size_enum *fse)
 {
+	static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = {
+		{ 1616, 1216 },
+		{ 1616, 1082 },
+		{ 1616,  916 },
+		{ 1456, 1096 },
+		{ 1296,  976 },
+		{ 1296,  736 },
+		{  800,  600 },
+		{  720,  592 },
+		{  656,  496 },
+		{  336,  256 },
+		{  352,  288 },
+		{  176,  144 },
+	};
 	int index = fse->index;
 
-	if (index >= N_RES_PREVIEW)
+	if (index >= ARRAY_SIZE(ov2680_frame_sizes))
 		return -EINVAL;
 
-	fse->min_width = ov2680_res_preview[index].width;
-	fse->min_height = ov2680_res_preview[index].height;
-	fse->max_width = ov2680_res_preview[index].width;
-	fse->max_height = ov2680_res_preview[index].height;
+	fse->min_width = ov2680_frame_sizes[index].width;
+	fse->min_height = ov2680_frame_sizes[index].height;
+	fse->max_width = ov2680_frame_sizes[index].width;
+	fse->max_height = ov2680_frame_sizes[index].height;
 
 	return 0;
 }
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index e9d0c84705fb..20ef59928cb1 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -154,18 +154,6 @@ struct regval_list {
 	u8 value;
 };
 
-struct ov2680_resolution {
-	const struct ov2680_reg *regs;
-	int res;
-	int width;
-	int height;
-	int fps;
-	int pix_clk_freq;
-	u32 skip_frames;
-	u16 pixels_per_line;
-	u16 lines_per_frame;
-};
-
 struct ov2680_format {
 	u8 *desc;
 	u32 pixelformat;
@@ -320,602 +308,4 @@ static struct ov2680_reg const ov2680_global_setting[] = {
 	{}
 };
 
-/*
- * 176x144 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_QCIF_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0xa0},
-	{0x3802, 0x00},
-	{0x3803, 0x78},
-	{0x3804, 0x05},
-	{0x3805, 0xaf},
-	{0x3806, 0x04},
-	{0x3807, 0x47},
-	{0x3808, 0x00},
-	{0x3809, 0xC0},
-	{0x380a, 0x00},
-	{0x380b, 0xa0},
-	{0x380c, 0x06},
-	{0x380d, 0xb0},
-	{0x3810, 0x00},
-	{0x3811, 0x04},
-	{0x3812, 0x00},
-	{0x3813, 0x04},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x4000, 0x81},
-	{0x4001, 0x40},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x00},
-	{0x5705, 0xc0},
-	{0x5706, 0x00},
-	{0x5707, 0xa0},
-	{0x3820, 0xc2},
-	{0x3821, 0x01},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- * 352x288 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_CIF_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0xa0},
-	{0x3802, 0x00},
-	{0x3803, 0x78},
-	{0x3804, 0x03},
-	{0x3805, 0x8f},
-	{0x3806, 0x02},
-	{0x3807, 0xe7},
-	{0x3808, 0x01},
-	{0x3809, 0x70},
-	{0x380a, 0x01},
-	{0x380b, 0x30},
-	{0x380c, 0x06},
-	{0x380d, 0xb0},
-	{0x3810, 0x00},
-	{0x3811, 0x04},
-	{0x3812, 0x00},
-	{0x3813, 0x04},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x01},
-	{0x5705, 0x70},
-	{0x5706, 0x01},
-	{0x5707, 0x30},
-	{0x3820, 0xc2},
-	{0x3821, 0x01},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- * 336x256 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_QVGA_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0xa0},
-	{0x3802, 0x00},
-	{0x3803, 0x78},
-	{0x3804, 0x03},
-	{0x3805, 0x4f},
-	{0x3806, 0x02},
-	{0x3807, 0x87},
-	{0x3808, 0x01},
-	{0x3809, 0x50},
-	{0x380a, 0x01},
-	{0x380b, 0x00},
-	{0x380c, 0x06},
-	{0x380d, 0xb0},
-	{0x3810, 0x00},
-	{0x3811, 0x04},
-	{0x3812, 0x00},
-	{0x3813, 0x04},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x01},
-	{0x5705, 0x50},
-	{0x5706, 0x01},
-	{0x5707, 0x00},
-	{0x3820, 0xc2},
-	{0x3821, 0x01},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- * 656x496 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_656x496_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0xa0},
-	{0x3802, 0x00},
-	{0x3803, 0x78},
-	{0x3804, 0x05},
-	{0x3805, 0xcf},
-	{0x3806, 0x04},
-	{0x3807, 0x67},
-	{0x3808, 0x02},
-	{0x3809, 0x90},
-	{0x380a, 0x01},
-	{0x380b, 0xf0},
-	{0x380c, 0x06},
-	{0x380d, 0xb0},
-	{0x3810, 0x00},
-	{0x3811, 0x04},
-	{0x3812, 0x00},
-	{0x3813, 0x04},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x02},
-	{0x5705, 0x90},
-	{0x5706, 0x01},
-	{0x5707, 0xf0},
-	{0x3820, 0xc2},
-	{0x3821, 0x01},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- * 720x592 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_720x592_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0x00}, // X_ADDR_START;
-	{0x3802, 0x00},
-	{0x3803, 0x00}, // Y_ADDR_START;
-	{0x3804, 0x05},
-	{0x3805, 0xaf}, // X_ADDR_END;
-	{0x3806, 0x04},
-	{0x3807, 0xaf}, // Y_ADDR_END;
-	{0x3808, 0x02},
-	{0x3809, 0xd0}, // X_OUTPUT_SIZE;
-	{0x380a, 0x02},
-	{0x380b, 0x50}, // Y_OUTPUT_SIZE;
-	{0x380c, 0x06},
-	{0x380d, 0xac}, // HTS;
-	{0x3810, 0x00},
-	{0x3811, 0x00},
-	{0x3812, 0x00},
-	{0x3813, 0x00},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5708, 0x01},
-	{0x5704, 0x02},
-	{0x5705, 0xd0}, // X_WIN;
-	{0x5706, 0x02},
-	{0x5707, 0x50}, // Y_WIN;
-	{0x3820, 0xc2}, // FLIP_FORMAT;
-	{0x3821, 0x01}, // MIRROR_FORMAT;
-	{0x5090, 0x00}, // PRE ISP CTRL16, default value is 0x0C;
-	// BIT[3]: Mirror order, BG or GB;
-	// BIT[2]: Flip order, BR or RB;
-	{0x5081, 0x41},
-	{}
-};
-
-/*
- * 800x600 30fps  VBlanking 1lane 10Bit (binning)
- */
-static struct ov2680_reg const ov2680_800x600_30fps[] = {
-	{0x3086, 0x01},
-	{0x370a, 0x23},
-	{0x3801, 0x00}, /* hstart 0 */
-	{0x3802, 0x00},
-	{0x3803, 0x00}, /* vstart 0 */
-	{0x3804, 0x06},
-	{0x3805, 0x4f}, /* hend 1615 */
-	{0x3806, 0x04},
-	{0x3807, 0xbf}, /* vend 1215 */
-	{0x3808, 0x03},
-	{0x3809, 0x20}, /* hsize 800 */
-	{0x380a, 0x02},
-	{0x380b, 0x58}, /* vsize 600 */
-	{0x380c, 0x06},
-	{0x380d, 0xac}, /* htotal 1708 */
-	{0x3810, 0x00},
-	{0x3811, 0x00},
-	{0x3812, 0x00},
-	{0x3813, 0x00},
-	{0x3814, 0x31},
-	{0x3815, 0x31},
-	{0x5708, 0x01},
-	{0x5704, 0x03},
-	{0x5705, 0x20},
-	{0x5706, 0x02},
-	{0x5707, 0x58},
-	{0x3820, 0xc2},
-	{0x3821, 0x01},
-	{0x5090, 0x00},
-	{0x4008, 0x00},
-	{0x4009, 0x03},
-	{0x5081, 0x41},
-	{}
-};
-
-/*
- * 720p=1280*720 30fps  VBlanking 1lane 10Bit (no-Scaling)
- */
-static struct ov2680_reg const ov2680_720p_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0xa0}, /* hstart 160 */
-	{0x3802, 0x00},
-	{0x3803, 0xf2}, /* vstart 242 */
-	{0x3804, 0x05},
-	{0x3805, 0xbf}, /* hend 1471 */
-	{0x3806, 0x03},
-	{0x3807, 0xdd}, /* vend 989 */
-	{0x3808, 0x05},
-	{0x3809, 0x10}, /* hsize 1296 */
-	{0x380a, 0x02},
-	{0x380b, 0xe0}, /* vsize 736 */
-	{0x380c, 0x06},
-	{0x380d, 0xa8}, /* htotal 1704 */
-	{0x3810, 0x00},
-	{0x3811, 0x08},
-	{0x3812, 0x00},
-	{0x3813, 0x06},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x4008, 0x02},
-	{0x4009, 0x09},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x05},
-	{0x5705, 0x10},
-	{0x5706, 0x02},
-	{0x5707, 0xe0},
-	{0x3820, 0xc0},
-	{0x3821, 0x00},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- * 1296x976 30fps  VBlanking 1lane 10Bit(no-scaling)
- */
-static struct ov2680_reg const ov2680_1296x976_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0xa0}, /* hstart 160 */
-	{0x3802, 0x00},
-	{0x3803, 0x78}, /* vstart 120 */
-	{0x3804, 0x05},
-	{0x3805, 0xbf}, /* hend 1471 */
-	{0x3806, 0x04},
-	{0x3807, 0x57}, /* vend 1111 */
-	{0x3808, 0x05},
-	{0x3809, 0x10}, /* hsize 1296 */
-	{0x380a, 0x03},
-	{0x380b, 0xd0}, /* vsize 976 */
-	{0x380c, 0x06},
-	{0x380d, 0xa8}, /* htotal 1704 */
-	{0x3810, 0x00},
-	{0x3811, 0x08},
-	{0x3812, 0x00},
-	{0x3813, 0x08},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x4008, 0x02},
-	{0x4009, 0x09},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x05},
-	{0x5705, 0x10},
-	{0x5706, 0x03},
-	{0x5707, 0xd0},
-	{0x3820, 0xc0},
-	{0x3821, 0x00}, //mirror/flip
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- *   1456*1096 30fps  VBlanking 1lane 10bit(no-scaling)
- */
-static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0x90},
-	{0x3802, 0x00},
-	{0x3803, 0x78},
-	{0x3804, 0x06},
-	{0x3805, 0x4f},
-	{0x3806, 0x04},
-	{0x3807, 0xC0},
-	{0x3808, 0x05},
-	{0x3809, 0xb0},
-	{0x380a, 0x04},
-	{0x380b, 0x48},
-	{0x380c, 0x06},
-	{0x380d, 0xa8},
-	{0x3810, 0x00},
-	{0x3811, 0x08},
-	{0x3812, 0x00},
-	{0x3813, 0x00},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x4008, 0x02},
-	{0x4009, 0x09},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x05},
-	{0x5705, 0xb0},
-	{0x5706, 0x04},
-	{0x5707, 0x48},
-	{0x3820, 0xc0},
-	{0x3821, 0x00},
-	// {0x5090, 0x0c},
-	{}
-};
-
-/*
- *1616x916  30fps  VBlanking 1lane 10bit
- */
-
-static struct ov2680_reg const ov2680_1616x916_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0x00},
-	{0x3802, 0x00},
-	{0x3803, 0x96},
-	{0x3804, 0x06},
-	{0x3805, 0x4f},
-	{0x3806, 0x04},
-	{0x3807, 0x39},
-	{0x3808, 0x06},
-	{0x3809, 0x50},
-	{0x380a, 0x03},
-	{0x380b, 0x94},
-	{0x380c, 0x06},
-	{0x380d, 0xa8},
-	{0x3810, 0x00},
-	{0x3811, 0x00},
-	{0x3812, 0x00},
-	{0x3813, 0x08},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x4008, 0x02},
-	{0x4009, 0x09},
-	{0x5081, 0x41},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x06},
-	{0x5705, 0x50},
-	{0x5706, 0x03},
-	{0x5707, 0x94},
-	{0x3820, 0xc0},
-	{0x3821, 0x00},
-	// {0x5090, 0x0C},
-	{}
-};
-
-/*
- * 1616x1082 30fps VBlanking 1lane 10Bit
- */
-static struct ov2680_reg const ov2680_1616x1082_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0x00},
-	{0x3802, 0x00},
-	{0x3803, 0x86},
-	{0x3804, 0x06},
-	{0x3805, 0x4f},
-	{0x3806, 0x04},
-	{0x3807, 0xbf},
-	{0x3808, 0x06},
-	{0x3809, 0x50},
-	{0x380a, 0x04},
-	{0x380b, 0x3a},
-	{0x380c, 0x06},
-	{0x380d, 0xa8},
-	{0x3810, 0x00},
-	{0x3811, 0x00},
-	{0x3812, 0x00},
-	{0x3813, 0x00},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x06},
-	{0x5705, 0x50},
-	{0x5706, 0x04},
-	{0x5707, 0x3a},
-	{0x3820, 0xc0},
-	{0x3821, 0x00},
-	// {0x5090, 0x0C},
-	{0x4008, 0x02},
-	{0x4009, 0x09},
-	{0x5081, 0x41},
-	{}
-};
-
-/*
- * 1616x1216 30fps VBlanking 1lane 10Bit
- */
-static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
-	{0x3086, 0x00},
-	{0x370a, 0x21},
-	{0x3801, 0x00},
-	{0x3802, 0x00},
-	{0x3803, 0x00},
-	{0x3804, 0x06},
-	{0x3805, 0x4f},
-	{0x3806, 0x04},
-	{0x3807, 0xbf},
-	{0x3808, 0x06},
-	{0x3809, 0x50},//50},//4line for mirror and flip
-	{0x380a, 0x04},
-	{0x380b, 0xc0},//c0},
-	{0x380c, 0x06},
-	{0x380d, 0xa8},
-	{0x3810, 0x00},
-	{0x3811, 0x00},
-	{0x3812, 0x00},
-	{0x3813, 0x00},
-	{0x3814, 0x11},
-	{0x3815, 0x11},
-	{0x4008, 0x00},
-	{0x4009, 0x0b},
-	{0x5081, 0x01},
-	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
-	{0x5704, 0x06},
-	{0x5705, 0x50},
-	{0x5706, 0x04},
-	{0x5707, 0xc0},
-	{0x3820, 0xc0},
-	{0x3821, 0x00},
-	// {0x5090, 0x0C},
-	{}
-};
-
-static struct ov2680_resolution ov2680_res_preview[] = {
-	{
-		.width = 1616,
-		.height = 1216,
-		.pix_clk_freq = 66,
-		.fps = 30,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_1616x1216_30fps,
-	},
-	{
-		.width = 1616,
-		.height = 1082,
-		.pix_clk_freq = 66,
-		.fps = 30,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_1616x1082_30fps,
-	},
-	{
-		.width = 1616,
-		.height = 916,
-		.fps = 30,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_1616x916_30fps,
-	},
-	{
-		.width = 1456,
-		.height = 1096,
-		.fps = 30,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_1456x1096_30fps,
-	},
-	{
-		.width = 1296,
-		.height = 976,
-		.fps = 30,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_1296x976_30fps,
-	},
-	{
-		.width = 1296,
-		.height = 736,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_720p_30fps,
-	},
-	{
-		.width = 800,
-		.height = 600,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_800x600_30fps,
-	},
-	{
-		.width = 720,
-		.height = 592,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_720x592_30fps,
-	},
-	{
-		.width = 656,
-		.height = 496,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_656x496_30fps,
-	},
-	{
-		.width = 336,
-		.height = 256,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_QVGA_30fps,
-	},
-	{
-		.width = 352,
-		.height = 288,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_CIF_30fps,
-	},
-	{
-		.width = 176,
-		.height = 144,
-		.fps = 60,
-		.pix_clk_freq = 66,
-		.pixels_per_line = 1698,//1704,
-		.lines_per_frame = 1294,
-		.skip_frames = 3,
-		.regs = ov2680_QCIF_30fps,
-	},
-};
-
-#define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview))
-
 #endif
-- 
2.39.0


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

* [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (39 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:46   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h Hans de Goede
                   ` (16 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

3 fixes for the framesize list:

1. Drop modes < 640x480, these are made by significant cropping,
   leading to such a small remainig field-of-view that they are
   not really usable

2. 1616x1082 is presumably intended to be 1600x1080 + 16 pixels
   padding in both dimensions, but the height is wrong.
   Change this to 1616x1096.

3. The 800x600 mode is missing the 16 pixels padding and
   720x592 is missing 16 pixels padding in its width and
   the 720x576 base mode is a mode with non square pixels,
   while the sensor has square pixels.
   Replace both with 768x576 + 16 pixels padding -> 784x592

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 432539dd274c..81fd36b09090 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -700,17 +700,13 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
 {
 	static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = {
 		{ 1616, 1216 },
-		{ 1616, 1082 },
+		{ 1616, 1096 },
 		{ 1616,  916 },
 		{ 1456, 1096 },
 		{ 1296,  976 },
 		{ 1296,  736 },
-		{  800,  600 },
-		{  720,  592 },
+		{  784,  592 },
 		{  656,  496 },
-		{  336,  256 },
-		{  352,  288 },
-		{  176,  144 },
 	};
 	int index = fse->index;
 
-- 
2.39.0


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

* [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (40 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:46   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define Hans de Goede
                   ` (15 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Remove a bunch of unused data-types and defines from ov2680.h.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/ov2680.h | 60 ----------------------
 1 file changed, 60 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 20ef59928cb1..189d1b2b7584 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -46,45 +46,11 @@
 
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
 
-#define OV2680_BIN_FACTOR_MAX 4
-
 #define MAX_FMTS		1
 
-/* sensor_mode_data read_mode adaptation */
-#define OV2680_READ_MODE_BINNING_ON	0x0400
-#define OV2680_READ_MODE_BINNING_OFF	0x00
 #define OV2680_INTEGRATION_TIME_MARGIN	8
-
-#define OV2680_MAX_EXPOSURE_VALUE	0xFFF1
-#define OV2680_MAX_GAIN_VALUE		0xFF
-
-/*
- * focal length bits definition:
- * bits 31-16: numerator, bits 15-0: denominator
- */
-#define OV2680_FOCAL_LENGTH_DEFAULT 0x1B70064
-
-/*
- * current f-number bits definition:
- * bits 31-16: numerator, bits 15-0: denominator
- */
-#define OV2680_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 OV2680_F_NUMBER_RANGE 0x180a180a
 #define OV2680_ID	0x2680
 
-#define OV2680_FINE_INTG_TIME_MIN 0
-#define OV2680_FINE_INTG_TIME_MAX_MARGIN 0
-#define OV2680_COARSE_INTG_TIME_MIN 1
-#define OV2680_COARSE_INTG_TIME_MAX_MARGIN 6
-
 /*
  * OV2680 System control registers
  */
@@ -147,19 +113,6 @@
 #define OV2680_START_STREAMING			0x01
 #define OV2680_STOP_STREAMING			0x00
 
-#define OV2680_INVALID_CONFIG	0xffffffff
-
-struct regval_list {
-	u16 reg_num;
-	u8 value;
-};
-
-struct ov2680_format {
-	u8 *desc;
-	u32 pixelformat;
-	struct ov2680_reg *regs;
-};
-
 /*
  * ov2680 device structure.
  */
@@ -216,18 +169,6 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
 			     ctrls.handler)->sd;
 }
 
-#define OV2680_MAX_WRITE_BUF_SIZE	30
-
-struct ov2680_write_buffer {
-	u16 addr;
-	u8 data[OV2680_MAX_WRITE_BUF_SIZE];
-};
-
-struct ov2680_write_ctrl {
-	int index;
-	struct ov2680_write_buffer buffer;
-};
-
 static struct ov2680_reg const ov2680_global_setting[] = {
 	{0x0103, 0x01},
 	{0x3002, 0x00},
@@ -304,7 +245,6 @@ static struct ov2680_reg const ov2680_global_setting[] = {
 	{0x5793, 0x00},
 	{0x5794, 0x03}, //based OV2680_R1A_AM10.ovt,Adjust DPC setting (57xx) on 14/06/13
 	{0x0100, 0x00},	//stream off
-
 	{}
 };
 
-- 
2.39.0


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

* [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (41 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:48   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values Hans de Goede
                   ` (14 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The ov2680 only supports a single format, there is no need to
use a define for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 2 +-
 drivers/staging/media/atomisp/i2c/ov2680.h         | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 81fd36b09090..994b6fe40069 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -687,7 +687,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_state *sd_state,
 				 struct v4l2_subdev_mbus_code_enum *code)
 {
-	if (code->index >= MAX_FMTS)
+	if (code->index)
 		return -EINVAL;
 
 	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 189d1b2b7584..5aa46f669715 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -46,8 +46,6 @@
 
 #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
 
-#define MAX_FMTS		1
-
 #define OV2680_INTEGRATION_TIME_MARGIN	8
 #define OV2680_ID	0x2680
 
-- 
2.39.0


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

* [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (42 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:49   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 45/57] media: atomisp: ov2680: Cleanup includes Hans de Goede
                   ` (13 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Use the same indentation level for all #define values.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/ov2680.h | 36 +++++++++++-----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 5aa46f669715..f0641dd611c3 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -44,10 +44,10 @@
 /* If possible send 16 extra rows / lines to the ISP as padding */
 #define OV2680_END_MARGIN			16
 
-#define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
+#define OV2680_FOCAL_LENGTH_NUM			334	/*3.34mm*/
 
-#define OV2680_INTEGRATION_TIME_MARGIN	8
-#define OV2680_ID	0x2680
+#define OV2680_INTEGRATION_TIME_MARGIN		8
+#define OV2680_ID				0x2680
 
 /*
  * OV2680 System control registers
@@ -61,23 +61,23 @@
 #define OV2680_SC_CMMN_SCCB_ID			0x302B /* 0x300C*/
 #define OV2680_SC_CMMN_SUB_ID			0x302A /* process, version*/
 
-#define OV2680_GROUP_ACCESS							0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
+#define OV2680_GROUP_ACCESS			0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
 
 #define OV2680_REG_EXPOSURE_PK_HIGH		0x3500
 #define OV2680_REG_GAIN_PK			0x350a
 
-#define OV2680_HORIZONTAL_START_H					0x3800 /*Bit[11:8]*/
-#define OV2680_HORIZONTAL_START_L					0x3801 /*Bit[7:0]*/
-#define OV2680_VERTICAL_START_H						0x3802 /*Bit[11:8]*/
-#define OV2680_VERTICAL_START_L						0x3803 /*Bit[7:0]*/
-#define OV2680_HORIZONTAL_END_H						0x3804 /*Bit[11:8]*/
-#define OV2680_HORIZONTAL_END_L						0x3805 /*Bit[7:0]*/
-#define OV2680_VERTICAL_END_H						0x3806 /*Bit[11:8]*/
-#define OV2680_VERTICAL_END_L						0x3807 /*Bit[7:0]*/
-#define OV2680_HORIZONTAL_OUTPUT_SIZE_H				0x3808 /*Bit[3:0]*/
-#define OV2680_HORIZONTAL_OUTPUT_SIZE_L				0x3809 /*Bit[7:0]*/
-#define OV2680_VERTICAL_OUTPUT_SIZE_H				0x380a /*Bit[3:0]*/
-#define OV2680_VERTICAL_OUTPUT_SIZE_L				0x380b /*Bit[7:0]*/
+#define OV2680_HORIZONTAL_START_H		0x3800 /*Bit[11:8]*/
+#define OV2680_HORIZONTAL_START_L		0x3801 /*Bit[7:0]*/
+#define OV2680_VERTICAL_START_H			0x3802 /*Bit[11:8]*/
+#define OV2680_VERTICAL_START_L			0x3803 /*Bit[7:0]*/
+#define OV2680_HORIZONTAL_END_H			0x3804 /*Bit[11:8]*/
+#define OV2680_HORIZONTAL_END_L			0x3805 /*Bit[7:0]*/
+#define OV2680_VERTICAL_END_H			0x3806 /*Bit[11:8]*/
+#define OV2680_VERTICAL_END_L			0x3807 /*Bit[7:0]*/
+#define OV2680_HORIZONTAL_OUTPUT_SIZE_H		0x3808 /*Bit[3:0]*/
+#define OV2680_HORIZONTAL_OUTPUT_SIZE_L		0x3809 /*Bit[7:0]*/
+#define OV2680_VERTICAL_OUTPUT_SIZE_H		0x380a /*Bit[3:0]*/
+#define OV2680_VERTICAL_OUTPUT_SIZE_L		0x380b /*Bit[7:0]*/
 #define OV2680_HTS_H				0x380c
 #define OV2680_HTS_L				0x380d
 #define OV2680_VTS_H				0x380e
@@ -89,7 +89,7 @@
 #define OV2680_X_INC				0x3814
 #define OV2680_Y_INC				0x3815
 
-#define OV2680_FRAME_OFF_NUM						0x4202
+#define OV2680_FRAME_OFF_NUM			0x4202
 
 /*Flip/Mirror*/
 #define OV2680_REG_FORMAT1			0x3820
@@ -98,7 +98,7 @@
 #define OV2680_MWB_RED_GAIN_H			0x5004/*0x3400*/
 #define OV2680_MWB_GREEN_GAIN_H			0x5006/*0x3402*/
 #define OV2680_MWB_BLUE_GAIN_H			0x5008/*0x3404*/
-#define OV2680_MWB_GAIN_MAX				0x0fff
+#define OV2680_MWB_GAIN_MAX			0x0fff
 
 #define OV2680_REG_ISP_CTRL00			0x5080
 
-- 
2.39.0


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

* [PATCH 45/57] media: atomisp: ov2680: Cleanup includes
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (43 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:50   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started Hans de Goede
                   ` (12 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Remove unused includes and sort the remaining ones alphabetically.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 994b6fe40069..1dc821ca4e68 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -15,27 +15,14 @@
  *
  */
 
-#include <asm/unaligned.h>
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kmod.h>
+#include <linux/acpi.h>
 #include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/i2c.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
+#include <linux/types.h>
 #include <media/ovxxxx_16bit_addr_reg_helpers.h>
 #include <media/v4l2-device.h>
-#include <linux/io.h>
-#include <linux/acpi.h>
 #include "../include/linux/atomisp_gmin_platform.h"
-
 #include "ov2680.h"
 
 static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = {
-- 
2.39.0


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

* [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (44 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 45/57] media: atomisp: ov2680: Cleanup includes Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:51   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support Hans de Goede
                   ` (11 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Move the setting of the mode to stream on, this also allows
delaying power-on till streaming is started.

And drop the deprecated s_power callback since this now no long
is necessary.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 101 +++++++-----------
 1 file changed, 41 insertions(+), 60 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 1dc821ca4e68..2a8c4508cc66 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -327,24 +327,6 @@ static int power_down(struct v4l2_subdev *sd)
 	return 0;
 }
 
-static int ov2680_s_power(struct v4l2_subdev *sd, int on)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	int ret;
-
-	mutex_lock(&dev->input_lock);
-
-	if (on == 0) {
-		ret = power_down(sd);
-	} else {
-		ret = power_up(sd);
-	}
-
-	mutex_unlock(&dev->input_lock);
-
-	return ret;
-}
-
 static struct v4l2_mbus_framefmt *
 __ov2680_get_pad_format(struct ov2680_device *sensor,
 			struct v4l2_subdev_state *state,
@@ -393,14 +375,12 @@ static void ov2680_calc_mode(struct ov2680_device *sensor, int width, int height
 	sensor->mode.vts = OV2680_LINES_PER_FRAME;
 }
 
-static int ov2680_set_mode(struct ov2680_device *sensor, int width, int height)
+static int ov2680_set_mode(struct ov2680_device *sensor)
 {
 	struct i2c_client *client = sensor->client;
 	u8 pll_div, unknown, inc, fmt1, fmt2;
 	int ret;
 
-	ov2680_calc_mode(sensor, width, height);
-
 	if (sensor->mode.binning) {
 		pll_div = 1;
 		unknown = 0x23;
@@ -500,7 +480,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *fmt;
 	unsigned int width, height;
-	int ret = 0;
 
 	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
 		__func__,
@@ -518,23 +497,10 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
 		return 0;
 
-	dev_dbg(&client->dev, "%s: %dx%d\n",
-		__func__, fmt->width, fmt->height);
-
 	mutex_lock(&dev->input_lock);
-
-	/* s_power has not been called yet for std v4l2 clients (camorama) */
-	power_up(sd);
-
-	ret = ov2680_set_mode(dev, fmt->width, fmt->height);
-	if (ret < 0)
-		goto err;
-
-	/* Restore value of all ctrls */
-	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
-err:
+	ov2680_calc_mode(dev, fmt->width, fmt->height);
 	mutex_unlock(&dev->input_lock);
-	return ret;
+	return 0;
 }
 
 static int ov2680_get_fmt(struct v4l2_subdev *sd,
@@ -584,30 +550,50 @@ static int ov2680_detect(struct i2c_client *client)
 
 static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int ret;
+	int ret = 0;
 
-	mutex_lock(&dev->input_lock);
-	if (enable)
-		dev_dbg(&client->dev, "ov2680_s_stream one\n");
-	else
-		dev_dbg(&client->dev, "ov2680_s_stream off\n");
-
-	ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM,
-				enable ? OV2680_START_STREAMING : OV2680_STOP_STREAMING);
-	if (ret == 0) {
-		dev->is_streaming = enable;
-		v4l2_ctrl_activate(dev->ctrls.vflip, !enable);
-		v4l2_ctrl_activate(dev->ctrls.hflip, !enable);
+	mutex_lock(&sensor->input_lock);
+
+	if (sensor->is_streaming == enable) {
+		dev_warn(&client->dev, "stream already %sed\n", enable ? "start" : "stopp");
+		goto error_unlock;
 	}
 
-	//otp valid at stream on state
-	//if(!dev->otp_data)
-	//	dev->otp_data = ov2680_otp_read(sd);
+	if (enable) {
+		ret = power_up(sd);
+		if (ret)
+			goto error_unlock;
 
-	mutex_unlock(&dev->input_lock);
+		ret = ov2680_set_mode(sensor);
+		if (ret)
+			goto error_power_down;
 
+		/* Restore value of all ctrls */
+		ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+		if (ret)
+			goto error_power_down;
+
+		ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_START_STREAMING);
+		if (ret)
+			goto error_power_down;
+	} else {
+		ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING);
+		power_down(sd);
+	}
+
+	sensor->is_streaming = enable;
+	v4l2_ctrl_activate(sensor->ctrls.vflip, !enable);
+	v4l2_ctrl_activate(sensor->ctrls.hflip, !enable);
+
+	mutex_unlock(&sensor->input_lock);
+	return 0;
+
+error_power_down:
+	power_down(sd);
+error_unlock:
+	mutex_unlock(&sensor->input_lock);
 	return ret;
 }
 
@@ -736,10 +722,6 @@ static const struct v4l2_subdev_sensor_ops ov2680_sensor_ops = {
 	.g_skip_frames	= ov2680_g_skip_frames,
 };
 
-static const struct v4l2_subdev_core_ops ov2680_core_ops = {
-	.s_power = ov2680_s_power,
-};
-
 static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
 	.enum_mbus_code = ov2680_enum_mbus_code,
 	.enum_frame_size = ov2680_enum_frame_size,
@@ -749,7 +731,6 @@ static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
 };
 
 static const struct v4l2_subdev_ops ov2680_ops = {
-	.core = &ov2680_core_ops,
 	.video = &ov2680_video_ops,
 	.pad = &ov2680_pad_ops,
 	.sensor = &ov2680_sensor_ops,
-- 
2.39.0


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

* [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (45 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:53   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/ Hans de Goede
                   ` (10 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Add runtime-pm support. This is a preparation patch for letting
ACPI deal with the regulators and clocks instead of the DIY code
in atomisp_gmin_platform.c.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 57 ++++++++++++-------
 drivers/staging/media/atomisp/i2c/ov2680.h    |  1 -
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 2a8c4508cc66..881340d7466f 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -19,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 #include <linux/types.h>
 #include <media/ovxxxx_16bit_addr_reg_helpers.h>
 #include <media/v4l2-device.h>
@@ -138,7 +139,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	int ret;
 
-	if (!sensor->power_on) {
+	/* Only apply changes to the controls if the device is powered up */
+	if (!pm_runtime_get_if_in_use(sensor->sd.dev)) {
 		ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
 		return 0;
 	}
@@ -162,6 +164,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
 	default:
 		ret = -EINVAL;
 	}
+
+	pm_runtime_put(sensor->sd.dev);
 	return ret;
 }
 
@@ -244,9 +248,6 @@ static int power_up(struct v4l2_subdev *sd)
 		return -ENODEV;
 	}
 
-	if (dev->power_on)
-		return 0; /* Already on */
-
 	/* power control */
 	ret = power_ctrl(sd, 1);
 	if (ret)
@@ -275,7 +276,6 @@ static int power_up(struct v4l2_subdev *sd)
 	if (ret)
 		goto fail_init_registers;
 
-	dev->power_on = true;
 	return 0;
 
 fail_init_registers:
@@ -301,9 +301,6 @@ static int power_down(struct v4l2_subdev *sd)
 		return -ENODEV;
 	}
 
-	if (!dev->power_on)
-		return 0; /* Already off */
-
 	ret = dev->platform_data->flisclk_ctrl(sd, 0);
 	if (ret)
 		dev_err(&client->dev, "flisclk failed\n");
@@ -323,7 +320,6 @@ static int power_down(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	dev->power_on = false;
 	return 0;
 }
 
@@ -562,8 +558,8 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 	}
 
 	if (enable) {
-		ret = power_up(sd);
-		if (ret)
+		ret = pm_runtime_get_sync(sensor->sd.dev);
+		if (ret < 0)
 			goto error_unlock;
 
 		ret = ov2680_set_mode(sensor);
@@ -580,7 +576,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 			goto error_power_down;
 	} else {
 		ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING);
-		power_down(sd);
+		pm_runtime_put(sensor->sd.dev);
 	}
 
 	sensor->is_streaming = enable;
@@ -591,7 +587,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 	return 0;
 
 error_power_down:
-	power_down(sd);
+	pm_runtime_put(sensor->sd.dev);
 error_unlock:
 	mutex_unlock(&sensor->input_lock);
 	return ret;
@@ -612,8 +608,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 
 	mutex_lock(&dev->input_lock);
 
-	ret = power_up(sd);
-	if (ret) {
+	ret = pm_runtime_get_sync(&client->dev);
+	if (ret < 0) {
 		dev_err(&client->dev, "ov2680 power-up err.\n");
 		goto fail_power_on;
 	}
@@ -630,11 +626,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 	}
 
 	/* turn off sensor, after probed */
-	ret = power_down(sd);
-	if (ret) {
-		dev_err(&client->dev, "ov2680 power-off err.\n");
-		goto fail_csi_cfg;
-	}
+	pm_runtime_put(&client->dev);
 	mutex_unlock(&dev->input_lock);
 
 	return 0;
@@ -642,7 +634,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 fail_csi_cfg:
 	dev->platform_data->csi_cfg(sd, 0);
 fail_power_on:
-	power_down(sd);
+	pm_runtime_put(&client->dev);
 	dev_err(&client->dev, "sensor power-gating failed\n");
 	mutex_unlock(&dev->input_lock);
 	return ret;
@@ -787,6 +779,7 @@ static void ov2680_remove(struct i2c_client *client)
 	v4l2_device_unregister_subdev(sd);
 	media_entity_cleanup(&dev->sd.entity);
 	v4l2_ctrl_handler_free(&dev->ctrls.handler);
+	pm_runtime_disable(&client->dev);
 	kfree(dev);
 }
 
@@ -813,6 +806,11 @@ static int ov2680_probe(struct i2c_client *client)
 		goto out_free;
 	}
 
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
+	pm_runtime_use_autosuspend(&client->dev);
+
 	ret = ov2680_s_config(&dev->sd, client->irq, pdata);
 	if (ret)
 		goto out_free;
@@ -849,6 +847,22 @@ static int ov2680_probe(struct i2c_client *client)
 	return ret;
 }
 
+static int ov2680_suspend(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+
+	return power_down(sd);
+}
+
+static int ov2680_resume(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+
+	return power_up(sd);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL);
+
 static const struct acpi_device_id ov2680_acpi_match[] = {
 	{"XXOV2680"},
 	{"OVTI2680"},
@@ -859,6 +873,7 @@ MODULE_DEVICE_TABLE(acpi, ov2680_acpi_match);
 static struct i2c_driver ov2680_driver = {
 	.driver = {
 		.name = "ov2680",
+		.pm = pm_sleep_ptr(&ov2680_pm_ops),
 		.acpi_match_table = ov2680_acpi_match,
 	},
 	.probe_new = ov2680_probe,
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index f0641dd611c3..58593da50f6f 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -120,7 +120,6 @@ struct ov2680_device {
 	struct mutex input_lock;
 	struct i2c_client *client;
 	struct camera_sensor_platform_data *platform_data;
-	bool power_on;
 	bool is_streaming;
 
 	struct ov2680_mode {
-- 
2.39.0


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

* [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (46 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:54   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct Hans de Goede
                   ` (9 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Using dev as name for variables pointing to struct ov2680_device is a bit
unfortunate choice.

All the recently added / rewritten code is already using sensor for this,
replace the remaining usages of "struct ov2680_device *dev" with
"struct ov2680_device *sensor".

Note the power_up()/power_down() related functions are not changed as
these will be removed in one of the next patches.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 74 +++++++++----------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 881340d7466f..5f26508a1e5a 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -472,7 +472,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *fmt;
 	unsigned int width, height;
@@ -485,17 +485,17 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	width = min_t(unsigned int, ALIGN(format->format.width, 2), OV2680_NATIVE_WIDTH);
 	height = min_t(unsigned int, ALIGN(format->format.height, 2), OV2680_NATIVE_HEIGHT);
 
-	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
-	ov2680_fill_format(dev, fmt, width, height);
+	fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which);
+	ov2680_fill_format(sensor, fmt, width, height);
 
 	format->format = *fmt;
 
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
 		return 0;
 
-	mutex_lock(&dev->input_lock);
-	ov2680_calc_mode(dev, fmt->width, fmt->height);
-	mutex_unlock(&dev->input_lock);
+	mutex_lock(&sensor->input_lock);
+	ov2680_calc_mode(sensor, fmt->width, fmt->height);
+	mutex_unlock(&sensor->input_lock);
 	return 0;
 }
 
@@ -503,10 +503,10 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	struct v4l2_mbus_framefmt *fmt;
 
-	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
+	fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which);
 	format->format = *fmt;
 	return 0;
 }
@@ -596,17 +596,17 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 static int ov2680_s_config(struct v4l2_subdev *sd,
 			   int irq, void *platform_data)
 {
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret = 0;
 
 	if (!platform_data)
 		return -ENODEV;
 
-	dev->platform_data =
+	sensor->platform_data =
 	    (struct camera_sensor_platform_data *)platform_data;
 
-	mutex_lock(&dev->input_lock);
+	mutex_lock(&sensor->input_lock);
 
 	ret = pm_runtime_get_sync(&client->dev);
 	if (ret < 0) {
@@ -614,7 +614,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 		goto fail_power_on;
 	}
 
-	ret = dev->platform_data->csi_cfg(sd, 1);
+	ret = sensor->platform_data->csi_cfg(sd, 1);
 	if (ret)
 		goto fail_csi_cfg;
 
@@ -627,16 +627,16 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 
 	/* turn off sensor, after probed */
 	pm_runtime_put(&client->dev);
-	mutex_unlock(&dev->input_lock);
+	mutex_unlock(&sensor->input_lock);
 
 	return 0;
 
 fail_csi_cfg:
-	dev->platform_data->csi_cfg(sd, 0);
+	sensor->platform_data->csi_cfg(sd, 0);
 fail_power_on:
 	pm_runtime_put(&client->dev);
 	dev_err(&client->dev, "sensor power-gating failed\n");
-	mutex_unlock(&dev->input_lock);
+	mutex_unlock(&sensor->input_lock);
 	return ret;
 }
 
@@ -770,35 +770,35 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
 static void ov2680_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 
 	dev_dbg(&client->dev, "ov2680_remove...\n");
 
-	dev->platform_data->csi_cfg(sd, 0);
+	sensor->platform_data->csi_cfg(sd, 0);
 
 	v4l2_device_unregister_subdev(sd);
-	media_entity_cleanup(&dev->sd.entity);
-	v4l2_ctrl_handler_free(&dev->ctrls.handler);
+	media_entity_cleanup(&sensor->sd.entity);
+	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 	pm_runtime_disable(&client->dev);
-	kfree(dev);
+	kfree(sensor);
 }
 
 static int ov2680_probe(struct i2c_client *client)
 {
-	struct ov2680_device *dev;
+	struct ov2680_device *sensor;
 	int ret;
 	void *pdata;
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev)
+	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+	if (!sensor)
 		return -ENOMEM;
 
-	mutex_init(&dev->input_lock);
+	mutex_init(&sensor->input_lock);
 
-	dev->client = client;
-	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
+	sensor->client = client;
+	v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops);
 
-	pdata = gmin_camera_platform_data(&dev->sd,
+	pdata = gmin_camera_platform_data(&sensor->sd,
 					  ATOMISP_INPUT_FORMAT_RAW_10,
 					  atomisp_bayer_order_bggr);
 	if (!pdata) {
@@ -811,29 +811,29 @@ static int ov2680_probe(struct i2c_client *client)
 	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
 	pm_runtime_use_autosuspend(&client->dev);
 
-	ret = ov2680_s_config(&dev->sd, client->irq, pdata);
+	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
 	if (ret)
 		goto out_free;
 
-	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
-	dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
 
-	ret = ov2680_init_controls(dev);
+	ret = ov2680_init_controls(sensor);
 	if (ret) {
 		ov2680_remove(client);
 		return ret;
 	}
 
-	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
+	ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
 	if (ret) {
 		ov2680_remove(client);
 		return ret;
 	}
 
-	ov2680_fill_format(dev, &dev->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
+	ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
 
-	ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
+	ret = atomisp_register_i2c_module(&sensor->sd, pdata, RAW_CAMERA);
 	if (ret) {
 		ov2680_remove(client);
 		return ret;
@@ -842,8 +842,8 @@ static int ov2680_probe(struct i2c_client *client)
 	return 0;
 out_free:
 	dev_dbg(&client->dev, "+++ out free\n");
-	v4l2_device_unregister_subdev(&dev->sd);
-	kfree(dev);
+	v4l2_device_unregister_subdev(&sensor->sd);
+	kfree(sensor);
 	return ret;
 }
 
-- 
2.39.0


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

* [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (47 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/ Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:55   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement Hans de Goede
                   ` (8 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Use devm_kzalloc() to allocate the sensor data struct. It is always free-ed
as the last step of probe-error-exit or remove, so it can be devm-managed.

This will make unwinding things easier when support is added to the ov2680
code to use standard GPIO APIs instead of the custom atomisp_gmin code.

This also allows dropping the out_free label and use direct return
on errors.

This may seem like a functional change since the out_free label also
did a v4l2_device_unregister_subdev() but at the 2 changed returns
the device is not registered yet, so that always is a no-op and can
be dropped.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/i2c/atomisp-ov2680.c   | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 5f26508a1e5a..2b4673092b6a 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -780,7 +780,6 @@ static void ov2680_remove(struct i2c_client *client)
 	media_entity_cleanup(&sensor->sd.entity);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 	pm_runtime_disable(&client->dev);
-	kfree(sensor);
 }
 
 static int ov2680_probe(struct i2c_client *client)
@@ -789,7 +788,7 @@ static int ov2680_probe(struct i2c_client *client)
 	int ret;
 	void *pdata;
 
-	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
 	if (!sensor)
 		return -ENOMEM;
 
@@ -801,10 +800,8 @@ static int ov2680_probe(struct i2c_client *client)
 	pdata = gmin_camera_platform_data(&sensor->sd,
 					  ATOMISP_INPUT_FORMAT_RAW_10,
 					  atomisp_bayer_order_bggr);
-	if (!pdata) {
-		ret = -EINVAL;
-		goto out_free;
-	}
+	if (!pdata)
+		return -EINVAL;
 
 	pm_runtime_set_suspended(&client->dev);
 	pm_runtime_enable(&client->dev);
@@ -813,7 +810,7 @@ static int ov2680_probe(struct i2c_client *client)
 
 	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
 	if (ret)
-		goto out_free;
+		return ret;
 
 	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
@@ -840,11 +837,6 @@ static int ov2680_probe(struct i2c_client *client)
 	}
 
 	return 0;
-out_free:
-	dev_dbg(&client->dev, "+++ out free\n");
-	v4l2_device_unregister_subdev(&sensor->sd);
-	kfree(sensor);
-	return ret;
 }
 
 static int ov2680_suspend(struct device *dev)
-- 
2.39.0


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

* [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (48 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-24 10:59   ` Andy Shevchenko
  2023-01-23 12:51 ` [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure Hans de Goede
                   ` (7 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The DSDT of all Windows BYT / CHT devices which I have seen has proper
ACPI powermagement for the clk and regulators used by the sensors.

So there is no need for the whole custom atomisp_gmin custom code to
disable the ACPI pm and directly poke at the PMIC for this.

Replace all the atomisp_gmin usage with using the new
atomisp_register_sensor_no_gmin() / atomisp_unregister_subdev()
helpers which allow registering a sensor with the atomisp code
without using any of the atomisp_gmin power-management code.

Note eventually these calls should be replaced by the standard
v4l2_async_register_subdev_sensor() mechanism.

But this first requires a bunch of work to the atomisp main code
to make it set the necessary fwnodes up, similar to how
drivers/media/pci/intel/ipu3/cio2-bridge.c does this.

This has been tested on:
-Trekstor Surftab duo W1 10.1, CHT, AXP288 PMIC, 2x ov2680 sensor
-Asus T101HA, CHT, TI PMIC, 1x ov2680 sensor
-MPMAN Converter 9, BYT, AXP288 PMIC, ov2680 back, gc0310 front sensor

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../media/atomisp/i2c/atomisp-ov2680.c        | 231 ++++--------------
 drivers/staging/media/atomisp/i2c/ov2680.h    |   3 +-
 2 files changed, 53 insertions(+), 181 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 2b4673092b6a..c5bd7ba1b502 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -17,6 +17,8 @@
 
 #include <linux/acpi.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
@@ -184,145 +186,6 @@ static int ov2680_init_registers(struct v4l2_subdev *sd)
 	return ret;
 }
 
-static int power_ctrl(struct v4l2_subdev *sd, bool flag)
-{
-	int ret = 0;
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!dev || !dev->platform_data)
-		return -ENODEV;
-
-	dev_dbg(&client->dev, "%s: %s", __func__, flag ? "on" : "off");
-
-	if (flag) {
-		ret |= dev->platform_data->v1p8_ctrl(sd, 1);
-		ret |= dev->platform_data->v2p8_ctrl(sd, 1);
-		usleep_range(10000, 15000);
-	}
-
-	if (!flag || ret) {
-		ret |= dev->platform_data->v1p8_ctrl(sd, 0);
-		ret |= dev->platform_data->v2p8_ctrl(sd, 0);
-	}
-	return ret;
-}
-
-static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
-{
-	int ret;
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-
-	if (!dev || !dev->platform_data)
-		return -ENODEV;
-
-	/*
-	 * The OV2680 documents only one GPIO input (#XSHUTDN), but
-	 * existing integrations often wire two (reset/power_down)
-	 * because that is the way other sensors work.  There is no
-	 * way to tell how it is wired internally, so existing
-	 * firmwares expose both and we drive them symmetrically.
-	 */
-	if (flag) {
-		ret = dev->platform_data->gpio0_ctrl(sd, 1);
-		usleep_range(10000, 15000);
-		/* Ignore return from second gpio, it may not be there */
-		dev->platform_data->gpio1_ctrl(sd, 1);
-		usleep_range(10000, 15000);
-	} else {
-		dev->platform_data->gpio1_ctrl(sd, 0);
-		ret = dev->platform_data->gpio0_ctrl(sd, 0);
-	}
-	return ret;
-}
-
-static int power_up(struct v4l2_subdev *sd)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int ret;
-
-	if (!dev->platform_data) {
-		dev_err(&client->dev,
-			"no camera_sensor_platform_data");
-		return -ENODEV;
-	}
-
-	/* power control */
-	ret = power_ctrl(sd, 1);
-	if (ret)
-		goto fail_power;
-
-	/* according to DS, at least 5ms is needed between DOVDD and PWDN */
-	usleep_range(5000, 6000);
-
-	/* gpio ctrl */
-	ret = gpio_ctrl(sd, 1);
-	if (ret) {
-		ret = gpio_ctrl(sd, 1);
-		if (ret)
-			goto fail_power;
-	}
-
-	/* flis clock control */
-	ret = dev->platform_data->flisclk_ctrl(sd, 1);
-	if (ret)
-		goto fail_clk;
-
-	/* according to DS, 20ms is needed between PWDN and i2c access */
-	msleep(20);
-
-	ret = ov2680_init_registers(sd);
-	if (ret)
-		goto fail_init_registers;
-
-	return 0;
-
-fail_init_registers:
-	dev->platform_data->flisclk_ctrl(sd, 0);
-fail_clk:
-	gpio_ctrl(sd, 0);
-fail_power:
-	power_ctrl(sd, 0);
-	dev_err(&client->dev, "sensor power-up failed\n");
-
-	return ret;
-}
-
-static int power_down(struct v4l2_subdev *sd)
-{
-	struct ov2680_device *dev = to_ov2680_sensor(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int ret = 0;
-
-	if (!dev->platform_data) {
-		dev_err(&client->dev,
-			"no camera_sensor_platform_data");
-		return -ENODEV;
-	}
-
-	ret = dev->platform_data->flisclk_ctrl(sd, 0);
-	if (ret)
-		dev_err(&client->dev, "flisclk failed\n");
-
-	/* gpio ctrl */
-	ret = gpio_ctrl(sd, 0);
-	if (ret) {
-		ret = gpio_ctrl(sd, 0);
-		if (ret)
-			dev_err(&client->dev, "gpio failed 2\n");
-	}
-
-	/* power control */
-	ret = power_ctrl(sd, 0);
-	if (ret) {
-		dev_err(&client->dev, "vprog failed.\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 static struct v4l2_mbus_framefmt *
 __ov2680_get_pad_format(struct ov2680_device *sensor,
 			struct v4l2_subdev_state *state,
@@ -593,20 +456,10 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
 	return ret;
 }
 
-static int ov2680_s_config(struct v4l2_subdev *sd,
-			   int irq, void *platform_data)
+static int ov2680_s_config(struct v4l2_subdev *sd)
 {
-	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int ret = 0;
-
-	if (!platform_data)
-		return -ENODEV;
-
-	sensor->platform_data =
-	    (struct camera_sensor_platform_data *)platform_data;
-
-	mutex_lock(&sensor->input_lock);
+	int ret;
 
 	ret = pm_runtime_get_sync(&client->dev);
 	if (ret < 0) {
@@ -614,29 +467,13 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
 		goto fail_power_on;
 	}
 
-	ret = sensor->platform_data->csi_cfg(sd, 1);
-	if (ret)
-		goto fail_csi_cfg;
-
 	/* config & detect sensor */
 	ret = ov2680_detect(client);
-	if (ret) {
+	if (ret)
 		dev_err(&client->dev, "ov2680_detect err s_config.\n");
-		goto fail_csi_cfg;
-	}
 
-	/* turn off sensor, after probed */
-	pm_runtime_put(&client->dev);
-	mutex_unlock(&sensor->input_lock);
-
-	return 0;
-
-fail_csi_cfg:
-	sensor->platform_data->csi_cfg(sd, 0);
 fail_power_on:
 	pm_runtime_put(&client->dev);
-	dev_err(&client->dev, "sensor power-gating failed\n");
-	mutex_unlock(&sensor->input_lock);
 	return ret;
 }
 
@@ -774,19 +611,32 @@ static void ov2680_remove(struct i2c_client *client)
 
 	dev_dbg(&client->dev, "ov2680_remove...\n");
 
-	sensor->platform_data->csi_cfg(sd, 0);
-
+	atomisp_unregister_subdev(sd);
 	v4l2_device_unregister_subdev(sd);
 	media_entity_cleanup(&sensor->sd.entity);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 	pm_runtime_disable(&client->dev);
 }
 
+/*
+ * Unlike other sensors which have both a rest and powerdown input pins,
+ * the OV2680 only has a powerdown input. But some ACPI tables still list
+ * 2 GPIOs for the OV2680 and it is unclear which to use. So try to get
+ * up to 2 GPIOs (1 mandatory, 1 optional) and control them in sync.
+ */
+static const struct acpi_gpio_params ov2680_first_gpio = { 0, 0, true };
+static const struct acpi_gpio_params ov2680_second_gpio = { 1, 0, true };
+
+static const struct acpi_gpio_mapping ov2680_gpio_mapping[] = {
+	{ "powerdown-gpios", &ov2680_first_gpio, 1 },
+	{ "powerdown-alt-gpios", &ov2680_second_gpio, 1 },
+	{ },
+};
+
 static int ov2680_probe(struct i2c_client *client)
 {
 	struct ov2680_device *sensor;
 	int ret;
-	void *pdata;
 
 	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
 	if (!sensor)
@@ -797,18 +647,24 @@ static int ov2680_probe(struct i2c_client *client)
 	sensor->client = client;
 	v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops);
 
-	pdata = gmin_camera_platform_data(&sensor->sd,
-					  ATOMISP_INPUT_FORMAT_RAW_10,
-					  atomisp_bayer_order_bggr);
-	if (!pdata)
-		return -EINVAL;
+	ret = devm_acpi_dev_add_driver_gpios(&client->dev, ov2680_gpio_mapping);
+	if (ret)
+		return ret;
+
+	sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->powerdown))
+		return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n");
+
+	sensor->powerdown_alt = devm_gpiod_get_optional(&client->dev, "powerdown-alt", GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->powerdown_alt))
+		return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown_alt), "getting powerdown-alt GPIO\n");
 
 	pm_runtime_set_suspended(&client->dev);
 	pm_runtime_enable(&client->dev);
 	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
 	pm_runtime_use_autosuspend(&client->dev);
 
-	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
+	ret = ov2680_s_config(&sensor->sd);
 	if (ret)
 		return ret;
 
@@ -830,7 +686,8 @@ static int ov2680_probe(struct i2c_client *client)
 
 	ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
 
-	ret = atomisp_register_i2c_module(&sensor->sd, pdata, RAW_CAMERA);
+	ret = atomisp_register_sensor_no_gmin(&sensor->sd, 1, ATOMISP_INPUT_FORMAT_RAW_10,
+					      atomisp_bayer_order_bggr);
 	if (ret) {
 		ov2680_remove(client);
 		return ret;
@@ -842,15 +699,29 @@ static int ov2680_probe(struct i2c_client *client)
 static int ov2680_suspend(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 
-	return power_down(sd);
+	gpiod_set_value_cansleep(sensor->powerdown, 1);
+	gpiod_set_value_cansleep(sensor->powerdown_alt, 1);
+	return 0;
 }
 
 static int ov2680_resume(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct ov2680_device *sensor = to_ov2680_sensor(sd);
 
-	return power_up(sd);
+	/* according to DS, at least 5ms is needed after DOVDD (enabled by ACPI) */
+	usleep_range(5000, 6000);
+
+	gpiod_set_value_cansleep(sensor->powerdown, 0);
+	gpiod_set_value_cansleep(sensor->powerdown_alt, 0);
+
+	/* according to DS, 20ms is needed between PWDN and i2c access */
+	msleep(20);
+
+	ov2680_init_registers(sd);
+	return 0;
 }
 
 static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL);
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 58593da50f6f..a2ed5a1edf35 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -119,7 +119,8 @@ struct ov2680_device {
 	struct media_pad pad;
 	struct mutex input_lock;
 	struct i2c_client *client;
-	struct camera_sensor_platform_data *platform_data;
+	struct gpio_desc *powerdown;
+	struct gpio_desc *powerdown_alt;
 	bool is_streaming;
 
 	struct ov2680_mode {
-- 
2.39.0


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

* [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (49 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement Hans de Goede
@ 2023-01-23 12:51 ` Hans de Goede
  2023-01-23 18:36   ` Andy Shevchenko
  2023-01-23 12:52 ` [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity Hans de Goede
                   ` (6 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:51 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Call atomisp_gmin_remove_subdev() on probe failure to properly free
the GPIOs and other resources acquired by the gmin_camera_platform_data()
call earlier.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index d819ab5de28a..d874e12da8cc 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -994,6 +994,7 @@ static int ov2722_probe(struct i2c_client *client)
 	v4l2_ctrl_handler_free(&dev->ctrl_handler);
 
 out_free:
+	atomisp_gmin_remove_subdev(&dev->sd);
 	v4l2_device_unregister_subdev(&dev->sd);
 	kfree(dev);
 	return ret;
-- 
2.39.0


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

* [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (50 preceding siblings ...)
  2023-01-23 12:51 ` [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-23 18:39   ` Andy Shevchenko
  2023-01-23 18:40   ` Andy Shevchenko
  2023-01-23 12:52 ` [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls Hans de Goede
                   ` (5 subsequent siblings)
  57 siblings, 2 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

The comment claims the PWDN pin is active when pulled down in other words,
it is /power-down so it needs to be driven high to get the sensor
powered-up (not powered down) and flag is 1 when powering-up the sensor
so the ! is wrong, drop it.

This also matches with the schematics which I have which shows GPIO1 also
enables a 3.3v line to the sensor-module which controls the privacy-LED
and indeed before this patch the privacy LED was inverted from what it
should be (and the sensor did not work).

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index d874e12da8cc..83d036b5d772 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -512,10 +512,7 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
 	 * before PWDN# when turning it on or off.
 	 */
 	ret = dev->platform_data->gpio0_ctrl(sd, flag);
-	/*
-	 *ov2722 PWDN# active high when pull down,opposite to the convention
-	 */
-	ret |= dev->platform_data->gpio1_ctrl(sd, !flag);
+	ret |= dev->platform_data->gpio1_ctrl(sd, flag);
 	return ret;
 }
 
-- 
2.39.0


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

* [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls.
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (51 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-23 18:39   ` Andy Shevchenko
  2023-01-23 12:52 ` [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback Hans de Goede
                   ` (4 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On ov2722_set_fmt() calls with format->which == V4L2_SUBDEV_FORMAT_TRY,
ov2722_set_fmt() does not talk to the sensor, so there is no need to
lock the dev->input_lock mutex in this case.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 83d036b5d772..e09c80d1f9ec 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -651,7 +651,6 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
 	if (!ov2722_info)
 		return -EINVAL;
 
-	mutex_lock(&dev->input_lock);
 	res = v4l2_find_nearest_size(ov2722_res_preview,
 				     ARRAY_SIZE(ov2722_res_preview), width,
 				     height, fmt->width, fmt->height);
@@ -665,10 +664,10 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
 	fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		sd_state->pads->try_fmt = *fmt;
-		mutex_unlock(&dev->input_lock);
 		return 0;
 	}
 
+	mutex_lock(&dev->input_lock);
 
 	dev->pixels_per_line = dev->res->pixels_per_line;
 	dev->lines_per_frame = dev->res->lines_per_frame;
-- 
2.39.0


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

* [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (52 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-23 18:42   ` Andy Shevchenko
  2023-01-23 12:52 ` [PATCH 55/57] media: atomisp: pci: Replace bytes macros with functions Hans de Goede
                   ` (3 subsequent siblings)
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Depending on which order userspace makes various v4l2 calls, the sensor
might still be powered down when set_fmt is called.

What should really happen here is delay the writing of the mode-related
registers till streaming is started, but for now use the same quick fix
as the atomisp_ov2680 / atomisp_gc0310 code and call power_up() from
set_fmt() in combination with keeping track of the power-state to avoid
doing the power-up sequence twice.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 12 ++++++++++++
 drivers/staging/media/atomisp/i2c/ov2722.h         |  2 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index e09c80d1f9ec..5d2e6e2e72f0 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -528,6 +528,9 @@ static int power_up(struct v4l2_subdev *sd)
 		return -ENODEV;
 	}
 
+	if (dev->power_on == 1)
+		return 0; /* Already on */
+
 	/* power control */
 	ret = power_ctrl(sd, 1);
 	if (ret)
@@ -552,6 +555,7 @@ static int power_up(struct v4l2_subdev *sd)
 	/* according to DS, 20ms is needed between PWDN and i2c access */
 	msleep(20);
 
+	dev->power_on = 1;
 	return 0;
 
 fail_clk:
@@ -575,6 +579,9 @@ static int power_down(struct v4l2_subdev *sd)
 		return -ENODEV;
 	}
 
+	if (dev->power_on == 0)
+		return 0; /* Already off */
+
 	ret = dev->platform_data->flisclk_ctrl(sd, 0);
 	if (ret)
 		dev_err(&client->dev, "flisclk failed\n");
@@ -592,6 +599,7 @@ static int power_down(struct v4l2_subdev *sd)
 	if (ret)
 		dev_err(&client->dev, "vprog failed.\n");
 
+	dev->power_on = 0;
 	return ret;
 }
 
@@ -669,6 +677,9 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
 
 	mutex_lock(&dev->input_lock);
 
+	/* s_power has not been called yet for std v4l2 clients (camorama) */
+	power_up(sd);
+
 	dev->pixels_per_line = dev->res->pixels_per_line;
 	dev->lines_per_frame = dev->res->lines_per_frame;
 
@@ -959,6 +970,7 @@ static int ov2722_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	mutex_init(&dev->input_lock);
+	dev->power_on = -1;
 
 	dev->res = &ov2722_res_preview[0];
 	v4l2_i2c_subdev_init(&dev->sd, client, &ov2722_ops);
diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
index 020743a944c4..640d3ffcaa5c 100644
--- a/drivers/staging/media/atomisp/i2c/ov2722.h
+++ b/drivers/staging/media/atomisp/i2c/ov2722.h
@@ -198,7 +198,7 @@ struct ov2722_device {
 	struct ov2722_resolution *res;
 
 	struct camera_sensor_platform_data *platform_data;
-	int run_mode;
+	int power_on;
 	u16 pixels_per_line;
 	u16 lines_per_frame;
 	u8 type;
-- 
2.39.0


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

* [PATCH 55/57] media: atomisp: pci: Replace bytes macros with functions
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (53 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-23 12:52 ` [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD " Hans de Goede
                   ` (2 subsequent siblings)
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Brent Pappas, Andy Shevchenko

From: Brent Pappas <bpappas@pappasbrent.com>

Replace the function-like macros FPNTBL_BYTES(), SCTBL_BYTES(), and
MORPH_PLANE_BYTES() with functions to comply with Linux coding style
standards.
Replace multiplication with calls to array_size() and array3_size()
to prevent accidental arithmetic overflow.

Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20230118160739.26059-1-bpappas@pappasbrent.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../staging/media/atomisp/pci/sh_css_params.c | 38 +++++++++++--------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
index f08564f58242..588f2adab058 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
+++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
@@ -98,17 +98,27 @@
 #include "sh_css_frac.h"
 #include "ia_css_bufq.h"
 
-#define FPNTBL_BYTES(binary) \
-	(sizeof(char) * (binary)->in_frame_info.res.height * \
-	 (binary)->in_frame_info.padded_width)
+static size_t fpntbl_bytes(const struct ia_css_binary *binary)
+{
+	return array3_size(sizeof(char),
+			   binary->in_frame_info.res.height,
+			   binary->in_frame_info.padded_width);
+}
 
-#define SCTBL_BYTES(binary) \
-	(sizeof(unsigned short) * (binary)->sctbl_height * \
-	 (binary)->sctbl_aligned_width_per_color * IA_CSS_SC_NUM_COLORS)
+static size_t sctbl_bytes(const struct ia_css_binary *binary)
+{
+	return size_mul(sizeof(unsigned short),
+			array3_size(binary->sctbl_height,
+				    binary->sctbl_aligned_width_per_color,
+				    IA_CSS_SC_NUM_COLORS));
+}
 
-#define MORPH_PLANE_BYTES(binary) \
-	(SH_CSS_MORPH_TABLE_ELEM_BYTES * (binary)->morph_tbl_aligned_width * \
-	 (binary)->morph_tbl_height)
+static size_t morph_plane_bytes(const struct ia_css_binary *binary)
+{
+	return array3_size(SH_CSS_MORPH_TABLE_ELEM_BYTES,
+			   binary->morph_tbl_aligned_width,
+			   binary->morph_tbl_height);
+}
 
 /* We keep a second copy of the ptr struct for the SP to access.
    Again, this would not be necessary on the chip. */
@@ -3279,7 +3289,7 @@ sh_css_params_write_to_ddr_internal(
 	if (binary->info->sp.enable.fpnr) {
 		buff_realloced = reallocate_buffer(&ddr_map->fpn_tbl,
 						   &ddr_map_size->fpn_tbl,
-						   (size_t)(FPNTBL_BYTES(binary)),
+						   fpntbl_bytes(binary),
 						   params->config_changed[IA_CSS_FPN_ID],
 						   &err);
 		if (err) {
@@ -3304,7 +3314,7 @@ sh_css_params_write_to_ddr_internal(
 
 		buff_realloced = reallocate_buffer(&ddr_map->sc_tbl,
 						   &ddr_map_size->sc_tbl,
-						   SCTBL_BYTES(binary),
+						   sctbl_bytes(binary),
 						   params->sc_table_changed,
 						   &err);
 		if (err) {
@@ -3538,8 +3548,7 @@ sh_css_params_write_to_ddr_internal(
 			buff_realloced |=
 			    reallocate_buffer(virt_addr_tetra_x[i],
 					    virt_size_tetra_x[i],
-					    (size_t)
-					    (MORPH_PLANE_BYTES(binary)),
+					    morph_plane_bytes(binary),
 					    params->morph_table_changed,
 					    &err);
 			if (err) {
@@ -3549,8 +3558,7 @@ sh_css_params_write_to_ddr_internal(
 			buff_realloced |=
 			    reallocate_buffer(virt_addr_tetra_y[i],
 					    virt_size_tetra_y[i],
-					    (size_t)
-					    (MORPH_PLANE_BYTES(binary)),
+					    morph_plane_bytes(binary),
 					    params->morph_table_changed,
 					    &err);
 			if (err) {
-- 
2.39.0


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

* [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD macros with functions
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (54 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 55/57] media: atomisp: pci: Replace bytes macros with functions Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-23 18:27   ` Andy Shevchenko
  2023-01-23 12:52 ` [PATCH 57/57] media: atomisp: pci: sh_css: Inline single invocation of macro STATS_ENABLED() Hans de Goede
  2023-01-24 11:01 ` [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Andy Shevchenko
  57 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Brent Pappas

From: Brent Pappas <bpappas@pappasbrent.com>

Replace the macros SUBWORD() and INV_SUBWORD() with functions to comply
with Linux coding style standards.

Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
Link: https://lore.kernel.org/r/20230120182625.23227-1-bpappas@pappasbrent.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../pci/hive_isp_css_common/host/vmem.c       | 20 +++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
index 6620f091442f..d9cdfbc50197 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
@@ -28,10 +28,18 @@ typedef hive_uedge *hive_wide;
 /* Copied from SDK: sim_semantics.c */
 
 /* subword bits move like this:         MSB[____xxxx____]LSB -> MSB[00000000xxxx]LSB */
-#define SUBWORD(w, start, end)     (((w) & (((1ULL << ((end) - 1)) - 1) << 1 | 1)) >> (start))
+static inline hive_uedge
+subword(hive_uedge w, unsigned int start, unsigned int end)
+{
+	return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start;
+}
 
 /* inverse subword bits move like this: MSB[xxxx____xxxx]LSB -> MSB[xxxx0000xxxx]LSB */
-#define INV_SUBWORD(w, start, end) ((w) & (~(((1ULL << ((end) - 1)) - 1) << 1 | 1) | ((1ULL << (start)) - 1)))
+static inline hive_uedge
+inv_subword(hive_uedge w, unsigned int start, unsigned int end)
+{
+	return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1));
+}
 
 #define uedge_bits (8 * sizeof(hive_uedge))
 #define move_lower_bits(target, target_bit, src, src_bit) move_subword(target, target_bit, src, 0, src_bit)
@@ -50,18 +58,18 @@ move_subword(
 	unsigned int start_bit  = target_bit % uedge_bits;
 	unsigned int subword_width = src_end - src_start;
 
-	hive_uedge src_subword = SUBWORD(src, src_start, src_end);
+	hive_uedge src_subword = subword(src, src_start, src_end);
 
 	if (subword_width + start_bit > uedge_bits) { /* overlap */
 		hive_uedge old_val1;
-		hive_uedge old_val0 = INV_SUBWORD(target[start_elem], start_bit, uedge_bits);
+		hive_uedge old_val0 = inv_subword(target[start_elem], start_bit, uedge_bits);
 
 		target[start_elem] = old_val0 | (src_subword << start_bit);
-		old_val1 = INV_SUBWORD(target[start_elem + 1], 0,
+		old_val1 = inv_subword(target[start_elem + 1], 0,
 				       subword_width + start_bit - uedge_bits);
 		target[start_elem + 1] = old_val1 | (src_subword >> (uedge_bits - start_bit));
 	} else {
-		hive_uedge old_val = INV_SUBWORD(target[start_elem], start_bit,
+		hive_uedge old_val = inv_subword(target[start_elem], start_bit,
 						 start_bit + subword_width);
 
 		target[start_elem] = old_val | (src_subword << start_bit);
-- 
2.39.0


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

* [PATCH 57/57] media: atomisp: pci: sh_css: Inline single invocation of macro STATS_ENABLED()
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (55 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD " Hans de Goede
@ 2023-01-23 12:52 ` Hans de Goede
  2023-01-24 11:01 ` [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Andy Shevchenko
  57 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-23 12:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Brent Pappas, Andy Shevchenko, Dan Carpenter

From: Brent Pappas <bpappas@pappasbrent.com>

Inline the single invocation of the macro STATS_ENABLED().
The macro abstraction is not necessary because the logic behind it is only
used once.

Signed-off-by: Brent Pappas <bpappas@pappasbrent.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Dan Carpenter <error27@gmail.com>
Link: https://lore.kernel.org/r/20230120171408.16099-1-bpappas@pappasbrent.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/staging/media/atomisp/pci/sh_css.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c
index 726cb7aa4ecd..93789500416f 100644
--- a/drivers/staging/media/atomisp/pci/sh_css.c
+++ b/drivers/staging/media/atomisp/pci/sh_css.c
@@ -97,9 +97,6 @@
  */
 #define JPEG_BYTES (16 * 1024 * 1024)
 
-#define STATS_ENABLED(stage) (stage && stage->binary && stage->binary->info && \
-	(stage->binary->info->sp.enable.s3a || stage->binary->info->sp.enable.dis))
-
 struct sh_css my_css;
 
 int  __printf(1, 0) (*sh_css_printf)(const char *fmt, va_list args) = NULL;
@@ -3743,7 +3740,9 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
 			 * The SP will read the params after it got
 			 * empty 3a and dis
 			 */
-			if (STATS_ENABLED(stage)) {
+			if (stage->binary && stage->binary->info &&
+			    (stage->binary->info->sp.enable.s3a ||
+			     stage->binary->info->sp.enable.dis)) {
 				/* there is a stage that needs it */
 				return_err = ia_css_bufq_enqueue_buffer(thread_id,
 									queue_id,
-- 
2.39.0


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

* Re: [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency
  2023-01-23 12:51 ` [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency Hans de Goede
@ 2023-01-23 14:12   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Arnd Bergmann

On Mon, Jan 23, 2023 at 01:51:09PM +0100, Hans de Goede wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> The recent conversion missed the Kconfig bit, so it can now
> end up in a link error on randconfig builds:
> 
> ld.lld: error: undefined symbol: vb2_vmalloc_memops
> >>> referenced by atomisp_fops.c
> >>>               drivers/staging/media/atomisp/pci/atomisp_fops.o:(atomisp_open) in archive vmlinux.a

IIRC I have given my Tb tag [1]...

For your convenience (but please, gather them next time)
Tested-by: Andy Shevchenko <andy@kernel.org>

[1]: https://lore.kernel.org/linux-media/Y7Vf6nejMFXs%2FqAk@smile.fi.intel.com/

> Fixes: cb48ae89be3b ("media: atomisp: Convert to videobuf2")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Link: https://lore.kernel.org/r/20230104082212.3770415-1-arnd@kernel.org
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig
> index 2c8d7fdcc5f7..c9bff98e5309 100644
> --- a/drivers/staging/media/atomisp/Kconfig
> +++ b/drivers/staging/media/atomisp/Kconfig
> @@ -14,7 +14,7 @@ config VIDEO_ATOMISP
>  	depends on VIDEO_DEV && INTEL_ATOMISP
>  	depends on PMIC_OPREGION
>  	select IOSF_MBI
> -	select VIDEOBUF_VMALLOC
> +	select VIDEOBUF2_VMALLOC
>  	select VIDEO_V4L2_SUBDEV_API
>  	help
>  	  Say Y here if your platform supports Intel Atom SoC
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct
  2023-01-23 12:51 ` [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct Hans de Goede
@ 2023-01-23 14:14   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:14 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:11PM +0100, Hans de Goede wrote:
> Remove the atomisp_sw_contex struct, it has only 1 member: running_freq,
> instead store running_freq directly.
> 
> While at it also change running_freq from an int to an unsigned int,
> all values stored in it are unsigned and it is compared to the also
> unsigned new_freq variable.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_cmd.c      | 4 ++--
>  drivers/staging/media/atomisp/pci/atomisp_fops.c     | 2 +-
>  drivers/staging/media/atomisp/pci/atomisp_internal.h | 6 +-----
>  3 files changed, 4 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> index d8c7e7367386..5cea1df48b7d 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> @@ -280,14 +280,14 @@ int atomisp_freq_scaling(struct atomisp_device *isp,
>  done:
>  	dev_dbg(isp->dev, "DFS target frequency=%d.\n", new_freq);
>  
> -	if ((new_freq == isp->sw_contex.running_freq) && !force)
> +	if ((new_freq == isp->running_freq) && !force)
>  		return 0;
>  
>  	dev_dbg(isp->dev, "Programming DFS frequency to %d\n", new_freq);
>  
>  	ret = write_target_freq_to_hw(isp, new_freq);
>  	if (!ret) {
> -		isp->sw_contex.running_freq = new_freq;
> +		isp->running_freq = new_freq;
>  		trace_ipu_pstate(new_freq, -1);
>  	}
>  	return ret;
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index acea7492847d..4643bb0db995 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -681,7 +681,7 @@ static void atomisp_dev_init_struct(struct atomisp_device *isp)
>  	 * For Merrifield, frequency is scalable.
>  	 * After boot-up, the default frequency is 200MHz.
>  	 */
> -	isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
> +	isp->running_freq = ISP_FREQ_200MHZ;
>  }
>  
>  static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h
> index 653e6d74a966..675007d7d9af 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h
> @@ -194,10 +194,6 @@ struct atomisp_regs {
>  	u32 csi_access_viol;
>  };
>  
> -struct atomisp_sw_contex {
> -	int running_freq;
> -};
> -
>  #define ATOMISP_DEVICE_STREAMING_DISABLED	0
>  #define ATOMISP_DEVICE_STREAMING_ENABLED	1
>  #define ATOMISP_DEVICE_STREAMING_STOPPING	2
> @@ -242,7 +238,6 @@ struct atomisp_device {
>  	struct v4l2_subdev *motor;
>  
>  	struct atomisp_regs saved_regs;
> -	struct atomisp_sw_contex sw_contex;
>  	struct atomisp_css_env css_env;
>  
>  	/* isp timeout status flag */
> @@ -257,6 +252,7 @@ struct atomisp_device {
>  	unsigned int mipi_frame_size;
>  	const struct atomisp_dfs_config *dfs;
>  	unsigned int hpll_freq;
> +	unsigned int running_freq;
>  
>  	bool css_initialized;
>  };
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages
  2023-01-23 12:51 ` [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages Hans de Goede
@ 2023-01-23 14:18   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:18 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:13PM +0100, Hans de Goede wrote:
> These are clearly debug messages, printing these all the time is not
> useful.
> 
> Silence these by simply removing them altogether.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/pci/css_2401_system/host/isys_dma_private.h   | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
> index a313e1dc7c71..d65fe9ec9049 100644
> --- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
> +++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h
> @@ -34,8 +34,6 @@ void isys2401_dma_reg_store(const isys2401_dma_ID_t	dma_id,
>  
>  	reg_loc = ISYS2401_DMA_BASE[dma_id] + (reg * sizeof(hrt_data));
>  
> -	ia_css_print("isys dma store at addr(0x%x) val(%u)\n", reg_loc,
> -		     (unsigned int)value);
>  	ia_css_device_store_uint32(reg_loc, value);
>  }
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl
  2023-01-23 12:51 ` [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl Hans de Goede
@ 2023-01-23 14:30   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:16PM +0100, Hans de Goede wrote:
> This ioctl simply returns a couple of fixed sensor parameters.
> 
> With libcamera these fixed parameters are instead stored in a table
> with sensor-name to parameters mappings (camera_sensor_properties.cpp),
> so these custom ioctl is not necessary; and it currently has no users.

s/ioctl is/IOCTLs are/

or

s/these/this/

> Remove the ioctl and also remove the custom v4l2-ctrls underpinning
> the ioctl.
> 
> This is part of a patch-series which tries to remove atomisp specific /
> custom code from the sensor drivers, with as end goal to make the atomisp
> drivers regular camera sensor drivers.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-gc0310.c        | 63 ------------------
>  .../media/atomisp/i2c/atomisp-gc2235.c        | 63 ------------------
>  .../media/atomisp/i2c/atomisp-mt9m114.c       | 64 -------------------
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 64 -------------------
>  .../media/atomisp/i2c/atomisp-ov2722.c        | 63 ------------------
>  drivers/staging/media/atomisp/i2c/gc0310.h    |  3 -
>  drivers/staging/media/atomisp/i2c/gc2235.h    |  3 -
>  drivers/staging/media/atomisp/i2c/mt9m114.h   |  3 -
>  drivers/staging/media/atomisp/i2c/ov2680.h    |  3 -
>  drivers/staging/media/atomisp/i2c/ov2722.h    |  3 -
>  .../media/atomisp/i2c/ov5693/atomisp-ov5693.c | 63 ------------------
>  .../media/atomisp/include/linux/atomisp.h     | 20 ------
>  .../staging/media/atomisp/pci/atomisp_cmd.c   | 36 -----------
>  .../staging/media/atomisp/pci/atomisp_cmd.h   |  3 -
>  .../staging/media/atomisp/pci/atomisp_ioctl.c |  7 --
>  15 files changed, 461 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> index 87a634bf9ff5..a9c4724a9358 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> @@ -241,27 +241,6 @@ static int gc0310_write_reg_array(struct i2c_client *client,
>  	return __gc0310_flush_reg_array(client, &ctrl);
>  }
>  
> -static int gc0310_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (GC0310_FOCAL_LENGTH_NUM << 16) | GC0310_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int gc0310_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/*const f number for imx*/
> -	*val = (GC0310_F_NUMBER_DEFAULT_NUM << 16) | GC0310_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int gc0310_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (GC0310_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (GC0310_F_NUMBER_DEM << 16) |
> -	       (GC0310_F_NUMBER_DEFAULT_NUM << 8) | GC0310_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  static int gc0310_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
>  {
>  	struct gc0310_device *dev = to_gc0310_sensor(sd);
> @@ -596,15 +575,6 @@ static int gc0310_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = gc0310_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = gc0310_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = gc0310_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = gc0310_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_BIN_FACTOR_HORZ:
>  		ret = gc0310_g_bin_factor_x(&dev->sd, &ctrl->val);
>  		break;
> @@ -655,39 +625,6 @@ static const struct v4l2_ctrl_config gc0310_controls[] = {
>  		.step = 1,
>  		.def = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "focal length",
> -		.min = GC0310_FOCAL_LENGTH_DEFAULT,
> -		.max = GC0310_FOCAL_LENGTH_DEFAULT,
> -		.step = 0x01,
> -		.def = GC0310_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number",
> -		.min = GC0310_F_NUMBER_DEFAULT,
> -		.max = GC0310_F_NUMBER_DEFAULT,
> -		.step = 0x01,
> -		.def = GC0310_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number range",
> -		.min = GC0310_F_NUMBER_RANGE,
> -		.max = GC0310_F_NUMBER_RANGE,
> -		.step = 0x01,
> -		.def = GC0310_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_BIN_FACTOR_HORZ,
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> index 4d5a7e335f85..e6df10bcab8c 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> @@ -220,27 +220,6 @@ static int gc2235_write_reg_array(struct i2c_client *client,
>  	return __gc2235_flush_reg_array(client, &ctrl);
>  }
>  
> -static int gc2235_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (GC2235_FOCAL_LENGTH_NUM << 16) | GC2235_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int gc2235_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/* const f number for imx */
> -	*val = (GC2235_F_NUMBER_DEFAULT_NUM << 16) | GC2235_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int gc2235_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (GC2235_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (GC2235_F_NUMBER_DEM << 16) |
> -	       (GC2235_F_NUMBER_DEFAULT_NUM << 8) | GC2235_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  static int gc2235_get_intg_factor(struct i2c_client *client,
>  				  struct camera_mipi_info *info,
>  				  const struct gc2235_resolution *res)
> @@ -467,15 +446,6 @@ static int gc2235_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = gc2235_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = gc2235_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = gc2235_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = gc2235_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -499,39 +469,6 @@ static struct v4l2_ctrl_config gc2235_controls[] = {
>  		.def = 0x00,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "focal length",
> -		.min = GC2235_FOCAL_LENGTH_DEFAULT,
> -		.max = GC2235_FOCAL_LENGTH_DEFAULT,
> -		.step = 0x01,
> -		.def = GC2235_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number",
> -		.min = GC2235_F_NUMBER_DEFAULT,
> -		.max = GC2235_F_NUMBER_DEFAULT,
> -		.step = 0x01,
> -		.def = GC2235_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number range",
> -		.min = GC2235_F_NUMBER_RANGE,
> -		.max = GC2235_F_NUMBER_RANGE,
> -		.step = 0x01,
> -		.def = GC2235_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  };
>  
>  static int __gc2235_init(struct v4l2_subdev *sd)
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> index a0e8e94b2412..eb34b5cadb33 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> @@ -841,28 +841,6 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
>  	return 0;
>  }
>  
> -/* TODO: Update to SOC functions, remove exposure and gain */
> -static int mt9m114_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (MT9M114_FOCAL_LENGTH_NUM << 16) | MT9M114_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int mt9m114_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/* const f number for mt9m114 */
> -	*val = (MT9M114_F_NUMBER_DEFAULT_NUM << 16) | MT9M114_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int mt9m114_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (MT9M114_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (MT9M114_F_NUMBER_DEM << 16) |
> -	       (MT9M114_F_NUMBER_DEFAULT_NUM << 8) | MT9M114_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  /* Horizontal flip the image. */
>  static int mt9m114_g_hflip(struct v4l2_subdev *sd, s32 *val)
>  {
> @@ -1271,15 +1249,6 @@ static int mt9m114_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_HFLIP:
>  		ret = mt9m114_g_hflip(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = mt9m114_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = mt9m114_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = mt9m114_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = mt9m114_g_exposure(&dev->sd, &ctrl->val);
>  		break;
> @@ -1331,39 +1300,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = {
>  		.step = 1,
>  		.def = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.name = "focal length",
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.min = MT9M114_FOCAL_LENGTH_DEFAULT,
> -		.max = MT9M114_FOCAL_LENGTH_DEFAULT,
> -		.step = 1,
> -		.def = MT9M114_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.name = "f-number",
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.min = MT9M114_F_NUMBER_DEFAULT,
> -		.max = MT9M114_F_NUMBER_DEFAULT,
> -		.step = 1,
> -		.def = MT9M114_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.name = "f-number range",
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.min = MT9M114_F_NUMBER_RANGE,
> -		.max = MT9M114_F_NUMBER_RANGE,
> -		.step = 1,
> -		.def = MT9M114_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_EXPOSURE_ABSOLUTE,
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index fa1de45b7a2d..39f86c7fd12e 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -119,28 +119,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
>  	return 0;
>  }
>  
> -static int ov2680_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV2680_FOCAL_LENGTH_NUM << 16) | OV2680_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int ov2680_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/* const f number for ov2680 */
> -
> -	*val = (OV2680_F_NUMBER_DEFAULT_NUM << 16) | OV2680_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int ov2680_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV2680_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (OV2680_F_NUMBER_DEM << 16) |
> -	       (OV2680_F_NUMBER_DEFAULT_NUM << 8) | OV2680_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
>  {
>  	struct ov2680_device *dev = to_ov2680_sensor(sd);
> @@ -517,15 +495,6 @@ static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = ov2680_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = ov2680_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = ov2680_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = ov2680_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_BIN_FACTOR_HORZ:
>  		ret = ov2680_g_bin_factor_x(&dev->sd, &ctrl->val);
>  		break;
> @@ -556,39 +525,6 @@ static const struct v4l2_ctrl_config ov2680_controls[] = {
>  		.def = 0x00,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "focal length",
> -		.min = OV2680_FOCAL_LENGTH_DEFAULT,
> -		.max = OV2680_FOCAL_LENGTH_DEFAULT,
> -		.step = 0x01,
> -		.def = OV2680_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number",
> -		.min = OV2680_F_NUMBER_DEFAULT,
> -		.max = OV2680_F_NUMBER_DEFAULT,
> -		.step = 0x01,
> -		.def = OV2680_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number range",
> -		.min = OV2680_F_NUMBER_RANGE,
> -		.max = OV2680_F_NUMBER_RANGE,
> -		.step = 0x01,
> -		.def = OV2680_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_BIN_FACTOR_HORZ,
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index 887b6f99f6ca..47eefaccbe0b 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -261,27 +261,6 @@ static int ov2722_write_reg_array(struct i2c_client *client,
>  	return __ov2722_flush_reg_array(client, &ctrl);
>  }
>  
> -static int ov2722_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV2722_FOCAL_LENGTH_NUM << 16) | OV2722_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int ov2722_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/*const f number for imx*/
> -	*val = (OV2722_F_NUMBER_DEFAULT_NUM << 16) | OV2722_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int ov2722_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV2722_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (OV2722_F_NUMBER_DEM << 16) |
> -	       (OV2722_F_NUMBER_DEFAULT_NUM << 8) | OV2722_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  static int ov2722_get_intg_factor(struct i2c_client *client,
>  				  struct camera_mipi_info *info,
>  				  const struct ov2722_resolution *res)
> @@ -547,15 +526,6 @@ static int ov2722_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = ov2722_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = ov2722_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = ov2722_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = ov2722_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_LINK_FREQ:
>  		val = dev->res->mipi_freq;
>  		if (val == 0)
> @@ -586,39 +556,6 @@ static const struct v4l2_ctrl_config ov2722_controls[] = {
>  		.def = 0x00,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "focal length",
> -		.min = OV2722_FOCAL_LENGTH_DEFAULT,
> -		.max = OV2722_FOCAL_LENGTH_DEFAULT,
> -		.step = 0x01,
> -		.def = OV2722_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number",
> -		.min = OV2722_F_NUMBER_DEFAULT,
> -		.max = OV2722_F_NUMBER_DEFAULT,
> -		.step = 0x01,
> -		.def = OV2722_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number range",
> -		.min = OV2722_F_NUMBER_RANGE,
> -		.max = OV2722_F_NUMBER_RANGE,
> -		.step = 0x01,
> -		.def = OV2722_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_LINK_FREQ,
> diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
> index 4b9ce681bd93..52b4c07e5cf0 100644
> --- a/drivers/staging/media/atomisp/i2c/gc0310.h
> +++ b/drivers/staging/media/atomisp/i2c/gc0310.h
> @@ -38,9 +38,6 @@
>  #define I2C_RETRY_COUNT		5
>  
>  #define GC0310_FOCAL_LENGTH_NUM	278	/*2.78mm*/
> -#define GC0310_FOCAL_LENGTH_DEM	100
> -#define GC0310_F_NUMBER_DEFAULT_NUM	26
> -#define GC0310_F_NUMBER_DEM	10
>  
>  #define MAX_FMTS		1
>  
> diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
> index 806be5dff7a5..dd2d44b40e22 100644
> --- a/drivers/staging/media/atomisp/i2c/gc2235.h
> +++ b/drivers/staging/media/atomisp/i2c/gc2235.h
> @@ -44,9 +44,6 @@
>  #define I2C_RETRY_COUNT		5
>  
>  #define GC2235_FOCAL_LENGTH_NUM	278	/*2.78mm*/
> -#define GC2235_FOCAL_LENGTH_DEM	100
> -#define GC2235_F_NUMBER_DEFAULT_NUM	26
> -#define GC2235_F_NUMBER_DEM	10
>  
>  #define MAX_FMTS		1
>  
> diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h
> index bcce18b65fa6..831875071cbb 100644
> --- a/drivers/staging/media/atomisp/i2c/mt9m114.h
> +++ b/drivers/staging/media/atomisp/i2c/mt9m114.h
> @@ -136,9 +136,6 @@
>  #define MT9M114_BPAT_BGBGGRGR	BIT(3)
>  
>  #define MT9M114_FOCAL_LENGTH_NUM	208	/*2.08mm*/
> -#define MT9M114_FOCAL_LENGTH_DEM	100
> -#define MT9M114_F_NUMBER_DEFAULT_NUM	24
> -#define MT9M114_F_NUMBER_DEM	10
>  #define MT9M114_WAIT_STAT_TIMEOUT	100
>  #define MT9M114_FLICKER_MODE_50HZ	1
>  #define MT9M114_FLICKER_MODE_60HZ	2
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 7ab337b859ad..2bc350c67711 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -37,9 +37,6 @@
>  #define I2C_RETRY_COUNT		5
>  
>  #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
> -#define OV2680_FOCAL_LENGTH_DEM	100
> -#define OV2680_F_NUMBER_DEFAULT_NUM	24
> -#define OV2680_F_NUMBER_DEM	10
>  
>  #define OV2680_BIN_FACTOR_MAX 4
>  
> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
> index d6e2510bc01c..d4cd6f27ee8d 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
> @@ -39,9 +39,6 @@
>  #define I2C_RETRY_COUNT		5
>  
>  #define OV2722_FOCAL_LENGTH_NUM	278	/*2.78mm*/
> -#define OV2722_FOCAL_LENGTH_DEM	100
> -#define OV2722_F_NUMBER_DEFAULT_NUM	26
> -#define OV2722_F_NUMBER_DEM	10
>  
>  #define MAX_FMTS		1
>  
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> index c1cd631455e6..9adaf2fc940a 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> @@ -415,27 +415,6 @@ static int ov5693_write_reg_array(struct i2c_client *client,
>  	return __ov5693_flush_reg_array(client, &ctrl);
>  }
>  
> -static int ov5693_g_focal(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV5693_FOCAL_LENGTH_NUM << 16) | OV5693_FOCAL_LENGTH_DEM;
> -	return 0;
> -}
> -
> -static int ov5693_g_fnumber(struct v4l2_subdev *sd, s32 *val)
> -{
> -	/*const f number for imx*/
> -	*val = (OV5693_F_NUMBER_DEFAULT_NUM << 16) | OV5693_F_NUMBER_DEM;
> -	return 0;
> -}
> -
> -static int ov5693_g_fnumber_range(struct v4l2_subdev *sd, s32 *val)
> -{
> -	*val = (OV5693_F_NUMBER_DEFAULT_NUM << 24) |
> -	       (OV5693_F_NUMBER_DEM << 16) |
> -	       (OV5693_F_NUMBER_DEFAULT_NUM << 8) | OV5693_F_NUMBER_DEM;
> -	return 0;
> -}
> -
>  static int ov5693_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
>  {
>  	struct ov5693_device *dev = to_ov5693_sensor(sd);
> @@ -1107,15 +1086,6 @@ static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = ov5693_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_FOCAL_ABSOLUTE:
> -		ret = ov5693_g_focal(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
> -		ret = ov5693_g_fnumber(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_FNUMBER_RANGE:
> -		ret = ov5693_g_fnumber_range(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_FOCUS_ABSOLUTE:
>  		ret = ov5693_q_focus_abs(&dev->sd, &ctrl->val);
>  		break;
> @@ -1152,39 +1122,6 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
>  		.def = 0x00,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FOCAL_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "focal length",
> -		.min = OV5693_FOCAL_LENGTH_DEFAULT,
> -		.max = OV5693_FOCAL_LENGTH_DEFAULT,
> -		.step = 0x01,
> -		.def = OV5693_FOCAL_LENGTH_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_ABSOLUTE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number",
> -		.min = OV5693_F_NUMBER_DEFAULT,
> -		.max = OV5693_F_NUMBER_DEFAULT,
> -		.step = 0x01,
> -		.def = OV5693_F_NUMBER_DEFAULT,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_FNUMBER_RANGE,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "f-number range",
> -		.min = OV5693_F_NUMBER_RANGE,
> -		.max = OV5693_F_NUMBER_RANGE,
> -		.step = 0x01,
> -		.def = OV5693_F_NUMBER_RANGE,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_FOCUS_ABSOLUTE,
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
> index 3f602b5aaff9..e70e57695300 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
> @@ -586,20 +586,6 @@ struct atomisp_shading_table {
>  	__u16 *data[ATOMISP_NUM_SC_COLORS];
>  };
>  
> -struct atomisp_makernote_info {
> -	/* bits 31-16: numerator, bits 15-0: denominator */
> -	unsigned int focal_length;
> -	/* bits 31-16: numerator, bits 15-0: denominator*/
> -	unsigned int f_number_curr;
> -	/*
> -	* 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
> -	*/
> -	unsigned int f_number_range;
> -};
> -
>  /* parameter for MACC */
>  #define ATOMISP_NUM_MACC_AXES           16
>  struct atomisp_macc_table {
> @@ -914,8 +900,6 @@ struct atomisp_sensor_ae_bracketing_lut {
>  	_IOR('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table)
>  #define ATOMISP_IOC_S_ISP_GDC_TAB \
>  	_IOW('v', BASE_VIDIOC_PRIVATE + 10, struct atomisp_morph_table)
> -#define ATOMISP_IOC_ISP_MAKERNOTE \
> -	_IOWR('v', BASE_VIDIOC_PRIVATE + 11, struct atomisp_makernote_info)
>  
>  /* macc parameter control*/
>  #define ATOMISP_IOC_G_ISP_MACC \
> @@ -1093,10 +1077,6 @@ struct atomisp_sensor_ae_bracketing_lut {
>   * Exposure, Flash and privacy (indicator) light controls, to be upstreamed */
>  #define V4L2_CID_CAMERA_LASTP1             (V4L2_CID_CAMERA_CLASS_BASE + 1024)
>  
> -#define V4L2_CID_FOCAL_ABSOLUTE            (V4L2_CID_CAMERA_LASTP1 + 0)
> -#define V4L2_CID_FNUMBER_ABSOLUTE          (V4L2_CID_CAMERA_LASTP1 + 1)
> -#define V4L2_CID_FNUMBER_RANGE             (V4L2_CID_CAMERA_LASTP1 + 2)
> -
>  /* Flash related CIDs, see also:
>   * http://linuxtv.org/downloads/v4l-dvb-apis/extended-controls.html\
>   * #flash-controls */
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> index 5cea1df48b7d..b167ee32a952 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> @@ -5492,42 +5492,6 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
>  	return ret;
>  }
>  
> -int atomisp_exif_makernote(struct atomisp_sub_device *asd,
> -			   struct atomisp_makernote_info *config)
> -{
> -	struct v4l2_control ctrl;
> -	struct atomisp_device *isp = asd->isp;
> -
> -	ctrl.id = V4L2_CID_FOCAL_ABSOLUTE;
> -	if (v4l2_g_ctrl
> -	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
> -		dev_warn(isp->dev, "failed to g_ctrl for focal length\n");
> -		return -EINVAL;
> -	} else {
> -		config->focal_length = ctrl.value;
> -	}
> -
> -	ctrl.id = V4L2_CID_FNUMBER_ABSOLUTE;
> -	if (v4l2_g_ctrl
> -	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
> -		dev_warn(isp->dev, "failed to g_ctrl for f-number\n");
> -		return -EINVAL;
> -	} else {
> -		config->f_number_curr = ctrl.value;
> -	}
> -
> -	ctrl.id = V4L2_CID_FNUMBER_RANGE;
> -	if (v4l2_g_ctrl
> -	    (isp->inputs[asd->input_curr].camera->ctrl_handler, &ctrl)) {
> -		dev_warn(isp->dev, "failed to g_ctrl for f number range\n");
> -		return -EINVAL;
> -	} else {
> -		config->f_number_range = ctrl.value;
> -	}
> -
> -	return 0;
> -}
> -
>  int atomisp_offline_capture_configure(struct atomisp_sub_device *asd,
>  				      struct atomisp_cont_capture_conf *cvf_config)
>  {
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> index b8911491581a..99bbab402c9c 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> @@ -273,9 +273,6 @@ int atomisp_set_shading_table(struct atomisp_sub_device *asd,
>  int atomisp_offline_capture_configure(struct atomisp_sub_device *asd,
>  				      struct atomisp_cont_capture_conf *cvf_config);
>  
> -int atomisp_exif_makernote(struct atomisp_sub_device *asd,
> -			   struct atomisp_makernote_info *config);
> -
>  void atomisp_free_internal_buffers(struct atomisp_sub_device *asd);
>  
>  int atomisp_s_ae_window(struct atomisp_sub_device *asd,
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> index 4f35e8f8250a..faf65387df56 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> @@ -1631,7 +1631,6 @@ static int atomisp_g_ctrl(struct file *file, void *fh,
>  	switch (control->id) {
>  	case V4L2_CID_IRIS_ABSOLUTE:
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
> -	case V4L2_CID_FNUMBER_ABSOLUTE:
>  	case V4L2_CID_2A_STATUS:
>  	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
>  	case V4L2_CID_EXPOSURE:
> @@ -1828,7 +1827,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
>  		case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		case V4L2_CID_EXPOSURE_AUTO:
>  		case V4L2_CID_IRIS_ABSOLUTE:
> -		case V4L2_CID_FNUMBER_ABSOLUTE:
>  		case V4L2_CID_BIN_FACTOR_HORZ:
>  		case V4L2_CID_BIN_FACTOR_VERT:
>  		case V4L2_CID_3A_LOCK:
> @@ -1940,7 +1938,6 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
>  		case V4L2_CID_EXPOSURE_AUTO:
>  		case V4L2_CID_EXPOSURE_METERING:
>  		case V4L2_CID_IRIS_ABSOLUTE:
> -		case V4L2_CID_FNUMBER_ABSOLUTE:
>  		case V4L2_CID_VCM_TIMING:
>  		case V4L2_CID_VCM_SLEW:
>  		case V4L2_CID_3A_LOCK:
> @@ -2276,10 +2273,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
>  		err = atomisp_fixed_pattern_table(asd, arg);
>  		break;
>  
> -	case ATOMISP_IOC_ISP_MAKERNOTE:
> -		err = atomisp_exif_makernote(asd, arg);
> -		break;
> -
>  	case ATOMISP_IOC_G_SENSOR_MODE_DATA:
>  		err = atomisp_get_sensor_mode_data(asd, arg);
>  		break;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl
  2023-01-23 12:51 ` [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl Hans de Goede
@ 2023-01-23 14:31   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:31 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:17PM +0100, Hans de Goede wrote:
> This ioctl returns a number of fixed sensor parameters +
> a number of mode-specific parameters.
> 
> With libcamera these fixed parameters are instead stored in a table
> with sensor-name to parameters mappings (camera_sensor_properties.cpp);
> and the variable parameters can be derived from the set fmt.
> 
> So this custom ioctl is not necessary; and it currently has no users.
> 
> Remove the ioctl and all the sensor drivers xxxx_get_intg_factor()
> helpers which return this info.
> 
> This is part of a patch-series which tries to remove atomisp specific /
> custom code from the sensor drivers, with as end goal to make the atomisp
> drivers regular camera sensor drivers.

Git history will keep this anyway (in case it will be needed for anything),
so

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-gc0310.c        | 140 ------------------
>  .../media/atomisp/i2c/atomisp-gc2235.c        | 113 --------------
>  .../media/atomisp/i2c/atomisp-mt9m114.c       |  96 ------------
>  .../media/atomisp/i2c/atomisp-ov2680.c        |  82 ----------
>  .../media/atomisp/i2c/atomisp-ov2722.c        | 111 --------------
>  drivers/staging/media/atomisp/i2c/gc0310.h    |   1 -
>  drivers/staging/media/atomisp/i2c/gc2235.h    |   1 -
>  drivers/staging/media/atomisp/i2c/ov2722.h    |   1 -
>  .../media/atomisp/i2c/ov5693/atomisp-ov5693.c |  86 -----------
>  .../staging/media/atomisp/i2c/ov5693/ov5693.h |   1 -
>  .../media/atomisp/include/linux/atomisp.h     |  26 ----
>  .../atomisp/include/linux/atomisp_platform.h  |   1 -
>  drivers/staging/media/atomisp/notes.txt       |   6 -
>  .../staging/media/atomisp/pci/atomisp_cmd.c   |  19 ---
>  .../staging/media/atomisp/pci/atomisp_cmd.h   |   3 -
>  .../staging/media/atomisp/pci/atomisp_ioctl.c |   4 -
>  16 files changed, 691 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> index a9c4724a9358..4968ec51ff1b 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> @@ -259,140 +259,6 @@ static int gc0310_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
>  	return 0;
>  }
>  
> -static int gc0310_get_intg_factor(struct i2c_client *client,
> -				  struct camera_mipi_info *info,
> -				  const struct gc0310_resolution *res)
> -{
> -	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> -	struct gc0310_device *dev = to_gc0310_sensor(sd);
> -	struct atomisp_sensor_mode_data *buf = &info->data;
> -	u16 val;
> -	u8 reg_val;
> -	int ret;
> -	unsigned int hori_blanking;
> -	unsigned int vert_blanking;
> -	unsigned int sh_delay;
> -
> -	if (!info)
> -		return -EINVAL;
> -
> -	/* pixel clock calculattion */
> -	dev->vt_pix_clk_freq_mhz = 14400000; // 16.8MHz
> -	buf->vt_pix_clk_freq_mhz = dev->vt_pix_clk_freq_mhz;
> -	dev_dbg(&client->dev, "vt_pix_clk_freq_mhz=%d\n", buf->vt_pix_clk_freq_mhz);
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = GC0310_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    GC0310_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = GC0310_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    GC0310_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = GC0310_FINE_INTG_TIME_MIN;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	/* Getting crop_horizontal_start */
> -	ret =  gc0310_read_reg(client, GC0310_8BIT,
> -			       GC0310_H_CROP_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret =  gc0310_read_reg(client, GC0310_8BIT,
> -			       GC0310_H_CROP_START_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_start = val | (reg_val & 0xFF);
> -	dev_dbg(&client->dev, "crop_horizontal_start=%d\n", buf->crop_horizontal_start);
> -
> -	/* Getting crop_vertical_start */
> -	ret =  gc0310_read_reg(client, GC0310_8BIT,
> -			       GC0310_V_CROP_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret =  gc0310_read_reg(client, GC0310_8BIT,
> -			       GC0310_V_CROP_START_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_start = val | (reg_val & 0xFF);
> -	dev_dbg(&client->dev, "crop_vertical_start=%d\n", buf->crop_vertical_start);
> -
> -	/* Getting output_width */
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_H_OUTSIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_H_OUTSIZE_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = val | (reg_val & 0xFF);
> -	dev_dbg(&client->dev, "output_width=%d\n", buf->output_width);
> -
> -	/* Getting output_height */
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_V_OUTSIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_V_OUTSIZE_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = val | (reg_val & 0xFF);
> -	dev_dbg(&client->dev, "output_height=%d\n", buf->output_height);
> -
> -	buf->crop_horizontal_end = buf->crop_horizontal_start + buf->output_width - 1;
> -	buf->crop_vertical_end = buf->crop_vertical_start + buf->output_height - 1;
> -	dev_dbg(&client->dev, "crop_horizontal_end=%d\n", buf->crop_horizontal_end);
> -	dev_dbg(&client->dev, "crop_vertical_end=%d\n", buf->crop_vertical_end);
> -
> -	/* Getting line_length_pck */
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_H_BLANKING_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_H_BLANKING_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	hori_blanking = val | (reg_val & 0xFF);
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_SH_DELAY, &reg_val);
> -	if (ret)
> -		return ret;
> -	sh_delay = reg_val;
> -	buf->line_length_pck = buf->output_width + hori_blanking + sh_delay + 4;
> -	dev_dbg(&client->dev, "hori_blanking=%d sh_delay=%d line_length_pck=%d\n", hori_blanking,
> -		sh_delay, buf->line_length_pck);
> -
> -	/* Getting frame_length_lines */
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_V_BLANKING_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	val = (reg_val & 0xFF) << 8;
> -	ret = gc0310_read_reg(client, GC0310_8BIT,
> -			      GC0310_V_BLANKING_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	vert_blanking = val | (reg_val & 0xFF);
> -	buf->frame_length_lines = buf->output_height + vert_blanking;
> -	dev_dbg(&client->dev, "vert_blanking=%d frame_length_lines=%d\n", vert_blanking,
> -		buf->frame_length_lines);
> -
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				res->bin_factor_x : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				res->bin_factor_y : 1;
> -	return 0;
> -}
> -
>  static int gc0310_set_gain(struct v4l2_subdev *sd, int gain)
>  
>  {
> @@ -889,12 +755,6 @@ static int gc0310_set_fmt(struct v4l2_subdev *sd,
>  		goto err;
>  	}
>  
> -	ret = gc0310_get_intg_factor(client, gc0310_info, dev->res);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to get integration_factor\n");
> -		goto err;
> -	}
> -
>  err:
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> index e6df10bcab8c..cb4c79b483ca 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
> @@ -220,114 +220,6 @@ static int gc2235_write_reg_array(struct i2c_client *client,
>  	return __gc2235_flush_reg_array(client, &ctrl);
>  }
>  
> -static int gc2235_get_intg_factor(struct i2c_client *client,
> -				  struct camera_mipi_info *info,
> -				  const struct gc2235_resolution *res)
> -{
> -	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> -	struct gc2235_device *dev = to_gc2235_sensor(sd);
> -	struct atomisp_sensor_mode_data *buf = &info->data;
> -	u16 reg_val, reg_val_h;
> -	int ret;
> -
> -	if (!info)
> -		return -EINVAL;
> -
> -	/* pixel clock calculattion */
> -	buf->vt_pix_clk_freq_mhz = dev->vt_pix_clk_freq_mhz = 30000000;
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = GC2235_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    GC2235_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = GC2235_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    GC2235_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = GC2235_FINE_INTG_TIME_MIN;
> -	buf->frame_length_lines = res->lines_per_frame;
> -	buf->line_length_pck = res->pixels_per_line;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	ret =  gc2235_read_reg(client, GC2235_8BIT,
> -			       GC2235_H_CROP_START_H, &reg_val_h);
> -	ret =  gc2235_read_reg(client, GC2235_8BIT,
> -			       GC2235_H_CROP_START_L, &reg_val);
> -	if (ret)
> -		return ret;
> -
> -	buf->crop_horizontal_start = (reg_val_h << 8) | reg_val;
> -
> -	ret =  gc2235_read_reg(client, GC2235_8BIT,
> -			       GC2235_V_CROP_START_H, &reg_val_h);
> -	ret =  gc2235_read_reg(client, GC2235_8BIT,
> -			       GC2235_V_CROP_START_L, &reg_val);
> -	if (ret)
> -		return ret;
> -
> -	buf->crop_vertical_start = (reg_val_h << 8) | reg_val;
> -
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_H_OUTSIZE_H, &reg_val_h);
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_H_OUTSIZE_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = (reg_val_h << 8) | reg_val;
> -
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_V_OUTSIZE_H, &reg_val_h);
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_V_OUTSIZE_L, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = (reg_val_h << 8) | reg_val;
> -
> -	buf->crop_horizontal_end = buf->crop_horizontal_start +
> -				   buf->output_width - 1;
> -	buf->crop_vertical_end = buf->crop_vertical_start +
> -				 buf->output_height - 1;
> -
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_HB_H, &reg_val_h);
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_HB_L, &reg_val);
> -	if (ret)
> -		return ret;
> -
> -#if 0
> -	u16 dummy = (reg_val_h << 8) | reg_val;
> -#endif
> -
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_SH_DELAY_H, &reg_val_h);
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_SH_DELAY_L, &reg_val);
> -
> -#if 0
> -	buf->line_length_pck = buf->output_width + 16 + dummy +
> -			       (((u16)reg_val_h << 8) | (u16)reg_val) + 4;
> -#endif
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_VB_H, &reg_val_h);
> -	ret = gc2235_read_reg(client, GC2235_8BIT,
> -			      GC2235_VB_L, &reg_val);
> -	if (ret)
> -		return ret;
> -
> -#if 0
> -	buf->frame_length_lines = buf->output_height + 32 +
> -				  (((u16)reg_val_h << 8) | (u16)reg_val);
> -#endif
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				res->bin_factor_x : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				res->bin_factor_y : 1;
> -	return 0;
> -}
> -
>  static long __gc2235_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -680,11 +572,6 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
>  		goto err;
>  	}
>  
> -	ret = gc2235_get_intg_factor(client, gc2235_info,
> -				     dev->res);
> -	if (ret)
> -		dev_err(&client->dev, "failed to get integration_factor\n");
> -
>  err:
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> index eb34b5cadb33..1df38f5fe1f4 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> @@ -612,96 +612,6 @@ static int mt9m114_res2size(struct v4l2_subdev *sd, int *h_size, int *v_size)
>  	return 0;
>  }
>  
> -static int mt9m114_get_intg_factor(struct i2c_client *client,
> -				   struct camera_mipi_info *info,
> -				   const struct mt9m114_res_struct *res)
> -{
> -	struct atomisp_sensor_mode_data *buf;
> -	u32 reg_val;
> -	int ret;
> -
> -	if (!info)
> -		return -EINVAL;
> -
> -	buf = &info->data;
> -
> -	ret =  mt9m114_read_reg(client, MISENSOR_32BIT,
> -				REG_PIXEL_CLK, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->vt_pix_clk_freq_mhz = reg_val;
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = MT9M114_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    MT9M114_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = MT9M114_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    MT9M114_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = MT9M114_FINE_INTG_TIME_MIN;
> -
> -	buf->frame_length_lines = res->lines_per_frame;
> -	buf->line_length_pck = res->pixels_per_line;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	ret =  mt9m114_read_reg(client, MISENSOR_16BIT,
> -				REG_H_START, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_start = reg_val;
> -
> -	ret =  mt9m114_read_reg(client, MISENSOR_16BIT,
> -				REG_V_START, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_start = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_H_END, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_end = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_V_END, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_end = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_WIDTH, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_HEIGHT, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_TIMING_HTS, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->line_length_pck = reg_val;
> -
> -	ret = mt9m114_read_reg(client, MISENSOR_16BIT,
> -			       REG_TIMING_VTS, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->frame_length_lines = reg_val;
> -
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				res->bin_factor_x : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				res->bin_factor_y : 1;
> -	return 0;
> -}
> -
>  static int mt9m114_get_fmt(struct v4l2_subdev *sd,
>  			   struct v4l2_subdev_state *sd_state,
>  			   struct v4l2_subdev_format *format)
> @@ -823,12 +733,6 @@ static int mt9m114_set_fmt(struct v4l2_subdev *sd,
>  			mt9m114_res[index].used = false;
>  		}
>  	}
> -	ret = mt9m114_get_intg_factor(c, mt9m114_info,
> -				      &mt9m114_res[res->res]);
> -	if (ret) {
> -		dev_err(&c->dev, "failed to get integration_factor\n");
> -		return -EINVAL;
> -	}
>  	/*
>  	 * mt9m114 - we don't poll for context switch
>  	 * because it does not happen with streaming disabled.
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 39f86c7fd12e..9379c25205b4 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -140,82 +140,6 @@ static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
>  	return 0;
>  }
>  
> -static int ov2680_get_intg_factor(struct i2c_client *client,
> -				  struct camera_mipi_info *info,
> -				  const struct ov2680_resolution *res)
> -{
> -	struct atomisp_sensor_mode_data *buf = &info->data;
> -	unsigned int pix_clk_freq_hz;
> -	u32 reg_val;
> -	int ret;
> -
> -	dev_dbg(&client->dev,  "++++ov2680_get_intg_factor\n");
> -	if (!info)
> -		return -EINVAL;
> -
> -	/* pixel clock */
> -	pix_clk_freq_hz = res->pix_clk_freq * 1000000;
> -
> -	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = OV2680_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    OV2680_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = OV2680_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    OV2680_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = OV2680_FINE_INTG_TIME_MIN;
> -	buf->frame_length_lines = res->lines_per_frame;
> -	buf->line_length_pck = res->pixels_per_line;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	ret =  ov2680_read_reg(client, 2,
> -			       OV2680_HORIZONTAL_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_start = reg_val;
> -
> -	ret =  ov2680_read_reg(client, 2,
> -			       OV2680_VERTICAL_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_start = reg_val;
> -
> -	ret = ov2680_read_reg(client, 2,
> -			      OV2680_HORIZONTAL_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_end = reg_val;
> -
> -	ret = ov2680_read_reg(client, 2,
> -			      OV2680_VERTICAL_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_end = reg_val;
> -
> -	ret = ov2680_read_reg(client, 2,
> -			      OV2680_HORIZONTAL_OUTPUT_SIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = reg_val;
> -
> -	ret = ov2680_read_reg(client, 2,
> -			      OV2680_VERTICAL_OUTPUT_SIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = reg_val;
> -
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				(res->bin_factor_x * 2) : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				(res->bin_factor_y * 2) : 1;
> -	return 0;
> -}
> -
>  static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -818,12 +742,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  		goto err;
>  	}
>  
> -	ret = ov2680_get_intg_factor(client, ov2680_info, res);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to get integration factor\n");
> -		goto err;
> -	}
> -
>  	/*
>  	 * recall flip functions to avoid flip registers
>  	 * were overridden by default setting
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index 47eefaccbe0b..d819ab5de28a 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -261,113 +261,6 @@ static int ov2722_write_reg_array(struct i2c_client *client,
>  	return __ov2722_flush_reg_array(client, &ctrl);
>  }
>  
> -static int ov2722_get_intg_factor(struct i2c_client *client,
> -				  struct camera_mipi_info *info,
> -				  const struct ov2722_resolution *res)
> -{
> -	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> -	struct ov2722_device *dev = NULL;
> -	struct atomisp_sensor_mode_data *buf = &info->data;
> -	const unsigned int ext_clk_freq_hz = 19200000;
> -	const unsigned int pll_invariant_div = 10;
> -	unsigned int pix_clk_freq_hz;
> -	u16 pre_pll_clk_div;
> -	u16 pll_multiplier;
> -	u16 op_pix_clk_div;
> -	u16 reg_val;
> -	int ret;
> -
> -	if (!info)
> -		return -EINVAL;
> -
> -	dev = to_ov2722_sensor(sd);
> -
> -	/* pixel clock calculattion */
> -	ret =  ov2722_read_reg(client, OV2722_8BIT,
> -			       OV2722_SC_CMMN_PLL_CTRL3, &pre_pll_clk_div);
> -	if (ret)
> -		return ret;
> -
> -	ret =  ov2722_read_reg(client, OV2722_8BIT,
> -			       OV2722_SC_CMMN_PLL_MULTIPLIER, &pll_multiplier);
> -	if (ret)
> -		return ret;
> -
> -	ret =  ov2722_read_reg(client, OV2722_8BIT,
> -			       OV2722_SC_CMMN_PLL_DEBUG_OPT, &op_pix_clk_div);
> -	if (ret)
> -		return ret;
> -
> -	pre_pll_clk_div = (pre_pll_clk_div & 0x70) >> 4;
> -	if (!pre_pll_clk_div)
> -		return -EINVAL;
> -
> -	pll_multiplier = pll_multiplier & 0x7f;
> -	op_pix_clk_div = op_pix_clk_div & 0x03;
> -	pix_clk_freq_hz = ext_clk_freq_hz / pre_pll_clk_div * pll_multiplier
> -			  * op_pix_clk_div / pll_invariant_div;
> -
> -	dev->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
> -	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = OV2722_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    OV2722_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = OV2722_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    OV2722_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = OV2722_FINE_INTG_TIME_MIN;
> -	buf->frame_length_lines = res->lines_per_frame;
> -	buf->line_length_pck = res->pixels_per_line;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	ret =  ov2722_read_reg(client, OV2722_16BIT,
> -			       OV2722_H_CROP_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_start = reg_val;
> -
> -	ret =  ov2722_read_reg(client, OV2722_16BIT,
> -			       OV2722_V_CROP_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_start = reg_val;
> -
> -	ret = ov2722_read_reg(client, OV2722_16BIT,
> -			      OV2722_H_CROP_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_end = reg_val;
> -
> -	ret = ov2722_read_reg(client, OV2722_16BIT,
> -			      OV2722_V_CROP_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_end = reg_val;
> -
> -	ret = ov2722_read_reg(client, OV2722_16BIT,
> -			      OV2722_H_OUTSIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = reg_val;
> -
> -	ret = ov2722_read_reg(client, OV2722_16BIT,
> -			      OV2722_V_OUTSIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = reg_val;
> -
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				res->bin_factor_x : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				res->bin_factor_y : 1;
> -	return 0;
> -}
> -
>  static long __ov2722_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -812,10 +705,6 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
>  		}
>  	}
>  
> -	ret = ov2722_get_intg_factor(client, ov2722_info, dev->res);
> -	if (ret)
> -		dev_err(&client->dev, "failed to get integration_factor\n");
> -
>  err:
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
> diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
> index 52b4c07e5cf0..2a559b0d474d 100644
> --- a/drivers/staging/media/atomisp/i2c/gc0310.h
> +++ b/drivers/staging/media/atomisp/i2c/gc0310.h
> @@ -146,7 +146,6 @@ struct gc0310_device {
>  	struct v4l2_ctrl_handler ctrl_handler;
>  
>  	struct camera_sensor_platform_data *platform_data;
> -	int vt_pix_clk_freq_mhz;
>  	struct gc0310_resolution *res;
>  	u8 type;
>  	bool power_on;
> diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
> index dd2d44b40e22..8e33eb166bed 100644
> --- a/drivers/staging/media/atomisp/i2c/gc2235.h
> +++ b/drivers/staging/media/atomisp/i2c/gc2235.h
> @@ -158,7 +158,6 @@ struct gc2235_device {
>  	struct gc2235_resolution *res;
>  
>  	struct camera_sensor_platform_data *platform_data;
> -	int vt_pix_clk_freq_mhz;
>  	u8 type;
>  };
>  
> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
> index d4cd6f27ee8d..5802cdb0e90c 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
> @@ -201,7 +201,6 @@ struct ov2722_device {
>  	struct ov2722_resolution *res;
>  
>  	struct camera_sensor_platform_data *platform_data;
> -	int vt_pix_clk_freq_mhz;
>  	int run_mode;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> index 9adaf2fc940a..e65759499d81 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> @@ -433,84 +433,6 @@ static int ov5693_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
>  	return 0;
>  }
>  
> -static int ov5693_get_intg_factor(struct i2c_client *client,
> -				  struct camera_mipi_info *info,
> -				  const struct ov5693_resolution *res)
> -{
> -	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> -	struct ov5693_device *dev = to_ov5693_sensor(sd);
> -	struct atomisp_sensor_mode_data *buf = &info->data;
> -	unsigned int pix_clk_freq_hz;
> -	u16 reg_val;
> -	int ret;
> -
> -	if (!info)
> -		return -EINVAL;
> -
> -	/* pixel clock */
> -	pix_clk_freq_hz = res->pix_clk_freq * 1000000;
> -
> -	dev->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
> -	buf->vt_pix_clk_freq_mhz = pix_clk_freq_hz;
> -
> -	/* get integration time */
> -	buf->coarse_integration_time_min = OV5693_COARSE_INTG_TIME_MIN;
> -	buf->coarse_integration_time_max_margin =
> -	    OV5693_COARSE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_min = OV5693_FINE_INTG_TIME_MIN;
> -	buf->fine_integration_time_max_margin =
> -	    OV5693_FINE_INTG_TIME_MAX_MARGIN;
> -
> -	buf->fine_integration_time_def = OV5693_FINE_INTG_TIME_MIN;
> -	buf->frame_length_lines = res->lines_per_frame;
> -	buf->line_length_pck = res->pixels_per_line;
> -	buf->read_mode = res->bin_mode;
> -
> -	/* get the cropping and output resolution to ISP for this mode. */
> -	ret =  ov5693_read_reg(client, OV5693_16BIT,
> -			       OV5693_HORIZONTAL_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_start = reg_val;
> -
> -	ret =  ov5693_read_reg(client, OV5693_16BIT,
> -			       OV5693_VERTICAL_START_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_start = reg_val;
> -
> -	ret = ov5693_read_reg(client, OV5693_16BIT,
> -			      OV5693_HORIZONTAL_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_horizontal_end = reg_val;
> -
> -	ret = ov5693_read_reg(client, OV5693_16BIT,
> -			      OV5693_VERTICAL_END_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->crop_vertical_end = reg_val;
> -
> -	ret = ov5693_read_reg(client, OV5693_16BIT,
> -			      OV5693_HORIZONTAL_OUTPUT_SIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_width = reg_val;
> -
> -	ret = ov5693_read_reg(client, OV5693_16BIT,
> -			      OV5693_VERTICAL_OUTPUT_SIZE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -	buf->output_height = reg_val;
> -
> -	buf->binning_factor_x = res->bin_factor_x ?
> -				res->bin_factor_x : 1;
> -	buf->binning_factor_y = res->bin_factor_y ?
> -				res->bin_factor_y : 1;
> -	return 0;
> -}
> -
>  static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -1596,18 +1518,10 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
>  	if (ret)
>  		dev_warn(&client->dev, "ov5693 stream off err\n");
>  
> -	ret = ov5693_get_intg_factor(client, ov5693_info,
> -				     &ov5693_res[dev->fmt_idx]);
> -	if (ret) {
> -		dev_err(&client->dev, "failed to get integration_factor\n");
> -		goto err;
> -	}
> -
>  	ov5693_info->metadata_width = fmt->width * 10 / 8;
>  	ov5693_info->metadata_height = 1;
>  	ov5693_info->metadata_effective_width = &ov5693_embedded_effective_size;
>  
> -err:
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
>  }
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> index a1366666f49c..c9b9dc780f96 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> @@ -228,7 +228,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;
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
> index e70e57695300..d6da776e9bf4 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
> @@ -636,28 +636,6 @@ struct atomisp_overlay {
>  	unsigned int overlay_start_y;
>  };
>  
> -/* Sensor resolution specific data for AE calculation.*/
> -struct atomisp_sensor_mode_data {
> -	unsigned int coarse_integration_time_min;
> -	unsigned int coarse_integration_time_max_margin;
> -	unsigned int fine_integration_time_min;
> -	unsigned int fine_integration_time_max_margin;
> -	unsigned int fine_integration_time_def;
> -	unsigned int frame_length_lines;
> -	unsigned int line_length_pck;
> -	unsigned int read_mode;
> -	unsigned int vt_pix_clk_freq_mhz;
> -	unsigned int crop_horizontal_start; /* Sensor crop start cord. (x0,y0)*/
> -	unsigned int crop_vertical_start;
> -	unsigned int crop_horizontal_end; /* Sensor crop end cord. (x1,y1)*/
> -	unsigned int crop_vertical_end;
> -	unsigned int output_width; /* input size to ISP after binning/scaling */
> -	unsigned int output_height;
> -	u8 binning_factor_x; /* horizontal binning factor used */
> -	u8 binning_factor_y; /* vertical binning factor used */
> -	u16 hts;
> -};
> -
>  struct atomisp_exposure {
>  	unsigned int integration_time[8];
>  	unsigned int shutter_speed[8];
> @@ -945,10 +923,6 @@ struct atomisp_sensor_ae_bracketing_lut {
>  #define ATOMISP_IOC_CAMERA_BRIDGE \
>  	_IOWR('v', BASE_VIDIOC_PRIVATE + 19, struct atomisp_bc_video_package)
>  
> -/* Sensor resolution specific info for AE */
> -#define ATOMISP_IOC_G_SENSOR_MODE_DATA \
> -	_IOR('v', BASE_VIDIOC_PRIVATE + 20, struct atomisp_sensor_mode_data)
> -
>  #define ATOMISP_IOC_S_EXPOSURE \
>  	_IOW('v', BASE_VIDIOC_PRIVATE + 21, struct atomisp_exposure)
>  
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> index 0253661d4332..559a497975c5 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> @@ -210,7 +210,6 @@ struct camera_mipi_info {
>  	unsigned int                    num_lanes;
>  	enum atomisp_input_format       input_format;
>  	enum atomisp_bayer_order        raw_bayer_order;
> -	struct atomisp_sensor_mode_data data;
>  	enum atomisp_input_format       metadata_format;
>  	u32                             metadata_width;
>  	u32                             metadata_height;
> diff --git a/drivers/staging/media/atomisp/notes.txt b/drivers/staging/media/atomisp/notes.txt
> index d3cf6ed547ae..c04c283ff438 100644
> --- a/drivers/staging/media/atomisp/notes.txt
> +++ b/drivers/staging/media/atomisp/notes.txt
> @@ -36,12 +36,6 @@ a camera_mipi_info struct. This struct is allocated/managed by
>  the core atomisp code. The most important parts of the struct
>  are filled by the atomisp core itself, like e.g. the port number.
>  
> -The sensor drivers on a set_fmt call do fill in camera_mipi_info.data
> -which is a atomisp_sensor_mode_data struct. This gets filled from
> -a function called <sensor_name>_get_intg_factor(). This struct is not
> -used by the atomisp code at all. It is returned to userspace by
> -a ATOMISP_IOC_G_SENSOR_MODE_DATA and the Android userspace does use this.
> -
>  Other members of camera_mipi_info which are set by some drivers are:
>  -metadata_width, metadata_height, metadata_effective_width, set by
>   the ov5693 driver (and used by the atomisp core)
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> index b167ee32a952..01c9845b9f28 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> @@ -4211,25 +4211,6 @@ int atomisp_digital_zoom(struct atomisp_sub_device *asd, int flag,
>  	return 0;
>  }
>  
> -/*
> - * Function to get sensor specific info for current resolution,
> - * which will be used for auto exposure conversion.
> - */
> -int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
> -				 struct atomisp_sensor_mode_data *config)
> -{
> -	struct camera_mipi_info *mipi_info;
> -	struct atomisp_device *isp = asd->isp;
> -
> -	mipi_info = atomisp_to_sensor_mipi_info(
> -			isp->inputs[asd->input_curr].camera);
> -	if (!mipi_info)
> -		return -EINVAL;
> -
> -	memcpy(config, &mipi_info->data, sizeof(*config));
> -	return 0;
> -}
> -
>  static void __atomisp_update_stream_env(struct atomisp_sub_device *asd,
>  					u16 stream_index, struct atomisp_input_stream_info *stream_info)
>  {
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> index 99bbab402c9c..a10577df10cb 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> @@ -258,9 +258,6 @@ int atomisp_makeup_css_parameters(struct atomisp_sub_device *asd,
>  int atomisp_compare_grid(struct atomisp_sub_device *asd,
>  			 struct atomisp_grid_info *atomgrid);
>  
> -int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd,
> -				 struct atomisp_sensor_mode_data *config);
> -
>  /* This function looks up the closest available resolution. */
>  int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
>  		    bool *res_overflow);
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> index faf65387df56..d202b2b9ae18 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> @@ -2273,10 +2273,6 @@ static long atomisp_vidioc_default(struct file *file, void *fh,
>  		err = atomisp_fixed_pattern_table(asd, arg);
>  		break;
>  
> -	case ATOMISP_IOC_G_SENSOR_MODE_DATA:
> -		err = atomisp_get_sensor_mode_data(asd, arg);
> -		break;
> -
>  	case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
>  		if (motor)
>  			err = v4l2_subdev_call(motor, core, ioctl, cmd, arg);
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT
  2023-01-23 12:51 ` [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT Hans de Goede
@ 2023-01-23 14:33   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:33 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:18PM +0100, Hans de Goede wrote:
> The bin-factor-x and bin-factor-y ctrls are only used internally to
> get a single value to pass to atomisp_css_input_set_binning_factor(),
> which is supposed to tune the lens-shading correction for the binning
> factor. But all sensor drivers return either 0 or 1 for this,
> with 0 meaning unset and 1 meaning no-binning. Even though some modes
> do actually do binning ...
> 
> Also note that the removed atomisp_get_sensor_bin_factor() would fall
> back to 0 if either the x and y factor differ or if the ctrls are not
> implemented (not all sensor drivers implement them).
> 
> Simply always pass 0 to atomisp_css_input_set_binning_factor().
> 
> This is part of a patch-series which tries to remove atomisp specific /
> custom code from the sensor drivers, with as end goal to make the atomisp
> drivers regular camera sensor drivers.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-gc0310.c        | 46 -----------------
>  .../media/atomisp/i2c/atomisp-mt9m114.c       | 46 -----------------
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 49 -------------------
>  .../media/atomisp/i2c/ov5693/atomisp-ov5693.c | 46 -----------------
>  .../media/atomisp/include/linux/atomisp.h     |  4 --
>  .../staging/media/atomisp/pci/atomisp_ioctl.c | 20 --------
>  .../media/atomisp/pci/atomisp_subdev.c        | 36 +-------------
>  7 files changed, 1 insertion(+), 246 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> index 4968ec51ff1b..0d90683ed227 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
> @@ -241,24 +241,6 @@ static int gc0310_write_reg_array(struct i2c_client *client,
>  	return __gc0310_flush_reg_array(client, &ctrl);
>  }
>  
> -static int gc0310_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct gc0310_device *dev = to_gc0310_sensor(sd);
> -
> -	*val = dev->res->bin_factor_x;
> -
> -	return 0;
> -}
> -
> -static int gc0310_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct gc0310_device *dev = to_gc0310_sensor(sd);
> -
> -	*val = dev->res->bin_factor_y;
> -
> -	return 0;
> -}
> -
>  static int gc0310_set_gain(struct v4l2_subdev *sd, int gain)
>  
>  {
> @@ -441,12 +423,6 @@ static int gc0310_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = gc0310_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_BIN_FACTOR_HORZ:
> -		ret = gc0310_g_bin_factor_x(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_BIN_FACTOR_VERT:
> -		ret = gc0310_g_bin_factor_y(&dev->sd, &ctrl->val);
> -		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -491,28 +467,6 @@ static const struct v4l2_ctrl_config gc0310_controls[] = {
>  		.step = 1,
>  		.def = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_HORZ,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "horizontal binning factor",
> -		.min = 0,
> -		.max = GC0310_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_VERT,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "vertical binning factor",
> -		.min = 0,
> -		.max = GC0310_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
>  };
>  
>  static int gc0310_init(struct v4l2_subdev *sd)
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> index 1df38f5fe1f4..0e5a981dd331 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
> @@ -1016,24 +1016,6 @@ static int mt9m114_s_exposure_selection(struct v4l2_subdev *sd,
>  	return 0;
>  }
>  
> -static int mt9m114_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct mt9m114_device *dev = to_mt9m114_sensor(sd);
> -
> -	*val = mt9m114_res[dev->res].bin_factor_x;
> -
> -	return 0;
> -}
> -
> -static int mt9m114_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct mt9m114_device *dev = to_mt9m114_sensor(sd);
> -
> -	*val = mt9m114_res[dev->res].bin_factor_y;
> -
> -	return 0;
> -}
> -
>  static int mt9m114_s_ev(struct v4l2_subdev *sd, s32 val)
>  {
>  	struct i2c_client *c = v4l2_get_subdevdata(sd);
> @@ -1159,12 +1141,6 @@ static int mt9m114_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ZONE_NUM:
>  		ret = mt9m114_g_exposure_zone_num(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_BIN_FACTOR_HORZ:
> -		ret = mt9m114_g_bin_factor_x(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_BIN_FACTOR_VERT:
> -		ret = mt9m114_g_bin_factor_y(&dev->sd, &ctrl->val);
> -		break;
>  	case V4L2_CID_EXPOSURE:
>  		ret = mt9m114_g_ev(&dev->sd, &ctrl->val);
>  		break;
> @@ -1237,28 +1213,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = {
>  		.def = 1,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_HORZ,
> -		.name = "horizontal binning factor",
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.min = 0,
> -		.max = MT9M114_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_VERT,
> -		.name = "vertical binning factor",
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.min = 0,
> -		.max = MT9M114_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_EXPOSURE,
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 9379c25205b4..88fdeb828c6c 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -119,27 +119,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
>  	return 0;
>  }
>  
> -static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -
> -	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_x\n");
> -	*val = dev->res->bin_factor_x;
> -
> -	return 0;
> -}
> -
> -static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -
> -	*val = dev->res->bin_factor_y;
> -	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_y\n");
> -	return 0;
> -}
> -
>  static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -419,12 +398,6 @@ static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		ret = ov2680_q_exposure(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_BIN_FACTOR_HORZ:
> -		ret = ov2680_g_bin_factor_x(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_BIN_FACTOR_VERT:
> -		ret = ov2680_g_bin_factor_y(&dev->sd, &ctrl->val);
> -		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -449,28 +422,6 @@ static const struct v4l2_ctrl_config ov2680_controls[] = {
>  		.def = 0x00,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_HORZ,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "horizontal binning factor",
> -		.min = 0,
> -		.max = OV2680_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_VERT,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "vertical binning factor",
> -		.min = 0,
> -		.max = OV2680_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
>  	{
>  		.ops = &ctrl_ops,
>  		.id = V4L2_CID_VFLIP,
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> index e65759499d81..da8c3b1d3bcd 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
> @@ -415,24 +415,6 @@ static int ov5693_write_reg_array(struct i2c_client *client,
>  	return __ov5693_flush_reg_array(client, &ctrl);
>  }
>  
> -static int ov5693_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct ov5693_device *dev = to_ov5693_sensor(sd);
> -
> -	*val = ov5693_res[dev->fmt_idx].bin_factor_x;
> -
> -	return 0;
> -}
> -
> -static int ov5693_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
> -{
> -	struct ov5693_device *dev = to_ov5693_sensor(sd);
> -
> -	*val = ov5693_res[dev->fmt_idx].bin_factor_y;
> -
> -	return 0;
> -}
> -
>  static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
>  				  int gain, int digitgain)
>  
> @@ -1014,12 +996,6 @@ static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_FOCUS_STATUS:
>  		ret = ov5693_q_focus_status(&dev->sd, &ctrl->val);
>  		break;
> -	case V4L2_CID_BIN_FACTOR_HORZ:
> -		ret = ov5693_g_bin_factor_x(&dev->sd, &ctrl->val);
> -		break;
> -	case V4L2_CID_BIN_FACTOR_VERT:
> -		ret = ov5693_g_bin_factor_y(&dev->sd, &ctrl->val);
> -		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -1099,28 +1075,6 @@ static const struct v4l2_ctrl_config ov5693_controls[] = {
>  		.def = 0,
>  		.flags = 0,
>  	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_HORZ,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "horizontal binning factor",
> -		.min = 0,
> -		.max = OV5693_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
> -	{
> -		.ops = &ctrl_ops,
> -		.id = V4L2_CID_BIN_FACTOR_VERT,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "vertical binning factor",
> -		.min = 0,
> -		.max = OV5693_BIN_FACTOR_MAX,
> -		.step = 1,
> -		.def = 0,
> -		.flags = 0,
> -	},
>  };
>  
>  static int ov5693_init(struct v4l2_subdev *sd)
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
> index d6da776e9bf4..63b1bcd35399 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
> @@ -1071,10 +1071,6 @@ struct atomisp_sensor_ae_bracketing_lut {
>  /* Query Focus Status */
>  #define V4L2_CID_FOCUS_STATUS              (V4L2_CID_CAMERA_LASTP1 + 14)
>  
> -/* Query sensor's binning factor */
> -#define V4L2_CID_BIN_FACTOR_HORZ	   (V4L2_CID_CAMERA_LASTP1 + 15)
> -#define V4L2_CID_BIN_FACTOR_VERT	   (V4L2_CID_CAMERA_LASTP1 + 16)
> -
>  /* number of frames to skip at stream start */
>  #define V4L2_CID_G_SKIP_FRAMES		   (V4L2_CID_CAMERA_LASTP1 + 17)
>  
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> index d202b2b9ae18..9cb9685d91bb 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> @@ -172,24 +172,6 @@ static struct v4l2_queryctrl ci_v4l2_controls[] = {
>  		.step = 1,
>  		.default_value = 1,
>  	},
> -	{
> -		.id = V4L2_CID_BIN_FACTOR_HORZ,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Horizontal binning factor",
> -		.minimum = 0,
> -		.maximum = 10,
> -		.step = 1,
> -		.default_value = 0,
> -	},
> -	{
> -		.id = V4L2_CID_BIN_FACTOR_VERT,
> -		.type = V4L2_CTRL_TYPE_INTEGER,
> -		.name = "Vertical binning factor",
> -		.minimum = 0,
> -		.maximum = 10,
> -		.step = 1,
> -		.default_value = 0,
> -	},
>  	{
>  		.id = V4L2_CID_2A_STATUS,
>  		.type = V4L2_CTRL_TYPE_BITMASK,
> @@ -1827,8 +1809,6 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
>  		case V4L2_CID_EXPOSURE_ABSOLUTE:
>  		case V4L2_CID_EXPOSURE_AUTO:
>  		case V4L2_CID_IRIS_ABSOLUTE:
> -		case V4L2_CID_BIN_FACTOR_HORZ:
> -		case V4L2_CID_BIN_FACTOR_VERT:
>  		case V4L2_CID_3A_LOCK:
>  		case V4L2_CID_TEST_PATTERN:
>  		case V4L2_CID_TEST_PATTERN_COLOR_R:
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> index cadc468b4c2f..fc9e07bf63ae 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> @@ -574,40 +574,6 @@ static int isp_subdev_set_selection(struct v4l2_subdev *sd,
>  					    sel->target, sel->flags, &sel->r);
>  }
>  
> -static int atomisp_get_sensor_bin_factor(struct atomisp_sub_device *asd)
> -{
> -	struct v4l2_control ctrl = {0};
> -	struct atomisp_device *isp = asd->isp;
> -	int hbin, vbin;
> -	int ret;
> -
> -	if (isp->inputs[asd->input_curr].type == FILE_INPUT ||
> -	    isp->inputs[asd->input_curr].type == TEST_PATTERN)
> -		return 0;
> -
> -	ctrl.id = V4L2_CID_BIN_FACTOR_HORZ;
> -	ret =
> -	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
> -			&ctrl);
> -	hbin = ctrl.value;
> -	ctrl.id = V4L2_CID_BIN_FACTOR_VERT;
> -	ret |=
> -	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
> -			&ctrl);
> -	vbin = ctrl.value;
> -
> -	/*
> -	 * ISP needs to know binning factor from sensor.
> -	 * In case horizontal and vertical sensor's binning factors
> -	 * are different or sensor does not support binning factor CID,
> -	 * ISP will apply default 0 value.
> -	 */
> -	if (ret || hbin != vbin)
> -		hbin = 0;
> -
> -	return hbin;
> -}
> -
>  void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
>  			     struct v4l2_subdev_state *sd_state,
>  			     uint32_t which,
> @@ -645,7 +611,7 @@ void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
>  							 ATOMISP_INPUT_STREAM_GENERAL, ffmt);
>  			atomisp_css_input_set_binning_factor(isp_sd,
>  							     ATOMISP_INPUT_STREAM_GENERAL,
> -							     atomisp_get_sensor_bin_factor(isp_sd));
> +							     0);
>  			atomisp_css_input_set_bayer_order(isp_sd, ATOMISP_INPUT_STREAM_GENERAL,
>  							  fc->bayer_order);
>  			atomisp_css_input_set_format(isp_sd, ATOMISP_INPUT_STREAM_GENERAL,
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info
  2023-01-23 12:51 ` [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info Hans de Goede
@ 2023-01-23 14:33   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:33 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:19PM +0100, Hans de Goede wrote:
> Remove the no longer used bin_factor_x, bin_factor_y and bin_mode members
> from the resolution info inside various atomisp camera sensor drivers.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/gc0310.h    |  6 --
>  drivers/staging/media/atomisp/i2c/gc2235.h    | 27 ---------
>  drivers/staging/media/atomisp/i2c/mt9m114.h   | 12 ----
>  drivers/staging/media/atomisp/i2c/ov2680.h    | 39 ------------
>  drivers/staging/media/atomisp/i2c/ov2722.h    | 30 ----------
>  .../staging/media/atomisp/i2c/ov5693/ov5693.h | 60 -------------------
>  6 files changed, 174 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h
> index 2a559b0d474d..cae480ae6fba 100644
> --- a/drivers/staging/media/atomisp/i2c/gc0310.h
> +++ b/drivers/staging/media/atomisp/i2c/gc0310.h
> @@ -123,9 +123,6 @@ struct gc0310_resolution {
>  	u32 skip_frames;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  	bool used;
>  };
>  
> @@ -386,9 +383,6 @@ static struct gc0310_resolution gc0310_res_preview[] = {
>  		.pixels_per_line = 0x0314,
>  		.lines_per_frame = 0x0213,
>  #endif
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 2,
>  		.regs = gc0310_VGA_30fps,
>  	},
> diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h
> index 8e33eb166bed..55ea422291ba 100644
> --- a/drivers/staging/media/atomisp/i2c/gc2235.h
> +++ b/drivers/staging/media/atomisp/i2c/gc2235.h
> @@ -134,9 +134,6 @@ struct gc2235_resolution {
>  	u32 skip_frames;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  	bool used;
>  };
>  
> @@ -536,9 +533,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1068,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1600_900_30fps,
>  	},
> @@ -552,9 +546,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1368,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1616_1082_30fps,
>  	},
> @@ -567,9 +558,6 @@ static struct gc2235_resolution gc2235_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1368,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1616_1216_30fps,
>  	},
> @@ -593,9 +581,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1068,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1600_900_30fps,
>  	},
> @@ -608,9 +593,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1368,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1616_1082_30fps,
>  	},
> @@ -623,9 +605,6 @@ static struct gc2235_resolution gc2235_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2132,
>  		.lines_per_frame = 1368,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1616_1216_30fps,
>  	},
> @@ -644,9 +623,6 @@ static struct gc2235_resolution gc2235_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 1828,
>  		.lines_per_frame = 888,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_1296_736_30fps,
>  	},
> @@ -659,9 +635,6 @@ static struct gc2235_resolution gc2235_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 1492,
>  		.lines_per_frame = 792,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = gc2235_960_640_30fps,
>  	},
> diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h
> index 831875071cbb..b0cd1b724394 100644
> --- a/drivers/staging/media/atomisp/i2c/mt9m114.h
> +++ b/drivers/staging/media/atomisp/i2c/mt9m114.h
> @@ -316,9 +316,6 @@ struct mt9m114_res_struct {
>  	struct regval_list *regs;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  };
>  
>  /* 2 bytes used for address: 256 bytes total */
> @@ -350,9 +347,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
>  
>  		.pixels_per_line = 0x0640,
>  		.lines_per_frame = 0x0307,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  	},
>  	{
>  		.desc	= "848P",
> @@ -366,9 +360,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
>  
>  		.pixels_per_line = 0x0640,
>  		.lines_per_frame = 0x03E8,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  	},
>  	{
>  		.desc	= "960P",
> @@ -382,9 +373,6 @@ static struct mt9m114_res_struct mt9m114_res[] = {
>  
>  		.pixels_per_line = 0x0644, /* consistent with regs arrays */
>  		.lines_per_frame = 0x03E5, /* consistent with regs arrays */
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  	},
>  };
>  
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 2bc350c67711..596e14453fb3 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -147,9 +147,6 @@ struct ov2680_resolution {
>  	u32 skip_frames;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  };
>  
>  struct ov2680_format {
> @@ -758,9 +755,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.fps = 30,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_1616x1216_30fps,
>  	},
> @@ -771,9 +765,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.fps = 30,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_1616x1082_30fps,
>  	},
> @@ -784,9 +775,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_1616x916_30fps,
>  	},
> @@ -797,9 +785,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_1456x1096_30fps,
>  	},
> @@ -810,9 +795,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_1296x976_30fps,
>  	},
> @@ -823,9 +805,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_720p_30fps,
>  	},
> @@ -836,9 +815,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_800x600_30fps,
>  	},
> @@ -849,9 +825,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_720x592_30fps,
>  	},
> @@ -862,9 +835,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_656x496_30fps,
>  	},
> @@ -875,9 +845,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_QVGA_30fps,
>  	},
> @@ -888,9 +855,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_CIF_30fps,
>  	},
> @@ -901,9 +865,6 @@ static struct ov2680_resolution ov2680_res_preview[] = {
>  		.pix_clk_freq = 66,
>  		.pixels_per_line = 1698,//1704,
>  		.lines_per_frame = 1294,
> -		.bin_factor_x = 0,
> -		.bin_factor_y = 0,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2680_QCIF_30fps,
>  	},
> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
> index 5802cdb0e90c..020743a944c4 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
> @@ -177,9 +177,6 @@ struct ov2722_resolution {
>  	u32 skip_frames;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  	bool used;
>  	int mipi_freq;
>  };
> @@ -1109,9 +1106,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2260,
>  		.lines_per_frame = 1244,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1632_1092_30fps,
>  		.mipi_freq = 422400,
> @@ -1125,9 +1119,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2260,
>  		.lines_per_frame = 1244,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1452_1092_30fps,
>  		.mipi_freq = 422400,
> @@ -1141,9 +1132,6 @@ static struct ov2722_resolution ov2722_res_preview[] = {
>  		.used = 0,
>  		.pixels_per_line = 2068,
>  		.lines_per_frame = 1114,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1080p_30fps,
>  		.mipi_freq = 345600,
> @@ -1167,9 +1155,6 @@ struct ov2722_resolution ov2722_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2260,
>  		.lines_per_frame = 1244,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1632_1092_30fps,
>  		.mipi_freq = 422400,
> @@ -1183,9 +1168,6 @@ struct ov2722_resolution ov2722_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2260,
>  		.lines_per_frame = 1244,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1452_1092_30fps,
>  		.mipi_freq = 422400,
> @@ -1199,9 +1181,6 @@ struct ov2722_resolution ov2722_res_still[] = {
>  		.used = 0,
>  		.pixels_per_line = 2068,
>  		.lines_per_frame = 1114,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1080p_30fps,
>  		.mipi_freq = 345600,
> @@ -1220,9 +1199,6 @@ struct ov2722_resolution ov2722_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2048,
>  		.lines_per_frame = 1184,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_QVGA_30fps,
>  		.mipi_freq = 364800,
> @@ -1236,9 +1212,6 @@ struct ov2722_resolution ov2722_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2048,
>  		.lines_per_frame = 1184,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_480P_30fps,
>  	},
> @@ -1251,9 +1224,6 @@ struct ov2722_resolution ov2722_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2068,
>  		.lines_per_frame = 1114,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.skip_frames = 3,
>  		.regs = ov2722_1080p_30fps,
>  		.mipi_freq = 345600,
> diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> index c9b9dc780f96..5e17eaf8fd6e 100644
> --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
> @@ -198,9 +198,6 @@ struct ov5693_resolution {
>  	int pix_clk_freq;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
> -	u8 bin_factor_x;
> -	u8 bin_factor_y;
> -	u8 bin_mode;
>  	bool used;
>  };
>  
> @@ -1109,9 +1106,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
>  		.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,
>  	},
>  	{
> @@ -1123,9 +1117,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
>  		.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,
>  	},
>  	{
> @@ -1137,9 +1128,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
>  		.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,
>  	},
>  	{
> @@ -1151,9 +1139,6 @@ static struct ov5693_resolution ov5693_res_preview[] = {
>  		.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,
>  	},
>  };
> @@ -1175,9 +1160,6 @@ struct ov5693_resolution ov5693_res_still[] = {
>  		.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,
>  	},
>  	{
> @@ -1189,9 +1171,6 @@ struct ov5693_resolution ov5693_res_still[] = {
>  		.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,
>  	},
>  	{
> @@ -1203,9 +1182,6 @@ struct ov5693_resolution ov5693_res_still[] = {
>  		.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,
>  	},
>  	{
> @@ -1217,9 +1193,6 @@ struct ov5693_resolution ov5693_res_still[] = {
>  		.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,
>  	},
>  	{
> @@ -1231,9 +1204,6 @@ struct ov5693_resolution ov5693_res_still[] = {
>  		.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,
>  	},
>  };
> @@ -1250,9 +1220,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 1,
>  		.regs = ov5693_736x496,
>  	},
>  	{
> @@ -1264,9 +1231,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 1,
>  		.regs = ov5693_336x256,
>  	},
>  	{
> @@ -1278,9 +1242,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 1,
>  		.regs = ov5693_368x304,
>  	},
>  	{
> @@ -1292,9 +1253,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 1,
>  		.regs = ov5693_192x160,
>  	},
>  	{
> @@ -1306,9 +1264,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 0,
>  		.regs = ov5693_1296x736,
>  	},
>  	{
> @@ -1320,9 +1275,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 2,
> -		.bin_factor_y = 2,
> -		.bin_mode = 0,
>  		.regs = ov5693_1296x976,
>  	},
>  	{
> @@ -1334,9 +1286,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.regs = ov5693_1636p_30fps,
>  	},
>  	{
> @@ -1348,9 +1297,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.used = 0,
>  		.pixels_per_line = 2688,
>  		.lines_per_frame = 1984,
> -		.bin_factor_x = 1,
> -		.bin_factor_y = 1,
> -		.bin_mode = 0,
>  		.regs = ov5693_1940x1096,
>  	},
>  	{
> @@ -1362,9 +1308,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.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,
>  	},
>  	{
> @@ -1376,9 +1319,6 @@ struct ov5693_resolution ov5693_res_video[] = {
>  		.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,
>  	},
>  };
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup()
  2023-01-23 12:51 ` [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup() Hans de Goede
@ 2023-01-23 14:35   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:20PM +0100, Hans de Goede wrote:
> If set_fmt() fails make queue_setup() actually return the error instead of
> returning 0.
> 
> This fixes the following oops on set_fmt() failures:
> 
> [ 1060.378662] ------------[ cut here ]------------
> [ 1060.378805] WARNING: CPU: 0 PID: 2080 at drivers/media/common/videobuf2/videobuf2-core.c:840 vb2_core_reqbufs+0x3f7/0x430 [videobuf2_common]
> ...
> [ 1060.381414] RIP: 0010:vb2_core_reqbufs+0x3f7/0x430 [videobuf2_common]
> ...
> [ 1060.382066]  vb2_ioctl_reqbufs+0x9d/0xe0 [videobuf2_v4l2]
> [ 1060.382181]  __video_do_ioctl+0x18e/0x3c0 [videodev]

Should we rather keep this at the beginning of the series?
Just for the logical split of fixes go first.

Yes, I know that it doesn't make much sense for the staging drivers,
but still grouping might help.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_fops.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index 4643bb0db995..682239ea042f 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -80,7 +80,7 @@ static int atomisp_queue_setup(struct vb2_queue *vq,
>  
>  out:
>  	mutex_unlock(&pipe->asd->isp->mutex);
> -	return 0;
> +	return ret;
>  }
>  
>  static int atomisp_buf_init(struct vb2_buffer *vb)
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 13/57] media: atomisp: Remove deferred firmware loading support
  2023-01-23 12:51 ` [PATCH 13/57] media: atomisp: Remove deferred firmware loading support Hans de Goede
@ 2023-01-23 14:37   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:37 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:21PM +0100, Hans de Goede wrote:
> Make atomisp behave like any othet drivers and have it load the firmware

other

> at probe time (as it was already doing by default).
> 
> The deferred firmware loading support needlessly complicates the
> v4l2_file_operations.open callback (atomisp_open()), getting in
> the way of allowing multiple opens like a normal v4l2 device would.

So it actually removes that variable and accompanying code w.o.
changing behaviour (as default).

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../staging/media/atomisp/pci/atomisp_fops.c  | 25 -----------
>  .../staging/media/atomisp/pci/atomisp_fops.h  |  2 -
>  .../staging/media/atomisp/pci/atomisp_v4l2.c  | 42 +++++++------------
>  3 files changed, 14 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index 682239ea042f..036ad339b344 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -757,25 +757,6 @@ static int atomisp_open(struct file *file)
>  	mutex_lock(&isp->mutex);
>  
>  	asd->subdev.devnode = vdev;
> -	/* Deferred firmware loading case. */
> -	if (isp->css_env.isp_css_fw.bytes == 0) {
> -		dev_err(isp->dev, "Deferred firmware load.\n");
> -		isp->firmware = atomisp_load_firmware(isp);
> -		if (!isp->firmware) {
> -			dev_err(isp->dev, "Failed to load ISP firmware.\n");
> -			ret = -ENOENT;
> -			goto error;
> -		}
> -		ret = atomisp_css_load_firmware(isp);
> -		if (ret) {
> -			dev_err(isp->dev, "Failed to init css.\n");
> -			goto error;
> -		}
> -		/* No need to keep FW in memory anymore. */
> -		release_firmware(isp->firmware);
> -		isp->firmware = NULL;
> -		isp->css_env.isp_css_fw.data = NULL;
> -	}
>  
>  	if (!isp->input_cnt) {
>  		dev_err(isp->dev, "no camera attached\n");
> @@ -901,12 +882,6 @@ static int atomisp_release(struct file *file)
>  
>  	atomisp_destroy_pipes_stream_force(asd);
>  
> -	if (defer_fw_load) {
> -		ia_css_unload_firmware();
> -		isp->css_env.isp_css_fw.data = NULL;
> -		isp->css_env.isp_css_fw.bytes = 0;
> -	}
> -
>  	ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
>  	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
>  		dev_warn(isp->dev, "Failed to power-off flash\n");
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp_fops.h
> index 10e43126b693..2efc5245e571 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h
> @@ -33,6 +33,4 @@ int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd);
>  
>  extern const struct v4l2_file_operations atomisp_fops;
>  
> -extern bool defer_fw_load;
> -
>  #endif /* __ATOMISP_FOPS_H__ */
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> index aa05c69a5c6b..2a949d3dc5d1 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> @@ -58,12 +58,6 @@ static uint skip_fwload;
>  module_param(skip_fwload, uint, 0644);
>  MODULE_PARM_DESC(skip_fwload, "Skip atomisp firmware load");
>  
> -/* memory optimization: deferred firmware loading */
> -bool defer_fw_load;
> -module_param(defer_fw_load, bool, 0644);
> -MODULE_PARM_DESC(defer_fw_load,
> -		 "Defer FW loading until device is opened (default:disable)");
> -
>  /* cross componnet debug message flag */
>  int dbg_level;
>  module_param(dbg_level, int, 0644);
> @@ -1514,21 +1508,17 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
>  	isp->max_isr_latency = ATOMISP_MAX_ISR_LATENCY;
>  
>  	/* Load isp firmware from user space */
> -	if (!defer_fw_load) {
> -		isp->firmware = atomisp_load_firmware(isp);
> -		if (!isp->firmware) {
> -			err = -ENOENT;
> -			dev_dbg(&pdev->dev, "Firmware load failed\n");
> -			goto load_fw_fail;
> -		}
> +	isp->firmware = atomisp_load_firmware(isp);
> +	if (!isp->firmware) {
> +		err = -ENOENT;
> +		dev_dbg(&pdev->dev, "Firmware load failed\n");
> +		goto load_fw_fail;
> +	}
>  
> -		err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
> -		if (err) {
> -			dev_dbg(&pdev->dev, "Firmware version check failed\n");
> -			goto fw_validation_fail;
> -		}
> -	} else {
> -		dev_info(&pdev->dev, "Firmware load will be deferred\n");
> +	err = sh_css_check_firmware_version(isp->dev, isp->firmware->data);
> +	if (err) {
> +		dev_dbg(&pdev->dev, "Firmware version check failed\n");
> +		goto fw_validation_fail;
>  	}
>  
>  	pci_set_master(pdev);
> @@ -1628,14 +1618,10 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
>  	}
>  
>  	/* Load firmware into ISP memory */
> -	if (!defer_fw_load) {
> -		err = atomisp_css_load_firmware(isp);
> -		if (err) {
> -			dev_err(&pdev->dev, "Failed to init css.\n");
> -			goto css_init_fail;
> -		}
> -	} else {
> -		dev_dbg(&pdev->dev, "Skip css init.\n");
> +	err = atomisp_css_load_firmware(isp);
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to init css.\n");
> +		goto css_init_fail;
>  	}
>  	/* Clear FW image from memory */
>  	release_firmware(isp->firmware);
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper()
  2023-01-23 12:51 ` [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper() Hans de Goede
@ 2023-01-23 14:38   ` Andy Shevchenko
  2023-01-24 11:09     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:38 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:22PM +0100, Hans de Goede wrote:
> Check buffer index is in range inside atomisp_qbuf_wrapper() before
> using it do index pipe->frame_request_config_id[].

...

>  	/* FIXME this abuse of buf->reserved2 comes from the original atomisp buffer handling */

Does the comment belong to this check?

> +	if (buf->index >= vdev->queue->num_buffers)
> +		return -EINVAL;
> +
>  	if (!atomisp_is_vf_pipe(pipe) &&
>  	    (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
>  		/* this buffer will have a per-frame parameter */

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT
  2023-01-23 12:51 ` [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT Hans de Goede
@ 2023-01-23 14:40   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 14:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:15PM +0100, Hans de Goede wrote:
> On BYT on poweron/runtime-resume the code is doing:
> 
> 1. Do nothing
> 2. msleep(10)
> 3. Start actual poweron sequence
> 
> Since the runtime resume can happen at any moment, waiting 10ms
> after it does not really make any sense.
> 
> According to both the comment and to:
> https://github.com/intel/ProductionKernelQuilts/blob/master/uefi/cht-m1stable/patches/cam-0341-atomisp-WA-sleep-10ms-when-power-up-ISP-on-byt.patch
> 
> Which is the patch which originally added this this was added
> as a workaround for a single test failing on a single model
> tablet/laptop. So lets just drop this.

Since it's for BYT platforms and you have plenty to test, I believe it's the
right thing to do.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> index 9eea8ffbc3d6..aa05c69a5c6b 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> @@ -665,14 +665,6 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable)
>  		msleep(20);
>  	}
>  
> -	/*
> -	 * FIXME:WA for ECS28A, with this sleep, CTS
> -	 * android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceAbort
> -	 * PASS, no impact on other platforms
> -	 */
> -	if (IS_BYT && enable)
> -		msleep(10);
> -
>  	/* Write to ISPSSPM0 bit[1:0] to power on/off the IUNIT */
>  	iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0,
>  			val, MRFLD_ISPSSPM0_ISPSSC_MASK);
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe()
  2023-01-23 12:51 ` [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe() Hans de Goede
@ 2023-01-23 15:30   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 15:30 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:23PM +0100, Hans de Goede wrote:
> atomisp_init_pipe() does 3 things:
> 
> 1. Init a bunch of list-heads / locks
> 2. Init the vb_queue for the videodev (aka pipe)
> 3. zero the per-frame parameters related variables of the pipe
> 
> 1. and 2. really should not be done at file-open time, but once at probe.
> Currently the code is getting away with doing this on every videodev-open
> because only 1 open is allowed at a time.
> 
> 1. is already done at probe time by atomisp_init_subdev_pipe(), move 2. to
> atomisp_init_subdev_pipe() so that it is also done once at probe.
> 
> As for 3. The per-frame parameters can only be set from a qbuf ioctl,
> which can only happen after a reqbufs ioctl and atomisp_buf_cleanup
> already zeros the per-frame parameters when the buffers are released,
> so 3. is not necessary at all.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../staging/media/atomisp/pci/atomisp_fops.c  | 40 +--------------
>  .../staging/media/atomisp/pci/atomisp_fops.h  |  1 +
>  .../media/atomisp/pci/atomisp_subdev.c        | 49 +++++++++++++++----
>  3 files changed, 41 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index 036ad339b344..7f4934ff9cab 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -624,7 +624,7 @@ static void atomisp_buf_cleanup(struct vb2_buffer *vb)
>  	hmm_free(frame->data);
>  }
>  
> -static const struct vb2_ops atomisp_vb2_ops = {
> +const struct vb2_ops atomisp_vb2_ops = {
>  	.queue_setup		= atomisp_queue_setup,
>  	.buf_init		= atomisp_buf_init,
>  	.buf_cleanup		= atomisp_buf_cleanup,
> @@ -633,40 +633,6 @@ static const struct vb2_ops atomisp_vb2_ops = {
>  	.stop_streaming		= atomisp_stop_streaming,
>  };
>  
> -static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
> -{
> -	int ret;
> -
> -	/* init locks */
> -	spin_lock_init(&pipe->irq_lock);
> -	mutex_init(&pipe->vb_queue_mutex);
> -
> -	/* Init videobuf2 queue structure */
> -	pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> -	pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR;
> -	pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame);
> -	pipe->vb_queue.ops = &atomisp_vb2_ops;
> -	pipe->vb_queue.mem_ops = &vb2_vmalloc_memops;
> -	pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> -	ret = vb2_queue_init(&pipe->vb_queue);
> -	if (ret)
> -		return ret;
> -
> -	pipe->vdev.queue = &pipe->vb_queue;
> -	pipe->vdev.queue->lock = &pipe->vb_queue_mutex;
> -
> -	INIT_LIST_HEAD(&pipe->activeq);
> -	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
> -	INIT_LIST_HEAD(&pipe->per_frame_params);
> -	memset(pipe->frame_request_config_id, 0,
> -	       VIDEO_MAX_FRAME * sizeof(unsigned int));
> -	memset(pipe->frame_params, 0,
> -	       VIDEO_MAX_FRAME *
> -	       sizeof(struct atomisp_css_params_with_list *));
> -
> -	return 0;
> -}
> -
>  static void atomisp_dev_init_struct(struct atomisp_device *isp)
>  {
>  	unsigned int i;
> @@ -773,10 +739,6 @@ static int atomisp_open(struct file *file)
>  		return -EBUSY;
>  	}
>  
> -	ret = atomisp_init_pipe(pipe);
> -	if (ret)
> -		goto error;
> -
>  	if (atomisp_dev_users(isp)) {
>  		dev_dbg(isp->dev, "skip init isp in open\n");
>  		goto init_subdev;
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp_fops.h
> index 2efc5245e571..883c1851c1c9 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h
> @@ -31,6 +31,7 @@ unsigned int atomisp_sub_dev_users(struct atomisp_sub_device *asd);
>  
>  int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd);
>  
> +extern const struct vb2_ops atomisp_vb2_ops;
>  extern const struct v4l2_file_operations atomisp_fops;
>  
>  #endif /* __ATOMISP_FOPS_H__ */
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> index fc9e07bf63ae..c32db4ffb778 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> @@ -25,9 +25,11 @@
>  
>  #include <media/v4l2-event.h>
>  #include <media/v4l2-mediabus.h>
> +#include <media/videobuf2-vmalloc.h>
>  #include "atomisp_cmd.h"
>  #include "atomisp_common.h"
>  #include "atomisp_compat.h"
> +#include "atomisp_fops.h"
>  #include "atomisp_internal.h"
>  
>  const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
> @@ -1023,14 +1025,31 @@ static const struct v4l2_ctrl_config ctrl_depth_mode = {
>  	.def = 0,
>  };
>  
> -static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
> -				     struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
> +static int atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
> +				    struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
>  {
> +	int ret;
> +
>  	pipe->type = buf_type;
>  	pipe->asd = asd;
>  	pipe->isp = asd->isp;
>  	spin_lock_init(&pipe->irq_lock);
>  	mutex_init(&pipe->vb_queue_mutex);
> +
> +	/* Init videobuf2 queue structure */
> +	pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> +	pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR;
> +	pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame);
> +	pipe->vb_queue.ops = &atomisp_vb2_ops;
> +	pipe->vb_queue.mem_ops = &vb2_vmalloc_memops;
> +	pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
> +	ret = vb2_queue_init(&pipe->vb_queue);
> +	if (ret)
> +		return ret;
> +
> +	pipe->vdev.queue = &pipe->vb_queue;
> +	pipe->vdev.queue->lock = &pipe->vb_queue_mutex;
> +
>  	INIT_LIST_HEAD(&pipe->buffers_in_css);
>  	INIT_LIST_HEAD(&pipe->activeq);
>  	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
> @@ -1040,6 +1059,8 @@ static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
>  	memset(pipe->frame_params,
>  	       0, VIDEO_MAX_FRAME *
>  	       sizeof(struct atomisp_css_params_with_list *));
> +
> +	return 0;
>  }
>  
>  /*
> @@ -1085,17 +1106,25 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
>  	if (ret < 0)
>  		return ret;
>  
> -	atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
> -				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
> +				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	if (ret)
> +		return ret;
>  
> -	atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
> -				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
> +				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	if (ret)
> +		return ret;
>  
> -	atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
> -				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
> +				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	if (ret)
> +		return ret;
>  
> -	atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
> -				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	ret = atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
> +				       V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +	if (ret)
> +		return ret;
>  
>  	ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE",
>  				 ATOMISP_RUN_MODE_STILL_CAPTURE);
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls
  2023-01-23 12:51 ` [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls Hans de Goede
@ 2023-01-23 17:41   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:41 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:24PM +0100, Hans de Goede wrote:
> The memory for all of struct atomisp_video_pipe is kzalloc()-ed in
> atomisp_subdev_init() so there is no need to memset parts of
> struct atomisp_video_pipe to 0.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_subdev.c | 5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> index c32db4ffb778..eb8f319fca5c 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> @@ -1054,11 +1054,6 @@ static int atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
>  	INIT_LIST_HEAD(&pipe->activeq);
>  	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
>  	INIT_LIST_HEAD(&pipe->per_frame_params);
> -	memset(pipe->frame_request_config_id,
> -	       0, VIDEO_MAX_FRAME * sizeof(unsigned int));
> -	memset(pipe->frame_params,
> -	       0, VIDEO_MAX_FRAME *
> -	       sizeof(struct atomisp_css_params_with_list *));
>  
>  	return 0;
>  }
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd
  2023-01-23 12:51 ` [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd Hans de Goede
@ 2023-01-23 17:42   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:42 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:25PM +0100, Hans de Goede wrote:
> Calling v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode) when
> the stream is already active (through another /dev/video# node) causes
> the stream to stop.
> 
> Move the call to set the default run-mode so that it is only done
> on the first open of one of the 4 /dev/video# nodes of one of
> the 2 streams (atomisp-sub-devices / asd-s).

As mentioned before, perhaps move it closer to the beginning of the series?

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Fixes: 2c45e343c581 ("media: atomisp: set per-device's default mode")
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_fops.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index 7f4934ff9cab..78af97a64362 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -764,13 +764,13 @@ static int atomisp_open(struct file *file)
>  		goto done;
>  
>  	atomisp_subdev_init_struct(asd);

+ Blank line?

> +	/* Ensure that a mode is set */
> +	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
>  
>  done:
>  	pipe->users++;
>  	mutex_unlock(&isp->mutex);
>  
> -	/* Ensure that a mode is set */
> -	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
>  
>  	return 0;
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback
  2023-01-23 12:51 ` [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback Hans de Goede
@ 2023-01-23 17:49   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:49 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:27PM +0100, Hans de Goede wrote:
> The s_power callback for v4l2-subdevs has been deprecated, allow sensor
> drivers without a s_power callback to work by ignoring the -ENOIOCTLCMD
> return value.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_fops.c  | 2 +-
>  drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> index 833c7aac8f0a..ce01479bdd68 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c
> @@ -832,7 +832,7 @@ static int atomisp_release(struct file *file)
>  	if (isp->inputs[asd->input_curr].asd == asd) {
>  		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
>  				       core, s_power, 0);
> -		if (ret)
> +		if (ret && ret != -ENOIOCTLCMD)
>  			dev_warn(isp->dev, "Failed to power-off sensor\n");
>  
>  		/* clear the asd field to show this camera is not used */
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> index d0dd3dbd6f6a..77856cbc5ba7 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> @@ -700,7 +700,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
>  	    asd->input_curr != input) {
>  		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
>  				       core, s_power, 0);
> -		if (ret)
> +		if (ret && ret != -ENOIOCTLCMD)
>  			dev_warn(isp->dev,
>  				 "Failed to power-off sensor\n");
>  		/* clear the asd field to show this camera is not used */
> @@ -709,7 +709,7 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
>  
>  	/* powe on the new sensor */
>  	ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
> -	if (ret) {
> +	if (ret && ret != -ENOIOCTLCMD) {
>  		dev_err(isp->dev, "Failed to power-on sensor\n");
>  		return ret;
>  	}
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC
  2023-01-23 12:51 ` [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC Hans de Goede
@ 2023-01-23 17:51   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:51 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:28PM +0100, Hans de Goede wrote:
> The Crystal Cove PMIC used on some BYT/CHT devices has different revisions
> when paired with Bay Trail (BYT) vs Cherry Trail (CHT) SoCs.
> 
> The current hardcoded values are only valid for CHT devices, change
> the code so that it uses the correct register values on both BYT and CHT.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
One nit-pick below.

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/pci/atomisp_gmin_platform.c | 22 +++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> index 3d41fab661cf..6116d3c62315 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> @@ -57,8 +57,10 @@ enum clock_rate {
>  #define LDO_1P8V_OFF	0x58 /* ... bottom bit is "enabled" */
>  
>  /* CRYSTAL COVE PMIC register set */
> -#define CRYSTAL_1P8V_REG	0x57
> -#define CRYSTAL_2P8V_REG	0x5d
> +#define CRYSTAL_BYT_1P8V_REG	0x5d
> +#define CRYSTAL_BYT_2P8V_REG	0x66
> +#define CRYSTAL_CHT_1P8V_REG	0x57
> +#define CRYSTAL_CHT_2P8V_REG	0x5d
>  #define CRYSTAL_ON		0x63
>  #define CRYSTAL_OFF		0x62

I would split to groups like this

#define CRYSTAL_BYT_1P8V_REG	0x5d
#define CRYSTAL_BYT_2P8V_REG	0x66

#define CRYSTAL_CHT_1P8V_REG	0x57
#define CRYSTAL_CHT_2P8V_REG	0x5d

#define CRYSTAL_ON		0x63
#define CRYSTAL_OFF		0x62

> @@ -843,6 +845,7 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
>  	struct gmin_subdev *gs = find_gmin_subdev(subdev);
>  	int ret;
>  	int value;
> +	int reg;
>  
>  	if (!gs || gs->v1p8_on == on)
>  		return 0;
> @@ -898,10 +901,15 @@ static int gmin_v1p8_ctrl(struct v4l2_subdev *subdev, int on)
>  				     LDO10_REG, value, 0xff);
>  		break;
>  	case PMIC_CRYSTALCOVE:
> +		if (IS_ISP2401)
> +			reg = CRYSTAL_CHT_1P8V_REG;
> +		else
> +			reg = CRYSTAL_BYT_1P8V_REG;
> +
>  		value = on ? CRYSTAL_ON : CRYSTAL_OFF;
>  
>  		ret = gmin_i2c_write(subdev->dev, gs->pwm_i2c_addr,
> -				     CRYSTAL_1P8V_REG, value, 0xff);
> +				     reg, value, 0xff);
>  		break;
>  	default:
>  		dev_err(subdev->dev, "Couldn't set power mode for v1p8\n");
> @@ -918,6 +926,7 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
>  	struct gmin_subdev *gs = find_gmin_subdev(subdev);
>  	int ret;
>  	int value;
> +	int reg;
>  
>  	if (WARN_ON(!gs))
>  		return -ENODEV;
> @@ -974,10 +983,15 @@ static int gmin_v2p8_ctrl(struct v4l2_subdev *subdev, int on)
>  				     LDO9_REG, value, 0xff);
>  		break;
>  	case PMIC_CRYSTALCOVE:
> +		if (IS_ISP2401)
> +			reg = CRYSTAL_CHT_2P8V_REG;
> +		else
> +			reg = CRYSTAL_BYT_2P8V_REG;
> +
>  		value = on ? CRYSTAL_ON : CRYSTAL_OFF;
>  
>  		ret = gmin_i2c_write(subdev->dev, gs->pwm_i2c_addr,
> -				     CRYSTAL_2P8V_REG, value, 0xff);
> +				     reg, value, 0xff);
>  		break;
>  	default:
>  		dev_err(subdev->dev, "Couldn't set power mode for v2p8\n");
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev()
  2023-01-23 12:51 ` [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev() Hans de Goede
@ 2023-01-23 17:53   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:53 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:29PM +0100, Hans de Goede wrote:
> atomisp_gmin_find_subdev() can be used to lookup a subdev
> given its i2c-adapter + i2c-client-address.
> 
> But the only caller of it reads this from the intel_v4l2_subdev_table
> struct and that same struct already contains a pointer to the v4l2_subdev.
> 
> So this function is not necessary, drop it and modify its only caller
> to directly take the subdev from the intel_v4l2_subdev_table struct.
> 
> Also drop struct intel_v4l2_subdev_i2c_board_info since that now no
> longer is used.

Cool!

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../include/linux/atomisp_gmin_platform.h     |  2 -
>  .../atomisp/include/linux/atomisp_platform.h  |  6 ---
>  .../media/atomisp/pci/atomisp_gmin_platform.c | 27 ----------
>  .../staging/media/atomisp/pci/atomisp_v4l2.c  | 54 +++----------------
>  4 files changed, 7 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
> index 5463d11d4295..64bd54835c32 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
> @@ -21,8 +21,6 @@
>  int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
>  				struct camera_sensor_platform_data *plat_data,
>  				enum intel_v4l2_subdev_type type);
> -struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
> -	struct i2c_board_info *board_info);
>  int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd);
>  int gmin_get_var_int(struct device *dev, bool is_gmin,
>  		     const char *var, int def);
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> index 559a497975c5..82973aa0e1eb 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> @@ -125,13 +125,7 @@ struct intel_v4l2_subdev_id {
>  	enum atomisp_camera_port    port;
>  };
>  
> -struct intel_v4l2_subdev_i2c_board_info {
> -	struct i2c_board_info board_info;
> -	int i2c_adapter_id;
> -};
> -
>  struct intel_v4l2_subdev_table {
> -	struct intel_v4l2_subdev_i2c_board_info v4l2_subdev;
>  	enum intel_v4l2_subdev_type type;
>  	enum atomisp_camera_port port;
>  	struct v4l2_subdev *subdev;
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> index 6116d3c62315..234088711f29 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> @@ -147,7 +147,6 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
>  				enum intel_v4l2_subdev_type type)
>  {
>  	int i;
> -	struct i2c_board_info *bi;
>  	struct gmin_subdev *gs;
>  	struct i2c_client *client = v4l2_get_subdevdata(subdev);
>  	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> @@ -181,36 +180,10 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
>  	pdata.subdevs[i].type = type;
>  	pdata.subdevs[i].port = gs->csi_port;
>  	pdata.subdevs[i].subdev = subdev;
> -	pdata.subdevs[i].v4l2_subdev.i2c_adapter_id = client->adapter->nr;
> -
> -	/* Convert i2c_client to i2c_board_info */
> -	bi = &pdata.subdevs[i].v4l2_subdev.board_info;
> -	memcpy(bi->type, client->name, I2C_NAME_SIZE);
> -	bi->flags = client->flags;
> -	bi->addr = client->addr;
> -	bi->irq = client->irq;
> -	bi->platform_data = plat_data;
> -
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(atomisp_register_i2c_module);
>  
> -struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
> -	struct i2c_board_info *board_info)
> -{
> -	int i;
> -
> -	for (i = 0; i < MAX_SUBDEVS && pdata.subdevs[i].type; i++) {
> -		struct intel_v4l2_subdev_table *sd = &pdata.subdevs[i];
> -
> -		if (sd->v4l2_subdev.i2c_adapter_id == adapter->nr &&
> -		    sd->v4l2_subdev.board_info.addr == board_info->addr)
> -			return sd->subdev;
> -	}
> -	return NULL;
> -}
> -EXPORT_SYMBOL_GPL(atomisp_gmin_find_subdev);
> -
>  int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd)
>  {
>  	int i, j;
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> index 2a949d3dc5d1..ba628f7cf385 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
> @@ -937,45 +937,9 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
>  	/* FIXME: should, instead, use I2C probe */
>  
>  	for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) {
> -		struct v4l2_subdev *subdev;
> -		struct i2c_board_info *board_info =
> -			    &subdevs->v4l2_subdev.board_info;
> -		struct i2c_adapter *adapter =
> -		    i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id);
> -
> -		dev_info(isp->dev, "Probing Subdev %s\n", board_info->type);
> -
> -		if (!adapter) {
> -			dev_err(isp->dev,
> -				"Failed to find i2c adapter for subdev %s\n",
> -				board_info->type);
> -			break;
> -		}
> -
> -		/* In G-Min, the sensor devices will already be probed
> -		 * (via ACPI) and registered, do not create new
> -		 * ones */
> -		subdev = atomisp_gmin_find_subdev(adapter, board_info);
> -		if (!subdev) {
> -			dev_warn(isp->dev, "Subdev %s not found\n",
> -				 board_info->type);
> -			continue;
> -		}
> -		ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdev);
> -		if (ret) {
> -			dev_warn(isp->dev, "Subdev %s detection fail\n",
> -				 board_info->type);
> +		ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdevs->subdev);
> +		if (ret)
>  			continue;
> -		}
> -
> -		if (!subdev) {
> -			dev_warn(isp->dev, "Subdev %s detection fail\n",
> -				 board_info->type);
> -			continue;
> -		}
> -
> -		dev_info(isp->dev, "Subdev %s successfully register\n",
> -			 board_info->type);
>  
>  		switch (subdevs->type) {
>  		case RAW_CAMERA:
> @@ -992,7 +956,7 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
>  
>  			isp->inputs[isp->input_cnt].type = subdevs->type;
>  			isp->inputs[isp->input_cnt].port = subdevs->port;
> -			isp->inputs[isp->input_cnt].camera = subdev;
> +			isp->inputs[isp->input_cnt].camera = subdevs->subdev;
>  			isp->inputs[isp->input_cnt].sensor_index = 0;
>  			/*
>  			 * initialize the subdev frame size, then next we can
> @@ -1004,22 +968,18 @@ static int atomisp_subdev_probe(struct atomisp_device *isp)
>  			break;
>  		case CAMERA_MOTOR:
>  			if (isp->motor) {
> -				dev_warn(isp->dev,
> -					 "too many atomisp motors, ignored %s\n",
> -					 board_info->type);
> +				dev_warn(isp->dev, "too many atomisp motors\n");
>  				continue;
>  			}
> -			isp->motor = subdev;
> +			isp->motor = subdevs->subdev;
>  			break;
>  		case LED_FLASH:
>  		case XENON_FLASH:
>  			if (isp->flash) {
> -				dev_warn(isp->dev,
> -					 "too many atomisp flash devices, ignored %s\n",
> -					 board_info->type);
> +				dev_warn(isp->dev, "too many atomisp flash devices\n");
>  				continue;
>  			}
> -			isp->flash = subdev;
> +			isp->flash = subdevs->subdev;
>  			break;
>  		default:
>  			dev_dbg(isp->dev, "unknown subdev probed\n");
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper
  2023-01-23 12:51 ` [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper Hans de Goede
@ 2023-01-23 17:55   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:55 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:30PM +0100, Hans de Goede wrote:
> The DSDT of all Windows BYT / CHT devices which I have seen has proper
> ACPI powermagement for the clk and regulators used by the sensors.
> 
> So there is no need for the whole custom atomisp_gmin custom code to
> disable the ACPI pm and directly poke at the PMIC for this.
> 
> Add new atomisp_register_sensor_no_gmin() + atomisp_unregister_subdev()
> helpers which allow registering a sensor with the atomisp code without
> using any of the atomisp_gmin power-management code.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../atomisp/include/linux/atomisp_platform.h  |  4 ++
>  .../media/atomisp/pci/atomisp_gmin_platform.c | 61 +++++++++++++++++++
>  2 files changed, 65 insertions(+)
> 
> diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> index 82973aa0e1eb..539b21d39d3b 100644
> --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h
> @@ -211,6 +211,10 @@ struct camera_mipi_info {
>  };
>  
>  const struct atomisp_platform_data *atomisp_get_platform_data(void);
> +int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
> +				    enum atomisp_input_format format,
> +				    enum atomisp_bayer_order bayer_order);
> +void atomisp_unregister_subdev(struct v4l2_subdev *subdev);
>  
>  /* API from old platform_camera.h, new CPUID implementation */
>  #define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> index 234088711f29..1e943c423893 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
> @@ -1082,6 +1082,67 @@ static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag)
>  	return 0;
>  }
>  
> +int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
> +				    enum atomisp_input_format format,
> +				    enum atomisp_bayer_order bayer_order)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(subdev);
> +	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> +	int i, ret, clock_num, port = 0;
> +
> +	if (adev) {
> +		/* Get ACPI _PR0 derived clock to determine the csi_port default */
> +		if (acpi_device_power_manageable(adev)) {
> +			clock_num = atomisp_get_acpi_power(&client->dev);
> +
> +			/* Compare clock to CsiPort 1 pmc-clock used in the CHT/BYT reference designs */
> +			if (IS_ISP2401)
> +				port = clock_num == 4 ? 1 : 0;
> +			else
> +				port = clock_num == 0 ? 1 : 0;
> +		}
> +
> +		port = gmin_get_var_int(&client->dev, false, "CsiPort", port);
> +		lanes = gmin_get_var_int(&client->dev, false, "CsiLanes", lanes);
> +	}
> +
> +	for (i = 0; i < MAX_SUBDEVS; i++)
> +		if (!pdata.subdevs[i].type)
> +			break;
> +
> +	if (i >= MAX_SUBDEVS) {
> +		dev_err(&client->dev, "Error too many subdevs already registered\n");
> +		return -ENOMEM;
> +	}
> +
> +	ret = camera_sensor_csi_alloc(subdev, port, lanes, format, bayer_order);
> +	if (ret)
> +		return ret;
> +
> +	pdata.subdevs[i].type = RAW_CAMERA;
> +	pdata.subdevs[i].port = port;
> +	pdata.subdevs[i].subdev = subdev;
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(atomisp_register_sensor_no_gmin);
> +
> +void atomisp_unregister_subdev(struct v4l2_subdev *subdev)
> +{
> +	int i;
> +
> +	for (i = 0; i < MAX_SUBDEVS; i++) {
> +		if (pdata.subdevs[i].subdev != subdev)
> +			continue;
> +
> +		camera_sensor_csi_free(subdev);
> +		pdata.subdevs[i].subdev = NULL;
> +		pdata.subdevs[i].type = 0;
> +		pdata.subdevs[i].port = 0;
> +		break;
> +	}
> +}
> +EXPORT_SYMBOL_GPL(atomisp_unregister_subdev);
> +
>  static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev,
>  	char *camera_module)
>  {
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails
  2023-01-23 12:51 ` [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails Hans de Goede
@ 2023-01-23 17:56   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:56 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:31PM +0100, Hans de Goede wrote:
> The videobuf2-core expects buffers to be put back in the queued state
> when the vb2 start_streaming callback fails. But the atomisp
> atomisp_flush_video_pipe() would unconditionally return them to the core
> in an error state.
> 
> This triggers the following warning in the videobuf2-core:
> 
> drivers/media/common/videobuf2/videobuf2-core.c:1652:
> 	/*
> 	 * If done_list is not empty, then start_streaming() didn't call
> 	 * vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED) but STATE_ERROR or
> 	 * STATE_DONE.
> 	 */
> 	WARN_ON(!list_empty(&q->done_list));
> 
> Fix this by adding a state argument to atomisp_flush_video_pipe() and use
> VB2_BUF_STATE_QUEUED as state when atomisp_start_streaming() fails.

Also sounds like a fix.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_cmd.c | 17 +++++++++--------
>  drivers/staging/media/atomisp/pci/atomisp_cmd.h |  3 ++-
>  .../staging/media/atomisp/pci/atomisp_ioctl.c   |  4 ++--
>  3 files changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> index 01c9845b9f28..b9e7ad57040e 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> @@ -679,7 +679,8 @@ void atomisp_buffer_done(struct ia_css_frame *frame, enum vb2_buffer_state state
>  	vb2_buffer_done(&frame->vb.vb2_buf, state);
>  }
>  
> -void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_frames)
> +void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, enum vb2_buffer_state state,
> +			      bool warn_on_css_frames)
>  {
>  	struct ia_css_frame *frame, *_frame;
>  	unsigned long irqflags;
> @@ -689,15 +690,15 @@ void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_
>  	list_for_each_entry_safe(frame, _frame, &pipe->buffers_in_css, queue) {
>  		if (warn_on_css_frames)
>  			dev_warn(pipe->isp->dev, "Warning: CSS frames queued on flush\n");
> -		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
> +		atomisp_buffer_done(frame, state);
>  	}
>  
>  	list_for_each_entry_safe(frame, _frame, &pipe->activeq, queue)
> -		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
> +		atomisp_buffer_done(frame, state);
>  
>  	list_for_each_entry_safe(frame, _frame, &pipe->buffers_waiting_for_param, queue) {
>  		pipe->frame_request_config_id[frame->vb.vb2_buf.index] = 0;
> -		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
> +		atomisp_buffer_done(frame, state);
>  	}
>  
>  	spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
> @@ -706,10 +707,10 @@ void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_
>  /* Returns queued buffers back to video-core */
>  void atomisp_flush_bufs_and_wakeup(struct atomisp_sub_device *asd)
>  {
> -	atomisp_flush_video_pipe(&asd->video_out_capture, false);
> -	atomisp_flush_video_pipe(&asd->video_out_vf, false);
> -	atomisp_flush_video_pipe(&asd->video_out_preview, false);
> -	atomisp_flush_video_pipe(&asd->video_out_video_capture, false);
> +	atomisp_flush_video_pipe(&asd->video_out_capture, VB2_BUF_STATE_ERROR, false);
> +	atomisp_flush_video_pipe(&asd->video_out_vf, VB2_BUF_STATE_ERROR, false);
> +	atomisp_flush_video_pipe(&asd->video_out_preview, VB2_BUF_STATE_ERROR, false);
> +	atomisp_flush_video_pipe(&asd->video_out_video_capture, VB2_BUF_STATE_ERROR, false);
>  }
>  
>  /* clean out the parameters that did not apply */
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> index a10577df10cb..733b9f8cd06f 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
> @@ -57,7 +57,8 @@ struct atomisp_video_pipe *atomisp_to_video_pipe(struct video_device *dev);
>  int atomisp_reset(struct atomisp_device *isp);
>  int atomisp_buffers_in_css(struct atomisp_video_pipe *pipe);
>  void atomisp_buffer_done(struct ia_css_frame *frame, enum vb2_buffer_state state);
> -void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, bool warn_on_css_frames);
> +void atomisp_flush_video_pipe(struct atomisp_video_pipe *pipe, enum vb2_buffer_state state,
> +			      bool warn_on_css_frames);
>  void atomisp_flush_bufs_and_wakeup(struct atomisp_sub_device *asd);
>  void atomisp_clear_css_buffer_counters(struct atomisp_sub_device *asd);
>  
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> index 77856cbc5ba7..c15bb0b7458b 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
> @@ -1339,7 +1339,7 @@ int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
>  
>  	ret = atomisp_css_start(asd, css_pipe_id, false);
>  	if (ret) {
> -		atomisp_flush_video_pipe(pipe, true);
> +		atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);
>  		goto out_unlock;
>  	}
>  
> @@ -1515,7 +1515,7 @@ void atomisp_stop_streaming(struct vb2_queue *vq)
>  	css_pipe_id = atomisp_get_css_pipe_id(asd);
>  	atomisp_css_stop(asd, css_pipe_id, false);
>  
> -	atomisp_flush_video_pipe(pipe, true);
> +	atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true);
>  
>  	atomisp_subdev_cleanup_pending_events(asd);
>  stopsensor:
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT
  2023-01-23 12:51 ` [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT Hans de Goede
@ 2023-01-23 17:59   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 17:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:33PM +0100, Hans de Goede wrote:
> atomisp_set_fmt() first does:
> 
> 	v4l2_fill_mbus_format(&vformat.format, ...);
>         vformat.format.height += padding_h;
>         vformat.format.width += padding_w;
> 
>         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
>                                set_fmt, NULL, &vformat);
>         if (ret)
>                 return ret;
> 
> 	f->fmt.pix.width = vformat.format.width - padding_w;
> 	f->fmt.pix.height = vformat.format.height - padding_h;
> 
> this happens with the original padding w/h = 16 values and then later
> on it calls:
> 
>                 ret = atomisp_set_fmt_to_snr(vdev, &s_fmt,
>                                              f->fmt.pix.pixelformat, padding_w,
>                                              padding_h, dvs_env_w, dvs_env_h);
> 
> Which repeats the above structure. If at that point padding w/h are
> changed to 12 then it will now request a different output-size of
> the sensor driver.
> 
> The sensor drivers so far have actually been ignoring this since they use
> v4l2_find_nearest_size() on a fixed resolution list and the nearest
> resolution will be the one from the earlier calls where padding w/h
> was 16.
> 
> But there really is no reason for sensor drivers to use a fixed
> resolution list. They make lower resolutions using cropping so they
> can make any resolution as long as width/height are even numbers.
> 
> Dropping the fixed-resolution list limit from sensors on BYT results
> in trying to start streaming failing because the resolution set to
> the sensor now no longer matches with the resolution used during
> the initial part of the configuration done by atomisp_set_fmt().
> 
> Drop the BYT specific overriding of the padding_w/h to 12, so that
> the padding in the first and second s_fmt calls made to the sensor
> matches, to fix stream start failing when the fixed resolution list
> is dropped.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/pci/atomisp_cmd.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> index eb05288d8fb1..47f18ac5e40e 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
> @@ -5163,9 +5163,6 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
>  	if (!atomisp_subdev_format_conversion(asd, source_pad)) {
>  		padding_w = 0;
>  		padding_h = 0;
> -	} else if (IS_BYT) {
> -		padding_w = 12;
> -		padding_h = 12;
>  	}
>  
>  	/* construct resolution supported by isp */
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup()
  2023-01-23 12:51 ` [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup() Hans de Goede
@ 2023-01-23 18:02   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:02 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:35PM +0100, Hans de Goede wrote:
> Looking at isp_subdev_link_setup(), this function can never work,
> it does a switch-case like this:
> 
>  switch (local->index | is_media_entity_v4l2_subdev(remote->entity))
> 
> with cases like this:
> 
>  case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
> 
> where ATOMISP_SUBDEV_PAD_SINK matches an index (0-4) and
> MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN is 0x00020000, but
> is_media_entity_v4l2_subdev(remote->entity) does not return
> MEDIA_ENT_F_* values, it return a bool, so 0 or 1 which means
> that non of the cases can ever match the input value.
> 
> Looking at the rest of the function all it ever does (if it
> would actually hit one of the cases) is set the atomisp_sub_device
> struct's input member.
> 
> And checking the rest of the atomisp code that member is never
> read. Also userspace does not actually setup media-controller
> links when using the atomisp /dev/video$ nodes since all the links
> are fixed. So isp_subdev_link_setup() never runs.
> 
> Remove the unnecessary and broken isp_subdev_link_setup() function
> and also remove the unused atomisp_sub_device struct's input member.

(One of the) best patch(es) in the series!
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/pci/atomisp_subdev.c        | 79 -------------------
>  .../media/atomisp/pci/atomisp_subdev.h        | 13 ---
>  2 files changed, 92 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> index eb8f319fca5c..52d1936b8c87 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c
> @@ -714,85 +714,8 @@ static void isp_subdev_init_params(struct atomisp_sub_device *asd)
>  	}
>  }
>  
> -/*
> -* isp_subdev_link_setup - Setup isp subdev connections
> -* @entity: ispsubdev media entity
> -* @local: Pad at the local end of the link
> -* @remote: Pad at the remote end of the link
> -* @flags: Link flags
> -*
> -* return -EINVAL or zero on success
> -*/
> -static int isp_subdev_link_setup(struct media_entity *entity,
> -				 const struct media_pad *local,
> -				 const struct media_pad *remote, u32 flags)
> -{
> -	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
> -	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
> -	struct atomisp_device *isp = isp_sd->isp;
> -	unsigned int i;
> -
> -	switch (local->index | is_media_entity_v4l2_subdev(remote->entity)) {
> -	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN:
> -		/* Read from the sensor CSI2-ports. */
> -		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
> -			isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
> -			break;
> -		}
> -
> -		if (isp_sd->input != ATOMISP_SUBDEV_INPUT_NONE)
> -			return -EBUSY;
> -
> -		for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
> -			if (remote->entity != &isp->csi2_port[i].subdev.entity)
> -				continue;
> -
> -			isp_sd->input = ATOMISP_SUBDEV_INPUT_CSI2_PORT1 + i;
> -			return 0;
> -		}
> -
> -		return -EINVAL;
> -
> -	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_OLD_BASE:
> -		/* read from memory */
> -		if (flags & MEDIA_LNK_FL_ENABLED) {
> -			if (isp_sd->input >= ATOMISP_SUBDEV_INPUT_CSI2_PORT1 &&
> -			    isp_sd->input < (ATOMISP_SUBDEV_INPUT_CSI2_PORT1
> -					     + ATOMISP_CAMERA_NR_PORTS))
> -				return -EBUSY;
> -			isp_sd->input = ATOMISP_SUBDEV_INPUT_MEMORY;
> -		} else {
> -			if (isp_sd->input == ATOMISP_SUBDEV_INPUT_MEMORY)
> -				isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
> -		}
> -		break;
> -
> -	case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW | MEDIA_ENT_F_OLD_BASE:
> -		/* always write to memory */
> -		break;
> -
> -	case ATOMISP_SUBDEV_PAD_SOURCE_VF | MEDIA_ENT_F_OLD_BASE:
> -		/* always write to memory */
> -		break;
> -
> -	case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE | MEDIA_ENT_F_OLD_BASE:
> -		/* always write to memory */
> -		break;
> -
> -	case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO | MEDIA_ENT_F_OLD_BASE:
> -		/* always write to memory */
> -		break;
> -
> -	default:
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
>  /* media operations */
>  static const struct media_entity_operations isp_subdev_media_ops = {
> -	.link_setup = isp_subdev_link_setup,
>  	.link_validate = v4l2_subdev_link_validate,
>  	/*	 .set_power = v4l2_subdev_set_power,	*/
>  };
> @@ -1071,8 +994,6 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
>  	struct media_entity *me = &sd->entity;
>  	int ret;
>  
> -	asd->input = ATOMISP_SUBDEV_INPUT_NONE;
> -
>  	v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
>  	sprintf(sd->name, "ATOMISP_SUBDEV_%d", asd->index);
>  	v4l2_set_subdevdata(sd, asd);
> diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
> index bd2872cbb50c..daa6077a83bd 100644
> --- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h
> +++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h
> @@ -30,18 +30,6 @@
>  
>  /* EXP_ID's ranger is 1 ~ 250 */
>  #define ATOMISP_MAX_EXP_ID     (250)
> -enum atomisp_subdev_input_entity {
> -	ATOMISP_SUBDEV_INPUT_NONE,
> -	ATOMISP_SUBDEV_INPUT_MEMORY,
> -	ATOMISP_SUBDEV_INPUT_CSI2,
> -	/*
> -	 * The following enum for CSI2 port must go together in one row.
> -	 * Otherwise it breaks the code logic.
> -	 */
> -	ATOMISP_SUBDEV_INPUT_CSI2_PORT1,
> -	ATOMISP_SUBDEV_INPUT_CSI2_PORT2,
> -	ATOMISP_SUBDEV_INPUT_CSI2_PORT3,
> -};
>  
>  #define ATOMISP_SUBDEV_PAD_SINK			0
>  /* capture output for still frames */
> @@ -267,7 +255,6 @@ struct atomisp_sub_device {
>  	struct atomisp_pad_format fmt[ATOMISP_SUBDEV_PADS_NUM];
>  	u16 capture_pad; /* main capture pad; defines much of isp config */
>  
> -	enum atomisp_subdev_input_entity input;
>  	unsigned int output;
>  	struct atomisp_video_pipe video_out_capture; /* capture output */
>  	struct atomisp_video_pipe video_out_vf;      /* viewfinder output */
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
@ 2023-01-23 18:09   ` Andy Shevchenko
  2023-01-24 11:21     ` Hans de Goede
  2023-01-23 18:15   ` Andy Shevchenko
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> 
> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> use register access helpers with the following function prototypes:
> 
> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>                     unsigned int len, u32 *val);
> 
> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>                      unsigned int len, u32 val);
> 
> To read/write registers on Omnivision OVxxxx image sensors wich expect
> a 16 bit register address in big-endian format and which have 1-3 byte
> wide registers, in big-endian format (for the higher width registers).
> 
> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> versions of these register access helpers, so that this code duplication
> can be removed.

...

> +#include <asm/unaligned.h>

Usually we put linux/* followed by asm/*.

> +#include <linux/dev_printk.h>
> +#include <linux/i2c.h>
> +
> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
> +				  unsigned int len, u32 *val)
> +{
> +	struct i2c_msg msgs[2];

> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };

Let's use unaligned.h or byteorder/generic.h?

	__be16 addr_buf = cpu_to_be16(reg);

> +	u8 data_buf[4] = { 0, };

0, is not needed.

> +	int ret;
> +
> +	if (len > 4)
> +		return -EINVAL;
> +
> +	msgs[0].addr = client->addr;
> +	msgs[0].flags = 0;
> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> +	msgs[0].buf = addr_buf;

	msgs[0].buf = &addr_buf;

> +	msgs[1].addr = client->addr;
> +	msgs[1].flags = I2C_M_RD;
> +	msgs[1].len = len;

> +	msgs[1].buf = &data_buf[4 - len];

This trick I don't like. Can we have like other driver have it, i.e. switch
case for the possible length and explicit usage of the endian conversion calls?

> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> +	if (ret != ARRAY_SIZE(msgs)) {
> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
> +		return -EIO;
> +	}
> +
> +	*val = get_unaligned_be32(data_buf);
> +
> +	return 0;
> +}
> +
> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
> +
> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
> +				   unsigned int len, u32 val)
> +{
> +	u8 buf[6];
> +	int ret;
> +
> +	if (len > 4)
> +		return -EINVAL;

> +	put_unaligned_be16(reg, buf);
> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);

Something similar here?

> +	ret = i2c_master_send(client, buf, len + 2);
> +	if (ret != len + 2) {
> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> +
> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> +{
> +	u32 readval;
> +	int ret;
> +
> +	ret = ovxxxx_read_reg8(client, reg, &readval);
> +	if (ret < 0)
> +		return ret;

> +	readval &= ~mask;
> +	val &= mask;
> +	val |= readval;

Usual pattern:

	val = (readval & ~mask) | (val & mask);

> +	return ovxxxx_write_reg8(client, reg, val);
> +}

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
@ 2023-01-23 18:13   ` Andy Shevchenko
  2023-01-24 11:22     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:13 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:37PM +0100, Hans de Goede wrote:
> Use the new ovxxxx_16bit_addr_reg_helpers.h instead of duplicating
> the ovxxxx sensor I2C register access helpers found in many different
> sensor drivers.

...

> -	ret = ov2680_write_reg(client, 1,
> -			       OV2680_GROUP_ACCESS, 0x00);
> +	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x00);
>  	if (ret) {
>  		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
>  			__func__, OV2680_GROUP_ACCESS);

Wouldn't this be a dup message without any additional value?

Same to many other places.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
  2023-01-23 18:09   ` Andy Shevchenko
@ 2023-01-23 18:15   ` Andy Shevchenko
  2023-01-23 18:23   ` Andy Shevchenko
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:15 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> 
> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> use register access helpers with the following function prototypes:
> 
> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>                     unsigned int len, u32 *val);
> 
> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>                      unsigned int len, u32 val);
> 

While reviewing the following patch, I realize that we actually don't need
these long names.

int ov_read_reg(struct ovxxxx_dev *sensor, u16 reg, unsigned int len, u32 *val);

int ov_write_reg(struct ovxxxx_dev *sensor, u16 reg, unsigned int len, u32 val);

will work fine and fit one line (80 limit).

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
  2023-01-23 18:09   ` Andy Shevchenko
  2023-01-23 18:15   ` Andy Shevchenko
@ 2023-01-23 18:23   ` Andy Shevchenko
  2023-01-24 11:25     ` Hans de Goede
  2023-02-08  9:52   ` Laurent Pinchart
  2023-02-08 11:31   ` Sakari Ailus
  4 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:23 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> 
> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> use register access helpers with the following function prototypes:
> 
> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>                     unsigned int len, u32 *val);
> 
> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>                      unsigned int len, u32 val);
> 
> To read/write registers on Omnivision OVxxxx image sensors wich expect
> a 16 bit register address in big-endian format and which have 1-3 byte
> wide registers, in big-endian format (for the higher width registers).
> 
> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> versions of these register access helpers, so that this code duplication
> can be removed.


A couple more comments.

...

> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)

Btw, we probably can use _Generic() for these...

...

> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)

Can we actually s/mod/update/ as it's more regular when we talk about IO
accessor APIs?

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD macros with functions
  2023-01-23 12:52 ` [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD " Hans de Goede
@ 2023-01-23 18:27   ` Andy Shevchenko
  2023-01-23 18:29     ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:27 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Brent Pappas

On Mon, Jan 23, 2023 at 01:52:04PM +0100, Hans de Goede wrote:
> From: Brent Pappas <bpappas@pappasbrent.com>
> 
> Replace the macros SUBWORD() and INV_SUBWORD() with functions to comply
> with Linux coding style standards.

...

> +static inline hive_uedge
> +subword(hive_uedge w, unsigned int start, unsigned int end)
> +{
> +	return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start;
> +}

...

> +static inline hive_uedge
> +inv_subword(hive_uedge w, unsigned int start, unsigned int end)
> +{
> +	return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1));
> +}

...

Brent, maybe you can look at these deeply and convert them to use GENMASK()
instead? (It can be done as a followup patch, this one is fine)

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD macros with functions
  2023-01-23 18:27   ` Andy Shevchenko
@ 2023-01-23 18:29     ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:29 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging, Brent Pappas

On Mon, Jan 23, 2023 at 08:27:37PM +0200, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:52:04PM +0100, Hans de Goede wrote:
> > From: Brent Pappas <bpappas@pappasbrent.com>
> > 
> > Replace the macros SUBWORD() and INV_SUBWORD() with functions to comply
> > with Linux coding style standards.

...

> > +static inline hive_uedge
> > +subword(hive_uedge w, unsigned int start, unsigned int end)
> > +{
> > +	return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start;
> > +}
> 
> ...
> 
> > +static inline hive_uedge
> > +inv_subword(hive_uedge w, unsigned int start, unsigned int end)
> > +{
> > +	return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1));
> > +}
> 
> ...
> 
> Brent, maybe you can look at these deeply and convert them to use GENMASK()
> instead? (It can be done as a followup patch, this one is fine)

Note, with such conversion done you may kill these macros and use GENMASK()
inline.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls
  2023-01-23 12:51 ` [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls Hans de Goede
@ 2023-01-23 18:33   ` Andy Shevchenko
  2023-01-29  0:36   ` kernel test robot
  1 sibling, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:33 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:38PM +0100, Hans de Goede wrote:
> Rework the flip ctrls to be more like those of mainline (non staging)
> drivers.
> 
> This is modelled after the main ov2680 and ov5693 drivers. This also
> introduces __ov2680_get_pad_format() to make the ov2680 code more compliant
> with the mainline v4l2-subdev APIs.
> 
> Note the OV2680_FLIP_REG and OV2680_MIRROR_REG defines are renamed to
> OV2680_REG_FORMAT1 and OV2680_REG_FORMAT2 to match the datasheet.

...

> +static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
> +{
> +	return &container_of(ctrl->handler, struct ov2680_device,
> +			     ctrls.handler)->sd;

I would unroll this for better readability.


	struct ov2680_device *ovd =
		container_of(ctrl->handler, struct ov2680_device, ctrls.handler);

	return &ovd->sd;

> +}

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support
  2023-01-23 12:51 ` [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support Hans de Goede
@ 2023-01-23 18:35   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:39PM +0100, Hans de Goede wrote:
> Exposure and gain control should use standard v4l2 controls,
> not a custom ioctl.
> 
> The next patch in this series will re-add support as standard controls,
> this is split into 2 patches for easier reviewing.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 209 +-----------------
>  drivers/staging/media/atomisp/i2c/ov2680.h    |   3 -
>  2 files changed, 2 insertions(+), 210 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index df92b35ce062..d508c02444eb 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -60,181 +60,6 @@ static int ov2680_write_reg_array(struct i2c_client *client,
>  	return 0;
>  }
>  
> -static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
> -				  int gain, int digitgain)
> -
> -{
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	u16 vts;
> -	int ret, exp_val;
> -
> -	dev_dbg(&client->dev,
> -		"+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",
> -		coarse_itg, gain, digitgain);
> -
> -	vts = dev->res->lines_per_frame;
> -
> -	/* group hold */
> -	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x00);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_GROUP_ACCESS);
> -		return ret;
> -	}
> -
> -	/* Increase the VTS to match exposure + MARGIN */
> -	if (coarse_itg > vts - OV2680_INTEGRATION_TIME_MARGIN)
> -		vts = (u16)coarse_itg + OV2680_INTEGRATION_TIME_MARGIN;
> -
> -	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_TIMING_VTS_H);
> -		return ret;
> -	}
> -
> -	/* set exposure */
> -
> -	/* Lower four bit should be 0*/
> -	exp_val = coarse_itg << 4;
> -	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_L, exp_val & 0xFF);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_EXPOSURE_L);
> -		return ret;
> -	}
> -
> -	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_M, (exp_val >> 8) & 0xFF);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_EXPOSURE_M);
> -		return ret;
> -	}
> -
> -	ret = ovxxxx_write_reg8(client, OV2680_EXPOSURE_H, (exp_val >> 16) & 0x0F);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_EXPOSURE_H);
> -		return ret;
> -	}
> -
> -	/* Analog gain */
> -	ret = ovxxxx_write_reg16(client, OV2680_AGC_H, gain);
> -	if (ret) {
> -		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
> -			__func__, OV2680_AGC_H);
> -		return ret;
> -	}
> -	/* Digital gain */
> -	if (digitgain) {
> -		ret = ovxxxx_write_reg16(client, OV2680_MWB_RED_GAIN_H, digitgain);
> -		if (ret) {
> -			dev_err(&client->dev,
> -				"%s: write 0x%02x: error, aborted\n",
> -				__func__, OV2680_MWB_RED_GAIN_H);
> -			return ret;
> -		}
> -
> -		ret = ovxxxx_write_reg16(client, OV2680_MWB_GREEN_GAIN_H, digitgain);
> -		if (ret) {
> -			dev_err(&client->dev,
> -				"%s: write 0x%02x: error, aborted\n",
> -				__func__, OV2680_MWB_RED_GAIN_H);
> -			return ret;
> -		}
> -
> -		ret = ovxxxx_write_reg16(client, OV2680_MWB_BLUE_GAIN_H, digitgain);
> -		if (ret) {
> -			dev_err(&client->dev,
> -				"%s: write 0x%02x: error, aborted\n",
> -				__func__, OV2680_MWB_RED_GAIN_H);
> -			return ret;
> -		}
> -	}
> -
> -	/* End group */
> -	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x10);
> -	if (ret)
> -		return ret;
> -
> -	/* Delay launch group */
> -	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0xa0);
> -	if (ret)
> -		return ret;
> -	return ret;
> -}
> -
> -static int ov2680_set_exposure(struct v4l2_subdev *sd, int exposure,
> -			       int gain, int digitgain)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	int ret = 0;
> -
> -	mutex_lock(&dev->input_lock);
> -
> -	dev->exposure = exposure;
> -	dev->gain = gain;
> -	dev->digitgain = digitgain;
> -
> -	if (dev->power_on)
> -		ret = __ov2680_set_exposure(sd, exposure, gain, digitgain);
> -
> -	mutex_unlock(&dev->input_lock);
> -
> -	return ret;
> -}
> -
> -static long ov2680_s_exposure(struct v4l2_subdev *sd,
> -			      struct atomisp_exposure *exposure)
> -{
> -	u16 coarse_itg = exposure->integration_time[0];
> -	u16 analog_gain = exposure->gain[0];
> -	u16 digital_gain = exposure->gain[1];
> -
> -	/* we should not accept the invalid value below */
> -	if (analog_gain == 0) {
> -		struct i2c_client *client = v4l2_get_subdevdata(sd);
> -
> -		v4l2_err(client, "%s: invalid value\n", __func__);
> -		return -EINVAL;
> -	}
> -
> -	return ov2680_set_exposure(sd, coarse_itg, analog_gain, digital_gain);
> -}
> -
> -static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
> -{
> -	switch (cmd) {
> -	case ATOMISP_IOC_S_EXPOSURE:
> -		return ov2680_s_exposure(sd, arg);
> -
> -	default:
> -		return -EINVAL;
> -	}
> -	return 0;
> -}
> -
> -/*
> - * This returns the exposure time being used. This should only be used
> - * for filling in EXIF data, not for actual image processing.
> - */
> -static int ov2680_q_exposure(struct v4l2_subdev *sd, s32 *value)
> -{
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	u32 reg_val;
> -	int ret;
> -
> -	/* get exposure */
> -	ret = ovxxxx_read_reg24(client, OV2680_EXPOSURE_H, &reg_val);
> -	if (ret)
> -		return ret;
> -
> -	/* Lower four bits are not part of the exposure val (always 0) */
> -	*value = reg_val >> 4;
> -	return 0;
> -}
> -
>  static void ov2680_set_bayer_order(struct ov2680_device *sensor, struct v4l2_mbus_framefmt *fmt)
>  {
>  	static const int ov2680_hv_flip_bayer_order[] = {
> @@ -316,25 +141,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  	return ret;
>  }
>  
> -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
> -{
> -	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> -	int ret = 0;
> -
> -	switch (ctrl->id) {
> -	case V4L2_CID_EXPOSURE_ABSOLUTE:
> -		ret = ov2680_q_exposure(sd, &ctrl->val);
> -		break;
> -	default:
> -		ret = -EINVAL;
> -	}
> -
> -	return ret;
> -}
> -
>  static const struct v4l2_ctrl_ops ov2680_ctrl_ops = {
>  	.s_ctrl = ov2680_s_ctrl,
> -	.g_volatile_ctrl = ov2680_g_volatile_ctrl
>  };
>  
>  static int ov2680_init_registers(struct v4l2_subdev *sd)
> @@ -443,10 +251,6 @@ static int power_up(struct v4l2_subdev *sd)
>  	if (ret)
>  		goto fail_init_registers;
>  
> -	ret = __ov2680_set_exposure(sd, dev->exposure, dev->gain, dev->digitgain);
> -	if (ret)
> -		goto fail_init_registers;
> -
>  	dev->power_on = true;
>  	return 0;
>  
> @@ -547,7 +351,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
>  	struct v4l2_mbus_framefmt *fmt;
>  	struct ov2680_resolution *res;
> -	int vts, ret = 0;
> +	int ret = 0;
>  
>  	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
>  		__func__,
> @@ -582,13 +386,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  		goto err;
>  	}
>  
> -	vts = dev->res->lines_per_frame;
> -
> -	/* If necessary increase the VTS to match exposure + MARGIN */
> -	if (dev->exposure > vts - OV2680_INTEGRATION_TIME_MARGIN)
> -		vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN;
> -
> -	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
> +	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, dev->res->lines_per_frame);
>  	if (ret) {
>  		dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
>  		goto err;
> @@ -814,7 +612,6 @@ static const struct v4l2_subdev_sensor_ops ov2680_sensor_ops = {
>  
>  static const struct v4l2_subdev_core_ops ov2680_core_ops = {
>  	.s_power = ov2680_s_power,
> -	.ioctl = ov2680_ioctl,
>  };
>  
>  static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
> @@ -884,8 +681,6 @@ static int ov2680_probe(struct i2c_client *client)
>  
>  	dev->client = client;
>  	dev->res = &ov2680_res_preview[0];
> -	dev->exposure = dev->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
> -	dev->gain = 250; /* 0-2047 */
>  	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
>  
>  	pdata = gmin_camera_platform_data(&dev->sd,
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 43bbc9368422..45eb1f93b847 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -163,9 +163,6 @@ struct ov2680_device {
>  	struct camera_sensor_platform_data *platform_data;
>  	bool power_on;
>  	bool is_streaming;
> -	u16 exposure;
> -	u16 gain;
> -	u16 digitgain;
>  
>  	struct ov2680_mode {
>  		struct v4l2_mbus_framefmt fmt;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure
  2023-01-23 12:51 ` [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure Hans de Goede
@ 2023-01-23 18:36   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:36 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:59PM +0100, Hans de Goede wrote:
> Call atomisp_gmin_remove_subdev() on probe failure to properly free
> the GPIOs and other resources acquired by the gmin_camera_platform_data()
> call earlier.

Fixes?

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index d819ab5de28a..d874e12da8cc 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -994,6 +994,7 @@ static int ov2722_probe(struct i2c_client *client)
>  	v4l2_ctrl_handler_free(&dev->ctrl_handler);
>  
>  out_free:
> +	atomisp_gmin_remove_subdev(&dev->sd);
>  	v4l2_device_unregister_subdev(&dev->sd);
>  	kfree(dev);
>  	return ret;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity
  2023-01-23 12:52 ` [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity Hans de Goede
@ 2023-01-23 18:39   ` Andy Shevchenko
  2023-01-23 18:40   ` Andy Shevchenko
  1 sibling, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:52:00PM +0100, Hans de Goede wrote:
> The comment claims the PWDN pin is active when pulled down in other words,
> it is /power-down so it needs to be driven high to get the sensor
> powered-up (not powered down) and flag is 1 when powering-up the sensor
> so the ! is wrong, drop it.
> 
> This also matches with the schematics which I have which shows GPIO1 also
> enables a 3.3v line to the sensor-module which controls the privacy-LED
> and indeed before this patch the privacy LED was inverted from what it
> should be (and the sensor did not work).

It's unclear if this is logical state or raw one?
Maybe this the root cause of the initial confusion?


-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls.
  2023-01-23 12:52 ` [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls Hans de Goede
@ 2023-01-23 18:39   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:52:01PM +0100, Hans de Goede wrote:
> On ov2722_set_fmt() calls with format->which == V4L2_SUBDEV_FORMAT_TRY,
> ov2722_set_fmt() does not talk to the sensor, so there is no need to
> lock the dev->input_lock mutex in this case.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index 83d036b5d772..e09c80d1f9ec 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -651,7 +651,6 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
>  	if (!ov2722_info)
>  		return -EINVAL;
>  
> -	mutex_lock(&dev->input_lock);
>  	res = v4l2_find_nearest_size(ov2722_res_preview,
>  				     ARRAY_SIZE(ov2722_res_preview), width,
>  				     height, fmt->width, fmt->height);
> @@ -665,10 +664,10 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
>  	fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
>  	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
>  		sd_state->pads->try_fmt = *fmt;
> -		mutex_unlock(&dev->input_lock);
>  		return 0;
>  	}
>  
> +	mutex_lock(&dev->input_lock);
>  
>  	dev->pixels_per_line = dev->res->pixels_per_line;
>  	dev->lines_per_frame = dev->res->lines_per_frame;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity
  2023-01-23 12:52 ` [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity Hans de Goede
  2023-01-23 18:39   ` Andy Shevchenko
@ 2023-01-23 18:40   ` Andy Shevchenko
  1 sibling, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:52:00PM +0100, Hans de Goede wrote:
> The comment claims the PWDN pin is active when pulled down in other words,
> it is /power-down so it needs to be driven high to get the sensor
> powered-up (not powered down) and flag is 1 when powering-up the sensor
> so the ! is wrong, drop it.
> 
> This also matches with the schematics which I have which shows GPIO1 also
> enables a 3.3v line to the sensor-module which controls the privacy-LED
> and indeed before this patch the privacy LED was inverted from what it
> should be (and the sensor did not work).

Code-wise it's okay
Reviewed-by: Andy Shevchenko <andy@kernel.org>


> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index d874e12da8cc..83d036b5d772 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -512,10 +512,7 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
>  	 * before PWDN# when turning it on or off.
>  	 */
>  	ret = dev->platform_data->gpio0_ctrl(sd, flag);
> -	/*
> -	 *ov2722 PWDN# active high when pull down,opposite to the convention
> -	 */
> -	ret |= dev->platform_data->gpio1_ctrl(sd, !flag);
> +	ret |= dev->platform_data->gpio1_ctrl(sd, flag);
>  	return ret;
>  }
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback
  2023-01-23 12:52 ` [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback Hans de Goede
@ 2023-01-23 18:42   ` Andy Shevchenko
  2023-01-24 11:32     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:42 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:52:02PM +0100, Hans de Goede wrote:
> Depending on which order userspace makes various v4l2 calls, the sensor
> might still be powered down when set_fmt is called.
> 
> What should really happen here is delay the writing of the mode-related
> registers till streaming is started, but for now use the same quick fix
> as the atomisp_ov2680 / atomisp_gc0310 code and call power_up() from
> set_fmt() in combination with keeping track of the power-state to avoid
> doing the power-up sequence twice.

OK.
Reviewed-by: Andy Shevchenko <andy@kernel.org>

Is there a plan to drop this hack from all of the (AtomISP) sensor drivers?

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 12 ++++++++++++
>  drivers/staging/media/atomisp/i2c/ov2722.h         |  2 +-
>  2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> index e09c80d1f9ec..5d2e6e2e72f0 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
> @@ -528,6 +528,9 @@ static int power_up(struct v4l2_subdev *sd)
>  		return -ENODEV;
>  	}
>  
> +	if (dev->power_on == 1)
> +		return 0; /* Already on */
> +
>  	/* power control */
>  	ret = power_ctrl(sd, 1);
>  	if (ret)
> @@ -552,6 +555,7 @@ static int power_up(struct v4l2_subdev *sd)
>  	/* according to DS, 20ms is needed between PWDN and i2c access */
>  	msleep(20);
>  
> +	dev->power_on = 1;
>  	return 0;
>  
>  fail_clk:
> @@ -575,6 +579,9 @@ static int power_down(struct v4l2_subdev *sd)
>  		return -ENODEV;
>  	}
>  
> +	if (dev->power_on == 0)
> +		return 0; /* Already off */
> +
>  	ret = dev->platform_data->flisclk_ctrl(sd, 0);
>  	if (ret)
>  		dev_err(&client->dev, "flisclk failed\n");
> @@ -592,6 +599,7 @@ static int power_down(struct v4l2_subdev *sd)
>  	if (ret)
>  		dev_err(&client->dev, "vprog failed.\n");
>  
> +	dev->power_on = 0;
>  	return ret;
>  }
>  
> @@ -669,6 +677,9 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
>  
>  	mutex_lock(&dev->input_lock);
>  
> +	/* s_power has not been called yet for std v4l2 clients (camorama) */
> +	power_up(sd);
> +
>  	dev->pixels_per_line = dev->res->pixels_per_line;
>  	dev->lines_per_frame = dev->res->lines_per_frame;
>  
> @@ -959,6 +970,7 @@ static int ov2722_probe(struct i2c_client *client)
>  		return -ENOMEM;
>  
>  	mutex_init(&dev->input_lock);
> +	dev->power_on = -1;
>  
>  	dev->res = &ov2722_res_preview[0];
>  	v4l2_i2c_subdev_init(&dev->sd, client, &ov2722_ops);
> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
> index 020743a944c4..640d3ffcaa5c 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
> @@ -198,7 +198,7 @@ struct ov2722_device {
>  	struct ov2722_resolution *res;
>  
>  	struct camera_sensor_platform_data *platform_data;
> -	int run_mode;
> +	int power_on;
>  	u16 pixels_per_line;
>  	u16 lines_per_frame;
>  	u8 type;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls
  2023-01-23 12:51 ` [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls Hans de Goede
@ 2023-01-23 18:43   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:43 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:40PM +0100, Hans de Goede wrote:
> Add exposure and gain controls. This allows controlling
> the exposure and gain through standard v4l2 IOCTLs.
> 
> Note the register defines for the exposure and gain registers
> are renamed to match the datasheet.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 27 +++++++++++++++----
>  drivers/staging/media/atomisp/i2c/ov2680.h    |  9 +++----
>  2 files changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index d508c02444eb..14002a1c22d2 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -117,6 +117,16 @@ static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val)
>  	return 0;
>  }
>  
> +static int ov2680_exposure_set(struct ov2680_device *sensor, u32 exp)
> +{
> +	return ovxxxx_write_reg24(sensor->client, OV2680_REG_EXPOSURE_PK_HIGH, exp << 4);
> +}
> +
> +static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
> +{
> +	return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
> +}
> +
>  static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  {
>  	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> @@ -135,6 +145,12 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_HFLIP:
>  		ret = ov2680_set_hflip(sensor, ctrl->val);
>  		break;
> +	case V4L2_CID_EXPOSURE:
> +		ret = ov2680_exposure_set(sensor, ctrl->val);
> +		break;
> +	case V4L2_CID_GAIN:
> +		ret = ov2680_gain_set(sensor, ctrl->val);
> +		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -392,10 +408,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  		goto err;
>  	}
>  
> -	/*
> -	 * recall flip functions to avoid flip registers
> -	 * were overridden by default setting
> -	 */
> +	/* Restore value of all ctrls */
>  	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
>  	if (ret < 0)
>  		goto err;
> @@ -634,13 +647,17 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
>  	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
>  	struct ov2680_ctrls *ctrls = &sensor->ctrls;
>  	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
> +	int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
>  
> -	v4l2_ctrl_handler_init(hdl, 2);
> +	v4l2_ctrl_handler_init(hdl, 4);
>  
>  	hdl->lock = &sensor->input_lock;
>  
>  	ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
>  	ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
> +	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
> +					    0, exp_max, 1, exp_max);
> +	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
>  
>  	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
>  	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 45eb1f93b847..e3ad20a7ffd5 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -90,11 +90,8 @@
>  
>  #define OV2680_GROUP_ACCESS							0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
>  
> -#define OV2680_EXPOSURE_H							0x3500 /*Bit[3:0] Bit[19:16] of exposure, remaining 16 bits lies in Reg0x3501&Reg0x3502*/
> -#define OV2680_EXPOSURE_M							0x3501
> -#define OV2680_EXPOSURE_L							0x3502
> -#define OV2680_AGC_H								0x350A /*Bit[1:0] means Bit[9:8] of gain*/
> -#define OV2680_AGC_L								0x350B /*Bit[7:0] of gain*/
> +#define OV2680_REG_EXPOSURE_PK_HIGH		0x3500
> +#define OV2680_REG_GAIN_PK			0x350a
>  
>  #define OV2680_HORIZONTAL_START_H					0x3800 /*Bit[11:8]*/
>  #define OV2680_HORIZONTAL_START_L					0x3801 /*Bit[7:0]*/
> @@ -172,6 +169,8 @@ struct ov2680_device {
>  		struct v4l2_ctrl_handler handler;
>  		struct v4l2_ctrl *hflip;
>  		struct v4l2_ctrl *vflip;
> +		struct v4l2_ctrl *exposure;
> +		struct v4l2_ctrl *gain;
>  	} ctrls;
>  };
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 33/57] media: atomisp: ov2680: Add test pattern control
  2023-01-23 12:51 ` [PATCH 33/57] media: atomisp: ov2680: Add test pattern control Hans de Goede
@ 2023-01-23 18:46   ` Andy Shevchenko
  2023-01-24 11:27     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:41PM +0100, Hans de Goede wrote:
> Add a test pattern control. This is a 1:1 copy of the test pattern
> control in the main drivers/media/i2c/ov2680.c driver.

Hmm... I'm not sure I understand the trend of the changes.
We have two drivers of the same sensor, correct?
So, the idea is to move the AtomISP-specific one to be like
the generic and then kill it eventually?

If so, why do we add something here?


Code-wise it's okay change, but see above.
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 33 +++++++++++++++++++
>  drivers/staging/media/atomisp/i2c/ov2680.h    |  3 ++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 14002a1c22d2..6ca2a5bb0700 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -127,6 +127,24 @@ static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
>  	return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
>  }
>  
> +static int ov2680_test_pattern_set(struct ov2680_device *sensor, int value)
> +{
> +	int ret;
> +
> +	if (!value)
> +		return ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), 0);
> +
> +	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, 0x03, value - 1);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7));
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
>  static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  {
>  	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> @@ -151,6 +169,9 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  	case V4L2_CID_GAIN:
>  		ret = ov2680_gain_set(sensor, ctrl->val);
>  		break;
> +	case V4L2_CID_TEST_PATTERN:
> +		ret = ov2680_test_pattern_set(sensor, ctrl->val);
> +		break;
>  	default:
>  		ret = -EINVAL;
>  	}
> @@ -644,6 +665,13 @@ static const struct v4l2_subdev_ops ov2680_ops = {
>  
>  static int ov2680_init_controls(struct ov2680_device *sensor)
>  {
> +	static const char * const test_pattern_menu[] = {
> +		"Disabled",
> +		"Color Bars",
> +		"Random Data",
> +		"Square",
> +		"Black Image",
> +	};
>  	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
>  	struct ov2680_ctrls *ctrls = &sensor->ctrls;
>  	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
> @@ -658,6 +686,11 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
>  	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
>  					    0, exp_max, 1, exp_max);
>  	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
> +	ctrls->test_pattern =
> +		v4l2_ctrl_new_std_menu_items(hdl,
> +					     &ov2680_ctrl_ops, V4L2_CID_TEST_PATTERN,
> +					     ARRAY_SIZE(test_pattern_menu) - 1,
> +					     0, 0, test_pattern_menu);
>  
>  	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
>  	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index e3ad20a7ffd5..45526477b612 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -120,6 +120,8 @@
>  #define OV2680_MWB_BLUE_GAIN_H			0x5008/*0x3404*/
>  #define OV2680_MWB_GAIN_MAX				0x0fff
>  
> +#define OV2680_REG_ISP_CTRL00			0x5080
> +
>  #define OV2680_START_STREAMING			0x01
>  #define OV2680_STOP_STREAMING			0x00
>  
> @@ -171,6 +173,7 @@ struct ov2680_device {
>  		struct v4l2_ctrl *vflip;
>  		struct v4l2_ctrl *exposure;
>  		struct v4l2_ctrl *gain;
> +		struct v4l2_ctrl *test_pattern;
>  	} ctrls;
>  };
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions
  2023-01-23 12:51 ` [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions Hans de Goede
@ 2023-01-23 18:48   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-23 18:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:42PM +0100, Hans de Goede wrote:
> By default the ov2680 automatically sets the window to match the outputsize
> and automatically adjusts it to keep the bayer pattern stable when enabling
> hflip/vflip.
> 
> This does not work for the 1616x1216 mode because there is no room to
> adjust the window there. To make flipping work in the 1616 wide modes the
> register lists for those modes set bit 0 of 0x5708 (manual_win_en) to 1 and
> ov2680_set_bayer_order() updates the bayer-order on the pad to match.
> 
> But ov2680_set_bayer_order() is always called, so when enabling flipping
> on modes with a width of less then 1616 now results in the wrong bayer
> order being reported on the pad since the sensor is auto-adjusting
> the window in this case.
> 
> Specify the correct (== output-size) window-size in all resolutions
> register-list and always set the manual_win_en bit, so that the bayer order
> is changed on hflip/vflip enable on all resolutions.

...

> +	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11

While at it, perhaps replace // with proper /* comment  */?
Same to the rest of the similar cases.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based
  2023-01-23 12:51 ` [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based Hans de Goede
@ 2023-01-24 10:37   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:37 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:43PM +0100, Hans de Goede wrote:
> Instead of using a long fixed register settings list for each resolution,
> calculate the register settings based on the requested width + height.
> 
> This will allow future enhancements like adding hblank and vblank controls
> and adding selection support.

...

> +	ret = ovxxxx_write_reg16(client, OV2680_HORIZONTAL_START_H, sensor->mode.h_start);
> +	if (ret)
> +		return ret;
> +
> +	ret = ovxxxx_write_reg16(client, OV2680_VERTICAL_START_H, sensor->mode.v_start);
> +	if (ret)
> +		return ret;

Wondering if those registers are always being accessed as 16-bit. In such case
I would consider to drop _L definitions along with _H suffixes.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device
  2023-01-23 12:51 ` [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device Hans de Goede
@ 2023-01-24 10:39   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:39 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:45PM +0100, Hans de Goede wrote:
> The res member of struct ov2680_device isn't read anywhere anymore,
> drop it.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 5 -----
>  drivers/staging/media/atomisp/i2c/ov2680.h         | 1 -
>  2 files changed, 6 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index dee6eb3d8c63..09c260ac93bf 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -548,10 +548,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  
>  	/* Restore value of all ctrls */
>  	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
> -	if (ret < 0)
> -		goto err;
> -
> -	dev->res = res;
>  err:
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
> @@ -839,7 +835,6 @@ static int ov2680_probe(struct i2c_client *client)
>  	mutex_init(&dev->input_lock);
>  
>  	dev->client = client;
> -	dev->res = &ov2680_res_preview[0];
>  	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
>  
>  	pdata = gmin_camera_platform_data(&dev->sd,
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 4c1d20f514b2..e9d0c84705fb 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -180,7 +180,6 @@ struct ov2680_device {
>  	struct media_pad pad;
>  	struct mutex input_lock;
>  	struct i2c_client *client;
> -	struct ov2680_resolution *res;
>  	struct camera_sensor_platform_data *platform_data;
>  	bool power_on;
>  	bool is_streaming;
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames
  2023-01-23 12:51 ` [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames Hans de Goede
@ 2023-01-24 10:40   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:44PM +0100, Hans de Goede wrote:
> The fps, lines-per-frame and skip-frames values are the same for all
> resolutions, use defines for these.
> 
> The ov2680_res_preview[] incorrectly sets fps to 60 for some low-res
> modes, this is incorrect with the current fixed (resolution independent)
> lines-per-frame value.
> 
> Note this not drop the now no longer used fps, lines-per-frame and
> skip-frames struct ov2680_resolution members. The entire struct is going
> away in the next patches so that would just cause unnecessary changes.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../staging/media/atomisp/i2c/atomisp-ov2680.c   | 16 ++++------------
>  drivers/staging/media/atomisp/i2c/ov2680.h       |  2 ++
>  2 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 6693f042f4f2..dee6eb3d8c63 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -685,11 +685,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  static int ov2680_g_frame_interval(struct v4l2_subdev *sd,
>  				   struct v4l2_subdev_frame_interval *interval)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -
>  	interval->interval.numerator = 1;
> -	interval->interval.denominator = dev->res->fps;
> -
> +	interval->interval.denominator = OV2680_FPS;
>  	return 0;
>  }
>  
> @@ -733,8 +730,8 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
>  	    fie->which > V4L2_SUBDEV_FORMAT_ACTIVE)
>  		return -EINVAL;
>  
> -	fract.denominator = ov2680_res_preview[fie->index].fps;
>  	fract.numerator = 1;
> +	fract.denominator = OV2680_FPS;
>  
>  	fie->interval = fract;
>  
> @@ -743,12 +740,7 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
>  
>  static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -
> -	mutex_lock(&dev->input_lock);
> -	*frames = dev->res->skip_frames;
> -	mutex_unlock(&dev->input_lock);
> -
> +	*frames = OV2680_SKIP_FRAMES;
>  	return 0;
>  }
>  
> @@ -792,7 +784,7 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
>  	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
>  	struct ov2680_ctrls *ctrls = &sensor->ctrls;
>  	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
> -	int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
> +	int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN;
>  
>  	v4l2_ctrl_handler_init(hdl, 4);
>  
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 9bbb34dd95a5..4c1d20f514b2 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -38,6 +38,8 @@
>  /* 1704 * 1294 * 30fps = 66MHz pixel clock */
>  #define OV2680_PIXELS_PER_LINE			1704
>  #define OV2680_LINES_PER_FRAME			1294
> +#define OV2680_FPS				30
> +#define OV2680_SKIP_FRAMES			3
>  
>  /* If possible send 16 extra rows / lines to the ISP as padding */
>  #define OV2680_END_MARGIN			16
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval()
  2023-01-23 12:51 ` [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval() Hans de Goede
@ 2023-01-24 10:42   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:42 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:46PM +0100, Hans de Goede wrote:
> Fix and simplify ov2680_enum_frame_interval(), the index is not
> an index into ov2680_res_preview[], so using N_PREVIEW is wrong.
> 
> Instead it is an index indexing the different framerates for
> the resolution specified in fie->width, fie->height.
> 
> Since the ov2680 code only supports a single fixed 30 fps,
> index must always be 0 and we don't need to check the other
> fie input values.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../staging/media/atomisp/i2c/atomisp-ov2680.c    | 15 ++++-----------
>  1 file changed, 4 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 09c260ac93bf..75d09c44202c 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -718,19 +718,12 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd,
>  				      struct v4l2_subdev_state *sd_state,
>  				      struct v4l2_subdev_frame_interval_enum *fie)
>  {
> -	struct v4l2_fract fract;
> -
> -	if (fie->index >= N_RES_PREVIEW ||
> -	    fie->width > ov2680_res_preview[0].width ||
> -	    fie->height > ov2680_res_preview[0].height ||
> -	    fie->which > V4L2_SUBDEV_FORMAT_ACTIVE)
> +	/* Only 1 framerate */
> +	if (fie->index)
>  		return -EINVAL;
>  
> -	fract.numerator = 1;
> -	fract.denominator = OV2680_FPS;
> -
> -	fie->interval = fract;
> -
> +	fie->interval.numerator = 1;
> +	fie->interval.denominator = OV2680_FPS;
>  	return 0;
>  }
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt()
  2023-01-23 12:51 ` [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt() Hans de Goede
@ 2023-01-24 10:43   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:43 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:47PM +0100, Hans de Goede wrote:
> Since we now calculate timings baded on the desired width and height,
> any width and height are valid as long as they don't exceed the sensor's
> dimensions.
> 
> Drop the v4l2_find_nearest_size() call and instead clamp the requested
> width and height.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 75d09c44202c..3d5e18fb45ee 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -512,7 +512,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  	struct ov2680_device *dev = to_ov2680_sensor(sd);
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
>  	struct v4l2_mbus_framefmt *fmt;
> -	struct ov2680_resolution *res;
> +	unsigned int width, height;
>  	int ret = 0;
>  
>  	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
> @@ -520,14 +520,11 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  		(format->which == V4L2_SUBDEV_FORMAT_TRY) ? "try" : "set",
>  		format->pad, fmt);
>  
> -	res = v4l2_find_nearest_size(ov2680_res_preview, ARRAY_SIZE(ov2680_res_preview),
> -				     width, height,
> -				     format->format.width, format->format.height);
> -	if (!res)
> -		res = &ov2680_res_preview[N_RES_PREVIEW - 1];
> +	width = min_t(unsigned int, ALIGN(format->format.width, 2), OV2680_NATIVE_WIDTH);
> +	height = min_t(unsigned int, ALIGN(format->format.height, 2), OV2680_NATIVE_HEIGHT);
>  
>  	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
> -	ov2680_fill_format(dev, fmt, res->width, res->height);
> +	ov2680_fill_format(dev, fmt, width, height);
>  
>  	format->format = *fmt;
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview
  2023-01-23 12:51 ` [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview Hans de Goede
@ 2023-01-24 10:44   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:44 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:48PM +0100, Hans de Goede wrote:
> Drop struct ov2680_resolution and the ov2680_res_preview[] array,
> this is now only used in ov2680_enum_frame_size() and only
> the width + height are used there.
> 
> Replace this with a new struct v4l2_frmsize_discrete ov2680_frame_sizes[]
> array.
> 
> No functional changes.

Makes sense,
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        |  24 +-
>  drivers/staging/media/atomisp/i2c/ov2680.h    | 610 ------------------
>  2 files changed, 19 insertions(+), 615 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 3d5e18fb45ee..432539dd274c 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -698,15 +698,29 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
>  				  struct v4l2_subdev_state *sd_state,
>  				  struct v4l2_subdev_frame_size_enum *fse)
>  {
> +	static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = {
> +		{ 1616, 1216 },
> +		{ 1616, 1082 },
> +		{ 1616,  916 },
> +		{ 1456, 1096 },
> +		{ 1296,  976 },
> +		{ 1296,  736 },
> +		{  800,  600 },
> +		{  720,  592 },
> +		{  656,  496 },
> +		{  336,  256 },
> +		{  352,  288 },
> +		{  176,  144 },
> +	};
>  	int index = fse->index;
>  
> -	if (index >= N_RES_PREVIEW)
> +	if (index >= ARRAY_SIZE(ov2680_frame_sizes))
>  		return -EINVAL;
>  
> -	fse->min_width = ov2680_res_preview[index].width;
> -	fse->min_height = ov2680_res_preview[index].height;
> -	fse->max_width = ov2680_res_preview[index].width;
> -	fse->max_height = ov2680_res_preview[index].height;
> +	fse->min_width = ov2680_frame_sizes[index].width;
> +	fse->min_height = ov2680_frame_sizes[index].height;
> +	fse->max_width = ov2680_frame_sizes[index].width;
> +	fse->max_height = ov2680_frame_sizes[index].height;
>  
>  	return 0;
>  }
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index e9d0c84705fb..20ef59928cb1 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -154,18 +154,6 @@ struct regval_list {
>  	u8 value;
>  };
>  
> -struct ov2680_resolution {
> -	const struct ov2680_reg *regs;
> -	int res;
> -	int width;
> -	int height;
> -	int fps;
> -	int pix_clk_freq;
> -	u32 skip_frames;
> -	u16 pixels_per_line;
> -	u16 lines_per_frame;
> -};
> -
>  struct ov2680_format {
>  	u8 *desc;
>  	u32 pixelformat;
> @@ -320,602 +308,4 @@ static struct ov2680_reg const ov2680_global_setting[] = {
>  	{}
>  };
>  
> -/*
> - * 176x144 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_QCIF_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0xa0},
> -	{0x3802, 0x00},
> -	{0x3803, 0x78},
> -	{0x3804, 0x05},
> -	{0x3805, 0xaf},
> -	{0x3806, 0x04},
> -	{0x3807, 0x47},
> -	{0x3808, 0x00},
> -	{0x3809, 0xC0},
> -	{0x380a, 0x00},
> -	{0x380b, 0xa0},
> -	{0x380c, 0x06},
> -	{0x380d, 0xb0},
> -	{0x3810, 0x00},
> -	{0x3811, 0x04},
> -	{0x3812, 0x00},
> -	{0x3813, 0x04},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x4000, 0x81},
> -	{0x4001, 0x40},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x00},
> -	{0x5705, 0xc0},
> -	{0x5706, 0x00},
> -	{0x5707, 0xa0},
> -	{0x3820, 0xc2},
> -	{0x3821, 0x01},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - * 352x288 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_CIF_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0xa0},
> -	{0x3802, 0x00},
> -	{0x3803, 0x78},
> -	{0x3804, 0x03},
> -	{0x3805, 0x8f},
> -	{0x3806, 0x02},
> -	{0x3807, 0xe7},
> -	{0x3808, 0x01},
> -	{0x3809, 0x70},
> -	{0x380a, 0x01},
> -	{0x380b, 0x30},
> -	{0x380c, 0x06},
> -	{0x380d, 0xb0},
> -	{0x3810, 0x00},
> -	{0x3811, 0x04},
> -	{0x3812, 0x00},
> -	{0x3813, 0x04},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x01},
> -	{0x5705, 0x70},
> -	{0x5706, 0x01},
> -	{0x5707, 0x30},
> -	{0x3820, 0xc2},
> -	{0x3821, 0x01},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - * 336x256 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_QVGA_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0xa0},
> -	{0x3802, 0x00},
> -	{0x3803, 0x78},
> -	{0x3804, 0x03},
> -	{0x3805, 0x4f},
> -	{0x3806, 0x02},
> -	{0x3807, 0x87},
> -	{0x3808, 0x01},
> -	{0x3809, 0x50},
> -	{0x380a, 0x01},
> -	{0x380b, 0x00},
> -	{0x380c, 0x06},
> -	{0x380d, 0xb0},
> -	{0x3810, 0x00},
> -	{0x3811, 0x04},
> -	{0x3812, 0x00},
> -	{0x3813, 0x04},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x01},
> -	{0x5705, 0x50},
> -	{0x5706, 0x01},
> -	{0x5707, 0x00},
> -	{0x3820, 0xc2},
> -	{0x3821, 0x01},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - * 656x496 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_656x496_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0xa0},
> -	{0x3802, 0x00},
> -	{0x3803, 0x78},
> -	{0x3804, 0x05},
> -	{0x3805, 0xcf},
> -	{0x3806, 0x04},
> -	{0x3807, 0x67},
> -	{0x3808, 0x02},
> -	{0x3809, 0x90},
> -	{0x380a, 0x01},
> -	{0x380b, 0xf0},
> -	{0x380c, 0x06},
> -	{0x380d, 0xb0},
> -	{0x3810, 0x00},
> -	{0x3811, 0x04},
> -	{0x3812, 0x00},
> -	{0x3813, 0x04},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x02},
> -	{0x5705, 0x90},
> -	{0x5706, 0x01},
> -	{0x5707, 0xf0},
> -	{0x3820, 0xc2},
> -	{0x3821, 0x01},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - * 720x592 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_720x592_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0x00}, // X_ADDR_START;
> -	{0x3802, 0x00},
> -	{0x3803, 0x00}, // Y_ADDR_START;
> -	{0x3804, 0x05},
> -	{0x3805, 0xaf}, // X_ADDR_END;
> -	{0x3806, 0x04},
> -	{0x3807, 0xaf}, // Y_ADDR_END;
> -	{0x3808, 0x02},
> -	{0x3809, 0xd0}, // X_OUTPUT_SIZE;
> -	{0x380a, 0x02},
> -	{0x380b, 0x50}, // Y_OUTPUT_SIZE;
> -	{0x380c, 0x06},
> -	{0x380d, 0xac}, // HTS;
> -	{0x3810, 0x00},
> -	{0x3811, 0x00},
> -	{0x3812, 0x00},
> -	{0x3813, 0x00},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5708, 0x01},
> -	{0x5704, 0x02},
> -	{0x5705, 0xd0}, // X_WIN;
> -	{0x5706, 0x02},
> -	{0x5707, 0x50}, // Y_WIN;
> -	{0x3820, 0xc2}, // FLIP_FORMAT;
> -	{0x3821, 0x01}, // MIRROR_FORMAT;
> -	{0x5090, 0x00}, // PRE ISP CTRL16, default value is 0x0C;
> -	// BIT[3]: Mirror order, BG or GB;
> -	// BIT[2]: Flip order, BR or RB;
> -	{0x5081, 0x41},
> -	{}
> -};
> -
> -/*
> - * 800x600 30fps  VBlanking 1lane 10Bit (binning)
> - */
> -static struct ov2680_reg const ov2680_800x600_30fps[] = {
> -	{0x3086, 0x01},
> -	{0x370a, 0x23},
> -	{0x3801, 0x00}, /* hstart 0 */
> -	{0x3802, 0x00},
> -	{0x3803, 0x00}, /* vstart 0 */
> -	{0x3804, 0x06},
> -	{0x3805, 0x4f}, /* hend 1615 */
> -	{0x3806, 0x04},
> -	{0x3807, 0xbf}, /* vend 1215 */
> -	{0x3808, 0x03},
> -	{0x3809, 0x20}, /* hsize 800 */
> -	{0x380a, 0x02},
> -	{0x380b, 0x58}, /* vsize 600 */
> -	{0x380c, 0x06},
> -	{0x380d, 0xac}, /* htotal 1708 */
> -	{0x3810, 0x00},
> -	{0x3811, 0x00},
> -	{0x3812, 0x00},
> -	{0x3813, 0x00},
> -	{0x3814, 0x31},
> -	{0x3815, 0x31},
> -	{0x5708, 0x01},
> -	{0x5704, 0x03},
> -	{0x5705, 0x20},
> -	{0x5706, 0x02},
> -	{0x5707, 0x58},
> -	{0x3820, 0xc2},
> -	{0x3821, 0x01},
> -	{0x5090, 0x00},
> -	{0x4008, 0x00},
> -	{0x4009, 0x03},
> -	{0x5081, 0x41},
> -	{}
> -};
> -
> -/*
> - * 720p=1280*720 30fps  VBlanking 1lane 10Bit (no-Scaling)
> - */
> -static struct ov2680_reg const ov2680_720p_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0xa0}, /* hstart 160 */
> -	{0x3802, 0x00},
> -	{0x3803, 0xf2}, /* vstart 242 */
> -	{0x3804, 0x05},
> -	{0x3805, 0xbf}, /* hend 1471 */
> -	{0x3806, 0x03},
> -	{0x3807, 0xdd}, /* vend 989 */
> -	{0x3808, 0x05},
> -	{0x3809, 0x10}, /* hsize 1296 */
> -	{0x380a, 0x02},
> -	{0x380b, 0xe0}, /* vsize 736 */
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8}, /* htotal 1704 */
> -	{0x3810, 0x00},
> -	{0x3811, 0x08},
> -	{0x3812, 0x00},
> -	{0x3813, 0x06},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x4008, 0x02},
> -	{0x4009, 0x09},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x05},
> -	{0x5705, 0x10},
> -	{0x5706, 0x02},
> -	{0x5707, 0xe0},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - * 1296x976 30fps  VBlanking 1lane 10Bit(no-scaling)
> - */
> -static struct ov2680_reg const ov2680_1296x976_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0xa0}, /* hstart 160 */
> -	{0x3802, 0x00},
> -	{0x3803, 0x78}, /* vstart 120 */
> -	{0x3804, 0x05},
> -	{0x3805, 0xbf}, /* hend 1471 */
> -	{0x3806, 0x04},
> -	{0x3807, 0x57}, /* vend 1111 */
> -	{0x3808, 0x05},
> -	{0x3809, 0x10}, /* hsize 1296 */
> -	{0x380a, 0x03},
> -	{0x380b, 0xd0}, /* vsize 976 */
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8}, /* htotal 1704 */
> -	{0x3810, 0x00},
> -	{0x3811, 0x08},
> -	{0x3812, 0x00},
> -	{0x3813, 0x08},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x4008, 0x02},
> -	{0x4009, 0x09},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x05},
> -	{0x5705, 0x10},
> -	{0x5706, 0x03},
> -	{0x5707, 0xd0},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00}, //mirror/flip
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - *   1456*1096 30fps  VBlanking 1lane 10bit(no-scaling)
> - */
> -static struct ov2680_reg const ov2680_1456x1096_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0x90},
> -	{0x3802, 0x00},
> -	{0x3803, 0x78},
> -	{0x3804, 0x06},
> -	{0x3805, 0x4f},
> -	{0x3806, 0x04},
> -	{0x3807, 0xC0},
> -	{0x3808, 0x05},
> -	{0x3809, 0xb0},
> -	{0x380a, 0x04},
> -	{0x380b, 0x48},
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8},
> -	{0x3810, 0x00},
> -	{0x3811, 0x08},
> -	{0x3812, 0x00},
> -	{0x3813, 0x00},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x4008, 0x02},
> -	{0x4009, 0x09},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x05},
> -	{0x5705, 0xb0},
> -	{0x5706, 0x04},
> -	{0x5707, 0x48},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00},
> -	// {0x5090, 0x0c},
> -	{}
> -};
> -
> -/*
> - *1616x916  30fps  VBlanking 1lane 10bit
> - */
> -
> -static struct ov2680_reg const ov2680_1616x916_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0x00},
> -	{0x3802, 0x00},
> -	{0x3803, 0x96},
> -	{0x3804, 0x06},
> -	{0x3805, 0x4f},
> -	{0x3806, 0x04},
> -	{0x3807, 0x39},
> -	{0x3808, 0x06},
> -	{0x3809, 0x50},
> -	{0x380a, 0x03},
> -	{0x380b, 0x94},
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8},
> -	{0x3810, 0x00},
> -	{0x3811, 0x00},
> -	{0x3812, 0x00},
> -	{0x3813, 0x08},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x4008, 0x02},
> -	{0x4009, 0x09},
> -	{0x5081, 0x41},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x06},
> -	{0x5705, 0x50},
> -	{0x5706, 0x03},
> -	{0x5707, 0x94},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00},
> -	// {0x5090, 0x0C},
> -	{}
> -};
> -
> -/*
> - * 1616x1082 30fps VBlanking 1lane 10Bit
> - */
> -static struct ov2680_reg const ov2680_1616x1082_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0x00},
> -	{0x3802, 0x00},
> -	{0x3803, 0x86},
> -	{0x3804, 0x06},
> -	{0x3805, 0x4f},
> -	{0x3806, 0x04},
> -	{0x3807, 0xbf},
> -	{0x3808, 0x06},
> -	{0x3809, 0x50},
> -	{0x380a, 0x04},
> -	{0x380b, 0x3a},
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8},
> -	{0x3810, 0x00},
> -	{0x3811, 0x00},
> -	{0x3812, 0x00},
> -	{0x3813, 0x00},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x06},
> -	{0x5705, 0x50},
> -	{0x5706, 0x04},
> -	{0x5707, 0x3a},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00},
> -	// {0x5090, 0x0C},
> -	{0x4008, 0x02},
> -	{0x4009, 0x09},
> -	{0x5081, 0x41},
> -	{}
> -};
> -
> -/*
> - * 1616x1216 30fps VBlanking 1lane 10Bit
> - */
> -static struct ov2680_reg const ov2680_1616x1216_30fps[] = {
> -	{0x3086, 0x00},
> -	{0x370a, 0x21},
> -	{0x3801, 0x00},
> -	{0x3802, 0x00},
> -	{0x3803, 0x00},
> -	{0x3804, 0x06},
> -	{0x3805, 0x4f},
> -	{0x3806, 0x04},
> -	{0x3807, 0xbf},
> -	{0x3808, 0x06},
> -	{0x3809, 0x50},//50},//4line for mirror and flip
> -	{0x380a, 0x04},
> -	{0x380b, 0xc0},//c0},
> -	{0x380c, 0x06},
> -	{0x380d, 0xa8},
> -	{0x3810, 0x00},
> -	{0x3811, 0x00},
> -	{0x3812, 0x00},
> -	{0x3813, 0x00},
> -	{0x3814, 0x11},
> -	{0x3815, 0x11},
> -	{0x4008, 0x00},
> -	{0x4009, 0x0b},
> -	{0x5081, 0x01},
> -	{0x5708, 0x01}, //add for full size flip off and mirror off 2014/09/11
> -	{0x5704, 0x06},
> -	{0x5705, 0x50},
> -	{0x5706, 0x04},
> -	{0x5707, 0xc0},
> -	{0x3820, 0xc0},
> -	{0x3821, 0x00},
> -	// {0x5090, 0x0C},
> -	{}
> -};
> -
> -static struct ov2680_resolution ov2680_res_preview[] = {
> -	{
> -		.width = 1616,
> -		.height = 1216,
> -		.pix_clk_freq = 66,
> -		.fps = 30,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_1616x1216_30fps,
> -	},
> -	{
> -		.width = 1616,
> -		.height = 1082,
> -		.pix_clk_freq = 66,
> -		.fps = 30,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_1616x1082_30fps,
> -	},
> -	{
> -		.width = 1616,
> -		.height = 916,
> -		.fps = 30,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_1616x916_30fps,
> -	},
> -	{
> -		.width = 1456,
> -		.height = 1096,
> -		.fps = 30,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_1456x1096_30fps,
> -	},
> -	{
> -		.width = 1296,
> -		.height = 976,
> -		.fps = 30,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_1296x976_30fps,
> -	},
> -	{
> -		.width = 1296,
> -		.height = 736,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_720p_30fps,
> -	},
> -	{
> -		.width = 800,
> -		.height = 600,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_800x600_30fps,
> -	},
> -	{
> -		.width = 720,
> -		.height = 592,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_720x592_30fps,
> -	},
> -	{
> -		.width = 656,
> -		.height = 496,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_656x496_30fps,
> -	},
> -	{
> -		.width = 336,
> -		.height = 256,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_QVGA_30fps,
> -	},
> -	{
> -		.width = 352,
> -		.height = 288,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_CIF_30fps,
> -	},
> -	{
> -		.width = 176,
> -		.height = 144,
> -		.fps = 60,
> -		.pix_clk_freq = 66,
> -		.pixels_per_line = 1698,//1704,
> -		.lines_per_frame = 1294,
> -		.skip_frames = 3,
> -		.regs = ov2680_QCIF_30fps,
> -	},
> -};
> -
> -#define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview))
> -
>  #endif
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list
  2023-01-23 12:51 ` [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list Hans de Goede
@ 2023-01-24 10:46   ` Andy Shevchenko
  2023-01-24 11:29     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:49PM +0100, Hans de Goede wrote:
> 3 fixes for the framesize list:
> 
> 1. Drop modes < 640x480, these are made by significant cropping,
>    leading to such a small remainig field-of-view that they are
>    not really usable

Wondering if we have an algo to actually scale instead of crop.

> 2. 1616x1082 is presumably intended to be 1600x1080 + 16 pixels
>    padding in both dimensions, but the height is wrong.
>    Change this to 1616x1096.
> 
> 3. The 800x600 mode is missing the 16 pixels padding and
>    720x592 is missing 16 pixels padding in its width and
>    the 720x576 base mode is a mode with non square pixels,
>    while the sensor has square pixels.
>    Replace both with 768x576 + 16 pixels padding -> 784x592

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 432539dd274c..81fd36b09090 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -700,17 +700,13 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
>  {
>  	static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = {
>  		{ 1616, 1216 },
> -		{ 1616, 1082 },
> +		{ 1616, 1096 },
>  		{ 1616,  916 },
>  		{ 1456, 1096 },
>  		{ 1296,  976 },
>  		{ 1296,  736 },
> -		{  800,  600 },
> -		{  720,  592 },
> +		{  784,  592 },
>  		{  656,  496 },
> -		{  336,  256 },
> -		{  352,  288 },
> -		{  176,  144 },
>  	};
>  	int index = fse->index;
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h
  2023-01-23 12:51 ` [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h Hans de Goede
@ 2023-01-24 10:46   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:50PM +0100, Hans de Goede wrote:
> Remove a bunch of unused data-types and defines from ov2680.h.

Good patch!
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/ov2680.h | 60 ----------------------
>  1 file changed, 60 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 20ef59928cb1..189d1b2b7584 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -46,45 +46,11 @@
>  
>  #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
>  
> -#define OV2680_BIN_FACTOR_MAX 4
> -
>  #define MAX_FMTS		1
>  
> -/* sensor_mode_data read_mode adaptation */
> -#define OV2680_READ_MODE_BINNING_ON	0x0400
> -#define OV2680_READ_MODE_BINNING_OFF	0x00
>  #define OV2680_INTEGRATION_TIME_MARGIN	8
> -
> -#define OV2680_MAX_EXPOSURE_VALUE	0xFFF1
> -#define OV2680_MAX_GAIN_VALUE		0xFF
> -
> -/*
> - * focal length bits definition:
> - * bits 31-16: numerator, bits 15-0: denominator
> - */
> -#define OV2680_FOCAL_LENGTH_DEFAULT 0x1B70064
> -
> -/*
> - * current f-number bits definition:
> - * bits 31-16: numerator, bits 15-0: denominator
> - */
> -#define OV2680_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 OV2680_F_NUMBER_RANGE 0x180a180a
>  #define OV2680_ID	0x2680
>  
> -#define OV2680_FINE_INTG_TIME_MIN 0
> -#define OV2680_FINE_INTG_TIME_MAX_MARGIN 0
> -#define OV2680_COARSE_INTG_TIME_MIN 1
> -#define OV2680_COARSE_INTG_TIME_MAX_MARGIN 6
> -
>  /*
>   * OV2680 System control registers
>   */
> @@ -147,19 +113,6 @@
>  #define OV2680_START_STREAMING			0x01
>  #define OV2680_STOP_STREAMING			0x00
>  
> -#define OV2680_INVALID_CONFIG	0xffffffff
> -
> -struct regval_list {
> -	u16 reg_num;
> -	u8 value;
> -};
> -
> -struct ov2680_format {
> -	u8 *desc;
> -	u32 pixelformat;
> -	struct ov2680_reg *regs;
> -};
> -
>  /*
>   * ov2680 device structure.
>   */
> @@ -216,18 +169,6 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
>  			     ctrls.handler)->sd;
>  }
>  
> -#define OV2680_MAX_WRITE_BUF_SIZE	30
> -
> -struct ov2680_write_buffer {
> -	u16 addr;
> -	u8 data[OV2680_MAX_WRITE_BUF_SIZE];
> -};
> -
> -struct ov2680_write_ctrl {
> -	int index;
> -	struct ov2680_write_buffer buffer;
> -};
> -
>  static struct ov2680_reg const ov2680_global_setting[] = {
>  	{0x0103, 0x01},
>  	{0x3002, 0x00},
> @@ -304,7 +245,6 @@ static struct ov2680_reg const ov2680_global_setting[] = {
>  	{0x5793, 0x00},
>  	{0x5794, 0x03}, //based OV2680_R1A_AM10.ovt,Adjust DPC setting (57xx) on 14/06/13
>  	{0x0100, 0x00},	//stream off
> -
>  	{}
>  };
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define
  2023-01-23 12:51 ` [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define Hans de Goede
@ 2023-01-24 10:48   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:51PM +0100, Hans de Goede wrote:
> The ov2680 only supports a single format, there is no need to
> use a define for this.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

(One nit-pick below)

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 2 +-
>  drivers/staging/media/atomisp/i2c/ov2680.h         | 2 --
>  2 files changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 81fd36b09090..994b6fe40069 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -687,7 +687,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd,
>  				 struct v4l2_subdev_state *sd_state,
>  				 struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	if (code->index >= MAX_FMTS)
> +	if (code->index)

Perhaps a comment above?

	/* We support only a single format */

>  		return -EINVAL;
>  
>  	code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 189d1b2b7584..5aa46f669715 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -46,8 +46,6 @@
>  
>  #define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
>  
> -#define MAX_FMTS		1
> -
>  #define OV2680_INTEGRATION_TIME_MARGIN	8
>  #define OV2680_ID	0x2680
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values
  2023-01-23 12:51 ` [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values Hans de Goede
@ 2023-01-24 10:49   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:49 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:52PM +0100, Hans de Goede wrote:
> Use the same indentation level for all #define values.

Can we at the same time add spaces surround the text?
With that,
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/staging/media/atomisp/i2c/ov2680.h | 36 +++++++++++-----------
>  1 file changed, 18 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 5aa46f669715..f0641dd611c3 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -44,10 +44,10 @@
>  /* If possible send 16 extra rows / lines to the ISP as padding */
>  #define OV2680_END_MARGIN			16
>  
> -#define OV2680_FOCAL_LENGTH_NUM	334	/*3.34mm*/
> +#define OV2680_FOCAL_LENGTH_NUM			334	/*3.34mm*/
>  
> -#define OV2680_INTEGRATION_TIME_MARGIN	8
> -#define OV2680_ID	0x2680
> +#define OV2680_INTEGRATION_TIME_MARGIN		8
> +#define OV2680_ID				0x2680
>  
>  /*
>   * OV2680 System control registers
> @@ -61,23 +61,23 @@
>  #define OV2680_SC_CMMN_SCCB_ID			0x302B /* 0x300C*/
>  #define OV2680_SC_CMMN_SUB_ID			0x302A /* process, version*/
>  
> -#define OV2680_GROUP_ACCESS							0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
> +#define OV2680_GROUP_ACCESS			0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
>  
>  #define OV2680_REG_EXPOSURE_PK_HIGH		0x3500
>  #define OV2680_REG_GAIN_PK			0x350a
>  
> -#define OV2680_HORIZONTAL_START_H					0x3800 /*Bit[11:8]*/
> -#define OV2680_HORIZONTAL_START_L					0x3801 /*Bit[7:0]*/
> -#define OV2680_VERTICAL_START_H						0x3802 /*Bit[11:8]*/
> -#define OV2680_VERTICAL_START_L						0x3803 /*Bit[7:0]*/
> -#define OV2680_HORIZONTAL_END_H						0x3804 /*Bit[11:8]*/
> -#define OV2680_HORIZONTAL_END_L						0x3805 /*Bit[7:0]*/
> -#define OV2680_VERTICAL_END_H						0x3806 /*Bit[11:8]*/
> -#define OV2680_VERTICAL_END_L						0x3807 /*Bit[7:0]*/
> -#define OV2680_HORIZONTAL_OUTPUT_SIZE_H				0x3808 /*Bit[3:0]*/
> -#define OV2680_HORIZONTAL_OUTPUT_SIZE_L				0x3809 /*Bit[7:0]*/
> -#define OV2680_VERTICAL_OUTPUT_SIZE_H				0x380a /*Bit[3:0]*/
> -#define OV2680_VERTICAL_OUTPUT_SIZE_L				0x380b /*Bit[7:0]*/
> +#define OV2680_HORIZONTAL_START_H		0x3800 /*Bit[11:8]*/
> +#define OV2680_HORIZONTAL_START_L		0x3801 /*Bit[7:0]*/
> +#define OV2680_VERTICAL_START_H			0x3802 /*Bit[11:8]*/
> +#define OV2680_VERTICAL_START_L			0x3803 /*Bit[7:0]*/
> +#define OV2680_HORIZONTAL_END_H			0x3804 /*Bit[11:8]*/
> +#define OV2680_HORIZONTAL_END_L			0x3805 /*Bit[7:0]*/
> +#define OV2680_VERTICAL_END_H			0x3806 /*Bit[11:8]*/
> +#define OV2680_VERTICAL_END_L			0x3807 /*Bit[7:0]*/
> +#define OV2680_HORIZONTAL_OUTPUT_SIZE_H		0x3808 /*Bit[3:0]*/
> +#define OV2680_HORIZONTAL_OUTPUT_SIZE_L		0x3809 /*Bit[7:0]*/
> +#define OV2680_VERTICAL_OUTPUT_SIZE_H		0x380a /*Bit[3:0]*/
> +#define OV2680_VERTICAL_OUTPUT_SIZE_L		0x380b /*Bit[7:0]*/
>  #define OV2680_HTS_H				0x380c
>  #define OV2680_HTS_L				0x380d
>  #define OV2680_VTS_H				0x380e
> @@ -89,7 +89,7 @@
>  #define OV2680_X_INC				0x3814
>  #define OV2680_Y_INC				0x3815
>  
> -#define OV2680_FRAME_OFF_NUM						0x4202
> +#define OV2680_FRAME_OFF_NUM			0x4202
>  
>  /*Flip/Mirror*/
>  #define OV2680_REG_FORMAT1			0x3820
> @@ -98,7 +98,7 @@
>  #define OV2680_MWB_RED_GAIN_H			0x5004/*0x3400*/
>  #define OV2680_MWB_GREEN_GAIN_H			0x5006/*0x3402*/
>  #define OV2680_MWB_BLUE_GAIN_H			0x5008/*0x3404*/
> -#define OV2680_MWB_GAIN_MAX				0x0fff
> +#define OV2680_MWB_GAIN_MAX			0x0fff
>  
>  #define OV2680_REG_ISP_CTRL00			0x5080
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 45/57] media: atomisp: ov2680: Cleanup includes
  2023-01-23 12:51 ` [PATCH 45/57] media: atomisp: ov2680: Cleanup includes Hans de Goede
@ 2023-01-24 10:50   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:53PM +0100, Hans de Goede wrote:
> Remove unused includes and sort the remaining ones alphabetically.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
See below.

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 19 +++----------------
>  1 file changed, 3 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 994b6fe40069..1dc821ca4e68 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -15,27 +15,14 @@
>   *
>   */
>  
> -#include <asm/unaligned.h>
> -
> -#include <linux/module.h>
> -#include <linux/types.h>
> -#include <linux/kernel.h>
> -#include <linux/mm.h>
> -#include <linux/string.h>
> -#include <linux/errno.h>
> -#include <linux/init.h>
> -#include <linux/kmod.h>
> +#include <linux/acpi.h>
>  #include <linux/device.h>
> -#include <linux/delay.h>
> -#include <linux/slab.h>
>  #include <linux/i2c.h>
> -#include <linux/moduleparam.h>
> +#include <linux/module.h>
> +#include <linux/types.h>

+ Blank line?

>  #include <media/ovxxxx_16bit_addr_reg_helpers.h>
>  #include <media/v4l2-device.h>
> -#include <linux/io.h>
> -#include <linux/acpi.h>

+ Blank line?

>  #include "../include/linux/atomisp_gmin_platform.h"

> -

I would leave it to make separate groups of headers.

>  #include "ov2680.h"
>  
>  static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = {
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started
  2023-01-23 12:51 ` [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started Hans de Goede
@ 2023-01-24 10:51   ` Andy Shevchenko
  2023-01-24 11:31     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:51 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:54PM +0100, Hans de Goede wrote:
> Move the setting of the mode to stream on, this also allows
> delaying power-on till streaming is started.
> 
> And drop the deprecated s_power callback since this now no long
> is necessary.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

See below.

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 101 +++++++-----------
>  1 file changed, 41 insertions(+), 60 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 1dc821ca4e68..2a8c4508cc66 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -327,24 +327,6 @@ static int power_down(struct v4l2_subdev *sd)
>  	return 0;
>  }
>  
> -static int ov2680_s_power(struct v4l2_subdev *sd, int on)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	int ret;
> -
> -	mutex_lock(&dev->input_lock);
> -
> -	if (on == 0) {
> -		ret = power_down(sd);
> -	} else {
> -		ret = power_up(sd);
> -	}
> -
> -	mutex_unlock(&dev->input_lock);
> -
> -	return ret;
> -}
> -
>  static struct v4l2_mbus_framefmt *
>  __ov2680_get_pad_format(struct ov2680_device *sensor,
>  			struct v4l2_subdev_state *state,
> @@ -393,14 +375,12 @@ static void ov2680_calc_mode(struct ov2680_device *sensor, int width, int height
>  	sensor->mode.vts = OV2680_LINES_PER_FRAME;
>  }
>  
> -static int ov2680_set_mode(struct ov2680_device *sensor, int width, int height)
> +static int ov2680_set_mode(struct ov2680_device *sensor)
>  {
>  	struct i2c_client *client = sensor->client;
>  	u8 pll_div, unknown, inc, fmt1, fmt2;
>  	int ret;
>  
> -	ov2680_calc_mode(sensor, width, height);
> -
>  	if (sensor->mode.binning) {
>  		pll_div = 1;
>  		unknown = 0x23;
> @@ -500,7 +480,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
>  	struct v4l2_mbus_framefmt *fmt;
>  	unsigned int width, height;
> -	int ret = 0;
>  
>  	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
>  		__func__,
> @@ -518,23 +497,10 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
>  		return 0;
>  
> -	dev_dbg(&client->dev, "%s: %dx%d\n",
> -		__func__, fmt->width, fmt->height);
> -
>  	mutex_lock(&dev->input_lock);
> -
> -	/* s_power has not been called yet for std v4l2 clients (camorama) */
> -	power_up(sd);
> -
> -	ret = ov2680_set_mode(dev, fmt->width, fmt->height);
> -	if (ret < 0)
> -		goto err;
> -
> -	/* Restore value of all ctrls */
> -	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
> -err:
> +	ov2680_calc_mode(dev, fmt->width, fmt->height);
>  	mutex_unlock(&dev->input_lock);
> -	return ret;
> +	return 0;
>  }
>  
>  static int ov2680_get_fmt(struct v4l2_subdev *sd,
> @@ -584,30 +550,50 @@ static int ov2680_detect(struct i2c_client *client)
>  
>  static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	int ret;
> +	int ret = 0;
>  
> -	mutex_lock(&dev->input_lock);
> -	if (enable)
> -		dev_dbg(&client->dev, "ov2680_s_stream one\n");
> -	else
> -		dev_dbg(&client->dev, "ov2680_s_stream off\n");
> -
> -	ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM,
> -				enable ? OV2680_START_STREAMING : OV2680_STOP_STREAMING);
> -	if (ret == 0) {
> -		dev->is_streaming = enable;
> -		v4l2_ctrl_activate(dev->ctrls.vflip, !enable);
> -		v4l2_ctrl_activate(dev->ctrls.hflip, !enable);
> +	mutex_lock(&sensor->input_lock);
> +
> +	if (sensor->is_streaming == enable) {
> +		dev_warn(&client->dev, "stream already %sed\n", enable ? "start" : "stopp");

stopP ?!

> +		goto error_unlock;
>  	}
>  
> -	//otp valid at stream on state
> -	//if(!dev->otp_data)
> -	//	dev->otp_data = ov2680_otp_read(sd);
> +	if (enable) {
> +		ret = power_up(sd);
> +		if (ret)
> +			goto error_unlock;
>  
> -	mutex_unlock(&dev->input_lock);
> +		ret = ov2680_set_mode(sensor);
> +		if (ret)
> +			goto error_power_down;
>  
> +		/* Restore value of all ctrls */
> +		ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> +		if (ret)
> +			goto error_power_down;
> +
> +		ret = ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_START_STREAMING);
> +		if (ret)
> +			goto error_power_down;
> +	} else {
> +		ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING);
> +		power_down(sd);
> +	}
> +
> +	sensor->is_streaming = enable;
> +	v4l2_ctrl_activate(sensor->ctrls.vflip, !enable);
> +	v4l2_ctrl_activate(sensor->ctrls.hflip, !enable);
> +
> +	mutex_unlock(&sensor->input_lock);
> +	return 0;
> +
> +error_power_down:
> +	power_down(sd);
> +error_unlock:
> +	mutex_unlock(&sensor->input_lock);
>  	return ret;
>  }
>  
> @@ -736,10 +722,6 @@ static const struct v4l2_subdev_sensor_ops ov2680_sensor_ops = {
>  	.g_skip_frames	= ov2680_g_skip_frames,
>  };
>  
> -static const struct v4l2_subdev_core_ops ov2680_core_ops = {
> -	.s_power = ov2680_s_power,
> -};
> -
>  static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
>  	.enum_mbus_code = ov2680_enum_mbus_code,
>  	.enum_frame_size = ov2680_enum_frame_size,
> @@ -749,7 +731,6 @@ static const struct v4l2_subdev_pad_ops ov2680_pad_ops = {
>  };
>  
>  static const struct v4l2_subdev_ops ov2680_ops = {
> -	.core = &ov2680_core_ops,
>  	.video = &ov2680_video_ops,
>  	.pad = &ov2680_pad_ops,
>  	.sensor = &ov2680_sensor_ops,
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support
  2023-01-23 12:51 ` [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support Hans de Goede
@ 2023-01-24 10:53   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:53 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:55PM +0100, Hans de Goede wrote:
> Add runtime-pm support. This is a preparation patch for letting
> ACPI deal with the regulators and clocks instead of the DIY code
> in atomisp_gmin_platform.c.

Good one!
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 57 ++++++++++++-------
>  drivers/staging/media/atomisp/i2c/ov2680.h    |  1 -
>  2 files changed, 36 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 2a8c4508cc66..881340d7466f 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -19,6 +19,7 @@
>  #include <linux/device.h>
>  #include <linux/i2c.h>
>  #include <linux/module.h>
> +#include <linux/pm_runtime.h>
>  #include <linux/types.h>
>  #include <media/ovxxxx_16bit_addr_reg_helpers.h>
>  #include <media/v4l2-device.h>
> @@ -138,7 +139,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	int ret;
>  
> -	if (!sensor->power_on) {
> +	/* Only apply changes to the controls if the device is powered up */
> +	if (!pm_runtime_get_if_in_use(sensor->sd.dev)) {
>  		ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
>  		return 0;
>  	}
> @@ -162,6 +164,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>  	default:
>  		ret = -EINVAL;
>  	}
> +
> +	pm_runtime_put(sensor->sd.dev);
>  	return ret;
>  }
>  
> @@ -244,9 +248,6 @@ static int power_up(struct v4l2_subdev *sd)
>  		return -ENODEV;
>  	}
>  
> -	if (dev->power_on)
> -		return 0; /* Already on */
> -
>  	/* power control */
>  	ret = power_ctrl(sd, 1);
>  	if (ret)
> @@ -275,7 +276,6 @@ static int power_up(struct v4l2_subdev *sd)
>  	if (ret)
>  		goto fail_init_registers;
>  
> -	dev->power_on = true;
>  	return 0;
>  
>  fail_init_registers:
> @@ -301,9 +301,6 @@ static int power_down(struct v4l2_subdev *sd)
>  		return -ENODEV;
>  	}
>  
> -	if (!dev->power_on)
> -		return 0; /* Already off */
> -
>  	ret = dev->platform_data->flisclk_ctrl(sd, 0);
>  	if (ret)
>  		dev_err(&client->dev, "flisclk failed\n");
> @@ -323,7 +320,6 @@ static int power_down(struct v4l2_subdev *sd)
>  		return ret;
>  	}
>  
> -	dev->power_on = false;
>  	return 0;
>  }
>  
> @@ -562,8 +558,8 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  	}
>  
>  	if (enable) {
> -		ret = power_up(sd);
> -		if (ret)
> +		ret = pm_runtime_get_sync(sensor->sd.dev);
> +		if (ret < 0)
>  			goto error_unlock;
>  
>  		ret = ov2680_set_mode(sensor);
> @@ -580,7 +576,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  			goto error_power_down;
>  	} else {
>  		ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING);
> -		power_down(sd);
> +		pm_runtime_put(sensor->sd.dev);
>  	}
>  
>  	sensor->is_streaming = enable;
> @@ -591,7 +587,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  	return 0;
>  
>  error_power_down:
> -	power_down(sd);
> +	pm_runtime_put(sensor->sd.dev);
>  error_unlock:
>  	mutex_unlock(&sensor->input_lock);
>  	return ret;
> @@ -612,8 +608,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  
>  	mutex_lock(&dev->input_lock);
>  
> -	ret = power_up(sd);
> -	if (ret) {
> +	ret = pm_runtime_get_sync(&client->dev);
> +	if (ret < 0) {
>  		dev_err(&client->dev, "ov2680 power-up err.\n");
>  		goto fail_power_on;
>  	}
> @@ -630,11 +626,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  	}
>  
>  	/* turn off sensor, after probed */
> -	ret = power_down(sd);
> -	if (ret) {
> -		dev_err(&client->dev, "ov2680 power-off err.\n");
> -		goto fail_csi_cfg;
> -	}
> +	pm_runtime_put(&client->dev);
>  	mutex_unlock(&dev->input_lock);
>  
>  	return 0;
> @@ -642,7 +634,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  fail_csi_cfg:
>  	dev->platform_data->csi_cfg(sd, 0);
>  fail_power_on:
> -	power_down(sd);
> +	pm_runtime_put(&client->dev);
>  	dev_err(&client->dev, "sensor power-gating failed\n");
>  	mutex_unlock(&dev->input_lock);
>  	return ret;
> @@ -787,6 +779,7 @@ static void ov2680_remove(struct i2c_client *client)
>  	v4l2_device_unregister_subdev(sd);
>  	media_entity_cleanup(&dev->sd.entity);
>  	v4l2_ctrl_handler_free(&dev->ctrls.handler);
> +	pm_runtime_disable(&client->dev);
>  	kfree(dev);
>  }
>  
> @@ -813,6 +806,11 @@ static int ov2680_probe(struct i2c_client *client)
>  		goto out_free;
>  	}
>  
> +	pm_runtime_set_suspended(&client->dev);
> +	pm_runtime_enable(&client->dev);
> +	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
> +	pm_runtime_use_autosuspend(&client->dev);
> +
>  	ret = ov2680_s_config(&dev->sd, client->irq, pdata);
>  	if (ret)
>  		goto out_free;
> @@ -849,6 +847,22 @@ static int ov2680_probe(struct i2c_client *client)
>  	return ret;
>  }
>  
> +static int ov2680_suspend(struct device *dev)
> +{
> +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +
> +	return power_down(sd);
> +}
> +
> +static int ov2680_resume(struct device *dev)
> +{
> +	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +
> +	return power_up(sd);
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL);
> +
>  static const struct acpi_device_id ov2680_acpi_match[] = {
>  	{"XXOV2680"},
>  	{"OVTI2680"},
> @@ -859,6 +873,7 @@ MODULE_DEVICE_TABLE(acpi, ov2680_acpi_match);
>  static struct i2c_driver ov2680_driver = {
>  	.driver = {
>  		.name = "ov2680",
> +		.pm = pm_sleep_ptr(&ov2680_pm_ops),
>  		.acpi_match_table = ov2680_acpi_match,
>  	},
>  	.probe_new = ov2680_probe,
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index f0641dd611c3..58593da50f6f 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -120,7 +120,6 @@ struct ov2680_device {
>  	struct mutex input_lock;
>  	struct i2c_client *client;
>  	struct camera_sensor_platform_data *platform_data;
> -	bool power_on;
>  	bool is_streaming;
>  
>  	struct ov2680_mode {
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/
  2023-01-23 12:51 ` [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/ Hans de Goede
@ 2023-01-24 10:54   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:54 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:56PM +0100, Hans de Goede wrote:
> Using dev as name for variables pointing to struct ov2680_device is a bit
> unfortunate choice.
> 
> All the recently added / rewritten code is already using sensor for this,
> replace the remaining usages of "struct ov2680_device *dev" with
> "struct ov2680_device *sensor".
> 
> Note the power_up()/power_down() related functions are not changed as
> these will be removed in one of the next patches.

No functional changes. ?

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 74 +++++++++----------
>  1 file changed, 37 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 881340d7466f..5f26508a1e5a 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -472,7 +472,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  			  struct v4l2_subdev_state *sd_state,
>  			  struct v4l2_subdev_format *format)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
>  	struct v4l2_mbus_framefmt *fmt;
>  	unsigned int width, height;
> @@ -485,17 +485,17 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
>  	width = min_t(unsigned int, ALIGN(format->format.width, 2), OV2680_NATIVE_WIDTH);
>  	height = min_t(unsigned int, ALIGN(format->format.height, 2), OV2680_NATIVE_HEIGHT);
>  
> -	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
> -	ov2680_fill_format(dev, fmt, width, height);
> +	fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which);
> +	ov2680_fill_format(sensor, fmt, width, height);
>  
>  	format->format = *fmt;
>  
>  	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
>  		return 0;
>  
> -	mutex_lock(&dev->input_lock);
> -	ov2680_calc_mode(dev, fmt->width, fmt->height);
> -	mutex_unlock(&dev->input_lock);
> +	mutex_lock(&sensor->input_lock);
> +	ov2680_calc_mode(sensor, fmt->width, fmt->height);
> +	mutex_unlock(&sensor->input_lock);
>  	return 0;
>  }
>  
> @@ -503,10 +503,10 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
>  			  struct v4l2_subdev_state *sd_state,
>  			  struct v4l2_subdev_format *format)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	struct v4l2_mbus_framefmt *fmt;
>  
> -	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
> +	fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which);
>  	format->format = *fmt;
>  	return 0;
>  }
> @@ -596,17 +596,17 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  static int ov2680_s_config(struct v4l2_subdev *sd,
>  			   int irq, void *platform_data)
>  {
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
>  	int ret = 0;
>  
>  	if (!platform_data)
>  		return -ENODEV;
>  
> -	dev->platform_data =
> +	sensor->platform_data =
>  	    (struct camera_sensor_platform_data *)platform_data;
>  
> -	mutex_lock(&dev->input_lock);
> +	mutex_lock(&sensor->input_lock);
>  
>  	ret = pm_runtime_get_sync(&client->dev);
>  	if (ret < 0) {
> @@ -614,7 +614,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  		goto fail_power_on;
>  	}
>  
> -	ret = dev->platform_data->csi_cfg(sd, 1);
> +	ret = sensor->platform_data->csi_cfg(sd, 1);
>  	if (ret)
>  		goto fail_csi_cfg;
>  
> @@ -627,16 +627,16 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  
>  	/* turn off sensor, after probed */
>  	pm_runtime_put(&client->dev);
> -	mutex_unlock(&dev->input_lock);
> +	mutex_unlock(&sensor->input_lock);
>  
>  	return 0;
>  
>  fail_csi_cfg:
> -	dev->platform_data->csi_cfg(sd, 0);
> +	sensor->platform_data->csi_cfg(sd, 0);
>  fail_power_on:
>  	pm_runtime_put(&client->dev);
>  	dev_err(&client->dev, "sensor power-gating failed\n");
> -	mutex_unlock(&dev->input_lock);
> +	mutex_unlock(&sensor->input_lock);
>  	return ret;
>  }
>  
> @@ -770,35 +770,35 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
>  static void ov2680_remove(struct i2c_client *client)
>  {
>  	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  
>  	dev_dbg(&client->dev, "ov2680_remove...\n");
>  
> -	dev->platform_data->csi_cfg(sd, 0);
> +	sensor->platform_data->csi_cfg(sd, 0);
>  
>  	v4l2_device_unregister_subdev(sd);
> -	media_entity_cleanup(&dev->sd.entity);
> -	v4l2_ctrl_handler_free(&dev->ctrls.handler);
> +	media_entity_cleanup(&sensor->sd.entity);
> +	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>  	pm_runtime_disable(&client->dev);
> -	kfree(dev);
> +	kfree(sensor);
>  }
>  
>  static int ov2680_probe(struct i2c_client *client)
>  {
> -	struct ov2680_device *dev;
> +	struct ov2680_device *sensor;
>  	int ret;
>  	void *pdata;
>  
> -	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> -	if (!dev)
> +	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
> +	if (!sensor)
>  		return -ENOMEM;
>  
> -	mutex_init(&dev->input_lock);
> +	mutex_init(&sensor->input_lock);
>  
> -	dev->client = client;
> -	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
> +	sensor->client = client;
> +	v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops);
>  
> -	pdata = gmin_camera_platform_data(&dev->sd,
> +	pdata = gmin_camera_platform_data(&sensor->sd,
>  					  ATOMISP_INPUT_FORMAT_RAW_10,
>  					  atomisp_bayer_order_bggr);
>  	if (!pdata) {
> @@ -811,29 +811,29 @@ static int ov2680_probe(struct i2c_client *client)
>  	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
>  	pm_runtime_use_autosuspend(&client->dev);
>  
> -	ret = ov2680_s_config(&dev->sd, client->irq, pdata);
> +	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
>  	if (ret)
>  		goto out_free;
>  
> -	dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> -	dev->pad.flags = MEDIA_PAD_FL_SOURCE;
> -	dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
> +	sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
>  
> -	ret = ov2680_init_controls(dev);
> +	ret = ov2680_init_controls(sensor);
>  	if (ret) {
>  		ov2680_remove(client);
>  		return ret;
>  	}
>  
> -	ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad);
> +	ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
>  	if (ret) {
>  		ov2680_remove(client);
>  		return ret;
>  	}
>  
> -	ov2680_fill_format(dev, &dev->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
> +	ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
>  
> -	ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
> +	ret = atomisp_register_i2c_module(&sensor->sd, pdata, RAW_CAMERA);
>  	if (ret) {
>  		ov2680_remove(client);
>  		return ret;
> @@ -842,8 +842,8 @@ static int ov2680_probe(struct i2c_client *client)
>  	return 0;
>  out_free:
>  	dev_dbg(&client->dev, "+++ out free\n");
> -	v4l2_device_unregister_subdev(&dev->sd);
> -	kfree(dev);
> +	v4l2_device_unregister_subdev(&sensor->sd);
> +	kfree(sensor);
>  	return ret;
>  }
>  
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct
  2023-01-23 12:51 ` [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct Hans de Goede
@ 2023-01-24 10:55   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:55 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:57PM +0100, Hans de Goede wrote:
> Use devm_kzalloc() to allocate the sensor data struct. It is always free-ed
> as the last step of probe-error-exit or remove, so it can be devm-managed.
> 
> This will make unwinding things easier when support is added to the ov2680
> code to use standard GPIO APIs instead of the custom atomisp_gmin code.
> 
> This also allows dropping the out_free label and use direct return
> on errors.
> 
> This may seem like a functional change since the out_free label also
> did a v4l2_device_unregister_subdev() but at the 2 changed returns
> the device is not registered yet, so that always is a no-op and can
> be dropped.

Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../staging/media/atomisp/i2c/atomisp-ov2680.c   | 16 ++++------------
>  1 file changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 5f26508a1e5a..2b4673092b6a 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -780,7 +780,6 @@ static void ov2680_remove(struct i2c_client *client)
>  	media_entity_cleanup(&sensor->sd.entity);
>  	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>  	pm_runtime_disable(&client->dev);
> -	kfree(sensor);
>  }
>  
>  static int ov2680_probe(struct i2c_client *client)
> @@ -789,7 +788,7 @@ static int ov2680_probe(struct i2c_client *client)
>  	int ret;
>  	void *pdata;
>  
> -	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
> +	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
>  	if (!sensor)
>  		return -ENOMEM;
>  
> @@ -801,10 +800,8 @@ static int ov2680_probe(struct i2c_client *client)
>  	pdata = gmin_camera_platform_data(&sensor->sd,
>  					  ATOMISP_INPUT_FORMAT_RAW_10,
>  					  atomisp_bayer_order_bggr);
> -	if (!pdata) {
> -		ret = -EINVAL;
> -		goto out_free;
> -	}
> +	if (!pdata)
> +		return -EINVAL;
>  
>  	pm_runtime_set_suspended(&client->dev);
>  	pm_runtime_enable(&client->dev);
> @@ -813,7 +810,7 @@ static int ov2680_probe(struct i2c_client *client)
>  
>  	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
>  	if (ret)
> -		goto out_free;
> +		return ret;
>  
>  	sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>  	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
> @@ -840,11 +837,6 @@ static int ov2680_probe(struct i2c_client *client)
>  	}
>  
>  	return 0;
> -out_free:
> -	dev_dbg(&client->dev, "+++ out free\n");
> -	v4l2_device_unregister_subdev(&sensor->sd);
> -	kfree(sensor);
> -	return ret;
>  }
>  
>  static int ov2680_suspend(struct device *dev)
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement
  2023-01-23 12:51 ` [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement Hans de Goede
@ 2023-01-24 10:59   ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 10:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:58PM +0100, Hans de Goede wrote:
> The DSDT of all Windows BYT / CHT devices which I have seen has proper
> ACPI powermagement for the clk and regulators used by the sensors.
> 
> So there is no need for the whole custom atomisp_gmin custom code to
> disable the ACPI pm and directly poke at the PMIC for this.
> 
> Replace all the atomisp_gmin usage with using the new
> atomisp_register_sensor_no_gmin() / atomisp_unregister_subdev()
> helpers which allow registering a sensor with the atomisp code
> without using any of the atomisp_gmin power-management code.
> 
> Note eventually these calls should be replaced by the standard
> v4l2_async_register_subdev_sensor() mechanism.
> 
> But this first requires a bunch of work to the atomisp main code
> to make it set the necessary fwnodes up, similar to how
> drivers/media/pci/intel/ipu3/cio2-bridge.c does this.
> 
> This has been tested on:
> -Trekstor Surftab duo W1 10.1, CHT, AXP288 PMIC, 2x ov2680 sensor
> -Asus T101HA, CHT, TI PMIC, 1x ov2680 sensor
> -MPMAN Converter 9, BYT, AXP288 PMIC, ov2680 back, gc0310 front sensor

Very nice! Long waited change, thanks!

Reviewed-by: Andy Shevchenko <andy@kernel.org>

See below.

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  .../media/atomisp/i2c/atomisp-ov2680.c        | 231 ++++--------------
>  drivers/staging/media/atomisp/i2c/ov2680.h    |   3 +-
>  2 files changed, 53 insertions(+), 181 deletions(-)
> 
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 2b4673092b6a..c5bd7ba1b502 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -17,6 +17,8 @@
>  
>  #include <linux/acpi.h>
>  #include <linux/device.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/gpio/machine.h>
>  #include <linux/i2c.h>
>  #include <linux/module.h>
>  #include <linux/pm_runtime.h>
> @@ -184,145 +186,6 @@ static int ov2680_init_registers(struct v4l2_subdev *sd)
>  	return ret;
>  }
>  
> -static int power_ctrl(struct v4l2_subdev *sd, bool flag)
> -{
> -	int ret = 0;
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -
> -	if (!dev || !dev->platform_data)
> -		return -ENODEV;
> -
> -	dev_dbg(&client->dev, "%s: %s", __func__, flag ? "on" : "off");
> -
> -	if (flag) {
> -		ret |= dev->platform_data->v1p8_ctrl(sd, 1);
> -		ret |= dev->platform_data->v2p8_ctrl(sd, 1);
> -		usleep_range(10000, 15000);
> -	}
> -
> -	if (!flag || ret) {
> -		ret |= dev->platform_data->v1p8_ctrl(sd, 0);
> -		ret |= dev->platform_data->v2p8_ctrl(sd, 0);
> -	}
> -	return ret;
> -}
> -
> -static int gpio_ctrl(struct v4l2_subdev *sd, bool flag)
> -{
> -	int ret;
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -
> -	if (!dev || !dev->platform_data)
> -		return -ENODEV;
> -
> -	/*
> -	 * The OV2680 documents only one GPIO input (#XSHUTDN), but
> -	 * existing integrations often wire two (reset/power_down)
> -	 * because that is the way other sensors work.  There is no
> -	 * way to tell how it is wired internally, so existing
> -	 * firmwares expose both and we drive them symmetrically.
> -	 */
> -	if (flag) {
> -		ret = dev->platform_data->gpio0_ctrl(sd, 1);
> -		usleep_range(10000, 15000);
> -		/* Ignore return from second gpio, it may not be there */
> -		dev->platform_data->gpio1_ctrl(sd, 1);
> -		usleep_range(10000, 15000);
> -	} else {
> -		dev->platform_data->gpio1_ctrl(sd, 0);
> -		ret = dev->platform_data->gpio0_ctrl(sd, 0);
> -	}
> -	return ret;
> -}
> -
> -static int power_up(struct v4l2_subdev *sd)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	int ret;
> -
> -	if (!dev->platform_data) {
> -		dev_err(&client->dev,
> -			"no camera_sensor_platform_data");
> -		return -ENODEV;
> -	}
> -
> -	/* power control */
> -	ret = power_ctrl(sd, 1);
> -	if (ret)
> -		goto fail_power;
> -
> -	/* according to DS, at least 5ms is needed between DOVDD and PWDN */
> -	usleep_range(5000, 6000);
> -
> -	/* gpio ctrl */
> -	ret = gpio_ctrl(sd, 1);
> -	if (ret) {
> -		ret = gpio_ctrl(sd, 1);
> -		if (ret)
> -			goto fail_power;
> -	}
> -
> -	/* flis clock control */
> -	ret = dev->platform_data->flisclk_ctrl(sd, 1);
> -	if (ret)
> -		goto fail_clk;
> -
> -	/* according to DS, 20ms is needed between PWDN and i2c access */
> -	msleep(20);
> -
> -	ret = ov2680_init_registers(sd);
> -	if (ret)
> -		goto fail_init_registers;
> -
> -	return 0;
> -
> -fail_init_registers:
> -	dev->platform_data->flisclk_ctrl(sd, 0);
> -fail_clk:
> -	gpio_ctrl(sd, 0);
> -fail_power:
> -	power_ctrl(sd, 0);
> -	dev_err(&client->dev, "sensor power-up failed\n");
> -
> -	return ret;
> -}
> -
> -static int power_down(struct v4l2_subdev *sd)
> -{
> -	struct ov2680_device *dev = to_ov2680_sensor(sd);
> -	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	int ret = 0;
> -
> -	if (!dev->platform_data) {
> -		dev_err(&client->dev,
> -			"no camera_sensor_platform_data");
> -		return -ENODEV;
> -	}
> -
> -	ret = dev->platform_data->flisclk_ctrl(sd, 0);
> -	if (ret)
> -		dev_err(&client->dev, "flisclk failed\n");
> -
> -	/* gpio ctrl */
> -	ret = gpio_ctrl(sd, 0);
> -	if (ret) {
> -		ret = gpio_ctrl(sd, 0);
> -		if (ret)
> -			dev_err(&client->dev, "gpio failed 2\n");
> -	}
> -
> -	/* power control */
> -	ret = power_ctrl(sd, 0);
> -	if (ret) {
> -		dev_err(&client->dev, "vprog failed.\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
>  static struct v4l2_mbus_framefmt *
>  __ov2680_get_pad_format(struct ov2680_device *sensor,
>  			struct v4l2_subdev_state *state,
> @@ -593,20 +456,10 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
>  	return ret;
>  }
>  
> -static int ov2680_s_config(struct v4l2_subdev *sd,
> -			   int irq, void *platform_data)
> +static int ov2680_s_config(struct v4l2_subdev *sd)
>  {
> -	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  	struct i2c_client *client = v4l2_get_subdevdata(sd);
> -	int ret = 0;
> -
> -	if (!platform_data)
> -		return -ENODEV;
> -
> -	sensor->platform_data =
> -	    (struct camera_sensor_platform_data *)platform_data;
> -
> -	mutex_lock(&sensor->input_lock);
> +	int ret;
>  
>  	ret = pm_runtime_get_sync(&client->dev);
>  	if (ret < 0) {
> @@ -614,29 +467,13 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>  		goto fail_power_on;
>  	}
>  
> -	ret = sensor->platform_data->csi_cfg(sd, 1);
> -	if (ret)
> -		goto fail_csi_cfg;
> -
>  	/* config & detect sensor */
>  	ret = ov2680_detect(client);
> -	if (ret) {
> +	if (ret)
>  		dev_err(&client->dev, "ov2680_detect err s_config.\n");
> -		goto fail_csi_cfg;
> -	}
>  
> -	/* turn off sensor, after probed */
> -	pm_runtime_put(&client->dev);
> -	mutex_unlock(&sensor->input_lock);
> -
> -	return 0;
> -
> -fail_csi_cfg:
> -	sensor->platform_data->csi_cfg(sd, 0);
>  fail_power_on:
>  	pm_runtime_put(&client->dev);
> -	dev_err(&client->dev, "sensor power-gating failed\n");
> -	mutex_unlock(&sensor->input_lock);
>  	return ret;
>  }
>  
> @@ -774,19 +611,32 @@ static void ov2680_remove(struct i2c_client *client)
>  
>  	dev_dbg(&client->dev, "ov2680_remove...\n");
>  
> -	sensor->platform_data->csi_cfg(sd, 0);
> -
> +	atomisp_unregister_subdev(sd);
>  	v4l2_device_unregister_subdev(sd);
>  	media_entity_cleanup(&sensor->sd.entity);
>  	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>  	pm_runtime_disable(&client->dev);
>  }
>  
> +/*
> + * Unlike other sensors which have both a rest and powerdown input pins,

reset ?

> + * the OV2680 only has a powerdown input. But some ACPI tables still list
> + * 2 GPIOs for the OV2680 and it is unclear which to use. So try to get
> + * up to 2 GPIOs (1 mandatory, 1 optional) and control them in sync.
> + */
> +static const struct acpi_gpio_params ov2680_first_gpio = { 0, 0, true };
> +static const struct acpi_gpio_params ov2680_second_gpio = { 1, 0, true };
> +
> +static const struct acpi_gpio_mapping ov2680_gpio_mapping[] = {
> +	{ "powerdown-gpios", &ov2680_first_gpio, 1 },
> +	{ "powerdown-alt-gpios", &ov2680_second_gpio, 1 },

> +	{ },

No comma for the terminator entry.

> +};
> +
>  static int ov2680_probe(struct i2c_client *client)
>  {
>  	struct ov2680_device *sensor;
>  	int ret;
> -	void *pdata;
>  
>  	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
>  	if (!sensor)
> @@ -797,18 +647,24 @@ static int ov2680_probe(struct i2c_client *client)
>  	sensor->client = client;
>  	v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops);
>  
> -	pdata = gmin_camera_platform_data(&sensor->sd,
> -					  ATOMISP_INPUT_FORMAT_RAW_10,
> -					  atomisp_bayer_order_bggr);
> -	if (!pdata)
> -		return -EINVAL;
> +	ret = devm_acpi_dev_add_driver_gpios(&client->dev, ov2680_gpio_mapping);
> +	if (ret)
> +		return ret;
> +
> +	sensor->powerdown = devm_gpiod_get(&client->dev, "powerdown", GPIOD_OUT_HIGH);
> +	if (IS_ERR(sensor->powerdown))
> +		return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n");
> +
> +	sensor->powerdown_alt = devm_gpiod_get_optional(&client->dev, "powerdown-alt", GPIOD_OUT_HIGH);
> +	if (IS_ERR(sensor->powerdown_alt))
> +		return dev_err_probe(&client->dev, PTR_ERR(sensor->powerdown_alt), "getting powerdown-alt GPIO\n");

You may shorten these by

	struct device *dev = &client->dev;

at the top of the function.

>  	pm_runtime_set_suspended(&client->dev);
>  	pm_runtime_enable(&client->dev);
>  	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
>  	pm_runtime_use_autosuspend(&client->dev);
>  
> -	ret = ov2680_s_config(&sensor->sd, client->irq, pdata);
> +	ret = ov2680_s_config(&sensor->sd);
>  	if (ret)
>  		return ret;
>  
> @@ -830,7 +686,8 @@ static int ov2680_probe(struct i2c_client *client)
>  
>  	ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT);
>  
> -	ret = atomisp_register_i2c_module(&sensor->sd, pdata, RAW_CAMERA);
> +	ret = atomisp_register_sensor_no_gmin(&sensor->sd, 1, ATOMISP_INPUT_FORMAT_RAW_10,
> +					      atomisp_bayer_order_bggr);
>  	if (ret) {
>  		ov2680_remove(client);
>  		return ret;
> @@ -842,15 +699,29 @@ static int ov2680_probe(struct i2c_client *client)
>  static int ov2680_suspend(struct device *dev)
>  {
>  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  
> -	return power_down(sd);
> +	gpiod_set_value_cansleep(sensor->powerdown, 1);
> +	gpiod_set_value_cansleep(sensor->powerdown_alt, 1);
> +	return 0;
>  }
>  
>  static int ov2680_resume(struct device *dev)
>  {
>  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct ov2680_device *sensor = to_ov2680_sensor(sd);
>  
> -	return power_up(sd);
> +	/* according to DS, at least 5ms is needed after DOVDD (enabled by ACPI) */

datasheet (DS can be acronym of some [unknown?] person).

> +	usleep_range(5000, 6000);
> +
> +	gpiod_set_value_cansleep(sensor->powerdown, 0);
> +	gpiod_set_value_cansleep(sensor->powerdown_alt, 0);
> +
> +	/* according to DS, 20ms is needed between PWDN and i2c access */
> +	msleep(20);
> +
> +	ov2680_init_registers(sd);
> +	return 0;
>  }
>  
>  static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL);
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 58593da50f6f..a2ed5a1edf35 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -119,7 +119,8 @@ struct ov2680_device {
>  	struct media_pad pad;
>  	struct mutex input_lock;
>  	struct i2c_client *client;
> -	struct camera_sensor_platform_data *platform_data;
> +	struct gpio_desc *powerdown;
> +	struct gpio_desc *powerdown_alt;
>  	bool is_streaming;
>  
>  	struct ov2680_mode {
> -- 
> 2.39.0
> 

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes
  2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
                   ` (56 preceding siblings ...)
  2023-01-23 12:52 ` [PATCH 57/57] media: atomisp: pci: sh_css: Inline single invocation of macro STATS_ENABLED() Hans de Goede
@ 2023-01-24 11:01 ` Andy Shevchenko
  2023-01-24 11:05   ` Hans de Goede
  57 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 11:01 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Mon, Jan 23, 2023 at 01:51:08PM +0100, Hans de Goede wrote:
> Hi All,
> 
> Here is another set of patches resulting from my continued work
> on cleaning up / improving the atomisp driver.
> 
> The main changes here are power-management related, divided
> into 2 sets:
> 
> 1. Move the pm of the core atomisp device to its own custom PM
>    domain. We turn the ISP on/off through the P-Unit and when
>    off the PCI subsystem resume method complains about the PCI
>    config space not being reachable. Changing to a custom PM
>    domain fixes the logs getting filled with PCI subsys errors
>    on every open of a /dev/video# node
> 
> 2. Except for devices shipped with Android as factory image,
>    all the DSDTs I have seen have proper ACPI pm code for
>    the sensors. So we really should be using ACPI pm for this.
> 
>    This series contains a lot of ov2680 patches, including
>    reworking the controls (so that control changes can be
>    delayed to stream on time instead of directly trying to do
>    i2c writes to the turned off sensor). Basically modernizing
>    the ov2680 driver a lot (there are still some atomisp-isms left).
> 
>    And then finally after all the ov2680 cleanups it moves
>    the ov2680 code over to using runtime-pm + ACPI pm,
>    dropping all the direct PMIC + clk poking done by the
>    atomisp_gmin_platform code.
> 
> Besides that this also contains quite a few other fixes / cleanups
> for things which I encountered during the way and it contains the
> start of making the ov2722 driver work. With the changes present
> in that driver I get a working (but very dark) stream. I expect
> that once I add a proper exposure control this will start working

The non-commented patches were reviewed, but I'm not so familiar with the
details of the functionality of the PM parts there. So I left them for others
to review.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes
  2023-01-24 11:01 ` [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Andy Shevchenko
@ 2023-01-24 11:05   ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi Andy,

On 1/24/23 12:01, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:08PM +0100, Hans de Goede wrote:
>> Hi All,
>>
>> Here is another set of patches resulting from my continued work
>> on cleaning up / improving the atomisp driver.
>>
>> The main changes here are power-management related, divided
>> into 2 sets:
>>
>> 1. Move the pm of the core atomisp device to its own custom PM
>>    domain. We turn the ISP on/off through the P-Unit and when
>>    off the PCI subsystem resume method complains about the PCI
>>    config space not being reachable. Changing to a custom PM
>>    domain fixes the logs getting filled with PCI subsys errors
>>    on every open of a /dev/video# node
>>
>> 2. Except for devices shipped with Android as factory image,
>>    all the DSDTs I have seen have proper ACPI pm code for
>>    the sensors. So we really should be using ACPI pm for this.
>>
>>    This series contains a lot of ov2680 patches, including
>>    reworking the controls (so that control changes can be
>>    delayed to stream on time instead of directly trying to do
>>    i2c writes to the turned off sensor). Basically modernizing
>>    the ov2680 driver a lot (there are still some atomisp-isms left).
>>
>>    And then finally after all the ov2680 cleanups it moves
>>    the ov2680 code over to using runtime-pm + ACPI pm,
>>    dropping all the direct PMIC + clk poking done by the
>>    atomisp_gmin_platform code.
>>
>> Besides that this also contains quite a few other fixes / cleanups
>> for things which I encountered during the way and it contains the
>> start of making the ov2722 driver work. With the changes present
>> in that driver I get a working (but very dark) stream. I expect
>> that once I add a proper exposure control this will start working
> 
> The non-commented patches were reviewed, but I'm not so familiar with the
> details of the functionality of the PM parts there. So I left them for others
> to review.

Thank you very much for reviewing this monster series!

I agree with all your code remarks / requested changes.

I'll make this changes in my personal tree and then prepare
a pull-req for Mauro with the updated patches.

I'll go over the couple of cases where you had questions
about things now.

I'll process the requested code changes (and add your Reviewed-by-s)
when I can make some time to work on this later this week.

Regards,

Hans


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

* Re: [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper()
  2023-01-23 14:38   ` Andy Shevchenko
@ 2023-01-24 11:09     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:09 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 15:38, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:22PM +0100, Hans de Goede wrote:
>> Check buffer index is in range inside atomisp_qbuf_wrapper() before
>> using it do index pipe->frame_request_config_id[].
> 
> ...
> 
>>  	/* FIXME this abuse of buf->reserved2 comes from the original atomisp buffer handling */
> 
> Does the comment belong to this check?

Yes and no, the whole reason we need a wrapper at all is because
of the reserved2 abuse; and likewise the index check is also only
necessary because of the code below using index. If it was not
for that, then we could simply rely on the identical index check in 
vb2_ioctl_qbuf() itself.

Before sending this to Mauro I'll amend this to replace this comment
with a comment above the entire wrapper function explaining that
the entire wrapper should eventually be removed.

Regards,

Hans



> 
>> +	if (buf->index >= vdev->queue->num_buffers)
>> +		return -EINVAL;
>> +
>>  	if (!atomisp_is_vf_pipe(pipe) &&
>>  	    (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
>>  		/* this buffer will have a per-frame parameter */
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 18:09   ` Andy Shevchenko
@ 2023-01-24 11:21     ` Hans de Goede
  2023-01-24 12:47       ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:21 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 19:09, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>
>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>> use register access helpers with the following function prototypes:
>>
>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                     unsigned int len, u32 *val);
>>
>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                      unsigned int len, u32 val);
>>
>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>> a 16 bit register address in big-endian format and which have 1-3 byte
>> wide registers, in big-endian format (for the higher width registers).
>>
>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>> versions of these register access helpers, so that this code duplication
>> can be removed.
> 
> ...
> 
>> +#include <asm/unaligned.h>
> 
> Usually we put linux/* followed by asm/*.

Ack.

> 
>> +#include <linux/dev_printk.h>
>> +#include <linux/i2c.h>
>> +
>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
>> +				  unsigned int len, u32 *val)
>> +{
>> +	struct i2c_msg msgs[2];
> 
>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
> 
> Let's use unaligned.h or byteorder/generic.h?
> 
> 	__be16 addr_buf = cpu_to_be16(reg);

Ack.

> 
>> +	u8 data_buf[4] = { 0, };
> 
> 0, is not needed.
> 
>> +	int ret;
>> +
>> +	if (len > 4)
>> +		return -EINVAL;
>> +
>> +	msgs[0].addr = client->addr;
>> +	msgs[0].flags = 0;
>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
>> +	msgs[0].buf = addr_buf;
> 
> 	msgs[0].buf = &addr_buf;
> 
>> +	msgs[1].addr = client->addr;
>> +	msgs[1].flags = I2C_M_RD;
>> +	msgs[1].len = len;
> 
>> +	msgs[1].buf = &data_buf[4 - len];
> 
> This trick I don't like. Can we have like other driver have it, i.e. switch
> case for the possible length and explicit usage of the endian conversion calls?

This new header (which is intended to eventually be used in many other
ovXXXX drivers too) is modeled after the reg access helpers
in drivers/media/i2c/ov*.c

And those do use be16 for the addr_buf in some cases, so I'm fine
with changing that. But non of them do a switch-case on len,
instead they all use similar tricks as this code (which was
copied from drivers/media/i2c/ov2680.c) does.

So I would prefer to keep this as is, so that the new
ovxxxx_16bit_addr_reg_helpers.h code is more like the code which
it intends to replace.

Regards,

Hans



> 
>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>> +	if (ret != ARRAY_SIZE(msgs)) {
>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
>> +		return -EIO;
>> +	}
>> +
>> +	*val = get_unaligned_be32(data_buf);
>> +
>> +	return 0;
>> +}
>> +
>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
>> +
>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
>> +				   unsigned int len, u32 val)
>> +{
>> +	u8 buf[6];
>> +	int ret;
>> +
>> +	if (len > 4)
>> +		return -EINVAL;
> 
>> +	put_unaligned_be16(reg, buf);
>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> 
> Something similar here?
> 
>> +	ret = i2c_master_send(client, buf, len + 2);
>> +	if (ret != len + 2) {
>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
>> +		return -EIO;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
>> +
>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
>> +{
>> +	u32 readval;
>> +	int ret;
>> +
>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
>> +	if (ret < 0)
>> +		return ret;
> 
>> +	readval &= ~mask;
>> +	val &= mask;
>> +	val |= readval;
> 
> Usual pattern:
> 
> 	val = (readval & ~mask) | (val & mask);
> 
>> +	return ovxxxx_write_reg8(client, reg, val);
>> +}
> 


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

* Re: [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 18:13   ` Andy Shevchenko
@ 2023-01-24 11:22     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:22 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 19:13, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:37PM +0100, Hans de Goede wrote:
>> Use the new ovxxxx_16bit_addr_reg_helpers.h instead of duplicating
>> the ovxxxx sensor I2C register access helpers found in many different
>> sensor drivers.
> 
> ...
> 
>> -	ret = ov2680_write_reg(client, 1,
>> -			       OV2680_GROUP_ACCESS, 0x00);
>> +	ret = ovxxxx_write_reg8(client, OV2680_GROUP_ACCESS, 0x00);
>>  	if (ret) {
>>  		dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n",
>>  			__func__, OV2680_GROUP_ACCESS);
> 
> Wouldn't this be a dup message without any additional value?
> 
> Same to many other places.

Ack, these errors are all removed in further refactoring.

Regards,

Hans



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 18:23   ` Andy Shevchenko
@ 2023-01-24 11:25     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:25 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 19:23, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>
>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>> use register access helpers with the following function prototypes:
>>
>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                     unsigned int len, u32 *val);
>>
>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                      unsigned int len, u32 val);
>>
>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>> a 16 bit register address in big-endian format and which have 1-3 byte
>> wide registers, in big-endian format (for the higher width registers).
>>
>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>> versions of these register access helpers, so that this code duplication
>> can be removed.
> 
> 
> A couple more comments.
> 
> ...
> 
>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> 
> Btw, we probably can use _Generic() for these...
> 
> ...
> 
>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> 
> Can we actually s/mod/update/ as it's more regular when we talk about IO
> accessor APIs?

Ack, I'll replace the mod with update.

Regards,

Hans



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

* Re: [PATCH 33/57] media: atomisp: ov2680: Add test pattern control
  2023-01-23 18:46   ` Andy Shevchenko
@ 2023-01-24 11:27     ` Hans de Goede
  2023-01-24 12:50       ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:27 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 19:46, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:41PM +0100, Hans de Goede wrote:
>> Add a test pattern control. This is a 1:1 copy of the test pattern
>> control in the main drivers/media/i2c/ov2680.c driver.
> 
> Hmm... I'm not sure I understand the trend of the changes.
> We have two drivers of the same sensor, correct?
> So, the idea is to move the AtomISP-specific one to be like
> the generic and then kill it eventually?

The goal is to kill one eventually yes. I'm not sure which
one to kill yet though. I have actually found a whole bunch
of bugs in the main drivers/media/i2c/ov2680.c code and
given its buggy-ness I wonder if anyone is actually using it.

I need to start an email thread about this (and a couple of
other open questions which I have), I have a bunch of notes
which I need to turn into emails for this.

> If so, why do we add something here?

Because I suspect that the atomisp version might eventually
be the one we want to keep (and move to drivers/media/i2c).

Regards,

Hans


> Code-wise it's okay change, but see above.
> Reviewed-by: Andy Shevchenko <andy@kernel.org>
> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  .../media/atomisp/i2c/atomisp-ov2680.c        | 33 +++++++++++++++++++
>>  drivers/staging/media/atomisp/i2c/ov2680.h    |  3 ++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> index 14002a1c22d2..6ca2a5bb0700 100644
>> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> @@ -127,6 +127,24 @@ static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
>>  	return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
>>  }
>>  
>> +static int ov2680_test_pattern_set(struct ov2680_device *sensor, int value)
>> +{
>> +	int ret;
>> +
>> +	if (!value)
>> +		return ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), 0);
>> +
>> +	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, 0x03, value - 1);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	ret = ovxxxx_mod_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7));
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>>  static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>>  {
>>  	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
>> @@ -151,6 +169,9 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
>>  	case V4L2_CID_GAIN:
>>  		ret = ov2680_gain_set(sensor, ctrl->val);
>>  		break;
>> +	case V4L2_CID_TEST_PATTERN:
>> +		ret = ov2680_test_pattern_set(sensor, ctrl->val);
>> +		break;
>>  	default:
>>  		ret = -EINVAL;
>>  	}
>> @@ -644,6 +665,13 @@ static const struct v4l2_subdev_ops ov2680_ops = {
>>  
>>  static int ov2680_init_controls(struct ov2680_device *sensor)
>>  {
>> +	static const char * const test_pattern_menu[] = {
>> +		"Disabled",
>> +		"Color Bars",
>> +		"Random Data",
>> +		"Square",
>> +		"Black Image",
>> +	};
>>  	const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
>>  	struct ov2680_ctrls *ctrls = &sensor->ctrls;
>>  	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
>> @@ -658,6 +686,11 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
>>  	ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
>>  					    0, exp_max, 1, exp_max);
>>  	ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
>> +	ctrls->test_pattern =
>> +		v4l2_ctrl_new_std_menu_items(hdl,
>> +					     &ov2680_ctrl_ops, V4L2_CID_TEST_PATTERN,
>> +					     ARRAY_SIZE(test_pattern_menu) - 1,
>> +					     0, 0, test_pattern_menu);
>>  
>>  	ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
>>  	ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
>> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
>> index e3ad20a7ffd5..45526477b612 100644
>> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
>> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
>> @@ -120,6 +120,8 @@
>>  #define OV2680_MWB_BLUE_GAIN_H			0x5008/*0x3404*/
>>  #define OV2680_MWB_GAIN_MAX				0x0fff
>>  
>> +#define OV2680_REG_ISP_CTRL00			0x5080
>> +
>>  #define OV2680_START_STREAMING			0x01
>>  #define OV2680_STOP_STREAMING			0x00
>>  
>> @@ -171,6 +173,7 @@ struct ov2680_device {
>>  		struct v4l2_ctrl *vflip;
>>  		struct v4l2_ctrl *exposure;
>>  		struct v4l2_ctrl *gain;
>> +		struct v4l2_ctrl *test_pattern;
>>  	} ctrls;
>>  };
>>  
>> -- 
>> 2.39.0
>>
> 


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

* Re: [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list
  2023-01-24 10:46   ` Andy Shevchenko
@ 2023-01-24 11:29     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:29 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/24/23 11:46, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:49PM +0100, Hans de Goede wrote:
>> 3 fixes for the framesize list:
>>
>> 1. Drop modes < 640x480, these are made by significant cropping,
>>    leading to such a small remainig field-of-view that they are
>>    not really usable
> 
> Wondering if we have an algo to actually scale instead of crop.

The sensor can "bin" the pixels, that is use every other pixel,
that already is used. Plain binning gives us 1600x1200 -> 800x600,
640x480 is binning + some cropping.

Regards,

Hans


> 
>> 2. 1616x1082 is presumably intended to be 1600x1080 + 16 pixels
>>    padding in both dimensions, but the height is wrong.
>>    Change this to 1616x1096.
>>
>> 3. The 800x600 mode is missing the 16 pixels padding and
>>    720x592 is missing 16 pixels padding in its width and
>>    the 720x576 base mode is a mode with non square pixels,
>>    while the sensor has square pixels.
>>    Replace both with 768x576 + 16 pixels padding -> 784x592
> 
> Reviewed-by: Andy Shevchenko <andy@kernel.org>
> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 8 ++------
>>  1 file changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> index 432539dd274c..81fd36b09090 100644
>> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> @@ -700,17 +700,13 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd,
>>  {
>>  	static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = {
>>  		{ 1616, 1216 },
>> -		{ 1616, 1082 },
>> +		{ 1616, 1096 },
>>  		{ 1616,  916 },
>>  		{ 1456, 1096 },
>>  		{ 1296,  976 },
>>  		{ 1296,  736 },
>> -		{  800,  600 },
>> -		{  720,  592 },
>> +		{  784,  592 },
>>  		{  656,  496 },
>> -		{  336,  256 },
>> -		{  352,  288 },
>> -		{  176,  144 },
>>  	};
>>  	int index = fse->index;
>>  
>> -- 
>> 2.39.0
>>
> 


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

* Re: [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started
  2023-01-24 10:51   ` Andy Shevchenko
@ 2023-01-24 11:31     ` Hans de Goede
  2023-01-24 12:52       ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:31 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/24/23 11:51, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:51:54PM +0100, Hans de Goede wrote:
>> Move the setting of the mode to stream on, this also allows
>> delaying power-on till streaming is started.
>>
>> And drop the deprecated s_power callback since this now no long
>> is necessary.
> 
> Reviewed-by: Andy Shevchenko <andy@kernel.org>
> 
> See below.
> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  .../media/atomisp/i2c/atomisp-ov2680.c        | 101 +++++++-----------
>>  1 file changed, 41 insertions(+), 60 deletions(-)
>>
>> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> index 1dc821ca4e68..2a8c4508cc66 100644
>> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
>> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c

<snip>

>> +	if (sensor->is_streaming == enable) {
>> +		dev_warn(&client->dev, "stream already %sed\n", enable ? "start" : "stopp");
> 
> stopP ?!

Yes the format string is "%sed" so "stopp" gives us "stopped".

Regards,

Hans


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

* Re: [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback
  2023-01-23 18:42   ` Andy Shevchenko
@ 2023-01-24 11:32     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 11:32 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/23/23 19:42, Andy Shevchenko wrote:
> On Mon, Jan 23, 2023 at 01:52:02PM +0100, Hans de Goede wrote:
>> Depending on which order userspace makes various v4l2 calls, the sensor
>> might still be powered down when set_fmt is called.
>>
>> What should really happen here is delay the writing of the mode-related
>> registers till streaming is started, but for now use the same quick fix
>> as the atomisp_ov2680 / atomisp_gc0310 code and call power_up() from
>> set_fmt() in combination with keeping track of the power-state to avoid
>> doing the power-up sequence twice.
> 
> OK.
> Reviewed-by: Andy Shevchenko <andy@kernel.org>
> 
> Is there a plan to drop this hack from all of the (AtomISP) sensor drivers?

Yes this is the next one on my list to convert to runtime-pm +
ACPI powermanagement. Which needs to be done on a sensor by sensor
basis :|

Regards,

Hans




> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 12 ++++++++++++
>>  drivers/staging/media/atomisp/i2c/ov2722.h         |  2 +-
>>  2 files changed, 13 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
>> index e09c80d1f9ec..5d2e6e2e72f0 100644
>> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
>> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
>> @@ -528,6 +528,9 @@ static int power_up(struct v4l2_subdev *sd)
>>  		return -ENODEV;
>>  	}
>>  
>> +	if (dev->power_on == 1)
>> +		return 0; /* Already on */
>> +
>>  	/* power control */
>>  	ret = power_ctrl(sd, 1);
>>  	if (ret)
>> @@ -552,6 +555,7 @@ static int power_up(struct v4l2_subdev *sd)
>>  	/* according to DS, 20ms is needed between PWDN and i2c access */
>>  	msleep(20);
>>  
>> +	dev->power_on = 1;
>>  	return 0;
>>  
>>  fail_clk:
>> @@ -575,6 +579,9 @@ static int power_down(struct v4l2_subdev *sd)
>>  		return -ENODEV;
>>  	}
>>  
>> +	if (dev->power_on == 0)
>> +		return 0; /* Already off */
>> +
>>  	ret = dev->platform_data->flisclk_ctrl(sd, 0);
>>  	if (ret)
>>  		dev_err(&client->dev, "flisclk failed\n");
>> @@ -592,6 +599,7 @@ static int power_down(struct v4l2_subdev *sd)
>>  	if (ret)
>>  		dev_err(&client->dev, "vprog failed.\n");
>>  
>> +	dev->power_on = 0;
>>  	return ret;
>>  }
>>  
>> @@ -669,6 +677,9 @@ static int ov2722_set_fmt(struct v4l2_subdev *sd,
>>  
>>  	mutex_lock(&dev->input_lock);
>>  
>> +	/* s_power has not been called yet for std v4l2 clients (camorama) */
>> +	power_up(sd);
>> +
>>  	dev->pixels_per_line = dev->res->pixels_per_line;
>>  	dev->lines_per_frame = dev->res->lines_per_frame;
>>  
>> @@ -959,6 +970,7 @@ static int ov2722_probe(struct i2c_client *client)
>>  		return -ENOMEM;
>>  
>>  	mutex_init(&dev->input_lock);
>> +	dev->power_on = -1;
>>  
>>  	dev->res = &ov2722_res_preview[0];
>>  	v4l2_i2c_subdev_init(&dev->sd, client, &ov2722_ops);
>> diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h
>> index 020743a944c4..640d3ffcaa5c 100644
>> --- a/drivers/staging/media/atomisp/i2c/ov2722.h
>> +++ b/drivers/staging/media/atomisp/i2c/ov2722.h
>> @@ -198,7 +198,7 @@ struct ov2722_device {
>>  	struct ov2722_resolution *res;
>>  
>>  	struct camera_sensor_platform_data *platform_data;
>> -	int run_mode;
>> +	int power_on;
>>  	u16 pixels_per_line;
>>  	u16 lines_per_frame;
>>  	u8 type;
>> -- 
>> 2.39.0
>>
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-24 11:21     ` Hans de Goede
@ 2023-01-24 12:47       ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 12:47 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Tue, Jan 24, 2023 at 12:21:50PM +0100, Hans de Goede wrote:
> On 1/23/23 19:09, Andy Shevchenko wrote:
> > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> >>
> >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> >> use register access helpers with the following function prototypes:
> >>
> >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>                     unsigned int len, u32 *val);
> >>
> >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>                      unsigned int len, u32 val);
> >>
> >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> >> a 16 bit register address in big-endian format and which have 1-3 byte
> >> wide registers, in big-endian format (for the higher width registers).
> >>
> >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> >> versions of these register access helpers, so that this code duplication
> >> can be removed.

...

> >> +	msgs[1].buf = &data_buf[4 - len];
> > 
> > This trick I don't like. Can we have like other driver have it, i.e. switch
> > case for the possible length and explicit usage of the endian conversion
> > calls?
> 
> This new header (which is intended to eventually be used in many other
> ovXXXX drivers too) is modeled after the reg access helpers
> in drivers/media/i2c/ov*.c
> 
> And those do use be16 for the addr_buf in some cases, so I'm fine
> with changing that. But non of them do a switch-case on len,
> instead they all use similar tricks as this code (which was
> copied from drivers/media/i2c/ov2680.c) does.
> 
> So I would prefer to keep this as is, so that the new
> ovxxxx_16bit_addr_reg_helpers.h code is more like the code which
> it intends to replace.

Yes, this is rather for the followup improvements when we have all drivers use
these helpers.

But under "other drivers" I meant more or less IIO ones where similar
(to what I suggest) approach is being used.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 33/57] media: atomisp: ov2680: Add test pattern control
  2023-01-24 11:27     ` Hans de Goede
@ 2023-01-24 12:50       ` Andy Shevchenko
  0 siblings, 0 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 12:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Tue, Jan 24, 2023 at 12:27:55PM +0100, Hans de Goede wrote:
> On 1/23/23 19:46, Andy Shevchenko wrote:
> > On Mon, Jan 23, 2023 at 01:51:41PM +0100, Hans de Goede wrote:
> >> Add a test pattern control. This is a 1:1 copy of the test pattern
> >> control in the main drivers/media/i2c/ov2680.c driver.
> > 
> > Hmm... I'm not sure I understand the trend of the changes.
> > We have two drivers of the same sensor, correct?
> > So, the idea is to move the AtomISP-specific one to be like
> > the generic and then kill it eventually?
> 
> The goal is to kill one eventually yes. I'm not sure which
> one to kill yet though. I have actually found a whole bunch
> of bugs in the main drivers/media/i2c/ov2680.c code and
> given its buggy-ness I wonder if anyone is actually using it.
> 
> I need to start an email thread about this (and a couple of
> other open questions which I have), I have a bunch of notes
> which I need to turn into emails for this.
> 
> > If so, why do we add something here?
> 
> Because I suspect that the atomisp version might eventually
> be the one we want to keep (and move to drivers/media/i2c).

Fine, just add a few words into cover letter.

Btw, do you use `b4` tool to handle patch(es) series?
It has a nice feature to handle a series as a PR. In
that case the cover letter becomes a merge-commit message
which is cool feature in my opinion.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started
  2023-01-24 11:31     ` Hans de Goede
@ 2023-01-24 12:52       ` Andy Shevchenko
  2023-01-24 13:35         ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-01-24 12:52 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Tue, Jan 24, 2023 at 12:31:14PM +0100, Hans de Goede wrote:
> On 1/24/23 11:51, Andy Shevchenko wrote:
> > On Mon, Jan 23, 2023 at 01:51:54PM +0100, Hans de Goede wrote:

...

> >> +	if (sensor->is_streaming == enable) {
> >> +		dev_warn(&client->dev, "stream already %sed\n", enable ? "start" : "stopp");
> > 
> > stopP ?!
> 
> Yes the format string is "%sed" so "stopp" gives us "stopped".

Can we, please, use full words, so it will be easier to find a candidate for
including into string_choices.h or so?

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started
  2023-01-24 12:52       ` Andy Shevchenko
@ 2023-01-24 13:35         ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-01-24 13:35 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 1/24/23 13:52, Andy Shevchenko wrote:
> On Tue, Jan 24, 2023 at 12:31:14PM +0100, Hans de Goede wrote:
>> On 1/24/23 11:51, Andy Shevchenko wrote:
>>> On Mon, Jan 23, 2023 at 01:51:54PM +0100, Hans de Goede wrote:
> 
> ...
> 
>>>> +	if (sensor->is_streaming == enable) {
>>>> +		dev_warn(&client->dev, "stream already %sed\n", enable ? "start" : "stopp");
>>>
>>> stopP ?!
>>
>> Yes the format string is "%sed" so "stopp" gives us "stopped".
> 
> Can we, please, use full words, so it will be easier to find a candidate for
> including into string_choices.h or so?

Sure I'll update this before adding it to the PR.

Regards,

Hans


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

* Re: [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls
  2023-01-23 12:51 ` [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls Hans de Goede
  2023-01-23 18:33   ` Andy Shevchenko
@ 2023-01-29  0:36   ` kernel test robot
  1 sibling, 0 replies; 168+ messages in thread
From: kernel test robot @ 2023-01-29  0:36 UTC (permalink / raw)
  To: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus
  Cc: llvm, oe-kbuild-all, linux-media, Hans de Goede, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-staging

Hi Hans,

I love your patch! Perhaps something to improve:

[auto build test WARNING on media-tree/master]
[also build test WARNING on sailus-media-tree/streams linus/master v6.2-rc5 next-20230127]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hans-de-Goede/media-atomisp-fix-videobuf2-Kconfig-depenendency/20230123-205911
base:   git://linuxtv.org/media_tree.git master
patch link:    https://lore.kernel.org/r/20230123125205.622152-31-hdegoede%40redhat.com
patch subject: [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls
config: x86_64-allmodconfig (https://download.01.org/0day-ci/archive/20230129/202301290857.L5301E4z-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/94a8aa6a6e07cfbfebce3e18938f0ec11e752b04
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Hans-de-Goede/media-atomisp-fix-videobuf2-Kconfig-depenendency/20230123-205911
        git checkout 94a8aa6a6e07cfbfebce3e18938f0ec11e752b04
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash arch/x86/kvm/ drivers/staging/media/atomisp/i2c/ kernel/sched/ net/mptcp/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/staging/media/atomisp/i2c/atomisp-ov2680.c:555:16: warning: variable 'fmt' is uninitialized when used here [-Wuninitialized]
                   format->pad, fmt);
                                ^~~
   include/linux/dev_printk.h:155:39: note: expanded from macro 'dev_dbg'
           dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
                                                ^~~~~~~~~~~
   include/linux/dynamic_debug.h:273:19: note: expanded from macro 'dynamic_dev_dbg'
                              dev, fmt, ##__VA_ARGS__)
                                          ^~~~~~~~~~~
   include/linux/dynamic_debug.h:249:59: note: expanded from macro '_dynamic_func_call'
           _dynamic_func_call_cls(_DPRINTK_CLASS_DFLT, fmt, func, ##__VA_ARGS__)
                                                                    ^~~~~~~~~~~
   include/linux/dynamic_debug.h:247:65: note: expanded from macro '_dynamic_func_call_cls'
           __dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
                                                                          ^~~~~~~~~~~
   include/linux/dynamic_debug.h:223:15: note: expanded from macro '__dynamic_func_call_cls'
                   func(&id, ##__VA_ARGS__);                       \
                               ^~~~~~~~~~~
   drivers/staging/media/atomisp/i2c/atomisp-ov2680.c:548:32: note: initialize the variable 'fmt' to silence this warning
           struct v4l2_mbus_framefmt *fmt;
                                         ^
                                          = NULL
   1 warning generated.


vim +/fmt +555 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c

94a8aa6a6e07cf Hans de Goede         2023-01-23  541  
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  542  static int ov2680_set_fmt(struct v4l2_subdev *sd,
0d346d2a6f54f0 Tomi Valkeinen        2021-06-10  543  			  struct v4l2_subdev_state *sd_state,
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  544  			  struct v4l2_subdev_format *format)
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  545  {
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  546  	struct ov2680_device *dev = to_ov2680_sensor(sd);
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  547  	struct i2c_client *client = v4l2_get_subdevdata(sd);
94a8aa6a6e07cf Hans de Goede         2023-01-23  548  	struct v4l2_mbus_framefmt *fmt;
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  549  	struct ov2680_resolution *res;
29400b5063db69 Hans de Goede         2021-11-07  550  	int vts, ret = 0;
bdfe0beb95eebc Mauro Carvalho Chehab 2020-04-19  551  
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  552  	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  553  		__func__,
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  554  		(format->which == V4L2_SUBDEV_FORMAT_TRY) ? "try" : "set",
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19 @555  		format->pad, fmt);
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  556  
94a8aa6a6e07cf Hans de Goede         2023-01-23  557  	res = v4l2_find_nearest_size(ov2680_res_preview, ARRAY_SIZE(ov2680_res_preview),
94a8aa6a6e07cf Hans de Goede         2023-01-23  558  				     width, height,
94a8aa6a6e07cf Hans de Goede         2023-01-23  559  				     format->format.width, format->format.height);
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  560  	if (!res)
b821cea597f84e Hans de Goede         2021-11-07  561  		res = &ov2680_res_preview[N_RES_PREVIEW - 1];
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  562  
94a8aa6a6e07cf Hans de Goede         2023-01-23  563  	fmt = __ov2680_get_pad_format(dev, sd_state, format->pad, format->which);
94a8aa6a6e07cf Hans de Goede         2023-01-23  564  	ov2680_fill_format(dev, fmt, res->width, res->height);
94a8aa6a6e07cf Hans de Goede         2023-01-23  565  
94a8aa6a6e07cf Hans de Goede         2023-01-23  566  	format->format = *fmt;
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  567  
94a8aa6a6e07cf Hans de Goede         2023-01-23  568  	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  569  		return 0;
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  570  
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  571  	dev_dbg(&client->dev, "%s: %dx%d\n",
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  572  		__func__, fmt->width, fmt->height);
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  573  
44a11920ac39fe Hans de Goede         2022-08-13  574  	mutex_lock(&dev->input_lock);
44a11920ac39fe Hans de Goede         2022-08-13  575  
12350633a8dbdc Hans de Goede         2021-11-07  576  	/* s_power has not been called yet for std v4l2 clients (camorama) */
eda1310b4087d6 Mauro Carvalho Chehab 2020-05-19  577  	power_up(sd);
b7573661282c92 Mauro Carvalho Chehab 2021-11-03  578  	ret = ov2680_write_reg_array(client, dev->res->regs);
cbd5b438f8c2b5 Hans de Goede         2022-08-13  579  	if (ret) {
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  580  		dev_err(&client->dev,
5589ea0745ef4f Mauro Carvalho Chehab 2020-05-19  581  			"ov2680 write resolution register err: %d\n", ret);
cbd5b438f8c2b5 Hans de Goede         2022-08-13  582  		goto err;
cbd5b438f8c2b5 Hans de Goede         2022-08-13  583  	}
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  584  
22f2cac62dea73 Mauro Carvalho Chehab 2021-11-10  585  	vts = dev->res->lines_per_frame;
22f2cac62dea73 Mauro Carvalho Chehab 2021-11-10  586  
29400b5063db69 Hans de Goede         2021-11-07  587  	/* If necessary increase the VTS to match exposure + MARGIN */
29400b5063db69 Hans de Goede         2021-11-07  588  	if (dev->exposure > vts - OV2680_INTEGRATION_TIME_MARGIN)
29400b5063db69 Hans de Goede         2021-11-07  589  		vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN;
29400b5063db69 Hans de Goede         2021-11-07  590  
bf46430efae7c2 Hans de Goede         2023-01-23  591  	ret = ovxxxx_write_reg16(client, OV2680_TIMING_VTS_H, vts);
cbd5b438f8c2b5 Hans de Goede         2022-08-13  592  	if (ret) {
29400b5063db69 Hans de Goede         2021-11-07  593  		dev_err(&client->dev, "ov2680 write vts err: %d\n", ret);
cbd5b438f8c2b5 Hans de Goede         2022-08-13  594  		goto err;
cbd5b438f8c2b5 Hans de Goede         2022-08-13  595  	}
29400b5063db69 Hans de Goede         2021-11-07  596  
f50559f0c9b43b Deepak R Varma        2021-04-28  597  	/*
f50559f0c9b43b Deepak R Varma        2021-04-28  598  	 * recall flip functions to avoid flip registers
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  599  	 * were overridden by default setting
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  600  	 */
94a8aa6a6e07cf Hans de Goede         2023-01-23  601  	ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
94a8aa6a6e07cf Hans de Goede         2023-01-23  602  	if (ret < 0)
94a8aa6a6e07cf Hans de Goede         2023-01-23  603  		goto err;
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  604  
adea153b4f6537 Hans de Goede         2022-08-13  605  	dev->res = res;
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  606  err:
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  607  	mutex_unlock(&dev->input_lock);
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  608  	return ret;
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  609  }
ad85094b293e40 Mauro Carvalho Chehab 2020-04-19  610  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
                     ` (2 preceding siblings ...)
  2023-01-23 18:23   ` Andy Shevchenko
@ 2023-02-08  9:52   ` Laurent Pinchart
  2023-02-08 11:27     ` Andy Shevchenko
  2023-02-09 15:03     ` Hans de Goede
  2023-02-08 11:31   ` Sakari Ailus
  4 siblings, 2 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-08  9:52 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

Thank you for the patch.

On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> 
> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> use register access helpers with the following function prototypes:
> 
> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>                     unsigned int len, u32 *val);
> 
> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>                      unsigned int len, u32 val);
> 
> To read/write registers on Omnivision OVxxxx image sensors wich expect
> a 16 bit register address in big-endian format and which have 1-3 byte
> wide registers, in big-endian format (for the higher width registers).
> 
> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> versions of these register access helpers, so that this code duplication
> can be removed.

Any reason to hand-roll those instead of using regmap ? Also, may I
suggest to have a look at drivers/media/i2c/imx290.c for an example of
how registers of different sizes can be handled in a less error-prone
way, using single read/write functions that adapt to the size
automatically ?

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
>  1 file changed, 93 insertions(+)
>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
> 
> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> new file mode 100644
> index 000000000000..e2ffee3d797a
> --- /dev/null
> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> @@ -0,0 +1,93 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
> + * a 16 bit register address in big-endian format and which have 1-3 byte
> + * wide registers, in big-endian format (for the higher width registers).
> + *
> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
> + * Copyright (C) 2018 Linaro Ltd
> + */
> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> +
> +#include <asm/unaligned.h>
> +#include <linux/dev_printk.h>
> +#include <linux/i2c.h>
> +
> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
> +				  unsigned int len, u32 *val)
> +{
> +	struct i2c_msg msgs[2];
> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
> +	u8 data_buf[4] = { 0, };
> +	int ret;
> +
> +	if (len > 4)
> +		return -EINVAL;
> +
> +	msgs[0].addr = client->addr;
> +	msgs[0].flags = 0;
> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> +	msgs[0].buf = addr_buf;
> +
> +	msgs[1].addr = client->addr;
> +	msgs[1].flags = I2C_M_RD;
> +	msgs[1].len = len;
> +	msgs[1].buf = &data_buf[4 - len];
> +
> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> +	if (ret != ARRAY_SIZE(msgs)) {
> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
> +		return -EIO;
> +	}
> +
> +	*val = get_unaligned_be32(data_buf);
> +
> +	return 0;
> +}
> +
> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
> +
> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
> +				   unsigned int len, u32 val)
> +{
> +	u8 buf[6];
> +	int ret;
> +
> +	if (len > 4)
> +		return -EINVAL;
> +
> +	put_unaligned_be16(reg, buf);
> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> +	ret = i2c_master_send(client, buf, len + 2);
> +	if (ret != len + 2) {
> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> +
> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> +{
> +	u32 readval;
> +	int ret;
> +
> +	ret = ovxxxx_read_reg8(client, reg, &readval);
> +	if (ret < 0)
> +		return ret;
> +
> +	readval &= ~mask;
> +	val &= mask;
> +	val |= readval;
> +
> +	return ovxxxx_write_reg8(client, reg, val);
> +}
> +
> +#endif

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08  9:52   ` Laurent Pinchart
@ 2023-02-08 11:27     ` Andy Shevchenko
  2023-02-08 15:41       ` Laurent Pinchart
  2023-02-09 15:03     ` Hans de Goede
  1 sibling, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-08 11:27 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:

...

> > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > versions of these register access helpers, so that this code duplication
> > can be removed.
>
> Any reason to hand-roll those instead of using regmap ? Also, may I
> suggest to have a look at drivers/media/i2c/imx290.c

While this is a bit error prone example, a patch is on its way, ...

>  for an example of
> how registers of different sizes can be handled in a less error-prone
> way, using single read/write functions that adapt to the size
> automatically ?

...with regmap fields I believe you can avoid even that and use proper
regmap accessors directly.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
                     ` (3 preceding siblings ...)
  2023-02-08  9:52   ` Laurent Pinchart
@ 2023-02-08 11:31   ` Sakari Ailus
  2023-02-08 14:33     ` Mauro Carvalho Chehab
  4 siblings, 1 reply; 168+ messages in thread
From: Sakari Ailus @ 2023-02-08 11:31 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Tsuchiya Yuto, Andy Shevchenko,
	Yury Luneff, Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi Hans,

On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> 
> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> use register access helpers with the following function prototypes:
> 
> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>                     unsigned int len, u32 *val);
> 
> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>                      unsigned int len, u32 val);
> 
> To read/write registers on Omnivision OVxxxx image sensors wich expect
> a 16 bit register address in big-endian format and which have 1-3 byte
> wide registers, in big-endian format (for the higher width registers).
> 
> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> versions of these register access helpers, so that this code duplication
> can be removed.

Ideally we'd have helpers for CCI, of which this is a subset. And on top of
regmap. I don't object adding these either though.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 11:31   ` Sakari Ailus
@ 2023-02-08 14:33     ` Mauro Carvalho Chehab
  2023-02-08 15:39       ` Laurent Pinchart
  0 siblings, 1 reply; 168+ messages in thread
From: Mauro Carvalho Chehab @ 2023-02-08 14:33 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans de Goede, Tsuchiya Yuto, Andy Shevchenko, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Em Wed, 8 Feb 2023 13:31:17 +0200
Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:

> Hi Hans,
> 
> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > 
> > as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > use register access helpers with the following function prototypes:
> > 
> > int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> >                     unsigned int len, u32 *val);
> > 
> > int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> >                      unsigned int len, u32 val);
> > 
> > To read/write registers on Omnivision OVxxxx image sensors wich expect
> > a 16 bit register address in big-endian format and which have 1-3 byte
> > wide registers, in big-endian format (for the higher width registers).
> > 
> > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > versions of these register access helpers, so that this code duplication
> > can be removed.  
> 
> Ideally we'd have helpers for CCI, of which this is a subset. And on top of
> regmap. I don't object adding these either though.

Well, ideally, when the atomisp-specific sensor ioctls go away, we can
merge the atomisp-specific sensor drivers for not-yet-uptreamed sensors
or modify the existing sensor drivers to accept the atomisp resolutions [1].

So, for now, I wouldn't convert those to use regmap. This can be done
later with the remaining drivers.

[1] atomisp usually requires 16 extra lines/columns for it to work, so
the current sensor drivers there allow setting resolutions like
1616x1216 at the sensor, while offering 1600x1200 resolution to
userspace.

Thanks,
Mauro

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 14:33     ` Mauro Carvalho Chehab
@ 2023-02-08 15:39       ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-08 15:39 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans de Goede, Tsuchiya Yuto, Andy Shevchenko,
	Yury Luneff, Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

On Wed, Feb 08, 2023 at 03:33:29PM +0100, Mauro Carvalho Chehab wrote:
> Em Wed, 8 Feb 2023 13:31:17 +0200
> Sakari Ailus <sakari.ailus@linux.intel.com> escreveu:
> 
> > Hi Hans,
> > 
> > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > > The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > > ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > > ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > > 
> > > as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > > use register access helpers with the following function prototypes:
> > > 
> > > int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >                     unsigned int len, u32 *val);
> > > 
> > > int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >                      unsigned int len, u32 val);
> > > 
> > > To read/write registers on Omnivision OVxxxx image sensors wich expect
> > > a 16 bit register address in big-endian format and which have 1-3 byte
> > > wide registers, in big-endian format (for the higher width registers).
> > > 
> > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > versions of these register access helpers, so that this code duplication
> > > can be removed.  
> > 
> > Ideally we'd have helpers for CCI, of which this is a subset. And on top of
> > regmap. I don't object adding these either though.
> 
> Well, ideally, when the atomisp-specific sensor ioctls go away, we can
> merge the atomisp-specific sensor drivers for not-yet-uptreamed sensors
> or modify the existing sensor drivers to accept the atomisp resolutions [1].

Please don't, that's not the right way to handle that. If the ISP needs
extra lines or columns, then the corresponding sensor drivers should be
converted to implement the selection API correctly, instead of adding
"modes".

> So, for now, I wouldn't convert those to use regmap. This can be done
> later with the remaining drivers.
> 
> [1] atomisp usually requires 16 extra lines/columns for it to work, so
> the current sensor drivers there allow setting resolutions like
> 1616x1216 at the sensor, while offering 1600x1200 resolution to
> userspace.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 11:27     ` Andy Shevchenko
@ 2023-02-08 15:41       ` Laurent Pinchart
  2023-02-08 15:50         ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-08 15:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

On Wed, Feb 08, 2023 at 01:27:37PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart wrote:
> > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> 
> ...
> 
> > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > versions of these register access helpers, so that this code duplication
> > > can be removed.
> >
> > Any reason to hand-roll those instead of using regmap ? Also, may I
> > suggest to have a look at drivers/media/i2c/imx290.c
> 
> While this is a bit error prone example, a patch is on its way, ...

The two cleanups are nice, but they're cleanup, not error fixes :-)

> > for an example of
> > how registers of different sizes can be handled in a less error-prone
> > way, using single read/write functions that adapt to the size
> > automatically ?
> 
> ...with regmap fields I believe you can avoid even that and use proper
> regmap accessors directly.

I haven't looked at regmap fields so I don't know if they're the right
tool for the job. If we can use the regmap API as-is without any
wrapper, even better. Otherwise, new regmap helpers and/or I2C helpers
may also be an option. This is a very common use case, not limited to OV
camera sensors, or even camera sensors in general.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 15:41       ` Laurent Pinchart
@ 2023-02-08 15:50         ` Andy Shevchenko
  2023-02-08 16:03           ` Laurent Pinchart
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-08 15:50 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

On Wed, Feb 8, 2023 at 5:41 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Wed, Feb 08, 2023 at 01:27:37PM +0200, Andy Shevchenko wrote:
> > On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart wrote:
> > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:

...

> > > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > versions of these register access helpers, so that this code duplication
> > > > can be removed.
> > >
> > > Any reason to hand-roll those instead of using regmap ? Also, may I
> > > suggest to have a look at drivers/media/i2c/imx290.c
> >
> > While this is a bit error prone example, a patch is on its way, ...
>
> The two cleanups are nice, but they're cleanup, not error fixes :-)

It depends on which side you look at it. I admit I haven't dug into
the code to see if endianess can be an issue there, but the code
itself is not written well, esp. when one offers it as an example. So
definitely there is a fix on the upper layer.

-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 15:50         ` Andy Shevchenko
@ 2023-02-08 16:03           ` Laurent Pinchart
  2023-02-08 17:31             ` Andy Shevchenko
  0 siblings, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-08 16:03 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

On Wed, Feb 08, 2023 at 05:50:26PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 8, 2023 at 5:41 PM Laurent Pinchart wrote:
> > On Wed, Feb 08, 2023 at 01:27:37PM +0200, Andy Shevchenko wrote:
> > > On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart wrote:
> > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> 
> ...
> 
> > > > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > > versions of these register access helpers, so that this code duplication
> > > > > can be removed.
> > > >
> > > > Any reason to hand-roll those instead of using regmap ? Also, may I
> > > > suggest to have a look at drivers/media/i2c/imx290.c
> > >
> > > While this is a bit error prone example, a patch is on its way, ...
> >
> > The two cleanups are nice, but they're cleanup, not error fixes :-)
> 
> It depends on which side you look at it. I admit I haven't dug into
> the code to see if endianess can be an issue there, but the code
> itself is not written well, esp. when one offers it as an example. So
> definitely there is a fix on the upper layer.

Did I miss something ? Your two patches replace a tiny amount of code
with helper functions that don't change any behaviour. It's nicer with
those helpers, no question about that, but "not written well" is a bit
of a stretch and feels quite insulting. Feel free to submit patches that
add new "well-written" helpers.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 16:03           ` Laurent Pinchart
@ 2023-02-08 17:31             ` Andy Shevchenko
  2023-02-09 10:31               ` Laurent Pinchart
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-08 17:31 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

On Wed, Feb 8, 2023 at 6:04 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> On Wed, Feb 08, 2023 at 05:50:26PM +0200, Andy Shevchenko wrote:
> > On Wed, Feb 8, 2023 at 5:41 PM Laurent Pinchart wrote:
> > > On Wed, Feb 08, 2023 at 01:27:37PM +0200, Andy Shevchenko wrote:
> > > > On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart wrote:
> > > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:

...

> > > > > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > > > versions of these register access helpers, so that this code duplication
> > > > > > can be removed.
> > > > >
> > > > > Any reason to hand-roll those instead of using regmap ? Also, may I
> > > > > suggest to have a look at drivers/media/i2c/imx290.c
> > > >
> > > > While this is a bit error prone example, a patch is on its way, ...
> > >
> > > The two cleanups are nice, but they're cleanup, not error fixes :-)
> >
> > It depends on which side you look at it. I admit I haven't dug into
> > the code to see if endianess can be an issue there, but the code
> > itself is not written well, esp. when one offers it as an example. So
> > definitely there is a fix on the upper layer.
>
> Did I miss something ? Your two patches replace a tiny amount of code
> with helper functions that don't change any behaviour. It's nicer with
> those helpers, no question about that, but "not written well" is a bit
> of a stretch and feels quite insulting.

Sorry for your feelings, what I meant is the pure educational purposes
of the example. When one takes the mentioned driver as an example and
uses the code in a slightly different environment the endianess issue
may become a real one. That's why we have helpers in kernel to improve
robustness against blind copy'n'paste approach. It does not mean your
code is broken per se.

> Feel free to submit patches that
> add new "well-written" helpers.



-- 
With Best Regards,
Andy Shevchenko

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08 17:31             ` Andy Shevchenko
@ 2023-02-09 10:31               ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-09 10:31 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Hans de Goede, Mauro Carvalho Chehab, Sakari Ailus,
	Tsuchiya Yuto, Andy Shevchenko, Yury Luneff, Nable,
	andrey.i.trufanov, Fabio Aiuto, linux-media, linux-staging

Hi Andy,

On Wed, Feb 08, 2023 at 07:31:43PM +0200, Andy Shevchenko wrote:
> On Wed, Feb 8, 2023 at 6:04 PM Laurent Pinchart wrote:
> > On Wed, Feb 08, 2023 at 05:50:26PM +0200, Andy Shevchenko wrote:
> > > On Wed, Feb 8, 2023 at 5:41 PM Laurent Pinchart wrote:
> > > > On Wed, Feb 08, 2023 at 01:27:37PM +0200, Andy Shevchenko wrote:
> > > > > On Wed, Feb 8, 2023 at 11:52 AM Laurent Pinchart wrote:
> > > > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> 
> ...
> 
> > > > > > > Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > > > > versions of these register access helpers, so that this code duplication
> > > > > > > can be removed.
> > > > > >
> > > > > > Any reason to hand-roll those instead of using regmap ? Also, may I
> > > > > > suggest to have a look at drivers/media/i2c/imx290.c
> > > > >
> > > > > While this is a bit error prone example, a patch is on its way, ...
> > > >
> > > > The two cleanups are nice, but they're cleanup, not error fixes :-)
> > >
> > > It depends on which side you look at it. I admit I haven't dug into
> > > the code to see if endianess can be an issue there, but the code
> > > itself is not written well, esp. when one offers it as an example. So
> > > definitely there is a fix on the upper layer.
> >
> > Did I miss something ? Your two patches replace a tiny amount of code
> > with helper functions that don't change any behaviour. It's nicer with
> > those helpers, no question about that, but "not written well" is a bit
> > of a stretch and feels quite insulting.
> 
> Sorry for your feelings, what I meant is the pure educational purposes
> of the example. When one takes the mentioned driver as an example and
> uses the code in a slightly different environment the endianess issue
> may become a real one. That's why we have helpers in kernel to improve
> robustness against blind copy'n'paste approach. It does not mean your
> code is broken per se.

Reference code should be pristine as much as possible, no disagreement
there. That's why I think your two patches are good :-)

> > Feel free to submit patches that
> > add new "well-written" helpers.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-08  9:52   ` Laurent Pinchart
  2023-02-08 11:27     ` Andy Shevchenko
@ 2023-02-09 15:03     ` Hans de Goede
  2023-02-09 16:11       ` Laurent Pinchart
  1 sibling, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-09 15:03 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi,

On 2/8/23 10:52, Laurent Pinchart wrote:
> Hi Hans,
> 
> Thank you for the patch.
> 
> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>
>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>> use register access helpers with the following function prototypes:
>>
>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                     unsigned int len, u32 *val);
>>
>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>                      unsigned int len, u32 val);
>>
>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>> a 16 bit register address in big-endian format and which have 1-3 byte
>> wide registers, in big-endian format (for the higher width registers).
>>
>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>> versions of these register access helpers, so that this code duplication
>> can be removed.
> 
> Any reason to hand-roll those instead of using regmap ?

These devices have a mix of 8 + 16 + 24 bit registers which regmap
appears to not handle, a regmap has a single regmap_config struct
with a single "@reg_bits: Number of bits in a register address, mandatory",
so we would still need wrappers around regmap, at which point it
really offers us very little.

Also I'm moving duplicate code present in many of the
drivers/media/i2c/ov*.c files into a common header to remove
duplicate code. The handrolling was already there before :)

My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
offer something which is as much of a drop-in replacement of the
current handrolled code as possible (usable with just a few
search-n-replaces) as possible.

Basically my idea here was to factor out code which I noticed was
being repeated over and over again. My goal was not to completely
redo how register accesses are done in these drivers.

I realize I have not yet converted any other drivers, that is because
I don't really have a way to test most of the other drivers. OTOH
with the current helpers most conversions should be fairly simply
and remove a nice amount of code. So maybe I should just only compile
test the conversions ?

> Also, may I
> suggest to have a look at drivers/media/i2c/imx290.c for an example of
> how registers of different sizes can be handled in a less error-prone
> way, using single read/write functions that adapt to the size
> automatically ?

Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
(at least I assume it is the same pattern you are talking about).

Regards,

Hans









> 
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
>>  1 file changed, 93 insertions(+)
>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
>>
>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>> new file mode 100644
>> index 000000000000..e2ffee3d797a
>> --- /dev/null
>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>> @@ -0,0 +1,93 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
>> + * a 16 bit register address in big-endian format and which have 1-3 byte
>> + * wide registers, in big-endian format (for the higher width registers).
>> + *
>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
>> + * Copyright (C) 2018 Linaro Ltd
>> + */
>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>> +
>> +#include <asm/unaligned.h>
>> +#include <linux/dev_printk.h>
>> +#include <linux/i2c.h>
>> +
>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
>> +				  unsigned int len, u32 *val)
>> +{
>> +	struct i2c_msg msgs[2];
>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
>> +	u8 data_buf[4] = { 0, };
>> +	int ret;
>> +
>> +	if (len > 4)
>> +		return -EINVAL;
>> +
>> +	msgs[0].addr = client->addr;
>> +	msgs[0].flags = 0;
>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
>> +	msgs[0].buf = addr_buf;
>> +
>> +	msgs[1].addr = client->addr;
>> +	msgs[1].flags = I2C_M_RD;
>> +	msgs[1].len = len;
>> +	msgs[1].buf = &data_buf[4 - len];
>> +
>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>> +	if (ret != ARRAY_SIZE(msgs)) {
>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
>> +		return -EIO;
>> +	}
>> +
>> +	*val = get_unaligned_be32(data_buf);
>> +
>> +	return 0;
>> +}
>> +
>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
>> +
>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
>> +				   unsigned int len, u32 val)
>> +{
>> +	u8 buf[6];
>> +	int ret;
>> +
>> +	if (len > 4)
>> +		return -EINVAL;
>> +
>> +	put_unaligned_be16(reg, buf);
>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
>> +	ret = i2c_master_send(client, buf, len + 2);
>> +	if (ret != len + 2) {
>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
>> +		return -EIO;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
>> +
>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
>> +{
>> +	u32 readval;
>> +	int ret;
>> +
>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	readval &= ~mask;
>> +	val &= mask;
>> +	val |= readval;
>> +
>> +	return ovxxxx_write_reg8(client, reg, val);
>> +}
>> +
>> +#endif
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-09 15:03     ` Hans de Goede
@ 2023-02-09 16:11       ` Laurent Pinchart
  2023-02-10 10:21         ` Sakari Ailus
  2023-02-10 11:20         ` Hans de Goede
  0 siblings, 2 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-09 16:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> On 2/8/23 10:52, Laurent Pinchart wrote:
> > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> >>
> >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> >> use register access helpers with the following function prototypes:
> >>
> >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>                     unsigned int len, u32 *val);
> >>
> >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>                      unsigned int len, u32 val);
> >>
> >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> >> a 16 bit register address in big-endian format and which have 1-3 byte
> >> wide registers, in big-endian format (for the higher width registers).
> >>
> >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> >> versions of these register access helpers, so that this code duplication
> >> can be removed.
> > 
> > Any reason to hand-roll those instead of using regmap ?
> 
> These devices have a mix of 8 + 16 + 24 bit registers which regmap
> appears to not handle, a regmap has a single regmap_config struct
> with a single "@reg_bits: Number of bits in a register address, mandatory",
> so we would still need wrappers around regmap, at which point it
> really offers us very little.

We could extend regmap too, although that may be too much yak shaving.
It would be nice, but I won't push hard for it.

> Also I'm moving duplicate code present in many of the
> drivers/media/i2c/ov*.c files into a common header to remove
> duplicate code. The handrolling was already there before :)
> 
> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> offer something which is as much of a drop-in replacement of the
> current handrolled code as possible (usable with just a few
> search-n-replaces) as possible.
> 
> Basically my idea here was to factor out code which I noticed was
> being repeated over and over again. My goal was not to completely
> redo how register accesses are done in these drivers.
> 
> I realize I have not yet converted any other drivers, that is because
> I don't really have a way to test most of the other drivers. OTOH
> with the current helpers most conversions should be fairly simply
> and remove a nice amount of code. So maybe I should just only compile
> test the conversions ?

Before you spend time converting drivers, I'd like to complete the
discussion regarding the design of those helpers. I'd rather avoid
mass-patching drivers now and doing it again in the next kernel release.

Sakari mentioned CCI (part of the CSI-2 specification). I think that
would be a good name to replace ov* here, as none of this is specific to
OmniVision.

> > Also, may I
> > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > how registers of different sizes can be handled in a less error-prone
> > way, using single read/write functions that adapt to the size
> > automatically ?
> 
> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> (at least I assume it is the same pattern you are talking about).

Correct. Can we use something like that to merge all the ov*_write_reg()
variants into a single function ? Having to select the size manually in
each call (either by picking the function variant, or by passing a size
as a function parameter) is error-prone. Encoding the size in the
register macro is much safer, easing both development and review.

> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >> ---
> >>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
> >>  1 file changed, 93 insertions(+)
> >>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>
> >> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >> new file mode 100644
> >> index 000000000000..e2ffee3d797a
> >> --- /dev/null
> >> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >> @@ -0,0 +1,93 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +/*
> >> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
> >> + * a 16 bit register address in big-endian format and which have 1-3 byte
> >> + * wide registers, in big-endian format (for the higher width registers).
> >> + *
> >> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
> >> + * Copyright (C) 2018 Linaro Ltd
> >> + */
> >> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >> +
> >> +#include <asm/unaligned.h>
> >> +#include <linux/dev_printk.h>
> >> +#include <linux/i2c.h>
> >> +
> >> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
> >> +				  unsigned int len, u32 *val)
> >> +{
> >> +	struct i2c_msg msgs[2];
> >> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
> >> +	u8 data_buf[4] = { 0, };
> >> +	int ret;
> >> +
> >> +	if (len > 4)
> >> +		return -EINVAL;
> >> +
> >> +	msgs[0].addr = client->addr;
> >> +	msgs[0].flags = 0;
> >> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> >> +	msgs[0].buf = addr_buf;
> >> +
> >> +	msgs[1].addr = client->addr;
> >> +	msgs[1].flags = I2C_M_RD;
> >> +	msgs[1].len = len;
> >> +	msgs[1].buf = &data_buf[4 - len];
> >> +
> >> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> >> +	if (ret != ARRAY_SIZE(msgs)) {
> >> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
> >> +		return -EIO;
> >> +	}
> >> +
> >> +	*val = get_unaligned_be32(data_buf);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
> >> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
> >> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
> >> +
> >> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
> >> +				   unsigned int len, u32 val)
> >> +{
> >> +	u8 buf[6];
> >> +	int ret;
> >> +
> >> +	if (len > 4)
> >> +		return -EINVAL;
> >> +
> >> +	put_unaligned_be16(reg, buf);
> >> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> >> +	ret = i2c_master_send(client, buf, len + 2);
> >> +	if (ret != len + 2) {
> >> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
> >> +		return -EIO;
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> >> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> >> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> >> +
> >> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> >> +{
> >> +	u32 readval;
> >> +	int ret;
> >> +
> >> +	ret = ovxxxx_read_reg8(client, reg, &readval);
> >> +	if (ret < 0)
> >> +		return ret;
> >> +
> >> +	readval &= ~mask;
> >> +	val &= mask;
> >> +	val |= readval;
> >> +
> >> +	return ovxxxx_write_reg8(client, reg, val);
> >> +}
> >> +
> >> +#endif

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-09 16:11       ` Laurent Pinchart
@ 2023-02-10 10:21         ` Sakari Ailus
  2023-02-10 10:29           ` Laurent Pinchart
  2023-02-10 11:20         ` Hans de Goede
  1 sibling, 1 reply; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 10:21 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> > On 2/8/23 10:52, Laurent Pinchart wrote:
> > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > >>
> > >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > >> use register access helpers with the following function prototypes:
> > >>
> > >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >>                     unsigned int len, u32 *val);
> > >>
> > >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >>                      unsigned int len, u32 val);
> > >>
> > >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> > >> a 16 bit register address in big-endian format and which have 1-3 byte
> > >> wide registers, in big-endian format (for the higher width registers).
> > >>
> > >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > >> versions of these register access helpers, so that this code duplication
> > >> can be removed.
> > > 
> > > Any reason to hand-roll those instead of using regmap ?
> > 
> > These devices have a mix of 8 + 16 + 24 bit registers which regmap
> > appears to not handle, a regmap has a single regmap_config struct
> > with a single "@reg_bits: Number of bits in a register address, mandatory",
> > so we would still need wrappers around regmap, at which point it
> > really offers us very little.
> 
> We could extend regmap too, although that may be too much yak shaving.
> It would be nice, but I won't push hard for it.

I took a look at this some time ago, too, and current regmap API is a poor
fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
on top of regmap is a better approach indeed.

Nearly all other devices have a fixed register width, so the regmap API
makes sense.

> 
> > Also I'm moving duplicate code present in many of the
> > drivers/media/i2c/ov*.c files into a common header to remove
> > duplicate code. The handrolling was already there before :)
> > 
> > My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> > offer something which is as much of a drop-in replacement of the
> > current handrolled code as possible (usable with just a few
> > search-n-replaces) as possible.
> > 
> > Basically my idea here was to factor out code which I noticed was
> > being repeated over and over again. My goal was not to completely
> > redo how register accesses are done in these drivers.
> > 
> > I realize I have not yet converted any other drivers, that is because
> > I don't really have a way to test most of the other drivers. OTOH
> > with the current helpers most conversions should be fairly simply
> > and remove a nice amount of code. So maybe I should just only compile
> > test the conversions ?
> 
> Before you spend time converting drivers, I'd like to complete the
> discussion regarding the design of those helpers. I'd rather avoid
> mass-patching drivers now and doing it again in the next kernel release.
> 
> Sakari mentioned CCI (part of the CSI-2 specification). I think that
> would be a good name to replace ov* here, as none of this is specific to
> OmniVision.
> 
> > > Also, may I
> > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > how registers of different sizes can be handled in a less error-prone
> > > way, using single read/write functions that adapt to the size
> > > automatically ?
> > 
> > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > (at least I assume it is the same pattern you are talking about).
> 
> Correct. Can we use something like that to merge all the ov*_write_reg()
> variants into a single function ? Having to select the size manually in
> each call (either by picking the function variant, or by passing a size
> as a function parameter) is error-prone. Encoding the size in the
> register macro is much safer, easing both development and review.

I think so, too.

That doesn't mean we shouldn't have function variants for specific register
sizes (taking just register addresses) though.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:21         ` Sakari Ailus
@ 2023-02-10 10:29           ` Laurent Pinchart
  2023-02-10 10:47             ` Sakari Ailus
  0 siblings, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 10:29 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Sakari,

On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> > On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> > > On 2/8/23 10:52, Laurent Pinchart wrote:
> > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > > >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > > >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > > >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > > >>
> > > >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > > >> use register access helpers with the following function prototypes:
> > > >>
> > > >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > >>                     unsigned int len, u32 *val);
> > > >>
> > > >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > >>                      unsigned int len, u32 val);
> > > >>
> > > >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> > > >> a 16 bit register address in big-endian format and which have 1-3 byte
> > > >> wide registers, in big-endian format (for the higher width registers).
> > > >>
> > > >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > >> versions of these register access helpers, so that this code duplication
> > > >> can be removed.
> > > > 
> > > > Any reason to hand-roll those instead of using regmap ?
> > > 
> > > These devices have a mix of 8 + 16 + 24 bit registers which regmap
> > > appears to not handle, a regmap has a single regmap_config struct
> > > with a single "@reg_bits: Number of bits in a register address, mandatory",
> > > so we would still need wrappers around regmap, at which point it
> > > really offers us very little.
> > 
> > We could extend regmap too, although that may be too much yak shaving.
> > It would be nice, but I won't push hard for it.
> 
> I took a look at this some time ago, too, and current regmap API is a poor
> fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> on top of regmap is a better approach indeed.

I'm confused, is regmap a poor fit, or a better approach ?

> Nearly all other devices have a fixed register width, so the regmap API
> makes sense.
> 
> > > Also I'm moving duplicate code present in many of the
> > > drivers/media/i2c/ov*.c files into a common header to remove
> > > duplicate code. The handrolling was already there before :)
> > > 
> > > My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> > > offer something which is as much of a drop-in replacement of the
> > > current handrolled code as possible (usable with just a few
> > > search-n-replaces) as possible.
> > > 
> > > Basically my idea here was to factor out code which I noticed was
> > > being repeated over and over again. My goal was not to completely
> > > redo how register accesses are done in these drivers.
> > > 
> > > I realize I have not yet converted any other drivers, that is because
> > > I don't really have a way to test most of the other drivers. OTOH
> > > with the current helpers most conversions should be fairly simply
> > > and remove a nice amount of code. So maybe I should just only compile
> > > test the conversions ?
> > 
> > Before you spend time converting drivers, I'd like to complete the
> > discussion regarding the design of those helpers. I'd rather avoid
> > mass-patching drivers now and doing it again in the next kernel release.
> > 
> > Sakari mentioned CCI (part of the CSI-2 specification). I think that
> > would be a good name to replace ov* here, as none of this is specific to
> > OmniVision.
> > 
> > > > Also, may I
> > > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > > how registers of different sizes can be handled in a less error-prone
> > > > way, using single read/write functions that adapt to the size
> > > > automatically ?
> > > 
> > > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > > (at least I assume it is the same pattern you are talking about).
> > 
> > Correct. Can we use something like that to merge all the ov*_write_reg()
> > variants into a single function ? Having to select the size manually in
> > each call (either by picking the function variant, or by passing a size
> > as a function parameter) is error-prone. Encoding the size in the
> > register macro is much safer, easing both development and review.
> 
> I think so, too.
> 
> That doesn't mean we shouldn't have function variants for specific register
> sizes (taking just register addresses) though.

I don't see why we should have multiple APIs when a single one works.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:29           ` Laurent Pinchart
@ 2023-02-10 10:47             ` Sakari Ailus
  2023-02-10 10:53               ` Andy Shevchenko
  2023-02-10 11:04               ` Laurent Pinchart
  0 siblings, 2 replies; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 10:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> Hi Sakari,
> 
> On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> > On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> > > On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> > > > On 2/8/23 10:52, Laurent Pinchart wrote:
> > > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > > > >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > > > >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > > > >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > > > >>
> > > > >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > > > >> use register access helpers with the following function prototypes:
> > > > >>
> > > > >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > > >>                     unsigned int len, u32 *val);
> > > > >>
> > > > >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > > >>                      unsigned int len, u32 val);
> > > > >>
> > > > >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> > > > >> a 16 bit register address in big-endian format and which have 1-3 byte
> > > > >> wide registers, in big-endian format (for the higher width registers).
> > > > >>
> > > > >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > >> versions of these register access helpers, so that this code duplication
> > > > >> can be removed.
> > > > > 
> > > > > Any reason to hand-roll those instead of using regmap ?
> > > > 
> > > > These devices have a mix of 8 + 16 + 24 bit registers which regmap
> > > > appears to not handle, a regmap has a single regmap_config struct
> > > > with a single "@reg_bits: Number of bits in a register address, mandatory",
> > > > so we would still need wrappers around regmap, at which point it
> > > > really offers us very little.
> > > 
> > > We could extend regmap too, although that may be too much yak shaving.
> > > It would be nice, but I won't push hard for it.
> > 
> > I took a look at this some time ago, too, and current regmap API is a poor
> > fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> > on top of regmap is a better approach indeed.
> 
> I'm confused, is regmap a poor fit, or a better approach ?

I'm proposing having something on top of regmap, but not changing regmap
itself.

> 
> > Nearly all other devices have a fixed register width, so the regmap API
> > makes sense.
> > 
> > > > Also I'm moving duplicate code present in many of the
> > > > drivers/media/i2c/ov*.c files into a common header to remove
> > > > duplicate code. The handrolling was already there before :)
> > > > 
> > > > My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> > > > offer something which is as much of a drop-in replacement of the
> > > > current handrolled code as possible (usable with just a few
> > > > search-n-replaces) as possible.
> > > > 
> > > > Basically my idea here was to factor out code which I noticed was
> > > > being repeated over and over again. My goal was not to completely
> > > > redo how register accesses are done in these drivers.
> > > > 
> > > > I realize I have not yet converted any other drivers, that is because
> > > > I don't really have a way to test most of the other drivers. OTOH
> > > > with the current helpers most conversions should be fairly simply
> > > > and remove a nice amount of code. So maybe I should just only compile
> > > > test the conversions ?
> > > 
> > > Before you spend time converting drivers, I'd like to complete the
> > > discussion regarding the design of those helpers. I'd rather avoid
> > > mass-patching drivers now and doing it again in the next kernel release.
> > > 
> > > Sakari mentioned CCI (part of the CSI-2 specification). I think that
> > > would be a good name to replace ov* here, as none of this is specific to
> > > OmniVision.
> > > 
> > > > > Also, may I
> > > > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > > > how registers of different sizes can be handled in a less error-prone
> > > > > way, using single read/write functions that adapt to the size
> > > > > automatically ?
> > > > 
> > > > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > > > (at least I assume it is the same pattern you are talking about).
> > > 
> > > Correct. Can we use something like that to merge all the ov*_write_reg()
> > > variants into a single function ? Having to select the size manually in
> > > each call (either by picking the function variant, or by passing a size
> > > as a function parameter) is error-prone. Encoding the size in the
> > > register macro is much safer, easing both development and review.
> > 
> > I think so, too.
> > 
> > That doesn't mean we shouldn't have function variants for specific register
> > sizes (taking just register addresses) though.
> 
> I don't see why we should have multiple APIs when a single one works.

Yes, it "works", but the purpose of the API is to avoid driver code. A
driver accessing fixed width registers is likely to use a helper function
with an API that requires encoding the width into the register address.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:47             ` Sakari Ailus
@ 2023-02-10 10:53               ` Andy Shevchenko
  2023-02-10 11:05                 ` Laurent Pinchart
  2023-02-10 11:19                 ` Hans de Goede
  2023-02-10 11:04               ` Laurent Pinchart
  1 sibling, 2 replies; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-10 10:53 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> > On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> > > On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:

...

> > > I took a look at this some time ago, too, and current regmap API is a poor
> > > fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> > > on top of regmap is a better approach indeed.
> > 
> > I'm confused, is regmap a poor fit, or a better approach ?
> 
> I'm proposing having something on top of regmap, but not changing regmap
> itself.

I don't understand why we can't change regmap? regmap has a facility called
regmap bus which we can provide specifically for these types of devices. What's
wrong to see it done?

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:47             ` Sakari Ailus
  2023-02-10 10:53               ` Andy Shevchenko
@ 2023-02-10 11:04               ` Laurent Pinchart
  2023-02-10 11:18                 ` Sakari Ailus
  1 sibling, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 11:04 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Sakari,

On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> > On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> > > On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> > > > On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> > > > > On 2/8/23 10:52, Laurent Pinchart wrote:
> > > > > > On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > > > > >> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > > > > >> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > > > > >> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > > > > >>
> > > > > >> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > > > > >> use register access helpers with the following function prototypes:
> > > > > >>
> > > > > >> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > > > >>                     unsigned int len, u32 *val);
> > > > > >>
> > > > > >> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > > > > >>                      unsigned int len, u32 val);
> > > > > >>
> > > > > >> To read/write registers on Omnivision OVxxxx image sensors wich expect
> > > > > >> a 16 bit register address in big-endian format and which have 1-3 byte
> > > > > >> wide registers, in big-endian format (for the higher width registers).
> > > > > >>
> > > > > >> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > > > > >> versions of these register access helpers, so that this code duplication
> > > > > >> can be removed.
> > > > > > 
> > > > > > Any reason to hand-roll those instead of using regmap ?
> > > > > 
> > > > > These devices have a mix of 8 + 16 + 24 bit registers which regmap
> > > > > appears to not handle, a regmap has a single regmap_config struct
> > > > > with a single "@reg_bits: Number of bits in a register address, mandatory",
> > > > > so we would still need wrappers around regmap, at which point it
> > > > > really offers us very little.
> > > > 
> > > > We could extend regmap too, although that may be too much yak shaving.
> > > > It would be nice, but I won't push hard for it.
> > > 
> > > I took a look at this some time ago, too, and current regmap API is a poor
> > > fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> > > on top of regmap is a better approach indeed.
> > 
> > I'm confused, is regmap a poor fit, or a better approach ?
> 
> I'm proposing having something on top of regmap, but not changing regmap
> itself.

Thanks for the clarification. I agree with you. If we later realize that
this would make sense within regmap, we can always move the code.

> > > Nearly all other devices have a fixed register width, so the regmap API
> > > makes sense.
> > > 
> > > > > Also I'm moving duplicate code present in many of the
> > > > > drivers/media/i2c/ov*.c files into a common header to remove
> > > > > duplicate code. The handrolling was already there before :)
> > > > > 
> > > > > My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> > > > > offer something which is as much of a drop-in replacement of the
> > > > > current handrolled code as possible (usable with just a few
> > > > > search-n-replaces) as possible.
> > > > > 
> > > > > Basically my idea here was to factor out code which I noticed was
> > > > > being repeated over and over again. My goal was not to completely
> > > > > redo how register accesses are done in these drivers.
> > > > > 
> > > > > I realize I have not yet converted any other drivers, that is because
> > > > > I don't really have a way to test most of the other drivers. OTOH
> > > > > with the current helpers most conversions should be fairly simply
> > > > > and remove a nice amount of code. So maybe I should just only compile
> > > > > test the conversions ?
> > > > 
> > > > Before you spend time converting drivers, I'd like to complete the
> > > > discussion regarding the design of those helpers. I'd rather avoid
> > > > mass-patching drivers now and doing it again in the next kernel release.
> > > > 
> > > > Sakari mentioned CCI (part of the CSI-2 specification). I think that
> > > > would be a good name to replace ov* here, as none of this is specific to
> > > > OmniVision.
> > > > 
> > > > > > Also, may I
> > > > > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > > > > how registers of different sizes can be handled in a less error-prone
> > > > > > way, using single read/write functions that adapt to the size
> > > > > > automatically ?
> > > > > 
> > > > > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > > > > (at least I assume it is the same pattern you are talking about).
> > > > 
> > > > Correct. Can we use something like that to merge all the ov*_write_reg()
> > > > variants into a single function ? Having to select the size manually in
> > > > each call (either by picking the function variant, or by passing a size
> > > > as a function parameter) is error-prone. Encoding the size in the
> > > > register macro is much safer, easing both development and review.
> > > 
> > > I think so, too.
> > > 
> > > That doesn't mean we shouldn't have function variants for specific register
> > > sizes (taking just register addresses) though.
> > 
> > I don't see why we should have multiple APIs when a single one works.
> 
> Yes, it "works", but the purpose of the API is to avoid driver code. A
> driver accessing fixed width registers is likely to use a helper function
> with an API that requires encoding the width into the register address.

Why not ? I don't see anything wrong with having that as a single API,
it doesn't make life more complicated for driver authors or reviewers.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:53               ` Andy Shevchenko
@ 2023-02-10 11:05                 ` Laurent Pinchart
  2023-02-10 15:35                   ` Andy Shevchenko
  2023-02-10 11:19                 ` Hans de Goede
  1 sibling, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 11:05 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Sakari Ailus, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 12:53:43PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
> > On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> > > On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> > > > On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> 
> ...
> 
> > > > I took a look at this some time ago, too, and current regmap API is a poor
> > > > fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> > > > on top of regmap is a better approach indeed.
> > > 
> > > I'm confused, is regmap a poor fit, or a better approach ?
> > 
> > I'm proposing having something on top of regmap, but not changing regmap
> > itself.
> 
> I don't understand why we can't change regmap? regmap has a facility called
> regmap bus which we can provide specifically for these types of devices. What's
> wrong to see it done?

How would that work ?

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:04               ` Laurent Pinchart
@ 2023-02-10 11:18                 ` Sakari Ailus
  2023-02-10 11:34                   ` Laurent Pinchart
  0 siblings, 1 reply; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 11:18 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On Fri, Feb 10, 2023 at 01:04:48PM +0200, Laurent Pinchart wrote:
> > > > > > > Also, may I
> > > > > > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > > > > > how registers of different sizes can be handled in a less error-prone
> > > > > > > way, using single read/write functions that adapt to the size
> > > > > > > automatically ?
> > > > > > 
> > > > > > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > > > > > (at least I assume it is the same pattern you are talking about).
> > > > > 
> > > > > Correct. Can we use something like that to merge all the ov*_write_reg()
> > > > > variants into a single function ? Having to select the size manually in
> > > > > each call (either by picking the function variant, or by passing a size
> > > > > as a function parameter) is error-prone. Encoding the size in the
> > > > > register macro is much safer, easing both development and review.
> > > > 
> > > > I think so, too.
> > > > 
> > > > That doesn't mean we shouldn't have function variants for specific register
> > > > sizes (taking just register addresses) though.
> > > 
> > > I don't see why we should have multiple APIs when a single one works.
> > 
> > Yes, it "works", but the purpose of the API is to avoid driver code. A
> > driver accessing fixed width registers is likely to use a helper function
> > with an API that requires encoding the width into the register address.
> 
> Why not ? I don't see anything wrong with having that as a single API,
> it doesn't make life more complicated for driver authors or reviewers.

Given that the reviewers (at least me) haven't had noteworthy issues when
each driver implements their own register access functions, I'm not
concerned having ~ six register read functions instead of one or two.
Driver authors should pick the one that fits the purpose best, and not be
required to implement wrappers in drivers --- which is exactly the
situation we have today.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 10:53               ` Andy Shevchenko
  2023-02-10 11:05                 ` Laurent Pinchart
@ 2023-02-10 11:19                 ` Hans de Goede
  2023-02-10 11:35                   ` Laurent Pinchart
  1 sibling, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 11:19 UTC (permalink / raw)
  To: Andy Shevchenko, Sakari Ailus
  Cc: Laurent Pinchart, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Yury Luneff, Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 2/10/23 11:53, Andy Shevchenko wrote:
> On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
>> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
>>> On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
>>>> On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> 
> ...
> 
>>>> I took a look at this some time ago, too, and current regmap API is a poor
>>>> fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
>>>> on top of regmap is a better approach indeed.
>>>
>>> I'm confused, is regmap a poor fit, or a better approach ?
>>
>> I'm proposing having something on top of regmap, but not changing regmap
>> itself.
> 
> I don't understand why we can't change regmap? regmap has a facility called
> regmap bus which we can provide specifically for these types of devices. What's
> wrong to see it done?

It is fairly easy to layer the few 16 and 24 bit register accesses over
a standard regmap with 16 bit reg-address and 8 bit reg-data width using
regmap_bulk_write() to still do the write in e.g. a single i2c-transfer.

So if we want regmap for underlying physical layer independence, e.g.
spi / i2c / i3c. we can just use standard regmap with a 
cci_write_reg helper on top.

I think that would be the most KISS solution here. One thing to also keep
in mind is the amount of work necessary to convert existing sensor drivers.
Also keeping in mind that it is not just the in tree sensor drivers, but
also all out of tree sensor drivers which I have seen use similar constructs.

Requiring drivers to have a list / array of structs of all used register
addresses + specifying the width per register address is not going to scale
very poorly wrt converting all the code out there and I'm afraid that
letting regmap somehow deal with the register-width issue is going to
require something like this.

Regards,

Hans



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-09 16:11       ` Laurent Pinchart
  2023-02-10 10:21         ` Sakari Ailus
@ 2023-02-10 11:20         ` Hans de Goede
  2023-02-10 11:45           ` Laurent Pinchart
  1 sibling, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 11:20 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On 2/9/23 17:11, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
>> On 2/8/23 10:52, Laurent Pinchart wrote:
>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>>>
>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>>>> use register access helpers with the following function prototypes:
>>>>
>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>                     unsigned int len, u32 *val);
>>>>
>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>                      unsigned int len, u32 val);
>>>>
>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>>>> a 16 bit register address in big-endian format and which have 1-3 byte
>>>> wide registers, in big-endian format (for the higher width registers).
>>>>
>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>>>> versions of these register access helpers, so that this code duplication
>>>> can be removed.
>>>
>>> Any reason to hand-roll those instead of using regmap ?
>>
>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
>> appears to not handle, a regmap has a single regmap_config struct
>> with a single "@reg_bits: Number of bits in a register address, mandatory",
>> so we would still need wrappers around regmap, at which point it
>> really offers us very little.
> 
> We could extend regmap too, although that may be too much yak shaving.
> It would be nice, but I won't push hard for it.
> 
>> Also I'm moving duplicate code present in many of the
>> drivers/media/i2c/ov*.c files into a common header to remove
>> duplicate code. The handrolling was already there before :)
>>
>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
>> offer something which is as much of a drop-in replacement of the
>> current handrolled code as possible (usable with just a few
>> search-n-replaces) as possible.
>>
>> Basically my idea here was to factor out code which I noticed was
>> being repeated over and over again. My goal was not to completely
>> redo how register accesses are done in these drivers.
>>
>> I realize I have not yet converted any other drivers, that is because
>> I don't really have a way to test most of the other drivers. OTOH
>> with the current helpers most conversions should be fairly simply
>> and remove a nice amount of code. So maybe I should just only compile
>> test the conversions ?
> 
> Before you spend time converting drivers, I'd like to complete the
> discussion regarding the design of those helpers. I'd rather avoid
> mass-patching drivers now and doing it again in the next kernel release.

I completely agree.

> Sakari mentioned CCI (part of the CSI-2 specification). I think that
> would be a good name to replace ov* here, as none of this is specific to
> OmniVision.

I did not realize this was CCI I agree renaming the helpers makes sense.

I see there still is a lot of discussion going on.

I'll do a follow up series renaming the helpers and converting the
atomisp ov2680 sensor driver (!) to the new helpers when the current
discussion about this is done.

And then we can discuss any further details based on v1 of that
follow up series.

Regards,

Hans



1) this is already in media-next, but only used by the 1 staging atomisp sensor driver


> 
>>> Also, may I
>>> suggest to have a look at drivers/media/i2c/imx290.c for an example of
>>> how registers of different sizes can be handled in a less error-prone
>>> way, using single read/write functions that adapt to the size
>>> automatically ?
>>
>> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
>> (at least I assume it is the same pattern you are talking about).
> 
> Correct. Can we use something like that to merge all the ov*_write_reg()
> variants into a single function ? Having to select the size manually in
> each call (either by picking the function variant, or by passing a size
> as a function parameter) is error-prone. Encoding the size in the
> register macro is much safer, easing both development and review.
> 
>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>> ---
>>>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
>>>>  1 file changed, 93 insertions(+)
>>>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>
>>>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>> new file mode 100644
>>>> index 000000000000..e2ffee3d797a
>>>> --- /dev/null
>>>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>> @@ -0,0 +1,93 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>> +/*
>>>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
>>>> + * a 16 bit register address in big-endian format and which have 1-3 byte
>>>> + * wide registers, in big-endian format (for the higher width registers).
>>>> + *
>>>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
>>>> + * Copyright (C) 2018 Linaro Ltd
>>>> + */
>>>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>> +
>>>> +#include <asm/unaligned.h>
>>>> +#include <linux/dev_printk.h>
>>>> +#include <linux/i2c.h>
>>>> +
>>>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
>>>> +				  unsigned int len, u32 *val)
>>>> +{
>>>> +	struct i2c_msg msgs[2];
>>>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
>>>> +	u8 data_buf[4] = { 0, };
>>>> +	int ret;
>>>> +
>>>> +	if (len > 4)
>>>> +		return -EINVAL;
>>>> +
>>>> +	msgs[0].addr = client->addr;
>>>> +	msgs[0].flags = 0;
>>>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
>>>> +	msgs[0].buf = addr_buf;
>>>> +
>>>> +	msgs[1].addr = client->addr;
>>>> +	msgs[1].flags = I2C_M_RD;
>>>> +	msgs[1].len = len;
>>>> +	msgs[1].buf = &data_buf[4 - len];
>>>> +
>>>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>>>> +	if (ret != ARRAY_SIZE(msgs)) {
>>>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
>>>> +		return -EIO;
>>>> +	}
>>>> +
>>>> +	*val = get_unaligned_be32(data_buf);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
>>>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
>>>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
>>>> +
>>>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
>>>> +				   unsigned int len, u32 val)
>>>> +{
>>>> +	u8 buf[6];
>>>> +	int ret;
>>>> +
>>>> +	if (len > 4)
>>>> +		return -EINVAL;
>>>> +
>>>> +	put_unaligned_be16(reg, buf);
>>>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
>>>> +	ret = i2c_master_send(client, buf, len + 2);
>>>> +	if (ret != len + 2) {
>>>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
>>>> +		return -EIO;
>>>> +	}
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>>>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>>>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
>>>> +
>>>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
>>>> +{
>>>> +	u32 readval;
>>>> +	int ret;
>>>> +
>>>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>> +
>>>> +	readval &= ~mask;
>>>> +	val &= mask;
>>>> +	val |= readval;
>>>> +
>>>> +	return ovxxxx_write_reg8(client, reg, val);
>>>> +}
>>>> +
>>>> +#endif
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:18                 ` Sakari Ailus
@ 2023-02-10 11:34                   ` Laurent Pinchart
  0 siblings, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 11:34 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Sakari,

On Fri, Feb 10, 2023 at 01:18:12PM +0200, Sakari Ailus wrote:
> On Fri, Feb 10, 2023 at 01:04:48PM +0200, Laurent Pinchart wrote:
> > > > > > > > Also, may I
> > > > > > > > suggest to have a look at drivers/media/i2c/imx290.c for an example of
> > > > > > > > how registers of different sizes can be handled in a less error-prone
> > > > > > > > way, using single read/write functions that adapt to the size
> > > > > > > > automatically ?
> > > > > > > 
> > > > > > > Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> > > > > > > (at least I assume it is the same pattern you are talking about).
> > > > > > 
> > > > > > Correct. Can we use something like that to merge all the ov*_write_reg()
> > > > > > variants into a single function ? Having to select the size manually in
> > > > > > each call (either by picking the function variant, or by passing a size
> > > > > > as a function parameter) is error-prone. Encoding the size in the
> > > > > > register macro is much safer, easing both development and review.
> > > > > 
> > > > > I think so, too.
> > > > > 
> > > > > That doesn't mean we shouldn't have function variants for specific register
> > > > > sizes (taking just register addresses) though.
> > > > 
> > > > I don't see why we should have multiple APIs when a single one works.
> > > 
> > > Yes, it "works", but the purpose of the API is to avoid driver code. A
> > > driver accessing fixed width registers is likely to use a helper function
> > > with an API that requires encoding the width into the register address.
> > 
> > Why not ? I don't see anything wrong with having that as a single API,
> > it doesn't make life more complicated for driver authors or reviewers.
> 
> Given that the reviewers (at least me) haven't had noteworthy issues when
> each driver implements their own register access functions, I'm not
> concerned having ~ six register read functions instead of one or two.
> Driver authors should pick the one that fits the purpose best, and not be
> required to implement wrappers in drivers --- which is exactly the
> situation we have today.

It's of course always technically possibly to have more functions, but I
don't see any practical advantage.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:19                 ` Hans de Goede
@ 2023-02-10 11:35                   ` Laurent Pinchart
  2023-02-10 12:01                     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 11:35 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Andy Shevchenko, Sakari Ailus, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 12:19:30PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 2/10/23 11:53, Andy Shevchenko wrote:
> > On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
> >> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> >>> On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> >>>> On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> > 
> > ...
> > 
> >>>> I took a look at this some time ago, too, and current regmap API is a poor
> >>>> fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> >>>> on top of regmap is a better approach indeed.
> >>>
> >>> I'm confused, is regmap a poor fit, or a better approach ?
> >>
> >> I'm proposing having something on top of regmap, but not changing regmap
> >> itself.
> > 
> > I don't understand why we can't change regmap? regmap has a facility called
> > regmap bus which we can provide specifically for these types of devices. What's
> > wrong to see it done?
> 
> It is fairly easy to layer the few 16 and 24 bit register accesses over
> a standard regmap with 16 bit reg-address and 8 bit reg-data width using
> regmap_bulk_write() to still do the write in e.g. a single i2c-transfer.

I think we could also use regmap_raw_write().

> So if we want regmap for underlying physical layer independence, e.g.
> spi / i2c / i3c. we can just use standard regmap with a 
> cci_write_reg helper on top.

Agreed. We can start experimenting with this, and if somebody has use
cases outside of the camera sensor drivers space, we could later move
those helpers to regmap.

> I think that would be the most KISS solution here. One thing to also keep
> in mind is the amount of work necessary to convert existing sensor drivers.
> Also keeping in mind that it is not just the in tree sensor drivers, but
> also all out of tree sensor drivers which I have seen use similar constructs.

If this was the only issue to handle when porting drivers to mainline
and upstreaming them, I'd be happy :-)

> Requiring drivers to have a list / array of structs of all used register
> addresses + specifying the width per register address is not going to scale
> very poorly wrt converting all the code out there and I'm afraid that
> letting regmap somehow deal with the register-width issue is going to
> require something like this.

Did you mean "not going to scale very well" ? I'm not sure to understand
what you mean here.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:20         ` Hans de Goede
@ 2023-02-10 11:45           ` Laurent Pinchart
  2023-02-10 11:56             ` Hans de Goede
  2023-02-10 12:26             ` Sakari Ailus
  0 siblings, 2 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 11:45 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
> On 2/9/23 17:11, Laurent Pinchart wrote:
> > On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> >> On 2/8/23 10:52, Laurent Pinchart wrote:
> >>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> >>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> >>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> >>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> >>>>
> >>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> >>>> use register access helpers with the following function prototypes:
> >>>>
> >>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>>>                     unsigned int len, u32 *val);
> >>>>
> >>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>>>                      unsigned int len, u32 val);
> >>>>
> >>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
> >>>> a 16 bit register address in big-endian format and which have 1-3 byte
> >>>> wide registers, in big-endian format (for the higher width registers).
> >>>>
> >>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> >>>> versions of these register access helpers, so that this code duplication
> >>>> can be removed.
> >>>
> >>> Any reason to hand-roll those instead of using regmap ?
> >>
> >> These devices have a mix of 8 + 16 + 24 bit registers which regmap
> >> appears to not handle, a regmap has a single regmap_config struct
> >> with a single "@reg_bits: Number of bits in a register address, mandatory",
> >> so we would still need wrappers around regmap, at which point it
> >> really offers us very little.
> > 
> > We could extend regmap too, although that may be too much yak shaving.
> > It would be nice, but I won't push hard for it.
> > 
> >> Also I'm moving duplicate code present in many of the
> >> drivers/media/i2c/ov*.c files into a common header to remove
> >> duplicate code. The handrolling was already there before :)
> >>
> >> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> >> offer something which is as much of a drop-in replacement of the
> >> current handrolled code as possible (usable with just a few
> >> search-n-replaces) as possible.
> >>
> >> Basically my idea here was to factor out code which I noticed was
> >> being repeated over and over again. My goal was not to completely
> >> redo how register accesses are done in these drivers.
> >>
> >> I realize I have not yet converted any other drivers, that is because
> >> I don't really have a way to test most of the other drivers. OTOH
> >> with the current helpers most conversions should be fairly simply
> >> and remove a nice amount of code. So maybe I should just only compile
> >> test the conversions ?
> > 
> > Before you spend time converting drivers, I'd like to complete the
> > discussion regarding the design of those helpers. I'd rather avoid
> > mass-patching drivers now and doing it again in the next kernel release.
> 
> I completely agree.
> 
> > Sakari mentioned CCI (part of the CSI-2 specification). I think that
> > would be a good name to replace ov* here, as none of this is specific to
> > OmniVision.
> 
> I did not realize this was CCI I agree renaming the helpers makes sense.
> 
> I see there still is a lot of discussion going on.

I haven't seen any disagreement regarding the cci prefix, so let's go
for that. I'd propose cci_read() and cci_write().

Sakari, you and I would prefer layering this on top of regmap, while
Andy proposed extending the regmap API. Let's see if we reach an
anonymous agreement on this.

Regarding the width-specific versions of the helpers, I really think
encoding the size in the register macros is the best option. It makes
life easier for driver authors (only one function to call, no need to
think about the register width to pick the appropriate function in each
call) and reviewers (same reason), without any drawback in my opinion.

Another feature I'd like in these helpers is improved error handling. In
quite a few sensor drivers I've written, I've implemented the write
function as

int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
{
	...
	int ret;

	if (err && *err)
		return *err;

	ret = real_write(...);
	if (ret < 0) {
		dev_err(...);
		if (err)
			*err = ret;
	}

	return ret;
}

This allows callers to write

	int ret = 0;

	foo_write(foo, REG_A, 0, &ret);
	foo_write(foo, REG_B, 1, &ret);
	foo_write(foo, REG_C, 2, &ret);
	foo_write(foo, REG_D, 3, &ret);

	return ret;

which massively simplifies error handling. I'd like the CCI write helper
to implement such a pattern.

> I'll do a follow up series renaming the helpers and converting the
> atomisp ov2680 sensor driver (!) to the new helpers when the current
> discussion about this is done.

Thank you in advance.

> And then we can discuss any further details based on v1 of that
> follow up series.
> 
> Regards,
> 
> Hans
> 
> 1) this is already in media-next, but only used by the 1 staging atomisp sensor driver

That's fine, let's just make sure not to use these new helpers further
before we rename them.

> >>> Also, may I
> >>> suggest to have a look at drivers/media/i2c/imx290.c for an example of
> >>> how registers of different sizes can be handled in a less error-prone
> >>> way, using single read/write functions that adapt to the size
> >>> automatically ?
> >>
> >> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> >> (at least I assume it is the same pattern you are talking about).
> > 
> > Correct. Can we use something like that to merge all the ov*_write_reg()
> > variants into a single function ? Having to select the size manually in
> > each call (either by picking the function variant, or by passing a size
> > as a function parameter) is error-prone. Encoding the size in the
> > register macro is much safer, easing both development and review.
> > 
> >>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>> ---
> >>>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
> >>>>  1 file changed, 93 insertions(+)
> >>>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>>
> >>>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>> new file mode 100644
> >>>> index 000000000000..e2ffee3d797a
> >>>> --- /dev/null
> >>>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>> @@ -0,0 +1,93 @@
> >>>> +/* SPDX-License-Identifier: GPL-2.0 */
> >>>> +/*
> >>>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
> >>>> + * a 16 bit register address in big-endian format and which have 1-3 byte
> >>>> + * wide registers, in big-endian format (for the higher width registers).
> >>>> + *
> >>>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
> >>>> + * Copyright (C) 2018 Linaro Ltd
> >>>> + */
> >>>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >>>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >>>> +
> >>>> +#include <asm/unaligned.h>
> >>>> +#include <linux/dev_printk.h>
> >>>> +#include <linux/i2c.h>
> >>>> +
> >>>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
> >>>> +				  unsigned int len, u32 *val)
> >>>> +{
> >>>> +	struct i2c_msg msgs[2];
> >>>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
> >>>> +	u8 data_buf[4] = { 0, };
> >>>> +	int ret;
> >>>> +
> >>>> +	if (len > 4)
> >>>> +		return -EINVAL;
> >>>> +
> >>>> +	msgs[0].addr = client->addr;
> >>>> +	msgs[0].flags = 0;
> >>>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> >>>> +	msgs[0].buf = addr_buf;
> >>>> +
> >>>> +	msgs[1].addr = client->addr;
> >>>> +	msgs[1].flags = I2C_M_RD;
> >>>> +	msgs[1].len = len;
> >>>> +	msgs[1].buf = &data_buf[4 - len];
> >>>> +
> >>>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> >>>> +	if (ret != ARRAY_SIZE(msgs)) {
> >>>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
> >>>> +		return -EIO;
> >>>> +	}
> >>>> +
> >>>> +	*val = get_unaligned_be32(data_buf);
> >>>> +
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
> >>>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
> >>>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
> >>>> +
> >>>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
> >>>> +				   unsigned int len, u32 val)
> >>>> +{
> >>>> +	u8 buf[6];
> >>>> +	int ret;
> >>>> +
> >>>> +	if (len > 4)
> >>>> +		return -EINVAL;
> >>>> +
> >>>> +	put_unaligned_be16(reg, buf);
> >>>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> >>>> +	ret = i2c_master_send(client, buf, len + 2);
> >>>> +	if (ret != len + 2) {
> >>>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
> >>>> +		return -EIO;
> >>>> +	}
> >>>> +
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> >>>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> >>>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> >>>> +
> >>>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> >>>> +{
> >>>> +	u32 readval;
> >>>> +	int ret;
> >>>> +
> >>>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
> >>>> +	if (ret < 0)
> >>>> +		return ret;
> >>>> +
> >>>> +	readval &= ~mask;
> >>>> +	val &= mask;
> >>>> +	val |= readval;
> >>>> +
> >>>> +	return ovxxxx_write_reg8(client, reg, val);
> >>>> +}
> >>>> +
> >>>> +#endif

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:45           ` Laurent Pinchart
@ 2023-02-10 11:56             ` Hans de Goede
  2023-02-10 12:09               ` Laurent Pinchart
  2023-02-10 12:26             ` Sakari Ailus
  1 sibling, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 11:56 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi,

On 2/10/23 12:45, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
>> On 2/9/23 17:11, Laurent Pinchart wrote:
>>> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
>>>> On 2/8/23 10:52, Laurent Pinchart wrote:
>>>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>>>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>>>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>>>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>>>>>
>>>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>>>>>> use register access helpers with the following function prototypes:
>>>>>>
>>>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>                     unsigned int len, u32 *val);
>>>>>>
>>>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>                      unsigned int len, u32 val);
>>>>>>
>>>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>>>>>> a 16 bit register address in big-endian format and which have 1-3 byte
>>>>>> wide registers, in big-endian format (for the higher width registers).
>>>>>>
>>>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>>>>>> versions of these register access helpers, so that this code duplication
>>>>>> can be removed.
>>>>>
>>>>> Any reason to hand-roll those instead of using regmap ?
>>>>
>>>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
>>>> appears to not handle, a regmap has a single regmap_config struct
>>>> with a single "@reg_bits: Number of bits in a register address, mandatory",
>>>> so we would still need wrappers around regmap, at which point it
>>>> really offers us very little.
>>>
>>> We could extend regmap too, although that may be too much yak shaving.
>>> It would be nice, but I won't push hard for it.
>>>
>>>> Also I'm moving duplicate code present in many of the
>>>> drivers/media/i2c/ov*.c files into a common header to remove
>>>> duplicate code. The handrolling was already there before :)
>>>>
>>>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
>>>> offer something which is as much of a drop-in replacement of the
>>>> current handrolled code as possible (usable with just a few
>>>> search-n-replaces) as possible.
>>>>
>>>> Basically my idea here was to factor out code which I noticed was
>>>> being repeated over and over again. My goal was not to completely
>>>> redo how register accesses are done in these drivers.
>>>>
>>>> I realize I have not yet converted any other drivers, that is because
>>>> I don't really have a way to test most of the other drivers. OTOH
>>>> with the current helpers most conversions should be fairly simply
>>>> and remove a nice amount of code. So maybe I should just only compile
>>>> test the conversions ?
>>>
>>> Before you spend time converting drivers, I'd like to complete the
>>> discussion regarding the design of those helpers. I'd rather avoid
>>> mass-patching drivers now and doing it again in the next kernel release.
>>
>> I completely agree.
>>
>>> Sakari mentioned CCI (part of the CSI-2 specification). I think that
>>> would be a good name to replace ov* here, as none of this is specific to
>>> OmniVision.
>>
>> I did not realize this was CCI I agree renaming the helpers makes sense.
>>
>> I see there still is a lot of discussion going on.
> 
> I haven't seen any disagreement regarding the cci prefix, so let's go
> for that. I'd propose cci_read() and cci_write().
> 
> Sakari, you and I would prefer layering this on top of regmap, while
> Andy proposed extending the regmap API. Let's see if we reach an
> anonymous agreement on this.
> 
> Regarding the width-specific versions of the helpers, I really think
> encoding the size in the register macros is the best option. It makes
> life easier for driver authors (only one function to call, no need to
> think about the register width to pick the appropriate function in each
> call) and reviewers (same reason), without any drawback in my opinion.
> 
> Another feature I'd like in these helpers is improved error handling. In
> quite a few sensor drivers I've written, I've implemented the write
> function as
> 
> int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
> {
> 	...
> 	int ret;
> 
> 	if (err && *err)
> 		return *err;
> 
> 	ret = real_write(...);
> 	if (ret < 0) {
> 		dev_err(...);
> 		if (err)
> 			*err = ret;
> 	}
> 
> 	return ret;
> }
> 
> This allows callers to write
> 
> 	int ret = 0;
> 
> 	foo_write(foo, REG_A, 0, &ret);
> 	foo_write(foo, REG_B, 1, &ret);
> 	foo_write(foo, REG_C, 2, &ret);
> 	foo_write(foo, REG_D, 3, &ret);
> 
> 	return ret;
> 
> which massively simplifies error handling. I'd like the CCI write helper
> to implement such a pattern.

Interesting, I see that the passing of the err return pointer is optional,
so we can still just do a search replace in existing code setting that
to just NULL.

I like this I agree we should add this.


> 
>> I'll do a follow up series renaming the helpers and converting the
>> atomisp ov2680 sensor driver (!) to the new helpers when the current
>> discussion about this is done.
> 
> Thank you in advance.
> 
>> And then we can discuss any further details based on v1 of that
>> follow up series.
>>
>> Regards,
>>
>> Hans
>>
>> 1) this is already in media-next, but only used by the 1 staging atomisp sensor driver
> 
> That's fine, let's just make sure not to use these new helpers further
> before we rename them.

Ack.

Regards,

Hans



> 
>>>>> Also, may I
>>>>> suggest to have a look at drivers/media/i2c/imx290.c for an example of
>>>>> how registers of different sizes can be handled in a less error-prone
>>>>> way, using single read/write functions that adapt to the size
>>>>> automatically ?
>>>>
>>>> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
>>>> (at least I assume it is the same pattern you are talking about).
>>>
>>> Correct. Can we use something like that to merge all the ov*_write_reg()
>>> variants into a single function ? Having to select the size manually in
>>> each call (either by picking the function variant, or by passing a size
>>> as a function parameter) is error-prone. Encoding the size in the
>>> register macro is much safer, easing both development and review.
>>>
>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>>> ---
>>>>>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
>>>>>>  1 file changed, 93 insertions(+)
>>>>>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>>
>>>>>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>> new file mode 100644
>>>>>> index 000000000000..e2ffee3d797a
>>>>>> --- /dev/null
>>>>>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>> @@ -0,0 +1,93 @@
>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>> +/*
>>>>>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
>>>>>> + * a 16 bit register address in big-endian format and which have 1-3 byte
>>>>>> + * wide registers, in big-endian format (for the higher width registers).
>>>>>> + *
>>>>>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
>>>>>> + * Copyright (C) 2018 Linaro Ltd
>>>>>> + */
>>>>>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>>>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>>>> +
>>>>>> +#include <asm/unaligned.h>
>>>>>> +#include <linux/dev_printk.h>
>>>>>> +#include <linux/i2c.h>
>>>>>> +
>>>>>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
>>>>>> +				  unsigned int len, u32 *val)
>>>>>> +{
>>>>>> +	struct i2c_msg msgs[2];
>>>>>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
>>>>>> +	u8 data_buf[4] = { 0, };
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	if (len > 4)
>>>>>> +		return -EINVAL;
>>>>>> +
>>>>>> +	msgs[0].addr = client->addr;
>>>>>> +	msgs[0].flags = 0;
>>>>>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
>>>>>> +	msgs[0].buf = addr_buf;
>>>>>> +
>>>>>> +	msgs[1].addr = client->addr;
>>>>>> +	msgs[1].flags = I2C_M_RD;
>>>>>> +	msgs[1].len = len;
>>>>>> +	msgs[1].buf = &data_buf[4 - len];
>>>>>> +
>>>>>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>>>>>> +	if (ret != ARRAY_SIZE(msgs)) {
>>>>>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
>>>>>> +		return -EIO;
>>>>>> +	}
>>>>>> +
>>>>>> +	*val = get_unaligned_be32(data_buf);
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
>>>>>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
>>>>>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
>>>>>> +
>>>>>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
>>>>>> +				   unsigned int len, u32 val)
>>>>>> +{
>>>>>> +	u8 buf[6];
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	if (len > 4)
>>>>>> +		return -EINVAL;
>>>>>> +
>>>>>> +	put_unaligned_be16(reg, buf);
>>>>>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
>>>>>> +	ret = i2c_master_send(client, buf, len + 2);
>>>>>> +	if (ret != len + 2) {
>>>>>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
>>>>>> +		return -EIO;
>>>>>> +	}
>>>>>> +
>>>>>> +	return 0;
>>>>>> +}
>>>>>> +
>>>>>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>>>>>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>>>>>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
>>>>>> +
>>>>>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
>>>>>> +{
>>>>>> +	u32 readval;
>>>>>> +	int ret;
>>>>>> +
>>>>>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
>>>>>> +	if (ret < 0)
>>>>>> +		return ret;
>>>>>> +
>>>>>> +	readval &= ~mask;
>>>>>> +	val &= mask;
>>>>>> +	val |= readval;
>>>>>> +
>>>>>> +	return ovxxxx_write_reg8(client, reg, val);
>>>>>> +}
>>>>>> +
>>>>>> +#endif
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:35                   ` Laurent Pinchart
@ 2023-02-10 12:01                     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 12:01 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Andy Shevchenko, Sakari Ailus, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi,

On 2/10/23 12:35, Laurent Pinchart wrote:
> On Fri, Feb 10, 2023 at 12:19:30PM +0100, Hans de Goede wrote:
>> Hi,
>>
>> On 2/10/23 11:53, Andy Shevchenko wrote:
>>> On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
>>>> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
>>>>> On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
>>>>>> On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
>>>
>>> ...
>>>
>>>>>> I took a look at this some time ago, too, and current regmap API is a poor
>>>>>> fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
>>>>>> on top of regmap is a better approach indeed.
>>>>>
>>>>> I'm confused, is regmap a poor fit, or a better approach ?
>>>>
>>>> I'm proposing having something on top of regmap, but not changing regmap
>>>> itself.
>>>
>>> I don't understand why we can't change regmap? regmap has a facility called
>>> regmap bus which we can provide specifically for these types of devices. What's
>>> wrong to see it done?
>>
>> It is fairly easy to layer the few 16 and 24 bit register accesses over
>> a standard regmap with 16 bit reg-address and 8 bit reg-data width using
>> regmap_bulk_write() to still do the write in e.g. a single i2c-transfer.
> 
> I think we could also use regmap_raw_write().
> 
>> So if we want regmap for underlying physical layer independence, e.g.
>> spi / i2c / i3c. we can just use standard regmap with a 
>> cci_write_reg helper on top.
> 
> Agreed. We can start experimenting with this, and if somebody has use
> cases outside of the camera sensor drivers space, we could later move
> those helpers to regmap.
> 
>> I think that would be the most KISS solution here. One thing to also keep
>> in mind is the amount of work necessary to convert existing sensor drivers.
>> Also keeping in mind that it is not just the in tree sensor drivers, but
>> also all out of tree sensor drivers which I have seen use similar constructs.
> 
> If this was the only issue to handle when porting drivers to mainline
> and upstreaming them, I'd be happy :-)

True :) The amount of churn on the stating atomisp sensor drivers which
(the few which I have been working on so far) is quite big and that is just
inching them closer to being mainline ready.

>> Requiring drivers to have a list / array of structs of all used register
>> addresses + specifying the width per register address is not going to scale
>> very poorly wrt converting all the code out there and I'm afraid that
>> letting regmap somehow deal with the register-width issue is going to
>> require something like this.
> 
> Did you mean "not going to scale very well" ? I'm not sure to understand
> what you mean here.

Yes my bad I meant to write "not going to scale very well".

I think that having to pass these kinda long lists of registers with
regmap already when you want to use caching (and need to specify volatile
registers which cannot be cached) is a bit of a pain of using regmap (*)

Regards,

Hans


*) Not that I have a better solution for e.g. the volatile registers thing,
it just causes a lot of what feels like boilerplate code


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:56             ` Hans de Goede
@ 2023-02-10 12:09               ` Laurent Pinchart
  2023-02-10 12:17                 ` Sakari Ailus
  2023-02-10 12:47                 ` Hans de Goede
  0 siblings, 2 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 12:09 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 12:56:45PM +0100, Hans de Goede wrote:
> On 2/10/23 12:45, Laurent Pinchart wrote:
> > On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
> >> On 2/9/23 17:11, Laurent Pinchart wrote:
> >>> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> >>>> On 2/8/23 10:52, Laurent Pinchart wrote:
> >>>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> >>>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> >>>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> >>>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> >>>>>>
> >>>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> >>>>>> use register access helpers with the following function prototypes:
> >>>>>>
> >>>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>>>>>                     unsigned int len, u32 *val);
> >>>>>>
> >>>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> >>>>>>                      unsigned int len, u32 val);
> >>>>>>
> >>>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
> >>>>>> a 16 bit register address in big-endian format and which have 1-3 byte
> >>>>>> wide registers, in big-endian format (for the higher width registers).
> >>>>>>
> >>>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> >>>>>> versions of these register access helpers, so that this code duplication
> >>>>>> can be removed.
> >>>>>
> >>>>> Any reason to hand-roll those instead of using regmap ?
> >>>>
> >>>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
> >>>> appears to not handle, a regmap has a single regmap_config struct
> >>>> with a single "@reg_bits: Number of bits in a register address, mandatory",
> >>>> so we would still need wrappers around regmap, at which point it
> >>>> really offers us very little.
> >>>
> >>> We could extend regmap too, although that may be too much yak shaving.
> >>> It would be nice, but I won't push hard for it.
> >>>
> >>>> Also I'm moving duplicate code present in many of the
> >>>> drivers/media/i2c/ov*.c files into a common header to remove
> >>>> duplicate code. The handrolling was already there before :)
> >>>>
> >>>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> >>>> offer something which is as much of a drop-in replacement of the
> >>>> current handrolled code as possible (usable with just a few
> >>>> search-n-replaces) as possible.
> >>>>
> >>>> Basically my idea here was to factor out code which I noticed was
> >>>> being repeated over and over again. My goal was not to completely
> >>>> redo how register accesses are done in these drivers.
> >>>>
> >>>> I realize I have not yet converted any other drivers, that is because
> >>>> I don't really have a way to test most of the other drivers. OTOH
> >>>> with the current helpers most conversions should be fairly simply
> >>>> and remove a nice amount of code. So maybe I should just only compile
> >>>> test the conversions ?
> >>>
> >>> Before you spend time converting drivers, I'd like to complete the
> >>> discussion regarding the design of those helpers. I'd rather avoid
> >>> mass-patching drivers now and doing it again in the next kernel release.
> >>
> >> I completely agree.
> >>
> >>> Sakari mentioned CCI (part of the CSI-2 specification). I think that
> >>> would be a good name to replace ov* here, as none of this is specific to
> >>> OmniVision.
> >>
> >> I did not realize this was CCI I agree renaming the helpers makes sense.
> >>
> >> I see there still is a lot of discussion going on.
> > 
> > I haven't seen any disagreement regarding the cci prefix, so let's go
> > for that. I'd propose cci_read() and cci_write().
> > 
> > Sakari, you and I would prefer layering this on top of regmap, while
> > Andy proposed extending the regmap API. Let's see if we reach an
> > anonymous agreement on this.
> > 
> > Regarding the width-specific versions of the helpers, I really think
> > encoding the size in the register macros is the best option. It makes
> > life easier for driver authors (only one function to call, no need to
> > think about the register width to pick the appropriate function in each
> > call) and reviewers (same reason), without any drawback in my opinion.
> > 
> > Another feature I'd like in these helpers is improved error handling. In
> > quite a few sensor drivers I've written, I've implemented the write
> > function as
> > 
> > int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
> > {
> > 	...
> > 	int ret;
> > 
> > 	if (err && *err)
> > 		return *err;
> > 
> > 	ret = real_write(...);
> > 	if (ret < 0) {
> > 		dev_err(...);
> > 		if (err)
> > 			*err = ret;
> > 	}
> > 
> > 	return ret;
> > }
> > 
> > This allows callers to write
> > 
> > 	int ret = 0;
> > 
> > 	foo_write(foo, REG_A, 0, &ret);
> > 	foo_write(foo, REG_B, 1, &ret);
> > 	foo_write(foo, REG_C, 2, &ret);
> > 	foo_write(foo, REG_D, 3, &ret);
> > 
> > 	return ret;
> > 
> > which massively simplifies error handling. I'd like the CCI write helper
> > to implement such a pattern.
> 
> Interesting, I see that the passing of the err return pointer is optional,
> so we can still just do a search replace in existing code setting that
> to just NULL.

And if someone dislikes having to pass NULL for the last argument, we
could use some macro magic to accept both the 3 arguments and 4
arguments variants.

int __cci_write3(struct cci *cci, u32 reg, u32 val);
int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);

#define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
#define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)

> I like this I agree we should add this.

Glad you like it :-)

> >> I'll do a follow up series renaming the helpers and converting the
> >> atomisp ov2680 sensor driver (!) to the new helpers when the current
> >> discussion about this is done.
> > 
> > Thank you in advance.
> > 
> >> And then we can discuss any further details based on v1 of that
> >> follow up series.
> >>
> >> Regards,
> >>
> >> Hans
> >>
> >> 1) this is already in media-next, but only used by the 1 staging atomisp sensor driver
> > 
> > That's fine, let's just make sure not to use these new helpers further
> > before we rename them.
> 
> Ack.
> 
> >>>>> Also, may I
> >>>>> suggest to have a look at drivers/media/i2c/imx290.c for an example of
> >>>>> how registers of different sizes can be handled in a less error-prone
> >>>>> way, using single read/write functions that adapt to the size
> >>>>> automatically ?
> >>>>
> >>>> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
> >>>> (at least I assume it is the same pattern you are talking about).
> >>>
> >>> Correct. Can we use something like that to merge all the ov*_write_reg()
> >>> variants into a single function ? Having to select the size manually in
> >>> each call (either by picking the function variant, or by passing a size
> >>> as a function parameter) is error-prone. Encoding the size in the
> >>> register macro is much safer, easing both development and review.
> >>>
> >>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>>>> ---
> >>>>>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
> >>>>>>  1 file changed, 93 insertions(+)
> >>>>>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>>>>
> >>>>>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>>>> new file mode 100644
> >>>>>> index 000000000000..e2ffee3d797a
> >>>>>> --- /dev/null
> >>>>>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
> >>>>>> @@ -0,0 +1,93 @@
> >>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
> >>>>>> +/*
> >>>>>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
> >>>>>> + * a 16 bit register address in big-endian format and which have 1-3 byte
> >>>>>> + * wide registers, in big-endian format (for the higher width registers).
> >>>>>> + *
> >>>>>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
> >>>>>> + * Copyright (C) 2018 Linaro Ltd
> >>>>>> + */
> >>>>>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >>>>>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
> >>>>>> +
> >>>>>> +#include <asm/unaligned.h>
> >>>>>> +#include <linux/dev_printk.h>
> >>>>>> +#include <linux/i2c.h>
> >>>>>> +
> >>>>>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
> >>>>>> +				  unsigned int len, u32 *val)
> >>>>>> +{
> >>>>>> +	struct i2c_msg msgs[2];
> >>>>>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
> >>>>>> +	u8 data_buf[4] = { 0, };
> >>>>>> +	int ret;
> >>>>>> +
> >>>>>> +	if (len > 4)
> >>>>>> +		return -EINVAL;
> >>>>>> +
> >>>>>> +	msgs[0].addr = client->addr;
> >>>>>> +	msgs[0].flags = 0;
> >>>>>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
> >>>>>> +	msgs[0].buf = addr_buf;
> >>>>>> +
> >>>>>> +	msgs[1].addr = client->addr;
> >>>>>> +	msgs[1].flags = I2C_M_RD;
> >>>>>> +	msgs[1].len = len;
> >>>>>> +	msgs[1].buf = &data_buf[4 - len];
> >>>>>> +
> >>>>>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> >>>>>> +	if (ret != ARRAY_SIZE(msgs)) {
> >>>>>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
> >>>>>> +		return -EIO;
> >>>>>> +	}
> >>>>>> +
> >>>>>> +	*val = get_unaligned_be32(data_buf);
> >>>>>> +
> >>>>>> +	return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
> >>>>>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
> >>>>>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
> >>>>>> +
> >>>>>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
> >>>>>> +				   unsigned int len, u32 val)
> >>>>>> +{
> >>>>>> +	u8 buf[6];
> >>>>>> +	int ret;
> >>>>>> +
> >>>>>> +	if (len > 4)
> >>>>>> +		return -EINVAL;
> >>>>>> +
> >>>>>> +	put_unaligned_be16(reg, buf);
> >>>>>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> >>>>>> +	ret = i2c_master_send(client, buf, len + 2);
> >>>>>> +	if (ret != len + 2) {
> >>>>>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
> >>>>>> +		return -EIO;
> >>>>>> +	}
> >>>>>> +
> >>>>>> +	return 0;
> >>>>>> +}
> >>>>>> +
> >>>>>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
> >>>>>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
> >>>>>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
> >>>>>> +
> >>>>>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
> >>>>>> +{
> >>>>>> +	u32 readval;
> >>>>>> +	int ret;
> >>>>>> +
> >>>>>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
> >>>>>> +	if (ret < 0)
> >>>>>> +		return ret;
> >>>>>> +
> >>>>>> +	readval &= ~mask;
> >>>>>> +	val &= mask;
> >>>>>> +	val |= readval;
> >>>>>> +
> >>>>>> +	return ovxxxx_write_reg8(client, reg, val);
> >>>>>> +}
> >>>>>> +
> >>>>>> +#endif

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:09               ` Laurent Pinchart
@ 2023-02-10 12:17                 ` Sakari Ailus
  2023-02-10 12:59                   ` Hans de Goede
  2023-02-10 12:47                 ` Hans de Goede
  1 sibling, 1 reply; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 12:17 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On Fri, Feb 10, 2023 at 02:09:02PM +0200, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Fri, Feb 10, 2023 at 12:56:45PM +0100, Hans de Goede wrote:
> > On 2/10/23 12:45, Laurent Pinchart wrote:
> > > On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
> > >> On 2/9/23 17:11, Laurent Pinchart wrote:
> > >>> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
> > >>>> On 2/8/23 10:52, Laurent Pinchart wrote:
> > >>>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
> > >>>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
> > >>>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
> > >>>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
> > >>>>>>
> > >>>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
> > >>>>>> use register access helpers with the following function prototypes:
> > >>>>>>
> > >>>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >>>>>>                     unsigned int len, u32 *val);
> > >>>>>>
> > >>>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
> > >>>>>>                      unsigned int len, u32 val);
> > >>>>>>
> > >>>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
> > >>>>>> a 16 bit register address in big-endian format and which have 1-3 byte
> > >>>>>> wide registers, in big-endian format (for the higher width registers).
> > >>>>>>
> > >>>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
> > >>>>>> versions of these register access helpers, so that this code duplication
> > >>>>>> can be removed.
> > >>>>>
> > >>>>> Any reason to hand-roll those instead of using regmap ?
> > >>>>
> > >>>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
> > >>>> appears to not handle, a regmap has a single regmap_config struct
> > >>>> with a single "@reg_bits: Number of bits in a register address, mandatory",
> > >>>> so we would still need wrappers around regmap, at which point it
> > >>>> really offers us very little.
> > >>>
> > >>> We could extend regmap too, although that may be too much yak shaving.
> > >>> It would be nice, but I won't push hard for it.
> > >>>
> > >>>> Also I'm moving duplicate code present in many of the
> > >>>> drivers/media/i2c/ov*.c files into a common header to remove
> > >>>> duplicate code. The handrolling was already there before :)
> > >>>>
> > >>>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
> > >>>> offer something which is as much of a drop-in replacement of the
> > >>>> current handrolled code as possible (usable with just a few
> > >>>> search-n-replaces) as possible.
> > >>>>
> > >>>> Basically my idea here was to factor out code which I noticed was
> > >>>> being repeated over and over again. My goal was not to completely
> > >>>> redo how register accesses are done in these drivers.
> > >>>>
> > >>>> I realize I have not yet converted any other drivers, that is because
> > >>>> I don't really have a way to test most of the other drivers. OTOH
> > >>>> with the current helpers most conversions should be fairly simply
> > >>>> and remove a nice amount of code. So maybe I should just only compile
> > >>>> test the conversions ?
> > >>>
> > >>> Before you spend time converting drivers, I'd like to complete the
> > >>> discussion regarding the design of those helpers. I'd rather avoid
> > >>> mass-patching drivers now and doing it again in the next kernel release.
> > >>
> > >> I completely agree.
> > >>
> > >>> Sakari mentioned CCI (part of the CSI-2 specification). I think that
> > >>> would be a good name to replace ov* here, as none of this is specific to
> > >>> OmniVision.
> > >>
> > >> I did not realize this was CCI I agree renaming the helpers makes sense.
> > >>
> > >> I see there still is a lot of discussion going on.
> > > 
> > > I haven't seen any disagreement regarding the cci prefix, so let's go
> > > for that. I'd propose cci_read() and cci_write().
> > > 
> > > Sakari, you and I would prefer layering this on top of regmap, while
> > > Andy proposed extending the regmap API. Let's see if we reach an
> > > anonymous agreement on this.
> > > 
> > > Regarding the width-specific versions of the helpers, I really think
> > > encoding the size in the register macros is the best option. It makes
> > > life easier for driver authors (only one function to call, no need to
> > > think about the register width to pick the appropriate function in each
> > > call) and reviewers (same reason), without any drawback in my opinion.
> > > 
> > > Another feature I'd like in these helpers is improved error handling. In
> > > quite a few sensor drivers I've written, I've implemented the write
> > > function as
> > > 
> > > int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
> > > {
> > > 	...
> > > 	int ret;
> > > 
> > > 	if (err && *err)
> > > 		return *err;
> > > 
> > > 	ret = real_write(...);
> > > 	if (ret < 0) {
> > > 		dev_err(...);
> > > 		if (err)
> > > 			*err = ret;
> > > 	}
> > > 
> > > 	return ret;
> > > }
> > > 
> > > This allows callers to write
> > > 
> > > 	int ret = 0;
> > > 
> > > 	foo_write(foo, REG_A, 0, &ret);
> > > 	foo_write(foo, REG_B, 1, &ret);
> > > 	foo_write(foo, REG_C, 2, &ret);
> > > 	foo_write(foo, REG_D, 3, &ret);
> > > 
> > > 	return ret;
> > > 
> > > which massively simplifies error handling. I'd like the CCI write helper
> > > to implement such a pattern.
> > 
> > Interesting, I see that the passing of the err return pointer is optional,
> > so we can still just do a search replace in existing code setting that
> > to just NULL.
> 
> And if someone dislikes having to pass NULL for the last argument, we
> could use some macro magic to accept both the 3 arguments and 4
> arguments variants.
> 
> int __cci_write3(struct cci *cci, u32 reg, u32 val);
> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
> 
> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)

This would be nice, yes.

Who will now write the patches for this? :-)

-- 
Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:45           ` Laurent Pinchart
  2023-02-10 11:56             ` Hans de Goede
@ 2023-02-10 12:26             ` Sakari Ailus
  2023-02-10 15:42               ` Andy Shevchenko
  2023-02-10 16:40               ` Laurent Pinchart
  1 sibling, 2 replies; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 12:26 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent,

On Fri, Feb 10, 2023 at 01:45:10PM +0200, Laurent Pinchart wrote:
> Regarding the width-specific versions of the helpers, I really think
> encoding the size in the register macros is the best option. It makes
> life easier for driver authors (only one function to call, no need to
> think about the register width to pick the appropriate function in each
> call) and reviewers (same reason), without any drawback in my opinion.

As I noted previously, this works well for drivers that need to access
registers with multiple widths, which indeed applies to the vast majority
of camera sensor drivers, but not to e.g. flash or lens VCM drivers. Fixed
width registers are better served with a width-specific function. But these
can be always added later on.

-- 
Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:09               ` Laurent Pinchart
  2023-02-10 12:17                 ` Sakari Ailus
@ 2023-02-10 12:47                 ` Hans de Goede
  2023-02-10 13:18                   ` Sakari Ailus
  1 sibling, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 12:47 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Sakari Ailus, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi,

On 2/10/23 13:09, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Fri, Feb 10, 2023 at 12:56:45PM +0100, Hans de Goede wrote:
>> On 2/10/23 12:45, Laurent Pinchart wrote:
>>> On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
>>>> On 2/9/23 17:11, Laurent Pinchart wrote:
>>>>> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
>>>>>> On 2/8/23 10:52, Laurent Pinchart wrote:
>>>>>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>>>>>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>>>>>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>>>>>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>>>>>>>
>>>>>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>>>>>>>> use register access helpers with the following function prototypes:
>>>>>>>>
>>>>>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>>>                     unsigned int len, u32 *val);
>>>>>>>>
>>>>>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>>>                      unsigned int len, u32 val);
>>>>>>>>
>>>>>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>>>>>>>> a 16 bit register address in big-endian format and which have 1-3 byte
>>>>>>>> wide registers, in big-endian format (for the higher width registers).
>>>>>>>>
>>>>>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>>>>>>>> versions of these register access helpers, so that this code duplication
>>>>>>>> can be removed.
>>>>>>>
>>>>>>> Any reason to hand-roll those instead of using regmap ?
>>>>>>
>>>>>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
>>>>>> appears to not handle, a regmap has a single regmap_config struct
>>>>>> with a single "@reg_bits: Number of bits in a register address, mandatory",
>>>>>> so we would still need wrappers around regmap, at which point it
>>>>>> really offers us very little.
>>>>>
>>>>> We could extend regmap too, although that may be too much yak shaving.
>>>>> It would be nice, but I won't push hard for it.
>>>>>
>>>>>> Also I'm moving duplicate code present in many of the
>>>>>> drivers/media/i2c/ov*.c files into a common header to remove
>>>>>> duplicate code. The handrolling was already there before :)
>>>>>>
>>>>>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
>>>>>> offer something which is as much of a drop-in replacement of the
>>>>>> current handrolled code as possible (usable with just a few
>>>>>> search-n-replaces) as possible.
>>>>>>
>>>>>> Basically my idea here was to factor out code which I noticed was
>>>>>> being repeated over and over again. My goal was not to completely
>>>>>> redo how register accesses are done in these drivers.
>>>>>>
>>>>>> I realize I have not yet converted any other drivers, that is because
>>>>>> I don't really have a way to test most of the other drivers. OTOH
>>>>>> with the current helpers most conversions should be fairly simply
>>>>>> and remove a nice amount of code. So maybe I should just only compile
>>>>>> test the conversions ?
>>>>>
>>>>> Before you spend time converting drivers, I'd like to complete the
>>>>> discussion regarding the design of those helpers. I'd rather avoid
>>>>> mass-patching drivers now and doing it again in the next kernel release.
>>>>
>>>> I completely agree.
>>>>
>>>>> Sakari mentioned CCI (part of the CSI-2 specification). I think that
>>>>> would be a good name to replace ov* here, as none of this is specific to
>>>>> OmniVision.
>>>>
>>>> I did not realize this was CCI I agree renaming the helpers makes sense.
>>>>
>>>> I see there still is a lot of discussion going on.
>>>
>>> I haven't seen any disagreement regarding the cci prefix, so let's go
>>> for that. I'd propose cci_read() and cci_write().
>>>
>>> Sakari, you and I would prefer layering this on top of regmap, while
>>> Andy proposed extending the regmap API. Let's see if we reach an
>>> anonymous agreement on this.
>>>
>>> Regarding the width-specific versions of the helpers, I really think
>>> encoding the size in the register macros is the best option. It makes
>>> life easier for driver authors (only one function to call, no need to
>>> think about the register width to pick the appropriate function in each
>>> call) and reviewers (same reason), without any drawback in my opinion.
>>>
>>> Another feature I'd like in these helpers is improved error handling. In
>>> quite a few sensor drivers I've written, I've implemented the write
>>> function as
>>>
>>> int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
>>> {
>>> 	...
>>> 	int ret;
>>>
>>> 	if (err && *err)
>>> 		return *err;
>>>
>>> 	ret = real_write(...);
>>> 	if (ret < 0) {
>>> 		dev_err(...);
>>> 		if (err)
>>> 			*err = ret;
>>> 	}
>>>
>>> 	return ret;
>>> }
>>>
>>> This allows callers to write
>>>
>>> 	int ret = 0;
>>>
>>> 	foo_write(foo, REG_A, 0, &ret);
>>> 	foo_write(foo, REG_B, 1, &ret);
>>> 	foo_write(foo, REG_C, 2, &ret);
>>> 	foo_write(foo, REG_D, 3, &ret);
>>>
>>> 	return ret;
>>>
>>> which massively simplifies error handling. I'd like the CCI write helper
>>> to implement such a pattern.
>>
>> Interesting, I see that the passing of the err return pointer is optional,
>> so we can still just do a search replace in existing code setting that
>> to just NULL.
> 
> And if someone dislikes having to pass NULL for the last argument, we
> could use some macro magic to accept both the 3 arguments and 4
> arguments variants.
> 
> int __cci_write3(struct cci *cci, u32 reg, u32 val);
> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
> 
> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)

TBH this just feels like code obfuscation to me and it is also going
to write havoc with various smarted code-editors / IDEs which give
proptype info to the user while typing the function name.

Having the extra ", NULL" there in calls which don't use / need
the *err thingie really is not a big deal IMHO.

Regards,

Hans



>>>>>>> Also, may I
>>>>>>> suggest to have a look at drivers/media/i2c/imx290.c for an example of
>>>>>>> how registers of different sizes can be handled in a less error-prone
>>>>>>> way, using single read/write functions that adapt to the size
>>>>>>> automatically ?
>>>>>>
>>>>>> Yes I have seen this pattern in drivers/media/i2c/ov5693.c too
>>>>>> (at least I assume it is the same pattern you are talking about).
>>>>>
>>>>> Correct. Can we use something like that to merge all the ov*_write_reg()
>>>>> variants into a single function ? Having to select the size manually in
>>>>> each call (either by picking the function variant, or by passing a size
>>>>> as a function parameter) is error-prone. Encoding the size in the
>>>>> register macro is much safer, easing both development and review.
>>>>>
>>>>>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>>>>> ---
>>>>>>>>  include/media/ovxxxx_16bit_addr_reg_helpers.h | 93 +++++++++++++++++++
>>>>>>>>  1 file changed, 93 insertions(+)
>>>>>>>>  create mode 100644 include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>>>>
>>>>>>>> diff --git a/include/media/ovxxxx_16bit_addr_reg_helpers.h b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>>>> new file mode 100644
>>>>>>>> index 000000000000..e2ffee3d797a
>>>>>>>> --- /dev/null
>>>>>>>> +++ b/include/media/ovxxxx_16bit_addr_reg_helpers.h
>>>>>>>> @@ -0,0 +1,93 @@
>>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>>> +/*
>>>>>>>> + * I2C register access helpers for Omnivision OVxxxx image sensors which expect
>>>>>>>> + * a 16 bit register address in big-endian format and which have 1-3 byte
>>>>>>>> + * wide registers, in big-endian format (for the higher width registers).
>>>>>>>> + *
>>>>>>>> + * Based on the register helpers from drivers/media/i2c/ov2680.c which is:
>>>>>>>> + * Copyright (C) 2018 Linaro Ltd
>>>>>>>> + */
>>>>>>>> +#ifndef __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>>>>>> +#define __OVXXXX_16BIT_ADDR_REG_HELPERS_H
>>>>>>>> +
>>>>>>>> +#include <asm/unaligned.h>
>>>>>>>> +#include <linux/dev_printk.h>
>>>>>>>> +#include <linux/i2c.h>
>>>>>>>> +
>>>>>>>> +static inline int ovxxxx_read_reg(struct i2c_client *client, u16 reg,
>>>>>>>> +				  unsigned int len, u32 *val)
>>>>>>>> +{
>>>>>>>> +	struct i2c_msg msgs[2];
>>>>>>>> +	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
>>>>>>>> +	u8 data_buf[4] = { 0, };
>>>>>>>> +	int ret;
>>>>>>>> +
>>>>>>>> +	if (len > 4)
>>>>>>>> +		return -EINVAL;
>>>>>>>> +
>>>>>>>> +	msgs[0].addr = client->addr;
>>>>>>>> +	msgs[0].flags = 0;
>>>>>>>> +	msgs[0].len = ARRAY_SIZE(addr_buf);
>>>>>>>> +	msgs[0].buf = addr_buf;
>>>>>>>> +
>>>>>>>> +	msgs[1].addr = client->addr;
>>>>>>>> +	msgs[1].flags = I2C_M_RD;
>>>>>>>> +	msgs[1].len = len;
>>>>>>>> +	msgs[1].buf = &data_buf[4 - len];
>>>>>>>> +
>>>>>>>> +	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
>>>>>>>> +	if (ret != ARRAY_SIZE(msgs)) {
>>>>>>>> +		dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret);
>>>>>>>> +		return -EIO;
>>>>>>>> +	}
>>>>>>>> +
>>>>>>>> +	*val = get_unaligned_be32(data_buf);
>>>>>>>> +
>>>>>>>> +	return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +#define ovxxxx_read_reg8(s, r, v)	ovxxxx_read_reg(s, r, 1, v)
>>>>>>>> +#define ovxxxx_read_reg16(s, r, v)	ovxxxx_read_reg(s, r, 2, v)
>>>>>>>> +#define ovxxxx_read_reg24(s, r, v)	ovxxxx_read_reg(s, r, 3, v)
>>>>>>>> +
>>>>>>>> +static inline int ovxxxx_write_reg(struct i2c_client *client, u16 reg,
>>>>>>>> +				   unsigned int len, u32 val)
>>>>>>>> +{
>>>>>>>> +	u8 buf[6];
>>>>>>>> +	int ret;
>>>>>>>> +
>>>>>>>> +	if (len > 4)
>>>>>>>> +		return -EINVAL;
>>>>>>>> +
>>>>>>>> +	put_unaligned_be16(reg, buf);
>>>>>>>> +	put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
>>>>>>>> +	ret = i2c_master_send(client, buf, len + 2);
>>>>>>>> +	if (ret != len + 2) {
>>>>>>>> +		dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret);
>>>>>>>> +		return -EIO;
>>>>>>>> +	}
>>>>>>>> +
>>>>>>>> +	return 0;
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +#define ovxxxx_write_reg8(s, r, v)	ovxxxx_write_reg(s, r, 1, v)
>>>>>>>> +#define ovxxxx_write_reg16(s, r, v)	ovxxxx_write_reg(s, r, 2, v)
>>>>>>>> +#define ovxxxx_write_reg24(s, r, v)	ovxxxx_write_reg(s, r, 3, v)
>>>>>>>> +
>>>>>>>> +static inline int ovxxxx_mod_reg(struct i2c_client *client, u16 reg, u8 mask, u8 val)
>>>>>>>> +{
>>>>>>>> +	u32 readval;
>>>>>>>> +	int ret;
>>>>>>>> +
>>>>>>>> +	ret = ovxxxx_read_reg8(client, reg, &readval);
>>>>>>>> +	if (ret < 0)
>>>>>>>> +		return ret;
>>>>>>>> +
>>>>>>>> +	readval &= ~mask;
>>>>>>>> +	val &= mask;
>>>>>>>> +	val |= readval;
>>>>>>>> +
>>>>>>>> +	return ovxxxx_write_reg8(client, reg, val);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +#endif
> 


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:17                 ` Sakari Ailus
@ 2023-02-10 12:59                   ` Hans de Goede
  2023-02-10 13:31                     ` Sakari Ailus
  0 siblings, 1 reply; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 12:59 UTC (permalink / raw)
  To: Sakari Ailus, Laurent Pinchart
  Cc: Mauro Carvalho Chehab, Tsuchiya Yuto, Andy Shevchenko,
	Yury Luneff, Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi,

On 2/10/23 13:17, Sakari Ailus wrote:
> Hi Laurent,
> 
> On Fri, Feb 10, 2023 at 02:09:02PM +0200, Laurent Pinchart wrote:
>> Hi Hans,
>>
>> On Fri, Feb 10, 2023 at 12:56:45PM +0100, Hans de Goede wrote:
>>> On 2/10/23 12:45, Laurent Pinchart wrote:
>>>> On Fri, Feb 10, 2023 at 12:20:36PM +0100, Hans de Goede wrote:
>>>>> On 2/9/23 17:11, Laurent Pinchart wrote:
>>>>>> On Thu, Feb 09, 2023 at 04:03:22PM +0100, Hans de Goede wrote:
>>>>>>> On 2/8/23 10:52, Laurent Pinchart wrote:
>>>>>>>> On Mon, Jan 23, 2023 at 01:51:36PM +0100, Hans de Goede wrote:
>>>>>>>>> The following drivers under drivers/media/i2c: ov08x40.c, ov13858.c,
>>>>>>>>> ov13b10.c, ov2680.c, ov2685.c, ov2740.c, ov4689.c, ov5670.c,
>>>>>>>>> ov5675.c, ov5695.c, ov8856.c, ov9282.c and ov9734.c,
>>>>>>>>>
>>>>>>>>> as well as various "atomisp" sensor drivers in drivers/staging, *all*
>>>>>>>>> use register access helpers with the following function prototypes:
>>>>>>>>>
>>>>>>>>> int ovxxxx_read_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>>>>                     unsigned int len, u32 *val);
>>>>>>>>>
>>>>>>>>> int ovxxxx_write_reg(struct ovxxxx_dev *sensor, u16 reg,
>>>>>>>>>                      unsigned int len, u32 val);
>>>>>>>>>
>>>>>>>>> To read/write registers on Omnivision OVxxxx image sensors wich expect
>>>>>>>>> a 16 bit register address in big-endian format and which have 1-3 byte
>>>>>>>>> wide registers, in big-endian format (for the higher width registers).
>>>>>>>>>
>>>>>>>>> Add a new ovxxxx_16bit_addr_reg_helpers.h header file with static inline
>>>>>>>>> versions of these register access helpers, so that this code duplication
>>>>>>>>> can be removed.
>>>>>>>>
>>>>>>>> Any reason to hand-roll those instead of using regmap ?
>>>>>>>
>>>>>>> These devices have a mix of 8 + 16 + 24 bit registers which regmap
>>>>>>> appears to not handle, a regmap has a single regmap_config struct
>>>>>>> with a single "@reg_bits: Number of bits in a register address, mandatory",
>>>>>>> so we would still need wrappers around regmap, at which point it
>>>>>>> really offers us very little.
>>>>>>
>>>>>> We could extend regmap too, although that may be too much yak shaving.
>>>>>> It would be nice, but I won't push hard for it.
>>>>>>
>>>>>>> Also I'm moving duplicate code present in many of the
>>>>>>> drivers/media/i2c/ov*.c files into a common header to remove
>>>>>>> duplicate code. The handrolling was already there before :)
>>>>>>>
>>>>>>> My goal with the new ovxxxx_16bit_addr_reg_helpers.h file was to
>>>>>>> offer something which is as much of a drop-in replacement of the
>>>>>>> current handrolled code as possible (usable with just a few
>>>>>>> search-n-replaces) as possible.
>>>>>>>
>>>>>>> Basically my idea here was to factor out code which I noticed was
>>>>>>> being repeated over and over again. My goal was not to completely
>>>>>>> redo how register accesses are done in these drivers.
>>>>>>>
>>>>>>> I realize I have not yet converted any other drivers, that is because
>>>>>>> I don't really have a way to test most of the other drivers. OTOH
>>>>>>> with the current helpers most conversions should be fairly simply
>>>>>>> and remove a nice amount of code. So maybe I should just only compile
>>>>>>> test the conversions ?
>>>>>>
>>>>>> Before you spend time converting drivers, I'd like to complete the
>>>>>> discussion regarding the design of those helpers. I'd rather avoid
>>>>>> mass-patching drivers now and doing it again in the next kernel release.
>>>>>
>>>>> I completely agree.
>>>>>
>>>>>> Sakari mentioned CCI (part of the CSI-2 specification). I think that
>>>>>> would be a good name to replace ov* here, as none of this is specific to
>>>>>> OmniVision.
>>>>>
>>>>> I did not realize this was CCI I agree renaming the helpers makes sense.
>>>>>
>>>>> I see there still is a lot of discussion going on.
>>>>
>>>> I haven't seen any disagreement regarding the cci prefix, so let's go
>>>> for that. I'd propose cci_read() and cci_write().
>>>>
>>>> Sakari, you and I would prefer layering this on top of regmap, while
>>>> Andy proposed extending the regmap API. Let's see if we reach an
>>>> anonymous agreement on this.
>>>>
>>>> Regarding the width-specific versions of the helpers, I really think
>>>> encoding the size in the register macros is the best option. It makes
>>>> life easier for driver authors (only one function to call, no need to
>>>> think about the register width to pick the appropriate function in each
>>>> call) and reviewers (same reason), without any drawback in my opinion.
>>>>
>>>> Another feature I'd like in these helpers is improved error handling. In
>>>> quite a few sensor drivers I've written, I've implemented the write
>>>> function as
>>>>
>>>> int foo_write(struct foo *foo, u32 reg, u32 val, int *err)
>>>> {
>>>> 	...
>>>> 	int ret;
>>>>
>>>> 	if (err && *err)
>>>> 		return *err;
>>>>
>>>> 	ret = real_write(...);
>>>> 	if (ret < 0) {
>>>> 		dev_err(...);
>>>> 		if (err)
>>>> 			*err = ret;
>>>> 	}
>>>>
>>>> 	return ret;
>>>> }
>>>>
>>>> This allows callers to write
>>>>
>>>> 	int ret = 0;
>>>>
>>>> 	foo_write(foo, REG_A, 0, &ret);
>>>> 	foo_write(foo, REG_B, 1, &ret);
>>>> 	foo_write(foo, REG_C, 2, &ret);
>>>> 	foo_write(foo, REG_D, 3, &ret);
>>>>
>>>> 	return ret;
>>>>
>>>> which massively simplifies error handling. I'd like the CCI write helper
>>>> to implement such a pattern.
>>>
>>> Interesting, I see that the passing of the err return pointer is optional,
>>> so we can still just do a search replace in existing code setting that
>>> to just NULL.
>>
>> And if someone dislikes having to pass NULL for the last argument, we
>> could use some macro magic to accept both the 3 arguments and 4
>> arguments variants.
>>
>> int __cci_write3(struct cci *cci, u32 reg, u32 val);
>> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
>>
>> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
>> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)
> 
> This would be nice, yes.

Disagree, see my reply directly to Laurent.

> Who will now write the patches for this? :-)

I have already more or less volunteered / I opened this can of worms,
so that would be me...

I see in your other reply that you are fine with going without
wrappers for the fixed width accesses for now, good. TBH I don't
think these will add much value.

I'll try to make some time to work on this somewhere the next
couple of weeks.

Here is a rough sketch of the API for initial discussion:

/*
 * Note cci_reg_8 deliberately is 0, not 1, so that raw
 * (not wrapped in a CCI_REG*() macro) register addresses
 * do 8 bit wide accesses. This allows unchanged use of register
 * initialization lists of raw address, value pairs which only
 * do 8 bit width accesses.
 */
enum cci_reg_type {
	cci_reg_8 = 0,
	cci_reg_16,
	cci_reg_24,
	cci_reg_32,
};

/*
 * Macros to define register address with the register width encoded
 * into the higher bits. CCI_REG8() is a no-op so its use is optional.
 */
#define CCI_REG_SIZE_SHIFT		16
#define CCI_REG_ADDR_MASK		GENMASK(15, 0)

#define CCI_REG8(x)			((cci_reg_8 << CCI_REG_SIZE_SHIFT) | (x))
#define CCI_REG16(x)			((cci_reg_16 << CCI_REG_SIZE_SHIFT) | (x))
#define CCI_REG24(x)			((cci_reg_24 << CCI_REG_SIZE_SHIFT) | (x))
#define CCI_REG32(x)			((cci_reg_32 << CCI_REG_SIZE_SHIFT) | (x))

int cci_read(struct regmap *regmap, u32 reg, u32 *val, int *err);
int cci_write(struct regmap *regmap, u32 reg, u32 val, int *err);
int cci_update_bits(struct regmap *map, u32 reg, u32 mask, u32 val, int *err);
int cci_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, int num_regs, int *err);

Note the regmap here is intended to be a regmap with 16 bit register-address
width and 8 bit register-data width. I'll add a helper to get the regmap
from an i2c_client to the initial implementation.

Also note that all the function names have been chosen to be 1:1 mirrors
of the matching regmap functions with the addition of the *err argument.

Regards,

Hans



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:47                 ` Hans de Goede
@ 2023-02-10 13:18                   ` Sakari Ailus
  2023-02-10 14:43                     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 13:18 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurent Pinchart, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 01:47:49PM +0100, Hans de Goede wrote:
> > And if someone dislikes having to pass NULL for the last argument, we
> > could use some macro magic to accept both the 3 arguments and 4
> > arguments variants.
> > 
> > int __cci_write3(struct cci *cci, u32 reg, u32 val);
> > int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
> > 
> > #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
> > #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)
> 
> TBH this just feels like code obfuscation to me and it is also going
> to write havoc with various smarted code-editors / IDEs which give
> proptype info to the user while typing the function name.
> 
> Having the extra ", NULL" there in calls which don't use / need
> the *err thingie really is not a big deal IMHO.

It's still an eyesore if the driver doesn't use that pattern of register
access error handling. I also prioritise source code itself rather than try
to make it fit for a particular editor (which is neither Emacs nor Vim I
suppose?).

My preference is to provide an interface that best suits a driver's needs,
whatever that is. There are just a couple of common patterns and the one above
is one of the rare ones.

-- 
Regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:59                   ` Hans de Goede
@ 2023-02-10 13:31                     ` Sakari Ailus
  0 siblings, 0 replies; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 13:31 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurent Pinchart, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 01:59:07PM +0100, Hans de Goede wrote:
> > Who will now write the patches for this? :-)
> 
> I have already more or less volunteered / I opened this can of worms,
> so that would be me...

:-)

Thank you, this is much appreciated, and will allow factoring out ~ 50
lines of code from almost all sensor (as well as a few other) drivers.

> 
> I see in your other reply that you are fine with going without
> wrappers for the fixed width accesses for now, good. TBH I don't
> think these will add much value.

We can get back to this topic when converting drivers. These are
convenience wrappers after all and they're easy to add if needed, there's
no connection to the underlying implementation which is the important part.

> 
> I'll try to make some time to work on this somewhere the next
> couple of weeks.
> 
> Here is a rough sketch of the API for initial discussion:
> 
> /*
>  * Note cci_reg_8 deliberately is 0, not 1, so that raw
>  * (not wrapped in a CCI_REG*() macro) register addresses
>  * do 8 bit wide accesses. This allows unchanged use of register
>  * initialization lists of raw address, value pairs which only
>  * do 8 bit width accesses.
>  */
> enum cci_reg_type {
> 	cci_reg_8 = 0,
> 	cci_reg_16,
> 	cci_reg_24,
> 	cci_reg_32,

I'd use capital letters for these as they are macro-like. Or define them as
macros.

> };
> 
> /*
>  * Macros to define register address with the register width encoded
>  * into the higher bits. CCI_REG8() is a no-op so its use is optional.
>  */
> #define CCI_REG_SIZE_SHIFT		16
> #define CCI_REG_ADDR_MASK		GENMASK(15, 0)
> 
> #define CCI_REG8(x)			((cci_reg_8 << CCI_REG_SIZE_SHIFT) | (x))
> #define CCI_REG16(x)			((cci_reg_16 << CCI_REG_SIZE_SHIFT) | (x))
> #define CCI_REG24(x)			((cci_reg_24 << CCI_REG_SIZE_SHIFT) | (x))
> #define CCI_REG32(x)			((cci_reg_32 << CCI_REG_SIZE_SHIFT) | (x))

The top 8 bits could be used for flags in the future, for driver's use.
The CCS driver stores register's properties (value format) there.

> 
> int cci_read(struct regmap *regmap, u32 reg, u32 *val, int *err);
> int cci_write(struct regmap *regmap, u32 reg, u32 val, int *err);
> int cci_update_bits(struct regmap *map, u32 reg, u32 mask, u32 val, int *err);
> int cci_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, int num_regs, int *err);

We should also have a bulk data write function, although drivers could use
regmap directly to do this. Not needed now, nor this is a common need. Just
a note.

> 
> Note the regmap here is intended to be a regmap with 16 bit register-address
> width and 8 bit register-data width. I'll add a helper to get the regmap
> from an i2c_client to the initial implementation.

CCI also supports 8-bit register addresses (virtually all lens VCM and
flash drivers as well as some sensor drivers) so this should be a
parameter.

I expect some drivers to support CCI via both I²C and I3C. We don't need
I3C now as all sensors are I²C, but I²C should be visible in the API only
when it's about making the connection to an I²C client.

> 
> Also note that all the function names have been chosen to be 1:1 mirrors
> of the matching regmap functions with the addition of the *err argument.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 13:18                   ` Sakari Ailus
@ 2023-02-10 14:43                     ` Hans de Goede
  2023-02-10 16:43                       ` Laurent Pinchart
  2023-02-10 20:16                       ` Sakari Ailus
  0 siblings, 2 replies; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 14:43 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Laurent Pinchart, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi,

On 2/10/23 14:18, Sakari Ailus wrote:
> Hi Hans,
> 
> On Fri, Feb 10, 2023 at 01:47:49PM +0100, Hans de Goede wrote:
>>> And if someone dislikes having to pass NULL for the last argument, we
>>> could use some macro magic to accept both the 3 arguments and 4
>>> arguments variants.
>>>
>>> int __cci_write3(struct cci *cci, u32 reg, u32 val);
>>> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
>>>
>>> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
>>> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)
>>
>> TBH this just feels like code obfuscation to me and it is also going
>> to write havoc with various smarted code-editors / IDEs which give
>> proptype info to the user while typing the function name.
>>
>> Having the extra ", NULL" there in calls which don't use / need
>> the *err thingie really is not a big deal IMHO.
> 
> It's still an eyesore if the driver doesn't use that pattern of register
> access error handling. I also prioritise source code itself rather than try
> to make it fit for a particular editor (which is neither Emacs nor Vim I
> suppose?).

vim and emacs also both have support for showing function prototypes,
but this is not only about breaking tooling like that.

My main objection is not that it confuses various tooling, it also confuses
me as a human if I'm trying to figure out what is going on. The kernel's
internal API documentation generally isn't great so I'm used to just look
at a functions implementation as an alternative. These sort of dark-magic
pre-compiler macros make it very hard for me *as a human* to figure out
what is going on.

So to me personally this level of code-obfuscation just to avoid 6 chars
", NULL" per function calls is very much not worth the making things
harder to understand level it adds.

I mean this will even allow mixing the 3 and 4 parameter variants
in a single .c file! That is just very very confusing and anti KISS.

Who knows maybe iso-c2023 or whatever will give us default function
arguments values? That would be a nice way to do this, the above
not so much IMHO.

So I won't be adding this per-processor (dark) magic to my patch-set
for this.

If people really want this they can add this in a follow-up patch-set.

Regards,

Hans


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 11:05                 ` Laurent Pinchart
@ 2023-02-10 15:35                   ` Andy Shevchenko
  2023-02-10 16:01                     ` Hans de Goede
  0 siblings, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-10 15:35 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Sakari Ailus, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 01:05:52PM +0200, Laurent Pinchart wrote:
> On Fri, Feb 10, 2023 at 12:53:43PM +0200, Andy Shevchenko wrote:
> > On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
> > > On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
> > > > On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
> > > > > On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:

...

> > > > > I took a look at this some time ago, too, and current regmap API is a poor
> > > > > fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
> > > > > on top of regmap is a better approach indeed.
> > > > 
> > > > I'm confused, is regmap a poor fit, or a better approach ?
> > > 
> > > I'm proposing having something on top of regmap, but not changing regmap
> > > itself.
> > 
> > I don't understand why we can't change regmap? regmap has a facility called
> > regmap bus which we can provide specifically for these types of devices. What's
> > wrong to see it done?
> 
> How would that work ?

If I'm not mistaken, you may introduce something like regmal CCI and then

	regmap_init_cci();


	regmap_read()/regmap_write()
	regmap_update_bits()
	regmap_bulk_*()

at your service without changing a bit in the drivers (they will use plain
regmap APIs instead of custom ones).

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:26             ` Sakari Ailus
@ 2023-02-10 15:42               ` Andy Shevchenko
  2023-02-10 16:39                 ` Laurent Pinchart
  2023-02-10 16:40               ` Laurent Pinchart
  1 sibling, 1 reply; 168+ messages in thread
From: Andy Shevchenko @ 2023-02-10 15:42 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 02:26:31PM +0200, Sakari Ailus wrote:
> On Fri, Feb 10, 2023 at 01:45:10PM +0200, Laurent Pinchart wrote:
> > Regarding the width-specific versions of the helpers, I really think
> > encoding the size in the register macros is the best option. It makes
> > life easier for driver authors (only one function to call, no need to
> > think about the register width to pick the appropriate function in each
> > call) and reviewers (same reason), without any drawback in my opinion.
> 
> As I noted previously, this works well for drivers that need to access
> registers with multiple widths, which indeed applies to the vast majority
> of camera sensor drivers, but not to e.g. flash or lens VCM drivers. Fixed
> width registers are better served with a width-specific function. But these
> can be always added later on.

Again, we can extend regmap to have something like

	int (*reg_width)(regmap *, offset)

callback added that will tell the regmap bus underneath what size to use.

In the driver one will define the respective method to return these widths.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 15:35                   ` Andy Shevchenko
@ 2023-02-10 16:01                     ` Hans de Goede
  0 siblings, 0 replies; 168+ messages in thread
From: Hans de Goede @ 2023-02-10 16:01 UTC (permalink / raw)
  To: Andy Shevchenko, Laurent Pinchart
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Tsuchiya Yuto, Yury Luneff,
	Nable, andrey.i.trufanov, Fabio Aiuto, linux-media,
	linux-staging

Hi Andy,

On 2/10/23 16:35, Andy Shevchenko wrote:
> On Fri, Feb 10, 2023 at 01:05:52PM +0200, Laurent Pinchart wrote:
>> On Fri, Feb 10, 2023 at 12:53:43PM +0200, Andy Shevchenko wrote:
>>> On Fri, Feb 10, 2023 at 12:47:55PM +0200, Sakari Ailus wrote:
>>>> On Fri, Feb 10, 2023 at 12:29:19PM +0200, Laurent Pinchart wrote:
>>>>> On Fri, Feb 10, 2023 at 12:21:15PM +0200, Sakari Ailus wrote:
>>>>>> On Thu, Feb 09, 2023 at 06:11:12PM +0200, Laurent Pinchart wrote:
> 
> ...
> 
>>>>>> I took a look at this some time ago, too, and current regmap API is a poor
>>>>>> fit for CCI devices. CCI works on top of e.g. both I²C and I3C so something
>>>>>> on top of regmap is a better approach indeed.
>>>>>
>>>>> I'm confused, is regmap a poor fit, or a better approach ?
>>>>
>>>> I'm proposing having something on top of regmap, but not changing regmap
>>>> itself.
>>>
>>> I don't understand why we can't change regmap? regmap has a facility called
>>> regmap bus which we can provide specifically for these types of devices. What's
>>> wrong to see it done?
>>
>> How would that work ?
> 
> If I'm not mistaken, you may introduce something like regmal CCI and then
> 
> 	regmap_init_cci();
> 
> 
> 	regmap_read()/regmap_write()
> 	regmap_update_bits()
> 	regmap_bulk_*()
> 
> at your service without changing a bit in the drivers (they will use plain
> regmap APIs instead of custom ones).

regmap_bus is for low-level busses like i2c, i3c, spi, etc.

We could "abuse" this to overwrite the standard regmap read/write helpers
with bus specific ones, but then we loose the actual bus abstraction
and we would need separate regmap-cci implementations for i2c/i3c/spi.

> Again, we can extend regmap to have something like
>
>	int (*reg_width)(regmap *, offset)
>
> callback added that will tell the regmap bus underneath what size to use.
>
> In the driver one will define the respective method to return these widths.

That won't work internal helpers to marshall raw-buffers with both reg-addr
+ reg value(s) to pass to the low-level (i2c/i3c/spi) drivers use an internal
regmap.format struct which gets filled with reg-width specific info once
from __regmap_init() what you are suggesting really requires major surgery
to the whole regmap core.

CCI really is an extra protocol layer on top of lower-level / more primitive
busses and it is best to have a helper library with a few helpers using
regmap underneath to abstract the raw bus accesses away. Note this helper
library can be quite thin and small though :)

Regards,

Hans


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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 15:42               ` Andy Shevchenko
@ 2023-02-10 16:39                 ` Laurent Pinchart
  2023-02-10 20:18                   ` Sakari Ailus
  0 siblings, 1 reply; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 16:39 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Sakari Ailus, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

On Fri, Feb 10, 2023 at 05:42:25PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 10, 2023 at 02:26:31PM +0200, Sakari Ailus wrote:
> > On Fri, Feb 10, 2023 at 01:45:10PM +0200, Laurent Pinchart wrote:
> > > Regarding the width-specific versions of the helpers, I really think
> > > encoding the size in the register macros is the best option. It makes
> > > life easier for driver authors (only one function to call, no need to
> > > think about the register width to pick the appropriate function in each
> > > call) and reviewers (same reason), without any drawback in my opinion.
> > 
> > As I noted previously, this works well for drivers that need to access
> > registers with multiple widths, which indeed applies to the vast majority
> > of camera sensor drivers, but not to e.g. flash or lens VCM drivers. Fixed
> > width registers are better served with a width-specific function. But these
> > can be always added later on.
> 
> Again, we can extend regmap to have something like
> 
> 	int (*reg_width)(regmap *, offset)
> 
> callback added that will tell the regmap bus underneath what size to use.
> 
> In the driver one will define the respective method to return these widths.

I don't think that's worth it, it would make drivers quite complex
compared to encoding the register width in the register address macros.
We're dealing with devices that have hundreds of registers of various
widths interleaved, a big switch/case for every write isn't great.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 12:26             ` Sakari Ailus
  2023-02-10 15:42               ` Andy Shevchenko
@ 2023-02-10 16:40               ` Laurent Pinchart
  1 sibling, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 16:40 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Hans de Goede, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Sakari,

On Fri, Feb 10, 2023 at 02:26:31PM +0200, Sakari Ailus wrote:
> On Fri, Feb 10, 2023 at 01:45:10PM +0200, Laurent Pinchart wrote:
> > Regarding the width-specific versions of the helpers, I really think
> > encoding the size in the register macros is the best option. It makes
> > life easier for driver authors (only one function to call, no need to
> > think about the register width to pick the appropriate function in each
> > call) and reviewers (same reason), without any drawback in my opinion.
> 
> As I noted previously, this works well for drivers that need to access
> registers with multiple widths, which indeed applies to the vast majority
> of camera sensor drivers, but not to e.g. flash or lens VCM drivers. Fixed
> width registers are better served with a width-specific function. But these
> can be always added later on.

I still fail to see why they would be *better* served by custom functions.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 14:43                     ` Hans de Goede
@ 2023-02-10 16:43                       ` Laurent Pinchart
  2023-02-10 20:16                       ` Sakari Ailus
  1 sibling, 0 replies; 168+ messages in thread
From: Laurent Pinchart @ 2023-02-10 16:43 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sakari Ailus, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 03:43:51PM +0100, Hans de Goede wrote:
> On 2/10/23 14:18, Sakari Ailus wrote:
> > On Fri, Feb 10, 2023 at 01:47:49PM +0100, Hans de Goede wrote:
> >>> And if someone dislikes having to pass NULL for the last argument, we
> >>> could use some macro magic to accept both the 3 arguments and 4
> >>> arguments variants.
> >>>
> >>> int __cci_write3(struct cci *cci, u32 reg, u32 val);
> >>> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
> >>>
> >>> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
> >>> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)
> >>
> >> TBH this just feels like code obfuscation to me and it is also going
> >> to write havoc with various smarted code-editors / IDEs which give
> >> proptype info to the user while typing the function name.
> >>
> >> Having the extra ", NULL" there in calls which don't use / need
> >> the *err thingie really is not a big deal IMHO.
> >
> > It's still an eyesore if the driver doesn't use that pattern of register
> > access error handling. I also prioritise source code itself rather than try
> > to make it fit for a particular editor (which is neither Emacs nor Vim I
> > suppose?).
> 
> vim and emacs also both have support for showing function prototypes,
> but this is not only about breaking tooling like that.
> 
> My main objection is not that it confuses various tooling, it also confuses
> me as a human if I'm trying to figure out what is going on. The kernel's
> internal API documentation generally isn't great so I'm used to just look
> at a functions implementation as an alternative. These sort of dark-magic
> pre-compiler macros make it very hard for me *as a human* to figure out
> what is going on.
> 
> So to me personally this level of code-obfuscation just to avoid 6 chars
> ", NULL" per function calls is very much not worth the making things
> harder to understand level it adds.
> 
> I mean this will even allow mixing the 3 and 4 parameter variants
> in a single .c file! That is just very very confusing and anti KISS.
> 
> Who knows maybe iso-c2023 or whatever will give us default function
> arguments values? That would be a nice way to do this, the above
> not so much IMHO.

The macro-based code I proposed is a poor man's workaround to the lack
of both default argument values and function override in plain C. It
could be nicer with dedicated language constructs for those, but that
won't change how the callers look like (you'll still be able to mix the
3 and 4 parameters variants in a single .c file), only the
implementation.

> So I won't be adding this per-processor (dark) magic to my patch-set
> for this.
> 
> If people really want this they can add this in a follow-up patch-set.

I don't mind much either way personally.

-- 
Regards,

Laurent Pinchart

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 14:43                     ` Hans de Goede
  2023-02-10 16:43                       ` Laurent Pinchart
@ 2023-02-10 20:16                       ` Sakari Ailus
  1 sibling, 0 replies; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 20:16 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Laurent Pinchart, Mauro Carvalho Chehab, Tsuchiya Yuto,
	Andy Shevchenko, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Hans,

On Fri, Feb 10, 2023 at 03:43:51PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 2/10/23 14:18, Sakari Ailus wrote:
> > Hi Hans,
> > 
> > On Fri, Feb 10, 2023 at 01:47:49PM +0100, Hans de Goede wrote:
> >>> And if someone dislikes having to pass NULL for the last argument, we
> >>> could use some macro magic to accept both the 3 arguments and 4
> >>> arguments variants.
> >>>
> >>> int __cci_write3(struct cci *cci, u32 reg, u32 val);
> >>> int __cci_write4(struct cci *cci, u32 reg, u32 val, int *err);
> >>>
> >>> #define __cci_write(_1, _2, _3, _4, NAME, ...) NAME
> >>> #define cci_write(...) __cci_write(__VA_ARGS__, __cci_write4, __cci_write3)(__VA_ARGS__)
> >>
> >> TBH this just feels like code obfuscation to me and it is also going
> >> to write havoc with various smarted code-editors / IDEs which give
> >> proptype info to the user while typing the function name.
> >>
> >> Having the extra ", NULL" there in calls which don't use / need
> >> the *err thingie really is not a big deal IMHO.
> > 
> > It's still an eyesore if the driver doesn't use that pattern of register
> > access error handling. I also prioritise source code itself rather than try
> > to make it fit for a particular editor (which is neither Emacs nor Vim I
> > suppose?).
> 
> vim and emacs also both have support for showing function prototypes,
> but this is not only about breaking tooling like that.
> 
> My main objection is not that it confuses various tooling, it also confuses
> me as a human if I'm trying to figure out what is going on. The kernel's
> internal API documentation generally isn't great so I'm used to just look
> at a functions implementation as an alternative. These sort of dark-magic
> pre-compiler macros make it very hard for me *as a human* to figure out
> what is going on.
> 
> So to me personally this level of code-obfuscation just to avoid 6 chars
> ", NULL" per function calls is very much not worth the making things
> harder to understand level it adds.
> 
> I mean this will even allow mixing the 3 and 4 parameter variants
> in a single .c file! That is just very very confusing and anti KISS.
> 
> Who knows maybe iso-c2023 or whatever will give us default function
> arguments values? That would be a nice way to do this, the above
> not so much IMHO.
> 
> So I won't be adding this per-processor (dark) magic to my patch-set
> for this.
> 
> If people really want this they can add this in a follow-up patch-set.

Your arguments are entirely reasonable, but I still prefer to have what is
a best fit for most sensor drivers.

Although this, as well as other fixed size register access helpers, can be
added later as needed. The core functionality is what interests me the most
now. Even with one function for read and another (or a few, for bulk data?)
for write is a huge improvement over the current situation IMO.

-- 
Kind regards,

Sakari Ailus

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

* Re: [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h
  2023-02-10 16:39                 ` Laurent Pinchart
@ 2023-02-10 20:18                   ` Sakari Ailus
  0 siblings, 0 replies; 168+ messages in thread
From: Sakari Ailus @ 2023-02-10 20:18 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Andy Shevchenko, Hans de Goede, Mauro Carvalho Chehab,
	Tsuchiya Yuto, Yury Luneff, Nable, andrey.i.trufanov,
	Fabio Aiuto, linux-media, linux-staging

Hi Laurent, Andy,

On Fri, Feb 10, 2023 at 06:39:11PM +0200, Laurent Pinchart wrote:
> On Fri, Feb 10, 2023 at 05:42:25PM +0200, Andy Shevchenko wrote:
> > On Fri, Feb 10, 2023 at 02:26:31PM +0200, Sakari Ailus wrote:
> > > On Fri, Feb 10, 2023 at 01:45:10PM +0200, Laurent Pinchart wrote:
> > > > Regarding the width-specific versions of the helpers, I really think
> > > > encoding the size in the register macros is the best option. It makes
> > > > life easier for driver authors (only one function to call, no need to
> > > > think about the register width to pick the appropriate function in each
> > > > call) and reviewers (same reason), without any drawback in my opinion.
> > > 
> > > As I noted previously, this works well for drivers that need to access
> > > registers with multiple widths, which indeed applies to the vast majority
> > > of camera sensor drivers, but not to e.g. flash or lens VCM drivers. Fixed
> > > width registers are better served with a width-specific function. But these
> > > can be always added later on.
> > 
> > Again, we can extend regmap to have something like
> > 
> > 	int (*reg_width)(regmap *, offset)
> > 
> > callback added that will tell the regmap bus underneath what size to use.
> > 
> > In the driver one will define the respective method to return these widths.
> 
> I don't think that's worth it, it would make drivers quite complex
> compared to encoding the register width in the register address macros.
> We're dealing with devices that have hundreds of registers of various
> widths interleaved, a big switch/case for every write isn't great.

I'd really prefer the register width information kept as close as possible
to the register address, and most probably the best way is to be part of
the same macro.

-- 
Kind regards,

Sakari Ailus

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

end of thread, other threads:[~2023-02-10 20:18 UTC | newest]

Thread overview: 168+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-23 12:51 [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Hans de Goede
2023-01-23 12:51 ` [PATCH 01/57] media: atomisp: fix videobuf2 Kconfig depenendency Hans de Goede
2023-01-23 14:12   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 02/57] media: atomisp: use vb2_start_streaming_called() Hans de Goede
2023-01-23 12:51 ` [PATCH 03/57] media: atomisp: Remove atomisp_sw_contex struct Hans de Goede
2023-01-23 14:14   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 04/57] media: atomisp: Move power-management over to a custom pm-domain Hans de Goede
2023-01-23 12:51 ` [PATCH 05/57] media: atomisp: Silence "isys dma store at addr, val" debug messages Hans de Goede
2023-01-23 14:18   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 06/57] media: atomisp: Remove non working doorbell check from punit_ddr_dvfs_enable() Hans de Goede
2023-01-23 12:51 ` [PATCH 07/57] media: atomisp: Remove useless msleep(10) before power-on on BYT Hans de Goede
2023-01-23 14:40   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 08/57] media: atomisp: Remove custom ATOMISP_IOC_ISP_MAKERNOTE ioctl Hans de Goede
2023-01-23 14:30   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 09/57] media: atomisp: Remove custom ATOMISP_IOC_G_SENSOR_MODE_DATA ioctl Hans de Goede
2023-01-23 14:31   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 10/57] media: atomisp: Remove V4L2_CID_BIN_FACTOR_HORZ/_VERT Hans de Goede
2023-01-23 14:33   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 11/57] media: atomisp: Remove no longer used binning info from sensor resolution info Hans de Goede
2023-01-23 14:33   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 12/57] media: atomisp: Propagate set_fmt() errors in queue_setup() Hans de Goede
2023-01-23 14:35   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 13/57] media: atomisp: Remove deferred firmware loading support Hans de Goede
2023-01-23 14:37   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 14/57] media: atomisp: Check buffer index is in range inside atomisp_qbuf_wrapper() Hans de Goede
2023-01-23 14:38   ` Andy Shevchenko
2023-01-24 11:09     ` Hans de Goede
2023-01-23 12:51 ` [PATCH 15/57] media: atomisp: Drop atomisp_init_pipe() Hans de Goede
2023-01-23 15:30   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 16/57] media: atomisp: Remove unnecessary memset(foo, 0, sizeof(foo)) calls Hans de Goede
2023-01-23 17:41   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 17/57] media: atomisp: Only set default_run_mode on first open of a stream/asd Hans de Goede
2023-01-23 17:42   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 18/57] media: atomisp: Do not turn off sensor when the atomisp-sub-dev does not own it Hans de Goede
2023-01-23 12:51 ` [PATCH 19/57] media: atomisp: Allow sensor drivers without a s_power callback Hans de Goede
2023-01-23 17:49   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 20/57] media: atomisp: Fix regulator registers on BYT devices with CRC PMIC Hans de Goede
2023-01-23 17:51   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 21/57] media: atomisp: Remove atomisp_gmin_find_subdev() Hans de Goede
2023-01-23 17:53   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 22/57] media: atomisp: Add atomisp_register_sensor_no_gmin() helper Hans de Goede
2023-01-23 17:55   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 23/57] media: atomisp: Fix WARN() when the vb2 start_streaming callback fails Hans de Goede
2023-01-23 17:56   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 24/57] media: atomisp: Drop ffmt local var from atomisp_set_fmt() Hans de Goede
2023-01-23 12:51 ` [PATCH 25/57] media: atomisp: Stop overriding padding w/h to 12 on BYT Hans de Goede
2023-01-23 17:59   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 26/57] media: atomisp: Put sensor ACPI devices in D3 before disable ACPI power-resources Hans de Goede
2023-01-23 12:51 ` [PATCH 27/57] media: atomisp: Remove isp_subdev_link_setup() Hans de Goede
2023-01-23 18:02   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 28/57] media: Add ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
2023-01-23 18:09   ` Andy Shevchenko
2023-01-24 11:21     ` Hans de Goede
2023-01-24 12:47       ` Andy Shevchenko
2023-01-23 18:15   ` Andy Shevchenko
2023-01-23 18:23   ` Andy Shevchenko
2023-01-24 11:25     ` Hans de Goede
2023-02-08  9:52   ` Laurent Pinchart
2023-02-08 11:27     ` Andy Shevchenko
2023-02-08 15:41       ` Laurent Pinchart
2023-02-08 15:50         ` Andy Shevchenko
2023-02-08 16:03           ` Laurent Pinchart
2023-02-08 17:31             ` Andy Shevchenko
2023-02-09 10:31               ` Laurent Pinchart
2023-02-09 15:03     ` Hans de Goede
2023-02-09 16:11       ` Laurent Pinchart
2023-02-10 10:21         ` Sakari Ailus
2023-02-10 10:29           ` Laurent Pinchart
2023-02-10 10:47             ` Sakari Ailus
2023-02-10 10:53               ` Andy Shevchenko
2023-02-10 11:05                 ` Laurent Pinchart
2023-02-10 15:35                   ` Andy Shevchenko
2023-02-10 16:01                     ` Hans de Goede
2023-02-10 11:19                 ` Hans de Goede
2023-02-10 11:35                   ` Laurent Pinchart
2023-02-10 12:01                     ` Hans de Goede
2023-02-10 11:04               ` Laurent Pinchart
2023-02-10 11:18                 ` Sakari Ailus
2023-02-10 11:34                   ` Laurent Pinchart
2023-02-10 11:20         ` Hans de Goede
2023-02-10 11:45           ` Laurent Pinchart
2023-02-10 11:56             ` Hans de Goede
2023-02-10 12:09               ` Laurent Pinchart
2023-02-10 12:17                 ` Sakari Ailus
2023-02-10 12:59                   ` Hans de Goede
2023-02-10 13:31                     ` Sakari Ailus
2023-02-10 12:47                 ` Hans de Goede
2023-02-10 13:18                   ` Sakari Ailus
2023-02-10 14:43                     ` Hans de Goede
2023-02-10 16:43                       ` Laurent Pinchart
2023-02-10 20:16                       ` Sakari Ailus
2023-02-10 12:26             ` Sakari Ailus
2023-02-10 15:42               ` Andy Shevchenko
2023-02-10 16:39                 ` Laurent Pinchart
2023-02-10 20:18                   ` Sakari Ailus
2023-02-10 16:40               ` Laurent Pinchart
2023-02-08 11:31   ` Sakari Ailus
2023-02-08 14:33     ` Mauro Carvalho Chehab
2023-02-08 15:39       ` Laurent Pinchart
2023-01-23 12:51 ` [PATCH 29/57] media: atomisp: ov2680: Use the new ovxxxx_16bit_addr_reg_helpers.h Hans de Goede
2023-01-23 18:13   ` Andy Shevchenko
2023-01-24 11:22     ` Hans de Goede
2023-01-23 12:51 ` [PATCH 30/57] media: atomisp: ov2680: Rework flip ctrls Hans de Goede
2023-01-23 18:33   ` Andy Shevchenko
2023-01-29  0:36   ` kernel test robot
2023-01-23 12:51 ` [PATCH 31/57] media: atomisp: ov2680: Drop custom ATOMISP_IOC_S_EXPOSURE support Hans de Goede
2023-01-23 18:35   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 32/57] media: atomisp: ov2680: Add exposure and gain controls Hans de Goede
2023-01-23 18:43   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 33/57] media: atomisp: ov2680: Add test pattern control Hans de Goede
2023-01-23 18:46   ` Andy Shevchenko
2023-01-24 11:27     ` Hans de Goede
2023-01-24 12:50       ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 34/57] media: atomisp: ov2680: Fix window settings and enable window for all resolutions Hans de Goede
2023-01-23 18:48   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 35/57] media: atomisp: ov2680: Make setting the modes algorithm based Hans de Goede
2023-01-24 10:37   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 36/57] media: atomisp: ov2680: Use defines for fps, lines-per-frame and skip-frames Hans de Goede
2023-01-24 10:40   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 37/57] media: atomisp: ov2680: Drop unused res member from struct ov2680_device Hans de Goede
2023-01-24 10:39   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 38/57] media: atomisp: ov2680: Fix ov2680_enum_frame_interval() Hans de Goede
2023-01-24 10:42   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 39/57] media: atomisp: ov2680: Drop v4l2_find_nearest_size() call from set_fmt() Hans de Goede
2023-01-24 10:43   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 40/57] media: atomisp: ov2680: Drop struct ov2680_resolution / ov2680_res_preview Hans de Goede
2023-01-24 10:44   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 41/57] media: atomisp: ov2680: Fix frame_size list Hans de Goede
2023-01-24 10:46   ` Andy Shevchenko
2023-01-24 11:29     ` Hans de Goede
2023-01-23 12:51 ` [PATCH 42/57] media: atomisp: ov2680: Remove unused data-types and defines from ov2680.h Hans de Goede
2023-01-24 10:46   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 43/57] media: atomisp: ov2680: Drop MAX_FMTS define Hans de Goede
2023-01-24 10:48   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 44/57] media: atomisp: ov2680: Consistently indent define values Hans de Goede
2023-01-24 10:49   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 45/57] media: atomisp: ov2680: Cleanup includes Hans de Goede
2023-01-24 10:50   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 46/57] media: atomisp: ov2680: Delay power-on till streaming is started Hans de Goede
2023-01-24 10:51   ` Andy Shevchenko
2023-01-24 11:31     ` Hans de Goede
2023-01-24 12:52       ` Andy Shevchenko
2023-01-24 13:35         ` Hans de Goede
2023-01-23 12:51 ` [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support Hans de Goede
2023-01-24 10:53   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 48/57] media: atomisp: ov2680: s/dev/sensor/ Hans de Goede
2023-01-24 10:54   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 49/57] media: atomisp: ov2680: Use devm_kzalloc() for sensor data struct Hans de Goede
2023-01-24 10:55   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 50/57] media: atomisp: ov2680: Switch over to ACPI powermanagement Hans de Goede
2023-01-24 10:59   ` Andy Shevchenko
2023-01-23 12:51 ` [PATCH 51/57] media: atomisp: ov2722: Call atomisp_gmin_remove_subdev() on probe failure Hans de Goede
2023-01-23 18:36   ` Andy Shevchenko
2023-01-23 12:52 ` [PATCH 52/57] media: atomisp: ov2722: Fix GPIO1 polarity Hans de Goede
2023-01-23 18:39   ` Andy Shevchenko
2023-01-23 18:40   ` Andy Shevchenko
2023-01-23 12:52 ` [PATCH 53/57] media: atomisp: ov2722: Don't take the input_lock for try_fmt calls Hans de Goede
2023-01-23 18:39   ` Andy Shevchenko
2023-01-23 12:52 ` [PATCH 54/57] media: atomisp: ov2722: Power on sensor from set_fmt() callback Hans de Goede
2023-01-23 18:42   ` Andy Shevchenko
2023-01-24 11:32     ` Hans de Goede
2023-01-23 12:52 ` [PATCH 55/57] media: atomisp: pci: Replace bytes macros with functions Hans de Goede
2023-01-23 12:52 ` [PATCH 56/57] media: atomisp: pci: hive_isp_css_common: host: vmem: Replace SUBWORD " Hans de Goede
2023-01-23 18:27   ` Andy Shevchenko
2023-01-23 18:29     ` Andy Shevchenko
2023-01-23 12:52 ` [PATCH 57/57] media: atomisp: pci: sh_css: Inline single invocation of macro STATS_ENABLED() Hans de Goede
2023-01-24 11:01 ` [PATCH 00/57] media: atomisp: Big power-management changes + lots of fixes Andy Shevchenko
2023-01-24 11:05   ` Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.