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.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

- New CEC driver: Extron DA HD 4K Plus

- Lots of driver fixes, cleanups and improvements

* tag 'media/v6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (179 commits)
media: atomisp: Use clamp() in ia_css_eed1_8_vmem_encode()
media: atomisp: Fix eed1_8 code assigning signed values to an unsigned variable
media: atomisp: set lock before calling vb2_queue_init()
media: atomisp: Improve binary finding debug logging
media: atomisp: Drop dev_dbg() calls from hmm_[alloc|free]()
media: atomisp: csi2-bridge: Add DMI quirk for t4ka3 on Xiaomi Mipad2
media: atomisp: add missing wait_prepare/finish ops
media: atomisp: Remove unused declaration
media: atomisp: use clamp() in compute_coring()
media: atomisp: use clamp() in ia_css_eed1_8_encode()
media: atomisp: Simplify ia_css_pipe_create_cas_scaler_desc_single_output()
media: atomisp: Replace rarely used macro from math_support.h
media: atomisp: Remove duplicated leftover, i.e. sh_css_dvs_info.h
media: atomisp: bnr: fix trailing statement
media: atomisp: move trailing */ to separate lines
media: atomisp: move trailing statement to next line.
media: atomisp: Fix trailing statement in ia_css_de.host.c
media: atomisp: Fix spelling mistakes in atomisp.h
media: atomisp: Fix spelling mistakes in atomisp_platform.h
media: atomisp: Fix spelling mistake in csi_rx_public.h
...

+7390 -1369
+87
Documentation/admin-guide/media/cec.rst
··· 42 42 ``persistent_config``: by default this is off, but when set to 1 the driver 43 43 will store the current settings to the device's internal eeprom and restore 44 44 it the next time the device is connected to the USB port. 45 + 45 46 - RainShadow Tech. Note: this driver does not support the persistent_config 46 47 module option of the Pulse-Eight driver. The hardware supports it, but I 47 48 have no plans to add this feature. But I accept patches :-) 49 + 50 + - Extron DA HD 4K PLUS HDMI Distribution Amplifier. See 51 + :ref:`extron_da_hd_4k_plus` for more information. 48 52 49 53 Miscellaneous: 50 54 ··· 382 378 383 379 You can also use this as a full-fledged CEC device by configuring it 384 380 using ``cec-ctl --tv -p0.0.0.0`` or ``cec-ctl --playback -p1.0.0.0``. 381 + 382 + .. _extron_da_hd_4k_plus: 383 + 384 + Extron DA HD 4K PLUS CEC Adapter driver 385 + ======================================= 386 + 387 + This driver is for the Extron DA HD 4K PLUS series of HDMI Distribution 388 + Amplifiers: https://www.extron.com/product/dahd4kplusseries 389 + 390 + The 2, 4 and 6 port models are supported. 391 + 392 + Firmware version 1.02.0001 or higher is required. 393 + 394 + Note that older Extron hardware revisions have a problem with the CEC voltage, 395 + which may mean that CEC will not work. This is fixed in hardware revisions 396 + E34814 and up. 397 + 398 + The CEC support has two modes: the first is a manual mode where userspace has 399 + to manually control CEC for the HDMI Input and all HDMI Outputs. While this gives 400 + full control, it is also complicated. 401 + 402 + The second mode is an automatic mode, which is selected if the module option 403 + ``vendor_id`` is set. In that case the driver controls CEC and CEC messages 404 + received in the input will be distributed to the outputs. It is still possible 405 + to use the /dev/cecX devices to talk to the connected devices directly, but it is 406 + the driver that configures everything and deals with things like Hotplug Detect 407 + changes. 408 + 409 + The driver also takes care of the EDIDs: /dev/videoX devices are created to 410 + read the EDIDs and (for the HDMI Input port) to set the EDID. 411 + 412 + By default userspace is responsible to set the EDID for the HDMI Input 413 + according to the EDIDs of the connected displays. But if the ``manufacturer_name`` 414 + module option is set, then the driver will take care of setting the EDID 415 + of the HDMI Input based on the supported resolutions of the connected displays. 416 + Currently the driver only supports resolutions 1080p60 and 4kp60: if all connected 417 + displays support 4kp60, then it will advertise 4kp60 on the HDMI input, otherwise 418 + it will fall back to an EDID that just reports 1080p60. 419 + 420 + The status of the Extron is reported in ``/sys/kernel/debug/cec/cecX/status``. 421 + 422 + The extron-da-hd-4k-plus driver implements the following module options: 423 + 424 + ``debug`` 425 + --------- 426 + 427 + If set to 1, then all serial port traffic is shown. 428 + 429 + ``vendor_id`` 430 + ------------- 431 + 432 + The CEC Vendor ID to report to connected displays. 433 + 434 + If set, then the driver will take care of distributing CEC messages received 435 + on the input to the HDMI outputs. This is done for the following CEC messages: 436 + 437 + - <Standby> 438 + - <Image View On> and <Text View On> 439 + - <Give Device Power Status> 440 + - <Set System Audio Mode> 441 + - <Request Current Latency> 442 + 443 + If not set, then userspace is responsible for this, and it will have to 444 + configure the CEC devices for HDMI Input and the HDMI Outputs manually. 445 + 446 + ``manufacturer_name`` 447 + --------------------- 448 + 449 + A three character manufacturer name that is used in the EDID for the HDMI 450 + Input. If not set, then userspace is reponsible for configuring an EDID. 451 + If set, then the driver will update the EDID automatically based on the 452 + resolutions supported by the connected displays, and it will not be possible 453 + anymore to manually set the EDID for the HDMI Input. 454 + 455 + ``hpd_never_low`` 456 + ----------------- 457 + 458 + If set, then the Hotplug Detect pin of the HDMI Input will always be high, 459 + even if nothing is connected to the HDMI Outputs. If not set (the default) 460 + then the Hotplug Detect pin of the HDMI input will go low if all the detected 461 + Hotplug Detect pins of the HDMI Outputs are also low. 462 + 463 + This option may be changed dynamically.
+14 -9
Documentation/admin-guide/media/mgb4.rst
··· 227 227 open.* 228 228 229 229 **frame_rate** (RW): 230 - Output video frame rate in frames per second. The default frame rate is 231 - 60Hz. 230 + Output video signal frame rate limit in frames per second. Due to 231 + the limited output pixel clock steps, the card can not always generate 232 + a frame rate perfectly matching the value required by the connected display. 233 + Using this parameter one can limit the frame rate by "crippling" the signal 234 + so that the lines are not equal (the porches of the last line differ) but 235 + the signal appears like having the exact frame rate to the connected display. 236 + The default frame rate limit is 60Hz. 232 237 233 238 **hsync_polarity** (RW): 234 239 HSYNC signal polarity. ··· 258 253 and there is a non-linear stepping between two consecutive allowed 259 254 frequencies. The driver finds the nearest allowed frequency to the given 260 255 value and sets it. When reading this property, you get the exact 261 - frequency set by the driver. The default frequency is 70000kHz. 256 + frequency set by the driver. The default frequency is 61150kHz. 262 257 263 258 *Note: This parameter can not be changed while the output v4l2 device is 264 259 open.* 265 260 266 261 **hsync_width** (RW): 267 - Width of the HSYNC signal in pixels. The default value is 16. 262 + Width of the HSYNC signal in pixels. The default value is 40. 268 263 269 264 **vsync_width** (RW): 270 - Width of the VSYNC signal in video lines. The default value is 2. 265 + Width of the VSYNC signal in video lines. The default value is 20. 271 266 272 267 **hback_porch** (RW): 273 268 Number of PCLK pulses between deassertion of the HSYNC signal and the first 274 - valid pixel in the video line (marked by DE=1). The default value is 32. 269 + valid pixel in the video line (marked by DE=1). The default value is 50. 275 270 276 271 **hfront_porch** (RW): 277 272 Number of PCLK pulses between the end of the last valid pixel in the video 278 273 line (marked by DE=1) and assertion of the HSYNC signal. The default value 279 - is 32. 274 + is 50. 280 275 281 276 **vback_porch** (RW): 282 277 Number of video lines between deassertion of the VSYNC signal and the video 283 - line with the first valid pixel (marked by DE=1). The default value is 2. 278 + line with the first valid pixel (marked by DE=1). The default value is 31. 284 279 285 280 **vfront_porch** (RW): 286 281 Number of video lines between the end of the last valid pixel line (marked 287 - by DE=1) and assertion of the VSYNC signal. The default value is 2. 282 + by DE=1) and assertion of the VSYNC signal. The default value is 30. 288 283 289 284 FPDL3 specific input parameters 290 285 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+9 -2
Documentation/admin-guide/media/rkisp1.rst
··· 114 114 to dynamically modify values such as black level, cross talk corrections 115 115 and others. 116 116 117 - The buffer format is defined by struct :c:type:`rkisp1_params_cfg`, and 118 - userspace should set 117 + The ISP driver supports two different parameters configuration methods, the 118 + `fixed parameters format` or the `extensible parameters format`. 119 + 120 + When using the `fixed parameters` method the buffer format is defined by struct 121 + :c:type:`rkisp1_params_cfg`, and userspace should set 119 122 :ref:`V4L2_META_FMT_RK_ISP1_PARAMS <v4l2-meta-fmt-rk-isp1-params>` as the 120 123 dataformat. 121 124 125 + When using the `extensible parameters` method the buffer format is defined by 126 + struct :c:type:`rkisp1_ext_params_cfg`, and userspace should set 127 + :ref:`V4L2_META_FMT_RK_ISP1_EXT_PARAMS <v4l2-meta-fmt-rk-isp1-ext-params>` as 128 + the dataformat. 122 129 123 130 Capturing Video Frames Example 124 131 ==============================
+2 -2
Documentation/admin-guide/media/vivid.rst
··· 1343 1343 Just as a reminder and in no particular order: 1344 1344 1345 1345 - Add a virtual alsa driver to test audio 1346 - - Add virtual sub-devices and media controller support 1346 + - Add virtual sub-devices 1347 1347 - Some support for testing compressed video 1348 1348 - Add support to loop raw VBI output to raw VBI input 1349 1349 - Add support to loop teletext sliced VBI output to VBI input ··· 1358 1358 - Make a thread for the RDS generation, that would help in particular for the 1359 1359 "Controls" RDS Rx I/O Mode as the read-only RDS controls could be updated 1360 1360 in real-time. 1361 - - Changing the EDID should cause hotplug detect emulation to happen. 1361 + - Changing the EDID doesn't wait 100 ms before setting the HPD signal.
+2 -1
Documentation/devicetree/bindings/media/amlogic,gx-vdec.yaml
··· 31 31 - items: 32 32 - enum: 33 33 - amlogic,gxbb-vdec # GXBB (S905) 34 - - amlogic,gxl-vdec # GXL (S905X, S905D) 34 + - amlogic,gxl-vdec # GXL (S905D, S905W, S905X, S905Y) 35 + - amlogic,gxlx-vdec # GXLX (S905L) 35 36 - amlogic,gxm-vdec # GXM (S912) 36 37 - const: amlogic,gx-vdec 37 38 - enum:
+107
Documentation/devicetree/bindings/media/i2c/ovti,og01a1b.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (c) 2023-2024 Linaro Ltd. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/media/i2c/ovti,og01a1b.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: OmniVision OG01A1B Image Sensor 9 + 10 + maintainers: 11 + - Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org> 12 + 13 + description: 14 + The OmniVision OG01A1B is black and white CMOS 1.3 Megapixel (1280x1024) 15 + image sensor controlled over an I2C-compatible SCCB bus. 16 + The sensor transmits images on a MIPI CSI-2 output interface with one or 17 + two data lanes. 18 + 19 + allOf: 20 + - $ref: /schemas/media/video-interface-devices.yaml# 21 + 22 + properties: 23 + compatible: 24 + const: ovti,og01a1b 25 + 26 + reg: 27 + maxItems: 1 28 + 29 + clocks: 30 + maxItems: 1 31 + 32 + reset-gpios: 33 + description: Active low GPIO connected to XSHUTDOWN pad of the sensor. 34 + maxItems: 1 35 + 36 + strobe-gpios: 37 + description: Input GPIO connected to strobe pad of the sensor. 38 + maxItems: 1 39 + 40 + avdd-supply: 41 + description: Analogue circuit voltage supply. 42 + 43 + dovdd-supply: 44 + description: I/O circuit voltage supply. 45 + 46 + dvdd-supply: 47 + description: Digital circuit voltage supply. 48 + 49 + port: 50 + $ref: /schemas/graph.yaml#/$defs/port-base 51 + additionalProperties: false 52 + description: 53 + Output port node, single endpoint describing the CSI-2 transmitter. 54 + 55 + properties: 56 + endpoint: 57 + $ref: /schemas/media/video-interfaces.yaml# 58 + unevaluatedProperties: false 59 + 60 + properties: 61 + data-lanes: 62 + minItems: 1 63 + maxItems: 2 64 + items: 65 + enum: [1, 2] 66 + 67 + link-frequencies: true 68 + 69 + required: 70 + - data-lanes 71 + - link-frequencies 72 + 73 + required: 74 + - compatible 75 + - reg 76 + - clocks 77 + - port 78 + 79 + unevaluatedProperties: false 80 + 81 + examples: 82 + - | 83 + #include <dt-bindings/gpio/gpio.h> 84 + 85 + i2c { 86 + #address-cells = <1>; 87 + #size-cells = <0>; 88 + 89 + sensor@60 { 90 + compatible = "ovti,og01a1b"; 91 + reg = <0x60>; 92 + clocks = <&clk 0>; 93 + reset-gpios = <&gpio 117 GPIO_ACTIVE_LOW>; 94 + avdd-supply = <&vreg_3v3>; 95 + dovdd-supply = <&vreg_1p8>; 96 + dvdd-supply = <&vreg_1p2>; 97 + 98 + port { 99 + og01a1b_ep: endpoint { 100 + remote-endpoint = <&csiphy_ep>; 101 + data-lanes = <1 2>; 102 + link-frequencies = /bits/ 64 <500000000>; 103 + }; 104 + }; 105 + }; 106 + }; 107 + ...
+4
Documentation/devicetree/bindings/media/i2c/sony,imx335.yaml
··· 75 75 76 76 examples: 77 77 - | 78 + #include <dt-bindings/gpio/gpio.h> 79 + 78 80 i2c { 79 81 #address-cells = <1>; 80 82 #size-cells = <0>; ··· 93 91 avdd-supply = <&camera_vdda_2v9>; 94 92 ovdd-supply = <&camera_vddo_1v8>; 95 93 dvdd-supply = <&camera_vddd_1v2>; 94 + 95 + reset-gpios = <&gpio 50 GPIO_ACTIVE_LOW>; 96 96 97 97 port { 98 98 imx335: endpoint {
+1
Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml
··· 43 43 - const: vcodec_bus 44 44 45 45 iommus: 46 + minItems: 1 46 47 maxItems: 2 47 48 48 49 interconnects:
+2
Documentation/devicetree/bindings/media/renesas,fcp.yaml
··· 27 27 - renesas,fcpf # FCP for FDP 28 28 - items: 29 29 - enum: 30 + - renesas,r9a07g043u-fcpvd # RZ/G2UL 30 31 - renesas,r9a07g044-fcpvd # RZ/G2{L,LC} 31 32 - renesas,r9a07g054-fcpvd # RZ/V2L 32 33 - const: renesas,fcpv # Generic FCP for VSP fallback ··· 63 62 compatible: 64 63 contains: 65 64 enum: 65 + - renesas,r9a07g043u-fcpvd 66 66 - renesas,r9a07g044-fcpvd 67 67 - renesas,r9a07g054-fcpvd 68 68 then:
+4
Documentation/devicetree/bindings/media/renesas,vin.yaml
··· 52 52 - renesas,vin-r8a77980 # R-Car V3H 53 53 - renesas,vin-r8a77990 # R-Car E3 54 54 - renesas,vin-r8a77995 # R-Car D3 55 + - items: 56 + - enum: 55 57 - renesas,vin-r8a779a0 # R-Car V3U 56 58 - renesas,vin-r8a779g0 # R-Car V4H 59 + - renesas,vin-r8a779h0 # R-Car V4M 60 + - const: renesas,rcar-gen4-vin # Generic R-Car Gen4 57 61 58 62 reg: 59 63 maxItems: 1
+1
Documentation/devicetree/bindings/media/renesas,vsp1.yaml
··· 23 23 - renesas,vsp2 # R-Car Gen3 and RZ/G2 24 24 - items: 25 25 - enum: 26 + - renesas,r9a07g043u-vsp2 # RZ/G2UL 26 27 - renesas,r9a07g054-vsp2 # RZ/V2L 27 28 - const: renesas,r9a07g044-vsp2 # RZ/G2L fallback 28 29
+1
Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml
··· 17 17 compatible: 18 18 enum: 19 19 - rockchip,rk3568-vepu 20 + - rockchip,rk3588-vepu121 20 21 21 22 reg: 22 23 maxItems: 1
+6 -1
Documentation/devicetree/bindings/media/rockchip-vpu.yaml
··· 26 26 - rockchip,rk3568-vpu 27 27 - rockchip,rk3588-av1-vpu 28 28 - items: 29 - - const: rockchip,rk3188-vpu 29 + - enum: 30 + - rockchip,rk3128-vpu 31 + - rockchip,rk3188-vpu 30 32 - const: rockchip,rk3066-vpu 31 33 - items: 32 34 - const: rockchip,rk3228-vpu 33 35 - const: rockchip,rk3399-vpu 36 + - items: 37 + - const: rockchip,rk3588-vpu121 38 + - const: rockchip,rk3568-vpu 34 39 35 40 reg: 36 41 maxItems: 1
+41 -26
Documentation/driver-api/media/mc-core.rst
··· 144 144 Graph traversal 145 145 ^^^^^^^^^^^^^^^ 146 146 147 - The media framework provides APIs to iterate over entities in a graph. 147 + The media framework provides APIs to traverse media graphs, locating connected 148 + entities and links. 148 149 149 150 To iterate over all entities belonging to a media device, drivers can use 150 151 the media_device_for_each_entity macro, defined in ··· 159 158 // entity will point to each entity in turn 160 159 ... 161 160 } 162 - 163 - Drivers might also need to iterate over all entities in a graph that can be 164 - reached only through enabled links starting at a given entity. The media 165 - framework provides a depth-first graph traversal API for that purpose. 166 - 167 - .. note:: 168 - 169 - Graphs with cycles (whether directed or undirected) are **NOT** 170 - supported by the graph traversal API. To prevent infinite loops, the graph 171 - traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``, 172 - currently defined as 16. 173 - 174 - Drivers initiate a graph traversal by calling 175 - :c:func:`media_graph_walk_start()` 176 - 177 - The graph structure, provided by the caller, is initialized to start graph 178 - traversal at the given entity. 179 - 180 - Drivers can then retrieve the next entity by calling 181 - :c:func:`media_graph_walk_next()` 182 - 183 - When the graph traversal is complete the function will return ``NULL``. 184 - 185 - Graph traversal can be interrupted at any moment. No cleanup function call 186 - is required and the graph structure can be freed normally. 187 161 188 162 Helper functions can be used to find a link between two given pads, or a pad 189 163 connected to another pad through an enabled link ··· 251 275 Subsystems should facilitate link validation by providing subsystem specific 252 276 helper functions to provide easy access for commonly needed information, and 253 277 in the end provide a way to use driver-specific callbacks. 278 + 279 + Pipeline traversal 280 + ^^^^^^^^^^^^^^^^^^ 281 + 282 + Once a pipeline has been constructed with :c:func:`media_pipeline_start()`, 283 + drivers can iterate over entities or pads in the pipeline with the 284 + :c:macro:´media_pipeline_for_each_entity` and 285 + :c:macro:´media_pipeline_for_each_pad` macros. Iterating over pads is 286 + straightforward: 287 + 288 + .. code-block:: c 289 + 290 + media_pipeline_pad_iter iter; 291 + struct media_pad *pad; 292 + 293 + media_pipeline_for_each_pad(pipe, &iter, pad) { 294 + /* 'pad' will point to each pad in turn */ 295 + ... 296 + } 297 + 298 + To iterate over entities, the iterator needs to be initialized and cleaned up 299 + as an additional steps: 300 + 301 + .. code-block:: c 302 + 303 + media_pipeline_entity_iter iter; 304 + struct media_entity *entity; 305 + int ret; 306 + 307 + ret = media_pipeline_entity_iter_init(pipe, &iter); 308 + if (ret) 309 + ...; 310 + 311 + media_pipeline_for_each_entity(pipe, &iter, entity) { 312 + /* 'entity' will point to each entity in turn */ 313 + ... 314 + } 315 + 316 + media_pipeline_entity_iter_cleanup(&iter); 254 317 255 318 Media Controller Device Allocator API 256 319 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+6
Documentation/userspace-api/media/cec/cec-ioc-adap-g-caps.rst
··· 137 137 - 0x00000100 138 138 - If this capability is set, then :ref:`CEC_ADAP_G_CONNECTOR_INFO` can 139 139 be used. 140 + * .. _`CEC-CAP-REPLY-VENDOR-ID`: 141 + 142 + - ``CEC_CAP_REPLY_VENDOR_ID`` 143 + - 0x00000200 144 + - If this capability is set, then 145 + :ref:`CEC_MSG_FL_REPLY_VENDOR_ID <cec-msg-flags>` can be used. 140 146 141 147 Return Value 142 148 ============
+15
Documentation/userspace-api/media/cec/cec-ioc-receive.rst
··· 232 232 capability. If that is not set, then the ``EPERM`` error code is 233 233 returned. 234 234 235 + * .. _`CEC-MSG-FL-REPLY-VENDOR-ID`: 236 + 237 + - ``CEC_MSG_FL_REPLY_VENDOR_ID`` 238 + - 4 239 + - This flag is only available if the ``CEC_CAP_REPLY_VENDOR_ID`` capability 240 + is set. If this flag is set, then the reply is expected to consist of 241 + the ``CEC_MSG_VENDOR_COMMAND_WITH_ID`` opcode followed by the Vendor ID 242 + (in bytes 1-4 of the message), followed by the ``struct cec_msg`` 243 + ``reply`` field. 244 + 245 + Note that this assumes that the byte after the Vendor ID is a 246 + vendor-specific opcode. 247 + 248 + This flag makes it easier to wait for replies to vendor commands. 249 + 235 250 .. tabularcolumns:: |p{5.6cm}|p{0.9cm}|p{10.8cm}| 236 251 237 252 .. _cec-tx-status:
+11
Documentation/userspace-api/media/v4l/biblio.rst
··· 334 334 335 335 :author: Video Electronics Standards Association (http://www.vesa.org) 336 336 337 + .. _vesaeddc: 338 + 339 + E-DDC 340 + ===== 341 + 342 + 343 + :title: VESA Enhanced Display Data Channel (E-DDC) Standard 344 + :subtitle: Version 1.3 345 + 346 + :author: Video Electronics Standards Association (http://www.vesa.org) 347 + 337 348 .. _vesaedid: 338 349 339 350 EDID
-35
Documentation/userspace-api/media/v4l/buffer.rst
··· 694 694 - 4 695 695 - The buffer is used for :ref:`DMA shared buffer <dmabuf>` I/O. 696 696 697 - .. _memory-flags: 698 - 699 - Memory Consistency Flags 700 - ------------------------ 701 - 702 - .. raw:: latex 703 - 704 - \small 705 - 706 - .. tabularcolumns:: |p{7.0cm}|p{2.1cm}|p{8.4cm}| 707 - 708 - .. cssclass:: longtable 709 - 710 - .. flat-table:: 711 - :header-rows: 0 712 - :stub-columns: 0 713 - :widths: 3 1 4 714 - 715 - * .. _`V4L2-MEMORY-FLAG-NON-COHERENT`: 716 - 717 - - ``V4L2_MEMORY_FLAG_NON_COHERENT`` 718 - - 0x00000001 719 - - A buffer is allocated either in coherent (it will be automatically 720 - coherent between the CPU and the bus) or non-coherent memory. The 721 - latter can provide performance gains, for instance the CPU cache 722 - sync/flush operations can be avoided if the buffer is accessed by the 723 - corresponding device only and the CPU does not read/write to/from that 724 - buffer. However, this requires extra care from the driver -- it must 725 - guarantee memory consistency by issuing a cache flush/sync when 726 - consistency is needed. If this flag is set V4L2 will attempt to 727 - allocate the buffer in non-coherent memory. The flag takes effect 728 - only if the buffer is used for :ref:`memory mapping <mmap>` I/O and the 729 - queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS 730 - <V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability. 731 - 732 697 .. raw:: latex 733 698 734 699 \normalsize
+3 -3
Documentation/userspace-api/media/v4l/capture.c.rst
··· 333 333 if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { 334 334 if (EINVAL == errno) { 335 335 fprintf(stderr, "%s does not support " 336 - "memory mappingn", dev_name); 336 + "memory mapping\n", dev_name); 337 337 exit(EXIT_FAILURE); 338 338 } else { 339 339 errno_exit("VIDIOC_REQBUFS"); ··· 391 391 if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { 392 392 if (EINVAL == errno) { 393 393 fprintf(stderr, "%s does not support " 394 - "user pointer i/on", dev_name); 394 + "user pointer i/o\n", dev_name); 395 395 exit(EXIT_FAILURE); 396 396 } else { 397 397 errno_exit("VIDIOC_REQBUFS"); ··· 547 547 } 548 548 549 549 if (!S_ISCHR(st.st_mode)) { 550 - fprintf(stderr, "%s is no devicen", dev_name); 550 + fprintf(stderr, "%s is no device\n", dev_name); 551 551 exit(EXIT_FAILURE); 552 552 } 553 553
+12 -8
Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst
··· 2993 2993 - Applications and drivers must set this to zero. 2994 2994 * - __u16 2995 2995 - ``max_frame_width_minus_1`` 2996 - - specifies the maximum frame width minus 1 for the frames represented by 2996 + - Specifies the maximum frame width minus 1 for the frames represented by 2997 + this sequence header. 2998 + * - __u16 2999 + - ``max_frame_height_minus_1`` 3000 + - Specifies the maximum frame height minus 1 for the frames represented by 2997 3001 this sequence header. 2998 3002 2999 3003 .. _av1_sequence_flags: ··· 3378 3374 - ``uv_pri_strength[V4L2_AV1_CDEF_MAX]`` 3379 3375 - Specifies the strength of the primary filter. 3380 3376 * - __u8 3381 - - ``uv_secondary_strength[V4L2_AV1_CDEF_MAX]`` 3377 + - ``uv_sec_strength[V4L2_AV1_CDEF_MAX]`` 3382 3378 - Specifies the strength of the secondary filter. 3383 3379 3384 3380 .. c:type:: v4l2_av1_segment_feature ··· 3443 3439 - Bitmask defining which features are enabled in each segment. Use 3444 3440 V4L2_AV1_SEGMENT_FEATURE_ENABLED to build a suitable mask. 3445 3441 * - __u16 3446 - - `feature_data[V4L2_AV1_MAX_SEGMENTS][V4L2_AV1_SEG_LVL_MAX]`` 3442 + - ``feature_data[V4L2_AV1_MAX_SEGMENTS][V4L2_AV1_SEG_LVL_MAX]`` 3447 3443 - Data attached to each feature. Data entry is only valid if the feature 3448 3444 is enabled. 3449 3445 ··· 3494 3490 3495 3491 .. tabularcolumns:: |p{1.5cm}|p{5.8cm}|p{10.0cm}| 3496 3492 3497 - .. flat-table:: struct v4l2_av1_global_motion 3493 + .. flat-table:: struct v4l2_av1_loop_filter 3498 3494 :header-rows: 0 3499 3495 :stub-columns: 0 3500 3496 :widths: 1 1 2 ··· 3810 3806 * - struct :c:type:`v4l2_av1_quantization` 3811 3807 - ``quantization`` 3812 3808 - Quantization parameters. 3813 - * - struct :c:type:`v4l2_av1_segmentation` 3814 - - ``segmentation`` 3815 - - Segmentation parameters. 3816 3809 * - __u8 3817 3810 - ``superres_denom`` 3818 3811 - The denominator for the upscaling ratio. 3812 + * - struct :c:type:`v4l2_av1_segmentation` 3813 + - ``segmentation`` 3814 + - Segmentation parameters. 3819 3815 * - struct :c:type:`v4l2_av1_loop_filter` 3820 3816 - ``loop_filter`` 3821 3817 - Loop filter params ··· 3833 3829 * - struct :c:type:`v4l2_av1_loop_restoration` 3834 3830 - ``loop_restoration`` 3835 3831 - Loop restoration parameters. 3836 - * - struct :c:type:`v4l2_av1_loop_global_motion` 3832 + * - struct :c:type:`v4l2_av1_global_motion` 3837 3833 - ``global_motion`` 3838 3834 - Global motion parameters. 3839 3835 * - __u32
+1 -1
Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
··· 31 31 Pixel sampling rate in the device's pixel array. This control is 32 32 read-only and its unit is pixels / second. 33 33 34 - Some devices use horizontal and vertical balanking to configure the frame 34 + Some devices use horizontal and vertical blanking to configure the frame 35 35 rate. The frame rate can be calculated from the pixel rate, analogue crop 36 36 rectangle as well as horizontal and vertical blanking. The pixel rate 37 37 control may be present in a different sub-device than the blanking controls
+48 -9
Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst
··· 1 1 .. SPDX-License-Identifier: GPL-2.0 2 2 3 - .. _v4l2-meta-fmt-rk-isp1-params: 4 - 5 3 .. _v4l2-meta-fmt-rk-isp1-stat-3a: 6 4 7 - ***************************************************************************** 8 - V4L2_META_FMT_RK_ISP1_PARAMS ('rk1p'), V4L2_META_FMT_RK_ISP1_STAT_3A ('rk1s') 9 - ***************************************************************************** 5 + ************************************************************************************************************************ 6 + V4L2_META_FMT_RK_ISP1_PARAMS ('rk1p'), V4L2_META_FMT_RK_ISP1_STAT_3A ('rk1s'), V4L2_META_FMT_RK_ISP1_EXT_PARAMS ('rk1e') 7 + ************************************************************************************************************************ 10 8 9 + ======================== 11 10 Configuration parameters 12 11 ======================== 13 12 14 - The configuration parameters are passed to the 13 + The configuration of the RkISP1 ISP is performed by userspace by providing 14 + parameters for the ISP to the driver using the :c:type:`v4l2_meta_format` 15 + interface. 16 + 17 + There are two methods that allow to configure the ISP, the `fixed parameters` 18 + configuration format and the `extensible parameters` configuration 19 + format. 20 + 21 + .. _v4l2-meta-fmt-rk-isp1-params: 22 + 23 + Fixed parameters configuration format 24 + ===================================== 25 + 26 + When using the fixed configuration format, parameters are passed to the 15 27 :ref:`rkisp1_params <rkisp1_params>` metadata output video node, using 16 - the :c:type:`v4l2_meta_format` interface. The buffer contains 17 - a single instance of the C structure :c:type:`rkisp1_params_cfg` defined in 18 - ``rkisp1-config.h``. So the structure can be obtained from the buffer by: 28 + the `V4L2_META_FMT_RK_ISP1_PARAMS` meta format. 29 + 30 + The buffer contains a single instance of the C structure 31 + :c:type:`rkisp1_params_cfg` defined in ``rkisp1-config.h``. So the structure can 32 + be obtained from the buffer by: 19 33 20 34 .. code-block:: c 21 35 22 36 struct rkisp1_params_cfg *params = (struct rkisp1_params_cfg*) buffer; 23 37 38 + This method supports a subset of the ISP features only, new applications should 39 + use the extensible parameters method. 40 + 41 + .. _v4l2-meta-fmt-rk-isp1-ext-params: 42 + 43 + Extensible parameters configuration format 44 + ========================================== 45 + 46 + When using the extensible configuration format, parameters are passed to the 47 + :ref:`rkisp1_params <rkisp1_params>` metadata output video node, using 48 + the `V4L2_META_FMT_RK_ISP1_EXT_PARAMS` meta format. 49 + 50 + The buffer contains a single instance of the C structure 51 + :c:type:`rkisp1_ext_params_cfg` defined in ``rkisp1-config.h``. The 52 + :c:type:`rkisp1_ext_params_cfg` structure is designed to allow userspace to 53 + populate the data buffer with only the configuration data for the ISP blocks it 54 + intends to configure. The extensible parameters format design allows developers 55 + to define new block types to support new configuration parameters, and defines a 56 + versioning scheme so that it can be extended and versioned without breaking 57 + compatibility with existing applications. 58 + 59 + For these reasons, this configuration method is preferred over the `fixed 60 + parameters` format alternative. 61 + 24 62 .. rkisp1_stat_buffer 25 63 64 + =========================== 26 65 3A and histogram statistics 27 66 =========================== 28 67
+315
Documentation/userspace-api/media/v4l/mt2110t.svg
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <!-- SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later --> 3 + <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 4 + <svg version="1.2" width="140mm" height="220mm" viewBox="0 0 14000 22000" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xml:space="preserve"> 5 + <defs class="ClipPathGroup"> 6 + <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse"> 7 + <rect x="0" y="0" width="14000" height="22000"/> 8 + </clipPath> 9 + <clipPath id="presentation_clip_path_shrink" clipPathUnits="userSpaceOnUse"> 10 + <rect x="14" y="22" width="13972" height="21956"/> 11 + </clipPath> 12 + </defs> 13 + <defs> 14 + <font id="EmbeddedFont_1" horiz-adv-x="2048"> 15 + <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/> 16 + <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/> 17 + <glyph unicode="y" horiz-adv-x="1033" d="M 191,-425 C 142,-425 100,-421 67,-414 L 67,-279 C 92,-283 120,-285 151,-285 263,-285 352,-203 417,-38 L 434,5 5,1082 197,1082 425,484 C 428,475 432,464 437,451 442,438 457,394 482,320 507,246 521,205 523,196 L 593,393 830,1082 1020,1082 604,0 C 559,-115 518,-201 479,-258 440,-314 398,-356 351,-384 304,-411 250,-425 191,-425 Z"/> 18 + <glyph unicode="x" horiz-adv-x="1006" d="M 801,0 L 510,444 217,0 23,0 408,556 41,1082 240,1082 510,661 778,1082 979,1082 612,558 1002,0 801,0 Z"/> 19 + <glyph unicode="w" horiz-adv-x="1509" d="M 1174,0 L 965,0 776,765 740,934 C 734,904 725,861 712,805 699,748 631,480 508,0 L 300,0 -3,1082 175,1082 358,347 C 363,331 377,265 401,149 L 418,223 644,1082 837,1082 1026,339 1072,149 1103,288 1308,1082 1484,1082 1174,0 Z"/> 20 + <glyph unicode="u" horiz-adv-x="874" d="M 314,1082 L 314,396 C 314,325 321,269 335,230 349,191 371,162 402,145 433,128 478,119 537,119 624,119 692,149 742,208 792,267 817,350 817,455 L 817,1082 997,1082 997,231 C 997,105 999,28 1003,0 L 833,0 C 832,3 832,12 831,27 830,42 830,59 829,78 828,97 826,132 825,185 L 822,185 C 781,110 733,58 679,27 624,-4 557,-20 476,-20 357,-20 271,10 216,69 161,128 133,225 133,361 L 133,1082 314,1082 Z"/> 21 + <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 495,-8 434,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 474,127 509,132 554,141 L 554,8 Z"/> 22 + <glyph unicode="s" horiz-adv-x="901" d="M 950,299 C 950,197 912,118 835,63 758,8 650,-20 511,-20 376,-20 273,2 200,47 127,91 79,160 57,254 L 216,285 C 231,227 263,185 311,158 359,131 426,117 511,117 602,117 669,131 712,159 754,187 775,229 775,285 775,328 760,362 731,389 702,416 654,438 589,455 L 460,489 C 357,516 283,542 240,568 196,593 162,624 137,661 112,698 100,743 100,796 100,895 135,970 206,1022 276,1073 378,1099 513,1099 632,1099 727,1078 798,1036 868,994 912,927 931,834 L 769,814 C 759,862 732,899 689,925 645,950 586,963 513,963 432,963 372,951 333,926 294,901 275,864 275,814 275,783 283,758 299,738 315,718 339,701 370,687 401,673 467,654 568,629 663,605 732,583 774,563 816,542 849,520 874,495 898,470 917,442 930,410 943,377 950,340 950,299 Z"/> 23 + <glyph unicode="r" horiz-adv-x="530" d="M 142,0 L 142,830 C 142,906 140,990 136,1082 L 306,1082 C 311,959 314,886 314,861 L 318,861 C 347,954 380,1017 417,1051 454,1085 507,1102 575,1102 599,1102 623,1099 648,1092 L 648,927 C 624,934 592,937 552,937 477,937 420,905 381,841 342,776 322,684 322,564 L 322,0 142,0 Z"/> 24 + <glyph unicode="p" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 488,-20 376,43 319,168 L 314,168 C 317,163 318,106 318,-2 L 318,-425 138,-425 138,861 C 138,972 136,1046 132,1082 L 306,1082 C 307,1079 308,1070 309,1054 310,1037 312,1012 314,978 315,944 316,921 316,908 L 320,908 C 352,975 394,1024 447,1055 500,1086 569,1101 655,1101 788,1101 888,1056 954,967 1020,878 1053,737 1053,546 Z M 864,542 C 864,693 844,800 803,865 762,930 698,962 609,962 538,962 482,947 442,917 401,887 371,840 350,777 329,713 318,630 318,528 318,386 341,281 386,214 431,147 505,113 607,113 696,113 762,146 803,212 844,277 864,387 864,542 Z"/> 25 + <glyph unicode="o" horiz-adv-x="980" d="M 1053,542 C 1053,353 1011,212 928,119 845,26 724,-20 565,-20 407,-20 288,28 207,125 126,221 86,360 86,542 86,915 248,1102 571,1102 736,1102 858,1057 936,966 1014,875 1053,733 1053,542 Z M 864,542 C 864,691 842,800 798,868 753,935 679,969 574,969 469,969 393,935 346,866 299,797 275,689 275,542 275,399 298,292 345,221 391,149 464,113 563,113 671,113 748,148 795,217 841,286 864,395 864,542 Z"/> 26 + <glyph unicode="l" horiz-adv-x="187" d="M 138,0 L 138,1484 318,1484 318,0 138,0 Z"/> 27 + <glyph unicode="i" horiz-adv-x="187" d="M 137,1312 L 137,1484 317,1484 317,1312 137,1312 Z M 137,0 L 137,1082 317,1082 317,0 137,0 Z"/> 28 + <glyph unicode="f" horiz-adv-x="557" d="M 361,951 L 361,0 181,0 181,951 29,951 29,1082 181,1082 181,1204 C 181,1303 203,1374 246,1417 289,1460 356,1482 445,1482 495,1482 537,1478 572,1470 L 572,1333 C 542,1338 515,1341 492,1341 446,1341 413,1329 392,1306 371,1283 361,1240 361,1179 L 361,1082 572,1082 572,951 361,951 Z"/> 29 + <glyph unicode="e" horiz-adv-x="980" d="M 276,503 C 276,379 302,283 353,216 404,149 479,115 578,115 656,115 719,131 766,162 813,193 844,233 861,281 L 1019,236 C 954,65 807,-20 578,-20 418,-20 296,28 213,123 129,218 87,360 87,548 87,727 129,864 213,959 296,1054 416,1102 571,1102 889,1102 1048,910 1048,527 L 1048,503 276,503 Z M 862,641 C 852,755 823,838 775,891 727,943 658,969 568,969 481,969 412,940 361,882 310,823 282,743 278,641 L 862,641 Z"/> 30 + <glyph unicode="b" horiz-adv-x="953" d="M 1053,546 C 1053,169 920,-20 655,-20 573,-20 505,-5 451,25 396,54 352,102 318,168 L 316,168 C 316,147 315,116 312,74 309,31 307,7 306,0 L 132,0 C 136,36 138,110 138,223 L 138,1484 318,1484 318,1061 C 318,1018 317,967 314,908 L 318,908 C 351,977 396,1027 451,1057 506,1087 574,1102 655,1102 792,1102 892,1056 957,964 1021,872 1053,733 1053,546 Z M 864,540 C 864,691 844,800 804,865 764,930 699,963 609,963 508,963 434,928 388,859 341,790 318,680 318,529 318,387 341,282 386,215 431,147 505,113 607,113 698,113 763,147 804,214 844,281 864,389 864,540 Z"/> 31 + <glyph unicode="8" horiz-adv-x="980" d="M 1050,393 C 1050,263 1009,162 926,89 843,16 725,-20 570,-20 419,-20 302,16 217,87 132,158 89,260 89,391 89,483 115,560 168,623 221,686 288,724 370,737 L 370,741 C 293,759 233,798 189,858 144,918 122,988 122,1069 122,1176 162,1263 243,1330 323,1397 431,1430 566,1430 705,1430 814,1397 895,1332 975,1267 1015,1178 1015,1067 1015,986 993,916 948,856 903,796 842,758 765,743 L 765,739 C 855,724 925,686 975,625 1025,563 1050,486 1050,393 Z M 828,1057 C 828,1216 741,1296 566,1296 481,1296 417,1276 373,1236 328,1196 306,1136 306,1057 306,976 329,915 375,873 420,830 485,809 568,809 653,809 717,829 762,868 806,907 828,970 828,1057 Z M 863,410 C 863,497 837,563 785,608 733,652 660,674 566,674 475,674 403,650 352,603 301,555 275,489 275,406 275,212 374,115 572,115 670,115 743,139 791,186 839,233 863,307 863,410 Z"/> 32 + <glyph unicode="6" horiz-adv-x="980" d="M 1049,461 C 1049,312 1009,195 928,109 847,23 736,-20 594,-20 435,-20 314,39 230,157 146,275 104,447 104,672 104,916 148,1103 235,1234 322,1365 447,1430 608,1430 821,1430 955,1334 1010,1143 L 838,1112 C 803,1227 725,1284 606,1284 503,1284 424,1236 368,1141 311,1045 283,906 283,725 316,786 362,832 421,864 480,895 548,911 625,911 755,911 858,870 935,789 1011,708 1049,598 1049,461 Z M 866,453 C 866,555 841,634 791,689 741,744 671,772 582,772 498,772 430,748 379,699 327,650 301,582 301,496 301,387 328,298 382,229 435,160 504,125 588,125 675,125 743,154 792,213 841,271 866,351 866,453 Z"/> 33 + <glyph unicode="4" horiz-adv-x="1060" d="M 881,319 L 881,0 711,0 711,319 47,319 47,459 692,1409 881,1409 881,461 1079,461 1079,319 881,319 Z M 711,1206 C 710,1202 700,1184 683,1153 666,1122 653,1100 644,1087 L 283,555 229,481 213,461 711,461 711,1206 Z"/> 34 + <glyph unicode="3" horiz-adv-x="1006" d="M 1049,389 C 1049,259 1008,158 925,87 842,16 724,-20 571,-20 428,-20 315,12 230,77 145,141 94,236 78,362 L 264,379 C 288,212 390,129 571,129 662,129 733,151 785,196 836,241 862,307 862,395 862,472 833,532 774,575 715,618 629,639 518,639 L 416,639 416,795 514,795 C 613,795 689,817 744,860 798,903 825,962 825,1038 825,1113 803,1173 759,1217 714,1260 648,1282 561,1282 482,1282 418,1262 369,1221 320,1180 291,1123 283,1049 L 102,1063 C 115,1178 163,1268 246,1333 328,1398 434,1430 563,1430 704,1430 814,1397 893,1332 971,1266 1010,1174 1010,1057 1010,967 985,894 935,838 884,781 811,743 715,723 L 715,719 C 820,708 902,672 961,613 1020,554 1049,479 1049,389 Z"/> 35 + <glyph unicode="2" horiz-adv-x="954" d="M 103,0 L 103,127 C 137,205 179,274 228,334 277,393 328,447 382,496 436,544 490,589 543,630 596,671 643,713 686,754 729,795 763,839 790,884 816,929 829,981 829,1038 829,1115 806,1175 761,1218 716,1261 653,1282 572,1282 495,1282 432,1261 383,1220 333,1178 304,1119 295,1044 L 111,1061 C 124,1174 172,1263 255,1330 337,1397 443,1430 572,1430 714,1430 823,1397 900,1330 976,1263 1014,1167 1014,1044 1014,989 1002,935 977,881 952,827 914,773 865,719 816,665 721,581 582,468 505,405 444,349 399,299 354,248 321,200 301,153 L 1036,153 1036,0 103,0 Z"/> 36 + <glyph unicode="1" horiz-adv-x="927" d="M 156,0 L 156,153 515,153 515,1237 197,1010 197,1180 530,1409 696,1409 696,153 1039,153 1039,0 156,0 Z"/> 37 + <glyph unicode=" " horiz-adv-x="556"/> 38 + </font> 39 + </defs> 40 + <defs class="TextShapeIndex"> 41 + <g ooo:slide="id1" ooo:id-list="id3 id4 id5 id6 id7 id8 id9 id10 id11 id12 id13 id14 id15 id16 id17 id18 id19 id20 id21 id22 id23 id24 id25 id26 id27 id28 id29 id30"/> 42 + </defs> 43 + <defs class="EmbeddedBulletChars"> 44 + <g id="bullet-char-template-57356" transform="scale(0.00048828125,-0.00048828125)"> 45 + <path d="M 580,1141 L 1163,571 580,0 -4,571 580,1141 Z"/> 46 + </g> 47 + <g id="bullet-char-template-57354" transform="scale(0.00048828125,-0.00048828125)"> 48 + <path d="M 8,1128 L 1137,1128 1137,0 8,0 8,1128 Z"/> 49 + </g> 50 + <g id="bullet-char-template-10146" transform="scale(0.00048828125,-0.00048828125)"> 51 + <path d="M 174,0 L 602,739 174,1481 1456,739 174,0 Z M 1358,739 L 309,1346 659,739 1358,739 Z"/> 52 + </g> 53 + <g id="bullet-char-template-10132" transform="scale(0.00048828125,-0.00048828125)"> 54 + <path d="M 2015,739 L 1276,0 717,0 1260,543 174,543 174,936 1260,936 717,1481 1274,1481 2015,739 Z"/> 55 + </g> 56 + <g id="bullet-char-template-10007" transform="scale(0.00048828125,-0.00048828125)"> 57 + <path d="M 0,-2 C -7,14 -16,27 -25,37 L 356,567 C 262,823 215,952 215,954 215,979 228,992 255,992 264,992 276,990 289,987 310,991 331,999 354,1012 L 381,999 492,748 772,1049 836,1024 860,1049 C 881,1039 901,1025 922,1006 886,937 835,863 770,784 769,783 710,716 594,584 L 774,223 C 774,196 753,168 711,139 L 727,119 C 717,90 699,76 672,76 641,76 570,178 457,381 L 164,-76 C 142,-110 111,-127 72,-127 30,-127 9,-110 8,-76 1,-67 -2,-52 -2,-32 -2,-23 -1,-13 0,-2 Z"/> 58 + </g> 59 + <g id="bullet-char-template-10004" transform="scale(0.00048828125,-0.00048828125)"> 60 + <path d="M 285,-33 C 182,-33 111,30 74,156 52,228 41,333 41,471 41,549 55,616 82,672 116,743 169,778 240,778 293,778 328,747 346,684 L 369,508 C 377,444 397,411 428,410 L 1163,1116 C 1174,1127 1196,1133 1229,1133 1271,1133 1292,1118 1292,1087 L 1292,965 C 1292,929 1282,901 1262,881 L 442,47 C 390,-6 338,-33 285,-33 Z"/> 61 + </g> 62 + <g id="bullet-char-template-9679" transform="scale(0.00048828125,-0.00048828125)"> 63 + <path d="M 813,0 C 632,0 489,54 383,161 276,268 223,411 223,592 223,773 276,916 383,1023 489,1130 632,1184 813,1184 992,1184 1136,1130 1245,1023 1353,916 1407,772 1407,592 1407,412 1353,268 1245,161 1136,54 992,0 813,0 Z"/> 64 + </g> 65 + <g id="bullet-char-template-8226" transform="scale(0.00048828125,-0.00048828125)"> 66 + <path d="M 346,457 C 273,457 209,483 155,535 101,586 74,649 74,723 74,796 101,859 155,911 209,963 273,989 346,989 419,989 480,963 531,910 582,859 608,796 608,723 608,648 583,586 532,535 482,483 420,457 346,457 Z"/> 67 + </g> 68 + <g id="bullet-char-template-8211" transform="scale(0.00048828125,-0.00048828125)"> 69 + <path d="M -4,459 L 1135,459 1135,606 -4,606 -4,459 Z"/> 70 + </g> 71 + <g id="bullet-char-template-61548" transform="scale(0.00048828125,-0.00048828125)"> 72 + <path d="M 173,740 C 173,903 231,1043 346,1159 462,1274 601,1332 765,1332 928,1332 1067,1274 1183,1159 1299,1043 1357,903 1357,740 1357,577 1299,437 1183,322 1067,206 928,148 765,148 601,148 462,206 346,322 231,437 173,577 173,740 Z"/> 73 + </g> 74 + </defs> 75 + <g> 76 + <g id="id2" class="Master_Slide"> 77 + <g id="bg-id2" class="Background"/> 78 + <g id="bo-id2" class="BackgroundObjects"/> 79 + </g> 80 + </g> 81 + <g class="SlideGroup"> 82 + <g> 83 + <g id="container-id1"> 84 + <g id="id1" class="Slide" clip-path="url(#presentation_clip_path)"> 85 + <g class="Page"> 86 + <g class="com.sun.star.drawing.MeasureShape"> 87 + <g id="id3"> 88 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="325" width="10003" height="15477"/> 89 + <path fill="none" stroke="rgb(0,0,0)" d="M 2037,950 L 11463,950"/> 90 + <path fill="rgb(0,0,0)" stroke="none" d="M 1750,950 L 2050,1050 2050,850 1750,950 Z"/> 91 + <path fill="rgb(0,0,0)" stroke="none" d="M 11750,950 L 11450,850 11450,1050 11750,950 Z"/> 92 + <path fill="none" stroke="rgb(0,0,0)" d="M 1750,15800 L 1750,750"/> 93 + <path fill="none" stroke="rgb(0,0,0)" d="M 11750,1650 L 11750,750"/> 94 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="5953" y="768"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">16 px</tspan></tspan></tspan></text> 95 + </g> 96 + </g> 97 + <g class="com.sun.star.drawing.MeasureShape"> 98 + <g id="id4"> 99 + <rect class="BoundingBox" stroke="none" fill="none" x="11795" y="1649" width="1853" height="19913"/> 100 + <path fill="none" stroke="rgb(0,0,0)" d="M 13446,1937 L 13446,21273"/> 101 + <path fill="rgb(0,0,0)" stroke="none" d="M 13446,1650 L 13346,1950 13546,1950 13446,1650 Z"/> 102 + <path fill="rgb(0,0,0)" stroke="none" d="M 13446,21560 L 13546,21260 13346,21260 13446,21560 Z"/> 103 + <path fill="none" stroke="rgb(0,0,0)" d="M 11796,1650 L 13646,1650"/> 104 + <path fill="none" stroke="rgb(0,0,0)" d="M 11796,21560 L 13646,21560"/> 105 + <text class="SVGTextShape" transform="rotate(-90 13395 12369)"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="13395" y="12369"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">32 px</tspan></tspan></tspan></text> 106 + </g> 107 + </g> 108 + <g class="Group"> 109 + <g class="com.sun.star.drawing.CustomShape"> 110 + <g id="id5"> 111 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="2449" width="10003" height="1753"/> 112 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,4200 L 1750,4200 1750,2450 11750,2450 11750,4200 6750,4200 Z"/> 113 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="3545"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 114 + </g> 115 + </g> 116 + <g class="com.sun.star.drawing.CustomShape"> 117 + <g id="id6"> 118 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="1699" width="10003" height="753"/> 119 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,2450 L 1750,2450 1750,1700 11750,1700 11750,2450 6750,2450 Z"/> 120 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3860" y="2295"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2bits</tspan></tspan></tspan></text> 121 + </g> 122 + </g> 123 + <g class="com.sun.star.drawing.CustomShape"> 124 + <g id="id7"> 125 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="1609" width="10083" height="2583"/> 126 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,4150 L 1750,4150 1750,1650 11750,1650 11750,4150 6750,4150 Z"/> 127 + </g> 128 + </g> 129 + </g> 130 + <g class="com.sun.star.drawing.MeasureShape"> 131 + <g id="id8"> 132 + <rect class="BoundingBox" stroke="none" fill="none" x="385" y="1199" width="1294" height="3971"/> 133 + <path fill="none" stroke="rgb(0,0,0)" d="M 1027,5079 L 1027,2737"/> 134 + <path fill="rgb(0,0,0)" stroke="none" d="M 1027,2450 L 927,2750 1127,2750 1027,2450 Z"/> 135 + <path fill="none" stroke="rgb(0,0,0)" d="M 1027,1413 L 1027,1200"/> 136 + <path fill="rgb(0,0,0)" stroke="none" d="M 1027,1700 L 1127,1400 927,1400 1027,1700 Z"/> 137 + <path fill="none" stroke="rgb(0,0,0)" d="M 1027,2450 L 1027,1700"/> 138 + <path fill="none" stroke="rgb(0,0,0)" d="M 1677,2450 L 827,2450"/> 139 + <path fill="none" stroke="rgb(0,0,0)" d="M 1677,1700 L 827,1700"/> 140 + <text class="SVGTextShape" transform="rotate(-90 845 5217)"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="845" y="5217"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">16 bytes</tspan></tspan></tspan></text> 141 + </g> 142 + </g> 143 + <g class="Group"> 144 + <g class="com.sun.star.drawing.CustomShape"> 145 + <g id="id9"> 146 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="4929" width="10003" height="1753"/> 147 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,6680 L 1750,6680 1750,4930 11750,4930 11750,6680 6750,6680 Z"/> 148 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="6025"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 149 + </g> 150 + </g> 151 + <g class="com.sun.star.drawing.CustomShape"> 152 + <g id="id10"> 153 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="4179" width="10003" height="753"/> 154 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,4930 L 1750,4930 1750,4180 11750,4180 11750,4930 6750,4930 Z"/> 155 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="4775"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 156 + </g> 157 + </g> 158 + <g class="com.sun.star.drawing.CustomShape"> 159 + <g id="id11"> 160 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="4089" width="10083" height="2583"/> 161 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,6630 L 1750,6630 1750,4130 11750,4130 11750,6630 6750,6630 Z"/> 162 + </g> 163 + </g> 164 + </g> 165 + <g class="Group"> 166 + <g class="com.sun.star.drawing.CustomShape"> 167 + <g id="id12"> 168 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="7409" width="10003" height="1753"/> 169 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,9160 L 1750,9160 1750,7410 11750,7410 11750,9160 6750,9160 Z"/> 170 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="8505"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 171 + </g> 172 + </g> 173 + <g class="com.sun.star.drawing.CustomShape"> 174 + <g id="id13"> 175 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="6659" width="10003" height="753"/> 176 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,7410 L 1750,7410 1750,6660 11750,6660 11750,7410 6750,7410 Z"/> 177 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="7255"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 178 + </g> 179 + </g> 180 + <g class="com.sun.star.drawing.CustomShape"> 181 + <g id="id14"> 182 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="6569" width="10083" height="2583"/> 183 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,9110 L 1750,9110 1750,6610 11750,6610 11750,9110 6750,9110 Z"/> 184 + </g> 185 + </g> 186 + </g> 187 + <g class="Group"> 188 + <g class="com.sun.star.drawing.CustomShape"> 189 + <g id="id15"> 190 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="9889" width="10003" height="1753"/> 191 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,11640 L 1750,11640 1750,9890 11750,9890 11750,11640 6750,11640 Z"/> 192 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="10985"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 193 + </g> 194 + </g> 195 + <g class="com.sun.star.drawing.CustomShape"> 196 + <g id="id16"> 197 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="9139" width="10003" height="753"/> 198 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,9890 L 1750,9890 1750,9140 11750,9140 11750,9890 6750,9890 Z"/> 199 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="9735"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 200 + </g> 201 + </g> 202 + <g class="com.sun.star.drawing.CustomShape"> 203 + <g id="id17"> 204 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="9049" width="10083" height="2583"/> 205 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,11590 L 1750,11590 1750,9090 11750,9090 11750,11590 6750,11590 Z"/> 206 + </g> 207 + </g> 208 + </g> 209 + <g class="Group"> 210 + <g class="com.sun.star.drawing.CustomShape"> 211 + <g id="id18"> 212 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="12369" width="10003" height="1753"/> 213 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,14120 L 1750,14120 1750,12370 11750,12370 11750,14120 6750,14120 Z"/> 214 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="13465"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 215 + </g> 216 + </g> 217 + <g class="com.sun.star.drawing.CustomShape"> 218 + <g id="id19"> 219 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="11619" width="10003" height="753"/> 220 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,12370 L 1750,12370 1750,11620 11750,11620 11750,12370 6750,12370 Z"/> 221 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="12215"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 222 + </g> 223 + </g> 224 + <g class="com.sun.star.drawing.CustomShape"> 225 + <g id="id20"> 226 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="11529" width="10083" height="2583"/> 227 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,14070 L 1750,14070 1750,11570 11750,11570 11750,14070 6750,14070 Z"/> 228 + </g> 229 + </g> 230 + </g> 231 + <g class="Group"> 232 + <g class="com.sun.star.drawing.CustomShape"> 233 + <g id="id21"> 234 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="14849" width="10003" height="1753"/> 235 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,16600 L 1750,16600 1750,14850 11750,14850 11750,16600 6750,16600 Z"/> 236 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="15945"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 237 + </g> 238 + </g> 239 + <g class="com.sun.star.drawing.CustomShape"> 240 + <g id="id22"> 241 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="14099" width="10003" height="753"/> 242 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,14850 L 1750,14850 1750,14100 11750,14100 11750,14850 6750,14850 Z"/> 243 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="14695"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 244 + </g> 245 + </g> 246 + <g class="com.sun.star.drawing.CustomShape"> 247 + <g id="id23"> 248 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="14009" width="10083" height="2583"/> 249 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,16550 L 1750,16550 1750,14050 11750,14050 11750,16550 6750,16550 Z"/> 250 + </g> 251 + </g> 252 + </g> 253 + <g class="Group"> 254 + <g class="com.sun.star.drawing.CustomShape"> 255 + <g id="id24"> 256 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="17329" width="10003" height="1753"/> 257 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,19080 L 1750,19080 1750,17330 11750,17330 11750,19080 6750,19080 Z"/> 258 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="18425"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 259 + </g> 260 + </g> 261 + <g class="com.sun.star.drawing.CustomShape"> 262 + <g id="id25"> 263 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="16579" width="10003" height="753"/> 264 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,17330 L 1750,17330 1750,16580 11750,16580 11750,17330 6750,17330 Z"/> 265 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="17175"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 266 + </g> 267 + </g> 268 + <g class="com.sun.star.drawing.CustomShape"> 269 + <g id="id26"> 270 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="16489" width="10083" height="2583"/> 271 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,19030 L 1750,19030 1750,16530 11750,16530 11750,19030 6750,19030 Z"/> 272 + </g> 273 + </g> 274 + </g> 275 + <g class="Group"> 276 + <g class="com.sun.star.drawing.CustomShape"> 277 + <g id="id27"> 278 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="19809" width="10003" height="1753"/> 279 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,21560 L 1750,21560 1750,19810 11750,19810 11750,21560 6750,21560 Z"/> 280 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3718" y="20905"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of upper 8 bits</tspan></tspan></tspan></text> 281 + </g> 282 + </g> 283 + <g class="com.sun.star.drawing.CustomShape"> 284 + <g id="id28"> 285 + <rect class="BoundingBox" stroke="none" fill="none" x="1749" y="19059" width="10003" height="753"/> 286 + <path fill="none" stroke="rgb(52,101,164)" d="M 6750,19810 L 1750,19810 1750,19060 11750,19060 11750,19810 6750,19810 Z"/> 287 + <text class="SVGTextShape"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="3771" y="19655"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">4 rows of lower 2 bits</tspan></tspan></tspan></text> 288 + </g> 289 + </g> 290 + <g class="com.sun.star.drawing.CustomShape"> 291 + <g id="id29"> 292 + <rect class="BoundingBox" stroke="none" fill="none" x="1709" y="18969" width="10083" height="2583"/> 293 + <path fill="none" stroke="rgb(52,101,164)" stroke-width="81" stroke-linejoin="round" d="M 6750,21510 L 1750,21510 1750,19010 11750,19010 11750,21510 6750,21510 Z"/> 294 + </g> 295 + </g> 296 + </g> 297 + <g class="com.sun.star.drawing.MeasureShape"> 298 + <g id="id30"> 299 + <rect class="BoundingBox" stroke="none" fill="none" x="11849" y="1949" width="1237" height="4987"/> 300 + <path fill="none" stroke="rgb(0,0,0)" d="M 12443,6845 L 12443,4487"/> 301 + <path fill="rgb(0,0,0)" stroke="none" d="M 12443,4200 L 12343,4500 12543,4500 12443,4200 Z"/> 302 + <path fill="none" stroke="rgb(0,0,0)" d="M 12443,2163 L 12443,1950"/> 303 + <path fill="rgb(0,0,0)" stroke="none" d="M 12443,2450 L 12543,2150 12343,2150 12443,2450 Z"/> 304 + <path fill="none" stroke="rgb(0,0,0)" d="M 12443,4200 L 12443,2450"/> 305 + <path fill="none" stroke="rgb(0,0,0)" d="M 11850,4200 L 12643,4200"/> 306 + <path fill="none" stroke="rgb(0,0,0)" d="M 11850,2450 L 12643,2450"/> 307 + <text class="SVGTextShape" transform="rotate(-90 12953 6967)"><tspan class="TextParagraph" font-family="Liberation Sans, sans-serif" font-size="635px" font-weight="400"><tspan class="TextPosition" x="12953" y="6967"><tspan fill="rgb(0,0,0)" stroke="none" style="white-space: pre">64 bytes</tspan></tspan></tspan></text> 308 + </g> 309 + </g> 310 + </g> 311 + </g> 312 + </g> 313 + </g> 314 + </g> 315 + </svg>
-13
Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
··· 275 275 276 276 Decoder's implementation can be found here, 277 277 `aspeed_codec <https://github.com/AspeedTech-BMC/aspeed_codec/>`__ 278 - * .. _V4L2-PIX-FMT-MT2110T: 279 - 280 - - ``V4L2_PIX_FMT_MT2110T`` 281 - - 'MT2110T' 282 - - This format is two-planar 10-Bit tile mode and having similitude with 283 - ``V4L2_PIX_FMT_MM21`` in term of alignment and tiling. Used for VP9, AV1 284 - and HEVC. 285 - * .. _V4L2-PIX-FMT-MT2110R: 286 - 287 - - ``V4L2_PIX_FMT_MT2110R`` 288 - - 'MT2110R' 289 - - This format is two-planar 10-Bit raster mode and having similitude with 290 - ``V4L2_PIX_FMT_MM21`` in term of alignment and tiling. Used for AVC. 291 278 * .. _V4L2-PIX-FMT-HEXTILE: 292 279 293 280 - ``V4L2_PIX_FMT_HEXTILE``
+155 -24
Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
··· 144 144 - Cb, Cr 145 145 - Yes 146 146 - 4x4 tiles 147 + * - V4L2_PIX_FMT_MT2110T 148 + - 'MT2T' 149 + - 15 150 + - 4:2:0 151 + - Cb, Cr 152 + - No 153 + - 16x32 / 16x16 tiles tiled low bits 154 + * - V4L2_PIX_FMT_MT2110R 155 + - 'MT2R' 156 + - 15 157 + - 4:2:0 158 + - Cb, Cr 159 + - No 160 + - 16x32 / 16x16 tiles raster low bits 147 161 * - V4L2_PIX_FMT_NV16 148 162 - 'NV16' 149 163 - 8 ··· 309 295 .. _V4L2-PIX-FMT-NV12-32L32: 310 296 .. _V4L2-PIX-FMT-NV12M-8L128: 311 297 .. _V4L2-PIX-FMT-NV12-8L128: 312 - .. _V4L2-PIX-FMT-NV12M-10BE-8L128: 313 - .. _V4L2-PIX-FMT-NV12-10BE-8L128: 314 298 .. _V4L2-PIX-FMT-MM21: 315 299 316 300 Tiled NV12 ··· 334 322 tiles is stored in linear order. The layouts of the luma and chroma 335 323 planes are identical. 336 324 325 + .. _nv12mt: 326 + 327 + .. kernel-figure:: nv12mt.svg 328 + :alt: nv12mt.svg 329 + :align: center 330 + 331 + V4L2_PIX_FMT_NV12MT macroblock Z shape memory layout 332 + 333 + .. _nv12mt_ex: 334 + 335 + .. kernel-figure:: nv12mt_example.svg 336 + :alt: nv12mt_example.svg 337 + :align: center 338 + 339 + Example V4L2_PIX_FMT_NV12MT memory layout of tiles 340 + 337 341 ``V4L2_PIX_FMT_NV12_4L4`` stores pixels in 4x4 tiles, and stores 338 342 tiles linearly in memory. The line stride and image height must be 339 343 aligned to a multiple of 4. The layouts of the luma and chroma planes are ··· 373 345 ``V4L2_PIX_FMT_NV12_8L128`` is similar to ``V4L2_PIX_FMT_NV12M_8L128`` but stores 374 346 two planes in one memory. 375 347 348 + ``V4L2_PIX_FMT_MM21`` store luma pixel in 16x32 tiles, and chroma pixels 349 + in 16x16 tiles. The line stride must be aligned to a multiple of 16 and the 350 + image height must be aligned to a multiple of 32. The number of luma and chroma 351 + tiles are identical, even though the tile size differ. The image is formed of 352 + two non-contiguous planes. 353 + 354 + 355 + .. _V4L2-PIX-FMT-NV15-4L4: 356 + .. _V4L2-PIX-FMT-NV12M-10BE-8L128: 357 + .. _V4L2-PIX-FMT-NV12-10BE-8L128: 358 + .. _V4L2-PIX-FMT-MT2110T: 359 + .. _V4L2-PIX-FMT-MT2110R: 360 + 361 + Tiled NV15 362 + ---------- 363 + 364 + ``V4L2_PIX_FMT_NV15_4L4`` Semi-planar 10-bit YUV 4:2:0 formats, using 4x4 tiling. 365 + All components are packed without any padding between each other. 366 + As a side-effect, each group of 4 components are stored over 5 bytes 367 + (YYYY or UVUV = 4 * 10 bits = 40 bits = 5 bytes). 368 + 376 369 ``V4L2_PIX_FMT_NV12M_10BE_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores 377 370 10 bits pixels in 2D 8x128 tiles, and stores tiles linearly in memory. 378 371 the data is arranged in big endian order. ··· 412 363 ``V4L2_PIX_FMT_NV12_10BE_8L128`` is similar to ``V4L2_PIX_FMT_NV12M_10BE_8L128`` but stores 413 364 two planes in one memory. 414 365 415 - ``V4L2_PIX_FMT_MM21`` store luma pixel in 16x32 tiles, and chroma pixels 416 - in 16x16 tiles. The line stride must be aligned to a multiple of 16 and the 417 - image height must be aligned to a multiple of 32. The number of luma and chroma 418 - tiles are identical, even though the tile size differ. The image is formed of 419 - two non-contiguous planes. 366 + ``V4L2_PIX_FMT_MT2110T`` is one of Mediatek packed 10bit YUV 4:2:0 formats. 367 + It is fully packed 10bit 4:2:0 format like NV15 (15 bits per pixel), except 368 + that the lower two bits data is stored in separate partitions. The format is 369 + composed of 16x32 luma tiles, and 16x16 chroma tiles. Each tiles is 640 bytes 370 + long, divided into 8 partitions of 80 bytes. The first 16 bytes of the 371 + partition represent the 2 least significant bits of pixel data. The remaining 372 + 64 bytes represent the 8 most significant bits of pixel data. 420 373 421 - .. _nv12mt: 422 - 423 - .. kernel-figure:: nv12mt.svg 424 - :alt: nv12mt.svg 374 + .. kernel-figure:: mt2110t.svg 375 + :alt: mt2110t.svg 425 376 :align: center 426 377 427 - V4L2_PIX_FMT_NV12MT macroblock Z shape memory layout 378 + Layout of MT2110T Chroma Tile 428 379 429 - .. _nv12mt_ex: 380 + Filtering out the upper part of each partitions results in a valid 381 + ``V4L2_PIX_FMT_MM21`` frame. A partition is a sub-tile of size 16 x 4. The 382 + lower two bits is said to be tiled since each bytes contains the lower two 383 + bits of the column of for pixel matching the same index. The chroma tiles 384 + only have 4 partitions. 430 385 431 - .. kernel-figure:: nv12mt_example.svg 432 - :alt: nv12mt_example.svg 433 - :align: center 386 + .. flat-table:: MT2110T LSB bits layout 387 + :header-rows: 1 388 + :stub-columns: 1 434 389 435 - Example V4L2_PIX_FMT_NV12MT memory layout of tiles 390 + * - 391 + - start + 0: 392 + - start + 1: 393 + - . . . 394 + - start\ +\ 15: 395 + * - Bits 1:0 396 + - Y'\ :sub:`0:0` 397 + - Y'\ :sub:`0:1` 398 + - . . . 399 + - Y'\ :sub:`0:15` 400 + * - Bit 3:2 401 + - Y'\ :sub:`1:0` 402 + - Y'\ :sub:`1:1` 403 + - . . . 404 + - Y'\ :sub:`1:15` 405 + * - Bits 5:4 406 + - Y'\ :sub:`2:0` 407 + - Y'\ :sub:`2:1` 408 + - . . . 409 + - Y'\ :sub:`2:15` 410 + * - Bits 7:6 411 + - Y'\ :sub:`3:0` 412 + - Y'\ :sub:`3:1` 413 + - . . . 414 + - Y'\ :sub:`3:15` 436 415 437 - .. _V4L2-PIX-FMT-NV15-4L4: 416 + ``V4L2_PIX_FMT_MT2110R`` is identical to ``V4L2_PIX_FMT_MT2110T`` except that 417 + the least significant two bits layout is in raster order. This means the first byte 418 + contains 4 pixels of the first row, with 4 bytes per line. 438 419 439 - Tiled NV15 440 - ---------- 420 + .. flat-table:: MT2110R LSB bits layout 421 + :header-rows: 2 422 + :stub-columns: 1 441 423 442 - Semi-planar 10-bit YUV 4:2:0 formats, using 4x4 tiling. 443 - All components are packed without any padding between each other. 444 - As a side-effect, each group of 4 components are stored over 5 bytes 445 - (YYYY or UVUV = 4 * 10 bits = 40 bits = 5 bytes). 424 + * - 425 + - :cspan:`3` Byte 0 426 + - ... 427 + - :cspan:`3` Byte 3 428 + * - 429 + - 7:6 430 + - 5:4 431 + - 3:2 432 + - 1:0 433 + - ... 434 + - 7:6 435 + - 5:4 436 + - 3:2 437 + - 1:0 438 + * - start + 0: 439 + - Y'\ :sub:`0:3` 440 + - Y'\ :sub:`0:2` 441 + - Y'\ :sub:`0:1` 442 + - Y'\ :sub:`0:0` 443 + - ... 444 + - Y'\ :sub:`0:15` 445 + - Y'\ :sub:`0:14` 446 + - Y'\ :sub:`0:13` 447 + - Y'\ :sub:`0:12` 448 + * - start + 4: 449 + - Y'\ :sub:`1:3` 450 + - Y'\ :sub:`1:2` 451 + - Y'\ :sub:`1:1` 452 + - Y'\ :sub:`1:0` 453 + - ... 454 + - Y'\ :sub:`1:15` 455 + - Y'\ :sub:`1:14` 456 + - Y'\ :sub:`1:13` 457 + - Y'\ :sub:`1:12` 458 + * - start + 8: 459 + - Y'\ :sub:`2:3` 460 + - Y'\ :sub:`2:2` 461 + - Y'\ :sub:`2:1` 462 + - Y'\ :sub:`2:0` 463 + - ... 464 + - Y'\ :sub:`2:15` 465 + - Y'\ :sub:`2:14` 466 + - Y'\ :sub:`2:13` 467 + - Y'\ :sub:`2:12` 468 + * - start\ +\ 12: 469 + - Y'\ :sub:`3:3` 470 + - Y'\ :sub:`3:2` 471 + - Y'\ :sub:`3:1` 472 + - Y'\ :sub:`3:0` 473 + - ... 474 + - Y'\ :sub:`3:15` 475 + - Y'\ :sub:`3:14` 476 + - Y'\ :sub:`3:13` 477 + - Y'\ :sub:`3:12` 478 + 446 479 447 480 .. _V4L2-PIX-FMT-NV16: 448 481 .. _V4L2-PIX-FMT-NV61:
+11
Documentation/userspace-api/media/v4l/vidioc-querycap.rst
··· 244 244 - 0x01000000 245 245 - The device supports the :c:func:`read()` and/or 246 246 :c:func:`write()` I/O methods. 247 + * - ``V4L2_CAP_EDID`` 248 + - 0x02000000 249 + - The device stores the EDID for a video input, or retrieves the EDID for a video 250 + output. It is a standalone EDID device, so no video streaming etc. will take place. 251 + 252 + For a video input this is typically an eeprom that supports the 253 + :ref:`VESA Enhanced Display Data Channel Standard <vesaeddc>`. It can be something 254 + else as well, for example a micro controller. 255 + 256 + For a video output this is typically read from an external device such as an 257 + HDMI splitter accessed by a serial port. 247 258 * - ``V4L2_CAP_STREAMING`` 248 259 - 0x04000000 249 260 - The device supports the :ref:`streaming <mmap>` I/O method.
+32 -8
Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst
··· 73 73 74 74 .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.5cm}| 75 75 76 + .. cssclass:: longtable 77 + 76 78 .. flat-table:: struct v4l2_requestbuffers 77 79 :header-rows: 0 78 80 :stub-columns: 0 ··· 125 123 .. _V4L2-BUF-CAP-SUPPORTS-MAX-NUM-BUFFERS: 126 124 .. _V4L2-BUF-CAP-SUPPORTS-REMOVE-BUFS: 127 125 128 - .. raw:: latex 129 - 130 - \footnotesize 131 - 132 - .. tabularcolumns:: |p{8.1cm}|p{2.2cm}|p{7.0cm}| 133 - 134 - .. cssclass:: longtable 135 - 136 126 .. flat-table:: V4L2 Buffer Capabilities Flags 137 127 :header-rows: 0 138 128 :stub-columns: 0 ··· 160 166 :ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE <V4L2-BUF-FLAG-NO-CACHE-INVALIDATE>`, 161 167 :ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN <V4L2-BUF-FLAG-NO-CACHE-CLEAN>` and 162 168 :ref:`V4L2_MEMORY_FLAG_NON_COHERENT <V4L2-MEMORY-FLAG-NON-COHERENT>`. 169 + * - ``V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS`` 170 + - 0x00000080 171 + - If set, then the ``max_num_buffers`` field in ``struct v4l2_create_buffers`` 172 + is valid. If not set, then the maximum is ``VIDEO_MAX_FRAME`` buffers. 173 + * - ``V4L2_BUF_CAP_SUPPORTS_REMOVE_BUFS`` 174 + - 0x00000100 175 + - If set, then ``VIDIOC_REMOVE_BUFS`` is supported. 176 + 177 + .. _memory-flags: 178 + .. _V4L2-MEMORY-FLAG-NON-COHERENT: 179 + 180 + .. flat-table:: Memory Consistency Flags 181 + :header-rows: 0 182 + :stub-columns: 0 183 + :widths: 3 1 4 184 + 185 + * - ``V4L2_MEMORY_FLAG_NON_COHERENT`` 186 + - 0x00000001 187 + - A buffer is allocated either in coherent (it will be automatically 188 + coherent between the CPU and the bus) or non-coherent memory. The 189 + latter can provide performance gains, for instance the CPU cache 190 + sync/flush operations can be avoided if the buffer is accessed by the 191 + corresponding device only and the CPU does not read/write to/from that 192 + buffer. However, this requires extra care from the driver -- it must 193 + guarantee memory consistency by issuing a cache flush/sync when 194 + consistency is needed. If this flag is set V4L2 will attempt to 195 + allocate the buffer in non-coherent memory. The flag takes effect 196 + only if the buffer is used for :ref:`memory mapping <mmap>` I/O and the 197 + queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS 198 + <V4L2-BUF-CAP-SUPPORTS-MMAP-CACHE-HINTS>` capability. 163 199 164 200 .. raw:: latex 165 201
+1
Documentation/userspace-api/media/videodev2.h.rst.exceptions
··· 197 197 replace define V4L2_CAP_DEVICE_CAPS device-capabilities 198 198 replace define V4L2_CAP_TOUCH device-capabilities 199 199 replace define V4L2_CAP_IO_MC device-capabilities 200 + replace define V4L2_CAP_EDID device-capabilities 200 201 201 202 # V4L2 pix flags 202 203 replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
+9 -1
MAINTAINERS
··· 8548 8548 F: tools/bootconfig/* 8549 8549 F: tools/bootconfig/scripts/* 8550 8550 8551 + EXTRON DA HD 4K PLUS CEC DRIVER 8552 + M: Hans Verkuil <hverkuil@xs4all.nl> 8553 + L: linux-media@vger.kernel.org 8554 + S: Maintained 8555 + T: git git://linuxtv.org/media_tree.git 8556 + F: drivers/media/cec/usb/extron-da-hd-4k-plus/ 8557 + 8551 8558 EXYNOS DP DRIVER 8552 8559 M: Jingoo Han <jingoohan1@gmail.com> 8553 8560 L: dri-devel@lists.freedesktop.org ··· 16971 16964 M: Sakari Ailus <sakari.ailus@linux.intel.com> 16972 16965 L: linux-media@vger.kernel.org 16973 16966 S: Maintained 16967 + F: Documentation/devicetree/bindings/media/i2c/ovti,og01a1b.yaml 16974 16968 F: drivers/media/i2c/og01a1b.c 16975 16969 16976 16970 OMNIVISION OV01A10 SENSOR DRIVER ··· 18940 18932 L: linux-media@vger.kernel.org 18941 18933 S: Maintained 18942 18934 F: Documentation/admin-guide/media/qcom_camss.rst 18943 - F: Documentation/devicetree/bindings/media/*camss* 18935 + F: Documentation/devicetree/bindings/media/qcom,*camss* 18944 18936 F: drivers/media/platform/qcom/camss/ 18945 18937 18946 18938 QUALCOMM CLOCK DRIVERS
+38 -15
drivers/media/cec/core/cec-adap.c
··· 673 673 /* Retry this message */ 674 674 data->attempts -= attempts_made; 675 675 if (msg->timeout) 676 - dprintk(2, "retransmit: %*ph (attempts: %d, wait for 0x%02x)\n", 677 - msg->len, msg->msg, data->attempts, msg->reply); 676 + dprintk(2, "retransmit: %*ph (attempts: %d, wait for %*ph)\n", 677 + msg->len, msg->msg, data->attempts, 678 + data->match_len, data->match_reply); 678 679 else 679 680 dprintk(2, "retransmit: %*ph (attempts: %d)\n", 680 681 msg->len, msg->msg, data->attempts); ··· 781 780 { 782 781 struct cec_data *data; 783 782 bool is_raw = msg_is_raw(msg); 783 + bool reply_vendor_id = (msg->flags & CEC_MSG_FL_REPLY_VENDOR_ID) && 784 + msg->len > 1 && msg->msg[1] == CEC_MSG_VENDOR_COMMAND_WITH_ID; 784 785 int err; 785 786 786 787 if (adap->devnode.unregistered) ··· 797 794 msg->tx_low_drive_cnt = 0; 798 795 msg->tx_error_cnt = 0; 799 796 msg->sequence = 0; 797 + msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW | 798 + (reply_vendor_id ? CEC_MSG_FL_REPLY_VENDOR_ID : 0); 800 799 801 - if (msg->reply && msg->timeout == 0) { 800 + if ((reply_vendor_id || msg->reply) && msg->timeout == 0) { 802 801 /* Make sure the timeout isn't 0. */ 803 802 msg->timeout = 1000; 804 803 } 805 - msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW; 806 804 807 805 if (!msg->timeout) 808 806 msg->flags &= ~CEC_MSG_FL_REPLY_TO_FOLLOWERS; ··· 811 807 /* Sanity checks */ 812 808 if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) { 813 809 dprintk(1, "%s: invalid length %d\n", __func__, msg->len); 810 + return -EINVAL; 811 + } 812 + if (reply_vendor_id && msg->len < 6) { 813 + dprintk(1, "%s: <Vendor Command With ID> message too short\n", 814 + __func__); 814 815 return -EINVAL; 815 816 } 816 817 ··· 909 900 __func__); 910 901 return -ENONET; 911 902 } 912 - if (msg->reply) { 913 - dprintk(1, "%s: invalid msg->reply\n", __func__); 903 + if (reply_vendor_id || msg->reply) { 904 + dprintk(1, "%s: adapter is unconfigured so reply is not supported\n", 905 + __func__); 914 906 return -EINVAL; 915 907 } 916 908 } ··· 933 923 data->fh = fh; 934 924 data->adap = adap; 935 925 data->blocking = block; 926 + if (reply_vendor_id) { 927 + memcpy(data->match_reply, msg->msg + 1, 4); 928 + data->match_reply[4] = msg->reply; 929 + data->match_len = 5; 930 + } else if (msg->timeout) { 931 + data->match_reply[0] = msg->reply; 932 + data->match_len = 1; 933 + } 936 934 937 935 init_completion(&data->c); 938 936 INIT_DELAYED_WORK(&data->work, cec_wait_timeout); ··· 1229 1211 if (!abort && dst->msg[1] == CEC_MSG_INITIATE_ARC && 1230 1212 (cmd == CEC_MSG_REPORT_ARC_INITIATED || 1231 1213 cmd == CEC_MSG_REPORT_ARC_TERMINATED) && 1232 - (dst->reply == CEC_MSG_REPORT_ARC_INITIATED || 1233 - dst->reply == CEC_MSG_REPORT_ARC_TERMINATED)) 1214 + (data->match_reply[0] == CEC_MSG_REPORT_ARC_INITIATED || 1215 + data->match_reply[0] == CEC_MSG_REPORT_ARC_TERMINATED)) { 1234 1216 dst->reply = cmd; 1217 + data->match_reply[0] = cmd; 1218 + } 1235 1219 1236 1220 /* Does the command match? */ 1237 1221 if ((abort && cmd != dst->msg[1]) || 1238 - (!abort && cmd != dst->reply)) 1222 + (!abort && memcmp(data->match_reply, msg->msg + 1, data->match_len))) 1239 1223 continue; 1240 1224 1241 1225 /* Does the addressing match? */ ··· 2338 2318 } 2339 2319 data = adap->transmitting; 2340 2320 if (data) 2341 - seq_printf(file, "transmitting message: %*ph (reply: %02x, timeout: %ums)\n", 2342 - data->msg.len, data->msg.msg, data->msg.reply, 2321 + seq_printf(file, "transmitting message: %*ph (reply: %*ph, timeout: %ums)\n", 2322 + data->msg.len, data->msg.msg, 2323 + data->match_len, data->match_reply, 2343 2324 data->msg.timeout); 2344 2325 seq_printf(file, "pending transmits: %u\n", adap->transmit_queue_sz); 2345 2326 list_for_each_entry(data, &adap->transmit_queue, list) { 2346 - seq_printf(file, "queued tx message: %*ph (reply: %02x, timeout: %ums)\n", 2347 - data->msg.len, data->msg.msg, data->msg.reply, 2327 + seq_printf(file, "queued tx message: %*ph (reply: %*ph, timeout: %ums)\n", 2328 + data->msg.len, data->msg.msg, 2329 + data->match_len, data->match_reply, 2348 2330 data->msg.timeout); 2349 2331 } 2350 2332 list_for_each_entry(data, &adap->wait_queue, list) { 2351 - seq_printf(file, "message waiting for reply: %*ph (reply: %02x, timeout: %ums)\n", 2352 - data->msg.len, data->msg.msg, data->msg.reply, 2333 + seq_printf(file, "message waiting for reply: %*ph (reply: %*ph, timeout: %ums)\n", 2334 + data->msg.len, data->msg.msg, 2335 + data->match_len, data->match_reply, 2353 2336 data->msg.timeout); 2354 2337 } 2355 2338
+2 -2
drivers/media/cec/core/cec-api.c
··· 580 580 fh->mode_initiator = CEC_MODE_INITIATOR; 581 581 fh->adap = adap; 582 582 583 - err = cec_get_device(devnode); 583 + err = cec_get_device(adap); 584 584 if (err) { 585 585 kfree(fh); 586 586 return err; ··· 686 686 mutex_unlock(&fh->lock); 687 687 kfree(fh); 688 688 689 - cec_put_device(devnode); 689 + cec_put_device(adap); 690 690 filp->private_data = NULL; 691 691 return 0; 692 692 }
+1 -30
drivers/media/cec/core/cec-core.c
··· 51 51 /* dev to cec_devnode */ 52 52 #define to_cec_devnode(cd) container_of(cd, struct cec_devnode, dev) 53 53 54 - int cec_get_device(struct cec_devnode *devnode) 55 - { 56 - /* 57 - * Check if the cec device is available. This needs to be done with 58 - * the devnode->lock held to prevent an open/unregister race: 59 - * without the lock, the device could be unregistered and freed between 60 - * the devnode->registered check and get_device() calls, leading to 61 - * a crash. 62 - */ 63 - mutex_lock(&devnode->lock); 64 - /* 65 - * return ENODEV if the cec device has been removed 66 - * already or if it is not registered anymore. 67 - */ 68 - if (!devnode->registered) { 69 - mutex_unlock(&devnode->lock); 70 - return -ENODEV; 71 - } 72 - /* and increase the device refcount */ 73 - get_device(&devnode->dev); 74 - mutex_unlock(&devnode->lock); 75 - return 0; 76 - } 77 - 78 - void cec_put_device(struct cec_devnode *devnode) 79 - { 80 - put_device(&devnode->dev); 81 - } 82 - 83 54 /* Called when the last user of the cec device exits. */ 84 55 static void cec_devnode_release(struct device *cd) 85 56 { ··· 244 273 adap->cec_pin_is_high = true; 245 274 adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; 246 275 adap->log_addrs.vendor_id = CEC_VENDOR_ID_NONE; 247 - adap->capabilities = caps; 276 + adap->capabilities = caps | CEC_CAP_REPLY_VENDOR_ID; 248 277 if (debug_phys_addr) 249 278 adap->capabilities |= CEC_CAP_PHYS_ADDR; 250 279 adap->needs_hpd = caps & CEC_CAP_NEEDS_HPD;
-2
drivers/media/cec/core/cec-priv.h
··· 37 37 38 38 /* cec-core.c */ 39 39 extern int cec_debug; 40 - int cec_get_device(struct cec_devnode *devnode); 41 - void cec_put_device(struct cec_devnode *devnode); 42 40 43 41 /* cec-adap.c */ 44 42 int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
+1
drivers/media/cec/usb/Kconfig
··· 3 3 # USB drivers 4 4 5 5 if USB_SUPPORT && TTY 6 + source "drivers/media/cec/usb/extron-da-hd-4k-plus/Kconfig" 6 7 source "drivers/media/cec/usb/pulse8/Kconfig" 7 8 source "drivers/media/cec/usb/rainshadow/Kconfig" 8 9 endif
+1
drivers/media/cec/usb/Makefile
··· 2 2 # 3 3 # Makefile for the CEC USB device drivers. 4 4 # 5 + obj-$(CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC) += extron-da-hd-4k-plus/ 5 6 obj-$(CONFIG_USB_PULSE8_CEC) += pulse8/ 6 7 obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow/
+14
drivers/media/cec/usb/extron-da-hd-4k-plus/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + config USB_EXTRON_DA_HD_4K_PLUS_CEC 3 + tristate "Extron DA HD 4K Plus CEC driver" 4 + depends on VIDEO_DEV 5 + depends on USB 6 + depends on USB_ACM 7 + select CEC_CORE 8 + select SERIO 9 + select SERIO_SERPORT 10 + help 11 + This is a CEC driver for the Extron DA HD 4K Plus HDMI Splitter. 12 + 13 + To compile this driver as a module, choose M here: the 14 + module will be called extron-da-hd-4k-plus-cec.
+8
drivers/media/cec/usb/extron-da-hd-4k-plus/Makefile
··· 1 + extron-da-hd-4k-plus-cec-objs := extron-da-hd-4k-plus.o cec-splitter.o 2 + obj-$(CONFIG_USB_EXTRON_DA_HD_4K_PLUS_CEC) := extron-da-hd-4k-plus-cec.o 3 + 4 + all: 5 + $(MAKE) -C $(KDIR) M=$(shell pwd) modules 6 + 7 + install: 8 + $(MAKE) -C $(KDIR) M=$(shell pwd) modules_install
+657
drivers/media/cec/usb/extron-da-hd-4k-plus/cec-splitter.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + /* 4 + * Copyright 2021-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 + */ 6 + 7 + #include <media/cec.h> 8 + 9 + #include "cec-splitter.h" 10 + 11 + /* 12 + * Helper function to reply to a received message with a Feature Abort 13 + * message. 14 + */ 15 + static int cec_feature_abort_reason(struct cec_adapter *adap, 16 + struct cec_msg *msg, u8 reason) 17 + { 18 + struct cec_msg tx_msg = { }; 19 + 20 + /* 21 + * Don't reply with CEC_MSG_FEATURE_ABORT to a CEC_MSG_FEATURE_ABORT 22 + * message! 23 + */ 24 + if (msg->msg[1] == CEC_MSG_FEATURE_ABORT) 25 + return 0; 26 + /* Don't Feature Abort messages from 'Unregistered' */ 27 + if (cec_msg_initiator(msg) == CEC_LOG_ADDR_UNREGISTERED) 28 + return 0; 29 + cec_msg_set_reply_to(&tx_msg, msg); 30 + cec_msg_feature_abort(&tx_msg, msg->msg[1], reason); 31 + return cec_transmit_msg(adap, &tx_msg, false); 32 + } 33 + 34 + /* Transmit an Active Source message from this output port to a sink */ 35 + static void cec_port_out_active_source(struct cec_splitter_port *p) 36 + { 37 + struct cec_adapter *adap = p->adap; 38 + struct cec_msg msg; 39 + 40 + if (!adap->is_configured) 41 + return; 42 + p->is_active_source = true; 43 + cec_msg_init(&msg, adap->log_addrs.log_addr[0], 0); 44 + cec_msg_active_source(&msg, adap->phys_addr); 45 + cec_transmit_msg(adap, &msg, false); 46 + } 47 + 48 + /* Transmit Active Source messages from all output ports to the sinks */ 49 + static void cec_out_active_source(struct cec_splitter *splitter) 50 + { 51 + unsigned int i; 52 + 53 + for (i = 0; i < splitter->num_out_ports; i++) 54 + cec_port_out_active_source(splitter->ports[i]); 55 + } 56 + 57 + /* Transmit a Standby message from this output port to a sink */ 58 + static void cec_port_out_standby(struct cec_splitter_port *p) 59 + { 60 + struct cec_adapter *adap = p->adap; 61 + struct cec_msg msg; 62 + 63 + if (!adap->is_configured) 64 + return; 65 + cec_msg_init(&msg, adap->log_addrs.log_addr[0], 0); 66 + cec_msg_standby(&msg); 67 + cec_transmit_msg(adap, &msg, false); 68 + } 69 + 70 + /* Transmit Standby messages from all output ports to the sinks */ 71 + static void cec_out_standby(struct cec_splitter *splitter) 72 + { 73 + unsigned int i; 74 + 75 + for (i = 0; i < splitter->num_out_ports; i++) 76 + cec_port_out_standby(splitter->ports[i]); 77 + } 78 + 79 + /* Transmit an Image/Text View On message from this output port to a sink */ 80 + static void cec_port_out_wakeup(struct cec_splitter_port *p, u8 opcode) 81 + { 82 + struct cec_adapter *adap = p->adap; 83 + u8 la = adap->log_addrs.log_addr[0]; 84 + struct cec_msg msg; 85 + 86 + if (la == CEC_LOG_ADDR_INVALID) 87 + la = CEC_LOG_ADDR_UNREGISTERED; 88 + cec_msg_init(&msg, la, 0); 89 + msg.len = 2; 90 + msg.msg[1] = opcode; 91 + cec_transmit_msg(adap, &msg, false); 92 + } 93 + 94 + /* Transmit Image/Text View On messages from all output ports to the sinks */ 95 + static void cec_out_wakeup(struct cec_splitter *splitter, u8 opcode) 96 + { 97 + unsigned int i; 98 + 99 + for (i = 0; i < splitter->num_out_ports; i++) 100 + cec_port_out_wakeup(splitter->ports[i], opcode); 101 + } 102 + 103 + /* 104 + * Update the power state of the unconfigured CEC device to either 105 + * Off or On depending on the current state of the splitter. 106 + * This keeps the outputs in a consistent state. 107 + */ 108 + void cec_splitter_unconfigured_output(struct cec_splitter_port *p) 109 + { 110 + p->video_latency = 1; 111 + p->power_status = p->splitter->is_standby ? 112 + CEC_OP_POWER_STATUS_TO_STANDBY : CEC_OP_POWER_STATUS_TO_ON; 113 + 114 + /* The adapter was unconfigured, so clear the sequence and ts values */ 115 + p->out_give_device_power_status_seq = 0; 116 + p->out_give_device_power_status_ts = ktime_set(0, 0); 117 + p->out_request_current_latency_seq = 0; 118 + p->out_request_current_latency_ts = ktime_set(0, 0); 119 + } 120 + 121 + /* 122 + * Update the power state of the newly configured CEC device to either 123 + * Off or On depending on the current state of the splitter. 124 + * This keeps the outputs in a consistent state. 125 + */ 126 + void cec_splitter_configured_output(struct cec_splitter_port *p) 127 + { 128 + p->video_latency = 1; 129 + p->power_status = p->splitter->is_standby ? 130 + CEC_OP_POWER_STATUS_TO_STANDBY : CEC_OP_POWER_STATUS_TO_ON; 131 + 132 + if (p->splitter->is_standby) { 133 + /* 134 + * Some sinks only obey Standby if it comes from the 135 + * active source. 136 + */ 137 + cec_port_out_active_source(p); 138 + cec_port_out_standby(p); 139 + } else { 140 + cec_port_out_wakeup(p, CEC_MSG_IMAGE_VIEW_ON); 141 + } 142 + } 143 + 144 + /* Pass the in_msg on to all output ports */ 145 + static void cec_out_passthrough(struct cec_splitter *splitter, 146 + const struct cec_msg *in_msg) 147 + { 148 + unsigned int i; 149 + 150 + for (i = 0; i < splitter->num_out_ports; i++) { 151 + struct cec_splitter_port *p = splitter->ports[i]; 152 + struct cec_adapter *adap = p->adap; 153 + struct cec_msg msg; 154 + 155 + if (!adap->is_configured) 156 + continue; 157 + cec_msg_init(&msg, adap->log_addrs.log_addr[0], 0); 158 + msg.len = in_msg->len; 159 + memcpy(msg.msg + 1, in_msg->msg + 1, msg.len - 1); 160 + cec_transmit_msg(adap, &msg, false); 161 + } 162 + } 163 + 164 + /* 165 + * See if all output ports received the Report Current Latency message, 166 + * and if so, transmit the result from the input port to the video source. 167 + */ 168 + static void cec_out_report_current_latency(struct cec_splitter *splitter, 169 + struct cec_adapter *input_adap) 170 + { 171 + struct cec_msg reply = {}; 172 + unsigned int reply_lat = 0; 173 + unsigned int cnt = 0; 174 + unsigned int i; 175 + 176 + for (i = 0; i < splitter->num_out_ports; i++) { 177 + struct cec_splitter_port *p = splitter->ports[i]; 178 + struct cec_adapter *adap = p->adap; 179 + 180 + /* Skip unconfigured ports */ 181 + if (!adap->is_configured) 182 + continue; 183 + /* Return if a port is still waiting for a reply */ 184 + if (p->out_request_current_latency_seq) 185 + return; 186 + reply_lat += p->video_latency - 1; 187 + cnt++; 188 + } 189 + 190 + /* 191 + * All ports that can reply, replied, so clear the sequence 192 + * and timestamp values. 193 + */ 194 + for (i = 0; i < splitter->num_out_ports; i++) { 195 + struct cec_splitter_port *p = splitter->ports[i]; 196 + 197 + p->out_request_current_latency_seq = 0; 198 + p->out_request_current_latency_ts = ktime_set(0, 0); 199 + } 200 + 201 + /* 202 + * Return if there were no replies or the input port is no longer 203 + * configured. 204 + */ 205 + if (!cnt || !input_adap->is_configured) 206 + return; 207 + 208 + /* Reply with the average latency */ 209 + reply_lat = 1 + reply_lat / cnt; 210 + cec_msg_init(&reply, input_adap->log_addrs.log_addr[0], 211 + splitter->request_current_latency_dest); 212 + cec_msg_report_current_latency(&reply, input_adap->phys_addr, 213 + reply_lat, 1, 1, 1); 214 + cec_transmit_msg(input_adap, &reply, false); 215 + } 216 + 217 + /* Transmit Request Current Latency to all output ports */ 218 + static int cec_out_request_current_latency(struct cec_splitter *splitter) 219 + { 220 + ktime_t now = ktime_get(); 221 + bool error = true; 222 + unsigned int i; 223 + 224 + for (i = 0; i < splitter->num_out_ports; i++) { 225 + struct cec_splitter_port *p = splitter->ports[i]; 226 + struct cec_adapter *adap = p->adap; 227 + 228 + if (!adap->is_configured) { 229 + /* Clear if not configured */ 230 + p->out_request_current_latency_seq = 0; 231 + p->out_request_current_latency_ts = ktime_set(0, 0); 232 + } else if (!p->out_request_current_latency_seq) { 233 + /* 234 + * Keep the old ts if an earlier request is still 235 + * pending. This ensures that the request will 236 + * eventually time out based on the timestamp of 237 + * the first request if the sink is unresponsive. 238 + */ 239 + p->out_request_current_latency_ts = now; 240 + } 241 + } 242 + 243 + for (i = 0; i < splitter->num_out_ports; i++) { 244 + struct cec_splitter_port *p = splitter->ports[i]; 245 + struct cec_adapter *adap = p->adap; 246 + struct cec_msg msg; 247 + 248 + if (!adap->is_configured) 249 + continue; 250 + cec_msg_init(&msg, adap->log_addrs.log_addr[0], 0); 251 + cec_msg_request_current_latency(&msg, true, adap->phys_addr); 252 + if (cec_transmit_msg(adap, &msg, false)) 253 + continue; 254 + p->out_request_current_latency_seq = msg.sequence | (1U << 31); 255 + error = false; 256 + } 257 + return error ? -ENODEV : 0; 258 + } 259 + 260 + /* 261 + * See if all output ports received the Report Power Status message, 262 + * and if so, transmit the result from the input port to the video source. 263 + */ 264 + static void cec_out_report_power_status(struct cec_splitter *splitter, 265 + struct cec_adapter *input_adap) 266 + { 267 + struct cec_msg reply = {}; 268 + /* The target power status of the splitter itself */ 269 + u8 splitter_pwr = splitter->is_standby ? 270 + CEC_OP_POWER_STATUS_STANDBY : CEC_OP_POWER_STATUS_ON; 271 + /* 272 + * The transient power status of the splitter, used if not all 273 + * output report the target power status. 274 + */ 275 + u8 splitter_transient_pwr = splitter->is_standby ? 276 + CEC_OP_POWER_STATUS_TO_STANDBY : CEC_OP_POWER_STATUS_TO_ON; 277 + u8 reply_pwr = splitter_pwr; 278 + unsigned int i; 279 + 280 + for (i = 0; i < splitter->num_out_ports; i++) { 281 + struct cec_splitter_port *p = splitter->ports[i]; 282 + 283 + /* Skip if no sink was found (HPD was low for more than 5s) */ 284 + if (!p->found_sink) 285 + continue; 286 + 287 + /* Return if a port is still waiting for a reply */ 288 + if (p->out_give_device_power_status_seq) 289 + return; 290 + if (p->power_status != splitter_pwr) 291 + reply_pwr = splitter_transient_pwr; 292 + } 293 + 294 + /* 295 + * All ports that can reply, replied, so clear the sequence 296 + * and timestamp values. 297 + */ 298 + for (i = 0; i < splitter->num_out_ports; i++) { 299 + struct cec_splitter_port *p = splitter->ports[i]; 300 + 301 + p->out_give_device_power_status_seq = 0; 302 + p->out_give_device_power_status_ts = ktime_set(0, 0); 303 + } 304 + 305 + /* Return if the input port is no longer configured. */ 306 + if (!input_adap->is_configured) 307 + return; 308 + 309 + /* Reply with the new power status */ 310 + cec_msg_init(&reply, input_adap->log_addrs.log_addr[0], 311 + splitter->give_device_power_status_dest); 312 + cec_msg_report_power_status(&reply, reply_pwr); 313 + cec_transmit_msg(input_adap, &reply, false); 314 + } 315 + 316 + /* Transmit Give Device Power Status to all output ports */ 317 + static int cec_out_give_device_power_status(struct cec_splitter *splitter) 318 + { 319 + ktime_t now = ktime_get(); 320 + bool error = true; 321 + unsigned int i; 322 + 323 + for (i = 0; i < splitter->num_out_ports; i++) { 324 + struct cec_splitter_port *p = splitter->ports[i]; 325 + struct cec_adapter *adap = p->adap; 326 + 327 + /* 328 + * Keep the old ts if an earlier request is still 329 + * pending. This ensures that the request will 330 + * eventually time out based on the timestamp of 331 + * the first request if the sink is unresponsive. 332 + */ 333 + if (adap->is_configured && !p->out_give_device_power_status_seq) 334 + p->out_give_device_power_status_ts = now; 335 + } 336 + 337 + for (i = 0; i < splitter->num_out_ports; i++) { 338 + struct cec_splitter_port *p = splitter->ports[i]; 339 + struct cec_adapter *adap = p->adap; 340 + struct cec_msg msg; 341 + 342 + if (!adap->is_configured) 343 + continue; 344 + 345 + cec_msg_init(&msg, adap->log_addrs.log_addr[0], 0); 346 + cec_msg_give_device_power_status(&msg, true); 347 + if (cec_transmit_msg(adap, &msg, false)) 348 + continue; 349 + p->out_give_device_power_status_seq = msg.sequence | (1U << 31); 350 + error = false; 351 + } 352 + return error ? -ENODEV : 0; 353 + } 354 + 355 + /* 356 + * CEC messages received on the HDMI input of the splitter are 357 + * forwarded (if relevant) to the HDMI outputs of the splitter. 358 + */ 359 + int cec_splitter_received_input(struct cec_splitter_port *p, struct cec_msg *msg) 360 + { 361 + if (!cec_msg_status_is_ok(msg)) 362 + return 0; 363 + 364 + if (msg->len < 2) 365 + return -ENOMSG; 366 + 367 + switch (msg->msg[1]) { 368 + case CEC_MSG_DEVICE_VENDOR_ID: 369 + case CEC_MSG_REPORT_POWER_STATUS: 370 + case CEC_MSG_SET_STREAM_PATH: 371 + case CEC_MSG_ROUTING_CHANGE: 372 + case CEC_MSG_REQUEST_ACTIVE_SOURCE: 373 + case CEC_MSG_SYSTEM_AUDIO_MODE_STATUS: 374 + return 0; 375 + 376 + case CEC_MSG_STANDBY: 377 + p->splitter->is_standby = true; 378 + cec_out_standby(p->splitter); 379 + return 0; 380 + 381 + case CEC_MSG_IMAGE_VIEW_ON: 382 + case CEC_MSG_TEXT_VIEW_ON: 383 + p->splitter->is_standby = false; 384 + cec_out_wakeup(p->splitter, msg->msg[1]); 385 + return 0; 386 + 387 + case CEC_MSG_ACTIVE_SOURCE: 388 + cec_out_active_source(p->splitter); 389 + return 0; 390 + 391 + case CEC_MSG_SET_SYSTEM_AUDIO_MODE: 392 + cec_out_passthrough(p->splitter, msg); 393 + return 0; 394 + 395 + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: 396 + p->splitter->give_device_power_status_dest = 397 + cec_msg_initiator(msg); 398 + if (cec_out_give_device_power_status(p->splitter)) 399 + cec_feature_abort_reason(p->adap, msg, 400 + CEC_OP_ABORT_INCORRECT_MODE); 401 + return 0; 402 + 403 + case CEC_MSG_REQUEST_CURRENT_LATENCY: { 404 + u16 pa; 405 + 406 + p->splitter->request_current_latency_dest = 407 + cec_msg_initiator(msg); 408 + cec_ops_request_current_latency(msg, &pa); 409 + if (pa == p->adap->phys_addr && 410 + cec_out_request_current_latency(p->splitter)) 411 + cec_feature_abort_reason(p->adap, msg, 412 + CEC_OP_ABORT_INCORRECT_MODE); 413 + return 0; 414 + } 415 + 416 + default: 417 + return -ENOMSG; 418 + } 419 + return -ENOMSG; 420 + } 421 + 422 + void cec_splitter_nb_transmit_canceled_output(struct cec_splitter_port *p, 423 + const struct cec_msg *msg, 424 + struct cec_adapter *input_adap) 425 + { 426 + struct cec_splitter *splitter = p->splitter; 427 + u32 seq = msg->sequence | (1U << 31); 428 + 429 + /* 430 + * If this is the result of a failed non-blocking transmit, or it is 431 + * the result of the failed reply to a non-blocking transmit, then 432 + * check if the original transmit was to get the current power status 433 + * or latency and, if so, assume that the remove device is for one 434 + * reason or another unavailable and assume that it is in the same 435 + * power status as the splitter, or has no video latency. 436 + */ 437 + if ((cec_msg_recv_is_tx_result(msg) && !(msg->tx_status & CEC_TX_STATUS_OK)) || 438 + (cec_msg_recv_is_rx_result(msg) && !(msg->rx_status & CEC_RX_STATUS_OK))) { 439 + u8 tx_op = msg->msg[1]; 440 + 441 + if (msg->len < 2) 442 + return; 443 + if (cec_msg_recv_is_rx_result(msg) && 444 + (msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT)) 445 + tx_op = msg->msg[2]; 446 + switch (tx_op) { 447 + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: 448 + if (p->out_give_device_power_status_seq != seq) 449 + break; 450 + p->out_give_device_power_status_seq = 0; 451 + p->out_give_device_power_status_ts = ktime_set(0, 0); 452 + p->power_status = splitter->is_standby ? 453 + CEC_OP_POWER_STATUS_STANDBY : 454 + CEC_OP_POWER_STATUS_ON; 455 + cec_out_report_power_status(splitter, input_adap); 456 + break; 457 + case CEC_MSG_REQUEST_CURRENT_LATENCY: 458 + if (p->out_request_current_latency_seq != seq) 459 + break; 460 + p->video_latency = 1; 461 + p->out_request_current_latency_seq = 0; 462 + p->out_request_current_latency_ts = ktime_set(0, 0); 463 + cec_out_report_current_latency(splitter, input_adap); 464 + break; 465 + } 466 + return; 467 + } 468 + 469 + if (cec_msg_recv_is_tx_result(msg)) { 470 + if (p->out_request_current_latency_seq != seq) 471 + return; 472 + p->out_request_current_latency_ts = ns_to_ktime(msg->tx_ts); 473 + return; 474 + } 475 + } 476 + 477 + /* 478 + * CEC messages received on an HDMI output of the splitter 479 + * are processed here. 480 + */ 481 + int cec_splitter_received_output(struct cec_splitter_port *p, struct cec_msg *msg, 482 + struct cec_adapter *input_adap) 483 + { 484 + struct cec_adapter *adap = p->adap; 485 + struct cec_splitter *splitter = p->splitter; 486 + u32 seq = msg->sequence | (1U << 31); 487 + struct cec_msg reply = {}; 488 + u16 pa; 489 + 490 + if (!adap->is_configured || msg->len < 2) 491 + return -ENOMSG; 492 + 493 + switch (msg->msg[1]) { 494 + case CEC_MSG_REPORT_POWER_STATUS: { 495 + u8 pwr; 496 + 497 + cec_ops_report_power_status(msg, &pwr); 498 + if (pwr > CEC_OP_POWER_STATUS_TO_STANDBY) 499 + pwr = splitter->is_standby ? 500 + CEC_OP_POWER_STATUS_TO_STANDBY : 501 + CEC_OP_POWER_STATUS_TO_ON; 502 + p->power_status = pwr; 503 + if (p->out_give_device_power_status_seq == seq) { 504 + p->out_give_device_power_status_seq = 0; 505 + p->out_give_device_power_status_ts = ktime_set(0, 0); 506 + } 507 + cec_out_report_power_status(splitter, input_adap); 508 + return 0; 509 + } 510 + 511 + case CEC_MSG_REPORT_CURRENT_LATENCY: { 512 + u8 video_lat; 513 + u8 low_lat_mode; 514 + u8 audio_out_comp; 515 + u8 audio_out_delay; 516 + 517 + cec_ops_report_current_latency(msg, &pa, 518 + &video_lat, &low_lat_mode, 519 + &audio_out_comp, &audio_out_delay); 520 + if (!video_lat || video_lat >= 252) 521 + video_lat = 1; 522 + p->video_latency = video_lat; 523 + if (p->out_request_current_latency_seq == seq) { 524 + p->out_request_current_latency_seq = 0; 525 + p->out_request_current_latency_ts = ktime_set(0, 0); 526 + } 527 + cec_out_report_current_latency(splitter, input_adap); 528 + return 0; 529 + } 530 + 531 + case CEC_MSG_STANDBY: 532 + case CEC_MSG_ROUTING_CHANGE: 533 + case CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS: 534 + return 0; 535 + 536 + case CEC_MSG_ACTIVE_SOURCE: 537 + cec_ops_active_source(msg, &pa); 538 + if (pa == 0) 539 + p->is_active_source = false; 540 + return 0; 541 + 542 + case CEC_MSG_REQUEST_ACTIVE_SOURCE: 543 + if (!p->is_active_source) 544 + return 0; 545 + cec_msg_set_reply_to(&reply, msg); 546 + cec_msg_active_source(&reply, adap->phys_addr); 547 + cec_transmit_msg(adap, &reply, false); 548 + return 0; 549 + 550 + case CEC_MSG_GIVE_DEVICE_POWER_STATUS: 551 + cec_msg_set_reply_to(&reply, msg); 552 + cec_msg_report_power_status(&reply, splitter->is_standby ? 553 + CEC_OP_POWER_STATUS_STANDBY : 554 + CEC_OP_POWER_STATUS_ON); 555 + cec_transmit_msg(adap, &reply, false); 556 + return 0; 557 + 558 + case CEC_MSG_SET_STREAM_PATH: 559 + cec_ops_set_stream_path(msg, &pa); 560 + if (pa == adap->phys_addr) { 561 + cec_msg_set_reply_to(&reply, msg); 562 + cec_msg_active_source(&reply, pa); 563 + cec_transmit_msg(adap, &reply, false); 564 + } 565 + return 0; 566 + 567 + default: 568 + return -ENOMSG; 569 + } 570 + return -ENOMSG; 571 + } 572 + 573 + /* 574 + * Called every second to check for timed out messages and whether there 575 + * still is a video sink connected or not. 576 + * 577 + * Returns true if sinks were lost. 578 + */ 579 + bool cec_splitter_poll(struct cec_splitter *splitter, 580 + struct cec_adapter *input_adap, bool debug) 581 + { 582 + ktime_t now = ktime_get(); 583 + u8 pwr = splitter->is_standby ? 584 + CEC_OP_POWER_STATUS_STANDBY : CEC_OP_POWER_STATUS_ON; 585 + unsigned int max_delay_ms = input_adap->xfer_timeout_ms + 2000; 586 + unsigned int i; 587 + bool res = false; 588 + 589 + for (i = 0; i < splitter->num_out_ports; i++) { 590 + struct cec_splitter_port *p = splitter->ports[i]; 591 + s64 pwr_delta, lat_delta; 592 + bool pwr_timeout, lat_timeout; 593 + 594 + if (!p) 595 + continue; 596 + 597 + pwr_delta = ktime_ms_delta(now, p->out_give_device_power_status_ts); 598 + pwr_timeout = p->out_give_device_power_status_seq && 599 + pwr_delta >= max_delay_ms; 600 + lat_delta = ktime_ms_delta(now, p->out_request_current_latency_ts); 601 + lat_timeout = p->out_request_current_latency_seq && 602 + lat_delta >= max_delay_ms; 603 + 604 + /* 605 + * If the HPD is low for more than 5 seconds, then assume no display 606 + * is connected. 607 + */ 608 + if (p->found_sink && ktime_to_ns(p->lost_sink_ts) && 609 + ktime_ms_delta(now, p->lost_sink_ts) > 5000) { 610 + if (debug) 611 + dev_info(splitter->dev, 612 + "port %u: HPD low for more than 5s, assume no sink is connected.\n", 613 + p->port); 614 + p->found_sink = false; 615 + p->lost_sink_ts = ktime_set(0, 0); 616 + res = true; 617 + } 618 + 619 + /* 620 + * If the power status request timed out, then set the port's 621 + * power status to that of the splitter, ensuring a consistent 622 + * power state. 623 + */ 624 + if (pwr_timeout) { 625 + mutex_lock(&p->adap->lock); 626 + if (debug) 627 + dev_info(splitter->dev, 628 + "port %u: give up on power status for seq %u\n", 629 + p->port, 630 + p->out_give_device_power_status_seq & ~(1 << 31)); 631 + p->power_status = pwr; 632 + p->out_give_device_power_status_seq = 0; 633 + p->out_give_device_power_status_ts = ktime_set(0, 0); 634 + mutex_unlock(&p->adap->lock); 635 + cec_out_report_power_status(splitter, input_adap); 636 + } 637 + 638 + /* 639 + * If the current latency request timed out, then set the port's 640 + * latency to 1. 641 + */ 642 + if (lat_timeout) { 643 + mutex_lock(&p->adap->lock); 644 + if (debug) 645 + dev_info(splitter->dev, 646 + "port %u: give up on latency for seq %u\n", 647 + p->port, 648 + p->out_request_current_latency_seq & ~(1 << 31)); 649 + p->video_latency = 1; 650 + p->out_request_current_latency_seq = 0; 651 + p->out_request_current_latency_ts = ktime_set(0, 0); 652 + mutex_unlock(&p->adap->lock); 653 + cec_out_report_current_latency(splitter, input_adap); 654 + } 655 + } 656 + return res; 657 + }
+51
drivers/media/cec/usb/extron-da-hd-4k-plus/cec-splitter.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + /* 4 + * Copyright 2021-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 + */ 6 + 7 + #ifndef _CEC_SPLITTER_H_ 8 + #define _CEC_SPLITTER_H_ 9 + 10 + struct cec_splitter; 11 + 12 + #define STATE_CHANGE_MAX_REPEATS 2 13 + 14 + struct cec_splitter_port { 15 + struct cec_splitter *splitter; 16 + struct cec_adapter *adap; 17 + unsigned int port; 18 + bool is_active_source; 19 + bool found_sink; 20 + ktime_t lost_sink_ts; 21 + u32 out_request_current_latency_seq; 22 + ktime_t out_request_current_latency_ts; 23 + u8 video_latency; 24 + u32 out_give_device_power_status_seq; 25 + ktime_t out_give_device_power_status_ts; 26 + u8 power_status; 27 + }; 28 + 29 + struct cec_splitter { 30 + struct device *dev; 31 + unsigned int num_out_ports; 32 + struct cec_splitter_port **ports; 33 + 34 + /* High-level splitter state */ 35 + u8 request_current_latency_dest; 36 + u8 give_device_power_status_dest; 37 + bool is_standby; 38 + }; 39 + 40 + void cec_splitter_unconfigured_output(struct cec_splitter_port *port); 41 + void cec_splitter_configured_output(struct cec_splitter_port *port); 42 + int cec_splitter_received_input(struct cec_splitter_port *port, struct cec_msg *msg); 43 + int cec_splitter_received_output(struct cec_splitter_port *port, struct cec_msg *msg, 44 + struct cec_adapter *input_adap); 45 + void cec_splitter_nb_transmit_canceled_output(struct cec_splitter_port *port, 46 + const struct cec_msg *msg, 47 + struct cec_adapter *input_adap); 48 + bool cec_splitter_poll(struct cec_splitter *splitter, 49 + struct cec_adapter *input_adap, bool debug); 50 + 51 + #endif
+1836
drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright 2021-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 4 + */ 5 + 6 + /* 7 + * Currently this driver does not fully support the serial port of the 8 + * Extron, only the USB port is fully supported. 9 + * 10 + * Issues specific to using the serial port instead of the USB since the 11 + * serial port doesn't detect if the device is powered off: 12 + * 13 + * - Some periodic ping mechanism is needed to detect when the Extron is 14 + * powered off and when it is powered on again. 15 + * - What to do when it is powered off and the driver is modprobed? Keep 16 + * trying to contact the Extron indefinitely? 17 + */ 18 + 19 + #include <linux/completion.h> 20 + #include <linux/ctype.h> 21 + #include <linux/delay.h> 22 + #include <linux/init.h> 23 + #include <linux/interrupt.h> 24 + #include <linux/kernel.h> 25 + #include <linux/module.h> 26 + #include <linux/slab.h> 27 + #include <linux/time.h> 28 + 29 + #include "extron-da-hd-4k-plus.h" 30 + 31 + MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>"); 32 + MODULE_DESCRIPTION("Extron DA HD 4K PLUS HDMI CEC driver"); 33 + MODULE_LICENSE("GPL"); 34 + 35 + static int debug; 36 + module_param(debug, int, 0644); 37 + MODULE_PARM_DESC(debug, "debug level (0-1)"); 38 + 39 + static unsigned int vendor_id; 40 + module_param(vendor_id, uint, 0444); 41 + MODULE_PARM_DESC(vendor_id, "CEC Vendor ID"); 42 + 43 + static char manufacturer_name[4]; 44 + module_param_string(manufacturer_name, manufacturer_name, 45 + sizeof(manufacturer_name), 0644); 46 + MODULE_PARM_DESC(manufacturer_name, 47 + "EDID Vendor String (3 uppercase characters)"); 48 + 49 + static bool hpd_never_low; 50 + module_param(hpd_never_low, bool, 0644); 51 + MODULE_PARM_DESC(hpd_never_low, "Input HPD will never go low (1), or go low if all output HPDs are low (0, default)"); 52 + 53 + #define EXTRON_TIMEOUT_SECS 6 54 + 55 + static const u8 hdmi_edid[256] = { 56 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 57 + 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 + 0x01, 0x20, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, 59 + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 60 + 0x0f, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01, 61 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 62 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 63 + 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, 64 + 0x45, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, 65 + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, 66 + 0x87, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 67 + 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, 68 + 0x64, 0x6d, 0x69, 0x2d, 0x31, 0x30, 0x38, 0x30, 69 + 0x70, 0x36, 0x30, 0x0a, 0x00, 0x00, 0x00, 0xfe, 70 + 0x00, 0x73, 0x65, 0x72, 0x69, 0x6f, 0x0a, 0x20, 71 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x95, 72 + 73 + 0x02, 0x03, 0x1b, 0xf1, 0x42, 0x10, 0x01, 0x23, 74 + 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x68, 75 + 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x21, 0x01, 76 + 0xe2, 0x00, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 77 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 79 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 80 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 82 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 84 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 85 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 86 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 87 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 88 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 89 + }; 90 + 91 + static const u8 hdmi_edid_4k_300[256] = { 92 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 93 + 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 + 0x01, 0x20, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, 95 + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 96 + 0x0f, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01, 97 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 98 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 99 + 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, 100 + 0x45, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, 101 + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, 102 + 0x87, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 103 + 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, 104 + 0x64, 0x6d, 0x69, 0x2d, 0x34, 0x6b, 0x2d, 0x36, 105 + 0x30, 0x30, 0x0a, 0x20, 0x00, 0x00, 0x00, 0xfe, 106 + 0x00, 0x73, 0x65, 0x72, 0x69, 0x6f, 0x0a, 0x20, 107 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x87, 108 + 109 + 0x02, 0x03, 0x1f, 0xf1, 0x43, 0x10, 0x5f, 0x01, 110 + 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 111 + 0x6b, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 112 + 0x21, 0x00, 0x20, 0x01, 0xe2, 0x00, 0xca, 0x00, 113 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 119 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 121 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 122 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 125 + }; 126 + 127 + static const u8 hdmi_edid_4k_600[256] = { 128 + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 129 + 0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 + 0x01, 0x20, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, 131 + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 132 + 0x0f, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01, 133 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 134 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xe8, 135 + 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58, 136 + 0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, 137 + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, 138 + 0x87, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 139 + 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, 140 + 0x64, 0x6d, 0x69, 0x2d, 0x34, 0x6b, 0x2d, 0x36, 141 + 0x30, 0x30, 0x0a, 0x20, 0x00, 0x00, 0x00, 0xfe, 142 + 0x00, 0x73, 0x65, 0x72, 0x69, 0x6f, 0x0a, 0x20, 143 + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x4c, 144 + 145 + 0x02, 0x03, 0x28, 0xf1, 0x44, 0x61, 0x5f, 0x10, 146 + 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 147 + 0x00, 0x6b, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 148 + 0x3c, 0x21, 0x00, 0x20, 0x01, 0x67, 0xd8, 0x5d, 149 + 0xc4, 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 150 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 152 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 153 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 154 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 155 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 158 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 161 + }; 162 + 163 + static int extron_send_byte(struct serio *serio, char byte) 164 + { 165 + int err, i; 166 + 167 + for (i = 0; i < 100; i++) { 168 + err = serio_write(serio, byte); 169 + if (!err) 170 + break; 171 + usleep_range(80, 120); 172 + } 173 + if (err) 174 + dev_warn(&serio->dev, "unable to write byte after 100 attempts\n"); 175 + return err ? -EIO : 0; 176 + } 177 + 178 + static int extron_send_len(struct serio *serio, const char *command, 179 + const unsigned char *bin, unsigned int len) 180 + { 181 + int err = 0; 182 + 183 + for (; !err && *command; command++) 184 + err = extron_send_byte(serio, *command); 185 + if (!err) 186 + err = extron_send_byte(serio, '\r'); 187 + if (bin) 188 + for (; !err && len; len--) 189 + err = extron_send_byte(serio, *bin++); 190 + return err; 191 + } 192 + 193 + static int extron_send_and_wait_len(struct extron *extron, struct extron_port *port, 194 + const char *cmd, const unsigned char *bin, 195 + unsigned int len, const char *response) 196 + { 197 + int timeout = EXTRON_TIMEOUT_SECS * HZ; 198 + int err; 199 + 200 + if (debug) { 201 + if (response) 202 + dev_info(extron->dev, "transmit %s (response: %s)\n", 203 + cmd, response); 204 + else 205 + dev_info(extron->dev, "transmit %s\n", cmd); 206 + } 207 + 208 + mutex_lock(&extron->serio_lock); 209 + if (port) { 210 + init_completion(&port->cmd_done); 211 + port->cmd_error = 0; 212 + port->response = response; 213 + } else { 214 + init_completion(&extron->cmd_done); 215 + extron->cmd_error = 0; 216 + extron->response = response; 217 + } 218 + err = extron_send_len(extron->serio, cmd, bin, len); 219 + 220 + if (!err && response && 221 + !wait_for_completion_timeout(port ? &port->cmd_done : &extron->cmd_done, timeout)) { 222 + dev_info(extron->dev, "transmit %s failed with %s (expected: %s)\n", 223 + cmd, extron->reply, response); 224 + err = -ETIMEDOUT; 225 + } 226 + 227 + if (!err && response && (port ? port->cmd_error : extron->cmd_error)) { 228 + dev_info(extron->dev, "transmit %s failed with E%02u (expected: %s)\n", 229 + cmd, port ? port->cmd_error : extron->cmd_error, response); 230 + if (port) 231 + port->cmd_error = 0; 232 + else 233 + extron->cmd_error = 0; 234 + err = -EPROTO; 235 + } 236 + if (port) 237 + port->response = NULL; 238 + else 239 + extron->response = NULL; 240 + mutex_unlock(&extron->serio_lock); 241 + return err; 242 + } 243 + 244 + static int extron_send_and_wait(struct extron *extron, struct extron_port *port, 245 + const char *cmd, const char *response) 246 + { 247 + return extron_send_and_wait_len(extron, port, cmd, NULL, 0, response); 248 + } 249 + 250 + static void extron_parse_edid(struct extron_port *port) 251 + { 252 + const u8 *edid = port->edid; 253 + unsigned int i, end; 254 + u8 d; 255 + 256 + port->has_4kp30 = false; 257 + port->has_4kp60 = false; 258 + port->has_qy = false; 259 + port->has_qs = false; 260 + /* Store Established Timings 1 and 2 */ 261 + port->est_i = edid[0x23]; 262 + port->est_ii = edid[0x24]; 263 + 264 + // Check DTDs in base block 265 + for (i = 0; i < 4; i++) { 266 + const u8 *dtd = edid + 0x36 + i * 18; 267 + unsigned int w, h; 268 + unsigned int mhz; 269 + u64 pclk; 270 + 271 + if (!dtd[0] && !dtd[1]) 272 + continue; 273 + w = dtd[2] + ((dtd[4] & 0xf0) << 4); 274 + h = dtd[5] + ((dtd[7] & 0xf0) << 4); 275 + if (w != 3840 || h != 2160) 276 + continue; 277 + 278 + w += dtd[3] + ((dtd[4] & 0x0f) << 8); 279 + h += dtd[6] + ((dtd[7] & 0x0f) << 8); 280 + pclk = dtd[0] + (dtd[1] << 8); 281 + pclk *= 100000; 282 + mhz = div_u64(pclk, w * h); 283 + if (mhz >= 297) 284 + port->has_4kp30 = true; 285 + if (mhz >= 594) 286 + port->has_4kp60 = true; 287 + } 288 + 289 + if (port->edid_blocks == 1) 290 + return; 291 + 292 + edid += 128; 293 + 294 + /* Return if not a CTA-861 extension block */ 295 + if (edid[0] != 0x02 || edid[1] != 0x03) 296 + return; 297 + 298 + /* search Video Data Block (tag 2) */ 299 + d = edid[2] & 0x7f; 300 + /* Check if there are Data Blocks */ 301 + if (d <= 4) 302 + return; 303 + 304 + i = 4; 305 + end = d; 306 + 307 + do { 308 + u8 tag = edid[i] >> 5; 309 + u8 len = edid[i] & 0x1f; 310 + 311 + /* Avoid buffer overrun in case the EDID is malformed */ 312 + if (i + len + 1 > 0x7f) 313 + return; 314 + 315 + switch (tag) { 316 + case 2: /* Video Data Block */ 317 + /* Search for VIC 97 */ 318 + if (memchr(edid + i + 1, 97, len)) 319 + port->has_4kp60 = true; 320 + /* Search for VIC 95 */ 321 + if (memchr(edid + i + 1, 95, len)) 322 + port->has_4kp30 = true; 323 + break; 324 + 325 + case 7: /* Use Extended Tag */ 326 + switch (edid[i + 1]) { 327 + case 0: /* Video Capability Data Block */ 328 + if (edid[i + 2] & 0x80) 329 + port->has_qy = true; 330 + if (edid[i + 2] & 0x40) 331 + port->has_qs = true; 332 + break; 333 + } 334 + break; 335 + } 336 + i += len + 1; 337 + } while (i < end); 338 + } 339 + 340 + static int get_edid_tag_location(const u8 *edid, unsigned int size, 341 + u8 want_tag, u8 ext_tag) 342 + { 343 + unsigned int offset = 128; 344 + int i, end; 345 + u8 d; 346 + 347 + edid += offset; 348 + 349 + /* Return if not a CTA-861 extension block */ 350 + if (size < 256 || edid[0] != 0x02 || edid[1] != 0x03) 351 + return -1; 352 + 353 + /* search tag */ 354 + d = edid[0x02] & 0x7f; 355 + if (d <= 4) 356 + return -1; 357 + 358 + i = 0x04; 359 + end = 0x00 + d; 360 + 361 + do { 362 + unsigned char tag = edid[i] >> 5; 363 + unsigned char len = edid[i] & 0x1f; 364 + 365 + if (tag != want_tag || i + len > end) { 366 + i += len + 1; 367 + continue; 368 + } 369 + 370 + if (tag < 7 || (len >= 1 && edid[i + 1] == ext_tag)) 371 + return offset + i; 372 + i += len + 1; 373 + } while (i < end); 374 + return -1; 375 + } 376 + 377 + static void extron_edid_crc(u8 *edid) 378 + { 379 + u8 sum = 0; 380 + int offset; 381 + 382 + /* Update CRC */ 383 + for (offset = 0; offset < 127; offset++) 384 + sum += edid[offset]; 385 + edid[127] = 256 - sum; 386 + } 387 + 388 + /* 389 + * Fill in EDID string. As per VESA EDID-1.3, strings are at most 13 chars 390 + * long. If shorter then add a 0x0a character after the string and pad the 391 + * remainder with spaces. 392 + */ 393 + static void extron_set_edid_string(u8 *start, const char *s) 394 + { 395 + const unsigned int max_len = 13; 396 + int len = strlen(s); 397 + 398 + memset(start, ' ', max_len); 399 + if (len > max_len) 400 + len = max_len; 401 + memcpy(start, s, len); 402 + if (len < max_len) 403 + start[len] = 0x0a; 404 + } 405 + 406 + static void extron_update_edid(struct extron_port *port, unsigned int blocks) 407 + { 408 + int offset; 409 + u8 c1, c2; 410 + 411 + c1 = ((manufacturer_name[0] - '@') << 2) | 412 + (((manufacturer_name[1] - '@') >> 3) & 0x03); 413 + c2 = (((manufacturer_name[1] - '@') & 0x07) << 5) | 414 + ((manufacturer_name[2] - '@') & 0x1f); 415 + 416 + port->edid_tmp[8] = c1; 417 + port->edid_tmp[9] = c2; 418 + 419 + /* Set Established Timings, but always enable VGA */ 420 + port->edid_tmp[0x23] = port->est_i | 0x20; 421 + port->edid_tmp[0x24] = port->est_ii; 422 + 423 + /* Set the Monitor Name to the unit name */ 424 + extron_set_edid_string(port->edid_tmp + 0x5f, port->extron->unit_name); 425 + /* Set the ASCII String to the CEC adapter name */ 426 + extron_set_edid_string(port->edid_tmp + 0x71, port->adap->name); 427 + 428 + extron_edid_crc(port->edid_tmp); 429 + 430 + /* Find Video Capability Data Block */ 431 + offset = get_edid_tag_location(port->edid_tmp, blocks * 128, 7, 0); 432 + if (offset > 0) { 433 + port->edid_tmp[offset + 2] &= ~0xc0; 434 + if (port->has_qy) 435 + port->edid_tmp[offset + 2] |= 0x80; 436 + if (port->has_qs) 437 + port->edid_tmp[offset + 2] |= 0x40; 438 + } 439 + 440 + extron_edid_crc(port->edid_tmp + 128); 441 + } 442 + 443 + static int extron_write_edid(struct extron_port *port, 444 + const u8 *edid, unsigned int blocks) 445 + { 446 + struct extron *extron = port->extron; 447 + u16 phys_addr = CEC_PHYS_ADDR_INVALID; 448 + int ret; 449 + 450 + if (cec_get_edid_spa_location(edid, blocks * 128)) 451 + phys_addr = 0; 452 + 453 + if (mutex_lock_interruptible(&extron->edid_lock)) 454 + return -EINTR; 455 + 456 + memcpy(port->edid_tmp, edid, blocks * 128); 457 + 458 + if (manufacturer_name[0]) 459 + extron_update_edid(port, blocks); 460 + 461 + ret = extron_send_and_wait_len(port->extron, port, "W+UF256,in.bin", 462 + port->edid_tmp, sizeof(port->edid_tmp), 463 + "Upl"); 464 + if (ret) 465 + goto unlock; 466 + ret = extron_send_and_wait(port->extron, port, "WI1,in.binEDID", 467 + "EdidI01"); 468 + if (ret) 469 + goto unlock; 470 + 471 + port->edid_blocks = blocks; 472 + memcpy(port->edid, port->edid_tmp, blocks * 128); 473 + port->read_edid = true; 474 + mutex_unlock(&extron->edid_lock); 475 + 476 + cec_s_phys_addr(port->adap, phys_addr, false); 477 + return 0; 478 + 479 + unlock: 480 + mutex_unlock(&extron->edid_lock); 481 + return ret; 482 + } 483 + 484 + static void update_edid_work(struct work_struct *w) 485 + { 486 + struct extron *extron = container_of(w, struct extron, 487 + work_update_edid.work); 488 + struct extron_port *in = extron->ports[extron->num_out_ports]; 489 + struct extron_port *p; 490 + bool has_edid = false; 491 + bool has_4kp30 = true; 492 + bool has_4kp60 = true; 493 + bool has_qy = true; 494 + bool has_qs = true; 495 + u8 est_i = 0xff; 496 + u8 est_ii = 0xff; 497 + unsigned int out; 498 + 499 + for (out = 0; has_4kp60 && out < extron->num_out_ports; out++) { 500 + p = extron->ports[out]; 501 + if (p->read_edid) { 502 + has_4kp60 = p->has_4kp60; 503 + est_i &= p->est_i; 504 + est_ii &= p->est_ii; 505 + has_edid = true; 506 + } 507 + } 508 + for (out = 0; has_4kp30 && out < extron->num_out_ports; out++) 509 + if (extron->ports[out]->read_edid) 510 + has_4kp30 = extron->ports[out]->has_4kp30; 511 + 512 + for (out = 0; has_qy && out < extron->num_out_ports; out++) 513 + if (extron->ports[out]->read_edid) 514 + has_qy = extron->ports[out]->has_qy; 515 + 516 + for (out = 0; has_qs && out < extron->num_out_ports; out++) 517 + if (extron->ports[out]->read_edid) 518 + has_qs = extron->ports[out]->has_qs; 519 + 520 + /* exit if no output port had an EDID */ 521 + if (!has_edid) 522 + return; 523 + 524 + /* exit if the input EDID properties remained unchanged */ 525 + if (has_4kp60 == in->has_4kp60 && has_4kp30 == in->has_4kp30 && 526 + has_qy == in->has_qy && has_qs == in->has_qs && 527 + est_i == in->est_i && est_ii == in->est_ii) 528 + return; 529 + 530 + in->has_4kp60 = has_4kp60; 531 + in->has_4kp30 = has_4kp30; 532 + in->has_qy = has_qy; 533 + in->has_qs = has_qs; 534 + in->est_i = est_i; 535 + in->est_ii = est_ii; 536 + extron_write_edid(extron->ports[extron->num_out_ports], 537 + has_4kp60 ? hdmi_edid_4k_600 : 538 + (has_4kp30 ? hdmi_edid_4k_300 : hdmi_edid), 2); 539 + } 540 + 541 + static void extron_read_edid(struct extron_port *port) 542 + { 543 + struct extron *extron = port->extron; 544 + char cmd[10], reply[10]; 545 + unsigned int idx; 546 + 547 + idx = port->port.port + (port->is_input ? 0 : extron->num_in_ports); 548 + snprintf(cmd, sizeof(cmd), "WR%uEDID", idx); 549 + snprintf(reply, sizeof(reply), "EdidR%u", idx); 550 + if (mutex_lock_interruptible(&extron->edid_lock)) 551 + return; 552 + if (port->read_edid) 553 + goto unlock; 554 + extron->edid_bytes_read = 0; 555 + extron->edid_port = port; 556 + port->edid_blocks = 0; 557 + if (!port->has_edid) 558 + goto no_edid; 559 + 560 + extron->edid_reading = true; 561 + 562 + if (!extron_send_and_wait(extron, port, cmd, reply)) 563 + wait_for_completion_killable_timeout(&extron->edid_completion, 564 + msecs_to_jiffies(1000)); 565 + if (port->edid_blocks) { 566 + extron_parse_edid(port); 567 + port->read_edid = true; 568 + if (!port->is_input) 569 + v4l2_ctrl_s_ctrl(port->ctrl_tx_edid_present, 1); 570 + } 571 + no_edid: 572 + extron->edid_reading = false; 573 + unlock: 574 + mutex_unlock(&extron->edid_lock); 575 + cancel_delayed_work_sync(&extron->work_update_edid); 576 + if (manufacturer_name[0]) 577 + schedule_delayed_work(&extron->work_update_edid, 578 + msecs_to_jiffies(1000)); 579 + } 580 + 581 + static void extron_irq_work_handler(struct work_struct *work) 582 + { 583 + struct extron_port *port = 584 + container_of(work, struct extron_port, irq_work); 585 + struct extron *extron = port->extron; 586 + unsigned long flags; 587 + bool update_pa; 588 + u16 pa; 589 + bool update_has_signal; 590 + bool has_signal; 591 + bool update_has_edid; 592 + bool has_edid; 593 + u32 status; 594 + 595 + spin_lock_irqsave(&port->msg_lock, flags); 596 + while (port->rx_msg_num) { 597 + spin_unlock_irqrestore(&port->msg_lock, flags); 598 + cec_received_msg(port->adap, 599 + &port->rx_msg[port->rx_msg_cur_idx]); 600 + spin_lock_irqsave(&port->msg_lock, flags); 601 + if (port->rx_msg_num) 602 + port->rx_msg_num--; 603 + port->rx_msg_cur_idx = 604 + (port->rx_msg_cur_idx + 1) % NUM_MSGS; 605 + } 606 + update_pa = port->update_phys_addr; 607 + pa = port->phys_addr; 608 + port->update_phys_addr = false; 609 + update_has_signal = port->update_has_signal; 610 + has_signal = port->has_signal; 611 + port->update_has_signal = false; 612 + update_has_edid = port->update_has_edid; 613 + has_edid = port->has_edid; 614 + port->update_has_edid = false; 615 + status = port->tx_done_status; 616 + port->tx_done_status = 0; 617 + spin_unlock_irqrestore(&port->msg_lock, flags); 618 + 619 + if (status) 620 + cec_transmit_done(port->adap, status, 0, 0, 0, 0); 621 + 622 + if (update_has_signal && port->is_input) 623 + v4l2_ctrl_s_ctrl(port->ctrl_rx_power_present, has_signal); 624 + 625 + if (update_has_edid && !port->is_input) { 626 + v4l2_ctrl_s_ctrl(port->ctrl_tx_hotplug, 627 + port->has_edid); 628 + if (port->has_edid) { 629 + port->port.found_sink = true; 630 + port->port.lost_sink_ts = ktime_set(0, 0); 631 + } else { 632 + port->port.lost_sink_ts = ktime_get(); 633 + } 634 + if (!has_edid) { 635 + port->edid_blocks = 0; 636 + port->read_edid = false; 637 + if (extron->edid_reading && !has_edid && 638 + extron->edid_port == port) 639 + extron->edid_reading = false; 640 + v4l2_ctrl_s_ctrl(port->ctrl_tx_edid_present, 0); 641 + } else if (!extron->edid_reading || extron->edid_port != port) { 642 + extron_read_edid(port); 643 + } 644 + } 645 + if (update_pa) 646 + cec_s_phys_addr(port->adap, pa, false); 647 + } 648 + 649 + static void extron_process_received(struct extron_port *port, const char *data) 650 + { 651 + struct cec_msg msg = {}; 652 + unsigned int len = strlen(data); 653 + unsigned long irq_flags; 654 + unsigned int idx; 655 + 656 + if (!port || port->disconnected) 657 + return; 658 + 659 + if (len < 5 || (len - 2) % 3 || data[len - 2] != '*') 660 + goto malformed; 661 + 662 + while (*data != '*') { 663 + int v = hex2bin(&msg.msg[msg.len], data + 1, 1); 664 + 665 + if (*data != '%' || v) 666 + goto malformed; 667 + msg.len++; 668 + data += 3; 669 + } 670 + 671 + spin_lock_irqsave(&port->msg_lock, irq_flags); 672 + idx = (port->rx_msg_cur_idx + port->rx_msg_num) % 673 + NUM_MSGS; 674 + if (port->rx_msg_num == NUM_MSGS) { 675 + dev_warn(port->dev, 676 + "message queue is full, dropping %*ph\n", 677 + msg.len, msg.msg); 678 + spin_unlock_irqrestore(&port->msg_lock, 679 + irq_flags); 680 + return; 681 + } 682 + port->rx_msg_num++; 683 + port->rx_msg[idx] = msg; 684 + spin_unlock_irqrestore(&port->msg_lock, irq_flags); 685 + if (!port->disconnected) 686 + schedule_work(&port->irq_work); 687 + return; 688 + 689 + malformed: 690 + dev_info(port->extron->dev, "malformed msg received: '%s'\n", data); 691 + } 692 + 693 + static void extron_port_signal_change(struct extron_port *port, bool has_sig) 694 + { 695 + unsigned long irq_flags; 696 + bool update = false; 697 + 698 + if (!port) 699 + return; 700 + 701 + spin_lock_irqsave(&port->msg_lock, irq_flags); 702 + if (!port->update_has_signal && port->has_signal != has_sig) { 703 + port->update_has_signal = true; 704 + update = true; 705 + } 706 + port->has_signal = has_sig; 707 + spin_unlock_irqrestore(&port->msg_lock, irq_flags); 708 + if (update && !port->disconnected) 709 + schedule_work(&port->irq_work); 710 + } 711 + 712 + static void extron_process_signal_change(struct extron *extron, const char *data) 713 + { 714 + unsigned int i; 715 + 716 + extron_port_signal_change(extron->ports[extron->num_out_ports], 717 + data[0] == '1'); 718 + for (i = 0; i < extron->num_out_ports; i++) 719 + extron_port_signal_change(extron->ports[i], 720 + data[2 + 2 * i] != '0'); 721 + } 722 + 723 + static void extron_port_edid_change(struct extron_port *port, bool has_edid) 724 + { 725 + unsigned long irq_flags; 726 + bool update = false; 727 + 728 + if (!port) 729 + return; 730 + 731 + spin_lock_irqsave(&port->msg_lock, irq_flags); 732 + if (!port->update_has_edid && port->has_edid != has_edid) { 733 + port->update_has_edid = true; 734 + update = true; 735 + } 736 + port->has_edid = has_edid; 737 + spin_unlock_irqrestore(&port->msg_lock, irq_flags); 738 + if (update && !port->disconnected) 739 + schedule_work(&port->irq_work); 740 + } 741 + 742 + static void extron_process_edid_change(struct extron *extron, const char *data) 743 + { 744 + unsigned int i; 745 + 746 + /* 747 + * Do nothing if the Extron isn't ready yet. Trying to do this 748 + * while the Extron firmware is still settling will fail. 749 + */ 750 + if (!extron->is_ready) 751 + return; 752 + 753 + for (i = 0; i < extron->num_out_ports; i++) 754 + extron_port_edid_change(extron->ports[i], 755 + data[2 + 2 * i] != '0'); 756 + } 757 + 758 + static void extron_phys_addr_change(struct extron_port *port, u16 pa) 759 + { 760 + unsigned long irq_flags; 761 + bool update = false; 762 + 763 + if (!port) 764 + return; 765 + 766 + spin_lock_irqsave(&port->msg_lock, irq_flags); 767 + if (!port->update_phys_addr && port->phys_addr != pa) { 768 + update = true; 769 + port->update_phys_addr = true; 770 + } 771 + port->phys_addr = pa; 772 + spin_unlock_irqrestore(&port->msg_lock, irq_flags); 773 + if (update && !port->disconnected) 774 + schedule_work(&port->irq_work); 775 + } 776 + 777 + static void extron_process_tx_done(struct extron_port *port, char status) 778 + { 779 + unsigned long irq_flags; 780 + unsigned int tx_status; 781 + 782 + if (!port) 783 + return; 784 + 785 + switch (status) { 786 + case '0': 787 + tx_status = CEC_TX_STATUS_NACK | CEC_TX_STATUS_MAX_RETRIES; 788 + break; 789 + case '1': 790 + tx_status = CEC_TX_STATUS_OK; 791 + break; 792 + default: 793 + tx_status = CEC_TX_STATUS_ERROR; 794 + break; 795 + } 796 + spin_lock_irqsave(&port->msg_lock, irq_flags); 797 + port->tx_done_status = tx_status; 798 + spin_unlock_irqrestore(&port->msg_lock, irq_flags); 799 + if (!port->disconnected) 800 + schedule_work(&port->irq_work); 801 + } 802 + 803 + static void extron_add_edid(struct extron_port *port, const char *hex) 804 + { 805 + struct extron *extron = port ? port->extron : NULL; 806 + 807 + if (!port || port != extron->edid_port) 808 + return; 809 + while (extron->edid_bytes_read < sizeof(port->edid) && *hex) { 810 + int err = hex2bin(&port->edid[extron->edid_bytes_read], hex, 1); 811 + 812 + if (err) { 813 + extron->edid_reading = false; 814 + complete(&extron->edid_completion); 815 + break; 816 + } 817 + extron->edid_bytes_read++; 818 + hex += 2; 819 + } 820 + if (extron->edid_bytes_read == 128 && 821 + port->edid[126] == 0) { 822 + /* There are no extension blocks, we're done */ 823 + port->edid_blocks = 1; 824 + extron->edid_reading = false; 825 + complete(&extron->edid_completion); 826 + } 827 + if (extron->edid_bytes_read < sizeof(port->edid)) 828 + return; 829 + if (!*hex) 830 + port->edid_blocks = 2; 831 + extron->edid_reading = false; 832 + complete(&extron->edid_completion); 833 + } 834 + 835 + static irqreturn_t extron_interrupt(struct serio *serio, unsigned char data, 836 + unsigned int flags) 837 + { 838 + struct extron *extron = serio_get_drvdata(serio); 839 + struct extron_port *port = NULL; 840 + bool found_response; 841 + unsigned int p; 842 + 843 + if (data == '\r' || data == '\n') { 844 + if (extron->idx == 0) 845 + return IRQ_HANDLED; 846 + memcpy(extron->data, extron->buf, extron->idx); 847 + extron->len = extron->idx; 848 + extron->data[extron->len] = 0; 849 + if (debug) 850 + dev_info(extron->dev, "received %s\n", extron->data); 851 + extron->idx = 0; 852 + if (!memcmp(extron->data, "Sig", 3) && 853 + extron->data[4] == '*') { 854 + extron_process_signal_change(extron, extron->data + 3); 855 + } else if (!memcmp(extron->data, "Hdcp", 4) && 856 + extron->data[5] == '*') { 857 + extron_process_edid_change(extron, extron->data + 4); 858 + } else if (!memcmp(extron->data, "DcecI", 5) && 859 + extron->data[5] >= '1' && 860 + extron->data[5] < '1' + extron->num_in_ports) { 861 + unsigned int p = extron->data[5] - '1'; 862 + 863 + p += extron->num_out_ports; 864 + extron_process_tx_done(extron->ports[p], 865 + extron->data[extron->len - 1]); 866 + } else if (!memcmp(extron->data, "Ceci", 4) && 867 + extron->data[4] >= '1' && 868 + extron->data[4] < '1' + extron->num_in_ports && 869 + extron->data[5] == '*') { 870 + unsigned int p = extron->data[4] - '1'; 871 + 872 + p += extron->num_out_ports; 873 + extron_process_received(extron->ports[p], 874 + extron->data + 6); 875 + } else if (!memcmp(extron->data, "DcecO", 5) && 876 + extron->data[5] >= '1' && 877 + extron->data[5] < '1' + extron->num_out_ports) { 878 + unsigned int p = extron->data[5] - '1'; 879 + 880 + extron_process_tx_done(extron->ports[p], 881 + extron->data[extron->len - 1]); 882 + } else if (!memcmp(extron->data, "Ceco", 4) && 883 + extron->data[4] >= '1' && 884 + extron->data[4] < '1' + extron->num_out_ports && 885 + extron->data[5] == '*') { 886 + unsigned int p = extron->data[4] - '1'; 887 + 888 + extron_process_received(extron->ports[p], 889 + extron->data + 6); 890 + } else if (!memcmp(extron->data, "Pceco", 5) && 891 + extron->data[5] >= '1' && 892 + extron->data[5] < '1' + extron->num_out_ports) { 893 + unsigned int p = extron->data[5] - '1'; 894 + unsigned int tmp_pa[2] = { 0xff, 0xff }; 895 + 896 + if (sscanf(extron->data + 7, "%%%02x%%%02x", 897 + &tmp_pa[0], &tmp_pa[1]) == 2) 898 + extron_phys_addr_change(extron->ports[p], 899 + tmp_pa[0] << 8 | tmp_pa[1]); 900 + } else if (!memcmp(extron->data, "Pceci", 5) && 901 + extron->data[5] >= '1' && 902 + extron->data[5] < '1' + extron->num_in_ports) { 903 + unsigned int p = extron->data[5] - '1'; 904 + unsigned int tmp_pa[2] = { 0xff, 0xff }; 905 + 906 + p += extron->num_out_ports; 907 + if (sscanf(extron->data + 7, "%%%02x%%%02x", 908 + &tmp_pa[0], &tmp_pa[1]) == 2) 909 + extron_phys_addr_change(extron->ports[p], 910 + tmp_pa[0] << 8 | tmp_pa[1]); 911 + } else if (!memcmp(extron->data, "EdidR", 5) && 912 + extron->data[5] >= '1' && 913 + extron->data[5] < '1' + extron->num_ports && 914 + extron->data[6] == '*') { 915 + unsigned int p = extron->data[5] - '1'; 916 + 917 + if (p) 918 + p--; 919 + else 920 + p = extron->num_out_ports; 921 + extron_add_edid(extron->ports[p], extron->data + 7); 922 + } else if (extron->edid_reading && extron->len == 32 && 923 + extron->edid_port) { 924 + extron_add_edid(extron->edid_port, extron->data); 925 + } 926 + 927 + found_response = false; 928 + if (extron->response && 929 + !strncmp(extron->response, extron->data, 930 + strlen(extron->response))) 931 + found_response = true; 932 + 933 + for (p = 0; !found_response && p < extron->num_ports; p++) { 934 + port = extron->ports[p]; 935 + if (port && port->response && 936 + !strncmp(port->response, extron->data, 937 + strlen(port->response))) 938 + found_response = true; 939 + } 940 + 941 + if (!found_response && extron->response && 942 + extron->data[0] == 'E' && 943 + isdigit(extron->data[1]) && 944 + isdigit(extron->data[2]) && 945 + !extron->data[3]) { 946 + extron->cmd_error = (extron->data[1] - '0') * 10 + 947 + extron->data[2] - '0'; 948 + extron->response = NULL; 949 + complete(&extron->cmd_done); 950 + } 951 + 952 + if (!found_response) 953 + return IRQ_HANDLED; 954 + 955 + memcpy(extron->reply, extron->data, extron->len); 956 + extron->reply[extron->len] = 0; 957 + if (!port) { 958 + extron->response = NULL; 959 + complete(&extron->cmd_done); 960 + } else { 961 + port->response = NULL; 962 + complete(&port->cmd_done); 963 + } 964 + return IRQ_HANDLED; 965 + } 966 + 967 + if (extron->idx >= DATA_SIZE - 1) { 968 + dev_info(extron->dev, 969 + "throwing away %d bytes of garbage\n", extron->idx); 970 + extron->idx = 0; 971 + } 972 + extron->buf[extron->idx++] = (char)data; 973 + return IRQ_HANDLED; 974 + } 975 + 976 + static int extron_cec_adap_enable(struct cec_adapter *adap, bool enable) 977 + { 978 + struct extron_port *port = cec_get_drvdata(adap); 979 + 980 + return (port->disconnected && enable) ? -ENODEV : 0; 981 + } 982 + 983 + static int extron_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) 984 + { 985 + struct extron_port *port = cec_get_drvdata(adap); 986 + char cmd[26]; 987 + char resp[25]; 988 + u8 la = log_addr == CEC_LOG_ADDR_INVALID ? 15 : log_addr; 989 + int err; 990 + 991 + if (port->disconnected) 992 + return -ENODEV; 993 + snprintf(cmd, sizeof(cmd), "W%c%u*%uLCEC", 994 + port->direction, port->port.port, la); 995 + snprintf(resp, sizeof(resp), "Lcec%c%u*%u", 996 + port->direction, port->port.port, la); 997 + err = extron_send_and_wait(port->extron, port, cmd, resp); 998 + return log_addr != CEC_LOG_ADDR_INVALID && err ? err : 0; 999 + } 1000 + 1001 + static int extron_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, 1002 + u32 signal_free_time, struct cec_msg *msg) 1003 + { 1004 + struct extron_port *port = cec_get_drvdata(adap); 1005 + char buf[CEC_MAX_MSG_SIZE * 3 + 1]; 1006 + char cmd[CEC_MAX_MSG_SIZE * 3 + 13]; 1007 + unsigned int i; 1008 + 1009 + if (port->disconnected) 1010 + return -ENODEV; 1011 + buf[0] = 0; 1012 + for (i = 0; i < msg->len - 1; i++) 1013 + sprintf(buf + i * 3, "%%%02X", msg->msg[i + 1]); 1014 + snprintf(cmd, sizeof(cmd), "W%c%u*%u*%u*%sDCEC", 1015 + port->direction, port->port.port, 1016 + cec_msg_initiator(msg), cec_msg_destination(msg), buf); 1017 + return extron_send_and_wait(port->extron, port, cmd, NULL); 1018 + } 1019 + 1020 + static void extron_cec_adap_unconfigured(struct cec_adapter *adap) 1021 + { 1022 + struct extron_port *port = cec_get_drvdata(adap); 1023 + 1024 + if (port->disconnected) 1025 + return; 1026 + if (debug) 1027 + dev_info(port->extron->dev, "unconfigured port %d (%s)\n", 1028 + port->port.port, 1029 + port->extron->splitter.is_standby ? "Off" : "On"); 1030 + if (!port->is_input) 1031 + cec_splitter_unconfigured_output(&port->port); 1032 + } 1033 + 1034 + static void extron_cec_configured(struct cec_adapter *adap) 1035 + { 1036 + struct extron_port *port = cec_get_drvdata(adap); 1037 + 1038 + if (port->disconnected) 1039 + return; 1040 + if (debug) 1041 + dev_info(port->extron->dev, "configured port %d (%s)\n", 1042 + port->port.port, 1043 + port->extron->splitter.is_standby ? "Off" : "On"); 1044 + if (!port->is_input) 1045 + cec_splitter_configured_output(&port->port); 1046 + } 1047 + 1048 + static void extron_cec_adap_nb_transmit_canceled(struct cec_adapter *adap, 1049 + const struct cec_msg *msg) 1050 + { 1051 + struct extron_port *port = cec_get_drvdata(adap); 1052 + struct cec_adapter *input_adap; 1053 + 1054 + if (!vendor_id) 1055 + return; 1056 + if (port->disconnected || port->is_input) 1057 + return; 1058 + input_adap = port->extron->ports[port->extron->num_out_ports]->adap; 1059 + cec_splitter_nb_transmit_canceled_output(&port->port, msg, input_adap); 1060 + } 1061 + 1062 + static int extron_received(struct cec_adapter *adap, struct cec_msg *msg) 1063 + { 1064 + struct extron_port *port = cec_get_drvdata(adap); 1065 + 1066 + if (!vendor_id) 1067 + return -ENOMSG; 1068 + if (port->disconnected) 1069 + return -ENOMSG; 1070 + if (port->is_input) 1071 + return cec_splitter_received_input(&port->port, msg); 1072 + return cec_splitter_received_output(&port->port, msg, 1073 + port->extron->ports[port->extron->num_out_ports]->adap); 1074 + } 1075 + 1076 + #define log_printf(adap, file, fmt, arg...) \ 1077 + do { \ 1078 + if (file) \ 1079 + seq_printf((file), fmt, ## arg); \ 1080 + else \ 1081 + pr_info("cec-%s: " fmt, (adap)->name, ## arg); \ 1082 + } while (0) 1083 + 1084 + static const char * const pwr_state[] = { 1085 + "on", 1086 + "standby", 1087 + "to on", 1088 + "to standby", 1089 + }; 1090 + 1091 + static void extron_adap_status_port(struct extron_port *port, struct seq_file *file) 1092 + { 1093 + struct cec_adapter *adap = port->adap; 1094 + 1095 + if (port->disconnected) { 1096 + log_printf(adap, file, 1097 + "\tport %u: disconnected\n", port->port.port); 1098 + return; 1099 + } 1100 + if (port->is_input) 1101 + log_printf(adap, file, 1102 + "\tport %u: %s signal, %s edid, %s 4kp30, %s 4kp60, %sQS/%sQY, is %s\n", 1103 + port->port.port, 1104 + port->has_signal ? "has" : "no", 1105 + port->has_edid ? "has" : "no", 1106 + port->has_4kp30 ? "has" : "no", 1107 + port->has_4kp60 ? "has" : "no", 1108 + port->has_qs ? "" : "no ", 1109 + port->has_qy ? "" : "no ", 1110 + !port->port.adap->is_configured ? "not configured" : 1111 + pwr_state[port->extron->splitter.is_standby]); 1112 + else 1113 + log_printf(adap, file, 1114 + "\tport %u: %s sink, %s signal, %s edid, %s 4kp30, %s 4kp60, %sQS/%sQY, is %sactive source, is %s\n", 1115 + port->port.port, 1116 + port->port.found_sink ? "found" : "no", 1117 + port->has_signal ? "has" : "no", 1118 + port->has_edid ? "has" : "no", 1119 + port->has_4kp30 ? "has" : "no", 1120 + port->has_4kp60 ? "has" : "no", 1121 + port->has_qs ? "" : "no ", 1122 + port->has_qy ? "" : "no ", 1123 + port->port.is_active_source ? "" : "not ", 1124 + !port->port.adap->is_configured ? "not configured" : 1125 + pwr_state[port->port.power_status & 3]); 1126 + if (port->port.out_give_device_power_status_seq) 1127 + log_printf(adap, file, 1128 + "\tport %u: querying power status (%u, %lldms)\n", 1129 + port->port.port, 1130 + port->port.out_give_device_power_status_seq & ~(1 << 31), 1131 + ktime_ms_delta(ktime_get(), 1132 + port->port.out_give_device_power_status_ts)); 1133 + if (port->port.out_request_current_latency_seq) 1134 + log_printf(adap, file, 1135 + "\tport %u: querying latency (%u, %lldms)\n", 1136 + port->port.port, 1137 + port->port.out_request_current_latency_seq & ~(1 << 31), 1138 + ktime_ms_delta(ktime_get(), 1139 + port->port.out_request_current_latency_ts)); 1140 + } 1141 + 1142 + static void extron_adap_status(struct cec_adapter *adap, struct seq_file *file) 1143 + { 1144 + struct extron_port *port = cec_get_drvdata(adap); 1145 + struct extron *extron = port->extron; 1146 + unsigned int i; 1147 + 1148 + log_printf(adap, file, "name: %s type: %s\n", 1149 + extron->unit_name, extron->unit_type); 1150 + log_printf(adap, file, "model: 60-160%c-01 (1 input, %u outputs)\n", 1151 + '6' + extron->num_out_ports / 2, extron->num_out_ports); 1152 + log_printf(adap, file, "firmware version: %s CEC engine version: %s\n", 1153 + extron->unit_fw_version, extron->unit_cec_engine_version); 1154 + if (extron->hpd_never_low) 1155 + log_printf(adap, file, "always keep input HPD high\n"); 1156 + else 1157 + log_printf(adap, file, 1158 + "pull input HPD low if all output HPDs are low\n"); 1159 + if (vendor_id) 1160 + log_printf(adap, file, 1161 + "splitter vendor ID: 0x%06x\n", vendor_id); 1162 + if (manufacturer_name[0]) 1163 + log_printf(adap, file, "splitter manufacturer name: %s\n", 1164 + manufacturer_name); 1165 + log_printf(adap, file, "splitter power status: %s\n", 1166 + pwr_state[extron->splitter.is_standby]); 1167 + log_printf(adap, file, "%s port: %d (%s)\n", 1168 + port->is_input ? "input" : "output", 1169 + port->port.port, port->name); 1170 + log_printf(adap, file, "splitter input port:\n"); 1171 + extron_adap_status_port(extron->ports[extron->num_out_ports], file); 1172 + 1173 + log_printf(adap, file, "splitter output ports:\n"); 1174 + for (i = 0; i < extron->num_out_ports; i++) 1175 + extron_adap_status_port(extron->ports[i], file); 1176 + 1177 + if (!port->has_edid || !port->read_edid) 1178 + return; 1179 + 1180 + for (i = 0; i < port->edid_blocks * 128; i += 16) { 1181 + if (i % 128 == 0) 1182 + log_printf(adap, file, "\n"); 1183 + log_printf(adap, file, "EDID: %*ph\n", 16, port->edid + i); 1184 + } 1185 + } 1186 + 1187 + static const struct cec_adap_ops extron_cec_adap_ops = { 1188 + .adap_enable = extron_cec_adap_enable, 1189 + .adap_log_addr = extron_cec_adap_log_addr, 1190 + .adap_transmit = extron_cec_adap_transmit, 1191 + .adap_nb_transmit_canceled = extron_cec_adap_nb_transmit_canceled, 1192 + .adap_unconfigured = extron_cec_adap_unconfigured, 1193 + .adap_status = extron_adap_status, 1194 + .configured = extron_cec_configured, 1195 + .received = extron_received, 1196 + }; 1197 + 1198 + static int extron_querycap(struct file *file, void *priv, 1199 + struct v4l2_capability *cap) 1200 + { 1201 + struct extron_port *port = video_drvdata(file); 1202 + 1203 + strscpy(cap->driver, "extron-da-hd-4k-plus-cec", sizeof(cap->driver)); 1204 + strscpy(cap->card, cap->driver, sizeof(cap->card)); 1205 + snprintf(cap->bus_info, sizeof(cap->bus_info), "serio:%s", port->name); 1206 + return 0; 1207 + } 1208 + 1209 + static int extron_enum_input(struct file *file, void *priv, struct v4l2_input *inp) 1210 + { 1211 + struct extron_port *port = video_drvdata(file); 1212 + 1213 + if (inp->index) 1214 + return -EINVAL; 1215 + inp->type = V4L2_INPUT_TYPE_CAMERA; 1216 + snprintf(inp->name, sizeof(inp->name), "HDMI IN %u", port->port.port); 1217 + inp->status = v4l2_ctrl_g_ctrl(port->ctrl_rx_power_present) ? 1218 + 0 : V4L2_IN_ST_NO_SIGNAL; 1219 + return 0; 1220 + } 1221 + 1222 + static int extron_g_input(struct file *file, void *priv, unsigned int *i) 1223 + { 1224 + *i = 0; 1225 + return 0; 1226 + } 1227 + 1228 + static int extron_s_input(struct file *file, void *priv, unsigned int i) 1229 + { 1230 + return i ? -EINVAL : 0; 1231 + } 1232 + 1233 + static int extron_enum_output(struct file *file, void *priv, struct v4l2_output *out) 1234 + { 1235 + struct extron_port *port = video_drvdata(file); 1236 + 1237 + if (out->index) 1238 + return -EINVAL; 1239 + out->type = V4L2_OUTPUT_TYPE_ANALOG; 1240 + snprintf(out->name, sizeof(out->name), "HDMI OUT %u", port->port.port); 1241 + return 0; 1242 + } 1243 + 1244 + static int extron_g_output(struct file *file, void *priv, unsigned int *o) 1245 + { 1246 + *o = 0; 1247 + return 0; 1248 + } 1249 + 1250 + static int extron_s_output(struct file *file, void *priv, unsigned int o) 1251 + { 1252 + return o ? -EINVAL : 0; 1253 + } 1254 + 1255 + static int extron_g_edid(struct file *file, void *_fh, 1256 + struct v4l2_edid *edid) 1257 + { 1258 + struct extron_port *port = video_drvdata(file); 1259 + 1260 + memset(edid->reserved, 0, sizeof(edid->reserved)); 1261 + if (port->disconnected) 1262 + return -ENODEV; 1263 + if (edid->pad) 1264 + return -EINVAL; 1265 + if (!port->has_edid) 1266 + return -ENODATA; 1267 + if (!port->read_edid) 1268 + extron_read_edid(port); 1269 + if (!port->read_edid) 1270 + return -ENODATA; 1271 + if (edid->start_block == 0 && edid->blocks == 0) { 1272 + edid->blocks = port->edid_blocks; 1273 + return 0; 1274 + } 1275 + if (edid->start_block >= port->edid_blocks) 1276 + return -EINVAL; 1277 + if (edid->blocks > port->edid_blocks - edid->start_block) 1278 + edid->blocks = port->edid_blocks - edid->start_block; 1279 + memcpy(edid->edid, port->edid + edid->start_block * 128, edid->blocks * 128); 1280 + return 0; 1281 + } 1282 + 1283 + static int extron_s_edid(struct file *file, void *_fh, struct v4l2_edid *edid) 1284 + { 1285 + struct extron_port *port = video_drvdata(file); 1286 + 1287 + memset(edid->reserved, 0, sizeof(edid->reserved)); 1288 + if (port->disconnected) 1289 + return -ENODEV; 1290 + if (edid->pad) 1291 + return -EINVAL; 1292 + 1293 + /* Unfortunately it is not possible to clear the EDID */ 1294 + if (edid->blocks == 0) 1295 + return -EINVAL; 1296 + 1297 + if (edid->blocks > MAX_EDID_BLOCKS) { 1298 + edid->blocks = MAX_EDID_BLOCKS; 1299 + return -E2BIG; 1300 + } 1301 + 1302 + if (cec_get_edid_spa_location(edid->edid, edid->blocks * 128)) 1303 + v4l2_set_edid_phys_addr(edid->edid, edid->blocks * 128, 0); 1304 + extron_parse_edid(port); 1305 + return extron_write_edid(port, edid->edid, edid->blocks); 1306 + } 1307 + 1308 + static int extron_log_status(struct file *file, void *priv) 1309 + { 1310 + struct extron_port *port = video_drvdata(file); 1311 + 1312 + extron_adap_status(port->adap, NULL); 1313 + return v4l2_ctrl_log_status(file, priv); 1314 + } 1315 + 1316 + static const struct v4l2_ioctl_ops extron_ioctl_ops = { 1317 + .vidioc_querycap = extron_querycap, 1318 + .vidioc_enum_input = extron_enum_input, 1319 + .vidioc_g_input = extron_g_input, 1320 + .vidioc_s_input = extron_s_input, 1321 + .vidioc_enum_output = extron_enum_output, 1322 + .vidioc_g_output = extron_g_output, 1323 + .vidioc_s_output = extron_s_output, 1324 + .vidioc_g_edid = extron_g_edid, 1325 + .vidioc_s_edid = extron_s_edid, 1326 + .vidioc_log_status = extron_log_status, 1327 + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 1328 + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 1329 + }; 1330 + 1331 + static const struct v4l2_file_operations extron_fops = { 1332 + .owner = THIS_MODULE, 1333 + .open = v4l2_fh_open, 1334 + .release = v4l2_fh_release, 1335 + .poll = v4l2_ctrl_poll, 1336 + .unlocked_ioctl = video_ioctl2, 1337 + }; 1338 + 1339 + static const struct video_device extron_videodev = { 1340 + .name = "extron-da-hd-4k-plus-cec", 1341 + .vfl_dir = VFL_DIR_RX, 1342 + .fops = &extron_fops, 1343 + .ioctl_ops = &extron_ioctl_ops, 1344 + .minor = -1, 1345 + .release = video_device_release_empty, 1346 + }; 1347 + 1348 + static void extron_disconnect(struct serio *serio) 1349 + { 1350 + struct extron *extron = serio_get_drvdata(serio); 1351 + unsigned int p; 1352 + 1353 + kthread_stop(extron->kthread_setup); 1354 + 1355 + for (p = 0; p < extron->num_ports; p++) { 1356 + struct extron_port *port = extron->ports[p]; 1357 + 1358 + if (!port) 1359 + continue; 1360 + port->disconnected = true; 1361 + cancel_work_sync(&port->irq_work); 1362 + } 1363 + cancel_delayed_work_sync(&extron->work_update_edid); 1364 + for (p = 0; p < extron->num_ports; p++) { 1365 + struct extron_port *port = extron->ports[p]; 1366 + 1367 + if (!port) 1368 + continue; 1369 + 1370 + if (port->cec_was_registered) { 1371 + if (cec_is_registered(port->adap)) 1372 + cec_unregister_adapter(port->adap); 1373 + /* 1374 + * After registering the adapter, the 1375 + * extron_setup_thread() function took an extra 1376 + * reference to the device. We call the corresponding 1377 + * put here. 1378 + */ 1379 + cec_put_device(port->adap); 1380 + } else { 1381 + cec_delete_adapter(port->adap); 1382 + } 1383 + video_unregister_device(&port->vdev); 1384 + } 1385 + 1386 + complete(&extron->edid_completion); 1387 + 1388 + for (p = 0; p < extron->num_ports; p++) { 1389 + struct extron_port *port = extron->ports[p]; 1390 + 1391 + if (!port) 1392 + continue; 1393 + v4l2_ctrl_handler_free(&port->hdl); 1394 + mutex_destroy(&port->video_lock); 1395 + kfree(port); 1396 + } 1397 + mutex_destroy(&extron->edid_lock); 1398 + mutex_destroy(&extron->serio_lock); 1399 + extron->serio = NULL; 1400 + serio_set_drvdata(serio, NULL); 1401 + serio_close(serio); 1402 + } 1403 + 1404 + static int extron_setup(struct extron *extron) 1405 + { 1406 + struct serio *serio = extron->serio; 1407 + struct extron_port *port; 1408 + u8 *reply = extron->reply; 1409 + unsigned int p; 1410 + unsigned int major, minor; 1411 + int err; 1412 + 1413 + /* 1414 + * Attempt to disable CEC: avoid received CEC messages 1415 + * from interfering with the other serial port traffic. 1416 + */ 1417 + extron_send_and_wait(extron, NULL, "WI1*0CCEC", NULL); 1418 + extron_send_and_wait(extron, NULL, "WO0*CCEC", NULL); 1419 + 1420 + /* Obtain unit part number */ 1421 + err = extron_send_and_wait(extron, NULL, "N", "Pno"); 1422 + if (err) 1423 + return err; 1424 + dev_info(extron->dev, "Unit part number: %s\n", reply + 3); 1425 + if (strcmp(reply + 3, "60-1607-01") && 1426 + strcmp(reply + 3, "60-1608-01") && 1427 + strcmp(reply + 3, "60-1609-01")) { 1428 + dev_err(extron->dev, "Unsupported model\n"); 1429 + return -ENODEV; 1430 + } 1431 + /* Up to 6 output ports and one input port */ 1432 + extron->num_out_ports = 2 * (reply[9] - '6'); 1433 + extron->splitter.num_out_ports = extron->num_out_ports; 1434 + extron->splitter.ports = extron->splitter_ports; 1435 + extron->splitter.dev = extron->dev; 1436 + extron->num_in_ports = 1; 1437 + extron->num_ports = extron->num_out_ports + extron->num_in_ports; 1438 + dev_info(extron->dev, "Unit output ports: %d\n", extron->num_out_ports); 1439 + dev_info(extron->dev, "Unit input ports: %d\n", extron->num_in_ports); 1440 + 1441 + err = extron_send_and_wait(extron, NULL, "W CN", "Ipn "); 1442 + if (err) 1443 + return err; 1444 + dev_info(extron->dev, "Unit name: %s\n", reply + 4); 1445 + strscpy(extron->unit_name, reply + 4, sizeof(extron->unit_name)); 1446 + 1447 + err = extron_send_and_wait(extron, NULL, "*Q", "Bld"); 1448 + if (err) 1449 + return err; 1450 + dev_info(extron->dev, "Unit FW Version: %s\n", reply + 3); 1451 + strscpy(extron->unit_fw_version, reply + 3, 1452 + sizeof(extron->unit_fw_version)); 1453 + if (sscanf(reply + 3, "%u.%u.", &major, &minor) < 2 || 1454 + major < 1 || minor < 2) { 1455 + dev_err(extron->dev, 1456 + "Unsupported FW version (only 1.02 or up is supported)\n"); 1457 + return -ENODEV; 1458 + } 1459 + 1460 + err = extron_send_and_wait(extron, NULL, "2i", "Inf02*"); 1461 + if (err) 1462 + return err; 1463 + dev_info(extron->dev, "Unit Type: %s\n", reply + 6); 1464 + strscpy(extron->unit_type, reply + 6, sizeof(extron->unit_type)); 1465 + 1466 + err = extron_send_and_wait(extron, NULL, "39Q", "Ver39*"); 1467 + if (err) 1468 + return err; 1469 + dev_info(extron->dev, "CEC Engine Version: %s\n", reply + 6); 1470 + strscpy(extron->unit_cec_engine_version, reply + 6, 1471 + sizeof(extron->unit_cec_engine_version)); 1472 + 1473 + /* Disable CEC */ 1474 + err = extron_send_and_wait(extron, NULL, "WI1*0CCEC", "CcecI1*"); 1475 + if (err) 1476 + return err; 1477 + err = extron_send_and_wait(extron, NULL, "WO0*CCEC", "CcecO0"); 1478 + if (err) 1479 + return err; 1480 + 1481 + extron->hpd_never_low = hpd_never_low; 1482 + 1483 + /* Pull input port HPD low if all output ports also have a low HPD */ 1484 + if (hpd_never_low) { 1485 + dev_info(extron->dev, "Always keep input HPD high\n"); 1486 + } else { 1487 + dev_info(extron->dev, "Pull input HPD low if all output HPDs are low\n"); 1488 + extron_send_and_wait(extron, NULL, "W1ihpd", "Ihpd1"); 1489 + } 1490 + 1491 + for (p = 0; p < extron->num_ports; p++) { 1492 + u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL; 1493 + 1494 + if (vendor_id) 1495 + caps &= ~CEC_CAP_LOG_ADDRS; 1496 + port = kzalloc(sizeof(*port), GFP_KERNEL); 1497 + if (!port) 1498 + return -ENOMEM; 1499 + 1500 + INIT_WORK(&port->irq_work, extron_irq_work_handler); 1501 + spin_lock_init(&port->msg_lock); 1502 + mutex_init(&port->video_lock); 1503 + port->extron = extron; 1504 + port->is_input = p >= extron->num_out_ports; 1505 + port->direction = port->is_input ? 'I' : 'O'; 1506 + port->port.port = 1 + (port->is_input ? p - extron->num_out_ports : p); 1507 + port->port.splitter = &extron->splitter; 1508 + port->phys_addr = CEC_PHYS_ADDR_INVALID; 1509 + snprintf(port->name, sizeof(port->name), "%s-%s-%u", 1510 + dev_name(&serio->dev), port->is_input ? "in" : "out", 1511 + port->port.port); 1512 + 1513 + port->dev = extron->dev; 1514 + port->adap = cec_allocate_adapter(&extron_cec_adap_ops, port, 1515 + port->name, caps, 1); 1516 + err = PTR_ERR_OR_ZERO(port->adap); 1517 + if (err < 0) { 1518 + kfree(port); 1519 + return err; 1520 + } 1521 + 1522 + port->adap->xfer_timeout_ms = EXTRON_TIMEOUT_SECS * 1000; 1523 + port->port.adap = port->adap; 1524 + port->vdev = extron_videodev; 1525 + port->vdev.lock = &port->video_lock; 1526 + port->vdev.v4l2_dev = &extron->v4l2_dev; 1527 + port->vdev.ctrl_handler = &port->hdl; 1528 + port->vdev.device_caps = V4L2_CAP_EDID; 1529 + video_set_drvdata(&port->vdev, port); 1530 + 1531 + v4l2_ctrl_handler_init(&port->hdl, 2); 1532 + 1533 + if (port->is_input) { 1534 + port->vdev.vfl_dir = VFL_DIR_RX; 1535 + port->ctrl_rx_power_present = 1536 + v4l2_ctrl_new_std(&port->hdl, NULL, 1537 + V4L2_CID_DV_RX_POWER_PRESENT, 1538 + 0, 1, 0, 0); 1539 + port->has_edid = true; 1540 + } else { 1541 + port->vdev.vfl_dir = VFL_DIR_TX; 1542 + port->ctrl_tx_hotplug = 1543 + v4l2_ctrl_new_std(&port->hdl, NULL, 1544 + V4L2_CID_DV_TX_HOTPLUG, 1545 + 0, 1, 0, 0); 1546 + port->ctrl_tx_edid_present = 1547 + v4l2_ctrl_new_std(&port->hdl, NULL, 1548 + V4L2_CID_DV_TX_EDID_PRESENT, 1549 + 0, 1, 0, 0); 1550 + } 1551 + 1552 + err = port->hdl.error; 1553 + if (err < 0) { 1554 + cec_delete_adapter(port->adap); 1555 + kfree(port); 1556 + return err; 1557 + } 1558 + extron->ports[p] = port; 1559 + extron->splitter_ports[p] = &port->port; 1560 + if (port->is_input && manufacturer_name[0]) 1561 + extron_write_edid(port, hdmi_edid, 2); 1562 + } 1563 + 1564 + /* Enable CEC (manual mode, i.e. controlled by the driver) */ 1565 + err = extron_send_and_wait(extron, NULL, "WI1*20CCEC", "CcecI1*"); 1566 + if (err) 1567 + return err; 1568 + 1569 + err = extron_send_and_wait(extron, NULL, "WO20*CCEC", "CcecO20"); 1570 + if (err) 1571 + return err; 1572 + 1573 + /* Set logical addresses to 15 */ 1574 + err = extron_send_and_wait(extron, NULL, "WI1*15LCEC", "LcecI1*15"); 1575 + if (err) 1576 + return err; 1577 + 1578 + for (p = 0; p < extron->num_out_ports; p++) { 1579 + char cmd[20]; 1580 + char resp[20]; 1581 + 1582 + snprintf(cmd, sizeof(cmd), "WO%u*15LCEC", p + 1); 1583 + snprintf(resp, sizeof(resp), "LcecO%u*15", p + 1); 1584 + err = extron_send_and_wait(extron, extron->ports[p], cmd, resp); 1585 + if (err) 1586 + return err; 1587 + } 1588 + 1589 + /* 1590 + * The Extron is now ready for operation. Specifically it is now 1591 + * possible to retrieve EDIDs. 1592 + */ 1593 + extron->is_ready = true; 1594 + 1595 + /* Query HDCP and Signal states, used to update the initial state */ 1596 + err = extron_send_and_wait(extron, NULL, "WHDCP", "Hdcp"); 1597 + if (err) 1598 + return err; 1599 + 1600 + return extron_send_and_wait(extron, NULL, "WLS", "Sig"); 1601 + } 1602 + 1603 + static int extron_setup_thread(void *_extron) 1604 + { 1605 + struct extron *extron = _extron; 1606 + struct extron_port *port; 1607 + unsigned int p; 1608 + bool poll_splitter = false; 1609 + bool was_connected = true; 1610 + int err; 1611 + 1612 + while (1) { 1613 + if (kthread_should_stop()) 1614 + return 0; 1615 + err = extron_send_and_wait(extron, NULL, "W3CV", "Vrb3"); 1616 + // that should make it possible to detect a serio disconnect 1617 + // here by stopping the workqueue 1618 + if (err >= 0) 1619 + break; 1620 + was_connected = false; 1621 + ssleep(1); 1622 + } 1623 + 1624 + /* 1625 + * If the Extron was not connected at probe() time, i.e. it just got 1626 + * powered up and while the serial port is working, the firmware is 1627 + * still booting up, then wait 10 seconds for the firmware to settle. 1628 + * 1629 + * Trying to continue too soon means that some commands will not 1630 + * work yet. 1631 + */ 1632 + if (!was_connected) 1633 + ssleep(10); 1634 + 1635 + err = extron_setup(extron); 1636 + if (err) 1637 + goto disable_ports; 1638 + 1639 + for (p = 0; p < extron->num_ports; p++) { 1640 + struct cec_log_addrs log_addrs = {}; 1641 + 1642 + port = extron->ports[p]; 1643 + if (port->is_input && manufacturer_name[0]) 1644 + v4l2_disable_ioctl(&port->vdev, VIDIOC_S_EDID); 1645 + err = video_register_device(&port->vdev, VFL_TYPE_VIDEO, -1); 1646 + if (err) { 1647 + v4l2_err(&extron->v4l2_dev, "Failed to register video device\n"); 1648 + goto disable_ports; 1649 + } 1650 + 1651 + err = cec_register_adapter(port->adap, extron->dev); 1652 + if (err < 0) 1653 + goto disable_ports; 1654 + port->dev = &port->adap->devnode.dev; 1655 + port->cec_was_registered = true; 1656 + /* 1657 + * This driver is unusual in that the whole setup takes place 1658 + * in a thread since it can take such a long time before the 1659 + * Extron Splitter boots up, and you do not want to block the 1660 + * probe function on this driver. In addition, as soon as 1661 + * CEC adapters come online, they can be used, and you cannot 1662 + * just unregister them again if an error occurs, since that 1663 + * can delete the underlying CEC adapter, which might already 1664 + * be in use. 1665 + * 1666 + * So we take an additional reference to the adapter. This 1667 + * allows us to unregister the device node if needed, without 1668 + * deleting the actual adapter. 1669 + * 1670 + * In the disconnect function we will do the corresponding 1671 + * put call to ensure the adapter is deleted. 1672 + */ 1673 + cec_get_device(port->adap); 1674 + 1675 + /* 1676 + * If vendor_id wasn't set, then userspace configures the 1677 + * CEC devices. Otherwise the driver configures the CEC 1678 + * devices as TV (input) and Playback (outputs) devices 1679 + * and the driver processes all CEC messages. 1680 + */ 1681 + if (!vendor_id) 1682 + continue; 1683 + 1684 + log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0; 1685 + log_addrs.num_log_addrs = 1; 1686 + log_addrs.vendor_id = vendor_id; 1687 + if (port->is_input) { 1688 + strscpy(log_addrs.osd_name, "Splitter In", 1689 + sizeof(log_addrs.osd_name)); 1690 + log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_TV; 1691 + log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_TV; 1692 + log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_TV; 1693 + } else { 1694 + snprintf(log_addrs.osd_name, sizeof(log_addrs.osd_name), 1695 + "Splitter Out%u", port->port.port); 1696 + log_addrs.log_addr_type[0] = CEC_LOG_ADDR_TYPE_PLAYBACK; 1697 + log_addrs.primary_device_type[0] = CEC_OP_PRIM_DEVTYPE_PLAYBACK; 1698 + log_addrs.all_device_types[0] = CEC_OP_ALL_DEVTYPE_PLAYBACK; 1699 + } 1700 + err = cec_s_log_addrs(port->adap, &log_addrs, false); 1701 + if (err < 0) 1702 + goto disable_ports; 1703 + } 1704 + poll_splitter = true; 1705 + 1706 + port = extron->ports[extron->num_out_ports]; 1707 + while (!kthread_should_stop()) { 1708 + ssleep(1); 1709 + if (hpd_never_low != extron->hpd_never_low) { 1710 + /* 1711 + * Keep input port HPD high at all times, or pull it low 1712 + * if all output ports also have a low HPD 1713 + */ 1714 + if (hpd_never_low) { 1715 + dev_info(extron->dev, "Always keep input HPD high\n"); 1716 + extron_send_and_wait(extron, NULL, "W0ihpd", "Ihpd0"); 1717 + } else { 1718 + dev_info(extron->dev, "Pull input HPD low if all output HPDs are low\n"); 1719 + extron_send_and_wait(extron, NULL, "W1ihpd", "Ihpd1"); 1720 + } 1721 + extron->hpd_never_low = hpd_never_low; 1722 + } 1723 + if (poll_splitter && 1724 + cec_splitter_poll(&extron->splitter, port->adap, debug) && 1725 + manufacturer_name[0]) { 1726 + /* 1727 + * Sinks were lost, so see if the input edid needs to 1728 + * be updated. 1729 + */ 1730 + cancel_delayed_work_sync(&extron->work_update_edid); 1731 + schedule_delayed_work(&extron->work_update_edid, 1732 + msecs_to_jiffies(1000)); 1733 + } 1734 + } 1735 + return 0; 1736 + 1737 + disable_ports: 1738 + extron->is_ready = false; 1739 + for (p = 0; p < extron->num_ports; p++) { 1740 + struct extron_port *port = extron->ports[p]; 1741 + 1742 + if (!port) 1743 + continue; 1744 + port->disconnected = true; 1745 + cancel_work_sync(&port->irq_work); 1746 + video_unregister_device(&port->vdev); 1747 + if (port->cec_was_registered) 1748 + cec_unregister_adapter(port->adap); 1749 + } 1750 + cancel_delayed_work_sync(&extron->work_update_edid); 1751 + complete(&extron->edid_completion); 1752 + dev_err(extron->dev, "Setup failed with error %d\n", err); 1753 + while (!kthread_should_stop()) 1754 + ssleep(1); 1755 + return err; 1756 + } 1757 + 1758 + static int extron_connect(struct serio *serio, struct serio_driver *drv) 1759 + { 1760 + struct extron *extron; 1761 + int err = -ENOMEM; 1762 + 1763 + if (manufacturer_name[0] && 1764 + (!isupper(manufacturer_name[0]) || 1765 + !isupper(manufacturer_name[1]) || 1766 + !isupper(manufacturer_name[2]))) { 1767 + dev_warn(&serio->dev, "ignoring invalid manufacturer name\n"); 1768 + manufacturer_name[0] = 0; 1769 + } 1770 + 1771 + extron = kzalloc(sizeof(*extron), GFP_KERNEL); 1772 + 1773 + if (!extron) 1774 + return -ENOMEM; 1775 + 1776 + extron->serio = serio; 1777 + extron->dev = &serio->dev; 1778 + mutex_init(&extron->serio_lock); 1779 + mutex_init(&extron->edid_lock); 1780 + INIT_DELAYED_WORK(&extron->work_update_edid, update_edid_work); 1781 + 1782 + err = v4l2_device_register(extron->dev, &extron->v4l2_dev); 1783 + if (err) 1784 + goto free_device; 1785 + 1786 + err = serio_open(serio, drv); 1787 + if (err) 1788 + goto unreg_v4l2_dev; 1789 + 1790 + serio_set_drvdata(serio, extron); 1791 + init_completion(&extron->edid_completion); 1792 + 1793 + extron->kthread_setup = kthread_run(extron_setup_thread, extron, 1794 + "extron-da-hd-4k-plus-cec-%s", dev_name(&serio->dev)); 1795 + if (!IS_ERR(extron->kthread_setup)) 1796 + return 0; 1797 + 1798 + dev_err(extron->dev, "kthread_run() failed\n"); 1799 + err = PTR_ERR(extron->kthread_setup); 1800 + 1801 + extron->serio = NULL; 1802 + serio_set_drvdata(serio, NULL); 1803 + serio_close(serio); 1804 + unreg_v4l2_dev: 1805 + v4l2_device_unregister(&extron->v4l2_dev); 1806 + free_device: 1807 + mutex_destroy(&extron->edid_lock); 1808 + mutex_destroy(&extron->serio_lock); 1809 + kfree(extron); 1810 + return err; 1811 + } 1812 + 1813 + static const struct serio_device_id extron_serio_ids[] = { 1814 + { 1815 + .type = SERIO_RS232, 1816 + .proto = SERIO_EXTRON_DA_HD_4K_PLUS, 1817 + .id = SERIO_ANY, 1818 + .extra = SERIO_ANY, 1819 + }, 1820 + { 0 } 1821 + }; 1822 + 1823 + MODULE_DEVICE_TABLE(serio, extron_serio_ids); 1824 + 1825 + static struct serio_driver extron_drv = { 1826 + .driver = { 1827 + .name = "extron-da-hd-4k-plus-cec", 1828 + }, 1829 + .description = "Extron DA HD 4K PLUS HDMI CEC driver", 1830 + .id_table = extron_serio_ids, 1831 + .interrupt = extron_interrupt, 1832 + .connect = extron_connect, 1833 + .disconnect = extron_disconnect, 1834 + }; 1835 + 1836 + module_serio_driver(extron_drv);
+118
drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + /* 4 + * Copyright 2021-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 + */ 6 + 7 + #ifndef _EXTRON_DA_HD_4K_PLUS_H_ 8 + #define _EXTRON_DA_HD_4K_PLUS_H_ 9 + 10 + #include <linux/kthread.h> 11 + #include <linux/serio.h> 12 + #include <linux/workqueue.h> 13 + #include <media/cec.h> 14 + #include <media/v4l2-ctrls.h> 15 + #include <media/v4l2-dev.h> 16 + #include <media/v4l2-device.h> 17 + #include <media/v4l2-dv-timings.h> 18 + #include <media/v4l2-event.h> 19 + #include <media/v4l2-fh.h> 20 + #include <media/v4l2-ioctl.h> 21 + 22 + #include "cec-splitter.h" 23 + 24 + #define DATA_SIZE 256 25 + 26 + #define PING_PERIOD (15 * HZ) 27 + 28 + #define NUM_MSGS CEC_MAX_MSG_RX_QUEUE_SZ 29 + 30 + #define MAX_PORTS (1 + 6) 31 + 32 + #define MAX_EDID_BLOCKS 2 33 + 34 + struct extron; 35 + 36 + struct extron_port { 37 + struct cec_splitter_port port; 38 + struct device *dev; 39 + struct cec_adapter *adap; 40 + struct video_device vdev; 41 + struct v4l2_ctrl_handler hdl; 42 + struct v4l2_ctrl *ctrl_rx_power_present; 43 + struct v4l2_ctrl *ctrl_tx_hotplug; 44 + struct v4l2_ctrl *ctrl_tx_edid_present; 45 + bool is_input; 46 + char direction; 47 + char name[26]; 48 + unsigned char edid[MAX_EDID_BLOCKS * 128]; 49 + unsigned char edid_tmp[MAX_EDID_BLOCKS * 128]; 50 + unsigned int edid_blocks; 51 + bool read_edid; 52 + struct extron *extron; 53 + struct work_struct irq_work; 54 + struct completion cmd_done; 55 + const char *response; 56 + unsigned int cmd_error; 57 + struct cec_msg rx_msg[NUM_MSGS]; 58 + unsigned int rx_msg_cur_idx, rx_msg_num; 59 + /* protect rx_msg_cur_idx and rx_msg_num */ 60 + spinlock_t msg_lock; 61 + u32 tx_done_status; 62 + bool update_phys_addr; 63 + u16 phys_addr; 64 + bool cec_was_registered; 65 + bool disconnected; 66 + bool update_has_signal; 67 + bool has_signal; 68 + bool update_has_edid; 69 + bool has_edid; 70 + bool has_4kp30; 71 + bool has_4kp60; 72 + bool has_qy; 73 + bool has_qs; 74 + u8 est_i, est_ii; 75 + 76 + /* locks access to the video_device */ 77 + struct mutex video_lock; 78 + }; 79 + 80 + struct extron { 81 + struct cec_splitter splitter; 82 + struct device *dev; 83 + struct serio *serio; 84 + /* locks access to serio */ 85 + struct mutex serio_lock; 86 + unsigned int num_ports; 87 + unsigned int num_in_ports; 88 + unsigned int num_out_ports; 89 + char unit_name[32]; 90 + char unit_type[64]; 91 + char unit_fw_version[32]; 92 + char unit_cec_engine_version[32]; 93 + struct extron_port *ports[MAX_PORTS]; 94 + struct cec_splitter_port *splitter_ports[MAX_PORTS]; 95 + struct v4l2_device v4l2_dev; 96 + bool hpd_never_low; 97 + struct task_struct *kthread_setup; 98 + struct delayed_work work_update_edid; 99 + 100 + /* serializes EDID reading */ 101 + struct mutex edid_lock; 102 + unsigned int edid_bytes_read; 103 + struct extron_port *edid_port; 104 + struct completion edid_completion; 105 + bool edid_reading; 106 + bool is_ready; 107 + 108 + struct completion cmd_done; 109 + const char *response; 110 + unsigned int cmd_error; 111 + char data[DATA_SIZE]; 112 + unsigned int len; 113 + char reply[DATA_SIZE]; 114 + char buf[DATA_SIZE]; 115 + unsigned int idx; 116 + }; 117 + 118 + #endif
+5 -10
drivers/media/common/siano/smscoreapi.c
··· 1132 1132 * return: 0 on success, <0 on error. 1133 1133 */ 1134 1134 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, 1135 - int mode, 1136 - loadfirmware_t loadfirmware_handler) 1135 + int mode) 1137 1136 { 1138 1137 int rc = -ENOENT; 1139 1138 u8 *fw_buf; ··· 1146 1147 } 1147 1148 pr_debug("Firmware name: %s\n", fw_filename); 1148 1149 1149 - if (!loadfirmware_handler && 1150 - !(coredev->device_flags & SMS_DEVICE_FAMILY2)) 1150 + if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) 1151 1151 return -EINVAL; 1152 1152 1153 1153 rc = request_firmware(&fw, fw_filename, coredev->device); ··· 1164 1166 memcpy(fw_buf, fw->data, fw->size); 1165 1167 fw_buf_size = fw->size; 1166 1168 1167 - rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? 1168 - smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size) 1169 - : loadfirmware_handler(coredev->context, fw_buf, 1170 - fw_buf_size); 1169 + rc = smscore_load_firmware_family2(coredev, fw_buf, 1170 + fw_buf_size); 1171 1171 } 1172 1172 1173 1173 kfree(fw_buf); ··· 1349 1353 } 1350 1354 1351 1355 if (!(coredev->modes_supported & (1 << mode))) { 1352 - rc = smscore_load_firmware_from_file(coredev, 1353 - mode, NULL); 1356 + rc = smscore_load_firmware_from_file(coredev, mode); 1354 1357 if (rc >= 0) 1355 1358 pr_debug("firmware download success\n"); 1356 1359 } else {
-10
drivers/media/common/siano/smscoreapi.h
··· 97 97 typedef int (*setmode_t)(void *context, int mode); 98 98 typedef void (*detectmode_t)(void *context, int *mode); 99 99 typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); 100 - typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); 101 100 typedef int (*preload_t)(void *context); 102 101 typedef int (*postload_t)(void *context); 103 102 ··· 1101 1102 extern void smscore_unregister_device(struct smscore_device_t *coredev); 1102 1103 1103 1104 extern int smscore_start_device(struct smscore_device_t *coredev); 1104 - extern int smscore_load_firmware(struct smscore_device_t *coredev, 1105 - char *filename, 1106 - loadfirmware_t loadfirmware_handler); 1107 1105 1108 1106 extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); 1109 1107 extern int smscore_get_device_mode(struct smscore_device_t *coredev); ··· 1114 1118 void *buffer, size_t size); 1115 1119 extern void smscore_onresponse(struct smscore_device_t *coredev, 1116 1120 struct smscore_buffer_t *cb); 1117 - 1118 - extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); 1119 - extern int smscore_map_common_buffer(struct smscore_device_t *coredev, 1120 - struct vm_area_struct *vma); 1121 - extern int smscore_send_fw_file(struct smscore_device_t *coredev, 1122 - u8 *ufwbuf, int size); 1123 1121 1124 1122 extern 1125 1123 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
+103 -79
drivers/media/common/videobuf2/videobuf2-core.c
··· 303 303 if (!p->mem_priv) 304 304 return; 305 305 306 - if (p->dbuf_mapped) 307 - call_void_memop(vb, unmap_dmabuf, p->mem_priv); 306 + if (!p->dbuf_duplicated) { 307 + if (p->dbuf_mapped) 308 + call_void_memop(vb, unmap_dmabuf, p->mem_priv); 308 309 309 - call_void_memop(vb, detach_dmabuf, p->mem_priv); 310 + call_void_memop(vb, detach_dmabuf, p->mem_priv); 311 + } 312 + 310 313 dma_buf_put(p->dbuf); 311 314 p->mem_priv = NULL; 312 315 p->dbuf = NULL; 313 316 p->dbuf_mapped = 0; 317 + p->bytesused = 0; 318 + p->length = 0; 319 + p->m.fd = 0; 320 + p->data_offset = 0; 321 + p->dbuf_duplicated = false; 314 322 } 315 323 316 324 /* ··· 327 319 */ 328 320 static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb) 329 321 { 330 - unsigned int plane; 322 + int plane; 331 323 332 - for (plane = 0; plane < vb->num_planes; ++plane) 324 + /* 325 + * When multiple planes share the same DMA buffer attachment, the plane 326 + * with the lowest index owns the mem_priv. 327 + * Put planes in the reversed order so that we don't leave invalid 328 + * mem_priv behind. 329 + */ 330 + for (plane = vb->num_planes - 1; plane >= 0; --plane) 333 331 __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); 334 332 } 335 333 ··· 1383 1369 struct vb2_plane planes[VB2_MAX_PLANES]; 1384 1370 struct vb2_queue *q = vb->vb2_queue; 1385 1371 void *mem_priv; 1386 - unsigned int plane; 1372 + unsigned int plane, i; 1387 1373 int ret = 0; 1388 1374 bool reacquired = vb->planes[0].mem_priv == NULL; 1389 1375 ··· 1397 1383 for (plane = 0; plane < vb->num_planes; ++plane) { 1398 1384 struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd); 1399 1385 1386 + planes[plane].dbuf = dbuf; 1387 + 1400 1388 if (IS_ERR_OR_NULL(dbuf)) { 1401 1389 dprintk(q, 1, "invalid dmabuf fd for plane %d\n", 1402 1390 plane); 1403 1391 ret = -EINVAL; 1404 - goto err; 1392 + goto err_put_planes; 1405 1393 } 1406 1394 1407 1395 /* use DMABUF size if length is not provided */ ··· 1414 1398 dprintk(q, 1, "invalid dmabuf length %u for plane %d, minimum length %u\n", 1415 1399 planes[plane].length, plane, 1416 1400 vb->planes[plane].min_length); 1417 - dma_buf_put(dbuf); 1418 1401 ret = -EINVAL; 1419 - goto err; 1402 + goto err_put_planes; 1420 1403 } 1421 1404 1422 1405 /* Skip the plane if already verified */ 1423 1406 if (dbuf == vb->planes[plane].dbuf && 1424 - vb->planes[plane].length == planes[plane].length) { 1425 - dma_buf_put(dbuf); 1407 + vb->planes[plane].length == planes[plane].length) 1426 1408 continue; 1427 - } 1428 1409 1429 1410 dprintk(q, 3, "buffer for plane %d changed\n", plane); 1430 1411 1431 - if (!reacquired) { 1432 - reacquired = true; 1433 - vb->copied_timestamp = 0; 1434 - call_void_vb_qop(vb, buf_cleanup, vb); 1435 - } 1436 - 1437 - /* Release previously acquired memory if present */ 1438 - __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); 1439 - vb->planes[plane].bytesused = 0; 1440 - vb->planes[plane].length = 0; 1441 - vb->planes[plane].m.fd = 0; 1442 - vb->planes[plane].data_offset = 0; 1443 - 1444 - /* Acquire each plane's memory */ 1445 - mem_priv = call_ptr_memop(attach_dmabuf, 1446 - vb, 1447 - q->alloc_devs[plane] ? : q->dev, 1448 - dbuf, 1449 - planes[plane].length); 1450 - if (IS_ERR(mem_priv)) { 1451 - dprintk(q, 1, "failed to attach dmabuf\n"); 1452 - ret = PTR_ERR(mem_priv); 1453 - dma_buf_put(dbuf); 1454 - goto err; 1455 - } 1456 - 1457 - vb->planes[plane].dbuf = dbuf; 1458 - vb->planes[plane].mem_priv = mem_priv; 1459 - } 1460 - 1461 - /* 1462 - * This pins the buffer(s) with dma_buf_map_attachment()). It's done 1463 - * here instead just before the DMA, while queueing the buffer(s) so 1464 - * userspace knows sooner rather than later if the dma-buf map fails. 1465 - */ 1466 - for (plane = 0; plane < vb->num_planes; ++plane) { 1467 - if (vb->planes[plane].dbuf_mapped) 1468 - continue; 1469 - 1470 - ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv); 1471 - if (ret) { 1472 - dprintk(q, 1, "failed to map dmabuf for plane %d\n", 1473 - plane); 1474 - goto err; 1475 - } 1476 - vb->planes[plane].dbuf_mapped = 1; 1477 - } 1478 - 1479 - /* 1480 - * Now that everything is in order, copy relevant information 1481 - * provided by userspace. 1482 - */ 1483 - for (plane = 0; plane < vb->num_planes; ++plane) { 1484 - vb->planes[plane].bytesused = planes[plane].bytesused; 1485 - vb->planes[plane].length = planes[plane].length; 1486 - vb->planes[plane].m.fd = planes[plane].m.fd; 1487 - vb->planes[plane].data_offset = planes[plane].data_offset; 1412 + reacquired = true; 1488 1413 } 1489 1414 1490 1415 if (reacquired) { 1416 + if (vb->planes[0].mem_priv) { 1417 + vb->copied_timestamp = 0; 1418 + call_void_vb_qop(vb, buf_cleanup, vb); 1419 + __vb2_buf_dmabuf_put(vb); 1420 + } 1421 + 1422 + for (plane = 0; plane < vb->num_planes; ++plane) { 1423 + /* 1424 + * This is an optimization to reduce dma_buf attachment/mapping. 1425 + * When the same dma_buf is used for multiple planes, there is no need 1426 + * to create duplicated attachments. 1427 + */ 1428 + for (i = 0; i < plane; ++i) { 1429 + if (planes[plane].dbuf == vb->planes[i].dbuf && 1430 + q->alloc_devs[plane] == q->alloc_devs[i]) { 1431 + vb->planes[plane].dbuf_duplicated = true; 1432 + vb->planes[plane].dbuf = vb->planes[i].dbuf; 1433 + vb->planes[plane].mem_priv = vb->planes[i].mem_priv; 1434 + break; 1435 + } 1436 + } 1437 + 1438 + if (vb->planes[plane].dbuf_duplicated) 1439 + continue; 1440 + 1441 + /* Acquire each plane's memory */ 1442 + mem_priv = call_ptr_memop(attach_dmabuf, 1443 + vb, 1444 + q->alloc_devs[plane] ? : q->dev, 1445 + planes[plane].dbuf, 1446 + planes[plane].length); 1447 + if (IS_ERR(mem_priv)) { 1448 + dprintk(q, 1, "failed to attach dmabuf\n"); 1449 + ret = PTR_ERR(mem_priv); 1450 + goto err_put_vb2_buf; 1451 + } 1452 + 1453 + vb->planes[plane].dbuf = planes[plane].dbuf; 1454 + vb->planes[plane].mem_priv = mem_priv; 1455 + 1456 + /* 1457 + * This pins the buffer(s) with dma_buf_map_attachment()). It's done 1458 + * here instead just before the DMA, while queueing the buffer(s) so 1459 + * userspace knows sooner rather than later if the dma-buf map fails. 1460 + */ 1461 + ret = call_memop(vb, map_dmabuf, vb->planes[plane].mem_priv); 1462 + if (ret) { 1463 + dprintk(q, 1, "failed to map dmabuf for plane %d\n", 1464 + plane); 1465 + goto err_put_vb2_buf; 1466 + } 1467 + vb->planes[plane].dbuf_mapped = 1; 1468 + } 1469 + 1470 + /* 1471 + * Now that everything is in order, copy relevant information 1472 + * provided by userspace. 1473 + */ 1474 + for (plane = 0; plane < vb->num_planes; ++plane) { 1475 + vb->planes[plane].bytesused = planes[plane].bytesused; 1476 + vb->planes[plane].length = planes[plane].length; 1477 + vb->planes[plane].m.fd = planes[plane].m.fd; 1478 + vb->planes[plane].data_offset = planes[plane].data_offset; 1479 + } 1480 + 1491 1481 /* 1492 1482 * Call driver-specific initialization on the newly acquired buffer, 1493 1483 * if provided. ··· 1501 1479 ret = call_vb_qop(vb, buf_init, vb); 1502 1480 if (ret) { 1503 1481 dprintk(q, 1, "buffer initialization failed\n"); 1504 - goto err; 1482 + goto err_put_vb2_buf; 1505 1483 } 1484 + } else { 1485 + for (plane = 0; plane < vb->num_planes; ++plane) 1486 + dma_buf_put(planes[plane].dbuf); 1506 1487 } 1507 1488 1508 1489 ret = call_vb_qop(vb, buf_prepare, vb); 1509 1490 if (ret) { 1510 1491 dprintk(q, 1, "buffer preparation failed\n"); 1511 1492 call_void_vb_qop(vb, buf_cleanup, vb); 1512 - goto err; 1493 + goto err_put_vb2_buf; 1513 1494 } 1514 1495 1515 1496 return 0; 1516 - err: 1497 + 1498 + err_put_planes: 1499 + for (plane = 0; plane < vb->num_planes; ++plane) { 1500 + if (!IS_ERR_OR_NULL(planes[plane].dbuf)) 1501 + dma_buf_put(planes[plane].dbuf); 1502 + } 1503 + err_put_vb2_buf: 1517 1504 /* In case of errors, release planes that were already acquired */ 1518 1505 __vb2_buf_dmabuf_put(vb); 1519 1506 ··· 2631 2600 */ 2632 2601 if (WARN_ON(q->supports_requests && q->min_queued_buffers)) 2633 2602 return -EINVAL; 2634 - 2635 - /* 2636 - * The minimum requirement is 2: one buffer is used 2637 - * by the hardware while the other is being processed by userspace. 2638 - */ 2639 - if (q->min_reqbufs_allocation < 2) 2640 - q->min_reqbufs_allocation = 2; 2641 2603 2642 2604 /* 2643 2605 * If the driver needs 'min_queued_buffers' in the queue before
+1 -1
drivers/media/dvb-frontends/a8293.c
··· 256 256 } 257 257 258 258 static const struct i2c_device_id a8293_id_table[] = { 259 - {"a8293", 0}, 259 + { "a8293" }, 260 260 {} 261 261 }; 262 262 MODULE_DEVICE_TABLE(i2c, a8293_id_table);
+1 -1
drivers/media/dvb-frontends/af9013.c
··· 1553 1553 } 1554 1554 1555 1555 static const struct i2c_device_id af9013_id_table[] = { 1556 - {"af9013", 0}, 1556 + { "af9013" }, 1557 1557 {} 1558 1558 }; 1559 1559 MODULE_DEVICE_TABLE(i2c, af9013_id_table);
+1 -1
drivers/media/dvb-frontends/af9033.c
··· 1173 1173 } 1174 1174 1175 1175 static const struct i2c_device_id af9033_id_table[] = { 1176 - {"af9033", 0}, 1176 + { "af9033" }, 1177 1177 {} 1178 1178 }; 1179 1179 MODULE_DEVICE_TABLE(i2c, af9033_id_table);
+1 -1
drivers/media/dvb-frontends/au8522_decoder.c
··· 767 767 } 768 768 769 769 static const struct i2c_device_id au8522_id[] = { 770 - {"au8522", 0}, 770 + { "au8522" }, 771 771 {} 772 772 }; 773 773
+1 -1
drivers/media/dvb-frontends/cxd2099.c
··· 672 672 } 673 673 674 674 static const struct i2c_device_id cxd2099_id[] = { 675 - {"cxd2099", 0}, 675 + { "cxd2099" }, 676 676 {} 677 677 }; 678 678 MODULE_DEVICE_TABLE(i2c, cxd2099_id);
+1 -1
drivers/media/dvb-frontends/cxd2820r_core.c
··· 723 723 } 724 724 725 725 static const struct i2c_device_id cxd2820r_id_table[] = { 726 - {"cxd2820r", 0}, 726 + { "cxd2820r" }, 727 727 {} 728 728 }; 729 729 MODULE_DEVICE_TABLE(i2c, cxd2820r_id_table);
+1 -1
drivers/media/dvb-frontends/lgdt3306a.c
··· 2244 2244 } 2245 2245 2246 2246 static const struct i2c_device_id lgdt3306a_id_table[] = { 2247 - {"lgdt3306a", 0}, 2247 + { "lgdt3306a" }, 2248 2248 {} 2249 2249 }; 2250 2250 MODULE_DEVICE_TABLE(i2c, lgdt3306a_id_table);
+1 -1
drivers/media/dvb-frontends/lgdt330x.c
··· 983 983 } 984 984 985 985 static const struct i2c_device_id lgdt330x_id_table[] = { 986 - {"lgdt330x", 0}, 986 + { "lgdt330x" }, 987 987 {} 988 988 }; 989 989 MODULE_DEVICE_TABLE(i2c, lgdt330x_id_table);
+1 -1
drivers/media/dvb-frontends/mn88472.c
··· 708 708 } 709 709 710 710 static const struct i2c_device_id mn88472_id_table[] = { 711 - {"mn88472", 0}, 711 + { "mn88472" }, 712 712 {} 713 713 }; 714 714 MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
+1 -1
drivers/media/dvb-frontends/mn88473.c
··· 743 743 } 744 744 745 745 static const struct i2c_device_id mn88473_id_table[] = { 746 - {"mn88473", 0}, 746 + { "mn88473" }, 747 747 {} 748 748 }; 749 749 MODULE_DEVICE_TABLE(i2c, mn88473_id_table);
+1 -1
drivers/media/dvb-frontends/mxl692.c
··· 1346 1346 } 1347 1347 1348 1348 static const struct i2c_device_id mxl692_id_table[] = { 1349 - {"mxl692", 0}, 1349 + { "mxl692" }, 1350 1350 {} 1351 1351 }; 1352 1352 MODULE_DEVICE_TABLE(i2c, mxl692_id_table);
+2 -2
drivers/media/dvb-frontends/rtl2830.c
··· 609 609 index, pid, onoff); 610 610 611 611 /* skip invalid PIDs (0x2000) */ 612 - if (pid > 0x1fff || index > 32) 612 + if (pid > 0x1fff || index >= 32) 613 613 return 0; 614 614 615 615 if (onoff) ··· 876 876 } 877 877 878 878 static const struct i2c_device_id rtl2830_id_table[] = { 879 - {"rtl2830", 0}, 879 + { "rtl2830" }, 880 880 {} 881 881 }; 882 882 MODULE_DEVICE_TABLE(i2c, rtl2830_id_table);
+2 -2
drivers/media/dvb-frontends/rtl2832.c
··· 983 983 index, pid, onoff, dev->slave_ts); 984 984 985 985 /* skip invalid PIDs (0x2000) */ 986 - if (pid > 0x1fff || index > 32) 986 + if (pid > 0x1fff || index >= 32) 987 987 return 0; 988 988 989 989 if (onoff) ··· 1125 1125 } 1126 1126 1127 1127 static const struct i2c_device_id rtl2832_id_table[] = { 1128 - {"rtl2832", 0}, 1128 + { "rtl2832" }, 1129 1129 {} 1130 1130 }; 1131 1131 MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
+1 -1
drivers/media/dvb-frontends/si2165.c
··· 1281 1281 } 1282 1282 1283 1283 static const struct i2c_device_id si2165_id_table[] = { 1284 - {"si2165", 0}, 1284 + { "si2165" }, 1285 1285 {} 1286 1286 }; 1287 1287 MODULE_DEVICE_TABLE(i2c, si2165_id_table);
+1 -1
drivers/media/dvb-frontends/si2168.c
··· 788 788 } 789 789 790 790 static const struct i2c_device_id si2168_id_table[] = { 791 - {"si2168", 0}, 791 + { "si2168" }, 792 792 {} 793 793 }; 794 794 MODULE_DEVICE_TABLE(i2c, si2168_id_table);
+1 -1
drivers/media/dvb-frontends/sp2.c
··· 407 407 } 408 408 409 409 static const struct i2c_device_id sp2_id[] = { 410 - {"sp2", 0}, 410 + { "sp2" }, 411 411 {} 412 412 }; 413 413 MODULE_DEVICE_TABLE(i2c, sp2_id);
+1 -1
drivers/media/dvb-frontends/stv090x.c
··· 5079 5079 EXPORT_SYMBOL_GPL(stv090x_attach); 5080 5080 5081 5081 static const struct i2c_device_id stv090x_id_table[] = { 5082 - {"stv090x", 0}, 5082 + { "stv090x" }, 5083 5083 {} 5084 5084 }; 5085 5085 MODULE_DEVICE_TABLE(i2c, stv090x_id_table);
+1 -1
drivers/media/dvb-frontends/stv6110x.c
··· 470 470 EXPORT_SYMBOL_GPL(stv6110x_attach); 471 471 472 472 static const struct i2c_device_id stv6110x_id_table[] = { 473 - {"stv6110x", 0}, 473 + { "stv6110x" }, 474 474 {} 475 475 }; 476 476 MODULE_DEVICE_TABLE(i2c, stv6110x_id_table);
+1 -1
drivers/media/dvb-frontends/tda10071.c
··· 1230 1230 } 1231 1231 1232 1232 static const struct i2c_device_id tda10071_id_table[] = { 1233 - {"tda10071_cx24118", 0}, 1233 + { "tda10071_cx24118" }, 1234 1234 {} 1235 1235 }; 1236 1236 MODULE_DEVICE_TABLE(i2c, tda10071_id_table);
+2 -2
drivers/media/dvb-frontends/ts2020.c
··· 710 710 } 711 711 712 712 static const struct i2c_device_id ts2020_id_table[] = { 713 - {"ts2020", 0}, 714 - {"ts2022", 0}, 713 + { "ts2020" }, 714 + { "ts2022" }, 715 715 {} 716 716 }; 717 717 MODULE_DEVICE_TABLE(i2c, ts2020_id_table);
+2 -2
drivers/media/i2c/ad5820.c
··· 347 347 } 348 348 349 349 static const struct i2c_device_id ad5820_id_table[] = { 350 - { "ad5820", 0 }, 351 - { "ad5821", 0 }, 350 + { "ad5820" }, 351 + { "ad5821" }, 352 352 { } 353 353 }; 354 354 MODULE_DEVICE_TABLE(i2c, ad5820_id_table);
+1 -1
drivers/media/i2c/adp1653.c
··· 522 522 } 523 523 524 524 static const struct i2c_device_id adp1653_id_table[] = { 525 - { ADP1653_NAME, 0 }, 525 + { ADP1653_NAME }, 526 526 { } 527 527 }; 528 528 MODULE_DEVICE_TABLE(i2c, adp1653_id_table);
+2 -2
drivers/media/i2c/adv7170.c
··· 377 377 /* ----------------------------------------------------------------------- */ 378 378 379 379 static const struct i2c_device_id adv7170_id[] = { 380 - { "adv7170", 0 }, 381 - { "adv7171", 0 }, 380 + { "adv7170" }, 381 + { "adv7171" }, 382 382 { } 383 383 }; 384 384 MODULE_DEVICE_TABLE(i2c, adv7170_id);
+2 -2
drivers/media/i2c/adv7175.c
··· 432 432 /* ----------------------------------------------------------------------- */ 433 433 434 434 static const struct i2c_device_id adv7175_id[] = { 435 - { "adv7175", 0 }, 436 - { "adv7176", 0 }, 435 + { "adv7175" }, 436 + { "adv7176" }, 437 437 { } 438 438 }; 439 439 MODULE_DEVICE_TABLE(i2c, adv7175_id);
+2 -2
drivers/media/i2c/adv7183.c
··· 619 619 } 620 620 621 621 static const struct i2c_device_id adv7183_id[] = { 622 - {"adv7183", 0}, 623 - {}, 622 + { "adv7183" }, 623 + {} 624 624 }; 625 625 626 626 MODULE_DEVICE_TABLE(i2c, adv7183_id);
+2 -2
drivers/media/i2c/adv7343.c
··· 502 502 } 503 503 504 504 static const struct i2c_device_id adv7343_id[] = { 505 - {"adv7343", 0}, 506 - {}, 505 + { "adv7343" }, 506 + {} 507 507 }; 508 508 509 509 MODULE_DEVICE_TABLE(i2c, adv7343_id);
+2 -2
drivers/media/i2c/adv7393.c
··· 446 446 } 447 447 448 448 static const struct i2c_device_id adv7393_id[] = { 449 - {"adv7393", 0}, 450 - {}, 449 + { "adv7393" }, 450 + {} 451 451 }; 452 452 MODULE_DEVICE_TABLE(i2c, adv7393_id); 453 453
+1 -1
drivers/media/i2c/adv7511-v4l2.c
··· 1949 1949 /* ----------------------------------------------------------------------- */ 1950 1950 1951 1951 static const struct i2c_device_id adv7511_id[] = { 1952 - { "adv7511-v4l2", 0 }, 1952 + { "adv7511-v4l2" }, 1953 1953 { } 1954 1954 }; 1955 1955 MODULE_DEVICE_TABLE(i2c, adv7511_id);
+1 -1
drivers/media/i2c/adv7842.c
··· 3617 3617 /* ----------------------------------------------------------------------- */ 3618 3618 3619 3619 static const struct i2c_device_id adv7842_id[] = { 3620 - { "adv7842", 0 }, 3620 + { "adv7842" }, 3621 3621 { } 3622 3622 }; 3623 3623 MODULE_DEVICE_TABLE(i2c, adv7842_id);
+2 -2
drivers/media/i2c/ak881x.c
··· 304 304 } 305 305 306 306 static const struct i2c_device_id ak881x_id[] = { 307 - { "ak8813", 0 }, 308 - { "ak8814", 0 }, 307 + { "ak8813" }, 308 + { "ak8814" }, 309 309 { } 310 310 }; 311 311 MODULE_DEVICE_TABLE(i2c, ak881x_id);
+16 -6
drivers/media/i2c/ar0521.c
··· 835 835 be(0x0707)), /* 3F44: couple k factor 2 */ 836 836 }; 837 837 838 - static int ar0521_power_off(struct device *dev) 838 + static void __ar0521_power_off(struct device *dev) 839 839 { 840 840 struct v4l2_subdev *sd = dev_get_drvdata(dev); 841 841 struct ar0521_dev *sensor = to_ar0521_dev(sd); 842 842 int i; 843 843 844 - clk_disable_unprepare(sensor->extclk); 845 - 846 844 if (sensor->reset_gpio) 847 - gpiod_set_value(sensor->reset_gpio, 1); /* assert RESET signal */ 845 + /* assert RESET signal */ 846 + gpiod_set_value_cansleep(sensor->reset_gpio, 1); 848 847 849 848 for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) { 850 849 if (sensor->supplies[i]) 851 850 regulator_disable(sensor->supplies[i]); 852 851 } 852 + } 853 + 854 + static int ar0521_power_off(struct device *dev) 855 + { 856 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 857 + struct ar0521_dev *sensor = to_ar0521_dev(sd); 858 + 859 + clk_disable_unprepare(sensor->extclk); 860 + __ar0521_power_off(dev); 861 + 853 862 return 0; 854 863 } 855 864 ··· 887 878 888 879 if (sensor->reset_gpio) 889 880 /* deassert RESET signal */ 890 - gpiod_set_value(sensor->reset_gpio, 0); 881 + gpiod_set_value_cansleep(sensor->reset_gpio, 0); 891 882 usleep_range(4500, 5000); /* min 45000 clocks */ 892 883 893 884 for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) { ··· 917 908 918 909 return 0; 919 910 off: 920 - ar0521_power_off(dev); 911 + clk_disable_unprepare(sensor->extclk); 912 + __ar0521_power_off(dev); 921 913 return ret; 922 914 } 923 915
+3 -3
drivers/media/i2c/bt819.c
··· 457 457 /* ----------------------------------------------------------------------- */ 458 458 459 459 static const struct i2c_device_id bt819_id[] = { 460 - { "bt819a", 0 }, 461 - { "bt817a", 0 }, 462 - { "bt815a", 0 }, 460 + { "bt819a" }, 461 + { "bt817a" }, 462 + { "bt815a" }, 463 463 { } 464 464 }; 465 465 MODULE_DEVICE_TABLE(i2c, bt819_id);
+1 -1
drivers/media/i2c/bt856.c
··· 230 230 } 231 231 232 232 static const struct i2c_device_id bt856_id[] = { 233 - { "bt856", 0 }, 233 + { "bt856" }, 234 234 { } 235 235 }; 236 236 MODULE_DEVICE_TABLE(i2c, bt856_id);
+1 -1
drivers/media/i2c/bt866.c
··· 197 197 } 198 198 199 199 static const struct i2c_device_id bt866_id[] = { 200 - { "bt866", 0 }, 200 + { "bt866" }, 201 201 { } 202 202 }; 203 203 MODULE_DEVICE_TABLE(i2c, bt866_id);
-3
drivers/media/i2c/ccs/ccs-reg-access.h
··· 21 21 22 22 struct ccs_sensor; 23 23 24 - int ccs_read_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 *val); 25 24 int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val); 26 25 int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val); 27 26 int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val); 28 - int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val); 29 27 int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val); 30 28 int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs, 31 29 size_t num_regs); 32 30 33 - unsigned int ccs_reg_width(u32 reg); 34 31 u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val); 35 32 36 33 #define ccs_read(sensor, reg_name, val) \
+1 -1
drivers/media/i2c/cs3308.c
··· 109 109 /* ----------------------------------------------------------------------- */ 110 110 111 111 static const struct i2c_device_id cs3308_id[] = { 112 - { "cs3308", 0 }, 112 + { "cs3308" }, 113 113 { } 114 114 }; 115 115 MODULE_DEVICE_TABLE(i2c, cs3308_id);
+1 -1
drivers/media/i2c/cs5345.c
··· 189 189 /* ----------------------------------------------------------------------- */ 190 190 191 191 static const struct i2c_device_id cs5345_id[] = { 192 - { "cs5345", 0 }, 192 + { "cs5345" }, 193 193 { } 194 194 }; 195 195 MODULE_DEVICE_TABLE(i2c, cs5345_id);
+1 -1
drivers/media/i2c/cs53l32a.c
··· 200 200 } 201 201 202 202 static const struct i2c_device_id cs53l32a_id[] = { 203 - { "cs53l32a", 0 }, 203 + { "cs53l32a" }, 204 204 { } 205 205 }; 206 206 MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
+1 -1
drivers/media/i2c/cx25840/cx25840-core.c
··· 3964 3964 } 3965 3965 3966 3966 static const struct i2c_device_id cx25840_id[] = { 3967 - { "cx25840", 0 }, 3967 + { "cx25840" }, 3968 3968 { } 3969 3969 }; 3970 3970 MODULE_DEVICE_TABLE(i2c, cx25840_id);
+4 -1
drivers/media/i2c/ds90ub913.c
··· 877 877 ub913_gpiochip_remove(priv); 878 878 } 879 879 880 - static const struct i2c_device_id ub913_id[] = { { "ds90ub913a-q1", 0 }, {} }; 880 + static const struct i2c_device_id ub913_id[] = { 881 + { "ds90ub913a-q1" }, 882 + {} 883 + }; 881 884 MODULE_DEVICE_TABLE(i2c, ub913_id); 882 885 883 886 static const struct of_device_id ub913_dt_ids[] = {
+2 -2
drivers/media/i2c/dw9714.c
··· 279 279 } 280 280 281 281 static const struct i2c_device_id dw9714_id_table[] = { 282 - { DW9714_NAME, 0 }, 283 - { { 0 } } 282 + { DW9714_NAME }, 283 + { } 284 284 }; 285 285 MODULE_DEVICE_TABLE(i2c, dw9714_id_table); 286 286
+1 -1
drivers/media/i2c/et8ek8/et8ek8_driver.c
··· 1501 1501 MODULE_DEVICE_TABLE(of, et8ek8_of_table); 1502 1502 1503 1503 static const struct i2c_device_id et8ek8_id_table[] = { 1504 - { ET8EK8_NAME, 0 }, 1504 + { ET8EK8_NAME }, 1505 1505 { } 1506 1506 }; 1507 1507 MODULE_DEVICE_TABLE(i2c, et8ek8_id_table);
+1 -1
drivers/media/i2c/gc05a2.c
··· 65 65 66 66 static const char *const gc05a2_test_pattern_menu[] = { 67 67 "No Pattern", "Fade_to_gray_Color Bar", "Color Bar", 68 - "PN9", "Horizental_gradient", "Checkboard Pattern", 68 + "PN9", "Horizontal_gradient", "Checkboard Pattern", 69 69 "Slant", "Resolution", "Solid Black", 70 70 "Solid White", 71 71 };
+1 -1
drivers/media/i2c/gc08a3.c
··· 948 948 949 949 ret = cci_write(gc08a3->regmap, GC08A3_STREAMING_REG, 1, NULL); 950 950 if (ret < 0) { 951 - dev_err(gc08a3->dev, "write STRAEMING_REG failed: %d\n", ret); 951 + dev_err(gc08a3->dev, "write STREAMING_REG failed: %d\n", ret); 952 952 goto err_rpm_put; 953 953 } 954 954
+1 -1
drivers/media/i2c/imx274.c
··· 1949 1949 MODULE_DEVICE_TABLE(of, imx274_of_id_table); 1950 1950 1951 1951 static const struct i2c_device_id imx274_id[] = { 1952 - { "IMX274", 0 }, 1952 + { "IMX274" }, 1953 1953 { } 1954 1954 }; 1955 1955 MODULE_DEVICE_TABLE(i2c, imx274_id);
+33
drivers/media/i2c/imx283.c
··· 472 472 .height = 3648, 473 473 }, 474 474 }, 475 + { 476 + /* 477 + * Readout mode 3 : 3/3 binned mode (1824x1216) 478 + */ 479 + .mode = IMX283_MODE_3, 480 + .bpp = 12, 481 + .width = 1824, 482 + .height = 1216, 483 + .min_hmax = 1894, /* Pixels (284 * 480MHz/72MHz + padding) */ 484 + .min_vmax = 4200, /* Lines */ 485 + 486 + /* 60.00 fps */ 487 + .default_hmax = 1900, /* 285 @ 480MHz/72Mhz */ 488 + .default_vmax = 4200, 489 + 490 + .veff = 1234, 491 + .vst = 0, 492 + .vct = 0, 493 + 494 + .hbin_ratio = 3, 495 + .vbin_ratio = 3, 496 + 497 + .min_shr = 16, 498 + .horizontal_ob = 32, 499 + .vertical_ob = 4, 500 + 501 + .crop = { 502 + .top = 40, 503 + .left = 108, 504 + .width = 5472, 505 + .height = 3648, 506 + }, 507 + }, 475 508 }; 476 509 477 510 static const struct imx283_mode supported_modes_10bit[] = {
+4 -5
drivers/media/i2c/imx335.c
··· 997 997 998 998 /* Request optional reset pin */ 999 999 imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset", 1000 - GPIOD_OUT_LOW); 1000 + GPIOD_OUT_HIGH); 1001 1001 if (IS_ERR(imx335->reset_gpio)) { 1002 1002 dev_err(imx335->dev, "failed to get reset gpio %ld\n", 1003 1003 PTR_ERR(imx335->reset_gpio)); ··· 1110 1110 1111 1111 usleep_range(500, 550); /* Tlow */ 1112 1112 1113 - /* Set XCLR */ 1114 - gpiod_set_value_cansleep(imx335->reset_gpio, 1); 1113 + gpiod_set_value_cansleep(imx335->reset_gpio, 0); 1115 1114 1116 1115 ret = clk_prepare_enable(imx335->inclk); 1117 1116 if (ret) { ··· 1123 1124 return 0; 1124 1125 1125 1126 error_reset: 1126 - gpiod_set_value_cansleep(imx335->reset_gpio, 0); 1127 + gpiod_set_value_cansleep(imx335->reset_gpio, 1); 1127 1128 regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); 1128 1129 1129 1130 return ret; ··· 1140 1141 struct v4l2_subdev *sd = dev_get_drvdata(dev); 1141 1142 struct imx335 *imx335 = to_imx335(sd); 1142 1143 1143 - gpiod_set_value_cansleep(imx335->reset_gpio, 0); 1144 + gpiod_set_value_cansleep(imx335->reset_gpio, 1); 1144 1145 clk_disable_unprepare(imx335->inclk); 1145 1146 regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); 1146 1147
+11 -1
drivers/media/i2c/imx355.c
··· 1520 1520 static int imx355_init_controls(struct imx355 *imx355) 1521 1521 { 1522 1522 struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd); 1523 + struct v4l2_fwnode_device_properties props; 1523 1524 struct v4l2_ctrl_handler *ctrl_hdlr; 1524 1525 s64 exposure_max; 1525 1526 s64 vblank_def; ··· 1532 1531 int ret; 1533 1532 1534 1533 ctrl_hdlr = &imx355->ctrl_handler; 1535 - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10); 1534 + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); 1536 1535 if (ret) 1537 1536 return ret; 1538 1537 ··· 1603 1602 dev_err(&client->dev, "control init failed: %d", ret); 1604 1603 goto error; 1605 1604 } 1605 + 1606 + ret = v4l2_fwnode_device_parse(&client->dev, &props); 1607 + if (ret) 1608 + goto error; 1609 + 1610 + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx355_ctrl_ops, 1611 + &props); 1612 + if (ret) 1613 + goto error; 1606 1614 1607 1615 imx355->sd.ctrl_handler = ctrl_hdlr; 1608 1616
+2 -2
drivers/media/i2c/isl7998x.c
··· 1561 1561 MODULE_DEVICE_TABLE(of, isl7998x_of_match); 1562 1562 1563 1563 static const struct i2c_device_id isl7998x_id[] = { 1564 - { "isl79987", 0 }, 1565 - { /* sentinel */ }, 1564 + { "isl79987" }, 1565 + { /* sentinel */ } 1566 1566 }; 1567 1567 MODULE_DEVICE_TABLE(i2c, isl7998x_id); 1568 1568
+3 -3
drivers/media/i2c/ks0127.c
··· 677 677 } 678 678 679 679 static const struct i2c_device_id ks0127_id[] = { 680 - { "ks0127", 0 }, 681 - { "ks0127b", 0 }, 682 - { "ks0122s", 0 }, 680 + { "ks0127" }, 681 + { "ks0127b" }, 682 + { "ks0122s" }, 683 683 { } 684 684 }; 685 685 MODULE_DEVICE_TABLE(i2c, ks0127_id);
+2 -2
drivers/media/i2c/lm3560.c
··· 455 455 } 456 456 457 457 static const struct i2c_device_id lm3560_id_table[] = { 458 - {LM3559_NAME, 0}, 459 - {LM3560_NAME, 0}, 458 + { LM3559_NAME }, 459 + { LM3560_NAME }, 460 460 {} 461 461 }; 462 462
+1 -1
drivers/media/i2c/lm3646.c
··· 386 386 } 387 387 388 388 static const struct i2c_device_id lm3646_id_table[] = { 389 - {LM3646_NAME, 0}, 389 + { LM3646_NAME }, 390 390 {} 391 391 }; 392 392
+1 -1
drivers/media/i2c/m52790.c
··· 163 163 /* ----------------------------------------------------------------------- */ 164 164 165 165 static const struct i2c_device_id m52790_id[] = { 166 - { "m52790", 0 }, 166 + { "m52790" }, 167 167 { } 168 168 }; 169 169 MODULE_DEVICE_TABLE(i2c, m52790_id);
+2 -2
drivers/media/i2c/max2175.c
··· 1413 1413 } 1414 1414 1415 1415 static const struct i2c_device_id max2175_id[] = { 1416 - { DRIVER_NAME, 0}, 1417 - {}, 1416 + { DRIVER_NAME }, 1417 + {} 1418 1418 }; 1419 1419 MODULE_DEVICE_TABLE(i2c, max2175_id); 1420 1420
+9 -9
drivers/media/i2c/max96714.c
··· 25 25 #define MAX96714_NPORTS 2 26 26 #define MAX96714_PAD_SINK 0 27 27 #define MAX96714_PAD_SOURCE 1 28 + #define MAX96714_CSI_NLANES 4 28 29 29 30 /* DEV */ 30 31 #define MAX96714_REG13 CCI_REG8(0x0d) ··· 53 52 #define MAX96714_PATGEN_V2D CCI_REG24(0x254) 54 53 #define MAX96714_PATGEN_DE_HIGH CCI_REG16(0x257) 55 54 #define MAX96714_PATGEN_DE_LOW CCI_REG16(0x259) 56 - #define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25B) 55 + #define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25b) 57 56 #define MAX96714_PATGEN_GRAD_INC CCI_REG8(0x25d) 58 - #define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25E) 57 + #define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25e) 59 58 #define MAX96714_PATGEN_CHKB_COLOR_B CCI_REG24(0x261) 60 59 #define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264) 61 60 #define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265) ··· 725 724 * Unused lanes need to be mapped as well to not have 726 725 * the same lanes mapped twice. 727 726 */ 728 - for (; lane < 4; lane++) { 729 - unsigned int idx = find_first_zero_bit(&lanes_used, 4); 727 + for (; lane < MAX96714_CSI_NLANES; lane++) { 728 + unsigned int idx = find_first_zero_bit(&lanes_used, 729 + MAX96714_CSI_NLANES); 730 730 731 731 val |= idx << (lane * 2); 732 732 lanes_used |= BIT(idx); ··· 759 757 static int max96714_parse_dt_txport(struct max96714_priv *priv) 760 758 { 761 759 struct device *dev = &priv->client->dev; 762 - struct v4l2_fwnode_endpoint vep = { 763 - .bus_type = V4L2_MBUS_CSI2_DPHY 764 - }; 760 + struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; 765 761 struct fwnode_handle *ep_fwnode; 766 762 u32 num_data_lanes; 767 763 int ret; ··· 791 791 } 792 792 793 793 num_data_lanes = vep.bus.mipi_csi2.num_data_lanes; 794 - if (num_data_lanes < 1 || num_data_lanes > 4) { 794 + if (num_data_lanes < 1 || num_data_lanes > MAX96714_CSI_NLANES) { 795 795 dev_err(dev, 796 796 "tx: invalid number of data lanes must be 1 to 4\n"); 797 797 ret = -EINVAL; 798 798 goto err_free_vep; 799 799 } 800 800 801 - memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2)); 801 + priv->mipi_csi2 = vep.bus.mipi_csi2; 802 802 803 803 err_free_vep: 804 804 v4l2_fwnode_endpoint_free(&vep);
+205 -31
drivers/media/i2c/max96717.c
··· 16 16 #include <linux/regmap.h> 17 17 18 18 #include <media/v4l2-cci.h> 19 + #include <media/v4l2-ctrls.h> 19 20 #include <media/v4l2-fwnode.h> 20 21 #include <media/v4l2-subdev.h> 21 22 ··· 25 24 #define MAX96717_PORTS 2 26 25 #define MAX96717_PAD_SINK 0 27 26 #define MAX96717_PAD_SOURCE 1 27 + #define MAX96717_CSI_NLANES 4 28 28 29 29 #define MAX96717_DEFAULT_CLKOUT_RATE 24000000UL 30 30 ··· 40 38 #define MAX96717_DEV_REV_MASK GENMASK(3, 0) 41 39 42 40 /* VID_TX Z */ 41 + #define MAX96717_VIDEO_TX0 CCI_REG8(0x110) 42 + #define MAX96717_VIDEO_AUTO_BPP BIT(3) 43 43 #define MAX96717_VIDEO_TX2 CCI_REG8(0x112) 44 44 #define MAX96717_VIDEO_PCLKDET BIT(7) 45 + 46 + /* VTX_Z */ 47 + #define MAX96717_VTX0 CCI_REG8(0x24e) 48 + #define MAX96717_VTX1 CCI_REG8(0x24f) 49 + #define MAX96717_PATTERN_CLK_FREQ GENMASK(3, 1) 50 + #define MAX96717_VTX_VS_DLY CCI_REG24(0x250) 51 + #define MAX96717_VTX_VS_HIGH CCI_REG24(0x253) 52 + #define MAX96717_VTX_VS_LOW CCI_REG24(0x256) 53 + #define MAX96717_VTX_V2H CCI_REG24(0x259) 54 + #define MAX96717_VTX_HS_HIGH CCI_REG16(0x25c) 55 + #define MAX96717_VTX_HS_LOW CCI_REG16(0x25e) 56 + #define MAX96717_VTX_HS_CNT CCI_REG16(0x260) 57 + #define MAX96717_VTX_V2D CCI_REG24(0x262) 58 + #define MAX96717_VTX_DE_HIGH CCI_REG16(0x265) 59 + #define MAX96717_VTX_DE_LOW CCI_REG16(0x267) 60 + #define MAX96717_VTX_DE_CNT CCI_REG16(0x269) 61 + #define MAX96717_VTX29 CCI_REG8(0x26b) 62 + #define MAX96717_VTX_MODE GENMASK(1, 0) 63 + #define MAX96717_VTX_GRAD_INC CCI_REG8(0x26c) 64 + #define MAX96717_VTX_CHKB_COLOR_A CCI_REG24(0x26d) 65 + #define MAX96717_VTX_CHKB_COLOR_B CCI_REG24(0x270) 66 + #define MAX96717_VTX_CHKB_RPT_CNT_A CCI_REG8(0x273) 67 + #define MAX96717_VTX_CHKB_RPT_CNT_B CCI_REG8(0x274) 68 + #define MAX96717_VTX_CHKB_ALT CCI_REG8(0x275) 45 69 46 70 /* GPIO */ 47 71 #define MAX96717_NUM_GPIO 11 ··· 110 82 /* MISC */ 111 83 #define PIO_SLEW_1 CCI_REG8(0x570) 112 84 85 + enum max96717_vpg_mode { 86 + MAX96717_VPG_DISABLED = 0, 87 + MAX96717_VPG_CHECKERBOARD = 1, 88 + MAX96717_VPG_GRADIENT = 2, 89 + }; 90 + 113 91 struct max96717_priv { 114 92 struct i2c_client *client; 115 93 struct regmap *regmap; ··· 123 89 struct v4l2_mbus_config_mipi_csi2 mipi_csi2; 124 90 struct v4l2_subdev sd; 125 91 struct media_pad pads[MAX96717_PORTS]; 92 + struct v4l2_ctrl_handler ctrl_handler; 126 93 struct v4l2_async_notifier notifier; 127 94 struct v4l2_subdev *source_sd; 128 95 u16 source_sd_pad; ··· 131 96 u8 pll_predef_index; 132 97 struct clk_hw clk_hw; 133 98 struct gpio_chip gpio_chip; 99 + enum max96717_vpg_mode pattern; 134 100 }; 135 101 136 102 static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd) ··· 166 130 MAX96717_START_PORT_B, 167 131 start ? MAX96717_START_PORT_B : 0, NULL); 168 132 } 133 + 134 + static int max96717_apply_patgen_timing(struct max96717_priv *priv, 135 + struct v4l2_subdev_state *state) 136 + { 137 + struct v4l2_mbus_framefmt *fmt = 138 + v4l2_subdev_state_get_format(state, MAX96717_PAD_SOURCE); 139 + const u32 h_active = fmt->width; 140 + const u32 h_fp = 88; 141 + const u32 h_sw = 44; 142 + const u32 h_bp = 148; 143 + u32 h_tot; 144 + const u32 v_active = fmt->height; 145 + const u32 v_fp = 4; 146 + const u32 v_sw = 5; 147 + const u32 v_bp = 36; 148 + u32 v_tot; 149 + int ret = 0; 150 + 151 + h_tot = h_active + h_fp + h_sw + h_bp; 152 + v_tot = v_active + v_fp + v_sw + v_bp; 153 + 154 + /* 75 Mhz pixel clock */ 155 + cci_update_bits(priv->regmap, MAX96717_VTX1, 156 + MAX96717_PATTERN_CLK_FREQ, 0xa, &ret); 157 + 158 + dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height, 159 + fmt->width); 160 + 161 + cci_write(priv->regmap, MAX96717_VTX_VS_DLY, 0, &ret); 162 + cci_write(priv->regmap, MAX96717_VTX_VS_HIGH, v_sw * h_tot, &ret); 163 + cci_write(priv->regmap, MAX96717_VTX_VS_LOW, 164 + (v_active + v_fp + v_bp) * h_tot, &ret); 165 + cci_write(priv->regmap, MAX96717_VTX_HS_HIGH, h_sw, &ret); 166 + cci_write(priv->regmap, MAX96717_VTX_HS_LOW, h_active + h_fp + h_bp, 167 + &ret); 168 + cci_write(priv->regmap, MAX96717_VTX_V2D, 169 + h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret); 170 + cci_write(priv->regmap, MAX96717_VTX_HS_CNT, v_tot, &ret); 171 + cci_write(priv->regmap, MAX96717_VTX_DE_HIGH, h_active, &ret); 172 + cci_write(priv->regmap, MAX96717_VTX_DE_LOW, h_fp + h_sw + h_bp, 173 + &ret); 174 + cci_write(priv->regmap, MAX96717_VTX_DE_CNT, v_active, &ret); 175 + /* B G R */ 176 + cci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_A, 0xfecc00, &ret); 177 + /* B G R */ 178 + cci_write(priv->regmap, MAX96717_VTX_CHKB_COLOR_B, 0x006aa7, &ret); 179 + cci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_A, 0x3c, &ret); 180 + cci_write(priv->regmap, MAX96717_VTX_CHKB_RPT_CNT_B, 0x3c, &ret); 181 + cci_write(priv->regmap, MAX96717_VTX_CHKB_ALT, 0x3c, &ret); 182 + cci_write(priv->regmap, MAX96717_VTX_GRAD_INC, 0x10, &ret); 183 + 184 + return ret; 185 + } 186 + 187 + static int max96717_apply_patgen(struct max96717_priv *priv, 188 + struct v4l2_subdev_state *state) 189 + { 190 + unsigned int val; 191 + int ret = 0; 192 + 193 + if (priv->pattern) 194 + ret = max96717_apply_patgen_timing(priv, state); 195 + 196 + cci_write(priv->regmap, MAX96717_VTX0, priv->pattern ? 0xfb : 0, 197 + &ret); 198 + 199 + val = FIELD_PREP(MAX96717_VTX_MODE, priv->pattern); 200 + cci_update_bits(priv->regmap, MAX96717_VTX29, MAX96717_VTX_MODE, 201 + val, &ret); 202 + return ret; 203 + } 204 + 205 + static int max96717_s_ctrl(struct v4l2_ctrl *ctrl) 206 + { 207 + struct max96717_priv *priv = 208 + container_of(ctrl->handler, struct max96717_priv, ctrl_handler); 209 + int ret; 210 + 211 + switch (ctrl->id) { 212 + case V4L2_CID_TEST_PATTERN: 213 + if (priv->enabled_source_streams) 214 + return -EBUSY; 215 + priv->pattern = ctrl->val; 216 + break; 217 + default: 218 + return -EINVAL; 219 + } 220 + 221 + /* Use bpp from bpp register */ 222 + ret = cci_update_bits(priv->regmap, MAX96717_VIDEO_TX0, 223 + MAX96717_VIDEO_AUTO_BPP, 224 + priv->pattern ? 0 : MAX96717_VIDEO_AUTO_BPP, 225 + NULL); 226 + 227 + /* 228 + * Pattern generator doesn't work with tunnel mode. 229 + * Needs RGB color format and deserializer tunnel mode must be disabled. 230 + */ 231 + return cci_update_bits(priv->regmap, MAX96717_MIPI_RX_EXT11, 232 + MAX96717_TUN_MODE, 233 + priv->pattern ? 0 : MAX96717_TUN_MODE, &ret); 234 + } 235 + 236 + static const char * const max96717_test_pattern[] = { 237 + "Disabled", 238 + "Checkerboard", 239 + "Gradient" 240 + }; 241 + 242 + static const struct v4l2_ctrl_ops max96717_ctrl_ops = { 243 + .s_ctrl = max96717_s_ctrl, 244 + }; 169 245 170 246 static int max96717_gpiochip_get(struct gpio_chip *gpiochip, 171 247 unsigned int offset) ··· 496 348 u64 streams_mask) 497 349 { 498 350 struct max96717_priv *priv = sd_to_max96717(sd); 499 - struct device *dev = &priv->client->dev; 500 351 u64 sink_streams; 501 352 int ret; 502 - 503 - sink_streams = v4l2_subdev_state_xlate_streams(state, 504 - MAX96717_PAD_SOURCE, 505 - MAX96717_PAD_SINK, 506 - &streams_mask); 507 353 508 354 if (!priv->enabled_source_streams) 509 355 max96717_start_csi(priv, true); 510 356 511 - ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad, 512 - sink_streams); 513 - if (ret) { 514 - dev_err(dev, "Fail to start streams:%llu on remote subdev\n", 515 - sink_streams); 357 + ret = max96717_apply_patgen(priv, state); 358 + if (ret) 516 359 goto stop_csi; 360 + 361 + if (!priv->pattern) { 362 + sink_streams = 363 + v4l2_subdev_state_xlate_streams(state, 364 + MAX96717_PAD_SOURCE, 365 + MAX96717_PAD_SINK, 366 + &streams_mask); 367 + 368 + ret = v4l2_subdev_enable_streams(priv->source_sd, 369 + priv->source_sd_pad, 370 + sink_streams); 371 + if (ret) 372 + goto stop_csi; 517 373 } 518 374 519 375 priv->enabled_source_streams |= streams_mask; ··· 527 375 stop_csi: 528 376 if (!priv->enabled_source_streams) 529 377 max96717_start_csi(priv, false); 378 + 530 379 return ret; 531 380 } 532 381 ··· 547 394 if (!priv->enabled_source_streams) 548 395 max96717_start_csi(priv, false); 549 396 550 - sink_streams = v4l2_subdev_state_xlate_streams(state, 551 - MAX96717_PAD_SOURCE, 552 - MAX96717_PAD_SINK, 553 - &streams_mask); 397 + if (!priv->pattern) { 398 + int ret; 554 399 555 - return v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad, 556 - sink_streams); 400 + sink_streams = 401 + v4l2_subdev_state_xlate_streams(state, 402 + MAX96717_PAD_SOURCE, 403 + MAX96717_PAD_SINK, 404 + &streams_mask); 405 + 406 + ret = v4l2_subdev_disable_streams(priv->source_sd, 407 + priv->source_sd_pad, 408 + sink_streams); 409 + if (ret) 410 + return ret; 411 + } 412 + 413 + return 0; 557 414 } 558 415 559 416 static const struct v4l2_subdev_pad_ops max96717_pad_ops = { ··· 676 513 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96717_subdev_ops); 677 514 priv->sd.internal_ops = &max96717_internal_ops; 678 515 516 + v4l2_ctrl_handler_init(&priv->ctrl_handler, 1); 517 + priv->sd.ctrl_handler = &priv->ctrl_handler; 518 + 519 + v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, 520 + &max96717_ctrl_ops, 521 + V4L2_CID_TEST_PATTERN, 522 + ARRAY_SIZE(max96717_test_pattern) - 1, 523 + 0, 0, max96717_test_pattern); 524 + if (priv->ctrl_handler.error) { 525 + ret = priv->ctrl_handler.error; 526 + goto err_free_ctrl; 527 + } 528 + 679 529 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; 680 530 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 681 531 priv->sd.entity.ops = &max96717_entity_ops; ··· 728 552 v4l2_subdev_cleanup(&priv->sd); 729 553 err_entity_cleanup: 730 554 media_entity_cleanup(&priv->sd.entity); 555 + err_free_ctrl: 556 + v4l2_ctrl_handler_free(&priv->ctrl_handler); 731 557 732 558 return ret; 733 559 } ··· 741 563 v4l2_async_nf_cleanup(&priv->notifier); 742 564 v4l2_subdev_cleanup(&priv->sd); 743 565 media_entity_cleanup(&priv->sd.entity); 566 + v4l2_ctrl_handler_free(&priv->ctrl_handler); 744 567 } 745 568 746 569 struct max96717_pll_predef_freq { ··· 767 588 static unsigned int max96717_clk_find_best_index(struct max96717_priv *priv, 768 589 unsigned long rate) 769 590 { 770 - unsigned int i, idx; 771 - unsigned long diff_new, diff_old; 772 - 773 - diff_old = U32_MAX; 774 - idx = 0; 591 + unsigned int i, idx = 0; 592 + unsigned long diff_new, diff_old = U32_MAX; 775 593 776 594 for (i = 0; i < ARRAY_SIZE(max96717_predef_freqs); i++) { 777 595 diff_new = abs(rate - max96717_predef_freqs[i].freq); ··· 855 679 struct clk_init_data init = { .ops = &max96717_clk_ops }; 856 680 int ret; 857 681 858 - init.name = kasprintf(GFP_KERNEL, "max96717.%s.clk_out", 859 - dev_name(dev)); 682 + init.name = kasprintf(GFP_KERNEL, "max96717.%s.clk_out", dev_name(dev)); 860 683 if (!init.name) 861 684 return -ENOMEM; 862 685 ··· 938 763 * Unused lanes need to be mapped as well to not have 939 764 * the same lanes mapped twice. 940 765 */ 941 - for (; lane < 4; lane++) { 942 - unsigned int idx = find_first_zero_bit(&lanes_used, 4); 766 + for (; lane < MAX96717_CSI_NLANES; lane++) { 767 + unsigned int idx = find_first_zero_bit(&lanes_used, 768 + MAX96717_CSI_NLANES); 943 769 944 770 val |= idx << (lane * 2); 945 771 lanes_used |= BIT(idx); ··· 994 818 static int max96717_parse_dt(struct max96717_priv *priv) 995 819 { 996 820 struct device *dev = &priv->client->dev; 997 - struct v4l2_fwnode_endpoint vep = { 998 - .bus_type = V4L2_MBUS_CSI2_DPHY 999 - }; 821 + struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; 1000 822 struct fwnode_handle *ep_fwnode; 1001 823 unsigned char num_data_lanes; 1002 824 int ret; ··· 1012 838 return dev_err_probe(dev, ret, "Failed to parse sink endpoint"); 1013 839 1014 840 num_data_lanes = vep.bus.mipi_csi2.num_data_lanes; 1015 - if (num_data_lanes < 1 || num_data_lanes > 4) 841 + if (num_data_lanes < 1 || num_data_lanes > MAX96717_CSI_NLANES) 1016 842 return dev_err_probe(dev, -EINVAL, 1017 843 "Invalid data lanes must be 1 to 4\n"); 1018 844 1019 - memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2)); 845 + priv->mipi_csi2 = vep.bus.mipi_csi2; 1020 846 1021 847 return 0; 1022 848 }
+2 -2
drivers/media/i2c/ml86v7667.c
··· 424 424 } 425 425 426 426 static const struct i2c_device_id ml86v7667_id[] = { 427 - {DRV_NAME, 0}, 428 - {}, 427 + { DRV_NAME }, 428 + {} 429 429 }; 430 430 MODULE_DEVICE_TABLE(i2c, ml86v7667_id); 431 431
+1 -1
drivers/media/i2c/msp3400-driver.c
··· 874 874 }; 875 875 876 876 static const struct i2c_device_id msp_id[] = { 877 - { "msp3400", 0 }, 877 + { "msp3400" }, 878 878 { } 879 879 }; 880 880 MODULE_DEVICE_TABLE(i2c, msp_id);
+1 -1
drivers/media/i2c/mt9m001.c
··· 854 854 } 855 855 856 856 static const struct i2c_device_id mt9m001_id[] = { 857 - { "mt9m001", 0 }, 857 + { "mt9m001" }, 858 858 { } 859 859 }; 860 860 MODULE_DEVICE_TABLE(i2c, mt9m001_id);
+1 -1
drivers/media/i2c/mt9m111.c
··· 1383 1383 MODULE_DEVICE_TABLE(of, mt9m111_of_match); 1384 1384 1385 1385 static const struct i2c_device_id mt9m111_id[] = { 1386 - { "mt9m111", 0 }, 1386 + { "mt9m111" }, 1387 1387 { } 1388 1388 }; 1389 1389 MODULE_DEVICE_TABLE(i2c, mt9m111_id);
+13 -25
drivers/media/i2c/mt9p031.c
··· 15 15 #include <linux/gpio/consumer.h> 16 16 #include <linux/i2c.h> 17 17 #include <linux/log2.h> 18 + #include <linux/mod_devicetable.h> 18 19 #include <linux/module.h> 19 20 #include <linux/of.h> 20 21 #include <linux/of_graph.h> ··· 113 112 #define MT9P031_TEST_PATTERN_RED 0xa2 114 113 #define MT9P031_TEST_PATTERN_BLUE 0xa3 115 114 116 - enum mt9p031_model { 117 - MT9P031_MODEL_COLOR, 118 - MT9P031_MODEL_MONOCHROME, 119 - }; 120 - 121 115 struct mt9p031 { 122 116 struct v4l2_subdev subdev; 123 117 struct media_pad pad; ··· 125 129 struct clk *clk; 126 130 struct regulator_bulk_data regulators[3]; 127 131 128 - enum mt9p031_model model; 132 + u32 code; 129 133 struct aptina_pll pll; 130 134 unsigned int clk_div; 131 135 bool use_pll; ··· 708 712 crop->height = MT9P031_WINDOW_HEIGHT_DEF; 709 713 710 714 format = __mt9p031_get_pad_format(mt9p031, sd_state, 0, which); 711 - 712 - if (mt9p031->model == MT9P031_MODEL_MONOCHROME) 713 - format->code = MEDIA_BUS_FMT_Y12_1X12; 714 - else 715 - format->code = MEDIA_BUS_FMT_SGRBG12_1X12; 716 - 715 + format->code = mt9p031->code; 717 716 format->width = MT9P031_WINDOW_WIDTH_DEF; 718 717 format->height = MT9P031_WINDOW_HEIGHT_DEF; 719 718 format->field = V4L2_FIELD_NONE; ··· 1093 1102 1094 1103 static int mt9p031_probe(struct i2c_client *client) 1095 1104 { 1096 - const struct i2c_device_id *did = i2c_client_get_device_id(client); 1097 1105 struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client); 1098 1106 struct i2c_adapter *adapter = client->adapter; 1099 1107 struct mt9p031 *mt9p031; ··· 1117 1127 mt9p031->pdata = pdata; 1118 1128 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; 1119 1129 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; 1120 - mt9p031->model = did->driver_data; 1130 + mt9p031->code = (uintptr_t)i2c_get_match_data(client); 1121 1131 1122 1132 mt9p031->regulators[0].supply = "vdd"; 1123 1133 mt9p031->regulators[1].supply = "vdd_io"; ··· 1214 1224 } 1215 1225 1216 1226 static const struct i2c_device_id mt9p031_id[] = { 1217 - { "mt9p006", MT9P031_MODEL_COLOR }, 1218 - { "mt9p031", MT9P031_MODEL_COLOR }, 1219 - { "mt9p031m", MT9P031_MODEL_MONOCHROME }, 1220 - { } 1227 + { "mt9p006", MEDIA_BUS_FMT_SGRBG12_1X12 }, 1228 + { "mt9p031", MEDIA_BUS_FMT_SGRBG12_1X12 }, 1229 + { "mt9p031m", MEDIA_BUS_FMT_Y12_1X12 }, 1230 + { /* sentinel */ } 1221 1231 }; 1222 1232 MODULE_DEVICE_TABLE(i2c, mt9p031_id); 1223 1233 1224 - #if IS_ENABLED(CONFIG_OF) 1225 1234 static const struct of_device_id mt9p031_of_match[] = { 1226 - { .compatible = "aptina,mt9p006", }, 1227 - { .compatible = "aptina,mt9p031", }, 1228 - { .compatible = "aptina,mt9p031m", }, 1229 - { /* sentinel */ }, 1235 + { .compatible = "aptina,mt9p006", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 }, 1236 + { .compatible = "aptina,mt9p031", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 }, 1237 + { .compatible = "aptina,mt9p031m", .data = (void *)MEDIA_BUS_FMT_Y12_1X12 }, 1238 + { /* sentinel */ } 1230 1239 }; 1231 1240 MODULE_DEVICE_TABLE(of, mt9p031_of_match); 1232 - #endif 1233 1241 1234 1242 static struct i2c_driver mt9p031_i2c_driver = { 1235 1243 .driver = { 1236 - .of_match_table = of_match_ptr(mt9p031_of_match), 1244 + .of_match_table = mt9p031_of_match, 1237 1245 .name = "mt9p031", 1238 1246 }, 1239 1247 .probe = mt9p031_probe,
+1 -1
drivers/media/i2c/mt9t112.c
··· 1109 1109 } 1110 1110 1111 1111 static const struct i2c_device_id mt9t112_id[] = { 1112 - { "mt9t112", 0 }, 1112 + { "mt9t112" }, 1113 1113 { } 1114 1114 }; 1115 1115 MODULE_DEVICE_TABLE(i2c, mt9t112_id);
+1 -1
drivers/media/i2c/mt9v011.c
··· 582 582 /* ----------------------------------------------------------------------- */ 583 583 584 584 static const struct i2c_device_id mt9v011_id[] = { 585 - { "mt9v011", 0 }, 585 + { "mt9v011" }, 586 586 { } 587 587 }; 588 588 MODULE_DEVICE_TABLE(i2c, mt9v011_id);
+2 -1
drivers/media/i2c/mt9v111.c
··· 1263 1263 1264 1264 static const struct of_device_id mt9v111_of_match[] = { 1265 1265 { .compatible = "aptina,mt9v111", }, 1266 - { /* sentinel */ }, 1266 + { /* sentinel */ } 1267 1267 }; 1268 + MODULE_DEVICE_TABLE(of, mt9v111_of_match); 1268 1269 1269 1270 static struct i2c_driver mt9v111_driver = { 1270 1271 .driver = {
+173 -14
drivers/media/i2c/og01a1b.c
··· 3 3 4 4 #include <asm/unaligned.h> 5 5 #include <linux/acpi.h> 6 + #include <linux/clk.h> 6 7 #include <linux/delay.h> 8 + #include <linux/gpio/consumer.h> 7 9 #include <linux/i2c.h> 8 10 #include <linux/module.h> 9 11 #include <linux/pm_runtime.h> 12 + #include <linux/regulator/consumer.h> 10 13 #include <media/v4l2-ctrls.h> 11 14 #include <media/v4l2-device.h> 12 15 #include <media/v4l2-fwnode.h> ··· 421 418 }; 422 419 423 420 struct og01a1b { 421 + struct clk *xvclk; 422 + struct gpio_desc *reset_gpio; 423 + struct regulator *avdd; 424 + struct regulator *dovdd; 425 + struct regulator *dvdd; 426 + 424 427 struct v4l2_subdev sd; 425 428 struct media_pad pad; 426 429 struct v4l2_ctrl_handler ctrl_handler; ··· 907 898 return 0; 908 899 } 909 900 910 - static int og01a1b_check_hwcfg(struct device *dev) 901 + static int og01a1b_check_hwcfg(struct og01a1b *og01a1b) 911 902 { 903 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 904 + struct device *dev = &client->dev; 912 905 struct fwnode_handle *ep; 913 906 struct fwnode_handle *fwnode = dev_fwnode(dev); 914 907 struct v4l2_fwnode_endpoint bus_cfg = { ··· 924 913 return -ENXIO; 925 914 926 915 ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); 927 - 928 916 if (ret) { 929 - dev_err(dev, "can't get clock frequency"); 930 - return ret; 917 + if (!og01a1b->xvclk) { 918 + dev_err(dev, "can't get clock frequency"); 919 + return ret; 920 + } 921 + 922 + mclk = clk_get_rate(og01a1b->xvclk); 931 923 } 932 924 933 925 if (mclk != OG01A1B_MCLK) { ··· 981 967 return ret; 982 968 } 983 969 970 + /* Power/clock management functions */ 971 + static int og01a1b_power_on(struct device *dev) 972 + { 973 + unsigned long delay = DIV_ROUND_UP(8192UL * USEC_PER_SEC, OG01A1B_MCLK); 974 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 975 + struct og01a1b *og01a1b = to_og01a1b(sd); 976 + int ret; 977 + 978 + if (og01a1b->avdd) { 979 + ret = regulator_enable(og01a1b->avdd); 980 + if (ret) 981 + return ret; 982 + } 983 + 984 + if (og01a1b->dovdd) { 985 + ret = regulator_enable(og01a1b->dovdd); 986 + if (ret) 987 + goto avdd_disable; 988 + } 989 + 990 + if (og01a1b->dvdd) { 991 + ret = regulator_enable(og01a1b->dvdd); 992 + if (ret) 993 + goto dovdd_disable; 994 + } 995 + 996 + ret = clk_prepare_enable(og01a1b->xvclk); 997 + if (ret) 998 + goto dvdd_disable; 999 + 1000 + gpiod_set_value_cansleep(og01a1b->reset_gpio, 0); 1001 + 1002 + if (og01a1b->reset_gpio) 1003 + usleep_range(5 * USEC_PER_MSEC, 6 * USEC_PER_MSEC); 1004 + else if (og01a1b->xvclk) 1005 + usleep_range(delay, 2 * delay); 1006 + 1007 + return 0; 1008 + 1009 + dvdd_disable: 1010 + if (og01a1b->dvdd) 1011 + regulator_disable(og01a1b->dvdd); 1012 + dovdd_disable: 1013 + if (og01a1b->dovdd) 1014 + regulator_disable(og01a1b->dovdd); 1015 + avdd_disable: 1016 + if (og01a1b->avdd) 1017 + regulator_disable(og01a1b->avdd); 1018 + 1019 + return ret; 1020 + } 1021 + 1022 + static int og01a1b_power_off(struct device *dev) 1023 + { 1024 + unsigned long delay = DIV_ROUND_UP(512 * USEC_PER_SEC, OG01A1B_MCLK); 1025 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 1026 + struct og01a1b *og01a1b = to_og01a1b(sd); 1027 + 1028 + if (og01a1b->xvclk) 1029 + usleep_range(delay, 2 * delay); 1030 + 1031 + clk_disable_unprepare(og01a1b->xvclk); 1032 + 1033 + gpiod_set_value_cansleep(og01a1b->reset_gpio, 1); 1034 + 1035 + if (og01a1b->dvdd) 1036 + regulator_disable(og01a1b->dvdd); 1037 + 1038 + if (og01a1b->dovdd) 1039 + regulator_disable(og01a1b->dovdd); 1040 + 1041 + if (og01a1b->avdd) 1042 + regulator_disable(og01a1b->avdd); 1043 + 1044 + return 0; 1045 + } 1046 + 984 1047 static void og01a1b_remove(struct i2c_client *client) 985 1048 { 986 1049 struct v4l2_subdev *sd = i2c_get_clientdata(client); ··· 1075 984 struct og01a1b *og01a1b; 1076 985 int ret; 1077 986 1078 - ret = og01a1b_check_hwcfg(&client->dev); 987 + og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL); 988 + if (!og01a1b) 989 + return -ENOMEM; 990 + 991 + v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops); 992 + 993 + og01a1b->xvclk = devm_clk_get_optional(&client->dev, NULL); 994 + if (IS_ERR(og01a1b->xvclk)) { 995 + ret = PTR_ERR(og01a1b->xvclk); 996 + dev_err(&client->dev, "failed to get xvclk clock: %d\n", ret); 997 + return ret; 998 + } 999 + 1000 + ret = og01a1b_check_hwcfg(og01a1b); 1079 1001 if (ret) { 1080 1002 dev_err(&client->dev, "failed to check HW configuration: %d", 1081 1003 ret); 1082 1004 return ret; 1083 1005 } 1084 1006 1085 - og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL); 1086 - if (!og01a1b) 1087 - return -ENOMEM; 1007 + og01a1b->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", 1008 + GPIOD_OUT_LOW); 1009 + if (IS_ERR(og01a1b->reset_gpio)) { 1010 + dev_err(&client->dev, "cannot get reset GPIO\n"); 1011 + return PTR_ERR(og01a1b->reset_gpio); 1012 + } 1088 1013 1089 - v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops); 1014 + og01a1b->avdd = devm_regulator_get_optional(&client->dev, "avdd"); 1015 + if (IS_ERR(og01a1b->avdd)) { 1016 + ret = PTR_ERR(og01a1b->avdd); 1017 + if (ret != -ENODEV) { 1018 + dev_err_probe(&client->dev, ret, 1019 + "Failed to get 'avdd' regulator\n"); 1020 + return ret; 1021 + } 1022 + 1023 + og01a1b->avdd = NULL; 1024 + } 1025 + 1026 + og01a1b->dovdd = devm_regulator_get_optional(&client->dev, "dovdd"); 1027 + if (IS_ERR(og01a1b->dovdd)) { 1028 + ret = PTR_ERR(og01a1b->dovdd); 1029 + if (ret != -ENODEV) { 1030 + dev_err_probe(&client->dev, ret, 1031 + "Failed to get 'dovdd' regulator\n"); 1032 + return ret; 1033 + } 1034 + 1035 + og01a1b->dovdd = NULL; 1036 + } 1037 + 1038 + og01a1b->dvdd = devm_regulator_get_optional(&client->dev, "dvdd"); 1039 + if (IS_ERR(og01a1b->dvdd)) { 1040 + ret = PTR_ERR(og01a1b->dvdd); 1041 + if (ret != -ENODEV) { 1042 + dev_err_probe(&client->dev, ret, 1043 + "Failed to get 'dvdd' regulator\n"); 1044 + return ret; 1045 + } 1046 + 1047 + og01a1b->dvdd = NULL; 1048 + } 1049 + 1050 + /* The sensor must be powered on to read the CHIP_ID register */ 1051 + ret = og01a1b_power_on(&client->dev); 1052 + if (ret) 1053 + return ret; 1054 + 1090 1055 ret = og01a1b_identify_module(og01a1b); 1091 1056 if (ret) { 1092 1057 dev_err(&client->dev, "failed to find sensor: %d", ret); 1093 - return ret; 1058 + goto power_off; 1094 1059 } 1095 1060 1096 1061 mutex_init(&og01a1b->mutex); ··· 1175 1028 goto probe_error_media_entity_cleanup; 1176 1029 } 1177 1030 1178 - /* 1179 - * Device is already turned on by i2c-core with ACPI domain PM. 1180 - * Enable runtime PM and turn off the device. 1181 - */ 1031 + /* Enable runtime PM and turn off the device */ 1182 1032 pm_runtime_set_active(&client->dev); 1183 1033 pm_runtime_enable(&client->dev); 1184 1034 pm_runtime_idle(&client->dev); ··· 1189 1045 v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler); 1190 1046 mutex_destroy(&og01a1b->mutex); 1191 1047 1048 + power_off: 1049 + og01a1b_power_off(&client->dev); 1050 + 1192 1051 return ret; 1193 1052 } 1053 + 1054 + static const struct dev_pm_ops og01a1b_pm_ops = { 1055 + SET_RUNTIME_PM_OPS(og01a1b_power_off, og01a1b_power_on, NULL) 1056 + }; 1194 1057 1195 1058 #ifdef CONFIG_ACPI 1196 1059 static const struct acpi_device_id og01a1b_acpi_ids[] = { ··· 1208 1057 MODULE_DEVICE_TABLE(acpi, og01a1b_acpi_ids); 1209 1058 #endif 1210 1059 1060 + static const struct of_device_id og01a1b_of_match[] = { 1061 + { .compatible = "ovti,og01a1b" }, 1062 + { /* sentinel */ } 1063 + }; 1064 + MODULE_DEVICE_TABLE(of, og01a1b_of_match); 1065 + 1211 1066 static struct i2c_driver og01a1b_i2c_driver = { 1212 1067 .driver = { 1213 1068 .name = "og01a1b", 1069 + .pm = &og01a1b_pm_ops, 1214 1070 .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids), 1071 + .of_match_table = og01a1b_of_match, 1215 1072 }, 1216 1073 .probe = og01a1b_probe, 1217 1074 .remove = og01a1b_remove,
+2 -2
drivers/media/i2c/ov13858.c
··· 1740 1740 } 1741 1741 1742 1742 static const struct i2c_device_id ov13858_id_table[] = { 1743 - {"ov13858", 0}, 1744 - {}, 1743 + { "ov13858" }, 1744 + {} 1745 1745 }; 1746 1746 1747 1747 MODULE_DEVICE_TABLE(i2c, ov13858_id_table);
+1 -1
drivers/media/i2c/ov2640.c
··· 1271 1271 } 1272 1272 1273 1273 static const struct i2c_device_id ov2640_id[] = { 1274 - { "ov2640", 0 }, 1274 + { "ov2640" }, 1275 1275 { } 1276 1276 }; 1277 1277 MODULE_DEVICE_TABLE(i2c, ov2640_id);
+2 -2
drivers/media/i2c/ov2659.c
··· 1551 1551 }; 1552 1552 1553 1553 static const struct i2c_device_id ov2659_id[] = { 1554 - { "ov2659", 0 }, 1555 - { /* sentinel */ }, 1554 + { "ov2659" }, 1555 + { /* sentinel */ } 1556 1556 }; 1557 1557 MODULE_DEVICE_TABLE(i2c, ov2659_id); 1558 1558
+2 -2
drivers/media/i2c/ov5640.c
··· 4003 4003 }; 4004 4004 4005 4005 static const struct i2c_device_id ov5640_id[] = { 4006 - {"ov5640", 0}, 4007 - {}, 4006 + { "ov5640" }, 4007 + {} 4008 4008 }; 4009 4009 MODULE_DEVICE_TABLE(i2c, ov5640_id); 4010 4010
+13 -4
drivers/media/i2c/ov5645.c
··· 635 635 return 0; 636 636 } 637 637 638 - static int ov5645_set_power_off(struct device *dev) 638 + static void __ov5645_set_power_off(struct device *dev) 639 639 { 640 640 struct v4l2_subdev *sd = dev_get_drvdata(dev); 641 641 struct ov5645 *ov5645 = to_ov5645(sd); ··· 643 643 ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58); 644 644 gpiod_set_value_cansleep(ov5645->rst_gpio, 1); 645 645 gpiod_set_value_cansleep(ov5645->enable_gpio, 0); 646 - clk_disable_unprepare(ov5645->xclk); 647 646 regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); 647 + } 648 + 649 + static int ov5645_set_power_off(struct device *dev) 650 + { 651 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 652 + struct ov5645 *ov5645 = to_ov5645(sd); 653 + 654 + __ov5645_set_power_off(dev); 655 + clk_disable_unprepare(ov5645->xclk); 648 656 649 657 return 0; 650 658 } ··· 694 686 return 0; 695 687 696 688 exit: 697 - ov5645_set_power_off(dev); 689 + __ov5645_set_power_off(dev); 690 + clk_disable_unprepare(ov5645->xclk); 698 691 return ret; 699 692 } 700 693 ··· 1281 1272 } 1282 1273 1283 1274 static const struct i2c_device_id ov5645_id[] = { 1284 - { "ov5645", 0 }, 1275 + { "ov5645" }, 1285 1276 {} 1286 1277 }; 1287 1278 MODULE_DEVICE_TABLE(i2c, ov5645_id);
+1 -1
drivers/media/i2c/ov5647.c
··· 1487 1487 }; 1488 1488 1489 1489 static const struct i2c_device_id ov5647_id[] = { 1490 - { "ov5647", 0 }, 1490 + { "ov5647" }, 1491 1491 { /* sentinel */ } 1492 1492 }; 1493 1493 MODULE_DEVICE_TABLE(i2c, ov5647_id);
+6 -6
drivers/media/i2c/ov5675.c
··· 972 972 973 973 static int ov5675_power_off(struct device *dev) 974 974 { 975 - /* 512 xvclk cycles after the last SCCB transation or MIPI frame end */ 976 - u32 delay_us = DIV_ROUND_UP(512, OV5675_XVCLK_19_2 / 1000 / 1000); 977 975 struct v4l2_subdev *sd = dev_get_drvdata(dev); 978 976 struct ov5675 *ov5675 = to_ov5675(sd); 979 977 980 - usleep_range(delay_us, delay_us * 2); 978 + usleep_range(90, 100); 981 979 982 980 clk_disable_unprepare(ov5675->xvclk); 983 981 gpiod_set_value_cansleep(ov5675->reset_gpio, 1); ··· 986 988 987 989 static int ov5675_power_on(struct device *dev) 988 990 { 989 - u32 delay_us = DIV_ROUND_UP(8192, OV5675_XVCLK_19_2 / 1000 / 1000); 990 991 struct v4l2_subdev *sd = dev_get_drvdata(dev); 991 992 struct ov5675 *ov5675 = to_ov5675(sd); 992 993 int ret; ··· 1011 1014 1012 1015 gpiod_set_value_cansleep(ov5675->reset_gpio, 0); 1013 1016 1014 - /* 8192 xvclk cycles prior to the first SCCB transation */ 1015 - usleep_range(delay_us, delay_us * 2); 1017 + /* Worst case quiesence gap is 1.365 milliseconds @ 6MHz XVCLK 1018 + * Add an additional threshold grace period to ensure reset 1019 + * completion before initiating our first I2C transaction. 1020 + */ 1021 + usleep_range(1500, 1600); 1016 1022 1017 1023 return 0; 1018 1024 }
+1 -1
drivers/media/i2c/ov6650.c
··· 1128 1128 } 1129 1129 1130 1130 static const struct i2c_device_id ov6650_id[] = { 1131 - { "ov6650", 0 }, 1131 + { "ov6650" }, 1132 1132 { } 1133 1133 }; 1134 1134 MODULE_DEVICE_TABLE(i2c, ov6650_id);
+1 -1
drivers/media/i2c/ov7640.c
··· 77 77 } 78 78 79 79 static const struct i2c_device_id ov7640_id[] = { 80 - { "ov7640", 0 }, 80 + { "ov7640" }, 81 81 { } 82 82 }; 83 83 MODULE_DEVICE_TABLE(i2c, ov7640_id);
+1 -1
drivers/media/i2c/ov772x.c
··· 1546 1546 } 1547 1547 1548 1548 static const struct i2c_device_id ov772x_id[] = { 1549 - { "ov772x", 0 }, 1549 + { "ov772x" }, 1550 1550 { } 1551 1551 }; 1552 1552 MODULE_DEVICE_TABLE(i2c, ov772x_id);
+1 -1
drivers/media/i2c/ov7740.c
··· 1152 1152 } 1153 1153 1154 1154 static const struct i2c_device_id ov7740_id[] = { 1155 - { "ov7740", 0 }, 1155 + { "ov7740" }, 1156 1156 { /* sentinel */ } 1157 1157 }; 1158 1158 MODULE_DEVICE_TABLE(i2c, ov7740_id);
+1 -1
drivers/media/i2c/ov9640.c
··· 751 751 } 752 752 753 753 static const struct i2c_device_id ov9640_id[] = { 754 - { "ov9640", 0 }, 754 + { "ov9640" }, 755 755 { } 756 756 }; 757 757 MODULE_DEVICE_TABLE(i2c, ov9640_id);
+2 -2
drivers/media/i2c/ov9650.c
··· 1566 1566 } 1567 1567 1568 1568 static const struct i2c_device_id ov965x_id[] = { 1569 - { "OV9650", 0 }, 1570 - { "OV9652", 0 }, 1569 + { "OV9650" }, 1570 + { "OV9652" }, 1571 1571 { /* sentinel */ } 1572 1572 }; 1573 1573 MODULE_DEVICE_TABLE(i2c, ov965x_id);
+1 -1
drivers/media/i2c/rj54n1cb0c.c
··· 1410 1410 } 1411 1411 1412 1412 static const struct i2c_device_id rj54n1_id[] = { 1413 - { "rj54n1cb0c", 0 }, 1413 + { "rj54n1cb0c" }, 1414 1414 { } 1415 1415 }; 1416 1416 MODULE_DEVICE_TABLE(i2c, rj54n1_id);
+13 -2
drivers/media/i2c/s5c73m3/s5c73m3-core.c
··· 1392 1392 return ret; 1393 1393 } 1394 1394 1395 + /* 1396 + * This function has been created just to avoid a smatch warning, 1397 + * please do not merge into __s5c73m3_power_off() until you have 1398 + * confirmed that it does not introduce a new warning. 1399 + */ 1400 + static void s5c73m3_enable_clk(struct s5c73m3 *state) 1401 + { 1402 + clk_prepare_enable(state->clock); 1403 + } 1404 + 1395 1405 static int __s5c73m3_power_off(struct s5c73m3 *state) 1396 1406 { 1397 1407 int i, ret; ··· 1431 1421 state->supplies[i].supply, r); 1432 1422 } 1433 1423 1434 - clk_prepare_enable(state->clock); 1424 + s5c73m3_enable_clk(state); 1425 + 1435 1426 return ret; 1436 1427 } 1437 1428 ··· 1735 1724 } 1736 1725 1737 1726 static const struct i2c_device_id s5c73m3_id[] = { 1738 - { DRIVER_NAME, 0 }, 1727 + { DRIVER_NAME }, 1739 1728 { } 1740 1729 }; 1741 1730 MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
+2 -2
drivers/media/i2c/s5k5baf.c
··· 2018 2018 } 2019 2019 2020 2020 static const struct i2c_device_id s5k5baf_id[] = { 2021 - { S5K5BAF_DRIVER_NAME, 0 }, 2022 - { }, 2021 + { S5K5BAF_DRIVER_NAME }, 2022 + { } 2023 2023 }; 2024 2024 MODULE_DEVICE_TABLE(i2c, s5k5baf_id); 2025 2025
+1 -1
drivers/media/i2c/saa6588.c
··· 496 496 /* ----------------------------------------------------------------------- */ 497 497 498 498 static const struct i2c_device_id saa6588_id[] = { 499 - { "saa6588", 0 }, 499 + { "saa6588" }, 500 500 { } 501 501 }; 502 502 MODULE_DEVICE_TABLE(i2c, saa6588_id);
+1 -1
drivers/media/i2c/saa6752hs.c
··· 770 770 } 771 771 772 772 static const struct i2c_device_id saa6752hs_id[] = { 773 - { "saa6752hs", 0 }, 773 + { "saa6752hs" }, 774 774 { } 775 775 }; 776 776 MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
+1 -1
drivers/media/i2c/saa7110.c
··· 439 439 /* ----------------------------------------------------------------------- */ 440 440 441 441 static const struct i2c_device_id saa7110_id[] = { 442 - { "saa7110", 0 }, 442 + { "saa7110" }, 443 443 { } 444 444 }; 445 445 MODULE_DEVICE_TABLE(i2c, saa7110_id);
+1 -1
drivers/media/i2c/saa717x.c
··· 1334 1334 /* ----------------------------------------------------------------------- */ 1335 1335 1336 1336 static const struct i2c_device_id saa717x_id[] = { 1337 - { "saa717x", 0 }, 1337 + { "saa717x" }, 1338 1338 { } 1339 1339 }; 1340 1340 MODULE_DEVICE_TABLE(i2c, saa717x_id);
+1 -1
drivers/media/i2c/saa7185.c
··· 334 334 /* ----------------------------------------------------------------------- */ 335 335 336 336 static const struct i2c_device_id saa7185_id[] = { 337 - { "saa7185", 0 }, 337 + { "saa7185" }, 338 338 { } 339 339 }; 340 340 MODULE_DEVICE_TABLE(i2c, saa7185_id);
+1 -1
drivers/media/i2c/sony-btf-mpx.c
··· 366 366 /* ----------------------------------------------------------------------- */ 367 367 368 368 static const struct i2c_device_id sony_btf_mpx_id[] = { 369 - { "sony-btf-mpx", 0 }, 369 + { "sony-btf-mpx" }, 370 370 { } 371 371 }; 372 372 MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
+1 -1
drivers/media/i2c/tc358743.c
··· 2197 2197 } 2198 2198 2199 2199 static const struct i2c_device_id tc358743_id[] = { 2200 - {"tc358743", 0}, 2200 + { "tc358743" }, 2201 2201 {} 2202 2202 }; 2203 2203
+11 -1
drivers/media/i2c/tc358746.c
··· 1616 1616 pm_runtime_dont_use_autosuspend(sd->dev); 1617 1617 } 1618 1618 1619 + /* 1620 + * This function has been created just to avoid a smatch warning, 1621 + * please do not merge it into tc358746_suspend until you have 1622 + * confirmed that it does not introduce a new warning. 1623 + */ 1624 + static void tc358746_clk_enable(struct tc358746 *tc358746) 1625 + { 1626 + clk_prepare_enable(tc358746->refclk); 1627 + } 1628 + 1619 1629 static int tc358746_suspend(struct device *dev) 1620 1630 { 1621 1631 struct tc358746 *tc358746 = dev_get_drvdata(dev); ··· 1636 1626 err = regulator_bulk_disable(ARRAY_SIZE(tc358746_supplies), 1637 1627 tc358746->supplies); 1638 1628 if (err) 1639 - clk_prepare_enable(tc358746->refclk); 1629 + tc358746_clk_enable(tc358746); 1640 1630 1641 1631 return err; 1642 1632 }
+1 -1
drivers/media/i2c/tda1997x.c
··· 2514 2514 { 2515 2515 } 2516 2516 2517 - static struct snd_soc_component_driver tda1997x_codec_driver = { 2517 + static const struct snd_soc_component_driver tda1997x_codec_driver = { 2518 2518 .probe = tda1997x_codec_probe, 2519 2519 .remove = tda1997x_codec_remove, 2520 2520 .idle_bias_on = 1,
+1 -1
drivers/media/i2c/tda7432.c
··· 400 400 } 401 401 402 402 static const struct i2c_device_id tda7432_id[] = { 403 - { "tda7432", 0 }, 403 + { "tda7432" }, 404 404 { } 405 405 }; 406 406 MODULE_DEVICE_TABLE(i2c, tda7432_id);
+1 -1
drivers/media/i2c/tda9840.c
··· 182 182 } 183 183 184 184 static const struct i2c_device_id tda9840_id[] = { 185 - { "tda9840", 0 }, 185 + { "tda9840" }, 186 186 { } 187 187 }; 188 188 MODULE_DEVICE_TABLE(i2c, tda9840_id);
+1 -1
drivers/media/i2c/tea6415c.c
··· 141 141 } 142 142 143 143 static const struct i2c_device_id tea6415c_id[] = { 144 - { "tea6415c", 0 }, 144 + { "tea6415c" }, 145 145 { } 146 146 }; 147 147 MODULE_DEVICE_TABLE(i2c, tea6415c_id);
+1 -1
drivers/media/i2c/tea6420.c
··· 123 123 } 124 124 125 125 static const struct i2c_device_id tea6420_id[] = { 126 - { "tea6420", 0 }, 126 + { "tea6420" }, 127 127 { } 128 128 }; 129 129 MODULE_DEVICE_TABLE(i2c, tea6420_id);
+1 -1
drivers/media/i2c/thp7312.c
··· 1503 1503 1504 1504 msgs[0].addr = client->addr; 1505 1505 msgs[0].flags = 0; 1506 - msgs[0].len = sizeof(thp7312_cmd_read_reg), 1506 + msgs[0].len = sizeof(thp7312_cmd_read_reg); 1507 1507 msgs[0].buf = (u8 *)thp7312_cmd_read_reg; 1508 1508 1509 1509 msgs[1].addr = client->addr;
+3 -3
drivers/media/i2c/ths7303.c
··· 369 369 } 370 370 371 371 static const struct i2c_device_id ths7303_id[] = { 372 - {"ths7303", 0}, 373 - {"ths7353", 0}, 374 - {}, 372 + { "ths7303" }, 373 + { "ths7353" }, 374 + {} 375 375 }; 376 376 377 377 MODULE_DEVICE_TABLE(i2c, ths7303_id);
+2 -2
drivers/media/i2c/ths8200.c
··· 487 487 } 488 488 489 489 static const struct i2c_device_id ths8200_id[] = { 490 - { "ths8200", 0 }, 491 - {}, 490 + { "ths8200" }, 491 + {} 492 492 }; 493 493 MODULE_DEVICE_TABLE(i2c, ths8200_id); 494 494
+1 -1
drivers/media/i2c/tlv320aic23b.c
··· 188 188 /* ----------------------------------------------------------------------- */ 189 189 190 190 static const struct i2c_device_id tlv320aic23b_id[] = { 191 - { "tlv320aic23b", 0 }, 191 + { "tlv320aic23b" }, 192 192 { } 193 193 }; 194 194 MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
+1 -1
drivers/media/i2c/tvaudio.c
··· 2086 2086 detect which device is present. So rather than listing all supported 2087 2087 devices here, we pretend to support a single, fake device type. */ 2088 2088 static const struct i2c_device_id tvaudio_id[] = { 2089 - { "tvaudio", 0 }, 2089 + { "tvaudio" }, 2090 2090 { } 2091 2091 }; 2092 2092 MODULE_DEVICE_TABLE(i2c, tvaudio_id);
+3 -3
drivers/media/i2c/tvp5150.c
··· 514 514 * and so on. There are 16 possible locations from 0 to 15. 515 515 */ 516 516 517 - static struct i2c_vbi_ram_value vbi_ram_default[] = { 517 + static const struct i2c_vbi_ram_value vbi_ram_default[] = { 518 518 519 519 /* 520 520 * FIXME: Current api doesn't handle all VBI types, those not ··· 1812 1812 .n_yes_ranges = ARRAY_SIZE(tvp5150_readable_ranges), 1813 1813 }; 1814 1814 1815 - static struct regmap_config tvp5150_config = { 1815 + static const struct regmap_config tvp5150_config = { 1816 1816 .reg_bits = 8, 1817 1817 .val_bits = 8, 1818 1818 .max_register = 0xff, ··· 2265 2265 }; 2266 2266 2267 2267 static const struct i2c_device_id tvp5150_id[] = { 2268 - { "tvp5150", 0 }, 2268 + { "tvp5150" }, 2269 2269 { } 2270 2270 }; 2271 2271 MODULE_DEVICE_TABLE(i2c, tvp5150_id);
+1 -1
drivers/media/i2c/tvp7002.c
··· 1070 1070 1071 1071 /* I2C Device ID table */ 1072 1072 static const struct i2c_device_id tvp7002_id[] = { 1073 - { "tvp7002", 0 }, 1073 + { "tvp7002" }, 1074 1074 { } 1075 1075 }; 1076 1076 MODULE_DEVICE_TABLE(i2c, tvp7002_id);
+1 -1
drivers/media/i2c/tw2804.c
··· 414 414 } 415 415 416 416 static const struct i2c_device_id tw2804_id[] = { 417 - { "tw2804", 0 }, 417 + { "tw2804" }, 418 418 { } 419 419 }; 420 420 MODULE_DEVICE_TABLE(i2c, tw2804_id);
+1 -1
drivers/media/i2c/tw9900.c
··· 753 753 }; 754 754 755 755 static const struct i2c_device_id tw9900_id[] = { 756 - { "tw9900", 0 }, 756 + { "tw9900" }, 757 757 { } 758 758 }; 759 759 MODULE_DEVICE_TABLE(i2c, tw9900_id);
+1 -1
drivers/media/i2c/tw9903.c
··· 245 245 /* ----------------------------------------------------------------------- */ 246 246 247 247 static const struct i2c_device_id tw9903_id[] = { 248 - { "tw9903", 0 }, 248 + { "tw9903" }, 249 249 { } 250 250 }; 251 251 MODULE_DEVICE_TABLE(i2c, tw9903_id);
+1 -1
drivers/media/i2c/tw9906.c
··· 213 213 /* ----------------------------------------------------------------------- */ 214 214 215 215 static const struct i2c_device_id tw9906_id[] = { 216 - { "tw9906", 0 }, 216 + { "tw9906" }, 217 217 { } 218 218 }; 219 219 MODULE_DEVICE_TABLE(i2c, tw9906_id);
+1 -1
drivers/media/i2c/tw9910.c
··· 996 996 } 997 997 998 998 static const struct i2c_device_id tw9910_id[] = { 999 - { "tw9910", 0 }, 999 + { "tw9910" }, 1000 1000 { } 1001 1001 }; 1002 1002 MODULE_DEVICE_TABLE(i2c, tw9910_id);
+1 -1
drivers/media/i2c/uda1342.c
··· 79 79 } 80 80 81 81 static const struct i2c_device_id uda1342_id[] = { 82 - { "uda1342", 0 }, 82 + { "uda1342" }, 83 83 { } 84 84 }; 85 85 MODULE_DEVICE_TABLE(i2c, uda1342_id);
+1 -1
drivers/media/i2c/upd64031a.c
··· 219 219 /* ----------------------------------------------------------------------- */ 220 220 221 221 static const struct i2c_device_id upd64031a_id[] = { 222 - { "upd64031a", 0 }, 222 + { "upd64031a" }, 223 223 { } 224 224 }; 225 225 MODULE_DEVICE_TABLE(i2c, upd64031a_id);
+1 -1
drivers/media/i2c/upd64083.c
··· 190 190 /* ----------------------------------------------------------------------- */ 191 191 192 192 static const struct i2c_device_id upd64083_id[] = { 193 - { "upd64083", 0 }, 193 + { "upd64083" }, 194 194 { } 195 195 }; 196 196 MODULE_DEVICE_TABLE(i2c, upd64083_id);
+1 -1
drivers/media/i2c/vp27smpx.c
··· 172 172 /* ----------------------------------------------------------------------- */ 173 173 174 174 static const struct i2c_device_id vp27smpx_id[] = { 175 - { "vp27smpx", 0 }, 175 + { "vp27smpx" }, 176 176 { } 177 177 }; 178 178 MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
+3 -3
drivers/media/i2c/vpx3220.c
··· 535 535 } 536 536 537 537 static const struct i2c_device_id vpx3220_id[] = { 538 - { "vpx3220a", 0 }, 539 - { "vpx3216b", 0 }, 540 - { "vpx3214c", 0 }, 538 + { "vpx3220a" }, 539 + { "vpx3216b" }, 540 + { "vpx3214c" }, 541 541 { } 542 542 }; 543 543 MODULE_DEVICE_TABLE(i2c, vpx3220_id);
+1 -1
drivers/media/i2c/wm8739.c
··· 243 243 } 244 244 245 245 static const struct i2c_device_id wm8739_id[] = { 246 - { "wm8739", 0 }, 246 + { "wm8739" }, 247 247 { } 248 248 }; 249 249 MODULE_DEVICE_TABLE(i2c, wm8739_id);
+1 -1
drivers/media/i2c/wm8775.c
··· 289 289 } 290 290 291 291 static const struct i2c_device_id wm8775_id[] = { 292 - { "wm8775", 0 }, 292 + { "wm8775" }, 293 293 { } 294 294 }; 295 295 MODULE_DEVICE_TABLE(i2c, wm8775_id);
+8 -12
drivers/media/pci/intel/ipu6/ipu6.c
··· 390 390 isys_adev = ipu6_bus_initialize_device(pdev, parent, pdata, ctrl, 391 391 IPU6_ISYS_NAME); 392 392 if (IS_ERR(isys_adev)) { 393 - dev_err_probe(dev, PTR_ERR(isys_adev), 394 - "ipu6_bus_initialize_device isys failed\n"); 395 393 kfree(pdata); 396 - return ERR_CAST(isys_adev); 394 + return dev_err_cast_probe(dev, isys_adev, 395 + "ipu6_bus_initialize_device isys failed\n"); 397 396 } 398 397 399 398 isys_adev->mmu = ipu6_mmu_init(dev, base, ISYS_MMID, 400 399 &ipdata->hw_variant); 401 400 if (IS_ERR(isys_adev->mmu)) { 402 - dev_err_probe(dev, PTR_ERR(isys_adev->mmu), 403 - "ipu6_mmu_init(isys_adev->mmu) failed\n"); 404 401 put_device(&isys_adev->auxdev.dev); 405 402 kfree(pdata); 406 - return ERR_CAST(isys_adev->mmu); 403 + return dev_err_cast_probe(dev, isys_adev->mmu, 404 + "ipu6_mmu_init(isys_adev->mmu) failed\n"); 407 405 } 408 406 409 407 isys_adev->mmu->dev = &isys_adev->auxdev.dev; ··· 434 436 psys_adev = ipu6_bus_initialize_device(pdev, parent, pdata, ctrl, 435 437 IPU6_PSYS_NAME); 436 438 if (IS_ERR(psys_adev)) { 437 - dev_err_probe(&pdev->dev, PTR_ERR(psys_adev), 438 - "ipu6_bus_initialize_device psys failed\n"); 439 439 kfree(pdata); 440 - return ERR_CAST(psys_adev); 440 + return dev_err_cast_probe(&pdev->dev, psys_adev, 441 + "ipu6_bus_initialize_device psys failed\n"); 441 442 } 442 443 443 444 psys_adev->mmu = ipu6_mmu_init(&pdev->dev, base, PSYS_MMID, 444 445 &ipdata->hw_variant); 445 446 if (IS_ERR(psys_adev->mmu)) { 446 - dev_err_probe(&pdev->dev, PTR_ERR(psys_adev->mmu), 447 - "ipu6_mmu_init(psys_adev->mmu) failed\n"); 448 447 put_device(&psys_adev->auxdev.dev); 449 448 kfree(pdata); 450 - return ERR_CAST(psys_adev->mmu); 449 + return dev_err_cast_probe(&pdev->dev, psys_adev->mmu, 450 + "ipu6_mmu_init(psys_adev->mmu) failed\n"); 451 451 } 452 452 453 453 psys_adev->mmu->dev = &psys_adev->auxdev.dev;
+1 -1
drivers/media/pci/mgb4/mgb4_core.c
··· 302 302 /* create dummy clock required by the xiic-i2c adapter */ 303 303 snprintf(clk_name, sizeof(clk_name), "xiic-i2c.%d", id); 304 304 mgbdev->i2c_clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 305 - 0, 125000000); 305 + 0, MGB4_HW_FREQ); 306 306 if (IS_ERR(mgbdev->i2c_clk)) { 307 307 dev_err(dev, "failed to register I2C clock\n"); 308 308 return PTR_ERR(mgbdev->i2c_clk);
+2
drivers/media/pci/mgb4/mgb4_core.h
··· 13 13 #include <linux/dmaengine.h> 14 14 #include "mgb4_regs.h" 15 15 16 + #define MGB4_HW_FREQ 125000000 17 + 16 18 #define MGB4_VIN_DEVICES 2 17 19 #define MGB4_VOUT_DEVICES 2 18 20
+25 -4
drivers/media/pci/mgb4/mgb4_io.h
··· 7 7 #ifndef __MGB4_IO_H__ 8 8 #define __MGB4_IO_H__ 9 9 10 + #include <linux/math64.h> 10 11 #include <media/v4l2-dev.h> 11 - 12 - #define MGB4_DEFAULT_WIDTH 1280 13 - #define MGB4_DEFAULT_HEIGHT 640 14 - #define MGB4_DEFAULT_PERIOD (125000000 / 60) 12 + #include "mgb4_core.h" 15 13 16 14 /* Register access error indication */ 17 15 #define MGB4_ERR_NO_REG 0xFFFFFFFE ··· 17 19 #define MGB4_ERR_QUEUE_TIMEOUT 0xFFFFFFFD 18 20 #define MGB4_ERR_QUEUE_EMPTY 0xFFFFFFFC 19 21 #define MGB4_ERR_QUEUE_FULL 0xFFFFFFFB 22 + 23 + #define MGB4_PERIOD(numerator, denominator) \ 24 + ((u32)div_u64((MGB4_HW_FREQ * (u64)(numerator)), (denominator))) 20 25 21 26 struct mgb4_frame_buffer { 22 27 struct vb2_v4l2_buffer vb; ··· 29 28 static inline struct mgb4_frame_buffer *to_frame_buffer(struct vb2_v4l2_buffer *vbuf) 30 29 { 31 30 return container_of(vbuf, struct mgb4_frame_buffer, vb); 31 + } 32 + 33 + static inline bool has_yuv_and_timeperframe(struct mgb4_regs *video) 34 + { 35 + u32 status = mgb4_read_reg(video, 0xD0); 36 + 37 + return (status & (1U << 8)); 38 + } 39 + 40 + #define has_yuv(video) has_yuv_and_timeperframe(video) 41 + #define has_timeperframe(video) has_yuv_and_timeperframe(video) 42 + 43 + static inline u32 pixel_size(struct v4l2_dv_timings *timings) 44 + { 45 + struct v4l2_bt_timings *bt = &timings->bt; 46 + 47 + u32 height = bt->height + bt->vfrontporch + bt->vsync + bt->vbackporch; 48 + u32 width = bt->width + bt->hfrontporch + bt->hsync + bt->hbackporch; 49 + 50 + return width * height; 32 51 } 33 52 34 53 #endif
+5 -4
drivers/media/pci/mgb4/mgb4_sysfs_out.c
··· 229 229 struct video_device *vdev = to_video_device(dev); 230 230 struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev); 231 231 u32 period = mgb4_read_reg(&voutdev->mgbdev->video, 232 - voutdev->config->regs.frame_period); 232 + voutdev->config->regs.frame_limit); 233 233 234 - return sprintf(buf, "%u\n", 125000000 / period); 234 + return sprintf(buf, "%u\n", period ? MGB4_HW_FREQ / period : 0); 235 235 } 236 236 237 237 /* ··· 245 245 struct video_device *vdev = to_video_device(dev); 246 246 struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev); 247 247 unsigned long val; 248 - int ret; 248 + int limit, ret; 249 249 250 250 ret = kstrtoul(buf, 10, &val); 251 251 if (ret) 252 252 return ret; 253 253 254 + limit = val ? MGB4_HW_FREQ / val : 0; 254 255 mgb4_write_reg(&voutdev->mgbdev->video, 255 - voutdev->config->regs.frame_period, 125000000 / val); 256 + voutdev->config->regs.frame_limit, limit); 256 257 257 258 return count; 258 259 }
+152 -41
drivers/media/pci/mgb4/mgb4_vin.c
··· 18 18 #include <linux/workqueue.h> 19 19 #include <linux/align.h> 20 20 #include <linux/dma/amd_xdma.h> 21 + #include <linux/v4l2-dv-timings.h> 21 22 #include <media/v4l2-ioctl.h> 22 23 #include <media/videobuf2-v4l2.h> 23 24 #include <media/videobuf2-dma-sg.h> ··· 35 34 ATTRIBUTE_GROUPS(mgb4_gmsl_in); 36 35 37 36 static const struct mgb4_vin_config vin_cfg[] = { 38 - {0, 0, 0, 6, {0x10, 0x00, 0x04, 0x08, 0x1C, 0x14, 0x18, 0x20, 0x24, 0x28}}, 39 - {1, 1, 1, 7, {0x40, 0x30, 0x34, 0x38, 0x4C, 0x44, 0x48, 0x50, 0x54, 0x58}} 37 + {0, 0, 0, 6, {0x10, 0x00, 0x04, 0x08, 0x1C, 0x14, 0x18, 0x20, 0x24, 0x28, 0xE8}}, 38 + {1, 1, 1, 7, {0x40, 0x30, 0x34, 0x38, 0x4C, 0x44, 0x48, 0x50, 0x54, 0x58, 0xEC}} 40 39 }; 41 40 42 41 static const struct i2c_board_info fpdl3_deser_info[] = { ··· 76 75 V4L2_DV_BT_CAP_CUSTOM, 77 76 }, 78 77 }; 78 + 79 + /* Dummy timings when no signal present */ 80 + static const struct v4l2_dv_timings cea1080p60 = V4L2_DV_BT_CEA_1920X1080P60; 79 81 80 82 /* 81 83 * Returns the video output connected with the given video input if the input ··· 190 186 struct device *alloc_devs[]) 191 187 { 192 188 struct mgb4_vin_dev *vindev = vb2_get_drv_priv(q); 189 + struct mgb4_regs *video = &vindev->mgbdev->video; 190 + u32 config = mgb4_read_reg(video, vindev->config->regs.config); 191 + u32 pixelsize = (config & (1U << 16)) ? 2 : 4; 193 192 unsigned int size = (vindev->timings.bt.width + vindev->padding) 194 - * vindev->timings.bt.height * 4; 193 + * vindev->timings.bt.height * pixelsize; 195 194 196 195 /* 197 196 * If I/O reconfiguration is in process, do not allow to start ··· 227 220 static int buffer_prepare(struct vb2_buffer *vb) 228 221 { 229 222 struct mgb4_vin_dev *vindev = vb2_get_drv_priv(vb->vb2_queue); 223 + struct mgb4_regs *video = &vindev->mgbdev->video; 230 224 struct device *dev = &vindev->mgbdev->pdev->dev; 225 + u32 config = mgb4_read_reg(video, vindev->config->regs.config); 226 + u32 pixelsize = (config & (1U << 16)) ? 2 : 4; 231 227 unsigned int size = (vindev->timings.bt.width + vindev->padding) 232 - * vindev->timings.bt.height * 4; 228 + * vindev->timings.bt.height * pixelsize; 233 229 234 230 if (vb2_plane_size(vb, 0) < size) { 235 231 dev_err(dev, "buffer too small (%lu < %u)\n", ··· 322 312 if (!v4l2_fh_is_singular_file(file)) 323 313 goto out; 324 314 325 - get_timings(vindev, &vindev->timings); 315 + if (get_timings(vindev, &vindev->timings) < 0) 316 + vindev->timings = cea1080p60; 326 317 set_loopback_padding(vindev, vindev->padding); 327 318 328 319 out: ··· 370 359 static int vidioc_enum_fmt(struct file *file, void *priv, 371 360 struct v4l2_fmtdesc *f) 372 361 { 373 - if (f->index != 0) 362 + struct mgb4_vin_dev *vindev = video_drvdata(file); 363 + struct mgb4_regs *video = &vindev->mgbdev->video; 364 + 365 + if (f->index == 0) { 366 + f->pixelformat = V4L2_PIX_FMT_ABGR32; 367 + return 0; 368 + } else if (f->index == 1 && has_yuv(video)) { 369 + f->pixelformat = V4L2_PIX_FMT_YUYV; 370 + return 0; 371 + } else { 374 372 return -EINVAL; 375 - 376 - f->pixelformat = V4L2_PIX_FMT_ABGR32; 377 - 378 - return 0; 373 + } 379 374 } 380 375 381 376 static int vidioc_enum_frameintervals(struct file *file, void *priv, 382 377 struct v4l2_frmivalenum *ival) 383 378 { 384 379 struct mgb4_vin_dev *vindev = video_drvdata(file); 380 + struct mgb4_regs *video = &vindev->mgbdev->video; 385 381 386 382 if (ival->index != 0) 387 383 return -EINVAL; 388 - if (ival->pixel_format != V4L2_PIX_FMT_ABGR32) 384 + if (!(ival->pixel_format == V4L2_PIX_FMT_ABGR32 || 385 + ((has_yuv(video) && ival->pixel_format == V4L2_PIX_FMT_YUYV)))) 389 386 return -EINVAL; 390 387 if (ival->width != vindev->timings.bt.width || 391 388 ival->height != vindev->timings.bt.height) 392 389 return -EINVAL; 393 390 394 - ival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; 395 - ival->stepwise.min.denominator = 60; 396 - ival->stepwise.min.numerator = 1; 397 - ival->stepwise.max.denominator = 1; 398 - ival->stepwise.max.numerator = 1; 399 - ival->stepwise.step = ival->stepwise.max; 391 + ival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 392 + ival->stepwise.max.denominator = MGB4_HW_FREQ; 393 + ival->stepwise.max.numerator = 0xFFFFFFFF; 394 + ival->stepwise.min.denominator = vindev->timings.bt.pixelclock; 395 + ival->stepwise.min.numerator = pixel_size(&vindev->timings); 396 + ival->stepwise.step.denominator = MGB4_HW_FREQ; 397 + ival->stepwise.step.numerator = 1; 400 398 401 399 return 0; 402 400 } ··· 413 393 static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 414 394 { 415 395 struct mgb4_vin_dev *vindev = video_drvdata(file); 396 + struct mgb4_regs *video = &vindev->mgbdev->video; 397 + u32 config = mgb4_read_reg(video, vindev->config->regs.config); 416 398 417 - f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 418 399 f->fmt.pix.width = vindev->timings.bt.width; 419 400 f->fmt.pix.height = vindev->timings.bt.height; 420 401 f->fmt.pix.field = V4L2_FIELD_NONE; 421 - f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 422 - f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 4; 402 + 403 + if (config & (1U << 16)) { 404 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 405 + if (config & (1U << 20)) { 406 + f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; 407 + } else { 408 + if (config & (1U << 19)) 409 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 410 + else 411 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 412 + } 413 + f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 2; 414 + } else { 415 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 416 + f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 417 + f->fmt.pix.bytesperline = (f->fmt.pix.width + vindev->padding) * 4; 418 + } 423 419 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 424 420 425 421 return 0; ··· 444 408 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 445 409 { 446 410 struct mgb4_vin_dev *vindev = video_drvdata(file); 411 + struct mgb4_regs *video = &vindev->mgbdev->video; 412 + u32 pixelsize; 447 413 448 - f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 449 414 f->fmt.pix.width = vindev->timings.bt.width; 450 415 f->fmt.pix.height = vindev->timings.bt.height; 451 416 f->fmt.pix.field = V4L2_FIELD_NONE; 452 - f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 453 - f->fmt.pix.bytesperline = max(f->fmt.pix.width * 4, 454 - ALIGN_DOWN(f->fmt.pix.bytesperline, 4)); 417 + 418 + if (has_yuv(video) && f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { 419 + pixelsize = 2; 420 + if (!(f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709 || 421 + f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M)) 422 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 423 + } else { 424 + pixelsize = 4; 425 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 426 + f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 427 + } 428 + 429 + if (f->fmt.pix.bytesperline > f->fmt.pix.width * pixelsize && 430 + f->fmt.pix.bytesperline < f->fmt.pix.width * pixelsize * 2) 431 + f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, 432 + pixelsize); 433 + else 434 + f->fmt.pix.bytesperline = f->fmt.pix.width * pixelsize; 455 435 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 456 436 457 437 return 0; ··· 477 425 { 478 426 struct mgb4_vin_dev *vindev = video_drvdata(file); 479 427 struct mgb4_regs *video = &vindev->mgbdev->video; 428 + u32 config, pixelsize; 480 429 481 430 if (vb2_is_busy(&vindev->queue)) 482 431 return -EBUSY; 483 432 484 433 vidioc_try_fmt(file, priv, f); 485 434 486 - vindev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width * 4)) / 4; 435 + config = mgb4_read_reg(video, vindev->config->regs.config); 436 + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { 437 + pixelsize = 2; 438 + config |= 1U << 16; 439 + 440 + if (f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709) { 441 + config |= 1U << 20; 442 + config |= 1U << 19; 443 + } else if (f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M) { 444 + config &= ~(1U << 20); 445 + config |= 1U << 19; 446 + } else { 447 + config &= ~(1U << 20); 448 + config &= ~(1U << 19); 449 + } 450 + } else { 451 + pixelsize = 4; 452 + config &= ~(1U << 16); 453 + } 454 + mgb4_write_reg(video, vindev->config->regs.config, config); 455 + 456 + vindev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width 457 + * pixelsize)) / pixelsize; 487 458 mgb4_write_reg(video, vindev->config->regs.padding, vindev->padding); 488 459 set_loopback_padding(vindev, vindev->padding); 489 460 ··· 542 467 { 543 468 struct mgb4_vin_dev *vindev = video_drvdata(file); 544 469 545 - if (fsize->index != 0 || fsize->pixel_format != V4L2_PIX_FMT_ABGR32) 470 + if (fsize->index != 0 || !(fsize->pixel_format == V4L2_PIX_FMT_ABGR32 || 471 + fsize->pixel_format == V4L2_PIX_FMT_YUYV)) 546 472 return -EINVAL; 547 473 548 474 fsize->discrete.width = vindev->timings.bt.width; ··· 564 488 return 0; 565 489 } 566 490 567 - static int vidioc_parm(struct file *file, void *priv, 568 - struct v4l2_streamparm *parm) 491 + static int vidioc_g_parm(struct file *file, void *priv, 492 + struct v4l2_streamparm *parm) 569 493 { 570 494 struct mgb4_vin_dev *vindev = video_drvdata(file); 571 495 struct mgb4_regs *video = &vindev->mgbdev->video; 572 - const struct mgb4_vin_regs *regs = &vindev->config->regs; 573 - struct v4l2_fract timeperframe = { 574 - .numerator = mgb4_read_reg(video, regs->frame_period), 575 - .denominator = 125000000, 576 - }; 577 - 578 - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 579 - return -EINVAL; 496 + struct v4l2_fract *tpf = &parm->parm.output.timeperframe; 497 + u32 timer; 580 498 581 499 parm->parm.capture.readbuffers = 2; 582 - parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 583 - parm->parm.capture.timeperframe = timeperframe; 500 + 501 + if (has_timeperframe(video)) { 502 + timer = mgb4_read_reg(video, vindev->config->regs.timer); 503 + if (timer < 0xFFFF) { 504 + tpf->numerator = pixel_size(&vindev->timings); 505 + tpf->denominator = vindev->timings.bt.pixelclock; 506 + } else { 507 + tpf->numerator = timer; 508 + tpf->denominator = MGB4_HW_FREQ; 509 + } 510 + 511 + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 512 + } 584 513 585 514 return 0; 515 + } 516 + 517 + static int vidioc_s_parm(struct file *file, void *priv, 518 + struct v4l2_streamparm *parm) 519 + { 520 + struct mgb4_vin_dev *vindev = video_drvdata(file); 521 + struct mgb4_regs *video = &vindev->mgbdev->video; 522 + struct v4l2_fract *tpf = &parm->parm.output.timeperframe; 523 + u32 period, timer; 524 + 525 + if (has_timeperframe(video)) { 526 + timer = tpf->denominator ? 527 + MGB4_PERIOD(tpf->numerator, tpf->denominator) : 0; 528 + if (timer) { 529 + period = MGB4_PERIOD(pixel_size(&vindev->timings), 530 + vindev->timings.bt.pixelclock); 531 + if (timer < period) 532 + timer = 0; 533 + } 534 + 535 + mgb4_write_reg(video, vindev->config->regs.timer, timer); 536 + } 537 + 538 + return vidioc_g_parm(file, priv, parm); 586 539 } 587 540 588 541 static int vidioc_s_dv_timings(struct file *file, void *fh, ··· 697 592 .vidioc_expbuf = vb2_ioctl_expbuf, 698 593 .vidioc_streamon = vb2_ioctl_streamon, 699 594 .vidioc_streamoff = vb2_ioctl_streamoff, 700 - .vidioc_g_parm = vidioc_parm, 701 - .vidioc_s_parm = vidioc_parm, 595 + .vidioc_g_parm = vidioc_g_parm, 596 + .vidioc_s_parm = vidioc_s_parm, 702 597 .vidioc_dv_timings_cap = vidioc_dv_timings_cap, 703 598 .vidioc_enum_dv_timings = vidioc_enum_dv_timings, 704 599 .vidioc_g_dv_timings = vidioc_g_dv_timings, ··· 881 776 vindev->regs[7].offset = vindev->config->regs.signal2; 882 777 vindev->regs[8].name = "PADDING_PIXELS"; 883 778 vindev->regs[8].offset = vindev->config->regs.padding; 779 + if (has_timeperframe(video)) { 780 + vindev->regs[9].name = "TIMER"; 781 + vindev->regs[9].offset = vindev->config->regs.timer; 782 + vindev->regset.nregs = 10; 783 + } else { 784 + vindev->regset.nregs = 9; 785 + } 884 786 885 787 vindev->regset.base = video->membase; 886 788 vindev->regset.regs = vindev->regs; 887 - vindev->regset.nregs = ARRAY_SIZE(vindev->regs); 888 789 889 790 debugfs_create_regset32("registers", 0444, vindev->debugfs, 890 791 &vindev->regset);
+2 -1
drivers/media/pci/mgb4/mgb4_vin.h
··· 25 25 u32 signal; 26 26 u32 signal2; 27 27 u32 padding; 28 + u32 timer; 28 29 }; 29 30 30 31 struct mgb4_vin_config { ··· 60 59 #ifdef CONFIG_DEBUG_FS 61 60 struct dentry *debugfs; 62 61 struct debugfs_regset32 regset; 63 - struct debugfs_reg32 regs[9]; 62 + struct debugfs_reg32 regs[sizeof(struct mgb4_vin_regs) / 4]; 64 63 #endif 65 64 }; 66 65
+278 -31
drivers/media/pci/mgb4/mgb4_vout.c
··· 16 16 #include <media/v4l2-ioctl.h> 17 17 #include <media/videobuf2-v4l2.h> 18 18 #include <media/videobuf2-dma-sg.h> 19 + #include <media/v4l2-dv-timings.h> 19 20 #include "mgb4_core.h" 20 21 #include "mgb4_dma.h" 21 22 #include "mgb4_sysfs.h" ··· 24 23 #include "mgb4_cmt.h" 25 24 #include "mgb4_vout.h" 26 25 26 + #define DEFAULT_WIDTH 1280 27 + #define DEFAULT_HEIGHT 640 28 + #define DEFAULT_PERIOD (MGB4_HW_FREQ / 60) 29 + 27 30 ATTRIBUTE_GROUPS(mgb4_fpdl3_out); 28 31 ATTRIBUTE_GROUPS(mgb4_gmsl_out); 29 32 30 33 static const struct mgb4_vout_config vout_cfg[] = { 31 - {0, 0, 8, {0x78, 0x60, 0x64, 0x68, 0x74, 0x6C, 0x70, 0x7c}}, 32 - {1, 1, 9, {0x98, 0x80, 0x84, 0x88, 0x94, 0x8c, 0x90, 0x9c}} 34 + {0, 0, 8, {0x78, 0x60, 0x64, 0x68, 0x74, 0x6C, 0x70, 0x7C, 0xE0}}, 35 + {1, 1, 9, {0x98, 0x80, 0x84, 0x88, 0x94, 0x8C, 0x90, 0x9C, 0xE4}} 33 36 }; 34 37 35 38 static const struct i2c_board_info fpdl3_ser_info[] = { ··· 44 39 static const struct mgb4_i2c_kv fpdl3_i2c[] = { 45 40 {0x05, 0xFF, 0x04}, {0x06, 0xFF, 0x01}, {0xC2, 0xFF, 0x80} 46 41 }; 42 + 43 + static const struct v4l2_dv_timings_cap video_timings_cap = { 44 + .type = V4L2_DV_BT_656_1120, 45 + .bt = { 46 + .min_width = 320, 47 + .max_width = 4096, 48 + .min_height = 240, 49 + .max_height = 2160, 50 + .min_pixelclock = 1843200, /* 320 x 240 x 24Hz */ 51 + .max_pixelclock = 530841600, /* 4096 x 2160 x 60Hz */ 52 + .standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | 53 + V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF, 54 + .capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | 55 + V4L2_DV_BT_CAP_CUSTOM, 56 + }, 57 + }; 58 + 59 + static void get_timings(struct mgb4_vout_dev *voutdev, 60 + struct v4l2_dv_timings *timings) 61 + { 62 + struct mgb4_regs *video = &voutdev->mgbdev->video; 63 + const struct mgb4_vout_regs *regs = &voutdev->config->regs; 64 + 65 + u32 hsync = mgb4_read_reg(video, regs->hsync); 66 + u32 vsync = mgb4_read_reg(video, regs->vsync); 67 + u32 resolution = mgb4_read_reg(video, regs->resolution); 68 + 69 + memset(timings, 0, sizeof(*timings)); 70 + timings->type = V4L2_DV_BT_656_1120; 71 + timings->bt.width = resolution >> 16; 72 + timings->bt.height = resolution & 0xFFFF; 73 + if (hsync & (1U << 31)) 74 + timings->bt.polarities |= V4L2_DV_HSYNC_POS_POL; 75 + if (vsync & (1U << 31)) 76 + timings->bt.polarities |= V4L2_DV_VSYNC_POS_POL; 77 + timings->bt.pixelclock = voutdev->freq * 1000; 78 + timings->bt.hsync = (hsync & 0x00FF0000) >> 16; 79 + timings->bt.vsync = (vsync & 0x00FF0000) >> 16; 80 + timings->bt.hbackporch = (hsync & 0x0000FF00) >> 8; 81 + timings->bt.hfrontporch = hsync & 0x000000FF; 82 + timings->bt.vbackporch = (vsync & 0x0000FF00) >> 8; 83 + timings->bt.vfrontporch = vsync & 0x000000FF; 84 + } 47 85 48 86 static void return_all_buffers(struct mgb4_vout_dev *voutdev, 49 87 enum vb2_buffer_state state) ··· 107 59 struct device *alloc_devs[]) 108 60 { 109 61 struct mgb4_vout_dev *voutdev = vb2_get_drv_priv(q); 110 - unsigned int size; 62 + struct mgb4_regs *video = &voutdev->mgbdev->video; 63 + u32 config = mgb4_read_reg(video, voutdev->config->regs.config); 64 + u32 pixelsize = (config & (1U << 16)) ? 2 : 4; 65 + unsigned int size = (voutdev->width + voutdev->padding) * voutdev->height 66 + * pixelsize; 111 67 112 68 /* 113 69 * If I/O reconfiguration is in process, do not allow to start ··· 120 68 */ 121 69 if (test_bit(0, &voutdev->mgbdev->io_reconfig)) 122 70 return -EBUSY; 123 - 124 - size = (voutdev->width + voutdev->padding) * voutdev->height * 4; 125 71 126 72 if (*nplanes) 127 73 return sizes[0] < size ? -EINVAL : 0; ··· 143 93 { 144 94 struct mgb4_vout_dev *voutdev = vb2_get_drv_priv(vb->vb2_queue); 145 95 struct device *dev = &voutdev->mgbdev->pdev->dev; 146 - unsigned int size; 147 - 148 - size = (voutdev->width + voutdev->padding) * voutdev->height * 4; 96 + struct mgb4_regs *video = &voutdev->mgbdev->video; 97 + u32 config = mgb4_read_reg(video, voutdev->config->regs.config); 98 + u32 pixelsize = (config & (1U << 16)) ? 2 : 4; 99 + unsigned int size = (voutdev->width + voutdev->padding) * voutdev->height 100 + * pixelsize; 149 101 150 102 if (vb2_plane_size(vb, 0) < size) { 151 103 dev_err(dev, "buffer too small (%lu < %u)\n", ··· 246 194 static int vidioc_enum_fmt(struct file *file, void *priv, 247 195 struct v4l2_fmtdesc *f) 248 196 { 249 - if (f->index != 0) 197 + struct mgb4_vin_dev *voutdev = video_drvdata(file); 198 + struct mgb4_regs *video = &voutdev->mgbdev->video; 199 + 200 + if (f->index == 0) { 201 + f->pixelformat = V4L2_PIX_FMT_ABGR32; 202 + return 0; 203 + } else if (f->index == 1 && has_yuv(video)) { 204 + f->pixelformat = V4L2_PIX_FMT_YUYV; 205 + return 0; 206 + } else { 250 207 return -EINVAL; 251 - 252 - f->pixelformat = V4L2_PIX_FMT_ABGR32; 253 - 254 - return 0; 208 + } 255 209 } 256 210 257 211 static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 258 212 { 259 213 struct mgb4_vout_dev *voutdev = video_drvdata(file); 214 + struct mgb4_regs *video = &voutdev->mgbdev->video; 215 + u32 config = mgb4_read_reg(video, voutdev->config->regs.config); 260 216 261 - f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 262 217 f->fmt.pix.width = voutdev->width; 263 218 f->fmt.pix.height = voutdev->height; 264 219 f->fmt.pix.field = V4L2_FIELD_NONE; 265 - f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 266 - f->fmt.pix.bytesperline = (f->fmt.pix.width + voutdev->padding) * 4; 220 + 221 + if (config & (1U << 16)) { 222 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 223 + if (config & (1U << 20)) { 224 + f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; 225 + } else { 226 + if (config & (1U << 19)) 227 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 228 + else 229 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 230 + } 231 + f->fmt.pix.bytesperline = (f->fmt.pix.width + voutdev->padding) * 2; 232 + } else { 233 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 234 + f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 235 + f->fmt.pix.bytesperline = (f->fmt.pix.width + voutdev->padding) * 4; 236 + } 237 + 267 238 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 268 239 269 240 return 0; ··· 295 220 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 296 221 { 297 222 struct mgb4_vout_dev *voutdev = video_drvdata(file); 223 + struct mgb4_regs *video = &voutdev->mgbdev->video; 224 + u32 pixelsize; 298 225 299 - f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 300 226 f->fmt.pix.width = voutdev->width; 301 227 f->fmt.pix.height = voutdev->height; 302 228 f->fmt.pix.field = V4L2_FIELD_NONE; 303 - f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 304 - f->fmt.pix.bytesperline = max(f->fmt.pix.width * 4, 305 - ALIGN_DOWN(f->fmt.pix.bytesperline, 4)); 229 + 230 + if (has_yuv(video) && f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { 231 + pixelsize = 2; 232 + if (!(f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709 || 233 + f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M)) 234 + f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 235 + } else { 236 + pixelsize = 4; 237 + f->fmt.pix.pixelformat = V4L2_PIX_FMT_ABGR32; 238 + f->fmt.pix.colorspace = V4L2_COLORSPACE_RAW; 239 + } 240 + 241 + if (f->fmt.pix.bytesperline > f->fmt.pix.width * pixelsize && 242 + f->fmt.pix.bytesperline < f->fmt.pix.width * pixelsize * 2) 243 + f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline, 244 + pixelsize); 245 + else 246 + f->fmt.pix.bytesperline = f->fmt.pix.width * pixelsize; 306 247 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; 307 248 308 249 return 0; ··· 328 237 { 329 238 struct mgb4_vout_dev *voutdev = video_drvdata(file); 330 239 struct mgb4_regs *video = &voutdev->mgbdev->video; 240 + u32 config, pixelsize; 241 + int ret; 331 242 332 243 if (vb2_is_busy(&voutdev->queue)) 333 244 return -EBUSY; 334 245 335 - vidioc_try_fmt(file, priv, f); 246 + ret = vidioc_try_fmt(file, priv, f); 247 + if (ret < 0) 248 + return ret; 336 249 337 - voutdev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width * 4)) / 4; 250 + config = mgb4_read_reg(video, voutdev->config->regs.config); 251 + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { 252 + pixelsize = 2; 253 + config |= 1U << 16; 254 + 255 + if (f->fmt.pix.colorspace == V4L2_COLORSPACE_REC709) { 256 + config |= 1U << 20; 257 + config |= 1U << 19; 258 + } else if (f->fmt.pix.colorspace == V4L2_COLORSPACE_SMPTE170M) { 259 + config &= ~(1U << 20); 260 + config |= 1U << 19; 261 + } else { 262 + config &= ~(1U << 20); 263 + config &= ~(1U << 19); 264 + } 265 + } else { 266 + pixelsize = 4; 267 + config &= ~(1U << 16); 268 + } 269 + mgb4_write_reg(video, voutdev->config->regs.config, config); 270 + 271 + voutdev->padding = (f->fmt.pix.bytesperline - (f->fmt.pix.width 272 + * pixelsize)) / pixelsize; 338 273 mgb4_write_reg(video, voutdev->config->regs.padding, voutdev->padding); 339 274 340 275 return 0; ··· 384 267 return -EINVAL; 385 268 386 269 out->type = V4L2_OUTPUT_TYPE_ANALOG; 270 + out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; 387 271 strscpy(out->name, "MGB4", sizeof(out->name)); 272 + 273 + return 0; 274 + } 275 + 276 + static int vidioc_enum_frameintervals(struct file *file, void *priv, 277 + struct v4l2_frmivalenum *ival) 278 + { 279 + struct mgb4_vout_dev *voutdev = video_drvdata(file); 280 + struct mgb4_regs *video = &voutdev->mgbdev->video; 281 + struct v4l2_dv_timings timings; 282 + 283 + if (ival->index != 0) 284 + return -EINVAL; 285 + if (!(ival->pixel_format == V4L2_PIX_FMT_ABGR32 || 286 + ((has_yuv(video) && ival->pixel_format == V4L2_PIX_FMT_YUYV)))) 287 + return -EINVAL; 288 + if (ival->width != voutdev->width || ival->height != voutdev->height) 289 + return -EINVAL; 290 + 291 + get_timings(voutdev, &timings); 292 + 293 + ival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 294 + ival->stepwise.max.denominator = MGB4_HW_FREQ; 295 + ival->stepwise.max.numerator = 0xFFFFFFFF; 296 + ival->stepwise.min.denominator = timings.bt.pixelclock; 297 + ival->stepwise.min.numerator = pixel_size(&timings); 298 + ival->stepwise.step.denominator = MGB4_HW_FREQ; 299 + ival->stepwise.step.numerator = 1; 300 + 301 + return 0; 302 + } 303 + 304 + static int vidioc_g_parm(struct file *file, void *priv, 305 + struct v4l2_streamparm *parm) 306 + { 307 + struct mgb4_vout_dev *voutdev = video_drvdata(file); 308 + struct mgb4_regs *video = &voutdev->mgbdev->video; 309 + struct v4l2_fract *tpf = &parm->parm.output.timeperframe; 310 + struct v4l2_dv_timings timings; 311 + u32 timer; 312 + 313 + parm->parm.output.writebuffers = 2; 314 + 315 + if (has_timeperframe(video)) { 316 + timer = mgb4_read_reg(video, voutdev->config->regs.timer); 317 + if (timer < 0xFFFF) { 318 + get_timings(voutdev, &timings); 319 + tpf->numerator = pixel_size(&timings); 320 + tpf->denominator = timings.bt.pixelclock; 321 + } else { 322 + tpf->numerator = timer; 323 + tpf->denominator = MGB4_HW_FREQ; 324 + } 325 + 326 + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 327 + } 328 + 329 + return 0; 330 + } 331 + 332 + static int vidioc_s_parm(struct file *file, void *priv, 333 + struct v4l2_streamparm *parm) 334 + { 335 + struct mgb4_vout_dev *voutdev = video_drvdata(file); 336 + struct mgb4_regs *video = &voutdev->mgbdev->video; 337 + struct v4l2_fract *tpf = &parm->parm.output.timeperframe; 338 + struct v4l2_dv_timings timings; 339 + u32 timer, period; 340 + 341 + if (has_timeperframe(video)) { 342 + timer = tpf->denominator ? 343 + MGB4_PERIOD(tpf->numerator, tpf->denominator) : 0; 344 + if (timer) { 345 + get_timings(voutdev, &timings); 346 + period = MGB4_PERIOD(pixel_size(&timings), 347 + timings.bt.pixelclock); 348 + if (timer < period) 349 + timer = 0; 350 + } 351 + 352 + mgb4_write_reg(video, voutdev->config->regs.timer, timer); 353 + } 354 + 355 + return vidioc_g_parm(file, priv, parm); 356 + } 357 + 358 + static int vidioc_g_dv_timings(struct file *file, void *fh, 359 + struct v4l2_dv_timings *timings) 360 + { 361 + struct mgb4_vout_dev *voutdev = video_drvdata(file); 362 + 363 + get_timings(voutdev, timings); 364 + 365 + return 0; 366 + } 367 + 368 + static int vidioc_s_dv_timings(struct file *file, void *fh, 369 + struct v4l2_dv_timings *timings) 370 + { 371 + struct mgb4_vout_dev *voutdev = video_drvdata(file); 372 + 373 + get_timings(voutdev, timings); 374 + 375 + return 0; 376 + } 377 + 378 + static int vidioc_enum_dv_timings(struct file *file, void *fh, 379 + struct v4l2_enum_dv_timings *timings) 380 + { 381 + return v4l2_enum_dv_timings_cap(timings, &video_timings_cap, NULL, NULL); 382 + } 383 + 384 + static int vidioc_dv_timings_cap(struct file *file, void *fh, 385 + struct v4l2_dv_timings_cap *cap) 386 + { 387 + *cap = video_timings_cap; 388 388 389 389 return 0; 390 390 } ··· 513 279 .vidioc_s_fmt_vid_out = vidioc_s_fmt, 514 280 .vidioc_g_fmt_vid_out = vidioc_g_fmt, 515 281 .vidioc_enum_output = vidioc_enum_output, 282 + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, 516 283 .vidioc_g_output = vidioc_g_output, 517 284 .vidioc_s_output = vidioc_s_output, 285 + .vidioc_g_parm = vidioc_g_parm, 286 + .vidioc_s_parm = vidioc_s_parm, 287 + .vidioc_dv_timings_cap = vidioc_dv_timings_cap, 288 + .vidioc_enum_dv_timings = vidioc_enum_dv_timings, 289 + .vidioc_g_dv_timings = vidioc_g_dv_timings, 290 + .vidioc_s_dv_timings = vidioc_s_dv_timings, 518 291 .vidioc_reqbufs = vb2_ioctl_reqbufs, 519 292 .vidioc_create_bufs = vb2_ioctl_create_bufs, 520 293 .vidioc_prepare_buf = vb2_ioctl_prepare_buf, ··· 664 423 665 424 mgb4_write_reg(video, regs->config, 0x00000011); 666 425 mgb4_write_reg(video, regs->resolution, 667 - (MGB4_DEFAULT_WIDTH << 16) | MGB4_DEFAULT_HEIGHT); 668 - mgb4_write_reg(video, regs->hsync, 0x00102020); 669 - mgb4_write_reg(video, regs->vsync, 0x40020202); 670 - mgb4_write_reg(video, regs->frame_period, MGB4_DEFAULT_PERIOD); 426 + (DEFAULT_WIDTH << 16) | DEFAULT_HEIGHT); 427 + mgb4_write_reg(video, regs->hsync, 0x00283232); 428 + mgb4_write_reg(video, regs->vsync, 0x40141F1E); 429 + mgb4_write_reg(video, regs->frame_limit, DEFAULT_PERIOD); 671 430 mgb4_write_reg(video, regs->padding, 0x00000000); 672 431 673 - voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, 70000 >> 1) << 1; 432 + voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, 61150 >> 1) << 1; 674 433 675 434 mgb4_write_reg(video, regs->config, 676 435 (voutdev->config->id + MGB4_VIN_DEVICES) << 2 | 1 << 4); ··· 696 455 voutdev->regs[3].offset = voutdev->config->regs.hsync; 697 456 voutdev->regs[4].name = "VIDEO_PARAMS_2"; 698 457 voutdev->regs[4].offset = voutdev->config->regs.vsync; 699 - voutdev->regs[5].name = "FRAME_PERIOD"; 700 - voutdev->regs[5].offset = voutdev->config->regs.frame_period; 701 - voutdev->regs[6].name = "PADDING"; 458 + voutdev->regs[5].name = "FRAME_LIMIT"; 459 + voutdev->regs[5].offset = voutdev->config->regs.frame_limit; 460 + voutdev->regs[6].name = "PADDING_PIXELS"; 702 461 voutdev->regs[6].offset = voutdev->config->regs.padding; 462 + if (has_timeperframe(video)) { 463 + voutdev->regs[7].name = "TIMER"; 464 + voutdev->regs[7].offset = voutdev->config->regs.timer; 465 + voutdev->regset.nregs = 8; 466 + } else { 467 + voutdev->regset.nregs = 7; 468 + } 703 469 704 470 voutdev->regset.base = video->membase; 705 471 voutdev->regset.regs = voutdev->regs; 706 - voutdev->regset.nregs = ARRAY_SIZE(voutdev->regs); 707 472 708 473 debugfs_create_regset32("registers", 0444, voutdev->debugfs, 709 474 &voutdev->regset);
+3 -2
drivers/media/pci/mgb4/mgb4_vout.h
··· 19 19 u32 config; 20 20 u32 status; 21 21 u32 resolution; 22 - u32 frame_period; 22 + u32 frame_limit; 23 23 u32 hsync; 24 24 u32 vsync; 25 25 u32 padding; 26 + u32 timer; 26 27 }; 27 28 28 29 struct mgb4_vout_config { ··· 56 55 #ifdef CONFIG_DEBUG_FS 57 56 struct dentry *debugfs; 58 57 struct debugfs_regset32 regset; 59 - struct debugfs_reg32 regs[7]; 58 + struct debugfs_reg32 regs[sizeof(struct mgb4_vout_regs) / 4]; 60 59 #endif 61 60 }; 62 61
+4 -4
drivers/media/pci/solo6x10/solo6x10-p2m.c
··· 57 57 int desc_cnt) 58 58 { 59 59 struct solo_p2m_dev *p2m_dev; 60 - unsigned int timeout; 60 + unsigned long time_left; 61 61 unsigned int config = 0; 62 62 int ret = 0; 63 63 unsigned int p2m_id = 0; ··· 99 99 desc[1].ctrl); 100 100 } 101 101 102 - timeout = wait_for_completion_timeout(&p2m_dev->completion, 103 - solo_dev->p2m_jiffies); 102 + time_left = wait_for_completion_timeout(&p2m_dev->completion, 103 + solo_dev->p2m_jiffies); 104 104 105 105 if (WARN_ON_ONCE(p2m_dev->error)) 106 106 ret = -EIO; 107 - else if (timeout == 0) { 107 + else if (time_left == 0) { 108 108 solo_dev->p2m_timeouts++; 109 109 ret = -EAGAIN; 110 110 }
+14 -14
drivers/media/platform/allegro-dvt/allegro-core.c
··· 179 179 struct list_head channels; 180 180 }; 181 181 182 - static struct regmap_config allegro_regmap_config = { 182 + static const struct regmap_config allegro_regmap_config = { 183 183 .name = "regmap", 184 184 .reg_bits = 32, 185 185 .val_bits = 32, ··· 188 188 .cache_type = REGCACHE_NONE, 189 189 }; 190 190 191 - static struct regmap_config allegro_sram_config = { 191 + static const struct regmap_config allegro_sram_config = { 192 192 .name = "sram", 193 193 .reg_bits = 32, 194 194 .val_bits = 32, ··· 1415 1415 static int allegro_mcu_wait_for_init_timeout(struct allegro_dev *dev, 1416 1416 unsigned long timeout_ms) 1417 1417 { 1418 - unsigned long tmo; 1418 + unsigned long time_left; 1419 1419 1420 - tmo = wait_for_completion_timeout(&dev->init_complete, 1421 - msecs_to_jiffies(timeout_ms)); 1422 - if (tmo == 0) 1420 + time_left = wait_for_completion_timeout(&dev->init_complete, 1421 + msecs_to_jiffies(timeout_ms)); 1422 + if (time_left == 0) 1423 1423 return -ETIMEDOUT; 1424 1424 1425 1425 reinit_completion(&dev->init_complete); ··· 2481 2481 static void allegro_destroy_channel(struct allegro_channel *channel) 2482 2482 { 2483 2483 struct allegro_dev *dev = channel->dev; 2484 - unsigned long timeout; 2484 + unsigned long time_left; 2485 2485 2486 2486 if (channel_exists(channel)) { 2487 2487 reinit_completion(&channel->completion); 2488 2488 allegro_mcu_send_destroy_channel(dev, channel); 2489 - timeout = wait_for_completion_timeout(&channel->completion, 2490 - msecs_to_jiffies(5000)); 2491 - if (timeout == 0) 2489 + time_left = wait_for_completion_timeout(&channel->completion, 2490 + msecs_to_jiffies(5000)); 2491 + if (time_left == 0) 2492 2492 v4l2_warn(&dev->v4l2_dev, 2493 2493 "channel %d: timeout while destroying\n", 2494 2494 channel->mcu_channel_id); ··· 2544 2544 static int allegro_create_channel(struct allegro_channel *channel) 2545 2545 { 2546 2546 struct allegro_dev *dev = channel->dev; 2547 - unsigned long timeout; 2547 + unsigned long time_left; 2548 2548 2549 2549 if (channel_exists(channel)) { 2550 2550 v4l2_warn(&dev->v4l2_dev, ··· 2595 2595 2596 2596 reinit_completion(&channel->completion); 2597 2597 allegro_mcu_send_create_channel(dev, channel); 2598 - timeout = wait_for_completion_timeout(&channel->completion, 2599 - msecs_to_jiffies(5000)); 2600 - if (timeout == 0) 2598 + time_left = wait_for_completion_timeout(&channel->completion, 2599 + msecs_to_jiffies(5000)); 2600 + if (time_left == 0) 2601 2601 channel->error = -ETIMEDOUT; 2602 2602 if (channel->error) 2603 2603 goto err;
+4 -4
drivers/media/platform/atmel/atmel-isi.c
··· 242 242 #define WAIT_ISI_DISABLE 0 243 243 static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset) 244 244 { 245 - unsigned long timeout; 245 + unsigned long time_left; 246 246 /* 247 247 * The reset or disable will only succeed if we have a 248 248 * pixel clock from the camera. ··· 257 257 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 258 258 } 259 259 260 - timeout = wait_for_completion_timeout(&isi->complete, 261 - msecs_to_jiffies(500)); 262 - if (timeout == 0) 260 + time_left = wait_for_completion_timeout(&isi->complete, 261 + msecs_to_jiffies(500)); 262 + if (time_left == 0) 263 263 return -ETIMEDOUT; 264 264 265 265 return 0;
+1 -1
drivers/media/platform/chips-media/coda/coda-bit.c
··· 585 585 586 586 if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) { 587 587 /* worst case slice size */ 588 - size = (DIV_ROUND_UP(q_data->rect.width, 16) * 588 + size = (unsigned long)(DIV_ROUND_UP(q_data->rect.width, 16) * 589 589 DIV_ROUND_UP(q_data->rect.height, 16)) * 3200 / 8 + 512; 590 590 ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, 591 591 "slicebuf");
+1
drivers/media/platform/imagination/Kconfig
··· 2 2 config VIDEO_E5010_JPEG_ENC 3 3 tristate "Imagination E5010 JPEG Encoder Driver" 4 4 depends on VIDEO_DEV 5 + depends on ARCH_K3 || COMPILE_TEST 5 6 select VIDEOBUF2_DMA_CONTIG 6 7 select VIDEOBUF2_VMALLOC 7 8 select V4L2_MEM2MEM_DEV
+1 -1
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c
··· 595 595 } 596 596 } 597 597 598 - static struct vb2_ops mtk_vdec_frame_vb2_ops = { 598 + static const struct vb2_ops mtk_vdec_frame_vb2_ops = { 599 599 .queue_setup = vb2ops_vdec_queue_setup, 600 600 .buf_prepare = vb2ops_vdec_buf_prepare, 601 601 .wait_prepare = vb2_ops_wait_prepare,
+1 -1
drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
··· 854 854 return 0; 855 855 } 856 856 857 - static struct vb2_ops mtk_vdec_request_vb2_ops = { 857 + static const struct vb2_ops mtk_vdec_request_vb2_ops = { 858 858 .queue_setup = vb2ops_vdec_queue_setup, 859 859 .wait_prepare = vb2_ops_wait_prepare, 860 860 .wait_finish = vb2_ops_wait_finish,
+7 -2
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c
··· 347 347 return vpu_dec_reset(vpu); 348 348 349 349 fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); 350 + if (!fb) { 351 + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); 352 + return -ENOMEM; 353 + } 354 + 350 355 src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); 351 356 dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); 352 357 353 - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 354 - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 358 + y_fb_dma = fb->base_y.dma_addr; 359 + c_fb_dma = fb->base_c.dma_addr; 355 360 356 361 mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", 357 362 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+7 -2
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
··· 724 724 return vpu_dec_reset(vpu); 725 725 726 726 fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); 727 + if (!fb) { 728 + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); 729 + return -ENOMEM; 730 + } 731 + 727 732 src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); 728 733 dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); 729 734 730 - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 731 - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 735 + y_fb_dma = fb->base_y.dma_addr; 736 + c_fb_dma = fb->base_c.dma_addr; 732 737 mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx", 733 738 inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma); 734 739
+7 -3
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
··· 334 334 src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); 335 335 336 336 fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); 337 - dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); 337 + if (!fb) { 338 + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); 339 + return -ENOMEM; 340 + } 338 341 339 - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; 342 + dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); 343 + y_fb_dma = fb->base_y.dma_addr; 340 344 if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) 341 345 c_fb_dma = y_fb_dma + 342 346 inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h; 343 347 else 344 - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; 348 + c_fb_dma = fb->base_c.dma_addr; 345 349 346 350 inst->vsi->dec.bs_dma = (u64)bs->dma_addr; 347 351 inst->vsi->dec.bs_sz = bs->size;
+4 -15
drivers/media/platform/microchip/microchip-isc-base.c
··· 902 902 return 0; 903 903 } 904 904 905 - static int isc_validate(struct isc_device *isc) 905 + static int isc_link_validate(struct media_link *link) 906 906 { 907 + struct video_device *vdev = 908 + media_entity_to_video_device(link->sink->entity); 909 + struct isc_device *isc = video_get_drvdata(vdev); 907 910 int ret; 908 911 int i; 909 912 struct isc_format *sd_fmt = NULL; ··· 1908 1905 return 0; 1909 1906 } 1910 1907 EXPORT_SYMBOL_GPL(microchip_isc_pipeline_init); 1911 - 1912 - static int isc_link_validate(struct media_link *link) 1913 - { 1914 - struct video_device *vdev = 1915 - media_entity_to_video_device(link->sink->entity); 1916 - struct isc_device *isc = video_get_drvdata(vdev); 1917 - int ret; 1918 - 1919 - ret = v4l2_subdev_link_validate(link); 1920 - if (ret) 1921 - return ret; 1922 - 1923 - return isc_validate(isc); 1924 - } 1925 1908 1926 1909 static const struct media_entity_operations isc_entity_operations = { 1927 1910 .link_validate = isc_link_validate,
+8 -13
drivers/media/platform/microchip/microchip-sama5d2-isc.c
··· 353 353 static int isc_parse_dt(struct device *dev, struct isc_device *isc) 354 354 { 355 355 struct device_node *np = dev->of_node; 356 - struct device_node *epn = NULL; 356 + struct device_node *epn; 357 357 struct isc_subdev_entity *subdev_entity; 358 358 unsigned int flags; 359 - int ret; 360 359 361 360 INIT_LIST_HEAD(&isc->subdev_entities); 362 361 363 - while (1) { 362 + for_each_endpoint_of_node(np, epn) { 364 363 struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; 365 - 366 - epn = of_graph_get_next_endpoint(np, epn); 367 - if (!epn) 368 - return 0; 364 + int ret; 369 365 370 366 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), 371 367 &v4l2_epn); 372 368 if (ret) { 373 - ret = -EINVAL; 369 + of_node_put(epn); 374 370 dev_err(dev, "Could not parse the endpoint\n"); 375 - break; 371 + return -EINVAL; 376 372 } 377 373 378 374 subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity), 379 375 GFP_KERNEL); 380 376 if (!subdev_entity) { 381 - ret = -ENOMEM; 382 - break; 377 + of_node_put(epn); 378 + return -ENOMEM; 383 379 } 384 380 subdev_entity->epn = epn; 385 381 ··· 396 400 397 401 list_add_tail(&subdev_entity->list, &isc->subdev_entities); 398 402 } 399 - of_node_put(epn); 400 403 401 - return ret; 404 + return 0; 402 405 } 403 406 404 407 static int microchip_isc_probe(struct platform_device *pdev)
+8 -13
drivers/media/platform/microchip/microchip-sama7g5-isc.c
··· 336 336 static int xisc_parse_dt(struct device *dev, struct isc_device *isc) 337 337 { 338 338 struct device_node *np = dev->of_node; 339 - struct device_node *epn = NULL; 339 + struct device_node *epn; 340 340 struct isc_subdev_entity *subdev_entity; 341 341 unsigned int flags; 342 - int ret; 343 342 bool mipi_mode; 344 343 345 344 INIT_LIST_HEAD(&isc->subdev_entities); 346 345 347 346 mipi_mode = of_property_read_bool(np, "microchip,mipi-mode"); 348 347 349 - while (1) { 348 + for_each_endpoint_of_node(np, epn) { 350 349 struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; 351 - 352 - epn = of_graph_get_next_endpoint(np, epn); 353 - if (!epn) 354 - return 0; 350 + int ret; 355 351 356 352 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), 357 353 &v4l2_epn); 358 354 if (ret) { 359 - ret = -EINVAL; 355 + of_node_put(epn); 360 356 dev_err(dev, "Could not parse the endpoint\n"); 361 - break; 357 + return -EINVAL; 362 358 } 363 359 364 360 subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity), 365 361 GFP_KERNEL); 366 362 if (!subdev_entity) { 367 - ret = -ENOMEM; 368 - break; 363 + of_node_put(epn); 364 + return -ENOMEM; 369 365 } 370 366 subdev_entity->epn = epn; 371 367 ··· 385 389 386 390 list_add_tail(&subdev_entity->list, &isc->subdev_entities); 387 391 } 388 - of_node_put(epn); 389 392 390 - return ret; 393 + return 0; 391 394 } 392 395 393 396 static int microchip_xisc_probe(struct platform_device *pdev)
+5 -5
drivers/media/platform/nvidia/tegra-vde/h264.c
··· 623 623 unsigned int read_bytes, macroblocks_nb; 624 624 struct device *dev = vde->dev; 625 625 dma_addr_t bsev_ptr; 626 - long timeout; 626 + long time_left; 627 627 int ret; 628 628 629 - timeout = wait_for_completion_interruptible_timeout( 629 + time_left = wait_for_completion_interruptible_timeout( 630 630 &vde->decode_completion, msecs_to_jiffies(1000)); 631 - if (timeout < 0) { 632 - ret = timeout; 633 - } else if (timeout == 0) { 631 + if (time_left < 0) { 632 + ret = time_left; 633 + } else if (time_left == 0) { 634 634 bsev_ptr = tegra_vde_readl(vde, vde->bsev, 0x10); 635 635 macroblocks_nb = tegra_vde_readl(vde, vde->sxe, 0xC8) & 0x1FFF; 636 636 read_bytes = bsev_ptr ? bsev_ptr - vde->bitstream_data_addr : 0;
+11 -8
drivers/media/platform/nxp/imx-mipi-csis.c
··· 861 861 { 862 862 unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS 863 863 : MIPI_CSIS_NUM_EVENTS - 8; 864 + unsigned int counters[MIPI_CSIS_NUM_EVENTS]; 864 865 unsigned long flags; 865 866 unsigned int i; 866 867 867 868 spin_lock_irqsave(&csis->slock, flags); 869 + for (i = 0; i < num_events; ++i) 870 + counters[i] = csis->events[i].counter; 871 + spin_unlock_irqrestore(&csis->slock, flags); 868 872 869 873 for (i = 0; i < num_events; ++i) { 870 - if (csis->events[i].counter > 0 || csis->debug.enable) 874 + if (counters[i] > 0 || csis->debug.enable) 871 875 dev_info(csis->dev, "%s events: %d\n", 872 876 csis->events[i].name, 873 - csis->events[i].counter); 877 + counters[i]); 874 878 } 875 - spin_unlock_irqrestore(&csis->slock, flags); 876 879 } 877 880 878 881 static int mipi_csis_dump_regs(struct mipi_csis_device *csis) ··· 1347 1344 * Suspend/resume 1348 1345 */ 1349 1346 1350 - static int __maybe_unused mipi_csis_runtime_suspend(struct device *dev) 1347 + static int mipi_csis_runtime_suspend(struct device *dev) 1351 1348 { 1352 1349 struct v4l2_subdev *sd = dev_get_drvdata(dev); 1353 1350 struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); ··· 1362 1359 return 0; 1363 1360 } 1364 1361 1365 - static int __maybe_unused mipi_csis_runtime_resume(struct device *dev) 1362 + static int mipi_csis_runtime_resume(struct device *dev) 1366 1363 { 1367 1364 struct v4l2_subdev *sd = dev_get_drvdata(dev); 1368 1365 struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); ··· 1382 1379 } 1383 1380 1384 1381 static const struct dev_pm_ops mipi_csis_pm_ops = { 1385 - SET_RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, 1386 - NULL) 1382 + RUNTIME_PM_OPS(mipi_csis_runtime_suspend, mipi_csis_runtime_resume, 1383 + NULL) 1387 1384 }; 1388 1385 1389 1386 /* ----------------------------------------------------------------------------- ··· 1574 1571 .driver = { 1575 1572 .of_match_table = mipi_csis_of_match, 1576 1573 .name = CSIS_DRIVER_NAME, 1577 - .pm = &mipi_csis_pm_ops, 1574 + .pm = pm_ptr(&mipi_csis_pm_ops), 1578 1575 }, 1579 1576 }; 1580 1577
+7 -2
drivers/media/platform/nxp/imx-pxp.h
··· 594 594 (((v) << 18) & BM_PXP_CSC1_COEF0_C0) 595 595 #define BP_PXP_CSC1_COEF0_UV_OFFSET 9 596 596 #define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00 597 + 598 + /* 599 + * We use v * (1 << 9) instead of v << 9, to workaround a gcc5 bug. 600 + * The compiler cannot understand that the expression is constant. 601 + */ 597 602 #define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \ 598 - (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET) 603 + (((v) * (1 << 9)) & BM_PXP_CSC1_COEF0_UV_OFFSET) 599 604 #define BP_PXP_CSC1_COEF0_Y_OFFSET 0 600 605 #define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF 601 606 #define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \ 602 - (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET) 607 + ((v) & BM_PXP_CSC1_COEF0_Y_OFFSET) 603 608 604 609 #define HW_PXP_CSC1_COEF1 (0x000001b0) 605 610
+8 -9
drivers/media/platform/nxp/imx8mq-mipi-csi2.c
··· 693 693 return ret ? -EAGAIN : 0; 694 694 } 695 695 696 - static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev) 696 + static int imx8mq_mipi_csi_suspend(struct device *dev) 697 697 { 698 698 struct v4l2_subdev *sd = dev_get_drvdata(dev); 699 699 struct csi_state *state = mipi_sd_to_csi2_state(sd); ··· 705 705 return 0; 706 706 } 707 707 708 - static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev) 708 + static int imx8mq_mipi_csi_resume(struct device *dev) 709 709 { 710 710 struct v4l2_subdev *sd = dev_get_drvdata(dev); 711 711 struct csi_state *state = mipi_sd_to_csi2_state(sd); ··· 716 716 return imx8mq_mipi_csi_pm_resume(dev); 717 717 } 718 718 719 - static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev) 719 + static int imx8mq_mipi_csi_runtime_suspend(struct device *dev) 720 720 { 721 721 struct v4l2_subdev *sd = dev_get_drvdata(dev); 722 722 struct csi_state *state = mipi_sd_to_csi2_state(sd); ··· 731 731 return ret; 732 732 } 733 733 734 - static int __maybe_unused imx8mq_mipi_csi_runtime_resume(struct device *dev) 734 + static int imx8mq_mipi_csi_runtime_resume(struct device *dev) 735 735 { 736 736 struct v4l2_subdev *sd = dev_get_drvdata(dev); 737 737 struct csi_state *state = mipi_sd_to_csi2_state(sd); ··· 747 747 } 748 748 749 749 static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = { 750 - SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend, 751 - imx8mq_mipi_csi_runtime_resume, 752 - NULL) 753 - SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume) 750 + RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend, 751 + imx8mq_mipi_csi_runtime_resume, NULL) 752 + SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume) 754 753 }; 755 754 756 755 /* ----------------------------------------------------------------------------- ··· 957 958 .driver = { 958 959 .of_match_table = imx8mq_mipi_csi_of_match, 959 960 .name = MIPI_CSI2_DRIVER_NAME, 960 - .pm = &imx8mq_mipi_csi_pm_ops, 961 + .pm = pm_ptr(&imx8mq_mipi_csi_pm_ops), 961 962 }, 962 963 }; 963 964
-6
drivers/media/platform/qcom/camss/camss-video.c
··· 297 297 298 298 ret = v4l2_subdev_call(subdev, video, s_stream, 0); 299 299 300 - if (entity->use_count > 1) { 301 - /* Don't stop if other instances of the pipeline are still running */ 302 - dev_dbg(video->camss->dev, "Video pipeline still used, don't stop streaming.\n"); 303 - return; 304 - } 305 - 306 300 if (ret) { 307 301 dev_err(video->camss->dev, "Video pipeline stop failed: %d\n", ret); 308 302 return;
+3 -2
drivers/media/platform/qcom/camss/camss.c
··· 2283 2283 2284 2284 v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev); 2285 2285 2286 + pm_runtime_enable(dev); 2287 + 2286 2288 num_subdevs = camss_of_parse_ports(camss); 2287 2289 if (num_subdevs < 0) { 2288 2290 ret = num_subdevs; ··· 2325 2323 } 2326 2324 } 2327 2325 2328 - pm_runtime_enable(dev); 2329 - 2330 2326 return 0; 2331 2327 2332 2328 err_register_subdevs: ··· 2332 2332 err_v4l2_device_unregister: 2333 2333 v4l2_device_unregister(&camss->v4l2_dev); 2334 2334 v4l2_async_nf_cleanup(&camss->notifier); 2335 + pm_runtime_disable(dev); 2335 2336 err_genpd_cleanup: 2336 2337 camss_genpd_cleanup(camss); 2337 2338
+1
drivers/media/platform/qcom/venus/core.c
··· 430 430 struct device *dev = core->dev; 431 431 int ret; 432 432 433 + cancel_delayed_work_sync(&core->work); 433 434 ret = pm_runtime_get_sync(dev); 434 435 WARN_ON(ret < 0); 435 436
+3 -3
drivers/media/platform/qcom/venus/firmware.c
··· 316 316 317 317 core->fw.dev = &pdev->dev; 318 318 319 - iommu_dom = iommu_domain_alloc(&platform_bus_type); 320 - if (!iommu_dom) { 319 + iommu_dom = iommu_paging_domain_alloc(core->fw.dev); 320 + if (IS_ERR(iommu_dom)) { 321 321 dev_err(core->fw.dev, "Failed to allocate iommu domain\n"); 322 - ret = -ENOMEM; 322 + ret = PTR_ERR(iommu_dom); 323 323 goto err_unregister; 324 324 } 325 325
+4 -4
drivers/media/platform/qcom/venus/hfi_cmds.c
··· 156 156 pkt->hdr.size = sizeof(*pkt); 157 157 pkt->hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY; 158 158 pkt->num_properties = 1; 159 - pkt->data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION; 159 + pkt->data = HFI_PROPERTY_SYS_IMAGE_VERSION; 160 160 } 161 161 162 162 int pkt_session_init(struct hfi_session_init_pkt *pkt, void *cookie, ··· 331 331 pkt->alloc_len = out_frame->alloc_len; 332 332 pkt->filled_len = out_frame->filled_len; 333 333 pkt->offset = out_frame->offset; 334 - pkt->data[0] = out_frame->extradata_size; 334 + pkt->data = out_frame->extradata_size; 335 335 336 336 return 0; 337 337 } ··· 402 402 pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_GET_PROPERTY; 403 403 pkt->shdr.session_id = hash32_ptr(cookie); 404 404 pkt->num_properties = 1; 405 - pkt->data[0] = ptype; 405 + pkt->data = ptype; 406 406 407 407 return 0; 408 408 } ··· 1110 1110 1111 1111 switch (ptype) { 1112 1112 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: 1113 - pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_ENTROPY; 1113 + pkt->data = HFI_PROPERTY_CONFIG_VDEC_ENTROPY; 1114 1114 break; 1115 1115 default: 1116 1116 ret = pkt_session_get_property_1x(pkt, cookie, ptype);
+8 -8
drivers/media/platform/qcom/venus/hfi_cmds.h
··· 74 74 struct hfi_sys_get_property_pkt { 75 75 struct hfi_pkt_hdr hdr; 76 76 u32 num_properties; 77 - u32 data[1]; 77 + u32 data; 78 78 }; 79 79 80 80 struct hfi_sys_set_buffers_pkt { ··· 82 82 u32 buffer_type; 83 83 u32 buffer_size; 84 84 u32 num_buffers; 85 - u32 buffer_addr[1]; 85 + u32 buffer_addr[]; 86 86 }; 87 87 88 88 struct hfi_sys_ping_pkt { ··· 151 151 u32 input_tag; 152 152 u32 packet_buffer; 153 153 u32 extradata_buffer; 154 - u32 data[1]; 154 + u32 data; 155 155 }; 156 156 157 157 struct hfi_session_empty_buffer_uncompressed_plane0_pkt { ··· 168 168 u32 input_tag; 169 169 u32 packet_buffer; 170 170 u32 extradata_buffer; 171 - u32 data[1]; 171 + u32 data; 172 172 }; 173 173 174 174 struct hfi_session_empty_buffer_uncompressed_plane1_pkt { ··· 177 177 u32 filled_len; 178 178 u32 offset; 179 179 u32 packet_buffer2; 180 - u32 data[1]; 180 + u32 data; 181 181 }; 182 182 183 183 struct hfi_session_empty_buffer_uncompressed_plane2_pkt { ··· 186 186 u32 filled_len; 187 187 u32 offset; 188 188 u32 packet_buffer3; 189 - u32 data[1]; 189 + u32 data; 190 190 }; 191 191 192 192 struct hfi_session_fill_buffer_pkt { ··· 198 198 u32 output_tag; 199 199 u32 packet_buffer; 200 200 u32 extradata_buffer; 201 - u32 data[1]; 201 + u32 data; 202 202 }; 203 203 204 204 struct hfi_session_flush_pkt { ··· 217 217 struct hfi_session_get_property_pkt { 218 218 struct hfi_session_hdr_pkt shdr; 219 219 u32 num_properties; 220 - u32 data[1]; 220 + u32 data; 221 221 }; 222 222 223 223 struct hfi_session_release_buffer_pkt {
+10 -10
drivers/media/platform/qcom/venus/hfi_helper.h
··· 761 761 762 762 struct hfi_multi_view_format { 763 763 u32 views; 764 - u32 view_order[1]; 764 + u32 view_order[]; 765 765 }; 766 766 767 767 #define HFI_MULTI_SLICE_OFF 0x1 ··· 1005 1005 struct hfi_uncompressed_plane_info { 1006 1006 u32 format; 1007 1007 u32 num_planes; 1008 - struct hfi_uncompressed_plane_constraints plane_constraints[1]; 1008 + struct hfi_uncompressed_plane_constraints plane_constraints; 1009 1009 }; 1010 1010 1011 1011 struct hfi_uncompressed_format_supported { 1012 1012 u32 buffer_type; 1013 1013 u32 format_entries; 1014 - struct hfi_uncompressed_plane_info plane_info[1]; 1014 + struct hfi_uncompressed_plane_info plane_info; 1015 1015 }; 1016 1016 1017 1017 struct hfi_uncompressed_plane_actual { ··· 1038 1038 1039 1039 struct hfi_properties_supported { 1040 1040 u32 num_properties; 1041 - u32 properties[1]; 1041 + u32 properties[]; 1042 1042 }; 1043 1043 1044 1044 struct hfi_max_sessions_supported { ··· 1085 1085 1086 1086 struct hfi_resource_ocmem_requirement_info { 1087 1087 u32 num_entries; 1088 - struct hfi_resource_ocmem_requirement requirements[1]; 1088 + struct hfi_resource_ocmem_requirement requirements[]; 1089 1089 }; 1090 1090 1091 1091 struct hfi_property_sys_image_version_info_type { 1092 1092 u32 string_size; 1093 - u8 str_image_version[1]; 1093 + u8 str_image_version[]; 1094 1094 }; 1095 1095 1096 1096 struct hfi_codec_mask_supported { ··· 1141 1141 u32 port_index; 1142 1142 u32 type; 1143 1143 u32 data_size; 1144 - u8 data[1]; 1144 + u8 data[]; 1145 1145 }; 1146 1146 1147 1147 struct hfi_batch_info { ··· 1236 1236 1237 1237 struct hfi_data_payload { 1238 1238 u32 size; 1239 - u8 data[1]; 1239 + u8 data[]; 1240 1240 }; 1241 1241 1242 1242 struct hfi_enable_picture { ··· 1264 1264 struct hfi_buffer_alloc_mode_supported { 1265 1265 u32 buffer_type; 1266 1266 u32 num_entries; 1267 - u32 data[1]; 1267 + u32 data[]; 1268 1268 }; 1269 1269 1270 1270 struct hfi_mb_error_map { 1271 1271 u32 error_map_size; 1272 - u8 error_map[1]; 1272 + u8 error_map[]; 1273 1273 }; 1274 1274 1275 1275 struct hfi_metadata_pass_through {
+1 -1
drivers/media/platform/qcom/venus/hfi_parser.c
··· 157 157 parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) 158 158 { 159 159 struct hfi_uncompressed_format_supported *fmt = data; 160 - struct hfi_uncompressed_plane_info *pinfo = fmt->plane_info; 160 + struct hfi_uncompressed_plane_info *pinfo = &fmt->plane_info; 161 161 struct hfi_uncompressed_plane_constraints *constr; 162 162 struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {}; 163 163 u32 entries = fmt->format_entries;
+10 -10
drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c
··· 1063 1063 u32 (*persist)(void); 1064 1064 }; 1065 1065 1066 - static struct dec_bufsize_ops dec_h264_ops = { 1066 + static const struct dec_bufsize_ops dec_h264_ops = { 1067 1067 .scratch = h264d_scratch_size, 1068 1068 .scratch1 = h264d_scratch1_size, 1069 1069 .persist1 = h264d_persist1_size, 1070 1070 }; 1071 1071 1072 - static struct dec_bufsize_ops dec_h265_ops = { 1072 + static const struct dec_bufsize_ops dec_h265_ops = { 1073 1073 .scratch = h265d_scratch_size, 1074 1074 .scratch1 = h265d_scratch1_size, 1075 1075 .persist1 = h265d_persist1_size, 1076 1076 }; 1077 1077 1078 - static struct dec_bufsize_ops dec_vp8_ops = { 1078 + static const struct dec_bufsize_ops dec_vp8_ops = { 1079 1079 .scratch = vpxd_scratch_size, 1080 1080 .scratch1 = vp8d_scratch1_size, 1081 1081 .persist1 = vp8d_persist1_size, 1082 1082 }; 1083 1083 1084 - static struct dec_bufsize_ops dec_vp9_ops = { 1084 + static const struct dec_bufsize_ops dec_vp9_ops = { 1085 1085 .scratch = vpxd_scratch_size, 1086 1086 .scratch1 = vp9d_scratch1_size, 1087 1087 .persist1 = vp9d_persist1_size, 1088 1088 }; 1089 1089 1090 - static struct dec_bufsize_ops dec_mpeg2_ops = { 1090 + static const struct dec_bufsize_ops dec_mpeg2_ops = { 1091 1091 .scratch = mpeg2d_scratch_size, 1092 1092 .scratch1 = mpeg2d_scratch1_size, 1093 1093 .persist1 = mpeg2d_persist1_size, 1094 1094 }; 1095 1095 1096 - static struct enc_bufsize_ops enc_h264_ops = { 1096 + static const struct enc_bufsize_ops enc_h264_ops = { 1097 1097 .scratch = h264e_scratch_size, 1098 1098 .scratch1 = h264e_scratch1_size, 1099 1099 .scratch2 = enc_scratch2_size, 1100 1100 .persist = enc_persist_size, 1101 1101 }; 1102 1102 1103 - static struct enc_bufsize_ops enc_h265_ops = { 1103 + static const struct enc_bufsize_ops enc_h265_ops = { 1104 1104 .scratch = h265e_scratch_size, 1105 1105 .scratch1 = h265e_scratch1_size, 1106 1106 .scratch2 = enc_scratch2_size, 1107 1107 .persist = enc_persist_size, 1108 1108 }; 1109 1109 1110 - static struct enc_bufsize_ops enc_vp8_ops = { 1110 + static const struct enc_bufsize_ops enc_vp8_ops = { 1111 1111 .scratch = vp8e_scratch_size, 1112 1112 .scratch1 = vp8e_scratch1_size, 1113 1113 .scratch2 = enc_scratch2_size, ··· 1186 1186 u32 codec = params->codec; 1187 1187 u32 width = params->width, height = params->height, out_min_count; 1188 1188 u32 out_width = params->out_width, out_height = params->out_height; 1189 - struct dec_bufsize_ops *dec_ops; 1189 + const struct dec_bufsize_ops *dec_ops; 1190 1190 bool is_secondary_output = params->dec.is_secondary_output; 1191 1191 bool is_interlaced = params->dec.is_interlaced; 1192 1192 u32 max_mbs_per_frame = params->dec.max_mbs_per_frame; ··· 1260 1260 struct hfi_buffer_requirements *bufreq) 1261 1261 { 1262 1262 enum hfi_version version = params->version; 1263 - struct enc_bufsize_ops *enc_ops; 1263 + const struct enc_bufsize_ops *enc_ops; 1264 1264 u32 width = params->width; 1265 1265 u32 height = params->height; 1266 1266 bool is_tenbit = params->enc.is_tenbit;
+1
drivers/media/platform/raspberrypi/pisp_be/Kconfig
··· 2 2 tristate "Raspberry Pi PiSP Backend (BE) ISP driver" 3 3 depends on V4L_PLATFORM_DRIVERS 4 4 depends on VIDEO_DEV 5 + depends on ARCH_BCM2835 || COMPILE_TEST 5 6 select VIDEO_V4L2_SUBDEV_API 6 7 select MEDIA_CONTROLLER 7 8 select VIDEOBUF2_DMA_CONTIG
+9 -12
drivers/media/platform/renesas/rcar-vin/rcar-core.c
··· 1274 1274 .scaler = rvin_scaler_gen3, 1275 1275 }; 1276 1276 1277 - static const struct rvin_info rcar_info_r8a779a0 = { 1278 - .model = RCAR_GEN3, 1279 - .use_mc = true, 1280 - .use_isp = true, 1281 - .nv12 = true, 1282 - .max_width = 4096, 1283 - .max_height = 4096, 1284 - }; 1285 - 1286 - static const struct rvin_info rcar_info_r8a779g0 = { 1277 + static const struct rvin_info rcar_info_gen4 = { 1287 1278 .model = RCAR_GEN3, 1288 1279 .use_mc = true, 1289 1280 .use_isp = true, ··· 1345 1354 .data = &rcar_info_r8a77995, 1346 1355 }, 1347 1356 { 1357 + /* Keep to be compatible with old DTS files. */ 1348 1358 .compatible = "renesas,vin-r8a779a0", 1349 - .data = &rcar_info_r8a779a0, 1359 + .data = &rcar_info_gen4, 1350 1360 }, 1351 1361 { 1362 + /* Keep to be compatible with old DTS files. */ 1352 1363 .compatible = "renesas,vin-r8a779g0", 1353 - .data = &rcar_info_r8a779g0, 1364 + .data = &rcar_info_gen4, 1365 + }, 1366 + { 1367 + .compatible = "renesas,rcar-gen4-vin", 1368 + .data = &rcar_info_gen4, 1354 1369 }, 1355 1370 { /* Sentinel */ }, 1356 1371 };
+1
drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
··· 865 865 { .compatible = "renesas,rzg2l-csi2", }, 866 866 { /* sentinel */ } 867 867 }; 868 + MODULE_DEVICE_TABLE(of, rzg2l_csi2_of_table); 868 869 869 870 static struct platform_driver rzg2l_csi2_pdrv = { 870 871 .remove_new = rzg2l_csi2_remove,
+22
drivers/media/platform/renesas/vsp1/vsp1_video.c
··· 1082 1082 }; 1083 1083 1084 1084 /* ----------------------------------------------------------------------------- 1085 + * Media entity operations 1086 + */ 1087 + 1088 + static int vsp1_video_link_validate(struct media_link *link) 1089 + { 1090 + /* 1091 + * Ideally, link validation should be implemented here instead of 1092 + * calling vsp1_video_verify_format() in vsp1_video_streamon() 1093 + * manually. That would however break userspace that start one video 1094 + * device before configures formats on other video devices in the 1095 + * pipeline. This operation is just a no-op to silence the warnings 1096 + * from v4l2_subdev_link_validate(). 1097 + */ 1098 + return 0; 1099 + } 1100 + 1101 + static const struct media_entity_operations vsp1_video_media_ops = { 1102 + .link_validate = vsp1_video_link_validate, 1103 + }; 1104 + 1105 + /* ----------------------------------------------------------------------------- 1085 1106 * Suspend and Resume 1086 1107 */ 1087 1108 ··· 1236 1215 1237 1216 /* ... and the video node... */ 1238 1217 video->video.v4l2_dev = &video->vsp1->v4l2_dev; 1218 + video->video.entity.ops = &vsp1_video_media_ops; 1239 1219 video->video.fops = &vsp1_video_fops; 1240 1220 snprintf(video->video.name, sizeof(video->video.name), "%s %s", 1241 1221 rwpf->entity.subdev.name, direction);
+14
drivers/media/platform/rockchip/rkisp1/rkisp1-common.c
··· 178 178 179 179 rkisp1_sd_adjust_crop_rect(crop, &crop_bounds); 180 180 } 181 + 182 + void rkisp1_bls_swap_regs(enum rkisp1_fmt_raw_pat_type pattern, 183 + const u32 input[4], u32 output[4]) 184 + { 185 + static const unsigned int swap[4][4] = { 186 + [RKISP1_RAW_RGGB] = { 0, 1, 2, 3 }, 187 + [RKISP1_RAW_GRBG] = { 1, 0, 3, 2 }, 188 + [RKISP1_RAW_GBRG] = { 2, 3, 0, 1 }, 189 + [RKISP1_RAW_BGGR] = { 3, 2, 1, 0 }, 190 + }; 191 + 192 + for (unsigned int i = 0; i < 4; ++i) 193 + output[i] = input[swap[pattern][i]]; 194 + }
+43 -6
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
··· 33 33 #define RKISP1_ISP_SD_SRC BIT(0) 34 34 #define RKISP1_ISP_SD_SINK BIT(1) 35 35 36 - /* min and max values for the widths and heights of the entities */ 37 - #define RKISP1_ISP_MAX_WIDTH 4032 38 - #define RKISP1_ISP_MAX_HEIGHT 3024 36 + /* 37 + * Minimum values for the width and height of entities. The maximum values are 38 + * model-specific and stored in the rkisp1_info structure. 39 + */ 39 40 #define RKISP1_ISP_MIN_WIDTH 32 40 41 #define RKISP1_ISP_MIN_HEIGHT 32 41 42 ··· 116 115 * @RKISP1_FEATURE_SELF_PATH: The ISP has a self path 117 116 * @RKISP1_FEATURE_DUAL_CROP: The ISP has the dual crop block at the resizer input 118 117 * @RKISP1_FEATURE_DMA_34BIT: The ISP uses 34-bit DMA addresses 118 + * @RKISP1_FEATURE_BLS: The ISP has a dedicated BLS block 119 + * @RKISP1_FEATURE_COMPAND: The ISP has a companding block 119 120 * 120 121 * The ISP features are stored in a bitmask in &rkisp1_info.features and allow 121 122 * the driver to implement support for features present in some ISP versions ··· 129 126 RKISP1_FEATURE_SELF_PATH = BIT(2), 130 127 RKISP1_FEATURE_DUAL_CROP = BIT(3), 131 128 RKISP1_FEATURE_DMA_34BIT = BIT(4), 129 + RKISP1_FEATURE_BLS = BIT(5), 130 + RKISP1_FEATURE_COMPAND = BIT(6), 132 131 }; 133 132 134 133 #define rkisp1_has_feature(rkisp1, feature) \ ··· 145 140 * @isr_size: number of entries in the @isrs array 146 141 * @isp_ver: ISP version 147 142 * @features: bitmask of rkisp1_feature features implemented by the ISP 143 + * @max_width: maximum input frame width 144 + * @max_height: maximum input frame height 148 145 * 149 146 * This structure contains information about the ISP specific to a particular 150 147 * ISP model, version, or integration in a particular SoC. ··· 158 151 unsigned int isr_size; 159 152 enum rkisp1_cif_isp_version isp_ver; 160 153 unsigned int features; 154 + unsigned int max_width; 155 + unsigned int max_height; 161 156 }; 162 157 163 158 /* ··· 241 232 242 233 /* 243 234 * struct rkisp1_buffer - A container for the vb2 buffers used by the video devices: 244 - * params, stats, mainpath, selfpath 235 + * stats, mainpath, selfpath 245 236 * 246 237 * @vb: vb2 buffer 247 238 * @queue: entry of the buffer in the queue ··· 252 243 struct list_head queue; 253 244 dma_addr_t buff_addr[VIDEO_MAX_PLANES]; 254 245 }; 246 + 247 + /* 248 + * struct rkisp1_params_buffer - A container for the vb2 buffers used by the 249 + * params video device 250 + * 251 + * @vb: vb2 buffer 252 + * @queue: entry of the buffer in the queue 253 + * @cfg: scratch buffer used for caching the ISP configuration parameters 254 + */ 255 + struct rkisp1_params_buffer { 256 + struct vb2_v4l2_buffer vb; 257 + struct list_head queue; 258 + void *cfg; 259 + }; 260 + 261 + static inline struct rkisp1_params_buffer * 262 + to_rkisp1_params_buffer(struct vb2_v4l2_buffer *vbuf) 263 + { 264 + return container_of(vbuf, struct rkisp1_params_buffer, vb); 265 + } 255 266 256 267 /* 257 268 * struct rkisp1_dummy_buffer - A buffer to write the next frame to in case ··· 401 372 * @ops: pointer to the variant-specific operations 402 373 * @config_lock: locks the buffer list 'params' 403 374 * @params: queue of rkisp1_buffer 404 - * @vdev_fmt: v4l2_format of the metadata format 375 + * @metafmt the currently enabled metadata format 405 376 * @quantization: the quantization configured on the isp's src pad 377 + * @ycbcr_encoding the YCbCr encoding 406 378 * @raw_type: the bayer pattern on the isp video sink pad 379 + * @enabled_blocks: bitmask of enabled ISP blocks 407 380 */ 408 381 struct rkisp1_params { 409 382 struct rkisp1_vdev_node vnode; ··· 414 383 415 384 spinlock_t config_lock; /* locks the buffers list 'params' */ 416 385 struct list_head params; 417 - struct v4l2_format vdev_fmt; 386 + 387 + const struct v4l2_meta_format *metafmt; 418 388 419 389 enum v4l2_quantization quantization; 420 390 enum v4l2_ycbcr_encoding ycbcr_encoding; 421 391 enum rkisp1_fmt_raw_pat_type raw_type; 392 + 393 + u32 enabled_blocks; 422 394 }; 423 395 424 396 /* ··· 606 572 */ 607 573 void rkisp1_sd_adjust_crop(struct v4l2_rect *crop, 608 574 const struct v4l2_mbus_framefmt *bounds); 575 + 576 + void rkisp1_bls_swap_regs(enum rkisp1_fmt_raw_pat_type pattern, 577 + const u32 input[4], u32 output[4]); 609 578 610 579 /* 611 580 * rkisp1_mbus_info_get_by_code - get the isp info of the media bus code
+3 -2
drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c
··· 307 307 struct v4l2_subdev_state *sd_state, 308 308 struct v4l2_subdev_format *fmt) 309 309 { 310 + struct rkisp1_csi *csi = to_rkisp1_csi(sd); 310 311 const struct rkisp1_mbus_info *mbus_info; 311 312 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 312 313 ··· 327 326 328 327 sink_fmt->width = clamp_t(u32, fmt->format.width, 329 328 RKISP1_ISP_MIN_WIDTH, 330 - RKISP1_ISP_MAX_WIDTH); 329 + csi->rkisp1->info->max_width); 331 330 sink_fmt->height = clamp_t(u32, fmt->format.height, 332 331 RKISP1_ISP_MIN_HEIGHT, 333 - RKISP1_ISP_MAX_HEIGHT); 332 + csi->rkisp1->info->max_height); 334 333 335 334 fmt->format = *sink_fmt; 336 335
+12 -3
drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
··· 509 509 .isp_ver = RKISP1_V12, 510 510 .features = RKISP1_FEATURE_MIPI_CSI2 511 511 | RKISP1_FEATURE_SELF_PATH 512 - | RKISP1_FEATURE_DUAL_CROP, 512 + | RKISP1_FEATURE_DUAL_CROP 513 + | RKISP1_FEATURE_BLS, 514 + .max_width = 3264, 515 + .max_height = 2448, 513 516 }; 514 517 515 518 static const char * const rk3399_isp_clks[] = { ··· 533 530 .isp_ver = RKISP1_V10, 534 531 .features = RKISP1_FEATURE_MIPI_CSI2 535 532 | RKISP1_FEATURE_SELF_PATH 536 - | RKISP1_FEATURE_DUAL_CROP, 533 + | RKISP1_FEATURE_DUAL_CROP 534 + | RKISP1_FEATURE_BLS, 535 + .max_width = 4416, 536 + .max_height = 3312, 537 537 }; 538 538 539 539 static const char * const imx8mp_isp_clks[] = { ··· 556 550 .isr_size = ARRAY_SIZE(imx8mp_isp_isrs), 557 551 .isp_ver = RKISP1_V_IMX8MP, 558 552 .features = RKISP1_FEATURE_MAIN_STRIDE 559 - | RKISP1_FEATURE_DMA_34BIT, 553 + | RKISP1_FEATURE_DMA_34BIT 554 + | RKISP1_FEATURE_COMPAND, 555 + .max_width = 4096, 556 + .max_height = 3072, 560 557 }; 561 558 562 559 static const struct of_device_id rkisp1_of_match[] = {
+5 -4
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
··· 517 517 struct v4l2_subdev_state *sd_state, 518 518 struct v4l2_subdev_frame_size_enum *fse) 519 519 { 520 + struct rkisp1_isp *isp = to_rkisp1_isp(sd); 520 521 const struct rkisp1_mbus_info *mbus_info; 521 522 522 523 if (fse->pad == RKISP1_ISP_PAD_SINK_PARAMS || ··· 540 539 return -EINVAL; 541 540 542 541 fse->min_width = RKISP1_ISP_MIN_WIDTH; 543 - fse->max_width = RKISP1_ISP_MAX_WIDTH; 542 + fse->max_width = isp->rkisp1->info->max_width; 544 543 fse->min_height = RKISP1_ISP_MIN_HEIGHT; 545 - fse->max_height = RKISP1_ISP_MAX_HEIGHT; 544 + fse->max_height = isp->rkisp1->info->max_height; 546 545 547 546 return 0; 548 547 } ··· 773 772 774 773 sink_fmt->width = clamp_t(u32, format->width, 775 774 RKISP1_ISP_MIN_WIDTH, 776 - RKISP1_ISP_MAX_WIDTH); 775 + isp->rkisp1->info->max_width); 777 776 sink_fmt->height = clamp_t(u32, format->height, 778 777 RKISP1_ISP_MIN_HEIGHT, 779 - RKISP1_ISP_MAX_HEIGHT); 778 + isp->rkisp1->info->max_height); 780 779 781 780 /* 782 781 * Adjust the color space fields. Accept any color primaries and
+936 -101
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
··· 5 5 * Copyright (C) 2017 Rockchip Electronics Co., Ltd. 6 6 */ 7 7 8 + #include <linux/math.h> 9 + #include <linux/string.h> 10 + 8 11 #include <media/v4l2-common.h> 9 12 #include <media/v4l2-event.h> 10 13 #include <media/v4l2-ioctl.h> ··· 35 32 (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n)) 36 33 #define RKISP1_ISP_CC_COEFF(n) \ 37 34 (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4) 35 + 36 + #define RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS BIT(0) 37 + #define RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC BIT(1) 38 + 39 + union rkisp1_ext_params_config { 40 + struct rkisp1_ext_params_block_header header; 41 + struct rkisp1_ext_params_bls_config bls; 42 + struct rkisp1_ext_params_dpcc_config dpcc; 43 + struct rkisp1_ext_params_sdg_config sdg; 44 + struct rkisp1_ext_params_lsc_config lsc; 45 + struct rkisp1_ext_params_awb_gain_config awbg; 46 + struct rkisp1_ext_params_flt_config flt; 47 + struct rkisp1_ext_params_bdm_config bdm; 48 + struct rkisp1_ext_params_ctk_config ctk; 49 + struct rkisp1_ext_params_goc_config goc; 50 + struct rkisp1_ext_params_dpf_config dpf; 51 + struct rkisp1_ext_params_dpf_strength_config dpfs; 52 + struct rkisp1_ext_params_cproc_config cproc; 53 + struct rkisp1_ext_params_ie_config ie; 54 + struct rkisp1_ext_params_awb_meas_config awbm; 55 + struct rkisp1_ext_params_hst_config hst; 56 + struct rkisp1_ext_params_aec_config aec; 57 + struct rkisp1_ext_params_afc_config afc; 58 + struct rkisp1_ext_params_compand_bls_config compand_bls; 59 + struct rkisp1_ext_params_compand_curve_config compand_curve; 60 + }; 61 + 62 + enum rkisp1_params_formats { 63 + RKISP1_PARAMS_FIXED, 64 + RKISP1_PARAMS_EXTENSIBLE, 65 + }; 66 + 67 + static const struct v4l2_meta_format rkisp1_params_formats[] = { 68 + [RKISP1_PARAMS_FIXED] = { 69 + .dataformat = V4L2_META_FMT_RK_ISP1_PARAMS, 70 + .buffersize = sizeof(struct rkisp1_params_cfg), 71 + }, 72 + [RKISP1_PARAMS_EXTENSIBLE] = { 73 + .dataformat = V4L2_META_FMT_RK_ISP1_EXT_PARAMS, 74 + .buffersize = sizeof(struct rkisp1_ext_params_cfg), 75 + }, 76 + }; 77 + 78 + static const struct v4l2_meta_format * 79 + rkisp1_params_get_format_info(u32 dataformat) 80 + { 81 + for (unsigned int i = 0; i < ARRAY_SIZE(rkisp1_params_formats); i++) { 82 + if (rkisp1_params_formats[i].dataformat == dataformat) 83 + return &rkisp1_params_formats[i]; 84 + } 85 + 86 + return &rkisp1_params_formats[RKISP1_PARAMS_FIXED]; 87 + } 38 88 39 89 static inline void 40 90 rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) ··· 168 112 new_control &= RKISP1_CIF_ISP_BLS_ENA; 169 113 /* fixed subtraction values */ 170 114 if (!arg->enable_auto) { 171 - const struct rkisp1_cif_isp_bls_fixed_val *pval = 172 - &arg->fixed_val; 115 + static const u32 regs[] = { 116 + RKISP1_CIF_ISP_BLS_A_FIXED, 117 + RKISP1_CIF_ISP_BLS_B_FIXED, 118 + RKISP1_CIF_ISP_BLS_C_FIXED, 119 + RKISP1_CIF_ISP_BLS_D_FIXED, 120 + }; 121 + u32 swapped[4]; 173 122 174 - switch (params->raw_type) { 175 - case RKISP1_RAW_BGGR: 176 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED, 177 - pval->r); 178 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED, 179 - pval->gr); 180 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED, 181 - pval->gb); 182 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED, 183 - pval->b); 184 - break; 185 - case RKISP1_RAW_GBRG: 186 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED, 187 - pval->r); 188 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED, 189 - pval->gr); 190 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED, 191 - pval->gb); 192 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED, 193 - pval->b); 194 - break; 195 - case RKISP1_RAW_GRBG: 196 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED, 197 - pval->r); 198 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED, 199 - pval->gr); 200 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED, 201 - pval->gb); 202 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED, 203 - pval->b); 204 - break; 205 - case RKISP1_RAW_RGGB: 206 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_A_FIXED, 207 - pval->r); 208 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_B_FIXED, 209 - pval->gr); 210 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_C_FIXED, 211 - pval->gb); 212 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_D_FIXED, 213 - pval->b); 214 - break; 215 - default: 216 - break; 217 - } 123 + rkisp1_bls_swap_regs(params->raw_type, regs, swapped); 218 124 125 + rkisp1_write(params->rkisp1, swapped[0], arg->fixed_val.r); 126 + rkisp1_write(params->rkisp1, swapped[1], arg->fixed_val.gr); 127 + rkisp1_write(params->rkisp1, swapped[2], arg->fixed_val.gb); 128 + rkisp1_write(params->rkisp1, swapped[3], arg->fixed_val.b); 219 129 } else { 220 130 if (arg->en_windows & BIT(1)) { 221 131 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_BLS_H2_START, ··· 1261 1239 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPF_STRENGTH_R, arg->r); 1262 1240 } 1263 1241 1242 + static void rkisp1_compand_write_px_curve(struct rkisp1_params *params, 1243 + unsigned int addr, const u8 *curve) 1244 + { 1245 + const unsigned int points_per_reg = 6; 1246 + const unsigned int num_regs = 1247 + DIV_ROUND_UP(RKISP1_CIF_ISP_COMPAND_NUM_POINTS, 1248 + points_per_reg); 1249 + 1250 + /* 1251 + * The compand curve is specified as a piecewise linear function with 1252 + * 64 points. X coordinates are stored as a log2 of the displacement 1253 + * from the previous point, in 5 bits, with 6 values per register. The 1254 + * last register stores 4 values. 1255 + */ 1256 + for (unsigned int reg = 0; reg < num_regs; ++reg) { 1257 + unsigned int num_points = 1258 + min(RKISP1_CIF_ISP_COMPAND_NUM_POINTS - 1259 + reg * points_per_reg, points_per_reg); 1260 + u32 val = 0; 1261 + 1262 + for (unsigned int i = 0; i < num_points; i++) 1263 + val |= (*curve++ & 0x1f) << (i * 5); 1264 + 1265 + rkisp1_write(params->rkisp1, addr, val); 1266 + addr += 4; 1267 + } 1268 + } 1269 + 1270 + static void 1271 + rkisp1_compand_write_curve_mem(struct rkisp1_params *params, 1272 + unsigned int reg_addr, unsigned int reg_data, 1273 + const u32 curve[RKISP1_CIF_ISP_COMPAND_NUM_POINTS]) 1274 + { 1275 + for (unsigned int i = 0; i < RKISP1_CIF_ISP_COMPAND_NUM_POINTS; i++) { 1276 + rkisp1_write(params->rkisp1, reg_addr, i); 1277 + rkisp1_write(params->rkisp1, reg_data, curve[i]); 1278 + } 1279 + } 1280 + 1281 + static void 1282 + rkisp1_compand_bls_config(struct rkisp1_params *params, 1283 + const struct rkisp1_cif_isp_compand_bls_config *arg) 1284 + { 1285 + static const u32 regs[] = { 1286 + RKISP1_CIF_ISP_COMPAND_BLS_A_FIXED, 1287 + RKISP1_CIF_ISP_COMPAND_BLS_B_FIXED, 1288 + RKISP1_CIF_ISP_COMPAND_BLS_C_FIXED, 1289 + RKISP1_CIF_ISP_COMPAND_BLS_D_FIXED, 1290 + }; 1291 + u32 swapped[4]; 1292 + 1293 + rkisp1_bls_swap_regs(params->raw_type, regs, swapped); 1294 + 1295 + rkisp1_write(params->rkisp1, swapped[0], arg->r); 1296 + rkisp1_write(params->rkisp1, swapped[1], arg->gr); 1297 + rkisp1_write(params->rkisp1, swapped[2], arg->gb); 1298 + rkisp1_write(params->rkisp1, swapped[3], arg->b); 1299 + } 1300 + 1301 + static void 1302 + rkisp1_compand_expand_config(struct rkisp1_params *params, 1303 + const struct rkisp1_cif_isp_compand_curve_config *arg) 1304 + { 1305 + rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_EXPAND_PX_N(0), 1306 + arg->px); 1307 + rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_Y_ADDR, 1308 + RKISP1_CIF_ISP_COMPAND_EXPAND_Y_WRITE_DATA, 1309 + arg->y); 1310 + rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_EXPAND_X_ADDR, 1311 + RKISP1_CIF_ISP_COMPAND_EXPAND_X_WRITE_DATA, 1312 + arg->x); 1313 + } 1314 + 1315 + static void 1316 + rkisp1_compand_compress_config(struct rkisp1_params *params, 1317 + const struct rkisp1_cif_isp_compand_curve_config *arg) 1318 + { 1319 + rkisp1_compand_write_px_curve(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_PX_N(0), 1320 + arg->px); 1321 + rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_ADDR, 1322 + RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_WRITE_DATA, 1323 + arg->y); 1324 + rkisp1_compand_write_curve_mem(params, RKISP1_CIF_ISP_COMPAND_COMPRESS_X_ADDR, 1325 + RKISP1_CIF_ISP_COMPAND_COMPRESS_X_WRITE_DATA, 1326 + arg->x); 1327 + } 1328 + 1264 1329 static void 1265 1330 rkisp1_isp_isr_other_config(struct rkisp1_params *params, 1266 1331 const struct rkisp1_params_cfg *new_params) ··· 1357 1248 module_en_update = new_params->module_en_update; 1358 1249 module_cfg_update = new_params->module_cfg_update; 1359 1250 module_ens = new_params->module_ens; 1251 + 1252 + if (!rkisp1_has_feature(params->rkisp1, BLS)) { 1253 + module_en_update &= ~RKISP1_CIF_ISP_MODULE_BLS; 1254 + module_cfg_update &= ~RKISP1_CIF_ISP_MODULE_BLS; 1255 + module_ens &= ~RKISP1_CIF_ISP_MODULE_BLS; 1256 + } 1360 1257 1361 1258 /* update dpc config */ 1362 1259 if (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC) ··· 1616 1501 } 1617 1502 } 1618 1503 1619 - static bool rkisp1_params_get_buffer(struct rkisp1_params *params, 1620 - struct rkisp1_buffer **buf, 1621 - struct rkisp1_params_cfg **cfg) 1504 + /*------------------------------------------------------------------------------ 1505 + * Extensible parameters format handling 1506 + */ 1507 + 1508 + static void 1509 + rkisp1_ext_params_bls(struct rkisp1_params *params, 1510 + const union rkisp1_ext_params_config *block) 1622 1511 { 1623 - if (list_empty(&params->params)) 1624 - return false; 1512 + const struct rkisp1_ext_params_bls_config *bls = &block->bls; 1625 1513 1626 - *buf = list_first_entry(&params->params, struct rkisp1_buffer, queue); 1627 - *cfg = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0); 1514 + if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1515 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL, 1516 + RKISP1_CIF_ISP_BLS_ENA); 1517 + return; 1518 + } 1628 1519 1629 - return true; 1520 + rkisp1_bls_config(params, &bls->config); 1521 + 1522 + if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1523 + !(params->enabled_blocks & BIT(bls->header.type))) 1524 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_BLS_CTRL, 1525 + RKISP1_CIF_ISP_BLS_ENA); 1526 + } 1527 + 1528 + static void 1529 + rkisp1_ext_params_dpcc(struct rkisp1_params *params, 1530 + const union rkisp1_ext_params_config *block) 1531 + { 1532 + const struct rkisp1_ext_params_dpcc_config *dpcc = &block->dpcc; 1533 + 1534 + if (dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1535 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 1536 + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1537 + return; 1538 + } 1539 + 1540 + rkisp1_dpcc_config(params, &dpcc->config); 1541 + 1542 + if ((dpcc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1543 + !(params->enabled_blocks & BIT(dpcc->header.type))) 1544 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 1545 + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1546 + } 1547 + 1548 + static void 1549 + rkisp1_ext_params_sdg(struct rkisp1_params *params, 1550 + const union rkisp1_ext_params_config *block) 1551 + { 1552 + const struct rkisp1_ext_params_sdg_config *sdg = &block->sdg; 1553 + 1554 + if (sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1555 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 1556 + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 1557 + return; 1558 + } 1559 + 1560 + rkisp1_sdg_config(params, &sdg->config); 1561 + 1562 + if ((sdg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1563 + !(params->enabled_blocks & BIT(sdg->header.type))) 1564 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1565 + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 1566 + } 1567 + 1568 + static void 1569 + rkisp1_ext_params_lsc(struct rkisp1_params *params, 1570 + const union rkisp1_ext_params_config *block) 1571 + { 1572 + const struct rkisp1_ext_params_lsc_config *lsc = &block->lsc; 1573 + 1574 + if (lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1575 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 1576 + RKISP1_CIF_ISP_LSC_CTRL_ENA); 1577 + return; 1578 + } 1579 + 1580 + rkisp1_lsc_config(params, &lsc->config); 1581 + 1582 + if ((lsc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1583 + !(params->enabled_blocks & BIT(lsc->header.type))) 1584 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 1585 + RKISP1_CIF_ISP_LSC_CTRL_ENA); 1586 + } 1587 + 1588 + static void 1589 + rkisp1_ext_params_awbg(struct rkisp1_params *params, 1590 + const union rkisp1_ext_params_config *block) 1591 + { 1592 + const struct rkisp1_ext_params_awb_gain_config *awbg = &block->awbg; 1593 + 1594 + if (awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1595 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 1596 + RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 1597 + return; 1598 + } 1599 + 1600 + params->ops->awb_gain_config(params, &awbg->config); 1601 + 1602 + if ((awbg->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1603 + !(params->enabled_blocks & BIT(awbg->header.type))) 1604 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1605 + RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); 1606 + } 1607 + 1608 + static void 1609 + rkisp1_ext_params_flt(struct rkisp1_params *params, 1610 + const union rkisp1_ext_params_config *block) 1611 + { 1612 + const struct rkisp1_ext_params_flt_config *flt = &block->flt; 1613 + 1614 + if (flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1615 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE, 1616 + RKISP1_CIF_ISP_FLT_ENA); 1617 + return; 1618 + } 1619 + 1620 + rkisp1_flt_config(params, &flt->config); 1621 + 1622 + if ((flt->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1623 + !(params->enabled_blocks & BIT(flt->header.type))) 1624 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_FILT_MODE, 1625 + RKISP1_CIF_ISP_FLT_ENA); 1626 + } 1627 + 1628 + static void 1629 + rkisp1_ext_params_bdm(struct rkisp1_params *params, 1630 + const union rkisp1_ext_params_config *block) 1631 + { 1632 + const struct rkisp1_ext_params_bdm_config *bdm = &block->bdm; 1633 + 1634 + if (bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1635 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC, 1636 + RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 1637 + return; 1638 + } 1639 + 1640 + rkisp1_bdm_config(params, &bdm->config); 1641 + 1642 + if ((bdm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1643 + !(params->enabled_blocks & BIT(bdm->header.type))) 1644 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DEMOSAIC, 1645 + RKISP1_CIF_ISP_DEMOSAIC_BYPASS); 1646 + } 1647 + 1648 + static void 1649 + rkisp1_ext_params_ctk(struct rkisp1_params *params, 1650 + const union rkisp1_ext_params_config *block) 1651 + { 1652 + const struct rkisp1_ext_params_ctk_config *ctk = &block->ctk; 1653 + 1654 + if (ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1655 + rkisp1_ctk_enable(params, false); 1656 + return; 1657 + } 1658 + 1659 + rkisp1_ctk_config(params, &ctk->config); 1660 + 1661 + if ((ctk->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1662 + !(params->enabled_blocks & BIT(ctk->header.type))) 1663 + rkisp1_ctk_enable(params, true); 1664 + } 1665 + 1666 + static void 1667 + rkisp1_ext_params_goc(struct rkisp1_params *params, 1668 + const union rkisp1_ext_params_config *block) 1669 + { 1670 + const struct rkisp1_ext_params_goc_config *goc = &block->goc; 1671 + 1672 + if (goc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1673 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 1674 + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 1675 + return; 1676 + } 1677 + 1678 + params->ops->goc_config(params, &goc->config); 1679 + 1680 + /* 1681 + * Unconditionally re-enable the GOC module which gets disabled by 1682 + * goc_config(). 1683 + */ 1684 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1685 + RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); 1686 + } 1687 + 1688 + static void 1689 + rkisp1_ext_params_dpf(struct rkisp1_params *params, 1690 + const union rkisp1_ext_params_config *block) 1691 + { 1692 + const struct rkisp1_ext_params_dpf_config *dpf = &block->dpf; 1693 + 1694 + if (dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1695 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, 1696 + RKISP1_CIF_ISP_DPF_MODE_EN); 1697 + return; 1698 + } 1699 + 1700 + rkisp1_dpf_config(params, &dpf->config); 1701 + 1702 + if ((dpf->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1703 + !(params->enabled_blocks & BIT(dpf->header.type))) 1704 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE, 1705 + RKISP1_CIF_ISP_DPF_MODE_EN); 1706 + } 1707 + 1708 + static void 1709 + rkisp1_ext_params_dpfs(struct rkisp1_params *params, 1710 + const union rkisp1_ext_params_config *block) 1711 + { 1712 + const struct rkisp1_ext_params_dpf_strength_config *dpfs = &block->dpfs; 1713 + 1714 + rkisp1_dpf_strength_config(params, &dpfs->config); 1715 + } 1716 + 1717 + static void 1718 + rkisp1_ext_params_cproc(struct rkisp1_params *params, 1719 + const union rkisp1_ext_params_config *block) 1720 + { 1721 + const struct rkisp1_ext_params_cproc_config *cproc = &block->cproc; 1722 + 1723 + if (cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1724 + rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, 1725 + RKISP1_CIF_C_PROC_CTR_ENABLE); 1726 + return; 1727 + } 1728 + 1729 + rkisp1_cproc_config(params, &cproc->config); 1730 + 1731 + if ((cproc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1732 + !(params->enabled_blocks & BIT(cproc->header.type))) 1733 + rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL, 1734 + RKISP1_CIF_C_PROC_CTR_ENABLE); 1735 + } 1736 + 1737 + static void 1738 + rkisp1_ext_params_ie(struct rkisp1_params *params, 1739 + const union rkisp1_ext_params_config *block) 1740 + { 1741 + const struct rkisp1_ext_params_ie_config *ie = &block->ie; 1742 + 1743 + if (ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1744 + rkisp1_ie_enable(params, false); 1745 + return; 1746 + } 1747 + 1748 + rkisp1_ie_config(params, &ie->config); 1749 + 1750 + if ((ie->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1751 + !(params->enabled_blocks & BIT(ie->header.type))) 1752 + rkisp1_ie_enable(params, true); 1753 + } 1754 + 1755 + static void 1756 + rkisp1_ext_params_awbm(struct rkisp1_params *params, 1757 + const union rkisp1_ext_params_config *block) 1758 + { 1759 + const struct rkisp1_ext_params_awb_meas_config *awbm = &block->awbm; 1760 + 1761 + if (awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1762 + params->ops->awb_meas_enable(params, &awbm->config, 1763 + false); 1764 + return; 1765 + } 1766 + 1767 + params->ops->awb_meas_config(params, &awbm->config); 1768 + 1769 + if ((awbm->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1770 + !(params->enabled_blocks & BIT(awbm->header.type))) 1771 + params->ops->awb_meas_enable(params, &awbm->config, 1772 + true); 1773 + } 1774 + 1775 + static void 1776 + rkisp1_ext_params_hstm(struct rkisp1_params *params, 1777 + const union rkisp1_ext_params_config *block) 1778 + { 1779 + const struct rkisp1_ext_params_hst_config *hst = &block->hst; 1780 + 1781 + if (hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1782 + params->ops->hst_enable(params, &hst->config, false); 1783 + return; 1784 + } 1785 + 1786 + params->ops->hst_config(params, &hst->config); 1787 + 1788 + if ((hst->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1789 + !(params->enabled_blocks & BIT(hst->header.type))) 1790 + params->ops->hst_enable(params, &hst->config, true); 1791 + } 1792 + 1793 + static void 1794 + rkisp1_ext_params_aecm(struct rkisp1_params *params, 1795 + const union rkisp1_ext_params_config *block) 1796 + { 1797 + const struct rkisp1_ext_params_aec_config *aec = &block->aec; 1798 + 1799 + if (aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1800 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 1801 + RKISP1_CIF_ISP_EXP_ENA); 1802 + return; 1803 + } 1804 + 1805 + params->ops->aec_config(params, &aec->config); 1806 + 1807 + if ((aec->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1808 + !(params->enabled_blocks & BIT(aec->header.type))) 1809 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL, 1810 + RKISP1_CIF_ISP_EXP_ENA); 1811 + } 1812 + 1813 + static void 1814 + rkisp1_ext_params_afcm(struct rkisp1_params *params, 1815 + const union rkisp1_ext_params_config *block) 1816 + { 1817 + const struct rkisp1_ext_params_afc_config *afc = &block->afc; 1818 + 1819 + if (afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1820 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 1821 + RKISP1_CIF_ISP_AFM_ENA); 1822 + return; 1823 + } 1824 + 1825 + params->ops->afm_config(params, &afc->config); 1826 + 1827 + if ((afc->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1828 + !(params->enabled_blocks & BIT(afc->header.type))) 1829 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL, 1830 + RKISP1_CIF_ISP_AFM_ENA); 1831 + } 1832 + 1833 + static void rkisp1_ext_params_compand_bls(struct rkisp1_params *params, 1834 + const union rkisp1_ext_params_config *block) 1835 + { 1836 + const struct rkisp1_ext_params_compand_bls_config *bls = 1837 + &block->compand_bls; 1838 + 1839 + if (bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1840 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1841 + RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE); 1842 + return; 1843 + } 1844 + 1845 + rkisp1_compand_bls_config(params, &bls->config); 1846 + 1847 + if ((bls->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1848 + !(params->enabled_blocks & BIT(bls->header.type))) 1849 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1850 + RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE); 1851 + } 1852 + 1853 + static void rkisp1_ext_params_compand_expand(struct rkisp1_params *params, 1854 + const union rkisp1_ext_params_config *block) 1855 + { 1856 + const struct rkisp1_ext_params_compand_curve_config *curve = 1857 + &block->compand_curve; 1858 + 1859 + if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1860 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1861 + RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE); 1862 + return; 1863 + } 1864 + 1865 + rkisp1_compand_expand_config(params, &curve->config); 1866 + 1867 + if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1868 + !(params->enabled_blocks & BIT(curve->header.type))) 1869 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1870 + RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE); 1871 + } 1872 + 1873 + static void rkisp1_ext_params_compand_compress(struct rkisp1_params *params, 1874 + const union rkisp1_ext_params_config *block) 1875 + { 1876 + const struct rkisp1_ext_params_compand_curve_config *curve = 1877 + &block->compand_curve; 1878 + 1879 + if (curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) { 1880 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1881 + RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE); 1882 + return; 1883 + } 1884 + 1885 + rkisp1_compand_compress_config(params, &curve->config); 1886 + 1887 + if ((curve->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) && 1888 + !(params->enabled_blocks & BIT(curve->header.type))) 1889 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_COMPAND_CTRL, 1890 + RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE); 1891 + } 1892 + 1893 + typedef void (*rkisp1_block_handler)(struct rkisp1_params *params, 1894 + const union rkisp1_ext_params_config *config); 1895 + 1896 + static const struct rkisp1_ext_params_handler { 1897 + size_t size; 1898 + rkisp1_block_handler handler; 1899 + unsigned int group; 1900 + unsigned int features; 1901 + } rkisp1_ext_params_handlers[] = { 1902 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = { 1903 + .size = sizeof(struct rkisp1_ext_params_bls_config), 1904 + .handler = rkisp1_ext_params_bls, 1905 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1906 + .features = RKISP1_FEATURE_BLS, 1907 + }, 1908 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = { 1909 + .size = sizeof(struct rkisp1_ext_params_dpcc_config), 1910 + .handler = rkisp1_ext_params_dpcc, 1911 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1912 + }, 1913 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = { 1914 + .size = sizeof(struct rkisp1_ext_params_sdg_config), 1915 + .handler = rkisp1_ext_params_sdg, 1916 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1917 + }, 1918 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = { 1919 + .size = sizeof(struct rkisp1_ext_params_awb_gain_config), 1920 + .handler = rkisp1_ext_params_awbg, 1921 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1922 + }, 1923 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = { 1924 + .size = sizeof(struct rkisp1_ext_params_flt_config), 1925 + .handler = rkisp1_ext_params_flt, 1926 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1927 + }, 1928 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = { 1929 + .size = sizeof(struct rkisp1_ext_params_bdm_config), 1930 + .handler = rkisp1_ext_params_bdm, 1931 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1932 + }, 1933 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = { 1934 + .size = sizeof(struct rkisp1_ext_params_ctk_config), 1935 + .handler = rkisp1_ext_params_ctk, 1936 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1937 + }, 1938 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = { 1939 + .size = sizeof(struct rkisp1_ext_params_goc_config), 1940 + .handler = rkisp1_ext_params_goc, 1941 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1942 + }, 1943 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = { 1944 + .size = sizeof(struct rkisp1_ext_params_dpf_config), 1945 + .handler = rkisp1_ext_params_dpf, 1946 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1947 + }, 1948 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = { 1949 + .size = sizeof(struct rkisp1_ext_params_dpf_strength_config), 1950 + .handler = rkisp1_ext_params_dpfs, 1951 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1952 + }, 1953 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = { 1954 + .size = sizeof(struct rkisp1_ext_params_cproc_config), 1955 + .handler = rkisp1_ext_params_cproc, 1956 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1957 + }, 1958 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = { 1959 + .size = sizeof(struct rkisp1_ext_params_ie_config), 1960 + .handler = rkisp1_ext_params_ie, 1961 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1962 + }, 1963 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = { 1964 + .size = sizeof(struct rkisp1_ext_params_lsc_config), 1965 + .handler = rkisp1_ext_params_lsc, 1966 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC, 1967 + }, 1968 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = { 1969 + .size = sizeof(struct rkisp1_ext_params_awb_meas_config), 1970 + .handler = rkisp1_ext_params_awbm, 1971 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1972 + }, 1973 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = { 1974 + .size = sizeof(struct rkisp1_ext_params_hst_config), 1975 + .handler = rkisp1_ext_params_hstm, 1976 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1977 + }, 1978 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = { 1979 + .size = sizeof(struct rkisp1_ext_params_aec_config), 1980 + .handler = rkisp1_ext_params_aecm, 1981 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1982 + }, 1983 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = { 1984 + .size = sizeof(struct rkisp1_ext_params_afc_config), 1985 + .handler = rkisp1_ext_params_afcm, 1986 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1987 + }, 1988 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = { 1989 + .size = sizeof(struct rkisp1_ext_params_compand_bls_config), 1990 + .handler = rkisp1_ext_params_compand_bls, 1991 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1992 + .features = RKISP1_FEATURE_COMPAND, 1993 + }, 1994 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = { 1995 + .size = sizeof(struct rkisp1_ext_params_compand_curve_config), 1996 + .handler = rkisp1_ext_params_compand_expand, 1997 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 1998 + .features = RKISP1_FEATURE_COMPAND, 1999 + }, 2000 + [RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = { 2001 + .size = sizeof(struct rkisp1_ext_params_compand_curve_config), 2002 + .handler = rkisp1_ext_params_compand_compress, 2003 + .group = RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS, 2004 + .features = RKISP1_FEATURE_COMPAND, 2005 + }, 2006 + }; 2007 + 2008 + static void rkisp1_ext_params_config(struct rkisp1_params *params, 2009 + struct rkisp1_ext_params_cfg *cfg, 2010 + u32 block_group_mask) 2011 + { 2012 + size_t block_offset = 0; 2013 + 2014 + if (WARN_ON(!cfg)) 2015 + return; 2016 + 2017 + /* Walk the list of parameter blocks and process them. */ 2018 + while (block_offset < cfg->data_size) { 2019 + const struct rkisp1_ext_params_handler *block_handler; 2020 + const union rkisp1_ext_params_config *block; 2021 + 2022 + block = (const union rkisp1_ext_params_config *) 2023 + &cfg->data[block_offset]; 2024 + block_offset += block->header.size; 2025 + 2026 + /* 2027 + * Make sure the block is supported by the platform and in the 2028 + * list of groups to configure. 2029 + */ 2030 + block_handler = &rkisp1_ext_params_handlers[block->header.type]; 2031 + if (!(block_handler->group & block_group_mask)) 2032 + continue; 2033 + 2034 + if ((params->rkisp1->info->features & block_handler->features) != 2035 + block_handler->features) 2036 + continue; 2037 + 2038 + block_handler->handler(params, block); 2039 + 2040 + if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE) 2041 + params->enabled_blocks &= ~BIT(block->header.type); 2042 + else if (block->header.flags & RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE) 2043 + params->enabled_blocks |= BIT(block->header.type); 2044 + } 1630 2045 } 1631 2046 1632 2047 static void rkisp1_params_complete_buffer(struct rkisp1_params *params, 1633 - struct rkisp1_buffer *buf, 2048 + struct rkisp1_params_buffer *buf, 1634 2049 unsigned int frame_sequence) 1635 2050 { 1636 2051 list_del(&buf->queue); ··· 2172 1527 void rkisp1_params_isr(struct rkisp1_device *rkisp1) 2173 1528 { 2174 1529 struct rkisp1_params *params = &rkisp1->params; 2175 - struct rkisp1_params_cfg *new_params; 2176 - struct rkisp1_buffer *cur_buf; 1530 + struct rkisp1_params_buffer *cur_buf; 2177 1531 2178 1532 spin_lock(&params->config_lock); 2179 1533 2180 - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1534 + cur_buf = list_first_entry_or_null(&params->params, 1535 + struct rkisp1_params_buffer, queue); 1536 + if (!cur_buf) 2181 1537 goto unlock; 2182 1538 2183 - rkisp1_isp_isr_other_config(params, new_params); 2184 - rkisp1_isp_isr_lsc_config(params, new_params); 2185 - rkisp1_isp_isr_meas_config(params, new_params); 1539 + if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { 1540 + rkisp1_isp_isr_other_config(params, cur_buf->cfg); 1541 + rkisp1_isp_isr_lsc_config(params, cur_buf->cfg); 1542 + rkisp1_isp_isr_meas_config(params, cur_buf->cfg); 1543 + } else { 1544 + rkisp1_ext_params_config(params, cur_buf->cfg, 1545 + RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS | 1546 + RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); 1547 + } 2186 1548 2187 1549 /* update shadow register immediately */ 2188 1550 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, ··· 2255 1603 enum v4l2_ycbcr_encoding ycbcr_encoding) 2256 1604 { 2257 1605 struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; 2258 - struct rkisp1_params_cfg *new_params; 2259 - struct rkisp1_buffer *cur_buf; 1606 + struct rkisp1_params_buffer *cur_buf; 2260 1607 2261 1608 params->quantization = quantization; 2262 1609 params->ycbcr_encoding = ycbcr_encoding; ··· 2284 1633 2285 1634 /* apply the first buffer if there is one already */ 2286 1635 2287 - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1636 + cur_buf = list_first_entry_or_null(&params->params, 1637 + struct rkisp1_params_buffer, queue); 1638 + if (!cur_buf) 2288 1639 goto unlock; 2289 1640 2290 - rkisp1_isp_isr_other_config(params, new_params); 2291 - rkisp1_isp_isr_meas_config(params, new_params); 1641 + if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) { 1642 + rkisp1_isp_isr_other_config(params, cur_buf->cfg); 1643 + rkisp1_isp_isr_meas_config(params, cur_buf->cfg); 1644 + } else { 1645 + rkisp1_ext_params_config(params, cur_buf->cfg, 1646 + RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS); 1647 + } 2292 1648 2293 1649 /* update shadow register immediately */ 2294 1650 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, ··· 2307 1649 2308 1650 void rkisp1_params_post_configure(struct rkisp1_params *params) 2309 1651 { 2310 - struct rkisp1_params_cfg *new_params; 2311 - struct rkisp1_buffer *cur_buf; 1652 + struct rkisp1_params_buffer *cur_buf; 2312 1653 2313 1654 spin_lock_irq(&params->config_lock); 2314 1655 ··· 2319 1662 * ordering doesn't affect other ISP versions negatively, do so 2320 1663 * unconditionally. 2321 1664 */ 2322 - 2323 - if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1665 + cur_buf = list_first_entry_or_null(&params->params, 1666 + struct rkisp1_params_buffer, queue); 1667 + if (!cur_buf) 2324 1668 goto unlock; 2325 1669 2326 - rkisp1_isp_isr_lsc_config(params, new_params); 1670 + if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_PARAMS) 1671 + rkisp1_isp_isr_lsc_config(params, cur_buf->cfg); 1672 + else 1673 + rkisp1_ext_params_config(params, cur_buf->cfg, 1674 + RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC); 2327 1675 2328 1676 /* update shadow register immediately */ 2329 1677 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, ··· 2404 1742 struct v4l2_fmtdesc *f) 2405 1743 { 2406 1744 struct video_device *video = video_devdata(file); 2407 - struct rkisp1_params *params = video_get_drvdata(video); 2408 1745 2409 - if (f->index > 0 || f->type != video->queue->type) 1746 + if (f->index >= ARRAY_SIZE(rkisp1_params_formats) || 1747 + f->type != video->queue->type) 2410 1748 return -EINVAL; 2411 1749 2412 - f->pixelformat = params->vdev_fmt.fmt.meta.dataformat; 1750 + f->pixelformat = rkisp1_params_formats[f->index].dataformat; 2413 1751 2414 1752 return 0; 2415 1753 } ··· 2424 1762 if (f->type != video->queue->type) 2425 1763 return -EINVAL; 2426 1764 2427 - memset(meta, 0, sizeof(*meta)); 2428 - meta->dataformat = params->vdev_fmt.fmt.meta.dataformat; 2429 - meta->buffersize = params->vdev_fmt.fmt.meta.buffersize; 1765 + *meta = *params->metafmt; 1766 + 1767 + return 0; 1768 + } 1769 + 1770 + static int rkisp1_params_try_fmt_meta_out(struct file *file, void *fh, 1771 + struct v4l2_format *f) 1772 + { 1773 + struct video_device *video = video_devdata(file); 1774 + struct v4l2_meta_format *meta = &f->fmt.meta; 1775 + 1776 + if (f->type != video->queue->type) 1777 + return -EINVAL; 1778 + 1779 + *meta = *rkisp1_params_get_format_info(meta->dataformat); 1780 + 1781 + return 0; 1782 + } 1783 + 1784 + static int rkisp1_params_s_fmt_meta_out(struct file *file, void *fh, 1785 + struct v4l2_format *f) 1786 + { 1787 + struct video_device *video = video_devdata(file); 1788 + struct rkisp1_params *params = video_get_drvdata(video); 1789 + struct v4l2_meta_format *meta = &f->fmt.meta; 1790 + 1791 + if (f->type != video->queue->type) 1792 + return -EINVAL; 1793 + 1794 + if (vb2_is_busy(video->queue)) 1795 + return -EBUSY; 1796 + 1797 + params->metafmt = rkisp1_params_get_format_info(meta->dataformat); 1798 + *meta = *params->metafmt; 2430 1799 2431 1800 return 0; 2432 1801 } ··· 2487 1794 .vidioc_streamoff = vb2_ioctl_streamoff, 2488 1795 .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out, 2489 1796 .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out, 2490 - .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out, 2491 - .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out, 1797 + .vidioc_s_fmt_meta_out = rkisp1_params_s_fmt_meta_out, 1798 + .vidioc_try_fmt_meta_out = rkisp1_params_try_fmt_meta_out, 2492 1799 .vidioc_querycap = rkisp1_params_querycap, 2493 1800 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 2494 1801 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, ··· 2500 1807 unsigned int sizes[], 2501 1808 struct device *alloc_devs[]) 2502 1809 { 1810 + struct rkisp1_params *params = vq->drv_priv; 1811 + 2503 1812 *num_buffers = clamp_t(u32, *num_buffers, 2504 1813 RKISP1_ISP_PARAMS_REQ_BUFS_MIN, 2505 1814 RKISP1_ISP_PARAMS_REQ_BUFS_MAX); 2506 1815 2507 1816 *num_planes = 1; 2508 1817 2509 - sizes[0] = sizeof(struct rkisp1_params_cfg); 1818 + sizes[0] = params->metafmt->buffersize; 2510 1819 2511 1820 return 0; 1821 + } 1822 + 1823 + static int rkisp1_params_vb2_buf_init(struct vb2_buffer *vb) 1824 + { 1825 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1826 + struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 1827 + struct rkisp1_params *params = vb->vb2_queue->drv_priv; 1828 + 1829 + params_buf->cfg = kvmalloc(params->metafmt->buffersize, 1830 + GFP_KERNEL); 1831 + if (!params_buf->cfg) 1832 + return -ENOMEM; 1833 + 1834 + return 0; 1835 + } 1836 + 1837 + static void rkisp1_params_vb2_buf_cleanup(struct vb2_buffer *vb) 1838 + { 1839 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1840 + struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 1841 + 1842 + kvfree(params_buf->cfg); 1843 + params_buf->cfg = NULL; 2512 1844 } 2513 1845 2514 1846 static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) 2515 1847 { 2516 1848 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 2517 - struct rkisp1_buffer *params_buf = 2518 - container_of(vbuf, struct rkisp1_buffer, vb); 1849 + struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 2519 1850 struct vb2_queue *vq = vb->vb2_queue; 2520 1851 struct rkisp1_params *params = vq->drv_priv; 2521 1852 ··· 2548 1831 spin_unlock_irq(&params->config_lock); 2549 1832 } 2550 1833 1834 + static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params, 1835 + struct vb2_buffer *vb) 1836 + { 1837 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1838 + struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 1839 + size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data); 1840 + struct rkisp1_ext_params_cfg *cfg = params_buf->cfg; 1841 + size_t payload_size = vb2_get_plane_payload(vb, 0); 1842 + struct rkisp1_ext_params_cfg *usr_cfg = 1843 + vb2_plane_vaddr(&vbuf->vb2_buf, 0); 1844 + size_t block_offset = 0; 1845 + size_t cfg_size; 1846 + 1847 + /* 1848 + * Validate the buffer payload size before copying the parameters. The 1849 + * payload has to be smaller than the destination buffer size and larger 1850 + * than the header size. 1851 + */ 1852 + if (payload_size > params->metafmt->buffersize) { 1853 + dev_dbg(params->rkisp1->dev, 1854 + "Too large buffer payload size %zu\n", payload_size); 1855 + return -EINVAL; 1856 + } 1857 + 1858 + if (payload_size < header_size) { 1859 + dev_dbg(params->rkisp1->dev, 1860 + "Buffer payload %zu smaller than header size %zu\n", 1861 + payload_size, header_size); 1862 + return -EINVAL; 1863 + } 1864 + 1865 + /* 1866 + * Copy the parameters buffer to the internal scratch buffer to avoid 1867 + * userspace modifying the buffer content while the driver processes it. 1868 + */ 1869 + memcpy(cfg, usr_cfg, payload_size); 1870 + 1871 + /* Only v1 is supported at the moment. */ 1872 + if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) { 1873 + dev_dbg(params->rkisp1->dev, 1874 + "Unsupported extensible format version: %u\n", 1875 + cfg->version); 1876 + return -EINVAL; 1877 + } 1878 + 1879 + /* Validate the size reported in the parameters buffer header. */ 1880 + cfg_size = header_size + cfg->data_size; 1881 + if (cfg_size != payload_size) { 1882 + dev_dbg(params->rkisp1->dev, 1883 + "Data size %zu different than buffer payload size %zu\n", 1884 + cfg_size, payload_size); 1885 + return -EINVAL; 1886 + } 1887 + 1888 + /* Walk the list of parameter blocks and validate them. */ 1889 + cfg_size = cfg->data_size; 1890 + while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) { 1891 + const struct rkisp1_ext_params_block_header *block; 1892 + const struct rkisp1_ext_params_handler *handler; 1893 + 1894 + block = (const struct rkisp1_ext_params_block_header *) 1895 + &cfg->data[block_offset]; 1896 + 1897 + if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) { 1898 + dev_dbg(params->rkisp1->dev, 1899 + "Invalid parameters block type\n"); 1900 + return -EINVAL; 1901 + } 1902 + 1903 + if (block->size > cfg_size) { 1904 + dev_dbg(params->rkisp1->dev, 1905 + "Premature end of parameters data\n"); 1906 + return -EINVAL; 1907 + } 1908 + 1909 + if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE | 1910 + RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) == 1911 + (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE | 1912 + RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) { 1913 + dev_dbg(params->rkisp1->dev, 1914 + "Invalid parameters block flags\n"); 1915 + return -EINVAL; 1916 + } 1917 + 1918 + handler = &rkisp1_ext_params_handlers[block->type]; 1919 + if (block->size != handler->size) { 1920 + dev_dbg(params->rkisp1->dev, 1921 + "Invalid parameters block size\n"); 1922 + return -EINVAL; 1923 + } 1924 + 1925 + block_offset += block->size; 1926 + cfg_size -= block->size; 1927 + } 1928 + 1929 + if (cfg_size) { 1930 + dev_dbg(params->rkisp1->dev, 1931 + "Unexpected data after the parameters buffer end\n"); 1932 + return -EINVAL; 1933 + } 1934 + 1935 + return 0; 1936 + } 1937 + 2551 1938 static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb) 2552 1939 { 2553 - if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg)) 1940 + struct rkisp1_params *params = vb->vb2_queue->drv_priv; 1941 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1942 + struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf); 1943 + struct rkisp1_params_cfg *cfg = vb2_plane_vaddr(&vbuf->vb2_buf, 0); 1944 + size_t payload = vb2_get_plane_payload(vb, 0); 1945 + 1946 + if (params->metafmt->dataformat == V4L2_META_FMT_RK_ISP1_EXT_PARAMS) 1947 + return rkisp1_params_prepare_ext_params(params, vb); 1948 + 1949 + /* 1950 + * For the fixed parameters format the payload size must be exactly the 1951 + * size of the parameters structure. 1952 + */ 1953 + if (payload != sizeof(*cfg)) 2554 1954 return -EINVAL; 2555 1955 2556 - vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg)); 1956 + /* 1957 + * Copy the parameters buffer to the internal scratch buffer to avoid 1958 + * userspace modifying the buffer content while the driver processes it. 1959 + */ 1960 + memcpy(params_buf->cfg, cfg, payload); 2557 1961 2558 1962 return 0; 2559 1963 } ··· 2682 1844 static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) 2683 1845 { 2684 1846 struct rkisp1_params *params = vq->drv_priv; 2685 - struct rkisp1_buffer *buf; 1847 + struct rkisp1_params_buffer *buf; 2686 1848 LIST_HEAD(tmp_list); 2687 1849 2688 1850 /* ··· 2696 1858 2697 1859 list_for_each_entry(buf, &tmp_list, queue) 2698 1860 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 1861 + 1862 + params->enabled_blocks = 0; 2699 1863 } 2700 1864 2701 1865 static const struct vb2_ops rkisp1_params_vb2_ops = { 2702 1866 .queue_setup = rkisp1_params_vb2_queue_setup, 1867 + .buf_init = rkisp1_params_vb2_buf_init, 1868 + .buf_cleanup = rkisp1_params_vb2_buf_cleanup, 2703 1869 .wait_prepare = vb2_ops_wait_prepare, 2704 1870 .wait_finish = vb2_ops_wait_finish, 2705 1871 .buf_queue = rkisp1_params_vb2_buf_queue, 2706 1872 .buf_prepare = rkisp1_params_vb2_buf_prepare, 2707 1873 .stop_streaming = rkisp1_params_vb2_stop_streaming, 2708 - 2709 1874 }; 2710 1875 2711 1876 static const struct v4l2_file_operations rkisp1_params_fops = { ··· 2731 1890 q->drv_priv = params; 2732 1891 q->ops = &rkisp1_params_vb2_ops; 2733 1892 q->mem_ops = &vb2_vmalloc_memops; 2734 - q->buf_struct_size = sizeof(struct rkisp1_buffer); 1893 + q->buf_struct_size = sizeof(struct rkisp1_params_buffer); 2735 1894 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 2736 1895 q->lock = &node->vlock; 2737 1896 2738 1897 return vb2_queue_init(q); 2739 - } 2740 - 2741 - static void rkisp1_init_params(struct rkisp1_params *params) 2742 - { 2743 - params->vdev_fmt.fmt.meta.dataformat = 2744 - V4L2_META_FMT_RK_ISP1_PARAMS; 2745 - params->vdev_fmt.fmt.meta.buffersize = 2746 - sizeof(struct rkisp1_params_cfg); 2747 - 2748 - if (params->rkisp1->info->isp_ver == RKISP1_V12) 2749 - params->ops = &rkisp1_v12_params_ops; 2750 - else 2751 - params->ops = &rkisp1_v10_params_ops; 2752 1898 } 2753 1899 2754 1900 int rkisp1_params_register(struct rkisp1_device *rkisp1) ··· 2766 1938 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT; 2767 1939 vdev->vfl_dir = VFL_DIR_TX; 2768 1940 rkisp1_params_init_vb2_queue(vdev->queue, params); 2769 - rkisp1_init_params(params); 1941 + 1942 + params->metafmt = &rkisp1_params_formats[RKISP1_PARAMS_FIXED]; 1943 + 1944 + if (params->rkisp1->info->isp_ver == RKISP1_V12) 1945 + params->ops = &rkisp1_v12_params_ops; 1946 + else 1947 + params->ops = &rkisp1_v10_params_ops; 1948 + 2770 1949 video_set_drvdata(vdev, params); 2771 1950 2772 1951 node->pad.flags = MEDIA_PAD_FL_SOURCE;
+23
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
··· 704 704 #define RKISP1_CIF_ISP_DPF_SPATIAL_COEFF_MAX 0x1f 705 705 #define RKISP1_CIF_ISP_DPF_NLL_COEFF_N_MAX 0x3ff 706 706 707 + /* COMPAND */ 708 + #define RKISP1_CIF_ISP_COMPAND_CTRL_EXPAND_ENABLE BIT(0) 709 + #define RKISP1_CIF_ISP_COMPAND_CTRL_COMPRESS_ENABLE BIT(1) 710 + #define RKISP1_CIF_ISP_COMPAND_CTRL_SOFT_RESET_FLAG BIT(2) 711 + #define RKISP1_CIF_ISP_COMPAND_CTRL_BLS_ENABLE BIT(3) 712 + 707 713 /* =================================================================== */ 708 714 /* CIF Registers */ 709 715 /* =================================================================== */ ··· 1399 1393 #define RKISP1_CIF_ISP_VSM_V_SEGMENTS (RKISP1_CIF_ISP_VSM_BASE + 0x00000018) 1400 1394 #define RKISP1_CIF_ISP_VSM_DELTA_H (RKISP1_CIF_ISP_VSM_BASE + 0x0000001c) 1401 1395 #define RKISP1_CIF_ISP_VSM_DELTA_V (RKISP1_CIF_ISP_VSM_BASE + 0x00000020) 1396 + 1397 + #define RKISP1_CIF_ISP_COMPAND_BASE 0x00003200 1398 + #define RKISP1_CIF_ISP_COMPAND_CTRL (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000000) 1399 + #define RKISP1_CIF_ISP_COMPAND_BLS_A_FIXED (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000004) 1400 + #define RKISP1_CIF_ISP_COMPAND_BLS_B_FIXED (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000008) 1401 + #define RKISP1_CIF_ISP_COMPAND_BLS_C_FIXED (RKISP1_CIF_ISP_COMPAND_BASE + 0x0000000c) 1402 + #define RKISP1_CIF_ISP_COMPAND_BLS_D_FIXED (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000010) 1403 + #define RKISP1_CIF_ISP_COMPAND_EXPAND_PX_N(n) (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000014 + (n) * 4) 1404 + #define RKISP1_CIF_ISP_COMPAND_COMPRESS_PX_N(n) (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000040 + (n) * 4) 1405 + #define RKISP1_CIF_ISP_COMPAND_EXPAND_Y_ADDR (RKISP1_CIF_ISP_COMPAND_BASE + 0x0000006c) 1406 + #define RKISP1_CIF_ISP_COMPAND_EXPAND_Y_WRITE_DATA (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000070) 1407 + #define RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_ADDR (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000074) 1408 + #define RKISP1_CIF_ISP_COMPAND_COMPRESS_Y_WRITE_DATA (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000078) 1409 + #define RKISP1_CIF_ISP_COMPAND_EXPAND_X_ADDR (RKISP1_CIF_ISP_COMPAND_BASE + 0x0000007c) 1410 + #define RKISP1_CIF_ISP_COMPAND_EXPAND_X_WRITE_DATA (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000080) 1411 + #define RKISP1_CIF_ISP_COMPAND_COMPRESS_X_ADDR (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000084) 1412 + #define RKISP1_CIF_ISP_COMPAND_COMPRESS_X_WRITE_DATA (RKISP1_CIF_ISP_COMPAND_BASE + 0x00000088) 1402 1413 1403 1414 #define RKISP1_CIF_ISP_CSI0_BASE 0x00007000 1404 1415 #define RKISP1_CIF_ISP_CSI0_CTRL0 (RKISP1_CIF_ISP_CSI0_BASE + 0x00000000)
+2 -2
drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
··· 494 494 495 495 sink_fmt->width = clamp_t(u32, format->width, 496 496 RKISP1_ISP_MIN_WIDTH, 497 - RKISP1_ISP_MAX_WIDTH); 497 + rsz->rkisp1->info->max_width); 498 498 sink_fmt->height = clamp_t(u32, format->height, 499 499 RKISP1_ISP_MIN_HEIGHT, 500 - RKISP1_ISP_MAX_HEIGHT); 500 + rsz->rkisp1->info->max_height); 501 501 502 502 /* 503 503 * Adjust the color space fields. Accept any color primaries and
+14 -37
drivers/media/platform/rockchip/rkisp1/rkisp1-stats.c
··· 304 304 static void rkisp1_stats_get_bls_meas(struct rkisp1_stats *stats, 305 305 struct rkisp1_stat_buffer *pbuf) 306 306 { 307 + static const u32 regs[] = { 308 + RKISP1_CIF_ISP_BLS_A_MEASURED, 309 + RKISP1_CIF_ISP_BLS_B_MEASURED, 310 + RKISP1_CIF_ISP_BLS_C_MEASURED, 311 + RKISP1_CIF_ISP_BLS_D_MEASURED, 312 + }; 307 313 struct rkisp1_device *rkisp1 = stats->rkisp1; 308 314 const struct rkisp1_mbus_info *in_fmt = rkisp1->isp.sink_fmt; 309 315 struct rkisp1_cif_isp_bls_meas_val *bls_val; 316 + u32 swapped[4]; 317 + 318 + rkisp1_bls_swap_regs(in_fmt->bayer_pat, regs, swapped); 310 319 311 320 bls_val = &pbuf->params.ae.bls_val; 312 - if (in_fmt->bayer_pat == RKISP1_RAW_BGGR) { 313 - bls_val->meas_b = 314 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED); 315 - bls_val->meas_gb = 316 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED); 317 - bls_val->meas_gr = 318 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED); 319 - bls_val->meas_r = 320 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED); 321 - } else if (in_fmt->bayer_pat == RKISP1_RAW_GBRG) { 322 - bls_val->meas_gb = 323 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED); 324 - bls_val->meas_b = 325 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED); 326 - bls_val->meas_r = 327 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED); 328 - bls_val->meas_gr = 329 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED); 330 - } else if (in_fmt->bayer_pat == RKISP1_RAW_GRBG) { 331 - bls_val->meas_gr = 332 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED); 333 - bls_val->meas_r = 334 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED); 335 - bls_val->meas_b = 336 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED); 337 - bls_val->meas_gb = 338 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED); 339 - } else if (in_fmt->bayer_pat == RKISP1_RAW_RGGB) { 340 - bls_val->meas_r = 341 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_A_MEASURED); 342 - bls_val->meas_gr = 343 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_B_MEASURED); 344 - bls_val->meas_gb = 345 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_C_MEASURED); 346 - bls_val->meas_b = 347 - rkisp1_read(rkisp1, RKISP1_CIF_ISP_BLS_D_MEASURED); 348 - } 321 + 322 + bls_val->meas_r = rkisp1_read(rkisp1, swapped[0]); 323 + bls_val->meas_gr = rkisp1_read(rkisp1, swapped[1]); 324 + bls_val->meas_gb = rkisp1_read(rkisp1, swapped[2]); 325 + bls_val->meas_b = rkisp1_read(rkisp1, swapped[3]); 349 326 } 350 327 351 328 static const struct rkisp1_stats_ops rkisp1_v10_stats_ops = {
+5 -5
drivers/media/platform/samsung/exynos-gsc/gsc-core.c
··· 1225 1225 static int gsc_m2m_suspend(struct gsc_dev *gsc) 1226 1226 { 1227 1227 unsigned long flags; 1228 - int timeout; 1228 + long time_left; 1229 1229 1230 1230 spin_lock_irqsave(&gsc->slock, flags); 1231 1231 if (!gsc_m2m_pending(gsc)) { ··· 1236 1236 set_bit(ST_M2M_SUSPENDING, &gsc->state); 1237 1237 spin_unlock_irqrestore(&gsc->slock, flags); 1238 1238 1239 - timeout = wait_event_timeout(gsc->irq_queue, 1240 - test_bit(ST_M2M_SUSPENDED, &gsc->state), 1241 - GSC_SHUTDOWN_TIMEOUT); 1239 + time_left = wait_event_timeout(gsc->irq_queue, 1240 + test_bit(ST_M2M_SUSPENDED, &gsc->state), 1241 + GSC_SHUTDOWN_TIMEOUT); 1242 1242 1243 1243 clear_bit(ST_M2M_SUSPENDING, &gsc->state); 1244 - return timeout == 0 ? -EAGAIN : 0; 1244 + return time_left == 0 ? -EAGAIN : 0; 1245 1245 } 1246 1246 1247 1247 static void gsc_m2m_resume(struct gsc_dev *gsc)
+5 -5
drivers/media/platform/samsung/exynos4-is/fimc-core.c
··· 822 822 static int fimc_m2m_suspend(struct fimc_dev *fimc) 823 823 { 824 824 unsigned long flags; 825 - int timeout; 825 + long time_left; 826 826 827 827 spin_lock_irqsave(&fimc->slock, flags); 828 828 if (!fimc_m2m_pending(fimc)) { ··· 833 833 set_bit(ST_M2M_SUSPENDING, &fimc->state); 834 834 spin_unlock_irqrestore(&fimc->slock, flags); 835 835 836 - timeout = wait_event_timeout(fimc->irq_queue, 837 - test_bit(ST_M2M_SUSPENDED, &fimc->state), 838 - FIMC_SHUTDOWN_TIMEOUT); 836 + time_left = wait_event_timeout(fimc->irq_queue, 837 + test_bit(ST_M2M_SUSPENDED, &fimc->state), 838 + FIMC_SHUTDOWN_TIMEOUT); 839 839 840 840 clear_bit(ST_M2M_SUSPENDING, &fimc->state); 841 - return timeout == 0 ? -EAGAIN : 0; 841 + return time_left == 0 ? -EAGAIN : 0; 842 842 } 843 843 844 844 static int fimc_m2m_resume(struct fimc_dev *fimc)
+5 -5
drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c
··· 1160 1160 static int bdisp_m2m_suspend(struct bdisp_dev *bdisp) 1161 1161 { 1162 1162 unsigned long flags; 1163 - int timeout; 1163 + long time_left; 1164 1164 1165 1165 spin_lock_irqsave(&bdisp->slock, flags); 1166 1166 if (!test_bit(ST_M2M_RUNNING, &bdisp->state)) { ··· 1171 1171 set_bit(ST_M2M_SUSPENDING, &bdisp->state); 1172 1172 spin_unlock_irqrestore(&bdisp->slock, flags); 1173 1173 1174 - timeout = wait_event_timeout(bdisp->irq_queue, 1175 - test_bit(ST_M2M_SUSPENDED, &bdisp->state), 1176 - BDISP_WORK_TIMEOUT); 1174 + time_left = wait_event_timeout(bdisp->irq_queue, 1175 + test_bit(ST_M2M_SUSPENDED, &bdisp->state), 1176 + BDISP_WORK_TIMEOUT); 1177 1177 1178 1178 clear_bit(ST_M2M_SUSPENDING, &bdisp->state); 1179 1179 1180 - if (!timeout) { 1180 + if (!time_left) { 1181 1181 dev_err(bdisp->dev, "%s IRQ timeout\n", __func__); 1182 1182 return -EAGAIN; 1183 1183 }
+12
drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
··· 35 35 bool has_isp; 36 36 }; 37 37 38 + static int sun4i_csi_video_link_validate(struct media_link *link) 39 + { 40 + dev_warn_once(link->graph_obj.mdev->dev, 41 + "Driver bug: link validation not implemented\n"); 42 + return 0; 43 + } 44 + 38 45 static const struct media_entity_operations sun4i_csi_video_entity_ops = { 46 + .link_validate = sun4i_csi_video_link_validate, 47 + }; 48 + 49 + static const struct media_entity_operations sun4i_csi_subdev_entity_ops = { 39 50 .link_validate = v4l2_subdev_link_validate, 40 51 }; 41 52 ··· 225 214 subdev->internal_ops = &sun4i_csi_subdev_internal_ops; 226 215 subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; 227 216 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 217 + subdev->entity.ops = &sun4i_csi_subdev_entity_ops; 228 218 subdev->owner = THIS_MODULE; 229 219 snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0"); 230 220 v4l2_set_subdevdata(subdev, csi);
+5 -7
drivers/media/platform/ti/am437x/am437x-vpfe.c
··· 2287 2287 static struct vpfe_config * 2288 2288 vpfe_get_pdata(struct vpfe_device *vpfe) 2289 2289 { 2290 - struct device_node *endpoint = NULL; 2290 + struct device_node *endpoint; 2291 2291 struct device *dev = vpfe->pdev; 2292 2292 struct vpfe_subdev_info *sdinfo; 2293 2293 struct vpfe_config *pdata; ··· 2306 2306 if (!pdata) 2307 2307 return NULL; 2308 2308 2309 - for (i = 0; ; i++) { 2309 + i = 0; 2310 + for_each_endpoint_of_node(dev->of_node, endpoint) { 2310 2311 struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; 2311 2312 struct device_node *rem; 2312 - 2313 - endpoint = of_graph_get_next_endpoint(dev->of_node, endpoint); 2314 - if (!endpoint) 2315 - break; 2316 2313 2317 2314 sdinfo = &pdata->sub_devs[i]; 2318 2315 sdinfo->grp_id = 0; ··· 2368 2371 of_node_put(rem); 2369 2372 if (IS_ERR(pdata->asd[i])) 2370 2373 goto cleanup; 2374 + 2375 + i++; 2371 2376 } 2372 2377 2373 - of_node_put(endpoint); 2374 2378 return pdata; 2375 2379 2376 2380 cleanup:
+1 -1
drivers/media/platform/ti/cal/cal-camerarx.c
··· 798 798 .init_state = cal_camerarx_sd_init_state, 799 799 }; 800 800 801 - static struct media_entity_operations cal_camerarx_media_ops = { 801 + static const struct media_entity_operations cal_camerarx_media_ops = { 802 802 .link_validate = v4l2_subdev_link_validate, 803 803 }; 804 804
+4 -4
drivers/media/platform/ti/cal/cal.c
··· 549 549 void cal_ctx_stop(struct cal_ctx *ctx) 550 550 { 551 551 struct cal_camerarx *phy = ctx->phy; 552 - long timeout; 552 + long time_left; 553 553 554 554 WARN_ON(phy->vc_enable_count[ctx->vc] == 0); 555 555 ··· 565 565 ctx->dma.state = CAL_DMA_STOP_REQUESTED; 566 566 spin_unlock_irq(&ctx->dma.lock); 567 567 568 - timeout = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx), 569 - msecs_to_jiffies(500)); 570 - if (!timeout) { 568 + time_left = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx), 569 + msecs_to_jiffies(500)); 570 + if (!time_left) { 571 571 ctx_err(ctx, "failed to disable dma cleanly\n"); 572 572 cal_ctx_wr_dma_disable(ctx); 573 573 }
+7 -7
drivers/media/platform/ti/davinci/vpif_capture.c
··· 1487 1487 vpif_capture_get_pdata(struct platform_device *pdev, 1488 1488 struct v4l2_device *v4l2_dev) 1489 1489 { 1490 - struct device_node *endpoint = NULL; 1490 + struct device_node *endpoint; 1491 1491 struct device_node *rem = NULL; 1492 1492 struct vpif_capture_config *pdata; 1493 1493 struct vpif_subdev_info *sdinfo; ··· 1517 1517 if (!pdata->subdev_info) 1518 1518 return NULL; 1519 1519 1520 - for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) { 1520 + i = 0; 1521 + for_each_endpoint_of_node(pdev->dev.of_node, endpoint) { 1521 1522 struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; 1522 1523 unsigned int flags; 1523 1524 int err; 1524 - 1525 - endpoint = of_graph_get_next_endpoint(pdev->dev.of_node, 1526 - endpoint); 1527 - if (!endpoint) 1528 - break; 1529 1525 1530 1526 rem = of_graph_get_remote_port_parent(endpoint); 1531 1527 if (!rem) { ··· 1573 1577 goto err_cleanup; 1574 1578 1575 1579 of_node_put(rem); 1580 + 1581 + i++; 1582 + if (i >= VPIF_CAPTURE_NUM_CHANNELS) 1583 + break; 1576 1584 } 1577 1585 1578 1586 done:
+8
drivers/media/platform/verisilicon/Kconfig
··· 21 21 To compile this driver as a module, choose M here: the module 22 22 will be called hantro-vpu. 23 23 24 + config VIDEO_HANTRO_HEVC_RFC 25 + bool "Use reference frame compression for HEVC" 26 + depends on VIDEO_HANTRO 27 + default n 28 + help 29 + Enable the reference frame compression feature for the HEVC codec. 30 + It will use more memory but save bandwidth on memory bus. 31 + 24 32 config VIDEO_HANTRO_IMX8M 25 33 bool "Hantro VPU i.MX8M support" 26 34 depends on VIDEO_HANTRO
+7 -7
drivers/media/platform/verisilicon/Makefile
··· 14 14 hantro_g2.o \ 15 15 hantro_g2_hevc_dec.o \ 16 16 hantro_g2_vp9_dec.o \ 17 - rockchip_vpu2_hw_jpeg_enc.o \ 18 - rockchip_vpu2_hw_h264_dec.o \ 19 - rockchip_vpu2_hw_mpeg2_dec.o \ 20 - rockchip_vpu2_hw_vp8_dec.o \ 21 - rockchip_vpu981_hw_av1_dec.o \ 22 - rockchip_av1_filmgrain.o \ 23 - rockchip_av1_entropymode.o \ 24 17 hantro_jpeg.o \ 25 18 hantro_h264.o \ 26 19 hantro_hevc.o \ ··· 28 35 sama5d4_vdec_hw.o 29 36 30 37 hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ 38 + rockchip_vpu2_hw_jpeg_enc.o \ 39 + rockchip_vpu2_hw_h264_dec.o \ 40 + rockchip_vpu2_hw_mpeg2_dec.o \ 41 + rockchip_vpu2_hw_vp8_dec.o \ 42 + rockchip_vpu981_hw_av1_dec.o \ 43 + rockchip_av1_filmgrain.o \ 44 + rockchip_av1_entropymode.o \ 31 45 rockchip_vpu_hw.o 32 46 33 47 hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \
+48
drivers/media/platform/verisilicon/hantro_drv.c
··· 722 722 { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, 723 723 { .compatible = "rockchip,rk3568-vepu", .data = &rk3568_vepu_variant, }, 724 724 { .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, }, 725 + { .compatible = "rockchip,rk3588-vepu121", .data = &rk3568_vepu_variant, }, 725 726 { .compatible = "rockchip,rk3588-av1-vpu", .data = &rk3588_vpu981_variant, }, 726 727 #endif 727 728 #ifdef CONFIG_VIDEO_HANTRO_IMX8M ··· 993 992 .req_queue = v4l2_m2m_request_queue, 994 993 }; 995 994 995 + /* 996 + * Some SoCs, like RK3588 have multiple identical Hantro cores, but the 997 + * kernel is currently missing support for multi-core handling. Exposing 998 + * separate devices for each core to userspace is bad, since that does 999 + * not allow scheduling tasks properly (and creates ABI). With this workaround 1000 + * the driver will only probe for the first core and early exit for the other 1001 + * cores. Once the driver gains multi-core support, the same technique 1002 + * for detecting the main core can be used to cluster all cores together. 1003 + */ 1004 + static int hantro_disable_multicore(struct hantro_dev *vpu) 1005 + { 1006 + struct device_node *node = NULL; 1007 + const char *compatible; 1008 + bool is_main_core; 1009 + int ret; 1010 + 1011 + /* Intentionally ignores the fallback strings */ 1012 + ret = of_property_read_string(vpu->dev->of_node, "compatible", &compatible); 1013 + if (ret) 1014 + return ret; 1015 + 1016 + /* The first compatible and available node found is considered the main core */ 1017 + do { 1018 + node = of_find_compatible_node(node, NULL, compatible); 1019 + if (of_device_is_available(node)) 1020 + break; 1021 + } while (node); 1022 + 1023 + if (!node) 1024 + return -EINVAL; 1025 + 1026 + is_main_core = (vpu->dev->of_node == node); 1027 + 1028 + of_node_put(node); 1029 + 1030 + if (!is_main_core) { 1031 + dev_info(vpu->dev, "missing multi-core support, ignoring this instance\n"); 1032 + return -ENODEV; 1033 + } 1034 + 1035 + return 0; 1036 + } 1037 + 996 1038 static int hantro_probe(struct platform_device *pdev) 997 1039 { 998 1040 const struct of_device_id *match; ··· 1054 1010 1055 1011 match = of_match_node(of_hantro_match, pdev->dev.of_node); 1056 1012 vpu->variant = match->data; 1013 + 1014 + ret = hantro_disable_multicore(vpu); 1015 + if (ret) 1016 + return ret; 1057 1017 1058 1018 /* 1059 1019 * Support for nxp,imx8mq-vpu is kept for backwards compatibility
+29
drivers/media/platform/verisilicon/hantro_g2.c
··· 56 56 57 57 return ALIGN((cr_offset * 3) / 2, G2_ALIGN); 58 58 } 59 + 60 + static size_t hantro_g2_mv_size(struct hantro_ctx *ctx) 61 + { 62 + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; 63 + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; 64 + unsigned int pic_width_in_ctbs, pic_height_in_ctbs; 65 + unsigned int max_log2_ctb_size; 66 + 67 + max_log2_ctb_size = sps->log2_min_luma_coding_block_size_minus3 + 3 + 68 + sps->log2_diff_max_min_luma_coding_block_size; 69 + pic_width_in_ctbs = (sps->pic_width_in_luma_samples + 70 + (1 << max_log2_ctb_size) - 1) >> max_log2_ctb_size; 71 + pic_height_in_ctbs = (sps->pic_height_in_luma_samples + (1 << max_log2_ctb_size) - 1) 72 + >> max_log2_ctb_size; 73 + 74 + return pic_width_in_ctbs * pic_height_in_ctbs * (1 << (2 * (max_log2_ctb_size - 4))) * 16; 75 + } 76 + 77 + size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx) 78 + { 79 + return hantro_g2_motion_vectors_offset(ctx) + 80 + hantro_g2_mv_size(ctx); 81 + } 82 + 83 + size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx) 84 + { 85 + return hantro_g2_luma_compress_offset(ctx) + 86 + hantro_hevc_luma_compressed_size(ctx->dst_fmt.width, ctx->dst_fmt.height); 87 + }
+17 -3
drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
··· 367 367 const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; 368 368 const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb; 369 369 dma_addr_t luma_addr, chroma_addr, mv_addr = 0; 370 + dma_addr_t compress_luma_addr, compress_chroma_addr = 0; 370 371 struct hantro_dev *vpu = ctx->dev; 371 372 struct vb2_v4l2_buffer *vb2_dst; 372 373 struct hantro_decoded_buffer *dst; 373 374 size_t cr_offset = hantro_g2_chroma_offset(ctx); 374 375 size_t mv_offset = hantro_g2_motion_vectors_offset(ctx); 376 + size_t compress_luma_offset = hantro_g2_luma_compress_offset(ctx); 377 + size_t compress_chroma_offset = hantro_g2_chroma_compress_offset(ctx); 375 378 u32 max_ref_frames; 376 379 u16 dpb_longterm_e; 377 380 static const struct hantro_reg cur_poc[] = { ··· 448 445 449 446 chroma_addr = luma_addr + cr_offset; 450 447 mv_addr = luma_addr + mv_offset; 448 + compress_luma_addr = luma_addr + compress_luma_offset; 449 + compress_chroma_addr = luma_addr + compress_chroma_offset; 451 450 452 451 if (dpb[i].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE) 453 452 dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i); ··· 457 452 hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr); 458 453 hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr); 459 454 hantro_write_addr(vpu, G2_REF_MV_ADDR(i), mv_addr); 455 + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), compress_luma_addr); 456 + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i), compress_chroma_addr); 460 457 } 461 458 462 459 vb2_dst = hantro_get_dst_buf(ctx); ··· 472 465 473 466 chroma_addr = luma_addr + cr_offset; 474 467 mv_addr = luma_addr + mv_offset; 468 + compress_luma_addr = luma_addr + compress_luma_offset; 469 + compress_chroma_addr = luma_addr + compress_chroma_offset; 475 470 476 471 hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr); 477 472 hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr); 478 - hantro_write_addr(vpu, G2_REF_MV_ADDR(i++), mv_addr); 473 + hantro_write_addr(vpu, G2_REF_MV_ADDR(i), mv_addr); 474 + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), compress_luma_addr); 475 + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i++), compress_chroma_addr); 479 476 480 477 hantro_write_addr(vpu, G2_OUT_LUMA_ADDR, luma_addr); 481 478 hantro_write_addr(vpu, G2_OUT_CHROMA_ADDR, chroma_addr); 482 479 hantro_write_addr(vpu, G2_OUT_MV_ADDR, mv_addr); 480 + hantro_write_addr(vpu, G2_OUT_COMP_LUMA_ADDR, compress_luma_addr); 481 + hantro_write_addr(vpu, G2_OUT_COMP_CHROMA_ADDR, compress_chroma_addr); 483 482 484 483 for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { 485 484 hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), 0); 486 485 hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), 0); 487 486 hantro_write_addr(vpu, G2_REF_MV_ADDR(i), 0); 487 + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), 0); 488 + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i), 0); 488 489 } 489 490 490 491 hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e); ··· 609 594 /* Don't disable output */ 610 595 hantro_reg_write(vpu, &g2_out_dis, 0); 611 596 612 - /* Don't compress buffers */ 613 - hantro_reg_write(vpu, &g2_ref_compress_bypass, 1); 597 + hantro_reg_write(vpu, &g2_ref_compress_bypass, !ctx->hevc_dec.use_compression); 614 598 615 599 /* Bus width and max burst */ 616 600 hantro_reg_write(vpu, &g2_buswidth, BUS_WIDTH_128);
+4
drivers/media/platform/verisilicon/hantro_g2_regs.h
··· 318 318 #define G2_TILE_BSD_ADDR (G2_SWREG(183)) 319 319 #define G2_DS_DST (G2_SWREG(186)) 320 320 #define G2_DS_DST_CHR (G2_SWREG(188)) 321 + #define G2_OUT_COMP_LUMA_ADDR (G2_SWREG(190)) 322 + #define G2_REF_COMP_LUMA_ADDR(i) (G2_SWREG(192) + ((i) * 0x8)) 323 + #define G2_OUT_COMP_CHROMA_ADDR (G2_SWREG(224)) 324 + #define G2_REF_COMP_CHROMA_ADDR(i) (G2_SWREG(226) + ((i) * 0x8)) 321 325 322 326 #define g2_strm_buffer_len G2_DEC_REG(258, 0, 0xffffffff) 323 327 #define g2_strm_start_offset G2_DEC_REG(259, 0, 0xffffffff)
+8
drivers/media/platform/verisilicon/hantro_hevc.c
··· 25 25 #define MAX_TILE_COLS 20 26 26 #define MAX_TILE_ROWS 22 27 27 28 + static bool hevc_use_compression = IS_ENABLED(CONFIG_VIDEO_HANTRO_HEVC_RFC); 29 + module_param_named(hevc_use_compression, hevc_use_compression, bool, 0644); 30 + MODULE_PARM_DESC(hevc_use_compression, 31 + "Use reference frame compression for HEVC"); 32 + 28 33 void hantro_hevc_ref_init(struct hantro_ctx *ctx) 29 34 { 30 35 struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; ··· 279 274 hevc_dec->scaling_lists.size = SCALING_LIST_SIZE; 280 275 281 276 hantro_hevc_ref_init(ctx); 277 + 278 + hevc_dec->use_compression = 279 + hevc_use_compression & hantro_needs_postproc(ctx, ctx->vpu_dst_fmt); 282 280 283 281 return 0; 284 282 }
+38
drivers/media/platform/verisilicon/hantro_hw.h
··· 42 42 43 43 #define MAX_POSTPROC_BUFFERS 64 44 44 45 + #define CBS_SIZE 16 /* compression table size in bytes */ 46 + #define CBS_LUMA 8 /* luminance CBS is composed of 1 8x8 coded block */ 47 + #define CBS_CHROMA_W (8 * 2) /* chrominance CBS is composed of two 8x4 coded 48 + * blocks, with Cb CB first then Cr CB following 49 + */ 50 + #define CBS_CHROMA_H 4 51 + 45 52 struct hantro_dev; 46 53 struct hantro_ctx; 47 54 struct hantro_buf; ··· 151 144 * @ref_bufs_used: Bitfield of used reference buffers 152 145 * @ctrls: V4L2 controls attached to a run 153 146 * @num_tile_cols_allocated: number of allocated tiles 147 + * @use_compression: use reference buffer compression 154 148 */ 155 149 struct hantro_hevc_dec_hw_ctx { 156 150 struct hantro_aux_buf tile_sizes; ··· 164 156 u32 ref_bufs_used; 165 157 struct hantro_hevc_dec_ctrls ctrls; 166 158 unsigned int num_tile_cols_allocated; 159 + bool use_compression; 167 160 }; 168 161 169 162 /** ··· 519 510 return width * height / 16; 520 511 } 521 512 513 + static inline size_t 514 + hantro_hevc_luma_compressed_size(unsigned int width, unsigned int height) 515 + { 516 + u32 pic_width_in_cbsy = 517 + round_up((width + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE); 518 + u32 pic_height_in_cbsy = (height + CBS_LUMA - 1) / CBS_LUMA; 519 + 520 + return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE); 521 + } 522 + 523 + static inline size_t 524 + hantro_hevc_chroma_compressed_size(unsigned int width, unsigned int height) 525 + { 526 + u32 pic_width_in_cbsc = 527 + round_up((width + CBS_CHROMA_W - 1) / CBS_CHROMA_W, CBS_SIZE); 528 + u32 pic_height_in_cbsc = (height / 2 + CBS_CHROMA_H - 1) / CBS_CHROMA_H; 529 + 530 + return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE); 531 + } 532 + 533 + static inline size_t 534 + hantro_hevc_compressed_size(unsigned int width, unsigned int height) 535 + { 536 + return hantro_hevc_luma_compressed_size(width, height) + 537 + hantro_hevc_chroma_compressed_size(width, height); 538 + } 539 + 522 540 static inline unsigned short hantro_av1_num_sbs(unsigned short dimension) 523 541 { 524 542 return DIV_ROUND_UP(dimension, 64); ··· 561 525 562 526 size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx); 563 527 size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx); 528 + size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx); 529 + size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx); 564 530 565 531 int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); 566 532 int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx);
+5 -1
drivers/media/platform/verisilicon/hantro_postproc.c
··· 213 213 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME) 214 214 buf_size += hantro_vp9_mv_size(pix_mp.width, 215 215 pix_mp.height); 216 - else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) 216 + else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) { 217 217 buf_size += hantro_hevc_mv_size(pix_mp.width, 218 218 pix_mp.height); 219 + if (ctx->hevc_dec.use_compression) 220 + buf_size += hantro_hevc_compressed_size(pix_mp.width, 221 + pix_mp.height); 222 + } 219 223 else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME) 220 224 buf_size += hantro_av1_mv_size(pix_mp.width, 221 225 pix_mp.height);
+1 -5
drivers/media/platform/verisilicon/hantro_v4l2.c
··· 303 303 304 304 coded = capture == ctx->is_encoder; 305 305 306 - vpu_debug(4, "trying format %c%c%c%c\n", 307 - (pix_mp->pixelformat & 0x7f), 308 - (pix_mp->pixelformat >> 8) & 0x7f, 309 - (pix_mp->pixelformat >> 16) & 0x7f, 310 - (pix_mp->pixelformat >> 24) & 0x7f); 306 + vpu_debug(4, "trying format %p4cc\n", &pix_mp->pixelformat); 311 307 312 308 fmt = hantro_find_format(ctx, pix_mp->pixelformat); 313 309 if (!fmt) {
+2 -1
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
··· 257 257 struct hantro_dev *vpu = ctx->dev; 258 258 struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; 259 259 struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; 260 - unsigned int num_tile_cols = 1 << ctrls->tile_group_entry->tile_col; 260 + const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info; 261 + unsigned int num_tile_cols = tile_info->tile_cols; 261 262 unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + 1, 64); 262 263 unsigned int height_in_sb = height / 64; 263 264 unsigned int stripe_num = ((height + 8) + 63) / 64;
+5 -5
drivers/media/platform/verisilicon/rockchip_vpu981_regs.h
··· 327 327 328 328 #define av1_apf_threshold AV1_DEC_REG(55, 0, 0xffff) 329 329 #define av1_apf_single_pu_mode AV1_DEC_REG(55, 30, 0x1) 330 - #define av1_apf_disable AV1_DEC_REG(55, 30, 0x1) 330 + #define av1_apf_disable AV1_DEC_REG(55, 31, 0x1) 331 331 332 332 #define av1_dec_max_burst AV1_DEC_REG(58, 0, 0xff) 333 333 #define av1_dec_buswidth AV1_DEC_REG(58, 8, 0x7) ··· 337 337 #define av1_dec_mc_polltime AV1_DEC_REG(58, 17, 0x3ff) 338 338 #define av1_dec_mc_pollmode AV1_DEC_REG(58, 27, 0x3) 339 339 340 - #define av1_filt_ref_adj_3 AV1_DEC_REG(59, 0, 0x3f) 341 - #define av1_filt_ref_adj_2 AV1_DEC_REG(59, 7, 0x3f) 342 - #define av1_filt_ref_adj_1 AV1_DEC_REG(59, 14, 0x3f) 343 - #define av1_filt_ref_adj_0 AV1_DEC_REG(59, 21, 0x3f) 340 + #define av1_filt_ref_adj_3 AV1_DEC_REG(59, 0, 0x7f) 341 + #define av1_filt_ref_adj_2 AV1_DEC_REG(59, 7, 0x7f) 342 + #define av1_filt_ref_adj_1 AV1_DEC_REG(59, 14, 0x7f) 343 + #define av1_filt_ref_adj_0 AV1_DEC_REG(59, 21, 0x7f) 344 344 #define av1_ref0_sign_bias AV1_DEC_REG(59, 28, 0x1) 345 345 #define av1_ref1_sign_bias AV1_DEC_REG(59, 29, 0x1) 346 346 #define av1_ref2_sign_bias AV1_DEC_REG(59, 30, 0x1)
-1
drivers/media/platform/verisilicon/rockchip_vpu_hw.c
··· 82 82 { 83 83 .fourcc = V4L2_PIX_FMT_NV12, 84 84 .codec_mode = HANTRO_MODE_NONE, 85 - .match_depth = true, 86 85 .postprocessed = true, 87 86 .frmsize = { 88 87 .min_width = ROCKCHIP_VPU981_MIN_SIZE,
+2 -7
drivers/media/platform/xilinx/xilinx-vipp.c
··· 199 199 struct media_pad *sink_pad; 200 200 struct xvip_graph_entity *ent; 201 201 struct v4l2_fwnode_link link; 202 - struct device_node *ep = NULL; 202 + struct device_node *ep; 203 203 struct xvip_dma *dma; 204 204 int ret = 0; 205 205 206 206 dev_dbg(xdev->dev, "creating links for DMA engines\n"); 207 207 208 - while (1) { 209 - /* Get the next endpoint and parse its link. */ 210 - ep = of_graph_get_next_endpoint(node, ep); 211 - if (ep == NULL) 212 - break; 213 - 208 + for_each_endpoint_of_node(node, ep) { 214 209 dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep); 215 210 216 211 ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+1 -1
drivers/media/radio/radio-tea5764.c
··· 502 502 503 503 /* I2C subsystem interface */ 504 504 static const struct i2c_device_id tea5764_id[] = { 505 - { "radio-tea5764", 0 }, 505 + { "radio-tea5764" }, 506 506 { } /* Terminating entry */ 507 507 }; 508 508 MODULE_DEVICE_TABLE(i2c, tea5764_id);
+2 -2
drivers/media/radio/saa7706h.c
··· 395 395 } 396 396 397 397 static const struct i2c_device_id saa7706h_id[] = { 398 - {DRIVER_NAME, 0}, 399 - {}, 398 + { DRIVER_NAME }, 399 + {} 400 400 }; 401 401 402 402 MODULE_DEVICE_TABLE(i2c, saa7706h_id);
+1 -1
drivers/media/radio/si470x/radio-si470x-i2c.c
··· 28 28 /* I2C Device ID List */ 29 29 static const struct i2c_device_id si470x_i2c_id[] = { 30 30 /* Generic Entry */ 31 - { "si470x", 0 }, 31 + { "si470x" }, 32 32 /* Terminating entry */ 33 33 { } 34 34 };
+2 -2
drivers/media/radio/si4713/si4713.c
··· 1639 1639 1640 1640 /* si4713_i2c_driver - i2c driver interface */ 1641 1641 static const struct i2c_device_id si4713_id[] = { 1642 - { "si4713" , 0 }, 1643 - { }, 1642 + { "si4713" }, 1643 + { } 1644 1644 }; 1645 1645 MODULE_DEVICE_TABLE(i2c, si4713_id); 1646 1646
+2 -2
drivers/media/radio/tef6862.c
··· 173 173 } 174 174 175 175 static const struct i2c_device_id tef6862_id[] = { 176 - {DRIVER_NAME, 0}, 177 - {}, 176 + { DRIVER_NAME }, 177 + {} 178 178 }; 179 179 180 180 MODULE_DEVICE_TABLE(i2c, tef6862_id);
-3
drivers/media/rc/ene_ir.c
··· 451 451 dev->rdev->max_timeout = 200000; 452 452 } 453 453 454 - if (dev->hw_learning_and_tx_capable) 455 - dev->rdev->tx_resolution = sample_period; 456 - 457 454 if (dev->rdev->timeout > dev->rdev->max_timeout) 458 455 dev->rdev->timeout = dev->rdev->max_timeout; 459 456 if (dev->rdev->timeout < dev->rdev->min_timeout)
-1
drivers/media/rc/ite-cir.c
··· 1380 1380 rdev->timeout = IR_DEFAULT_TIMEOUT; 1381 1381 rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; 1382 1382 rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * sample_period / 1000; 1383 - rdev->tx_resolution = ITE_BAUDRATE_DIVISOR * sample_period / 1000; 1384 1383 1385 1384 /* set up transmitter related values */ 1386 1385 rdev->tx_ir = ite_tx_ir;
+27
drivers/media/rc/meson-ir.c
··· 567 567 spin_unlock_irqrestore(&ir->lock, flags); 568 568 } 569 569 570 + static __maybe_unused int meson_ir_resume(struct device *dev) 571 + { 572 + struct meson_ir *ir = dev_get_drvdata(dev); 573 + 574 + if (ir->param->support_hw_decoder) 575 + meson_ir_hw_decoder_init(ir->rc, &ir->rc->enabled_protocols); 576 + else 577 + meson_ir_sw_decoder_init(ir->rc); 578 + 579 + return 0; 580 + } 581 + 582 + static __maybe_unused int meson_ir_suspend(struct device *dev) 583 + { 584 + struct meson_ir *ir = dev_get_drvdata(dev); 585 + unsigned long flags; 586 + 587 + spin_lock_irqsave(&ir->lock, flags); 588 + regmap_update_bits(ir->reg, IR_DEC_REG1, IR_DEC_REG1_ENABLE, 0); 589 + spin_unlock_irqrestore(&ir->lock, flags); 590 + 591 + return 0; 592 + } 593 + 594 + static SIMPLE_DEV_PM_OPS(meson_ir_pm_ops, meson_ir_suspend, meson_ir_resume); 595 + 570 596 static const struct meson_ir_param meson6_ir_param = { 571 597 .support_hw_decoder = false, 572 598 .max_register = IR_DEC_REG1, ··· 633 607 .driver = { 634 608 .name = DRIVER_NAME, 635 609 .of_match_table = meson_ir_match, 610 + .pm = pm_ptr(&meson_ir_pm_ops), 636 611 }, 637 612 }; 638 613
-1
drivers/media/rc/rc-loopback.c
··· 230 230 rc->min_timeout = 1; 231 231 rc->max_timeout = IR_MAX_TIMEOUT; 232 232 rc->rx_resolution = 1; 233 - rc->tx_resolution = 1; 234 233 rc->s_tx_mask = loop_set_tx_mask; 235 234 rc->s_tx_carrier = loop_set_tx_carrier; 236 235 rc->s_tx_duty_cycle = loop_set_tx_duty_cycle;
+2 -4
drivers/media/test-drivers/vicodec/vicodec-core.c
··· 1215 1215 if (ret < 0) 1216 1216 return ret; 1217 1217 1218 - if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) || 1219 - !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) 1218 + if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) 1220 1219 return 0; 1221 1220 1222 1221 ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec); ··· 1249 1250 if (ret < 0) 1250 1251 return ret; 1251 1252 1252 - if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) || 1253 - !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) 1253 + if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) 1254 1254 return 0; 1255 1255 1256 1256 ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc);
+1 -1
drivers/media/test-drivers/vidtv/vidtv_demod.c
··· 407 407 }; 408 408 409 409 static const struct i2c_device_id vidtv_demod_i2c_id_table[] = { 410 - {"dvb_vidtv_demod", 0}, 410 + { "dvb_vidtv_demod" }, 411 411 {} 412 412 }; 413 413 MODULE_DEVICE_TABLE(i2c, vidtv_demod_i2c_id_table);
+1 -1
drivers/media/test-drivers/vidtv/vidtv_tuner.c
··· 385 385 }; 386 386 387 387 static const struct i2c_device_id vidtv_tuner_i2c_id_table[] = { 388 - {"dvb_vidtv_tuner", 0}, 388 + { "dvb_vidtv_tuner" }, 389 389 {} 390 390 }; 391 391 MODULE_DEVICE_TABLE(i2c, vidtv_tuner_i2c_id_table);
+45 -3
drivers/media/test-drivers/vivid/vivid-cec.c
··· 316 316 struct vivid_dev *dev = cec_get_drvdata(adap); 317 317 struct cec_msg reply; 318 318 u8 dest = cec_msg_destination(msg); 319 - u8 disp_ctl; 320 - char osd[14]; 321 319 322 320 if (cec_msg_is_broadcast(msg)) 323 321 dest = adap->log_addrs.log_addr[0]; 324 322 cec_msg_init(&reply, dest, cec_msg_initiator(msg)); 325 323 326 324 switch (cec_msg_opcode(msg)) { 327 - case CEC_MSG_SET_OSD_STRING: 325 + case CEC_MSG_SET_OSD_STRING: { 326 + u8 disp_ctl; 327 + char osd[14]; 328 + 328 329 if (!cec_is_sink(adap)) 329 330 return -ENOMSG; 330 331 cec_ops_set_osd_string(msg, &disp_ctl, osd); ··· 349 348 break; 350 349 } 351 350 break; 351 + } 352 + case CEC_MSG_VENDOR_COMMAND_WITH_ID: { 353 + u32 vendor_id; 354 + u8 size; 355 + const u8 *vendor_cmd; 356 + 357 + /* 358 + * If we receive <Vendor Command With ID> with our vendor ID 359 + * and with a payload of size 1, and the payload value is odd, 360 + * then we reply with the same message, but with the payload 361 + * byte incremented by 1. 362 + * 363 + * If the size is 1 and the payload value is even, then we 364 + * ignore the message. 365 + * 366 + * The reason we reply to odd instead of even payload values 367 + * is that it allows for testing of the corner case where the 368 + * reply value is 0 (0xff + 1 % 256). 369 + * 370 + * For other sizes we Feature Abort. 371 + * 372 + * This is added for the specific purpose of testing the 373 + * CEC_MSG_FL_REPLY_VENDOR_ID flag using vivid. 374 + */ 375 + cec_ops_vendor_command_with_id(msg, &vendor_id, &size, &vendor_cmd); 376 + if (vendor_id != adap->log_addrs.vendor_id) 377 + break; 378 + if (size == 1) { 379 + // Ignore even op values 380 + if (!(vendor_cmd[0] & 1)) 381 + break; 382 + reply.len = msg->len; 383 + memcpy(reply.msg + 1, msg->msg + 1, msg->len - 1); 384 + reply.msg[msg->len - 1]++; 385 + } else { 386 + cec_msg_feature_abort(&reply, cec_msg_opcode(msg), 387 + CEC_OP_ABORT_INVALID_OP); 388 + } 389 + cec_transmit_msg(adap, &reply, false); 390 + break; 391 + } 352 392 default: 353 393 return -ENOMSG; 354 394 }
+1 -1
drivers/media/tuners/e4000.c
··· 719 719 } 720 720 721 721 static const struct i2c_device_id e4000_id_table[] = { 722 - {"e4000", 0}, 722 + { "e4000" }, 723 723 {} 724 724 }; 725 725 MODULE_DEVICE_TABLE(i2c, e4000_id_table);
+1 -1
drivers/media/tuners/fc2580.c
··· 600 600 } 601 601 602 602 static const struct i2c_device_id fc2580_id_table[] = { 603 - {"fc2580", 0}, 603 + { "fc2580" }, 604 604 {} 605 605 }; 606 606 MODULE_DEVICE_TABLE(i2c, fc2580_id_table);
+1 -1
drivers/media/tuners/m88rs6000t.c
··· 709 709 } 710 710 711 711 static const struct i2c_device_id m88rs6000t_id[] = { 712 - {"m88rs6000t", 0}, 712 + { "m88rs6000t" }, 713 713 {} 714 714 }; 715 715 MODULE_DEVICE_TABLE(i2c, m88rs6000t_id);
+1 -1
drivers/media/tuners/mt2060.c
··· 514 514 } 515 515 516 516 static const struct i2c_device_id mt2060_id_table[] = { 517 - {"mt2060", 0}, 517 + { "mt2060" }, 518 518 {} 519 519 }; 520 520 MODULE_DEVICE_TABLE(i2c, mt2060_id_table);
+1 -1
drivers/media/tuners/mxl301rf.c
··· 317 317 318 318 319 319 static const struct i2c_device_id mxl301rf_id[] = { 320 - {"mxl301rf", 0}, 320 + { "mxl301rf" }, 321 321 {} 322 322 }; 323 323 MODULE_DEVICE_TABLE(i2c, mxl301rf_id);
+1 -1
drivers/media/tuners/qm1d1b0004.c
··· 243 243 244 244 245 245 static const struct i2c_device_id qm1d1b0004_id[] = { 246 - {"qm1d1b0004", 0}, 246 + { "qm1d1b0004" }, 247 247 {} 248 248 }; 249 249
+1 -1
drivers/media/tuners/qm1d1c0042.c
··· 434 434 435 435 436 436 static const struct i2c_device_id qm1d1c0042_id[] = { 437 - {"qm1d1c0042", 0}, 437 + { "qm1d1c0042" }, 438 438 {} 439 439 }; 440 440 MODULE_DEVICE_TABLE(i2c, qm1d1c0042_id);
+1 -1
drivers/media/tuners/tda18212.c
··· 254 254 } 255 255 256 256 static const struct i2c_device_id tda18212_id[] = { 257 - {"tda18212", 0}, 257 + { "tda18212" }, 258 258 {} 259 259 }; 260 260 MODULE_DEVICE_TABLE(i2c, tda18212_id);
+1 -1
drivers/media/tuners/tda18250.c
··· 868 868 } 869 869 870 870 static const struct i2c_device_id tda18250_id_table[] = { 871 - {"tda18250", 0}, 871 + { "tda18250" }, 872 872 {} 873 873 }; 874 874 MODULE_DEVICE_TABLE(i2c, tda18250_id_table);
+1 -1
drivers/media/tuners/tua9001.c
··· 245 245 } 246 246 247 247 static const struct i2c_device_id tua9001_id_table[] = { 248 - {"tua9001", 0}, 248 + { "tua9001" }, 249 249 {} 250 250 }; 251 251 MODULE_DEVICE_TABLE(i2c, tua9001_id_table);
+1 -3
drivers/media/tuners/tuner-i2c.h
··· 133 133 } \ 134 134 if (0 == __ret) { \ 135 135 state = kzalloc(sizeof(type), GFP_KERNEL); \ 136 - if (!state) { \ 137 - __ret = -ENOMEM; \ 136 + if (NULL == state) \ 138 137 goto __fail; \ 139 - } \ 140 138 state->i2c_props.addr = i2caddr; \ 141 139 state->i2c_props.adap = i2cadap; \ 142 140 state->i2c_props.name = devname; \
+1 -1
drivers/media/usb/go7007/s2250-board.c
··· 611 611 } 612 612 613 613 static const struct i2c_device_id s2250_id[] = { 614 - { "s2250", 0 }, 614 + { "s2250" }, 615 615 { } 616 616 }; 617 617 MODULE_DEVICE_TABLE(i2c, s2250_id);
+15
drivers/media/v4l2-core/v4l2-dev.c
··· 557 557 bool is_tx = vdev->vfl_dir != VFL_DIR_RX; 558 558 bool is_io_mc = vdev->device_caps & V4L2_CAP_IO_MC; 559 559 bool has_streaming = vdev->device_caps & V4L2_CAP_STREAMING; 560 + bool is_edid = vdev->device_caps & V4L2_CAP_EDID; 560 561 561 562 bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE); 562 563 ··· 784 783 SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); 785 784 SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); 786 785 SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek); 786 + } 787 + if (is_edid) { 788 + SET_VALID_IOCTL(ops, VIDIOC_G_EDID, vidioc_g_edid); 789 + if (is_tx) { 790 + SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); 791 + SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); 792 + SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); 793 + } 794 + if (is_rx) { 795 + SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); 796 + SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); 797 + SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); 798 + SET_VALID_IOCTL(ops, VIDIOC_S_EDID, vidioc_s_edid); 799 + } 787 800 } 788 801 789 802 bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls,
+2 -1
drivers/media/v4l2-core/v4l2-ioctl.c
··· 484 484 { 485 485 const struct v4l2_create_buffers *p = arg; 486 486 487 - pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, max num buffers=%u", 487 + pr_cont("index=%d, count=%d, memory=%s, capabilities=0x%08x, max num buffers=%u, ", 488 488 p->index, p->count, prt_names(p->memory, v4l2_memory_names), 489 489 p->capabilities, p->max_num_buffers); 490 490 v4l_print_format(&p->format, write_only); ··· 1458 1458 case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; 1459 1459 case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break; 1460 1460 case V4L2_META_FMT_RK_ISP1_STAT_3A: descr = "Rockchip ISP1 3A Statistics"; break; 1461 + case V4L2_META_FMT_RK_ISP1_EXT_PARAMS: descr = "Rockchip ISP1 Ext 3A Params"; break; 1461 1462 case V4L2_PIX_FMT_NV12_8L128: descr = "NV12 (8x128 Linear)"; break; 1462 1463 case V4L2_PIX_FMT_NV12M_8L128: descr = "NV12M (8x128 Linear)"; break; 1463 1464 case V4L2_PIX_FMT_NV12_10BE_8L128: descr = "10-bit NV12 (8x128 Linear, BE)"; break;
+45 -8
drivers/media/v4l2-core/v4l2-subdev.c
··· 1443 1443 bool states_locked; 1444 1444 int ret; 1445 1445 1446 - if (!is_media_entity_v4l2_subdev(link->sink->entity) || 1447 - !is_media_entity_v4l2_subdev(link->source->entity)) { 1448 - pr_warn_once("%s of link '%s':%u->'%s':%u is not a V4L2 sub-device, driver bug!\n", 1449 - !is_media_entity_v4l2_subdev(link->sink->entity) ? 1450 - "sink" : "source", 1451 - link->source->entity->name, link->source->index, 1452 - link->sink->entity->name, link->sink->index); 1453 - return 0; 1446 + /* 1447 + * Links are validated in the context of the sink entity. Usage of this 1448 + * helper on a sink that is not a subdev is a clear driver bug. 1449 + */ 1450 + if (WARN_ON_ONCE(!is_media_entity_v4l2_subdev(link->sink->entity))) 1451 + return -EINVAL; 1452 + 1453 + /* 1454 + * If the source is a video device, delegate link validation to it. This 1455 + * allows usage of this helper for subdev connected to a video output 1456 + * device, provided that the driver implement the video output device's 1457 + * .link_validate() operation. 1458 + */ 1459 + if (is_media_entity_v4l2_video_device(link->source->entity)) { 1460 + struct media_entity *source = link->source->entity; 1461 + 1462 + if (!source->ops || !source->ops->link_validate) { 1463 + /* 1464 + * Many existing drivers do not implement the required 1465 + * .link_validate() operation for their video devices. 1466 + * Print a warning to get the drivers fixed, and return 1467 + * 0 to avoid breaking userspace. This should 1468 + * eventually be turned into a WARN_ON() when all 1469 + * drivers will have been fixed. 1470 + */ 1471 + pr_warn_once("video device '%s' does not implement .link_validate(), driver bug!\n", 1472 + source->name); 1473 + return 0; 1474 + } 1475 + 1476 + /* 1477 + * Avoid infinite loops in case a video device incorrectly uses 1478 + * this helper function as its .link_validate() handler. 1479 + */ 1480 + if (WARN_ON(source->ops->link_validate == v4l2_subdev_link_validate)) 1481 + return -EINVAL; 1482 + 1483 + return source->ops->link_validate(link); 1454 1484 } 1485 + 1486 + /* 1487 + * If the source is still not a subdev, usage of this helper is a clear 1488 + * driver bug. 1489 + */ 1490 + if (WARN_ON(!is_media_entity_v4l2_subdev(link->source->entity))) 1491 + return -EINVAL; 1455 1492 1456 1493 sink_sd = media_entity_to_v4l2_subdev(link->sink->entity); 1457 1494 source_sd = media_entity_to_v4l2_subdev(link->source->entity);
+2 -2
drivers/staging/media/atomisp/include/linux/atomisp.h
··· 200 200 }; 201 201 202 202 /* DVS 2.0 Coefficient types. This structure contains 4 pointers to 203 - * arrays that contain the coeffients for each type. 203 + * arrays that contain the coefficients for each type. 204 204 */ 205 205 struct atomisp_dvs2_coef_types { 206 206 short __user *odd_real; /** real part of the odd coefficients*/ ··· 698 698 /* Digital Image Stabilization: 699 699 * 1. get dis statistics: reads DIS statistics from ISP (every frame) 700 700 * 2. set dis coefficients: set DIS filter coefficients (one time) 701 - * 3. set dis motion vecotr: set motion vector (result of DIS, every frame) 701 + * 3. set dis motion vector: set motion vector (result of DIS, every frame) 702 702 */ 703 703 #define ATOMISP_IOC_G_DIS_STAT \ 704 704 _IOWR('v', BASE_VIDIOC_PRIVATE + 6, struct atomisp_dis_statistics)
+2 -4
drivers/staging/media/atomisp/include/linux/atomisp_platform.h
··· 116 116 }; 117 117 118 118 /* 119 - * Sensor of external ISP can send multiple steams with different mipi data 119 + * Sensor of external ISP can send multiple streams with different mipi data 120 120 * type in the same virtual channel. This information needs to come from the 121 121 * sensor or external ISP 122 122 */ ··· 138 138 /* 139 139 * if more isys_configs is more than 0, sensor needs to configure the 140 140 * input format differently. width and height can be 0. If width and 141 - * height is not zero, then the corresponsing data needs to be set 141 + * height is not zero, then the corresponding data needs to be set 142 142 */ 143 143 struct atomisp_isys_config_info isys_info[MAX_STREAMS_PER_CHANNEL]; 144 144 }; ··· 174 174 enum atomisp_input_format format, 175 175 enum atomisp_bayer_order bayer_order); 176 176 void atomisp_unregister_subdev(struct v4l2_subdev *subdev); 177 - 178 - int v4l2_get_acpi_sensor_info(struct device *dev, char **module_id_str); 179 177 180 178 /* API from old platform_camera.h, new CPUID implementation */ 181 179 #define __IS_SOC(x) (boot_cpu_data.x86_vfm == x)
+2
drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c
··· 109 109 static struct gmin_cfg_var xiaomi_mipad2_vars[] = { 110 110 /* _DSM contains the wrong CsiPort for the front facing OV5693 sensor */ 111 111 { "INT33BE:00", "CsiPort", "0" }, 112 + /* _DSM contains the wrong CsiLanes for the back facing T4KA3 sensor */ 113 + { "XMCC0003:00", "CsiLanes", "4" }, 112 114 {} 113 115 }; 114 116
+2
drivers/staging/media/atomisp/pci/atomisp_fops.c
··· 441 441 .buf_queue = atomisp_buf_queue, 442 442 .start_streaming = atomisp_start_streaming, 443 443 .stop_streaming = atomisp_stop_streaming, 444 + .wait_prepare = vb2_ops_wait_prepare, 445 + .wait_finish = vb2_ops_wait_finish, 444 446 }; 445 447 446 448 static void atomisp_dev_init_struct(struct atomisp_device *isp)
+1 -1
drivers/staging/media/atomisp/pci/atomisp_subdev.c
··· 797 797 pipe->vb_queue.ops = &atomisp_vb2_ops; 798 798 pipe->vb_queue.mem_ops = &vb2_vmalloc_memops; 799 799 pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 800 + pipe->vb_queue.lock = &pipe->vb_queue_mutex; 800 801 ret = vb2_queue_init(&pipe->vb_queue); 801 802 if (ret) 802 803 return ret; 803 804 804 805 pipe->vdev.queue = &pipe->vb_queue; 805 - pipe->vdev.queue->lock = &pipe->vb_queue_mutex; 806 806 807 807 INIT_LIST_HEAD(&pipe->buffers_in_css); 808 808 INIT_LIST_HEAD(&pipe->activeq);
+3 -1
drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem_local.h
··· 20 20 #include "vmem_global.h" 21 21 22 22 typedef u16 t_vmem_elem; 23 + typedef s16 t_svmem_elem; 23 24 24 - #define VMEM_ARRAY(x, s) t_vmem_elem x[s / ISP_NWAY][ISP_NWAY] 25 + #define VMEM_ARRAY(x, s) t_vmem_elem x[(s) / ISP_NWAY][ISP_NWAY] 26 + #define SVMEM_ARRAY(x, s) t_svmem_elem x[(s) / ISP_NWAY][ISP_NWAY] 25 27 26 28 void isp_vmem_load( 27 29 const isp_ID_t ID,
+4 -2
drivers/staging/media/atomisp/pci/hive_isp_css_include/assert_support.h
··· 27 27 * #define assert(cnd) BUG_ON(cnd) 28 28 * but that causes many compiler warnings (==errors) under Android 29 29 * because it seems that the BUG_ON() macro is not seen as a check by 30 - * gcc like the BUG() macro is. */ 30 + * gcc like the BUG() macro is. 31 + */ 31 32 #define assert(cnd) \ 32 33 do { \ 33 34 if (!(cnd)) \ ··· 38 37 #ifndef PIPE_GENERATION 39 38 /* Deprecated OP___assert, this is still used in ~1000 places 40 39 * in the code. This will be removed over time. 41 - * The implementation for the pipe generation tool is in see support.isp.h */ 40 + * The implementation for the pipe generation tool is in see support.isp.h 41 + */ 42 42 #define OP___assert(cnd) assert(cnd) 43 43 44 44 static inline void compile_time_assert(unsigned int cond)
+2 -2
drivers/staging/media/atomisp/pci/hive_isp_css_include/host/csi_rx_public.h
··· 94 94 const hrt_address reg); 95 95 /** 96 96 * @brief Store a value to the register. 97 - * Store a value to the registe of the csi rx fe. 97 + * Store a value to the register of the csi rx fe. 98 98 * 99 99 * @param[in] ID The global unique ID for the ibuf-controller instance. 100 100 * @param[in] reg The offset address of the register. ··· 119 119 const hrt_address reg); 120 120 /** 121 121 * @brief Store a value to the register. 122 - * Store a value to the registe of the csi rx be. 122 + * Store a value to the register of the csi rx be. 123 123 * 124 124 * @param[in] ID The global unique ID for the ibuf-controller instance. 125 125 * @param[in] reg The offset address of the register.
-6
drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h
··· 28 28 #define CEIL_SHIFT(a, b) (((a) + (1 << (b)) - 1) >> (b)) 29 29 #define CEIL_SHIFT_MUL(a, b) (CEIL_SHIFT(a, b) << (b)) 30 30 31 - #if !defined(PIPE_GENERATION) 32 - 33 - #define ceil_div(a, b) (CEIL_DIV(a, b)) 34 - 35 - #endif /* !defined(PIPE_GENERATION) */ 36 - 37 31 /* 38 32 * For SP and ISP, SDK provides the definition of OP_std_modadd. 39 33 * We need it only for host
-5
drivers/staging/media/atomisp/pci/hmm/hmm.c
··· 204 204 goto bind_err; 205 205 } 206 206 207 - dev_dbg(atomisp_dev, "pages: 0x%08x (%zu bytes), type: %d, vmalloc %p\n", 208 - bo->start, bytes, type, vmalloc_noprof); 209 - 210 207 return bo->start; 211 208 212 209 bind_err: ··· 227 230 void hmm_free(ia_css_ptr virt) 228 231 { 229 232 struct hmm_buffer_object *bo; 230 - 231 - dev_dbg(atomisp_dev, "%s: free 0x%08x\n", __func__, virt); 232 233 233 234 if (WARN_ON(virt == mmgr_EXCEPTION)) 234 235 return;
+2 -1
drivers/staging/media/atomisp/pci/isp/kernels/bnr/bnr_1.0/ia_css_bnr.host.c
··· 45 45 const struct sh_css_isp_bnr_params *bnr, 46 46 unsigned int level) 47 47 { 48 - if (!bnr) return; 48 + if (!bnr) 49 + return; 49 50 ia_css_debug_dtrace(level, "Bayer Noise Reduction:\n"); 50 51 ia_css_debug_dtrace(level, "\t%-32s = %d\n", 51 52 "bnr_gain_all", bnr->gain_all);
+2 -1
drivers/staging/media/atomisp/pci/isp/kernels/de/de_1.0/ia_css_de.host.c
··· 47 47 const struct sh_css_isp_de_params *de, 48 48 unsigned int level) 49 49 { 50 - if (!de) return; 50 + if (!de) 51 + return; 51 52 ia_css_debug_dtrace(level, "Demosaic:\n"); 52 53 ia_css_debug_dtrace(level, "\t%-32s = %d\n", 53 54 "de_pixelnoise", de->pixelnoise);
+9 -13
drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8.host.c
··· 172 172 base = shuffle_block * i; 173 173 174 174 for (j = 0; j < IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS; j++) { 175 - to->e_dew_enh_x[0][base + j] = min_t(int, max_t(int, 176 - from->dew_enhance_seg_x[j], 0), 177 - 8191); 178 - to->e_dew_enh_y[0][base + j] = min_t(int, max_t(int, 179 - from->dew_enhance_seg_y[j], -8192), 180 - 8191); 175 + to->e_dew_enh_x[0][base + j] = clamp(from->dew_enhance_seg_x[j], 176 + 0, 8191); 177 + to->e_dew_enh_y[0][base + j] = clamp(from->dew_enhance_seg_y[j], 178 + -8192, 8191); 181 179 } 182 180 183 181 for (j = 0; j < (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1); j++) { 184 - to->e_dew_enh_a[0][base + j] = min_t(int, max_t(int, 185 - from->dew_enhance_seg_slope[j], 186 - -8192), 8191); 182 + to->e_dew_enh_a[0][base + j] = clamp(from->dew_enhance_seg_slope[j], 183 + -8192, 8191); 187 184 /* Convert dew_enhance_seg_exp to flag: 188 185 * 0 -> 0 189 186 * 1...13 -> 1 190 187 */ 191 - to->e_dew_enh_f[0][base + j] = (min_t(int, max_t(int, 192 - from->dew_enhance_seg_exp[j], 193 - 0), 13) > 0); 188 + to->e_dew_enh_f[0][base + j] = clamp(from->dew_enhance_seg_exp[j], 189 + 0, 13) > 0; 194 190 } 195 191 196 192 /* Hard-coded to 0, in order to be able to handle out of ··· 272 276 for (i = 0; i < (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1); i++) { 273 277 min_exp = max(min_exp, from->dew_enhance_seg_exp[i]); 274 278 } 275 - to->e_dew_enh_asr = 13 - min(max(min_exp, 0), 13); 279 + to->e_dew_enh_asr = 13 - clamp(min_exp, 0, 13); 276 280 277 281 to->dedgew_max = from->dedgew_max; 278 282 }
+2 -2
drivers/staging/media/atomisp/pci/isp/kernels/eed1_8/ia_css_eed1_8_param.h
··· 94 94 95 95 struct eed1_8_vmem_params { 96 96 VMEM_ARRAY(e_dew_enh_x, ISP_VEC_NELEMS); 97 - VMEM_ARRAY(e_dew_enh_y, ISP_VEC_NELEMS); 98 - VMEM_ARRAY(e_dew_enh_a, ISP_VEC_NELEMS); 97 + SVMEM_ARRAY(e_dew_enh_y, ISP_VEC_NELEMS); 98 + SVMEM_ARRAY(e_dew_enh_a, ISP_VEC_NELEMS); 99 99 VMEM_ARRAY(e_dew_enh_f, ISP_VEC_NELEMS); 100 100 VMEM_ARRAY(chgrinv_x, ISP_VEC_NELEMS); 101 101 VMEM_ARRAY(chgrinv_a, ISP_VEC_NELEMS);
+2 -1
drivers/staging/media/atomisp/pci/isp/kernels/fpn/fpn_1.0/ia_css_fpn.host.c
··· 43 43 const struct sh_css_isp_fpn_params *fpn, 44 44 unsigned int level) 45 45 { 46 - if (!fpn) return; 46 + if (!fpn) 47 + return; 47 48 ia_css_debug_dtrace(level, "Fixed Pattern Noise Reduction:\n"); 48 49 ia_css_debug_dtrace(level, "\t%-32s = %d\n", 49 50 "fpn_shift", fpn->shift);
+5 -4
drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/bayer_io_ls/ia_css_bayer_io.host.c
··· 13 13 * more details. 14 14 */ 15 15 16 + #include <linux/bitops.h> 17 + #include <linux/math.h> 18 + 16 19 #include "ia_css_bayer_io.host.h" 17 20 #include "dma.h" 18 - #include "math_support.h" 19 21 #ifndef IA_CSS_NO_DEBUG 20 22 #include "ia_css_debug.h" 21 23 #endif ··· 31 29 const struct ia_css_frame **out_frames = (const struct ia_css_frame **) 32 30 &args->out_frame; 33 31 const struct ia_css_frame_info *in_frame_info = ia_css_frame_get_info(in_frame); 34 - const unsigned int ddr_bits_per_element = sizeof(short) * 8; 35 - const unsigned int ddr_elems_per_word = ceil_div(HIVE_ISP_DDR_WORD_BITS, 36 - ddr_bits_per_element); 32 + const unsigned int ddr_elems_per_word = 33 + DIV_ROUND_UP(HIVE_ISP_DDR_WORD_BITS, BITS_PER_TYPE(short)); 37 34 unsigned int size_get = 0, size_put = 0; 38 35 unsigned int offset = 0; 39 36 int ret;
+5 -4
drivers/staging/media/atomisp/pci/isp/kernels/ipu2_io_ls/yuv444_io_ls/ia_css_yuv444_io.host.c
··· 13 13 more details. 14 14 */ 15 15 16 + #include <linux/bitops.h> 17 + #include <linux/math.h> 18 + 16 19 #include "ia_css_yuv444_io.host.h" 17 20 #include "dma.h" 18 - #include "math_support.h" 19 21 #ifndef IA_CSS_NO_DEBUG 20 22 #include "ia_css_debug.h" 21 23 #endif ··· 31 29 const struct ia_css_frame **out_frames = (const struct ia_css_frame **) 32 30 &args->out_frame; 33 31 const struct ia_css_frame_info *in_frame_info = ia_css_frame_get_info(in_frame); 34 - const unsigned int ddr_bits_per_element = sizeof(short) * 8; 35 - const unsigned int ddr_elems_per_word = ceil_div(HIVE_ISP_DDR_WORD_BITS, 36 - ddr_bits_per_element); 32 + const unsigned int ddr_elems_per_word = 33 + DIV_ROUND_UP(HIVE_ISP_DDR_WORD_BITS, BITS_PER_TYPE(short)); 37 34 unsigned int size_get = 0, size_put = 0; 38 35 unsigned int offset = 0; 39 36 int ret;
+6 -6
drivers/staging/media/atomisp/pci/isp/kernels/xnr/xnr_3.0/ia_css_xnr3.host.c
··· 108 108 * factor. Clip to [0, isp_scale-1). 109 109 */ 110 110 isp_coring = ((coring * isp_scale) + offset) / host_scale; 111 - return min(max(isp_coring, 0), isp_scale - 1); 111 + return clamp(isp_coring, 0, isp_scale - 1); 112 112 } 113 113 114 114 /* ··· 168 168 to->alpha.y0 = alpha_y0; 169 169 to->alpha.u0 = alpha_u0; 170 170 to->alpha.v0 = alpha_v0; 171 - to->alpha.ydiff = min(max(alpha_ydiff, min_diff), max_diff); 172 - to->alpha.udiff = min(max(alpha_udiff, min_diff), max_diff); 173 - to->alpha.vdiff = min(max(alpha_vdiff, min_diff), max_diff); 171 + to->alpha.ydiff = clamp(alpha_ydiff, min_diff, max_diff); 172 + to->alpha.udiff = clamp(alpha_udiff, min_diff, max_diff); 173 + to->alpha.vdiff = clamp(alpha_vdiff, min_diff, max_diff); 174 174 175 175 /* coring parameters are expressed in q1.NN format */ 176 176 to->coring.u0 = coring_u0; 177 177 to->coring.v0 = coring_v0; 178 - to->coring.udiff = min(max(coring_udiff, min_diff), max_diff); 179 - to->coring.vdiff = min(max(coring_vdiff, min_diff), max_diff); 178 + to->coring.udiff = clamp(coring_udiff, min_diff, max_diff); 179 + to->coring.vdiff = clamp(coring_vdiff, min_diff, max_diff); 180 180 181 181 /* blending strength is expressed in q1.NN format */ 182 182 to->blending.strength = blending;
+97 -162
drivers/staging/media/atomisp/pci/runtime/binary/src/binary.c
··· 328 328 329 329 dvs_info = &info->dvs_grid.dvs_grid_info; 330 330 331 - /* for DIS, we use a division instead of a ceil_div. If this is smaller 331 + /* 332 + * For DIS, we use a division instead of a DIV_ROUND_UP(). If this is smaller 332 333 * than the 3a grid size, it indicates that the outer values are not 333 334 * valid for DIS. 334 335 */ ··· 924 923 return 0; 925 924 } 926 925 927 - static int __ia_css_binary_find(struct ia_css_binary_descr *descr, 928 - struct ia_css_binary *binary) { 926 + int ia_css_binary_find(struct ia_css_binary_descr *descr, struct ia_css_binary *binary) 927 + { 929 928 int mode; 930 929 bool online; 931 930 bool two_ppc; ··· 954 953 /* MW: used after an error check, may accept NULL, but doubtfull */ 955 954 assert(binary); 956 955 957 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 958 - "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n", 959 - descr, descr->mode, 960 - binary); 956 + dev_dbg(atomisp_dev, "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n", 957 + descr, descr->mode, binary); 961 958 962 959 mode = descr->mode; 963 960 online = descr->online; ··· 1000 1001 } 1001 1002 1002 1003 /* print a map of the binary file */ 1003 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n"); 1004 + dev_dbg(atomisp_dev, "BINARY INFO:\n"); 1004 1005 for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) { 1005 1006 xcandidate = binary_infos[i]; 1006 1007 if (xcandidate) { 1007 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i); 1008 + dev_dbg(atomisp_dev, "%d:\n", i); 1008 1009 while (xcandidate) { 1009 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n", 1010 - xcandidate->blob->name, xcandidate->type, 1011 - xcandidate->sp.enable.continuous); 1010 + dev_dbg(atomisp_dev, " Name:%s Type:%d Cont:%d\n", 1011 + xcandidate->blob->name, xcandidate->type, 1012 + xcandidate->sp.enable.continuous); 1012 1013 xcandidate = xcandidate->next; 1013 1014 } 1014 1015 } ··· 1020 1021 struct ia_css_binary_info *candidate = &xcandidate->sp; 1021 1022 /* printf("sh_css_binary_find: evaluating candidate: 1022 1023 * %d\n",candidate->id); */ 1023 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1024 - "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n", 1025 - candidate, candidate->pipeline.mode, candidate->id); 1024 + dev_dbg(atomisp_dev, 1025 + "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n", 1026 + candidate, candidate->pipeline.mode, candidate->id); 1026 1027 1027 1028 /* 1028 1029 * MW: Only a limited set of jointly configured binaries can ··· 1031 1032 */ 1032 1033 if (!candidate->enable.continuous && 1033 1034 continuous && (mode != IA_CSS_BINARY_MODE_COPY)) { 1034 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1035 - "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n", 1036 - __LINE__, candidate->enable.continuous, 1037 - continuous, mode, 1038 - IA_CSS_BINARY_MODE_COPY); 1035 + dev_dbg(atomisp_dev, 1036 + "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n", 1037 + __LINE__, candidate->enable.continuous, 1038 + continuous, mode, IA_CSS_BINARY_MODE_COPY); 1039 1039 continue; 1040 1040 } 1041 1041 if (striped && candidate->iterator.num_stripes == 1) { 1042 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1043 - "ia_css_binary_find() [%d] continue: binary is not striped\n", 1044 - __LINE__); 1042 + dev_dbg(atomisp_dev, 1043 + "ia_css_binary_find() [%d] continue: binary is not striped\n", 1044 + __LINE__); 1045 1045 continue; 1046 1046 } 1047 1047 ··· 1048 1050 (mode != IA_CSS_BINARY_MODE_COPY) && 1049 1051 (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) && 1050 1052 (mode != IA_CSS_BINARY_MODE_VF_PP)) { 1051 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1052 - "ia_css_binary_find() [%d] continue: (%d != %d)\n", 1053 - __LINE__, 1054 - candidate->pipeline.isp_pipe_version, isp_pipe_version); 1053 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: (%d != %d)\n", 1054 + __LINE__, candidate->pipeline.isp_pipe_version, isp_pipe_version); 1055 1055 continue; 1056 1056 } 1057 1057 if (!candidate->enable.reduced_pipe && enable_reduced_pipe) { 1058 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1059 - "ia_css_binary_find() [%d] continue: !%d && %d\n", 1060 - __LINE__, 1061 - candidate->enable.reduced_pipe, 1062 - enable_reduced_pipe); 1058 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d && %d\n", 1059 + __LINE__, candidate->enable.reduced_pipe, enable_reduced_pipe); 1063 1060 continue; 1064 1061 } 1065 1062 if (!candidate->enable.dvs_6axis && enable_dvs_6axis) { 1066 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1067 - "ia_css_binary_find() [%d] continue: !%d && %d\n", 1068 - __LINE__, 1069 - candidate->enable.dvs_6axis, 1070 - enable_dvs_6axis); 1063 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d && %d\n", 1064 + __LINE__, candidate->enable.dvs_6axis, enable_dvs_6axis); 1071 1065 continue; 1072 1066 } 1073 1067 if (candidate->enable.high_speed && !enable_high_speed) { 1074 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1075 - "ia_css_binary_find() [%d] continue: %d && !%d\n", 1076 - __LINE__, 1077 - candidate->enable.high_speed, 1078 - enable_high_speed); 1068 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: %d && !%d\n", 1069 + __LINE__, candidate->enable.high_speed, enable_high_speed); 1079 1070 continue; 1080 1071 } 1081 1072 if (!candidate->enable.xnr && need_xnr) { 1082 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1083 - "ia_css_binary_find() [%d] continue: %d && !%d\n", 1084 - __LINE__, 1085 - candidate->enable.xnr, 1086 - need_xnr); 1073 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: %d && !%d\n", 1074 + __LINE__, candidate->enable.xnr, need_xnr); 1087 1075 continue; 1088 1076 } 1089 1077 if (!(candidate->enable.ds & 2) && enable_yuv_ds) { 1090 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1091 - "ia_css_binary_find() [%d] continue: !%d && %d\n", 1092 - __LINE__, 1093 - ((candidate->enable.ds & 2) != 0), 1094 - enable_yuv_ds); 1078 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d && %d\n", 1079 + __LINE__, ((candidate->enable.ds & 2) != 0), enable_yuv_ds); 1095 1080 continue; 1096 1081 } 1097 1082 if ((candidate->enable.ds & 2) && !enable_yuv_ds) { 1098 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1099 - "ia_css_binary_find() [%d] continue: %d && !%d\n", 1100 - __LINE__, 1101 - ((candidate->enable.ds & 2) != 0), 1102 - enable_yuv_ds); 1083 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: %d && !%d\n", 1084 + __LINE__, ((candidate->enable.ds & 2) != 0), enable_yuv_ds); 1103 1085 continue; 1104 1086 } 1105 1087 ··· 1093 1115 candidate->vf_dec.is_variable || 1094 1116 /* or more than one output pin. */ 1095 1117 xcandidate->num_output_pins > 1)) { 1096 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1097 - "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n", 1098 - __LINE__, req_vf_info, 1099 - candidate->enable.vf_veceven, 1100 - candidate->vf_dec.is_variable, 1101 - xcandidate->num_output_pins, 1); 1118 + dev_dbg(atomisp_dev, 1119 + "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n", 1120 + __LINE__, req_vf_info, candidate->enable.vf_veceven, 1121 + candidate->vf_dec.is_variable, xcandidate->num_output_pins, 1); 1102 1122 continue; 1103 1123 } 1104 1124 if (!candidate->enable.dvs_envelope && need_dvs) { 1105 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1106 - "ia_css_binary_find() [%d] continue: !%d && %d\n", 1107 - __LINE__, 1108 - candidate->enable.dvs_envelope, (int)need_dvs); 1125 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d && %d\n", 1126 + __LINE__, candidate->enable.dvs_envelope, (int)need_dvs); 1109 1127 continue; 1110 1128 } 1111 1129 /* internal_res check considers input, output, and dvs envelope sizes */ 1112 1130 ia_css_binary_internal_res(req_in_info, req_bds_out_info, 1113 1131 req_bin_out_info, &dvs_env, candidate, &internal_res); 1114 1132 if (internal_res.width > candidate->internal.max_width) { 1115 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1116 - "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1117 - __LINE__, internal_res.width, 1118 - candidate->internal.max_width); 1133 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1134 + __LINE__, internal_res.width, candidate->internal.max_width); 1119 1135 continue; 1120 1136 } 1121 1137 if (internal_res.height > candidate->internal.max_height) { 1122 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1123 - "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1124 - __LINE__, internal_res.height, 1125 - candidate->internal.max_height); 1138 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1139 + __LINE__, internal_res.height, candidate->internal.max_height); 1126 1140 continue; 1127 1141 } 1128 1142 if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) { 1129 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1130 - "ia_css_binary_find() [%d] continue: !%d && %d\n", 1131 - __LINE__, candidate->enable.ds, (int)need_ds); 1143 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d && %d\n", 1144 + __LINE__, candidate->enable.ds, (int)need_ds); 1132 1145 continue; 1133 1146 } 1134 1147 if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) { 1135 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1136 - "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n", 1137 - __LINE__, candidate->enable.uds, 1138 - candidate->enable.dvs_6axis, (int)need_dz); 1148 + dev_dbg(atomisp_dev, 1149 + "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n", 1150 + __LINE__, candidate->enable.uds, candidate->enable.dvs_6axis, 1151 + (int)need_dz); 1139 1152 continue; 1140 1153 } 1141 1154 if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) { 1142 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1143 - "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n", 1144 - __LINE__, online, candidate->input.source, 1145 - IA_CSS_BINARY_INPUT_MEMORY); 1155 + dev_dbg(atomisp_dev, 1156 + "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n", 1157 + __LINE__, online, candidate->input.source, 1158 + IA_CSS_BINARY_INPUT_MEMORY); 1146 1159 continue; 1147 1160 } 1148 1161 if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) { 1149 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1150 - "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n", 1151 - __LINE__, online, candidate->input.source, 1152 - IA_CSS_BINARY_INPUT_SENSOR); 1162 + dev_dbg(atomisp_dev, 1163 + "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n", 1164 + __LINE__, online, candidate->input.source, 1165 + IA_CSS_BINARY_INPUT_SENSOR); 1153 1166 continue; 1154 1167 } 1155 1168 if (req_bin_out_info->res.width < candidate->output.min_width || 1156 1169 req_bin_out_info->res.width > candidate->output.max_width) { 1157 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1158 - "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n", 1159 - __LINE__, 1160 - req_bin_out_info->padded_width, 1161 - candidate->output.min_width, 1162 - req_bin_out_info->padded_width, 1163 - candidate->output.max_width); 1170 + dev_dbg(atomisp_dev, 1171 + "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n", 1172 + __LINE__, req_bin_out_info->padded_width, 1173 + candidate->output.min_width, req_bin_out_info->padded_width, 1174 + candidate->output.max_width); 1164 1175 continue; 1165 1176 } 1166 1177 if (xcandidate->num_output_pins > 1 && 1167 1178 /* in case we have a second output pin, */ 1168 1179 req_vf_info) { /* and we need vf output. */ 1169 1180 if (req_vf_info->res.width > candidate->output.max_width) { 1170 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1171 - "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1172 - __LINE__, 1173 - req_vf_info->res.width, 1174 - candidate->output.max_width); 1181 + dev_dbg(atomisp_dev, 1182 + "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1183 + __LINE__, req_vf_info->res.width, 1184 + candidate->output.max_width); 1175 1185 continue; 1176 1186 } 1177 1187 } 1178 1188 if (req_in_info->padded_width > candidate->input.max_width) { 1179 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1180 - "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1181 - __LINE__, req_in_info->padded_width, 1182 - candidate->input.max_width); 1189 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: (%d > %d)\n", 1190 + __LINE__, req_in_info->padded_width, candidate->input.max_width); 1183 1191 continue; 1184 1192 } 1185 1193 if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) { 1186 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1187 - "ia_css_binary_find() [%d] continue: !%d\n", 1188 - __LINE__, 1189 - binary_supports_output_format(xcandidate, req_bin_out_info->format)); 1194 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: !%d\n", 1195 + __LINE__, binary_supports_output_format(xcandidate, 1196 + req_bin_out_info->format)); 1190 1197 continue; 1191 1198 } 1192 1199 if (xcandidate->num_output_pins > 1 && ··· 1180 1217 /* check if the required vf format 1181 1218 is supported. */ 1182 1219 !binary_supports_output_format(xcandidate, req_vf_info->format)) { 1183 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1184 - "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n", 1185 - __LINE__, xcandidate->num_output_pins, 1, 1186 - req_vf_info, 1187 - binary_supports_output_format(xcandidate, req_vf_info->format)); 1220 + dev_dbg(atomisp_dev, 1221 + "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n", 1222 + __LINE__, xcandidate->num_output_pins, 1, req_vf_info, 1223 + binary_supports_output_format(xcandidate, req_vf_info->format)); 1188 1224 continue; 1189 1225 } 1190 1226 ··· 1191 1229 if (xcandidate->num_output_pins == 1 && 1192 1230 req_vf_info && candidate->enable.vf_veceven && 1193 1231 !binary_supports_vf_format(xcandidate, req_vf_info->format)) { 1194 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1195 - "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n", 1196 - __LINE__, xcandidate->num_output_pins, 1, 1197 - req_vf_info, candidate->enable.vf_veceven, 1198 - binary_supports_vf_format(xcandidate, req_vf_info->format)); 1232 + dev_dbg(atomisp_dev, 1233 + "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n", 1234 + __LINE__, xcandidate->num_output_pins, 1, 1235 + req_vf_info, candidate->enable.vf_veceven, 1236 + binary_supports_vf_format(xcandidate, req_vf_info->format)); 1199 1237 continue; 1200 1238 } 1201 1239 ··· 1203 1241 if (xcandidate->num_output_pins == 1 && 1204 1242 req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */ 1205 1243 if (req_vf_info->res.width > candidate->output.max_width) { 1206 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1207 - "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1208 - __LINE__, 1209 - req_vf_info->res.width, 1210 - candidate->output.max_width); 1244 + dev_dbg(atomisp_dev, 1245 + "ia_css_binary_find() [%d] continue: (%d < %d)\n", 1246 + __LINE__, req_vf_info->res.width, 1247 + candidate->output.max_width); 1211 1248 continue; 1212 1249 } 1213 1250 } 1214 1251 1215 1252 if (!supports_bds_factor(candidate->bds.supported_bds_factors, 1216 1253 descr->required_bds_factor)) { 1217 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1218 - "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1219 - __LINE__, candidate->bds.supported_bds_factors, 1220 - descr->required_bds_factor); 1254 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1255 + __LINE__, candidate->bds.supported_bds_factors, 1256 + descr->required_bds_factor); 1221 1257 continue; 1222 1258 } 1223 1259 1224 1260 if (!candidate->enable.dpc && need_dpc) { 1225 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1226 - "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1227 - __LINE__, candidate->enable.dpc, 1228 - descr->enable_dpc); 1261 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1262 + __LINE__, candidate->enable.dpc, descr->enable_dpc); 1229 1263 continue; 1230 1264 } 1231 1265 1232 1266 if (candidate->uds.use_bci && enable_capture_pp_bli) { 1233 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1234 - "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1235 - __LINE__, candidate->uds.use_bci, 1236 - descr->enable_capture_pp_bli); 1267 + dev_dbg(atomisp_dev, "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n", 1268 + __LINE__, candidate->uds.use_bci, descr->enable_capture_pp_bli); 1237 1269 continue; 1238 1270 } 1239 1271 ··· 1246 1290 break; 1247 1291 } 1248 1292 1249 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1250 - "ia_css_binary_find() selected = %p, mode = %d ID = %d\n", 1251 - xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0); 1252 - 1253 - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, 1254 - "ia_css_binary_find() leave: return_err=%d\n", err); 1255 - 1256 1293 if (!err && xcandidate) 1257 - dev_dbg(atomisp_dev, 1258 - "Using binary %s (id %d), type %d, mode %d, continuous %s\n", 1259 - xcandidate->blob->name, 1260 - xcandidate->sp.id, 1261 - xcandidate->type, 1294 + dev_dbg(atomisp_dev, "Using binary %s (id %d), type %d, mode %d, continuous %s\n", 1295 + xcandidate->blob->name, xcandidate->sp.id, xcandidate->type, 1262 1296 xcandidate->sp.pipeline.mode, 1263 1297 xcandidate->sp.enable.continuous ? "true" : "false"); 1264 1298 1299 + if (err) 1300 + dev_err(atomisp_dev, "Failed to find a firmware binary matching the pipeline parameters\n"); 1265 1301 1266 1302 return err; 1267 - } 1268 - 1269 - int ia_css_binary_find(struct ia_css_binary_descr *descr, 1270 - struct ia_css_binary *binary) 1271 - { 1272 - int ret = __ia_css_binary_find(descr, binary); 1273 - 1274 - if (unlikely(ret)) { 1275 - dev_dbg(atomisp_dev, "Seeking for binary failed at:"); 1276 - dump_stack(); 1277 - } 1278 - 1279 - return ret; 1280 1303 } 1281 1304 1282 1305 unsigned
+4 -4
drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c
··· 13 13 * more details. 14 14 */ 15 15 16 + #include <linux/bitops.h> 17 + #include <linux/math.h> 16 18 #include <linux/string.h> /* for memcpy() */ 17 19 18 20 #include "system_global.h" ··· 22 20 23 21 #include "ia_css_isys.h" 24 22 #include "ia_css_debug.h" 25 - #include "math_support.h" 26 23 #include "virtual_isys.h" 27 24 #include "isp.h" 28 25 #include "sh_css_defs.h" ··· 559 558 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8); 560 559 561 560 pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel; 562 - words_per_line = ceil_div(pixels_per_line_padded, pixels_per_word); 561 + words_per_line = DIV_ROUND_UP(pixels_per_line_padded, pixels_per_word); 563 562 bytes_per_line = HIVE_ISP_DDR_WORD_BYTES * words_per_line; 564 563 565 564 return bytes_per_line; ··· 691 690 const isp2401_input_system_cfg_t *isys_cfg, 692 691 ibuf_ctrl_cfg_t *cfg) 693 692 { 694 - const s32 bits_per_byte = 8; 695 693 s32 bits_per_pixel; 696 694 s32 bytes_per_pixel; 697 695 s32 left_padding; ··· 698 698 (void)input_port; 699 699 700 700 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel; 701 - bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte); 701 + bytes_per_pixel = BITS_TO_BYTES(bits_per_pixel); 702 702 703 703 left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS) 704 704 * bytes_per_pixel;
+20 -24
drivers/staging/media/atomisp/pci/sh_css.c
··· 5826 5826 * Later, merge this with ia_css_pipe_create_cas_scaler_desc 5827 5827 */ 5828 5828 static int ia_css_pipe_create_cas_scaler_desc_single_output( 5829 - struct ia_css_frame_info *cas_scaler_in_info, 5830 - struct ia_css_frame_info *cas_scaler_out_info, 5831 - struct ia_css_frame_info *cas_scaler_vf_info, 5829 + struct ia_css_frame_info *in_info, 5830 + struct ia_css_frame_info *out_info, 5831 + struct ia_css_frame_info *vf_info, 5832 5832 struct ia_css_cas_binary_descr *descr) 5833 5833 { 5834 5834 unsigned int i; 5835 5835 unsigned int hor_ds_factor = 0, ver_ds_factor = 0; 5836 5836 int err = 0; 5837 5837 struct ia_css_frame_info tmp_in_info; 5838 - 5839 5838 unsigned int max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP; 5840 5839 5841 - assert(cas_scaler_in_info); 5842 - assert(cas_scaler_out_info); 5840 + assert(in_info); 5841 + assert(out_info); 5843 5842 5844 5843 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, 5845 5844 "ia_css_pipe_create_cas_scaler_desc() enter:\n"); ··· 5846 5847 /* We assume that this function is used only for single output port case. */ 5847 5848 descr->num_output_stage = 1; 5848 5849 5849 - hor_ds_factor = CEIL_DIV(cas_scaler_in_info->res.width, 5850 - cas_scaler_out_info->res.width); 5851 - ver_ds_factor = CEIL_DIV(cas_scaler_in_info->res.height, 5852 - cas_scaler_out_info->res.height); 5850 + hor_ds_factor = CEIL_DIV(in_info->res.width, out_info->res.width); 5851 + ver_ds_factor = CEIL_DIV(in_info->res.height, out_info->res.height); 5853 5852 /* use the same horizontal and vertical downscaling factor for simplicity */ 5854 5853 assert(hor_ds_factor == ver_ds_factor); 5855 5854 ··· 5892 5895 goto ERR; 5893 5896 } 5894 5897 5895 - tmp_in_info = *cas_scaler_in_info; 5898 + tmp_in_info = *in_info; 5896 5899 for (i = 0; i < descr->num_stage; i++) { 5897 5900 descr->in_info[i] = tmp_in_info; 5898 - if ((tmp_in_info.res.width / max_scale_factor_per_stage) <= 5899 - cas_scaler_out_info->res.width) { 5901 + if ((tmp_in_info.res.width / max_scale_factor_per_stage) <= out_info->res.width) { 5900 5902 descr->is_output_stage[i] = true; 5901 5903 if ((descr->num_output_stage > 1) && (i != (descr->num_stage - 1))) { 5902 - descr->internal_out_info[i].res.width = cas_scaler_out_info->res.width; 5903 - descr->internal_out_info[i].res.height = cas_scaler_out_info->res.height; 5904 - descr->internal_out_info[i].padded_width = cas_scaler_out_info->padded_width; 5904 + descr->internal_out_info[i].res.width = out_info->res.width; 5905 + descr->internal_out_info[i].res.height = out_info->res.height; 5906 + descr->internal_out_info[i].padded_width = out_info->padded_width; 5905 5907 descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420; 5906 5908 } else { 5907 5909 assert(i == (descr->num_stage - 1)); 5908 5910 descr->internal_out_info[i].res.width = 0; 5909 5911 descr->internal_out_info[i].res.height = 0; 5910 5912 } 5911 - descr->out_info[i].res.width = cas_scaler_out_info->res.width; 5912 - descr->out_info[i].res.height = cas_scaler_out_info->res.height; 5913 - descr->out_info[i].padded_width = cas_scaler_out_info->padded_width; 5914 - descr->out_info[i].format = cas_scaler_out_info->format; 5915 - if (cas_scaler_vf_info) { 5916 - descr->vf_info[i].res.width = cas_scaler_vf_info->res.width; 5917 - descr->vf_info[i].res.height = cas_scaler_vf_info->res.height; 5918 - descr->vf_info[i].padded_width = cas_scaler_vf_info->padded_width; 5913 + descr->out_info[i].res.width = out_info->res.width; 5914 + descr->out_info[i].res.height = out_info->res.height; 5915 + descr->out_info[i].padded_width = out_info->padded_width; 5916 + descr->out_info[i].format = out_info->format; 5917 + if (vf_info) { 5918 + descr->vf_info[i].res.width = vf_info->res.width; 5919 + descr->vf_info[i].res.height = vf_info->res.height; 5920 + descr->vf_info[i].padded_width = vf_info->padded_width; 5919 5921 ia_css_frame_info_set_format(&descr->vf_info[i], IA_CSS_FRAME_FORMAT_YUV_LINE); 5920 5922 } else { 5921 5923 descr->vf_info[i].res.width = 0;
-37
drivers/staging/media/atomisp/pci/sh_css_dvs_info.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /** 3 - Support for Intel Camera Imaging ISP subsystem. 4 - Copyright (c) 2010 - 2015, Intel Corporation. 5 - 6 - This program is free software; you can redistribute it and/or modify it 7 - under the terms and conditions of the GNU General Public License, 8 - version 2, as published by the Free Software Foundation. 9 - 10 - This program is distributed in the hope it will be useful, but WITHOUT 11 - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 - more details. 14 - */ 15 - 16 - #ifndef __SH_CSS_DVS_INFO_H__ 17 - #define __SH_CSS_DVS_INFO_H__ 18 - 19 - #include <math_support.h> 20 - 21 - /* horizontal 64x64 blocks round up to DVS_BLOCKDIM_X, make even */ 22 - #define DVS_NUM_BLOCKS_X(X) (CEIL_MUL(CEIL_DIV((X), DVS_BLOCKDIM_X), 2)) 23 - 24 - /* vertical 64x64 blocks round up to DVS_BLOCKDIM_Y */ 25 - #define DVS_NUM_BLOCKS_Y(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_LUMA)) 26 - 27 - /* Bilinear interpolation (HRT_GDC_BLI_MODE) is the supported method currently. 28 - * Bicubic interpolation (HRT_GDC_BCI_MODE) is not supported yet */ 29 - #define DVS_GDC_INTERP_METHOD HRT_GDC_BLI_MODE 30 - 31 - #define DVS_INPUT_BYTES_PER_PIXEL (1) 32 - 33 - #define DVS_NUM_BLOCKS_X_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_X)) 34 - 35 - #define DVS_NUM_BLOCKS_Y_CHROMA(X) (CEIL_DIV((X), DVS_BLOCKDIM_Y_CHROMA)) 36 - 37 - #endif /* __SH_CSS_DVS_INFO_H__ */
-1
drivers/staging/media/atomisp/pci/sh_css_param_dvs.h
··· 18 18 19 19 #include <math_support.h> 20 20 #include <ia_css_types.h> 21 - #include <sh_css_dvs_info.h> 22 21 #include "gdc_global.h" /* gdc_warp_param_mem_t */ 23 22 24 23 #define DVS_ENV_MIN_X (12)
+3 -7
drivers/staging/media/deprecated/atmel/atmel-sama5d2-isc.c
··· 333 333 static int isc_parse_dt(struct device *dev, struct isc_device *isc) 334 334 { 335 335 struct device_node *np = dev->of_node; 336 - struct device_node *epn = NULL; 336 + struct device_node *epn; 337 337 struct isc_subdev_entity *subdev_entity; 338 338 unsigned int flags; 339 - int ret; 339 + int ret = -EINVAL; 340 340 341 341 INIT_LIST_HEAD(&isc->subdev_entities); 342 342 343 - while (1) { 343 + for_each_endpoint_of_node(np, epn) { 344 344 struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; 345 - 346 - epn = of_graph_get_next_endpoint(np, epn); 347 - if (!epn) 348 - return 0; 349 345 350 346 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), 351 347 &v4l2_epn);
+3 -7
drivers/staging/media/deprecated/atmel/atmel-sama7g5-isc.c
··· 316 316 static int xisc_parse_dt(struct device *dev, struct isc_device *isc) 317 317 { 318 318 struct device_node *np = dev->of_node; 319 - struct device_node *epn = NULL; 319 + struct device_node *epn; 320 320 struct isc_subdev_entity *subdev_entity; 321 321 unsigned int flags; 322 - int ret; 322 + int ret = -EINVAL; 323 323 bool mipi_mode; 324 324 325 325 INIT_LIST_HEAD(&isc->subdev_entities); 326 326 327 327 mipi_mode = of_property_read_bool(np, "microchip,mipi-mode"); 328 328 329 - while (1) { 329 + for_each_endpoint_of_node(np, epn) { 330 330 struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; 331 - 332 - epn = of_graph_get_next_endpoint(np, epn); 333 - if (!epn) 334 - return 0; 335 331 336 332 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), 337 333 &v4l2_epn);
+31 -9
drivers/staging/media/ipu3/ipu3-v4l2.c
··· 535 535 container_of(vq, struct imgu_video_device, vbq); 536 536 int r; 537 537 unsigned int pipe; 538 + bool stop_streaming = false; 538 539 540 + /* Verify that the node had been setup with imgu_v4l2_node_setup() */ 539 541 WARN_ON(!node->enabled); 540 542 541 543 pipe = node->pipe; 542 544 dev_dbg(dev, "Try to stream off node [%u][%u]", pipe, node->id); 543 - imgu_pipe = &imgu->imgu_pipe[pipe]; 544 - r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0); 545 - if (r) 546 - dev_err(&imgu->pci_dev->dev, 547 - "failed to stop subdev streaming\n"); 548 545 546 + /* 547 + * When the first node of a streaming setup is stopped, the entire 548 + * pipeline needs to stop before individual nodes are disabled. 549 + * Perform the inverse of the initial setup. 550 + * 551 + * Part 1 - s_stream on the entire pipeline 552 + */ 549 553 mutex_lock(&imgu->streaming_lock); 550 - /* Was this the first node with streaming disabled? */ 551 - if (imgu->streaming && imgu_all_nodes_streaming(imgu, node)) { 554 + if (imgu->streaming) { 552 555 /* Yes, really stop streaming now */ 553 556 dev_dbg(dev, "IMGU streaming is ready to stop"); 554 557 r = imgu_s_stream(imgu, false); 555 558 if (!r) 556 559 imgu->streaming = false; 560 + stop_streaming = true; 557 561 } 558 - 559 - imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); 560 562 mutex_unlock(&imgu->streaming_lock); 561 563 564 + /* Part 2 - s_stream on subdevs 565 + * 566 + * If we call s_stream multiple times, Linux v6.7's call_s_stream() 567 + * WARNs and aborts. Thus, disable all pipes at once, and only once. 568 + */ 569 + if (stop_streaming) { 570 + for_each_set_bit(pipe, imgu->css.enabled_pipes, 571 + IMGU_MAX_PIPE_NUM) { 572 + imgu_pipe = &imgu->imgu_pipe[pipe]; 573 + 574 + r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, 575 + video, s_stream, 0); 576 + if (r) 577 + dev_err(&imgu->pci_dev->dev, 578 + "failed to stop subdev streaming\n"); 579 + } 580 + } 581 + 582 + /* Part 3 - individual node teardown */ 562 583 video_device_pipeline_stop(&node->vdev); 584 + imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); 563 585 } 564 586 565 587 /******************** v4l2_ioctl_ops ********************/
+2
drivers/staging/media/meson/vdec/vdec.c
··· 982 982 .data = &vdec_platform_gxm }, 983 983 { .compatible = "amlogic,gxl-vdec", 984 984 .data = &vdec_platform_gxl }, 985 + { .compatible = "amlogic,gxlx-vdec", 986 + .data = &vdec_platform_gxlx }, 985 987 { .compatible = "amlogic,g12a-vdec", 986 988 .data = &vdec_platform_g12a }, 987 989 { .compatible = "amlogic,sm1-vdec",
+12 -4
drivers/staging/media/meson/vdec/vdec_1.c
··· 129 129 return amvdec_read_dos(core, VLD_MEM_VIFIFO_LEVEL); 130 130 } 131 131 132 - static int vdec_1_stop(struct amvdec_session *sess) 132 + static void __vdec_1_stop(struct amvdec_session *sess) 133 133 { 134 134 struct amvdec_core *core = sess->core; 135 135 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ··· 158 158 regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, 159 159 GEN_PWR_VDEC_1, GEN_PWR_VDEC_1); 160 160 161 - clk_disable_unprepare(core->vdec_1_clk); 162 - 163 161 if (sess->priv) 164 162 codec_ops->stop(sess); 163 + } 164 + 165 + static int vdec_1_stop(struct amvdec_session *sess) 166 + { 167 + struct amvdec_core *core = sess->core; 168 + 169 + __vdec_1_stop(sess); 170 + 171 + clk_disable_unprepare(core->vdec_1_clk); 165 172 166 173 return 0; 167 174 } ··· 242 235 return 0; 243 236 244 237 stop: 245 - vdec_1_stop(sess); 238 + __vdec_1_stop(sess); 239 + clk_disable_unprepare(core->vdec_1_clk); 246 240 return ret; 247 241 } 248 242
+32 -11
drivers/staging/media/meson/vdec/vdec_hevc.c
··· 110 110 return readl_relaxed(sess->core->dos_base + HEVC_STREAM_LEVEL); 111 111 } 112 112 113 - static int vdec_hevc_stop(struct amvdec_session *sess) 113 + static void __vdec_hevc_stop(struct amvdec_session *sess) 114 114 { 115 115 struct amvdec_core *core = sess->core; 116 116 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; ··· 142 142 else 143 143 regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, 144 144 GEN_PWR_VDEC_HEVC, GEN_PWR_VDEC_HEVC); 145 + } 146 + 147 + static int vdec_hevc_stop(struct amvdec_session *sess) 148 + { 149 + struct amvdec_core *core = sess->core; 150 + 151 + __vdec_hevc_stop(sess); 145 152 146 153 clk_disable_unprepare(core->vdec_hevc_clk); 147 154 if (core->platform->revision == VDEC_REVISION_G12A || ··· 158 151 return 0; 159 152 } 160 153 161 - static int vdec_hevc_start(struct amvdec_session *sess) 154 + static int __vdec_hevc_start(struct amvdec_session *sess) 162 155 { 163 156 int ret; 164 157 struct amvdec_core *core = sess->core; 165 158 struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops; 166 - 167 - if (core->platform->revision == VDEC_REVISION_G12A || 168 - core->platform->revision == VDEC_REVISION_SM1) { 169 - clk_set_rate(core->vdec_hevcf_clk, 666666666); 170 - ret = clk_prepare_enable(core->vdec_hevcf_clk); 171 - if (ret) 172 - return ret; 173 - } 174 159 175 160 clk_set_rate(core->vdec_hevc_clk, 666666666); 176 161 ret = clk_prepare_enable(core->vdec_hevc_clk); ··· 222 223 return 0; 223 224 224 225 stop: 225 - vdec_hevc_stop(sess); 226 + __vdec_hevc_stop(sess); 227 + clk_disable_unprepare(core->vdec_hevc_clk); 226 228 return ret; 229 + } 230 + 231 + static int vdec_hevc_start(struct amvdec_session *sess) 232 + { 233 + struct amvdec_core *core = sess->core; 234 + int ret; 235 + 236 + if (core->platform->revision == VDEC_REVISION_G12A || 237 + core->platform->revision == VDEC_REVISION_SM1) { 238 + clk_set_rate(core->vdec_hevcf_clk, 666666666); 239 + ret = clk_prepare_enable(core->vdec_hevcf_clk); 240 + if (ret) 241 + return ret; 242 + 243 + ret = __vdec_hevc_start(sess); 244 + if (ret) 245 + clk_disable_unprepare(core->vdec_hevcf_clk); 246 + return ret; 247 + } 248 + 249 + return __vdec_hevc_start(sess); 227 250 } 228 251 229 252 struct amvdec_ops vdec_hevc_ops = {
+44
drivers/staging/media/meson/vdec/vdec_platform.c
··· 101 101 }, 102 102 }; 103 103 104 + static const struct amvdec_format vdec_formats_gxlx[] = { 105 + { 106 + .pixfmt = V4L2_PIX_FMT_H264, 107 + .min_buffers = 2, 108 + .max_buffers = 24, 109 + .max_width = 3840, 110 + .max_height = 2160, 111 + .vdec_ops = &vdec_1_ops, 112 + .codec_ops = &codec_h264_ops, 113 + .firmware_path = "meson/vdec/gxl_h264.bin", 114 + .pixfmts_cap = { V4L2_PIX_FMT_NV12M, 0 }, 115 + .flags = V4L2_FMT_FLAG_COMPRESSED | 116 + V4L2_FMT_FLAG_DYN_RESOLUTION, 117 + }, { 118 + .pixfmt = V4L2_PIX_FMT_MPEG1, 119 + .min_buffers = 8, 120 + .max_buffers = 8, 121 + .max_width = 1920, 122 + .max_height = 1080, 123 + .vdec_ops = &vdec_1_ops, 124 + .codec_ops = &codec_mpeg12_ops, 125 + .firmware_path = "meson/vdec/gxl_mpeg12.bin", 126 + .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, 127 + .flags = V4L2_FMT_FLAG_COMPRESSED, 128 + }, { 129 + .pixfmt = V4L2_PIX_FMT_MPEG2, 130 + .min_buffers = 8, 131 + .max_buffers = 8, 132 + .max_width = 1920, 133 + .max_height = 1080, 134 + .vdec_ops = &vdec_1_ops, 135 + .codec_ops = &codec_mpeg12_ops, 136 + .firmware_path = "meson/vdec/gxl_mpeg12.bin", 137 + .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 }, 138 + .flags = V4L2_FMT_FLAG_COMPRESSED, 139 + }, 140 + }; 141 + 104 142 static const struct amvdec_format vdec_formats_gxm[] = { 105 143 { 106 144 .pixfmt = V4L2_PIX_FMT_VP9, ··· 299 261 .formats = vdec_formats_gxl, 300 262 .num_formats = ARRAY_SIZE(vdec_formats_gxl), 301 263 .revision = VDEC_REVISION_GXL, 264 + }; 265 + 266 + const struct vdec_platform vdec_platform_gxlx = { 267 + .formats = vdec_formats_gxlx, 268 + .num_formats = ARRAY_SIZE(vdec_formats_gxlx), 269 + .revision = VDEC_REVISION_GXLX, 302 270 }; 303 271 304 272 const struct vdec_platform vdec_platform_gxm = {
+2
drivers/staging/media/meson/vdec/vdec_platform.h
··· 14 14 enum vdec_revision { 15 15 VDEC_REVISION_GXBB, 16 16 VDEC_REVISION_GXL, 17 + VDEC_REVISION_GXLX, 17 18 VDEC_REVISION_GXM, 18 19 VDEC_REVISION_G12A, 19 20 VDEC_REVISION_SM1, ··· 29 28 extern const struct vdec_platform vdec_platform_gxbb; 30 29 extern const struct vdec_platform vdec_platform_gxm; 31 30 extern const struct vdec_platform vdec_platform_gxl; 31 + extern const struct vdec_platform vdec_platform_gxlx; 32 32 extern const struct vdec_platform vdec_platform_g12a; 33 33 extern const struct vdec_platform vdec_platform_sm1; 34 34
-2
drivers/staging/media/starfive/camss/stf-camss.c
··· 358 358 /* 359 359 * stfcamss_remove - Remove STFCAMSS platform device 360 360 * @pdev: Pointer to STFCAMSS platform device 361 - * 362 - * Always returns 0. 363 361 */ 364 362 static void stfcamss_remove(struct platform_device *pdev) 365 363 {
+3 -1
drivers/staging/media/starfive/camss/stf-capture.c
··· 180 180 u32 val; 181 181 182 182 if (cap->type == STF_CAPTURE_RAW) { 183 + const struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix; 184 + 183 185 val = stf_syscon_reg_read(stfcamss, VIN_CHANNEL_SEL_EN); 184 186 val &= ~U0_VIN_CHANNEL_SEL_MASK; 185 187 val |= CHANNEL(0); ··· 195 193 val |= PIXEL_HEIGH_BIT_SEL(0); 196 194 197 195 val &= ~U0_VIN_PIX_CNT_END_MASK; 198 - val |= PIX_CNT_END(IMAGE_MAX_WIDTH / 4 - 1); 196 + val |= PIX_CNT_END(pix->width / 4 - 1); 199 197 200 198 stf_syscon_reg_write(stfcamss, VIN_INRT_PIX_CFG, val); 201 199 } else if (cap->type == STF_CAPTURE_YUV) {
+33
include/media/cec.h
··· 66 66 struct list_head xfer_list; 67 67 struct cec_adapter *adap; 68 68 struct cec_msg msg; 69 + u8 match_len; 70 + u8 match_reply[5]; 69 71 struct cec_fh *fh; 70 72 struct delayed_work work; 71 73 struct completion c; ··· 297 295 298 296 char input_phys[40]; 299 297 }; 298 + 299 + static inline int cec_get_device(struct cec_adapter *adap) 300 + { 301 + struct cec_devnode *devnode = &adap->devnode; 302 + 303 + /* 304 + * Check if the cec device is available. This needs to be done with 305 + * the devnode->lock held to prevent an open/unregister race: 306 + * without the lock, the device could be unregistered and freed between 307 + * the devnode->registered check and get_device() calls, leading to 308 + * a crash. 309 + */ 310 + mutex_lock(&devnode->lock); 311 + /* 312 + * return ENODEV if the cec device has been removed 313 + * already or if it is not registered anymore. 314 + */ 315 + if (!devnode->registered) { 316 + mutex_unlock(&devnode->lock); 317 + return -ENODEV; 318 + } 319 + /* and increase the device refcount */ 320 + get_device(&devnode->dev); 321 + mutex_unlock(&devnode->lock); 322 + return 0; 323 + } 324 + 325 + static inline void cec_put_device(struct cec_adapter *adap) 326 + { 327 + put_device(&adap->devnode.dev); 328 + } 300 329 301 330 static inline void *cec_get_drvdata(const struct cec_adapter *adap) 302 331 {
-2
include/media/rc-core.h
··· 127 127 * @min_timeout: minimum timeout supported by device 128 128 * @max_timeout: maximum timeout supported by device 129 129 * @rx_resolution : resolution (in us) of input sampler 130 - * @tx_resolution: resolution (in us) of output sampler 131 130 * @lirc_dev: lirc device 132 131 * @lirc_cdev: lirc char cdev 133 132 * @gap_start: start time for gap after timeout if non-zero ··· 193 194 u32 min_timeout; 194 195 u32 max_timeout; 195 196 u32 rx_resolution; 196 - u32 tx_resolution; 197 197 #ifdef CONFIG_LIRC 198 198 struct device lirc_dev; 199 199 struct cdev lirc_cdev;
+3
include/media/v4l2-mc.h
··· 178 178 * @flags: New link flags that will be applied 179 179 * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*) 180 180 * 181 + * THIS FUNCTION IS DEPRECATED. DO NOT USE IN NEW DRIVERS. USE RUNTIME PM 182 + * ON SUB-DEVICE DRIVERS INSTEAD. 183 + * 181 184 * React to link management on powered pipelines by updating the use count of 182 185 * all entities in the source and sink sides of the link. Entities are powered 183 186 * on or off accordingly. The use of this function should be paired
+6
include/media/v4l2-subdev.h
··· 1250 1250 * calls v4l2_subdev_link_validate_default() to ensure that 1251 1251 * width, height and the media bus pixel code are equal on both 1252 1252 * source and sink of the link. 1253 + * 1254 + * The function can be used as a drop-in &media_entity_ops.link_validate 1255 + * implementation for v4l2_subdev instances. It supports all links between 1256 + * subdevs, as well as links between subdevs and video devices, provided that 1257 + * the video devices also implement their &media_entity_ops.link_validate 1258 + * operation. 1253 1259 */ 1254 1260 int v4l2_subdev_link_validate(struct media_link *link); 1255 1261
+3
include/media/videobuf2-core.h
··· 154 154 * @mem_priv: private data with this plane. 155 155 * @dbuf: dma_buf - shared buffer object. 156 156 * @dbuf_mapped: flag to show whether dbuf is mapped or not 157 + * @dbuf_duplicated: boolean to show whether dbuf is duplicated with a 158 + * previous plane of the buffer. 157 159 * @bytesused: number of bytes occupied by data in the plane (payload). 158 160 * @length: size of this plane (NOT the payload) in bytes. The maximum 159 161 * valid size is MAX_UINT - PAGE_SIZE. ··· 181 179 void *mem_priv; 182 180 struct dma_buf *dbuf; 183 181 unsigned int dbuf_mapped; 182 + bool dbuf_duplicated; 184 183 unsigned int bytesused; 185 184 unsigned int length; 186 185 unsigned int min_length;
+8 -1
include/uapi/linux/cec.h
··· 132 132 * Set the msg destination to the orig initiator and the msg initiator to the 133 133 * orig destination. Note that msg and orig may be the same pointer, in which 134 134 * case the change is done in place. 135 + * 136 + * It also zeroes the reply, timeout and flags fields. 135 137 */ 136 138 static inline void cec_msg_set_reply_to(struct cec_msg *msg, 137 139 struct cec_msg *orig) ··· 141 139 /* The destination becomes the initiator and vice versa */ 142 140 msg->msg[0] = (cec_msg_destination(orig) << 4) | 143 141 cec_msg_initiator(orig); 144 - msg->reply = msg->timeout = 0; 142 + msg->reply = 0; 143 + msg->timeout = 0; 144 + msg->flags = 0; 145 145 } 146 146 147 147 /** ··· 169 165 /* cec_msg flags field */ 170 166 #define CEC_MSG_FL_REPLY_TO_FOLLOWERS (1 << 0) 171 167 #define CEC_MSG_FL_RAW (1 << 1) 168 + #define CEC_MSG_FL_REPLY_VENDOR_ID (1 << 2) 172 169 173 170 /* cec_msg tx/rx_status field */ 174 171 #define CEC_TX_STATUS_OK (1 << 0) ··· 344 339 #define CEC_CAP_MONITOR_PIN (1 << 7) 345 340 /* CEC_ADAP_G_CONNECTOR_INFO is available */ 346 341 #define CEC_CAP_CONNECTOR_INFO (1 << 8) 342 + /* CEC_MSG_FL_REPLY_VENDOR_ID is available */ 343 + #define CEC_CAP_REPLY_VENDOR_ID (1 << 9) 347 344 348 345 /** 349 346 * struct cec_caps - CEC capabilities structure.
+578
include/uapi/linux/rkisp1-config.h
··· 165 165 #define RKISP1_CIF_ISP_DPF_MAX_SPATIAL_COEFFS 6 166 166 167 167 /* 168 + * Compand 169 + */ 170 + #define RKISP1_CIF_ISP_COMPAND_NUM_POINTS 64 171 + 172 + /* 168 173 * Measurement types 169 174 */ 170 175 #define RKISP1_CIF_ISP_STAT_AWB (1U << 0) ··· 856 851 struct rkisp1_cif_isp_isp_other_cfg others; 857 852 }; 858 853 854 + /** 855 + * struct rkisp1_cif_isp_compand_bls_config - Rockchip ISP1 Companding parameters (BLS) 856 + * @r: Fixed subtraction value for Bayer pattern R 857 + * @gr: Fixed subtraction value for Bayer pattern Gr 858 + * @gb: Fixed subtraction value for Bayer pattern Gb 859 + * @b: Fixed subtraction value for Bayer pattern B 860 + * 861 + * The values will be subtracted from the sensor values. Note that unlike the 862 + * dedicated BLS block, the BLS values in the compander are 20-bit unsigned. 863 + */ 864 + struct rkisp1_cif_isp_compand_bls_config { 865 + __u32 r; 866 + __u32 gr; 867 + __u32 gb; 868 + __u32 b; 869 + }; 870 + 871 + /** 872 + * struct rkisp1_cif_isp_compand_curve_config - Rockchip ISP1 Companding 873 + * parameters (expand and compression curves) 874 + * @px: Compand curve x-values. Each value stores the distance from the 875 + * previous x-value, expressed as log2 of the distance on 5 bits. 876 + * @x: Compand curve x-values. The functionality of these parameters are 877 + * unknown due to do a lack of hardware documentation, but these are left 878 + * here for future compatibility purposes. 879 + * @y: Compand curve y-values 880 + */ 881 + struct rkisp1_cif_isp_compand_curve_config { 882 + __u8 px[RKISP1_CIF_ISP_COMPAND_NUM_POINTS]; 883 + __u32 x[RKISP1_CIF_ISP_COMPAND_NUM_POINTS]; 884 + __u32 y[RKISP1_CIF_ISP_COMPAND_NUM_POINTS]; 885 + }; 886 + 859 887 /*---------- PART2: Measurement Statistics ------------*/ 860 888 861 889 /** ··· 1032 994 __u32 meas_type; 1033 995 __u32 frame_id; 1034 996 struct rkisp1_cif_isp_stat params; 997 + }; 998 + 999 + /*---------- PART3: Extensible Configuration Parameters ------------*/ 1000 + 1001 + /** 1002 + * enum rkisp1_ext_params_block_type - RkISP1 extensible params block type 1003 + * 1004 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS: Black level subtraction 1005 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC: Defect pixel cluster correction 1006 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG: Sensor de-gamma 1007 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN: Auto white balance gains 1008 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT: ISP filtering 1009 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM: Bayer de-mosaic 1010 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK: Cross-talk correction 1011 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC: Gamma out correction 1012 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF: De-noise pre-filter 1013 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH: De-noise pre-filter strength 1014 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC: Color processing 1015 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_IE: Image effects 1016 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC: Lens shading correction 1017 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS: Auto white balance statistics 1018 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS: Histogram statistics 1019 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS: Auto exposure statistics 1020 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS: Auto-focus statistics 1021 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS: BLS in the compand block 1022 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND: Companding expand curve 1023 + * @RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS: Companding compress curve 1024 + */ 1025 + enum rkisp1_ext_params_block_type { 1026 + RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS, 1027 + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC, 1028 + RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG, 1029 + RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN, 1030 + RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT, 1031 + RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM, 1032 + RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK, 1033 + RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC, 1034 + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF, 1035 + RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH, 1036 + RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC, 1037 + RKISP1_EXT_PARAMS_BLOCK_TYPE_IE, 1038 + RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC, 1039 + RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS, 1040 + RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS, 1041 + RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS, 1042 + RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS, 1043 + RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS, 1044 + RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND, 1045 + RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS, 1046 + }; 1047 + 1048 + #define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE (1U << 0) 1049 + #define RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE (1U << 1) 1050 + 1051 + /** 1052 + * struct rkisp1_ext_params_block_header - RkISP1 extensible parameters block 1053 + * header 1054 + * 1055 + * This structure represents the common part of all the ISP configuration 1056 + * blocks. Each parameters block shall embed an instance of this structure type 1057 + * as its first member, followed by the block-specific configuration data. The 1058 + * driver inspects this common header to discern the block type and its size and 1059 + * properly handle the block content by casting it to the correct block-specific 1060 + * type. 1061 + * 1062 + * The @type field is one of the values enumerated by 1063 + * :c:type:`rkisp1_ext_params_block_type` and specifies how the data should be 1064 + * interpreted by the driver. The @size field specifies the size of the 1065 + * parameters block and is used by the driver for validation purposes. 1066 + * 1067 + * The @flags field is a bitmask of per-block flags RKISP1_EXT_PARAMS_FL_*. 1068 + * 1069 + * When userspace wants to configure and enable an ISP block it shall fully 1070 + * populate the block configuration and set the 1071 + * RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE bit in the @flags field. 1072 + * 1073 + * When userspace simply wants to disable an ISP block the 1074 + * RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bit should be set in @flags field. The 1075 + * driver ignores the rest of the block configuration structure in this case. 1076 + * 1077 + * If a new configuration of an ISP block has to be applied userspace shall 1078 + * fully populate the ISP block configuration and omit setting the 1079 + * RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE and RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bits 1080 + * in the @flags field. 1081 + * 1082 + * Setting both the RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE and 1083 + * RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bits in the @flags field is not allowed 1084 + * and not accepted by the driver. 1085 + * 1086 + * Userspace is responsible for correctly populating the parameters block header 1087 + * fields (@type, @flags and @size) and the block-specific parameters. 1088 + * 1089 + * For example: 1090 + * 1091 + * .. code-block:: c 1092 + * 1093 + * void populate_bls(struct rkisp1_ext_params_block_header *block) { 1094 + * struct rkisp1_ext_params_bls_config *bls = 1095 + * (struct rkisp1_ext_params_bls_config *)block; 1096 + * 1097 + * bls->header.type = RKISP1_EXT_PARAMS_BLOCK_ID_BLS; 1098 + * bls->header.flags = RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE; 1099 + * bls->header.size = sizeof(*bls); 1100 + * 1101 + * bls->config.enable_auto = 0; 1102 + * bls->config.fixed_val.r = blackLevelRed_; 1103 + * bls->config.fixed_val.gr = blackLevelGreenR_; 1104 + * bls->config.fixed_val.gb = blackLevelGreenB_; 1105 + * bls->config.fixed_val.b = blackLevelBlue_; 1106 + * } 1107 + * 1108 + * @type: The parameters block type, see 1109 + * :c:type:`rkisp1_ext_params_block_type` 1110 + * @flags: A bitmask of block flags 1111 + * @size: Size (in bytes) of the parameters block, including this header 1112 + */ 1113 + struct rkisp1_ext_params_block_header { 1114 + __u16 type; 1115 + __u16 flags; 1116 + __u32 size; 1117 + }; 1118 + 1119 + /** 1120 + * struct rkisp1_ext_params_bls_config - RkISP1 extensible params BLS config 1121 + * 1122 + * RkISP1 extensible parameters Black Level Subtraction configuration block. 1123 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS`. 1124 + * 1125 + * @header: The RkISP1 extensible parameters header, see 1126 + * :c:type:`rkisp1_ext_params_block_header` 1127 + * @config: Black Level Subtraction configuration, see 1128 + * :c:type:`rkisp1_cif_isp_bls_config` 1129 + */ 1130 + struct rkisp1_ext_params_bls_config { 1131 + struct rkisp1_ext_params_block_header header; 1132 + struct rkisp1_cif_isp_bls_config config; 1133 + } __attribute__((aligned(8))); 1134 + 1135 + /** 1136 + * struct rkisp1_ext_params_dpcc_config - RkISP1 extensible params DPCC config 1137 + * 1138 + * RkISP1 extensible parameters Defective Pixel Cluster Correction configuration 1139 + * block. Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC`. 1140 + * 1141 + * @header: The RkISP1 extensible parameters header, see 1142 + * :c:type:`rkisp1_ext_params_block_header` 1143 + * @config: Defective Pixel Cluster Correction configuration, see 1144 + * :c:type:`rkisp1_cif_isp_dpcc_config` 1145 + */ 1146 + struct rkisp1_ext_params_dpcc_config { 1147 + struct rkisp1_ext_params_block_header header; 1148 + struct rkisp1_cif_isp_dpcc_config config; 1149 + } __attribute__((aligned(8))); 1150 + 1151 + /** 1152 + * struct rkisp1_ext_params_sdg_config - RkISP1 extensible params SDG config 1153 + * 1154 + * RkISP1 extensible parameters Sensor Degamma configuration block. Identified 1155 + * by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG`. 1156 + * 1157 + * @header: The RkISP1 extensible parameters header, see 1158 + * :c:type:`rkisp1_ext_params_block_header` 1159 + * @config: Sensor Degamma configuration, see 1160 + * :c:type:`rkisp1_cif_isp_sdg_config` 1161 + */ 1162 + struct rkisp1_ext_params_sdg_config { 1163 + struct rkisp1_ext_params_block_header header; 1164 + struct rkisp1_cif_isp_sdg_config config; 1165 + } __attribute__((aligned(8))); 1166 + 1167 + /** 1168 + * struct rkisp1_ext_params_lsc_config - RkISP1 extensible params LSC config 1169 + * 1170 + * RkISP1 extensible parameters Lens Shading Correction configuration block. 1171 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC`. 1172 + * 1173 + * @header: The RkISP1 extensible parameters header, see 1174 + * :c:type:`rkisp1_ext_params_block_header` 1175 + * @config: Lens Shading Correction configuration, see 1176 + * :c:type:`rkisp1_cif_isp_lsc_config` 1177 + */ 1178 + struct rkisp1_ext_params_lsc_config { 1179 + struct rkisp1_ext_params_block_header header; 1180 + struct rkisp1_cif_isp_lsc_config config; 1181 + } __attribute__((aligned(8))); 1182 + 1183 + /** 1184 + * struct rkisp1_ext_params_awb_gain_config - RkISP1 extensible params AWB 1185 + * gain config 1186 + * 1187 + * RkISP1 extensible parameters Auto-White Balance Gains configuration block. 1188 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN`. 1189 + * 1190 + * @header: The RkISP1 extensible parameters header, see 1191 + * :c:type:`rkisp1_ext_params_block_header` 1192 + * @config: Auto-White Balance Gains configuration, see 1193 + * :c:type:`rkisp1_cif_isp_awb_gain_config` 1194 + */ 1195 + struct rkisp1_ext_params_awb_gain_config { 1196 + struct rkisp1_ext_params_block_header header; 1197 + struct rkisp1_cif_isp_awb_gain_config config; 1198 + } __attribute__((aligned(8))); 1199 + 1200 + /** 1201 + * struct rkisp1_ext_params_flt_config - RkISP1 extensible params FLT config 1202 + * 1203 + * RkISP1 extensible parameters Filter configuration block. Identified by 1204 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT`. 1205 + * 1206 + * @header: The RkISP1 extensible parameters header, see 1207 + * :c:type:`rkisp1_ext_params_block_header` 1208 + * @config: Filter configuration, see :c:type:`rkisp1_cif_isp_flt_config` 1209 + */ 1210 + struct rkisp1_ext_params_flt_config { 1211 + struct rkisp1_ext_params_block_header header; 1212 + struct rkisp1_cif_isp_flt_config config; 1213 + } __attribute__((aligned(8))); 1214 + 1215 + /** 1216 + * struct rkisp1_ext_params_bdm_config - RkISP1 extensible params BDM config 1217 + * 1218 + * RkISP1 extensible parameters Demosaicing configuration block. Identified by 1219 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM`. 1220 + * 1221 + * @header: The RkISP1 extensible parameters header, see 1222 + * :c:type:`rkisp1_ext_params_block_header` 1223 + * @config: Demosaicing configuration, see :c:type:`rkisp1_cif_isp_bdm_config` 1224 + */ 1225 + struct rkisp1_ext_params_bdm_config { 1226 + struct rkisp1_ext_params_block_header header; 1227 + struct rkisp1_cif_isp_bdm_config config; 1228 + } __attribute__((aligned(8))); 1229 + 1230 + /** 1231 + * struct rkisp1_ext_params_ctk_config - RkISP1 extensible params CTK config 1232 + * 1233 + * RkISP1 extensible parameters Cross-Talk configuration block. Identified by 1234 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK`. 1235 + * 1236 + * @header: The RkISP1 extensible parameters header, see 1237 + * :c:type:`rkisp1_ext_params_block_header` 1238 + * @config: Cross-Talk configuration, see :c:type:`rkisp1_cif_isp_ctk_config` 1239 + */ 1240 + struct rkisp1_ext_params_ctk_config { 1241 + struct rkisp1_ext_params_block_header header; 1242 + struct rkisp1_cif_isp_ctk_config config; 1243 + } __attribute__((aligned(8))); 1244 + 1245 + /** 1246 + * struct rkisp1_ext_params_goc_config - RkISP1 extensible params GOC config 1247 + * 1248 + * RkISP1 extensible parameters Gamma-Out configuration block. Identified by 1249 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC`. 1250 + * 1251 + * @header: The RkISP1 extensible parameters header, see 1252 + * :c:type:`rkisp1_ext_params_block_header` 1253 + * @config: Gamma-Out configuration, see :c:type:`rkisp1_cif_isp_goc_config` 1254 + */ 1255 + struct rkisp1_ext_params_goc_config { 1256 + struct rkisp1_ext_params_block_header header; 1257 + struct rkisp1_cif_isp_goc_config config; 1258 + } __attribute__((aligned(8))); 1259 + 1260 + /** 1261 + * struct rkisp1_ext_params_dpf_config - RkISP1 extensible params DPF config 1262 + * 1263 + * RkISP1 extensible parameters De-noise Pre-Filter configuration block. 1264 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF`. 1265 + * 1266 + * @header: The RkISP1 extensible parameters header, see 1267 + * :c:type:`rkisp1_ext_params_block_header` 1268 + * @config: De-noise Pre-Filter configuration, see 1269 + * :c:type:`rkisp1_cif_isp_dpf_config` 1270 + */ 1271 + struct rkisp1_ext_params_dpf_config { 1272 + struct rkisp1_ext_params_block_header header; 1273 + struct rkisp1_cif_isp_dpf_config config; 1274 + } __attribute__((aligned(8))); 1275 + 1276 + /** 1277 + * struct rkisp1_ext_params_dpf_strength_config - RkISP1 extensible params DPF 1278 + * strength config 1279 + * 1280 + * RkISP1 extensible parameters De-noise Pre-Filter strength configuration 1281 + * block. Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH`. 1282 + * 1283 + * @header: The RkISP1 extensible parameters header, see 1284 + * :c:type:`rkisp1_ext_params_block_header` 1285 + * @config: De-noise Pre-Filter strength configuration, see 1286 + * :c:type:`rkisp1_cif_isp_dpf_strength_config` 1287 + */ 1288 + struct rkisp1_ext_params_dpf_strength_config { 1289 + struct rkisp1_ext_params_block_header header; 1290 + struct rkisp1_cif_isp_dpf_strength_config config; 1291 + } __attribute__((aligned(8))); 1292 + 1293 + /** 1294 + * struct rkisp1_ext_params_cproc_config - RkISP1 extensible params CPROC config 1295 + * 1296 + * RkISP1 extensible parameters Color Processing configuration block. 1297 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC`. 1298 + * 1299 + * @header: The RkISP1 extensible parameters header, see 1300 + * :c:type:`rkisp1_ext_params_block_header` 1301 + * @config: Color processing configuration, see 1302 + * :c:type:`rkisp1_cif_isp_cproc_config` 1303 + */ 1304 + struct rkisp1_ext_params_cproc_config { 1305 + struct rkisp1_ext_params_block_header header; 1306 + struct rkisp1_cif_isp_cproc_config config; 1307 + } __attribute__((aligned(8))); 1308 + 1309 + /** 1310 + * struct rkisp1_ext_params_ie_config - RkISP1 extensible params IE config 1311 + * 1312 + * RkISP1 extensible parameters Image Effect configuration block. Identified by 1313 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_IE`. 1314 + * 1315 + * @header: The RkISP1 extensible parameters header, see 1316 + * :c:type:`rkisp1_ext_params_block_header` 1317 + * @config: Image Effect configuration, see :c:type:`rkisp1_cif_isp_ie_config` 1318 + */ 1319 + struct rkisp1_ext_params_ie_config { 1320 + struct rkisp1_ext_params_block_header header; 1321 + struct rkisp1_cif_isp_ie_config config; 1322 + } __attribute__((aligned(8))); 1323 + 1324 + /** 1325 + * struct rkisp1_ext_params_awb_meas_config - RkISP1 extensible params AWB 1326 + * Meas config 1327 + * 1328 + * RkISP1 extensible parameters Auto-White Balance Measurement configuration 1329 + * block. Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS`. 1330 + * 1331 + * @header: The RkISP1 extensible parameters header, see 1332 + * :c:type:`rkisp1_ext_params_block_header` 1333 + * @config: Auto-White Balance measure configuration, see 1334 + * :c:type:`rkisp1_cif_isp_awb_meas_config` 1335 + */ 1336 + struct rkisp1_ext_params_awb_meas_config { 1337 + struct rkisp1_ext_params_block_header header; 1338 + struct rkisp1_cif_isp_awb_meas_config config; 1339 + } __attribute__((aligned(8))); 1340 + 1341 + /** 1342 + * struct rkisp1_ext_params_hst_config - RkISP1 extensible params Histogram config 1343 + * 1344 + * RkISP1 extensible parameters Histogram statistics configuration block. 1345 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS`. 1346 + * 1347 + * @header: The RkISP1 extensible parameters header, see 1348 + * :c:type:`rkisp1_ext_params_block_header` 1349 + * @config: Histogram statistics configuration, see 1350 + * :c:type:`rkisp1_cif_isp_hst_config` 1351 + */ 1352 + struct rkisp1_ext_params_hst_config { 1353 + struct rkisp1_ext_params_block_header header; 1354 + struct rkisp1_cif_isp_hst_config config; 1355 + } __attribute__((aligned(8))); 1356 + 1357 + /** 1358 + * struct rkisp1_ext_params_aec_config - RkISP1 extensible params AEC config 1359 + * 1360 + * RkISP1 extensible parameters Auto-Exposure statistics configuration block. 1361 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS`. 1362 + * 1363 + * @header: The RkISP1 extensible parameters header, see 1364 + * :c:type:`rkisp1_ext_params_block_header` 1365 + * @config: Auto-Exposure statistics configuration, see 1366 + * :c:type:`rkisp1_cif_isp_aec_config` 1367 + */ 1368 + struct rkisp1_ext_params_aec_config { 1369 + struct rkisp1_ext_params_block_header header; 1370 + struct rkisp1_cif_isp_aec_config config; 1371 + } __attribute__((aligned(8))); 1372 + 1373 + /** 1374 + * struct rkisp1_ext_params_afc_config - RkISP1 extensible params AFC config 1375 + * 1376 + * RkISP1 extensible parameters Auto-Focus statistics configuration block. 1377 + * Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS`. 1378 + * 1379 + * @header: The RkISP1 extensible parameters header, see 1380 + * :c:type:`rkisp1_ext_params_block_header` 1381 + * @config: Auto-Focus statistics configuration, see 1382 + * :c:type:`rkisp1_cif_isp_afc_config` 1383 + */ 1384 + struct rkisp1_ext_params_afc_config { 1385 + struct rkisp1_ext_params_block_header header; 1386 + struct rkisp1_cif_isp_afc_config config; 1387 + } __attribute__((aligned(8))); 1388 + 1389 + /** 1390 + * struct rkisp1_ext_params_compand_bls_config - RkISP1 extensible params 1391 + * Compand BLS config 1392 + * 1393 + * RkISP1 extensible parameters Companding configuration block (black level 1394 + * subtraction). Identified by :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS`. 1395 + * 1396 + * @header: The RkISP1 extensible parameters header, see 1397 + * :c:type:`rkisp1_ext_params_block_header` 1398 + * @config: Companding BLS configuration, see 1399 + * :c:type:`rkisp1_cif_isp_compand_bls_config` 1400 + */ 1401 + struct rkisp1_ext_params_compand_bls_config { 1402 + struct rkisp1_ext_params_block_header header; 1403 + struct rkisp1_cif_isp_compand_bls_config config; 1404 + } __attribute__((aligned(8))); 1405 + 1406 + /** 1407 + * struct rkisp1_ext_params_compand_curve_config - RkISP1 extensible params 1408 + * Compand curve config 1409 + * 1410 + * RkISP1 extensible parameters Companding configuration block (expand and 1411 + * compression curves). Identified by 1412 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND` or 1413 + * :c:type:`RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS`. 1414 + * 1415 + * @header: The RkISP1 extensible parameters header, see 1416 + * :c:type:`rkisp1_ext_params_block_header` 1417 + * @config: Companding curve configuration, see 1418 + * :c:type:`rkisp1_cif_isp_compand_curve_config` 1419 + */ 1420 + struct rkisp1_ext_params_compand_curve_config { 1421 + struct rkisp1_ext_params_block_header header; 1422 + struct rkisp1_cif_isp_compand_curve_config config; 1423 + } __attribute__((aligned(8))); 1424 + 1425 + /* 1426 + * The rkisp1_ext_params_compand_curve_config structure is counted twice as it 1427 + * is used for both the COMPAND_EXPAND and COMPAND_COMPRESS block types. 1428 + */ 1429 + #define RKISP1_EXT_PARAMS_MAX_SIZE \ 1430 + (sizeof(struct rkisp1_ext_params_bls_config) +\ 1431 + sizeof(struct rkisp1_ext_params_dpcc_config) +\ 1432 + sizeof(struct rkisp1_ext_params_sdg_config) +\ 1433 + sizeof(struct rkisp1_ext_params_lsc_config) +\ 1434 + sizeof(struct rkisp1_ext_params_awb_gain_config) +\ 1435 + sizeof(struct rkisp1_ext_params_flt_config) +\ 1436 + sizeof(struct rkisp1_ext_params_bdm_config) +\ 1437 + sizeof(struct rkisp1_ext_params_ctk_config) +\ 1438 + sizeof(struct rkisp1_ext_params_goc_config) +\ 1439 + sizeof(struct rkisp1_ext_params_dpf_config) +\ 1440 + sizeof(struct rkisp1_ext_params_dpf_strength_config) +\ 1441 + sizeof(struct rkisp1_ext_params_cproc_config) +\ 1442 + sizeof(struct rkisp1_ext_params_ie_config) +\ 1443 + sizeof(struct rkisp1_ext_params_awb_meas_config) +\ 1444 + sizeof(struct rkisp1_ext_params_hst_config) +\ 1445 + sizeof(struct rkisp1_ext_params_aec_config) +\ 1446 + sizeof(struct rkisp1_ext_params_afc_config) +\ 1447 + sizeof(struct rkisp1_ext_params_compand_bls_config) +\ 1448 + sizeof(struct rkisp1_ext_params_compand_curve_config) +\ 1449 + sizeof(struct rkisp1_ext_params_compand_curve_config)) 1450 + 1451 + /** 1452 + * enum rksip1_ext_param_buffer_version - RkISP1 extensible parameters version 1453 + * 1454 + * @RKISP1_EXT_PARAM_BUFFER_V1: First version of RkISP1 extensible parameters 1455 + */ 1456 + enum rksip1_ext_param_buffer_version { 1457 + RKISP1_EXT_PARAM_BUFFER_V1 = 1, 1458 + }; 1459 + 1460 + /** 1461 + * struct rkisp1_ext_params_cfg - RkISP1 extensible parameters configuration 1462 + * 1463 + * This struct contains the configuration parameters of the RkISP1 ISP 1464 + * algorithms, serialized by userspace into a data buffer. Each configuration 1465 + * parameter block is represented by a block-specific structure which contains a 1466 + * :c:type:`rkisp1_ext_params_block_header` entry as first member. Userspace 1467 + * populates the @data buffer with configuration parameters for the blocks that 1468 + * it intends to configure. As a consequence, the data buffer effective size 1469 + * changes according to the number of ISP blocks that userspace intends to 1470 + * configure and is set by userspace in the @data_size field. 1471 + * 1472 + * The parameters buffer is versioned by the @version field to allow modifying 1473 + * and extending its definition. Userspace shall populate the @version field to 1474 + * inform the driver about the version it intends to use. The driver will parse 1475 + * and handle the @data buffer according to the data layout specific to the 1476 + * indicated version and return an error if the desired version is not 1477 + * supported. 1478 + * 1479 + * Currently the single RKISP1_EXT_PARAM_BUFFER_V1 version is supported. 1480 + * When a new format version will be added, a mechanism for userspace to query 1481 + * the supported format versions will be implemented in the form of a read-only 1482 + * V4L2 control. If such control is not available, userspace should assume only 1483 + * RKISP1_EXT_PARAM_BUFFER_V1 is supported by the driver. 1484 + * 1485 + * For each ISP block that userspace wants to configure, a block-specific 1486 + * structure is appended to the @data buffer, one after the other without gaps 1487 + * in between nor overlaps. Userspace shall populate the @data_size field with 1488 + * the effective size, in bytes, of the @data buffer. 1489 + * 1490 + * The expected memory layout of the parameters buffer is:: 1491 + * 1492 + * +-------------------- struct rkisp1_ext_params_cfg -------------------+ 1493 + * | version = RKISP_EXT_PARAMS_BUFFER_V1; | 1494 + * | data_size = sizeof(struct rkisp1_ext_params_bls_config) | 1495 + * | + sizeof(struct rkisp1_ext_params_dpcc_config); | 1496 + * | +------------------------- data ---------------------------------+ | 1497 + * | | +------------- struct rkisp1_ext_params_bls_config -----------+ | | 1498 + * | | | +-------- struct rkisp1_ext_params_block_header ---------+ | | | 1499 + * | | | | type = RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS; | | | | 1500 + * | | | | flags = RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE; | | | | 1501 + * | | | | size = sizeof(struct rkisp1_ext_params_bls_config); | | | | 1502 + * | | | +---------------------------------------------------------+ | | | 1503 + * | | | +---------- struct rkisp1_cif_isp_bls_config -------------+ | | | 1504 + * | | | | enable_auto = 0; | | | | 1505 + * | | | | fixed_val.r = 256; | | | | 1506 + * | | | | fixed_val.gr = 256; | | | | 1507 + * | | | | fixed_val.gb = 256; | | | | 1508 + * | | | | fixed_val.b = 256; | | | | 1509 + * | | | +---------------------------------------------------------+ | | | 1510 + * | | +------------ struct rkisp1_ext_params_dpcc_config -----------+ | | 1511 + * | | | +-------- struct rkisp1_ext_params_block_header ---------+ | | | 1512 + * | | | | type = RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC; | | | | 1513 + * | | | | flags = RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE; | | | | 1514 + * | | | | size = sizeof(struct rkisp1_ext_params_dpcc_config); | | | | 1515 + * | | | +---------------------------------------------------------+ | | | 1516 + * | | | +---------- struct rkisp1_cif_isp_dpcc_config ------------+ | | | 1517 + * | | | | mode = RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE; | | | | 1518 + * | | | | output_mode = | | | | 1519 + * | | | | RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_G_CENTER; | | | | 1520 + * | | | | set_use = ... ; | | | | 1521 + * | | | | ... = ... ; | | | | 1522 + * | | | +---------------------------------------------------------+ | | | 1523 + * | | +-------------------------------------------------------------+ | | 1524 + * | +-----------------------------------------------------------------+ | 1525 + * +---------------------------------------------------------------------+ 1526 + * 1527 + * @version: The RkISP1 extensible parameters buffer version, see 1528 + * :c:type:`rksip1_ext_param_buffer_version` 1529 + * @data_size: The RkISP1 configuration data effective size, excluding this 1530 + * header 1531 + * @data: The RkISP1 extensible configuration data blocks 1532 + */ 1533 + struct rkisp1_ext_params_cfg { 1534 + __u32 version; 1535 + __u32 data_size; 1536 + __u8 data[RKISP1_EXT_PARAMS_MAX_SIZE]; 1035 1537 }; 1036 1538 1037 1539 #endif /* _UAPI_RKISP1_CONFIG_H */
+1
include/uapi/linux/serio.h
··· 83 83 #define SERIO_PULSE8_CEC 0x40 84 84 #define SERIO_RAINSHADOW_CEC 0x41 85 85 #define SERIO_FSIA6B 0x42 86 + #define SERIO_EXTRON_DA_HD_4K_PLUS 0x43 86 87 87 88 #endif /* _UAPI_SERIO_H */
+2
include/uapi/linux/videodev2.h
··· 502 502 #define V4L2_CAP_META_CAPTURE 0x00800000 /* Is a metadata capture device */ 503 503 504 504 #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ 505 + #define V4L2_CAP_EDID 0x02000000 /* Is an EDID-only device */ 505 506 #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ 506 507 #define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */ 507 508 ··· 855 854 /* Vendor specific - used for RK_ISP1 camera sub-system */ 856 855 #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ 857 856 #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */ 857 + #define V4L2_META_FMT_RK_ISP1_EXT_PARAMS v4l2_fourcc('R', 'K', '1', 'E') /* Rockchip ISP1 3a Extensible Parameters */ 858 858 859 859 /* Vendor specific - used for RaspberryPi PiSP */ 860 860 #define V4L2_META_FMT_RPI_BE_CFG v4l2_fourcc('R', 'P', 'B', 'C') /* PiSP BE configuration */