aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml174
-rw-r--r--Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml157
-rw-r--r--Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml (renamed from Documentation/devicetree/bindings/media/i2c/imx258.yaml)11
-rw-r--r--Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml107
-rw-r--r--Documentation/devicetree/bindings/media/rockchip-rga.yaml1
-rw-r--r--Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst4
-rw-r--r--MAINTAINERS25
-rw-r--r--drivers/media/common/siano/smscoreapi.c10
-rw-r--r--drivers/media/common/siano/smscoreapi.h18
-rw-r--r--drivers/media/common/siano/smsdvb-main.c4
-rw-r--r--drivers/media/common/siano/smsendian.c8
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c5
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c7
-rw-r--r--drivers/media/dvb-frontends/stv090x.c37
-rw-r--r--drivers/media/dvb-frontends/stv0910.c5
-rw-r--r--drivers/media/i2c/Kconfig45
-rw-r--r--drivers/media/i2c/Makefile3
-rw-r--r--drivers/media/i2c/adv7511-v4l2.c5
-rw-r--r--drivers/media/i2c/dw9768.c5
-rw-r--r--drivers/media/i2c/hi846.c2
-rw-r--r--drivers/media/i2c/imx258.c1424
-rw-r--r--drivers/media/i2c/imx283.c1605
-rw-r--r--drivers/media/i2c/imx412.c9
-rw-r--r--drivers/media/i2c/ks0127.c8
-rw-r--r--drivers/media/i2c/max96714.c1024
-rw-r--r--drivers/media/i2c/max96717.c927
-rw-r--r--drivers/media/i2c/ov5693.c10
-rw-r--r--drivers/media/i2c/tw9910.c5
-rw-r--r--drivers/media/pci/cx18/cx18-scb.h2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-buttress.c4
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c98
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h2
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-queue.c3
-rw-r--r--drivers/media/pci/intel/ipu6/ipu6-isys-video.c43
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.c93
-rw-r--r--drivers/media/pci/ivtv/ivtv-fileops.c66
-rw-r--r--drivers/media/pci/ivtv/ivtv-udma.c8
-rw-r--r--drivers/media/pci/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c6
-rw-r--r--drivers/media/platform/allegro-dvt/nal-hevc.h7
-rw-r--r--drivers/media/platform/amphion/vpu_malone.c5
-rw-r--r--drivers/media/platform/m2m-deinterlace.c4
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/h264.c5
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/vde.h1
-rw-r--r--drivers/media/platform/rockchip/rga/rga-buf.c5
-rw-r--r--drivers/media/platform/rockchip/rga/rga.c4
-rw-r--r--drivers/media/platform/rockchip/rga/rga.h3
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c8
-rw-r--r--drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c8
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.c4
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.h2
-rw-r--r--drivers/media/rc/imon.c5
-rw-r--r--drivers/media/rc/mceusb.c11
-rw-r--r--drivers/media/spi/gs1662.c8
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c35
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c4
-rw-r--r--drivers/media/usb/go7007/go7007-i2c.c30
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-debugifc.c5
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c7
-rw-r--r--drivers/media/v4l2-core/v4l2-cci.c9
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c385
-rw-r--r--drivers/staging/media/av7110/Kconfig22
-rw-r--r--drivers/staging/media/av7110/Makefile2
-rw-r--r--drivers/staging/media/av7110/TODO3
-rw-r--r--drivers/staging/media/av7110/audio-bilingual-channel-select.rst58
-rw-r--r--drivers/staging/media/av7110/audio-channel-select.rst57
-rw-r--r--drivers/staging/media/av7110/audio-clear-buffer.rst48
-rw-r--r--drivers/staging/media/av7110/audio-continue.rst48
-rw-r--r--drivers/staging/media/av7110/audio-fclose.rst51
-rw-r--r--drivers/staging/media/av7110/audio-fopen.rst103
-rw-r--r--drivers/staging/media/av7110/audio-fwrite.rst79
-rw-r--r--drivers/staging/media/av7110/audio-get-capabilities.rst54
-rw-r--r--drivers/staging/media/av7110/audio-get-status.rst54
-rw-r--r--drivers/staging/media/av7110/audio-pause.rst49
-rw-r--r--drivers/staging/media/av7110/audio-play.rst48
-rw-r--r--drivers/staging/media/av7110/audio-select-source.rst56
-rw-r--r--drivers/staging/media/av7110/audio-set-av-sync.rst58
-rw-r--r--drivers/staging/media/av7110/audio-set-bypass-mode.rst62
-rw-r--r--drivers/staging/media/av7110/audio-set-id.rst59
-rw-r--r--drivers/staging/media/av7110/audio-set-mixer.rst53
-rw-r--r--drivers/staging/media/av7110/audio-set-mute.rst62
-rw-r--r--drivers/staging/media/av7110/audio-set-streamtype.rst66
-rw-r--r--drivers/staging/media/av7110/audio-stop.rst48
-rw-r--r--drivers/staging/media/av7110/audio.rst27
-rw-r--r--drivers/staging/media/av7110/audio_data_types.rst116
-rw-r--r--drivers/staging/media/av7110/audio_function_calls.rst30
-rw-r--r--drivers/staging/media/av7110/av7110.c496
-rw-r--r--drivers/staging/media/av7110/av7110.h50
-rw-r--r--drivers/staging/media/av7110/av7110_av.c234
-rw-r--r--drivers/staging/media/av7110/av7110_av.h37
-rw-r--r--drivers/staging/media/av7110/av7110_ca.c43
-rw-r--r--drivers/staging/media/av7110/av7110_ca.h12
-rw-r--r--drivers/staging/media/av7110/av7110_hw.c230
-rw-r--r--drivers/staging/media/av7110/av7110_hw.h79
-rw-r--r--drivers/staging/media/av7110/av7110_ipack.c282
-rw-r--r--drivers/staging/media/av7110/av7110_ipack.h12
-rw-r--r--drivers/staging/media/av7110/av7110_ir.c3
-rw-r--r--drivers/staging/media/av7110/av7110_v4l.c102
-rw-r--r--drivers/staging/media/av7110/budget-patch.c665
-rw-r--r--drivers/staging/media/av7110/dvb_filter.c116
-rw-r--r--drivers/staging/media/av7110/dvb_filter.h22
-rw-r--r--drivers/staging/media/av7110/sp8870.c200
-rw-r--r--drivers/staging/media/av7110/sp8870.h24
-rw-r--r--drivers/staging/media/av7110/video-clear-buffer.rst54
-rw-r--r--drivers/staging/media/av7110/video-command.rst96
-rw-r--r--drivers/staging/media/av7110/video-continue.rst57
-rw-r--r--drivers/staging/media/av7110/video-fast-forward.rst72
-rw-r--r--drivers/staging/media/av7110/video-fclose.rst51
-rw-r--r--drivers/staging/media/av7110/video-fopen.rst111
-rw-r--r--drivers/staging/media/av7110/video-freeze.rst61
-rw-r--r--drivers/staging/media/av7110/video-fwrite.rst79
-rw-r--r--drivers/staging/media/av7110/video-get-capabilities.rst61
-rw-r--r--drivers/staging/media/av7110/video-get-event.rst105
-rw-r--r--drivers/staging/media/av7110/video-get-frame-count.rst65
-rw-r--r--drivers/staging/media/av7110/video-get-pts.rst69
-rw-r--r--drivers/staging/media/av7110/video-get-size.rst69
-rw-r--r--drivers/staging/media/av7110/video-get-status.rst72
-rw-r--r--drivers/staging/media/av7110/video-play.rst57
-rw-r--r--drivers/staging/media/av7110/video-select-source.rst76
-rw-r--r--drivers/staging/media/av7110/video-set-blank.rst64
-rw-r--r--drivers/staging/media/av7110/video-set-display-format.rst60
-rw-r--r--drivers/staging/media/av7110/video-set-format.rst82
-rw-r--r--drivers/staging/media/av7110/video-set-streamtype.rst61
-rw-r--r--drivers/staging/media/av7110/video-slowmotion.rst72
-rw-r--r--drivers/staging/media/av7110/video-stillpicture.rst61
-rw-r--r--drivers/staging/media/av7110/video-stop.rst74
-rw-r--r--drivers/staging/media/av7110/video-try-command.rst66
-rw-r--r--drivers/staging/media/av7110/video.rst36
-rw-r--r--drivers/staging/media/av7110/video_function_calls.rst35
-rw-r--r--drivers/staging/media/av7110/video_types.rst248
-rw-r--r--drivers/staging/media/max96712/max96712.c37
-rw-r--r--include/media/ipu-bridge.h1
-rw-r--r--include/media/v4l2-subdev.h90
133 files changed, 6425 insertions, 6168 deletions
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
new file mode 100644
index 000000000000..3ace50e11921
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Collabora Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/maxim,max96714.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX96714 GMSL2 to CSI-2 Deserializer
+
+maintainers:
+ - Julien Massot <[email protected]>
+
+description:
+ The MAX96714 deserializer converts GMSL2 serial inputs into MIPI
+ CSI-2 D-PHY formatted output. The device allows the GMSL2 link to
+ simultaneously transmit bidirectional control-channel data while forward
+ video transmissions are in progress. The MAX96714 can connect to one
+ remotely located serializer using industry-standard coax or STP
+ interconnects. The device cans operate in pixel or tunnel mode. In pixel mode
+ the MAX96714 can select individual video stream, while the tunnel mode forward all
+ the MIPI data received by the serializer.
+
+ The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
+ forward direction and 187.5Mbps in the reverse direction.
+ MAX96714F only supports a fixed rate of 3Gbps in the forward direction.
+
+properties:
+ compatible:
+ oneOf:
+ - const: maxim,max96714f
+ - items:
+ - enum:
+ - maxim,max96714
+ - const: maxim,max96714f
+
+ reg:
+ maxItems: 1
+
+ powerdown-gpios:
+ maxItems: 1
+ description:
+ Specifier for the GPIO connected to the PWDNB pin.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ unevaluatedProperties: false
+ description: GMSL Input
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+ description:
+ Endpoint for GMSL2-Link port.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: CSI-2 Output port
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+
+ link-frequencies:
+ maxItems: 1
+
+ required:
+ - data-lanes
+
+ required:
+ - port@1
+
+ i2c-gate:
+ $ref: /schemas/i2c/i2c-gate.yaml
+ unevaluatedProperties: false
+ description:
+ The MAX96714 will pass through and forward the I2C requests from the
+ incoming I2C bus over the GMSL2 link. Therefore it supports an i2c-gate
+ subnode to configure a serializer.
+
+ port0-poc-supply:
+ description: Regulator providing Power over Coax for the GMSL port
+
+required:
+ - compatible
+ - reg
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/media/video-interfaces.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deserializer@28 {
+ compatible = "maxim,max96714f";
+ reg = <0x28>;
+ powerdown-gpios = <&main_gpio0 37 GPIO_ACTIVE_LOW>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ max96714_gmsl_in: endpoint {
+ remote-endpoint = <&max96917f_gmsl_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96714_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <400000000>;
+ remote-endpoint = <&csi_in>;
+ };
+ };
+ };
+
+ i2c-gate {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serializer@40 {
+ compatible = "maxim,max96717f";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ max96717f_csi_in: endpoint {
+ data-lanes = <1 2>;
+ lane-polarities = <1 0 1>;
+ remote-endpoint = <&sensor_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96917f_gmsl_out: endpoint {
+ remote-endpoint = <&max96714_gmsl_in>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
new file mode 100644
index 000000000000..d1e8ba6e368e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -0,0 +1,157 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Collabora Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/maxim,max96717.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAX96717 CSI-2 to GMSL2 Serializer
+
+maintainers:
+ - Julien Massot <[email protected]>
+
+description:
+ The MAX96717 serializer converts MIPI CSI-2 D-PHY formatted input
+ into GMSL2 serial outputs. The device allows the GMSL2 link to
+ simultaneously transmit bidirectional control-channel data while forward
+ video transmissions are in progress. The MAX96717 can connect to one
+ remotely located deserializer using industry-standard coax or STP
+ interconnects. The device cans operate in pixel or tunnel mode. In pixel mode
+ the MAX96717 can select the MIPI datatype, while the tunnel mode forward all the MIPI
+ data received by the serializer.
+ The MAX96717 supports Reference Over Reverse (channel),
+ to generate a clock output for the sensor from the GMSL reverse channel.
+
+ The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
+ forward direction and 187.5Mbps in the reverse direction.
+ MAX96717F only supports a fixed rate of 3Gbps in the forward direction.
+
+properties:
+ compatible:
+ oneOf:
+ - const: maxim,max96717f
+ - items:
+ - enum:
+ - maxim,max96717
+ - const: maxim,max96717f
+
+ '#gpio-cells':
+ const: 2
+ description:
+ First cell is the GPIO pin number, second cell is the flags. The GPIO pin
+ number must be in range of [0, 10].
+
+ gpio-controller: true
+
+ '#clock-cells':
+ const: 0
+
+ reg:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: CSI-2 Input port
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+
+ required:
+ - data-lanes
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ unevaluatedProperties: false
+ description: GMSL Output port
+
+ required:
+ - port@1
+
+ i2c-gate:
+ $ref: /schemas/i2c/i2c-gate.yaml
+ unevaluatedProperties: false
+ description:
+ The MAX96717 will forward the I2C requests from the
+ incoming GMSL2 link. Therefore, it supports an i2c-gate
+ subnode to configure a sensor.
+
+required:
+ - compatible
+ - reg
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/media/video-interfaces.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ serializer: serializer@40 {
+ compatible = "maxim,max96717f";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ max96717f_csi_in: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&sensor_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96917f_gmsl_out: endpoint {
+ remote-endpoint = <&deser_gmsl_in>;
+ };
+ };
+ };
+
+ i2c-gate {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sensor@10 {
+ compatible = "st,st-vgxy61";
+ reg = <0x10>;
+ reset-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
+ clocks = <&serializer>;
+ VCORE-supply = <&v1v2>;
+ VDDIO-supply = <&v1v8>;
+ VANA-supply = <&v2v8>;
+ port {
+ sensor_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max96717f_csi_in>;
+ };
+ };
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/media/i2c/imx258.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml
index 80d24220baa0..c978abc0cdb3 100644
--- a/Documentation/devicetree/bindings/media/i2c/imx258.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
-$id: http://devicetree.org/schemas/media/i2c/imx258.yaml#
+$id: http://devicetree.org/schemas/media/i2c/sony,imx258.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sony IMX258 13 Mpixel CMOS Digital Image Sensor
@@ -13,11 +13,16 @@ description: |-
IMX258 is a diagonal 5.867mm (Type 1/3.06) 13 Mega-pixel CMOS active pixel
type stacked image sensor with a square pixel array of size 4208 x 3120. It
is programmable through I2C interface. Image data is sent through MIPI
- CSI-2.
+ CSI-2. The sensor exists in two different models, a standard variant
+ (IMX258) and a variant with phase detection autofocus (IMX258-PDAF).
+ The camera module does not expose the model through registers, so the
+ exact model needs to be specified.
properties:
compatible:
- const: sony,imx258
+ enum:
+ - sony,imx258
+ - sony,imx258-pdaf
assigned-clocks: true
assigned-clock-parents: true
diff --git a/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
new file mode 100644
index 000000000000..e4f49f1435a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Ideas on Board Oy
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/sony,imx283.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sony IMX283 Sensor
+
+maintainers:
+ - Kieran Bingham <[email protected]>
+ - Umang Jain <[email protected]>
+
+description:
+ IMX283 sensor is a Sony CMOS active pixel digital image sensor with an active
+ array size of 5472H x 3648V. It is programmable through I2C interface. The
+ I2C client address is fixed to 0x1a as per sensor data sheet. Image data is
+ sent through MIPI CSI-2.
+
+properties:
+ compatible:
+ const: sony,imx283
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description: Clock frequency from 6 to 24 MHz.
+ maxItems: 1
+
+ vadd-supply:
+ description: Analog power supply (2.9V)
+
+ vdd1-supply:
+ description: Interface power supply (1.8V)
+
+ vdd2-supply:
+ description: Digital power supply (1.2V)
+
+ reset-gpios:
+ description: Sensor reset (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:
+ anyOf:
+ - items:
+ - const: 1
+ - const: 2
+ - const: 3
+ - const: 4
+
+ link-frequencies: true
+
+ required:
+ - data-lanes
+ - link-frequencies
+
+ required:
+ - endpoint
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - port
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@1a {
+ compatible = "sony,imx283";
+ reg = <0x1a>;
+ clocks = <&imx283_clk>;
+
+ assigned-clocks = <&imx283_clk>;
+ assigned-clock-parents = <&imx283_clk_parent>;
+ assigned-clock-rates = <12000000>;
+
+ vadd-supply = <&camera_vadd_2v9>;
+ vdd1-supply = <&camera_vdd1_1v8>;
+ vdd2-supply = <&camera_vdd2_1v2>;
+
+ port {
+ imx283: endpoint {
+ remote-endpoint = <&cam>;
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <360000000>;
+ };
+ };
+ };
+ };
+...
diff --git a/Documentation/devicetree/bindings/media/rockchip-rga.yaml b/Documentation/devicetree/bindings/media/rockchip-rga.yaml
index ea2342222408..ac17cda65191 100644
--- a/Documentation/devicetree/bindings/media/rockchip-rga.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip-rga.yaml
@@ -24,6 +24,7 @@ properties:
- enum:
- rockchip,rk3228-rga
- rockchip,rk3568-rga
+ - rockchip,rk3588-rga
- const: rockchip,rk3288-rga
reg:
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
index 786127b1e206..22bde00d42df 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
@@ -971,8 +971,8 @@ FWHT Flags
- ``horizontal_scale``
- Horizontal scaling factor.
* - __u8
- - ``vertical_scaling factor``
- - Vertical scale.
+ - ``vertical_scale``
+ - Vertical scaling factor.
* - __u8
- ``version``
- Bitstream version.
diff --git a/MAINTAINERS b/MAINTAINERS
index aacccb376c28..9caf669234f2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13513,6 +13513,20 @@ S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
F: drivers/staging/media/max96712/max96712.c
+MAX96714 GMSL2 DESERIALIZER DRIVER
+M: Julien Massot <[email protected]>
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
+F: drivers/media/i2c/max96714.c
+
+MAX96717 GMSL2 SERIALIZER DRIVER
+M: Julien Massot <[email protected]>
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+F: drivers/media/i2c/max96717.c
+
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <[email protected]>
L: [email protected] (moderated for non-subscribers)
@@ -20802,7 +20816,7 @@ M: Sakari Ailus <[email protected]>
S: Maintained
T: git git://linuxtv.org/media_tree.git
-F: Documentation/devicetree/bindings/media/i2c/imx258.yaml
+F: Documentation/devicetree/bindings/media/i2c/sony,imx258.yaml
F: drivers/media/i2c/imx258.c
SONY IMX274 SENSOR DRIVER
@@ -20813,6 +20827,15 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/i2c/sony,imx274.yaml
F: drivers/media/i2c/imx274.c
+SONY IMX283 SENSOR DRIVER
+M: Kieran Bingham <[email protected]>
+M: Umang Jain <[email protected]>
+S: Maintained
+T: git git://linuxtv.org/media_tree.git
+F: Documentation/devicetree/bindings/media/i2c/sony,imx283.yaml
+F: drivers/media/i2c/imx283.c
+
SONY IMX290 SENSOR DRIVER
M: Manivannan Sadhasivam <[email protected]>
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 7ebcb10126c9..b6f1eb5dbbdf 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -839,7 +839,7 @@ static int smscore_configure_board(struct smscore_device_t *coredev)
mtu_msg.x_msg_header.msg_flags = 0;
mtu_msg.x_msg_header.msg_type = MSG_SMS_SET_MAX_TX_MSG_LEN_REQ;
mtu_msg.x_msg_header.msg_length = sizeof(mtu_msg);
- mtu_msg.msg_data[0] = board->mtu;
+ mtu_msg.msg_data = board->mtu;
coredev->sendrequest_handler(coredev->context, &mtu_msg,
sizeof(mtu_msg));
@@ -852,7 +852,7 @@ static int smscore_configure_board(struct smscore_device_t *coredev)
SMS_INIT_MSG(&crys_msg.x_msg_header,
MSG_SMS_NEW_CRYSTAL_REQ,
sizeof(crys_msg));
- crys_msg.msg_data[0] = board->crystal;
+ crys_msg.msg_data = board->crystal;
coredev->sendrequest_handler(coredev->context, &crys_msg,
sizeof(crys_msg));
@@ -1306,7 +1306,7 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
msg = (struct sms_msg_data *)SMS_ALIGN_ADDRESS(buffer);
SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
sizeof(struct sms_msg_data));
- msg->msg_data[0] = mode;
+ msg->msg_data = mode;
rc = smscore_sendrequest_and_wait(coredev, msg,
msg->x_msg_header. msg_length,
@@ -1394,7 +1394,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
sizeof(struct sms_msg_data));
- msg->msg_data[0] = mode;
+ msg->msg_data = mode;
rc = smscore_sendrequest_and_wait(
coredev, msg, msg->x_msg_header.msg_length,
@@ -1554,7 +1554,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
pr_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x\n",
- validity->msg_data[0]);
+ validity->msg_data);
complete(&coredev->data_validity_done);
break;
}
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
index f8789ee0d554..82d9f8a64d99 100644
--- a/drivers/media/common/siano/smscoreapi.h
+++ b/drivers/media/common/siano/smscoreapi.h
@@ -616,7 +616,7 @@ struct sms_msg_hdr {
struct sms_msg_data {
struct sms_msg_hdr x_msg_header;
- u32 msg_data[1];
+ u32 msg_data;
};
struct sms_msg_data2 {
@@ -666,7 +666,7 @@ struct sms_firmware {
u32 check_sum;
u32 length;
u32 start_address;
- u8 payload[1];
+ u8 payload[];
};
/* statistics information returned as response for
@@ -1042,20 +1042,6 @@ struct sms_srvm_signal_status {
u32 request_id;
};
-struct sms_i2c_req {
- u32 device_address; /* I2c device address */
- u32 write_count; /* number of bytes to write */
- u32 read_count; /* number of bytes to read */
- u8 Data[1];
-};
-
-struct sms_i2c_res {
- u32 status; /* non-zero value in case of failure */
- u32 read_count; /* number of bytes read */
- u8 Data[1];
-};
-
-
struct smscore_config_gpio {
#define SMS_GPIO_DIRECTION_INPUT 0
#define SMS_GPIO_DIRECTION_OUTPUT 1
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index d893a0e4672b..44d8fe8b220e 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -689,7 +689,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed)
pid_msg.x_msg_header.msg_flags = 0;
pid_msg.x_msg_header.msg_type = MSG_SMS_ADD_PID_FILTER_REQ;
pid_msg.x_msg_header.msg_length = sizeof(pid_msg);
- pid_msg.msg_data[0] = feed->pid;
+ pid_msg.msg_data = feed->pid;
return smsclient_sendrequest(client->smsclient,
&pid_msg, sizeof(pid_msg));
@@ -711,7 +711,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
pid_msg.x_msg_header.msg_flags = 0;
pid_msg.x_msg_header.msg_type = MSG_SMS_REMOVE_PID_FILTER_REQ;
pid_msg.x_msg_header.msg_length = sizeof(pid_msg);
- pid_msg.msg_data[0] = feed->pid;
+ pid_msg.msg_data = feed->pid;
return smsclient_sendrequest(client->smsclient,
&pid_msg, sizeof(pid_msg));
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
index a3573814919b..b957970c7d97 100644
--- a/drivers/media/common/siano/smsendian.c
+++ b/drivers/media/common/siano/smsendian.c
@@ -20,11 +20,12 @@ void smsendian_handle_tx_message(void *buffer)
struct sms_msg_data *msg = buffer;
int i;
int msg_words;
+ u32 *msg_data = &msg->msg_data;
switch (msg->x_msg_header.msg_type) {
case MSG_SMS_DATA_DOWNLOAD_REQ:
{
- msg->msg_data[0] = le32_to_cpu((__force __le32)(msg->msg_data[0]));
+ msg->msg_data = le32_to_cpu((__force __le32)(msg->msg_data));
break;
}
@@ -33,7 +34,7 @@ void smsendian_handle_tx_message(void *buffer)
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
+ msg_data[i] = le32_to_cpu((__force __le32)msg_data[i]);
break;
}
@@ -66,11 +67,12 @@ void smsendian_handle_rx_message(void *buffer)
default:
{
+ u32 *msg_data = &msg->msg_data;
msg_words = (msg->x_msg_header.msg_length -
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
+ msg_data[i] = le32_to_cpu((__force __le32)msg_data[i]);
break;
}
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 444fe1c4bf2d..c5582d4fa5be 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -32,11 +32,6 @@ MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (defau
__func__, ##arg); \
} while (0)
-struct i2c_device {
- struct i2c_adapter *i2c_adap;
- u8 i2c_addr;
-};
-
struct dib7000p_state {
struct dvb_frontend demod;
struct dib7000p_config cfg;
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 6fcaf07e1b82..779cce93e94a 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -976,13 +976,6 @@ static struct drx_aud_data drxj_default_aud_data_g = {
/*-----------------------------------------------------------------------------
STRUCTURES
----------------------------------------------------------------------------*/
-struct drxjeq_stat {
- u16 eq_mse;
- u8 eq_mode;
- u8 eq_ctrl;
- u8 eq_stat;
-};
-
/* HI command */
struct drxj_hi_cmd {
u16 cmd;
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index cc45139057ba..3b02d504941f 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -748,6 +748,22 @@ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 d
return stv090x_write_regs(state, reg, &tmp, 1);
}
+static inline void stv090x_tuner_i2c_lock(struct stv090x_state *state)
+{
+ if (state->config->tuner_i2c_lock)
+ state->config->tuner_i2c_lock(&state->frontend, 1);
+ else
+ mutex_lock(&state->internal->tuner_lock);
+}
+
+static inline void stv090x_tuner_i2c_unlock(struct stv090x_state *state)
+{
+ if (state->config->tuner_i2c_lock)
+ state->config->tuner_i2c_lock(&state->frontend, 0);
+ else
+ mutex_unlock(&state->internal->tuner_lock);
+}
+
static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
{
u32 reg;
@@ -761,12 +777,8 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
* In case of any error, the lock is unlocked and exit within the
* relevant operations themselves.
*/
- if (enable) {
- if (state->config->tuner_i2c_lock)
- state->config->tuner_i2c_lock(&state->frontend, 1);
- else
- mutex_lock(&state->internal->tuner_lock);
- }
+ if (enable)
+ stv090x_tuner_i2c_lock(state);
reg = STV090x_READ_DEMOD(state, I2CRPT);
if (enable) {
@@ -782,20 +794,13 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
goto err;
}
- if (!enable) {
- if (state->config->tuner_i2c_lock)
- state->config->tuner_i2c_lock(&state->frontend, 0);
- else
- mutex_unlock(&state->internal->tuner_lock);
- }
+ if (!enable)
+ stv090x_tuner_i2c_unlock(state);
return 0;
err:
dprintk(FE_ERROR, 1, "I/O error");
- if (state->config->tuner_i2c_lock)
- state->config->tuner_i2c_lock(&state->frontend, 0);
- else
- mutex_unlock(&state->internal->tuner_lock);
+ stv090x_tuner_i2c_unlock(state);
return -1;
}
diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c
index e517ff757744..069dec75129c 100644
--- a/drivers/media/dvb-frontends/stv0910.c
+++ b/drivers/media/dvb-frontends/stv0910.c
@@ -119,11 +119,6 @@ struct stv {
u8 vth[6];
};
-struct sinit_table {
- u16 address;
- u8 data;
-};
-
struct slookup {
s16 value;
u32 reg_value;
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index c6d3ee472d81..5498128773c7 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -139,6 +139,7 @@ config VIDEO_IMX219
config VIDEO_IMX258
tristate "Sony IMX258 sensor support"
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX258 camera.
@@ -153,6 +154,16 @@ config VIDEO_IMX274
This is a V4L2 sensor driver for the Sony IMX274
CMOS image sensor.
+config VIDEO_IMX283
+ tristate "Sony IMX283 sensor support"
+ select V4L2_CCI_I2C
+ help
+ This is a V4L2 sensor driver for the Sony IMX283
+ CMOS image sensor.
+
+ To compile this driver as a module, choose M here: the
+ module will be called imx283.
+
config VIDEO_IMX290
tristate "Sony IMX290 sensor support"
select REGMAP_I2C
@@ -1575,6 +1586,40 @@ config VIDEO_DS90UB960
Device driver for the Texas Instruments DS90UB960
FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer.
+config VIDEO_MAX96714
+ tristate "Maxim MAX96714 GMSL2 deserializer"
+ depends on OF && I2C && VIDEO_DEV
+ select I2C_MUX
+ select MEDIA_CONTROLLER
+ select GPIOLIB
+ select V4L2_CCI_I2C
+ select V4L2_FWNODE
+ select VIDEO_V4L2_SUBDEV_API
+ help
+ Device driver for the Maxim MAX96714 GMSL2 Deserializer.
+ MAX96714 deserializers convert a GMSL2 input to MIPI CSI-2
+ output.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max96714.
+
+config VIDEO_MAX96717
+ tristate "Maxim MAX96717 GMSL2 Serializer support"
+ depends on OF && I2C && VIDEO_DEV && COMMON_CLK
+ select I2C_MUX
+ select MEDIA_CONTROLLER
+ select GPIOLIB
+ select V4L2_CCI_I2C
+ select V4L2_FWNODE
+ select VIDEO_V4L2_SUBDEV_API
+ help
+ Device driver for the Maxim MAX96717 GMSL2 Serializer.
+ MAX96717 serializers convert video on a MIPI CSI-2
+ input to a GMSL2 output.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max96717.
+
endmenu
endif # VIDEO_DEV
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..d1403e3273ca 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_VIDEO_IMX214) += imx214.o
obj-$(CONFIG_VIDEO_IMX219) += imx219.o
obj-$(CONFIG_VIDEO_IMX258) += imx258.o
obj-$(CONFIG_VIDEO_IMX274) += imx274.o
+obj-$(CONFIG_VIDEO_IMX283) += imx283.o
obj-$(CONFIG_VIDEO_IMX290) += imx290.o
obj-$(CONFIG_VIDEO_IMX296) += imx296.o
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
@@ -64,6 +65,8 @@ obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
+obj-$(CONFIG_VIDEO_MAX96714) += max96714.o
+obj-$(CONFIG_VIDEO_MAX96717) += max96717.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index 79946e9c7401..261871be833f 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -62,11 +62,6 @@ MODULE_LICENSE("GPL v2");
**********************************************************************
*/
-struct i2c_reg_value {
- unsigned char reg;
- unsigned char value;
-};
-
struct adv7511_state_edid {
/* total number of blocks */
u32 blocks;
diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
index daabbece8c7e..18ef2b35c9aa 100644
--- a/drivers/media/i2c/dw9768.c
+++ b/drivers/media/i2c/dw9768.c
@@ -115,11 +115,6 @@ static inline struct dw9768 *sd_to_dw9768(struct v4l2_subdev *subdev)
return container_of(subdev, struct dw9768, sd);
}
-struct regval_list {
- u8 reg_num;
- u8 value;
-};
-
struct dw9768_aac_mode_ot_multi {
u32 aac_mode_enum;
u32 ot_multi_base100;
diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
index 9c565ec033d4..52d9ca68a86c 100644
--- a/drivers/media/i2c/hi846.c
+++ b/drivers/media/i2c/hi846.c
@@ -1851,7 +1851,7 @@ static int hi846_get_selection(struct v4l2_subdev *sd,
mutex_lock(&hi846->mutex);
switch (sel->which) {
case V4L2_SUBDEV_FORMAT_TRY:
- v4l2_subdev_state_get_crop(sd_state, sel->pad);
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad);
break;
case V4L2_SUBDEV_FORMAT_ACTIVE:
sel->r = hi846->cur_mode->crop;
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index a577afb530b7..1a99eaaff21a 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -7,97 +7,150 @@
#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-device.h>
#include <media/v4l2-fwnode.h>
#include <asm/unaligned.h>
-#define IMX258_REG_VALUE_08BIT 1
-#define IMX258_REG_VALUE_16BIT 2
-
-#define IMX258_REG_MODE_SELECT 0x0100
+#define IMX258_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX258_MODE_STANDBY 0x00
#define IMX258_MODE_STREAMING 0x01
+#define IMX258_REG_RESET CCI_REG8(0x0103)
+
/* Chip ID */
-#define IMX258_REG_CHIP_ID 0x0016
+#define IMX258_REG_CHIP_ID CCI_REG16(0x0016)
#define IMX258_CHIP_ID 0x0258
/* V_TIMING internal */
#define IMX258_VTS_30FPS 0x0c50
#define IMX258_VTS_30FPS_2K 0x0638
#define IMX258_VTS_30FPS_VGA 0x034c
-#define IMX258_VTS_MAX 0xffff
-
-/*Frame Length Line*/
-#define IMX258_FLL_MIN 0x08a6
-#define IMX258_FLL_MAX 0xffff
-#define IMX258_FLL_STEP 1
-#define IMX258_FLL_DEFAULT 0x0c98
+#define IMX258_VTS_MAX 65525
/* HBLANK control - read only */
#define IMX258_PPL_DEFAULT 5352
/* Exposure control */
-#define IMX258_REG_EXPOSURE 0x0202
+#define IMX258_REG_EXPOSURE CCI_REG16(0x0202)
+#define IMX258_EXPOSURE_OFFSET 10
#define IMX258_EXPOSURE_MIN 4
#define IMX258_EXPOSURE_STEP 1
#define IMX258_EXPOSURE_DEFAULT 0x640
-#define IMX258_EXPOSURE_MAX 65535
+#define IMX258_EXPOSURE_MAX (IMX258_VTS_MAX - IMX258_EXPOSURE_OFFSET)
/* Analog gain control */
-#define IMX258_REG_ANALOG_GAIN 0x0204
+#define IMX258_REG_ANALOG_GAIN CCI_REG16(0x0204)
#define IMX258_ANA_GAIN_MIN 0
#define IMX258_ANA_GAIN_MAX 480
#define IMX258_ANA_GAIN_STEP 1
#define IMX258_ANA_GAIN_DEFAULT 0x0
/* Digital gain control */
-#define IMX258_REG_GR_DIGITAL_GAIN 0x020e
-#define IMX258_REG_R_DIGITAL_GAIN 0x0210
-#define IMX258_REG_B_DIGITAL_GAIN 0x0212
-#define IMX258_REG_GB_DIGITAL_GAIN 0x0214
+#define IMX258_REG_GR_DIGITAL_GAIN CCI_REG16(0x020e)
+#define IMX258_REG_R_DIGITAL_GAIN CCI_REG16(0x0210)
+#define IMX258_REG_B_DIGITAL_GAIN CCI_REG16(0x0212)
+#define IMX258_REG_GB_DIGITAL_GAIN CCI_REG16(0x0214)
#define IMX258_DGTL_GAIN_MIN 0
#define IMX258_DGTL_GAIN_MAX 4096 /* Max = 0xFFF */
#define IMX258_DGTL_GAIN_DEFAULT 1024
#define IMX258_DGTL_GAIN_STEP 1
/* HDR control */
-#define IMX258_REG_HDR 0x0220
+#define IMX258_REG_HDR CCI_REG8(0x0220)
#define IMX258_HDR_ON BIT(0)
-#define IMX258_REG_HDR_RATIO 0x0222
+#define IMX258_REG_HDR_RATIO CCI_REG8(0x0222)
#define IMX258_HDR_RATIO_MIN 0
#define IMX258_HDR_RATIO_MAX 5
#define IMX258_HDR_RATIO_STEP 1
#define IMX258_HDR_RATIO_DEFAULT 0x0
/* Test Pattern Control */
-#define IMX258_REG_TEST_PATTERN 0x0600
+#define IMX258_REG_TEST_PATTERN CCI_REG16(0x0600)
+
+#define IMX258_CLK_BLANK_STOP CCI_REG8(0x4040)
/* Orientation */
-#define REG_MIRROR_FLIP_CONTROL 0x0101
-#define REG_CONFIG_MIRROR_FLIP 0x03
-#define REG_CONFIG_FLIP_TEST_PATTERN 0x02
+#define REG_MIRROR_FLIP_CONTROL CCI_REG8(0x0101)
+#define REG_CONFIG_MIRROR_HFLIP 0x01
+#define REG_CONFIG_MIRROR_VFLIP 0x02
+
+/* IMX258 native and active pixel array size. */
+#define IMX258_NATIVE_WIDTH 4224U
+#define IMX258_NATIVE_HEIGHT 3192U
+#define IMX258_PIXEL_ARRAY_LEFT 8U
+#define IMX258_PIXEL_ARRAY_TOP 16U
+#define IMX258_PIXEL_ARRAY_WIDTH 4208U
+#define IMX258_PIXEL_ARRAY_HEIGHT 3120U
+
+/* regs */
+#define IMX258_REG_PLL_MULT_DRIV CCI_REG8(0x0310)
+#define IMX258_REG_IVTPXCK_DIV CCI_REG8(0x0301)
+#define IMX258_REG_IVTSYCK_DIV CCI_REG8(0x0303)
+#define IMX258_REG_PREPLLCK_VT_DIV CCI_REG8(0x0305)
+#define IMX258_REG_IOPPXCK_DIV CCI_REG8(0x0309)
+#define IMX258_REG_IOPSYCK_DIV CCI_REG8(0x030b)
+#define IMX258_REG_PREPLLCK_OP_DIV CCI_REG8(0x030d)
+#define IMX258_REG_PHASE_PIX_OUTEN CCI_REG8(0x3030)
+#define IMX258_REG_PDPIX_DATA_RATE CCI_REG8(0x3032)
+#define IMX258_REG_SCALE_MODE CCI_REG8(0x0401)
+#define IMX258_REG_SCALE_MODE_EXT CCI_REG8(0x3038)
+#define IMX258_REG_AF_WINDOW_MODE CCI_REG8(0x7bcd)
+#define IMX258_REG_FRM_LENGTH_CTL CCI_REG8(0x0350)
+#define IMX258_REG_CSI_LANE_MODE CCI_REG8(0x0114)
+#define IMX258_REG_X_EVN_INC CCI_REG8(0x0381)
+#define IMX258_REG_X_ODD_INC CCI_REG8(0x0383)
+#define IMX258_REG_Y_EVN_INC CCI_REG8(0x0385)
+#define IMX258_REG_Y_ODD_INC CCI_REG8(0x0387)
+#define IMX258_REG_BINNING_MODE CCI_REG8(0x0900)
+#define IMX258_REG_BINNING_TYPE_V CCI_REG8(0x0901)
+#define IMX258_REG_FORCE_FD_SUM CCI_REG8(0x300d)
+#define IMX258_REG_DIG_CROP_X_OFFSET CCI_REG16(0x0408)
+#define IMX258_REG_DIG_CROP_Y_OFFSET CCI_REG16(0x040a)
+#define IMX258_REG_DIG_CROP_IMAGE_WIDTH CCI_REG16(0x040c)
+#define IMX258_REG_DIG_CROP_IMAGE_HEIGHT CCI_REG16(0x040e)
+#define IMX258_REG_SCALE_M CCI_REG16(0x0404)
+#define IMX258_REG_X_OUT_SIZE CCI_REG16(0x034c)
+#define IMX258_REG_Y_OUT_SIZE CCI_REG16(0x034e)
+#define IMX258_REG_X_ADD_STA CCI_REG16(0x0344)
+#define IMX258_REG_Y_ADD_STA CCI_REG16(0x0346)
+#define IMX258_REG_X_ADD_END CCI_REG16(0x0348)
+#define IMX258_REG_Y_ADD_END CCI_REG16(0x034a)
+#define IMX258_REG_EXCK_FREQ CCI_REG16(0x0136)
+#define IMX258_REG_CSI_DT_FMT CCI_REG16(0x0112)
+#define IMX258_REG_LINE_LENGTH_PCK CCI_REG16(0x0342)
+#define IMX258_REG_SCALE_M_EXT CCI_REG16(0x303a)
+#define IMX258_REG_FRM_LENGTH_LINES CCI_REG16(0x0340)
+#define IMX258_REG_FINE_INTEG_TIME CCI_REG8(0x0200)
+#define IMX258_REG_PLL_IVT_MPY CCI_REG16(0x0306)
+#define IMX258_REG_PLL_IOP_MPY CCI_REG16(0x030e)
+#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H CCI_REG16(0x0820)
+#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L CCI_REG16(0x0822)
-/* Input clock frequency in Hz */
-#define IMX258_INPUT_CLOCK_FREQ 19200000
+struct imx258_reg_list {
+ u32 num_of_regs;
+ const struct cci_reg_sequence *regs;
+};
-struct imx258_reg {
- u16 address;
- u8 val;
+struct imx258_link_cfg {
+ unsigned int lf_to_pix_rate_factor;
+ struct imx258_reg_list reg_list;
};
-struct imx258_reg_list {
- u32 num_of_regs;
- const struct imx258_reg *regs;
+enum {
+ IMX258_2_LANE_MODE,
+ IMX258_4_LANE_MODE,
+ IMX258_LANE_CONFIGS,
};
/* Link frequency config */
struct imx258_link_freq_config {
u32 pixels_per_line;
- /* PLL registers for this link frequency */
- struct imx258_reg_list reg_list;
+ /* Configuration for this link frequency / num lanes selection */
+ struct imx258_link_cfg link_cfg[IMX258_LANE_CONFIGS];
};
/* Mode : resolution and related config&values */
@@ -115,400 +168,307 @@ struct imx258_mode {
u32 link_freq_index;
/* Default register values */
struct imx258_reg_list reg_list;
+
+ /* Analog crop rectangle */
+ struct v4l2_rect crop;
+};
+
+/*
+ * 4208x3120 @ 30 fps needs 1267Mbps/lane, 4 lanes.
+ * To avoid further computation of clock settings, adopt the same per
+ * lane data rate when using 2 lanes, thus allowing a maximum of 15fps.
+ */
+static const struct cci_reg_sequence mipi_1267mbps_19_2mhz_2l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1333 },
+ { IMX258_REG_IVTPXCK_DIV, 10 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 3 },
+ { IMX258_REG_PLL_IVT_MPY, 198 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 1 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1267 * 2 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
+};
+
+static const struct cci_reg_sequence mipi_1267mbps_19_2mhz_4l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1333 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 3 },
+ { IMX258_REG_PLL_IVT_MPY, 198 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 3 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1267 * 4 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
+};
+
+static const struct cci_reg_sequence mipi_1272mbps_24mhz_2l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1800 },
+ { IMX258_REG_IVTPXCK_DIV, 10 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 4 },
+ { IMX258_REG_PLL_IVT_MPY, 212 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 1 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1272 * 2 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
+};
+
+static const struct cci_reg_sequence mipi_1272mbps_24mhz_4l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1800 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 4 },
+ { IMX258_REG_PLL_IVT_MPY, 212 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 3 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 1272 * 4 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
+};
+
+static const struct cci_reg_sequence mipi_640mbps_19_2mhz_2l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1333 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 3 },
+ { IMX258_REG_PLL_IVT_MPY, 100 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 1 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 640 * 2 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
+};
+
+static const struct cci_reg_sequence mipi_640mbps_19_2mhz_4l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1333 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 3 },
+ { IMX258_REG_PLL_IVT_MPY, 100 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 3 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 640 * 4 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
};
-/* 4208x3118 needs 1267Mbps/lane, 4 lanes */
-static const struct imx258_reg mipi_data_rate_1267mbps[] = {
- { 0x0301, 0x05 },
- { 0x0303, 0x02 },
- { 0x0305, 0x03 },
- { 0x0306, 0x00 },
- { 0x0307, 0xC6 },
- { 0x0309, 0x0A },
- { 0x030B, 0x01 },
- { 0x030D, 0x02 },
- { 0x030E, 0x00 },
- { 0x030F, 0xD8 },
- { 0x0310, 0x00 },
- { 0x0820, 0x13 },
- { 0x0821, 0x4C },
- { 0x0822, 0xCC },
- { 0x0823, 0xCC },
+static const struct cci_reg_sequence mipi_642mbps_24mhz_2l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1800 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 4 },
+ { IMX258_REG_PLL_IVT_MPY, 107 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 1 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 642 * 2 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
};
-static const struct imx258_reg mipi_data_rate_640mbps[] = {
- { 0x0301, 0x05 },
- { 0x0303, 0x02 },
- { 0x0305, 0x03 },
- { 0x0306, 0x00 },
- { 0x0307, 0x64 },
- { 0x0309, 0x0A },
- { 0x030B, 0x01 },
- { 0x030D, 0x02 },
- { 0x030E, 0x00 },
- { 0x030F, 0xD8 },
- { 0x0310, 0x00 },
- { 0x0820, 0x0A },
- { 0x0821, 0x00 },
- { 0x0822, 0x00 },
- { 0x0823, 0x00 },
+static const struct cci_reg_sequence mipi_642mbps_24mhz_4l[] = {
+ { IMX258_REG_EXCK_FREQ, 0x1800 },
+ { IMX258_REG_IVTPXCK_DIV, 5 },
+ { IMX258_REG_IVTSYCK_DIV, 2 },
+ { IMX258_REG_PREPLLCK_VT_DIV, 4 },
+ { IMX258_REG_PLL_IVT_MPY, 107 },
+ { IMX258_REG_IOPPXCK_DIV, 10 },
+ { IMX258_REG_IOPSYCK_DIV, 1 },
+ { IMX258_REG_PREPLLCK_OP_DIV, 2 },
+ { IMX258_REG_PLL_IOP_MPY, 216 },
+ { IMX258_REG_PLL_MULT_DRIV, 0 },
+
+ { IMX258_REG_CSI_LANE_MODE, 3 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H, 642 * 4 },
+ { IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L, 0 },
};
-static const struct imx258_reg mode_4208x3118_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x3051, 0x00 },
- { 0x3052, 0x00 },
- { 0x4E21, 0x14 },
- { 0x6B11, 0xCF },
- { 0x7FF0, 0x08 },
- { 0x7FF1, 0x0F },
- { 0x7FF2, 0x08 },
- { 0x7FF3, 0x1B },
- { 0x7FF4, 0x23 },
- { 0x7FF5, 0x60 },
- { 0x7FF6, 0x00 },
- { 0x7FF7, 0x01 },
- { 0x7FF8, 0x00 },
- { 0x7FF9, 0x78 },
- { 0x7FFA, 0x00 },
- { 0x7FFB, 0x00 },
- { 0x7FFC, 0x00 },
- { 0x7FFD, 0x00 },
- { 0x7FFE, 0x00 },
- { 0x7FFF, 0x03 },
- { 0x7F76, 0x03 },
- { 0x7F77, 0xFE },
- { 0x7FA8, 0x03 },
- { 0x7FA9, 0xFE },
- { 0x7B24, 0x81 },
- { 0x7B25, 0x00 },
- { 0x6564, 0x07 },
- { 0x6B0D, 0x41 },
- { 0x653D, 0x04 },
- { 0x6B05, 0x8C },
- { 0x6B06, 0xF9 },
- { 0x6B08, 0x65 },
- { 0x6B09, 0xFC },
- { 0x6B0A, 0xCF },
- { 0x6B0B, 0xD2 },
- { 0x6700, 0x0E },
- { 0x6707, 0x0E },
- { 0x9104, 0x00 },
- { 0x4648, 0x7F },
- { 0x7420, 0x00 },
- { 0x7421, 0x1C },
- { 0x7422, 0x00 },
- { 0x7423, 0xD7 },
- { 0x5F04, 0x00 },
- { 0x5F05, 0xED },
- { 0x0112, 0x0A },
- { 0x0113, 0x0A },
- { 0x0114, 0x03 },
- { 0x0342, 0x14 },
- { 0x0343, 0xE8 },
- { 0x0340, 0x0C },
- { 0x0341, 0x50 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x10 },
- { 0x0349, 0x6F },
- { 0x034A, 0x0C },
- { 0x034B, 0x2E },
- { 0x0381, 0x01 },
- { 0x0383, 0x01 },
- { 0x0385, 0x01 },
- { 0x0387, 0x01 },
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0401, 0x00 },
- { 0x0404, 0x00 },
- { 0x0405, 0x10 },
- { 0x0408, 0x00 },
- { 0x0409, 0x00 },
- { 0x040A, 0x00 },
- { 0x040B, 0x00 },
- { 0x040C, 0x10 },
- { 0x040D, 0x70 },
- { 0x040E, 0x0C },
- { 0x040F, 0x30 },
- { 0x3038, 0x00 },
- { 0x303A, 0x00 },
- { 0x303B, 0x10 },
- { 0x300D, 0x00 },
- { 0x034C, 0x10 },
- { 0x034D, 0x70 },
- { 0x034E, 0x0C },
- { 0x034F, 0x30 },
- { 0x0350, 0x01 },
- { 0x0202, 0x0C },
- { 0x0203, 0x46 },
- { 0x0204, 0x00 },
- { 0x0205, 0x00 },
- { 0x020E, 0x01 },
- { 0x020F, 0x00 },
- { 0x0210, 0x01 },
- { 0x0211, 0x00 },
- { 0x0212, 0x01 },
- { 0x0213, 0x00 },
- { 0x0214, 0x01 },
- { 0x0215, 0x00 },
- { 0x7BCD, 0x00 },
- { 0x94DC, 0x20 },
- { 0x94DD, 0x20 },
- { 0x94DE, 0x20 },
- { 0x95DC, 0x20 },
- { 0x95DD, 0x20 },
- { 0x95DE, 0x20 },
- { 0x7FB0, 0x00 },
- { 0x9010, 0x3E },
- { 0x9419, 0x50 },
- { 0x941B, 0x50 },
- { 0x9519, 0x50 },
- { 0x951B, 0x50 },
- { 0x3030, 0x00 },
- { 0x3032, 0x00 },
- { 0x0220, 0x00 },
+static const struct cci_reg_sequence mode_common_regs[] = {
+ { CCI_REG8(0x3051), 0x00 },
+ { CCI_REG8(0x6B11), 0xCF },
+ { CCI_REG8(0x7FF0), 0x08 },
+ { CCI_REG8(0x7FF1), 0x0F },
+ { CCI_REG8(0x7FF2), 0x08 },
+ { CCI_REG8(0x7FF3), 0x1B },
+ { CCI_REG8(0x7FF4), 0x23 },
+ { CCI_REG8(0x7FF5), 0x60 },
+ { CCI_REG8(0x7FF6), 0x00 },
+ { CCI_REG8(0x7FF7), 0x01 },
+ { CCI_REG8(0x7FF8), 0x00 },
+ { CCI_REG8(0x7FF9), 0x78 },
+ { CCI_REG8(0x7FFA), 0x00 },
+ { CCI_REG8(0x7FFB), 0x00 },
+ { CCI_REG8(0x7FFC), 0x00 },
+ { CCI_REG8(0x7FFD), 0x00 },
+ { CCI_REG8(0x7FFE), 0x00 },
+ { CCI_REG8(0x7FFF), 0x03 },
+ { CCI_REG8(0x7F76), 0x03 },
+ { CCI_REG8(0x7F77), 0xFE },
+ { CCI_REG8(0x7FA8), 0x03 },
+ { CCI_REG8(0x7FA9), 0xFE },
+ { CCI_REG8(0x7B24), 0x81 },
+ { CCI_REG8(0x6564), 0x07 },
+ { CCI_REG8(0x6B0D), 0x41 },
+ { CCI_REG8(0x653D), 0x04 },
+ { CCI_REG8(0x6B05), 0x8C },
+ { CCI_REG8(0x6B06), 0xF9 },
+ { CCI_REG8(0x6B08), 0x65 },
+ { CCI_REG8(0x6B09), 0xFC },
+ { CCI_REG8(0x6B0A), 0xCF },
+ { CCI_REG8(0x6B0B), 0xD2 },
+ { CCI_REG8(0x6700), 0x0E },
+ { CCI_REG8(0x6707), 0x0E },
+ { CCI_REG8(0x9104), 0x00 },
+ { CCI_REG8(0x4648), 0x7F },
+ { CCI_REG8(0x7420), 0x00 },
+ { CCI_REG8(0x7421), 0x1C },
+ { CCI_REG8(0x7422), 0x00 },
+ { CCI_REG8(0x7423), 0xD7 },
+ { CCI_REG8(0x5F04), 0x00 },
+ { CCI_REG8(0x5F05), 0xED },
+ {IMX258_REG_CSI_DT_FMT, 0x0a0a},
+ {IMX258_REG_LINE_LENGTH_PCK, 5352},
+ {IMX258_REG_X_ADD_STA, 0},
+ {IMX258_REG_Y_ADD_STA, 0},
+ {IMX258_REG_X_ADD_END, 4207},
+ {IMX258_REG_Y_ADD_END, 3119},
+ {IMX258_REG_X_EVN_INC, 1},
+ {IMX258_REG_X_ODD_INC, 1},
+ {IMX258_REG_Y_EVN_INC, 1},
+ {IMX258_REG_Y_ODD_INC, 1},
+ {IMX258_REG_DIG_CROP_X_OFFSET, 0},
+ {IMX258_REG_DIG_CROP_Y_OFFSET, 0},
+ {IMX258_REG_DIG_CROP_IMAGE_WIDTH, 4208},
+ {IMX258_REG_SCALE_MODE_EXT, 0},
+ {IMX258_REG_SCALE_M_EXT, 16},
+ {IMX258_REG_FORCE_FD_SUM, 0},
+ {IMX258_REG_FRM_LENGTH_CTL, 0},
+ {IMX258_REG_ANALOG_GAIN, 0},
+ {IMX258_REG_GR_DIGITAL_GAIN, 256},
+ {IMX258_REG_R_DIGITAL_GAIN, 256},
+ {IMX258_REG_B_DIGITAL_GAIN, 256},
+ {IMX258_REG_GB_DIGITAL_GAIN, 256},
+ {IMX258_REG_AF_WINDOW_MODE, 0},
+ { CCI_REG8(0x94DC), 0x20 },
+ { CCI_REG8(0x94DD), 0x20 },
+ { CCI_REG8(0x94DE), 0x20 },
+ { CCI_REG8(0x95DC), 0x20 },
+ { CCI_REG8(0x95DD), 0x20 },
+ { CCI_REG8(0x95DE), 0x20 },
+ { CCI_REG8(0x7FB0), 0x00 },
+ { CCI_REG8(0x9010), 0x3E },
+ { CCI_REG8(0x9419), 0x50 },
+ { CCI_REG8(0x941B), 0x50 },
+ { CCI_REG8(0x9519), 0x50 },
+ { CCI_REG8(0x951B), 0x50 },
+ {IMX258_REG_PHASE_PIX_OUTEN, 0},
+ {IMX258_REG_PDPIX_DATA_RATE, 0},
+ {IMX258_REG_HDR, 0},
};
-static const struct imx258_reg mode_2104_1560_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x3051, 0x00 },
- { 0x3052, 0x00 },
- { 0x4E21, 0x14 },
- { 0x6B11, 0xCF },
- { 0x7FF0, 0x08 },
- { 0x7FF1, 0x0F },
- { 0x7FF2, 0x08 },
- { 0x7FF3, 0x1B },
- { 0x7FF4, 0x23 },
- { 0x7FF5, 0x60 },
- { 0x7FF6, 0x00 },
- { 0x7FF7, 0x01 },
- { 0x7FF8, 0x00 },
- { 0x7FF9, 0x78 },
- { 0x7FFA, 0x00 },
- { 0x7FFB, 0x00 },
- { 0x7FFC, 0x00 },
- { 0x7FFD, 0x00 },
- { 0x7FFE, 0x00 },
- { 0x7FFF, 0x03 },
- { 0x7F76, 0x03 },
- { 0x7F77, 0xFE },
- { 0x7FA8, 0x03 },
- { 0x7FA9, 0xFE },
- { 0x7B24, 0x81 },
- { 0x7B25, 0x00 },
- { 0x6564, 0x07 },
- { 0x6B0D, 0x41 },
- { 0x653D, 0x04 },
- { 0x6B05, 0x8C },
- { 0x6B06, 0xF9 },
- { 0x6B08, 0x65 },
- { 0x6B09, 0xFC },
- { 0x6B0A, 0xCF },
- { 0x6B0B, 0xD2 },
- { 0x6700, 0x0E },
- { 0x6707, 0x0E },
- { 0x9104, 0x00 },
- { 0x4648, 0x7F },
- { 0x7420, 0x00 },
- { 0x7421, 0x1C },
- { 0x7422, 0x00 },
- { 0x7423, 0xD7 },
- { 0x5F04, 0x00 },
- { 0x5F05, 0xED },
- { 0x0112, 0x0A },
- { 0x0113, 0x0A },
- { 0x0114, 0x03 },
- { 0x0342, 0x14 },
- { 0x0343, 0xE8 },
- { 0x0340, 0x06 },
- { 0x0341, 0x38 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x10 },
- { 0x0349, 0x6F },
- { 0x034A, 0x0C },
- { 0x034B, 0x2E },
- { 0x0381, 0x01 },
- { 0x0383, 0x01 },
- { 0x0385, 0x01 },
- { 0x0387, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x12 },
- { 0x0401, 0x01 },
- { 0x0404, 0x00 },
- { 0x0405, 0x20 },
- { 0x0408, 0x00 },
- { 0x0409, 0x02 },
- { 0x040A, 0x00 },
- { 0x040B, 0x00 },
- { 0x040C, 0x10 },
- { 0x040D, 0x6A },
- { 0x040E, 0x06 },
- { 0x040F, 0x18 },
- { 0x3038, 0x00 },
- { 0x303A, 0x00 },
- { 0x303B, 0x10 },
- { 0x300D, 0x00 },
- { 0x034C, 0x08 },
- { 0x034D, 0x38 },
- { 0x034E, 0x06 },
- { 0x034F, 0x18 },
- { 0x0350, 0x01 },
- { 0x0202, 0x06 },
- { 0x0203, 0x2E },
- { 0x0204, 0x00 },
- { 0x0205, 0x00 },
- { 0x020E, 0x01 },
- { 0x020F, 0x00 },
- { 0x0210, 0x01 },
- { 0x0211, 0x00 },
- { 0x0212, 0x01 },
- { 0x0213, 0x00 },
- { 0x0214, 0x01 },
- { 0x0215, 0x00 },
- { 0x7BCD, 0x01 },
- { 0x94DC, 0x20 },
- { 0x94DD, 0x20 },
- { 0x94DE, 0x20 },
- { 0x95DC, 0x20 },
- { 0x95DD, 0x20 },
- { 0x95DE, 0x20 },
- { 0x7FB0, 0x00 },
- { 0x9010, 0x3E },
- { 0x9419, 0x50 },
- { 0x941B, 0x50 },
- { 0x9519, 0x50 },
- { 0x951B, 0x50 },
- { 0x3030, 0x00 },
- { 0x3032, 0x00 },
- { 0x0220, 0x00 },
+static const struct cci_reg_sequence mode_4208x3120_regs[] = {
+ {IMX258_REG_BINNING_MODE, 0},
+ {IMX258_REG_BINNING_TYPE_V, 0x11},
+ {IMX258_REG_SCALE_MODE, 0},
+ {IMX258_REG_SCALE_M, 16},
+ {IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 3120},
+ {IMX258_REG_X_OUT_SIZE, 4208},
+ {IMX258_REG_Y_OUT_SIZE, 3120},
};
-static const struct imx258_reg mode_1048_780_regs[] = {
- { 0x0136, 0x13 },
- { 0x0137, 0x33 },
- { 0x3051, 0x00 },
- { 0x3052, 0x00 },
- { 0x4E21, 0x14 },
- { 0x6B11, 0xCF },
- { 0x7FF0, 0x08 },
- { 0x7FF1, 0x0F },
- { 0x7FF2, 0x08 },
- { 0x7FF3, 0x1B },
- { 0x7FF4, 0x23 },
- { 0x7FF5, 0x60 },
- { 0x7FF6, 0x00 },
- { 0x7FF7, 0x01 },
- { 0x7FF8, 0x00 },
- { 0x7FF9, 0x78 },
- { 0x7FFA, 0x00 },
- { 0x7FFB, 0x00 },
- { 0x7FFC, 0x00 },
- { 0x7FFD, 0x00 },
- { 0x7FFE, 0x00 },
- { 0x7FFF, 0x03 },
- { 0x7F76, 0x03 },
- { 0x7F77, 0xFE },
- { 0x7FA8, 0x03 },
- { 0x7FA9, 0xFE },
- { 0x7B24, 0x81 },
- { 0x7B25, 0x00 },
- { 0x6564, 0x07 },
- { 0x6B0D, 0x41 },
- { 0x653D, 0x04 },
- { 0x6B05, 0x8C },
- { 0x6B06, 0xF9 },
- { 0x6B08, 0x65 },
- { 0x6B09, 0xFC },
- { 0x6B0A, 0xCF },
- { 0x6B0B, 0xD2 },
- { 0x6700, 0x0E },
- { 0x6707, 0x0E },
- { 0x9104, 0x00 },
- { 0x4648, 0x7F },
- { 0x7420, 0x00 },
- { 0x7421, 0x1C },
- { 0x7422, 0x00 },
- { 0x7423, 0xD7 },
- { 0x5F04, 0x00 },
- { 0x5F05, 0xED },
- { 0x0112, 0x0A },
- { 0x0113, 0x0A },
- { 0x0114, 0x03 },
- { 0x0342, 0x14 },
- { 0x0343, 0xE8 },
- { 0x0340, 0x03 },
- { 0x0341, 0x4C },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x10 },
- { 0x0349, 0x6F },
- { 0x034A, 0x0C },
- { 0x034B, 0x2E },
- { 0x0381, 0x01 },
- { 0x0383, 0x01 },
- { 0x0385, 0x01 },
- { 0x0387, 0x01 },
- { 0x0900, 0x01 },
- { 0x0901, 0x14 },
- { 0x0401, 0x01 },
- { 0x0404, 0x00 },
- { 0x0405, 0x40 },
- { 0x0408, 0x00 },
- { 0x0409, 0x06 },
- { 0x040A, 0x00 },
- { 0x040B, 0x00 },
- { 0x040C, 0x10 },
- { 0x040D, 0x64 },
- { 0x040E, 0x03 },
- { 0x040F, 0x0C },
- { 0x3038, 0x00 },
- { 0x303A, 0x00 },
- { 0x303B, 0x10 },
- { 0x300D, 0x00 },
- { 0x034C, 0x04 },
- { 0x034D, 0x18 },
- { 0x034E, 0x03 },
- { 0x034F, 0x0C },
- { 0x0350, 0x01 },
- { 0x0202, 0x03 },
- { 0x0203, 0x42 },
- { 0x0204, 0x00 },
- { 0x0205, 0x00 },
- { 0x020E, 0x01 },
- { 0x020F, 0x00 },
- { 0x0210, 0x01 },
- { 0x0211, 0x00 },
- { 0x0212, 0x01 },
- { 0x0213, 0x00 },
- { 0x0214, 0x01 },
- { 0x0215, 0x00 },
- { 0x7BCD, 0x00 },
- { 0x94DC, 0x20 },
- { 0x94DD, 0x20 },
- { 0x94DE, 0x20 },
- { 0x95DC, 0x20 },
- { 0x95DD, 0x20 },
- { 0x95DE, 0x20 },
- { 0x7FB0, 0x00 },
- { 0x9010, 0x3E },
- { 0x9419, 0x50 },
- { 0x941B, 0x50 },
- { 0x9519, 0x50 },
- { 0x951B, 0x50 },
- { 0x3030, 0x00 },
- { 0x3032, 0x00 },
- { 0x0220, 0x00 },
+static const struct cci_reg_sequence mode_2104_1560_regs[] = {
+ {IMX258_REG_BINNING_MODE, 1},
+ {IMX258_REG_BINNING_TYPE_V, 0x12},
+ {IMX258_REG_SCALE_MODE, 1},
+ {IMX258_REG_SCALE_M, 32},
+ {IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 1560},
+ {IMX258_REG_X_OUT_SIZE, 2104},
+ {IMX258_REG_Y_OUT_SIZE, 1560},
+};
+
+static const struct cci_reg_sequence mode_1048_780_regs[] = {
+ {IMX258_REG_BINNING_MODE, 1},
+ {IMX258_REG_BINNING_TYPE_V, 0x14},
+ {IMX258_REG_SCALE_MODE, 1},
+ {IMX258_REG_SCALE_M, 64},
+ {IMX258_REG_DIG_CROP_IMAGE_HEIGHT, 780},
+ {IMX258_REG_X_OUT_SIZE, 1048},
+ {IMX258_REG_Y_OUT_SIZE, 780},
+};
+
+struct imx258_variant_cfg {
+ const struct cci_reg_sequence *regs;
+ unsigned int num_regs;
+};
+
+static const struct cci_reg_sequence imx258_cfg_regs[] = {
+ { CCI_REG8(0x3052), 0x00 },
+ { CCI_REG8(0x4E21), 0x14 },
+ { CCI_REG8(0x7B25), 0x00 },
+};
+
+static const struct imx258_variant_cfg imx258_cfg = {
+ .regs = imx258_cfg_regs,
+ .num_regs = ARRAY_SIZE(imx258_cfg_regs),
+};
+
+static const struct cci_reg_sequence imx258_pdaf_cfg_regs[] = {
+ { CCI_REG8(0x3052), 0x01 },
+ { CCI_REG8(0x4E21), 0x10 },
+ { CCI_REG8(0x7B25), 0x01 },
+};
+
+static const struct imx258_variant_cfg imx258_pdaf_cfg = {
+ .regs = imx258_pdaf_cfg_regs,
+ .num_regs = ARRAY_SIZE(imx258_pdaf_cfg_regs),
+};
+
+/*
+ * The supported formats.
+ * This table MUST contain 4 entries per format, to cover the various flip
+ * combinations in the order
+ * - no flip
+ * - h flip
+ * - v flip
+ * - h&v flips
+ */
+static const u32 codes[] = {
+ /* 10-bit modes. */
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+ MEDIA_BUS_FMT_SGRBG10_1X10,
+ MEDIA_BUS_FMT_SGBRG10_1X10,
+ MEDIA_BUS_FMT_SBGGR10_1X10
};
static const char * const imx258_test_pattern_menu[] = {
@@ -519,9 +479,15 @@ static const char * const imx258_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
-/* Configurations for supported link frequencies */
-#define IMX258_LINK_FREQ_634MHZ 633600000ULL
-#define IMX258_LINK_FREQ_320MHZ 320000000ULL
+/* regulator supplies */
+static const char * const imx258_supply_name[] = {
+ /* Supplies can be enabled in any order */
+ "vana", /* Analog (2.8V) supply */
+ "vdig", /* Digital Core (1.2V) supply */
+ "vif", /* IF (1.8V) supply */
+};
+
+#define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name)
enum {
IMX258_LINK_FREQ_1267MBPS,
@@ -529,37 +495,96 @@ enum {
};
/*
- * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
- * data rate => double data rate; number of lanes => 4; bits per pixel => 10
+ * Pixel rate does not necessarily relate to link frequency on this sensor as
+ * there is a FIFO between the pixel array pipeline and the MIPI serializer.
+ * The recommendation from Sony is that the pixel array is always run with a
+ * line length of 5352 pixels, which means that there is a large amount of
+ * blanking time for the 1048x780 mode. There is no need to replicate this
+ * blanking on the CSI2 bus, and the configuration of register 0x0301 allows the
+ * divider to be altered.
+ *
+ * The actual factor between link frequency and pixel rate is in the
+ * imx258_link_cfg, so use this to convert between the two.
+ * bits per pixel being 10, and D-PHY being DDR is assumed by this function, so
+ * the value is only the combination of number of lanes and pixel clock divider.
*/
-static u64 link_freq_to_pixel_rate(u64 f)
+static u64 link_freq_to_pixel_rate(u64 f, const struct imx258_link_cfg *link_cfg)
{
- f *= 2 * 4;
+ f *= 2 * link_cfg->lf_to_pix_rate_factor;
do_div(f, 10);
return f;
}
/* Menu items for LINK_FREQ V4L2 control */
-static const s64 link_freq_menu_items[] = {
- IMX258_LINK_FREQ_634MHZ,
- IMX258_LINK_FREQ_320MHZ,
+/* Configurations for supported link frequencies */
+static const s64 link_freq_menu_items_19_2[] = {
+ 633600000ULL,
+ 320000000ULL,
};
+static const s64 link_freq_menu_items_24[] = {
+ 636000000ULL,
+ 321000000ULL,
+};
+
+#define REGS(_list) { .num_of_regs = ARRAY_SIZE(_list), .regs = _list, }
+
/* Link frequency configs */
-static const struct imx258_link_freq_config link_freq_configs[] = {
+static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
[IMX258_LINK_FREQ_1267MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_data_rate_1267mbps),
- .regs = mipi_data_rate_1267mbps,
+ .link_cfg = {
+ [IMX258_2_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 2 * 2,
+ .reg_list = REGS(mipi_1267mbps_19_2mhz_2l),
+ },
+ [IMX258_4_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_1267mbps_19_2mhz_4l),
+ },
}
},
[IMX258_LINK_FREQ_640MBPS] = {
.pixels_per_line = IMX258_PPL_DEFAULT,
- .reg_list = {
- .num_of_regs = ARRAY_SIZE(mipi_data_rate_640mbps),
- .regs = mipi_data_rate_640mbps,
+ .link_cfg = {
+ [IMX258_2_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 2,
+ .reg_list = REGS(mipi_640mbps_19_2mhz_2l),
+ },
+ [IMX258_4_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_640mbps_19_2mhz_4l),
+ },
+ }
+ },
+};
+
+static const struct imx258_link_freq_config link_freq_configs_24[] = {
+ [IMX258_LINK_FREQ_1267MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .link_cfg = {
+ [IMX258_2_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 2,
+ .reg_list = REGS(mipi_1272mbps_24mhz_2l),
+ },
+ [IMX258_4_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_1272mbps_24mhz_4l),
+ },
+ }
+ },
+ [IMX258_LINK_FREQ_640MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .link_cfg = {
+ [IMX258_2_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 2 * 2,
+ .reg_list = REGS(mipi_642mbps_24mhz_2l),
+ },
+ [IMX258_4_LANE_MODE] = {
+ .lf_to_pix_rate_factor = 4,
+ .reg_list = REGS(mipi_642mbps_24mhz_4l),
+ },
}
},
};
@@ -568,14 +593,20 @@ static const struct imx258_link_freq_config link_freq_configs[] = {
static const struct imx258_mode supported_modes[] = {
{
.width = 4208,
- .height = 3118,
+ .height = 3120,
.vts_def = IMX258_VTS_30FPS,
.vts_min = IMX258_VTS_30FPS,
.reg_list = {
- .num_of_regs = ARRAY_SIZE(mode_4208x3118_regs),
- .regs = mode_4208x3118_regs,
+ .num_of_regs = ARRAY_SIZE(mode_4208x3120_regs),
+ .regs = mode_4208x3120_regs,
},
.link_freq_index = IMX258_LINK_FREQ_1267MBPS,
+ .crop = {
+ .left = IMX258_PIXEL_ARRAY_LEFT,
+ .top = IMX258_PIXEL_ARRAY_TOP,
+ .width = 4208,
+ .height = 3120,
+ },
},
{
.width = 2104,
@@ -587,6 +618,12 @@ static const struct imx258_mode supported_modes[] = {
.regs = mode_2104_1560_regs,
},
.link_freq_index = IMX258_LINK_FREQ_640MBPS,
+ .crop = {
+ .left = IMX258_PIXEL_ARRAY_LEFT,
+ .top = IMX258_PIXEL_ARRAY_TOP,
+ .width = 4208,
+ .height = 3120,
+ },
},
{
.width = 1048,
@@ -598,12 +635,21 @@ static const struct imx258_mode supported_modes[] = {
.regs = mode_1048_780_regs,
},
.link_freq_index = IMX258_LINK_FREQ_640MBPS,
+ .crop = {
+ .left = IMX258_PIXEL_ARRAY_LEFT,
+ .top = IMX258_PIXEL_ARRAY_TOP,
+ .width = 4208,
+ .height = 3120,
+ },
},
};
struct imx258 {
struct v4l2_subdev sd;
struct media_pad pad;
+ struct regmap *regmap;
+
+ const struct imx258_variant_cfg *variant_cfg;
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
@@ -612,10 +658,18 @@ struct imx258 {
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
/* Current mode */
const struct imx258_mode *cur_mode;
+ unsigned long link_freq_bitmap;
+ const struct imx258_link_freq_config *link_freq_configs;
+ const s64 *link_freq_menu_items;
+ unsigned int lane_mode_idx;
+ unsigned int csi2_flags;
+
/*
* Mutex for serialized access:
* Protect sensor module set pad format and start/stop streaming safely.
@@ -623,6 +677,7 @@ struct imx258 {
struct mutex mutex;
struct clk *clk;
+ struct regulator_bulk_data supplies[IMX258_NUM_SUPPLIES];
};
static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd)
@@ -630,120 +685,66 @@ static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd)
return container_of(_sd, struct imx258, sd);
}
-/* Read registers up to 2 at a time */
-static int imx258_read_reg(struct imx258 *imx258, u16 reg, u32 len, u32 *val)
+/* Get bayer order based on flip setting. */
+static u32 imx258_get_format_code(const struct imx258 *imx258)
{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
- struct i2c_msg msgs[2];
- u8 addr_buf[2] = { reg >> 8, reg & 0xff };
- u8 data_buf[4] = { 0, };
- int ret;
-
- if (len > 4)
- return -EINVAL;
-
- /* 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 2 at a time */
-static int imx258_write_reg(struct imx258 *imx258, u16 reg, u32 len, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->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 imx258_write_regs(struct imx258 *imx258,
- const struct imx258_reg *regs, u32 len)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
unsigned int i;
- int ret;
- for (i = 0; i < len; i++) {
- ret = imx258_write_reg(imx258, regs[i].address, 1,
- regs[i].val);
- if (ret) {
- dev_err_ratelimited(
- &client->dev,
- "Failed to write reg 0x%4.4x. error = %d\n",
- regs[i].address, ret);
+ lockdep_assert_held(&imx258->mutex);
- return ret;
- }
- }
+ i = (imx258->vflip->val ? 2 : 0) |
+ (imx258->hflip->val ? 1 : 0);
- return 0;
+ return codes[i];
}
/* Open sub-device */
static int imx258_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
+ struct imx258 *imx258 = to_imx258(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_state_get_format(fh->state, 0);
+ struct v4l2_rect *try_crop;
/* Initialize try_fmt */
try_fmt->width = supported_modes[0].width;
try_fmt->height = supported_modes[0].height;
- try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ try_fmt->code = imx258_get_format_code(imx258);
try_fmt->field = V4L2_FIELD_NONE;
+ /* Initialize try_crop */
+ try_crop = v4l2_subdev_state_get_crop(fh->state, 0);
+ try_crop->left = IMX258_PIXEL_ARRAY_LEFT;
+ try_crop->top = IMX258_PIXEL_ARRAY_TOP;
+ try_crop->width = IMX258_PIXEL_ARRAY_WIDTH;
+ try_crop->height = IMX258_PIXEL_ARRAY_HEIGHT;
+
return 0;
}
-static int imx258_update_digital_gain(struct imx258 *imx258, u32 len, u32 val)
+static int imx258_update_digital_gain(struct imx258 *imx258, u32 val)
{
- int ret;
+ int ret = 0;
- ret = imx258_write_reg(imx258, IMX258_REG_GR_DIGITAL_GAIN,
- IMX258_REG_VALUE_16BIT,
- val);
- if (ret)
- return ret;
- ret = imx258_write_reg(imx258, IMX258_REG_GB_DIGITAL_GAIN,
- IMX258_REG_VALUE_16BIT,
- val);
- if (ret)
- return ret;
- ret = imx258_write_reg(imx258, IMX258_REG_R_DIGITAL_GAIN,
- IMX258_REG_VALUE_16BIT,
- val);
- if (ret)
- return ret;
- ret = imx258_write_reg(imx258, IMX258_REG_B_DIGITAL_GAIN,
- IMX258_REG_VALUE_16BIT,
- val);
- if (ret)
- return ret;
- return 0;
+ cci_write(imx258->regmap, IMX258_REG_GR_DIGITAL_GAIN, val, &ret);
+ cci_write(imx258->regmap, IMX258_REG_GB_DIGITAL_GAIN, val, &ret);
+ cci_write(imx258->regmap, IMX258_REG_R_DIGITAL_GAIN, val, &ret);
+ cci_write(imx258->regmap, IMX258_REG_B_DIGITAL_GAIN, val, &ret);
+
+ return ret;
+}
+
+static void imx258_adjust_exposure_range(struct imx258 *imx258)
+{
+ int exposure_max, exposure_def;
+
+ /* Honour the VBLANK limits when setting exposure. */
+ exposure_max = imx258->cur_mode->height + imx258->vblank->val -
+ IMX258_EXPOSURE_OFFSET;
+ exposure_def = min(exposure_max, imx258->exposure->val);
+ __v4l2_ctrl_modify_range(imx258->exposure, imx258->exposure->minimum,
+ exposure_max, imx258->exposure->step,
+ exposure_def);
}
static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -754,6 +755,13 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
int ret = 0;
/*
+ * The VBLANK control may change the limits of usable exposure, so check
+ * and adjust if necessary.
+ */
+ if (ctrl->id == V4L2_CID_VBLANK)
+ imx258_adjust_exposure_range(imx258);
+
+ /*
* Applying V4L2 control value only happens
* when power is up for streaming
*/
@@ -762,44 +770,46 @@ static int imx258_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
- ret = imx258_write_reg(imx258, IMX258_REG_ANALOG_GAIN,
- IMX258_REG_VALUE_16BIT,
- ctrl->val);
+ ret = cci_write(imx258->regmap, IMX258_REG_ANALOG_GAIN,
+ ctrl->val, NULL);
break;
case V4L2_CID_EXPOSURE:
- ret = imx258_write_reg(imx258, IMX258_REG_EXPOSURE,
- IMX258_REG_VALUE_16BIT,
- ctrl->val);
+ ret = cci_write(imx258->regmap, IMX258_REG_EXPOSURE,
+ ctrl->val, NULL);
break;
case V4L2_CID_DIGITAL_GAIN:
- ret = imx258_update_digital_gain(imx258, IMX258_REG_VALUE_16BIT,
- ctrl->val);
+ ret = imx258_update_digital_gain(imx258, ctrl->val);
break;
case V4L2_CID_TEST_PATTERN:
- ret = imx258_write_reg(imx258, IMX258_REG_TEST_PATTERN,
- IMX258_REG_VALUE_16BIT,
- ctrl->val);
- ret = imx258_write_reg(imx258, REG_MIRROR_FLIP_CONTROL,
- IMX258_REG_VALUE_08BIT,
- !ctrl->val ? REG_CONFIG_MIRROR_FLIP :
- REG_CONFIG_FLIP_TEST_PATTERN);
+ ret = cci_write(imx258->regmap, IMX258_REG_TEST_PATTERN,
+ ctrl->val, NULL);
break;
case V4L2_CID_WIDE_DYNAMIC_RANGE:
if (!ctrl->val) {
- ret = imx258_write_reg(imx258, IMX258_REG_HDR,
- IMX258_REG_VALUE_08BIT,
- IMX258_HDR_RATIO_MIN);
+ ret = cci_write(imx258->regmap, IMX258_REG_HDR,
+ IMX258_HDR_RATIO_MIN, NULL);
} else {
- ret = imx258_write_reg(imx258, IMX258_REG_HDR,
- IMX258_REG_VALUE_08BIT,
- IMX258_HDR_ON);
+ ret = cci_write(imx258->regmap, IMX258_REG_HDR,
+ IMX258_HDR_ON, NULL);
if (ret)
break;
- ret = imx258_write_reg(imx258, IMX258_REG_HDR_RATIO,
- IMX258_REG_VALUE_08BIT,
- BIT(IMX258_HDR_RATIO_MAX));
+ ret = cci_write(imx258->regmap, IMX258_REG_HDR_RATIO,
+ BIT(IMX258_HDR_RATIO_MAX), NULL);
}
break;
+ case V4L2_CID_VBLANK:
+ ret = cci_write(imx258->regmap, IMX258_REG_FRM_LENGTH_LINES,
+ imx258->cur_mode->height + ctrl->val, NULL);
+ break;
+ case V4L2_CID_VFLIP:
+ case V4L2_CID_HFLIP:
+ ret = cci_write(imx258->regmap, REG_MIRROR_FLIP_CONTROL,
+ (imx258->hflip->val ?
+ REG_CONFIG_MIRROR_HFLIP : 0) |
+ (imx258->vflip->val ?
+ REG_CONFIG_MIRROR_VFLIP : 0),
+ NULL);
+ break;
default:
dev_info(&client->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
@@ -821,11 +831,13 @@ static int imx258_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{
- /* Only one bayer order(GRBG) is supported */
+ struct imx258 *imx258 = to_imx258(sd);
+
+ /* Only one bayer format (10 bit) is supported */
if (code->index > 0)
return -EINVAL;
- code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ code->code = imx258_get_format_code(imx258);
return 0;
}
@@ -834,10 +846,11 @@ static int imx258_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{
+ struct imx258 *imx258 = to_imx258(sd);
if (fse->index >= ARRAY_SIZE(supported_modes))
return -EINVAL;
- if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+ if (fse->code != imx258_get_format_code(imx258))
return -EINVAL;
fse->min_width = supported_modes[fse->index].width;
@@ -848,12 +861,13 @@ static int imx258_enum_frame_size(struct v4l2_subdev *sd,
return 0;
}
-static void imx258_update_pad_format(const struct imx258_mode *mode,
+static void imx258_update_pad_format(struct imx258 *imx258,
+ const struct imx258_mode *mode,
struct v4l2_subdev_format *fmt)
{
fmt->format.width = mode->width;
fmt->format.height = mode->height;
- fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ fmt->format.code = imx258_get_format_code(imx258);
fmt->format.field = V4L2_FIELD_NONE;
}
@@ -865,7 +879,7 @@ static int __imx258_get_pad_format(struct imx258 *imx258,
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
- imx258_update_pad_format(imx258->cur_mode, fmt);
+ imx258_update_pad_format(imx258, imx258->cur_mode, fmt);
return 0;
}
@@ -889,8 +903,10 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_format *fmt)
{
struct imx258 *imx258 = to_imx258(sd);
- const struct imx258_mode *mode;
+ const struct imx258_link_freq_config *link_freq_cfgs;
+ const struct imx258_link_cfg *link_cfg;
struct v4l2_mbus_framefmt *framefmt;
+ const struct imx258_mode *mode;
s32 vblank_def;
s32 vblank_min;
s64 h_blank;
@@ -899,13 +915,12 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
mutex_lock(&imx258->mutex);
- /* Only one raw bayer(GBRG) order is supported */
- fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
+ fmt->format.code = imx258_get_format_code(imx258);
mode = v4l2_find_nearest_size(supported_modes,
ARRAY_SIZE(supported_modes), width, height,
fmt->format.width, fmt->format.height);
- imx258_update_pad_format(mode, fmt);
+ imx258_update_pad_format(imx258, mode, fmt);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
*framefmt = fmt->format;
@@ -913,9 +928,14 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
imx258->cur_mode = mode;
__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
- link_freq = link_freq_menu_items[mode->link_freq_index];
- pixel_rate = link_freq_to_pixel_rate(link_freq);
- __v4l2_ctrl_s_ctrl_int64(imx258->pixel_rate, pixel_rate);
+ link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
+ link_freq_cfgs =
+ &imx258->link_freq_configs[mode->link_freq_index];
+
+ link_cfg = &link_freq_cfgs->link_cfg[imx258->lane_mode_idx];
+ pixel_rate = link_freq_to_pixel_rate(link_freq, link_cfg);
+ __v4l2_ctrl_modify_range(imx258->pixel_rate, pixel_rate,
+ pixel_rate, 1, pixel_rate);
/* Update limits and set FPS to default */
vblank_def = imx258->cur_mode->vts_def -
imx258->cur_mode->height;
@@ -927,7 +947,7 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
vblank_def);
__v4l2_ctrl_s_ctrl(imx258->vblank, vblank_def);
h_blank =
- link_freq_configs[mode->link_freq_index].pixels_per_line
+ imx258->link_freq_configs[mode->link_freq_index].pixels_per_line
- imx258->cur_mode->width;
__v4l2_ctrl_modify_range(imx258->hblank, h_blank,
h_blank, 1, h_blank);
@@ -938,48 +958,125 @@ static int imx258_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
+static const struct v4l2_rect *
+__imx258_get_pad_crop(struct imx258 *imx258,
+ struct v4l2_subdev_state *sd_state,
+ unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ return v4l2_subdev_state_get_crop(sd_state, pad);
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ return &imx258->cur_mode->crop;
+ }
+
+ return NULL;
+}
+
+static int imx258_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: {
+ struct imx258 *imx258 = to_imx258(sd);
+
+ mutex_lock(&imx258->mutex);
+ sel->r = *__imx258_get_pad_crop(imx258, sd_state, sel->pad,
+ sel->which);
+ mutex_unlock(&imx258->mutex);
+
+ return 0;
+ }
+
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.left = 0;
+ sel->r.top = 0;
+ sel->r.width = IMX258_NATIVE_WIDTH;
+ sel->r.height = IMX258_NATIVE_HEIGHT;
+
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.left = IMX258_PIXEL_ARRAY_LEFT;
+ sel->r.top = IMX258_PIXEL_ARRAY_TOP;
+ sel->r.width = IMX258_PIXEL_ARRAY_WIDTH;
+ sel->r.height = IMX258_PIXEL_ARRAY_HEIGHT;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
/* Start streaming */
static int imx258_start_streaming(struct imx258 *imx258)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
const struct imx258_reg_list *reg_list;
+ const struct imx258_link_freq_config *link_freq_cfg;
int ret, link_freq_index;
+ ret = cci_write(imx258->regmap, IMX258_REG_RESET, 0x01, NULL);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to reset sensor\n", __func__);
+ return ret;
+ }
+
+ /* 12ms is required from poweron to standby */
+ fsleep(12000);
+
/* Setup PLL */
link_freq_index = imx258->cur_mode->link_freq_index;
- reg_list = &link_freq_configs[link_freq_index].reg_list;
- ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
+ link_freq_cfg = &imx258->link_freq_configs[link_freq_index];
+
+ reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;
+ ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
if (ret) {
dev_err(&client->dev, "%s failed to set plls\n", __func__);
return ret;
}
- /* Apply default values of current mode */
- reg_list = &imx258->cur_mode->reg_list;
- ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
+ ret = cci_multi_reg_write(imx258->regmap, mode_common_regs,
+ ARRAY_SIZE(mode_common_regs), NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ dev_err(&client->dev, "%s failed to set common regs\n", __func__);
return ret;
}
- /* Set Orientation be 180 degree */
- ret = imx258_write_reg(imx258, REG_MIRROR_FLIP_CONTROL,
- IMX258_REG_VALUE_08BIT, REG_CONFIG_MIRROR_FLIP);
+ ret = cci_multi_reg_write(imx258->regmap, imx258->variant_cfg->regs,
+ imx258->variant_cfg->num_regs, NULL);
if (ret) {
- dev_err(&client->dev, "%s failed to set orientation\n",
+ dev_err(&client->dev, "%s failed to set variant config\n",
__func__);
return ret;
}
+ ret = cci_write(imx258->regmap, IMX258_CLK_BLANK_STOP,
+ !!(imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK),
+ NULL);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set clock lane mode\n", __func__);
+ return ret;
+ }
+
+ /* Apply default values of current mode */
+ reg_list = &imx258->cur_mode->reg_list;
+ ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set mode\n", __func__);
+ return ret;
+ }
+
/* Apply customized values from user */
ret = __v4l2_ctrl_handler_setup(imx258->sd.ctrl_handler);
if (ret)
return ret;
/* set stream on register */
- return imx258_write_reg(imx258, IMX258_REG_MODE_SELECT,
- IMX258_REG_VALUE_08BIT,
- IMX258_MODE_STREAMING);
+ return cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
+ IMX258_MODE_STREAMING, NULL);
}
/* Stop streaming */
@@ -989,8 +1086,8 @@ static int imx258_stop_streaming(struct imx258 *imx258)
int ret;
/* set stream off register */
- ret = imx258_write_reg(imx258, IMX258_REG_MODE_SELECT,
- IMX258_REG_VALUE_08BIT, IMX258_MODE_STANDBY);
+ ret = cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
+ IMX258_MODE_STANDBY, NULL);
if (ret)
dev_err(&client->dev, "%s failed to set stream\n", __func__);
@@ -1007,9 +1104,19 @@ static int imx258_power_on(struct device *dev)
struct imx258 *imx258 = to_imx258(sd);
int ret;
+ ret = regulator_bulk_enable(IMX258_NUM_SUPPLIES,
+ imx258->supplies);
+ if (ret) {
+ dev_err(dev, "%s: failed to enable regulators\n",
+ __func__);
+ return ret;
+ }
+
ret = clk_prepare_enable(imx258->clk);
- if (ret)
+ if (ret) {
dev_err(dev, "failed to enable clock\n");
+ regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
+ }
return ret;
}
@@ -1020,6 +1127,7 @@ static int imx258_power_off(struct device *dev)
struct imx258 *imx258 = to_imx258(sd);
clk_disable_unprepare(imx258->clk);
+ regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
return 0;
}
@@ -1066,10 +1174,10 @@ static int imx258_identify_module(struct imx258 *imx258)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
int ret;
- u32 val;
+ u64 val;
- ret = imx258_read_reg(imx258, IMX258_REG_CHIP_ID,
- IMX258_REG_VALUE_16BIT, &val);
+ ret = cci_read(imx258->regmap, IMX258_REG_CHIP_ID,
+ &val, NULL);
if (ret) {
dev_err(&client->dev, "failed to read chip id %x\n",
IMX258_CHIP_ID);
@@ -1077,7 +1185,7 @@ static int imx258_identify_module(struct imx258 *imx258)
}
if (val != IMX258_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ dev_err(&client->dev, "chip id mismatch: %x!=%llx\n",
IMX258_CHIP_ID, val);
return -EIO;
}
@@ -1094,6 +1202,7 @@ static const struct v4l2_subdev_pad_ops imx258_pad_ops = {
.get_fmt = imx258_get_pad_format,
.set_fmt = imx258_set_pad_format,
.enum_frame_size = imx258_enum_frame_size,
+ .get_selection = imx258_get_selection,
};
static const struct v4l2_subdev_ops imx258_subdev_ops = {
@@ -1109,13 +1218,13 @@ static const struct v4l2_subdev_internal_ops imx258_internal_ops = {
static int imx258_init_controls(struct imx258 *imx258)
{
struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
+ const struct imx258_link_freq_config *link_freq_cfgs;
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl_handler *ctrl_hdlr;
- struct v4l2_ctrl *vflip, *hflip;
+ const struct imx258_link_cfg *link_cfg;
s64 vblank_def;
s64 vblank_min;
- s64 pixel_rate_min;
- s64 pixel_rate_max;
+ s64 pixel_rate;
int ret;
ctrl_hdlr = &imx258->ctrl_handler;
@@ -1128,32 +1237,33 @@ static int imx258_init_controls(struct imx258 *imx258)
imx258->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx258_ctrl_ops,
V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(link_freq_menu_items) - 1,
+ ARRAY_SIZE(link_freq_menu_items_19_2) - 1,
0,
- link_freq_menu_items);
+ imx258->link_freq_menu_items);
if (imx258->link_freq)
imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- /* The driver only supports one bayer order and flips by default. */
- hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
- V4L2_CID_HFLIP, 1, 1, 1, 1);
- if (hflip)
- hflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ imx258->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 1);
+ if (imx258->hflip)
+ imx258->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+ imx258->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 1);
+ if (imx258->vflip)
+ imx258->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
- vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
- V4L2_CID_VFLIP, 1, 1, 1, 1);
- if (vflip)
- vflip->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ link_freq_cfgs = &imx258->link_freq_configs[0];
+ link_cfg = link_freq_cfgs[imx258->lane_mode_idx].link_cfg;
+ pixel_rate = link_freq_to_pixel_rate(imx258->link_freq_menu_items[0],
+ link_cfg);
- pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
- pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
/* By default, PIXEL_RATE is read only */
imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
V4L2_CID_PIXEL_RATE,
- pixel_rate_min, pixel_rate_max,
- 1, pixel_rate_max);
-
+ pixel_rate, pixel_rate,
+ 1, pixel_rate);
vblank_def = imx258->cur_mode->vts_def - imx258->cur_mode->height;
vblank_min = imx258->cur_mode->vts_min - imx258->cur_mode->height;
@@ -1163,9 +1273,6 @@ static int imx258_init_controls(struct imx258 *imx258)
IMX258_VTS_MAX - imx258->cur_mode->height, 1,
vblank_def);
- if (imx258->vblank)
- imx258->vblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
imx258->hblank = v4l2_ctrl_new_std(
ctrl_hdlr, &imx258_ctrl_ops, V4L2_CID_HBLANK,
IMX258_PPL_DEFAULT - imx258->cur_mode->width,
@@ -1232,9 +1339,25 @@ static void imx258_free_controls(struct imx258 *imx258)
mutex_destroy(&imx258->mutex);
}
+static int imx258_get_regulators(struct imx258 *imx258,
+ struct i2c_client *client)
+{
+ unsigned int i;
+
+ for (i = 0; i < IMX258_NUM_SUPPLIES; i++)
+ imx258->supplies[i].supply = imx258_supply_name[i];
+
+ return devm_regulator_bulk_get(&client->dev,
+ IMX258_NUM_SUPPLIES, imx258->supplies);
+}
+
static int imx258_probe(struct i2c_client *client)
{
struct imx258 *imx258;
+ struct fwnode_handle *endpoint;
+ struct v4l2_fwnode_endpoint ep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
int ret;
u32 val = 0;
@@ -1242,6 +1365,18 @@ static int imx258_probe(struct i2c_client *client)
if (!imx258)
return -ENOMEM;
+ imx258->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx258->regmap)) {
+ ret = PTR_ERR(imx258->regmap);
+ dev_err(&client->dev, "failed to initialize CCI: %d\n", ret);
+ return ret;
+ }
+
+ ret = imx258_get_regulators(imx258, client);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "failed to get regulators\n");
+
imx258->clk = devm_clk_get_optional(&client->dev, NULL);
if (IS_ERR(imx258->clk))
return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
@@ -1254,18 +1389,74 @@ static int imx258_probe(struct i2c_client *client)
} else {
val = clk_get_rate(imx258->clk);
}
- if (val != IMX258_INPUT_CLOCK_FREQ) {
- dev_err(&client->dev, "input clock frequency not supported\n");
+
+ switch (val) {
+ case 19200000:
+ imx258->link_freq_configs = link_freq_configs_19_2;
+ imx258->link_freq_menu_items = link_freq_menu_items_19_2;
+ break;
+ case 24000000:
+ imx258->link_freq_configs = link_freq_configs_24;
+ imx258->link_freq_menu_items = link_freq_menu_items_24;
+ break;
+ default:
+ dev_err(&client->dev, "input clock frequency of %u not supported\n",
+ val);
return -EINVAL;
}
+ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL);
+ if (!endpoint) {
+ dev_err(&client->dev, "Endpoint node not found\n");
+ return -EINVAL;
+ }
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &ep);
+ fwnode_handle_put(endpoint);
+ if (ret) {
+ dev_err(&client->dev, "Parsing endpoint node failed\n");
+ return ret;
+ }
+
+ ret = v4l2_link_freq_to_bitmap(&client->dev,
+ ep.link_frequencies,
+ ep.nr_of_link_frequencies,
+ imx258->link_freq_menu_items,
+ ARRAY_SIZE(link_freq_menu_items_19_2),
+ &imx258->link_freq_bitmap);
+ if (ret) {
+ dev_err(&client->dev, "Link frequency not supported\n");
+ goto error_endpoint_free;
+ }
+
+ /* Get number of data lanes */
+ switch (ep.bus.mipi_csi2.num_data_lanes) {
+ case 2:
+ imx258->lane_mode_idx = IMX258_2_LANE_MODE;
+ break;
+ case 4:
+ imx258->lane_mode_idx = IMX258_4_LANE_MODE;
+ break;
+ default:
+ dev_err(&client->dev, "Invalid data lanes: %u\n",
+ ep.bus.mipi_csi2.num_data_lanes);
+ ret = -EINVAL;
+ goto error_endpoint_free;
+ }
+
+ imx258->csi2_flags = ep.bus.mipi_csi2.flags;
+
+ imx258->variant_cfg = device_get_match_data(&client->dev);
+ if (!imx258->variant_cfg)
+ imx258->variant_cfg = &imx258_cfg;
+
/* Initialize subdev */
v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
/* Will be powered off via pm_runtime_idle */
ret = imx258_power_on(&client->dev);
if (ret)
- return ret;
+ goto error_endpoint_free;
/* Check module identity */
ret = imx258_identify_module(imx258);
@@ -1298,6 +1489,7 @@ static int imx258_probe(struct i2c_client *client)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
pm_runtime_idle(&client->dev);
+ v4l2_fwnode_endpoint_free(&ep);
return 0;
@@ -1310,6 +1502,9 @@ error_handler_free:
error_identify:
imx258_power_off(&client->dev);
+error_endpoint_free:
+ v4l2_fwnode_endpoint_free(&ep);
+
return ret;
}
@@ -1342,7 +1537,8 @@ MODULE_DEVICE_TABLE(acpi, imx258_acpi_ids);
#endif
static const struct of_device_id imx258_dt_ids[] = {
- { .compatible = "sony,imx258" },
+ { .compatible = "sony,imx258", .data = &imx258_cfg },
+ { .compatible = "sony,imx258-pdaf", .data = &imx258_pdaf_cfg },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx258_dt_ids);
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
new file mode 100644
index 000000000000..6428eb5394a9
--- /dev/null
+++ b/drivers/media/i2c/imx283.c
@@ -0,0 +1,1605 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * V4L2 Support for the IMX283
+ *
+ * Diagonal 15.86 mm (Type 1) CMOS Image Sensor with Square Pixel for Color
+ * Cameras.
+ *
+ * Copyright (C) 2024 Ideas on Board Oy.
+ *
+ * Based on Sony IMX283 driver prepared by Will Whang
+ *
+ * Based on Sony imx477 camera driver
+ * Copyright (C) 2019-2020 Raspberry Pi (Trading) Ltd
+ */
+
+#include <linux/array_size.h>
+#include <linux/bitops.h>
+#include <linux/container_of.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/minmax.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/units.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>
+#include <media/v4l2-mediabus.h>
+
+/* Chip ID */
+#define IMX283_REG_CHIP_ID CCI_REG8(0x3000)
+#define IMX283_CHIP_ID 0x0b // Default power on state
+
+#define IMX283_REG_STANDBY CCI_REG8(0x3000)
+#define IMX283_ACTIVE 0
+#define IMX283_STANDBY BIT(0)
+#define IMX283_STBLOGIC BIT(1)
+#define IMX283_STBMIPI BIT(2)
+#define IMX283_STBDV BIT(3)
+#define IMX283_SLEEP BIT(4)
+
+#define IMX283_REG_CLAMP CCI_REG8(0x3001)
+#define IMX283_CLPSQRST BIT(4)
+
+#define IMX283_REG_PLSTMG08 CCI_REG8(0x3003)
+#define IMX283_PLSTMG08_VAL 0x77
+
+#define IMX283_REG_MDSEL1 CCI_REG8(0x3004)
+#define IMX283_REG_MDSEL2 CCI_REG8(0x3005)
+#define IMX283_REG_MDSEL3 CCI_REG8(0x3006)
+#define IMX283_MDSEL3_VCROP_EN BIT(5)
+#define IMX283_REG_MDSEL4 CCI_REG8(0x3007)
+#define IMX283_MDSEL4_VCROP_EN (BIT(4) | BIT(6))
+
+#define IMX283_REG_SVR CCI_REG16_LE(0x3009)
+
+#define IMX283_REG_HTRIMMING CCI_REG8(0x300b)
+#define IMX283_MDVREV BIT(0) /* VFLIP */
+#define IMX283_HTRIMMING_EN BIT(4)
+
+#define IMX283_REG_VWINPOS CCI_REG16_LE(0x300f)
+#define IMX283_REG_VWIDCUT CCI_REG16_LE(0x3011)
+
+#define IMX283_REG_MDSEL7 CCI_REG16_LE(0x3013)
+
+/* CSI Clock Configuration */
+#define IMX283_REG_TCLKPOST CCI_REG8(0x3018)
+#define IMX283_REG_THSPREPARE CCI_REG8(0x301a)
+#define IMX283_REG_THSZERO CCI_REG8(0x301c)
+#define IMX283_REG_THSTRAIL CCI_REG8(0x301e)
+#define IMX283_REG_TCLKTRAIL CCI_REG8(0x3020)
+#define IMX283_REG_TCLKPREPARE CCI_REG8(0x3022)
+#define IMX283_REG_TCLKZERO CCI_REG16_LE(0x3024)
+#define IMX283_REG_TLPX CCI_REG8(0x3026)
+#define IMX283_REG_THSEXIT CCI_REG8(0x3028)
+#define IMX283_REG_TCLKPRE CCI_REG8(0x302a)
+#define IMX283_REG_SYSMODE CCI_REG8(0x3104)
+
+#define IMX283_REG_Y_OUT_SIZE CCI_REG16_LE(0x302f)
+#define IMX283_REG_WRITE_VSIZE CCI_REG16_LE(0x3031)
+#define IMX283_REG_OB_SIZE_V CCI_REG8(0x3033)
+
+/* HMAX internal HBLANK */
+#define IMX283_REG_HMAX CCI_REG16_LE(0x3036)
+#define IMX283_HMAX_MAX (BIT(16) - 1)
+
+/* VMAX internal VBLANK */
+#define IMX283_REG_VMAX CCI_REG24_LE(0x3038)
+#define IMX283_VMAX_MAX (BIT(16) - 1)
+
+/* SHR internal */
+#define IMX283_REG_SHR CCI_REG16_LE(0x303b)
+#define IMX283_SHR_MIN 11
+
+/*
+ * Analog gain control
+ * Gain [dB] = -20log{(2048 - value [10:0]) /2048}
+ * Range: 0dB to approximately +27dB
+ */
+#define IMX283_REG_ANALOG_GAIN CCI_REG16_LE(0x3042)
+#define IMX283_ANA_GAIN_MIN 0
+#define IMX283_ANA_GAIN_MAX 1957
+#define IMX283_ANA_GAIN_STEP 1
+#define IMX283_ANA_GAIN_DEFAULT 0x0
+
+/*
+ * Digital gain control
+ * Gain [dB] = value * 6
+ * Range: 0dB to +18db
+ */
+#define IMX283_REG_DIGITAL_GAIN CCI_REG8(0x3044)
+#define IMX283_DGTL_GAIN_MIN 0
+#define IMX283_DGTL_GAIN_MAX 3
+#define IMX283_DGTL_GAIN_DEFAULT 0
+#define IMX283_DGTL_GAIN_STEP 1
+
+#define IMX283_REG_HTRIMMING_START CCI_REG16_LE(0x3058)
+#define IMX283_REG_HTRIMMING_END CCI_REG16_LE(0x305a)
+
+#define IMX283_REG_MDSEL18 CCI_REG16_LE(0x30f6)
+
+/* Master Mode Operation Control */
+#define IMX283_REG_XMSTA CCI_REG8(0x3105)
+#define IMX283_XMSTA BIT(0)
+
+#define IMX283_REG_SYNCDRV CCI_REG8(0x3107)
+#define IMX283_SYNCDRV_XHS_XVS (0xa0 | 0x02)
+#define IMX283_SYNCDRV_HIZ (0xa0 | 0x03)
+
+/* PLL Standby */
+#define IMX283_REG_STBPL CCI_REG8(0x320b)
+#define IMX283_STBPL_NORMAL 0x00
+#define IMX283_STBPL_STANDBY 0x03
+
+/* Input Frequency Setting */
+#define IMX283_REG_PLRD1 CCI_REG8(0x36c1)
+#define IMX283_REG_PLRD2 CCI_REG16_LE(0x36c2)
+#define IMX283_REG_PLRD3 CCI_REG8(0x36f7)
+#define IMX283_REG_PLRD4 CCI_REG8(0x36f8)
+
+#define IMX283_REG_PLSTMG02 CCI_REG8(0x36aa)
+#define IMX283_PLSTMG02_VAL 0x00
+
+#define IMX283_REG_EBD_X_OUT_SIZE CCI_REG16_LE(0x3a54)
+
+/* Test pattern generator */
+#define IMX283_REG_TPG_CTRL CCI_REG8(0x3156)
+#define IMX283_TPG_CTRL_CLKEN BIT(0)
+#define IMX283_TPG_CTRL_PATEN BIT(4)
+
+#define IMX283_REG_TPG_PAT CCI_REG8(0x3157)
+#define IMX283_TPG_PAT_ALL_000 0x00
+#define IMX283_TPG_PAT_ALL_FFF 0x01
+#define IMX283_TPG_PAT_ALL_555 0x02
+#define IMX283_TPG_PAT_ALL_AAA 0x03
+#define IMX283_TPG_PAT_H_COLOR_BARS 0x0a
+#define IMX283_TPG_PAT_V_COLOR_BARS 0x0b
+
+/* Exposure control */
+#define IMX283_EXPOSURE_MIN 52
+#define IMX283_EXPOSURE_STEP 1
+#define IMX283_EXPOSURE_DEFAULT 1000
+#define IMX283_EXPOSURE_MAX 49865
+
+#define IMAGE_PAD 0
+
+#define IMX283_XCLR_MIN_DELAY_US (1 * USEC_PER_MSEC)
+#define IMX283_XCLR_DELAY_RANGE_US (1 * USEC_PER_MSEC)
+
+/* IMX283 native and active pixel array size. */
+static const struct v4l2_rect imx283_native_area = {
+ .top = 0,
+ .left = 0,
+ .width = 5592,
+ .height = 3710,
+};
+
+static const struct v4l2_rect imx283_active_area = {
+ .top = 40,
+ .left = 108,
+ .width = 5472,
+ .height = 3648,
+};
+
+struct imx283_reg_list {
+ unsigned int num_of_regs;
+ const struct cci_reg_sequence *regs;
+};
+
+/* Mode : resolution and related config values */
+struct imx283_mode {
+ unsigned int mode;
+
+ /* Bits per pixel */
+ unsigned int bpp;
+
+ /* Frame width */
+ unsigned int width;
+
+ /* Frame height */
+ unsigned int height;
+
+ /*
+ * Minimum horizontal timing in pixel-units
+ *
+ * Note that HMAX is written in 72MHz units, and the datasheet assumes a
+ * 720MHz link frequency. Convert datasheet values with the following:
+ *
+ * For 12 bpp modes (480Mbps) convert with:
+ * hmax = [hmax in 72MHz units] * 480 / 72
+ *
+ * For 10 bpp modes (576Mbps) convert with:
+ * hmax = [hmax in 72MHz units] * 576 / 72
+ */
+ u32 min_hmax;
+
+ /* minimum V-timing in lines */
+ u32 min_vmax;
+
+ /* default H-timing */
+ u32 default_hmax;
+
+ /* default V-timing */
+ u32 default_vmax;
+
+ /* minimum SHR */
+ u32 min_shr;
+
+ /*
+ * Per-mode vertical crop constants used to calculate values
+ * of IMX283REG_WIDCUT and IMX283_REG_VWINPOS.
+ */
+ u32 veff;
+ u32 vst;
+ u32 vct;
+
+ /* Horizontal and vertical binning ratio */
+ u8 hbin_ratio;
+ u8 vbin_ratio;
+
+ /* Optical Blanking */
+ u32 horizontal_ob;
+ u32 vertical_ob;
+
+ /* Analog crop rectangle. */
+ struct v4l2_rect crop;
+};
+
+struct imx283_input_frequency {
+ unsigned int mhz;
+ unsigned int reg_count;
+ struct cci_reg_sequence regs[4];
+};
+
+static const struct imx283_input_frequency imx283_frequencies[] = {
+ {
+ .mhz = 6 * HZ_PER_MHZ,
+ .reg_count = 4,
+ .regs = {
+ { IMX283_REG_PLRD1, 0x00 },
+ { IMX283_REG_PLRD2, 0x00f0 },
+ { IMX283_REG_PLRD3, 0x00 },
+ { IMX283_REG_PLRD4, 0xc0 },
+ },
+ },
+ {
+ .mhz = 12 * HZ_PER_MHZ,
+ .reg_count = 4,
+ .regs = {
+ { IMX283_REG_PLRD1, 0x01 },
+ { IMX283_REG_PLRD2, 0x00f0 },
+ { IMX283_REG_PLRD3, 0x01 },
+ { IMX283_REG_PLRD4, 0xc0 },
+ },
+ },
+ {
+ .mhz = 18 * HZ_PER_MHZ,
+ .reg_count = 4,
+ .regs = {
+ { IMX283_REG_PLRD1, 0x01 },
+ { IMX283_REG_PLRD2, 0x00a0 },
+ { IMX283_REG_PLRD3, 0x01 },
+ { IMX283_REG_PLRD4, 0x80 },
+ },
+ },
+ {
+ .mhz = 24 * HZ_PER_MHZ,
+ .reg_count = 4,
+ .regs = {
+ { IMX283_REG_PLRD1, 0x02 },
+ { IMX283_REG_PLRD2, 0x00f0 },
+ { IMX283_REG_PLRD3, 0x02 },
+ { IMX283_REG_PLRD4, 0xc0 },
+ },
+ },
+};
+
+enum imx283_modes {
+ IMX283_MODE_0,
+ IMX283_MODE_1,
+ IMX283_MODE_1A,
+ IMX283_MODE_1S,
+ IMX283_MODE_2,
+ IMX283_MODE_2A,
+ IMX283_MODE_3,
+ IMX283_MODE_4,
+ IMX283_MODE_5,
+ IMX283_MODE_6,
+};
+
+struct imx283_readout_mode {
+ u8 mdsel1;
+ u8 mdsel2;
+ u8 mdsel3;
+ u8 mdsel4;
+};
+
+static const struct imx283_readout_mode imx283_readout_modes[] = {
+ /* All pixel scan modes */
+ [IMX283_MODE_0] = { 0x04, 0x03, 0x10, 0x00 }, /* 12 bit */
+ [IMX283_MODE_1] = { 0x04, 0x01, 0x00, 0x00 }, /* 10 bit */
+ [IMX283_MODE_1A] = { 0x04, 0x01, 0x20, 0x50 }, /* 10 bit */
+ [IMX283_MODE_1S] = { 0x04, 0x41, 0x20, 0x50 }, /* 10 bit */
+
+ /* Horizontal / Vertical 2/2-line binning */
+ [IMX283_MODE_2] = { 0x0d, 0x11, 0x50, 0x00 }, /* 12 bit */
+ [IMX283_MODE_2A] = { 0x0d, 0x11, 0x70, 0x50 }, /* 12 bit */
+
+ /* Horizontal / Vertical 3/3-line binning */
+ [IMX283_MODE_3] = { 0x1e, 0x18, 0x10, 0x00 }, /* 12 bit */
+
+ /* Vertical 2/9 subsampling, horizontal 3 binning cropping */
+ [IMX283_MODE_4] = { 0x29, 0x18, 0x30, 0x50 }, /* 12 bit */
+
+ /* Vertical 2/19 subsampling binning, horizontal 3 binning */
+ [IMX283_MODE_5] = { 0x2d, 0x18, 0x10, 0x00 }, /* 12 bit */
+
+ /* Vertical 2 binning horizontal 2/4, subsampling 16:9 cropping */
+ [IMX283_MODE_6] = { 0x18, 0x21, 0x00, 0x09 }, /* 10 bit */
+
+ /*
+ * New modes should make sure the offset period is complied.
+ * See imx283_exposure() for reference.
+ */
+};
+
+static const struct cci_reg_sequence mipi_data_rate_1440Mbps[] = {
+ /* The default register settings provide the 1440Mbps rate */
+ { CCI_REG8(0x36c5), 0x00 }, /* Undocumented */
+ { CCI_REG8(0x3ac4), 0x00 }, /* Undocumented */
+
+ { IMX283_REG_STBPL, 0x00 },
+ { IMX283_REG_TCLKPOST, 0xa7 },
+ { IMX283_REG_THSPREPARE, 0x6f },
+ { IMX283_REG_THSZERO, 0x9f },
+ { IMX283_REG_THSTRAIL, 0x5f },
+ { IMX283_REG_TCLKTRAIL, 0x5f },
+ { IMX283_REG_TCLKPREPARE, 0x6f },
+ { IMX283_REG_TCLKZERO, 0x017f },
+ { IMX283_REG_TLPX, 0x4f },
+ { IMX283_REG_THSEXIT, 0x47 },
+ { IMX283_REG_TCLKPRE, 0x07 },
+ { IMX283_REG_SYSMODE, 0x02 },
+};
+
+static const struct cci_reg_sequence mipi_data_rate_720Mbps[] = {
+ /* Undocumented Additions "For 720MBps" Setting */
+ { CCI_REG8(0x36c5), 0x01 }, /* Undocumented */
+ { CCI_REG8(0x3ac4), 0x01 }, /* Undocumented */
+
+ { IMX283_REG_STBPL, 0x00 },
+ { IMX283_REG_TCLKPOST, 0x77 },
+ { IMX283_REG_THSPREPARE, 0x37 },
+ { IMX283_REG_THSZERO, 0x67 },
+ { IMX283_REG_THSTRAIL, 0x37 },
+ { IMX283_REG_TCLKTRAIL, 0x37 },
+ { IMX283_REG_TCLKPREPARE, 0x37 },
+ { IMX283_REG_TCLKZERO, 0xdf },
+ { IMX283_REG_TLPX, 0x2f },
+ { IMX283_REG_THSEXIT, 0x47 },
+ { IMX283_REG_TCLKPRE, 0x0f },
+ { IMX283_REG_SYSMODE, 0x02 },
+};
+
+static const s64 link_frequencies[] = {
+ 720 * HZ_PER_MHZ, /* 1440 Mbps lane data rate */
+ 360 * HZ_PER_MHZ, /* 720 Mbps data lane rate */
+};
+
+static const struct imx283_reg_list link_freq_reglist[] = {
+ { /* 720 MHz */
+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_1440Mbps),
+ .regs = mipi_data_rate_1440Mbps,
+ },
+ { /* 360 MHz */
+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_720Mbps),
+ .regs = mipi_data_rate_720Mbps,
+ },
+};
+
+#define CENTERED_RECTANGLE(rect, _width, _height) \
+ { \
+ .left = rect.left + ((rect.width - (_width)) / 2), \
+ .top = rect.top + ((rect.height - (_height)) / 2), \
+ .width = (_width), \
+ .height = (_height), \
+ }
+
+/* Mode configs */
+static const struct imx283_mode supported_modes_12bit[] = {
+ {
+ /* 20MPix 21.40 fps readout mode 0 */
+ .mode = IMX283_MODE_0,
+ .bpp = 12,
+ .width = 5472,
+ .height = 3648,
+ .min_hmax = 5914, /* 887 @ 480MHz/72MHz */
+ .min_vmax = 3793, /* Lines */
+
+ .veff = 3694,
+ .vst = 0,
+ .vct = 0,
+
+ .hbin_ratio = 1,
+ .vbin_ratio = 1,
+
+ /* 20.00 FPS */
+ .default_hmax = 6000, /* 900 @ 480MHz/72MHz */
+ .default_vmax = 4000,
+
+ .min_shr = 11,
+ .horizontal_ob = 96,
+ .vertical_ob = 16,
+ .crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+ },
+ {
+ /*
+ * Readout mode 2 : 2/2 binned mode (2736x1824)
+ */
+ .mode = IMX283_MODE_2,
+ .bpp = 12,
+ .width = 2736,
+ .height = 1824,
+ .min_hmax = 2414, /* Pixels (362 * 480MHz/72MHz + padding) */
+ .min_vmax = 3840, /* Lines */
+
+ /* 50.00 FPS */
+ .default_hmax = 2500, /* 375 @ 480MHz/72Mhz */
+ .default_vmax = 3840,
+
+ .veff = 1824,
+ .vst = 0,
+ .vct = 0,
+
+ .hbin_ratio = 2,
+ .vbin_ratio = 2,
+
+ .min_shr = 12,
+ .horizontal_ob = 48,
+ .vertical_ob = 4,
+
+ .crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+ },
+};
+
+static const struct imx283_mode supported_modes_10bit[] = {
+ {
+ /* 20MPix 25.48 fps readout mode 1 */
+ .mode = IMX283_MODE_1,
+ .bpp = 10,
+ .width = 5472,
+ .height = 3648,
+ .min_hmax = 5960, /* 745 @ 576MHz / 72MHz */
+ .min_vmax = 3793,
+
+ /* 25.00 FPS */
+ .default_hmax = 6000, /* 750 @ 576MHz / 72MHz */
+ .default_vmax = 3840,
+
+ .min_shr = 10,
+ .horizontal_ob = 96,
+ .vertical_ob = 16,
+ .crop = CENTERED_RECTANGLE(imx283_active_area, 5472, 3648),
+ },
+};
+
+static const u32 imx283_mbus_codes[] = {
+ MEDIA_BUS_FMT_SRGGB12_1X12,
+ MEDIA_BUS_FMT_SRGGB10_1X10,
+};
+
+/* regulator supplies */
+static const char *const imx283_supply_name[] = {
+ "vadd", /* Analog (2.9V) supply */
+ "vdd1", /* Supply Voltage 2 (1.8V) supply */
+ "vdd2", /* Supply Voltage 3 (1.2V) supply */
+};
+
+struct imx283 {
+ struct device *dev;
+ struct regmap *cci;
+
+ const struct imx283_input_frequency *freq;
+
+ struct v4l2_subdev sd;
+ struct media_pad pad;
+
+ struct clk *xclk;
+
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(imx283_supply_name)];
+
+ /* V4L2 Controls */
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vflip;
+
+ unsigned long link_freq_bitmap;
+
+ u16 hmax;
+ u32 vmax;
+};
+
+static inline struct imx283 *to_imx283(struct v4l2_subdev *sd)
+{
+ return container_of_const(sd, struct imx283, sd);
+}
+
+static inline void get_mode_table(unsigned int code,
+ const struct imx283_mode **mode_list,
+ unsigned int *num_modes)
+{
+ switch (code) {
+ case MEDIA_BUS_FMT_SRGGB12_1X12:
+ case MEDIA_BUS_FMT_SGRBG12_1X12:
+ case MEDIA_BUS_FMT_SGBRG12_1X12:
+ case MEDIA_BUS_FMT_SBGGR12_1X12:
+ *mode_list = supported_modes_12bit;
+ *num_modes = ARRAY_SIZE(supported_modes_12bit);
+ break;
+
+ case MEDIA_BUS_FMT_SRGGB10_1X10:
+ case MEDIA_BUS_FMT_SGRBG10_1X10:
+ case MEDIA_BUS_FMT_SGBRG10_1X10:
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
+ *mode_list = supported_modes_10bit;
+ *num_modes = ARRAY_SIZE(supported_modes_10bit);
+ break;
+ default:
+ *mode_list = NULL;
+ *num_modes = 0;
+ break;
+ }
+}
+
+/* Calculate the Pixel Rate based on the current mode */
+static u64 imx283_pixel_rate(struct imx283 *imx283,
+ const struct imx283_mode *mode)
+{
+ u64 link_frequency = link_frequencies[__ffs(imx283->link_freq_bitmap)];
+ unsigned int bpp = mode->bpp;
+ const unsigned int ddr = 2; /* Double Data Rate */
+ const unsigned int lanes = 4; /* Only 4 lane support */
+ u64 numerator = link_frequency * ddr * lanes;
+
+ do_div(numerator, bpp);
+
+ return numerator;
+}
+
+/* Convert from a variable pixel_rate to 72 MHz clock cycles */
+static u64 imx283_internal_clock(unsigned int pixel_rate, unsigned int pixels)
+{
+ /*
+ * Determine the following operation without overflow:
+ * pixels = 72 Mhz / pixel_rate
+ *
+ * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
+ * can easily overflow this calculation, so pre-divide to simplify.
+ */
+ const u32 iclk_pre = 72;
+ const u32 pclk_pre = pixel_rate / HZ_PER_MHZ;
+ u64 numerator = pixels * iclk_pre;
+
+ do_div(numerator, pclk_pre);
+
+ return numerator;
+}
+
+/* Internal clock (72MHz) to Pixel Rate clock (Variable) */
+static u64 imx283_iclk_to_pix(unsigned int pixel_rate, unsigned int cycles)
+{
+ /*
+ * Determine the following operation without overflow:
+ * cycles * pixel_rate / 72 MHz
+ *
+ * The internal clock at 72MHz and Pixel Rate (between 240 and 576MHz)
+ * can easily overflow this calculation, so pre-divide to simplify.
+ */
+ const u32 iclk_pre = 72;
+ const u32 pclk_pre = pixel_rate / HZ_PER_MHZ;
+ u64 numerator = cycles * pclk_pre;
+
+ do_div(numerator, iclk_pre);
+
+ return numerator;
+}
+
+/* Determine the exposure based on current hmax, vmax and a given SHR */
+static u32 imx283_exposure(struct imx283 *imx283,
+ const struct imx283_mode *mode, u64 shr)
+{
+ u32 svr = 0; /* SVR feature is not currently supported */
+ u32 offset;
+ u64 numerator;
+
+ /* Number of clocks per internal offset period */
+ offset = mode->mode == IMX283_MODE_0 ? 209 : 157;
+ numerator = (imx283->vmax * (svr + 1) - shr) * imx283->hmax + offset;
+
+ do_div(numerator, imx283->hmax);
+
+ return clamp(numerator, 0, U32_MAX);
+}
+
+static void imx283_exposure_limits(struct imx283 *imx283,
+ const struct imx283_mode *mode,
+ s64 *min_exposure, s64 *max_exposure)
+{
+ u32 svr = 0; /* SVR feature is not currently supported */
+ u64 min_shr = mode->min_shr;
+ /* Global Shutter is not supported */
+ u64 max_shr = (svr + 1) * imx283->vmax - 4;
+
+ max_shr = min(max_shr, BIT(16) - 1);
+
+ *min_exposure = imx283_exposure(imx283, mode, max_shr);
+ *max_exposure = imx283_exposure(imx283, mode, min_shr);
+}
+
+/*
+ * Integration Time [s] = [ {VMAX x (SVR + 1) – (SHR)} x HMAX + offset ]
+ * / [ 72 x 10^6 ]
+ */
+static u32 imx283_shr(struct imx283 *imx283, const struct imx283_mode *mode,
+ u32 exposure)
+{
+ u32 svr = 0; /* SVR feature is not currently supported */
+ u32 offset;
+ u64 temp;
+
+ /* Number of clocks per internal offset period */
+ offset = mode->mode == IMX283_MODE_0 ? 209 : 157;
+ temp = ((u64)exposure * imx283->hmax - offset);
+ do_div(temp, imx283->hmax);
+
+ return (imx283->vmax * (svr + 1) - temp);
+}
+
+static const char * const imx283_tpg_menu[] = {
+ "Disabled",
+ "All 000h",
+ "All FFFh",
+ "All 555h",
+ "All AAAh",
+ "Horizontal color bars",
+ "Vertical color bars",
+};
+
+static const int imx283_tpg_val[] = {
+ IMX283_TPG_PAT_ALL_000,
+ IMX283_TPG_PAT_ALL_000,
+ IMX283_TPG_PAT_ALL_FFF,
+ IMX283_TPG_PAT_ALL_555,
+ IMX283_TPG_PAT_ALL_AAA,
+ IMX283_TPG_PAT_H_COLOR_BARS,
+ IMX283_TPG_PAT_V_COLOR_BARS,
+};
+
+static int imx283_update_test_pattern(struct imx283 *imx283, u32 pattern_index)
+{
+ int ret;
+
+ if (pattern_index >= ARRAY_SIZE(imx283_tpg_val))
+ return -EINVAL;
+
+ if (!pattern_index)
+ return cci_write(imx283->cci, IMX283_REG_TPG_CTRL, 0x00, NULL);
+
+ ret = cci_write(imx283->cci, IMX283_REG_TPG_PAT,
+ imx283_tpg_val[pattern_index], NULL);
+ if (ret)
+ return ret;
+
+ return cci_write(imx283->cci, IMX283_REG_TPG_CTRL,
+ IMX283_TPG_CTRL_CLKEN | IMX283_TPG_CTRL_PATEN, NULL);
+}
+
+static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct imx283 *imx283 = container_of(ctrl->handler, struct imx283,
+ ctrl_handler);
+ const struct imx283_mode *mode;
+ struct v4l2_mbus_framefmt *fmt;
+ const struct imx283_mode *mode_list;
+ struct v4l2_subdev_state *state;
+ unsigned int num_modes;
+ u64 shr, pixel_rate;
+ int ret = 0;
+
+ state = v4l2_subdev_get_locked_active_state(&imx283->sd);
+ fmt = v4l2_subdev_state_get_format(state, 0);
+
+ get_mode_table(fmt->code, &mode_list, &num_modes);
+ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+ fmt->width, fmt->height);
+
+ /*
+ * The VBLANK control may change the limits of usable exposure, so check
+ * and adjust if necessary.
+ */
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ /* Honour the VBLANK limits when setting exposure. */
+ s64 current_exposure, max_exposure, min_exposure;
+
+ imx283->vmax = mode->height + ctrl->val;
+
+ imx283_exposure_limits(imx283, mode,
+ &min_exposure, &max_exposure);
+
+ current_exposure = imx283->exposure->val;
+ current_exposure = clamp(current_exposure, min_exposure,
+ max_exposure);
+
+ __v4l2_ctrl_modify_range(imx283->exposure, min_exposure,
+ max_exposure, 1, current_exposure);
+ }
+
+ /*
+ * Applying V4L2 control value only happens
+ * when power is up for streaming
+ */
+ if (!pm_runtime_get_if_active(imx283->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ shr = imx283_shr(imx283, mode, ctrl->val);
+ dev_dbg(imx283->dev, "V4L2_CID_EXPOSURE : %d - SHR: %lld\n",
+ ctrl->val, shr);
+ ret = cci_write(imx283->cci, IMX283_REG_SHR, shr, NULL);
+ break;
+
+ case V4L2_CID_HBLANK:
+ pixel_rate = imx283_pixel_rate(imx283, mode);
+ imx283->hmax = imx283_internal_clock(pixel_rate, mode->width + ctrl->val);
+ dev_dbg(imx283->dev, "V4L2_CID_HBLANK : %d HMAX : %u\n",
+ ctrl->val, imx283->hmax);
+ ret = cci_write(imx283->cci, IMX283_REG_HMAX, imx283->hmax, NULL);
+ break;
+
+ case V4L2_CID_VBLANK:
+ imx283->vmax = mode->height + ctrl->val;
+ dev_dbg(imx283->dev, "V4L2_CID_VBLANK : %d VMAX : %u\n",
+ ctrl->val, imx283->vmax);
+ ret = cci_write(imx283->cci, IMX283_REG_VMAX, imx283->vmax, NULL);
+ break;
+
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = cci_write(imx283->cci, IMX283_REG_ANALOG_GAIN, ctrl->val, NULL);
+ break;
+
+ case V4L2_CID_DIGITAL_GAIN:
+ ret = cci_write(imx283->cci, IMX283_REG_DIGITAL_GAIN, ctrl->val, NULL);
+ break;
+
+ case V4L2_CID_VFLIP:
+ /*
+ * VFLIP is managed by BIT(0) of IMX283_REG_HTRIMMING address, hence
+ * both need to be set simultaneously.
+ */
+ if (ctrl->val) {
+ cci_write(imx283->cci, IMX283_REG_HTRIMMING,
+ IMX283_HTRIMMING_EN | IMX283_MDVREV, &ret);
+ } else {
+ cci_write(imx283->cci, IMX283_REG_HTRIMMING,
+ IMX283_HTRIMMING_EN, &ret);
+ }
+ break;
+
+ case V4L2_CID_TEST_PATTERN:
+ ret = imx283_update_test_pattern(imx283, ctrl->val);
+ break;
+
+ default:
+ dev_err(imx283->dev, "ctrl(id:0x%x, val:0x%x) is not handled\n",
+ ctrl->id, ctrl->val);
+ break;
+ }
+
+ pm_runtime_put(imx283->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops imx283_ctrl_ops = {
+ .s_ctrl = imx283_set_ctrl,
+};
+
+static int imx283_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index >= ARRAY_SIZE(imx283_mbus_codes))
+ return -EINVAL;
+
+ code->code = imx283_mbus_codes[code->index];
+
+ return 0;
+}
+
+static int imx283_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ const struct imx283_mode *mode_list;
+ unsigned int num_modes;
+
+ get_mode_table(fse->code, &mode_list, &num_modes);
+
+ if (fse->index >= num_modes)
+ return -EINVAL;
+
+ fse->min_width = mode_list[fse->index].width;
+ fse->max_width = fse->min_width;
+ fse->min_height = mode_list[fse->index].height;
+ fse->max_height = fse->min_height;
+
+ return 0;
+}
+
+static void imx283_update_image_pad_format(struct imx283 *imx283,
+ const struct imx283_mode *mode,
+ struct v4l2_mbus_framefmt *format)
+{
+ format->width = mode->width;
+ format->height = mode->height;
+ format->field = V4L2_FIELD_NONE;
+ format->colorspace = V4L2_COLORSPACE_RAW;
+ format->ycbcr_enc = V4L2_YCBCR_ENC_601;
+ format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ format->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int imx283_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct imx283 *imx283 = to_imx283(sd);
+ struct v4l2_mbus_framefmt *format;
+ const struct imx283_mode *mode;
+ struct v4l2_rect *crop;
+
+ /* Initialize try_fmt */
+ format = v4l2_subdev_state_get_format(state, IMAGE_PAD);
+
+ mode = &supported_modes_12bit[0];
+ format->code = MEDIA_BUS_FMT_SRGGB12_1X12;
+ imx283_update_image_pad_format(imx283, mode, format);
+
+ /* Initialize crop rectangle to mode default */
+ crop = v4l2_subdev_state_get_crop(state, IMAGE_PAD);
+ *crop = mode->crop;
+
+ return 0;
+}
+
+static void imx283_set_framing_limits(struct imx283 *imx283,
+ const struct imx283_mode *mode)
+{
+ u64 pixel_rate = imx283_pixel_rate(imx283, mode);
+ u64 min_hblank, max_hblank, def_hblank;
+
+ /* Initialise hmax and vmax for exposure calculations */
+ imx283->hmax = imx283_internal_clock(pixel_rate, mode->default_hmax);
+ imx283->vmax = mode->default_vmax;
+
+ /*
+ * Horizontal Blanking
+ * Convert the HMAX_MAX (72MHz) to Pixel rate values for HBLANK_MAX
+ */
+ min_hblank = mode->min_hmax - mode->width;
+ max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
+ def_hblank = mode->default_hmax - mode->width;
+ __v4l2_ctrl_modify_range(imx283->hblank, min_hblank, max_hblank, 1,
+ def_hblank);
+ __v4l2_ctrl_s_ctrl(imx283->hblank, def_hblank);
+
+ /* Vertical Blanking */
+ __v4l2_ctrl_modify_range(imx283->vblank, mode->min_vmax - mode->height,
+ IMX283_VMAX_MAX - mode->height, 1,
+ mode->default_vmax - mode->height);
+ __v4l2_ctrl_s_ctrl(imx283->vblank, mode->default_vmax - mode->height);
+}
+
+static int imx283_set_pad_format(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *fmt)
+{
+ struct v4l2_mbus_framefmt *format;
+ const struct imx283_mode *mode;
+ struct imx283 *imx283 = to_imx283(sd);
+ const struct imx283_mode *mode_list;
+ unsigned int num_modes;
+
+ get_mode_table(fmt->format.code, &mode_list, &num_modes);
+
+ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+ fmt->format.width, fmt->format.height);
+
+ fmt->format.width = mode->width;
+ fmt->format.height = mode->height;
+ fmt->format.field = V4L2_FIELD_NONE;
+ 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;
+
+ format = v4l2_subdev_state_get_format(sd_state, 0);
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+ imx283_set_framing_limits(imx283, mode);
+
+ *format = fmt->format;
+
+ return 0;
+}
+
+static int imx283_standby_cancel(struct imx283 *imx283)
+{
+ unsigned int link_freq_idx;
+ int ret = 0;
+
+ cci_write(imx283->cci, IMX283_REG_STANDBY,
+ IMX283_STBLOGIC | IMX283_STBDV, &ret);
+
+ /* Configure PLL clocks based on the xclk */
+ cci_multi_reg_write(imx283->cci, imx283->freq->regs,
+ imx283->freq->reg_count, &ret);
+
+ dev_dbg(imx283->dev, "Using clk freq %ld MHz",
+ imx283->freq->mhz / HZ_PER_MHZ);
+
+ /* Initialise communication */
+ cci_write(imx283->cci, IMX283_REG_PLSTMG08, IMX283_PLSTMG08_VAL, &ret);
+ cci_write(imx283->cci, IMX283_REG_PLSTMG02, IMX283_PLSTMG02_VAL, &ret);
+
+ /* Enable PLL */
+ cci_write(imx283->cci, IMX283_REG_STBPL, IMX283_STBPL_NORMAL, &ret);
+
+ /* Configure the MIPI link speed */
+ link_freq_idx = __ffs(imx283->link_freq_bitmap);
+ cci_multi_reg_write(imx283->cci, link_freq_reglist[link_freq_idx].regs,
+ link_freq_reglist[link_freq_idx].num_of_regs,
+ &ret);
+
+ /* 1st Stabilisation period of 1 ms or more */
+ usleep_range(1000, 2000);
+
+ /* Activate */
+ cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_ACTIVE, &ret);
+
+ /* 2nd Stabilisation period of 19ms or more */
+ usleep_range(19000, 20000);
+
+ cci_write(imx283->cci, IMX283_REG_CLAMP, IMX283_CLPSQRST, &ret);
+ cci_write(imx283->cci, IMX283_REG_XMSTA, 0, &ret);
+ cci_write(imx283->cci, IMX283_REG_SYNCDRV, IMX283_SYNCDRV_XHS_XVS, &ret);
+
+ return ret;
+}
+
+/* Start streaming */
+static int imx283_start_streaming(struct imx283 *imx283,
+ struct v4l2_subdev_state *state)
+{
+ const struct imx283_readout_mode *readout;
+ const struct imx283_mode *mode;
+ const struct v4l2_mbus_framefmt *fmt;
+ const struct imx283_mode *mode_list;
+ unsigned int num_modes;
+ u32 v_widcut;
+ s32 v_pos;
+ u32 write_v_size;
+ u32 y_out_size;
+ int ret = 0;
+
+ fmt = v4l2_subdev_state_get_format(state, 0);
+ get_mode_table(fmt->code, &mode_list, &num_modes);
+ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
+ fmt->width, fmt->height);
+
+ ret = imx283_standby_cancel(imx283);
+ if (ret) {
+ dev_err(imx283->dev, "failed to cancel standby\n");
+ return ret;
+ }
+
+ /*
+ * Set the readout mode registers.
+ * MDSEL3 and MDSEL4 are updated to enable Arbitrary Vertical Cropping.
+ */
+ readout = &imx283_readout_modes[mode->mode];
+ cci_write(imx283->cci, IMX283_REG_MDSEL1, readout->mdsel1, &ret);
+ cci_write(imx283->cci, IMX283_REG_MDSEL2, readout->mdsel2, &ret);
+ cci_write(imx283->cci, IMX283_REG_MDSEL3,
+ readout->mdsel3 | IMX283_MDSEL3_VCROP_EN, &ret);
+ cci_write(imx283->cci, IMX283_REG_MDSEL4,
+ readout->mdsel4 | IMX283_MDSEL4_VCROP_EN, &ret);
+
+ /* Mode 1S specific entries from the Readout Drive Mode Tables */
+ if (mode->mode == IMX283_MODE_1S) {
+ cci_write(imx283->cci, IMX283_REG_MDSEL7, 0x01, &ret);
+ cci_write(imx283->cci, IMX283_REG_MDSEL18, 0x1098, &ret);
+ }
+
+ if (ret) {
+ dev_err(imx283->dev, "failed to set readout\n");
+ return ret;
+ }
+
+ /* Initialise SVR. Unsupported for now - Always 0 */
+ cci_write(imx283->cci, IMX283_REG_SVR, 0x00, &ret);
+
+ dev_dbg(imx283->dev, "Mode: Size %d x %d\n", mode->width, mode->height);
+ dev_dbg(imx283->dev, "Analogue Crop (in the mode) %d,%d %dx%d\n",
+ mode->crop.left,
+ mode->crop.top,
+ mode->crop.width,
+ mode->crop.height);
+
+ y_out_size = mode->crop.height / mode->vbin_ratio;
+ write_v_size = y_out_size + mode->vertical_ob;
+ /*
+ * cropping start position = (VWINPOS – Vst) × 2
+ * cropping width = Veff – (VWIDCUT – Vct) × 2
+ */
+ v_pos = imx283->vflip->val ?
+ ((-mode->crop.top / mode->vbin_ratio) / 2) + mode->vst :
+ ((mode->crop.top / mode->vbin_ratio) / 2) + mode->vst;
+ v_widcut = ((mode->veff - y_out_size) / 2) + mode->vct;
+
+ cci_write(imx283->cci, IMX283_REG_Y_OUT_SIZE, y_out_size, &ret);
+ cci_write(imx283->cci, IMX283_REG_WRITE_VSIZE, write_v_size, &ret);
+ cci_write(imx283->cci, IMX283_REG_VWIDCUT, v_widcut, &ret);
+ cci_write(imx283->cci, IMX283_REG_VWINPOS, v_pos, &ret);
+
+ cci_write(imx283->cci, IMX283_REG_OB_SIZE_V, mode->vertical_ob, &ret);
+
+ /* TODO: Validate mode->crop is fully contained within imx283_native_area */
+ cci_write(imx283->cci, IMX283_REG_HTRIMMING_START, mode->crop.left, &ret);
+ cci_write(imx283->cci, IMX283_REG_HTRIMMING_END,
+ mode->crop.left + mode->crop.width, &ret);
+
+ /* Disable embedded data */
+ cci_write(imx283->cci, IMX283_REG_EBD_X_OUT_SIZE, 0, &ret);
+
+ /* Apply customized values from controls (HMAX/VMAX/SHR) */
+ ret = __v4l2_ctrl_handler_setup(imx283->sd.ctrl_handler);
+
+ return ret;
+}
+
+static int imx283_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct imx283 *imx283 = to_imx283(sd);
+ int ret;
+
+ if (pad != IMAGE_PAD)
+ return -EINVAL;
+
+ ret = pm_runtime_get_sync(imx283->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(imx283->dev);
+ return ret;
+ }
+
+ ret = imx283_start_streaming(imx283, state);
+ if (ret)
+ goto err_rpm_put;
+
+ return 0;
+
+err_rpm_put:
+ pm_runtime_mark_last_busy(imx283->dev);
+ pm_runtime_put_autosuspend(imx283->dev);
+
+ return ret;
+}
+
+static int imx283_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct imx283 *imx283 = to_imx283(sd);
+ int ret;
+
+ if (pad != IMAGE_PAD)
+ return -EINVAL;
+
+ ret = cci_write(imx283->cci, IMX283_REG_STANDBY, IMX283_STBLOGIC, NULL);
+ if (ret)
+ dev_err(imx283->dev, "Failed to stop stream\n");
+
+ pm_runtime_mark_last_busy(imx283->dev);
+ pm_runtime_put_autosuspend(imx283->dev);
+
+ return ret;
+}
+
+/* Power/clock management functions */
+static int imx283_power_on(struct imx283 *imx283)
+{
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(imx283_supply_name),
+ imx283->supplies);
+ if (ret) {
+ dev_err(imx283->dev, "failed to enable regulators\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(imx283->xclk);
+ if (ret) {
+ dev_err(imx283->dev, "failed to enable clock\n");
+ goto reg_off;
+ }
+
+ gpiod_set_value_cansleep(imx283->reset_gpio, 0);
+
+ usleep_range(IMX283_XCLR_MIN_DELAY_US,
+ IMX283_XCLR_MIN_DELAY_US + IMX283_XCLR_DELAY_RANGE_US);
+
+ return 0;
+
+reg_off:
+ regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
+ return ret;
+}
+
+static int imx283_power_off(struct imx283 *imx283)
+{
+ gpiod_set_value_cansleep(imx283->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(imx283_supply_name), imx283->supplies);
+ clk_disable_unprepare(imx283->xclk);
+
+ return 0;
+}
+
+static int imx283_runtime_resume(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct imx283 *imx283 = to_imx283(sd);
+
+ return imx283_power_on(imx283);
+}
+
+static int imx283_runtime_suspend(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct imx283 *imx283 = to_imx283(sd);
+
+ imx283_power_off(imx283);
+
+ return 0;
+}
+
+static int imx283_get_regulators(struct imx283 *imx283)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx283_supply_name); i++)
+ imx283->supplies[i].supply = imx283_supply_name[i];
+
+ return devm_regulator_bulk_get(imx283->dev,
+ ARRAY_SIZE(imx283_supply_name),
+ imx283->supplies);
+}
+
+/* Verify chip ID */
+static int imx283_identify_module(struct imx283 *imx283)
+{
+ int ret;
+ u64 val;
+
+ ret = cci_read(imx283->cci, IMX283_REG_CHIP_ID, &val, NULL);
+ if (ret) {
+ dev_err(imx283->dev, "failed to read chip id %x, with error %d\n",
+ IMX283_CHIP_ID, ret);
+ return ret;
+ }
+
+ if (val != IMX283_CHIP_ID) {
+ dev_err(imx283->dev, "chip id mismatch: %x!=%llx\n",
+ IMX283_CHIP_ID, val);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int imx283_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_NATIVE_SIZE:
+ sel->r = imx283_native_area;
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r = imx283_active_area;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_subdev_core_ops imx283_core_ops = {
+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_video_ops imx283_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_pad_ops imx283_pad_ops = {
+ .enum_mbus_code = imx283_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = imx283_set_pad_format,
+ .get_selection = imx283_get_selection,
+ .enum_frame_size = imx283_enum_frame_size,
+ .enable_streams = imx283_enable_streams,
+ .disable_streams = imx283_disable_streams,
+};
+
+static const struct v4l2_subdev_internal_ops imx283_internal_ops = {
+ .init_state = imx283_init_state,
+};
+
+static const struct v4l2_subdev_ops imx283_subdev_ops = {
+ .core = &imx283_core_ops,
+ .video = &imx283_video_ops,
+ .pad = &imx283_pad_ops,
+};
+
+/* Initialize control handlers */
+static int imx283_init_controls(struct imx283 *imx283)
+{
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ struct v4l2_fwnode_device_properties props;
+ struct v4l2_ctrl *link_freq;
+ const struct imx283_mode *mode = &supported_modes_12bit[0];
+ u64 min_hblank, max_hblank, def_hblank;
+ u64 pixel_rate;
+ int ret;
+
+ ctrl_hdlr = &imx283->ctrl_handler;
+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
+ if (ret)
+ return ret;
+
+ /*
+ * Create the controls here, but mode specific limits are setup
+ * in the imx283_set_framing_limits() call below.
+ */
+
+ /* By default, PIXEL_RATE is read only */
+ pixel_rate = imx283_pixel_rate(imx283, mode);
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, pixel_rate,
+ pixel_rate, 1, pixel_rate);
+
+ link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+ __fls(imx283->link_freq_bitmap),
+ __ffs(imx283->link_freq_bitmap),
+ link_frequencies);
+ if (link_freq)
+ link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ /* Initialise vblank/hblank/exposure based on the current mode. */
+ imx283->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_VBLANK,
+ mode->min_vmax - mode->height,
+ IMX283_VMAX_MAX, 1,
+ mode->default_vmax - mode->height);
+
+ min_hblank = mode->min_hmax - mode->width;
+ max_hblank = imx283_iclk_to_pix(pixel_rate, IMX283_HMAX_MAX) - mode->width;
+ def_hblank = mode->default_hmax - mode->width;
+ imx283->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_HBLANK, min_hblank, max_hblank,
+ 1, def_hblank);
+
+ imx283->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ IMX283_EXPOSURE_MIN,
+ IMX283_EXPOSURE_MAX,
+ IMX283_EXPOSURE_STEP,
+ IMX283_EXPOSURE_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+ IMX283_ANA_GAIN_MIN, IMX283_ANA_GAIN_MAX,
+ IMX283_ANA_GAIN_STEP, IMX283_ANA_GAIN_DEFAULT);
+
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+ IMX283_DGTL_GAIN_MIN, IMX283_DGTL_GAIN_MAX,
+ IMX283_DGTL_GAIN_STEP, IMX283_DGTL_GAIN_DEFAULT);
+
+ imx283->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx283_ctrl_ops, V4L2_CID_VFLIP,
+ 0, 1, 1, 0);
+ if (imx283->vflip)
+ imx283->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
+
+ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx283_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(imx283_tpg_menu) - 1,
+ 0, 0, imx283_tpg_menu);
+
+ if (ctrl_hdlr->error) {
+ ret = ctrl_hdlr->error;
+ dev_err(imx283->dev, "control init failed (%d)\n", ret);
+ goto error;
+ }
+
+ ret = v4l2_fwnode_device_parse(imx283->dev, &props);
+ if (ret)
+ goto error;
+
+ ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx283_ctrl_ops,
+ &props);
+ if (ret)
+ goto error;
+
+ imx283->sd.ctrl_handler = ctrl_hdlr;
+
+ mutex_lock(imx283->ctrl_handler.lock);
+
+ /* Setup exposure and frame/line length limits. */
+ imx283_set_framing_limits(imx283, mode);
+
+ mutex_unlock(imx283->ctrl_handler.lock);
+
+ return 0;
+
+error:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+
+ return ret;
+}
+
+static int imx283_parse_endpoint(struct imx283 *imx283)
+{
+ struct fwnode_handle *fwnode;
+ struct v4l2_fwnode_endpoint bus_cfg = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct fwnode_handle *ep;
+ int ret;
+
+ fwnode = dev_fwnode(imx283->dev);
+ ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (!ep) {
+ dev_err(imx283->dev, "Failed to get next endpoint\n");
+ return -ENXIO;
+ }
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return ret;
+
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+ dev_err(imx283->dev,
+ "number of CSI2 data lanes %d is not supported\n",
+ bus_cfg.bus.mipi_csi2.num_data_lanes);
+ ret = -EINVAL;
+ goto done_endpoint_free;
+ }
+
+ ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
+ bus_cfg.nr_of_link_frequencies,
+ link_frequencies, ARRAY_SIZE(link_frequencies),
+ &imx283->link_freq_bitmap);
+
+done_endpoint_free:
+ v4l2_fwnode_endpoint_free(&bus_cfg);
+
+ return ret;
+};
+
+static int imx283_probe(struct i2c_client *client)
+{
+ struct imx283 *imx283;
+ unsigned int i;
+ unsigned int xclk_freq;
+ int ret;
+
+ imx283 = devm_kzalloc(&client->dev, sizeof(*imx283), GFP_KERNEL);
+ if (!imx283)
+ return -ENOMEM;
+
+ imx283->dev = &client->dev;
+
+ v4l2_i2c_subdev_init(&imx283->sd, client, &imx283_subdev_ops);
+
+ imx283->cci = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx283->cci)) {
+ ret = PTR_ERR(imx283->cci);
+ dev_err(imx283->dev, "failed to initialize CCI: %d\n", ret);
+ return ret;
+ }
+
+ /* Get system clock (xclk) */
+ imx283->xclk = devm_clk_get(imx283->dev, NULL);
+ if (IS_ERR(imx283->xclk)) {
+ return dev_err_probe(imx283->dev, PTR_ERR(imx283->xclk),
+ "failed to get xclk\n");
+ }
+
+ xclk_freq = clk_get_rate(imx283->xclk);
+ for (i = 0; i < ARRAY_SIZE(imx283_frequencies); i++) {
+ if (xclk_freq == imx283_frequencies[i].mhz) {
+ imx283->freq = &imx283_frequencies[i];
+ break;
+ }
+ }
+ if (!imx283->freq) {
+ dev_err(imx283->dev, "xclk frequency unsupported: %d Hz\n", xclk_freq);
+ return -EINVAL;
+ }
+
+ ret = imx283_get_regulators(imx283);
+ if (ret) {
+ return dev_err_probe(imx283->dev, ret,
+ "failed to get regulators\n");
+ }
+
+ ret = imx283_parse_endpoint(imx283);
+ if (ret) {
+ dev_err(imx283->dev, "failed to parse endpoint configuration\n");
+ return ret;
+ }
+
+ /* Request optional enable pin */
+ imx283->reset_gpio = devm_gpiod_get_optional(imx283->dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(imx283->reset_gpio))
+ return dev_err_probe(imx283->dev, PTR_ERR(imx283->reset_gpio),
+ "failed to get reset GPIO\n");
+
+ /*
+ * The sensor must be powered for imx283_identify_module()
+ * to be able to read the CHIP_ID register
+ */
+ ret = imx283_power_on(imx283);
+ if (ret)
+ return ret;
+
+ ret = imx283_identify_module(imx283);
+ if (ret)
+ goto error_power_off;
+
+ /*
+ * Enable runtime PM with autosuspend. As the device has been powered
+ * manually, mark it as active, and increase the usage count without
+ * resuming the device.
+ */
+ pm_runtime_set_active(imx283->dev);
+ pm_runtime_get_noresume(imx283->dev);
+ pm_runtime_enable(imx283->dev);
+ pm_runtime_set_autosuspend_delay(imx283->dev, 1000);
+ pm_runtime_use_autosuspend(imx283->dev);
+
+ /* This needs the pm runtime to be registered. */
+ ret = imx283_init_controls(imx283);
+ if (ret)
+ goto error_pm;
+
+ /* Initialize subdev */
+ imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+ V4L2_SUBDEV_FL_HAS_EVENTS;
+ imx283->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ imx283->sd.internal_ops = &imx283_internal_ops;
+
+ /* Initialize source pads */
+ imx283->pad.flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&imx283->sd.entity, 1, &imx283->pad);
+ if (ret) {
+ dev_err(imx283->dev, "failed to init entity pads: %d\n", ret);
+ goto error_handler_free;
+ }
+
+ imx283->sd.state_lock = imx283->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&imx283->sd);
+ if (ret < 0) {
+ dev_err(imx283->dev, "subdev init error: %d\n", ret);
+ goto error_media_entity;
+ }
+
+ ret = v4l2_async_register_subdev_sensor(&imx283->sd);
+ if (ret < 0) {
+ dev_err(imx283->dev, "failed to register sensor sub-device: %d\n", ret);
+ goto error_subdev_cleanup;
+ }
+
+ /*
+ * Decrease the PM usage count. The device will get suspended after the
+ * autosuspend delay, turning the power off.
+ */
+ pm_runtime_mark_last_busy(imx283->dev);
+ pm_runtime_put_autosuspend(imx283->dev);
+
+ return 0;
+
+error_subdev_cleanup:
+ v4l2_subdev_cleanup(&imx283->sd);
+
+error_media_entity:
+ media_entity_cleanup(&imx283->sd.entity);
+
+error_handler_free:
+ v4l2_ctrl_handler_free(imx283->sd.ctrl_handler);
+
+error_pm:
+ pm_runtime_disable(imx283->dev);
+ pm_runtime_set_suspended(imx283->dev);
+error_power_off:
+ imx283_power_off(imx283);
+
+ return ret;
+}
+
+static void imx283_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct imx283 *imx283 = to_imx283(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ v4l2_subdev_cleanup(&imx283->sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(imx283->sd.ctrl_handler);
+
+ pm_runtime_disable(imx283->dev);
+ if (!pm_runtime_status_suspended(imx283->dev))
+ imx283_power_off(imx283);
+ pm_runtime_set_suspended(imx283->dev);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(imx283_pm_ops, imx283_runtime_suspend,
+ imx283_runtime_resume, NULL);
+
+static const struct of_device_id imx283_dt_ids[] = {
+ { .compatible = "sony,imx283" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx283_dt_ids);
+
+static struct i2c_driver imx283_i2c_driver = {
+ .driver = {
+ .name = "imx283",
+ .pm = pm_ptr(&imx283_pm_ops),
+ .of_match_table = imx283_dt_ids,
+ },
+ .probe = imx283_probe,
+ .remove = imx283_remove,
+};
+module_i2c_driver(imx283_i2c_driver);
+
+MODULE_AUTHOR("Will Whang <[email protected]>");
+MODULE_AUTHOR("Kieran Bingham <[email protected]>");
+MODULE_AUTHOR("Umang Jain <[email protected]>");
+MODULE_DESCRIPTION("Sony IMX283 Sensor Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c
index 0efce329525e..7d1f7af0a9df 100644
--- a/drivers/media/i2c/imx412.c
+++ b/drivers/media/i2c/imx412.c
@@ -542,14 +542,13 @@ static int imx412_update_controls(struct imx412 *imx412,
*/
static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
{
- u32 lpfr, shutter;
+ u32 lpfr;
int ret;
lpfr = imx412->vblank + imx412->cur_mode->height;
- shutter = lpfr - exposure;
- dev_dbg(imx412->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u",
- exposure, gain, shutter, lpfr);
+ dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u",
+ exposure, gain, lpfr);
ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1);
if (ret)
@@ -559,7 +558,7 @@ static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
if (ret)
goto error_release_group_hold;
- ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, shutter);
+ ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure);
if (ret)
goto error_release_group_hold;
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index 5c583f57e3f3..9d0a763cd503 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -175,14 +175,6 @@ MODULE_LICENSE("GPL");
* mga_dev : represents one ks0127 chip.
****************************************************************************/
-struct adjust {
- int contrast;
- int bright;
- int hue;
- int ugain;
- int vgain;
-};
-
struct ks0127 {
struct v4l2_subdev sd;
v4l2_std_id norm;
diff --git a/drivers/media/i2c/max96714.c b/drivers/media/i2c/max96714.c
new file mode 100644
index 000000000000..c97de66631e0
--- /dev/null
+++ b/drivers/media/i2c/max96714.c
@@ -0,0 +1,1024 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim GMSL2 Deserializer Driver
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/fwnode.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/module.h>
+#include <linux/regmap.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>
+
+#define MAX96714_DEVICE_ID 0xc9
+#define MAX96714F_DEVICE_ID 0xca
+#define MAX96714_NPORTS 2
+#define MAX96714_PAD_SINK 0
+#define MAX96714_PAD_SOURCE 1
+
+/* DEV */
+#define MAX96714_REG13 CCI_REG8(0x0d)
+#define MAX96714_DEV_REV CCI_REG8(0x0e)
+#define MAX96714_DEV_REV_MASK GENMASK(3, 0)
+#define MAX96714_LINK_LOCK CCI_REG8(0x13)
+#define MAX96714_LINK_LOCK_BIT BIT(3)
+#define MAX96714_IO_CHK0 CCI_REG8(0x38)
+#define MAX96714_PATTERN_CLK_FREQ GENMASK(1, 0)
+/* VID_RX */
+#define MAX96714_VIDEO_RX8 CCI_REG8(0x11a)
+#define MAX96714_VID_LOCK BIT(6)
+
+/* VRX_PATGEN_0 */
+#define MAX96714_PATGEN_0 CCI_REG8(0x240)
+#define MAX96714_PATGEN_1 CCI_REG8(0x241)
+#define MAX96714_PATGEN_MODE GENMASK(5, 4)
+#define MAX96714_PATGEN_VS_DLY CCI_REG24(0x242)
+#define MAX96714_PATGEN_VS_HIGH CCI_REG24(0x245)
+#define MAX96714_PATGEN_VS_LOW CCI_REG24(0x248)
+#define MAX96714_PATGEN_V2H CCI_REG24(0x24b)
+#define MAX96714_PATGEN_HS_HIGH CCI_REG16(0x24e)
+#define MAX96714_PATGEN_HS_LOW CCI_REG16(0x250)
+#define MAX96714_PATGEN_HS_CNT CCI_REG16(0x252)
+#define MAX96714_PATGEN_V2D CCI_REG24(0x254)
+#define MAX96714_PATGEN_DE_HIGH CCI_REG16(0x257)
+#define MAX96714_PATGEN_DE_LOW CCI_REG16(0x259)
+#define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25B)
+#define MAX96714_PATGEN_GRAD_INC CCI_REG8(0x25d)
+#define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25E)
+#define MAX96714_PATGEN_CHKB_COLOR_B CCI_REG24(0x261)
+#define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264)
+#define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265)
+#define MAX96714_PATGEN_CHKB_ALT CCI_REG8(0x266)
+/* BACKTOP */
+#define MAX96714_BACKTOP25 CCI_REG8(0x320)
+#define CSI_DPLL_FREQ_MASK GENMASK(4, 0)
+
+/* MIPI_PHY */
+#define MAX96714_MIPI_PHY0 CCI_REG8(0x330)
+#define MAX96714_FORCE_CSI_OUT BIT(7)
+#define MAX96714_MIPI_STDBY_N CCI_REG8(0x332)
+#define MAX96714_MIPI_STDBY_MASK GENMASK(5, 4)
+#define MAX96714_MIPI_LANE_MAP CCI_REG8(0x333)
+#define MAX96714_MIPI_POLARITY CCI_REG8(0x335)
+#define MAX96714_MIPI_POLARITY_MASK GENMASK(5, 0)
+
+/* MIPI_TX */
+#define MAX96714_MIPI_LANE_CNT CCI_REG8(0x44a)
+#define MAX96714_CSI2_LANE_CNT_MASK GENMASK(7, 6)
+#define MAX96714_MIPI_TX52 CCI_REG8(0x474)
+#define MAX96714_TUN_EN BIT(0)
+
+#define MHZ(v) ((u32)((v) * 1000000U))
+
+enum max96714_vpg_mode {
+ MAX96714_VPG_DISABLED = 0,
+ MAX96714_VPG_CHECKERBOARD = 1,
+ MAX96714_VPG_GRADIENT = 2,
+};
+
+struct max96714_rxport {
+ struct {
+ struct v4l2_subdev *sd;
+ u16 pad;
+ struct fwnode_handle *ep_fwnode;
+ } source;
+ struct regulator *poc;
+};
+
+struct max96714_txport {
+ struct v4l2_fwnode_endpoint vep;
+};
+
+struct max96714_priv {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct gpio_desc *pd_gpio;
+ struct max96714_rxport rxport;
+ struct i2c_mux_core *mux;
+ u64 enabled_source_streams;
+ struct v4l2_subdev sd;
+ struct media_pad pads[MAX96714_NPORTS];
+ struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_async_notifier notifier;
+ s64 tx_link_freq;
+ enum max96714_vpg_mode pattern;
+};
+
+static inline struct max96714_priv *sd_to_max96714(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct max96714_priv, sd);
+}
+
+static int max96714_enable_tx_port(struct max96714_priv *priv)
+{
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
+ MAX96714_MIPI_STDBY_MASK,
+ MAX96714_MIPI_STDBY_MASK, NULL);
+}
+
+static int max96714_disable_tx_port(struct max96714_priv *priv)
+{
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
+ MAX96714_MIPI_STDBY_MASK, 0, NULL);
+}
+
+static bool max96714_tx_port_enabled(struct max96714_priv *priv)
+{
+ u64 val;
+
+ cci_read(priv->regmap, MAX96714_MIPI_STDBY_N, &val, NULL);
+
+ return val & MAX96714_MIPI_STDBY_MASK;
+}
+
+static int max96714_apply_patgen_timing(struct max96714_priv *priv,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_mbus_framefmt *fmt =
+ v4l2_subdev_state_get_format(state, MAX96714_PAD_SOURCE);
+ const u32 h_active = fmt->width;
+ const u32 h_fp = 88;
+ const u32 h_sw = 44;
+ const u32 h_bp = 148;
+ u32 h_tot;
+ const u32 v_active = fmt->height;
+ const u32 v_fp = 4;
+ const u32 v_sw = 5;
+ const u32 v_bp = 36;
+ u32 v_tot;
+ int ret = 0;
+
+ h_tot = h_active + h_fp + h_sw + h_bp;
+ v_tot = v_active + v_fp + v_sw + v_bp;
+
+ /* 75 Mhz pixel clock */
+ cci_update_bits(priv->regmap, MAX96714_IO_CHK0,
+ MAX96714_PATTERN_CLK_FREQ, 1, &ret);
+
+ dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
+ fmt->width);
+
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_DLY, 0, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_HIGH, v_sw * h_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_LOW,
+ (v_active + v_fp + v_bp) * h_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_HIGH, h_sw, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_LOW, h_active + h_fp + h_bp,
+ &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_V2D,
+ h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_CNT, v_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_HIGH, h_active, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_LOW, h_fp + h_sw + h_bp,
+ &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_CNT, v_active, &ret);
+ /* B G R */
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_A, 0xfecc00, &ret);
+ /* B G R */
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_B, 0x006aa7, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_A, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_B, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_ALT, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_GRAD_INC, 0x10, &ret);
+
+ return ret;
+}
+
+static int max96714_apply_patgen(struct max96714_priv *priv,
+ struct v4l2_subdev_state *state)
+{
+ unsigned int val;
+ int ret = 0;
+
+ if (priv->pattern)
+ ret = max96714_apply_patgen_timing(priv, state);
+
+ cci_write(priv->regmap, MAX96714_PATGEN_0, priv->pattern ? 0xfb : 0,
+ &ret);
+
+ val = FIELD_PREP(MAX96714_PATGEN_MODE, priv->pattern);
+ cci_update_bits(priv->regmap, MAX96714_PATGEN_1, MAX96714_PATGEN_MODE,
+ val, &ret);
+ return ret;
+}
+
+static int max96714_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct max96714_priv *priv =
+ container_of(ctrl->handler, struct max96714_priv, ctrl_handler);
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_TEST_PATTERN:
+ if (priv->enabled_source_streams)
+ return -EBUSY;
+ priv->pattern = ctrl->val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = cci_update_bits(priv->regmap, MAX96714_MIPI_PHY0,
+ MAX96714_FORCE_CSI_OUT,
+ priv->pattern ? MAX96714_FORCE_CSI_OUT : 0, NULL);
+
+ /* Pattern generator doesn't work with tunnel mode */
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_TX52,
+ MAX96714_TUN_EN,
+ priv->pattern ? 0 : MAX96714_TUN_EN, &ret);
+}
+
+static const char * const max96714_test_pattern[] = {
+ "Disabled",
+ "Checkerboard",
+ "Gradient"
+};
+
+static const struct v4l2_ctrl_ops max96714_ctrl_ops = {
+ .s_ctrl = max96714_s_ctrl,
+};
+
+static int max96714_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 source_pad, u64 streams_mask)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ u64 sink_streams;
+ int ret;
+
+ if (!priv->enabled_source_streams)
+ max96714_enable_tx_port(priv);
+
+ ret = max96714_apply_patgen(priv, state);
+ if (ret)
+ goto err;
+
+ if (!priv->pattern) {
+ if (!priv->rxport.source.sd) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ sink_streams =
+ v4l2_subdev_state_xlate_streams(state,
+ MAX96714_PAD_SOURCE,
+ MAX96714_PAD_SINK,
+ &streams_mask);
+
+ ret = v4l2_subdev_enable_streams(priv->rxport.source.sd,
+ priv->rxport.source.pad,
+ sink_streams);
+ if (ret)
+ goto err;
+ }
+
+ priv->enabled_source_streams |= streams_mask;
+
+ return 0;
+
+err:
+ if (!priv->enabled_source_streams)
+ max96714_disable_tx_port(priv);
+
+ return ret;
+}
+
+static int max96714_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 source_pad, u64 streams_mask)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ u64 sink_streams;
+
+ if (!priv->pattern) {
+ int ret;
+
+ sink_streams =
+ v4l2_subdev_state_xlate_streams(state,
+ MAX96714_PAD_SOURCE,
+ MAX96714_PAD_SINK,
+ &streams_mask);
+
+ ret = v4l2_subdev_disable_streams(priv->rxport.source.sd,
+ priv->rxport.source.pad,
+ sink_streams);
+ if (ret)
+ return ret;
+ }
+
+ priv->enabled_source_streams &= ~streams_mask;
+
+ if (!priv->enabled_source_streams)
+ max96714_disable_tx_port(priv);
+
+ return 0;
+}
+
+static int max96714_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ priv->enabled_source_streams)
+ return -EBUSY;
+
+ /* No transcoding, source and sink formats must match. */
+ if (format->pad == MAX96714_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, state, format);
+
+ fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+ format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ return 0;
+}
+
+static int _max96714_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ static const struct v4l2_mbus_framefmt format = {
+ .width = 1280,
+ .height = 1080,
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .field = V4L2_FIELD_NONE,
+ };
+ int ret;
+
+ /*
+ * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
+ * frame desc is made dynamically allocated.
+ */
+ if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+ return -EINVAL;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+}
+
+static int max96714_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
+ return -EBUSY;
+
+ return _max96714_set_routing(sd, state, which, routing);
+}
+
+static int max96714_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = MAX96714_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = MAX96714_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ }
+ };
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return _max96714_set_routing(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE,
+ &routing);
+}
+
+static const struct v4l2_subdev_pad_ops max96714_pad_ops = {
+ .enable_streams = max96714_enable_streams,
+ .disable_streams = max96714_disable_streams,
+
+ .set_routing = max96714_set_routing,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = max96714_set_fmt,
+};
+
+static bool max96714_link_locked(struct max96714_priv *priv)
+{
+ u64 val = 0;
+
+ cci_read(priv->regmap, MAX96714_LINK_LOCK, &val, NULL);
+
+ return val & MAX96714_LINK_LOCK_BIT;
+}
+
+static void max96714_link_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Link locked:%d\n", max96714_link_locked(priv));
+}
+
+static bool max96714_pipe_locked(struct max96714_priv *priv)
+{
+ u64 val;
+
+ cci_read(priv->regmap, MAX96714_VIDEO_RX8, &val, NULL);
+
+ return val & MAX96714_VID_LOCK;
+}
+
+static void max96714_pipe_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Pipe vidlock:%d\n", max96714_pipe_locked(priv));
+}
+
+static void max96714_csi_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 freq = 0;
+
+ cci_read(priv->regmap, MAX96714_BACKTOP25, &freq, NULL);
+ freq = FIELD_GET(CSI_DPLL_FREQ_MASK, freq);
+
+ dev_info(dev, "CSI controller DPLL freq:%u00MHz CSIPHY enabled:%d\n",
+ (u8)freq, max96714_tx_port_enabled(priv));
+}
+
+static int max96714_log_status(struct v4l2_subdev *sd)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Deserializer: max96714\n");
+
+ max96714_link_status(priv);
+ max96714_pipe_status(priv);
+ max96714_csi_status(priv);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops max96714_subdev_core_ops = {
+ .log_status = max96714_log_status,
+};
+
+static const struct v4l2_subdev_video_ops max96714_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_internal_ops max96714_internal_ops = {
+ .init_state = max96714_init_state,
+};
+
+static const struct v4l2_subdev_ops max96714_subdev_ops = {
+ .video = &max96714_video_ops,
+ .core = &max96714_subdev_core_ops,
+ .pad = &max96714_pad_ops,
+};
+
+static const struct media_entity_operations max96714_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int max96714_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_connection *asd)
+{
+ struct max96714_priv *priv = sd_to_max96714(notifier->sd);
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ ret = media_entity_get_fwnode_pad(&subdev->entity,
+ priv->rxport.source.ep_fwnode,
+ MEDIA_PAD_FL_SOURCE);
+ if (ret < 0) {
+ dev_err(dev, "Failed to find pad for %s\n", subdev->name);
+ return ret;
+ }
+
+ priv->rxport.source.sd = subdev;
+ priv->rxport.source.pad = ret;
+
+ ret = media_create_pad_link(&priv->rxport.source.sd->entity,
+ priv->rxport.source.pad, &priv->sd.entity,
+ MAX96714_PAD_SINK,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret) {
+ dev_err(dev, "Unable to link %s:%u -> %s:%u\n",
+ priv->rxport.source.sd->name, priv->rxport.source.pad,
+ priv->sd.name, MAX96714_PAD_SINK);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations max96714_notify_ops = {
+ .bound = max96714_notify_bound,
+};
+
+static int max96714_v4l2_notifier_register(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct max96714_rxport *rxport = &priv->rxport;
+ struct v4l2_async_connection *asd;
+ int ret;
+
+ if (!rxport->source.ep_fwnode)
+ return 0;
+
+ v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
+
+ asd = v4l2_async_nf_add_fwnode(&priv->notifier,
+ rxport->source.ep_fwnode,
+ struct v4l2_async_connection);
+ if (IS_ERR(asd)) {
+ dev_err(dev, "Failed to add subdev: %pe", asd);
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return PTR_ERR(asd);
+ }
+
+ priv->notifier.ops = &max96714_notify_ops;
+
+ ret = v4l2_async_nf_register(&priv->notifier);
+ if (ret) {
+ dev_err(dev, "Failed to register subdev_notifier");
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int max96714_create_subdev(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96714_subdev_ops);
+ priv->sd.internal_ops = &max96714_internal_ops;
+
+ v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
+ priv->sd.ctrl_handler = &priv->ctrl_handler;
+
+ v4l2_ctrl_new_int_menu(&priv->ctrl_handler, NULL, V4L2_CID_LINK_FREQ,
+ 0, 0, &priv->tx_link_freq);
+ v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,
+ &max96714_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(max96714_test_pattern) - 1,
+ 0, 0, max96714_test_pattern);
+ if (priv->ctrl_handler.error) {
+ ret = priv->ctrl_handler.error;
+ goto err_free_ctrl;
+ }
+
+ priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+ priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ priv->sd.entity.ops = &max96714_entity_ops;
+
+ priv->pads[MAX96714_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ priv->pads[MAX96714_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&priv->sd.entity,
+ MAX96714_NPORTS,
+ priv->pads);
+ if (ret)
+ goto err_free_ctrl;
+
+ priv->sd.state_lock = priv->sd.ctrl_handler->lock;
+
+ ret = v4l2_subdev_init_finalize(&priv->sd);
+ if (ret)
+ goto err_entity_cleanup;
+
+ ret = max96714_v4l2_notifier_register(priv);
+ if (ret) {
+ dev_err(dev, "v4l2 subdev notifier register failed: %d\n", ret);
+ goto err_subdev_cleanup;
+ }
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret) {
+ dev_err(dev, "v4l2_async_register_subdev error: %d\n", ret);
+ goto err_unreg_notif;
+ }
+
+ return 0;
+
+err_unreg_notif:
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+err_subdev_cleanup:
+ v4l2_subdev_cleanup(&priv->sd);
+err_entity_cleanup:
+ media_entity_cleanup(&priv->sd.entity);
+err_free_ctrl:
+ v4l2_ctrl_handler_free(&priv->ctrl_handler);
+
+ return ret;
+};
+
+static void max96714_destroy_subdev(struct max96714_priv *priv)
+{
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+ v4l2_async_unregister_subdev(&priv->sd);
+
+ v4l2_subdev_cleanup(&priv->sd);
+
+ media_entity_cleanup(&priv->sd.entity);
+ v4l2_ctrl_handler_free(&priv->ctrl_handler);
+}
+
+static int max96714_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
+{
+ return 0;
+}
+
+static int max96714_i2c_mux_init(struct max96714_priv *priv)
+{
+ priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
+ 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
+ max96714_i2c_mux_select, NULL);
+ if (!priv->mux)
+ return -ENOMEM;
+
+ return i2c_mux_add_adapter(priv->mux, 0, 0);
+}
+
+static int max96714_init_tx_port(struct max96714_priv *priv)
+{
+ struct v4l2_mbus_config_mipi_csi2 *mipi;
+ unsigned long lanes_used = 0;
+ unsigned int val, lane;
+ int ret;
+
+ ret = max96714_disable_tx_port(priv);
+
+ mipi = &priv->mipi_csi2;
+ val = div_u64(priv->tx_link_freq * 2, MHZ(100));
+
+ cci_update_bits(priv->regmap, MAX96714_BACKTOP25,
+ CSI_DPLL_FREQ_MASK, val, &ret);
+
+ val = FIELD_PREP(MAX96714_CSI2_LANE_CNT_MASK, mipi->num_data_lanes - 1);
+ cci_update_bits(priv->regmap, MAX96714_MIPI_LANE_CNT,
+ MAX96714_CSI2_LANE_CNT_MASK, val, &ret);
+
+ /* lanes polarity */
+ val = 0;
+ for (lane = 0; lane < mipi->num_data_lanes + 1; lane++) {
+ if (!mipi->lane_polarities[lane])
+ continue;
+ if (lane == 0)
+ /* clock lane */
+ val |= BIT(5);
+ else if (lane < 3)
+ /* Lane D0 and D1 */
+ val |= BIT(lane - 1);
+ else
+ /* D2 and D3 */
+ val |= BIT(lane);
+ }
+
+ cci_update_bits(priv->regmap, MAX96714_MIPI_POLARITY,
+ MAX96714_MIPI_POLARITY_MASK, val, &ret);
+
+ /* lanes mapping */
+ val = 0;
+ for (lane = 0; lane < mipi->num_data_lanes; lane++) {
+ val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
+ lanes_used |= BIT(mipi->data_lanes[lane] - 1);
+ }
+
+ /*
+ * Unused lanes need to be mapped as well to not have
+ * the same lanes mapped twice.
+ */
+ for (; lane < 4; lane++) {
+ unsigned int idx = find_first_zero_bit(&lanes_used, 4);
+
+ val |= idx << (lane * 2);
+ lanes_used |= BIT(idx);
+ }
+
+ return cci_write(priv->regmap, MAX96714_MIPI_LANE_MAP, val, &ret);
+}
+
+static int max96714_rxport_enable_poc(struct max96714_priv *priv)
+{
+ struct max96714_rxport *rxport = &priv->rxport;
+
+ if (!rxport->poc)
+ return 0;
+
+ return regulator_enable(rxport->poc);
+}
+
+static int max96714_rxport_disable_poc(struct max96714_priv *priv)
+{
+ struct max96714_rxport *rxport = &priv->rxport;
+
+ if (!rxport->poc)
+ return 0;
+
+ return regulator_disable(rxport->poc);
+}
+
+static int max96714_parse_dt_txport(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct fwnode_handle *ep_fwnode;
+ u32 num_data_lanes;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96714_PAD_SOURCE, 0, 0);
+ if (!ep_fwnode)
+ return -EINVAL;
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &vep);
+ fwnode_handle_put(ep_fwnode);
+ if (ret) {
+ dev_err(dev, "tx: failed to parse endpoint data\n");
+ return -EINVAL;
+ }
+
+ if (vep.nr_of_link_frequencies != 1) {
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ priv->tx_link_freq = vep.link_frequencies[0];
+ /* Min 50MHz, Max 1250MHz, 50MHz step */
+ if (priv->tx_link_freq < MHZ(50) || priv->tx_link_freq > MHZ(1250) ||
+ (u32)priv->tx_link_freq % MHZ(50)) {
+ dev_err(dev, "tx: invalid link frequency\n");
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
+ if (num_data_lanes < 1 || num_data_lanes > 4) {
+ dev_err(dev,
+ "tx: invalid number of data lanes must be 1 to 4\n");
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2));
+
+err_free_vep:
+ v4l2_fwnode_endpoint_free(&vep);
+
+ return ret;
+}
+
+static int max96714_parse_dt_rxport(struct max96714_priv *priv)
+{
+ static const char *poc_name = "port0-poc";
+ struct max96714_rxport *rxport = &priv->rxport;
+ struct device *dev = &priv->client->dev;
+ struct fwnode_handle *ep_fwnode;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96714_PAD_SINK, 0, 0);
+ if (!ep_fwnode)
+ return -ENOENT;
+
+ rxport->source.ep_fwnode = fwnode_graph_get_remote_endpoint(ep_fwnode);
+ fwnode_handle_put(ep_fwnode);
+
+ if (!rxport->source.ep_fwnode) {
+ dev_err(dev, "rx: no remote endpoint\n");
+ return -EINVAL;
+ }
+
+ rxport->poc = devm_regulator_get_optional(dev, poc_name);
+ if (IS_ERR(rxport->poc)) {
+ ret = PTR_ERR(rxport->poc);
+ if (ret == -ENODEV) {
+ rxport->poc = NULL;
+ } else {
+ dev_err(dev, "rx: failed to get POC supply: %d\n", ret);
+ goto err_put_source_ep_fwnode;
+ }
+ }
+
+ return 0;
+
+err_put_source_ep_fwnode:
+ fwnode_handle_put(rxport->source.ep_fwnode);
+ return ret;
+}
+
+static int max96714_parse_dt(struct max96714_priv *priv)
+{
+ int ret;
+
+ ret = max96714_parse_dt_txport(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_parse_dt_rxport(priv);
+ /*
+ * The deserializer can create a test pattern even if the
+ * rx port is not connected to a serializer.
+ */
+ if (ret && ret == -ENOENT)
+ ret = 0;
+
+ return ret;
+}
+
+static int max96714_enable_core_hw(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 val;
+ int ret;
+
+ if (priv->pd_gpio) {
+ /* wait min 2 ms for reset to complete */
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+ fsleep(2000);
+ gpiod_set_value_cansleep(priv->pd_gpio, 0);
+ /* wait min 2 ms for power up to finish */
+ fsleep(2000);
+ }
+
+ ret = cci_read(priv->regmap, MAX96714_REG13, &val, NULL);
+ if (ret) {
+ dev_err_probe(dev, ret, "Cannot read first register, abort\n");
+ goto err_pd_gpio;
+ }
+
+ if (val != MAX96714_DEVICE_ID && val != MAX96714F_DEVICE_ID) {
+ dev_err(dev, "Unsupported device id expected %x got %x\n",
+ MAX96714F_DEVICE_ID, (u8)val);
+ ret = -EOPNOTSUPP;
+ goto err_pd_gpio;
+ }
+
+ ret = cci_read(priv->regmap, MAX96714_DEV_REV, &val, NULL);
+ if (ret)
+ goto err_pd_gpio;
+
+ dev_dbg(dev, "Found %x (rev %lx)\n", MAX96714F_DEVICE_ID,
+ (u8)val & MAX96714_DEV_REV_MASK);
+
+ ret = cci_read(priv->regmap, MAX96714_MIPI_TX52, &val, NULL);
+ if (ret)
+ goto err_pd_gpio;
+
+ if (!(val & MAX96714_TUN_EN)) {
+ dev_err(dev, "Only supporting tunnel mode");
+ ret = -EOPNOTSUPP;
+ goto err_pd_gpio;
+ }
+
+ return 0;
+
+err_pd_gpio:
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+ return ret;
+}
+
+static void max96714_disable_core_hw(struct max96714_priv *priv)
+{
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+}
+
+static int max96714_get_hw_resources(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ priv->regmap = devm_cci_regmap_init_i2c(priv->client, 16);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->pd_gpio =
+ devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->pd_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->pd_gpio),
+ "Cannot get powerdown GPIO\n");
+ return 0;
+}
+
+static int max96714_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct max96714_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->client = client;
+
+ ret = max96714_get_hw_resources(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_enable_core_hw(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_parse_dt(priv);
+ if (ret)
+ goto err_disable_core_hw;
+
+ max96714_init_tx_port(priv);
+
+ ret = max96714_rxport_enable_poc(priv);
+ if (ret)
+ goto err_free_ports;
+
+ ret = max96714_i2c_mux_init(priv);
+ if (ret)
+ goto err_disable_poc;
+
+ ret = max96714_create_subdev(priv);
+ if (ret)
+ goto err_del_mux;
+
+ return 0;
+
+err_del_mux:
+ i2c_mux_del_adapters(priv->mux);
+err_disable_poc:
+ max96714_rxport_disable_poc(priv);
+err_free_ports:
+ fwnode_handle_put(priv->rxport.source.ep_fwnode);
+err_disable_core_hw:
+ max96714_disable_core_hw(priv);
+
+ return ret;
+}
+
+static void max96714_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct max96714_priv *priv = sd_to_max96714(sd);
+
+ max96714_destroy_subdev(priv);
+ i2c_mux_del_adapters(priv->mux);
+ max96714_rxport_disable_poc(priv);
+ fwnode_handle_put(priv->rxport.source.ep_fwnode);
+ max96714_disable_core_hw(priv);
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+}
+
+static const struct of_device_id max96714_of_ids[] = {
+ { .compatible = "maxim,max96714f" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max96714_of_ids);
+
+static struct i2c_driver max96714_i2c_driver = {
+ .driver = {
+ .name = "max96714",
+ .of_match_table = max96714_of_ids,
+ },
+ .probe = max96714_probe,
+ .remove = max96714_remove,
+};
+
+module_i2c_driver(max96714_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Maxim Integrated GMSL2 Deserializers Driver");
+MODULE_AUTHOR("Julien Massot <[email protected]>");
diff --git a/drivers/media/i2c/max96717.c b/drivers/media/i2c/max96717.c
new file mode 100644
index 000000000000..949306485873
--- /dev/null
+++ b/drivers/media/i2c/max96717.c
@@ -0,0 +1,927 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim GMSL2 Serializer Driver
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/fwnode.h>
+#include <linux/gpio/driver.h>
+#include <linux/i2c-mux.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX96717_DEVICE_ID 0xbf
+#define MAX96717F_DEVICE_ID 0xc8
+#define MAX96717_PORTS 2
+#define MAX96717_PAD_SINK 0
+#define MAX96717_PAD_SOURCE 1
+
+#define MAX96717_DEFAULT_CLKOUT_RATE 24000000UL
+
+/* DEV */
+#define MAX96717_REG3 CCI_REG8(0x3)
+#define MAX96717_RCLKSEL GENMASK(1, 0)
+#define RCLKSEL_REF_PLL CCI_REG8(0x3)
+#define MAX96717_REG6 CCI_REG8(0x6)
+#define RCLKEN BIT(5)
+#define MAX96717_DEV_ID CCI_REG8(0xd)
+#define MAX96717_DEV_REV CCI_REG8(0xe)
+#define MAX96717_DEV_REV_MASK GENMASK(3, 0)
+
+/* VID_TX Z */
+#define MAX96717_VIDEO_TX2 CCI_REG8(0x112)
+#define MAX96717_VIDEO_PCLKDET BIT(7)
+
+/* GPIO */
+#define MAX96717_NUM_GPIO 11
+#define MAX96717_GPIO_REG_A(gpio) CCI_REG8(0x2be + (gpio) * 3)
+#define MAX96717_GPIO_OUT BIT(4)
+#define MAX96717_GPIO_IN BIT(3)
+#define MAX96717_GPIO_RX_EN BIT(2)
+#define MAX96717_GPIO_TX_EN BIT(1)
+#define MAX96717_GPIO_OUT_DIS BIT(0)
+
+/* FRONTTOP */
+/* MAX96717 only have CSI port 'B' */
+#define MAX96717_FRONTOP0 CCI_REG8(0x308)
+#define MAX96717_START_PORT_B BIT(5)
+
+/* MIPI_RX */
+#define MAX96717_MIPI_RX1 CCI_REG8(0x331)
+#define MAX96717_MIPI_LANES_CNT GENMASK(5, 4)
+#define MAX96717_MIPI_RX2 CCI_REG8(0x332) /* phy1 Lanes map */
+#define MAX96717_PHY2_LANES_MAP GENMASK(7, 4)
+#define MAX96717_MIPI_RX3 CCI_REG8(0x333) /* phy2 Lanes map */
+#define MAX96717_PHY1_LANES_MAP GENMASK(3, 0)
+#define MAX96717_MIPI_RX4 CCI_REG8(0x334) /* phy1 lane polarities */
+#define MAX96717_PHY1_LANES_POL GENMASK(6, 4)
+#define MAX96717_MIPI_RX5 CCI_REG8(0x335) /* phy2 lane polarities */
+#define MAX96717_PHY2_LANES_POL GENMASK(2, 0)
+
+/* MIPI_RX_EXT */
+#define MAX96717_MIPI_RX_EXT11 CCI_REG8(0x383)
+#define MAX96717_TUN_MODE BIT(7)
+
+/* REF_VTG */
+#define REF_VTG0 CCI_REG8(0x3f0)
+#define REFGEN_PREDEF_EN BIT(6)
+#define REFGEN_PREDEF_FREQ_MASK GENMASK(5, 4)
+#define REFGEN_PREDEF_FREQ_ALT BIT(3)
+#define REFGEN_RST BIT(1)
+#define REFGEN_EN BIT(0)
+
+/* MISC */
+#define PIO_SLEW_1 CCI_REG8(0x570)
+
+struct max96717_priv {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct i2c_mux_core *mux;
+ struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+ struct v4l2_subdev sd;
+ struct media_pad pads[MAX96717_PORTS];
+ struct v4l2_async_notifier notifier;
+ struct v4l2_subdev *source_sd;
+ u16 source_sd_pad;
+ u64 enabled_source_streams;
+ u8 pll_predef_index;
+ struct clk_hw clk_hw;
+ struct gpio_chip gpio_chip;
+};
+
+static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct max96717_priv, sd);
+}
+
+static inline struct max96717_priv *clk_hw_to_max96717(struct clk_hw *hw)
+{
+ return container_of(hw, struct max96717_priv, clk_hw);
+}
+
+static int max96717_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
+{
+ return 0;
+}
+
+static int max96717_i2c_mux_init(struct max96717_priv *priv)
+{
+ priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
+ 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
+ max96717_i2c_mux_select, NULL);
+ if (!priv->mux)
+ return -ENOMEM;
+
+ return i2c_mux_add_adapter(priv->mux, 0, 0);
+}
+
+static inline int max96717_start_csi(struct max96717_priv *priv, bool start)
+{
+ return cci_update_bits(priv->regmap, MAX96717_FRONTOP0,
+ MAX96717_START_PORT_B,
+ start ? MAX96717_START_PORT_B : 0, NULL);
+}
+
+static int max96717_gpiochip_get(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+ u64 val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ &val, NULL);
+ if (ret)
+ return ret;
+
+ if (val & MAX96717_GPIO_OUT_DIS)
+ return !!(val & MAX96717_GPIO_IN);
+ else
+ return !!(val & MAX96717_GPIO_OUT);
+}
+
+static void max96717_gpiochip_set(struct gpio_chip *gpiochip,
+ unsigned int offset, int value)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
+}
+
+static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+ u64 val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset), &val, NULL);
+ if (ret < 0)
+ return ret;
+
+ return !!(val & MAX96717_GPIO_OUT_DIS);
+}
+
+static int max96717_gpio_direction_out(struct gpio_chip *gpiochip,
+ unsigned int offset, int value)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT_DIS | MAX96717_GPIO_OUT,
+ value ? MAX96717_GPIO_OUT : 0, NULL);
+}
+
+static int max96717_gpio_direction_in(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT_DIS, MAX96717_GPIO_OUT_DIS,
+ NULL);
+}
+
+static int max96717_gpiochip_probe(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct gpio_chip *gc = &priv->gpio_chip;
+ int i, ret = 0;
+
+ gc->label = dev_name(dev);
+ gc->parent = dev;
+ gc->owner = THIS_MODULE;
+ gc->ngpio = MAX96717_NUM_GPIO;
+ gc->base = -1;
+ gc->can_sleep = true;
+ gc->get_direction = max96717_gpio_get_direction;
+ gc->direction_input = max96717_gpio_direction_in;
+ gc->direction_output = max96717_gpio_direction_out;
+ gc->set = max96717_gpiochip_set;
+ gc->get = max96717_gpiochip_get;
+ gc->of_gpio_n_cells = 2;
+
+ /* Disable GPIO forwarding */
+ for (i = 0; i < gc->ngpio; i++)
+ cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(i),
+ MAX96717_GPIO_RX_EN | MAX96717_GPIO_TX_EN,
+ 0, &ret);
+
+ if (ret)
+ return ret;
+
+ ret = devm_gpiochip_add_data(dev, gc, priv);
+ if (ret) {
+ dev_err(dev, "Unable to create gpio_chip\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int _max96717_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ static const struct v4l2_mbus_framefmt format = {
+ .width = 1280,
+ .height = 1080,
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .field = V4L2_FIELD_NONE,
+ };
+ int ret;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int max96717_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
+ return -EBUSY;
+
+ return _max96717_set_routing(sd, state, routing);
+}
+
+static int max96717_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct v4l2_mbus_framefmt *fmt;
+ u64 stream_source_mask;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ priv->enabled_source_streams)
+ return -EBUSY;
+
+ /* No transcoding, source and sink formats must match. */
+ if (format->pad == MAX96717_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, state, format);
+
+ /* Set sink format */
+ fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ /* Propagate to source format */
+ fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+ format->stream);
+ if (!fmt)
+ return -EINVAL;
+ *fmt = format->format;
+
+ stream_source_mask = BIT(format->stream);
+
+ return v4l2_subdev_state_xlate_streams(state, MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &stream_source_mask);
+}
+
+static int max96717_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = MAX96717_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = MAX96717_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ },
+ };
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return _max96717_set_routing(sd, state, &routing);
+}
+
+static bool max96717_pipe_pclkdet(struct max96717_priv *priv)
+{
+ u64 val = 0;
+
+ cci_read(priv->regmap, MAX96717_VIDEO_TX2, &val, NULL);
+
+ return val & MAX96717_VIDEO_PCLKDET;
+}
+
+static int max96717_log_status(struct v4l2_subdev *sd)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Serializer: max96717\n");
+ dev_info(dev, "Pipe: pclkdet:%d\n", max96717_pipe_pclkdet(priv));
+
+ return 0;
+}
+
+static int max96717_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct device *dev = &priv->client->dev;
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &streams_mask);
+
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, true);
+
+ ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad,
+ sink_streams);
+ if (ret) {
+ dev_err(dev, "Fail to start streams:%llu on remote subdev\n",
+ sink_streams);
+ goto stop_csi;
+ }
+
+ priv->enabled_source_streams |= streams_mask;
+
+ return 0;
+
+stop_csi:
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, false);
+ return ret;
+}
+
+static int max96717_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ u64 sink_streams;
+
+ /*
+ * Stop the CSI receiver first then the source,
+ * otherwise the device may become unresponsive
+ * while holding the I2C bus low.
+ */
+ priv->enabled_source_streams &= ~streams_mask;
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, false);
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &streams_mask);
+
+ return v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad,
+ sink_streams);
+}
+
+static const struct v4l2_subdev_pad_ops max96717_pad_ops = {
+ .enable_streams = max96717_enable_streams,
+ .disable_streams = max96717_disable_streams,
+ .set_routing = max96717_set_routing,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = max96717_set_fmt,
+};
+
+static const struct v4l2_subdev_core_ops max96717_subdev_core_ops = {
+ .log_status = max96717_log_status,
+};
+
+static const struct v4l2_subdev_internal_ops max96717_internal_ops = {
+ .init_state = max96717_init_state,
+};
+
+static const struct v4l2_subdev_ops max96717_subdev_ops = {
+ .core = &max96717_subdev_core_ops,
+ .pad = &max96717_pad_ops,
+};
+
+static const struct media_entity_operations max96717_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int max96717_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *source_subdev,
+ struct v4l2_async_connection *asd)
+{
+ struct max96717_priv *priv = sd_to_max96717(notifier->sd);
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ ret = media_entity_get_fwnode_pad(&source_subdev->entity,
+ source_subdev->fwnode,
+ MEDIA_PAD_FL_SOURCE);
+ if (ret < 0) {
+ dev_err(dev, "Failed to find pad for %s\n",
+ source_subdev->name);
+ return ret;
+ }
+
+ priv->source_sd = source_subdev;
+ priv->source_sd_pad = ret;
+
+ ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad,
+ &priv->sd.entity, 0,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret) {
+ dev_err(dev, "Unable to link %s:%u -> %s:0\n",
+ source_subdev->name, priv->source_sd_pad,
+ priv->sd.name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations max96717_notify_ops = {
+ .bound = max96717_notify_bound,
+};
+
+static int max96717_v4l2_notifier_register(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_async_connection *asd;
+ struct fwnode_handle *ep_fwnode;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96717_PAD_SINK, 0, 0);
+ if (!ep_fwnode) {
+ dev_err(dev, "No graph endpoint\n");
+ return -ENODEV;
+ }
+
+ v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
+
+ asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode,
+ struct v4l2_async_connection);
+
+ fwnode_handle_put(ep_fwnode);
+
+ if (IS_ERR(asd)) {
+ dev_err(dev, "Failed to add subdev: %ld", PTR_ERR(asd));
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return PTR_ERR(asd);
+ }
+
+ priv->notifier.ops = &max96717_notify_ops;
+
+ ret = v4l2_async_nf_register(&priv->notifier);
+ if (ret) {
+ dev_err(dev, "Failed to register subdev_notifier");
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int max96717_subdev_init(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96717_subdev_ops);
+ priv->sd.internal_ops = &max96717_internal_ops;
+
+ priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+ priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ priv->sd.entity.ops = &max96717_entity_ops;
+
+ priv->pads[MAX96717_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ priv->pads[MAX96717_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to init pads\n");
+
+ ret = v4l2_subdev_init_finalize(&priv->sd);
+ if (ret) {
+ dev_err_probe(dev, ret,
+ "v4l2 subdev init finalized failed\n");
+ goto err_entity_cleanup;
+ }
+ ret = max96717_v4l2_notifier_register(priv);
+ if (ret) {
+ dev_err_probe(dev, ret,
+ "v4l2 subdev notifier register failed\n");
+ goto err_free_state;
+ }
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret) {
+ dev_err_probe(dev, ret, "v4l2_async_register_subdev error\n");
+ goto err_unreg_notif;
+ }
+
+ return 0;
+
+err_unreg_notif:
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+err_free_state:
+ v4l2_subdev_cleanup(&priv->sd);
+err_entity_cleanup:
+ media_entity_cleanup(&priv->sd.entity);
+
+ return ret;
+}
+
+static void max96717_subdev_uninit(struct max96717_priv *priv)
+{
+ v4l2_async_unregister_subdev(&priv->sd);
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+ v4l2_subdev_cleanup(&priv->sd);
+ media_entity_cleanup(&priv->sd.entity);
+}
+
+struct max96717_pll_predef_freq {
+ unsigned long freq;
+ bool is_alt;
+ u8 val;
+};
+
+static const struct max96717_pll_predef_freq max96717_predef_freqs[] = {
+ { 13500000, true, 0 }, { 19200000, false, 0 },
+ { 24000000, true, 1 }, { 27000000, false, 1 },
+ { 37125000, false, 2 }, { 74250000, false, 3 },
+};
+
+static unsigned long
+max96717_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ return max96717_predef_freqs[priv->pll_predef_index].freq;
+}
+
+static unsigned int max96717_clk_find_best_index(struct max96717_priv *priv,
+ unsigned long rate)
+{
+ unsigned int i, idx;
+ unsigned long diff_new, diff_old;
+
+ diff_old = U32_MAX;
+ idx = 0;
+
+ for (i = 0; i < ARRAY_SIZE(max96717_predef_freqs); i++) {
+ diff_new = abs(rate - max96717_predef_freqs[i].freq);
+ if (diff_new < diff_old) {
+ diff_old = diff_new;
+ idx = i;
+ }
+ }
+
+ return idx;
+}
+
+static long max96717_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+ struct device *dev = &priv->client->dev;
+ unsigned int idx;
+
+ idx = max96717_clk_find_best_index(priv, rate);
+
+ if (rate != max96717_predef_freqs[idx].freq) {
+ dev_warn(dev, "Request CLK freq:%lu, found CLK freq:%lu\n",
+ rate, max96717_predef_freqs[idx].freq);
+ }
+
+ return max96717_predef_freqs[idx].freq;
+}
+
+static int max96717_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+ unsigned int val, idx;
+ int ret = 0;
+
+ idx = max96717_clk_find_best_index(priv, rate);
+
+ val = FIELD_PREP(REFGEN_PREDEF_FREQ_MASK,
+ max96717_predef_freqs[idx].val);
+
+ if (max96717_predef_freqs[idx].is_alt)
+ val |= REFGEN_PREDEF_FREQ_ALT;
+
+ val |= REFGEN_RST | REFGEN_PREDEF_EN;
+
+ cci_write(priv->regmap, REF_VTG0, val, &ret);
+ cci_update_bits(priv->regmap, REF_VTG0, REFGEN_RST | REFGEN_EN,
+ REFGEN_EN, &ret);
+ if (ret)
+ return ret;
+
+ priv->pll_predef_index = idx;
+
+ return 0;
+}
+
+static int max96717_clk_prepare(struct clk_hw *hw)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ return cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN,
+ RCLKEN, NULL);
+}
+
+static void max96717_clk_unprepare(struct clk_hw *hw)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN, 0, NULL);
+}
+
+static const struct clk_ops max96717_clk_ops = {
+ .prepare = max96717_clk_prepare,
+ .unprepare = max96717_clk_unprepare,
+ .set_rate = max96717_clk_set_rate,
+ .recalc_rate = max96717_clk_recalc_rate,
+ .round_rate = max96717_clk_round_rate,
+};
+
+static int max96717_register_clkout(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct clk_init_data init = { .ops = &max96717_clk_ops };
+ int ret;
+
+ init.name = kasprintf(GFP_KERNEL, "max96717.%s.clk_out",
+ dev_name(dev));
+ if (!init.name)
+ return -ENOMEM;
+
+ /* RCLKSEL Reference PLL output */
+ ret = cci_update_bits(priv->regmap, MAX96717_REG3, MAX96717_RCLKSEL,
+ MAX96717_RCLKSEL, NULL);
+ /* MFP4 fastest slew rate */
+ cci_update_bits(priv->regmap, PIO_SLEW_1, BIT(5) | BIT(4), 0, &ret);
+ if (ret)
+ goto free_init_name;
+
+ priv->clk_hw.init = &init;
+
+ /* Initialize to 24 MHz */
+ ret = max96717_clk_set_rate(&priv->clk_hw,
+ MAX96717_DEFAULT_CLKOUT_RATE, 0);
+ if (ret < 0)
+ goto free_init_name;
+
+ ret = devm_clk_hw_register(dev, &priv->clk_hw);
+ kfree(init.name);
+ if (ret)
+ return dev_err_probe(dev, ret, "Cannot register clock HW\n");
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+ &priv->clk_hw);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Cannot add OF clock provider\n");
+
+ return 0;
+
+free_init_name:
+ kfree(init.name);
+ return ret;
+}
+
+static int max96717_init_csi_lanes(struct max96717_priv *priv)
+{
+ struct v4l2_mbus_config_mipi_csi2 *mipi = &priv->mipi_csi2;
+ unsigned long lanes_used = 0;
+ unsigned int nlanes, lane, val = 0;
+ int ret;
+
+ nlanes = mipi->num_data_lanes;
+
+ ret = cci_update_bits(priv->regmap, MAX96717_MIPI_RX1,
+ MAX96717_MIPI_LANES_CNT,
+ FIELD_PREP(MAX96717_MIPI_LANES_CNT,
+ nlanes - 1), NULL);
+
+ /* lanes polarity */
+ for (lane = 0; lane < nlanes + 1; lane++) {
+ if (!mipi->lane_polarities[lane])
+ continue;
+ /* Clock lane */
+ if (lane == 0)
+ val |= BIT(2);
+ else if (lane < 3)
+ val |= BIT(lane - 1);
+ else
+ val |= BIT(lane);
+ }
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX5,
+ MAX96717_PHY2_LANES_POL,
+ FIELD_PREP(MAX96717_PHY2_LANES_POL, val), &ret);
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX4,
+ MAX96717_PHY1_LANES_POL,
+ FIELD_PREP(MAX96717_PHY1_LANES_POL,
+ val >> 3), &ret);
+ /* lanes mapping */
+ for (lane = 0, val = 0; lane < nlanes; lane++) {
+ val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
+ lanes_used |= BIT(mipi->data_lanes[lane] - 1);
+ }
+
+ /*
+ * Unused lanes need to be mapped as well to not have
+ * the same lanes mapped twice.
+ */
+ for (; lane < 4; lane++) {
+ unsigned int idx = find_first_zero_bit(&lanes_used, 4);
+
+ val |= idx << (lane * 2);
+ lanes_used |= BIT(idx);
+ }
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX3,
+ MAX96717_PHY1_LANES_MAP,
+ FIELD_PREP(MAX96717_PHY1_LANES_MAP, val), &ret);
+
+ return cci_update_bits(priv->regmap, MAX96717_MIPI_RX2,
+ MAX96717_PHY2_LANES_MAP,
+ FIELD_PREP(MAX96717_PHY2_LANES_MAP, val >> 4),
+ &ret);
+}
+
+static int max96717_hw_init(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 dev_id, val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_DEV_ID, &dev_id, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read the device id\n");
+
+ if (dev_id != MAX96717_DEVICE_ID && dev_id != MAX96717F_DEVICE_ID)
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "Unsupported device id got %x\n", (u8)dev_id);
+
+ ret = cci_read(priv->regmap, MAX96717_DEV_REV, &val, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read device revision");
+
+ dev_dbg(dev, "Found %x (rev %lx)\n", (u8)dev_id,
+ (u8)val & MAX96717_DEV_REV_MASK);
+
+ ret = cci_read(priv->regmap, MAX96717_MIPI_RX_EXT11, &val, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read mipi rx extension");
+
+ if (!(val & MAX96717_TUN_MODE))
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "Only supporting tunnel mode");
+
+ return max96717_init_csi_lanes(priv);
+}
+
+static int max96717_parse_dt(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct fwnode_handle *ep_fwnode;
+ unsigned char num_data_lanes;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96717_PAD_SINK, 0, 0);
+ if (!ep_fwnode)
+ return dev_err_probe(dev, -ENOENT, "no endpoint found\n");
+
+ ret = v4l2_fwnode_endpoint_parse(ep_fwnode, &vep);
+
+ fwnode_handle_put(ep_fwnode);
+
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to parse sink endpoint");
+
+ num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
+ if (num_data_lanes < 1 || num_data_lanes > 4)
+ return dev_err_probe(dev, -EINVAL,
+ "Invalid data lanes must be 1 to 4\n");
+
+ memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2));
+
+ return 0;
+}
+
+static int max96717_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct max96717_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->client = client;
+ priv->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(priv->regmap)) {
+ ret = PTR_ERR(priv->regmap);
+ return dev_err_probe(dev, ret, "Failed to init regmap\n");
+ }
+
+ ret = max96717_parse_dt(priv);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to parse the dt\n");
+
+ ret = max96717_hw_init(priv);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to initialize the hardware\n");
+
+ ret = max96717_gpiochip_probe(priv);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to init gpiochip\n");
+
+ ret = max96717_register_clkout(priv);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register clkout\n");
+
+ ret = max96717_subdev_init(priv);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to initialize v4l2 subdev\n");
+
+ ret = max96717_i2c_mux_init(priv);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to add remote i2c adapter\n");
+ max96717_subdev_uninit(priv);
+ }
+
+ return ret;
+}
+
+static void max96717_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct max96717_priv *priv = sd_to_max96717(sd);
+
+ max96717_subdev_uninit(priv);
+ i2c_mux_del_adapters(priv->mux);
+}
+
+static const struct of_device_id max96717_of_ids[] = {
+ { .compatible = "maxim,max96717f" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max96717_of_ids);
+
+static struct i2c_driver max96717_i2c_driver = {
+ .driver = {
+ .name = "max96717",
+ .of_match_table = max96717_of_ids,
+ },
+ .probe = max96717_probe,
+ .remove = max96717_remove,
+};
+
+module_i2c_driver(max96717_i2c_driver);
+
+MODULE_DESCRIPTION("Maxim GMSL2 MAX96717 Serializer Driver");
+MODULE_AUTHOR("Julien Massot <[email protected]>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c
index 8deb28b55983..46b9ce111676 100644
--- a/drivers/media/i2c/ov5693.c
+++ b/drivers/media/i2c/ov5693.c
@@ -141,7 +141,6 @@ struct ov5693_device {
struct gpio_desc *reset;
struct gpio_desc *powerdown;
- struct gpio_desc *privacy_led;
struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES];
struct clk *xvclk;
@@ -657,7 +656,6 @@ static int ov5693_sensor_init(struct ov5693_device *ov5693)
static void ov5693_sensor_powerdown(struct ov5693_device *ov5693)
{
- gpiod_set_value_cansleep(ov5693->privacy_led, 0);
gpiod_set_value_cansleep(ov5693->reset, 1);
gpiod_set_value_cansleep(ov5693->powerdown, 1);
@@ -687,7 +685,6 @@ static int ov5693_sensor_powerup(struct ov5693_device *ov5693)
gpiod_set_value_cansleep(ov5693->powerdown, 0);
gpiod_set_value_cansleep(ov5693->reset, 0);
- gpiod_set_value_cansleep(ov5693->privacy_led, 1);
usleep_range(5000, 7500);
@@ -1201,13 +1198,6 @@ static int ov5693_configure_gpios(struct ov5693_device *ov5693)
return PTR_ERR(ov5693->powerdown);
}
- ov5693->privacy_led = devm_gpiod_get_optional(ov5693->dev, "privacy-led",
- GPIOD_OUT_LOW);
- if (IS_ERR(ov5693->privacy_led)) {
- dev_err(ov5693->dev, "Error fetching privacy-led GPIO\n");
- return PTR_ERR(ov5693->privacy_led);
- }
-
return 0;
}
diff --git a/drivers/media/i2c/tw9910.c b/drivers/media/i2c/tw9910.c
index 905af98c7d53..6dffaaa9ed56 100644
--- a/drivers/media/i2c/tw9910.c
+++ b/drivers/media/i2c/tw9910.c
@@ -212,11 +212,6 @@
* structure
*/
-struct regval_list {
- unsigned char reg_num;
- unsigned char value;
-};
-
struct tw9910_scale_ctrl {
char *name;
unsigned short width;
diff --git a/drivers/media/pci/cx18/cx18-scb.h b/drivers/media/pci/cx18/cx18-scb.h
index f7105421dd25..841edc0712ab 100644
--- a/drivers/media/pci/cx18/cx18-scb.h
+++ b/drivers/media/pci/cx18/cx18-scb.h
@@ -258,7 +258,7 @@ struct cx18_scb {
struct cx18_mailbox ppu2epu_mb;
struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS];
- struct cx18_mdl_ent cpu_mdl[1];
+ struct cx18_mdl_ent cpu_mdl[];
};
void cx18_init_scb(struct cx18 *cx);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
index 23c537e7ce1e..e47f84c30e10 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c
@@ -163,8 +163,8 @@ int ipu6_buttress_ipc_reset(struct ipu6_device *isp,
writel(ENTRY, isp->base + ipc->csr_out);
break;
default:
- dev_warn_ratelimited(&isp->pdev->dev,
- "Unexpected CSR 0x%x\n", val);
+ dev_dbg_ratelimited(&isp->pdev->dev,
+ "Unexpected CSR 0x%x\n", val);
break;
}
} while (retries--);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
index b9ce4324996d..051898ce53f4 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c
@@ -345,42 +345,61 @@ static int ipu6_isys_csi2_set_stream(struct v4l2_subdev *sd,
return ret;
}
-static int set_stream(struct v4l2_subdev *sd, int enable)
+static int ipu6_isys_csi2_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
{
struct ipu6_isys_subdev *asd = to_ipu6_isys_subdev(sd);
struct ipu6_isys_csi2 *csi2 = to_ipu6_isys_csi2(asd);
- struct device *dev = &csi2->isys->adev->auxdev.dev;
struct ipu6_isys_csi2_timing timing = { };
- unsigned int nlanes;
+ struct v4l2_subdev *remote_sd;
+ struct media_pad *remote_pad;
+ u64 sink_streams;
int ret;
- dev_dbg(dev, "csi2 stream %s callback\n", enable ? "on" : "off");
-
- if (!enable) {
- csi2->stream_count--;
- if (csi2->stream_count)
- return 0;
-
- ipu6_isys_csi2_set_stream(sd, &timing, 0, enable);
- return 0;
- }
-
- if (csi2->stream_count) {
- csi2->stream_count++;
- return 0;
- }
+ remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+ remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
- nlanes = csi2->nlanes;
+ sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
+ CSI2_PAD_SINK,
+ &streams_mask);
ret = ipu6_isys_csi2_calc_timing(csi2, &timing, CSI2_ACCINV);
if (ret)
return ret;
- ret = ipu6_isys_csi2_set_stream(sd, &timing, nlanes, enable);
+ ret = ipu6_isys_csi2_set_stream(sd, &timing, csi2->nlanes, true);
if (ret)
return ret;
- csi2->stream_count++;
+ ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index,
+ sink_streams);
+ if (ret) {
+ ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ipu6_isys_csi2_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct v4l2_subdev *remote_sd;
+ struct media_pad *remote_pad;
+ u64 sink_streams;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state, CSI2_PAD_SRC,
+ CSI2_PAD_SINK,
+ &streams_mask);
+
+ remote_pad = media_pad_remote_pad_first(&sd->entity.pads[CSI2_PAD_SINK]);
+ remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+ ipu6_isys_csi2_set_stream(sd, NULL, 0, false);
+
+ v4l2_subdev_disable_streams(remote_sd, remote_pad->index, sink_streams);
return 0;
}
@@ -475,10 +494,6 @@ static int ipu6_isys_csi2_get_sel(struct v4l2_subdev *sd,
return ret;
}
-static const struct v4l2_subdev_video_ops csi2_sd_video_ops = {
- .s_stream = set_stream,
-};
-
static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = {
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ipu6_isys_subdev_set_fmt,
@@ -486,11 +501,12 @@ static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = {
.set_selection = ipu6_isys_csi2_set_sel,
.enum_mbus_code = ipu6_isys_subdev_enum_mbus_code,
.set_routing = ipu6_isys_subdev_set_routing,
+ .enable_streams = ipu6_isys_csi2_enable_streams,
+ .disable_streams = ipu6_isys_csi2_disable_streams,
};
static const struct v4l2_subdev_ops csi2_sd_ops = {
.core = &csi2_sd_core_ops,
- .video = &csi2_sd_video_ops,
.pad = &csi2_sd_pad_ops,
};
@@ -631,33 +647,3 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
return 0;
}
-
-void ipu6_isys_set_csi2_streams_status(struct ipu6_isys_video *av, bool status)
-{
- struct ipu6_isys_stream *stream = av->stream;
- struct v4l2_subdev *sd = &stream->asd->sd;
- struct v4l2_subdev_state *state;
- struct media_pad *r_pad;
- unsigned int i;
- u32 r_stream;
-
- r_pad = media_pad_remote_pad_first(&av->pad);
- r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, r_pad->index);
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
-
- for (i = 0; i < state->stream_configs.num_configs; i++) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
-
- if (cfg->pad == r_pad->index && r_stream == cfg->stream) {
- dev_dbg(&av->isys->adev->auxdev.dev,
- "%s: pad:%u, stream:%u, status:%u\n",
- sd->entity.name, r_pad->index, r_stream,
- status);
- cfg->enabled = status;
- }
- }
-
- v4l2_subdev_unlock_state(state);
-}
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
index eba6b29386ea..bc8594c94f99 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h
@@ -45,7 +45,6 @@ struct ipu6_isys_csi2 {
u32 receiver_errors;
unsigned int nlanes;
unsigned int port;
- unsigned int stream_count;
};
struct ipu6_isys_csi2_timing {
@@ -77,6 +76,5 @@ int ipu6_isys_csi2_get_remote_desc(u32 source_stream,
struct ipu6_isys_csi2 *csi2,
struct media_entity *source_entity,
struct v4l2_mbus_frame_desc_entry *entry);
-void ipu6_isys_set_csi2_streams_status(struct ipu6_isys_video *av, bool status);
#endif /* IPU6_ISYS_CSI2_H */
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
index 4bd4e324abc9..03dbb0e0ea79 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
@@ -551,7 +551,6 @@ static int start_streaming(struct vb2_queue *q, unsigned int count)
stream->nr_queues);
list_add(&aq->node, &stream->queues);
- ipu6_isys_set_csi2_streams_status(av, true);
ipu6_isys_configure_stream_watermark(av, true);
ipu6_isys_update_stream_watermark(av, true);
@@ -598,8 +597,6 @@ static void stop_streaming(struct vb2_queue *q)
struct ipu6_isys_video *av = ipu6_isys_queue_to_video(aq);
struct ipu6_isys_stream *stream = av->stream;
- ipu6_isys_set_csi2_streams_status(av, false);
-
mutex_lock(&stream->mutex);
ipu6_isys_update_stream_watermark(av, false);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index c8a33e1e910c..e41d40243abd 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -990,9 +990,7 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
struct v4l2_subdev_state *subdev_state;
struct device *dev = &av->isys->adev->auxdev.dev;
struct v4l2_subdev *sd;
- struct v4l2_subdev *ssd;
struct media_pad *r_pad;
- struct media_pad *s_pad;
u32 sink_pad, sink_stream;
u64 r_stream;
u64 stream_mask = 0;
@@ -1003,7 +1001,6 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
if (WARN(!stream->source_entity, "No source entity for stream\n"))
return -ENODEV;
- ssd = media_entity_to_v4l2_subdev(stream->source_entity);
sd = &stream->asd->sd;
r_pad = media_pad_remote_pad_first(&av->pad);
r_stream = ipu6_isys_get_src_stream_by_src_pad(sd, r_pad->index);
@@ -1017,27 +1014,15 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
if (ret)
return ret;
- s_pad = media_pad_remote_pad_first(&stream->asd->pad[sink_pad]);
-
stream_mask = get_stream_mask_by_pipeline(av);
if (!state) {
stop_streaming_firmware(av);
- /* stop external sub-device now. */
- dev_dbg(dev, "disable streams 0x%llx of %s\n", stream_mask,
- ssd->name);
- ret = v4l2_subdev_disable_streams(ssd, s_pad->index,
- stream_mask);
- if (ret) {
- dev_err(dev, "disable streams of %s failed with %d\n",
- ssd->name, ret);
- return ret;
- }
-
/* stop sub-device which connects with video */
- dev_dbg(dev, "stream off entity %s pad:%d\n", sd->name,
- r_pad->index);
- ret = v4l2_subdev_call(sd, video, s_stream, state);
+ dev_dbg(dev, "stream off entity %s pad:%d mask:0x%llx\n",
+ sd->name, r_pad->index, stream_mask);
+ ret = v4l2_subdev_disable_streams(sd, r_pad->index,
+ stream_mask);
if (ret) {
dev_err(dev, "stream off %s failed with %d\n", sd->name,
ret);
@@ -1052,34 +1037,20 @@ int ipu6_isys_video_set_streaming(struct ipu6_isys_video *av, int state,
}
/* start sub-device which connects with video */
- dev_dbg(dev, "stream on %s pad %d\n", sd->name, r_pad->index);
- ret = v4l2_subdev_call(sd, video, s_stream, state);
+ dev_dbg(dev, "stream on %s pad %d mask 0x%llx\n", sd->name,
+ r_pad->index, stream_mask);
+ ret = v4l2_subdev_enable_streams(sd, r_pad->index, stream_mask);
if (ret) {
dev_err(dev, "stream on %s failed with %d\n", sd->name,
ret);
goto out_media_entity_stop_streaming_firmware;
}
-
- /* start external sub-device now. */
- dev_dbg(dev, "enable streams 0x%llx of %s\n", stream_mask,
- ssd->name);
- ret = v4l2_subdev_enable_streams(ssd, s_pad->index,
- stream_mask);
- if (ret) {
- dev_err(dev,
- "enable streams 0x%llx of %s failed with %d\n",
- stream_mask, stream->source_entity->name, ret);
- goto out_media_entity_stop_streaming;
- }
}
av->streaming = state;
return 0;
-out_media_entity_stop_streaming:
- v4l2_subdev_disable_streams(sd, r_pad->index, BIT(r_stream));
-
out_media_entity_stop_streaming_firmware:
stop_streaming_firmware(av);
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index ba503d820e48..ecc20cd89926 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -371,33 +371,6 @@ int ivtv_msleep_timeout(unsigned int msecs, int intr)
return 0;
}
-/* Release ioremapped memory */
-static void ivtv_iounmap(struct ivtv *itv)
-{
- if (itv == NULL)
- return;
-
- /* Release registers memory */
- if (itv->reg_mem != NULL) {
- IVTV_DEBUG_INFO("releasing reg_mem\n");
- iounmap(itv->reg_mem);
- itv->reg_mem = NULL;
- }
- /* Release io memory */
- if (itv->has_cx23415 && itv->dec_mem != NULL) {
- IVTV_DEBUG_INFO("releasing dec_mem\n");
- iounmap(itv->dec_mem);
- }
- itv->dec_mem = NULL;
-
- /* Release io memory */
- if (itv->enc_mem != NULL) {
- IVTV_DEBUG_INFO("releasing enc_mem\n");
- iounmap(itv->enc_mem);
- itv->enc_mem = NULL;
- }
-}
-
/* Hauppauge card? get values from tveeprom */
void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
{
@@ -833,7 +806,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
IVTV_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(pdev)) {
+ if (pcim_enable_device(pdev)) {
IVTV_ERR("Can't enable device!\n");
return -EIO;
}
@@ -841,24 +814,24 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
IVTV_ERR("No suitable DMA available.\n");
return -EIO;
}
- if (!request_mem_region(itv->base_addr, IVTV_ENCODER_SIZE, "ivtv encoder")) {
+ if (!devm_request_mem_region(&pdev->dev, itv->base_addr,
+ IVTV_ENCODER_SIZE, "ivtv encoder")) {
IVTV_ERR("Cannot request encoder memory region.\n");
return -EIO;
}
- if (!request_mem_region(itv->base_addr + IVTV_REG_OFFSET,
- IVTV_REG_SIZE, "ivtv registers")) {
+ if (!devm_request_mem_region(&pdev->dev,
+ itv->base_addr + IVTV_REG_OFFSET,
+ IVTV_REG_SIZE, "ivtv registers")) {
IVTV_ERR("Cannot request register memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
return -EIO;
}
if (itv->has_cx23415 &&
- !request_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE, "ivtv decoder")) {
+ !devm_request_mem_region(&pdev->dev,
+ itv->base_addr + IVTV_DECODER_OFFSET,
+ IVTV_DECODER_SIZE, "ivtv decoder")) {
IVTV_ERR("Cannot request decoder memory region.\n");
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
return -EIO;
}
@@ -870,11 +843,6 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_ERR("Bus Mastering is not enabled\n");
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
return -ENXIO;
}
}
@@ -1033,37 +1001,37 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
/* PCI Device Setup */
retval = ivtv_setup_pci(itv, pdev, pci_id);
- if (retval == -EIO)
+ if (retval == -EIO || retval == -ENXIO)
goto free_worker;
- if (retval == -ENXIO)
- goto free_mem;
/* map io memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE);
- itv->enc_mem = ioremap(itv->base_addr + IVTV_ENCODER_OFFSET,
- IVTV_ENCODER_SIZE);
+ itv->enc_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_ENCODER_OFFSET,
+ IVTV_ENCODER_SIZE);
if (!itv->enc_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 encoder memory\n");
IVTV_ERR("Each capture card with a CX23415/6 needs 8 MB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_mem;
+ goto free_worker;
}
if (itv->has_cx23415) {
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- itv->dec_mem = ioremap(itv->base_addr + IVTV_DECODER_OFFSET,
- IVTV_DECODER_SIZE);
+ itv->dec_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_DECODER_OFFSET,
+ IVTV_DECODER_SIZE);
if (!itv->dec_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415 decoder memory\n");
IVTV_ERR("Each capture card with a CX23415 needs 8 MB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_mem;
+ goto free_worker;
}
}
else {
@@ -1073,26 +1041,27 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
/* map registers memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n",
(u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- itv->reg_mem =
- ioremap(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
+ itv->reg_mem = devm_ioremap(&pdev->dev,
+ itv->base_addr + IVTV_REG_OFFSET,
+ IVTV_REG_SIZE);
if (!itv->reg_mem) {
IVTV_ERR("ioremap failed. Can't get a window into CX23415/6 register space\n");
IVTV_ERR("Each capture card with a CX23415/6 needs 64 kB of vmalloc address space for this window\n");
IVTV_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n");
IVTV_ERR("Use the vmalloc= kernel command line option to set VmallocTotal to a larger value\n");
retval = -ENOMEM;
- goto free_io;
+ goto free_worker;
}
retval = ivtv_gpio_init(itv);
if (retval)
- goto free_io;
+ goto free_worker;
/* active i2c */
IVTV_DEBUG_INFO("activating i2c...\n");
if (init_ivtv_i2c(itv)) {
IVTV_ERR("Could not initialize i2c\n");
- goto free_io;
+ goto free_worker;
}
if (itv->card->hw_all & IVTV_HW_TVEEPROM) {
@@ -1277,13 +1246,6 @@ free_irq:
free_i2c:
v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
exit_ivtv_i2c(itv);
-free_io:
- ivtv_iounmap(itv);
-free_mem:
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
free_worker:
kthread_stop(itv->irq_worker_task);
err:
@@ -1439,14 +1401,7 @@ static void ivtv_remove(struct pci_dev *pdev)
exit_ivtv_i2c(itv);
free_irq(itv->pdev->irq, (void *)itv);
- ivtv_iounmap(itv);
-
- release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
- release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
- if (itv->has_cx23415)
- release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- pci_disable_device(itv->pdev);
for (i = 0; i < IVTV_VBI_FRAMES; i++)
kfree(itv->vbi.sliced_mpeg_data[i]);
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c
index 4202c3a47d33..cfa28d035586 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -21,6 +21,7 @@
#include "ivtv-ioctl.h"
#include "ivtv-cards.h"
#include "ivtv-firmware.h"
+#include <linux/lockdep.h>
#include <media/v4l2-event.h>
#include <media/i2c/saa7115.h>
@@ -190,12 +191,27 @@ static void ivtv_update_pgm_info(struct ivtv *itv)
itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
}
+static void ivtv_schedule(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+ DEFINE_WAIT(wait);
+
+ lockdep_assert_held(&itv->serialize_lock);
+
+ mutex_unlock(&itv->serialize_lock);
+ prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
+ /* New buffers might have become free before we were added to the waitqueue */
+ if (!s->q_free.buffers)
+ schedule();
+ finish_wait(&s->waitq, &wait);
+ mutex_lock(&itv->serialize_lock);
+}
+
static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, int *err)
{
struct ivtv *itv = s->itv;
struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
struct ivtv_buffer *buf;
- DEFINE_WAIT(wait);
*err = 0;
while (1) {
@@ -258,13 +274,7 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
}
/* wait for more data to arrive */
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become available before we were added to the waitqueue */
- if (!s->q_full.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
+ ivtv_schedule(s);
if (signal_pending(current)) {
/* return if a signal was received */
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
@@ -533,6 +543,25 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
return 0;
}
+static int ivtv_schedule_dma(struct ivtv_stream *s)
+{
+ struct ivtv *itv = s->itv;
+ int got_sig;
+ DEFINE_WAIT(wait);
+
+ lockdep_assert_held(&itv->serialize_lock);
+
+ mutex_unlock(&itv->serialize_lock);
+ prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
+ while (!(got_sig = signal_pending(current)) &&
+ test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
+ schedule();
+ finish_wait(&itv->dma_waitq, &wait);
+ mutex_lock(&itv->serialize_lock);
+
+ return got_sig;
+}
+
static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos)
{
struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -544,7 +573,6 @@ static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t
int bytes_written = 0;
int mode;
int rc;
- DEFINE_WAIT(wait);
IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
@@ -618,13 +646,7 @@ retry:
break;
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
- /* New buffers might have become free before we were added to the waitqueue */
- if (!s->q_free.buffers)
- schedule();
- finish_wait(&s->waitq, &wait);
- mutex_lock(&itv->serialize_lock);
+ ivtv_schedule(s);
if (signal_pending(current)) {
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
return -EINTR;
@@ -674,20 +696,10 @@ retry:
if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
if (s->q_full.length >= itv->dma_data_req_size) {
- int got_sig;
-
if (mode == OUT_YUV)
ivtv_yuv_setup_stream_frame(itv);
- mutex_unlock(&itv->serialize_lock);
- prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
- while (!(got_sig = signal_pending(current)) &&
- test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
- schedule();
- }
- finish_wait(&itv->dma_waitq, &wait);
- mutex_lock(&itv->serialize_lock);
- if (got_sig) {
+ if (ivtv_schedule_dma(s)) {
IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
return -EINTR;
}
diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
index 99b9f55ca829..f467a00492f4 100644
--- a/drivers/media/pci/ivtv/ivtv-udma.c
+++ b/drivers/media/pci/ivtv/ivtv-udma.c
@@ -131,6 +131,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
/* Fill SG List with new values */
if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
+ IVTV_DEBUG_WARN("%s: could not allocate bounce buffers for highmem userspace buffers\n",
+ __func__);
unpin_user_pages(dma->map, dma->page_count);
dma->page_count = 0;
return -ENOMEM;
@@ -139,6 +141,12 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
/* Map SG List */
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE);
+ if (!dma->SG_length) {
+ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+ unpin_user_pages(dma->map, dma->page_count);
+ dma->page_count = 0;
+ return -EINVAL;
+ }
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
index 582146f8d70d..2d9274537725 100644
--- a/drivers/media/pci/ivtv/ivtv-yuv.c
+++ b/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -114,6 +114,12 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
}
dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
dma->page_count, DMA_TO_DEVICE);
+ if (!dma->SG_length) {
+ IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+ unpin_user_pages(dma->map, dma->page_count);
+ dma->page_count = 0;
+ return -EINVAL;
+ }
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 410477e3e621..d1ab7fee0d05 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -281,10 +281,10 @@ static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
/* Map User DMA */
if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
mutex_unlock(&itv->udma.lock);
- IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with pin_user_pages: %d bytes, %d pages returned\n",
- size_in_bytes, itv->udma.page_count);
+ IVTVFB_WARN("%s, Error in ivtv_udma_setup: %d bytes, %d pages returned\n",
+ __func__, size_in_bytes, itv->udma.page_count);
- /* pin_user_pages must have failed completely */
+ /* pin_user_pages or DMA must have failed completely */
return -EIO;
}
diff --git a/drivers/media/platform/allegro-dvt/nal-hevc.h b/drivers/media/platform/allegro-dvt/nal-hevc.h
index eb46f12aae80..361e2f55c254 100644
--- a/drivers/media/platform/allegro-dvt/nal-hevc.h
+++ b/drivers/media/platform/allegro-dvt/nal-hevc.h
@@ -96,10 +96,11 @@ struct nal_hevc_vps {
unsigned int extension_data_flag;
};
+#define N_HRD_PARAMS 1
struct nal_hevc_sub_layer_hrd_parameters {
- unsigned int bit_rate_value_minus1[1];
- unsigned int cpb_size_value_minus1[1];
- unsigned int cbr_flag[1];
+ unsigned int bit_rate_value_minus1[N_HRD_PARAMS];
+ unsigned int cpb_size_value_minus1[N_HRD_PARAMS];
+ unsigned int cbr_flag[N_HRD_PARAMS];
};
struct nal_hevc_hrd_parameters {
diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
index d3425de7bccd..4769c053c6c2 100644
--- a/drivers/media/platform/amphion/vpu_malone.c
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -207,11 +207,6 @@ struct vpu_malone_dbglog_desc {
u32 reserved;
};
-struct vpu_malone_frame_buffer {
- u32 addr;
- u32 size;
-};
-
struct vpu_malone_udata {
u32 base;
u32 total_size;
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 96b35a5d6174..5adcef80c698 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -724,10 +724,6 @@ static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = {
/*
* Queue operations
*/
-struct vb2_dc_conf {
- struct device *dev;
-};
-
static int deinterlace_queue_setup(struct vb2_queue *vq,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], struct device *alloc_devs[])
diff --git a/drivers/media/platform/nvidia/tegra-vde/h264.c b/drivers/media/platform/nvidia/tegra-vde/h264.c
index cfea5572a1b8..d8812fc06c67 100644
--- a/drivers/media/platform/nvidia/tegra-vde/h264.c
+++ b/drivers/media/platform/nvidia/tegra-vde/h264.c
@@ -19,11 +19,6 @@
#define FLAG_B_FRAME 0x1
#define FLAG_REFERENCE 0x2
-struct tegra_vde_h264_frame {
- unsigned int frame_num;
- unsigned int flags;
-};
-
struct tegra_vde_h264_decoder_ctx {
unsigned int dpb_frames_nb;
unsigned int dpb_ref_frames_with_earlier_poc_nb;
diff --git a/drivers/media/platform/nvidia/tegra-vde/vde.h b/drivers/media/platform/nvidia/tegra-vde/vde.h
index 0fbb1f3d2c88..b2890484b7c3 100644
--- a/drivers/media/platform/nvidia/tegra-vde/vde.h
+++ b/drivers/media/platform/nvidia/tegra-vde/vde.h
@@ -47,7 +47,6 @@ struct iommu_group;
struct iommu_domain;
struct reset_control;
struct dma_buf_attachment;
-struct tegra_vde_h264_frame;
struct tegra_vde_h264_decoder_ctx;
struct tegra_video_frame {
diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c
index 662c81b6d0b5..70808049d2e8 100644
--- a/drivers/media/platform/rockchip/rga/rga-buf.c
+++ b/drivers/media/platform/rockchip/rga/rga-buf.c
@@ -195,6 +195,11 @@ static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count)
return ret;
}
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
+ ctx->osequence = 0;
+ else
+ ctx->csequence = 0;
+
return 0;
}
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 00fdfa9e10bc..0e768f3e9eda 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -43,6 +43,8 @@ static void device_run(void *prv)
rga->curr = ctx;
src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+ src->sequence = ctx->osequence++;
+
dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
rga_hw_start(rga, vb_to_rga(src), vb_to_rga(dst));
@@ -75,6 +77,8 @@ static irqreturn_t rga_isr(int irq, void *prv)
v4l2_m2m_buf_copy_metadata(src, dst, true);
+ dst->sequence = ctx->csequence++;
+
v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx);
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 3502dff6055c..8105bb2efe57 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -57,6 +57,9 @@ struct rga_ctx {
struct rga_frame out;
struct v4l2_ctrl_handler ctrl_handler;
+ int osequence;
+ int csequence;
+
/* Control values */
u32 op;
u32 hflip;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
index e45a213baf49..91301d17d356 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
@@ -173,7 +173,7 @@ static void rkisp1_gasket_disable(struct rkisp1_device *rkisp1)
* or at the frame end interrupt
*/
static void rkisp1_config_ism(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state)
+ const struct v4l2_subdev_state *sd_state)
{
const struct v4l2_rect *src_crop =
v4l2_subdev_state_get_crop(sd_state,
@@ -201,7 +201,7 @@ static void rkisp1_config_ism(struct rkisp1_isp *isp,
* configure ISP blocks with input format, size......
*/
static int rkisp1_config_isp(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state,
+ const struct v4l2_subdev_state *sd_state,
enum v4l2_mbus_type mbus_type, u32 mbus_flags)
{
struct rkisp1_device *rkisp1 = isp->rkisp1;
@@ -309,7 +309,7 @@ static int rkisp1_config_isp(struct rkisp1_isp *isp,
if (src_fmt->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
rkisp1_params_disable(&rkisp1->params);
} else {
- struct v4l2_mbus_framefmt *src_frm;
+ const struct v4l2_mbus_framefmt *src_frm;
src_frm = v4l2_subdev_state_get_format(sd_state,
RKISP1_ISP_PAD_SOURCE_VIDEO);
@@ -429,7 +429,7 @@ static void rkisp1_config_clk(struct rkisp1_isp *isp)
}
static int rkisp1_isp_start(struct rkisp1_isp *isp,
- struct v4l2_subdev_state *sd_state,
+ const struct v4l2_subdev_state *sd_state,
struct media_pad *source)
{
struct rkisp1_device *rkisp1 = isp->rkisp1;
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
index 6f3931ca5b51..1fa991227fa9 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
@@ -135,11 +135,11 @@ static void rkisp1_dcrop_disable(struct rkisp1_resizer *rsz,
/* configure dual-crop unit */
static void rkisp1_dcrop_config(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_state *sd_state)
+ const struct v4l2_subdev_state *sd_state)
{
struct rkisp1_device *rkisp1 = rsz->rkisp1;
- struct v4l2_mbus_framefmt *sink_fmt;
- struct v4l2_rect *sink_crop;
+ const struct v4l2_mbus_framefmt *sink_fmt;
+ const struct v4l2_rect *sink_crop;
u32 dc_ctrl;
sink_crop = v4l2_subdev_state_get_crop(sd_state, RKISP1_RSZ_PAD_SINK);
@@ -264,7 +264,7 @@ static void rkisp1_rsz_config_regs(struct rkisp1_resizer *rsz,
}
static void rkisp1_rsz_config(struct rkisp1_resizer *rsz,
- struct v4l2_subdev_state *sd_state,
+ const struct v4l2_subdev_state *sd_state,
enum rkisp1_shadow_regs_when when)
{
const struct rkisp1_rsz_yuv_mbus_info *sink_yuv_info, *src_yuv_info;
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index a96de5d388a1..a1687b868a44 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -348,8 +348,8 @@ static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
}
dma->xt.frame_size = 1;
- dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp;
- dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size;
+ dma->sgl.size = dma->format.width * dma->fmtinfo->bpp;
+ dma->sgl.icg = dma->format.bytesperline - dma->sgl.size;
dma->xt.numf = dma->format.height;
desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags);
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
index 9c6d4c18d1a9..18f77e1a7b39 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.h
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -97,7 +97,7 @@ struct xvip_dma {
struct dma_chan *dma;
unsigned int align;
struct dma_interleaved_template xt;
- struct data_chunk sgl[1];
+ struct data_chunk sgl;
};
#define to_xvip_dma(vdev) container_of(vdev, struct xvip_dma, video)
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 0b55314a8082..8f1361bcce3a 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1148,10 +1148,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
- if (!mutex_is_locked(&ictx->lock)) {
- unlock = true;
- mutex_lock(&ictx->lock);
- }
+ unlock = mutex_trylock(&ictx->lock);
retval = send_packet(ictx);
if (retval)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index c76ba24c1f55..615f48898300 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -494,7 +494,6 @@ struct mceusb_dev {
u32 carrier;
unsigned char tx_mask;
- char name[128];
char phys[64];
enum mceusb_model_type model;
@@ -1591,16 +1590,10 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
goto out;
}
- snprintf(ir->name, sizeof(ir->name), "%s (%04x:%04x)",
- mceusb_model[ir->model].name ?
- mceusb_model[ir->model].name :
- "Media Center Ed. eHome Infrared Remote Transceiver",
- le16_to_cpu(ir->usbdev->descriptor.idVendor),
- le16_to_cpu(ir->usbdev->descriptor.idProduct));
-
usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
- rc->device_name = ir->name;
+ rc->device_name = mceusb_model[ir->model].name ? :
+ "Media Center Ed. eHome Infrared Remote Transceiver";
rc->input_phys = ir->phys;
usb_to_input_id(ir->usbdev, &rc->input_id);
rc->dev.parent = dev;
diff --git a/drivers/media/spi/gs1662.c b/drivers/media/spi/gs1662.c
index dc5c4c055d29..7adf55fd0707 100644
--- a/drivers/media/spi/gs1662.c
+++ b/drivers/media/spi/gs1662.c
@@ -55,14 +55,6 @@ struct gs_reg_fmt {
struct v4l2_dv_timings format;
};
-struct gs_reg_fmt_custom {
- u16 reg_value;
- __u32 width;
- __u32 height;
- __u64 pixelclock;
- __u32 interlaced;
-};
-
static const struct spi_device_id gs_id[] = {
{ "gs1662", 0 },
{ }
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
index fbf58012becd..22d83ac18eb7 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -23,11 +23,40 @@ static int dvb_usb_force_pid_filter_usage;
module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
+static int dvb_usb_check_bulk_endpoint(struct dvb_usb_device *d, u8 endpoint)
+{
+ if (endpoint) {
+ int ret;
+
+ ret = usb_pipe_type_check(d->udev, usb_sndbulkpipe(d->udev, endpoint));
+ if (ret)
+ return ret;
+ ret = usb_pipe_type_check(d->udev, usb_rcvbulkpipe(d->udev, endpoint));
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static void dvb_usb_clear_halt(struct dvb_usb_device *d, u8 endpoint)
+{
+ if (endpoint) {
+ usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, endpoint));
+ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, endpoint));
+ }
+}
+
static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
{
struct dvb_usb_adapter *adap;
int ret, n, o;
+ ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint);
+ if (ret)
+ return ret;
+ ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint_response);
+ if (ret)
+ return ret;
for (n = 0; n < d->props.num_adapters; n++) {
adap = &d->adapter[n];
adap->dev = d;
@@ -103,10 +132,8 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
* when reloading the driver w/o replugging the device
* sometimes a timeout occurs, this helps
*/
- if (d->props.generic_bulk_ctrl_endpoint != 0) {
- usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
- usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
- }
+ dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint);
+ dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint_response);
return 0;
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
index d269f8bb2dee..268f05fc8691 100644
--- a/drivers/media/usb/dvb-usb/opera1.c
+++ b/drivers/media/usb/dvb-usb/opera1.c
@@ -32,10 +32,6 @@
struct opera1_state {
u32 last_key_pressed;
};
-struct rc_map_opera_table {
- u32 keycode;
- u32 event;
-};
static int dvb_usb_opera1_debug;
module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
diff --git a/drivers/media/usb/go7007/go7007-i2c.c b/drivers/media/usb/go7007/go7007-i2c.c
index 2880370e45c8..f6ce28a4a768 100644
--- a/drivers/media/usb/go7007/go7007-i2c.c
+++ b/drivers/media/usb/go7007/go7007-i2c.c
@@ -33,7 +33,21 @@
/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
* on the Adlink PCI-MPG24, so access is shared between all of them. */
-static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
+static DEFINE_MUTEX(adlink_mpg24_i2c_mutex);
+
+static inline void adlink_mpg24_i2c_lock(struct go7007 *go)
+{
+ /* Bridge the I2C port on this GO7007 to the shared bus */
+ mutex_lock(&adlink_mpg24_i2c_mutex);
+ go7007_write_addr(go, 0x3c82, 0x0020);
+}
+
+static inline void adlink_mpg24_i2c_unlock(struct go7007 *go)
+{
+ /* Isolate the I2C port on this GO7007 from the shared bus */
+ go7007_write_addr(go, 0x3c82, 0x0000);
+ mutex_unlock(&adlink_mpg24_i2c_mutex);
+}
static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
u16 command, int flags, u8 *data)
@@ -56,11 +70,8 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
mutex_lock(&go->hw_lock);
- if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
- /* Bridge the I2C port on this GO7007 to the shared bus */
- mutex_lock(&adlink_mpg24_i2c_lock);
- go7007_write_addr(go, 0x3c82, 0x0020);
- }
+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
+ adlink_mpg24_i2c_lock(go);
/* Wait for I2C adapter to be ready */
for (i = 0; i < 10; ++i) {
@@ -116,11 +127,8 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
ret = 0;
i2c_done:
- if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
- /* Isolate the I2C port on this GO7007 from the shared bus */
- go7007_write_addr(go, 0x3c82, 0x0000);
- mutex_unlock(&adlink_mpg24_i2c_lock);
- }
+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
+ adlink_mpg24_i2c_unlock(go);
mutex_unlock(&go->hw_lock);
return ret;
}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
index 84cfb5ce8b8d..81d711269ab5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-debugifc.c
@@ -9,11 +9,6 @@
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
-struct debugifc_mask_item {
- const char *name;
- unsigned long msk;
-};
-
static unsigned int debugifc_count_whitespace(const char *buf,
unsigned int count)
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 222f01665f7c..81a9b5473969 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -323,6 +323,13 @@ static int v4l2_async_create_ancillary_links(struct v4l2_async_notifier *n,
sd->entity.function != MEDIA_ENT_F_FLASH)
return 0;
+ if (!n->sd) {
+ dev_warn(notifier_dev(n),
+ "not a sub-device notifier, not creating an ancillary link for %s!\n",
+ dev_name(sd->dev));
+ return 0;
+ }
+
link = media_create_ancillary_link(&n->sd->entity, &sd->entity);
return IS_ERR(link) ? PTR_ERR(link) : 0;
diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
index ee3475bed37f..1ff94affbaf3 100644
--- a/drivers/media/v4l2-core/v4l2-cci.c
+++ b/drivers/media/v4l2-core/v4l2-cci.c
@@ -23,6 +23,15 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
u8 buf[8];
int ret;
+ /*
+ * TODO: Fix smatch. Assign *val to 0 here in order to avoid
+ * failing a smatch check on caller when the caller proceeds to
+ * read *val without initialising it on caller's side. *val is set
+ * to a valid value whenever this function returns 0 but smatch
+ * can't figure that out currently.
+ */
+ *val = 0;
+
if (err && *err)
return *err;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 8470d6eda9a3..4f71199bf592 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -148,6 +148,23 @@ static int subdev_close(struct file *file)
}
#endif /* CONFIG_VIDEO_V4L2_SUBDEV_API */
+static void v4l2_subdev_enable_privacy_led(struct v4l2_subdev *sd)
+{
+#if IS_REACHABLE(CONFIG_LEDS_CLASS)
+ if (!IS_ERR_OR_NULL(sd->privacy_led))
+ led_set_brightness(sd->privacy_led,
+ sd->privacy_led->max_brightness);
+#endif
+}
+
+static void v4l2_subdev_disable_privacy_led(struct v4l2_subdev *sd)
+{
+#if IS_REACHABLE(CONFIG_LEDS_CLASS)
+ if (!IS_ERR_OR_NULL(sd->privacy_led))
+ led_set_brightness(sd->privacy_led, 0);
+#endif
+}
+
static inline int check_which(u32 which)
{
if (which != V4L2_SUBDEV_FORMAT_TRY &&
@@ -434,12 +451,8 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable)
* The .s_stream() operation must never be called to start or stop an
* already started or stopped subdev. Catch offenders but don't return
* an error yet to avoid regressions.
- *
- * As .s_stream() is mutually exclusive with the .enable_streams() and
- * .disable_streams() operation, we can use the enabled_streams field
- * to store the subdev streaming state.
*/
- if (WARN_ON(!!sd->enabled_streams == !!enable))
+ if (WARN_ON(sd->s_stream_enabled == !!enable))
return 0;
ret = sd->ops->video->s_stream(sd, enable);
@@ -450,17 +463,12 @@ static int call_s_stream(struct v4l2_subdev *sd, int enable)
}
if (!ret) {
- sd->enabled_streams = enable ? BIT(0) : 0;
+ sd->s_stream_enabled = enable;
-#if IS_REACHABLE(CONFIG_LEDS_CLASS)
- if (!IS_ERR_OR_NULL(sd->privacy_led)) {
- if (enable)
- led_set_brightness(sd->privacy_led,
- sd->privacy_led->max_brightness);
- else
- led_set_brightness(sd->privacy_led, 0);
- }
-#endif
+ if (enable)
+ v4l2_subdev_enable_privacy_led(sd);
+ else
+ v4l2_subdev_disable_privacy_led(sd);
}
return ret;
@@ -1576,6 +1584,33 @@ int __v4l2_subdev_init_finalize(struct v4l2_subdev *sd, const char *name,
struct lock_class_key *key)
{
struct v4l2_subdev_state *state;
+ struct device *dev = sd->dev;
+ bool has_disable_streams;
+ bool has_enable_streams;
+ bool has_s_stream;
+
+ /* Check that the subdevice implements the required features */
+
+ has_s_stream = v4l2_subdev_has_op(sd, video, s_stream);
+ has_enable_streams = v4l2_subdev_has_op(sd, pad, enable_streams);
+ has_disable_streams = v4l2_subdev_has_op(sd, pad, disable_streams);
+
+ if (has_enable_streams != has_disable_streams) {
+ dev_err(dev,
+ "subdev '%s' must implement both or neither of .enable_streams() and .disable_streams()\n",
+ sd->name);
+ return -EINVAL;
+ }
+
+ if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {
+ if (has_s_stream && !has_enable_streams) {
+ dev_err(dev,
+ "subdev '%s' must implement .enable/disable_streams()\n",
+ sd->name);
+
+ return -EINVAL;
+ }
+ }
state = __v4l2_subdev_state_alloc(sd, name, key);
if (IS_ERR(state))
@@ -2120,43 +2155,55 @@ out:
}
EXPORT_SYMBOL_GPL(v4l2_subdev_routing_validate);
-static int v4l2_subdev_enable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
- u64 streams_mask)
+static void v4l2_subdev_collect_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask,
+ u64 *found_streams,
+ u64 *enabled_streams)
{
- struct device *dev = sd->entity.graph_obj.mdev->dev;
- unsigned int i;
- int ret;
+ if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {
+ *found_streams = BIT_ULL(0);
+ *enabled_streams =
+ (sd->enabled_pads & BIT_ULL(pad)) ? BIT_ULL(0) : 0;
+ return;
+ }
- /*
- * The subdev doesn't implement pad-based stream enable, fall back
- * on the .s_stream() operation. This can only be done for subdevs that
- * have a single source pad, as sd->enabled_streams is global to the
- * subdev.
- */
- if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
- return -EOPNOTSUPP;
+ *found_streams = 0;
+ *enabled_streams = 0;
- for (i = 0; i < sd->entity.num_pads; ++i) {
- if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
- return -EOPNOTSUPP;
- }
+ for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {
+ const struct v4l2_subdev_stream_config *cfg =
+ &state->stream_configs.configs[i];
- if (sd->enabled_streams & streams_mask) {
- dev_dbg(dev, "set of streams %#llx already enabled on %s:%u\n",
- streams_mask, sd->entity.name, pad);
- return -EALREADY;
+ if (cfg->pad != pad || !(streams_mask & BIT_ULL(cfg->stream)))
+ continue;
+
+ *found_streams |= BIT_ULL(cfg->stream);
+ if (cfg->enabled)
+ *enabled_streams |= BIT_ULL(cfg->stream);
}
+}
- /* Start streaming when the first streams are enabled. */
- if (!sd->enabled_streams) {
- ret = v4l2_subdev_call(sd, video, s_stream, 1);
- if (ret)
- return ret;
+static void v4l2_subdev_set_streams_enabled(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask,
+ bool enabled)
+{
+ if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS)) {
+ if (enabled)
+ sd->enabled_pads |= BIT_ULL(pad);
+ else
+ sd->enabled_pads &= ~BIT_ULL(pad);
+ return;
}
- sd->enabled_streams |= streams_mask;
+ for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {
+ struct v4l2_subdev_stream_config *cfg =
+ &state->stream_configs.configs[i];
- return 0;
+ if (cfg->pad == pad && (streams_mask & BIT_ULL(cfg->stream)))
+ cfg->enabled = enabled;
+ }
}
int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,
@@ -2164,44 +2211,44 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,
{
struct device *dev = sd->entity.graph_obj.mdev->dev;
struct v4l2_subdev_state *state;
- u64 found_streams = 0;
- unsigned int i;
+ bool already_streaming;
+ u64 enabled_streams;
+ u64 found_streams;
+ bool use_s_stream;
int ret;
/* A few basic sanity checks first. */
if (pad >= sd->entity.num_pads)
return -EINVAL;
+ if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
+ return -EOPNOTSUPP;
+
+ /*
+ * We use a 64-bit bitmask for tracking enabled pads, so only subdevices
+ * with 64 pads or less can be supported.
+ */
+ if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
+ return -EOPNOTSUPP;
+
if (!streams_mask)
return 0;
/* Fallback on .s_stream() if .enable_streams() isn't available. */
- if (!sd->ops->pad || !sd->ops->pad->enable_streams)
- return v4l2_subdev_enable_streams_fallback(sd, pad,
- streams_mask);
+ use_s_stream = !v4l2_subdev_has_op(sd, pad, enable_streams);
- state = v4l2_subdev_lock_and_get_active_state(sd);
+ if (!use_s_stream)
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ else
+ state = NULL;
/*
* Verify that the requested streams exist and that they are not
* already enabled.
*/
- for (i = 0; i < state->stream_configs.num_configs; ++i) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
- if (cfg->pad != pad || !(streams_mask & BIT_ULL(cfg->stream)))
- continue;
-
- found_streams |= BIT_ULL(cfg->stream);
-
- if (cfg->enabled) {
- dev_dbg(dev, "stream %u already enabled on %s:%u\n",
- cfg->stream, sd->entity.name, pad);
- ret = -EALREADY;
- goto done;
- }
- }
+ v4l2_subdev_collect_streams(sd, state, pad, streams_mask,
+ &found_streams, &enabled_streams);
if (found_streams != streams_mask) {
dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",
@@ -2210,11 +2257,29 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,
goto done;
}
+ if (enabled_streams) {
+ dev_dbg(dev, "streams 0x%llx already enabled on %s:%u\n",
+ enabled_streams, sd->entity.name, pad);
+ ret = -EALREADY;
+ goto done;
+ }
+
dev_dbg(dev, "enable streams %u:%#llx\n", pad, streams_mask);
- /* Call the .enable_streams() operation. */
- ret = v4l2_subdev_call(sd, pad, enable_streams, state, pad,
- streams_mask);
+ already_streaming = v4l2_subdev_is_streaming(sd);
+
+ if (!use_s_stream) {
+ /* Call the .enable_streams() operation. */
+ ret = v4l2_subdev_call(sd, pad, enable_streams, state, pad,
+ streams_mask);
+ } else {
+ /* Start streaming when the first pad is enabled. */
+ if (!already_streaming)
+ ret = v4l2_subdev_call(sd, video, s_stream, 1);
+ else
+ ret = 0;
+ }
+
if (ret) {
dev_dbg(dev, "enable streams %u:%#llx failed: %d\n", pad,
streams_mask, ret);
@@ -2222,103 +2287,68 @@ int v4l2_subdev_enable_streams(struct v4l2_subdev *sd, u32 pad,
}
/* Mark the streams as enabled. */
- for (i = 0; i < state->stream_configs.num_configs; ++i) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
+ v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, true);
- if (cfg->pad == pad && (streams_mask & BIT_ULL(cfg->stream)))
- cfg->enabled = true;
- }
+ /*
+ * TODO: When all the drivers have been changed to use
+ * v4l2_subdev_enable_streams() and v4l2_subdev_disable_streams(),
+ * instead of calling .s_stream() operation directly, we can remove
+ * the privacy LED handling from call_s_stream() and do it here
+ * for all cases.
+ */
+ if (!use_s_stream && !already_streaming)
+ v4l2_subdev_enable_privacy_led(sd);
done:
- v4l2_subdev_unlock_state(state);
+ if (!use_s_stream)
+ v4l2_subdev_unlock_state(state);
return ret;
}
EXPORT_SYMBOL_GPL(v4l2_subdev_enable_streams);
-static int v4l2_subdev_disable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
- u64 streams_mask)
-{
- struct device *dev = sd->entity.graph_obj.mdev->dev;
- unsigned int i;
- int ret;
-
- /*
- * If the subdev doesn't implement pad-based stream enable, fall back
- * on the .s_stream() operation. This can only be done for subdevs that
- * have a single source pad, as sd->enabled_streams is global to the
- * subdev.
- */
- if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
- return -EOPNOTSUPP;
-
- for (i = 0; i < sd->entity.num_pads; ++i) {
- if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
- return -EOPNOTSUPP;
- }
-
- if ((sd->enabled_streams & streams_mask) != streams_mask) {
- dev_dbg(dev, "set of streams %#llx already disabled on %s:%u\n",
- streams_mask, sd->entity.name, pad);
- return -EALREADY;
- }
-
- /* Stop streaming when the last streams are disabled. */
- if (!(sd->enabled_streams & ~streams_mask)) {
- ret = v4l2_subdev_call(sd, video, s_stream, 0);
- if (ret)
- return ret;
- }
-
- sd->enabled_streams &= ~streams_mask;
-
- return 0;
-}
-
int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad,
u64 streams_mask)
{
struct device *dev = sd->entity.graph_obj.mdev->dev;
struct v4l2_subdev_state *state;
- u64 found_streams = 0;
- unsigned int i;
+ u64 enabled_streams;
+ u64 found_streams;
+ bool use_s_stream;
int ret;
/* A few basic sanity checks first. */
if (pad >= sd->entity.num_pads)
return -EINVAL;
+ if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
+ return -EOPNOTSUPP;
+
+ /*
+ * We use a 64-bit bitmask for tracking enabled pads, so only subdevices
+ * with 64 pads or less can be supported.
+ */
+ if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
+ return -EOPNOTSUPP;
+
if (!streams_mask)
return 0;
/* Fallback on .s_stream() if .disable_streams() isn't available. */
- if (!sd->ops->pad || !sd->ops->pad->disable_streams)
- return v4l2_subdev_disable_streams_fallback(sd, pad,
- streams_mask);
+ use_s_stream = !v4l2_subdev_has_op(sd, pad, disable_streams);
- state = v4l2_subdev_lock_and_get_active_state(sd);
+ if (!use_s_stream)
+ state = v4l2_subdev_lock_and_get_active_state(sd);
+ else
+ state = NULL;
/*
* Verify that the requested streams exist and that they are not
* already disabled.
*/
- for (i = 0; i < state->stream_configs.num_configs; ++i) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
-
- if (cfg->pad != pad || !(streams_mask & BIT_ULL(cfg->stream)))
- continue;
-
- found_streams |= BIT_ULL(cfg->stream);
- if (!cfg->enabled) {
- dev_dbg(dev, "stream %u already disabled on %s:%u\n",
- cfg->stream, sd->entity.name, pad);
- ret = -EALREADY;
- goto done;
- }
- }
+ v4l2_subdev_collect_streams(sd, state, pad, streams_mask,
+ &found_streams, &enabled_streams);
if (found_streams != streams_mask) {
dev_dbg(dev, "streams 0x%llx not found on %s:%u\n",
@@ -2327,28 +2357,43 @@ int v4l2_subdev_disable_streams(struct v4l2_subdev *sd, u32 pad,
goto done;
}
+ if (enabled_streams != streams_mask) {
+ dev_dbg(dev, "streams 0x%llx already disabled on %s:%u\n",
+ streams_mask & ~enabled_streams, sd->entity.name, pad);
+ ret = -EALREADY;
+ goto done;
+ }
+
dev_dbg(dev, "disable streams %u:%#llx\n", pad, streams_mask);
- /* Call the .disable_streams() operation. */
- ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,
- streams_mask);
+ if (!use_s_stream) {
+ /* Call the .disable_streams() operation. */
+ ret = v4l2_subdev_call(sd, pad, disable_streams, state, pad,
+ streams_mask);
+ } else {
+ /* Stop streaming when the last streams are disabled. */
+
+ if (!(sd->enabled_pads & ~BIT_ULL(pad)))
+ ret = v4l2_subdev_call(sd, video, s_stream, 0);
+ else
+ ret = 0;
+ }
+
if (ret) {
dev_dbg(dev, "disable streams %u:%#llx failed: %d\n", pad,
streams_mask, ret);
goto done;
}
- /* Mark the streams as disabled. */
- for (i = 0; i < state->stream_configs.num_configs; ++i) {
- struct v4l2_subdev_stream_config *cfg =
- &state->stream_configs.configs[i];
-
- if (cfg->pad == pad && (streams_mask & BIT_ULL(cfg->stream)))
- cfg->enabled = false;
- }
+ v4l2_subdev_set_streams_enabled(sd, state, pad, streams_mask, false);
done:
- v4l2_subdev_unlock_state(state);
+ if (!use_s_stream) {
+ if (!v4l2_subdev_is_streaming(sd))
+ v4l2_subdev_disable_privacy_led(sd);
+
+ v4l2_subdev_unlock_state(state);
+ }
return ret;
}
@@ -2377,15 +2422,24 @@ int v4l2_subdev_s_stream_helper(struct v4l2_subdev *sd, int enable)
if (WARN_ON(pad_index == -1))
return -EINVAL;
- /*
- * As there's a single source pad, just collect all the source streams.
- */
- state = v4l2_subdev_lock_and_get_active_state(sd);
+ if (sd->flags & V4L2_SUBDEV_FL_STREAMS) {
+ /*
+ * As there's a single source pad, just collect all the source
+ * streams.
+ */
+ state = v4l2_subdev_lock_and_get_active_state(sd);
- for_each_active_route(&state->routing, route)
- source_mask |= BIT_ULL(route->source_stream);
+ for_each_active_route(&state->routing, route)
+ source_mask |= BIT_ULL(route->source_stream);
- v4l2_subdev_unlock_state(state);
+ v4l2_subdev_unlock_state(state);
+ } else {
+ /*
+ * For non-streams subdevices, there's a single implicit stream
+ * per pad.
+ */
+ source_mask = BIT_ULL(0);
+ }
if (enable)
return v4l2_subdev_enable_streams(sd, pad_index, source_mask);
@@ -2427,6 +2481,31 @@ void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
}
EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event);
+bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd)
+{
+ struct v4l2_subdev_state *state;
+
+ if (!v4l2_subdev_has_op(sd, pad, enable_streams))
+ return sd->s_stream_enabled;
+
+ if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS))
+ return !!sd->enabled_pads;
+
+ state = v4l2_subdev_get_locked_active_state(sd);
+
+ for (unsigned int i = 0; i < state->stream_configs.num_configs; ++i) {
+ const struct v4l2_subdev_stream_config *cfg;
+
+ cfg = &state->stream_configs.configs[i];
+
+ if (cfg->enabled)
+ return true;
+ }
+
+ return false;
+}
+EXPORT_SYMBOL_GPL(v4l2_subdev_is_streaming);
+
int v4l2_subdev_get_privacy_led(struct v4l2_subdev *sd)
{
#if IS_REACHABLE(CONFIG_LEDS_CLASS)
diff --git a/drivers/staging/media/av7110/Kconfig b/drivers/staging/media/av7110/Kconfig
index 9faf9d2d4001..0722df9e6a41 100644
--- a/drivers/staging/media/av7110/Kconfig
+++ b/drivers/staging/media/av7110/Kconfig
@@ -51,28 +51,6 @@ config DVB_AV7110_OSD
All other people say N.
-config DVB_BUDGET_PATCH
- tristate "AV7110 cards with Budget Patch"
- depends on DVB_BUDGET_CORE && I2C
- depends on DVB_AV7110
- select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
- select DVB_VES1X93 if MEDIA_SUBDRV_AUTOSELECT
- select DVB_TDA8083 if MEDIA_SUBDRV_AUTOSELECT
- help
- Support for Budget Patch (full TS) modification on
- SAA7146+AV7110 based cards (DVB-S cards). This
- driver doesn't use onboard MPEG2 decoder. The
- card is driven in Budget-only mode. Card is
- required to have loaded firmware to tune properly.
- Firmware can be loaded by insertion and removal of
- standard AV7110 driver prior to loading this
- driver.
-
- Say Y if you own such a card and want to use it.
-
- To compile this driver as a module, choose M here: the
- module will be called budget-patch.
-
if DVB_AV7110
# Frontend driver that it is used only by AV7110 driver
diff --git a/drivers/staging/media/av7110/Makefile b/drivers/staging/media/av7110/Makefile
index 307b267598ea..f4bbb535d988 100644
--- a/drivers/staging/media/av7110/Makefile
+++ b/drivers/staging/media/av7110/Makefile
@@ -10,8 +10,6 @@ ifdef CONFIG_DVB_AV7110_IR
dvb-ttpci-objs += av7110_ir.o
endif
-obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
-
obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
obj-$(CONFIG_DVB_SP8870) += sp8870.o
diff --git a/drivers/staging/media/av7110/TODO b/drivers/staging/media/av7110/TODO
deleted file mode 100644
index 60062d8441b3..000000000000
--- a/drivers/staging/media/av7110/TODO
+++ /dev/null
@@ -1,3 +0,0 @@
-- This driver is too old and relies on a different API.
- Drop it from Kernel on a couple of versions.
-- Cleanup patches for the drivers here won't be accepted.
diff --git a/drivers/staging/media/av7110/audio-bilingual-channel-select.rst b/drivers/staging/media/av7110/audio-bilingual-channel-select.rst
deleted file mode 100644
index 33b5363317f1..000000000000
--- a/drivers/staging/media/av7110/audio-bilingual-channel-select.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_BILINGUAL_CHANNEL_SELECT:
-
-==============================
-AUDIO_BILINGUAL_CHANNEL_SELECT
-==============================
-
-Name
-----
-
-AUDIO_BILINGUAL_CHANNEL_SELECT
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_BILINGUAL_CHANNEL_SELECT
-
-``int ioctl(int fd, AUDIO_BILINGUAL_CHANNEL_SELECT, struct audio_channel_select *select)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - audio_channel_select_t ch
-
- - Select the output format of the audio (mono left/right, stereo).
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. It has been replaced
-by the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK`` control
-for MPEG decoders controlled through V4L2.
-
-This ioctl call asks the Audio Device to select the requested channel
-for bilingual streams if possible.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-channel-select.rst b/drivers/staging/media/av7110/audio-channel-select.rst
deleted file mode 100644
index 74093df92a68..000000000000
--- a/drivers/staging/media/av7110/audio-channel-select.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_CHANNEL_SELECT:
-
-====================
-AUDIO_CHANNEL_SELECT
-====================
-
-Name
-----
-
-AUDIO_CHANNEL_SELECT
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_CHANNEL_SELECT
-
-``int ioctl(int fd, AUDIO_CHANNEL_SELECT, struct audio_channel_select *select)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - audio_channel_select_t ch
-
- - Select the output format of the audio (mono left/right, stereo).
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead.
-
-This ioctl call asks the Audio Device to select the requested channel if
-possible.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-clear-buffer.rst b/drivers/staging/media/av7110/audio-clear-buffer.rst
deleted file mode 100644
index a0ebb0278260..000000000000
--- a/drivers/staging/media/av7110/audio-clear-buffer.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_CLEAR_BUFFER:
-
-==================
-AUDIO_CLEAR_BUFFER
-==================
-
-Name
-----
-
-AUDIO_CLEAR_BUFFER
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_CLEAR_BUFFER
-
-``int ioctl(int fd, AUDIO_CLEAR_BUFFER)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call asks the Audio Device to clear all software and hardware
-buffers of the audio decoder device.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-continue.rst b/drivers/staging/media/av7110/audio-continue.rst
deleted file mode 100644
index a2e9850f37f2..000000000000
--- a/drivers/staging/media/av7110/audio-continue.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_CONTINUE:
-
-==============
-AUDIO_CONTINUE
-==============
-
-Name
-----
-
-AUDIO_CONTINUE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_CONTINUE
-
-``int ioctl(int fd, AUDIO_CONTINUE)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl restarts the decoding and playing process previously paused
-with AUDIO_PAUSE command.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-fclose.rst b/drivers/staging/media/av7110/audio-fclose.rst
deleted file mode 100644
index 77857d578e83..000000000000
--- a/drivers/staging/media/av7110/audio-fclose.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _audio_fclose:
-
-========================
-Digital TV audio close()
-========================
-
-Name
-----
-
-Digital TV audio close()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This system call closes a previously opened audio device.
-
-Return Value
-------------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EBADF``
-
- - fd is not a valid open file descriptor.
diff --git a/drivers/staging/media/av7110/audio-fopen.rst b/drivers/staging/media/av7110/audio-fopen.rst
deleted file mode 100644
index 774daaab3bad..000000000000
--- a/drivers/staging/media/av7110/audio-fopen.rst
+++ /dev/null
@@ -1,103 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _audio_fopen:
-
-=======================
-Digital TV audio open()
-=======================
-
-Name
-----
-
-Digital TV audio open()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: int open(const char *deviceName, int flags)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - const char \*deviceName
-
- - Name of specific audio device.
-
- - .. row 2
-
- - int flags
-
- - A bit-wise OR of the following flags:
-
- - .. row 3
-
- -
- - O_RDONLY read-only access
-
- - .. row 4
-
- -
- - O_RDWR read/write access
-
- - .. row 5
-
- -
- - O_NONBLOCK open in non-blocking mode
-
- - .. row 6
-
- -
- - (blocking mode is the default)
-
-Description
------------
-
-This system call opens a named audio device (e.g.
-/dev/dvb/adapter0/audio0) for subsequent use. When an open() call has
-succeeded, the device will be ready for use. The significance of
-blocking or non-blocking mode is described in the documentation for
-functions where there is a difference. It does not affect the semantics
-of the open() call itself. A device opened in blocking mode can later be
-put into non-blocking mode (and vice versa) using the F_SETFL command
-of the fcntl system call. This is a standard system call, documented in
-the Linux manual page for fcntl. Only one user can open the Audio Device
-in O_RDWR mode. All other attempts to open the device in this mode will
-fail, and an error code will be returned. If the Audio Device is opened
-in O_RDONLY mode, the only ioctl call that can be used is
-AUDIO_GET_STATUS. All other call will return with an error code.
-
-Return Value
-------------
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``ENODEV``
-
- - Device driver not loaded/available.
-
- - .. row 2
-
- - ``EBUSY``
-
- - Device or resource busy.
-
- - .. row 3
-
- - ``EINVAL``
-
- - Invalid argument.
diff --git a/drivers/staging/media/av7110/audio-fwrite.rst b/drivers/staging/media/av7110/audio-fwrite.rst
deleted file mode 100644
index 7b096ac2b6c4..000000000000
--- a/drivers/staging/media/av7110/audio-fwrite.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _audio_fwrite:
-
-=========================
-Digital TV audio write()
-=========================
-
-Name
-----
-
-Digital TV audio write()
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:function:: size_t write(int fd, const void *buf, size_t count)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - void \*buf
-
- - Pointer to the buffer containing the PES data.
-
- - .. row 3
-
- - size_t count
-
- - Size of buf.
-
-Description
------------
-
-This system call can only be used if AUDIO_SOURCE_MEMORY is selected
-in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
-PES format. If O_NONBLOCK is not specified the function will block
-until buffer space is available. The amount of data to be transferred is
-implied by count.
-
-Return Value
-------------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EPERM``
-
- - Mode AUDIO_SOURCE_MEMORY not selected.
-
- - .. row 2
-
- - ``ENOMEM``
-
- - Attempted to write more data than the internal buffer can hold.
-
- - .. row 3
-
- - ``EBADF``
-
- - fd is not a valid open file descriptor.
diff --git a/drivers/staging/media/av7110/audio-get-capabilities.rst b/drivers/staging/media/av7110/audio-get-capabilities.rst
deleted file mode 100644
index 6d9eb71dad17..000000000000
--- a/drivers/staging/media/av7110/audio-get-capabilities.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_GET_CAPABILITIES:
-
-======================
-AUDIO_GET_CAPABILITIES
-======================
-
-Name
-----
-
-AUDIO_GET_CAPABILITIES
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_GET_CAPABILITIES
-
-``int ioctl(int fd, AUDIO_GET_CAPABILITIES, unsigned int *cap)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - unsigned int \*cap
-
- - Returns a bit array of supported sound formats.
-
-Description
------------
-
-This ioctl call asks the Audio Device to tell us about the decoding
-capabilities of the audio hardware.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-get-status.rst b/drivers/staging/media/av7110/audio-get-status.rst
deleted file mode 100644
index 7ae8db2e65e9..000000000000
--- a/drivers/staging/media/av7110/audio-get-status.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_GET_STATUS:
-
-================
-AUDIO_GET_STATUS
-================
-
-Name
-----
-
-AUDIO_GET_STATUS
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_GET_STATUS
-
-``int ioctl(int fd, AUDIO_GET_STATUS, struct audio_status *status)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - struct audio_status \*status
-
- - Returns the current state of Audio Device.
-
-Description
------------
-
-This ioctl call asks the Audio Device to return the current state of the
-Audio Device.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-pause.rst b/drivers/staging/media/av7110/audio-pause.rst
deleted file mode 100644
index d37d1ddce4df..000000000000
--- a/drivers/staging/media/av7110/audio-pause.rst
+++ /dev/null
@@ -1,49 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_PAUSE:
-
-===========
-AUDIO_PAUSE
-===========
-
-Name
-----
-
-AUDIO_PAUSE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_PAUSE
-
-``int ioctl(int fd, AUDIO_PAUSE)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call suspends the audio stream being played. Decoding and
-playing are paused. It is then possible to restart again decoding and
-playing process of the audio stream using AUDIO_CONTINUE command.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-play.rst b/drivers/staging/media/av7110/audio-play.rst
deleted file mode 100644
index e591930b6ca7..000000000000
--- a/drivers/staging/media/av7110/audio-play.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_PLAY:
-
-==========
-AUDIO_PLAY
-==========
-
-Name
-----
-
-AUDIO_PLAY
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_PLAY
-
-``int ioctl(int fd, AUDIO_PLAY)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call asks the Audio Device to start playing an audio stream
-from the selected source.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-select-source.rst b/drivers/staging/media/av7110/audio-select-source.rst
deleted file mode 100644
index 6a0c0f365eb1..000000000000
--- a/drivers/staging/media/av7110/audio-select-source.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SELECT_SOURCE:
-
-===================
-AUDIO_SELECT_SOURCE
-===================
-
-Name
-----
-
-AUDIO_SELECT_SOURCE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SELECT_SOURCE
-
-``int ioctl(int fd, AUDIO_SELECT_SOURCE, struct audio_stream_source *source)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - audio_stream_source_t source
-
- - Indicates the source that shall be used for the Audio stream.
-
-Description
------------
-
-This ioctl call informs the audio device which source shall be used for
-the input data. The possible sources are demux or memory. If
-AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
-through the write command.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-av-sync.rst b/drivers/staging/media/av7110/audio-set-av-sync.rst
deleted file mode 100644
index 85a8016bf025..000000000000
--- a/drivers/staging/media/av7110/audio-set-av-sync.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_AV_SYNC:
-
-=================
-AUDIO_SET_AV_SYNC
-=================
-
-Name
-----
-
-AUDIO_SET_AV_SYNC
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_AV_SYNC
-
-``int ioctl(int fd, AUDIO_SET_AV_SYNC, boolean state)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - boolean state
-
- - Tells the Digital TV subsystem if A/V synchronization shall be ON or OFF.
-
- TRUE: AV-sync ON
-
- FALSE: AV-sync OFF
-
-Description
------------
-
-This ioctl call asks the Audio Device to turn ON or OFF A/V
-synchronization.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-bypass-mode.rst b/drivers/staging/media/av7110/audio-set-bypass-mode.rst
deleted file mode 100644
index 80d551a2053a..000000000000
--- a/drivers/staging/media/av7110/audio-set-bypass-mode.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_BYPASS_MODE:
-
-=====================
-AUDIO_SET_BYPASS_MODE
-=====================
-
-Name
-----
-
-AUDIO_SET_BYPASS_MODE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_BYPASS_MODE
-
-``int ioctl(int fd, AUDIO_SET_BYPASS_MODE, boolean mode)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - boolean mode
-
- - Enables or disables the decoding of the current Audio stream in
- the Digital TV subsystem.
-
- TRUE: Bypass is disabled
-
- FALSE: Bypass is enabled
-
-Description
------------
-
-This ioctl call asks the Audio Device to bypass the Audio decoder and
-forward the stream without decoding. This mode shall be used if streams
-that can't be handled by the Digital TV system shall be decoded. Dolby
-DigitalTM streams are automatically forwarded by the Digital TV subsystem if
-the hardware can handle it.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-id.rst b/drivers/staging/media/av7110/audio-set-id.rst
deleted file mode 100644
index 39ad846d412d..000000000000
--- a/drivers/staging/media/av7110/audio-set-id.rst
+++ /dev/null
@@ -1,59 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_ID:
-
-============
-AUDIO_SET_ID
-============
-
-Name
-----
-
-AUDIO_SET_ID
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_ID
-
-``int ioctl(int fd, AUDIO_SET_ID, int id)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - int id
-
- - audio sub-stream id
-
-Description
------------
-
-This ioctl selects which sub-stream is to be decoded if a program or
-system stream is sent to the video device. If no audio stream type is
-set the id has to be in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for
-AC3 and in [0xA0,0xA7] for LPCM. More specifications may follow for
-other stream types. If the stream type is set the id just specifies the
-substream id of the audio stream and only the first 5 bits are
-recognized.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-mixer.rst b/drivers/staging/media/av7110/audio-set-mixer.rst
deleted file mode 100644
index 45dbdf4801e0..000000000000
--- a/drivers/staging/media/av7110/audio-set-mixer.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_MIXER:
-
-===============
-AUDIO_SET_MIXER
-===============
-
-Name
-----
-
-AUDIO_SET_MIXER
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_MIXER
-
-``int ioctl(int fd, AUDIO_SET_MIXER, struct audio_mixer *mix)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - audio_mixer_t \*mix
-
- - mixer settings.
-
-Description
------------
-
-This ioctl lets you adjust the mixer settings of the audio decoder.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-mute.rst b/drivers/staging/media/av7110/audio-set-mute.rst
deleted file mode 100644
index 987751f92967..000000000000
--- a/drivers/staging/media/av7110/audio-set-mute.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_MUTE:
-
-==============
-AUDIO_SET_MUTE
-==============
-
-Name
-----
-
-AUDIO_SET_MUTE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_MUTE
-
-``int ioctl(int fd, AUDIO_SET_MUTE, boolean state)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - boolean state
-
- - Indicates if audio device shall mute or not.
-
- TRUE: Audio Mute
-
- FALSE: Audio Un-mute
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` with the
-``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead.
-
-This ioctl call asks the audio device to mute the stream that is
-currently being played.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio-set-streamtype.rst b/drivers/staging/media/av7110/audio-set-streamtype.rst
deleted file mode 100644
index 77d73c74882f..000000000000
--- a/drivers/staging/media/av7110/audio-set-streamtype.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_SET_STREAMTYPE:
-
-====================
-AUDIO_SET_STREAMTYPE
-====================
-
-Name
-----
-
-AUDIO_SET_STREAMTYPE
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_SET_STREAMTYPE
-
-``int ioctl(fd, AUDIO_SET_STREAMTYPE, int type)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- -
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- -
-
- - int type
-
- - stream type
-
-Description
------------
-
-This ioctl tells the driver which kind of audio stream to expect. This
-is useful if the stream offers several audio sub-streams like LPCM and
-AC3.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EINVAL``
-
- - type is not a valid or supported stream type.
diff --git a/drivers/staging/media/av7110/audio-stop.rst b/drivers/staging/media/av7110/audio-stop.rst
deleted file mode 100644
index d77f786fd797..000000000000
--- a/drivers/staging/media/av7110/audio-stop.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.audio
-
-.. _AUDIO_STOP:
-
-==========
-AUDIO_STOP
-==========
-
-Name
-----
-
-AUDIO_STOP
-
-.. attention:: This ioctl is deprecated
-
-Synopsis
---------
-
-.. c:macro:: AUDIO_STOP
-
-``int ioctl(int fd, AUDIO_STOP)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This ioctl call asks the Audio Device to stop playing the current
-stream.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/audio.rst b/drivers/staging/media/av7110/audio.rst
deleted file mode 100644
index aa753336b31f..000000000000
--- a/drivers/staging/media/av7110/audio.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _dvb_audio:
-
-#######################
-Digital TV Audio Device
-#######################
-
-The Digital TV audio device controls the MPEG2 audio decoder of the Digital
-TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data
-types and ioctl definitions can be accessed by including
-``linux/dvb/audio.h`` in your application.
-
-Please note that some Digital TV cards don't have their own MPEG decoder, which
-results in the omission of the audio and video device.
-
-These ioctls were also used by V4L2 to control MPEG decoders implemented
-in V4L2. The use of these ioctls for that purpose has been made obsolete
-and proper V4L2 ioctls or controls have been created to replace that
-functionality.
-
-
-.. toctree::
- :maxdepth: 1
-
- audio_data_types
- audio_function_calls
diff --git a/drivers/staging/media/av7110/audio_data_types.rst b/drivers/staging/media/av7110/audio_data_types.rst
deleted file mode 100644
index 4744529136a8..000000000000
--- a/drivers/staging/media/av7110/audio_data_types.rst
+++ /dev/null
@@ -1,116 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _audio_data_types:
-
-****************
-Audio Data Types
-****************
-
-This section describes the structures, data types and defines used when
-talking to the audio device.
-
-.. c:type:: audio_stream_source
-
-The audio stream source is set through the AUDIO_SELECT_SOURCE call
-and can take the following values, depending on whether we are replaying
-from an internal (demux) or external (user write) source.
-
-
-.. code-block:: c
-
- typedef enum {
- AUDIO_SOURCE_DEMUX,
- AUDIO_SOURCE_MEMORY
- } audio_stream_source_t;
-
-AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the
-frontend or the DVR device) as the source of the video stream. If
-AUDIO_SOURCE_MEMORY is selected the stream comes from the application
-through the ``write()`` system call.
-
-
-.. c:type:: audio_play_state
-
-The following values can be returned by the AUDIO_GET_STATUS call
-representing the state of audio playback.
-
-
-.. code-block:: c
-
- typedef enum {
- AUDIO_STOPPED,
- AUDIO_PLAYING,
- AUDIO_PAUSED
- } audio_play_state_t;
-
-
-.. c:type:: audio_channel_select
-
-The audio channel selected via AUDIO_CHANNEL_SELECT is determined by
-the following values.
-
-
-.. code-block:: c
-
- typedef enum {
- AUDIO_STEREO,
- AUDIO_MONO_LEFT,
- AUDIO_MONO_RIGHT,
- AUDIO_MONO,
- AUDIO_STEREO_SWAPPED
- } audio_channel_select_t;
-
-
-.. c:type:: audio_status
-
-The AUDIO_GET_STATUS call returns the following structure informing
-about various states of the playback operation.
-
-
-.. code-block:: c
-
- typedef struct audio_status {
- boolean AV_sync_state;
- boolean mute_state;
- audio_play_state_t play_state;
- audio_stream_source_t stream_source;
- audio_channel_select_t channel_select;
- boolean bypass_mode;
- audio_mixer_t mixer_state;
- } audio_status_t;
-
-
-.. c:type:: audio_mixer
-
-The following structure is used by the AUDIO_SET_MIXER call to set the
-audio volume.
-
-
-.. code-block:: c
-
- typedef struct audio_mixer {
- unsigned int volume_left;
- unsigned int volume_right;
- } audio_mixer_t;
-
-
-.. _audio_encodings:
-
-audio encodings
-===============
-
-A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the
-following bits set according to the hardwares capabilities.
-
-
-.. code-block:: c
-
- #define AUDIO_CAP_DTS 1
- #define AUDIO_CAP_LPCM 2
- #define AUDIO_CAP_MP1 4
- #define AUDIO_CAP_MP2 8
- #define AUDIO_CAP_MP3 16
- #define AUDIO_CAP_AAC 32
- #define AUDIO_CAP_OGG 64
- #define AUDIO_CAP_SDDS 128
- #define AUDIO_CAP_AC3 256
diff --git a/drivers/staging/media/av7110/audio_function_calls.rst b/drivers/staging/media/av7110/audio_function_calls.rst
deleted file mode 100644
index fa5ba9539caf..000000000000
--- a/drivers/staging/media/av7110/audio_function_calls.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _audio_function_calls:
-
-********************
-Audio Function Calls
-********************
-
-.. toctree::
- :maxdepth: 1
-
- audio-fopen
- audio-fclose
- audio-fwrite
- audio-stop
- audio-play
- audio-pause
- audio-continue
- audio-select-source
- audio-set-mute
- audio-set-av-sync
- audio-set-bypass-mode
- audio-channel-select
- audio-bilingual-channel-select
- audio-get-status
- audio-get-capabilities
- audio-clear-buffer
- audio-set-id
- audio-set-mixer
- audio-set-streamtype
diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c
index a5a431c14ea7..728b3892a20c 100644
--- a/drivers/staging/media/av7110/av7110.c
+++ b/drivers/staging/media/av7110/av7110.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB)
- * av7110.c: initialization and demux stuff
+ * - initialization and demux stuff
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -12,7 +12,6 @@
* the project's page is at https://linuxtv.org
*/
-
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/delay.h>
@@ -36,7 +35,6 @@
#include <asm/unaligned.h>
#include <asm/byteorder.h>
-
#include <linux/dvb/frontend.h>
#include <media/dvb_frontend.h>
@@ -54,9 +52,8 @@
#define TS_WIDTH 376
#define TS_HEIGHT 512
-#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
-#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
-
+#define TS_BUFLEN (TS_WIDTH * TS_HEIGHT)
+#define TS_MAX_PACKETS (TS_BUFLEN / TS_SIZE)
int av7110_debug;
@@ -75,11 +72,11 @@ static int full_ts;
module_param_named(debug, av7110_debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
module_param(vidmode, int, 0444);
-MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
+MODULE_PARM_DESC(vidmode, "analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
module_param(pids_off, int, 0444);
-MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
+MODULE_PARM_DESC(pids_off, "clear video/audio/PCR PID filters when demux is closed");
module_param(adac, int, 0444);
-MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
+MODULE_PARM_DESC(adac, "audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
module_param(hw_sections, int, 0444);
MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
module_param(rgb_on, int, 0444);
@@ -107,12 +104,11 @@ static int av7110_num;
#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
{\
- if (fe_func != NULL) { \
+ if (fe_func) { \
av7110_copy = fe_func; \
fe_func = av7110_func; \
} \
-}
-
+} /* Macro argument reuse of 'fe_func' is intentional! */
static void init_av7110_av(struct av7110 *av7110)
{
@@ -123,27 +119,27 @@ static void init_av7110_av(struct av7110 *av7110)
av7110->adac_type = DVB_ADAC_TI;
ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
if (ret < 0)
- printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
+ pr_err("cannot set internal volume to maximum:%d\n", ret);
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
- 1, (u16) av7110->display_ar);
+ 1, (u16)av7110->display_ar);
if (ret < 0)
- printk("dvb-ttpci: unable to set aspect ratio\n");
+ pr_err("unable to set aspect ratio\n");
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType,
1, av7110->display_panscan);
if (ret < 0)
- printk("dvb-ttpci: unable to set pan scan\n");
+ pr_err("unable to set pan scan\n");
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3);
if (ret < 0)
- printk("dvb-ttpci: unable to configure 4:3 wss\n");
+ pr_err("unable to configure 4:3 wss\n");
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9);
if (ret < 0)
- printk("dvb-ttpci: unable to configure 16:9 wss\n");
+ pr_err("unable to configure 16:9 wss\n");
ret = av7710_set_video_mode(av7110, vidmode);
if (ret < 0)
- printk("dvb-ttpci:cannot set video mode:%d\n",ret);
+ pr_err("cannot set video mode:%d\n", ret);
/* handle different card types */
/* remaining inits according to card and frontend type */
@@ -152,8 +148,7 @@ static void init_av7110_av(struct av7110 *av7110)
if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a)
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on
if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
- printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
- av7110->dvb_adapter.num);
+ pr_info("Crystal audio DAC @ card %d detected\n", av7110->dvb_adapter.num);
av7110->adac_type = DVB_ADAC_CRYSTAL;
i2c_writereg(av7110, 0x20, 0x01, 0xd2);
i2c_writereg(av7110, 0x20, 0x02, 0x49);
@@ -163,28 +158,24 @@ static void init_av7110_av(struct av7110 *av7110)
/**
* some special handling for the Siemens DVB-C cards...
*/
- } else if (0 == av7110_init_analog_module(av7110)) {
+ } else if (av7110_init_analog_module(av7110) == 0) {
/* done. */
- }
- else if (dev->pci->subsystem_vendor == 0x110a) {
- printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
- av7110->dvb_adapter.num);
+ } else if (dev->pci->subsystem_vendor == 0x110a) {
+ pr_info("DVB-C w/o analog module @ card %d detected\n", av7110->dvb_adapter.num);
av7110->adac_type = DVB_ADAC_NONE;
- }
- else {
+ } else {
av7110->adac_type = adac;
- printk("dvb-ttpci: adac type set to %d @ card %d\n",
- av7110->adac_type, av7110->dvb_adapter.num);
+ pr_info("adac type set to %d @ card %d\n", av7110->adac_type, av7110->dvb_adapter.num);
}
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) {
// switch DVB SCART on
ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
if (ret < 0)
- printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
+ pr_err("cannot switch on SCART(Main):%d\n", ret);
ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
if (ret < 0)
- printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
+ pr_err("cannot switch on SCART(AD):%d\n", ret);
if (rgb_on &&
((av7110->dev->pci->subsystem_vendor == 0x110a) ||
(av7110->dev->pci->subsystem_vendor == 0x13c2)) &&
@@ -199,12 +190,12 @@ static void init_av7110_av(struct av7110 *av7110)
ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
if (ret < 0)
- printk("dvb-ttpci:cannot set volume :%d\n",ret);
+ pr_err("cannot set volume :%d\n", ret);
}
static void recover_arm(struct av7110 *av7110)
{
- dprintk(4, "%p\n",av7110);
+ dprintk(4, "%p\n", av7110);
av7110_bootarm(av7110);
msleep(100);
@@ -236,11 +227,11 @@ static int arm_thread(void *data)
u16 newloops = 0;
int timeout;
- dprintk(4, "%p\n",av7110);
+ dprintk(4, "%p\n", av7110);
for (;;) {
timeout = wait_event_interruptible_timeout(av7110->arm_wait,
- kthread_should_stop(), 5 * HZ);
+ kthread_should_stop(), 5 * HZ);
if (-ERESTARTSYS == timeout || kthread_should_stop()) {
/* got signal or told to quit*/
@@ -256,8 +247,7 @@ static int arm_thread(void *data)
mutex_unlock(&av7110->dcomlock);
if (newloops == av7110->arm_loops || av7110->arm_errors > 3) {
- printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
- av7110->dvb_adapter.num);
+ pr_err("ARM crashed @ card %d\n", av7110->dvb_adapter.num);
recover_arm(av7110);
@@ -273,7 +263,6 @@ static int arm_thread(void *data)
return 0;
}
-
/****************************************************************************
* IRQ handling
****************************************************************************/
@@ -325,14 +314,14 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
}
}
-
//#define DEBUG_TIMING
static inline void print_time(char *s)
{
#ifdef DEBUG_TIMING
struct timespec64 ts;
+
ktime_get_real_ts64(&ts);
- printk("%s: %lld.%09ld\n", s, (s64)ts.tv_sec, ts.tv_nsec);
+ pr_info("%s(): %lld.%09ld\n", s, (s64)ts.tv_sec, ts.tv_nsec);
#endif
}
@@ -343,7 +332,7 @@ static inline void start_debi_dma(struct av7110 *av7110, int dir,
{
dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len);
if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
- printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
+ pr_err("%s(): saa7146_wait_for_debi_done timed out\n", __func__);
return;
}
@@ -368,18 +357,16 @@ static void debiirq(struct tasklet_struct *t)
dprintk(4, "type 0x%04x\n", type);
if (type == -1) {
- printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
- jiffies, saa7146_read(av7110->dev, PSR),
- saa7146_read(av7110->dev, SSR));
+ pr_err("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", jiffies,
+ saa7146_read(av7110->dev, PSR), saa7146_read(av7110->dev, SSR));
goto debi_done;
}
av7110->debitype = -1;
switch (type & 0xff) {
-
case DATA_TS_RECORD:
dvb_dmx_swfilter_packets(&av7110->demux,
- (const u8 *) av7110->debi_virt,
+ (const u8 *)av7110->debi_virt,
av7110->debilen / 188);
xfer = RX_BUFF;
break;
@@ -387,7 +374,7 @@ static void debiirq(struct tasklet_struct *t)
case DATA_PES_RECORD:
if (av7110->demux.recording)
av7110_record_cb(&av7110->p2t[handle],
- (u8 *) av7110->debi_virt,
+ (u8 *)av7110->debi_virt,
av7110->debilen);
xfer = RX_BUFF;
break;
@@ -410,15 +397,17 @@ static void debiirq(struct tasklet_struct *t)
if (data_0 < 2 && data[2] == 0xff) {
int flags = 0;
+
if (data[5] > 0)
flags |= CA_CI_MODULE_PRESENT;
if (data[5] > 5)
flags |= CA_CI_MODULE_READY;
av7110->ci_slot[data_0].flags = flags;
- } else
+ } else {
ci_get_data(&av7110->ci_rbuffer,
av7110->debi_virt,
av7110->debilen);
+ }
xfer = RX_BUFF;
break;
}
@@ -429,8 +418,8 @@ static void debiirq(struct tasklet_struct *t)
break;
case DATA_DEBUG_MESSAGE:
- ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
- printk("%s\n", (s8 *) av7110->debi_virt);
+ ((s8 *)av7110->debi_virt)[Reserved_SIZE - 1] = 0;
+ pr_info("%s\n", (s8 *)av7110->debi_virt);
xfer = RX_BUFF;
break;
@@ -466,12 +455,11 @@ static void gpioirq(struct tasklet_struct *t)
if (av7110->debitype != -1)
/* we shouldn't get any irq while a debi xfer is running */
- printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
- jiffies, saa7146_read(av7110->dev, PSR),
- saa7146_read(av7110->dev, SSR));
+ pr_err("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", jiffies,
+ saa7146_read(av7110->dev, PSR), saa7146_read(av7110->dev, SSR));
if (saa7146_wait_for_debi_done(av7110->dev, 0)) {
- printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__);
+ pr_err("%s(): saa7146_wait_for_debi_done timed out\n", __func__);
BUG(); /* maybe we should try resetting the debi? */
}
@@ -489,7 +477,6 @@ static void gpioirq(struct tasklet_struct *t)
dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen);
switch (av7110->debitype & 0xff) {
-
case DATA_TS_PLAY:
case DATA_PES_PLAY:
break;
@@ -510,8 +497,7 @@ static void gpioirq(struct tasklet_struct *t)
event.type = VIDEO_EVENT_SIZE_CHANGED;
event.u.size.w = av7110->video_size.w;
event.u.size.h = av7110->video_size.h;
- switch ((h_ar >> 12) & 0xf)
- {
+ switch ((h_ar >> 12) & 0xf) {
case 3:
av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9;
event.u.size.aspect_ratio = VIDEO_FORMAT_16_9;
@@ -582,8 +568,8 @@ static void gpioirq(struct tasklet_struct *t)
len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048);
spin_unlock(&av7110->aout.lock);
}
- if (len <= 0 && (av7110->debitype & 0x200)
- &&av7110->videostate.play_state != VIDEO_FREEZED) {
+ if (len <= 0 && (av7110->debitype & 0x200) &&
+ av7110->videostate.play_state != VIDEO_FREEZED) {
spin_lock(&av7110->avout.lock);
len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048);
spin_unlock(&av7110->avout.lock);
@@ -620,11 +606,11 @@ static void gpioirq(struct tasklet_struct *t)
len = 2 * 1024;
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
- memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
+ memcpy(av7110->debi_virt, av7110->bmpbuf + av7110->bmpp, len);
av7110->bmpp += len;
av7110->bmplen -= len;
dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len);
- start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len);
+ start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len);
spin_unlock(&av7110->debilock);
return;
@@ -642,7 +628,7 @@ static void gpioirq(struct tasklet_struct *t)
case DATA_TS_RECORD:
case DATA_PES_RECORD:
dprintk(8, "DMA: TS_REC etc.\n");
- start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len);
+ start_debi_dma(av7110, DEBI_READ, DPRAM_BASE + rxbuf, len);
spin_unlock(&av7110->debilock);
return;
@@ -665,7 +651,7 @@ static void gpioirq(struct tasklet_struct *t)
break;
default:
- printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
+ pr_err("%s(): unknown irq: type=%d len=%d\n", __func__,
av7110->debitype, av7110->debilen);
break;
}
@@ -674,7 +660,6 @@ static void gpioirq(struct tasklet_struct *t)
spin_unlock(&av7110->debilock);
}
-
#ifdef CONFIG_DVB_AV7110_OSD
static int dvb_osd_ioctl(struct file *file,
unsigned int cmd, void *parg)
@@ -685,14 +670,13 @@ static int dvb_osd_ioctl(struct file *file,
dprintk(4, "%p\n", av7110);
if (cmd == OSD_SEND_CMD)
- return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
+ return av7110_osd_cmd(av7110, (osd_cmd_t *)parg);
if (cmd == OSD_GET_CAPABILITY)
- return av7110_osd_capability(av7110, (osd_cap_t *) parg);
+ return av7110_osd_capability(av7110, (osd_cap_t *)parg);
return -EINVAL;
}
-
static const struct file_operations dvb_osd_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = dvb_generic_ioctl,
@@ -710,7 +694,6 @@ static struct dvb_device dvbdev_osd = {
};
#endif /* CONFIG_DVB_AV7110_OSD */
-
static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
@@ -720,7 +703,11 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
if (vpid == 0x1fff || apid == 0x1fff ||
ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
- vpid = apid = ttpid = subpid = pcrpid = 0;
+ vpid = 0;
+ apid = 0;
+ ttpid = 0;
+ subpid = 0;
+ pcrpid = 0;
av7110->pids[DMX_PES_VIDEO] = 0;
av7110->pids[DMX_PES_AUDIO] = 0;
av7110->pids[DMX_PES_TELETEXT] = 0;
@@ -735,9 +722,10 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
}
int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
- u16 subpid, u16 pcrpid)
+ u16 subpid, u16 pcrpid)
{
int ret = 0;
+
dprintk(4, "%p\n", av7110);
if (mutex_lock_interruptible(&av7110->pid_mutex))
@@ -763,7 +751,6 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
return ret;
}
-
/******************************************************************************
* hardware filter functions
******************************************************************************/
@@ -805,9 +792,8 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
if (ret != 0 || handle >= 32) {
- printk(KERN_ERR "dvb-ttpci: %s error buf %04x %04x %04x %04x ret %d handle %04x\n",
- __func__, buf[0], buf[1], buf[2], buf[3],
- ret, handle);
+ pr_err("%s(): error buf %04x %04x %04x %04x ret %d handle %04x\n",
+ __func__, buf[0], buf[1], buf[2], buf[3], ret, handle);
dvbdmxfilter->hw_handle = 0xffff;
if (!ret)
ret = -1;
@@ -835,8 +821,8 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
handle = dvbdmxfilter->hw_handle;
if (handle >= 32) {
- printk("%s tried to stop invalid filter %04x, filter type = %x\n",
- __func__, handle, dvbdmxfilter->type);
+ pr_err("%s(): tried to stop invalid filter %04x, filter type = %x\n",
+ __func__, handle, dvbdmxfilter->type);
return -EINVAL;
}
@@ -847,16 +833,14 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
buf[2] = handle;
ret = av7110_fw_request(av7110, buf, 3, answ, 2);
if (ret != 0 || answ[1] != handle) {
- printk(KERN_ERR "dvb-ttpci: %s error cmd %04x %04x %04x ret %x resp %04x %04x pid %d\n",
- __func__, buf[0], buf[1], buf[2], ret,
- answ[0], answ[1], dvbdmxfilter->feed->pid);
+ pr_err("%s(): error cmd %04x %04x %04x ret %x resp %04x %04x pid %d\n", __func__,
+ buf[0], buf[1], buf[2], ret, answ[0], answ[1], dvbdmxfilter->feed->pid);
if (!ret)
ret = -1;
}
return ret;
}
-
static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
@@ -867,9 +851,13 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
dprintk(4, "%p\n", av7110);
- npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
+ npids[0] = 0xffff;
+ npids[1] = 0xffff;
+ npids[2] = 0xffff;
+ npids[3] = 0xffff;
+ npids[4] = 0xffff;
i = dvbdmxfeed->pes_type;
- npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
+ npids[i] = (pid[i] & 0x8000) ? 0 : pid[i];
if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
npids[i] = 0;
ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
@@ -884,8 +872,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
}
if (dvbdmxfeed->pes_type < 2 && npids[0])
- if (av7110->fe_synced)
- {
+ if (av7110->fe_synced) {
ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
if (ret)
return ret;
@@ -920,7 +907,11 @@ static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
if (!av7110->playing)
dvbdmx->playing = 0;
}
- npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
+ npids[0] = 0xffff;
+ npids[1] = 0xffff;
+ npids[2] = 0xffff;
+ npids[3] = 0xffff;
+ npids[4] = 0xffff;
i = dvbdmxfeed->pes_type;
switch (i) {
case 2: //teletext
@@ -933,7 +924,7 @@ static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
case 4:
if (!pids_off)
return 0;
- npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
+ npids[i] = (pid[i] & 0x8000) ? 0 : pid[i];
break;
}
if (!ret)
@@ -961,14 +952,14 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
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)) {
+ 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:
@@ -1008,12 +999,12 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
return ret;
}
-
static int av7110_stop_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv;
int i, rc, ret = 0;
+
dprintk(4, "%p\n", av7110);
if (feed->type == DMX_TYPE_TS) {
@@ -1024,10 +1015,9 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
demux->pids[feed->pes_type] |= 0x8000;
demux->pesfilter[feed->pes_type] = NULL;
}
- if (feed->ts_type & TS_DECODER &&
- feed->pes_type < DMX_PES_OTHER) {
+ if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_PES_OTHER)
ret = dvb_feed_stop_pid(feed);
- } else
+ else
if ((feed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE))
ret = StopHWFilter(feed->filter);
@@ -1039,7 +1029,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
}
if (feed->type == DMX_TYPE_SEC) {
- for (i = 0; i<demux->filternum; i++) {
+ for (i = 0; i < demux->filternum; i++) {
if (demux->filter[i].state == DMX_STATE_GO &&
demux->filter[i].filter.parent == &feed->feed.sec) {
demux->filter[i].state = DMX_STATE_READY;
@@ -1056,7 +1046,6 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
return ret;
}
-
static void restart_feeds(struct av7110 *av7110)
{
struct dvb_demux *dvbdmx = &av7110->demux;
@@ -1097,7 +1086,7 @@ static void restart_feeds(struct av7110 *av7110)
}
static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
- uint64_t *stc, unsigned int *base)
+ u64 *stc, unsigned int *base)
{
int ret;
u16 fwstc[4];
@@ -1120,14 +1109,13 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
if (ret) {
- printk(KERN_ERR "%s: av7110_fw_request error\n", __func__);
+ pr_err("%s(): av7110_fw_request error\n", __func__);
return ret;
}
- dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
- fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
+ dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
- *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
- (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
+ *stc = (((uint64_t)((fwstc[3] & 0x8000) >> 15)) << 32) |
+ (((uint64_t)fwstc[1]) << 16) | ((uint64_t)fwstc[0]);
*base = 1;
dprintk(4, "stc = %lu\n", (unsigned long)*stc);
@@ -1135,15 +1123,13 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
return 0;
}
-
/******************************************************************************
* SEC device file operations
******************************************************************************/
-
static int av7110_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
switch (tone) {
case SEC_TONE_ON:
@@ -1157,18 +1143,18 @@ static int av7110_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
}
}
-static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
- struct dvb_diseqc_master_cmd* cmd)
+static int av7110_diseqc_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
}
-static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
+static int av7110_diseqc_send_burst(struct dvb_frontend *fe,
enum fe_sec_mini_cmd minicmd)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
return av7110_diseqc_send(av7110, 0, NULL, minicmd);
}
@@ -1188,7 +1174,7 @@ static int stop_ts_capture(struct av7110 *budget)
static int start_ts_capture(struct av7110 *budget)
{
- unsigned y;
+ unsigned int y;
dprintk(2, "budget: %p\n", budget);
@@ -1235,7 +1221,7 @@ static int budget_stop_feed(struct dvb_demux_feed *feed)
static void vpeirq(struct tasklet_struct *t)
{
struct av7110 *budget = from_tasklet(budget, t, vpe_tasklet);
- u8 *mem = (u8 *) (budget->grabbing);
+ u8 *mem = (u8 *)(budget->grabbing);
u32 olddma = budget->ttbp;
u32 newdma = saa7146_read(budget->dev, PCI_VDP3);
struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1;
@@ -1255,17 +1241,16 @@ static void vpeirq(struct tasklet_struct *t)
dma_sync_sg_for_cpu(&budget->dev->pci->dev, budget->pt.slist,
budget->pt.nents, DMA_FROM_DEVICE);
-#if 0
+#ifdef RPS_DEBUG
/* track rps1 activity */
- printk("vpeirq: %02x Event Counter 1 0x%04x\n",
- mem[olddma],
- saa7146_read(budget->dev, EC1R) & 0x3fff);
+ pr_info("%s(): %02x Event Counter 1 0x%04x\n", __func__, mem[olddma],
+ saa7146_read(budget->dev, EC1R) & 0x3fff);
#endif
- if (newdma > olddma)
+ if (newdma > olddma) {
/* no wraparound, dump olddma..newdma */
dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188);
- else {
+ } else {
/* wraparound, dump olddma..buflen and 0..newdma */
dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188);
dvb_dmx_swfilter_packets(demux, mem, newdma / 188);
@@ -1285,7 +1270,7 @@ static int av7110_register(struct av7110 *av7110)
av7110->registered = 1;
- dvbdemux->priv = (void *) av7110;
+ dvbdemux->priv = (void *)av7110;
for (i = 0; i < 32; i++)
av7110->handle2filter[i] = NULL;
@@ -1340,7 +1325,7 @@ static int av7110_register(struct av7110 *av7110)
/* initialize software demux1 without its own frontend
* demux1 hardware is connected to frontend0 of demux0
*/
- dvbdemux1->priv = (void *) av7110;
+ dvbdemux1->priv = (void *)av7110;
dvbdemux1->filternum = 256;
dvbdemux1->feednum = 256;
@@ -1360,12 +1345,11 @@ static int av7110_register(struct av7110 *av7110)
dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter);
dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx);
- printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
+ pr_info("additional demux1 for budget-patch registered\n");
}
return 0;
}
-
static void dvb_unregister(struct av7110 *av7110)
{
struct dvb_demux *dvbdemux = &av7110->demux;
@@ -1392,7 +1376,7 @@ static void dvb_unregister(struct av7110 *av7110)
dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux);
- if (av7110->fe != NULL) {
+ if (av7110->fe) {
dvb_unregister_frontend(av7110->fe);
dvb_frontend_detach(av7110->fe);
}
@@ -1401,7 +1385,6 @@ static void dvb_unregister(struct av7110 *av7110)
av7110_ca_unregister(av7110);
}
-
/****************************************************************************
* I2C client commands
****************************************************************************/
@@ -1426,10 +1409,13 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
msgs[0].flags = 0;
msgs[1].flags = I2C_M_RD;
- msgs[0].addr = msgs[1].addr = id / 2;
+ msgs[0].addr = id / 2;
+ msgs[1].addr = id / 2;
mm1[0] = reg;
- msgs[0].len = 1; msgs[1].len = 1;
- msgs[0].buf = mm1; msgs[1].buf = mm2;
+ msgs[0].len = 1;
+ msgs[1].len = 1;
+ msgs[0].buf = mm1;
+ msgs[1].buf = mm2;
i2c_transfer(&av7110->i2c_adap, msgs, 2);
return mm2[0];
@@ -1439,8 +1425,7 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
* INITIALIZATION
****************************************************************************/
-
-static int check_firmware(struct av7110* av7110)
+static int check_firmware(struct av7110 *av7110)
{
u32 crc = 0, len = 0;
unsigned char *ptr;
@@ -1449,7 +1434,7 @@ static int check_firmware(struct av7110* av7110)
ptr = av7110->bin_fw;
if (ptr[0] != 'A' || ptr[1] != 'V' ||
ptr[2] != 'F' || ptr[3] != 'W') {
- printk("dvb-ttpci: this is not an av7110 firmware\n");
+ pr_err("this is not an av7110 firmware\n");
return -EINVAL;
}
ptr += 4;
@@ -1460,11 +1445,11 @@ static int check_firmware(struct av7110* av7110)
len = get_unaligned_be32(ptr);
ptr += 4;
if (len >= 512) {
- printk("dvb-ttpci: dpram file is way too big.\n");
+ pr_err("dpram file is way too big.\n");
return -EINVAL;
}
if (crc != crc32_le(0, ptr, len)) {
- printk("dvb-ttpci: crc32 of dpram file does not match.\n");
+ pr_err("crc32 of dpram file does not match.\n");
return -EINVAL;
}
av7110->bin_dpram = ptr;
@@ -1479,11 +1464,11 @@ static int check_firmware(struct av7110* av7110)
if (len <= 200000 || len >= 300000 ||
len > ((av7110->bin_fw + av7110->size_fw) - ptr)) {
- printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len);
+ pr_err("root file has strange size (%d). aborting.\n", len);
return -EINVAL;
}
- if( crc != crc32_le(0, ptr, len)) {
- printk("dvb-ttpci: crc32 of root file does not match.\n");
+ if (crc != crc32_le(0, ptr, len)) {
+ pr_err("crc32 of root file does not match.\n");
return -EINVAL;
}
av7110->bin_root = ptr;
@@ -1491,12 +1476,12 @@ static int check_firmware(struct av7110* av7110)
return 0;
}
-static void put_firmware(struct av7110* av7110)
+static void put_firmware(struct av7110 *av7110)
{
vfree(av7110->bin_fw);
}
-static int get_firmware(struct av7110* av7110)
+static int get_firmware(struct av7110 *av7110)
{
int ret;
const struct firmware *fw;
@@ -1505,24 +1490,24 @@ static int get_firmware(struct av7110* av7110)
ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
if (ret) {
if (ret == -ENOENT) {
- printk(KERN_ERR "dvb-ttpci: could not load firmware, file not found: dvb-ttpci-01.fw\n");
- printk(KERN_ERR "dvb-ttpci: usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n");
- printk(KERN_ERR "dvb-ttpci: and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n");
- } else
- printk(KERN_ERR "dvb-ttpci: cannot request firmware (error %i)\n",
- ret);
+ pr_err("could not load firmware, file not found: dvb-ttpci-01.fw\n");
+ pr_err("usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n");
+ pr_err("and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n");
+ } else {
+ pr_err("cannot request firmware (error %i)\n", ret);
+ }
return -EINVAL;
}
if (fw->size <= 200000) {
- printk("dvb-ttpci: this firmware is way too small.\n");
+ pr_err("this firmware is way too small.\n");
release_firmware(fw);
return -EINVAL;
}
/* check if the firmware is available */
av7110->bin_fw = vmalloc(fw->size);
- if (NULL == av7110->bin_fw) {
+ if (!av7110->bin_fw) {
dprintk(1, "out of memory\n");
release_firmware(fw);
return -ENOMEM;
@@ -1530,7 +1515,8 @@ static int get_firmware(struct av7110* av7110)
memcpy(av7110->bin_fw, fw->data, fw->size);
av7110->size_fw = fw->size;
- if ((ret = check_firmware(av7110)))
+ ret = check_firmware(av7110);
+ if (ret)
vfree(av7110->bin_fw);
release_firmware(fw);
@@ -1540,7 +1526,7 @@ static int get_firmware(struct av7110* av7110)
static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u8 pwr = 0;
u8 buf[4];
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
@@ -1569,7 +1555,7 @@ static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
+ if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
@@ -1583,7 +1569,7 @@ static struct ves1x93_config alps_bsrv2_config = {
static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div;
u8 data[4];
struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -1609,13 +1595,10 @@ static struct ves1820_config alps_tdbe2_config = {
.selagc = VES1820_SELAGC_SIGNAMPERR,
};
-
-
-
static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div;
u8 data[4];
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -1637,12 +1620,10 @@ static struct tda8083_config grundig_29504_451_config = {
.demod_address = 0x68,
};
-
-
static int philips_cd1516_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div;
u32 f = p->frequency;
u8 data[4];
@@ -1669,12 +1650,10 @@ static struct ves1820_config philips_cd1516_config = {
.selagc = VES1820_SELAGC_SIGNAMPERR,
};
-
-
static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div, pwr;
u8 data[4];
struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -1698,10 +1677,10 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend *fe)
return 0;
}
-static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+static int alps_tdlb7_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name)
{
#if IS_ENABLED(CONFIG_DVB_SP8870)
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
return request_firmware(fw, name, &av7110->dev->pci->dev);
#else
@@ -1710,12 +1689,10 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir
}
static const struct sp8870_config alps_tdlb7_config = {
-
.demod_address = 0x71,
.request_firmware = alps_tdlb7_request_firmware,
};
-
static u8 nexusca_stv0297_inittab[] = {
0x80, 0x01,
0x80, 0x00,
@@ -1812,7 +1789,7 @@ static u8 nexusca_stv0297_inittab[] = {
static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div;
u8 data[4];
struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
@@ -1839,16 +1816,17 @@ static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) {
- printk("nexusca: pll transfer failed!\n");
+ pr_err("nexusca: pll transfer failed!\n");
return -EIO;
}
// wait for PLL lock
- for(i = 0; i < 20; i++) {
+ for (i = 0; i < 20; i++) {
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1)
- if (data[0] & 0x40) break;
+ if (data[0] & 0x40)
+ break;
msleep(10);
}
@@ -1856,19 +1834,16 @@ static int nexusca_stv0297_tuner_set_params(struct dvb_frontend *fe)
}
static struct stv0297_config nexusca_stv0297_config = {
-
.demod_address = 0x1C,
.inittab = nexusca_stv0297_inittab,
.invert = 1,
.stop_during_read = 1,
};
-
-
static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
u32 div;
u8 cfg, cpump, band_select;
u8 data[4];
@@ -1903,7 +1878,8 @@ static int grundig_29504_401_tuner_set_params(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO;
+ if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
+ return -EIO;
return 0;
}
@@ -1911,8 +1887,6 @@ static struct l64781_config grundig_29504_401_config = {
.demod_address = 0x55,
};
-
-
static int av7110_fe_lock_fix(struct av7110 *av7110, enum fe_status status)
{
int ret = 0;
@@ -1933,7 +1907,7 @@ static int av7110_fe_lock_fix(struct av7110 *av7110, enum fe_status status)
if (synced) {
ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
- av7110->pids[DMX_PES_AUDIO],
+ av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT], 0,
av7110->pids[DMX_PES_PCR]);
if (!ret)
@@ -1956,20 +1930,22 @@ static int av7110_fe_lock_fix(struct av7110 *av7110, enum fe_status status)
static int av7110_fe_set_frontend(struct dvb_frontend *fe)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret)
ret = av7110->fe_set_frontend(fe);
return ret;
}
-static int av7110_fe_init(struct dvb_frontend* fe)
+static int av7110_fe_init(struct dvb_frontend *fe)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret)
ret = av7110->fe_init(fe);
return ret;
@@ -1978,32 +1954,35 @@ static int av7110_fe_init(struct dvb_frontend* fe)
static int av7110_fe_read_status(struct dvb_frontend *fe,
enum fe_status *status)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
/* call the real implementation */
int ret = av7110->fe_read_status(fe, status);
+
if (!ret)
if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
ret = av7110_fe_lock_fix(av7110, *status);
return ret;
}
-static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
+static int av7110_fe_diseqc_reset_overload(struct dvb_frontend *fe)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret)
ret = av7110->fe_diseqc_reset_overload(fe);
return ret;
}
-static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
- struct dvb_diseqc_master_cmd* cmd)
+static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret) {
av7110->saved_master_cmd = *cmd;
ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
@@ -2014,9 +1993,10 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
static int av7110_fe_diseqc_send_burst(struct dvb_frontend *fe,
enum fe_sec_mini_cmd minicmd)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret) {
av7110->saved_minicmd = minicmd;
ret = av7110->fe_diseqc_send_burst(fe, minicmd);
@@ -2027,9 +2007,10 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend *fe,
static int av7110_fe_set_tone(struct dvb_frontend *fe,
enum fe_sec_tone_mode tone)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret) {
av7110->saved_tone = tone;
ret = av7110->fe_set_tone(fe, tone);
@@ -2040,9 +2021,10 @@ static int av7110_fe_set_tone(struct dvb_frontend *fe,
static int av7110_fe_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret) {
av7110->saved_voltage = voltage;
ret = av7110->fe_set_voltage(fe, voltage);
@@ -2050,17 +2032,18 @@ static int av7110_fe_set_voltage(struct dvb_frontend *fe,
return ret;
}
-static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd)
+static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend *fe, unsigned long cmd)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = fe->dvb->priv;
int ret = av7110_fe_lock_fix(av7110, 0);
+
if (!ret)
ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
return ret;
}
-static void dvb_s_recover(struct av7110* av7110)
+static void dvb_s_recover(struct av7110 *av7110)
{
av7110_fe_init(av7110->fe);
@@ -2077,12 +2060,12 @@ static void dvb_s_recover(struct av7110* av7110)
av7110_fe_set_frontend(av7110->fe);
}
-static u8 read_pwm(struct av7110* av7110)
+static u8 read_pwm(struct av7110 *av7110)
{
u8 b = 0xff;
u8 pwm;
- struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
- { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
+ struct i2c_msg msg[] = { { .addr = 0x50, .flags = 0, .buf = &b, .len = 1 },
+ { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1} };
if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
pwm = 0x48;
@@ -2095,18 +2078,17 @@ static int frontend_init(struct av7110 *av7110)
int ret;
if (av7110->dev->pci->subsystem_vendor == 0x110a) {
- switch(av7110->dev->pci->subsystem_device) {
+ switch (av7110->dev->pci->subsystem_device) {
case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config,
- &av7110->i2c_adap, read_pwm(av7110));
- if (av7110->fe) {
+ &av7110->i2c_adap, read_pwm(av7110));
+ if (av7110->fe)
av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
- }
break;
}
} else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
- switch(av7110->dev->pci->subsystem_device) {
+ switch (av7110->dev->pci->subsystem_device) {
case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
@@ -2147,22 +2129,20 @@ static int frontend_init(struct av7110 *av7110)
}
/* Try DVB-C cards */
- switch(av7110->dev->pci->subsystem_device) {
+ switch (av7110->dev->pci->subsystem_device) {
case 0x0000:
/* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap,
read_pwm(av7110));
- if (av7110->fe) {
+ if (av7110->fe)
av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params;
- }
break;
case 0x0003:
/* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */
av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap,
read_pwm(av7110));
- if (av7110->fe) {
+ if (av7110->fe)
av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
- }
break;
}
break;
@@ -2191,9 +2171,8 @@ static int frontend_init(struct av7110 *av7110)
case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
- if (av7110->fe) {
+ if (av7110->fe)
av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
- }
break;
case 0x0004: // Galaxis DVB-S rev1.3
@@ -2243,8 +2222,8 @@ static int frontend_init(struct av7110 *av7110)
av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params;
av7110->fe->tuner_priv = &av7110->i2c_adap;
- if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) {
- printk("dvb-ttpci: LNBP21 not found!\n");
+ if (!dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0)) {
+ pr_err("LNBP21 not found!\n");
if (av7110->fe->ops.release)
av7110->fe->ops.release(av7110->fe);
av7110->fe = NULL;
@@ -2260,11 +2239,9 @@ static int frontend_init(struct av7110 *av7110)
if (!av7110->fe) {
/* FIXME: propagate the failure code from the lower layers */
ret = -ENOMEM;
- printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
- av7110->dev->pci->vendor,
- av7110->dev->pci->device,
- av7110->dev->pci->subsystem_vendor,
- av7110->dev->pci->subsystem_device);
+ pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
+ av7110->dev->pci->vendor, av7110->dev->pci->device,
+ av7110->dev->pci->subsystem_vendor, av7110->dev->pci->subsystem_device);
} else {
FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init);
FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status);
@@ -2278,7 +2255,7 @@ static int frontend_init(struct av7110 *av7110)
ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe);
if (ret < 0) {
- printk("av7110: Frontend registration failed!\n");
+ pr_err("av7110: Frontend registration failed!\n");
dvb_frontend_detach(av7110->fe);
av7110->fe = NULL;
}
@@ -2346,7 +2323,7 @@ static int frontend_init(struct av7110 *av7110)
* The same behaviour of missing VSYNC can be duplicated on budget
* cards, by setting DD1_INIT trigger mode 7 in 3rd nibble.
*/
-static int av7110_attach(struct saa7146_dev* dev,
+static int av7110_attach(struct saa7146_dev *dev,
struct saa7146_pci_extension_data *pci_ext)
{
const int length = TS_WIDTH * TS_HEIGHT;
@@ -2402,9 +2379,9 @@ static int av7110_attach(struct saa7146_dev* dev,
/* RPS1 timeout disable */
saa7146_write(dev, RPS_TOV1, 0);
WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL >> 2));
WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO << 24);
#if RPS_IRQ
/* issue RPS1 interrupt to increment counter */
WRITE_RPS1(CMD_INTERRUPT);
@@ -2419,14 +2396,14 @@ static int av7110_attach(struct saa7146_dev* dev,
* use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
* use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
*/
- saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+ saa7146_write(dev, EC1SSR, (0x03 << 2) | 3);
/* set event counter 1 threshold to maximum allowed value (rEC p55) */
- saa7146_write(dev, ECT1R, 0x3fff );
+ saa7146_write(dev, ECT1R, 0x3fff);
#endif
/* Set RPS1 Address register to point to RPS code (r108 p42) */
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
/* Enable RPS1, (rFC p33) */
- saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
+ saa7146_write(dev, MC1, (MASK_13 | MASK_29));
mdelay(10);
/* now send VSYNC_B to rps1 by rising GPIO3 */
@@ -2437,23 +2414,23 @@ static int av7110_attach(struct saa7146_dev* dev,
*/
if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) {
budgetpatch = 1;
- printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n");
+ pr_info("BUDGET-PATCH DETECTED.\n");
}
/* Disable RPS1 */
- saa7146_write(dev, MC1, ( MASK_29 ));
+ saa7146_write(dev, MC1, (MASK_29));
#if RPS_IRQ
- printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+ pr_info("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff);
#endif
}
/* prepare the av7110 device struct */
- av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL);
+ av7110 = kzalloc(sizeof(*av7110), GFP_KERNEL);
if (!av7110) {
dprintk(1, "out of memory\n");
return -ENOMEM;
}
- av7110->card_name = (char*) pci_ext->ext_priv;
+ av7110->card_name = (char *)pci_ext->ext_priv;
av7110->dev = dev;
dev->ext_priv = av7110;
@@ -2467,7 +2444,8 @@ static int av7110_attach(struct saa7146_dev* dev,
goto err_put_firmware_1;
/* the Siemens DVB needs this if you want to have the i2c chips
- get recognized before the main driver is fully loaded */
+ * get recognized before the main driver is fully loaded
+ */
saa7146_write(dev, GPIO_CTRL, 0x500000);
strscpy(av7110->i2c_adap.name, pci_ext->ext_priv,
@@ -2490,12 +2468,13 @@ static int av7110_attach(struct saa7146_dev* dev,
/* check for full-ts flag in eeprom */
if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) {
u8 flags = i2c_readreg(av7110, 0xaa, 2);
+
if (flags != 0xff && (flags & 0x01))
av7110->full_ts = true;
}
if (av7110->full_ts) {
- printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n");
+ pr_info("full-ts mode enabled for saa7146 port B\n");
spin_lock_init(&av7110->feedlock1);
av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length,
&av7110->pt);
@@ -2553,9 +2532,9 @@ static int av7110_attach(struct saa7146_dev* dev,
* use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
* use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
*/
- saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+ saa7146_write(dev, EC1SSR, (0x03 << 2) | 3);
/* set event counter 1 threshold to maximum allowed value (rEC p55) */
- saa7146_write(dev, ECT1R, 0x3fff );
+ saa7146_write(dev, ECT1R, 0x3fff);
#endif
/* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */
count = 0;
@@ -2563,9 +2542,9 @@ static int av7110_attach(struct saa7146_dev* dev,
/* Wait Source Line Counter Threshold (p36) */
WRITE_RPS1(CMD_PAUSE | EVT_HS);
/* Set GPIO3=1 (p42) */
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL >> 2));
WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
+ WRITE_RPS1(SAA7146_GPIO_OUTHI << 24);
#if RPS_IRQ
/* issue RPS1 interrupt */
WRITE_RPS1(CMD_INTERRUPT);
@@ -2573,9 +2552,9 @@ static int av7110_attach(struct saa7146_dev* dev,
/* Wait reset Source Line Counter Threshold (p36) */
WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
/* Set GPIO3=0 (p42) */
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
+ WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL >> 2));
WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
+ WRITE_RPS1(SAA7146_GPIO_OUTLO << 24);
#if RPS_IRQ
/* issue RPS1 interrupt */
WRITE_RPS1(CMD_INTERRUPT);
@@ -2596,7 +2575,7 @@ static int av7110_attach(struct saa7146_dev* dev,
* then RPS_THRESH1 should be set to trigger
* every TS_HEIGHT (512) lines.
*/
- saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+ saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT * 1) | MASK_12);
/* Enable RPS1 (rFC p33) */
saa7146_write(dev, MC1, (MASK_13 | MASK_29));
@@ -2645,8 +2624,7 @@ static int av7110_attach(struct saa7146_dev* dev,
if (!av7110->debi_virt)
goto err_saa71466_vfree_4;
-
- av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS);
+ av7110->iobuf = vmalloc(AVOUTLEN + AOUTLEN + BMPLEN + 4 * IPACKS);
if (!av7110->iobuf)
goto err_pci_free_5;
@@ -2655,7 +2633,7 @@ static int av7110_attach(struct saa7146_dev* dev,
goto err_iobuf_vfree_6;
/* init BMP buffer */
- av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN;
+ av7110->bmpbuf = av7110->iobuf + AVOUTLEN + AOUTLEN;
init_waitqueue_head(&av7110->bmpq);
ret = av7110_ca_init(av7110);
@@ -2671,12 +2649,11 @@ static int av7110_attach(struct saa7146_dev* dev,
if (ret < 0)
goto err_stop_arm_9;
- if (FW_VERSION(av7110->arm_app)<0x2501)
- printk(KERN_WARNING
- "dvb-ttpci: Warning, firmware version 0x%04x is too old. System might be unstable!\n",
- FW_VERSION(av7110->arm_app));
+ if (FW_VERSION(av7110->arm_app) < 0x2501)
+ pr_warn("Warning, firmware version 0x%04x is too old. System might be unstable!\n",
+ FW_VERSION(av7110->arm_app));
- thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
+ thread = kthread_run(arm_thread, (void *)av7110, "arm_mon");
if (IS_ERR(thread)) {
ret = PTR_ERR(thread);
goto err_stop_arm_9;
@@ -2694,8 +2671,9 @@ static int av7110_attach(struct saa7146_dev* dev,
init_av7110_av(av7110);
/* special case DVB-C: these cards have an analog tuner
- plus need some special handling, so we have separate
- saa7146_ext_vv data for these... */
+ * plus need some special handling, so we have separate
+ * saa7146_ext_vv data for these...
+ */
ret = av7110_init_v4l(av7110);
if (ret < 0)
goto err_av7110_unregister_11;
@@ -2710,7 +2688,7 @@ static int av7110_attach(struct saa7146_dev* dev,
#if IS_ENABLED(CONFIG_DVB_AV7110_IR)
av7110_ir_init(av7110);
#endif
- printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
+ pr_info("found av7110-%d.\n", av7110_num);
av7110_num++;
out:
return ret;
@@ -2746,9 +2724,10 @@ err_kfree_0:
goto out;
}
-static int av7110_detach(struct saa7146_dev* saa)
+static int av7110_detach(struct saa7146_dev *saa)
{
struct av7110 *av7110 = saa->ext_priv;
+
dprintk(4, "%p\n", av7110);
#if IS_ENABLED(CONFIG_DVB_AV7110_IR)
@@ -2789,7 +2768,7 @@ static int av7110_detach(struct saa7146_dev* saa)
i2c_del_adapter(&av7110->i2c_adap);
- dvb_unregister_adapter (&av7110->dvb_adapter);
+ dvb_unregister_adapter(&av7110->dvb_adapter);
av7110_num--;
@@ -2802,8 +2781,7 @@ static int av7110_detach(struct saa7146_dev* saa)
return 0;
}
-
-static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
+static void av7110_irq(struct saa7146_dev *dev, u32 *isr)
{
struct av7110 *av7110 = dev->ext_priv;
@@ -2844,15 +2822,14 @@ static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
tasklet_schedule(&av7110->vpe_tasklet);
}
-
static struct saa7146_extension av7110_extension_driver;
-#define MAKE_AV7110_INFO(x_var,x_name) \
+#define MAKE_AV7110_INFO(x_var, x_name) \
static struct saa7146_pci_extension_data x_var = { \
.ext_priv = x_name, \
.ext = &av7110_extension_driver }
-MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(tts_1_X_fsc, "Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C");
MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
@@ -2877,8 +2854,8 @@ static const struct pci_device_id pci_tbl[] = {
MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e),
MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
+// MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD // Technisat SkyStar1
+// MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD // TT/Hauppauge WinTV Nexus-CA v???
{
.vendor = 0,
@@ -2887,7 +2864,6 @@ static const struct pci_device_id pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, pci_tbl);
-
static struct saa7146_extension av7110_extension_driver = {
.name = "av7110",
.flags = SAA7146_USE_I2C_IRQ,
@@ -2901,13 +2877,11 @@ static struct saa7146_extension av7110_extension_driver = {
.irq_func = av7110_irq,
};
-
static int __init av7110_init(void)
{
return saa7146_register_extension(&av7110_extension_driver);
}
-
static void __exit av7110_exit(void)
{
saa7146_unregister_extension(&av7110_extension_driver);
diff --git a/drivers/staging/media/av7110/av7110.h b/drivers/staging/media/av7110/av7110.h
index 809d938ae166..ec461fd187af 100644
--- a/drivers/staging/media/av7110/av7110.h
+++ b/drivers/staging/media/av7110/av7110.h
@@ -35,16 +35,19 @@
#include <media/drv-intf/saa7146_vv.h>
-
#define ANALOG_TUNER_VES1820 1
#define ANALOG_TUNER_STV0297 2
extern int av7110_debug;
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define dprintk(level, fmt, arg...) do { \
- if (level & av7110_debug) \
- printk(KERN_DEBUG KBUILD_MODNAME ": %s(): " fmt, \
- __func__, ##arg); \
+ if ((level) & av7110_debug) \
+ pr_info("%s(): " fmt, __func__, ##arg); \
} while (0)
#define MAXFILT 32
@@ -59,7 +62,7 @@ enum av7110_video_mode {
struct av7110_p2t {
u8 pes[TS_SIZE];
u8 counter;
- long int pos;
+ long pos;
int frags;
struct dvb_demux_feed *feed;
};
@@ -76,7 +79,6 @@ struct dvb_video_events {
spinlock_t lock;
};
-
struct av7110;
/* infrared remote control */
@@ -88,7 +90,6 @@ struct infrared {
/* place to store all the necessary device information */
struct av7110 {
-
/* devices */
struct dvb_device dvb_dev;
@@ -118,16 +119,15 @@ struct av7110 {
#define DVB_ADAC_MSP34x5 3
#define DVB_ADAC_NONE -1
-
/* buffers */
void *iobuf; /* memory for all buffers */
struct dvb_ringbuffer avout; /* buffer for video or A/V mux */
-#define AVOUTLEN (128*1024)
+#define AVOUTLEN (128 * 1024)
struct dvb_ringbuffer aout; /* buffer for audio */
-#define AOUTLEN (64*1024)
+#define AOUTLEN (64 * 1024)
void *bmpbuf;
-#define BMPLEN (8*32768+1024)
+#define BMPLEN (8 * 32768 + 1024)
/* bitmap buffers and states */
@@ -139,7 +139,6 @@ struct av7110 {
#define BMP_LOADED 2
wait_queue_head_t bmpq;
-
/* DEBI and polled command interface */
spinlock_t debilock;
@@ -147,7 +146,6 @@ struct av7110 {
volatile int debitype;
volatile int debilen;
-
/* Recording and playback flags */
int rec_mode;
@@ -157,7 +155,6 @@ struct av7110 {
#define RP_AUDIO 2
#define RP_AV 3
-
/* OSD */
int osdwin; /* currently active window */
@@ -213,7 +210,6 @@ struct av7110 {
int arm_errors;
int registered;
-
/* AV711X */
u32 arm_fw;
@@ -260,19 +256,19 @@ struct av7110 {
unsigned char *bin_root;
unsigned long size_root;
- struct dvb_frontend* fe;
+ struct dvb_frontend *fe;
enum fe_status fe_status;
struct mutex ioctl_mutex;
/* crash recovery */
- void (*recover)(struct av7110* av7110);
+ void (*recover)(struct av7110 *av7110);
enum fe_sec_voltage saved_voltage;
enum fe_sec_tone_mode saved_tone;
struct dvb_diseqc_master_cmd saved_master_cmd;
enum fe_sec_mini_cmd saved_minicmd;
- int (*fe_init)(struct dvb_frontend* fe);
+ int (*fe_init)(struct dvb_frontend *fe);
int (*fe_read_status)(struct dvb_frontend *fe, enum fe_status *status);
int (*fe_diseqc_reset_overload)(struct dvb_frontend *fe);
int (*fe_diseqc_send_master_cmd)(struct dvb_frontend *fe,
@@ -288,9 +284,8 @@ struct av7110 {
int (*fe_set_frontend)(struct dvb_frontend *fe);
};
-
-extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
- u16 subpid, u16 pcrpid);
+int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+ u16 subpid, u16 pcrpid);
void av7110_ir_handler(struct av7110 *av7110, u32 ircom);
int av7110_set_ir_config(struct av7110 *av7110);
@@ -303,13 +298,12 @@ void av7110_ir_exit(struct av7110 *av7110);
#define MSP_WR_DSP 0x12
#define MSP_RD_DSP 0x13
-extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
-extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
-extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
-
+int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val);
+u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg);
+int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val);
-extern int av7110_init_analog_module(struct av7110 *av7110);
-extern int av7110_init_v4l(struct av7110 *av7110);
-extern int av7110_exit_v4l(struct av7110 *av7110);
+int av7110_init_analog_module(struct av7110 *av7110);
+int av7110_init_v4l(struct av7110 *av7110);
+int av7110_exit_v4l(struct av7110 *av7110);
#endif /* _AV7110_H_ */
diff --git a/drivers/staging/media/av7110/av7110_av.c b/drivers/staging/media/av7110/av7110_av.c
index 00dd6a7fea64..2993ac43c49c 100644
--- a/drivers/staging/media/av7110/av7110_av.c
+++ b/drivers/staging/media/av7110/av7110_av.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * av7110_av.c: audio and video MPEG decoder stuff
+ * driver for the SAA7146 based AV110 cards
+ * - audio and video MPEG decoder stuff
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -70,20 +71,20 @@
#define PIECE_RATE 0x40
#define SEAM_SPLICE 0x20
-
-static void p_to_t(u8 const *buf, long int length, u16 pid,
+static void p_to_t(u8 const *buf, long length, u16 pid,
u8 *counter, struct dvb_demux_feed *feed);
static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len);
-
int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
{
struct dvb_demux_feed *dvbdmxfeed = p2t->priv;
if (!(dvbdmxfeed->ts_type & TS_PACKET))
return 0;
- if (buf[3] == 0xe0) // video PES do not have a length in TS
- buf[4] = buf[5] = 0;
+ if (buf[3] == 0xe0) { // video PES do not have a length in TS
+ buf[4] = 0;
+ buf[5] = 0;
+ }
if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
return dvbdmxfeed->cb.ts(buf, len, NULL, 0,
&dvbdmxfeed->feed.ts, NULL);
@@ -93,7 +94,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len)
static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
{
- struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv;
+ struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)priv;
dvbdmxfeed->cb.ts(data, 188, NULL, 0,
&dvbdmxfeed->feed.ts, NULL);
@@ -119,7 +120,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvb_filter_pes2ts_init(&av7110->p2t[0],
dvbdmx->pesfilter[0]->pid,
dvb_filter_pes2ts_cb,
- (void *) dvbdmx->pesfilter[0]);
+ (void *)dvbdmx->pesfilter[0]);
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break;
@@ -127,7 +128,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvb_filter_pes2ts_init(&av7110->p2t[1],
dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb,
- (void *) dvbdmx->pesfilter[1]);
+ (void *)dvbdmx->pesfilter[1]);
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break;
@@ -135,11 +136,11 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvb_filter_pes2ts_init(&av7110->p2t[0],
dvbdmx->pesfilter[0]->pid,
dvb_filter_pes2ts_cb,
- (void *) dvbdmx->pesfilter[0]);
+ (void *)dvbdmx->pesfilter[0]);
dvb_filter_pes2ts_init(&av7110->p2t[1],
dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb,
- (void *) dvbdmx->pesfilter[1]);
+ (void *)dvbdmx->pesfilter[1]);
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
break;
}
@@ -149,7 +150,8 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
int av7110_av_start_play(struct av7110 *av7110, int av)
{
int ret = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
if (av7110->rec_mode)
return -EBUSY;
@@ -183,7 +185,8 @@ int av7110_av_start_play(struct av7110 *av7110, int av)
int av7110_av_stop(struct av7110 *av7110, int av)
{
int ret = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
if (!(av7110->playing & av) && !(av7110->rec_mode & av))
return 0;
@@ -217,7 +220,6 @@ int av7110_av_stop(struct av7110 *av7110, int av)
return ret;
}
-
int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
{
int len;
@@ -239,38 +241,37 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8;
sync |= DVB_RINGBUFFER_PEEK(buf, 3);
- if (((sync &~ 0x0f) == 0x000001e0) ||
- ((sync &~ 0x1f) == 0x000001c0) ||
+ if (((sync & ~0x0f) == 0x000001e0) ||
+ ((sync & ~0x1f) == 0x000001c0) ||
(sync == 0x000001bd))
break;
- printk("resync\n");
+ pr_info("resync\n");
DVB_RINGBUFFER_SKIP(buf, 1);
}
blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8;
blen |= DVB_RINGBUFFER_PEEK(buf, 5);
blen += 6;
if (len < blen || blen > dlen) {
- //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
+ //pr_info("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen);
wake_up(&buf->queue);
return -1;
}
- dvb_ringbuffer_read(buf, dest, (size_t) blen);
+ dvb_ringbuffer_read(buf, dest, (size_t)blen);
dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
- (unsigned long) buf->pread, (unsigned long) buf->pwrite);
+ (unsigned long)buf->pread, (unsigned long)buf->pwrite);
wake_up(&buf->queue);
return blen;
}
-
int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
unsigned int volright)
{
unsigned int vol, val, balance = 0;
int err;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
av7110->mixer.volume_left = volleft;
av7110->mixer.volume_right = volright;
@@ -283,7 +284,8 @@ int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
volleft = 0x3f;
if (volright > 0x3f)
volright = 0x3f;
- if ((err = SendDAC(av7110, 3, 0x80 + volleft)))
+ err = SendDAC(av7110, 3, 0x80 + volleft);
+ if (err)
return err;
return SendDAC(av7110, 4, volright);
@@ -298,7 +300,7 @@ int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
vol = (volleft > volright) ? volleft : volright;
val = (vol * 0x73 / 255) << 8;
if (vol > 0)
- balance = ((volright - volleft) * 127) / vol;
+ balance = ((volright - volleft) * 127) / vol;
msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8);
msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */
msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */
@@ -320,13 +322,14 @@ int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
{
int ret;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
if (!ret && !av7110->playing) {
ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
- av7110->pids[DMX_PES_AUDIO],
+ av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT],
0, av7110->pids[DMX_PES_PCR]);
if (!ret)
@@ -335,7 +338,6 @@ int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode)
return ret;
}
-
static enum av7110_video_mode sw2mode[16] = {
AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC,
AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL,
@@ -355,7 +357,7 @@ static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
u8 *p;
int ret = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if (av7110->sinfo)
return 0;
@@ -364,8 +366,8 @@ static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
continue;
p += 4;
- hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
- vsize = ((p[1] &0x0F) << 8) | (p[2]);
+ hsize = ((p[1] & 0xF0) >> 4) | (p[0] << 4);
+ vsize = ((p[1] & 0x0F) << 8) | (p[2]);
sw = (p[3] & 0x0F);
ret = av7110_set_vidmode(av7110, sw2mode[sw]);
if (!ret) {
@@ -377,7 +379,6 @@ static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
return ret;
}
-
/****************************************************************************
* I/O buffer management and control
****************************************************************************/
@@ -407,25 +408,27 @@ static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf,
static void play_video_cb(u8 *buf, int count, void *priv)
{
- struct av7110 *av7110 = (struct av7110 *) priv;
- dprintk(2, "av7110:%p, \n", av7110);
+ struct av7110 *av7110 = (struct av7110 *)priv;
+
+ dprintk(2, "av7110:%p\n", av7110);
if ((buf[3] & 0xe0) == 0xe0) {
get_video_format(av7110, buf, count);
aux_ring_buffer_write(&av7110->avout, buf, count);
- } else
+ } else {
aux_ring_buffer_write(&av7110->aout, buf, count);
+ }
}
static void play_audio_cb(u8 *buf, int count, void *priv)
{
- struct av7110 *av7110 = (struct av7110 *) priv;
- dprintk(2, "av7110:%p, \n", av7110);
+ struct av7110 *av7110 = (struct av7110 *)priv;
+
+ dprintk(2, "av7110:%p\n", av7110);
aux_ring_buffer_write(&av7110->aout, buf, count);
}
-
#define FREE_COND_TS (dvb_ringbuffer_free(rb) >= 4096)
static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
@@ -435,7 +438,7 @@ static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
u8 *kb;
unsigned long todo = count;
- dprintk(2, "%s: type %d cnt %lu\n", __func__, type, count);
+ dprintk(2, "type %d cnt %lu\n", type, count);
rb = (type) ? &av7110->avout : &av7110->aout;
kb = av7110->kbuf[type];
@@ -463,7 +466,6 @@ static ssize_t ts_play(struct av7110 *av7110, const char __user *buf,
return count - todo;
}
-
#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \
dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
@@ -471,7 +473,8 @@ static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf,
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -501,10 +504,11 @@ static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf,
}
static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf,
- unsigned long count, int nonblock, int type)
+ unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -534,7 +538,8 @@ static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf,
unsigned long count, int nonblock, int type)
{
unsigned long todo = count, n;
- dprintk(2, "av7110:%p, \n", av7110);
+
+ dprintk(2, "av7110:%p\n", av7110);
if (!av7110->kbuf[type])
return -ENOBUFS;
@@ -546,8 +551,8 @@ static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf,
if (nonblock)
return count - todo;
if (wait_event_interruptible(av7110->aout.queue,
- (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
- return count-todo;
+ (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)))
+ return count - todo;
}
n = todo;
if (n > IPACKS * 2)
@@ -580,8 +585,7 @@ static void clear_p2t(struct av7110_p2t *p)
p->frags = 0;
}
-
-static int find_pes_header(u8 const *buf, long int length, int *frags)
+static int find_pes_header(u8 const *buf, long length, int *frags)
{
int c = 0;
int found = 0;
@@ -591,7 +595,7 @@ static int find_pes_header(u8 const *buf, long int length, int *frags)
while (c < length - 3 && !found) {
if (buf[c] == 0x00 && buf[c + 1] == 0x00 &&
buf[c + 2] == 0x01) {
- switch ( buf[c + 3] ) {
+ switch (buf[c + 3]) {
case PROG_STREAM_MAP:
case PRIVATE_STREAM2:
case PROG_STREAM_DIR:
@@ -610,8 +614,9 @@ static int find_pes_header(u8 const *buf, long int length, int *frags)
c++;
break;
}
- } else
+ } else {
c++;
+ }
}
if (c == length - 3 && !found) {
if (buf[length - 1] == 0x00)
@@ -629,16 +634,16 @@ static int find_pes_header(u8 const *buf, long int length, int *frags)
return c;
}
-void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p)
+void av7110_p2t_write(u8 const *buf, long length, u16 pid, struct av7110_p2t *p)
{
int c, c2, l, add;
int check, rest;
c = 0;
c2 = 0;
- if (p->frags){
+ if (p->frags) {
check = 0;
- switch(p->frags) {
+ switch (p->frags) {
case 1:
if (buf[c] == 0x00 && buf[c + 1] == 0x01) {
check = 1;
@@ -689,7 +694,7 @@ void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t
if (p->pos) {
c2 = find_pes_header(buf + c, length - c, &p->frags);
if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos)
- l = c2+c;
+ l = c2 + c;
else
l = (TS_SIZE - 4) - p->pos;
memcpy(p->pes + p->pos, buf, l);
@@ -704,13 +709,14 @@ void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t
c2 = find_pes_header(buf + c + add, length - c - add, &p->frags);
if (c2 >= 0) {
c2 += c + add;
- if (c2 > c){
+ if (c2 > c) {
p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed);
c = c2;
clear_p2t(p);
add = 0;
- } else
+ } else {
add = 1;
+ }
} else {
l = length - c;
rest = l % (TS_SIZE - 4);
@@ -723,7 +729,6 @@ void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t
}
}
-
static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length)
{
int i;
@@ -758,8 +763,7 @@ static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 len
return c;
}
-
-static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
+static void p_to_t(u8 const *buf, long length, u16 pid, u8 *counter,
struct dvb_demux_feed *feed)
{
int l, pes_start;
@@ -768,7 +772,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
pes_start = 0;
if (length > 3 &&
- buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
+ buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)
switch (buf[3]) {
case PROG_STREAM_MAP:
case PRIVATE_STREAM2:
@@ -790,7 +794,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
while (c < length) {
memset(obuf, 0, TS_SIZE);
- if (length - c >= (TS_SIZE - 4)){
+ if (length - c >= (TS_SIZE - 4)) {
l = write_ts_header2(pid, counter, pes_start,
obuf, (TS_SIZE - 4));
memcpy(obuf + l, buf + c, TS_SIZE - l);
@@ -806,7 +810,6 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter,
}
}
-
static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, size_t len)
{
struct ipack *ipack = &av7110->ipack[type];
@@ -833,13 +836,12 @@ static int write_ts_to_decoder(struct av7110 *av7110, int type, const u8 *buf, s
return 0;
}
-
int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len)
{
struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE)
return 0;
@@ -860,8 +862,6 @@ int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t l
return write_ts_to_decoder(av7110, feed->pes_type, buf, len);
}
-
-
/******************************************************************************
* Video MPEG decoder events
******************************************************************************/
@@ -887,8 +887,7 @@ void dvb_video_add_event(struct av7110 *av7110, struct video_event *event)
wake_up_interruptible(&events->wait_queue);
}
-
-static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags)
+static int dvb_video_get_event(struct av7110 *av7110, struct video_event *event, int flags)
{
struct dvb_video_events *events = &av7110->video_events;
@@ -929,7 +928,7 @@ static __poll_t dvb_video_poll(struct file *file, poll_table *wait)
struct av7110 *av7110 = dvbdev->priv;
__poll_t mask = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if ((file->f_flags & O_ACCMODE) != O_RDONLY)
poll_wait(file, &av7110->avout.queue, wait);
@@ -959,7 +958,7 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
struct av7110 *av7110 = dvbdev->priv;
unsigned char c;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
return -EPERM;
@@ -981,15 +980,17 @@ static __poll_t dvb_audio_poll(struct file *file, poll_table *wait)
struct av7110 *av7110 = dvbdev->priv;
__poll_t mask = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
poll_wait(file, &av7110->aout.queue, wait);
if (av7110->playing) {
if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024)
mask |= (EPOLLOUT | EPOLLWRNORM);
- } else /* if not playing: may play if asked for */
+ } else {
+ /* if not playing: may play if asked for */
mask = (EPOLLOUT | EPOLLWRNORM);
+ }
return mask;
}
@@ -1001,10 +1002,10 @@ static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
struct av7110 *av7110 = dvbdev->priv;
unsigned char c;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) {
- printk(KERN_ERR "not audio source memory\n");
+ pr_err("not audio source memory\n");
return -EPERM;
}
@@ -1022,11 +1023,11 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x
static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock)
{
- unsigned i, n;
+ unsigned int i, n;
int progressive = 0;
int match = 0;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if (len == 0)
return 0;
@@ -1039,6 +1040,7 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
/* search in buf for instances of 00 00 01 b5 1? */
for (i = 0; i < len; i++) {
unsigned char c;
+
if (get_user(c, buf + i))
return -EFAULT;
if (match == 5) {
@@ -1050,13 +1052,16 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
continue;
}
switch (match++) {
- case 2: if (c == 0x01)
+ case 2:
+ if (c == 0x01)
continue;
break;
- case 3: if (c == 0xb5)
+ case 3:
+ if (c == 0xb5)
continue;
break;
- case 4: if ((c & 0xf0) == 0x10)
+ case 4:
+ if ((c & 0xf0) == 0x10)
continue;
break;
}
@@ -1064,7 +1069,8 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
}
/* setting n always > 1, fixes problems when playing stillframes
- consisting of I- and P-Frames */
+ * consisting of I- and P-Frames
+ */
n = MIN_IFRAME / len + 1;
/* FIXME: nonblock? */
@@ -1084,8 +1090,9 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len
#ifdef CONFIG_COMPAT
struct compat_video_still_picture {
compat_uptr_t iFrame;
- int32_t size;
+ s32 size;
};
+
#define VIDEO_STILLPICTURE32 _IOW('o', 30, struct compat_video_still_picture)
struct compat_video_event {
@@ -1098,6 +1105,7 @@ struct compat_video_event {
unsigned char vsync_field; /* unknown/odd/even/progressive */
} u;
};
+
#define VIDEO_GET_EVENT32 _IOR('o', 28, struct compat_video_event)
static int dvb_compat_video_get_event(struct av7110 *av7110,
@@ -1123,14 +1131,14 @@ static int dvb_video_ioctl(struct file *file,
{
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- unsigned long arg = (unsigned long) parg;
+ unsigned long arg = (unsigned long)parg;
int ret = 0;
- dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
+ dprintk(1, "av7110:%p, cmd=%04x\n", av7110, cmd);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
- if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
- cmd != VIDEO_GET_SIZE ) {
+ if (cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
+ cmd != VIDEO_GET_SIZE) {
return -EPERM;
}
}
@@ -1145,7 +1153,7 @@ static int dvb_video_ioctl(struct file *file,
ret = av7110_av_stop(av7110, RP_VIDEO);
else
ret = vidcom(av7110, AV_VIDEO_CMD_STOP,
- av7110->videostate.video_blank ? 0 : 1);
+ av7110->videostate.video_blank ? 0 : 1);
if (!ret)
av7110->trickmode = TRICK_NONE;
break;
@@ -1195,11 +1203,11 @@ static int dvb_video_ioctl(struct file *file,
break;
case VIDEO_SELECT_SOURCE:
- av7110->videostate.stream_source = (video_stream_source_t) arg;
+ av7110->videostate.stream_source = (video_stream_source_t)arg;
break;
case VIDEO_SET_BLANK:
- av7110->videostate.video_blank = (int) arg;
+ av7110->videostate.video_blank = (int)arg;
break;
case VIDEO_GET_STATUS:
@@ -1222,7 +1230,8 @@ static int dvb_video_ioctl(struct file *file,
case VIDEO_SET_DISPLAY_FORMAT:
{
- video_displayformat_t format = (video_displayformat_t) arg;
+ video_displayformat_t format = (video_displayformat_t)arg;
+
switch (format) {
case VIDEO_PAN_SCAN:
av7110->display_panscan = VID_PAN_SCAN_PREF;
@@ -1251,14 +1260,14 @@ static int dvb_video_ioctl(struct file *file,
}
av7110->display_ar = arg;
ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType,
- 1, (u16) arg);
+ 1, (u16)arg);
break;
#ifdef CONFIG_COMPAT
case VIDEO_STILLPICTURE32:
{
struct compat_video_still_picture *pic =
- (struct compat_video_still_picture *) parg;
+ (struct compat_video_still_picture *)parg;
av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
ret = play_iframe(av7110, compat_ptr(pic->iFrame),
@@ -1270,7 +1279,7 @@ static int dvb_video_ioctl(struct file *file,
case VIDEO_STILLPICTURE:
{
struct video_still_picture *pic =
- (struct video_still_picture *) parg;
+ (struct video_still_picture *)parg;
av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY;
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
ret = play_iframe(av7110, pic->iFrame, pic->size,
@@ -1292,7 +1301,7 @@ static int dvb_video_ioctl(struct file *file,
break;
case VIDEO_SLOWMOTION:
- if (av7110->playing&RP_VIDEO) {
+ if (av7110->playing & RP_VIDEO) {
if (av7110->trickmode != TRICK_SLOW)
ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
if (!ret)
@@ -1354,10 +1363,10 @@ static int dvb_audio_ioctl(struct file *file,
{
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- unsigned long arg = (unsigned long) parg;
+ unsigned long arg = (unsigned long)parg;
int ret = 0;
- dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
+ dprintk(1, "av7110:%p, cmd=%04x\n", av7110, cmd);
if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
(cmd != AUDIO_GET_STATUS))
@@ -1399,19 +1408,19 @@ static int dvb_audio_ioctl(struct file *file,
break;
case AUDIO_SELECT_SOURCE:
- av7110->audiostate.stream_source = (audio_stream_source_t) arg;
+ av7110->audiostate.stream_source = (audio_stream_source_t)arg;
break;
case AUDIO_SET_MUTE:
{
ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
if (!ret)
- av7110->audiostate.mute_state = (int) arg;
+ av7110->audiostate.mute_state = (int)arg;
break;
}
case AUDIO_SET_AV_SYNC:
- av7110->audiostate.AV_sync_state = (int) arg;
+ av7110->audiostate.AV_sync_state = (int)arg;
ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
break;
@@ -1422,8 +1431,8 @@ static int dvb_audio_ioctl(struct file *file,
break;
case AUDIO_CHANNEL_SELECT:
- av7110->audiostate.channel_select = (audio_channel_select_t) arg;
- switch(av7110->audiostate.channel_select) {
+ av7110->audiostate.channel_select = (audio_channel_select_t)arg;
+ switch (av7110->audiostate.channel_select) {
case AUDIO_STEREO:
ret = audcom(av7110, AUDIO_CMD_STEREO);
if (!ret) {
@@ -1483,6 +1492,7 @@ static int dvb_audio_ioctl(struct file *file,
case AUDIO_SET_MIXER:
{
struct audio_mixer *amix = (struct audio_mixer *)parg;
+
ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
break;
}
@@ -1498,16 +1508,16 @@ static int dvb_audio_ioctl(struct file *file,
return ret;
}
-
static int dvb_video_open(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
int err;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
- if ((err = dvb_generic_open(inode, file)) < 0)
+ err = dvb_generic_open(inode, file);
+ if (err < 0)
return err;
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
@@ -1518,7 +1528,8 @@ static int dvb_video_open(struct inode *inode, struct file *file)
av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX;
/* empty event queue */
- av7110->video_events.eventr = av7110->video_events.eventw = 0;
+ av7110->video_events.eventr = 0;
+ av7110->video_events.eventw = 0;
}
return 0;
@@ -1529,11 +1540,10 @@ static int dvb_video_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
- if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+ if ((file->f_flags & O_ACCMODE) != O_RDONLY)
av7110_av_stop(av7110, RP_VIDEO);
- }
return dvb_generic_release(inode, file);
}
@@ -1544,7 +1554,7 @@ static int dvb_audio_open(struct inode *inode, struct file *file)
struct av7110 *av7110 = dvbdev->priv;
int err = dvb_generic_open(inode, file);
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
if (err < 0)
return err;
@@ -1558,14 +1568,12 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- dprintk(2, "av7110:%p, \n", av7110);
+ dprintk(2, "av7110:%p\n", av7110);
av7110_av_stop(av7110, RP_AUDIO);
return dvb_generic_release(inode, file);
}
-
-
/******************************************************************************
* driver registration
******************************************************************************/
@@ -1609,7 +1617,6 @@ static struct dvb_device dvbdev_audio = {
.kernel_ioctl = dvb_audio_ioctl,
};
-
int av7110_av_register(struct av7110 *av7110)
{
av7110->audiostate.AV_sync_state = 0;
@@ -1629,9 +1636,10 @@ int av7110_av_register(struct av7110 *av7110)
init_waitqueue_head(&av7110->video_events.wait_queue);
spin_lock_init(&av7110->video_events.lock);
- av7110->video_events.eventw = av7110->video_events.eventr = 0;
+ av7110->video_events.eventw = 0;
+ av7110->video_events.eventr = 0;
av7110->video_events.overflow = 0;
- memset(&av7110->video_size, 0, sizeof (video_size_t));
+ memset(&av7110->video_size, 0, sizeof(video_size_t));
dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev,
&dvbdev_video, av7110, DVB_DEVICE_VIDEO, 0);
diff --git a/drivers/staging/media/av7110/av7110_av.h b/drivers/staging/media/av7110/av7110_av.h
index 71bbd4391f57..eebaf59c7585 100644
--- a/drivers/staging/media/av7110/av7110_av.h
+++ b/drivers/staging/media/av7110/av7110_av.h
@@ -4,29 +4,28 @@
struct av7110;
-extern int av7110_set_vidmode(struct av7110 *av7110,
- enum av7110_video_mode mode);
+int av7110_set_vidmode(struct av7110 *av7110,
+ enum av7110_video_mode mode);
-extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
-extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
-extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
+int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
+int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
+int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
-extern int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
- unsigned int volright);
-extern int av7110_av_stop(struct av7110 *av7110, int av);
-extern int av7110_av_start_record(struct av7110 *av7110, int av,
- struct dvb_demux_feed *dvbdmxfeed);
-extern int av7110_av_start_play(struct av7110 *av7110, int av);
+int av7110_set_volume(struct av7110 *av7110, unsigned int volleft,
+ unsigned int volright);
+int av7110_av_stop(struct av7110 *av7110, int av);
+int av7110_av_start_record(struct av7110 *av7110, int av,
+ struct dvb_demux_feed *dvbdmxfeed);
+int av7110_av_start_play(struct av7110 *av7110, int av);
-extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
+void dvb_video_add_event(struct av7110 *av7110, struct video_event *event);
-extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
-extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p);
-
-extern int av7110_av_register(struct av7110 *av7110);
-extern void av7110_av_unregister(struct av7110 *av7110);
-extern int av7110_av_init(struct av7110 *av7110);
-extern void av7110_av_exit(struct av7110 *av7110);
+void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed);
+void av7110_p2t_write(u8 const *buf, long length, u16 pid, struct av7110_p2t *p);
+int av7110_av_register(struct av7110 *av7110);
+void av7110_av_unregister(struct av7110 *av7110);
+int av7110_av_init(struct av7110 *av7110);
+void av7110_av_exit(struct av7110 *av7110);
#endif /* _AV7110_AV_H_ */
diff --git a/drivers/staging/media/av7110/av7110_ca.c b/drivers/staging/media/av7110/av7110_ca.c
index c1338e074a3d..6ce212c64e5d 100644
--- a/drivers/staging/media/av7110/av7110_ca.c
+++ b/drivers/staging/media/av7110/av7110_ca.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * av7110_ca.c: CA and CI stuff
+ * driver for the SAA7146 based AV110 cards
+ * - CA and CI stuff
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -23,10 +24,9 @@
#include "av7110_hw.h"
#include "av7110_ca.h"
-
void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
{
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
if (len < 3)
return;
@@ -54,7 +54,6 @@ void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
}
}
-
void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
{
if (dvb_ringbuffer_free(cibuf) < len + 2)
@@ -66,7 +65,6 @@ void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len)
wake_up_interruptible(&cibuf->queue);
}
-
/******************************************************************************
* CI link layer file ops
******************************************************************************/
@@ -201,7 +199,7 @@ static int dvb_ca_open(struct inode *inode, struct file *file)
struct av7110 *av7110 = dvbdev->priv;
int err = dvb_generic_open(inode, file);
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
if (err < 0)
return err;
@@ -209,7 +207,7 @@ static int dvb_ca_open(struct inode *inode, struct file *file)
return 0;
}
-static __poll_t dvb_ca_poll (struct file *file, poll_table *wait)
+static __poll_t dvb_ca_poll(struct file *file, poll_table *wait)
{
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
@@ -217,7 +215,7 @@ static __poll_t dvb_ca_poll (struct file *file, poll_table *wait)
struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
__poll_t mask = 0;
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
poll_wait(file, &rbuf->queue, wait);
poll_wait(file, &wbuf->queue, wait);
@@ -235,10 +233,10 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- unsigned long arg = (unsigned long) parg;
+ unsigned long arg = (unsigned long)parg;
int ret = 0;
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
if (mutex_lock_interruptible(&av7110->ioctl_mutex))
return -ERESTARTSYS;
@@ -263,7 +261,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
case CA_GET_SLOT_INFO:
{
- struct ca_slot_info *info=(struct ca_slot_info *)parg;
+ struct ca_slot_info *info = (struct ca_slot_info *)parg;
if (info->num < 0 || info->num > 1) {
mutex_unlock(&av7110->ioctl_mutex);
@@ -288,24 +286,24 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg)
info.num = 16;
info.type = CA_ECD;
- memcpy(parg, &info, sizeof (info));
+ memcpy(parg, &info, sizeof(info));
break;
}
case CA_SET_DESCR:
{
- struct ca_descr *descr = (struct ca_descr*) parg;
+ struct ca_descr *descr = (struct ca_descr *)parg;
if (descr->index >= 16 || descr->parity > 1) {
mutex_unlock(&av7110->ioctl_mutex);
return -EINVAL;
}
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5,
- (descr->index<<8)|descr->parity,
- (descr->cw[0]<<8)|descr->cw[1],
- (descr->cw[2]<<8)|descr->cw[3],
- (descr->cw[4]<<8)|descr->cw[5],
- (descr->cw[6]<<8)|descr->cw[7]);
+ (descr->index << 8) | descr->parity,
+ (descr->cw[0] << 8) | descr->cw[1],
+ (descr->cw[2] << 8) | descr->cw[3],
+ (descr->cw[4] << 8) | descr->cw[5],
+ (descr->cw[6] << 8) | descr->cw[7]);
break;
}
@@ -324,7 +322,7 @@ static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
}
@@ -334,7 +332,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf,
struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = dvbdev->priv;
- dprintk(8, "av7110:%p\n",av7110);
+ dprintk(8, "av7110:%p\n", av7110);
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}
@@ -357,7 +355,6 @@ static struct dvb_device dvbdev_ca = {
.kernel_ioctl = dvb_ca_ioctl,
};
-
int av7110_ca_register(struct av7110 *av7110)
{
return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev,
@@ -369,12 +366,12 @@ void av7110_ca_unregister(struct av7110 *av7110)
dvb_unregister_device(av7110->ca_dev);
}
-int av7110_ca_init(struct av7110* av7110)
+int av7110_ca_init(struct av7110 *av7110)
{
return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192);
}
-void av7110_ca_exit(struct av7110* av7110)
+void av7110_ca_exit(struct av7110 *av7110)
{
ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer);
}
diff --git a/drivers/staging/media/av7110/av7110_ca.h b/drivers/staging/media/av7110/av7110_ca.h
index a6e3f2955730..d3521944b97c 100644
--- a/drivers/staging/media/av7110/av7110_ca.h
+++ b/drivers/staging/media/av7110/av7110_ca.h
@@ -4,12 +4,12 @@
struct av7110;
-extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
-extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
+void CI_handle(struct av7110 *av7110, u8 *data, u16 len);
+void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len);
-extern int av7110_ca_register(struct av7110 *av7110);
-extern void av7110_ca_unregister(struct av7110 *av7110);
-extern int av7110_ca_init(struct av7110* av7110);
-extern void av7110_ca_exit(struct av7110* av7110);
+int av7110_ca_register(struct av7110 *av7110);
+void av7110_ca_unregister(struct av7110 *av7110);
+int av7110_ca_init(struct av7110 *av7110);
+void av7110_ca_exit(struct av7110 *av7110);
#endif /* _AV7110_CA_H_ */
diff --git a/drivers/staging/media/av7110/av7110_hw.c b/drivers/staging/media/av7110/av7110_hw.c
index a0be37717259..bf8e6dca40e5 100644
--- a/drivers/staging/media/av7110/av7110_hw.c
+++ b/drivers/staging/media/av7110/av7110_hw.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * av7110_hw.c: av7110 low level hardware access and firmware interface
+ * driver for the SAA7146 based AV110 cards
+ * - av7110 low level hardware access and firmware interface
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -38,7 +39,8 @@
****************************************************************************/
/* This DEBI code is based on the Stradis driver
- by Nathan Laredo <[email protected]> */
+ * by Nathan Laredo <[email protected]>
+ */
int av7110_debiwrite(struct av7110 *av7110, u32 config,
int addr, u32 val, unsigned int count)
@@ -46,11 +48,11 @@ int av7110_debiwrite(struct av7110 *av7110, u32 config,
struct saa7146_dev *dev = av7110->dev;
if (count > 32764) {
- printk("%s: invalid count %d\n", __func__, count);
+ pr_err("%s(): invalid count %d\n", __func__, count);
return -1;
}
if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
- printk("%s: wait_for_debi_done failed\n", __func__);
+ pr_err("%s(): wait_for_debi_done failed\n", __func__);
return -1;
}
saa7146_write(dev, DEBI_CONFIG, config);
@@ -69,11 +71,11 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int co
u32 result = 0;
if (count > 32764) {
- printk("%s: invalid count %d\n", __func__, count);
+ pr_err("%s(): invalid count %d\n", __func__, count);
return 0;
}
if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
- printk("%s: wait_for_debi_done #1 failed\n", __func__);
+ pr_err("%s(): wait_for_debi_done #1 failed\n", __func__);
return 0;
}
saa7146_write(dev, DEBI_AD, av7110->debi_bus);
@@ -84,7 +86,7 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int co
if (count > 4)
return count;
if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) {
- printk("%s: wait_for_debi_done #2 failed\n", __func__);
+ pr_err("%s(): wait_for_debi_done #2 failed\n", __func__);
return 0;
}
@@ -93,8 +95,6 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, unsigned int co
return result;
}
-
-
/* av7110 ARM core boot stuff */
#if 0
void av7110_reset_arm(struct av7110 *av7110)
@@ -146,7 +146,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
for (i = 0; i < blocks; i++) {
if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
- printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
+ pr_err("%s(): timeout at block %d\n", __func__, i);
return -ETIMEDOUT;
}
dprintk(4, "writing DRAM block %d\n", i);
@@ -161,7 +161,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
if (rest > 0) {
if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
- printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
+ pr_err("%s(): timeout at last block\n", __func__);
return -ETIMEDOUT;
}
if (rest > 4)
@@ -176,21 +176,21 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len)
iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
}
if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
- printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
+ pr_err("%s(): timeout after last block\n", __func__);
return -ETIMEDOUT;
}
iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2);
iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) {
- printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
+ pr_err("%s(): final handshake timeout\n", __func__);
return -ETIMEDOUT;
}
return 0;
}
-
/* we cannot write av7110 DRAM directly, so load a bootloader into
- * the DPRAM which implements a simple boot protocol */
+ * the DPRAM which implements a simple boot protocol
+ */
int av7110_bootarm(struct av7110 *av7110)
{
const struct firmware *fw;
@@ -219,9 +219,10 @@ int av7110_bootarm(struct av7110 *av7110)
/* FIXME: Why does Nexus CA require 2x iwdebi for first init? */
iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4);
- if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) {
- printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: %08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
- ret, 0x10325476);
+ ret = irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4);
+ if (ret != 0x10325476) {
+ pr_err("debi test in %s() failed: %08x != %08x (check your BIOS 'Plug&Play OS' settings)\n",
+ __func__, ret, 0x10325476);
return -1;
}
for (i = 0; i < 8192; i += 4)
@@ -236,8 +237,7 @@ int av7110_bootarm(struct av7110 *av7110)
ret = request_firmware(&fw, fw_name, &dev->pci->dev);
if (ret) {
- printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
- fw_name);
+ pr_err("Failed to load firmware \"%s\"\n", fw_name);
return ret;
}
@@ -246,7 +246,7 @@ int av7110_bootarm(struct av7110 *av7110)
iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
- printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out\n");
+ pr_err("%s(): saa7146_wait_for_debi_done() timed out\n", __func__);
return -ETIMEDOUT;
}
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
@@ -254,7 +254,7 @@ int av7110_bootarm(struct av7110 *av7110)
dprintk(1, "load dram code\n");
if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) {
- printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): load_dram() failed\n");
+ pr_err("%s(): load_dram() failed\n", __func__);
return -1;
}
@@ -265,7 +265,7 @@ int av7110_bootarm(struct av7110 *av7110)
mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram);
if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
- printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): saa7146_wait_for_debi_done() timed out after loading DRAM\n");
+ pr_err("%s(): saa7146_wait_for_debi_done() timed out after loading DRAM\n", __func__);
return -ETIMEDOUT;
}
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
@@ -309,8 +309,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
if ((stat & flags) == 0)
break;
if (err) {
- printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
- __func__, stat & flags);
+ pr_err("%s(): timeout waiting for MSGSTATE %04x\n", __func__, stat & flags);
return -ETIMEDOUT;
}
msleep(1);
@@ -318,7 +317,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
return 0;
}
-static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
{
int i;
unsigned long start;
@@ -340,7 +339,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__);
+ pr_err("%s(): timeout waiting for COMMAND idle\n", __func__);
av7110->arm_errors++;
return -ETIMEDOUT;
}
@@ -357,7 +356,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__);
+ pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__);
return -ETIMEDOUT;
}
msleep(1);
@@ -389,22 +388,20 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
break;
}
- if (type != NULL) {
+ if (type) {
/* non-immediate COMMAND type */
start = jiffies;
for (;;) {
err = time_after(jiffies, start + ARM_WAIT_FREE);
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & flags[0]) {
- printk(KERN_ERR "%s: %s QUEUE overflow\n",
- __func__, type);
+ pr_err("%s(): %s QUEUE overflow\n", __func__, type);
return -1;
}
if ((stat & flags[1]) == 0)
break;
if (err) {
- printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
- __func__, type);
+ pr_err("%s(): timeout waiting on busy %s QUEUE\n", __func__, type);
av7110->arm_errors++;
return -ETIMEDOUT;
}
@@ -413,14 +410,14 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
}
for (i = 2; i < length; i++)
- wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
+ wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32)buf[i], 2);
if (length)
- wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2);
+ wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32)buf[1], 2);
else
wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2);
- wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2);
+ wdebi(av7110, DEBINOSWAP, COMMAND, (u32)buf[0], 2);
if (FW_VERSION(av7110->arm_app) <= 0x261f)
wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2);
@@ -432,7 +429,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
+ pr_err("%s(): timeout waiting for COMMAND %d to complete\n",
__func__, (buf[0] >> 8) & 0xff);
return -ETIMEDOUT;
}
@@ -441,11 +438,10 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & GPMQOver) {
- printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__);
+ pr_err("%s(): GPMQOver\n", __func__);
return -ENOSPC;
- }
- else if (stat & OSDQOver) {
- printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__);
+ } else if (stat & OSDQOver) {
+ pr_err("%s(): OSDQOver\n", __func__);
return -ENOSPC;
}
#endif
@@ -453,7 +449,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
return 0;
}
-static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
+static int av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
{
int ret;
@@ -468,9 +464,8 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
ret = __av7110_send_fw_cmd(av7110, buf, length);
mutex_unlock(&av7110->dcomlock);
- if (ret && ret!=-ERESTARTSYS)
- printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
- __func__, ret);
+ if (ret && ret != -ERESTARTSYS)
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
@@ -483,9 +478,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
// dprintk(4, "%p\n", av7110);
if (2 + num > ARRAY_SIZE(buf)) {
- printk(KERN_WARNING
- "%s: %s len=%d is too big!\n",
- KBUILD_MODNAME, __func__, num);
+ pr_warn("%s(): len=%d is too big!\n", __func__, num);
return -EINVAL;
}
@@ -501,7 +494,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...)
ret = av7110_send_fw_cmd(av7110, buf, num + 2);
if (ret && ret != -ERESTARTSYS)
- printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
@@ -514,9 +507,8 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
dprintk(4, "%p\n", av7110);
- for(i = 0; i < len && i < 32; i++)
- {
- if(i % 2 == 0)
+ for (i = 0; i < len && i < 32; i++) {
+ if (i % 2 == 0)
cmd[(i / 2) + 2] = (u16)(buf[i]) << 8;
else
cmd[(i / 2) + 2] |= buf[i];
@@ -524,7 +516,7 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len)
ret = av7110_send_fw_cmd(av7110, cmd, 18);
if (ret && ret != -ERESTARTSYS)
- printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
#endif /* 0 */
@@ -549,9 +541,10 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
if (mutex_lock_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
- if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) {
+ err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len);
+ if (err < 0) {
mutex_unlock(&av7110->dcomlock);
- printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err);
+ pr_err("%s(): error %d\n", __func__, err);
return err;
}
@@ -561,7 +554,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__);
+ pr_err("%s(): timeout waiting for COMMAND to complete\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
@@ -577,7 +570,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__);
+ pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
@@ -588,12 +581,11 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
#ifdef COM_DEBUG
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (stat & GPMQOver) {
- printk(KERN_ERR "%s: GPMQOver\n", __func__);
+ pr_err("%s(): GPMQOver\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -1;
- }
- else if (stat & OSDQOver) {
- printk(KERN_ERR "%s: OSDQOver\n", __func__);
+ } else if (stat & OSDQOver) {
+ pr_err("%s(): OSDQOver\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -1;
}
@@ -606,16 +598,16 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
return 0;
}
-static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length)
+static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16 *buf, s16 length)
{
int ret;
+
ret = av7110_fw_request(av7110, &tag, 0, buf, length);
if (ret)
- printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret);
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
-
/****************************************************************************
* Firmware commands
****************************************************************************/
@@ -629,8 +621,7 @@ int av7110_firmversion(struct av7110 *av7110)
dprintk(4, "%p\n", av7110);
if (av7110_fw_query(av7110, tag, buf, 16)) {
- printk("dvb-ttpci: failed to boot firmware @ card %d\n",
- av7110->dvb_adapter.num);
+ pr_err("failed to boot firmware @ card %d\n", av7110->dvb_adapter.num);
return -EIO;
}
@@ -640,22 +631,21 @@ int av7110_firmversion(struct av7110 *av7110)
av7110->arm_app = (buf[6] << 16) + buf[7];
av7110->avtype = (buf[8] << 16) + buf[9];
- printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
- av7110->dvb_adapter.num, av7110->arm_fw,
- av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
+ pr_info("info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n",
+ av7110->dvb_adapter.num, av7110->arm_fw,
+ av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app);
/* print firmware capabilities */
if (FW_CI_LL_SUPPORT(av7110->arm_app))
- printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n",
- av7110->dvb_adapter.num);
+ pr_info("firmware @ card %d supports CI link layer interface\n",
+ av7110->dvb_adapter.num);
else
- printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n",
- av7110->dvb_adapter.num);
+ pr_info("no firmware support for CI link layer interface @ card %d\n",
+ av7110->dvb_adapter.num);
return 0;
}
-
int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst)
{
int i, ret;
@@ -679,12 +669,11 @@ int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long bu
buf[i + 4] = msg[i];
ret = av7110_send_fw_cmd(av7110, buf, 18);
- if (ret && ret!=-ERESTARTSYS)
- printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
+ if (ret && ret != -ERESTARTSYS)
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
-
#ifdef CONFIG_DVB_AV7110_OSD
static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
@@ -693,14 +682,14 @@ static inline int SetColorBlend(struct av7110 *av7110, u8 windownr)
}
static inline int SetBlend_(struct av7110 *av7110, u8 windownr,
- enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
+ enum av7110_osd_palette_type colordepth, u16 index, u8 blending)
{
return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4,
windownr, colordepth, index, blending);
}
static inline int SetColor_(struct av7110 *av7110, u8 windownr,
- enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
+ enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo)
{
return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5,
windownr, colordepth, index, colorhi, colorlo);
@@ -726,8 +715,7 @@ static int FlushText(struct av7110 *av7110)
if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
break;
if (err) {
- printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
- __func__);
+ pr_err("%s(): timeout waiting for BUFF1_BASE == 0\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
@@ -753,8 +741,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
break;
if (ret) {
- printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
- __func__);
+ pr_err("%s(): timeout waiting for BUFF1_BASE == 0\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
@@ -767,8 +754,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
break;
if (ret) {
- printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
- __func__);
+ pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__);
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
@@ -782,8 +768,8 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
mutex_unlock(&av7110->dcomlock);
- if (ret && ret!=-ERESTARTSYS)
- printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
+ if (ret && ret != -ERESTARTSYS)
+ pr_err("%s(): error %d\n", __func__, ret);
return ret;
}
@@ -829,10 +815,10 @@ static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
windownr, disptype, width, height);
}
-
static enum av7110_osd_palette_type bpp2pal[8] = {
Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
};
+
static osd_raw_window_t bpp2bit[8] = {
OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
};
@@ -840,10 +826,9 @@ static osd_raw_window_t bpp2bit[8] = {
static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
{
int ret = wait_event_timeout(av7110->bmpq,
- av7110->bmp_state != BMP_LOADING, 10*HZ);
+ av7110->bmp_state != BMP_LOADING, 10 * HZ);
if (ret == 0) {
- printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
- ret, av7110->bmp_state);
+ pr_warn("warning: timeout waiting in LoadBitmap: %d, %d\n", ret, av7110->bmp_state);
av7110->bmp_state = BMP_NONE;
return -ETIMEDOUT;
}
@@ -851,7 +836,7 @@ static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
}
static inline int LoadBitmap(struct av7110 *av7110,
- u16 dx, u16 dy, int inc, u8 __user * data)
+ u16 dx, u16 dy, int inc, u8 __user *data)
{
u16 format;
int bpp;
@@ -866,13 +851,13 @@ static inline int LoadBitmap(struct av7110 *av7110,
av7110->bmp_state = BMP_LOADING;
if (format == OSD_BITMAP8) {
- bpp=8; delta = 1;
+ bpp = 8; delta = 1;
} else if (format == OSD_BITMAP4) {
- bpp=4; delta = 2;
+ bpp = 4; delta = 2;
} else if (format == OSD_BITMAP2) {
- bpp=2; delta = 4;
+ bpp = 2; delta = 4;
} else if (format == OSD_BITMAP1) {
- bpp=1; delta = 8;
+ bpp = 1; delta = 8;
} else {
av7110->bmp_state = BMP_NONE;
return -EINVAL;
@@ -900,7 +885,7 @@ static inline int LoadBitmap(struct av7110 *av7110,
}
}
av7110->bmplen += 1024;
- dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
+ dprintk(4, "av7110_fw_cmd(): LoadBmp size %d\n", av7110->bmplen);
ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
if (!ret)
ret = WaitUntilBmpLoaded(av7110);
@@ -921,7 +906,7 @@ static inline int ReleaseBitmap(struct av7110 *av7110)
if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
return -1;
if (av7110->bmp_state == BMP_LOADING)
- dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
+ dprintk(1, "%s called while BMP_LOADING\n", __func__);
av7110->bmp_state = BMP_NONE;
return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
}
@@ -932,8 +917,8 @@ static u32 RGB2YUV(u16 R, u16 G, u16 B)
u16 Y, Cr, Cb;
y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */
- u = 2048 + B * 8 -(y >> 5); /* Cr 0..4095 */
- v = 2048 + R * 8 -(y >> 5); /* Cb 0..4095 */
+ u = 2048 + B * 8 - (y >> 5); /* Cr 0..4095 */
+ v = 2048 + R * 8 - (y >> 5); /* Cb 0..4095 */
Y = y / 256;
Cb = u / 16;
@@ -949,7 +934,7 @@ static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 ble
u16 ch, cl;
u32 yuv;
- yuv = blend ? RGB2YUV(r,g,b) : 0;
+ yuv = blend ? RGB2YUV(r, g, b) : 0;
cl = (yuv & 0xffff);
ch = ((yuv >> 16) & 0xffff);
ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
@@ -960,7 +945,7 @@ static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 ble
return ret;
}
-static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
+static int OSDSetPalette(struct av7110 *av7110, u32 __user *colors, u8 first, u8 last)
{
int i;
int length = last - first + 1;
@@ -986,11 +971,11 @@ static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u
}
static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
- int x1, int y1, int inc, u8 __user * data)
+ int x1, int y1, int inc, u8 __user *data)
{
uint w, h, bpp, bpl, size, lpb, bnum, brest;
int i;
- int rc,release_rc;
+ int rc, release_rc;
w = x1 - x0 + 1;
h = y1 - y0 + 1;
@@ -1036,7 +1021,7 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
if (!rc)
rc = release_rc;
if (rc)
- dprintk(1,"returns %d\n",rc);
+ dprintk(1, "returns %d\n", rc);
return rc;
}
@@ -1054,7 +1039,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
case OSD_Open:
av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
ret = CreateOSDWindow(av7110, av7110->osdwin,
- bpp2bit[av7110->osdbpp[av7110->osdwin]],
+ bpp2bit[av7110->osdbpp[av7110->osdwin]],
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
if (ret)
break;
@@ -1081,21 +1066,22 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
break;
case OSD_SetPalette:
- if (FW_VERSION(av7110->arm_app) >= 0x2618)
+ if (FW_VERSION(av7110->arm_app) >= 0x2618) {
ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
- else {
- int i, len = dc->x0-dc->color+1;
+ } else {
+ int i, len = dc->x0 - dc->color + 1;
u8 __user *colors = (u8 __user *)dc->data;
u8 r, g = 0, b = 0, blend = 0;
+
ret = 0;
- for (i = 0; i<len; i++) {
+ for (i = 0; i < len; i++) {
if (get_user(r, colors + i * 4) ||
get_user(g, colors + i * 4 + 1) ||
get_user(b, colors + i * 4 + 2) ||
get_user(blend, colors + i * 4 + 3)) {
ret = -EFAULT;
break;
- }
+ }
ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
if (ret)
break;
@@ -1104,7 +1090,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
break;
case OSD_SetPixel:
ret = DrawLine(av7110, av7110->osdwin,
- dc->x0, dc->y0, 0, 0, dc->color);
+ dc->x0, dc->y0, 0, 0, dc->color);
break;
case OSD_SetRow:
dc->y1 = dc->y0;
@@ -1114,15 +1100,15 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
break;
case OSD_FillRow:
ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
- dc->x1-dc->x0+1, dc->y1, dc->color);
+ dc->x1 - dc->x0 + 1, dc->y1, dc->color);
break;
case OSD_FillBlock:
ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
- dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
+ dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
break;
case OSD_Line:
ret = DrawLine(av7110, av7110->osdwin,
- dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
+ dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
break;
case OSD_Text:
{
@@ -1136,7 +1122,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
if (dc->x1 > 3)
dc->x1 = 3;
ret = SetFont(av7110, av7110->osdwin, dc->x1,
- (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
+ (u16)(dc->color & 0xffff), (u16)(dc->color >> 16));
if (!ret)
ret = FlushText(av7110);
if (!ret)
@@ -1144,9 +1130,9 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
break;
}
case OSD_SetWindow:
- if (dc->x0 < 1 || dc->x0 > 7)
+ if (dc->x0 < 1 || dc->x0 > 7) {
ret = -EINVAL;
- else {
+ } else {
av7110->osdwin = dc->x0;
ret = 0;
}
@@ -1166,7 +1152,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
else
av7110->osdbpp[av7110->osdwin] = 0;
ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
- dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+ dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
if (ret)
break;
if (!dc->data) {
@@ -1181,10 +1167,10 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
}
mutex_unlock(&av7110->osd_mutex);
- if (ret==-ERESTARTSYS)
- dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
+ if (ret == -ERESTARTSYS)
+ dprintk(1, "%s(%d) returns with -ERESTARTSYS\n", __func__, dc->cmd);
else if (ret)
- dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
+ dprintk(1, "%s(%d) returns with %d\n", __func__, dc->cmd, ret);
return ret;
}
diff --git a/drivers/staging/media/av7110/av7110_hw.h b/drivers/staging/media/av7110/av7110_hw.h
index 6380d8950c69..d4579f411c56 100644
--- a/drivers/staging/media/av7110/av7110_hw.h
+++ b/drivers/staging/media/av7110/av7110_hw.h
@@ -11,19 +11,17 @@
#define DEBISWAP 0x002e0000
#define ARM_WAIT_FREE (HZ)
-#define ARM_WAIT_SHAKE (HZ/5)
+#define ARM_WAIT_SHAKE (HZ / 5)
#define ARM_WAIT_OSD (HZ)
-
-enum av7110_bootstate
-{
+enum av7110_bootstate {
BOOTSTATE_BUFFER_EMPTY = 0,
BOOTSTATE_BUFFER_FULL = 1,
BOOTSTATE_AV7110_BOOT_COMPLETE = 2
};
-enum av7110_type_rec_play_format
-{ RP_None,
+enum av7110_type_rec_play_format {
+ RP_None,
AudioPES,
AudioMp2,
AudioPCM,
@@ -31,8 +29,7 @@ enum av7110_type_rec_play_format
AV_PES
};
-enum av7110_osd_palette_type
-{
+enum av7110_osd_palette_type {
NoPalet = 0, /* No palette */
Pal1Bit = 2, /* 2 colors for 1 Bit Palette */
Pal2Bit = 4, /* 4 colors for 2 bit palette */
@@ -51,8 +48,7 @@ enum av7110_osd_palette_type
#define FB_ON SAA7146_GPIO_OUTHI /* FastBlank on (RGB-Mode) */
#define FB_LOOP SAA7146_GPIO_INPUT /* FastBlank loop-through (PC graphics ???) */
-enum av7110_video_output_mode
-{
+enum av7110_video_output_mode {
NO_OUT = 0, /* disable analog output */
CVBS_RGB_OUT = 1,
CVBS_YC_OUT = 2,
@@ -90,7 +86,6 @@ enum av7110_video_output_mode
#define PBUFSIZE_16K 0x0700
#define PBUFSIZE_32K 0x0800
-
/* firmware command codes */
enum av7110_osd_command {
WCreate,
@@ -255,7 +250,8 @@ enum av7110_command_type {
#define DATA_TS_PLAY 0x13
/* ancient CI command codes, only two are actually still used
- * by the link level CI firmware */
+ * by the link level CI firmware
+ */
#define CI_CMD_ERROR 0x00
#define CI_CMD_ACK 0x01
#define CI_CMD_SYSTEM_READY 0x02
@@ -289,10 +285,10 @@ enum av7110_command_type {
#define CI_MSG_CA_PMT 0xe0
#define CI_MSG_ERROR 0xf0
-
/* base address of the dual ported RAM which serves as communication
* area between PCI bus and av7110,
- * as seen by the DEBI bus of the saa7146 */
+ * as seen by the DEBI bus of the saa7146
+ */
#define DPRAM_BASE 0x4000
/* boot protocol area */
@@ -317,19 +313,18 @@ enum av7110_command_type {
#define DATA_BUFF0_BASE (DPRAM_BASE + 0x200)
#define DATA_BUFF0_SIZE 0x0800
-#define DATA_BUFF1_BASE (DATA_BUFF0_BASE+DATA_BUFF0_SIZE)
+#define DATA_BUFF1_BASE (DATA_BUFF0_BASE + DATA_BUFF0_SIZE)
#define DATA_BUFF1_SIZE 0x0800
-#define DATA_BUFF2_BASE (DATA_BUFF1_BASE+DATA_BUFF1_SIZE)
+#define DATA_BUFF2_BASE (DATA_BUFF1_BASE + DATA_BUFF1_SIZE)
#define DATA_BUFF2_SIZE 0x0800
-#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE)
+#define DATA_BUFF3_BASE (DATA_BUFF2_BASE + DATA_BUFF2_SIZE)
#define DATA_BUFF3_SIZE 0x0400
#define Reserved (DPRAM_BASE + 0x1E00)
#define Reserved_SIZE 0x1C0
-
/* firmware status area */
#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
#define STATUS_LOOPS (STATUS_BASE + 0x08)
@@ -362,26 +357,22 @@ enum av7110_command_type {
#define DEBI_DONE_LINE 1
#define ARM_IRQ_LINE 0
-
-
-extern int av7110_bootarm(struct av7110 *av7110);
-extern int av7110_firmversion(struct av7110 *av7110);
+int av7110_bootarm(struct av7110 *av7110);
+int av7110_firmversion(struct av7110 *av7110);
#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000)
#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF)
-extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
-extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
-extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
- int request_buf_len, u16 *reply_buf, int reply_buf_len);
-
+int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
+int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
+int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
+ int request_buf_len, u16 *reply_buf, int reply_buf_len);
/* DEBI (saa7146 data extension bus interface) access */
-extern int av7110_debiwrite(struct av7110 *av7110, u32 config,
- int addr, u32 val, unsigned int count);
-extern u32 av7110_debiread(struct av7110 *av7110, u32 config,
- int addr, unsigned int count);
-
+int av7110_debiwrite(struct av7110 *av7110, u32 config,
+ int addr, u32 val, unsigned int count);
+u32 av7110_debiread(struct av7110 *av7110, u32 config,
+ int addr, unsigned int count);
/* DEBI during interrupt */
/* single word writes */
@@ -402,9 +393,9 @@ static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, u
{
u32 res;
- res=av7110_debiread(av7110, config, addr, count);
- if (count<=4)
- memcpy(av7110->debi_virt, (char *) &res, count);
+ res = av7110_debiread(av7110, config, addr, count);
+ if (count <= 4)
+ memcpy(av7110->debi_virt, (char *)&res, count);
return res;
}
@@ -424,7 +415,7 @@ static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, un
u32 res;
spin_lock_irqsave(&av7110->debilock, flags);
- res=av7110_debiread(av7110, config, addr, count);
+ res = av7110_debiread(av7110, config, addr, count);
spin_unlock_irqrestore(&av7110->debilock, flags);
return res;
}
@@ -467,14 +458,14 @@ static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
{
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
- (com>>16), (com&0xffff),
- (arg>>16), (arg&0xffff));
+ (com >> 16), (com & 0xffff),
+ (arg >> 16), (arg & 0xffff));
}
static inline int audcom(struct av7110 *av7110, u32 com)
{
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
- (com>>16), (com&0xffff));
+ (com >> 16), (com & 0xffff));
}
static inline int Set22K(struct av7110 *av7110, int state)
@@ -482,15 +473,11 @@ static inline int Set22K(struct av7110 *av7110, int state)
return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
}
-
-extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
-
+int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst);
#ifdef CONFIG_DVB_AV7110_OSD
-extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
-extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
+int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
+int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
#endif /* CONFIG_DVB_AV7110_OSD */
-
-
#endif /* _AV7110_HW_H_ */
diff --git a/drivers/staging/media/av7110/av7110_ipack.c b/drivers/staging/media/av7110/av7110_ipack.c
index 30330ed01ce8..4be6e225f08e 100644
--- a/drivers/staging/media/av7110/av7110_ipack.c
+++ b/drivers/staging/media/av7110/av7110_ipack.c
@@ -4,7 +4,6 @@
#include <linux/string.h> /* for memcpy() */
#include <linux/vmalloc.h>
-
void av7110_ipack_reset(struct ipack *p)
{
p->found = 0;
@@ -20,14 +19,12 @@ void av7110_ipack_reset(struct ipack *p)
p->count = 0;
}
-
int av7110_ipack_init(struct ipack *p, int size,
void (*func)(u8 *buf, int size, void *priv))
{
- if (!(p->buf = vmalloc(size))) {
- printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
+ p->buf = vmalloc(size);
+ if (!p->buf)
return -ENOMEM;
- }
p->size = size;
p->func = func;
p->repack_subids = 0;
@@ -35,13 +32,11 @@ int av7110_ipack_init(struct ipack *p, int size,
return 0;
}
-
void av7110_ipack_free(struct ipack *p)
{
vfree(p->buf);
}
-
static void send_ipack(struct ipack *p)
{
int off;
@@ -63,7 +58,7 @@ static void send_ipack(struct ipack *p)
streamid = p->buf[off];
if ((streamid & 0xf8) == 0x80) {
ai.off = 0;
- ac3_off = ((p->buf[off + 2] << 8)|
+ ac3_off = ((p->buf[off + 2] << 8) |
p->buf[off + 3]);
if (ac3_off < p->count)
f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
@@ -84,8 +79,8 @@ static void send_ipack(struct ipack *p)
p->buf[7] = 0x00;
p->buf[8] = 0x00;
p->count = 9;
- if (p->repack_subids && p->cid == PRIVATE_STREAM1
- && (streamid & 0xf8) == 0x80) {
+ if (p->repack_subids && p->cid == PRIVATE_STREAM1 &&
+ (streamid & 0xf8) == 0x80) {
p->count += 4;
p->buf[9] = streamid;
p->buf[10] = (ac3_off >> 8) & 0xff;
@@ -108,7 +103,6 @@ static void send_ipack(struct ipack *p)
}
}
-
void av7110_ipack_flush(struct ipack *p)
{
if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
@@ -119,7 +113,6 @@ void av7110_ipack_flush(struct ipack *p)
av7110_ipack_reset(p);
}
-
static void write_ipack(struct ipack *p, const u8 *data, int count)
{
u8 headr[3] = { 0x00, 0x00, 0x01 };
@@ -129,12 +122,13 @@ static void write_ipack(struct ipack *p, const u8 *data, int count)
p->count = 6;
}
- if (p->count + count < p->size){
- memcpy(p->buf+p->count, data, count);
+ if (p->count + count < p->size) {
+ memcpy(p->buf + p->count, data, count);
p->count += count;
} else {
int rest = p->size - p->count;
- memcpy(p->buf+p->count, data, rest);
+
+ memcpy(p->buf + p->count, data, rest);
p->count += rest;
send_ipack(p);
if (count - rest > 0)
@@ -142,16 +136,15 @@ static void write_ipack(struct ipack *p, const u8 *data, int count)
}
}
-
-int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
+int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p)
{
int l;
int c = 0;
while (c < count && (p->mpeg == 0 ||
(p->mpeg == 1 && p->found < 7) ||
- (p->mpeg == 2 && p->found < 9))
- && (p->found < 5 || !p->done)) {
+ (p->mpeg == 2 && p->found < 9)) &&
+ (p->found < 5 || !p->done)) {
switch (p->found) {
case 0:
case 1:
@@ -176,10 +169,10 @@ int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
case PROG_STREAM_MAP:
case PRIVATE_STREAM2:
case PROG_STREAM_DIR:
- case ECM_STREAM :
- case EMM_STREAM :
- case PADDING_STREAM :
- case DSM_CC_STREAM :
+ case ECM_STREAM:
+ case EMM_STREAM:
+ case PADDING_STREAM:
+ case DSM_CC_STREAM:
case ISO13522_STREAM:
p->done = 1;
fallthrough;
@@ -197,7 +190,7 @@ int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
break;
case 4:
- if (count-c > 1) {
+ if (count - c > 1) {
p->plen[0] = buf[c];
c++;
p->plen[1] = buf[c];
@@ -221,9 +214,9 @@ int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
p->flag1 = buf[c];
c++;
p->found++;
- if ((p->flag1 & 0xc0) == 0x80)
+ if ((p->flag1 & 0xc0) == 0x80) {
p->mpeg = 2;
- else {
+ } else {
p->hlength = 0;
p->which = 0;
p->mpeg = 1;
@@ -256,149 +249,146 @@ int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
if (!p->plength)
p->plength = MMAX_PLENGTH - 6;
- if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
- (p->mpeg == 1 && p->found >= 7))) {
- switch (p->cid) {
- case AUDIO_STREAM_S ... AUDIO_STREAM_E:
- case VIDEO_STREAM_S ... VIDEO_STREAM_E:
- case PRIVATE_STREAM1:
- if (p->mpeg == 2 && p->found == 9) {
- write_ipack(p, &p->flag1, 1);
- write_ipack(p, &p->flag2, 1);
- write_ipack(p, &p->hlength, 1);
- }
+ if (!(p->done || ((p->mpeg == 2 && p->found >= 9) ||
+ (p->mpeg == 1 && p->found >= 7))))
+ return count;
- if (p->mpeg == 1 && p->found == 7)
- write_ipack(p, &p->flag1, 1);
+ switch (p->cid) {
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+ case PRIVATE_STREAM1:
+ if (p->mpeg == 2 && p->found == 9) {
+ write_ipack(p, &p->flag1, 1);
+ write_ipack(p, &p->flag2, 1);
+ write_ipack(p, &p->hlength, 1);
+ }
- if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
- p->found < 14) {
- while (c < count && p->found < 14) {
- p->pts[p->found - 9] = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- }
- if (c == count)
- return count;
+ if (p->mpeg == 1 && p->found == 7)
+ write_ipack(p, &p->flag1, 1);
+
+ if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && p->found < 14) {
+ while (c < count && p->found < 14) {
+ p->pts[p->found - 9] = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
}
+ if (c == count)
+ return count;
+ }
- if (p->mpeg == 1 && p->which < 2000) {
+ if (p->mpeg == 1 && p->which < 2000) {
+ if (p->found == 7) {
+ p->check = p->flag1;
+ p->hlength = 1;
+ }
- if (p->found == 7) {
- p->check = p->flag1;
- p->hlength = 1;
- }
+ while (!p->which && c < count && p->check == 0xff) {
+ p->check = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ }
- while (!p->which && c < count &&
- p->check == 0xff){
- p->check = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->hlength++;
- }
+ if (c == count)
+ return count;
+ if ((p->check & 0xc0) == 0x40 && !p->which) {
+ p->check = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+
+ p->which = 1;
+ if (c == count)
+ return count;
+ p->check = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ p->which = 2;
if (c == count)
return count;
+ }
- if ((p->check & 0xc0) == 0x40 && !p->which) {
- p->check = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->hlength++;
+ if (p->which == 1) {
+ p->check = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->hlength++;
+ p->which = 2;
+ if (c == count)
+ return count;
+ }
- p->which = 1;
- if (c == count)
- return count;
- p->check = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->hlength++;
- p->which = 2;
- if (c == count)
- return count;
- }
+ if ((p->check & 0x30) && p->check != 0xff) {
+ p->flag2 = (p->check & 0xf0) << 2;
+ p->pts[0] = p->check;
+ p->which = 3;
+ }
- if (p->which == 1) {
- p->check = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->hlength++;
- p->which = 2;
+ if (c == count)
+ return count;
+ if (p->which > 2) {
+ if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
+ while (c < count && p->which < 7) {
+ p->pts[p->which - 2] = buf[c];
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->which++;
+ p->hlength++;
+ }
if (c == count)
return count;
- }
-
- if ((p->check & 0x30) && p->check != 0xff) {
- p->flag2 = (p->check & 0xf0) << 2;
- p->pts[0] = p->check;
- p->which = 3;
- }
-
- if (c == count)
- return count;
- if (p->which > 2){
- if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
- while (c < count && p->which < 7) {
+ } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
+ while (c < count && p->which < 12) {
+ if (p->which < 7)
p->pts[p->which - 2] = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->which++;
- p->hlength++;
- }
- if (c == count)
- return count;
- } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
- while (c < count && p->which < 12) {
- if (p->which < 7)
- p->pts[p->which - 2] = buf[c];
- write_ipack(p, buf + c, 1);
- c++;
- p->found++;
- p->which++;
- p->hlength++;
- }
- if (c == count)
- return count;
+ write_ipack(p, buf + c, 1);
+ c++;
+ p->found++;
+ p->which++;
+ p->hlength++;
}
- p->which = 2000;
+ if (c == count)
+ return count;
}
-
+ p->which = 2000;
}
-
- while (c < count && p->found < p->plength + 6) {
- l = count - c;
- if (l + p->found > p->plength + 6)
- l = p->plength + 6 - p->found;
- write_ipack(p, buf + c, l);
- p->found += l;
- c += l;
- }
- break;
}
-
- if (p->done) {
- if (p->found + count - c < p->plength + 6) {
- p->found += count - c;
- c = count;
- } else {
- c += p->plength + 6 - p->found;
- p->found = p->plength + 6;
- }
+ while (c < count && p->found < p->plength + 6) {
+ l = count - c;
+ if (l + p->found > p->plength + 6)
+ l = p->plength + 6 - p->found;
+ write_ipack(p, buf + c, l);
+ p->found += l;
+ c += l;
}
+ break;
+ }
- if (p->plength && p->found == p->plength + 6) {
- send_ipack(p);
- av7110_ipack_reset(p);
- if (c < count)
- av7110_ipack_instant_repack(buf + c, count - c, p);
+ if (p->done) {
+ if (p->found + count - c < p->plength + 6) {
+ p->found += count - c;
+ c = count;
+ } else {
+ c += p->plength + 6 - p->found;
+ p->found = p->plength + 6;
}
}
+
+ if (p->plength && p->found == p->plength + 6) {
+ send_ipack(p);
+ av7110_ipack_reset(p);
+ if (c < count)
+ av7110_ipack_instant_repack(buf + c, count - c, p);
+ }
+
return count;
}
diff --git a/drivers/staging/media/av7110/av7110_ipack.h b/drivers/staging/media/av7110/av7110_ipack.h
index 943ec899bb93..55296421d52f 100644
--- a/drivers/staging/media/av7110/av7110_ipack.h
+++ b/drivers/staging/media/av7110/av7110_ipack.h
@@ -2,12 +2,12 @@
#ifndef _AV7110_IPACK_H_
#define _AV7110_IPACK_H_
-extern int av7110_ipack_init(struct ipack *p, int size,
- void (*func)(u8 *buf, int size, void *priv));
+int av7110_ipack_init(struct ipack *p, int size,
+ void (*func)(u8 *buf, int size, void *priv));
-extern void av7110_ipack_reset(struct ipack *p);
-extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
-extern void av7110_ipack_free(struct ipack * p);
-extern void av7110_ipack_flush(struct ipack *p);
+void av7110_ipack_reset(struct ipack *p);
+int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p);
+void av7110_ipack_free(struct ipack *p);
+void av7110_ipack_flush(struct ipack *p);
#endif
diff --git a/drivers/staging/media/av7110/av7110_ir.c b/drivers/staging/media/av7110/av7110_ir.c
index a851ba328e4a..68b3979ba5f2 100644
--- a/drivers/staging/media/av7110/av7110_ir.c
+++ b/drivers/staging/media/av7110/av7110_ir.c
@@ -59,8 +59,7 @@ void av7110_ir_handler(struct av7110 *av7110, u32 ircom)
proto = RC_PROTO_RC5;
break;
default:
- dprintk(2, "unknown ir config %d\n",
- av7110->ir.ir_config);
+ dprintk(2, "unknown ir config %d\n", av7110->ir.ir_config);
return;
}
diff --git a/drivers/staging/media/av7110/av7110_v4l.c b/drivers/staging/media/av7110/av7110_v4l.c
index ed2c605808e8..04e659243f02 100644
--- a/drivers/staging/media/av7110/av7110_v4l.c
+++ b/drivers/staging/media/av7110/av7110_v4l.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module
+ * driver for the SAA7146 based AV110 cards
+ * - video4linux interface for DVB and Siemens DVB-C analog module
*
* Copyright (C) 1999-2002 Ralph Metzler
* & Marcus Metzler for convergence integrated media GmbH
@@ -26,7 +27,7 @@
int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
{
- u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
+ u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8, val & 0xff };
struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg };
switch (av7110->adac_type) {
@@ -41,8 +42,7 @@ int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
}
if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
- dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n",
- av7110->dvb_adapter.num, reg, val);
+ dprintk(1, "failed @ card %d, %u = %u\n", av7110->dvb_adapter.num, reg, val);
return -EIO;
}
return 0;
@@ -53,7 +53,7 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
u8 msg2[2];
struct i2c_msg msgs[2] = {
- { .flags = 0 , .len = 3, .buf = msg1 },
+ { .flags = 0, .len = 3, .buf = msg1 },
{ .flags = I2C_M_RD, .len = 2, .buf = msg2 }
};
@@ -71,8 +71,7 @@ static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
}
if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
- dprintk(1, "dvb-ttpci: failed @ card %d, %u\n",
- av7110->dvb_adapter.num, reg);
+ dprintk(1, "failed @ card %d, %u\n", av7110->dvb_adapter.num, reg);
return -EIO;
}
*val = (msg2[0] << 8) | msg2[1];
@@ -86,7 +85,7 @@ static struct v4l2_input inputs[4] = {
.type = V4L2_INPUT_TYPE_CAMERA,
.audioset = 1,
.tuner = 0, /* ignored */
- .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
.capabilities = V4L2_IN_CAP_STD,
}, {
@@ -95,7 +94,7 @@ static struct v4l2_input inputs[4] = {
.type = V4L2_INPUT_TYPE_TUNER,
.audioset = 1,
.tuner = 0,
- .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
.capabilities = V4L2_IN_CAP_STD,
}, {
@@ -104,7 +103,7 @@ static struct v4l2_input inputs[4] = {
.type = V4L2_INPUT_TYPE_CAMERA,
.audioset = 0,
.tuner = 0,
- .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
.capabilities = V4L2_IN_CAP_STD,
}, {
@@ -113,7 +112,7 @@ static struct v4l2_input inputs[4] = {
.type = V4L2_INPUT_TYPE_CAMERA,
.audioset = 0,
.tuner = 0,
- .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
+ .std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
.capabilities = V4L2_IN_CAP_STD,
}
@@ -127,19 +126,19 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
dprintk(4, "dev: %p\n", dev);
- if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
+ if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
return -1;
return 0;
}
-static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
+static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data[4])
{
struct av7110 *av7110 = dev->ext_priv;
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
dprintk(4, "dev: %p\n", dev);
- if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
+ if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1)
return -1;
return 0;
}
@@ -153,7 +152,8 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
dprintk(4, "freq: 0x%08x\n", freq);
/* magic number: 614. tuning with the frequency given by v4l2
- is always off by 614*62.5 = 38375 kHz...*/
+ * is always off by 614*62.5 = 38375 kHz...
+ */
div = freq + 614;
buf[0] = (div >> 8) & 0x7f;
@@ -175,7 +175,7 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{
- struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
u32 div;
u8 data[4];
@@ -201,8 +201,6 @@ static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
return tuner_write(dev, 0x63, data);
}
-
-
static struct saa7146_standard analog_standard[];
static struct saa7146_standard dvb_standard[];
static struct saa7146_standard standard[];
@@ -215,13 +213,13 @@ static const struct v4l2_audio msp3400_v4l2_audio = {
static int av7110_dvb_c_switch(struct saa7146_dev *dev)
{
- struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
u16 adswitch;
int source, sync;
dprintk(4, "%p\n", av7110);
- if (0 != av7110->current_input) {
+ if (av7110->current_input != 0) {
dprintk(1, "switching to analog TV:\n");
adswitch = 1;
source = SAA7146_HPS_SOURCE_PORT_B;
@@ -330,8 +328,10 @@ static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
/* bilingual */
t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
t->audmode = V4L2_TUNER_MODE_LANG1;
- } else /* mono */
+ } else {
+ /* mono */
t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ }
return 0;
}
@@ -341,6 +341,7 @@ static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *
struct saa7146_dev *dev = video_drvdata(file);
struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
u16 fm_matrix, src;
+
dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
if (!av7110->analog_tuner_flags || av7110->current_input != 1)
@@ -406,7 +407,7 @@ static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_fre
if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL;
- if (V4L2_TUNER_ANALOG_TV != f->type)
+ if (f->type != V4L2_TUNER_ANALOG_TV)
return -EINVAL;
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
@@ -530,7 +531,7 @@ static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *
}
static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
- struct v4l2_sliced_vbi_cap *cap)
+ struct v4l2_sliced_vbi_cap *cap)
{
struct saa7146_dev *dev = video_drvdata(file);
struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
@@ -546,7 +547,7 @@ static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
}
static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct saa7146_dev *dev = video_drvdata(file);
struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
@@ -554,7 +555,7 @@ static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
dprintk(2, "VIDIOC_G_FMT:\n");
if (FW_VERSION(av7110->arm_app) < 0x2623)
return -EINVAL;
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
if (av7110->wssMode) {
f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
@@ -585,7 +586,7 @@ static int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh,
}
static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct saa7146_dev *dev = video_drvdata(file);
struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
@@ -610,12 +611,12 @@ static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
{
struct saa7146_dev *dev = video_drvdata(file);
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
struct v4l2_sliced_vbi_data d;
int rc;
- dprintk(2, "%s\n", __func__);
- if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
+ dprintk(2, "\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof(d))
return -EINVAL;
if (copy_from_user(&d, data, count))
return -EFAULT;
@@ -691,7 +692,6 @@ static u8 saa7113_init_regs[] = {
0xff
};
-
static struct saa7146_ext_vv av7110_vv_data_st;
static struct saa7146_ext_vv av7110_vv_data_c;
@@ -709,13 +709,14 @@ int av7110_init_analog_module(struct av7110 *av7110)
pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n",
av7110->dvb_adapter.num);
av7110->adac_type = DVB_ADAC_MSP34x5;
- } else
+ } else {
return -ENODEV;
+ }
msleep(100); // the probing above resets the msp...
msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
- dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n",
+ dprintk(1, "@ card %d MSP34xx version 0x%04x 0x%04x\n",
av7110->dvb_adapter.num, version1, version2);
msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00);
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
@@ -726,18 +727,21 @@ int av7110_init_analog_module(struct av7110 *av7110)
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART
- if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) {
+ if (i2c_writereg(av7110, 0x48, 0x01, 0x00) != 1) {
pr_info("saa7113 not accessible\n");
} else {
u8 *i = saa7113_init_regs;
- if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
+ if ((av7110->dev->pci->subsystem_vendor == 0x110a) &&
+ (av7110->dev->pci->subsystem_device == 0x0000)) {
/* Fujitsu/Siemens DVB-Cable */
av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
- } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
+ } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) &&
+ (av7110->dev->pci->subsystem_device == 0x0002)) {
/* Hauppauge/TT DVB-C premium */
av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
- } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
+ } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) &&
+ (av7110->dev->pci->subsystem_device == 0x000A)) {
/* Hauppauge/TT DVB-C premium */
av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
}
@@ -795,13 +799,14 @@ int av7110_init_analog_module(struct av7110 *av7110)
int av7110_init_v4l(struct av7110 *av7110)
{
- struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_dev *dev = av7110->dev;
struct saa7146_ext_vv *vv_data;
int ret;
/* special case DVB-C: these cards have an analog tuner
- plus need some special handling, so we have separate
- saa7146_ext_vv data for these... */
+ * plus need some special handling, so we have separate
+ * saa7146_ext_vv data for these...
+ */
if (av7110->analog_tuner_flags)
vv_data = &av7110_vv_data_c;
else
@@ -853,7 +858,7 @@ int av7110_init_v4l(struct av7110 *av7110)
int av7110_exit_v4l(struct av7110 *av7110)
{
- struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_dev *dev = av7110->dev;
saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
@@ -863,10 +868,9 @@ int av7110_exit_v4l(struct av7110 *av7110)
return 0;
}
-
-
/* FIXME: these values are experimental values that look better than the
- values from the latest "official" driver -- at least for me... (MiHu) */
+ * values from the latest "official" driver -- at least for me... (MiHu)
+ */
static struct saa7146_standard standard[] = {
{
.name = "PAL", .id = V4L2_STD_PAL_BG,
@@ -909,25 +913,23 @@ static struct saa7146_standard dvb_standard[] = {
}
};
-static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
+static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
if (std->id & V4L2_STD_PAL) {
av7110->vidmode = AV7110_VIDEO_MODE_PAL;
av7110_set_vidmode(av7110, av7110->vidmode);
- }
- else if (std->id & V4L2_STD_NTSC) {
+ } else if (std->id & V4L2_STD_NTSC) {
av7110->vidmode = AV7110_VIDEO_MODE_NTSC;
av7110_set_vidmode(av7110, av7110->vidmode);
- }
- else
+ } else {
return -1;
+ }
return 0;
}
-
static struct saa7146_ext_vv av7110_vv_data_st = {
.inputs = 1,
.audios = 1,
diff --git a/drivers/staging/media/av7110/budget-patch.c b/drivers/staging/media/av7110/budget-patch.c
deleted file mode 100644
index d173c8ade6a7..000000000000
--- a/drivers/staging/media/av7110/budget-patch.c
+++ /dev/null
@@ -1,665 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * budget-patch.c: driver for Budget Patch,
- * hardware modification of DVB-S cards enabling full TS
- *
- * Written by Emard <[email protected]>
- *
- * Original idea by Roberto Deza <[email protected]>
- *
- * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
- * and Metzlerbros
- *
- * the project's page is at https://linuxtv.org
- */
-
-#include "av7110.h"
-#include "av7110_hw.h"
-#include "budget.h"
-#include "stv0299.h"
-#include "ves1x93.h"
-#include "tda8083.h"
-
-#include "bsru6.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-#define budget_patch budget
-
-static struct saa7146_extension budget_extension;
-
-MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
-//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
-
-static const struct pci_device_id pci_tbl[] = {
- MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
-// MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
- {
- .vendor = 0,
- }
-};
-
-/* those lines are for budget-patch to be tried
-** on a true budget card and observe the
-** behaviour of VSYNC generated by rps1.
-** this code was shamelessly copy/pasted from budget.c
-*/
-static void gpio_Set22K (struct budget *budget, int state)
-{
- struct saa7146_dev *dev=budget->dev;
- dprintk(2, "budget: %p\n", budget);
- saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
-}
-
-/* Diseqc functions only for TT Budget card */
-/* taken from the Skyvision DVB driver by
- Ralph Metzler <[email protected]> */
-
-static void DiseqcSendBit (struct budget *budget, int data)
-{
- struct saa7146_dev *dev=budget->dev;
- dprintk(2, "budget: %p\n", budget);
-
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
- udelay(data ? 500 : 1000);
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
- udelay(data ? 1000 : 500);
-}
-
-static void DiseqcSendByte (struct budget *budget, int data)
-{
- int i, par=1, d;
-
- dprintk(2, "budget: %p\n", budget);
-
- for (i=7; i>=0; i--) {
- d = (data>>i)&1;
- par ^= d;
- DiseqcSendBit(budget, d);
- }
-
- DiseqcSendBit(budget, par);
-}
-
-static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
-{
- struct saa7146_dev *dev=budget->dev;
- int i;
-
- dprintk(2, "budget: %p\n", budget);
-
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
- mdelay(16);
-
- for (i=0; i<len; i++)
- DiseqcSendByte(budget, msg[i]);
-
- mdelay(16);
-
- if (burst!=-1) {
- if (burst)
- DiseqcSendByte(budget, 0xff);
- else {
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
- mdelay(12);
- udelay(500);
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
- }
- msleep(20);
- }
-
- return 0;
-}
-
-/* shamelessly copy/pasted from budget.c */
-static int budget_set_tone(struct dvb_frontend *fe,
- enum fe_sec_tone_mode tone)
-{
- struct budget* budget = (struct budget*) fe->dvb->priv;
-
- switch (tone) {
- case SEC_TONE_ON:
- gpio_Set22K (budget, 1);
- break;
-
- case SEC_TONE_OFF:
- gpio_Set22K (budget, 0);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-{
- struct budget* budget = (struct budget*) fe->dvb->priv;
-
- SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
-
- return 0;
-}
-
-static int budget_diseqc_send_burst(struct dvb_frontend *fe,
- enum fe_sec_mini_cmd minicmd)
-{
- struct budget* budget = (struct budget*) fe->dvb->priv;
-
- SendDiSEqCMsg (budget, 0, NULL, minicmd);
-
- return 0;
-}
-
-static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
-{
- int i;
-
- dprintk(2, "budget: %p\n", budget);
-
- for (i = 2; i < length; i++)
- {
- ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
- msleep(5);
- }
- if (length)
- ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
- else
- ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
- msleep(5);
- ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
- msleep(5);
- return 0;
-}
-
-static void av7110_set22k(struct budget_patch *budget, int state)
-{
- u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
-
- dprintk(2, "budget: %p\n", budget);
- budget_av7110_send_fw_cmd(budget, buf, 2);
-}
-
-static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
-{
- int i;
- u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
- 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- dprintk(2, "budget: %p\n", budget);
-
- if (len>10)
- len=10;
-
- buf[1] = len+2;
- buf[2] = len;
-
- if (burst != -1)
- buf[3]=burst ? 0x01 : 0x00;
- else
- buf[3]=0xffff;
-
- for (i=0; i<len; i++)
- buf[i+4]=msg[i];
-
- budget_av7110_send_fw_cmd(budget, buf, 18);
- return 0;
-}
-
-static int budget_patch_set_tone(struct dvb_frontend *fe,
- enum fe_sec_tone_mode tone)
-{
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
- switch (tone) {
- case SEC_TONE_ON:
- av7110_set22k (budget, 1);
- break;
-
- case SEC_TONE_OFF:
- av7110_set22k (budget, 0);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-{
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
- av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
-
- return 0;
-}
-
-static int budget_patch_diseqc_send_burst(struct dvb_frontend *fe,
- enum fe_sec_mini_cmd minicmd)
-{
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
-
- av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
-
- return 0;
-}
-
-static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
- u8 pwr = 0;
- u8 buf[4];
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- u32 div = (p->frequency + 479500) / 125;
-
- if (p->frequency > 2000000)
- pwr = 3;
- else if (p->frequency > 1800000)
- pwr = 2;
- else if (p->frequency > 1600000)
- pwr = 1;
- else if (p->frequency > 1200000)
- pwr = 0;
- else if (p->frequency >= 1100000)
- pwr = 1;
- else pwr = 2;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = div & 0xff;
- buf[2] = ((div & 0x18000) >> 10) | 0x95;
- buf[3] = (pwr << 6) | 0x30;
-
- // NOTE: since we're using a prescaler of 2, we set the
- // divisor frequency to 62.5kHz and divide by 125 above
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct ves1x93_config alps_bsrv2_config = {
- .demod_address = 0x08,
- .xin = 90100000UL,
- .invert_pwm = 0,
-};
-
-static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
- u32 div;
- u8 data[4];
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
- div = p->frequency / 125;
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x8e;
- data[3] = 0x00;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct tda8083_config grundig_29504_451_config = {
- .demod_address = 0x68,
-};
-
-static void frontend_init(struct budget_patch* budget)
-{
- switch(budget->dev->pci->subsystem_device) {
- case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
- case 0x1013: // SATELCO Multimedia PCI
-
- // try the ALPS BSRV2 first of all
- budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
- if (budget->dvb_frontend) {
- budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
- budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
- budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
- budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
- break;
- }
-
- // try the ALPS BSRU6 now
- budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
- if (budget->dvb_frontend) {
- budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
- budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
-
- budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
- budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
- budget->dvb_frontend->ops.set_tone = budget_set_tone;
- break;
- }
-
- // Try the grundig 29504-451
- budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
- if (budget->dvb_frontend) {
- budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
- budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
- budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
- budget->dvb_frontend->ops.set_tone = budget_set_tone;
- break;
- }
- break;
- }
-
- if (budget->dvb_frontend == NULL) {
- printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
- budget->dev->pci->vendor,
- budget->dev->pci->device,
- budget->dev->pci->subsystem_vendor,
- budget->dev->pci->subsystem_device);
- } else {
- if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
- printk("budget-av: Frontend registration failed!\n");
- dvb_frontend_detach(budget->dvb_frontend);
- budget->dvb_frontend = NULL;
- }
- }
-}
-
-/* written by Emard */
-static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
-{
- struct budget_patch *budget;
- int err;
- int count = 0;
- int detected = 0;
-
-#define PATCH_RESET 0
-#define RPS_IRQ 0
-#define HPS_SETUP 0
-#if PATCH_RESET
- saa7146_write(dev, MC1, MASK_31);
- msleep(40);
-#endif
-#if HPS_SETUP
- // initialize registers. Better to have it like this
- // than leaving something unconfigured
- saa7146_write(dev, DD1_STREAM_B, 0);
- // port B VSYNC at rising edge
- saa7146_write(dev, DD1_INIT, 0x00000200); // have this in budget-core too!
- saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI
-
- // debi config
- // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
-
- // zero all HPS registers
- saa7146_write(dev, HPS_H_PRESCALE, 0); // r68
- saa7146_write(dev, HPS_H_SCALE, 0); // r6c
- saa7146_write(dev, BCS_CTRL, 0); // r70
- saa7146_write(dev, HPS_V_SCALE, 0); // r60
- saa7146_write(dev, HPS_V_GAIN, 0); // r64
- saa7146_write(dev, CHROMA_KEY_RANGE, 0); // r74
- saa7146_write(dev, CLIP_FORMAT_CTRL, 0); // r78
- // Set HPS prescaler for port B input
- saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
- saa7146_write(dev, MC2,
- 0 * (MASK_08 | MASK_24) | // BRS control
- 0 * (MASK_09 | MASK_25) | // a
- 0 * (MASK_10 | MASK_26) | // b
- 1 * (MASK_06 | MASK_22) | // HPS_CTRL1
- 1 * (MASK_05 | MASK_21) | // HPS_CTRL2
- 0 * (MASK_01 | MASK_15) // DEBI
- );
-#endif
- // Disable RPS1 and RPS0
- saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
- // RPS1 timeout disable
- saa7146_write(dev, RPS_TOV1, 0);
-
- // code for autodetection
- // will wait for VBI_B event (vertical blank at port B)
- // and will reset GPIO3 after VBI_B is detected.
- // (GPIO3 should be raised high by CPU to
- // test if GPIO3 will generate vertical blank signal
- // in budget patch GPIO3 is connected to VSYNC_B
- count = 0;
-#if 0
- WRITE_RPS1(CMD_UPLOAD |
- MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
-#endif
- WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
- WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
- // issue RPS1 interrupt to increment counter
- WRITE_RPS1(CMD_INTERRUPT);
- // at least a NOP is neede between two interrupts
- WRITE_RPS1(CMD_NOP);
- // interrupt again
- WRITE_RPS1(CMD_INTERRUPT);
-#endif
- WRITE_RPS1(CMD_STOP);
-
-#if RPS_IRQ
- // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
- // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
- // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called
- saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
- // set event counter 1 threshold to maximum allowed value (rEC p55)
- saa7146_write(dev, ECT1R, 0x3fff );
-#endif
- // Fix VSYNC level
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
- // Set RPS1 Address register to point to RPS code (r108 p42)
- saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
- // Enable RPS1, (rFC p33)
- saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
-
-
- mdelay(50);
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
- mdelay(150);
-
-
- if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
- detected = 1;
-
-#if RPS_IRQ
- printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
-#endif
- // Disable RPS1
- saa7146_write(dev, MC1, ( MASK_29 ));
-
- if(detected == 0)
- printk("budget-patch not detected or saa7146 in non-default state.\n"
- "try enabling resetting of 7146 with MASK_31 in MC1 register\n");
-
- else
- printk("BUDGET-PATCH DETECTED.\n");
-
-
-/* OLD (Original design by Roberto Deza):
-** This code will setup the SAA7146_RPS1 to generate a square
-** wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
-** TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
-** then, this GPIO3 output which is connected to the D1B_VSYNC
-** input, will trigger the acquisition of the alternate field
-** and so on.
-** Currently, the TT_budget / WinTV_Nova cards have two ICs
-** (74HCT4040, LVC74) for the generation of this VSYNC signal,
-** which seems that can be done perfectly without this :-)).
-*/
-
-/* New design (By Emard)
-** this rps1 code will copy internal HS event to GPIO3 pin.
-** GPIO3 is in budget-patch hardware connected to port B VSYNC
-
-** HS is an internal event of 7146, accessible with RPS
-** and temporarily raised high every n lines
-** (n in defined in the RPS_THRESH1 counter threshold)
-** I think HS is raised high on the beginning of the n-th line
-** and remains high until this n-th line that triggered
-** it is completely received. When the reception of n-th line
-** ends, HS is lowered.
-
-** To transmit data over DMA, 7146 needs changing state at
-** port B VSYNC pin. Any changing of port B VSYNC will
-** cause some DMA data transfer, with more or less packets loss.
-** It depends on the phase and frequency of VSYNC and
-** the way of 7146 is instructed to trigger on port B (defined
-** in DD1_INIT register, 3rd nibble from the right valid
-** numbers are 0-7, see datasheet)
-**
-** The correct triggering can minimize packet loss,
-** dvbtraffic should give this stable bandwidths:
-** 22k transponder = 33814 kbit/s
-** 27.5k transponder = 38045 kbit/s
-** by experiment it is found that the best results
-** (stable bandwidths and almost no packet loss)
-** are obtained using DD1_INIT triggering number 2
-** (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
-** and a VSYNC phase that occurs in the middle of DMA transfer
-** (about byte 188*512=96256 in the DMA window).
-**
-** Phase of HS is still not clear to me how to control,
-** It just happens to be so. It can be seen if one enables
-** RPS_IRQ and print Event Counter 1 in vpeirq(). Every
-** time RPS_INTERRUPT is called, the Event Counter 1 will
-** increment. That's how the 7146 is programmed to do event
-** counting in this budget-patch.c
-** I *think* HPS setting has something to do with the phase
-** of HS but I can't be 100% sure in that.
-
-** hardware debug note: a working budget card (including budget patch)
-** with vpeirq() interrupt setup in mode "0x90" (every 64K) will
-** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
-** and that means 3*25=75 Hz of interrupt frequency, as seen by
-** watch cat /proc/interrupts
-**
-** If this frequency is 3x lower (and data received in the DMA
-** buffer don't start with 0x47, but in the middle of packets,
-** whose lengths appear to be like 188 292 188 104 etc.
-** this means VSYNC line is not connected in the hardware.
-** (check soldering pcb and pins)
-** The same behaviour of missing VSYNC can be duplicated on budget
-** cards, by setting DD1_INIT trigger mode 7 in 3rd nibble.
-*/
-
- // Setup RPS1 "program" (p35)
- count = 0;
-
-
- // Wait Source Line Counter Threshold (p36)
- WRITE_RPS1(CMD_PAUSE | EVT_HS);
- // Set GPIO3=1 (p42)
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
- WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
-#if RPS_IRQ
- // issue RPS1 interrupt
- WRITE_RPS1(CMD_INTERRUPT);
-#endif
- // Wait reset Source Line Counter Threshold (p36)
- WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
- // Set GPIO3=0 (p42)
- WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
- WRITE_RPS1(GPIO3_MSK);
- WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
-#if RPS_IRQ
- // issue RPS1 interrupt
- WRITE_RPS1(CMD_INTERRUPT);
-#endif
- // Jump to begin of RPS program (p37)
- WRITE_RPS1(CMD_JUMP);
- WRITE_RPS1(dev->d_rps1.dma_handle);
-
- // Fix VSYNC level
- saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
- // Set RPS1 Address register to point to RPS code (r108 p42)
- saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-
- if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
- return -ENOMEM;
-
- dprintk(2, "budget: %p\n", budget);
-
- err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
- if (err) {
- kfree(budget);
- return err;
- }
-
- // Set Source Line Counter Threshold, using BRS (rCC p43)
- // It generates HS event every TS_HEIGHT lines
- // this is related to TS_WIDTH set in register
- // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
- // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
- //,then RPS_THRESH1
- // should be set to trigger every TS_HEIGHT (512) lines.
- //
- saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
-
- // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
- // Enable RPS1 (rFC p33)
- saa7146_write(dev, MC1, (MASK_13 | MASK_29));
-
-
- dev->ext_priv = budget;
-
- budget->dvb_adapter.priv = budget;
- frontend_init(budget);
-
- ttpci_budget_init_hooks(budget);
-
- return 0;
-}
-
-static int budget_patch_detach (struct saa7146_dev* dev)
-{
- struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
- int err;
-
- if (budget->dvb_frontend) {
- dvb_unregister_frontend(budget->dvb_frontend);
- dvb_frontend_detach(budget->dvb_frontend);
- }
- err = ttpci_budget_deinit (budget);
-
- kfree (budget);
-
- return err;
-}
-
-static int __init budget_patch_init(void)
-{
- return saa7146_register_extension(&budget_extension);
-}
-
-static void __exit budget_patch_exit(void)
-{
- saa7146_unregister_extension(&budget_extension);
-}
-
-static struct saa7146_extension budget_extension = {
- .name = "budget_patch dvb",
- .flags = 0,
-
- .module = THIS_MODULE,
- .pci_tbl = pci_tbl,
- .attach = budget_patch_attach,
- .detach = budget_patch_detach,
-
- .irq_mask = MASK_10,
- .irq_func = ttpci_budget_irq10_handler,
-};
-
-module_init(budget_patch_init);
-module_exit(budget_patch_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
-MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 based so-called Budget Patch cards");
diff --git a/drivers/staging/media/av7110/dvb_filter.c b/drivers/staging/media/av7110/dvb_filter.c
index 8c2eca5dcdc9..9eafbb82bf42 100644
--- a/drivers/staging/media/av7110/dvb_filter.c
+++ b/drivers/staging/media/av7110/dvb_filter.c
@@ -6,17 +6,19 @@
static u32 freq[4] = {480, 441, 320, 0};
-static unsigned int ac3_bitrates[32] =
- {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
- 0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-static u32 ac3_frames[3][32] =
- {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
- 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
- {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
- 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
- {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
- 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+static unsigned int ac3_bitrates[32] = {
+ 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u32 ac3_frames[3][32] = {
+ {64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024,
+ 1152, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, 557, 696, 835, 975, 1114,
+ 1253, 1393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, 768, 960, 1152, 1344,
+ 1536, 1728, 1920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+};
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
{
@@ -26,43 +28,40 @@ int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int p
u8 frame = 0;
int fr = 0;
- while ( !found && c < count){
- u8 *b = mbuf+c;
+ while (!found && c < count) {
+ u8 *b = mbuf + c;
- if ( b[0] == 0x0b && b[1] == 0x77 )
+ if (b[0] == 0x0b && b[1] == 0x77)
found = 1;
- else {
+ else
c++;
- }
}
- if (!found) return -1;
- if (pr)
- printk(KERN_DEBUG "Audiostream: AC3");
+ if (!found)
+ return -1;
ai->off = c;
- if (c+5 >= count) return -1;
+ if (c + 5 >= count)
+ return -1;
ai->layer = 0; // 0 for AC3
- headr = mbuf+c+2;
+ headr = mbuf + c + 2;
- frame = (headr[2]&0x3f);
- ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
+ frame = (headr[2] & 0x3f);
+ ai->bit_rate = ac3_bitrates[frame >> 1] * 1000;
- if (pr)
- printk(KERN_CONT " BRate: %d kb/s", (int) ai->bit_rate/1000);
-
- ai->frequency = (headr[2] & 0xc0 ) >> 6;
- fr = (headr[2] & 0xc0 ) >> 6;
- ai->frequency = freq[fr]*100;
- if (pr)
- printk(KERN_CONT " Freq: %d Hz\n", (int) ai->frequency);
+ ai->frequency = (headr[2] & 0xc0) >> 6;
+ fr = (headr[2] & 0xc0) >> 6;
+ ai->frequency = freq[fr] * 100;
ai->framesize = ac3_frames[fr][frame >> 1];
- if ((frame & 1) && (fr == 1)) ai->framesize++;
+ if ((frame & 1) && (fr == 1))
+ ai->framesize++;
ai->framesize = ai->framesize << 1;
+
if (pr)
- printk(KERN_DEBUG " Framesize %d\n", (int) ai->framesize);
+ pr_info("Audiostream: AC3, BRate: %d kb/s, Freq: %d Hz, Framesize %d\n",
+ (int)ai->bit_rate / 1000, (int)ai->frequency, (int)ai->framesize);
return 0;
}
@@ -70,46 +69,47 @@ int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int p
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
dvb_filter_pes2ts_cb_t *cb, void *priv)
{
- unsigned char *buf=p2ts->buf;
-
- buf[0]=0x47;
- buf[1]=(pid>>8);
- buf[2]=pid&0xff;
- p2ts->cc=0;
- p2ts->cb=cb;
- p2ts->priv=priv;
+ unsigned char *buf = p2ts->buf;
+
+ buf[0] = 0x47;
+ buf[1] = (pid >> 8);
+ buf[2] = pid & 0xff;
+ p2ts->cc = 0;
+ p2ts->cb = cb;
+ p2ts->priv = priv;
}
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
int len, int payload_start)
{
- unsigned char *buf=p2ts->buf;
- int ret=0, rest;
+ unsigned char *buf = p2ts->buf;
+ int ret = 0, rest;
//len=6+((pes[4]<<8)|pes[5]);
if (payload_start)
- buf[1]|=0x40;
+ buf[1] |= 0x40;
else
- buf[1]&=~0x40;
- while (len>=184) {
- buf[3]=0x10|((p2ts->cc++)&0x0f);
- memcpy(buf+4, pes, 184);
- if ((ret=p2ts->cb(p2ts->priv, buf)))
+ buf[1] &= ~0x40;
+ while (len >= 184) {
+ buf[3] = 0x10 | ((p2ts->cc++) & 0x0f);
+ memcpy(buf + 4, pes, 184);
+ ret = p2ts->cb(p2ts->priv, buf);
+ if (ret)
return ret;
- len-=184; pes+=184;
- buf[1]&=~0x40;
+ len -= 184; pes += 184;
+ buf[1] &= ~0x40;
}
if (!len)
return 0;
- buf[3]=0x30|((p2ts->cc++)&0x0f);
- rest=183-len;
+ buf[3] = 0x30 | ((p2ts->cc++) & 0x0f);
+ rest = 183 - len;
if (rest) {
- buf[5]=0x00;
- if (rest-1)
- memset(buf+6, 0xff, rest-1);
+ buf[5] = 0x00;
+ if (rest - 1)
+ memset(buf + 6, 0xff, rest - 1);
}
- buf[4]=rest;
- memcpy(buf+5+rest, pes, len);
+ buf[4] = rest;
+ memcpy(buf + 5 + rest, pes, len);
return p2ts->cb(p2ts->priv, buf);
}
diff --git a/drivers/staging/media/av7110/dvb_filter.h b/drivers/staging/media/av7110/dvb_filter.h
index 67a3c6333bca..38b483508e07 100644
--- a/drivers/staging/media/av7110/dvb_filter.h
+++ b/drivers/staging/media/av7110/dvb_filter.h
@@ -1,6 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
- * dvb_filter.h
- *
* Copyright (C) 2003 Convergence GmbH
*
* This program is free software; you can redistribute it and/or
@@ -21,7 +20,7 @@
#include <media/demux.h>
-typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
+typedef int (dvb_filter_pes2ts_cb_t)(void *, unsigned char *);
struct dvb_filter_pes2ts {
unsigned char buf[188];
@@ -36,7 +35,6 @@ void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
int len, int payload_start);
-
#define PROG_STREAM_MAP 0xBC
#define PRIVATE_STREAM1 0xBD
#define PADDING_STREAM 0xBE
@@ -78,7 +76,6 @@ int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
#define INIT_DISP_HORIZONTAL_SIZE 540
#define INIT_DISP_VERTICAL_SIZE 576
-
//flags2
#define PTS_DTS_FLAGS 0xC0
#define ESCR_FLAG 0x20
@@ -119,9 +116,8 @@ int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
#define PIECE_RATE 0x40
#define SEAM_SPLICE 0x20
-
#define MAX_PLENGTH 0xFFFF
-#define MMAX_PLENGTH (256*MAX_PLENGTH)
+#define MMAX_PLENGTH (256 * MAX_PLENGTH)
#ifndef IPACKS
#define IPACKS 2048
@@ -187,10 +183,11 @@ struct mpg_picture {
s8 matrix_change_flag;
u8 picture_header_parameter;
- /* bit 0 - 2: bwd f code
- bit 3 : fpb vector
- bit 4 - 6: fwd f code
- bit 7 : fpf vector */
+ /* bit 0 - 2: bwd f code
+ * bit 3 : fpb vector
+ * bit 4 - 6: fwd f code
+ * bit 7 : fpf vector
+ */
int mpeg1_flag;
int progressive_sequence;
@@ -230,7 +227,7 @@ struct dvb_audio_info {
u32 bit_rate;
u32 frequency;
u32 mode;
- u32 mode_extension ;
+ u32 mode_extension;
u32 emphasis;
u32 framesize;
u32 off;
@@ -238,5 +235,4 @@ struct dvb_audio_info {
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
-
#endif
diff --git a/drivers/staging/media/av7110/sp8870.c b/drivers/staging/media/av7110/sp8870.c
index abf5c72607b6..0c813860f5b2 100644
--- a/drivers/staging/media/av7110/sp8870.c
+++ b/drivers/staging/media/av7110/sp8870.c
@@ -1,17 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- Driver for Spase SP8870 demodulator
-
- Copyright (C) 1999 Juergen Peitz
-
+ * Driver for Spase SP8870 demodulator
+.*
+ * Copyright (C) 1999 Juergen Peitz
+ */
-*/
/*
* This driver needs external firmware. Please use the command
* "<kerneldir>/scripts/get_dvb_firmware alps_tdlb7" to
* download/extract it, and then copy it to /usr/lib/hotplug/firmware
* or /lib/firmware (depending on configuration of firmware hotplug).
*/
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
#include <linux/init.h>
@@ -25,12 +30,10 @@
#include <media/dvb_frontend.h>
#include "sp8870.h"
-
struct sp8870_state {
+ struct i2c_adapter *i2c;
- struct i2c_adapter* i2c;
-
- const struct sp8870_config* config;
+ const struct sp8870_config *config;
struct dvb_frontend frontend;
@@ -39,9 +42,10 @@ struct sp8870_state {
};
static int debug;
-#define dprintk(args...) \
+#define dprintk(fmt, arg...) \
do { \
- if (debug) printk(KERN_DEBUG "sp8870: " args); \
+ if (debug) \
+ pr_info("%s(): " fmt, __func__, ##arg); \
} while (0)
/* firmware size for sp8870 */
@@ -50,39 +54,48 @@ static int debug;
/* starting point for firmware in file 'Sc_main.mc' */
#define SP8870_FIRMWARE_OFFSET 0x0A
-static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
+static int sp8870_writereg(struct sp8870_state *state, u16 reg, u16 data)
{
- u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
- struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
+ u8 buf[] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 4
+ };
+
int err;
- if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ dprintk("writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", err, reg, data);
return -EREMOTEIO;
}
return 0;
}
-static int sp8870_readreg (struct sp8870_state* state, u16 reg)
+static int sp8870_readreg(struct sp8870_state *state, u16 reg)
{
int ret;
- u8 b0 [] = { reg >> 8 , reg & 0xff };
- u8 b1 [] = { 0, 0 };
- struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
- { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
+ u8 b0[] = { reg >> 8, reg & 0xff };
+ u8 b1[] = { 0, 0 };
+ struct i2c_msg msg[] = {
+ { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }
+ };
- ret = i2c_transfer (state->i2c, msg, 2);
+ ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
+ dprintk("readreg error (ret == %i)\n", ret);
return -1;
}
return (b1[0] << 8 | b1[1]);
}
-static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
+static int sp8870_firmware_upload(struct sp8870_state *state, const struct firmware *fw)
{
struct i2c_msg msg;
const char *fw_buf = fw->data;
@@ -91,7 +104,7 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm
int tx_len;
int err = 0;
- dprintk ("%s: ...\n", __func__);
+ dprintk("start firmware upload...\n");
if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
return -EINVAL;
@@ -107,8 +120,9 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm
// do firmware upload
fw_pos = SP8870_FIRMWARE_OFFSET;
- while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
- tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
+ while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) {
+ tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 :
+ SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
// write register 0xCF0A
tx_buf[0] = 0xCF;
tx_buf[1] = 0x0A;
@@ -117,19 +131,20 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm
msg.flags = 0;
msg.buf = tx_buf;
msg.len = tx_len + 2;
- if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- printk("%s: firmware upload failed!\n", __func__);
- printk ("%s: i2c error (err == %i)\n", __func__, err);
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ pr_err("%s(): firmware upload failed!\n", __func__);
+ pr_err("%s(): i2c error (err == %i)\n", __func__, err);
return err;
}
fw_pos += tx_len;
}
- dprintk ("%s: done!\n", __func__);
+ dprintk("firmware upload successful!\n");
return 0;
};
-static void sp8870_microcontroller_stop (struct sp8870_state* state)
+static void sp8870_microcontroller_stop(struct sp8870_state *state)
{
sp8870_writereg(state, 0x0F08, 0x000);
sp8870_writereg(state, 0x0F09, 0x000);
@@ -138,7 +153,7 @@ static void sp8870_microcontroller_stop (struct sp8870_state* state)
sp8870_writereg(state, 0x0F00, 0x000);
}
-static void sp8870_microcontroller_start (struct sp8870_state* state)
+static void sp8870_microcontroller_start(struct sp8870_state *state)
{
sp8870_writereg(state, 0x0F08, 0x000);
sp8870_writereg(state, 0x0F09, 0x000);
@@ -150,12 +165,12 @@ static void sp8870_microcontroller_start (struct sp8870_state* state)
sp8870_readreg(state, 0x0D01);
}
-static int sp8870_read_data_valid_signal(struct sp8870_state* state)
+static int sp8870_read_data_valid_signal(struct sp8870_state *state)
{
return (sp8870_readreg(state, 0x0D02) > 0);
}
-static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
+static int configure_reg0xc05(struct dtv_frontend_properties *p, u16 *reg0xc05)
{
int known_parameters = 1;
@@ -226,7 +241,7 @@ static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
return 0;
}
-static int sp8870_wake_up(struct sp8870_state* state)
+static int sp8870_wake_up(struct sp8870_state *state)
{
// enable TS output and interface pins
return sp8870_writereg(state, 0xC18, 0x00D);
@@ -235,11 +250,12 @@ static int sp8870_wake_up(struct sp8870_state* state)
static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
int err;
u16 reg0xc05;
- if ((err = configure_reg0xc05(p, &reg0xc05)))
+ err = configure_reg0xc05(p, &reg0xc05);
+ if (err)
return err;
// system controller stop
@@ -248,7 +264,8 @@ static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
// set tuner parameters
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe);
- if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
}
// sample rate correction bit [23..17]
@@ -290,32 +307,32 @@ static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
return 0;
}
-static int sp8870_init (struct dvb_frontend* fe)
+static int sp8870_init(struct dvb_frontend *fe)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
const struct firmware *fw = NULL;
sp8870_wake_up(state);
- if (state->initialised) return 0;
+ if (state->initialised)
+ return 0;
state->initialised = 1;
- dprintk ("%s\n", __func__);
-
+ dprintk("initialising frontend...\n");
/* request the firmware, this will block until someone uploads it */
- printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
+ pr_info("waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
- printk("sp8870: no firmware upload (timeout or file not found?)\n");
+ pr_err("no firmware upload (timeout or file not found?)\n");
return -EIO;
}
if (sp8870_firmware_upload(state, fw)) {
- printk("sp8870: writing firmware to device failed\n");
+ pr_err("writing firmware to device failed\n");
release_firmware(fw);
return -EIO;
}
release_firmware(fw);
- printk("sp8870: firmware upload complete\n");
+ pr_info("firmware upload complete\n");
/* enable TS output and interface pins */
sp8870_writereg(state, 0xc18, 0x00d);
@@ -342,17 +359,17 @@ static int sp8870_init (struct dvb_frontend* fe)
static int sp8870_read_status(struct dvb_frontend *fe,
enum fe_status *fe_status)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
int status;
int signal;
*fe_status = 0;
- status = sp8870_readreg (state, 0x0200);
+ status = sp8870_readreg(state, 0x0200);
if (status < 0)
return -EIO;
- signal = sp8870_readreg (state, 0x0303);
+ signal = sp8870_readreg(state, 0x0303);
if (signal < 0)
return -EIO;
@@ -366,9 +383,9 @@ static int sp8870_read_status(struct dvb_frontend *fe,
return 0;
}
-static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
+static int sp8870_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
int ret;
u32 tmp;
@@ -393,21 +410,21 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
return 0;
}
-static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
+static int sp8870_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
int ret;
u16 tmp;
*signal = 0;
- ret = sp8870_readreg (state, 0x306);
+ ret = sp8870_readreg(state, 0x306);
if (ret < 0)
return -EIO;
tmp = ret << 8;
- ret = sp8870_readreg (state, 0x303);
+ ret = sp8870_readreg(state, 0x303);
if (ret < 0)
return -EIO;
@@ -419,9 +436,9 @@ static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
return 0;
}
-static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
+static int sp8870_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ublocks)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
int ret;
*ublocks = 0;
@@ -451,24 +468,23 @@ static int switches;
static int sp8870_set_frontend(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
/*
- The firmware of the sp8870 sometimes locks up after setting frontend parameters.
- We try to detect this by checking the data valid signal.
- If it is not set after MAXCHECKS we try to recover the lockup by setting
- the frontend parameters again.
- */
+ * The firmware of the sp8870 sometimes locks up after setting frontend parameters.
+ * We try to detect this by checking the data valid signal.
+ * If it is not set after MAXCHECKS we try to recover the lockup by setting
+ * the frontend parameters again.
+ */
int err = 0;
int valid = 0;
int trials = 0;
int check_count = 0;
- dprintk("%s: frequency = %i\n", __func__, p->frequency);
+ dprintk("frequency = %i\n", p->frequency);
for (trials = 1; trials <= MAXTRIALS; trials++) {
-
err = sp8870_set_frontend_parameters(fe);
if (err)
return err;
@@ -477,8 +493,7 @@ static int sp8870_set_frontend(struct dvb_frontend *fe)
// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
valid = sp8870_read_data_valid_signal(state);
if (valid) {
- dprintk("%s: delay = %i usec\n",
- __func__, check_count * 10);
+ dprintk("delay = %i usec\n", check_count * 10);
break;
}
udelay(10);
@@ -488,34 +503,34 @@ static int sp8870_set_frontend(struct dvb_frontend *fe)
}
if (!valid) {
- printk("%s: firmware crash!!!!!!\n", __func__);
+ pr_err("%s(): firmware crash!!!!!!\n", __func__);
return -EIO;
}
if (debug) {
if (valid) {
if (trials > 1) {
- printk("%s: firmware lockup!!!\n", __func__);
- printk("%s: recovered after %i trial(s))\n", __func__, trials - 1);
+ pr_info("%s(): firmware lockup!!!\n", __func__);
+ pr_info("%s(): recovered after %i trial(s))\n", __func__, trials - 1);
lockups++;
}
}
switches++;
- printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
+ pr_info("%s(): switches = %i lockups = %i\n", __func__, switches, lockups);
}
return 0;
}
-static int sp8870_sleep(struct dvb_frontend* fe)
+static int sp8870_sleep(struct dvb_frontend *fe)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
// tristate TS output and disable interface pins
return sp8870_writereg(state, 0xC18, 0x000);
}
-static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+static int sp8870_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *fesettings)
{
fesettings->min_delay_ms = 350;
fesettings->step_size = 0;
@@ -523,33 +538,34 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend
return 0;
}
-static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+static int sp8870_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
- if (enable) {
+ if (enable)
return sp8870_writereg(state, 0x206, 0x001);
- } else {
+ else
return sp8870_writereg(state, 0x206, 0x000);
- }
}
-static void sp8870_release(struct dvb_frontend* fe)
+static void sp8870_release(struct dvb_frontend *fe)
{
- struct sp8870_state* state = fe->demodulator_priv;
+ struct sp8870_state *state = fe->demodulator_priv;
+
kfree(state);
}
static const struct dvb_frontend_ops sp8870_ops;
-struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
- struct i2c_adapter* i2c)
+struct dvb_frontend *sp8870_attach(const struct sp8870_config *config,
+ struct i2c_adapter *i2c)
{
- struct sp8870_state* state = NULL;
+ struct sp8870_state *state = NULL;
/* allocate memory for the internal state */
- state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
- if (state == NULL) goto error;
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state)
+ goto error;
/* setup the state */
state->config = config;
@@ -557,10 +573,11 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
state->initialised = 0;
/* check if the demod is there */
- if (sp8870_readreg(state, 0x0200) < 0) goto error;
+ if (sp8870_readreg(state, 0x0200) < 0)
+ goto error;
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
+ memcpy(&state->frontend.ops, &sp8870_ops, sizeof(sp8870_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
@@ -568,6 +585,7 @@ error:
kfree(state);
return NULL;
}
+EXPORT_SYMBOL_GPL(sp8870_attach);
static const struct dvb_frontend_ops sp8870_ops = {
.delsys = { SYS_DVBT },
@@ -605,5 +623,3 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
MODULE_AUTHOR("Juergen Peitz");
MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL_GPL(sp8870_attach);
diff --git a/drivers/staging/media/av7110/sp8870.h b/drivers/staging/media/av7110/sp8870.h
index 5eacf39f425e..3323d1dfa568 100644
--- a/drivers/staging/media/av7110/sp8870.h
+++ b/drivers/staging/media/av7110/sp8870.h
@@ -1,11 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
- Driver for Spase SP8870 demodulator
-
- Copyright (C) 1999 Juergen Peitz
-
-
-*/
+ * Driver for Spase SP8870 demodulator
+ *
+ * Copyright (C) 1999 Juergen Peitz
+ */
#ifndef SP8870_H
#define SP8870_H
@@ -13,23 +11,21 @@
#include <linux/dvb/frontend.h>
#include <linux/firmware.h>
-struct sp8870_config
-{
+struct sp8870_config {
/* the demodulator's i2c address */
u8 demod_address;
/* request firmware for device */
- int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+ int (*request_firmware)(struct dvb_frontend *fe, const struct firmware **fw, char *name);
};
#if IS_REACHABLE(CONFIG_DVB_SP8870)
-extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
- struct i2c_adapter* i2c);
+struct dvb_frontend *sp8870_attach(const struct sp8870_config *config, struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *sp8870_attach(const struct sp8870_config *config,
+ struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ pr_warn(KBUILD_MODNAME ": %s(): driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_SP8870
diff --git a/drivers/staging/media/av7110/video-clear-buffer.rst b/drivers/staging/media/av7110/video-clear-buffer.rst
deleted file mode 100644
index a7730559bbb2..000000000000
--- a/drivers/staging/media/av7110/video-clear-buffer.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_CLEAR_BUFFER:
-
-==================
-VIDEO_CLEAR_BUFFER
-==================
-
-Name
-----
-
-VIDEO_CLEAR_BUFFER
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_CLEAR_BUFFER
-
-``int ioctl(fd, VIDEO_CLEAR_BUFFER)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_CLEAR_BUFFER for this command.
-
-Description
------------
-
-This ioctl call clears all video buffers in the driver and in the
-decoder hardware.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-command.rst b/drivers/staging/media/av7110/video-command.rst
deleted file mode 100644
index cae9445eb3af..000000000000
--- a/drivers/staging/media/av7110/video-command.rst
+++ /dev/null
@@ -1,96 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_COMMAND:
-
-=============
-VIDEO_COMMAND
-=============
-
-Name
-----
-
-VIDEO_COMMAND
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_COMMAND
-
-``int ioctl(int fd, VIDEO_COMMAND, struct video_command *cmd)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_COMMAND for this command.
-
- - .. row 3
-
- - struct video_command \*cmd
-
- - Commands the decoder.
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the
-:ref:`VIDIOC_DECODER_CMD` ioctl.
-
-This ioctl commands the decoder. The ``video_command`` struct is a
-subset of the ``v4l2_decoder_cmd`` struct, so refer to the
-:ref:`VIDIOC_DECODER_CMD` documentation for
-more information.
-
-.. c:type:: video_command
-
-.. code-block:: c
-
- /* The structure must be zeroed before use by the application
- This ensures it can be extended safely in the future. */
- struct video_command {
- __u32 cmd;
- __u32 flags;
- union {
- struct {
- __u64 pts;
- } stop;
-
- struct {
- /* 0 or 1000 specifies normal speed,
- 1 specifies forward single stepping,
- -1 specifies backward single stepping,
- >1: playback at speed/1000 of the normal speed,
- <-1: reverse playback at (-speed/1000) of the normal speed. */
- __s32 speed;
- __u32 format;
- } play;
-
- struct {
- __u32 data[16];
- } raw;
- };
- };
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-continue.rst b/drivers/staging/media/av7110/video-continue.rst
deleted file mode 100644
index bc34bf3989e4..000000000000
--- a/drivers/staging/media/av7110/video-continue.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_CONTINUE:
-
-==============
-VIDEO_CONTINUE
-==============
-
-Name
-----
-
-VIDEO_CONTINUE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_CONTINUE
-
-``int ioctl(fd, VIDEO_CONTINUE)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_CONTINUE for this command.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call restarts decoding and playing processes of the video
-stream which was played before a call to VIDEO_FREEZE was made.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-fast-forward.rst b/drivers/staging/media/av7110/video-fast-forward.rst
deleted file mode 100644
index e71fa8d6965b..000000000000
--- a/drivers/staging/media/av7110/video-fast-forward.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_FAST_FORWARD:
-
-==================
-VIDEO_FAST_FORWARD
-==================
-
-Name
-----
-
-VIDEO_FAST_FORWARD
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_FAST_FORWARD
-
-``int ioctl(fd, VIDEO_FAST_FORWARD, int nFrames)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_FAST_FORWARD for this command.
-
- - .. row 3
-
- - int nFrames
-
- - The number of frames to skip.
-
-Description
------------
-
-This ioctl call asks the Video Device to skip decoding of N number of
-I-frames. This call can only be used if VIDEO_SOURCE_MEMORY is
-selected.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EPERM``
-
- - Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/drivers/staging/media/av7110/video-fclose.rst b/drivers/staging/media/av7110/video-fclose.rst
deleted file mode 100644
index 01d24d548439..000000000000
--- a/drivers/staging/media/av7110/video-fclose.rst
+++ /dev/null
@@ -1,51 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _video_fclose:
-
-=================
-dvb video close()
-=================
-
-Name
-----
-
-dvb video close()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int close(int fd)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
-Description
------------
-
-This system call closes a previously opened video device.
-
-Return Value
-------------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EBADF``
-
- - fd is not a valid open file descriptor.
diff --git a/drivers/staging/media/av7110/video-fopen.rst b/drivers/staging/media/av7110/video-fopen.rst
deleted file mode 100644
index 1371b083e4e8..000000000000
--- a/drivers/staging/media/av7110/video-fopen.rst
+++ /dev/null
@@ -1,111 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _video_fopen:
-
-================
-dvb video open()
-================
-
-Name
-----
-
-dvb video open()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: int open(const char *deviceName, int flags)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - const char \*deviceName
-
- - Name of specific video device.
-
- - .. row 2
-
- - int flags
-
- - A bit-wise OR of the following flags:
-
- - .. row 3
-
- -
- - O_RDONLY read-only access
-
- - .. row 4
-
- -
- - O_RDWR read/write access
-
- - .. row 5
-
- -
- - O_NONBLOCK open in non-blocking mode
-
- - .. row 6
-
- -
- - (blocking mode is the default)
-
-Description
------------
-
-This system call opens a named video device (e.g.
-/dev/dvb/adapter0/video0) for subsequent use.
-
-When an open() call has succeeded, the device will be ready for use. The
-significance of blocking or non-blocking mode is described in the
-documentation for functions where there is a difference. It does not
-affect the semantics of the open() call itself. A device opened in
-blocking mode can later be put into non-blocking mode (and vice versa)
-using the F_SETFL command of the fcntl system call. This is a standard
-system call, documented in the Linux manual page for fcntl. Only one
-user can open the Video Device in O_RDWR mode. All other attempts to
-open the device in this mode will fail, and an error-code will be
-returned. If the Video Device is opened in O_RDONLY mode, the only
-ioctl call that can be used is VIDEO_GET_STATUS. All other call will
-return an error code.
-
-Return Value
-------------
-
-.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``ENODEV``
-
- - Device driver not loaded/available.
-
- - .. row 2
-
- - ``EINTERNAL``
-
- - Internal error.
-
- - .. row 3
-
- - ``EBUSY``
-
- - Device or resource busy.
-
- - .. row 4
-
- - ``EINVAL``
-
- - Invalid argument.
diff --git a/drivers/staging/media/av7110/video-freeze.rst b/drivers/staging/media/av7110/video-freeze.rst
deleted file mode 100644
index 4321f257cb70..000000000000
--- a/drivers/staging/media/av7110/video-freeze.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_FREEZE:
-
-============
-VIDEO_FREEZE
-============
-
-Name
-----
-
-VIDEO_FREEZE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_FREEZE
-
-``int ioctl(fd, VIDEO_FREEZE)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_FREEZE for this command.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call suspends the live video stream being played. Decoding
-and playing are frozen. It is then possible to restart the decoding and
-playing process of the video stream using the VIDEO_CONTINUE command.
-If VIDEO_SOURCE_MEMORY is selected in the ioctl call
-VIDEO_SELECT_SOURCE, the Digital TV subsystem will not decode any more data
-until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-fwrite.rst b/drivers/staging/media/av7110/video-fwrite.rst
deleted file mode 100644
index a07fd7d7a40e..000000000000
--- a/drivers/staging/media/av7110/video-fwrite.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _video_fwrite:
-
-=================
-dvb video write()
-=================
-
-Name
-----
-
-dvb video write()
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:function:: size_t write(int fd, const void *buf, size_t count)
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - void \*buf
-
- - Pointer to the buffer containing the PES data.
-
- - .. row 3
-
- - size_t count
-
- - Size of buf.
-
-Description
------------
-
-This system call can only be used if VIDEO_SOURCE_MEMORY is selected
-in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
-PES format, unless the capability allows other formats. If O_NONBLOCK
-is not specified the function will block until buffer space is
-available. The amount of data to be transferred is implied by count.
-
-Return Value
-------------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EPERM``
-
- - Mode VIDEO_SOURCE_MEMORY not selected.
-
- - .. row 2
-
- - ``ENOMEM``
-
- - Attempted to write more data than the internal buffer can hold.
-
- - .. row 3
-
- - ``EBADF``
-
- - fd is not a valid open file descriptor.
diff --git a/drivers/staging/media/av7110/video-get-capabilities.rst b/drivers/staging/media/av7110/video-get-capabilities.rst
deleted file mode 100644
index 01e09f56656c..000000000000
--- a/drivers/staging/media/av7110/video-get-capabilities.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_CAPABILITIES:
-
-======================
-VIDEO_GET_CAPABILITIES
-======================
-
-Name
-----
-
-VIDEO_GET_CAPABILITIES
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_CAPABILITIES
-
-``int ioctl(fd, VIDEO_GET_CAPABILITIES, unsigned int *cap)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_CAPABILITIES for this command.
-
- - .. row 3
-
- - unsigned int \*cap
-
- - Pointer to a location where to store the capability information.
-
-Description
------------
-
-This ioctl call asks the video device about its decoding capabilities.
-On success it returns and integer which has bits set according to the
-defines in section ??.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-get-event.rst b/drivers/staging/media/av7110/video-get-event.rst
deleted file mode 100644
index 90382bc36cfe..000000000000
--- a/drivers/staging/media/av7110/video-get-event.rst
+++ /dev/null
@@ -1,105 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_EVENT:
-
-===============
-VIDEO_GET_EVENT
-===============
-
-Name
-----
-
-VIDEO_GET_EVENT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_EVENT
-
-``int ioctl(fd, VIDEO_GET_EVENT, struct video_event *ev)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_EVENT for this command.
-
- - .. row 3
-
- - struct video_event \*ev
-
- - Points to the location where the event, if any, is to be stored.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To get events from a V4L2 decoder
-use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead.
-
-This ioctl call returns an event of type video_event if available. If
-an event is not available, the behavior depends on whether the device is
-in blocking or non-blocking mode. In the latter case, the call fails
-immediately with errno set to ``EWOULDBLOCK``. In the former case, the call
-blocks until an event becomes available. The standard Linux poll()
-and/or select() system calls can be used with the device file descriptor
-to watch for new events. For select(), the file descriptor should be
-included in the exceptfds argument, and for poll(), POLLPRI should be
-specified as the wake-up condition. Read-only permissions are sufficient
-for this ioctl call.
-
-.. c:type:: video_event
-
-.. code-block:: c
-
- struct video_event {
- __s32 type;
- #define VIDEO_EVENT_SIZE_CHANGED 1
- #define VIDEO_EVENT_FRAME_RATE_CHANGED 2
- #define VIDEO_EVENT_DECODER_STOPPED 3
- #define VIDEO_EVENT_VSYNC 4
- long timestamp;
- union {
- video_size_t size;
- unsigned int frame_rate; /* in frames per 1000sec */
- unsigned char vsync_field; /* unknown/odd/even/progressive */
- } u;
- };
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EWOULDBLOCK``
-
- - There is no event pending, and the device is in non-blocking mode.
-
- - .. row 2
-
- - ``EOVERFLOW``
-
- - Overflow in event queue - one or more events were lost.
diff --git a/drivers/staging/media/av7110/video-get-frame-count.rst b/drivers/staging/media/av7110/video-get-frame-count.rst
deleted file mode 100644
index b48ac8c58a41..000000000000
--- a/drivers/staging/media/av7110/video-get-frame-count.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_FRAME_COUNT:
-
-=====================
-VIDEO_GET_FRAME_COUNT
-=====================
-
-Name
-----
-
-VIDEO_GET_FRAME_COUNT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_FRAME_COUNT
-
-``int ioctl(int fd, VIDEO_GET_FRAME_COUNT, __u64 *pts)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_FRAME_COUNT for this command.
-
- - .. row 3
-
- - __u64 \*pts
-
- - Returns the number of frames displayed since the decoder was
- started.
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_FRAME``
-control.
-
-This ioctl call asks the Video Device to return the number of displayed
-frames since the decoder was started.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-get-pts.rst b/drivers/staging/media/av7110/video-get-pts.rst
deleted file mode 100644
index fedaff41be0b..000000000000
--- a/drivers/staging/media/av7110/video-get-pts.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_PTS:
-
-=============
-VIDEO_GET_PTS
-=============
-
-Name
-----
-
-VIDEO_GET_PTS
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_PTS
-
-``int ioctl(int fd, VIDEO_GET_PTS, __u64 *pts)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_PTS for this command.
-
- - .. row 3
-
- - __u64 \*pts
-
- - Returns the 33-bit timestamp as defined in ITU T-REC-H.222.0 /
- ISO/IEC 13818-1.
-
- The PTS should belong to the currently played frame if possible,
- but may also be a value close to it like the PTS of the last
- decoded frame or the last PTS extracted by the PES parser.
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the ``V4L2_CID_MPEG_VIDEO_DEC_PTS``
-control.
-
-This ioctl call asks the Video Device to return the current PTS
-timestamp.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-get-size.rst b/drivers/staging/media/av7110/video-get-size.rst
deleted file mode 100644
index de34331c5bd1..000000000000
--- a/drivers/staging/media/av7110/video-get-size.rst
+++ /dev/null
@@ -1,69 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_SIZE:
-
-==============
-VIDEO_GET_SIZE
-==============
-
-Name
-----
-
-VIDEO_GET_SIZE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_SIZE
-
-``int ioctl(int fd, VIDEO_GET_SIZE, video_size_t *size)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_SIZE for this command.
-
- - .. row 3
-
- - video_size_t \*size
-
- - Returns the size and aspect ratio.
-
-Description
------------
-
-This ioctl returns the size and aspect ratio.
-
-.. c:type:: video_size_t
-
-.. code-block::c
-
- typedef struct {
- int w;
- int h;
- video_format_t aspect_ratio;
- } video_size_t;
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-get-status.rst b/drivers/staging/media/av7110/video-get-status.rst
deleted file mode 100644
index 9b86fbf411d4..000000000000
--- a/drivers/staging/media/av7110/video-get-status.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_GET_STATUS:
-
-================
-VIDEO_GET_STATUS
-================
-
-Name
-----
-
-VIDEO_GET_STATUS
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_GET_STATUS
-
-``int ioctl(fd, VIDEO_GET_STATUS, struct video_status *status)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_GET_STATUS for this command.
-
- - .. row 3
-
- - struct video_status \*status
-
- - Returns the current status of the Video Device.
-
-Description
------------
-
-This ioctl call asks the Video Device to return the current status of
-the device.
-
-.. c:type:: video_status
-
-.. code-block:: c
-
- struct video_status {
- int video_blank; /* blank video on freeze? */
- video_play_state_t play_state; /* current state of playback */
- video_stream_source_t stream_source; /* current source (demux/memory) */
- video_format_t video_format; /* current aspect ratio of stream*/
- video_displayformat_t display_format;/* selected cropping mode */
- };
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-play.rst b/drivers/staging/media/av7110/video-play.rst
deleted file mode 100644
index 35ac8b98fdbf..000000000000
--- a/drivers/staging/media/av7110/video-play.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_PLAY:
-
-==========
-VIDEO_PLAY
-==========
-
-Name
-----
-
-VIDEO_PLAY
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_PLAY
-
-``int ioctl(fd, VIDEO_PLAY)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_PLAY for this command.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call asks the Video Device to start playing a video stream
-from the selected source.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-select-source.rst b/drivers/staging/media/av7110/video-select-source.rst
deleted file mode 100644
index 929a20985d53..000000000000
--- a/drivers/staging/media/av7110/video-select-source.rst
+++ /dev/null
@@ -1,76 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SELECT_SOURCE:
-
-===================
-VIDEO_SELECT_SOURCE
-===================
-
-Name
-----
-
-VIDEO_SELECT_SOURCE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SELECT_SOURCE
-
-``int ioctl(fd, VIDEO_SELECT_SOURCE, video_stream_source_t source)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SELECT_SOURCE for this command.
-
- - .. row 3
-
- - video_stream_source_t source
-
- - Indicates which source shall be used for the Video stream.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. This ioctl was also supported by the
-V4L2 ivtv driver, but that has been replaced by the ivtv-specific
-``IVTV_IOC_PASSTHROUGH_MODE`` ioctl.
-
-This ioctl call informs the video device which source shall be used for
-the input data. The possible sources are demux or memory. If memory is
-selected, the data is fed to the video device through the write command.
-
-.. c:type:: video_stream_source_t
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
- VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
- comes from the user through the write
- system call */
- } video_stream_source_t;
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-set-blank.rst b/drivers/staging/media/av7110/video-set-blank.rst
deleted file mode 100644
index 70249a6ba125..000000000000
--- a/drivers/staging/media/av7110/video-set-blank.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SET_BLANK:
-
-===============
-VIDEO_SET_BLANK
-===============
-
-Name
-----
-
-VIDEO_SET_BLANK
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SET_BLANK
-
-``int ioctl(fd, VIDEO_SET_BLANK, boolean mode)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SET_BLANK for this command.
-
- - .. row 3
-
- - boolean mode
-
- - TRUE: Blank screen when stop.
-
- - .. row 4
-
- -
- - FALSE: Show last decoded frame.
-
-Description
------------
-
-This ioctl call asks the Video Device to blank out the picture.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-set-display-format.rst b/drivers/staging/media/av7110/video-set-display-format.rst
deleted file mode 100644
index 1de4f40ae732..000000000000
--- a/drivers/staging/media/av7110/video-set-display-format.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SET_DISPLAY_FORMAT:
-
-========================
-VIDEO_SET_DISPLAY_FORMAT
-========================
-
-Name
-----
-
-VIDEO_SET_DISPLAY_FORMAT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SET_DISPLAY_FORMAT
-
-``int ioctl(fd, VIDEO_SET_DISPLAY_FORMAT)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SET_DISPLAY_FORMAT for this command.
-
- - .. row 3
-
- - video_display_format_t format
-
- - Selects the video format to be used.
-
-Description
------------
-
-This ioctl call asks the Video Device to select the video format to be
-applied by the MPEG chip on the video.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-set-format.rst b/drivers/staging/media/av7110/video-set-format.rst
deleted file mode 100644
index bb64e37ae081..000000000000
--- a/drivers/staging/media/av7110/video-set-format.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SET_FORMAT:
-
-================
-VIDEO_SET_FORMAT
-================
-
-Name
-----
-
-VIDEO_SET_FORMAT
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SET_FORMAT
-
-``int ioctl(fd, VIDEO_SET_FORMAT, video_format_t format)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SET_FORMAT for this command.
-
- - .. row 3
-
- - video_format_t format
-
- - video format of TV as defined in section ??.
-
-Description
------------
-
-This ioctl sets the screen format (aspect ratio) of the connected output
-device (TV) so that the output of the decoder can be adjusted
-accordingly.
-
-.. c:type:: video_format_t
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_FORMAT_4_3, /* Select 4:3 format */
- VIDEO_FORMAT_16_9, /* Select 16:9 format. */
- VIDEO_FORMAT_221_1 /* 2.21:1 */
- } video_format_t;
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EINVAL``
-
- - format is not a valid video format.
diff --git a/drivers/staging/media/av7110/video-set-streamtype.rst b/drivers/staging/media/av7110/video-set-streamtype.rst
deleted file mode 100644
index 1f31c048bdbc..000000000000
--- a/drivers/staging/media/av7110/video-set-streamtype.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SET_STREAMTYPE:
-
-====================
-VIDEO_SET_STREAMTYPE
-====================
-
-Name
-----
-
-VIDEO_SET_STREAMTYPE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SET_STREAMTYPE
-
-``int ioctl(fd, VIDEO_SET_STREAMTYPE, int type)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SET_STREAMTYPE for this command.
-
- - .. row 3
-
- - int type
-
- - stream type
-
-Description
------------
-
-This ioctl tells the driver which kind of stream to expect being written
-to it. If this call is not used the default of video PES is used. Some
-drivers might not support this call and always expect PES.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-slowmotion.rst b/drivers/staging/media/av7110/video-slowmotion.rst
deleted file mode 100644
index 1478fcc30cb8..000000000000
--- a/drivers/staging/media/av7110/video-slowmotion.rst
+++ /dev/null
@@ -1,72 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_SLOWMOTION:
-
-================
-VIDEO_SLOWMOTION
-================
-
-Name
-----
-
-VIDEO_SLOWMOTION
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_SLOWMOTION
-
-``int ioctl(fd, VIDEO_SLOWMOTION, int nFrames)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_SLOWMOTION for this command.
-
- - .. row 3
-
- - int nFrames
-
- - The number of times to repeat each frame.
-
-Description
------------
-
-This ioctl call asks the video device to repeat decoding frames N number
-of times. This call can only be used if VIDEO_SOURCE_MEMORY is
-selected.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
-
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - ``EPERM``
-
- - Mode VIDEO_SOURCE_MEMORY not selected.
diff --git a/drivers/staging/media/av7110/video-stillpicture.rst b/drivers/staging/media/av7110/video-stillpicture.rst
deleted file mode 100644
index d25384222a20..000000000000
--- a/drivers/staging/media/av7110/video-stillpicture.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_STILLPICTURE:
-
-==================
-VIDEO_STILLPICTURE
-==================
-
-Name
-----
-
-VIDEO_STILLPICTURE
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_STILLPICTURE
-
-``int ioctl(fd, VIDEO_STILLPICTURE, struct video_still_picture *sp)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_STILLPICTURE for this command.
-
- - .. row 3
-
- - struct video_still_picture \*sp
-
- - Pointer to a location where an I-frame and size is stored.
-
-Description
------------
-
-This ioctl call asks the Video Device to display a still picture
-(I-frame). The input data shall contain an I-frame. If the pointer is
-NULL, then the current displayed still picture is blanked.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-stop.rst b/drivers/staging/media/av7110/video-stop.rst
deleted file mode 100644
index 96f61c5b48a2..000000000000
--- a/drivers/staging/media/av7110/video-stop.rst
+++ /dev/null
@@ -1,74 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_STOP:
-
-==========
-VIDEO_STOP
-==========
-
-Name
-----
-
-VIDEO_STOP
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_STOP
-
-``int ioctl(fd, VIDEO_STOP, boolean mode)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_STOP for this command.
-
- - .. row 3
-
- - Boolean mode
-
- - Indicates how the screen shall be handled.
-
- - .. row 4
-
- -
- - TRUE: Blank screen when stop.
-
- - .. row 5
-
- -
- - FALSE: Show last decoded frame.
-
-Description
------------
-
-This ioctl is for Digital TV devices only. To control a V4L2 decoder use the
-V4L2 :ref:`VIDIOC_DECODER_CMD` instead.
-
-This ioctl call asks the Video Device to stop playing the current
-stream. Depending on the input parameter, the screen can be blanked out
-or displaying the last decoded frame.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video-try-command.rst b/drivers/staging/media/av7110/video-try-command.rst
deleted file mode 100644
index 79bf3dfb8a32..000000000000
--- a/drivers/staging/media/av7110/video-try-command.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-.. c:namespace:: DTV.video
-
-.. _VIDEO_TRY_COMMAND:
-
-=================
-VIDEO_TRY_COMMAND
-=================
-
-Name
-----
-
-VIDEO_TRY_COMMAND
-
-.. attention:: This ioctl is deprecated.
-
-Synopsis
---------
-
-.. c:macro:: VIDEO_TRY_COMMAND
-
-``int ioctl(int fd, VIDEO_TRY_COMMAND, struct video_command *cmd)``
-
-Arguments
----------
-
-.. flat-table::
- :header-rows: 0
- :stub-columns: 0
-
- - .. row 1
-
- - int fd
-
- - File descriptor returned by a previous call to open().
-
- - .. row 2
-
- - int request
-
- - Equals VIDEO_TRY_COMMAND for this command.
-
- - .. row 3
-
- - struct video_command \*cmd
-
- - Try a decoder command.
-
-Description
------------
-
-This ioctl is obsolete. Do not use in new drivers. For V4L2 decoders
-this ioctl has been replaced by the
-:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` ioctl.
-
-This ioctl tries a decoder command. The ``video_command`` struct is a
-subset of the ``v4l2_decoder_cmd`` struct, so refer to the
-:ref:`VIDIOC_TRY_DECODER_CMD <VIDIOC_DECODER_CMD>` documentation
-for more information.
-
-Return Value
-------------
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/drivers/staging/media/av7110/video.rst b/drivers/staging/media/av7110/video.rst
deleted file mode 100644
index 808705b769a1..000000000000
--- a/drivers/staging/media/av7110/video.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _dvb_video:
-
-#######################
-Digital TV Video Device
-#######################
-
-The Digital TV video device controls the MPEG2 video decoder of the Digital
-TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data
-types and ioctl definitions can be accessed by including
-**linux/dvb/video.h** in your application.
-
-Note that the Digital TV video device only controls decoding of the MPEG video
-stream, not its presentation on the TV or computer screen. On PCs this
-is typically handled by an associated video4linux device, e.g.
-**/dev/video**, which allows scaling and defining output windows.
-
-Some Digital TV cards don't have their own MPEG decoder, which results in the
-omission of the audio and video device as well as the video4linux
-device.
-
-The ioctls that deal with SPUs (sub picture units) and navigation
-packets are only supported on some MPEG decoders made for DVD playback.
-
-These ioctls were also used by V4L2 to control MPEG decoders implemented
-in V4L2. The use of these ioctls for that purpose has been made obsolete
-and proper V4L2 ioctls or controls have been created to replace that
-functionality.
-
-
-.. toctree::
- :maxdepth: 1
-
- video_types
- video_function_calls
diff --git a/drivers/staging/media/av7110/video_function_calls.rst b/drivers/staging/media/av7110/video_function_calls.rst
deleted file mode 100644
index 20a897be5dca..000000000000
--- a/drivers/staging/media/av7110/video_function_calls.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _video_function_calls:
-
-********************
-Video Function Calls
-********************
-
-.. toctree::
- :maxdepth: 1
-
- video-fopen
- video-fclose
- video-fwrite
- video-stop
- video-play
- video-freeze
- video-continue
- video-select-source
- video-set-blank
- video-get-status
- video-get-frame-count
- video-get-pts
- video-get-event
- video-command
- video-try-command
- video-get-size
- video-set-display-format
- video-stillpicture
- video-fast-forward
- video-slowmotion
- video-get-capabilities
- video-clear-buffer
- video-set-streamtype
- video-set-format
diff --git a/drivers/staging/media/av7110/video_types.rst b/drivers/staging/media/av7110/video_types.rst
deleted file mode 100644
index c4557d328b7a..000000000000
--- a/drivers/staging/media/av7110/video_types.rst
+++ /dev/null
@@ -1,248 +0,0 @@
-.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
-
-.. _video_types:
-
-****************
-Video Data Types
-****************
-
-
-.. _video-format-t:
-
-video_format_t
-==============
-
-The ``video_format_t`` data type defined by
-
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_FORMAT_4_3, /* Select 4:3 format */
- VIDEO_FORMAT_16_9, /* Select 16:9 format. */
- VIDEO_FORMAT_221_1 /* 2.21:1 */
- } video_format_t;
-
-is used in the VIDEO_SET_FORMAT function (??) to tell the driver which
-aspect ratio the output hardware (e.g. TV) has. It is also used in the
-data structures video_status (??) returned by VIDEO_GET_STATUS (??)
-and video_event (??) returned by VIDEO_GET_EVENT (??) which report
-about the display format of the current video stream.
-
-
-.. _video-displayformat-t:
-
-video_displayformat_t
-=====================
-
-In case the display format of the video stream and of the display
-hardware differ the application has to specify how to handle the
-cropping of the picture. This can be done using the
-VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
-
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_PAN_SCAN, /* use pan and scan format */
- VIDEO_LETTER_BOX, /* use letterbox format */
- VIDEO_CENTER_CUT_OUT /* use center cut out format */
- } video_displayformat_t;
-
-as argument.
-
-
-.. _video-stream-source-t:
-
-video_stream_source_t
-=====================
-
-The video stream source is set through the VIDEO_SELECT_SOURCE call
-and can take the following values, depending on whether we are replaying
-from an internal (demuxer) or external (user write) source.
-
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
- VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
- comes from the user through the write
- system call */
- } video_stream_source_t;
-
-VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the
-frontend or the DVR device) as the source of the video stream. If
-VIDEO_SOURCE_MEMORY is selected the stream comes from the application
-through the **write()** system call.
-
-
-.. _video-play-state-t:
-
-video_play_state_t
-==================
-
-The following values can be returned by the VIDEO_GET_STATUS call
-representing the state of video playback.
-
-
-.. code-block:: c
-
- typedef enum {
- VIDEO_STOPPED, /* Video is stopped */
- VIDEO_PLAYING, /* Video is currently playing */
- VIDEO_FREEZED /* Video is freezed */
- } video_play_state_t;
-
-
-.. c:type:: video_command
-
-struct video_command
-====================
-
-The structure must be zeroed before use by the application This ensures
-it can be extended safely in the future.
-
-
-.. code-block:: c
-
- struct video_command {
- __u32 cmd;
- __u32 flags;
- union {
- struct {
- __u64 pts;
- } stop;
-
- struct {
- /* 0 or 1000 specifies normal speed,
- 1 specifies forward single stepping,
- -1 specifies backward single stepping,
- >>1: playback at speed/1000 of the normal speed,
- <-1: reverse playback at (-speed/1000) of the normal speed. */
- __s32 speed;
- __u32 format;
- } play;
-
- struct {
- __u32 data[16];
- } raw;
- };
- };
-
-
-.. _video-size-t:
-
-video_size_t
-============
-
-
-.. code-block:: c
-
- typedef struct {
- int w;
- int h;
- video_format_t aspect_ratio;
- } video_size_t;
-
-
-.. c:type:: video_event
-
-struct video_event
-==================
-
-The following is the structure of a video event as it is returned by the
-VIDEO_GET_EVENT call.
-
-
-.. code-block:: c
-
- struct video_event {
- __s32 type;
- #define VIDEO_EVENT_SIZE_CHANGED 1
- #define VIDEO_EVENT_FRAME_RATE_CHANGED 2
- #define VIDEO_EVENT_DECODER_STOPPED 3
- #define VIDEO_EVENT_VSYNC 4
- long timestamp;
- union {
- video_size_t size;
- unsigned int frame_rate; /* in frames per 1000sec */
- unsigned char vsync_field; /* unknown/odd/even/progressive */
- } u;
- };
-
-
-.. c:type:: video_status
-
-struct video_status
-===================
-
-The VIDEO_GET_STATUS call returns the following structure informing
-about various states of the playback operation.
-
-
-.. code-block:: c
-
- struct video_status {
- int video_blank; /* blank video on freeze? */
- video_play_state_t play_state; /* current state of playback */
- video_stream_source_t stream_source; /* current source (demux/memory) */
- video_format_t video_format; /* current aspect ratio of stream */
- video_displayformat_t display_format;/* selected cropping mode */
- };
-
-If video_blank is set video will be blanked out if the channel is
-changed or if playback is stopped. Otherwise, the last picture will be
-displayed. play_state indicates if the video is currently frozen,
-stopped, or being played back. The stream_source corresponds to the
-selected source for the video stream. It can come either from the
-demultiplexer or from memory. The video_format indicates the aspect
-ratio (one of 4:3 or 16:9) of the currently played video stream.
-Finally, display_format corresponds to the selected cropping mode in
-case the source video format is not the same as the format of the output
-device.
-
-
-.. c:type:: video_still_picture
-
-struct video_still_picture
-==========================
-
-An I-frame displayed via the VIDEO_STILLPICTURE call is passed on
-within the following structure.
-
-
-.. code-block:: c
-
- /* pointer to and size of a single iframe in memory */
- struct video_still_picture {
- char *iFrame; /* pointer to a single iframe in memory */
- int32_t size;
- };
-
-
-.. _video_caps:
-
-video capabilities
-==================
-
-A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the
-following bits set according to the hardwares capabilities.
-
-
-.. code-block:: c
-
- /* bit definitions for capabilities: */
- /* can the hardware decode MPEG1 and/or MPEG2? */
- #define VIDEO_CAP_MPEG1 1
- #define VIDEO_CAP_MPEG2 2
- /* can you send a system and/or program stream to video device?
- (you still have to open the video and the audio device but only
- send the stream to the video device) */
- #define VIDEO_CAP_SYS 4
- #define VIDEO_CAP_PROG 8
- /* can the driver also handle SPU, NAVI and CSS encoded data?
- (CSS API is not present yet) */
- #define VIDEO_CAP_SPU 16
- #define VIDEO_CAP_NAVI 32
- #define VIDEO_CAP_CSS 64
diff --git a/drivers/staging/media/max96712/max96712.c b/drivers/staging/media/max96712/max96712.c
index ea67bcf69c9d..6bdbccbee05a 100644
--- a/drivers/staging/media/max96712/max96712.c
+++ b/drivers/staging/media/max96712/max96712.c
@@ -242,21 +242,34 @@ static const struct v4l2_subdev_video_ops max96712_video_ops = {
.s_stream = max96712_s_stream,
};
-static int max96712_get_pad_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
+static int max96712_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
{
- format->format.width = 1920;
- format->format.height = 1080;
- format->format.code = MEDIA_BUS_FMT_RGB888_1X24;
- format->format.field = V4L2_FIELD_NONE;
+ static const struct v4l2_mbus_framefmt default_fmt = {
+ .width = 1920,
+ .height = 1080,
+ .code = MEDIA_BUS_FMT_RGB888_1X24,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .field = V4L2_FIELD_NONE,
+ .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+ .quantization = V4L2_QUANTIZATION_DEFAULT,
+ .xfer_func = V4L2_XFER_FUNC_DEFAULT,
+ };
+ struct v4l2_mbus_framefmt *fmt;
+
+ fmt = v4l2_subdev_state_get_format(state, 0);
+ *fmt = default_fmt;
return 0;
}
+static const struct v4l2_subdev_internal_ops max96712_internal_ops = {
+ .init_state = max96712_init_state,
+};
+
static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
- .get_fmt = max96712_get_pad_format,
- .set_fmt = max96712_get_pad_format,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = v4l2_subdev_get_fmt,
};
static const struct v4l2_subdev_ops max96712_subdev_ops = {
@@ -293,6 +306,7 @@ static int max96712_v4l2_register(struct max96712_priv *priv)
long pixel_rate;
int ret;
+ priv->sd.internal_ops = &max96712_internal_ops;
v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
@@ -324,6 +338,11 @@ static int max96712_v4l2_register(struct max96712_priv *priv)
v4l2_set_subdevdata(&priv->sd, priv);
+ priv->sd.state_lock = priv->ctrl_handler.lock;
+ ret = v4l2_subdev_init_finalize(&priv->sd);
+ if (ret)
+ goto error;
+
ret = v4l2_async_register_subdev(&priv->sd);
if (ret < 0) {
dev_err(&priv->client->dev, "Unable to register subdevice\n");
diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h
index 783bda6d5cc3..16fac765456e 100644
--- a/include/media/ipu-bridge.h
+++ b/include/media/ipu-bridge.h
@@ -3,6 +3,7 @@
#ifndef __IPU_BRIDGE_H
#define __IPU_BRIDGE_H
+#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/types.h>
#include <media/v4l2-fwnode.h>
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index e30c463d90e5..1b74e037e440 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -450,6 +450,15 @@ enum v4l2_subdev_pre_streamon_flags {
* already started or stopped subdev. Also see call_s_stream wrapper in
* v4l2-subdev.c.
*
+ * New drivers should instead implement &v4l2_subdev_pad_ops.enable_streams
+ * and &v4l2_subdev_pad_ops.disable_streams operations, and use
+ * v4l2_subdev_s_stream_helper for the &v4l2_subdev_video_ops.s_stream
+ * operation to support legacy users.
+ *
+ * Drivers should also not call the .s_stream() subdev operation directly,
+ * but use the v4l2_subdev_enable_streams() and
+ * v4l2_subdev_disable_streams() helpers.
+ *
* @g_pixelaspect: callback to return the pixelaspect ratio.
*
* @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev
@@ -1041,10 +1050,11 @@ struct v4l2_subdev_platform_data {
* @active_state: Active state for the subdev (NULL for subdevs tracking the
* state internally). Initialized by calling
* v4l2_subdev_init_finalize().
- * @enabled_streams: Bitmask of enabled streams used by
- * v4l2_subdev_enable_streams() and
- * v4l2_subdev_disable_streams() helper functions for fallback
- * cases.
+ * @enabled_pads: Bitmask of enabled pads used by v4l2_subdev_enable_streams()
+ * and v4l2_subdev_disable_streams() helper functions for
+ * fallback cases.
+ * @s_stream_enabled: Tracks whether streaming has been enabled with s_stream.
+ * This is only for call_s_stream() internal use.
*
* Each instance of a subdev driver should create this struct, either
* stand-alone or embedded in a larger struct.
@@ -1092,7 +1102,8 @@ struct v4l2_subdev {
* doesn't support it.
*/
struct v4l2_subdev_state *active_state;
- u64 enabled_streams;
+ u64 enabled_pads;
+ bool s_stream_enabled;
};
@@ -1326,6 +1337,16 @@ void v4l2_subdev_cleanup(struct v4l2_subdev *sd);
#define __v4l2_subdev_state_gen_call(NAME, _1, ARG, ...) \
__v4l2_subdev_state_get_ ## NAME ## ARG
+/*
+ * A macro to constify the return value of the state accessors when the state
+ * parameter is const.
+ */
+#define __v4l2_subdev_state_constify_ret(state, value) \
+ _Generic(state, \
+ const struct v4l2_subdev_state *: (const typeof(*(value)) *)(value), \
+ struct v4l2_subdev_state *: (value) \
+ )
+
/**
* v4l2_subdev_state_get_format() - Get pointer to a stream format
* @state: subdevice state
@@ -1340,16 +1361,21 @@ void v4l2_subdev_cleanup(struct v4l2_subdev *sd);
*/
/*
* Wrap v4l2_subdev_state_get_format(), allowing the function to be called with
- * two or three arguments. The purpose of the __v4l2_subdev_state_get_format()
- * macro below is to come up with the name of the function or macro to call,
- * using the last two arguments (_stream and _pad). The selected function or
- * macro is then called using the arguments specified by the caller. A similar
- * arrangement is used for v4l2_subdev_state_crop() and
- * v4l2_subdev_state_compose() below.
- */
-#define v4l2_subdev_state_get_format(state, pad, ...) \
- __v4l2_subdev_state_gen_call(format, ##__VA_ARGS__, , _pad) \
- (state, pad, ##__VA_ARGS__)
+ * two or three arguments. The purpose of the __v4l2_subdev_state_gen_call()
+ * macro is to come up with the name of the function or macro to call, using
+ * the last two arguments (_stream and _pad). The selected function or macro is
+ * then called using the arguments specified by the caller. The
+ * __v4l2_subdev_state_constify_ret() macro constifies the returned pointer
+ * when the state is const, allowing the state accessors to guarantee
+ * const-correctness in all cases.
+ *
+ * A similar arrangement is used for v4l2_subdev_state_crop(),
+ * v4l2_subdev_state_compose() and v4l2_subdev_state_get_interval() below.
+ */
+#define v4l2_subdev_state_get_format(state, pad, ...) \
+ __v4l2_subdev_state_constify_ret(state, \
+ __v4l2_subdev_state_gen_call(format, ##__VA_ARGS__, , _pad) \
+ ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__))
#define __v4l2_subdev_state_get_format_pad(state, pad) \
__v4l2_subdev_state_get_format(state, pad, 0)
struct v4l2_mbus_framefmt *
@@ -1368,9 +1394,10 @@ __v4l2_subdev_state_get_format(struct v4l2_subdev_state *state,
* For stream-unaware drivers the crop rectangle for the corresponding pad is
* returned. If the pad does not exist, NULL is returned.
*/
-#define v4l2_subdev_state_get_crop(state, pad, ...) \
- __v4l2_subdev_state_gen_call(crop, ##__VA_ARGS__, , _pad) \
- (state, pad, ##__VA_ARGS__)
+#define v4l2_subdev_state_get_crop(state, pad, ...) \
+ __v4l2_subdev_state_constify_ret(state, \
+ __v4l2_subdev_state_gen_call(crop, ##__VA_ARGS__, , _pad) \
+ ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__))
#define __v4l2_subdev_state_get_crop_pad(state, pad) \
__v4l2_subdev_state_get_crop(state, pad, 0)
struct v4l2_rect *
@@ -1389,9 +1416,10 @@ __v4l2_subdev_state_get_crop(struct v4l2_subdev_state *state, unsigned int pad,
* For stream-unaware drivers the compose rectangle for the corresponding pad is
* returned. If the pad does not exist, NULL is returned.
*/
-#define v4l2_subdev_state_get_compose(state, pad, ...) \
- __v4l2_subdev_state_gen_call(compose, ##__VA_ARGS__, , _pad) \
- (state, pad, ##__VA_ARGS__)
+#define v4l2_subdev_state_get_compose(state, pad, ...) \
+ __v4l2_subdev_state_constify_ret(state, \
+ __v4l2_subdev_state_gen_call(compose, ##__VA_ARGS__, , _pad) \
+ ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__))
#define __v4l2_subdev_state_get_compose_pad(state, pad) \
__v4l2_subdev_state_get_compose(state, pad, 0)
struct v4l2_rect *
@@ -1410,9 +1438,10 @@ __v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,
* For stream-unaware drivers the frame interval for the corresponding pad is
* returned. If the pad does not exist, NULL is returned.
*/
-#define v4l2_subdev_state_get_interval(state, pad, ...) \
- __v4l2_subdev_state_gen_call(interval, ##__VA_ARGS__, , _pad) \
- (state, pad, ##__VA_ARGS__)
+#define v4l2_subdev_state_get_interval(state, pad, ...) \
+ __v4l2_subdev_state_constify_ret(state, \
+ __v4l2_subdev_state_gen_call(interval, ##__VA_ARGS__, , _pad) \
+ ((struct v4l2_subdev_state *)state, pad, ##__VA_ARGS__))
#define __v4l2_subdev_state_get_interval_pad(state, pad) \
__v4l2_subdev_state_get_interval(state, pad, 0)
struct v4l2_fract *
@@ -1954,4 +1983,17 @@ extern const struct v4l2_subdev_ops v4l2_subdev_call_wrappers;
void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
const struct v4l2_event *ev);
+/**
+ * v4l2_subdev_is_streaming() - Returns if the subdevice is streaming
+ * @sd: The subdevice
+ *
+ * v4l2_subdev_is_streaming() tells if the subdevice is currently streaming.
+ * "Streaming" here means whether .s_stream() or .enable_streams() has been
+ * successfully called, and the streaming has not yet been disabled.
+ *
+ * If the subdevice implements .enable_streams() this function must be called
+ * while holding the active state lock.
+ */
+bool v4l2_subdev_is_streaming(struct v4l2_subdev *sd);
+
#endif /* _V4L2_SUBDEV_H */