summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS7
-rw-r--r--Documentation/admin-guide/media/em28xx-cardlist.rst4
-rw-r--r--Documentation/devicetree/bindings/media/i2c/sony,imx355.yaml11
-rw-r--r--Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml130
-rw-r--r--Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml3
-rw-r--r--Documentation/devicetree/bindings/media/rc.yaml4
-rw-r--r--Documentation/driver-api/media/maintainer-entry-profile.rst4
-rw-r--r--Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst7
-rw-r--r--Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst15
-rw-r--r--MAINTAINERS43
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/media/cec/core/cec-adap.c95
-rw-r--r--drivers/media/cec/core/cec-api.c5
-rw-r--r--drivers/media/cec/core/cec-core.c117
-rw-r--r--drivers/media/cec/core/cec-pin.c18
-rw-r--r--drivers/media/cec/platform/meson/ao-cec-g12a.c1
-rw-r--r--drivers/media/cec/platform/seco/seco-cec.c5
-rw-r--r--drivers/media/cec/platform/stm32/stm32-cec.c19
-rw-r--r--drivers/media/cec/platform/tegra/tegra_cec.c33
-rw-r--r--drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c3
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-core.c14
-rw-r--r--drivers/media/common/videobuf2/videobuf2-v4l2.c13
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c159
-rw-r--r--drivers/media/dvb-frontends/helene.c56
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.c21
-rw-r--r--drivers/media/i2c/Kconfig23
-rw-r--r--drivers/media/i2c/Makefile2
-rw-r--r--drivers/media/i2c/alvium-csi2.c2
-rw-r--r--drivers/media/i2c/cvs/core.c3
-rw-r--r--drivers/media/i2c/gc0310.c30
-rw-r--r--drivers/media/i2c/imx355.c1522
-rw-r--r--drivers/media/i2c/imx412.c751
-rw-r--r--drivers/media/i2c/imx471.c957
-rw-r--r--drivers/media/i2c/imx678.c1447
-rw-r--r--drivers/media/i2c/ov02a10.c12
-rw-r--r--drivers/media/i2c/ov7740.c10
-rw-r--r--drivers/media/i2c/ov8865.c44
-rw-r--r--drivers/media/i2c/ov9282.c1
-rw-r--r--drivers/media/i2c/rdacm21.c5
-rw-r--r--drivers/media/i2c/vd55g1.c160
-rw-r--r--drivers/media/i2c/video-i2c.c8
-rw-r--r--drivers/media/pci/bt8xx/bttv-driver.c12
-rw-r--r--drivers/media/pci/cobalt/cobalt-alsa-main.c1
-rw-r--r--drivers/media/pci/cobalt/cobalt-driver.c5
-rw-r--r--drivers/media/pci/cx18/cx18-driver.c5
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885-core.c10
-rw-r--r--drivers/media/pci/cx25821/cx25821-alsa.c4
-rw-r--r--drivers/media/pci/cx25821/cx25821-core.c10
-rw-r--r--drivers/media/pci/cx88/cx88-alsa.c6
-rw-r--r--drivers/media/pci/cx88/cx88-mpeg.c5
-rw-r--r--drivers/media/pci/cx88/cx88-video.c5
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-main.c2
-rw-r--r--drivers/media/pci/ddbridge/ddbridge.h2
-rw-r--r--drivers/media/pci/dm1105/dm1105.c10
-rw-r--r--drivers/media/pci/dt3155/dt3155.c4
-rw-r--r--drivers/media/pci/hws/hws_v4l2_ioctl.h4
-rw-r--r--drivers/media/pci/intel/ipu-bridge.c51
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2.c2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6.c10
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c8
-rw-r--r--drivers/media/pci/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/pci/mantis/mantis_common.h8
-rw-r--r--drivers/media/pci/mgb4/mgb4_core.c6
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c2
-rw-r--r--drivers/media/pci/ngene/ngene-cards.c5
-rw-r--r--drivers/media/pci/pluto2/pluto2.c5
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c2047
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c22
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c33
-rw-r--r--drivers/media/pci/saa7146/mxb.c10
-rw-r--r--drivers/media/pci/saa7164/saa7164-core.c5
-rw-r--r--drivers/media/pci/smipcie/smipcie-main.c5
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-core.c2
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c4
-rw-r--r--drivers/media/pci/ttpci/budget.c4
-rw-r--r--drivers/media/pci/tw5864/tw5864-core.c4
-rw-r--r--drivers/media/pci/tw68/tw68-core.c16
-rw-r--r--drivers/media/pci/tw686x/tw686x-core.c23
-rw-r--r--drivers/media/pci/zoran/zoran_card.c7
-rw-r--r--drivers/media/platform/amd/isp4/Kconfig1
-rw-r--r--drivers/media/platform/amd/isp4/isp4_interface.c4
-rw-r--r--drivers/media/platform/amd/isp4/isp4_interface.h2
-rw-r--r--drivers/media/platform/amd/isp4/isp4_subdev.c2
-rw-r--r--drivers/media/platform/amphion/venc.c2
-rw-r--r--drivers/media/platform/broadcom/bcm2835-unicam.c2
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c64
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c6
-rw-r--r--drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h2
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c6
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h6
-rw-r--r--drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c6
-rw-r--r--drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c29
-rw-r--r--drivers/media/platform/qcom/iris/iris_vpu_buffer.c4
-rw-r--r--drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h2
-rw-r--r--drivers/media/platform/rockchip/rga/rga3-hw.c12
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c3
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c4
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c8
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c8
-rw-r--r--drivers/media/platform/rockchip/rkvdec/rkvdec.c8
-rw-r--r--drivers/media/platform/samsung/s3c-camif/camif-core.c10
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmi.c4
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c4
-rw-r--r--drivers/media/platform/ti/Kconfig1
-rw-r--r--drivers/media/platform/verisilicon/hantro_drv.c12
-rw-r--r--drivers/media/radio/radio-cadet.c4
-rw-r--r--drivers/media/radio/radio-gemtek.c4
-rw-r--r--drivers/media/rc/fintek-cir.c4
-rw-r--r--drivers/media/rc/ite-cir.c29
-rw-r--r--drivers/media/rc/keymaps/Makefile2
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-k100.c (renamed from drivers/media/rc/keymaps/rc-videomate-m1f.c)2
-rw-r--r--drivers/media/rc/nuvoton-cir.c6
-rw-r--r--drivers/media/rc/sunxi-cir.c9
-rw-r--r--drivers/media/rc/winbond-cir.c4
-rw-r--r--drivers/media/test-drivers/vicodec/vicodec-core.c4
-rw-r--r--drivers/media/test-drivers/vimc/vimc-sensor.c12
-rw-r--r--drivers/media/test-drivers/vivid/vivid-meta-out.c23
-rw-r--r--drivers/media/usb/airspy/airspy.c17
-rw-r--r--drivers/media/usb/au0828/au0828-cards.c14
-rw-r--r--drivers/media/usb/au0828/au0828-cards.h1
-rw-r--r--drivers/media/usb/au0828/au0828-dvb.c1
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-audio.c5
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c33
-rw-r--r--drivers/media/usb/em28xx/em28xx-core.c4
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-reg.h1
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c114
-rw-r--r--drivers/media/usb/em28xx/em28xx.h3
-rw-r--r--drivers/media/usb/go7007/go7007-driver.c14
-rw-r--r--drivers/media/usb/go7007/go7007-fw.c28
-rw-r--r--drivers/media/usb/go7007/snd-go7007.c10
-rw-r--r--drivers/media/usb/s2255/s2255drv.c5
-rw-r--r--drivers/media/usb/stk1160/stk1160-core.c15
-rw-r--r--drivers/media/usb/stk1160/stk1160-video.c3
-rw-r--r--drivers/media/usb/usbtv/usbtv-audio.c11
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c15
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls-core.c15
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c2
-rw-r--r--drivers/platform/x86/intel/int3472/discrete.c18
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h40
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h4
-rw-r--r--drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h14
-rw-r--r--drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h2
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h18
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h4
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h12
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h8
-rw-r--r--drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h2
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h2
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h2
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h18
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h12
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h8
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h4
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h2
-rw-r--r--drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h2
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_frame_public.h2
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_host_data.h4
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_pipe_public.h8
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_prbs.h4
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_stream.h2
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_timer.h7
-rw-r--r--drivers/staging/media/atomisp/pci/ia_css_types.h6
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h42
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h4
-rw-r--r--drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h14
-rw-r--r--drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h26
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h10
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h10
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h4
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h8
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h10
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h4
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h18
-rw-r--r--drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h4
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_internal.h4
-rw-r--r--drivers/staging/media/atomisp/pci/sh_css_sp.h14
-rw-r--r--drivers/staging/media/atomisp/pci/system_global.h4
-rw-r--r--drivers/staging/media/av7110/av7110.c20
-rw-r--r--drivers/staging/media/ipu7/ipu7.c4
-rw-r--r--drivers/staging/media/meson/vdec/vdec.c4
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus.c4
-rw-r--r--drivers/staging/media/tegra-video/vi.c87
-rw-r--r--drivers/staging/media/tegra-video/vip.c10
-rw-r--r--include/media/cec.h6
-rw-r--r--include/media/drv-intf/s3c_camif.h2
-rw-r--r--include/media/drv-intf/saa7146.h11
-rw-r--r--include/media/media-entity.h1
-rw-r--r--include/media/rc-map.h2
-rw-r--r--include/media/v4l2-ioctl.h4
-rw-r--r--include/media/videobuf2-v4l2.h13
-rw-r--r--include/uapi/linux/cec.h2
204 files changed, 5571 insertions, 3765 deletions
diff --git a/CREDITS b/CREDITS
index fff8e1490714..8c949d9f8505 100644
--- a/CREDITS
+++ b/CREDITS
@@ -640,6 +640,10 @@ S: 25-29 St Giles
S: Oxford
S: United Kingdom
+N: Bingbu Cao
+E: bingbu.cao@amd.com
+D: Ipu6, ipu7 and camera sensor drivers
+
N: Luiz Fernando N. Capitulino
E: lcapitulino@mandriva.com.br
E: lcapitulino@gmail.com
@@ -3338,6 +3342,9 @@ E: rpurdie@rpsys.net
D: Backlight subsystem maintainer
S: United Kingdom
+N: Tian Shu Qiu
+D: Ipu6, ipu7 and camera sensor drivers
+
N: Daniel Quinlan
E: quinlan@pathname.com
W: https://www.pathname.com/~quinlan/
diff --git a/Documentation/admin-guide/media/em28xx-cardlist.rst b/Documentation/admin-guide/media/em28xx-cardlist.rst
index 7dac07986d91..741aa7f7c882 100644
--- a/Documentation/admin-guide/media/em28xx-cardlist.rst
+++ b/Documentation/admin-guide/media/em28xx-cardlist.rst
@@ -446,3 +446,7 @@ EM28xx cards list
- MyGica UTV3 Analog USB2.0 TV Box
- em2860
- eb1a:2860
+ * - 113
+ - StarTech SVID2USB232
+ - em28281
+ - eb1a:8286
diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx355.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx355.yaml
index 6050d7e7dcfe..d9cdfda699bf 100644
--- a/Documentation/devicetree/bindings/media/i2c/sony,imx355.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx355.yaml
@@ -50,8 +50,15 @@ properties:
properties:
data-lanes:
- minItems: 4
- maxItems: 4
+ oneOf:
+ - items:
+ - const: 1
+ - const: 2
+ - const: 3
+ - const: 4
+ - items:
+ - const: 1
+ - const: 2
required:
- link-frequencies
diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml
new file mode 100644
index 000000000000..098f72544216
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Ideas on Board Oy
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx678.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony IMX678 Sensor
+
+maintainers:
+ - Jai Luthra <jai.luthra@ideasonboard.com>
+
+description:
+ Sony IMX678 diagonal 8.86 mm (Type 1/1.8) CMOS active pixel type solid-state
+ image sensor with a square pixel array and 8.40M (3856x2180) effective pixels.
+
+allOf:
+ - $ref: /schemas/media/video-interface-devices.yaml#
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - sony,imx678-aamr
+ - sony,imx678-aaqr
+ - const: sony,imx678
+ description:
+ The IMX678 sensor exists in a colour variant (IMX678-AAQR) and a mono
+ variant (IMX678-AAMR). The variant-specific compatible describes the
+ exact sensor variant, with the generic IMX678 compatible as a fallback.
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description: |
+ Input clock (INCK). Only the rates listed in the datasheet are supported:
+ 13.5, 18, 24, 27, 36, 37.125, 72, and 74.25 MHz.
+ maxItems: 1
+
+ avdd-supply:
+ description: Analog power supply (3.3V)
+
+ ovdd-supply:
+ description: Interface power supply (1.8V)
+
+ dvdd-supply:
+ description: Digital power supply (1.1V)
+
+ reset-gpios:
+ description: Sensor RESETN (XCLR) GPIO
+ maxItems: 1
+
+ port:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ additionalProperties: false
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ oneOf:
+ - items:
+ - const: 1
+ - const: 2
+ - items:
+ - const: 1
+ - const: 2
+ - const: 3
+ - const: 4
+ - items:
+ - const: 1
+ - const: 2
+ - const: 3
+ - const: 4
+ - const: 5
+ - const: 6
+ - const: 7
+ - const: 8
+
+ required:
+ - data-lanes
+ - link-frequencies
+
+ required:
+ - endpoint
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - avdd-supply
+ - ovdd-supply
+ - dvdd-supply
+ - port
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@1a {
+ compatible = "sony,imx678-aaqr", "sony,imx678";
+ reg = <0x1a>;
+ clocks = <&imx678_clk>;
+
+ avdd-supply = <&camera_avdd_3v3>;
+ ovdd-supply = <&camera_ovdd_1v8>;
+ dvdd-supply = <&camera_dvdd_1v1>;
+
+ reset-gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+
+ port {
+ imx678: endpoint {
+ remote-endpoint = <&cam>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <720000000>;
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
index 060ac6829b66..58b1f9e85a9d 100644
--- a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml
@@ -27,9 +27,10 @@ properties:
compatible:
enum:
- st,vd55g1
+ - st,vd55g4
- st,vd65g4
description:
- VD55G1 is the monochrome variant, while VD65G4 is the color one.
+ VD55G1 and VD55G4 are monochrome variants, while VD65G4 is a color one.
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml
index dedc5a4b81ec..43d84296e70d 100644
--- a/Documentation/devicetree/bindings/media/rc.yaml
+++ b/Documentation/devicetree/bindings/media/rc.yaml
@@ -122,10 +122,10 @@ properties:
- rc-proteus-2309
- rc-purpletv
- rc-pv951
- - rc-rc5-tv
- rc-rc6-mce
- rc-real-audio-220-32-keys
- rc-reddo
+ - rc-siemens-gigaset-rc20
- rc-snapstream-firefly
- rc-streamzap
- rc-su3000
@@ -147,11 +147,11 @@ properties:
- rc-tt-1500
- rc-twinhan-dtv-cab-ci
- rc-twinhan1027
+ - rc-vega-s9x
- rc-videomate-k100
- rc-videomate-s350
- rc-videomate-tv-pvr
- rc-videostrong-kii-pro
- - rc-vega-s9x
- rc-wetek-hub
- rc-wetek-play2
- rc-winfast
diff --git a/Documentation/driver-api/media/maintainer-entry-profile.rst b/Documentation/driver-api/media/maintainer-entry-profile.rst
index c5c00c66d85c..7806d83128d4 100644
--- a/Documentation/driver-api/media/maintainer-entry-profile.rst
+++ b/Documentation/driver-api/media/maintainer-entry-profile.rst
@@ -432,6 +432,10 @@ The Media Driver Maintainers responsible for specific areas are:
- Qualcomm drivers
+ - Ricardo Ribalda <ribalda@chromium.org>
+
+ - Media-CI
+
Submit Checklist Addendum
-------------------------
diff --git a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst
index f3293a589dd6..8397bf573798 100644
--- a/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst
+++ b/Documentation/userspace-api/media/cec/cec-ioc-adap-g-log-addrs.rst
@@ -185,6 +185,13 @@ logical address types are already defined will return with error ``EBUSY``.
are CEC devices that can only handle CDC messages.
All other messages are ignored.
+ * .. _`CEC-LOG-ADDRS-FL-CONFIG-FAILED`:
+
+ - ``CEC_LOG_ADDRS_FL_CONFIG_FAILED``
+ - 8
+ - If this flag is set, then the CEC device failed to claim a free logical
+ address and is in the unconfigured state. This can never happen if
+ ``CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK`` was set as well.
.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.5cm}|
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index b8698b85bd80..d78328152b75 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -72,12 +72,6 @@ partial array, all elements have to be set or retrieved. The total size
is calculated as ``elems`` * ``elem_size``. These values can be obtained
by calling :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>`.
-To change the value of a set of controls applications initialize the
-``id``, ``size``, ``reserved2`` and ``value/value64/string/ptr`` fields
-of each struct :c:type:`v4l2_ext_control` and call
-the :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl. The controls will only be set if *all*
-control values are valid.
-
To check if a set of controls have correct values applications
initialize the ``id``, ``size``, ``reserved2`` and
``value/value64/string/ptr`` fields of each struct
@@ -86,6 +80,15 @@ initialize the ``id``, ``size``, ``reserved2`` and
values are automatically adjusted to a valid value or if an error is
returned.
+To change the value of a set of controls applications initialize the
+``id``, ``size``, ``reserved2`` and ``value/value64/string/ptr`` fields
+of each struct :c:type:`v4l2_ext_control` and call
+the :ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` ioctl.
+:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` will implicitly call
+:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` first and return an
+error if that fails. So the controls will only be set if *all*
+control values are valid.
+
When the ``id`` or ``which`` is invalid drivers return an ``EINVAL`` error
code. When the value is out of bounds drivers can choose to take the
closest valid value or return an ``ERANGE`` error code, whatever seems more
diff --git a/MAINTAINERS b/MAINTAINERS
index 8b43b860ec69..e33bfaddaaee 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3956,7 +3956,7 @@ F: Documentation/devicetree/bindings/leds/ams,as3668.yaml
F: drivers/leds/leds-as3668.c
ASAHI KASEI AK7375 LENS VOICE COIL DRIVER
-M: Tianshu Qiu <tian.shu.qiu@intel.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -13150,9 +13150,7 @@ F: drivers/iommu/intel/
INTEL IPU3 CSI-2 CIO2 DRIVER
M: Yong Zhi <yong.zhi@intel.com>
M: Sakari Ailus <sakari.ailus@linux.intel.com>
-M: Bingbu Cao <bingbu.cao@intel.com>
M: Dan Scally <dan.scally@ideasonboard.com>
-R: Tianshu Qiu <tian.shu.qiu@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -13161,8 +13159,6 @@ F: drivers/media/pci/intel/ipu3/
INTEL IPU3 CSI-2 IMGU DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
-R: Bingbu Cao <bingbu.cao@intel.com>
-R: Tianshu Qiu <tian.shu.qiu@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/admin-guide/media/ipu3.rst
@@ -13172,8 +13168,6 @@ F: drivers/staging/media/ipu3/
INTEL IPU6 INPUT SYSTEM DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
-M: Bingbu Cao <bingbu.cao@intel.com>
-R: Tianshu Qiu <tian.shu.qiu@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -13182,7 +13176,6 @@ F: drivers/media/pci/intel/ipu6/
INTEL IPU7 INPUT SYSTEM DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
-R: Bingbu Cao <bingbu.cao@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -13394,6 +13387,7 @@ INTEL SKYLAKE INT3472 ACPI DEVICE DRIVER
M: Daniel Scally <dan.scally@ideasonboard.com>
M: Sakari Ailus <sakari.ailus@linux.intel.com>
S: Maintained
+T: git git://linuxtv.org/media.git
F: drivers/platform/x86/intel/int3472/
F: include/linux/platform_data/x86/int3472.h
@@ -13484,7 +13478,6 @@ F: drivers/net/wireless/intel/iwlwifi/
INTEL VISION SENSING CONTROLLER DRIVER
M: Sakari Ailus <sakari.ailus@linux.intel.com>
-R: Bingbu Cao <bingbu.cao@intel.com>
R: Lixu Zhang <lixu.zhang@intel.com>
L: linux-media@vger.kernel.org
S: Maintained
@@ -19930,7 +19923,8 @@ F: Documentation/devicetree/bindings/media/i2c/ovti,os05b10.yaml
F: drivers/media/i2c/os05b10.c
OMNIVISION OV01A10 SENSOR DRIVER
-M: Bingbu Cao <bingbu.cao@intel.com>
+M: Bingbu Cao <bingbu.cao@amd.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -20023,9 +20017,8 @@ F: Documentation/devicetree/bindings/media/i2c/ovti,ov2735.yaml
F: drivers/media/i2c/ov2735.c
OMNIVISION OV2740 SENSOR DRIVER
-M: Tianshu Qiu <tian.shu.qiu@intel.com>
-R: Sakari Ailus <sakari.ailus@linux.intel.com>
-R: Bingbu Cao <bingbu.cao@intel.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+R: Bingbu Cao <bingbu.cao@amd.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -20167,8 +20160,8 @@ F: Documentation/devicetree/bindings/media/i2c/ovti,ov9650.txt
F: drivers/media/i2c/ov9650.c
OMNIVISION OV9734 SENSOR DRIVER
-M: Tianshu Qiu <tian.shu.qiu@intel.com>
-R: Bingbu Cao <bingbu.cao@intel.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+R: Bingbu Cao <bingbu.cao@amd.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -25265,7 +25258,8 @@ F: Documentation/devicetree/bindings/media/i2c/sony,imx296.yaml
F: drivers/media/i2c/imx296.c
SONY IMX319 SENSOR DRIVER
-M: Bingbu Cao <bingbu.cao@intel.com>
+M: Bingbu Cao <bingbu.cao@amd.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -25287,7 +25281,9 @@ F: Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
F: drivers/media/i2c/imx335.c
SONY IMX355 SENSOR DRIVER
-M: Tianshu Qiu <tian.shu.qiu@intel.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+M: Dave Stevenson <dave.stevenson@raspberrypi.com>
+R: David Heidelberg <david@ixit.cz>
L: linux-media@vger.kernel.org
S: Maintained
T: git git://linuxtv.org/media.git
@@ -25308,6 +25304,19 @@ T: git git://linuxtv.org/media.git
F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
F: drivers/media/i2c/imx415.c
+SONY IMX471 SENSOR DRIVER
+M: Kate Hsuan <hpa@redhat.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/i2c/imx471.c
+
+SONY IMX678 SENSOR DRIVER
+M: Jai Luthra <jai.luthra@ideasonboard.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/sony,imx678.yaml
+F: drivers/media/i2c/imx678.c
+
SONY MEMORYSTICK SUBSYSTEM
M: Maxim Levitsky <maximlevitsky@gmail.com>
M: Alex Dubov <oakad@yahoo.com>
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9a7ac2eb9ce0..21937912a1a5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -862,6 +862,7 @@ static const char * const acpi_honor_dep_ids[] = {
"INTC10DE", /* CVS (LNL) driver must be loaded to allow camera streaming */
"INTC10E0", /* CVS (ARL) driver must be loaded to allow camera streaming */
"INTC10E1", /* CVS (PTL) driver must be loaded to allow camera streaming */
+ "INTC10FA", /* CVS (NVL) driver must be loaded to allow camera streaming */
"RSCV0001", /* RISC-V PLIC */
"RSCV0002", /* RISC-V APLIC */
"RSCV0005", /* RISC-V SBI MPXY MBOX */
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c
index a90cb84a4b4d..ee8a200b9803 100644
--- a/drivers/media/cec/core/cec-adap.c
+++ b/drivers/media/cec/core/cec-adap.c
@@ -80,9 +80,9 @@ void cec_queue_event_fh(struct cec_fh *fh,
const struct cec_event *new_ev, u64 ts)
{
static const u16 max_events[CEC_NUM_EVENTS] = {
- 1, 1, 800, 800, 8, 8, 8, 8
+ 3, 1, 800, 800, 8, 8, 8, 8
};
- struct cec_event_entry *entry;
+ struct cec_event_entry *new_entry, *entry;
unsigned int ev_idx = new_ev->event - 1;
if (WARN_ON(ev_idx >= ARRAY_SIZE(fh->events)))
@@ -92,36 +92,57 @@ void cec_queue_event_fh(struct cec_fh *fh,
ts = ktime_get_ns();
mutex_lock(&fh->lock);
- if (ev_idx < CEC_NUM_CORE_EVENTS)
- entry = &fh->core_events[ev_idx];
- else
- entry = kmalloc_obj(*entry);
- if (entry) {
+ new_entry = kmalloc_obj(*new_entry);
+ if (new_entry) {
if (new_ev->event == CEC_EVENT_LOST_MSGS &&
fh->queued_events[ev_idx]) {
+ entry = list_first_entry(&fh->events[ev_idx],
+ struct cec_event_entry, list);
entry->ev.lost_msgs.lost_msgs +=
new_ev->lost_msgs.lost_msgs;
+ kfree(new_entry);
goto unlock;
}
- entry->ev = *new_ev;
- entry->ev.ts = ts;
+
+ new_entry->ev = *new_ev;
+ new_entry->ev.ts = ts;
+
+ /*
+ * If the physical address becomes invalid (HPD went low),
+ * then just flush all pending STATE_CHANGE events since
+ * those are all obsoleted.
+ *
+ * This ensures you will not see stale STATE_CHANGE events.
+ */
+ if (new_ev->event == CEC_EVENT_STATE_CHANGE &&
+ new_ev->state_change.phys_addr == CEC_PHYS_ADDR_INVALID &&
+ fh->queued_events[ev_idx]) {
+ /* drop all events */
+ while (!list_empty(&fh->events[ev_idx])) {
+ entry = list_first_entry(&fh->events[ev_idx],
+ struct cec_event_entry, list);
+ list_del(&entry->list);
+ kfree(entry);
+ fh->total_queued_events--;
+ fh->queued_events[ev_idx]--;
+ }
+ new_entry->ev.flags |= CEC_EVENT_FL_DROPPED_EVENTS;
+ }
if (fh->queued_events[ev_idx] < max_events[ev_idx]) {
/* Add new msg at the end of the queue */
- list_add_tail(&entry->list, &fh->events[ev_idx]);
+ list_add_tail(&new_entry->list, &fh->events[ev_idx]);
fh->queued_events[ev_idx]++;
fh->total_queued_events++;
goto unlock;
}
- if (ev_idx >= CEC_NUM_CORE_EVENTS) {
- list_add_tail(&entry->list, &fh->events[ev_idx]);
- /* drop the oldest event */
- entry = list_first_entry(&fh->events[ev_idx],
- struct cec_event_entry, list);
- list_del(&entry->list);
- kfree(entry);
- }
+ list_add_tail(&new_entry->list, &fh->events[ev_idx]);
+ /* drop the oldest event */
+ entry = list_first_entry(&fh->events[ev_idx],
+ struct cec_event_entry, list);
+ list_del(&entry->list);
+ kfree(entry);
}
/* Mark that events were lost */
entry = list_first_entry_or_null(&fh->events[ev_idx],
@@ -608,6 +629,13 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
attempts_made = 1;
mutex_lock(&adap->lock);
+ if (adap->error_inj_tx_timeouts) {
+ dprintk(2, "%s: error_inj_tx_timeouts %u\n",
+ __func__, adap->error_inj_tx_timeouts);
+ adap->error_inj_tx_timeouts--;
+ mutex_unlock(&adap->lock);
+ return;
+ }
data = adap->transmitting;
if (!data) {
/*
@@ -965,7 +993,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
*/
mutex_unlock(&adap->lock);
err = wait_for_completion_killable(&data->c);
- cancel_delayed_work_sync(&data->work);
+ disable_delayed_work_sync(&data->work);
mutex_lock(&adap->lock);
if (err)
@@ -1317,7 +1345,7 @@ static int cec_config_log_addr(struct cec_adapter *adap,
{
struct cec_log_addrs *las = &adap->log_addrs;
struct cec_msg msg = { };
- const unsigned int max_retries = 2;
+ const unsigned int max_attempts = 3;
unsigned int i;
int err;
@@ -1328,7 +1356,7 @@ static int cec_config_log_addr(struct cec_adapter *adap,
msg.len = 1;
msg.msg[0] = (log_addr << 4) | log_addr;
- for (i = 0; i < max_retries; i++) {
+ for (i = 0; i < max_attempts; i++) {
err = cec_transmit_msg_fh(adap, &msg, NULL, true);
/*
@@ -1345,31 +1373,24 @@ static int cec_config_log_addr(struct cec_adapter *adap,
if (err)
return err;
- /*
- * The message was aborted or timed out due to a disconnect or
- * unconfigure, just bail out.
- */
- if (msg.tx_status &
- (CEC_TX_STATUS_ABORTED | CEC_TX_STATUS_TIMEOUT))
- return -EINTR;
if (msg.tx_status & CEC_TX_STATUS_OK)
return 0;
if (msg.tx_status & CEC_TX_STATUS_NACK)
break;
/*
- * Retry up to max_retries times if the message was neither
+ * Do up to max_attempts if the message was neither
* OKed or NACKed. This can happen due to e.g. a Lost
* Arbitration condition.
*/
}
/*
- * If we are unable to get an OK or a NACK after max_retries attempts
+ * If we are unable to get an OK or a NACK after max_attempts
* (and note that each attempt already consists of four polls), then
* we assume that something is really weird and that it is not a
* good idea to try and claim this logical address.
*/
- if (i == max_retries) {
+ if (i == max_attempts) {
dprintk(0, "polling for LA %u failed with tx_status=0x%04x\n",
log_addr, msg.tx_status);
return 0;
@@ -1468,6 +1489,7 @@ static int cec_config_thread_func(void *arg)
dprintk(1, "physical address: %x.%x.%x.%x, claim %d logical addresses\n",
cec_phys_addr_exp(adap->phys_addr), las->num_log_addrs);
las->log_addr_mask = 0;
+ las->flags &= ~CEC_LOG_ADDRS_FL_CONFIG_FAILED;
if (las->log_addr_type[0] == CEC_LOG_ADDR_TYPE_UNREGISTERED)
goto configured;
@@ -1600,6 +1622,8 @@ configured:
unconfigure:
for (i = 0; i < las->num_log_addrs; i++)
las->log_addr[i] = CEC_LOG_ADDR_INVALID;
+ if (adap->phys_addr != CEC_PHYS_ADDR_INVALID)
+ las->flags |= CEC_LOG_ADDRS_FL_CONFIG_FAILED;
cec_adap_unconfigure(adap);
adap->is_configuring = false;
adap->must_reconfigure = false;
@@ -1717,7 +1741,6 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
cec_phys_addr_exp(phys_addr));
if (becomes_invalid || !is_invalid) {
adap->phys_addr = CEC_PHYS_ADDR_INVALID;
- cec_post_state_event(adap);
cec_adap_unconfigure(adap);
if (becomes_invalid) {
cec_adap_enable(adap);
@@ -2219,9 +2242,13 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
* Unprocessed messages are aborted if userspace isn't doing
* any processing either.
*/
+ mutex_lock(&adap->lock);
if (!is_broadcast && !is_reply && !adap->follower_cnt &&
- !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT)
+ !adap->cec_follower && msg->msg[1] != CEC_MSG_FEATURE_ABORT) {
+ mutex_unlock(&adap->lock);
return cec_feature_abort(adap, msg);
+ }
+ mutex_unlock(&adap->lock);
break;
}
@@ -2234,10 +2261,12 @@ skip_processing:
* Send to the exclusive follower if there is one, otherwise send
* to all followers.
*/
+ mutex_lock(&adap->lock);
if (adap->cec_follower)
cec_queue_msg_fh(adap->cec_follower, msg);
else
cec_queue_msg_followers(adap, msg);
+ mutex_unlock(&adap->lock);
return 0;
}
diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c
index 103ded79526f..a491d7fc8a71 100644
--- a/drivers/media/cec/core/cec-api.c
+++ b/drivers/media/cec/core/cec-api.c
@@ -345,8 +345,7 @@ static long cec_dqevent(struct cec_adapter *adap, struct cec_fh *fh,
if (copy_to_user(parg, &ev->ev, sizeof(ev->ev)))
err = -EFAULT;
- if (ev_idx >= CEC_NUM_CORE_EVENTS)
- kfree(ev);
+ kfree(ev);
fh->queued_events[ev_idx]--;
fh->total_queued_events--;
@@ -673,7 +672,7 @@ static int cec_release(struct inode *inode, struct file *filp)
list_del(&entry->list);
kfree(entry);
}
- for (i = CEC_NUM_CORE_EVENTS; i < CEC_NUM_EVENTS; i++) {
+ for (i = 0; i < CEC_NUM_EVENTS; i++) {
while (!list_empty(&fh->events[i])) {
struct cec_event_entry *entry =
list_first_entry(&fh->events[i],
diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c
index 0fcd3b5e60c8..230f8a413e74 100644
--- a/drivers/media/cec/core/cec-core.c
+++ b/drivers/media/cec/core/cec-core.c
@@ -5,16 +5,33 @@
* Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitops.h>
+#include <linux/bug.h>
+#include <linux/cdev.h>
+#include <linux/container_of.h>
#include <linux/debugfs.h>
-#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h>
-#include <linux/mm.h>
+#include <linux/kobject.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/minmax.h>
#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/printk.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
+#include <linux/sprintf.h>
#include <linux/string.h>
+#include <linux/time.h>
#include <linux/types.h>
+#include <linux/wait.h>
+
+#include <asm/page.h>
#include "cec-priv.h"
@@ -93,7 +110,7 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
minor = find_first_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES);
if (minor == CEC_NUM_DEVICES) {
mutex_unlock(&cec_devnode_lock);
- pr_err("could not get a free minor\n");
+ pr_err("Could not get a free minor\n");
return -ENFILE;
}
@@ -104,19 +121,19 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
devnode->dev.bus = &cec_bus_type;
devnode->dev.devt = MKDEV(MAJOR(cec_dev_t), minor);
devnode->dev.release = cec_devnode_release;
- dev_set_name(&devnode->dev, "cec%d", devnode->minor);
+ dev_set_name(&devnode->dev, "%s%d", CEC_NAME, devnode->minor);
device_initialize(&devnode->dev);
/* Part 2: Initialize and register the character device */
cdev_init(&devnode->cdev, &cec_devnode_fops);
devnode->cdev.owner = owner;
- kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
+ kobject_set_name(&devnode->cdev.kobj, "%s%d", CEC_NAME, devnode->minor);
devnode->registered = true;
ret = cdev_device_add(&devnode->cdev, &devnode->dev);
if (ret) {
devnode->registered = false;
- pr_err("%s: cdev_device_add failed\n", __func__);
+ pr_err("cdev_device_add() failed\n");
goto clr_bit;
}
@@ -205,19 +222,35 @@ static int cec_error_inj_show(struct seq_file *sf, void *unused)
return call_op(adap, error_inj_show, sf);
}
+DEFINE_SHOW_STORE_ATTRIBUTE(cec_error_inj);
-static int cec_error_inj_open(struct inode *inode, struct file *file)
+static ssize_t cec_error_inj_tx_timeouts_write(struct file *file,
+ const char __user *ubuf, size_t count, loff_t *ppos)
{
- return single_open(file, cec_error_inj_show, inode->i_private);
+ struct seq_file *sf = file->private_data;
+ struct cec_adapter *adap = sf->private;
+ int ret;
+
+ if (count > 5)
+ return -EINVAL;
+
+ mutex_lock(&adap->lock);
+ ret = kstrtou32_from_user(ubuf, count, 0, &adap->error_inj_tx_timeouts);
+ if (ret)
+ adap->error_inj_tx_timeouts = 0;
+ mutex_unlock(&adap->lock);
+ return ret ? : count;
}
-static const struct file_operations cec_error_inj_fops = {
- .open = cec_error_inj_open,
- .write = cec_error_inj_write,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+static int cec_error_inj_tx_timeouts_show(struct seq_file *sf, void *unused)
+{
+ struct cec_adapter *adap = sf->private;
+
+ seq_printf(sf, "%u", adap->error_inj_tx_timeouts);
+ return 0;
+}
+
+DEFINE_SHOW_STORE_ATTRIBUTE(cec_error_inj_tx_timeouts);
#endif
struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
@@ -263,12 +296,11 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
mutex_init(&adap->devnode.lock_fhs);
mutex_init(&adap->devnode.lock);
- adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
+ adap->kthread = kthread_run(cec_thread_func, adap, "%s-%s", CEC_NAME, name);
if (IS_ERR(adap->kthread)) {
- pr_err("cec-%s: kernel_thread() failed\n", name);
+ pr_err("%s: kthread_run() failed\n", name);
res = PTR_ERR(adap->kthread);
- kfree(adap);
- return ERR_PTR(res);
+ goto err_free_adap;
}
#ifdef CONFIG_MEDIA_CEC_RC
@@ -278,11 +310,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
/* Prepare the RC input device */
adap->rc = rc_allocate_device(RC_DRIVER_SCANCODE);
if (!adap->rc) {
- pr_err("cec-%s: failed to allocate memory for rc_dev\n",
- name);
+ pr_err("%s: failed to allocate memory for rc_dev\n", name);
kthread_stop(adap->kthread);
- kfree(adap);
- return ERR_PTR(-ENOMEM);
+ res = -ENOMEM;
+ goto err_free_adap;
}
snprintf(adap->input_phys, sizeof(adap->input_phys),
@@ -298,9 +329,18 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
adap->rc->priv = adap;
adap->rc->map_name = RC_MAP_CEC;
- adap->rc->timeout = MS_TO_US(550);
+ adap->rc->timeout = 550 * USEC_PER_MSEC;
#endif
return adap;
+
+err_free_adap:
+ mutex_destroy(&adap->devnode.lock);
+ mutex_destroy(&adap->devnode.lock_fhs);
+
+ mutex_destroy(&adap->lock);
+
+ kfree(adap);
+ return ERR_PTR(res);
}
EXPORT_SYMBOL_GPL(cec_allocate_adapter);
@@ -326,8 +366,7 @@ int cec_register_adapter(struct cec_adapter *adap,
res = rc_register_device(adap->rc);
if (res) {
- pr_err("cec-%s: failed to prepare input device\n",
- adap->name);
+ pr_err("%s: failed to prepare input device\n", adap->name);
rc_free_device(adap->rc);
adap->rc = NULL;
return res;
@@ -356,6 +395,9 @@ int cec_register_adapter(struct cec_adapter *adap,
debugfs_create_devm_seqfile(&adap->devnode.dev, "status", adap->cec_dir,
cec_adap_status);
+ debugfs_create_file("error-inj-tx-timeouts", 0644, adap->cec_dir, adap,
+ &cec_error_inj_tx_timeouts_fops);
+
if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line)
return 0;
debugfs_create_file("error-inj", 0644, adap->cec_dir, adap,
@@ -371,9 +413,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
return;
#ifdef CONFIG_MEDIA_CEC_RC
- /* Note: rc_unregister also calls rc_free */
rc_unregister_device(adap->rc);
- adap->rc = NULL;
#endif
debugfs_remove_recursive(adap->cec_dir);
#ifdef CONFIG_CEC_NOTIFIER
@@ -387,14 +427,23 @@ void cec_delete_adapter(struct cec_adapter *adap)
{
if (IS_ERR_OR_NULL(adap))
return;
+
if (adap->kthread_config)
kthread_stop(adap->kthread_config);
kthread_stop(adap->kthread);
+
if (adap->ops->adap_free)
adap->ops->adap_free(adap);
+
#ifdef CONFIG_MEDIA_CEC_RC
rc_free_device(adap->rc);
#endif
+
+ mutex_destroy(&adap->devnode.lock);
+ mutex_destroy(&adap->devnode.lock_fhs);
+
+ mutex_destroy(&adap->lock);
+
kfree(adap);
}
EXPORT_SYMBOL_GPL(cec_delete_adapter);
@@ -407,14 +456,14 @@ static int __init cec_devnode_init(void)
int ret = alloc_chrdev_region(&cec_dev_t, 0, CEC_NUM_DEVICES, CEC_NAME);
if (ret < 0) {
- pr_warn("cec: unable to allocate major\n");
+ pr_warn("Unable to allocate major\n");
return ret;
}
#ifdef CONFIG_DEBUG_FS
- top_cec_dir = debugfs_create_dir("cec", NULL);
+ top_cec_dir = debugfs_create_dir(CEC_NAME, NULL);
if (IS_ERR_OR_NULL(top_cec_dir)) {
- pr_warn("cec: Failed to create debugfs cec dir\n");
+ pr_warn("Failed to create debugfs " CEC_NAME " dir\n");
top_cec_dir = NULL;
}
#endif
@@ -423,7 +472,7 @@ static int __init cec_devnode_init(void)
if (ret < 0) {
debugfs_remove_recursive(top_cec_dir);
unregister_chrdev_region(cec_dev_t, CEC_NUM_DEVICES);
- pr_warn("cec: bus_register failed\n");
+ pr_warn("bus_register() failed\n");
return -EIO;
}
diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c
index 6e1c39102832..6a0ee32e8401 100644
--- a/drivers/media/cec/core/cec-pin.c
+++ b/drivers/media/cec/core/cec-pin.c
@@ -115,7 +115,7 @@ static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
return;
pin->adap->cec_pin_is_high = v;
- if (atomic_read(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
+ if (atomic_read_acquire(&pin->work_pin_num_events) < CEC_NUM_PIN_EVENTS) {
u8 ev = v;
if (pin->work_pin_events_dropped) {
@@ -126,7 +126,7 @@ static void cec_pin_update(struct cec_pin *pin, bool v, bool force)
pin->work_pin_ts[pin->work_pin_events_wr] = ktime_get();
pin->work_pin_events_wr =
(pin->work_pin_events_wr + 1) % CEC_NUM_PIN_EVENTS;
- atomic_inc(&pin->work_pin_num_events);
+ atomic_inc_return_release(&pin->work_pin_num_events);
} else {
pin->work_pin_events_dropped = true;
pin->work_pin_events_dropped_cnt++;
@@ -692,7 +692,6 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
v = cec_pin_read(pin);
if (!v)
break;
- pin->state = CEC_ST_RX_START_BIT_HIGH;
delta = ktime_us_delta(ts, pin->ts);
/* Start bit low is too short, go back to idle */
if (delta < CEC_TIM_START_BIT_LOW_MIN - CEC_TIM_IDLE_SAMPLE) {
@@ -703,7 +702,16 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
cec_pin_to_idle(pin);
break;
}
+ pin->state = CEC_ST_RX_START_BIT_HIGH;
if (rx_arb_lost(pin, &poll)) {
+ /*
+ * Normally rx_toggle is toggled in cec_pin_to_idle()
+ * when we're in an RX state, but here we switch to TX
+ * mode, so cec_pin_to_idle() sees a TX mode and never
+ * toggles rx_toggle. So toggle it here as a special
+ * corner case.
+ */
+ pin->rx_toggle ^= 1;
cec_msg_init(&pin->tx_msg, poll >> 4, poll & 0xf);
pin->tx_generated_poll = true;
pin->tx_extra_bytes = 0;
@@ -1101,7 +1109,7 @@ static int cec_pin_thread_func(void *_adap)
pin->work_tx_ts);
}
- while (atomic_read(&pin->work_pin_num_events)) {
+ while (atomic_read_acquire(&pin->work_pin_num_events)) {
unsigned int idx = pin->work_pin_events_rd;
u8 v = pin->work_pin_events[idx];
@@ -1110,7 +1118,7 @@ static int cec_pin_thread_func(void *_adap)
v & CEC_PIN_EVENT_FL_DROPPED,
pin->work_pin_ts[idx]);
pin->work_pin_events_rd = (idx + 1) % CEC_NUM_PIN_EVENTS;
- atomic_dec(&pin->work_pin_num_events);
+ atomic_dec_return_release(&pin->work_pin_num_events);
}
switch (atomic_xchg(&pin->work_irq_change,
diff --git a/drivers/media/cec/platform/meson/ao-cec-g12a.c b/drivers/media/cec/platform/meson/ao-cec-g12a.c
index 41f5b8669cb0..2c914f0008b5 100644
--- a/drivers/media/cec/platform/meson/ao-cec-g12a.c
+++ b/drivers/media/cec/platform/meson/ao-cec-g12a.c
@@ -405,6 +405,7 @@ static int meson_ao_cec_g12a_write(void *context, unsigned int addr,
}
static const struct regmap_config meson_ao_cec_g12a_cec_regmap_conf = {
+ .name = "core",
.reg_bits = 8,
.val_bits = 8,
.reg_read = meson_ao_cec_g12a_read,
diff --git a/drivers/media/cec/platform/seco/seco-cec.c b/drivers/media/cec/platform/seco/seco-cec.c
index 97ed9654c78a..654c70503dd5 100644
--- a/drivers/media/cec/platform/seco/seco-cec.c
+++ b/drivers/media/cec/platform/seco/seco-cec.c
@@ -7,14 +7,15 @@
* Copyright (C) 2018, Aidilab Srl.
*/
-#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
+#include <linux/time.h>
/* CEC Framework */
#include <media/cec-notifier.h>
@@ -356,7 +357,7 @@ static int secocec_ir_probe(void *priv)
cec->ir->allowed_protocols = RC_PROTO_BIT_RC5;
cec->ir->priv = cec;
cec->ir->map_name = RC_MAP_HAUPPAUGE;
- cec->ir->timeout = MS_TO_US(100);
+ cec->ir->timeout = 100 * USEC_PER_MSEC;
/* Clear the status register */
status = smb_rd16(SECOCEC_STATUS_REG_1, &val);
diff --git a/drivers/media/cec/platform/stm32/stm32-cec.c b/drivers/media/cec/platform/stm32/stm32-cec.c
index 1ec0cece0a5b..29418966a98e 100644
--- a/drivers/media/cec/platform/stm32/stm32-cec.c
+++ b/drivers/media/cec/platform/stm32/stm32-cec.c
@@ -132,7 +132,8 @@ static void stm32_rx_done(struct stm32_cec *cec, u32 status)
u32 val;
regmap_read(cec->regmap, CEC_RXDR, &val);
- cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
+ if (cec->rx_msg.len < CEC_MAX_MSG_SIZE)
+ cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
}
if (cec->irq_status & RXEND) {
@@ -193,18 +194,24 @@ static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
{
struct stm32_cec *cec = adap->priv;
- u32 oar = (1 << logical_addr) << 16;
u32 val;
+ int ret;
/* Poll every 100µs the register CEC_CR to wait end of transmission */
- regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
- 100, CEC_XFER_TIMEOUT_MS * 1000);
+ ret = regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
+ 100, CEC_XFER_TIMEOUT_MS * 1000);
+ if (ret)
+ return ret;
+
regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
- if (logical_addr == CEC_LOG_ADDR_INVALID)
+ if (logical_addr == CEC_LOG_ADDR_INVALID) {
regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
- else
+ } else {
+ u32 oar = BIT(logical_addr) << 16;
+
regmap_update_bits(cec->regmap, CEC_CFGR, oar, oar);
+ }
regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
diff --git a/drivers/media/cec/platform/tegra/tegra_cec.c b/drivers/media/cec/platform/tegra/tegra_cec.c
index 3ed50097262f..e22a4625f192 100644
--- a/drivers/media/cec/platform/tegra/tegra_cec.c
+++ b/drivers/media/cec/platform/tegra/tegra_cec.c
@@ -24,6 +24,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/seq_file.h>
#include <linux/clk/tegra.h>
#include <media/cec-notifier.h>
@@ -47,6 +48,7 @@ struct tegra_cec {
u32 tx_buf[CEC_MAX_MSG_SIZE];
u8 tx_buf_cur;
u8 tx_buf_cnt;
+ u32 rx_total_low_drives;
};
static inline u32 cec_read(struct tegra_cec *cec, u32 reg)
@@ -116,6 +118,13 @@ static irqreturn_t tegra_cec_irq_handler(int irq, void *data)
return IRQ_WAKE_THREAD;
}
+ if (status & TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED) {
+ dev_warn_ratelimited(dev, "RX bus error detected, generated low drive\n");
+ cec->rx_total_low_drives++;
+ cec_write(cec, TEGRA_CEC_INT_STAT,
+ TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED);
+ }
+
if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) ||
(status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) {
tegra_cec_error_recovery(cec);
@@ -241,9 +250,21 @@ static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable)
TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED |
TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED |
TEGRA_CEC_INT_MASK_RX_REGISTER_FULL |
+ TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED |
TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED);
- cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE);
+ /*
+ * TX_NAK_MODE ensures that the whole message is transmitted even
+ * if each byte is NACKed. Without this flag the retransmit of the
+ * messages after a NACK can be corrupt. This is a bug in the hardware.
+ *
+ * While less efficient, in practice you rarely transmit messages
+ * that can be NACKed, with the exception of POLL messages which
+ * are just one byte anyway.
+ */
+ cec_write(cec, TEGRA_CEC_HW_CONTROL,
+ TEGRA_CEC_HWCTRL_TX_RX_MODE |
+ TEGRA_CEC_HWCTRL_TX_NAK_MODE);
return 0;
}
@@ -307,11 +328,20 @@ static int tegra_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
return 0;
}
+static void tegra_cec_adap_status(struct cec_adapter *adap, struct seq_file *file)
+{
+ struct tegra_cec *cec = adap->priv;
+
+ seq_printf(file, "receive low drive count: %u\n",
+ cec->rx_total_low_drives);
+}
+
static const struct cec_adap_ops tegra_cec_ops = {
.adap_enable = tegra_cec_adap_enable,
.adap_log_addr = tegra_cec_adap_log_addr,
.adap_transmit = tegra_cec_adap_transmit,
.adap_monitor_all_enable = tegra_cec_adap_monitor_all_enable,
+ .adap_status = tegra_cec_adap_status,
};
static int tegra_cec_probe(struct platform_device *pdev)
@@ -458,6 +488,7 @@ static const struct of_device_id tegra_cec_of_match[] = {
{ .compatible = "nvidia,tegra210-cec", },
{},
};
+MODULE_DEVICE_TABLE(of, tegra_cec_of_match);
static struct platform_driver tegra_cec_driver = {
.driver = {
diff --git a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
index 3381d86096a1..3c6ce6f3d93e 100644
--- a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
+++ b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
@@ -657,7 +657,8 @@ static void extron_process_received(struct extron_port *port, const char *data)
if (!port || port->disconnected)
return;
- if (len < 5 || (len - 2) % 3 || data[len - 2] != '*')
+ if (len < 5 || ((len - 2) / 3 > sizeof(msg.msg)) ||
+ (len - 2) % 3 || data[len - 2] != '*')
goto malformed;
while (*data != '*') {
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index 931e5dc453b9..e1d5c220f738 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -2346,9 +2346,11 @@ static void tpg_fill_params_extras(const struct tpg_data *tpg,
(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
}
-static void tpg_fill_plane_extras(const struct tpg_data *tpg,
- const struct tpg_draw_params *params,
- unsigned p, unsigned h, u8 *vbuf)
+/* noinline to work around clang KASAN issues */
+static noinline_for_stack void
+tpg_fill_plane_extras(const struct tpg_data *tpg,
+ const struct tpg_draw_params *params,
+ unsigned p, unsigned h, u8 *vbuf)
{
unsigned twopixsize = params->twopixsize;
unsigned img_width = params->img_width;
@@ -2483,9 +2485,9 @@ static void tpg_fill_plane_extras(const struct tpg_data *tpg,
}
}
-static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
- const struct tpg_draw_params *params,
- unsigned p, unsigned h, u8 *vbuf)
+static noinline_for_stack void
+tpg_fill_plane_pattern(const struct tpg_data *tpg, const struct tpg_draw_params *params,
+ unsigned p, unsigned h, u8 *vbuf)
{
unsigned twopixsize = params->twopixsize;
unsigned img_width = params->img_width;
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 4baded4fd3b8..5a1ee5eb9c0f 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -635,19 +635,6 @@ struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp)
}
EXPORT_SYMBOL_GPL(vb2_find_buffer);
-/*
- * vb2_querybuf() - query video buffer information
- * @q: vb2 queue
- * @b: buffer struct passed from userspace to vidioc_querybuf handler
- * in driver
- *
- * Should be called from vidioc_querybuf ioctl handler in driver.
- * This function will verify the passed v4l2_buffer structure and fill the
- * relevant information for the userspace.
- *
- * The return values from this function are intended to be directly returned
- * from vidioc_querybuf handler in driver.
- */
int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
{
struct vb2_buffer *vb;
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index d082b6c57c76..0286da57f382 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -30,6 +30,7 @@
#include <linux/kthread.h>
#include <linux/ktime.h>
#include <linux/compat.h>
+#include <linux/lockdep.h>
#include <asm/processor.h>
#include <media/dvb_frontend.h>
@@ -2760,77 +2761,25 @@ static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *w
return 0;
}
-static int dvb_frontend_open(struct inode *inode, struct file *file)
+static int __dvb_frontend_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- struct dvb_adapter *adapter = fe->dvb;
int ret;
- dev_dbg(fe->dvb->device, "%s:\n", __func__);
- if (fe->exit == DVB_FE_DEVICE_REMOVED)
- return -ENODEV;
-
- if (adapter->mfe_shared == 2) {
- mutex_lock(&adapter->mfe_lock);
- if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
- if (adapter->mfe_dvbdev &&
- !adapter->mfe_dvbdev->writers) {
- mutex_unlock(&adapter->mfe_lock);
- return -EBUSY;
- }
- adapter->mfe_dvbdev = dvbdev;
- }
- } else if (adapter->mfe_shared) {
- mutex_lock(&adapter->mfe_lock);
-
- if (!adapter->mfe_dvbdev)
- adapter->mfe_dvbdev = dvbdev;
-
- else if (adapter->mfe_dvbdev != dvbdev) {
- struct dvb_device
- *mfedev = adapter->mfe_dvbdev;
- struct dvb_frontend
- *mfe = mfedev->priv;
- struct dvb_frontend_private
- *mfepriv = mfe->frontend_priv;
- int mferetry = (dvb_mfe_wait_time << 1);
-
- mutex_unlock(&adapter->mfe_lock);
- while (mferetry-- && (mfedev->users != -1 ||
- mfepriv->thread)) {
- if (msleep_interruptible(500)) {
- if (signal_pending(current))
- return -EINTR;
- }
- }
-
- mutex_lock(&adapter->mfe_lock);
- if (adapter->mfe_dvbdev != dvbdev) {
- mfedev = adapter->mfe_dvbdev;
- mfe = mfedev->priv;
- mfepriv = mfe->frontend_priv;
- if (mfedev->users != -1 ||
- mfepriv->thread) {
- mutex_unlock(&adapter->mfe_lock);
- return -EBUSY;
- }
- adapter->mfe_dvbdev = dvbdev;
- }
- }
- }
-
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
- goto err0;
-
- /* If we took control of the bus, we need to force
- reinitialization. This is because many ts_bus_ctrl()
- functions strobe the RESET pin on the demod, and if the
- frontend thread already exists then the dvb_init() routine
- won't get called (which is what usually does initial
- register configuration). */
+ return ret;
+
+ /*
+ * If we took control of the bus, we need to force
+ * reinitialization. This is because many ts_bus_ctrl()
+ * functions strobe the RESET pin on the demod, and if the
+ * frontend thread already exists then the dvb_init() routine
+ * won't get called (which is what usually does initial
+ * register configuration).
+ */
fepriv->reinitialise = 1;
}
@@ -2871,8 +2820,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
dvb_frontend_get(fe);
- if (adapter->mfe_shared)
- mutex_unlock(&adapter->mfe_lock);
return ret;
err3:
@@ -2891,12 +2838,88 @@ err2:
err1:
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
-err0:
- if (adapter->mfe_shared)
- mutex_unlock(&adapter->mfe_lock);
+
+ return ret;
+}
+
+static int wait_dvb_frontend(struct dvb_adapter *adapter,
+ struct dvb_device *mfedev)
+{
+ struct dvb_frontend *mfe = mfedev->priv;
+ struct dvb_frontend_private *mfepriv = mfe->frontend_priv;
+ int mferetry = (dvb_mfe_wait_time << 1);
+ int ret = 0;
+
+ lockdep_assert_held(&adapter->mfe_lock);
+
+ if (mfedev->users == -1 && !mfepriv->thread)
+ return 0;
+
+ mutex_unlock(&adapter->mfe_lock);
+
+ while (mferetry-- && (mfedev->users != -1 || mfepriv->thread)) {
+ if (msleep_interruptible(500))
+ if (signal_pending(current)) {
+ ret = -EINTR;
+ break;
+ }
+ }
+
+ mutex_lock(&adapter->mfe_lock);
+
return ret;
}
+static int dvb_frontend_open(struct inode *inode, struct file *file)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dvb_frontend *fe = dvbdev->priv;
+ struct dvb_adapter *adapter = fe->dvb;
+
+ dev_dbg(fe->dvb->device, "%s:\n", __func__);
+ if (fe->exit == DVB_FE_DEVICE_REMOVED)
+ return -ENODEV;
+
+ if (!adapter->mfe_shared)
+ return __dvb_frontend_open(inode, file);
+
+ guard(mutex)(&adapter->mfe_lock);
+
+ if (adapter->mfe_shared == 2) {
+ if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+ if (adapter->mfe_dvbdev &&
+ !adapter->mfe_dvbdev->writers)
+ return -EBUSY;
+ adapter->mfe_dvbdev = dvbdev;
+ }
+ return __dvb_frontend_open(inode, file);
+ }
+
+ if (!adapter->mfe_dvbdev) {
+ adapter->mfe_dvbdev = dvbdev;
+ } else if (adapter->mfe_dvbdev != dvbdev) {
+ struct dvb_device *mfedev = adapter->mfe_dvbdev;
+ struct dvb_frontend *mfe = mfedev->priv;
+ struct dvb_frontend_private *mfepriv = mfe->frontend_priv;
+ int ret;
+
+ ret = wait_dvb_frontend(adapter, mfedev);
+ if (ret)
+ return ret;
+
+ if (adapter->mfe_dvbdev != dvbdev) {
+ mfedev = adapter->mfe_dvbdev;
+ mfe = mfedev->priv;
+ mfepriv = mfe->frontend_priv;
+ if (mfedev->users != -1 || mfepriv->thread)
+ return -EBUSY;
+ adapter->mfe_dvbdev = dvbdev;
+ }
+ }
+
+ return __dvb_frontend_open(inode, file);
+}
+
static int dvb_frontend_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 993280fefc2c..5fbb466cc8af 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -995,22 +995,22 @@ struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
const struct helene_config *config,
struct i2c_adapter *i2c)
{
- struct helene_priv *priv = NULL;
+ struct helene_priv *pr = NULL;
- priv = kzalloc_obj(struct helene_priv);
- if (priv == NULL)
+ pr = kzalloc_obj(struct helene_priv);
+ if (!pr)
return NULL;
- priv->i2c_address = (config->i2c_address >> 1);
- priv->i2c = i2c;
- priv->set_tuner_data = config->set_tuner_priv;
- priv->set_tuner = config->set_tuner_callback;
- priv->xtal = config->xtal;
+ pr->i2c_address = (config->i2c_address >> 1);
+ pr->i2c = i2c;
+ pr->set_tuner_data = config->set_tuner_priv;
+ pr->set_tuner = config->set_tuner_callback;
+ pr->xtal = config->xtal;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- if (helene_x_pon(priv) != 0) {
- kfree(priv);
+ if (helene_x_pon(pr) != 0) {
+ kfree(pr);
return NULL;
}
@@ -1019,10 +1019,10 @@ struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_s,
sizeof(struct dvb_tuner_ops));
- fe->tuner_priv = priv;
- dev_info(&priv->i2c->dev,
- "Sony HELENE Sat attached on addr=%x at I2C adapter %p\n",
- priv->i2c_address, priv->i2c);
+ fe->tuner_priv = pr;
+ dev_info(&pr->i2c->dev,
+ "Sony HELENE Sat attached on addr=%x at I2C adapter %p\n",
+ pr->i2c_address, pr->i2c);
return fe;
}
EXPORT_SYMBOL_GPL(helene_attach_s);
@@ -1031,22 +1031,22 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
const struct helene_config *config,
struct i2c_adapter *i2c)
{
- struct helene_priv *priv = NULL;
+ struct helene_priv *pr = NULL;
- priv = kzalloc_obj(struct helene_priv);
- if (priv == NULL)
+ pr = kzalloc_obj(struct helene_priv);
+ if (!pr)
return NULL;
- priv->i2c_address = (config->i2c_address >> 1);
- priv->i2c = i2c;
- priv->set_tuner_data = config->set_tuner_priv;
- priv->set_tuner = config->set_tuner_callback;
- priv->xtal = config->xtal;
+ pr->i2c_address = (config->i2c_address >> 1);
+ pr->i2c = i2c;
+ pr->set_tuner_data = config->set_tuner_priv;
+ pr->set_tuner = config->set_tuner_callback;
+ pr->xtal = config->xtal;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- if (helene_x_pon(priv) != 0) {
- kfree(priv);
+ if (helene_x_pon(pr) != 0) {
+ kfree(pr);
return NULL;
}
@@ -1055,10 +1055,10 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe,
memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_t,
sizeof(struct dvb_tuner_ops));
- fe->tuner_priv = priv;
- dev_info(&priv->i2c->dev,
- "Sony HELENE Ter attached on addr=%x at I2C adapter %p\n",
- priv->i2c_address, priv->i2c);
+ fe->tuner_priv = pr;
+ dev_info(&pr->i2c->dev,
+ "Sony HELENE Ter attached on addr=%x at I2C adapter %p\n",
+ pr->i2c_address, pr->i2c);
return fe;
}
EXPORT_SYMBOL_GPL(helene_attach);
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index c564485e3bbb..0330e7f0881a 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -906,9 +906,12 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
goto err;
mutex_unlock(&dev->v4l2_lock);
+
return 0;
err:
+ rtl2832_sdr_free_urbs(dev);
+ rtl2832_sdr_free_stream_bufs(dev);
rtl2832_sdr_cleanup_queued_bufs(dev, VB2_BUF_STATE_QUEUED);
mutex_unlock(&dev->v4l2_lock);
@@ -1477,14 +1480,22 @@ static void rtl2832_sdr_remove(struct platform_device *pdev)
dev_dbg(&pdev->dev, "\n");
- mutex_lock(&dev->vb_queue_lock);
+ /*
+ * vb2_video_unregister_device() releases the vb2 queue, which
+ * triggers rtl2832_sdr_stop_streaming() if streaming is active.
+ * stop_streaming() uses dev->udev to free URBs and coherent DMA
+ * stream buffers via usb_free_coherent(), so it must run before
+ * dev->udev is cleared. vb2_video_unregister_device() locks
+ * vb_queue_lock internally and stop_streaming() locks v4l2_lock,
+ * so neither may be held by the caller.
+ */
+ v4l2_device_disconnect(&dev->v4l2_dev);
+ vb2_video_unregister_device(&dev->vdev);
+
mutex_lock(&dev->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
dev->udev = NULL;
- v4l2_device_disconnect(&dev->v4l2_dev);
- video_unregister_device(&dev->vdev);
mutex_unlock(&dev->v4l2_lock);
- mutex_unlock(&dev->vb_queue_lock);
+
v4l2_device_put(&dev->v4l2_dev);
module_put(pdev->dev.parent->driver->owner);
}
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 5d173e0ecf42..5c52007f9cbe 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -259,6 +259,7 @@ config VIDEO_IMX335
config VIDEO_IMX355
tristate "Sony IMX355 sensor support"
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX355 camera.
@@ -269,6 +270,7 @@ config VIDEO_IMX355
config VIDEO_IMX412
tristate "Sony IMX412 sensor support"
depends on OF
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX412 camera.
@@ -287,6 +289,27 @@ config VIDEO_IMX415
To compile this driver as a module, choose M here: the
module will be called imx415.
+config VIDEO_IMX471
+ tristate "Sony IMX471 sensor support"
+ select V4L2_CCI_I2C
+ help
+ This is a Video4Linux2 sensor driver for the Sony
+ IMX471 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called imx471.
+
+config VIDEO_IMX678
+ tristate "Sony IMX678 sensor support"
+ depends on GPIOLIB
+ select V4L2_CCI_I2C
+ help
+ This is a Video4Linux2 sensor driver for the Sony
+ IMX678 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called imx678.
+
config VIDEO_MAX9271_LIB
tristate
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index e45359efe0e4..d04bd5724552 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -61,6 +61,8 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
obj-$(CONFIG_VIDEO_IMX412) += imx412.o
obj-$(CONFIG_VIDEO_IMX415) += imx415.o
+obj-$(CONFIG_VIDEO_IMX678) += imx678.o
+obj-$(CONFIG_VIDEO_IMX471) += imx471.o
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c
index dd991c2ee700..f51f9b987759 100644
--- a/drivers/media/i2c/alvium-csi2.c
+++ b/drivers/media/i2c/alvium-csi2.c
@@ -1290,7 +1290,7 @@ static int alvium_set_ctrl_auto_exposure(struct alvium_dev *alvium, bool on)
struct device *dev = &alvium->i2c_client->dev;
int ret;
- ret = alvium_write_hshake(alvium, REG_BCRM_WHITE_BALANCE_AUTO_RW,
+ ret = alvium_write_hshake(alvium, REG_BCRM_EXPOSURE_AUTO_RW,
on ? 0x02 : 0x00);
if (ret) {
dev_err(dev, "Fail to set autoexposure reg\n");
diff --git a/drivers/media/i2c/cvs/core.c b/drivers/media/i2c/cvs/core.c
index fe9e59ac311c..d4a3b9c3bab1 100644
--- a/drivers/media/i2c/cvs/core.c
+++ b/drivers/media/i2c/cvs/core.c
@@ -31,6 +31,7 @@
#define PCI_DEVICE_ID_INTEL_IPU7 0x645d /* MTL / LNL */
#define PCI_DEVICE_ID_INTEL_IPU7P5 0xb05d /* ARL / PTL */
+#define PCI_DEVICE_ID_INTEL_IPU8 0xd719 /* NVL */
/*
* IPU7 PCI device IDs not covered by ipu6_pci_tbl in ipu6-pci-table.h.
@@ -39,6 +40,7 @@
static const struct pci_device_id icvs_ipu7_tbl[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7) },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU7P5) },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU8) },
{ }
};
@@ -962,6 +964,7 @@ static const struct acpi_device_id intel_cvs_acpi_match[] = {
{ "INTC10DE" }, /* LNL */
{ "INTC10E0" }, /* ARL */
{ "INTC10E1" }, /* PTL */
+ { "INTC10FA" }, /* NVL */
{ }
};
MODULE_DEVICE_TABLE(acpi, intel_cvs_acpi_match);
diff --git a/drivers/media/i2c/gc0310.c b/drivers/media/i2c/gc0310.c
index 7af4d66f42a0..754e82ad50ae 100644
--- a/drivers/media/i2c/gc0310.c
+++ b/drivers/media/i2c/gc0310.c
@@ -6,6 +6,7 @@
* Copyright (c) 2023-2025 Hans de Goede <hansg@kernel.org>
*/
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
@@ -84,6 +85,8 @@
#define to_gc0310_sensor(x) container_of(x, struct gc0310_device, sd)
struct gc0310_device {
+ struct clk *clk;
+
struct v4l2_subdev sd;
struct media_pad pad;
@@ -635,7 +638,6 @@ static int gc0310_check_hwcfg(struct device *dev)
};
struct fwnode_handle *ep_fwnode;
unsigned long link_freq_bitmap;
- u32 mclk;
int ret;
/*
@@ -647,21 +649,6 @@ static int gc0310_check_hwcfg(struct device *dev)
return dev_err_probe(dev, -EPROBE_DEFER,
"waiting for fwnode graph endpoint\n");
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &mclk);
- if (ret) {
- fwnode_handle_put(ep_fwnode);
- return dev_err_probe(dev, ret,
- "reading clock-frequency property\n");
- }
-
- if (mclk != GC0310_MCLK_FREQ) {
- fwnode_handle_put(ep_fwnode);
- return dev_err_probe(dev, -EINVAL,
- "external clock %u is not supported\n",
- mclk);
- }
-
ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg);
fwnode_handle_put(ep_fwnode);
if (ret)
@@ -685,6 +672,7 @@ static int gc0310_check_hwcfg(struct device *dev)
static int gc0310_probe(struct i2c_client *client)
{
struct gc0310_device *sensor;
+ unsigned long freq;
int ret;
ret = gc0310_check_hwcfg(&client->dev);
@@ -695,6 +683,16 @@ static int gc0310_probe(struct i2c_client *client)
if (!sensor)
return -ENOMEM;
+ sensor->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
+ if (IS_ERR(sensor->clk))
+ return dev_err_probe(&client->dev, PTR_ERR(sensor->clk),
+ "failed to get clock\n");
+
+ freq = clk_get_rate(sensor->clk);
+ if (freq != GC0310_MCLK_FREQ)
+ return dev_err_probe(&client->dev, -EINVAL,
+ "external clock %lu is not supported\n", freq);
+
sensor->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(sensor->reset)) {
return dev_err_probe(&client->dev, PTR_ERR(sensor->reset),
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 27a5c212a527..8eb8588cb71b 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -9,74 +9,97 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/unaligned.h>
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
-#define IMX355_REG_MODE_SELECT 0x0100
+#define IMX355_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX355_MODE_STANDBY 0x00
#define IMX355_MODE_STREAMING 0x01
/* Chip ID */
-#define IMX355_REG_CHIP_ID 0x0016
+#define IMX355_REG_CHIP_ID CCI_REG16(0x0016)
#define IMX355_CHIP_ID 0x0355
+#define IMX355_REG_LANE_SEL CCI_REG8(0x0114)
+
+/* PLL registers that depend on the external clock frequency */
+#define IMX355_REG_EXTCLK_FREQ CCI_REG16(0x0136)
+#define IMX355_REG_PLL_OP_PREDIV CCI_REG8(0x030d)
+#define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e)
+#define IMX355_REG_PLL_IVT_PCK_DIV CCI_REG8(0x0301)
+#define IMX355_REG_PLL_IVT_SYSCK_DIV CCI_REG8(0x0303)
+#define IMX355_PLL_OP_PREDIV 2
+#define IMX355_PLL_IVT_PCK_DIV 5
+
/* V_TIMING internal */
-#define IMX355_REG_FLL 0x0340
+#define IMX355_REG_FLL CCI_REG16(0x0340)
#define IMX355_FLL_MAX 0xffff
+#define IMX355_VBLANK_MIN 20
+
+#define IMX355_REG_LLP CCI_REG16(0x0342)
+#define IMX355_LLP_MAX 0xffff
+
+#define IMX355_REG_X_ADD_START CCI_REG16(0x0344)
+#define IMX355_REG_Y_ADD_START CCI_REG16(0x0346)
+#define IMX355_REG_X_ADD_END CCI_REG16(0x0348)
+#define IMX355_REG_Y_ADD_END CCI_REG16(0x034a)
+#define IMX355_REG_X_OUT_SIZE CCI_REG16(0x034c)
+#define IMX355_REG_Y_OUT_SIZE CCI_REG16(0x034e)
/* Exposure control */
-#define IMX355_REG_EXPOSURE 0x0202
+#define IMX355_REG_EXPOSURE CCI_REG16(0x0202)
#define IMX355_EXPOSURE_MIN 1
#define IMX355_EXPOSURE_STEP 1
#define IMX355_EXPOSURE_DEFAULT 0x0282
+#define IMX355_EXPOSURE_OFFSET 10
/* Analog gain control */
-#define IMX355_REG_ANALOG_GAIN 0x0204
+#define IMX355_REG_ANALOG_GAIN CCI_REG16(0x0204)
#define IMX355_ANA_GAIN_MIN 0
#define IMX355_ANA_GAIN_MAX 960
#define IMX355_ANA_GAIN_STEP 1
#define IMX355_ANA_GAIN_DEFAULT 0
/* Digital gain control */
-#define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
-#define IMX355_REG_DIG_GAIN_GLOBAL 0x020e
+#define IMX355_REG_DPGA_USE_GLOBAL_GAIN CCI_REG8(0x3070)
+#define IMX355_REG_DIG_GAIN_GLOBAL CCI_REG16(0x020e)
#define IMX355_DGTL_GAIN_MIN 256
#define IMX355_DGTL_GAIN_MAX 4095
#define IMX355_DGTL_GAIN_STEP 1
#define IMX355_DGTL_GAIN_DEFAULT 256
/* Test Pattern Control */
-#define IMX355_REG_TEST_PATTERN 0x0600
+#define IMX355_REG_TEST_PATTERN CCI_REG16(0x0600)
#define IMX355_TEST_PATTERN_DISABLED 0
#define IMX355_TEST_PATTERN_SOLID_COLOR 1
#define IMX355_TEST_PATTERN_COLOR_BARS 2
#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
#define IMX355_TEST_PATTERN_PN9 4
-/* Flip Control */
-#define IMX355_REG_ORIENTATION 0x0101
+#define IMX355_REG_REQ_LINK_BIT_RATE CCI_REG16(0x0820)
-/* default link frequency and external clock */
-#define IMX355_LINK_FREQ_DEFAULT 360000000LL
-#define IMX355_EXT_CLK 19200000
-#define IMX355_LINK_FREQ_INDEX 0
+#define IMX355_REG_BINNING_MODE CCI_REG8(0x0900)
+#define IMX355_REG_BINNING_TYPE CCI_REG8(0x0901)
+#define IMX355_REG_BINNING_WEIGHTING CCI_REG8(0x0902)
-/* number of data lanes */
-#define IMX355_DATA_LANES 4
+/* Flip Control */
+#define IMX355_REG_ORIENTATION CCI_REG8(0x0101)
-struct imx355_reg {
- u16 address;
- u8 val;
-};
+#define IMX355_PIXEL_ARRAY_TOP 0
+#define IMX355_PIXEL_ARRAY_LEFT 0
+#define IMX355_PIXEL_ARRAY_WIDTH 3280
+#define IMX355_PIXEL_ARRAY_HEIGHT 2464
struct imx355_reg_list {
u32 num_of_regs;
- const struct imx355_reg *regs;
+ const struct cci_reg_sequence *regs;
};
/* Mode : resolution and related config&values */
@@ -85,28 +108,58 @@ struct imx355_mode {
u32 width;
/* Frame height */
u32 height;
+ struct v4l2_rect crop;
/* V-timing */
u32 fll_def;
- u32 fll_min;
/* H-timing */
u32 llp;
- /* index of link frequency */
- u32 link_freq_index;
-
/* Default register values */
struct imx355_reg_list reg_list;
};
+struct imx355_clk_params {
+ u32 ext_clk;
+ u16 extclk_freq; /* External clock (MHz) in 8.8 fixed point) */
+ u16 pll_op_mpy[2]; /* OP system PLL multiplier */
+ u8 pll_op_prediv[2]; /* OP system pre PLL d */
+};
+
+/*
+ * The clock tree is in single PLL mode, so PREDIV_VT and MPY_IVT do nothing.
+ * In 4 lane mode the MIPI rate is 360Mhz (720Mbit/s) and pixel rate is
+ * 288MPix/s.
+ * In 2 lane mode the MIPI rate is 444MHz (888Mbit/s) and pixel rate
+ * 177.6MPix/s with a 24MHz clock, and 441.6MHz (883.2Mbit/s) and 176.6MPix/s
+ * with a 19.2MHz clock.
+ */
+static const struct imx355_clk_params imx355_clk_params[] = {
+ {
+ .ext_clk = 19200000,
+ .extclk_freq = 0x1333,
+ .pll_op_mpy = { 75, 92 },
+ .pll_op_prediv = { 2, 2 }
+ },
+ {
+ .ext_clk = 24000000,
+ .extclk_freq = 0x1800,
+ .pll_op_mpy = { 60, 111 },
+ .pll_op_prediv = { 2, 3 }
+ },
+};
+
struct imx355_hwcfg {
+ s64 link_freq_menu;
unsigned long link_freq_bitmap;
+ unsigned int num_lanes;
};
struct imx355 {
struct device *dev;
struct clk *clk;
+ struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
@@ -114,24 +167,14 @@ struct imx355 {
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
struct v4l2_ctrl *link_freq;
- struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *exposure;
struct v4l2_ctrl *vflip;
struct v4l2_ctrl *hflip;
- /* Current mode */
- const struct imx355_mode *cur_mode;
-
struct imx355_hwcfg *hwcfg;
-
- /*
- * Mutex for serialized access:
- * Protect sensor set pad format and start/stop streaming safely.
- * Protect access to sensor v4l2 controls.
- */
- struct mutex mutex;
+ const struct imx355_clk_params *clk_params;
struct gpio_desc *reset_gpio;
struct regulator_bulk_data *supplies;
@@ -143,750 +186,147 @@ static const struct regulator_bulk_data imx355_supplies[] = {
{ .supply = "dovdd" },
};
-static const struct imx355_reg imx355_global_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x304e, 0x03 },
- { 0x4348, 0x16 },
- { 0x4350, 0x19 },
- { 0x4408, 0x0a },
- { 0x440c, 0x0b },
- { 0x4411, 0x5f },
- { 0x4412, 0x2c },
- { 0x4623, 0x00 },
- { 0x462c, 0x0f },
- { 0x462d, 0x00 },
- { 0x462e, 0x00 },
- { 0x4684, 0x54 },
- { 0x480a, 0x07 },
- { 0x4908, 0x07 },
- { 0x4909, 0x07 },
- { 0x490d, 0x0a },
- { 0x491e, 0x0f },
- { 0x4921, 0x06 },
- { 0x4923, 0x28 },
- { 0x4924, 0x28 },
- { 0x4925, 0x29 },
- { 0x4926, 0x29 },
- { 0x4927, 0x1f },
- { 0x4928, 0x20 },
- { 0x4929, 0x20 },
- { 0x492a, 0x20 },
- { 0x492c, 0x05 },
- { 0x492d, 0x06 },
- { 0x492e, 0x06 },
- { 0x492f, 0x06 },
- { 0x4930, 0x03 },
- { 0x4931, 0x04 },
- { 0x4932, 0x04 },
- { 0x4933, 0x05 },
- { 0x595e, 0x01 },
- { 0x5963, 0x01 },
- { 0x3030, 0x01 },
- { 0x3031, 0x01 },
- { 0x3045, 0x01 },
- { 0x4010, 0x00 },
- { 0x4011, 0x00 },
- { 0x4012, 0x00 },
- { 0x4013, 0x01 },
- { 0x68a8, 0xfe },
- { 0x68a9, 0xff },
- { 0x6888, 0x00 },
- { 0x6889, 0x00 },
- { 0x68b0, 0x00 },
- { 0x3058, 0x00 },
- { 0x305a, 0x00 },
+static const struct cci_reg_sequence imx355_global_regs[] = {
+ { CCI_REG8(0x304e), 0x03 },
+ { CCI_REG8(0x4348), 0x16 },
+ { CCI_REG8(0x4350), 0x19 },
+ { CCI_REG8(0x4408), 0x0a },
+ { CCI_REG8(0x440c), 0x0b },
+ { CCI_REG8(0x4411), 0x5f },
+ { CCI_REG8(0x4412), 0x2c },
+ { CCI_REG8(0x4623), 0x00 },
+ { CCI_REG8(0x462c), 0x0f },
+ { CCI_REG8(0x462d), 0x00 },
+ { CCI_REG8(0x462e), 0x00 },
+ { CCI_REG8(0x4684), 0x54 },
+ { CCI_REG8(0x480a), 0x07 },
+ { CCI_REG8(0x4908), 0x07 },
+ { CCI_REG8(0x4909), 0x07 },
+ { CCI_REG8(0x490d), 0x0a },
+ { CCI_REG8(0x491e), 0x0f },
+ { CCI_REG8(0x4921), 0x06 },
+ { CCI_REG8(0x4923), 0x28 },
+ { CCI_REG8(0x4924), 0x28 },
+ { CCI_REG8(0x4925), 0x29 },
+ { CCI_REG8(0x4926), 0x29 },
+ { CCI_REG8(0x4927), 0x1f },
+ { CCI_REG8(0x4928), 0x20 },
+ { CCI_REG8(0x4929), 0x20 },
+ { CCI_REG8(0x492a), 0x20 },
+ { CCI_REG8(0x492c), 0x05 },
+ { CCI_REG8(0x492d), 0x06 },
+ { CCI_REG8(0x492e), 0x06 },
+ { CCI_REG8(0x492f), 0x06 },
+ { CCI_REG8(0x4930), 0x03 },
+ { CCI_REG8(0x4931), 0x04 },
+ { CCI_REG8(0x4932), 0x04 },
+ { CCI_REG8(0x4933), 0x05 },
+ { CCI_REG8(0x595e), 0x01 },
+ { CCI_REG8(0x5963), 0x01 },
+ { CCI_REG8(0x3030), 0x01 },
+ { CCI_REG8(0x3031), 0x01 },
+ { CCI_REG8(0x3045), 0x01 },
+ { CCI_REG8(0x4010), 0x00 },
+ { CCI_REG8(0x4011), 0x00 },
+ { CCI_REG8(0x4012), 0x00 },
+ { CCI_REG8(0x4013), 0x01 },
+ { CCI_REG8(0x68a8), 0xfe },
+ { CCI_REG8(0x68a9), 0xff },
+ { CCI_REG8(0x6888), 0x00 },
+ { CCI_REG8(0x6889), 0x00 },
+ { CCI_REG8(0x68b0), 0x00 },
+ { CCI_REG8(0x3058), 0x00 },
+ { CCI_REG8(0x305a), 0x00 },
+ { CCI_REG8(0x0112), 0x0a },
+ { CCI_REG8(0x0113), 0x0a },
+ { IMX355_REG_PLL_IVT_PCK_DIV, IMX355_PLL_IVT_PCK_DIV },
+ { CCI_REG8(0x0303), 0x01 },
+ { CCI_REG8(0x0305), 0x02 },
+ { CCI_REG8(0x0306), 0x00 },
+ { CCI_REG8(0x0307), 0x78 },
+ { CCI_REG8(0x030b), 0x01 },
+ { IMX355_REG_PLL_OP_PREDIV, IMX355_PLL_OP_PREDIV },
+ { CCI_REG8(0x0310), 0x00 },
+ { CCI_REG8(0x0220), 0x00 },
+ { CCI_REG8(0x0222), 0x01 },
+ { CCI_REG8(0x3088), 0x04 },
+ { CCI_REG8(0x6813), 0x02 },
+ { CCI_REG8(0x6835), 0x07 },
+ { CCI_REG8(0x6836), 0x01 },
+ { CCI_REG8(0x6837), 0x04 },
+ { CCI_REG8(0x684d), 0x07 },
+ { CCI_REG8(0x684e), 0x01 },
+ { CCI_REG8(0x684f), 0x04 },
};
-static const struct imx355_reg_list imx355_global_setting = {
- .num_of_regs = ARRAY_SIZE(imx355_global_regs),
- .regs = imx355_global_regs,
+static const struct cci_reg_sequence mode_3268x2448_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3268x2448_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
- { 0x0344, 0x00 },
- { 0x0345, 0x08 },
- { 0x0346, 0x00 },
- { 0x0347, 0x08 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcb },
- { 0x034a, 0x09 },
- { 0x034b, 0x97 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xc4 },
- { 0x034e, 0x09 },
- { 0x034f, 0x90 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_3264x2448_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3264x2448_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
- { 0x0344, 0x00 },
- { 0x0345, 0x08 },
- { 0x0346, 0x00 },
- { 0x0347, 0x08 },
- { 0x0348, 0x0c },
- { 0x0349, 0xc7 },
- { 0x034a, 0x09 },
- { 0x034b, 0x97 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xc0 },
- { 0x034e, 0x09 },
- { 0x034f, 0x90 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_3280x2464_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3280x2464_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xd0 },
- { 0x034e, 0x09 },
- { 0x034f, 0xa0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1940x1096_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1940x1096_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x02 },
- { 0x0345, 0xa0 },
- { 0x0346, 0x02 },
- { 0x0347, 0xac },
- { 0x0348, 0x0a },
- { 0x0349, 0x33 },
- { 0x034a, 0x06 },
- { 0x034b, 0xf3 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x94 },
- { 0x034e, 0x04 },
- { 0x034f, 0x48 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1936x1096_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1936x1096_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x02 },
- { 0x0345, 0xa0 },
- { 0x0346, 0x02 },
- { 0x0347, 0xac },
- { 0x0348, 0x0a },
- { 0x0349, 0x2f },
- { 0x034a, 0x06 },
- { 0x034b, 0xf3 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x90 },
- { 0x034e, 0x04 },
- { 0x034f, 0x48 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1924x1080_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1924x1080_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x02 },
- { 0x0345, 0xa8 },
- { 0x0346, 0x02 },
- { 0x0347, 0xb4 },
- { 0x0348, 0x0a },
- { 0x0349, 0x2b },
- { 0x034a, 0x06 },
- { 0x034b, 0xeb },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x84 },
- { 0x034e, 0x04 },
- { 0x034f, 0x38 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1920x1080_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1920x1080_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x02 },
- { 0x0345, 0xa8 },
- { 0x0346, 0x02 },
- { 0x0347, 0xb4 },
- { 0x0348, 0x0a },
- { 0x0349, 0x27 },
- { 0x034a, 0x06 },
- { 0x034b, 0xeb },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x80 },
- { 0x034e, 0x04 },
- { 0x034f, 0x38 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1640x1232_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1640x1232_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x06 },
- { 0x034d, 0x68 },
- { 0x034e, 0x04 },
- { 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1640x922_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1640x922_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x01 },
- { 0x0347, 0x30 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x08 },
- { 0x034b, 0x63 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x06 },
- { 0x034d, 0x68 },
- { 0x034e, 0x03 },
- { 0x034f, 0x9a },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1300x736_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1300x736_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x01 },
- { 0x0345, 0x58 },
- { 0x0346, 0x01 },
- { 0x0347, 0xf0 },
- { 0x0348, 0x0b },
- { 0x0349, 0x7f },
- { 0x034a, 0x07 },
- { 0x034b, 0xaf },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x14 },
- { 0x034e, 0x02 },
- { 0x034f, 0xe0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1296x736_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1296x736_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x01 },
- { 0x0345, 0x58 },
- { 0x0346, 0x01 },
- { 0x0347, 0xf0 },
- { 0x0348, 0x0b },
- { 0x0349, 0x77 },
- { 0x034a, 0x07 },
- { 0x034b, 0xaf },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x10 },
- { 0x034e, 0x02 },
- { 0x034f, 0xe0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1284x720_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1284x720_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x01 },
- { 0x0345, 0x68 },
- { 0x0346, 0x02 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0b },
- { 0x0349, 0x6f },
- { 0x034a, 0x07 },
- { 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x04 },
- { 0x034e, 0x02 },
- { 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_1280x720_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1280x720_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
- { 0x0344, 0x01 },
- { 0x0345, 0x68 },
- { 0x0346, 0x02 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0b },
- { 0x0349, 0x67 },
- { 0x034a, 0x07 },
- { 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x00 },
- { 0x034e, 0x02 },
- { 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
-};
-
-static const struct imx355_reg mode_820x616_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
- { 0x0340, 0x02 },
- { 0x0341, 0x8c },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x44 },
- { 0x0902, 0x00 },
- { 0x034c, 0x03 },
- { 0x034d, 0x34 },
- { 0x034e, 0x02 },
- { 0x034f, 0x68 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x0306, 0x00 },
- { 0x0307, 0x78 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x030e, 0x00 },
- { 0x030f, 0x4b },
- { 0x0310, 0x00 },
- { 0x0700, 0x02 },
- { 0x0701, 0x78 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence mode_820x616_regs[] = {
+ { CCI_REG8(0x0700), 0x02 },
+ { CCI_REG8(0x0701), 0x78 },
};
static const char * const imx355_test_pattern_menu[] = {
@@ -897,23 +337,19 @@ static const char * const imx355_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
-/*
- * When adding more than the one below, make sure the disallowed ones will
- * actually be disabled in the LINK_FREQ control.
- */
-static const s64 link_freq_menu_items[] = {
- IMX355_LINK_FREQ_DEFAULT,
-};
-
/* Mode configs */
static const struct imx355_mode supported_modes[] = {
{
.width = 3280,
.height = 2464,
+ .crop = {
+ .width = 3280,
+ .height = 2464,
+ .left = 0,
+ .top = 0,
+ },
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
.regs = mode_3280x2464_regs,
@@ -922,10 +358,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 3268,
.height = 2448,
+ .crop = {
+ .width = 3268,
+ .height = 2448,
+ .left = 8,
+ .top = 8,
+ },
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
.regs = mode_3268x2448_regs,
@@ -934,10 +374,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 3264,
.height = 2448,
+ .crop = {
+ .width = 3264,
+ .height = 2448,
+ .left = 8,
+ .top = 8,
+ },
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
.regs = mode_3264x2448_regs,
@@ -946,10 +390,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1940,
.height = 1096,
+ .crop = {
+ .width = 1940,
+ .height = 1096,
+ .left = 672,
+ .top = 684,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
.regs = mode_1940x1096_regs,
@@ -958,10 +406,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1936,
.height = 1096,
+ .crop = {
+ .width = 1936,
+ .height = 1096,
+ .left = 672,
+ .top = 684,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
.regs = mode_1936x1096_regs,
@@ -970,10 +422,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1924,
.height = 1080,
+ .crop = {
+ .width = 1924,
+ .height = 1080,
+ .left = 680,
+ .top = 692,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
.regs = mode_1924x1080_regs,
@@ -982,10 +438,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1920,
.height = 1080,
+ .crop = {
+ .width = 1920,
+ .height = 1080,
+ .left = 680,
+ .top = 692,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
.regs = mode_1920x1080_regs,
@@ -994,10 +454,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1640,
.height = 1232,
+ .crop = {
+ .width = 3280,
+ .height = 2464,
+ .left = 0,
+ .top = 0,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
.regs = mode_1640x1232_regs,
@@ -1006,10 +470,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1640,
.height = 922,
+ .crop = {
+ .width = 3280,
+ .height = 1844,
+ .left = 0,
+ .top = 304,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
.regs = mode_1640x922_regs,
@@ -1018,10 +486,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1300,
.height = 736,
+ .crop = {
+ .width = 2600,
+ .height = 1472,
+ .left = 344,
+ .top = 496,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
.regs = mode_1300x736_regs,
@@ -1030,10 +502,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1296,
.height = 736,
+ .crop = {
+ .width = 2592,
+ .height = 1472,
+ .left = 344,
+ .top = 496,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
.regs = mode_1296x736_regs,
@@ -1042,10 +518,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1284,
.height = 720,
+ .crop = {
+ .width = 2568,
+ .height = 1440,
+ .left = 360,
+ .top = 512,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
.regs = mode_1284x720_regs,
@@ -1054,10 +534,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 1280,
.height = 720,
+ .crop = {
+ .width = 2560,
+ .height = 1440,
+ .left = 360,
+ .top = 512,
+ },
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
.regs = mode_1280x720_regs,
@@ -1066,10 +550,14 @@ static const struct imx355_mode supported_modes[] = {
{
.width = 820,
.height = 616,
+ .crop = {
+ .width = 3280,
+ .height = 2464,
+ .left = 0,
+ .top = 0,
+ },
.fll_def = 652,
- .fll_min = 652,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
.regs = mode_820x616_regs,
@@ -1095,116 +583,28 @@ static u32 imx355_get_format_code(struct imx355 *imx355)
{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
};
- lockdep_assert_held(&imx355->mutex);
code = codes[imx355->vflip->val][imx355->hflip->val];
return code;
}
-/* Read registers up to 4 at a time */
-static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
- struct i2c_msg msgs[2];
- u8 addr_buf[2];
- u8 data_buf[4] = { 0 };
- int ret;
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, addr_buf);
- /* Write register address */
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = ARRAY_SIZE(addr_buf);
- msgs[0].buf = addr_buf;
-
- /* Read data from register */
- 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))
- return -EIO;
-
- *val = get_unaligned_be32(data_buf);
-
- return 0;
-}
-
-/* Write registers up to 4 at a time */
-static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
- u8 buf[6];
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, buf);
- put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
- if (i2c_master_send(client, buf, len + 2) != len + 2)
- return -EIO;
-
- return 0;
-}
-
-/* Write a list of registers */
-static int imx355_write_regs(struct imx355 *imx355,
- const struct imx355_reg *regs, u32 len)
-{
- int ret;
- u32 i;
-
- for (i = 0; i < len; i++) {
- ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
- if (ret) {
- dev_err_ratelimited(imx355->dev,
- "write reg 0x%4.4x return err %d",
- regs[i].address, ret);
-
- return ret;
- }
- }
-
- return 0;
-}
-
-/* Open sub-device */
-static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- struct imx355 *imx355 = to_imx355(sd);
- struct v4l2_mbus_framefmt *try_fmt =
- v4l2_subdev_state_get_format(fh->state, 0);
-
- mutex_lock(&imx355->mutex);
-
- /* Initialize try_fmt */
- try_fmt->width = imx355->cur_mode->width;
- try_fmt->height = imx355->cur_mode->height;
- try_fmt->code = imx355_get_format_code(imx355);
- try_fmt->field = V4L2_FIELD_NONE;
-
- mutex_unlock(&imx355->mutex);
-
- return 0;
-}
-
static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct imx355 *imx355 = container_of(ctrl->handler,
struct imx355, ctrl_handler);
+ const struct v4l2_mbus_framefmt *format = NULL;
+ struct v4l2_subdev_state *state;
s64 max;
int ret;
+ state = v4l2_subdev_get_locked_active_state(&imx355->sd);
+ format = v4l2_subdev_state_get_format(state, 0);
+
/* Propagate change of current control to all related controls */
switch (ctrl->id) {
case V4L2_CID_VBLANK:
/* Update max exposure while meeting expected vblanking */
- max = imx355->cur_mode->height + ctrl->val - 10;
+ max = format->height + ctrl->val - IMX355_EXPOSURE_OFFSET;
__v4l2_ctrl_modify_range(imx355->exposure,
imx355->exposure->minimum,
max, imx355->exposure->step, max);
@@ -1221,31 +621,31 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
/* Analog gain = 1024/(1024 - ctrl->val) times */
- ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_ANALOG_GAIN,
+ ctrl->val, NULL);
break;
case V4L2_CID_DIGITAL_GAIN:
- ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_DIG_GAIN_GLOBAL,
+ ctrl->val, NULL);
break;
case V4L2_CID_EXPOSURE:
- ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_EXPOSURE,
+ ctrl->val, NULL);
break;
case V4L2_CID_VBLANK:
/* Update FLL that meets expected vertical blanking */
- ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
- imx355->cur_mode->height + ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_FLL,
+ format->height + ctrl->val, NULL);
break;
case V4L2_CID_TEST_PATTERN:
- ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
- 2, ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_TEST_PATTERN,
+ ctrl->val, NULL);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
- ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
- imx355->hflip->val |
- imx355->vflip->val << 1);
+ ret = cci_write(imx355->regmap, IMX355_REG_ORIENTATION,
+ imx355->hflip->val | imx355->vflip->val << 1,
+ NULL);
break;
default:
ret = -EINVAL;
@@ -1272,9 +672,7 @@ static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
if (code->index > 0)
return -EINVAL;
- mutex_lock(&imx355->mutex);
code->code = imx355_get_format_code(imx355);
- mutex_unlock(&imx355->mutex);
return 0;
}
@@ -1288,12 +686,9 @@ static int imx355_enum_frame_size(struct v4l2_subdev *sd,
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- mutex_lock(&imx355->mutex);
if (fse->code != imx355_get_format_code(imx355)) {
- mutex_unlock(&imx355->mutex);
return -EINVAL;
}
- mutex_unlock(&imx355->mutex);
fse->min_width = supported_modes[fse->index].width;
fse->max_width = fse->min_width;
@@ -1311,36 +706,10 @@ static void imx355_update_pad_format(struct imx355 *imx355,
fmt->format.height = mode->height;
fmt->format.code = imx355_get_format_code(imx355);
fmt->format.field = V4L2_FIELD_NONE;
-}
-
-static int imx355_do_get_pad_format(struct imx355 *imx355,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct v4l2_mbus_framefmt *framefmt;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
- fmt->format = *framefmt;
- } else {
- imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
- }
-
- return 0;
-}
-
-static int imx355_get_pad_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct imx355 *imx355 = to_imx355(sd);
- int ret;
-
- mutex_lock(&imx355->mutex);
- ret = imx355_do_get_pad_format(imx355, sd_state, fmt);
- mutex_unlock(&imx355->mutex);
-
- return ret;
+ fmt->format.colorspace = V4L2_COLORSPACE_RAW;
+ fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_601;
+ fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
}
static int
@@ -1351,13 +720,8 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
struct imx355 *imx355 = to_imx355(sd);
const struct imx355_mode *mode;
struct v4l2_mbus_framefmt *framefmt;
- s32 vblank_def;
- s32 vblank_min;
+ struct v4l2_rect *crop;
s64 h_blank;
- u64 pixel_rate;
- u32 height;
-
- mutex_lock(&imx355->mutex);
/*
* Only one bayer order is supported.
@@ -1370,23 +734,25 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
width, height,
fmt->format.width, fmt->format.height);
imx355_update_pad_format(imx355, mode, fmt);
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
- *framefmt = fmt->format;
- } else {
- imx355->cur_mode = mode;
- pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
- do_div(pixel_rate, 10);
- __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
+ framefmt = v4l2_subdev_state_get_format(sd_state, 0);
+
+ *framefmt = fmt->format;
+
+ crop = v4l2_subdev_state_get_crop(sd_state, 0);
+ crop->width = mode->crop.width;
+ crop->height = mode->crop.height;
+ crop->left = mode->crop.left;
+ crop->top = mode->crop.top;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
/* Update limits and set FPS to default */
- height = imx355->cur_mode->height;
- vblank_def = imx355->cur_mode->fll_def - height;
- vblank_min = imx355->cur_mode->fll_min - height;
- height = IMX355_FLL_MAX - height;
- __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
- vblank_def);
- __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
- h_blank = mode->llp - imx355->cur_mode->width;
+ __v4l2_ctrl_modify_range(imx355->vblank, IMX355_VBLANK_MIN,
+ IMX355_FLL_MAX - mode->height, 1,
+ mode->fll_def - mode->height);
+ __v4l2_ctrl_s_ctrl(imx355->vblank, mode->fll_def - mode->height);
+
+ h_blank = mode->llp - mode->width;
+
/*
* Currently hblank is not changeable.
* So FPS control is done only by vblank.
@@ -1395,7 +761,42 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
h_blank, 1, h_blank);
}
- mutex_unlock(&imx355->mutex);
+ return 0;
+}
+
+static int imx355_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = IMX355_PIXEL_ARRAY_TOP;
+ sel->r.left = IMX355_PIXEL_ARRAY_LEFT;
+ sel->r.width = IMX355_PIXEL_ARRAY_WIDTH;
+ sel->r.height = IMX355_PIXEL_ARRAY_HEIGHT;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int imx355_entity_init_state(struct v4l2_subdev *subdev,
+ struct v4l2_subdev_state *sd_state)
+{
+ struct v4l2_subdev_format fmt = { };
+
+ fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
+ fmt.format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
+ fmt.format.width = supported_modes[0].width;
+ fmt.format.height = supported_modes[0].height;
+
+ imx355_set_pad_format(subdev, sd_state, &fmt);
return 0;
}
@@ -1403,52 +804,98 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
/* Start streaming */
static int imx355_start_streaming(struct imx355 *imx355)
{
- const struct imx355_reg_list *reg_list;
- int ret;
+ const struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_subdev_state *state;
+ const struct imx355_mode *mode;
+ int lane_idx = imx355->hwcfg->num_lanes == 4 ? 0 : 1;
+ struct v4l2_rect *crop;
+ u64 link_bitrate;
+ u8 binning_mode;
+ int ret = 0;
/* Global Setting */
- reg_list = &imx355_global_setting;
- ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
- if (ret) {
- dev_err(imx355->dev, "failed to set global settings");
- return ret;
- }
+ cci_multi_reg_write(imx355->regmap, imx355_global_regs,
+ ARRAY_SIZE(imx355_global_regs), &ret);
- /* Apply default values of current mode */
- reg_list = &imx355->cur_mode->reg_list;
- ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
- if (ret) {
- dev_err(imx355->dev, "failed to set mode");
- return ret;
- }
+ /* Apply values of current mode */
+ state = v4l2_subdev_get_locked_active_state(&imx355->sd);
+ fmt = v4l2_subdev_state_get_format(state, 0);
+ crop = v4l2_subdev_state_get_crop(state, 0);
+ mode = v4l2_find_nearest_size(supported_modes,
+ ARRAY_SIZE(supported_modes),
+ width, height, fmt->width, fmt->height);
+ cci_multi_reg_write(imx355->regmap, mode->reg_list.regs,
+ mode->reg_list.num_of_regs, &ret);
+
+ /* Set readout crop and size registers */
+ cci_write(imx355->regmap, IMX355_REG_X_ADD_START, crop->left,
+ &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_ADD_START, crop->top, &ret);
+ cci_write(imx355->regmap, IMX355_REG_X_ADD_END,
+ crop->width + crop->left - 1, &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_ADD_END,
+ crop->height + crop->top - 1, &ret);
+ cci_write(imx355->regmap, IMX355_REG_X_OUT_SIZE, fmt->width, &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_OUT_SIZE, fmt->height, &ret);
+
+ binning_mode = ((crop->width / fmt->width) << 4) |
+ (crop->height / fmt->height);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_MODE,
+ binning_mode == 0x11 ? 0x00 : 0x01, &ret);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_TYPE, binning_mode, &ret);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_WEIGHTING, 0x00, &ret);
+
+ /* Set PLL registers for the external clock frequency */
+ cci_write(imx355->regmap, IMX355_REG_EXTCLK_FREQ,
+ imx355->clk_params->extclk_freq, &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_OP_MUL,
+ imx355->clk_params->pll_op_mpy[lane_idx], &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_OP_PREDIV,
+ imx355->clk_params->pll_op_prediv[lane_idx], &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_IVT_SYSCK_DIV,
+ lane_idx ? 2 : 1, &ret);
+
+ /* Set MIPI configuration */
+ cci_write(imx355->regmap, IMX355_REG_LANE_SEL,
+ imx355->hwcfg->num_lanes - 1, &ret);
+
+ link_bitrate = imx355->link_freq->qmenu_int[imx355->link_freq->val] *
+ imx355->hwcfg->num_lanes * 2;
+ do_div(link_bitrate, 1000000);
+ cci_write(imx355->regmap, IMX355_REG_REQ_LINK_BIT_RATE, link_bitrate,
+ &ret);
/* set digital gain control to all color mode */
- ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
- if (ret)
- return ret;
+ cci_write(imx355->regmap, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, &ret);
+
+ /* set line length */
+ cci_write(imx355->regmap, IMX355_REG_LLP,
+ imx355->hblank->val + fmt->width, &ret);
/* Apply customized values from user */
- ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
- if (ret)
- return ret;
+ if (!ret)
+ ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
+
+ cci_write(imx355->regmap, IMX355_REG_MODE_SELECT, IMX355_MODE_STREAMING,
+ &ret);
- return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
- 1, IMX355_MODE_STREAMING);
+ return ret;
}
/* Stop streaming */
static int imx355_stop_streaming(struct imx355 *imx355)
{
- return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
- 1, IMX355_MODE_STANDBY);
+ return cci_write(imx355->regmap, IMX355_REG_MODE_SELECT,
+ IMX355_MODE_STANDBY, NULL);
}
static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
{
struct imx355 *imx355 = to_imx355(sd);
+ struct v4l2_subdev_state *state;
int ret = 0;
- mutex_lock(&imx355->mutex);
+ state = v4l2_subdev_lock_and_get_active_state(sd);
if (enable) {
ret = pm_runtime_resume_and_get(imx355->dev);
@@ -1464,21 +911,21 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx355_stop_streaming(imx355);
- pm_runtime_put(imx355->dev);
+ pm_runtime_put_autosuspend(imx355->dev);
}
/* vflip and hflip cannot change during streaming */
__v4l2_ctrl_grab(imx355->vflip, enable);
__v4l2_ctrl_grab(imx355->hflip, enable);
- mutex_unlock(&imx355->mutex);
+ v4l2_subdev_unlock_state(state);
return ret;
err_rpm_put:
- pm_runtime_put(imx355->dev);
+ pm_runtime_put_autosuspend(imx355->dev);
err_unlock:
- mutex_unlock(&imx355->mutex);
+ v4l2_subdev_unlock_state(state);
return ret;
}
@@ -1487,14 +934,14 @@ err_unlock:
static int imx355_identify_module(struct imx355 *imx355)
{
int ret;
- u32 val;
+ u64 val;
- ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
+ ret = cci_read(imx355->regmap, IMX355_REG_CHIP_ID, &val, NULL);
if (ret)
return ret;
if (val != IMX355_CHIP_ID) {
- dev_err(imx355->dev, "chip id mismatch: %x!=%x",
+ dev_err(imx355->dev, "chip id mismatch: %x!=%llx",
IMX355_CHIP_ID, val);
return -EIO;
}
@@ -1512,9 +959,10 @@ static const struct v4l2_subdev_video_ops imx355_video_ops = {
static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
.enum_mbus_code = imx355_enum_mbus_code,
- .get_fmt = imx355_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = imx355_set_pad_format,
.enum_frame_size = imx355_enum_frame_size,
+ .get_selection = imx355_get_selection,
};
static const struct v4l2_subdev_ops imx355_subdev_ops = {
@@ -1528,7 +976,7 @@ static const struct media_entity_operations imx355_subdev_entity_ops = {
};
static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
- .open = imx355_open,
+ .init_state = imx355_entity_init_state,
};
static int imx355_power_off(struct device *dev)
@@ -1582,13 +1030,11 @@ static int imx355_init_controls(struct imx355 *imx355)
{
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
+ const struct imx355_mode *mode = &supported_modes[0];
s64 exposure_max;
s64 vblank_def;
- s64 vblank_min;
s64 hblank;
u64 pixel_rate;
- const struct imx355_mode *mode;
- u32 max;
int ret;
ctrl_hdlr = &imx355->ctrl_handler;
@@ -1596,40 +1042,34 @@ static int imx355_init_controls(struct imx355 *imx355)
if (ret)
return ret;
- ctrl_hdlr->lock = &imx355->mutex;
- max = ARRAY_SIZE(link_freq_menu_items) - 1;
imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_LINK_FREQ, max, 0,
- link_freq_menu_items);
+ V4L2_CID_LINK_FREQ, 0, 0,
+ &imx355->hwcfg->link_freq_menu);
if (imx355->link_freq)
imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
+ pixel_rate = imx355->hwcfg->link_freq_menu * 2 * imx355->hwcfg->num_lanes;
do_div(pixel_rate, 10);
- /* By default, PIXEL_RATE is read only */
- imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pixel_rate,
- pixel_rate, 1, pixel_rate);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE,
+ pixel_rate, pixel_rate, 1, pixel_rate);
/* Initialize vblank/hblank/exposure parameters based on current mode */
- mode = imx355->cur_mode;
vblank_def = mode->fll_def - mode->height;
- vblank_min = mode->fll_min - mode->height;
imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_VBLANK, vblank_min,
+ V4L2_CID_VBLANK, IMX355_VBLANK_MIN,
IMX355_FLL_MAX - mode->height,
1, vblank_def);
hblank = mode->llp - mode->width;
- imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_HBLANK, hblank, hblank,
- 1, hblank);
+ imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, NULL, V4L2_CID_HBLANK,
+ hblank, hblank, 1, hblank);
if (imx355->hblank)
imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* fll >= exposure time + adjust parameter (default value is 10) */
- exposure_max = mode->fll_def - 10;
+ exposure_max = mode->fll_def - IMX355_EXPOSURE_OFFSET;
imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
V4L2_CID_EXPOSURE,
IMX355_EXPOSURE_MIN, exposure_max,
@@ -1683,14 +1123,17 @@ error:
return ret;
}
-static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
+static struct imx355_hwcfg *imx355_get_hwcfg(struct imx355 *imx355)
{
+ struct device *dev = imx355->dev;
struct imx355_hwcfg *cfg;
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
+ const struct imx355_clk_params *clk = imx355->clk_params;
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
+ int lane_idx;
int ret;
if (!fwnode)
@@ -1708,13 +1151,18 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
if (!cfg)
goto out_err;
- if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX355_DATA_LANES)
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 &&
+ bus_cfg.bus.mipi_csi2.num_data_lanes != 4)
goto out_err;
+ cfg->num_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+
+ lane_idx = cfg->num_lanes == 4 ? 0 : 1;
+ cfg->link_freq_menu = (clk->ext_clk * clk->pll_op_mpy[lane_idx]) /
+ (clk->pll_op_prediv[lane_idx] * 2);
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
- link_freq_menu_items,
- ARRAY_SIZE(link_freq_menu_items),
+ &cfg->link_freq_menu, 1,
&cfg->link_freq_bitmap);
if (ret)
goto out_err;
@@ -1741,7 +1189,10 @@ static int imx355_probe(struct i2c_client *client)
imx355->dev = &client->dev;
- mutex_init(&imx355->mutex);
+ imx355->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx355->regmap))
+ return dev_err_probe(imx355->dev, PTR_ERR(imx355->regmap),
+ "Unable to initialize I2C\n");
imx355->clk = devm_v4l2_sensor_clk_get(imx355->dev, NULL);
if (IS_ERR(imx355->clk))
@@ -1749,7 +1200,13 @@ static int imx355_probe(struct i2c_client *client)
"failed to get clock\n");
freq = clk_get_rate(imx355->clk);
- if (freq != IMX355_EXT_CLK)
+ for (unsigned int i = 0; i < ARRAY_SIZE(imx355_clk_params); i++) {
+ if (freq == imx355_clk_params[i].ext_clk) {
+ imx355->clk_params = &imx355_clk_params[i];
+ break;
+ }
+ }
+ if (!imx355->clk_params)
return dev_err_probe(imx355->dev, -EINVAL,
"external clock %lu is not supported\n",
freq);
@@ -1760,7 +1217,7 @@ static int imx355_probe(struct i2c_client *client)
&imx355->supplies);
if (ret) {
dev_err_probe(imx355->dev, ret, "could not get regulators");
- goto error_probe;
+ return ret;
}
imx355->reset_gpio = devm_gpiod_get_optional(imx355->dev, "reset",
@@ -1768,22 +1225,21 @@ static int imx355_probe(struct i2c_client *client)
if (IS_ERR(imx355->reset_gpio)) {
ret = dev_err_probe(imx355->dev, PTR_ERR(imx355->reset_gpio),
"failed to get gpios");
- goto error_probe;
+ return ret;
}
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
- imx355->hwcfg = imx355_get_hwcfg(imx355->dev);
+ imx355->hwcfg = imx355_get_hwcfg(imx355);
if (!imx355->hwcfg) {
dev_err(imx355->dev, "failed to get hwcfg");
- ret = -ENODEV;
- goto error_probe;
+ return -ENODEV;
}
ret = imx355_power_on(imx355->dev);
if (ret)
- goto error_probe;
+ return ret;
/* Check module identity */
ret = imx355_identify_module(imx355);
@@ -1792,9 +1248,6 @@ static int imx355_probe(struct i2c_client *client)
goto error_power_off;
}
- /* Set default mode to max resolution */
- imx355->cur_mode = &supported_modes[0];
-
ret = imx355_init_controls(imx355);
if (ret) {
dev_err(imx355->dev, "failed to init controls: %d", ret);
@@ -1816,23 +1269,36 @@ static int imx355_probe(struct i2c_client *client)
goto error_handler_free;
}
+ imx355->sd.state_lock = imx355->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&imx355->sd);
+ if (ret < 0) {
+ dev_err_probe(imx355->dev, ret, "subdev init error\n");
+ goto error_media_entity_free;
+ }
+
/*
* Device is already turned on by i2c-core with ACPI domain PM.
* Enable runtime PM and turn off the device.
*/
pm_runtime_set_active(imx355->dev);
pm_runtime_enable(imx355->dev);
- pm_runtime_idle(imx355->dev);
+ pm_runtime_set_autosuspend_delay(imx355->dev, 1000);
+ pm_runtime_use_autosuspend(imx355->dev);
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
if (ret < 0)
- goto error_media_entity_runtime_pm;
+ goto error_subdev_cleanup_runtime_pm;
+
+ pm_runtime_idle(imx355->dev);
return 0;
-error_media_entity_runtime_pm:
+error_subdev_cleanup_runtime_pm:
pm_runtime_disable(imx355->dev);
pm_runtime_set_suspended(imx355->dev);
+ pm_runtime_dont_use_autosuspend(imx355->dev);
+ v4l2_subdev_cleanup(&imx355->sd);
+error_media_entity_free:
media_entity_cleanup(&imx355->sd.entity);
error_handler_free:
@@ -1841,9 +1307,6 @@ error_handler_free:
error_power_off:
imx355_power_off(imx355->dev);
-error_probe:
- mutex_destroy(&imx355->mutex);
-
return ret;
}
@@ -1853,6 +1316,7 @@ static void imx355_remove(struct i2c_client *client)
struct imx355 *imx355 = to_imx355(sd);
v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
@@ -1863,7 +1327,7 @@ static void imx355_remove(struct i2c_client *client)
pm_runtime_set_suspended(imx355->dev);
}
- mutex_destroy(&imx355->mutex);
+ pm_runtime_dont_use_autosuspend(imx355->dev);
}
static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c
index 2705af2f16c0..d2760e9e6194 100644
--- a/drivers/media/i2c/imx412.c
+++ b/drivers/media/i2c/imx412.c
@@ -13,38 +13,39 @@
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
/* Streaming Mode */
-#define IMX412_REG_MODE_SELECT 0x0100
+#define IMX412_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX412_MODE_STANDBY 0x00
#define IMX412_MODE_STREAMING 0x01
/* Lines per frame */
-#define IMX412_REG_LPFR 0x0340
+#define IMX412_REG_LPFR CCI_REG16(0x0340)
/* Chip ID */
-#define IMX412_REG_ID 0x0016
+#define IMX412_REG_ID CCI_REG16(0x0016)
#define IMX412_ID 0x577
/* Exposure control */
-#define IMX412_REG_EXPOSURE_CIT 0x0202
+#define IMX412_REG_EXPOSURE_CIT CCI_REG16(0x0202)
#define IMX412_EXPOSURE_MIN 8
#define IMX412_EXPOSURE_OFFSET 22
#define IMX412_EXPOSURE_STEP 1
#define IMX412_EXPOSURE_DEFAULT 0x0648
/* Analog gain control */
-#define IMX412_REG_AGAIN 0x0204
+#define IMX412_REG_AGAIN CCI_REG16(0x0204)
#define IMX412_AGAIN_MIN 0
#define IMX412_AGAIN_MAX 978
#define IMX412_AGAIN_STEP 1
#define IMX412_AGAIN_DEFAULT 0
/* Group hold register */
-#define IMX412_REG_HOLD 0x0104
+#define IMX412_REG_HOLD CCI_REG8(0x0104)
/* Input clock rate */
#define IMX412_INCLK_RATE 24000000
@@ -57,23 +58,13 @@
#define IMX412_REG_MAX 0xffff
/**
- * struct imx412_reg - imx412 sensor register
- * @address: Register address
- * @val: Register value
- */
-struct imx412_reg {
- u16 address;
- u8 val;
-};
-
-/**
* struct imx412_reg_list - imx412 sensor register list
* @num_of_regs: Number of registers in the list
* @regs: Pointer to register list
*/
struct imx412_reg_list {
u32 num_of_regs;
- const struct imx412_reg *regs;
+ const struct cci_reg_sequence *regs;
};
/**
@@ -111,6 +102,7 @@ static const char * const imx412_supply_names[] = {
/**
* struct imx412 - imx412 sensor device structure
* @dev: Pointer to generic device
+ * @cci: CCI register map
* @client: Pointer to i2c client
* @sd: V4L2 sub-device
* @pad: Media pad. Only one pad supported
@@ -126,10 +118,10 @@ static const char * const imx412_supply_names[] = {
* @again_ctrl: Pointer to analog gain control
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
- * @mutex: Mutex for serializing sensor controls
*/
struct imx412 {
struct device *dev;
+ struct regmap *cci;
struct i2c_client *client;
struct v4l2_subdev sd;
struct media_pad pad;
@@ -147,7 +139,6 @@ struct imx412 {
};
u32 vblank;
const struct imx412_mode *cur_mode;
- struct mutex mutex;
};
static const s64 link_freq[] = {
@@ -155,238 +146,238 @@ static const s64 link_freq[] = {
};
/* Sensor mode registers */
-static const struct imx412_reg mode_4056x3040_regs[] = {
- {0x0136, 0x18},
- {0x0137, 0x00},
- {0x3c7e, 0x08},
- {0x3c7f, 0x02},
- {0x38a8, 0x1f},
- {0x38a9, 0xff},
- {0x38aa, 0x1f},
- {0x38ab, 0xff},
- {0x55d4, 0x00},
- {0x55d5, 0x00},
- {0x55d6, 0x07},
- {0x55d7, 0xff},
- {0x55e8, 0x07},
- {0x55e9, 0xff},
- {0x55ea, 0x00},
- {0x55eb, 0x00},
- {0x575c, 0x07},
- {0x575d, 0xff},
- {0x575e, 0x00},
- {0x575f, 0x00},
- {0x5764, 0x00},
- {0x5765, 0x00},
- {0x5766, 0x07},
- {0x5767, 0xff},
- {0x5974, 0x04},
- {0x5975, 0x01},
- {0x5f10, 0x09},
- {0x5f11, 0x92},
- {0x5f12, 0x32},
- {0x5f13, 0x72},
- {0x5f14, 0x16},
- {0x5f15, 0xba},
- {0x5f17, 0x13},
- {0x5f18, 0x24},
- {0x5f19, 0x60},
- {0x5f1a, 0xe3},
- {0x5f1b, 0xad},
- {0x5f1c, 0x74},
- {0x5f2d, 0x25},
- {0x5f5c, 0xd0},
- {0x6a22, 0x00},
- {0x6a23, 0x1d},
- {0x7ba8, 0x00},
- {0x7ba9, 0x00},
- {0x886b, 0x00},
- {0x9002, 0x0a},
- {0x9004, 0x1a},
- {0x9214, 0x93},
- {0x9215, 0x69},
- {0x9216, 0x93},
- {0x9217, 0x6b},
- {0x9218, 0x93},
- {0x9219, 0x6d},
- {0x921a, 0x57},
- {0x921b, 0x58},
- {0x921c, 0x57},
- {0x921d, 0x59},
- {0x921e, 0x57},
- {0x921f, 0x5a},
- {0x9220, 0x57},
- {0x9221, 0x5b},
- {0x9222, 0x93},
- {0x9223, 0x02},
- {0x9224, 0x93},
- {0x9225, 0x03},
- {0x9226, 0x93},
- {0x9227, 0x04},
- {0x9228, 0x93},
- {0x9229, 0x05},
- {0x922a, 0x98},
- {0x922b, 0x21},
- {0x922c, 0xb2},
- {0x922d, 0xdb},
- {0x922e, 0xb2},
- {0x922f, 0xdc},
- {0x9230, 0xb2},
- {0x9231, 0xdd},
- {0x9232, 0xe2},
- {0x9233, 0xe1},
- {0x9234, 0xb2},
- {0x9235, 0xe2},
- {0x9236, 0xb2},
- {0x9237, 0xe3},
- {0x9238, 0xb7},
- {0x9239, 0xb9},
- {0x923a, 0xb7},
- {0x923b, 0xbb},
- {0x923c, 0xb7},
- {0x923d, 0xbc},
- {0x923e, 0xb7},
- {0x923f, 0xc5},
- {0x9240, 0xb7},
- {0x9241, 0xc7},
- {0x9242, 0xb7},
- {0x9243, 0xc9},
- {0x9244, 0x98},
- {0x9245, 0x56},
- {0x9246, 0x98},
- {0x9247, 0x55},
- {0x9380, 0x00},
- {0x9381, 0x62},
- {0x9382, 0x00},
- {0x9383, 0x56},
- {0x9384, 0x00},
- {0x9385, 0x52},
- {0x9388, 0x00},
- {0x9389, 0x55},
- {0x938a, 0x00},
- {0x938b, 0x55},
- {0x938c, 0x00},
- {0x938d, 0x41},
- {0x5078, 0x01},
- {0x0112, 0x0a},
- {0x0113, 0x0a},
- {0x0114, 0x03},
- {0x0342, 0x11},
- {0x0343, 0xa0},
- {0x0340, 0x0d},
- {0x0341, 0xda},
- {0x3210, 0x00},
- {0x0344, 0x00},
- {0x0345, 0x00},
- {0x0346, 0x00},
- {0x0347, 0x00},
- {0x0348, 0x0f},
- {0x0349, 0xd7},
- {0x034a, 0x0b},
- {0x034b, 0xdf},
- {0x00e3, 0x00},
- {0x00e4, 0x00},
- {0x00e5, 0x01},
- {0x00fc, 0x0a},
- {0x00fd, 0x0a},
- {0x00fe, 0x0a},
- {0x00ff, 0x0a},
- {0xe013, 0x00},
- {0x0220, 0x00},
- {0x0221, 0x11},
- {0x0381, 0x01},
- {0x0383, 0x01},
- {0x0385, 0x01},
- {0x0387, 0x01},
- {0x0900, 0x00},
- {0x0901, 0x11},
- {0x0902, 0x00},
- {0x3140, 0x02},
- {0x3241, 0x11},
- {0x3250, 0x03},
- {0x3e10, 0x00},
- {0x3e11, 0x00},
- {0x3f0d, 0x00},
- {0x3f42, 0x00},
- {0x3f43, 0x00},
- {0x0401, 0x00},
- {0x0404, 0x00},
- {0x0405, 0x10},
- {0x0408, 0x00},
- {0x0409, 0x00},
- {0x040a, 0x00},
- {0x040b, 0x00},
- {0x040c, 0x0f},
- {0x040d, 0xd8},
- {0x040e, 0x0b},
- {0x040f, 0xe0},
- {0x034c, 0x0f},
- {0x034d, 0xd8},
- {0x034e, 0x0b},
- {0x034f, 0xe0},
- {0x0301, 0x05},
- {0x0303, 0x02},
- {0x0305, 0x04},
- {0x0306, 0x00},
- {0x0307, 0xc8},
- {0x0309, 0x0a},
- {0x030b, 0x01},
- {0x030d, 0x02},
- {0x030e, 0x01},
- {0x030f, 0x5e},
- {0x0310, 0x00},
- {0x0820, 0x12},
- {0x0821, 0xc0},
- {0x0822, 0x00},
- {0x0823, 0x00},
- {0x3e20, 0x01},
- {0x3e37, 0x00},
- {0x3f50, 0x00},
- {0x3f56, 0x00},
- {0x3f57, 0xe2},
- {0x3c0a, 0x5a},
- {0x3c0b, 0x55},
- {0x3c0c, 0x28},
- {0x3c0d, 0x07},
- {0x3c0e, 0xff},
- {0x3c0f, 0x00},
- {0x3c10, 0x00},
- {0x3c11, 0x02},
- {0x3c12, 0x00},
- {0x3c13, 0x03},
- {0x3c14, 0x00},
- {0x3c15, 0x00},
- {0x3c16, 0x0c},
- {0x3c17, 0x0c},
- {0x3c18, 0x0c},
- {0x3c19, 0x0a},
- {0x3c1a, 0x0a},
- {0x3c1b, 0x0a},
- {0x3c1c, 0x00},
- {0x3c1d, 0x00},
- {0x3c1e, 0x00},
- {0x3c1f, 0x00},
- {0x3c20, 0x00},
- {0x3c21, 0x00},
- {0x3c22, 0x3f},
- {0x3c23, 0x0a},
- {0x3e35, 0x01},
- {0x3f4a, 0x03},
- {0x3f4b, 0xbf},
- {0x3f26, 0x00},
- {0x0202, 0x0d},
- {0x0203, 0xc4},
- {0x0204, 0x00},
- {0x0205, 0x00},
- {0x020e, 0x01},
- {0x020f, 0x00},
- {0x0210, 0x01},
- {0x0211, 0x00},
- {0x0212, 0x01},
- {0x0213, 0x00},
- {0x0214, 0x01},
- {0x0215, 0x00},
- {0xbcf1, 0x00},
+static const struct cci_reg_sequence mode_4056x3040_regs[] = {
+ { CCI_REG8(0x0136), 0x18 },
+ { CCI_REG8(0x0137), 0x00 },
+ { CCI_REG8(0x3c7e), 0x08 },
+ { CCI_REG8(0x3c7f), 0x02 },
+ { CCI_REG8(0x38a8), 0x1f },
+ { CCI_REG8(0x38a9), 0xff },
+ { CCI_REG8(0x38aa), 0x1f },
+ { CCI_REG8(0x38ab), 0xff },
+ { CCI_REG8(0x55d4), 0x00 },
+ { CCI_REG8(0x55d5), 0x00 },
+ { CCI_REG8(0x55d6), 0x07 },
+ { CCI_REG8(0x55d7), 0xff },
+ { CCI_REG8(0x55e8), 0x07 },
+ { CCI_REG8(0x55e9), 0xff },
+ { CCI_REG8(0x55ea), 0x00 },
+ { CCI_REG8(0x55eb), 0x00 },
+ { CCI_REG8(0x575c), 0x07 },
+ { CCI_REG8(0x575d), 0xff },
+ { CCI_REG8(0x575e), 0x00 },
+ { CCI_REG8(0x575f), 0x00 },
+ { CCI_REG8(0x5764), 0x00 },
+ { CCI_REG8(0x5765), 0x00 },
+ { CCI_REG8(0x5766), 0x07 },
+ { CCI_REG8(0x5767), 0xff },
+ { CCI_REG8(0x5974), 0x04 },
+ { CCI_REG8(0x5975), 0x01 },
+ { CCI_REG8(0x5f10), 0x09 },
+ { CCI_REG8(0x5f11), 0x92 },
+ { CCI_REG8(0x5f12), 0x32 },
+ { CCI_REG8(0x5f13), 0x72 },
+ { CCI_REG8(0x5f14), 0x16 },
+ { CCI_REG8(0x5f15), 0xba },
+ { CCI_REG8(0x5f17), 0x13 },
+ { CCI_REG8(0x5f18), 0x24 },
+ { CCI_REG8(0x5f19), 0x60 },
+ { CCI_REG8(0x5f1a), 0xe3 },
+ { CCI_REG8(0x5f1b), 0xad },
+ { CCI_REG8(0x5f1c), 0x74 },
+ { CCI_REG8(0x5f2d), 0x25 },
+ { CCI_REG8(0x5f5c), 0xd0 },
+ { CCI_REG8(0x6a22), 0x00 },
+ { CCI_REG8(0x6a23), 0x1d },
+ { CCI_REG8(0x7ba8), 0x00 },
+ { CCI_REG8(0x7ba9), 0x00 },
+ { CCI_REG8(0x886b), 0x00 },
+ { CCI_REG8(0x9002), 0x0a },
+ { CCI_REG8(0x9004), 0x1a },
+ { CCI_REG8(0x9214), 0x93 },
+ { CCI_REG8(0x9215), 0x69 },
+ { CCI_REG8(0x9216), 0x93 },
+ { CCI_REG8(0x9217), 0x6b },
+ { CCI_REG8(0x9218), 0x93 },
+ { CCI_REG8(0x9219), 0x6d },
+ { CCI_REG8(0x921a), 0x57 },
+ { CCI_REG8(0x921b), 0x58 },
+ { CCI_REG8(0x921c), 0x57 },
+ { CCI_REG8(0x921d), 0x59 },
+ { CCI_REG8(0x921e), 0x57 },
+ { CCI_REG8(0x921f), 0x5a },
+ { CCI_REG8(0x9220), 0x57 },
+ { CCI_REG8(0x9221), 0x5b },
+ { CCI_REG8(0x9222), 0x93 },
+ { CCI_REG8(0x9223), 0x02 },
+ { CCI_REG8(0x9224), 0x93 },
+ { CCI_REG8(0x9225), 0x03 },
+ { CCI_REG8(0x9226), 0x93 },
+ { CCI_REG8(0x9227), 0x04 },
+ { CCI_REG8(0x9228), 0x93 },
+ { CCI_REG8(0x9229), 0x05 },
+ { CCI_REG8(0x922a), 0x98 },
+ { CCI_REG8(0x922b), 0x21 },
+ { CCI_REG8(0x922c), 0xb2 },
+ { CCI_REG8(0x922d), 0xdb },
+ { CCI_REG8(0x922e), 0xb2 },
+ { CCI_REG8(0x922f), 0xdc },
+ { CCI_REG8(0x9230), 0xb2 },
+ { CCI_REG8(0x9231), 0xdd },
+ { CCI_REG8(0x9232), 0xe2 },
+ { CCI_REG8(0x9233), 0xe1 },
+ { CCI_REG8(0x9234), 0xb2 },
+ { CCI_REG8(0x9235), 0xe2 },
+ { CCI_REG8(0x9236), 0xb2 },
+ { CCI_REG8(0x9237), 0xe3 },
+ { CCI_REG8(0x9238), 0xb7 },
+ { CCI_REG8(0x9239), 0xb9 },
+ { CCI_REG8(0x923a), 0xb7 },
+ { CCI_REG8(0x923b), 0xbb },
+ { CCI_REG8(0x923c), 0xb7 },
+ { CCI_REG8(0x923d), 0xbc },
+ { CCI_REG8(0x923e), 0xb7 },
+ { CCI_REG8(0x923f), 0xc5 },
+ { CCI_REG8(0x9240), 0xb7 },
+ { CCI_REG8(0x9241), 0xc7 },
+ { CCI_REG8(0x9242), 0xb7 },
+ { CCI_REG8(0x9243), 0xc9 },
+ { CCI_REG8(0x9244), 0x98 },
+ { CCI_REG8(0x9245), 0x56 },
+ { CCI_REG8(0x9246), 0x98 },
+ { CCI_REG8(0x9247), 0x55 },
+ { CCI_REG8(0x9380), 0x00 },
+ { CCI_REG8(0x9381), 0x62 },
+ { CCI_REG8(0x9382), 0x00 },
+ { CCI_REG8(0x9383), 0x56 },
+ { CCI_REG8(0x9384), 0x00 },
+ { CCI_REG8(0x9385), 0x52 },
+ { CCI_REG8(0x9388), 0x00 },
+ { CCI_REG8(0x9389), 0x55 },
+ { CCI_REG8(0x938a), 0x00 },
+ { CCI_REG8(0x938b), 0x55 },
+ { CCI_REG8(0x938c), 0x00 },
+ { CCI_REG8(0x938d), 0x41 },
+ { CCI_REG8(0x5078), 0x01 },
+ { CCI_REG8(0x0112), 0x0a },
+ { CCI_REG8(0x0113), 0x0a },
+ { CCI_REG8(0x0114), 0x03 },
+ { CCI_REG8(0x0342), 0x11 },
+ { CCI_REG8(0x0343), 0xa0 },
+ { CCI_REG8(0x0340), 0x0d },
+ { CCI_REG8(0x0341), 0xda },
+ { CCI_REG8(0x3210), 0x00 },
+ { CCI_REG8(0x0344), 0x00 },
+ { CCI_REG8(0x0345), 0x00 },
+ { CCI_REG8(0x0346), 0x00 },
+ { CCI_REG8(0x0347), 0x00 },
+ { CCI_REG8(0x0348), 0x0f },
+ { CCI_REG8(0x0349), 0xd7 },
+ { CCI_REG8(0x034a), 0x0b },
+ { CCI_REG8(0x034b), 0xdf },
+ { CCI_REG8(0x00e3), 0x00 },
+ { CCI_REG8(0x00e4), 0x00 },
+ { CCI_REG8(0x00e5), 0x01 },
+ { CCI_REG8(0x00fc), 0x0a },
+ { CCI_REG8(0x00fd), 0x0a },
+ { CCI_REG8(0x00fe), 0x0a },
+ { CCI_REG8(0x00ff), 0x0a },
+ { CCI_REG8(0xe013), 0x00 },
+ { CCI_REG8(0x0220), 0x00 },
+ { CCI_REG8(0x0221), 0x11 },
+ { CCI_REG8(0x0381), 0x01 },
+ { CCI_REG8(0x0383), 0x01 },
+ { CCI_REG8(0x0385), 0x01 },
+ { CCI_REG8(0x0387), 0x01 },
+ { CCI_REG8(0x0900), 0x00 },
+ { CCI_REG8(0x0901), 0x11 },
+ { CCI_REG8(0x0902), 0x00 },
+ { CCI_REG8(0x3140), 0x02 },
+ { CCI_REG8(0x3241), 0x11 },
+ { CCI_REG8(0x3250), 0x03 },
+ { CCI_REG8(0x3e10), 0x00 },
+ { CCI_REG8(0x3e11), 0x00 },
+ { CCI_REG8(0x3f0d), 0x00 },
+ { CCI_REG8(0x3f42), 0x00 },
+ { CCI_REG8(0x3f43), 0x00 },
+ { CCI_REG8(0x0401), 0x00 },
+ { CCI_REG8(0x0404), 0x00 },
+ { CCI_REG8(0x0405), 0x10 },
+ { CCI_REG8(0x0408), 0x00 },
+ { CCI_REG8(0x0409), 0x00 },
+ { CCI_REG8(0x040a), 0x00 },
+ { CCI_REG8(0x040b), 0x00 },
+ { CCI_REG8(0x040c), 0x0f },
+ { CCI_REG8(0x040d), 0xd8 },
+ { CCI_REG8(0x040e), 0x0b },
+ { CCI_REG8(0x040f), 0xe0 },
+ { CCI_REG8(0x034c), 0x0f },
+ { CCI_REG8(0x034d), 0xd8 },
+ { CCI_REG8(0x034e), 0x0b },
+ { CCI_REG8(0x034f), 0xe0 },
+ { CCI_REG8(0x0301), 0x05 },
+ { CCI_REG8(0x0303), 0x02 },
+ { CCI_REG8(0x0305), 0x04 },
+ { CCI_REG8(0x0306), 0x00 },
+ { CCI_REG8(0x0307), 0xc8 },
+ { CCI_REG8(0x0309), 0x0a },
+ { CCI_REG8(0x030b), 0x01 },
+ { CCI_REG8(0x030d), 0x02 },
+ { CCI_REG8(0x030e), 0x01 },
+ { CCI_REG8(0x030f), 0x5e },
+ { CCI_REG8(0x0310), 0x00 },
+ { CCI_REG8(0x0820), 0x12 },
+ { CCI_REG8(0x0821), 0xc0 },
+ { CCI_REG8(0x0822), 0x00 },
+ { CCI_REG8(0x0823), 0x00 },
+ { CCI_REG8(0x3e20), 0x01 },
+ { CCI_REG8(0x3e37), 0x00 },
+ { CCI_REG8(0x3f50), 0x00 },
+ { CCI_REG8(0x3f56), 0x00 },
+ { CCI_REG8(0x3f57), 0xe2 },
+ { CCI_REG8(0x3c0a), 0x5a },
+ { CCI_REG8(0x3c0b), 0x55 },
+ { CCI_REG8(0x3c0c), 0x28 },
+ { CCI_REG8(0x3c0d), 0x07 },
+ { CCI_REG8(0x3c0e), 0xff },
+ { CCI_REG8(0x3c0f), 0x00 },
+ { CCI_REG8(0x3c10), 0x00 },
+ { CCI_REG8(0x3c11), 0x02 },
+ { CCI_REG8(0x3c12), 0x00 },
+ { CCI_REG8(0x3c13), 0x03 },
+ { CCI_REG8(0x3c14), 0x00 },
+ { CCI_REG8(0x3c15), 0x00 },
+ { CCI_REG8(0x3c16), 0x0c },
+ { CCI_REG8(0x3c17), 0x0c },
+ { CCI_REG8(0x3c18), 0x0c },
+ { CCI_REG8(0x3c19), 0x0a },
+ { CCI_REG8(0x3c1a), 0x0a },
+ { CCI_REG8(0x3c1b), 0x0a },
+ { CCI_REG8(0x3c1c), 0x00 },
+ { CCI_REG8(0x3c1d), 0x00 },
+ { CCI_REG8(0x3c1e), 0x00 },
+ { CCI_REG8(0x3c1f), 0x00 },
+ { CCI_REG8(0x3c20), 0x00 },
+ { CCI_REG8(0x3c21), 0x00 },
+ { CCI_REG8(0x3c22), 0x3f },
+ { CCI_REG8(0x3c23), 0x0a },
+ { CCI_REG8(0x3e35), 0x01 },
+ { CCI_REG8(0x3f4a), 0x03 },
+ { CCI_REG8(0x3f4b), 0xbf },
+ { CCI_REG8(0x3f26), 0x00 },
+ { CCI_REG8(0x0202), 0x0d },
+ { CCI_REG8(0x0203), 0xc4 },
+ { CCI_REG8(0x0204), 0x00 },
+ { CCI_REG8(0x0205), 0x00 },
+ { CCI_REG8(0x020e), 0x01 },
+ { CCI_REG8(0x020f), 0x00 },
+ { CCI_REG8(0x0210), 0x01 },
+ { CCI_REG8(0x0211), 0x00 },
+ { CCI_REG8(0x0212), 0x01 },
+ { CCI_REG8(0x0213), 0x00 },
+ { CCI_REG8(0x0214), 0x01 },
+ { CCI_REG8(0x0215), 0x00 },
+ { CCI_REG8(0xbcf1), 0x00 },
};
/* Supported sensor mode configurations */
@@ -418,97 +409,6 @@ static inline struct imx412 *to_imx412(struct v4l2_subdev *subdev)
}
/**
- * imx412_read_reg() - Read registers.
- * @imx412: pointer to imx412 device
- * @reg: register address
- * @len: length of bytes to read. Max supported bytes is 4
- * @val: pointer to register value to be filled.
- *
- * Return: 0 if successful, error code otherwise.
- */
-static int imx412_read_reg(struct imx412 *imx412, u16 reg, u32 len, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx412->sd);
- struct i2c_msg msgs[2] = {0};
- u8 addr_buf[2] = {0};
- u8 data_buf[4] = {0};
- int ret;
-
- if (WARN_ON(len > 4))
- return -EINVAL;
-
- put_unaligned_be16(reg, addr_buf);
-
- /* Write register address */
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = ARRAY_SIZE(addr_buf);
- msgs[0].buf = addr_buf;
-
- /* Read data from register */
- 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))
- return -EIO;
-
- *val = get_unaligned_be32(data_buf);
-
- return 0;
-}
-
-/**
- * imx412_write_reg() - Write register
- * @imx412: pointer to imx412 device
- * @reg: register address
- * @len: length of bytes. Max supported bytes is 4
- * @val: register value
- *
- * Return: 0 if successful, error code otherwise.
- */
-static int imx412_write_reg(struct imx412 *imx412, u16 reg, u32 len, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx412->sd);
- u8 buf[6] = {0};
-
- if (WARN_ON(len > 4))
- return -EINVAL;
-
- put_unaligned_be16(reg, buf);
- put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
- if (i2c_master_send(client, buf, len + 2) != len + 2)
- return -EIO;
-
- return 0;
-}
-
-/**
- * imx412_write_regs() - Write a list of registers
- * @imx412: pointer to imx412 device
- * @regs: list of registers to be written
- * @len: length of registers array
- *
- * Return: 0 if successful, error code otherwise.
- */
-static int imx412_write_regs(struct imx412 *imx412,
- const struct imx412_reg *regs, u32 len)
-{
- unsigned int i;
- int ret;
-
- for (i = 0; i < len; i++) {
- ret = imx412_write_reg(imx412, regs[i].address, 1, regs[i].val);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-/**
* imx412_update_controls() - Update control ranges based on streaming mode
* @imx412: pointer to imx412 device
* @mode: pointer to imx412_mode sensor mode
@@ -543,29 +443,25 @@ static int imx412_update_controls(struct imx412 *imx412,
static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
{
u32 lpfr;
- int ret;
+ int ret = 0;
+ int ret_hold;
lpfr = imx412->vblank + imx412->cur_mode->height;
dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n",
exposure, gain, lpfr);
- ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1);
- if (ret)
- return ret;
+ cci_write(imx412->cci, IMX412_REG_HOLD, 1, &ret);
- ret = imx412_write_reg(imx412, IMX412_REG_LPFR, 2, lpfr);
- if (ret)
- goto error_release_group_hold;
+ cci_write(imx412->cci, IMX412_REG_LPFR, lpfr, &ret);
- ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure);
- if (ret)
- goto error_release_group_hold;
+ cci_write(imx412->cci, IMX412_REG_EXPOSURE_CIT, exposure, &ret);
- ret = imx412_write_reg(imx412, IMX412_REG_AGAIN, 2, gain);
+ cci_write(imx412->cci, IMX412_REG_AGAIN, gain, &ret);
-error_release_group_hold:
- imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 0);
+ ret_hold = cci_write(imx412->cci, IMX412_REG_HOLD, 0, NULL);
+ if (ret_hold)
+ return ret_hold;
return ret;
}
@@ -679,8 +575,6 @@ static int imx412_get_pad_format(struct v4l2_subdev *sd,
{
struct imx412 *imx412 = to_imx412(sd);
- mutex_lock(&imx412->mutex);
-
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
struct v4l2_mbus_framefmt *framefmt;
@@ -690,8 +584,6 @@ static int imx412_get_pad_format(struct v4l2_subdev *sd,
imx412_fill_pad_format(imx412, imx412->cur_mode, fmt);
}
- mutex_unlock(&imx412->mutex);
-
return 0;
}
@@ -703,8 +595,6 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
const struct imx412_mode *mode;
int ret = 0;
- mutex_lock(&imx412->mutex);
-
mode = &supported_mode;
imx412_fill_pad_format(imx412, mode, fmt);
@@ -719,8 +609,6 @@ static int imx412_set_pad_format(struct v4l2_subdev *sd,
imx412->cur_mode = mode;
}
- mutex_unlock(&imx412->mutex);
-
return ret;
}
@@ -737,88 +625,86 @@ static int imx412_init_state(struct v4l2_subdev *sd,
}
/**
- * imx412_start_streaming() - Start sensor stream
- * @imx412: pointer to imx412 device
+ * imx412_enable_streams() - Enable specified streams for the sensor
+ * @sd: pointer to the V4L2 subdevice
+ * @state: pointer to the subdevice state
+ * @pad: pad number for which streams are enabled
+ * @streams_mask: bitmask specifying the streams to enable
*
* Return: 0 if successful, error code otherwise.
*/
-static int imx412_start_streaming(struct imx412 *imx412)
+static int imx412_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
{
const struct imx412_reg_list *reg_list;
+ struct imx412 *imx412 = to_imx412(sd);
int ret;
+ ret = pm_runtime_resume_and_get(imx412->dev);
+ if (ret < 0)
+ return ret;
+
/* Write sensor mode registers */
reg_list = &imx412->cur_mode->reg_list;
- ret = imx412_write_regs(imx412, reg_list->regs,
- reg_list->num_of_regs);
+ ret = cci_multi_reg_write(imx412->cci, reg_list->regs,
+ reg_list->num_of_regs, NULL);
if (ret) {
dev_err(imx412->dev, "fail to write initial registers\n");
- return ret;
+ goto err_rpm_put;
}
/* Setup handler will write actual exposure and gain */
ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler);
if (ret) {
dev_err(imx412->dev, "fail to setup handler\n");
- return ret;
+ goto err_rpm_put;
}
/* Delay is required before streaming*/
usleep_range(7400, 8000);
/* Start streaming */
- ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT,
- 1, IMX412_MODE_STREAMING);
+ ret = cci_write(imx412->cci, IMX412_REG_MODE_SELECT,
+ IMX412_MODE_STREAMING, NULL);
if (ret) {
dev_err(imx412->dev, "fail to start streaming\n");
- return ret;
+ goto err_rpm_put;
}
return 0;
+
+err_rpm_put:
+ pm_runtime_put(imx412->dev);
+
+ return ret;
}
/**
- * imx412_stop_streaming() - Stop sensor stream
- * @imx412: pointer to imx412 device
+ * imx412_disable_streams() - Enable specified streams for the sensor
+ * @sd: pointer to the V4L2 subdevice
+ * @state: pointer to the subdevice state
+ * @pad: pad number for which streams are disabled
+ * @streams_mask: bitmask specifying the streams to disable
*
* Return: 0 if successful, error code otherwise.
*/
-static int imx412_stop_streaming(struct imx412 *imx412)
-{
- return imx412_write_reg(imx412, IMX412_REG_MODE_SELECT,
- 1, IMX412_MODE_STANDBY);
-}
-
-static int imx412_set_stream(struct v4l2_subdev *sd, int enable)
+static int imx412_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
{
struct imx412 *imx412 = to_imx412(sd);
int ret;
- mutex_lock(&imx412->mutex);
+ ret = cci_write(imx412->cci, IMX412_REG_MODE_SELECT,
+ IMX412_MODE_STANDBY, NULL);
- if (enable) {
- ret = pm_runtime_resume_and_get(imx412->dev);
- if (ret)
- goto error_unlock;
-
- ret = imx412_start_streaming(imx412);
- if (ret)
- goto error_power_off;
- } else {
- imx412_stop_streaming(imx412);
- pm_runtime_put(imx412->dev);
- }
-
- mutex_unlock(&imx412->mutex);
-
- return 0;
+ if (ret)
+ dev_err(imx412->dev, "failed to set stream off\n");
-error_power_off:
pm_runtime_put(imx412->dev);
-error_unlock:
- mutex_unlock(&imx412->mutex);
- return ret;
+ return 0;
}
/**
@@ -830,16 +716,18 @@ error_unlock:
static int imx412_detect(struct imx412 *imx412)
{
int ret;
- u32 val;
+ u64 val;
- ret = imx412_read_reg(imx412, IMX412_REG_ID, 2, &val);
+ ret = cci_read(imx412->cci, IMX412_REG_ID, &val, NULL);
if (ret)
- return ret;
+ return dev_err_probe(imx412->dev, ret,
+ "failed to read chip id %x\n",
+ IMX412_ID);
if (val != IMX412_ID) {
- dev_err(imx412->dev, "chip id mismatch: %x!=%x\n",
- IMX412_ID, val);
- return -ENXIO;
+ return dev_err_probe(imx412->dev, -ENODEV,
+ "chip id mismatch: %x!=%llx",
+ IMX412_ID, val);
}
return 0;
@@ -933,7 +821,7 @@ done_endpoint_free:
/* V4l2 subdevice ops */
static const struct v4l2_subdev_video_ops imx412_video_ops = {
- .s_stream = imx412_set_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops imx412_pad_ops = {
@@ -941,6 +829,8 @@ static const struct v4l2_subdev_pad_ops imx412_pad_ops = {
.enum_frame_size = imx412_enum_frame_size,
.get_fmt = imx412_get_pad_format,
.set_fmt = imx412_set_pad_format,
+ .enable_streams = imx412_enable_streams,
+ .disable_streams = imx412_disable_streams,
};
static const struct v4l2_subdev_ops imx412_subdev_ops = {
@@ -1021,9 +911,6 @@ static int imx412_init_controls(struct imx412 *imx412)
if (ret)
return ret;
- /* Serialize controls with sensor device */
- ctrl_hdlr->lock = &imx412->mutex;
-
/* Initialize exposure and gain */
lpfr = mode->vblank + mode->height;
imx412->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
@@ -1104,6 +991,11 @@ static int imx412_probe(struct i2c_client *client)
if (!name)
return -ENODEV;
+ imx412->cci = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx412->cci))
+ return dev_err_probe(imx412->dev, PTR_ERR(imx412->cci),
+ "Failed to init CCI\n");
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx412->sd, client, &imx412_subdev_ops);
imx412->sd.internal_ops = &imx412_internal_ops;
@@ -1114,13 +1006,10 @@ static int imx412_probe(struct i2c_client *client)
return ret;
}
- mutex_init(&imx412->mutex);
-
ret = imx412_power_on(imx412->dev);
- if (ret) {
- dev_err(imx412->dev, "failed to power-on the sensor\n");
- goto error_mutex_destroy;
- }
+ if (ret)
+ return dev_err_probe(imx412->dev, ret,
+ "failed to power-on the sensor\n");
/* Check module identity */
ret = imx412_detect(imx412);
@@ -1153,27 +1042,37 @@ static int imx412_probe(struct i2c_client *client)
goto error_handler_free;
}
- ret = v4l2_async_register_subdev_sensor(&imx412->sd);
+ imx412->sd.state_lock = imx412->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&imx412->sd);
if (ret < 0) {
- dev_err(imx412->dev,
- "failed to register async subdev: %d\n", ret);
+ dev_err_probe(imx412->dev, ret, "subdev init error\n");
goto error_media_entity;
}
pm_runtime_set_active(imx412->dev);
pm_runtime_enable(imx412->dev);
+
+ ret = v4l2_async_register_subdev_sensor(&imx412->sd);
+ if (ret < 0) {
+ dev_err_probe(imx412->dev, ret,
+ "failed to register sub-device\n");
+ goto error_subdev_cleanup;
+ }
+
pm_runtime_idle(imx412->dev);
return 0;
+error_subdev_cleanup:
+ v4l2_subdev_cleanup(&imx412->sd);
+ pm_runtime_disable(imx412->dev);
+ pm_runtime_set_suspended(imx412->dev);
error_media_entity:
media_entity_cleanup(&imx412->sd.entity);
error_handler_free:
v4l2_ctrl_handler_free(imx412->sd.ctrl_handler);
error_power_off:
imx412_power_off(imx412->dev);
-error_mutex_destroy:
- mutex_destroy(&imx412->mutex);
return ret;
}
@@ -1181,9 +1080,9 @@ error_mutex_destroy:
static void imx412_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct imx412 *imx412 = to_imx412(sd);
v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
@@ -1191,8 +1090,6 @@ static void imx412_remove(struct i2c_client *client)
if (!pm_runtime_status_suspended(&client->dev))
imx412_power_off(&client->dev);
pm_runtime_set_suspended(&client->dev);
-
- mutex_destroy(&imx412->mutex);
}
static const struct dev_pm_ops imx412_pm_ops = {
diff --git a/drivers/media/i2c/imx471.c b/drivers/media/i2c/imx471.c
new file mode 100644
index 000000000000..6d358b11e96d
--- /dev/null
+++ b/drivers/media/i2c/imx471.c
@@ -0,0 +1,957 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * imx471.c - imx471 sensor driver
+ *
+ * Copyright (C) 2025 Intel Corporation
+ * Copyright (C) 2026 Kate Hsuan <hpa@redhat.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-fwnode.h>
+
+#define IMX471_REG_MODE_SELECT CCI_REG8(0x0100)
+#define IMX471_MODE_STANDBY 0x00
+#define IMX471_MODE_STREAMING 0x01
+
+/* Chip ID */
+#define IMX471_REG_CHIP_ID CCI_REG16(0x0016)
+#define IMX471_CHIP_ID 0x0471
+
+/* V_TIMING internal */
+#define IMX471_REG_FLL CCI_REG16(0x0340)
+#define IMX471_FLL_MAX 0xffff
+
+/* Exposure control */
+#define IMX471_REG_EXPOSURE CCI_REG16(0x0202)
+#define IMX471_EXPOSURE_MIN 1
+#define IMX471_EXPOSURE_STEP 1
+#define IMX471_EXPOSURE_DEFAULT 1270
+
+/* Default exposure margin */
+#define IMX471_EXPOSURE_MARGIN 18
+
+/* Analog gain control */
+#define IMX471_REG_ANALOG_GAIN CCI_REG16(0x0204)
+#define IMX471_ANA_GAIN_MIN 0
+#define IMX471_ANA_GAIN_MAX 800
+#define IMX471_ANA_GAIN_STEP 1
+#define IMX471_ANA_GAIN_DEFAULT 0
+
+/* Digital gain control */
+#define IMX471_REG_DPGA_USE_GLOBAL_GAIN CCI_REG16(0x3ff9)
+#define IMX471_REG_DIG_GAIN_GLOBAL CCI_REG16(0x020e)
+#define IMX471_DGTL_GAIN_MIN 256
+#define IMX471_DGTL_GAIN_MAX 4095
+#define IMX471_DGTL_GAIN_STEP 1
+#define IMX471_DGTL_GAIN_DEFAULT 256
+
+/* HFLIP and VFLIP control */
+#define IMX471_REG_ORIENTATION CCI_REG8(0x0101)
+
+/* Test Pattern Control */
+#define IMX471_REG_TEST_PATTERN CCI_REG8(0x0600)
+
+/* default link frequency and external clock */
+#define IMX471_LINK_FREQ_DEFAULT 200000000LL
+#define IMX471_EXT_CLK 19200000
+
+/* PLL */
+#define IMX471_REG_VTPXCK_DIV CCI_REG8(0x0301)
+#define IMX471_REG_VTSYCK_DIV CCI_REG8(0x0303)
+#define IMX471_REG_PREPLLCK_VT_DIV CCI_REG8(0x0305)
+#define IMX471_REG_PLL_VT_MPY CCI_REG16(0x0306)
+#define IMX471_REG_OPPXCK_DIV CCI_REG8(0x0309)
+#define IMX471_REG_OPSYCK_DIV CCI_REG8(0x030b)
+#define IMX471_REG_PLL_MULT_DRIV CCI_REG8(0x0310)
+#define IMX471_PLL_SINGLE 0
+#define IMX471_PLL_DUAL 1
+
+/* IMX471 native and active pixel array size */
+#define IMX471_NATIVE_WIDTH 4672
+#define IMX471_NATIVE_HEIGHT 3512
+#define IMX471_PIXEL_ARRAY_LEFT 8
+#define IMX471_PIXEL_ARRAY_TOP 8
+#define IMX471_PIXEL_ARRAY_WIDTH 4656
+#define IMX471_PIXEL_ARRAY_HEIGHT 3496
+
+#define IMX471_REG_EXCK_FREQ CCI_REG16(0x0136)
+
+#define IMX471_REG_CSI_DATA_FORMAT CCI_REG16(0x0112)
+#define IMX471_CSI_DATA_FORMAT_RAW10 0x0a0a
+
+#define IMX471_REG_CSI_LANE_MODE CCI_REG8(0x0114)
+#define IMX471_CSI_2_LANE_MODE 1
+#define IMX471_CSI_4_LANE_MODE 3
+
+#define IMX471_REG_X_ADD_STA CCI_REG16(0x0344)
+#define IMX471_REG_Y_ADD_STA CCI_REG16(0x0346)
+#define IMX471_REG_X_ADD_END CCI_REG16(0x0348)
+#define IMX471_REG_Y_ADD_END CCI_REG16(0x034a)
+#define IMX471_REG_X_OUTPUT_SIZE CCI_REG16(0x034c)
+#define IMX471_REG_Y_OUTPUT_SIZE CCI_REG16(0x034e)
+#define IMX471_REG_X_EVEN_INC CCI_REG8(0x0381)
+#define IMX471_REG_X_ODD_INC CCI_REG8(0x0383)
+#define IMX471_REG_Y_EVEN_INC CCI_REG8(0x0385)
+#define IMX471_REG_Y_ODD_INC CCI_REG8(0x0387)
+
+#define IMX471_REG_DIG_CROP_X_OFFSET CCI_REG16(0x0408)
+#define IMX471_REG_DIG_CROP_Y_OFFSET CCI_REG16(0x040a)
+#define IMX471_REG_DIG_CROP_WIDTH CCI_REG16(0x040c)
+#define IMX471_REG_DIG_CROP_HEIGHT CCI_REG16(0x040e)
+
+/* Binning mode */
+#define IMX471_REG_BINNING_MODE CCI_REG8(0x0900)
+#define IMX471_BINNING_NONE 0
+#define IMX471_BINNING_ENABLE 1
+#define IMX471_REG_BINNING_TYPE CCI_REG8(0x0901)
+#define IMX471_REG_BINNING_WEIGHTING CCI_REG8(0x0902)
+
+#define to_imx471(_sd) container_of_const(_sd, struct imx471, sd)
+
+static const char * const imx471_supply_name[] = {
+ "vana",
+};
+
+struct imx471_mode {
+ u32 width;
+ u32 height;
+
+ /* V-timing */
+ u32 fll_def;
+ u32 fll_min;
+
+ /* H-timing */
+ u32 llp;
+
+ const struct cci_reg_sequence *default_mode_regs;
+ unsigned int default_mode_regs_length;
+};
+
+struct imx471 {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *exposure;
+
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(imx471_supply_name)];
+ struct clk *img_clk;
+
+ struct device *dev;
+ struct regmap *regmap;
+};
+
+static const struct cci_reg_sequence imx471_global_regs[] = {
+ { IMX471_REG_EXCK_FREQ, 0x1333 },
+ { CCI_REG8(0x3c7e), 0x08 },
+ { CCI_REG8(0x3c7f), 0x05 },
+ { CCI_REG8(0x3e35), 0x00 },
+ { CCI_REG8(0x3e36), 0x00 },
+ { CCI_REG8(0x3e37), 0x00 },
+ { CCI_REG8(0x3f7f), 0x01 },
+ { CCI_REG8(0x4431), 0x04 },
+ { CCI_REG8(0x531c), 0x01 },
+ { CCI_REG8(0x531d), 0x02 },
+ { CCI_REG8(0x531e), 0x04 },
+ { CCI_REG8(0x5928), 0x00 },
+ { CCI_REG8(0x5929), 0x2f },
+ { CCI_REG8(0x592a), 0x00 },
+ { CCI_REG8(0x592b), 0x85 },
+ { CCI_REG8(0x592c), 0x00 },
+ { CCI_REG8(0x592d), 0x32 },
+ { CCI_REG8(0x592e), 0x00 },
+ { CCI_REG8(0x592f), 0x88 },
+ { CCI_REG8(0x5930), 0x00 },
+ { CCI_REG8(0x5931), 0x3d },
+ { CCI_REG8(0x5932), 0x00 },
+ { CCI_REG8(0x5933), 0x93 },
+ { CCI_REG8(0x5938), 0x00 },
+ { CCI_REG8(0x5939), 0x24 },
+ { CCI_REG8(0x593a), 0x00 },
+ { CCI_REG8(0x593b), 0x7a },
+ { CCI_REG8(0x593c), 0x00 },
+ { CCI_REG8(0x593d), 0x24 },
+ { CCI_REG8(0x593e), 0x00 },
+ { CCI_REG8(0x593f), 0x7a },
+ { CCI_REG8(0x5940), 0x00 },
+ { CCI_REG8(0x5941), 0x2f },
+ { CCI_REG8(0x5942), 0x00 },
+ { CCI_REG8(0x5943), 0x85 },
+ { CCI_REG8(0x5f0e), 0x6e },
+ { CCI_REG8(0x5f11), 0xc6 },
+ { CCI_REG8(0x5f17), 0x5e },
+ { CCI_REG8(0x7990), 0x01 },
+ { CCI_REG8(0x7993), 0x5d },
+ { CCI_REG8(0x7994), 0x5d },
+ { CCI_REG8(0x7995), 0xa1 },
+ { CCI_REG8(0x799a), 0x01 },
+ { CCI_REG8(0x799d), 0x00 },
+ { CCI_REG8(0x8169), 0x01 },
+ { CCI_REG8(0x8359), 0x01 },
+ { CCI_REG8(0x9302), 0x1e },
+ { CCI_REG8(0x9306), 0x1f },
+ { CCI_REG8(0x930a), 0x26 },
+ { CCI_REG8(0x930e), 0x23 },
+ { CCI_REG8(0x9312), 0x23 },
+ { CCI_REG8(0x9316), 0x2c },
+ { CCI_REG8(0x9317), 0x19 },
+ { CCI_REG8(0xb046), 0x01 },
+ { CCI_REG8(0xb048), 0x01 },
+};
+
+static const struct cci_reg_sequence mode_1928x1088_regs[] = {
+ { IMX471_REG_CSI_DATA_FORMAT, IMX471_CSI_DATA_FORMAT_RAW10 },
+ { IMX471_REG_CSI_LANE_MODE, IMX471_CSI_4_LANE_MODE },
+ { IMX471_REG_X_ADD_STA, 8 },
+ { IMX471_REG_Y_ADD_STA, 408 },
+ { IMX471_REG_X_ADD_END, 4647 },
+ { IMX471_REG_Y_ADD_END, 3051 },
+ { IMX471_REG_X_EVEN_INC, 1 },
+ { IMX471_REG_X_ODD_INC, 1 },
+ { IMX471_REG_Y_EVEN_INC, 1 },
+ { IMX471_REG_Y_ODD_INC, 1 },
+ { IMX471_REG_BINNING_MODE, IMX471_BINNING_ENABLE },
+ { IMX471_REG_BINNING_TYPE, 0x22 },
+ { IMX471_REG_BINNING_WEIGHTING, 0x08 },
+ { IMX471_REG_DIG_CROP_X_OFFSET, 208 },
+ { IMX471_REG_DIG_CROP_Y_OFFSET, 108 },
+ { IMX471_REG_DIG_CROP_WIDTH, 1928 },
+ { IMX471_REG_DIG_CROP_HEIGHT, 1088 },
+ { IMX471_REG_X_OUTPUT_SIZE, 1928 },
+ { IMX471_REG_Y_OUTPUT_SIZE, 1088 },
+ { IMX471_REG_VTPXCK_DIV, 0x06 },
+ { IMX471_REG_VTSYCK_DIV, 0x02 },
+ { IMX471_REG_PREPLLCK_VT_DIV, 0x02 },
+ { IMX471_REG_PLL_VT_MPY, 0x0079 },
+ { IMX471_REG_OPSYCK_DIV, 0x01 },
+ { CCI_REG8(0x030d), 0x02 },
+ { CCI_REG8(0x030e), 0x00 },
+ { CCI_REG8(0x030f), 0x53 },
+ { IMX471_REG_PLL_MULT_DRIV, IMX471_PLL_DUAL },
+ { CCI_REG8(0x3f4c), 0x81 },
+ { CCI_REG8(0x3f4d), 0x81 },
+ { CCI_REG8(0x3f78), 0x01 },
+ { CCI_REG8(0x3f79), 0x31 },
+ { CCI_REG8(0x3ffe), 0x00 },
+ { CCI_REG8(0x3fff), 0x8a },
+ { CCI_REG8(0x5f0a), 0xb6 },
+};
+
+static const char * const imx471_test_pattern_menu[] = {
+ "Disabled",
+ "Solid Colour",
+ "Eight Vertical Colour Bars",
+ "Colour Bars With Fade to Grey",
+ "Pseudorandom Sequence (PN9)",
+};
+
+static const s64 link_freq_menu_items[] = {
+ IMX471_LINK_FREQ_DEFAULT,
+};
+
+/*
+ * The Bayer formats for the flipping.
+ * - no flip
+ * - h flip
+ * - v flip
+ * - h and v flips
+ */
+static const u32 imx471_hv_flips_bayer_order[] = {
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+ MEDIA_BUS_FMT_SGRBG10_1X10,
+ MEDIA_BUS_FMT_SGBRG10_1X10,
+ MEDIA_BUS_FMT_SBGGR10_1X10,
+};
+
+static const struct imx471_mode imx471_modes[] = {
+ {
+ .width = 1928,
+ .height = 1088,
+ .fll_def = 1308,
+ .fll_min = 1308,
+ .llp = 2328,
+ .default_mode_regs = mode_1928x1088_regs,
+ .default_mode_regs_length = ARRAY_SIZE(mode_1928x1088_regs),
+ },
+};
+
+static int imx471_get_regulators(struct device *dev, struct imx471 *sensor)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(imx471_supply_name); i++)
+ sensor->supplies[i].supply = imx471_supply_name[i];
+
+ return devm_regulator_bulk_get(dev, ARRAY_SIZE(imx471_supply_name),
+ sensor->supplies);
+}
+
+static int imx471_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct imx471 *sensor = container_of_const(ctrl->handler,
+ struct imx471,
+ ctrl_handler);
+ struct v4l2_subdev_state *state =
+ v4l2_subdev_get_locked_active_state(&sensor->sd);
+ const struct v4l2_mbus_framefmt *format =
+ v4l2_subdev_state_get_format(state, 0);
+ int ret;
+
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ s64 exposure_max = format->height + ctrl->val -
+ IMX471_EXPOSURE_MARGIN;
+ ret = __v4l2_ctrl_modify_range(sensor->exposure,
+ sensor->exposure->minimum,
+ exposure_max,
+ sensor->exposure->step,
+ exposure_max);
+ if (ret)
+ return ret;
+ }
+
+ if (!pm_runtime_get_if_in_use(sensor->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = cci_write(sensor->regmap, IMX471_REG_ANALOG_GAIN,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_DIGITAL_GAIN:
+ ret = cci_write(sensor->regmap, IMX471_REG_DIG_GAIN_GLOBAL,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_EXPOSURE:
+ ret = cci_write(sensor->regmap, IMX471_REG_EXPOSURE,
+ ctrl->val, &ret);
+ break;
+ case V4L2_CID_VBLANK:
+ /* Update FLL that meets expected vertical blanking */
+ ret = cci_write(sensor->regmap, IMX471_REG_FLL,
+ format->height + ctrl->val, &ret);
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = cci_write(sensor->regmap, IMX471_REG_TEST_PATTERN,
+ ctrl->val, NULL);
+ break;
+ case V4L2_CID_HFLIP:
+ case V4L2_CID_VFLIP:
+ ret = cci_write(sensor->regmap, IMX471_REG_ORIENTATION,
+ sensor->hflip->val | sensor->vflip->val << 1,
+ NULL);
+ break;
+ default:
+ ret = -EINVAL;
+ dev_err(sensor->dev, "ctrl(id:0x%x,val:0x%x) is not handled\n",
+ ctrl->id, ctrl->val);
+ break;
+ }
+
+ pm_runtime_put(sensor->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops imx471_ctrl_ops = {
+ .s_ctrl = imx471_set_ctrl,
+};
+
+static u32 imx471_get_format_code(struct imx471 *sensor)
+{
+ unsigned int i;
+
+ i = (sensor->vflip->val ? 2 : 0) | (sensor->hflip->val ? 1 : 0);
+
+ return imx471_hv_flips_bayer_order[i];
+}
+
+static int imx471_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct imx471 *sensor = to_imx471(sd);
+
+ if (code->index >= (ARRAY_SIZE(imx471_hv_flips_bayer_order) / 4))
+ return -EINVAL;
+
+ code->code = imx471_get_format_code(sensor);
+
+ return 0;
+}
+
+static int imx471_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ARRAY_SIZE(imx471_modes))
+ return -EINVAL;
+
+ fse->min_width = imx471_modes[fse->index].width;
+ fse->max_width = fse->min_width;
+ fse->min_height = imx471_modes[fse->index].height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static void imx471_update_pad_format(struct imx471 *sensor,
+ const struct imx471_mode *mode,
+ struct v4l2_subdev_format *fmt)
+{
+ fmt->format.code = imx471_get_format_code(sensor);
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.field = V4L2_FIELD_NONE;
+}
+
+static int imx471_set_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *fmt)
+{
+ struct imx471 *sensor = to_imx471(sd);
+ const struct imx471_mode *mode;
+ int h_blank, ret;
+
+ mode = v4l2_find_nearest_size(imx471_modes, ARRAY_SIZE(imx471_modes),
+ width, height, fmt->format.width,
+ fmt->format.height);
+
+ imx471_update_pad_format(sensor, mode, fmt);
+
+ *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+ return 0;
+
+ if (media_entity_is_streaming(&sensor->sd.entity))
+ return -EBUSY;
+
+ ret = __v4l2_ctrl_modify_range(sensor->vblank,
+ mode->fll_min - mode->height,
+ IMX471_FLL_MAX - mode->height,
+ 1,
+ mode->fll_def - mode->height);
+ if (ret)
+ return ret;
+
+ h_blank = mode->llp - mode->width;
+ /*
+ * Currently hblank is not changeable.
+ * So FPS control is done only by vblank.
+ */
+ return __v4l2_ctrl_modify_range(sensor->hblank, h_blank,
+ h_blank, 1, h_blank);
+}
+
+static int imx471_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad);
+ break;
+
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = IMX471_NATIVE_WIDTH;
+ sel->r.height = IMX471_NATIVE_HEIGHT;
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = IMX471_PIXEL_ARRAY_TOP;
+ sel->r.left = IMX471_PIXEL_ARRAY_LEFT;
+ sel->r.width = IMX471_PIXEL_ARRAY_WIDTH;
+ sel->r.height = IMX471_PIXEL_ARRAY_HEIGHT;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int imx471_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+{
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .format = {
+ .code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .width = imx471_modes[0].width,
+ .height = imx471_modes[0].height,
+ },
+ };
+
+ return imx471_set_pad_format(sd, sd_state, &fmt);
+}
+
+static int imx471_identify_module(struct imx471 *sensor)
+{
+ int ret;
+ u64 val;
+
+ ret = cci_read(sensor->regmap, IMX471_REG_CHIP_ID, &val, NULL);
+ if (ret)
+ return dev_err_probe(sensor->dev, ret,
+ "failed to read chip id\n");
+
+ if (val != IMX471_CHIP_ID)
+ return dev_err_probe(sensor->dev, -EIO,
+ "chip id mismatch: %x!=%llx\n",
+ IMX471_CHIP_ID, val);
+
+ return 0;
+}
+
+static int imx471_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct imx471 *sensor = to_imx471(sd);
+
+ clk_disable_unprepare(sensor->img_clk);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
+
+ regulator_bulk_disable(ARRAY_SIZE(imx471_supply_name),
+ sensor->supplies);
+
+ return 0;
+}
+
+static int imx471_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct imx471 *sensor = to_imx471(sd);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(imx471_supply_name),
+ sensor->supplies);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable regulators: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sensor->img_clk);
+ if (ret < 0) {
+ regulator_bulk_disable(ARRAY_SIZE(imx471_supply_name),
+ sensor->supplies);
+ dev_err(dev, "failed to enable imaging clock: %d\n", ret);
+ return ret;
+ }
+
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
+
+ usleep_range(10000, 15000);
+
+ return 0;
+}
+
+static int imx471_enable_stream(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct imx471 *sensor = to_imx471(sd);
+ const struct imx471_mode *mode;
+ struct v4l2_mbus_framefmt *fmt;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(sensor->dev);
+ if (ret)
+ return ret;
+
+ ret = imx471_identify_module(sensor);
+ if (ret)
+ goto error_powerdown;
+
+ ret = cci_multi_reg_write(sensor->regmap, imx471_global_regs,
+ ARRAY_SIZE(imx471_global_regs), NULL);
+ if (ret) {
+ dev_err(sensor->dev, "failed to set global settings: %d\n",
+ ret);
+ goto error_powerdown;
+ }
+
+ fmt = v4l2_subdev_state_get_format(state, 0);
+ mode = v4l2_find_nearest_size(imx471_modes, ARRAY_SIZE(imx471_modes),
+ width, height, fmt->width, fmt->height);
+
+ ret = cci_multi_reg_write(sensor->regmap, mode->default_mode_regs,
+ mode->default_mode_regs_length, NULL);
+ if (ret) {
+ dev_err(sensor->dev, "failed to set mode: %d\n", ret);
+ goto error_powerdown;
+ }
+
+ ret = cci_write(sensor->regmap, IMX471_REG_DPGA_USE_GLOBAL_GAIN, 1,
+ NULL);
+ if (ret)
+ goto error_powerdown;
+
+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrl_handler);
+ if (ret)
+ goto error_powerdown;
+
+ ret = cci_write(sensor->regmap, IMX471_REG_MODE_SELECT,
+ IMX471_MODE_STREAMING, NULL);
+ if (ret)
+ goto error_powerdown;
+
+ __v4l2_ctrl_grab(sensor->vflip, true);
+ __v4l2_ctrl_grab(sensor->hflip, true);
+
+ return ret;
+
+error_powerdown:
+ pm_runtime_put(sensor->dev);
+
+ return ret;
+}
+
+static int imx471_disable_stream(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct imx471 *sensor = to_imx471(sd);
+ int ret;
+
+ ret = cci_write(sensor->regmap, IMX471_REG_MODE_SELECT,
+ IMX471_MODE_STANDBY, NULL);
+ pm_runtime_put(sensor->dev);
+
+ if (ret)
+ dev_err(sensor->dev,
+ "failed to disable stream with return value: %d\n",
+ ret);
+
+ __v4l2_ctrl_grab(sensor->vflip, false);
+ __v4l2_ctrl_grab(sensor->hflip, false);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops imx471_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops imx471_pad_ops = {
+ .enum_mbus_code = imx471_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = imx471_set_pad_format,
+ .get_selection = imx471_get_selection,
+ .enum_frame_size = imx471_enum_frame_size,
+ .enable_streams = imx471_enable_stream,
+ .disable_streams = imx471_disable_stream,
+};
+
+static const struct v4l2_subdev_ops imx471_subdev_ops = {
+ .video = &imx471_video_ops,
+ .pad = &imx471_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops imx471_internal_ops = {
+ .init_state = imx471_init_state,
+};
+
+static int imx471_init_controls(struct imx471 *sensor)
+{
+ const struct imx471_mode *mode = &imx471_modes[0];
+ struct v4l2_fwnode_device_properties props;
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ struct v4l2_ctrl *link_freq;
+ s64 exposure_max, hblank;
+ u64 pixel_rate;
+ int ret;
+
+ ret = v4l2_fwnode_device_parse(sensor->dev, &props);
+ if (ret) {
+ dev_err(sensor->dev, "failed to parse fwnode: %d\n", ret);
+ return ret;
+ }
+
+ ctrl_hdlr = &sensor->ctrl_handler;
+ v4l2_ctrl_handler_init(ctrl_hdlr, 12);
+
+ v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx471_ctrl_ops, &props);
+
+ link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
+ &imx471_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ ARRAY_SIZE(link_freq_menu_items) - 1,
+ 0,
+ link_freq_menu_items);
+
+ /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
+ pixel_rate = div_u64(IMX471_LINK_FREQ_DEFAULT * 2 * 4, 10);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, pixel_rate,
+ pixel_rate, 1, pixel_rate);
+
+ sensor->vblank = v4l2_ctrl_new_std(ctrl_hdlr,
+ &imx471_ctrl_ops,
+ V4L2_CID_VBLANK,
+ mode->fll_min - mode->height,
+ IMX471_FLL_MAX - mode->height,
+ 1,
+ mode->fll_def - mode->height);
+
+ hblank = mode->llp - mode->width;
+ sensor->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_HBLANK, hblank, hblank,
+ 1, hblank);
+
+ /* fll >= exposure time + adjust parameter (default value is 18) */
+ exposure_max = mode->fll_def - IMX471_EXPOSURE_MARGIN;
+ sensor->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ IMX471_EXPOSURE_MIN, exposure_max,
+ IMX471_EXPOSURE_STEP,
+ IMX471_EXPOSURE_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ IMX471_ANA_GAIN_MIN, IMX471_ANA_GAIN_MAX,
+ IMX471_ANA_GAIN_STEP, IMX471_ANA_GAIN_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+ IMX471_DGTL_GAIN_MIN, IMX471_DGTL_GAIN_MAX,
+ IMX471_DGTL_GAIN_STEP, IMX471_DGTL_GAIN_DEFAULT);
+
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(imx471_test_pattern_menu) - 1,
+ 0, 0, imx471_test_pattern_menu);
+
+ sensor->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+ sensor->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx471_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ if (ctrl_hdlr->error) {
+ dev_err(sensor->dev, "%s control init failed: %d\n",
+ __func__, ctrl_hdlr->error);
+ goto error;
+ }
+
+ link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ sensor->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+ sensor->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+ sensor->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+
+error:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+
+ return ctrl_hdlr->error;
+}
+
+static int imx471_check_hwcfg(struct imx471 *sensor)
+{
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY,
+ };
+ struct fwnode_handle *ep, *fwnode = dev_fwnode(sensor->dev);
+ unsigned long link_freq_bitmap;
+ struct clk *clk;
+ int ret;
+
+ clk = devm_v4l2_sensor_clk_get(sensor->dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(sensor->dev, PTR_ERR(clk),
+ "can't get clock frequency\n");
+
+ if (clk_get_rate(clk) != IMX471_EXT_CLK)
+ return dev_err_probe(sensor->dev, -EINVAL,
+ "external clock %lu is not supported\n",
+ clk_get_rate(clk));
+
+ ep = fwnode_graph_get_endpoint_by_id(fwnode, 0, 0, 0);
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return dev_err_probe(sensor->dev, ret,
+ "parsing endpoint failed\n");
+
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+ ret = dev_err_probe(sensor->dev, -EINVAL,
+ "number of CSI2 data lanes %u is not supported\n",
+ bus_cfg.bus.mipi_csi2.num_data_lanes);
+ goto done_endpoint_free;
+ }
+
+ ret = v4l2_link_freq_to_bitmap(sensor->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items),
+ &link_freq_bitmap);
+
+done_endpoint_free:
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+}
+
+static int imx471_probe(struct i2c_client *client)
+{
+ struct imx471 *sensor;
+ int ret;
+
+ sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+ return dev_err_probe(&client->dev, -ENOMEM,
+ "failed to allocate memory\n");
+
+ sensor->dev = &client->dev;
+
+ ret = imx471_check_hwcfg(sensor);
+ if (ret)
+ return dev_err_probe(sensor->dev, ret,
+ "failed to check hwcfg: %d\n", ret);
+
+ ret = imx471_get_regulators(sensor->dev, sensor);
+ if (ret)
+ return dev_err_probe(sensor->dev, ret,
+ "failed to get regulators\n");
+
+ sensor->reset_gpio = devm_gpiod_get_optional(sensor->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(sensor->reset_gpio))
+ return dev_err_probe(sensor->dev, PTR_ERR(sensor->reset_gpio),
+ "failed to get reset gpio\n");
+
+ sensor->img_clk = devm_v4l2_sensor_clk_get(sensor->dev, NULL);
+ if (IS_ERR(sensor->img_clk))
+ return dev_err_probe(sensor->dev, PTR_ERR(sensor->img_clk),
+ "failed to get imaging clock\n");
+
+ v4l2_i2c_subdev_init(&sensor->sd, client, &imx471_subdev_ops);
+
+ sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(sensor->regmap))
+ return dev_err_probe(sensor->dev, PTR_ERR(sensor->regmap),
+ "failed to initialize CCI\n");
+
+ ret = imx471_power_on(sensor->dev);
+ if (ret)
+ return dev_err_probe(sensor->dev, ret,
+ "failed to power on\n");
+
+ ret = imx471_identify_module(sensor);
+ if (ret) {
+ dev_err_probe(sensor->dev, ret, "failed to find sensor: %d\n",
+ ret);
+ goto error_power_off;
+ }
+
+ ret = imx471_init_controls(sensor);
+ if (ret) {
+ dev_err_probe(sensor->dev, ret, "failed to init controls: %d\n",
+ ret);
+ goto error_power_off;
+ }
+
+ sensor->sd.internal_ops = &imx471_internal_ops;
+ 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 = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
+ if (ret) {
+ dev_err_probe(sensor->dev, ret,
+ "failed to init entity pads: %d\n", ret);
+ goto error_v4l2_ctrl_handler_free;
+ }
+
+ sensor->sd.state_lock = sensor->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&sensor->sd);
+ if (ret < 0) {
+ dev_err_probe(sensor->dev, ret, "failed to init subdev: %d\n",
+ ret);
+ goto error_media_entity_pm;
+ }
+
+ pm_runtime_set_active(sensor->dev);
+ pm_runtime_enable(sensor->dev);
+
+ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
+ if (ret < 0)
+ goto error_v4l2_subdev_cleanup;
+
+ pm_runtime_idle(sensor->dev);
+
+ return 0;
+
+error_v4l2_subdev_cleanup:
+ pm_runtime_disable(sensor->dev);
+ pm_runtime_set_suspended(sensor->dev);
+ v4l2_subdev_cleanup(&sensor->sd);
+
+error_media_entity_pm:
+ media_entity_cleanup(&sensor->sd.entity);
+
+error_v4l2_ctrl_handler_free:
+ v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
+
+error_power_off:
+ imx471_power_off(sensor->dev);
+
+ return ret;
+}
+
+static void imx471_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+
+ pm_runtime_disable(&client->dev);
+
+ if (!pm_runtime_status_suspended(&client->dev)) {
+ imx471_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ }
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx471_pm_ops, imx471_power_off,
+ imx471_power_on, NULL);
+
+static const struct acpi_device_id imx471_acpi_ids[] __maybe_unused = {
+ { "SONY471A" },
+ { "TBE20A0" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(acpi, imx471_acpi_ids);
+
+static struct i2c_driver imx471_i2c_driver = {
+ .driver = {
+ .name = "imx471",
+ .acpi_match_table = ACPI_PTR(imx471_acpi_ids),
+ .pm = pm_sleep_ptr(&imx471_pm_ops),
+ },
+ .probe = imx471_probe,
+ .remove = imx471_remove,
+};
+module_i2c_driver(imx471_i2c_driver);
+
+MODULE_AUTHOR("Jimmy Su <jimmy.su@intel.com>");
+MODULE_AUTHOR("Serin Yeh <serin.yeh@intel.com>");
+MODULE_AUTHOR("Kate Hsuan <hpa@redhat.com>");
+MODULE_DESCRIPTION("Sony imx471 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/imx678.c b/drivers/media/i2c/imx678.c
new file mode 100644
index 000000000000..0efbf43d2fe6
--- /dev/null
+++ b/drivers/media/i2c/imx678.c
@@ -0,0 +1,1447 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 driver for Sony IMX678
+ *
+ * Diagonal 8.86 mm (Type 1/1.8) CMOS image sensor with 8.40 M effective pixels.
+ *
+ * Copyright (C) 2026 Ideas On Board Oy.
+ *
+ * Based on Sony IMX678 driver prepared by Will Whang & Soho Enterprise Ltd.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mediabus.h>
+#include <media/v4l2-rect.h>
+#include <media/v4l2-subdev.h>
+
+/* Standby or streaming mode */
+#define IMX678_REG_MODE_SELECT CCI_REG8(0x3000)
+#define IMX678_MODE_STANDBY 0x01
+#define IMX678_MODE_STREAMING 0x00
+#define IMX678_STREAM_DELAY_US 25000
+#define IMX678_STREAM_DELAY_RANGE_US 1000
+
+/* XVS/XHS sync control */
+#define IMX678_REG_XMSTA CCI_REG8(0x3002)
+#define IMX678_REG_XXS_DRV CCI_REG8(0x30a6)
+#define IMX678_REG_XXS_OUTSEL CCI_REG8(0x30a4)
+
+/* Clk selection */
+#define IMX678_REG_INCK_SEL CCI_REG8(0x3014)
+
+/* Link Speed */
+#define IMX678_REG_DATARATE_SEL CCI_REG8(0x3015)
+
+/* Lane Count */
+#define IMX678_REG_LANEMODE CCI_REG8(0x3040)
+
+/*
+ * The internal readout clock runs at 74.25 MHz. In one cycle the AD reads 8
+ * pixels, thus giving us a rate of 74.25 * 8 = 594 MPix/s
+ */
+#define IMX678_PIXEL_RATE 594000000
+#define IMX678_PIX_PER_CLK 8
+
+/* VMAX - Frame Length in Lines */
+#define IMX678_REG_VMAX CCI_REG24_LE(0x3028)
+#define IMX678_VMAX_MAX 0xfffff
+#define IMX678_VMAX_DEFAULT 2250
+
+/* HMAX - Line Length in Cycles (8 Pixels) */
+#define IMX678_REG_HMAX CCI_REG16_LE(0x302c)
+#define IMX678_HMAX_MAX 0xffff
+
+/* SHR internal */
+#define IMX678_REG_SHR CCI_REG24_LE(0x3050)
+#define IMX678_SHR_MIN 8
+
+/* Exposure control */
+#define IMX678_EXPOSURE_MIN 2
+#define IMX678_EXPOSURE_STEP 1
+#define IMX678_EXPOSURE_DEFAULT 1000
+
+/*
+ * Analogue gain control
+ * Range is from 0 to 100 (0dB - 30dB) with 0.3dB step size
+ * Values from 101 to 240 are valid but correspond to additional digital gain
+ * (0.3dB - 42dB) so don't expose it to userspace
+ */
+#define IMX678_REG_GAIN CCI_REG16_LE(0x3070)
+#define IMX678_ANA_GAIN_MIN_NORMAL 0
+#define IMX678_ANA_GAIN_MAX_NORMAL 100
+#define IMX678_ANA_GAIN_STEP 1
+#define IMX678_ANA_GAIN_DEFAULT 0
+
+/* Crop */
+#define IMX678_REG_WINMODE CCI_REG8(0x3018)
+#define IMX678_REG_PIX_HST CCI_REG16_LE(0x303c)
+#define IMX678_REG_PIX_HWIDTH CCI_REG16_LE(0x303e)
+#define IMX678_REG_PIX_VST CCI_REG16_LE(0x3044)
+#define IMX678_REG_PIX_VWIDTH CCI_REG16_LE(0x3046)
+
+/* Flip */
+#define IMX678_REG_WINMODEH CCI_REG8(0x3020)
+#define IMX678_REG_WINMODEV CCI_REG8(0x3021)
+
+/* Sensor Identification */
+#define IMX678_REG_MONOCHROME CCI_REG8(0x4d18)
+#define IMX678_TYPE BIT(0)
+#define IMX678_REG_MODULE_ID CCI_REG16_LE(0x4d1c)
+#define IMX678_ID 0x02a6
+#define IMX678_MODULE_ID_DELAY 80000
+
+/* Common configuration registers */
+#define IMX678_REG_WDMODE CCI_REG8(0x301a)
+#define IMX678_REG_ADDMODE CCI_REG8(0x301b)
+#define IMX678_REG_THIN_V_EN CCI_REG8(0x301c)
+#define IMX678_REG_VCMODE CCI_REG8(0x301e)
+#define IMX678_REG_ADBIT CCI_REG8(0x3022)
+#define IMX678_REG_MDBIT CCI_REG8(0x3023)
+#define IMX678_REG_GAIN_PGC_FIDMD CCI_REG8(0x3400)
+
+/* Test pattern generator */
+#define IMX678_REG_TPG_EN_DUOUT CCI_REG8(0x30e0)
+#define IMX678_REG_TPG_PATSEL_DUOUT CCI_REG8(0x30e2)
+#define IMX678_TPG_ALL_000 0
+#define IMX678_TPG_ALL_FFF 1
+#define IMX678_TPG_ALL_555 2
+#define IMX678_TPG_ALL_AAA 3
+#define IMX678_TPG_TOG_555_AAA 4
+#define IMX678_TPG_TOG_AAA_555 5
+#define IMX678_TPG_TOG_000_555 6
+#define IMX678_TPG_TOG_555_000 7
+#define IMX678_TPG_TOG_000_FFF 8
+#define IMX678_TPG_TOG_FFF_000 9
+#define IMX678_TPG_H_COLOR_BARS 10
+#define IMX678_TPG_V_COLOR_BARS 11
+#define IMX678_REG_TPG_COLORWIDTH CCI_REG8(0x30e4)
+#define IMX678_TPG_COLORWIDTH_80PIX 0
+#define IMX678_TPG_COLORWIDTH_160PIX 1
+#define IMX678_TPG_COLORWIDTH_320PIX 2
+#define IMX678_TPG_COLORWIDTH_640PIX 3
+
+#define IMX678_REG_INTERFACE_SEL CCI_REG8(0x4e3c)
+#define IMX678_INTERFACE_2L_4L 0x07
+#define IMX678_INTERFACE_8L_2x4L 0x7f
+
+/* Minimum output resolution */
+#define IMX678_PIXEL_ARRAY_MIN_WIDTH 1040
+#define IMX678_PIXEL_ARRAY_MIN_HEIGHT 956
+
+/* Sensor windowing register alignment */
+#define IMX678_CROP_HWIDTH_ALIGN 16
+#define IMX678_CROP_VWIDTH_ALIGN 4
+#define IMX678_CROP_HST_ALIGN 4
+#define IMX678_CROP_VST_ALIGN 4
+
+/* Subdev pads */
+#define IMX678_SOURCE_PAD 0
+
+/* IMX678 native and active pixel array size. */
+static const struct v4l2_rect imx678_native_area = {
+ .top = 0,
+ .left = 0,
+ .width = 3857,
+ .height = 2201,
+};
+
+static const struct v4l2_rect imx678_active_area = {
+ .top = 20,
+ .left = 0,
+ .width = 3856,
+ .height = 2180,
+};
+
+enum imx678_type {
+ IMX678_COLOR = 0,
+ IMX678_MONOCHROME = 1,
+};
+
+struct imx678_model_info {
+ enum imx678_type type;
+ const u32 *codes;
+ unsigned int num_codes;
+};
+
+enum imx678_lanemode {
+ IMX678_LANEMODE_2L = 1,
+ IMX678_LANEMODE_4L = 3,
+};
+
+/* Link frequency setup (DDR: lane rate = 2 x link freq) */
+enum {
+ IMX678_LINK_FREQ_297MHZ,
+ IMX678_LINK_FREQ_360MHZ,
+ IMX678_LINK_FREQ_445MHZ,
+ IMX678_LINK_FREQ_594MHZ,
+ IMX678_LINK_FREQ_720MHZ,
+ IMX678_LINK_FREQ_891MHZ,
+ IMX678_LINK_FREQ_1039MHZ,
+ IMX678_LINK_FREQ_1188MHZ,
+};
+
+static const u8 link_freqs_reg_value[] = {
+ [IMX678_LINK_FREQ_297MHZ] = 0x07,
+ [IMX678_LINK_FREQ_360MHZ] = 0x06,
+ [IMX678_LINK_FREQ_445MHZ] = 0x05,
+ [IMX678_LINK_FREQ_594MHZ] = 0x04,
+ [IMX678_LINK_FREQ_720MHZ] = 0x03,
+ [IMX678_LINK_FREQ_891MHZ] = 0x02,
+ [IMX678_LINK_FREQ_1039MHZ] = 0x01,
+ [IMX678_LINK_FREQ_1188MHZ] = 0x00,
+};
+
+static const u64 link_freqs[] = {
+ [IMX678_LINK_FREQ_297MHZ] = 297000000,
+ [IMX678_LINK_FREQ_360MHZ] = 360000000,
+ [IMX678_LINK_FREQ_445MHZ] = 445500000,
+ [IMX678_LINK_FREQ_594MHZ] = 594000000,
+ [IMX678_LINK_FREQ_720MHZ] = 720000000,
+ [IMX678_LINK_FREQ_891MHZ] = 891000000,
+ [IMX678_LINK_FREQ_1039MHZ] = 1039500000,
+ [IMX678_LINK_FREQ_1188MHZ] = 1188000000,
+};
+
+static const u16 min_hmax_4lane[] = {
+ [IMX678_LINK_FREQ_297MHZ] = 1584,
+ [IMX678_LINK_FREQ_360MHZ] = 1320,
+ [IMX678_LINK_FREQ_445MHZ] = 1100,
+ [IMX678_LINK_FREQ_594MHZ] = 792,
+ [IMX678_LINK_FREQ_720MHZ] = 660,
+ [IMX678_LINK_FREQ_891MHZ] = 550,
+ [IMX678_LINK_FREQ_1039MHZ] = 550,
+ [IMX678_LINK_FREQ_1188MHZ] = 550,
+};
+
+struct imx678_inck_cfg {
+ u32 xclk_hz; /* platform clock rate */
+ u8 inck_sel; /* value for reg */
+};
+
+static const struct imx678_inck_cfg imx678_inck_table[] = {
+ { 74250000, 0x00 },
+ { 37125000, 0x01 },
+ { 72000000, 0x02 },
+ { 27000000, 0x03 },
+ { 24000000, 0x04 },
+ { 36000000, 0x05 },
+ { 18000000, 0x06 },
+ { 13500000, 0x07 },
+};
+
+static const char * const imx678_tpg_menu[] = {
+ "Disabled",
+ "All 000h",
+ "All FFFh",
+ "All 555h",
+ "All AAAh",
+ "Toggle 555/AAAh",
+ "Toggle AAA/555h",
+ "Toggle 000/555h",
+ "Toggle 555/000h",
+ "Toggle 000/FFFh",
+ "Toggle FFF/000h",
+ "Horizontal color bars",
+ "Vertical color bars",
+};
+
+static const int imx678_tpg_val[] = {
+ IMX678_TPG_ALL_000,
+ IMX678_TPG_ALL_000,
+ IMX678_TPG_ALL_FFF,
+ IMX678_TPG_ALL_555,
+ IMX678_TPG_ALL_AAA,
+ IMX678_TPG_TOG_555_AAA,
+ IMX678_TPG_TOG_AAA_555,
+ IMX678_TPG_TOG_000_555,
+ IMX678_TPG_TOG_555_000,
+ IMX678_TPG_TOG_000_FFF,
+ IMX678_TPG_TOG_FFF_000,
+ IMX678_TPG_H_COLOR_BARS,
+ IMX678_TPG_V_COLOR_BARS,
+};
+
+/* Common configuration */
+static const struct cci_reg_sequence common_regs[] = {
+ { IMX678_REG_THIN_V_EN, 0x00 },
+ { IMX678_REG_VCMODE, 0x01 },
+ { CCI_REG8(0x306b), 0x00 },
+ { IMX678_REG_GAIN_PGC_FIDMD, 0x01 },
+ { CCI_REG8(0x3460), 0x22 },
+ { CCI_REG8(0x355a), 0x64 },
+ { CCI_REG8(0x3a02), 0x7a },
+ { CCI_REG8(0x3a10), 0xec },
+ { CCI_REG8(0x3a12), 0x71 },
+ { CCI_REG8(0x3a14), 0xde },
+ { CCI_REG8(0x3a20), 0x2b },
+ { CCI_REG8(0x3a24), 0x22 },
+ { CCI_REG8(0x3a25), 0x25 },
+ { CCI_REG8(0x3a26), 0x2a },
+ { CCI_REG8(0x3a27), 0x2c },
+ { CCI_REG8(0x3a28), 0x39 },
+ { CCI_REG8(0x3a29), 0x38 },
+ { CCI_REG8(0x3a30), 0x04 },
+ { CCI_REG8(0x3a31), 0x04 },
+ { CCI_REG8(0x3a32), 0x03 },
+ { CCI_REG8(0x3a33), 0x03 },
+ { CCI_REG8(0x3a34), 0x09 },
+ { CCI_REG8(0x3a35), 0x06 },
+ { CCI_REG8(0x3a38), 0xcd },
+ { CCI_REG8(0x3a3a), 0x4c },
+ { CCI_REG8(0x3a3c), 0xb9 },
+ { CCI_REG8(0x3a3e), 0x30 },
+ { CCI_REG8(0x3a40), 0x2c },
+ { CCI_REG8(0x3a42), 0x39 },
+ { CCI_REG8(0x3a4e), 0x00 },
+ { CCI_REG8(0x3a52), 0x00 },
+ { CCI_REG8(0x3a56), 0x00 },
+ { CCI_REG8(0x3a5a), 0x00 },
+ { CCI_REG8(0x3a5e), 0x00 },
+ { CCI_REG8(0x3a62), 0x00 },
+ { CCI_REG8(0x3a64), 0x00 },
+ { CCI_REG8(0x3a6e), 0xa0 },
+ { CCI_REG8(0x3a70), 0x50 },
+ { CCI_REG8(0x3a8c), 0x04 },
+ { CCI_REG8(0x3a8d), 0x03 },
+ { CCI_REG8(0x3a8e), 0x09 },
+ { CCI_REG8(0x3a90), 0x38 },
+ { CCI_REG8(0x3a91), 0x42 },
+ { CCI_REG8(0x3a92), 0x3c },
+ { CCI_REG8(0x3b0e), 0xf3 },
+ { CCI_REG8(0x3b12), 0xe5 },
+ { CCI_REG8(0x3b27), 0xc0 },
+ { CCI_REG8(0x3b2e), 0xef },
+ { CCI_REG8(0x3b30), 0x6a },
+ { CCI_REG8(0x3b32), 0xf6 },
+ { CCI_REG8(0x3b36), 0xe1 },
+ { CCI_REG8(0x3b3a), 0xe8 },
+ { CCI_REG8(0x3b5a), 0x17 },
+ { CCI_REG8(0x3b5e), 0xef },
+ { CCI_REG8(0x3b60), 0x6a },
+ { CCI_REG8(0x3b62), 0xf6 },
+ { CCI_REG8(0x3b66), 0xe1 },
+ { CCI_REG8(0x3b6a), 0xe8 },
+ { CCI_REG8(0x3b88), 0xec },
+ { CCI_REG8(0x3b8a), 0xed },
+ { CCI_REG8(0x3b94), 0x71 },
+ { CCI_REG8(0x3b96), 0x72 },
+ { CCI_REG8(0x3b98), 0xde },
+ { CCI_REG8(0x3b9a), 0xdf },
+ { CCI_REG8(0x3c0f), 0x06 },
+ { CCI_REG8(0x3c10), 0x06 },
+ { CCI_REG8(0x3c11), 0x06 },
+ { CCI_REG8(0x3c12), 0x06 },
+ { CCI_REG8(0x3c13), 0x06 },
+ { CCI_REG8(0x3c18), 0x20 },
+ { CCI_REG8(0x3c37), 0x10 },
+ { CCI_REG8(0x3c3a), 0x7a },
+ { CCI_REG8(0x3c40), 0xf4 },
+ { CCI_REG8(0x3c48), 0xe6 },
+ { CCI_REG8(0x3c54), 0xce },
+ { CCI_REG8(0x3c56), 0xd0 },
+ { CCI_REG8(0x3c6c), 0x53 },
+ { CCI_REG8(0x3c6e), 0x55 },
+ { CCI_REG8(0x3c70), 0xc0 },
+ { CCI_REG8(0x3c72), 0xc2 },
+ { CCI_REG8(0x3c7e), 0xce },
+ { CCI_REG8(0x3c8c), 0xcf },
+ { CCI_REG8(0x3c8e), 0xeb },
+ { CCI_REG8(0x3c98), 0x54 },
+ { CCI_REG8(0x3c9a), 0x70 },
+ { CCI_REG8(0x3c9c), 0xc1 },
+ { CCI_REG8(0x3c9e), 0xdd },
+ { CCI_REG8(0x3cb0), 0x7a },
+ { CCI_REG8(0x3cb2), 0xba },
+ { CCI_REG8(0x3cc8), 0xbc },
+ { CCI_REG8(0x3cca), 0x7c },
+ { CCI_REG8(0x3cd4), 0xea },
+ { CCI_REG8(0x3cd5), 0x01 },
+ { CCI_REG8(0x3cd6), 0x4a },
+ { CCI_REG8(0x3cd8), 0x00 },
+ { CCI_REG8(0x3cd9), 0x00 },
+ { CCI_REG8(0x3cda), 0xff },
+ { CCI_REG8(0x3cdb), 0x03 },
+ { CCI_REG8(0x3cdc), 0x00 },
+ { CCI_REG8(0x3cdd), 0x00 },
+ { CCI_REG8(0x3cde), 0xff },
+ { CCI_REG8(0x3cdf), 0x03 },
+ { CCI_REG8(0x3ce4), 0x4c },
+ { CCI_REG8(0x3ce6), 0xec },
+ { CCI_REG8(0x3ce7), 0x01 },
+ { CCI_REG8(0x3ce8), 0xff },
+ { CCI_REG8(0x3ce9), 0x03 },
+ { CCI_REG8(0x3cea), 0x00 },
+ { CCI_REG8(0x3ceb), 0x00 },
+ { CCI_REG8(0x3cec), 0xff },
+ { CCI_REG8(0x3ced), 0x03 },
+ { CCI_REG8(0x3cee), 0x00 },
+ { CCI_REG8(0x3cef), 0x00 },
+ { CCI_REG8(0x3cf2), 0xff },
+ { CCI_REG8(0x3cf3), 0x03 },
+ { CCI_REG8(0x3cf4), 0x00 },
+ { CCI_REG8(0x3e28), 0x82 },
+ { CCI_REG8(0x3e2a), 0x80 },
+ { CCI_REG8(0x3e30), 0x85 },
+ { CCI_REG8(0x3e32), 0x7d },
+ { CCI_REG8(0x3e5c), 0xce },
+ { CCI_REG8(0x3e5e), 0xd3 },
+ { CCI_REG8(0x3e70), 0x53 },
+ { CCI_REG8(0x3e72), 0x58 },
+ { CCI_REG8(0x3e74), 0xc0 },
+ { CCI_REG8(0x3e76), 0xc5 },
+ { CCI_REG8(0x3e78), 0xc0 },
+ { CCI_REG8(0x3e79), 0x01 },
+ { CCI_REG8(0x3e7a), 0xd4 },
+ { CCI_REG8(0x3e7b), 0x01 },
+ { CCI_REG8(0x3eb4), 0x0b },
+ { CCI_REG8(0x3eb5), 0x02 },
+ { CCI_REG8(0x3eb6), 0x4d },
+ { CCI_REG8(0x3eb7), 0x42 },
+ { CCI_REG8(0x3eec), 0xf3 },
+ { CCI_REG8(0x3eee), 0xe7 },
+ { CCI_REG8(0x3f01), 0x01 },
+ { CCI_REG8(0x3f24), 0x10 },
+ { CCI_REG8(0x3f28), 0x2d },
+ { CCI_REG8(0x3f2a), 0x2d },
+ { CCI_REG8(0x3f2c), 0x2d },
+ { CCI_REG8(0x3f2e), 0x2d },
+ { CCI_REG8(0x3f30), 0x23 },
+ { CCI_REG8(0x3f38), 0x2d },
+ { CCI_REG8(0x3f3a), 0x2d },
+ { CCI_REG8(0x3f3c), 0x2d },
+ { CCI_REG8(0x3f3e), 0x28 },
+ { CCI_REG8(0x3f40), 0x1e },
+ { CCI_REG8(0x3f48), 0x2d },
+ { CCI_REG8(0x3f4a), 0x2d },
+ { CCI_REG8(0x3f4c), 0x00 },
+ { CCI_REG8(0x4004), 0xe4 },
+ { CCI_REG8(0x4006), 0xff },
+ { CCI_REG8(0x4018), 0x69 },
+ { CCI_REG8(0x401a), 0x84 },
+ { CCI_REG8(0x401c), 0xd6 },
+ { CCI_REG8(0x401e), 0xf1 },
+ { CCI_REG8(0x4038), 0xde },
+ { CCI_REG8(0x403a), 0x00 },
+ { CCI_REG8(0x403b), 0x01 },
+ { CCI_REG8(0x404c), 0x63 },
+ { CCI_REG8(0x404e), 0x85 },
+ { CCI_REG8(0x4050), 0xd0 },
+ { CCI_REG8(0x4052), 0xf2 },
+ { CCI_REG8(0x4108), 0xdd },
+ { CCI_REG8(0x410a), 0xf7 },
+ { CCI_REG8(0x411c), 0x62 },
+ { CCI_REG8(0x411e), 0x7c },
+ { CCI_REG8(0x4120), 0xcf },
+ { CCI_REG8(0x4122), 0xe9 },
+ { CCI_REG8(0x4138), 0xe6 },
+ { CCI_REG8(0x413a), 0xf1 },
+ { CCI_REG8(0x414c), 0x6b },
+ { CCI_REG8(0x414e), 0x76 },
+ { CCI_REG8(0x4150), 0xd8 },
+ { CCI_REG8(0x4152), 0xe3 },
+ { CCI_REG8(0x417e), 0x03 },
+ { CCI_REG8(0x417f), 0x01 },
+ { CCI_REG8(0x4186), 0xe0 },
+ { CCI_REG8(0x4190), 0xf3 },
+ { CCI_REG8(0x4192), 0xf7 },
+ { CCI_REG8(0x419c), 0x78 },
+ { CCI_REG8(0x419e), 0x7c },
+ { CCI_REG8(0x41a0), 0xe5 },
+ { CCI_REG8(0x41a2), 0xe9 },
+ { CCI_REG8(0x41c8), 0xe2 },
+ { CCI_REG8(0x41ca), 0xfd },
+ { CCI_REG8(0x41dc), 0x67 },
+ { CCI_REG8(0x41de), 0x82 },
+ { CCI_REG8(0x41e0), 0xd4 },
+ { CCI_REG8(0x41e2), 0xef },
+ { CCI_REG8(0x4200), 0xde },
+ { CCI_REG8(0x4202), 0xda },
+ { CCI_REG8(0x4218), 0x63 },
+ { CCI_REG8(0x421a), 0x5f },
+ { CCI_REG8(0x421c), 0xd0 },
+ { CCI_REG8(0x421e), 0xcc },
+ { CCI_REG8(0x425a), 0x82 },
+ { CCI_REG8(0x425c), 0xef },
+ { CCI_REG8(0x4348), 0xfe },
+ { CCI_REG8(0x4349), 0x06 },
+ { CCI_REG8(0x4352), 0xce },
+ { CCI_REG8(0x4420), 0x0b },
+ { CCI_REG8(0x4421), 0x02 },
+ { CCI_REG8(0x4422), 0x4d },
+ { CCI_REG8(0x4423), 0x0a },
+ { CCI_REG8(0x4426), 0xf5 },
+ { CCI_REG8(0x442a), 0xe7 },
+ { CCI_REG8(0x4432), 0xf5 },
+ { CCI_REG8(0x4436), 0xe7 },
+ { CCI_REG8(0x4466), 0xb4 },
+ { CCI_REG8(0x446e), 0x32 },
+ { CCI_REG8(0x449f), 0x1c },
+ { CCI_REG8(0x44a4), 0x2c },
+ { CCI_REG8(0x44a6), 0x2c },
+ { CCI_REG8(0x44a8), 0x2c },
+ { CCI_REG8(0x44aa), 0x2c },
+ { CCI_REG8(0x44b4), 0x2c },
+ { CCI_REG8(0x44b6), 0x2c },
+ { CCI_REG8(0x44b8), 0x2c },
+ { CCI_REG8(0x44ba), 0x2c },
+ { CCI_REG8(0x44c4), 0x2c },
+ { CCI_REG8(0x44c6), 0x2c },
+ { CCI_REG8(0x44c8), 0x2c },
+ { CCI_REG8(0x4506), 0xf3 },
+ { CCI_REG8(0x450e), 0xe5 },
+ { CCI_REG8(0x4516), 0xf3 },
+ { CCI_REG8(0x4522), 0xe5 },
+ { CCI_REG8(0x4524), 0xf3 },
+ { CCI_REG8(0x452c), 0xe5 },
+ { CCI_REG8(0x453c), 0x22 },
+ { CCI_REG8(0x453d), 0x1b },
+ { CCI_REG8(0x453e), 0x1b },
+ { CCI_REG8(0x453f), 0x15 },
+ { CCI_REG8(0x4540), 0x15 },
+ { CCI_REG8(0x4541), 0x15 },
+ { CCI_REG8(0x4542), 0x15 },
+ { CCI_REG8(0x4543), 0x15 },
+ { CCI_REG8(0x4544), 0x15 },
+ { CCI_REG8(0x4548), 0x00 },
+ { CCI_REG8(0x4549), 0x01 },
+ { CCI_REG8(0x454a), 0x01 },
+ { CCI_REG8(0x454b), 0x06 },
+ { CCI_REG8(0x454c), 0x06 },
+ { CCI_REG8(0x454d), 0x06 },
+ { CCI_REG8(0x454e), 0x06 },
+ { CCI_REG8(0x454f), 0x06 },
+ { CCI_REG8(0x4550), 0x06 },
+ { CCI_REG8(0x4554), 0x55 },
+ { CCI_REG8(0x4555), 0x02 },
+ { CCI_REG8(0x4556), 0x42 },
+ { CCI_REG8(0x4557), 0x05 },
+ { CCI_REG8(0x4558), 0xfd },
+ { CCI_REG8(0x4559), 0x05 },
+ { CCI_REG8(0x455a), 0x94 },
+ { CCI_REG8(0x455b), 0x06 },
+ { CCI_REG8(0x455d), 0x06 },
+ { CCI_REG8(0x455e), 0x49 },
+ { CCI_REG8(0x455f), 0x07 },
+ { CCI_REG8(0x4560), 0x7f },
+ { CCI_REG8(0x4561), 0x07 },
+ { CCI_REG8(0x4562), 0xa5 },
+ { CCI_REG8(0x4564), 0x55 },
+ { CCI_REG8(0x4565), 0x02 },
+ { CCI_REG8(0x4566), 0x42 },
+ { CCI_REG8(0x4567), 0x05 },
+ { CCI_REG8(0x4568), 0xfd },
+ { CCI_REG8(0x4569), 0x05 },
+ { CCI_REG8(0x456a), 0x94 },
+ { CCI_REG8(0x456b), 0x06 },
+ { CCI_REG8(0x456d), 0x06 },
+ { CCI_REG8(0x456e), 0x49 },
+ { CCI_REG8(0x456f), 0x07 },
+ { CCI_REG8(0x4572), 0xa5 },
+ { CCI_REG8(0x460c), 0x7d },
+ { CCI_REG8(0x460e), 0xb1 },
+ { CCI_REG8(0x4614), 0xa8 },
+ { CCI_REG8(0x4616), 0xb2 },
+ { CCI_REG8(0x461c), 0x7e },
+ { CCI_REG8(0x461e), 0xa7 },
+ { CCI_REG8(0x4624), 0xa8 },
+ { CCI_REG8(0x4626), 0xb2 },
+ { CCI_REG8(0x462c), 0x7e },
+ { CCI_REG8(0x462e), 0x8a },
+ { CCI_REG8(0x4630), 0x94 },
+ { CCI_REG8(0x4632), 0xa7 },
+ { CCI_REG8(0x4634), 0xfb },
+ { CCI_REG8(0x4636), 0x2f },
+ { CCI_REG8(0x4638), 0x81 },
+ { CCI_REG8(0x4639), 0x01 },
+ { CCI_REG8(0x463a), 0xb5 },
+ { CCI_REG8(0x463b), 0x01 },
+ { CCI_REG8(0x463c), 0x26 },
+ { CCI_REG8(0x463e), 0x30 },
+ { CCI_REG8(0x4640), 0xac },
+ { CCI_REG8(0x4641), 0x01 },
+ { CCI_REG8(0x4642), 0xb6 },
+ { CCI_REG8(0x4643), 0x01 },
+ { CCI_REG8(0x4644), 0xfc },
+ { CCI_REG8(0x4646), 0x25 },
+ { CCI_REG8(0x4648), 0x82 },
+ { CCI_REG8(0x4649), 0x01 },
+ { CCI_REG8(0x464a), 0xab },
+ { CCI_REG8(0x464b), 0x01 },
+ { CCI_REG8(0x464c), 0x26 },
+ { CCI_REG8(0x464e), 0x30 },
+ { CCI_REG8(0x4654), 0xfc },
+ { CCI_REG8(0x4656), 0x08 },
+ { CCI_REG8(0x4658), 0x12 },
+ { CCI_REG8(0x465a), 0x25 },
+ { CCI_REG8(0x4662), 0xfc },
+ { CCI_REG8(0x46a2), 0xfb },
+ { CCI_REG8(0x46d6), 0xf3 },
+ { CCI_REG8(0x46e6), 0x00 },
+ { CCI_REG8(0x46e8), 0xff },
+ { CCI_REG8(0x46e9), 0x03 },
+ { CCI_REG8(0x46ec), 0x7a },
+ { CCI_REG8(0x46ee), 0xe5 },
+ { CCI_REG8(0x46f4), 0xee },
+ { CCI_REG8(0x46f6), 0xf2 },
+ { CCI_REG8(0x470c), 0xff },
+ { CCI_REG8(0x470d), 0x03 },
+ { CCI_REG8(0x470e), 0x00 },
+ { CCI_REG8(0x4714), 0xe0 },
+ { CCI_REG8(0x4716), 0xe4 },
+ { CCI_REG8(0x471e), 0xed },
+ { CCI_REG8(0x472e), 0x00 },
+ { CCI_REG8(0x4730), 0xff },
+ { CCI_REG8(0x4731), 0x03 },
+ { CCI_REG8(0x4734), 0x7b },
+ { CCI_REG8(0x4736), 0xdf },
+ { CCI_REG8(0x4754), 0x7d },
+ { CCI_REG8(0x4756), 0x8b },
+ { CCI_REG8(0x4758), 0x93 },
+ { CCI_REG8(0x475a), 0xb1 },
+ { CCI_REG8(0x475c), 0xfb },
+ { CCI_REG8(0x475e), 0x09 },
+ { CCI_REG8(0x4760), 0x11 },
+ { CCI_REG8(0x4762), 0x2f },
+ { CCI_REG8(0x4766), 0xcc },
+ { CCI_REG8(0x4776), 0xcb },
+ { CCI_REG8(0x477e), 0x4a },
+ { CCI_REG8(0x478e), 0x49 },
+ { CCI_REG8(0x4794), 0x7c },
+ { CCI_REG8(0x4796), 0x8f },
+ { CCI_REG8(0x4798), 0xb3 },
+ { CCI_REG8(0x4799), 0x00 },
+ { CCI_REG8(0x479a), 0xcc },
+ { CCI_REG8(0x479c), 0xc1 },
+ { CCI_REG8(0x479e), 0xcb },
+ { CCI_REG8(0x47a4), 0x7d },
+ { CCI_REG8(0x47a6), 0x8e },
+ { CCI_REG8(0x47a8), 0xb4 },
+ { CCI_REG8(0x47a9), 0x00 },
+ { CCI_REG8(0x47aa), 0xc0 },
+ { CCI_REG8(0x47ac), 0xfa },
+ { CCI_REG8(0x47ae), 0x0d },
+ { CCI_REG8(0x47b0), 0x31 },
+ { CCI_REG8(0x47b1), 0x01 },
+ { CCI_REG8(0x47b2), 0x4a },
+ { CCI_REG8(0x47b3), 0x01 },
+ { CCI_REG8(0x47b4), 0x3f },
+ { CCI_REG8(0x47b6), 0x49 },
+ { CCI_REG8(0x47bc), 0xfb },
+ { CCI_REG8(0x47be), 0x0c },
+ { CCI_REG8(0x47c0), 0x32 },
+ { CCI_REG8(0x47c1), 0x01 },
+ { CCI_REG8(0x47c2), 0x3e },
+ { CCI_REG8(0x47c3), 0x01 },
+ { IMX678_REG_WDMODE, 0x00 },
+ { IMX678_REG_MDBIT, 0x01 },
+ { IMX678_REG_XXS_DRV, 0x00 },
+};
+
+static const u32 codes_bayer[] = {
+ MEDIA_BUS_FMT_SRGGB12_1X12,
+};
+
+static const u32 codes_monochrome[] = {
+ MEDIA_BUS_FMT_Y12_1X12,
+};
+
+static const struct imx678_model_info imx678_aaqr_info = {
+ .type = IMX678_COLOR,
+ .codes = codes_bayer,
+ .num_codes = ARRAY_SIZE(codes_bayer),
+};
+
+static const struct imx678_model_info imx678_aamr_info = {
+ .type = IMX678_MONOCHROME,
+ .codes = codes_monochrome,
+ .num_codes = ARRAY_SIZE(codes_monochrome),
+};
+
+static const char * const imx678_supply_name[] = {
+ "avdd", /* Analog (3.3V) supply */
+ "dvdd", /* Digital Core (1.1V) supply */
+ "ovdd", /* IF (1.8V) supply */
+};
+
+struct imx678 {
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+ struct regmap *cci;
+
+ const struct imx678_model_info *info;
+
+ struct clk *xclk;
+ u32 xclk_freq;
+
+ /* chosen INCK_SEL register value */
+ u8 inck_sel_val;
+
+ /* Link configurations */
+ enum imx678_lanemode lane_mode;
+ unsigned long link_freq_bitmap;
+
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(imx678_supply_name)];
+
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ /* V4L2 Controls */
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *hblank;
+
+ /* Track VMAX for exposure updates */
+ u32 vmax;
+};
+
+static inline struct imx678 *to_imx678(struct v4l2_subdev *_sd)
+{
+ return container_of_const(_sd, struct imx678, sd);
+}
+
+static u32 imx678_default_mbus_code(struct imx678 *imx678)
+{
+ return imx678->info->codes[0];
+}
+
+static bool imx678_mbus_code_supported(struct imx678 *imx678, u32 code)
+{
+ for (unsigned int i = 0; i < imx678->info->num_codes; i++) {
+ if (imx678->info->codes[i] == code)
+ return true;
+ }
+
+ return false;
+}
+
+static int imx678_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct imx678 *imx678 = container_of_const(ctrl->handler, struct
+ imx678, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd);
+ const struct v4l2_mbus_framefmt *format;
+ struct v4l2_subdev_state *state;
+ int ret = 0;
+
+ state = v4l2_subdev_get_locked_active_state(&imx678->sd);
+ format = v4l2_subdev_state_get_format(state, IMX678_SOURCE_PAD);
+
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ u32 current_exposure = imx678->exposure->cur.val;
+
+ imx678->vmax = format->height + ctrl->val;
+
+ current_exposure = clamp_t(u32, current_exposure,
+ IMX678_EXPOSURE_MIN,
+ imx678->vmax - IMX678_SHR_MIN);
+ ret = __v4l2_ctrl_modify_range(imx678->exposure,
+ IMX678_EXPOSURE_MIN,
+ imx678->vmax - IMX678_SHR_MIN,
+ 1, current_exposure);
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * Only apply control values when device is powered on (RPM ACTIVE)
+ * and streaming (usage count != 0)
+ */
+ if (!pm_runtime_get_if_in_use(&client->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VBLANK:
+ cci_write(imx678->cci, IMX678_REG_VMAX, imx678->vmax, &ret);
+ fallthrough; /* SHR = VMAX - exposure, so update it */
+ case V4L2_CID_EXPOSURE: {
+ u32 shr = imx678->vmax - imx678->exposure->val;
+
+ cci_write(imx678->cci, IMX678_REG_SHR, shr, &ret);
+ break;
+ }
+ case V4L2_CID_ANALOGUE_GAIN:
+ cci_write(imx678->cci, IMX678_REG_GAIN, ctrl->val, &ret);
+ break;
+ case V4L2_CID_HBLANK: {
+ u32 hmax = (format->width + ctrl->val) / IMX678_PIX_PER_CLK;
+
+ cci_write(imx678->cci, IMX678_REG_HMAX, hmax, &ret);
+ break;
+ }
+ case V4L2_CID_TEST_PATTERN: {
+ cci_write(imx678->cci, IMX678_REG_TPG_COLORWIDTH,
+ IMX678_TPG_COLORWIDTH_160PIX, &ret);
+ cci_write(imx678->cci, IMX678_REG_TPG_PATSEL_DUOUT,
+ imx678_tpg_val[ctrl->val], &ret);
+ cci_write(imx678->cci, IMX678_REG_TPG_EN_DUOUT,
+ (ctrl->val) ? 1 : 0,
+ &ret);
+ break;
+ }
+ case V4L2_CID_HFLIP:
+ cci_write(imx678->cci, IMX678_REG_WINMODEH, ctrl->val, &ret);
+ break;
+ case V4L2_CID_VFLIP:
+ cci_write(imx678->cci, IMX678_REG_WINMODEV, ctrl->val, &ret);
+ break;
+ default:
+ dev_warn(&client->dev,
+ "ctrl(id:0x%x,val:0x%x) is not handled\n",
+ ctrl->id, ctrl->val);
+ break;
+ }
+
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops imx678_ctrl_ops = {
+ .s_ctrl = imx678_set_ctrl,
+};
+
+static int imx678_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct imx678 *imx678 = to_imx678(sd);
+
+ if (code->index >= imx678->info->num_codes)
+ return -EINVAL;
+
+ code->code = imx678->info->codes[code->index];
+
+ return 0;
+}
+
+static int imx678_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct imx678 *imx678 = to_imx678(sd);
+ const struct v4l2_rect *crop;
+
+ if (fse->index)
+ return -EINVAL;
+
+ if (!imx678_mbus_code_supported(imx678, fse->code))
+ return -EINVAL;
+
+ crop = v4l2_subdev_state_get_crop(sd_state, fse->pad);
+
+ fse->min_width = crop->width;
+ fse->max_width = fse->min_width;
+ fse->min_height = crop->height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static int imx678_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad);
+ return 0;
+
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r = imx678_native_area;
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r = imx678_active_area;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int imx678_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct imx678 *imx678 = to_imx678(sd);
+ struct v4l2_mbus_framefmt *format;
+ struct v4l2_rect *crop;
+
+ crop = v4l2_subdev_state_get_crop(state, IMX678_SOURCE_PAD);
+ *crop = imx678_active_area;
+
+ format = v4l2_subdev_state_get_format(state, IMX678_SOURCE_PAD);
+ format->code = imx678_default_mbus_code(imx678);
+ format->width = imx678_active_area.width;
+ format->height = imx678_active_area.height;
+ format->field = V4L2_FIELD_NONE;
+ format->colorspace = V4L2_COLORSPACE_RAW;
+ format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ format->xfer_func = V4L2_XFER_FUNC_NONE;
+
+ return 0;
+}
+
+static int imx678_write_common(struct imx678 *imx678)
+{
+ int ret = 0;
+
+ cci_multi_reg_write(imx678->cci, common_regs, ARRAY_SIZE(common_regs),
+ &ret);
+
+ cci_write(imx678->cci, IMX678_REG_INCK_SEL, imx678->inck_sel_val, &ret);
+ cci_write(imx678->cci, IMX678_REG_DATARATE_SEL,
+ link_freqs_reg_value[__ffs(imx678->link_freq_bitmap)], &ret);
+ cci_write(imx678->cci, IMX678_REG_LANEMODE, imx678->lane_mode, &ret);
+
+ cci_write(imx678->cci, IMX678_REG_INTERFACE_SEL, IMX678_INTERFACE_2L_4L,
+ &ret);
+
+ return ret;
+}
+
+static int imx678_program_window(struct imx678 *imx678,
+ const struct v4l2_rect *crop)
+{
+ int ret = 0;
+
+ cci_write(imx678->cci, IMX678_REG_ADDMODE, 0x00, &ret);
+ cci_write(imx678->cci, IMX678_REG_WINMODE,
+ v4l2_rect_equal(crop, &imx678_active_area) ? 0x00 : 0x04,
+ &ret);
+ cci_write(imx678->cci, IMX678_REG_PIX_HST,
+ crop->left - imx678_active_area.left, &ret);
+ cci_write(imx678->cci, IMX678_REG_PIX_HWIDTH, crop->width, &ret);
+ cci_write(imx678->cci, IMX678_REG_PIX_VST,
+ crop->top - imx678_active_area.top, &ret);
+ cci_write(imx678->cci, IMX678_REG_PIX_VWIDTH, crop->height, &ret);
+ cci_write(imx678->cci, IMX678_REG_ADBIT, 0x01, &ret);
+
+ return ret;
+}
+
+static int imx678_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 mask)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct imx678 *imx678 = to_imx678(sd);
+ const struct v4l2_rect *crop;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(&client->dev);
+ if (ret < 0)
+ return ret;
+
+ crop = v4l2_subdev_state_get_crop(state, pad);
+ ret = imx678_program_window(imx678, crop);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ goto err_rpm_put;
+ }
+
+ ret = __v4l2_ctrl_handler_setup(imx678->sd.ctrl_handler);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to apply user values\n",
+ __func__);
+ goto err_rpm_put;
+ }
+
+ cci_write(imx678->cci, IMX678_REG_MODE_SELECT, IMX678_MODE_STREAMING,
+ &ret);
+ usleep_range(IMX678_STREAM_DELAY_US, IMX678_STREAM_DELAY_US +
+ IMX678_STREAM_DELAY_RANGE_US);
+ cci_write(imx678->cci, IMX678_REG_XMSTA, 0x00, &ret);
+
+ if (ret) {
+ dev_err(&client->dev, "%s failed to start streaming\n",
+ __func__);
+ goto err_rpm_put;
+ }
+
+ return 0;
+
+err_rpm_put:
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static int imx678_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 mask)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct imx678 *imx678 = to_imx678(sd);
+ int ret = 0;
+
+ /* Master mode disable */
+ cci_write(imx678->cci, IMX678_REG_XMSTA, 0x01, &ret);
+ /* Standby */
+ cci_write(imx678->cci, IMX678_REG_MODE_SELECT, IMX678_MODE_STANDBY,
+ &ret);
+ if (ret)
+ dev_err(&client->dev, "%s failed to stop stream\n", __func__);
+
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static int imx678_power_on(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct imx678 *imx678 = to_imx678(sd);
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(imx678_supply_name),
+ imx678->supplies);
+ if (ret) {
+ dev_err(&client->dev, "%s: failed to enable regulators\n",
+ __func__);
+ return ret;
+ }
+
+ fsleep(1); /* Tlow > 500ns */
+
+ gpiod_set_value_cansleep(imx678->reset_gpio, 0);
+
+ fsleep(1); /* T3 > 1us */
+
+ ret = clk_prepare_enable(imx678->xclk);
+ if (ret) {
+ dev_err(&client->dev, "%s: failed to enable clock\n",
+ __func__);
+ goto reg_off;
+ }
+
+ fsleep(20); /* T4 > 20us */
+
+ ret = imx678_write_common(imx678);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to write registers\n",
+ __func__);
+ goto clk_off;
+ }
+
+ return 0;
+
+clk_off:
+ clk_disable_unprepare(imx678->xclk);
+
+reg_off:
+ gpiod_set_value_cansleep(imx678->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(imx678_supply_name),
+ imx678->supplies);
+
+ return ret;
+}
+
+static int imx678_power_off(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct imx678 *imx678 = to_imx678(sd);
+
+ clk_disable_unprepare(imx678->xclk);
+ gpiod_set_value_cansleep(imx678->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(imx678_supply_name),
+ imx678->supplies);
+
+ return 0;
+}
+
+static int imx678_identify_model(struct imx678 *imx678)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd);
+ const struct imx678_model_info *info;
+ enum imx678_type detected;
+ int ret = 0;
+ u64 val = 0;
+
+ info = device_get_match_data(&client->dev);
+
+ /*
+ * This sensor's ID registers become accessible 80ms after coming out
+ * of STANDBY mode.
+ */
+ cci_write(imx678->cci, IMX678_REG_MODE_SELECT, 0, &ret);
+ fsleep(IMX678_MODULE_ID_DELAY);
+
+ cci_read(imx678->cci, IMX678_REG_MODULE_ID, &val, &ret);
+
+ if (ret) {
+ dev_err(&client->dev,
+ "I2C transaction failed ret = %d\n", ret);
+ return ret;
+ }
+
+ if (val != IMX678_ID) {
+ dev_err(&client->dev,
+ "Chip ID mismatch: %x!=%llx\n", IMX678_ID, val);
+ return -ENXIO;
+ }
+
+ cci_read(imx678->cci, IMX678_REG_MONOCHROME, &val, &ret);
+
+ if (ret) {
+ dev_err(&client->dev,
+ "I2C transaction failed ret = %d\n", ret);
+ return ret;
+ }
+
+ detected = val & IMX678_TYPE;
+
+ /* Prefer to use sensor type specified in device tree */
+ if (info) {
+ imx678->info = info;
+ if (detected != info->type)
+ dev_err(&client->dev,
+ "detected %s sensor, DT specifies %s; using DT value\n",
+ detected == IMX678_COLOR ? "color" : "mono",
+ info->type == IMX678_COLOR ? "color" : "mono");
+ } else {
+ imx678->info = detected == IMX678_MONOCHROME ?
+ &imx678_aamr_info : &imx678_aaqr_info;
+ dev_info(&client->dev,
+ "sensor type missing in DT; detected %s sensor\n",
+ detected == IMX678_MONOCHROME ? "mono" : "color");
+ }
+
+ return 0;
+}
+
+static const struct v4l2_subdev_video_ops imx678_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops imx678_pad_ops = {
+ .enum_mbus_code = imx678_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = v4l2_subdev_get_fmt,
+ .get_selection = imx678_get_selection,
+ .enum_frame_size = imx678_enum_frame_size,
+ .enable_streams = imx678_enable_streams,
+ .disable_streams = imx678_disable_streams,
+};
+
+static const struct v4l2_subdev_ops imx678_subdev_ops = {
+ .video = &imx678_video_ops,
+ .pad = &imx678_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops imx678_internal_ops = {
+ .init_state = imx678_init_state,
+};
+
+static int imx678_init_controls(struct imx678 *imx678)
+{
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ const u32 hmax_4lane = min_hmax_4lane[__ffs(imx678->link_freq_bitmap)];
+ const u32 lane_scale = imx678->lane_mode == IMX678_LANEMODE_2L ? 2 : 1;
+ struct i2c_client *client = v4l2_get_subdevdata(&imx678->sd);
+ struct v4l2_fwnode_device_properties props;
+ struct v4l2_ctrl *link_freq;
+ s32 hblank, max_hblank, vblank, max_vblank;
+ u32 hmax;
+ int ret;
+
+ ret = v4l2_fwnode_device_parse(&client->dev, &props);
+ if (ret < 0)
+ return ret;
+
+ ctrl_hdlr = &imx678->ctrl_handler;
+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 11);
+ if (ret)
+ return ret;
+
+ imx678->vmax = IMX678_VMAX_DEFAULT;
+ hmax = hmax_4lane * lane_scale;
+
+ /* PIXEL_RATE is fixed and read-only */
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_PIXEL_RATE,
+ IMX678_PIXEL_RATE, IMX678_PIXEL_RATE, 1,
+ IMX678_PIXEL_RATE);
+
+ /* LINK_FREQ is also read only */
+ link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx678_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ ARRAY_SIZE(link_freqs) - 1,
+ __ffs(imx678->link_freq_bitmap),
+ link_freqs);
+
+ if (link_freq)
+ link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ vblank = imx678->vmax - imx678_active_area.height;
+ max_vblank = IMX678_VMAX_MAX - imx678_active_area.height;
+ imx678->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops,
+ V4L2_CID_VBLANK, vblank, max_vblank,
+ 2, vblank);
+
+ hblank = hmax * IMX678_PIX_PER_CLK - imx678_active_area.width;
+ max_hblank = IMX678_HMAX_MAX * IMX678_PIX_PER_CLK -
+ imx678_active_area.width;
+ imx678->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops,
+ V4L2_CID_HBLANK, hblank, max_hblank,
+ IMX678_PIX_PER_CLK, hblank);
+
+ imx678->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ IMX678_EXPOSURE_MIN,
+ IMX678_VMAX_DEFAULT -
+ IMX678_SHR_MIN,
+ IMX678_EXPOSURE_STEP,
+ IMX678_EXPOSURE_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ IMX678_ANA_GAIN_MIN_NORMAL,
+ IMX678_ANA_GAIN_MAX_NORMAL, IMX678_ANA_GAIN_STEP,
+ IMX678_ANA_GAIN_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_HFLIP,
+ 0, 1, 1, 0);
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx678_ctrl_ops, V4L2_CID_VFLIP,
+ 0, 1, 1, 0);
+
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx678_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(imx678_tpg_menu) - 1, 0, 0,
+ imx678_tpg_menu);
+
+ v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx678_ctrl_ops, &props);
+
+ if (ctrl_hdlr->error) {
+ ret = ctrl_hdlr->error;
+ dev_err(&client->dev, "%s control init failed (%d)\n",
+ __func__, ret);
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+ return ret;
+ }
+
+ imx678->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+}
+
+static int imx678_check_hwcfg(struct device *dev, struct imx678 *imx678)
+{
+ struct fwnode_handle *endpoint;
+ struct v4l2_fwnode_endpoint ep_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ int ret = -EINVAL;
+
+ endpoint = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
+ if (!endpoint) {
+ dev_err(dev, "endpoint node not found\n");
+ return -EINVAL;
+ }
+
+ if (v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep_cfg)) {
+ dev_err(dev, "could not parse endpoint\n");
+ goto error_out;
+ }
+
+ switch (ep_cfg.bus.mipi_csi2.num_data_lanes) {
+ case 2:
+ imx678->lane_mode = IMX678_LANEMODE_2L;
+ break;
+ case 4:
+ imx678->lane_mode = IMX678_LANEMODE_4L;
+ break;
+ default:
+ dev_err(dev,
+ "only 2 or 4 CSI2 data lanes are currently supported\n");
+ goto error_out;
+ }
+
+ ret = v4l2_link_freq_to_bitmap(dev, ep_cfg.link_frequencies,
+ ep_cfg.nr_of_link_frequencies,
+ link_freqs, ARRAY_SIZE(link_freqs),
+ &imx678->link_freq_bitmap);
+
+error_out:
+ v4l2_fwnode_endpoint_free(&ep_cfg);
+ fwnode_handle_put(endpoint);
+
+ return ret;
+}
+
+static int imx678_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct imx678 *imx678;
+ int ret, i;
+
+ imx678 = devm_kzalloc(&client->dev, sizeof(*imx678), GFP_KERNEL);
+ if (!imx678)
+ return -ENOMEM;
+
+ v4l2_i2c_subdev_init(&imx678->sd, client, &imx678_subdev_ops);
+
+ imx678->cci = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx678->cci))
+ return dev_err_probe(dev, PTR_ERR(imx678->cci),
+ "failed to init CCI\n");
+
+ if (imx678_check_hwcfg(dev, imx678))
+ return -EINVAL;
+
+ imx678->xclk = devm_v4l2_sensor_clk_get(dev, NULL);
+ if (IS_ERR(imx678->xclk))
+ return dev_err_probe(dev, PTR_ERR(imx678->xclk),
+ "failed to get xclk\n");
+
+ imx678->xclk_freq = clk_get_rate(imx678->xclk);
+
+ for (i = 0; i < ARRAY_SIZE(imx678_inck_table); ++i) {
+ if (imx678_inck_table[i].xclk_hz == imx678->xclk_freq) {
+ imx678->inck_sel_val = imx678_inck_table[i].inck_sel;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(imx678_inck_table))
+ return dev_err_probe(dev, -EINVAL,
+ "unsupported XCLK rate %u Hz\n",
+ imx678->xclk_freq);
+
+ for (i = 0; i < ARRAY_SIZE(imx678_supply_name); i++)
+ imx678->supplies[i].supply = imx678_supply_name[i];
+
+ ret = devm_regulator_bulk_get(&client->dev,
+ ARRAY_SIZE(imx678_supply_name),
+ imx678->supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get regulators\n");
+
+ imx678->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(imx678->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(imx678->reset_gpio),
+ "failed to get reset GPIO\n");
+
+ ret = imx678_power_on(dev);
+ if (ret)
+ return ret;
+
+ ret = imx678_identify_model(imx678);
+ if (ret)
+ goto error_power_off;
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ ret = imx678_init_controls(imx678);
+ if (ret)
+ goto error_pm_runtime;
+
+ imx678->sd.internal_ops = &imx678_internal_ops;
+ imx678->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ imx678->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+ imx678->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&imx678->sd.entity, 1, &imx678->pad);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to init entity pads\n");
+ goto error_handler_free;
+ }
+
+ imx678->sd.state_lock = imx678->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&imx678->sd);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "subdev init error\n");
+ goto error_media_entity;
+ }
+
+ ret = v4l2_async_register_subdev_sensor(&imx678->sd);
+ if (ret < 0) {
+ dev_err_probe(dev, ret,
+ "failed to register sensor sub-device\n");
+ goto error_subdev_cleanup;
+ }
+
+ pm_runtime_idle(dev);
+
+ return 0;
+
+error_subdev_cleanup:
+ v4l2_subdev_cleanup(&imx678->sd);
+
+error_media_entity:
+ media_entity_cleanup(&imx678->sd.entity);
+
+error_handler_free:
+ v4l2_ctrl_handler_free(imx678->sd.ctrl_handler);
+
+error_pm_runtime:
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+
+error_power_off:
+ imx678_power_off(&client->dev);
+
+ return ret;
+}
+
+static void imx678_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct imx678 *imx678 = to_imx678(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(imx678->sd.ctrl_handler);
+
+ pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ imx678_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+}
+
+static const struct dev_pm_ops imx678_pm_ops = {
+ SET_RUNTIME_PM_OPS(imx678_power_off, imx678_power_on, NULL)
+};
+
+static const struct of_device_id imx678_of_match[] = {
+ { .compatible = "sony,imx678-aamr", .data = &imx678_aamr_info },
+ { .compatible = "sony,imx678-aaqr", .data = &imx678_aaqr_info },
+ /* for non-conforming DTs that rely on runtime check */
+ { .compatible = "sony,imx678" },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, imx678_of_match);
+
+static struct i2c_driver imx678_i2c_driver = {
+ .driver = {
+ .name = "imx678",
+ .of_match_table = imx678_of_match,
+ .pm = pm_ptr(&imx678_pm_ops),
+ },
+ .probe = imx678_probe,
+ .remove = imx678_remove,
+};
+
+module_i2c_driver(imx678_i2c_driver);
+
+MODULE_AUTHOR("Will Whang <will@willwhang.com>");
+MODULE_AUTHOR("Tetsuya NOMURA <tetsuya.nomura@soho-enterprise.com>");
+MODULE_AUTHOR("Jai Luthra <jai.luthra@ideasonboard.com>");
+MODULE_DESCRIPTION("Sony imx678 sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c
index 143dcfe10445..0150e4d296af 100644
--- a/drivers/media/i2c/ov02a10.c
+++ b/drivers/media/i2c/ov02a10.c
@@ -820,18 +820,16 @@ static int ov02a10_check_hwcfg(struct device *dev, struct ov02a10 *ov02a10)
if (!ep)
return -ENXIO;
+ /* Optional indication of MIPI clock voltage unit */
+ if (!fwnode_property_read_u32(ep, "ovti,mipi-clock-voltage",
+ &clk_volt))
+ ov02a10->mipi_clock_voltage = clk_volt;
+
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
if (ret)
return ret;
- /* Optional indication of MIPI clock voltage unit */
- ret = fwnode_property_read_u32(ep, "ovti,mipi-clock-voltage",
- &clk_volt);
-
- if (!ret)
- ov02a10->mipi_clock_voltage = clk_volt;
-
for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
if (link_freq_menu_items[i] ==
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index c2e02f191816..b4e14171556f 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -1116,18 +1116,14 @@ static void ov7740_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
- mutex_destroy(&ov7740->mutex);
- v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
- media_entity_cleanup(&ov7740->subdev.entity);
v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&ov7740->subdev.entity);
ov7740_free_controls(ov7740);
- pm_runtime_get_sync(&client->dev);
pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ ov7740_set_power(ov7740, 0);
pm_runtime_set_suspended(&client->dev);
- pm_runtime_put_noidle(&client->dev);
-
- ov7740_set_power(ov7740, 0);
}
static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
index 8c9cd769fa01..289a34a3eeb1 100644
--- a/drivers/media/i2c/ov8865.c
+++ b/drivers/media/i2c/ov8865.c
@@ -2608,7 +2608,7 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)
{
struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
struct ov8865_state *state = &sensor->state;
- int ret;
+ int ret = 0;
if (enable) {
ret = pm_runtime_resume_and_get(sensor->dev);
@@ -2617,18 +2617,32 @@ static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)
}
mutex_lock(&sensor->mutex);
- ret = ov8865_sw_standby(sensor, !enable);
- mutex_unlock(&sensor->mutex);
- if (ret)
- return ret;
+ /*
+ * The sensor may have been kept powered by something else (e.g. the
+ * VCM's runtime PM device link on IPU3 platforms), in which case
+ * runtime resume did not run and the hardware may still be
+ * configured for a previous mode. Always program the negotiated
+ * configuration on stream start.
+ */
+ if (enable) {
+ ret = ov8865_sensor_init(sensor);
+ if (!ret)
+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+ }
- state->streaming = !!enable;
+ if (!ret)
+ ret = ov8865_sw_standby(sensor, !enable);
+
+ mutex_unlock(&sensor->mutex);
- if (!enable)
+ if (ret || !enable)
pm_runtime_put(sensor->dev);
- return 0;
+ if (!ret)
+ state->streaming = enable;
+
+ return ret;
}
static const struct v4l2_subdev_video_ops ov8865_subdev_video_ops = {
@@ -2915,15 +2929,15 @@ static int ov8865_resume(struct device *dev)
if (ret)
goto complete;
- ret = ov8865_sensor_init(sensor);
- if (ret)
- goto error_power;
+ if (state->streaming) {
+ ret = ov8865_sensor_init(sensor);
+ if (ret)
+ goto error_power;
- ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
- if (ret)
- goto error_power;
+ ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+ if (ret)
+ goto error_power;
- if (state->streaming) {
ret = ov8865_sw_standby(sensor, false);
if (ret)
goto error_power;
diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index 5b6f897a74fc..3ba630ec4f2a 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -197,7 +197,6 @@ struct ov9282_mode {
* @noncontinuous_clock: Selection of CSI2 noncontinuous clock mode
* @cur_mode: Pointer to current selected sensor mode
* @code: Mbus code currently selected
- * @mutex: Mutex for serializing sensor controls
*/
struct ov9282 {
struct device *dev;
diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
index bcab462708c7..ece8a410e7ce 100644
--- a/drivers/media/i2c/rdacm21.c
+++ b/drivers/media/i2c/rdacm21.c
@@ -588,10 +588,12 @@ static int rdacm21_probe(struct i2c_client *client)
ret = v4l2_async_register_subdev(&dev->sd);
if (ret)
- goto error_free_ctrls;
+ goto error_entity_cleanup;
return 0;
+error_entity_cleanup:
+ media_entity_cleanup(&dev->sd.entity);
error_free_ctrls:
v4l2_ctrl_handler_free(&dev->ctrls);
error:
@@ -606,6 +608,7 @@ static void rdacm21_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(&dev->sd);
v4l2_ctrl_handler_free(&dev->ctrls);
+ media_entity_cleanup(&dev->sd.entity);
i2c_unregister_device(dev->isp);
}
diff --git a/drivers/media/i2c/vd55g1.c b/drivers/media/i2c/vd55g1.c
index 78d18c028154..c4142d771e7c 100644
--- a/drivers/media/i2c/vd55g1.c
+++ b/drivers/media/i2c/vd55g1.c
@@ -29,11 +29,7 @@
/* Register Map */
#define VD55G1_REG_MODEL_ID CCI_REG32_LE(0x0000)
-#define VD55G1_MODEL_ID_VD55G1 0x53354731 /* Mono */
-#define VD55G1_MODEL_ID_VD65G4 0x53354733 /* RGB */
-#define VD55G1_REG_REVISION CCI_REG16_LE(0x0004)
-#define VD55G1_REVISION_CCB 0x2020
-#define VD55G1_REVISION_BAYER 0x3030
+#define VD55G1_REG_COLOR_VERSION CCI_REG32_LE(0x0670)
#define VD55G1_REG_FWPATCH_REVISION CCI_REG16_LE(0x0012)
#define VD55G1_REG_FWPATCH_START_ADDR CCI_REG8(0x2000)
#define VD55G1_REG_SYSTEM_FSM CCI_REG8(0x001c)
@@ -60,7 +56,10 @@
#define VD55G1_PATGEN_ENABLE BIT(0)
#define VD55G1_REG_MANUAL_ANALOG_GAIN CCI_REG8(0x0501)
#define VD55G1_REG_MANUAL_COARSE_EXPOSURE CCI_REG16_LE(0x0502)
-#define VD55G1_REG_MANUAL_DIGITAL_GAIN CCI_REG16_LE(0x0504)
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN_CH0 CCI_REG16_LE(0x0504)
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN_CH1 CCI_REG16_LE(0x0506)
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN_CH2 CCI_REG16_LE(0x0508)
+#define VD55G1_REG_MANUAL_DIGITAL_GAIN_CH3 CCI_REG16_LE(0x050a)
#define VD55G1_REG_APPLIED_COARSE_EXPOSURE CCI_REG16_LE(0x00e8)
#define VD55G1_REG_APPLIED_ANALOG_GAIN CCI_REG16_LE(0x00ea)
#define VD55G1_REG_APPLIED_DIGITAL_GAIN CCI_REG16_LE(0x00ec)
@@ -114,9 +113,8 @@
#define VD55G1_WIDTH 804
#define VD55G1_HEIGHT 704
-#define VD55G1_MODE_DEF 0
+#define VD55G1_MODE_IDX_DEF 0
#define VD55G1_NB_GPIOS 4
-#define VD55G1_MBUS_CODE_DEF 0
#define VD55G1_DGAIN_DEF 256
#define VD55G1_AGAIN_DEF 19
#define VD55G1_EXPO_MAX_TERM 64
@@ -135,8 +133,39 @@
#define VD55G1_MIPI_RATE_MIN (250 * MEGA)
#define VD55G1_MIPI_RATE_MAX (1200 * MEGA)
-#define VD55G1_MODEL_ID_NAME(id) \
- ((id) == VD55G1_MODEL_ID_VD55G1 ? "vd55g1" : "vd65g4")
+enum vd55g1_model_id {
+ VD55G1_MODEL_ID_2 = 0x53354731,
+ VD55G1_MODEL_ID_3 = 0x53354733,
+};
+
+enum vd55g1_color_version {
+ VD55G1_COLOR_VERSION_MONO,
+ VD55G1_COLOR_VERSION_BAYER,
+};
+
+struct vd55g1_version {
+ char *name;
+ enum vd55g1_model_id id;
+ enum vd55g1_color_version color;
+};
+
+static const struct vd55g1_version vd55g1_versions[] = {
+ {
+ .name = "vd55g1",
+ .id = VD55G1_MODEL_ID_2,
+ .color = VD55G1_COLOR_VERSION_MONO,
+ },
+ {
+ .name = "vd55g4",
+ .id = VD55G1_MODEL_ID_3,
+ .color = VD55G1_COLOR_VERSION_MONO,
+ },
+ {
+ .name = "vd65g4",
+ .id = VD55G1_MODEL_ID_3,
+ .color = VD55G1_COLOR_VERSION_BAYER,
+ },
+};
static const u8 vd55g1_patch_array[] = {
0x44, 0x03, 0x09, 0x02, 0xe6, 0x01, 0x42, 0x00, 0xea, 0x01, 0x42, 0x00,
@@ -532,7 +561,7 @@ struct vd55g1_vblank_limits {
struct vd55g1 {
struct device *dev;
- unsigned int id;
+ const struct vd55g1_version *version;
struct v4l2_subdev sd;
struct media_pad pad;
struct regulator_bulk_data supplies[ARRAY_SIZE(vd55g1_supply_name)];
@@ -623,20 +652,28 @@ static unsigned int vd55g1_get_fmt_data_type(u32 code)
static u32 vd55g1_get_fmt_code(struct vd55g1 *sensor, u32 code)
{
+ u32 fallback_code;
unsigned int i, j;
- if (sensor->id == VD55G1_MODEL_ID_VD55G1)
- return code;
-
- for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_formats_bayer); i++) {
- for (j = 0; j < ARRAY_SIZE(vd55g1_mbus_formats_bayer[i]); j++) {
- if (vd55g1_mbus_formats_bayer[i][j] == code)
- goto adapt_bayer_pattern;
+ if (sensor->version->color == VD55G1_COLOR_VERSION_MONO) {
+ fallback_code = vd55g1_mbus_formats_mono[0];
+ for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_formats_mono); i++)
+ if (vd55g1_mbus_formats_mono[i] == code)
+ return code;
+ } else {
+ fallback_code = vd55g1_mbus_formats_bayer[0][0];
+ for (i = 0; i < ARRAY_SIZE(vd55g1_mbus_formats_bayer); i++) {
+ for (j = 0;
+ j < ARRAY_SIZE(vd55g1_mbus_formats_bayer[i]);
+ j++) {
+ if (vd55g1_mbus_formats_bayer[i][j] == code)
+ goto adapt_bayer_pattern;
+ }
}
}
- dev_warn(sensor->dev, "Unsupported mbus format\n");
+ dev_warn(sensor->dev, "Unsupported mbus format: 0x%x\n", code);
- return code;
+ return fallback_code;
adapt_bayer_pattern:
j = 0;
@@ -850,9 +887,16 @@ static int vd55g1_update_expo_cluster(struct vd55g1 *sensor, bool is_auto)
vd55g1_write(sensor, VD55G1_REG_MANUAL_ANALOG_GAIN,
sensor->again_ctrl->val, &ret);
- if (!is_auto && sensor->dgain_ctrl->is_new)
- vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN,
+ if (!is_auto && sensor->dgain_ctrl->is_new) {
+ vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN_CH0,
sensor->dgain_ctrl->val, &ret);
+ vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN_CH1,
+ sensor->dgain_ctrl->val, &ret);
+ vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN_CH2,
+ sensor->dgain_ctrl->val, &ret);
+ vd55g1_write(sensor, VD55G1_REG_MANUAL_DIGITAL_GAIN_CH3,
+ sensor->dgain_ctrl->val, &ret);
+ }
return ret;
}
@@ -1173,8 +1217,8 @@ static int vd55g1_patch(struct vd55g1 *sensor)
u64 patch;
int ret = 0;
- /* vd55g1 needs a patch while vd65g4 does not */
- if (sensor->id == VD55G1_MODEL_ID_VD55G1) {
+ /* Version 2 needs a patch while version 3 does not */
+ if (sensor->version->id == VD55G1_MODEL_ID_2) {
vd55g1_write_array(sensor, VD55G1_REG_FWPATCH_START_ADDR,
sizeof(vd55g1_patch_array),
vd55g1_patch_array, &ret);
@@ -1246,7 +1290,7 @@ static int vd55g1_enum_mbus_code(struct v4l2_subdev *sd,
struct vd55g1 *sensor = to_vd55g1(sd);
u32 base_code;
- if (sensor->id == VD55G1_MODEL_ID_VD55G1) {
+ if (sensor->version->color != VD55G1_COLOR_VERSION_BAYER) {
if (code->index >= ARRAY_SIZE(vd55g1_mbus_formats_mono))
return -EINVAL;
base_code = vd55g1_mbus_formats_mono[code->index];
@@ -1347,6 +1391,7 @@ static int vd55g1_init_state(struct v4l2_subdev *sd,
{
struct vd55g1 *sensor = to_vd55g1(sd);
struct v4l2_subdev_format fmt = { 0 };
+ int code;
struct v4l2_subdev_route routes[] = {
{ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE }
};
@@ -1361,9 +1406,13 @@ static int vd55g1_init_state(struct v4l2_subdev *sd,
if (ret)
return ret;
- vd55g1_update_pad_fmt(sensor, &vd55g1_supported_modes[VD55G1_MODE_DEF],
- vd55g1_get_fmt_code(sensor, VD55G1_MBUS_CODE_DEF),
- &fmt.format);
+ if (sensor->version->color != VD55G1_COLOR_VERSION_BAYER)
+ code = vd55g1_mbus_formats_mono[0];
+ else
+ code = vd55g1_mbus_formats_bayer[0][0];
+ fmt.format.code = vd55g1_get_fmt_code(sensor, code);
+ fmt.format.width = vd55g1_supported_modes[VD55G1_MODE_IDX_DEF].width;
+ fmt.format.height = vd55g1_supported_modes[VD55G1_MODE_IDX_DEF].height;
return vd55g1_set_pad_fmt(sd, sd_state, &fmt);
}
@@ -1644,38 +1693,46 @@ unlock_state:
return ret;
}
+static const struct vd55g1_version *
+vd55g1_get_version(enum vd55g1_model_id id,
+ enum vd55g1_color_version color)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(vd55g1_versions); i++) {
+ if (vd55g1_versions[i].id == id &&
+ vd55g1_versions[i].color == color)
+ return &vd55g1_versions[i];
+ }
+
+ return NULL;
+}
+
static int vd55g1_detect(struct vd55g1 *sensor)
{
- unsigned int dt_id = (uintptr_t)device_get_match_data(sensor->dev);
- u64 rev, id;
- int ret;
+ const struct vd55g1_version *dt_version =
+ device_get_match_data(sensor->dev);
+ const struct vd55g1_version *version;
+ u64 color, id;
+ int ret = 0;
- ret = vd55g1_read(sensor, VD55G1_REG_MODEL_ID, &id, NULL);
+ vd55g1_read(sensor, VD55G1_REG_MODEL_ID, &id, &ret);
+ vd55g1_read(sensor, VD55G1_REG_COLOR_VERSION, &color, &ret);
if (ret)
return ret;
- if (id != VD55G1_MODEL_ID_VD55G1 && id != VD55G1_MODEL_ID_VD65G4) {
- dev_warn(sensor->dev, "Unsupported sensor id 0x%x\n",
- (u32)id);
+ version = vd55g1_get_version(id, color);
+ if (!version) {
+ dev_warn(sensor->dev, "Unsupported sensor version, expected %s\n",
+ dt_version->name);
return -ENODEV;
}
- if (id != dt_id) {
- dev_err(sensor->dev, "Probed sensor %s and device tree definition (%s) mismatch",
- VD55G1_MODEL_ID_NAME(id), VD55G1_MODEL_ID_NAME(dt_id));
+ if (version->id != dt_version->id ||
+ version->color != dt_version->color) {
+ dev_err(sensor->dev, "Probed sensor version %s and device tree definition %s mismatch",
+ version->name, dt_version->name);
return -ENODEV;
}
- sensor->id = id;
-
- ret = vd55g1_read(sensor, VD55G1_REG_REVISION, &rev, NULL);
- if (ret)
- return ret;
- if ((id == VD55G1_MODEL_ID_VD55G1 && rev != VD55G1_REVISION_CCB) &&
- (id == VD55G1_MODEL_ID_VD65G4 && rev != VD55G1_REVISION_BAYER)) {
- dev_err(sensor->dev, "Unsupported sensor revision 0x%x for sensor %s\n",
- (u16)rev, VD55G1_MODEL_ID_NAME(id));
- return -ENODEV;
- }
+ sensor->version = version;
return 0;
}
@@ -2033,8 +2090,9 @@ static void vd55g1_remove(struct i2c_client *client)
}
static const struct of_device_id vd55g1_dt_ids[] = {
- { .compatible = "st,vd55g1", .data = (void *)VD55G1_MODEL_ID_VD55G1 },
- { .compatible = "st,vd65g4", .data = (void *)VD55G1_MODEL_ID_VD65G4 },
+ { .compatible = "st,vd55g1", .data = (void *)&vd55g1_versions[0] },
+ { .compatible = "st,vd55g4", .data = (void *)&vd55g1_versions[1] },
+ { .compatible = "st,vd65g4", .data = (void *)&vd55g1_versions[2] },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, vd55g1_dt_ids);
diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c
index 6b50fb422a61..4811a0489524 100644
--- a/drivers/media/i2c/video-i2c.c
+++ b/drivers/media/i2c/video-i2c.c
@@ -522,8 +522,12 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
data->kthread_vid_cap = kthread_run(video_i2c_thread_vid_cap, data,
"%s-vid-cap", data->v4l2_dev.name);
ret = PTR_ERR_OR_ZERO(data->kthread_vid_cap);
- if (!ret)
- return 0;
+ if (ret) {
+ data->kthread_vid_cap = NULL;
+ goto error_rpm_put;
+ }
+
+ return 0;
error_rpm_put:
pm_runtime_put_autosuspend(dev);
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 663469208271..c631b8bbd386 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -3563,12 +3563,12 @@ static int __maybe_unused bttv_resume(struct device *dev)
}
static const struct pci_device_id bttv_pci_tbl[] = {
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0},
- {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0},
- {0,}
+ { PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848) },
+ { PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849) },
+ { PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878) },
+ { PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879) },
+ { PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879) },
+ { }
};
MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
diff --git a/drivers/media/pci/cobalt/cobalt-alsa-main.c b/drivers/media/pci/cobalt/cobalt-alsa-main.c
index 7bb7f13c70c0..9ed547cd40af 100644
--- a/drivers/media/pci/cobalt/cobalt-alsa-main.c
+++ b/drivers/media/pci/cobalt/cobalt-alsa-main.c
@@ -135,7 +135,6 @@ int cobalt_alsa_init(struct cobalt_stream *s)
err_exit_free:
if (sc != NULL)
snd_card_free(sc);
- kfree(cobsc);
err_exit:
return ret;
}
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c
index 9b9f69ff4016..7b1ca1238c8d 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.c
+++ b/drivers/media/pci/cobalt/cobalt-driver.c
@@ -26,9 +26,8 @@
/* add your revision and whatnot here */
static const struct pci_device_id cobalt_pci_tbl[] = {
- {PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_COBALT,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ { PCI_VDEVICE(CISCO, PCI_DEVICE_ID_COBALT) },
+ { }
};
MODULE_DEVICE_TABLE(pci, cobalt_pci_tbl);
diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c
index f778f79b921d..214fac7af61e 100644
--- a/drivers/media/pci/cx18/cx18-driver.c
+++ b/drivers/media/pci/cx18/cx18-driver.c
@@ -40,9 +40,8 @@ EXPORT_SYMBOL(cx18_ext_init);
/* add your revision and whatnot here */
static const struct pci_device_id cx18_pci_tbl[] = {
- {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ { PCI_VDEVICE(CX, PCI_DEVICE_ID_CX23418) },
+ { }
};
MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
diff --git a/drivers/media/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
index 8dc4ce325935..3a8430f3259e 100644
--- a/drivers/media/pci/cx18/cx18-vbi.c
+++ b/drivers/media/pci/cx18/cx18-vbi.c
@@ -135,7 +135,7 @@ static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
: VBI_HBLANK_SAMPLES_50HZ;
/* find the first valid line */
- for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
+ for (i = hdr_size, buf += hdr_size; i + 3 < size; i++, buf++) {
if (buf[0] == 0xff && !buf[1] && !buf[2] &&
(buf[3] == sliced_vbi_eav_rp[0] ||
buf[3] == sliced_vbi_eav_rp[1]))
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index 9b92e8db494c..5fb26285e4af 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -2279,16 +2279,10 @@ static int __maybe_unused cx23885_resume(struct device *dev_d)
static const struct pci_device_id cx23885_pci_tbl[] = {
{
/* CX23885 */
- .vendor = 0x14f1,
- .device = 0x8852,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_DEVICE(0x14f1, 0x8852),
}, {
/* CX23887 Rev 2 */
- .vendor = 0x14f1,
- .device = 0x8880,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_DEVICE(0x14f1, 0x8880),
}, {
/* --- end of list --- */
}
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 4fdc59aaed8e..f963ae79f685 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -681,8 +681,8 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device,
*/
static const struct pci_device_id __maybe_unused cx25821_audio_pci_tbl[] = {
- {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ { PCI_DEVICE(0x14f1, 0x0920) },
+ { }
};
MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c
index 5acb1dc00ae8..f883a779b570 100644
--- a/drivers/media/pci/cx25821/cx25821-core.c
+++ b/drivers/media/pci/cx25821/cx25821-core.c
@@ -1347,16 +1347,10 @@ static void cx25821_finidev(struct pci_dev *pci_dev)
static const struct pci_device_id cx25821_pci_tbl[] = {
{
/* CX25821 Athena */
- .vendor = 0x14f1,
- .device = 0x8210,
- .subvendor = 0x14f1,
- .subdevice = 0x0920,
+ PCI_DEVICE_SUB(0x14f1, 0x8210, 0x14f1, 0x0920),
}, {
/* CX25821 No Brand */
- .vendor = 0x14f1,
- .device = 0x8210,
- .subvendor = 0x0000,
- .subdevice = 0x0000,
+ PCI_DEVICE_SUB(0x14f1, 0x8210, 0x0000, 0x0000),
}, {
/* --- end of list --- */
}
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index dce041a5e47a..d2534f90cfba 100644
--- a/drivers/media/pci/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -809,9 +809,9 @@ static const struct snd_kcontrol_new snd_cx88_alc_switch = {
*/
static const struct pci_device_id cx88_audio_pci_tbl[] = {
- {0x14f1, 0x8801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0x14f1, 0x8811, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0, }
+ { PCI_DEVICE(0x14f1, 0x8801) },
+ { PCI_DEVICE(0x14f1, 0x8811) },
+ { }
};
MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl);
diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c
index 676160e9554d..a399a9bf3b92 100644
--- a/drivers/media/pci/cx88/cx88-mpeg.c
+++ b/drivers/media/pci/cx88/cx88-mpeg.c
@@ -787,10 +787,7 @@ static void cx8802_remove(struct pci_dev *pci_dev)
static const struct pci_device_id cx8802_pci_tbl[] = {
{
- .vendor = 0x14f1,
- .device = 0x8802,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_DEVICE(0x14f1, 0x8802),
}, {
/* --- end of list --- */
}
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index c78b156c5cda..eaa46a2f92e7 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1610,10 +1610,7 @@ static int __maybe_unused cx8800_resume(struct device *dev_d)
static const struct pci_device_id cx8800_pci_tbl[] = {
{
- .vendor = 0x14f1,
- .device = 0x8800,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_DEVICE(0x14f1, 0x8800),
}, {
/* --- end of list --- */
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c
index 363badab7cf0..248ace29e5c8 100644
--- a/drivers/media/pci/ddbridge/ddbridge-main.c
+++ b/drivers/media/pci/ddbridge/ddbridge-main.c
@@ -269,7 +269,7 @@ static const struct pci_device_id ddb_id_table[] = {
DDB_DEVICE_ANY(0x0323),
DDB_DEVICE_ANY(0x0328),
DDB_DEVICE_ANY(0x0329),
- {0}
+ { }
};
MODULE_DEVICE_TABLE(pci, ddb_id_table);
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index f01ecdb0b627..cf50898f9a92 100644
--- a/drivers/media/pci/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
@@ -14,7 +14,7 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dvb/ca.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 80d2e143384b..ae4544042a74 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -1209,15 +1209,9 @@ static void dm1105_remove(struct pci_dev *pdev)
static const struct pci_device_id dm1105_id_table[] = {
{
- .vendor = PCI_VENDOR_ID_TRIGEM,
- .device = PCI_DEVICE_ID_DM1105,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_VDEVICE(TRIGEM, PCI_DEVICE_ID_DM1105),
}, {
- .vendor = PCI_VENDOR_ID_AXESS,
- .device = PCI_DEVICE_ID_DM05,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_VDEVICE(AXESS, PCI_DEVICE_ID_DM05),
}, {
/* empty */
},
diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c
index 7bddcbba4cf1..660aab6b62e0 100644
--- a/drivers/media/pci/dt3155/dt3155.c
+++ b/drivers/media/pci/dt3155/dt3155.c
@@ -577,8 +577,8 @@ static void dt3155_remove(struct pci_dev *pdev)
}
static const struct pci_device_id pci_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, DT3155_DEVICE_ID) },
- { 0, /* zero marks the end */ },
+ { PCI_VDEVICE(INTEL, DT3155_DEVICE_ID) },
+ { /* zero marks the end */ },
};
MODULE_DEVICE_TABLE(pci, pci_ids);
diff --git a/drivers/media/pci/hws/hws_v4l2_ioctl.h b/drivers/media/pci/hws/hws_v4l2_ioctl.h
index 53044f78d6fa..9a81e940e33e 100644
--- a/drivers/media/pci/hws/hws_v4l2_ioctl.h
+++ b/drivers/media/pci/hws/hws_v4l2_ioctl.h
@@ -17,14 +17,10 @@ int hws_vidioc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *setfp
int hws_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i);
int hws_vidioc_g_input(struct file *file, void *priv, unsigned int *i);
int hws_vidioc_s_input(struct file *file, void *priv, unsigned int i);
-int hws_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *a);
-int hws_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a);
int hws_vidioc_dv_timings_cap(struct file *file, void *fh,
struct v4l2_dv_timings_cap *cap);
int hws_vidioc_s_dv_timings(struct file *file, void *fh,
struct v4l2_dv_timings *timings);
-
-int hws_vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
int hws_vidioc_g_dv_timings(struct file *file, void *fh,
struct v4l2_dv_timings *timings);
int hws_vidioc_enum_dv_timings(struct file *file, void *fh,
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index 88581a4c081d..42a309e7218e 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -97,6 +97,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = {
IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000),
/* Sony IMX471 */
IPU_SENSOR_CONFIG("SONY471A", 1, 200000000),
+ /* Sony IMX471 (found on Lenovo X1 Carbon G14) */
+ IPU_SENSOR_CONFIG("TBE20A0", 1, 200000000),
/* Toshiba T4KA3 */
IPU_SENSOR_CONFIG("XMCC0003", 1, 321468000),
};
@@ -134,6 +136,52 @@ static const struct dmi_system_id upside_down_sensor_dmi_ids[] = {
},
.driver_data = "OVTI02C1",
},
+ {
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS 16 (Dell 16 Premium) DA16250"),
+ },
+ .driver_data = "OVTI02C1",
+ },
+ /*
+ * The first four characters of DMI_BOARD_NAME identify the Lenovo
+ * machine type/model. For example, a DMI_BOARD_NAME starting with
+ * "21Q6" indicates a ThinkPad X9-15.
+ *
+ * Reference: https://psref.lenovo.com/
+ */
+ {
+ /* Lenovo X9-14 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "21QA"),
+ },
+ .driver_data = "SONY471A",
+ },
+ {
+ /* Lenovo X9-14 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "21QB"),
+ },
+ .driver_data = "SONY471A",
+ },
+ {
+ /* Lenovo X9-15 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "21Q6"),
+ },
+ .driver_data = "SONY471A",
+ },
+ {
+ /* Lenovo X9-15 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "21Q7"),
+ },
+ .driver_data = "SONY471A",
+ },
{} /* Terminating entry */
};
@@ -171,6 +219,7 @@ static const struct acpi_device_id ivsc_acpi_ids[] = {
{ "INTC10DE" }, /* LNL */
{ "INTC10E0" }, /* ARL */
{ "INTC10E1" }, /* PTL */
+ { "INTC10FA" }, /* NVL */
};
static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
@@ -180,8 +229,8 @@ static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev
for (i = 0; i < ARRAY_SIZE(ivsc_acpi_ids); i++) {
const struct acpi_device_id *acpi_id = &ivsc_acpi_ids[i];
struct acpi_device *consumer, *ivsc_adev;
-
acpi_handle handle = acpi_device_handle(ACPI_PTR(adev));
+
for_each_acpi_dev_match(ivsc_adev, acpi_id->id, NULL, -1)
/* camera sensor depends on IVSC in DSDT if exist */
for_each_acpi_consumer_dev(ivsc_adev, consumer)
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
index 986b9afd7cb5..eb1824ee86fd 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -1961,7 +1961,7 @@ static const struct dev_pm_ops cio2_pm_ops = {
};
static const struct pci_device_id cio2_pci_id_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, CIO2_PCI_ID) },
+ { PCI_VDEVICE(INTEL, CIO2_PCI_ID) },
{ }
};
diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c
index d033d4618169..5449a2006bcc 100644
--- a/drivers/media/pci/intel/ipu6/ipu6.c
+++ b/drivers/media/pci/intel/ipu6/ipu6.c
@@ -400,7 +400,6 @@ ipu6_isys_init(struct pci_dev *pdev, struct device *parent,
&ipdata->hw_variant);
if (IS_ERR(isys_adev->mmu)) {
put_device(&isys_adev->auxdev.dev);
- kfree(pdata);
return dev_err_cast_probe(dev, isys_adev->mmu,
"ipu6_mmu_init(isys_adev->mmu) failed\n");
}
@@ -408,10 +407,8 @@ ipu6_isys_init(struct pci_dev *pdev, struct device *parent,
isys_adev->mmu->dev = &isys_adev->auxdev.dev;
ret = ipu6_bus_add_device(isys_adev);
- if (ret) {
- kfree(pdata);
+ if (ret)
return ERR_PTR(ret);
- }
return isys_adev;
}
@@ -444,7 +441,6 @@ ipu6_psys_init(struct pci_dev *pdev, struct device *parent,
&ipdata->hw_variant);
if (IS_ERR(psys_adev->mmu)) {
put_device(&psys_adev->auxdev.dev);
- kfree(pdata);
return dev_err_cast_probe(&pdev->dev, psys_adev->mmu,
"ipu6_mmu_init(psys_adev->mmu) failed\n");
}
@@ -452,10 +448,8 @@ ipu6_psys_init(struct pci_dev *pdev, struct device *parent,
psys_adev->mmu->dev = &psys_adev->auxdev.dev;
ret = ipu6_bus_add_device(psys_adev);
- if (ret) {
- kfree(pdata);
+ if (ret)
return ERR_PTR(ret);
- }
return psys_adev;
}
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index e0091a8e5c88..b9ea56ec9593 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -60,11 +60,9 @@ EXPORT_SYMBOL(ivtv_ext_init);
/* add your revision and whatnot here */
static const struct pci_device_id ivtv_pci_tbl[] = {
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV15,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_ICOMP, PCI_DEVICE_ID_IVTV16,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
+ { PCI_VDEVICE(ICOMP, PCI_DEVICE_ID_IVTV15) },
+ { PCI_VDEVICE(ICOMP, PCI_DEVICE_ID_IVTV16) },
+ { }
};
MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
diff --git a/drivers/media/pci/ivtv/ivtv-vbi.c b/drivers/media/pci/ivtv/ivtv-vbi.c
index ae7a00f46257..af086c4cbe1a 100644
--- a/drivers/media/pci/ivtv/ivtv-vbi.c
+++ b/drivers/media/pci/ivtv/ivtv-vbi.c
@@ -330,7 +330,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
unsigned lines = 0;
/* find the first valid line */
- for (i = 0; i < size; i++, buf++) {
+ for (i = 0; i + 3 < size; i++, buf++) {
if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
break;
}
diff --git a/drivers/media/pci/mantis/mantis_common.h b/drivers/media/pci/mantis/mantis_common.h
index 6e563ecd94e8..f357ca268dd1 100644
--- a/drivers/media/pci/mantis/mantis_common.h
+++ b/drivers/media/pci/mantis/mantis_common.h
@@ -58,11 +58,9 @@
#define TERRATEC 0x153b
#define MAKE_ENTRY(__subven, __subdev, __configptr, __rc) { \
- .vendor = TWINHAN_TECHNOLOGIES, \
- .device = MANTIS, \
- .subvendor = (__subven), \
- .subdevice = (__subdev), \
- .driver_data = (unsigned long) \
+ PCI_DEVICE_SUB(TWINHAN_TECHNOLOGIES, MANTIS, \
+ (__subven), (__subdev)), \
+ .driver_data = (unsigned long) \
&(struct mantis_pci_drvdata){__configptr, __rc} \
}
diff --git a/drivers/media/pci/mgb4/mgb4_core.c b/drivers/media/pci/mgb4/mgb4_core.c
index d23d854581c5..cbd193e06536 100644
--- a/drivers/media/pci/mgb4/mgb4_core.c
+++ b/drivers/media/pci/mgb4/mgb4_core.c
@@ -694,9 +694,9 @@ static void mgb4_remove(struct pci_dev *pdev)
}
static const struct pci_device_id mgb4_pci_ids[] = {
- { PCI_DEVICE(DIGITEQ_VID, T100_DID), },
- { PCI_DEVICE(DIGITEQ_VID, T200_DID), },
- { 0, }
+ { PCI_DEVICE(DIGITEQ_VID, T100_DID) },
+ { PCI_DEVICE(DIGITEQ_VID, T200_DID) },
+ { }
};
MODULE_DEVICE_TABLE(pci, mgb4_pci_ids);
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index ec08023b5d5e..00f81e4c8e8d 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -1014,7 +1014,7 @@ static void netup_unidvb_finidev(struct pci_dev *pci_dev)
static const struct pci_device_id netup_unidvb_pci_tbl[] = {
{ PCI_DEVICE(0x1b55, 0x18f6) }, /* hw rev. 1.3 */
{ PCI_DEVICE(0x1b55, 0x18f7) }, /* hw rev. 1.4 */
- { 0, }
+ { }
};
MODULE_DEVICE_TABLE(pci, netup_unidvb_pci_tbl);
diff --git a/drivers/media/pci/ngene/ngene-cards.c b/drivers/media/pci/ngene/ngene-cards.c
index 7dbc21e1a2ca..a1a83f3bb6b4 100644
--- a/drivers/media/pci/ngene/ngene-cards.c
+++ b/drivers/media/pci/ngene/ngene-cards.c
@@ -1155,8 +1155,7 @@ static const struct ngene_info ngene_info_terratec = {
/****************************************************************************/
#define NGENE_ID(_subvend, _subdev, _driverdata) { \
- .vendor = NGENE_VID, .device = NGENE_PID, \
- .subvendor = _subvend, .subdevice = _subdev, \
+ PCI_DEVICE_SUB(NGENE_VID, NGENE_PID, (_subvend), (_subdev)), \
.driver_data = (unsigned long) &_driverdata }
/****************************************************************************/
@@ -1173,7 +1172,7 @@ static const struct pci_device_id ngene_id_tbl[] = {
NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
NGENE_ID(0x1461, 0x062e, ngene_info_m780),
NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
- {0}
+ { }
};
MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index 22c2222d5c4d..77b3e4eec54d 100644
--- a/drivers/media/pci/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
@@ -762,10 +762,7 @@ static void pluto2_remove(struct pci_dev *pdev)
static const struct pci_device_id pluto2_id_table[] = {
{
- .vendor = PCI_VENDOR_ID_SCM,
- .device = PCI_DEVICE_ID_PLUTO2,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_VDEVICE(SCM, PCI_DEVICE_ID_PLUTO2),
}, {
/* empty */
},
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index e80fb4ebfda6..a7d665407460 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -5800,1317 +5800,758 @@ const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
struct pci_device_id saa7134_pci_tbl[] = {
{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_PROTEUS_PRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x6752,
- .driver_data = SAA7134_BOARD_EMPRESS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x4e85,
- .driver_data = SAA7134_BOARD_MONSTERTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1142,
- .driver_data = SAA7134_BOARD_CINERGY400,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1143,
- .driver_data = SAA7134_BOARD_CINERGY600,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x153b,
- .subdevice = 0x1158,
- .driver_data = SAA7134_BOARD_CINERGY600_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1162,
- .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5169,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x4e42, /* "Typhoon PCI Capture TV Card" Art.No. 50673 */
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO3000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5168,
- .subdevice = 0x0138,
- .driver_data = SAA7134_BOARD_FLYVIDEO2000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x4e42, /* Typhoon */
- .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
- .driver_data = SAA7134_BOARD_FLYVIDEO2000,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0212, /* minipci, LR212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x14c0,
- .subdevice = 0x1212, /* minipci, LR1212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42,
- .subdevice = 0x0212, /* OEM minipci, LR212 */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0214, /* Standard PCI, LR214 Rev E and earlier (SAA7135) */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x5214, /* Standard PCI, LR214 Rev F onwards (SAA7131) */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1489, /* KYE */
- .subdevice = 0x0214, /* Genius VideoWonder ProTV */
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be,
- .subdevice = 0x0003,
- .driver_data = SAA7134_BOARD_MD7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be, /* CTX946 analog TV, HW mpeg, DVB-T */
- .subdevice = 0x5000, /* only analog TV and DVB-T for now */
- .driver_data = SAA7134_BOARD_MD7134,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226b,
- .driver_data = SAA7134_BOARD_ELSA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226a,
- .driver_data = SAA7134_BOARD_ELSA_500TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1048,
- .subdevice = 0x226c,
- .driver_data = SAA7134_BOARD_ELSA_700TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4842,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4845,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7135,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4830,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4843,
- .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_ASUSTEK,
- .subdevice = 0x4840,
- .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0xfe01,
- .driver_data = SAA7134_BOARD_TVSTATION_RDS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1894,
- .subdevice = 0xfe01,
- .driver_data = SAA7134_BOARD_TVSTATION_RDS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1894,
- .subdevice = 0xa006,
- .driver_data = SAA7134_BOARD_TVSTATION_DVR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1131,
- .subdevice = 0x7133,
- .driver_data = SAA7134_BOARD_VA1000POWER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2001,
- .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_MATROX,
- .subdevice = 0x48d0,
- .driver_data = SAA7134_BOARD_CRONOS_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa70b,
- .driver_data = SAA7134_BOARD_MD2819,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa7a1,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A700_PRO,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa7a2,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A700_HYBRID,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2115,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa115,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_505,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2108,
- .driver_data = SAA7134_BOARD_AVERMEDIA_305,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x10ff,
- .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
- },{
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_PHILIPS, 0x2001),
+ .driver_data = SAA7134_BOARD_PROTEUS_PRO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133,
+ PCI_VENDOR_ID_PHILIPS, 0x2001),
+ .driver_data = SAA7134_BOARD_PROTEUS_PRO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_PHILIPS, 0x6752),
+ .driver_data = SAA7134_BOARD_EMPRESS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1131, 0x4e85),
+ .driver_data = SAA7134_BOARD_MONSTERTV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x153b, 0x1142),
+ .driver_data = SAA7134_BOARD_CINERGY400,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x153b, 0x1143),
+ .driver_data = SAA7134_BOARD_CINERGY600,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x153b, 0x1158),
+ .driver_data = SAA7134_BOARD_CINERGY600_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x153b, 0x1162),
+ .driver_data = SAA7134_BOARD_CINERGY400_CARDBUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5169, 0x0138),
+ .driver_data = SAA7134_BOARD_FLYVIDEO3000_NTSC,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5168, 0x0138),
+ .driver_data = SAA7134_BOARD_FLYVIDEO3000,
+ }, {
+ /* "Typhoon PCI Capture TV Card" Art.No. 50673 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x4e42, 0x0138),
+ .driver_data = SAA7134_BOARD_FLYVIDEO3000,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x5168, 0x0138),
+ .driver_data = SAA7134_BOARD_FLYVIDEO2000,
+ }, {
+ /* Typhoon LifeView FlyTV Prime30 OEM */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x4e42, 0x0138),
+ .driver_data = SAA7134_BOARD_FLYVIDEO2000,
+ }, {
+ /* minipci, LR212 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0212),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
+ }, {
+ /* minipci, LR1212 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x14c0, 0x1212),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
+ }, {
+ /* OEM minipci, LR212 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x4e42, 0x0212),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
+ }, {
+ /*
+ * Animation Technologies (LifeView)
+ * Standard PCI, LR214 Rev E and earlier (SAA7135)
+ */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0214),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
+ }, {
+ /*
+ * Animation Technologies (LifeView)
+ * Standard PCI, LR214 Rev F onwards (SAA7131)
+ */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x5214),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
+ }, {
+ /* KYE Genius VideoWonder ProTV */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1489, 0x0214),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x16be, 0x0003),
+ .driver_data = SAA7134_BOARD_MD7134,
+ }, {
+ /* CTX946 analog TV, HW mpeg, DVB-T; only analog TV and DVB-T for now */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x16be, 0x5000),
+ .driver_data = SAA7134_BOARD_MD7134,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1048, 0x226b),
+ .driver_data = SAA7134_BOARD_ELSA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1048, 0x226a),
+ .driver_data = SAA7134_BOARD_ELSA_500TV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1048, 0x226c),
+ .driver_data = SAA7134_BOARD_ELSA_700TV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_ASUSTEK, 0x4842),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133,
+ PCI_VENDOR_ID_ASUSTEK, 0x4845),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7135,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_ASUSTEK, 0x4830),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133,
+ PCI_VENDOR_ID_ASUSTEK, 0x4843),
+ .driver_data = SAA7134_BOARD_ASUSTEK_TVFM7133,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_ASUSTEK, 0x4840),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_PHILIPS, 0xfe01),
+ .driver_data = SAA7134_BOARD_TVSTATION_RDS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1894, 0xfe01),
+ .driver_data = SAA7134_BOARD_TVSTATION_RDS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1894, 0xa006),
+ .driver_data = SAA7134_BOARD_TVSTATION_DVR,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1131, 0x7133),
+ .driver_data = SAA7134_BOARD_VA1000POWER,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_PHILIPS, 0x2001),
+ .driver_data = SAA7134_BOARD_10MOONSTVMASTER,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x185b, 0xc100),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_TV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x185b, 0xc100),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_MATROX, 0x48d0),
+ .driver_data = SAA7134_BOARD_CRONOS_PLUS,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0xa70b),
+ .driver_data = SAA7134_BOARD_MD2819,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xa7a1),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A700_PRO,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xa7a2),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A700_HYBRID,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0x2115),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0xa115),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_505,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0x2108),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_305,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0x10ff),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
+ }, {
/* AVerMedia CardBus */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xd6ee,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
- },{
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0xd6ee),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS,
+ }, {
/* AVerMedia CardBus */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xb7e9,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0xb7e9),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_501,
}, {
- /* TransGear 3000TV */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x050c,
- .driver_data = SAA7134_BOARD_TG3000TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002b,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x11bd,
- .subdevice = 0x002d,
- .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1019,
- .subdevice = 0x4cb4,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1019,
- .subdevice = 0x4cb5,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1019,
- .subdevice = 0x4cb6,
- .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x12ab,
- .subdevice = 0x0800,
- .driver_data = SAA7134_BOARD_UPMOST_PURPLE_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x153b,
- .subdevice = 0x1152,
- .driver_data = SAA7134_BOARD_CINERGY200,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc100,
- .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x9715,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa70a,
- .driver_data = SAA7134_BOARD_AVERMEDIA_307,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x185b,
- .subdevice = 0xc200,
- .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1540,
- .subdevice = 0x9524,
- .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0502, /* Cardbus version */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x0306, /* PCI version */
- .driver_data = SAA7134_BOARD_FLYDVBTDUO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31f,
- .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf11d,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M135A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x4155,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x4255,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_PHILIPS_TOUGH,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0350, /* PCI version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0351, /* PCI version, new revision */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x0370, /* cardbus version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1421,
- .subdevice = 0x1370, /* cardbus version */
- .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42, /* Typhoon */
- .subdevice = 0x0502, /* LifeView LR502 OEM */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x0210, /* mini pci NTSC version */
- .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x0210, /* mini pci PAL/SECAM version */
- .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
-
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
- .subdevice = 0x4091,
- .driver_data = SAA7134_BOARD_BEHOLD_409FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5456, /* GoTView */
- .subdevice = 0x7135,
- .driver_data = SAA7134_BOARD_GOTVIEW_7135,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc901,
- .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1435,
- .subdevice = 0x7350,
- .driver_data = SAA7134_BOARD_RTD_VFG7350,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1435,
- .subdevice = 0x7330,
- .driver_data = SAA7134_BOARD_RTD_VFG7330,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461,
- .subdevice = 0x1044,
- .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1131,
- .subdevice = 0x4ee9,
- .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x11bd,
- .subdevice = 0x002e,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4862,
- .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2018,
- .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462,
- .subdevice = 0x6231, /* tda8275a, ks003 IR */
- .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462,
- .subdevice = 0x8624, /* tda8275, ks003 IR */
- .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1160,
- .driver_data = SAA7134_BOARD_CINERGY250PCI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA 7131E */
- .subvendor = 0x5168,
- .subdevice = 0x0319,
- .driver_data = SAA7134_BOARD_FLYDVB_TRIO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x2c05,
- .driver_data = SAA7134_BOARD_AVERMEDIA_777,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0301,
- .driver_data = SAA7134_BOARD_FLYDVBT_LR301,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0331,
- .subdevice = 0x1421,
- .driver_data = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0x7201,
- .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0x7250,
- .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0x7350,
- .driver_data = SAA7134_BOARD_KWORLD_ATSC110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0x7352,
- .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x17de,
- .subdevice = 0xa134,
- .driver_data = SAA7134_BOARD_KWORLD_PC150U,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x7360,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x6360,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B1,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x16be,
- .subdevice = 0x0005,
- .driver_data = SAA7134_BOARD_MD7134_BRIDGE_2,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5168,
- .subdevice = 0x0300,
- .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x4e42,
- .subdevice = 0x0300,/* LR300 */
- .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1489,
- .subdevice = 0x0301,
+ /* AVerMedia TransGear 3000TV */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0x050c),
+ .driver_data = SAA7134_BOARD_TG3000TV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x11bd, 0x002b),
+ .driver_data = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x11bd, 0x002d),
+ .driver_data = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1019, 0x4cb4),
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1019, 0x4cb5),
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1019, 0x4cb6),
+ .driver_data = SAA7134_BOARD_ECS_TVP3XP_4CB6,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x12ab, 0x0800),
+ .driver_data = SAA7134_BOARD_UPMOST_PURPLE_TV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x153b, 0x1152),
+ .driver_data = SAA7134_BOARD_CINERGY200,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x185b, 0xc100),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_TV_PVR,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0x9715),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0xa70a),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_307,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x185b, 0xc200),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1540, 0x9524),
+ .driver_data = SAA7134_BOARD_PROVIDEO_PV952,
+ }, {
+ /* Cardbus version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0502),
+ .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
+ }, {
+ /* PCI version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0306),
+ .driver_data = SAA7134_BOARD_FLYDVBTDUO,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf31f),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf11d),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M135A,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x4155),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x4255),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M733A,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_PHILIPS, 0x2004),
+ .driver_data = SAA7134_BOARD_PHILIPS_TOUGH,
+ }, {
+ /* PCI version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1421, 0x0350),
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+ }, {
+ /* PCI version, new revision */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1421, 0x0351),
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+ }, {
+ /* cardbus version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1421, 0x0370),
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+ }, {
+ /* cardbus version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1421, 0x1370),
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+ }, {
+ /* Typhoon LifeView LR502 OEM */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x4e42, 0x0502),
+ .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
+ }, {
+ /* mini pci NTSC version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x0210),
+ .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX,
+ }, {
+ /* mini pci PAL/SECAM version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1043, 0x0210),
+ .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
+ }, {
+ /* subvendor == 0 shouldn't break anything, since subdevice id seems unique */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0000, 0x4091),
+ .driver_data = SAA7134_BOARD_BEHOLD_409FM,
+ }, {
+ /* GoTView */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5456, 0x7135),
+ .driver_data = SAA7134_BOARD_GOTVIEW_7135,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_PHILIPS, 0x2004),
+ .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x185b, 0xc900),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x185b, 0xc901),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1435, 0x7350),
+ .driver_data = SAA7134_BOARD_RTD_VFG7350,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1435, 0x7330),
+ .driver_data = SAA7134_BOARD_RTD_VFG7330,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x1044),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1131, 0x4ee9),
+ .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x11bd, 0x002e),
+ .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x4862),
+ .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133,
+ PCI_VENDOR_ID_PHILIPS, 0x2018),
+ .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
+ }, {
+ /* tda8275a, ks003 IR */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1462, 0x6231),
+ .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
+ }, {
+ /* tda8275, ks003 IR */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1462, 0x8624),
+ .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x153b, 0x1160),
+ .driver_data = SAA7134_BOARD_CINERGY250PCI,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0319),
+ .driver_data = SAA7134_BOARD_FLYDVB_TRIO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0x2c05),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_777,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5168, 0x0301),
.driver_data = SAA7134_BOARD_FLYDVBT_LR301,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168, /* Animation Technologies (LifeView) */
- .subdevice = 0x0304,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0331, 0x1421),
+ .driver_data = SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0x7201),
+ .driver_data = SAA7134_BOARD_TEVION_DVBT_220RF,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0x7250),
+ .driver_data = SAA7134_BOARD_KWORLD_DVBT_210,
+ }, {
+ /* SAA7135HL */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0x7350),
+ .driver_data = SAA7134_BOARD_KWORLD_ATSC110,
+ }, {
+ /* SAA7135HL */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0x7352),
+ .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
+ }, {
+ /* SAA7135HL */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0xa134),
+ .driver_data = SAA7134_BOARD_KWORLD_PC150U,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0x7360),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0x6360),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A169_B1,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x16be, 0x0005),
+ .driver_data = SAA7134_BOARD_MD7134_BRIDGE_2,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5168, 0x0300),
+ .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
+ }, {
+ /* LR300 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x4e42, 0x0300),
+ .driver_data = SAA7134_BOARD_FLYDVBS_LR300,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1489, 0x0301),
+ .driver_data = SAA7134_BOARD_FLYDVBT_LR301,
+ }, {
+ /* Animation Technologies (LifeView) */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x0304),
.driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3306,
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3502, /* what's the difference to 0x3306 ?*/
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5168,
- .subdevice = 0x3307, /* FlyDVB-T Hybrid Mini PCI */
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0007,
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0008,
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x000d, /* triple CTX948_V1.1.1 */
- .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461,
- .subdevice = 0x2c05,
- .driver_data = SAA7134_BOARD_AVERMEDIA_777,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1489,
- .subdevice = 0x0502, /* Cardbus version */
- .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0919, /* Philips Proteus PRO 2309 */
- .subdevice = 0x2003,
- .driver_data = SAA7134_BOARD_PROTEUS_2309,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461,
- .subdevice = 0x2c00,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A16AR,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x4860,
- .driver_data = SAA7134_BOARD_ASUS_EUROPA2_HYBRID,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x11bd,
- .subdevice = 0x002f,
- .driver_data = SAA7134_BOARD_PINNACLE_PCTV_310i,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x9715,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa11b,
- .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4876,
- .driver_data = SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6700,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6701,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6702,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6703,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6704,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6705,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6706,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6707,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6708,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x6709,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0070,
- .subdevice = 0x670a,
- .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1172,
- .driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2342,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0x2341,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x3016,
- .subdevice = 0x2344,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1131,
- .subdevice = 0x230f,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1a7f,
- .subdevice = 0x2008,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1a7f,
- .subdevice = 0x2108,
- .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM3,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x153b,
- .subdevice = 0x1175,
- .driver_data = SAA7134_BOARD_CINERGY_HT_PCI,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31e,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M102,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4E42, /* MSI */
- .subdevice = 0x0306, /* TV@nywhere DUO */
- .driver_data = SAA7134_BOARD_FLYDVBTDUO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4871,
- .driver_data = SAA7134_BOARD_ASUS_P7131_4871,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4857, /* REV:1.00 */
- .driver_data = SAA7134_BOARD_ASUSTeK_TIGER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0919, /* SinoVideo PCI 2309 Proteus (7134) */
- .subdevice = 0x2003, /* OEM cardbus */
- .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2304,
- .driver_data = SAA7134_BOARD_10MOONSTVMASTER3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf01d, /* AVerTV DVB-T Super 007 */
- .driver_data = SAA7134_BOARD_AVERMEDIA_SUPER_007,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4016,
- .driver_data = SAA7134_BOARD_BEHOLD_401,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4036,
- .driver_data = SAA7134_BOARD_BEHOLD_403,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4037,
- .driver_data = SAA7134_BOARD_BEHOLD_403FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4050,
- .driver_data = SAA7134_BOARD_BEHOLD_405,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x4051,
- .driver_data = SAA7134_BOARD_BEHOLD_405FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4070,
- .driver_data = SAA7134_BOARD_BEHOLD_407,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x0000,
- .subdevice = 0x4071,
- .driver_data = SAA7134_BOARD_BEHOLD_407FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x4090,
- .driver_data = SAA7134_BOARD_BEHOLD_409,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x505B,
- .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK5,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x0000,
- .subdevice = 0x5051,
- .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5ace,
- .subdevice = 0x5050,
- .driver_data = SAA7134_BOARD_BEHOLD_505FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x5071,
- .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x507B,
- .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x5070,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x5090,
- .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x0000,
- .subdevice = 0x5201,
- .driver_data = SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6070,
- .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6071,
- .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6072,
- .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x5ace,
- .subdevice = 0x6073,
- .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6090,
- .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6091,
- .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6092,
- .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6093,
- .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6190,
- .driver_data = SAA7134_BOARD_BEHOLD_M6,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6193,
- .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6191,
- .driver_data = SAA7134_BOARD_BEHOLD_M63,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x4e42,
- .subdevice = 0x3502,
- .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1822, /*Twinhan Technology Co. Ltd*/
- .subdevice = 0x0022,
- .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x16be,
- .subdevice = 0x0010, /* Medion version CTX953_V.1.4.3 */
- .driver_data = SAA7134_BOARD_CREATIX_CTX953,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462, /* MSI */
- .subdevice = 0x8625, /* TV@nywhere A/D v1.1 */
- .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_AD11,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf436,
- .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_506,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf936,
- .driver_data = SAA7134_BOARD_AVERMEDIA_A16D,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa836,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M115,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_T750,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
- .subvendor = 0x1421,
- .subdevice = 0x0380,
- .driver_data = SAA7134_BOARD_ADS_INSTANT_HDTV_PCI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5169,
- .subdevice = 0x1502,
- .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x6290,
- .driver_data = SAA7134_BOARD_BEHOLD_H6,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf636,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf736,
- .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x4878, /* REV:1.02G */
- .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1043,
- .subdevice = 0x48cd,
- .driver_data = SAA7134_BOARD_ASUSTeK_PS3_100,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x17de,
- .subdevice = 0x7128,
- .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x17de,
- .subdevice = 0xb136,
- .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xf31d,
- .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_S350,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7595,
- .driver_data = SAA7134_BOARD_BEHOLD_X7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x19d1, /* RoverMedia */
- .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
- .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0x2004,
- .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x1043,
- .subdevice = 0x4847,
- .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x107d,
- .subdevice = 0x6655,
- .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x13c2,
- .subdevice = 0x2804,
- .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7190,
- .driver_data = SAA7134_BOARD_BEHOLD_H7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace, /* Beholder Intl. Ltd. */
- .subdevice = 0x7090,
- .driver_data = SAA7134_BOARD_BEHOLD_A7,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = 0x185b,
- .subdevice = 0xc900,
- .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x5ace,
- .subdevice = 0x5030,
- .driver_data = SAA7134_BOARD_BEHOLD_503FM,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x5ace,
- .subdevice = 0x5010,
- .driver_data = SAA7134_BOARD_BEHOLD_501,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = 0x17de,
- .subdevice = 0xd136,
- .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x6000,
- .subdevice = 0x0811,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x6000,
- .subdevice = 0x0911,
- .driver_data = SAA7134_BOARD_SENSORAY811_911,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0x2055, /* AverTV Satellite Hybrid+FM A706 */
- .driver_data = SAA7134_BOARD_AVERMEDIA_A706,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1905, /* WIS */
- .subdevice = 0x7007,
- .driver_data = SAA7134_BOARD_WIS_VOYAGER,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x1461, /* Avermedia Technologies Inc */
- .subdevice = 0xa10a,
- .driver_data = SAA7134_BOARD_AVERMEDIA_505,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = 0x107d,
- .subdevice = 0x6f3a,
- .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1779, /* V One Multimedia PTE Ltd */
- .subdevice = 0x13cf,
- .driver_data = SAA7134_BOARD_SNAZIO_TVPVR_PRO,
- }, {
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x107d,
- .subdevice = 0x6f2e,
- .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_HDTV200_H,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x3306),
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ /* what's the difference to .subdevice = 0x3306 above? */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x3502),
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ /* FlyDVB-T Hybrid Mini PCI */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5168, 0x3307),
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x16be, 0x0007),
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x16be, 0x0008),
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ }, {
+ /* triple CTX948_V1.1.1 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x16be, 0x000d),
+ .driver_data = SAA7134_BOARD_MEDION_MD8800_QUADRO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x2c05),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_777,
+ }, {
+ /* Cardbus version */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1489, 0x0502),
+ .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
+ }, {
+ /* Philips Proteus PRO 2309 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0919, 0x2003),
+ .driver_data = SAA7134_BOARD_PROTEUS_2309,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0x2c00),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A16AR,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1043, 0x4860),
+ .driver_data = SAA7134_BOARD_ASUS_EUROPA2_HYBRID,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x11bd, 0x002f),
+ .driver_data = SAA7134_BOARD_PINNACLE_PCTV_310i,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x9715),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1461, 0xa11b),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507UA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x4876),
+ .driver_data = SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6700),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6701),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6702),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6703),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6704),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6705),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6706),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6707),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6708),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1150,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x6709),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0070, 0x670a),
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x153b, 0x1172),
+ .driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_PHILIPS, 0x2342),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1131, 0x2341),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x3016, 0x2344),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1131, 0x230f),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1a7f, 0x2008),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1a7f, 0x2108),
+ .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x153b, 0x1175),
+ .driver_data = SAA7134_BOARD_CINERGY_HT_PCI,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf31e),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M102,
+ }, {
+ /* MSI TV@nywhere DUO */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x4E42, 0x0306),
+ .driver_data = SAA7134_BOARD_FLYDVBTDUO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x4871),
+ .driver_data = SAA7134_BOARD_ASUS_P7131_4871,
+ }, {
+ /* REV:1.00 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x4857),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TIGER,
+ }, {
+ /* SinoVideo PCI 2309 Proteus (7134) OEM cardbus */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x0919, 0x2003),
+ .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_PHILIPS, 0x2304),
+ .driver_data = SAA7134_BOARD_10MOONSTVMASTER3,
+ }, {
+ /* Avermedia Technologies Inc AVerTV DVB-T Super 007 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf01d),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_SUPER_007,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0000, 0x4016),
+ .driver_data = SAA7134_BOARD_BEHOLD_401,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x0000, 0x4036),
+ .driver_data = SAA7134_BOARD_BEHOLD_403,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x0000, 0x4037),
+ .driver_data = SAA7134_BOARD_BEHOLD_403FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0000, 0x4050),
+ .driver_data = SAA7134_BOARD_BEHOLD_405,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0000, 0x4051),
+ .driver_data = SAA7134_BOARD_BEHOLD_405FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x0000, 0x4070),
+ .driver_data = SAA7134_BOARD_BEHOLD_407,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x0000, 0x4071),
+ .driver_data = SAA7134_BOARD_BEHOLD_407FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0000, 0x4090),
+ .driver_data = SAA7134_BOARD_BEHOLD_409,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0000, 0x505B),
+ .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x0000, 0x5051),
+ .driver_data = SAA7134_BOARD_BEHOLD_505RDS_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x5ace, 0x5050),
+ .driver_data = SAA7134_BOARD_BEHOLD_505FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0000, 0x5071),
+ .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0000, 0x507B),
+ .driver_data = SAA7134_BOARD_BEHOLD_507RDS_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5ace, 0x5070),
+ .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x5090),
+ .driver_data = SAA7134_BOARD_BEHOLD_507_9FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x0000, 0x5201),
+ .driver_data = SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5ace, 0x6070),
+ .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5ace, 0x6071),
+ .driver_data = SAA7134_BOARD_BEHOLD_607FM_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5ace, 0x6072),
+ .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x5ace, 0x6073),
+ .driver_data = SAA7134_BOARD_BEHOLD_607RDS_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6090),
+ .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6091),
+ .driver_data = SAA7134_BOARD_BEHOLD_609FM_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6092),
+ .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK3,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6093),
+ .driver_data = SAA7134_BOARD_BEHOLD_609RDS_MK5,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6190),
+ .driver_data = SAA7134_BOARD_BEHOLD_M6,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6193),
+ .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6191),
+ .driver_data = SAA7134_BOARD_BEHOLD_M63,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x4e42, 0x3502),
+ .driver_data = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS,
+ }, {
+ /*Twinhan Technology Co. Ltd*/
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1822, 0x0022),
+ .driver_data = SAA7134_BOARD_TWINHAN_DTV_DVB_3056,
+ }, {
+ /* Medion version CTX953_V.1.4.3 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x16be, 0x0010),
+ .driver_data = SAA7134_BOARD_CREATIX_CTX953,
+ }, {
+ /* MSI TV@nywhere A/D v1.1 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1462, 0x8625),
+ .driver_data = SAA7134_BOARD_MSI_TVANYWHERE_AD11,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf436),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_CARDBUS_506,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf936),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A16D,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xa836),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M115,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x185b, 0xc900),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_T750,
+ }, {
+ /* SAA7135HL */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1421, 0x0380),
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_HDTV_PCI,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5169, 0x1502),
+ .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x6290),
+ .driver_data = SAA7134_BOARD_BEHOLD_H6,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf636),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf736),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_M103,
+ }, {
+ /* REV:1.02G */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x4878),
+ .driver_data = SAA7134_BOARD_ASUSTeK_TIGER_3IN1,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1043, 0x48cd),
+ .driver_data = SAA7134_BOARD_ASUSTeK_PS3_100,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x17de, 0x7128),
+ .driver_data = SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x17de, 0xb136),
+ .driver_data = SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0xf31d),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x185b, 0xc900),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_S350,
+ }, {
+ /* Beholder Intl. Ltd. */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x7595),
+ .driver_data = SAA7134_BOARD_BEHOLD_X7,
+ }, {
+ /* RoverMedia LifeView FlyTV Prime30 OEM */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x19d1, 0x0138),
+ .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133,
+ PCI_VENDOR_ID_PHILIPS, 0x2004),
+ .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x1043, 0x4847),
+ .driver_data = SAA7134_BOARD_ASUS_EUROPA_HYBRID,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x107d, 0x6655),
+ .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x13c2, 0x2804),
+ .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000,
+ }, {
+ /* Beholder Intl. Ltd. */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x7190),
+ .driver_data = SAA7134_BOARD_BEHOLD_H7,
+ }, {
+ /* Beholder Intl. Ltd. */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x7090),
+ .driver_data = SAA7134_BOARD_BEHOLD_A7,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7135, 0x185b, 0xc900),
+ .driver_data = SAA7134_BOARD_VIDEOMATE_M1F,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x5ace, 0x5030),
+ .driver_data = SAA7134_BOARD_BEHOLD_503FM,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x5ace, 0x5010),
+ .driver_data = SAA7134_BOARD_BEHOLD_501,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134, 0x17de, 0xd136),
+ .driver_data = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x6000, 0x0811),
+ .driver_data = SAA7134_BOARD_SENSORAY811_911,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x6000, 0x0911),
+ .driver_data = SAA7134_BOARD_SENSORAY811_911,
+ }, {
+ /* Avermedia Technologies Inc AverTV Satellite Hybrid+FM A706 */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1461, 0x2055),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_A706,
+ }, {
+ /* WIS */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1905, 0x7007),
+ .driver_data = SAA7134_BOARD_WIS_VOYAGER,
+ }, {
+ /* Avermedia Technologies Inc */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x1461, 0xa10a),
+ .driver_data = SAA7134_BOARD_AVERMEDIA_505,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130, 0x107d, 0x6f3a),
+ .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_TV2100_FM,
+ }, {
+ /* V One Multimedia PTE Ltd */
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x1779, 0x13cf),
+ .driver_data = SAA7134_BOARD_SNAZIO_TVPVR_PRO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133, 0x107d, 0x6f2e),
+ .driver_data = SAA7134_BOARD_LEADTEK_WINFAST_HDTV200_H,
}, {
/* --- boards without eeprom + subsystem ID --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0,
- .driver_data = SAA7134_BOARD_NOAUTO,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_VENDOR_ID_PHILIPS,
- .subdevice = 0,
- .driver_data = SAA7134_BOARD_NOAUTO,
- },{
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134,
+ PCI_VENDOR_ID_PHILIPS, 0),
+ .driver_data = SAA7134_BOARD_NOAUTO,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130,
+ PCI_VENDOR_ID_PHILIPS, 0),
+ .driver_data = SAA7134_BOARD_NOAUTO,
+ }, {
/* --- default catch --- */
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = SAA7134_BOARD_UNKNOWN,
- },{
+ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7130),
+ .driver_data = SAA7134_BOARD_UNKNOWN,
+ }, {
+ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7133),
+ .driver_data = SAA7134_BOARD_UNKNOWN,
+ }, {
+ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7134),
+ .driver_data = SAA7134_BOARD_UNKNOWN,
+ }, {
+ PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7135),
+ .driver_data = SAA7134_BOARD_UNKNOWN,
+ }, {
/* --- end of list --- */
}
};
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index 1eef4e102972..f2298e8bb96d 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -361,22 +361,14 @@ static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
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,
- },
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x17c8, 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,
- }
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x17c8, 0x2402),
+ .driver_data = (unsigned long)&hexium_gemini_dual_4bnc,
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 6f1b4bff7596..8ef2a4e8235d 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -425,29 +425,16 @@ static struct saa7146_pci_extension_data hexium_orion_4bnc = {
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,
- }
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x0000, 0x0000),
+ .driver_data = (unsigned long)&hexium_hv_pci6,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x17c8, 0x0101),
+ .driver_data = (unsigned long)&hexium_orion_1svhs_3bnc,
+ }, {
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x17c8, 0x2101),
+ .driver_data = (unsigned long)&hexium_orion_4bnc,
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index d931b4e3052f..d759e8a87e24 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -821,14 +821,10 @@ static struct saa7146_pci_extension_data mxb = {
static const struct pci_device_id pci_tbl[] = {
{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
- .subvendor = 0x0000,
- .subdevice = 0x0000,
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x0000, 0x0000),
.driver_data = (unsigned long)&mxb,
- }, {
- .vendor = 0,
- }
+ },
+ { }
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 6bcde506adf5..683bd78288b3 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1535,10 +1535,7 @@ static void saa7164_finidev(struct pci_dev *pci_dev)
static const struct pci_device_id saa7164_pci_tbl[] = {
{
/* SAA7164 */
- .vendor = 0x1131,
- .device = 0x7164,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ PCI_DEVICE(0x1131, 0x7164),
}, {
/* --- end of list --- */
}
diff --git a/drivers/media/pci/smipcie/smipcie-main.c b/drivers/media/pci/smipcie/smipcie-main.c
index 387c29958c98..5f18abb48b17 100644
--- a/drivers/media/pci/smipcie/smipcie-main.c
+++ b/drivers/media/pci/smipcie/smipcie-main.c
@@ -1097,8 +1097,7 @@ static const struct smi_cfg_info technotrend_s2_4200_cfg = {
/* PCI IDs */
#define SMI_ID(_subvend, _subdev, _driverdata) { \
- .vendor = SMI_VID, .device = SMI_PID, \
- .subvendor = _subvend, .subdevice = _subdev, \
+ PCI_DEVICE_SUB(SMI_VID, SMI_PID, (_subvend), (_subdev)), \
.driver_data = (unsigned long)&_driverdata }
static const struct pci_device_id smi_id_table[] = {
@@ -1106,7 +1105,7 @@ static const struct pci_device_id smi_id_table[] = {
SMI_ID(0x4254, 0x0552, dvbsky_s952_cfg),
SMI_ID(0x4254, 0x5580, dvbsky_t9580_cfg),
SMI_ID(0x13c2, 0x3016, technotrend_s2_4200_cfg),
- {0}
+ { }
};
MODULE_DEVICE_TABLE(pci, smi_id_table);
diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
index 11cddf4b4312..282c2c87151f 100644
--- a/drivers/media/pci/solo6x10/solo6x10-core.c
+++ b/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -656,7 +656,7 @@ static const struct pci_device_id solo_id_table[] = {
.driver_data = SOLO_DEV_6110 },
{ PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16),
.driver_data = SOLO_DEV_6110 },
- {0,}
+ { }
};
MODULE_DEVICE_TABLE(pci, solo_id_table);
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 8b496b959d7e..eb82a670c5bf 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -1537,9 +1537,7 @@ static const struct pci_device_id pci_tbl[] = {
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);
diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c
index 95370156aff5..c9f419fc07ad 100644
--- a/drivers/media/pci/ttpci/budget.c
+++ b/drivers/media/pci/ttpci/budget.c
@@ -858,9 +858,7 @@ static const struct pci_device_id pci_tbl[] = {
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);
diff --git a/drivers/media/pci/tw5864/tw5864-core.c b/drivers/media/pci/tw5864/tw5864-core.c
index 832788603f88..6ec8bce4ac4f 100644
--- a/drivers/media/pci/tw5864/tw5864-core.c
+++ b/drivers/media/pci/tw5864/tw5864-core.c
@@ -72,8 +72,8 @@ MODULE_PARM_DESC(video_nr, "video devices numbers array");
* added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
*/
static const struct pci_device_id tw5864_pci_tbl[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_5864)},
- {0,}
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_5864) },
+ { }
};
void tw5864_irqmask_apply(struct tw5864_dev *dev)
diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c
index 08b7ce1043aa..509d7ddec150 100644
--- a/drivers/media/pci/tw68/tw68-core.c
+++ b/drivers/media/pci/tw68/tw68-core.c
@@ -62,14 +62,14 @@ static atomic_t tw68_instance = ATOMIC_INIT(0);
* added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
*/
static const struct pci_device_id tw68_pci_tbl[] = {
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6800)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6801)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6804)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_1)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_2)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_3)},
- {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_4)},
- {0,}
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6800) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6801) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6804) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_1) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_2) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_3) },
+ { PCI_VDEVICE(TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_4) },
+ { }
};
/* ------------------------------------------------------------------ */
diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c
index a10e38221817..5a4ab329c06e 100644
--- a/drivers/media/pci/tw686x/tw686x-core.c
+++ b/drivers/media/pci/tw686x/tw686x-core.c
@@ -416,25 +416,24 @@ static void tw686x_remove(struct pci_dev *pci_dev)
/* driver_data is number of A/V channels */
static const struct pci_device_id tw686x_pci_tbl[] = {
{
- PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6864),
- .driver_data = 4
- },
- {
- PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6865), /* not tested */
- .driver_data = 4 | TYPE_SECOND_GEN
+ PCI_VDEVICE(TECHWELL, 0x6864),
+ .driver_data = 4,
+ }, {
+ PCI_VDEVICE(TECHWELL, 0x6865), /* not tested */
+ .driver_data = 4 | TYPE_SECOND_GEN,
},
/*
* TW6868 supports 8 A/V channels with an external TW2865 chip;
* not supported by the driver.
*/
{
- PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6868), /* not tested */
- .driver_data = 4
+ PCI_VDEVICE(TECHWELL, 0x6868), /* not tested */
+ .driver_data = 4,
+ }, {
+ PCI_VDEVICE(TECHWELL, 0x6869),
+ .driver_data = 8 | TYPE_SECOND_GEN
},
- {
- PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, 0x6869),
- .driver_data = 8 | TYPE_SECOND_GEN},
- {}
+ { }
};
MODULE_DEVICE_TABLE(pci, tw686x_pci_tbl);
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index f707bdc1fb0f..8bcf355a5418 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -75,8 +75,9 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(ZORAN_VERSION);
#define ZR_DEVICE(subven, subdev, data) { \
- .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \
- .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) }
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, \
+ (subven), (subdev)), \
+ .driver_data = (data) }
static const struct pci_device_id zr36067_pci_tbl[] = {
ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10_PLUS),
@@ -84,7 +85,7 @@ static const struct pci_device_id zr36067_pci_tbl[] = {
ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10),
ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ),
ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS),
- {0}
+ { }
};
MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
diff --git a/drivers/media/platform/amd/isp4/Kconfig b/drivers/media/platform/amd/isp4/Kconfig
index 9d1927af1cb8..77b61fae82ba 100644
--- a/drivers/media/platform/amd/isp4/Kconfig
+++ b/drivers/media/platform/amd/isp4/Kconfig
@@ -5,6 +5,7 @@ config VIDEO_AMD_ISP4_CAPTURE
depends on DRM_AMDGPU && DRM_AMD_ISP
depends on HAS_DMA
depends on VIDEO_DEV
+ select MEDIA_CONTROLLER
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
select VIDEOBUF2_V4L2
diff --git a/drivers/media/platform/amd/isp4/isp4_interface.c b/drivers/media/platform/amd/isp4/isp4_interface.c
index 8d73f66bb42c..00a817909292 100644
--- a/drivers/media/platform/amd/isp4/isp4_interface.c
+++ b/drivers/media/platform/amd/isp4/isp4_interface.c
@@ -375,7 +375,7 @@ static int isp4if_send_fw_cmd(struct isp4_interface *ispif, u32 cmd_id,
return -ENOMEM;
/* Get two references: one for the resp thread, one for us */
- atomic_set(&ele->refcnt, 2);
+ refcount_set(&ele->refcnt, 2);
init_completion(&ele->cmd_done);
}
@@ -455,7 +455,7 @@ err_dequeue_ele:
put_ele_ref:
/* Don't free the command if we didn't put the last reference */
- if (ele && atomic_dec_return(&ele->refcnt))
+ if (ele && !refcount_dec_and_test(&ele->refcnt))
ele = NULL;
free_ele:
diff --git a/drivers/media/platform/amd/isp4/isp4_interface.h b/drivers/media/platform/amd/isp4/isp4_interface.h
index ce3ac9b9e5cd..04db71cd54e6 100644
--- a/drivers/media/platform/amd/isp4/isp4_interface.h
+++ b/drivers/media/platform/amd/isp4/isp4_interface.h
@@ -68,7 +68,7 @@ struct isp4if_cmd_element {
u32 seq_num;
u32 cmd_id;
struct completion cmd_done;
- atomic_t refcnt;
+ refcount_t refcnt;
};
struct isp4_interface {
diff --git a/drivers/media/platform/amd/isp4/isp4_subdev.c b/drivers/media/platform/amd/isp4/isp4_subdev.c
index 48deea79ce6c..2a8bc1207843 100644
--- a/drivers/media/platform/amd/isp4/isp4_subdev.c
+++ b/drivers/media/platform/amd/isp4/isp4_subdev.c
@@ -391,7 +391,7 @@ static void isp4sd_fw_resp_cmd_done(struct isp4_subdev *isp_subdev,
if (ele) {
complete(&ele->cmd_done);
- if (atomic_dec_and_test(&ele->refcnt))
+ if (refcount_dec_and_test(&ele->refcnt))
kfree(ele);
}
}
diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
index 0b3d58b9f2f7..2ba4ae20f829 100644
--- a/drivers/media/platform/amphion/venc.c
+++ b/drivers/media/platform/amphion/venc.c
@@ -973,8 +973,6 @@ static int venc_start_session(struct vpu_inst *inst, u32 type)
venc->ready_count = 0;
venc->stopped = false;
vpu_process_output_buffer(inst);
- if (venc->frame_count == 0)
- dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
return 0;
error:
diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c
index 8d28ba0b59a3..1508843ae58c 100644
--- a/drivers/media/platform/broadcom/bcm2835-unicam.c
+++ b/drivers/media/platform/broadcom/bcm2835-unicam.c
@@ -2613,6 +2613,7 @@ static int unicam_async_nf_init(struct unicam_device *unicam)
return 0;
error:
+ v4l2_async_nf_cleanup(&unicam->notifier);
fwnode_handle_put(ep_handle);
return ret;
}
@@ -2745,6 +2746,7 @@ static void unicam_remove(struct platform_device *pdev)
v4l2_device_unregister(&unicam->v4l2_dev);
media_device_unregister(&unicam->mdev);
v4l2_async_nf_unregister(&unicam->notifier);
+ v4l2_async_nf_cleanup(&unicam->notifier);
unicam_subdev_cleanup(unicam);
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index bb2ba9204a83..6564cf3ec739 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -5,6 +5,7 @@
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
+#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include "wave5-helper.h"
@@ -474,7 +475,10 @@ static void wave5_vpu_dec_finish_decode(struct vpu_instance *inst)
v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
}
- inst->queuing_fail = false;
+ if (inst->queuing_fail) {
+ inst->queuing_fail = false;
+ v4l2_m2m_try_schedule(m2m_ctx);
+ }
}
static int wave5_vpu_dec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
@@ -819,7 +823,15 @@ static int wave5_vpu_dec_stop(struct vpu_instance *inst)
* calls do not block on a mutex while inside this spinlock.
*/
spin_unlock_irqrestore(&inst->state_spinlock, flags);
+ /*
+ * V4L2_DEC_CMD_STOP can arrive while the device is runtime
+ * suspended (e.g. on pipeline teardown). Setting the EOS flag
+ * accesses VPU registers via send_firmware_command(), so the
+ * device must be resumed first to avoid an asynchronous SError.
+ */
+ pm_runtime_resume_and_get(inst->dev->dev);
ret = wave5_vpu_dec_set_eos_on_firmware(inst);
+ pm_runtime_put_autosuspend(inst->dev->dev);
if (ret)
return ret;
@@ -1403,6 +1415,7 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
} else if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
struct dec_initial_info *initial_info =
&inst->codec_info->dec_info.initial_info;
+ struct dec_info *p_dec_info = &inst->codec_info->dec_info;
if (inst->state == VPU_INST_STATE_STOP)
ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ);
@@ -1410,6 +1423,7 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
goto return_buffers;
if (inst->state == VPU_INST_STATE_INIT_SEQ &&
+ p_dec_info->initial_info_obtained &&
inst->dev->product_code == WAVE521C_CODE) {
if (initial_info->luma_bitdepth != 8) {
dev_info(inst->dev->dev, "%s: no support for %d bit depth",
@@ -1418,7 +1432,6 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
goto return_buffers;
}
}
-
}
pm_runtime_put_autosuspend(inst->dev->dev);
return ret;
@@ -1536,15 +1549,15 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
{
struct vpu_instance *inst = vb2_get_drv_priv(q);
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
-
- bool check_cmd = TRUE;
+ unsigned long timeout;
dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
pm_runtime_resume_and_get(inst->dev->dev);
inst->empty_queue = true;
- while (check_cmd) {
+
+ timeout = jiffies + msecs_to_jiffies(VPU_DEC_STOP_TIMEOUT);
+ while (true) {
struct queue_status_info q_status;
- struct dec_output_info dec_output_info;
wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status);
if ((inst->state == VPU_INST_STATE_STOP ||
@@ -1553,8 +1566,10 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
q_status.report_queue_count == 0)
break;
- if (wave5_vpu_dec_get_output_info(inst, &dec_output_info))
- dev_dbg(inst->dev->dev, "there is no output info\n");
+ if (time_after(jiffies, timeout))
+ break;
+
+ usleep_range(1000, 2000);
}
v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
@@ -1651,6 +1666,7 @@ static void wave5_vpu_dec_device_run(void *priv)
struct queue_status_info q_status;
u32 fail_res = 0;
int ret = 0;
+ bool cmd_issued = false;
dev_dbg(inst->dev->dev, "%s: Fill the ring buffer with new bitstream data", __func__);
pm_runtime_resume_and_get(inst->dev->dev);
@@ -1662,9 +1678,13 @@ static void wave5_vpu_dec_device_run(void *priv)
} else if (!inst->eos &&
inst->queuing_num == 0 &&
inst->state == VPU_INST_STATE_PIC_RUN) {
- dev_dbg(inst->dev->dev, "%s: no bitstream for feeding, so skip ", __func__);
- inst->empty_queue = true;
- goto finish_job_and_return;
+ wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status);
+ if (q_status.instance_queue_count == v4l2_m2m_num_src_bufs_ready(m2m_ctx)) {
+ dev_dbg(inst->dev->dev, "%s: no bitstream, skip\n",
+ __func__);
+ inst->empty_queue = true;
+ goto finish_job_and_return;
+ }
}
}
@@ -1744,6 +1764,7 @@ static void wave5_vpu_dec_device_run(void *priv)
inst->retry = false;
if (!inst->eos)
inst->queuing_num--;
+ cmd_issued = true;
}
break;
default:
@@ -1761,8 +1782,16 @@ finish_job_and_return:
* in power and CPU time.
* If EOS is passed, device_run will not call job_finish no more, it is called
* only if HW is idle status in order to reduce overhead.
+ *
+ * Deferring job_finish() is only safe when this run actually queued a
+ * DEC_PIC command (cmd_issued): that guarantees a completion IRQ, and
+ * thus a later finish_decode(), will release the shared job slot. When
+ * device_run() is entered with no command to issue (e.g. a job that was
+ * queued while draining but reached the STOP state by the time it ran),
+ * no IRQ follows, so finish the job here to avoid leaking the slot and
+ * stalling every instance sharing the VPU.
*/
- if (!inst->sent_eos)
+ if (!inst->sent_eos || !cmd_issued)
v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
}
@@ -1776,11 +1805,22 @@ static void wave5_vpu_dec_job_abort(void *priv)
if (ret)
return;
+ /*
+ * job_abort() runs from the STREAMOFF path and may be called while the
+ * device is runtime suspended. Setting the EOS flag talks to the
+ * firmware (send_firmware_command() accesses VPU registers), so the
+ * device must be resumed first; otherwise the register access faults
+ * with an asynchronous SError.
+ */
+ pm_runtime_resume_and_get(inst->dev->dev);
+
ret = wave5_vpu_dec_set_eos_on_firmware(inst);
if (ret)
dev_warn(inst->dev->dev,
"Setting EOS for the bitstream, fail: %d\n", ret);
+ pm_runtime_put_autosuspend(inst->dev->dev);
+
v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
}
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
index e6c94b6f2671..f9fcdf4c224b 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
@@ -1494,7 +1494,8 @@ static const struct vb2_ops wave5_vpu_enc_vb2_ops = {
.stop_streaming = wave5_vpu_enc_stop_streaming,
};
-static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt,
+static void wave5_set_default_format(struct vpu_instance *inst,
+ struct v4l2_pix_format_mplane *src_fmt,
struct v4l2_pix_format_mplane *dst_fmt)
{
src_fmt->pixelformat = enc_fmt_list[VPU_FMT_TYPE_RAW][0].v4l2_pix_fmt;
@@ -1506,6 +1507,7 @@ static void wave5_set_default_format(struct v4l2_pix_format_mplane *src_fmt,
wave5_update_pix_fmt(dst_fmt, VPU_FMT_TYPE_CODEC,
W5_DEF_ENC_PIC_WIDTH, W5_DEF_ENC_PIC_HEIGHT,
&enc_frmsize[VPU_FMT_TYPE_CODEC]);
+ inst->std = wave5_to_vpu_std(dst_fmt->pixelformat, inst->type);
}
static int wave5_vpu_enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
@@ -1770,7 +1772,7 @@ static int wave5_vpu_open_enc(struct file *filp)
inst->v4l2_fh.ctrl_handler = v4l2_ctrl_hdl;
v4l2_ctrl_handler_setup(v4l2_ctrl_hdl);
- wave5_set_default_format(&inst->src_fmt, &inst->dst_fmt);
+ wave5_set_default_format(inst, &inst->src_fmt, &inst->dst_fmt);
inst->conf_win.width = inst->dst_fmt.width;
inst->conf_win.height = inst->dst_fmt.height;
inst->colorspace = V4L2_COLORSPACE_REC709;
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
index 4ebd48d5550e..e04f2dbf3b65 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
@@ -59,7 +59,7 @@
// application specific configuration
#define VPU_ENC_TIMEOUT 60000
#define VPU_DEC_TIMEOUT 60000
-#define VPU_DEC_STOP_TIMEOUT 10
+#define VPU_DEC_STOP_TIMEOUT 300
// for WAVE encoder
#define USE_SRC_PRP_AXI 0
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
index d30a05782ab9..96a66aadf0cd 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
@@ -321,7 +321,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
/* Enable mux settings */
for (index = 0; index < ctrl->num_sets; index++) {
set = &ctrl->sets[index];
- cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value);
+ cmdq_pkt_write_subsys(&cmd->pkt, set->subsys_id, set->reg, set->reg, set->value);
}
/* Config sub-frame information */
for (index = (num_comp - 1); index >= 0; index--) {
@@ -376,7 +376,7 @@ static int mdp_path_config_subfrm(struct mdp_cmdq_cmd *cmd,
/* Disable mux settings */
for (index = 0; index < ctrl->num_sets; index++) {
set = &ctrl->sets[index];
- cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0);
+ cmdq_pkt_write_subsys(&cmd->pkt, set->subsys_id, set->reg, set->reg, 0);
}
return 0;
@@ -628,7 +628,7 @@ static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp,
goto err_free_path;
}
cmdq_pkt_eoc(&cmd->pkt);
- cmdq_pkt_jump_rel(&cmd->pkt, CMDQ_INST_SIZE, mdp->cmdq_shift_pa[pp_idx]);
+ cmdq_pkt_jump_rel_temp(&cmd->pkt, CMDQ_INST_SIZE, mdp->cmdq_shift_pa[pp_idx]);
for (i = 0; i < num_comp; i++) {
s32 inner_id = MDP_COMP_NONE;
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
index 681906c16419..c6fc180950f2 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
@@ -12,14 +12,14 @@
#define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \
do { \
typeof(mask) (m) = (mask); \
- cmdq_pkt_write_mask(&((cmd)->pkt), id, (base) + (ofst), \
- (val), \
+ cmdq_pkt_write_mask_subsys(&((cmd)->pkt), (id), (base), \
+ (base) + (ofst), (val), \
(((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \
(0xffffffff) : (m)); \
} while (0)
#define MM_REG_WRITE(cmd, id, base, ofst, val) \
- cmdq_pkt_write(&((cmd)->pkt), id, (base) + (ofst), (val))
+ cmdq_pkt_write_subsys(&((cmd)->pkt), (id), (base), (base) + (ofst), (val))
#define MM_REG_WAIT(cmd, evt) \
do { \
diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
index 8f4da4cf55d2..f412aadb5996 100644
--- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
@@ -294,7 +294,11 @@ static int mdp_probe(struct platform_device *pdev)
goto err_destroy_clock_wq;
}
mdp->scp = platform_get_drvdata(mm_pdev);
- put_device(&mm_pdev->dev);
+ }
+
+ if (!mdp->scp) {
+ ret = -EPROBE_DEFER;
+ goto err_destroy_clock_wq;
}
mdp->rproc_handle = scp_get_rproc(mdp->scp);
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
index adbacabdbebc..ba7a1cd998b9 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
@@ -974,10 +974,10 @@ static int vdec_vp9_slice_setup_pfc(struct vdec_vp9_slice_instance *instance,
return 0;
}
-static int vdec_vp9_slice_setup_lat_buffer(struct vdec_vp9_slice_instance *instance,
- struct vdec_vp9_slice_vsi *vsi,
- struct mtk_vcodec_mem *bs,
- struct vdec_lat_buf *lat_buf)
+static void vdec_vp9_slice_setup_lat_buffer(struct vdec_vp9_slice_instance *instance,
+ struct vdec_vp9_slice_vsi *vsi,
+ struct mtk_vcodec_mem *bs,
+ struct vdec_lat_buf *lat_buf)
{
int i;
@@ -1011,12 +1011,10 @@ static int vdec_vp9_slice_setup_lat_buffer(struct vdec_vp9_slice_instance *insta
vsi->row_info.buf = 0;
vsi->row_info.size = 0;
-
- return 0;
}
-static int vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *instance,
- struct vdec_vp9_slice_vsi *vsi)
+static void vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *instance,
+ struct vdec_vp9_slice_vsi *vsi)
{
struct vdec_vp9_slice_frame_ctx *frame_ctx;
struct vdec_vp9_slice_uncompressed_header *uh;
@@ -1032,8 +1030,6 @@ static int vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *inst
else
frame_ctx = vdec_vp9_slice_default_frame_ctx;
memcpy(instance->prob.va, frame_ctx, sizeof(*frame_ctx));
-
- return 0;
}
static void vdec_vp9_slice_setup_seg_buffer(struct vdec_vp9_slice_instance *instance,
@@ -1166,17 +1162,13 @@ static int vdec_vp9_slice_setup_lat(struct vdec_vp9_slice_instance *instance,
if (ret)
goto err;
- ret = vdec_vp9_slice_setup_lat_buffer(instance, vsi, bs, lat_buf);
- if (ret)
- goto err;
+ vdec_vp9_slice_setup_lat_buffer(instance, vsi, bs, lat_buf);
vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]);
/* setup prob/tile buffers for LAT */
- ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi);
- if (ret)
- goto err;
+ vdec_vp9_slice_setup_prob_buffer(instance, vsi);
ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs);
if (ret)
@@ -1808,10 +1800,7 @@ static int vdec_vp9_slice_setup_single(struct vdec_vp9_slice_instance *instance,
vdec_vp9_slice_setup_single_buffer(instance, pfc, vsi, bs, fb);
vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]);
-
- ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi);
- if (ret)
- goto err;
+ vdec_vp9_slice_setup_prob_buffer(instance, vsi);
ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs);
if (ret)
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
index fb6f1016415e..faebb5472866 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c
@@ -580,7 +580,7 @@ static u32 hfi_buffer_line_av1d(u32 frame_width, u32 frame_height,
ALIGN(size_av1d_qp(frame_width, frame_height), DMA_ALIGNMENT);
opbwr8 = size_av1d_lb_opb_wr1_nv12_ubwc(frame_width, frame_height);
opbwr10 = size_av1d_lb_opb_wr1_tp10_ubwc(frame_width, frame_height);
- opbwrbufsize = opbwr8 >= opbwr10 ? opbwr8 : opbwr10;
+ opbwrbufsize = max(opbwr8, opbwr10);
size = ALIGN((size + opbwrbufsize), DMA_ALIGNMENT);
if (is_opb) {
vpss_lb_size = size_vpss_lb(frame_width, frame_height);
@@ -700,7 +700,7 @@ static u32 hfi_buffer_ibc_av1d(u32 frame_width, u32 frame_height)
ibc8 = size_av1d_ibc_nv12_ubwc(frame_width, frame_height);
ibc10 = size_av1d_ibc_tp10_ubwc(frame_width, frame_height);
- size = ibc8 >= ibc10 ? ibc8 : ibc10;
+ size = max(ibc8, ibc10);
return ALIGN(size, DMA_ALIGNMENT);
}
diff --git a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
index 5bf334e173d2..b426bc7898bf 100644
--- a/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
+++ b/drivers/media/platform/renesas/rzg2l-cru/rzg2l-cru.h
@@ -116,11 +116,9 @@ struct rzg2l_cru_info {
* @scratch_phys: physical address of the scratch buffer
*
* @qlock: protects @queue_buf, @buf_list, @sequence
- * @state
* @queue_buf: Keeps track of buffers given to HW slot
* @buf_list: list of queued buffers
* @sequence: V4L2 buffers sequence number
- * @state: keeps track of operation state
*
* @format: active V4L2 pixel format
*/
diff --git a/drivers/media/platform/rockchip/rga/rga3-hw.c b/drivers/media/platform/rockchip/rga/rga3-hw.c
index ca1c268303dd..c4a71306278b 100644
--- a/drivers/media/platform/rockchip/rga/rga3-hw.c
+++ b/drivers/media/platform/rockchip/rga/rga3-hw.c
@@ -450,10 +450,14 @@ static void *rga3_adjust_and_map_format(struct rga_ctx *ctx,
other_format = is_output ? &ctx->out.pix : &ctx->in.pix;
other_format_info = v4l2_format_info(other_format->pixelformat);
- if ((v4l2_is_format_rgb(format_info) &&
- v4l2_is_format_yuv(other_format_info)) ||
- (v4l2_is_format_yuv(format_info) &&
- v4l2_is_format_rgb(other_format_info))) {
+ /*
+ * Only apply the quantization restrictions when we need to
+ * convert between RGB and YUV. Otherwise there is no point
+ * to limit the quantization for operations like scaling or
+ * rotations.
+ */
+ if (v4l2_is_format_yuv(format_info) &&
+ v4l2_is_format_rgb(other_format_info)) {
/*
* The RGA3 only supports BT601, BT709 and BT2020 RGB<->YUV conversions
* Additionally BT709 and BT2020 only support limited range YUV.
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
index f89602075121..9c4a6093af32 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
@@ -209,6 +209,9 @@ static void st_ref_pic_set_prediction(struct rkvdec_hevc_run *run, int idx,
int i, j;
int dPoc;
+ if ((unsigned int)rps_data->delta_idx_minus1 + 1 > idx)
+ return;
+
ref_rps_idx = st_rps_idx - (rps_data->delta_idx_minus1 + 1); /* 7-59 */
delta_rps = (1 - 2 * rps_data->delta_rps_sign) *
(rps_data->abs_delta_rps_minus1 + 1); /* 7-60 */
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
index 87abf93dfd5e..ff3942f91c5d 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
@@ -258,9 +258,9 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
for (i = 0; i <= pps->num_tile_rows_minus1; i++)
WRITE_PPS(pps->row_height_minus1[i], ROW_HEIGHT(i));
} else {
- WRITE_PPS(((sps->pic_width_in_luma_samples + ctb_size_y - 1) / ctb_size_y) - 1,
+ WRITE_PPS(DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_y) - 1,
COLUMN_WIDTH(0));
- WRITE_PPS(((sps->pic_height_in_luma_samples + ctb_size_y - 1) / ctb_size_y) - 1,
+ WRITE_PPS(DIV_ROUND_UP(sps->pic_height_in_luma_samples, ctb_size_y) - 1,
ROW_HEIGHT(0));
}
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
index fe6414a17551..d07c74679552 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
@@ -261,8 +261,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
memset(row_height, 0, sizeof(row_height));
max_cu_width = 1 << (sps->log2_diff_max_min_luma_coding_block_size + log2_min_cb_size);
- pic_in_cts_width = (width + max_cu_width - 1) / max_cu_width;
- pic_in_cts_height = (height + max_cu_width - 1) / max_cu_width;
+ pic_in_cts_width = DIV_ROUND_UP(width, max_cu_width);
+ pic_in_cts_height = DIV_ROUND_UP(height, max_cu_width);
if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) {
if (pps->flags & V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING) {
@@ -275,8 +275,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
column_width, row_height);
}
} else {
- column_width[0] = (width + max_cu_width - 1) / max_cu_width;
- row_height[0] = (height + max_cu_width - 1) / max_cu_width;
+ column_width[0] = DIV_ROUND_UP(width, max_cu_width);
+ row_height[0] = DIV_ROUND_UP(height, max_cu_width);
}
for (i = 0; i < 20; i++) {
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
index 3575338a531a..3462d995d4cf 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
@@ -287,8 +287,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
memset(row_height, 0, sizeof(row_height));
max_cu_width = 1 << (sps->log2_diff_max_min_luma_coding_block_size + log2_min_cb_size);
- pic_in_cts_width = (width + max_cu_width - 1) / max_cu_width;
- pic_in_cts_height = (height + max_cu_width - 1) / max_cu_width;
+ pic_in_cts_width = DIV_ROUND_UP(width, max_cu_width);
+ pic_in_cts_height = DIV_ROUND_UP(height, max_cu_width);
if (tiles_enabled) {
if (pps->flags & V4L2_HEVC_PPS_FLAG_UNIFORM_SPACING) {
@@ -301,8 +301,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
column_width, row_height);
}
} else {
- column_width[0] = (width + max_cu_width - 1) / max_cu_width;
- row_height[0] = (height + max_cu_width - 1) / max_cu_width;
+ column_width[0] = DIV_ROUND_UP(width, max_cu_width);
+ row_height[0] = DIV_ROUND_UP(height, max_cu_width);
}
for (i = 0; i < 20; i++)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 1d1e9bfef8e9..061281f903f3 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -278,12 +278,12 @@ static const struct rkvdec_ctrl_desc vdpu38x_hevc_ctrl_descs[] = {
{
.cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS,
.cfg.ops = &rkvdec_ctrl_ops,
- .cfg.dims = { 65 },
+ .cfg.dims = { 64 },
},
{
.cfg.id = V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS,
.cfg.ops = &rkvdec_ctrl_ops,
- .cfg.dims = { 65 },
+ .cfg.dims = { 32 },
},
};
@@ -1818,8 +1818,8 @@ static int rkvdec_probe(struct platform_device *pdev)
vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
irq = platform_get_irq(pdev, 0);
- if (irq <= 0)
- return -ENXIO;
+ if (irq < 0)
+ return irq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
rkvdec_irq_handler, IRQF_ONESHOT,
diff --git a/drivers/media/platform/samsung/s3c-camif/camif-core.c b/drivers/media/platform/samsung/s3c-camif/camif-core.c
index 221e3c447f36..14eedd1ceb27 100644
--- a/drivers/media/platform/samsung/s3c-camif/camif-core.c
+++ b/drivers/media/platform/samsung/s3c-camif/camif-core.c
@@ -12,7 +12,6 @@
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
-#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -412,7 +411,7 @@ static int s3c_camif_probe(struct platform_device *pdev)
camif->dev = dev;
- if (!pdata || !pdata->gpio_get || !pdata->gpio_put) {
+ if (!pdata) {
dev_err(dev, "wrong platform data\n");
return -EINVAL;
}
@@ -429,9 +428,7 @@ static int s3c_camif_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
- ret = pdata->gpio_get();
- if (ret < 0)
- return ret;
+ /* FIXME: get GPIOs here */
ret = s3c_camif_create_subdev(camif);
if (ret < 0)
@@ -504,14 +501,12 @@ err_disable:
err_clk:
s3c_camif_unregister_subdev(camif);
err_sd:
- pdata->gpio_put();
return ret;
}
static void s3c_camif_remove(struct platform_device *pdev)
{
struct camif_dev *camif = platform_get_drvdata(pdev);
- struct s3c_camif_plat_data *pdata = &camif->pdata;
media_device_unregister(&camif->media_dev);
media_device_cleanup(&camif->media_dev);
@@ -521,7 +516,6 @@ static void s3c_camif_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
camif_clk_put(camif);
s3c_camif_unregister_subdev(camif);
- pdata->gpio_put();
}
static int s3c_camif_runtime_resume(struct device *dev)
diff --git a/drivers/media/platform/st/stm32/stm32-dcmi.c b/drivers/media/platform/st/stm32/stm32-dcmi.c
index eeb0199864dd..b1f9af8edf6e 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmi.c
@@ -2273,9 +2273,7 @@ static int dcmi_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
/* clock enable */
- pm_runtime_force_resume(dev);
-
- return 0;
+ return pm_runtime_force_resume(dev);
}
static const struct dev_pm_ops dcmi_pm_ops = {
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
index 49398d077764..516334541b2c 100644
--- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -649,9 +649,7 @@ static int dcmipp_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
/* clock enable */
- pm_runtime_force_resume(dev);
-
- return 0;
+ return pm_runtime_force_resume(dev);
}
static const struct dev_pm_ops dcmipp_pm_ops = {
diff --git a/drivers/media/platform/ti/Kconfig b/drivers/media/platform/ti/Kconfig
index d0cb05481bd8..1a020b2bbb4f 100644
--- a/drivers/media/platform/ti/Kconfig
+++ b/drivers/media/platform/ti/Kconfig
@@ -50,6 +50,7 @@ config VIDEO_TI_VIP
select VIDEO_TI_VPDMA
select VIDEO_TI_SC
select VIDEO_TI_CSC
+ select V4L2_FWNODE
help
Driver support for VIP module on certain TI SoC's
VIP = Video Input Port.
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index 2e81877f640f..ad71c0402ef3 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -771,8 +771,10 @@ static int hantro_register_entity(struct media_device *mdev,
return ret;
ret = media_device_register_entity(mdev, entity);
- if (ret)
+ if (ret) {
+ media_entity_cleanup(entity);
return ret;
+ }
return 0;
}
@@ -860,12 +862,13 @@ err_rm_links0:
err_rel_entity2:
media_device_unregister_entity(&func->sink);
-
+ media_entity_cleanup(&func->sink);
err_rel_entity1:
media_device_unregister_entity(&func->proc);
-
+ media_entity_cleanup(&func->proc);
err_rel_entity0:
media_device_unregister_entity(&func->vdev.entity);
+ media_entity_cleanup(&func->vdev.entity);
return ret;
}
@@ -878,6 +881,9 @@ static void hantro_detach_func(struct hantro_func *func)
media_device_unregister_entity(&func->sink);
media_device_unregister_entity(&func->proc);
media_device_unregister_entity(&func->vdev.entity);
+ media_entity_cleanup(&func->sink);
+ media_entity_cleanup(&func->proc);
+ media_entity_cleanup(&func->vdev.entity);
}
static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid)
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 5110754e1a31..53c1d1061cf4 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -527,8 +527,8 @@ static const struct v4l2_ctrl_ops cadet_ctrl_ops = {
static const struct pnp_device_id cadet_pnp_devices[] = {
/* ADS Cadet AM/FM Radio Card */
- {.id = "MSM0c24", .driver_data = 0},
- {.id = ""}
+ { .id = "MSM0c24" },
+ { }
};
MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 3d1d0b46195b..7e4257e4b71d 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -284,8 +284,8 @@ static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c }
#ifdef CONFIG_PNP
static const struct pnp_device_id gemtek_pnp_devices[] = {
/* AOpen FX-3D/Pro Radio */
- {.id = "ADS7183", .driver_data = 0},
- {.id = ""}
+ { .id = "ADS7183" },
+ { }
};
MODULE_DEVICE_TABLE(pnp, gemtek_pnp_devices);
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 5055dfc3f465..c196ee923ecd 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -642,8 +642,8 @@ static void fintek_shutdown(struct pnp_dev *pdev)
}
static const struct pnp_device_id fintek_ids[] = {
- { "FIT0002", 0 }, /* CIR */
- { "", 0 },
+ { .id = "FIT0002" }, /* CIR */
+ { }
};
static struct pnp_driver fintek_driver = {
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index bde2a7051231..1fbafcd8219e 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1203,9 +1203,16 @@ static void ite_close(struct rc_dev *rcdev)
spin_unlock_irqrestore(&dev->lock, flags);
}
+enum ite_model_type {
+ ITE8704,
+ ITE8713,
+ ITE8708,
+ ITE8709,
+};
+
/* supported models and their parameters */
static const struct ite_dev_params ite_dev_descs[] = {
- { /* 0: ITE8704 */
+ [ITE8704] = {
.model = "ITE8704 CIR transceiver",
.io_region_size = IT87_IOREG_LENGTH,
.io_rsrc_no = 0,
@@ -1224,7 +1231,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
.init_hardware = it87_init_hardware,
.set_carrier_params = it87_set_carrier_params,
},
- { /* 1: ITE8713 */
+ [ITE8713] = {
.model = "ITE8713 CIR transceiver",
.io_region_size = IT87_IOREG_LENGTH,
.io_rsrc_no = 0,
@@ -1243,7 +1250,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
.init_hardware = it87_init_hardware,
.set_carrier_params = it87_set_carrier_params,
},
- { /* 2: ITE8708 */
+ [ITE8708] = {
.model = "ITE8708 CIR transceiver",
.io_region_size = IT8708_IOREG_LENGTH,
.io_rsrc_no = 0,
@@ -1263,7 +1270,7 @@ static const struct ite_dev_params ite_dev_descs[] = {
.init_hardware = it8708_init_hardware,
.set_carrier_params = it8708_set_carrier_params,
},
- { /* 3: ITE8709 */
+ [ITE8709] = {
.model = "ITE8709 CIR transceiver",
.io_region_size = IT8709_IOREG_LENGTH,
.io_rsrc_no = 2,
@@ -1286,11 +1293,11 @@ static const struct ite_dev_params ite_dev_descs[] = {
};
static const struct pnp_device_id ite_ids[] = {
- {"ITE8704", 0}, /* Default model */
- {"ITE8713", 1}, /* CIR found in EEEBox 1501U */
- {"ITE8708", 2}, /* Bridged IT8512 */
- {"ITE8709", 3}, /* SRAM-Bridged IT8512 */
- {"", 0},
+ { .id = "ITE8704", .driver_data = ITE8704 }, /* Default model */
+ { .id = "ITE8713", .driver_data = ITE8713 }, /* CIR found in EEEBox 1501U */
+ { .id = "ITE8708", .driver_data = ITE8708 }, /* Bridged IT8512 */
+ { .id = "ITE8709", .driver_data = ITE8709 }, /* SRAM-Bridged IT8512 */
+ { }
};
/* allocate memory, probe hardware, and initialize everything */
@@ -1301,7 +1308,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
struct ite_dev *itdev = NULL;
struct rc_dev *rdev = NULL;
int ret = -ENOMEM;
- int model_no;
+ enum ite_model_type model_no;
int io_rsrc_no;
itdev = kzalloc_obj(struct ite_dev);
@@ -1317,7 +1324,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
ret = -ENODEV;
/* get the model number */
- model_no = (int)dev_id->driver_data;
+ model_no = dev_id->driver_data;
dev_dbg(&pdev->dev, "Auto-detected model: %s\n",
ite_dev_descs[model_no].model);
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index d04572627cdd..38b84e34b225 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -129,7 +129,7 @@ obj-$(CONFIG_RC_MAP) += \
rc-twinhan1027.o \
rc-twinhan-dtv-cab-ci.o \
rc-vega-s9x.o \
- rc-videomate-m1f.o \
+ rc-videomate-k100.o \
rc-videomate-s350.o \
rc-videomate-tv-pvr.o \
rc-videostrong-kii-pro.o \
diff --git a/drivers/media/rc/keymaps/rc-videomate-m1f.c b/drivers/media/rc/keymaps/rc-videomate-k100.c
index 1f9be84ff27b..6664cfd0b7f3 100644
--- a/drivers/media/rc/keymaps/rc-videomate-m1f.c
+++ b/drivers/media/rc/keymaps/rc-videomate-k100.c
@@ -87,4 +87,4 @@ module_exit(exit_rc_map_videomate_k100)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pavel Osnova <pvosnova@gmail.com>");
-MODULE_DESCRIPTION("videomate-m1f remote controller keytable");
+MODULE_DESCRIPTION("videomate-k100 remote controller keytable");
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 4e5a0c8dc9a0..918258dadd69 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1092,9 +1092,9 @@ static void nvt_shutdown(struct pnp_dev *pdev)
}
static const struct pnp_device_id nvt_ids[] = {
- { "WEC0530", 0 }, /* CIR */
- { "NTN0530", 0 }, /* CIR for new chip's pnp id*/
- { "", 0 },
+ { .id = "WEC0530" }, /* CIR */
+ { .id = "NTN0530" }, /* CIR for new chip's pnp id*/
+ { }
};
static struct pnp_driver nvt_driver = {
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index cb4c56bf0752..28e840a7e5b8 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -344,22 +344,25 @@ static int sunxi_ir_probe(struct platform_device *pdev)
ir->irq = platform_get_irq(pdev, 0);
if (ir->irq < 0) {
ret = ir->irq;
- goto exit_free_dev;
+ goto exit_unregister_dev;
}
ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir);
if (ret) {
dev_err(dev, "failed request irq\n");
- goto exit_free_dev;
+ goto exit_unregister_dev;
}
ret = sunxi_ir_hw_init(dev);
if (ret)
- goto exit_free_dev;
+ goto exit_unregister_dev;
dev_info(dev, "initialized sunXi IR driver\n");
return 0;
+exit_unregister_dev:
+ rc_unregister_device(ir->rc);
+
exit_free_dev:
rc_free_device(ir->rc);
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 8e804661a621..1ae036f8a296 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1179,8 +1179,8 @@ wbcir_remove(struct pnp_dev *device)
}
static const struct pnp_device_id wbcir_ids[] = {
- { "WEC1022", 0 },
- { "", 0 }
+ { .id = "WEC1022" },
+ { }
};
MODULE_DEVICE_TABLE(pnp, wbcir_ids);
diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c
index 318e8330f16a..ff9d50fb05fd 100644
--- a/drivers/media/test-drivers/vicodec/vicodec-core.c
+++ b/drivers/media/test-drivers/vicodec/vicodec-core.c
@@ -63,11 +63,11 @@ struct pixfmt_info {
};
static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
- V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1
+ V4L2_PIX_FMT_FWHT, 0, 4, 1, 1, 1, 1, 1, 0, 1
};
static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = {
- V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1
+ V4L2_PIX_FMT_FWHT_STATELESS, 0, 4, 1, 1, 1, 1, 1, 0, 1
};
static void vicodec_dev_release(struct device *dev)
diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c
index 5deebcc78a33..83dcc9d61ee0 100644
--- a/drivers/media/test-drivers/vimc/vimc-sensor.c
+++ b/drivers/media/test-drivers/vimc/vimc-sensor.c
@@ -92,8 +92,8 @@ static void vimc_sensor_tpg_s_format(struct vimc_sensor_device *vsensor,
tpg_s_xfer_func(&vsensor->tpg, format->xfer_func);
}
-static int vimc_sensor_update_frame_timing(struct v4l2_subdev *sd,
- u32 width, u32 height)
+static void vimc_sensor_update_frame_timing(struct v4l2_subdev *sd,
+ u32 width, u32 height)
{
struct vimc_sensor_device *vsensor =
container_of(sd, struct vimc_sensor_device, sd);
@@ -103,13 +103,15 @@ static int vimc_sensor_update_frame_timing(struct v4l2_subdev *sd,
u64 total_pixels = (u64)hts * vts;
u64 frame_interval_ns;
+ /* Sanity check, pixel rate is fixed and fits in 32 bits. */
+ if (WARN_ON(pixel_rate >= 0x100000000))
+ return;
+
frame_interval_ns = total_pixels * NSEC_PER_SEC;
- do_div(frame_interval_ns, pixel_rate);
+ do_div(frame_interval_ns, (u32)pixel_rate);
vsensor->hw.fps_jiffies = nsecs_to_jiffies(frame_interval_ns);
if (vsensor->hw.fps_jiffies == 0)
vsensor->hw.fps_jiffies = 1;
-
- return 0;
}
static void vimc_sensor_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
diff --git a/drivers/media/test-drivers/vivid/vivid-meta-out.c b/drivers/media/test-drivers/vivid/vivid-meta-out.c
index 55e5e5dec2f2..ca913b808225 100644
--- a/drivers/media/test-drivers/vivid/vivid-meta-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-meta-out.c
@@ -17,12 +17,8 @@ static int meta_out_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[],
struct device *alloc_devs[])
{
- struct vivid_dev *dev = vb2_get_drv_priv(vq);
unsigned int size = sizeof(struct vivid_meta_out_buf);
- if (!vivid_is_webcam(dev))
- return -EINVAL;
-
if (*nplanes) {
if (sizes[0] < size)
return -EINVAL;
@@ -127,11 +123,6 @@ const struct vb2_ops vivid_meta_out_qops = {
int vidioc_enum_fmt_meta_out(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- struct vivid_dev *dev = video_drvdata(file);
-
- if (!vivid_is_webcam(dev))
- return -EINVAL;
-
if (f->index > 0)
return -EINVAL;
@@ -143,12 +134,8 @@ int vidioc_enum_fmt_meta_out(struct file *file, void *priv,
int vidioc_g_fmt_meta_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- struct vivid_dev *dev = video_drvdata(file);
struct v4l2_meta_format *meta = &f->fmt.meta;
- if (!vivid_is_webcam(dev) || !dev->has_meta_out)
- return -EINVAL;
-
meta->dataformat = V4L2_META_FMT_VIVID;
meta->buffersize = sizeof(struct vivid_meta_out_buf);
return 0;
@@ -159,10 +146,12 @@ void vivid_meta_out_process(struct vivid_dev *dev,
{
struct vivid_meta_out_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
- v4l2_ctrl_s_ctrl(dev->brightness, meta->brightness);
- v4l2_ctrl_s_ctrl(dev->contrast, meta->contrast);
- v4l2_ctrl_s_ctrl(dev->saturation, meta->saturation);
- v4l2_ctrl_s_ctrl(dev->hue, meta->hue);
+ if (dev->brightness) {
+ v4l2_ctrl_s_ctrl(dev->brightness, meta->brightness);
+ v4l2_ctrl_s_ctrl(dev->contrast, meta->contrast);
+ v4l2_ctrl_s_ctrl(dev->saturation, meta->saturation);
+ v4l2_ctrl_s_ctrl(dev->hue, meta->hue);
+ }
dprintk(dev, 2, " %s brightness %u contrast %u saturation %u hue %d\n",
__func__, meta->brightness, meta->contrast,
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index 57edb42463e8..358a66ab8e48 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -464,14 +464,21 @@ static void airspy_disconnect(struct usb_interface *intf)
dev_dbg(s->dev, "\n");
- mutex_lock(&s->vb_queue_lock);
+ /*
+ * vb2_video_unregister_device() releases the vb2 queue, which
+ * triggers airspy_stop_streaming() if streaming is active.
+ * stop_streaming() dereferences s->udev via airspy_ctrl_msg() and
+ * airspy_free_stream_bufs(), so it must run before s->udev is
+ * cleared. vb2_video_unregister_device() locks vb_queue_lock
+ * internally and stop_streaming() locks v4l2_lock, so neither may
+ * be held by the caller.
+ */
+ v4l2_device_disconnect(&s->v4l2_dev);
+ vb2_video_unregister_device(&s->vdev);
+
mutex_lock(&s->v4l2_lock);
- /* No need to keep the urbs around after disconnection */
s->udev = NULL;
- v4l2_device_disconnect(&s->v4l2_dev);
- video_unregister_device(&s->vdev);
mutex_unlock(&s->v4l2_lock);
- mutex_unlock(&s->vb_queue_lock);
v4l2_device_put(&s->v4l2_dev);
}
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c
index 9929ce5dcdcd..8ab100db01ab 100644
--- a/drivers/media/usb/au0828/au0828-cards.c
+++ b/drivers/media/usb/au0828/au0828-cards.c
@@ -124,6 +124,17 @@ struct au0828_board au0828_boards[] = {
},
},
},
+ [AU0828_BOARD_MONOPRICE_106456] = {
+ /*
+ * Monoprice 106456 USB ATSC/QAM tuner (board rev TV22AD-A),
+ * a.k.a. AnyTV AUTV002, USB ID 05e1:0400. Same AU8522 demod +
+ * NXP TDA18271HDC2 tuner @ 0x60 as the Hauppauge Woodbury.
+ */
+ .name = "Monoprice 106456 USB ATSC/QAM (TV22AD-A)",
+ .tuner_type = TUNER_NXP_TDA18271,
+ .tuner_addr = 0x60,
+ .i2c_clk_divider = AU0828_I2C_CLK_250KHZ,
+ },
[AU0828_BOARD_HAUPPAUGE_HVR1265] = {
.name = "Hauppauge HVR1265",
.tuner_type = TUNER_XC5000,
@@ -294,6 +305,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
case AU0828_BOARD_HAUPPAUGE_HVR1265:
case AU0828_BOARD_HAUPPAUGE_IMPACTVCBE:
+ case AU0828_BOARD_MONOPRICE_106456:
/* GPIO's
* 4 - CS5340
* 5 - AU8522 Demodulator
@@ -378,6 +390,8 @@ struct usb_device_id au0828_usb_id_table[] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL },
{ USB_DEVICE(0x05e1, 0x0480),
.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
+ { USB_DEVICE(0x05e1, 0x0400),
+ .driver_info = AU0828_BOARD_MONOPRICE_106456 },
{ USB_DEVICE(0x2040, 0x8200),
.driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY },
{ USB_DEVICE(0x2040, 0x7260),
diff --git a/drivers/media/usb/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h
index a438aeb334a0..a4a283731f7d 100644
--- a/drivers/media/usb/au0828/au0828-cards.h
+++ b/drivers/media/usb/au0828/au0828-cards.h
@@ -13,3 +13,4 @@
#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
#define AU0828_BOARD_HAUPPAUGE_IMPACTVCBE 6
#define AU0828_BOARD_HAUPPAUGE_HVR1265 7
+#define AU0828_BOARD_MONOPRICE_106456 8
diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c
index 31123e6f9fc3..9c95b7ceaecd 100644
--- a/drivers/media/usb/au0828/au0828-dvb.c
+++ b/drivers/media/usb/au0828/au0828-dvb.c
@@ -600,6 +600,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
&mxl5007t_hvr950q_config);
break;
case AU0828_BOARD_HAUPPAUGE_WOODBURY:
+ case AU0828_BOARD_MONOPRICE_106456:
dvb->frontend = dvb_attach(au8522_attach,
&hauppauge_woodbury_config,
&dev->i2c_adap);
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index 9c71b32552df..b24ceef497e4 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -443,6 +443,11 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
int ret;
struct cx231xx *dev = snd_pcm_substream_chip(substream);
+ if (!dev) {
+ pr_err("cx231xx: called with null device\n");
+ return -ENODEV;
+ }
+
dev_dbg(dev->dev, "closing device\n");
/* inform hardware to stop streaming */
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 2cd4e333bc4b..70aa99fead27 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -898,7 +898,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
if (rc)
return rc;
- if (vb2_is_busy(&dev->vidq)) {
+ if (vb2_is_busy(&dev->vidq) || vb2_is_busy(&dev->vbiq)) {
dev_err(dev->dev, "%s: queue busy\n", __func__);
return -EBUSY;
}
@@ -933,7 +933,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
if (dev->norm == norm)
return 0;
- if (vb2_is_busy(&dev->vidq))
+ if (vb2_is_busy(&dev->vidq) || vb2_is_busy(&dev->vbiq))
return -EBUSY;
dev->norm = norm;
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index fbfb74eab475..b94b00456bcd 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -2677,6 +2677,28 @@ const struct em28xx_board em28xx_boards[] = {
.gpio = mygica_utv3_tuner_audio_gpio,
} },
},
+ /* eb1a:8286 StarTech SVID2USB232
+ * Empia EM28281 with integrated TVP5150-compatible video decoder.
+ * Composite and S-Video inputs, stereo line-in audio.
+ */
+ [EM28281_BOARD_STARTECH_SVID2USB232] = {
+ .name = "StarTech SVID2USB232",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .has_dvb = 0,
+ .decoder = EM28XX_BUILTIN,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE,
+ .vmux = EM2828X_COMPOSITE,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = EM2828X_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
[EM2828X_BOARD_HAUPPAUGE_USB_LIVE2] = {
.name = "Hauppauge USB Live2",
.vchannels = 2,
@@ -2946,6 +2968,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2874_BOARD_HAUPPAUGE_USB_QUADHD },
{ USB_DEVICE(0x2040, 0xc220),
.driver_info = EM2828X_BOARD_HAUPPAUGE_USB_LIVE2 },
+ { USB_DEVICE(0xeb1a, 0x8286),
+ .driver_info = EM28281_BOARD_STARTECH_SVID2USB232 },
{ USB_DEVICE(0x2040, 0x0360),
.driver_info = EM2828X_BOARD_HAUPPAUGE_935_V2 },
{ USB_DEVICE(0x2040, 0x8360),
@@ -3758,7 +3782,7 @@ void em28xx_free_device(struct kref *ref)
{
struct em28xx *dev = kref_to_dev(ref);
- dev_info(&dev->intf->dev, "Freeing device\n");
+ pr_info("%s: Freeing device\n", dev->name);
if (!dev->disconnected)
em28xx_release_resources(dev);
@@ -3859,6 +3883,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
dev->wait_after_write = 0;
dev->eeprom_addrwidth_16bit = 1;
break;
+ case CHIP_ID_EM28281:
+ chip_name = "em28281";
+ dev->wait_after_write = 0;
+ dev->eeprom_addrwidth_16bit = 1;
+ break;
case CHIP_ID_EM2883:
chip_name = "em2882/3";
dev->wait_after_write = 0;
@@ -4082,7 +4111,7 @@ static void em28xx_check_usb_descriptor(struct em28xx *dev,
dev->analog_ep_bulk = e->bEndpointAddress;
}
return;
- };
+ }
}
/*
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index 5bbb082dbed9..0b998e7cafef 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -632,7 +632,7 @@ void em2828X_decoder_vmux(struct em28xx *dev, unsigned int vin)
default:
dev_dbg(&dev->intf->dev, "EM2828X_SVIDEO\n");
break;
- };
+ }
em28xx_write_reg(dev, 0x24, 0x00);
em28xx_write_reg(dev, 0x25, 0x02);
@@ -1265,6 +1265,8 @@ void em28xx_close_extension(struct em28xx *dev)
ops->fini(dev);
}
}
+ if (dev->dev_next)
+ list_del(&dev->dev_next->devlist);
list_del(&dev->devlist);
mutex_unlock(&em28xx_devlist_mutex);
}
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 938f1980d448..8482fc4045ea 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -29,7 +29,7 @@
#include <media/dmxdev.h>
#include <media/tuner.h>
#include "tuner-simple.h"
-#include <linux/gpio.h>
+#include <linux/gpio/legacy.h>
#include "lgdt330x.h"
#include "lgdt3305.h"
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 68a0fcc2fa72..8931733a8e24 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -283,6 +283,7 @@ enum em28xx_chip_id {
CHIP_ID_EM2884 = 68,
CHIP_ID_EM28174 = 113,
CHIP_ID_EM28178 = 114,
+ CHIP_ID_EM28281 = 145,
CHIP_ID_EM2828X = 148,
};
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index da0422c65e5f..c418add65bb5 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -1213,6 +1213,9 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
{
struct em28xx *dev = vb2_get_drv_priv(vq);
struct em28xx_v4l2 *v4l2 = dev->v4l2;
+ struct em28xx_dmaqueue *dmaq = vq->type == V4L2_BUF_TYPE_VBI_CAPTURE ?
+ &dev->vbiq : &dev->vidq;
+ unsigned long flags = 0;
struct v4l2_frequency f;
struct v4l2_fh *owner;
int rc = 0;
@@ -1227,7 +1230,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
*/
rc = res_get(dev, vq->type);
if (rc)
- return rc;
+ goto exit;
if (v4l2->streaming_users == 0) {
/* First active streaming user, so allocate all the URBs */
@@ -1250,7 +1253,7 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
em28xx_urb_data_copy);
if (rc < 0) {
res_free(dev, vq->type);
- return rc;
+ goto exit;
}
/*
@@ -1275,7 +1278,18 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
}
v4l2->streaming_users++;
+ return 0;
+
+exit:
+ spin_lock_irqsave(&dev->slock, flags);
+ while (!list_empty(&dmaq->active)) {
+ struct em28xx_buffer *buf;
+ buf = list_entry(dmaq->active.next, struct em28xx_buffer, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+ }
+ spin_unlock_irqrestore(&dev->slock, flags);
return rc;
}
@@ -2275,18 +2289,27 @@ static int radio_s_tuner(struct file *file, void *priv,
}
/*
- * em28xx_free_v4l2() - Free struct em28xx_v4l2
+ * em28xx_free_v4l2() - v4l2_device release callback
*
- * @ref: struct kref for struct em28xx_v4l2
+ * @v4l2_dev: pointer to struct v4l2_device embedded in struct em28xx_v4l2
*
- * Called when all users of struct em28xx_v4l2 are gone
+ * Called by the v4l2 core when the last reference to the v4l2_device is
+ * released. At this point no userspace file handle nor video_device node
+ * keeps the v4l2 instance alive anymore, so it is safe to release all
+ * v4l2-related resources and drop the em28xx device reference taken when
+ * the v4l2 extension was initialized.
*/
-static void em28xx_free_v4l2(struct kref *ref)
+static void em28xx_free_v4l2(struct v4l2_device *v4l2_dev)
{
- struct em28xx_v4l2 *v4l2 = container_of(ref, struct em28xx_v4l2, ref);
+ struct em28xx_v4l2 *v4l2 =
+ container_of(v4l2_dev, struct em28xx_v4l2, v4l2_dev);
+ struct em28xx *dev = v4l2->dev;
- v4l2->dev->v4l2 = NULL;
+ v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
+ v4l2_device_unregister(v4l2_dev);
+ dev->v4l2 = NULL;
kfree(v4l2);
+ kref_put(&dev->ref, em28xx_free_device);
}
/*
@@ -2323,9 +2346,8 @@ static int em28xx_v4l2_open(struct file *filp)
return -ENODEV;
}
- em28xx_videodbg("open dev=%s type=%s users=%d\n",
- video_device_node_name(vdev), v4l2_type_names[fh_type],
- v4l2->users);
+ em28xx_videodbg("open dev=%s type=%s\n",
+ video_device_node_name(vdev), v4l2_type_names[fh_type]);
ret = v4l2_fh_open(filp);
if (ret) {
@@ -2336,7 +2358,7 @@ static int em28xx_v4l2_open(struct file *filp)
return ret;
}
- if (v4l2->users == 0) {
+ if (v4l2_fh_is_singular_file(filp)) {
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
if (vdev->vfl_type != VFL_TYPE_RADIO)
@@ -2354,10 +2376,6 @@ static int em28xx_v4l2_open(struct file *filp)
v4l2_device_call_all(&v4l2->v4l2_dev, 0, tuner, s_radio);
}
- kref_get(&dev->ref);
- kref_get(&v4l2->ref);
- v4l2->users++;
-
mutex_unlock(&dev->lock);
return 0;
@@ -2398,27 +2416,27 @@ static int em28xx_v4l2_fini(struct em28xx *dev)
if (video_is_registered(&v4l2->radio_dev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->radio_dev));
- video_unregister_device(&v4l2->radio_dev);
+ vb2_video_unregister_device(&v4l2->radio_dev);
}
if (video_is_registered(&v4l2->vbi_dev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vbi_dev));
- video_unregister_device(&v4l2->vbi_dev);
+ vb2_video_unregister_device(&v4l2->vbi_dev);
}
if (video_is_registered(&v4l2->vdev)) {
dev_info(&dev->intf->dev, "V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vdev));
- video_unregister_device(&v4l2->vdev);
+ vb2_video_unregister_device(&v4l2->vdev);
}
- v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
- v4l2_device_unregister(&v4l2->v4l2_dev);
-
- kref_put(&v4l2->ref, em28xx_free_v4l2);
-
mutex_unlock(&dev->lock);
- kref_put(&dev->ref, em28xx_free_device);
+ /*
+ * Drop the initial reference taken at v4l2_device_register() time.
+ * The em28xx_free_v4l2() release callback will be invoked once all
+ * userspace file handles to the video device nodes are closed.
+ */
+ v4l2_device_put(&v4l2->v4l2_dev);
return 0;
}
@@ -2460,13 +2478,13 @@ static int em28xx_v4l2_close(struct file *filp)
struct em28xx_v4l2 *v4l2 = dev->v4l2;
struct usb_device *udev = interface_to_usbdev(dev->intf);
int err;
+ bool last_user;
- em28xx_videodbg("users=%d\n", v4l2->users);
-
- vb2_fop_release(filp);
mutex_lock(&dev->lock);
+ last_user = v4l2_fh_is_singular_file(filp);
+ _vb2_fop_release(filp, NULL);
- if (v4l2->users == 1) {
+ if (last_user) {
/* No sense to try to write to the device */
if (dev->disconnected)
goto exit;
@@ -2489,10 +2507,7 @@ static int em28xx_v4l2_close(struct file *filp)
}
exit:
- v4l2->users--;
- kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock);
- kref_put(&dev->ref, em28xx_free_device);
return 0;
}
@@ -2711,7 +2726,6 @@ static int em28xx_v4l2_init(struct em28xx *dev)
mutex_unlock(&dev->lock);
return -ENOMEM;
}
- kref_init(&v4l2->ref);
v4l2->dev = dev;
dev->v4l2 = v4l2;
@@ -2722,9 +2736,21 @@ static int em28xx_v4l2_init(struct em28xx *dev)
if (ret < 0) {
dev_err(&dev->intf->dev,
"Call to v4l2_device_register() failed!\n");
- goto err;
+ dev->v4l2 = NULL;
+ kfree(v4l2);
+ mutex_unlock(&dev->lock);
+ return ret;
}
+ /*
+ * From this point on, em28xx_free_v4l2() will be used to release
+ * v4l2-related resources when the v4l2_device refcount reaches
+ * zero. Take a reference to the em28xx device so that it cannot
+ * be freed before the v4l2 instance is released.
+ */
+ v4l2->v4l2_dev.release = em28xx_free_v4l2;
+ kref_get(&dev->ref);
+
hdl = &v4l2->ctrl_handler;
v4l2_ctrl_handler_init(hdl, 9);
v4l2->v4l2_dev.ctrl_handler = hdl;
@@ -3048,8 +3074,6 @@ static int em28xx_v4l2_init(struct em28xx *dev)
dev_info(&dev->intf->dev,
"V4L2 extension successfully initialized\n");
- kref_get(&dev->ref);
-
mutex_unlock(&dev->lock);
return 0;
@@ -3058,27 +3082,29 @@ unregister_dev:
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->radio_dev));
- video_unregister_device(&v4l2->radio_dev);
+ vb2_video_unregister_device(&v4l2->radio_dev);
}
if (video_is_registered(&v4l2->vbi_dev)) {
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vbi_dev));
- video_unregister_device(&v4l2->vbi_dev);
+ vb2_video_unregister_device(&v4l2->vbi_dev);
}
if (video_is_registered(&v4l2->vdev)) {
dev_info(&dev->intf->dev,
"V4L2 device %s deregistered\n",
video_device_node_name(&v4l2->vdev));
- video_unregister_device(&v4l2->vdev);
+ vb2_video_unregister_device(&v4l2->vdev);
}
- v4l2_ctrl_handler_free(&v4l2->ctrl_handler);
- v4l2_device_unregister(&v4l2->v4l2_dev);
-err:
- dev->v4l2 = NULL;
- kref_put(&v4l2->ref, em28xx_free_v4l2);
mutex_unlock(&dev->lock);
+
+ /*
+ * Drop the initial reference. em28xx_free_v4l2() will be called
+ * once the last video_device node release has decremented the
+ * v4l2_device refcount to zero.
+ */
+ v4l2_device_put(&v4l2->v4l2_dev);
return ret;
}
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 711f281613f5..8eee639b0940 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -150,6 +150,7 @@
#define EM2828X_BOARD_HAUPPAUGE_955_V2 110
#define EM2828X_BOARD_HAUPPAUGE_975_V2 111
#define EM28178_BOARD_PCTV_461E_V3 112
+#define EM28281_BOARD_STARTECH_SVID2USB232 113
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -558,7 +559,6 @@ struct em28xx_eeprom {
#define EM28XX_RESOURCE_VBI 0x02
struct em28xx_v4l2 {
- struct kref ref;
struct em28xx *dev;
struct v4l2_device v4l2_dev;
@@ -582,7 +582,6 @@ struct em28xx_v4l2 {
int sensor_yres;
int sensor_xtal;
- int users; /* user count for exclusive use */
int streaming_users; /* number of actively streaming users */
u32 frequency; /* selected tuner frequency */
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
index 25b3ee25aaa4..453ab5c3aa03 100644
--- a/drivers/media/usb/go7007/go7007-driver.c
+++ b/drivers/media/usb/go7007/go7007-driver.c
@@ -264,17 +264,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
ret = go7007_init_encoder(go);
mutex_unlock(&go->hw_lock);
if (ret < 0)
- return ret;
+ goto err_unregister_v4l2_dev;
ret = go7007_v4l2_ctrl_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
if (!go->i2c_adapter_online &&
go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
ret = go7007_i2c_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
go->i2c_adapter_online = 1;
}
if (go->i2c_adapter_online) {
@@ -304,13 +304,19 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
ret = go7007_v4l2_init(go);
if (ret < 0)
- return ret;
+ goto err_free_controls;
if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
go->audio_enabled = 1;
go7007_snd_init(go);
}
return 0;
+
+err_free_controls:
+ v4l2_ctrl_handler_free(&go->hdl);
+err_unregister_v4l2_dev:
+ v4l2_device_unregister(&go->v4l2_dev);
+ return ret;
}
EXPORT_SYMBOL(go7007_register_encoder);
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
index 86ce593e0c54..8cf959c20e30 100644
--- a/drivers/media/usb/go7007/go7007-fw.c
+++ b/drivers/media/usb/go7007/go7007-fw.c
@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/device.h>
@@ -58,14 +59,16 @@ struct code_gen {
#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
#define CODE_ADD(name, val, length) do { \
- name.b -= (length); \
- name.a |= (val) << name.b; \
- while (name.b <= 24) { \
- *name.p = name.a >> 24; \
- ++name.p; \
- name.a <<= 8; \
- name.b += 8; \
- name.len += 8; \
+ if (length) { \
+ name.b -= (length); \
+ name.a |= (val) << name.b; \
+ while (name.b <= 24) { \
+ *name.p = name.a >> 24; \
+ ++name.p; \
+ name.a <<= 8; \
+ name.b += 8; \
+ name.len += 8; \
+ } \
} \
} while (0)
@@ -707,11 +710,10 @@ done:
static int vti_bitlen(struct go7007 *go)
{
- unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
+ unsigned int max_time_incr = go->sensor_framerate / go->fps_scale;
+ int bitlen = fls(max_time_incr);
- for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
- ;
- return i + 1;
+ return bitlen ?: 1;
}
static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
@@ -1209,7 +1211,7 @@ static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
0xbf08, fps,
0xbf09, 0,
0xbff2, vop_time_increment_bitlength,
- 0xbff3, (1 << vop_time_increment_bitlength) - 1,
+ 0xbff3, GENMASK(vop_time_increment_bitlength - 1, 0),
0xbfe6, 0,
0xbfe7, (fps / 1000) << 8,
0, 0,
diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c
index e4b9f37be77b..01d547ad678d 100644
--- a/drivers/media/usb/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c
@@ -195,6 +195,13 @@ static const struct snd_device_ops go7007_snd_device_ops = {
.dev_free = go7007_snd_free,
};
+static void go7007_snd_card_free(struct snd_card *card)
+{
+ struct go7007 *go = card->private_data;
+
+ v4l2_device_put(&go->v4l2_dev);
+}
+
int go7007_snd_init(struct go7007 *go)
{
static int dev;
@@ -245,6 +252,8 @@ int go7007_snd_init(struct go7007 *go)
gosnd->substream = NULL;
go->snd_context = gosnd;
v4l2_device_get(&go->v4l2_dev);
+ gosnd->card->private_data = go;
+ gosnd->card->private_free = go7007_snd_card_free;
++dev;
return 0;
@@ -263,7 +272,6 @@ int go7007_snd_remove(struct go7007 *go)
snd_card_disconnect(gosnd->card);
snd_card_free_when_closed(gosnd->card);
- v4l2_device_put(&go->v4l2_dev);
return 0;
}
EXPORT_SYMBOL(go7007_snd_remove);
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 0b8182edf8e4..3917913c3b47 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -2277,6 +2277,11 @@ static int s2255_probe(struct usb_interface *interface,
}
/* check the firmware is valid */
fw_size = dev->fw_data->fw->size;
+ if (fw_size < 8) {
+ dev_err(&interface->dev, "Firmware invalid: too small.\n");
+ retval = -ENODEV;
+ goto errorFWMARKER;
+ }
pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
if (*pdata != S2255_FW_MARKER) {
diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c
index f9462a9ca761..5058cada0d0a 100644
--- a/drivers/media/usb/stk1160/stk1160-core.c
+++ b/drivers/media/usb/stk1160/stk1160-core.c
@@ -263,7 +263,7 @@ static int stk1160_scan_usb(struct usb_interface *intf, struct usb_device *udev,
static int stk1160_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- int rc = 0;
+ int rc;
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct usb_device *udev;
@@ -290,15 +290,13 @@ static int stk1160_probe(struct usb_interface *interface,
* Also, check if device speed is fast enough.
*/
rc = stk1160_scan_usb(interface, udev, alt_max_pkt_size);
- if (rc < 0) {
- kfree(alt_max_pkt_size);
- return rc;
- }
+ if (rc < 0)
+ goto free_array;
dev = kzalloc_obj(struct stk1160);
if (dev == NULL) {
- kfree(alt_max_pkt_size);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto free_array;
}
dev->alt_max_pkt_size = alt_max_pkt_size;
@@ -379,8 +377,9 @@ unreg_v4l2:
free_ctrl:
v4l2_ctrl_handler_free(&dev->ctrl_handler);
free_err:
- kfree(alt_max_pkt_size);
kfree(dev);
+free_array:
+ kfree(alt_max_pkt_size);
return rc;
}
diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c
index f4baf9263286..020b75fc5b2d 100644
--- a/drivers/media/usb/stk1160/stk1160-video.c
+++ b/drivers/media/usb/stk1160/stk1160-video.c
@@ -48,6 +48,9 @@ static inline void print_err_status(struct stk1160 *dev,
case -EILSEQ:
errmsg = "CRC/Timeout (could be anything)";
break;
+ case -ESHUTDOWN:
+ errmsg = "host controller removed";
+ break;
case -ETIME:
errmsg = "Device does not respond";
break;
diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c
index 333bd305a4f9..ae0a14e5ed2a 100644
--- a/drivers/media/usb/usbtv/usbtv-audio.c
+++ b/drivers/media/usb/usbtv/usbtv-audio.c
@@ -317,6 +317,13 @@ static const struct snd_pcm_ops snd_usbtv_pcm_ops = {
.pointer = snd_usbtv_pointer,
};
+static void usbtv_audio_card_free(struct snd_card *card)
+{
+ struct usbtv *usbtv = card->private_data;
+
+ v4l2_device_put(&usbtv->v4l2_dev);
+}
+
int usbtv_audio_init(struct usbtv *usbtv)
{
int rv;
@@ -331,6 +338,10 @@ int usbtv_audio_init(struct usbtv *usbtv)
if (rv < 0)
return rv;
+ v4l2_device_get(&usbtv->v4l2_dev);
+ card->private_data = usbtv;
+ card->private_free = usbtv_audio_card_free;
+
strscpy(card->driver, usbtv->dev->driver->name, sizeof(card->driver));
strscpy(card->shortname, "usbtv", sizeof(card->shortname));
snprintf(card->longname, sizeof(card->longname),
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 888a2e213b08..f36d60e6ff41 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -898,9 +898,18 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
sd->subdev_notifier = NULL;
if (sd->asc_list.next) {
- list_for_each_entry_safe(asc, asc_tmp, &sd->asc_list,
- asc_subdev_entry) {
- v4l2_async_unbind_subdev_one(asc->notifier, asc);
+ if (list_empty(&sd->asc_list)) {
+ /*
+ * If the sub-device was registered through other means
+ * than v4l2-async, there are no async connections but
+ * the sub-device may still well be registered.
+ * Unregister it now.
+ */
+ v4l2_device_unregister_subdev(sd);
+ } else {
+ list_for_each_entry_safe(asc, asc_tmp, &sd->asc_list,
+ asc_subdev_entry)
+ v4l2_async_unbind_subdev_one(asc->notifier, asc);
}
}
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index ba047d7d8601..1214e7744ac0 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -16,6 +16,9 @@
static const union v4l2_ctrl_ptr ptr_null;
+#define V4L2_HEVC_MAX_SHORT_TERM_REF_PIC_SETS 64
+#define V4L2_HEVC_MAX_LONG_TERM_REF_PICS_SPS 32
+
static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl,
u32 changes)
{
@@ -1214,6 +1217,10 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
case V4L2_CTRL_TYPE_HEVC_SPS:
p_hevc_sps = p;
+ if (p_hevc_sps->num_short_term_ref_pic_sets >
+ V4L2_HEVC_MAX_SHORT_TERM_REF_PIC_SETS)
+ return -EINVAL;
+
if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) {
p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0;
p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0;
@@ -1224,6 +1231,9 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
if (!(p_hevc_sps->flags &
V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT))
p_hevc_sps->num_long_term_ref_pics_sps = 0;
+ else if (p_hevc_sps->num_long_term_ref_pics_sps >
+ V4L2_HEVC_MAX_LONG_TERM_REF_PICS_SPS)
+ return -EINVAL;
break;
case V4L2_CTRL_TYPE_HEVC_PPS:
@@ -1280,6 +1290,11 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
if (p_hevc_st_rps->flags & ~V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED)
return -EINVAL;
+ if (p_hevc_st_rps->num_negative_pics > 16 ||
+ p_hevc_st_rps->num_positive_pics > 16 ||
+ p_hevc_st_rps->num_negative_pics +
+ p_hevc_st_rps->num_positive_pics > 16)
+ return -EINVAL;
break;
case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 62a3a452f788..570df3c415b0 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -633,6 +633,8 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
if (!link->remote_node)
goto err_put_remote_endpoint;
+ fwnode_handle_put(fwnode);
+
return 0;
err_put_remote_endpoint:
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index 115bb37577a1..adff564bf3fd 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -164,6 +164,24 @@ static const struct int3472_gpio_map int3472_gpio_map[] = {
.con_id = "dvdd",
.enable_time_us = 45 * USEC_PER_MSEC,
},
+ { /* imx471 expects "vana" as con_id for power enable */
+ .hid = "SONY471A",
+ .type_from = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .type_to = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .con_id = "vana",
+ .enable_time_us = GPIO_REGULATOR_ENABLE_TIME,
+ },
+ {
+ /*
+ * imx471 (on Lenovo ThinkPads X1 G14) expects "vana" as con_id
+ * for power enable
+ */
+ .hid = "TBE20A0",
+ .type_from = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .type_to = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .con_id = "vana",
+ .enable_time_us = GPIO_REGULATOR_ENABLE_TIME,
+ },
};
static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3472, u8 *type,
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
index 4732b45b25ee..fbcd73b711ba 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf.h
@@ -20,7 +20,7 @@
* Data structures.
*
****************************************************************/
-/**
+/*
* @brief Data structure for the circular buffer.
*/
typedef struct ia_css_circbuf_s ia_css_circbuf_t;
@@ -29,7 +29,7 @@ struct ia_css_circbuf_s {
ia_css_circbuf_elem_t *elems; /* an array of elements */
};
-/**
+/*
* @brief Create the circular buffer.
*
* @param cb The pointer to the circular buffer.
@@ -41,7 +41,7 @@ void ia_css_circbuf_create(
ia_css_circbuf_elem_t *elems,
ia_css_circbuf_desc_t *desc);
-/**
+/*
* @brief Destroy the circular buffer.
*
* @param cb The pointer to the circular buffer.
@@ -49,7 +49,7 @@ void ia_css_circbuf_create(
void ia_css_circbuf_destroy(
ia_css_circbuf_t *cb);
-/**
+/*
* @brief Pop a value out of the circular buffer.
* Get a value at the head of the circular buffer.
* The user should call "ia_css_circbuf_is_empty()"
@@ -62,7 +62,7 @@ void ia_css_circbuf_destroy(
uint32_t ia_css_circbuf_pop(
ia_css_circbuf_t *cb);
-/**
+/*
* @brief Extract a value out of the circular buffer.
* Get a value at an arbitrary position in the circular
* buffer. The user should call "ia_css_circbuf_is_empty()"
@@ -82,7 +82,7 @@ uint32_t ia_css_circbuf_extract(
* Inline functions.
*
****************************************************************/
-/**
+/*
* @brief Set the "val" field in the element.
*
* @param elem The pointer to the element.
@@ -97,7 +97,7 @@ static inline void ia_css_circbuf_elem_set_val(
elem->val = val;
}
-/**
+/*
* @brief Initialize the element.
*
* @param elem The pointer to the element.
@@ -109,7 +109,7 @@ static inline void ia_css_circbuf_elem_init(
ia_css_circbuf_elem_set_val(elem, 0);
}
-/**
+/*
* @brief Copy an element.
*
* @param src The element as the copy source.
@@ -125,7 +125,7 @@ static inline void ia_css_circbuf_elem_cpy(
ia_css_circbuf_elem_set_val(dest, src->val);
}
-/**
+/*
* @brief Get position in the circular buffer.
*
* @param cb The pointer to the circular buffer.
@@ -151,7 +151,7 @@ static inline uint8_t ia_css_circbuf_get_pos_at_offset(
return (base + offset) % cb->desc->size;
}
-/**
+/*
* @brief Get the offset between two positions in the circular buffer.
* Get the offset from the source position to the terminal position,
* along the direction in which the new elements come in.
@@ -178,7 +178,7 @@ static inline int ia_css_circbuf_get_offset(
return offset;
}
-/**
+/*
* @brief Get the maximum number of elements.
*
* @param cb The pointer to the circular buffer.
@@ -196,7 +196,7 @@ static inline uint32_t ia_css_circbuf_get_size(
return cb->desc->size;
}
-/**
+/*
* @brief Get the number of available elements.
*
* @param cb The pointer to the circular buffer.
@@ -216,7 +216,7 @@ static inline uint32_t ia_css_circbuf_get_num_elems(
return (uint32_t)num;
}
-/**
+/*
* @brief Test if the circular buffer is empty.
*
* @param cb The pointer to the circular buffer.
@@ -234,7 +234,7 @@ static inline bool ia_css_circbuf_is_empty(
return ia_css_circbuf_desc_is_empty(cb->desc);
}
-/**
+/*
* @brief Test if the circular buffer is full.
*
* @param cb The pointer to the circular buffer.
@@ -251,7 +251,7 @@ static inline bool ia_css_circbuf_is_full(ia_css_circbuf_t *cb)
return ia_css_circbuf_desc_is_full(cb->desc);
}
-/**
+/*
* @brief Write a new element into the circular buffer.
* Write a new element WITHOUT checking whether the
* circular buffer is full or not. So it also overwrites
@@ -275,7 +275,7 @@ static inline void ia_css_circbuf_write(
cb->desc->end = ia_css_circbuf_get_pos_at_offset(cb, cb->desc->end, 1);
}
-/**
+/*
* @brief Push a value in the circular buffer.
* Put a new value at the tail of the circular buffer.
* The user should call "ia_css_circbuf_is_full()"
@@ -300,7 +300,7 @@ static inline void ia_css_circbuf_push(
ia_css_circbuf_write(cb, elem);
}
-/**
+/*
* @brief Get the number of free elements.
*
* @param cb The pointer to the circular buffer.
@@ -316,7 +316,7 @@ static inline uint32_t ia_css_circbuf_get_free_elems(
return ia_css_circbuf_desc_get_free_elems(cb->desc);
}
-/**
+/*
* @brief Peek an element in Circular Buffer.
*
* @param cb The pointer to the circular buffer.
@@ -328,7 +328,7 @@ uint32_t ia_css_circbuf_peek(
ia_css_circbuf_t *cb,
int offset);
-/**
+/*
* @brief Get an element in Circular Buffer.
*
* @param cb The pointer to the circular buffer.
@@ -340,7 +340,7 @@ uint32_t ia_css_circbuf_peek_from_start(
ia_css_circbuf_t *cb,
int offset);
-/**
+/*
* @brief Increase Size of a Circular Buffer.
* Use 'CAUTION' before using this function, This was added to
* support / fix issue with increasing size for tagger only
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
index 971e07f2acc5..090e2e764042 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_comm.h
@@ -24,7 +24,7 @@
* Portable Data structures
*
****************************************************************/
-/**
+/*
* @brief Data structure for the circular descriptor.
*/
typedef struct ia_css_circbuf_desc_s ia_css_circbuf_desc_t;
@@ -40,7 +40,7 @@ struct ia_css_circbuf_desc_s {
static_assert(sizeof(struct ia_css_circbuf_desc_s) == SIZE_OF_IA_CSS_CIRCBUF_DESC_S_STRUCT);
-/**
+/*
* @brief Data structure for the circular buffer element.
*/
typedef struct ia_css_circbuf_elem_s ia_css_circbuf_elem_t;
diff --git a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
index 64f754f1d49b..3306a7a0fa5e 100644
--- a/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
+++ b/drivers/staging/media/atomisp/pci/base/circbuf/interface/ia_css_circbuf_desc.h
@@ -17,7 +17,7 @@
* Inline functions.
*
****************************************************************/
-/**
+/*
* @brief Test if the circular buffer is empty.
*
* @param cb_desc The pointer to the circular buffer descriptor.
@@ -33,7 +33,7 @@ static inline bool ia_css_circbuf_desc_is_empty(
return (cb_desc->end == cb_desc->start);
}
-/**
+/*
* @brief Test if the circular buffer descriptor is full.
*
* @param cb_desc The pointer to the circular buffer
@@ -50,7 +50,7 @@ static inline bool ia_css_circbuf_desc_is_full(
return ((cb_desc->end + 1) % cb_desc->size) == cb_desc->start;
}
-/**
+/*
* @brief Initialize the circular buffer descriptor
*
* @param cb_desc The pointer circular buffer descriptor
@@ -64,7 +64,7 @@ static inline void ia_css_circbuf_desc_init(
cb_desc->size = size;
}
-/**
+/*
* @brief Get a position in the circular buffer descriptor.
*
* @param cb The pointer to the circular buffer descriptor.
@@ -89,7 +89,7 @@ static inline uint8_t ia_css_circbuf_desc_get_pos_at_offset(
return (base + offset) % cb_desc->size;
}
-/**
+/*
* @brief Get the offset between two positions in the circular buffer
* descriptor.
* Get the offset from the source position to the terminal position,
@@ -116,7 +116,7 @@ static inline int ia_css_circbuf_desc_get_offset(
return offset;
}
-/**
+/*
* @brief Get the number of available elements.
*
* @param cb_desc The pointer to the circular buffer.
@@ -137,7 +137,7 @@ static inline uint32_t ia_css_circbuf_desc_get_num_elems(
return (uint32_t)num;
}
-/**
+/*
* @brief Get the number of free elements.
*
* @param cb_desc The pointer to the circular buffer descriptor.
diff --git a/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
index 24cd99a659ca..dce8dd23b47c 100644
--- a/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
+++ b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h
@@ -81,7 +81,7 @@ bool ia_css_util_res_leq(
struct ia_css_resolution b);
/* ISP2401 */
-/**
+/*
* @brief Check if resolution is zero
*
* @param[in] resolution The resolution to check
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
index 989f55bec519..43bb352a8e05 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/csi_rx_private.h
@@ -21,7 +21,7 @@
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Refer to "csi_rx_public.h" for details.
*/
@@ -35,7 +35,7 @@ static inline hrt_data csi_rx_fe_ctrl_reg_load(
hrt_data));
}
-/**
+/*
* @brief Store a value to the register.
* Refer to "ibuf_ctrl_public.h" for details.
*/
@@ -51,7 +51,7 @@ static inline void csi_rx_fe_ctrl_reg_store(
value);
}
-/**
+/*
* @brief Load the register value.
* Refer to "csi_rx_public.h" for details.
*/
@@ -65,7 +65,7 @@ static inline hrt_data csi_rx_be_ctrl_reg_load(
hrt_data));
}
-/**
+/*
* @brief Store a value to the register.
* Refer to "ibuf_ctrl_public.h" for details.
*/
@@ -88,7 +88,7 @@ static inline void csi_rx_be_ctrl_reg_store(
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the state of the csi rx fe dlane process.
* Refer to "csi_rx_public.h" for details.
*/
@@ -103,7 +103,7 @@ static inline void csi_rx_fe_ctrl_get_dlane_state(
csi_rx_fe_ctrl_reg_load(ID, _HRT_CSI_RX_DLY_CNT_SETTLE_DLANE_REG_IDX(lane));
}
-/**
+/*
* @brief Get the csi rx fe state.
* Refer to "csi_rx_public.h" for details.
*/
@@ -142,7 +142,7 @@ static inline void csi_rx_fe_ctrl_get_state(
}
}
-/**
+/*
* @brief dump the csi rx fe state.
* Refer to "csi_rx_public.h" for details.
*/
@@ -180,7 +180,7 @@ static inline void csi_rx_fe_ctrl_dump_state(
}
}
-/**
+/*
* @brief Get the csi rx be state.
* Refer to "csi_rx_public.h" for details.
*/
@@ -243,7 +243,7 @@ static inline void csi_rx_be_ctrl_get_state(
}
}
-/**
+/*
* @brief Dump the csi rx be state.
* Refer to "csi_rx_public.h" for details.
*/
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
index 4bd8209aaa01..85439d561ba3 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_irq_private.h
@@ -15,7 +15,7 @@
| Native command interface (NCI) |
+ -------------------------------------------------------*/
-/**
+/*
* @brief Get the isys irq status.
* Refer to "isys_irq.h" for details.
*/
@@ -34,7 +34,7 @@ void isys_irqc_state_get(
*/
}
-/**
+/*
* @brief Dump the isys irq status.
* Refer to "isys_irq.h" for details.
*/
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
index 8e295cd78129..88a763365631 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/isys_stream2mmio_private.h
@@ -27,7 +27,7 @@
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the stream2mmio-controller state.
* Refer to "stream2mmio_public.h" for details.
*/
@@ -45,7 +45,7 @@ STORAGE_CLASS_STREAM2MMIO_C void stream2mmio_get_state(
stream2mmio_get_sid_state(ID, i, &state->sid_state[i]);
}
-/**
+/*
* @brief Get the state of the stream2mmio-controller sidess.
* Refer to "stream2mmio_public.h" for details.
*/
@@ -76,7 +76,7 @@ STORAGE_CLASS_STREAM2MMIO_C void stream2mmio_get_sid_state(
stream2mmio_reg_load(ID, sid_id, STREAM2MMIO_BLOCK_WHEN_NO_CMD_REG_ID);
}
-/**
+/*
* @brief Dump the state of the stream2mmio-controller sidess.
* Refer to "stream2mmio_public.h" for details.
*/
@@ -92,7 +92,7 @@ STORAGE_CLASS_STREAM2MMIO_C void stream2mmio_print_sid_state(
ia_css_print("\t \t block when no cmd 0x%x\n", state->block_when_no_cmd);
}
-/**
+/*
* @brief Dump the ibuf-controller state.
* Refer to "stream2mmio_public.h" for details.
*/
@@ -119,7 +119,7 @@ STORAGE_CLASS_STREAM2MMIO_C void stream2mmio_dump_state(
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Refer to "stream2mmio_public.h" for details.
*/
@@ -137,7 +137,7 @@ STORAGE_CLASS_STREAM2MMIO_C hrt_data stream2mmio_reg_load(
(reg_bank_offset + reg_idx) * sizeof(hrt_data));
}
-/**
+/*
* @brief Store a value to the register.
* Refer to "stream2mmio_public.h" for details.
*/
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
index b8b98106bd31..0faf6ffdf55d 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/host/pixelgen_private.h
@@ -16,7 +16,7 @@
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Refer to "pixelgen_public.h" for details.
*/
@@ -30,7 +30,7 @@ STORAGE_CLASS_PIXELGEN_C hrt_data pixelgen_ctrl_reg_load(
hrt_data));
}
-/**
+/*
* @brief Store a value to the register.
* Refer to "pixelgen_ctrl_public.h" for details.
*/
@@ -53,7 +53,7 @@ STORAGE_CLASS_PIXELGEN_C void pixelgen_ctrl_reg_store(
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the pixelgen state.
* Refer to "pixelgen_public.h" for details.
*/
@@ -117,7 +117,7 @@ STORAGE_CLASS_PIXELGEN_C void pixelgen_ctrl_get_state(
pixelgen_ctrl_reg_load(ID, _PXG_TPG_B2_REG_IDX);
}
-/**
+/*
* @brief Dump the pixelgen state.
* Refer to "pixelgen_public.h" for details.
*/
diff --git a/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h b/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
index 59e0b44bfdc3..b5a6a8f0c3d2 100644
--- a/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
+++ b/drivers/staging/media/atomisp/pci/css_2401_system/pixelgen_global.h
@@ -9,7 +9,7 @@
#include <type_support.h>
-/**
+/*
* Pixel-generator. ("pixelgen_global.h")
*/
/*
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h b/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
index 2dc0fb88399f..e4c136660b1e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/timed_ctrl_global.h
@@ -11,7 +11,7 @@
#include "timed_controller_defs.h"
-/**
+/*
* Order of the input bits for the timed controller taken from
* ISP_CSS_2401 System Architecture Description valid for
* 2400, 2401.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
index ca33a1e03d8d..f5b0ff414395 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/device_access/device_access.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
index 2002960f078e..e8ce556bfd6a 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
@@ -12,7 +12,7 @@
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the csi rx frontend state.
* Get the state of the csi rx frontend regiester-set.
*
@@ -22,7 +22,7 @@
void csi_rx_fe_ctrl_get_state(
const csi_rx_frontend_ID_t ID,
csi_rx_fe_ctrl_state_t *state);
-/**
+/*
* @brief Dump the csi rx frontend state.
* Dump the state of the csi rx frontend regiester-set.
*
@@ -32,7 +32,7 @@ void csi_rx_fe_ctrl_get_state(
void csi_rx_fe_ctrl_dump_state(
const csi_rx_frontend_ID_t ID,
csi_rx_fe_ctrl_state_t *state);
-/**
+/*
* @brief Get the state of the csi rx fe dlane.
* Get the state of the register set per dlane process.
*
@@ -44,7 +44,7 @@ void csi_rx_fe_ctrl_get_dlane_state(
const csi_rx_frontend_ID_t ID,
const u32 lane,
csi_rx_fe_ctrl_lane_t *dlane_state);
-/**
+/*
* @brief Get the csi rx backend state.
* Get the state of the csi rx backend regiester-set.
*
@@ -54,7 +54,7 @@ void csi_rx_fe_ctrl_get_dlane_state(
void csi_rx_be_ctrl_get_state(
const csi_rx_backend_ID_t ID,
csi_rx_be_ctrl_state_t *state);
-/**
+/*
* @brief Dump the csi rx backend state.
* Dump the state of the csi rx backend regiester-set.
*
@@ -71,7 +71,7 @@ void csi_rx_be_ctrl_dump_state(
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Load the value of the register of the csi rx fe.
*
@@ -83,7 +83,7 @@ void csi_rx_be_ctrl_dump_state(
hrt_data csi_rx_fe_ctrl_reg_load(
const csi_rx_frontend_ID_t ID,
const hrt_address reg);
-/**
+/*
* @brief Store a value to the register.
* Store a value to the register of the csi rx fe.
*
@@ -96,7 +96,7 @@ void csi_rx_fe_ctrl_reg_store(
const csi_rx_frontend_ID_t ID,
const hrt_address reg,
const hrt_data value);
-/**
+/*
* @brief Load the register value.
* Load the value of the register of the csirx be.
*
@@ -108,7 +108,7 @@ void csi_rx_fe_ctrl_reg_store(
hrt_data csi_rx_be_ctrl_reg_load(
const csi_rx_backend_ID_t ID,
const hrt_address reg);
-/**
+/*
* @brief Store a value to the register.
* Store a value to the register of the csi rx be.
*
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
index 7ed55d427cf6..e4f77e975f4e 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/isys_stream2mmio_public.h
@@ -12,7 +12,7 @@
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the stream2mmio-controller state.
* Get the state of the stream2mmio-controller regiester-set.
*
@@ -23,7 +23,7 @@ STORAGE_CLASS_STREAM2MMIO_H void stream2mmio_get_state(
const stream2mmio_ID_t ID,
stream2mmio_state_t *state);
-/**
+/*
* @brief Get the state of the stream2mmio-controller sidess.
* Get the state of the register set per buf-controller sidess.
*
@@ -42,7 +42,7 @@ STORAGE_CLASS_STREAM2MMIO_H void stream2mmio_get_sid_state(
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Load the value of the register of the stream2mmio-controller.
*
@@ -57,7 +57,7 @@ STORAGE_CLASS_STREAM2MMIO_H hrt_data stream2mmio_reg_load(
const stream2mmio_sid_ID_t sid_id,
const uint32_t reg_idx);
-/**
+/*
* @brief Dump the SID processor state.
* Dump the state of the sid regiester-set.
*
@@ -65,7 +65,7 @@ STORAGE_CLASS_STREAM2MMIO_H hrt_data stream2mmio_reg_load(
*/
STORAGE_CLASS_STREAM2MMIO_H void stream2mmio_print_sid_state(
stream2mmio_sid_state_t *state);
-/**
+/*
* @brief Dump the stream2mmio state.
* Dump the state of the ibuf-controller regiester-set.
*
@@ -75,7 +75,7 @@ STORAGE_CLASS_STREAM2MMIO_H void stream2mmio_print_sid_state(
STORAGE_CLASS_STREAM2MMIO_H void stream2mmio_dump_state(
const stream2mmio_ID_t ID,
stream2mmio_state_t *state);
-/**
+/*
* @brief Store a value to the register.
* Store a value to the registe of the stream2mmio-controller.
*
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
index dc31ce3cd741..6aabf0b1995f 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/pixelgen_public.h
@@ -12,7 +12,7 @@
* Native command interface (NCI).
*
*****************************************************/
-/**
+/*
* @brief Get the pixelgen state.
* Get the state of the pixelgen regiester-set.
*
@@ -22,7 +22,7 @@
STORAGE_CLASS_PIXELGEN_H void pixelgen_ctrl_get_state(
const pixelgen_ID_t ID,
pixelgen_ctrl_state_t *state);
-/**
+/*
* @brief Dump the pixelgen state.
* Dump the state of the pixelgen regiester-set.
*
@@ -39,7 +39,7 @@ STORAGE_CLASS_PIXELGEN_H void pixelgen_ctrl_dump_state(
* Device level interface (DLI).
*
*****************************************************/
-/**
+/*
* @brief Load the register value.
* Load the value of the register of the pixelgen
*
@@ -51,7 +51,7 @@ STORAGE_CLASS_PIXELGEN_H void pixelgen_ctrl_dump_state(
STORAGE_CLASS_PIXELGEN_H hrt_data pixelgen_ctrl_reg_load(
const pixelgen_ID_t ID,
const hrt_address reg);
-/**
+/*
* @brief Store a value to the register.
* Store a value to the registe of the pixelgen
*
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
index ad83ff97bbd6..1652c9f79349 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/host/tag_public.h
@@ -7,7 +7,7 @@
#ifndef __TAG_PUBLIC_H_INCLUDED__
#define __TAG_PUBLIC_H_INCLUDED__
-/**
+/*
* @brief Creates the tag description from the given parameters.
* @param[in] num_captures
* @param[in] skip
@@ -21,7 +21,7 @@ sh_css_create_tag_descr(int num_captures,
unsigned int exp_id,
struct sh_css_tag_descr *tag_descr);
-/**
+/*
* @brief Encodes the members of tag description into a 32-bit value.
* @param[in] tag Pointer to the tag description
* @return (unsigned int) Encoded 32-bit tag-info
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
index 473d8d4fb9ba..20a5faad0716 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/platform_support.h
@@ -7,7 +7,7 @@
#ifndef __PLATFORM_SUPPORT_H_INCLUDED__
#define __PLATFORM_SUPPORT_H_INCLUDED__
-/**
+/*
* @file
* Platform specific includes and functionality.
*/
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h b/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
index 097be6bd3cb5..cbd290121a28 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/type_support.h
@@ -7,7 +7,7 @@
#ifndef __TYPE_SUPPORT_H_INCLUDED__
#define __TYPE_SUPPORT_H_INCLUDED__
-/**
+/*
* @file
* Platform specific types.
*
diff --git a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
index 7acfedb541d8..936b17950b3a 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_frame_public.h
@@ -119,7 +119,7 @@ struct ia_css_frame_info {
.raw_bayer_order = IA_CSS_BAYER_ORDER_NUM, \
}
-/**
+/*
* Specifies the DVS loop delay in "frame periods"
*/
enum ia_css_frame_delay {
diff --git a/drivers/staging/media/atomisp/pci/ia_css_host_data.h b/drivers/staging/media/atomisp/pci/ia_css_host_data.h
index 0e45650cc1ab..547542577902 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_host_data.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_host_data.h
@@ -10,7 +10,7 @@
#include <ia_css_types.h> /* ia_css_pipe */
-/**
+/*
* @brief Allocate structure ia_css_host_data.
*
* @param[in] size Size of the requested host data
@@ -22,7 +22,7 @@
struct ia_css_host_data *
ia_css_host_data_allocate(size_t size);
-/**
+/*
* @brief Free structure ia_css_host_data.
*
* @param[in] me Pointer to structure, if a NULL is passed functions
diff --git a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
index 2bb06b0ff5db..1d1b704b2bc6 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_pipe_public.h
@@ -44,7 +44,7 @@ enum ia_css_pipe_mode {
/* Temporary define */
#define IA_CSS_PIPE_MODE_NUM (IA_CSS_PIPE_MODE_YUVPP + 1)
-/**
+/*
* Enumeration of pipe versions.
* the order should match with definition in sh_css_defs.h
*/
@@ -55,7 +55,7 @@ enum ia_css_pipe_version {
IA_CSS_PIPE_VERSION_2_7 = 4 /** ISP2.7 pipe */
};
-/**
+/*
* Pipe configuration structure.
* Resolution properties are filled by Driver, kernel configurations are
* set by AIC
@@ -123,7 +123,7 @@ struct ia_css_pipe_config {
to retrieve shading gains which correspond to bayer data. */
};
-/**
+/*
* Default settings for newly created pipe configurations.
*/
#define DEFAULT_PIPE_CONFIG { \
@@ -175,7 +175,7 @@ struct ia_css_pipe_info {
output at the first valid frame. */
};
-/**
+/*
* Defaults for ia_css_pipe_info structs.
*/
#define DEFAULT_PIPE_INFO {\
diff --git a/drivers/staging/media/atomisp/pci/ia_css_prbs.h b/drivers/staging/media/atomisp/pci/ia_css_prbs.h
index abdbcb8fda53..3bb1e5dbb4fc 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_prbs.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_prbs.h
@@ -19,7 +19,7 @@ enum ia_css_prbs_id {
IA_CSS_PRBS_ID2
};
-/**
+/*
* Maximum number of PRBS IDs.
*
* Make sure the value of this define gets changed to reflect the correct
@@ -27,7 +27,7 @@ enum ia_css_prbs_id {
*/
#define N_CSS_PRBS_IDS (IA_CSS_PRBS_ID2 + 1)
-/**
+/*
* PRBS configuration structure.
*
* Seed the for the Pseudo Random Bit Sequence.
diff --git a/drivers/staging/media/atomisp/pci/ia_css_stream.h b/drivers/staging/media/atomisp/pci/ia_css_stream.h
index c8de632a8e12..578dc45785fc 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_stream.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_stream.h
@@ -13,7 +13,7 @@
#include "ia_css_types.h"
#include "ia_css_stream_public.h"
-/**
+/*
* structure to hold all internal stream related information
*/
struct ia_css_stream {
diff --git a/drivers/staging/media/atomisp/pci/ia_css_timer.h b/drivers/staging/media/atomisp/pci/ia_css_timer.h
index da752834adf4..5c73e8c61588 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_timer.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_timer.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
@@ -42,7 +42,10 @@ struct ia_css_time_meas {
clock_value_t end_timer_value; /** measured time in ticks */
};
-/**@brief SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT checks to ensure correct alignment for struct ia_css_clock_tick. */
+/*
+ * @brief SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT checks to ensure correct alignment
+ * for struct ia_css_clock_tick.
+ */
#define SIZE_OF_IA_CSS_CLOCK_TICK_STRUCT sizeof(clock_value_t)
/* @brief checks to ensure correct alignment for ia_css_time_meas. */
#define SIZE_OF_IA_CSS_TIME_MEAS_STRUCT (sizeof(clock_value_t) \
diff --git a/drivers/staging/media/atomisp/pci/ia_css_types.h b/drivers/staging/media/atomisp/pci/ia_css_types.h
index 2b7db9cda23a..7065eded7a33 100644
--- a/drivers/staging/media/atomisp/pci/ia_css_types.h
+++ b/drivers/staging/media/atomisp/pci/ia_css_types.h
@@ -53,7 +53,7 @@
#include "isp/kernels/output/output_1.0/ia_css_output_types.h"
#define IA_CSS_DVS_STAT_GRID_INFO_SUPPORTED
-/** Should be removed after Driver adaptation will be done */
+/* Should be removed after Driver adaptation will be done */
#define IA_CSS_VERSION_MAJOR 2
#define IA_CSS_VERSION_MINOR 0
@@ -421,7 +421,7 @@ struct ia_css_dvs_6axis_config {
u32 *ycoords_uv;
};
-/**
+/*
* This specifies the coordinates (x,y)
*/
struct ia_css_point {
@@ -429,7 +429,7 @@ struct ia_css_point {
s32 y; /** y coordinate */
};
-/**
+/*
* Digital zoom:
* This feature is currently available only for video, but will become
* available for preview and capture as well.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
index 374261d25520..ee2cf2877b7d 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/conversion/conversion_1.0/ia_css_conversion_types.h
@@ -7,7 +7,7 @@
#ifndef __IA_CSS_CONVERSION_TYPES_H
#define __IA_CSS_CONVERSION_TYPES_H
-/**
+/*
* Conversion Kernel parameters.
* Deinterleave bayer quad into isys format
*
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
index 0b977eb7ad71..bbd97c71a6fd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_types.h
@@ -13,7 +13,7 @@
#include "type_support.h"
-/**
+/*
* \brief EED1_8 public parameters.
* \details Struct with all parameters for the EED1.8 kernel that can be set
* from the CSS API.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
index e32290d1c86b..d6785724fe97 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/hdr/ia_css_hdr_types.h
@@ -10,44 +10,46 @@
#define IA_CSS_HDR_MAX_NUM_INPUT_FRAMES (3)
-/**
+/*
* \brief HDR Irradiance Parameters
* \detail Currently HDR parameters are used only for testing purposes
*/
struct ia_css_hdr_irradiance_params {
- int test_irr; /** Test parameter */
- int match_shift[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Histogram matching shift parameter */
- int match_mul[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Histogram matching multiplication parameter */
- int thr_low[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Weight map soft threshold low bound parameter */
- int thr_high[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Weight map soft threshold high bound parameter */
- int thr_coeff[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Soft threshold linear function coefficien */
- int thr_shift[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES -
- 1]; /** Soft threshold precision shift parameter */
- int weight_bpp; /** Weight map bits per pixel */
+ /* Test parameter */
+ int test_irr;
+ /* Histogram matching shift parameter */
+ int match_shift[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Histogram matching multiplication parameter */
+ int match_mul[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Weight map soft threshold low bound parameter */
+ int thr_low[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Weight map soft threshold high bound parameter */
+ int thr_high[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Soft threshold linear function coefficien */
+ int thr_coeff[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Soft threshold precision shift parameter */
+ int thr_shift[IA_CSS_HDR_MAX_NUM_INPUT_FRAMES - 1];
+ /* Weight map bits per pixel */
+ int weight_bpp;
};
-/**
+/*
* \brief HDR Deghosting Parameters
* \detail Currently HDR parameters are used only for testing purposes
*/
struct ia_css_hdr_deghost_params {
- int test_deg; /** Test parameter */
+ int test_deg; /* Test parameter */
};
-/**
+/*
* \brief HDR Exclusion Parameters
* \detail Currently HDR parameters are used only for testing purposes
*/
struct ia_css_hdr_exclusion_params {
- int test_excl; /** Test parameter */
+ int test_excl; /* Test parameter */
};
-/**
+/*
* \brief HDR public parameters.
* \details Struct with all parameters for HDR that can be seet from
* the CSS API. Currently, only test parameters are defined.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
index c9a3f7bfaa90..de535503b70e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_param.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
index c1c93b2245c5..69a40a15264b 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/common/ia_css_common_io_types.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
index e6ce0cba44b9..72310781cf7e 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
index 429fcdb73f60..9fabb8b2d3b8 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_param.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
index 485ad17cb29b..1daafd96a0cd 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io_types.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
index 42b760ffac67..676a633336a2 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/tnr/tnr3/ia_css_tnr3_types.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
@@ -12,7 +12,7 @@ Copyright (c) 2010 - 2015, Intel Corporation.
* CSS-API header file for Temporal Noise Reduction v3 (TNR3) kernel
*/
-/**
+/*
* \brief Number of piecewise linear segments.
* \details The parameters to TNR3 are specified as a piecewise linear segment.
* The number of such segments is fixed at 3.
diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
index c012c1865d1e..fc4b9033951c 100644
--- a/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
+++ b/drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3_types.h
@@ -11,25 +11,25 @@
* CSS-API header file for Extra Noise Reduction (XNR) parameters.
*/
-/**
+/*
* \brief Scale of the XNR sigma parameters.
* \details The define specifies which fixed-point value represents 1.0.
*/
#define IA_CSS_XNR3_SIGMA_SCALE BIT(10)
-/**
+/*
* \brief Scale of the XNR coring parameters.
* \details The define specifies which fixed-point value represents 1.0.
*/
#define IA_CSS_XNR3_CORING_SCALE BIT(15)
-/**
+/*
* \brief Scale of the XNR blending parameter.
* \details The define specifies which fixed-point value represents 1.0.
*/
#define IA_CSS_XNR3_BLENDING_SCALE BIT(11)
-/**
+/*
* \brief XNR3 Sigma Parameters.
* \details Sigma parameters define the strength of the XNR filter.
* A higher number means stronger filtering. There are two values for each of
@@ -46,7 +46,7 @@ struct ia_css_xnr3_sigma_params {
int v1; /** Sigma for V range similarity in bright area */
};
-/**
+/*
* \brief XNR3 Coring Parameters
* \details Coring parameters define the "coring" strength, which is a soft
* thresholding technique to avoid false coloring. There are two values for
@@ -61,7 +61,7 @@ struct ia_css_xnr3_coring_params {
int v1; /** Coring threshold of V channel in bright area */
};
-/**
+/*
* \brief XNR3 Blending Parameters
* \details Blending parameters define the blending strength of filtered
* output pixels with the original chroma pixels from before xnr3. The
@@ -75,7 +75,7 @@ struct ia_css_xnr3_blending_params {
int strength; /** Blending strength */
};
-/**
+/*
* \brief XNR3 public parameters.
* \details Struct with all parameters for the XNR3 kernel that can be set
* from the CSS API.
diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
index 6a0257359e69..d6ed1fbb0e8e 100644
--- a/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
+++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/input_buf.isp.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
index 9c682f2ecbb2..5f768af9bc1d 100644
--- a/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
+++ b/drivers/staging/media/atomisp/pci/runtime/binary/interface/ia_css_binary.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
index 3e7dadca6d70..618172f17b63 100644
--- a/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
+++ b/drivers/staging/media/atomisp/pci/runtime/bufq/interface/ia_css_bufq.h
@@ -13,7 +13,7 @@
#include "ia_css_err.h"
#define BUFQ_EVENT_SIZE 4
-/**
+/*
* @brief Query the internal frame ID.
*
* @param[in] key The query key.
@@ -29,7 +29,7 @@ bool ia_css_query_internal_queue_id(
enum sh_css_queue_id *val
);
-/**
+/*
* @brief Map buffer type to a internal queue id.
*
* @param[in] thread id Thread in which the buffer type has to be mapped or unmapped
@@ -43,13 +43,13 @@ void ia_css_queue_map(
bool map
);
-/**
+/*
* @brief Initialize buffer type to a queue id mapping
* @return none
*/
void ia_css_queue_map_init(void);
-/**
+/*
* @brief initializes bufq module
* It create instances of
* -host to SP buffer queue which is a list with predefined size,
@@ -62,7 +62,7 @@ void ia_css_queue_map_init(void);
*/
void ia_css_bufq_init(void);
-/**
+/*
* @brief Enqueues an item into host to SP buffer queue
*
* @param thread_index[in] Thread in which the item to be enqueued
@@ -77,7 +77,7 @@ int ia_css_bufq_enqueue_buffer(
int queue_id,
uint32_t item);
-/**
+/*
* @brief Dequeues an item from SP to host buffer queue.
*
* @param queue_id[in] Specifies the index of the queue in the list where
@@ -90,7 +90,7 @@ int ia_css_bufq_dequeue_buffer(
int queue_id,
uint32_t *item);
-/**
+/*
* @brief Enqueue an event item into host to SP communication event queue.
*
* @param[in] evt_id The event ID.
@@ -107,7 +107,7 @@ int ia_css_bufq_enqueue_psys_event(
uint8_t evt_payload_2
);
-/**
+/*
* @brief Dequeue an item from SP to host communication event queue.
*
* @param item Object to be dequeued into this item.
@@ -119,7 +119,7 @@ int ia_css_bufq_dequeue_psys_event(
);
-/**
+/*
* @brief Enqueue an event item into host to SP EOF event queue.
*
* @param[in] evt_id The event ID.
@@ -129,7 +129,7 @@ int ia_css_bufq_dequeue_psys_event(
int ia_css_bufq_enqueue_isys_event(
uint8_t evt_id);
-/**
+/*
* @brief Dequeue an item from SP to host communication EOF event queue.
*
@@ -140,7 +140,7 @@ int ia_css_bufq_enqueue_isys_event(
int ia_css_bufq_dequeue_isys_event(
u8 item[BUFQ_EVENT_SIZE]);
-/**
+/*
* @brief Enqueue a tagger command item into tagger command queue..
*
* @param item Object to be enqueue.
@@ -150,7 +150,7 @@ int ia_css_bufq_dequeue_isys_event(
int ia_css_bufq_enqueue_tag_cmd(
uint32_t item);
-/**
+/*
* @brief Uninitializes bufq module.
*
* @return 0 or error code upon error.
@@ -158,7 +158,7 @@ int ia_css_bufq_enqueue_tag_cmd(
*/
int ia_css_bufq_deinit(void);
-/**
+/*
* @brief Dump queue states
*
* @return None
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
index 2d0e906530af..b7ff809eeeab 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug.h
@@ -312,7 +312,7 @@ void ia_css_debug_dump_stream_config(
const struct ia_css_stream_config *config,
int num_pipes);
-/**
+/*
* @brief Initialize the debug mode.
*
* WARNING:
@@ -324,7 +324,7 @@ void ia_css_debug_dump_stream_config(
*/
bool ia_css_debug_mode_init(void);
-/**
+/*
* @brief Disable the DMA channel.
*
* @param[in] dma_ID The ID of the target DMA.
@@ -344,7 +344,7 @@ bool ia_css_debug_mode_disable_dma_channel(
int dma_ID,
int channel_id,
int request_type);
-/**
+/*
* @brief Enable the DMA channel.
*
* @param[in] dma_ID The ID of the target DMA.
@@ -363,7 +363,7 @@ bool ia_css_debug_mode_enable_dma_channel(
int channel_id,
int request_type);
-/**
+/*
* @brief Dump tracer data.
* [Currently support is only for SKC]
*
@@ -373,7 +373,7 @@ bool ia_css_debug_mode_enable_dma_channel(
void ia_css_debug_dump_trace(void);
/* ISP2401 */
-/**
+/*
* @brief Program counter dumping (in loop)
*
* @param[in] id The ID of the SP
diff --git a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
index 80c58cb934d5..6f6cd77ce91d 100644
--- a/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
+++ b/drivers/staging/media/atomisp/pci/runtime/debug/interface/ia_css_debug_pipe.h
@@ -13,21 +13,21 @@
#include <ia_css_stream_public.h>
#include "ia_css_pipeline.h"
-/**
+/*
* @brief Internal debug support for constructing a pipe graph.
*
* @return None
*/
void ia_css_debug_pipe_graph_dump_prologue(void);
-/**
+/*
* @brief Internal debug support for constructing a pipe graph.
*
* @return None
*/
void ia_css_debug_pipe_graph_dump_epilogue(void);
-/**
+/*
* @brief Internal debug support for constructing a pipe graph.
* @param[in] stage Pipeline stage.
* @param[in] id Pipe id.
@@ -38,7 +38,7 @@ void ia_css_debug_pipe_graph_dump_stage(
struct ia_css_pipeline_stage *stage,
enum ia_css_pipe_id id);
-/**
+/*
* @brief Internal debug support for constructing a pipe graph.
* @param[in] out_frame Output frame of SP raw copy.
*
@@ -47,7 +47,7 @@ void ia_css_debug_pipe_graph_dump_stage(
void ia_css_debug_pipe_graph_dump_sp_raw_copy(
struct ia_css_frame *out_frame);
-/**
+/*
* @brief Internal debug support for constructing a pipe graph.
* @param[in] stream_config info about sensor and input formatter.
*
diff --git a/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h b/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
index 9b058e296c93..f8ce32e9b90d 100644
--- a/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
+++ b/drivers/staging/media/atomisp/pci/runtime/eventq/interface/ia_css_eventq.h
@@ -9,7 +9,7 @@
#include "ia_css_queue.h" /* queue APIs */
-/**
+/*
* @brief HOST receives event from SP.
*
* @param[in] eventq_handle eventq_handle.
@@ -22,7 +22,7 @@ int ia_css_eventq_recv(
ia_css_queue_t *eventq_handle,
uint8_t *payload);
-/**
+/*
* @brief The Host sends the event to SP.
* The caller of this API will be blocked until the event
* is sent.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
index d6d60508c1bf..095d1853670f 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isp_param/interface/ia_css_isp_param_types.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/**
+/*
Support for Intel Camera Imaging ISP subsystem.
Copyright (c) 2010 - 2015, Intel Corporation.
diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
index 29eebe8f9078..8870ff294c1e 100644
--- a/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
+++ b/drivers/staging/media/atomisp/pci/runtime/isys/interface/ia_css_isys.h
@@ -15,7 +15,7 @@
#include <system_global.h>
#include "ia_css_isys_comm.h"
-/**
+/*
* Virtual Input System. (Input System 2401)
*/
typedef isp2401_input_system_cfg_t ia_css_isys_descr_t;
@@ -28,7 +28,7 @@ enum mipi_port_id ia_css_isys_port_to_mipi_port(
enum mipi_port_id api_port);
-/**
+/*
* @brief Register one (virtual) stream. This is used to track when all
* virtual streams are configured inside the input system. The CSI RX is
* only started when all registered streams are configured.
@@ -43,7 +43,7 @@ int ia_css_isys_csi_rx_register_stream(
enum mipi_port_id port,
uint32_t isys_stream_id);
-/**
+/*
* @brief Unregister one (virtual) stream. This is used to track when all
* virtual streams are configured inside the input system. The CSI RX is
* only started when all registered streams are configured.
@@ -97,7 +97,7 @@ int ia_css_isys_convert_stream_format_to_mipi_format(
mipi_predictor_t compression,
unsigned int *fmt_type);
-/**
+/*
* Virtual Input System. (Input System 2401)
*/
ia_css_isys_error_t ia_css_isys_stream_create(
diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
index 8b7cbf31a1a2..04d9f1fdb5b0 100644
--- a/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
+++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/interface/ia_css_pipeline.h
@@ -219,7 +219,7 @@ int ia_css_pipeline_get_output_stage(
*/
bool ia_css_pipeline_uses_params(struct ia_css_pipeline *pipeline);
-/**
+/*
* @brief get the SP thread ID.
*
* @param[in] key The query key, typical use is pipe_num.
@@ -231,7 +231,7 @@ bool ia_css_pipeline_uses_params(struct ia_css_pipeline *pipeline);
*/
bool ia_css_pipeline_get_sp_thread_id(unsigned int key, unsigned int *val);
-/**
+/*
* @brief Get the pipeline io status
*
* @param[in] None
@@ -240,7 +240,7 @@ bool ia_css_pipeline_get_sp_thread_id(unsigned int key, unsigned int *val);
*/
struct sh_css_sp_pipeline_io_status *ia_css_pipeline_get_pipe_io_status(void);
-/**
+/*
* @brief Map an SP thread to this pipeline
*
* @param[in] pipe_num
@@ -249,7 +249,7 @@ struct sh_css_sp_pipeline_io_status *ia_css_pipeline_get_pipe_io_status(void);
*/
void ia_css_pipeline_map(unsigned int pipe_num, bool map);
-/**
+/*
* @brief Checks whether the pipeline is mapped to SP threads
*
* @param[in] Query key, typical use is pipe_num
@@ -260,7 +260,7 @@ void ia_css_pipeline_map(unsigned int pipe_num, bool map);
*/
bool ia_css_pipeline_is_mapped(unsigned int key);
-/**
+/*
* @brief Print pipeline thread mapping
*
* @param[in] none
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
index 00b903d950df..4c86c19811bb 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr.h
@@ -17,12 +17,12 @@
#define STORAGE_CLASS_RMGR_C static inline
#endif /* __INLINE_RMGR__ */
-/**
+/*
* @brief Initialize resource manager (host/common)
*/
int ia_css_rmgr_init(void);
-/**
+/*
* @brief Uninitialize resource manager (host/common)
*/
void ia_css_rmgr_uninit(void);
diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
index 6820bfc77432..68285334bc88 100644
--- a/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
+++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/interface/ia_css_rmgr_vbuf.h
@@ -12,7 +12,7 @@
#include <ia_css_types.h>
#include <system_local.h>
-/**
+/*
* @brief Data structure for the resource handle (host, vbuf)
*/
struct ia_css_rmgr_vbuf_handle {
@@ -21,7 +21,7 @@ struct ia_css_rmgr_vbuf_handle {
u32 size;
};
-/**
+/*
* @brief Data structure for the resource pool (host, vbuf)
*/
struct ia_css_rmgr_vbuf_pool {
@@ -32,14 +32,14 @@ struct ia_css_rmgr_vbuf_pool {
struct ia_css_rmgr_vbuf_handle **handles;
};
-/**
+/*
* @brief VBUF resource pools
*/
extern struct ia_css_rmgr_vbuf_pool *vbuf_ref;
extern struct ia_css_rmgr_vbuf_pool *vbuf_write;
extern struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool;
-/**
+/*
* @brief Initialize the resource pool (host, vbuf)
*
* @param pool The pointer to the pool
@@ -47,7 +47,7 @@ extern struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool;
STORAGE_CLASS_RMGR_H int ia_css_rmgr_init_vbuf(
struct ia_css_rmgr_vbuf_pool *pool);
-/**
+/*
* @brief Uninitialize the resource pool (host, vbuf)
*
* @param pool The pointer to the pool
@@ -55,7 +55,7 @@ STORAGE_CLASS_RMGR_H int ia_css_rmgr_init_vbuf(
STORAGE_CLASS_RMGR_H void ia_css_rmgr_uninit_vbuf(
struct ia_css_rmgr_vbuf_pool *pool);
-/**
+/*
* @brief Acquire a handle from the pool (host, vbuf)
*
* @param pool The pointer to the pool
@@ -65,7 +65,7 @@ STORAGE_CLASS_RMGR_H void ia_css_rmgr_acq_vbuf(
struct ia_css_rmgr_vbuf_pool *pool,
struct ia_css_rmgr_vbuf_handle **handle);
-/**
+/*
* @brief Release a handle to the pool (host, vbuf)
*
* @param pool The pointer to the pool
@@ -75,14 +75,14 @@ STORAGE_CLASS_RMGR_H void ia_css_rmgr_rel_vbuf(
struct ia_css_rmgr_vbuf_pool *pool,
struct ia_css_rmgr_vbuf_handle **handle);
-/**
+/*
* @brief Retain the reference count for a handle (host, vbuf)
*
* @param handle The pointer to the handle
*/
void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle);
-/**
+/*
* @brief Release the reference count for a handle (host, vbuf)
*
* @param handle The pointer to the handle
diff --git a/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h b/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
index 79006c325de6..9208c650fde7 100644
--- a/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
+++ b/drivers/staging/media/atomisp/pci/runtime/tagger/interface/ia_css_tagger_common.h
@@ -10,14 +10,14 @@
#include <system_local.h>
#include <type_support.h>
-/**
+/*
* @brief The tagger's circular buffer.
*
* Should be one less than NUM_CONTINUOUS_FRAMES in sh_css_internal.h
*/
#define MAX_CB_ELEMS_FOR_TAGGER 14
-/**
+/*
* @brief Data structure for the tagger buffer element.
*/
typedef struct {
diff --git a/drivers/staging/media/atomisp/pci/sh_css_internal.h b/drivers/staging/media/atomisp/pci/sh_css_internal.h
index 9155a83fcc03..ec68c16d4272 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_internal.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_internal.h
@@ -80,7 +80,7 @@
#define SH_CSS_MAX_SP_THREADS 5
-/**
+/*
* The C99 standard does not specify the exact object representation of structs;
* the representation is compiler dependent.
*
@@ -638,7 +638,7 @@ struct sh_css_sp_output {
unsigned int sw_interrupt_value[SH_CSS_NUM_SDW_IRQS];
};
-/**
+/*
* @brief Data structure for the circular buffer.
* The circular buffer is empty if "start == end". The
* circular buffer is full if "(end + 1) % size == start".
diff --git a/drivers/staging/media/atomisp/pci/sh_css_sp.h b/drivers/staging/media/atomisp/pci/sh_css_sp.h
index 78aec5b7e8fa..6985ca200f09 100644
--- a/drivers/staging/media/atomisp/pci/sh_css_sp.h
+++ b/drivers/staging/media/atomisp/pci/sh_css_sp.h
@@ -68,7 +68,7 @@ sh_css_read_host2sp_command(void);
void
sh_css_init_host2sp_frame_data(void);
-/**
+/*
* @brief Update the offline frame information in host_sp_communication.
*
* @param[in] frame_num The offline frame number.
@@ -80,7 +80,7 @@ sh_css_update_host2sp_offline_frame(
struct ia_css_frame *frame,
struct ia_css_metadata *metadata);
-/**
+/*
* @brief Update the mipi frame information in host_sp_communication.
*
* @param[in] frame_num The mipi frame number.
@@ -91,7 +91,7 @@ sh_css_update_host2sp_mipi_frame(
unsigned int frame_num,
struct ia_css_frame *frame);
-/**
+/*
* @brief Update the mipi metadata information in host_sp_communication.
*
* @param[in] frame_num The mipi frame number.
@@ -102,7 +102,7 @@ sh_css_update_host2sp_mipi_metadata(
unsigned int frame_num,
struct ia_css_metadata *metadata);
-/**
+/*
* @brief Update the nr of mipi frames to use in host_sp_communication.
*
* @param[in] num_frames The number of mipi frames to use.
@@ -110,7 +110,7 @@ sh_css_update_host2sp_mipi_metadata(
void
sh_css_update_host2sp_num_mipi_frames(unsigned int num_frames);
-/**
+/*
* @brief Update the nr of offline frames to use in host_sp_communication.
*
* @param[in] num_frames The number of raw frames to use.
@@ -170,7 +170,7 @@ sh_css_sp_set_disable_continuous_viewfinder(bool flag);
void
sh_css_sp_reset_global_vars(void);
-/**
+/*
* @brief Initialize the DMA software-mask in the debug mode.
* This API should be ONLY called in the debugging mode.
* And it should be always called before the first call of
@@ -185,7 +185,7 @@ sh_css_sp_reset_global_vars(void);
bool
sh_css_sp_init_dma_sw_reg(int dma_id);
-/**
+/*
* @brief Set the DMA software-mask in the debug mode.
* This API should be ONLYL called in the debugging mode. Must
* call "sh_css_set_dma_sw_reg(...)" before this
diff --git a/drivers/staging/media/atomisp/pci/system_global.h b/drivers/staging/media/atomisp/pci/system_global.h
index e8a29f73d67a..ee1d9b66ccb1 100644
--- a/drivers/staging/media/atomisp/pci/system_global.h
+++ b/drivers/staging/media/atomisp/pci/system_global.h
@@ -293,7 +293,7 @@ typedef enum {
} stream2mmio_sid_ID_t;
/* end of Stream2MMIO */
-/**
+/*
* Input System 2401: CSI-MIPI recevier.
*/
typedef enum {
@@ -324,7 +324,7 @@ typedef enum {
N_ISYS2401_DMA_ID
} isys2401_dma_ID_t;
-/**
+/*
* Pixel-generator. ("system_global.h")
*/
typedef enum {
diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c
index 862aee993889..06c43b5f8a87 100644
--- a/drivers/staging/media/av7110/av7110.c
+++ b/drivers/staging/media/av7110/av7110.c
@@ -942,16 +942,16 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
(feed->pes_type <= DMX_PES_PCR)) {
switch (demux->dmx.frontend->source) {
case DMX_MEMORY_FE:
- if (feed->ts_type & TS_DECODER)
- if (feed->pes_type < 2 &&
- !(demux->pids[0] & 0x8000) &&
- !(demux->pids[1] & 0x8000)) {
- dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
- dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
- ret = av7110_av_start_play(av7110, RP_AV);
- if (!ret)
- demux->playing = 1;
- }
+ if (feed->pes_type >= 2 ||
+ (demux->pids[0] & 0x8000) ||
+ (demux->pids[1] & 0x8000))
+ break;
+
+ dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
+ dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
+ ret = av7110_av_start_play(av7110, RP_AV);
+ if (!ret)
+ demux->playing = 1;
break;
default:
ret = dvb_feed_start_pid(feed);
diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c
index 310e3f24e571..48a35bda4237 100644
--- a/drivers/staging/media/ipu7/ipu7.c
+++ b/drivers/staging/media/ipu7/ipu7.c
@@ -2343,7 +2343,7 @@ static int ipu7_init_fw_code_region_by_sys(struct ipu7_bus_device *sys,
return ret;
}
- ret = pm_runtime_get_sync(dev);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0) {
dev_err(dev, "Failed to get runtime PM\n");
return ret;
@@ -2702,7 +2702,7 @@ static int ipu7_resume(struct device *dev)
if (ret)
dev_err(dev, "IPC reset protocol failed!\n");
- ret = pm_runtime_get_sync(&isp->psys->auxdev.dev);
+ ret = pm_runtime_resume_and_get(&isp->psys->auxdev.dev);
if (ret < 0) {
dev_err(dev, "Failed to get runtime PM\n");
return 0;
diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
index a039d925c0fe..c18bf352b199 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -504,8 +504,8 @@ vdec_try_fmt_common(struct amvdec_session *sess, u32 size,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
fmt_out = find_format(fmts, size, pixmp->pixelformat);
if (!fmt_out) {
- pixmp->pixelformat = V4L2_PIX_FMT_MPEG2;
- fmt_out = find_format(fmts, size, pixmp->pixelformat);
+ pixmp->pixelformat = fmts[0].pixfmt;
+ fmt_out = &fmts[0];
}
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index bbd186b8035b..96acd52e380c 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -285,8 +285,10 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
ctrl_size = sizeof(ctrl) * CEDRUS_CONTROLS_COUNT + 1;
ctx->ctrls = kzalloc(ctrl_size, GFP_KERNEL);
- if (!ctx->ctrls)
+ if (!ctx->ctrls) {
+ v4l2_ctrl_handler_free(hdl);
return -ENOMEM;
+ }
j = 0;
for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c
index 456134a9e8cf..01622013c109 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1257,6 +1257,7 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
struct device_node *parent;
struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
unsigned int lanes;
+ int err;
int ret = 0;
ports = of_get_child_by_name(node, "ports");
@@ -1267,8 +1268,8 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
if (!of_node_name_eq(port, "port"))
continue;
- ret = of_property_read_u32(port, "reg", &port_num);
- if (ret < 0)
+ err = of_property_read_u32(port, "reg", &port_num);
+ if (err < 0)
continue;
if (port_num > vi->soc->vi_max_channels) {
@@ -1289,10 +1290,10 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
ep = of_graph_get_endpoint_by_regs(parent, 0, 0);
of_node_put(parent);
- ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep),
+ err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep),
&v4l2_ep);
of_node_put(ep);
- if (ret)
+ if (err)
continue;
lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
@@ -1468,7 +1469,6 @@ static int tegra_vi_graph_build(struct tegra_vi_channel *chan,
struct tegra_vi *vi = chan->vi;
struct tegra_vi_graph_entity *ent;
struct fwnode_handle *ep = NULL;
- struct v4l2_fwnode_link link;
struct media_entity *local = entity->entity;
struct media_entity *remote;
struct media_pad *local_pad;
@@ -1478,70 +1478,64 @@ static int tegra_vi_graph_build(struct tegra_vi_channel *chan,
dev_dbg(vi->dev, "creating links for entity %s\n", local->name);
- while (1) {
- ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode,
- ep);
- if (!ep)
- break;
+ fwnode_graph_for_each_endpoint(entity->asd.match.fwnode, ep) {
+ struct fwnode_handle *remote_parent __free(fwnode_handle) = NULL;
+ struct fwnode_handle *sink_ep __free(fwnode_handle) = NULL;
+ int src_idx, sink_idx;
- ret = v4l2_fwnode_parse_link(ep, &link);
- if (ret < 0) {
- dev_err(vi->dev, "failed to parse link for %pOF: %d\n",
- to_of_node(ep), ret);
+ src_idx = media_entity_get_fwnode_pad(local, ep,
+ MEDIA_PAD_FL_SOURCE);
+ if (src_idx < 0) {
+ dev_dbg(vi->dev, "no source pad found for %pfw\n", ep);
continue;
}
- if (link.local_port >= local->num_pads) {
- dev_err(vi->dev, "invalid port number %u on %pOF\n",
- link.local_port, to_of_node(link.local_node));
- v4l2_fwnode_put_link(&link);
- ret = -EINVAL;
- break;
+ remote_parent = fwnode_graph_get_remote_port_parent(ep);
+ if (!remote_parent) {
+ dev_dbg(vi->dev, "no remote parent found for %pfw\n",
+ ep);
+ continue;
}
- local_pad = &local->pads[link.local_port];
+ local_pad = &local->pads[src_idx];
/* Remote node is vi node. So use channel video entity and pad
* as remote/sink.
*/
- if (link.remote_node == of_fwnode_handle(vi->dev->of_node)) {
+ if (remote_parent == of_fwnode_handle(vi->dev->of_node)) {
remote = &chan->video.entity;
remote_pad = &chan->pad;
goto create_link;
}
- /*
- * Skip sink ports, they will be processed from the other end
- * of the link.
- */
- if (local_pad->flags & MEDIA_PAD_FL_SINK) {
- dev_dbg(vi->dev, "skipping sink port %pOF:%u\n",
- to_of_node(link.local_node), link.local_port);
- v4l2_fwnode_put_link(&link);
- continue;
- }
-
/* find the remote entity from notifier list */
ent = tegra_vi_graph_find_entity(&chan->notifier.done_list,
- link.remote_node);
+ remote_parent);
if (!ent) {
- dev_err(vi->dev, "no entity found for %pOF\n",
- to_of_node(link.remote_node));
- v4l2_fwnode_put_link(&link);
+ fwnode_handle_put(ep);
+ dev_err(vi->dev, "no entity found for %pfw\n",
+ remote_parent);
ret = -ENODEV;
break;
}
remote = ent->entity;
- if (link.remote_port >= remote->num_pads) {
- dev_err(vi->dev, "invalid port number %u on %pOF\n",
- link.remote_port,
- to_of_node(link.remote_node));
- v4l2_fwnode_put_link(&link);
- ret = -EINVAL;
- break;
+
+ sink_ep = fwnode_graph_get_remote_endpoint(ep);
+ if (!sink_ep) {
+ dev_dbg(vi->dev, "no sink ep found for %pfw\n",
+ ep);
+ continue;
+ }
+
+ sink_idx = media_entity_get_fwnode_pad(remote, sink_ep,
+ MEDIA_PAD_FL_SINK);
+ if (sink_idx < 0) {
+ dev_dbg(vi->dev, "no sink pad found for %pfw\n",
+ sink_ep);
+ continue;
}
- remote_pad = &remote->pads[link.remote_port];
+ remote_pad = &remote->pads[sink_idx];
create_link:
dev_dbg(vi->dev, "creating %s:%u -> %s:%u link\n",
@@ -1551,8 +1545,8 @@ create_link:
ret = media_create_pad_link(local, local_pad->index,
remote, remote_pad->index,
link_flags);
- v4l2_fwnode_put_link(&link);
if (ret < 0) {
+ fwnode_handle_put(ep);
dev_err(vi->dev,
"failed to create %s:%u -> %s:%u link: %d\n",
local->name, local_pad->index,
@@ -1561,7 +1555,6 @@ create_link:
}
}
- fwnode_handle_put(ep);
return ret;
}
diff --git a/drivers/staging/media/tegra-video/vip.c b/drivers/staging/media/tegra-video/vip.c
index 9ff1f1750a15..5fba11e31e1d 100644
--- a/drivers/staging/media/tegra-video/vip.c
+++ b/drivers/staging/media/tegra-video/vip.c
@@ -126,7 +126,7 @@ static int tegra_vip_channel_of_parse(struct tegra_vip *vip)
if (!ep) {
err = -EINVAL;
dev_err_probe(dev, err, "%pOF: error getting endpoint node\n", np);
- goto err_node_put;
+ return err;
}
fwh = of_fwnode_handle(ep);
@@ -134,14 +134,14 @@ static int tegra_vip_channel_of_parse(struct tegra_vip *vip)
of_node_put(ep);
if (err) {
dev_err_probe(dev, err, "%pOF: failed to parse v4l2 endpoint\n", np);
- goto err_node_put;
+ return err;
}
num_pads = of_graph_get_endpoint_count(np);
if (num_pads != TEGRA_VIP_PADS_NUM) {
err = -EINVAL;
dev_err_probe(dev, err, "%pOF: need 2 pads, got %d\n", np, num_pads);
- goto err_node_put;
+ return err;
}
vip->chan.of_node = of_node_get(np);
@@ -149,10 +149,6 @@ static int tegra_vip_channel_of_parse(struct tegra_vip *vip)
vip->chan.pads[TEGRA_VIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
return 0;
-
-err_node_put:
- of_node_put(np);
- return err;
}
static int tegra_vip_channel_init(struct tegra_vip *vip)
diff --git a/include/media/cec.h b/include/media/cec.h
index 0c8e86115b6f..4c8b0950b377 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -85,7 +85,6 @@ struct cec_event_entry {
struct cec_event ev;
};
-#define CEC_NUM_CORE_EVENTS 2
#define CEC_NUM_EVENTS CEC_EVENT_PIN_5V_HIGH
struct cec_fh {
@@ -101,7 +100,6 @@ struct cec_fh {
struct list_head events[CEC_NUM_EVENTS]; /* queued events */
u16 queued_events[CEC_NUM_EVENTS];
unsigned int total_queued_events;
- struct cec_event_entry core_events[CEC_NUM_CORE_EVENTS];
struct list_head msgs; /* queued messages */
unsigned int queued_msgs;
};
@@ -223,6 +221,8 @@ struct cec_adap_ops {
* @tx_error_log_cnt: number of logged Error transmits since the adapter was
* enabled. Used to avoid flooding the kernel log if this
* happens a lot.
+ * @error_inj_tx_timeouts: error injection: the next @error_inj_tx_timeouts
+ * transmits will time out.
* @notifier: CEC notifier
* @pin: CEC pin status struct
* @cec_dir: debugfs cec directory
@@ -283,6 +283,8 @@ struct cec_adapter {
u32 tx_low_drive_log_cnt;
u32 tx_error_log_cnt;
+ u32 error_inj_tx_timeouts;
+
#ifdef CONFIG_CEC_NOTIFIER
struct cec_notifier *notifier;
#endif
diff --git a/include/media/drv-intf/s3c_camif.h b/include/media/drv-intf/s3c_camif.h
index f746851a5ce6..00d83620ea5f 100644
--- a/include/media/drv-intf/s3c_camif.h
+++ b/include/media/drv-intf/s3c_camif.h
@@ -31,8 +31,6 @@ struct s3c_camif_sensor_info {
struct s3c_camif_plat_data {
struct s3c_camif_sensor_info sensor;
- int (*gpio_get)(void);
- int (*gpio_put)(void);
};
#endif /* MEDIA_S3C_CAMIF_ */
diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h
index 71ce63c99cb4..b8f2fe5680f0 100644
--- a/include/media/drv-intf/saa7146.h
+++ b/include/media/drv-intf/saa7146.h
@@ -77,13 +77,10 @@ struct saa7146_pci_extension_data {
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, \
+#define MAKE_EXTENSION_PCI(x_var, x_vendor, x_device) \
+ { \
+ PCI_VDEVICE_SUB(PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, (x_vendor), (x_device)),\
+ .driver_data = (unsigned long)&(x_var), \
}
struct saa7146_extension
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index d9b72cd87d52..fa393e840669 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -1387,6 +1387,7 @@ void media_remove_intf_links(struct media_interface *intf);
* @entity: entity where the @operation will be called
* @operation: type of the operation. Should be the name of a member of
* struct &media_entity_operations.
+ * @args: arguments for the operation.
*
* This helper function will check if @operation is not %NULL. On such case,
* it will issue a call to @operation\(@entity, @args\).
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index d90e4611b066..d95ed3e96de2 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -262,7 +262,6 @@ struct rc_map *rc_map_get(const char *name);
#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce"
#define RC_MAP_GOTVIEW7135 "rc-gotview7135"
#define RC_MAP_HAUPPAUGE "rc-hauppauge"
-#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge"
#define RC_MAP_HISI_POPLAR "rc-hisi-poplar"
#define RC_MAP_HISI_TV_DEMO "rc-hisi-tv-demo"
#define RC_MAP_IMON_MCE "rc-imon-mce"
@@ -309,7 +308,6 @@ struct rc_map *rc_map_get(const char *name);
#define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
#define RC_MAP_PURPLETV "rc-purpletv"
#define RC_MAP_PV951 "rc-pv951"
-#define RC_MAP_RC5_TV "rc-rc5-tv"
#define RC_MAP_RC6_MCE "rc-rc6-mce"
#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
#define RC_MAP_REDDO "rc-reddo"
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 54c83b18d555..a13dca7c609f 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -736,8 +736,8 @@ long int video_usercopy(struct file *file, unsigned int cmd,
* @cmd: Ioctl name.
* @arg: Ioctl argument.
*
- * Method used to hancle an ioctl. Should be used to fill the
- * &v4l2_ioctl_ops.unlocked_ioctl on all V4L2 drivers.
+ * Method used to handle an ioctl. Should be used to fill the
+ * &v4l2_file_operations.unlocked_ioctl on all V4L2 drivers.
*/
long int video_ioctl2(struct file *file,
unsigned int cmd, unsigned long int arg);
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index 71d2864fb235..d51e10c10fc0 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -72,6 +72,19 @@ struct vb2_v4l2_buffer {
*/
struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp);
+/**
+ * vb2_querybuf() - Query video buffer information
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @b: buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_querybuf handler in driver
+ *
+ * Should be called from vidioc_querybuf ioctl handler in driver.
+ * This function will verify the passed v4l2_buffer structure and fill the
+ * relevant information for the userspace.
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_querybuf handler in driver.
+ */
int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
/**
diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
index 81a05c9c0706..fdfc97a6e4ec 100644
--- a/include/uapi/linux/cec.h
+++ b/include/uapi/linux/cec.h
@@ -403,6 +403,8 @@ struct cec_log_addrs {
#define CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU (1 << 1)
/* CDC-Only device: supports only CDC messages */
#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2)
+/* Configuration failed */
+#define CEC_LOG_ADDRS_FL_CONFIG_FAILED (1 << 3)
/**
* struct cec_drm_connector_info - tells which drm connector is