diff options
author | Mauro Carvalho Chehab <mchehab@kernel.org> | 2023-02-15 12:40:21 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@kernel.org> | 2023-02-15 12:40:31 +0100 |
commit | 83e0f265aa8d0e37cc8e15d318b64da0ec03ff41 (patch) | |
tree | 860a02db84f093dbdb8484eb6014008bd5219768 /drivers/staging | |
parent | 94817983fb2ccd1869ed0c5a763317a45283a272 (diff) | |
parent | 05165248df6552daaacf5621e3a5e2369117a8a9 (diff) | |
download | lwn-83e0f265aa8d0e37cc8e15d318b64da0ec03ff41.tar.gz lwn-83e0f265aa8d0e37cc8e15d318b64da0ec03ff41.zip |
Merge git://git.linuxtv.org/media_stage into media_tree
* git://git.linuxtv.org/media_stage: (216 commits)
media: v4l2-ctrls-api.c: move ctrl->is_new = 1 to the correct line
media: Revert "media: saa7146: deprecate hexium_gemini/orion, mxb and ttpci"
media: Revert "media: av7110: move to staging/media/deprecated/saa7146"
media: imx-pxp: convert to regmap
media: imx-pxp: Use non-threaded IRQ
media: imx-pxp: Introduce pxp_read() and pxp_write() wrappers
media: imx-pxp: Implement frame size enumeration
media: imx-pxp: Pass pixel format value to find_format()
media: imx-pxp: Add media controller support
media: imx-pxp: Don't set bus_info manually in .querycap()
media: imx-pxp: Sort headers alphabetically
media: imx-pxp: add support for i.MX7D
media: imx-pxp: make data_path_ctrl0 platform dependent
media: imx-pxp: disable LUT block
media: imx-pxp: explicitly disable unused blocks
media: imx-pxp: extract helper function to setup data path
media: imx-pxp: detect PXP version
media: dt-bindings: media: fsl-pxp: convert to yaml
media: imx-mipi-csis: Implement .init_cfg() using .set_fmt()
media: imx-mipi-csis: Use V4L2 subdev active state
...
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/media/Kconfig | 3 | ||||
-rw-r--r-- | drivers/staging/media/Makefile | 2 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-gc0310.c | 249 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-gc2235.c | 176 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c | 206 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-ov2680.c | 1280 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/atomisp-ov2722.c | 195 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/gc0310.h | 10 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/gc2235.h | 31 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/mt9m114.h | 15 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/ov2680.h | 836 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/ov2722.h | 36 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c | 195 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/i2c/ov5693/ov5693.h | 61 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/include/linux/atomisp.h | 50 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h | 2 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/include/linux/atomisp_platform.h | 11 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/notes.txt | 6 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_cmd.c | 90 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_cmd.h | 9 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_csi2.c | 41 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_csi2.h | 5 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_fops.c | 89 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_fops.h | 3 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c | 120 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_internal.h | 7 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 60 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_subdev.c | 171 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_subdev.h | 13 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_tpg.c | 2 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 165 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/css_2401_system/host/isys_dma_private.h | 2 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c | 20 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/sh_css.c | 7 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/sh_css_params.c | 38 | ||||
-rw-r--r-- | drivers/staging/media/av7110/Kconfig (renamed from drivers/staging/media/deprecated/saa7146/av7110/Kconfig) | 20 | ||||
-rw-r--r-- | drivers/staging/media/av7110/Makefile (renamed from drivers/staging/media/deprecated/saa7146/av7110/Makefile) | 3 | ||||
-rw-r--r-- | drivers/staging/media/av7110/TODO | 3 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-bilingual-channel-select.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-channel-select.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-clear-buffer.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-continue.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-fclose.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-fopen.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-fwrite.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-get-capabilities.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-get-status.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-pause.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-play.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-select-source.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-av-sync.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-bypass-mode.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-id.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-mixer.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-mute.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-set-streamtype.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio-stop.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio_data_types.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/audio_function_calls.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110.h) | 2 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_av.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_av.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_ca.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_ca.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_hw.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_hw.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_ipack.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_ipack.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_ir.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/av7110_v4l.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/budget-patch.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/dvb_filter.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/dvb_filter.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/sp8870.c (renamed from drivers/staging/media/deprecated/saa7146/av7110/sp8870.c) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/sp8870.h (renamed from drivers/staging/media/deprecated/saa7146/av7110/sp8870.h) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-clear-buffer.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-command.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-command.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-continue.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-fast-forward.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-fclose.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-fopen.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-freeze.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-fwrite.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-capabilities.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-event.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-frame-count.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-pts.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-size.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-get-status.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-play.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-play.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-select-source.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-set-blank.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-set-display-format.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-set-format.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-set-streamtype.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-slowmotion.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-stillpicture.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-stop.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video-try-command.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video_function_calls.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/av7110/video_types.rst (renamed from drivers/staging/media/deprecated/saa7146/av7110/video_types.rst) | 0 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/Kconfig | 5 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/Makefile | 2 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/av7110/TODO | 9 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/Kconfig | 10 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146.h | 472 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_core.c | 578 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c | 658 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c | 1046 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c | 421 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c | 498 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_video.c | 1286 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h | 266 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/Kconfig | 48 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/TODO | 7 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c | 425 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c | 496 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/saa7146/mxb.c | 873 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/Kconfig | 95 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/Makefile | 13 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/TODO | 7 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c | 1622 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c | 1574 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c | 603 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/budget.c | 883 | ||||
-rw-r--r-- | drivers/staging/media/deprecated/saa7146/ttpci/budget.h | 129 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media-csi.c | 7 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media-fim.c | 13 | ||||
-rw-r--r-- | drivers/staging/media/imx/imx-media.h | 6 | ||||
-rw-r--r-- | drivers/staging/media/meson/vdec/esparser.c | 3 | ||||
-rw-r--r-- | drivers/staging/media/omap4iss/iss_video.c | 66 |
137 files changed, 831 insertions, 15538 deletions
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index d71ee9a5d04b..bc6c7b248f86 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -22,6 +22,8 @@ if STAGING_MEDIA && MEDIA_SUPPORT # Please keep them in alphabetic order source "drivers/staging/media/atomisp/Kconfig" +source "drivers/staging/media/av7110/Kconfig" + source "drivers/staging/media/imx/Kconfig" source "drivers/staging/media/ipu3/Kconfig" @@ -52,7 +54,6 @@ menuconfig STAGING_MEDIA_DEPRECATED if STAGING_MEDIA_DEPRECATED source "drivers/staging/media/deprecated/atmel/Kconfig" -source "drivers/staging/media/deprecated/saa7146/Kconfig" endif endif diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 1a01c1af3224..1a4c3a062e3d 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/ obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ -obj-y += deprecated/saa7146/ +obj-$(CONFIG_DVB_AV7110) += av7110/ 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 diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 87a634bf9ff5..0d90683ed227 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -241,179 +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); - - *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_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_H_CROP_START_L, ®_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_V_CROP_START_L, ®_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_H_OUTSIZE_L, ®_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_V_OUTSIZE_L, ®_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_H_BLANKING_L, ®_val); - if (ret) - return ret; - hori_blanking = val | (reg_val & 0xFF); - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_SH_DELAY, ®_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, ®_val); - if (ret) - return ret; - val = (reg_val & 0xFF) << 8; - ret = gc0310_read_reg(client, GC0310_8BIT, - GC0310_V_BLANKING_L, ®_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) { @@ -596,21 +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_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; - case V4L2_CID_BIN_FACTOR_VERT: - ret = gc0310_g_bin_factor_y(&dev->sd, &ctrl->val); - break; default: ret = -EINVAL; } @@ -655,61 +467,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, - .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) @@ -952,12 +709,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 4d5a7e335f85..cb4c79b483ca 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -220,135 +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) -{ - 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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_H_CROP_START_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_V_CROP_START_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_H_OUTSIZE_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_V_OUTSIZE_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_HB_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_SH_DELAY_L, ®_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, ®_val_h); - ret = gc2235_read_reg(client, GC2235_8BIT, - GC2235_VB_L, ®_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) @@ -467,15 +338,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 +361,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) @@ -743,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 a0e8e94b2412..0e5a981dd331 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, ®_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, ®_val); - if (ret) - return ret; - buf->crop_horizontal_start = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_V_START, ®_val); - if (ret) - return ret; - buf->crop_vertical_start = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_H_END, ®_val); - if (ret) - return ret; - buf->crop_horizontal_end = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_V_END, ®_val); - if (ret) - return ret; - buf->crop_vertical_end = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_WIDTH, ®_val); - if (ret) - return ret; - buf->output_width = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_HEIGHT, ®_val); - if (ret) - return ret; - buf->output_height = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_TIMING_HTS, ®_val); - if (ret) - return ret; - buf->line_length_pck = reg_val; - - ret = mt9m114_read_reg(client, MISENSOR_16BIT, - REG_TIMING_VTS, ®_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. @@ -841,28 +745,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) { @@ -1134,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); @@ -1271,27 +1135,12 @@ 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; 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; @@ -1333,39 +1182,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = { }, { .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, .name = "exposure", .type = V4L2_CTRL_TYPE_INTEGER, @@ -1399,28 +1215,6 @@ static struct v4l2_ctrl_config mt9m114_controls[] = { }, { .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, .name = "exposure biasx", .type = V4L2_CTRL_TYPE_INTEGER, diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index fa1de45b7a2d..aeb38599fe13 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -15,30 +15,22 @@ * */ -#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/gpio/consumer.h> +#include <linux/gpio/machine.h> #include <linux/i2c.h> -#include <linux/moduleparam.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/types.h> + +#include <media/ov_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 int h_flag; -static int v_flag; static enum atomisp_bayer_order ov2680_bayer_order_mapping[] = { atomisp_bayer_order_bggr, atomisp_bayer_order_grbg, @@ -46,64 +38,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 +45,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 = ov_write_reg8(client, next->reg, next->val); if (ret) return ret; } @@ -119,518 +53,127 @@ 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) +static void ov2680_set_bayer_order(struct ov2680_device *sensor, struct v4l2_mbus_framefmt *fmt) { - /* const f number for ov2680 */ - - *val = (OV2680_F_NUMBER_DEFAULT_NUM << 16) | OV2680_F_NUMBER_DEM; - return 0; -} + 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; -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; -} + if (sensor->ctrls.vflip->val) + hv_flip += 1; -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); + if (sensor->ctrls.hflip->val) + hv_flip += 2; - dev_dbg(&client->dev, "++++ov2680_g_bin_factor_x\n"); - *val = dev->res->bin_factor_x; + fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; - return 0; + /* 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_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val) +static int ov2680_set_vflip(struct ov2680_device *sensor, 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 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, ®_val); - if (ret) - return ret; - buf->crop_horizontal_start = reg_val; - - ret = ov2680_read_reg(client, 2, - OV2680_VERTICAL_START_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_start = reg_val; - - ret = ov2680_read_reg(client, 2, - OV2680_HORIZONTAL_END_H, ®_val); - if (ret) - return ret; - buf->crop_horizontal_end = reg_val; - - ret = ov2680_read_reg(client, 2, - OV2680_VERTICAL_END_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_end = reg_val; + if (sensor->is_streaming) + return -EBUSY; - ret = ov2680_read_reg(client, 2, - OV2680_HORIZONTAL_OUTPUT_SIZE_H, ®_val); - if (ret) + ret = ov_update_reg(sensor->client, OV2680_REG_FORMAT1, BIT(2), val ? BIT(2) : 0); + if (ret < 0) return ret; - buf->output_width = reg_val; - ret = ov2680_read_reg(client, 2, - OV2680_VERTICAL_OUTPUT_SIZE_H, ®_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; + ov2680_set_bayer_order(sensor, &sensor->mode.fmt); return 0; } -static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg, - int gain, int digitgain) - +static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val) { - 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 = ov2680_write_reg(client, 1, - 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 = ov2680_write_reg(client, 2, 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 = ov2680_write_reg(client, 1, - 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); - 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); - if (ret) { - dev_err(&client->dev, "%s: write 0x%02x: error, aborted\n", - __func__, OV2680_EXPOSURE_H); - return ret; - } - - /* Analog gain */ - ret = ov2680_write_reg(client, 2, 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 = ov2680_write_reg(client, 2, - 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 = ov2680_write_reg(client, 2, - 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 = ov2680_write_reg(client, 2, - 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; - } - } + int ret; - /* End group */ - ret = ov2680_write_reg(client, 1, - OV2680_GROUP_ACCESS, 0x10); - if (ret) - return ret; + if (sensor->is_streaming) + return -EBUSY; - /* Delay launch group */ - ret = ov2680_write_reg(client, 1, - OV2680_GROUP_ACCESS, 0xa0); - if (ret) + ret = ov_update_reg(sensor->client, OV2680_REG_FORMAT2, BIT(2), val ? BIT(2) : 0); + if (ret < 0) 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; + ov2680_set_bayer_order(sensor, &sensor->mode.fmt); + return 0; } -static long ov2680_s_exposure(struct v4l2_subdev *sd, - struct atomisp_exposure *exposure) +static int ov2680_exposure_set(struct ov2680_device *sensor, u32 exp) { - 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); + return ov_write_reg24(sensor->client, OV2680_REG_EXPOSURE_PK_HIGH, exp << 4); } -static long ov2680_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain) { - switch (cmd) { - case ATOMISP_IOC_S_EXPOSURE: - return ov2680_s_exposure(sd, arg); - - default: - return -EINVAL; - } - return 0; + return ov_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain); } -/* - * 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) +static int ov2680_test_pattern_set(struct ov2680_device *sensor, int value) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - u32 reg_val; int ret; - /* get exposure */ - ret = ov2680_read_reg(client, 3, OV2680_EXPOSURE_H, ®_val); - if (ret) - return ret; - - /* Lower four bits are not part of the exposure val (always 0) */ - *value = reg_val >> 4; - return 0; -} + if (!value) + return ov_update_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), 0); -static int ov2680_v_flip(struct v4l2_subdev *sd, s32 value) -{ - 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 = ov2680_read_reg(client, 1, OV2680_FLIP_REG, &val); - if (ret) + ret = ov_update_reg(sensor->client, OV2680_REG_ISP_CTRL00, 0x03, value - 1); + if (ret < 0) return ret; - if (value) - val |= OV2680_FLIP_MIRROR_BIT_ENABLE; - else - val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE; - ret = ov2680_write_reg(client, 1, - OV2680_FLIP_REG, val); - if (ret) + ret = ov_update_reg(sensor->client, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7)); + 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; + + return 0; } -static int ov2680_h_flip(struct v4l2_subdev *sd, s32 value) +static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) { - struct camera_mipi_info *ov2680_info = NULL; - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct v4l2_subdev *sd = ctrl_to_sd(ctrl); + struct ov2680_device *sensor = to_ov2680_sensor(sd); int ret; - u32 val; - u8 index; - - dev_dbg(&client->dev, "@%s: value:%d\n", __func__, value); - - ret = ov2680_read_reg(client, 1, OV2680_MIRROR_REG, &val); - if (ret) - return ret; - if (value) - val |= OV2680_FLIP_MIRROR_BIT_ENABLE; - else - val &= ~OV2680_FLIP_MIRROR_BIT_ENABLE; - ret = ov2680_write_reg(client, 1, - 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]; + /* 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; } - return ret; -} - -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; 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; - } - return ret; -} - -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ov2680_device *dev = - container_of(ctrl->handler, struct ov2680_device, ctrl_handler); - int ret = 0; - - switch (ctrl->id) { - 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); + case V4L2_CID_EXPOSURE: + ret = ov2680_exposure_set(sensor, ctrl->val); break; - case V4L2_CID_BIN_FACTOR_HORZ: - ret = ov2680_g_bin_factor_x(&dev->sd, &ctrl->val); + case V4L2_CID_GAIN: + ret = ov2680_gain_set(sensor, ctrl->val); break; - case V4L2_CID_BIN_FACTOR_VERT: - ret = ov2680_g_bin_factor_y(&dev->sd, &ctrl->val); + case V4L2_CID_TEST_PATTERN: + ret = ov2680_test_pattern_set(sensor, ctrl->val); break; default: ret = -EINVAL; } + pm_runtime_put(sensor->sd.dev); 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_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, - .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, - .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) @@ -638,288 +181,191 @@ 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 = ov_write_reg8(client, OV2680_SW_RESET, 0x01); ret |= ov2680_write_reg_array(client, ov2680_global_setting); return ret; } -static int power_ctrl(struct v4l2_subdev *sd, bool flag) +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) { - 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 (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&sensor->sd, state, pad); - if (!flag || ret) { - ret |= dev->platform_data->v1p8_ctrl(sd, 0); - ret |= dev->platform_data->v2p8_ctrl(sd, 0); - } - return ret; + return &sensor->mode.fmt; } -static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) +static void ov2680_fill_format(struct ov2680_device *sensor, + struct v4l2_mbus_framefmt *fmt, + unsigned int width, unsigned int height) { - int ret; - struct ov2680_device *dev = to_ov2680_sensor(sd); + memset(fmt, 0, sizeof(*fmt)); + fmt->width = width; + fmt->height = height; + fmt->field = V4L2_FIELD_NONE; + ov2680_set_bayer_order(sensor, fmt); +} - if (!dev || !dev->platform_data) - return -ENODEV; +static void ov2680_calc_mode(struct ov2680_device *sensor, int width, int height) +{ + int orig_width = width; + int orig_height = height; - /* - * 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); + if (width <= (OV2680_NATIVE_WIDTH / 2) && + height <= (OV2680_NATIVE_HEIGHT / 2)) { + sensor->mode.binning = true; + width *= 2; + height *= 2; } else { - dev->platform_data->gpio1_ctrl(sd, 0); - ret = dev->platform_data->gpio0_ctrl(sd, 0); + sensor->mode.binning = false; } - return ret; + + 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 power_up(struct v4l2_subdev *sd) +static int ov2680_set_mode(struct ov2680_device *sensor) { - struct ov2680_device *dev = to_ov2680_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); + struct i2c_client *client = sensor->client; + u8 pll_div, unknown, inc, fmt1, fmt2; int ret; - if (!dev->platform_data) { - dev_err(&client->dev, - "no camera_sensor_platform_data"); - return -ENODEV; + 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; } - if (dev->power_on) - return 0; /* Already on */ - - /* power control */ - ret = power_ctrl(sd, 1); + ret = ov_write_reg8(client, 0x3086, pll_div); 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; - } + return ret; - /* flis clock control */ - ret = dev->platform_data->flisclk_ctrl(sd, 1); + ret = ov_write_reg8(client, 0x370a, unknown); if (ret) - goto fail_clk; - - /* according to DS, 20ms is needed between PWDN and i2c access */ - msleep(20); + return ret; - ret = ov2680_init_registers(sd); + ret = ov_write_reg16(client, OV2680_HORIZONTAL_START_H, sensor->mode.h_start); if (ret) - goto fail_init_registers; + return ret; - ret = __ov2680_set_exposure(sd, dev->exposure, dev->gain, dev->digitgain); + ret = ov_write_reg16(client, OV2680_VERTICAL_START_H, sensor->mode.v_start); if (ret) - goto fail_init_registers; + return ret; - dev->power_on = true; - return 0; + ret = ov_write_reg16(client, OV2680_HORIZONTAL_END_H, sensor->mode.h_end); + if (ret) + return ret; -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"); + ret = ov_write_reg16(client, OV2680_VERTICAL_END_H, sensor->mode.v_end); + if (ret) + return ret; - return ret; -} + ret = ov_write_reg16(client, OV2680_HORIZONTAL_OUTPUT_SIZE_H, + sensor->mode.h_output_size); + if (ret) + 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; + ret = ov_write_reg16(client, OV2680_VERTICAL_OUTPUT_SIZE_H, + sensor->mode.v_output_size); + if (ret) + return ret; - h_flag = 0; - v_flag = 0; - if (!dev->platform_data) { - dev_err(&client->dev, - "no camera_sensor_platform_data"); - return -ENODEV; - } + ret = ov_write_reg16(client, OV2680_HTS, sensor->mode.hts); + if (ret) + return ret; - if (!dev->power_on) - return 0; /* Already off */ + ret = ov_write_reg16(client, OV2680_VTS, sensor->mode.vts); + if (ret) + return ret; - ret = dev->platform_data->flisclk_ctrl(sd, 0); + ret = ov_write_reg16(client, OV2680_ISP_X_WIN, 0); if (ret) - dev_err(&client->dev, "flisclk failed\n"); + return ret; - /* gpio ctrl */ - ret = gpio_ctrl(sd, 0); - if (ret) { - ret = gpio_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "gpio failed 2\n"); - } + ret = ov_write_reg16(client, OV2680_ISP_Y_WIN, 0); + if (ret) + return ret; - /* power control */ - ret = power_ctrl(sd, 0); - if (ret) { - dev_err(&client->dev, "vprog failed.\n"); + ret = ov_write_reg8(client, OV2680_X_INC, inc); + if (ret) return ret; - } - dev->power_on = false; - return 0; -} + ret = ov_write_reg8(client, OV2680_Y_INC, inc); + if (ret) + return ret; -static int ov2680_s_power(struct v4l2_subdev *sd, int on) -{ - struct ov2680_device *dev = to_ov2680_sensor(sd); - int ret; + ret = ov_write_reg16(client, OV2680_X_WIN, sensor->mode.h_output_size); + if (ret) + return ret; - mutex_lock(&dev->input_lock); + ret = ov_write_reg16(client, OV2680_Y_WIN, sensor->mode.v_output_size); + if (ret) + return ret; - if (on == 0) { - ret = power_down(sd); - } else { - ret = power_up(sd); - } + ret = ov_write_reg8(client, OV2680_REG_FORMAT1, fmt1); + if (ret) + return ret; - mutex_unlock(&dev->input_lock); + ret = ov_write_reg8(client, OV2680_REG_FORMAT2, fmt2); + if (ret) + return 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) { - 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 ov2680_resolution *res; - int vts, ret = 0; - - dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n", - __func__, - (format->which == V4L2_SUBDEV_FORMAT_TRY) ? "try" : "set", - format->pad, fmt); - - if (format->pad) - return -EINVAL; + struct ov2680_device *sensor = to_ov2680_sensor(sd); + struct v4l2_mbus_framefmt *fmt; + unsigned int width, height; - if (!fmt) - return -EINVAL; + 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); - ov2680_info = v4l2_get_subdev_hostdata(sd); - if (!ov2680_info) - return -EINVAL; + fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which); + ov2680_fill_format(sensor, fmt, width, height); - res = v4l2_find_nearest_size(ov2680_res_preview, - ARRAY_SIZE(ov2680_res_preview), width, - height, fmt->width, fmt->height); - if (!res) - res = &ov2680_res_preview[N_RES_PREVIEW - 1]; + format->format = *fmt; - fmt->width = res->width; - fmt->height = res->height; - - 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); - mutex_lock(&dev->input_lock); - - /* 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; - } - - 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 = ov2680_write_reg(client, 2, OV2680_TIMING_VTS_H, vts); - if (ret) { - dev_err(&client->dev, "ov2680 write vts err: %d\n", ret); - 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 - */ - if (h_flag) - ov2680_h_flip(sd, h_flag); - if (v_flag) - ov2680_v_flip(sd, v_flag); - - dev->res = res; -err: - mutex_unlock(&dev->input_lock); - return ret; + mutex_lock(&sensor->input_lock); + ov2680_calc_mode(sensor, fmt->width, fmt->height); + mutex_unlock(&sensor->input_lock); + return 0; } 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); - - 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; + struct ov2680_device *sensor = to_ov2680_sensor(sd); + struct v4l2_mbus_framefmt *fmt; + fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which); + format->format = *fmt; return 0; } @@ -934,14 +380,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 = ov_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 = ov_read_reg8(client, OV2680_SC_CMMN_CHIP_ID_L, &low); id = ((((u16)high) << 8) | (u16)low); if (id != OV2680_ID) { @@ -949,8 +393,7 @@ static int ov2680_detect(struct i2c_client *client) return -ENODEV; } - ret = ov2680_read_reg(client, 1, - OV2680_SC_CMMN_SUB_ID, &high); + ret = ov_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", @@ -961,88 +404,79 @@ 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(&sensor->input_lock); + + if (sensor->is_streaming == enable) { + dev_warn(&client->dev, "stream already %s\n", enable ? "started" : "stopped"); + goto error_unlock; + } + + if (enable) { + ret = pm_runtime_get_sync(sensor->sd.dev); + if (ret < 0) + goto error_unlock; + + ret = ov2680_set_mode(sensor); + if (ret) + goto error_power_down; - 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"); + /* Restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); + if (ret) + goto error_power_down; - ret = ov2680_write_reg(client, 1, OV2680_SW_STREAM, - enable ? OV2680_START_STREAMING : - OV2680_STOP_STREAMING); + ret = ov_write_reg8(client, OV2680_SW_STREAM, OV2680_START_STREAMING); + if (ret) + goto error_power_down; + } else { + ov_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING); + pm_runtime_put(sensor->sd.dev); + } - //otp valid at stream on state - //if(!dev->otp_data) - // dev->otp_data = ov2680_otp_read(sd); + sensor->is_streaming = enable; + v4l2_ctrl_activate(sensor->ctrls.vflip, !enable); + v4l2_ctrl_activate(sensor->ctrls.hflip, !enable); - mutex_unlock(&dev->input_lock); + mutex_unlock(&sensor->input_lock); + return 0; +error_power_down: + pm_runtime_put(sensor->sd.dev); +error_unlock: + mutex_unlock(&sensor->input_lock); 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 *dev = to_ov2680_sensor(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; - - if (!platform_data) - return -ENODEV; - - dev->platform_data = - (struct camera_sensor_platform_data *)platform_data; - - mutex_lock(&dev->input_lock); + int ret; - 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; } - ret = dev->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 */ - ret = power_down(sd); - if (ret) { - dev_err(&client->dev, "ov2680 power-off err.\n"); - goto fail_csi_cfg; - } - mutex_unlock(&dev->input_lock); - - return 0; - -fail_csi_cfg: - dev->platform_data->csi_cfg(sd, 0); fail_power_on: - power_down(sd); - dev_err(&client->dev, "sensor power-gating failed\n"); - mutex_unlock(&dev->input_lock); + pm_runtime_put(&client->dev); return ret; } 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; } @@ -1050,7 +484,8 @@ 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) + /* We support only a single format */ + if (code->index) return -EINVAL; code->code = MEDIA_BUS_FMT_SBGGR10_1X10; @@ -1061,15 +496,25 @@ 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, 1096 }, + { 1616, 916 }, + { 1456, 1096 }, + { 1296, 976 }, + { 1296, 736 }, + { 784, 592 }, + { 656, 496 }, + }; 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; } @@ -1078,30 +523,18 @@ 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.denominator = ov2680_res_preview[fie->index].fps; - fract.numerator = 1; - - fie->interval = fract; - + fie->interval.numerator = 1; + fie->interval.denominator = OV2680_FPS; return 0; } 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; } @@ -1114,11 +547,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, - .ioctl = ov2680_ioctl, -}; - static const struct v4l2_subdev_pad_ops ov2680_pad_ops = { .enum_mbus_code = ov2680_enum_mbus_code, .enum_frame_size = ov2680_enum_frame_size, @@ -1128,98 +556,173 @@ 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, }; +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; + int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN; + + 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->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; + + 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); - 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); - + atomisp_unregister_subdev(sd); v4l2_device_unregister_subdev(sd); - media_entity_cleanup(&dev->sd.entity); - v4l2_ctrl_handler_free(&dev->ctrl_handler); - kfree(dev); + 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 *dev; + struct device *dev = &client->dev; + struct ov2680_device *sensor; int ret; - void *pdata; - unsigned int i; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) + sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) return -ENOMEM; - mutex_init(&dev->input_lock); + mutex_init(&sensor->input_lock); - 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); + sensor->client = client; + v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops); - pdata = gmin_camera_platform_data(&dev->sd, - ATOMISP_INPUT_FORMAT_RAW_10, - atomisp_bayer_order_bggr); - if (!pdata) { - ret = -EINVAL; - goto out_free; - } - - ret = ov2680_s_config(&dev->sd, client->irq, pdata); + ret = devm_acpi_dev_add_driver_gpios(&client->dev, ov2680_gpio_mapping); if (ret) - goto out_free; + return ret; + + sensor->powerdown = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_HIGH); + if (IS_ERR(sensor->powerdown)) + return dev_err_probe(dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n"); + + sensor->powerdown_alt = devm_gpiod_get_optional(dev, "powerdown-alt", GPIOD_OUT_HIGH); + if (IS_ERR(sensor->powerdown_alt)) + return dev_err_probe(dev, PTR_ERR(sensor->powerdown_alt), "getting powerdown-alt GPIO\n"); - ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA); + pm_runtime_set_suspended(dev); + pm_runtime_enable(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + + ret = ov2680_s_config(&sensor->sd); 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)); + return ret; + + 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(sensor); 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(&sensor->sd.entity, 1, &sensor->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(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT); - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); + ret = atomisp_register_sensor_no_gmin(&sensor->sd, 1, ATOMISP_INPUT_FORMAT_RAW_10, + atomisp_bayer_order_bggr); if (ret) { ov2680_remove(client); - dev_dbg(&client->dev, "+++ remove ov2680\n"); + return ret; } - return ret; -out_free: - dev_dbg(&client->dev, "+++ out free\n"); - v4l2_device_unregister_subdev(&dev->sd); - kfree(dev); - return ret; + + return 0; } +static int ov2680_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct ov2680_device *sensor = to_ov2680_sensor(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); + + /* 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); + static const struct acpi_device_id ov2680_acpi_match[] = { {"XXOV2680"}, {"OVTI2680"}, @@ -1230,6 +733,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/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 887b6f99f6ca..5d2e6e2e72f0 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -261,134 +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) -{ - 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, ®_val); - if (ret) - return ret; - buf->crop_horizontal_start = reg_val; - - ret = ov2722_read_reg(client, OV2722_16BIT, - OV2722_V_CROP_START_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_start = reg_val; - - ret = ov2722_read_reg(client, OV2722_16BIT, - OV2722_H_CROP_END_H, ®_val); - if (ret) - return ret; - buf->crop_horizontal_end = reg_val; - - ret = ov2722_read_reg(client, OV2722_16BIT, - OV2722_V_CROP_END_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_end = reg_val; - - ret = ov2722_read_reg(client, OV2722_16BIT, - OV2722_H_OUTSIZE_H, ®_val); - if (ret) - return ret; - buf->output_width = reg_val; - - ret = ov2722_read_reg(client, OV2722_16BIT, - OV2722_V_OUTSIZE_H, ®_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) @@ -547,15 +419,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) @@ -588,39 +451,6 @@ static const struct v4l2_ctrl_config ov2722_controls[] = { }, { .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, .name = "Link Frequency", .type = V4L2_CTRL_TYPE_INTEGER, @@ -682,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; } @@ -701,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) @@ -725,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: @@ -748,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"); @@ -765,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; } @@ -824,7 +659,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); @@ -838,10 +672,13 @@ 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); + + /* 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; @@ -875,10 +712,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; @@ -1137,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); @@ -1168,6 +1002,7 @@ out_ctrl_handler_free: 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; diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h index 4b9ce681bd93..cae480ae6fba 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 @@ -126,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; }; @@ -149,7 +143,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; @@ -390,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 806be5dff7a5..55ea422291ba 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 @@ -137,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; }; @@ -161,7 +155,6 @@ struct gc2235_device { struct gc2235_resolution *res; struct camera_sensor_platform_data *platform_data; - int vt_pix_clk_freq_mhz; u8 type; }; @@ -540,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, }, @@ -556,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, }, @@ -571,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, }, @@ -597,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, }, @@ -612,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, }, @@ -627,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, }, @@ -648,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, }, @@ -663,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 bcce18b65fa6..b0cd1b724394 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 @@ -319,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 */ @@ -353,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", @@ -369,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", @@ -385,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 7ab337b859ad..a37af0a74a53 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ b/drivers/staging/media/atomisp/i2c/ov2680.h @@ -32,53 +32,22 @@ #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_NATIVE_WIDTH 1616 +#define OV2680_NATIVE_HEIGHT 1216 -#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 +/* 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 -#define OV2680_BIN_FACTOR_MAX 4 +/* If possible send 16 extra rows / lines to the ISP as padding */ +#define OV2680_END_MARGIN 16 -#define MAX_FMTS 1 +#define OV2680_FOCAL_LENGTH_NUM 334 /*3.34mm*/ -/* 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 +#define OV2680_INTEGRATION_TIME_MARGIN 8 +#define OV2680_ID 0x2680 /* * OV2680 System control registers @@ -92,74 +61,49 @@ #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_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_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_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_FRAME_OFF_NUM 0x4202 +#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[11:8] */ +#define OV2680_HORIZONTAL_OUTPUT_SIZE_L 0x3809 /* Bit[7:0] */ +#define OV2680_VERTICAL_OUTPUT_SIZE_H 0x380a /* Bit[11:8] */ +#define OV2680_VERTICAL_OUTPUT_SIZE_L 0x380b /* Bit[7:0] */ +#define OV2680_HTS 0x380c +#define OV2680_VTS 0x380e +#define OV2680_ISP_X_WIN 0x3810 +#define OV2680_ISP_Y_WIN 0x3812 +#define OV2680_X_INC 0x3814 +#define OV2680_Y_INC 0x3815 + +#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*/ #define OV2680_MWB_BLUE_GAIN_H 0x5008/*0x3404*/ -#define OV2680_MWB_GAIN_MAX 0x0fff - -#define OV2680_START_STREAMING 0x01 -#define OV2680_STOP_STREAMING 0x00 - -#define OV2680_INVALID_CONFIG 0xffffffff +#define OV2680_MWB_GAIN_MAX 0x0fff -struct regval_list { - u16 reg_num; - u8 value; -}; +#define OV2680_REG_ISP_CTRL00 0x5080 -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; - u8 bin_factor_x; - u8 bin_factor_y; - u8 bin_mode; -}; +#define OV2680_X_WIN 0x5704 +#define OV2680_Y_WIN 0x5706 +#define OV2680_WIN_CONTROL 0x5708 -struct ov2680_format { - u8 *desc; - u32 pixelformat; - struct ov2680_reg *regs; -}; +#define OV2680_START_STREAMING 0x01 +#define OV2680_STOP_STREAMING 0x00 /* * ov2680 device structure. @@ -168,13 +112,32 @@ struct ov2680_device { struct v4l2_subdev sd; struct media_pad pad; struct mutex input_lock; - struct v4l2_ctrl_handler ctrl_handler; - struct ov2680_resolution *res; - struct camera_sensor_platform_data *platform_data; - bool power_on; - u16 exposure; - u16 gain; - u16 digitgain; + struct i2c_client *client; + struct gpio_desc *powerdown; + struct gpio_desc *powerdown_alt; + bool is_streaming; + + 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 { + struct v4l2_ctrl_handler handler; + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + struct v4l2_ctrl *test_pattern; + } ctrls; }; /** @@ -192,17 +155,13 @@ struct ov2680_reg { #define to_ov2680_sensor(x) container_of(x, struct ov2680_device, sd) -#define OV2680_MAX_WRITE_BUF_SIZE 30 +static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) +{ + struct ov2680_device *sensor = + container_of(ctrl->handler, struct ov2680_device, ctrls.handler); -struct ov2680_write_buffer { - u16 addr; - u8 data[OV2680_MAX_WRITE_BUF_SIZE]; -}; - -struct ov2680_write_ctrl { - int index; - struct ov2680_write_buffer buffer; -}; + return &sensor->sd; +} static struct ov2680_reg const ov2680_global_setting[] = { {0x0103, 0x01}, @@ -240,6 +199,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}, @@ -252,6 +213,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 @@ -276,642 +239,7 @@ 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 - - {} -}; - -/* - * 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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, - {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, 0x00}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0x00}, //add for full size flip off and mirror off 2014/09/11 - {0x5704, 0x10}, - {0x5705, 0xa0}, - {0x5706, 0x0c}, - {0x5707, 0x78}, - {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, 0xcc}, - {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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .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, - .bin_factor_x = 0, - .bin_factor_y = 0, - .bin_mode = 0, - .skip_frames = 3, - .regs = ov2680_QCIF_30fps, - }, -}; - -#define N_RES_PREVIEW (ARRAY_SIZE(ov2680_res_preview)) - #endif diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h index d6e2510bc01c..640d3ffcaa5c 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 @@ -180,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; }; @@ -204,8 +198,7 @@ struct ov2722_device { struct ov2722_resolution *res; struct camera_sensor_platform_data *platform_data; - int vt_pix_clk_freq_mhz; - int run_mode; + int power_on; u16 pixels_per_line; u16 lines_per_frame; u8 type; @@ -1113,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, @@ -1129,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, @@ -1145,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, @@ -1171,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, @@ -1187,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, @@ -1203,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, @@ -1224,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, @@ -1240,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, }, @@ -1255,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/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c index c1cd631455e6..da8c3b1d3bcd 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c @@ -415,123 +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); - - *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 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, ®_val); - if (ret) - return ret; - buf->crop_horizontal_start = reg_val; - - ret = ov5693_read_reg(client, OV5693_16BIT, - OV5693_VERTICAL_START_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_start = reg_val; - - ret = ov5693_read_reg(client, OV5693_16BIT, - OV5693_HORIZONTAL_END_H, ®_val); - if (ret) - return ret; - buf->crop_horizontal_end = reg_val; - - ret = ov5693_read_reg(client, OV5693_16BIT, - OV5693_VERTICAL_END_H, ®_val); - if (ret) - return ret; - buf->crop_vertical_end = reg_val; - - ret = ov5693_read_reg(client, OV5693_16BIT, - OV5693_HORIZONTAL_OUTPUT_SIZE_H, ®_val); - if (ret) - return ret; - buf->output_width = reg_val; - - ret = ov5693_read_reg(client, OV5693_16BIT, - OV5693_VERTICAL_OUTPUT_SIZE_H, ®_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) @@ -1107,27 +990,12 @@ 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; 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; } @@ -1154,39 +1022,6 @@ static const struct v4l2_ctrl_config ov5693_controls[] = { }, { .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, .type = V4L2_CTRL_TYPE_INTEGER, .name = "focus move absolute", @@ -1240,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) @@ -1659,18 +1472,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..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; }; @@ -228,7 +225,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; @@ -1110,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, }, { @@ -1124,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, }, { @@ -1138,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, }, { @@ -1152,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, }, }; @@ -1176,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, }, { @@ -1190,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, }, { @@ -1204,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, }, { @@ -1218,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, }, { @@ -1232,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, }, }; @@ -1251,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, }, { @@ -1265,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, }, { @@ -1279,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, }, { @@ -1293,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, }, { @@ -1307,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, }, { @@ -1321,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, }, { @@ -1335,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, }, { @@ -1349,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, }, { @@ -1363,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, }, { @@ -1377,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, }, }; diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h index 3f602b5aaff9..63b1bcd35399 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 { @@ -650,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]; @@ -914,8 +878,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 \ @@ -961,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) @@ -1093,10 +1051,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 */ @@ -1117,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/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 0253661d4332..539b21d39d3b 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; @@ -210,7 +204,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; @@ -218,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/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 d8c7e7367386..47f18ac5e40e 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; @@ -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 */ @@ -4211,25 +4212,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) { @@ -5010,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; @@ -5049,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; @@ -5182,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 */ @@ -5492,42 +5470,6 @@ out: 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..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); @@ -258,9 +259,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); @@ -273,9 +271,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_csi2.c b/drivers/staging/media/atomisp/pci/atomisp_csi2.c index 4a9268bac8a9..b00bc0b7aaad 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.c @@ -175,47 +175,8 @@ static const struct v4l2_subdev_ops csi2_ops = { .pad = &csi2_pad_ops, }; -/* - * csi2_link_setup - Setup CSI2 connections. - * @entity : Pointer to media entity structure - * @local : Pointer to local pad array - * @remote : Pointer to remote pad array - * @flags : Link flags - * return -EINVAL or zero on success - */ -static int csi2_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_mipi_csi2_device *csi2 = v4l2_get_subdevdata(sd); - u32 result = local->index | is_media_entity_v4l2_subdev(remote->entity); - - switch (result) { - case CSI2_PAD_SOURCE | MEDIA_ENT_F_OLD_BASE: - /* not supported yet */ - return -EINVAL; - - case CSI2_PAD_SOURCE | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: - if (flags & MEDIA_LNK_FL_ENABLED) { - if (csi2->output & ~CSI2_OUTPUT_ISP_SUBDEV) - return -EBUSY; - csi2->output |= CSI2_OUTPUT_ISP_SUBDEV; - } else { - csi2->output &= ~CSI2_OUTPUT_ISP_SUBDEV; - } - break; - - default: - /* Link from camera to CSI2 is fixed... */ - return -EINVAL; - } - return 0; -} - /* media operations */ static const struct media_entity_operations csi2_media_ops = { - .link_setup = csi2_link_setup, .link_validate = v4l2_subdev_link_validate, }; @@ -242,7 +203,7 @@ static int mipi_csi2_init_entities(struct atomisp_mipi_csi2_device *csi2, pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK; me->ops = &csi2_media_ops; - me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + me->function = MEDIA_ENT_F_VID_IF_BRIDGE; ret = media_entity_pads_init(me, CSI2_PADS_NUM, pads); if (ret < 0) return ret; diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp_csi2.h index e35711be8a37..b245b2f5ce99 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2.h +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2.h @@ -25,9 +25,6 @@ #define CSI2_PAD_SOURCE 1 #define CSI2_PADS_NUM 2 -#define CSI2_OUTPUT_ISP_SUBDEV BIT(0) -#define CSI2_OUTPUT_MEMORY BIT(1) - struct atomisp_device; struct v4l2_device; struct atomisp_sub_device; @@ -39,8 +36,6 @@ struct atomisp_mipi_csi2_device { struct v4l2_ctrl_handler ctrls; struct atomisp_device *isp; - - u32 output; /* output direction */ }; int atomisp_csi2_set_ffmt(struct v4l2_subdev *sd, diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index acea7492847d..ce01479bdd68 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) @@ -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; @@ -681,7 +647,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) @@ -757,25 +723,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"); @@ -792,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; @@ -821,13 +764,13 @@ init_subdev: 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; @@ -885,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 && ret != -ENOIOCTLCMD) + 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); @@ -901,12 +848,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..883c1851c1c9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.h +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.h @@ -31,8 +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; -extern bool defer_fw_load; - #endif /* __ATOMISP_FOPS_H__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index 3d41fab661cf..7fc7dfa56172 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -57,8 +57,12 @@ 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 @@ -145,7 +149,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); @@ -158,6 +161,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++) @@ -179,36 +190,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; @@ -843,6 +828,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 +884,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 +909,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 +966,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"); @@ -1095,6 +1092,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) { diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index 653e6d74a966..fa38d91420cf 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 @@ -214,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; @@ -242,7 +239,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 +253,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; }; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index cb01ba65c88f..d1314bdbf7d5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -173,24 +173,6 @@ static struct v4l2_queryctrl ci_v4l2_controls[] = { .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, .name = "AE and AWB status", @@ -636,10 +618,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) @@ -718,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 */ @@ -727,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; } @@ -1067,13 +1049,23 @@ error: return -ENOMEM; } +/* + * FIXME the abuse of buf->reserved2 in the qbuf and dqbuf wrappers comes from + * the original atomisp buffer handling and should be replaced with proper V4L2 + * per frame parameters use. + * + * Once this is fixed these wrappers can be removed, replacing them with direct + * calls to vb2_ioctl_[d]qbuf(). + */ static int atomisp_qbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf) { struct video_device *vdev = video_devdata(file); struct atomisp_device *isp = video_get_drvdata(vdev); 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 */ @@ -1106,7 +1098,6 @@ static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer vb = pipe->vb_queue.bufs[buf->index]; frame = vb_to_frame(vb); - /* FIXME this abuse of buf->reserved* comes from the original atomisp buffer handling */ buf->reserved = asd->frame_status[buf->index]; /* @@ -1354,7 +1345,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; } @@ -1530,7 +1521,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: @@ -1631,7 +1622,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,9 +1818,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: case V4L2_CID_TEST_PATTERN: case V4L2_CID_TEST_PATTERN_COLOR_R: @@ -1940,7 +1927,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,14 +2262,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; - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: if (motor) err = v4l2_subdev_call(motor, core, ioctl, cmd, arg); diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c index cadc468b4c2f..9cfb85c61db6 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[] = { @@ -574,40 +576,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 +613,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, @@ -746,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, */ }; @@ -1057,23 +948,37 @@ 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); 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; } /* @@ -1089,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); @@ -1114,22 +1017,30 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) MEDIA_BUS_FMT_SBGGR10_1X10; me->ops = &isp_subdev_media_ops; - me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + me->function = MEDIA_ENT_F_PROC_VIDEO_ISP; ret = media_entity_pads_init(me, ATOMISP_SUBDEV_PADS_NUM, pads); 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); 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 */ diff --git a/drivers/staging/media/atomisp/pci/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp_tpg.c index e29a96da5f98..074826a5b706 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_tpg.c +++ b/drivers/staging/media/atomisp/pci/atomisp_tpg.c @@ -152,7 +152,7 @@ int atomisp_tpg_init(struct atomisp_device *isp) v4l2_set_subdevdata(sd, tpg); pads[0].flags = MEDIA_PAD_FL_SINK; - me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + me->function = MEDIA_ENT_F_PROC_VIDEO_ISP; ret = media_entity_pads_init(me, 1, pads); if (ret < 0) diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index e786b81921da..ba628f7cf385 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> @@ -57,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); @@ -524,7 +519,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); @@ -637,31 +632,21 @@ done: */ 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, ®); 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, ®); - 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) { + 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; @@ -669,16 +654,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); - - /* - * 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); + msleep(20); + } /* Write to ISPSSPM0 bit[1:0] to power on/off the IUNIT */ iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, @@ -703,6 +682,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 +723,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 +737,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 +749,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 +772,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); } @@ -953,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); + ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdevs->subdev); + if (ret) continue; - } - ret = v4l2_device_register_subdev(&isp->v4l2_dev, subdev); - if (ret) { - dev_warn(isp->dev, "Subdev %s detection fail\n", - board_info->type); - 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: @@ -1008,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 @@ -1020,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"); @@ -1524,21 +1468,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); @@ -1603,6 +1543,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); @@ -1618,14 +1578,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); @@ -1645,6 +1601,7 @@ css_init_fail: 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 +1654,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 +1679,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, 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); } 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); 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, 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) { diff --git a/drivers/staging/media/deprecated/saa7146/av7110/Kconfig b/drivers/staging/media/av7110/Kconfig index 1571eab31926..9faf9d2d4001 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/Kconfig +++ b/drivers/staging/media/av7110/Kconfig @@ -5,7 +5,7 @@ config DVB_AV7110_IR default DVB_AV7110 config DVB_AV7110 - tristate "AV7110 cards (DEPRECATED)" + tristate "AV7110 cards" depends on DVB_CORE && PCI && I2C select TTPCI_EEPROM select VIDEO_SAA7146_VV @@ -35,13 +35,10 @@ config DVB_AV7110 kernel image by adding the filename to the EXTRA_FIRMWARE configuration option string. - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - Say Y if you own such a card and want to use it. config DVB_AV7110_OSD - bool "AV7110 OSD support (DEPRECATED)" + bool "AV7110 OSD support" depends on DVB_AV7110 default y if DVB_AV7110=y || DVB_AV7110=m help @@ -52,13 +49,10 @@ config DVB_AV7110_OSD Anyway, some popular DVB software like VDR uses this OSD to render its menus, so say Y if you want to use this software. - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - All other people say N. config DVB_BUDGET_PATCH - tristate "AV7110 cards with Budget Patch (DEPRECATED)" + tristate "AV7110 cards with Budget Patch" depends on DVB_BUDGET_CORE && I2C depends on DVB_AV7110 select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT @@ -74,9 +68,6 @@ config DVB_BUDGET_PATCH standard AV7110 driver prior to loading this driver. - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - Say Y if you own such a card and want to use it. To compile this driver as a module, choose M here: the @@ -89,7 +80,7 @@ if DVB_AV7110 # it if we drop support for AV7110, as no other driver will use it. config DVB_SP8870 - tristate "Spase sp8870 based (DEPRECATED)" + tristate "Spase sp8870 based" depends on DVB_CORE && I2C default m if !MEDIA_SUBDRV_AUTOSELECT help @@ -100,7 +91,4 @@ config DVB_SP8870 download/extract it, and then copy it to /usr/lib/hotplug/firmware or /lib/firmware (depending on configuration of firmware hotplug). - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - endif diff --git a/drivers/staging/media/deprecated/saa7146/av7110/Makefile b/drivers/staging/media/av7110/Makefile index c04cd0a59109..307b267598ea 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/Makefile +++ b/drivers/staging/media/av7110/Makefile @@ -18,6 +18,5 @@ obj-$(CONFIG_DVB_SP8870) += sp8870.o ccflags-y += -I $(srctree)/drivers/media/dvb-frontends ccflags-y += -I $(srctree)/drivers/media/tuners +ccflags-y += -I $(srctree)/drivers/media/pci/ttpci ccflags-y += -I $(srctree)/drivers/media/common -ccflags-y += -I $(srctree)/drivers/staging/media/deprecated/saa7146/ttpci -ccflags-y += -I $(srctree)/drivers/staging/media/deprecated/saa7146/common diff --git a/drivers/staging/media/av7110/TODO b/drivers/staging/media/av7110/TODO new file mode 100644 index 000000000000..60062d8441b3 --- /dev/null +++ b/drivers/staging/media/av7110/TODO @@ -0,0 +1,3 @@ +- This driver is too old and relies on a different API. + Drop it from Kernel on a couple of versions. +- Cleanup patches for the drivers here won't be accepted. diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst b/drivers/staging/media/av7110/audio-bilingual-channel-select.rst index 33b5363317f1..33b5363317f1 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-bilingual-channel-select.rst +++ b/drivers/staging/media/av7110/audio-bilingual-channel-select.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst b/drivers/staging/media/av7110/audio-channel-select.rst index 74093df92a68..74093df92a68 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-channel-select.rst +++ b/drivers/staging/media/av7110/audio-channel-select.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst b/drivers/staging/media/av7110/audio-clear-buffer.rst index a0ebb0278260..a0ebb0278260 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-clear-buffer.rst +++ b/drivers/staging/media/av7110/audio-clear-buffer.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst b/drivers/staging/media/av7110/audio-continue.rst index a2e9850f37f2..a2e9850f37f2 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-continue.rst +++ b/drivers/staging/media/av7110/audio-continue.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst b/drivers/staging/media/av7110/audio-fclose.rst index 77857d578e83..77857d578e83 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-fclose.rst +++ b/drivers/staging/media/av7110/audio-fclose.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst b/drivers/staging/media/av7110/audio-fopen.rst index 774daaab3bad..774daaab3bad 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-fopen.rst +++ b/drivers/staging/media/av7110/audio-fopen.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst b/drivers/staging/media/av7110/audio-fwrite.rst index 7b096ac2b6c4..7b096ac2b6c4 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-fwrite.rst +++ b/drivers/staging/media/av7110/audio-fwrite.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst b/drivers/staging/media/av7110/audio-get-capabilities.rst index 6d9eb71dad17..6d9eb71dad17 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-get-capabilities.rst +++ b/drivers/staging/media/av7110/audio-get-capabilities.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst b/drivers/staging/media/av7110/audio-get-status.rst index 7ae8db2e65e9..7ae8db2e65e9 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-get-status.rst +++ b/drivers/staging/media/av7110/audio-get-status.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst b/drivers/staging/media/av7110/audio-pause.rst index d37d1ddce4df..d37d1ddce4df 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-pause.rst +++ b/drivers/staging/media/av7110/audio-pause.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst b/drivers/staging/media/av7110/audio-play.rst index e591930b6ca7..e591930b6ca7 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-play.rst +++ b/drivers/staging/media/av7110/audio-play.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst b/drivers/staging/media/av7110/audio-select-source.rst index 6a0c0f365eb1..6a0c0f365eb1 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-select-source.rst +++ b/drivers/staging/media/av7110/audio-select-source.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst b/drivers/staging/media/av7110/audio-set-av-sync.rst index 85a8016bf025..85a8016bf025 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-av-sync.rst +++ b/drivers/staging/media/av7110/audio-set-av-sync.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst b/drivers/staging/media/av7110/audio-set-bypass-mode.rst index 80d551a2053a..80d551a2053a 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-bypass-mode.rst +++ b/drivers/staging/media/av7110/audio-set-bypass-mode.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst b/drivers/staging/media/av7110/audio-set-id.rst index 39ad846d412d..39ad846d412d 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-id.rst +++ b/drivers/staging/media/av7110/audio-set-id.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst b/drivers/staging/media/av7110/audio-set-mixer.rst index 45dbdf4801e0..45dbdf4801e0 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mixer.rst +++ b/drivers/staging/media/av7110/audio-set-mixer.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst b/drivers/staging/media/av7110/audio-set-mute.rst index 987751f92967..987751f92967 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-mute.rst +++ b/drivers/staging/media/av7110/audio-set-mute.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst b/drivers/staging/media/av7110/audio-set-streamtype.rst index 77d73c74882f..77d73c74882f 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-set-streamtype.rst +++ b/drivers/staging/media/av7110/audio-set-streamtype.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst b/drivers/staging/media/av7110/audio-stop.rst index d77f786fd797..d77f786fd797 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio-stop.rst +++ b/drivers/staging/media/av7110/audio-stop.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio.rst b/drivers/staging/media/av7110/audio.rst index aa753336b31f..aa753336b31f 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio.rst +++ b/drivers/staging/media/av7110/audio.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst b/drivers/staging/media/av7110/audio_data_types.rst index 4744529136a8..4744529136a8 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio_data_types.rst +++ b/drivers/staging/media/av7110/audio_data_types.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst b/drivers/staging/media/av7110/audio_function_calls.rst index fa5ba9539caf..fa5ba9539caf 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/audio_function_calls.rst +++ b/drivers/staging/media/av7110/audio_function_calls.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c index df81a9b744c2..df81a9b744c2 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110.c +++ b/drivers/staging/media/av7110/av7110.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110.h b/drivers/staging/media/av7110/av7110.h index 9fde69b38f1c..809d938ae166 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110.h +++ b/drivers/staging/media/av7110/av7110.h @@ -33,7 +33,7 @@ #include "stv0297.h" #include "l64781.h" -#include "saa7146_vv.h" +#include <media/drv-intf/saa7146_vv.h> #define ANALOG_TUNER_VES1820 1 diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c b/drivers/staging/media/av7110/av7110_av.c index 0bf513c26b6b..0bf513c26b6b 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.c +++ b/drivers/staging/media/av7110/av7110_av.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h b/drivers/staging/media/av7110/av7110_av.h index 71bbd4391f57..71bbd4391f57 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_av.h +++ b/drivers/staging/media/av7110/av7110_av.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c b/drivers/staging/media/av7110/av7110_ca.c index c1338e074a3d..c1338e074a3d 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.c +++ b/drivers/staging/media/av7110/av7110_ca.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h b/drivers/staging/media/av7110/av7110_ca.h index a6e3f2955730..a6e3f2955730 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ca.h +++ b/drivers/staging/media/av7110/av7110_ca.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c b/drivers/staging/media/av7110/av7110_hw.c index 93ca31e38ddd..93ca31e38ddd 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.c +++ b/drivers/staging/media/av7110/av7110_hw.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h b/drivers/staging/media/av7110/av7110_hw.h index 6380d8950c69..6380d8950c69 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_hw.h +++ b/drivers/staging/media/av7110/av7110_hw.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c b/drivers/staging/media/av7110/av7110_ipack.c index 30330ed01ce8..30330ed01ce8 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.c +++ b/drivers/staging/media/av7110/av7110_ipack.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h b/drivers/staging/media/av7110/av7110_ipack.h index 943ec899bb93..943ec899bb93 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ipack.h +++ b/drivers/staging/media/av7110/av7110_ipack.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c b/drivers/staging/media/av7110/av7110_ir.c index a851ba328e4a..a851ba328e4a 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_ir.c +++ b/drivers/staging/media/av7110/av7110_ir.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c b/drivers/staging/media/av7110/av7110_v4l.c index c89f536f699c..c89f536f699c 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/av7110_v4l.c +++ b/drivers/staging/media/av7110/av7110_v4l.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c b/drivers/staging/media/av7110/budget-patch.c index d173c8ade6a7..d173c8ade6a7 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/budget-patch.c +++ b/drivers/staging/media/av7110/budget-patch.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c b/drivers/staging/media/av7110/dvb_filter.c index 8c2eca5dcdc9..8c2eca5dcdc9 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.c +++ b/drivers/staging/media/av7110/dvb_filter.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h b/drivers/staging/media/av7110/dvb_filter.h index 67a3c6333bca..67a3c6333bca 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/dvb_filter.h +++ b/drivers/staging/media/av7110/dvb_filter.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/sp8870.c b/drivers/staging/media/av7110/sp8870.c index 9767159aeb9b..9767159aeb9b 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/sp8870.c +++ b/drivers/staging/media/av7110/sp8870.c diff --git a/drivers/staging/media/deprecated/saa7146/av7110/sp8870.h b/drivers/staging/media/av7110/sp8870.h index 5eacf39f425e..5eacf39f425e 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/sp8870.h +++ b/drivers/staging/media/av7110/sp8870.h diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst b/drivers/staging/media/av7110/video-clear-buffer.rst index a7730559bbb2..a7730559bbb2 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-clear-buffer.rst +++ b/drivers/staging/media/av7110/video-clear-buffer.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-command.rst b/drivers/staging/media/av7110/video-command.rst index cae9445eb3af..cae9445eb3af 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-command.rst +++ b/drivers/staging/media/av7110/video-command.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst b/drivers/staging/media/av7110/video-continue.rst index bc34bf3989e4..bc34bf3989e4 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-continue.rst +++ b/drivers/staging/media/av7110/video-continue.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst b/drivers/staging/media/av7110/video-fast-forward.rst index e71fa8d6965b..e71fa8d6965b 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-fast-forward.rst +++ b/drivers/staging/media/av7110/video-fast-forward.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst b/drivers/staging/media/av7110/video-fclose.rst index 01d24d548439..01d24d548439 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-fclose.rst +++ b/drivers/staging/media/av7110/video-fclose.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst b/drivers/staging/media/av7110/video-fopen.rst index 1371b083e4e8..1371b083e4e8 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-fopen.rst +++ b/drivers/staging/media/av7110/video-fopen.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst b/drivers/staging/media/av7110/video-freeze.rst index 4321f257cb70..4321f257cb70 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-freeze.rst +++ b/drivers/staging/media/av7110/video-freeze.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst b/drivers/staging/media/av7110/video-fwrite.rst index a07fd7d7a40e..a07fd7d7a40e 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-fwrite.rst +++ b/drivers/staging/media/av7110/video-fwrite.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst b/drivers/staging/media/av7110/video-get-capabilities.rst index 01e09f56656c..01e09f56656c 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-capabilities.rst +++ b/drivers/staging/media/av7110/video-get-capabilities.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst b/drivers/staging/media/av7110/video-get-event.rst index 90382bc36cfe..90382bc36cfe 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-event.rst +++ b/drivers/staging/media/av7110/video-get-event.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst b/drivers/staging/media/av7110/video-get-frame-count.rst index b48ac8c58a41..b48ac8c58a41 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-frame-count.rst +++ b/drivers/staging/media/av7110/video-get-frame-count.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst b/drivers/staging/media/av7110/video-get-pts.rst index fedaff41be0b..fedaff41be0b 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-pts.rst +++ b/drivers/staging/media/av7110/video-get-pts.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst b/drivers/staging/media/av7110/video-get-size.rst index de34331c5bd1..de34331c5bd1 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-size.rst +++ b/drivers/staging/media/av7110/video-get-size.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst b/drivers/staging/media/av7110/video-get-status.rst index 9b86fbf411d4..9b86fbf411d4 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-get-status.rst +++ b/drivers/staging/media/av7110/video-get-status.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-play.rst b/drivers/staging/media/av7110/video-play.rst index 35ac8b98fdbf..35ac8b98fdbf 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-play.rst +++ b/drivers/staging/media/av7110/video-play.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst b/drivers/staging/media/av7110/video-select-source.rst index 929a20985d53..929a20985d53 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-select-source.rst +++ b/drivers/staging/media/av7110/video-select-source.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst b/drivers/staging/media/av7110/video-set-blank.rst index 70249a6ba125..70249a6ba125 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-set-blank.rst +++ b/drivers/staging/media/av7110/video-set-blank.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst b/drivers/staging/media/av7110/video-set-display-format.rst index 1de4f40ae732..1de4f40ae732 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-set-display-format.rst +++ b/drivers/staging/media/av7110/video-set-display-format.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst b/drivers/staging/media/av7110/video-set-format.rst index bb64e37ae081..bb64e37ae081 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-set-format.rst +++ b/drivers/staging/media/av7110/video-set-format.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst b/drivers/staging/media/av7110/video-set-streamtype.rst index 1f31c048bdbc..1f31c048bdbc 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-set-streamtype.rst +++ b/drivers/staging/media/av7110/video-set-streamtype.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst b/drivers/staging/media/av7110/video-slowmotion.rst index 1478fcc30cb8..1478fcc30cb8 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-slowmotion.rst +++ b/drivers/staging/media/av7110/video-slowmotion.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst b/drivers/staging/media/av7110/video-stillpicture.rst index d25384222a20..d25384222a20 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-stillpicture.rst +++ b/drivers/staging/media/av7110/video-stillpicture.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst b/drivers/staging/media/av7110/video-stop.rst index 96f61c5b48a2..96f61c5b48a2 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-stop.rst +++ b/drivers/staging/media/av7110/video-stop.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst b/drivers/staging/media/av7110/video-try-command.rst index 79bf3dfb8a32..79bf3dfb8a32 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video-try-command.rst +++ b/drivers/staging/media/av7110/video-try-command.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video.rst b/drivers/staging/media/av7110/video.rst index 808705b769a1..808705b769a1 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video.rst +++ b/drivers/staging/media/av7110/video.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst b/drivers/staging/media/av7110/video_function_calls.rst index 20a897be5dca..20a897be5dca 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video_function_calls.rst +++ b/drivers/staging/media/av7110/video_function_calls.rst diff --git a/drivers/staging/media/deprecated/saa7146/av7110/video_types.rst b/drivers/staging/media/av7110/video_types.rst index c4557d328b7a..c4557d328b7a 100644 --- a/drivers/staging/media/deprecated/saa7146/av7110/video_types.rst +++ b/drivers/staging/media/av7110/video_types.rst diff --git a/drivers/staging/media/deprecated/saa7146/Kconfig b/drivers/staging/media/deprecated/saa7146/Kconfig deleted file mode 100644 index 54154da79f59..000000000000 --- a/drivers/staging/media/deprecated/saa7146/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -source "drivers/staging/media/deprecated/saa7146/common/Kconfig" -source "drivers/staging/media/deprecated/saa7146/av7110/Kconfig" -source "drivers/staging/media/deprecated/saa7146/saa7146/Kconfig" -source "drivers/staging/media/deprecated/saa7146/ttpci/Kconfig" diff --git a/drivers/staging/media/deprecated/saa7146/Makefile b/drivers/staging/media/deprecated/saa7146/Makefile deleted file mode 100644 index 68e7aa10c639..000000000000 --- a/drivers/staging/media/deprecated/saa7146/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - # SPDX-License-Identifier: GPL-2.0-only -obj-y += common/ av7110/ saa7146/ ttpci/ diff --git a/drivers/staging/media/deprecated/saa7146/av7110/TODO b/drivers/staging/media/deprecated/saa7146/av7110/TODO deleted file mode 100644 index 38817e04bb67..000000000000 --- a/drivers/staging/media/deprecated/saa7146/av7110/TODO +++ /dev/null @@ -1,9 +0,0 @@ -- This driver is too old and relies on a different API. - Drop it from Kernel on a couple of versions. -- Cleanup patches for the drivers here won't be accepted. - -These drivers are now deprecated with the intent of -removing them altogether by the beginning of 2023. - -If someone is interested in doing this work, then contact the -linux-media mailinglist (https://linuxtv.org/lists.php). diff --git a/drivers/staging/media/deprecated/saa7146/common/Kconfig b/drivers/staging/media/deprecated/saa7146/common/Kconfig deleted file mode 100644 index a0aa155e5d85..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config VIDEO_SAA7146 - tristate - depends on I2C && PCI - -config VIDEO_SAA7146_VV - tristate - depends on VIDEO_DEV - select VIDEOBUF_DMA_SG - select VIDEO_SAA7146 diff --git a/drivers/staging/media/deprecated/saa7146/common/Makefile b/drivers/staging/media/deprecated/saa7146/common/Makefile deleted file mode 100644 index 2a6337feaec8..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -saa7146-objs := saa7146_i2c.o saa7146_core.o -saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o - -obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o -obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146.h b/drivers/staging/media/deprecated/saa7146/common/saa7146.h deleted file mode 100644 index 71ce63c99cb4..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146.h +++ /dev/null @@ -1,472 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __SAA7146__ -#define __SAA7146__ - -#include <linux/delay.h> /* for delay-stuff */ -#include <linux/slab.h> /* for kmalloc/kfree */ -#include <linux/pci.h> /* for pci-config-stuff, vendor ids etc. */ -#include <linux/init.h> /* for "__init" */ -#include <linux/interrupt.h> /* for IMMEDIATE_BH */ -#include <linux/kmod.h> /* for kernel module loader */ -#include <linux/i2c.h> /* for i2c subsystem */ -#include <asm/io.h> /* for accessing devices */ -#include <linux/stringify.h> -#include <linux/mutex.h> -#include <linux/scatterlist.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ctrls.h> - -#include <linux/vmalloc.h> /* for vmalloc() */ -#include <linux/mm.h> /* for vmalloc_to_page() */ - -#define saa7146_write(sxy,adr,dat) writel((dat),(sxy->mem+(adr))) -#define saa7146_read(sxy,adr) readl(sxy->mem+(adr)) - -extern unsigned int saa7146_debug; - -#ifndef DEBUG_VARIABLE - #define DEBUG_VARIABLE saa7146_debug -#endif - -#define ERR(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__) - -#define _DBG(mask, fmt, ...) \ -do { \ - if (DEBUG_VARIABLE & mask) \ - pr_debug("%s(): " fmt, __func__, ##__VA_ARGS__); \ -} while (0) - -/* simple debug messages */ -#define DEB_S(fmt, ...) _DBG(0x01, fmt, ##__VA_ARGS__) -/* more detailed debug messages */ -#define DEB_D(fmt, ...) _DBG(0x02, fmt, ##__VA_ARGS__) -/* print enter and exit of functions */ -#define DEB_EE(fmt, ...) _DBG(0x04, fmt, ##__VA_ARGS__) -/* i2c debug messages */ -#define DEB_I2C(fmt, ...) _DBG(0x08, fmt, ##__VA_ARGS__) -/* vbi debug messages */ -#define DEB_VBI(fmt, ...) _DBG(0x10, fmt, ##__VA_ARGS__) -/* interrupt debug messages */ -#define DEB_INT(fmt, ...) _DBG(0x20, fmt, ##__VA_ARGS__) -/* capture debug messages */ -#define DEB_CAP(fmt, ...) _DBG(0x40, fmt, ##__VA_ARGS__) - -#define SAA7146_ISR_CLEAR(x,y) \ - saa7146_write(x, ISR, (y)); - -struct module; - -struct saa7146_dev; -struct saa7146_extension; -struct saa7146_vv; - -/* saa7146 page table */ -struct saa7146_pgtable { - unsigned int size; - __le32 *cpu; - dma_addr_t dma; - /* used for offsets for u,v planes for planar capture modes */ - unsigned long offset; - /* used for custom pagetables (used for example by budget dvb cards) */ - struct scatterlist *slist; - int nents; -}; - -struct saa7146_pci_extension_data { - struct saa7146_extension *ext; - void *ext_priv; /* most likely a name string */ -}; - -#define MAKE_EXTENSION_PCI(x_var, x_vendor, x_device) \ - { \ - .vendor = PCI_VENDOR_ID_PHILIPS, \ - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, \ - .subvendor = x_vendor, \ - .subdevice = x_device, \ - .driver_data = (unsigned long)& x_var, \ - } - -struct saa7146_extension -{ - char name[32]; /* name of the device */ -#define SAA7146_USE_I2C_IRQ 0x1 -#define SAA7146_I2C_SHORT_DELAY 0x2 - int flags; - - /* pairs of subvendor and subdevice ids for - supported devices, last entry 0xffff, 0xfff */ - struct module *module; - struct pci_driver driver; - const struct pci_device_id *pci_tbl; - - /* extension functions */ - int (*probe)(struct saa7146_dev *); - int (*attach)(struct saa7146_dev *, struct saa7146_pci_extension_data *); - int (*detach)(struct saa7146_dev*); - - u32 irq_mask; /* mask to indicate, which irq-events are handled by the extension */ - void (*irq_func)(struct saa7146_dev*, u32* irq_mask); -}; - -struct saa7146_dma -{ - dma_addr_t dma_handle; - __le32 *cpu_addr; -}; - -struct saa7146_dev -{ - struct module *module; - - struct v4l2_device v4l2_dev; - struct v4l2_ctrl_handler ctrl_handler; - - /* different device locks */ - spinlock_t slock; - struct mutex v4l2_lock; - - unsigned char __iomem *mem; /* pointer to mapped IO memory */ - u32 revision; /* chip revision; needed for bug-workarounds*/ - - /* pci-device & irq stuff*/ - char name[32]; - struct pci_dev *pci; - u32 int_todo; - spinlock_t int_slock; - - /* extension handling */ - struct saa7146_extension *ext; /* indicates if handled by extension */ - void *ext_priv; /* pointer for extension private use (most likely some private data) */ - struct saa7146_ext_vv *ext_vv_data; - - /* per device video/vbi information (if available) */ - struct saa7146_vv *vv_data; - void (*vv_callback)(struct saa7146_dev *dev, unsigned long status); - - /* i2c-stuff */ - struct mutex i2c_lock; - - u32 i2c_bitrate; - struct saa7146_dma d_i2c; /* pointer to i2c memory */ - wait_queue_head_t i2c_wq; - int i2c_op; - - /* memories */ - struct saa7146_dma d_rps0; - struct saa7146_dma d_rps1; -}; - -static inline struct saa7146_dev *to_saa7146_dev(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct saa7146_dev, v4l2_dev); -} - -/* from saa7146_i2c.c */ -int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate); - -/* from saa7146_core.c */ -int saa7146_register_extension(struct saa7146_extension*); -int saa7146_unregister_extension(struct saa7146_extension*); -struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc); -int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt); -void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt); -int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length ); -void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt); -void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt); -void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data); -int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop); - -/* some memory sizes */ -#define SAA7146_I2C_MEM ( 1*PAGE_SIZE) -#define SAA7146_RPS_MEM ( 1*PAGE_SIZE) - -/* some i2c constants */ -#define SAA7146_I2C_TIMEOUT 100 /* i2c-timeout-value in ms */ -#define SAA7146_I2C_RETRIES 3 /* how many times shall we retry an i2c-operation? */ -#define SAA7146_I2C_DELAY 5 /* time we wait after certain i2c-operations */ - -/* unsorted defines */ -#define ME1 0x0000000800 -#define PV1 0x0000000008 - -/* gpio defines */ -#define SAA7146_GPIO_INPUT 0x00 -#define SAA7146_GPIO_IRQHI 0x10 -#define SAA7146_GPIO_IRQLO 0x20 -#define SAA7146_GPIO_IRQHL 0x30 -#define SAA7146_GPIO_OUTLO 0x40 -#define SAA7146_GPIO_OUTHI 0x50 - -/* debi defines */ -#define DEBINOSWAP 0x000e0000 - -/* define for the register programming sequencer (rps) */ -#define CMD_NOP 0x00000000 /* No operation */ -#define CMD_CLR_EVENT 0x00000000 /* Clear event */ -#define CMD_SET_EVENT 0x10000000 /* Set signal event */ -#define CMD_PAUSE 0x20000000 /* Pause */ -#define CMD_CHECK_LATE 0x30000000 /* Check late */ -#define CMD_UPLOAD 0x40000000 /* Upload */ -#define CMD_STOP 0x50000000 /* Stop */ -#define CMD_INTERRUPT 0x60000000 /* Interrupt */ -#define CMD_JUMP 0x80000000 /* Jump */ -#define CMD_WR_REG 0x90000000 /* Write (load) register */ -#define CMD_RD_REG 0xa0000000 /* Read (store) register */ -#define CMD_WR_REG_MASK 0xc0000000 /* Write register with mask */ - -#define CMD_OAN MASK_27 -#define CMD_INV MASK_26 -#define CMD_SIG4 MASK_25 -#define CMD_SIG3 MASK_24 -#define CMD_SIG2 MASK_23 -#define CMD_SIG1 MASK_22 -#define CMD_SIG0 MASK_21 -#define CMD_O_FID_B MASK_14 -#define CMD_E_FID_B MASK_13 -#define CMD_O_FID_A MASK_12 -#define CMD_E_FID_A MASK_11 - -/* some events and command modifiers for rps1 squarewave generator */ -#define EVT_HS (1<<15) // Source Line Threshold reached -#define EVT_VBI_B (1<<9) // VSYNC Event -#define RPS_OAN (1<<27) // 1: OR events, 0: AND events -#define RPS_INV (1<<26) // Invert (compound) event -#define GPIO3_MSK 0xFF000000 // GPIO #3 control bits - -/* Bit mask constants */ -#define MASK_00 0x00000001 /* Mask value for bit 0 */ -#define MASK_01 0x00000002 /* Mask value for bit 1 */ -#define MASK_02 0x00000004 /* Mask value for bit 2 */ -#define MASK_03 0x00000008 /* Mask value for bit 3 */ -#define MASK_04 0x00000010 /* Mask value for bit 4 */ -#define MASK_05 0x00000020 /* Mask value for bit 5 */ -#define MASK_06 0x00000040 /* Mask value for bit 6 */ -#define MASK_07 0x00000080 /* Mask value for bit 7 */ -#define MASK_08 0x00000100 /* Mask value for bit 8 */ -#define MASK_09 0x00000200 /* Mask value for bit 9 */ -#define MASK_10 0x00000400 /* Mask value for bit 10 */ -#define MASK_11 0x00000800 /* Mask value for bit 11 */ -#define MASK_12 0x00001000 /* Mask value for bit 12 */ -#define MASK_13 0x00002000 /* Mask value for bit 13 */ -#define MASK_14 0x00004000 /* Mask value for bit 14 */ -#define MASK_15 0x00008000 /* Mask value for bit 15 */ -#define MASK_16 0x00010000 /* Mask value for bit 16 */ -#define MASK_17 0x00020000 /* Mask value for bit 17 */ -#define MASK_18 0x00040000 /* Mask value for bit 18 */ -#define MASK_19 0x00080000 /* Mask value for bit 19 */ -#define MASK_20 0x00100000 /* Mask value for bit 20 */ -#define MASK_21 0x00200000 /* Mask value for bit 21 */ -#define MASK_22 0x00400000 /* Mask value for bit 22 */ -#define MASK_23 0x00800000 /* Mask value for bit 23 */ -#define MASK_24 0x01000000 /* Mask value for bit 24 */ -#define MASK_25 0x02000000 /* Mask value for bit 25 */ -#define MASK_26 0x04000000 /* Mask value for bit 26 */ -#define MASK_27 0x08000000 /* Mask value for bit 27 */ -#define MASK_28 0x10000000 /* Mask value for bit 28 */ -#define MASK_29 0x20000000 /* Mask value for bit 29 */ -#define MASK_30 0x40000000 /* Mask value for bit 30 */ -#define MASK_31 0x80000000 /* Mask value for bit 31 */ - -#define MASK_B0 0x000000ff /* Mask value for byte 0 */ -#define MASK_B1 0x0000ff00 /* Mask value for byte 1 */ -#define MASK_B2 0x00ff0000 /* Mask value for byte 2 */ -#define MASK_B3 0xff000000 /* Mask value for byte 3 */ - -#define MASK_W0 0x0000ffff /* Mask value for word 0 */ -#define MASK_W1 0xffff0000 /* Mask value for word 1 */ - -#define MASK_PA 0xfffffffc /* Mask value for physical address */ -#define MASK_PR 0xfffffffe /* Mask value for protection register */ -#define MASK_ER 0xffffffff /* Mask value for the entire register */ - -#define MASK_NONE 0x00000000 /* No mask */ - -/* register aliases */ -#define BASE_ODD1 0x00 /* Video DMA 1 registers */ -#define BASE_EVEN1 0x04 -#define PROT_ADDR1 0x08 -#define PITCH1 0x0C -#define BASE_PAGE1 0x10 /* Video DMA 1 base page */ -#define NUM_LINE_BYTE1 0x14 - -#define BASE_ODD2 0x18 /* Video DMA 2 registers */ -#define BASE_EVEN2 0x1C -#define PROT_ADDR2 0x20 -#define PITCH2 0x24 -#define BASE_PAGE2 0x28 /* Video DMA 2 base page */ -#define NUM_LINE_BYTE2 0x2C - -#define BASE_ODD3 0x30 /* Video DMA 3 registers */ -#define BASE_EVEN3 0x34 -#define PROT_ADDR3 0x38 -#define PITCH3 0x3C -#define BASE_PAGE3 0x40 /* Video DMA 3 base page */ -#define NUM_LINE_BYTE3 0x44 - -#define PCI_BT_V1 0x48 /* Video/FIFO 1 */ -#define PCI_BT_V2 0x49 /* Video/FIFO 2 */ -#define PCI_BT_V3 0x4A /* Video/FIFO 3 */ -#define PCI_BT_DEBI 0x4B /* DEBI */ -#define PCI_BT_A 0x4C /* Audio */ - -#define DD1_INIT 0x50 /* Init setting of DD1 interface */ - -#define DD1_STREAM_B 0x54 /* DD1 B video data stream handling */ -#define DD1_STREAM_A 0x56 /* DD1 A video data stream handling */ - -#define BRS_CTRL 0x58 /* BRS control register */ -#define HPS_CTRL 0x5C /* HPS control register */ -#define HPS_V_SCALE 0x60 /* HPS vertical scale */ -#define HPS_V_GAIN 0x64 /* HPS vertical ACL and gain */ -#define HPS_H_PRESCALE 0x68 /* HPS horizontal prescale */ -#define HPS_H_SCALE 0x6C /* HPS horizontal scale */ -#define BCS_CTRL 0x70 /* BCS control */ -#define CHROMA_KEY_RANGE 0x74 -#define CLIP_FORMAT_CTRL 0x78 /* HPS outputs formats & clipping */ - -#define DEBI_CONFIG 0x7C -#define DEBI_COMMAND 0x80 -#define DEBI_PAGE 0x84 -#define DEBI_AD 0x88 - -#define I2C_TRANSFER 0x8C -#define I2C_STATUS 0x90 - -#define BASE_A1_IN 0x94 /* Audio 1 input DMA */ -#define PROT_A1_IN 0x98 -#define PAGE_A1_IN 0x9C - -#define BASE_A1_OUT 0xA0 /* Audio 1 output DMA */ -#define PROT_A1_OUT 0xA4 -#define PAGE_A1_OUT 0xA8 - -#define BASE_A2_IN 0xAC /* Audio 2 input DMA */ -#define PROT_A2_IN 0xB0 -#define PAGE_A2_IN 0xB4 - -#define BASE_A2_OUT 0xB8 /* Audio 2 output DMA */ -#define PROT_A2_OUT 0xBC -#define PAGE_A2_OUT 0xC0 - -#define RPS_PAGE0 0xC4 /* RPS task 0 page register */ -#define RPS_PAGE1 0xC8 /* RPS task 1 page register */ - -#define RPS_THRESH0 0xCC /* HBI threshold for task 0 */ -#define RPS_THRESH1 0xD0 /* HBI threshold for task 1 */ - -#define RPS_TOV0 0xD4 /* RPS timeout for task 0 */ -#define RPS_TOV1 0xD8 /* RPS timeout for task 1 */ - -#define IER 0xDC /* Interrupt enable register */ - -#define GPIO_CTRL 0xE0 /* GPIO 0-3 register */ - -#define EC1SSR 0xE4 /* Event cnt set 1 source select */ -#define EC2SSR 0xE8 /* Event cnt set 2 source select */ -#define ECT1R 0xEC /* Event cnt set 1 thresholds */ -#define ECT2R 0xF0 /* Event cnt set 2 thresholds */ - -#define ACON1 0xF4 -#define ACON2 0xF8 - -#define MC1 0xFC /* Main control register 1 */ -#define MC2 0x100 /* Main control register 2 */ - -#define RPS_ADDR0 0x104 /* RPS task 0 address register */ -#define RPS_ADDR1 0x108 /* RPS task 1 address register */ - -#define ISR 0x10C /* Interrupt status register */ -#define PSR 0x110 /* Primary status register */ -#define SSR 0x114 /* Secondary status register */ - -#define EC1R 0x118 /* Event counter set 1 register */ -#define EC2R 0x11C /* Event counter set 2 register */ - -#define PCI_VDP1 0x120 /* Video DMA pointer of FIFO 1 */ -#define PCI_VDP2 0x124 /* Video DMA pointer of FIFO 2 */ -#define PCI_VDP3 0x128 /* Video DMA pointer of FIFO 3 */ -#define PCI_ADP1 0x12C /* Audio DMA pointer of audio out 1 */ -#define PCI_ADP2 0x130 /* Audio DMA pointer of audio in 1 */ -#define PCI_ADP3 0x134 /* Audio DMA pointer of audio out 2 */ -#define PCI_ADP4 0x138 /* Audio DMA pointer of audio in 2 */ -#define PCI_DMA_DDP 0x13C /* DEBI DMA pointer */ - -#define LEVEL_REP 0x140, -#define A_TIME_SLOT1 0x180, /* from 180 - 1BC */ -#define A_TIME_SLOT2 0x1C0, /* from 1C0 - 1FC */ - -/* isr masks */ -#define SPCI_PPEF 0x80000000 /* PCI parity error */ -#define SPCI_PABO 0x40000000 /* PCI access error (target or master abort) */ -#define SPCI_PPED 0x20000000 /* PCI parity error on 'real time data' */ -#define SPCI_RPS_I1 0x10000000 /* Interrupt issued by RPS1 */ -#define SPCI_RPS_I0 0x08000000 /* Interrupt issued by RPS0 */ -#define SPCI_RPS_LATE1 0x04000000 /* RPS task 1 is late */ -#define SPCI_RPS_LATE0 0x02000000 /* RPS task 0 is late */ -#define SPCI_RPS_E1 0x01000000 /* RPS error from task 1 */ -#define SPCI_RPS_E0 0x00800000 /* RPS error from task 0 */ -#define SPCI_RPS_TO1 0x00400000 /* RPS timeout task 1 */ -#define SPCI_RPS_TO0 0x00200000 /* RPS timeout task 0 */ -#define SPCI_UPLD 0x00100000 /* RPS in upload */ -#define SPCI_DEBI_S 0x00080000 /* DEBI status */ -#define SPCI_DEBI_E 0x00040000 /* DEBI error */ -#define SPCI_IIC_S 0x00020000 /* I2C status */ -#define SPCI_IIC_E 0x00010000 /* I2C error */ -#define SPCI_A2_IN 0x00008000 /* Audio 2 input DMA protection / limit */ -#define SPCI_A2_OUT 0x00004000 /* Audio 2 output DMA protection / limit */ -#define SPCI_A1_IN 0x00002000 /* Audio 1 input DMA protection / limit */ -#define SPCI_A1_OUT 0x00001000 /* Audio 1 output DMA protection / limit */ -#define SPCI_AFOU 0x00000800 /* Audio FIFO over- / underflow */ -#define SPCI_V_PE 0x00000400 /* Video protection address */ -#define SPCI_VFOU 0x00000200 /* Video FIFO over- / underflow */ -#define SPCI_FIDA 0x00000100 /* Field ID video port A */ -#define SPCI_FIDB 0x00000080 /* Field ID video port B */ -#define SPCI_PIN3 0x00000040 /* GPIO pin 3 */ -#define SPCI_PIN2 0x00000020 /* GPIO pin 2 */ -#define SPCI_PIN1 0x00000010 /* GPIO pin 1 */ -#define SPCI_PIN0 0x00000008 /* GPIO pin 0 */ -#define SPCI_ECS 0x00000004 /* Event counter 1, 2, 4, 5 */ -#define SPCI_EC3S 0x00000002 /* Event counter 3 */ -#define SPCI_EC0S 0x00000001 /* Event counter 0 */ - -/* i2c */ -#define SAA7146_I2C_ABORT (1<<7) -#define SAA7146_I2C_SPERR (1<<6) -#define SAA7146_I2C_APERR (1<<5) -#define SAA7146_I2C_DTERR (1<<4) -#define SAA7146_I2C_DRERR (1<<3) -#define SAA7146_I2C_AL (1<<2) -#define SAA7146_I2C_ERR (1<<1) -#define SAA7146_I2C_BUSY (1<<0) - -#define SAA7146_I2C_START (0x3) -#define SAA7146_I2C_CONT (0x2) -#define SAA7146_I2C_STOP (0x1) -#define SAA7146_I2C_NOP (0x0) - -#define SAA7146_I2C_BUS_BIT_RATE_6400 (0x500) -#define SAA7146_I2C_BUS_BIT_RATE_3200 (0x100) -#define SAA7146_I2C_BUS_BIT_RATE_480 (0x400) -#define SAA7146_I2C_BUS_BIT_RATE_320 (0x600) -#define SAA7146_I2C_BUS_BIT_RATE_240 (0x700) -#define SAA7146_I2C_BUS_BIT_RATE_120 (0x000) -#define SAA7146_I2C_BUS_BIT_RATE_80 (0x200) -#define SAA7146_I2C_BUS_BIT_RATE_60 (0x300) - -static inline void SAA7146_IER_DISABLE(struct saa7146_dev *x, unsigned y) -{ - unsigned long flags; - spin_lock_irqsave(&x->int_slock, flags); - saa7146_write(x, IER, saa7146_read(x, IER) & ~y); - spin_unlock_irqrestore(&x->int_slock, flags); -} - -static inline void SAA7146_IER_ENABLE(struct saa7146_dev *x, unsigned y) -{ - unsigned long flags; - spin_lock_irqsave(&x->int_slock, flags); - saa7146_write(x, IER, saa7146_read(x, IER) | y); - spin_unlock_irqrestore(&x->int_slock, flags); -} - -#endif diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_core.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_core.c deleted file mode 100644 index da21d346b870..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_core.c +++ /dev/null @@ -1,578 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - saa7146.o - driver for generic saa7146-based hardware - - Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include "saa7146.h" - -static int saa7146_num; - -unsigned int saa7146_debug; - -module_param(saa7146_debug, uint, 0644); -MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); - -#if 0 -static void dump_registers(struct saa7146_dev* dev) -{ - int i = 0; - - pr_info(" @ %li jiffies:\n", jiffies); - for (i = 0; i <= 0x148; i += 4) - pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i)); -} -#endif - -/**************************************************************************** - * gpio and debi helper functions - ****************************************************************************/ - -void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data) -{ - u32 value = 0; - - BUG_ON(port > 3); - - value = saa7146_read(dev, GPIO_CTRL); - value &= ~(0xff << (8*port)); - value |= (data << (8*port)); - saa7146_write(dev, GPIO_CTRL, value); -} - -/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */ -static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, - unsigned long us1, unsigned long us2) -{ - unsigned long timeout; - int err; - - /* wait for registers to be programmed */ - timeout = jiffies + usecs_to_jiffies(us1); - while (1) { - err = time_after(jiffies, timeout); - if (saa7146_read(dev, MC2) & 2) - break; - if (err) { - pr_debug("%s: %s timed out while waiting for registers getting programmed\n", - dev->name, __func__); - return -ETIMEDOUT; - } - msleep(1); - } - - /* wait for transfer to complete */ - timeout = jiffies + usecs_to_jiffies(us2); - while (1) { - err = time_after(jiffies, timeout); - if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) - break; - saa7146_read(dev, MC2); - if (err) { - DEB_S("%s: %s timed out while waiting for transfer completion\n", - dev->name, __func__); - return -ETIMEDOUT; - } - msleep(1); - } - - return 0; -} - -static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev, - unsigned long us1, unsigned long us2) -{ - unsigned long loops; - - /* wait for registers to be programmed */ - loops = us1; - while (1) { - if (saa7146_read(dev, MC2) & 2) - break; - if (!loops--) { - pr_err("%s: %s timed out while waiting for registers getting programmed\n", - dev->name, __func__); - return -ETIMEDOUT; - } - udelay(1); - } - - /* wait for transfer to complete */ - loops = us2 / 5; - while (1) { - if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S)) - break; - saa7146_read(dev, MC2); - if (!loops--) { - DEB_S("%s: %s timed out while waiting for transfer completion\n", - dev->name, __func__); - return -ETIMEDOUT; - } - udelay(5); - } - - return 0; -} - -int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop) -{ - if (nobusyloop) - return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000); - else - return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000); -} - -/**************************************************************************** - * general helper functions - ****************************************************************************/ - -/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c - make sure virt has been allocated with vmalloc_32(), otherwise the BUG() - may be triggered on highmem machines */ -static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) -{ - struct scatterlist *sglist; - struct page *pg; - int i; - - sglist = kmalloc_array(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); - if (NULL == sglist) - return NULL; - sg_init_table(sglist, nr_pages); - for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) { - pg = vmalloc_to_page(virt); - if (NULL == pg) - goto err; - BUG_ON(PageHighMem(pg)); - sg_set_page(&sglist[i], pg, PAGE_SIZE, 0); - } - return sglist; - - err: - kfree(sglist); - return NULL; -} - -/********************************************************************************/ -/* common page table functions */ - -void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt) -{ - int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; - void *mem = vmalloc_32(length); - int slen = 0; - - if (NULL == mem) - goto err_null; - - if (!(pt->slist = vmalloc_to_sg(mem, pages))) - goto err_free_mem; - - if (saa7146_pgtable_alloc(pci, pt)) - goto err_free_slist; - - pt->nents = pages; - slen = dma_map_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE); - if (0 == slen) - goto err_free_pgtable; - - if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen)) - goto err_unmap_sg; - - return mem; - -err_unmap_sg: - dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE); -err_free_pgtable: - saa7146_pgtable_free(pci, pt); -err_free_slist: - kfree(pt->slist); - pt->slist = NULL; -err_free_mem: - vfree(mem); -err_null: - return NULL; -} - -void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt) -{ - dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE); - saa7146_pgtable_free(pci, pt); - kfree(pt->slist); - pt->slist = NULL; - vfree(mem); -} - -void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) -{ - if (NULL == pt->cpu) - return; - dma_free_coherent(&pci->dev, pt->size, pt->cpu, pt->dma); - pt->cpu = NULL; -} - -int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) -{ - __le32 *cpu; - dma_addr_t dma_addr = 0; - - cpu = dma_alloc_coherent(&pci->dev, PAGE_SIZE, &dma_addr, GFP_KERNEL); - if (NULL == cpu) { - return -ENOMEM; - } - pt->size = PAGE_SIZE; - pt->cpu = cpu; - pt->dma = dma_addr; - - return 0; -} - -int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, - struct scatterlist *list, int sglen ) -{ - __le32 *ptr, fill; - int nr_pages = 0; - int i,p; - - BUG_ON(0 == sglen); - BUG_ON(list->offset > PAGE_SIZE); - - /* if we have a user buffer, the first page may not be - aligned to a page boundary. */ - pt->offset = list->offset; - - ptr = pt->cpu; - for (i = 0; i < sglen; i++, list++) { -/* - pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n", - i, sg_dma_address(list), sg_dma_len(list), - list->offset); -*/ - for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr++) { - *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096); - nr_pages++; - } - } - - - /* safety; fill the page table up with the last valid page */ - fill = *(ptr-1); - for(i=nr_pages;i<1024;i++) { - *ptr++ = fill; - } - -/* - ptr = pt->cpu; - pr_debug("offset: %d\n", pt->offset); - for(i=0;i<5;i++) { - pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]); - } -*/ - return 0; -} - -/********************************************************************************/ -/* interrupt handler */ -static irqreturn_t interrupt_hw(int irq, void *dev_id) -{ - struct saa7146_dev *dev = dev_id; - u32 isr; - u32 ack_isr; - - /* read out the interrupt status register */ - ack_isr = isr = saa7146_read(dev, ISR); - - /* is this our interrupt? */ - if ( 0 == isr ) { - /* nope, some other device */ - return IRQ_NONE; - } - - if (dev->ext) { - if (dev->ext->irq_mask & isr) { - if (dev->ext->irq_func) - dev->ext->irq_func(dev, &isr); - isr &= ~dev->ext->irq_mask; - } - } - if (0 != (isr & (MASK_27))) { - DEB_INT("irq: RPS0 (0x%08x)\n", isr); - if (dev->vv_data && dev->vv_callback) - dev->vv_callback(dev,isr); - isr &= ~MASK_27; - } - if (0 != (isr & (MASK_28))) { - if (dev->vv_data && dev->vv_callback) - dev->vv_callback(dev,isr); - isr &= ~MASK_28; - } - if (0 != (isr & (MASK_16|MASK_17))) { - SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); - /* only wake up if we expect something */ - if (0 != dev->i2c_op) { - dev->i2c_op = 0; - wake_up(&dev->i2c_wq); - } else { - u32 psr = saa7146_read(dev, PSR); - u32 ssr = saa7146_read(dev, SSR); - pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n", - dev->name, isr, psr, ssr); - } - isr &= ~(MASK_16|MASK_17); - } - if( 0 != isr ) { - ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n", - isr); - ERR("disabling interrupt source(s)!\n"); - SAA7146_IER_DISABLE(dev,isr); - } - saa7146_write(dev, ISR, ack_isr); - return IRQ_HANDLED; -} - -/*********************************************************************************/ -/* configuration-functions */ - -static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent) -{ - struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data; - struct saa7146_extension *ext = pci_ext->ext; - struct saa7146_dev *dev; - int err = -ENOMEM; - - /* clear out mem for sure */ - dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL); - if (!dev) { - ERR("out of memory\n"); - goto out; - } - - /* create a nice device name */ - sprintf(dev->name, "saa7146 (%d)", saa7146_num); - - DEB_EE("pci:%p\n", pci); - - err = pci_enable_device(pci); - if (err < 0) { - ERR("pci_enable_device() failed\n"); - goto err_free; - } - - /* enable bus-mastering */ - pci_set_master(pci); - - dev->pci = pci; - - /* get chip-revision; this is needed to enable bug-fixes */ - dev->revision = pci->revision; - - /* remap the memory from virtual to physical address */ - - err = pci_request_region(pci, 0, "saa7146"); - if (err < 0) - goto err_disable; - - dev->mem = ioremap(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); - if (!dev->mem) { - ERR("ioremap() failed\n"); - err = -ENODEV; - goto err_release; - } - - /* we don't do a master reset here anymore, it screws up - some boards that don't have an i2c-eeprom for configuration - values */ -/* - saa7146_write(dev, MC1, MASK_31); -*/ - - /* disable all irqs */ - saa7146_write(dev, IER, 0); - - /* shut down all dma transfers and rps tasks */ - saa7146_write(dev, MC1, 0x30ff0000); - - /* clear out any rps-signals pending */ - saa7146_write(dev, MC2, 0xf8000000); - - /* request an interrupt for the saa7146 */ - err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED, - dev->name, dev); - if (err < 0) { - ERR("request_irq() failed\n"); - goto err_unmap; - } - - err = -ENOMEM; - - /* get memory for various stuff */ - dev->d_rps0.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM, - &dev->d_rps0.dma_handle, - GFP_KERNEL); - if (!dev->d_rps0.cpu_addr) - goto err_free_irq; - - dev->d_rps1.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM, - &dev->d_rps1.dma_handle, - GFP_KERNEL); - if (!dev->d_rps1.cpu_addr) - goto err_free_rps0; - - dev->d_i2c.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM, - &dev->d_i2c.dma_handle, GFP_KERNEL); - if (!dev->d_i2c.cpu_addr) - goto err_free_rps1; - - /* the rest + print status message */ - - pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n", - dev->mem, dev->revision, pci->irq, - pci->subsystem_vendor, pci->subsystem_device); - dev->ext = ext; - - mutex_init(&dev->v4l2_lock); - spin_lock_init(&dev->int_slock); - spin_lock_init(&dev->slock); - - mutex_init(&dev->i2c_lock); - - dev->module = THIS_MODULE; - init_waitqueue_head(&dev->i2c_wq); - - /* set some sane pci arbitrition values */ - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - - /* TODO: use the status code of the callback */ - - err = -ENODEV; - - if (ext->probe && ext->probe(dev)) { - DEB_D("ext->probe() failed for %p. skipping device.\n", dev); - goto err_free_i2c; - } - - if (ext->attach(dev, pci_ext)) { - DEB_D("ext->attach() failed for %p. skipping device.\n", dev); - goto err_free_i2c; - } - /* V4L extensions will set the pci drvdata to the v4l2_device in the - attach() above. So for those cards that do not use V4L we have to - set it explicitly. */ - pci_set_drvdata(pci, &dev->v4l2_dev); - - saa7146_num++; - - err = 0; -out: - return err; - -err_free_i2c: - dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, - dev->d_i2c.dma_handle); -err_free_rps1: - dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, - dev->d_rps1.dma_handle); -err_free_rps0: - dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, - dev->d_rps0.dma_handle); -err_free_irq: - free_irq(pci->irq, (void *)dev); -err_unmap: - iounmap(dev->mem); -err_release: - pci_release_region(pci, 0); -err_disable: - pci_disable_device(pci); -err_free: - kfree(dev); - goto out; -} - -static void saa7146_remove_one(struct pci_dev *pdev) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); - struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); - struct { - void *addr; - dma_addr_t dma; - } dev_map[] = { - { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle }, - { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle }, - { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle }, - { NULL, 0 } - }, *p; - - DEB_EE("dev:%p\n", dev); - - dev->ext->detach(dev); - - /* shut down all video dma transfers */ - saa7146_write(dev, MC1, 0x00ff0000); - - /* disable all irqs, release irq-routine */ - saa7146_write(dev, IER, 0); - - free_irq(pdev->irq, dev); - - for (p = dev_map; p->addr; p++) - dma_free_coherent(&pdev->dev, SAA7146_RPS_MEM, p->addr, - p->dma); - - iounmap(dev->mem); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - kfree(dev); - - saa7146_num--; -} - -/*********************************************************************************/ -/* extension handling functions */ - -int saa7146_register_extension(struct saa7146_extension* ext) -{ - DEB_EE("ext:%p\n", ext); - - ext->driver.name = ext->name; - ext->driver.id_table = ext->pci_tbl; - ext->driver.probe = saa7146_init_one; - ext->driver.remove = saa7146_remove_one; - - pr_info("register extension '%s'\n", ext->name); - return pci_register_driver(&ext->driver); -} - -int saa7146_unregister_extension(struct saa7146_extension* ext) -{ - DEB_EE("ext:%p\n", ext); - pr_info("unregister extension '%s'\n", ext->name); - pci_unregister_driver(&ext->driver); - return 0; -} - -EXPORT_SYMBOL_GPL(saa7146_register_extension); -EXPORT_SYMBOL_GPL(saa7146_unregister_extension); - -/* misc functions used by extension modules */ -EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc); -EXPORT_SYMBOL_GPL(saa7146_pgtable_free); -EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single); -EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable); -EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable); -EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done); - -EXPORT_SYMBOL_GPL(saa7146_setgpio); - -EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare); - -EXPORT_SYMBOL_GPL(saa7146_debug); - -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); -MODULE_DESCRIPTION("driver for generic saa7146-based hardware"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c deleted file mode 100644 index aa14698a9c54..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_fops.c +++ /dev/null @@ -1,658 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include "saa7146_vv.h" - -/****************************************************************************/ -/* resource management functions, shamelessly stolen from saa7134 driver */ - -int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - - if (fh->resources & bit) { - DEB_D("already allocated! want: 0x%02x, cur:0x%02x\n", - bit, vv->resources); - /* have it already allocated */ - return 1; - } - - /* is it free? */ - if (vv->resources & bit) { - DEB_D("locked! vv->resources:0x%02x, we want:0x%02x\n", - vv->resources, bit); - /* no, someone else uses it */ - return 0; - } - /* it's free, grab it */ - fh->resources |= bit; - vv->resources |= bit; - DEB_D("res: get 0x%02x, cur:0x%02x\n", bit, vv->resources); - return 1; -} - -void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - - BUG_ON((fh->resources & bits) != bits); - - fh->resources &= ~bits; - vv->resources &= ~bits; - DEB_D("res: put 0x%02x, cur:0x%02x\n", bits, vv->resources); -} - - -/********************************************************************************/ -/* common dma functions */ - -void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q, - struct saa7146_buf *buf) -{ - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - DEB_EE("dev:%p, buf:%p\n", dev, buf); - - videobuf_waiton(q, &buf->vb, 0, 0); - videobuf_dma_unmap(q->dev, dma); - videobuf_dma_free(dma); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - - -/********************************************************************************/ -/* common buffer functions */ - -int saa7146_buffer_queue(struct saa7146_dev *dev, - struct saa7146_dmaqueue *q, - struct saa7146_buf *buf) -{ - assert_spin_locked(&dev->slock); - DEB_EE("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf); - - BUG_ON(!q); - - if (NULL == q->curr) { - q->curr = buf; - DEB_D("immediately activating buffer %p\n", buf); - buf->activate(dev,buf,NULL); - } else { - list_add_tail(&buf->vb.queue,&q->queue); - buf->vb.state = VIDEOBUF_QUEUED; - DEB_D("adding buffer %p to queue. (active buffer present)\n", - buf); - } - return 0; -} - -void saa7146_buffer_finish(struct saa7146_dev *dev, - struct saa7146_dmaqueue *q, - int state) -{ - assert_spin_locked(&dev->slock); - DEB_EE("dev:%p, dmaq:%p, state:%d\n", dev, q, state); - DEB_EE("q->curr:%p\n", q->curr); - - /* finish current buffer */ - if (NULL == q->curr) { - DEB_D("aiii. no current buffer\n"); - return; - } - - q->curr->vb.state = state; - q->curr->vb.ts = ktime_get_ns(); - wake_up(&q->curr->vb.done); - - q->curr = NULL; -} - -void saa7146_buffer_next(struct saa7146_dev *dev, - struct saa7146_dmaqueue *q, int vbi) -{ - struct saa7146_buf *buf,*next = NULL; - - BUG_ON(!q); - - DEB_INT("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi); - - assert_spin_locked(&dev->slock); - if (!list_empty(&q->queue)) { - /* activate next one from queue */ - buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue); - list_del(&buf->vb.queue); - if (!list_empty(&q->queue)) - next = list_entry(q->queue.next,struct saa7146_buf, vb.queue); - q->curr = buf; - DEB_INT("next buffer: buf:%p, prev:%p, next:%p\n", - buf, q->queue.prev, q->queue.next); - buf->activate(dev,buf,next); - } else { - DEB_INT("no next buffer. stopping.\n"); - if( 0 != vbi ) { - /* turn off video-dma3 */ - saa7146_write(dev,MC1, MASK_20); - } else { - /* nothing to do -- just prevent next video-dma1 transfer - by lowering the protection address */ - - // fixme: fix this for vflip != 0 - - saa7146_write(dev, PROT_ADDR1, 0); - saa7146_write(dev, MC2, (MASK_02|MASK_18)); - - /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); - /* turn on rps */ - saa7146_write(dev, MC1, (MASK_12 | MASK_28)); - -/* - printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1)); - printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1)); - printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1)); - printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1)); - printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1)); - printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1)); -*/ - } - del_timer(&q->timeout); - } -} - -void saa7146_buffer_timeout(struct timer_list *t) -{ - struct saa7146_dmaqueue *q = from_timer(q, t, timeout); - struct saa7146_dev *dev = q->dev; - unsigned long flags; - - DEB_EE("dev:%p, dmaq:%p\n", dev, q); - - spin_lock_irqsave(&dev->slock,flags); - if (q->curr) { - DEB_D("timeout on %p\n", q->curr); - saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR); - } - - /* we don't restart the transfer here like other drivers do. when - a streaming capture is disabled, the timeout function will be - called for the current buffer. if we activate the next buffer now, - we mess up our capture logic. if a timeout occurs on another buffer, - then something is seriously broken before, so no need to buffer the - next capture IMHO... */ -/* - saa7146_buffer_next(dev,q); -*/ - spin_unlock_irqrestore(&dev->slock,flags); -} - -/********************************************************************************/ -/* file operations */ - -static int fops_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_dev *dev = video_drvdata(file); - struct saa7146_fh *fh = NULL; - int result = 0; - - DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); - - if (mutex_lock_interruptible(vdev->lock)) - return -ERESTARTSYS; - - DEB_D("using: %p\n", dev); - - /* check if an extension is registered */ - if( NULL == dev->ext ) { - DEB_S("no extension registered for this device\n"); - result = -ENODEV; - goto out; - } - - /* allocate per open data */ - fh = kzalloc(sizeof(*fh),GFP_KERNEL); - if (NULL == fh) { - DEB_S("cannot allocate memory for per open data\n"); - result = -ENOMEM; - goto out; - } - - v4l2_fh_init(&fh->fh, vdev); - - file->private_data = &fh->fh; - fh->dev = dev; - - if (vdev->vfl_type == VFL_TYPE_VBI) { - DEB_S("initializing vbi...\n"); - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - result = saa7146_vbi_uops.open(dev,file); - if (dev->ext_vv_data->vbi_fops.open) - dev->ext_vv_data->vbi_fops.open(file); - } else { - DEB_S("initializing video...\n"); - result = saa7146_video_uops.open(dev,file); - } - - if (0 != result) { - goto out; - } - - if( 0 == try_module_get(dev->ext->module)) { - result = -EINVAL; - goto out; - } - - result = 0; - v4l2_fh_add(&fh->fh); -out: - if (fh && result != 0) { - kfree(fh); - file->private_data = NULL; - } - mutex_unlock(vdev->lock); - return result; -} - -static int fops_release(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - - DEB_EE("file:%p\n", file); - - mutex_lock(vdev->lock); - - if (vdev->vfl_type == VFL_TYPE_VBI) { - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - saa7146_vbi_uops.release(dev,file); - if (dev->ext_vv_data->vbi_fops.release) - dev->ext_vv_data->vbi_fops.release(file); - } else { - saa7146_video_uops.release(dev,file); - } - - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - module_put(dev->ext->module); - file->private_data = NULL; - kfree(fh); - - mutex_unlock(vdev->lock); - - return 0; -} - -static int fops_mmap(struct file *file, struct vm_area_struct * vma) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_fh *fh = file->private_data; - struct videobuf_queue *q; - int res; - - switch (vdev->vfl_type) { - case VFL_TYPE_VIDEO: { - DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n", - file, vma); - q = &fh->video_q; - break; - } - case VFL_TYPE_VBI: { - DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n", - file, vma); - if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT) - return -ENODEV; - q = &fh->vbi_q; - break; - } - default: - BUG(); - } - - if (mutex_lock_interruptible(vdev->lock)) - return -ERESTARTSYS; - res = videobuf_mmap_mapper(q, vma); - mutex_unlock(vdev->lock); - return res; -} - -static __poll_t __fops_poll(struct file *file, struct poll_table_struct *wait) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_fh *fh = file->private_data; - struct videobuf_buffer *buf = NULL; - struct videobuf_queue *q; - __poll_t res = v4l2_ctrl_poll(file, wait); - - DEB_EE("file:%p, poll:%p\n", file, wait); - - if (vdev->vfl_type == VFL_TYPE_VBI) { - if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT) - return res | EPOLLOUT | EPOLLWRNORM; - if( 0 == fh->vbi_q.streaming ) - return res | videobuf_poll_stream(file, &fh->vbi_q, wait); - q = &fh->vbi_q; - } else { - DEB_D("using video queue\n"); - q = &fh->video_q; - } - - if (!list_empty(&q->stream)) - buf = list_entry(q->stream.next, struct videobuf_buffer, stream); - - if (!buf) { - DEB_D("buf == NULL!\n"); - return res | EPOLLERR; - } - - poll_wait(file, &buf->done, wait); - if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { - DEB_D("poll succeeded!\n"); - return res | EPOLLIN | EPOLLRDNORM; - } - - DEB_D("nothing to poll for, buf->state:%d\n", buf->state); - return res; -} - -static __poll_t fops_poll(struct file *file, struct poll_table_struct *wait) -{ - struct video_device *vdev = video_devdata(file); - __poll_t res; - - mutex_lock(vdev->lock); - res = __fops_poll(file, wait); - mutex_unlock(vdev->lock); - return res; -} - -static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_fh *fh = file->private_data; - int ret; - - switch (vdev->vfl_type) { - case VFL_TYPE_VIDEO: -/* - DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", - file, data, (unsigned long)count); -*/ - return saa7146_video_uops.read(file,data,count,ppos); - case VFL_TYPE_VBI: -/* - DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", - file, data, (unsigned long)count); -*/ - if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) { - if (mutex_lock_interruptible(vdev->lock)) - return -ERESTARTSYS; - ret = saa7146_vbi_uops.read(file, data, count, ppos); - mutex_unlock(vdev->lock); - return ret; - } - return -EINVAL; - default: - BUG(); - } -} - -static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) -{ - struct video_device *vdev = video_devdata(file); - struct saa7146_fh *fh = file->private_data; - int ret; - - switch (vdev->vfl_type) { - case VFL_TYPE_VIDEO: - return -EINVAL; - case VFL_TYPE_VBI: - if (fh->dev->ext_vv_data->vbi_fops.write) { - if (mutex_lock_interruptible(vdev->lock)) - return -ERESTARTSYS; - ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); - mutex_unlock(vdev->lock); - return ret; - } - return -EINVAL; - default: - BUG(); - } -} - -static const struct v4l2_file_operations video_fops = -{ - .owner = THIS_MODULE, - .open = fops_open, - .release = fops_release, - .read = fops_read, - .write = fops_write, - .poll = fops_poll, - .mmap = fops_mmap, - .unlocked_ioctl = video_ioctl2, -}; - -static void vv_callback(struct saa7146_dev *dev, unsigned long status) -{ - u32 isr = status; - - DEB_INT("dev:%p, isr:0x%08x\n", dev, (u32)status); - - if (0 != (isr & (MASK_27))) { - DEB_INT("irq: RPS0 (0x%08x)\n", isr); - saa7146_video_uops.irq_done(dev,isr); - } - - if (0 != (isr & (MASK_28))) { - u32 mc2 = saa7146_read(dev, MC2); - if( 0 != (mc2 & MASK_15)) { - DEB_INT("irq: RPS1 vbi workaround (0x%08x)\n", isr); - wake_up(&dev->vv_data->vbi_wq); - saa7146_write(dev,MC2, MASK_31); - return; - } - DEB_INT("irq: RPS1 (0x%08x)\n", isr); - saa7146_vbi_uops.irq_done(dev,isr); - } -} - -static const struct v4l2_ctrl_ops saa7146_ctrl_ops = { - .s_ctrl = saa7146_s_ctrl, -}; - -int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) -{ - struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; - struct v4l2_pix_format *fmt; - struct v4l2_vbi_format *vbi; - struct saa7146_vv *vv; - int err; - - err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); - if (err) - return err; - - v4l2_ctrl_handler_init(hdl, 6); - v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); - v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops, - V4L2_CID_CONTRAST, 0, 127, 1, 64); - v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops, - V4L2_CID_SATURATION, 0, 127, 1, 64); - v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - if (hdl->error) { - err = hdl->error; - v4l2_ctrl_handler_free(hdl); - v4l2_device_unregister(&dev->v4l2_dev); - return err; - } - dev->v4l2_dev.ctrl_handler = hdl; - - vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); - if (vv == NULL) { - ERR("out of memory. aborting.\n"); - v4l2_ctrl_handler_free(hdl); - v4l2_device_unregister(&dev->v4l2_dev); - return -ENOMEM; - } - ext_vv->vid_ops = saa7146_video_ioctl_ops; - ext_vv->vbi_ops = saa7146_vbi_ioctl_ops; - ext_vv->core_ops = &saa7146_video_ioctl_ops; - - DEB_EE("dev:%p\n", dev); - - /* set default values for video parts of the saa7146 */ - saa7146_write(dev, BCS_CTRL, 0x80400040); - - /* enable video-port pins */ - saa7146_write(dev, MC1, (MASK_10 | MASK_26)); - - /* save per-device extension data (one extension can - handle different devices that might need different - configuration data) */ - dev->ext_vv_data = ext_vv; - - vv->d_clipping.cpu_addr = - dma_alloc_coherent(&dev->pci->dev, SAA7146_CLIPPING_MEM, - &vv->d_clipping.dma_handle, GFP_KERNEL); - if( NULL == vv->d_clipping.cpu_addr ) { - ERR("out of memory. aborting.\n"); - kfree(vv); - v4l2_ctrl_handler_free(hdl); - v4l2_device_unregister(&dev->v4l2_dev); - return -ENOMEM; - } - - saa7146_video_uops.init(dev,vv); - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - saa7146_vbi_uops.init(dev,vv); - - vv->ov_fb.fmt.width = vv->standard->h_max_out; - vv->ov_fb.fmt.height = vv->standard->v_max_out; - vv->ov_fb.fmt.pixelformat = V4L2_PIX_FMT_RGB565; - vv->ov_fb.fmt.bytesperline = 2 * vv->ov_fb.fmt.width; - vv->ov_fb.fmt.sizeimage = vv->ov_fb.fmt.bytesperline * vv->ov_fb.fmt.height; - vv->ov_fb.fmt.colorspace = V4L2_COLORSPACE_SRGB; - - fmt = &vv->video_fmt; - fmt->width = 384; - fmt->height = 288; - fmt->pixelformat = V4L2_PIX_FMT_BGR24; - fmt->field = V4L2_FIELD_ANY; - fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->bytesperline = 3 * fmt->width; - fmt->sizeimage = fmt->bytesperline * fmt->height; - - vbi = &vv->vbi_fmt; - vbi->sampling_rate = 27000000; - vbi->offset = 248; /* todo */ - vbi->samples_per_line = 720 * 2; - vbi->sample_format = V4L2_PIX_FMT_GREY; - - /* fixme: this only works for PAL */ - vbi->start[0] = 5; - vbi->count[0] = 16; - vbi->start[1] = 312; - vbi->count[1] = 16; - - timer_setup(&vv->vbi_read_timeout, NULL, 0); - - vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING; - vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY; - dev->vv_data = vv; - dev->vv_callback = &vv_callback; - - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_vv_init); - -int saa7146_vv_release(struct saa7146_dev* dev) -{ - struct saa7146_vv *vv = dev->vv_data; - - DEB_EE("dev:%p\n", dev); - - v4l2_device_unregister(&dev->v4l2_dev); - dma_free_coherent(&dev->pci->dev, SAA7146_CLIPPING_MEM, - vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); - v4l2_ctrl_handler_free(&dev->ctrl_handler); - kfree(vv); - dev->vv_data = NULL; - dev->vv_callback = NULL; - - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_vv_release); - -int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev, - char *name, int type) -{ - int err; - int i; - - DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type); - - vfd->fops = &video_fops; - if (type == VFL_TYPE_VIDEO) - vfd->ioctl_ops = &dev->ext_vv_data->vid_ops; - else - vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops; - vfd->release = video_device_release_empty; - vfd->lock = &dev->v4l2_lock; - vfd->v4l2_dev = &dev->v4l2_dev; - vfd->tvnorms = 0; - for (i = 0; i < dev->ext_vv_data->num_stds; i++) - vfd->tvnorms |= dev->ext_vv_data->stds[i].id; - strscpy(vfd->name, name, sizeof(vfd->name)); - vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - vfd->device_caps |= dev->ext_vv_data->capabilities; - if (type == VFL_TYPE_VIDEO) - vfd->device_caps &= - ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT); - else - vfd->device_caps &= - ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO); - video_set_drvdata(vfd, dev); - - err = video_register_device(vfd, type, -1); - if (err < 0) { - ERR("cannot register v4l2 device. skipping.\n"); - return err; - } - - pr_info("%s: registered device %s [v4l2]\n", - dev->name, video_device_node_name(vfd)); - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_register_device); - -int saa7146_unregister_device(struct video_device *vfd, struct saa7146_dev *dev) -{ - DEB_EE("dev:%p\n", dev); - - video_unregister_device(vfd); - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_unregister_device); - -static int __init saa7146_vv_init_module(void) -{ - return 0; -} - - -static void __exit saa7146_vv_cleanup_module(void) -{ -} - -module_init(saa7146_vv_init_module); -module_exit(saa7146_vv_cleanup_module); - -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); -MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c deleted file mode 100644 index b1222a4cfa4a..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_hlp.c +++ /dev/null @@ -1,1046 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include <linux/export.h> -#include "saa7146_vv.h" - -static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format) -{ - /* clear out the necessary bits */ - *clip_format &= 0x0000ffff; - /* set these bits new */ - *clip_format |= (( ((palette&0xf00)>>8) << 30) | ((palette&0x00f) << 24) | (((palette&0x0f0)>>4) << 16)); -} - -static void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync, u32* hps_ctrl) -{ - *hps_ctrl &= ~(MASK_30 | MASK_31 | MASK_28); - *hps_ctrl |= (source << 30) | (sync << 28); -} - -static void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl) -{ - int hyo = 0, hxo = 0; - - hyo = vv->standard->v_offset; - hxo = vv->standard->h_offset; - - *hps_h_scale &= ~(MASK_B0 | 0xf00); - *hps_h_scale |= (hxo << 0); - - *hps_ctrl &= ~(MASK_W0 | MASK_B2); - *hps_ctrl |= (hyo << 12); -} - -/* helper functions for the calculation of the horizontal- and vertical - scaling registers, clip-format-register etc ... - these functions take pointers to the (most-likely read-out - original-values) and manipulate them according to the requested - changes. -*/ - -/* hps_coeff used for CXY and CXUV; scale 1/1 -> scale 1/64 */ -static struct { - u16 hps_coeff; - u16 weight_sum; -} hps_h_coeff_tab [] = { - {0x00, 2}, {0x02, 4}, {0x00, 4}, {0x06, 8}, {0x02, 8}, - {0x08, 8}, {0x00, 8}, {0x1E, 16}, {0x0E, 8}, {0x26, 8}, - {0x06, 8}, {0x42, 8}, {0x02, 8}, {0x80, 8}, {0x00, 8}, - {0xFE, 16}, {0xFE, 8}, {0x7E, 8}, {0x7E, 8}, {0x3E, 8}, - {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, {0x0E, 8}, {0x0E, 8}, - {0x06, 8}, {0x06, 8}, {0x02, 8}, {0x02, 8}, {0x00, 8}, - {0x00, 8}, {0xFE, 16}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0x7E, 8}, - {0x7E, 8}, {0x3E, 8}, {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, - {0x0E, 8}, {0x0E, 8}, {0x06, 8}, {0x06, 8}, {0x02, 8}, - {0x02, 8}, {0x00, 8}, {0x00, 8}, {0xFE, 16} -}; - -/* table of attenuation values for horizontal scaling */ -static u8 h_attenuation[] = { 1, 2, 4, 8, 2, 4, 8, 16, 0}; - -/* calculate horizontal scale registers */ -static int calculate_h_scale_registers(struct saa7146_dev *dev, - int in_x, int out_x, int flip_lr, - u32* hps_ctrl, u32* hps_v_gain, u32* hps_h_prescale, u32* hps_h_scale) -{ - /* horizontal prescaler */ - u32 dcgx = 0, xpsc = 0, xacm = 0, cxy = 0, cxuv = 0; - /* horizontal scaler */ - u32 xim = 0, xp = 0, xsci =0; - /* vertical scale & gain */ - u32 pfuv = 0; - - /* helper variables */ - u32 h_atten = 0, i = 0; - - if ( 0 == out_x ) { - return -EINVAL; - } - - /* mask out vanity-bit */ - *hps_ctrl &= ~MASK_29; - - /* calculate prescale-(xspc)-value: [n .. 1/2) : 1 - [1/2 .. 1/3) : 2 - [1/3 .. 1/4) : 3 - ... */ - if (in_x > out_x) { - xpsc = in_x / out_x; - } - else { - /* zooming */ - xpsc = 1; - } - - /* if flip_lr-bit is set, number of pixels after - horizontal prescaling must be < 384 */ - if ( 0 != flip_lr ) { - - /* set vanity bit */ - *hps_ctrl |= MASK_29; - - while (in_x / xpsc >= 384 ) - xpsc++; - } - /* if zooming is wanted, number of pixels after - horizontal prescaling must be < 768 */ - else { - while ( in_x / xpsc >= 768 ) - xpsc++; - } - - /* maximum prescale is 64 (p.69) */ - if ( xpsc > 64 ) - xpsc = 64; - - /* keep xacm clear*/ - xacm = 0; - - /* set horizontal filter parameters (CXY = CXUV) */ - cxy = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].hps_coeff; - cxuv = cxy; - - /* calculate and set horizontal fine scale (xsci) */ - - /* bypass the horizontal scaler ? */ - if ( (in_x == out_x) && ( 1 == xpsc ) ) - xsci = 0x400; - else - xsci = ( (1024 * in_x) / (out_x * xpsc) ) + xpsc; - - /* set start phase for horizontal fine scale (xp) to 0 */ - xp = 0; - - /* set xim, if we bypass the horizontal scaler */ - if ( 0x400 == xsci ) - xim = 1; - else - xim = 0; - - /* if the prescaler is bypassed, enable horizontal - accumulation mode (xacm) and clear dcgx */ - if( 1 == xpsc ) { - xacm = 1; - dcgx = 0; - } else { - xacm = 0; - /* get best match in the table of attenuations - for horizontal scaling */ - h_atten = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].weight_sum; - - for (i = 0; h_attenuation[i] != 0; i++) { - if (h_attenuation[i] >= h_atten) - break; - } - - dcgx = i; - } - - /* the horizontal scaling increment controls the UV filter - to reduce the bandwidth to improve the display quality, - so set it ... */ - if ( xsci == 0x400) - pfuv = 0x00; - else if ( xsci < 0x600) - pfuv = 0x01; - else if ( xsci < 0x680) - pfuv = 0x11; - else if ( xsci < 0x700) - pfuv = 0x22; - else - pfuv = 0x33; - - - *hps_v_gain &= MASK_W0|MASK_B2; - *hps_v_gain |= (pfuv << 24); - - *hps_h_scale &= ~(MASK_W1 | 0xf000); - *hps_h_scale |= (xim << 31) | (xp << 24) | (xsci << 12); - - *hps_h_prescale |= (dcgx << 27) | ((xpsc-1) << 18) | (xacm << 17) | (cxy << 8) | (cxuv << 0); - - return 0; -} - -static struct { - u16 hps_coeff; - u16 weight_sum; -} hps_v_coeff_tab [] = { - {0x0100, 2}, {0x0102, 4}, {0x0300, 4}, {0x0106, 8}, {0x0502, 8}, - {0x0708, 8}, {0x0F00, 8}, {0x011E, 16}, {0x110E, 16}, {0x1926, 16}, - {0x3906, 16}, {0x3D42, 16}, {0x7D02, 16}, {0x7F80, 16}, {0xFF00, 16}, - {0x01FE, 32}, {0x01FE, 32}, {0x817E, 32}, {0x817E, 32}, {0xC13E, 32}, - {0xC13E, 32}, {0xE11E, 32}, {0xE11E, 32}, {0xF10E, 32}, {0xF10E, 32}, - {0xF906, 32}, {0xF906, 32}, {0xFD02, 32}, {0xFD02, 32}, {0xFF00, 32}, - {0xFF00, 32}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x817E, 64}, - {0x817E, 64}, {0xC13E, 64}, {0xC13E, 64}, {0xE11E, 64}, {0xE11E, 64}, - {0xF10E, 64}, {0xF10E, 64}, {0xF906, 64}, {0xF906, 64}, {0xFD02, 64}, - {0xFD02, 64}, {0xFF00, 64}, {0xFF00, 64}, {0x01FE, 128} -}; - -/* table of attenuation values for vertical scaling */ -static u16 v_attenuation[] = { 2, 4, 8, 16, 32, 64, 128, 256, 0}; - -/* calculate vertical scale registers */ -static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field field, - int in_y, int out_y, u32* hps_v_scale, u32* hps_v_gain) -{ - int lpi = 0; - - /* vertical scaling */ - u32 yacm = 0, ysci = 0, yacl = 0, ypo = 0, ype = 0; - /* vertical scale & gain */ - u32 dcgy = 0, cya_cyb = 0; - - /* helper variables */ - u32 v_atten = 0, i = 0; - - /* error, if vertical zooming */ - if ( in_y < out_y ) { - return -EINVAL; - } - - /* linear phase interpolation may be used - if scaling is between 1 and 1/2 (both fields used) - or scaling is between 1/2 and 1/4 (if only one field is used) */ - - if (V4L2_FIELD_HAS_BOTH(field)) { - if( 2*out_y >= in_y) { - lpi = 1; - } - } else if (field == V4L2_FIELD_TOP - || field == V4L2_FIELD_ALTERNATE - || field == V4L2_FIELD_BOTTOM) { - if( 4*out_y >= in_y ) { - lpi = 1; - } - out_y *= 2; - } - if( 0 != lpi ) { - - yacm = 0; - yacl = 0; - cya_cyb = 0x00ff; - - /* calculate scaling increment */ - if ( in_y > out_y ) - ysci = ((1024 * in_y) / (out_y + 1)) - 1024; - else - ysci = 0; - - dcgy = 0; - - /* calculate ype and ypo */ - ype = ysci / 16; - ypo = ype + (ysci / 64); - - } else { - yacm = 1; - - /* calculate scaling increment */ - ysci = (((10 * 1024 * (in_y - out_y - 1)) / in_y) + 9) / 10; - - /* calculate ype and ypo */ - ypo = ype = ((ysci + 15) / 16); - - /* the sequence length interval (yacl) has to be set according - to the prescale value, e.g. [n .. 1/2) : 0 - [1/2 .. 1/3) : 1 - [1/3 .. 1/4) : 2 - ... */ - if ( ysci < 512) { - yacl = 0; - } else { - yacl = ( ysci / (1024 - ysci) ); - } - - /* get filter coefficients for cya, cyb from table hps_v_coeff_tab */ - cya_cyb = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].hps_coeff; - - /* get best match in the table of attenuations for vertical scaling */ - v_atten = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].weight_sum; - - for (i = 0; v_attenuation[i] != 0; i++) { - if (v_attenuation[i] >= v_atten) - break; - } - - dcgy = i; - } - - /* ypo and ype swapped in spec ? */ - *hps_v_scale |= (yacm << 31) | (ysci << 21) | (yacl << 15) | (ypo << 8 ) | (ype << 1); - - *hps_v_gain &= ~(MASK_W0|MASK_B2); - *hps_v_gain |= (dcgy << 16) | (cya_cyb << 0); - - return 0; -} - -/* simple bubble-sort algorithm with duplicate elimination */ -static int sort_and_eliminate(u32* values, int* count) -{ - int low = 0, high = 0, top = 0; - int cur = 0, next = 0; - - /* sanity checks */ - if( (0 > *count) || (NULL == values) ) { - return -EINVAL; - } - - /* bubble sort the first @count items of the array @values */ - for( top = *count; top > 0; top--) { - for( low = 0, high = 1; high < top; low++, high++) { - if( values[low] > values[high] ) - swap(values[low], values[high]); - } - } - - /* remove duplicate items */ - for( cur = 0, next = 1; next < *count; next++) { - if( values[cur] != values[next]) - values[++cur] = values[next]; - } - - *count = cur + 1; - - return 0; -} - -static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh, - struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field) -{ - struct saa7146_vv *vv = dev->vv_data; - __le32 *clipping = vv->d_clipping.cpu_addr; - - int width = vv->ov.win.w.width; - int height = vv->ov.win.w.height; - int clipcount = vv->ov.nclips; - - u32 line_list[32]; - u32 pixel_list[32]; - int numdwords = 0; - - int i = 0, j = 0; - int cnt_line = 0, cnt_pixel = 0; - - int x[32], y[32], w[32], h[32]; - - /* clear out memory */ - memset(&line_list[0], 0x00, sizeof(u32)*32); - memset(&pixel_list[0], 0x00, sizeof(u32)*32); - memset(clipping, 0x00, SAA7146_CLIPPING_MEM); - - /* fill the line and pixel-lists */ - for(i = 0; i < clipcount; i++) { - int l = 0, r = 0, t = 0, b = 0; - - x[i] = vv->ov.clips[i].c.left; - y[i] = vv->ov.clips[i].c.top; - w[i] = vv->ov.clips[i].c.width; - h[i] = vv->ov.clips[i].c.height; - - if( w[i] < 0) { - x[i] += w[i]; w[i] = -w[i]; - } - if( h[i] < 0) { - y[i] += h[i]; h[i] = -h[i]; - } - if( x[i] < 0) { - w[i] += x[i]; x[i] = 0; - } - if( y[i] < 0) { - h[i] += y[i]; y[i] = 0; - } - if( 0 != vv->vflip ) { - y[i] = height - y[i] - h[i]; - } - - l = x[i]; - r = x[i]+w[i]; - t = y[i]; - b = y[i]+h[i]; - - /* insert left/right coordinates */ - pixel_list[ 2*i ] = min_t(int, l, width); - pixel_list[(2*i)+1] = min_t(int, r, width); - /* insert top/bottom coordinates */ - line_list[ 2*i ] = min_t(int, t, height); - line_list[(2*i)+1] = min_t(int, b, height); - } - - /* sort and eliminate lists */ - cnt_line = cnt_pixel = 2*clipcount; - sort_and_eliminate( &pixel_list[0], &cnt_pixel ); - sort_and_eliminate( &line_list[0], &cnt_line ); - - /* calculate the number of used u32s */ - numdwords = max_t(int, (cnt_line+1), (cnt_pixel+1))*2; - numdwords = max_t(int, 4, numdwords); - numdwords = min_t(int, 64, numdwords); - - /* fill up cliptable */ - for(i = 0; i < cnt_pixel; i++) { - clipping[2*i] |= cpu_to_le32(pixel_list[i] << 16); - } - for(i = 0; i < cnt_line; i++) { - clipping[(2*i)+1] |= cpu_to_le32(line_list[i] << 16); - } - - /* fill up cliptable with the display infos */ - for(j = 0; j < clipcount; j++) { - - for(i = 0; i < cnt_pixel; i++) { - - if( x[j] < 0) - x[j] = 0; - - if( pixel_list[i] < (x[j] + w[j])) { - - if ( pixel_list[i] >= x[j] ) { - clipping[2*i] |= cpu_to_le32(1 << j); - } - } - } - for(i = 0; i < cnt_line; i++) { - - if( y[j] < 0) - y[j] = 0; - - if( line_list[i] < (y[j] + h[j]) ) { - - if( line_list[i] >= y[j] ) { - clipping[(2*i)+1] |= cpu_to_le32(1 << j); - } - } - } - } - - /* adjust arbitration control register */ - *arbtr_ctrl &= 0xffff00ff; - *arbtr_ctrl |= 0x00001c00; - - vdma2->base_even = vv->d_clipping.dma_handle; - vdma2->base_odd = vv->d_clipping.dma_handle; - vdma2->prot_addr = vv->d_clipping.dma_handle+((sizeof(u32))*(numdwords)); - vdma2->base_page = 0x04; - vdma2->pitch = 0x00; - vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) ); - - /* set clipping-mode. this depends on the field(s) used */ - *clip_format &= 0xfffffff7; - if (V4L2_FIELD_HAS_BOTH(field)) { - *clip_format |= 0x00000008; - } else { - *clip_format |= 0x00000000; - } -} - -/* disable clipping */ -static void saa7146_disable_clipping(struct saa7146_dev *dev) -{ - u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL); - - /* mask out relevant bits (=lower word)*/ - clip_format &= MASK_W1; - - /* upload clipping-registers*/ - saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format); - saa7146_write(dev, MC2, (MASK_05 | MASK_21)); - - /* disable video dma2 */ - saa7146_write(dev, MC1, MASK_21); -} - -static void saa7146_set_clipping_rect(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - enum v4l2_field field = vv->ov.win.field; - struct saa7146_video_dma vdma2; - u32 clip_format; - u32 arbtr_ctrl; - - /* check clipcount, disable clipping if clipcount == 0*/ - if (vv->ov.nclips == 0) { - saa7146_disable_clipping(dev); - return; - } - - clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL); - arbtr_ctrl = saa7146_read(dev, PCI_BT_V1); - - calculate_clipping_registers_rect(dev, fh, &vdma2, &clip_format, &arbtr_ctrl, field); - - /* set clipping format */ - clip_format &= 0xffff0008; - clip_format |= (SAA7146_CLIPPING_RECT << 4); - - /* prepare video dma2 */ - saa7146_write(dev, BASE_EVEN2, vdma2.base_even); - saa7146_write(dev, BASE_ODD2, vdma2.base_odd); - saa7146_write(dev, PROT_ADDR2, vdma2.prot_addr); - saa7146_write(dev, BASE_PAGE2, vdma2.base_page); - saa7146_write(dev, PITCH2, vdma2.pitch); - saa7146_write(dev, NUM_LINE_BYTE2, vdma2.num_line_byte); - - /* prepare the rest */ - saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format); - saa7146_write(dev, PCI_BT_V1, arbtr_ctrl); - - /* upload clip_control-register, clipping-registers, enable video dma2 */ - saa7146_write(dev, MC2, (MASK_05 | MASK_21 | MASK_03 | MASK_19)); - saa7146_write(dev, MC1, (MASK_05 | MASK_21)); -} - -static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field) -{ - struct saa7146_vv *vv = dev->vv_data; - - int source = vv->current_hps_source; - int sync = vv->current_hps_sync; - - u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0; - - /* set vertical scale */ - hps_v_scale = 0; /* all bits get set by the function-call */ - hps_v_gain = 0; /* fixme: saa7146_read(dev, HPS_V_GAIN);*/ - calculate_v_scale_registers(dev, field, vv->standard->v_field*2, height, &hps_v_scale, &hps_v_gain); - - /* set horizontal scale */ - hps_ctrl = 0; - hps_h_prescale = 0; /* all bits get set in the function */ - hps_h_scale = 0; - calculate_h_scale_registers(dev, vv->standard->h_pixels, width, vv->hflip, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale); - - /* set hyo and hxo */ - calculate_hxo_and_hyo(vv, &hps_h_scale, &hps_ctrl); - calculate_hps_source_and_sync(dev, source, sync, &hps_ctrl); - - /* write out new register contents */ - saa7146_write(dev, HPS_V_SCALE, hps_v_scale); - saa7146_write(dev, HPS_V_GAIN, hps_v_gain); - saa7146_write(dev, HPS_CTRL, hps_ctrl); - saa7146_write(dev, HPS_H_PRESCALE,hps_h_prescale); - saa7146_write(dev, HPS_H_SCALE, hps_h_scale); - - /* upload shadow-ram registers */ - saa7146_write(dev, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) ); -} - -/* calculate the new memory offsets for a desired position */ -static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat) -{ - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat); - - int b_depth = vv->ov_fmt->depth; - int b_bpl = vv->ov_fb.fmt.bytesperline; - /* The unsigned long cast is to remove a 64-bit compile warning since - it looks like a 64-bit address is cast to a 32-bit value, even - though the base pointer is really a 32-bit physical address that - goes into a 32-bit DMA register. - FIXME: might not work on some 64-bit platforms, but see the FIXME - in struct v4l2_framebuffer (videodev2.h) for that. - */ - u32 base = (u32)(unsigned long)vv->ov_fb.base; - - struct saa7146_video_dma vdma1; - - /* calculate memory offsets for picture, look if we shall top-down-flip */ - vdma1.pitch = 2*b_bpl; - if ( 0 == vv->vflip ) { - vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); - vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); - vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2)); - } - else { - vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); - vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2); - vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2)); - } - - if (V4L2_FIELD_HAS_BOTH(field)) { - } else if (field == V4L2_FIELD_ALTERNATE) { - /* fixme */ - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - } else if (field == V4L2_FIELD_TOP) { - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - } else if (field == V4L2_FIELD_BOTTOM) { - vdma1.base_odd = vdma1.base_even; - vdma1.base_even = vdma1.prot_addr; - vdma1.pitch /= 2; - } - - if ( 0 != vv->vflip ) { - vdma1.pitch *= -1; - } - - vdma1.base_page = sfmt->swap; - vdma1.num_line_byte = (vv->standard->v_field<<16)+vv->standard->h_pixels; - - saa7146_write_out_dma(dev, 1, &vdma1); -} - -static void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette) -{ - u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL); - - /* call helper function */ - calculate_output_format_register(dev,palette,&clip_format); - - /* update the hps registers */ - saa7146_write(dev, CLIP_FORMAT_CTRL, clip_format); - saa7146_write(dev, MC2, (MASK_05 | MASK_21)); -} - -/* select input-source */ -void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync) -{ - struct saa7146_vv *vv = dev->vv_data; - u32 hps_ctrl = 0; - - /* read old state */ - hps_ctrl = saa7146_read(dev, HPS_CTRL); - - hps_ctrl &= ~( MASK_31 | MASK_30 | MASK_28 ); - hps_ctrl |= (source << 30) | (sync << 28); - - /* write back & upload register */ - saa7146_write(dev, HPS_CTRL, hps_ctrl); - saa7146_write(dev, MC2, (MASK_05 | MASK_21)); - - vv->current_hps_source = source; - vv->current_hps_sync = sync; -} -EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync); - -int saa7146_enable_overlay(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - - saa7146_set_window(dev, vv->ov.win.w.width, vv->ov.win.w.height, vv->ov.win.field); - saa7146_set_position(dev, vv->ov.win.w.left, vv->ov.win.w.top, vv->ov.win.w.height, vv->ov.win.field, vv->ov_fmt->pixelformat); - saa7146_set_output_format(dev, vv->ov_fmt->trans); - saa7146_set_clipping_rect(fh); - - /* enable video dma1 */ - saa7146_write(dev, MC1, (MASK_06 | MASK_22)); - return 0; -} - -void saa7146_disable_overlay(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - - /* disable clipping + video dma1 */ - saa7146_disable_clipping(dev); - saa7146_write(dev, MC1, MASK_22); -} - -void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma) -{ - int where = 0; - - if( which < 1 || which > 3) { - return; - } - - /* calculate starting address */ - where = (which-1)*0x18; - - saa7146_write(dev, where, vdma->base_odd); - saa7146_write(dev, where+0x04, vdma->base_even); - saa7146_write(dev, where+0x08, vdma->prot_addr); - saa7146_write(dev, where+0x0c, vdma->pitch); - saa7146_write(dev, where+0x10, vdma->base_page); - saa7146_write(dev, where+0x14, vdma->num_line_byte); - - /* upload */ - saa7146_write(dev, MC2, (MASK_02<<(which-1))|(MASK_18<<(which-1))); -/* - printk("vdma%d.base_even: 0x%08x\n", which,vdma->base_even); - printk("vdma%d.base_odd: 0x%08x\n", which,vdma->base_odd); - printk("vdma%d.prot_addr: 0x%08x\n", which,vdma->prot_addr); - printk("vdma%d.base_page: 0x%08x\n", which,vdma->base_page); - printk("vdma%d.pitch: 0x%08x\n", which,vdma->pitch); - printk("vdma%d.num_line_byte: 0x%08x\n", which,vdma->num_line_byte); -*/ -} - -static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf) -{ - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_video_dma vdma1; - - struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); - - int width = buf->fmt->width; - int height = buf->fmt->height; - int bytesperline = buf->fmt->bytesperline; - enum v4l2_field field = buf->fmt->field; - - int depth = sfmt->depth; - - DEB_CAP("[size=%dx%d,fields=%s]\n", - width, height, v4l2_field_names[field]); - - if( bytesperline != 0) { - vdma1.pitch = bytesperline*2; - } else { - vdma1.pitch = (width*depth*2)/8; - } - vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels); - vdma1.base_page = buf->pt[0].dma | ME1 | sfmt->swap; - - if( 0 != vv->vflip ) { - vdma1.prot_addr = buf->pt[0].offset; - vdma1.base_even = buf->pt[0].offset+(vdma1.pitch/2)*height; - vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2); - } else { - vdma1.base_even = buf->pt[0].offset; - vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2); - vdma1.prot_addr = buf->pt[0].offset+(vdma1.pitch/2)*height; - } - - if (V4L2_FIELD_HAS_BOTH(field)) { - } else if (field == V4L2_FIELD_ALTERNATE) { - /* fixme */ - if ( vv->last_field == V4L2_FIELD_TOP ) { - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) { - vdma1.base_odd = vdma1.base_even; - vdma1.base_even = vdma1.prot_addr; - vdma1.pitch /= 2; - } - } else if (field == V4L2_FIELD_TOP) { - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - } else if (field == V4L2_FIELD_BOTTOM) { - vdma1.base_odd = vdma1.base_even; - vdma1.base_even = vdma1.prot_addr; - vdma1.pitch /= 2; - } - - if( 0 != vv->vflip ) { - vdma1.pitch *= -1; - } - - saa7146_write_out_dma(dev, 1, &vdma1); - return 0; -} - -static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) -{ - int height = buf->fmt->height; - int width = buf->fmt->width; - - vdma2->pitch = width; - vdma3->pitch = width; - - /* fixme: look at bytesperline! */ - - if( 0 != vv->vflip ) { - vdma2->prot_addr = buf->pt[1].offset; - vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[1].offset; - vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2); - - vdma3->prot_addr = buf->pt[2].offset; - vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[2].offset; - vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2); - } else { - vdma3->base_even = buf->pt[2].offset; - vdma3->base_odd = vdma3->base_even + (vdma3->pitch/2); - vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset; - - vdma2->base_even = buf->pt[1].offset; - vdma2->base_odd = vdma2->base_even + (vdma2->pitch/2); - vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset; - } - - return 0; -} - -static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) -{ - int height = buf->fmt->height; - int width = buf->fmt->width; - - vdma2->pitch = width/2; - vdma3->pitch = width/2; - - if( 0 != vv->vflip ) { - vdma2->prot_addr = buf->pt[2].offset; - vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[2].offset; - vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2); - - vdma3->prot_addr = buf->pt[1].offset; - vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[1].offset; - vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2); - - } else { - vdma3->base_even = buf->pt[2].offset; - vdma3->base_odd = vdma3->base_even + (vdma3->pitch); - vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset; - - vdma2->base_even = buf->pt[1].offset; - vdma2->base_odd = vdma2->base_even + (vdma2->pitch); - vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset; - } - return 0; -} - -static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf) -{ - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_video_dma vdma1; - struct saa7146_video_dma vdma2; - struct saa7146_video_dma vdma3; - - struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); - - int width = buf->fmt->width; - int height = buf->fmt->height; - enum v4l2_field field = buf->fmt->field; - - BUG_ON(0 == buf->pt[0].dma); - BUG_ON(0 == buf->pt[1].dma); - BUG_ON(0 == buf->pt[2].dma); - - DEB_CAP("[size=%dx%d,fields=%s]\n", - width, height, v4l2_field_names[field]); - - /* fixme: look at bytesperline! */ - - /* fixme: what happens for user space buffers here?. The offsets are - most likely wrong, this version here only works for page-aligned - buffers, modifications to the pagetable-functions are necessary...*/ - - vdma1.pitch = width*2; - vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels); - vdma1.base_page = buf->pt[0].dma | ME1; - - if( 0 != vv->vflip ) { - vdma1.prot_addr = buf->pt[0].offset; - vdma1.base_even = ((vdma1.pitch/2)*height)+buf->pt[0].offset; - vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2); - } else { - vdma1.base_even = buf->pt[0].offset; - vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2); - vdma1.prot_addr = (vdma1.pitch/2)*height+buf->pt[0].offset; - } - - vdma2.num_line_byte = 0; /* unused */ - vdma2.base_page = buf->pt[1].dma | ME1; - - vdma3.num_line_byte = 0; /* unused */ - vdma3.base_page = buf->pt[2].dma | ME1; - - switch( sfmt->depth ) { - case 12: { - calc_planar_420(vv,buf,&vdma2,&vdma3); - break; - } - case 16: { - calc_planar_422(vv,buf,&vdma2,&vdma3); - break; - } - default: { - return -1; - } - } - - if (V4L2_FIELD_HAS_BOTH(field)) { - } else if (field == V4L2_FIELD_ALTERNATE) { - /* fixme */ - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - vdma2.base_odd = vdma2.prot_addr; - vdma2.pitch /= 2; - vdma3.base_odd = vdma3.prot_addr; - vdma3.pitch /= 2; - } else if (field == V4L2_FIELD_TOP) { - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - vdma2.base_odd = vdma2.prot_addr; - vdma2.pitch /= 2; - vdma3.base_odd = vdma3.prot_addr; - vdma3.pitch /= 2; - } else if (field == V4L2_FIELD_BOTTOM) { - vdma1.base_odd = vdma1.base_even; - vdma1.base_even = vdma1.prot_addr; - vdma1.pitch /= 2; - vdma2.base_odd = vdma2.base_even; - vdma2.base_even = vdma2.prot_addr; - vdma2.pitch /= 2; - vdma3.base_odd = vdma3.base_even; - vdma3.base_even = vdma3.prot_addr; - vdma3.pitch /= 2; - } - - if( 0 != vv->vflip ) { - vdma1.pitch *= -1; - vdma2.pitch *= -1; - vdma3.pitch *= -1; - } - - saa7146_write_out_dma(dev, 1, &vdma1); - if( (sfmt->flags & FORMAT_BYTE_SWAP) != 0 ) { - saa7146_write_out_dma(dev, 3, &vdma2); - saa7146_write_out_dma(dev, 2, &vdma3); - } else { - saa7146_write_out_dma(dev, 2, &vdma2); - saa7146_write_out_dma(dev, 3, &vdma3); - } - return 0; -} - -static void program_capture_engine(struct saa7146_dev *dev, int planar) -{ - struct saa7146_vv *vv = dev->vv_data; - int count = 0; - - unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B; - unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B; - - /* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/ - WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait); - WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait); - - /* set rps register 0 */ - WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4)); - WRITE_RPS0(MASK_27 | MASK_11); - - /* turn on video-dma1 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_06 | MASK_22); /* => mask */ - WRITE_RPS0(MASK_06 | MASK_22); /* => values */ - if( 0 != planar ) { - /* turn on video-dma2 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_05 | MASK_21); /* => mask */ - WRITE_RPS0(MASK_05 | MASK_21); /* => values */ - - /* turn on video-dma3 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_04 | MASK_20); /* => mask */ - WRITE_RPS0(MASK_04 | MASK_20); /* => values */ - } - - /* wait for o_fid_a/b / e_fid_a/b toggle */ - if ( vv->last_field == V4L2_FIELD_INTERLACED ) { - WRITE_RPS0(CMD_PAUSE | o_wait); - WRITE_RPS0(CMD_PAUSE | e_wait); - } else if ( vv->last_field == V4L2_FIELD_TOP ) { - WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09)); - WRITE_RPS0(CMD_PAUSE | o_wait); - } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) { - WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09)); - WRITE_RPS0(CMD_PAUSE | e_wait); - } - - /* turn off video-dma1 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_22 | MASK_06); /* => mask */ - WRITE_RPS0(MASK_22); /* => values */ - if( 0 != planar ) { - /* turn off video-dma2 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_05 | MASK_21); /* => mask */ - WRITE_RPS0(MASK_21); /* => values */ - - /* turn off video-dma3 */ - WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS0(MASK_04 | MASK_20); /* => mask */ - WRITE_RPS0(MASK_20); /* => values */ - } - - /* generate interrupt */ - WRITE_RPS0(CMD_INTERRUPT); - - /* stop */ - WRITE_RPS0(CMD_STOP); -} - -void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) -{ - struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); - struct saa7146_vv *vv = dev->vv_data; - u32 vdma1_prot_addr; - - DEB_CAP("buf:%p, next:%p\n", buf, next); - - vdma1_prot_addr = saa7146_read(dev, PROT_ADDR1); - if( 0 == vdma1_prot_addr ) { - /* clear out beginning of streaming bit (rps register 0)*/ - DEB_CAP("forcing sync to new frame\n"); - saa7146_write(dev, MC2, MASK_27 ); - } - - saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field); - saa7146_set_output_format(dev, sfmt->trans); - saa7146_disable_clipping(dev); - - if ( vv->last_field == V4L2_FIELD_INTERLACED ) { - } else if ( vv->last_field == V4L2_FIELD_TOP ) { - vv->last_field = V4L2_FIELD_BOTTOM; - } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) { - vv->last_field = V4L2_FIELD_TOP; - } - - if( 0 != IS_PLANAR(sfmt->trans)) { - calculate_video_dma_grab_planar(dev, buf); - program_capture_engine(dev,1); - } else { - calculate_video_dma_grab_packed(dev, buf); - program_capture_engine(dev,0); - } - -/* - printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1)); - printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1)); - printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1)); - printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1)); - printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1)); - printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1)); - printk("vdma%d => vptr : 0x%08x\n", 1,saa7146_read(dev,PCI_VDP1)); -*/ - - /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); - - /* turn on rps */ - saa7146_write(dev, MC1, (MASK_12 | MASK_28)); -} diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c deleted file mode 100644 index 7a33fe51775a..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_i2c.c +++ /dev/null @@ -1,421 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "saa7146_vv.h" - -static u32 saa7146_i2c_func(struct i2c_adapter *adapter) -{ - /* DEB_I2C("'%s'\n", adapter->name); */ - - return I2C_FUNC_I2C - | I2C_FUNC_SMBUS_QUICK - | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE - | I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA; -} - -/* this function returns the status-register of our i2c-device */ -static inline u32 saa7146_i2c_status(struct saa7146_dev *dev) -{ - u32 iicsta = saa7146_read(dev, I2C_STATUS); - /* DEB_I2C("status: 0x%08x\n", iicsta); */ - return iicsta; -} - -/* this function runs through the i2c-messages and prepares the data to be - sent through the saa7146. have a look at the specifications p. 122 ff - to understand this. it returns the number of u32s to send, or -1 - in case of an error. */ -static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, __le32 *op) -{ - int h1, h2; - int i, j, addr; - int mem = 0, op_count = 0; - - /* first determine size of needed memory */ - for(i = 0; i < num; i++) { - mem += m[i].len + 1; - } - - /* worst case: we need one u32 for three bytes to be send - plus one extra byte to address the device */ - mem = 1 + ((mem-1) / 3); - - /* we assume that op points to a memory of at least - * SAA7146_I2C_MEM bytes size. if we exceed this limit... - */ - if ((4 * mem) > SAA7146_I2C_MEM) { - /* DEB_I2C("cannot prepare i2c-message\n"); */ - return -ENOMEM; - } - - /* be careful: clear out the i2c-mem first */ - memset(op,0,sizeof(__le32)*mem); - - /* loop through all messages */ - for(i = 0; i < num; i++) { - - addr = i2c_8bit_addr_from_msg(&m[i]); - h1 = op_count/3; h2 = op_count%3; - op[h1] |= cpu_to_le32( (u8)addr << ((3-h2)*8)); - op[h1] |= cpu_to_le32(SAA7146_I2C_START << ((3-h2)*2)); - op_count++; - - /* loop through all bytes of message i */ - for(j = 0; j < m[i].len; j++) { - /* insert the data bytes */ - h1 = op_count/3; h2 = op_count%3; - op[h1] |= cpu_to_le32( (u32)((u8)m[i].buf[j]) << ((3-h2)*8)); - op[h1] |= cpu_to_le32( SAA7146_I2C_CONT << ((3-h2)*2)); - op_count++; - } - - } - - /* have a look at the last byte inserted: - if it was: ...CONT change it to ...STOP */ - h1 = (op_count-1)/3; h2 = (op_count-1)%3; - if ( SAA7146_I2C_CONT == (0x3 & (le32_to_cpu(op[h1]) >> ((3-h2)*2))) ) { - op[h1] &= ~cpu_to_le32(0x2 << ((3-h2)*2)); - op[h1] |= cpu_to_le32(SAA7146_I2C_STOP << ((3-h2)*2)); - } - - /* return the number of u32s to send */ - return mem; -} - -/* this functions loops through all i2c-messages. normally, it should determine - which bytes were read through the adapter and write them back to the corresponding - i2c-message. but instead, we simply write back all bytes. - fixme: this could be improved. */ -static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op) -{ - int i, j; - int op_count = 0; - - /* loop through all messages */ - for(i = 0; i < num; i++) { - - op_count++; - - /* loop through all bytes of message i */ - for(j = 0; j < m[i].len; j++) { - /* write back all bytes that could have been read */ - m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8)); - op_count++; - } - } - - return 0; -} - -/* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */ -static int saa7146_i2c_reset(struct saa7146_dev *dev) -{ - /* get current status */ - u32 status = saa7146_i2c_status(dev); - - /* clear registers for sure */ - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, 0); - - /* check if any operation is still in progress */ - if ( 0 != ( status & SAA7146_I2C_BUSY) ) { - - /* yes, kill ongoing operation */ - DEB_I2C("busy_state detected\n"); - - /* set "ABORT-OPERATION"-bit (bit 7)*/ - saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07)); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - msleep(SAA7146_I2C_DELAY); - - /* clear all error-bits pending; this is needed because p.123, note 1 */ - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - msleep(SAA7146_I2C_DELAY); - } - - /* check if any error is (still) present. (this can be necessary because p.123, note 1) */ - status = saa7146_i2c_status(dev); - - if ( dev->i2c_bitrate != status ) { - - DEB_I2C("error_state detected. status:0x%08x\n", status); - - /* Repeat the abort operation. This seems to be necessary - after serious protocol errors caused by e.g. the SAA7740 */ - saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07)); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - msleep(SAA7146_I2C_DELAY); - - /* clear all error-bits pending */ - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - msleep(SAA7146_I2C_DELAY); - - /* the data sheet says it might be necessary to clear the status - twice after an abort */ - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - msleep(SAA7146_I2C_DELAY); - } - - /* if any error is still present, a fatal error has occurred ... */ - status = saa7146_i2c_status(dev); - if ( dev->i2c_bitrate != status ) { - DEB_I2C("fatal error. status:0x%08x\n", status); - return -1; - } - - return 0; -} - -/* this functions writes out the data-byte 'dword' to the i2c-device. - it returns 0 if ok, -1 if the transfer failed, -2 if the transfer - failed badly (e.g. address error) */ -static int saa7146_i2c_writeout(struct saa7146_dev *dev, __le32 *dword, int short_delay) -{ - u32 status = 0, mc2 = 0; - int trial = 0; - unsigned long timeout; - - /* write out i2c-command */ - DEB_I2C("before: 0x%08x (status: 0x%08x), %d\n", - *dword, saa7146_read(dev, I2C_STATUS), dev->i2c_op); - - if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { - - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword)); - - dev->i2c_op = 1; - SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17); - SAA7146_IER_ENABLE(dev, MASK_16|MASK_17); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - - timeout = HZ/100 + 1; /* 10ms */ - timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout); - if (timeout == -ERESTARTSYS || dev->i2c_op) { - SAA7146_IER_DISABLE(dev, MASK_16|MASK_17); - SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17); - if (timeout == -ERESTARTSYS) - /* a signal arrived */ - return -ERESTARTSYS; - - pr_warn("%s %s [irq]: timed out waiting for end of xfer\n", - dev->name, __func__); - return -EIO; - } - status = saa7146_read(dev, I2C_STATUS); - } else { - saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword)); - saa7146_write(dev, MC2, (MASK_00 | MASK_16)); - - /* do not poll for i2c-status before upload is complete */ - timeout = jiffies + HZ/100 + 1; /* 10ms */ - while(1) { - mc2 = (saa7146_read(dev, MC2) & 0x1); - if( 0 != mc2 ) { - break; - } - if (time_after(jiffies,timeout)) { - pr_warn("%s %s: timed out waiting for MC2\n", - dev->name, __func__); - return -EIO; - } - } - /* wait until we get a transfer done or error */ - timeout = jiffies + HZ/100 + 1; /* 10ms */ - /* first read usually delivers bogus results... */ - saa7146_i2c_status(dev); - while(1) { - status = saa7146_i2c_status(dev); - if ((status & 0x3) != 1) - break; - if (time_after(jiffies,timeout)) { - /* this is normal when probing the bus - * (no answer from nonexisistant device...) - */ - pr_warn("%s %s [poll]: timed out waiting for end of xfer\n", - dev->name, __func__); - return -EIO; - } - if (++trial < 50 && short_delay) - udelay(10); - else - msleep(1); - } - } - - /* give a detailed status report */ - if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR | - SAA7146_I2C_DTERR | SAA7146_I2C_DRERR | - SAA7146_I2C_AL | SAA7146_I2C_ERR | - SAA7146_I2C_BUSY)) ) { - - if ( 0 == (status & SAA7146_I2C_ERR) || - 0 == (status & SAA7146_I2C_BUSY) ) { - /* it may take some time until ERR goes high - ignore */ - DEB_I2C("unexpected i2c status %04x\n", status); - } - if( 0 != (status & SAA7146_I2C_SPERR) ) { - DEB_I2C("error due to invalid start/stop condition\n"); - } - if( 0 != (status & SAA7146_I2C_DTERR) ) { - DEB_I2C("error in data transmission\n"); - } - if( 0 != (status & SAA7146_I2C_DRERR) ) { - DEB_I2C("error when receiving data\n"); - } - if( 0 != (status & SAA7146_I2C_AL) ) { - DEB_I2C("error because arbitration lost\n"); - } - - /* we handle address-errors here */ - if( 0 != (status & SAA7146_I2C_APERR) ) { - DEB_I2C("error in address phase\n"); - return -EREMOTEIO; - } - - return -EIO; - } - - /* read back data, just in case we were reading ... */ - *dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER)); - - DEB_I2C("after: 0x%08x\n", *dword); - return 0; -} - -static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries) -{ - int i = 0, count = 0; - __le32 *buffer = dev->d_i2c.cpu_addr; - int err = 0; - int short_delay = 0; - - if (mutex_lock_interruptible(&dev->i2c_lock)) - return -ERESTARTSYS; - - for(i=0;i<num;i++) { - DEB_I2C("msg:%d/%d\n", i+1, num); - } - - /* prepare the message(s), get number of u32s to transfer */ - count = saa7146_i2c_msg_prepare(msgs, num, buffer); - if ( 0 > count ) { - err = -EIO; - goto out; - } - - if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) ) - short_delay = 1; - - do { - /* reset the i2c-device if necessary */ - err = saa7146_i2c_reset(dev); - if ( 0 > err ) { - DEB_I2C("could not reset i2c-device\n"); - goto out; - } - - /* write out the u32s one after another */ - for(i = 0; i < count; i++) { - err = saa7146_i2c_writeout(dev, &buffer[i], short_delay); - if ( 0 != err) { - /* this one is unsatisfying: some i2c slaves on some - dvb cards don't acknowledge correctly, so the saa7146 - thinks that an address error occurred. in that case, the - transaction should be retrying, even if an address error - occurred. analog saa7146 based cards extensively rely on - i2c address probing, however, and address errors indicate that a - device is really *not* there. retrying in that case - increases the time the device needs to probe greatly, so - it should be avoided. So we bail out in irq mode after an - address error and trust the saa7146 address error detection. */ - if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) - goto out; - DEB_I2C("error while sending message(s). starting again\n"); - break; - } - } - if( 0 == err ) { - err = num; - break; - } - - /* delay a bit before retrying */ - msleep(10); - - } while (err != num && retries--); - - /* quit if any error occurred */ - if (err != num) - goto out; - - /* if any things had to be read, get the results */ - if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) { - DEB_I2C("could not cleanup i2c-message\n"); - err = -EIO; - goto out; - } - - /* return the number of delivered messages */ - DEB_I2C("transmission successful. (msg:%d)\n", err); -out: - /* another bug in revision 0: the i2c-registers get uploaded randomly by other - uploads, so we better clear them out before continuing */ - if( 0 == dev->revision ) { - __le32 zero = 0; - saa7146_i2c_reset(dev); - if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) { - pr_info("revision 0 error. this should never happen\n"); - } - } - - mutex_unlock(&dev->i2c_lock); - return err; -} - -/* utility functions */ -static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) -{ - struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); - struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); - - /* use helper function to transfer data */ - return saa7146_i2c_transfer(dev, msg, num, adapter->retries); -} - - -/*****************************************************************************/ -/* i2c-adapter helper functions */ - -/* exported algorithm data */ -static const struct i2c_algorithm saa7146_algo = { - .master_xfer = saa7146_i2c_xfer, - .functionality = saa7146_i2c_func, -}; - -int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate) -{ - DEB_EE("bitrate: 0x%08x\n", bitrate); - - /* enable i2c-port pins */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24)); - - dev->i2c_bitrate = bitrate; - saa7146_i2c_reset(dev); - - if (i2c_adapter) { - i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); - i2c_adapter->dev.parent = &dev->pci->dev; - i2c_adapter->algo = &saa7146_algo; - i2c_adapter->algo_data = NULL; - i2c_adapter->timeout = SAA7146_I2C_TIMEOUT; - i2c_adapter->retries = SAA7146_I2C_RETRIES; - } - - return 0; -} diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c deleted file mode 100644 index 2d4a05d7bc5b..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_vbi.c +++ /dev/null @@ -1,498 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "saa7146_vv.h" - -static int vbi_pixel_to_capture = 720 * 2; - -static int vbi_workaround(struct saa7146_dev *dev) -{ - struct saa7146_vv *vv = dev->vv_data; - - u32 *cpu; - dma_addr_t dma_addr; - - int count = 0; - int i; - - DECLARE_WAITQUEUE(wait, current); - - DEB_VBI("dev:%p\n", dev); - - /* once again, a bug in the saa7146: the brs acquisition - is buggy and especially the BXO-counter does not work - as specified. there is this workaround, but please - don't let me explain it. ;-) */ - - cpu = dma_alloc_coherent(&dev->pci->dev, 4096, &dma_addr, GFP_KERNEL); - if (NULL == cpu) - return -ENOMEM; - - /* setup some basic programming, just for the workaround */ - saa7146_write(dev, BASE_EVEN3, dma_addr); - saa7146_write(dev, BASE_ODD3, dma_addr+vbi_pixel_to_capture); - saa7146_write(dev, PROT_ADDR3, dma_addr+4096); - saa7146_write(dev, PITCH3, vbi_pixel_to_capture); - saa7146_write(dev, BASE_PAGE3, 0x0); - saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0)); - saa7146_write(dev, MC2, MASK_04|MASK_20); - - /* load brs-control register */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); - /* BXO = 1h, BRS to outbound */ - WRITE_RPS1(0xc000008c); - /* wait for vbi_a or vbi_b*/ - if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { - DEB_D("...using port b\n"); - WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B); - WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B); -/* - WRITE_RPS1(CMD_PAUSE | MASK_09); -*/ - } else { - DEB_D("...using port a\n"); - WRITE_RPS1(CMD_PAUSE | MASK_10); - } - /* upload brs */ - WRITE_RPS1(CMD_UPLOAD | MASK_08); - /* load brs-control register */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); - /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */ - WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19); - /* wait for brs_done */ - WRITE_RPS1(CMD_PAUSE | MASK_08); - /* upload brs */ - WRITE_RPS1(CMD_UPLOAD | MASK_08); - /* load video-dma3 NumLines3 and NumBytes3 */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4)); - /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */ - WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture)); - /* load brs-control register */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); - /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */ - WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start - /* wait for brs_done */ - WRITE_RPS1(CMD_PAUSE | MASK_08); - /* upload brs and video-dma3*/ - WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04); - /* load mc2 register: enable dma3 */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4)); - WRITE_RPS1(MASK_20 | MASK_04); - /* generate interrupt */ - WRITE_RPS1(CMD_INTERRUPT); - /* stop rps1 */ - WRITE_RPS1(CMD_STOP); - - /* we have to do the workaround twice to be sure that - everything is ok */ - for(i = 0; i < 2; i++) { - - /* indicate to the irq handler that we do the workaround */ - saa7146_write(dev, MC2, MASK_31|MASK_15); - - saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0)); - saa7146_write(dev, MC2, MASK_04|MASK_20); - - /* enable rps1 irqs */ - SAA7146_IER_ENABLE(dev,MASK_28); - - /* prepare to wait to be woken up by the irq-handler */ - add_wait_queue(&vv->vbi_wq, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - /* start rps1 to enable workaround */ - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - saa7146_write(dev, MC1, (MASK_13 | MASK_29)); - - schedule(); - - DEB_VBI("brs bug workaround %d/1\n", i); - - remove_wait_queue(&vv->vbi_wq, &wait); - __set_current_state(TASK_RUNNING); - - /* disable rps1 irqs */ - SAA7146_IER_DISABLE(dev,MASK_28); - - /* stop video-dma3 */ - saa7146_write(dev, MC1, MASK_20); - - if(signal_pending(current)) { - - DEB_VBI("aborted (rps:0x%08x)\n", - saa7146_read(dev, RPS_ADDR1)); - - /* stop rps1 for sure */ - saa7146_write(dev, MC1, MASK_29); - - dma_free_coherent(&dev->pci->dev, 4096, cpu, dma_addr); - return -EINTR; - } - } - - dma_free_coherent(&dev->pci->dev, 4096, cpu, dma_addr); - return 0; -} - -static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) -{ - struct saa7146_vv *vv = dev->vv_data; - - struct saa7146_video_dma vdma3; - - int count = 0; - unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B; - unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B; - -/* - vdma3.base_even = 0xc8000000+2560*70; - vdma3.base_odd = 0xc8000000; - vdma3.prot_addr = 0xc8000000+2560*164; - vdma3.pitch = 2560; - vdma3.base_page = 0; - vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above! -*/ - vdma3.base_even = buf->pt[2].offset; - vdma3.base_odd = buf->pt[2].offset + 16 * vbi_pixel_to_capture; - vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture; - vdma3.pitch = vbi_pixel_to_capture; - vdma3.base_page = buf->pt[2].dma | ME1; - vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture; - - saa7146_write_out_dma(dev, 3, &vdma3); - - /* write beginning of rps-program */ - count = 0; - - /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */ - - /* we don't wait here for the first field anymore. this is different from the video - capture and might cause that the first buffer is only half filled (with only - one field). but since this is some sort of streaming data, this is not that negative. - but by doing this, we can use the whole engine from videobuf-dma-sg.c... */ - -/* - WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait); - WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait); -*/ - /* set bit 1 */ - WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4)); - WRITE_RPS1(MASK_28 | MASK_12); - - /* turn on video-dma3 */ - WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4)); - WRITE_RPS1(MASK_04 | MASK_20); /* => mask */ - WRITE_RPS1(MASK_04 | MASK_20); /* => values */ - - /* wait for o_fid_a/b / e_fid_a/b toggle */ - WRITE_RPS1(CMD_PAUSE | o_wait); - WRITE_RPS1(CMD_PAUSE | e_wait); - - /* generate interrupt */ - WRITE_RPS1(CMD_INTERRUPT); - - /* stop */ - WRITE_RPS1(CMD_STOP); - - /* enable rps1 irqs */ - SAA7146_IER_ENABLE(dev, MASK_28); - - /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - - /* turn on rps */ - saa7146_write(dev, MC1, (MASK_13 | MASK_29)); -} - -static int buffer_activate(struct saa7146_dev *dev, - struct saa7146_buf *buf, - struct saa7146_buf *next) -{ - struct saa7146_vv *vv = dev->vv_data; - buf->vb.state = VIDEOBUF_ACTIVE; - - DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next); - saa7146_set_vbi_capture(dev,buf,next); - - mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT); - return 0; -} - -static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - - int err = 0; - int lines, llength, size; - - lines = 16 * 2 ; /* 2 fields */ - llength = vbi_pixel_to_capture; - size = lines * llength; - - DEB_VBI("vb:%p\n", vb); - - if (0 != buf->vb.baddr && buf->vb.bsize < size) { - DEB_VBI("size mismatch\n"); - return -EINVAL; - } - - if (buf->vb.size != size) - saa7146_dma_free(dev,q,buf); - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - - buf->vb.width = llength; - buf->vb.height = lines; - buf->vb.size = size; - buf->vb.field = field; // FIXME: check this - - saa7146_pgtable_free(dev->pci, &buf->pt[2]); - saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); - - err = videobuf_iolock(q,&buf->vb, NULL); - if (err) - goto oops; - err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], - dma->sglist, dma->sglen); - if (0 != err) - return err; - } - buf->vb.state = VIDEOBUF_PREPARED; - buf->activate = buffer_activate; - - return 0; - - oops: - DEB_VBI("error out\n"); - saa7146_dma_free(dev,q,buf); - - return err; -} - -static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) -{ - int llength,lines; - - lines = 16 * 2 ; /* 2 fields */ - llength = vbi_pixel_to_capture; - - *size = lines * llength; - *count = 2; - - DEB_VBI("count:%d, size:%d\n", *count, *size); - - return 0; -} - -static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - - DEB_VBI("vb:%p\n", vb); - saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf); -} - -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - - DEB_VBI("vb:%p\n", vb); - saa7146_dma_free(dev,q,buf); -} - -static const struct videobuf_queue_ops vbi_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -/* ------------------------------------------------------------------ */ - -static void vbi_stop(struct saa7146_fh *fh, struct file *file) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - unsigned long flags; - DEB_VBI("dev:%p, fh:%p\n", dev, fh); - - spin_lock_irqsave(&dev->slock,flags); - - /* disable rps1 */ - saa7146_write(dev, MC1, MASK_29); - - /* disable rps1 irqs */ - SAA7146_IER_DISABLE(dev, MASK_28); - - /* shut down dma 3 transfers */ - saa7146_write(dev, MC1, MASK_20); - - if (vv->vbi_dmaq.curr) - saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE); - - videobuf_queue_cancel(&fh->vbi_q); - - vv->vbi_streaming = NULL; - - del_timer(&vv->vbi_dmaq.timeout); - del_timer(&vv->vbi_read_timeout); - - spin_unlock_irqrestore(&dev->slock, flags); -} - -static void vbi_read_timeout(struct timer_list *t) -{ - struct saa7146_vv *vv = from_timer(vv, t, vbi_read_timeout); - struct file *file = vv->vbi_read_timeout_file; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - - DEB_VBI("dev:%p, fh:%p\n", dev, fh); - - vbi_stop(fh, file); -} - -static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv) -{ - DEB_VBI("dev:%p\n", dev); - - INIT_LIST_HEAD(&vv->vbi_dmaq.queue); - - timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0); - vv->vbi_dmaq.dev = dev; - - init_waitqueue_head(&vv->vbi_wq); -} - -static int vbi_open(struct saa7146_dev *dev, struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_vv *vv = fh->dev->vv_data; - - u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1); - int ret = 0; - - DEB_VBI("dev:%p, fh:%p\n", dev, fh); - - ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS); - if (0 == ret) { - DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n"); - return -EBUSY; - } - - /* adjust arbitrition control for video dma 3 */ - arbtr_ctrl &= ~0x1f0000; - arbtr_ctrl |= 0x1d0000; - saa7146_write(dev, PCI_BT_V1, arbtr_ctrl); - saa7146_write(dev, MC2, (MASK_04|MASK_20)); - - videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VBI_CAPTURE, - V4L2_FIELD_SEQ_TB, // FIXME: does this really work? - sizeof(struct saa7146_buf), - file, &dev->v4l2_lock); - - vv->vbi_read_timeout.function = vbi_read_timeout; - vv->vbi_read_timeout_file = file; - - /* initialize the brs */ - if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { - saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19)); - } else { - saa7146_write(dev, BRS_CTRL, 0x00000001); - - if (0 != (ret = vbi_workaround(dev))) { - DEB_VBI("vbi workaround failed!\n"); - /* return ret;*/ - } - } - - /* upload brs register */ - saa7146_write(dev, MC2, (MASK_08|MASK_24)); - return 0; -} - -static void vbi_close(struct saa7146_dev *dev, struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_vv *vv = dev->vv_data; - DEB_VBI("dev:%p, fh:%p\n", dev, fh); - - if( fh == vv->vbi_streaming ) { - vbi_stop(fh, file); - } - saa7146_res_free(fh, RESOURCE_DMA3_BRS); -} - -static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) -{ - struct saa7146_vv *vv = dev->vv_data; - spin_lock(&dev->slock); - - if (vv->vbi_dmaq.curr) { - DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr); - /* this must be += 2, one count for each field */ - vv->vbi_fieldcount+=2; - vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount; - saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE); - } else { - DEB_VBI("dev:%p\n", dev); - } - saa7146_buffer_next(dev, &vv->vbi_dmaq, 1); - - spin_unlock(&dev->slock); -} - -static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - ssize_t ret = 0; - - DEB_VBI("dev:%p, fh:%p\n", dev, fh); - - if( NULL == vv->vbi_streaming ) { - // fixme: check if dma3 is available - // fixme: activate vbi engine here if necessary. (really?) - vv->vbi_streaming = fh; - } - - if( fh != vv->vbi_streaming ) { - DEB_VBI("open %p is already using vbi capture\n", - vv->vbi_streaming); - return -EBUSY; - } - - mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT); - ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1, - file->f_flags & O_NONBLOCK); -/* - printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3)); - printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3)); - printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3)); - printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3)); - printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3)); - printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3)); - printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL)); -*/ - return ret; -} - -const struct saa7146_use_ops saa7146_vbi_uops = { - .init = vbi_init, - .open = vbi_open, - .release = vbi_close, - .irq_done = vbi_irq_done, - .read = vbi_read, -}; diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_video.c b/drivers/staging/media/deprecated/saa7146/common/saa7146_video.c deleted file mode 100644 index 4598a44231fa..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_video.c +++ /dev/null @@ -1,1286 +0,0 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <media/v4l2-event.h> -#include <media/v4l2-ctrls.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include "saa7146_vv.h" - -static int max_memory = 32; - -module_param(max_memory, int, 0644); -MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)"); - -#define IS_CAPTURE_ACTIVE(fh) \ - (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh)) - -#define IS_OVERLAY_ACTIVE(fh) \ - (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh)) - -/* format descriptions for capture and preview */ -static struct saa7146_format formats[] = { - { - .pixelformat = V4L2_PIX_FMT_RGB332, - .trans = RGB08_COMPOSED, - .depth = 8, - .flags = 0, - }, { - .pixelformat = V4L2_PIX_FMT_RGB565, - .trans = RGB16_COMPOSED, - .depth = 16, - .flags = 0, - }, { - .pixelformat = V4L2_PIX_FMT_BGR24, - .trans = RGB24_COMPOSED, - .depth = 24, - .flags = 0, - }, { - .pixelformat = V4L2_PIX_FMT_BGR32, - .trans = RGB32_COMPOSED, - .depth = 32, - .flags = 0, - }, { - .pixelformat = V4L2_PIX_FMT_RGB32, - .trans = RGB32_COMPOSED, - .depth = 32, - .flags = 0, - .swap = 0x2, - }, { - .pixelformat = V4L2_PIX_FMT_GREY, - .trans = Y8, - .depth = 8, - .flags = 0, - }, { - .pixelformat = V4L2_PIX_FMT_YUV422P, - .trans = YUV422_DECOMPOSED, - .depth = 16, - .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, - }, { - .pixelformat = V4L2_PIX_FMT_YVU420, - .trans = YUV420_DECOMPOSED, - .depth = 12, - .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR, - }, { - .pixelformat = V4L2_PIX_FMT_YUV420, - .trans = YUV420_DECOMPOSED, - .depth = 12, - .flags = FORMAT_IS_PLANAR, - }, { - .pixelformat = V4L2_PIX_FMT_UYVY, - .trans = YUV422_COMPOSED, - .depth = 16, - .flags = 0, - } -}; - -/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps. - due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped - (like V4L2_PIX_FMT_YUYV) ... 8-( */ - -struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(formats); i++) { - if (formats[i].pixelformat == fourcc) { - return formats+i; - } - } - - DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc); - return NULL; -} - -static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); - -int saa7146_start_preview(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct v4l2_format fmt; - int ret = 0, err = 0; - - DEB_EE("dev:%p, fh:%p\n", dev, fh); - - /* check if we have overlay information */ - if (vv->ov.fh == NULL) { - DEB_D("no overlay data available. try S_FMT first.\n"); - return -EAGAIN; - } - - /* check if streaming capture is running */ - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_D("streaming capture is active\n"); - return -EBUSY; - } - - /* check if overlay is running */ - if (IS_OVERLAY_ACTIVE(fh) != 0) { - if (vv->video_fh == fh) { - DEB_D("overlay is already active\n"); - return 0; - } - DEB_D("overlay is already active in another open\n"); - return -EBUSY; - } - - if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) { - DEB_D("cannot get necessary overlay resources\n"); - return -EBUSY; - } - - fmt.fmt.win = vv->ov.win; - err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); - if (0 != err) { - saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); - return -EBUSY; - } - vv->ov.win = fmt.fmt.win; - - DEB_D("%dx%d+%d+%d 0x%08x field=%s\n", - vv->ov.win.w.width, vv->ov.win.w.height, - vv->ov.win.w.left, vv->ov.win.w.top, - vv->ov_fmt->pixelformat, v4l2_field_names[vv->ov.win.field]); - - if (0 != (ret = saa7146_enable_overlay(fh))) { - DEB_D("enabling overlay failed: %d\n", ret); - saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); - return ret; - } - - vv->video_status = STATUS_OVERLAY; - vv->video_fh = fh; - - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_start_preview); - -int saa7146_stop_preview(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - - DEB_EE("dev:%p, fh:%p\n", dev, fh); - - /* check if streaming capture is running */ - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_D("streaming capture is active\n"); - return -EBUSY; - } - - /* check if overlay is running at all */ - if ((vv->video_status & STATUS_OVERLAY) == 0) { - DEB_D("no active overlay\n"); - return 0; - } - - if (vv->video_fh != fh) { - DEB_D("overlay is active, but in another open\n"); - return -EBUSY; - } - - vv->video_status = 0; - vv->video_fh = NULL; - - saa7146_disable_overlay(fh); - - saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); - - return 0; -} -EXPORT_SYMBOL_GPL(saa7146_stop_preview); - -/********************************************************************************/ -/* common pagetable functions */ - -static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) -{ - struct pci_dev *pci = dev->pci; - struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); - struct scatterlist *list = dma->sglist; - int length = dma->sglen; - struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); - - DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length); - - if( 0 != IS_PLANAR(sfmt->trans)) { - struct saa7146_pgtable *pt1 = &buf->pt[0]; - struct saa7146_pgtable *pt2 = &buf->pt[1]; - struct saa7146_pgtable *pt3 = &buf->pt[2]; - __le32 *ptr1, *ptr2, *ptr3; - __le32 fill; - - int size = buf->fmt->width*buf->fmt->height; - int i,p,m1,m2,m3,o1,o2; - - switch( sfmt->depth ) { - case 12: { - /* create some offsets inside the page table */ - m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; - m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1; - m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; - o1 = size%PAGE_SIZE; - o2 = (size+(size/4))%PAGE_SIZE; - DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", - size, m1, m2, m3, o1, o2); - break; - } - case 16: { - /* create some offsets inside the page table */ - m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1; - m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1; - m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1; - o1 = size%PAGE_SIZE; - o2 = (size+(size/2))%PAGE_SIZE; - DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n", - size, m1, m2, m3, o1, o2); - break; - } - default: { - return -1; - } - } - - ptr1 = pt1->cpu; - ptr2 = pt2->cpu; - ptr3 = pt3->cpu; - - /* walk all pages, copy all page addresses to ptr1 */ - for (i = 0; i < length; i++, list++) { - for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr1++) - *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset); - } -/* - ptr1 = pt1->cpu; - for(j=0;j<40;j++) { - printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); - } -*/ - - /* if we have a user buffer, the first page may not be - aligned to a page boundary. */ - pt1->offset = dma->sglist->offset; - pt2->offset = pt1->offset+o1; - pt3->offset = pt1->offset+o2; - - /* create video-dma2 page table */ - ptr1 = pt1->cpu; - for(i = m1; i <= m2 ; i++, ptr2++) { - *ptr2 = ptr1[i]; - } - fill = *(ptr2-1); - for(;i<1024;i++,ptr2++) { - *ptr2 = fill; - } - /* create video-dma3 page table */ - ptr1 = pt1->cpu; - for(i = m2; i <= m3; i++,ptr3++) { - *ptr3 = ptr1[i]; - } - fill = *(ptr3-1); - for(;i<1024;i++,ptr3++) { - *ptr3 = fill; - } - /* finally: finish up video-dma1 page table */ - ptr1 = pt1->cpu+m1; - fill = pt1->cpu[m1]; - for(i=m1;i<1024;i++,ptr1++) { - *ptr1 = fill; - } -/* - ptr1 = pt1->cpu; - ptr2 = pt2->cpu; - ptr3 = pt3->cpu; - for(j=0;j<40;j++) { - printk("ptr1 %d: 0x%08x\n",j,ptr1[j]); - } - for(j=0;j<40;j++) { - printk("ptr2 %d: 0x%08x\n",j,ptr2[j]); - } - for(j=0;j<40;j++) { - printk("ptr3 %d: 0x%08x\n",j,ptr3[j]); - } -*/ - } else { - struct saa7146_pgtable *pt = &buf->pt[0]; - return saa7146_pgtable_build_single(pci, pt, list, length); - } - - return 0; -} - - -/********************************************************************************/ -/* file operations */ - -static int video_begin(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *fmt = NULL; - unsigned int resource; - int ret = 0, err = 0; - - DEB_EE("dev:%p, fh:%p\n", dev, fh); - - if ((vv->video_status & STATUS_CAPTURE) != 0) { - if (vv->video_fh == fh) { - DEB_S("already capturing\n"); - return 0; - } - DEB_S("already capturing in another open\n"); - return -EBUSY; - } - - if ((vv->video_status & STATUS_OVERLAY) != 0) { - DEB_S("warning: suspending overlay video for streaming capture\n"); - vv->ov_suspend = vv->video_fh; - err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ - if (0 != err) { - DEB_D("suspending video failed. aborting\n"); - return err; - } - } - - fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); - /* we need to have a valid format set here */ - if (!fmt) - return -EINVAL; - - if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { - resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; - } else { - resource = RESOURCE_DMA1_HPS; - } - - ret = saa7146_res_get(fh, resource); - if (0 == ret) { - DEB_S("cannot get capture resource %d\n", resource); - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - return -EBUSY; - } - - /* clear out beginning of streaming bit (rps register 0)*/ - saa7146_write(dev, MC2, MASK_27 ); - - /* enable rps0 irqs */ - SAA7146_IER_ENABLE(dev, MASK_27); - - vv->video_fh = fh; - vv->video_status = STATUS_CAPTURE; - - return 0; -} - -static int video_end(struct saa7146_fh *fh, struct file *file) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_dmaqueue *q = &vv->video_dmaq; - struct saa7146_format *fmt = NULL; - unsigned long flags; - unsigned int resource; - u32 dmas = 0; - DEB_EE("dev:%p, fh:%p\n", dev, fh); - - if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { - DEB_S("not capturing\n"); - return 0; - } - - if (vv->video_fh != fh) { - DEB_S("capturing, but in another open\n"); - return -EBUSY; - } - - fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat); - /* we need to have a valid format set here */ - if (!fmt) - return -EINVAL; - - if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { - resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS; - dmas = MASK_22 | MASK_21 | MASK_20; - } else { - resource = RESOURCE_DMA1_HPS; - dmas = MASK_22; - } - spin_lock_irqsave(&dev->slock,flags); - - /* disable rps0 */ - saa7146_write(dev, MC1, MASK_28); - - /* disable rps0 irqs */ - SAA7146_IER_DISABLE(dev, MASK_27); - - /* shut down all used video dma transfers */ - saa7146_write(dev, MC1, dmas); - - if (q->curr) - saa7146_buffer_finish(dev, q, VIDEOBUF_DONE); - - spin_unlock_irqrestore(&dev->slock, flags); - - vv->video_fh = NULL; - vv->video_status = 0; - - saa7146_res_free(fh, resource); - - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - - return 0; -} - -static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - - strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver)); - strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | - V4L2_CAP_DEVICE_CAPS; - cap->capabilities |= dev->ext_vv_data->capabilities; - return 0; -} - -static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - *fb = vv->ov_fb; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - fb->flags = V4L2_FBUF_FLAG_PRIMARY; - return 0; -} - -static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *fmt; - - DEB_EE("VIDIOC_S_FBUF\n"); - - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* check args */ - fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; - - /* planar formats are not allowed for overlay video, clipping and video dma would clash */ - if (fmt->flags & FORMAT_IS_PLANAR) - DEB_S("planar pixelformat '%4.4s' not allowed for overlay\n", - (char *)&fmt->pixelformat); - - /* check if overlay is running */ - if (IS_OVERLAY_ACTIVE(fh) != 0) { - if (vv->video_fh != fh) { - DEB_D("refusing to change framebuffer information while overlay is active in another open\n"); - return -EBUSY; - } - } - - /* ok, accept it */ - vv->ov_fb = *fb; - vv->ov_fmt = fmt; - - if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) { - vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8; - DEB_D("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline); - } - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) -{ - if (f->index >= ARRAY_SIZE(formats)) - return -EINVAL; - f->pixelformat = formats[f->index].pixelformat; - return 0; -} - -int saa7146_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct saa7146_dev *dev = container_of(ctrl->handler, - struct saa7146_dev, ctrl_handler); - struct saa7146_vv *vv = dev->vv_data; - u32 val; - - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - val = saa7146_read(dev, BCS_CTRL); - val &= 0x00ffffff; - val |= (ctrl->val << 24); - saa7146_write(dev, BCS_CTRL, val); - saa7146_write(dev, MC2, MASK_22 | MASK_06); - break; - - case V4L2_CID_CONTRAST: - val = saa7146_read(dev, BCS_CTRL); - val &= 0xff00ffff; - val |= (ctrl->val << 16); - saa7146_write(dev, BCS_CTRL, val); - saa7146_write(dev, MC2, MASK_22 | MASK_06); - break; - - case V4L2_CID_SATURATION: - val = saa7146_read(dev, BCS_CTRL); - val &= 0xffffff00; - val |= (ctrl->val << 0); - saa7146_write(dev, BCS_CTRL, val); - saa7146_write(dev, MC2, MASK_22 | MASK_06); - break; - - case V4L2_CID_HFLIP: - /* fixme: we can support changing VFLIP and HFLIP here... */ - if ((vv->video_status & STATUS_CAPTURE)) - return -EBUSY; - vv->hflip = ctrl->val; - break; - - case V4L2_CID_VFLIP: - if ((vv->video_status & STATUS_CAPTURE)) - return -EBUSY; - vv->vflip = ctrl->val; - break; - - default: - return -EINVAL; - } - - if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */ - struct saa7146_fh *fh = vv->video_fh; - - saa7146_stop_preview(fh); - saa7146_start_preview(fh); - } - return 0; -} - -static int vidioc_g_parm(struct file *file, void *fh, - struct v4l2_streamparm *parm) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - parm->parm.capture.readbuffers = 1; - v4l2_video_std_frame_period(vv->standard->id, - &parm->parm.capture.timeperframe); - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - f->fmt.pix = vv->video_fmt; - return 0; -} - -static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - f->fmt.win = vv->ov.win; - return 0; -} - -static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - f->fmt.vbi = vv->vbi_fmt; - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_format *fmt; - enum v4l2_field field; - int maxw, maxh; - int calc_bpl; - - DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh); - - fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; - - field = f->fmt.pix.field; - maxw = vv->standard->h_max_out; - maxh = vv->standard->v_max_out; - - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh / 2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - switch (field) { - case V4L2_FIELD_ALTERNATE: - vv->last_field = V4L2_FIELD_TOP; - maxh = maxh / 2; - break; - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - vv->last_field = V4L2_FIELD_INTERLACED; - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - vv->last_field = V4L2_FIELD_INTERLACED; - break; - default: - DEB_D("no known field mode '%d'\n", field); - return -EINVAL; - } - - f->fmt.pix.field = field; - f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - - calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; - - if (f->fmt.pix.bytesperline < calc_bpl) - f->fmt.pix.bytesperline = calc_bpl; - - if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ - f->fmt.pix.bytesperline = calc_bpl; - - f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; - DEB_D("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", - f->fmt.pix.width, f->fmt.pix.height, - f->fmt.pix.bytesperline, f->fmt.pix.sizeimage); - - return 0; -} - - -static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - struct v4l2_window *win = &f->fmt.win; - enum v4l2_field field; - int maxw, maxh; - - DEB_EE("dev:%p\n", dev); - - if (NULL == vv->ov_fb.base) { - DEB_D("no fb base set\n"); - return -EINVAL; - } - if (NULL == vv->ov_fmt) { - DEB_D("no fb fmt set\n"); - return -EINVAL; - } - if (win->w.width < 48 || win->w.height < 32) { - DEB_D("min width/height. (%d,%d)\n", - win->w.width, win->w.height); - return -EINVAL; - } - if (win->clipcount > 16) { - DEB_D("clipcount too big\n"); - return -EINVAL; - } - - field = win->field; - maxw = vv->standard->h_max_out; - maxh = vv->standard->v_max_out; - - if (V4L2_FIELD_ANY == field) { - field = (win->w.height > maxh / 2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; - } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_ALTERNATE: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - DEB_D("no known field mode '%d'\n", field); - return -EINVAL; - } - - win->field = field; - if (win->w.width > maxw) - win->w.width = maxw; - if (win->w.height > maxh) - win->w.height = maxh; - - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh); - if (IS_CAPTURE_ACTIVE(fh) != 0) { - DEB_EE("streaming capture is active\n"); - return -EBUSY; - } - err = vidioc_try_fmt_vid_cap(file, fh, f); - if (0 != err) - return err; - vv->video_fmt = f->fmt.pix; - DEB_EE("set to pixelformat '%4.4s'\n", - (char *)&vv->video_fmt.pixelformat); - return 0; -} - -static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_EE("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh); - err = vidioc_try_fmt_vid_overlay(file, fh, f); - if (0 != err) - return err; - vv->ov.win = f->fmt.win; - vv->ov.nclips = f->fmt.win.clipcount; - if (vv->ov.nclips > 16) - vv->ov.nclips = 16; - memcpy(vv->ov.clips, f->fmt.win.clips, - sizeof(struct v4l2_clip) * vv->ov.nclips); - - /* vv->ov.fh is used to indicate that we have valid overlay information, too */ - vv->ov.fh = fh; - - /* check if our current overlay is active */ - if (IS_OVERLAY_ACTIVE(fh) != 0) { - saa7146_stop_preview(fh); - saa7146_start_preview(fh); - } - return 0; -} - -static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - - *norm = vv->standard->id; - return 0; -} - - /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) - PAL / NTSC / SECAM. if your hardware does not (or does more) - -- override this function in your extension */ -/* - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - if (e->index < 0 ) - return -EINVAL; - if( e->index < dev->ext_vv_data->num_stds ) { - DEB_EE("VIDIOC_ENUMSTD: index:%d\n", e->index); - v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name); - return 0; - } - return -EINVAL; - } - */ - -static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct saa7146_vv *vv = dev->vv_data; - int found = 0; - int err, i; - - DEB_EE("VIDIOC_S_STD\n"); - - if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { - DEB_D("cannot change video standard while streaming capture is active\n"); - return -EBUSY; - } - - if ((vv->video_status & STATUS_OVERLAY) != 0) { - vv->ov_suspend = vv->video_fh; - err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ - if (0 != err) { - DEB_D("suspending video failed. aborting\n"); - return err; - } - } - - for (i = 0; i < dev->ext_vv_data->num_stds; i++) - if (id & dev->ext_vv_data->stds[i].id) - break; - if (i != dev->ext_vv_data->num_stds) { - vv->standard = &dev->ext_vv_data->stds[i]; - if (NULL != dev->ext_vv_data->std_callback) - dev->ext_vv_data->std_callback(dev, vv->standard); - found = 1; - } - - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - - if (!found) { - DEB_EE("VIDIOC_S_STD: standard not found\n"); - return -EINVAL; - } - - DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name); - return 0; -} - -static int vidioc_overlay(struct file *file, void *fh, unsigned int on) -{ - int err; - - DEB_D("VIDIOC_OVERLAY on:%d\n", on); - if (on) - err = saa7146_start_preview(fh); - else - err = saa7146_stop_preview(fh); - return err; -} - -static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) -{ - struct saa7146_fh *fh = __fh; - - if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_reqbufs(&fh->video_q, b); - if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_reqbufs(&fh->vbi_q, b); - return -EINVAL; -} - -static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_querybuf(&fh->video_q, buf); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_querybuf(&fh->vbi_q, buf); - return -EINVAL; -} - -static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_qbuf(&fh->video_q, buf); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_qbuf(&fh->vbi_q, buf); - return -EINVAL; -} - -static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) -{ - struct saa7146_fh *fh = __fh; - - if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); - if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); - return -EINVAL; -} - -static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct saa7146_fh *fh = __fh; - int err; - - DEB_D("VIDIOC_STREAMON, type:%d\n", type); - - err = video_begin(fh); - if (err) - return err; - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - return videobuf_streamon(&fh->video_q); - if (type == V4L2_BUF_TYPE_VBI_CAPTURE) - return videobuf_streamon(&fh->vbi_q); - return -EINVAL; -} - -static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) -{ - struct saa7146_fh *fh = __fh; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - int err; - - DEB_D("VIDIOC_STREAMOFF, type:%d\n", type); - - /* ugly: we need to copy some checks from video_end(), - because videobuf_streamoff() relies on the capture running. - check and fix this */ - if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { - DEB_S("not capturing\n"); - return 0; - } - - if (vv->video_fh != fh) { - DEB_S("capturing, but in another open\n"); - return -EBUSY; - } - - err = -EINVAL; - if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - err = videobuf_streamoff(&fh->video_q); - else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) - err = videobuf_streamoff(&fh->vbi_q); - if (0 != err) { - DEB_D("warning: videobuf_streamoff() failed\n"); - video_end(fh, file); - } else { - err = video_end(fh, file); - } - return err; -} - -const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, - - .vidioc_overlay = vidioc_overlay, - .vidioc_g_fbuf = vidioc_g_fbuf, - .vidioc_s_fbuf = vidioc_s_fbuf, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_g_std = vidioc_g_std, - .vidioc_s_std = vidioc_s_std, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_parm = vidioc_g_parm, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -}; - -const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, - - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_g_std = vidioc_g_std, - .vidioc_s_std = vidioc_s_std, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_parm = vidioc_g_parm, - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -}; - -/*********************************************************************************/ -/* buffer handling functions */ - -static int buffer_activate (struct saa7146_dev *dev, - struct saa7146_buf *buf, - struct saa7146_buf *next) -{ - struct saa7146_vv *vv = dev->vv_data; - - buf->vb.state = VIDEOBUF_ACTIVE; - saa7146_set_capture(dev,buf,next); - - mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT); - return 0; -} - -static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf) -{ - saa7146_pgtable_free(dev->pci, &buf->pt[0]); - saa7146_pgtable_free(dev->pci, &buf->pt[1]); - saa7146_pgtable_free(dev->pci, &buf->pt[2]); -} - -static int buffer_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - int size,err = 0; - - DEB_CAP("vbuf:%p\n", vb); - - /* sanity checks */ - if (vv->video_fmt.width < 48 || - vv->video_fmt.height < 32 || - vv->video_fmt.width > vv->standard->h_max_out || - vv->video_fmt.height > vv->standard->v_max_out) { - DEB_D("w (%d) / h (%d) out of bounds\n", - vv->video_fmt.width, vv->video_fmt.height); - return -EINVAL; - } - - size = vv->video_fmt.sizeimage; - if (0 != buf->vb.baddr && buf->vb.bsize < size) { - DEB_D("size mismatch\n"); - return -EINVAL; - } - - DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n", - vv->video_fmt.width, vv->video_fmt.height, - size, v4l2_field_names[vv->video_fmt.field]); - if (buf->vb.width != vv->video_fmt.width || - buf->vb.bytesperline != vv->video_fmt.bytesperline || - buf->vb.height != vv->video_fmt.height || - buf->vb.size != size || - buf->vb.field != field || - buf->vb.field != vv->video_fmt.field || - buf->fmt != &vv->video_fmt) { - saa7146_dma_free(dev,q,buf); - } - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - struct saa7146_format *sfmt; - - buf->vb.bytesperline = vv->video_fmt.bytesperline; - buf->vb.width = vv->video_fmt.width; - buf->vb.height = vv->video_fmt.height; - buf->vb.size = size; - buf->vb.field = field; - buf->fmt = &vv->video_fmt; - buf->vb.field = vv->video_fmt.field; - - sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); - - release_all_pagetables(dev, buf); - if( 0 != IS_PLANAR(sfmt->trans)) { - saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); - saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); - saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); - } else { - saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); - } - - err = videobuf_iolock(q,&buf->vb, &vv->ov_fb); - if (err) - goto oops; - err = saa7146_pgtable_build(dev,buf); - if (err) - goto oops; - } - buf->vb.state = VIDEOBUF_PREPARED; - buf->activate = buffer_activate; - - return 0; - - oops: - DEB_D("error out\n"); - saa7146_dma_free(dev,q,buf); - - return err; -} - -static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_vv *vv = fh->dev->vv_data; - - if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS) - *count = MAX_SAA7146_CAPTURE_BUFFERS; - - *size = vv->video_fmt.sizeimage; - - /* check if we exceed the "max_memory" parameter */ - if( (*count * *size) > (max_memory*1048576) ) { - *count = (max_memory*1048576) / *size; - } - - DEB_CAP("%d buffers, %d bytes each\n", *count, *size); - - return 0; -} - -static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - - DEB_CAP("vbuf:%p\n", vb); - saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf); -} - -static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct file *file = q->priv_data; - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_buf *buf = (struct saa7146_buf *)vb; - - DEB_CAP("vbuf:%p\n", vb); - - saa7146_dma_free(dev,q,buf); - - release_all_pagetables(dev, buf); -} - -static const struct videobuf_queue_ops video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -/********************************************************************************/ -/* file operations */ - -static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) -{ - INIT_LIST_HEAD(&vv->video_dmaq.queue); - - timer_setup(&vv->video_dmaq.timeout, saa7146_buffer_timeout, 0); - vv->video_dmaq.dev = dev; - - /* set some default values */ - vv->standard = &dev->ext_vv_data->stds[0]; - - /* FIXME: what's this? */ - vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A; - vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A; -} - - -static int video_open(struct saa7146_dev *dev, struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - - videobuf_queue_sg_init(&fh->video_q, &video_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct saa7146_buf), - file, &dev->v4l2_lock); - - return 0; -} - - -static void video_close(struct saa7146_dev *dev, struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_vv *vv = dev->vv_data; - struct videobuf_queue *q = &fh->video_q; - - if (IS_CAPTURE_ACTIVE(fh) != 0) - video_end(fh, file); - else if (IS_OVERLAY_ACTIVE(fh) != 0) - saa7146_stop_preview(fh); - - videobuf_stop(q); - /* hmm, why is this function declared void? */ -} - - -static void video_irq_done(struct saa7146_dev *dev, unsigned long st) -{ - struct saa7146_vv *vv = dev->vv_data; - struct saa7146_dmaqueue *q = &vv->video_dmaq; - - spin_lock(&dev->slock); - DEB_CAP("called\n"); - - /* only finish the buffer if we have one... */ - if( NULL != q->curr ) { - saa7146_buffer_finish(dev,q,VIDEOBUF_DONE); - } - saa7146_buffer_next(dev,q,0); - - spin_unlock(&dev->slock); -} - -static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - ssize_t ret = 0; - - DEB_EE("called\n"); - - if ((vv->video_status & STATUS_CAPTURE) != 0) { - /* fixme: should we allow read() captures while streaming capture? */ - if (vv->video_fh == fh) { - DEB_S("already capturing\n"); - return -EBUSY; - } - DEB_S("already capturing in another open\n"); - return -EBUSY; - } - - ret = video_begin(fh); - if( 0 != ret) { - goto out; - } - - ret = videobuf_read_one(&fh->video_q , data, count, ppos, - file->f_flags & O_NONBLOCK); - if (ret != 0) { - video_end(fh, file); - } else { - ret = video_end(fh, file); - } -out: - /* restart overlay if it was active before */ - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - - return ret; -} - -const struct saa7146_use_ops saa7146_video_uops = { - .init = video_init, - .open = video_open, - .release = video_close, - .irq_done = video_irq_done, - .read = video_read, -}; diff --git a/drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h b/drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h deleted file mode 100644 index d7bd916fe3ad..000000000000 --- a/drivers/staging/media/deprecated/saa7146/common/saa7146_vv.h +++ /dev/null @@ -1,266 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __SAA7146_VV__ -#define __SAA7146_VV__ - -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/v4l2-fh.h> -#include <media/videobuf-dma-sg.h> -#include "saa7146.h" - -#define MAX_SAA7146_CAPTURE_BUFFERS 32 /* arbitrary */ -#define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */ - -#define WRITE_RPS0(x) do { \ - dev->d_rps0.cpu_addr[ count++ ] = cpu_to_le32(x); \ - } while (0); - -#define WRITE_RPS1(x) do { \ - dev->d_rps1.cpu_addr[ count++ ] = cpu_to_le32(x); \ - } while (0); - -struct saa7146_video_dma { - u32 base_odd; - u32 base_even; - u32 prot_addr; - u32 pitch; - u32 base_page; - u32 num_line_byte; -}; - -#define FORMAT_BYTE_SWAP 0x1 -#define FORMAT_IS_PLANAR 0x2 - -struct saa7146_format { - u32 pixelformat; - u32 trans; - u8 depth; - u8 flags; - u8 swap; -}; - -struct saa7146_standard -{ - char *name; - v4l2_std_id id; - - int v_offset; /* number of lines of vertical offset before processing */ - int v_field; /* number of lines in a field for HPS to process */ - - int h_offset; /* horizontal offset of processing window */ - int h_pixels; /* number of horizontal pixels to process */ - - int v_max_out; - int h_max_out; -}; - -/* buffer for one video/vbi frame */ -struct saa7146_buf { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - /* saa7146 specific */ - struct v4l2_pix_format *fmt; - int (*activate)(struct saa7146_dev *dev, - struct saa7146_buf *buf, - struct saa7146_buf *next); - - /* page tables */ - struct saa7146_pgtable pt[3]; -}; - -struct saa7146_dmaqueue { - struct saa7146_dev *dev; - struct saa7146_buf *curr; - struct list_head queue; - struct timer_list timeout; -}; - -struct saa7146_overlay { - struct saa7146_fh *fh; - struct v4l2_window win; - struct v4l2_clip clips[16]; - int nclips; -}; - -/* per open data */ -struct saa7146_fh { - /* Must be the first field! */ - struct v4l2_fh fh; - struct saa7146_dev *dev; - - /* video capture */ - struct videobuf_queue video_q; - - /* vbi capture */ - struct videobuf_queue vbi_q; - - unsigned int resources; /* resource management for device open */ -}; - -#define STATUS_OVERLAY 0x01 -#define STATUS_CAPTURE 0x02 - -struct saa7146_vv -{ - /* vbi capture */ - struct saa7146_dmaqueue vbi_dmaq; - struct v4l2_vbi_format vbi_fmt; - struct timer_list vbi_read_timeout; - struct file *vbi_read_timeout_file; - /* vbi workaround interrupt queue */ - wait_queue_head_t vbi_wq; - int vbi_fieldcount; - struct saa7146_fh *vbi_streaming; - - int video_status; - struct saa7146_fh *video_fh; - - /* video overlay */ - struct saa7146_overlay ov; - struct v4l2_framebuffer ov_fb; - struct saa7146_format *ov_fmt; - struct saa7146_fh *ov_suspend; - - /* video capture */ - struct saa7146_dmaqueue video_dmaq; - struct v4l2_pix_format video_fmt; - enum v4l2_field last_field; - - /* common: fixme? shouldn't this be in saa7146_fh? - (this leads to a more complicated question: shall the driver - store the different settings (for example S_INPUT) for every open - and restore it appropriately, or should all settings be common for - all opens? currently, we do the latter, like all other - drivers do... */ - struct saa7146_standard *standard; - - int vflip; - int hflip; - int current_hps_source; - int current_hps_sync; - - struct saa7146_dma d_clipping; /* pointer to clipping memory */ - - unsigned int resources; /* resource management for device */ -}; - -/* flags */ -#define SAA7146_USE_PORT_B_FOR_VBI 0x2 /* use input port b for vbi hardware bug workaround */ - -struct saa7146_ext_vv -{ - /* information about the video capabilities of the device */ - int inputs; - int audios; - u32 capabilities; - int flags; - - /* additionally supported transmission standards */ - struct saa7146_standard *stds; - int num_stds; - int (*std_callback)(struct saa7146_dev*, struct saa7146_standard *); - - /* the extension can override this */ - struct v4l2_ioctl_ops vid_ops; - struct v4l2_ioctl_ops vbi_ops; - /* pointer to the saa7146 core ops */ - const struct v4l2_ioctl_ops *core_ops; - - struct v4l2_file_operations vbi_fops; -}; - -struct saa7146_use_ops { - void (*init)(struct saa7146_dev *, struct saa7146_vv *); - int(*open)(struct saa7146_dev *, struct file *); - void (*release)(struct saa7146_dev *, struct file *); - void (*irq_done)(struct saa7146_dev *, unsigned long status); - ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); -}; - -/* from saa7146_fops.c */ -int saa7146_register_device(struct video_device *vid, struct saa7146_dev *dev, char *name, int type); -int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev *dev); -void saa7146_buffer_finish(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, int state); -void saa7146_buffer_next(struct saa7146_dev *dev, struct saa7146_dmaqueue *q,int vbi); -int saa7146_buffer_queue(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, struct saa7146_buf *buf); -void saa7146_buffer_timeout(struct timer_list *t); -void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q, - struct saa7146_buf *buf); - -int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv); -int saa7146_vv_release(struct saa7146_dev* dev); - -/* from saa7146_hlp.c */ -int saa7146_enable_overlay(struct saa7146_fh *fh); -void saa7146_disable_overlay(struct saa7146_fh *fh); - -void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next); -void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma) ; -void saa7146_set_hps_source_and_sync(struct saa7146_dev *saa, int source, int sync); -void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data); - -/* from saa7146_video.c */ -extern const struct v4l2_ioctl_ops saa7146_video_ioctl_ops; -extern const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops; -extern const struct saa7146_use_ops saa7146_video_uops; -int saa7146_start_preview(struct saa7146_fh *fh); -int saa7146_stop_preview(struct saa7146_fh *fh); -long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); -int saa7146_s_ctrl(struct v4l2_ctrl *ctrl); - -/* from saa7146_vbi.c */ -extern const struct saa7146_use_ops saa7146_vbi_uops; - -/* resource management functions */ -int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit); -void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits); - -#define RESOURCE_DMA1_HPS 0x1 -#define RESOURCE_DMA2_CLP 0x2 -#define RESOURCE_DMA3_BRS 0x4 - -/* saa7146 source inputs */ -#define SAA7146_HPS_SOURCE_PORT_A 0x00 -#define SAA7146_HPS_SOURCE_PORT_B 0x01 -#define SAA7146_HPS_SOURCE_YPB_CPA 0x02 -#define SAA7146_HPS_SOURCE_YPA_CPB 0x03 - -/* sync inputs */ -#define SAA7146_HPS_SYNC_PORT_A 0x00 -#define SAA7146_HPS_SYNC_PORT_B 0x01 - -/* some memory sizes */ -/* max. 16 clipping rectangles */ -#define SAA7146_CLIPPING_MEM (16 * 4 * sizeof(u32)) - -/* some defines for the various clipping-modes */ -#define SAA7146_CLIPPING_RECT 0x4 -#define SAA7146_CLIPPING_RECT_INVERTED 0x5 -#define SAA7146_CLIPPING_MASK 0x6 -#define SAA7146_CLIPPING_MASK_INVERTED 0x7 - -/* output formats: each entry holds four information */ -#define RGB08_COMPOSED 0x0217 /* composed is used in the sense of "not-planar" */ -/* this means: planar?=0, yuv2rgb-conversation-mode=2, dither=yes(=1), format-mode = 7 */ -#define RGB15_COMPOSED 0x0213 -#define RGB16_COMPOSED 0x0210 -#define RGB24_COMPOSED 0x0201 -#define RGB32_COMPOSED 0x0202 - -#define Y8 0x0006 -#define YUV411_COMPOSED 0x0003 -#define YUV422_COMPOSED 0x0000 -/* this means: planar?=1, yuv2rgb-conversion-mode=0, dither=no(=0), format-mode = b */ -#define YUV411_DECOMPOSED 0x100b -#define YUV422_DECOMPOSED 0x1009 -#define YUV420_DECOMPOSED 0x100a - -#define IS_PLANAR(x) (x & 0xf000) - -/* misc defines */ -#define SAA7146_NO_SWAP (0x0) -#define SAA7146_TWO_BYTE_SWAP (0x1) -#define SAA7146_FOUR_BYTE_SWAP (0x2) - -#endif diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/Kconfig b/drivers/staging/media/deprecated/saa7146/saa7146/Kconfig deleted file mode 100644 index 228e8d3f8d2b..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/Kconfig +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config VIDEO_HEXIUM_GEMINI - tristate "Hexium Gemini frame grabber (DEPRECATED)" - depends on PCI && VIDEO_DEV && I2C - select VIDEO_SAA7146_VV - help - This is a video4linux driver for the Hexium Gemini frame - grabber card by Hexium. Please note that the Gemini Dual - card is *not* fully supported. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - To compile this driver as a module, choose M here: the - module will be called hexium_gemini. - -config VIDEO_HEXIUM_ORION - tristate "Hexium HV-PCI6 and Orion frame grabber (DEPRECATED)" - depends on PCI && VIDEO_DEV && I2C - select VIDEO_SAA7146_VV - help - This is a video4linux driver for the Hexium HV-PCI6 and - Orion frame grabber cards by Hexium. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - To compile this driver as a module, choose M here: the - module will be called hexium_orion. - -config VIDEO_MXB - tristate "Siemens-Nixdorf 'Multimedia eXtension Board' (DEPRECATED)" - depends on PCI && VIDEO_DEV && I2C - select VIDEO_SAA7146_VV - select VIDEO_TUNER - select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TDA9840 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TEA6415C if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_TEA6420 if MEDIA_SUBDRV_AUTOSELECT - help - This is a video4linux driver for the 'Multimedia eXtension Board' - TV card by Siemens-Nixdorf. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - To compile this driver as a module, choose M here: the - module will be called mxb. diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/Makefile b/drivers/staging/media/deprecated/saa7146/saa7146/Makefile deleted file mode 100644 index 37c9336f83d5..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_MXB) += mxb.o -obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o -obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o - -ccflags-y += -I$(srctree)/drivers/media/i2c diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/TODO b/drivers/staging/media/deprecated/saa7146/saa7146/TODO deleted file mode 100644 index c9ae2ec79cea..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/TODO +++ /dev/null @@ -1,7 +0,0 @@ -The saa7146-based drivers are one of the few drivers still not using -the vb2 framework, so these drivers are now deprecated with the intent of -removing them altogether by the beginning of 2023. - -In order to keep these drivers they have to be converted to vb2. -If someone is interested in doing this work, then contact the -linux-media mailinglist (https://linuxtv.org/lists.php). diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c deleted file mode 100644 index 124e82bd4507..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/hexium_gemini.c +++ /dev/null @@ -1,425 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards - - Visit http://www.mihu.de/linux/saa7146/ and follow the link - to "hexium" for further details about this card. - - Copyright (C) 2003 Michael Hunold <michael@mihu.de> - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define DEBUG_VARIABLE debug - -#include <linux/module.h> -#include <linux/kernel.h> -#include "../common/saa7146_vv.h" - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "debug verbosity"); - -/* global variables */ -static int hexium_num; - -#define HEXIUM_GEMINI 4 -#define HEXIUM_GEMINI_DUAL 5 - -#define HEXIUM_INPUTS 9 -static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { - { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, -}; - -#define HEXIUM_AUDIOS 0 - -struct hexium_data -{ - s8 adr; - u8 byte; -}; - -#define HEXIUM_GEMINI_V_1_0 1 -#define HEXIUM_GEMINI_DUAL_V_1_0 2 - -struct hexium -{ - int type; - - struct video_device video_dev; - struct i2c_adapter i2c_adapter; - - int cur_input; /* current input */ - v4l2_std_id cur_std; /* current standard */ -}; - -/* Samsung KS0127B decoder default registers */ -static u8 hexium_ks0127b[0x100]={ -/*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10, -/*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06, -/*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00, -/*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22, -/*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00, -/*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80, -/*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00, -/*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -/*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 -}; - -static struct hexium_data hexium_pal[] = { - { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF } -}; - -static struct hexium_data hexium_ntsc[] = { - { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF } -}; - -static struct hexium_data hexium_secam[] = { - { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF } -}; - -static struct hexium_data hexium_input_select[] = { - { 0x02, 0x60 }, - { 0x02, 0x64 }, - { 0x02, 0x61 }, - { 0x02, 0x65 }, - { 0x02, 0x62 }, - { 0x02, 0x66 }, - { 0x02, 0x68 }, - { 0x02, 0x69 }, - { 0x02, 0x6A }, -}; - -/* fixme: h_offset = 0 for Hexium Gemini *Dual*, which - are currently *not* supported*/ -static struct saa7146_standard hexium_standards[] = { - { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 28, .v_field = 288, - .h_offset = 1, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 28, .v_field = 240, - .h_offset = 1, .h_pixels = 640, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 28, .v_field = 288, - .h_offset = 1, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int hexium_init_done(struct saa7146_dev *dev) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - union i2c_smbus_data data; - int i = 0; - - DEB_D("hexium_init_done called\n"); - - /* initialize the helper ics to useful values */ - for (i = 0; i < sizeof(hexium_ks0127b); i++) { - data.byte = hexium_ks0127b[i]; - if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) { - pr_err("hexium_init_done() failed for address 0x%02x\n", - i); - } - } - - return 0; -} - -static int hexium_set_input(struct hexium *hexium, int input) -{ - union i2c_smbus_data data; - - DEB_D("\n"); - - data.byte = hexium_input_select[input].byte; - if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) { - return -1; - } - - return 0; -} - -static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec) -{ - union i2c_smbus_data data; - int i = 0; - - DEB_D("\n"); - - while (vdec[i].adr != -1) { - data.byte = vdec[i].byte; - if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) { - pr_err("hexium_init_done: hexium_set_standard() failed for address 0x%02x\n", - i); - return -1; - } - i++; - } - return 0; -} - -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); - - if (i->index >= HEXIUM_INPUTS) - return -EINVAL; - - memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D("v4l2_ioctl: VIDIOC_ENUMINPUT %d\n", i->index); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - *input = hexium->cur_input; - - DEB_D("VIDIOC_G_INPUT: %d\n", *input); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - DEB_EE("VIDIOC_S_INPUT %d\n", input); - - if (input >= HEXIUM_INPUTS) - return -EINVAL; - - hexium->cur_input = input; - hexium_set_input(hexium, input); - return 0; -} - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct hexium *hexium; - int ret; - - DEB_EE("\n"); - - hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); - if (!hexium) - return -ENOMEM; - - dev->ext_priv = hexium; - - /* enable i2c-port pins */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - - strscpy(hexium->i2c_adapter.name, "hexium gemini", - sizeof(hexium->i2c_adapter.name)); - saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { - DEB_S("cannot register i2c-device. skipping.\n"); - kfree(hexium); - return -EFAULT; - } - - /* set HWControl GPIO number 2 */ - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - - saa7146_write(dev, DD1_INIT, 0x07000700); - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - /* the rest */ - hexium->cur_input = 0; - hexium_init_done(dev); - - hexium_set_standard(hexium, hexium_pal); - hexium->cur_std = V4L2_STD_PAL; - - hexium_set_input(hexium, 0); - hexium->cur_input = 0; - - ret = saa7146_vv_init(dev, &vv_data); - if (ret) { - i2c_del_adapter(&hexium->i2c_adapter); - kfree(hexium); - return ret; - } - - vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; - vv_data.vid_ops.vidioc_g_input = vidioc_g_input; - vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_VIDEO); - if (ret < 0) { - pr_err("cannot register capture v4l2 device. skipping.\n"); - saa7146_vv_release(dev); - i2c_del_adapter(&hexium->i2c_adapter); - kfree(hexium); - return ret; - } - - pr_info("found 'hexium gemini' frame grabber-%d\n", hexium_num); - hexium_num++; - - return 0; -} - -static int hexium_detach(struct saa7146_dev *dev) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - DEB_EE("dev:%p\n", dev); - - saa7146_unregister_device(&hexium->video_dev, dev); - saa7146_vv_release(dev); - - hexium_num--; - - i2c_del_adapter(&hexium->i2c_adapter); - kfree(hexium); - return 0; -} - -static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - if (V4L2_STD_PAL == std->id) { - hexium_set_standard(hexium, hexium_pal); - hexium->cur_std = V4L2_STD_PAL; - return 0; - } else if (V4L2_STD_NTSC == std->id) { - hexium_set_standard(hexium, hexium_ntsc); - hexium->cur_std = V4L2_STD_NTSC; - return 0; - } else if (V4L2_STD_SECAM == std->id) { - hexium_set_standard(hexium, hexium_secam); - hexium->cur_std = V4L2_STD_SECAM; - return 0; - } - - return -1; -} - -static struct saa7146_extension hexium_extension; - -static struct saa7146_pci_extension_data hexium_gemini_4bnc = { - .ext_priv = "Hexium Gemini (4 BNC)", - .ext = &hexium_extension, -}; - -static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = { - .ext_priv = "Hexium Gemini Dual (4 BNC)", - .ext = &hexium_extension, -}; - -static const struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x17c8, - .subdevice = 0x2401, - .driver_data = (unsigned long) &hexium_gemini_4bnc, - }, - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x17c8, - .subdevice = 0x2402, - .driver_data = (unsigned long) &hexium_gemini_dual_4bnc, - }, - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = HEXIUM_INPUTS, - .capabilities = 0, - .stds = &hexium_standards[0], - .num_stds = ARRAY_SIZE(hexium_standards), - .std_callback = &std_callback, -}; - -static struct saa7146_extension hexium_extension = { - .name = "hexium gemini", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .attach = hexium_attach, - .detach = hexium_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init hexium_init_module(void) -{ - if (0 != saa7146_register_extension(&hexium_extension)) { - DEB_S("failed to register extension\n"); - return -ENODEV; - } - - return 0; -} - -static void __exit hexium_cleanup_module(void) -{ - saa7146_unregister_extension(&hexium_extension); -} - -module_init(hexium_init_module); -module_exit(hexium_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards"); -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c b/drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c deleted file mode 100644 index ebd63998ac79..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/hexium_orion.c +++ /dev/null @@ -1,496 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards - - Visit http://www.mihu.de/linux/saa7146/ and follow the link - to "hexium" for further details about this card. - - Copyright (C) 2003 Michael Hunold <michael@mihu.de> - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define DEBUG_VARIABLE debug - -#include <linux/module.h> -#include <linux/kernel.h> -#include "../common/saa7146_vv.h" - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "debug verbosity"); - -/* global variables */ -static int hexium_num; - -#define HEXIUM_HV_PCI6_ORION 1 -#define HEXIUM_ORION_1SVHS_3BNC 2 -#define HEXIUM_ORION_4BNC 3 - -#define HEXIUM_INPUTS 9 -static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = { - { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, -}; - -#define HEXIUM_AUDIOS 0 - -struct hexium_data -{ - s8 adr; - u8 byte; -}; - -struct hexium -{ - int type; - struct video_device video_dev; - struct i2c_adapter i2c_adapter; - - int cur_input; /* current input */ -}; - -/* Philips SAA7110 decoder default registers */ -static u8 hexium_saa7110[53]={ -/*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00, -/*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90, -/*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA, -/*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00, -/*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F, -/*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03, -/*30*/ 0x44,0x75,0x01,0x8C,0x03 -}; - -static struct { - struct hexium_data data[8]; -} hexium_input_select[] = { -{ - { /* cvbs 1 */ - { 0x06, 0x00 }, - { 0x20, 0xD9 }, - { 0x21, 0x17 }, // 0x16, - { 0x22, 0x40 }, - { 0x2C, 0x03 }, - { 0x30, 0x44 }, - { 0x31, 0x75 }, // ?? - { 0x21, 0x16 }, // 0x03, - } -}, { - { /* cvbs 2 */ - { 0x06, 0x00 }, - { 0x20, 0x78 }, - { 0x21, 0x07 }, // 0x03, - { 0x22, 0xD2 }, - { 0x2C, 0x83 }, - { 0x30, 0x60 }, - { 0x31, 0xB5 }, // ? - { 0x21, 0x03 }, - } -}, { - { /* cvbs 3 */ - { 0x06, 0x00 }, - { 0x20, 0xBA }, - { 0x21, 0x07 }, // 0x05, - { 0x22, 0x91 }, - { 0x2C, 0x03 }, - { 0x30, 0x60 }, - { 0x31, 0xB5 }, // ?? - { 0x21, 0x05 }, // 0x03, - } -}, { - { /* cvbs 4 */ - { 0x06, 0x00 }, - { 0x20, 0xD8 }, - { 0x21, 0x17 }, // 0x16, - { 0x22, 0x40 }, - { 0x2C, 0x03 }, - { 0x30, 0x44 }, - { 0x31, 0x75 }, // ?? - { 0x21, 0x16 }, // 0x03, - } -}, { - { /* cvbs 5 */ - { 0x06, 0x00 }, - { 0x20, 0xB8 }, - { 0x21, 0x07 }, // 0x05, - { 0x22, 0x91 }, - { 0x2C, 0x03 }, - { 0x30, 0x60 }, - { 0x31, 0xB5 }, // ?? - { 0x21, 0x05 }, // 0x03, - } -}, { - { /* cvbs 6 */ - { 0x06, 0x00 }, - { 0x20, 0x7C }, - { 0x21, 0x07 }, // 0x03 - { 0x22, 0xD2 }, - { 0x2C, 0x83 }, - { 0x30, 0x60 }, - { 0x31, 0xB5 }, // ?? - { 0x21, 0x03 }, - } -}, { - { /* y/c 1 */ - { 0x06, 0x80 }, - { 0x20, 0x59 }, - { 0x21, 0x17 }, - { 0x22, 0x42 }, - { 0x2C, 0xA3 }, - { 0x30, 0x44 }, - { 0x31, 0x75 }, - { 0x21, 0x12 }, - } -}, { - { /* y/c 2 */ - { 0x06, 0x80 }, - { 0x20, 0x9A }, - { 0x21, 0x17 }, - { 0x22, 0xB1 }, - { 0x2C, 0x13 }, - { 0x30, 0x60 }, - { 0x31, 0xB5 }, - { 0x21, 0x14 }, - } -}, { - { /* y/c 3 */ - { 0x06, 0x80 }, - { 0x20, 0x3C }, - { 0x21, 0x27 }, - { 0x22, 0xC1 }, - { 0x2C, 0x23 }, - { 0x30, 0x44 }, - { 0x31, 0x75 }, - { 0x21, 0x21 }, - } -} -}; - -static struct saa7146_standard hexium_standards[] = { - { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 16, .v_field = 288, - .h_offset = 1, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 16, .v_field = 240, - .h_offset = 1, .h_pixels = 640, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 16, .v_field = 288, - .h_offset = 1, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -/* this is only called for old HV-PCI6/Orion cards - without eeprom */ -static int hexium_probe(struct saa7146_dev *dev) -{ - struct hexium *hexium = NULL; - union i2c_smbus_data data; - int err = 0; - - DEB_EE("\n"); - - /* there are no hexium orion cards with revision 0 saa7146s */ - if (0 == dev->revision) { - return -EFAULT; - } - - hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); - if (!hexium) - return -ENOMEM; - - /* enable i2c-port pins */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - - saa7146_write(dev, DD1_INIT, 0x01000100); - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - strscpy(hexium->i2c_adapter.name, "hexium orion", - sizeof(hexium->i2c_adapter.name)); - saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { - DEB_S("cannot register i2c-device. skipping.\n"); - kfree(hexium); - return -EFAULT; - } - - /* set SAA7110 control GPIO 0 */ - saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI); - /* set HWControl GPIO number 2 */ - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - - mdelay(10); - - /* detect newer Hexium Orion cards by subsystem ids */ - if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) { - pr_info("device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs\n"); - /* we store the pointer in our private data field */ - dev->ext_priv = hexium; - hexium->type = HEXIUM_ORION_1SVHS_3BNC; - return 0; - } - - if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) { - pr_info("device is a Hexium Orion w/ 4 BNC inputs\n"); - /* we store the pointer in our private data field */ - dev->ext_priv = hexium; - hexium->type = HEXIUM_ORION_4BNC; - return 0; - } - - /* check if this is an old hexium Orion card by looking at - a saa7110 at address 0x4e */ - err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, - 0x00, I2C_SMBUS_BYTE_DATA, &data); - if (err == 0) { - pr_info("device is a Hexium HV-PCI6/Orion (old)\n"); - /* we store the pointer in our private data field */ - dev->ext_priv = hexium; - hexium->type = HEXIUM_HV_PCI6_ORION; - return 0; - } - - i2c_del_adapter(&hexium->i2c_adapter); - kfree(hexium); - return -EFAULT; -} - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int hexium_init_done(struct saa7146_dev *dev) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - union i2c_smbus_data data; - int i = 0; - - DEB_D("hexium_init_done called\n"); - - /* initialize the helper ics to useful values */ - for (i = 0; i < sizeof(hexium_saa7110); i++) { - data.byte = hexium_saa7110[i]; - if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) { - pr_err("failed for address 0x%02x\n", i); - } - } - - return 0; -} - -static int hexium_set_input(struct hexium *hexium, int input) -{ - union i2c_smbus_data data; - int i = 0; - - DEB_D("\n"); - - for (i = 0; i < 8; i++) { - int adr = hexium_input_select[input].data[i].adr; - data.byte = hexium_input_select[input].data[i].byte; - if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, adr, I2C_SMBUS_BYTE_DATA, &data)) { - return -1; - } - pr_debug("%d: 0x%02x => 0x%02x\n", input, adr, data.byte); - } - - return 0; -} - -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); - - if (i->index >= HEXIUM_INPUTS) - return -EINVAL; - - memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D("v4l2_ioctl: VIDIOC_ENUMINPUT %d\n", i->index); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - *input = hexium->cur_input; - - DEB_D("VIDIOC_G_INPUT: %d\n", *input); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - if (input >= HEXIUM_INPUTS) - return -EINVAL; - - hexium->cur_input = input; - hexium_set_input(hexium, input); - - return 0; -} - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - int ret; - - DEB_EE("\n"); - - ret = saa7146_vv_init(dev, &vv_data); - if (ret) { - pr_err("Error in saa7146_vv_init()\n"); - return ret; - } - - vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; - vv_data.vid_ops.vidioc_g_input = vidioc_g_input; - vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_VIDEO)) { - pr_err("cannot register capture v4l2 device. skipping.\n"); - return -1; - } - - pr_err("found 'hexium orion' frame grabber-%d\n", hexium_num); - hexium_num++; - - /* the rest */ - hexium->cur_input = 0; - hexium_init_done(dev); - - return 0; -} - -static int hexium_detach(struct saa7146_dev *dev) -{ - struct hexium *hexium = (struct hexium *) dev->ext_priv; - - DEB_EE("dev:%p\n", dev); - - saa7146_unregister_device(&hexium->video_dev, dev); - saa7146_vv_release(dev); - - hexium_num--; - - i2c_del_adapter(&hexium->i2c_adapter); - kfree(hexium); - return 0; -} - -static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std) -{ - return 0; -} - -static struct saa7146_extension extension; - -static struct saa7146_pci_extension_data hexium_hv_pci6 = { - .ext_priv = "Hexium HV-PCI6 / Orion", - .ext = &extension, -}; - -static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = { - .ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)", - .ext = &extension, -}; - -static struct saa7146_pci_extension_data hexium_orion_4bnc = { - .ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)", - .ext = &extension, -}; - -static const struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x0000, - .subdevice = 0x0000, - .driver_data = (unsigned long) &hexium_hv_pci6, - }, - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x17c8, - .subdevice = 0x0101, - .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc, - }, - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x17c8, - .subdevice = 0x2101, - .driver_data = (unsigned long) &hexium_orion_4bnc, - }, - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = HEXIUM_INPUTS, - .capabilities = 0, - .stds = &hexium_standards[0], - .num_stds = ARRAY_SIZE(hexium_standards), - .std_callback = &std_callback, -}; - -static struct saa7146_extension extension = { - .name = "hexium HV-PCI6 Orion", - .flags = 0, // SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .probe = hexium_probe, - .attach = hexium_attach, - .detach = hexium_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init hexium_init_module(void) -{ - if (0 != saa7146_register_extension(&extension)) { - DEB_S("failed to register extension\n"); - return -ENODEV; - } - - return 0; -} - -static void __exit hexium_cleanup_module(void) -{ - saa7146_unregister_extension(&extension); -} - -module_init(hexium_init_module); -module_exit(hexium_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards"); -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/saa7146/mxb.c b/drivers/staging/media/deprecated/saa7146/saa7146/mxb.c deleted file mode 100644 index 3e568f952dae..000000000000 --- a/drivers/staging/media/deprecated/saa7146/saa7146/mxb.c +++ /dev/null @@ -1,873 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - mxb - v4l2 driver for the Multimedia eXtension Board - - Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de> - - Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html - for further details about this card. - -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#define DEBUG_VARIABLE debug - -#include <media/tuner.h> -#include <media/v4l2-common.h> -#include <media/i2c/saa7115.h> -#include <linux/module.h> -#include <linux/kernel.h> - -#include "../common/saa7146_vv.h" -#include "tea6415c.h" -#include "tea6420.h" - -#define MXB_AUDIOS 6 - -#define I2C_SAA7111A 0x24 -#define I2C_TDA9840 0x42 -#define I2C_TEA6415C 0x43 -#define I2C_TEA6420_1 0x4c -#define I2C_TEA6420_2 0x4d -#define I2C_TUNER 0x60 - -#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) - -/* global variable */ -static int mxb_num; - -/* initial frequence the tuner will be tuned to. - in verden (lower saxony, germany) 4148 is a - channel called "phoenix" */ -static int freq = 4148; -module_param(freq, int, 0644); -MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); - -#define MXB_INPUTS 4 -enum { TUNER, AUX1, AUX3, AUX3_YC }; - -static struct v4l2_input mxb_inputs[MXB_INPUTS] = { - { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0, - V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, - { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, - { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, - V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, -}; - -/* this array holds the information, which port of the saa7146 each - input actually uses. the mxb uses port 0 for every input */ -static struct { - int hps_source; - int hps_sync; -} input_port_selection[MXB_INPUTS] = { - { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, - { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, - { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, - { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, -}; - -/* this array holds the information of the audio source (mxb_audios), - which has to be switched corresponding to the video source (mxb_channels) */ -static int video_audio_connect[MXB_INPUTS] = - { 0, 1, 3, 3 }; - -struct mxb_routing { - u32 input; - u32 output; -}; - -/* these are the available audio sources, which can switched - to the line- and cd-output individually */ -static struct v4l2_audio mxb_audios[MXB_AUDIOS] = { - { - .index = 0, - .name = "Tuner", - .capability = V4L2_AUDCAP_STEREO, - } , { - .index = 1, - .name = "AUX1", - .capability = V4L2_AUDCAP_STEREO, - } , { - .index = 2, - .name = "AUX2", - .capability = V4L2_AUDCAP_STEREO, - } , { - .index = 3, - .name = "AUX3", - .capability = V4L2_AUDCAP_STEREO, - } , { - .index = 4, - .name = "Radio (X9)", - .capability = V4L2_AUDCAP_STEREO, - } , { - .index = 5, - .name = "CD-ROM (X10)", - .capability = V4L2_AUDCAP_STEREO, - } -}; - -/* These are the necessary input-output-pins for bringing one audio source - (see above) to the CD-output. Note that gain is set to 0 in this table. */ -static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { - { { 1, 1 }, { 1, 1 } }, /* Tuner */ - { { 5, 1 }, { 6, 1 } }, /* AUX 1 */ - { { 4, 1 }, { 6, 1 } }, /* AUX 2 */ - { { 3, 1 }, { 6, 1 } }, /* AUX 3 */ - { { 1, 1 }, { 3, 1 } }, /* Radio */ - { { 1, 1 }, { 2, 1 } }, /* CD-Rom */ - { { 6, 1 }, { 6, 1 } } /* Mute */ -}; - -/* These are the necessary input-output-pins for bringing one audio source - (see above) to the line-output. Note that gain is set to 0 in this table. */ -static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = { - { { 2, 3 }, { 1, 2 } }, - { { 5, 3 }, { 6, 2 } }, - { { 4, 3 }, { 6, 2 } }, - { { 3, 3 }, { 6, 2 } }, - { { 2, 3 }, { 3, 2 } }, - { { 2, 3 }, { 2, 2 } }, - { { 6, 3 }, { 6, 2 } } /* Mute */ -}; - -struct mxb -{ - struct video_device video_dev; - struct video_device vbi_dev; - - struct i2c_adapter i2c_adapter; - - struct v4l2_subdev *saa7111a; - struct v4l2_subdev *tda9840; - struct v4l2_subdev *tea6415c; - struct v4l2_subdev *tuner; - struct v4l2_subdev *tea6420_1; - struct v4l2_subdev *tea6420_2; - - int cur_mode; /* current audio mode (mono, stereo, ...) */ - int cur_input; /* current input */ - int cur_audinput; /* current audio input */ - int cur_mute; /* current mute status */ - struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ -}; - -#define saa7111a_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->saa7111a, o, f, ##args) -#define tda9840_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tda9840, o, f, ##args) -#define tea6415c_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tea6415c, o, f, ##args) -#define tuner_call(mxb, o, f, args...) \ - v4l2_subdev_call(mxb->tuner, o, f, ##args) -#define call_all(dev, o, f, args...) \ - v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) - -static void mxb_update_audmode(struct mxb *mxb) -{ - struct v4l2_tuner t = { - .audmode = mxb->cur_mode, - }; - - tda9840_call(mxb, tuner, s_tuner, &t); -} - -static inline void tea6420_route(struct mxb *mxb, int idx) -{ - v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, - TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0); - v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, - TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0); - v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, - TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0); - v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, - TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0); -} - -static struct saa7146_extension extension; - -static int mxb_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct saa7146_dev *dev = container_of(ctrl->handler, - struct saa7146_dev, ctrl_handler); - struct mxb *mxb = dev->ext_priv; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - mxb->cur_mute = ctrl->val; - /* switch the audio-source */ - tea6420_route(mxb, ctrl->val ? 6 : - video_audio_connect[mxb->cur_input]); - break; - default: - return -EINVAL; - } - return 0; -} - -static const struct v4l2_ctrl_ops mxb_ctrl_ops = { - .s_ctrl = mxb_s_ctrl, -}; - -static int mxb_probe(struct saa7146_dev *dev) -{ - struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; - struct mxb *mxb = NULL; - - v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops, - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); - if (hdl->error) - return hdl->error; - mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); - if (mxb == NULL) { - DEB_D("not enough kernel memory\n"); - return -ENOMEM; - } - - - snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); - - saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if (i2c_add_adapter(&mxb->i2c_adapter) < 0) { - DEB_S("cannot register i2c-device. skipping.\n"); - kfree(mxb); - return -EFAULT; - } - - mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "saa7111", I2C_SAA7111A, NULL); - mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "tea6420", I2C_TEA6420_1, NULL); - mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "tea6420", I2C_TEA6420_2, NULL); - mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "tea6415c", I2C_TEA6415C, NULL); - mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "tda9840", I2C_TDA9840, NULL); - mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, - "tuner", I2C_TUNER, NULL); - - /* check if all devices are present */ - if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || - !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) { - pr_err("did not find all i2c devices. aborting\n"); - i2c_del_adapter(&mxb->i2c_adapter); - kfree(mxb); - return -ENODEV; - } - - /* all devices are present, probe was successful */ - - /* we store the pointer in our private data field */ - dev->ext_priv = mxb; - - v4l2_ctrl_handler_setup(hdl); - - return 0; -} - -/* some init data for the saa7740, the so-called 'sound arena module'. - there are no specs available, so we simply use some init values */ -static struct { - int length; - char data[9]; -} mxb_saa7740_init[] = { - { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } }, - { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } }, - { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } }, - { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } }, - { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } }, - { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } }, - { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } }, - { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } }, - { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } }, - { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } }, - { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } }, - { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } }, - { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } }, - { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } }, - { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } }, - { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } }, - { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } }, - { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } }, - { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } }, - { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } }, - { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } }, - { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } }, - { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } }, - { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } }, - { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } }, - { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } }, - { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } }, - { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } }, - { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } }, - { 3, { 0x48, 0x00, 0x01 } }, - { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } }, - { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } }, - { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } }, - { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } }, - { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } }, - { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } }, - { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } }, - { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } }, - { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } }, - { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } }, - { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } }, - { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } }, - { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } }, - { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } }, - { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, - { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, - { 3, { 0x80, 0xb3, 0x0a } }, - {-1, { 0 } } -}; - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int mxb_init_done(struct saa7146_dev* dev) -{ - struct mxb* mxb = (struct mxb*)dev->ext_priv; - struct i2c_msg msg; - struct tuner_setup tun_setup; - v4l2_std_id std = V4L2_STD_PAL_BG; - - int i, err = 0; - - /* mute audio on tea6420s */ - tea6420_route(mxb, 6); - - /* select video mode in saa7111a */ - saa7111a_call(mxb, video, s_std, std); - - /* select tuner-output on saa7111a */ - saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, - SAA7111_FMT_CCIR, 0); - - /* select a tuner type */ - tun_setup.mode_mask = T_ANALOG_TV; - tun_setup.addr = ADDR_UNSET; - tun_setup.type = TUNER_PHILIPS_PAL; - tuner_call(mxb, tuner, s_type_addr, &tun_setup); - /* tune in some frequency on tuner */ - mxb->cur_freq.tuner = 0; - mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV; - mxb->cur_freq.frequency = freq; - tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); - - /* set a default video standard */ - /* These two gpio calls set the GPIO pins that control the tda9820 */ - saa7146_write(dev, GPIO_CTRL, 0x00404050); - saa7111a_call(mxb, core, s_gpio, 1); - saa7111a_call(mxb, video, s_std, std); - tuner_call(mxb, video, s_std, std); - - /* switch to tuner-channel on tea6415c */ - tea6415c_call(mxb, video, s_routing, 3, 17, 0); - - /* select tuner-output on multicable on tea6415c */ - tea6415c_call(mxb, video, s_routing, 3, 13, 0); - - /* the rest for mxb */ - mxb->cur_input = 0; - mxb->cur_audinput = video_audio_connect[mxb->cur_input]; - mxb->cur_mute = 1; - - mxb->cur_mode = V4L2_TUNER_MODE_STEREO; - mxb_update_audmode(mxb); - - /* check if the saa7740 (aka 'sound arena module') is present - on the mxb. if so, we must initialize it. due to lack of - information about the saa7740, the values were reverse - engineered. */ - msg.addr = 0x1b; - msg.flags = 0; - msg.len = mxb_saa7740_init[0].length; - msg.buf = &mxb_saa7740_init[0].data[0]; - - err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); - if (err == 1) { - /* the sound arena module is a pos, that's probably the reason - philips refuses to hand out a datasheet for the saa7740... - it seems to screw up the i2c bus, so we disable fast irq - based i2c transactions here and rely on the slow and safe - polling method ... */ - extension.flags &= ~SAA7146_USE_I2C_IRQ; - for (i = 1; ; i++) { - if (-1 == mxb_saa7740_init[i].length) - break; - - msg.len = mxb_saa7740_init[i].length; - msg.buf = &mxb_saa7740_init[i].data[0]; - err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); - if (err != 1) { - DEB_D("failed to initialize 'sound arena module'\n"); - goto err; - } - } - pr_info("'sound arena module' detected\n"); - } -err: - /* the rest for saa7146: you should definitely set some basic values - for the input-port handling of the saa7146. */ - - /* ext->saa has been filled by the core driver */ - - /* some stuff is done via variables */ - saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, - input_port_selection[mxb->cur_input].hps_sync); - - /* some stuff is done via direct write to the registers */ - - /* this is ugly, but because of the fact that this is completely - hardware dependend, it should be done directly... */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x02000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - return 0; -} - -/* interrupt-handler. this gets called when irq_mask is != 0. - it must clear the interrupt-bits in irq_mask it has handled */ -/* -void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask) -{ - struct mxb* mxb = (struct mxb*)dev->ext_priv; -} -*/ - -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); - if (i->index >= MXB_INPUTS) - return -EINVAL; - memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - *i = mxb->cur_input; - - DEB_EE("VIDIOC_G_INPUT %d\n", *i); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - int err = 0; - int i = 0; - - DEB_EE("VIDIOC_S_INPUT %d\n", input); - - if (input >= MXB_INPUTS) - return -EINVAL; - - mxb->cur_input = input; - - saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, - input_port_selection[input].hps_sync); - - /* prepare switching of tea6415c and saa7111a; - have a look at the 'background'-file for further information */ - switch (input) { - case TUNER: - i = SAA7115_COMPOSITE0; - - err = tea6415c_call(mxb, video, s_routing, 3, 17, 0); - - /* connect tuner-output always to multicable */ - if (!err) - err = tea6415c_call(mxb, video, s_routing, 3, 13, 0); - break; - case AUX3_YC: - /* nothing to be done here. aux3_yc is - directly connected to the saa711a */ - i = SAA7115_SVIDEO1; - break; - case AUX3: - /* nothing to be done here. aux3 is - directly connected to the saa711a */ - i = SAA7115_COMPOSITE1; - break; - case AUX1: - i = SAA7115_COMPOSITE0; - err = tea6415c_call(mxb, video, s_routing, 1, 17, 0); - break; - } - - if (err) - return err; - - /* switch video in saa7111a */ - if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) - pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); - - mxb->cur_audinput = video_audio_connect[input]; - /* switch the audio-source only if necessary */ - if (0 == mxb->cur_mute) - tea6420_route(mxb, mxb->cur_audinput); - if (mxb->cur_audinput == 0) - mxb_update_audmode(mxb); - - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - if (t->index) { - DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n", - t->index); - return -EINVAL; - } - - DEB_EE("VIDIOC_G_TUNER: %d\n", t->index); - - memset(t, 0, sizeof(*t)); - strscpy(t->name, "TV Tuner", sizeof(t->name)); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - t->audmode = mxb->cur_mode; - return call_all(dev, tuner, g_tuner, t); -} - -static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - if (t->index) { - DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n", - t->index); - return -EINVAL; - } - - mxb->cur_mode = t->audmode; - return call_all(dev, tuner, s_tuner, t); -} - -static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - - return call_all(dev, video, querystd, norm); -} - -static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - if (f->tuner) - return -EINVAL; - *f = mxb->cur_freq; - - DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency); - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - struct saa7146_vv *vv = dev->vv_data; - - if (f->tuner) - return -EINVAL; - - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - - DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency); - - /* tune in desired frequency */ - tuner_call(mxb, tuner, s_frequency, f); - /* let the tuner subdev clamp the frequency to the tuner range */ - mxb->cur_freq = *f; - tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq); - if (mxb->cur_audinput == 0) - mxb_update_audmode(mxb); - - if (mxb->cur_input) - return 0; - - /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ - spin_lock(&dev->slock); - vv->vbi_fieldcount = 0; - spin_unlock(&dev->slock); - - return 0; -} - -static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) -{ - if (a->index >= MXB_AUDIOS) - return -EINVAL; - *a = mxb_audios[a->index]; - return 0; -} - -static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - DEB_EE("VIDIOC_G_AUDIO\n"); - *a = mxb_audios[mxb->cur_audinput]; - return 0; -} - -static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - DEB_D("VIDIOC_S_AUDIO %d\n", a->index); - if (a->index >= 32 || - !(mxb_inputs[mxb->cur_input].audioset & (1 << a->index))) - return -EINVAL; - - if (mxb->cur_audinput != a->index) { - mxb->cur_audinput = a->index; - tea6420_route(mxb, a->index); - if (mxb->cur_audinput == 0) - mxb_update_audmode(mxb); - } - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - - if (reg->reg > pci_resource_len(dev->pci, 0) - 4) - return -EINVAL; - reg->val = saa7146_read(dev, reg->reg); - reg->size = 4; - return 0; -} - -static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - - if (reg->reg > pci_resource_len(dev->pci, 0) - 4) - return -EINVAL; - saa7146_write(dev, reg->reg, reg->val); - return 0; -} -#endif - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct mxb *mxb; - int ret; - - DEB_EE("dev:%p\n", dev); - - ret = saa7146_vv_init(dev, &vv_data); - if (ret) { - ERR("Error in saa7146_vv_init()"); - return ret; - } - - if (mxb_probe(dev)) { - saa7146_vv_release(dev); - return -1; - } - mxb = (struct mxb *)dev->ext_priv; - - vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; - vv_data.vid_ops.vidioc_g_input = vidioc_g_input; - vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - vv_data.vid_ops.vidioc_querystd = vidioc_querystd; - vv_data.vid_ops.vidioc_g_tuner = vidioc_g_tuner; - vv_data.vid_ops.vidioc_s_tuner = vidioc_s_tuner; - vv_data.vid_ops.vidioc_g_frequency = vidioc_g_frequency; - vv_data.vid_ops.vidioc_s_frequency = vidioc_s_frequency; - vv_data.vid_ops.vidioc_enumaudio = vidioc_enumaudio; - vv_data.vid_ops.vidioc_g_audio = vidioc_g_audio; - vv_data.vid_ops.vidioc_s_audio = vidioc_s_audio; -#ifdef CONFIG_VIDEO_ADV_DEBUG - vv_data.vid_ops.vidioc_g_register = vidioc_g_register; - vv_data.vid_ops.vidioc_s_register = vidioc_s_register; -#endif - if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_VIDEO)) { - ERR("cannot register capture v4l2 device. skipping.\n"); - saa7146_vv_release(dev); - return -1; - } - - /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if (MXB_BOARD_CAN_DO_VBI(dev)) { - if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { - ERR("cannot register vbi v4l2 device. skipping.\n"); - } - } - - pr_info("found Multimedia eXtension Board #%d\n", mxb_num); - - mxb_num++; - mxb_init_done(dev); - return 0; -} - -static int mxb_detach(struct saa7146_dev *dev) -{ - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - DEB_EE("dev:%p\n", dev); - - /* mute audio on tea6420s */ - tea6420_route(mxb, 6); - - saa7146_unregister_device(&mxb->video_dev,dev); - if (MXB_BOARD_CAN_DO_VBI(dev)) - saa7146_unregister_device(&mxb->vbi_dev, dev); - saa7146_vv_release(dev); - - mxb_num--; - - i2c_del_adapter(&mxb->i2c_adapter); - kfree(mxb); - - return 0; -} - -static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard) -{ - struct mxb *mxb = (struct mxb *)dev->ext_priv; - - if (V4L2_STD_PAL_I == standard->id) { - v4l2_std_id std = V4L2_STD_PAL_I; - - DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n"); - /* These two gpio calls set the GPIO pins that control the tda9820 */ - saa7146_write(dev, GPIO_CTRL, 0x00404050); - saa7111a_call(mxb, core, s_gpio, 0); - saa7111a_call(mxb, video, s_std, std); - if (mxb->cur_input == 0) - tuner_call(mxb, video, s_std, std); - } else { - v4l2_std_id std = V4L2_STD_PAL_BG; - - if (mxb->cur_input) - std = standard->id; - DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n"); - /* These two gpio calls set the GPIO pins that control the tda9820 */ - saa7146_write(dev, GPIO_CTRL, 0x00404050); - saa7111a_call(mxb, core, s_gpio, 1); - saa7111a_call(mxb, video, s_std, std); - if (mxb->cur_input == 0) - tuner_call(mxb, video, s_std, std); - } - return 0; -} - -static struct saa7146_standard standard[] = { - { - .name = "PAL-BG", .id = V4L2_STD_PAL_BG, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "PAL-I", .id = V4L2_STD_PAL_I, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x16, .v_field = 240, - .h_offset = 0x06, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x14, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -static struct saa7146_pci_extension_data mxb = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, -}; - -static const struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x0000, - .subdevice = 0x0000, - .driver_data = (unsigned long)&mxb, - }, { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = MXB_INPUTS, - .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO, - .stds = &standard[0], - .num_stds = ARRAY_SIZE(standard), - .std_callback = &std_callback, -}; - -static struct saa7146_extension extension = { - .name = "Multimedia eXtension Board", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .attach = mxb_attach, - .detach = mxb_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init mxb_init_module(void) -{ - if (saa7146_register_extension(&extension)) { - DEB_S("failed to register extension\n"); - return -ENODEV; - } - - return 0; -} - -static void __exit mxb_cleanup_module(void) -{ - saa7146_unregister_extension(&extension); -} - -module_init(mxb_init_module); -module_exit(mxb_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'"); -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/Kconfig b/drivers/staging/media/deprecated/saa7146/ttpci/Kconfig deleted file mode 100644 index 8c85ed58e938..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/Kconfig +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config DVB_BUDGET_CORE - tristate "SAA7146 DVB cards (aka Budget, Nova-PCI) (DEPRECATED)" - depends on DVB_CORE && PCI && I2C - select VIDEO_SAA7146 - select TTPCI_EEPROM - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder. - -config DVB_BUDGET - tristate "Budget cards (DEPRECATED)" - depends on DVB_BUDGET_CORE && I2C - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT - select DVB_VES1820 if MEDIA_SUBDRV_AUTOSELECT - select DVB_L64781 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT - select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA10086 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA826X if MEDIA_SUBDRV_AUTOSELECT - select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT - select DVB_ISL6423 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT - help - Support for simple SAA7146 based DVB cards (so called Budget- - or Nova-PCI cards) without onboard MPEG2 decoder, and without - analog inputs or an onboard Common Interface connector. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget. - -config DVB_BUDGET_CI - tristate "Budget cards with onboard CI connector (DEPRECATED)" - depends on DVB_BUDGET_CORE && I2C - select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT - select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STB6100 if MEDIA_SUBDRV_AUTOSELECT - select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT - select MEDIA_TUNER_TDA827X if MEDIA_SUBDRV_AUTOSELECT - depends on RC_CORE - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder, but with onboard Common Interface connector. - - Note: The Common Interface is not yet supported by this driver - due to lack of information from the vendor. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-ci. - -config DVB_BUDGET_AV - tristate "Budget cards with analog video inputs (DEPRECATED)" - depends on DVB_BUDGET_CORE && I2C - select VIDEO_SAA7146_VV - depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA1004X if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA10021 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STB0899 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA8261 if MEDIA_SUBDRV_AUTOSELECT - select DVB_TUA6100 if MEDIA_SUBDRV_AUTOSELECT - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder, but with one or more analog video inputs. - - This driver is deprecated and is scheduled for removal by - the beginning of 2023. See the TODO file for more information. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-av. diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/Makefile b/drivers/staging/media/deprecated/saa7146/ttpci/Makefile deleted file mode 100644 index b0708f6e40cc..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the kernel SAA7146 FULL TS DVB device driver -# - -obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o -obj-$(CONFIG_DVB_BUDGET) += budget.o -obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o -obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o - -ccflags-y += -I $(srctree)/drivers/media/dvb-frontends/ -ccflags-y += -I $(srctree)/drivers/media/tuners -ccflags-y += -I $(srctree)/drivers/media/common diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/TODO b/drivers/staging/media/deprecated/saa7146/ttpci/TODO deleted file mode 100644 index c9ae2ec79cea..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/TODO +++ /dev/null @@ -1,7 +0,0 @@ -The saa7146-based drivers are one of the few drivers still not using -the vb2 framework, so these drivers are now deprecated with the intent of -removing them altogether by the beginning of 2023. - -In order to keep these drivers they have to be converted to vb2. -If someone is interested in doing this work, then contact the -linux-media mailinglist (https://linuxtv.org/lists.php). diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c deleted file mode 100644 index 0c61a2dec221..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/budget-av.c +++ /dev/null @@ -1,1622 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * budget-av.c: driver for the SAA7146 based Budget DVB cards - * with analog video in - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * the project's page is at https://linuxtv.org - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "budget.h" -#include "stv0299.h" -#include "stb0899_drv.h" -#include "stb0899_reg.h" -#include "stb0899_cfg.h" -#include "tda8261.h" -#include "tda8261_cfg.h" -#include "tda1002x.h" -#include "tda1004x.h" -#include "tua6100.h" -#include "dvb-pll.h" -#include "../common/saa7146_vv.h" -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/spinlock.h> - -#include <media/dvb_ca_en50221.h> - -#define DEBICICAM 0x02420000 - -#define SLOTSTATUS_NONE 1 -#define SLOTSTATUS_PRESENT 2 -#define SLOTSTATUS_RESET 4 -#define SLOTSTATUS_READY 8 -#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct budget_av { - struct budget budget; - struct video_device vd; - int cur_input; - int has_saa7113; - struct tasklet_struct ciintf_irq_tasklet; - int slot_status; - struct dvb_ca_en50221 ca; - u8 reinitialise_demod:1; -}; - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); - - -/* GPIO Connections: - * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! - * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory - * 2 - CI Card Enable (Active Low) - * 3 - CI Card Detect - */ - -/**************************************************************************** - * INITIALIZATION - ****************************************************************************/ - -static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg) -{ - u8 mm1[] = { 0x00 }; - u8 mm2[] = { 0x00 }; - struct i2c_msg msgs[2]; - - msgs[0].flags = 0; - msgs[1].flags = I2C_M_RD; - msgs[0].addr = msgs[1].addr = id / 2; - mm1[0] = reg; - msgs[0].len = 1; - msgs[1].len = 1; - msgs[0].buf = mm1; - msgs[1].buf = mm2; - - i2c_transfer(i2c, msgs, 2); - - return mm2[0]; -} - -static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len) -{ - u8 mm1[] = { reg }; - struct i2c_msg msgs[2] = { - {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1}, - {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len} - }; - - if (i2c_transfer(i2c, msgs, 2) != 2) - return -EIO; - - return 0; -} - -static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val) -{ - u8 msg[2] = { reg, val }; - struct i2c_msg msgs; - - msgs.flags = 0; - msgs.addr = id / 2; - msgs.len = 2; - msgs.buf = msg; - return i2c_transfer(i2c, &msgs, 1); -} - -static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); - udelay(1); - - result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - pr_info("cam ejected 1\n"); - } - return result; -} - -static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); - udelay(1); - - result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - pr_info("cam ejected 2\n"); - } - return result; -} - -static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - udelay(1); - - result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - pr_info("cam ejected 3\n"); - return -ETIMEDOUT; - } - return result; -} - -static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - udelay(1); - - result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); - if (result == -ETIMEDOUT) { - ciintf_slot_shutdown(ca, slot); - pr_info("cam ejected 5\n"); - } - return result; -} - -static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_reset\n"); - budget_av->slot_status = SLOTSTATUS_RESET; - - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ - msleep(2); - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ - msleep(20); /* 20 ms Vcc settling time */ - - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - msleep(20); - - /* reinitialise the frontend if necessary */ - if (budget_av->reinitialise_demod) - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); - - return 0; -} - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_shutdown\n"); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - budget_av->slot_status = SLOTSTATUS_NONE; - - return 0; -} - -static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); - - return 0; -} - -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - int result; - - if (slot != 0) - return -EINVAL; - - /* test the card detect line - needs to be done carefully - * since it never goes high for some CAMs on this interface (e.g. topuptv) */ - if (budget_av->slot_status == SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - udelay(1); - if (saa7146_read(saa, PSR) & MASK_06) { - if (budget_av->slot_status == SLOTSTATUS_NONE) { - budget_av->slot_status = SLOTSTATUS_PRESENT; - pr_info("cam inserted A\n"); - } - } - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - } - - /* We also try and read from IO memory to work round the above detection bug. If - * there is no CAM, we will get a timeout. Only done if there is no cam - * present, since this test actually breaks some cams :( - * - * if the CI interface is not open, we also do the above test since we - * don't care if the cam has problems - we'll be resetting it on open() anyway */ - if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); - if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { - budget_av->slot_status = SLOTSTATUS_PRESENT; - pr_info("cam inserted B\n"); - } else if (result < 0) { - if (budget_av->slot_status != SLOTSTATUS_NONE) { - ciintf_slot_shutdown(ca, slot); - pr_info("cam ejected 5\n"); - return 0; - } - } - } - - /* read from attribute memory in reset/ready state to know when the CAM is ready */ - if (budget_av->slot_status == SLOTSTATUS_RESET) { - result = ciintf_read_attribute_mem(ca, slot, 0); - if (result == 0x1d) { - budget_av->slot_status = SLOTSTATUS_READY; - } - } - - /* work out correct return code */ - if (budget_av->slot_status != SLOTSTATUS_NONE) { - if (budget_av->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - return 0; -} - -static int ciintf_init(struct budget_av *budget_av) -{ - struct saa7146_dev *saa = budget_av->budget.dev; - int result; - - memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - - /* Enable DEBI pins */ - saa7146_write(saa, MC1, MASK_27 | MASK_11); - - /* register CI interface */ - budget_av->ca.owner = THIS_MODULE; - budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem; - budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem; - budget_av->ca.read_cam_control = ciintf_read_cam_control; - budget_av->ca.write_cam_control = ciintf_write_cam_control; - budget_av->ca.slot_reset = ciintf_slot_reset; - budget_av->ca.slot_shutdown = ciintf_slot_shutdown; - budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_av->ca.poll_slot_status = ciintf_poll_slot_status; - budget_av->ca.data = budget_av; - budget_av->budget.ci_present = 1; - budget_av->slot_status = SLOTSTATUS_NONE; - - if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, - &budget_av->ca, 0, 1)) != 0) { - pr_err("ci initialisation failed\n"); - goto error; - } - - pr_info("ci interface initialised\n"); - return 0; - -error: - saa7146_write(saa, MC1, MASK_27); - return result; -} - -static void ciintf_deinit(struct budget_av *budget_av) -{ - struct saa7146_dev *saa = budget_av->budget.dev; - - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - - /* release the CA device */ - dvb_ca_en50221_release(&budget_av->ca); - - /* disable DEBI pins */ - saa7146_write(saa, MC1, MASK_27); -} - - -static const u8 saa7113_tab[] = { - 0x01, 0x08, - 0x02, 0xc0, - 0x03, 0x33, - 0x04, 0x00, - 0x05, 0x00, - 0x06, 0xeb, - 0x07, 0xe0, - 0x08, 0x28, - 0x09, 0x00, - 0x0a, 0x80, - 0x0b, 0x47, - 0x0c, 0x40, - 0x0d, 0x00, - 0x0e, 0x01, - 0x0f, 0x44, - - 0x10, 0x08, - 0x11, 0x0c, - 0x12, 0x7b, - 0x13, 0x00, - 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, - - 0x57, 0xff, - 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07, - 0x5b, 0x83, 0x5e, 0x00, - 0xff -}; - -static int saa7113_init(struct budget_av *budget_av) -{ - struct budget *budget = &budget_av->budget; - struct saa7146_dev *saa = budget->dev; - const u8 *data = saa7113_tab; - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); - msleep(200); - - if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { - dprintk(1, "saa7113 not found on KNC card\n"); - return -ENODEV; - } - - dprintk(1, "saa7113 detected and initializing\n"); - - while (*data != 0xff) { - i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1)); - data += 2; - } - - dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)); - - return 0; -} - -static int saa7113_setinput(struct budget_av *budget_av, int input) -{ - struct budget *budget = &budget_av->budget; - - if (1 != budget_av->has_saa7113) - return -ENODEV; - - if (input == 1) { - i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7); - i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80); - } else if (input == 0) { - i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0); - i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00); - } else - return -EINVAL; - - budget_av->cur_input = input; - return 0; -} - - -static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - u8 m1; - - aclk = 0xb5; - if (srate < 2000000) - bclk = 0x86; - else if (srate < 5000000) - bclk = 0x89; - else if (srate < 15000000) - bclk = 0x8f; - else if (srate < 45000000) - bclk = 0x95; - - m1 = 0x14; - if (srate < 4000000) - m1 = 0x10; - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - stv0299_writereg(fe, 0x0f, 0x80 | m1); - - return 0; -} - -static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - u32 div; - u8 buf[4]; - struct budget *budget = (struct budget *) fe->dvb->priv; - struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - if ((c->frequency < 950000) || (c->frequency > 2150000)) - return -EINVAL; - - div = (c->frequency + (125 - 1)) / 125; /* round correctly */ - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0x20; - - if (c->symbol_rate < 4000000) - buf[3] |= 1; - - if (c->frequency < 1250000) - buf[3] |= 0; - else if (c->frequency < 1550000) - buf[3] |= 0x40; - else if (c->frequency < 2050000) - buf[3] |= 0x80; - else if (c->frequency < 2150000) - buf[3] |= 0xC0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static u8 typhoon_cinergy1200s_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x92, - 0xff, 0xff -}; - -static const struct stv0299_config typhoon_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - - -static const struct stv0299_config cinergy_1200s_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_0, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - -static const struct stv0299_config cinergy_1200s_1894_0010_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - -static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget *budget = (struct budget *) fe->dvb->priv; - u8 buf[6]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; - int i; - -#define CU1216_IF 36125000 -#define TUNER_MUL 62500 - - u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0xce; - buf[3] = (c->frequency < 150000000 ? 0x01 : - c->frequency < 445000000 ? 0x02 : 0x04); - buf[4] = 0xde; - buf[5] = 0x20; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - - /* wait for the pll lock */ - msg.flags = I2C_M_RD; - msg.len = 1; - for (i = 0; i < 20; i++) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40)) - break; - msleep(10); - } - - /* switch the charge pump to the lower current */ - msg.flags = 0; - msg.len = 2; - msg.buf = &buf[2]; - buf[2] &= ~0x40; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static struct tda1002x_config philips_cu1216_config = { - .demod_address = 0x0c, - .invert = 1, -}; - -static struct tda1002x_config philips_cu1216_config_altaddress = { - .demod_address = 0x0d, - .invert = 0, -}; - -static struct tda10023_config philips_cu1216_tda10023_config = { - .demod_address = 0x0c, - .invert = 1, -}; - -static int philips_tu1216_tuner_init(struct dvb_frontend *fe) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; - - // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - msleep(1); - - return 0; -} - -static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget *budget = (struct budget *) fe->dvb->priv; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = - sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = c->frequency + 36166000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) - cp = 3; - else if (tuner_frequency < 160000000) - cp = 5; - else if (tuner_frequency < 200000000) - cp = 6; - else if (tuner_frequency < 290000000) - cp = 3; - else if (tuner_frequency < 420000000) - cp = 5; - else if (tuner_frequency < 480000000) - cp = 6; - else if (tuner_frequency < 620000000) - cp = 3; - else if (tuner_frequency < 830000000) - cp = 5; - else if (tuner_frequency < 895000000) - cp = 7; - else - return -EINVAL; - - // determine band - if (c->frequency < 49000000) - return -EINVAL; - else if (c->frequency < 161000000) - band = 1; - else if (c->frequency < 444000000) - band = 2; - else if (c->frequency < 861000000) - band = 4; - else - return -EINVAL; - - // setup PLL filter - switch (c->bandwidth_hz) { - case 6000000: - filter = 0; - break; - - case 7000000: - filter = 0; - break; - - case 8000000: - filter = 1; - break; - - default: - return -EINVAL; - } - - // calculate divisor - // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000; - - // setup tuner buffer - tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xca; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - return 0; -} - -static int philips_tu1216_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char *name) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - - return request_firmware(fw, name, &budget->dev->pci->dev); -} - -static struct tda1004x_config philips_tu1216_config = { - - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 1, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tu1216_request_firmware, -}; - -static u8 philips_sd1878_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, - 0x05, 0x35, - 0x06, 0x40, - 0x07, 0x00, - 0x08, 0x43, - 0x09, 0x02, - 0x0C, 0x51, - 0x0D, 0x82, - 0x0E, 0x23, - 0x10, 0x3f, - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, - 0x16, 0x19, - 0x17, 0x8c, - 0x18, 0x59, - 0x19, 0xf8, - 0x1a, 0xfe, - 0x1c, 0x7f, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, - 0x29, 0x28, - 0x2a, 0x14, - 0x2b, 0x0f, - 0x2c, 0x09, - 0x2d, 0x09, - 0x31, 0x1f, - 0x32, 0x19, - 0x33, 0xfc, - 0x34, 0x93, - 0xff, 0xff -}; - -static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, - u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - u8 m1; - - aclk = 0xb5; - if (srate < 2000000) - bclk = 0x86; - else if (srate < 5000000) - bclk = 0x89; - else if (srate < 15000000) - bclk = 0x8f; - else if (srate < 45000000) - bclk = 0x95; - - m1 = 0x14; - if (srate < 4000000) - m1 = 0x10; - - stv0299_writereg(fe, 0x0e, 0x23); - stv0299_writereg(fe, 0x0f, 0x94); - stv0299_writereg(fe, 0x10, 0x39); - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x15, 0xc9); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - stv0299_writereg(fe, 0x0f, 0x80 | m1); - - return 0; -} - -static const struct stv0299_config philips_sd1878_config = { - .demod_address = 0x68, - .inittab = philips_sd1878_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, -}; - -/* KNC1 DVB-S (STB0899) Inittab */ -static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { - - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, -}; - -static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x08 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x33 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xee }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, -}; - -/* STB0899 demodulator config for the KNC1 and clones */ -static struct stb0899_config knc1_dvbs2_config = { - .init_dev = knc1_stb0899_s1_init_1, - .init_s2_demod = stb0899_s2_init_2, - .init_s1_demod = knc1_stb0899_s1_init_3, - .init_s2_fec = stb0899_s2_init_4, - .init_tst = stb0899_s1_init_5, - - .postproc = NULL, - - .demod_address = 0x68, -// .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */ - .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */ -// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */ - - .xtal_freq = 27000000, - .inversion = IQ_SWAP_OFF, - - .lo_clk = 76500000, - .hi_clk = 90000000, - - .esno_ave = STB0899_DVBS2_ESNO_AVE, - .esno_quant = STB0899_DVBS2_ESNO_QUANT, - .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, - .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, - .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, - .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, - .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, - .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, - .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, - - .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, - .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, - .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, - .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, - - .tuner_get_frequency = tda8261_get_frequency, - .tuner_set_frequency = tda8261_set_frequency, - .tuner_set_bandwidth = NULL, - .tuner_get_bandwidth = tda8261_get_bandwidth, - .tuner_set_rfsiggain = NULL -}; - -/* - * SD1878/SHA tuner config - * 1F, Single I/P, Horizontal mount, High Sensitivity - */ -static const struct tda8261_config sd1878c_config = { -// .name = "SD1878/SHA", - .addr = 0x60, - .step_size = TDA8261_STEP_1000 /* kHz */ -}; - -static u8 read_pwm(struct budget_av *budget_av) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1}, - {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} - }; - - if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2) - || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -#define SUBID_DVBS_KNC1 0x0010 -#define SUBID_DVBS_KNC1_PLUS 0x0011 -#define SUBID_DVBS_TYPHOON 0x4f56 -#define SUBID_DVBS_CINERGY1200 0x1154 -#define SUBID_DVBS_CYNERGY1200N 0x1155 -#define SUBID_DVBS_TV_STAR 0x0014 -#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 -#define SUBID_DVBS_TV_STAR_CI 0x0016 -#define SUBID_DVBS2_KNC1 0x0018 -#define SUBID_DVBS2_KNC1_OEM 0x0019 -#define SUBID_DVBS_EASYWATCH_1 0x001a -#define SUBID_DVBS_EASYWATCH_2 0x001b -#define SUBID_DVBS2_EASYWATCH 0x001d -#define SUBID_DVBS_EASYWATCH 0x001e - -#define SUBID_DVBC_EASYWATCH 0x002a -#define SUBID_DVBC_EASYWATCH_MK3 0x002c -#define SUBID_DVBC_KNC1 0x0020 -#define SUBID_DVBC_KNC1_PLUS 0x0021 -#define SUBID_DVBC_KNC1_MK3 0x0022 -#define SUBID_DVBC_KNC1_TDA10024 0x0028 -#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023 -#define SUBID_DVBC_CINERGY1200 0x1156 -#define SUBID_DVBC_CINERGY1200_MK3 0x1176 - -#define SUBID_DVBT_EASYWATCH 0x003a -#define SUBID_DVBT_KNC1_PLUS 0x0031 -#define SUBID_DVBT_KNC1 0x0030 -#define SUBID_DVBT_CINERGY1200 0x1157 - -static void frontend_init(struct budget_av *budget_av) -{ - struct saa7146_dev * saa = budget_av->budget.dev; - struct dvb_frontend * fe = NULL; - - /* Enable / PowerON Frontend */ - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); - - /* Wait for PowerON */ - msleep(100); - - /* additional setup necessary for the PLUS cards */ - switch (saa->pci->subsystem_device) { - case SUBID_DVBS_KNC1_PLUS: - case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBT_KNC1_PLUS: - case SUBID_DVBC_EASYWATCH: - case SUBID_DVBC_KNC1_PLUS_MK3: - case SUBID_DVBS2_KNC1: - case SUBID_DVBS2_KNC1_OEM: - case SUBID_DVBS2_EASYWATCH: - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); - break; - } - - switch (saa->pci->subsystem_device) { - - case SUBID_DVBS_KNC1: - /* - * maybe that setting is needed for other dvb-s cards as well, - * but so far it has been only confirmed for this type - */ - budget_av->reinitialise_demod = 1; - fallthrough; - case SUBID_DVBS_KNC1_PLUS: - case SUBID_DVBS_EASYWATCH_1: - if (saa->pci->subsystem_vendor == 0x1894) { - fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config, - &budget_av->budget.i2c_adap); - if (fe) { - dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap); - } - } else { - fe = dvb_attach(stv0299_attach, &typhoon_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - } - break; - - case SUBID_DVBS_TV_STAR: - case SUBID_DVBS_TV_STAR_PLUS_X4: - case SUBID_DVBS_TV_STAR_CI: - case SUBID_DVBS_CYNERGY1200N: - case SUBID_DVBS_EASYWATCH: - case SUBID_DVBS_EASYWATCH_2: - fe = dvb_attach(stv0299_attach, &philips_sd1878_config, - &budget_av->budget.i2c_adap); - if (fe) { - dvb_attach(dvb_pll_attach, fe, 0x60, - &budget_av->budget.i2c_adap, - DVB_PLL_PHILIPS_SD1878_TDA8261); - } - break; - - case SUBID_DVBS_TYPHOON: - fe = dvb_attach(stv0299_attach, &typhoon_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - break; - case SUBID_DVBS2_KNC1: - case SUBID_DVBS2_KNC1_OEM: - case SUBID_DVBS2_EASYWATCH: - budget_av->reinitialise_demod = 1; - if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap))) - dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap); - - break; - case SUBID_DVBS_CINERGY1200: - fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - break; - - case SUBID_DVBC_KNC1: - case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBC_CINERGY1200: - case SUBID_DVBC_EASYWATCH: - budget_av->reinitialise_demod = 1; - budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - fe = dvb_attach(tda10021_attach, &philips_cu1216_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe == NULL) - fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe) { - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } - break; - - case SUBID_DVBC_EASYWATCH_MK3: - case SUBID_DVBC_CINERGY1200_MK3: - case SUBID_DVBC_KNC1_MK3: - case SUBID_DVBC_KNC1_TDA10024: - case SUBID_DVBC_KNC1_PLUS_MK3: - budget_av->reinitialise_demod = 1; - budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - fe = dvb_attach(tda10023_attach, - &philips_cu1216_tda10023_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe) { - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } - break; - - case SUBID_DVBT_EASYWATCH: - case SUBID_DVBT_KNC1: - case SUBID_DVBT_KNC1_PLUS: - case SUBID_DVBT_CINERGY1200: - budget_av->reinitialise_demod = 1; - fe = dvb_attach(tda10046_attach, &philips_tu1216_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.init = philips_tu1216_tuner_init; - fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; - } - break; - } - - if (fe == NULL) { - pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - saa->pci->vendor, - saa->pci->device, - saa->pci->subsystem_vendor, - saa->pci->subsystem_device); - return; - } - - budget_av->budget.dvb_frontend = fe; - - if (dvb_register_frontend(&budget_av->budget.dvb_adapter, - budget_av->budget.dvb_frontend)) { - pr_err("Frontend registration failed!\n"); - dvb_frontend_detach(budget_av->budget.dvb_frontend); - budget_av->budget.dvb_frontend = NULL; - } -} - - -static void budget_av_irq(struct saa7146_dev *dev, u32 * isr) -{ - struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; - - dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av); - - if (*isr & MASK_10) - ttpci_budget_irq10_handler(dev, isr); -} - -static int budget_av_detach(struct saa7146_dev *dev) -{ - struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; - int err; - - dprintk(2, "dev: %p\n", dev); - - if (1 == budget_av->has_saa7113) { - saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); - - msleep(200); - - saa7146_unregister_device(&budget_av->vd, dev); - - saa7146_vv_release(dev); - } - - if (budget_av->budget.ci_present) - ciintf_deinit(budget_av); - - if (budget_av->budget.dvb_frontend != NULL) { - dvb_unregister_frontend(budget_av->budget.dvb_frontend); - dvb_frontend_detach(budget_av->budget.dvb_frontend); - } - err = ttpci_budget_deinit(&budget_av->budget); - - kfree(budget_av); - - return err; -} - -#define KNC1_INPUTS 2 -static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { - { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, - V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, - { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, - V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD }, -}; - -static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) -{ - dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index); - if (i->index >= KNC1_INPUTS) - return -EINVAL; - memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); - return 0; -} - -static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; - - *i = budget_av->cur_input; - - dprintk(1, "VIDIOC_G_INPUT %d\n", *i); - return 0; -} - -static int vidioc_s_input(struct file *file, void *fh, unsigned int input) -{ - struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; - struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; - - dprintk(1, "VIDIOC_S_INPUT %d\n", input); - return saa7113_setinput(budget_av, input); -} - -static struct saa7146_ext_vv vv_data; - -static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct budget_av *budget_av; - u8 *mac; - int err; - - dprintk(2, "dev: %p\n", dev); - - if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL))) - return -ENOMEM; - - budget_av->has_saa7113 = 0; - budget_av->budget.ci_present = 0; - - dev->ext_priv = budget_av; - - err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE, - adapter_nr); - if (err) { - kfree(budget_av); - return err; - } - - /* knc1 initialization */ - saa7146_write(dev, DD1_STREAM_B, 0x04000000); - saa7146_write(dev, DD1_INIT, 0x07000600); - saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); - - if (saa7113_init(budget_av) == 0) { - budget_av->has_saa7113 = 1; - err = saa7146_vv_init(dev, &vv_data); - if (err != 0) { - /* fixme: proper cleanup here */ - ERR("cannot init vv subsystem\n"); - return err; - } - vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; - vv_data.vid_ops.vidioc_g_input = vidioc_g_input; - vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - - if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) { - /* fixme: proper cleanup here */ - ERR("cannot register capture v4l2 device\n"); - saa7146_vv_release(dev); - return err; - } - - /* beware: this modifies dev->vv ... */ - saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A, - SAA7146_HPS_SYNC_PORT_A); - - saa7113_setinput(budget_av, 0); - } - - /* fixme: find some sane values here... */ - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - - mac = budget_av->budget.dvb_adapter.proposed_mac; - if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { - pr_err("KNC1-%d: Could not read MAC from KNC1 card\n", - budget_av->budget.dvb_adapter.num); - eth_zero_addr(mac); - } else { - pr_info("KNC1-%d: MAC addr = %pM\n", - budget_av->budget.dvb_adapter.num, mac); - } - - budget_av->budget.dvb_adapter.priv = budget_av; - frontend_init(budget_av); - ciintf_init(budget_av); - - ttpci_budget_init_hooks(&budget_av->budget); - - return 0; -} - -static struct saa7146_standard standard[] = { - {.name = "PAL",.id = V4L2_STD_PAL, - .v_offset = 0x17,.v_field = 288, - .h_offset = 0x14,.h_pixels = 680, - .v_max_out = 576,.h_max_out = 768 }, - - {.name = "NTSC",.id = V4L2_STD_NTSC, - .v_offset = 0x16,.v_field = 240, - .h_offset = 0x06,.h_pixels = 708, - .v_max_out = 480,.h_max_out = 640, }, -}; - -static struct saa7146_ext_vv vv_data = { - .inputs = 2, - .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113 - .flags = 0, - .stds = &standard[0], - .num_stds = ARRAY_SIZE(standard), -}; - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); -MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2); -MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); -MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); -MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); -MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); -MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); -MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); -MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); -MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); -MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); -MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); -MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); -MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); -MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024); -MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); -MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); -MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); -MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); -MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); -MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); -MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); - -static const struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), - MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), - MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), - MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), - MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), - MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), - MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), - MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), - MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018), - MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019), - MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d), - MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), - MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), - MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), - MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), - MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), - MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), - MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), - MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), - MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), - MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028), - MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), - MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), - MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), - MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), - MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), - MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), - MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176), - MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget_av", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = pci_tbl, - - .module = THIS_MODULE, - .attach = budget_av_attach, - .detach = budget_av_detach, - - .irq_mask = MASK_10, - .irq_func = budget_av_irq, -}; - -static int __init budget_av_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_av_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_av_init); -module_exit(budget_av_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c deleted file mode 100644 index d59d18647371..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/budget-ci.c +++ /dev/null @@ -1,1574 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * budget-ci.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM> - * partially based on the Siemens DVB driver by Ralph+Marcus Metzler - * - * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - * - * the project's page is at https://linuxtv.org - */ - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <media/rc-core.h> - -#include "budget.h" - -#include <media/dvb_ca_en50221.h> -#include "stv0299.h" -#include "stv0297.h" -#include "tda1004x.h" -#include "stb0899_drv.h" -#include "stb0899_reg.h" -#include "stb0899_cfg.h" -#include "stb6100.h" -#include "stb6100_cfg.h" -#include "lnbp21.h" -#include "bsbe1.h" -#include "bsru6.h" -#include "tda1002x.h" -#include "tda827x.h" -#include "bsbe1-d01a.h" - -#define MODULE_NAME "budget_ci" - -/* - * Regarding DEBIADDR_IR: - * Some CI modules hang if random addresses are read. - * Using address 0x4000 for the IR read means that we - * use the same address as for CI version, which should - * be a safe default. - */ -#define DEBIADDR_IR 0x4000 -#define DEBIADDR_CICONTROL 0x0000 -#define DEBIADDR_CIVERSION 0x4000 -#define DEBIADDR_IO 0x1000 -#define DEBIADDR_ATTR 0x3000 - -#define CICONTROL_RESET 0x01 -#define CICONTROL_ENABLETS 0x02 -#define CICONTROL_CAMDETECT 0x08 - -#define DEBICICTL 0x00420000 -#define DEBICICAM 0x02420000 - -#define SLOTSTATUS_NONE 1 -#define SLOTSTATUS_PRESENT 2 -#define SLOTSTATUS_RESET 4 -#define SLOTSTATUS_READY 8 -#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) - -/* RC5 device wildcard */ -#define IR_DEVICE_ANY 255 - -static int rc5_device = -1; -module_param(rc5_device, int, 0644); -MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); - -static int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct budget_ci_ir { - struct rc_dev *dev; - struct tasklet_struct msp430_irq_tasklet; - char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ - char phys[32]; - int rc5_device; - u32 ir_key; - bool have_command; - bool full_rc5; /* Outputs a full RC5 code */ -}; - -struct budget_ci { - struct budget budget; - struct tasklet_struct ciintf_irq_tasklet; - int slot_status; - int ci_irq; - struct dvb_ca_en50221 ca; - struct budget_ci_ir ir; - u8 tuner_pll_address; /* used for philips_tdm1316l configs */ -}; - -static void msp430_ir_interrupt(struct tasklet_struct *t) -{ - struct budget_ci_ir *ir = from_tasklet(ir, t, msp430_irq_tasklet); - struct budget_ci *budget_ci = container_of(ir, typeof(*budget_ci), ir); - struct rc_dev *dev = budget_ci->ir.dev; - u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; - - /* - * The msp430 chip can generate two different bytes, command and device - * - * type1: X1CCCCCC, C = command bits (0 - 63) - * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit - * - * Each signal from the remote control can generate one or more command - * bytes and one or more device bytes. For the repeated bytes, the - * highest bit (X) is set. The first command byte is always generated - * before the first device byte. Other than that, no specific order - * seems to apply. To make life interesting, bytes can also be lost. - * - * Only when we have a command and device byte, a keypress is - * generated. - */ - - if (ir_debug) - printk("budget_ci: received byte 0x%02x\n", command); - - /* Remove repeat bit, we use every command */ - command = command & 0x7f; - - /* Is this a RC5 command byte? */ - if (command & 0x40) { - budget_ci->ir.have_command = true; - budget_ci->ir.ir_key = command & 0x3f; - return; - } - - /* It's a RC5 device byte */ - if (!budget_ci->ir.have_command) - return; - budget_ci->ir.have_command = false; - - if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && - budget_ci->ir.rc5_device != (command & 0x1f)) - return; - - if (budget_ci->ir.full_rc5) { - rc_keydown(dev, RC_PROTO_RC5, - RC_SCANCODE_RC5(budget_ci->ir.rc5_device, budget_ci->ir.ir_key), - !!(command & 0x20)); - return; - } - - /* FIXME: We should generate complete scancodes for all devices */ - rc_keydown(dev, RC_PROTO_UNKNOWN, budget_ci->ir.ir_key, - !!(command & 0x20)); -} - -static int msp430_ir_init(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - struct rc_dev *dev; - int error; - - dev = rc_allocate_device(RC_DRIVER_SCANCODE); - if (!dev) { - printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); - return -ENOMEM; - } - - snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), - "Budget-CI dvb ir receiver %s", saa->name); - snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), - "pci-%s/ir0", pci_name(saa->pci)); - - dev->driver_name = MODULE_NAME; - dev->device_name = budget_ci->ir.name; - dev->input_phys = budget_ci->ir.phys; - dev->input_id.bustype = BUS_PCI; - dev->input_id.version = 1; - if (saa->pci->subsystem_vendor) { - dev->input_id.vendor = saa->pci->subsystem_vendor; - dev->input_id.product = saa->pci->subsystem_device; - } else { - dev->input_id.vendor = saa->pci->vendor; - dev->input_id.product = saa->pci->device; - } - dev->dev.parent = &saa->pci->dev; - - if (rc5_device < 0) - budget_ci->ir.rc5_device = IR_DEVICE_ANY; - else - budget_ci->ir.rc5_device = rc5_device; - - /* Select keymap and address */ - switch (budget_ci->budget.dev->pci->subsystem_device) { - case 0x100c: - case 0x100f: - case 0x1011: - case 0x1012: - /* The hauppauge keymap is a superset of these remotes */ - dev->map_name = RC_MAP_HAUPPAUGE; - budget_ci->ir.full_rc5 = true; - - if (rc5_device < 0) - budget_ci->ir.rc5_device = 0x1f; - break; - case 0x1010: - case 0x1017: - case 0x1019: - case 0x101a: - case 0x101b: - /* for the Technotrend 1500 bundled remote */ - dev->map_name = RC_MAP_TT_1500; - break; - default: - /* unknown remote */ - dev->map_name = RC_MAP_BUDGET_CI_OLD; - break; - } - if (!budget_ci->ir.full_rc5) - dev->scancode_mask = 0xff; - - error = rc_register_device(dev); - if (error) { - printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); - rc_free_device(dev); - return error; - } - - budget_ci->ir.dev = dev; - - tasklet_setup(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt); - - SAA7146_IER_ENABLE(saa, MASK_06); - saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); - - return 0; -} - -static void msp430_ir_deinit(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - - SAA7146_IER_DISABLE(saa, MASK_06); - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); - - rc_unregister_device(budget_ci->ir.dev); -} - -static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, - DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0); -} - -static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, - DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0); -} - -static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, - DEBIADDR_IO | (address & 3), 1, 1, 0); -} - -static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, - DEBIADDR_IO | (address & 3), 1, value, 1, 0); -} - -static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - - if (slot != 0) - return -EINVAL; - - if (budget_ci->ci_irq) { - // trigger on RISING edge during reset so we know when READY is re-asserted - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - budget_ci->slot_status = SLOTSTATUS_RESET; - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); - msleep(1); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - return 0; -} - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - return 0; -} - -static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - int tmp; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); - - tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - tmp | CICONTROL_ENABLETS, 1, 0); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); - return 0; -} - -static void ciintf_interrupt(struct tasklet_struct *t) -{ - struct budget_ci *budget_ci = from_tasklet(budget_ci, t, - ciintf_irq_tasklet); - struct saa7146_dev *saa = budget_ci->budget.dev; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - - // GPIO should be set to trigger on falling edge if a CAM is present - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - // CAM insertion IRQ - budget_ci->slot_status = SLOTSTATUS_PRESENT; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, - DVB_CA_EN50221_CAMCHANGE_INSERTED); - - } else if (budget_ci->slot_status & SLOTSTATUS_RESET) { - // CAM ready (reset completed) - budget_ci->slot_status = SLOTSTATUS_READY; - dvb_ca_en50221_camready_irq(&budget_ci->ca, 0); - - } else if (budget_ci->slot_status & SLOTSTATUS_READY) { - // FR/DA IRQ - dvb_ca_en50221_frda_irq(&budget_ci->ca, 0); - } - } else { - - // trigger on rising edge if a CAM is not present - when a CAM is inserted, we - // only want to get the IRQ when it sets READY. If we trigger on the falling edge, - // the CAM might not actually be ready yet. - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - - // generate a CAM removal IRQ if we haven't already - if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) { - // CAM removal IRQ - budget_ci->slot_status = SLOTSTATUS_NONE; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, - DVB_CA_EN50221_CAMCHANGE_REMOVED); - } - } -} - -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return -EINVAL; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - // mark it as present if it wasn't before - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - budget_ci->slot_status = SLOTSTATUS_PRESENT; - } - - // during a RESET, we check if we can read from IO memory to see when CAM is ready - if (budget_ci->slot_status & SLOTSTATUS_RESET) { - if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { - budget_ci->slot_status = SLOTSTATUS_READY; - } - } - } else { - budget_ci->slot_status = SLOTSTATUS_NONE; - } - - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - if (budget_ci->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - - return 0; -} - -static int ciintf_init(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - int flags; - int result; - int ci_version; - int ca_flags; - - memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); - - // enable DEBI pins - saa7146_write(saa, MC1, MASK_27 | MASK_11); - - // test if it is there - ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); - if ((ci_version & 0xa0) != 0xa0) { - result = -ENODEV; - goto error; - } - - // determine whether a CAM is present or not - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - budget_ci->slot_status = SLOTSTATUS_NONE; - if (flags & CICONTROL_CAMDETECT) - budget_ci->slot_status = SLOTSTATUS_PRESENT; - - // version 0xa2 of the CI firmware doesn't generate interrupts - if (ci_version == 0xa2) { - ca_flags = 0; - budget_ci->ci_irq = 0; - } else { - ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | - DVB_CA_EN50221_FLAG_IRQ_FR | - DVB_CA_EN50221_FLAG_IRQ_DA; - budget_ci->ci_irq = 1; - } - - // register CI interface - budget_ci->ca.owner = THIS_MODULE; - budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; - budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem; - budget_ci->ca.read_cam_control = ciintf_read_cam_control; - budget_ci->ca.write_cam_control = ciintf_write_cam_control; - budget_ci->ca.slot_reset = ciintf_slot_reset; - budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; - budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; - budget_ci->ca.data = budget_ci; - if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, - &budget_ci->ca, - ca_flags, 1)) != 0) { - printk("budget_ci: CI interface detected, but initialisation failed.\n"); - goto error; - } - - // Setup CI slot IRQ - if (budget_ci->ci_irq) { - tasklet_setup(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - SAA7146_IER_ENABLE(saa, MASK_03); - } - - // enable interface - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - // success! - printk("budget_ci: CI interface initialised\n"); - budget_ci->budget.ci_present = 1; - - // forge a fake CI IRQ so the CAM state is setup correctly - if (budget_ci->ci_irq) { - flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; - if (budget_ci->slot_status != SLOTSTATUS_NONE) - flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); - } - - return 0; - -error: - saa7146_write(saa, MC1, MASK_27); - return result; -} - -static void ciintf_deinit(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - - // disable CI interrupts - if (budget_ci->ci_irq) { - SAA7146_IER_DISABLE(saa, MASK_03); - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); - } - - // reset interface - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); - msleep(1); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - // disable TS data stream to CI interface - saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); - - // release the CA device - dvb_ca_en50221_release(&budget_ci->ca); - - // disable DEBI pins - saa7146_write(saa, MC1, MASK_27); -} - -static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) -{ - struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; - - dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci); - - if (*isr & MASK_06) - tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet); - - if (*isr & MASK_10) - ttpci_budget_irq10_handler(dev, isr); - - if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) - tasklet_schedule(&budget_ci->ciintf_irq_tasklet); -} - -static u8 philips_su1278_tt_inittab[] = { - 0x01, 0x0f, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x5b, - 0x05, 0x85, - 0x06, 0x02, - 0x07, 0x00, - 0x08, 0x02, - 0x09, 0x00, - 0x0C, 0x01, - 0x0D, 0x81, - 0x0E, 0x44, - 0x0f, 0x14, - 0x10, 0x3c, - 0x11, 0x84, - 0x12, 0xda, - 0x13, 0x97, - 0x14, 0x95, - 0x15, 0xc9, - 0x16, 0x19, - 0x17, 0x8c, - 0x18, 0x59, - 0x19, 0xf8, - 0x1a, 0xfe, - 0x1c, 0x7f, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, - 0x29, 0x28, - 0x2a, 0x14, - 0x2b, 0x0f, - 0x2c, 0x09, - 0x2d, 0x09, - 0x31, 0x1f, - 0x32, 0x19, - 0x33, 0xfc, - 0x34, 0x93, - 0xff, 0xff -}; - -static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - stv0299_writereg(fe, 0x0e, 0x44); - if (srate >= 10000000) { - stv0299_writereg(fe, 0x13, 0x97); - stv0299_writereg(fe, 0x14, 0x95); - stv0299_writereg(fe, 0x15, 0xc9); - stv0299_writereg(fe, 0x17, 0x8c); - stv0299_writereg(fe, 0x1a, 0xfe); - stv0299_writereg(fe, 0x1c, 0x7f); - stv0299_writereg(fe, 0x2d, 0x09); - } else { - stv0299_writereg(fe, 0x13, 0x99); - stv0299_writereg(fe, 0x14, 0x8d); - stv0299_writereg(fe, 0x15, 0xce); - stv0299_writereg(fe, 0x17, 0x43); - stv0299_writereg(fe, 0x1a, 0x1d); - stv0299_writereg(fe, 0x1c, 0x12); - stv0299_writereg(fe, 0x2d, 0x05); - } - stv0299_writereg(fe, 0x0e, 0x23); - stv0299_writereg(fe, 0x0f, 0x94); - stv0299_writereg(fe, 0x10, 0x39); - stv0299_writereg(fe, 0x15, 0xc9); - - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - - return 0; -} - -static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u32 div; - u8 buf[4]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - if ((p->frequency < 950000) || (p->frequency > 2150000)) - return -EINVAL; - - div = (p->frequency + (500 - 1)) / 500; /* round correctly */ - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2; - buf[3] = 0x20; - - if (p->symbol_rate < 4000000) - buf[3] |= 1; - - if (p->frequency < 1250000) - buf[3] |= 0; - else if (p->frequency < 1550000) - buf[3] |= 0x40; - else if (p->frequency < 2050000) - buf[3] |= 0x80; - else if (p->frequency < 2150000) - buf[3] |= 0xC0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static const struct stv0299_config philips_su1278_tt_config = { - - .demod_address = 0x68, - .inittab = philips_su1278_tt_inittab, - .mclk = 64000000UL, - .invert = 0, - .skip_reinit = 1, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 50, - .set_symbol_rate = philips_su1278_tt_set_symbol_rate, -}; - - - -static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len = - sizeof(td1316_init) }; - - // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - msleep(1); - - // disable the mc44BC374c (do not check for errors) - tuner_msg.addr = 0x65; - tuner_msg.buf = disable_mc44BC374c; - tuner_msg.len = sizeof(disable_mc44BC374c); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); - } - - return 0; -} - -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = p->frequency + 36130000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) - cp = 3; - else if (tuner_frequency < 160000000) - cp = 5; - else if (tuner_frequency < 200000000) - cp = 6; - else if (tuner_frequency < 290000000) - cp = 3; - else if (tuner_frequency < 420000000) - cp = 5; - else if (tuner_frequency < 480000000) - cp = 6; - else if (tuner_frequency < 620000000) - cp = 3; - else if (tuner_frequency < 830000000) - cp = 5; - else if (tuner_frequency < 895000000) - cp = 7; - else - return -EINVAL; - - // determine band - if (p->frequency < 49000000) - return -EINVAL; - else if (p->frequency < 159000000) - band = 1; - else if (p->frequency < 444000000) - band = 2; - else if (p->frequency < 861000000) - band = 4; - else - return -EINVAL; - - // setup PLL filter and TDA9889 - switch (p->bandwidth_hz) { - case 6000000: - tda1004x_writereg(fe, 0x0C, 0x14); - filter = 0; - break; - - case 7000000: - tda1004x_writereg(fe, 0x0C, 0x80); - filter = 0; - break; - - case 8000000: - tda1004x_writereg(fe, 0x0C, 0x14); - filter = 1; - break; - - default: - return -EINVAL; - } - - // calculate divisor - // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000; - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xca; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - return 0; -} - -static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char *name) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - - return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev); -} - -static struct tda1004x_config philips_tdm1316l_config = { - - .demod_address = 0x8, - .invert = 0, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tdm1316l_request_firmware, -}; - -static struct tda1004x_config philips_tdm1316l_config_invert = { - - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tdm1316l_request_firmware, -}; - -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u8 tuner_buf[5]; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, - .flags = 0, - .buf = tuner_buf, - .len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = p->frequency + 36125000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) { - cp = 3; - band = 1; - } else if (tuner_frequency < 160000000) { - cp = 5; - band = 1; - } else if (tuner_frequency < 200000000) { - cp = 6; - band = 1; - } else if (tuner_frequency < 290000000) { - cp = 3; - band = 2; - } else if (tuner_frequency < 420000000) { - cp = 5; - band = 2; - } else if (tuner_frequency < 480000000) { - cp = 6; - band = 2; - } else if (tuner_frequency < 620000000) { - cp = 3; - band = 4; - } else if (tuner_frequency < 830000000) { - cp = 5; - band = 4; - } else if (tuner_frequency < 895000000) { - cp = 7; - band = 4; - } else - return -EINVAL; - - // assume PLL filter should always be 8MHz for the moment. - filter = 1; - - // calculate divisor - tuner_frequency = (p->frequency + 36125000 + (62500/2)) / 62500; - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xc8; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - tuner_buf[4] = 0x80; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(50); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - - return 0; -} - -static u8 dvbc_philips_tdm1316l_inittab[] = { - 0x80, 0x01, - 0x80, 0x00, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x20, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0x00, - 0x4b, 0x7b, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x10, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x04, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x53, - 0xc1, 0x70, - 0xc2, 0x12, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x38, - 0x62, 0x0a, - 0x53, 0x13, - 0x59, 0x08, - 0xff, 0xff, -}; - -static struct stv0297_config dvbc_philips_tdm1316l_config = { - .demod_address = 0x1c, - .inittab = dvbc_philips_tdm1316l_inittab, - .invert = 0, - .stop_during_read = 1, -}; - -static struct tda10023_config tda10023_config = { - .demod_address = 0xc, - .invert = 0, - .xtal = 16000000, - .pll_m = 11, - .pll_p = 3, - .pll_n = 1, - .deltaf = 0xa511, -}; - -static struct tda827x_config tda827x_config = { - .config = 0, -}; - -/* TT S2-3200 DVB-S (STB0899) Inittab */ -static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { - - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, -}; - -static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x10 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xc7 }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, -}; - -static struct stb0899_config tt3200_config = { - .init_dev = tt3200_stb0899_s1_init_1, - .init_s2_demod = stb0899_s2_init_2, - .init_s1_demod = tt3200_stb0899_s1_init_3, - .init_s2_fec = stb0899_s2_init_4, - .init_tst = stb0899_s1_init_5, - - .postproc = NULL, - - .demod_address = 0x68, - - .xtal_freq = 27000000, - .inversion = IQ_SWAP_ON, - - .lo_clk = 76500000, - .hi_clk = 99000000, - - .esno_ave = STB0899_DVBS2_ESNO_AVE, - .esno_quant = STB0899_DVBS2_ESNO_QUANT, - .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, - .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, - .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, - .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, - .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, - .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, - .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, - - .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, - .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, - .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, - .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, - - .tuner_get_frequency = stb6100_get_frequency, - .tuner_set_frequency = stb6100_set_frequency, - .tuner_set_bandwidth = stb6100_set_bandwidth, - .tuner_get_bandwidth = stb6100_get_bandwidth, - .tuner_set_rfsiggain = NULL -}; - -static struct stb6100_config tt3200_stb6100_config = { - .tuner_address = 0x60, - .refclock = 27000000, -}; - -static void frontend_init(struct budget_ci *budget_ci) -{ - switch (budget_ci->budget.dev->pci->subsystem_device) { - case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059)) - budget_ci->budget.dvb_frontend = - dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; - break; - } - break; - - case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059)) - budget_ci->budget.dvb_frontend = - dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; - break; - } - break; - - case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt)) - budget_ci->tuner_pll_address = 0x61; - budget_ci->budget.dvb_frontend = - dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) - budget_ci->tuner_pll_address = 0x63; - budget_ci->budget.dvb_frontend = - dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) - budget_ci->tuner_pll_address = 0x60; - budget_ci->budget.dvb_frontend = - dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1017: // TT S-1500 PCI - budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; - - budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ - budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); - if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) { - printk(KERN_ERR "%s: No tda827x found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */ - budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) { - if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { - printk(KERN_ERR "%s: No LNBP21 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } else { - printk(KERN_ERR "%s: No STB6000 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - case 0x1019: // TT S2-3200 PCI - /* - * NOTE! on some STB0899 versions, the internal PLL takes a longer time - * to settle, aka LOCK. On the older revisions of the chip, we don't see - * this, as a result on the newer chips the entire clock tree, will not - * be stable after a freshly POWER 'ed up situation. - * In this case, we should RESET the STB0899 (Active LOW) and wait for - * PLL stabilization. - * - * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is - * connected to the SAA7146 GPIO, GPIO2, Pin 142 - */ - /* Reset Demodulator */ - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO); - /* Wait for everything to die */ - msleep(50); - /* Pull it up out of Reset state */ - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI); - /* Wait for PLL to stabilize */ - msleep(250); - /* - * PLL state should be stable now. Ideally, we should check - * for PLL LOCK status. But well, never mind! - */ - budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) { - if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { - printk("%s: No LNBP21 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } else { - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - } - - if (budget_ci->budget.dvb_frontend == NULL) { - printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - budget_ci->budget.dev->pci->vendor, - budget_ci->budget.dev->pci->device, - budget_ci->budget.dev->pci->subsystem_vendor, - budget_ci->budget.dev->pci->subsystem_device); - } else { - if (dvb_register_frontend - (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { - printk("budget-ci: Frontend registration failed!\n"); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } -} - -static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct budget_ci *budget_ci; - int err; - - budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL); - if (!budget_ci) { - err = -ENOMEM; - goto out1; - } - - dprintk(2, "budget_ci: %p\n", budget_ci); - - dev->ext_priv = budget_ci; - - err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE, - adapter_nr); - if (err) - goto out2; - - err = msp430_ir_init(budget_ci); - if (err) - goto out3; - - ciintf_init(budget_ci); - - budget_ci->budget.dvb_adapter.priv = budget_ci; - frontend_init(budget_ci); - - ttpci_budget_init_hooks(&budget_ci->budget); - - return 0; - -out3: - ttpci_budget_deinit(&budget_ci->budget); -out2: - kfree(budget_ci); -out1: - return err; -} - -static int budget_ci_detach(struct saa7146_dev *dev) -{ - struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; - struct saa7146_dev *saa = budget_ci->budget.dev; - int err; - - if (budget_ci->budget.ci_present) - ciintf_deinit(budget_ci); - msp430_ir_deinit(budget_ci); - if (budget_ci->budget.dvb_frontend) { - dvb_unregister_frontend(budget_ci->budget.dvb_frontend); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - } - err = ttpci_budget_deinit(&budget_ci->budget); - - // disable frontend and CI interface - saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); - - kfree(budget_ci); - - return err; -} - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); -MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT); - -static const struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), - MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), - MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), - MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), - MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), - MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), - MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), - MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), - MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget_ci dvb", - .flags = SAA7146_USE_I2C_IRQ, - - .module = THIS_MODULE, - .pci_tbl = &pci_tbl[0], - .attach = budget_ci_attach, - .detach = budget_ci_detach, - - .irq_mask = MASK_03 | MASK_06 | MASK_10, - .irq_func = budget_ci_irq, -}; - -static int __init budget_ci_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_ci_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_ci_init); -module_exit(budget_ci_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards w/ CI-module produced by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c deleted file mode 100644 index 5d5796f24469..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/budget-core.c +++ /dev/null @@ -1,603 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * budget-core.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * 26feb2004 Support for FS Activy Card (Grundig tuner) by - * Michael Dreher <michael@5dot1.de>, - * Oliver Endriss <o.endriss@gmx.de>, - * Andreas 'randy' Weinberger - * - * the project's page is at https://linuxtv.org - */ - - -#include "budget.h" -#include "ttpci-eeprom.h" - -#define TS_WIDTH (2 * TS_SIZE) -#define TS_WIDTH_ACTIVY TS_SIZE -#define TS_WIDTH_DVBC TS_SIZE -#define TS_HEIGHT_MASK 0xf00 -#define TS_HEIGHT_MASK_ACTIVY 0xc00 -#define TS_HEIGHT_MASK_DVBC 0xe00 -#define TS_MIN_BUFSIZE_K 188 -#define TS_MAX_BUFSIZE_K 1410 -#define TS_MAX_BUFSIZE_K_ACTIVY 564 -#define TS_MAX_BUFSIZE_K_DVBC 1316 -#define BUFFER_WARNING_WAIT (30*HZ) - -int budget_debug; -static int dma_buffer_size = TS_MIN_BUFSIZE_K; -module_param_named(debug, budget_debug, int, 0644); -module_param_named(bufsize, dma_buffer_size, int, 0444); -MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); -MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); - -/**************************************************************************** - * TT budget / WinTV Nova - ****************************************************************************/ - -static int stop_ts_capture(struct budget *budget) -{ - dprintk(2, "budget: %p\n", budget); - - saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off - SAA7146_IER_DISABLE(budget->dev, MASK_10); - return 0; -} - -static int start_ts_capture(struct budget *budget) -{ - struct saa7146_dev *dev = budget->dev; - - dprintk(2, "budget: %p\n", budget); - - if (!budget->feeding || !budget->fe_synced) - return 0; - - saa7146_write(dev, MC1, MASK_20); // DMA3 off - - memset(budget->grabbing, 0x00, budget->buffer_size); - - saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); - - budget->ttbp = 0; - - /* - * Signal path on the Activy: - * - * tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory - * - * Since the tuner feeds 204 bytes packets into the SAA7146, - * DMA3 is configured to strip the trailing 16 FEC bytes: - * Pitch: 188, NumBytes3: 188, NumLines3: 1024 - */ - - switch(budget->card->type) { - case BUDGET_FS_ACTIVY: - saa7146_write(dev, DD1_INIT, 0x04000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - break; - case BUDGET_PATCH: - saa7146_write(dev, DD1_INIT, 0x00000200); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - break; - case BUDGET_CIN1200C_MK3: - case BUDGET_KNC1C_MK3: - case BUDGET_KNC1C_TDA10024: - case BUDGET_KNC1CP_MK3: - if (budget->video_port == BUDGET_VIDEO_PORTA) { - saa7146_write(dev, DD1_INIT, 0x06000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - } else { - saa7146_write(dev, DD1_INIT, 0x00000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - } - break; - default: - if (budget->video_port == BUDGET_VIDEO_PORTA) { - saa7146_write(dev, DD1_INIT, 0x06000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - } else { - saa7146_write(dev, DD1_INIT, 0x02000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - } - } - - saa7146_write(dev, MC2, (MASK_08 | MASK_24)); - mdelay(10); - - saa7146_write(dev, BASE_ODD3, 0); - if (budget->buffer_size > budget->buffer_height * budget->buffer_width) { - // using odd/even buffers - saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width); - } else { - // using a single buffer - saa7146_write(dev, BASE_EVEN3, 0); - } - saa7146_write(dev, PROT_ADDR3, budget->buffer_size); - saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); - - saa7146_write(dev, PITCH3, budget->buffer_width); - saa7146_write(dev, NUM_LINE_BYTE3, - (budget->buffer_height << 16) | budget->buffer_width); - - saa7146_write(dev, MC2, (MASK_04 | MASK_20)); - - SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ - SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ - saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ - - return 0; -} - -static int budget_read_fe_status(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - int synced; - int ret; - - if (budget->read_fe_status) - ret = budget->read_fe_status(fe, status); - else - ret = -EINVAL; - - if (!ret) { - synced = (*status & FE_HAS_LOCK); - if (synced != budget->fe_synced) { - budget->fe_synced = synced; - spin_lock(&budget->feedlock); - if (synced) - start_ts_capture(budget); - else - stop_ts_capture(budget); - spin_unlock(&budget->feedlock); - } - } - return ret; -} - -static void vpeirq(struct tasklet_struct *t) -{ - struct budget *budget = from_tasklet(budget, t, vpe_tasklet); - u8 *mem = (u8 *) (budget->grabbing); - u32 olddma = budget->ttbp; - u32 newdma = saa7146_read(budget->dev, PCI_VDP3); - u32 count; - - /* Ensure streamed PCI data is synced to CPU */ - dma_sync_sg_for_cpu(&budget->dev->pci->dev, budget->pt.slist, - budget->pt.nents, DMA_FROM_DEVICE); - - /* nearest lower position divisible by 188 */ - newdma -= newdma % 188; - - if (newdma >= budget->buffer_size) - return; - - budget->ttbp = newdma; - - if (budget->feeding == 0 || newdma == olddma) - return; - - if (newdma > olddma) { /* no wraparound, dump olddma..newdma */ - count = newdma - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); - } else { /* wraparound, dump olddma..buflen and 0..newdma */ - count = budget->buffer_size - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); - count += newdma; - dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188); - } - - if (count > budget->buffer_warning_threshold) - budget->buffer_warnings++; - - if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { - printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", - budget->dev->name, __func__, budget->buffer_warnings, count); - budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; - budget->buffer_warnings = 0; - } -} - - -static int ttpci_budget_debiread_nolock(struct budget *budget, u32 config, - int addr, int count, int nobusyloop) -{ - struct saa7146_dev *saa = budget->dev; - int result; - - result = saa7146_wait_for_debi_done(saa, nobusyloop); - if (result < 0) - return result; - - saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - saa7146_write(saa, DEBI_CONFIG, config); - saa7146_write(saa, DEBI_PAGE, 0); - saa7146_write(saa, MC2, (2 << 16) | 2); - - result = saa7146_wait_for_debi_done(saa, nobusyloop); - if (result < 0) - return result; - - result = saa7146_read(saa, DEBI_AD); - result &= (0xffffffffUL >> ((4 - count) * 8)); - return result; -} - -int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, - int uselocks, int nobusyloop) -{ - if (count > 4 || count <= 0) - return 0; - - if (uselocks) { - unsigned long flags; - int result; - - spin_lock_irqsave(&budget->debilock, flags); - result = ttpci_budget_debiread_nolock(budget, config, addr, - count, nobusyloop); - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - return ttpci_budget_debiread_nolock(budget, config, addr, - count, nobusyloop); -} - -static int ttpci_budget_debiwrite_nolock(struct budget *budget, u32 config, - int addr, int count, u32 value, int nobusyloop) -{ - struct saa7146_dev *saa = budget->dev; - int result; - - result = saa7146_wait_for_debi_done(saa, nobusyloop); - if (result < 0) - return result; - - saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff)); - saa7146_write(saa, DEBI_CONFIG, config); - saa7146_write(saa, DEBI_PAGE, 0); - saa7146_write(saa, DEBI_AD, value); - saa7146_write(saa, MC2, (2 << 16) | 2); - - result = saa7146_wait_for_debi_done(saa, nobusyloop); - return result < 0 ? result : 0; -} - -int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, - int count, u32 value, int uselocks, int nobusyloop) -{ - if (count > 4 || count <= 0) - return 0; - - if (uselocks) { - unsigned long flags; - int result; - - spin_lock_irqsave(&budget->debilock, flags); - result = ttpci_budget_debiwrite_nolock(budget, config, addr, - count, value, nobusyloop); - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - return ttpci_budget_debiwrite_nolock(budget, config, addr, - count, value, nobusyloop); -} - - -/**************************************************************************** - * DVB API SECTION - ****************************************************************************/ - -static int budget_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; - int status = 0; - - dprintk(2, "budget: %p\n", budget); - - if (!demux->dmx.frontend) - return -EINVAL; - - spin_lock(&budget->feedlock); - feed->pusi_seen = false; /* have a clean section start */ - if (budget->feeding++ == 0) - status = start_ts_capture(budget); - spin_unlock(&budget->feedlock); - return status; -} - -static int budget_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; - int status = 0; - - dprintk(2, "budget: %p\n", budget); - - spin_lock(&budget->feedlock); - if (--budget->feeding == 0) - status = stop_ts_capture(budget); - spin_unlock(&budget->feedlock); - return status; -} - -static int budget_register(struct budget *budget) -{ - struct dvb_demux *dvbdemux = &budget->demux; - int ret; - - dprintk(2, "budget: %p\n", budget); - - dvbdemux->priv = (void *) budget; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = budget_start_feed; - dvbdemux->stop_feed = budget_stop_feed; - dvbdemux->write_to_decoder = NULL; - - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - - dvb_dmx_init(&budget->demux); - - budget->dmxdev.filternum = 256; - budget->dmxdev.demux = &dvbdemux->dmx; - budget->dmxdev.capabilities = 0; - - dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter); - - budget->hw_frontend.source = DMX_FRONTEND_0; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend); - - if (ret < 0) - goto err_release_dmx; - - budget->mem_frontend.source = DMX_MEMORY_FE; - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend); - if (ret < 0) - goto err_release_dmx; - - ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend); - if (ret < 0) - goto err_release_dmx; - - dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); - - return 0; - -err_release_dmx: - dvb_dmxdev_release(&budget->dmxdev); - dvb_dmx_release(&budget->demux); - return ret; -} - -static void budget_unregister(struct budget *budget) -{ - struct dvb_demux *dvbdemux = &budget->demux; - - dprintk(2, "budget: %p\n", budget); - - dvb_net_release(&budget->dvb_net); - - dvbdemux->dmx.close(&dvbdemux->dmx); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend); - - dvb_dmxdev_release(&budget->dmxdev); - dvb_dmx_release(&budget->demux); -} - -int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, - struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums) -{ - int ret = 0; - struct budget_info *bi = info->ext_priv; - int max_bufsize; - int height_mask; - - memset(budget, 0, sizeof(struct budget)); - - dprintk(2, "dev: %p, budget: %p\n", dev, budget); - - budget->card = bi; - budget->dev = (struct saa7146_dev *) dev; - - switch(budget->card->type) { - case BUDGET_FS_ACTIVY: - budget->buffer_width = TS_WIDTH_ACTIVY; - max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; - height_mask = TS_HEIGHT_MASK_ACTIVY; - break; - - case BUDGET_KNC1C: - case BUDGET_KNC1CP: - case BUDGET_CIN1200C: - case BUDGET_KNC1C_MK3: - case BUDGET_KNC1C_TDA10024: - case BUDGET_KNC1CP_MK3: - case BUDGET_CIN1200C_MK3: - budget->buffer_width = TS_WIDTH_DVBC; - max_bufsize = TS_MAX_BUFSIZE_K_DVBC; - height_mask = TS_HEIGHT_MASK_DVBC; - break; - - default: - budget->buffer_width = TS_WIDTH; - max_bufsize = TS_MAX_BUFSIZE_K; - height_mask = TS_HEIGHT_MASK; - } - - if (dma_buffer_size < TS_MIN_BUFSIZE_K) - dma_buffer_size = TS_MIN_BUFSIZE_K; - else if (dma_buffer_size > max_bufsize) - dma_buffer_size = max_bufsize; - - budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; - if (budget->buffer_height > 0xfff) { - budget->buffer_height /= 2; - budget->buffer_height &= height_mask; - budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width; - } else { - budget->buffer_height &= height_mask; - budget->buffer_size = budget->buffer_height * budget->buffer_width; - } - budget->buffer_warning_threshold = budget->buffer_size * 80/100; - budget->buffer_warnings = 0; - budget->buffer_warning_time = jiffies; - - dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n", - budget->dev->name, - budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single", - budget->buffer_width, budget->buffer_height); - printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); - - ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, - owner, &budget->dev->pci->dev, adapter_nums); - if (ret < 0) - return ret; - - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25)); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - saa7146_write(dev, DD1_INIT, 0x02000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - if (bi->type != BUDGET_FS_ACTIVY) - budget->video_port = BUDGET_VIDEO_PORTB; - else - budget->video_port = BUDGET_VIDEO_PORTA; - spin_lock_init(&budget->feedlock); - spin_lock_init(&budget->debilock); - - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is loaded */ - if (bi->type != BUDGET_FS_ACTIVY) - saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ - - strscpy(budget->i2c_adap.name, budget->card->name, - sizeof(budget->i2c_adap.name)); - - saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); - strscpy(budget->i2c_adap.name, budget->card->name, - sizeof(budget->i2c_adap.name)); - - if (i2c_add_adapter(&budget->i2c_adap) < 0) { - ret = -ENOMEM; - goto err_dvb_unregister; - } - - ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); - - budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt); - if (NULL == budget->grabbing) { - ret = -ENOMEM; - goto err_del_i2c; - } - - saa7146_write(dev, PCI_BT_V1, 0x001c0000); - /* upload all */ - saa7146_write(dev, GPIO_CTRL, 0x000000); - - tasklet_setup(&budget->vpe_tasklet, vpeirq); - - /* frontend power on */ - if (bi->type != BUDGET_FS_ACTIVY) - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - - if ((ret = budget_register(budget)) == 0) - return 0; /* Everything OK */ - - /* An error occurred, cleanup resources */ - saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - -err_del_i2c: - i2c_del_adapter(&budget->i2c_adap); - -err_dvb_unregister: - dvb_unregister_adapter(&budget->dvb_adapter); - - return ret; -} - -void ttpci_budget_init_hooks(struct budget *budget) -{ - if (budget->dvb_frontend && !budget->read_fe_status) { - budget->read_fe_status = budget->dvb_frontend->ops.read_status; - budget->dvb_frontend->ops.read_status = budget_read_fe_status; - } -} - -int ttpci_budget_deinit(struct budget *budget) -{ - struct saa7146_dev *dev = budget->dev; - - dprintk(2, "budget: %p\n", budget); - - budget_unregister(budget); - - tasklet_kill(&budget->vpe_tasklet); - - saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - - i2c_del_adapter(&budget->i2c_adap); - - dvb_unregister_adapter(&budget->dvb_adapter); - - return 0; -} - -void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr) -{ - struct budget *budget = (struct budget *) dev->ext_priv; - - dprintk(8, "dev: %p, budget: %p\n", dev, budget); - - if (*isr & MASK_10) - tasklet_schedule(&budget->vpe_tasklet); -} - -void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) -{ - struct budget *budget = (struct budget *) dev->ext_priv; - - spin_lock(&budget->feedlock); - budget->video_port = video_port; - if (budget->feeding) { - stop_ts_capture(budget); - start_ts_capture(budget); - } - spin_unlock(&budget->feedlock); -} - -EXPORT_SYMBOL_GPL(ttpci_budget_debiread); -EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); -EXPORT_SYMBOL_GPL(ttpci_budget_init); -EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); -EXPORT_SYMBOL_GPL(ttpci_budget_deinit); -EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); -EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); -EXPORT_SYMBOL_GPL(budget_debug); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget.c b/drivers/staging/media/deprecated/saa7146/ttpci/budget.c deleted file mode 100644 index a88711a3ac7f..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/budget.c +++ /dev/null @@ -1,883 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * budget.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * 26feb2004 Support for FS Activy Card (Grundig tuner) by - * Michael Dreher <michael@5dot1.de>, - * Oliver Endriss <o.endriss@gmx.de> and - * Andreas 'randy' Weinberger - * - * the project's page is at https://linuxtv.org - */ - -#include "budget.h" -#include "stv0299.h" -#include "ves1x93.h" -#include "ves1820.h" -#include "l64781.h" -#include "tda8083.h" -#include "s5h1420.h" -#include "tda10086.h" -#include "tda826x.h" -#include "lnbp21.h" -#include "bsru6.h" -#include "bsbe1.h" -#include "tdhd1.h" -#include "stv6110x.h" -#include "stv090x.h" -#include "isl6423.h" -#include "lnbh24.h" - - -static int diseqc_method; -module_param(diseqc_method, int, 0444); -MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static void Set22K (struct budget *budget, int state) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); -} - -/* Diseqc functions only for TT Budget card */ -/* taken from the Skyvision DVB driver by - Ralph Metzler <rjkm@metzlerbros.de> */ - -static void DiseqcSendBit (struct budget *budget, int data) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - udelay(data ? 500 : 1000); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - udelay(data ? 1000 : 500); -} - -static void DiseqcSendByte (struct budget *budget, int data) -{ - int i, par=1, d; - - dprintk(2, "budget: %p\n", budget); - - for (i=7; i>=0; i--) { - d = (data>>i)&1; - par ^= d; - DiseqcSendBit(budget, d); - } - - DiseqcSendBit(budget, par); -} - -static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) -{ - struct saa7146_dev *dev=budget->dev; - int i; - - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - mdelay(16); - - for (i=0; i<len; i++) - DiseqcSendByte(budget, msg[i]); - - mdelay(16); - - if (burst!=-1) { - if (burst) - DiseqcSendByte(budget, 0xff); - else { - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - mdelay(12); - udelay(500); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - } - msleep(20); - } - - return 0; -} - -/* - * Routines for the Fujitsu Siemens Activy budget card - * 22 kHz tone and DiSEqC are handled by the frontend. - * Voltage must be set here. - * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL - */ -static int SetVoltage_Activy(struct budget *budget, - enum fe_sec_voltage voltage) -{ - struct saa7146_dev *dev=budget->dev; - - dprintk(2, "budget: %p\n", budget); - - switch (voltage) { - case SEC_VOLTAGE_13: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); - break; - case SEC_VOLTAGE_18: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - break; - case SEC_VOLTAGE_OFF: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int siemens_budget_set_voltage(struct dvb_frontend *fe, - enum fe_sec_voltage voltage) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - return SetVoltage_Activy (budget, voltage); -} - -static int budget_set_tone(struct dvb_frontend *fe, - enum fe_sec_tone_mode tone) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - switch (tone) { - case SEC_TONE_ON: - Set22K (budget, 1); - break; - - case SEC_TONE_OFF: - Set22K (budget, 0); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); - - return 0; -} - -static int budget_diseqc_send_burst(struct dvb_frontend *fe, - enum fe_sec_mini_cmd minicmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, 0, NULL, minicmd); - - return 0; -} - -static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget* budget = (struct budget*) fe->dvb->priv; - u8 pwr = 0; - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (c->frequency + 479500) / 125; - - if (c->frequency > 2000000) - pwr = 3; - else if (c->frequency > 1800000) - pwr = 2; - else if (c->frequency > 1600000) - pwr = 1; - else if (c->frequency > 1200000) - pwr = 0; - else if (c->frequency >= 1100000) - pwr = 1; - else pwr = 2; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = ((div & 0x18000) >> 10) | 0x95; - buf[3] = (pwr << 6) | 0x30; - - // NOTE: since we're using a prescaler of 2, we set the - // divisor frequency to 62.5kHz and divide by 125 above - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct ves1x93_config alps_bsrv2_config = -{ - .demod_address = 0x08, - .xin = 90100000UL, - .invert_pwm = 0, -}; - -static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (c->frequency + 35937500 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (c->frequency < 174000000 ? 0x88 : c->frequency < 470000000 ? 0x84 : 0x81); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct ves1820_config alps_tdbe2_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, -}; - -static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget *budget = fe->dvb->priv; - u8 *tuner_addr = fe->tuner_priv; - u32 div; - u8 cfg, cpump, band_select; - u8 data[4]; - struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) }; - - if (tuner_addr) - msg.addr = *tuner_addr; - else - msg.addr = 0x61; - - div = (36125000 + c->frequency) / 166666; - - cfg = 0x88; - - if (c->frequency < 175000000) - cpump = 2; - else if (c->frequency < 390000000) - cpump = 1; - else if (c->frequency < 470000000) - cpump = 2; - else if (c->frequency < 750000000) - cpump = 1; - else - cpump = 3; - - if (c->frequency < 175000000) - band_select = 0x0e; - else if (c->frequency < 470000000) - band_select = 0x05; - else - band_select = 0x03; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = ((div >> 10) & 0x60) | cfg; - data[3] = (cpump << 6) | band_select; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct l64781_config grundig_29504_401_config = { - .demod_address = 0x55, -}; - -static struct l64781_config grundig_29504_401_config_activy = { - .demod_address = 0x54, -}; - -static u8 tuner_address_grundig_29504_401_activy = 0x60; - -static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = c->frequency / 125; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = 0x00; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct tda8083_config grundig_29504_451_config = { - .demod_address = 0x68, -}; - -static int s5h1420_tuner_set_params(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = c->frequency / 1000; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0xc2; - - if (div < 1450) - data[3] = 0x00; - else if (div < 1850) - data[3] = 0x40; - else if (div < 2000) - data[3] = 0x80; - else - data[3] = 0xc0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - - return 0; -} - -static struct s5h1420_config s5h1420_config = { - .demod_address = 0x53, - .invert = 1, - .cdclk_polarity = 1, -}; - -static struct tda10086_config tda10086_config = { - .demod_address = 0x0e, - .invert = 0, - .diseqc_tone = 1, - .xtal_freq = TDA10086_XTAL_16M, -}; - -static const struct stv0299_config alps_bsru6_config_activy = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .op0_off = 1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, -}; - -static const struct stv0299_config alps_bsbe1_config_activy = { - .demod_address = 0x68, - .inittab = alps_bsbe1_inittab, - .mclk = 88000000UL, - .invert = 1, - .op0_off = 1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsbe1_set_symbol_rate, -}; - -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) -{ - struct budget *budget = (struct budget *)fe->dvb->priv; - - return request_firmware(fw, name, &budget->dev->pci->dev); -} - - -static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) -{ - u8 val; - struct i2c_msg msg[] = { - { .addr = adr, .flags = 0, .buf = ®, .len = 1 }, - { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 } - }; - - return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; -} - -static u8 read_pwm(struct budget* budget) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; - - if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -static struct stv090x_config tt1600_stv090x_config = { - .device = STV0903, - .demod_mode = STV090x_SINGLE, - .clk_mode = STV090x_CLK_EXT, - - .xtal = 13500000, - .address = 0x68, - - .ts1_mode = STV090x_TSMODE_DVBCI, - .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, - - .repeater_level = STV090x_RPTLEVEL_16, - - .tuner_init = NULL, - .tuner_sleep = NULL, - .tuner_set_mode = NULL, - .tuner_set_frequency = NULL, - .tuner_get_frequency = NULL, - .tuner_set_bandwidth = NULL, - .tuner_get_bandwidth = NULL, - .tuner_set_bbgain = NULL, - .tuner_get_bbgain = NULL, - .tuner_set_refclk = NULL, - .tuner_get_status = NULL, -}; - -static struct stv6110x_config tt1600_stv6110x_config = { - .addr = 0x60, - .refclk = 27000000, - .clk_div = 2, -}; - -static struct isl6423_config tt1600_isl6423_config = { - .current_max = SEC_CURRENT_515m, - .curlim = SEC_CURRENT_LIM_ON, - .mod_extern = 1, - .addr = 0x08, -}; - -static void frontend_init(struct budget *budget) -{ - (void)alps_bsbe1_config; /* avoid warning */ - - switch(budget->dev->pci->subsystem_device) { - case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) - case 0x1013: - // try the ALPS BSRV2 first of all - budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - break; - } - - // try the ALPS BSRU6 now - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - } - break; - } - break; - - case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) - - budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - break; - } - break; - - case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) - - budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - budget->dvb_frontend->tuner_priv = NULL; - break; - } - break; - - case 0x4f52: /* Cards based on Philips Semi Sylt PCI ref. design */ - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSRU6 in Philips Semi. Sylt detected\n"); - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - break; - } - break; - - case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */ - { - int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); - - if (subtype < 0) - break; - /* fixme: find a better way to identify the card */ - if (subtype < 0x36) { - /* assume ALPS BSRU6 */ - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n"); - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - break; - } - } else { - /* assume ALPS BSBE1 */ - /* reset tuner */ - saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO); - msleep(50); - saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI); - msleep(250); - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n"); - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - break; - } - } - break; - } - - case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) - budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - } - break; - - case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */ - budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - } - break; - - case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ - budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy; - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - } - break; - - case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) - { - struct dvb_frontend *fe; - - fe = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = s5h1420_tuner_set_params; - budget->dvb_frontend = fe; - if (dvb_attach(lnbp21_attach, fe, &budget->i2c_adap, - 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - goto error_out; - } - break; - } - } - fallthrough; - case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262) - { - struct dvb_frontend *fe; - - // gpio2 is connected to CLB - reset it + leave it high - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); - msleep(1); - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); - msleep(1); - - fe = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); - if (fe) { - budget->dvb_frontend = fe; - if (dvb_attach(tda826x_attach, fe, 0x60, - &budget->i2c_adap, 0) == NULL) - printk("%s: No tda826x found!\n", __func__); - if (dvb_attach(lnbp21_attach, fe, - &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - goto error_out; - } - break; - } - } - fallthrough; - - case 0x101c: { /* TT S2-1600 */ - const struct stv6110x_devctl *ctl; - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); - msleep(50); - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); - msleep(250); - - budget->dvb_frontend = dvb_attach(stv090x_attach, - &tt1600_stv090x_config, - &budget->i2c_adap, - STV090x_DEMODULATOR_0); - - if (budget->dvb_frontend) { - - ctl = dvb_attach(stv6110x_attach, - budget->dvb_frontend, - &tt1600_stv6110x_config, - &budget->i2c_adap); - - if (ctl) { - tt1600_stv090x_config.tuner_init = ctl->tuner_init; - tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; - tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; - tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; - tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; - tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; - tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; - tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; - tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; - tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; - tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; - - /* call the init function once to initialize - tuner's clock output divider and demod's - master clock */ - if (budget->dvb_frontend->ops.init) - budget->dvb_frontend->ops.init(budget->dvb_frontend); - - if (dvb_attach(isl6423_attach, - budget->dvb_frontend, - &budget->i2c_adap, - &tt1600_isl6423_config) == NULL) { - printk(KERN_ERR "%s: No Intersil ISL6423 found!\n", __func__); - goto error_out; - } - } else { - printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); - goto error_out; - } - } - } - break; - - case 0x1020: { /* Omicom S2 */ - const struct stv6110x_devctl *ctl; - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); - msleep(50); - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); - msleep(250); - - budget->dvb_frontend = dvb_attach(stv090x_attach, - &tt1600_stv090x_config, - &budget->i2c_adap, - STV090x_DEMODULATOR_0); - - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: Omicom S2 detected\n"); - - ctl = dvb_attach(stv6110x_attach, - budget->dvb_frontend, - &tt1600_stv6110x_config, - &budget->i2c_adap); - - if (ctl) { - tt1600_stv090x_config.tuner_init = ctl->tuner_init; - tt1600_stv090x_config.tuner_sleep = ctl->tuner_sleep; - tt1600_stv090x_config.tuner_set_mode = ctl->tuner_set_mode; - tt1600_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; - tt1600_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; - tt1600_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; - tt1600_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; - tt1600_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain; - tt1600_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain; - tt1600_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk; - tt1600_stv090x_config.tuner_get_status = ctl->tuner_get_status; - - /* call the init function once to initialize - tuner's clock output divider and demod's - master clock */ - if (budget->dvb_frontend->ops.init) - budget->dvb_frontend->ops.init(budget->dvb_frontend); - - if (dvb_attach(lnbh24_attach, - budget->dvb_frontend, - &budget->i2c_adap, - LNBH24_PCL | LNBH24_TTX, - LNBH24_TEN, 0x14>>1) == NULL) { - printk(KERN_ERR - "No LNBH24 found!\n"); - goto error_out; - } - } else { - printk(KERN_ERR "%s: No STV6110(A) Silicon Tuner found!\n", __func__); - goto error_out; - } - } - } - break; - } - - if (budget->dvb_frontend == NULL) { - printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - budget->dev->pci->vendor, - budget->dev->pci->device, - budget->dev->pci->subsystem_vendor, - budget->dev->pci->subsystem_device); - } else { - if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) - goto error_out; - } - return; - -error_out: - printk("budget: Frontend registration failed!\n"); - dvb_frontend_detach(budget->dvb_frontend); - budget->dvb_frontend = NULL; - return; -} - -static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct budget *budget = NULL; - int err; - - budget = kmalloc(sizeof(struct budget), GFP_KERNEL); - if( NULL == budget ) { - return -ENOMEM; - } - - dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); - - dev->ext_priv = budget; - - err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); - if (err) { - printk("==> failed\n"); - kfree (budget); - return err; - } - - budget->dvb_adapter.priv = budget; - frontend_init(budget); - - ttpci_budget_init_hooks(budget); - - return 0; -} - -static int budget_detach (struct saa7146_dev* dev) -{ - struct budget *budget = (struct budget*) dev->ext_priv; - int err; - - if (budget->dvb_frontend) { - dvb_unregister_frontend(budget->dvb_frontend); - dvb_frontend_detach(budget->dvb_frontend); - } - - err = ttpci_budget_deinit (budget); - - kfree (budget); - dev->ext_priv = NULL; - - return err; -} - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); -MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); -MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(tt1600, "TT-Budget S2-1600 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(omicom, "Omicom S2 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(sylt, "Philips Semi Sylt PCI", BUDGET_TT_HW_DISEQC); - -static const struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), - MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), - MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), - MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), - MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), - MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), - MAKE_EXTENSION_PCI(tt1600, 0x13c2, 0x101c), - MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), - MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), - MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), - MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), - MAKE_EXTENSION_PCI(omicom, 0x14c4, 0x1020), - MAKE_EXTENSION_PCI(sylt, 0x1131, 0x4f52), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget dvb", - .flags = SAA7146_USE_I2C_IRQ, - - .module = THIS_MODULE, - .pci_tbl = pci_tbl, - .attach = budget_attach, - .detach = budget_detach, - - .irq_mask = MASK_10, - .irq_func = ttpci_budget_irq10_handler, -}; - -static int __init budget_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_init); -module_exit(budget_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/staging/media/deprecated/saa7146/ttpci/budget.h b/drivers/staging/media/deprecated/saa7146/ttpci/budget.h deleted file mode 100644 index 82cc0df492b3..000000000000 --- a/drivers/staging/media/deprecated/saa7146/ttpci/budget.h +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __BUDGET_DVB__ -#define __BUDGET_DVB__ - -#include <media/dvb_frontend.h> -#include <media/dvbdev.h> -#include <media/demux.h> -#include <media/dvb_demux.h> -#include <media/dmxdev.h> -#include <media/dvb_net.h> - -#include <linux/module.h> -#include <linux/mutex.h> - -#include "../common/saa7146.h" - -extern int budget_debug; - -#ifdef dprintk -#undef dprintk -#endif - -#define dprintk(level, fmt, arg...) do { \ - if (level & budget_debug) \ - printk(KERN_DEBUG KBUILD_MODNAME ": %s(): " fmt, \ - __func__, ##arg); \ -} while (0) - -#define TS_SIZE 188 - -struct budget_info { - char *name; - int type; -}; - -/* place to store all the necessary device information */ -struct budget { - - /* devices */ - struct dvb_device dvb_dev; - struct dvb_net dvb_net; - - struct saa7146_dev *dev; - - struct i2c_adapter i2c_adap; - struct budget_info *card; - - unsigned char *grabbing; - struct saa7146_pgtable pt; - - struct tasklet_struct fidb_tasklet; - struct tasklet_struct vpe_tasklet; - - struct dmxdev dmxdev; - struct dvb_demux demux; - - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - - int ci_present; - int video_port; - - u32 buffer_width; - u32 buffer_height; - u32 buffer_size; - u32 buffer_warning_threshold; - u32 buffer_warnings; - unsigned long buffer_warning_time; - - u32 ttbp; - int feeding; - - spinlock_t feedlock; - - spinlock_t debilock; - - struct dvb_adapter dvb_adapter; - struct dvb_frontend *dvb_frontend; - int (*read_fe_status)(struct dvb_frontend *fe, enum fe_status *status); - int fe_synced; - - void *priv; -}; - -#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \ -static struct budget_info x_var ## _info = { \ - .name=x_name, \ - .type=x_type }; \ -static struct saa7146_pci_extension_data x_var = { \ - .ext_priv = &x_var ## _info, \ - .ext = &budget_extension }; - -#define BUDGET_TT 0 -#define BUDGET_TT_HW_DISEQC 1 -#define BUDGET_PATCH 3 -#define BUDGET_FS_ACTIVY 4 -#define BUDGET_CIN1200S 5 -#define BUDGET_CIN1200C 6 -#define BUDGET_CIN1200T 7 -#define BUDGET_KNC1S 8 -#define BUDGET_KNC1C 9 -#define BUDGET_KNC1T 10 -#define BUDGET_KNC1SP 11 -#define BUDGET_KNC1CP 12 -#define BUDGET_KNC1TP 13 -#define BUDGET_TVSTAR 14 -#define BUDGET_CIN1200C_MK3 15 -#define BUDGET_KNC1C_MK3 16 -#define BUDGET_KNC1CP_MK3 17 -#define BUDGET_KNC1S2 18 -#define BUDGET_KNC1C_TDA10024 19 - -#define BUDGET_VIDEO_PORTA 0 -#define BUDGET_VIDEO_PORTB 1 - -extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, - struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums); -extern void ttpci_budget_init_hooks(struct budget *budget); -extern int ttpci_budget_deinit(struct budget *budget); -extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); -extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); -extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, - int uselocks, int nobusyloop); -extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value, - int uselocks, int nobusyloop); - -#endif diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5c3cc7de209d..44d87fe30d52 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -779,11 +779,8 @@ static int csi_start(struct csi_priv *priv) goto idmac_stop; /* start the frame interval monitor */ - if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC) { - ret = imx_media_fim_set_stream(priv->fim, output_fi, true); - if (ret) - goto idmac_stop; - } + if (priv->fim && priv->dest == IPU_CSI_DEST_IDMAC) + imx_media_fim_set_stream(priv->fim, output_fi, true); ret = ipu_csi_enable(priv->csi); if (ret) { diff --git a/drivers/staging/media/imx/imx-media-fim.c b/drivers/staging/media/imx/imx-media-fim.c index fb6590dcfc36..e28a33d9dec7 100644 --- a/drivers/staging/media/imx/imx-media-fim.c +++ b/drivers/staging/media/imx/imx-media-fim.c @@ -68,7 +68,10 @@ struct imx_media_fim { bool stream_on; }; -#define icap_enabled(fim) ((fim)->icap_flags != IRQ_TYPE_NONE) +static bool icap_enabled(struct imx_media_fim *fim) +{ + return fim->icap_flags != IRQ_TYPE_NONE; +} static void update_fim_nominal(struct imx_media_fim *fim, const struct v4l2_fract *fi) @@ -368,12 +371,11 @@ void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp) } /* Called by the subdev in its s_stream callback */ -int imx_media_fim_set_stream(struct imx_media_fim *fim, - const struct v4l2_fract *fi, - bool on) +void imx_media_fim_set_stream(struct imx_media_fim *fim, + const struct v4l2_fract *fi, + bool on) { unsigned long flags; - int ret = 0; v4l2_ctrl_lock(fim->ctrl[FIM_CL_ENABLE]); @@ -393,7 +395,6 @@ int imx_media_fim_set_stream(struct imx_media_fim *fim, fim->stream_on = on; out: v4l2_ctrl_unlock(fim->ctrl[FIM_CL_ENABLE]); - return ret; } int imx_media_fim_add_controls(struct imx_media_fim *fim) diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index f679249d82e4..6f9a46573edd 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -246,9 +246,9 @@ int imx_media_dev_notifier_register(struct imx_media_dev *imxmd, /* imx-media-fim.c */ struct imx_media_fim; void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp); -int imx_media_fim_set_stream(struct imx_media_fim *fim, - const struct v4l2_fract *frame_interval, - bool on); +void imx_media_fim_set_stream(struct imx_media_fim *fim, + const struct v4l2_fract *frame_interval, + bool on); int imx_media_fim_add_controls(struct imx_media_fim *fim); struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd); void imx_media_fim_free(struct imx_media_fim *fim); diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c index 86ccc8937afc..7b15fc54efe4 100644 --- a/drivers/staging/media/meson/vdec/esparser.c +++ b/drivers/staging/media/meson/vdec/esparser.c @@ -314,8 +314,7 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf) num_dst_bufs = codec_ops->num_pending_bufs(sess); num_dst_bufs += v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx); - if (sess->fmt_out->pixfmt == V4L2_PIX_FMT_VP9) - num_dst_bufs -= 3; + num_dst_bufs -= 3; if (esparser_vififo_get_free_space(sess) < payload_size || atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 0ad70faa9ba0..05548eab7daa 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -201,39 +201,34 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad) /* Return a pointer to the ISS video instance at the far end of the pipeline. */ static struct iss_video * -iss_video_far_end(struct iss_video *video) +iss_video_far_end(struct iss_video *video, struct iss_pipeline *pipe) { - struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_pipeline_entity_iter iter; + struct media_entity *entity; struct iss_video *far_end = NULL; + int ret; - mutex_lock(&mdev->graph_mutex); - - if (media_graph_walk_init(&graph, mdev)) { - mutex_unlock(&mdev->graph_mutex); - return NULL; - } + ret = media_pipeline_entity_iter_init(&pipe->pipe, &iter); + if (ret) + return ERR_PTR(-ENOMEM); - media_graph_walk_start(&graph, entity); + media_pipeline_for_each_entity(&pipe->pipe, &iter, entity) { + struct iss_video *other; - while ((entity = media_graph_walk_next(&graph))) { if (entity == &video->video.entity) continue; if (!is_media_entity_v4l2_video_device(entity)) continue; - far_end = to_iss_video(media_entity_to_video_device(entity)); - if (far_end->type != video->type) + other = to_iss_video(media_entity_to_video_device(entity)); + if (other->type != video->type) { + far_end = other; break; - - far_end = NULL; + } } - mutex_unlock(&mdev->graph_mutex); - - media_graph_walk_cleanup(&graph); + media_pipeline_entity_iter_cleanup(&iter); return far_end; } @@ -850,12 +845,12 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { struct iss_video_fh *vfh = to_iss_video_fh(fh); struct iss_video *video = video_drvdata(file); - struct media_graph graph; - struct media_entity *entity = &video->video.entity; - struct media_device *mdev = entity->graph_obj.mdev; + struct media_device *mdev = video->video.entity.graph_obj.mdev; + struct media_pipeline_pad_iter iter; enum iss_pipeline_state state; struct iss_pipeline *pipe; struct iss_video *far_end; + struct media_pad *pad; unsigned long flags; int ret; @@ -873,13 +868,9 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) pipe->external_rate = 0; pipe->external_bpp = 0; - ret = media_entity_enum_init(&pipe->ent_enum, entity->graph_obj.mdev); - if (ret) - goto err_graph_walk_init; - - ret = media_graph_walk_init(&graph, entity->graph_obj.mdev); + ret = media_entity_enum_init(&pipe->ent_enum, mdev); if (ret) - goto err_graph_walk_init; + goto err_entity_enum_init; if (video->iss->pdata->set_constraints) video->iss->pdata->set_constraints(video->iss, true); @@ -888,11 +879,8 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) if (ret < 0) goto err_media_pipeline_start; - mutex_lock(&mdev->graph_mutex); - media_graph_walk_start(&graph, entity); - while ((entity = media_graph_walk_next(&graph))) - media_entity_enum_set(&pipe->ent_enum, entity); - mutex_unlock(&mdev->graph_mutex); + media_pipeline_for_each_pad(&pipe->pipe, &iter, pad) + media_entity_enum_set(&pipe->ent_enum, pad->entity); /* * Verify that the currently configured format matches the output of @@ -909,7 +897,11 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) * Find the ISS video node connected at the far end of the pipeline and * update the pipeline. */ - far_end = iss_video_far_end(video); + far_end = iss_video_far_end(video, pipe); + if (IS_ERR(far_end)) { + ret = PTR_ERR(far_end); + goto err_iss_video_check_format; + } if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { state = ISS_PIPELINE_STREAM_OUTPUT | ISS_PIPELINE_IDLE_OUTPUT; @@ -966,8 +958,6 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) spin_unlock_irqrestore(&video->qlock, flags); } - media_graph_walk_cleanup(&graph); - mutex_unlock(&video->stream_lock); return 0; @@ -981,9 +971,7 @@ err_media_pipeline_start: video->iss->pdata->set_constraints(video->iss, false); video->queue = NULL; - media_graph_walk_cleanup(&graph); - -err_graph_walk_init: +err_entity_enum_init: media_entity_enum_cleanup(&pipe->ent_enum); mutex_unlock(&video->stream_lock); |