Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'media/v6.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

- Sensor driver fixes

- remove dead TI wl128x FM radio driver

- Add support for the imx462 sensor at the IMX290 binding

- V4L2 pixel data transmitter and receiver documentation improvements

- Add support for MIPI Discovery and Configuration for C-PHY line
orders

- imx8-isi fixes and improvements

- stm32: dcmipp: add core support for the stm32mp25

- qcom: camss: Add sc7280 support

- Various fixes and enhancements

* tag 'media/v6.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (152 commits)
media: nuvoton: Fix an error check in npcm_video_ece_init()
media: dvb-usb-v2: af9035: fix ISO C90 compilation error on af9035_i2c_master_xfer
media: platform: rzg2l-cru: rzg2l-video: Fix the comment in rzg2l_cru_start_streaming_vq()
media: fix secfeed undefined when filter alloc fail
media: dt-bindings: trivial white-space and example cleanup
MAINTAINERS: repair file entry in MEDIA DRIVERS FOR STM32 - CSI
media: solo6x10: Use const 'struct bin_attribute' callback
media: saa7164: Remove unused values
staging: media: imx: fix OF node leak in imx_media_add_of_subdevs()
media: platform: exynos4-is: Remove unused __is_get_frame_size
media: vidtv: Fix a null-ptr-deref in vidtv_mux_stop_thread
media: mmp: Bring back registration of the device
media: cec: include linux/debugfs.h and linux/seq_file.h where needed
Revert "media: qcom: camss: Restructure camss_link_entities"
media: venus: Remove unused hfi_core_ping()
media: dt-bindings: qcom-venus: Deprecate video-decoder and video-encoder where applicable
media: venus: Populate video encoder/decoder nodename entries
media: venus: Add support for static video encoder/decoder declarations
media: venus: match instance creation and destruction order
media: venus: destroy hfi session after m2m_ctx release
...

+4603 -6314
+1 -5
Documentation/admin-guide/media/ipu3.rst
··· 98 98 # and that ov5670 sensor is connected to i2c bus 10 with address 0x36 99 99 export SDEV=$(media-ctl -d $MDEV -e "ov5670 10-0036") 100 100 101 - # Establish the link for the media devices using media-ctl [#f3]_ 101 + # Establish the link for the media devices using media-ctl 102 102 media-ctl -d $MDEV -l "ov5670:0 -> ipu3-csi2 0:0[1]" 103 103 104 104 # Set the format for the media devices ··· 589 589 References 590 590 ========== 591 591 592 - .. [#f5] drivers/staging/media/ipu3/include/uapi/intel-ipu3.h 593 - 594 592 .. [#f1] https://github.com/intel/nvt 595 593 596 594 .. [#f2] http://git.ideasonboard.org/yavta.git 597 - 598 - .. [#f3] http://git.ideasonboard.org/?p=media-ctl.git;a=summary 599 595 600 596 .. [#f4] ImgU limitation requires an additional 16x16 for all input resolutions
-1
Documentation/devicetree/bindings/media/allwinner,sun50i-h6-vpu-g2.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/allwinner,sun50i-h6-vpu-g2.yaml#
-1
Documentation/devicetree/bindings/media/amlogic,meson-ir-tx.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/amlogic,meson-ir-tx.yaml#
-1
Documentation/devicetree/bindings/media/amphion,vpu.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
-1
Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/fsl,imx6ull-pxp.yaml#
+2
Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
··· 33 33 - sony,imx290lqr # Colour 34 34 - sony,imx290llr # Monochrome 35 35 - sony,imx327lqr # Colour 36 + - sony,imx462lqr # Colour 37 + - sony,imx462llr # Monochrome 36 38 - const: sony,imx290 37 39 deprecated: true 38 40
-1
Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
-1
Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
-1
Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#
+8 -9
Documentation/devicetree/bindings/media/microchip,sama5d4-vdec.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/microchip,sama5d4-vdec.yaml# ··· 35 36 36 37 examples: 37 38 - | 38 - #include <dt-bindings/clock/at91.h> 39 - #include <dt-bindings/interrupt-controller/irq.h> 39 + #include <dt-bindings/clock/at91.h> 40 + #include <dt-bindings/interrupt-controller/irq.h> 40 41 41 - vdec0: vdec@300000 { 42 - compatible = "microchip,sama5d4-vdec"; 43 - reg = <0x00300000 0x100000>; 44 - interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; 45 - clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; 46 - }; 42 + vdec@300000 { 43 + compatible = "microchip,sama5d4-vdec"; 44 + reg = <0x00300000 0x100000>; 45 + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; 46 + clocks = <&pmc PMC_TYPE_PERIPHERAL 19>; 47 + };
+2
Documentation/devicetree/bindings/media/nxp,imx8-isi.yaml
··· 21 21 enum: 22 22 - fsl,imx8mn-isi 23 23 - fsl,imx8mp-isi 24 + - fsl,imx8ulp-isi 24 25 - fsl,imx93-isi 25 26 26 27 reg: ··· 76 75 contains: 77 76 enum: 78 77 - fsl,imx8mn-isi 78 + - fsl,imx8ulp-isi 79 79 - fsl,imx93-isi 80 80 then: 81 81 properties:
+20 -21
Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml# ··· 43 44 44 45 examples: 45 46 - | 46 - #include <dt-bindings/clock/imx8mq-clock.h> 47 - #include <dt-bindings/power/imx8mq-power.h> 48 - #include <dt-bindings/interrupt-controller/arm-gic.h> 47 + #include <dt-bindings/clock/imx8mq-clock.h> 48 + #include <dt-bindings/power/imx8mq-power.h> 49 + #include <dt-bindings/interrupt-controller/arm-gic.h> 49 50 50 - vpu_g1: video-codec@38300000 { 51 - compatible = "nxp,imx8mq-vpu-g1"; 52 - reg = <0x38300000 0x10000>; 53 - interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; 54 - clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>; 55 - power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>; 56 - }; 51 + video-codec@38300000 { 52 + compatible = "nxp,imx8mq-vpu-g1"; 53 + reg = <0x38300000 0x10000>; 54 + interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; 55 + clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>; 56 + power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>; 57 + }; 57 58 - | 58 - #include <dt-bindings/clock/imx8mq-clock.h> 59 - #include <dt-bindings/power/imx8mq-power.h> 60 - #include <dt-bindings/interrupt-controller/arm-gic.h> 59 + #include <dt-bindings/clock/imx8mq-clock.h> 60 + #include <dt-bindings/power/imx8mq-power.h> 61 + #include <dt-bindings/interrupt-controller/arm-gic.h> 61 62 62 - vpu_g2: video-codec@38300000 { 63 - compatible = "nxp,imx8mq-vpu-g2"; 64 - reg = <0x38310000 0x10000>; 65 - interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; 66 - clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>; 67 - power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>; 68 - }; 63 + video-codec@38300000 { 64 + compatible = "nxp,imx8mq-vpu-g2"; 65 + reg = <0x38310000 0x10000>; 66 + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; 67 + clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>; 68 + power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>; 69 + };
-1
Documentation/devicetree/bindings/media/qcom,msm8916-camss.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/qcom,msm8916-camss.yaml#
+2 -10
Documentation/devicetree/bindings/media/qcom,msm8916-venus.yaml
··· 45 45 required: 46 46 - compatible 47 47 48 + deprecated: true 48 49 additionalProperties: false 49 50 50 51 video-encoder: ··· 58 57 required: 59 58 - compatible 60 59 60 + deprecated: true 61 61 additionalProperties: false 62 62 63 63 required: 64 64 - compatible 65 65 - iommus 66 - - video-decoder 67 - - video-encoder 68 66 69 67 unevaluatedProperties: false 70 68 ··· 83 83 power-domains = <&gcc VENUS_GDSC>; 84 84 iommus = <&apps_iommu 5>; 85 85 memory-region = <&venus_mem>; 86 - 87 - video-decoder { 88 - compatible = "venus-decoder"; 89 - }; 90 - 91 - video-encoder { 92 - compatible = "venus-encoder"; 93 - }; 94 86 };
-1
Documentation/devicetree/bindings/media/qcom,msm8996-camss.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/qcom,msm8996-camss.yaml#
+2 -10
Documentation/devicetree/bindings/media/qcom,sc7180-venus.yaml
··· 70 70 required: 71 71 - compatible 72 72 73 + deprecated: true 73 74 additionalProperties: false 74 75 75 76 video-encoder: ··· 83 82 required: 84 83 - compatible 85 84 85 + deprecated: true 86 86 additionalProperties: false 87 87 88 88 required: 89 89 - compatible 90 90 - power-domain-names 91 91 - iommus 92 - - video-decoder 93 - - video-encoder 94 92 95 93 unevaluatedProperties: false 96 94 ··· 114 114 "vcodec0_core", "vcodec0_bus"; 115 115 iommus = <&apps_smmu 0x0c00 0x60>; 116 116 memory-region = <&venus_mem>; 117 - 118 - video-decoder { 119 - compatible = "venus-decoder"; 120 - }; 121 - 122 - video-encoder { 123 - compatible = "venus-encoder"; 124 - }; 125 117 };
+425
Documentation/devicetree/bindings/media/qcom,sc7280-camss.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/media/qcom,sc7280-camss.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm SC7280 CAMSS ISP 8 + 9 + maintainers: 10 + - Azam Sadiq Pasha Kapatrala Syed <akapatra@quicinc.com> 11 + - Hariram Purushothaman <hariramp@quicinc.com> 12 + 13 + description: 14 + The CAMSS IP is a CSI decoder and ISP present on Qualcomm platforms. 15 + 16 + properties: 17 + compatible: 18 + const: qcom,sc7280-camss 19 + 20 + reg: 21 + maxItems: 15 22 + 23 + reg-names: 24 + items: 25 + - const: csid0 26 + - const: csid1 27 + - const: csid2 28 + - const: csid_lite0 29 + - const: csid_lite1 30 + - const: csiphy0 31 + - const: csiphy1 32 + - const: csiphy2 33 + - const: csiphy3 34 + - const: csiphy4 35 + - const: vfe0 36 + - const: vfe1 37 + - const: vfe2 38 + - const: vfe_lite0 39 + - const: vfe_lite1 40 + 41 + clocks: 42 + maxItems: 33 43 + 44 + clock-names: 45 + items: 46 + - const: camnoc_axi 47 + - const: cpas_ahb 48 + - const: csiphy0 49 + - const: csiphy0_timer 50 + - const: csiphy1 51 + - const: csiphy1_timer 52 + - const: csiphy2 53 + - const: csiphy2_timer 54 + - const: csiphy3 55 + - const: csiphy3_timer 56 + - const: csiphy4 57 + - const: csiphy4_timer 58 + - const: gcc_camera_ahb 59 + - const: gcc_cam_hf_axi 60 + - const: icp_ahb 61 + - const: vfe0 62 + - const: vfe0_axi 63 + - const: vfe0_cphy_rx 64 + - const: vfe0_csid 65 + - const: vfe1 66 + - const: vfe1_axi 67 + - const: vfe1_cphy_rx 68 + - const: vfe1_csid 69 + - const: vfe2 70 + - const: vfe2_axi 71 + - const: vfe2_cphy_rx 72 + - const: vfe2_csid 73 + - const: vfe_lite0 74 + - const: vfe_lite0_cphy_rx 75 + - const: vfe_lite0_csid 76 + - const: vfe_lite1 77 + - const: vfe_lite1_cphy_rx 78 + - const: vfe_lite1_csid 79 + 80 + interrupts: 81 + maxItems: 15 82 + 83 + interrupt-names: 84 + items: 85 + - const: csid0 86 + - const: csid1 87 + - const: csid2 88 + - const: csid_lite0 89 + - const: csid_lite1 90 + - const: csiphy0 91 + - const: csiphy1 92 + - const: csiphy2 93 + - const: csiphy3 94 + - const: csiphy4 95 + - const: vfe0 96 + - const: vfe1 97 + - const: vfe2 98 + - const: vfe_lite0 99 + - const: vfe_lite1 100 + 101 + interconnects: 102 + maxItems: 2 103 + 104 + interconnect-names: 105 + items: 106 + - const: ahb 107 + - const: hf_0 108 + 109 + iommus: 110 + maxItems: 1 111 + 112 + power-domains: 113 + items: 114 + - description: IFE0 GDSC - Image Front End, Global Distributed Switch Controller. 115 + - description: IFE1 GDSC - Image Front End, Global Distributed Switch Controller. 116 + - description: IFE2 GDSC - Image Front End, Global Distributed Switch Controller. 117 + - description: Titan GDSC - Titan ISP Block, Global Distributed Switch Controller. 118 + 119 + power-domain-names: 120 + items: 121 + - const: ife0 122 + - const: ife1 123 + - const: ife2 124 + - const: top 125 + 126 + vdda-phy-supply: 127 + description: 128 + Phandle to a regulator supply to PHY core block. 129 + 130 + vdda-pll-supply: 131 + description: 132 + Phandle to 1.8V regulator supply to PHY refclk pll block. 133 + 134 + ports: 135 + $ref: /schemas/graph.yaml#/properties/ports 136 + 137 + description: 138 + CSI input ports. 139 + 140 + properties: 141 + port@0: 142 + $ref: /schemas/graph.yaml#/$defs/port-base 143 + unevaluatedProperties: false 144 + description: 145 + Input port for receiving CSI data on CSIPHY 0. 146 + 147 + properties: 148 + endpoint: 149 + $ref: video-interfaces.yaml# 150 + unevaluatedProperties: false 151 + 152 + properties: 153 + data-lanes: 154 + minItems: 1 155 + maxItems: 4 156 + 157 + required: 158 + - data-lanes 159 + 160 + port@1: 161 + $ref: /schemas/graph.yaml#/$defs/port-base 162 + unevaluatedProperties: false 163 + description: 164 + Input port for receiving CSI data on CSIPHY 1. 165 + 166 + properties: 167 + endpoint: 168 + $ref: video-interfaces.yaml# 169 + unevaluatedProperties: false 170 + 171 + properties: 172 + data-lanes: 173 + minItems: 1 174 + maxItems: 4 175 + 176 + required: 177 + - data-lanes 178 + 179 + port@2: 180 + $ref: /schemas/graph.yaml#/$defs/port-base 181 + unevaluatedProperties: false 182 + description: 183 + Input port for receiving CSI data on CSIPHY 2. 184 + 185 + properties: 186 + endpoint: 187 + $ref: video-interfaces.yaml# 188 + unevaluatedProperties: false 189 + 190 + properties: 191 + data-lanes: 192 + minItems: 1 193 + maxItems: 4 194 + 195 + required: 196 + - data-lanes 197 + 198 + port@3: 199 + $ref: /schemas/graph.yaml#/$defs/port-base 200 + unevaluatedProperties: false 201 + description: 202 + Input port for receiving CSI data on CSIPHY 3. 203 + 204 + properties: 205 + endpoint: 206 + $ref: video-interfaces.yaml# 207 + unevaluatedProperties: false 208 + 209 + properties: 210 + data-lanes: 211 + minItems: 1 212 + maxItems: 4 213 + 214 + required: 215 + - data-lanes 216 + 217 + port@4: 218 + $ref: /schemas/graph.yaml#/$defs/port-base 219 + unevaluatedProperties: false 220 + description: 221 + Input port for receiving CSI data on CSIPHY 4. 222 + 223 + properties: 224 + endpoint: 225 + $ref: video-interfaces.yaml# 226 + unevaluatedProperties: false 227 + 228 + properties: 229 + data-lanes: 230 + minItems: 1 231 + maxItems: 4 232 + 233 + required: 234 + - data-lanes 235 + 236 + required: 237 + - compatible 238 + - reg 239 + - reg-names 240 + - clocks 241 + - clock-names 242 + - interrupts 243 + - interrupt-names 244 + - interconnects 245 + - interconnect-names 246 + - iommus 247 + - power-domains 248 + - power-domain-names 249 + - vdda-phy-supply 250 + - vdda-pll-supply 251 + 252 + additionalProperties: false 253 + 254 + examples: 255 + - | 256 + #include <dt-bindings/clock/qcom,camcc-sc7280.h> 257 + #include <dt-bindings/clock/qcom,gcc-sc7280.h> 258 + #include <dt-bindings/interconnect/qcom,sc7280.h> 259 + #include <dt-bindings/interconnect/qcom,icc.h> 260 + #include <dt-bindings/interrupt-controller/arm-gic.h> 261 + #include <dt-bindings/power/qcom-rpmpd.h> 262 + 263 + soc { 264 + #address-cells = <2>; 265 + #size-cells = <2>; 266 + 267 + isp@acb3000 { 268 + compatible = "qcom,sc7280-camss"; 269 + 270 + reg = <0x0 0x0acb3000 0x0 0x1000>, 271 + <0x0 0x0acba000 0x0 0x1000>, 272 + <0x0 0x0acc1000 0x0 0x1000>, 273 + <0x0 0x0acc8000 0x0 0x1000>, 274 + <0x0 0x0accf000 0x0 0x1000>, 275 + <0x0 0x0ace0000 0x0 0x2000>, 276 + <0x0 0x0ace2000 0x0 0x2000>, 277 + <0x0 0x0ace4000 0x0 0x2000>, 278 + <0x0 0x0ace6000 0x0 0x2000>, 279 + <0x0 0x0ace8000 0x0 0x2000>, 280 + <0x0 0x0acaf000 0x0 0x4000>, 281 + <0x0 0x0acb6000 0x0 0x4000>, 282 + <0x0 0x0acbd000 0x0 0x4000>, 283 + <0x0 0x0acc4000 0x0 0x4000>, 284 + <0x0 0x0accb000 0x0 0x4000>; 285 + reg-names = "csid0", 286 + "csid1", 287 + "csid2", 288 + "csid_lite0", 289 + "csid_lite1", 290 + "csiphy0", 291 + "csiphy1", 292 + "csiphy2", 293 + "csiphy3", 294 + "csiphy4", 295 + "vfe0", 296 + "vfe1", 297 + "vfe2", 298 + "vfe_lite0", 299 + "vfe_lite1"; 300 + 301 + clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>, 302 + <&camcc CAM_CC_CPAS_AHB_CLK>, 303 + <&camcc CAM_CC_CSIPHY0_CLK>, 304 + <&camcc CAM_CC_CSI0PHYTIMER_CLK>, 305 + <&camcc CAM_CC_CSIPHY1_CLK>, 306 + <&camcc CAM_CC_CSI1PHYTIMER_CLK>, 307 + <&camcc CAM_CC_CSIPHY2_CLK>, 308 + <&camcc CAM_CC_CSI2PHYTIMER_CLK>, 309 + <&camcc CAM_CC_CSIPHY3_CLK>, 310 + <&camcc CAM_CC_CSI3PHYTIMER_CLK>, 311 + <&camcc CAM_CC_CSIPHY4_CLK>, 312 + <&camcc CAM_CC_CSI4PHYTIMER_CLK>, 313 + <&gcc GCC_CAMERA_AHB_CLK>, 314 + <&gcc GCC_CAMERA_HF_AXI_CLK>, 315 + <&camcc CAM_CC_ICP_AHB_CLK>, 316 + <&camcc CAM_CC_IFE_0_CLK>, 317 + <&camcc CAM_CC_IFE_0_AXI_CLK>, 318 + <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>, 319 + <&camcc CAM_CC_IFE_0_CSID_CLK>, 320 + <&camcc CAM_CC_IFE_1_CLK>, 321 + <&camcc CAM_CC_IFE_1_AXI_CLK>, 322 + <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>, 323 + <&camcc CAM_CC_IFE_1_CSID_CLK>, 324 + <&camcc CAM_CC_IFE_2_CLK>, 325 + <&camcc CAM_CC_IFE_2_AXI_CLK>, 326 + <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>, 327 + <&camcc CAM_CC_IFE_2_CSID_CLK>, 328 + <&camcc CAM_CC_IFE_LITE_0_CLK>, 329 + <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>, 330 + <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>, 331 + <&camcc CAM_CC_IFE_LITE_1_CLK>, 332 + <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>, 333 + <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>; 334 + clock-names = "camnoc_axi", 335 + "cpas_ahb", 336 + "csiphy0", 337 + "csiphy0_timer", 338 + "csiphy1", 339 + "csiphy1_timer", 340 + "csiphy2", 341 + "csiphy2_timer", 342 + "csiphy3", 343 + "csiphy3_timer", 344 + "csiphy4", 345 + "csiphy4_timer", 346 + "gcc_camera_ahb", 347 + "gcc_cam_hf_axi", 348 + "icp_ahb", 349 + "vfe0", 350 + "vfe0_axi", 351 + "vfe0_cphy_rx", 352 + "vfe0_csid", 353 + "vfe1", 354 + "vfe1_axi", 355 + "vfe1_cphy_rx", 356 + "vfe1_csid", 357 + "vfe2", 358 + "vfe2_axi", 359 + "vfe2_cphy_rx", 360 + "vfe2_csid", 361 + "vfe_lite0", 362 + "vfe_lite0_cphy_rx", 363 + "vfe_lite0_csid", 364 + "vfe_lite1", 365 + "vfe_lite1_cphy_rx", 366 + "vfe_lite1_csid"; 367 + 368 + interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, 369 + <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, 370 + <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>, 371 + <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>, 372 + <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>, 373 + <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>, 374 + <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>, 375 + <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>, 376 + <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>, 377 + <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>, 378 + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, 379 + <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, 380 + <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>, 381 + <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>, 382 + <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>; 383 + interrupt-names = "csid0", 384 + "csid1", 385 + "csid2", 386 + "csid_lite0", 387 + "csid_lite1", 388 + "csiphy0", 389 + "csiphy1", 390 + "csiphy2", 391 + "csiphy3", 392 + "csiphy4", 393 + "vfe0", 394 + "vfe1", 395 + "vfe2", 396 + "vfe_lite0", 397 + "vfe_lite1"; 398 + 399 + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY 400 + &cnoc2 SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, 401 + <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS 402 + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; 403 + interconnect-names = "ahb", 404 + "hf_0"; 405 + 406 + iommus = <&apps_smmu 0x800 0x4e0>; 407 + 408 + power-domains = <&camcc CAM_CC_IFE_0_GDSC>, 409 + <&camcc CAM_CC_IFE_1_GDSC>, 410 + <&camcc CAM_CC_IFE_2_GDSC>, 411 + <&camcc CAM_CC_TITAN_TOP_GDSC>; 412 + power-domain-names = "ife0", 413 + "ife1", 414 + "ife2", 415 + "top"; 416 + 417 + vdda-phy-supply = <&vreg_l10c_0p88>; 418 + vdda-pll-supply = <&vreg_l6b_1p2>; 419 + 420 + ports { 421 + #address-cells = <1>; 422 + #size-cells = <0>; 423 + }; 424 + }; 425 + };
+2 -10
Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml
··· 68 68 required: 69 69 - compatible 70 70 71 + deprecated: true 71 72 additionalProperties: false 72 73 73 74 video-encoder: ··· 81 80 required: 82 81 - compatible 83 82 83 + deprecated: true 84 84 additionalProperties: false 85 85 86 86 required: 87 87 - compatible 88 88 - power-domain-names 89 89 - iommus 90 - - video-decoder 91 - - video-encoder 92 90 93 91 unevaluatedProperties: false 94 92 ··· 124 124 <&apps_smmu 0x2184 0x20>; 125 125 126 126 memory-region = <&video_mem>; 127 - 128 - video-decoder { 129 - compatible = "venus-decoder"; 130 - }; 131 - 132 - video-encoder { 133 - compatible = "venus-encoder"; 134 - }; 135 127 136 128 video-firmware { 137 129 iommus = <&apps_smmu 0x21a2 0x0>;
+20 -20
Documentation/devicetree/bindings/media/qcom,sc8280xp-camss.yaml
··· 328 328 vdda-phy-supply = <&vreg_l6d>; 329 329 vdda-pll-supply = <&vreg_l4d>; 330 330 331 - interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>, 332 - <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>, 333 - <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, 334 - <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>, 335 - <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>, 336 - <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>, 337 - <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>, 338 - <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>, 339 - <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>, 340 - <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>, 341 - <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>, 342 - <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>, 343 - <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>, 344 - <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>, 345 - <GIC_SPI 758 IRQ_TYPE_LEVEL_HIGH>, 346 - <GIC_SPI 759 IRQ_TYPE_LEVEL_HIGH>, 347 - <GIC_SPI 760 IRQ_TYPE_LEVEL_HIGH>, 348 - <GIC_SPI 761 IRQ_TYPE_LEVEL_HIGH>, 349 - <GIC_SPI 762 IRQ_TYPE_LEVEL_HIGH>, 350 - <GIC_SPI 764 IRQ_TYPE_LEVEL_HIGH>; 331 + interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>, 332 + <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>, 333 + <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>, 334 + <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, 335 + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, 336 + <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, 337 + <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, 338 + <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>, 339 + <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>, 340 + <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>, 341 + <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>, 342 + <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>, 343 + <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>, 344 + <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>, 345 + <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>, 346 + <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>, 347 + <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>, 348 + <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>, 349 + <GIC_SPI 762 IRQ_TYPE_EDGE_RISING>, 350 + <GIC_SPI 764 IRQ_TYPE_EDGE_RISING>; 351 351 352 352 interrupt-names = "csid1_lite", 353 353 "vfe_lite1",
-1
Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/qcom,sdm660-camss.yaml#
+10 -11
Documentation/devicetree/bindings/media/qcom,sdm845-camss.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/qcom,sdm845-camss.yaml# ··· 295 296 "vfe_lite_cphy_rx", 296 297 "vfe_lite_src"; 297 298 298 - interrupts = <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>, 299 - <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>, 300 - <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>, 301 - <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>, 302 - <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>, 303 - <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>, 304 - <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, 305 - <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>, 306 - <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>, 307 - <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>; 299 + interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, 300 + <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, 301 + <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>, 302 + <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>, 303 + <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>, 304 + <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>, 305 + <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>, 306 + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, 307 + <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, 308 + <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>; 308 309 309 310 interrupt-names = "csid0", 310 311 "csid1",
+2 -10
Documentation/devicetree/bindings/media/qcom,sdm845-venus-v2.yaml
··· 70 70 required: 71 71 - compatible 72 72 73 + deprecated: true 73 74 additionalProperties: false 74 75 75 76 video-core1: ··· 83 82 required: 84 83 - compatible 85 84 85 + deprecated: true 86 86 additionalProperties: false 87 87 88 88 required: 89 89 - compatible 90 90 - power-domain-names 91 91 - iommus 92 - - video-core0 93 - - video-core1 94 92 95 93 unevaluatedProperties: false 96 94 ··· 119 119 iommus = <&apps_smmu 0x10a0 0x8>, 120 120 <&apps_smmu 0x10b0 0x0>; 121 121 memory-region = <&venus_mem>; 122 - 123 - video-core0 { 124 - compatible = "venus-decoder"; 125 - }; 126 - 127 - video-core1 { 128 - compatible = "venus-encoder"; 129 - }; 130 122 };
+14 -15
Documentation/devicetree/bindings/media/qcom,sm8250-camss.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/qcom,sm8250-camss.yaml# ··· 328 329 vdda-phy-supply = <&vreg_l5a_0p88>; 329 330 vdda-pll-supply = <&vreg_l9a_1p2>; 330 331 331 - interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>, 332 - <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>, 333 - <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>, 334 - <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, 335 - <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, 336 - <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, 337 - <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>, 338 - <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>, 339 - <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>, 340 - <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>, 341 - <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>, 342 - <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>, 343 - <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>, 344 - <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>; 332 + interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>, 333 + <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>, 334 + <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>, 335 + <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>, 336 + <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>, 337 + <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>, 338 + <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, 339 + <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, 340 + <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>, 341 + <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>, 342 + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, 343 + <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, 344 + <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>, 345 + <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>; 345 346 interrupt-names = "csiphy0", 346 347 "csiphy1", 347 348 "csiphy2",
+2 -10
Documentation/devicetree/bindings/media/qcom,sm8250-venus.yaml
··· 73 73 required: 74 74 - compatible 75 75 76 + deprecated: true 76 77 additionalProperties: false 77 78 78 79 video-encoder: ··· 86 85 required: 87 86 - compatible 88 87 88 + deprecated: true 89 89 additionalProperties: false 90 90 91 91 required: ··· 97 95 - iommus 98 96 - resets 99 97 - reset-names 100 - - video-decoder 101 - - video-encoder 102 98 103 99 unevaluatedProperties: false 104 100 ··· 132 132 resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>, 133 133 <&videocc VIDEO_CC_MVS0C_CLK_ARES>; 134 134 reset-names = "bus", "core"; 135 - 136 - video-decoder { 137 - compatible = "venus-decoder"; 138 - }; 139 - 140 - video-encoder { 141 - compatible = "venus-encoder"; 142 - }; 143 135 };
-1
Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/rockchip,rk3568-vepu.yaml#
+14 -15
Documentation/devicetree/bindings/media/rockchip-vpu.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 - 3 2 %YAML 1.2 4 3 --- 5 4 $id: http://devicetree.org/schemas/media/rockchip-vpu.yaml# ··· 91 92 92 93 examples: 93 94 - | 94 - #include <dt-bindings/clock/rk3288-cru.h> 95 - #include <dt-bindings/interrupt-controller/arm-gic.h> 96 - #include <dt-bindings/power/rk3288-power.h> 95 + #include <dt-bindings/clock/rk3288-cru.h> 96 + #include <dt-bindings/interrupt-controller/arm-gic.h> 97 + #include <dt-bindings/power/rk3288-power.h> 97 98 98 - vpu: video-codec@ff9a0000 { 99 - compatible = "rockchip,rk3288-vpu"; 100 - reg = <0xff9a0000 0x800>; 101 - interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, 102 - <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; 103 - interrupt-names = "vepu", "vdpu"; 104 - clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; 105 - clock-names = "aclk", "hclk"; 106 - power-domains = <&power RK3288_PD_VIDEO>; 107 - iommus = <&vpu_mmu>; 108 - }; 99 + video-codec@ff9a0000 { 100 + compatible = "rockchip,rk3288-vpu"; 101 + reg = <0xff9a0000 0x800>; 102 + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, 103 + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; 104 + interrupt-names = "vepu", "vdpu"; 105 + clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; 106 + clock-names = "aclk", "hclk"; 107 + power-domains = <&power RK3288_PD_VIDEO>; 108 + iommus = <&vpu_mmu>; 109 + };
+47 -6
Documentation/devicetree/bindings/media/st,stm32-dcmipp.yaml
··· 12 12 13 13 properties: 14 14 compatible: 15 - const: st,stm32mp13-dcmipp 15 + enum: 16 + - st,stm32mp13-dcmipp 17 + - st,stm32mp25-dcmipp 16 18 17 19 reg: 18 20 maxItems: 1 ··· 23 21 maxItems: 1 24 22 25 23 clocks: 26 - maxItems: 1 24 + items: 25 + - description: bus clock 26 + - description: csi clock 27 + minItems: 1 28 + 29 + clock-names: 30 + items: 31 + - const: kclk 32 + - const: mclk 33 + minItems: 1 27 34 28 35 resets: 29 36 maxItems: 1 37 + 38 + access-controllers: 39 + minItems: 1 40 + maxItems: 2 30 41 31 42 port: 32 43 $ref: /schemas/graph.yaml#/$defs/port-base ··· 54 39 55 40 properties: 56 41 bus-type: 57 - enum: [5, 6] 42 + enum: [4, 5, 6] 58 43 default: 5 59 44 60 45 bus-width: ··· 65 50 hsync-active: true 66 51 vsync-active: true 67 52 68 - required: 69 - - pclk-sample 70 - 71 53 required: 72 54 - compatible 73 55 - reg ··· 72 60 - clocks 73 61 - resets 74 62 - port 63 + 64 + allOf: 65 + - if: 66 + properties: 67 + compatible: 68 + contains: 69 + enum: 70 + - st,stm32mp13-dcmipp 71 + then: 72 + properties: 73 + clocks: 74 + maxItems: 1 75 + 76 + clock-names: 77 + maxItems: 1 78 + 79 + port: 80 + properties: 81 + endpoint: 82 + properties: 83 + bus-type: 84 + enum: [5, 6] 85 + else: 86 + properties: 87 + clocks: 88 + minItems: 2 89 + 90 + clock-names: 91 + minItems: 2 75 92 76 93 additionalProperties: false 77 94
+125
Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/media/st,stm32mp25-csi.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: STMicroelectronics STM32 CSI controller 8 + 9 + description: 10 + The STM32 CSI controller allows connecting a CSI based 11 + camera to the DCMIPP camera pipeline. 12 + 13 + maintainers: 14 + - Alain Volmat <alain.volmat@foss.st.com> 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - st,stm32mp25-csi 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + interrupts: 25 + maxItems: 1 26 + 27 + clocks: 28 + maxItems: 3 29 + 30 + clock-names: 31 + items: 32 + - const: pclk 33 + - const: txesc 34 + - const: csi2phy 35 + 36 + resets: 37 + maxItems: 1 38 + 39 + vdd-supply: 40 + description: Digital core power supply (0.91V) 41 + 42 + vdda18-supply: 43 + description: System analog power supply (1.8V) 44 + 45 + access-controllers: 46 + minItems: 1 47 + maxItems: 2 48 + 49 + ports: 50 + $ref: /schemas/graph.yaml#/properties/ports 51 + 52 + properties: 53 + port@0: 54 + $ref: /schemas/graph.yaml#/$defs/port-base 55 + unevaluatedProperties: false 56 + description: 57 + Input port node 58 + 59 + properties: 60 + endpoint: 61 + $ref: video-interfaces.yaml# 62 + unevaluatedProperties: false 63 + 64 + properties: 65 + data-lanes: 66 + minItems: 1 67 + items: 68 + - const: 1 69 + - const: 2 70 + 71 + required: 72 + - data-lanes 73 + 74 + port@1: 75 + $ref: /schemas/graph.yaml#/properties/port 76 + description: 77 + Output port node 78 + 79 + required: 80 + - compatible 81 + - reg 82 + - interrupts 83 + - clocks 84 + - clock-names 85 + - resets 86 + - ports 87 + 88 + additionalProperties: false 89 + 90 + examples: 91 + - | 92 + #include <dt-bindings/clock/st,stm32mp25-rcc.h> 93 + #include <dt-bindings/interrupt-controller/arm-gic.h> 94 + #include <dt-bindings/media/video-interfaces.h> 95 + #include <dt-bindings/reset/st,stm32mp25-rcc.h> 96 + csi@48020000 { 97 + compatible = "st,stm32mp25-csi"; 98 + reg = <0x48020000 0x2000>; 99 + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; 100 + resets = <&rcc CSI_R>; 101 + clocks = <&rcc CK_KER_CSI>, <&rcc CK_KER_CSITXESC>, <&rcc CK_KER_CSIPHY>; 102 + clock-names = "pclk", "txesc", "csi2phy"; 103 + 104 + ports { 105 + #address-cells = <1>; 106 + #size-cells = <0>; 107 + port@0 { 108 + reg = <0>; 109 + endpoint { 110 + remote-endpoint = <&imx335_ep>; 111 + data-lanes = <1 2>; 112 + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; 113 + }; 114 + }; 115 + 116 + port@1 { 117 + reg = <1>; 118 + endpoint { 119 + remote-endpoint = <&dcmipp_0>; 120 + }; 121 + }; 122 + }; 123 + }; 124 + 125 + ...
+21
Documentation/devicetree/bindings/media/video-interfaces.yaml
··· 210 210 lane-polarities property is omitted, the value must be interpreted as 0 211 211 (normal). This property is valid for serial busses only. 212 212 213 + line-orders: 214 + $ref: /schemas/types.yaml#/definitions/uint32-array 215 + minItems: 1 216 + maxItems: 8 217 + items: 218 + enum: 219 + - 0 # ABC 220 + - 1 # ACB 221 + - 2 # BAC 222 + - 3 # BCA 223 + - 4 # CAB 224 + - 5 # CBA 225 + description: 226 + An array of line orders of the CSI-2 C-PHY data lanes. The order of the 227 + lanes are the same as in data-lanes property. Valid values are 0-5 as 228 + defined in the MIPI Discovery and Configuration (DisCo) Specification for 229 + Imaging. The length of the array must be the same length as the 230 + data-lanes property. If the line-orders property is omitted, the value 231 + shall be interpreted as 0 (ABC). This property is valid for CSI-2 C-PHY 232 + busses only. 233 + 213 234 strobe: 214 235 $ref: /schemas/types.yaml#/definitions/uint32 215 236 enum: [ 0, 1 ]
+5 -4
Documentation/driver-api/media/tx-rx.rst
··· 50 50 receiver the frequency of the bus (i.e. it is not the same as the symbol rate). 51 51 52 52 ``.enable_streams()`` and ``.disable_streams()`` callbacks 53 - ^^^^^^^^^^^^^^^^^^^^^^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 53 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 54 54 55 55 The struct v4l2_subdev_pad_ops->enable_streams() and struct 56 56 v4l2_subdev_pad_ops->disable_streams() callbacks are used by the receiver driver ··· 79 79 * - link_freq 80 80 - The value of the ``V4L2_CID_LINK_FREQ`` integer64 menu item. 81 81 * - nr_of_lanes 82 - - Number of data lanes used on the CSI-2 link. This can 83 - be obtained from the OF endpoint configuration. 82 + - Number of data lanes used on the CSI-2 link. 84 83 * - 2 85 84 - Data is transferred on both rising and falling edge of the signal. 86 85 * - bits_per_sample 87 86 - Number of bits per sample. 88 87 * - k 89 - - 16 for D-PHY and 7 for C-PHY 88 + - 16 for D-PHY and 7 for C-PHY. 89 + 90 + Information on whether D-PHY or C-PHY is used, and the value of ``nr_of_lanes``, can be obtained from the OF endpoint configuration. 90 91 91 92 .. note:: 92 93
+19 -6
MAINTAINERS
··· 824 824 825 825 ALLWINNER A31 CSI DRIVER 826 826 M: Yong Deng <yong.deng@magewell.com> 827 - M: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 827 + M: Paul Kocialkowski <paulk@sys-base.io> 828 828 L: linux-media@vger.kernel.org 829 829 S: Maintained 830 830 T: git git://linuxtv.org/media.git ··· 832 832 F: drivers/media/platform/sunxi/sun6i-csi/ 833 833 834 834 ALLWINNER A31 ISP DRIVER 835 - M: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 835 + M: Paul Kocialkowski <paulk@sys-base.io> 836 836 L: linux-media@vger.kernel.org 837 837 S: Maintained 838 838 T: git git://linuxtv.org/media.git ··· 841 841 F: drivers/staging/media/sunxi/sun6i-isp/uapi/sun6i-isp-config.h 842 842 843 843 ALLWINNER A31 MIPI CSI-2 BRIDGE DRIVER 844 - M: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 844 + M: Paul Kocialkowski <paulk@sys-base.io> 845 845 L: linux-media@vger.kernel.org 846 846 S: Maintained 847 847 T: git git://linuxtv.org/media.git ··· 884 884 885 885 ALLWINNER VPU DRIVER 886 886 M: Maxime Ripard <mripard@kernel.org> 887 - M: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 887 + M: Paul Kocialkowski <paulk@sys-base.io> 888 888 L: linux-media@vger.kernel.org 889 889 S: Maintained 890 890 F: drivers/staging/media/sunxi/cedrus/ ··· 7296 7296 F: drivers/gpu/drm/panel/panel-lg-sw43408.c 7297 7297 7298 7298 DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER 7299 - M: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 7299 + M: Paul Kocialkowski <paulk@sys-base.io> 7300 7300 S: Supported 7301 7301 T: git https://gitlab.freedesktop.org/drm/misc/kernel.git 7302 7302 F: drivers/gpu/drm/logicvc/ ··· 10099 10099 F: net/handshake/ 10100 10100 10101 10101 HANTRO VPU CODEC DRIVER 10102 - M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> 10102 + M: Nicolas Dufresne <nicolas.dufresne@collabora.com> 10103 + M: Benjamin Gaignard <benjamin.gaignard@collabora.com> 10103 10104 M: Philipp Zabel <p.zabel@pengutronix.de> 10104 10105 L: linux-media@vger.kernel.org 10105 10106 L: linux-rockchip@lists.infradead.org ··· 14590 14589 W: https://linuxtv.org 14591 14590 T: git git://linuxtv.org/media.git 14592 14591 F: drivers/media/dvb-frontends/stv6111* 14592 + 14593 + MEDIA DRIVERS FOR STM32 - CSI 14594 + M: Alain Volmat <alain.volmat@foss.st.com> 14595 + L: linux-media@vger.kernel.org 14596 + S: Supported 14597 + T: git git://linuxtv.org/media_tree.git 14598 + F: Documentation/devicetree/bindings/media/st,stm32mp25-csi.yaml 14599 + F: drivers/media/platform/st/stm32/stm32-csi.c 14593 14600 14594 14601 MEDIA DRIVERS FOR STM32 - DCMI / DCMIPP 14595 14602 M: Hugues Fruchet <hugues.fruchet@foss.st.com> ··· 24577 24568 S: Maintained 24578 24569 W: http://www.ideasonboard.org/uvc/ 24579 24570 T: git git://linuxtv.org/media.git 24571 + F: Documentation/userspace-api/media/drivers/uvcvideo.rst 24572 + F: Documentation/userspace-api/media/v4l/metafmt-uvc.rst 24573 + F: drivers/media/common/uvc.c 24580 24574 F: drivers/media/usb/uvc/ 24575 + F: include/linux/usb/uvc.h 24581 24576 F: include/uapi/linux/uvcvideo.h 24582 24577 24583 24578 USB WEBCAM GADGET
+3 -2
drivers/media/cec/core/cec-adap.c
··· 7 7 8 8 #include <linux/errno.h> 9 9 #include <linux/init.h> 10 - #include <linux/module.h> 11 10 #include <linux/kernel.h> 12 11 #include <linux/kmod.h> 13 12 #include <linux/ktime.h> 14 - #include <linux/slab.h> 15 13 #include <linux/mm.h> 14 + #include <linux/module.h> 15 + #include <linux/seq_file.h> 16 + #include <linux/slab.h> 16 17 #include <linux/string.h> 17 18 #include <linux/types.h> 18 19
+3 -2
drivers/media/cec/core/cec-core.c
··· 5 5 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 6 6 */ 7 7 8 + #include <linux/debugfs.h> 8 9 #include <linux/errno.h> 9 10 #include <linux/init.h> 10 - #include <linux/module.h> 11 11 #include <linux/kernel.h> 12 12 #include <linux/kmod.h> 13 - #include <linux/slab.h> 14 13 #include <linux/mm.h> 14 + #include <linux/module.h> 15 + #include <linux/slab.h> 15 16 #include <linux/string.h> 16 17 #include <linux/types.h> 17 18
+2 -1
drivers/media/cec/core/cec-pin-error-inj.c
··· 4 4 */ 5 5 6 6 #include <linux/delay.h> 7 - #include <linux/slab.h> 8 7 #include <linux/sched/types.h> 8 + #include <linux/seq_file.h> 9 + #include <linux/slab.h> 9 10 10 11 #include <media/cec-pin.h> 11 12 #include "cec-pin-priv.h"
+2 -1
drivers/media/cec/core/cec-pin.c
··· 4 4 */ 5 5 6 6 #include <linux/delay.h> 7 - #include <linux/slab.h> 8 7 #include <linux/sched/types.h> 8 + #include <linux/seq_file.h> 9 + #include <linux/slab.h> 9 10 10 11 #include <media/cec-pin.h> 11 12 #include "cec-pin-priv.h"
+4 -3
drivers/media/cec/platform/cec-gpio/cec-gpio.c
··· 3 3 * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 4 4 */ 5 5 6 - #include <linux/module.h> 7 - #include <linux/interrupt.h> 8 6 #include <linux/delay.h> 9 - #include <linux/platform_device.h> 10 7 #include <linux/gpio/consumer.h> 8 + #include <linux/interrupt.h> 9 + #include <linux/module.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/seq_file.h> 11 12 #include <media/cec-notifier.h> 12 13 #include <media/cec-pin.h> 13 14
-4
drivers/media/common/b2c2/flexcop-common.h
··· 125 125 126 126 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, 127 127 flexcop_dma_index_t no, int onoff); 128 - int flexcop_dma_control_size_irq(struct flexcop_device *fc, 129 - flexcop_dma_index_t no, int onoff); 130 128 int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, 131 129 flexcop_dma_index_t dma_idx); 132 130 int flexcop_dma_xfer_control(struct flexcop_device *fc, ··· 168 170 void flexcop_determine_revision(struct flexcop_device *fc); 169 171 void flexcop_device_name(struct flexcop_device *fc, 170 172 const char *prefix, const char *suffix); 171 - void flexcop_dump_reg(struct flexcop_device *fc, 172 - flexcop_ibi_register reg, int num); 173 173 174 174 /* from flexcop-hw-filter.c */ 175 175 int flexcop_pid_feed_control(struct flexcop_device *fc,
-13
drivers/media/common/b2c2/flexcop-misc.c
··· 70 70 flexcop_bus_names[fc->bus_type], 71 71 flexcop_revision_names[fc->rev], suffix); 72 72 } 73 - 74 - void flexcop_dump_reg(struct flexcop_device *fc, 75 - flexcop_ibi_register reg, int num) 76 - { 77 - flexcop_ibi_value v; 78 - int i; 79 - for (i = 0; i < num; i++) { 80 - v = fc->read_ibi_reg(fc, reg+4*i); 81 - deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw); 82 - } 83 - deb_rdump("\n"); 84 - } 85 - EXPORT_SYMBOL(flexcop_dump_reg);
+1 -1
drivers/media/dvb-core/dmxdev.c
··· 731 731 ret = (*secfeed)->allocate_filter(*secfeed, secfilter); 732 732 if (ret < 0) { 733 733 dvb_dmxdev_feed_restart(filter); 734 - filter->feed.sec->start_filtering(*secfeed); 734 + *secfeed = NULL; 735 735 dprintk("could not get filter\n"); 736 736 return ret; 737 737 }
+2 -6
drivers/media/dvb-frontends/cxd2841er.c
··· 311 311 312 312 static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz) 313 313 { 314 - u64 tmp; 315 - 316 - tmp = (u64) ifhz * 16777216; 317 - do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000)); 318 - 319 - return (u32) tmp; 314 + return div_u64(ifhz * 16777216ull, 315 + (xtal == SONY_XTAL_24000) ? 48000000 : 41000000); 320 316 } 321 317 322 318 static u32 cxd2841er_calc_iffreq(u32 ifhz)
+11 -7
drivers/media/i2c/ccs/ccs-core.c
··· 3335 3335 3336 3336 rval = request_firmware(&fw, filename, &client->dev); 3337 3337 if (!rval) { 3338 - ccs_data_parse(&sensor->sdata, fw->data, fw->size, &client->dev, 3339 - true); 3338 + rval = ccs_data_parse(&sensor->sdata, fw->data, fw->size, 3339 + &client->dev, true); 3340 3340 release_firmware(fw); 3341 + if (rval) 3342 + goto out_power_off; 3341 3343 } 3342 3344 3343 3345 if (!(ccsdev->flags & CCS_DEVICE_FLAG_IS_SMIA) || ··· 3353 3351 3354 3352 rval = request_firmware(&fw, filename, &client->dev); 3355 3353 if (!rval) { 3356 - ccs_data_parse(&sensor->mdata, fw->data, fw->size, 3357 - &client->dev, true); 3354 + rval = ccs_data_parse(&sensor->mdata, fw->data, 3355 + fw->size, &client->dev, true); 3358 3356 release_firmware(fw); 3357 + if (rval) 3358 + goto out_release_sdata; 3359 3359 } 3360 3360 } 3361 3361 ··· 3570 3566 out_cleanup: 3571 3567 ccs_cleanup(sensor); 3572 3568 3569 + out_free_ccs_limits: 3570 + kfree(sensor->ccs_limits); 3571 + 3573 3572 out_release_mdata: 3574 3573 kvfree(sensor->mdata.backing); 3575 3574 3576 3575 out_release_sdata: 3577 3576 kvfree(sensor->sdata.backing); 3578 - 3579 - out_free_ccs_limits: 3580 - kfree(sensor->ccs_limits); 3581 3577 3582 3578 out_power_off: 3583 3579 ccs_power_off(&client->dev);
+9 -6
drivers/media/i2c/ccs/ccs-data.c
··· 10 10 #include <linux/limits.h> 11 11 #include <linux/mm.h> 12 12 #include <linux/slab.h> 13 + #include <linux/string.h> 13 14 14 15 #include "ccs-data-defs.h" 15 16 ··· 98 97 plen = ((size_t) 99 98 (__len3->length[0] & 100 99 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1)) 101 - << 16) + (__len3->length[0] << 8) + __len3->length[1]; 100 + << 16) + (__len3->length[1] << 8) + __len3->length[2]; 102 101 break; 103 102 } 104 103 default: ··· 949 948 950 949 rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose); 951 950 if (rval) 952 - return rval; 951 + goto out_cleanup; 953 952 954 953 rval = bin_backing_alloc(&bin); 955 954 if (rval) 956 - return rval; 955 + goto out_cleanup; 957 956 958 957 rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false); 959 958 if (rval) 960 - goto out_free; 959 + goto out_cleanup; 961 960 962 961 if (verbose && ccsdata->version) 963 962 print_ccs_data_version(dev, ccsdata->version); ··· 966 965 rval = -EPROTO; 967 966 dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n", 968 967 bin.base, bin.now, bin.end); 969 - goto out_free; 968 + goto out_cleanup; 970 969 } 971 970 972 971 ccsdata->backing = bin.base; 973 972 974 973 return 0; 975 974 976 - out_free: 975 + out_cleanup: 977 976 kvfree(bin.base); 977 + memset(ccsdata, 0, sizeof(*ccsdata)); 978 + dev_warn(dev, "failed to parse CCS static data: %d\n", rval); 978 979 979 980 return rval; 980 981 }
+21 -5
drivers/media/i2c/ds90ub913.c
··· 8 8 * Copyright (c) 2023 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> 9 9 */ 10 10 11 + #include <linux/bitfield.h> 11 12 #include <linux/clk-provider.h> 12 13 #include <linux/clk.h> 13 14 #include <linux/delay.h> ··· 143 142 if (ret < 0) 144 143 dev_err(&priv->client->dev, 145 144 "Cannot write register 0x%02x: %d!\n", reg, ret); 145 + 146 + return ret; 147 + } 148 + 149 + static int ub913_update_bits(const struct ub913_data *priv, u8 reg, u8 mask, 150 + u8 val) 151 + { 152 + int ret; 153 + 154 + ret = regmap_update_bits(priv->regmap, reg, mask, val); 155 + if (ret < 0) 156 + dev_err(&priv->client->dev, 157 + "Cannot update register 0x%02x %d!\n", reg, ret); 146 158 147 159 return ret; 148 160 } ··· 747 733 if (ret) 748 734 return dev_err_probe(dev, ret, "i2c master init failed\n"); 749 735 750 - ub913_read(priv, UB913_REG_GENERAL_CFG, &v); 751 - v &= ~UB913_REG_GENERAL_CFG_PCLK_RISING; 752 - v |= priv->pclk_polarity_rising ? UB913_REG_GENERAL_CFG_PCLK_RISING : 0; 753 - ub913_write(priv, UB913_REG_GENERAL_CFG, v); 736 + ret = ub913_update_bits(priv, UB913_REG_GENERAL_CFG, 737 + UB913_REG_GENERAL_CFG_PCLK_RISING, 738 + FIELD_PREP(UB913_REG_GENERAL_CFG_PCLK_RISING, 739 + priv->pclk_polarity_rising)); 740 + 741 + if (ret) 742 + return ret; 754 743 755 744 return 0; 756 745 } ··· 810 793 v4l2_async_unregister_subdev(&priv->sd); 811 794 ub913_v4l2_nf_unregister(priv); 812 795 v4l2_subdev_cleanup(&priv->sd); 813 - fwnode_handle_put(priv->sd.fwnode); 814 796 media_entity_cleanup(&priv->sd.entity); 815 797 } 816 798
+41 -15
drivers/media/i2c/ds90ub953.c
··· 65 65 #define UB953_REG_GPIO_INPUT_CTRL_OUT_EN(n) BIT(4 + (n)) 66 66 #define UB953_REG_GPIO_INPUT_CTRL_INPUT_EN(n) BIT(0 + (n)) 67 67 68 + #define UB953_REG_BC_CTRL 0x49 69 + #define UB953_REG_BC_CTRL_CRC_ERR_CLR BIT(3) 70 + 68 71 #define UB953_REG_REV_MASK_ID 0x50 69 72 #define UB953_REG_GENERAL_STATUS 0x52 70 73 ··· 400 397 int ret; 401 398 402 399 /* Set all GPIOs to local input mode */ 403 - ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); 404 - ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); 400 + ret = ub953_write(priv, UB953_REG_LOCAL_GPIO_DATA, 0); 401 + if (ret) 402 + return ret; 403 + 404 + ret = ub953_write(priv, UB953_REG_GPIO_INPUT_CTRL, 0xf); 405 + if (ret) 406 + return ret; 405 407 406 408 gc->label = dev_name(dev); 407 409 gc->parent = dev; ··· 625 617 ub953_read(priv, UB953_REG_CRC_ERR_CNT1, &v1); 626 618 ub953_read(priv, UB953_REG_CRC_ERR_CNT2, &v2); 627 619 dev_info(dev, "CRC error count %u\n", v1 | (v2 << 8)); 620 + 621 + /* Clear CRC error counter */ 622 + if (v1 || v2) 623 + regmap_update_bits(priv->regmap, UB953_REG_BC_CTRL, 624 + UB953_REG_BC_CTRL_CRC_ERR_CLR, 625 + UB953_REG_BC_CTRL_CRC_ERR_CLR); 628 626 629 627 ub953_read(priv, UB953_REG_CSI_ERR_CNT, &v); 630 628 dev_info(dev, "CSI error count %u\n", v); ··· 972 958 clkout_data->rate = clkout_rate; 973 959 } 974 960 975 - static void ub953_write_clkout_regs(struct ub953_data *priv, 976 - const struct ub953_clkout_data *clkout_data) 961 + static int ub953_write_clkout_regs(struct ub953_data *priv, 962 + const struct ub953_clkout_data *clkout_data) 977 963 { 978 964 u8 clkout_ctrl0, clkout_ctrl1; 965 + int ret; 979 966 980 967 if (priv->hw_data->is_ub971) 981 968 clkout_ctrl0 = clkout_data->m; ··· 986 971 987 972 clkout_ctrl1 = clkout_data->n; 988 973 989 - ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); 990 - ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); 974 + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL0, clkout_ctrl0); 975 + if (ret) 976 + return ret; 977 + 978 + ret = ub953_write(priv, UB953_REG_CLKOUT_CTRL1, clkout_ctrl1); 979 + if (ret) 980 + return ret; 981 + 982 + return 0; 991 983 } 992 984 993 985 static unsigned long ub953_clkout_recalc_rate(struct clk_hw *hw, ··· 1074 1052 dev_dbg(&priv->client->dev, "%s %lu (requested %lu)\n", __func__, 1075 1053 clkout_data.rate, rate); 1076 1054 1077 - ub953_write_clkout_regs(priv, &clkout_data); 1078 - 1079 - return 0; 1055 + return ub953_write_clkout_regs(priv, &clkout_data); 1080 1056 } 1081 1057 1082 1058 static const struct clk_ops ub953_clkout_ops = { ··· 1099 1079 1100 1080 /* Initialize clkout to 25MHz by default */ 1101 1081 ub953_calc_clkout_params(priv, UB953_DEFAULT_CLKOUT_RATE, &clkout_data); 1102 - ub953_write_clkout_regs(priv, &clkout_data); 1082 + ret = ub953_write_clkout_regs(priv, &clkout_data); 1083 + if (ret) 1084 + return ret; 1103 1085 1104 1086 priv->clkout_clk_hw.init = &init; 1105 1087 ··· 1248 1226 if (ret) 1249 1227 return dev_err_probe(dev, ret, "i2c init failed\n"); 1250 1228 1251 - ub953_write(priv, UB953_REG_GENERAL_CFG, 1252 - (priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK) | 1253 - ((priv->num_data_lanes - 1) << UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT) | 1254 - UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE); 1229 + v = 0; 1230 + v |= priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK; 1231 + v |= (priv->num_data_lanes - 1) << 1232 + UB953_REG_GENERAL_CFG_CSI_LANE_SEL_SHIFT; 1233 + v |= UB953_REG_GENERAL_CFG_CRC_TX_GEN_ENABLE; 1234 + 1235 + ret = ub953_write(priv, UB953_REG_GENERAL_CFG, v); 1236 + if (ret) 1237 + return ret; 1255 1238 1256 1239 return 0; 1257 1240 } ··· 1315 1288 v4l2_async_unregister_subdev(&priv->sd); 1316 1289 ub953_v4l2_notifier_unregister(priv); 1317 1290 v4l2_subdev_cleanup(&priv->sd); 1318 - fwnode_handle_put(priv->sd.fwnode); 1319 1291 media_entity_cleanup(&priv->sd.entity); 1320 1292 } 1321 1293
+126 -62
drivers/media/i2c/ds90ub960.c
··· 43 43 #include <linux/regmap.h> 44 44 #include <linux/regulator/consumer.h> 45 45 #include <linux/slab.h> 46 + #include <linux/units.h> 46 47 #include <linux/workqueue.h> 47 48 48 49 #include <media/i2c/ds90ub9xx.h> ··· 52 51 #include <media/v4l2-fwnode.h> 53 52 #include <media/v4l2-subdev.h> 54 53 55 - #define MHZ(v) ((u32)((v) * 1000000U)) 54 + #define MHZ(v) ((u32)((v) * HZ_PER_MHZ)) 55 + 56 + /* 57 + * If this is defined, the i2c addresses from UB960_DEBUG_I2C_RX_ID to 58 + * UB960_DEBUG_I2C_RX_ID + 3 can be used to access the paged RX port registers 59 + * directly. 60 + * 61 + * Only for debug purposes. 62 + */ 63 + /* #define UB960_DEBUG_I2C_RX_ID 0x40 */ 56 64 57 65 #define UB960_POLL_TIME_MS 500 58 66 ··· 359 349 #define UB960_SR_FPD3_RX_ID(n) (0xf0 + (n)) 360 350 #define UB960_SR_FPD3_RX_ID_LEN 6 361 351 362 - #define UB960_SR_I2C_RX_ID(n) (0xf8 + (n)) /* < UB960_FPD_RX_NPORTS */ 352 + #define UB960_SR_I2C_RX_ID(n) (0xf8 + (n)) 353 + 354 + #define UB9702_SR_REFCLK_FREQ 0x3d 363 355 364 356 /* Indirect register blocks */ 365 357 #define UB960_IND_TARGET_PAT_GEN 0x00 366 358 #define UB960_IND_TARGET_RX_ANA(n) (0x01 + (n)) 367 - #define UB960_IND_TARGET_CSI_CSIPLL_REG_1 0x92 /* UB9702 */ 368 359 #define UB960_IND_TARGET_CSI_ANA 0x07 369 360 370 361 /* UB960_IR_PGEN_*: Indirect Registers for Test Pattern Generator */ ··· 579 568 }; 580 569 581 570 static const struct ub960_format_info ub960_formats[] = { 571 + { .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, .datatype = MIPI_CSI2_DT_RGB888, }, 572 + 582 573 { .code = MEDIA_BUS_FMT_YUYV8_1X16, .bpp = 16, .datatype = MIPI_CSI2_DT_YUV422_8B, }, 583 574 { .code = MEDIA_BUS_FMT_UYVY8_1X16, .bpp = 16, .datatype = MIPI_CSI2_DT_YUV422_8B, }, 584 575 { .code = MEDIA_BUS_FMT_VYUY8_1X16, .bpp = 16, .datatype = MIPI_CSI2_DT_YUV422_8B, }, 585 576 { .code = MEDIA_BUS_FMT_YVYU8_1X16, .bpp = 16, .datatype = MIPI_CSI2_DT_YUV422_8B, }, 577 + 578 + { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, }, 579 + { .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, }, 580 + { .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, }, 581 + { .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, .datatype = MIPI_CSI2_DT_RAW8, }, 582 + 583 + { .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, }, 584 + { .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, }, 585 + { .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, }, 586 + { .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, .datatype = MIPI_CSI2_DT_RAW10, }, 586 587 587 588 { .code = MEDIA_BUS_FMT_SBGGR12_1X12, .bpp = 12, .datatype = MIPI_CSI2_DT_RAW12, }, 588 589 { .code = MEDIA_BUS_FMT_SGBRG12_1X12, .bpp = 12, .datatype = MIPI_CSI2_DT_RAW12, }, ··· 1575 1552 if (missing == 0) 1576 1553 break; 1577 1554 1578 - msleep(50); 1555 + /* 1556 + * The sleep time of 10 ms was found by testing to give a lock 1557 + * with a few iterations. It can be decreased if on some setups 1558 + * the lock can be achieved much faster. 1559 + */ 1560 + fsleep(10 * USEC_PER_MSEC); 1579 1561 } 1580 1562 1581 1563 if (lock_mask) ··· 1602 1574 1603 1575 ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v); 1604 1576 1605 - ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); 1606 - if (ret) 1607 - return ret; 1577 + if (priv->hw_data->is_ub9702) { 1578 + dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n", 1579 + nport, ((u64)v * HZ_PER_MHZ) >> 8); 1580 + } else { 1581 + ret = ub960_rxport_get_strobe_pos(priv, nport, 1582 + &strobe_pos); 1583 + if (ret) 1584 + return ret; 1608 1585 1609 - ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); 1610 - if (ret) 1611 - return ret; 1586 + ret = ub960_rxport_get_eq_level(priv, nport, &eq_level); 1587 + if (ret) 1588 + return ret; 1612 1589 1613 - dev_dbg(dev, "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", 1614 - nport, strobe_pos, eq_level, (v * 1000000ULL) >> 8); 1590 + dev_dbg(dev, 1591 + "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n", 1592 + nport, strobe_pos, eq_level, 1593 + ((u64)v * HZ_PER_MHZ) >> 8); 1594 + } 1615 1595 } 1616 1596 1617 1597 return 0; ··· 2448 2412 } rx_data[UB960_MAX_RX_NPORTS] = {}; 2449 2413 u8 vc_map[UB960_MAX_RX_NPORTS] = {}; 2450 2414 struct v4l2_subdev_route *route; 2451 - unsigned int nport; 2452 2415 int ret; 2453 2416 2454 2417 ret = ub960_validate_stream_vcs(priv); ··· 2517 2482 */ 2518 2483 fwd_ctl = GENMASK(7, 4); 2519 2484 2520 - for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { 2485 + for (unsigned int nport = 0; nport < priv->hw_data->num_rxports; 2486 + nport++) { 2521 2487 struct ub960_rxport *rxport = priv->rxports[nport]; 2522 2488 u8 vc = vc_map[nport]; 2523 2489 ··· 2558 2522 for (i = 0; i < 8; i++) 2559 2523 ub960_rxport_write(priv, nport, 2560 2524 UB960_RR_VC_ID_MAP(i), 2561 - nport); 2525 + (nport << 4) | nport); 2562 2526 } 2563 2527 2564 2528 break; ··· 2975 2939 .set_fmt = ub960_set_fmt, 2976 2940 }; 2977 2941 2942 + static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv, 2943 + unsigned int nport) 2944 + { 2945 + struct device *dev = &priv->client->dev; 2946 + u8 eq_level; 2947 + s8 strobe_pos; 2948 + int ret; 2949 + u8 v; 2950 + 2951 + /* Strobe */ 2952 + 2953 + ret = ub960_read(priv, UB960_XR_AEQ_CTL1, &v); 2954 + if (ret) 2955 + return; 2956 + 2957 + dev_info(dev, "\t%s strobe\n", 2958 + (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : 2959 + "Manual"); 2960 + 2961 + if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { 2962 + ret = ub960_read(priv, UB960_XR_SFILTER_CFG, &v); 2963 + if (ret) 2964 + return; 2965 + 2966 + dev_info(dev, "\tStrobe range [%d, %d]\n", 2967 + ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, 2968 + ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); 2969 + } 2970 + 2971 + ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); 2972 + if (ret) 2973 + return; 2974 + 2975 + dev_info(dev, "\tStrobe pos %d\n", strobe_pos); 2976 + 2977 + /* EQ */ 2978 + 2979 + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); 2980 + if (ret) 2981 + return; 2982 + 2983 + dev_info(dev, "\t%s EQ\n", 2984 + (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : 2985 + "Adaptive"); 2986 + 2987 + if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { 2988 + ret = ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); 2989 + if (ret) 2990 + return; 2991 + 2992 + dev_info(dev, "\tEQ range [%u, %u]\n", 2993 + (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, 2994 + (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); 2995 + } 2996 + 2997 + if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) 2998 + dev_info(dev, "\tEQ level %u\n", eq_level); 2999 + } 3000 + 2978 3001 static int ub960_log_status(struct v4l2_subdev *sd) 2979 3002 { 2980 3003 struct ub960_data *priv = sd_to_ub960(sd); 2981 3004 struct device *dev = &priv->client->dev; 2982 3005 struct v4l2_subdev_state *state; 2983 3006 unsigned int nport; 2984 - unsigned int i; 2985 3007 u16 v16 = 0; 2986 3008 u8 v = 0; 2987 3009 u8 id[UB960_SR_FPD3_RX_ID_LEN]; 2988 3010 2989 3011 state = v4l2_subdev_lock_and_get_active_state(sd); 2990 3012 2991 - for (i = 0; i < sizeof(id); i++) 3013 + for (unsigned int i = 0; i < sizeof(id); i++) 2992 3014 ub960_read(priv, UB960_SR_FPD3_RX_ID(i), &id[i]); 2993 3015 2994 3016 dev_info(dev, "ID '%.*s'\n", (int)sizeof(id), id); ··· 3080 2986 3081 2987 for (nport = 0; nport < priv->hw_data->num_rxports; nport++) { 3082 2988 struct ub960_rxport *rxport = priv->rxports[nport]; 3083 - u8 eq_level; 3084 - s8 strobe_pos; 3085 - unsigned int i; 3086 2989 3087 2990 dev_info(dev, "RX %u\n", nport); 3088 2991 ··· 3100 3009 dev_info(dev, "\trx_port_sts2 %#02x\n", v); 3101 3010 3102 3011 ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v16); 3103 - dev_info(dev, "\tlink freq %llu Hz\n", (v16 * 1000000ULL) >> 8); 3012 + dev_info(dev, "\tlink freq %llu Hz\n", ((u64)v16 * HZ_PER_MHZ) >> 8); 3104 3013 3105 3014 ub960_rxport_read16(priv, nport, UB960_RR_RX_PAR_ERR_HI, &v16); 3106 3015 dev_info(dev, "\tparity errors %u\n", v16); ··· 3114 3023 ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v); 3115 3024 dev_info(dev, "\tcsi_err_counter %u\n", v); 3116 3025 3117 - /* Strobe */ 3118 - 3119 - ub960_read(priv, UB960_XR_AEQ_CTL1, &v); 3120 - 3121 - dev_info(dev, "\t%s strobe\n", 3122 - (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" : 3123 - "Manual"); 3124 - 3125 - if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) { 3126 - ub960_read(priv, UB960_XR_SFILTER_CFG, &v); 3127 - 3128 - dev_info(dev, "\tStrobe range [%d, %d]\n", 3129 - ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7, 3130 - ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7); 3131 - } 3132 - 3133 - ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos); 3134 - 3135 - dev_info(dev, "\tStrobe pos %d\n", strobe_pos); 3136 - 3137 - /* EQ */ 3138 - 3139 - ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v); 3140 - 3141 - dev_info(dev, "\t%s EQ\n", 3142 - (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" : 3143 - "Adaptive"); 3144 - 3145 - if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) { 3146 - ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v); 3147 - 3148 - dev_info(dev, "\tEQ range [%u, %u]\n", 3149 - (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf, 3150 - (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf); 3151 - } 3152 - 3153 - if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0) 3154 - dev_info(dev, "\tEQ level %u\n", eq_level); 3026 + if (!priv->hw_data->is_ub9702) 3027 + ub960_log_status_ub960_sp_eq(priv, nport); 3155 3028 3156 3029 /* GPIOs */ 3157 - for (i = 0; i < UB960_NUM_BC_GPIOS; i++) { 3030 + for (unsigned int i = 0; i < UB960_NUM_BC_GPIOS; i++) { 3158 3031 u8 ctl_reg; 3159 3032 u8 ctl_shift; 3160 3033 ··· 3889 3834 if (ret) 3890 3835 goto err_pd_gpio; 3891 3836 3892 - ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); 3837 + if (priv->hw_data->is_ub9702) 3838 + ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq); 3839 + else 3840 + ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq); 3893 3841 if (ret) 3894 3842 goto err_pd_gpio; 3895 3843 3896 3844 dev_dbg(dev, "refclk valid %u freq %u MHz (clk fw freq %lu MHz)\n", 3897 3845 !!(dev_sts & BIT(4)), refclk_freq, 3898 - clk_get_rate(priv->refclk) / 1000000); 3846 + clk_get_rate(priv->refclk) / HZ_PER_MHZ); 3899 3847 3900 3848 /* Disable all RX ports by default */ 3901 3849 ret = ub960_write(priv, UB960_SR_RX_PORT_CTL, 0); ··· 4031 3973 4032 3974 schedule_delayed_work(&priv->poll_work, 4033 3975 msecs_to_jiffies(UB960_POLL_TIME_MS)); 3976 + 3977 + #ifdef UB960_DEBUG_I2C_RX_ID 3978 + for (unsigned int i = 0; i < priv->hw_data->num_rxports; i++) 3979 + ub960_write(priv, UB960_SR_I2C_RX_ID(i), 3980 + (UB960_DEBUG_I2C_RX_ID + i) << 1); 3981 + #endif 4034 3982 4035 3983 return 0; 4036 3984
+1 -1
drivers/media/i2c/imx208.c
··· 814 814 } 815 815 816 816 static ssize_t otp_read(struct file *filp, struct kobject *kobj, 817 - struct bin_attribute *bin_attr, 817 + const struct bin_attribute *bin_attr, 818 818 char *buf, loff_t off, size_t count) 819 819 { 820 820 struct i2c_client *client = to_i2c_client(kobj_to_dev(kobj));
+74 -7
drivers/media/i2c/imx290.c
··· 170 170 IMX290_MODEL_IMX290LQR, 171 171 IMX290_MODEL_IMX290LLR, 172 172 IMX290_MODEL_IMX327LQR, 173 + IMX290_MODEL_IMX462LQR, 174 + IMX290_MODEL_IMX462LLR, 173 175 }; 174 176 175 177 struct imx290_model_info { 176 178 enum imx290_colour_variant colour_variant; 177 179 const struct cci_reg_sequence *init_regs; 178 180 size_t init_regs_num; 181 + unsigned int max_analog_gain; 179 182 const char *name; 180 183 }; 181 184 ··· 270 267 { IMX290_WINWV, 1097 }, 271 268 { IMX290_XSOUTSEL, IMX290_XSOUTSEL_XVSOUTSEL_VSYNC | 272 269 IMX290_XSOUTSEL_XHSOUTSEL_HSYNC }, 273 - { CCI_REG8(0x3011), 0x02 }, 274 270 { CCI_REG8(0x3012), 0x64 }, 275 271 { CCI_REG8(0x3013), 0x00 }, 276 272 }; ··· 277 275 static const struct cci_reg_sequence imx290_global_init_settings_290[] = { 278 276 { CCI_REG8(0x300f), 0x00 }, 279 277 { CCI_REG8(0x3010), 0x21 }, 278 + { CCI_REG8(0x3011), 0x00 }, 279 + { CCI_REG8(0x3016), 0x09 }, 280 + { CCI_REG8(0x3070), 0x02 }, 281 + { CCI_REG8(0x3071), 0x11 }, 282 + { CCI_REG8(0x309b), 0x10 }, 283 + { CCI_REG8(0x309c), 0x22 }, 284 + { CCI_REG8(0x30a2), 0x02 }, 285 + { CCI_REG8(0x30a6), 0x20 }, 286 + { CCI_REG8(0x30a8), 0x20 }, 287 + { CCI_REG8(0x30aa), 0x20 }, 288 + { CCI_REG8(0x30ac), 0x20 }, 289 + { CCI_REG8(0x30b0), 0x43 }, 290 + { CCI_REG8(0x3119), 0x9e }, 291 + { CCI_REG8(0x311c), 0x1e }, 292 + { CCI_REG8(0x311e), 0x08 }, 293 + { CCI_REG8(0x3128), 0x05 }, 294 + { CCI_REG8(0x313d), 0x83 }, 295 + { CCI_REG8(0x3150), 0x03 }, 296 + { CCI_REG8(0x317e), 0x00 }, 297 + { CCI_REG8(0x32b8), 0x50 }, 298 + { CCI_REG8(0x32b9), 0x10 }, 299 + { CCI_REG8(0x32ba), 0x00 }, 300 + { CCI_REG8(0x32bb), 0x04 }, 301 + { CCI_REG8(0x32c8), 0x50 }, 302 + { CCI_REG8(0x32c9), 0x10 }, 303 + { CCI_REG8(0x32ca), 0x00 }, 304 + { CCI_REG8(0x32cb), 0x04 }, 305 + { CCI_REG8(0x332c), 0xd3 }, 306 + { CCI_REG8(0x332d), 0x10 }, 307 + { CCI_REG8(0x332e), 0x0d }, 308 + { CCI_REG8(0x3358), 0x06 }, 309 + { CCI_REG8(0x3359), 0xe1 }, 310 + { CCI_REG8(0x335a), 0x11 }, 311 + { CCI_REG8(0x3360), 0x1e }, 312 + { CCI_REG8(0x3361), 0x61 }, 313 + { CCI_REG8(0x3362), 0x10 }, 314 + { CCI_REG8(0x33b0), 0x50 }, 315 + { CCI_REG8(0x33b2), 0x1a }, 316 + { CCI_REG8(0x33b3), 0x04 }, 317 + }; 318 + 319 + static const struct cci_reg_sequence imx290_global_init_settings_462[] = { 320 + { CCI_REG8(0x300f), 0x00 }, 321 + { CCI_REG8(0x3010), 0x21 }, 322 + { CCI_REG8(0x3011), 0x02 }, 280 323 { CCI_REG8(0x3016), 0x09 }, 281 324 { CCI_REG8(0x3070), 0x02 }, 282 325 { CCI_REG8(0x3071), 0x11 }, ··· 375 328 }; 376 329 377 330 static const struct cci_reg_sequence imx290_global_init_settings_327[] = { 331 + { CCI_REG8(0x3011), 0x02 }, 378 332 { CCI_REG8(0x309e), 0x4A }, 379 333 { CCI_REG8(0x309f), 0x4A }, 380 334 { CCI_REG8(0x313b), 0x61 }, ··· 924 876 * up to 72.0dB (240) add further digital gain. Limit the range to 925 877 * analog gain only, support for digital gain can be added separately 926 878 * if needed. 927 - * 928 - * The IMX327 and IMX462 are largely compatible with the IMX290, but 929 - * have an analog gain range of 0.0dB to 29.4dB and 42dB of digital 930 - * gain. When support for those sensors gets added to the driver, the 931 - * gain control should be adjusted accordingly. 932 879 */ 933 880 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, 934 - V4L2_CID_ANALOGUE_GAIN, 0, 100, 1, 0); 881 + V4L2_CID_ANALOGUE_GAIN, 0, 882 + imx290->model->max_analog_gain, 1, 0); 935 883 936 884 /* 937 885 * Correct range will be determined through imx290_ctrl_update setting ··· 1485 1441 .colour_variant = IMX290_VARIANT_COLOUR, 1486 1442 .init_regs = imx290_global_init_settings_290, 1487 1443 .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290), 1444 + .max_analog_gain = 100, 1488 1445 .name = "imx290", 1489 1446 }, 1490 1447 [IMX290_MODEL_IMX290LLR] = { 1491 1448 .colour_variant = IMX290_VARIANT_MONO, 1492 1449 .init_regs = imx290_global_init_settings_290, 1493 1450 .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_290), 1451 + .max_analog_gain = 100, 1494 1452 .name = "imx290", 1495 1453 }, 1496 1454 [IMX290_MODEL_IMX327LQR] = { 1497 1455 .colour_variant = IMX290_VARIANT_COLOUR, 1498 1456 .init_regs = imx290_global_init_settings_327, 1499 1457 .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_327), 1458 + .max_analog_gain = 98, 1500 1459 .name = "imx327", 1460 + }, 1461 + [IMX290_MODEL_IMX462LQR] = { 1462 + .colour_variant = IMX290_VARIANT_COLOUR, 1463 + .init_regs = imx290_global_init_settings_462, 1464 + .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_462), 1465 + .max_analog_gain = 98, 1466 + .name = "imx462", 1467 + }, 1468 + [IMX290_MODEL_IMX462LLR] = { 1469 + .colour_variant = IMX290_VARIANT_MONO, 1470 + .init_regs = imx290_global_init_settings_462, 1471 + .init_regs_num = ARRAY_SIZE(imx290_global_init_settings_462), 1472 + .max_analog_gain = 98, 1473 + .name = "imx462", 1501 1474 }, 1502 1475 }; 1503 1476 ··· 1714 1653 }, { 1715 1654 .compatible = "sony,imx327lqr", 1716 1655 .data = &imx290_models[IMX290_MODEL_IMX327LQR], 1656 + }, { 1657 + .compatible = "sony,imx462lqr", 1658 + .data = &imx290_models[IMX290_MODEL_IMX462LQR], 1659 + }, { 1660 + .compatible = "sony,imx462llr", 1661 + .data = &imx290_models[IMX290_MODEL_IMX462LLR], 1717 1662 }, 1718 1663 { /* sentinel */ }, 1719 1664 };
+2
drivers/media/i2c/imx296.c
··· 954 954 return ret; 955 955 } 956 956 957 + usleep_range(2000, 5000); 958 + 957 959 ret = imx296_read(sensor, IMX296_SENSOR_INFO); 958 960 if (ret < 0) { 959 961 dev_err(sensor->dev, "failed to read sensor information (%d)\n",
+21 -21
drivers/media/i2c/imx412.c
··· 547 547 548 548 lpfr = imx412->vblank + imx412->cur_mode->height; 549 549 550 - dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u", 550 + dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n", 551 551 exposure, gain, lpfr); 552 552 553 553 ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1); ··· 594 594 case V4L2_CID_VBLANK: 595 595 imx412->vblank = imx412->vblank_ctrl->val; 596 596 597 - dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u", 597 + dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n", 598 598 imx412->vblank, 599 599 imx412->vblank + imx412->cur_mode->height); 600 600 ··· 613 613 exposure = ctrl->val; 614 614 analog_gain = imx412->again_ctrl->val; 615 615 616 - dev_dbg(imx412->dev, "Received exp %u, analog gain %u", 616 + dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n", 617 617 exposure, analog_gain); 618 618 619 619 ret = imx412_update_exp_gain(imx412, exposure, analog_gain); ··· 622 622 623 623 break; 624 624 default: 625 - dev_err(imx412->dev, "Invalid control %d", ctrl->id); 625 + dev_err(imx412->dev, "Invalid control %d\n", ctrl->id); 626 626 ret = -EINVAL; 627 627 } 628 628 ··· 803 803 ret = imx412_write_regs(imx412, reg_list->regs, 804 804 reg_list->num_of_regs); 805 805 if (ret) { 806 - dev_err(imx412->dev, "fail to write initial registers"); 806 + dev_err(imx412->dev, "fail to write initial registers\n"); 807 807 return ret; 808 808 } 809 809 810 810 /* Setup handler will write actual exposure and gain */ 811 811 ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler); 812 812 if (ret) { 813 - dev_err(imx412->dev, "fail to setup handler"); 813 + dev_err(imx412->dev, "fail to setup handler\n"); 814 814 return ret; 815 815 } 816 816 ··· 821 821 ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT, 822 822 1, IMX412_MODE_STREAMING); 823 823 if (ret) { 824 - dev_err(imx412->dev, "fail to start streaming"); 824 + dev_err(imx412->dev, "fail to start streaming\n"); 825 825 return ret; 826 826 } 827 827 ··· 895 895 return ret; 896 896 897 897 if (val != IMX412_ID) { 898 - dev_err(imx412->dev, "chip id mismatch: %x!=%x", 898 + dev_err(imx412->dev, "chip id mismatch: %x!=%x\n", 899 899 IMX412_ID, val); 900 900 return -ENXIO; 901 901 } ··· 927 927 imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset", 928 928 GPIOD_OUT_LOW); 929 929 if (IS_ERR(imx412->reset_gpio)) { 930 - dev_err(imx412->dev, "failed to get reset gpio %ld", 930 + dev_err(imx412->dev, "failed to get reset gpio %ld\n", 931 931 PTR_ERR(imx412->reset_gpio)); 932 932 return PTR_ERR(imx412->reset_gpio); 933 933 } ··· 935 935 /* Get sensor input clock */ 936 936 imx412->inclk = devm_clk_get(imx412->dev, NULL); 937 937 if (IS_ERR(imx412->inclk)) { 938 - dev_err(imx412->dev, "could not get inclk"); 938 + dev_err(imx412->dev, "could not get inclk\n"); 939 939 return PTR_ERR(imx412->inclk); 940 940 } 941 941 942 942 rate = clk_get_rate(imx412->inclk); 943 943 if (rate != IMX412_INCLK_RATE) { 944 - dev_err(imx412->dev, "inclk frequency mismatch"); 944 + dev_err(imx412->dev, "inclk frequency mismatch\n"); 945 945 return -EINVAL; 946 946 } 947 947 ··· 966 966 967 967 if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX412_NUM_DATA_LANES) { 968 968 dev_err(imx412->dev, 969 - "number of CSI2 data lanes %d is not supported", 969 + "number of CSI2 data lanes %d is not supported\n", 970 970 bus_cfg.bus.mipi_csi2.num_data_lanes); 971 971 ret = -EINVAL; 972 972 goto done_endpoint_free; 973 973 } 974 974 975 975 if (!bus_cfg.nr_of_link_frequencies) { 976 - dev_err(imx412->dev, "no link frequencies defined"); 976 + dev_err(imx412->dev, "no link frequencies defined\n"); 977 977 ret = -EINVAL; 978 978 goto done_endpoint_free; 979 979 } ··· 1034 1034 1035 1035 ret = clk_prepare_enable(imx412->inclk); 1036 1036 if (ret) { 1037 - dev_err(imx412->dev, "fail to enable inclk"); 1037 + dev_err(imx412->dev, "fail to enable inclk\n"); 1038 1038 goto error_reset; 1039 1039 } 1040 1040 ··· 1145 1145 imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1146 1146 1147 1147 if (ctrl_hdlr->error) { 1148 - dev_err(imx412->dev, "control init failed: %d", 1148 + dev_err(imx412->dev, "control init failed: %d\n", 1149 1149 ctrl_hdlr->error); 1150 1150 v4l2_ctrl_handler_free(ctrl_hdlr); 1151 1151 return ctrl_hdlr->error; ··· 1183 1183 1184 1184 ret = imx412_parse_hw_config(imx412); 1185 1185 if (ret) { 1186 - dev_err(imx412->dev, "HW configuration is not supported"); 1186 + dev_err(imx412->dev, "HW configuration is not supported\n"); 1187 1187 return ret; 1188 1188 } 1189 1189 ··· 1191 1191 1192 1192 ret = imx412_power_on(imx412->dev); 1193 1193 if (ret) { 1194 - dev_err(imx412->dev, "failed to power-on the sensor"); 1194 + dev_err(imx412->dev, "failed to power-on the sensor\n"); 1195 1195 goto error_mutex_destroy; 1196 1196 } 1197 1197 1198 1198 /* Check module identity */ 1199 1199 ret = imx412_detect(imx412); 1200 1200 if (ret) { 1201 - dev_err(imx412->dev, "failed to find sensor: %d", ret); 1201 + dev_err(imx412->dev, "failed to find sensor: %d\n", ret); 1202 1202 goto error_power_off; 1203 1203 } 1204 1204 ··· 1208 1208 1209 1209 ret = imx412_init_controls(imx412); 1210 1210 if (ret) { 1211 - dev_err(imx412->dev, "failed to init controls: %d", ret); 1211 + dev_err(imx412->dev, "failed to init controls: %d\n", ret); 1212 1212 goto error_power_off; 1213 1213 } 1214 1214 ··· 1222 1222 imx412->pad.flags = MEDIA_PAD_FL_SOURCE; 1223 1223 ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad); 1224 1224 if (ret) { 1225 - dev_err(imx412->dev, "failed to init entity pads: %d", ret); 1225 + dev_err(imx412->dev, "failed to init entity pads: %d\n", ret); 1226 1226 goto error_handler_free; 1227 1227 } 1228 1228 1229 1229 ret = v4l2_async_register_subdev_sensor(&imx412->sd); 1230 1230 if (ret < 0) { 1231 1231 dev_err(imx412->dev, 1232 - "failed to register async subdev: %d", ret); 1232 + "failed to register async subdev: %d\n", ret); 1233 1233 goto error_media_entity; 1234 1234 } 1235 1235
+52 -6
drivers/media/i2c/ov2740.c
··· 11 11 #include <linux/pm_runtime.h> 12 12 #include <linux/nvmem-provider.h> 13 13 #include <linux/regmap.h> 14 + #include <linux/regulator/consumer.h> 14 15 #include <media/v4l2-ctrls.h> 15 16 #include <media/v4l2-device.h> 16 17 #include <media/v4l2-fwnode.h> ··· 76 75 #define CUSTOMER_USE_OTP_SIZE 0x100 77 76 /* OTP registers from sensor */ 78 77 #define OV2740_REG_OTP_CUSTOMER 0x7010 78 + 79 + static const char * const ov2740_supply_name[] = { 80 + "AVDD", 81 + "DOVDD", 82 + "DVDD", 83 + }; 84 + 85 + #define OV2740_NUM_SUPPLIES ARRAY_SIZE(ov2740_supply_name) 79 86 80 87 struct nvm_data { 81 88 struct nvmem_device *nvmem; ··· 532 523 struct v4l2_ctrl *hblank; 533 524 struct v4l2_ctrl *exposure; 534 525 535 - /* GPIOs, clocks */ 526 + /* GPIOs, clocks, regulators */ 536 527 struct gpio_desc *reset_gpio; 528 + struct gpio_desc *powerdown_gpio; 537 529 struct clk *clk; 530 + struct regulator_bulk_data supplies[OV2740_NUM_SUPPLIES]; 538 531 539 532 /* Current mode */ 540 533 const struct ov2740_mode *cur_mode; ··· 655 644 return -ENXIO; 656 645 } 657 646 647 + dev_dbg(&client->dev, "chip id: %x\n", val); 648 + 658 649 ov2740->identified = true; 659 650 660 651 return 0; ··· 766 753 767 754 static int ov2740_init_controls(struct ov2740 *ov2740) 768 755 { 756 + struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd); 769 757 struct v4l2_ctrl_handler *ctrl_hdlr; 770 758 const struct ov2740_mode *cur_mode; 771 759 s64 exposure_max, h_blank, pixel_rate; 772 760 u32 vblank_min, vblank_max, vblank_default; 761 + struct v4l2_fwnode_device_properties props; 773 762 int size; 774 763 int ret; 775 764 776 765 ctrl_hdlr = &ov2740->ctrl_handler; 777 - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); 766 + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10); 778 767 if (ret) 779 768 return ret; 780 769 ··· 826 811 V4L2_CID_TEST_PATTERN, 827 812 ARRAY_SIZE(ov2740_test_pattern_menu) - 1, 828 813 0, 0, ov2740_test_pattern_menu); 814 + 815 + ret = v4l2_fwnode_device_parse(&client->dev, &props); 816 + if (ret) 817 + return ret; 818 + 819 + v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov2740_ctrl_ops, &props); 820 + 829 821 if (ctrl_hdlr->error) { 830 822 v4l2_ctrl_handler_free(ctrl_hdlr); 831 823 return ctrl_hdlr->error; ··· 1317 1295 struct ov2740 *ov2740 = to_ov2740(sd); 1318 1296 1319 1297 gpiod_set_value_cansleep(ov2740->reset_gpio, 1); 1298 + gpiod_set_value_cansleep(ov2740->powerdown_gpio, 1); 1320 1299 clk_disable_unprepare(ov2740->clk); 1300 + regulator_bulk_disable(OV2740_NUM_SUPPLIES, ov2740->supplies); 1321 1301 return 0; 1322 1302 } 1323 1303 ··· 1329 1305 struct ov2740 *ov2740 = to_ov2740(sd); 1330 1306 int ret; 1331 1307 1332 - ret = clk_prepare_enable(ov2740->clk); 1308 + ret = regulator_bulk_enable(OV2740_NUM_SUPPLIES, ov2740->supplies); 1333 1309 if (ret) 1334 1310 return ret; 1335 1311 1312 + ret = clk_prepare_enable(ov2740->clk); 1313 + if (ret) { 1314 + regulator_bulk_disable(OV2740_NUM_SUPPLIES, ov2740->supplies); 1315 + return ret; 1316 + } 1317 + 1318 + gpiod_set_value_cansleep(ov2740->powerdown_gpio, 0); 1336 1319 gpiod_set_value_cansleep(ov2740->reset_gpio, 0); 1337 1320 msleep(20); 1338 1321 ··· 1351 1320 struct device *dev = &client->dev; 1352 1321 struct ov2740 *ov2740; 1353 1322 bool full_power; 1354 - int ret; 1323 + int i, ret; 1355 1324 1356 1325 ov2740 = devm_kzalloc(&client->dev, sizeof(*ov2740), GFP_KERNEL); 1357 1326 if (!ov2740) ··· 1368 1337 if (IS_ERR(ov2740->reset_gpio)) { 1369 1338 return dev_err_probe(dev, PTR_ERR(ov2740->reset_gpio), 1370 1339 "failed to get reset GPIO\n"); 1371 - } else if (ov2740->reset_gpio) { 1340 + } 1341 + 1342 + ov2740->powerdown_gpio = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH); 1343 + if (IS_ERR(ov2740->powerdown_gpio)) { 1344 + return dev_err_probe(dev, PTR_ERR(ov2740->powerdown_gpio), 1345 + "failed to get powerdown GPIO\n"); 1346 + } 1347 + 1348 + if (ov2740->reset_gpio || ov2740->powerdown_gpio) { 1372 1349 /* 1373 - * Ensure reset is asserted for at least 20 ms before 1350 + * Ensure reset/powerdown is asserted for at least 20 ms before 1374 1351 * ov2740_resume() deasserts it. 1375 1352 */ 1376 1353 msleep(20); ··· 1388 1349 if (IS_ERR(ov2740->clk)) 1389 1350 return dev_err_probe(dev, PTR_ERR(ov2740->clk), 1390 1351 "failed to get clock\n"); 1352 + 1353 + for (i = 0; i < OV2740_NUM_SUPPLIES; i++) 1354 + ov2740->supplies[i].supply = ov2740_supply_name[i]; 1355 + 1356 + ret = devm_regulator_bulk_get(dev, OV2740_NUM_SUPPLIES, ov2740->supplies); 1357 + if (ret) 1358 + return dev_err_probe(dev, ret, "failed to get regulators\n"); 1391 1359 1392 1360 full_power = acpi_dev_state_d0(&client->dev); 1393 1361 if (full_power) {
+1
drivers/media/i2c/ov5640.c
··· 1982 1982 light_freq = 50; 1983 1983 } else { 1984 1984 /* 60Hz */ 1985 + light_freq = 60; 1985 1986 } 1986 1987 } 1987 1988
+1 -1
drivers/media/i2c/ov9282.c
··· 40 40 /* Exposure control */ 41 41 #define OV9282_REG_EXPOSURE 0x3500 42 42 #define OV9282_EXPOSURE_MIN 1 43 - #define OV9282_EXPOSURE_OFFSET 12 43 + #define OV9282_EXPOSURE_OFFSET 25 44 44 #define OV9282_EXPOSURE_STEP 1 45 45 #define OV9282_EXPOSURE_DEFAULT 0x0282 46 46
-17
drivers/media/pci/b2c2/flexcop-dma.c
··· 123 123 return 0; 124 124 } 125 125 126 - int flexcop_dma_control_size_irq(struct flexcop_device *fc, 127 - flexcop_dma_index_t no, 128 - int onoff) 129 - { 130 - flexcop_ibi_value v = fc->read_ibi_reg(fc, ctrl_208); 131 - 132 - if (no & FC_DMA_1) 133 - v.ctrl_208.DMA1_IRQ_Enable_sig = onoff; 134 - 135 - if (no & FC_DMA_2) 136 - v.ctrl_208.DMA2_IRQ_Enable_sig = onoff; 137 - 138 - fc->write_ibi_reg(fc, ctrl_208, v); 139 - return 0; 140 - } 141 - EXPORT_SYMBOL(flexcop_dma_control_size_irq); 142 - 143 126 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, 144 127 flexcop_dma_index_t no, 145 128 int onoff)
-15
drivers/media/pci/cx18/cx18-gpio.c
··· 305 305 return v4l2_device_register_subdev(&cx->v4l2_dev, sd); 306 306 } 307 307 308 - void cx18_reset_ir_gpio(void *data) 309 - { 310 - struct cx18 *cx = to_cx18(data); 311 - 312 - if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0) 313 - return; 314 - 315 - CX18_DEBUG_INFO("Resetting IR microcontroller\n"); 316 - 317 - v4l2_subdev_call(&cx->sd_resetctrl, 318 - core, reset, CX18_GPIO_RESET_Z8F0811); 319 - } 320 - EXPORT_SYMBOL(cx18_reset_ir_gpio); 321 - /* This symbol is exported for use by lirc_pvr150 for the IR-blaster */ 322 - 323 308 /* Xceive tuner reset function */ 324 309 int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) 325 310 {
-1
drivers/media/pci/cx18/cx18-gpio.h
··· 17 17 CX18_GPIO_RESET_XC2028 = 2, 18 18 }; 19 19 20 - void cx18_reset_ir_gpio(void *data); 21 20 int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
+4 -4
drivers/media/pci/intel/ipu6/ipu6-buttress.c
··· 847 847 INIT_LIST_HEAD(&b->constraints); 848 848 849 849 isp->secure_mode = ipu6_buttress_get_secure_mode(isp); 850 - dev_info(&isp->pdev->dev, "IPU6 in %s mode touch 0x%x mask 0x%x\n", 851 - isp->secure_mode ? "secure" : "non-secure", 852 - readl(isp->base + BUTTRESS_REG_SECURITY_TOUCH), 853 - readl(isp->base + BUTTRESS_REG_CAMERA_MASK)); 850 + dev_dbg(&isp->pdev->dev, "IPU6 in %s mode touch 0x%x mask 0x%x\n", 851 + isp->secure_mode ? "secure" : "non-secure", 852 + readl(isp->base + BUTTRESS_REG_SECURITY_TOUCH), 853 + readl(isp->base + BUTTRESS_REG_CAMERA_MASK)); 854 854 855 855 b->wdt_cached_value = readl(isp->base + BUTTRESS_REG_WDT); 856 856 writel(BUTTRESS_IRQS, isp->base + BUTTRESS_REG_ISR_CLEAR);
+1 -1
drivers/media/pci/intel/ipu6/ipu6-cpd.c
··· 275 275 return -EINVAL; 276 276 } 277 277 278 - dev_info(&isp->pdev->dev, "FW version: %x\n", mod_hdr->fw_pkg_date); 278 + dev_dbg(&isp->pdev->dev, "FW version: %x\n", mod_hdr->fw_pkg_date); 279 279 ret = ipu6_cpd_validate_cpd(isp, moduledata + mod_hdr->hdr_len, 280 280 moduledata_size - mod_hdr->hdr_len, 281 281 moduledata_size);
+1
drivers/media/pci/intel/ipu6/ipu6-isys.c
··· 1133 1133 free_fw_msg_bufs: 1134 1134 free_fw_msg_bufs(isys); 1135 1135 out_remove_pkg_dir_shared_buffer: 1136 + cpu_latency_qos_remove_request(&isys->pm_qos); 1136 1137 if (!isp->secure_mode) 1137 1138 ipu6_cpd_free_pkg_dir(adev); 1138 1139 remove_shared_buffer:
+3 -1
drivers/media/pci/mgb4/mgb4_core.c
··· 40 40 #include "mgb4_trigger.h" 41 41 #include "mgb4_core.h" 42 42 43 - #define MGB4_USER_IRQS 16 43 + #define MGB4_USER_IRQS 16 44 + #define MGB4_MGB4_BAR_ID 0 45 + #define MGB4_XDMA_BAR_ID 1 44 46 45 47 #define DIGITEQ_VID 0x1ed8 46 48 #define T100_DID 0x0101
-3
drivers/media/pci/mgb4/mgb4_core.h
··· 18 18 #define MGB4_VIN_DEVICES 2 19 19 #define MGB4_VOUT_DEVICES 2 20 20 21 - #define MGB4_MGB4_BAR_ID 0 22 - #define MGB4_XDMA_BAR_ID 1 23 - 24 21 #define MGB4_IS_GMSL(mgbdev) \ 25 22 ((mgbdev)->module_version >> 4 == 2) 26 23 #define MGB4_IS_FPDL3(mgbdev) \
+6 -6
drivers/media/pci/mgb4/mgb4_sysfs_in.c
··· 333 333 struct video_device *vdev = to_video_device(dev); 334 334 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 335 335 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 336 - vindev->config->regs.signal); 336 + vindev->config->regs.hsync); 337 337 338 338 return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16); 339 339 } ··· 344 344 struct video_device *vdev = to_video_device(dev); 345 345 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 346 346 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 347 - vindev->config->regs.signal2); 347 + vindev->config->regs.vsync); 348 348 349 349 return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16); 350 350 } ··· 355 355 struct video_device *vdev = to_video_device(dev); 356 356 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 357 357 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 358 - vindev->config->regs.signal); 358 + vindev->config->regs.hsync); 359 359 360 360 return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8); 361 361 } ··· 366 366 struct video_device *vdev = to_video_device(dev); 367 367 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 368 368 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 369 - vindev->config->regs.signal); 369 + vindev->config->regs.hsync); 370 370 371 371 return sprintf(buf, "%u\n", (sig & 0x000000FF)); 372 372 } ··· 377 377 struct video_device *vdev = to_video_device(dev); 378 378 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 379 379 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 380 - vindev->config->regs.signal2); 380 + vindev->config->regs.vsync); 381 381 382 382 return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8); 383 383 } ··· 388 388 struct video_device *vdev = to_video_device(dev); 389 389 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 390 390 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 391 - vindev->config->regs.signal2); 391 + vindev->config->regs.vsync); 392 392 393 393 return sprintf(buf, "%u\n", (sig & 0x000000FF)); 394 394 }
+10 -10
drivers/media/pci/mgb4/mgb4_vin.c
··· 143 143 144 144 u32 status = mgb4_read_reg(video, regs->status); 145 145 u32 pclk = mgb4_read_reg(video, regs->pclk); 146 - u32 signal = mgb4_read_reg(video, regs->signal); 147 - u32 signal2 = mgb4_read_reg(video, regs->signal2); 146 + u32 hsync = mgb4_read_reg(video, regs->hsync); 147 + u32 vsync = mgb4_read_reg(video, regs->vsync); 148 148 u32 resolution = mgb4_read_reg(video, regs->resolution); 149 149 150 150 if (!(status & (1U << 2))) ··· 161 161 if (status & (1U << 13)) 162 162 timings->bt.polarities |= V4L2_DV_VSYNC_POS_POL; 163 163 timings->bt.pixelclock = pclk * 1000; 164 - timings->bt.hsync = (signal & 0x00FF0000) >> 16; 165 - timings->bt.vsync = (signal2 & 0x00FF0000) >> 16; 166 - timings->bt.hbackporch = (signal & 0x0000FF00) >> 8; 167 - timings->bt.hfrontporch = signal & 0x000000FF; 168 - timings->bt.vbackporch = (signal2 & 0x0000FF00) >> 8; 169 - timings->bt.vfrontporch = signal2 & 0x000000FF; 164 + timings->bt.hsync = (hsync & 0x00FF0000) >> 16; 165 + timings->bt.vsync = (vsync & 0x00FF0000) >> 16; 166 + timings->bt.hbackporch = (hsync & 0x0000FF00) >> 8; 167 + timings->bt.hfrontporch = hsync & 0x000000FF; 168 + timings->bt.vbackporch = (vsync & 0x0000FF00) >> 8; 169 + timings->bt.vfrontporch = vsync & 0x000000FF; 170 170 171 171 return 0; 172 172 } ··· 864 864 vindev->regs[5].name = "PCLK_FREQUENCY"; 865 865 vindev->regs[5].offset = vindev->config->regs.pclk; 866 866 vindev->regs[6].name = "VIDEO_PARAMS_1"; 867 - vindev->regs[6].offset = vindev->config->regs.signal; 867 + vindev->regs[6].offset = vindev->config->regs.hsync; 868 868 vindev->regs[7].name = "VIDEO_PARAMS_2"; 869 - vindev->regs[7].offset = vindev->config->regs.signal2; 869 + vindev->regs[7].offset = vindev->config->regs.vsync; 870 870 vindev->regs[8].name = "PADDING_PIXELS"; 871 871 vindev->regs[8].offset = vindev->config->regs.padding; 872 872 if (has_timeperframe(video)) {
+2 -2
drivers/media/pci/mgb4/mgb4_vin.h
··· 22 22 u32 frame_period; 23 23 u32 sync; 24 24 u32 pclk; 25 - u32 signal; 26 - u32 signal2; 25 + u32 hsync; 26 + u32 vsync; 27 27 u32 padding; 28 28 u32 timer; 29 29 };
+6 -8
drivers/media/pci/mgb4/mgb4_vout.c
··· 24 24 #include "mgb4_cmt.h" 25 25 #include "mgb4_vout.h" 26 26 27 - #define DEFAULT_WIDTH 1280 28 - #define DEFAULT_HEIGHT 640 29 - #define DEFAULT_PERIOD (MGB4_HW_FREQ / 60) 30 - 31 27 ATTRIBUTE_GROUPS(mgb4_fpdl3_out); 32 28 ATTRIBUTE_GROUPS(mgb4_gmsl_out); 33 29 ··· 176 180 177 181 xdma_disable_user_irq(mgbdev->xdev, irq); 178 182 cancel_work_sync(&voutdev->dma_work); 183 + 179 184 mgb4_mask_reg(&mgbdev->video, voutdev->config->regs.config, 0x2, 0x0); 185 + mgb4_write_reg(&mgbdev->video, voutdev->config->regs.padding, 0); 186 + 180 187 return_all_buffers(voutdev, VB2_BUF_STATE_ERROR); 181 188 } 182 189 ··· 195 196 int rv; 196 197 u32 addr; 197 198 199 + mgb4_write_reg(video, config->regs.padding, voutdev->padding); 198 200 mgb4_mask_reg(video, config->regs.config, 0x2, 0x2); 199 201 200 202 addr = mgb4_read_reg(video, config->regs.address); ··· 359 359 360 360 voutdev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width 361 361 * pixelsize)) / pixelsize; 362 - mgb4_write_reg(video, voutdev->config->regs.padding, voutdev->padding); 363 362 364 363 return 0; 365 364 } ··· 660 661 const struct mgb4_vout_regs *regs = &voutdev->config->regs; 661 662 662 663 mgb4_write_reg(video, regs->config, 0x00000011); 663 - mgb4_write_reg(video, regs->resolution, 664 - (DEFAULT_WIDTH << 16) | DEFAULT_HEIGHT); 664 + mgb4_write_reg(video, regs->resolution, (1280 << 16) | 640); 665 665 mgb4_write_reg(video, regs->hsync, 0x00283232); 666 666 mgb4_write_reg(video, regs->vsync, 0x40141F1E); 667 - mgb4_write_reg(video, regs->frame_limit, DEFAULT_PERIOD); 667 + mgb4_write_reg(video, regs->frame_limit, MGB4_HW_FREQ / 60); 668 668 mgb4_write_reg(video, regs->padding, 0x00000000); 669 669 670 670 voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, 61150 >> 1) << 1;
-2
drivers/media/pci/saa7164/saa7164-vbi.c
··· 77 77 /* TODO: NTSC SPECIFIC */ 78 78 /* Init and establish defaults */ 79 79 params->samplesperline = 1440; 80 - params->numberoflines = 12; 81 80 params->numberoflines = 18; 82 - params->pitch = 1600; 83 81 params->pitch = 1440; 84 82 params->numpagetables = 2 + 85 83 ((params->numberoflines * params->pitch) / PAGE_SIZE);
+2 -2
drivers/media/pci/solo6x10/solo6x10-core.c
··· 362 362 } 363 363 364 364 static ssize_t sdram_show(struct file *file, struct kobject *kobj, 365 - struct bin_attribute *a, char *buf, 365 + const struct bin_attribute *a, char *buf, 366 366 loff_t off, size_t count) 367 367 { 368 368 struct device *dev = kobj_to_dev(kobj); ··· 432 432 sysfs_attr_init(&sdram_attr->attr); 433 433 sdram_attr->attr.name = "sdram"; 434 434 sdram_attr->attr.mode = 0440; 435 - sdram_attr->read = sdram_show; 435 + sdram_attr->read_new = sdram_show; 436 436 sdram_attr->size = solo_dev->sdram_size; 437 437 438 438 if (device_create_bin_file(dev, sdram_attr)) {
+31 -11
drivers/media/platform/broadcom/bcm2835-unicam.c
··· 199 199 /* subdevice async notifier */ 200 200 struct v4l2_async_notifier notifier; 201 201 unsigned int sequence; 202 + bool frame_started; 202 203 203 204 /* Sensor node */ 204 205 struct { ··· 547 546 } 548 547 549 548 for (i = 0; i < num_formats; ++i) { 550 - if (formats[i].fourcc == fourcc) 549 + if (formats[i].fourcc == fourcc || 550 + formats[i].unpacked_fourcc == fourcc) 551 551 return &formats[i]; 552 552 } 553 553 ··· 640 638 static void unicam_wr_dma_addr(struct unicam_node *node, 641 639 struct unicam_buffer *buf) 642 640 { 643 - dma_addr_t endaddr = buf->dma_addr + buf->size; 641 + /* 642 + * Due to a HW bug causing buffer overruns in circular buffer mode under 643 + * certain (not yet fully known) conditions, the dummy buffer allocation 644 + * is set to a a single page size, but the hardware gets programmed with 645 + * a buffer size of 0. 646 + */ 647 + dma_addr_t endaddr = buf->dma_addr + 648 + (buf != &node->dummy_buf ? buf->size : 0); 644 649 645 650 if (node->id == UNICAM_IMAGE_NODE) { 646 651 unicam_reg_write(node->dev, UNICAM_IBSA0, buf->dma_addr); ··· 751 742 * buffer forever. 752 743 */ 753 744 if (fe) { 745 + bool inc_seq = unicam->frame_started; 746 + 754 747 /* 755 748 * Ensure we have swapped buffers already as we can't 756 749 * stop the peripheral. If no buffer is available, use a ··· 772 761 * + FS + LS). In this case, we cannot signal the buffer 773 762 * as complete, as the HW will reuse that buffer. 774 763 */ 775 - if (node->cur_frm && node->cur_frm != node->next_frm) 764 + if (node->cur_frm && node->cur_frm != node->next_frm) { 776 765 unicam_process_buffer_complete(node, sequence); 766 + inc_seq = true; 767 + } 777 768 node->cur_frm = node->next_frm; 778 769 } 779 - unicam->sequence++; 770 + 771 + /* 772 + * Increment the sequence number conditionally on either a FS 773 + * having already occurred, or in the FE + FS condition as 774 + * caught in the FE handler above. This ensures the sequence 775 + * number corresponds to the frames generated by the sensor, not 776 + * the frames dequeued to userland. 777 + */ 778 + if (inc_seq) { 779 + unicam->sequence++; 780 + unicam->frame_started = false; 781 + } 780 782 } 781 783 782 784 if (ista & UNICAM_FSI) { ··· 819 795 } 820 796 821 797 unicam_queue_event_sof(unicam); 798 + unicam->frame_started = true; 822 799 } 823 800 824 801 /* ··· 841 816 } 842 817 } 843 818 844 - if (unicam_reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) { 845 - /* Switch out of trigger mode if selected */ 846 - unicam_reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC); 847 - unicam_reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM); 848 - } 849 819 return IRQ_HANDLED; 850 820 } 851 821 ··· 1004 984 1005 985 unicam_reg_write_field(unicam, UNICAM_ANA, 0, UNICAM_DDL); 1006 986 1007 - /* Always start in trigger frame capture mode (UNICAM_FCM set) */ 1008 - val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB; 987 + val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_IBOB; 1009 988 line_int_freq = max(fmt->height >> 2, 128); 1010 989 unicam_set_field(&val, line_int_freq, UNICAM_LCIE_MASK); 1011 990 unicam_reg_write(unicam, UNICAM_ICTL, val); ··· 1432 1413 if (unicam->pipe.nodes & BIT(UNICAM_METADATA_NODE)) 1433 1414 unicam_start_metadata(unicam); 1434 1415 1416 + unicam->frame_started = false; 1435 1417 unicam_start_rx(unicam, state); 1436 1418 } 1437 1419
+6 -1
drivers/media/platform/marvell/mcam-core.c
··· 935 935 ret = pm_runtime_resume_and_get(cam->dev); 936 936 if (ret < 0) 937 937 return ret; 938 - clk_enable(cam->clk[0]); 938 + ret = clk_enable(cam->clk[0]); 939 + if (ret) { 940 + pm_runtime_put(cam->dev); 941 + return ret; 942 + } 943 + 939 944 mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); 940 945 mcam_ctlr_power_up(cam); 941 946
+17 -4
drivers/media/platform/marvell/mmp-driver.c
··· 232 232 mcam_init_clk(mcam); 233 233 234 234 /* 235 + * Register with V4L. 236 + */ 237 + 238 + ret = v4l2_device_register(mcam->dev, &mcam->v4l2_dev); 239 + if (ret) 240 + return ret; 241 + 242 + /* 235 243 * Create a match of the sensor against its OF node. 236 244 */ 237 245 ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(pdev->dev.of_node), 238 246 NULL); 239 - if (!ep) 240 - return -ENODEV; 247 + if (!ep) { 248 + ret = -ENODEV; 249 + goto out_v4l2_device_unregister; 250 + } 241 251 242 252 v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev); 243 253 ··· 256 246 fwnode_handle_put(ep); 257 247 if (IS_ERR(asd)) { 258 248 ret = PTR_ERR(asd); 259 - goto out; 249 + goto out_v4l2_device_unregister; 260 250 } 261 251 262 252 /* ··· 264 254 */ 265 255 ret = mccic_register(mcam); 266 256 if (ret) 267 - goto out; 257 + goto out_v4l2_device_unregister; 268 258 269 259 /* 270 260 * Add OF clock provider. ··· 293 283 return 0; 294 284 out: 295 285 mccic_shutdown(mcam); 286 + out_v4l2_device_unregister: 287 + v4l2_device_unregister(&mcam->v4l2_dev); 296 288 297 289 return ret; 298 290 } ··· 305 293 struct mcam_camera *mcam = &cam->mcam; 306 294 307 295 mccic_shutdown(mcam); 296 + v4l2_device_unregister(&mcam->v4l2_dev); 308 297 pm_runtime_force_suspend(mcam->dev); 309 298 } 310 299
+15 -62
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
··· 114 114 if (pp_idx >= mdp->mdp_data->pp_used) 115 115 goto err_param; 116 116 117 - if (CFG_CHECK(MT8183, p_id)) 117 + if (CFG_CHECK(MT8183, p_id)) { 118 118 cfg_c = CFG_OFST(MT8183, param->config, pp_idx); 119 - else if (CFG_CHECK(MT8195, p_id)) 120 - cfg_c = CFG_OFST(MT8195, param->config, pp_idx); 121 - else 122 - goto err_param; 123 - 124 - if (CFG_CHECK(MT8183, p_id)) 125 119 cfg_n = CFG_OFST(MT8183, param->config, pp_idx + 1); 126 - else if (CFG_CHECK(MT8195, p_id)) 120 + } else if (CFG_CHECK(MT8195, p_id)) { 121 + cfg_c = CFG_OFST(MT8195, param->config, pp_idx); 127 122 cfg_n = CFG_OFST(MT8195, param->config, pp_idx + 1); 128 - else 123 + } else { 129 124 goto err_param; 125 + } 130 126 131 127 if ((long)cfg_n - (long)mdp->vpu.config > bound) { 132 128 dev_err(dev, "config offset %ld OOB %ld\n", (long)cfg_n, bound); ··· 321 325 /* Enable mux settings */ 322 326 for (index = 0; index < ctrl->num_sets; index++) { 323 327 set = &ctrl->sets[index]; 324 - cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg, 325 - set->value, 0xFFFFFFFF); 328 + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, set->value); 326 329 } 327 330 /* Config sub-frame information */ 328 331 for (index = (num_comp - 1); index >= 0; index--) { ··· 376 381 /* Disable mux settings */ 377 382 for (index = 0; index < ctrl->num_sets; index++) { 378 383 set = &ctrl->sets[index]; 379 - cmdq_pkt_write_mask(&cmd->pkt, set->subsys_id, set->reg, 380 - 0, 0xFFFFFFFF); 384 + cmdq_pkt_write(&cmd->pkt, set->subsys_id, set->reg, 0); 381 385 } 382 386 383 387 return 0; ··· 465 471 return 0; 466 472 } 467 473 468 - static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, 469 - size_t size) 470 - { 471 - struct device *dev; 472 - dma_addr_t dma_addr; 473 - 474 - pkt->va_base = kzalloc(size, GFP_KERNEL); 475 - if (!pkt->va_base) 476 - return -ENOMEM; 477 - 478 - pkt->buf_size = size; 479 - pkt->cl = (void *)client; 480 - 481 - dev = client->chan->mbox->dev; 482 - dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size, 483 - DMA_TO_DEVICE); 484 - if (dma_mapping_error(dev, dma_addr)) { 485 - dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); 486 - kfree(pkt->va_base); 487 - return -ENOMEM; 488 - } 489 - 490 - pkt->pa_base = dma_addr; 491 - 492 - return 0; 493 - } 494 - 495 - static void mdp_cmdq_pkt_destroy(struct cmdq_pkt *pkt) 496 - { 497 - struct cmdq_client *client = (struct cmdq_client *)pkt->cl; 498 - 499 - dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size, 500 - DMA_TO_DEVICE); 501 - kfree(pkt->va_base); 502 - pkt->va_base = NULL; 503 - } 504 - 505 474 static void mdp_auto_release_work(struct work_struct *work) 506 475 { 507 476 struct mdp_cmdq_cmd *cmd; ··· 495 538 wake_up(&mdp->callback_wq); 496 539 } 497 540 498 - mdp_cmdq_pkt_destroy(&cmd->pkt); 541 + cmdq_pkt_destroy(mdp->cmdq_clt[cmd->pp_idx], &cmd->pkt); 499 542 kfree(cmd->comps); 500 543 cmd->comps = NULL; 501 544 kfree(cmd); ··· 535 578 if (refcount_dec_and_test(&mdp->job_count)) 536 579 wake_up(&mdp->callback_wq); 537 580 538 - mdp_cmdq_pkt_destroy(&cmd->pkt); 581 + cmdq_pkt_destroy(mdp->cmdq_clt[cmd->pp_idx], &cmd->pkt); 539 582 kfree(cmd->comps); 540 583 cmd->comps = NULL; 541 584 kfree(cmd); ··· 564 607 goto err_uninit; 565 608 } 566 609 567 - if (CFG_CHECK(MT8183, p_id)) 568 - num_comp = CFG_GET(MT8183, config, num_components); 569 - else if (CFG_CHECK(MT8195, p_id)) 570 - num_comp = CFG_GET(MT8195, config, num_components); 571 - else 572 - goto err_uninit; 573 - 574 610 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 575 611 if (!cmd) { 576 612 ret = -ENOMEM; 577 613 goto err_uninit; 578 614 } 579 615 580 - ret = mdp_cmdq_pkt_create(mdp->cmdq_clt[pp_idx], &cmd->pkt, SZ_16K); 616 + ret = cmdq_pkt_create(mdp->cmdq_clt[pp_idx], &cmd->pkt, SZ_16K); 581 617 if (ret) 582 618 goto err_free_cmd; 583 619 ··· 582 632 ret = -EINVAL; 583 633 goto err_destroy_pkt; 584 634 } 635 + 585 636 comps = kcalloc(num_comp, sizeof(*comps), GFP_KERNEL); 586 637 if (!comps) { 587 638 ret = -ENOMEM; ··· 627 676 dev_err(dev, "mdp_path_config error %d\n", pp_idx); 628 677 goto err_free_path; 629 678 } 630 - cmdq_pkt_finalize(&cmd->pkt); 679 + cmdq_pkt_eoc(&cmd->pkt); 680 + cmdq_pkt_jump_rel(&cmd->pkt, CMDQ_INST_SIZE, mdp->cmdq_shift_pa[pp_idx]); 631 681 632 682 for (i = 0; i < num_comp; i++) { 633 683 s32 inner_id = MDP_COMP_NONE; ··· 651 699 cmd->comps = comps; 652 700 cmd->num_comps = num_comp; 653 701 cmd->mdp_ctx = param->mdp_ctx; 702 + cmd->pp_idx = pp_idx; 654 703 655 704 kfree(path); 656 705 return cmd; ··· 663 710 err_free_comps: 664 711 kfree(comps); 665 712 err_destroy_pkt: 666 - mdp_cmdq_pkt_destroy(&cmd->pkt); 713 + cmdq_pkt_destroy(mdp->cmdq_clt[pp_idx], &cmd->pkt); 667 714 err_free_cmd: 668 715 kfree(cmd); 669 716 err_uninit:
+1
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.h
··· 35 35 struct mdp_comp *comps; 36 36 void *mdp_ctx; 37 37 u8 num_comps; 38 + u8 pp_idx; 38 39 }; 39 40 40 41 struct mdp_dev;
+238 -299
drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
··· 72 72 73 73 /* Disable RSZ1 */ 74 74 if (ctx->comp->inner_id == rdma0 && prz1) 75 - MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE, 76 - 0x0, BIT(0)); 75 + MM_REG_WRITE_MASK(cmd, subsys_id, prz1->reg_base, 76 + PRZ_ENABLE, 0x0, BIT(0)); 77 77 } 78 78 79 79 /* Reset RDMA */ 80 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0)); 81 - MM_REG_POLL(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8)); 82 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0)); 80 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, BIT(0), BIT(0)); 81 + MM_REG_POLL_MASK(cmd, subsys_id, base, MDP_RDMA_MON_STA_1, BIT(8), BIT(8)); 82 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_RESET, 0x0, BIT(0)); 83 83 return 0; 84 84 } 85 85 ··· 98 98 99 99 if (mdp_cfg && mdp_cfg->rdma_support_10bit) { 100 100 if (block10bit) 101 - MM_REG_WRITE(cmd, subsys_id, base, 102 - MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7); 101 + MM_REG_WRITE_MASK(cmd, subsys_id, base, 102 + MDP_RDMA_RESV_DUMMY_0, 0x7, 0x7); 103 103 else 104 - MM_REG_WRITE(cmd, subsys_id, base, 105 - MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7); 104 + MM_REG_WRITE_MASK(cmd, subsys_id, base, 105 + MDP_RDMA_RESV_DUMMY_0, 0x0, 0x7); 106 106 } 107 107 108 108 /* Setup smi control */ 109 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON, 110 - (7 << 4) + //burst type to 8 111 - (1 << 16), //enable pre-ultra 112 - 0x00030071); 109 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_GMCIF_CON, 110 + (7 << 4) + //burst type to 8 111 + (1 << 16), //enable pre-ultra 112 + 0x00030071); 113 113 114 114 /* Setup source frame info */ 115 115 if (CFG_CHECK(MT8183, p_id)) 116 116 reg = CFG_COMP(MT8183, ctx->param, rdma.src_ctrl); 117 117 else if (CFG_CHECK(MT8195, p_id)) 118 118 reg = CFG_COMP(MT8195, ctx->param, rdma.src_ctrl); 119 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg, 120 - 0x03C8FE0F); 119 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_SRC_CON, reg, 0x03C8FE0F); 121 120 122 121 if (mdp_cfg) 123 122 if (mdp_cfg->rdma_support_10bit && en_ufo) { ··· 125 126 reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_y); 126 127 else if (CFG_CHECK(MT8195, p_id)) 127 128 reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_y); 128 - MM_REG_WRITE(cmd, subsys_id, 129 - base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y, 130 - reg, 0xFFFFFFFF); 129 + MM_REG_WRITE(cmd, subsys_id, base, 130 + MDP_RDMA_UFO_DEC_LENGTH_BASE_Y, reg); 131 131 132 132 if (CFG_CHECK(MT8183, p_id)) 133 133 reg = CFG_COMP(MT8183, ctx->param, rdma.ufo_dec_c); 134 134 else if (CFG_CHECK(MT8195, p_id)) 135 135 reg = CFG_COMP(MT8195, ctx->param, rdma.ufo_dec_c); 136 - MM_REG_WRITE(cmd, subsys_id, 137 - base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C, 138 - reg, 0xFFFFFFFF); 136 + MM_REG_WRITE(cmd, subsys_id, base, 137 + MDP_RDMA_UFO_DEC_LENGTH_BASE_C, reg); 139 138 140 139 /* Set 10bit source frame pitch */ 141 140 if (block10bit) { ··· 141 144 reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd_in_pxl); 142 145 else if (CFG_CHECK(MT8195, p_id)) 143 146 reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd_in_pxl); 144 - MM_REG_WRITE(cmd, subsys_id, 145 - base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL, 146 - reg, 0x001FFFFF); 147 + MM_REG_WRITE_MASK(cmd, subsys_id, base, 148 + MDP_RDMA_MF_BKGD_SIZE_IN_PXL, 149 + reg, 0x001FFFFF); 147 150 } 148 151 } 149 152 ··· 154 157 reg = CFG_COMP(MT8195, ctx->param, rdma.control); 155 158 rdma_con_mask = 0x1130; 156 159 } 157 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, reg, 158 - rdma_con_mask); 160 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_CON, reg, rdma_con_mask); 159 161 160 162 /* Setup source buffer base */ 161 163 if (CFG_CHECK(MT8183, p_id)) 162 164 reg = CFG_COMP(MT8183, ctx->param, rdma.iova[0]); 163 165 else if (CFG_CHECK(MT8195, p_id)) 164 166 reg = CFG_COMP(MT8195, ctx->param, rdma.iova[0]); 165 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg, 166 - 0xFFFFFFFF); 167 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, reg); 167 168 168 169 if (CFG_CHECK(MT8183, p_id)) 169 170 reg = CFG_COMP(MT8183, ctx->param, rdma.iova[1]); 170 171 else if (CFG_CHECK(MT8195, p_id)) 171 172 reg = CFG_COMP(MT8195, ctx->param, rdma.iova[1]); 172 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg, 173 - 0xFFFFFFFF); 173 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_1, reg); 174 174 175 175 if (CFG_CHECK(MT8183, p_id)) 176 176 reg = CFG_COMP(MT8183, ctx->param, rdma.iova[2]); 177 177 else if (CFG_CHECK(MT8195, p_id)) 178 178 reg = CFG_COMP(MT8195, ctx->param, rdma.iova[2]); 179 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg, 180 - 0xFFFFFFFF); 179 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_2, reg); 181 180 182 181 /* Setup source buffer end */ 183 182 if (CFG_CHECK(MT8183, p_id)) 184 183 reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[0]); 185 184 else if (CFG_CHECK(MT8195, p_id)) 186 185 reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[0]); 187 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0, 188 - reg, 0xFFFFFFFF); 186 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_0, reg); 189 187 190 188 if (CFG_CHECK(MT8183, p_id)) 191 189 reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[1]); 192 190 else if (CFG_CHECK(MT8195, p_id)) 193 191 reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[1]); 194 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1, 195 - reg, 0xFFFFFFFF); 192 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_1, reg); 196 193 197 194 if (CFG_CHECK(MT8183, p_id)) 198 195 reg = CFG_COMP(MT8183, ctx->param, rdma.iova_end[2]); 199 196 else if (CFG_CHECK(MT8195, p_id)) 200 197 reg = CFG_COMP(MT8195, ctx->param, rdma.iova_end[2]); 201 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2, 202 - reg, 0xFFFFFFFF); 198 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_END_2, reg); 203 199 204 200 /* Setup source frame pitch */ 205 201 if (CFG_CHECK(MT8183, p_id)) 206 202 reg = CFG_COMP(MT8183, ctx->param, rdma.mf_bkgd); 207 203 else if (CFG_CHECK(MT8195, p_id)) 208 204 reg = CFG_COMP(MT8195, ctx->param, rdma.mf_bkgd); 209 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, 210 - reg, 0x001FFFFF); 205 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, 206 + reg, 0x001FFFFF); 211 207 212 208 if (CFG_CHECK(MT8183, p_id)) 213 209 reg = CFG_COMP(MT8183, ctx->param, rdma.sf_bkgd); 214 210 else if (CFG_CHECK(MT8195, p_id)) 215 211 reg = CFG_COMP(MT8195, ctx->param, rdma.sf_bkgd); 216 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE, 217 - reg, 0x001FFFFF); 212 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_SF_BKGD_SIZE_IN_BYTE, 213 + reg, 0x001FFFFF); 218 214 219 215 /* Setup color transform */ 220 216 if (CFG_CHECK(MT8183, p_id)) 221 217 reg = CFG_COMP(MT8183, ctx->param, rdma.transform); 222 218 else if (CFG_CHECK(MT8195, p_id)) 223 219 reg = CFG_COMP(MT8195, ctx->param, rdma.transform); 224 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0, 225 - reg, 0x0F110000); 220 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0, 221 + reg, 0x0F110000); 226 222 227 223 if (!mdp_cfg || !mdp_cfg->rdma_esl_setting) 228 224 goto rdma_config_done; 229 225 230 226 if (CFG_CHECK(MT8195, p_id)) 231 227 reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con0); 232 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0, 233 - reg, 0x0FFF00FF); 228 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0, 229 + reg, 0x0FFF00FF); 234 230 235 231 if (CFG_CHECK(MT8195, p_id)) 236 232 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con0); 237 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0, 238 - reg, 0x3FFFFFFF); 233 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0, 234 + reg, 0x3FFFFFFF); 239 235 240 236 if (CFG_CHECK(MT8195, p_id)) 241 237 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con0); 242 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0, 243 - reg, 0x3FFFFFFF); 238 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0, 239 + reg, 0x3FFFFFFF); 244 240 245 241 if (CFG_CHECK(MT8195, p_id)) 246 242 reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con1); 247 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1, 248 - reg, 0x0F7F007F); 243 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1, 244 + reg, 0x0F7F007F); 249 245 250 246 if (CFG_CHECK(MT8195, p_id)) 251 247 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con1); 252 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1, 253 - reg, 0x3FFFFFFF); 248 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1, 249 + reg, 0x3FFFFFFF); 254 250 255 251 if (CFG_CHECK(MT8195, p_id)) 256 252 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con1); 257 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1, 258 - reg, 0x3FFFFFFF); 253 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1, 254 + reg, 0x3FFFFFFF); 259 255 260 256 if (CFG_CHECK(MT8195, p_id)) 261 257 reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con2); 262 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2, 263 - reg, 0x0F3F003F); 258 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2, 259 + reg, 0x0F3F003F); 264 260 265 261 if (CFG_CHECK(MT8195, p_id)) 266 262 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_high_con2); 267 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2, 268 - reg, 0x3FFFFFFF); 263 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2, 264 + reg, 0x3FFFFFFF); 269 265 270 266 if (CFG_CHECK(MT8195, p_id)) 271 267 reg = CFG_COMP(MT8195, ctx->param, rdma.ultra_th_low_con2); 272 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2, 273 - reg, 0x3FFFFFFF); 268 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2, 269 + reg, 0x3FFFFFFF); 274 270 275 271 if (CFG_CHECK(MT8195, p_id)) 276 272 reg = CFG_COMP(MT8195, ctx->param, rdma.dmabuf_con3); 277 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3, 278 - reg, 0x0F3F003F); 273 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3, 274 + reg, 0x0F3F003F); 279 275 280 276 rdma_config_done: 281 277 return 0; ··· 287 297 u32 reg = 0; 288 298 289 299 /* Enable RDMA */ 290 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0)); 300 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0)); 291 301 292 302 /* Set Y pixel offset */ 293 303 if (CFG_CHECK(MT8183, p_id)) 294 304 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[0]); 295 305 else if (CFG_CHECK(MT8195, p_id)) 296 306 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[0]); 297 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0, 298 - reg, 0xFFFFFFFF); 307 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0, reg); 299 308 300 309 /* Set 10bit UFO mode */ 301 310 if (mdp_cfg) { ··· 304 315 else if (CFG_CHECK(MT8195, p_id)) 305 316 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset_0_p); 306 317 MM_REG_WRITE(cmd, subsys_id, base, 307 - MDP_RDMA_SRC_OFFSET_0_P, 308 - reg, 0xFFFFFFFF); 318 + MDP_RDMA_SRC_OFFSET_0_P, reg); 309 319 } 310 320 } 311 321 ··· 313 325 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[1]); 314 326 else if (CFG_CHECK(MT8195, p_id)) 315 327 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[1]); 316 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1, 317 - reg, 0xFFFFFFFF); 328 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_1, reg); 318 329 319 330 /* Set V pixel offset */ 320 331 if (CFG_CHECK(MT8183, p_id)) 321 332 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].offset[2]); 322 333 else if (CFG_CHECK(MT8195, p_id)) 323 334 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].offset[2]); 324 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2, 325 - reg, 0xFFFFFFFF); 335 + MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_2, reg); 326 336 327 337 /* Set source size */ 328 338 if (CFG_CHECK(MT8183, p_id)) 329 339 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].src); 330 340 else if (CFG_CHECK(MT8195, p_id)) 331 341 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].src); 332 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg, 333 - 0x1FFF1FFF); 342 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_SRC_SIZE, reg, 343 + 0x1FFF1FFF); 334 344 335 345 /* Set target size */ 336 346 if (CFG_CHECK(MT8183, p_id)) 337 347 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip); 338 348 else if (CFG_CHECK(MT8195, p_id)) 339 349 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip); 340 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE, 341 - reg, 0x1FFF1FFF); 350 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_CLIP_SIZE, 351 + reg, 0x1FFF1FFF); 342 352 343 353 /* Set crop offset */ 344 354 if (CFG_CHECK(MT8183, p_id)) 345 355 reg = CFG_COMP(MT8183, ctx->param, rdma.subfrms[index].clip_ofst); 346 356 else if (CFG_CHECK(MT8195, p_id)) 347 357 reg = CFG_COMP(MT8195, ctx->param, rdma.subfrms[index].clip_ofst); 348 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1, 349 - reg, 0x003F001F); 358 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_MF_OFFSET_1, 359 + reg, 0x003F001F); 350 360 351 361 if (CFG_CHECK(MT8183, p_id)) { 352 362 csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); ··· 355 369 } 356 370 if (mdp_cfg && mdp_cfg->rdma_upsample_repeat_only) 357 371 if ((csf_r - csf_l + 1) > 320) 358 - MM_REG_WRITE(cmd, subsys_id, base, 359 - MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2)); 372 + MM_REG_WRITE_MASK(cmd, subsys_id, base, 373 + MDP_RDMA_RESV_DUMMY_0, BIT(2), BIT(2)); 360 374 361 375 return 0; 362 376 } ··· 379 393 MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); 380 394 381 395 /* Disable RDMA */ 382 - MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0)); 396 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0)); 383 397 return 0; 384 398 } 385 399 ··· 397 411 u8 subsys_id = ctx->comp->subsys_id; 398 412 399 413 /* Reset RSZ */ 400 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16)); 401 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16)); 414 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16)); 415 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16)); 402 416 /* Enable RSZ */ 403 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0)); 417 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0)); 404 418 405 419 if (CFG_CHECK(MT8195, p_id)) { 406 420 struct device *dev; ··· 423 437 u32 reg = 0; 424 438 425 439 if (mdp_cfg && mdp_cfg->rsz_etc_control) 426 - MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0, 0xFFFFFFFF); 440 + MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0); 427 441 428 442 if (CFG_CHECK(MT8183, p_id)) 429 443 bypass = CFG_COMP(MT8183, ctx->param, frame.bypass); ··· 432 446 433 447 if (bypass) { 434 448 /* Disable RSZ */ 435 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0)); 449 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0)); 436 450 return 0; 437 451 } 438 452 ··· 440 454 reg = CFG_COMP(MT8183, ctx->param, rsz.control1); 441 455 else if (CFG_CHECK(MT8195, p_id)) 442 456 reg = CFG_COMP(MT8195, ctx->param, rsz.control1); 443 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, reg, 444 - 0x03FFFDF3); 457 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, reg, 0x03FFFDF3); 445 458 446 459 if (CFG_CHECK(MT8183, p_id)) 447 460 reg = CFG_COMP(MT8183, ctx->param, rsz.control2); 448 461 else if (CFG_CHECK(MT8195, p_id)) 449 462 reg = CFG_COMP(MT8195, ctx->param, rsz.control2); 450 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 451 - 0x0FFFC290); 463 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x0FFFC290); 452 464 453 465 if (CFG_CHECK(MT8183, p_id)) 454 466 reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_x); 455 467 else if (CFG_CHECK(MT8195, p_id)) 456 468 reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_x); 457 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP, 458 - reg, 0x007FFFFF); 469 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_HORIZONTAL_COEFF_STEP, reg, 470 + 0x007FFFFF); 459 471 460 472 if (CFG_CHECK(MT8183, p_id)) 461 473 reg = CFG_COMP(MT8183, ctx->param, rsz.coeff_step_y); 462 474 else if (CFG_CHECK(MT8195, p_id)) 463 475 reg = CFG_COMP(MT8195, ctx->param, rsz.coeff_step_y); 464 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP, 465 - reg, 0x007FFFFF); 476 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_VERTICAL_COEFF_STEP, reg, 477 + 0x007FFFFF); 466 478 467 479 return 0; 468 480 } ··· 479 495 reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].control2); 480 496 else if (CFG_CHECK(MT8195, p_id)) 481 497 reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].control2); 482 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 483 - 0x00003800); 498 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_2, reg, 0x00003800); 484 499 485 500 if (CFG_CHECK(MT8183, p_id)) 486 501 reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].src); 487 502 else if (CFG_CHECK(MT8195, p_id)) 488 503 reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].src); 489 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg, 490 - 0xFFFFFFFF); 504 + MM_REG_WRITE(cmd, subsys_id, base, PRZ_INPUT_IMAGE, reg); 491 505 492 506 if (CFG_CHECK(MT8183, p_id)) { 493 507 csf_l = CFG_COMP(MT8183, ctx->param, subfrms[index].in.left); ··· 496 514 } 497 515 if (mdp_cfg && mdp_cfg->rsz_disable_dcm_small_sample) 498 516 if ((csf_r - csf_l + 1) <= 16) 499 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 500 - BIT(27), BIT(27)); 517 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, 518 + BIT(27), BIT(27)); 501 519 502 520 if (CFG_CHECK(MT8183, p_id)) 503 521 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left); 504 522 else if (CFG_CHECK(MT8195, p_id)) 505 523 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left); 506 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET, 507 - reg, 0xFFFF); 524 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_INTEGER_OFFSET, 525 + reg, 0xFFFF); 508 526 509 527 if (CFG_CHECK(MT8183, p_id)) 510 528 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.left_subpix); 511 529 else if (CFG_CHECK(MT8195, p_id)) 512 530 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.left_subpix); 513 - MM_REG_WRITE(cmd, subsys_id, 514 - base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET, 515 - reg, 0x1FFFFF); 531 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_HORIZONTAL_SUBPIXEL_OFFSET, 532 + reg, 0x1FFFFF); 516 533 517 534 if (CFG_CHECK(MT8183, p_id)) 518 535 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top); 519 536 else if (CFG_CHECK(MT8195, p_id)) 520 537 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top); 521 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET, 522 - reg, 0xFFFF); 538 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_INTEGER_OFFSET, 539 + reg, 0xFFFF); 523 540 524 541 if (CFG_CHECK(MT8183, p_id)) 525 542 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].luma.top_subpix); 526 543 else if (CFG_CHECK(MT8195, p_id)) 527 544 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].luma.top_subpix); 528 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET, 529 - reg, 0x1FFFFF); 545 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET, 546 + reg, 0x1FFFFF); 530 547 531 548 if (CFG_CHECK(MT8183, p_id)) 532 549 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left); 533 550 else if (CFG_CHECK(MT8195, p_id)) 534 551 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left); 535 - MM_REG_WRITE(cmd, subsys_id, 536 - base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET, 537 - reg, 0xFFFF); 552 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET, 553 + reg, 0xFFFF); 538 554 539 555 if (CFG_CHECK(MT8183, p_id)) 540 556 reg = CFG_COMP(MT8183, ctx->param, subfrms[index].chroma.left_subpix); 541 557 else if (CFG_CHECK(MT8195, p_id)) 542 558 reg = CFG_COMP(MT8195, ctx->param, subfrms[index].chroma.left_subpix); 543 - MM_REG_WRITE(cmd, subsys_id, 544 - base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET, 545 - reg, 0x1FFFFF); 559 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET, 560 + reg, 0x1FFFFF); 546 561 547 562 if (CFG_CHECK(MT8183, p_id)) 548 563 reg = CFG_COMP(MT8183, ctx->param, rsz.subfrms[index].clip); 549 564 else if (CFG_CHECK(MT8195, p_id)) 550 565 reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].clip); 551 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg, 552 - 0xFFFFFFFF); 566 + MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, reg); 553 567 554 568 if (CFG_CHECK(MT8195, p_id)) { 555 569 struct device *dev; ··· 574 596 if (CFG_CHECK(MT8195, p_id)) 575 597 reg = CFG_COMP(MT8195, ctx->param, rsz.subfrms[index].merge_cfg); 576 598 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 577 - MDP_MERGE_CFG_0, reg, 0xFFFFFFFF); 599 + MDP_MERGE_CFG_0, reg); 578 600 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 579 - MDP_MERGE_CFG_4, reg, 0xFFFFFFFF); 601 + MDP_MERGE_CFG_4, reg); 580 602 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 581 - MDP_MERGE_CFG_24, reg, 0xFFFFFFFF); 603 + MDP_MERGE_CFG_24, reg); 582 604 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 583 - MDP_MERGE_CFG_25, reg, 0xFFFFFFFF); 605 + MDP_MERGE_CFG_25, reg); 584 606 585 607 /* Bypass mode */ 586 608 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 587 - MDP_MERGE_CFG_12, BIT(0), 0xFFFFFFFF); 609 + MDP_MERGE_CFG_12, BIT(0)); 588 610 MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base, 589 - MDP_MERGE_ENABLE, BIT(0), 0xFFFFFFFF); 611 + MDP_MERGE_ENABLE, BIT(0)); 590 612 } 591 613 592 614 rsz_subfrm_done: ··· 612 634 } 613 635 614 636 if ((csf_r - csf_l + 1) <= 16) 615 - MM_REG_WRITE(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0, 616 - BIT(27)); 637 + MM_REG_WRITE_MASK(cmd, subsys_id, base, PRZ_CONTROL_1, 0x0, 638 + BIT(27)); 617 639 } 618 640 619 641 return 0; ··· 633 655 u8 subsys_id = ctx->comp->subsys_id; 634 656 635 657 /* Reset WROT */ 636 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); 637 - MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); 658 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0)); 659 + MM_REG_POLL_MASK(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0)); 638 660 639 661 /* Reset setting */ 640 662 if (CFG_CHECK(MT8195, p_id)) 641 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0, 0xFFFFFFFF); 663 + MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0); 642 664 643 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); 644 - MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); 665 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0)); 666 + MM_REG_POLL_MASK(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0)); 645 667 return 0; 646 668 } 647 669 ··· 659 681 reg = CFG_COMP(MT8183, ctx->param, wrot.iova[0]); 660 682 else if (CFG_CHECK(MT8195, p_id)) 661 683 reg = CFG_COMP(MT8195, ctx->param, wrot.iova[0]); 662 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg, 663 - 0xFFFFFFFF); 684 + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, reg); 664 685 665 686 if (CFG_CHECK(MT8183, p_id)) 666 687 reg = CFG_COMP(MT8183, ctx->param, wrot.iova[1]); 667 688 else if (CFG_CHECK(MT8195, p_id)) 668 689 reg = CFG_COMP(MT8195, ctx->param, wrot.iova[1]); 669 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg, 670 - 0xFFFFFFFF); 690 + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C, reg); 671 691 672 692 if (CFG_CHECK(MT8183, p_id)) 673 693 reg = CFG_COMP(MT8183, ctx->param, wrot.iova[2]); 674 694 else if (CFG_CHECK(MT8195, p_id)) 675 695 reg = CFG_COMP(MT8195, ctx->param, wrot.iova[2]); 676 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg, 677 - 0xFFFFFFFF); 696 + MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, reg); 678 697 679 698 if (mdp_cfg && mdp_cfg->wrot_support_10bit) { 680 699 if (CFG_CHECK(MT8195, p_id)) 681 700 reg = CFG_COMP(MT8195, ctx->param, wrot.scan_10bit); 682 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT, 683 - reg, 0x0000000F); 701 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_SCAN_10BIT, 702 + reg, 0x0000000F); 684 703 685 704 if (CFG_CHECK(MT8195, p_id)) 686 705 reg = CFG_COMP(MT8195, ctx->param, wrot.pending_zero); 687 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO, 688 - reg, 0x04000000); 706 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_PENDING_ZERO, 707 + reg, 0x04000000); 689 708 } 690 709 691 710 if (CFG_CHECK(MT8195, p_id)) { 692 711 reg = CFG_COMP(MT8195, ctx->param, wrot.bit_number); 693 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2, 694 - reg, 0x00000007); 712 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_CTRL_2, 713 + reg, 0x00000007); 695 714 } 696 715 697 716 /* Write frame related registers */ ··· 696 721 reg = CFG_COMP(MT8183, ctx->param, wrot.control); 697 722 else if (CFG_CHECK(MT8195, p_id)) 698 723 reg = CFG_COMP(MT8195, ctx->param, wrot.control); 699 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, reg, 700 - 0xF131510F); 724 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_CTRL, reg, 0xF131510F); 701 725 702 726 /* Write pre-ultra threshold */ 703 727 if (CFG_CHECK(MT8195, p_id)) { 704 728 reg = CFG_COMP(MT8195, ctx->param, wrot.pre_ultra); 705 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA, reg, 706 - 0x00FFFFFF); 729 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_DMA_PREULTRA, reg, 730 + 0x00FFFFFF); 707 731 } 708 732 709 733 /* Write frame Y pitch */ ··· 710 736 reg = CFG_COMP(MT8183, ctx->param, wrot.stride[0]); 711 737 else if (CFG_CHECK(MT8195, p_id)) 712 738 reg = CFG_COMP(MT8195, ctx->param, wrot.stride[0]); 713 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, reg, 714 - 0x0000FFFF); 739 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE, reg, 0x0000FFFF); 715 740 716 741 /* Write frame UV pitch */ 717 742 if (CFG_CHECK(MT8183, p_id)) 718 743 reg = CFG_COMP(MT8183, ctx->param, wrot.stride[1]); 719 744 else if (CFG_CHECK(MT8195, p_id)) 720 745 reg = CFG_COMP(MT8195, ctx->param, wrot.stride[1]); 721 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C, reg, 722 - 0xFFFF); 746 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE_C, reg, 0xFFFF); 723 747 724 748 if (CFG_CHECK(MT8183, p_id)) 725 749 reg = CFG_COMP(MT8183, ctx->param, wrot.stride[2]); 726 750 else if (CFG_CHECK(MT8195, p_id)) 727 751 reg = CFG_COMP(MT8195, ctx->param, wrot.stride[2]); 728 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V, reg, 729 - 0xFFFF); 752 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_STRIDE_V, reg, 0xFFFF); 730 753 731 754 /* Write matrix control */ 732 755 if (CFG_CHECK(MT8183, p_id)) 733 756 reg = CFG_COMP(MT8183, ctx->param, wrot.mat_ctrl); 734 757 else if (CFG_CHECK(MT8195, p_id)) 735 758 reg = CFG_COMP(MT8195, ctx->param, wrot.mat_ctrl); 736 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3); 759 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAT_CTRL, reg, 0xF3); 737 760 738 761 /* Set the fixed ALPHA as 0xFF */ 739 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000, 740 - 0xFF000000); 762 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_DITHER, 0xFF000000, 763 + 0xFF000000); 741 764 742 765 /* Set VIDO_EOL_SEL */ 743 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31)); 766 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_RSV_1, BIT(31), BIT(31)); 744 767 745 768 /* Set VIDO_FIFO_TEST */ 746 769 if (CFG_CHECK(MT8183, p_id)) ··· 746 775 reg = CFG_COMP(MT8195, ctx->param, wrot.fifo_test); 747 776 748 777 if (reg != 0) 749 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST, 750 - reg, 0xFFF); 778 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_FIFO_TEST, reg, 779 + 0xFFF); 751 780 752 781 /* Filter enable */ 753 782 if (mdp_cfg && mdp_cfg->wrot_filter_constraint) { ··· 755 784 reg = CFG_COMP(MT8183, ctx->param, wrot.filter); 756 785 else if (CFG_CHECK(MT8195, p_id)) 757 786 reg = CFG_COMP(MT8195, ctx->param, wrot.filter); 758 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 759 - reg, 0x77); 787 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 788 + 0x77); 760 789 761 790 /* Turn off WROT DMA DCM */ 762 791 if (CFG_CHECK(MT8195, p_id)) 763 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 764 - (0x1 << 23) + (0x1 << 20), 0x900000); 792 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_ROT_EN, 793 + (0x1 << 23) + (0x1 << 20), 0x900000); 765 794 } 766 795 767 796 return 0; ··· 779 808 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[0]); 780 809 else if (CFG_CHECK(MT8195, p_id)) 781 810 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[0]); 782 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR, 783 - reg, 0x0FFFFFFF); 811 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR, reg, 0x0FFFFFFF); 784 812 785 813 /* Write U pixel offset */ 786 814 if (CFG_CHECK(MT8183, p_id)) 787 815 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[1]); 788 816 else if (CFG_CHECK(MT8195, p_id)) 789 817 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[1]); 790 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C, 791 - reg, 0x0FFFFFFF); 818 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR_C, reg, 0x0FFFFFFF); 792 819 793 820 /* Write V pixel offset */ 794 821 if (CFG_CHECK(MT8183, p_id)) 795 822 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].offset[2]); 796 823 else if (CFG_CHECK(MT8195, p_id)) 797 824 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].offset[2]); 798 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V, 799 - reg, 0x0FFFFFFF); 825 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_OFST_ADDR_V, reg, 826 + 0x0FFFFFFF); 800 827 801 828 /* Write source size */ 802 829 if (CFG_CHECK(MT8183, p_id)) 803 830 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].src); 804 831 else if (CFG_CHECK(MT8195, p_id)) 805 832 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].src); 806 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE, reg, 807 - 0x1FFF1FFF); 833 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_IN_SIZE, reg, 0x1FFF1FFF); 808 834 809 835 /* Write target size */ 810 836 if (CFG_CHECK(MT8183, p_id)) 811 837 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip); 812 838 else if (CFG_CHECK(MT8195, p_id)) 813 839 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip); 814 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE, reg, 815 - 0x1FFF1FFF); 840 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_TAR_SIZE, reg, 0x1FFF1FFF); 816 841 817 842 if (CFG_CHECK(MT8183, p_id)) 818 843 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].clip_ofst); 819 844 else if (CFG_CHECK(MT8195, p_id)) 820 845 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].clip_ofst); 821 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, reg, 822 - 0x1FFF1FFF); 846 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_CROP_OFST, reg, 0x1FFF1FFF); 823 847 824 848 if (CFG_CHECK(MT8183, p_id)) 825 849 reg = CFG_COMP(MT8183, ctx->param, wrot.subfrms[index].main_buf); 826 850 else if (CFG_CHECK(MT8195, p_id)) 827 851 reg = CFG_COMP(MT8195, ctx->param, wrot.subfrms[index].main_buf); 828 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 829 - reg, 0x1FFF7F00); 852 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, reg, 853 + 0x1FFF7F00); 830 854 831 855 /* Enable WROT */ 832 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0)); 856 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_ROT_EN, BIT(0), BIT(0)); 833 857 834 858 return 0; 835 859 } ··· 847 881 MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); 848 882 849 883 if (mdp_cfg && mdp_cfg->wrot_filter_constraint) 850 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0, 851 - 0x77); 884 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0, 885 + 0x77); 852 886 853 887 /* Disable WROT */ 854 - MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0)); 888 + MM_REG_WRITE_MASK(cmd, subsys_id, base, VIDO_ROT_EN, 0x0, BIT(0)); 855 889 856 890 return 0; 857 891 } ··· 870 904 u8 subsys_id = ctx->comp->subsys_id; 871 905 872 906 /* Reset WDMA */ 873 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0)); 874 - MM_REG_POLL(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0)); 875 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0)); 907 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, BIT(0), BIT(0)); 908 + MM_REG_POLL_MASK(cmd, subsys_id, base, WDMA_FLOW_CTRL_DBG, BIT(0), BIT(0)); 909 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_RST, 0x0, BIT(0)); 876 910 return 0; 877 911 } 878 912 ··· 884 918 u8 subsys_id = ctx->comp->subsys_id; 885 919 u32 reg = 0; 886 920 887 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050, 888 - 0xFFFFFFFF); 921 + MM_REG_WRITE(cmd, subsys_id, base, WDMA_BUF_CON2, 0x10101050); 889 922 890 923 /* Setup frame information */ 891 924 if (CFG_CHECK(MT8183, p_id)) 892 925 reg = CFG_COMP(MT8183, ctx->param, wdma.wdma_cfg); 893 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CFG, reg, 894 - 0x0F01B8F0); 926 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CFG, reg, 0x0F01B8F0); 895 927 /* Setup frame base address */ 896 928 if (CFG_CHECK(MT8183, p_id)) 897 929 reg = CFG_COMP(MT8183, ctx->param, wdma.iova[0]); 898 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg, 899 - 0xFFFFFFFF); 930 + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR, reg); 900 931 if (CFG_CHECK(MT8183, p_id)) 901 932 reg = CFG_COMP(MT8183, ctx->param, wdma.iova[1]); 902 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg, 903 - 0xFFFFFFFF); 933 + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR, reg); 904 934 if (CFG_CHECK(MT8183, p_id)) 905 935 reg = CFG_COMP(MT8183, ctx->param, wdma.iova[2]); 906 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg, 907 - 0xFFFFFFFF); 936 + MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR, reg); 908 937 /* Setup Y pitch */ 909 938 if (CFG_CHECK(MT8183, p_id)) 910 939 reg = CFG_COMP(MT8183, ctx->param, wdma.w_in_byte); 911 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE, 912 - reg, 0x0000FFFF); 940 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_W_IN_BYTE, reg, 941 + 0x0000FFFF); 913 942 /* Setup UV pitch */ 914 943 if (CFG_CHECK(MT8183, p_id)) 915 944 reg = CFG_COMP(MT8183, ctx->param, wdma.uv_stride); 916 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_UV_PITCH, 917 - reg, 0x0000FFFF); 945 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_UV_PITCH, reg, 946 + 0x0000FFFF); 918 947 /* Set the fixed ALPHA as 0xFF */ 919 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF, 920 - 0x800000FF); 948 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_ALPHA, 0x800000FF, 949 + 0x800000FF); 921 950 922 951 return 0; 923 952 } ··· 927 966 /* Write Y pixel offset */ 928 967 if (CFG_CHECK(MT8183, p_id)) 929 968 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[0]); 930 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET, 931 - reg, 0x0FFFFFFF); 969 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_ADDR_OFFSET, reg, 970 + 0x0FFFFFFF); 932 971 /* Write U pixel offset */ 933 972 if (CFG_CHECK(MT8183, p_id)) 934 973 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[1]); 935 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET, 936 - reg, 0x0FFFFFFF); 974 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_U_ADDR_OFFSET, reg, 975 + 0x0FFFFFFF); 937 976 /* Write V pixel offset */ 938 977 if (CFG_CHECK(MT8183, p_id)) 939 978 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].offset[2]); 940 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET, 941 - reg, 0x0FFFFFFF); 979 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_DST_V_ADDR_OFFSET, reg, 980 + 0x0FFFFFFF); 942 981 /* Write source size */ 943 982 if (CFG_CHECK(MT8183, p_id)) 944 983 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].src); 945 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_SRC_SIZE, reg, 946 - 0x3FFF3FFF); 984 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_SRC_SIZE, reg, 0x3FFF3FFF); 947 985 /* Write target size */ 948 986 if (CFG_CHECK(MT8183, p_id)) 949 987 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip); 950 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg, 951 - 0x3FFF3FFF); 988 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CLIP_SIZE, reg, 0x3FFF3FFF); 952 989 /* Write clip offset */ 953 990 if (CFG_CHECK(MT8183, p_id)) 954 991 reg = CFG_COMP(MT8183, ctx->param, wdma.subfrms[index].clip_ofst); 955 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_CLIP_COORD, reg, 956 - 0x3FFF3FFF); 992 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_CLIP_COORD, reg, 0x3FFF3FFF); 957 993 958 994 /* Enable WDMA */ 959 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0)); 995 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_EN, BIT(0), BIT(0)); 960 996 961 997 return 0; 962 998 } ··· 965 1007 966 1008 MM_REG_WAIT(cmd, ctx->comp->gce_event[MDP_GCE_EVENT_EOF]); 967 1009 /* Disable WDMA */ 968 - MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0)); 1010 + MM_REG_WRITE_MASK(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0)); 969 1011 return 0; 970 1012 } 971 1013 ··· 991 1033 992 1034 /* Reset histogram */ 993 1035 for (i = 0; i <= hist_num; i++) 994 - MM_REG_WRITE_MASK(cmd, subsys_id, base, 995 - (MDP_LUMA_HIST_INIT + (i << 2)), 996 - 0, 0xFFFFFFFF); 1036 + MM_REG_WRITE(cmd, subsys_id, base, 1037 + (MDP_LUMA_HIST_INIT + (i << 2)), 0); 997 1038 998 1039 if (mdp_cfg->tdshp_constrain) 999 1040 MM_REG_WRITE(cmd, subsys_id, base, 1000 - MDP_DC_TWO_D_W1_RESULT_INIT, 0, 0xFFFFFFFF); 1041 + MDP_DC_TWO_D_W1_RESULT_INIT, 0); 1001 1042 1002 1043 if (mdp_cfg->tdshp_contour) 1003 1044 for (i = 0; i < hist_num; i++) 1004 - MM_REG_WRITE_MASK(cmd, subsys_id, base, 1005 - (MDP_CONTOUR_HIST_INIT + (i << 2)), 1006 - 0, 0xFFFFFFFF); 1045 + MM_REG_WRITE(cmd, subsys_id, base, 1046 + (MDP_CONTOUR_HIST_INIT + (i << 2)), 0); 1007 1047 1008 1048 return 0; 1009 1049 } ··· 1011 1055 phys_addr_t base = ctx->comp->reg_base; 1012 1056 u16 subsys_id = ctx->comp->subsys_id; 1013 1057 1014 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CTRL, BIT(0), BIT(0)); 1058 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_TDSHP_CTRL, BIT(0), BIT(0)); 1015 1059 /* Enable FIFO */ 1016 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, BIT(1), BIT(1)); 1060 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_TDSHP_CFG, BIT(1), BIT(1)); 1017 1061 1018 1062 return reset_luma_hist(ctx, cmd); 1019 1063 } ··· 1028 1072 1029 1073 if (CFG_CHECK(MT8195, p_id)) 1030 1074 reg = CFG_COMP(MT8195, ctx->param, tdshp.cfg); 1031 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, reg, BIT(0)); 1075 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_TDSHP_CFG, reg, BIT(0)); 1032 1076 1033 1077 return 0; 1034 1078 } ··· 1042 1086 1043 1087 if (CFG_CHECK(MT8195, p_id)) 1044 1088 reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].src); 1045 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE, 1046 - reg, MDP_TDSHP_INPUT_SIZE_MASK); 1089 + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE, reg); 1047 1090 1048 1091 if (CFG_CHECK(MT8195, p_id)) 1049 1092 reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip_ofst); 1050 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET, 1051 - reg, 0x00FF00FF); 1093 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET, reg, 1094 + 0x00FF00FF); 1052 1095 1053 1096 if (CFG_CHECK(MT8195, p_id)) 1054 1097 reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].clip); 1055 - MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE, 1056 - reg, MDP_TDSHP_OUTPUT_SIZE_MASK); 1098 + MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE, reg); 1057 1099 1058 1100 if (CFG_CHECK(MT8195, p_id)) 1059 1101 reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_0); 1060 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00, reg, 0xFFFFFFFF); 1102 + MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00, reg); 1061 1103 1062 1104 if (CFG_CHECK(MT8195, p_id)) 1063 1105 reg = CFG_COMP(MT8195, ctx->param, tdshp.subfrms[index].hist_cfg_1); 1064 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01, reg, 0xFFFFFFFF); 1106 + MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01, reg); 1065 1107 1066 1108 return 0; 1067 1109 } ··· 1076 1122 phys_addr_t base = ctx->comp->reg_base; 1077 1123 u16 subsys_id = ctx->comp->subsys_id; 1078 1124 1079 - MM_REG_WRITE(cmd, subsys_id, base, 1080 - MDP_COLOR_START, 0x1, BIT(1) | BIT(0)); 1081 - MM_REG_WRITE(cmd, subsys_id, base, 1082 - MDP_COLOR_WIN_X_MAIN, 0xFFFF0000, 0xFFFFFFFF); 1083 - MM_REG_WRITE(cmd, subsys_id, base, 1084 - MDP_COLOR_WIN_Y_MAIN, 0xFFFF0000, 0xFFFFFFFF); 1125 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_START, 0x1, 1126 + BIT(1) | BIT(0)); 1127 + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_WIN_X_MAIN, 0xFFFF0000); 1128 + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_WIN_Y_MAIN, 0xFFFF0000); 1085 1129 1086 1130 /* Reset color matrix */ 1087 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM1_EN, 0x0, BIT(0)); 1088 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_CM2_EN, 0x0, BIT(0)); 1131 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_CM1_EN, 0x0, BIT(0)); 1132 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_CM2_EN, 0x0, BIT(0)); 1089 1133 1090 1134 /* Enable interrupt */ 1091 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTEN, 0x7, 0x7); 1135 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_INTEN, 0x7, 0x7); 1092 1136 1093 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_OUT_SEL, 0x333, 0x333); 1137 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_OUT_SEL, 0x333, 0x333); 1094 1138 1095 1139 return 0; 1096 1140 } ··· 1103 1151 1104 1152 if (CFG_CHECK(MT8195, p_id)) 1105 1153 reg = CFG_COMP(MT8195, ctx->param, color.start); 1106 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_START, 1107 - reg, MDP_COLOR_START_MASK); 1154 + MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_START, reg); 1108 1155 1109 1156 return 0; 1110 1157 } ··· 1117 1166 1118 1167 if (CFG_CHECK(MT8195, p_id)) 1119 1168 reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_hsize); 1120 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_WIDTH, 1121 - reg, 0x00003FFF); 1169 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_WIDTH, 1170 + reg, 0x00003FFF); 1122 1171 1123 1172 if (CFG_CHECK(MT8195, p_id)) 1124 1173 reg = CFG_COMP(MT8195, ctx->param, color.subfrms[index].in_vsize); 1125 - MM_REG_WRITE(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_HEIGHT, 1126 - reg, 0x00003FFF); 1174 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_COLOR_INTERNAL_IP_HEIGHT, 1175 + reg, 0x00003FFF); 1127 1176 1128 1177 return 0; 1129 1178 } ··· 1141 1190 u8 subsys_id = ctx->comp->subsys_id; 1142 1191 1143 1192 /* CCORR enable */ 1144 - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0)); 1193 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_EN, BIT(0), BIT(0)); 1145 1194 /* Relay mode */ 1146 - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0)); 1195 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_CFG, BIT(0), BIT(0)); 1147 1196 return 0; 1148 1197 } 1149 1198 ··· 1165 1214 1166 1215 hsize = csf_r - csf_l + 1; 1167 1216 vsize = csf_b - csf_t + 1; 1168 - MM_REG_WRITE(cmd, subsys_id, base, MDP_CCORR_SIZE, 1169 - (hsize << 16) + (vsize << 0), 0x1FFF1FFF); 1217 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_CCORR_SIZE, 1218 + (hsize << 16) + (vsize << 0), 0x1FFF1FFF); 1170 1219 return 0; 1171 1220 } 1172 1221 ··· 1182 1231 u16 subsys_id = ctx->comp->subsys_id; 1183 1232 1184 1233 /* Always set MDP_AAL enable to 1 */ 1185 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_EN, BIT(0), BIT(0)); 1234 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_AAL_EN, BIT(0), BIT(0)); 1186 1235 1187 1236 return 0; 1188 1237 } ··· 1197 1246 1198 1247 if (CFG_CHECK(MT8195, p_id)) 1199 1248 reg = CFG_COMP(MT8195, ctx->param, aal.cfg_main); 1200 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, reg, BIT(7)); 1249 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, reg, BIT(7)); 1201 1250 1202 1251 if (CFG_CHECK(MT8195, p_id)) 1203 1252 reg = CFG_COMP(MT8195, ctx->param, aal.cfg); 1204 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG, reg, BIT(0)); 1253 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_AAL_CFG, reg, BIT(0)); 1205 1254 1206 1255 return 0; 1207 1256 } ··· 1215 1264 1216 1265 if (CFG_CHECK(MT8195, p_id)) 1217 1266 reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].src); 1218 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE, 1219 - reg, MDP_AAL_SIZE_MASK); 1267 + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE, reg); 1220 1268 1221 1269 if (CFG_CHECK(MT8195, p_id)) 1222 1270 reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip_ofst); 1223 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET, 1224 - reg, 0x00FF00FF); 1271 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET, reg, 1272 + 0x00FF00FF); 1225 1273 1226 1274 if (CFG_CHECK(MT8195, p_id)) 1227 1275 reg = CFG_COMP(MT8195, ctx->param, aal.subfrms[index].clip); 1228 - MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE, 1229 - reg, MDP_AAL_OUTPUT_SIZE_MASK); 1276 + MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE, reg); 1230 1277 1231 1278 return 0; 1232 1279 } ··· 1242 1293 u16 subsys_id = ctx->comp->subsys_id; 1243 1294 1244 1295 /* Always set MDP_HDR enable to 1 */ 1245 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, BIT(0), BIT(0)); 1296 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_TOP, BIT(0), BIT(0)); 1246 1297 1247 1298 return 0; 1248 1299 } ··· 1257 1308 1258 1309 if (CFG_CHECK(MT8195, p_id)) 1259 1310 reg = CFG_COMP(MT8195, ctx->param, hdr.top); 1260 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(29) | BIT(28)); 1311 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(29) | BIT(28)); 1261 1312 1262 1313 if (CFG_CHECK(MT8195, p_id)) 1263 1314 reg = CFG_COMP(MT8195, ctx->param, hdr.relay); 1264 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_RELAY, reg, BIT(0)); 1315 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_RELAY, reg, BIT(0)); 1265 1316 1266 1317 return 0; 1267 1318 } ··· 1275 1326 1276 1327 if (CFG_CHECK(MT8195, p_id)) 1277 1328 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].win_size); 1278 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS, 1279 - reg, MDP_HDR_TILE_POS_MASK); 1329 + MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS, reg); 1280 1330 1281 1331 if (CFG_CHECK(MT8195, p_id)) 1282 1332 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].src); 1283 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_0, reg, 0x1FFF1FFF); 1333 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_SIZE_0, reg, 0x1FFF1FFF); 1284 1334 1285 1335 if (CFG_CHECK(MT8195, p_id)) 1286 1336 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst0); 1287 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_1, reg, 0x1FFF1FFF); 1337 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_SIZE_1, reg, 0x1FFF1FFF); 1288 1338 1289 1339 if (CFG_CHECK(MT8195, p_id)) 1290 1340 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].clip_ofst1); 1291 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_2, reg, 0x1FFF1FFF); 1341 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_SIZE_2, reg, 0x1FFF1FFF); 1292 1342 1293 1343 if (CFG_CHECK(MT8195, p_id)) 1294 1344 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_0); 1295 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0, reg, 0x00003FFF); 1345 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0, reg, 0x00003FFF); 1296 1346 1297 1347 if (CFG_CHECK(MT8195, p_id)) 1298 1348 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_ctrl_1); 1299 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1, reg, 0x00003FFF); 1349 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1, reg, 0x00003FFF); 1300 1350 1301 1351 if (CFG_CHECK(MT8195, p_id)) 1302 1352 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hdr_top); 1303 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(6) | BIT(5)); 1353 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_TOP, reg, BIT(6) | BIT(5)); 1304 1354 1305 1355 /* Enable histogram */ 1306 1356 if (CFG_CHECK(MT8195, p_id)) 1307 1357 reg = CFG_COMP(MT8195, ctx->param, hdr.subfrms[index].hist_addr); 1308 - MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_ADDR, reg, BIT(9)); 1358 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_HDR_HIST_ADDR, reg, BIT(9)); 1309 1359 1310 1360 return 0; 1311 1361 } ··· 1321 1373 phys_addr_t base = ctx->comp->reg_base; 1322 1374 u16 subsys_id = ctx->comp->subsys_id; 1323 1375 1324 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, BIT(2), BIT(2)); 1325 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER, 0x0, BIT(2)); 1376 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_FG_TRIGGER, BIT(2), BIT(2)); 1377 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_FG_TRIGGER, 0x0, BIT(2)); 1326 1378 1327 1379 return 0; 1328 1380 } ··· 1337 1389 1338 1390 if (CFG_CHECK(MT8195, p_id)) 1339 1391 reg = CFG_COMP(MT8195, ctx->param, fg.ctrl_0); 1340 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, reg, BIT(0)); 1392 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, reg, BIT(0)); 1341 1393 1342 1394 if (CFG_CHECK(MT8195, p_id)) 1343 1395 reg = CFG_COMP(MT8195, ctx->param, fg.ck_en); 1344 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CK_EN, reg, 0x7); 1396 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_FG_FG_CK_EN, reg, 0x7); 1345 1397 1346 1398 return 0; 1347 1399 } ··· 1355 1407 1356 1408 if (CFG_CHECK(MT8195, p_id)) 1357 1409 reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_0); 1358 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, reg, 0xFFFFFFFF); 1410 + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, reg); 1359 1411 1360 1412 if (CFG_CHECK(MT8195, p_id)) 1361 1413 reg = CFG_COMP(MT8195, ctx->param, fg.subfrms[index].info_1); 1362 - MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, reg, 0xFFFFFFFF); 1414 + MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, reg); 1363 1415 1364 1416 return 0; 1365 1417 } ··· 1376 1428 phys_addr_t base = ctx->comp->reg_base; 1377 1429 u16 subsys_id = ctx->comp->subsys_id; 1378 1430 1379 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_EN, 1380 - BIT(0), MDP_OVL_EN_MASK); 1431 + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_EN, BIT(0)); 1381 1432 1382 1433 /* Set to relay mode */ 1383 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, 1384 - BIT(9), MDP_OVL_SRC_CON_MASK); 1385 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_DP_CON, 1386 - BIT(0), MDP_OVL_DP_CON_MASK); 1434 + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, BIT(9)); 1435 + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_DP_CON, BIT(0)); 1387 1436 1388 1437 return 0; 1389 1438 } ··· 1395 1450 1396 1451 if (CFG_CHECK(MT8195, p_id)) 1397 1452 reg = CFG_COMP(MT8195, ctx->param, ovl.L0_con); 1398 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_CON, reg, BIT(29) | BIT(28)); 1453 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_OVL_L0_CON, reg, BIT(29) | BIT(28)); 1399 1454 1400 1455 if (CFG_CHECK(MT8195, p_id)) 1401 1456 reg = CFG_COMP(MT8195, ctx->param, ovl.src_con); 1402 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_SRC_CON, reg, BIT(0)); 1457 + MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_OVL_SRC_CON, reg, BIT(0)); 1403 1458 1404 1459 return 0; 1405 1460 } ··· 1413 1468 1414 1469 if (CFG_CHECK(MT8195, p_id)) 1415 1470 reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].L0_src_size); 1416 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_SRC_SIZE, 1417 - reg, MDP_OVL_L0_SRC_SIZE_MASK); 1471 + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_L0_SRC_SIZE, reg); 1418 1472 1419 1473 /* Setup output size */ 1420 1474 if (CFG_CHECK(MT8195, p_id)) 1421 1475 reg = CFG_COMP(MT8195, ctx->param, ovl.subfrms[index].roi_size); 1422 - MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_ROI_SIZE, 1423 - reg, MDP_OVL_ROI_SIZE_MASK); 1476 + MM_REG_WRITE(cmd, subsys_id, base, MDP_OVL_ROI_SIZE, reg); 1424 1477 1425 1478 return 0; 1426 1479 } ··· 1435 1492 phys_addr_t base = ctx->comp->reg_base; 1436 1493 u16 subsys_id = ctx->comp->subsys_id; 1437 1494 1438 - MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_CON, 1439 - BIT(1), MDP_PAD_CON_MASK); 1495 + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_CON, BIT(1)); 1440 1496 /* Reset */ 1441 - MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_W_SIZE, 1442 - 0, MDP_PAD_W_SIZE_MASK); 1443 - MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_H_SIZE, 1444 - 0, MDP_PAD_H_SIZE_MASK); 1497 + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_W_SIZE, 0); 1498 + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_H_SIZE, 0); 1445 1499 1446 1500 return 0; 1447 1501 } ··· 1452 1512 1453 1513 if (CFG_CHECK(MT8195, p_id)) 1454 1514 reg = CFG_COMP(MT8195, ctx->param, pad.subfrms[index].pic_size); 1455 - MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_PIC_SIZE, 1456 - reg, MDP_PAD_PIC_SIZE_MASK); 1515 + MM_REG_WRITE(cmd, subsys_id, base, MDP_PAD_PIC_SIZE, reg); 1457 1516 1458 1517 return 0; 1459 1518 }
+13 -16
drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.h
··· 9 9 10 10 #include "mtk-mdp3-cmdq.h" 11 11 12 - #define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask, ...) \ 13 - cmdq_pkt_write_mask(&((cmd)->pkt), id, \ 14 - (base) + (ofst), (val), (mask), ##__VA_ARGS__) 15 - 16 - #define MM_REG_WRITE(cmd, id, base, ofst, val, mask, ...) \ 12 + #define MM_REG_WRITE_MASK(cmd, id, base, ofst, val, mask) \ 17 13 do { \ 18 14 typeof(mask) (m) = (mask); \ 19 - MM_REG_WRITE_MASK(cmd, id, base, ofst, val, \ 15 + cmdq_pkt_write_mask(&((cmd)->pkt), id, (base) + (ofst), \ 16 + (val), \ 20 17 (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ 21 - (0xffffffff) : (m), ##__VA_ARGS__); \ 18 + (0xffffffff) : (m)); \ 22 19 } while (0) 20 + 21 + #define MM_REG_WRITE(cmd, id, base, ofst, val) \ 22 + cmdq_pkt_write(&((cmd)->pkt), id, (base) + (ofst), (val)) 23 23 24 24 #define MM_REG_WAIT(cmd, evt) \ 25 25 do { \ ··· 49 49 cmdq_pkt_set_event(&((c)->pkt), (e)); \ 50 50 } while (0) 51 51 52 - #define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask, ...) \ 52 + #define MM_REG_POLL_MASK(cmd, id, base, ofst, val, _mask) \ 53 53 do { \ 54 54 typeof(_mask) (_m) = (_mask); \ 55 55 cmdq_pkt_poll_mask(&((cmd)->pkt), id, \ 56 - (base) + (ofst), (val), (_m), ##__VA_ARGS__); \ 56 + (base) + (ofst), (val), \ 57 + (((_m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ 58 + (0xffffffff) : (_m)); \ 57 59 } while (0) 58 60 59 - #define MM_REG_POLL(cmd, id, base, ofst, val, mask, ...) \ 60 - do { \ 61 - typeof(mask) (m) = (mask); \ 62 - MM_REG_POLL_MASK((cmd), id, base, ofst, val, \ 63 - (((m) & (ofst##_MASK)) == (ofst##_MASK)) ? \ 64 - (0xffffffff) : (m), ##__VA_ARGS__); \ 65 - } while (0) 61 + #define MM_REG_POLL(cmd, id, base, ofst, val) \ 62 + cmdq_pkt_poll(&((cmd)->pkt), id, (base) + (ofst), (val)) 66 63 67 64 enum mtk_mdp_comp_id { 68 65 MDP_COMP_NONE = -1, /* Invalid engine */
+2
drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
··· 312 312 ret = PTR_ERR(mdp->cmdq_clt[i]); 313 313 goto err_mbox_destroy; 314 314 } 315 + 316 + mdp->cmdq_shift_pa[i] = cmdq_get_shift_pa(mdp->cmdq_clt[i]->chan); 315 317 } 316 318 317 319 init_waitqueue_head(&mdp->callback_wq);
+1
drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.h
··· 126 126 u32 id_count; 127 127 struct ida mdp_ida; 128 128 struct cmdq_client *cmdq_clt[MDP_PP_MAX]; 129 + u8 cmdq_shift_pa[MDP_PP_MAX]; 129 130 wait_queue_head_t callback_wq; 130 131 131 132 struct v4l2_device v4l2_dev;
+2 -2
drivers/media/platform/nuvoton/npcm-video.c
··· 1665 1665 dev_info(dev, "Support HEXTILE pixel format\n"); 1666 1666 1667 1667 ece_pdev = of_find_device_by_node(ece_node); 1668 - if (IS_ERR(ece_pdev)) { 1668 + if (!ece_pdev) { 1669 1669 dev_err(dev, "Failed to find ECE device\n"); 1670 - return PTR_ERR(ece_pdev); 1670 + return -ENODEV; 1671 1671 } 1672 1672 of_node_put(ece_node); 1673 1673
+4 -3
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
··· 2677 2677 int i; 2678 2678 2679 2679 for (i = 0; i < jpeg->num_domains; i++) { 2680 - if (jpeg->pd_dev[i] && !pm_runtime_suspended(jpeg->pd_dev[i])) 2680 + if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) && 2681 + !pm_runtime_suspended(jpeg->pd_dev[i])) 2681 2682 pm_runtime_force_suspend(jpeg->pd_dev[i]); 2682 - if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i])) 2683 + if (!IS_ERR_OR_NULL(jpeg->pd_link[i])) 2683 2684 device_link_del(jpeg->pd_link[i]); 2684 - if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i])) 2685 + if (!IS_ERR_OR_NULL(jpeg->pd_dev[i])) 2685 2686 dev_pm_domain_detach(jpeg->pd_dev[i], true); 2686 2687 jpeg->pd_dev[i] = NULL; 2687 2688 jpeg->pd_link[i] = NULL;
+14
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c
··· 307 307 .has_36bit_dma = true, 308 308 }; 309 309 310 + static const struct mxc_isi_plat_data mxc_imx8ulp_data = { 311 + .model = MXC_ISI_IMX8ULP, 312 + .num_ports = 1, 313 + .num_channels = 1, 314 + .reg_offset = 0x0, 315 + .ier_reg = &mxc_imx8_isi_ier_v2, 316 + .set_thd = &mxc_imx8_isi_thd_v1, 317 + .clks = mxc_imx8mn_clks, 318 + .num_clks = ARRAY_SIZE(mxc_imx8mn_clks), 319 + .buf_active_reverse = true, 320 + .has_36bit_dma = false, 321 + }; 322 + 310 323 static const struct mxc_isi_plat_data mxc_imx93_data = { 311 324 .model = MXC_ISI_IMX93, 312 325 .num_ports = 1, ··· 541 528 static const struct of_device_id mxc_isi_of_match[] = { 542 529 { .compatible = "fsl,imx8mn-isi", .data = &mxc_imx8mn_data }, 543 530 { .compatible = "fsl,imx8mp-isi", .data = &mxc_imx8mp_data }, 531 + { .compatible = "fsl,imx8ulp-isi", .data = &mxc_imx8ulp_data }, 544 532 { .compatible = "fsl,imx93-isi", .data = &mxc_imx93_data }, 545 533 { /* sentinel */ }, 546 534 };
+1
drivers/media/platform/nxp/imx8-isi/imx8-isi-core.h
··· 158 158 enum model { 159 159 MXC_ISI_IMX8MN, 160 160 MXC_ISI_IMX8MP, 161 + MXC_ISI_IMX8ULP, 161 162 MXC_ISI_IMX93, 162 163 }; 163 164
+3
drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
··· 861 861 const struct mxc_isi_format_info *info, 862 862 const struct v4l2_pix_format_mplane *pix) 863 863 { 864 + struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb2); 864 865 unsigned int i; 865 866 866 867 for (i = 0; i < info->mem_planes; i++) { ··· 875 874 876 875 vb2_set_plane_payload(vb2, i, size); 877 876 } 877 + 878 + v4l2_buf->field = pix->field; 878 879 879 880 return 0; 880 881 }
+9 -4
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
··· 505 505 u32 val; 506 506 507 507 switch (csiphy->camss->res->version) { 508 - case CAMSS_845: 509 - r = &lane_regs_sdm845[0][0]; 510 - array_size = ARRAY_SIZE(lane_regs_sdm845[0]); 508 + case CAMSS_7280: 509 + r = &lane_regs_sm8250[0][0]; 510 + array_size = ARRAY_SIZE(lane_regs_sm8250[0]); 511 511 break; 512 512 case CAMSS_8250: 513 513 r = &lane_regs_sm8250[0][0]; ··· 516 516 case CAMSS_8280XP: 517 517 r = &lane_regs_sc8280xp[0][0]; 518 518 array_size = ARRAY_SIZE(lane_regs_sc8280xp[0]); 519 + break; 520 + case CAMSS_845: 521 + r = &lane_regs_sdm845[0][0]; 522 + array_size = ARRAY_SIZE(lane_regs_sdm845[0]); 519 523 break; 520 524 default: 521 525 WARN(1, "unknown cspi version\n"); ··· 561 557 bool ret = false; 562 558 563 559 switch (version) { 564 - case CAMSS_845: 560 + case CAMSS_7280: 565 561 case CAMSS_8250: 566 562 case CAMSS_8280XP: 563 + case CAMSS_845: 567 564 ret = true; 568 565 break; 569 566 }
+5
drivers/media/platform/qcom/camss/camss-csiphy.c
··· 103 103 .formats = formats_8x96 104 104 }; 105 105 106 + const struct csiphy_formats csiphy_formats_sc7280 = { 107 + .nformats = ARRAY_SIZE(formats_sdm845), 108 + .formats = formats_sdm845 109 + }; 110 + 106 111 const struct csiphy_formats csiphy_formats_sdm845 = { 107 112 .nformats = ARRAY_SIZE(formats_sdm845), 108 113 .formats = formats_sdm845
+7
drivers/media/platform/qcom/camss/camss-csiphy.h
··· 26 26 u8 pol; 27 27 }; 28 28 29 + /** 30 + * struct csiphy_lanes_cfg - CSIPHY lanes configuration 31 + * @num_data: number of data lanes 32 + * @data: data lanes configuration 33 + * @clk: clock lane configuration (only for D-PHY) 34 + */ 29 35 struct csiphy_lanes_cfg { 30 36 int num_data; 31 37 struct csiphy_lane *data; ··· 117 111 118 112 extern const struct csiphy_formats csiphy_formats_8x16; 119 113 extern const struct csiphy_formats csiphy_formats_8x96; 114 + extern const struct csiphy_formats csiphy_formats_sc7280; 120 115 extern const struct csiphy_formats csiphy_formats_sdm845; 121 116 122 117 extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
+5 -3
drivers/media/platform/qcom/camss/camss-vfe.c
··· 334 334 return sink_code; 335 335 } 336 336 break; 337 - case CAMSS_8x96: 338 337 case CAMSS_660: 339 - case CAMSS_845: 338 + case CAMSS_7280: 339 + case CAMSS_8x96: 340 340 case CAMSS_8250: 341 341 case CAMSS_8280XP: 342 + case CAMSS_845: 342 343 switch (sink_code) { 343 344 case MEDIA_BUS_FMT_YUYV8_1X16: 344 345 { ··· 1694 1693 int ret = 8; 1695 1694 1696 1695 switch (vfe->camss->res->version) { 1697 - case CAMSS_845: 1696 + case CAMSS_7280: 1698 1697 case CAMSS_8250: 1699 1698 case CAMSS_8280XP: 1699 + case CAMSS_845: 1700 1700 ret = 16; 1701 1701 break; 1702 1702 default:
+355 -24
drivers/media/platform/qcom/camss/camss.c
··· 1266 1266 }, 1267 1267 }; 1268 1268 1269 + static const struct camss_subdev_resources csiphy_res_7280[] = { 1270 + /* CSIPHY0 */ 1271 + { 1272 + .regulators = { "vdda-phy", "vdda-pll" }, 1273 + 1274 + .clock = { "csiphy0", "csiphy0_timer" }, 1275 + .clock_rate = { { 300000000, 400000000 }, 1276 + { 300000000 } }, 1277 + .reg = { "csiphy0" }, 1278 + .interrupt = { "csiphy0" }, 1279 + .csiphy = { 1280 + .hw_ops = &csiphy_ops_3ph_1_0, 1281 + .formats = &csiphy_formats_sc7280 1282 + } 1283 + }, 1284 + /* CSIPHY1 */ 1285 + { 1286 + .regulators = { "vdda-phy", "vdda-pll" }, 1287 + 1288 + .clock = { "csiphy1", "csiphy1_timer" }, 1289 + .clock_rate = { { 300000000, 400000000 }, 1290 + { 300000000 } }, 1291 + .reg = { "csiphy1" }, 1292 + .interrupt = { "csiphy1" }, 1293 + .csiphy = { 1294 + .hw_ops = &csiphy_ops_3ph_1_0, 1295 + .formats = &csiphy_formats_sc7280 1296 + } 1297 + }, 1298 + /* CSIPHY2 */ 1299 + { 1300 + .regulators = { "vdda-phy", "vdda-pll" }, 1301 + 1302 + .clock = { "csiphy2", "csiphy2_timer" }, 1303 + .clock_rate = { { 300000000, 400000000 }, 1304 + { 300000000 } }, 1305 + .reg = { "csiphy2" }, 1306 + .interrupt = { "csiphy2" }, 1307 + .csiphy = { 1308 + .hw_ops = &csiphy_ops_3ph_1_0, 1309 + .formats = &csiphy_formats_sc7280 1310 + } 1311 + }, 1312 + /* CSIPHY3 */ 1313 + { 1314 + .regulators = { "vdda-phy", "vdda-pll" }, 1315 + 1316 + .clock = { "csiphy3", "csiphy3_timer" }, 1317 + .clock_rate = { { 300000000, 400000000 }, 1318 + { 300000000 } }, 1319 + .reg = { "csiphy3" }, 1320 + .interrupt = { "csiphy3" }, 1321 + .csiphy = { 1322 + .hw_ops = &csiphy_ops_3ph_1_0, 1323 + .formats = &csiphy_formats_sc7280 1324 + } 1325 + }, 1326 + /* CSIPHY4 */ 1327 + { 1328 + .regulators = { "vdda-phy", "vdda-pll" }, 1329 + 1330 + .clock = { "csiphy4", "csiphy4_timer" }, 1331 + .clock_rate = { { 300000000, 400000000 }, 1332 + { 300000000 } }, 1333 + .reg = { "csiphy4" }, 1334 + .interrupt = { "csiphy4" }, 1335 + .csiphy = { 1336 + .hw_ops = &csiphy_ops_3ph_1_0, 1337 + .formats = &csiphy_formats_sc7280 1338 + } 1339 + }, 1340 + }; 1341 + 1342 + static const struct camss_subdev_resources csid_res_7280[] = { 1343 + /* CSID0 */ 1344 + { 1345 + .regulators = {}, 1346 + 1347 + .clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0" }, 1348 + .clock_rate = { { 300000000, 400000000 }, 1349 + { 0 }, 1350 + { 380000000, 510000000, 637000000, 760000000 } 1351 + }, 1352 + 1353 + .reg = { "csid0" }, 1354 + .interrupt = { "csid0" }, 1355 + .csid = { 1356 + .is_lite = false, 1357 + .hw_ops = &csid_ops_gen2, 1358 + .parent_dev_ops = &vfe_parent_dev_ops, 1359 + .formats = &csid_formats_gen2 1360 + } 1361 + }, 1362 + /* CSID1 */ 1363 + { 1364 + .regulators = {}, 1365 + 1366 + .clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1" }, 1367 + .clock_rate = { { 300000000, 400000000 }, 1368 + { 0 }, 1369 + { 380000000, 510000000, 637000000, 760000000 } 1370 + }, 1371 + 1372 + .reg = { "csid1" }, 1373 + .interrupt = { "csid1" }, 1374 + .csid = { 1375 + .is_lite = false, 1376 + .hw_ops = &csid_ops_gen2, 1377 + .parent_dev_ops = &vfe_parent_dev_ops, 1378 + .formats = &csid_formats_gen2 1379 + } 1380 + }, 1381 + /* CSID2 */ 1382 + { 1383 + .regulators = {}, 1384 + 1385 + .clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2" }, 1386 + .clock_rate = { { 300000000, 400000000 }, 1387 + { 0 }, 1388 + { 380000000, 510000000, 637000000, 760000000 } 1389 + }, 1390 + 1391 + .reg = { "csid2" }, 1392 + .interrupt = { "csid2" }, 1393 + .csid = { 1394 + .is_lite = false, 1395 + .hw_ops = &csid_ops_gen2, 1396 + .parent_dev_ops = &vfe_parent_dev_ops, 1397 + .formats = &csid_formats_gen2 1398 + } 1399 + }, 1400 + /* CSID3 */ 1401 + { 1402 + .regulators = {}, 1403 + 1404 + .clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" }, 1405 + .clock_rate = { { 300000000, 400000000 }, 1406 + { 0 }, 1407 + { 320000000, 400000000, 480000000, 600000000 } 1408 + }, 1409 + 1410 + .reg = { "csid_lite0" }, 1411 + .interrupt = { "csid_lite0" }, 1412 + .csid = { 1413 + .is_lite = true, 1414 + .hw_ops = &csid_ops_gen2, 1415 + .parent_dev_ops = &vfe_parent_dev_ops, 1416 + .formats = &csid_formats_gen2 1417 + } 1418 + }, 1419 + /* CSID4 */ 1420 + { 1421 + .regulators = {}, 1422 + 1423 + .clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" }, 1424 + .clock_rate = { { 300000000, 400000000 }, 1425 + { 0 }, 1426 + { 320000000, 400000000, 480000000, 600000000 } 1427 + }, 1428 + 1429 + .reg = { "csid_lite1" }, 1430 + .interrupt = { "csid_lite1" }, 1431 + .csid = { 1432 + .is_lite = true, 1433 + .hw_ops = &csid_ops_gen2, 1434 + .parent_dev_ops = &vfe_parent_dev_ops, 1435 + .formats = &csid_formats_gen2 1436 + } 1437 + }, 1438 + }; 1439 + 1440 + static const struct camss_subdev_resources vfe_res_7280[] = { 1441 + /* VFE0 */ 1442 + { 1443 + .regulators = {}, 1444 + 1445 + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe0", 1446 + "vfe0_axi", "gcc_cam_hf_axi" }, 1447 + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, 1448 + { 80000000 }, 1449 + { 0 }, 1450 + { 380000000, 510000000, 637000000, 760000000 }, 1451 + { 0 }, 1452 + { 0 } }, 1453 + 1454 + .reg = { "vfe0" }, 1455 + .interrupt = { "vfe0" }, 1456 + .vfe = { 1457 + .line_num = 3, 1458 + .is_lite = false, 1459 + .has_pd = true, 1460 + .pd_name = "ife0", 1461 + .hw_ops = &vfe_ops_170, 1462 + .formats_rdi = &vfe_formats_rdi_845, 1463 + .formats_pix = &vfe_formats_pix_845 1464 + } 1465 + }, 1466 + /* VFE1 */ 1467 + { 1468 + .regulators = {}, 1469 + 1470 + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe1", 1471 + "vfe1_axi", "gcc_cam_hf_axi" }, 1472 + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, 1473 + { 80000000 }, 1474 + { 0 }, 1475 + { 380000000, 510000000, 637000000, 760000000 }, 1476 + { 0 }, 1477 + { 0 } }, 1478 + 1479 + .reg = { "vfe1" }, 1480 + .interrupt = { "vfe1" }, 1481 + .vfe = { 1482 + .line_num = 3, 1483 + .is_lite = false, 1484 + .has_pd = true, 1485 + .pd_name = "ife1", 1486 + .hw_ops = &vfe_ops_170, 1487 + .formats_rdi = &vfe_formats_rdi_845, 1488 + .formats_pix = &vfe_formats_pix_845 1489 + } 1490 + }, 1491 + /* VFE2 */ 1492 + { 1493 + .regulators = {}, 1494 + 1495 + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", "vfe2", 1496 + "vfe2_axi", "gcc_cam_hf_axi" }, 1497 + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, 1498 + { 80000000 }, 1499 + { 0 }, 1500 + { 380000000, 510000000, 637000000, 760000000 }, 1501 + { 0 }, 1502 + { 0 } }, 1503 + 1504 + .reg = { "vfe2" }, 1505 + .interrupt = { "vfe2" }, 1506 + .vfe = { 1507 + .line_num = 3, 1508 + .is_lite = false, 1509 + .hw_ops = &vfe_ops_170, 1510 + .has_pd = true, 1511 + .pd_name = "ife2", 1512 + .formats_rdi = &vfe_formats_rdi_845, 1513 + .formats_pix = &vfe_formats_pix_845 1514 + } 1515 + }, 1516 + /* VFE3 (lite) */ 1517 + { 1518 + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", 1519 + "vfe_lite0", "gcc_cam_hf_axi" }, 1520 + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, 1521 + { 80000000 }, 1522 + { 0 }, 1523 + { 320000000, 400000000, 480000000, 600000000 }, 1524 + { 0 } }, 1525 + 1526 + .regulators = {}, 1527 + .reg = { "vfe_lite0" }, 1528 + .interrupt = { "vfe_lite0" }, 1529 + .vfe = { 1530 + .line_num = 4, 1531 + .is_lite = true, 1532 + .hw_ops = &vfe_ops_170, 1533 + .formats_rdi = &vfe_formats_rdi_845, 1534 + .formats_pix = &vfe_formats_pix_845 1535 + } 1536 + }, 1537 + /* VFE4 (lite) */ 1538 + { 1539 + .clock = { "camnoc_axi", "cpas_ahb", "icp_ahb", 1540 + "vfe_lite1", "gcc_cam_hf_axi" }, 1541 + .clock_rate = { { 150000000, 240000000, 320000000, 400000000, 480000000 }, 1542 + { 80000000 }, 1543 + { 0 }, 1544 + { 320000000, 400000000, 480000000, 600000000 }, 1545 + { 0 } }, 1546 + 1547 + .regulators = {}, 1548 + .reg = { "vfe_lite1" }, 1549 + .interrupt = { "vfe_lite1" }, 1550 + .vfe = { 1551 + .line_num = 4, 1552 + .is_lite = true, 1553 + .hw_ops = &vfe_ops_170, 1554 + .formats_rdi = &vfe_formats_rdi_845, 1555 + .formats_pix = &vfe_formats_pix_845 1556 + } 1557 + }, 1558 + }; 1559 + 1560 + static const struct resources_icc icc_res_sc7280[] = { 1561 + { 1562 + .name = "ahb", 1563 + .icc_bw_tbl.avg = 38400, 1564 + .icc_bw_tbl.peak = 76800, 1565 + }, 1566 + { 1567 + .name = "hf_0", 1568 + .icc_bw_tbl.avg = 2097152, 1569 + .icc_bw_tbl.peak = 2097152, 1570 + }, 1571 + }; 1572 + 1269 1573 static const struct camss_subdev_resources csiphy_res_sc8280xp[] = { 1270 1574 /* CSIPHY0 */ 1271 1575 { ··· 2299 1995 2300 1996 /* 2301 1997 * camss_link_entities - Register subdev nodes and create links 1998 + * camss_link_err - print error in case link creation fails 1999 + * @src_name: name for source of the link 2000 + * @sink_name: name for sink of the link 2001 + */ 2002 + inline void camss_link_err(struct camss *camss, 2003 + const char *src_name, 2004 + const char *sink_name, 2005 + int ret) 2006 + { 2007 + dev_err(camss->dev, 2008 + "Failed to link %s->%s entities: %d\n", 2009 + src_name, 2010 + sink_name, 2011 + ret); 2012 + } 2013 + 2014 + /* 2015 + * camss_link_entities - Register subdev nodes and create links 2302 2016 * @camss: CAMSS device 2303 2017 * 2304 2018 * Return 0 on success or a negative error code on failure ··· 2334 2012 MSM_CSID_PAD_SINK, 2335 2013 0); 2336 2014 if (ret < 0) { 2337 - dev_err(camss->dev, 2338 - "Failed to link %s->%s entities: %d\n", 2339 - camss->csiphy[i].subdev.entity.name, 2340 - camss->csid[j].subdev.entity.name, 2341 - ret); 2015 + camss_link_err(camss, 2016 + camss->csiphy[i].subdev.entity.name, 2017 + camss->csid[j].subdev.entity.name, 2018 + ret); 2342 2019 return ret; 2343 2020 } 2344 2021 } ··· 2352 2031 MSM_ISPIF_PAD_SINK, 2353 2032 0); 2354 2033 if (ret < 0) { 2355 - dev_err(camss->dev, 2356 - "Failed to link %s->%s entities: %d\n", 2357 - camss->csid[i].subdev.entity.name, 2358 - camss->ispif->line[j].subdev.entity.name, 2359 - ret); 2034 + camss_link_err(camss, 2035 + camss->csid[i].subdev.entity.name, 2036 + camss->ispif->line[j].subdev.entity.name, 2037 + ret); 2360 2038 return ret; 2361 2039 } 2362 2040 } ··· 2373 2053 MSM_VFE_PAD_SINK, 2374 2054 0); 2375 2055 if (ret < 0) { 2376 - dev_err(camss->dev, 2377 - "Failed to link %s->%s entities: %d\n", 2378 - ispif->entity.name, 2379 - vfe->entity.name, 2380 - ret); 2056 + camss_link_err(camss, ispif->entity.name, 2057 + vfe->entity.name, 2058 + ret); 2381 2059 return ret; 2382 2060 } 2383 2061 } ··· 2392 2074 MSM_VFE_PAD_SINK, 2393 2075 0); 2394 2076 if (ret < 0) { 2395 - dev_err(camss->dev, 2396 - "Failed to link %s->%s entities: %d\n", 2397 - csid->entity.name, 2398 - vfe->entity.name, 2399 - ret); 2077 + camss_link_err(camss, csid->entity.name, 2078 + vfe->entity.name, 2079 + ret); 2400 2080 return ret; 2401 2081 } 2402 2082 } ··· 2543 2227 input, MSM_CSIPHY_PAD_SINK, 2544 2228 MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); 2545 2229 if (ret < 0) { 2546 - dev_err(camss->dev, 2547 - "Failed to link %s->%s entities: %d\n", 2548 - sensor->name, input->name, ret); 2230 + camss_link_err(camss, sensor->name, 2231 + input->name, 2232 + ret); 2549 2233 return ret; 2550 2234 } 2551 2235 } ··· 2938 2622 .link_entities = camss_link_entities 2939 2623 }; 2940 2624 2625 + static const struct camss_resources sc7280_resources = { 2626 + .version = CAMSS_7280, 2627 + .pd_name = "top", 2628 + .csiphy_res = csiphy_res_7280, 2629 + .csid_res = csid_res_7280, 2630 + .vfe_res = vfe_res_7280, 2631 + .icc_res = icc_res_sc7280, 2632 + .icc_path_num = ARRAY_SIZE(icc_res_sc7280), 2633 + .csiphy_num = ARRAY_SIZE(csiphy_res_7280), 2634 + .csid_num = ARRAY_SIZE(csid_res_7280), 2635 + .vfe_num = ARRAY_SIZE(vfe_res_7280), 2636 + .link_entities = camss_link_entities 2637 + }; 2638 + 2941 2639 static const struct of_device_id camss_dt_match[] = { 2942 2640 { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources }, 2943 2641 { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources }, 2944 2642 { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources }, 2643 + { .compatible = "qcom,sc7280-camss", .data = &sc7280_resources }, 2644 + { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, 2945 2645 { .compatible = "qcom,sdm660-camss", .data = &sdm660_resources }, 2946 2646 { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, 2947 2647 { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, 2948 - { .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources }, 2949 2648 { } 2950 2649 }; 2951 2650
+3 -2
drivers/media/platform/qcom/camss/camss.h
··· 77 77 }; 78 78 79 79 enum camss_version { 80 + CAMSS_660, 81 + CAMSS_7280, 80 82 CAMSS_8x16, 81 83 CAMSS_8x53, 82 84 CAMSS_8x96, 83 - CAMSS_660, 84 - CAMSS_845, 85 85 CAMSS_8250, 86 86 CAMSS_8280XP, 87 + CAMSS_845, 87 88 }; 88 89 89 90 enum icc_count {
+1
drivers/media/platform/qcom/venus/Kconfig
··· 3 3 depends on V4L_MEM2MEM_DRIVERS 4 4 depends on VIDEO_DEV && QCOM_SMEM 5 5 depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST 6 + select OF_DYNAMIC if ARCH_QCOM 6 7 select QCOM_MDT_LOADER if ARCH_QCOM 7 8 select QCOM_SCM 8 9 select VIDEOBUF2_DMA_CONTIG
+106 -7
drivers/media/platform/qcom/venus/core.c
··· 286 286 return ret; 287 287 } 288 288 289 + #if defined(CONFIG_OF_DYNAMIC) 290 + static int venus_add_video_core(struct venus_core *core, const char *node_name, 291 + const char *compat) 292 + { 293 + struct of_changeset *ocs = core->ocs; 294 + struct device *dev = core->dev; 295 + struct device_node *np, *enp; 296 + int ret; 297 + 298 + if (!node_name) 299 + return 0; 300 + 301 + enp = of_find_node_by_name(dev->of_node, node_name); 302 + if (enp) { 303 + of_node_put(enp); 304 + return 0; 305 + } 306 + 307 + np = of_changeset_create_node(ocs, dev->of_node, node_name); 308 + if (!np) { 309 + dev_err(dev, "Unable to create new node\n"); 310 + return -ENODEV; 311 + } 312 + 313 + ret = of_changeset_add_prop_string(ocs, np, "compatible", compat); 314 + if (ret) 315 + dev_err(dev, "unable to add %s\n", compat); 316 + 317 + of_node_put(np); 318 + 319 + return ret; 320 + } 321 + 322 + static int venus_add_dynamic_nodes(struct venus_core *core) 323 + { 324 + struct device *dev = core->dev; 325 + int ret; 326 + 327 + core->ocs = kmalloc(sizeof(*core->ocs), GFP_KERNEL); 328 + if (!core->ocs) 329 + return -ENOMEM; 330 + 331 + of_changeset_init(core->ocs); 332 + 333 + ret = venus_add_video_core(core, core->res->dec_nodename, "venus-decoder"); 334 + if (ret) 335 + goto err; 336 + 337 + ret = venus_add_video_core(core, core->res->enc_nodename, "venus-encoder"); 338 + if (ret) 339 + goto err; 340 + 341 + ret = of_changeset_apply(core->ocs); 342 + if (ret) { 343 + dev_err(dev, "applying changeset fail ret %d\n", ret); 344 + goto err; 345 + } 346 + 347 + return 0; 348 + err: 349 + of_changeset_destroy(core->ocs); 350 + kfree(core->ocs); 351 + core->ocs = NULL; 352 + return ret; 353 + } 354 + 355 + static void venus_remove_dynamic_nodes(struct venus_core *core) 356 + { 357 + if (core->ocs) { 358 + of_changeset_revert(core->ocs); 359 + of_changeset_destroy(core->ocs); 360 + kfree(core->ocs); 361 + } 362 + } 363 + #else 364 + static int venus_add_dynamic_nodes(struct venus_core *core) 365 + { 366 + return 0; 367 + } 368 + 369 + static void venus_remove_dynamic_nodes(struct venus_core *core) {} 370 + #endif 371 + 289 372 static int venus_probe(struct platform_device *pdev) 290 373 { 291 374 struct device *dev = &pdev->dev; ··· 448 365 if (ret < 0) 449 366 goto err_runtime_disable; 450 367 368 + if (core->res->dec_nodename || core->res->enc_nodename) { 369 + ret = venus_add_dynamic_nodes(core); 370 + if (ret) 371 + goto err_runtime_disable; 372 + } 373 + 451 374 ret = of_platform_populate(dev->of_node, NULL, NULL, dev); 452 375 if (ret) 453 - goto err_runtime_disable; 376 + goto err_remove_dynamic_nodes; 454 377 455 378 ret = venus_firmware_init(core); 456 379 if (ret) ··· 500 411 venus_firmware_deinit(core); 501 412 err_of_depopulate: 502 413 of_platform_depopulate(dev); 414 + err_remove_dynamic_nodes: 415 + venus_remove_dynamic_nodes(core); 503 416 err_runtime_disable: 504 417 pm_runtime_put_noidle(dev); 505 418 pm_runtime_disable(dev); ··· 533 442 of_platform_depopulate(dev); 534 443 535 444 venus_firmware_deinit(core); 445 + 446 + venus_remove_dynamic_nodes(core); 536 447 537 448 pm_runtime_put_sync(dev); 538 449 pm_runtime_disable(dev); ··· 599 506 void venus_close_common(struct venus_inst *inst) 600 507 { 601 508 /* 602 - * First, remove the inst from the ->instances list, so that 603 - * to_instance() will return NULL. 604 - */ 605 - hfi_session_destroy(inst); 606 - /* 607 - * Second, make sure we don't have IRQ/IRQ-thread currently running 509 + * Make sure we don't have IRQ/IRQ-thread currently running 608 510 * or pending execution, which would race with the inst destruction. 609 511 */ 610 512 synchronize_irq(inst->core->irq); 611 513 612 514 v4l2_m2m_ctx_release(inst->m2m_ctx); 613 515 v4l2_m2m_release(inst->m2m_dev); 516 + hfi_session_destroy(inst); 614 517 v4l2_fh_del(&inst->fh); 615 518 v4l2_fh_exit(&inst->fh); 616 519 v4l2_ctrl_handler_free(&inst->ctrl_handler); ··· 671 582 .vmem_addr = 0, 672 583 .dma_mask = 0xddc00000 - 1, 673 584 .fwname = "qcom/venus-1.8/venus.mbn", 585 + .dec_nodename = "video-decoder", 586 + .enc_nodename = "video-encoder", 674 587 }; 675 588 676 589 static const struct freq_tbl msm8996_freq_table[] = { ··· 882 791 .cp_nonpixel_start = 0x1000000, 883 792 .cp_nonpixel_size = 0x24800000, 884 793 .fwname = "qcom/venus-5.2/venus.mbn", 794 + .dec_nodename = "video-core0", 795 + .enc_nodename = "video-core1", 885 796 }; 886 797 887 798 static const struct freq_tbl sc7180_freq_table[] = { ··· 932 839 .cp_nonpixel_start = 0x1000000, 933 840 .cp_nonpixel_size = 0x24800000, 934 841 .fwname = "qcom/venus-5.4/venus.mbn", 842 + .dec_nodename = "video-decoder", 843 + .enc_nodename = "video-encoder", 935 844 }; 936 845 937 846 static const struct freq_tbl sm8250_freq_table[] = { ··· 989 894 .vmem_addr = 0, 990 895 .dma_mask = 0xe0000000 - 1, 991 896 .fwname = "qcom/vpu-1.0/venus.mbn", 897 + .dec_nodename = "video-decoder", 898 + .enc_nodename = "video-encoder", 992 899 }; 993 900 994 901 static const struct freq_tbl sc7280_freq_table[] = { ··· 1053 956 .cp_nonpixel_start = 0x1000000, 1054 957 .cp_nonpixel_size = 0x24800000, 1055 958 .fwname = "qcom/vpu-2.0/venus.mbn", 959 + .dec_nodename = "video-decoder", 960 + .enc_nodename = "video-encoder", 1056 961 }; 1057 962 1058 963 static const struct of_device_id venus_dt_match[] = {
+4
drivers/media/platform/qcom/venus/core.h
··· 90 90 u32 cp_nonpixel_start; 91 91 u32 cp_nonpixel_size; 92 92 const char *fwname; 93 + const char *enc_nodename; 94 + const char *dec_nodename; 93 95 }; 94 96 95 97 enum venus_fmt { ··· 171 169 * @root: debugfs root directory 172 170 * @venus_ver: the venus firmware version 173 171 * @dump_core: a flag indicating that a core dump is required 172 + * @ocs: OF changeset pointer 174 173 */ 175 174 struct venus_core { 176 175 void __iomem *base; ··· 234 231 u32 rev; 235 232 } venus_ver; 236 233 unsigned long dump_core; 234 + struct of_changeset *ocs; 237 235 }; 238 236 239 237 struct vdec_controls {
-23
drivers/media/platform/qcom/venus/hfi.c
··· 138 138 return core->ops->core_trigger_ssr(core, type); 139 139 } 140 140 141 - int hfi_core_ping(struct venus_core *core) 142 - { 143 - int ret; 144 - 145 - mutex_lock(&core->lock); 146 - 147 - ret = core->ops->core_ping(core, 0xbeef); 148 - if (ret) 149 - goto unlock; 150 - 151 - ret = wait_for_completion_timeout(&core->done, TIMEOUT); 152 - if (!ret) { 153 - ret = -ETIMEDOUT; 154 - goto unlock; 155 - } 156 - ret = 0; 157 - if (core->error != HFI_ERR_NONE) 158 - ret = -ENODEV; 159 - unlock: 160 - mutex_unlock(&core->lock); 161 - return ret; 162 - } 163 - 164 141 static int wait_session_msg(struct venus_inst *inst) 165 142 { 166 143 int ret;
-2
drivers/media/platform/qcom/venus/hfi.h
··· 108 108 struct hfi_ops { 109 109 int (*core_init)(struct venus_core *core); 110 110 int (*core_deinit)(struct venus_core *core); 111 - int (*core_ping)(struct venus_core *core, u32 cookie); 112 111 int (*core_trigger_ssr)(struct venus_core *core, u32 trigger_type); 113 112 114 113 int (*session_init)(struct venus_inst *inst, u32 session_type, ··· 151 152 int hfi_core_suspend(struct venus_core *core); 152 153 int hfi_core_resume(struct venus_core *core, bool force); 153 154 int hfi_core_trigger_ssr(struct venus_core *core, u32 type); 154 - int hfi_core_ping(struct venus_core *core); 155 155 int hfi_session_create(struct venus_inst *inst, const struct hfi_inst_ops *ops); 156 156 void hfi_session_destroy(struct venus_inst *inst); 157 157 int hfi_session_init(struct venus_inst *inst, u32 pixfmt);
-11
drivers/media/platform/qcom/venus/hfi_venus.c
··· 1178 1178 return 0; 1179 1179 } 1180 1180 1181 - static int venus_core_ping(struct venus_core *core, u32 cookie) 1182 - { 1183 - struct venus_hfi_device *hdev = to_hfi_priv(core); 1184 - struct hfi_sys_ping_pkt pkt; 1185 - 1186 - pkt_sys_ping(&pkt, cookie); 1187 - 1188 - return venus_iface_cmdq_write(hdev, &pkt, false); 1189 - } 1190 - 1191 1181 static int venus_core_trigger_ssr(struct venus_core *core, u32 trigger_type) 1192 1182 { 1193 1183 struct venus_hfi_device *hdev = to_hfi_priv(core); ··· 1629 1639 static const struct hfi_ops venus_hfi_ops = { 1630 1640 .core_init = venus_core_init, 1631 1641 .core_deinit = venus_core_deinit, 1632 - .core_ping = venus_core_ping, 1633 1642 .core_trigger_ssr = venus_core_trigger_ssr, 1634 1643 1635 1644 .session_init = venus_session_init,
+9 -9
drivers/media/platform/qcom/venus/vdec.c
··· 1697 1697 if (ret) 1698 1698 goto err_free; 1699 1699 1700 - ret = hfi_session_create(inst, &vdec_hfi_ops); 1701 - if (ret) 1702 - goto err_ctrl_deinit; 1703 - 1704 1700 vdec_inst_init(inst); 1705 1701 1706 1702 ida_init(&inst->dpb_ids); ··· 1708 1712 inst->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops); 1709 1713 if (IS_ERR(inst->m2m_dev)) { 1710 1714 ret = PTR_ERR(inst->m2m_dev); 1711 - goto err_session_destroy; 1715 + goto err_ctrl_deinit; 1712 1716 } 1713 1717 1714 1718 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1715 1719 if (IS_ERR(inst->m2m_ctx)) { 1716 1720 ret = PTR_ERR(inst->m2m_ctx); 1717 - goto err_m2m_release; 1721 + goto err_m2m_dev_release; 1718 1722 } 1723 + 1724 + ret = hfi_session_create(inst, &vdec_hfi_ops); 1725 + if (ret) 1726 + goto err_m2m_ctx_release; 1719 1727 1720 1728 v4l2_fh_init(&inst->fh, core->vdev_dec); 1721 1729 ··· 1730 1730 1731 1731 return 0; 1732 1732 1733 - err_m2m_release: 1733 + err_m2m_ctx_release: 1734 + v4l2_m2m_ctx_release(inst->m2m_ctx); 1735 + err_m2m_dev_release: 1734 1736 v4l2_m2m_release(inst->m2m_dev); 1735 - err_session_destroy: 1736 - hfi_session_destroy(inst); 1737 1737 err_ctrl_deinit: 1738 1738 v4l2_ctrl_handler_free(&inst->ctrl_handler); 1739 1739 err_free:
+9 -9
drivers/media/platform/qcom/venus/venc.c
··· 1492 1492 if (ret) 1493 1493 goto err_free; 1494 1494 1495 - ret = hfi_session_create(inst, &venc_hfi_ops); 1496 - if (ret) 1497 - goto err_ctrl_deinit; 1498 - 1499 1495 venc_inst_init(inst); 1500 1496 1501 1497 /* ··· 1501 1505 inst->m2m_dev = v4l2_m2m_init(&venc_m2m_ops); 1502 1506 if (IS_ERR(inst->m2m_dev)) { 1503 1507 ret = PTR_ERR(inst->m2m_dev); 1504 - goto err_session_destroy; 1508 + goto err_ctrl_deinit; 1505 1509 } 1506 1510 1507 1511 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1508 1512 if (IS_ERR(inst->m2m_ctx)) { 1509 1513 ret = PTR_ERR(inst->m2m_ctx); 1510 - goto err_m2m_release; 1514 + goto err_m2m_dev_release; 1511 1515 } 1516 + 1517 + ret = hfi_session_create(inst, &venc_hfi_ops); 1518 + if (ret) 1519 + goto err_m2m_ctx_release; 1512 1520 1513 1521 v4l2_fh_init(&inst->fh, core->vdev_enc); 1514 1522 ··· 1523 1523 1524 1524 return 0; 1525 1525 1526 - err_m2m_release: 1526 + err_m2m_ctx_release: 1527 + v4l2_m2m_ctx_release(inst->m2m_ctx); 1528 + err_m2m_dev_release: 1527 1529 v4l2_m2m_release(inst->m2m_dev); 1528 - err_session_destroy: 1529 - hfi_session_destroy(inst); 1530 1530 err_ctrl_deinit: 1531 1531 v4l2_ctrl_handler_free(&inst->ctrl_handler); 1532 1532 err_free:
+78 -13
drivers/media/platform/renesas/rcar-csi2.c
··· 183 183 #define V4H_CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_REG(n) (0x23840 + ((n) * 2)) /* n = 0 - 11 */ 184 184 #define V4H_CORE_DIG_RW_COMMON_REG(n) (0x23880 + ((n) * 2)) /* n = 0 - 15 */ 185 185 #define V4H_CORE_DIG_ANACTRL_RW_COMMON_ANACTRL_REG(n) (0x239e0 + ((n) * 2)) /* n = 0 - 3 */ 186 - #define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400 187 186 #define V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG 0x2a60c 188 187 189 188 /* V4H C-PHY */ 190 189 #define V4H_CORE_DIG_RW_TRIO0_REG(n) (0x22100 + ((n) * 2)) /* n = 0 - 3 */ 191 190 #define V4H_CORE_DIG_RW_TRIO1_REG(n) (0x22500 + ((n) * 2)) /* n = 0 - 3 */ 192 191 #define V4H_CORE_DIG_RW_TRIO2_REG(n) (0x22900 + ((n) * 2)) /* n = 0 - 3 */ 192 + #define V4H_CORE_DIG_CLANE_0_RW_CFG_0_REG 0x2a000 193 193 #define V4H_CORE_DIG_CLANE_0_RW_LP_0_REG 0x2a080 194 194 #define V4H_CORE_DIG_CLANE_0_RW_HS_RX_REG(n) (0x2a100 + ((n) * 2)) /* n = 0 - 6 */ 195 + #define V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG 0x2a400 195 196 #define V4H_CORE_DIG_CLANE_1_RW_LP_0_REG 0x2a480 196 197 #define V4H_CORE_DIG_CLANE_1_RW_HS_RX_REG(n) (0x2a500 + ((n) * 2)) /* n = 0 - 6 */ 198 + #define V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG 0x2a800 197 199 #define V4H_CORE_DIG_CLANE_2_RW_LP_0_REG 0x2a880 198 200 #define V4H_CORE_DIG_CLANE_2_RW_HS_RX_REG(n) (0x2a900 + ((n) * 2)) /* n = 0 - 6 */ 199 201 ··· 674 672 return NULL; 675 673 } 676 674 675 + struct rcsi2_cphy_line_order { 676 + enum v4l2_mbus_csi2_cphy_line_orders_type order; 677 + u16 cfg; 678 + u16 ctrl29; 679 + }; 680 + 681 + static const struct rcsi2_cphy_line_order rcsi2_cphy_line_orders[] = { 682 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ABC, .cfg = 0x0, .ctrl29 = 0x0 }, 683 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ACB, .cfg = 0xa, .ctrl29 = 0x1 }, 684 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BAC, .cfg = 0xc, .ctrl29 = 0x1 }, 685 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BCA, .cfg = 0x5, .ctrl29 = 0x0 }, 686 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CAB, .cfg = 0x3, .ctrl29 = 0x0 }, 687 + { .order = V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CBA, .cfg = 0x9, .ctrl29 = 0x1 } 688 + }; 689 + 677 690 enum rcar_csi2_pads { 678 691 RCAR_CSI2_SINK, 679 692 RCAR_CSI2_SOURCE_VC0, ··· 739 722 bool cphy; 740 723 unsigned short lanes; 741 724 unsigned char lane_swap[4]; 725 + enum v4l2_mbus_csi2_cphy_line_orders_type line_orders[3]; 742 726 }; 743 727 744 728 static inline struct rcar_csi2 *sd_to_csi2(struct v4l2_subdev *sd) ··· 772 754 iowrite32(data, priv->base + reg); 773 755 } 774 756 757 + static u16 rcsi2_read16(struct rcar_csi2 *priv, unsigned int reg) 758 + { 759 + return ioread16(priv->base + reg); 760 + } 761 + 775 762 static void rcsi2_write16(struct rcar_csi2 *priv, unsigned int reg, u16 data) 776 763 { 777 764 iowrite16(data, priv->base + reg); 765 + } 766 + 767 + static void rcsi2_modify16(struct rcar_csi2 *priv, unsigned int reg, u16 data, u16 mask) 768 + { 769 + u16 val; 770 + 771 + val = rcsi2_read16(priv, reg) & ~mask; 772 + rcsi2_write16(priv, reg, val | data); 778 773 } 779 774 780 775 static int rcsi2_phtw_write(struct rcar_csi2 *priv, u8 data, u8 code) ··· 1143 1112 return 0; 1144 1113 } 1145 1114 1115 + static void rsci2_set_line_order(struct rcar_csi2 *priv, 1116 + enum v4l2_mbus_csi2_cphy_line_orders_type order, 1117 + unsigned int cfgreg, unsigned int ctrlreg) 1118 + { 1119 + const struct rcsi2_cphy_line_order *info = NULL; 1120 + 1121 + for (unsigned int i = 0; i < ARRAY_SIZE(rcsi2_cphy_line_orders); i++) { 1122 + if (rcsi2_cphy_line_orders[i].order == order) { 1123 + info = &rcsi2_cphy_line_orders[i]; 1124 + break; 1125 + } 1126 + } 1127 + 1128 + if (!info) 1129 + return; 1130 + 1131 + rcsi2_modify16(priv, cfgreg, info->cfg, 0x000f); 1132 + rcsi2_modify16(priv, ctrlreg, info->ctrl29, 0x0100); 1133 + } 1134 + 1146 1135 static int rcsi2_wait_phy_start_v4h(struct rcar_csi2 *priv, u32 match) 1147 1136 { 1148 1137 unsigned int timeout; ··· 1240 1189 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO1_REG(1), conf->trio1); 1241 1190 rcsi2_write16(priv, V4H_CORE_DIG_RW_TRIO2_REG(1), conf->trio1); 1242 1191 1243 - /* 1244 - * Configure pin-swap. 1245 - * TODO: This registers is not documented yet, the values should depend 1246 - * on the 'clock-lanes' and 'data-lanes' devicetree properties. 1247 - */ 1248 - rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG, 0xf5); 1192 + /* Configure data line order. */ 1193 + rsci2_set_line_order(priv, priv->line_orders[0], 1194 + V4H_CORE_DIG_CLANE_0_RW_CFG_0_REG, 1195 + V4H_CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_REG(9)); 1196 + rsci2_set_line_order(priv, priv->line_orders[1], 1197 + V4H_CORE_DIG_CLANE_1_RW_CFG_0_REG, 1198 + V4H_CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_REG(9)); 1199 + rsci2_set_line_order(priv, priv->line_orders[2], 1200 + V4H_CORE_DIG_CLANE_2_RW_CFG_0_REG, 1201 + V4H_CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_REG(9)); 1202 + 1203 + /* TODO: This registers is not documented. */ 1249 1204 rcsi2_write16(priv, V4H_CORE_DIG_CLANE_1_RW_HS_TX_6_REG, 0x5000); 1250 1205 1251 1206 /* Leave Shutdown mode */ ··· 1406 1349 static const struct phtw_value step2[] = { 1407 1350 { .data = 0x00, .code = 0x00 }, 1408 1351 { .data = 0x80, .code = 0xe0 }, 1409 - { .data = 0x01, .code = 0xe1 }, 1352 + { .data = 0x31, .code = 0xe1 }, 1410 1353 { .data = 0x06, .code = 0x00 }, 1411 - { .data = 0x0f, .code = 0x11 }, 1354 + { .data = 0x11, .code = 0x11 }, 1412 1355 { .data = 0x08, .code = 0x00 }, 1413 - { .data = 0x0f, .code = 0x11 }, 1356 + { .data = 0x11, .code = 0x11 }, 1414 1357 { .data = 0x0a, .code = 0x00 }, 1415 - { .data = 0x0f, .code = 0x11 }, 1358 + { .data = 0x11, .code = 0x11 }, 1416 1359 { .data = 0x0c, .code = 0x00 }, 1417 - { .data = 0x0f, .code = 0x11 }, 1360 + { .data = 0x11, .code = 0x11 }, 1418 1361 { .data = 0x01, .code = 0x00 }, 1419 1362 { .data = 0x31, .code = 0xaa }, 1420 1363 { .data = 0x05, .code = 0x00 }, ··· 1425 1368 { .data = 0x05, .code = 0x09 }, 1426 1369 { .data = 0x0b, .code = 0x00 }, 1427 1370 { .data = 0x05, .code = 0x09 }, 1371 + }; 1372 + 1373 + static const struct phtw_value step3[] = { 1374 + { .data = 0x01, .code = 0x00 }, 1375 + { .data = 0x06, .code = 0xab }, 1428 1376 }; 1429 1377 1430 1378 if (priv->info->hsfreqrange) { ··· 1462 1400 return ret; 1463 1401 } 1464 1402 1465 - return ret; 1403 + return rcsi2_phtw_write_array(priv, step3, ARRAY_SIZE(step3)); 1466 1404 } 1467 1405 1468 1406 static int rcsi2_start_receiver_v4m(struct rcar_csi2 *priv, ··· 1793 1731 return -EINVAL; 1794 1732 } 1795 1733 } 1734 + 1735 + for (i = 0; i < ARRAY_SIZE(priv->line_orders); i++) 1736 + priv->line_orders[i] = vep->bus.mipi_csi2.line_orders[i]; 1796 1737 1797 1738 return 0; 1798 1739 }
+1 -1
drivers/media/platform/renesas/rzg2l-cru/rzg2l-video.c
··· 558 558 goto assert_aresetn; 559 559 } 560 560 561 - /* Allocate scratch buffer. */ 561 + /* Allocate scratch buffer */ 562 562 cru->scratch = dma_alloc_coherent(cru->dev, cru->format.sizeimage, 563 563 &cru->scratch_phys, GFP_KERNEL); 564 564 if (!cru->scratch) {
+1 -1
drivers/media/platform/rockchip/rga/rga-buf.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd 3 + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. 4 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 5 */ 6 6
+1 -1
drivers/media/platform/rockchip/rga/rga-hw.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Copyright (C) Rockchip Electronics Co., Ltd. 4 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 5 */ 6 6
+1 -1
drivers/media/platform/rockchip/rga/rga-hw.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Copyright (C) Rockchip Electronics Co., Ltd. 4 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 5 */ 6 6 #ifndef __RGA_HW_H__
+1 -1
drivers/media/platform/rockchip/rga/rga.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Copyright (C) Rockchip Electronics Co., Ltd. 4 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 5 */ 6 6
+1 -1
drivers/media/platform/rockchip/rga/rga.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd 3 + * Copyright (C) Rockchip Electronics Co., Ltd. 4 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 5 */ 6 6 #ifndef __RGA_H__
+1 -3
drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
··· 35 35 #define RKISP1_SP_DEV_NAME RKISP1_DRIVER_NAME "_selfpath" 36 36 #define RKISP1_MP_DEV_NAME RKISP1_DRIVER_NAME "_mainpath" 37 37 38 - #define RKISP1_MIN_BUFFERS_NEEDED 3 39 - 40 38 enum rkisp1_plane { 41 39 RKISP1_PLANE_Y = 0, 42 40 RKISP1_PLANE_CB = 1, ··· 1559 1561 q->ops = &rkisp1_vb2_ops; 1560 1562 q->mem_ops = &vb2_dma_contig_memops; 1561 1563 q->buf_struct_size = sizeof(struct rkisp1_buffer); 1562 - q->min_queued_buffers = RKISP1_MIN_BUFFERS_NEEDED; 1564 + q->min_queued_buffers = 1; 1563 1565 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1564 1566 q->lock = &node->vlock; 1565 1567 q->dev = cap->rkisp1->dev;
+3
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
··· 228 228 break; 229 229 } 230 230 231 + if (ret) 232 + break; 233 + 231 234 /* Parse the endpoint and validate the bus type. */ 232 235 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 233 236 if (ret) {
-131
drivers/media/platform/samsung/exynos4-is/fimc-is-errno.c
··· 12 12 13 13 #include "fimc-is-errno.h" 14 14 15 - const char *fimc_is_param_strerr(unsigned int error) 16 - { 17 - switch (error) { 18 - case ERROR_COMMON_CMD: 19 - return "ERROR_COMMON_CMD: Invalid Command"; 20 - case ERROR_COMMON_PARAMETER: 21 - return "ERROR_COMMON_PARAMETER: Invalid Parameter"; 22 - case ERROR_COMMON_SETFILE_LOAD: 23 - return "ERROR_COMMON_SETFILE_LOAD: Illegal Setfile Loading"; 24 - case ERROR_COMMON_SETFILE_ADJUST: 25 - return "ERROR_COMMON_SETFILE_ADJUST: Setfile isn't adjusted"; 26 - case ERROR_COMMON_SETFILE_INDEX: 27 - return "ERROR_COMMON_SETFILE_INDEX: Invalid setfile index"; 28 - case ERROR_COMMON_INPUT_PATH: 29 - return "ERROR_COMMON_INPUT_PATH: Input path can be changed in ready state"; 30 - case ERROR_COMMON_INPUT_INIT: 31 - return "ERROR_COMMON_INPUT_INIT: IP can not start if input path is not set"; 32 - case ERROR_COMMON_OUTPUT_PATH: 33 - return "ERROR_COMMON_OUTPUT_PATH: Output path can be changed in ready state (stop)"; 34 - case ERROR_COMMON_OUTPUT_INIT: 35 - return "ERROR_COMMON_OUTPUT_INIT: IP can not start if output path is not set"; 36 - case ERROR_CONTROL_BYPASS: 37 - return "ERROR_CONTROL_BYPASS"; 38 - case ERROR_OTF_INPUT_FORMAT: 39 - return "ERROR_OTF_INPUT_FORMAT: Invalid format (DRC: YUV444, FD: YUV444, 422, 420)"; 40 - case ERROR_OTF_INPUT_WIDTH: 41 - return "ERROR_OTF_INPUT_WIDTH: Invalid width (DRC: 128~8192, FD: 32~8190)"; 42 - case ERROR_OTF_INPUT_HEIGHT: 43 - return "ERROR_OTF_INPUT_HEIGHT: Invalid bit-width (DRC: 8~12bits, FD: 8bit)"; 44 - case ERROR_OTF_INPUT_BIT_WIDTH: 45 - return "ERROR_OTF_INPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)"; 46 - case ERROR_DMA_INPUT_WIDTH: 47 - return "ERROR_DMA_INPUT_WIDTH: Invalid width (DRC: 128~8192, FD: 32~8190)"; 48 - case ERROR_DMA_INPUT_HEIGHT: 49 - return "ERROR_DMA_INPUT_HEIGHT: Invalid height (DRC: 64~8192, FD: 16~8190)"; 50 - case ERROR_DMA_INPUT_FORMAT: 51 - return "ERROR_DMA_INPUT_FORMAT: Invalid format (DRC: YUV444 or YUV422, FD: YUV444,422,420)"; 52 - case ERROR_DMA_INPUT_BIT_WIDTH: 53 - return "ERROR_DMA_INPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)"; 54 - case ERROR_DMA_INPUT_ORDER: 55 - return "ERROR_DMA_INPUT_ORDER: Invalid order(DRC: YYCbCr,YCbYCr,FD:NO,YYCbCr,YCbYCr,CbCr,CrCb)"; 56 - case ERROR_DMA_INPUT_PLANE: 57 - return "ERROR_DMA_INPUT_PLANE: Invalid plane (DRC: 3, FD: 1, 2, 3)"; 58 - case ERROR_OTF_OUTPUT_WIDTH: 59 - return "ERROR_OTF_OUTPUT_WIDTH: Invalid width (DRC: 128~8192)"; 60 - case ERROR_OTF_OUTPUT_HEIGHT: 61 - return "ERROR_OTF_OUTPUT_HEIGHT: Invalid height (DRC: 64~8192)"; 62 - case ERROR_OTF_OUTPUT_FORMAT: 63 - return "ERROR_OTF_OUTPUT_FORMAT: Invalid format (DRC: YUV444)"; 64 - case ERROR_OTF_OUTPUT_BIT_WIDTH: 65 - return "ERROR_OTF_OUTPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)"; 66 - case ERROR_DMA_OUTPUT_WIDTH: 67 - return "ERROR_DMA_OUTPUT_WIDTH"; 68 - case ERROR_DMA_OUTPUT_HEIGHT: 69 - return "ERROR_DMA_OUTPUT_HEIGHT"; 70 - case ERROR_DMA_OUTPUT_FORMAT: 71 - return "ERROR_DMA_OUTPUT_FORMAT"; 72 - case ERROR_DMA_OUTPUT_BIT_WIDTH: 73 - return "ERROR_DMA_OUTPUT_BIT_WIDTH"; 74 - case ERROR_DMA_OUTPUT_PLANE: 75 - return "ERROR_DMA_OUTPUT_PLANE"; 76 - case ERROR_DMA_OUTPUT_ORDER: 77 - return "ERROR_DMA_OUTPUT_ORDER"; 78 - 79 - /* Sensor Error(100~199) */ 80 - case ERROR_SENSOR_I2C_FAIL: 81 - return "ERROR_SENSOR_I2C_FAIL"; 82 - case ERROR_SENSOR_INVALID_FRAMERATE: 83 - return "ERROR_SENSOR_INVALID_FRAMERATE"; 84 - case ERROR_SENSOR_INVALID_EXPOSURETIME: 85 - return "ERROR_SENSOR_INVALID_EXPOSURETIME"; 86 - case ERROR_SENSOR_INVALID_SIZE: 87 - return "ERROR_SENSOR_INVALID_SIZE"; 88 - case ERROR_SENSOR_INVALID_SETTING: 89 - return "ERROR_SENSOR_INVALID_SETTING"; 90 - case ERROR_SENSOR_ACTUATOR_INIT_FAIL: 91 - return "ERROR_SENSOR_ACTUATOR_INIT_FAIL"; 92 - case ERROR_SENSOR_INVALID_AF_POS: 93 - return "ERROR_SENSOR_INVALID_AF_POS"; 94 - case ERROR_SENSOR_UNSUPPORT_FUNC: 95 - return "ERROR_SENSOR_UNSUPPORT_FUNC"; 96 - case ERROR_SENSOR_UNSUPPORT_PERI: 97 - return "ERROR_SENSOR_UNSUPPORT_PERI"; 98 - case ERROR_SENSOR_UNSUPPORT_AF: 99 - return "ERROR_SENSOR_UNSUPPORT_AF"; 100 - 101 - /* ISP Error (200~299) */ 102 - case ERROR_ISP_AF_BUSY: 103 - return "ERROR_ISP_AF_BUSY"; 104 - case ERROR_ISP_AF_INVALID_COMMAND: 105 - return "ERROR_ISP_AF_INVALID_COMMAND"; 106 - case ERROR_ISP_AF_INVALID_MODE: 107 - return "ERROR_ISP_AF_INVALID_MODE"; 108 - 109 - /* DRC Error (300~399) */ 110 - /* FD Error (400~499) */ 111 - case ERROR_FD_CONFIG_MAX_NUMBER_STATE: 112 - return "ERROR_FD_CONFIG_MAX_NUMBER_STATE"; 113 - case ERROR_FD_CONFIG_MAX_NUMBER_INVALID: 114 - return "ERROR_FD_CONFIG_MAX_NUMBER_INVALID"; 115 - case ERROR_FD_CONFIG_YAW_ANGLE_STATE: 116 - return "ERROR_FD_CONFIG_YAW_ANGLE_STATE"; 117 - case ERROR_FD_CONFIG_YAW_ANGLE_INVALID: 118 - return "ERROR_FD_CONFIG_YAW_ANGLE_INVALID\n"; 119 - case ERROR_FD_CONFIG_ROLL_ANGLE_STATE: 120 - return "ERROR_FD_CONFIG_ROLL_ANGLE_STATE"; 121 - case ERROR_FD_CONFIG_ROLL_ANGLE_INVALID: 122 - return "ERROR_FD_CONFIG_ROLL_ANGLE_INVALID"; 123 - case ERROR_FD_CONFIG_SMILE_MODE_INVALID: 124 - return "ERROR_FD_CONFIG_SMILE_MODE_INVALID"; 125 - case ERROR_FD_CONFIG_BLINK_MODE_INVALID: 126 - return "ERROR_FD_CONFIG_BLINK_MODE_INVALID"; 127 - case ERROR_FD_CONFIG_EYES_DETECT_INVALID: 128 - return "ERROR_FD_CONFIG_EYES_DETECT_INVALID"; 129 - case ERROR_FD_CONFIG_MOUTH_DETECT_INVALID: 130 - return "ERROR_FD_CONFIG_MOUTH_DETECT_INVALID"; 131 - case ERROR_FD_CONFIG_ORIENTATION_STATE: 132 - return "ERROR_FD_CONFIG_ORIENTATION_STATE"; 133 - case ERROR_FD_CONFIG_ORIENTATION_INVALID: 134 - return "ERROR_FD_CONFIG_ORIENTATION_INVALID"; 135 - case ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID: 136 - return "ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID"; 137 - case ERROR_FD_RESULT: 138 - return "ERROR_FD_RESULT"; 139 - case ERROR_FD_MODE: 140 - return "ERROR_FD_MODE"; 141 - default: 142 - return "Unknown"; 143 - } 144 - } 145 - 146 15 const char *fimc_is_strerr(unsigned int error) 147 16 { 148 17 error &= ~IS_ERROR_TIME_OUT_FLAG;
-1
drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h
··· 240 240 }; 241 241 242 242 const char *fimc_is_strerr(unsigned int error); 243 - const char *fimc_is_param_strerr(unsigned int error); 244 243 245 244 #endif /* FIMC_IS_ERR_H_ */
-9
drivers/media/platform/samsung/exynos4-is/fimc-is-param.c
··· 204 204 return ret; 205 205 } 206 206 207 - void __is_get_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf) 208 - { 209 - struct isp_param *isp; 210 - 211 - isp = &is->config[is->config_index].isp; 212 - mf->width = isp->otf_input.width; 213 - mf->height = isp->otf_input.height; 214 - } 215 - 216 207 void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf) 217 208 { 218 209 unsigned int index = is->config_index;
-1
drivers/media/platform/samsung/exynos4-is/fimc-is-param.h
··· 994 994 unsigned int __get_pending_param_count(struct fimc_is *is); 995 995 996 996 int __is_hw_update_params(struct fimc_is *is); 997 - void __is_get_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf); 998 997 void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf); 999 998 void __is_set_sensor(struct fimc_is *is, int fps); 1000 999 void __is_set_isp_aa_ae(struct fimc_is *is);
+8 -2
drivers/media/platform/samsung/exynos4-is/mipi-csis.c
··· 940 940 state->supplies); 941 941 goto unlock; 942 942 } 943 - clk_enable(state->clock[CSIS_CLK_GATE]); 943 + ret = clk_enable(state->clock[CSIS_CLK_GATE]); 944 + if (ret) { 945 + phy_power_off(state->phy); 946 + regulator_bulk_disable(CSIS_NUM_SUPPLIES, 947 + state->supplies); 948 + goto unlock; 949 + } 944 950 } 945 951 if (state->flags & ST_STREAMING) 946 952 s5pcsis_start_stream(state); 947 953 948 954 state->flags &= ~ST_SUSPENDED; 949 - unlock: 955 + unlock: 950 956 mutex_unlock(&state->lock); 951 957 return ret ? -EAGAIN : 0; 952 958 }
+11 -2
drivers/media/platform/samsung/s3c-camif/camif-core.c
··· 527 527 static int s3c_camif_runtime_resume(struct device *dev) 528 528 { 529 529 struct camif_dev *camif = dev_get_drvdata(dev); 530 + int ret; 530 531 531 - clk_enable(camif->clock[CLK_GATE]); 532 + ret = clk_enable(camif->clock[CLK_GATE]); 533 + if (ret) 534 + return ret; 535 + 532 536 /* null op on s3c244x */ 533 - clk_enable(camif->clock[CLK_CAM]); 537 + ret = clk_enable(camif->clock[CLK_CAM]); 538 + if (ret) { 539 + clk_disable(camif->clock[CLK_GATE]); 540 + return ret; 541 + } 542 + 534 543 return 0; 535 544 } 536 545
+5 -2
drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
··· 774 774 int ret = 0; 775 775 776 776 mfc_debug_enter(); 777 - if (mutex_lock_interruptible(&dev->mfc_mutex)) 778 - return -ERESTARTSYS; 777 + if (mutex_lock_interruptible(&dev->mfc_mutex)) { 778 + ret = -ERESTARTSYS; 779 + goto err_enter; 780 + } 779 781 dev->num_inst++; /* It is guarded by mfc_mutex in vfd */ 780 782 /* Allocate memory for context */ 781 783 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); ··· 948 946 err_alloc: 949 947 dev->num_inst--; 950 948 mutex_unlock(&dev->mfc_mutex); 949 + err_enter: 951 950 mfc_debug_leave(); 952 951 return ret; 953 952 }
+14
drivers/media/platform/st/stm32/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 # V4L drivers 4 + config VIDEO_STM32_CSI 5 + tristate "STM32 Camera Serial Interface (CSI) support" 6 + depends on V4L_PLATFORM_DRIVERS 7 + depends on VIDEO_DEV && OF 8 + depends on ARCH_STM32 || COMPILE_TEST 9 + select MEDIA_CONTROLLER 10 + select V4L2_FWNODE 11 + help 12 + This module makes the STM32 Camera Serial Interface (CSI) 13 + available as a v4l2 device. 14 + 15 + To compile this driver as a module, choose M here: the module 16 + will be called stm32-csi. 17 + 4 18 config VIDEO_STM32_DCMI 5 19 tristate "STM32 Digital Camera Memory Interface (DCMI) support" 6 20 depends on V4L_PLATFORM_DRIVERS
+1
drivers/media/platform/st/stm32/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_VIDEO_STM32_CSI) += stm32-csi.o 2 3 obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32-dcmi.o 3 4 obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp/ 4 5 stm32-dma2d-objs := dma2d/dma2d.o dma2d/dma2d-hw.o
+1137
drivers/media/platform/st/stm32/stm32-csi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Driver for STM32 Camera Serial Interface 4 + * 5 + * Copyright (C) STMicroelectronics SA 2024 6 + * Author: Alain Volmat <alain.volmat@foss.st.com> 7 + * for STMicroelectronics. 8 + */ 9 + 10 + #include <linux/clk.h> 11 + #include <linux/delay.h> 12 + #include <linux/io.h> 13 + #include <linux/iopoll.h> 14 + #include <linux/module.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/pm_runtime.h> 17 + #include <linux/reset.h> 18 + #include <linux/slab.h> 19 + 20 + #include <media/mipi-csi2.h> 21 + #include <media/v4l2-fwnode.h> 22 + #include <media/v4l2-subdev.h> 23 + 24 + #define STM32_CSI_CR 0x0000 25 + #define STM32_CSI_CR_CSIEN BIT(0) 26 + #define STM32_CSI_CR_VCXSTART(x) BIT(2 + ((x) * 4)) 27 + #define STM32_CSI_CR_VCXSTOP(x) BIT(3 + ((x) * 4)) 28 + #define STM32_CSI_PCR 0x0004 29 + #define STM32_CSI_PCR_DL1EN BIT(3) 30 + #define STM32_CSI_PCR_DL0EN BIT(2) 31 + #define STM32_CSI_PCR_CLEN BIT(1) 32 + #define STM32_CSI_PCR_PWRDOWN BIT(0) 33 + #define STM32_CSI_VCXCFGR1(x) ((((x) + 1) * 0x0010) + 0x0) 34 + #define STM32_CSI_VCXCFGR1_ALLDT BIT(0) 35 + #define STM32_CSI_VCXCFGR1_DT0EN BIT(1) 36 + #define STM32_CSI_VCXCFGR1_DT1EN BIT(2) 37 + #define STM32_CSI_VCXCFGR1_CDTFT_SHIFT 8 38 + #define STM32_CSI_VCXCFGR1_DT0_SHIFT 16 39 + #define STM32_CSI_VCXCFGR1_DT0FT_SHIFT 24 40 + #define STM32_CSI_VCXCFGR2(x) ((((x) + 1) * 0x0010) + 0x4) 41 + #define STM32_CSI_VCXCFGR2_DT1_SHIFT 0 42 + #define STM32_CSI_VCXCFGR2_DT1FT_SHIFT 8 43 + #define STM32_CSI_INPUT_BPP8 2 44 + #define STM32_CSI_INPUT_BPP10 3 45 + #define STM32_CSI_INPUT_BPP12 4 46 + #define STM32_CSI_INPUT_BPP14 5 47 + #define STM32_CSI_LMCFGR 0x0070 48 + #define STM32_CSI_LMCFGR_LANENB_SHIFT 8 49 + #define STM32_CSI_LMCFGR_DLMAP_SHIFT 16 50 + #define STM32_CSI_IER0 0x0080 51 + #define STM32_CSI_IER1 0x0084 52 + #define STM32_CSI_SR0 0x0090 53 + #define STM32_CSI_SR0_SYNCERRF BIT(30) 54 + #define STM32_CSI_SR0_SPKTERRF BIT(28) 55 + #define STM32_CSI_SR0_IDERRF BIT(27) 56 + #define STM32_CSI_SR0_CECCERRF BIT(26) 57 + #define STM32_CSI_SR0_ECCERRF BIT(25) 58 + #define STM32_CSI_SR0_CRCERRF BIT(24) 59 + #define STM32_CSI_SR0_CCFIFOFF BIT(21) 60 + #define STM32_CSI_SR0_VCXSTATEF(x) BIT(17 + (x)) 61 + #define STM32_CSI_SR1 0x0094 62 + #define STM32_CSI_SR1_ECTRLDL1F BIT(12) 63 + #define STM32_CSI_SR1_ESYNCESCDL1F BIT(11) 64 + #define STM32_CSI_SR1_EESCDL1F BIT(10) 65 + #define STM32_CSI_SR1_ESOTSYNCDL1F BIT(9) 66 + #define STM32_CSI_SR1_ESOTDL1F BIT(8) 67 + #define STM32_CSI_SR1_ECTRLDL0F BIT(4) 68 + #define STM32_CSI_SR1_ESYNCESCDL0F BIT(3) 69 + #define STM32_CSI_SR1_EESCDL0F BIT(2) 70 + #define STM32_CSI_SR1_ESOTSYNCDL0F BIT(1) 71 + #define STM32_CSI_SR1_ESOTDL0F BIT(0) 72 + #define STM32_CSI_FCR0 0x0100 73 + #define STM32_CSI_FCR1 0x0104 74 + #define STM32_CSI_SPDFR 0x0110 75 + #define STM32_CSI_DT_MASK 0x3f 76 + #define STM32_CSI_VC_MASK 0x03 77 + #define STM32_CSI_ERR1 0x0114 78 + #define STM32_CSI_ERR1_IDVCERR_SHIFT 22 79 + #define STM32_CSI_ERR1_IDDTERR_SHIFT 16 80 + #define STM32_CSI_ERR1_CECCVCERR_SHIFT 14 81 + #define STM32_CSI_ERR1_CECCDTERR_SHIFT 8 82 + #define STM32_CSI_ERR1_CRCVCERR_SHIFT 6 83 + #define STM32_CSI_ERR1_CRCDTERR_SHIFT 0 84 + #define STM32_CSI_ERR2 0x0118 85 + #define STM32_CSI_ERR2_SYNCVCERR_SHIFT 18 86 + #define STM32_CSI_ERR2_SPKTVCERR_SHIFT 6 87 + #define STM32_CSI_ERR2_SPKTDTERR_SHIFT 0 88 + #define STM32_CSI_PRCR 0x1000 89 + #define STM32_CSI_PRCR_PEN BIT(1) 90 + #define STM32_CSI_PMCR 0x1004 91 + #define STM32_CSI_PFCR 0x1008 92 + #define STM32_CSI_PFCR_CCFR_MASK GENMASK(5, 0) 93 + #define STM32_CSI_PFCR_CCFR_SHIFT 0 94 + #define STM32_CSI_PFCR_HSFR_MASK GENMASK(14, 8) 95 + #define STM32_CSI_PFCR_HSFR_SHIFT 8 96 + #define STM32_CSI_PFCR_DLD BIT(16) 97 + #define STM32_CSI_PTCR0 0x1010 98 + #define STM32_CSI_PTCR0_TCKEN BIT(0) 99 + #define STM32_CSI_PTCR1 0x1014 100 + #define STM32_CSI_PTCR1_TWM BIT(16) 101 + #define STM32_CSI_PTCR1_TDI_MASK GENMASK(7, 0) 102 + #define STM32_CSI_PTCR1_TDI_SHIFT 0 103 + #define STM32_CSI_PTSR 0x1018 104 + 105 + #define STM32_CSI_LANES_MAX 2 106 + 107 + #define STM32_CSI_SR0_ERRORS (STM32_CSI_SR0_SYNCERRF | STM32_CSI_SR0_SPKTERRF |\ 108 + STM32_CSI_SR0_IDERRF | STM32_CSI_SR0_CECCERRF |\ 109 + STM32_CSI_SR0_ECCERRF | STM32_CSI_SR0_CRCERRF |\ 110 + STM32_CSI_SR0_CCFIFOFF) 111 + #define STM32_CSI_SR1_DL0_ERRORS (STM32_CSI_SR1_ECTRLDL0F | STM32_CSI_SR1_ESYNCESCDL0F |\ 112 + STM32_CSI_SR1_EESCDL0F | STM32_CSI_SR1_ESOTSYNCDL0F |\ 113 + STM32_CSI_SR1_ESOTDL0F) 114 + #define STM32_CSI_SR1_DL1_ERRORS (STM32_CSI_SR1_ECTRLDL1F | STM32_CSI_SR1_ESYNCESCDL1F |\ 115 + STM32_CSI_SR1_EESCDL1F | STM32_CSI_SR1_ESOTSYNCDL1F |\ 116 + STM32_CSI_SR1_ESOTDL1F) 117 + #define STM32_CSI_SR1_ERRORS (STM32_CSI_SR1_DL0_ERRORS | STM32_CSI_SR1_DL1_ERRORS) 118 + 119 + enum stm32_csi_pads { 120 + STM32_CSI_PAD_SINK, 121 + STM32_CSI_PAD_SOURCE, 122 + STM32_CSI_PAD_MAX, 123 + }; 124 + 125 + struct stm32_csi_event { 126 + u32 mask; 127 + const char * const name; 128 + }; 129 + 130 + static const struct stm32_csi_event stm32_csi_events_sr0[] = { 131 + {STM32_CSI_SR0_SYNCERRF, "Synchronization error"}, 132 + {STM32_CSI_SR0_SPKTERRF, "Short packet error"}, 133 + {STM32_CSI_SR0_IDERRF, "Data type ID error"}, 134 + {STM32_CSI_SR0_CECCERRF, "Corrected ECC error"}, 135 + {STM32_CSI_SR0_ECCERRF, "ECC error"}, 136 + {STM32_CSI_SR0_CRCERRF, "CRC error"}, 137 + {STM32_CSI_SR0_CCFIFOFF, "Clk changer FIFO full error"}, 138 + }; 139 + 140 + #define STM32_CSI_NUM_SR0_EVENTS ARRAY_SIZE(stm32_csi_events_sr0) 141 + 142 + static const struct stm32_csi_event stm32_csi_events_sr1[] = { 143 + {STM32_CSI_SR1_ECTRLDL1F, "L1: D-PHY control error"}, 144 + {STM32_CSI_SR1_ESYNCESCDL1F, 145 + "L1: D-PHY low power data transmission synchro error"}, 146 + {STM32_CSI_SR1_EESCDL1F, "L1: D-PHY escape entry error"}, 147 + {STM32_CSI_SR1_ESOTSYNCDL1F, 148 + "L1: Start of transmission synchro error"}, 149 + {STM32_CSI_SR1_ESOTDL1F, "L1: Start of transmission error"}, 150 + {STM32_CSI_SR1_ECTRLDL0F, "L0: D-PHY control error"}, 151 + {STM32_CSI_SR1_ESYNCESCDL0F, 152 + "L0: D-PHY low power data transmission synchro error"}, 153 + {STM32_CSI_SR1_EESCDL0F, "L0: D-PHY escape entry error"}, 154 + {STM32_CSI_SR1_ESOTSYNCDL0F, 155 + "L0: Start of transmission synchro error"}, 156 + {STM32_CSI_SR1_ESOTDL0F, "L0: Start of transmission error"}, 157 + }; 158 + 159 + #define STM32_CSI_NUM_SR1_EVENTS ARRAY_SIZE(stm32_csi_events_sr1) 160 + 161 + enum stm32_csi_clk { 162 + STM32_CSI_CLK_PCLK, 163 + STM32_CSI_CLK_TXESC, 164 + STM32_CSI_CLK_CSI2PHY, 165 + STM32_CSI_CLK_NB, 166 + }; 167 + 168 + static const char * const stm32_csi_clks_id[] = { 169 + "pclk", 170 + "txesc", 171 + "csi2phy", 172 + }; 173 + 174 + struct stm32_csi_dev { 175 + struct device *dev; 176 + 177 + void __iomem *base; 178 + 179 + struct clk_bulk_data clks[STM32_CSI_CLK_NB]; 180 + struct regulator_bulk_data supplies[2]; 181 + 182 + u8 lanes[STM32_CSI_LANES_MAX]; 183 + u8 num_lanes; 184 + 185 + /* 186 + * spinlock slock is used to protect to srX_counters tables being 187 + * accessed from log_status and interrupt context 188 + */ 189 + spinlock_t slock; 190 + 191 + u32 sr0_counters[STM32_CSI_NUM_SR0_EVENTS]; 192 + u32 sr1_counters[STM32_CSI_NUM_SR1_EVENTS]; 193 + 194 + struct v4l2_subdev sd; 195 + struct v4l2_async_notifier notifier; 196 + struct media_pad pads[STM32_CSI_PAD_MAX]; 197 + 198 + /* Remote source */ 199 + struct v4l2_subdev *s_subdev; 200 + u32 s_subdev_pad_nb; 201 + }; 202 + 203 + struct stm32_csi_fmts { 204 + u32 code; 205 + u32 datatype; 206 + u32 input_fmt; 207 + u8 bpp; 208 + }; 209 + 210 + #define FMT_MBUS_DT_DTFMT_BPP(mbus, dt, input, byteperpixel) \ 211 + { \ 212 + .code = MEDIA_BUS_FMT_##mbus, \ 213 + .datatype = MIPI_CSI2_DT_##dt, \ 214 + .input_fmt = STM32_CSI_INPUT_##input, \ 215 + .bpp = byteperpixel, \ 216 + } 217 + static const struct stm32_csi_fmts stm32_csi_formats[] = { 218 + /* YUV 422 8 bit */ 219 + FMT_MBUS_DT_DTFMT_BPP(UYVY8_1X16, YUV422_8B, BPP8, 8), 220 + FMT_MBUS_DT_DTFMT_BPP(YUYV8_1X16, YUV422_8B, BPP8, 8), 221 + FMT_MBUS_DT_DTFMT_BPP(YVYU8_1X16, YUV422_8B, BPP8, 8), 222 + FMT_MBUS_DT_DTFMT_BPP(VYUY8_1X16, YUV422_8B, BPP8, 8), 223 + 224 + /* Raw Bayer */ 225 + /* 8 bit */ 226 + FMT_MBUS_DT_DTFMT_BPP(SBGGR8_1X8, RAW8, BPP8, 8), 227 + FMT_MBUS_DT_DTFMT_BPP(SGBRG8_1X8, RAW8, BPP8, 8), 228 + FMT_MBUS_DT_DTFMT_BPP(SGRBG8_1X8, RAW8, BPP8, 8), 229 + FMT_MBUS_DT_DTFMT_BPP(SRGGB8_1X8, RAW8, BPP8, 8), 230 + /* 10 bit */ 231 + FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10), 232 + FMT_MBUS_DT_DTFMT_BPP(SGBRG10_1X10, RAW10, BPP10, 10), 233 + FMT_MBUS_DT_DTFMT_BPP(SGRBG10_1X10, RAW10, BPP10, 10), 234 + FMT_MBUS_DT_DTFMT_BPP(SRGGB10_1X10, RAW10, BPP10, 10), 235 + /* 12 bit */ 236 + FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12), 237 + FMT_MBUS_DT_DTFMT_BPP(SGBRG12_1X12, RAW12, BPP12, 12), 238 + FMT_MBUS_DT_DTFMT_BPP(SGRBG12_1X12, RAW12, BPP12, 12), 239 + FMT_MBUS_DT_DTFMT_BPP(SRGGB12_1X12, RAW12, BPP12, 12), 240 + /* 14 bit */ 241 + FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14), 242 + FMT_MBUS_DT_DTFMT_BPP(SGBRG14_1X14, RAW14, BPP14, 14), 243 + FMT_MBUS_DT_DTFMT_BPP(SGRBG14_1X14, RAW14, BPP14, 14), 244 + FMT_MBUS_DT_DTFMT_BPP(SRGGB14_1X14, RAW14, BPP14, 14), 245 + 246 + /* RGB 565 */ 247 + FMT_MBUS_DT_DTFMT_BPP(RGB565_1X16, RGB565, BPP8, 8), 248 + 249 + /* JPEG (datatype isn't used) */ 250 + FMT_MBUS_DT_DTFMT_BPP(JPEG_1X8, NULL, BPP8, 8), 251 + }; 252 + 253 + struct stm32_csi_mbps_phy_reg { 254 + unsigned int mbps; 255 + unsigned int hsfreqrange; 256 + unsigned int osc_freq_target; 257 + }; 258 + 259 + /* 260 + * Table describing configuration of the PHY depending on the 261 + * intended Bit Rate. From table 5-8 Frequency Ranges and Defaults 262 + * of the Synopsis DWC MIPI PHY databook 263 + */ 264 + static const struct stm32_csi_mbps_phy_reg snps_stm32mp25[] = { 265 + { .mbps = 80, .hsfreqrange = 0x00, .osc_freq_target = 460 }, 266 + { .mbps = 90, .hsfreqrange = 0x10, .osc_freq_target = 460 }, 267 + { .mbps = 100, .hsfreqrange = 0x20, .osc_freq_target = 460 }, 268 + { .mbps = 110, .hsfreqrange = 0x30, .osc_freq_target = 460 }, 269 + { .mbps = 120, .hsfreqrange = 0x01, .osc_freq_target = 460 }, 270 + { .mbps = 130, .hsfreqrange = 0x11, .osc_freq_target = 460 }, 271 + { .mbps = 140, .hsfreqrange = 0x21, .osc_freq_target = 460 }, 272 + { .mbps = 150, .hsfreqrange = 0x31, .osc_freq_target = 460 }, 273 + { .mbps = 160, .hsfreqrange = 0x02, .osc_freq_target = 460 }, 274 + { .mbps = 170, .hsfreqrange = 0x12, .osc_freq_target = 460 }, 275 + { .mbps = 180, .hsfreqrange = 0x22, .osc_freq_target = 460 }, 276 + { .mbps = 190, .hsfreqrange = 0x32, .osc_freq_target = 460 }, 277 + { .mbps = 205, .hsfreqrange = 0x03, .osc_freq_target = 460 }, 278 + { .mbps = 220, .hsfreqrange = 0x13, .osc_freq_target = 460 }, 279 + { .mbps = 235, .hsfreqrange = 0x23, .osc_freq_target = 460 }, 280 + { .mbps = 250, .hsfreqrange = 0x33, .osc_freq_target = 460 }, 281 + { .mbps = 275, .hsfreqrange = 0x04, .osc_freq_target = 460 }, 282 + { .mbps = 300, .hsfreqrange = 0x14, .osc_freq_target = 460 }, 283 + { .mbps = 325, .hsfreqrange = 0x25, .osc_freq_target = 460 }, 284 + { .mbps = 350, .hsfreqrange = 0x35, .osc_freq_target = 460 }, 285 + { .mbps = 400, .hsfreqrange = 0x05, .osc_freq_target = 460 }, 286 + { .mbps = 450, .hsfreqrange = 0x16, .osc_freq_target = 460 }, 287 + { .mbps = 500, .hsfreqrange = 0x26, .osc_freq_target = 460 }, 288 + { .mbps = 550, .hsfreqrange = 0x37, .osc_freq_target = 460 }, 289 + { .mbps = 600, .hsfreqrange = 0x07, .osc_freq_target = 460 }, 290 + { .mbps = 650, .hsfreqrange = 0x18, .osc_freq_target = 460 }, 291 + { .mbps = 700, .hsfreqrange = 0x28, .osc_freq_target = 460 }, 292 + { .mbps = 750, .hsfreqrange = 0x39, .osc_freq_target = 460 }, 293 + { .mbps = 800, .hsfreqrange = 0x09, .osc_freq_target = 460 }, 294 + { .mbps = 850, .hsfreqrange = 0x19, .osc_freq_target = 460 }, 295 + { .mbps = 900, .hsfreqrange = 0x29, .osc_freq_target = 460 }, 296 + { .mbps = 950, .hsfreqrange = 0x3a, .osc_freq_target = 460 }, 297 + { .mbps = 1000, .hsfreqrange = 0x0a, .osc_freq_target = 460 }, 298 + { .mbps = 1050, .hsfreqrange = 0x1a, .osc_freq_target = 460 }, 299 + { .mbps = 1100, .hsfreqrange = 0x2a, .osc_freq_target = 460 }, 300 + { .mbps = 1150, .hsfreqrange = 0x3b, .osc_freq_target = 460 }, 301 + { .mbps = 1200, .hsfreqrange = 0x0b, .osc_freq_target = 460 }, 302 + { .mbps = 1250, .hsfreqrange = 0x1b, .osc_freq_target = 460 }, 303 + { .mbps = 1300, .hsfreqrange = 0x2b, .osc_freq_target = 460 }, 304 + { .mbps = 1350, .hsfreqrange = 0x3c, .osc_freq_target = 460 }, 305 + { .mbps = 1400, .hsfreqrange = 0x0c, .osc_freq_target = 460 }, 306 + { .mbps = 1450, .hsfreqrange = 0x1c, .osc_freq_target = 460 }, 307 + { .mbps = 1500, .hsfreqrange = 0x2c, .osc_freq_target = 460 }, 308 + { .mbps = 1550, .hsfreqrange = 0x3d, .osc_freq_target = 285 }, 309 + { .mbps = 1600, .hsfreqrange = 0x0d, .osc_freq_target = 295 }, 310 + { .mbps = 1650, .hsfreqrange = 0x1d, .osc_freq_target = 304 }, 311 + { .mbps = 1700, .hsfreqrange = 0x2e, .osc_freq_target = 313 }, 312 + { .mbps = 1750, .hsfreqrange = 0x3e, .osc_freq_target = 322 }, 313 + { .mbps = 1800, .hsfreqrange = 0x0e, .osc_freq_target = 331 }, 314 + { .mbps = 1850, .hsfreqrange = 0x1e, .osc_freq_target = 341 }, 315 + { .mbps = 1900, .hsfreqrange = 0x2f, .osc_freq_target = 350 }, 316 + { .mbps = 1950, .hsfreqrange = 0x3f, .osc_freq_target = 359 }, 317 + { .mbps = 2000, .hsfreqrange = 0x0f, .osc_freq_target = 368 }, 318 + { .mbps = 2050, .hsfreqrange = 0x40, .osc_freq_target = 377 }, 319 + { .mbps = 2100, .hsfreqrange = 0x41, .osc_freq_target = 387 }, 320 + { .mbps = 2150, .hsfreqrange = 0x42, .osc_freq_target = 396 }, 321 + { .mbps = 2200, .hsfreqrange = 0x43, .osc_freq_target = 405 }, 322 + { .mbps = 2250, .hsfreqrange = 0x44, .osc_freq_target = 414 }, 323 + { .mbps = 2300, .hsfreqrange = 0x45, .osc_freq_target = 423 }, 324 + { .mbps = 2350, .hsfreqrange = 0x46, .osc_freq_target = 432 }, 325 + { .mbps = 2400, .hsfreqrange = 0x47, .osc_freq_target = 442 }, 326 + { .mbps = 2450, .hsfreqrange = 0x48, .osc_freq_target = 451 }, 327 + { .mbps = 2500, .hsfreqrange = 0x49, .osc_freq_target = 460 }, 328 + { /* sentinel */ } 329 + }; 330 + 331 + static const struct v4l2_mbus_framefmt fmt_default = { 332 + .width = 640, 333 + .height = 480, 334 + .code = MEDIA_BUS_FMT_RGB565_1X16, 335 + .field = V4L2_FIELD_NONE, 336 + .colorspace = V4L2_COLORSPACE_REC709, 337 + .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT, 338 + .quantization = V4L2_QUANTIZATION_DEFAULT, 339 + .xfer_func = V4L2_XFER_FUNC_DEFAULT, 340 + }; 341 + 342 + static const struct stm32_csi_fmts *stm32_csi_code_to_fmt(unsigned int code) 343 + { 344 + unsigned int i; 345 + 346 + for (i = 0; i < ARRAY_SIZE(stm32_csi_formats); i++) 347 + if (stm32_csi_formats[i].code == code) 348 + return &stm32_csi_formats[i]; 349 + 350 + return NULL; 351 + } 352 + 353 + static inline struct stm32_csi_dev *to_csidev(struct v4l2_subdev *sd) 354 + { 355 + return container_of(sd, struct stm32_csi_dev, sd); 356 + } 357 + 358 + static int stm32_csi_setup_lane_merger(struct stm32_csi_dev *csidev) 359 + { 360 + u32 lmcfgr = 0; 361 + int i; 362 + 363 + for (i = 0; i < csidev->num_lanes; i++) { 364 + if (!csidev->lanes[i] || csidev->lanes[i] > STM32_CSI_LANES_MAX) { 365 + dev_err(csidev->dev, "Invalid lane id (%d)\n", csidev->lanes[i]); 366 + return -EINVAL; 367 + } 368 + lmcfgr |= (csidev->lanes[i] << ((i * 4) + STM32_CSI_LMCFGR_DLMAP_SHIFT)); 369 + } 370 + 371 + lmcfgr |= (csidev->num_lanes << STM32_CSI_LMCFGR_LANENB_SHIFT); 372 + 373 + writel_relaxed(lmcfgr, csidev->base + STM32_CSI_LMCFGR); 374 + 375 + return 0; 376 + } 377 + 378 + static void stm32_csi_phy_reg_write(struct stm32_csi_dev *csidev, 379 + u32 addr, u32 val) 380 + { 381 + /* Based on sequence described at section 5.2.3.2 of DesignWave document */ 382 + /* For writing the 4-bit testcode MSBs */ 383 + /* Set testen to high */ 384 + writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1); 385 + 386 + /* Set testclk to high */ 387 + writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0); 388 + 389 + /* Place 0x00 in testdin */ 390 + writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1); 391 + 392 + /* 393 + * Set testclk to low (with the falling edge on testclk, the testdin 394 + * signal content is latched internally) 395 + */ 396 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR0); 397 + 398 + /* Set testen to low */ 399 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR1); 400 + 401 + /* Place the 8-bit word corresponding to the testcode MSBs in testdin */ 402 + writel_relaxed(((addr >> 8) & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT, 403 + csidev->base + STM32_CSI_PTCR1); 404 + 405 + /* Set testclk to high */ 406 + writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0); 407 + 408 + /* For writing the 8-bit testcode LSBs */ 409 + /* Set testclk to low */ 410 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR0); 411 + 412 + /* Set testen to high */ 413 + writel_relaxed(STM32_CSI_PTCR1_TWM, csidev->base + STM32_CSI_PTCR1); 414 + 415 + /* Set testclk to high */ 416 + writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0); 417 + 418 + /* Place the 8-bit word test data in testdin */ 419 + writel_relaxed((addr & STM32_CSI_PTCR1_TDI_MASK) << 420 + STM32_CSI_PTCR1_TDI_SHIFT | STM32_CSI_PTCR1_TWM, 421 + csidev->base + STM32_CSI_PTCR1); 422 + 423 + /* 424 + * Set testclk to low (with the falling edge on testclk, the testdin 425 + * signal content is latched internally) 426 + */ 427 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR0); 428 + 429 + /* Set testen to low */ 430 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR1); 431 + 432 + /* For writing the data */ 433 + /* Place the 8-bit word corresponding to the page offset in testdin */ 434 + writel_relaxed((val & STM32_CSI_PTCR1_TDI_MASK) << STM32_CSI_PTCR1_TDI_SHIFT, 435 + csidev->base + STM32_CSI_PTCR1); 436 + 437 + /* Set testclk to high (test data is programmed internally */ 438 + writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0); 439 + 440 + /* Finish by setting testclk to low */ 441 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR0); 442 + } 443 + 444 + static int stm32_csi_start(struct stm32_csi_dev *csidev, 445 + struct v4l2_subdev_state *state) 446 + { 447 + const struct stm32_csi_mbps_phy_reg *phy_regs; 448 + struct v4l2_mbus_framefmt *sink_fmt; 449 + const struct stm32_csi_fmts *fmt; 450 + unsigned long phy_clk_frate; 451 + unsigned int mbps; 452 + u32 lanes_ie = 0; 453 + u32 lanes_en = 0; 454 + s64 link_freq; 455 + int ret; 456 + u32 ccfr; 457 + 458 + dev_dbg(csidev->dev, "Starting the CSI2\n"); 459 + 460 + /* Get the bpp value on pad0 (input of CSI) */ 461 + sink_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK); 462 + fmt = stm32_csi_code_to_fmt(sink_fmt->code); 463 + 464 + /* Get the remote sensor link frequency */ 465 + if (!csidev->s_subdev) 466 + return -EIO; 467 + 468 + link_freq = v4l2_get_link_freq(csidev->s_subdev->ctrl_handler, 469 + fmt->bpp, 2 * csidev->num_lanes); 470 + if (link_freq < 0) 471 + return link_freq; 472 + 473 + /* MBPS is expressed in Mbps, hence link_freq / 100000 * 2 */ 474 + mbps = div_s64(link_freq, 500000); 475 + dev_dbg(csidev->dev, "Computed Mbps: %u\n", mbps); 476 + 477 + for (phy_regs = snps_stm32mp25; phy_regs->mbps != 0; phy_regs++) 478 + if (phy_regs->mbps >= mbps) 479 + break; 480 + 481 + if (!phy_regs->mbps) { 482 + dev_err(csidev->dev, "Unsupported PHY speed (%u Mbps)", mbps); 483 + return -ERANGE; 484 + } 485 + 486 + dev_dbg(csidev->dev, "PHY settings: (%u Mbps, %u HS FRange, %u OSC Freq)\n", 487 + phy_regs->mbps, phy_regs->hsfreqrange, 488 + phy_regs->osc_freq_target); 489 + 490 + /* Prepare lanes related configuration bits */ 491 + lanes_ie |= STM32_CSI_SR1_DL0_ERRORS; 492 + lanes_en |= STM32_CSI_PCR_DL0EN; 493 + if (csidev->num_lanes == 2) { 494 + lanes_ie |= STM32_CSI_SR1_DL1_ERRORS; 495 + lanes_en |= STM32_CSI_PCR_DL1EN; 496 + } 497 + 498 + ret = pm_runtime_get_sync(csidev->dev); 499 + if (ret < 0) 500 + return ret; 501 + 502 + /* Retrieve CSI2PHY clock rate to compute CCFR value */ 503 + phy_clk_frate = clk_get_rate(csidev->clks[STM32_CSI_CLK_CSI2PHY].clk); 504 + if (!phy_clk_frate) { 505 + pm_runtime_put(csidev->dev); 506 + dev_err(csidev->dev, "CSI2PHY clock rate invalid (0)\n"); 507 + return ret; 508 + } 509 + 510 + ret = stm32_csi_setup_lane_merger(csidev); 511 + if (ret) { 512 + pm_runtime_put(csidev->dev); 513 + return ret; 514 + } 515 + 516 + /* Enable the CSI */ 517 + writel_relaxed(STM32_CSI_CR_CSIEN, csidev->base + STM32_CSI_CR); 518 + 519 + /* Enable some global CSI related interrupts - bits are same as SR0 */ 520 + writel_relaxed(STM32_CSI_SR0_ERRORS, csidev->base + STM32_CSI_IER0); 521 + 522 + /* Enable lanes related error interrupts */ 523 + writel_relaxed(lanes_ie, csidev->base + STM32_CSI_IER1); 524 + 525 + /* Initialization of the D-PHY */ 526 + /* Stop the D-PHY */ 527 + writel_relaxed(0, csidev->base + STM32_CSI_PRCR); 528 + 529 + /* Keep the D-PHY in power down state */ 530 + writel_relaxed(0, csidev->base + STM32_CSI_PCR); 531 + 532 + /* Enable testclr clock during 15ns */ 533 + writel_relaxed(STM32_CSI_PTCR0_TCKEN, csidev->base + STM32_CSI_PTCR0); 534 + udelay(1); 535 + writel_relaxed(0, csidev->base + STM32_CSI_PTCR0); 536 + 537 + /* Set hsfreqrange */ 538 + phy_clk_frate /= 1000000; 539 + ccfr = (phy_clk_frate - 17) * 4; 540 + writel_relaxed((ccfr << STM32_CSI_PFCR_CCFR_SHIFT) | 541 + (phy_regs->hsfreqrange << STM32_CSI_PFCR_HSFR_SHIFT), 542 + csidev->base + STM32_CSI_PFCR); 543 + 544 + /* set reg @08 deskew_polarity_rw 1'b1 */ 545 + stm32_csi_phy_reg_write(csidev, 0x08, 0x38); 546 + 547 + /* set reg @0xE4 counter_for_des_en_config_if_rx 0x10 + DLL prog EN */ 548 + /* This is because 13<= cfgclkfreqrange[5:0]<=38 */ 549 + stm32_csi_phy_reg_write(csidev, 0xe4, 0x11); 550 + 551 + /* set reg @0xe2 & reg @0xe3 value DLL target oscilation freq */ 552 + /* Based on the table page 77, osc_freq_target */ 553 + stm32_csi_phy_reg_write(csidev, 0xe2, phy_regs->osc_freq_target & 0xFF); 554 + stm32_csi_phy_reg_write(csidev, 0xe3, (phy_regs->osc_freq_target >> 8) & 0x0F); 555 + 556 + writel_relaxed(STM32_CSI_PFCR_DLD | readl_relaxed(csidev->base + STM32_CSI_PFCR), 557 + csidev->base + STM32_CSI_PFCR); 558 + 559 + /* Enable Lanes */ 560 + writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN, csidev->base + STM32_CSI_PCR); 561 + writel_relaxed(lanes_en | STM32_CSI_PCR_CLEN | STM32_CSI_PCR_PWRDOWN, 562 + csidev->base + STM32_CSI_PCR); 563 + 564 + writel_relaxed(STM32_CSI_PRCR_PEN, csidev->base + STM32_CSI_PRCR); 565 + 566 + /* Remove the force */ 567 + writel_relaxed(0, csidev->base + STM32_CSI_PMCR); 568 + 569 + return ret; 570 + } 571 + 572 + static void stm32_csi_stop(struct stm32_csi_dev *csidev) 573 + { 574 + dev_dbg(csidev->dev, "Stopping the CSI2\n"); 575 + 576 + /* Disable the D-PHY */ 577 + writel_relaxed(0, csidev->base + STM32_CSI_PCR); 578 + 579 + /* Disable ITs */ 580 + writel_relaxed(0, csidev->base + STM32_CSI_IER0); 581 + writel_relaxed(0, csidev->base + STM32_CSI_IER1); 582 + 583 + /* Disable the CSI */ 584 + writel_relaxed(0, csidev->base + STM32_CSI_CR); 585 + 586 + pm_runtime_put(csidev->dev); 587 + } 588 + 589 + static int stm32_csi_start_vc(struct stm32_csi_dev *csidev, 590 + struct v4l2_subdev_state *state, u32 vc) 591 + { 592 + struct v4l2_mbus_framefmt *mbus_fmt; 593 + const struct stm32_csi_fmts *fmt; 594 + u32 cfgr1 = 0; 595 + int ret = 0; 596 + u32 status; 597 + 598 + mbus_fmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE); 599 + fmt = stm32_csi_code_to_fmt(mbus_fmt->code); 600 + 601 + /* If the mbus code is JPEG, don't enable filtering */ 602 + if (mbus_fmt->code == MEDIA_BUS_FMT_JPEG_1X8) { 603 + cfgr1 |= STM32_CSI_VCXCFGR1_ALLDT; 604 + cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_CDTFT_SHIFT; 605 + dev_dbg(csidev->dev, "VC%d: enable AllDT mode\n", vc); 606 + } else { 607 + cfgr1 |= fmt->datatype << STM32_CSI_VCXCFGR1_DT0_SHIFT; 608 + cfgr1 |= fmt->input_fmt << STM32_CSI_VCXCFGR1_DT0FT_SHIFT; 609 + cfgr1 |= STM32_CSI_VCXCFGR1_DT0EN; 610 + dev_dbg(csidev->dev, "VC%d: enable DT0(0x%x)/DT0FT(0x%x)\n", 611 + vc, fmt->datatype, fmt->input_fmt); 612 + } 613 + writel_relaxed(cfgr1, csidev->base + STM32_CSI_VCXCFGR1(vc)); 614 + 615 + /* Enable processing of the virtual-channel and wait for its status */ 616 + writel_relaxed(STM32_CSI_CR_VCXSTART(vc) | STM32_CSI_CR_CSIEN, 617 + csidev->base + STM32_CSI_CR); 618 + 619 + ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0, 620 + status, 621 + status & STM32_CSI_SR0_VCXSTATEF(vc), 622 + 1000, 1000000); 623 + if (ret) { 624 + dev_err(csidev->dev, "failed to start VC(%d)\n", vc); 625 + return ret; 626 + } 627 + 628 + return 0; 629 + } 630 + 631 + static int stm32_csi_stop_vc(struct stm32_csi_dev *csidev, u32 vc) 632 + { 633 + int ret = 0; 634 + u32 status; 635 + 636 + /* Stop the Virtual Channel */ 637 + writel_relaxed(STM32_CSI_CR_VCXSTOP(vc) | STM32_CSI_CR_CSIEN, 638 + csidev->base + STM32_CSI_CR); 639 + 640 + ret = readl_relaxed_poll_timeout(csidev->base + STM32_CSI_SR0, 641 + status, 642 + !(status & STM32_CSI_SR0_VCXSTATEF(vc)), 643 + 1000, 1000000); 644 + if (ret) { 645 + dev_err(csidev->dev, "failed to stop VC(%d)\n", vc); 646 + return ret; 647 + } 648 + 649 + /* Disable all DTs */ 650 + writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR1(vc)); 651 + writel_relaxed(0, csidev->base + STM32_CSI_VCXCFGR2(vc)); 652 + 653 + return 0; 654 + } 655 + 656 + static int stm32_csi_disable_streams(struct v4l2_subdev *sd, 657 + struct v4l2_subdev_state *state, u32 pad, 658 + u64 streams_mask) 659 + { 660 + struct stm32_csi_dev *csidev = to_csidev(sd); 661 + int ret; 662 + 663 + ret = v4l2_subdev_disable_streams(csidev->s_subdev, 664 + csidev->s_subdev_pad_nb, BIT_ULL(0)); 665 + if (ret) 666 + return ret; 667 + 668 + /* Stop the VC0 */ 669 + ret = stm32_csi_stop_vc(csidev, 0); 670 + if (ret) 671 + dev_err(csidev->dev, "Failed to stop VC0\n"); 672 + 673 + stm32_csi_stop(csidev); 674 + 675 + return 0; 676 + } 677 + 678 + static int stm32_csi_enable_streams(struct v4l2_subdev *sd, 679 + struct v4l2_subdev_state *state, u32 pad, 680 + u64 streams_mask) 681 + { 682 + struct stm32_csi_dev *csidev = to_csidev(sd); 683 + int ret; 684 + 685 + ret = stm32_csi_start(csidev, state); 686 + if (ret) 687 + return ret; 688 + 689 + /* Configure & start the VC0 */ 690 + ret = stm32_csi_start_vc(csidev, state, 0); 691 + if (ret) { 692 + dev_err(csidev->dev, "Failed to start VC0\n"); 693 + stm32_csi_stop(csidev); 694 + return ret; 695 + } 696 + 697 + ret = v4l2_subdev_enable_streams(csidev->s_subdev, 698 + csidev->s_subdev_pad_nb, BIT_ULL(0)); 699 + if (ret) { 700 + stm32_csi_stop_vc(csidev, 0); 701 + stm32_csi_stop(csidev); 702 + return ret; 703 + } 704 + 705 + return 0; 706 + } 707 + 708 + static int stm32_csi_init_state(struct v4l2_subdev *sd, 709 + struct v4l2_subdev_state *state) 710 + { 711 + int i; 712 + 713 + for (i = 0; i < sd->entity.num_pads; i++) 714 + *v4l2_subdev_state_get_format(state, i) = fmt_default; 715 + 716 + return 0; 717 + } 718 + 719 + static int stm32_csi_enum_mbus_code(struct v4l2_subdev *sd, 720 + struct v4l2_subdev_state *state, 721 + struct v4l2_subdev_mbus_code_enum *code) 722 + { 723 + if (code->index >= ARRAY_SIZE(stm32_csi_formats)) 724 + return -EINVAL; 725 + 726 + code->code = stm32_csi_formats[code->index].code; 727 + return 0; 728 + } 729 + 730 + static int stm32_csi_set_pad_format(struct v4l2_subdev *sd, 731 + struct v4l2_subdev_state *state, 732 + struct v4l2_subdev_format *format) 733 + { 734 + struct stm32_csi_dev *csidev = to_csidev(sd); 735 + struct v4l2_mbus_framefmt *framefmt; 736 + const struct stm32_csi_fmts *fmt; 737 + 738 + fmt = stm32_csi_code_to_fmt(format->format.code); 739 + if (!fmt) { 740 + dev_dbg(csidev->dev, "Unsupported code %d, use default\n", 741 + format->format.code); 742 + format->format.code = fmt_default.code; 743 + } 744 + 745 + framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SINK); 746 + 747 + if (format->pad == STM32_CSI_PAD_SOURCE) 748 + format->format = *framefmt; 749 + else 750 + *framefmt = format->format; 751 + 752 + framefmt = v4l2_subdev_state_get_format(state, STM32_CSI_PAD_SOURCE); 753 + *framefmt = format->format; 754 + 755 + return 0; 756 + } 757 + 758 + static int stm32_csi_log_status(struct v4l2_subdev *sd) 759 + { 760 + struct stm32_csi_dev *csidev = to_csidev(sd); 761 + unsigned long flags; 762 + unsigned int i; 763 + 764 + spin_lock_irqsave(&csidev->slock, flags); 765 + 766 + for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++) { 767 + if (csidev->sr0_counters[i]) 768 + dev_info(csidev->dev, "%s events: %d\n", 769 + stm32_csi_events_sr0[i].name, 770 + csidev->sr0_counters[i]); 771 + } 772 + 773 + for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++) { 774 + if (csidev->sr1_counters[i]) 775 + dev_info(csidev->dev, "%s events: %d\n", 776 + stm32_csi_events_sr1[i].name, 777 + csidev->sr1_counters[i]); 778 + } 779 + 780 + spin_unlock_irqrestore(&csidev->slock, flags); 781 + 782 + return 0; 783 + } 784 + 785 + static const struct v4l2_subdev_core_ops stm32_csi_core_ops = { 786 + .log_status = stm32_csi_log_status, 787 + }; 788 + 789 + static const struct v4l2_subdev_video_ops stm32_csi_video_ops = { 790 + .s_stream = v4l2_subdev_s_stream_helper, 791 + }; 792 + 793 + static const struct v4l2_subdev_pad_ops stm32_csi_pad_ops = { 794 + .enum_mbus_code = stm32_csi_enum_mbus_code, 795 + .set_fmt = stm32_csi_set_pad_format, 796 + .get_fmt = v4l2_subdev_get_fmt, 797 + .enable_streams = stm32_csi_enable_streams, 798 + .disable_streams = stm32_csi_disable_streams, 799 + }; 800 + 801 + static const struct v4l2_subdev_ops stm32_csi_subdev_ops = { 802 + .core = &stm32_csi_core_ops, 803 + .pad = &stm32_csi_pad_ops, 804 + .video = &stm32_csi_video_ops, 805 + }; 806 + 807 + static const struct v4l2_subdev_internal_ops stm32_csi_subdev_internal_ops = { 808 + .init_state = stm32_csi_init_state, 809 + }; 810 + 811 + static int stm32_csi_async_bound(struct v4l2_async_notifier *notifier, 812 + struct v4l2_subdev *s_subdev, 813 + struct v4l2_async_connection *asd) 814 + { 815 + struct v4l2_subdev *sd = notifier->sd; 816 + struct stm32_csi_dev *csidev = to_csidev(sd); 817 + int remote_pad; 818 + 819 + remote_pad = media_entity_get_fwnode_pad(&s_subdev->entity, 820 + s_subdev->fwnode, 821 + MEDIA_PAD_FL_SOURCE); 822 + if (remote_pad < 0) { 823 + dev_err(csidev->dev, "Couldn't find output pad for subdev %s\n", 824 + s_subdev->name); 825 + return remote_pad; 826 + } 827 + 828 + csidev->s_subdev = s_subdev; 829 + csidev->s_subdev_pad_nb = remote_pad; 830 + 831 + return media_create_pad_link(&csidev->s_subdev->entity, 832 + remote_pad, &csidev->sd.entity, 833 + STM32_CSI_PAD_SINK, 834 + MEDIA_LNK_FL_ENABLED | 835 + MEDIA_LNK_FL_IMMUTABLE); 836 + } 837 + 838 + static const struct v4l2_async_notifier_operations stm32_csi_notifier_ops = { 839 + .bound = stm32_csi_async_bound, 840 + }; 841 + 842 + static irqreturn_t stm32_csi_irq_thread(int irq, void *arg) 843 + { 844 + struct stm32_csi_dev *csidev = arg; 845 + unsigned long flags; 846 + u32 sr0, sr1; 847 + int i; 848 + 849 + sr0 = readl_relaxed(csidev->base + STM32_CSI_SR0); 850 + sr1 = readl_relaxed(csidev->base + STM32_CSI_SR1); 851 + 852 + /* Clear interrupt */ 853 + writel_relaxed(sr0 & STM32_CSI_SR0_ERRORS, 854 + csidev->base + STM32_CSI_FCR0); 855 + writel_relaxed(sr1 & STM32_CSI_SR1_ERRORS, 856 + csidev->base + STM32_CSI_FCR1); 857 + 858 + spin_lock_irqsave(&csidev->slock, flags); 859 + 860 + for (i = 0; i < STM32_CSI_NUM_SR0_EVENTS; i++) 861 + if (sr0 & stm32_csi_events_sr0[i].mask) 862 + csidev->sr0_counters[i]++; 863 + 864 + for (i = 0; i < STM32_CSI_NUM_SR1_EVENTS; i++) 865 + if (sr1 & stm32_csi_events_sr1[i].mask) 866 + csidev->sr1_counters[i]++; 867 + 868 + spin_unlock_irqrestore(&csidev->slock, flags); 869 + 870 + return IRQ_HANDLED; 871 + } 872 + 873 + static int stm32_csi_get_resources(struct stm32_csi_dev *csidev, 874 + struct platform_device *pdev) 875 + { 876 + int irq, ret, i; 877 + 878 + csidev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); 879 + if (IS_ERR(csidev->base)) 880 + return dev_err_probe(&pdev->dev, PTR_ERR(csidev->base), 881 + "Failed to ioremap resource\n"); 882 + 883 + for (i = 0; i < STM32_CSI_CLK_NB; i++) 884 + csidev->clks[i].id = stm32_csi_clks_id[i]; 885 + 886 + ret = devm_clk_bulk_get(&pdev->dev, STM32_CSI_CLK_NB, 887 + csidev->clks); 888 + if (ret < 0) 889 + return dev_err_probe(&pdev->dev, ret, "Couldn't get clks\n"); 890 + 891 + csidev->supplies[0].supply = "vdd"; 892 + csidev->supplies[1].supply = "vdda18"; 893 + ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(csidev->supplies), 894 + csidev->supplies); 895 + if (ret) 896 + return dev_err_probe(&pdev->dev, ret, 897 + "Failed to request regulator vdd\n"); 898 + 899 + irq = platform_get_irq(pdev, 0); 900 + if (irq < 0) 901 + return irq; 902 + 903 + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 904 + stm32_csi_irq_thread, IRQF_ONESHOT, 905 + dev_name(&pdev->dev), csidev); 906 + if (ret) 907 + return dev_err_probe(&pdev->dev, ret, 908 + "Unable to request irq"); 909 + 910 + return 0; 911 + } 912 + 913 + static int stm32_csi_parse_dt(struct stm32_csi_dev *csidev) 914 + { 915 + struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; 916 + struct v4l2_async_connection *asd; 917 + struct fwnode_handle *ep; 918 + int ret; 919 + 920 + /* Get bus characteristics from devicetree */ 921 + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csidev->dev), 0, 0, 922 + FWNODE_GRAPH_ENDPOINT_NEXT); 923 + if (!ep) { 924 + dev_err(csidev->dev, "Could not find the endpoint\n"); 925 + return -ENODEV; 926 + } 927 + 928 + ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep); 929 + fwnode_handle_put(ep); 930 + if (ret) { 931 + dev_err(csidev->dev, "Could not parse v4l2 endpoint\n"); 932 + return ret; 933 + } 934 + 935 + csidev->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes; 936 + if (csidev->num_lanes > STM32_CSI_LANES_MAX) { 937 + dev_err(csidev->dev, "Unsupported number of data-lanes: %d\n", 938 + csidev->num_lanes); 939 + return -EINVAL; 940 + } 941 + 942 + memcpy(csidev->lanes, v4l2_ep.bus.mipi_csi2.data_lanes, 943 + sizeof(csidev->lanes)); 944 + 945 + ep = fwnode_graph_get_next_endpoint(dev_fwnode(csidev->dev), NULL); 946 + if (!ep) { 947 + dev_err(csidev->dev, "Failed to get next endpoint\n"); 948 + return -EINVAL; 949 + } 950 + 951 + v4l2_async_subdev_nf_init(&csidev->notifier, &csidev->sd); 952 + 953 + asd = v4l2_async_nf_add_fwnode_remote(&csidev->notifier, ep, 954 + struct v4l2_async_connection); 955 + 956 + fwnode_handle_put(ep); 957 + 958 + if (IS_ERR(asd)) { 959 + dev_err(csidev->dev, "Failed to add fwnode remote subdev\n"); 960 + return PTR_ERR(asd); 961 + } 962 + 963 + csidev->notifier.ops = &stm32_csi_notifier_ops; 964 + 965 + ret = v4l2_async_nf_register(&csidev->notifier); 966 + if (ret) { 967 + dev_err(csidev->dev, "Failed to register notifier\n"); 968 + v4l2_async_nf_cleanup(&csidev->notifier); 969 + return ret; 970 + } 971 + 972 + return ret; 973 + } 974 + 975 + static int stm32_csi_probe(struct platform_device *pdev) 976 + { 977 + struct stm32_csi_dev *csidev; 978 + struct reset_control *rstc; 979 + int ret; 980 + 981 + csidev = devm_kzalloc(&pdev->dev, sizeof(*csidev), GFP_KERNEL); 982 + if (!csidev) 983 + return -ENOMEM; 984 + 985 + platform_set_drvdata(pdev, csidev); 986 + csidev->dev = &pdev->dev; 987 + 988 + spin_lock_init(&csidev->slock); 989 + 990 + ret = stm32_csi_get_resources(csidev, pdev); 991 + if (ret) 992 + goto err_free_priv; 993 + 994 + ret = stm32_csi_parse_dt(csidev); 995 + if (ret) 996 + goto err_free_priv; 997 + 998 + csidev->sd.owner = THIS_MODULE; 999 + csidev->sd.dev = &pdev->dev; 1000 + csidev->sd.internal_ops = &stm32_csi_subdev_internal_ops; 1001 + v4l2_subdev_init(&csidev->sd, &stm32_csi_subdev_ops); 1002 + v4l2_set_subdevdata(&csidev->sd, &pdev->dev); 1003 + snprintf(csidev->sd.name, sizeof(csidev->sd.name), "%s", 1004 + dev_name(&pdev->dev)); 1005 + 1006 + /* Create our media pads */ 1007 + csidev->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 1008 + csidev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1009 + csidev->pads[STM32_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK; 1010 + csidev->pads[STM32_CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 1011 + 1012 + ret = media_entity_pads_init(&csidev->sd.entity, STM32_CSI_PAD_MAX, 1013 + csidev->pads); 1014 + if (ret) 1015 + goto err_cleanup; 1016 + 1017 + ret = v4l2_subdev_init_finalize(&csidev->sd); 1018 + if (ret < 0) 1019 + goto err_cleanup; 1020 + 1021 + ret = v4l2_async_register_subdev(&csidev->sd); 1022 + if (ret < 0) 1023 + goto err_cleanup; 1024 + 1025 + /* Reset device */ 1026 + rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 1027 + if (IS_ERR(rstc)) { 1028 + ret = dev_err_probe(&pdev->dev, PTR_ERR(rstc), 1029 + "Couldn't get reset control\n"); 1030 + goto err_cleanup; 1031 + } 1032 + 1033 + ret = reset_control_assert(rstc); 1034 + if (ret) { 1035 + ret = dev_err_probe(&pdev->dev, ret, 1036 + "Failed to assert the reset line\n"); 1037 + goto err_cleanup; 1038 + } 1039 + 1040 + usleep_range(3000, 5000); 1041 + 1042 + ret = reset_control_deassert(rstc); 1043 + if (ret) { 1044 + ret = dev_err_probe(&pdev->dev, ret, 1045 + "Failed to deassert the reset line\n"); 1046 + goto err_cleanup; 1047 + } 1048 + 1049 + pm_runtime_enable(&pdev->dev); 1050 + 1051 + dev_info(&pdev->dev, 1052 + "Probed CSI with %u lanes\n", csidev->num_lanes); 1053 + 1054 + return 0; 1055 + 1056 + err_cleanup: 1057 + v4l2_async_nf_cleanup(&csidev->notifier); 1058 + err_free_priv: 1059 + return ret; 1060 + } 1061 + 1062 + static void stm32_csi_remove(struct platform_device *pdev) 1063 + { 1064 + struct stm32_csi_dev *csidev = platform_get_drvdata(pdev); 1065 + 1066 + v4l2_async_unregister_subdev(&csidev->sd); 1067 + 1068 + pm_runtime_disable(&pdev->dev); 1069 + } 1070 + 1071 + static int stm32_csi_runtime_suspend(struct device *dev) 1072 + { 1073 + struct stm32_csi_dev *csidev = dev_get_drvdata(dev); 1074 + int ret; 1075 + 1076 + clk_bulk_disable_unprepare(STM32_CSI_CLK_NB, csidev->clks); 1077 + 1078 + ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies), 1079 + csidev->supplies); 1080 + if (ret < 0) 1081 + dev_err(dev, "cannot disable regulators %d\n", ret); 1082 + 1083 + return 0; 1084 + } 1085 + 1086 + static int stm32_csi_runtime_resume(struct device *dev) 1087 + { 1088 + struct stm32_csi_dev *csidev = dev_get_drvdata(dev); 1089 + int ret; 1090 + 1091 + ret = regulator_bulk_enable(ARRAY_SIZE(csidev->supplies), 1092 + csidev->supplies); 1093 + if (ret) 1094 + goto error_out; 1095 + 1096 + ret = clk_bulk_prepare_enable(STM32_CSI_CLK_NB, csidev->clks); 1097 + if (ret) 1098 + goto error_disable_supplies; 1099 + 1100 + return 0; 1101 + 1102 + error_disable_supplies: 1103 + ret = regulator_bulk_disable(ARRAY_SIZE(csidev->supplies), csidev->supplies); 1104 + if (ret < 0) 1105 + dev_err(dev, "cannot disable regulators %d\n", ret); 1106 + error_out: 1107 + dev_err(csidev->dev, "Failed to resume: %d\n", ret); 1108 + 1109 + return ret; 1110 + } 1111 + 1112 + static const struct of_device_id stm32_csi_of_table[] = { 1113 + { .compatible = "st,stm32mp25-csi", }, 1114 + { /* end node */ }, 1115 + }; 1116 + MODULE_DEVICE_TABLE(of, stm32_csi_of_table); 1117 + 1118 + static const struct dev_pm_ops stm32_csi_pm_ops = { 1119 + RUNTIME_PM_OPS(stm32_csi_runtime_suspend, 1120 + stm32_csi_runtime_resume, NULL) 1121 + }; 1122 + 1123 + static struct platform_driver stm32_csi_driver = { 1124 + .driver = { 1125 + .name = "stm32-csi", 1126 + .of_match_table = stm32_csi_of_table, 1127 + .pm = pm_ptr(&stm32_csi_pm_ops), 1128 + }, 1129 + .probe = stm32_csi_probe, 1130 + .remove = stm32_csi_remove, 1131 + }; 1132 + 1133 + module_platform_driver(stm32_csi_driver); 1134 + 1135 + MODULE_AUTHOR("Alain Volmat <alain.volmat@foss.st.com>"); 1136 + MODULE_DESCRIPTION("STM32 CSI controller"); 1137 + MODULE_LICENSE("GPL");
+1 -1
drivers/media/platform/st/stm32/stm32-dcmipp/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - stm32-dcmipp-y := dcmipp-core.o dcmipp-common.o dcmipp-parallel.o dcmipp-byteproc.o dcmipp-bytecap.o 2 + stm32-dcmipp-y := dcmipp-core.o dcmipp-common.o dcmipp-input.o dcmipp-byteproc.o dcmipp-bytecap.o 3 3 4 4 obj-$(CONFIG_VIDEO_STM32_DCMIPP) += stm32-dcmipp.o
+71 -57
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
··· 56 56 57 57 static const struct dcmipp_bytecap_pix_map dcmipp_bytecap_pix_map_list[] = { 58 58 PIXMAP_MBUS_PFMT(RGB565_2X8_LE, RGB565), 59 + PIXMAP_MBUS_PFMT(RGB565_1X16, RGB565), 59 60 PIXMAP_MBUS_PFMT(YUYV8_2X8, YUYV), 61 + PIXMAP_MBUS_PFMT(YUYV8_1X16, YUYV), 60 62 PIXMAP_MBUS_PFMT(YVYU8_2X8, YVYU), 63 + PIXMAP_MBUS_PFMT(YVYU8_1X16, YVYU), 61 64 PIXMAP_MBUS_PFMT(UYVY8_2X8, UYVY), 65 + PIXMAP_MBUS_PFMT(UYVY8_1X16, UYVY), 62 66 PIXMAP_MBUS_PFMT(VYUY8_2X8, VYUY), 67 + PIXMAP_MBUS_PFMT(VYUY8_1X16, VYUY), 63 68 PIXMAP_MBUS_PFMT(Y8_1X8, GREY), 64 69 PIXMAP_MBUS_PFMT(SBGGR8_1X8, SBGGR8), 65 70 PIXMAP_MBUS_PFMT(SGBRG8_1X8, SGBRG8), 66 71 PIXMAP_MBUS_PFMT(SGRBG8_1X8, SGRBG8), 67 72 PIXMAP_MBUS_PFMT(SRGGB8_1X8, SRGGB8), 73 + PIXMAP_MBUS_PFMT(SBGGR10_1X10, SBGGR10), 74 + PIXMAP_MBUS_PFMT(SGBRG10_1X10, SGBRG10), 75 + PIXMAP_MBUS_PFMT(SGRBG10_1X10, SGRBG10), 76 + PIXMAP_MBUS_PFMT(SRGGB10_1X10, SRGGB10), 77 + PIXMAP_MBUS_PFMT(SBGGR12_1X12, SBGGR12), 78 + PIXMAP_MBUS_PFMT(SGBRG12_1X12, SGBRG12), 79 + PIXMAP_MBUS_PFMT(SGRBG12_1X12, SGRBG12), 80 + PIXMAP_MBUS_PFMT(SRGGB12_1X12, SRGGB12), 81 + PIXMAP_MBUS_PFMT(SBGGR14_1X14, SBGGR14), 82 + PIXMAP_MBUS_PFMT(SGBRG14_1X14, SGBRG14), 83 + PIXMAP_MBUS_PFMT(SGRBG14_1X14, SGRBG14), 84 + PIXMAP_MBUS_PFMT(SRGGB14_1X14, SRGGB14), 68 85 PIXMAP_MBUS_PFMT(JPEG_1X8, JPEG), 69 86 }; 70 87 ··· 129 112 u32 sequence; 130 113 struct media_pipeline pipe; 131 114 struct v4l2_subdev *s_subdev; 115 + u32 s_subdev_pad_nb; 132 116 133 117 enum dcmipp_state state; 134 118 ··· 268 250 { 269 251 const struct dcmipp_bytecap_pix_map *vpix; 270 252 unsigned int index = f->index; 271 - unsigned int i; 253 + unsigned int i, prev_pixelformat = 0; 272 254 273 - if (f->mbus_code) { 274 - /* 275 - * If a media bus code is specified, only enumerate formats 276 - * compatible with it. 277 - */ 278 - for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) { 279 - vpix = &dcmipp_bytecap_pix_map_list[i]; 280 - if (vpix->code != f->mbus_code) 281 - continue; 255 + /* 256 + * List up all formats (or only ones matching f->mbus_code), taking 257 + * care of removing duplicated entries (due to support of both 258 + * parallel & csi 16 bits formats 259 + */ 260 + for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) { 261 + vpix = &dcmipp_bytecap_pix_map_list[i]; 262 + /* Skip formats not matching requested mbus code */ 263 + if (f->mbus_code && vpix->code != f->mbus_code) 264 + continue; 282 265 283 - if (index == 0) 284 - break; 266 + /* Skip duplicated pixelformat */ 267 + if (vpix->pixelformat == prev_pixelformat) 268 + continue; 285 269 286 - index--; 287 - } 270 + prev_pixelformat = vpix->pixelformat; 288 271 289 - if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list)) 290 - return -EINVAL; 291 - } else { 292 - /* Otherwise, enumerate all formats. */ 293 - if (f->index >= ARRAY_SIZE(dcmipp_bytecap_pix_map_list)) 294 - return -EINVAL; 272 + if (index == 0) 273 + break; 295 274 296 - vpix = &dcmipp_bytecap_pix_map_list[f->index]; 275 + index--; 297 276 } 277 + 278 + if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list)) 279 + return -EINVAL; 298 280 299 281 f->pixelformat = vpix->pixelformat; 300 282 ··· 355 337 .vidioc_streamoff = vb2_ioctl_streamoff, 356 338 }; 357 339 358 - static int dcmipp_pipeline_s_stream(struct dcmipp_bytecap_device *vcap, 359 - int state) 360 - { 361 - struct media_pad *pad; 362 - int ret; 363 - 364 - /* 365 - * Get source subdev - since link is IMMUTABLE, pointer is cached 366 - * within the dcmipp_bytecap_device structure 367 - */ 368 - if (!vcap->s_subdev) { 369 - pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]); 370 - if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 371 - return -EINVAL; 372 - vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity); 373 - } 374 - 375 - ret = v4l2_subdev_call(vcap->s_subdev, video, s_stream, state); 376 - if (ret < 0) { 377 - dev_err(vcap->dev, "failed to %s streaming (%d)\n", 378 - state ? "start" : "stop", ret); 379 - return ret; 380 - } 381 - 382 - return 0; 383 - } 384 - 385 340 static void dcmipp_start_capture(struct dcmipp_bytecap_device *vcap, 386 341 struct dcmipp_buf *buf) 387 342 { ··· 386 395 struct dcmipp_bytecap_device *vcap = vb2_get_drv_priv(vq); 387 396 struct media_entity *entity = &vcap->vdev.entity; 388 397 struct dcmipp_buf *buf; 398 + struct media_pad *pad; 389 399 int ret; 390 400 391 401 vcap->sequence = 0; 392 402 memset(&vcap->count, 0, sizeof(vcap->count)); 403 + 404 + /* 405 + * Get source subdev - since link is IMMUTABLE, pointer is cached 406 + * within the dcmipp_bytecap_device structure 407 + */ 408 + if (!vcap->s_subdev) { 409 + pad = media_pad_remote_pad_first(&vcap->vdev.entity.pads[0]); 410 + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 411 + return -EINVAL; 412 + vcap->s_subdev = media_entity_to_v4l2_subdev(pad->entity); 413 + vcap->s_subdev_pad_nb = pad->index; 414 + } 393 415 394 416 ret = pm_runtime_resume_and_get(vcap->dev); 395 417 if (ret < 0) { ··· 418 414 goto err_pm_put; 419 415 } 420 416 421 - ret = dcmipp_pipeline_s_stream(vcap, 1); 417 + ret = v4l2_subdev_enable_streams(vcap->s_subdev, 418 + vcap->s_subdev_pad_nb, BIT_ULL(0)); 422 419 if (ret) 423 420 goto err_media_pipeline_stop; 424 421 ··· 487 482 int ret; 488 483 u32 status; 489 484 490 - dcmipp_pipeline_s_stream(vcap, 0); 485 + ret = v4l2_subdev_disable_streams(vcap->s_subdev, 486 + vcap->s_subdev_pad_nb, BIT_ULL(0)); 487 + if (ret) 488 + dev_warn(vcap->dev, "Failed to disable stream\n"); 491 489 492 490 /* Stop the media pipeline */ 493 491 media_pipeline_stop(vcap->vdev.entity.pads); ··· 818 810 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 819 811 .pad = link->source->index, 820 812 }; 821 - const struct dcmipp_bytecap_pix_map *vpix; 822 - int ret; 813 + int ret, i; 823 814 824 815 ret = v4l2_subdev_call(source_sd, pad, get_fmt, NULL, &source_fmt); 825 816 if (ret < 0) ··· 832 825 return -EINVAL; 833 826 } 834 827 835 - vpix = dcmipp_bytecap_pix_map_by_pixelformat(vcap->format.pixelformat); 836 - if (source_fmt.format.code != vpix->code) { 837 - dev_err(vcap->dev, "Wrong mbus_code 0x%x, (0x%x expected)\n", 838 - vpix->code, source_fmt.format.code); 828 + for (i = 0; i < ARRAY_SIZE(dcmipp_bytecap_pix_map_list); i++) { 829 + if (dcmipp_bytecap_pix_map_list[i].pixelformat == 830 + vcap->format.pixelformat && 831 + dcmipp_bytecap_pix_map_list[i].code == 832 + source_fmt.format.code) 833 + break; 834 + } 835 + 836 + if (i == ARRAY_SIZE(dcmipp_bytecap_pix_map_list)) { 837 + dev_err(vcap->dev, "mbus code 0x%x do not match capture device format (0x%x)\n", 838 + vcap->format.pixelformat, source_fmt.format.code); 839 839 return -EINVAL; 840 840 } 841 841 ··· 901 887 q->dev = dev; 902 888 903 889 /* DCMIPP requires 16 bytes aligned buffers */ 904 - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32) & ~0x0f); 890 + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 905 891 if (ret) { 906 892 dev_err(dev, "Failed to set DMA mask\n"); 907 893 goto err_mutex_destroy;
+73 -44
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c
··· 48 48 } 49 49 static const struct dcmipp_byteproc_pix_map dcmipp_byteproc_pix_map_list[] = { 50 50 PIXMAP_MBUS_BPP(RGB565_2X8_LE, 2), 51 + PIXMAP_MBUS_BPP(RGB565_1X16, 2), 51 52 PIXMAP_MBUS_BPP(YUYV8_2X8, 2), 53 + PIXMAP_MBUS_BPP(YUYV8_1X16, 2), 52 54 PIXMAP_MBUS_BPP(YVYU8_2X8, 2), 55 + PIXMAP_MBUS_BPP(YVYU8_1X16, 2), 53 56 PIXMAP_MBUS_BPP(UYVY8_2X8, 2), 57 + PIXMAP_MBUS_BPP(UYVY8_1X16, 2), 54 58 PIXMAP_MBUS_BPP(VYUY8_2X8, 2), 59 + PIXMAP_MBUS_BPP(VYUY8_1X16, 2), 55 60 PIXMAP_MBUS_BPP(Y8_1X8, 1), 56 61 PIXMAP_MBUS_BPP(SBGGR8_1X8, 1), 57 62 PIXMAP_MBUS_BPP(SGBRG8_1X8, 1), 58 63 PIXMAP_MBUS_BPP(SGRBG8_1X8, 1), 59 64 PIXMAP_MBUS_BPP(SRGGB8_1X8, 1), 65 + PIXMAP_MBUS_BPP(SBGGR10_1X10, 2), 66 + PIXMAP_MBUS_BPP(SGBRG10_1X10, 2), 67 + PIXMAP_MBUS_BPP(SGRBG10_1X10, 2), 68 + PIXMAP_MBUS_BPP(SRGGB10_1X10, 2), 69 + PIXMAP_MBUS_BPP(SBGGR12_1X12, 2), 70 + PIXMAP_MBUS_BPP(SGBRG12_1X12, 2), 71 + PIXMAP_MBUS_BPP(SGRBG12_1X12, 2), 72 + PIXMAP_MBUS_BPP(SRGGB12_1X12, 2), 73 + PIXMAP_MBUS_BPP(SBGGR14_1X14, 2), 74 + PIXMAP_MBUS_BPP(SGBRG14_1X14, 2), 75 + PIXMAP_MBUS_BPP(SGRBG14_1X14, 2), 76 + PIXMAP_MBUS_BPP(SRGGB14_1X14, 2), 60 77 PIXMAP_MBUS_BPP(JPEG_1X8, 1), 61 78 }; 62 79 ··· 95 78 struct v4l2_subdev sd; 96 79 struct device *dev; 97 80 void __iomem *regs; 98 - bool streaming; 99 81 }; 100 82 101 83 static const struct v4l2_mbus_framefmt fmt_default = { ··· 255 239 struct v4l2_subdev_state *sd_state, 256 240 struct v4l2_subdev_format *fmt) 257 241 { 258 - struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd); 259 242 struct v4l2_mbus_framefmt *mf; 260 243 struct v4l2_rect *crop, *compose; 261 244 262 - if (byteproc->streaming) 245 + if (v4l2_subdev_is_streaming(sd)) 263 246 return -EBUSY; 264 247 265 248 mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); ··· 397 382 return 0; 398 383 } 399 384 400 - static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = { 401 - .enum_mbus_code = dcmipp_byteproc_enum_mbus_code, 402 - .enum_frame_size = dcmipp_byteproc_enum_frame_size, 403 - .get_fmt = v4l2_subdev_get_fmt, 404 - .set_fmt = dcmipp_byteproc_set_fmt, 405 - .get_selection = dcmipp_byteproc_get_selection, 406 - .set_selection = dcmipp_byteproc_set_selection, 407 - }; 408 - 409 385 static int dcmipp_byteproc_configure_scale_crop 410 - (struct dcmipp_byteproc_device *byteproc) 386 + (struct dcmipp_byteproc_device *byteproc, 387 + struct v4l2_subdev_state *state) 411 388 { 412 389 const struct dcmipp_byteproc_pix_map *vpix; 413 - struct v4l2_subdev_state *state; 414 390 struct v4l2_mbus_framefmt *sink_fmt; 415 391 u32 hprediv, vprediv; 416 392 struct v4l2_rect *compose, *crop; 417 393 u32 val = 0; 418 394 419 - state = v4l2_subdev_lock_and_get_active_state(&byteproc->sd); 420 395 sink_fmt = v4l2_subdev_state_get_format(state, 0); 421 396 compose = v4l2_subdev_state_get_compose(state, 0); 422 397 crop = v4l2_subdev_state_get_crop(state, 1); 423 - v4l2_subdev_unlock_state(state); 424 398 425 399 /* find output format bpp */ 426 400 vpix = dcmipp_byteproc_pix_map_by_code(sink_fmt->code); ··· 464 460 return 0; 465 461 } 466 462 467 - static int dcmipp_byteproc_s_stream(struct v4l2_subdev *sd, int enable) 463 + static int dcmipp_byteproc_enable_streams(struct v4l2_subdev *sd, 464 + struct v4l2_subdev_state *state, 465 + u32 pad, u64 streams_mask) 468 466 { 469 467 struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd); 470 468 struct v4l2_subdev *s_subdev; 471 - struct media_pad *pad; 472 - int ret = 0; 469 + struct media_pad *s_pad; 470 + int ret; 473 471 474 472 /* Get source subdev */ 475 - pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 476 - if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 473 + s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 474 + if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity)) 477 475 return -EINVAL; 478 - s_subdev = media_entity_to_v4l2_subdev(pad->entity); 476 + s_subdev = media_entity_to_v4l2_subdev(s_pad->entity); 479 477 480 - if (enable) { 481 - ret = dcmipp_byteproc_configure_scale_crop(byteproc); 482 - if (ret) 483 - return ret; 478 + ret = dcmipp_byteproc_configure_scale_crop(byteproc, state); 479 + if (ret) 480 + return ret; 484 481 485 - ret = v4l2_subdev_call(s_subdev, video, s_stream, enable); 486 - if (ret < 0) { 487 - dev_err(byteproc->dev, 488 - "failed to start source subdev streaming (%d)\n", 489 - ret); 490 - return ret; 491 - } 492 - } else { 493 - ret = v4l2_subdev_call(s_subdev, video, s_stream, enable); 494 - if (ret < 0) { 495 - dev_err(byteproc->dev, 496 - "failed to stop source subdev streaming (%d)\n", 497 - ret); 498 - return ret; 499 - } 482 + ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0)); 483 + if (ret < 0) { 484 + dev_err(byteproc->dev, 485 + "failed to start source subdev streaming (%d)\n", ret); 486 + return ret; 500 487 } 501 - 502 - byteproc->streaming = enable; 503 488 504 489 return 0; 505 490 } 506 491 492 + static int dcmipp_byteproc_disable_streams(struct v4l2_subdev *sd, 493 + struct v4l2_subdev_state *state, 494 + u32 pad, u64 streams_mask) 495 + { 496 + struct dcmipp_byteproc_device *byteproc = v4l2_get_subdevdata(sd); 497 + struct v4l2_subdev *s_subdev; 498 + struct media_pad *s_pad; 499 + int ret; 500 + 501 + /* Get source subdev */ 502 + s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 503 + if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity)) 504 + return -EINVAL; 505 + s_subdev = media_entity_to_v4l2_subdev(s_pad->entity); 506 + 507 + ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0)); 508 + if (ret < 0) { 509 + dev_err(byteproc->dev, 510 + "failed to start source subdev streaming (%d)\n", ret); 511 + return ret; 512 + } 513 + 514 + return 0; 515 + } 516 + 517 + static const struct v4l2_subdev_pad_ops dcmipp_byteproc_pad_ops = { 518 + .enum_mbus_code = dcmipp_byteproc_enum_mbus_code, 519 + .enum_frame_size = dcmipp_byteproc_enum_frame_size, 520 + .get_fmt = v4l2_subdev_get_fmt, 521 + .set_fmt = dcmipp_byteproc_set_fmt, 522 + .get_selection = dcmipp_byteproc_get_selection, 523 + .set_selection = dcmipp_byteproc_set_selection, 524 + .enable_streams = dcmipp_byteproc_enable_streams, 525 + .disable_streams = dcmipp_byteproc_disable_streams, 526 + }; 527 + 507 528 static const struct v4l2_subdev_video_ops dcmipp_byteproc_video_ops = { 508 - .s_stream = dcmipp_byteproc_s_stream, 529 + .s_stream = v4l2_subdev_s_stream_helper, 509 530 }; 510 531 511 532 static const struct v4l2_subdev_ops dcmipp_byteproc_ops = {
+2 -2
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h
··· 199 199 } 200 200 201 201 /* DCMIPP subdev init / release entry points */ 202 - struct dcmipp_ent_device *dcmipp_par_ent_init(struct device *dev, 202 + struct dcmipp_ent_device *dcmipp_inp_ent_init(struct device *dev, 203 203 const char *entity_name, 204 204 struct v4l2_device *v4l2_dev, 205 205 void __iomem *regs); 206 - void dcmipp_par_ent_release(struct dcmipp_ent_device *ved); 206 + void dcmipp_inp_ent_release(struct dcmipp_ent_device *ved); 207 207 struct dcmipp_ent_device * 208 208 dcmipp_byteproc_ent_init(struct device *dev, const char *entity_name, 209 209 struct v4l2_device *v4l2_dev, void __iomem *regs);
+96 -26
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
··· 40 40 41 41 /* Hardware resources */ 42 42 void __iomem *regs; 43 + struct clk *mclk; 43 44 struct clk *kclk; 44 45 45 46 /* The pipeline configuration */ ··· 88 87 size_t num_ents; 89 88 const struct dcmipp_ent_link *links; 90 89 size_t num_links; 90 + u32 hw_revision; 91 91 }; 92 92 93 93 /* -------------------------------------------------------------------------- ··· 97 95 98 96 static const struct dcmipp_ent_config stm32mp13_ent_config[] = { 99 97 { 100 - .name = "dcmipp_parallel", 101 - .init = dcmipp_par_ent_init, 102 - .release = dcmipp_par_ent_release, 98 + .name = "dcmipp_input", 99 + .init = dcmipp_inp_ent_init, 100 + .release = dcmipp_inp_ent_release, 103 101 }, 104 102 { 105 103 .name = "dcmipp_dump_postproc", ··· 113 111 }, 114 112 }; 115 113 116 - #define ID_PARALLEL 0 114 + #define ID_INPUT 0 117 115 #define ID_DUMP_BYTEPROC 1 118 116 #define ID_DUMP_CAPTURE 2 119 117 120 118 static const struct dcmipp_ent_link stm32mp13_ent_links[] = { 121 - DCMIPP_ENT_LINK(ID_PARALLEL, 1, ID_DUMP_BYTEPROC, 0, 119 + DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0, 122 120 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), 123 121 DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE, 0, 124 122 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), 125 123 }; 126 124 125 + #define DCMIPP_STM32MP13_VERR 0x10 127 126 static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = { 128 127 .ents = stm32mp13_ent_config, 129 128 .num_ents = ARRAY_SIZE(stm32mp13_ent_config), 130 129 .links = stm32mp13_ent_links, 131 - .num_links = ARRAY_SIZE(stm32mp13_ent_links) 130 + .num_links = ARRAY_SIZE(stm32mp13_ent_links), 131 + .hw_revision = DCMIPP_STM32MP13_VERR 132 + }; 133 + 134 + static const struct dcmipp_ent_config stm32mp25_ent_config[] = { 135 + { 136 + .name = "dcmipp_input", 137 + .init = dcmipp_inp_ent_init, 138 + .release = dcmipp_inp_ent_release, 139 + }, 140 + { 141 + .name = "dcmipp_dump_postproc", 142 + .init = dcmipp_byteproc_ent_init, 143 + .release = dcmipp_byteproc_ent_release, 144 + }, 145 + { 146 + .name = "dcmipp_dump_capture", 147 + .init = dcmipp_bytecap_ent_init, 148 + .release = dcmipp_bytecap_ent_release, 149 + }, 150 + }; 151 + 152 + static const struct dcmipp_ent_link stm32mp25_ent_links[] = { 153 + DCMIPP_ENT_LINK(ID_INPUT, 1, ID_DUMP_BYTEPROC, 0, 154 + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), 155 + DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE, 0, 156 + MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE), 157 + }; 158 + 159 + #define DCMIPP_STM32MP25_VERR 0x30 160 + static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = { 161 + .ents = stm32mp25_ent_config, 162 + .num_ents = ARRAY_SIZE(stm32mp25_ent_config), 163 + .links = stm32mp25_ent_links, 164 + .num_links = ARRAY_SIZE(stm32mp25_ent_links), 165 + .hw_revision = DCMIPP_STM32MP25_VERR 132 166 }; 133 167 134 168 #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\ ··· 247 209 248 210 static const struct of_device_id dcmipp_of_match[] = { 249 211 { .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg }, 212 + { .compatible = "st,stm32mp25-dcmipp", .data = &stm32mp25_pipe_cfg }, 250 213 { /* end node */ }, 251 214 }; 252 215 MODULE_DEVICE_TABLE(of, dcmipp_of_match); ··· 297 258 { 298 259 struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier); 299 260 unsigned int ret; 300 - int src_pad; 261 + int src_pad, i; 301 262 struct dcmipp_ent_device *sink; 302 - struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL }; 263 + struct v4l2_fwnode_endpoint vep = { 0 }; 303 264 struct fwnode_handle *ep; 265 + enum v4l2_mbus_type supported_types[] = { 266 + V4L2_MBUS_PARALLEL, V4L2_MBUS_BT656, V4L2_MBUS_CSI2_DPHY 267 + }; 268 + int supported_types_nb = ARRAY_SIZE(supported_types); 304 269 305 270 dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name); 271 + 272 + /* Only MP25 supports CSI input */ 273 + if (!of_device_is_compatible(dcmipp->dev->of_node, 274 + "st,stm32mp25-dcmipp")) 275 + supported_types_nb--; 306 276 307 277 /* 308 278 * Link this sub-device to DCMIPP, it could be ··· 329 281 return -ENODEV; 330 282 } 331 283 332 - /* Check for parallel bus-type first, then bt656 */ 333 - ret = v4l2_fwnode_endpoint_parse(ep, &vep); 334 - if (ret) { 335 - vep.bus_type = V4L2_MBUS_BT656; 284 + /* Check for supported MBUS type */ 285 + for (i = 0; i < supported_types_nb; i++) { 286 + vep.bus_type = supported_types[i]; 336 287 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 337 - if (ret) { 338 - dev_err(dcmipp->dev, "Could not parse the endpoint\n"); 339 - fwnode_handle_put(ep); 340 - return ret; 341 - } 288 + if (!ret) 289 + break; 342 290 } 343 291 344 292 fwnode_handle_put(ep); 345 293 346 - if (vep.bus.parallel.bus_width == 0) { 294 + if (ret) { 295 + dev_err(dcmipp->dev, "Could not parse the endpoint\n"); 296 + return ret; 297 + } 298 + 299 + if (vep.bus_type != V4L2_MBUS_CSI2_DPHY && 300 + vep.bus.parallel.bus_width == 0) { 347 301 dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n"); 348 302 return -ENODEV; 349 303 } ··· 358 308 return -ENODEV; 359 309 } 360 310 361 - /* Parallel input device detected, connect it to parallel subdev */ 362 - sink = dcmipp->entity[ID_PARALLEL]; 363 - sink->bus.flags = vep.bus.parallel.flags; 364 - sink->bus.bus_width = vep.bus.parallel.bus_width; 365 - sink->bus.data_shift = vep.bus.parallel.data_shift; 311 + /* Connect input device to the dcmipp_input subdev */ 312 + sink = dcmipp->entity[ID_INPUT]; 313 + if (vep.bus_type != V4L2_MBUS_CSI2_DPHY) { 314 + sink->bus.flags = vep.bus.parallel.flags; 315 + sink->bus.bus_width = vep.bus.parallel.bus_width; 316 + sink->bus.data_shift = vep.bus.parallel.data_shift; 317 + } 366 318 sink->bus_type = vep.bus_type; 367 319 ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0, 368 320 MEDIA_LNK_FL_IMMUTABLE | ··· 463 411 static int dcmipp_probe(struct platform_device *pdev) 464 412 { 465 413 struct dcmipp_device *dcmipp; 466 - struct clk *kclk; 414 + struct clk *kclk, *mclk; 467 415 const struct dcmipp_pipeline_config *pipe_cfg; 468 416 struct reset_control *rstc; 469 417 int irq; ··· 523 471 return ret; 524 472 } 525 473 526 - kclk = devm_clk_get(&pdev->dev, NULL); 474 + kclk = devm_clk_get(&pdev->dev, "kclk"); 527 475 if (IS_ERR(kclk)) 528 476 return dev_err_probe(&pdev->dev, PTR_ERR(kclk), 529 477 "Unable to get kclk\n"); 530 478 dcmipp->kclk = kclk; 479 + 480 + if (!of_device_is_compatible(pdev->dev.of_node, "st,stm32mp13-dcmipp")) { 481 + mclk = devm_clk_get(&pdev->dev, "mclk"); 482 + if (IS_ERR(mclk)) 483 + return dev_err_probe(&pdev->dev, PTR_ERR(mclk), 484 + "Unable to get mclk\n"); 485 + dcmipp->mclk = mclk; 486 + } 531 487 532 488 dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents, 533 489 sizeof(*dcmipp->entity), GFP_KERNEL); ··· 556 496 /* Initialize media device */ 557 497 strscpy(dcmipp->mdev.model, DCMIPP_MDEV_MODEL_NAME, 558 498 sizeof(dcmipp->mdev.model)); 499 + dcmipp->mdev.hw_revision = pipe_cfg->hw_revision; 559 500 dcmipp->mdev.dev = &pdev->dev; 560 501 media_device_init(&dcmipp->mdev); 561 502 ··· 599 538 struct dcmipp_device *dcmipp = dev_get_drvdata(dev); 600 539 601 540 clk_disable_unprepare(dcmipp->kclk); 541 + clk_disable_unprepare(dcmipp->mclk); 602 542 603 543 return 0; 604 544 } ··· 609 547 struct dcmipp_device *dcmipp = dev_get_drvdata(dev); 610 548 int ret; 611 549 550 + ret = clk_prepare_enable(dcmipp->mclk); 551 + if (ret) { 552 + dev_err(dev, "%s: Failed to prepare_enable mclk\n", __func__); 553 + return ret; 554 + } 555 + 612 556 ret = clk_prepare_enable(dcmipp->kclk); 613 - if (ret) 557 + if (ret) { 558 + clk_disable_unprepare(dcmipp->mclk); 614 559 dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__); 560 + } 615 561 616 562 return ret; 617 563 }
+540
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Driver for STM32 Digital Camera Memory Interface Pixel Processor 4 + * 5 + * Copyright (C) STMicroelectronics SA 2023 6 + * Authors: Hugues Fruchet <hugues.fruchet@foss.st.com> 7 + * Alain Volmat <alain.volmat@foss.st.com> 8 + * for STMicroelectronics. 9 + */ 10 + 11 + #include <linux/v4l2-mediabus.h> 12 + #include <media/mipi-csi2.h> 13 + #include <media/v4l2-event.h> 14 + #include <media/v4l2-subdev.h> 15 + 16 + #include "dcmipp-common.h" 17 + 18 + #define DCMIPP_PRCR 0x104 19 + #define DCMIPP_PRCR_FORMAT_SHIFT 16 20 + #define DCMIPP_PRCR_FORMAT_YUV422 0x1e 21 + #define DCMIPP_PRCR_FORMAT_RGB565 0x22 22 + #define DCMIPP_PRCR_FORMAT_RAW8 0x2a 23 + #define DCMIPP_PRCR_FORMAT_RAW10 0x2b 24 + #define DCMIPP_PRCR_FORMAT_RAW12 0x2c 25 + #define DCMIPP_PRCR_FORMAT_RAW14 0x2d 26 + #define DCMIPP_PRCR_FORMAT_G8 0x4a 27 + #define DCMIPP_PRCR_FORMAT_BYTE_STREAM 0x5a 28 + #define DCMIPP_PRCR_ESS BIT(4) 29 + #define DCMIPP_PRCR_PCKPOL BIT(5) 30 + #define DCMIPP_PRCR_HSPOL BIT(6) 31 + #define DCMIPP_PRCR_VSPOL BIT(7) 32 + #define DCMIPP_PRCR_ENABLE BIT(14) 33 + #define DCMIPP_PRCR_SWAPCYCLES BIT(25) 34 + 35 + #define DCMIPP_PRESCR 0x108 36 + #define DCMIPP_PRESUR 0x10c 37 + 38 + #define DCMIPP_CMCR 0x204 39 + #define DCMIPP_CMCR_INSEL BIT(0) 40 + 41 + #define DCMIPP_P0FSCR 0x404 42 + #define DCMIPP_P0FSCR_DTMODE_MASK GENMASK(17, 16) 43 + #define DCMIPP_P0FSCR_DTMODE_SHIFT 16 44 + #define DCMIPP_P0FSCR_DTMODE_DTIDA 0x00 45 + #define DCMIPP_P0FSCR_DTMODE_ALLDT 0x03 46 + #define DCMIPP_P0FSCR_DTIDA_MASK GENMASK(5, 0) 47 + #define DCMIPP_P0FSCR_DTIDA_SHIFT 0 48 + 49 + #define IS_SINK(pad) (!(pad)) 50 + #define IS_SRC(pad) ((pad)) 51 + 52 + struct dcmipp_inp_pix_map { 53 + unsigned int code_sink; 54 + unsigned int code_src; 55 + /* Parallel related information */ 56 + u8 prcr_format; 57 + u8 prcr_swapcycles; 58 + /* CSI related information */ 59 + unsigned int dt; 60 + }; 61 + 62 + #define PIXMAP_SINK_SRC_PRCR_SWAP(sink, src, prcr, swap, data_type) \ 63 + { \ 64 + .code_sink = MEDIA_BUS_FMT_##sink, \ 65 + .code_src = MEDIA_BUS_FMT_##src, \ 66 + .prcr_format = DCMIPP_PRCR_FORMAT_##prcr, \ 67 + .prcr_swapcycles = swap, \ 68 + .dt = data_type, \ 69 + } 70 + static const struct dcmipp_inp_pix_map dcmipp_inp_pix_map_list[] = { 71 + /* RGB565 */ 72 + PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_LE, RGB565_2X8_LE, RGB565, 1, MIPI_CSI2_DT_RGB565), 73 + PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_BE, RGB565_2X8_LE, RGB565, 0, MIPI_CSI2_DT_RGB565), 74 + PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_1X16, RGB565_1X16, RGB565, 0, MIPI_CSI2_DT_RGB565), 75 + /* YUV422 */ 76 + PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), 77 + PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_1X16, YUYV8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 78 + PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 79 + PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), 80 + PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_1X16, UYVY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 81 + PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 82 + PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), 83 + PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_1X16, YVYU8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 84 + PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), 85 + PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_1X16, VYUY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), 86 + /* GREY */ 87 + PIXMAP_SINK_SRC_PRCR_SWAP(Y8_1X8, Y8_1X8, G8, 0, MIPI_CSI2_DT_RAW8), 88 + /* Raw Bayer */ 89 + PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR8_1X8, SBGGR8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8), 90 + PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG8_1X8, SGBRG8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8), 91 + PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG8_1X8, SGRBG8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8), 92 + PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB8_1X8, SRGGB8_1X8, RAW8, 0, MIPI_CSI2_DT_RAW8), 93 + PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR10_1X10, SBGGR10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10), 94 + PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG10_1X10, SGBRG10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10), 95 + PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG10_1X10, SGRBG10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10), 96 + PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB10_1X10, SRGGB10_1X10, RAW10, 0, MIPI_CSI2_DT_RAW10), 97 + PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR12_1X12, SBGGR12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12), 98 + PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG12_1X12, SGBRG12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12), 99 + PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG12_1X12, SGRBG12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12), 100 + PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB12_1X12, SRGGB12_1X12, RAW12, 0, MIPI_CSI2_DT_RAW12), 101 + PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR14_1X14, SBGGR14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14), 102 + PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG14_1X14, SGBRG14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14), 103 + PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG14_1X14, SGRBG14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14), 104 + PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB14_1X14, SRGGB14_1X14, RAW14, 0, MIPI_CSI2_DT_RAW14), 105 + /* JPEG */ 106 + PIXMAP_SINK_SRC_PRCR_SWAP(JPEG_1X8, JPEG_1X8, BYTE_STREAM, 0, 0), 107 + }; 108 + 109 + /* 110 + * Search through the pix_map table, skipping two consecutive entry with the 111 + * same code 112 + */ 113 + static inline const struct dcmipp_inp_pix_map *dcmipp_inp_pix_map_by_index 114 + (unsigned int index, 115 + unsigned int pad) 116 + { 117 + unsigned int i = 0; 118 + u32 prev_code = 0, cur_code; 119 + 120 + while (i < ARRAY_SIZE(dcmipp_inp_pix_map_list)) { 121 + if (IS_SRC(pad)) 122 + cur_code = dcmipp_inp_pix_map_list[i].code_src; 123 + else 124 + cur_code = dcmipp_inp_pix_map_list[i].code_sink; 125 + 126 + if (cur_code == prev_code) { 127 + i++; 128 + continue; 129 + } 130 + prev_code = cur_code; 131 + 132 + if (index == 0) 133 + break; 134 + i++; 135 + index--; 136 + } 137 + 138 + if (i >= ARRAY_SIZE(dcmipp_inp_pix_map_list)) 139 + return NULL; 140 + 141 + return &dcmipp_inp_pix_map_list[i]; 142 + } 143 + 144 + static inline const struct dcmipp_inp_pix_map *dcmipp_inp_pix_map_by_code 145 + (u32 code_sink, u32 code_src) 146 + { 147 + unsigned int i; 148 + 149 + for (i = 0; i < ARRAY_SIZE(dcmipp_inp_pix_map_list); i++) { 150 + if ((dcmipp_inp_pix_map_list[i].code_sink == code_sink && 151 + dcmipp_inp_pix_map_list[i].code_src == code_src) || 152 + (dcmipp_inp_pix_map_list[i].code_sink == code_src && 153 + dcmipp_inp_pix_map_list[i].code_src == code_sink) || 154 + (dcmipp_inp_pix_map_list[i].code_sink == code_sink && 155 + code_src == 0) || 156 + (code_sink == 0 && 157 + dcmipp_inp_pix_map_list[i].code_src == code_src)) 158 + return &dcmipp_inp_pix_map_list[i]; 159 + } 160 + return NULL; 161 + } 162 + 163 + struct dcmipp_inp_device { 164 + struct dcmipp_ent_device ved; 165 + struct v4l2_subdev sd; 166 + struct device *dev; 167 + void __iomem *regs; 168 + }; 169 + 170 + static const struct v4l2_mbus_framefmt fmt_default = { 171 + .width = DCMIPP_FMT_WIDTH_DEFAULT, 172 + .height = DCMIPP_FMT_HEIGHT_DEFAULT, 173 + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, 174 + .field = V4L2_FIELD_NONE, 175 + .colorspace = DCMIPP_COLORSPACE_DEFAULT, 176 + .ycbcr_enc = DCMIPP_YCBCR_ENC_DEFAULT, 177 + .quantization = DCMIPP_QUANTIZATION_DEFAULT, 178 + .xfer_func = DCMIPP_XFER_FUNC_DEFAULT, 179 + }; 180 + 181 + static int dcmipp_inp_init_state(struct v4l2_subdev *sd, 182 + struct v4l2_subdev_state *sd_state) 183 + { 184 + unsigned int i; 185 + 186 + for (i = 0; i < sd->entity.num_pads; i++) { 187 + struct v4l2_mbus_framefmt *mf; 188 + 189 + mf = v4l2_subdev_state_get_format(sd_state, i); 190 + *mf = fmt_default; 191 + } 192 + 193 + return 0; 194 + } 195 + 196 + static int dcmipp_inp_enum_mbus_code(struct v4l2_subdev *sd, 197 + struct v4l2_subdev_state *sd_state, 198 + struct v4l2_subdev_mbus_code_enum *code) 199 + { 200 + const struct dcmipp_inp_pix_map *vpix = 201 + dcmipp_inp_pix_map_by_index(code->index, code->pad); 202 + 203 + if (!vpix) 204 + return -EINVAL; 205 + 206 + code->code = IS_SRC(code->pad) ? vpix->code_src : vpix->code_sink; 207 + 208 + return 0; 209 + } 210 + 211 + static int dcmipp_inp_enum_frame_size(struct v4l2_subdev *sd, 212 + struct v4l2_subdev_state *sd_state, 213 + struct v4l2_subdev_frame_size_enum *fse) 214 + { 215 + const struct dcmipp_inp_pix_map *vpix; 216 + 217 + if (fse->index) 218 + return -EINVAL; 219 + 220 + /* Only accept code in the pix map table */ 221 + vpix = dcmipp_inp_pix_map_by_code(IS_SINK(fse->pad) ? fse->code : 0, 222 + IS_SRC(fse->pad) ? fse->code : 0); 223 + if (!vpix) 224 + return -EINVAL; 225 + 226 + fse->min_width = DCMIPP_FRAME_MIN_WIDTH; 227 + fse->max_width = DCMIPP_FRAME_MAX_WIDTH; 228 + fse->min_height = DCMIPP_FRAME_MIN_HEIGHT; 229 + fse->max_height = DCMIPP_FRAME_MAX_HEIGHT; 230 + 231 + return 0; 232 + } 233 + 234 + static void dcmipp_inp_adjust_fmt(struct dcmipp_inp_device *inp, 235 + struct v4l2_mbus_framefmt *fmt, __u32 pad) 236 + { 237 + const struct dcmipp_inp_pix_map *vpix; 238 + 239 + /* Only accept code in the pix map table */ 240 + vpix = dcmipp_inp_pix_map_by_code(IS_SINK(pad) ? fmt->code : 0, 241 + IS_SRC(pad) ? fmt->code : 0); 242 + if (!vpix) 243 + fmt->code = fmt_default.code; 244 + 245 + /* Exclude JPEG if BT656 bus is selected */ 246 + if (vpix && vpix->code_sink == MEDIA_BUS_FMT_JPEG_1X8 && 247 + inp->ved.bus_type == V4L2_MBUS_BT656) 248 + fmt->code = fmt_default.code; 249 + 250 + fmt->width = clamp_t(u32, fmt->width, DCMIPP_FRAME_MIN_WIDTH, 251 + DCMIPP_FRAME_MAX_WIDTH) & ~1; 252 + fmt->height = clamp_t(u32, fmt->height, DCMIPP_FRAME_MIN_HEIGHT, 253 + DCMIPP_FRAME_MAX_HEIGHT) & ~1; 254 + 255 + if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE) 256 + fmt->field = fmt_default.field; 257 + 258 + dcmipp_colorimetry_clamp(fmt); 259 + } 260 + 261 + static int dcmipp_inp_set_fmt(struct v4l2_subdev *sd, 262 + struct v4l2_subdev_state *sd_state, 263 + struct v4l2_subdev_format *fmt) 264 + { 265 + struct dcmipp_inp_device *inp = v4l2_get_subdevdata(sd); 266 + struct v4l2_mbus_framefmt *mf; 267 + 268 + if (v4l2_subdev_is_streaming(sd)) 269 + return -EBUSY; 270 + 271 + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); 272 + 273 + /* Set the new format */ 274 + dcmipp_inp_adjust_fmt(inp, &fmt->format, fmt->pad); 275 + 276 + dev_dbg(inp->dev, "%s: format update: old:%dx%d (0x%x, %d, %d, %d, %d) new:%dx%d (0x%x, %d, %d, %d, %d)\n", 277 + inp->sd.name, 278 + /* old */ 279 + mf->width, mf->height, mf->code, 280 + mf->colorspace, mf->quantization, 281 + mf->xfer_func, mf->ycbcr_enc, 282 + /* new */ 283 + fmt->format.width, fmt->format.height, fmt->format.code, 284 + fmt->format.colorspace, fmt->format.quantization, 285 + fmt->format.xfer_func, fmt->format.ycbcr_enc); 286 + 287 + *mf = fmt->format; 288 + 289 + /* When setting the sink format, report that format on the src pad */ 290 + if (IS_SINK(fmt->pad)) { 291 + mf = v4l2_subdev_state_get_format(sd_state, 1); 292 + *mf = fmt->format; 293 + dcmipp_inp_adjust_fmt(inp, mf, 1); 294 + } 295 + 296 + return 0; 297 + } 298 + 299 + static int dcmipp_inp_configure_parallel(struct dcmipp_inp_device *inp, 300 + struct v4l2_subdev_state *state) 301 + { 302 + u32 val = 0; 303 + const struct dcmipp_inp_pix_map *vpix; 304 + struct v4l2_mbus_framefmt *sink_fmt; 305 + struct v4l2_mbus_framefmt *src_fmt; 306 + 307 + /* Set vertical synchronization polarity */ 308 + if (inp->ved.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) 309 + val |= DCMIPP_PRCR_VSPOL; 310 + 311 + /* Set horizontal synchronization polarity */ 312 + if (inp->ved.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) 313 + val |= DCMIPP_PRCR_HSPOL; 314 + 315 + /* Set pixel clock polarity */ 316 + if (inp->ved.bus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING) 317 + val |= DCMIPP_PRCR_PCKPOL; 318 + 319 + /* 320 + * BT656 embedded synchronisation bus mode. 321 + * 322 + * Default SAV/EAV mode is supported here with default codes 323 + * SAV=0xff000080 & EAV=0xff00009d. 324 + * With DCMIPP this means LSC=SAV=0x80 & LEC=EAV=0x9d. 325 + */ 326 + if (inp->ved.bus_type == V4L2_MBUS_BT656) { 327 + val |= DCMIPP_PRCR_ESS; 328 + 329 + /* Unmask all codes */ 330 + reg_write(inp, DCMIPP_PRESUR, 0xffffffff);/* FEC:LEC:LSC:FSC */ 331 + 332 + /* Trig on LSC=0x80 & LEC=0x9d codes, ignore FSC and FEC */ 333 + reg_write(inp, DCMIPP_PRESCR, 0xff9d80ff);/* FEC:LEC:LSC:FSC */ 334 + } 335 + 336 + /* Set format */ 337 + sink_fmt = v4l2_subdev_state_get_format(state, 0); 338 + src_fmt = v4l2_subdev_state_get_format(state, 1); 339 + 340 + vpix = dcmipp_inp_pix_map_by_code(sink_fmt->code, src_fmt->code); 341 + if (!vpix) { 342 + dev_err(inp->dev, "Invalid sink/src format configuration\n"); 343 + return -EINVAL; 344 + } 345 + 346 + val |= vpix->prcr_format << DCMIPP_PRCR_FORMAT_SHIFT; 347 + 348 + /* swap cycles */ 349 + if (vpix->prcr_swapcycles) 350 + val |= DCMIPP_PRCR_SWAPCYCLES; 351 + 352 + reg_write(inp, DCMIPP_PRCR, val); 353 + 354 + /* Select the DCMIPP parallel interface */ 355 + reg_write(inp, DCMIPP_CMCR, 0); 356 + 357 + /* Enable parallel interface */ 358 + reg_set(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE); 359 + 360 + return 0; 361 + } 362 + 363 + static int dcmipp_inp_configure_csi(struct dcmipp_inp_device *inp, 364 + struct v4l2_subdev_state *state) 365 + { 366 + const struct dcmipp_inp_pix_map *vpix; 367 + struct v4l2_mbus_framefmt *sink_fmt; 368 + struct v4l2_mbus_framefmt *src_fmt; 369 + 370 + /* Get format information */ 371 + sink_fmt = v4l2_subdev_state_get_format(state, 0); 372 + src_fmt = v4l2_subdev_state_get_format(state, 1); 373 + 374 + vpix = dcmipp_inp_pix_map_by_code(sink_fmt->code, src_fmt->code); 375 + if (!vpix) { 376 + dev_err(inp->dev, "Invalid sink/src format configuration\n"); 377 + return -EINVAL; 378 + } 379 + 380 + /* Apply configuration on each input pipe */ 381 + reg_clear(inp, DCMIPP_P0FSCR, 382 + DCMIPP_P0FSCR_DTMODE_MASK | DCMIPP_P0FSCR_DTIDA_MASK); 383 + 384 + /* In case of JPEG we don't know the DT so we allow all data */ 385 + /* 386 + * TODO - check instead dt == 0 for the time being to allow other 387 + * unknown data-type 388 + */ 389 + if (!vpix->dt) 390 + reg_set(inp, DCMIPP_P0FSCR, 391 + DCMIPP_P0FSCR_DTMODE_ALLDT << DCMIPP_P0FSCR_DTMODE_SHIFT); 392 + else 393 + reg_set(inp, DCMIPP_P0FSCR, 394 + vpix->dt << DCMIPP_P0FSCR_DTIDA_SHIFT | 395 + DCMIPP_P0FSCR_DTMODE_DTIDA); 396 + 397 + /* Select the DCMIPP CSI interface */ 398 + reg_write(inp, DCMIPP_CMCR, DCMIPP_CMCR_INSEL); 399 + 400 + return 0; 401 + } 402 + 403 + static int dcmipp_inp_enable_streams(struct v4l2_subdev *sd, 404 + struct v4l2_subdev_state *state, 405 + u32 pad, u64 streams_mask) 406 + { 407 + struct dcmipp_inp_device *inp = 408 + container_of(sd, struct dcmipp_inp_device, sd); 409 + struct v4l2_subdev *s_subdev; 410 + struct media_pad *s_pad; 411 + int ret = 0; 412 + 413 + /* Get source subdev */ 414 + s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 415 + if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity)) 416 + return -EINVAL; 417 + s_subdev = media_entity_to_v4l2_subdev(s_pad->entity); 418 + 419 + if (inp->ved.bus_type == V4L2_MBUS_PARALLEL || 420 + inp->ved.bus_type == V4L2_MBUS_BT656) 421 + ret = dcmipp_inp_configure_parallel(inp, state); 422 + else if (inp->ved.bus_type == V4L2_MBUS_CSI2_DPHY) 423 + ret = dcmipp_inp_configure_csi(inp, state); 424 + if (ret) 425 + return ret; 426 + 427 + ret = v4l2_subdev_enable_streams(s_subdev, s_pad->index, BIT_ULL(0)); 428 + if (ret < 0) { 429 + dev_err(inp->dev, 430 + "failed to start source subdev streaming (%d)\n", ret); 431 + return ret; 432 + } 433 + 434 + return 0; 435 + } 436 + 437 + static int dcmipp_inp_disable_streams(struct v4l2_subdev *sd, 438 + struct v4l2_subdev_state *state, 439 + u32 pad, u64 streams_mask) 440 + { 441 + struct dcmipp_inp_device *inp = 442 + container_of(sd, struct dcmipp_inp_device, sd); 443 + struct v4l2_subdev *s_subdev; 444 + struct media_pad *s_pad; 445 + int ret; 446 + 447 + /* Get source subdev */ 448 + s_pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 449 + if (!s_pad || !is_media_entity_v4l2_subdev(s_pad->entity)) 450 + return -EINVAL; 451 + s_subdev = media_entity_to_v4l2_subdev(s_pad->entity); 452 + 453 + ret = v4l2_subdev_disable_streams(s_subdev, s_pad->index, BIT_ULL(0)); 454 + if (ret < 0) { 455 + dev_err(inp->dev, 456 + "failed to stop source subdev streaming (%d)\n", ret); 457 + return ret; 458 + } 459 + 460 + if (inp->ved.bus_type == V4L2_MBUS_PARALLEL || 461 + inp->ved.bus_type == V4L2_MBUS_BT656) { 462 + /* Disable parallel interface */ 463 + reg_clear(inp, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE); 464 + } 465 + 466 + return 0; 467 + } 468 + 469 + static const struct v4l2_subdev_pad_ops dcmipp_inp_pad_ops = { 470 + .enum_mbus_code = dcmipp_inp_enum_mbus_code, 471 + .enum_frame_size = dcmipp_inp_enum_frame_size, 472 + .get_fmt = v4l2_subdev_get_fmt, 473 + .set_fmt = dcmipp_inp_set_fmt, 474 + .enable_streams = dcmipp_inp_enable_streams, 475 + .disable_streams = dcmipp_inp_disable_streams, 476 + }; 477 + 478 + static const struct v4l2_subdev_video_ops dcmipp_inp_video_ops = { 479 + .s_stream = v4l2_subdev_s_stream_helper, 480 + }; 481 + 482 + static const struct v4l2_subdev_ops dcmipp_inp_ops = { 483 + .pad = &dcmipp_inp_pad_ops, 484 + .video = &dcmipp_inp_video_ops, 485 + }; 486 + 487 + static void dcmipp_inp_release(struct v4l2_subdev *sd) 488 + { 489 + struct dcmipp_inp_device *inp = 490 + container_of(sd, struct dcmipp_inp_device, sd); 491 + 492 + kfree(inp); 493 + } 494 + 495 + static const struct v4l2_subdev_internal_ops dcmipp_inp_int_ops = { 496 + .init_state = dcmipp_inp_init_state, 497 + .release = dcmipp_inp_release, 498 + }; 499 + 500 + void dcmipp_inp_ent_release(struct dcmipp_ent_device *ved) 501 + { 502 + struct dcmipp_inp_device *inp = 503 + container_of(ved, struct dcmipp_inp_device, ved); 504 + 505 + dcmipp_ent_sd_unregister(ved, &inp->sd); 506 + } 507 + 508 + struct dcmipp_ent_device *dcmipp_inp_ent_init(struct device *dev, 509 + const char *entity_name, 510 + struct v4l2_device *v4l2_dev, 511 + void __iomem *regs) 512 + { 513 + struct dcmipp_inp_device *inp; 514 + const unsigned long pads_flag[] = { 515 + MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE, 516 + }; 517 + int ret; 518 + 519 + /* Allocate the inp struct */ 520 + inp = kzalloc(sizeof(*inp), GFP_KERNEL); 521 + if (!inp) 522 + return ERR_PTR(-ENOMEM); 523 + 524 + inp->regs = regs; 525 + 526 + /* Initialize ved and sd */ 527 + ret = dcmipp_ent_sd_register(&inp->ved, &inp->sd, v4l2_dev, 528 + entity_name, MEDIA_ENT_F_VID_IF_BRIDGE, 529 + ARRAY_SIZE(pads_flag), pads_flag, 530 + &dcmipp_inp_int_ops, &dcmipp_inp_ops, 531 + NULL, NULL); 532 + if (ret) { 533 + kfree(inp); 534 + return ERR_PTR(ret); 535 + } 536 + 537 + inp->dev = dev; 538 + 539 + return &inp->ved; 540 + }
-440
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-parallel.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Driver for STM32 Digital Camera Memory Interface Pixel Processor 4 - * 5 - * Copyright (C) STMicroelectronics SA 2023 6 - * Authors: Hugues Fruchet <hugues.fruchet@foss.st.com> 7 - * Alain Volmat <alain.volmat@foss.st.com> 8 - * for STMicroelectronics. 9 - */ 10 - 11 - #include <linux/v4l2-mediabus.h> 12 - #include <media/v4l2-event.h> 13 - #include <media/v4l2-subdev.h> 14 - 15 - #include "dcmipp-common.h" 16 - 17 - #define DCMIPP_PRCR 0x104 18 - #define DCMIPP_PRCR_FORMAT_SHIFT 16 19 - #define DCMIPP_PRCR_FORMAT_YUV422 0x1e 20 - #define DCMIPP_PRCR_FORMAT_RGB565 0x22 21 - #define DCMIPP_PRCR_FORMAT_RAW8 0x2a 22 - #define DCMIPP_PRCR_FORMAT_G8 0x4a 23 - #define DCMIPP_PRCR_FORMAT_BYTE_STREAM 0x5a 24 - #define DCMIPP_PRCR_ESS BIT(4) 25 - #define DCMIPP_PRCR_PCKPOL BIT(5) 26 - #define DCMIPP_PRCR_HSPOL BIT(6) 27 - #define DCMIPP_PRCR_VSPOL BIT(7) 28 - #define DCMIPP_PRCR_ENABLE BIT(14) 29 - #define DCMIPP_PRCR_SWAPCYCLES BIT(25) 30 - 31 - #define DCMIPP_PRESCR 0x108 32 - #define DCMIPP_PRESUR 0x10c 33 - 34 - #define IS_SINK(pad) (!(pad)) 35 - #define IS_SRC(pad) ((pad)) 36 - 37 - struct dcmipp_par_pix_map { 38 - unsigned int code_sink; 39 - unsigned int code_src; 40 - u8 prcr_format; 41 - u8 prcr_swapcycles; 42 - }; 43 - 44 - #define PIXMAP_SINK_SRC_PRCR_SWAP(sink, src, prcr, swap) \ 45 - { \ 46 - .code_sink = MEDIA_BUS_FMT_##sink, \ 47 - .code_src = MEDIA_BUS_FMT_##src, \ 48 - .prcr_format = DCMIPP_PRCR_FORMAT_##prcr, \ 49 - .prcr_swapcycles = swap, \ 50 - } 51 - static const struct dcmipp_par_pix_map dcmipp_par_pix_map_list[] = { 52 - /* RGB565 */ 53 - PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_LE, RGB565_2X8_LE, RGB565, 1), 54 - PIXMAP_SINK_SRC_PRCR_SWAP(RGB565_2X8_BE, RGB565_2X8_LE, RGB565, 0), 55 - /* YUV422 */ 56 - PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 1), 57 - PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 0), 58 - PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 1), 59 - PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 0), 60 - PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 1), 61 - PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 1), 62 - /* GREY */ 63 - PIXMAP_SINK_SRC_PRCR_SWAP(Y8_1X8, Y8_1X8, G8, 0), 64 - /* Raw Bayer */ 65 - PIXMAP_SINK_SRC_PRCR_SWAP(SBGGR8_1X8, SBGGR8_1X8, RAW8, 0), 66 - PIXMAP_SINK_SRC_PRCR_SWAP(SGBRG8_1X8, SGBRG8_1X8, RAW8, 0), 67 - PIXMAP_SINK_SRC_PRCR_SWAP(SGRBG8_1X8, SGRBG8_1X8, RAW8, 0), 68 - PIXMAP_SINK_SRC_PRCR_SWAP(SRGGB8_1X8, SRGGB8_1X8, RAW8, 0), 69 - /* JPEG */ 70 - PIXMAP_SINK_SRC_PRCR_SWAP(JPEG_1X8, JPEG_1X8, BYTE_STREAM, 0), 71 - }; 72 - 73 - /* 74 - * Search through the pix_map table, skipping two consecutive entry with the 75 - * same code 76 - */ 77 - static inline const struct dcmipp_par_pix_map *dcmipp_par_pix_map_by_index 78 - (unsigned int index, 79 - unsigned int pad) 80 - { 81 - unsigned int i = 0; 82 - u32 prev_code = 0, cur_code; 83 - 84 - while (i < ARRAY_SIZE(dcmipp_par_pix_map_list)) { 85 - if (IS_SRC(pad)) 86 - cur_code = dcmipp_par_pix_map_list[i].code_src; 87 - else 88 - cur_code = dcmipp_par_pix_map_list[i].code_sink; 89 - 90 - if (cur_code == prev_code) { 91 - i++; 92 - continue; 93 - } 94 - prev_code = cur_code; 95 - 96 - if (index == 0) 97 - break; 98 - i++; 99 - index--; 100 - } 101 - 102 - if (i >= ARRAY_SIZE(dcmipp_par_pix_map_list)) 103 - return NULL; 104 - 105 - return &dcmipp_par_pix_map_list[i]; 106 - } 107 - 108 - static inline const struct dcmipp_par_pix_map *dcmipp_par_pix_map_by_code 109 - (u32 code_sink, u32 code_src) 110 - { 111 - unsigned int i; 112 - 113 - for (i = 0; i < ARRAY_SIZE(dcmipp_par_pix_map_list); i++) { 114 - if ((dcmipp_par_pix_map_list[i].code_sink == code_sink && 115 - dcmipp_par_pix_map_list[i].code_src == code_src) || 116 - (dcmipp_par_pix_map_list[i].code_sink == code_src && 117 - dcmipp_par_pix_map_list[i].code_src == code_sink) || 118 - (dcmipp_par_pix_map_list[i].code_sink == code_sink && 119 - code_src == 0) || 120 - (code_sink == 0 && 121 - dcmipp_par_pix_map_list[i].code_src == code_src)) 122 - return &dcmipp_par_pix_map_list[i]; 123 - } 124 - return NULL; 125 - } 126 - 127 - struct dcmipp_par_device { 128 - struct dcmipp_ent_device ved; 129 - struct v4l2_subdev sd; 130 - struct device *dev; 131 - void __iomem *regs; 132 - bool streaming; 133 - }; 134 - 135 - static const struct v4l2_mbus_framefmt fmt_default = { 136 - .width = DCMIPP_FMT_WIDTH_DEFAULT, 137 - .height = DCMIPP_FMT_HEIGHT_DEFAULT, 138 - .code = MEDIA_BUS_FMT_RGB565_2X8_LE, 139 - .field = V4L2_FIELD_NONE, 140 - .colorspace = DCMIPP_COLORSPACE_DEFAULT, 141 - .ycbcr_enc = DCMIPP_YCBCR_ENC_DEFAULT, 142 - .quantization = DCMIPP_QUANTIZATION_DEFAULT, 143 - .xfer_func = DCMIPP_XFER_FUNC_DEFAULT, 144 - }; 145 - 146 - static int dcmipp_par_init_state(struct v4l2_subdev *sd, 147 - struct v4l2_subdev_state *sd_state) 148 - { 149 - unsigned int i; 150 - 151 - for (i = 0; i < sd->entity.num_pads; i++) { 152 - struct v4l2_mbus_framefmt *mf; 153 - 154 - mf = v4l2_subdev_state_get_format(sd_state, i); 155 - *mf = fmt_default; 156 - } 157 - 158 - return 0; 159 - } 160 - 161 - static int dcmipp_par_enum_mbus_code(struct v4l2_subdev *sd, 162 - struct v4l2_subdev_state *sd_state, 163 - struct v4l2_subdev_mbus_code_enum *code) 164 - { 165 - const struct dcmipp_par_pix_map *vpix = 166 - dcmipp_par_pix_map_by_index(code->index, code->pad); 167 - 168 - if (!vpix) 169 - return -EINVAL; 170 - 171 - code->code = IS_SRC(code->pad) ? vpix->code_src : vpix->code_sink; 172 - 173 - return 0; 174 - } 175 - 176 - static int dcmipp_par_enum_frame_size(struct v4l2_subdev *sd, 177 - struct v4l2_subdev_state *sd_state, 178 - struct v4l2_subdev_frame_size_enum *fse) 179 - { 180 - const struct dcmipp_par_pix_map *vpix; 181 - 182 - if (fse->index) 183 - return -EINVAL; 184 - 185 - /* Only accept code in the pix map table */ 186 - vpix = dcmipp_par_pix_map_by_code(IS_SINK(fse->pad) ? fse->code : 0, 187 - IS_SRC(fse->pad) ? fse->code : 0); 188 - if (!vpix) 189 - return -EINVAL; 190 - 191 - fse->min_width = DCMIPP_FRAME_MIN_WIDTH; 192 - fse->max_width = DCMIPP_FRAME_MAX_WIDTH; 193 - fse->min_height = DCMIPP_FRAME_MIN_HEIGHT; 194 - fse->max_height = DCMIPP_FRAME_MAX_HEIGHT; 195 - 196 - return 0; 197 - } 198 - 199 - static void dcmipp_par_adjust_fmt(struct dcmipp_par_device *par, 200 - struct v4l2_mbus_framefmt *fmt, __u32 pad) 201 - { 202 - const struct dcmipp_par_pix_map *vpix; 203 - 204 - /* Only accept code in the pix map table */ 205 - vpix = dcmipp_par_pix_map_by_code(IS_SINK(pad) ? fmt->code : 0, 206 - IS_SRC(pad) ? fmt->code : 0); 207 - if (!vpix) 208 - fmt->code = fmt_default.code; 209 - 210 - /* Exclude JPEG if BT656 bus is selected */ 211 - if (vpix && vpix->code_sink == MEDIA_BUS_FMT_JPEG_1X8 && 212 - par->ved.bus_type == V4L2_MBUS_BT656) 213 - fmt->code = fmt_default.code; 214 - 215 - fmt->width = clamp_t(u32, fmt->width, DCMIPP_FRAME_MIN_WIDTH, 216 - DCMIPP_FRAME_MAX_WIDTH) & ~1; 217 - fmt->height = clamp_t(u32, fmt->height, DCMIPP_FRAME_MIN_HEIGHT, 218 - DCMIPP_FRAME_MAX_HEIGHT) & ~1; 219 - 220 - if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE) 221 - fmt->field = fmt_default.field; 222 - 223 - dcmipp_colorimetry_clamp(fmt); 224 - } 225 - 226 - static int dcmipp_par_set_fmt(struct v4l2_subdev *sd, 227 - struct v4l2_subdev_state *sd_state, 228 - struct v4l2_subdev_format *fmt) 229 - { 230 - struct dcmipp_par_device *par = v4l2_get_subdevdata(sd); 231 - struct v4l2_mbus_framefmt *mf; 232 - 233 - if (par->streaming) 234 - return -EBUSY; 235 - 236 - mf = v4l2_subdev_state_get_format(sd_state, fmt->pad); 237 - 238 - /* Set the new format */ 239 - dcmipp_par_adjust_fmt(par, &fmt->format, fmt->pad); 240 - 241 - dev_dbg(par->dev, "%s: format update: old:%dx%d (0x%x, %d, %d, %d, %d) new:%dx%d (0x%x, %d, %d, %d, %d)\n", 242 - par->sd.name, 243 - /* old */ 244 - mf->width, mf->height, mf->code, 245 - mf->colorspace, mf->quantization, 246 - mf->xfer_func, mf->ycbcr_enc, 247 - /* new */ 248 - fmt->format.width, fmt->format.height, fmt->format.code, 249 - fmt->format.colorspace, fmt->format.quantization, 250 - fmt->format.xfer_func, fmt->format.ycbcr_enc); 251 - 252 - *mf = fmt->format; 253 - 254 - /* When setting the sink format, report that format on the src pad */ 255 - if (IS_SINK(fmt->pad)) { 256 - mf = v4l2_subdev_state_get_format(sd_state, 1); 257 - *mf = fmt->format; 258 - dcmipp_par_adjust_fmt(par, mf, 1); 259 - } 260 - 261 - return 0; 262 - } 263 - 264 - static const struct v4l2_subdev_pad_ops dcmipp_par_pad_ops = { 265 - .enum_mbus_code = dcmipp_par_enum_mbus_code, 266 - .enum_frame_size = dcmipp_par_enum_frame_size, 267 - .get_fmt = v4l2_subdev_get_fmt, 268 - .set_fmt = dcmipp_par_set_fmt, 269 - }; 270 - 271 - static int dcmipp_par_configure(struct dcmipp_par_device *par) 272 - { 273 - u32 val = 0; 274 - const struct dcmipp_par_pix_map *vpix; 275 - struct v4l2_subdev_state *state; 276 - struct v4l2_mbus_framefmt *sink_fmt; 277 - struct v4l2_mbus_framefmt *src_fmt; 278 - 279 - /* Set vertical synchronization polarity */ 280 - if (par->ved.bus.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) 281 - val |= DCMIPP_PRCR_VSPOL; 282 - 283 - /* Set horizontal synchronization polarity */ 284 - if (par->ved.bus.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) 285 - val |= DCMIPP_PRCR_HSPOL; 286 - 287 - /* Set pixel clock polarity */ 288 - if (par->ved.bus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING) 289 - val |= DCMIPP_PRCR_PCKPOL; 290 - 291 - /* 292 - * BT656 embedded synchronisation bus mode. 293 - * 294 - * Default SAV/EAV mode is supported here with default codes 295 - * SAV=0xff000080 & EAV=0xff00009d. 296 - * With DCMIPP this means LSC=SAV=0x80 & LEC=EAV=0x9d. 297 - */ 298 - if (par->ved.bus_type == V4L2_MBUS_BT656) { 299 - val |= DCMIPP_PRCR_ESS; 300 - 301 - /* Unmask all codes */ 302 - reg_write(par, DCMIPP_PRESUR, 0xffffffff);/* FEC:LEC:LSC:FSC */ 303 - 304 - /* Trig on LSC=0x80 & LEC=0x9d codes, ignore FSC and FEC */ 305 - reg_write(par, DCMIPP_PRESCR, 0xff9d80ff);/* FEC:LEC:LSC:FSC */ 306 - } 307 - 308 - /* Set format */ 309 - state = v4l2_subdev_lock_and_get_active_state(&par->sd); 310 - sink_fmt = v4l2_subdev_state_get_format(state, 0); 311 - src_fmt = v4l2_subdev_state_get_format(state, 1); 312 - v4l2_subdev_unlock_state(state); 313 - 314 - vpix = dcmipp_par_pix_map_by_code(sink_fmt->code, src_fmt->code); 315 - if (!vpix) { 316 - dev_err(par->dev, "Invalid sink/src format configuration\n"); 317 - return -EINVAL; 318 - } 319 - 320 - val |= vpix->prcr_format << DCMIPP_PRCR_FORMAT_SHIFT; 321 - 322 - /* swap cycles */ 323 - if (vpix->prcr_swapcycles) 324 - val |= DCMIPP_PRCR_SWAPCYCLES; 325 - 326 - reg_write(par, DCMIPP_PRCR, val); 327 - 328 - return 0; 329 - } 330 - 331 - static int dcmipp_par_s_stream(struct v4l2_subdev *sd, int enable) 332 - { 333 - struct dcmipp_par_device *par = 334 - container_of(sd, struct dcmipp_par_device, sd); 335 - struct v4l2_subdev *s_subdev; 336 - struct media_pad *pad; 337 - int ret = 0; 338 - 339 - /* Get source subdev */ 340 - pad = media_pad_remote_pad_first(&sd->entity.pads[0]); 341 - if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) 342 - return -EINVAL; 343 - s_subdev = media_entity_to_v4l2_subdev(pad->entity); 344 - 345 - if (enable) { 346 - ret = dcmipp_par_configure(par); 347 - if (ret) 348 - return ret; 349 - 350 - /* Enable parallel interface */ 351 - reg_set(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE); 352 - 353 - ret = v4l2_subdev_call(s_subdev, video, s_stream, enable); 354 - if (ret < 0) { 355 - dev_err(par->dev, 356 - "failed to start source subdev streaming (%d)\n", 357 - ret); 358 - return ret; 359 - } 360 - } else { 361 - ret = v4l2_subdev_call(s_subdev, video, s_stream, enable); 362 - if (ret < 0) { 363 - dev_err(par->dev, 364 - "failed to stop source subdev streaming (%d)\n", 365 - ret); 366 - return ret; 367 - } 368 - 369 - /* Disable parallel interface */ 370 - reg_clear(par, DCMIPP_PRCR, DCMIPP_PRCR_ENABLE); 371 - } 372 - 373 - par->streaming = enable; 374 - 375 - return ret; 376 - } 377 - 378 - static const struct v4l2_subdev_video_ops dcmipp_par_video_ops = { 379 - .s_stream = dcmipp_par_s_stream, 380 - }; 381 - 382 - static const struct v4l2_subdev_ops dcmipp_par_ops = { 383 - .pad = &dcmipp_par_pad_ops, 384 - .video = &dcmipp_par_video_ops, 385 - }; 386 - 387 - static void dcmipp_par_release(struct v4l2_subdev *sd) 388 - { 389 - struct dcmipp_par_device *par = 390 - container_of(sd, struct dcmipp_par_device, sd); 391 - 392 - kfree(par); 393 - } 394 - 395 - static const struct v4l2_subdev_internal_ops dcmipp_par_int_ops = { 396 - .init_state = dcmipp_par_init_state, 397 - .release = dcmipp_par_release, 398 - }; 399 - 400 - void dcmipp_par_ent_release(struct dcmipp_ent_device *ved) 401 - { 402 - struct dcmipp_par_device *par = 403 - container_of(ved, struct dcmipp_par_device, ved); 404 - 405 - dcmipp_ent_sd_unregister(ved, &par->sd); 406 - } 407 - 408 - struct dcmipp_ent_device *dcmipp_par_ent_init(struct device *dev, 409 - const char *entity_name, 410 - struct v4l2_device *v4l2_dev, 411 - void __iomem *regs) 412 - { 413 - struct dcmipp_par_device *par; 414 - const unsigned long pads_flag[] = { 415 - MEDIA_PAD_FL_SINK, MEDIA_PAD_FL_SOURCE, 416 - }; 417 - int ret; 418 - 419 - /* Allocate the par struct */ 420 - par = kzalloc(sizeof(*par), GFP_KERNEL); 421 - if (!par) 422 - return ERR_PTR(-ENOMEM); 423 - 424 - par->regs = regs; 425 - 426 - /* Initialize ved and sd */ 427 - ret = dcmipp_ent_sd_register(&par->ved, &par->sd, v4l2_dev, 428 - entity_name, MEDIA_ENT_F_VID_IF_BRIDGE, 429 - ARRAY_SIZE(pads_flag), pads_flag, 430 - &dcmipp_par_int_ops, &dcmipp_par_ops, 431 - NULL, NULL); 432 - if (ret) { 433 - kfree(par); 434 - return ERR_PTR(ret); 435 - } 436 - 437 - par->dev = dev; 438 - 439 - return &par->ved; 440 - }
+9
drivers/media/platform/verisilicon/hantro.h
··· 227 227 * @src_fmt: V4L2 pixel format of active source format. 228 228 * @vpu_dst_fmt: Descriptor of active destination format. 229 229 * @dst_fmt: V4L2 pixel format of active destination format. 230 + * @ref_fmt: V4L2 pixel format of the reference frames format. 230 231 * 231 232 * @ctrl_handler: Control handler used to register controls. 232 233 * @jpeg_quality: User-specified JPEG compression quality. ··· 256 255 struct v4l2_pix_format_mplane src_fmt; 257 256 const struct hantro_fmt *vpu_dst_fmt; 258 257 struct v4l2_pix_format_mplane dst_fmt; 258 + struct v4l2_pix_format_mplane ref_fmt; 259 259 260 260 struct v4l2_ctrl_handler ctrl_handler; 261 261 int jpeg_quality; ··· 334 332 u32 bit_depth : 4; 335 333 }; 336 334 335 + struct hantro_av1_decoded_buffer_info { 336 + /* Info needed when the decoded frame serves as a reference frame. */ 337 + size_t chroma_offset; 338 + size_t mv_offset; 339 + }; 340 + 337 341 struct hantro_decoded_buffer { 338 342 /* Must be the first field in this struct. */ 339 343 struct v4l2_m2m_buffer base; 340 344 341 345 union { 342 346 struct hantro_vp9_decoded_buffer_info vp9; 347 + struct hantro_av1_decoded_buffer_info av1; 343 348 }; 344 349 }; 345 350
+1 -1
drivers/media/platform/verisilicon/hantro_g2.c
··· 47 47 48 48 size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx) 49 49 { 50 - return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; 50 + return ctx->ref_fmt.plane_fmt[0].bytesperline * ctx->ref_fmt.height; 51 51 } 52 52 53 53 size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx)
+11 -21
drivers/media/platform/verisilicon/hantro_postproc.c
··· 194 194 195 195 static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx) 196 196 { 197 - struct v4l2_pix_format_mplane pix_mp; 198 - const struct hantro_fmt *fmt; 199 197 unsigned int buf_size; 200 198 201 - /* this should always pick native format */ 202 - fmt = hantro_get_default_fmt(ctx, false, ctx->bit_depth, HANTRO_AUTO_POSTPROC); 203 - if (!fmt) 204 - return 0; 205 - 206 - v4l2_fill_pixfmt_mp(&pix_mp, fmt->fourcc, ctx->src_fmt.width, 207 - ctx->src_fmt.height); 208 - 209 - buf_size = pix_mp.plane_fmt[0].sizeimage; 199 + buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage; 210 200 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE) 211 - buf_size += hantro_h264_mv_size(pix_mp.width, 212 - pix_mp.height); 201 + buf_size += hantro_h264_mv_size(ctx->ref_fmt.width, 202 + ctx->ref_fmt.height); 213 203 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME) 214 - buf_size += hantro_vp9_mv_size(pix_mp.width, 215 - pix_mp.height); 204 + buf_size += hantro_vp9_mv_size(ctx->ref_fmt.width, 205 + ctx->ref_fmt.height); 216 206 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) { 217 - buf_size += hantro_hevc_mv_size(pix_mp.width, 218 - pix_mp.height); 207 + buf_size += hantro_hevc_mv_size(ctx->ref_fmt.width, 208 + ctx->ref_fmt.height); 219 209 if (ctx->hevc_dec.use_compression) 220 - buf_size += hantro_hevc_compressed_size(pix_mp.width, 221 - pix_mp.height); 210 + buf_size += hantro_hevc_compressed_size(ctx->ref_fmt.width, 211 + ctx->ref_fmt.height); 222 212 } 223 213 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME) 224 - buf_size += hantro_av1_mv_size(pix_mp.width, 225 - pix_mp.height); 214 + buf_size += hantro_av1_mv_size(ctx->ref_fmt.width, 215 + ctx->ref_fmt.height); 226 216 227 217 return buf_size; 228 218 }
+21
drivers/media/platform/verisilicon/hantro_v4l2.c
··· 126 126 return NULL; 127 127 } 128 128 129 + static int 130 + hantro_set_reference_frames_format(struct hantro_ctx *ctx) 131 + { 132 + const struct hantro_fmt *fmt; 133 + int dst_bit_depth = hantro_get_format_depth(ctx->vpu_dst_fmt->fourcc); 134 + 135 + fmt = hantro_get_default_fmt(ctx, false, dst_bit_depth, HANTRO_AUTO_POSTPROC); 136 + if (!fmt) 137 + return -EINVAL; 138 + 139 + ctx->ref_fmt.width = ctx->src_fmt.width; 140 + ctx->ref_fmt.height = ctx->src_fmt.height; 141 + 142 + v4l2_apply_frmsize_constraints(&ctx->ref_fmt.width, &ctx->ref_fmt.height, &fmt->frmsize); 143 + return v4l2_fill_pixfmt_mp(&ctx->ref_fmt, fmt->fourcc, 144 + ctx->ref_fmt.width, ctx->ref_fmt.height); 145 + } 146 + 129 147 const struct hantro_fmt * 130 148 hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream, 131 149 int bit_depth, bool need_postproc) ··· 613 595 614 596 ctx->vpu_dst_fmt = hantro_find_format(ctx, pix_mp->pixelformat); 615 597 ctx->dst_fmt = *pix_mp; 598 + ret = hantro_set_reference_frames_format(ctx); 599 + if (ret) 600 + return ret; 616 601 617 602 /* 618 603 * Current raw format might have become invalid with newly
+5 -5
drivers/media/platform/verisilicon/imx8m_vpu_hw.c
··· 187 187 .frmsize = { 188 188 .min_width = FMT_MIN_WIDTH, 189 189 .max_width = FMT_UHD_WIDTH, 190 - .step_width = TILE_MB_DIM, 190 + .step_width = 8, 191 191 .min_height = FMT_MIN_HEIGHT, 192 192 .max_height = FMT_UHD_HEIGHT, 193 - .step_height = TILE_MB_DIM, 193 + .step_height = 32, 194 194 }, 195 195 }, 196 196 { 197 - .fourcc = V4L2_PIX_FMT_P010_4L4, 197 + .fourcc = V4L2_PIX_FMT_NV15_4L4, 198 198 .codec_mode = HANTRO_MODE_NONE, 199 199 .match_depth = true, 200 200 .frmsize = { 201 201 .min_width = FMT_MIN_WIDTH, 202 202 .max_width = FMT_UHD_WIDTH, 203 - .step_width = TILE_MB_DIM, 203 + .step_width = 8, 204 204 .min_height = FMT_MIN_HEIGHT, 205 205 .max_height = FMT_UHD_HEIGHT, 206 - .step_height = TILE_MB_DIM, 206 + .step_height = 32, 207 207 }, 208 208 }, 209 209 {
+5 -4
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
··· 686 686 struct hantro_dev *vpu = ctx->dev; 687 687 struct hantro_decoded_buffer *dst; 688 688 dma_addr_t luma_addr, chroma_addr, mv_addr = 0; 689 - size_t cr_offset = rockchip_vpu981_av1_dec_luma_size(ctx); 690 - size_t mv_offset = rockchip_vpu981_av1_dec_chroma_size(ctx); 691 689 int cur_width = frame->frame_width_minus_1 + 1; 692 690 int cur_height = frame->frame_height_minus_1 + 1; 693 691 int scale_width = ··· 742 744 743 745 dst = vb2_to_hantro_decoded_buf(&av1_dec->frame_refs[idx].vb2_ref->vb2_buf); 744 746 luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf); 745 - chroma_addr = luma_addr + cr_offset; 746 - mv_addr = luma_addr + mv_offset; 747 + chroma_addr = luma_addr + dst->av1.chroma_offset; 748 + mv_addr = luma_addr + dst->av1.mv_offset; 747 749 748 750 hantro_write_addr(vpu, AV1_REFERENCE_Y(ref), luma_addr); 749 751 hantro_write_addr(vpu, AV1_REFERENCE_CB(ref), chroma_addr); ··· 2086 2088 luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf); 2087 2089 chroma_addr = luma_addr + cr_offset; 2088 2090 mv_addr = luma_addr + mv_offset; 2091 + 2092 + dst->av1.chroma_offset = cr_offset; 2093 + dst->av1.mv_offset = mv_offset; 2089 2094 2090 2095 hantro_write_addr(vpu, AV1_TILE_OUT_LU, luma_addr); 2091 2096 hantro_write_addr(vpu, AV1_TILE_OUT_CH, chroma_addr);
-4
drivers/media/radio/Kconfig
··· 221 221 source "drivers/media/radio/si470x/Kconfig" 222 222 source "drivers/media/radio/si4713/Kconfig" 223 223 224 - # TI's ST based wl128x FM radio 225 - 226 - source "drivers/media/radio/wl128x/Kconfig" 227 - 228 224 # 229 225 # ISA drivers configuration 230 226 #
-1
drivers/media/radio/Makefile
··· 31 31 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o 32 32 obj-$(CONFIG_RADIO_TYPHOON) += radio-typhoon.o 33 33 obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o 34 - obj-$(CONFIG_RADIO_WL128X) += wl128x/ 35 34 obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o 36 35 37 36 obj-$(CONFIG_USB_DSBR) += dsbr100.o
-15
drivers/media/radio/wl128x/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # TI's wl128x FM driver based on TI's ST driver. 4 - # 5 - config RADIO_WL128X 6 - tristate "Texas Instruments WL128x FM Radio" 7 - depends on VIDEO_DEV && RFKILL && TTY && TI_ST 8 - depends on GPIOLIB || COMPILE_TEST 9 - help 10 - Choose Y here if you have this FM radio chip. 11 - 12 - In order to control your radio card, you will need to use programs 13 - that are compatible with the Video For Linux 2 API. Information on 14 - this API and pointers to "v4l2" programs may be found at 15 - <file:Documentation/userspace-api/media/index.rst>.
-7
drivers/media/radio/wl128x/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # Makefile for TI's shared transport driver based wl128x 4 - # FM radio. 5 - # 6 - obj-$(CONFIG_RADIO_WL128X) += fm_drv.o 7 - fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_tx.o fmdrv_v4l2.o
-229
drivers/media/radio/wl128x/fmdrv.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * 5 - * Common header for all FM driver sub-modules. 6 - * 7 - * Copyright (C) 2011 Texas Instruments 8 - */ 9 - 10 - #ifndef _FM_DRV_H 11 - #define _FM_DRV_H 12 - 13 - #include <linux/skbuff.h> 14 - #include <linux/interrupt.h> 15 - #include <sound/core.h> 16 - #include <sound/initval.h> 17 - #include <linux/timer.h> 18 - #include <linux/workqueue.h> 19 - #include <media/v4l2-ioctl.h> 20 - #include <media/v4l2-common.h> 21 - #include <media/v4l2-device.h> 22 - #include <media/v4l2-ctrls.h> 23 - 24 - #define FM_DRV_VERSION "0.1.1" 25 - #define FM_DRV_NAME "ti_fmdrv" 26 - #define FM_DRV_CARD_SHORT_NAME "TI FM Radio" 27 - #define FM_DRV_CARD_LONG_NAME "Texas Instruments FM Radio" 28 - 29 - /* Flag info */ 30 - #define FM_INTTASK_RUNNING 0 31 - #define FM_INTTASK_SCHEDULE_PENDING 1 32 - #define FM_FW_DW_INPROGRESS 2 33 - #define FM_CORE_READY 3 34 - #define FM_CORE_TRANSPORT_READY 4 35 - #define FM_AF_SWITCH_INPROGRESS 5 36 - #define FM_CORE_TX_XMITING 6 37 - 38 - #define FM_TUNE_COMPLETE 0x1 39 - #define FM_BAND_LIMIT 0x2 40 - 41 - #define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */ 42 - #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */ 43 - 44 - #define fmerr(format, ...) \ 45 - printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__) 46 - #define fmwarn(format, ...) \ 47 - printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__) 48 - #ifdef DEBUG 49 - #define fmdbg(format, ...) \ 50 - printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__) 51 - #else /* DEBUG */ 52 - #define fmdbg(format, ...) do {} while(0) 53 - #endif 54 - enum { 55 - FM_MODE_OFF, 56 - FM_MODE_TX, 57 - FM_MODE_RX, 58 - FM_MODE_ENTRY_MAX 59 - }; 60 - 61 - #define FM_RX_RDS_INFO_FIELD_MAX 8 /* 4 Group * 2 Bytes */ 62 - 63 - /* RX RDS data format */ 64 - struct fm_rdsdata_format { 65 - union { 66 - struct { 67 - u8 buff[FM_RX_RDS_INFO_FIELD_MAX]; 68 - } groupdatabuff; 69 - struct { 70 - u16 pidata; 71 - u8 blk_b[2]; 72 - u8 blk_c[2]; 73 - u8 blk_d[2]; 74 - } groupgeneral; 75 - struct { 76 - u16 pidata; 77 - u8 blk_b[2]; 78 - u8 af[2]; 79 - u8 ps[2]; 80 - } group0A; 81 - struct { 82 - u16 pi[2]; 83 - u8 blk_b[2]; 84 - u8 ps[2]; 85 - } group0B; 86 - } data; 87 - }; 88 - 89 - /* FM region (Europe/US, Japan) info */ 90 - struct region_info { 91 - u32 chanl_space; 92 - u32 bot_freq; 93 - u32 top_freq; 94 - u8 fm_band; 95 - }; 96 - struct fmdev; 97 - typedef void (*int_handler_prototype) (struct fmdev *); 98 - 99 - /* FM Interrupt processing related info */ 100 - struct fm_irq { 101 - u8 stage; 102 - u16 flag; /* FM interrupt flag */ 103 - u16 mask; /* FM interrupt mask */ 104 - /* Interrupt process timeout handler */ 105 - struct timer_list timer; 106 - u8 retry; 107 - int_handler_prototype *handlers; 108 - }; 109 - 110 - /* RDS info */ 111 - struct fm_rds { 112 - u8 flag; /* RX RDS on/off status */ 113 - u8 last_blk_idx; /* Last received RDS block */ 114 - 115 - /* RDS buffer */ 116 - wait_queue_head_t read_queue; 117 - u32 buf_size; /* Size is always multiple of 3 */ 118 - u32 wr_idx; 119 - u32 rd_idx; 120 - u8 *buff; 121 - }; 122 - 123 - #define FM_RDS_MAX_AF_LIST 25 124 - 125 - /* 126 - * Current RX channel Alternate Frequency cache. 127 - * This info is used to switch to other freq (AF) 128 - * when current channel signal strength is below RSSI threshold. 129 - */ 130 - struct tuned_station_info { 131 - u16 picode; 132 - u32 af_cache[FM_RDS_MAX_AF_LIST]; 133 - u8 afcache_size; 134 - u8 af_list_max; 135 - }; 136 - 137 - /* FM RX mode info */ 138 - struct fm_rx { 139 - struct region_info region; /* Current selected band */ 140 - u32 freq; /* Current RX frquency */ 141 - u8 mute_mode; /* Current mute mode */ 142 - u8 deemphasis_mode; /* Current deemphasis mode */ 143 - /* RF dependent soft mute mode */ 144 - u8 rf_depend_mute; 145 - u16 volume; /* Current volume level */ 146 - u16 rssi_threshold; /* Current RSSI threshold level */ 147 - /* Holds the index of the current AF jump */ 148 - u8 afjump_idx; 149 - /* Will hold the frequency before the jump */ 150 - u32 freq_before_jump; 151 - u8 rds_mode; /* RDS operation mode (RDS/RDBS) */ 152 - u8 af_mode; /* Alternate frequency on/off */ 153 - struct tuned_station_info stat_info; 154 - struct fm_rds rds; 155 - }; 156 - 157 - #define FMTX_RDS_TXT_STR_SIZE 25 158 - /* 159 - * FM TX RDS data 160 - * 161 - * @ text_type: is the text following PS or RT 162 - * @ text: radio text string which could either be PS or RT 163 - * @ af_freq: alternate frequency for Tx 164 - * TODO: to be declared in application 165 - */ 166 - struct tx_rds { 167 - u8 text_type; 168 - u8 text[FMTX_RDS_TXT_STR_SIZE]; 169 - u8 flag; 170 - u32 af_freq; 171 - }; 172 - /* 173 - * FM TX global data 174 - * 175 - * @ pwr_lvl: Power Level of the Transmission from mixer control 176 - * @ xmit_state: Transmission state = Updated locally upon Start/Stop 177 - * @ audio_io: i2S/Analog 178 - * @ tx_frq: Transmission frequency 179 - */ 180 - struct fmtx_data { 181 - u8 pwr_lvl; 182 - u8 xmit_state; 183 - u8 audio_io; 184 - u8 region; 185 - u16 aud_mode; 186 - u32 preemph; 187 - u32 tx_frq; 188 - struct tx_rds rds; 189 - }; 190 - 191 - /* FM driver operation structure */ 192 - struct fmdev { 193 - struct video_device *radio_dev; /* V4L2 video device pointer */ 194 - struct v4l2_device v4l2_dev; /* V4L2 top level struct */ 195 - struct snd_card *card; /* Card which holds FM mixer controls */ 196 - u16 asci_id; 197 - spinlock_t rds_buff_lock; /* To protect access to RDS buffer */ 198 - spinlock_t resp_skb_lock; /* To protect access to received SKB */ 199 - 200 - long flag; /* FM driver state machine info */ 201 - int streg_cbdata; /* status of ST registration */ 202 - 203 - struct sk_buff_head rx_q; /* RX queue */ 204 - struct work_struct rx_bh_work; /* RX BH Work */ 205 - 206 - struct sk_buff_head tx_q; /* TX queue */ 207 - struct work_struct tx_bh_work; /* TX BH Work */ 208 - unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */ 209 - atomic_t tx_cnt; /* Number of packets can send at a time */ 210 - 211 - struct sk_buff *resp_skb; /* Response from the chip */ 212 - /* Main task completion handler */ 213 - struct completion maintask_comp; 214 - /* Opcode of last command sent to the chip */ 215 - u8 pre_op; 216 - /* Handler used for wakeup when response packet is received */ 217 - struct completion *resp_comp; 218 - struct fm_irq irq_info; 219 - u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */ 220 - struct fm_rx rx; /* FM receiver info */ 221 - struct fmtx_data tx_data; 222 - 223 - /* V4L2 ctrl framework handler*/ 224 - struct v4l2_ctrl_handler ctrl_handler; 225 - 226 - /* For core assisted locking */ 227 - struct mutex mutex; 228 - }; 229 - #endif
-1676
drivers/media/radio/wl128x/fmdrv_common.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * 5 - * This sub-module of FM driver is common for FM RX and TX 6 - * functionality. This module is responsible for: 7 - * 1) Forming group of Channel-8 commands to perform particular 8 - * functionality (eg., frequency set require more than 9 - * one Channel-8 command to be sent to the chip). 10 - * 2) Sending each Channel-8 command to the chip and reading 11 - * response back over Shared Transport. 12 - * 3) Managing TX and RX Queues and BH bh Works. 13 - * 4) Handling FM Interrupt packet and taking appropriate action. 14 - * 5) Loading FM firmware to the chip (common, FM TX, and FM RX 15 - * firmware files based on mode selection) 16 - * 17 - * Copyright (C) 2011 Texas Instruments 18 - * Author: Raja Mani <raja_mani@ti.com> 19 - * Author: Manjunatha Halli <manjunatha_halli@ti.com> 20 - */ 21 - 22 - #include <linux/delay.h> 23 - #include <linux/firmware.h> 24 - #include <linux/module.h> 25 - #include <linux/nospec.h> 26 - #include <linux/jiffies.h> 27 - 28 - #include "fmdrv.h" 29 - #include "fmdrv_v4l2.h" 30 - #include "fmdrv_common.h" 31 - #include <linux/ti_wilink_st.h> 32 - #include "fmdrv_rx.h" 33 - #include "fmdrv_tx.h" 34 - 35 - /* Region info */ 36 - static struct region_info region_configs[] = { 37 - /* Europe/US */ 38 - { 39 - .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL, 40 - .bot_freq = 87500, /* 87.5 MHz */ 41 - .top_freq = 108000, /* 108 MHz */ 42 - .fm_band = 0, 43 - }, 44 - /* Japan */ 45 - { 46 - .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL, 47 - .bot_freq = 76000, /* 76 MHz */ 48 - .top_freq = 90000, /* 90 MHz */ 49 - .fm_band = 1, 50 - }, 51 - }; 52 - 53 - /* Band selection */ 54 - static u8 default_radio_region; /* Europe/US */ 55 - module_param(default_radio_region, byte, 0); 56 - MODULE_PARM_DESC(default_radio_region, "Region: 0=Europe/US, 1=Japan"); 57 - 58 - /* RDS buffer blocks */ 59 - static u32 default_rds_buf = 300; 60 - module_param(default_rds_buf, uint, 0444); 61 - MODULE_PARM_DESC(default_rds_buf, "RDS buffer entries"); 62 - 63 - /* Radio Nr */ 64 - static u32 radio_nr = -1; 65 - module_param(radio_nr, int, 0444); 66 - MODULE_PARM_DESC(radio_nr, "Radio Nr"); 67 - 68 - /* FM irq handlers forward declaration */ 69 - static void fm_irq_send_flag_getcmd(struct fmdev *); 70 - static void fm_irq_handle_flag_getcmd_resp(struct fmdev *); 71 - static void fm_irq_handle_hw_malfunction(struct fmdev *); 72 - static void fm_irq_handle_rds_start(struct fmdev *); 73 - static void fm_irq_send_rdsdata_getcmd(struct fmdev *); 74 - static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *); 75 - static void fm_irq_handle_rds_finish(struct fmdev *); 76 - static void fm_irq_handle_tune_op_ended(struct fmdev *); 77 - static void fm_irq_handle_power_enb(struct fmdev *); 78 - static void fm_irq_handle_low_rssi_start(struct fmdev *); 79 - static void fm_irq_afjump_set_pi(struct fmdev *); 80 - static void fm_irq_handle_set_pi_resp(struct fmdev *); 81 - static void fm_irq_afjump_set_pimask(struct fmdev *); 82 - static void fm_irq_handle_set_pimask_resp(struct fmdev *); 83 - static void fm_irq_afjump_setfreq(struct fmdev *); 84 - static void fm_irq_handle_setfreq_resp(struct fmdev *); 85 - static void fm_irq_afjump_enableint(struct fmdev *); 86 - static void fm_irq_afjump_enableint_resp(struct fmdev *); 87 - static void fm_irq_start_afjump(struct fmdev *); 88 - static void fm_irq_handle_start_afjump_resp(struct fmdev *); 89 - static void fm_irq_afjump_rd_freq(struct fmdev *); 90 - static void fm_irq_afjump_rd_freq_resp(struct fmdev *); 91 - static void fm_irq_handle_low_rssi_finish(struct fmdev *); 92 - static void fm_irq_send_intmsk_cmd(struct fmdev *); 93 - static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *); 94 - 95 - /* 96 - * When FM common module receives interrupt packet, following handlers 97 - * will be executed one after another to service the interrupt(s) 98 - */ 99 - enum fmc_irq_handler_index { 100 - FM_SEND_FLAG_GETCMD_IDX, 101 - FM_HANDLE_FLAG_GETCMD_RESP_IDX, 102 - 103 - /* HW malfunction irq handler */ 104 - FM_HW_MAL_FUNC_IDX, 105 - 106 - /* RDS threshold reached irq handler */ 107 - FM_RDS_START_IDX, 108 - FM_RDS_SEND_RDS_GETCMD_IDX, 109 - FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX, 110 - FM_RDS_FINISH_IDX, 111 - 112 - /* Tune operation ended irq handler */ 113 - FM_HW_TUNE_OP_ENDED_IDX, 114 - 115 - /* TX power enable irq handler */ 116 - FM_HW_POWER_ENB_IDX, 117 - 118 - /* Low RSSI irq handler */ 119 - FM_LOW_RSSI_START_IDX, 120 - FM_AF_JUMP_SETPI_IDX, 121 - FM_AF_JUMP_HANDLE_SETPI_RESP_IDX, 122 - FM_AF_JUMP_SETPI_MASK_IDX, 123 - FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX, 124 - FM_AF_JUMP_SET_AF_FREQ_IDX, 125 - FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX, 126 - FM_AF_JUMP_ENABLE_INT_IDX, 127 - FM_AF_JUMP_ENABLE_INT_RESP_IDX, 128 - FM_AF_JUMP_START_AFJUMP_IDX, 129 - FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX, 130 - FM_AF_JUMP_RD_FREQ_IDX, 131 - FM_AF_JUMP_RD_FREQ_RESP_IDX, 132 - FM_LOW_RSSI_FINISH_IDX, 133 - 134 - /* Interrupt process post action */ 135 - FM_SEND_INTMSK_CMD_IDX, 136 - FM_HANDLE_INTMSK_CMD_RESP_IDX, 137 - }; 138 - 139 - /* FM interrupt handler table */ 140 - static int_handler_prototype int_handler_table[] = { 141 - fm_irq_send_flag_getcmd, 142 - fm_irq_handle_flag_getcmd_resp, 143 - fm_irq_handle_hw_malfunction, 144 - fm_irq_handle_rds_start, /* RDS threshold reached irq handler */ 145 - fm_irq_send_rdsdata_getcmd, 146 - fm_irq_handle_rdsdata_getcmd_resp, 147 - fm_irq_handle_rds_finish, 148 - fm_irq_handle_tune_op_ended, 149 - fm_irq_handle_power_enb, /* TX power enable irq handler */ 150 - fm_irq_handle_low_rssi_start, 151 - fm_irq_afjump_set_pi, 152 - fm_irq_handle_set_pi_resp, 153 - fm_irq_afjump_set_pimask, 154 - fm_irq_handle_set_pimask_resp, 155 - fm_irq_afjump_setfreq, 156 - fm_irq_handle_setfreq_resp, 157 - fm_irq_afjump_enableint, 158 - fm_irq_afjump_enableint_resp, 159 - fm_irq_start_afjump, 160 - fm_irq_handle_start_afjump_resp, 161 - fm_irq_afjump_rd_freq, 162 - fm_irq_afjump_rd_freq_resp, 163 - fm_irq_handle_low_rssi_finish, 164 - fm_irq_send_intmsk_cmd, /* Interrupt process post action */ 165 - fm_irq_handle_intmsk_cmd_resp 166 - }; 167 - 168 - static long (*g_st_write) (struct sk_buff *skb); 169 - static struct completion wait_for_fmdrv_reg_comp; 170 - 171 - static inline void fm_irq_call(struct fmdev *fmdev) 172 - { 173 - fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev); 174 - } 175 - 176 - /* Continue next function in interrupt handler table */ 177 - static inline void fm_irq_call_stage(struct fmdev *fmdev, u8 stage) 178 - { 179 - fmdev->irq_info.stage = stage; 180 - fm_irq_call(fmdev); 181 - } 182 - 183 - static inline void fm_irq_timeout_stage(struct fmdev *fmdev, u8 stage) 184 - { 185 - fmdev->irq_info.stage = stage; 186 - mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT); 187 - } 188 - 189 - #ifdef FM_DUMP_TXRX_PKT 190 - /* To dump outgoing FM Channel-8 packets */ 191 - inline void dump_tx_skb_data(struct sk_buff *skb) 192 - { 193 - int len, len_org; 194 - u8 index; 195 - struct fm_cmd_msg_hdr *cmd_hdr; 196 - 197 - cmd_hdr = (struct fm_cmd_msg_hdr *)skb->data; 198 - printk(KERN_INFO "<<%shdr:%02x len:%02x opcode:%02x type:%s dlen:%02x", 199 - fm_cb(skb)->completion ? " " : "*", cmd_hdr->hdr, 200 - cmd_hdr->len, cmd_hdr->op, 201 - cmd_hdr->rd_wr ? "RD" : "WR", cmd_hdr->dlen); 202 - 203 - len_org = skb->len - FM_CMD_MSG_HDR_SIZE; 204 - if (len_org > 0) { 205 - printk(KERN_CONT "\n data(%d): ", cmd_hdr->dlen); 206 - len = min(len_org, 14); 207 - for (index = 0; index < len; index++) 208 - printk(KERN_CONT "%x ", 209 - skb->data[FM_CMD_MSG_HDR_SIZE + index]); 210 - printk(KERN_CONT "%s", (len_org > 14) ? ".." : ""); 211 - } 212 - printk(KERN_CONT "\n"); 213 - } 214 - 215 - /* To dump incoming FM Channel-8 packets */ 216 - inline void dump_rx_skb_data(struct sk_buff *skb) 217 - { 218 - int len, len_org; 219 - u8 index; 220 - struct fm_event_msg_hdr *evt_hdr; 221 - 222 - evt_hdr = (struct fm_event_msg_hdr *)skb->data; 223 - printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x opcode:%02x type:%s dlen:%02x", 224 - evt_hdr->hdr, evt_hdr->len, 225 - evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op, 226 - (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen); 227 - 228 - len_org = skb->len - FM_EVT_MSG_HDR_SIZE; 229 - if (len_org > 0) { 230 - printk(KERN_CONT "\n data(%d): ", evt_hdr->dlen); 231 - len = min(len_org, 14); 232 - for (index = 0; index < len; index++) 233 - printk(KERN_CONT "%x ", 234 - skb->data[FM_EVT_MSG_HDR_SIZE + index]); 235 - printk(KERN_CONT "%s", (len_org > 14) ? ".." : ""); 236 - } 237 - printk(KERN_CONT "\n"); 238 - } 239 - #endif 240 - 241 - void fmc_update_region_info(struct fmdev *fmdev, u8 region_to_set) 242 - { 243 - fmdev->rx.region = region_configs[region_to_set]; 244 - } 245 - 246 - /* 247 - * FM common sub-module will queue this bh work whenever it receives 248 - * FM packet from ST driver. 249 - */ 250 - static void recv_bh_work(struct work_struct *t) 251 - { 252 - struct fmdev *fmdev; 253 - struct fm_irq *irq_info; 254 - struct fm_event_msg_hdr *evt_hdr; 255 - struct sk_buff *skb; 256 - u8 num_fm_hci_cmds; 257 - unsigned long flags; 258 - 259 - fmdev = from_work(fmdev, t, tx_bh_work); 260 - irq_info = &fmdev->irq_info; 261 - /* Process all packets in the RX queue */ 262 - while ((skb = skb_dequeue(&fmdev->rx_q))) { 263 - if (skb->len < sizeof(struct fm_event_msg_hdr)) { 264 - fmerr("skb(%p) has only %d bytes, at least need %zu bytes to decode\n", 265 - skb, 266 - skb->len, sizeof(struct fm_event_msg_hdr)); 267 - kfree_skb(skb); 268 - continue; 269 - } 270 - 271 - evt_hdr = (void *)skb->data; 272 - num_fm_hci_cmds = evt_hdr->num_fm_hci_cmds; 273 - 274 - /* FM interrupt packet? */ 275 - if (evt_hdr->op == FM_INTERRUPT) { 276 - /* FM interrupt handler started already? */ 277 - if (!test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) { 278 - set_bit(FM_INTTASK_RUNNING, &fmdev->flag); 279 - if (irq_info->stage != 0) { 280 - fmerr("Inval stage resetting to zero\n"); 281 - irq_info->stage = 0; 282 - } 283 - 284 - /* 285 - * Execute first function in interrupt handler 286 - * table. 287 - */ 288 - irq_info->handlers[irq_info->stage](fmdev); 289 - } else { 290 - set_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag); 291 - } 292 - kfree_skb(skb); 293 - } 294 - /* Anyone waiting for this with completion handler? */ 295 - else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp != NULL) { 296 - 297 - spin_lock_irqsave(&fmdev->resp_skb_lock, flags); 298 - fmdev->resp_skb = skb; 299 - spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); 300 - complete(fmdev->resp_comp); 301 - 302 - fmdev->resp_comp = NULL; 303 - atomic_set(&fmdev->tx_cnt, 1); 304 - } 305 - /* Is this for interrupt handler? */ 306 - else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp == NULL) { 307 - if (fmdev->resp_skb != NULL) 308 - fmerr("Response SKB ptr not NULL\n"); 309 - 310 - spin_lock_irqsave(&fmdev->resp_skb_lock, flags); 311 - fmdev->resp_skb = skb; 312 - spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); 313 - 314 - /* Execute interrupt handler where state index points */ 315 - irq_info->handlers[irq_info->stage](fmdev); 316 - 317 - kfree_skb(skb); 318 - atomic_set(&fmdev->tx_cnt, 1); 319 - } else { 320 - fmerr("Nobody claimed SKB(%p),purging\n", skb); 321 - } 322 - 323 - /* 324 - * Check flow control field. If Num_FM_HCI_Commands field is 325 - * not zero, queue FM TX bh work. 326 - */ 327 - if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt)) 328 - if (!skb_queue_empty(&fmdev->tx_q)) 329 - queue_work(system_bh_wq, &fmdev->tx_bh_work); 330 - } 331 - } 332 - 333 - /* FM send_bh_work: is scheduled when FM packet has to be sent to chip */ 334 - static void send_bh_work(struct work_struct *t) 335 - { 336 - struct fmdev *fmdev; 337 - struct sk_buff *skb; 338 - int len; 339 - 340 - fmdev = from_work(fmdev, t, tx_bh_work); 341 - 342 - if (!atomic_read(&fmdev->tx_cnt)) 343 - return; 344 - 345 - /* Check, is there any timeout happened to last transmitted packet */ 346 - if (time_is_before_jiffies(fmdev->last_tx_jiffies + FM_DRV_TX_TIMEOUT)) { 347 - fmerr("TX timeout occurred\n"); 348 - atomic_set(&fmdev->tx_cnt, 1); 349 - } 350 - 351 - /* Send queued FM TX packets */ 352 - skb = skb_dequeue(&fmdev->tx_q); 353 - if (!skb) 354 - return; 355 - 356 - atomic_dec(&fmdev->tx_cnt); 357 - fmdev->pre_op = fm_cb(skb)->fm_op; 358 - 359 - if (fmdev->resp_comp != NULL) 360 - fmerr("Response completion handler is not NULL\n"); 361 - 362 - fmdev->resp_comp = fm_cb(skb)->completion; 363 - 364 - /* Write FM packet to ST driver */ 365 - len = g_st_write(skb); 366 - if (len < 0) { 367 - kfree_skb(skb); 368 - fmdev->resp_comp = NULL; 369 - fmerr("TX bh work failed to send skb(%p)\n", skb); 370 - atomic_set(&fmdev->tx_cnt, 1); 371 - } else { 372 - fmdev->last_tx_jiffies = jiffies; 373 - } 374 - } 375 - 376 - /* 377 - * Queues FM Channel-8 packet to FM TX queue and schedules FM TX bh work for 378 - * transmission 379 - */ 380 - static int fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, 381 - int payload_len, struct completion *wait_completion) 382 - { 383 - struct sk_buff *skb; 384 - struct fm_cmd_msg_hdr *hdr; 385 - int size; 386 - 387 - if (fm_op >= FM_INTERRUPT) { 388 - fmerr("Invalid fm opcode - %d\n", fm_op); 389 - return -EINVAL; 390 - } 391 - if (test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) && payload == NULL) { 392 - fmerr("Payload data is NULL during fw download\n"); 393 - return -EINVAL; 394 - } 395 - if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag)) 396 - size = 397 - FM_CMD_MSG_HDR_SIZE + ((payload == NULL) ? 0 : payload_len); 398 - else 399 - size = payload_len; 400 - 401 - skb = alloc_skb(size, GFP_ATOMIC); 402 - if (!skb) { 403 - fmerr("No memory to create new SKB\n"); 404 - return -ENOMEM; 405 - } 406 - /* 407 - * Don't fill FM header info for the commands which come from 408 - * FM firmware file. 409 - */ 410 - if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) || 411 - test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) { 412 - /* Fill command header info */ 413 - hdr = skb_put(skb, FM_CMD_MSG_HDR_SIZE); 414 - hdr->hdr = FM_PKT_LOGICAL_CHAN_NUMBER; /* 0x08 */ 415 - 416 - /* 3 (fm_opcode,rd_wr,dlen) + payload len) */ 417 - hdr->len = ((payload == NULL) ? 0 : payload_len) + 3; 418 - 419 - /* FM opcode */ 420 - hdr->op = fm_op; 421 - 422 - /* read/write type */ 423 - hdr->rd_wr = type; 424 - hdr->dlen = payload_len; 425 - fm_cb(skb)->fm_op = fm_op; 426 - 427 - /* 428 - * If firmware download has finished and the command is 429 - * not a read command then payload is != NULL - a write 430 - * command with u16 payload - convert to be16 431 - */ 432 - if (payload != NULL) 433 - *(__be16 *)payload = cpu_to_be16(*(u16 *)payload); 434 - 435 - } else if (payload != NULL) { 436 - fm_cb(skb)->fm_op = *((u8 *)payload + 2); 437 - } 438 - if (payload != NULL) 439 - skb_put_data(skb, payload, payload_len); 440 - 441 - fm_cb(skb)->completion = wait_completion; 442 - skb_queue_tail(&fmdev->tx_q, skb); 443 - queue_work(system_bh_wq, &fmdev->tx_bh_work); 444 - 445 - return 0; 446 - } 447 - 448 - /* Sends FM Channel-8 command to the chip and waits for the response */ 449 - int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, 450 - unsigned int payload_len, void *response, int *response_len) 451 - { 452 - struct sk_buff *skb; 453 - struct fm_event_msg_hdr *evt_hdr; 454 - unsigned long flags; 455 - int ret; 456 - 457 - init_completion(&fmdev->maintask_comp); 458 - ret = fm_send_cmd(fmdev, fm_op, type, payload, payload_len, 459 - &fmdev->maintask_comp); 460 - if (ret) 461 - return ret; 462 - 463 - if (!wait_for_completion_timeout(&fmdev->maintask_comp, 464 - FM_DRV_TX_TIMEOUT)) { 465 - fmerr("Timeout(%d sec),didn't get regcompletion signal from RX bh work\n", 466 - jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); 467 - return -ETIMEDOUT; 468 - } 469 - spin_lock_irqsave(&fmdev->resp_skb_lock, flags); 470 - if (!fmdev->resp_skb) { 471 - spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); 472 - fmerr("Response SKB is missing\n"); 473 - return -EFAULT; 474 - } 475 - skb = fmdev->resp_skb; 476 - fmdev->resp_skb = NULL; 477 - spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); 478 - 479 - evt_hdr = (void *)skb->data; 480 - if (evt_hdr->status != 0) { 481 - fmerr("Received event pkt status(%d) is not zero\n", 482 - evt_hdr->status); 483 - kfree_skb(skb); 484 - return -EIO; 485 - } 486 - /* Send response data to caller */ 487 - if (response != NULL && response_len != NULL && evt_hdr->dlen && 488 - evt_hdr->dlen <= payload_len) { 489 - /* Skip header info and copy only response data */ 490 - skb_pull(skb, sizeof(struct fm_event_msg_hdr)); 491 - memcpy(response, skb->data, evt_hdr->dlen); 492 - *response_len = evt_hdr->dlen; 493 - } else if (response_len != NULL && evt_hdr->dlen == 0) { 494 - *response_len = 0; 495 - } 496 - kfree_skb(skb); 497 - 498 - return 0; 499 - } 500 - 501 - /* --- Helper functions used in FM interrupt handlers ---*/ 502 - static inline int check_cmdresp_status(struct fmdev *fmdev, 503 - struct sk_buff **skb) 504 - { 505 - struct fm_event_msg_hdr *fm_evt_hdr; 506 - unsigned long flags; 507 - 508 - del_timer(&fmdev->irq_info.timer); 509 - 510 - spin_lock_irqsave(&fmdev->resp_skb_lock, flags); 511 - *skb = fmdev->resp_skb; 512 - fmdev->resp_skb = NULL; 513 - spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); 514 - 515 - fm_evt_hdr = (void *)(*skb)->data; 516 - if (fm_evt_hdr->status != 0) { 517 - fmerr("irq: opcode %x response status is not zero Initiating irq recovery process\n", 518 - fm_evt_hdr->op); 519 - 520 - mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT); 521 - return -1; 522 - } 523 - 524 - return 0; 525 - } 526 - 527 - static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage) 528 - { 529 - struct sk_buff *skb; 530 - 531 - if (!check_cmdresp_status(fmdev, &skb)) 532 - fm_irq_call_stage(fmdev, stage); 533 - } 534 - 535 - /* 536 - * Interrupt process timeout handler. 537 - * One of the irq handler did not get proper response from the chip. So take 538 - * recovery action here. FM interrupts are disabled in the beginning of 539 - * interrupt process. Therefore reset stage index to re-enable default 540 - * interrupts. So that next interrupt will be processed as usual. 541 - */ 542 - static void int_timeout_handler(struct timer_list *t) 543 - { 544 - struct fmdev *fmdev; 545 - struct fm_irq *fmirq; 546 - 547 - fmdbg("irq: timeout,trying to re-enable fm interrupts\n"); 548 - fmdev = from_timer(fmdev, t, irq_info.timer); 549 - fmirq = &fmdev->irq_info; 550 - fmirq->retry++; 551 - 552 - if (fmirq->retry > FM_IRQ_TIMEOUT_RETRY_MAX) { 553 - /* Stop recovery action (interrupt reenable process) and 554 - * reset stage index & retry count values */ 555 - fmirq->stage = 0; 556 - fmirq->retry = 0; 557 - fmerr("Recovery action failed duringirq processing, max retry reached\n"); 558 - return; 559 - } 560 - fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX); 561 - } 562 - 563 - /* --------- FM interrupt handlers ------------*/ 564 - static void fm_irq_send_flag_getcmd(struct fmdev *fmdev) 565 - { 566 - u16 flag; 567 - 568 - /* Send FLAG_GET command , to know the source of interrupt */ 569 - if (!fm_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, sizeof(flag), NULL)) 570 - fm_irq_timeout_stage(fmdev, FM_HANDLE_FLAG_GETCMD_RESP_IDX); 571 - } 572 - 573 - static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev) 574 - { 575 - struct sk_buff *skb; 576 - struct fm_event_msg_hdr *fm_evt_hdr; 577 - 578 - if (check_cmdresp_status(fmdev, &skb)) 579 - return; 580 - 581 - fm_evt_hdr = (void *)skb->data; 582 - if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag)) 583 - return; 584 - 585 - /* Skip header info and copy only response data */ 586 - skb_pull(skb, sizeof(struct fm_event_msg_hdr)); 587 - memcpy(&fmdev->irq_info.flag, skb->data, fm_evt_hdr->dlen); 588 - 589 - fmdev->irq_info.flag = be16_to_cpu((__force __be16)fmdev->irq_info.flag); 590 - fmdbg("irq: flag register(0x%x)\n", fmdev->irq_info.flag); 591 - 592 - /* Continue next function in interrupt handler table */ 593 - fm_irq_call_stage(fmdev, FM_HW_MAL_FUNC_IDX); 594 - } 595 - 596 - static void fm_irq_handle_hw_malfunction(struct fmdev *fmdev) 597 - { 598 - if (fmdev->irq_info.flag & FM_MAL_EVENT & fmdev->irq_info.mask) 599 - fmerr("irq: HW MAL int received - do nothing\n"); 600 - 601 - /* Continue next function in interrupt handler table */ 602 - fm_irq_call_stage(fmdev, FM_RDS_START_IDX); 603 - } 604 - 605 - static void fm_irq_handle_rds_start(struct fmdev *fmdev) 606 - { 607 - if (fmdev->irq_info.flag & FM_RDS_EVENT & fmdev->irq_info.mask) { 608 - fmdbg("irq: rds threshold reached\n"); 609 - fmdev->irq_info.stage = FM_RDS_SEND_RDS_GETCMD_IDX; 610 - } else { 611 - /* Continue next function in interrupt handler table */ 612 - fmdev->irq_info.stage = FM_HW_TUNE_OP_ENDED_IDX; 613 - } 614 - 615 - fm_irq_call(fmdev); 616 - } 617 - 618 - static void fm_irq_send_rdsdata_getcmd(struct fmdev *fmdev) 619 - { 620 - /* Send the command to read RDS data from the chip */ 621 - if (!fm_send_cmd(fmdev, RDS_DATA_GET, REG_RD, NULL, 622 - (FM_RX_RDS_FIFO_THRESHOLD * 3), NULL)) 623 - fm_irq_timeout_stage(fmdev, FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX); 624 - } 625 - 626 - /* Keeps track of current RX channel AF (Alternate Frequency) */ 627 - static void fm_rx_update_af_cache(struct fmdev *fmdev, u8 af) 628 - { 629 - struct tuned_station_info *stat_info = &fmdev->rx.stat_info; 630 - u8 reg_idx = fmdev->rx.region.fm_band; 631 - u8 index; 632 - u32 freq; 633 - 634 - /* First AF indicates the number of AF follows. Reset the list */ 635 - if ((af >= FM_RDS_1_AF_FOLLOWS) && (af <= FM_RDS_25_AF_FOLLOWS)) { 636 - fmdev->rx.stat_info.af_list_max = (af - FM_RDS_1_AF_FOLLOWS + 1); 637 - fmdev->rx.stat_info.afcache_size = 0; 638 - fmdbg("No of expected AF : %d\n", fmdev->rx.stat_info.af_list_max); 639 - return; 640 - } 641 - 642 - if (af < FM_RDS_MIN_AF) 643 - return; 644 - if (reg_idx == FM_BAND_EUROPE_US && af > FM_RDS_MAX_AF) 645 - return; 646 - if (reg_idx == FM_BAND_JAPAN && af > FM_RDS_MAX_AF_JAPAN) 647 - return; 648 - 649 - freq = fmdev->rx.region.bot_freq + (af * 100); 650 - if (freq == fmdev->rx.freq) { 651 - fmdbg("Current freq(%d) is matching with received AF(%d)\n", 652 - fmdev->rx.freq, freq); 653 - return; 654 - } 655 - /* Do check in AF cache */ 656 - for (index = 0; index < stat_info->afcache_size; index++) { 657 - if (stat_info->af_cache[index] == freq) 658 - break; 659 - } 660 - /* Reached the limit of the list - ignore the next AF */ 661 - if (index == stat_info->af_list_max) { 662 - fmdbg("AF cache is full\n"); 663 - return; 664 - } 665 - /* 666 - * If we reached the end of the list then this AF is not 667 - * in the list - add it. 668 - */ 669 - if (index == stat_info->afcache_size) { 670 - fmdbg("Storing AF %d to cache index %d\n", freq, index); 671 - stat_info->af_cache[index] = freq; 672 - stat_info->afcache_size++; 673 - } 674 - } 675 - 676 - /* 677 - * Converts RDS buffer data from big endian format 678 - * to little endian format. 679 - */ 680 - static void fm_rdsparse_swapbytes(struct fmdev *fmdev, 681 - struct fm_rdsdata_format *rds_format) 682 - { 683 - u8 index = 0; 684 - u8 *rds_buff; 685 - 686 - /* 687 - * Since in Orca the 2 RDS Data bytes are in little endian and 688 - * in Dolphin they are in big endian, the parsing of the RDS data 689 - * is chip dependent 690 - */ 691 - if (fmdev->asci_id != 0x6350) { 692 - rds_buff = &rds_format->data.groupdatabuff.buff[0]; 693 - while (index + 1 < FM_RX_RDS_INFO_FIELD_MAX) { 694 - swap(rds_buff[index], rds_buff[index + 1]); 695 - index += 2; 696 - } 697 - } 698 - } 699 - 700 - static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev) 701 - { 702 - struct sk_buff *skb; 703 - struct fm_rdsdata_format rds_fmt; 704 - struct fm_rds *rds = &fmdev->rx.rds; 705 - unsigned long group_idx, flags; 706 - u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE]; 707 - u8 type, blk_idx, idx; 708 - u16 cur_picode; 709 - u32 rds_len; 710 - 711 - if (check_cmdresp_status(fmdev, &skb)) 712 - return; 713 - 714 - /* Skip header info */ 715 - skb_pull(skb, sizeof(struct fm_event_msg_hdr)); 716 - rds_data = skb->data; 717 - rds_len = skb->len; 718 - 719 - /* Parse the RDS data */ 720 - while (rds_len >= FM_RDS_BLK_SIZE) { 721 - meta_data = rds_data[2]; 722 - /* Get the type: 0=A, 1=B, 2=C, 3=C', 4=D, 5=E */ 723 - type = (meta_data & 0x07); 724 - 725 - /* Transform the blk type into index sequence (0, 1, 2, 3, 4) */ 726 - blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1)); 727 - fmdbg("Block index:%d(%s)\n", blk_idx, 728 - (meta_data & FM_RDS_STATUS_ERR_MASK) ? "Bad" : "Ok"); 729 - 730 - if ((meta_data & FM_RDS_STATUS_ERR_MASK) != 0) 731 - break; 732 - 733 - if (blk_idx > FM_RDS_BLK_IDX_D) { 734 - fmdbg("Block sequence mismatch\n"); 735 - rds->last_blk_idx = -1; 736 - break; 737 - } 738 - 739 - /* Skip checkword (control) byte and copy only data byte */ 740 - idx = array_index_nospec(blk_idx * (FM_RDS_BLK_SIZE - 1), 741 - FM_RX_RDS_INFO_FIELD_MAX - (FM_RDS_BLK_SIZE - 1)); 742 - 743 - memcpy(&rds_fmt.data.groupdatabuff.buff[idx], rds_data, 744 - FM_RDS_BLK_SIZE - 1); 745 - 746 - rds->last_blk_idx = blk_idx; 747 - 748 - /* If completed a whole group then handle it */ 749 - if (blk_idx == FM_RDS_BLK_IDX_D) { 750 - fmdbg("Good block received\n"); 751 - fm_rdsparse_swapbytes(fmdev, &rds_fmt); 752 - 753 - /* 754 - * Extract PI code and store in local cache. 755 - * We need this during AF switch processing. 756 - */ 757 - cur_picode = be16_to_cpu((__force __be16)rds_fmt.data.groupgeneral.pidata); 758 - if (fmdev->rx.stat_info.picode != cur_picode) 759 - fmdev->rx.stat_info.picode = cur_picode; 760 - 761 - fmdbg("picode:%d\n", cur_picode); 762 - 763 - group_idx = (rds_fmt.data.groupgeneral.blk_b[0] >> 3); 764 - fmdbg("(fmdrv):Group:%ld%s\n", group_idx/2, 765 - (group_idx % 2) ? "B" : "A"); 766 - 767 - group_idx = 1 << (rds_fmt.data.groupgeneral.blk_b[0] >> 3); 768 - if (group_idx == FM_RDS_GROUP_TYPE_MASK_0A) { 769 - fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[0]); 770 - fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[1]); 771 - } 772 - } 773 - rds_len -= FM_RDS_BLK_SIZE; 774 - rds_data += FM_RDS_BLK_SIZE; 775 - } 776 - 777 - /* Copy raw rds data to internal rds buffer */ 778 - rds_data = skb->data; 779 - rds_len = skb->len; 780 - 781 - spin_lock_irqsave(&fmdev->rds_buff_lock, flags); 782 - while (rds_len > 0) { 783 - /* 784 - * Fill RDS buffer as per V4L2 specification. 785 - * Store control byte 786 - */ 787 - type = (rds_data[2] & 0x07); 788 - blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1)); 789 - tmpbuf[2] = blk_idx; /* Offset name */ 790 - tmpbuf[2] |= blk_idx << 3; /* Received offset */ 791 - 792 - /* Store data byte */ 793 - tmpbuf[0] = rds_data[0]; 794 - tmpbuf[1] = rds_data[1]; 795 - 796 - memcpy(&rds->buff[rds->wr_idx], &tmpbuf, FM_RDS_BLK_SIZE); 797 - rds->wr_idx = (rds->wr_idx + FM_RDS_BLK_SIZE) % rds->buf_size; 798 - 799 - /* Check for overflow & start over */ 800 - if (rds->wr_idx == rds->rd_idx) { 801 - fmdbg("RDS buffer overflow\n"); 802 - rds->wr_idx = 0; 803 - rds->rd_idx = 0; 804 - break; 805 - } 806 - rds_len -= FM_RDS_BLK_SIZE; 807 - rds_data += FM_RDS_BLK_SIZE; 808 - } 809 - spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); 810 - 811 - /* Wakeup read queue */ 812 - if (rds->wr_idx != rds->rd_idx) 813 - wake_up_interruptible(&rds->read_queue); 814 - 815 - fm_irq_call_stage(fmdev, FM_RDS_FINISH_IDX); 816 - } 817 - 818 - static void fm_irq_handle_rds_finish(struct fmdev *fmdev) 819 - { 820 - fm_irq_call_stage(fmdev, FM_HW_TUNE_OP_ENDED_IDX); 821 - } 822 - 823 - static void fm_irq_handle_tune_op_ended(struct fmdev *fmdev) 824 - { 825 - if (fmdev->irq_info.flag & (FM_FR_EVENT | FM_BL_EVENT) & fmdev-> 826 - irq_info.mask) { 827 - fmdbg("irq: tune ended/bandlimit reached\n"); 828 - if (test_and_clear_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag)) { 829 - fmdev->irq_info.stage = FM_AF_JUMP_RD_FREQ_IDX; 830 - } else { 831 - complete(&fmdev->maintask_comp); 832 - fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX; 833 - } 834 - } else 835 - fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX; 836 - 837 - fm_irq_call(fmdev); 838 - } 839 - 840 - static void fm_irq_handle_power_enb(struct fmdev *fmdev) 841 - { 842 - if (fmdev->irq_info.flag & FM_POW_ENB_EVENT) { 843 - fmdbg("irq: Power Enabled/Disabled\n"); 844 - complete(&fmdev->maintask_comp); 845 - } 846 - 847 - fm_irq_call_stage(fmdev, FM_LOW_RSSI_START_IDX); 848 - } 849 - 850 - static void fm_irq_handle_low_rssi_start(struct fmdev *fmdev) 851 - { 852 - if ((fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) && 853 - (fmdev->irq_info.flag & FM_LEV_EVENT & fmdev->irq_info.mask) && 854 - (fmdev->rx.freq != FM_UNDEFINED_FREQ) && 855 - (fmdev->rx.stat_info.afcache_size != 0)) { 856 - fmdbg("irq: rssi level has fallen below threshold level\n"); 857 - 858 - /* Disable further low RSSI interrupts */ 859 - fmdev->irq_info.mask &= ~FM_LEV_EVENT; 860 - 861 - fmdev->rx.afjump_idx = 0; 862 - fmdev->rx.freq_before_jump = fmdev->rx.freq; 863 - fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX; 864 - } else { 865 - /* Continue next function in interrupt handler table */ 866 - fmdev->irq_info.stage = FM_SEND_INTMSK_CMD_IDX; 867 - } 868 - 869 - fm_irq_call(fmdev); 870 - } 871 - 872 - static void fm_irq_afjump_set_pi(struct fmdev *fmdev) 873 - { 874 - u16 payload; 875 - 876 - /* Set PI code - must be updated if the AF list is not empty */ 877 - payload = fmdev->rx.stat_info.picode; 878 - if (!fm_send_cmd(fmdev, RDS_PI_SET, REG_WR, &payload, sizeof(payload), NULL)) 879 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_RESP_IDX); 880 - } 881 - 882 - static void fm_irq_handle_set_pi_resp(struct fmdev *fmdev) 883 - { 884 - fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SETPI_MASK_IDX); 885 - } 886 - 887 - /* 888 - * Set PI mask. 889 - * 0xFFFF = Enable PI code matching 890 - * 0x0000 = Disable PI code matching 891 - */ 892 - static void fm_irq_afjump_set_pimask(struct fmdev *fmdev) 893 - { 894 - u16 payload; 895 - 896 - payload = 0x0000; 897 - if (!fm_send_cmd(fmdev, RDS_PI_MASK_SET, REG_WR, &payload, sizeof(payload), NULL)) 898 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX); 899 - } 900 - 901 - static void fm_irq_handle_set_pimask_resp(struct fmdev *fmdev) 902 - { 903 - fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SET_AF_FREQ_IDX); 904 - } 905 - 906 - static void fm_irq_afjump_setfreq(struct fmdev *fmdev) 907 - { 908 - u16 frq_index; 909 - u16 payload; 910 - 911 - fmdbg("Switch to %d KHz\n", fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]); 912 - frq_index = (fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx] - 913 - fmdev->rx.region.bot_freq) / FM_FREQ_MUL; 914 - 915 - payload = frq_index; 916 - if (!fm_send_cmd(fmdev, AF_FREQ_SET, REG_WR, &payload, sizeof(payload), NULL)) 917 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX); 918 - } 919 - 920 - static void fm_irq_handle_setfreq_resp(struct fmdev *fmdev) 921 - { 922 - fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_ENABLE_INT_IDX); 923 - } 924 - 925 - static void fm_irq_afjump_enableint(struct fmdev *fmdev) 926 - { 927 - u16 payload; 928 - 929 - /* Enable FR (tuning operation ended) interrupt */ 930 - payload = FM_FR_EVENT; 931 - if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, sizeof(payload), NULL)) 932 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_ENABLE_INT_RESP_IDX); 933 - } 934 - 935 - static void fm_irq_afjump_enableint_resp(struct fmdev *fmdev) 936 - { 937 - fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_START_AFJUMP_IDX); 938 - } 939 - 940 - static void fm_irq_start_afjump(struct fmdev *fmdev) 941 - { 942 - u16 payload; 943 - 944 - payload = FM_TUNER_AF_JUMP_MODE; 945 - if (!fm_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload, 946 - sizeof(payload), NULL)) 947 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX); 948 - } 949 - 950 - static void fm_irq_handle_start_afjump_resp(struct fmdev *fmdev) 951 - { 952 - struct sk_buff *skb; 953 - 954 - if (check_cmdresp_status(fmdev, &skb)) 955 - return; 956 - 957 - fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX; 958 - set_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag); 959 - clear_bit(FM_INTTASK_RUNNING, &fmdev->flag); 960 - } 961 - 962 - static void fm_irq_afjump_rd_freq(struct fmdev *fmdev) 963 - { 964 - u16 payload; 965 - 966 - if (!fm_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, sizeof(payload), NULL)) 967 - fm_irq_timeout_stage(fmdev, FM_AF_JUMP_RD_FREQ_RESP_IDX); 968 - } 969 - 970 - static void fm_irq_afjump_rd_freq_resp(struct fmdev *fmdev) 971 - { 972 - struct sk_buff *skb; 973 - u16 read_freq; 974 - u32 curr_freq, jumped_freq; 975 - 976 - if (check_cmdresp_status(fmdev, &skb)) 977 - return; 978 - 979 - /* Skip header info and copy only response data */ 980 - skb_pull(skb, sizeof(struct fm_event_msg_hdr)); 981 - memcpy(&read_freq, skb->data, sizeof(read_freq)); 982 - read_freq = be16_to_cpu((__force __be16)read_freq); 983 - curr_freq = fmdev->rx.region.bot_freq + ((u32)read_freq * FM_FREQ_MUL); 984 - 985 - jumped_freq = fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]; 986 - 987 - /* If the frequency was changed the jump succeeded */ 988 - if ((curr_freq != fmdev->rx.freq_before_jump) && (curr_freq == jumped_freq)) { 989 - fmdbg("Successfully switched to alternate freq %d\n", curr_freq); 990 - fmdev->rx.freq = curr_freq; 991 - fm_rx_reset_rds_cache(fmdev); 992 - 993 - /* AF feature is on, enable low level RSSI interrupt */ 994 - if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) 995 - fmdev->irq_info.mask |= FM_LEV_EVENT; 996 - 997 - fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX; 998 - } else { /* jump to the next freq in the AF list */ 999 - fmdev->rx.afjump_idx++; 1000 - 1001 - /* If we reached the end of the list - stop searching */ 1002 - if (fmdev->rx.afjump_idx >= fmdev->rx.stat_info.afcache_size) { 1003 - fmdbg("AF switch processing failed\n"); 1004 - fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX; 1005 - } else { /* AF List is not over - try next one */ 1006 - 1007 - fmdbg("Trying next freq in AF cache\n"); 1008 - fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX; 1009 - } 1010 - } 1011 - fm_irq_call(fmdev); 1012 - } 1013 - 1014 - static void fm_irq_handle_low_rssi_finish(struct fmdev *fmdev) 1015 - { 1016 - fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX); 1017 - } 1018 - 1019 - static void fm_irq_send_intmsk_cmd(struct fmdev *fmdev) 1020 - { 1021 - u16 payload; 1022 - 1023 - /* Re-enable FM interrupts */ 1024 - payload = fmdev->irq_info.mask; 1025 - 1026 - if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 1027 - sizeof(payload), NULL)) 1028 - fm_irq_timeout_stage(fmdev, FM_HANDLE_INTMSK_CMD_RESP_IDX); 1029 - } 1030 - 1031 - static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *fmdev) 1032 - { 1033 - struct sk_buff *skb; 1034 - 1035 - if (check_cmdresp_status(fmdev, &skb)) 1036 - return; 1037 - /* 1038 - * This is last function in interrupt table to be executed. 1039 - * So, reset stage index to 0. 1040 - */ 1041 - fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX; 1042 - 1043 - /* Start processing any pending interrupt */ 1044 - if (test_and_clear_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag)) 1045 - fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev); 1046 - else 1047 - clear_bit(FM_INTTASK_RUNNING, &fmdev->flag); 1048 - } 1049 - 1050 - /* Returns availability of RDS data in internal buffer */ 1051 - int fmc_is_rds_data_available(struct fmdev *fmdev, struct file *file, 1052 - struct poll_table_struct *pts) 1053 - { 1054 - poll_wait(file, &fmdev->rx.rds.read_queue, pts); 1055 - if (fmdev->rx.rds.rd_idx != fmdev->rx.rds.wr_idx) 1056 - return 0; 1057 - 1058 - return -EAGAIN; 1059 - } 1060 - 1061 - /* Copies RDS data from internal buffer to user buffer */ 1062 - int fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file, 1063 - u8 __user *buf, size_t count) 1064 - { 1065 - u32 block_count; 1066 - u8 tmpbuf[FM_RDS_BLK_SIZE]; 1067 - unsigned long flags; 1068 - int ret; 1069 - 1070 - if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) { 1071 - if (file->f_flags & O_NONBLOCK) 1072 - return -EWOULDBLOCK; 1073 - 1074 - ret = wait_event_interruptible(fmdev->rx.rds.read_queue, 1075 - (fmdev->rx.rds.wr_idx != fmdev->rx.rds.rd_idx)); 1076 - if (ret) 1077 - return -EINTR; 1078 - } 1079 - 1080 - /* Calculate block count from byte count */ 1081 - count /= FM_RDS_BLK_SIZE; 1082 - block_count = 0; 1083 - ret = 0; 1084 - 1085 - while (block_count < count) { 1086 - spin_lock_irqsave(&fmdev->rds_buff_lock, flags); 1087 - 1088 - if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) { 1089 - spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); 1090 - break; 1091 - } 1092 - memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx], 1093 - FM_RDS_BLK_SIZE); 1094 - fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE; 1095 - if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size) 1096 - fmdev->rx.rds.rd_idx = 0; 1097 - 1098 - spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); 1099 - 1100 - if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE)) 1101 - break; 1102 - 1103 - block_count++; 1104 - buf += FM_RDS_BLK_SIZE; 1105 - ret += FM_RDS_BLK_SIZE; 1106 - } 1107 - return ret; 1108 - } 1109 - 1110 - int fmc_set_freq(struct fmdev *fmdev, u32 freq_to_set) 1111 - { 1112 - switch (fmdev->curr_fmmode) { 1113 - case FM_MODE_RX: 1114 - return fm_rx_set_freq(fmdev, freq_to_set); 1115 - 1116 - case FM_MODE_TX: 1117 - return fm_tx_set_freq(fmdev, freq_to_set); 1118 - 1119 - default: 1120 - return -EINVAL; 1121 - } 1122 - } 1123 - 1124 - int fmc_get_freq(struct fmdev *fmdev, u32 *cur_tuned_frq) 1125 - { 1126 - if (fmdev->rx.freq == FM_UNDEFINED_FREQ) { 1127 - fmerr("RX frequency is not set\n"); 1128 - return -EPERM; 1129 - } 1130 - if (cur_tuned_frq == NULL) { 1131 - fmerr("Invalid memory\n"); 1132 - return -ENOMEM; 1133 - } 1134 - 1135 - switch (fmdev->curr_fmmode) { 1136 - case FM_MODE_RX: 1137 - *cur_tuned_frq = fmdev->rx.freq; 1138 - return 0; 1139 - 1140 - case FM_MODE_TX: 1141 - *cur_tuned_frq = 0; /* TODO : Change this later */ 1142 - return 0; 1143 - 1144 - default: 1145 - return -EINVAL; 1146 - } 1147 - 1148 - } 1149 - 1150 - int fmc_set_region(struct fmdev *fmdev, u8 region_to_set) 1151 - { 1152 - switch (fmdev->curr_fmmode) { 1153 - case FM_MODE_RX: 1154 - return fm_rx_set_region(fmdev, region_to_set); 1155 - 1156 - case FM_MODE_TX: 1157 - return fm_tx_set_region(fmdev, region_to_set); 1158 - 1159 - default: 1160 - return -EINVAL; 1161 - } 1162 - } 1163 - 1164 - int fmc_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset) 1165 - { 1166 - switch (fmdev->curr_fmmode) { 1167 - case FM_MODE_RX: 1168 - return fm_rx_set_mute_mode(fmdev, mute_mode_toset); 1169 - 1170 - case FM_MODE_TX: 1171 - return fm_tx_set_mute_mode(fmdev, mute_mode_toset); 1172 - 1173 - default: 1174 - return -EINVAL; 1175 - } 1176 - } 1177 - 1178 - int fmc_set_stereo_mono(struct fmdev *fmdev, u16 mode) 1179 - { 1180 - switch (fmdev->curr_fmmode) { 1181 - case FM_MODE_RX: 1182 - return fm_rx_set_stereo_mono(fmdev, mode); 1183 - 1184 - case FM_MODE_TX: 1185 - return fm_tx_set_stereo_mono(fmdev, mode); 1186 - 1187 - default: 1188 - return -EINVAL; 1189 - } 1190 - } 1191 - 1192 - int fmc_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis) 1193 - { 1194 - switch (fmdev->curr_fmmode) { 1195 - case FM_MODE_RX: 1196 - return fm_rx_set_rds_mode(fmdev, rds_en_dis); 1197 - 1198 - case FM_MODE_TX: 1199 - return fm_tx_set_rds_mode(fmdev, rds_en_dis); 1200 - 1201 - default: 1202 - return -EINVAL; 1203 - } 1204 - } 1205 - 1206 - /* Sends power off command to the chip */ 1207 - static int fm_power_down(struct fmdev *fmdev) 1208 - { 1209 - u16 payload; 1210 - int ret; 1211 - 1212 - if (!test_bit(FM_CORE_READY, &fmdev->flag)) { 1213 - fmerr("FM core is not ready\n"); 1214 - return -EPERM; 1215 - } 1216 - if (fmdev->curr_fmmode == FM_MODE_OFF) { 1217 - fmdbg("FM chip is already in OFF state\n"); 1218 - return 0; 1219 - } 1220 - 1221 - payload = 0x0; 1222 - ret = fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload, 1223 - sizeof(payload), NULL, NULL); 1224 - if (ret < 0) 1225 - return ret; 1226 - 1227 - return fmc_release(fmdev); 1228 - } 1229 - 1230 - /* Reads init command from FM firmware file and loads to the chip */ 1231 - static int fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name) 1232 - { 1233 - const struct firmware *fw_entry; 1234 - struct bts_header *fw_header; 1235 - struct bts_action *action; 1236 - struct bts_action_delay *delay; 1237 - u8 *fw_data; 1238 - int ret, fw_len; 1239 - 1240 - set_bit(FM_FW_DW_INPROGRESS, &fmdev->flag); 1241 - 1242 - ret = request_firmware(&fw_entry, fw_name, 1243 - &fmdev->radio_dev->dev); 1244 - if (ret < 0) { 1245 - fmerr("Unable to read firmware(%s) content\n", fw_name); 1246 - return ret; 1247 - } 1248 - fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size); 1249 - 1250 - fw_data = (void *)fw_entry->data; 1251 - fw_len = fw_entry->size; 1252 - 1253 - fw_header = (struct bts_header *)fw_data; 1254 - if (fw_header->magic != FM_FW_FILE_HEADER_MAGIC) { 1255 - fmerr("%s not a legal TI firmware file\n", fw_name); 1256 - ret = -EINVAL; 1257 - goto rel_fw; 1258 - } 1259 - fmdbg("FW(%s) magic number : 0x%x\n", fw_name, fw_header->magic); 1260 - 1261 - /* Skip file header info , we already verified it */ 1262 - fw_data += sizeof(struct bts_header); 1263 - fw_len -= sizeof(struct bts_header); 1264 - 1265 - while (fw_data && fw_len > 0) { 1266 - action = (struct bts_action *)fw_data; 1267 - 1268 - switch (action->type) { 1269 - case ACTION_SEND_COMMAND: /* Send */ 1270 - ret = fmc_send_cmd(fmdev, 0, 0, action->data, 1271 - action->size, NULL, NULL); 1272 - if (ret) 1273 - goto rel_fw; 1274 - 1275 - break; 1276 - 1277 - case ACTION_DELAY: /* Delay */ 1278 - delay = (struct bts_action_delay *)action->data; 1279 - mdelay(delay->msec); 1280 - break; 1281 - } 1282 - 1283 - fw_data += (sizeof(struct bts_action) + (action->size)); 1284 - fw_len -= (sizeof(struct bts_action) + (action->size)); 1285 - } 1286 - fmdbg("Transferred only %d of %d bytes of the firmware to chip\n", 1287 - fw_entry->size - fw_len, fw_entry->size); 1288 - rel_fw: 1289 - release_firmware(fw_entry); 1290 - clear_bit(FM_FW_DW_INPROGRESS, &fmdev->flag); 1291 - 1292 - return ret; 1293 - } 1294 - 1295 - /* Loads default RX configuration to the chip */ 1296 - static int load_default_rx_configuration(struct fmdev *fmdev) 1297 - { 1298 - int ret; 1299 - 1300 - ret = fm_rx_set_volume(fmdev, FM_DEFAULT_RX_VOLUME); 1301 - if (ret < 0) 1302 - return ret; 1303 - 1304 - return fm_rx_set_rssi_threshold(fmdev, FM_DEFAULT_RSSI_THRESHOLD); 1305 - } 1306 - 1307 - /* Does FM power on sequence */ 1308 - static int fm_power_up(struct fmdev *fmdev, u8 mode) 1309 - { 1310 - u16 payload; 1311 - __be16 asic_id = 0, asic_ver = 0; 1312 - int resp_len, ret; 1313 - u8 fw_name[50]; 1314 - 1315 - if (mode >= FM_MODE_ENTRY_MAX) { 1316 - fmerr("Invalid firmware download option\n"); 1317 - return -EINVAL; 1318 - } 1319 - 1320 - /* 1321 - * Initialize FM common module. FM GPIO toggling is 1322 - * taken care in Shared Transport driver. 1323 - */ 1324 - ret = fmc_prepare(fmdev); 1325 - if (ret < 0) { 1326 - fmerr("Unable to prepare FM Common\n"); 1327 - return ret; 1328 - } 1329 - 1330 - payload = FM_ENABLE; 1331 - if (fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload, 1332 - sizeof(payload), NULL, NULL)) 1333 - goto rel; 1334 - 1335 - /* Allow the chip to settle down in Channel-8 mode */ 1336 - msleep(20); 1337 - 1338 - if (fmc_send_cmd(fmdev, ASIC_ID_GET, REG_RD, NULL, 1339 - sizeof(asic_id), &asic_id, &resp_len)) 1340 - goto rel; 1341 - 1342 - if (fmc_send_cmd(fmdev, ASIC_VER_GET, REG_RD, NULL, 1343 - sizeof(asic_ver), &asic_ver, &resp_len)) 1344 - goto rel; 1345 - 1346 - fmdbg("ASIC ID: 0x%x , ASIC Version: %d\n", 1347 - be16_to_cpu(asic_id), be16_to_cpu(asic_ver)); 1348 - 1349 - sprintf(fw_name, "%s_%x.%d.bts", FM_FMC_FW_FILE_START, 1350 - be16_to_cpu(asic_id), be16_to_cpu(asic_ver)); 1351 - 1352 - ret = fm_download_firmware(fmdev, fw_name); 1353 - if (ret < 0) { 1354 - fmdbg("Failed to download firmware file %s\n", fw_name); 1355 - goto rel; 1356 - } 1357 - sprintf(fw_name, "%s_%x.%d.bts", (mode == FM_MODE_RX) ? 1358 - FM_RX_FW_FILE_START : FM_TX_FW_FILE_START, 1359 - be16_to_cpu(asic_id), be16_to_cpu(asic_ver)); 1360 - 1361 - ret = fm_download_firmware(fmdev, fw_name); 1362 - if (ret < 0) { 1363 - fmdbg("Failed to download firmware file %s\n", fw_name); 1364 - goto rel; 1365 - } else 1366 - return ret; 1367 - rel: 1368 - return fmc_release(fmdev); 1369 - } 1370 - 1371 - /* Set FM Modes(TX, RX, OFF) */ 1372 - int fmc_set_mode(struct fmdev *fmdev, u8 fm_mode) 1373 - { 1374 - int ret = 0; 1375 - 1376 - if (fm_mode >= FM_MODE_ENTRY_MAX) { 1377 - fmerr("Invalid FM mode\n"); 1378 - return -EINVAL; 1379 - } 1380 - if (fmdev->curr_fmmode == fm_mode) { 1381 - fmdbg("Already fm is in mode(%d)\n", fm_mode); 1382 - return ret; 1383 - } 1384 - 1385 - switch (fm_mode) { 1386 - case FM_MODE_OFF: /* OFF Mode */ 1387 - ret = fm_power_down(fmdev); 1388 - if (ret < 0) { 1389 - fmerr("Failed to set OFF mode\n"); 1390 - return ret; 1391 - } 1392 - break; 1393 - 1394 - case FM_MODE_TX: /* TX Mode */ 1395 - case FM_MODE_RX: /* RX Mode */ 1396 - /* Power down before switching to TX or RX mode */ 1397 - if (fmdev->curr_fmmode != FM_MODE_OFF) { 1398 - ret = fm_power_down(fmdev); 1399 - if (ret < 0) { 1400 - fmerr("Failed to set OFF mode\n"); 1401 - return ret; 1402 - } 1403 - msleep(30); 1404 - } 1405 - ret = fm_power_up(fmdev, fm_mode); 1406 - if (ret < 0) { 1407 - fmerr("Failed to load firmware\n"); 1408 - return ret; 1409 - } 1410 - } 1411 - fmdev->curr_fmmode = fm_mode; 1412 - 1413 - /* Set default configuration */ 1414 - if (fmdev->curr_fmmode == FM_MODE_RX) { 1415 - fmdbg("Loading default rx configuration..\n"); 1416 - ret = load_default_rx_configuration(fmdev); 1417 - if (ret < 0) 1418 - fmerr("Failed to load default values\n"); 1419 - } 1420 - 1421 - return ret; 1422 - } 1423 - 1424 - /* Returns current FM mode (TX, RX, OFF) */ 1425 - int fmc_get_mode(struct fmdev *fmdev, u8 *fmmode) 1426 - { 1427 - if (!test_bit(FM_CORE_READY, &fmdev->flag)) { 1428 - fmerr("FM core is not ready\n"); 1429 - return -EPERM; 1430 - } 1431 - if (fmmode == NULL) { 1432 - fmerr("Invalid memory\n"); 1433 - return -ENOMEM; 1434 - } 1435 - 1436 - *fmmode = fmdev->curr_fmmode; 1437 - return 0; 1438 - } 1439 - 1440 - /* Called by ST layer when FM packet is available */ 1441 - static long fm_st_receive(void *arg, struct sk_buff *skb) 1442 - { 1443 - struct fmdev *fmdev; 1444 - 1445 - fmdev = arg; 1446 - 1447 - if (skb == NULL) { 1448 - fmerr("Invalid SKB received from ST\n"); 1449 - return -EFAULT; 1450 - } 1451 - 1452 - if (skb->cb[0] != FM_PKT_LOGICAL_CHAN_NUMBER) { 1453 - fmerr("Received SKB (%p) is not FM Channel 8 pkt\n", skb); 1454 - return -EINVAL; 1455 - } 1456 - 1457 - memcpy(skb_push(skb, 1), &skb->cb[0], 1); 1458 - skb_queue_tail(&fmdev->rx_q, skb); 1459 - queue_work(system_bh_wq, &fmdev->rx_bh_work); 1460 - 1461 - return 0; 1462 - } 1463 - 1464 - /* 1465 - * Called by ST layer to indicate protocol registration completion 1466 - * status. 1467 - */ 1468 - static void fm_st_reg_comp_cb(void *arg, int data) 1469 - { 1470 - struct fmdev *fmdev; 1471 - 1472 - fmdev = (struct fmdev *)arg; 1473 - fmdev->streg_cbdata = data; 1474 - complete(&wait_for_fmdrv_reg_comp); 1475 - } 1476 - 1477 - /* 1478 - * This function will be called from FM V4L2 open function. 1479 - * Register with ST driver and initialize driver data. 1480 - */ 1481 - int fmc_prepare(struct fmdev *fmdev) 1482 - { 1483 - static struct st_proto_s fm_st_proto; 1484 - int ret; 1485 - 1486 - if (test_bit(FM_CORE_READY, &fmdev->flag)) { 1487 - fmdbg("FM Core is already up\n"); 1488 - return 0; 1489 - } 1490 - 1491 - memset(&fm_st_proto, 0, sizeof(fm_st_proto)); 1492 - fm_st_proto.recv = fm_st_receive; 1493 - fm_st_proto.match_packet = NULL; 1494 - fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb; 1495 - fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */ 1496 - fm_st_proto.priv_data = fmdev; 1497 - fm_st_proto.chnl_id = 0x08; 1498 - fm_st_proto.max_frame_size = 0xff; 1499 - fm_st_proto.hdr_len = 1; 1500 - fm_st_proto.offset_len_in_hdr = 0; 1501 - fm_st_proto.len_size = 1; 1502 - fm_st_proto.reserve = 1; 1503 - 1504 - ret = st_register(&fm_st_proto); 1505 - if (ret == -EINPROGRESS) { 1506 - init_completion(&wait_for_fmdrv_reg_comp); 1507 - fmdev->streg_cbdata = -EINPROGRESS; 1508 - fmdbg("%s waiting for ST reg completion signal\n", __func__); 1509 - 1510 - if (!wait_for_completion_timeout(&wait_for_fmdrv_reg_comp, 1511 - FM_ST_REG_TIMEOUT)) { 1512 - fmerr("Timeout(%d sec), didn't get reg completion signal from ST\n", 1513 - jiffies_to_msecs(FM_ST_REG_TIMEOUT) / 1000); 1514 - return -ETIMEDOUT; 1515 - } 1516 - if (fmdev->streg_cbdata != 0) { 1517 - fmerr("ST reg comp CB called with error status %d\n", 1518 - fmdev->streg_cbdata); 1519 - return -EAGAIN; 1520 - } 1521 - 1522 - ret = 0; 1523 - } else if (ret < 0) { 1524 - fmerr("st_register failed %d\n", ret); 1525 - return -EAGAIN; 1526 - } 1527 - 1528 - if (fm_st_proto.write != NULL) { 1529 - g_st_write = fm_st_proto.write; 1530 - } else { 1531 - fmerr("Failed to get ST write func pointer\n"); 1532 - ret = st_unregister(&fm_st_proto); 1533 - if (ret < 0) 1534 - fmerr("st_unregister failed %d\n", ret); 1535 - return -EAGAIN; 1536 - } 1537 - 1538 - spin_lock_init(&fmdev->rds_buff_lock); 1539 - spin_lock_init(&fmdev->resp_skb_lock); 1540 - 1541 - /* Initialize TX queue and TX bh work */ 1542 - skb_queue_head_init(&fmdev->tx_q); 1543 - INIT_WORK(&fmdev->tx_bh_work, send_bh_work); 1544 - 1545 - /* Initialize RX Queue and RX bh work */ 1546 - skb_queue_head_init(&fmdev->rx_q); 1547 - INIT_WORK(&fmdev->rx_bh_work, recv_bh_work); 1548 - 1549 - fmdev->irq_info.stage = 0; 1550 - atomic_set(&fmdev->tx_cnt, 1); 1551 - fmdev->resp_comp = NULL; 1552 - 1553 - timer_setup(&fmdev->irq_info.timer, int_timeout_handler, 0); 1554 - /*TODO: add FM_STIC_EVENT later */ 1555 - fmdev->irq_info.mask = FM_MAL_EVENT; 1556 - 1557 - /* Region info */ 1558 - fmdev->rx.region = region_configs[default_radio_region]; 1559 - 1560 - fmdev->rx.mute_mode = FM_MUTE_OFF; 1561 - fmdev->rx.rf_depend_mute = FM_RX_RF_DEPENDENT_MUTE_OFF; 1562 - fmdev->rx.rds.flag = FM_RDS_DISABLE; 1563 - fmdev->rx.freq = FM_UNDEFINED_FREQ; 1564 - fmdev->rx.rds_mode = FM_RDS_SYSTEM_RDS; 1565 - fmdev->rx.af_mode = FM_RX_RDS_AF_SWITCH_MODE_OFF; 1566 - fmdev->irq_info.retry = 0; 1567 - 1568 - fm_rx_reset_rds_cache(fmdev); 1569 - init_waitqueue_head(&fmdev->rx.rds.read_queue); 1570 - 1571 - fm_rx_reset_station_info(fmdev); 1572 - set_bit(FM_CORE_READY, &fmdev->flag); 1573 - 1574 - return ret; 1575 - } 1576 - 1577 - /* 1578 - * This function will be called from FM V4L2 release function. 1579 - * Unregister from ST driver. 1580 - */ 1581 - int fmc_release(struct fmdev *fmdev) 1582 - { 1583 - static struct st_proto_s fm_st_proto; 1584 - int ret; 1585 - 1586 - if (!test_bit(FM_CORE_READY, &fmdev->flag)) { 1587 - fmdbg("FM Core is already down\n"); 1588 - return 0; 1589 - } 1590 - /* Service pending read */ 1591 - wake_up_interruptible(&fmdev->rx.rds.read_queue); 1592 - 1593 - cancel_work_sync(&fmdev->tx_bh_work); 1594 - cancel_work_sync(&fmdev->rx_bh_work); 1595 - 1596 - skb_queue_purge(&fmdev->tx_q); 1597 - skb_queue_purge(&fmdev->rx_q); 1598 - 1599 - fmdev->resp_comp = NULL; 1600 - fmdev->rx.freq = 0; 1601 - 1602 - memset(&fm_st_proto, 0, sizeof(fm_st_proto)); 1603 - fm_st_proto.chnl_id = 0x08; 1604 - 1605 - ret = st_unregister(&fm_st_proto); 1606 - 1607 - if (ret < 0) 1608 - fmerr("Failed to de-register FM from ST %d\n", ret); 1609 - else 1610 - fmdbg("Successfully unregistered from ST\n"); 1611 - 1612 - clear_bit(FM_CORE_READY, &fmdev->flag); 1613 - return ret; 1614 - } 1615 - 1616 - /* 1617 - * Module init function. Ask FM V4L module to register video device. 1618 - * Allocate memory for FM driver context and RX RDS buffer. 1619 - */ 1620 - static int __init fm_drv_init(void) 1621 - { 1622 - struct fmdev *fmdev = NULL; 1623 - int ret = -ENOMEM; 1624 - 1625 - fmdbg("FM driver version %s\n", FM_DRV_VERSION); 1626 - 1627 - fmdev = kzalloc(sizeof(struct fmdev), GFP_KERNEL); 1628 - if (NULL == fmdev) { 1629 - fmerr("Can't allocate operation structure memory\n"); 1630 - return ret; 1631 - } 1632 - fmdev->rx.rds.buf_size = default_rds_buf * FM_RDS_BLK_SIZE; 1633 - fmdev->rx.rds.buff = kzalloc(fmdev->rx.rds.buf_size, GFP_KERNEL); 1634 - if (NULL == fmdev->rx.rds.buff) { 1635 - fmerr("Can't allocate rds ring buffer\n"); 1636 - goto rel_dev; 1637 - } 1638 - 1639 - ret = fm_v4l2_init_video_device(fmdev, radio_nr); 1640 - if (ret < 0) 1641 - goto rel_rdsbuf; 1642 - 1643 - fmdev->irq_info.handlers = int_handler_table; 1644 - fmdev->curr_fmmode = FM_MODE_OFF; 1645 - fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF; 1646 - fmdev->tx_data.preemph = FM_TX_PREEMPH_50US; 1647 - return ret; 1648 - 1649 - rel_rdsbuf: 1650 - kfree(fmdev->rx.rds.buff); 1651 - rel_dev: 1652 - kfree(fmdev); 1653 - 1654 - return ret; 1655 - } 1656 - 1657 - /* Module exit function. Ask FM V4L module to unregister video device */ 1658 - static void __exit fm_drv_exit(void) 1659 - { 1660 - struct fmdev *fmdev = NULL; 1661 - 1662 - fmdev = fm_v4l2_deinit_video_device(); 1663 - if (fmdev != NULL) { 1664 - kfree(fmdev->rx.rds.buff); 1665 - kfree(fmdev); 1666 - } 1667 - } 1668 - 1669 - module_init(fm_drv_init); 1670 - module_exit(fm_drv_exit); 1671 - 1672 - /* ------------- Module Info ------------- */ 1673 - MODULE_AUTHOR("Manjunatha Halli <manjunatha_halli@ti.com>"); 1674 - MODULE_DESCRIPTION("FM Driver for TI's Connectivity chip. " FM_DRV_VERSION); 1675 - MODULE_VERSION(FM_DRV_VERSION); 1676 - MODULE_LICENSE("GPL");
-389
drivers/media/radio/wl128x/fmdrv_common.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * FM Common module header file 5 - * 6 - * Copyright (C) 2011 Texas Instruments 7 - */ 8 - 9 - #ifndef _FMDRV_COMMON_H 10 - #define _FMDRV_COMMON_H 11 - 12 - #define FM_ST_REG_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */ 13 - #define FM_PKT_LOGICAL_CHAN_NUMBER 0x08 /* Logical channel 8 */ 14 - 15 - #define REG_RD 0x1 16 - #define REG_WR 0x0 17 - 18 - struct fm_reg_table { 19 - u8 opcode; 20 - u8 type; 21 - u8 *name; 22 - }; 23 - 24 - #define STEREO_GET 0 25 - #define RSSI_LVL_GET 1 26 - #define IF_COUNT_GET 2 27 - #define FLAG_GET 3 28 - #define RDS_SYNC_GET 4 29 - #define RDS_DATA_GET 5 30 - #define FREQ_SET 10 31 - #define AF_FREQ_SET 11 32 - #define MOST_MODE_SET 12 33 - #define MOST_BLEND_SET 13 34 - #define DEMPH_MODE_SET 14 35 - #define SEARCH_LVL_SET 15 36 - #define BAND_SET 16 37 - #define MUTE_STATUS_SET 17 38 - #define RDS_PAUSE_LVL_SET 18 39 - #define RDS_PAUSE_DUR_SET 19 40 - #define RDS_MEM_SET 20 41 - #define RDS_BLK_B_SET 21 42 - #define RDS_MSK_B_SET 22 43 - #define RDS_PI_MASK_SET 23 44 - #define RDS_PI_SET 24 45 - #define RDS_SYSTEM_SET 25 46 - #define INT_MASK_SET 26 47 - #define SEARCH_DIR_SET 27 48 - #define VOLUME_SET 28 49 - #define AUDIO_ENABLE_SET 29 50 - #define PCM_MODE_SET 30 51 - #define I2S_MODE_CONFIG_SET 31 52 - #define POWER_SET 32 53 - #define INTX_CONFIG_SET 33 54 - #define PULL_EN_SET 34 55 - #define HILO_SET 35 56 - #define SWITCH2FREF 36 57 - #define FREQ_DRIFT_REPORT 37 58 - 59 - #define PCE_GET 40 60 - #define FIRM_VER_GET 41 61 - #define ASIC_VER_GET 42 62 - #define ASIC_ID_GET 43 63 - #define MAN_ID_GET 44 64 - #define TUNER_MODE_SET 45 65 - #define STOP_SEARCH 46 66 - #define RDS_CNTRL_SET 47 67 - 68 - #define WRITE_HARDWARE_REG 100 69 - #define CODE_DOWNLOAD 101 70 - #define RESET 102 71 - 72 - #define FM_POWER_MODE 254 73 - #define FM_INTERRUPT 255 74 - 75 - /* Transmitter API */ 76 - 77 - #define CHANL_SET 55 78 - #define CHANL_BW_SET 56 79 - #define REF_SET 57 80 - #define POWER_ENB_SET 90 81 - #define POWER_ATT_SET 58 82 - #define POWER_LEV_SET 59 83 - #define AUDIO_DEV_SET 60 84 - #define PILOT_DEV_SET 61 85 - #define RDS_DEV_SET 62 86 - #define TX_BAND_SET 65 87 - #define PUPD_SET 91 88 - #define AUDIO_IO_SET 63 89 - #define PREMPH_SET 64 90 - #define MONO_SET 66 91 - #define MUTE 92 92 - #define MPX_LMT_ENABLE 67 93 - #define PI_SET 93 94 - #define ECC_SET 69 95 - #define PTY 70 96 - #define AF 71 97 - #define DISPLAY_MODE 74 98 - #define RDS_REP_SET 77 99 - #define RDS_CONFIG_DATA_SET 98 100 - #define RDS_DATA_SET 99 101 - #define RDS_DATA_ENB 94 102 - #define TA_SET 78 103 - #define TP_SET 79 104 - #define DI_SET 80 105 - #define MS_SET 81 106 - #define PS_SCROLL_SPEED 82 107 - #define TX_AUDIO_LEVEL_TEST 96 108 - #define TX_AUDIO_LEVEL_TEST_THRESHOLD 73 109 - #define TX_AUDIO_INPUT_LEVEL_RANGE_SET 54 110 - #define RX_ANTENNA_SELECT 87 111 - #define I2C_DEV_ADDR_SET 86 112 - #define REF_ERR_CALIB_PARAM_SET 88 113 - #define REF_ERR_CALIB_PERIODICITY_SET 89 114 - #define SOC_INT_TRIGGER 52 115 - #define SOC_AUDIO_PATH_SET 83 116 - #define SOC_PCMI_OVERRIDE 84 117 - #define SOC_I2S_OVERRIDE 85 118 - #define RSSI_BLOCK_SCAN_FREQ_SET 95 119 - #define RSSI_BLOCK_SCAN_START 97 120 - #define RSSI_BLOCK_SCAN_DATA_GET 5 121 - #define READ_FMANT_TUNE_VALUE 104 122 - 123 - /* SKB helpers */ 124 - struct fm_skb_cb { 125 - __u8 fm_op; 126 - struct completion *completion; 127 - }; 128 - 129 - #define fm_cb(skb) ((struct fm_skb_cb *)(skb->cb)) 130 - 131 - /* FM Channel-8 command message format */ 132 - struct fm_cmd_msg_hdr { 133 - __u8 hdr; /* Logical Channel-8 */ 134 - __u8 len; /* Number of bytes follows */ 135 - __u8 op; /* FM Opcode */ 136 - __u8 rd_wr; /* Read/Write command */ 137 - __u8 dlen; /* Length of payload */ 138 - } __attribute__ ((packed)); 139 - 140 - #define FM_CMD_MSG_HDR_SIZE 5 /* sizeof(struct fm_cmd_msg_hdr) */ 141 - 142 - /* FM Channel-8 event messgage format */ 143 - struct fm_event_msg_hdr { 144 - __u8 header; /* Logical Channel-8 */ 145 - __u8 len; /* Number of bytes follows */ 146 - __u8 status; /* Event status */ 147 - __u8 num_fm_hci_cmds; /* Number of pkts the host allowed to send */ 148 - __u8 op; /* FM Opcode */ 149 - __u8 rd_wr; /* Read/Write command */ 150 - __u8 dlen; /* Length of payload */ 151 - } __attribute__ ((packed)); 152 - 153 - #define FM_EVT_MSG_HDR_SIZE 7 /* sizeof(struct fm_event_msg_hdr) */ 154 - 155 - /* TI's magic number in firmware file */ 156 - #define FM_FW_FILE_HEADER_MAGIC 0x42535442 157 - 158 - #define FM_ENABLE 1 159 - #define FM_DISABLE 0 160 - 161 - /* FLAG_GET register bits */ 162 - #define FM_FR_EVENT BIT(0) 163 - #define FM_BL_EVENT BIT(1) 164 - #define FM_RDS_EVENT BIT(2) 165 - #define FM_BBLK_EVENT BIT(3) 166 - #define FM_LSYNC_EVENT BIT(4) 167 - #define FM_LEV_EVENT BIT(5) 168 - #define FM_IFFR_EVENT BIT(6) 169 - #define FM_PI_EVENT BIT(7) 170 - #define FM_PD_EVENT BIT(8) 171 - #define FM_STIC_EVENT BIT(9) 172 - #define FM_MAL_EVENT BIT(10) 173 - #define FM_POW_ENB_EVENT BIT(11) 174 - 175 - /* 176 - * Firmware files of FM. ASIC ID and ASIC version will be appened to this, 177 - * later. 178 - */ 179 - #define FM_FMC_FW_FILE_START ("fmc_ch8") 180 - #define FM_RX_FW_FILE_START ("fm_rx_ch8") 181 - #define FM_TX_FW_FILE_START ("fm_tx_ch8") 182 - 183 - #define FM_UNDEFINED_FREQ 0xFFFFFFFF 184 - 185 - /* Band types */ 186 - #define FM_BAND_EUROPE_US 0 187 - #define FM_BAND_JAPAN 1 188 - 189 - /* Seek directions */ 190 - #define FM_SEARCH_DIRECTION_DOWN 0 191 - #define FM_SEARCH_DIRECTION_UP 1 192 - 193 - /* Tunner modes */ 194 - #define FM_TUNER_STOP_SEARCH_MODE 0 195 - #define FM_TUNER_PRESET_MODE 1 196 - #define FM_TUNER_AUTONOMOUS_SEARCH_MODE 2 197 - #define FM_TUNER_AF_JUMP_MODE 3 198 - 199 - /* Min and Max volume */ 200 - #define FM_RX_VOLUME_MIN 0 201 - #define FM_RX_VOLUME_MAX 70 202 - 203 - /* Volume gain step */ 204 - #define FM_RX_VOLUME_GAIN_STEP 0x370 205 - 206 - /* Mute modes */ 207 - #define FM_MUTE_ON 0 208 - #define FM_MUTE_OFF 1 209 - #define FM_MUTE_ATTENUATE 2 210 - 211 - #define FM_RX_UNMUTE_MODE 0x00 212 - #define FM_RX_RF_DEP_MODE 0x01 213 - #define FM_RX_AC_MUTE_MODE 0x02 214 - #define FM_RX_HARD_MUTE_LEFT_MODE 0x04 215 - #define FM_RX_HARD_MUTE_RIGHT_MODE 0x08 216 - #define FM_RX_SOFT_MUTE_FORCE_MODE 0x10 217 - 218 - /* RF dependent mute mode */ 219 - #define FM_RX_RF_DEPENDENT_MUTE_ON 1 220 - #define FM_RX_RF_DEPENDENT_MUTE_OFF 0 221 - 222 - /* RSSI threshold min and max */ 223 - #define FM_RX_RSSI_THRESHOLD_MIN -128 224 - #define FM_RX_RSSI_THRESHOLD_MAX 127 225 - 226 - /* Stereo/Mono mode */ 227 - #define FM_STEREO_MODE 0 228 - #define FM_MONO_MODE 1 229 - #define FM_STEREO_SOFT_BLEND 1 230 - 231 - /* FM RX De-emphasis filter modes */ 232 - #define FM_RX_EMPHASIS_FILTER_50_USEC 0 233 - #define FM_RX_EMPHASIS_FILTER_75_USEC 1 234 - 235 - /* FM RDS modes */ 236 - #define FM_RDS_DISABLE 0 237 - #define FM_RDS_ENABLE 1 238 - 239 - #define FM_NO_PI_CODE 0 240 - 241 - /* FM and RX RDS block enable/disable */ 242 - #define FM_RX_PWR_SET_FM_ON_RDS_OFF 0x1 243 - #define FM_RX_PWR_SET_FM_AND_RDS_BLK_ON 0x3 244 - #define FM_RX_PWR_SET_FM_AND_RDS_BLK_OFF 0x0 245 - 246 - /* RX RDS */ 247 - #define FM_RX_RDS_FLUSH_FIFO 0x1 248 - #define FM_RX_RDS_FIFO_THRESHOLD 64 /* tuples */ 249 - #define FM_RDS_BLK_SIZE 3 /* 3 bytes */ 250 - 251 - /* RDS block types */ 252 - #define FM_RDS_BLOCK_A 0 253 - #define FM_RDS_BLOCK_B 1 254 - #define FM_RDS_BLOCK_C 2 255 - #define FM_RDS_BLOCK_Ctag 3 256 - #define FM_RDS_BLOCK_D 4 257 - #define FM_RDS_BLOCK_E 5 258 - 259 - #define FM_RDS_BLK_IDX_A 0 260 - #define FM_RDS_BLK_IDX_B 1 261 - #define FM_RDS_BLK_IDX_C 2 262 - #define FM_RDS_BLK_IDX_D 3 263 - #define FM_RDS_BLK_IDX_UNKNOWN 0xF0 264 - 265 - #define FM_RDS_STATUS_ERR_MASK 0x18 266 - 267 - /* 268 - * Represents an RDS group type & version. 269 - * There are 15 groups, each group has 2 versions: A and B. 270 - */ 271 - #define FM_RDS_GROUP_TYPE_MASK_0A BIT(0) 272 - #define FM_RDS_GROUP_TYPE_MASK_0B BIT(1) 273 - #define FM_RDS_GROUP_TYPE_MASK_1A BIT(2) 274 - #define FM_RDS_GROUP_TYPE_MASK_1B BIT(3) 275 - #define FM_RDS_GROUP_TYPE_MASK_2A BIT(4) 276 - #define FM_RDS_GROUP_TYPE_MASK_2B BIT(5) 277 - #define FM_RDS_GROUP_TYPE_MASK_3A BIT(6) 278 - #define FM_RDS_GROUP_TYPE_MASK_3B BIT(7) 279 - #define FM_RDS_GROUP_TYPE_MASK_4A BIT(8) 280 - #define FM_RDS_GROUP_TYPE_MASK_4B BIT(9) 281 - #define FM_RDS_GROUP_TYPE_MASK_5A BIT(10) 282 - #define FM_RDS_GROUP_TYPE_MASK_5B BIT(11) 283 - #define FM_RDS_GROUP_TYPE_MASK_6A BIT(12) 284 - #define FM_RDS_GROUP_TYPE_MASK_6B BIT(13) 285 - #define FM_RDS_GROUP_TYPE_MASK_7A BIT(14) 286 - #define FM_RDS_GROUP_TYPE_MASK_7B BIT(15) 287 - #define FM_RDS_GROUP_TYPE_MASK_8A BIT(16) 288 - #define FM_RDS_GROUP_TYPE_MASK_8B BIT(17) 289 - #define FM_RDS_GROUP_TYPE_MASK_9A BIT(18) 290 - #define FM_RDS_GROUP_TYPE_MASK_9B BIT(19) 291 - #define FM_RDS_GROUP_TYPE_MASK_10A BIT(20) 292 - #define FM_RDS_GROUP_TYPE_MASK_10B BIT(21) 293 - #define FM_RDS_GROUP_TYPE_MASK_11A BIT(22) 294 - #define FM_RDS_GROUP_TYPE_MASK_11B BIT(23) 295 - #define FM_RDS_GROUP_TYPE_MASK_12A BIT(24) 296 - #define FM_RDS_GROUP_TYPE_MASK_12B BIT(25) 297 - #define FM_RDS_GROUP_TYPE_MASK_13A BIT(26) 298 - #define FM_RDS_GROUP_TYPE_MASK_13B BIT(27) 299 - #define FM_RDS_GROUP_TYPE_MASK_14A BIT(28) 300 - #define FM_RDS_GROUP_TYPE_MASK_14B BIT(29) 301 - #define FM_RDS_GROUP_TYPE_MASK_15A BIT(30) 302 - #define FM_RDS_GROUP_TYPE_MASK_15B BIT(31) 303 - 304 - /* RX Alternate Frequency info */ 305 - #define FM_RDS_MIN_AF 1 306 - #define FM_RDS_MAX_AF 204 307 - #define FM_RDS_MAX_AF_JAPAN 140 308 - #define FM_RDS_1_AF_FOLLOWS 225 309 - #define FM_RDS_25_AF_FOLLOWS 249 310 - 311 - /* RDS system type (RDS/RBDS) */ 312 - #define FM_RDS_SYSTEM_RDS 0 313 - #define FM_RDS_SYSTEM_RBDS 1 314 - 315 - /* AF on/off */ 316 - #define FM_RX_RDS_AF_SWITCH_MODE_ON 1 317 - #define FM_RX_RDS_AF_SWITCH_MODE_OFF 0 318 - 319 - /* Retry count when interrupt process goes wrong */ 320 - #define FM_IRQ_TIMEOUT_RETRY_MAX 5 /* 5 times */ 321 - 322 - /* Audio IO set values */ 323 - #define FM_RX_AUDIO_ENABLE_I2S 0x01 324 - #define FM_RX_AUDIO_ENABLE_ANALOG 0x02 325 - #define FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG 0x03 326 - #define FM_RX_AUDIO_ENABLE_DISABLE 0x00 327 - 328 - /* HI/LO set values */ 329 - #define FM_RX_IFFREQ_TO_HI_SIDE 0x0 330 - #define FM_RX_IFFREQ_TO_LO_SIDE 0x1 331 - #define FM_RX_IFFREQ_HILO_AUTOMATIC 0x2 332 - 333 - /* 334 - * Default RX mode configuration. Chip will be configured 335 - * with this default values after loading RX firmware. 336 - */ 337 - #define FM_DEFAULT_RX_VOLUME 10 338 - #define FM_DEFAULT_RSSI_THRESHOLD 3 339 - 340 - /* Range for TX power level in units for dB/uV */ 341 - #define FM_PWR_LVL_LOW 91 342 - #define FM_PWR_LVL_HIGH 122 343 - 344 - /* Chip specific default TX power level value */ 345 - #define FM_PWR_LVL_DEF 4 346 - 347 - /* FM TX Pre-emphasis filter values */ 348 - #define FM_TX_PREEMPH_OFF 1 349 - #define FM_TX_PREEMPH_50US 0 350 - #define FM_TX_PREEMPH_75US 2 351 - 352 - /* FM TX antenna impedance values */ 353 - #define FM_TX_ANT_IMP_50 0 354 - #define FM_TX_ANT_IMP_200 1 355 - #define FM_TX_ANT_IMP_500 2 356 - 357 - /* Functions exported by FM common sub-module */ 358 - int fmc_prepare(struct fmdev *); 359 - int fmc_release(struct fmdev *); 360 - 361 - void fmc_update_region_info(struct fmdev *, u8); 362 - int fmc_send_cmd(struct fmdev *, u8, u16, 363 - void *, unsigned int, void *, int *); 364 - int fmc_is_rds_data_available(struct fmdev *, struct file *, 365 - struct poll_table_struct *); 366 - int fmc_transfer_rds_from_internal_buff(struct fmdev *, struct file *, 367 - u8 __user *, size_t); 368 - 369 - int fmc_set_freq(struct fmdev *, u32); 370 - int fmc_set_mode(struct fmdev *, u8); 371 - int fmc_set_region(struct fmdev *, u8); 372 - int fmc_set_mute_mode(struct fmdev *, u8); 373 - int fmc_set_stereo_mono(struct fmdev *, u16); 374 - int fmc_set_rds_mode(struct fmdev *, u8); 375 - 376 - int fmc_get_freq(struct fmdev *, u32 *); 377 - int fmc_get_region(struct fmdev *, u8 *); 378 - int fmc_get_mode(struct fmdev *, u8 *); 379 - 380 - /* 381 - * channel spacing 382 - */ 383 - #define FM_CHANNEL_SPACING_50KHZ 1 384 - #define FM_CHANNEL_SPACING_100KHZ 2 385 - #define FM_CHANNEL_SPACING_200KHZ 4 386 - #define FM_FREQ_MUL 50 387 - 388 - #endif 389 -
-820
drivers/media/radio/wl128x/fmdrv_rx.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * This sub-module of FM driver implements FM RX functionality. 5 - * 6 - * Copyright (C) 2011 Texas Instruments 7 - * Author: Raja Mani <raja_mani@ti.com> 8 - * Author: Manjunatha Halli <manjunatha_halli@ti.com> 9 - */ 10 - 11 - #include "fmdrv.h" 12 - #include "fmdrv_common.h" 13 - #include "fmdrv_rx.h" 14 - 15 - void fm_rx_reset_rds_cache(struct fmdev *fmdev) 16 - { 17 - fmdev->rx.rds.flag = FM_RDS_DISABLE; 18 - fmdev->rx.rds.last_blk_idx = 0; 19 - fmdev->rx.rds.wr_idx = 0; 20 - fmdev->rx.rds.rd_idx = 0; 21 - 22 - if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) 23 - fmdev->irq_info.mask |= FM_LEV_EVENT; 24 - } 25 - 26 - void fm_rx_reset_station_info(struct fmdev *fmdev) 27 - { 28 - fmdev->rx.stat_info.picode = FM_NO_PI_CODE; 29 - fmdev->rx.stat_info.afcache_size = 0; 30 - fmdev->rx.stat_info.af_list_max = 0; 31 - } 32 - 33 - int fm_rx_set_freq(struct fmdev *fmdev, u32 freq) 34 - { 35 - unsigned long timeleft; 36 - u16 payload, curr_frq, intr_flag; 37 - u32 curr_frq_in_khz; 38 - u32 resp_len; 39 - int ret; 40 - 41 - if (freq < fmdev->rx.region.bot_freq || freq > fmdev->rx.region.top_freq) { 42 - fmerr("Invalid frequency %d\n", freq); 43 - return -EINVAL; 44 - } 45 - 46 - /* Set audio enable */ 47 - payload = FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG; 48 - 49 - ret = fmc_send_cmd(fmdev, AUDIO_ENABLE_SET, REG_WR, &payload, 50 - sizeof(payload), NULL, NULL); 51 - if (ret < 0) 52 - return ret; 53 - 54 - /* Set hilo to automatic selection */ 55 - payload = FM_RX_IFFREQ_HILO_AUTOMATIC; 56 - ret = fmc_send_cmd(fmdev, HILO_SET, REG_WR, &payload, 57 - sizeof(payload), NULL, NULL); 58 - if (ret < 0) 59 - return ret; 60 - 61 - /* Calculate frequency index and set*/ 62 - payload = (freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL; 63 - 64 - ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload, 65 - sizeof(payload), NULL, NULL); 66 - if (ret < 0) 67 - return ret; 68 - 69 - /* Read flags - just to clear any pending interrupts if we had */ 70 - ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL); 71 - if (ret < 0) 72 - return ret; 73 - 74 - /* Enable FR, BL interrupts */ 75 - intr_flag = fmdev->irq_info.mask; 76 - fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT); 77 - payload = fmdev->irq_info.mask; 78 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 79 - sizeof(payload), NULL, NULL); 80 - if (ret < 0) 81 - return ret; 82 - 83 - /* Start tune */ 84 - payload = FM_TUNER_PRESET_MODE; 85 - ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload, 86 - sizeof(payload), NULL, NULL); 87 - if (ret < 0) 88 - goto exit; 89 - 90 - /* Wait for tune ended interrupt */ 91 - init_completion(&fmdev->maintask_comp); 92 - timeleft = wait_for_completion_timeout(&fmdev->maintask_comp, 93 - FM_DRV_TX_TIMEOUT); 94 - if (!timeleft) { 95 - fmerr("Timeout(%d sec),didn't get tune ended int\n", 96 - jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); 97 - ret = -ETIMEDOUT; 98 - goto exit; 99 - } 100 - 101 - /* Read freq back to confirm */ 102 - ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2, &curr_frq, &resp_len); 103 - if (ret < 0) 104 - goto exit; 105 - 106 - curr_frq = be16_to_cpu((__force __be16)curr_frq); 107 - curr_frq_in_khz = (fmdev->rx.region.bot_freq + ((u32)curr_frq * FM_FREQ_MUL)); 108 - 109 - if (curr_frq_in_khz != freq) { 110 - pr_info("Frequency is set to (%d) but requested freq is (%d)\n", 111 - curr_frq_in_khz, freq); 112 - } 113 - 114 - /* Update local cache */ 115 - fmdev->rx.freq = curr_frq_in_khz; 116 - exit: 117 - /* Re-enable default FM interrupts */ 118 - fmdev->irq_info.mask = intr_flag; 119 - payload = fmdev->irq_info.mask; 120 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 121 - sizeof(payload), NULL, NULL); 122 - if (ret < 0) 123 - return ret; 124 - 125 - /* Reset RDS cache and current station pointers */ 126 - fm_rx_reset_rds_cache(fmdev); 127 - fm_rx_reset_station_info(fmdev); 128 - 129 - return ret; 130 - } 131 - 132 - static int fm_rx_set_channel_spacing(struct fmdev *fmdev, u32 spacing) 133 - { 134 - u16 payload; 135 - int ret; 136 - 137 - if (spacing > 0 && spacing <= 50000) 138 - spacing = FM_CHANNEL_SPACING_50KHZ; 139 - else if (spacing > 50000 && spacing <= 100000) 140 - spacing = FM_CHANNEL_SPACING_100KHZ; 141 - else 142 - spacing = FM_CHANNEL_SPACING_200KHZ; 143 - 144 - /* set channel spacing */ 145 - payload = spacing; 146 - ret = fmc_send_cmd(fmdev, CHANL_BW_SET, REG_WR, &payload, 147 - sizeof(payload), NULL, NULL); 148 - if (ret < 0) 149 - return ret; 150 - 151 - fmdev->rx.region.chanl_space = spacing * FM_FREQ_MUL; 152 - 153 - return ret; 154 - } 155 - 156 - int fm_rx_seek(struct fmdev *fmdev, u32 seek_upward, 157 - u32 wrap_around, u32 spacing) 158 - { 159 - u32 resp_len; 160 - u16 curr_frq, next_frq, last_frq; 161 - u16 payload, int_reason, intr_flag; 162 - u16 offset, space_idx; 163 - unsigned long timeleft; 164 - int ret; 165 - 166 - /* Set channel spacing */ 167 - ret = fm_rx_set_channel_spacing(fmdev, spacing); 168 - if (ret < 0) { 169 - fmerr("Failed to set channel spacing\n"); 170 - return ret; 171 - } 172 - 173 - /* Read the current frequency from chip */ 174 - ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 175 - sizeof(curr_frq), &curr_frq, &resp_len); 176 - if (ret < 0) 177 - return ret; 178 - 179 - curr_frq = be16_to_cpu((__force __be16)curr_frq); 180 - last_frq = (fmdev->rx.region.top_freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL; 181 - 182 - /* Check the offset in order to be aligned to the channel spacing*/ 183 - space_idx = fmdev->rx.region.chanl_space / FM_FREQ_MUL; 184 - offset = curr_frq % space_idx; 185 - 186 - next_frq = seek_upward ? curr_frq + space_idx /* Seek Up */ : 187 - curr_frq - space_idx /* Seek Down */ ; 188 - 189 - /* 190 - * Add or subtract offset in order to stay aligned to the channel 191 - * spacing. 192 - */ 193 - if ((short)next_frq < 0) 194 - next_frq = last_frq - offset; 195 - else if (next_frq > last_frq) 196 - next_frq = 0 + offset; 197 - 198 - again: 199 - /* Set calculated next frequency to perform seek */ 200 - payload = next_frq; 201 - ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload, 202 - sizeof(payload), NULL, NULL); 203 - if (ret < 0) 204 - return ret; 205 - 206 - /* Set search direction (0:Seek Down, 1:Seek Up) */ 207 - payload = (seek_upward ? FM_SEARCH_DIRECTION_UP : FM_SEARCH_DIRECTION_DOWN); 208 - ret = fmc_send_cmd(fmdev, SEARCH_DIR_SET, REG_WR, &payload, 209 - sizeof(payload), NULL, NULL); 210 - if (ret < 0) 211 - return ret; 212 - 213 - /* Read flags - just to clear any pending interrupts if we had */ 214 - ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL); 215 - if (ret < 0) 216 - return ret; 217 - 218 - /* Enable FR, BL interrupts */ 219 - intr_flag = fmdev->irq_info.mask; 220 - fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT); 221 - payload = fmdev->irq_info.mask; 222 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 223 - sizeof(payload), NULL, NULL); 224 - if (ret < 0) 225 - return ret; 226 - 227 - /* Start seek */ 228 - payload = FM_TUNER_AUTONOMOUS_SEARCH_MODE; 229 - ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload, 230 - sizeof(payload), NULL, NULL); 231 - if (ret < 0) 232 - return ret; 233 - 234 - /* Wait for tune ended/band limit reached interrupt */ 235 - init_completion(&fmdev->maintask_comp); 236 - timeleft = wait_for_completion_timeout(&fmdev->maintask_comp, 237 - FM_DRV_RX_SEEK_TIMEOUT); 238 - if (!timeleft) { 239 - fmerr("Timeout(%d sec),didn't get tune ended int\n", 240 - jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000); 241 - return -ENODATA; 242 - } 243 - 244 - int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT); 245 - 246 - /* Re-enable default FM interrupts */ 247 - fmdev->irq_info.mask = intr_flag; 248 - payload = fmdev->irq_info.mask; 249 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 250 - sizeof(payload), NULL, NULL); 251 - if (ret < 0) 252 - return ret; 253 - 254 - if (int_reason & FM_BL_EVENT) { 255 - if (wrap_around == 0) { 256 - fmdev->rx.freq = seek_upward ? 257 - fmdev->rx.region.top_freq : 258 - fmdev->rx.region.bot_freq; 259 - } else { 260 - fmdev->rx.freq = seek_upward ? 261 - fmdev->rx.region.bot_freq : 262 - fmdev->rx.region.top_freq; 263 - /* Calculate frequency index to write */ 264 - next_frq = (fmdev->rx.freq - 265 - fmdev->rx.region.bot_freq) / FM_FREQ_MUL; 266 - goto again; 267 - } 268 - } else { 269 - /* Read freq to know where operation tune operation stopped */ 270 - ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2, 271 - &curr_frq, &resp_len); 272 - if (ret < 0) 273 - return ret; 274 - 275 - curr_frq = be16_to_cpu((__force __be16)curr_frq); 276 - fmdev->rx.freq = (fmdev->rx.region.bot_freq + 277 - ((u32)curr_frq * FM_FREQ_MUL)); 278 - 279 - } 280 - /* Reset RDS cache and current station pointers */ 281 - fm_rx_reset_rds_cache(fmdev); 282 - fm_rx_reset_station_info(fmdev); 283 - 284 - return ret; 285 - } 286 - 287 - int fm_rx_set_volume(struct fmdev *fmdev, u16 vol_to_set) 288 - { 289 - u16 payload; 290 - int ret; 291 - 292 - if (fmdev->curr_fmmode != FM_MODE_RX) 293 - return -EPERM; 294 - 295 - if (vol_to_set > FM_RX_VOLUME_MAX) { 296 - fmerr("Volume is not within(%d-%d) range\n", 297 - FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX); 298 - return -EINVAL; 299 - } 300 - vol_to_set *= FM_RX_VOLUME_GAIN_STEP; 301 - 302 - payload = vol_to_set; 303 - ret = fmc_send_cmd(fmdev, VOLUME_SET, REG_WR, &payload, 304 - sizeof(payload), NULL, NULL); 305 - if (ret < 0) 306 - return ret; 307 - 308 - fmdev->rx.volume = vol_to_set; 309 - return ret; 310 - } 311 - 312 - /* Get volume */ 313 - int fm_rx_get_volume(struct fmdev *fmdev, u16 *curr_vol) 314 - { 315 - if (fmdev->curr_fmmode != FM_MODE_RX) 316 - return -EPERM; 317 - 318 - if (curr_vol == NULL) { 319 - fmerr("Invalid memory\n"); 320 - return -ENOMEM; 321 - } 322 - 323 - *curr_vol = fmdev->rx.volume / FM_RX_VOLUME_GAIN_STEP; 324 - 325 - return 0; 326 - } 327 - 328 - /* To get current band's bottom and top frequency */ 329 - int fm_rx_get_band_freq_range(struct fmdev *fmdev, u32 *bot_freq, u32 *top_freq) 330 - { 331 - if (bot_freq != NULL) 332 - *bot_freq = fmdev->rx.region.bot_freq; 333 - 334 - if (top_freq != NULL) 335 - *top_freq = fmdev->rx.region.top_freq; 336 - 337 - return 0; 338 - } 339 - 340 - /* Returns current band index (0-Europe/US; 1-Japan) */ 341 - void fm_rx_get_region(struct fmdev *fmdev, u8 *region) 342 - { 343 - *region = fmdev->rx.region.fm_band; 344 - } 345 - 346 - /* Sets band (0-Europe/US; 1-Japan) */ 347 - int fm_rx_set_region(struct fmdev *fmdev, u8 region_to_set) 348 - { 349 - u16 payload; 350 - u32 new_frq = 0; 351 - int ret; 352 - 353 - if (region_to_set != FM_BAND_EUROPE_US && 354 - region_to_set != FM_BAND_JAPAN) { 355 - fmerr("Invalid band\n"); 356 - return -EINVAL; 357 - } 358 - 359 - if (fmdev->rx.region.fm_band == region_to_set) { 360 - fmerr("Requested band is already configured\n"); 361 - return 0; 362 - } 363 - 364 - /* Send cmd to set the band */ 365 - payload = (u16)region_to_set; 366 - ret = fmc_send_cmd(fmdev, BAND_SET, REG_WR, &payload, 367 - sizeof(payload), NULL, NULL); 368 - if (ret < 0) 369 - return ret; 370 - 371 - fmc_update_region_info(fmdev, region_to_set); 372 - 373 - /* Check whether current RX frequency is within band boundary */ 374 - if (fmdev->rx.freq < fmdev->rx.region.bot_freq) 375 - new_frq = fmdev->rx.region.bot_freq; 376 - else if (fmdev->rx.freq > fmdev->rx.region.top_freq) 377 - new_frq = fmdev->rx.region.top_freq; 378 - 379 - if (new_frq) { 380 - fmdbg("Current freq is not within band limit boundary,switching to %d KHz\n", 381 - new_frq); 382 - /* Current RX frequency is not in range. So, update it */ 383 - ret = fm_rx_set_freq(fmdev, new_frq); 384 - } 385 - 386 - return ret; 387 - } 388 - 389 - /* Reads current mute mode (Mute Off/On/Attenuate)*/ 390 - int fm_rx_get_mute_mode(struct fmdev *fmdev, u8 *curr_mute_mode) 391 - { 392 - if (fmdev->curr_fmmode != FM_MODE_RX) 393 - return -EPERM; 394 - 395 - if (curr_mute_mode == NULL) { 396 - fmerr("Invalid memory\n"); 397 - return -ENOMEM; 398 - } 399 - 400 - *curr_mute_mode = fmdev->rx.mute_mode; 401 - 402 - return 0; 403 - } 404 - 405 - static int fm_config_rx_mute_reg(struct fmdev *fmdev) 406 - { 407 - u16 payload, muteval; 408 - int ret; 409 - 410 - muteval = 0; 411 - switch (fmdev->rx.mute_mode) { 412 - case FM_MUTE_ON: 413 - muteval = FM_RX_AC_MUTE_MODE; 414 - break; 415 - 416 - case FM_MUTE_OFF: 417 - muteval = FM_RX_UNMUTE_MODE; 418 - break; 419 - 420 - case FM_MUTE_ATTENUATE: 421 - muteval = FM_RX_SOFT_MUTE_FORCE_MODE; 422 - break; 423 - } 424 - if (fmdev->rx.rf_depend_mute == FM_RX_RF_DEPENDENT_MUTE_ON) 425 - muteval |= FM_RX_RF_DEP_MODE; 426 - else 427 - muteval &= ~FM_RX_RF_DEP_MODE; 428 - 429 - payload = muteval; 430 - ret = fmc_send_cmd(fmdev, MUTE_STATUS_SET, REG_WR, &payload, 431 - sizeof(payload), NULL, NULL); 432 - if (ret < 0) 433 - return ret; 434 - 435 - return 0; 436 - } 437 - 438 - /* Configures mute mode (Mute Off/On/Attenuate) */ 439 - int fm_rx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset) 440 - { 441 - u8 org_state; 442 - int ret; 443 - 444 - if (fmdev->rx.mute_mode == mute_mode_toset) 445 - return 0; 446 - 447 - org_state = fmdev->rx.mute_mode; 448 - fmdev->rx.mute_mode = mute_mode_toset; 449 - 450 - ret = fm_config_rx_mute_reg(fmdev); 451 - if (ret < 0) { 452 - fmdev->rx.mute_mode = org_state; 453 - return ret; 454 - } 455 - 456 - return 0; 457 - } 458 - 459 - /* Gets RF dependent soft mute mode enable/disable status */ 460 - int fm_rx_get_rfdepend_softmute(struct fmdev *fmdev, u8 *curr_mute_mode) 461 - { 462 - if (fmdev->curr_fmmode != FM_MODE_RX) 463 - return -EPERM; 464 - 465 - if (curr_mute_mode == NULL) { 466 - fmerr("Invalid memory\n"); 467 - return -ENOMEM; 468 - } 469 - 470 - *curr_mute_mode = fmdev->rx.rf_depend_mute; 471 - 472 - return 0; 473 - } 474 - 475 - /* Sets RF dependent soft mute mode */ 476 - int fm_rx_set_rfdepend_softmute(struct fmdev *fmdev, u8 rfdepend_mute) 477 - { 478 - u8 org_state; 479 - int ret; 480 - 481 - if (fmdev->curr_fmmode != FM_MODE_RX) 482 - return -EPERM; 483 - 484 - if (rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_ON && 485 - rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_OFF) { 486 - fmerr("Invalid RF dependent soft mute\n"); 487 - return -EINVAL; 488 - } 489 - if (fmdev->rx.rf_depend_mute == rfdepend_mute) 490 - return 0; 491 - 492 - org_state = fmdev->rx.rf_depend_mute; 493 - fmdev->rx.rf_depend_mute = rfdepend_mute; 494 - 495 - ret = fm_config_rx_mute_reg(fmdev); 496 - if (ret < 0) { 497 - fmdev->rx.rf_depend_mute = org_state; 498 - return ret; 499 - } 500 - 501 - return 0; 502 - } 503 - 504 - /* Returns the signal strength level of current channel */ 505 - int fm_rx_get_rssi_level(struct fmdev *fmdev, u16 *rssilvl) 506 - { 507 - __be16 curr_rssi_lel; 508 - u32 resp_len; 509 - int ret; 510 - 511 - if (rssilvl == NULL) { 512 - fmerr("Invalid memory\n"); 513 - return -ENOMEM; 514 - } 515 - /* Read current RSSI level */ 516 - ret = fmc_send_cmd(fmdev, RSSI_LVL_GET, REG_RD, NULL, 2, 517 - &curr_rssi_lel, &resp_len); 518 - if (ret < 0) 519 - return ret; 520 - 521 - *rssilvl = be16_to_cpu(curr_rssi_lel); 522 - 523 - return 0; 524 - } 525 - 526 - /* 527 - * Sets the signal strength level that once reached 528 - * will stop the auto search process 529 - */ 530 - int fm_rx_set_rssi_threshold(struct fmdev *fmdev, short rssi_lvl_toset) 531 - { 532 - u16 payload; 533 - int ret; 534 - 535 - if (rssi_lvl_toset < FM_RX_RSSI_THRESHOLD_MIN || 536 - rssi_lvl_toset > FM_RX_RSSI_THRESHOLD_MAX) { 537 - fmerr("Invalid RSSI threshold level\n"); 538 - return -EINVAL; 539 - } 540 - payload = (u16)rssi_lvl_toset; 541 - ret = fmc_send_cmd(fmdev, SEARCH_LVL_SET, REG_WR, &payload, 542 - sizeof(payload), NULL, NULL); 543 - if (ret < 0) 544 - return ret; 545 - 546 - fmdev->rx.rssi_threshold = rssi_lvl_toset; 547 - 548 - return 0; 549 - } 550 - 551 - /* Returns current RX RSSI threshold value */ 552 - int fm_rx_get_rssi_threshold(struct fmdev *fmdev, short *curr_rssi_lvl) 553 - { 554 - if (fmdev->curr_fmmode != FM_MODE_RX) 555 - return -EPERM; 556 - 557 - if (curr_rssi_lvl == NULL) { 558 - fmerr("Invalid memory\n"); 559 - return -ENOMEM; 560 - } 561 - 562 - *curr_rssi_lvl = fmdev->rx.rssi_threshold; 563 - 564 - return 0; 565 - } 566 - 567 - /* Sets RX stereo/mono modes */ 568 - int fm_rx_set_stereo_mono(struct fmdev *fmdev, u16 mode) 569 - { 570 - u16 payload; 571 - int ret; 572 - 573 - if (mode != FM_STEREO_MODE && mode != FM_MONO_MODE) { 574 - fmerr("Invalid mode\n"); 575 - return -EINVAL; 576 - } 577 - 578 - /* Set stereo/mono mode */ 579 - payload = (u16)mode; 580 - ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_WR, &payload, 581 - sizeof(payload), NULL, NULL); 582 - if (ret < 0) 583 - return ret; 584 - 585 - /* Set stereo blending mode */ 586 - payload = FM_STEREO_SOFT_BLEND; 587 - ret = fmc_send_cmd(fmdev, MOST_BLEND_SET, REG_WR, &payload, 588 - sizeof(payload), NULL, NULL); 589 - if (ret < 0) 590 - return ret; 591 - 592 - return 0; 593 - } 594 - 595 - /* Gets current RX stereo/mono mode */ 596 - int fm_rx_get_stereo_mono(struct fmdev *fmdev, u16 *mode) 597 - { 598 - __be16 curr_mode; 599 - u32 resp_len; 600 - int ret; 601 - 602 - if (mode == NULL) { 603 - fmerr("Invalid memory\n"); 604 - return -ENOMEM; 605 - } 606 - 607 - ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_RD, NULL, 2, 608 - &curr_mode, &resp_len); 609 - if (ret < 0) 610 - return ret; 611 - 612 - *mode = be16_to_cpu(curr_mode); 613 - 614 - return 0; 615 - } 616 - 617 - /* Choose RX de-emphasis filter mode (50us/75us) */ 618 - int fm_rx_set_deemphasis_mode(struct fmdev *fmdev, u16 mode) 619 - { 620 - u16 payload; 621 - int ret; 622 - 623 - if (fmdev->curr_fmmode != FM_MODE_RX) 624 - return -EPERM; 625 - 626 - if (mode != FM_RX_EMPHASIS_FILTER_50_USEC && 627 - mode != FM_RX_EMPHASIS_FILTER_75_USEC) { 628 - fmerr("Invalid rx de-emphasis mode (%d)\n", mode); 629 - return -EINVAL; 630 - } 631 - 632 - payload = mode; 633 - ret = fmc_send_cmd(fmdev, DEMPH_MODE_SET, REG_WR, &payload, 634 - sizeof(payload), NULL, NULL); 635 - if (ret < 0) 636 - return ret; 637 - 638 - fmdev->rx.deemphasis_mode = mode; 639 - 640 - return 0; 641 - } 642 - 643 - /* Gets current RX de-emphasis filter mode */ 644 - int fm_rx_get_deemph_mode(struct fmdev *fmdev, u16 *curr_deemphasis_mode) 645 - { 646 - if (fmdev->curr_fmmode != FM_MODE_RX) 647 - return -EPERM; 648 - 649 - if (curr_deemphasis_mode == NULL) { 650 - fmerr("Invalid memory\n"); 651 - return -ENOMEM; 652 - } 653 - 654 - *curr_deemphasis_mode = fmdev->rx.deemphasis_mode; 655 - 656 - return 0; 657 - } 658 - 659 - /* Enable/Disable RX RDS */ 660 - int fm_rx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis) 661 - { 662 - u16 payload; 663 - int ret; 664 - 665 - if (rds_en_dis != FM_RDS_ENABLE && rds_en_dis != FM_RDS_DISABLE) { 666 - fmerr("Invalid rds option\n"); 667 - return -EINVAL; 668 - } 669 - 670 - if (rds_en_dis == FM_RDS_ENABLE 671 - && fmdev->rx.rds.flag == FM_RDS_DISABLE) { 672 - /* Turn on RX RDS and RDS circuit */ 673 - payload = FM_RX_PWR_SET_FM_AND_RDS_BLK_ON; 674 - ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload, 675 - sizeof(payload), NULL, NULL); 676 - if (ret < 0) 677 - return ret; 678 - 679 - /* Clear and reset RDS FIFO */ 680 - payload = FM_RX_RDS_FLUSH_FIFO; 681 - ret = fmc_send_cmd(fmdev, RDS_CNTRL_SET, REG_WR, &payload, 682 - sizeof(payload), NULL, NULL); 683 - if (ret < 0) 684 - return ret; 685 - 686 - /* Read flags - just to clear any pending interrupts. */ 687 - ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, 688 - NULL, NULL); 689 - if (ret < 0) 690 - return ret; 691 - 692 - /* Set RDS FIFO threshold value */ 693 - payload = FM_RX_RDS_FIFO_THRESHOLD; 694 - ret = fmc_send_cmd(fmdev, RDS_MEM_SET, REG_WR, &payload, 695 - sizeof(payload), NULL, NULL); 696 - if (ret < 0) 697 - return ret; 698 - 699 - /* Enable RDS interrupt */ 700 - fmdev->irq_info.mask |= FM_RDS_EVENT; 701 - payload = fmdev->irq_info.mask; 702 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 703 - sizeof(payload), NULL, NULL); 704 - if (ret < 0) { 705 - fmdev->irq_info.mask &= ~FM_RDS_EVENT; 706 - return ret; 707 - } 708 - 709 - /* Update our local flag */ 710 - fmdev->rx.rds.flag = FM_RDS_ENABLE; 711 - } else if (rds_en_dis == FM_RDS_DISABLE 712 - && fmdev->rx.rds.flag == FM_RDS_ENABLE) { 713 - /* Turn off RX RDS */ 714 - payload = FM_RX_PWR_SET_FM_ON_RDS_OFF; 715 - ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload, 716 - sizeof(payload), NULL, NULL); 717 - if (ret < 0) 718 - return ret; 719 - 720 - /* Reset RDS pointers */ 721 - fmdev->rx.rds.last_blk_idx = 0; 722 - fmdev->rx.rds.wr_idx = 0; 723 - fmdev->rx.rds.rd_idx = 0; 724 - fm_rx_reset_station_info(fmdev); 725 - 726 - /* Update RDS local cache */ 727 - fmdev->irq_info.mask &= ~(FM_RDS_EVENT); 728 - fmdev->rx.rds.flag = FM_RDS_DISABLE; 729 - } 730 - 731 - return 0; 732 - } 733 - 734 - /* Returns current RX RDS enable/disable status */ 735 - int fm_rx_get_rds_mode(struct fmdev *fmdev, u8 *curr_rds_en_dis) 736 - { 737 - if (fmdev->curr_fmmode != FM_MODE_RX) 738 - return -EPERM; 739 - 740 - if (curr_rds_en_dis == NULL) { 741 - fmerr("Invalid memory\n"); 742 - return -ENOMEM; 743 - } 744 - 745 - *curr_rds_en_dis = fmdev->rx.rds.flag; 746 - 747 - return 0; 748 - } 749 - 750 - /* Sets RDS operation mode (RDS/RDBS) */ 751 - int fm_rx_set_rds_system(struct fmdev *fmdev, u8 rds_mode) 752 - { 753 - u16 payload; 754 - int ret; 755 - 756 - if (fmdev->curr_fmmode != FM_MODE_RX) 757 - return -EPERM; 758 - 759 - if (rds_mode != FM_RDS_SYSTEM_RDS && rds_mode != FM_RDS_SYSTEM_RBDS) { 760 - fmerr("Invalid rds mode\n"); 761 - return -EINVAL; 762 - } 763 - /* Set RDS operation mode */ 764 - payload = (u16)rds_mode; 765 - ret = fmc_send_cmd(fmdev, RDS_SYSTEM_SET, REG_WR, &payload, 766 - sizeof(payload), NULL, NULL); 767 - if (ret < 0) 768 - return ret; 769 - 770 - fmdev->rx.rds_mode = rds_mode; 771 - 772 - return 0; 773 - } 774 - 775 - /* Configures Alternate Frequency switch mode */ 776 - int fm_rx_set_af_switch(struct fmdev *fmdev, u8 af_mode) 777 - { 778 - u16 payload; 779 - int ret; 780 - 781 - if (fmdev->curr_fmmode != FM_MODE_RX) 782 - return -EPERM; 783 - 784 - if (af_mode != FM_RX_RDS_AF_SWITCH_MODE_ON && 785 - af_mode != FM_RX_RDS_AF_SWITCH_MODE_OFF) { 786 - fmerr("Invalid af mode\n"); 787 - return -EINVAL; 788 - } 789 - /* Enable/disable low RSSI interrupt based on af_mode */ 790 - if (af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) 791 - fmdev->irq_info.mask |= FM_LEV_EVENT; 792 - else 793 - fmdev->irq_info.mask &= ~FM_LEV_EVENT; 794 - 795 - payload = fmdev->irq_info.mask; 796 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 797 - sizeof(payload), NULL, NULL); 798 - if (ret < 0) 799 - return ret; 800 - 801 - fmdev->rx.af_mode = af_mode; 802 - 803 - return 0; 804 - } 805 - 806 - /* Returns Alternate Frequency switch status */ 807 - int fm_rx_get_af_switch(struct fmdev *fmdev, u8 *af_mode) 808 - { 809 - if (fmdev->curr_fmmode != FM_MODE_RX) 810 - return -EPERM; 811 - 812 - if (af_mode == NULL) { 813 - fmerr("Invalid memory\n"); 814 - return -ENOMEM; 815 - } 816 - 817 - *af_mode = fmdev->rx.af_mode; 818 - 819 - return 0; 820 - }
-45
drivers/media/radio/wl128x/fmdrv_rx.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * FM RX module header. 5 - * 6 - * Copyright (C) 2011 Texas Instruments 7 - */ 8 - 9 - #ifndef _FMDRV_RX_H 10 - #define _FMDRV_RX_H 11 - 12 - int fm_rx_set_freq(struct fmdev *, u32); 13 - int fm_rx_set_mute_mode(struct fmdev *, u8); 14 - int fm_rx_set_stereo_mono(struct fmdev *, u16); 15 - int fm_rx_set_rds_mode(struct fmdev *, u8); 16 - int fm_rx_set_rds_system(struct fmdev *, u8); 17 - int fm_rx_set_volume(struct fmdev *, u16); 18 - int fm_rx_set_rssi_threshold(struct fmdev *, short); 19 - int fm_rx_set_region(struct fmdev *, u8); 20 - int fm_rx_set_rfdepend_softmute(struct fmdev *, u8); 21 - int fm_rx_set_deemphasis_mode(struct fmdev *, u16); 22 - int fm_rx_set_af_switch(struct fmdev *, u8); 23 - 24 - void fm_rx_reset_rds_cache(struct fmdev *); 25 - void fm_rx_reset_station_info(struct fmdev *); 26 - 27 - int fm_rx_seek(struct fmdev *, u32, u32, u32); 28 - 29 - int fm_rx_get_rds_mode(struct fmdev *, u8 *); 30 - int fm_rx_get_mute_mode(struct fmdev *, u8 *); 31 - int fm_rx_get_volume(struct fmdev *, u16 *); 32 - int fm_rx_get_band_freq_range(struct fmdev *, 33 - u32 *, u32 *); 34 - int fm_rx_get_stereo_mono(struct fmdev *, u16 *); 35 - int fm_rx_get_rssi_level(struct fmdev *, u16 *); 36 - int fm_rx_get_rssi_threshold(struct fmdev *, short *); 37 - int fm_rx_get_rfdepend_softmute(struct fmdev *, u8 *); 38 - int fm_rx_get_deemph_mode(struct fmdev *, u16 *); 39 - int fm_rx_get_af_switch(struct fmdev *, u8 *); 40 - void fm_rx_get_region(struct fmdev *, u8 *); 41 - 42 - int fm_rx_set_chanl_spacing(struct fmdev *, u8); 43 - int fm_rx_get_chanl_spacing(struct fmdev *, u8 *); 44 - #endif 45 -
-413
drivers/media/radio/wl128x/fmdrv_tx.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * This sub-module of FM driver implements FM TX functionality. 5 - * 6 - * Copyright (C) 2011 Texas Instruments 7 - */ 8 - 9 - #include <linux/delay.h> 10 - #include "fmdrv.h" 11 - #include "fmdrv_common.h" 12 - #include "fmdrv_tx.h" 13 - 14 - int fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode) 15 - { 16 - u16 payload; 17 - int ret; 18 - 19 - if (fmdev->tx_data.aud_mode == mode) 20 - return 0; 21 - 22 - fmdbg("stereo mode: %d\n", mode); 23 - 24 - /* Set Stereo/Mono mode */ 25 - payload = (1 - mode); 26 - ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload, 27 - sizeof(payload), NULL, NULL); 28 - if (ret < 0) 29 - return ret; 30 - 31 - fmdev->tx_data.aud_mode = mode; 32 - 33 - return ret; 34 - } 35 - 36 - static int set_rds_text(struct fmdev *fmdev, u8 *rds_text) 37 - { 38 - u16 payload; 39 - int ret; 40 - 41 - ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text, 42 - strlen(rds_text), NULL, NULL); 43 - if (ret < 0) 44 - return ret; 45 - 46 - /* Scroll mode */ 47 - payload = (u16)0x1; 48 - ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload, 49 - sizeof(payload), NULL, NULL); 50 - if (ret < 0) 51 - return ret; 52 - 53 - return 0; 54 - } 55 - 56 - static int set_rds_data_mode(struct fmdev *fmdev, u8 mode) 57 - { 58 - u16 payload; 59 - int ret; 60 - 61 - /* Setting unique PI TODO: how unique? */ 62 - payload = (u16)0xcafe; 63 - ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload, 64 - sizeof(payload), NULL, NULL); 65 - if (ret < 0) 66 - return ret; 67 - 68 - /* Set decoder id */ 69 - payload = (u16)0xa; 70 - ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload, 71 - sizeof(payload), NULL, NULL); 72 - if (ret < 0) 73 - return ret; 74 - 75 - /* TODO: RDS_MODE_GET? */ 76 - return 0; 77 - } 78 - 79 - static int set_rds_len(struct fmdev *fmdev, u8 type, u16 len) 80 - { 81 - u16 payload; 82 - int ret; 83 - 84 - len |= type << 8; 85 - payload = len; 86 - ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload, 87 - sizeof(payload), NULL, NULL); 88 - if (ret < 0) 89 - return ret; 90 - 91 - /* TODO: LENGTH_GET? */ 92 - return 0; 93 - } 94 - 95 - int fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis) 96 - { 97 - u16 payload; 98 - int ret; 99 - u8 rds_text[] = "Zoom2\n"; 100 - 101 - fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis, 102 - FM_RDS_ENABLE, FM_RDS_DISABLE); 103 - 104 - if (rds_en_dis == FM_RDS_ENABLE) { 105 - /* Set RDS length */ 106 - set_rds_len(fmdev, 0, strlen(rds_text)); 107 - 108 - /* Set RDS text */ 109 - set_rds_text(fmdev, rds_text); 110 - 111 - /* Set RDS mode */ 112 - set_rds_data_mode(fmdev, 0x0); 113 - } 114 - 115 - /* Send command to enable RDS */ 116 - if (rds_en_dis == FM_RDS_ENABLE) 117 - payload = 0x01; 118 - else 119 - payload = 0x00; 120 - 121 - ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload, 122 - sizeof(payload), NULL, NULL); 123 - if (ret < 0) 124 - return ret; 125 - 126 - if (rds_en_dis == FM_RDS_ENABLE) { 127 - /* Set RDS length */ 128 - set_rds_len(fmdev, 0, strlen(rds_text)); 129 - 130 - /* Set RDS text */ 131 - set_rds_text(fmdev, rds_text); 132 - } 133 - fmdev->tx_data.rds.flag = rds_en_dis; 134 - 135 - return 0; 136 - } 137 - 138 - int fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type) 139 - { 140 - u16 payload; 141 - int ret; 142 - 143 - if (fmdev->curr_fmmode != FM_MODE_TX) 144 - return -EPERM; 145 - 146 - fm_tx_set_rds_mode(fmdev, 0); 147 - 148 - /* Set RDS length */ 149 - set_rds_len(fmdev, rds_type, strlen(rds_text)); 150 - 151 - /* Set RDS text */ 152 - set_rds_text(fmdev, rds_text); 153 - 154 - /* Set RDS mode */ 155 - set_rds_data_mode(fmdev, 0x0); 156 - 157 - payload = 1; 158 - ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload, 159 - sizeof(payload), NULL, NULL); 160 - if (ret < 0) 161 - return ret; 162 - 163 - return 0; 164 - } 165 - 166 - int fm_tx_set_af(struct fmdev *fmdev, u32 af) 167 - { 168 - u16 payload; 169 - int ret; 170 - 171 - if (fmdev->curr_fmmode != FM_MODE_TX) 172 - return -EPERM; 173 - 174 - fmdbg("AF: %d\n", af); 175 - 176 - af = (af - 87500) / 100; 177 - payload = (u16)af; 178 - ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload, 179 - sizeof(payload), NULL, NULL); 180 - if (ret < 0) 181 - return ret; 182 - 183 - return 0; 184 - } 185 - 186 - int fm_tx_set_region(struct fmdev *fmdev, u8 region) 187 - { 188 - u16 payload; 189 - int ret; 190 - 191 - if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) { 192 - fmerr("Invalid band\n"); 193 - return -EINVAL; 194 - } 195 - 196 - /* Send command to set the band */ 197 - payload = (u16)region; 198 - ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload, 199 - sizeof(payload), NULL, NULL); 200 - if (ret < 0) 201 - return ret; 202 - 203 - return 0; 204 - } 205 - 206 - int fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset) 207 - { 208 - u16 payload; 209 - int ret; 210 - 211 - fmdbg("tx: mute mode %d\n", mute_mode_toset); 212 - 213 - payload = mute_mode_toset; 214 - ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload, 215 - sizeof(payload), NULL, NULL); 216 - if (ret < 0) 217 - return ret; 218 - 219 - return 0; 220 - } 221 - 222 - /* Set TX Audio I/O */ 223 - static int set_audio_io(struct fmdev *fmdev) 224 - { 225 - struct fmtx_data *tx = &fmdev->tx_data; 226 - u16 payload; 227 - int ret; 228 - 229 - /* Set Audio I/O Enable */ 230 - payload = tx->audio_io; 231 - ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload, 232 - sizeof(payload), NULL, NULL); 233 - if (ret < 0) 234 - return ret; 235 - 236 - /* TODO: is audio set? */ 237 - return 0; 238 - } 239 - 240 - /* Start TX Transmission */ 241 - static int enable_xmit(struct fmdev *fmdev, u8 new_xmit_state) 242 - { 243 - struct fmtx_data *tx = &fmdev->tx_data; 244 - unsigned long timeleft; 245 - u16 payload; 246 - int ret; 247 - 248 - /* Enable POWER_ENB interrupts */ 249 - payload = FM_POW_ENB_EVENT; 250 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 251 - sizeof(payload), NULL, NULL); 252 - if (ret < 0) 253 - return ret; 254 - 255 - /* Set Power Enable */ 256 - payload = new_xmit_state; 257 - ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload, 258 - sizeof(payload), NULL, NULL); 259 - if (ret < 0) 260 - return ret; 261 - 262 - /* Wait for Power Enabled */ 263 - init_completion(&fmdev->maintask_comp); 264 - timeleft = wait_for_completion_timeout(&fmdev->maintask_comp, 265 - FM_DRV_TX_TIMEOUT); 266 - if (!timeleft) { 267 - fmerr("Timeout(%d sec),didn't get tune ended interrupt\n", 268 - jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); 269 - return -ETIMEDOUT; 270 - } 271 - 272 - set_bit(FM_CORE_TX_XMITING, &fmdev->flag); 273 - tx->xmit_state = new_xmit_state; 274 - 275 - return 0; 276 - } 277 - 278 - /* Set TX power level */ 279 - int fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl) 280 - { 281 - u16 payload; 282 - struct fmtx_data *tx = &fmdev->tx_data; 283 - int ret; 284 - 285 - if (fmdev->curr_fmmode != FM_MODE_TX) 286 - return -EPERM; 287 - fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl); 288 - 289 - /* If the core isn't ready update global variable */ 290 - if (!test_bit(FM_CORE_READY, &fmdev->flag)) { 291 - tx->pwr_lvl = new_pwr_lvl; 292 - return 0; 293 - } 294 - 295 - /* Set power level: Application will specify power level value in 296 - * units of dB/uV, whereas range and step are specific to FM chip. 297 - * For TI's WL chips, convert application specified power level value 298 - * to chip specific value by subtracting 122 from it. Refer to TI FM 299 - * data sheet for details. 300 - * */ 301 - 302 - payload = (FM_PWR_LVL_HIGH - new_pwr_lvl); 303 - ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload, 304 - sizeof(payload), NULL, NULL); 305 - if (ret < 0) 306 - return ret; 307 - 308 - /* TODO: is the power level set? */ 309 - tx->pwr_lvl = new_pwr_lvl; 310 - 311 - return 0; 312 - } 313 - 314 - /* 315 - * Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us) 316 - * Convert V4L2 specified filter values to chip specific filter values. 317 - */ 318 - int fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis) 319 - { 320 - struct fmtx_data *tx = &fmdev->tx_data; 321 - u16 payload; 322 - int ret; 323 - 324 - if (fmdev->curr_fmmode != FM_MODE_TX) 325 - return -EPERM; 326 - 327 - switch (preemphasis) { 328 - case V4L2_PREEMPHASIS_DISABLED: 329 - payload = FM_TX_PREEMPH_OFF; 330 - break; 331 - case V4L2_PREEMPHASIS_50_uS: 332 - payload = FM_TX_PREEMPH_50US; 333 - break; 334 - case V4L2_PREEMPHASIS_75_uS: 335 - payload = FM_TX_PREEMPH_75US; 336 - break; 337 - } 338 - 339 - ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload, 340 - sizeof(payload), NULL, NULL); 341 - if (ret < 0) 342 - return ret; 343 - 344 - tx->preemph = payload; 345 - 346 - return ret; 347 - } 348 - 349 - /* Get the TX tuning capacitor value.*/ 350 - int fm_tx_get_tune_cap_val(struct fmdev *fmdev) 351 - { 352 - u16 curr_val; 353 - u32 resp_len; 354 - int ret; 355 - 356 - if (fmdev->curr_fmmode != FM_MODE_TX) 357 - return -EPERM; 358 - 359 - ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD, 360 - NULL, sizeof(curr_val), &curr_val, &resp_len); 361 - if (ret < 0) 362 - return ret; 363 - 364 - curr_val = be16_to_cpu((__force __be16)curr_val); 365 - 366 - return curr_val; 367 - } 368 - 369 - /* Set TX Frequency */ 370 - int fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set) 371 - { 372 - struct fmtx_data *tx = &fmdev->tx_data; 373 - u16 payload, chanl_index; 374 - int ret; 375 - 376 - if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) { 377 - enable_xmit(fmdev, 0); 378 - clear_bit(FM_CORE_TX_XMITING, &fmdev->flag); 379 - } 380 - 381 - /* Enable FR, BL interrupts */ 382 - payload = (FM_FR_EVENT | FM_BL_EVENT); 383 - ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, 384 - sizeof(payload), NULL, NULL); 385 - if (ret < 0) 386 - return ret; 387 - 388 - tx->tx_frq = (unsigned long)freq_to_set; 389 - fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq); 390 - 391 - chanl_index = freq_to_set / 10; 392 - 393 - /* Set current tuner channel */ 394 - payload = chanl_index; 395 - ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload, 396 - sizeof(payload), NULL, NULL); 397 - if (ret < 0) 398 - return ret; 399 - 400 - fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl); 401 - fm_tx_set_preemph_filter(fmdev, tx->preemph); 402 - 403 - tx->audio_io = 0x01; /* I2S */ 404 - set_audio_io(fmdev); 405 - 406 - enable_xmit(fmdev, 0x01); /* Enable transmission */ 407 - 408 - tx->aud_mode = FM_STEREO_MODE; 409 - tx->rds.flag = FM_RDS_DISABLE; 410 - 411 - return 0; 412 - } 413 -
-24
drivers/media/radio/wl128x/fmdrv_tx.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * FM TX module header. 5 - * 6 - * Copyright (C) 2011 Texas Instruments 7 - */ 8 - 9 - #ifndef _FMDRV_TX_H 10 - #define _FMDRV_TX_H 11 - 12 - int fm_tx_set_freq(struct fmdev *, u32); 13 - int fm_tx_set_pwr_lvl(struct fmdev *, u8); 14 - int fm_tx_set_region(struct fmdev *, u8); 15 - int fm_tx_set_mute_mode(struct fmdev *, u8); 16 - int fm_tx_set_stereo_mono(struct fmdev *, u16); 17 - int fm_tx_set_rds_mode(struct fmdev *, u8); 18 - int fm_tx_set_radio_text(struct fmdev *, u8 *, u8); 19 - int fm_tx_set_af(struct fmdev *, u32); 20 - int fm_tx_set_preemph_filter(struct fmdev *, u32); 21 - int fm_tx_get_tune_cap_val(struct fmdev *); 22 - 23 - #endif 24 -
-604
drivers/media/radio/wl128x/fmdrv_v4l2.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * This file provides interfaces to V4L2 subsystem. 5 - * 6 - * This module registers with V4L2 subsystem as Radio 7 - * data system interface (/dev/radio). During the registration, 8 - * it will expose two set of function pointers. 9 - * 10 - * 1) File operation related API (open, close, read, write, poll...etc). 11 - * 2) Set of V4L2 IOCTL complaint API. 12 - * 13 - * Copyright (C) 2011 Texas Instruments 14 - * Author: Raja Mani <raja_mani@ti.com> 15 - * Author: Manjunatha Halli <manjunatha_halli@ti.com> 16 - */ 17 - 18 - #include <linux/export.h> 19 - 20 - #include "fmdrv.h" 21 - #include "fmdrv_v4l2.h" 22 - #include "fmdrv_common.h" 23 - #include "fmdrv_rx.h" 24 - #include "fmdrv_tx.h" 25 - 26 - static struct video_device gradio_dev; 27 - static u8 radio_disconnected; 28 - 29 - /* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */ 30 - 31 - /* Read RX RDS data */ 32 - static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf, 33 - size_t count, loff_t *ppos) 34 - { 35 - u8 rds_mode; 36 - int ret; 37 - struct fmdev *fmdev; 38 - 39 - fmdev = video_drvdata(file); 40 - 41 - if (!radio_disconnected) { 42 - fmerr("FM device is already disconnected\n"); 43 - return -EIO; 44 - } 45 - 46 - if (mutex_lock_interruptible(&fmdev->mutex)) 47 - return -ERESTARTSYS; 48 - 49 - /* Turn on RDS mode if it is disabled */ 50 - ret = fm_rx_get_rds_mode(fmdev, &rds_mode); 51 - if (ret < 0) { 52 - fmerr("Unable to read current rds mode\n"); 53 - goto read_unlock; 54 - } 55 - 56 - if (rds_mode == FM_RDS_DISABLE) { 57 - ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE); 58 - if (ret < 0) { 59 - fmerr("Failed to enable rds mode\n"); 60 - goto read_unlock; 61 - } 62 - } 63 - 64 - /* Copy RDS data from internal buffer to user buffer */ 65 - ret = fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count); 66 - read_unlock: 67 - mutex_unlock(&fmdev->mutex); 68 - return ret; 69 - } 70 - 71 - /* Write TX RDS data */ 72 - static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf, 73 - size_t count, loff_t *ppos) 74 - { 75 - struct tx_rds rds; 76 - int ret; 77 - struct fmdev *fmdev; 78 - 79 - ret = copy_from_user(&rds, buf, sizeof(rds)); 80 - rds.text[sizeof(rds.text) - 1] = '\0'; 81 - fmdbg("(%d)type: %d, text %s, af %d\n", 82 - ret, rds.text_type, rds.text, rds.af_freq); 83 - if (ret) 84 - return -EFAULT; 85 - 86 - fmdev = video_drvdata(file); 87 - if (mutex_lock_interruptible(&fmdev->mutex)) 88 - return -ERESTARTSYS; 89 - fm_tx_set_radio_text(fmdev, rds.text, rds.text_type); 90 - fm_tx_set_af(fmdev, rds.af_freq); 91 - mutex_unlock(&fmdev->mutex); 92 - 93 - return sizeof(rds); 94 - } 95 - 96 - static __poll_t fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts) 97 - { 98 - int ret; 99 - struct fmdev *fmdev; 100 - 101 - fmdev = video_drvdata(file); 102 - mutex_lock(&fmdev->mutex); 103 - ret = fmc_is_rds_data_available(fmdev, file, pts); 104 - mutex_unlock(&fmdev->mutex); 105 - if (ret < 0) 106 - return EPOLLIN | EPOLLRDNORM; 107 - 108 - return 0; 109 - } 110 - 111 - /* 112 - * Handle open request for "/dev/radioX" device. 113 - * Start with FM RX mode as default. 114 - */ 115 - static int fm_v4l2_fops_open(struct file *file) 116 - { 117 - int ret; 118 - struct fmdev *fmdev = NULL; 119 - 120 - /* Don't allow multiple open */ 121 - if (radio_disconnected) { 122 - fmerr("FM device is already opened\n"); 123 - return -EBUSY; 124 - } 125 - 126 - fmdev = video_drvdata(file); 127 - 128 - if (mutex_lock_interruptible(&fmdev->mutex)) 129 - return -ERESTARTSYS; 130 - ret = fmc_prepare(fmdev); 131 - if (ret < 0) { 132 - fmerr("Unable to prepare FM CORE\n"); 133 - goto open_unlock; 134 - } 135 - 136 - fmdbg("Load FM RX firmware..\n"); 137 - 138 - ret = fmc_set_mode(fmdev, FM_MODE_RX); 139 - if (ret < 0) { 140 - fmerr("Unable to load FM RX firmware\n"); 141 - goto open_unlock; 142 - } 143 - radio_disconnected = 1; 144 - 145 - open_unlock: 146 - mutex_unlock(&fmdev->mutex); 147 - return ret; 148 - } 149 - 150 - static int fm_v4l2_fops_release(struct file *file) 151 - { 152 - int ret; 153 - struct fmdev *fmdev; 154 - 155 - fmdev = video_drvdata(file); 156 - if (!radio_disconnected) { 157 - fmdbg("FM device is already closed\n"); 158 - return 0; 159 - } 160 - 161 - mutex_lock(&fmdev->mutex); 162 - ret = fmc_set_mode(fmdev, FM_MODE_OFF); 163 - if (ret < 0) { 164 - fmerr("Unable to turn off the chip\n"); 165 - goto release_unlock; 166 - } 167 - 168 - ret = fmc_release(fmdev); 169 - if (ret < 0) { 170 - fmerr("FM CORE release failed\n"); 171 - goto release_unlock; 172 - } 173 - radio_disconnected = 0; 174 - 175 - release_unlock: 176 - mutex_unlock(&fmdev->mutex); 177 - return ret; 178 - } 179 - 180 - /* V4L2 RADIO (/dev/radioX) device IOCTL interfaces */ 181 - static int fm_v4l2_vidioc_querycap(struct file *file, void *priv, 182 - struct v4l2_capability *capability) 183 - { 184 - strscpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver)); 185 - strscpy(capability->card, FM_DRV_CARD_SHORT_NAME, 186 - sizeof(capability->card)); 187 - sprintf(capability->bus_info, "UART"); 188 - return 0; 189 - } 190 - 191 - static int fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 192 - { 193 - struct fmdev *fmdev = container_of(ctrl->handler, 194 - struct fmdev, ctrl_handler); 195 - 196 - switch (ctrl->id) { 197 - case V4L2_CID_TUNE_ANTENNA_CAPACITOR: 198 - ctrl->val = fm_tx_get_tune_cap_val(fmdev); 199 - break; 200 - default: 201 - fmwarn("%s: Unknown IOCTL: %d\n", __func__, ctrl->id); 202 - break; 203 - } 204 - 205 - return 0; 206 - } 207 - 208 - static int fm_v4l2_s_ctrl(struct v4l2_ctrl *ctrl) 209 - { 210 - struct fmdev *fmdev = container_of(ctrl->handler, 211 - struct fmdev, ctrl_handler); 212 - 213 - switch (ctrl->id) { 214 - case V4L2_CID_AUDIO_VOLUME: /* set volume */ 215 - return fm_rx_set_volume(fmdev, (u16)ctrl->val); 216 - 217 - case V4L2_CID_AUDIO_MUTE: /* set mute */ 218 - return fmc_set_mute_mode(fmdev, (u8)ctrl->val); 219 - 220 - case V4L2_CID_TUNE_POWER_LEVEL: 221 - /* set TX power level - ext control */ 222 - return fm_tx_set_pwr_lvl(fmdev, (u8)ctrl->val); 223 - 224 - case V4L2_CID_TUNE_PREEMPHASIS: 225 - return fm_tx_set_preemph_filter(fmdev, (u8) ctrl->val); 226 - 227 - default: 228 - return -EINVAL; 229 - } 230 - } 231 - 232 - static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv, 233 - struct v4l2_audio *audio) 234 - { 235 - memset(audio, 0, sizeof(*audio)); 236 - strscpy(audio->name, "Radio", sizeof(audio->name)); 237 - audio->capability = V4L2_AUDCAP_STEREO; 238 - 239 - return 0; 240 - } 241 - 242 - static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv, 243 - const struct v4l2_audio *audio) 244 - { 245 - if (audio->index != 0) 246 - return -EINVAL; 247 - 248 - return 0; 249 - } 250 - 251 - /* Get tuner attributes. If current mode is NOT RX, return error */ 252 - static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv, 253 - struct v4l2_tuner *tuner) 254 - { 255 - struct fmdev *fmdev = video_drvdata(file); 256 - u32 bottom_freq; 257 - u32 top_freq; 258 - u16 stereo_mono_mode; 259 - u16 rssilvl; 260 - int ret; 261 - 262 - if (tuner->index != 0) 263 - return -EINVAL; 264 - 265 - if (fmdev->curr_fmmode != FM_MODE_RX) 266 - return -EPERM; 267 - 268 - ret = fm_rx_get_band_freq_range(fmdev, &bottom_freq, &top_freq); 269 - if (ret != 0) 270 - return ret; 271 - 272 - ret = fm_rx_get_stereo_mono(fmdev, &stereo_mono_mode); 273 - if (ret != 0) 274 - return ret; 275 - 276 - ret = fm_rx_get_rssi_level(fmdev, &rssilvl); 277 - if (ret != 0) 278 - return ret; 279 - 280 - strscpy(tuner->name, "FM", sizeof(tuner->name)); 281 - tuner->type = V4L2_TUNER_RADIO; 282 - /* Store rangelow and rangehigh freq in unit of 62.5 Hz */ 283 - tuner->rangelow = bottom_freq * 16; 284 - tuner->rangehigh = top_freq * 16; 285 - tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO | 286 - ((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0); 287 - tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | 288 - V4L2_TUNER_CAP_LOW | 289 - V4L2_TUNER_CAP_HWSEEK_BOUNDED | 290 - V4L2_TUNER_CAP_HWSEEK_WRAP; 291 - tuner->audmode = (stereo_mono_mode ? 292 - V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO); 293 - 294 - /* 295 - * Actual rssi value lies in between -128 to +127. 296 - * Convert this range from 0 to 255 by adding +128 297 - */ 298 - rssilvl += 128; 299 - 300 - /* 301 - * Return signal strength value should be within 0 to 65535. 302 - * Find out correct signal radio by multiplying (65535/255) = 257 303 - */ 304 - tuner->signal = rssilvl * 257; 305 - tuner->afc = 0; 306 - 307 - return ret; 308 - } 309 - 310 - /* 311 - * Set tuner attributes. If current mode is NOT RX, set to RX. 312 - * Currently, we set only audio mode (mono/stereo) and RDS state (on/off). 313 - * Should we set other tuner attributes, too? 314 - */ 315 - static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv, 316 - const struct v4l2_tuner *tuner) 317 - { 318 - struct fmdev *fmdev = video_drvdata(file); 319 - u16 aud_mode; 320 - u8 rds_mode; 321 - int ret; 322 - 323 - if (tuner->index != 0) 324 - return -EINVAL; 325 - 326 - aud_mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ? 327 - FM_STEREO_MODE : FM_MONO_MODE; 328 - rds_mode = (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ? 329 - FM_RDS_ENABLE : FM_RDS_DISABLE; 330 - 331 - if (fmdev->curr_fmmode != FM_MODE_RX) { 332 - ret = fmc_set_mode(fmdev, FM_MODE_RX); 333 - if (ret < 0) { 334 - fmerr("Failed to set RX mode\n"); 335 - return ret; 336 - } 337 - } 338 - 339 - ret = fmc_set_stereo_mono(fmdev, aud_mode); 340 - if (ret < 0) { 341 - fmerr("Failed to set RX stereo/mono mode\n"); 342 - return ret; 343 - } 344 - 345 - ret = fmc_set_rds_mode(fmdev, rds_mode); 346 - if (ret < 0) 347 - fmerr("Failed to set RX RDS mode\n"); 348 - 349 - return ret; 350 - } 351 - 352 - /* Get tuner or modulator radio frequency */ 353 - static int fm_v4l2_vidioc_g_freq(struct file *file, void *priv, 354 - struct v4l2_frequency *freq) 355 - { 356 - struct fmdev *fmdev = video_drvdata(file); 357 - int ret; 358 - 359 - ret = fmc_get_freq(fmdev, &freq->frequency); 360 - if (ret < 0) { 361 - fmerr("Failed to get frequency\n"); 362 - return ret; 363 - } 364 - 365 - /* Frequency unit of 62.5 Hz*/ 366 - freq->frequency = (u32) freq->frequency * 16; 367 - 368 - return 0; 369 - } 370 - 371 - /* Set tuner or modulator radio frequency */ 372 - static int fm_v4l2_vidioc_s_freq(struct file *file, void *priv, 373 - const struct v4l2_frequency *freq) 374 - { 375 - struct fmdev *fmdev = video_drvdata(file); 376 - 377 - /* 378 - * As V4L2_TUNER_CAP_LOW is set 1 user sends the frequency 379 - * in units of 62.5 Hz. 380 - */ 381 - return fmc_set_freq(fmdev, freq->frequency / 16); 382 - } 383 - 384 - /* Set hardware frequency seek. If current mode is NOT RX, set it RX. */ 385 - static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv, 386 - const struct v4l2_hw_freq_seek *seek) 387 - { 388 - struct fmdev *fmdev = video_drvdata(file); 389 - int ret; 390 - 391 - if (file->f_flags & O_NONBLOCK) 392 - return -EWOULDBLOCK; 393 - 394 - if (fmdev->curr_fmmode != FM_MODE_RX) { 395 - ret = fmc_set_mode(fmdev, FM_MODE_RX); 396 - if (ret != 0) { 397 - fmerr("Failed to set RX mode\n"); 398 - return ret; 399 - } 400 - } 401 - 402 - ret = fm_rx_seek(fmdev, seek->seek_upward, seek->wrap_around, 403 - seek->spacing); 404 - if (ret < 0) 405 - fmerr("RX seek failed - %d\n", ret); 406 - 407 - return ret; 408 - } 409 - /* Get modulator attributes. If mode is not TX, return no attributes. */ 410 - static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv, 411 - struct v4l2_modulator *mod) 412 - { 413 - struct fmdev *fmdev = video_drvdata(file); 414 - 415 - if (mod->index != 0) 416 - return -EINVAL; 417 - 418 - if (fmdev->curr_fmmode != FM_MODE_TX) 419 - return -EPERM; 420 - 421 - mod->txsubchans = ((fmdev->tx_data.aud_mode == FM_STEREO_MODE) ? 422 - V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO) | 423 - ((fmdev->tx_data.rds.flag == FM_RDS_ENABLE) ? 424 - V4L2_TUNER_SUB_RDS : 0); 425 - 426 - mod->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | 427 - V4L2_TUNER_CAP_LOW; 428 - 429 - return 0; 430 - } 431 - 432 - /* Set modulator attributes. If mode is not TX, set to TX. */ 433 - static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv, 434 - const struct v4l2_modulator *mod) 435 - { 436 - struct fmdev *fmdev = video_drvdata(file); 437 - u8 rds_mode; 438 - u16 aud_mode; 439 - int ret; 440 - 441 - if (mod->index != 0) 442 - return -EINVAL; 443 - 444 - if (fmdev->curr_fmmode != FM_MODE_TX) { 445 - ret = fmc_set_mode(fmdev, FM_MODE_TX); 446 - if (ret != 0) { 447 - fmerr("Failed to set TX mode\n"); 448 - return ret; 449 - } 450 - } 451 - 452 - aud_mode = (mod->txsubchans & V4L2_TUNER_SUB_STEREO) ? 453 - FM_STEREO_MODE : FM_MONO_MODE; 454 - rds_mode = (mod->txsubchans & V4L2_TUNER_SUB_RDS) ? 455 - FM_RDS_ENABLE : FM_RDS_DISABLE; 456 - ret = fm_tx_set_stereo_mono(fmdev, aud_mode); 457 - if (ret < 0) { 458 - fmerr("Failed to set mono/stereo mode for TX\n"); 459 - return ret; 460 - } 461 - ret = fm_tx_set_rds_mode(fmdev, rds_mode); 462 - if (ret < 0) 463 - fmerr("Failed to set rds mode for TX\n"); 464 - 465 - return ret; 466 - } 467 - 468 - static const struct v4l2_file_operations fm_drv_fops = { 469 - .owner = THIS_MODULE, 470 - .read = fm_v4l2_fops_read, 471 - .write = fm_v4l2_fops_write, 472 - .poll = fm_v4l2_fops_poll, 473 - .unlocked_ioctl = video_ioctl2, 474 - .open = fm_v4l2_fops_open, 475 - .release = fm_v4l2_fops_release, 476 - }; 477 - 478 - static const struct v4l2_ctrl_ops fm_ctrl_ops = { 479 - .s_ctrl = fm_v4l2_s_ctrl, 480 - .g_volatile_ctrl = fm_g_volatile_ctrl, 481 - }; 482 - static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = { 483 - .vidioc_querycap = fm_v4l2_vidioc_querycap, 484 - .vidioc_g_audio = fm_v4l2_vidioc_g_audio, 485 - .vidioc_s_audio = fm_v4l2_vidioc_s_audio, 486 - .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner, 487 - .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner, 488 - .vidioc_g_frequency = fm_v4l2_vidioc_g_freq, 489 - .vidioc_s_frequency = fm_v4l2_vidioc_s_freq, 490 - .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek, 491 - .vidioc_g_modulator = fm_v4l2_vidioc_g_modulator, 492 - .vidioc_s_modulator = fm_v4l2_vidioc_s_modulator 493 - }; 494 - 495 - /* V4L2 RADIO device parent structure */ 496 - static const struct video_device fm_viddev_template = { 497 - .fops = &fm_drv_fops, 498 - .ioctl_ops = &fm_drv_ioctl_ops, 499 - .name = FM_DRV_NAME, 500 - .release = video_device_release_empty, 501 - /* 502 - * To ensure both the tuner and modulator ioctls are accessible we 503 - * set the vfl_dir to M2M to indicate this. 504 - * 505 - * It is not really a mem2mem device of course, but it can both receive 506 - * and transmit using the same radio device. It's the only radio driver 507 - * that does this and it should really be split in two radio devices, 508 - * but that would affect applications using this driver. 509 - */ 510 - .vfl_dir = VFL_DIR_M2M, 511 - .device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER | V4L2_CAP_RADIO | 512 - V4L2_CAP_MODULATOR | V4L2_CAP_AUDIO | 513 - V4L2_CAP_READWRITE | V4L2_CAP_RDS_CAPTURE, 514 - }; 515 - 516 - int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) 517 - { 518 - struct v4l2_ctrl *ctrl; 519 - int ret; 520 - 521 - strscpy(fmdev->v4l2_dev.name, FM_DRV_NAME, 522 - sizeof(fmdev->v4l2_dev.name)); 523 - ret = v4l2_device_register(NULL, &fmdev->v4l2_dev); 524 - if (ret < 0) 525 - return ret; 526 - 527 - /* Init mutex for core locking */ 528 - mutex_init(&fmdev->mutex); 529 - 530 - /* Setup FM driver's V4L2 properties */ 531 - gradio_dev = fm_viddev_template; 532 - 533 - video_set_drvdata(&gradio_dev, fmdev); 534 - 535 - gradio_dev.lock = &fmdev->mutex; 536 - gradio_dev.v4l2_dev = &fmdev->v4l2_dev; 537 - 538 - /* Register with V4L2 subsystem as RADIO device */ 539 - if (video_register_device(&gradio_dev, VFL_TYPE_RADIO, radio_nr)) { 540 - v4l2_device_unregister(&fmdev->v4l2_dev); 541 - fmerr("Could not register video device\n"); 542 - return -ENOMEM; 543 - } 544 - 545 - fmdev->radio_dev = &gradio_dev; 546 - 547 - /* Register to v4l2 ctrl handler framework */ 548 - fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler; 549 - 550 - ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 5); 551 - if (ret < 0) { 552 - fmerr("(fmdev): Can't init ctrl handler\n"); 553 - v4l2_ctrl_handler_free(&fmdev->ctrl_handler); 554 - video_unregister_device(fmdev->radio_dev); 555 - v4l2_device_unregister(&fmdev->v4l2_dev); 556 - return -EBUSY; 557 - } 558 - 559 - /* 560 - * Following controls are handled by V4L2 control framework. 561 - * Added in ascending ID order. 562 - */ 563 - v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, 564 - V4L2_CID_AUDIO_VOLUME, FM_RX_VOLUME_MIN, 565 - FM_RX_VOLUME_MAX, 1, FM_RX_VOLUME_MAX); 566 - 567 - v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, 568 - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 569 - 570 - v4l2_ctrl_new_std_menu(&fmdev->ctrl_handler, &fm_ctrl_ops, 571 - V4L2_CID_TUNE_PREEMPHASIS, V4L2_PREEMPHASIS_75_uS, 572 - 0, V4L2_PREEMPHASIS_75_uS); 573 - 574 - v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, 575 - V4L2_CID_TUNE_POWER_LEVEL, FM_PWR_LVL_LOW, 576 - FM_PWR_LVL_HIGH, 1, FM_PWR_LVL_HIGH); 577 - 578 - ctrl = v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, 579 - V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, 580 - 255, 1, 255); 581 - 582 - if (ctrl) 583 - ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 584 - 585 - return 0; 586 - } 587 - 588 - void *fm_v4l2_deinit_video_device(void) 589 - { 590 - struct fmdev *fmdev; 591 - 592 - 593 - fmdev = video_get_drvdata(&gradio_dev); 594 - 595 - /* Unregister to v4l2 ctrl handler framework*/ 596 - v4l2_ctrl_handler_free(&fmdev->ctrl_handler); 597 - 598 - /* Unregister RADIO device from V4L2 subsystem */ 599 - video_unregister_device(&gradio_dev); 600 - 601 - v4l2_device_unregister(&fmdev->v4l2_dev); 602 - 603 - return fmdev; 604 - }
-20
drivers/media/radio/wl128x/fmdrv_v4l2.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * FM Driver for Connectivity chip of Texas Instruments. 4 - * 5 - * FM V4L2 module header. 6 - * 7 - * Copyright (C) 2011 Texas Instruments 8 - */ 9 - 10 - #ifndef _FMDRV_V4L2_H 11 - #define _FMDRV_V4L2_H 12 - 13 - #include <media/v4l2-ioctl.h> 14 - #include <media/v4l2-common.h> 15 - #include <media/v4l2-ctrls.h> 16 - 17 - int fm_v4l2_init_video_device(struct fmdev *, int); 18 - void *fm_v4l2_deinit_video_device(void); 19 - 20 - #endif
+3 -1
drivers/media/rc/iguanair.c
··· 194 194 if (rc) 195 195 return rc; 196 196 197 - if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) 197 + if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { 198 + usb_kill_urb(ir->urb_out); 198 199 return -ETIMEDOUT; 200 + } 199 201 200 202 return rc; 201 203 }
+1 -1
drivers/media/rc/imon_raw.c
··· 37 37 if (packet_no == 0xff) 38 38 return; 39 39 40 - dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); 40 + dev_dbg(imon->dev, "data: %8ph", imon->ir_buf); 41 41 42 42 /* 43 43 * Only the first 5 bytes contain IR data. Right shift so we move
+2 -3
drivers/media/rc/mceusb.c
··· 28 28 #include <linux/workqueue.h> 29 29 #include <linux/usb.h> 30 30 #include <linux/usb/input.h> 31 - #include <linux/pm_wakeup.h> 32 31 #include <media/rc-core.h> 33 32 34 33 #define DRIVER_VERSION "1.95" ··· 657 658 if (len == 2) 658 659 dev_dbg(dev, "Get hw/sw rev?"); 659 660 else 660 - dev_dbg(dev, "hw/sw rev %*ph", 661 - 4, &buf[offset + 2]); 661 + dev_dbg(dev, "hw/sw rev %4ph", 662 + &buf[offset + 2]); 662 663 break; 663 664 case MCE_CMD_RESUME: 664 665 dev_dbg(dev, "Device resume requested");
+7 -1
drivers/media/test-drivers/vidtv/vidtv_bridge.c
··· 191 191 192 192 mux_args.mux_buf_sz = mux_buf_sz; 193 193 194 - dvb->streaming = true; 195 194 dvb->mux = vidtv_mux_init(dvb->fe[0], dev, &mux_args); 196 195 if (!dvb->mux) 197 196 return -ENOMEM; 197 + 198 + dvb->streaming = true; 198 199 vidtv_mux_start_thread(dvb->mux); 199 200 200 201 dev_dbg_ratelimited(dev, "Started streaming\n"); ··· 205 204 static int vidtv_stop_streaming(struct vidtv_dvb *dvb) 206 205 { 207 206 struct device *dev = &dvb->pdev->dev; 207 + 208 + if (!dvb->streaming) { 209 + dev_warn_ratelimited(dev, "No streaming. Skipping.\n"); 210 + return 0; 211 + } 208 212 209 213 dvb->streaming = false; 210 214 vidtv_mux_stop_thread(dvb->mux);
-64
drivers/media/tuners/fc0013.c
··· 112 112 return 0; 113 113 } 114 114 115 - int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val) 116 - { 117 - struct fc0013_priv *priv = fe->tuner_priv; 118 - int ret; 119 - u8 rc_cal; 120 - int val; 121 - 122 - if (fe->ops.i2c_gate_ctrl) 123 - fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 124 - 125 - /* push rc_cal value, get rc_cal value */ 126 - ret = fc0013_writereg(priv, 0x10, 0x00); 127 - if (ret) 128 - goto error_out; 129 - 130 - /* get rc_cal value */ 131 - ret = fc0013_readreg(priv, 0x10, &rc_cal); 132 - if (ret) 133 - goto error_out; 134 - 135 - rc_cal &= 0x0f; 136 - 137 - val = (int)rc_cal + rc_val; 138 - 139 - /* forcing rc_cal */ 140 - ret = fc0013_writereg(priv, 0x0d, 0x11); 141 - if (ret) 142 - goto error_out; 143 - 144 - /* modify rc_cal value */ 145 - if (val > 15) 146 - ret = fc0013_writereg(priv, 0x10, 0x0f); 147 - else if (val < 0) 148 - ret = fc0013_writereg(priv, 0x10, 0x00); 149 - else 150 - ret = fc0013_writereg(priv, 0x10, (u8)val); 151 - 152 - error_out: 153 - if (fe->ops.i2c_gate_ctrl) 154 - fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 155 - 156 - return ret; 157 - } 158 - EXPORT_SYMBOL(fc0013_rc_cal_add); 159 - 160 - int fc0013_rc_cal_reset(struct dvb_frontend *fe) 161 - { 162 - struct fc0013_priv *priv = fe->tuner_priv; 163 - int ret; 164 - 165 - if (fe->ops.i2c_gate_ctrl) 166 - fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 167 - 168 - ret = fc0013_writereg(priv, 0x0d, 0x01); 169 - if (!ret) 170 - ret = fc0013_writereg(priv, 0x10, 0x00); 171 - 172 - if (fe->ops.i2c_gate_ctrl) 173 - fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 174 - 175 - return ret; 176 - } 177 - EXPORT_SYMBOL(fc0013_rc_cal_reset); 178 - 179 115 static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq) 180 116 { 181 117 int ret;
-11
drivers/media/tuners/fc0013.h
··· 16 16 struct i2c_adapter *i2c, 17 17 u8 i2c_address, int dual_master, 18 18 enum fc001x_xtal_freq xtal_freq); 19 - extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val); 20 - extern int fc0013_rc_cal_reset(struct dvb_frontend *fe); 21 19 #else 22 20 static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe, 23 21 struct i2c_adapter *i2c, ··· 26 28 return NULL; 27 29 } 28 30 29 - static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val) 30 - { 31 - return 0; 32 - } 33 - 34 - static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe) 35 - { 36 - return 0; 37 - } 38 31 #endif 39 32 40 33 #endif
-1
drivers/media/usb/cx231xx/cx231xx-avcore.c
··· 2704 2704 dev->gpio_dir = value; 2705 2705 status = cx231xx_set_gpio_bit(dev, dev->gpio_dir, 2706 2706 dev->gpio_val); 2707 - value = 0; 2708 2707 } 2709 2708 2710 2709 if (pin_value == 0)
+12 -6
drivers/media/usb/dvb-usb-v2/af9035.c
··· 322 322 ret = -EOPNOTSUPP; 323 323 } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || 324 324 (msg[0].addr == state->af9033_i2c_addr[1])) { 325 + /* demod access via firmware interface */ 326 + u32 reg; 327 + 325 328 if (msg[0].len < 3 || msg[1].len < 1) { 326 329 ret = -EOPNOTSUPP; 327 330 goto unlock; 328 331 } 329 - /* demod access via firmware interface */ 330 - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | 331 - msg[0].buf[2]; 332 + 333 + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | 334 + msg[0].buf[2]; 332 335 333 336 if (msg[0].addr == state->af9033_i2c_addr[1]) 334 337 reg |= 0x100000; ··· 388 385 ret = -EOPNOTSUPP; 389 386 } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || 390 387 (msg[0].addr == state->af9033_i2c_addr[1])) { 388 + /* demod access via firmware interface */ 389 + u32 reg; 390 + 391 391 if (msg[0].len < 3) { 392 392 ret = -EOPNOTSUPP; 393 393 goto unlock; 394 394 } 395 - /* demod access via firmware interface */ 396 - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | 397 - msg[0].buf[2]; 395 + 396 + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | 397 + msg[0].buf[2]; 398 398 399 399 if (msg[0].addr == state->af9033_i2c_addr[1]) 400 400 reg |= 0x100000;
+11 -1
drivers/media/usb/dvb-usb-v2/lmedm04.c
··· 373 373 struct dvb_usb_device *d = adap_to_d(adap); 374 374 struct lme2510_state *lme_int = adap_to_priv(adap); 375 375 struct usb_host_endpoint *ep; 376 + int ret; 376 377 377 378 lme_int->lme_urb = usb_alloc_urb(0, GFP_KERNEL); 378 379 ··· 391 390 392 391 /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ 393 392 ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); 393 + if (!ep) { 394 + usb_free_urb(lme_int->lme_urb); 395 + return -ENODEV; 396 + } 394 397 395 398 if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) 396 399 lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa); 397 400 398 - usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); 401 + ret = usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); 402 + if (ret) { 403 + usb_free_urb(lme_int->lme_urb); 404 + return ret; 405 + } 406 + 399 407 info("INT Interrupt Service Started"); 400 408 401 409 return 0;
+75 -13
drivers/media/usb/uvc/uvc_ctrl.c
··· 1579 1579 uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); 1580 1580 } 1581 1581 1582 + static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, 1583 + struct uvc_fh *new_handle) 1584 + { 1585 + lockdep_assert_held(&handle->chain->ctrl_mutex); 1586 + 1587 + if (new_handle) { 1588 + if (ctrl->handle) 1589 + dev_warn_ratelimited(&handle->stream->dev->udev->dev, 1590 + "UVC non compliance: Setting an async control with a pending operation."); 1591 + 1592 + if (new_handle == ctrl->handle) 1593 + return; 1594 + 1595 + if (ctrl->handle) { 1596 + WARN_ON(!ctrl->handle->pending_async_ctrls); 1597 + if (ctrl->handle->pending_async_ctrls) 1598 + ctrl->handle->pending_async_ctrls--; 1599 + } 1600 + 1601 + ctrl->handle = new_handle; 1602 + handle->pending_async_ctrls++; 1603 + return; 1604 + } 1605 + 1606 + /* Cannot clear the handle for a control not owned by us.*/ 1607 + if (WARN_ON(ctrl->handle != handle)) 1608 + return; 1609 + 1610 + ctrl->handle = NULL; 1611 + if (WARN_ON(!handle->pending_async_ctrls)) 1612 + return; 1613 + handle->pending_async_ctrls--; 1614 + } 1615 + 1582 1616 void uvc_ctrl_status_event(struct uvc_video_chain *chain, 1583 1617 struct uvc_control *ctrl, const u8 *data) 1584 1618 { ··· 1622 1588 1623 1589 mutex_lock(&chain->ctrl_mutex); 1624 1590 1591 + /* Flush the control cache, the data might have changed. */ 1592 + ctrl->loaded = 0; 1593 + 1625 1594 handle = ctrl->handle; 1626 - ctrl->handle = NULL; 1595 + if (handle) 1596 + uvc_ctrl_set_handle(handle, ctrl, NULL); 1627 1597 1628 1598 list_for_each_entry(mapping, &ctrl->info.mappings, list) { 1629 1599 s32 value = __uvc_ctrl_get_value(mapping, data); ··· 1678 1640 struct uvc_device *dev = chain->dev; 1679 1641 struct uvc_ctrl_work *w = &dev->async_ctrl; 1680 1642 1681 - if (list_empty(&ctrl->info.mappings)) { 1682 - ctrl->handle = NULL; 1643 + if (list_empty(&ctrl->info.mappings)) 1683 1644 return false; 1684 - } 1685 1645 1686 1646 w->data = data; 1687 1647 w->urb = urb; ··· 1709 1673 { 1710 1674 struct uvc_control_mapping *mapping; 1711 1675 struct uvc_control *ctrl; 1712 - u32 changes = V4L2_EVENT_CTRL_CH_VALUE; 1713 1676 unsigned int i; 1714 1677 unsigned int j; 1715 1678 1716 1679 for (i = 0; i < xctrls_count; ++i) { 1717 - ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); 1680 + u32 changes = V4L2_EVENT_CTRL_CH_VALUE; 1718 1681 1682 + ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); 1719 1683 if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) 1720 1684 /* Notification will be sent from an Interrupt event. */ 1721 1685 continue; ··· 1847 1811 } 1848 1812 1849 1813 static int uvc_ctrl_commit_entity(struct uvc_device *dev, 1850 - struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl) 1814 + struct uvc_fh *handle, 1815 + struct uvc_entity *entity, 1816 + int rollback, 1817 + struct uvc_control **err_ctrl) 1851 1818 { 1852 1819 struct uvc_control *ctrl; 1853 1820 unsigned int i; ··· 1898 1859 *err_ctrl = ctrl; 1899 1860 return ret; 1900 1861 } 1862 + 1863 + if (!rollback && handle && 1864 + ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) 1865 + uvc_ctrl_set_handle(handle, ctrl, handle); 1901 1866 } 1902 1867 1903 1868 return 0; ··· 1938 1895 1939 1896 /* Find the control. */ 1940 1897 list_for_each_entry(entity, &chain->entities, chain) { 1941 - ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback, 1942 - &err_ctrl); 1898 + ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, 1899 + rollback, &err_ctrl); 1943 1900 if (ret < 0) { 1944 1901 if (ctrls) 1945 1902 ctrls->error_idx = ··· 1983 1940 s32 min; 1984 1941 s32 max; 1985 1942 int ret; 1943 + 1944 + lockdep_assert_held(&chain->ctrl_mutex); 1986 1945 1987 1946 if (__uvc_query_v4l2_class(chain, xctrl->id, 0) >= 0) 1988 1947 return -EACCES; ··· 2090 2045 2091 2046 mapping->set(mapping, value, 2092 2047 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); 2093 - 2094 - if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) 2095 - ctrl->handle = handle; 2096 2048 2097 2049 ctrl->dirty = 1; 2098 2050 ctrl->modified = 1; ··· 2419 2377 ctrl->dirty = 1; 2420 2378 } 2421 2379 2422 - ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL); 2380 + ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL); 2423 2381 if (ret < 0) 2424 2382 return ret; 2425 2383 } ··· 2810 2768 } 2811 2769 2812 2770 return 0; 2771 + } 2772 + 2773 + void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) 2774 + { 2775 + struct uvc_entity *entity; 2776 + 2777 + guard(mutex)(&handle->chain->ctrl_mutex); 2778 + 2779 + if (!handle->pending_async_ctrls) 2780 + return; 2781 + 2782 + list_for_each_entry(entity, &handle->chain->dev->entities, list) { 2783 + for (unsigned int i = 0; i < entity->ncontrols; ++i) { 2784 + if (entity->controls[i].handle != handle) 2785 + continue; 2786 + uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); 2787 + } 2788 + } 2789 + 2790 + WARN_ON(handle->pending_async_ctrls); 2813 2791 } 2814 2792 2815 2793 /*
+181 -117
drivers/media/usb/uvc/uvc_driver.c
··· 32 32 33 33 unsigned int uvc_clock_param = CLOCK_MONOTONIC; 34 34 unsigned int uvc_hw_timestamps_param; 35 - unsigned int uvc_no_drop_param; 35 + unsigned int uvc_no_drop_param = 1; 36 36 static unsigned int uvc_quirks_param = -1; 37 37 unsigned int uvc_dbg_param; 38 38 unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT; ··· 220 220 * Descriptors parsing 221 221 */ 222 222 223 + static int uvc_parse_frame(struct uvc_device *dev, 224 + struct uvc_streaming *streaming, 225 + struct uvc_format *format, struct uvc_frame *frame, 226 + u32 **intervals, u8 ftype, int width_multiplier, 227 + const unsigned char *buffer, int buflen) 228 + { 229 + struct usb_host_interface *alts = streaming->intf->cur_altsetting; 230 + unsigned int maxIntervalIndex; 231 + unsigned int interval; 232 + unsigned int i, n; 233 + 234 + if (ftype != UVC_VS_FRAME_FRAME_BASED) 235 + n = buflen > 25 ? buffer[25] : 0; 236 + else 237 + n = buflen > 21 ? buffer[21] : 0; 238 + 239 + n = n ? n : 3; 240 + 241 + if (buflen < 26 + 4 * n) { 242 + uvc_dbg(dev, DESCR, 243 + "device %d videostreaming interface %d FRAME error\n", 244 + dev->udev->devnum, alts->desc.bInterfaceNumber); 245 + return -EINVAL; 246 + } 247 + 248 + frame->bFrameIndex = buffer[3]; 249 + frame->bmCapabilities = buffer[4]; 250 + frame->wWidth = get_unaligned_le16(&buffer[5]) * width_multiplier; 251 + frame->wHeight = get_unaligned_le16(&buffer[7]); 252 + frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); 253 + frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); 254 + if (ftype != UVC_VS_FRAME_FRAME_BASED) { 255 + frame->dwMaxVideoFrameBufferSize = 256 + get_unaligned_le32(&buffer[17]); 257 + frame->dwDefaultFrameInterval = 258 + get_unaligned_le32(&buffer[21]); 259 + frame->bFrameIntervalType = buffer[25]; 260 + } else { 261 + frame->dwMaxVideoFrameBufferSize = 0; 262 + frame->dwDefaultFrameInterval = 263 + get_unaligned_le32(&buffer[17]); 264 + frame->bFrameIntervalType = buffer[21]; 265 + } 266 + 267 + /* 268 + * Copy the frame intervals. 269 + * 270 + * Some bogus devices report dwMinFrameInterval equal to 271 + * dwMaxFrameInterval and have dwFrameIntervalStep set to zero. Setting 272 + * all null intervals to 1 fixes the problem and some other divisions 273 + * by zero that could happen. 274 + */ 275 + frame->dwFrameInterval = *intervals; 276 + 277 + for (i = 0; i < n; ++i) { 278 + interval = get_unaligned_le32(&buffer[26 + 4 * i]); 279 + (*intervals)[i] = interval ? interval : 1; 280 + } 281 + 282 + /* 283 + * Apply more fixes, quirks and workarounds to handle incorrect or 284 + * broken descriptors. 285 + */ 286 + 287 + /* 288 + * Several UVC chipsets screw up dwMaxVideoFrameBufferSize completely. 289 + * Observed behaviours range from setting the value to 1.1x the actual 290 + * frame size to hardwiring the 16 low bits to 0. This results in a 291 + * higher than necessary memory usage as well as a wrong image size 292 + * information. For uncompressed formats this can be fixed by computing 293 + * the value from the frame size. 294 + */ 295 + if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) 296 + frame->dwMaxVideoFrameBufferSize = format->bpp * frame->wWidth 297 + * frame->wHeight / 8; 298 + 299 + /* 300 + * Clamp the default frame interval to the boundaries. A zero 301 + * bFrameIntervalType value indicates a continuous frame interval 302 + * range, with dwFrameInterval[0] storing the minimum value and 303 + * dwFrameInterval[1] storing the maximum value. 304 + */ 305 + maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1; 306 + frame->dwDefaultFrameInterval = 307 + clamp(frame->dwDefaultFrameInterval, 308 + frame->dwFrameInterval[0], 309 + frame->dwFrameInterval[maxIntervalIndex]); 310 + 311 + /* 312 + * Some devices report frame intervals that are not functional. If the 313 + * corresponding quirk is set, restrict operation to the first interval 314 + * only. 315 + */ 316 + if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { 317 + frame->bFrameIntervalType = 1; 318 + (*intervals)[0] = frame->dwDefaultFrameInterval; 319 + } 320 + 321 + uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", 322 + frame->wWidth, frame->wHeight, 323 + 10000000 / frame->dwDefaultFrameInterval, 324 + (100000000 / frame->dwDefaultFrameInterval) % 10); 325 + 326 + *intervals += n; 327 + 328 + return buffer[0]; 329 + } 330 + 223 331 static int uvc_parse_format(struct uvc_device *dev, 224 332 struct uvc_streaming *streaming, struct uvc_format *format, 225 333 struct uvc_frame *frames, u32 **intervals, const unsigned char *buffer, 226 334 int buflen) 227 335 { 228 - struct usb_interface *intf = streaming->intf; 229 - struct usb_host_interface *alts = intf->cur_altsetting; 336 + struct usb_host_interface *alts = streaming->intf->cur_altsetting; 230 337 const struct uvc_format_desc *fmtdesc; 231 338 struct uvc_frame *frame; 232 339 const unsigned char *start = buffer; 233 340 unsigned int width_multiplier = 1; 234 - unsigned int interval; 235 341 unsigned int i, n; 236 342 u8 ftype; 343 + int ret; 237 344 238 345 format->type = buffer[2]; 239 346 format->index = buffer[3]; ··· 478 371 * Parse the frame descriptors. Only uncompressed, MJPEG and frame 479 372 * based formats have frame descriptors. 480 373 */ 481 - while (ftype && buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && 482 - buffer[2] == ftype) { 483 - unsigned int maxIntervalIndex; 484 - 485 - frame = &frames[format->nframes]; 486 - if (ftype != UVC_VS_FRAME_FRAME_BASED) 487 - n = buflen > 25 ? buffer[25] : 0; 488 - else 489 - n = buflen > 21 ? buffer[21] : 0; 490 - 491 - n = n ? n : 3; 492 - 493 - if (buflen < 26 + 4*n) { 494 - uvc_dbg(dev, DESCR, 495 - "device %d videostreaming interface %d FRAME error\n", 496 - dev->udev->devnum, 497 - alts->desc.bInterfaceNumber); 498 - return -EINVAL; 374 + if (ftype) { 375 + while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && 376 + buffer[2] == ftype) { 377 + frame = &frames[format->nframes]; 378 + ret = uvc_parse_frame(dev, streaming, format, frame, 379 + intervals, ftype, width_multiplier, 380 + buffer, buflen); 381 + if (ret < 0) 382 + return ret; 383 + format->nframes++; 384 + buflen -= ret; 385 + buffer += ret; 499 386 } 500 - 501 - frame->bFrameIndex = buffer[3]; 502 - frame->bmCapabilities = buffer[4]; 503 - frame->wWidth = get_unaligned_le16(&buffer[5]) 504 - * width_multiplier; 505 - frame->wHeight = get_unaligned_le16(&buffer[7]); 506 - frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); 507 - frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); 508 - if (ftype != UVC_VS_FRAME_FRAME_BASED) { 509 - frame->dwMaxVideoFrameBufferSize = 510 - get_unaligned_le32(&buffer[17]); 511 - frame->dwDefaultFrameInterval = 512 - get_unaligned_le32(&buffer[21]); 513 - frame->bFrameIntervalType = buffer[25]; 514 - } else { 515 - frame->dwMaxVideoFrameBufferSize = 0; 516 - frame->dwDefaultFrameInterval = 517 - get_unaligned_le32(&buffer[17]); 518 - frame->bFrameIntervalType = buffer[21]; 519 - } 520 - 521 - /* 522 - * Copy the frame intervals. 523 - * 524 - * Some bogus devices report dwMinFrameInterval equal to 525 - * dwMaxFrameInterval and have dwFrameIntervalStep set to 526 - * zero. Setting all null intervals to 1 fixes the problem and 527 - * some other divisions by zero that could happen. 528 - */ 529 - frame->dwFrameInterval = *intervals; 530 - 531 - for (i = 0; i < n; ++i) { 532 - interval = get_unaligned_le32(&buffer[26+4*i]); 533 - (*intervals)[i] = interval ? interval : 1; 534 - } 535 - 536 - /* 537 - * Apply more fixes, quirks and workarounds to handle incorrect 538 - * or broken descriptors. 539 - */ 540 - 541 - /* 542 - * Several UVC chipsets screw up dwMaxVideoFrameBufferSize 543 - * completely. Observed behaviours range from setting the 544 - * value to 1.1x the actual frame size to hardwiring the 545 - * 16 low bits to 0. This results in a higher than necessary 546 - * memory usage as well as a wrong image size information. For 547 - * uncompressed formats this can be fixed by computing the 548 - * value from the frame size. 549 - */ 550 - if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) 551 - frame->dwMaxVideoFrameBufferSize = format->bpp 552 - * frame->wWidth * frame->wHeight / 8; 553 - 554 - /* 555 - * Clamp the default frame interval to the boundaries. A zero 556 - * bFrameIntervalType value indicates a continuous frame 557 - * interval range, with dwFrameInterval[0] storing the minimum 558 - * value and dwFrameInterval[1] storing the maximum value. 559 - */ 560 - maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1; 561 - frame->dwDefaultFrameInterval = 562 - clamp(frame->dwDefaultFrameInterval, 563 - frame->dwFrameInterval[0], 564 - frame->dwFrameInterval[maxIntervalIndex]); 565 - 566 - /* 567 - * Some devices report frame intervals that are not functional. 568 - * If the corresponding quirk is set, restrict operation to the 569 - * first interval only. 570 - */ 571 - if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { 572 - frame->bFrameIntervalType = 1; 573 - (*intervals)[0] = frame->dwDefaultFrameInterval; 574 - } 575 - 576 - uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", 577 - frame->wWidth, frame->wHeight, 578 - 10000000 / frame->dwDefaultFrameInterval, 579 - (100000000 / frame->dwDefaultFrameInterval) % 10); 580 - 581 - format->nframes++; 582 - *intervals += n; 583 - 584 - buflen -= buffer[0]; 585 - buffer += buffer[0]; 586 387 } 587 388 588 389 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && ··· 1310 1295 struct gpio_desc *gpio_privacy; 1311 1296 int irq; 1312 1297 1313 - gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", 1298 + gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy", 1314 1299 GPIOD_IN); 1315 1300 if (IS_ERR_OR_NULL(gpio_privacy)) 1316 1301 return PTR_ERR_OR_ZERO(gpio_privacy); 1317 1302 1318 1303 irq = gpiod_to_irq(gpio_privacy); 1319 1304 if (irq < 0) 1320 - return dev_err_probe(&dev->udev->dev, irq, 1305 + return dev_err_probe(&dev->intf->dev, irq, 1321 1306 "No IRQ for privacy GPIO\n"); 1322 1307 1323 1308 unit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT, ··· 1344 1329 static int uvc_gpio_init_irq(struct uvc_device *dev) 1345 1330 { 1346 1331 struct uvc_entity *unit = dev->gpio_unit; 1332 + int ret; 1347 1333 1348 1334 if (!unit || unit->gpio.irq < 0) 1349 1335 return 0; 1350 1336 1351 - return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, 1352 - uvc_gpio_irq, 1353 - IRQF_ONESHOT | IRQF_TRIGGER_FALLING | 1354 - IRQF_TRIGGER_RISING, 1355 - "uvc_privacy_gpio", dev); 1337 + ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq, 1338 + IRQF_ONESHOT | IRQF_TRIGGER_FALLING | 1339 + IRQF_TRIGGER_RISING, 1340 + "uvc_privacy_gpio", dev); 1341 + 1342 + unit->gpio.initialized = !ret; 1343 + 1344 + return ret; 1345 + } 1346 + 1347 + static void uvc_gpio_deinit(struct uvc_device *dev) 1348 + { 1349 + if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) 1350 + return; 1351 + 1352 + free_irq(dev->gpio_unit->gpio.irq, dev); 1356 1353 } 1357 1354 1358 1355 /* ------------------------------------------------------------------------ ··· 1961 1934 { 1962 1935 struct uvc_streaming *stream; 1963 1936 1937 + uvc_gpio_deinit(dev); 1938 + 1964 1939 list_for_each_entry(stream, &dev->streams, list) { 1965 1940 /* Nothing to do here, continue. */ 1966 1941 if (!video_is_registered(&stream->vdev)) ··· 2024 1995 int ret; 2025 1996 2026 1997 /* Initialize the video buffers queue. */ 2027 - ret = uvc_queue_init(queue, type, !uvc_no_drop_param); 1998 + ret = uvc_queue_init(queue, type); 2028 1999 if (ret) 2029 2000 return ret; 2030 2001 ··· 2453 2424 MODULE_PARM_DESC(clock, "Video buffers timestamp clock"); 2454 2425 module_param_named(hwtimestamps, uvc_hw_timestamps_param, uint, 0644); 2455 2426 MODULE_PARM_DESC(hwtimestamps, "Use hardware timestamps"); 2456 - module_param_named(nodrop, uvc_no_drop_param, uint, 0644); 2427 + 2428 + static int param_set_nodrop(const char *val, const struct kernel_param *kp) 2429 + { 2430 + pr_warn_once("uvcvideo: " 2431 + DEPRECATED 2432 + "nodrop parameter will be eventually removed.\n"); 2433 + return param_set_bool(val, kp); 2434 + } 2435 + 2436 + static const struct kernel_param_ops param_ops_nodrop = { 2437 + .set = param_set_nodrop, 2438 + .get = param_get_uint, 2439 + }; 2440 + 2441 + param_check_uint(nodrop, &uvc_no_drop_param); 2442 + module_param_cb(nodrop, &param_ops_nodrop, &uvc_no_drop_param, 0644); 2443 + __MODULE_PARM_TYPE(nodrop, "uint"); 2457 2444 MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames"); 2445 + 2458 2446 module_param_named(quirks, uvc_quirks_param, uint, 0644); 2459 2447 MODULE_PARM_DESC(quirks, "Forced device quirks"); 2460 2448 module_param_named(trace, uvc_dbg_param, uint, 0644); ··· 2848 2802 .bInterfaceSubClass = 1, 2849 2803 .bInterfaceProtocol = 0, 2850 2804 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, 2805 + /* Sonix Technology Co. Ltd. - 292A IPC AR0330 */ 2806 + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2807 + | USB_DEVICE_ID_MATCH_INT_INFO, 2808 + .idVendor = 0x0c45, 2809 + .idProduct = 0x6366, 2810 + .bInterfaceClass = USB_CLASS_VIDEO, 2811 + .bInterfaceSubClass = 1, 2812 + .bInterfaceProtocol = 0, 2813 + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, 2851 2814 /* MT6227 */ 2852 2815 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2853 2816 | USB_DEVICE_ID_MATCH_INT_INFO, ··· 2885 2830 .bInterfaceSubClass = 1, 2886 2831 .bInterfaceProtocol = 0, 2887 2832 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, 2833 + /* Kurokesu C1 PRO */ 2834 + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2835 + | USB_DEVICE_ID_MATCH_INT_INFO, 2836 + .idVendor = 0x16d0, 2837 + .idProduct = 0x0ed1, 2838 + .bInterfaceClass = USB_CLASS_VIDEO, 2839 + .bInterfaceSubClass = 1, 2840 + .bInterfaceProtocol = 0, 2841 + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_MJPEG_NO_EOF) }, 2888 2842 /* Syntek (HP Spartan) */ 2889 2843 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE 2890 2844 | USB_DEVICE_ID_MATCH_INT_INFO,
+4 -5
drivers/media/usb/uvc/uvc_queue.c
··· 208 208 .stop_streaming = uvc_stop_streaming, 209 209 }; 210 210 211 - int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, 212 - int drop_corrupted) 211 + int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type) 213 212 { 214 213 int ret; 215 214 ··· 238 239 mutex_init(&queue->mutex); 239 240 spin_lock_init(&queue->irqlock); 240 241 INIT_LIST_HEAD(&queue->irqqueue); 241 - queue->flags = drop_corrupted ? UVC_QUEUE_DROP_CORRUPTED : 0; 242 242 243 243 return 0; 244 244 } ··· 470 472 struct vb2_buffer *vb = &buf->buf.vb2_buf; 471 473 struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); 472 474 473 - if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { 475 + if (buf->error && !uvc_no_drop_param) { 474 476 uvc_queue_buffer_requeue(queue, buf); 475 477 return; 476 478 } 477 479 478 480 buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; 479 481 vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); 480 - vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); 482 + vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR : 483 + VB2_BUF_STATE_DONE); 481 484 } 482 485 483 486 /*
+6 -2
drivers/media/usb/uvc/uvc_status.c
··· 262 262 if (ep == NULL) 263 263 return 0; 264 264 265 - uvc_input_init(dev); 266 - 267 265 dev->status = kzalloc(sizeof(*dev->status), GFP_KERNEL); 268 266 if (!dev->status) 269 267 return -ENOMEM; ··· 269 271 dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); 270 272 if (!dev->int_urb) { 271 273 kfree(dev->status); 274 + dev->status = NULL; 272 275 return -ENOMEM; 273 276 } 274 277 ··· 288 289 dev->status, sizeof(*dev->status), uvc_status_complete, 289 290 dev, interval); 290 291 292 + uvc_input_init(dev); 293 + 291 294 return 0; 292 295 } 293 296 294 297 void uvc_status_unregister(struct uvc_device *dev) 295 298 { 299 + if (!dev->status) 300 + return; 301 + 296 302 uvc_status_suspend(dev); 297 303 uvc_input_unregister(dev); 298 304 }
+45 -119
drivers/media/usb/uvc/uvc_v4l2.c
··· 26 26 27 27 #include "uvcvideo.h" 28 28 29 + static int uvc_acquire_privileges(struct uvc_fh *handle); 30 + 29 31 static int uvc_control_add_xu_mapping(struct uvc_video_chain *chain, 30 32 struct uvc_control_mapping *map, 31 33 const struct uvc_xu_control_mapping *xmap) ··· 363 361 return ret; 364 362 } 365 363 366 - static int uvc_v4l2_get_format(struct uvc_streaming *stream, 367 - struct v4l2_format *fmt) 364 + static int uvc_ioctl_g_fmt(struct file *file, void *fh, 365 + struct v4l2_format *fmt) 368 366 { 367 + struct uvc_fh *handle = fh; 368 + struct uvc_streaming *stream = handle->stream; 369 369 const struct uvc_format *format; 370 370 const struct uvc_frame *frame; 371 371 int ret = 0; ··· 399 395 return ret; 400 396 } 401 397 402 - static int uvc_v4l2_set_format(struct uvc_streaming *stream, 403 - struct v4l2_format *fmt) 398 + static int uvc_ioctl_s_fmt(struct file *file, void *fh, 399 + struct v4l2_format *fmt) 404 400 { 401 + struct uvc_fh *handle = fh; 402 + struct uvc_streaming *stream = handle->stream; 405 403 struct uvc_streaming_control probe; 406 404 const struct uvc_format *format; 407 405 const struct uvc_frame *frame; 408 406 int ret; 407 + 408 + ret = uvc_acquire_privileges(handle); 409 + if (ret < 0) 410 + return ret; 409 411 410 412 if (fmt->type != stream->type) 411 413 return -EINVAL; ··· 436 426 return ret; 437 427 } 438 428 439 - static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, 440 - struct v4l2_streamparm *parm) 429 + static int uvc_ioctl_g_parm(struct file *file, void *fh, 430 + struct v4l2_streamparm *parm) 441 431 { 442 432 u32 numerator, denominator; 433 + struct uvc_fh *handle = fh; 434 + struct uvc_streaming *stream = handle->stream; 443 435 444 436 if (parm->type != stream->type) 445 437 return -EINVAL; ··· 473 461 return 0; 474 462 } 475 463 476 - static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, 477 - struct v4l2_streamparm *parm) 464 + static int uvc_ioctl_s_parm(struct file *file, void *fh, 465 + struct v4l2_streamparm *parm) 478 466 { 467 + struct uvc_fh *handle = fh; 468 + struct uvc_streaming *stream = handle->stream; 479 469 struct uvc_streaming_control probe; 480 470 struct v4l2_fract timeperframe; 481 471 const struct uvc_format *format; ··· 485 471 u32 interval, maxd; 486 472 unsigned int i; 487 473 int ret; 474 + 475 + ret = uvc_acquire_privileges(handle); 476 + if (ret < 0) 477 + return ret; 488 478 489 479 if (parm->type != stream->type) 490 480 return -EINVAL; ··· 591 573 * - VIDIOC_S_INPUT 592 574 * - VIDIOC_S_PARM 593 575 * - VIDIOC_S_FMT 576 + * - VIDIOC_CREATE_BUFS 594 577 * - VIDIOC_REQBUFS 595 578 */ 596 579 static int uvc_acquire_privileges(struct uvc_fh *handle) ··· 671 652 672 653 uvc_dbg(stream->dev, CALLS, "%s\n", __func__); 673 654 655 + uvc_ctrl_cleanup_fh(handle); 656 + 674 657 /* Only free resources if this is a privileged handle. */ 675 658 if (uvc_has_privileges(handle)) 676 659 uvc_queue_release(&stream->queue); ··· 706 685 return 0; 707 686 } 708 687 709 - static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, 688 + static int uvc_ioctl_enum_fmt(struct file *file, void *fh, 710 689 struct v4l2_fmtdesc *fmt) 711 690 { 712 - const struct uvc_format *format; 691 + struct uvc_fh *handle = fh; 692 + struct uvc_streaming *stream = handle->stream; 713 693 enum v4l2_buf_type type = fmt->type; 694 + const struct uvc_format *format; 714 695 u32 index = fmt->index; 715 696 716 697 if (fmt->type != stream->type || fmt->index >= stream->nformats) ··· 730 707 return 0; 731 708 } 732 709 733 - static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh, 734 - struct v4l2_fmtdesc *fmt) 735 - { 736 - struct uvc_fh *handle = fh; 737 - struct uvc_streaming *stream = handle->stream; 738 - 739 - return uvc_ioctl_enum_fmt(stream, fmt); 740 - } 741 - 742 - static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh, 743 - struct v4l2_fmtdesc *fmt) 744 - { 745 - struct uvc_fh *handle = fh; 746 - struct uvc_streaming *stream = handle->stream; 747 - 748 - return uvc_ioctl_enum_fmt(stream, fmt); 749 - } 750 - 751 - static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh, 752 - struct v4l2_format *fmt) 753 - { 754 - struct uvc_fh *handle = fh; 755 - struct uvc_streaming *stream = handle->stream; 756 - 757 - return uvc_v4l2_get_format(stream, fmt); 758 - } 759 - 760 - static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh, 761 - struct v4l2_format *fmt) 762 - { 763 - struct uvc_fh *handle = fh; 764 - struct uvc_streaming *stream = handle->stream; 765 - 766 - return uvc_v4l2_get_format(stream, fmt); 767 - } 768 - 769 - static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh, 770 - struct v4l2_format *fmt) 771 - { 772 - struct uvc_fh *handle = fh; 773 - struct uvc_streaming *stream = handle->stream; 774 - int ret; 775 - 776 - ret = uvc_acquire_privileges(handle); 777 - if (ret < 0) 778 - return ret; 779 - 780 - return uvc_v4l2_set_format(stream, fmt); 781 - } 782 - 783 - static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh, 784 - struct v4l2_format *fmt) 785 - { 786 - struct uvc_fh *handle = fh; 787 - struct uvc_streaming *stream = handle->stream; 788 - int ret; 789 - 790 - ret = uvc_acquire_privileges(handle); 791 - if (ret < 0) 792 - return ret; 793 - 794 - return uvc_v4l2_set_format(stream, fmt); 795 - } 796 - 797 - static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh, 798 - struct v4l2_format *fmt) 799 - { 800 - struct uvc_fh *handle = fh; 801 - struct uvc_streaming *stream = handle->stream; 802 - struct uvc_streaming_control probe; 803 - 804 - return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL); 805 - } 806 - 807 - static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh, 808 - struct v4l2_format *fmt) 710 + static int uvc_ioctl_try_fmt(struct file *file, void *fh, 711 + struct v4l2_format *fmt) 809 712 { 810 713 struct uvc_fh *handle = fh; 811 714 struct uvc_streaming *stream = handle->stream; ··· 1161 1212 return 0; 1162 1213 } 1163 1214 1164 - static int uvc_ioctl_g_parm(struct file *file, void *fh, 1165 - struct v4l2_streamparm *parm) 1166 - { 1167 - struct uvc_fh *handle = fh; 1168 - struct uvc_streaming *stream = handle->stream; 1169 - 1170 - return uvc_v4l2_get_streamparm(stream, parm); 1171 - } 1172 - 1173 - static int uvc_ioctl_s_parm(struct file *file, void *fh, 1174 - struct v4l2_streamparm *parm) 1175 - { 1176 - struct uvc_fh *handle = fh; 1177 - struct uvc_streaming *stream = handle->stream; 1178 - int ret; 1179 - 1180 - ret = uvc_acquire_privileges(handle); 1181 - if (ret < 0) 1182 - return ret; 1183 - 1184 - return uvc_v4l2_set_streamparm(stream, parm); 1185 - } 1186 - 1187 1215 static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, 1188 1216 struct v4l2_frmsizeenum *fsize) 1189 1217 { ··· 1469 1543 #endif 1470 1544 1471 1545 const struct v4l2_ioctl_ops uvc_ioctl_ops = { 1546 + .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt, 1547 + .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt, 1548 + .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt, 1549 + .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt, 1550 + .vidioc_g_parm = uvc_ioctl_g_parm, 1551 + .vidioc_s_parm = uvc_ioctl_s_parm, 1472 1552 .vidioc_querycap = uvc_ioctl_querycap, 1473 - .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap, 1474 - .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out, 1475 - .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap, 1476 - .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out, 1477 - .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap, 1478 - .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out, 1479 - .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap, 1480 - .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out, 1553 + .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt, 1554 + .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt, 1555 + .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt, 1556 + .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt, 1481 1557 .vidioc_reqbufs = uvc_ioctl_reqbufs, 1482 1558 .vidioc_querybuf = uvc_ioctl_querybuf, 1483 1559 .vidioc_qbuf = uvc_ioctl_qbuf, ··· 1498 1570 .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls, 1499 1571 .vidioc_querymenu = uvc_ioctl_querymenu, 1500 1572 .vidioc_g_selection = uvc_ioctl_g_selection, 1501 - .vidioc_g_parm = uvc_ioctl_g_parm, 1502 - .vidioc_s_parm = uvc_ioctl_s_parm, 1503 1573 .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes, 1504 1574 .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals, 1505 1575 .vidioc_subscribe_event = uvc_ioctl_subscribe_event,
+55 -4
drivers/media/usb/uvc/uvc_video.c
··· 20 20 #include <linux/atomic.h> 21 21 #include <linux/unaligned.h> 22 22 23 + #include <media/jpeg.h> 23 24 #include <media/v4l2-common.h> 24 25 25 26 #include "uvcvideo.h" ··· 80 79 if (likely(ret == size)) 81 80 return 0; 82 81 82 + /* 83 + * Some devices return shorter USB control packets than expected if the 84 + * returned value can fit in less bytes. Zero all the bytes that the 85 + * device has not written. 86 + * 87 + * This quirk is applied to all controls, regardless of their data type. 88 + * Most controls are little-endian integers, in which case the missing 89 + * bytes become 0 MSBs. For other data types, a different heuristic 90 + * could be implemented if a device is found needing it. 91 + * 92 + * We exclude UVC_GET_INFO from the quirk. UVC_GET_LEN does not need 93 + * to be excluded because its size is always 1. 94 + */ 95 + if (ret > 0 && query != UVC_GET_INFO) { 96 + memset(data + ret, 0, size - ret); 97 + dev_warn_once(&dev->udev->dev, 98 + "UVC non compliance: %s control %u on unit %u returned %d bytes when we expected %u.\n", 99 + uvc_query_name(query), cs, unit, ret, size); 100 + return 0; 101 + } 102 + 83 103 if (ret != -EPIPE) { 84 104 dev_err(&dev->udev->dev, 85 105 "Failed to query (%s) UVC control %u on unit %u: %d (exp. %u).\n", ··· 118 96 error = *(u8 *)data; 119 97 *(u8 *)data = tmp; 120 98 121 - if (ret != 1) 99 + if (ret != 1) { 100 + dev_err_ratelimited(&dev->udev->dev, 101 + "Failed to query (%s) UVC error code control %u on unit %u: %d (exp. 1).\n", 102 + uvc_query_name(query), cs, unit, ret); 122 103 return ret < 0 ? ret : -EPIPE; 104 + } 123 105 124 106 uvc_dbg(dev, CONTROL, "Control error %u\n", error); 125 107 ··· 323 297 goto out; 324 298 } else if (ret != size) { 325 299 dev_err(&stream->intf->dev, 326 - "Failed to query (%u) UVC %s control : %d (exp. %u).\n", 327 - query, probe ? "probe" : "commit", ret, size); 300 + "Failed to query (%s) UVC %s control : %d (exp. %u).\n", 301 + uvc_query_name(query), probe ? "probe" : "commit", 302 + ret, size); 328 303 ret = (ret == -EPROTO) ? -EPROTO : -EIO; 329 304 goto out; 330 305 } ··· 1143 1116 static int uvc_video_decode_start(struct uvc_streaming *stream, 1144 1117 struct uvc_buffer *buf, const u8 *data, int len) 1145 1118 { 1119 + u8 header_len; 1146 1120 u8 fid; 1147 1121 1148 1122 /* ··· 1157 1129 return -EINVAL; 1158 1130 } 1159 1131 1132 + header_len = data[0]; 1160 1133 fid = data[1] & UVC_STREAM_FID; 1161 1134 1162 1135 /* ··· 1239 1210 return -EAGAIN; 1240 1211 } 1241 1212 1213 + /* 1214 + * Some cameras, when running two parallel streams (one MJPEG alongside 1215 + * another non-MJPEG stream), are known to lose the EOF packet for a frame. 1216 + * We can detect the end of a frame by checking for a new SOI marker, as 1217 + * the SOI always lies on the packet boundary between two frames for 1218 + * these devices. 1219 + */ 1220 + if (stream->dev->quirks & UVC_QUIRK_MJPEG_NO_EOF && 1221 + (stream->cur_format->fcc == V4L2_PIX_FMT_MJPEG || 1222 + stream->cur_format->fcc == V4L2_PIX_FMT_JPEG)) { 1223 + const u8 *packet = data + header_len; 1224 + 1225 + if (len >= header_len + 2 && 1226 + packet[0] == 0xff && packet[1] == JPEG_MARKER_SOI && 1227 + buf->bytesused != 0) { 1228 + buf->state = UVC_BUF_STATE_READY; 1229 + buf->error = 1; 1230 + stream->last_fid ^= UVC_STREAM_FID; 1231 + return -EAGAIN; 1232 + } 1233 + } 1234 + 1242 1235 stream->last_fid = fid; 1243 1236 1244 - return data[0]; 1237 + return header_len; 1245 1238 } 1246 1239 1247 1240 static inline enum dma_data_direction uvc_stream_dir(
+11 -4
drivers/media/usb/uvc/uvcvideo.h
··· 76 76 #define UVC_QUIRK_NO_RESET_RESUME 0x00004000 77 77 #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000 78 78 #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000 79 + #define UVC_QUIRK_MJPEG_NO_EOF 0x00020000 79 80 80 81 /* Format flags */ 81 82 #define UVC_FMT_FLAG_COMPRESSED 0x00000001 ··· 235 234 u8 *bmControls; 236 235 struct gpio_desc *gpio_privacy; 237 236 int irq; 237 + bool initialized; 238 238 } gpio; 239 239 }; 240 240 ··· 318 316 }; 319 317 320 318 #define UVC_QUEUE_DISCONNECTED (1 << 0) 321 - #define UVC_QUEUE_DROP_CORRUPTED (1 << 1) 322 319 323 320 struct uvc_video_queue { 324 321 struct vb2_queue queue; ··· 338 337 struct uvc_entity *processing; /* Processing unit */ 339 338 struct uvc_entity *selector; /* Selector unit */ 340 339 341 - struct mutex ctrl_mutex; /* Protects ctrl.info */ 340 + struct mutex ctrl_mutex; /* 341 + * Protects ctrl.info, 342 + * ctrl.handle and 343 + * uvc_fh.pending_async_ctrls 344 + */ 342 345 343 346 struct v4l2_prio_state prio; /* V4L2 priority state */ 344 347 u32 caps; /* V4L2 chain-wide caps */ ··· 617 612 struct uvc_video_chain *chain; 618 613 struct uvc_streaming *stream; 619 614 enum uvc_handle_state state; 615 + unsigned int pending_async_ctrls; 620 616 }; 621 617 622 618 struct uvc_driver { ··· 680 674 struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); 681 675 682 676 /* Video buffers queue management. */ 683 - int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, 684 - int drop_corrupted); 677 + int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type); 685 678 void uvc_queue_release(struct uvc_video_queue *queue); 686 679 int uvc_request_buffers(struct uvc_video_queue *queue, 687 680 struct v4l2_requestbuffers *rb); ··· 801 796 802 797 int uvc_xu_ctrl_query(struct uvc_video_chain *chain, 803 798 struct uvc_xu_control_query *xqry); 799 + 800 + void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); 804 801 805 802 /* Utility functions */ 806 803 struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
+42 -1
drivers/media/v4l2-core/v4l2-fwnode.c
··· 127 127 { 128 128 struct v4l2_mbus_config_mipi_csi2 *bus = &vep->bus.mipi_csi2; 129 129 bool have_clk_lane = false, have_data_lanes = false, 130 - have_lane_polarities = false; 130 + have_lane_polarities = false, have_line_orders = false; 131 131 unsigned int flags = 0, lanes_used = 0; 132 132 u32 array[1 + V4L2_MBUS_CSI2_MAX_DATA_LANES]; 133 133 u32 clock_lane = 0; ··· 197 197 have_lane_polarities = true; 198 198 } 199 199 200 + rval = fwnode_property_count_u32(fwnode, "line-orders"); 201 + if (rval > 0) { 202 + if (rval != num_data_lanes) { 203 + pr_warn("invalid number of line-orders entries (need %u, got %u)\n", 204 + num_data_lanes, rval); 205 + return -EINVAL; 206 + } 207 + 208 + have_line_orders = true; 209 + } 210 + 200 211 if (!fwnode_property_read_u32(fwnode, "clock-lanes", &v)) { 201 212 clock_lane = v; 202 213 pr_debug("clock lane position %u\n", v); ··· 260 249 } 261 250 } else { 262 251 pr_debug("no lane polarities defined, assuming not inverted\n"); 252 + } 253 + 254 + if (have_line_orders) { 255 + fwnode_property_read_u32_array(fwnode, 256 + "line-orders", array, 257 + num_data_lanes); 258 + 259 + for (i = 0; i < num_data_lanes; i++) { 260 + static const char * const orders[] = { 261 + "ABC", "ACB", "BAC", "BCA", "CAB", "CBA" 262 + }; 263 + 264 + if (array[i] >= ARRAY_SIZE(orders)) { 265 + pr_warn("lane %u invalid line-order assuming ABC (got %u)\n", 266 + i, array[i]); 267 + bus->line_orders[i] = 268 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ABC; 269 + continue; 270 + } 271 + 272 + bus->line_orders[i] = array[i]; 273 + pr_debug("lane %u line order %s", i, 274 + orders[array[i]]); 275 + } 276 + } else { 277 + for (i = 0; i < num_data_lanes; i++) 278 + bus->line_orders[i] = 279 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ABC; 280 + 281 + pr_debug("no line orders defined, assuming ABC\n"); 263 282 } 264 283 } 265 284
+1 -1
drivers/media/v4l2-core/v4l2-mc.c
··· 329 329 if (!(sink->flags & MEDIA_PAD_FL_SINK)) 330 330 return -EINVAL; 331 331 332 - fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) { 332 + fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) { 333 333 struct fwnode_handle *remote_ep; 334 334 int src_idx, sink_idx, ret; 335 335 struct media_pad *src;
-18
drivers/soc/mediatek/mtk-cmdq-helper.c
··· 524 524 } 525 525 EXPORT_SYMBOL(cmdq_pkt_eoc); 526 526 527 - int cmdq_pkt_finalize(struct cmdq_pkt *pkt) 528 - { 529 - struct cmdq_instruction inst = { {0} }; 530 - int err; 531 - 532 - /* insert EOC and generate IRQ for each command iteration */ 533 - err = cmdq_pkt_eoc(pkt); 534 - if (err < 0) 535 - return err; 536 - 537 - /* JUMP to end */ 538 - inst.op = CMDQ_CODE_JUMP; 539 - inst.value = CMDQ_JUMP_PASS >> 540 - cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan); 541 - return cmdq_pkt_append_command(pkt, inst); 542 - } 543 - EXPORT_SYMBOL(cmdq_pkt_finalize); 544 - 545 527 MODULE_DESCRIPTION("MediaTek Command Queue (CMDQ) driver"); 546 528 MODULE_LICENSE("GPL v2");
+2 -6
drivers/staging/media/imx/imx-media-of.c
··· 54 54 break; 55 55 56 56 ret = imx_media_of_add_csi(imxmd, csi_np); 57 + of_node_put(csi_np); 57 58 if (ret) { 58 59 /* unavailable or already added is not an error */ 59 60 if (ret == -ENODEV || ret == -EEXIST) { 60 - of_node_put(csi_np); 61 61 continue; 62 62 } 63 63 64 64 /* other error, can't continue */ 65 - goto err_out; 65 + return ret; 66 66 } 67 67 } 68 68 69 69 return 0; 70 - 71 - err_out: 72 - of_node_put(csi_np); 73 - return ret; 74 70 } 75 71 EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs);
+2 -2
drivers/staging/media/max96712/max96712.c
··· 418 418 priv->info = of_device_get_match_data(&client->dev); 419 419 420 420 priv->client = client; 421 - i2c_set_clientdata(client, priv); 422 421 423 422 priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap); 424 423 if (IS_ERR(priv->regmap)) ··· 447 448 448 449 static void max96712_remove(struct i2c_client *client) 449 450 { 450 - struct max96712_priv *priv = i2c_get_clientdata(client); 451 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 452 + struct max96712_priv *priv = container_of(sd, struct max96712_priv, sd); 451 453 452 454 v4l2_async_unregister_subdev(&priv->sd); 453 455
+7
include/dt-bindings/media/video-interfaces.h
··· 13 13 #define MEDIA_BUS_TYPE_PARALLEL 5 14 14 #define MEDIA_BUS_TYPE_BT656 6 15 15 16 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_ABC 0 17 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_ACB 1 18 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_BAC 2 19 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_BCA 3 20 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CAB 4 21 + #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CBA 5 22 + 16 23 #endif /* __DT_BINDINGS_MEDIA_VIDEO_INTERFACES_H__ */
-13
include/linux/soc/mediatek/mtk-cmdq.h
··· 391 391 */ 392 392 int cmdq_pkt_eoc(struct cmdq_pkt *pkt); 393 393 394 - /** 395 - * cmdq_pkt_finalize() - Append EOC and jump command to pkt. 396 - * @pkt: the CMDQ packet 397 - * 398 - * Return: 0 for success; else the error code is returned 399 - */ 400 - int cmdq_pkt_finalize(struct cmdq_pkt *pkt); 401 - 402 394 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */ 403 395 404 396 static inline int cmdq_dev_get_client_reg(struct device *dev, ··· 507 515 } 508 516 509 517 static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt) 510 - { 511 - return -EINVAL; 512 - } 513 - 514 - static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt) 515 518 { 516 519 return -EINVAL; 517 520 }
-1
include/media/cec.h
··· 10 10 11 11 #include <linux/poll.h> 12 12 #include <linux/fs.h> 13 - #include <linux/debugfs.h> 14 13 #include <linux/device.h> 15 14 #include <linux/cdev.h> 16 15 #include <linux/kthread.h>
+21
include/media/v4l2-mediabus.h
··· 74 74 #define V4L2_MBUS_CSI2_MAX_DATA_LANES 8 75 75 76 76 /** 77 + * enum v4l2_mbus_csi2_cphy_line_orders_type - CSI-2 C-PHY line order 78 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ABC: C-PHY line order ABC (default) 79 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ACB: C-PHY line order ACB 80 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BAC: C-PHY line order BAC 81 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BCA: C-PHY line order BCA 82 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CAB: C-PHY line order CAB 83 + * @V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CBA: C-PHY line order CBA 84 + */ 85 + enum v4l2_mbus_csi2_cphy_line_orders_type { 86 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ABC, 87 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_ACB, 88 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BAC, 89 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_BCA, 90 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CAB, 91 + V4L2_MBUS_CSI2_CPHY_LINE_ORDER_CBA, 92 + }; 93 + 94 + /** 77 95 * struct v4l2_mbus_config_mipi_csi2 - MIPI CSI-2 data bus configuration 78 96 * @flags: media bus (V4L2_MBUS_*) flags 79 97 * @data_lanes: an array of physical data lane indexes ··· 99 81 * @num_data_lanes: number of data lanes 100 82 * @lane_polarities: polarity of the lanes. The order is the same of 101 83 * the physical lanes. 84 + * @line_orders: line order of the data lanes. The order is the same of the 85 + * physical lanes. 102 86 */ 103 87 struct v4l2_mbus_config_mipi_csi2 { 104 88 unsigned int flags; ··· 108 88 unsigned char clock_lane; 109 89 unsigned char num_data_lanes; 110 90 bool lane_polarities[1 + V4L2_MBUS_CSI2_MAX_DATA_LANES]; 91 + enum v4l2_mbus_csi2_cphy_line_orders_type line_orders[V4L2_MBUS_CSI2_MAX_DATA_LANES]; 111 92 }; 112 93 113 94 /**