diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 14:13:17 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 14:13:17 -0400 |
| commit | e7a1414f9dc3498c4c35b9ca266d539e8bccab53 (patch) | |
| tree | f50a78785859182f9916c93dcf97c6539dbe3f3e | |
| parent | 85c1a25494837ff33fdfebe98b2e4cf5b0c78475 (diff) | |
| parent | 0d672fffb447aa1699d76fdacd90dc31eeb66d97 (diff) | |
Merge tag 'media/v5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- remove the deprecated Zoran driver from staging
- new I2C driver: ST MIPID02 CSI-2 camera bridge
- new platform driver: Amlogic Meson AO CEC G12A Controller
- add support for USB audio via the media controller
- au0828 driver is now supported via the media controller on both on
media and on usbaudio
- new kernel test for the media device allocator
- add support for stateless decoder at vicodec driver
- lots of other driver improvements fixes and cleanups
* tag 'media/v5.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (218 commits)
media: dt-bindings: aspeed-video: Add missing memory-region property
media: platform: Aspeed: Make reserved memory optional
media: platform: Aspeed: Remove use of reset line
media: stm32-dcmi: return appropriate error codes during probe
media: vsp1: Add support for missing 16-bit RGB555 formats
media: vsp1: Add support for missing 16-bit RGB444 formats
media: vsp1: Add support for missing 32-bit RGB formats
media: v4l: Add definitions for missing 16-bit RGB555 formats
media: v4l: Add definitions for missing 16-bit RGB4444 formats
media: v4l: Add definitions for missing 32-bit RGB formats
media: zoran: remove deprecated driver
media: MAINTAINERS: Update AO CEC with ao-cec-g12a driver
media: platform: meson: Add Amlogic Meson G12A AO CEC Controller driver
media: dt-bindings: media: meson-ao-cec: Add G12A AO-CEC-B Compatible
media: cros-ec-cec: decrement HDMI device refcount
media: seco-cec: decrement HDMI device refcount
media: tegra_cec: use new cec_notifier_parse_hdmi_phandle helper
media: stih_cec: use new cec_notifier_parse_hdmi_phandle helper
media: s5p_cec: use new cec_notifier_parse_hdmi_phandle helper
media: meson: ao-cec: use new cec_notifier_parse_hdmi_phandle helper
...
324 files changed, 7625 insertions, 13909 deletions
diff --git a/Documentation/devicetree/bindings/media/aspeed-video.txt b/Documentation/devicetree/bindings/media/aspeed-video.txt index 78b464ae2672..ce2894506e1f 100644 --- a/Documentation/devicetree/bindings/media/aspeed-video.txt +++ b/Documentation/devicetree/bindings/media/aspeed-video.txt | |||
| @@ -14,6 +14,11 @@ Required properties: | |||
| 14 | the VE | 14 | the VE |
| 15 | - interrupts: the interrupt associated with the VE on this platform | 15 | - interrupts: the interrupt associated with the VE on this platform |
| 16 | 16 | ||
| 17 | Optional properties: | ||
| 18 | - memory-region: | ||
| 19 | phandle to a memory region to allocate from, as defined in | ||
| 20 | Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt | ||
| 21 | |||
| 17 | Example: | 22 | Example: |
| 18 | 23 | ||
| 19 | video-engine@1e700000 { | 24 | video-engine@1e700000 { |
| @@ -23,4 +28,5 @@ video-engine@1e700000 { | |||
| 23 | clock-names = "vclk", "eclk"; | 28 | clock-names = "vclk", "eclk"; |
| 24 | resets = <&syscon ASPEED_RESET_VIDEO>; | 29 | resets = <&syscon ASPEED_RESET_VIDEO>; |
| 25 | interrupts = <7>; | 30 | interrupts = <7>; |
| 31 | memory-region = <&video_engine_memory>; | ||
| 26 | }; | 32 | }; |
diff --git a/Documentation/devicetree/bindings/media/cedrus.txt b/Documentation/devicetree/bindings/media/cedrus.txt index bce0705df953..20c82fb0c343 100644 --- a/Documentation/devicetree/bindings/media/cedrus.txt +++ b/Documentation/devicetree/bindings/media/cedrus.txt | |||
| @@ -13,6 +13,7 @@ Required properties: | |||
| 13 | - "allwinner,sun8i-h3-video-engine" | 13 | - "allwinner,sun8i-h3-video-engine" |
| 14 | - "allwinner,sun50i-a64-video-engine" | 14 | - "allwinner,sun50i-a64-video-engine" |
| 15 | - "allwinner,sun50i-h5-video-engine" | 15 | - "allwinner,sun50i-h5-video-engine" |
| 16 | - "allwinner,sun50i-h6-video-engine" | ||
| 16 | - reg : register base and length of VE; | 17 | - reg : register base and length of VE; |
| 17 | - clocks : list of clock specifiers, corresponding to entries in | 18 | - clocks : list of clock specifiers, corresponding to entries in |
| 18 | the clock-names property; | 19 | the clock-names property; |
diff --git a/Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt b/Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt new file mode 100644 index 000000000000..7976e6c40a80 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge | ||
| 2 | |||
| 3 | MIPID02 has two CSI-2 input ports, only one of those ports can be active at a | ||
| 4 | time. Active port input stream will be de-serialized and its content outputted | ||
| 5 | through PARALLEL output port. | ||
| 6 | CSI-2 first input port is a dual lane 800Mbps per lane whereas CSI-2 second | ||
| 7 | input port is a single lane 800Mbps. Both ports support clock and data lane | ||
| 8 | polarity swap. First port also supports data lane swap. | ||
| 9 | PARALLEL output port has a maximum width of 12 bits. | ||
| 10 | Supported formats are RAW6, RAW7, RAW8, RAW10, RAW12, RGB565, RGB888, RGB444, | ||
| 11 | YUV420 8-bit, YUV422 8-bit and YUV420 10-bit. | ||
| 12 | |||
| 13 | Required Properties: | ||
| 14 | - compatible: shall be "st,st-mipid02" | ||
| 15 | - clocks: reference to the xclk input clock. | ||
| 16 | - clock-names: shall be "xclk". | ||
| 17 | - VDDE-supply: sensor digital IO supply. Must be 1.8 volts. | ||
| 18 | - VDDIN-supply: sensor internal regulator supply. Must be 1.8 volts. | ||
| 19 | |||
| 20 | Optional Properties: | ||
| 21 | - reset-gpios: reference to the GPIO connected to the xsdn pin, if any. | ||
| 22 | This is an active low signal to the mipid02. | ||
| 23 | |||
| 24 | Required subnodes: | ||
| 25 | - ports: A ports node with one port child node per device input and output | ||
| 26 | port, in accordance with the video interface bindings defined in | ||
| 27 | Documentation/devicetree/bindings/media/video-interfaces.txt. The | ||
| 28 | port nodes are numbered as follows: | ||
| 29 | |||
| 30 | Port Description | ||
| 31 | ----------------------------- | ||
| 32 | 0 CSI-2 first input port | ||
| 33 | 1 CSI-2 second input port | ||
| 34 | 2 PARALLEL output | ||
| 35 | |||
| 36 | Endpoint node required property for CSI-2 connection is: | ||
| 37 | - data-lanes: shall be <1> for Port 1. for Port 0 dual-lane operation shall be | ||
| 38 | <1 2> or <2 1>. For Port 0 single-lane operation shall be <1> or <2>. | ||
| 39 | Endpoint node optional property for CSI-2 connection is: | ||
| 40 | - lane-polarities: any lane can be inverted or not. | ||
| 41 | |||
| 42 | Endpoint node required property for PARALLEL connection is: | ||
| 43 | - bus-width: shall be set to <6>, <7>, <8>, <10> or <12>. | ||
| 44 | Endpoint node optional properties for PARALLEL connection are: | ||
| 45 | - hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively. | ||
| 46 | LOW being the default. | ||
| 47 | - vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively. | ||
| 48 | LOW being the default. | ||
| 49 | |||
| 50 | Example: | ||
| 51 | |||
| 52 | mipid02: csi2rx@14 { | ||
| 53 | compatible = "st,st-mipid02"; | ||
| 54 | reg = <0x14>; | ||
| 55 | status = "okay"; | ||
| 56 | clocks = <&clk_ext_camera_12>; | ||
| 57 | clock-names = "xclk"; | ||
| 58 | VDDE-supply = <&vdd>; | ||
| 59 | VDDIN-supply = <&vdd>; | ||
| 60 | ports { | ||
| 61 | #address-cells = <1>; | ||
| 62 | #size-cells = <0>; | ||
| 63 | port@0 { | ||
| 64 | reg = <0>; | ||
| 65 | |||
| 66 | ep0: endpoint { | ||
| 67 | data-lanes = <1 2>; | ||
| 68 | remote-endpoint = <&mipi_csi2_in>; | ||
| 69 | }; | ||
| 70 | }; | ||
| 71 | port@2 { | ||
| 72 | reg = <2>; | ||
| 73 | |||
| 74 | ep2: endpoint { | ||
| 75 | bus-width = <8>; | ||
| 76 | hsync-active = <0>; | ||
| 77 | vsync-active = <0>; | ||
| 78 | remote-endpoint = <¶llel_out>; | ||
| 79 | }; | ||
| 80 | }; | ||
| 81 | }; | ||
| 82 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt b/Documentation/devicetree/bindings/media/meson-ao-cec.txt index 8671bdb08080..c67fc41d4aa2 100644 --- a/Documentation/devicetree/bindings/media/meson-ao-cec.txt +++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt | |||
| @@ -4,16 +4,23 @@ The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is | |||
| 4 | to handle communication between HDMI connected devices over the CEC bus. | 4 | to handle communication between HDMI connected devices over the CEC bus. |
| 5 | 5 | ||
| 6 | Required properties: | 6 | Required properties: |
| 7 | - compatible : value should be following | 7 | - compatible : value should be following depending on the SoC : |
| 8 | For GXBB, GXL, GXM and G12A (AO_CEC_A module) : | ||
| 8 | "amlogic,meson-gx-ao-cec" | 9 | "amlogic,meson-gx-ao-cec" |
| 10 | For G12A (AO_CEC_B module) : | ||
| 11 | "amlogic,meson-g12a-ao-cec" | ||
| 9 | 12 | ||
| 10 | - reg : Physical base address of the IP registers and length of memory | 13 | - reg : Physical base address of the IP registers and length of memory |
| 11 | mapped region. | 14 | mapped region. |
| 12 | 15 | ||
| 13 | - interrupts : AO-CEC interrupt number to the CPU. | 16 | - interrupts : AO-CEC interrupt number to the CPU. |
| 14 | - clocks : from common clock binding: handle to AO-CEC clock. | 17 | - clocks : from common clock binding: handle to AO-CEC clock. |
| 15 | - clock-names : from common clock binding: must contain "core", | 18 | - clock-names : from common clock binding, must contain : |
| 16 | corresponding to entry in the clocks property. | 19 | For GXBB, GXL, GXM and G12A (AO_CEC_A module) : |
| 20 | - "core" | ||
| 21 | For G12A (AO_CEC_B module) : | ||
| 22 | - "oscin" | ||
| 23 | corresponding to entry in the clocks property. | ||
| 17 | - hdmi-phandle: phandle to the HDMI controller | 24 | - hdmi-phandle: phandle to the HDMI controller |
| 18 | 25 | ||
| 19 | Example: | 26 | Example: |
diff --git a/Documentation/devicetree/bindings/media/rcar_imr.txt b/Documentation/devicetree/bindings/media/rcar_imr.txt new file mode 100644 index 000000000000..b0614153ed36 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rcar_imr.txt | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | Renesas R-Car Image Renderer (Distortion Correction Engine) | ||
| 2 | ----------------------------------------------------------- | ||
| 3 | |||
| 4 | The image renderer, or the distortion correction engine, is a drawing processor | ||
| 5 | with a simple instruction system capable of referencing video capture data or | ||
| 6 | data in an external memory as 2D texture data and performing texture mapping | ||
| 7 | and drawing with respect to any shape that is split into triangular objects. | ||
| 8 | |||
| 9 | Required properties: | ||
| 10 | |||
| 11 | - compatible: "renesas,<soctype>-imr-lx4", "renesas,imr-lx4" as a fallback for | ||
| 12 | the image renderer light extended 4 (IMR-LX4) found in the R-Car gen3 SoCs, | ||
| 13 | where the examples with <soctype> are: | ||
| 14 | - "renesas,r8a7795-imr-lx4" for R-Car H3, | ||
| 15 | - "renesas,r8a7796-imr-lx4" for R-Car M3-W. | ||
| 16 | - reg: offset and length of the register block; | ||
| 17 | - interrupts: single interrupt specifier; | ||
| 18 | - clocks: single clock phandle/specifier pair; | ||
| 19 | - power-domains: power domain phandle/specifier pair; | ||
| 20 | - resets: reset phandle/specifier pair. | ||
| 21 | |||
| 22 | Example: | ||
| 23 | |||
| 24 | imr-lx4@fe860000 { | ||
| 25 | compatible = "renesas,r8a7795-imr-lx4", "renesas,imr-lx4"; | ||
| 26 | reg = <0 0xfe860000 0 0x2000>; | ||
| 27 | interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; | ||
| 28 | clocks = <&cpg CPG_MOD 823>; | ||
| 29 | power-domains = <&sysc R8A7795_PD_A3VC>; | ||
| 30 | resets = <&cpg 823>; | ||
| 31 | }; | ||
diff --git a/Documentation/devicetree/bindings/media/rcar_vin.txt b/Documentation/devicetree/bindings/media/rcar_vin.txt index 224a4615b418..aa217b096279 100644 --- a/Documentation/devicetree/bindings/media/rcar_vin.txt +++ b/Documentation/devicetree/bindings/media/rcar_vin.txt | |||
| @@ -13,6 +13,7 @@ on Gen3 and RZ/G2 platforms to a CSI-2 receiver. | |||
| 13 | - "renesas,vin-r8a7743" for the R8A7743 device | 13 | - "renesas,vin-r8a7743" for the R8A7743 device |
| 14 | - "renesas,vin-r8a7744" for the R8A7744 device | 14 | - "renesas,vin-r8a7744" for the R8A7744 device |
| 15 | - "renesas,vin-r8a7745" for the R8A7745 device | 15 | - "renesas,vin-r8a7745" for the R8A7745 device |
| 16 | - "renesas,vin-r8a774a1" for the R8A774A1 device | ||
| 16 | - "renesas,vin-r8a774c0" for the R8A774C0 device | 17 | - "renesas,vin-r8a774c0" for the R8A774C0 device |
| 17 | - "renesas,vin-r8a7778" for the R8A7778 device | 18 | - "renesas,vin-r8a7778" for the R8A7778 device |
| 18 | - "renesas,vin-r8a7779" for the R8A7779 device | 19 | - "renesas,vin-r8a7779" for the R8A7779 device |
diff --git a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt index d63275e17afd..331409259752 100644 --- a/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt +++ b/Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt | |||
| @@ -8,6 +8,7 @@ R-Car VIN module, which provides the video capture capabilities. | |||
| 8 | Mandatory properties | 8 | Mandatory properties |
| 9 | -------------------- | 9 | -------------------- |
| 10 | - compatible: Must be one or more of the following | 10 | - compatible: Must be one or more of the following |
| 11 | - "renesas,r8a774a1-csi2" for the R8A774A1 device. | ||
| 11 | - "renesas,r8a774c0-csi2" for the R8A774C0 device. | 12 | - "renesas,r8a774c0-csi2" for the R8A774C0 device. |
| 12 | - "renesas,r8a7795-csi2" for the R8A7795 device. | 13 | - "renesas,r8a7795-csi2" for the R8A7795 device. |
| 13 | - "renesas,r8a7796-csi2" for the R8A7796 device. | 14 | - "renesas,r8a7796-csi2" for the R8A7796 device. |
| @@ -18,7 +19,8 @@ Mandatory properties | |||
| 18 | 19 | ||
| 19 | - reg: the register base and size for the device registers | 20 | - reg: the register base and size for the device registers |
| 20 | - interrupts: the interrupt for the device | 21 | - interrupts: the interrupt for the device |
| 21 | - clocks: reference to the parent clock | 22 | - clocks: A phandle + clock specifier for the module clock |
| 23 | - resets: A phandle + reset specifier for the module reset | ||
| 22 | 24 | ||
| 23 | The device node shall contain two 'port' child nodes according to the | 25 | The device node shall contain two 'port' child nodes according to the |
| 24 | bindings defined in Documentation/devicetree/bindings/media/ | 26 | bindings defined in Documentation/devicetree/bindings/media/ |
diff --git a/Documentation/media/index.rst b/Documentation/media/index.rst index 0a222fc1d7ca..0301c25ff887 100644 --- a/Documentation/media/index.rst +++ b/Documentation/media/index.rst | |||
| @@ -18,7 +18,7 @@ Linux Media Subsystem Documentation | |||
| 18 | v4l-drivers/index | 18 | v4l-drivers/index |
| 19 | cec-drivers/index | 19 | cec-drivers/index |
| 20 | 20 | ||
| 21 | .. only:: subproject | 21 | .. only:: html and subproject |
| 22 | 22 | ||
| 23 | Indices | 23 | Indices |
| 24 | ======= | 24 | ======= |
diff --git a/Documentation/media/kapi/mc-core.rst b/Documentation/media/kapi/mc-core.rst index f930725e0d6b..05bba0b61748 100644 --- a/Documentation/media/kapi/mc-core.rst +++ b/Documentation/media/kapi/mc-core.rst | |||
| @@ -259,6 +259,45 @@ Subsystems should facilitate link validation by providing subsystem specific | |||
| 259 | helper functions to provide easy access for commonly needed information, and | 259 | helper functions to provide easy access for commonly needed information, and |
| 260 | in the end provide a way to use driver-specific callbacks. | 260 | in the end provide a way to use driver-specific callbacks. |
| 261 | 261 | ||
| 262 | Media Controller Device Allocator API | ||
| 263 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 264 | |||
| 265 | When the media device belongs to more than one driver, the shared media | ||
| 266 | device is allocated with the shared struct device as the key for look ups. | ||
| 267 | |||
| 268 | The shared media device should stay in registered state until the last | ||
| 269 | driver unregisters it. In addition, the media device should be released when | ||
| 270 | all the references are released. Each driver gets a reference to the media | ||
| 271 | device during probe, when it allocates the media device. If media device is | ||
| 272 | already allocated, the allocate API bumps up the refcount and returns the | ||
| 273 | existing media device. The driver puts the reference back in its disconnect | ||
| 274 | routine when it calls :c:func:`media_device_delete()`. | ||
| 275 | |||
| 276 | The media device is unregistered and cleaned up from the kref put handler to | ||
| 277 | ensure that the media device stays in registered state until the last driver | ||
| 278 | unregisters the media device. | ||
| 279 | |||
| 280 | **Driver Usage** | ||
| 281 | |||
| 282 | Drivers should use the appropriate media-core routines to manage the shared | ||
| 283 | media device life-time handling the two states: | ||
| 284 | 1. allocate -> register -> delete | ||
| 285 | 2. get reference to already registered device -> delete | ||
| 286 | |||
| 287 | call :c:func:`media_device_delete()` routine to make sure the shared media | ||
| 288 | device delete is handled correctly. | ||
| 289 | |||
| 290 | **driver probe:** | ||
| 291 | Call :c:func:`media_device_usb_allocate()` to allocate or get a reference | ||
| 292 | Call :c:func:`media_device_register()`, if media devnode isn't registered | ||
| 293 | |||
| 294 | **driver disconnect:** | ||
| 295 | Call :c:func:`media_device_delete()` to free the media_device. Freeing is | ||
| 296 | handled by the kref put handler. | ||
| 297 | |||
| 298 | API Definitions | ||
| 299 | ^^^^^^^^^^^^^^^ | ||
| 300 | |||
| 262 | .. kernel-doc:: include/media/media-device.h | 301 | .. kernel-doc:: include/media/media-device.h |
| 263 | 302 | ||
| 264 | .. kernel-doc:: include/media/media-devnode.h | 303 | .. kernel-doc:: include/media/media-devnode.h |
| @@ -266,3 +305,5 @@ in the end provide a way to use driver-specific callbacks. | |||
| 266 | .. kernel-doc:: include/media/media-entity.h | 305 | .. kernel-doc:: include/media/media-entity.h |
| 267 | 306 | ||
| 268 | .. kernel-doc:: include/media/media-request.h | 307 | .. kernel-doc:: include/media/media-request.h |
| 308 | |||
| 309 | .. kernel-doc:: include/media/media-dev-allocator.h | ||
diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions index 7a8b8ff4f076..ac768d769113 100644 --- a/Documentation/media/lirc.h.rst.exceptions +++ b/Documentation/media/lirc.h.rst.exceptions | |||
| @@ -63,6 +63,7 @@ ignore symbol RC_PROTO_IMON | |||
| 63 | ignore symbol RC_PROTO_RCMM12 | 63 | ignore symbol RC_PROTO_RCMM12 |
| 64 | ignore symbol RC_PROTO_RCMM24 | 64 | ignore symbol RC_PROTO_RCMM24 |
| 65 | ignore symbol RC_PROTO_RCMM32 | 65 | ignore symbol RC_PROTO_RCMM32 |
| 66 | ignore symbol RC_PROTO_XBOX_DVD | ||
| 66 | 67 | ||
| 67 | # Undocumented macros | 68 | # Undocumented macros |
| 68 | 69 | ||
diff --git a/Documentation/media/uapi/mediactl/request-api.rst b/Documentation/media/uapi/mediactl/request-api.rst index 1ad631e549fe..a74c82d95609 100644 --- a/Documentation/media/uapi/mediactl/request-api.rst +++ b/Documentation/media/uapi/mediactl/request-api.rst | |||
| @@ -93,7 +93,7 @@ A queued request cannot be modified anymore. | |||
| 93 | .. caution:: | 93 | .. caution:: |
| 94 | For :ref:`memory-to-memory devices <mem2mem>` you can use requests only for | 94 | For :ref:`memory-to-memory devices <mem2mem>` you can use requests only for |
| 95 | output buffers, not for capture buffers. Attempting to add a capture buffer | 95 | output buffers, not for capture buffers. Attempting to add a capture buffer |
| 96 | to a request will result in an ``EACCES`` error. | 96 | to a request will result in an ``EBADR`` error. |
| 97 | 97 | ||
| 98 | If the request contains configurations for multiple entities, individual drivers | 98 | If the request contains configurations for multiple entities, individual drivers |
| 99 | may synchronize so the requested pipeline's topology is applied before the | 99 | may synchronize so the requested pipeline's topology is applied before the |
diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst index 81ffdcb89057..1cbd9cde57f3 100644 --- a/Documentation/media/uapi/v4l/buffer.rst +++ b/Documentation/media/uapi/v4l/buffer.rst | |||
| @@ -165,7 +165,7 @@ of appropriately sized buffers for each use case). | |||
| 165 | struct v4l2_buffer | 165 | struct v4l2_buffer |
| 166 | ================== | 166 | ================== |
| 167 | 167 | ||
| 168 | .. tabularcolumns:: |p{2.8cm}|p{2.5cm}|p{1.3cm}|p{10.5cm}| | 168 | .. tabularcolumns:: |p{2.8cm}|p{2.5cm}|p{1.6cm}|p{10.2cm}| |
| 169 | 169 | ||
| 170 | .. cssclass:: longtable | 170 | .. cssclass:: longtable |
| 171 | 171 | ||
| @@ -326,7 +326,7 @@ struct v4l2_buffer | |||
| 326 | Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls | 326 | Applications should not set ``V4L2_BUF_FLAG_REQUEST_FD`` for any ioctls |
| 327 | other than :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`. | 327 | other than :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`. |
| 328 | 328 | ||
| 329 | If the device does not support requests, then ``EACCES`` will be returned. | 329 | If the device does not support requests, then ``EBADR`` will be returned. |
| 330 | If requests are supported but an invalid request file descriptor is | 330 | If requests are supported but an invalid request file descriptor is |
| 331 | given, then ``EINVAL`` will be returned. | 331 | given, then ``EINVAL`` will be returned. |
| 332 | 332 | ||
| @@ -420,7 +420,7 @@ enum v4l2_buf_type | |||
| 420 | 420 | ||
| 421 | .. cssclass:: longtable | 421 | .. cssclass:: longtable |
| 422 | 422 | ||
| 423 | .. tabularcolumns:: |p{7.2cm}|p{0.6cm}|p{9.7cm}| | 423 | .. tabularcolumns:: |p{7.8cm}|p{0.6cm}|p{9.1cm}| |
| 424 | 424 | ||
| 425 | .. flat-table:: | 425 | .. flat-table:: |
| 426 | :header-rows: 0 | 426 | :header-rows: 0 |
| @@ -482,7 +482,11 @@ enum v4l2_buf_type | |||
| 482 | Buffer Flags | 482 | Buffer Flags |
| 483 | ============ | 483 | ============ |
| 484 | 484 | ||
| 485 | .. tabularcolumns:: |p{7.0cm}|p{2.2cm}|p{8.3cm}| | 485 | .. raw:: latex |
| 486 | |||
| 487 | \small | ||
| 488 | |||
| 489 | .. tabularcolumns:: |p{7.0cm}|p{2.1cm}|p{8.4cm}| | ||
| 486 | 490 | ||
| 487 | .. cssclass:: longtable | 491 | .. cssclass:: longtable |
| 488 | 492 | ||
| @@ -681,6 +685,9 @@ Buffer Flags | |||
| 681 | exposure of the frame has begun. This is only valid for the | 685 | exposure of the frame has begun. This is only valid for the |
| 682 | ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type. | 686 | ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type. |
| 683 | 687 | ||
| 688 | .. raw:: latex | ||
| 689 | |||
| 690 | \normalsize | ||
| 684 | 691 | ||
| 685 | 692 | ||
| 686 | .. c:type:: v4l2_memory | 693 | .. c:type:: v4l2_memory |
| @@ -688,7 +695,7 @@ Buffer Flags | |||
| 688 | enum v4l2_memory | 695 | enum v4l2_memory |
| 689 | ================ | 696 | ================ |
| 690 | 697 | ||
| 691 | .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| | 698 | .. tabularcolumns:: |p{5.0cm}|p{0.8cm}|p{11.7cm}| |
| 692 | 699 | ||
| 693 | .. flat-table:: | 700 | .. flat-table:: |
| 694 | :header-rows: 0 | 701 | :header-rows: 0 |
| @@ -724,7 +731,7 @@ The :c:type:`v4l2_buffer_timecode` structure is designed to hold a | |||
| 724 | struct v4l2_timecode | 731 | struct v4l2_timecode |
| 725 | -------------------- | 732 | -------------------- |
| 726 | 733 | ||
| 727 | .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| | 734 | .. tabularcolumns:: |p{1.4cm}|p{2.8cm}|p{12.3cm}| |
| 728 | 735 | ||
| 729 | .. flat-table:: | 736 | .. flat-table:: |
| 730 | :header-rows: 0 | 737 | :header-rows: 0 |
| @@ -761,7 +768,7 @@ struct v4l2_timecode | |||
| 761 | Timecode Types | 768 | Timecode Types |
| 762 | -------------- | 769 | -------------- |
| 763 | 770 | ||
| 764 | .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| | 771 | .. tabularcolumns:: |p{5.6cm}|p{0.8cm}|p{11.1cm}| |
| 765 | 772 | ||
| 766 | .. flat-table:: | 773 | .. flat-table:: |
| 767 | :header-rows: 0 | 774 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/colorspaces-defs.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst index c4e8fc620379..e122bbe3d799 100644 --- a/Documentation/media/uapi/v4l/colorspaces-defs.rst +++ b/Documentation/media/uapi/v4l/colorspaces-defs.rst | |||
| @@ -39,7 +39,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum | |||
| 39 | colorspaces except for BT.2020 which uses limited range R'G'B' | 39 | colorspaces except for BT.2020 which uses limited range R'G'B' |
| 40 | quantization. | 40 | quantization. |
| 41 | 41 | ||
| 42 | .. tabularcolumns:: |p{6.0cm}|p{11.5cm}| | 42 | .. tabularcolumns:: |p{6.7cm}|p{10.8cm}| |
| 43 | 43 | ||
| 44 | .. c:type:: v4l2_colorspace | 44 | .. c:type:: v4l2_colorspace |
| 45 | 45 | ||
| @@ -112,7 +112,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum | |||
| 112 | 112 | ||
| 113 | .. c:type:: v4l2_ycbcr_encoding | 113 | .. c:type:: v4l2_ycbcr_encoding |
| 114 | 114 | ||
| 115 | .. tabularcolumns:: |p{6.5cm}|p{11.0cm}| | 115 | .. tabularcolumns:: |p{7.2cm}|p{10.3cm}| |
| 116 | 116 | ||
| 117 | .. flat-table:: V4L2 Y'CbCr Encodings | 117 | .. flat-table:: V4L2 Y'CbCr Encodings |
| 118 | :header-rows: 1 | 118 | :header-rows: 1 |
diff --git a/Documentation/media/uapi/v4l/colorspaces.rst b/Documentation/media/uapi/v4l/colorspaces.rst index c5a560f0c13d..4f6c82fa057f 100644 --- a/Documentation/media/uapi/v4l/colorspaces.rst +++ b/Documentation/media/uapi/v4l/colorspaces.rst | |||
| @@ -56,9 +56,9 @@ The Y value in the CIE XYZ colorspace corresponds to luminance. Often | |||
| 56 | the CIE XYZ colorspace is transformed to the normalized CIE xyY | 56 | the CIE XYZ colorspace is transformed to the normalized CIE xyY |
| 57 | colorspace: | 57 | colorspace: |
| 58 | 58 | ||
| 59 | x = X / (X + Y + Z) | 59 | x = X / (X + Y + Z) |
| 60 | 60 | ||
| 61 | y = Y / (X + Y + Z) | 61 | y = Y / (X + Y + Z) |
| 62 | 62 | ||
| 63 | The x and y values are the chromaticity coordinates and can be used to | 63 | The x and y values are the chromaticity coordinates and can be used to |
| 64 | define a color without the luminance component Y. It is very confusing | 64 | define a color without the luminance component Y. It is very confusing |
diff --git a/Documentation/media/uapi/v4l/dev-raw-vbi.rst b/Documentation/media/uapi/v4l/dev-raw-vbi.rst index d6a707f0b24f..e06b03ca2ab2 100644 --- a/Documentation/media/uapi/v4l/dev-raw-vbi.rst +++ b/Documentation/media/uapi/v4l/dev-raw-vbi.rst | |||
| @@ -106,7 +106,7 @@ VBI devices must implement both the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and | |||
| 106 | and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. | 106 | and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does. |
| 107 | :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional. | 107 | :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` is optional. |
| 108 | 108 | ||
| 109 | .. tabularcolumns:: |p{2.4cm}|p{4.4cm}|p{10.7cm}| | 109 | .. tabularcolumns:: |p{1.6cm}|p{4.2cm}|p{11.7cm}| |
| 110 | 110 | ||
| 111 | .. c:type:: v4l2_vbi_format | 111 | .. c:type:: v4l2_vbi_format |
| 112 | 112 | ||
| @@ -190,7 +190,7 @@ and always returns default parameters as :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` does | |||
| 190 | applications must set it to zero. | 190 | applications must set it to zero. |
| 191 | 191 | ||
| 192 | 192 | ||
| 193 | .. tabularcolumns:: |p{4.0cm}|p{1.5cm}|p{12.0cm}| | 193 | .. tabularcolumns:: |p{4.4cm}|p{1.5cm}|p{11.6cm}| |
| 194 | 194 | ||
| 195 | .. _vbifmt-flags: | 195 | .. _vbifmt-flags: |
| 196 | 196 | ||
diff --git a/Documentation/media/uapi/v4l/dev-rds.rst b/Documentation/media/uapi/v4l/dev-rds.rst index 624d6f95b842..64a724ef58f5 100644 --- a/Documentation/media/uapi/v4l/dev-rds.rst +++ b/Documentation/media/uapi/v4l/dev-rds.rst | |||
| @@ -146,7 +146,7 @@ RDS datastructures | |||
| 146 | 146 | ||
| 147 | .. _v4l2-rds-block-codes: | 147 | .. _v4l2-rds-block-codes: |
| 148 | 148 | ||
| 149 | .. tabularcolumns:: |p{5.6cm}|p{2.0cm}|p{1.5cm}|p{7.0cm}| | 149 | .. tabularcolumns:: |p{6.4cm}|p{2.0cm}|p{1.2cm}|p{7.9cm}| |
| 150 | 150 | ||
| 151 | .. flat-table:: Block defines | 151 | .. flat-table:: Block defines |
| 152 | :header-rows: 0 | 152 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst index 0aa6cb8a272b..e86346f66017 100644 --- a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst +++ b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst | |||
| @@ -118,7 +118,7 @@ struct v4l2_sliced_vbi_format | |||
| 118 | \scriptsize | 118 | \scriptsize |
| 119 | \setlength{\tabcolsep}{2pt} | 119 | \setlength{\tabcolsep}{2pt} |
| 120 | 120 | ||
| 121 | .. tabularcolumns:: |p{.75cm}|p{3.3cm}|p{3.4cm}|p{3.4cm}|p{3.4cm}| | 121 | .. tabularcolumns:: |p{.85cm}|p{3.3cm}|p{4.4cm}|p{4.4cm}|p{4.4cm}| |
| 122 | 122 | ||
| 123 | .. cssclass:: longtable | 123 | .. cssclass:: longtable |
| 124 | 124 | ||
| @@ -223,7 +223,7 @@ Sliced VBI services | |||
| 223 | 223 | ||
| 224 | .. raw:: latex | 224 | .. raw:: latex |
| 225 | 225 | ||
| 226 | \footnotesize | 226 | \scriptsize |
| 227 | 227 | ||
| 228 | .. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}| | 228 | .. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}| |
| 229 | 229 | ||
| @@ -541,7 +541,7 @@ Magic Constants for struct v4l2_mpeg_vbi_fmt_ivtv magic field | |||
| 541 | structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 | 541 | structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 |
| 542 | ------------------------------------------------- | 542 | ------------------------------------------------- |
| 543 | 543 | ||
| 544 | .. tabularcolumns:: |p{4.9cm}|p{2.4cm}|p{10.2cm}| | 544 | .. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}| |
| 545 | 545 | ||
| 546 | .. flat-table:: | 546 | .. flat-table:: |
| 547 | :header-rows: 0 | 547 | :header-rows: 0 |
| @@ -561,12 +561,12 @@ structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 | |||
| 561 | 561 | ||
| 562 | :: | 562 | :: |
| 563 | 563 | ||
| 564 | linemask[0] b0: line 6 first field | 564 | linemask[0] b0: line 6 first field |
| 565 | linemask[0] b17: line 23 first field | 565 | linemask[0] b17: line 23 first field |
| 566 | linemask[0] b18: line 6 second field | 566 | linemask[0] b18: line 6 second field |
| 567 | linemask[0] b31: line 19 second field | 567 | linemask[0] b31: line 19 second field |
| 568 | linemask[1] b0: line 20 second field | 568 | linemask[1] b0: line 20 second field |
| 569 | linemask[1] b3: line 23 second field | 569 | linemask[1] b3: line 23 second field |
| 570 | linemask[1] b4-b31: unused and set to 0 | 570 | linemask[1] b4-b31: unused and set to 0 |
| 571 | * - struct | 571 | * - struct |
| 572 | :c:type:`v4l2_mpeg_vbi_itv0_line` | 572 | :c:type:`v4l2_mpeg_vbi_itv0_line` |
| @@ -590,7 +590,7 @@ structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 | |||
| 590 | struct v4l2_mpeg_vbi_ITV0 | 590 | struct v4l2_mpeg_vbi_ITV0 |
| 591 | ------------------------- | 591 | ------------------------- |
| 592 | 592 | ||
| 593 | .. tabularcolumns:: |p{4.9cm}|p{4.4cm}|p{8.2cm}| | 593 | .. tabularcolumns:: |p{5.2cm}|p{2.4cm}|p{9.9cm}| |
| 594 | 594 | ||
| 595 | .. flat-table:: | 595 | .. flat-table:: |
| 596 | :header-rows: 0 | 596 | :header-rows: 0 |
| @@ -635,7 +635,7 @@ struct v4l2_mpeg_vbi_itv0_line | |||
| 635 | Line Identifiers for struct v4l2_mpeg_vbi_itv0_line id field | 635 | Line Identifiers for struct v4l2_mpeg_vbi_itv0_line id field |
| 636 | ------------------------------------------------------------ | 636 | ------------------------------------------------------------ |
| 637 | 637 | ||
| 638 | .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| | 638 | .. tabularcolumns:: |p{7.0cm}|p{1.8cm}|p{8.7cm}| |
| 639 | 639 | ||
| 640 | .. flat-table:: | 640 | .. flat-table:: |
| 641 | :header-rows: 1 | 641 | :header-rows: 1 |
diff --git a/Documentation/media/uapi/v4l/dev-subdev.rst b/Documentation/media/uapi/v4l/dev-subdev.rst index 2c2768c7343b..029bb2d9928a 100644 --- a/Documentation/media/uapi/v4l/dev-subdev.rst +++ b/Documentation/media/uapi/v4l/dev-subdev.rst | |||
| @@ -211,7 +211,7 @@ list entity names and pad numbers). | |||
| 211 | 211 | ||
| 212 | .. raw:: latex | 212 | .. raw:: latex |
| 213 | 213 | ||
| 214 | \tiny | 214 | \scriptsize |
| 215 | 215 | ||
| 216 | .. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}| | 216 | .. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}| |
| 217 | 217 | ||
| @@ -223,40 +223,80 @@ list entity names and pad numbers). | |||
| 223 | :widths: 5 5 5 5 5 5 5 | 223 | :widths: 5 5 5 5 5 5 5 |
| 224 | 224 | ||
| 225 | * - | 225 | * - |
| 226 | - Sensor/0 format | 226 | - Sensor/0 |
| 227 | - Frontend/0 format | 227 | |
| 228 | - Frontend/1 format | 228 | format |
| 229 | - Scaler/0 format | 229 | - Frontend/0 |
| 230 | - Scaler/0 compose selection rectangle | 230 | |
| 231 | - Scaler/1 format | 231 | format |
| 232 | - Frontend/1 | ||
| 233 | |||
| 234 | format | ||
| 235 | - Scaler/0 | ||
| 236 | |||
| 237 | format | ||
| 238 | - Scaler/0 | ||
| 239 | |||
| 240 | compose selection rectangle | ||
| 241 | - Scaler/1 | ||
| 242 | |||
| 243 | format | ||
| 232 | * - Initial state | 244 | * - Initial state |
| 233 | - 2048x1536/SGRBG8_1X8 | 245 | - 2048x1536 |
| 246 | |||
| 247 | SGRBG8_1X8 | ||
| 234 | - (default) | 248 | - (default) |
| 235 | - (default) | 249 | - (default) |
| 236 | - (default) | 250 | - (default) |
| 237 | - (default) | 251 | - (default) |
| 238 | - (default) | 252 | - (default) |
| 239 | * - Configure frontend sink format | 253 | * - Configure frontend sink format |
| 240 | - 2048x1536/SGRBG8_1X8 | 254 | - 2048x1536 |
| 241 | - *2048x1536/SGRBG8_1X8* | 255 | |
| 242 | - *2046x1534/SGRBG8_1X8* | 256 | SGRBG8_1X8 |
| 257 | - *2048x1536* | ||
| 258 | |||
| 259 | *SGRBG8_1X8* | ||
| 260 | - *2046x1534* | ||
| 261 | |||
| 262 | *SGRBG8_1X8* | ||
| 243 | - (default) | 263 | - (default) |
| 244 | - (default) | 264 | - (default) |
| 245 | - (default) | 265 | - (default) |
| 246 | * - Configure scaler sink format | 266 | * - Configure scaler sink format |
| 247 | - 2048x1536/SGRBG8_1X8 | 267 | - 2048x1536 |
| 248 | - 2048x1536/SGRBG8_1X8 | 268 | |
| 249 | - 2046x1534/SGRBG8_1X8 | 269 | SGRBG8_1X8 |
| 250 | - *2046x1534/SGRBG8_1X8* | 270 | - 2048x1536 |
| 271 | |||
| 272 | SGRBG8_1X8 | ||
| 273 | - 2046x1534 | ||
| 274 | |||
| 275 | SGRBG8_1X8 | ||
| 276 | - *2046x1534* | ||
| 277 | |||
| 278 | *SGRBG8_1X8* | ||
| 251 | - *0,0/2046x1534* | 279 | - *0,0/2046x1534* |
| 252 | - *2046x1534/SGRBG8_1X8* | 280 | - *2046x1534* |
| 281 | |||
| 282 | *SGRBG8_1X8* | ||
| 253 | * - Configure scaler sink compose selection | 283 | * - Configure scaler sink compose selection |
| 254 | - 2048x1536/SGRBG8_1X8 | 284 | - 2048x1536 |
| 255 | - 2048x1536/SGRBG8_1X8 | 285 | |
| 256 | - 2046x1534/SGRBG8_1X8 | 286 | SGRBG8_1X8 |
| 257 | - 2046x1534/SGRBG8_1X8 | 287 | - 2048x1536 |
| 288 | |||
| 289 | SGRBG8_1X8 | ||
| 290 | - 2046x1534 | ||
| 291 | |||
| 292 | SGRBG8_1X8 | ||
| 293 | - 2046x1534 | ||
| 294 | |||
| 295 | SGRBG8_1X8 | ||
| 258 | - *0,0/1280x960* | 296 | - *0,0/1280x960* |
| 259 | - *1280x960/SGRBG8_1X8* | 297 | - *1280x960* |
| 298 | |||
| 299 | *SGRBG8_1X8* | ||
| 260 | 300 | ||
| 261 | .. raw:: latex | 301 | .. raw:: latex |
| 262 | 302 | ||
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst index d3a553cd86c9..51c1d5c9eb00 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-camera.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-camera.rst | |||
| @@ -88,7 +88,7 @@ enum v4l2_exposure_metering - | |||
| 88 | Determines how the camera measures the amount of light available for | 88 | Determines how the camera measures the amount of light available for |
| 89 | the frame exposure. Possible values are: | 89 | the frame exposure. Possible values are: |
| 90 | 90 | ||
| 91 | .. tabularcolumns:: |p{8.5cm}|p{9.0cm}| | 91 | .. tabularcolumns:: |p{8.7cm}|p{8.8cm}| |
| 92 | 92 | ||
| 93 | .. flat-table:: | 93 | .. flat-table:: |
| 94 | :header-rows: 0 | 94 | :header-rows: 0 |
| @@ -180,7 +180,7 @@ enum v4l2_exposure_metering - | |||
| 180 | control may stop updates of the ``V4L2_CID_AUTO_FOCUS_STATUS`` | 180 | control may stop updates of the ``V4L2_CID_AUTO_FOCUS_STATUS`` |
| 181 | control value. | 181 | control value. |
| 182 | 182 | ||
| 183 | .. tabularcolumns:: |p{6.5cm}|p{11.0cm}| | 183 | .. tabularcolumns:: |p{6.7cm}|p{10.8cm}| |
| 184 | 184 | ||
| 185 | .. flat-table:: | 185 | .. flat-table:: |
| 186 | :header-rows: 0 | 186 | :header-rows: 0 |
| @@ -206,7 +206,7 @@ enum v4l2_exposure_metering - | |||
| 206 | enum v4l2_auto_focus_range - | 206 | enum v4l2_auto_focus_range - |
| 207 | Determines auto focus distance range for which lens may be adjusted. | 207 | Determines auto focus distance range for which lens may be adjusted. |
| 208 | 208 | ||
| 209 | .. tabularcolumns:: |p{6.5cm}|p{11.0cm}| | 209 | .. tabularcolumns:: |p{6.8cm}|p{10.7cm}| |
| 210 | 210 | ||
| 211 | .. flat-table:: | 211 | .. flat-table:: |
| 212 | :header-rows: 0 | 212 | :header-rows: 0 |
| @@ -281,7 +281,7 @@ enum v4l2_auto_n_preset_white_balance - | |||
| 281 | representation. The following white balance presets are listed in | 281 | representation. The following white balance presets are listed in |
| 282 | order of increasing color temperature. | 282 | order of increasing color temperature. |
| 283 | 283 | ||
| 284 | .. tabularcolumns:: |p{7.0 cm}|p{10.5cm}| | 284 | .. tabularcolumns:: |p{7.2 cm}|p{10.3cm}| |
| 285 | 285 | ||
| 286 | .. flat-table:: | 286 | .. flat-table:: |
| 287 | :header-rows: 0 | 287 | :header-rows: 0 |
| @@ -387,7 +387,11 @@ enum v4l2_scene_mode - | |||
| 387 | to ``V4L2_SCENE_MODE_NONE`` to make sure the other possibly related | 387 | to ``V4L2_SCENE_MODE_NONE`` to make sure the other possibly related |
| 388 | controls are accessible. The following scene programs are defined: | 388 | controls are accessible. The following scene programs are defined: |
| 389 | 389 | ||
| 390 | .. tabularcolumns:: |p{6.0cm}|p{11.5cm}| | 390 | .. raw:: latex |
| 391 | |||
| 392 | \small | ||
| 393 | |||
| 394 | .. tabularcolumns:: |p{5.9cm}|p{11.5cm}| | ||
| 391 | 395 | ||
| 392 | .. flat-table:: | 396 | .. flat-table:: |
| 393 | :header-rows: 0 | 397 | :header-rows: 0 |
| @@ -459,6 +463,9 @@ enum v4l2_scene_mode - | |||
| 459 | may be switched to close-up mode and this setting may also involve | 463 | may be switched to close-up mode and this setting may also involve |
| 460 | some lens-distortion correction. | 464 | some lens-distortion correction. |
| 461 | 465 | ||
| 466 | .. raw:: latex | ||
| 467 | |||
| 468 | \normalsize | ||
| 462 | 469 | ||
| 463 | 470 | ||
| 464 | ``V4L2_CID_3A_LOCK (bitmask)`` | 471 | ``V4L2_CID_3A_LOCK (bitmask)`` |
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst index c97fb7923be5..4a8446203085 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst | |||
| @@ -105,7 +105,7 @@ enum v4l2_mpeg_stream_vbi_fmt - | |||
| 105 | 105 | ||
| 106 | 106 | ||
| 107 | 107 | ||
| 108 | .. tabularcolumns:: |p{6 cm}|p{11.5cm}| | 108 | .. tabularcolumns:: |p{6.6 cm}|p{10.9cm}| |
| 109 | 109 | ||
| 110 | .. flat-table:: | 110 | .. flat-table:: |
| 111 | :header-rows: 0 | 111 | :header-rows: 0 |
| @@ -477,7 +477,7 @@ enum v4l2_mpeg_audio_dec_playback - | |||
| 477 | 477 | ||
| 478 | 478 | ||
| 479 | 479 | ||
| 480 | .. tabularcolumns:: |p{9.0cm}|p{8.5cm}| | 480 | .. tabularcolumns:: |p{9.8cm}|p{7.7cm}| |
| 481 | 481 | ||
| 482 | .. flat-table:: | 482 | .. flat-table:: |
| 483 | :header-rows: 0 | 483 | :header-rows: 0 |
| @@ -888,7 +888,7 @@ enum v4l2_mpeg_video_multi_slice_mode - | |||
| 888 | 888 | ||
| 889 | 889 | ||
| 890 | 890 | ||
| 891 | .. tabularcolumns:: |p{8.7cm}|p{8.8cm}| | 891 | .. tabularcolumns:: |p{9.6cm}|p{7.9cm}| |
| 892 | 892 | ||
| 893 | .. flat-table:: | 893 | .. flat-table:: |
| 894 | :header-rows: 0 | 894 | :header-rows: 0 |
| @@ -923,9 +923,11 @@ enum v4l2_mpeg_video_multi_slice_mode - | |||
| 923 | enum v4l2_mpeg_video_h264_loop_filter_mode - | 923 | enum v4l2_mpeg_video_h264_loop_filter_mode - |
| 924 | Loop filter mode for H264 encoder. Possible values are: | 924 | Loop filter mode for H264 encoder. Possible values are: |
| 925 | 925 | ||
| 926 | .. raw:: latex | ||
| 926 | 927 | ||
| 928 | \small | ||
| 927 | 929 | ||
| 928 | .. tabularcolumns:: |p{14.0cm}|p{3.5cm}| | 930 | .. tabularcolumns:: |p{13.6cm}|p{3.9cm}| |
| 929 | 931 | ||
| 930 | .. flat-table:: | 932 | .. flat-table:: |
| 931 | :header-rows: 0 | 933 | :header-rows: 0 |
| @@ -938,6 +940,9 @@ enum v4l2_mpeg_video_h264_loop_filter_mode - | |||
| 938 | * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY`` | 940 | * - ``V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY`` |
| 939 | - Loop filter is disabled at the slice boundary. | 941 | - Loop filter is disabled at the slice boundary. |
| 940 | 942 | ||
| 943 | .. raw:: latex | ||
| 944 | |||
| 945 | \normalsize | ||
| 941 | 946 | ||
| 942 | 947 | ||
| 943 | ``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (integer)`` | 948 | ``V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (integer)`` |
| @@ -964,6 +969,8 @@ enum v4l2_mpeg_video_h264_entropy_mode - | |||
| 964 | encoder. Possible values are: | 969 | encoder. Possible values are: |
| 965 | 970 | ||
| 966 | 971 | ||
| 972 | .. tabularcolumns:: |p{9.0cm}|p{8.5cm}| | ||
| 973 | |||
| 967 | 974 | ||
| 968 | .. flat-table:: | 975 | .. flat-table:: |
| 969 | :header-rows: 0 | 976 | :header-rows: 0 |
| @@ -1048,6 +1055,30 @@ enum v4l2_mpeg_video_h264_entropy_mode - | |||
| 1048 | Quantization parameter for an B frame for H264. Valid range: from 0 | 1055 | Quantization parameter for an B frame for H264. Valid range: from 0 |
| 1049 | to 51. | 1056 | to 51. |
| 1050 | 1057 | ||
| 1058 | ``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (integer)`` | ||
| 1059 | Minimum quantization parameter for the H264 I frame to limit I frame | ||
| 1060 | quality to a range. Valid range: from 0 to 51. If | ||
| 1061 | V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter | ||
| 1062 | should be chosen to meet both requirements. | ||
| 1063 | |||
| 1064 | ``V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (integer)`` | ||
| 1065 | Maximum quantization parameter for the H264 I frame to limit I frame | ||
| 1066 | quality to a range. Valid range: from 0 to 51. If | ||
| 1067 | V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter | ||
| 1068 | should be chosen to meet both requirements. | ||
| 1069 | |||
| 1070 | ``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (integer)`` | ||
| 1071 | Minimum quantization parameter for the H264 P frame to limit P frame | ||
| 1072 | quality to a range. Valid range: from 0 to 51. If | ||
| 1073 | V4L2_CID_MPEG_VIDEO_H264_MIN_QP is also set, the quantization parameter | ||
| 1074 | should be chosen to meet both requirements. | ||
| 1075 | |||
| 1076 | ``V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (integer)`` | ||
| 1077 | Maximum quantization parameter for the H264 P frame to limit P frame | ||
| 1078 | quality to a range. Valid range: from 0 to 51. If | ||
| 1079 | V4L2_CID_MPEG_VIDEO_H264_MAX_QP is also set, the quantization parameter | ||
| 1080 | should be chosen to meet both requirements. | ||
| 1081 | |||
| 1051 | ``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)`` | 1082 | ``V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (integer)`` |
| 1052 | Quantization parameter for an I frame for MPEG4. Valid range: from 1 | 1083 | Quantization parameter for an I frame for MPEG4. Valid range: from 1 |
| 1053 | to 31. | 1084 | to 31. |
| @@ -1129,7 +1160,9 @@ enum v4l2_mpeg_video_header_mode - | |||
| 1129 | it returned together with the first frame. Applicable to encoders. | 1160 | it returned together with the first frame. Applicable to encoders. |
| 1130 | Possible values are: | 1161 | Possible values are: |
| 1131 | 1162 | ||
| 1163 | .. raw:: latex | ||
| 1132 | 1164 | ||
| 1165 | \small | ||
| 1133 | 1166 | ||
| 1134 | .. tabularcolumns:: |p{10.3cm}|p{7.2cm}| | 1167 | .. tabularcolumns:: |p{10.3cm}|p{7.2cm}| |
| 1135 | 1168 | ||
| @@ -1143,6 +1176,9 @@ enum v4l2_mpeg_video_header_mode - | |||
| 1143 | - The stream header is returned together with the first encoded | 1176 | - The stream header is returned together with the first encoded |
| 1144 | frame. | 1177 | frame. |
| 1145 | 1178 | ||
| 1179 | .. raw:: latex | ||
| 1180 | |||
| 1181 | \normalsize | ||
| 1146 | 1182 | ||
| 1147 | 1183 | ||
| 1148 | ``V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (boolean)`` | 1184 | ``V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (boolean)`` |
| @@ -1181,6 +1217,10 @@ enum v4l2_mpeg_video_h264_sei_fp_arrangement_type - | |||
| 1181 | Frame packing arrangement type for H264 SEI. Applicable to the H264 | 1217 | Frame packing arrangement type for H264 SEI. Applicable to the H264 |
| 1182 | encoder. Possible values are: | 1218 | encoder. Possible values are: |
| 1183 | 1219 | ||
| 1220 | .. raw:: latex | ||
| 1221 | |||
| 1222 | \small | ||
| 1223 | |||
| 1184 | .. tabularcolumns:: |p{12cm}|p{5.5cm}| | 1224 | .. tabularcolumns:: |p{12cm}|p{5.5cm}| |
| 1185 | 1225 | ||
| 1186 | .. flat-table:: | 1226 | .. flat-table:: |
| @@ -1200,6 +1240,10 @@ enum v4l2_mpeg_video_h264_sei_fp_arrangement_type - | |||
| 1200 | * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL`` | 1240 | * - ``V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL`` |
| 1201 | - One view per frame. | 1241 | - One view per frame. |
| 1202 | 1242 | ||
| 1243 | .. raw:: latex | ||
| 1244 | |||
| 1245 | \normalsize | ||
| 1246 | |||
| 1203 | 1247 | ||
| 1204 | 1248 | ||
| 1205 | ``V4L2_CID_MPEG_VIDEO_H264_FMO (boolean)`` | 1249 | ``V4L2_CID_MPEG_VIDEO_H264_FMO (boolean)`` |
| @@ -1217,6 +1261,10 @@ enum v4l2_mpeg_video_h264_fmo_map_type - | |||
| 1217 | patterns of macroblocks. Applicable to the H264 encoder. Possible | 1261 | patterns of macroblocks. Applicable to the H264 encoder. Possible |
| 1218 | values are: | 1262 | values are: |
| 1219 | 1263 | ||
| 1264 | .. raw:: latex | ||
| 1265 | |||
| 1266 | \small | ||
| 1267 | |||
| 1220 | .. tabularcolumns:: |p{12.5cm}|p{5.0cm}| | 1268 | .. tabularcolumns:: |p{12.5cm}|p{5.0cm}| |
| 1221 | 1269 | ||
| 1222 | .. flat-table:: | 1270 | .. flat-table:: |
| @@ -1240,6 +1288,10 @@ enum v4l2_mpeg_video_h264_fmo_map_type - | |||
| 1240 | * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT`` | 1288 | * - ``V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT`` |
| 1241 | - User defined map type. | 1289 | - User defined map type. |
| 1242 | 1290 | ||
| 1291 | .. raw:: latex | ||
| 1292 | |||
| 1293 | \normalsize | ||
| 1294 | |||
| 1243 | 1295 | ||
| 1244 | 1296 | ||
| 1245 | ``V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (integer)`` | 1297 | ``V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (integer)`` |
| @@ -1361,6 +1413,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - | |||
| 1361 | 1413 | ||
| 1362 | .. cssclass:: longtable | 1414 | .. cssclass:: longtable |
| 1363 | 1415 | ||
| 1416 | .. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}| | ||
| 1417 | |||
| 1364 | .. flat-table:: struct v4l2_ctrl_mpeg2_slice_params | 1418 | .. flat-table:: struct v4l2_ctrl_mpeg2_slice_params |
| 1365 | :header-rows: 0 | 1419 | :header-rows: 0 |
| 1366 | :stub-columns: 0 | 1420 | :stub-columns: 0 |
| @@ -1402,6 +1456,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - | |||
| 1402 | 1456 | ||
| 1403 | .. cssclass:: longtable | 1457 | .. cssclass:: longtable |
| 1404 | 1458 | ||
| 1459 | .. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| | ||
| 1460 | |||
| 1405 | .. flat-table:: struct v4l2_mpeg2_sequence | 1461 | .. flat-table:: struct v4l2_mpeg2_sequence |
| 1406 | :header-rows: 0 | 1462 | :header-rows: 0 |
| 1407 | :stub-columns: 0 | 1463 | :stub-columns: 0 |
| @@ -1433,6 +1489,8 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - | |||
| 1433 | 1489 | ||
| 1434 | .. cssclass:: longtable | 1490 | .. cssclass:: longtable |
| 1435 | 1491 | ||
| 1492 | .. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}| | ||
| 1493 | |||
| 1436 | .. flat-table:: struct v4l2_mpeg2_picture | 1494 | .. flat-table:: struct v4l2_mpeg2_picture |
| 1437 | :header-rows: 0 | 1495 | :header-rows: 0 |
| 1438 | :stub-columns: 0 | 1496 | :stub-columns: 0 |
| @@ -1492,6 +1550,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - | |||
| 1492 | 1550 | ||
| 1493 | .. cssclass:: longtable | 1551 | .. cssclass:: longtable |
| 1494 | 1552 | ||
| 1553 | .. tabularcolumns:: |p{1.2cm}|p{8.0cm}|p{7.4cm}| | ||
| 1554 | |||
| 1555 | .. raw:: latex | ||
| 1556 | |||
| 1557 | \small | ||
| 1558 | |||
| 1495 | .. flat-table:: struct v4l2_ctrl_mpeg2_quantization | 1559 | .. flat-table:: struct v4l2_ctrl_mpeg2_quantization |
| 1496 | :header-rows: 0 | 1560 | :header-rows: 0 |
| 1497 | :stub-columns: 0 | 1561 | :stub-columns: 0 |
| @@ -1537,6 +1601,19 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - | |||
| 1537 | non-intra-coded frames, in zigzag scanning order. Only relevant for | 1601 | non-intra-coded frames, in zigzag scanning order. Only relevant for |
| 1538 | non-4:2:0 YUV formats. | 1602 | non-4:2:0 YUV formats. |
| 1539 | 1603 | ||
| 1604 | ``V4L2_CID_FWHT_I_FRAME_QP (integer)`` | ||
| 1605 | Quantization parameter for an I frame for FWHT. Valid range: from 1 | ||
| 1606 | to 31. | ||
| 1607 | |||
| 1608 | ``V4L2_CID_FWHT_P_FRAME_QP (integer)`` | ||
| 1609 | Quantization parameter for a P frame for FWHT. Valid range: from 1 | ||
| 1610 | to 31. | ||
| 1611 | |||
| 1612 | .. raw:: latex | ||
| 1613 | |||
| 1614 | \normalsize | ||
| 1615 | |||
| 1616 | |||
| 1540 | MFC 5.1 MPEG Controls | 1617 | MFC 5.1 MPEG Controls |
| 1541 | ===================== | 1618 | ===================== |
| 1542 | 1619 | ||
| @@ -1644,7 +1721,11 @@ enum v4l2_mpeg_mfc51_video_frame_skip_mode - | |||
| 1644 | are: | 1721 | are: |
| 1645 | 1722 | ||
| 1646 | 1723 | ||
| 1647 | .. tabularcolumns:: |p{9.0cm}|p{8.5cm}| | 1724 | .. tabularcolumns:: |p{9.2cm}|p{8.3cm}| |
| 1725 | |||
| 1726 | .. raw:: latex | ||
| 1727 | |||
| 1728 | \small | ||
| 1648 | 1729 | ||
| 1649 | .. flat-table:: | 1730 | .. flat-table:: |
| 1650 | :header-rows: 0 | 1731 | :header-rows: 0 |
| @@ -1659,7 +1740,9 @@ enum v4l2_mpeg_mfc51_video_frame_skip_mode - | |||
| 1659 | - Frame skip mode enabled and buffer limit is set by the VBV | 1740 | - Frame skip mode enabled and buffer limit is set by the VBV |
| 1660 | (MPEG1/2/4) or CPB (H264) buffer size control. | 1741 | (MPEG1/2/4) or CPB (H264) buffer size control. |
| 1661 | 1742 | ||
| 1743 | .. raw:: latex | ||
| 1662 | 1744 | ||
| 1745 | \normalsize | ||
| 1663 | 1746 | ||
| 1664 | ``V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (integer)`` | 1747 | ``V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (integer)`` |
| 1665 | Enable rate-control with fixed target bit. If this setting is | 1748 | Enable rate-control with fixed target bit. If this setting is |
| @@ -1682,7 +1765,7 @@ enum v4l2_mpeg_mfc51_video_force_frame_type - | |||
| 1682 | Force a frame type for the next queued buffer. Applicable to | 1765 | Force a frame type for the next queued buffer. Applicable to |
| 1683 | encoders. Possible values are: | 1766 | encoders. Possible values are: |
| 1684 | 1767 | ||
| 1685 | 1768 | .. tabularcolumns:: |p{9.5cm}|p{8.0cm}| | |
| 1686 | 1769 | ||
| 1687 | .. flat-table:: | 1770 | .. flat-table:: |
| 1688 | :header-rows: 0 | 1771 | :header-rows: 0 |
| @@ -1696,6 +1779,125 @@ enum v4l2_mpeg_mfc51_video_force_frame_type - | |||
| 1696 | - Force a non-coded frame. | 1779 | - Force a non-coded frame. |
| 1697 | 1780 | ||
| 1698 | 1781 | ||
| 1782 | .. _v4l2-mpeg-fwht: | ||
| 1783 | |||
| 1784 | ``V4L2_CID_MPEG_VIDEO_FWHT_PARAMS (struct)`` | ||
| 1785 | Specifies the fwht parameters (as extracted from the bitstream) for the | ||
| 1786 | associated FWHT data. This includes the necessary parameters for | ||
| 1787 | configuring a stateless hardware decoding pipeline for FWHT. | ||
| 1788 | |||
| 1789 | .. note:: | ||
| 1790 | |||
| 1791 | This compound control is not yet part of the public kernel API and | ||
| 1792 | it is expected to change. | ||
| 1793 | |||
| 1794 | .. c:type:: v4l2_ctrl_fwht_params | ||
| 1795 | |||
| 1796 | .. cssclass:: longtable | ||
| 1797 | |||
| 1798 | .. tabularcolumns:: |p{1.4cm}|p{4.3cm}|p{11.8cm}| | ||
| 1799 | |||
| 1800 | .. flat-table:: struct v4l2_ctrl_fwht_params | ||
| 1801 | :header-rows: 0 | ||
| 1802 | :stub-columns: 0 | ||
| 1803 | :widths: 1 1 2 | ||
| 1804 | |||
| 1805 | * - __u64 | ||
| 1806 | - ``backward_ref_ts`` | ||
| 1807 | - Timestamp of the V4L2 capture buffer to use as backward reference, used | ||
| 1808 | with P-coded frames. The timestamp refers to the | ||
| 1809 | ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the | ||
| 1810 | :c:func:`v4l2_timeval_to_ns()` function to convert the struct | ||
| 1811 | :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. | ||
| 1812 | * - __u32 | ||
| 1813 | - ``version`` | ||
| 1814 | - The version of the codec | ||
| 1815 | * - __u32 | ||
| 1816 | - ``width`` | ||
| 1817 | - The width of the frame | ||
| 1818 | * - __u32 | ||
| 1819 | - ``height`` | ||
| 1820 | - The height of the frame | ||
| 1821 | * - __u32 | ||
| 1822 | - ``flags`` | ||
| 1823 | - The flags of the frame, see :ref:`fwht-flags`. | ||
| 1824 | * - __u32 | ||
| 1825 | - ``colorspace`` | ||
| 1826 | - The colorspace of the frame, from enum :c:type:`v4l2_colorspace`. | ||
| 1827 | * - __u32 | ||
| 1828 | - ``xfer_func`` | ||
| 1829 | - The transfer function, from enum :c:type:`v4l2_xfer_func`. | ||
| 1830 | * - __u32 | ||
| 1831 | - ``ycbcr_enc`` | ||
| 1832 | - The Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. | ||
| 1833 | * - __u32 | ||
| 1834 | - ``quantization`` | ||
| 1835 | - The quantization range, from enum :c:type:`v4l2_quantization`. | ||
| 1836 | |||
| 1837 | |||
| 1838 | |||
| 1839 | .. _fwht-flags: | ||
| 1840 | |||
| 1841 | FWHT Flags | ||
| 1842 | ============ | ||
| 1843 | |||
| 1844 | .. cssclass:: longtable | ||
| 1845 | |||
| 1846 | .. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.3cm}| | ||
| 1847 | |||
| 1848 | .. flat-table:: | ||
| 1849 | :header-rows: 0 | ||
| 1850 | :stub-columns: 0 | ||
| 1851 | :widths: 3 1 4 | ||
| 1852 | |||
| 1853 | * - ``FWHT_FL_IS_INTERLACED`` | ||
| 1854 | - 0x00000001 | ||
| 1855 | - Set if this is an interlaced format | ||
| 1856 | * - ``FWHT_FL_IS_BOTTOM_FIRST`` | ||
| 1857 | - 0x00000002 | ||
| 1858 | - Set if this is a bottom-first (NTSC) interlaced format | ||
| 1859 | * - ``FWHT_FL_IS_ALTERNATE`` | ||
| 1860 | - 0x00000004 | ||
| 1861 | - Set if each 'frame' contains just one field | ||
| 1862 | * - ``FWHT_FL_IS_BOTTOM_FIELD`` | ||
| 1863 | - 0x00000008 | ||
| 1864 | - If FWHT_FL_IS_ALTERNATE was set, then this is set if this 'frame' is the | ||
| 1865 | bottom field, else it is the top field. | ||
| 1866 | * - ``FWHT_FL_LUMA_IS_UNCOMPRESSED`` | ||
| 1867 | - 0x00000010 | ||
| 1868 | - Set if the luma plane is uncompressed | ||
| 1869 | * - ``FWHT_FL_CB_IS_UNCOMPRESSED`` | ||
| 1870 | - 0x00000020 | ||
| 1871 | - Set if the cb plane is uncompressed | ||
| 1872 | * - ``FWHT_FL_CR_IS_UNCOMPRESSED`` | ||
| 1873 | - 0x00000040 | ||
| 1874 | - Set if the cr plane is uncompressed | ||
| 1875 | * - ``FWHT_FL_CHROMA_FULL_HEIGHT`` | ||
| 1876 | - 0x00000080 | ||
| 1877 | - Set if the chroma plane has the same height as the luma plane, | ||
| 1878 | else the chroma plane is half the height of the luma plane | ||
| 1879 | * - ``FWHT_FL_CHROMA_FULL_WIDTH`` | ||
| 1880 | - 0x00000100 | ||
| 1881 | - Set if the chroma plane has the same width as the luma plane, | ||
| 1882 | else the chroma plane is half the width of the luma plane | ||
| 1883 | * - ``FWHT_FL_ALPHA_IS_UNCOMPRESSED`` | ||
| 1884 | - 0x00000200 | ||
| 1885 | - Set if the alpha plane is uncompressed | ||
| 1886 | * - ``FWHT_FL_I_FRAME`` | ||
| 1887 | - 0x00000400 | ||
| 1888 | - Set if this is an I-frame | ||
| 1889 | * - ``FWHT_FL_COMPONENTS_NUM_MSK`` | ||
| 1890 | - 0x00070000 | ||
| 1891 | - A 4-values flag - the number of components - 1 | ||
| 1892 | * - ``FWHT_FL_PIXENC_YUV`` | ||
| 1893 | - 0x00080000 | ||
| 1894 | - Set if the pixel encoding is YUV | ||
| 1895 | * - ``FWHT_FL_PIXENC_RGB`` | ||
| 1896 | - 0x00100000 | ||
| 1897 | - Set if the pixel encoding is RGB | ||
| 1898 | * - ``FWHT_FL_PIXENC_HSV`` | ||
| 1899 | - 0x00180000 | ||
| 1900 | - Set if the pixel encoding is HSV | ||
| 1699 | 1901 | ||
| 1700 | 1902 | ||
| 1701 | CX2341x MPEG Controls | 1903 | CX2341x MPEG Controls |
| @@ -1745,9 +1947,11 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type - | |||
| 1745 | Select the algorithm to use for the Luma Spatial Filter (default | 1947 | Select the algorithm to use for the Luma Spatial Filter (default |
| 1746 | ``1D_HOR``). Possible values: | 1948 | ``1D_HOR``). Possible values: |
| 1747 | 1949 | ||
| 1950 | .. tabularcolumns:: |p{14.5cm}|p{3.0cm}| | ||
| 1748 | 1951 | ||
| 1952 | .. raw:: latex | ||
| 1749 | 1953 | ||
| 1750 | .. tabularcolumns:: |p{14.5cm}|p{3.0cm}| | 1954 | \small |
| 1751 | 1955 | ||
| 1752 | .. flat-table:: | 1956 | .. flat-table:: |
| 1753 | :header-rows: 0 | 1957 | :header-rows: 0 |
| @@ -1764,6 +1968,10 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type - | |||
| 1764 | * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE`` | 1968 | * - ``V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE`` |
| 1765 | - Two-dimensional symmetrical non-separable | 1969 | - Two-dimensional symmetrical non-separable |
| 1766 | 1970 | ||
| 1971 | .. raw:: latex | ||
| 1972 | |||
| 1973 | \normalsize | ||
| 1974 | |||
| 1767 | 1975 | ||
| 1768 | 1976 | ||
| 1769 | .. _chroma-spatial-filter-type: | 1977 | .. _chroma-spatial-filter-type: |
| @@ -1776,6 +1984,7 @@ enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type - | |||
| 1776 | ``1D_HOR``). Possible values are: | 1984 | ``1D_HOR``). Possible values are: |
| 1777 | 1985 | ||
| 1778 | 1986 | ||
| 1987 | .. tabularcolumns:: |p{14.0cm}|p{3.5cm}| | ||
| 1779 | 1988 | ||
| 1780 | .. flat-table:: | 1989 | .. flat-table:: |
| 1781 | :header-rows: 0 | 1990 | :header-rows: 0 |
| @@ -1918,6 +2127,10 @@ enum v4l2_vp8_num_ref_frames - | |||
| 1918 | 2127 | ||
| 1919 | .. tabularcolumns:: |p{7.9cm}|p{9.6cm}| | 2128 | .. tabularcolumns:: |p{7.9cm}|p{9.6cm}| |
| 1920 | 2129 | ||
| 2130 | .. raw:: latex | ||
| 2131 | |||
| 2132 | \small | ||
| 2133 | |||
| 1921 | .. flat-table:: | 2134 | .. flat-table:: |
| 1922 | :header-rows: 0 | 2135 | :header-rows: 0 |
| 1923 | :stub-columns: 0 | 2136 | :stub-columns: 0 |
| @@ -1932,6 +2145,10 @@ enum v4l2_vp8_num_ref_frames - | |||
| 1932 | - The last encoded frame, the golden frame and the altref frame will | 2145 | - The last encoded frame, the golden frame and the altref frame will |
| 1933 | be searched. | 2146 | be searched. |
| 1934 | 2147 | ||
| 2148 | .. raw:: latex | ||
| 2149 | |||
| 2150 | \normalsize | ||
| 2151 | |||
| 1935 | 2152 | ||
| 1936 | 2153 | ||
| 1937 | ``V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (integer)`` | 2154 | ``V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (integer)`` |
| @@ -1961,7 +2178,7 @@ enum v4l2_vp8_golden_frame_sel - | |||
| 1961 | 2178 | ||
| 1962 | .. raw:: latex | 2179 | .. raw:: latex |
| 1963 | 2180 | ||
| 1964 | \footnotesize | 2181 | \scriptsize |
| 1965 | 2182 | ||
| 1966 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| | 2183 | .. tabularcolumns:: |p{9.0cm}|p{8.0cm}| |
| 1967 | 2184 | ||
| @@ -2283,7 +2500,7 @@ enum v4l2_mpeg_video_hevc_loop_filter_mode - | |||
| 2283 | 2500 | ||
| 2284 | \footnotesize | 2501 | \footnotesize |
| 2285 | 2502 | ||
| 2286 | .. tabularcolumns:: |p{10.7cm}|p{6.3cm}| | 2503 | .. tabularcolumns:: |p{12.1cm}|p{5.4cm}| |
| 2287 | 2504 | ||
| 2288 | .. flat-table:: | 2505 | .. flat-table:: |
| 2289 | :header-rows: 0 | 2506 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-detect.rst b/Documentation/media/uapi/v4l/ext-ctrls-detect.rst index 8a45ce642829..80981d0cff42 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-detect.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-detect.rst | |||
| @@ -30,7 +30,7 @@ Detect Control IDs | |||
| 30 | ``V4L2_CID_DETECT_MD_MODE (menu)`` | 30 | ``V4L2_CID_DETECT_MD_MODE (menu)`` |
| 31 | Sets the motion detection mode. | 31 | Sets the motion detection mode. |
| 32 | 32 | ||
| 33 | .. tabularcolumns:: |p{7.5cm}|p{10.0cm}| | 33 | .. tabularcolumns:: |p{7.7cm}|p{9.8cm}| |
| 34 | 34 | ||
| 35 | .. flat-table:: | 35 | .. flat-table:: |
| 36 | :header-rows: 0 | 36 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-dv.rst b/Documentation/media/uapi/v4l/ext-ctrls-dv.rst index 57edf211875c..5c70ac98f710 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-dv.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-dv.rst | |||
| @@ -106,7 +106,7 @@ enum v4l2_dv_it_content_type - | |||
| 106 | or an analog source. The enum v4l2_dv_it_content_type defines | 106 | or an analog source. The enum v4l2_dv_it_content_type defines |
| 107 | the possible content types: | 107 | the possible content types: |
| 108 | 108 | ||
| 109 | .. tabularcolumns:: |p{7.0cm}|p{10.5cm}| | 109 | .. tabularcolumns:: |p{7.3cm}|p{10.4cm}| |
| 110 | 110 | ||
| 111 | .. flat-table:: | 111 | .. flat-table:: |
| 112 | :header-rows: 0 | 112 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst b/Documentation/media/uapi/v4l/ext-ctrls-flash.rst index 5f30791c35b5..eff056b17167 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-flash.rst | |||
| @@ -87,7 +87,7 @@ Flash Control IDs | |||
| 87 | ``V4L2_CID_FLASH_STROBE_SOURCE (menu)`` | 87 | ``V4L2_CID_FLASH_STROBE_SOURCE (menu)`` |
| 88 | Defines the source of the flash LED strobe. | 88 | Defines the source of the flash LED strobe. |
| 89 | 89 | ||
| 90 | .. tabularcolumns:: |p{7.0cm}|p{10.5cm}| | 90 | .. tabularcolumns:: |p{7.5cm}|p{10.0cm}| |
| 91 | 91 | ||
| 92 | .. flat-table:: | 92 | .. flat-table:: |
| 93 | :header-rows: 0 | 93 | :header-rows: 0 |
| @@ -146,7 +146,7 @@ Flash Control IDs | |||
| 146 | an effect is chip dependent. Reading the faults resets the control | 146 | an effect is chip dependent. Reading the faults resets the control |
| 147 | and returns the chip to a usable state if possible. | 147 | and returns the chip to a usable state if possible. |
| 148 | 148 | ||
| 149 | .. tabularcolumns:: |p{8.0cm}|p{9.5cm}| | 149 | .. tabularcolumns:: |p{8.4cm}|p{9.1cm}| |
| 150 | 150 | ||
| 151 | .. flat-table:: | 151 | .. flat-table:: |
| 152 | :header-rows: 0 | 152 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst b/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst index cf9cd8a9f9b4..60ce3f949319 100644 --- a/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst +++ b/Documentation/media/uapi/v4l/ext-ctrls-jpeg.rst | |||
| @@ -37,7 +37,7 @@ JPEG Control IDs | |||
| 37 | how Cb and Cr components are downsampled after converting an input | 37 | how Cb and Cr components are downsampled after converting an input |
| 38 | image from RGB to Y'CbCr color space. | 38 | image from RGB to Y'CbCr color space. |
| 39 | 39 | ||
| 40 | .. tabularcolumns:: |p{7.0cm}|p{10.5cm}| | 40 | .. tabularcolumns:: |p{7.5cm}|p{10.0cm}| |
| 41 | 41 | ||
| 42 | .. flat-table:: | 42 | .. flat-table:: |
| 43 | :header-rows: 0 | 43 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/field-order.rst b/Documentation/media/uapi/v4l/field-order.rst index 8415268d439c..3fb473e3b8e2 100644 --- a/Documentation/media/uapi/v4l/field-order.rst +++ b/Documentation/media/uapi/v4l/field-order.rst | |||
| @@ -64,7 +64,9 @@ enum v4l2_field | |||
| 64 | 64 | ||
| 65 | .. c:type:: v4l2_field | 65 | .. c:type:: v4l2_field |
| 66 | 66 | ||
| 67 | .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| | 67 | .. tabularcolumns:: |p{5.8cm}|p{0.6cm}|p{11.1cm}| |
| 68 | |||
| 69 | .. cssclass:: longtable | ||
| 68 | 70 | ||
| 69 | .. flat-table:: | 71 | .. flat-table:: |
| 70 | :header-rows: 0 | 72 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst index 2675bef3eefe..6c961cfb74da 100644 --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst | |||
| @@ -125,3 +125,9 @@ Compressed Formats | |||
| 125 | - Video elementary stream using a codec based on the Fast Walsh Hadamard | 125 | - Video elementary stream using a codec based on the Fast Walsh Hadamard |
| 126 | Transform. This codec is implemented by the vicodec ('Virtual Codec') | 126 | Transform. This codec is implemented by the vicodec ('Virtual Codec') |
| 127 | driver. See the codec-fwht.h header for more details. | 127 | driver. See the codec-fwht.h header for more details. |
| 128 | * .. _V4L2-PIX-FMT-FWHT-STATELESS: | ||
| 129 | |||
| 130 | - ``V4L2_PIX_FMT_FWHT_STATELESS`` | ||
| 131 | - 'SFWH' | ||
| 132 | - Same format as V4L2_PIX_FMT_FWHT but requires stateless codec implementation. | ||
| 133 | See the :ref:`associated Codec Control IDs <v4l2-mpeg-fwht>`. | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst index 862e1f327150..87e8fd7d5d02 100644 --- a/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst +++ b/Documentation/media/uapi/v4l/pixfmt-meta-d4xx.rst | |||
| @@ -36,13 +36,16 @@ per frame, therefore their headers cannot be larger than 255 bytes. | |||
| 36 | Below are proprietary Microsoft style metadata types, used by D4xx cameras, | 36 | Below are proprietary Microsoft style metadata types, used by D4xx cameras, |
| 37 | where all fields are in little endian order: | 37 | where all fields are in little endian order: |
| 38 | 38 | ||
| 39 | .. tabularcolumns:: |p{5.0cm}|p{12.5cm}| | ||
| 40 | |||
| 41 | |||
| 39 | .. flat-table:: D4xx metadata | 42 | .. flat-table:: D4xx metadata |
| 40 | :widths: 1 4 | 43 | :widths: 1 2 |
| 41 | :header-rows: 1 | 44 | :header-rows: 1 |
| 42 | :stub-columns: 0 | 45 | :stub-columns: 0 |
| 43 | 46 | ||
| 44 | * - Field | 47 | * - **Field** |
| 45 | - Description | 48 | - **Description** |
| 46 | * - :cspan:`1` *Depth Control* | 49 | * - :cspan:`1` *Depth Control* |
| 47 | * - __u32 ID | 50 | * - __u32 ID |
| 48 | - 0x80000000 | 51 | - 0x80000000 |
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst b/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst index 2ebccdcca95d..d1a341af9c48 100644 --- a/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst +++ b/Documentation/media/uapi/v4l/pixfmt-meta-vsp1-hgt.rst | |||
| @@ -41,6 +41,10 @@ The Hue position **m** (0 - 5) of the bucket in the matrix depends on | |||
| 41 | how the HGT Hue areas are configured. There are 6 user configurable Hue | 41 | how the HGT Hue areas are configured. There are 6 user configurable Hue |
| 42 | Areas which can be configured to cover overlapping Hue values: | 42 | Areas which can be configured to cover overlapping Hue values: |
| 43 | 43 | ||
| 44 | .. raw:: latex | ||
| 45 | |||
| 46 | \small | ||
| 47 | |||
| 44 | :: | 48 | :: |
| 45 | 49 | ||
| 46 | Area 0 Area 1 Area 2 Area 3 Area 4 Area 5 | 50 | Area 0 Area 1 Area 2 Area 3 Area 4 Area 5 |
| @@ -53,6 +57,11 @@ Areas which can be configured to cover overlapping Hue values: | |||
| 53 | 5U 0L 0U 1L 1U 2L 2U 3L 3U 4L 4U 5L 5U 0L | 57 | 5U 0L 0U 1L 1U 2L 2U 3L 3U 4L 4U 5L 5U 0L |
| 54 | <0..............................Hue Value............................255> | 58 | <0..............................Hue Value............................255> |
| 55 | 59 | ||
| 60 | |||
| 61 | .. raw:: latex | ||
| 62 | |||
| 63 | \normalsize | ||
| 64 | |||
| 56 | When two consecutive areas don't overlap (n+1L is equal to nU) the boundary | 65 | When two consecutive areas don't overlap (n+1L is equal to nU) the boundary |
| 57 | value is considered as part of the lower area. | 66 | value is considered as part of the lower area. |
| 58 | 67 | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst index 38b1895a509f..dfc4a8367b3d 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst | |||
| @@ -31,7 +31,7 @@ The values are packed in 24 or 32 bit formats. | |||
| 31 | \tiny | 31 | \tiny |
| 32 | \setlength{\tabcolsep}{2pt} | 32 | \setlength{\tabcolsep}{2pt} |
| 33 | 33 | ||
| 34 | .. tabularcolumns:: |p{2.0cm}|p{0.54cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| | 34 | .. tabularcolumns:: |p{2.6cm}|p{0.8cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| |
| 35 | 35 | ||
| 36 | .. _packed-hsv-formats: | 36 | .. _packed-hsv-formats: |
| 37 | 37 | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst index 6b3781c04dd5..738bb14c0ee2 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst | |||
| @@ -27,7 +27,7 @@ next to each other in memory. | |||
| 27 | \tiny | 27 | \tiny |
| 28 | \setlength{\tabcolsep}{2pt} | 28 | \setlength{\tabcolsep}{2pt} |
| 29 | 29 | ||
| 30 | .. tabularcolumns:: |p{2.3cm}|p{1.6cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| | 30 | .. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| |
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | .. _rgb-formats: | 33 | .. _rgb-formats: |
| @@ -139,6 +139,144 @@ next to each other in memory. | |||
| 139 | - r\ :sub:`1` | 139 | - r\ :sub:`1` |
| 140 | - r\ :sub:`0` | 140 | - r\ :sub:`0` |
| 141 | - | 141 | - |
| 142 | * .. _V4L2-PIX-FMT-RGBA444: | ||
| 143 | |||
| 144 | - ``V4L2_PIX_FMT_RGBA444`` | ||
| 145 | - 'RA12' | ||
| 146 | |||
| 147 | - b\ :sub:`3` | ||
| 148 | - b\ :sub:`2` | ||
| 149 | - b\ :sub:`1` | ||
| 150 | - b\ :sub:`0` | ||
| 151 | - a\ :sub:`3` | ||
| 152 | - a\ :sub:`2` | ||
| 153 | - a\ :sub:`1` | ||
| 154 | - a\ :sub:`0` | ||
| 155 | |||
| 156 | - r\ :sub:`3` | ||
| 157 | - r\ :sub:`2` | ||
| 158 | - r\ :sub:`1` | ||
| 159 | - r\ :sub:`0` | ||
| 160 | - g\ :sub:`3` | ||
| 161 | - g\ :sub:`2` | ||
| 162 | - g\ :sub:`1` | ||
| 163 | - g\ :sub:`0` | ||
| 164 | - | ||
| 165 | * .. _V4L2-PIX-FMT-RGBX444: | ||
| 166 | |||
| 167 | - ``V4L2_PIX_FMT_RGBX444`` | ||
| 168 | - 'RX12' | ||
| 169 | |||
| 170 | - b\ :sub:`3` | ||
| 171 | - b\ :sub:`2` | ||
| 172 | - b\ :sub:`1` | ||
| 173 | - b\ :sub:`0` | ||
| 174 | - | ||
| 175 | - | ||
| 176 | - | ||
| 177 | - | ||
| 178 | |||
| 179 | - r\ :sub:`3` | ||
| 180 | - r\ :sub:`2` | ||
| 181 | - r\ :sub:`1` | ||
| 182 | - r\ :sub:`0` | ||
| 183 | - g\ :sub:`3` | ||
| 184 | - g\ :sub:`2` | ||
| 185 | - g\ :sub:`1` | ||
| 186 | - g\ :sub:`0` | ||
| 187 | - | ||
| 188 | * .. _V4L2-PIX-FMT-ABGR444: | ||
| 189 | |||
| 190 | - ``V4L2_PIX_FMT_ABGR444`` | ||
| 191 | - 'AB12' | ||
| 192 | |||
| 193 | - g\ :sub:`3` | ||
| 194 | - g\ :sub:`2` | ||
| 195 | - g\ :sub:`1` | ||
| 196 | - g\ :sub:`0` | ||
| 197 | - r\ :sub:`3` | ||
| 198 | - r\ :sub:`2` | ||
| 199 | - r\ :sub:`1` | ||
| 200 | - r\ :sub:`0` | ||
| 201 | |||
| 202 | - a\ :sub:`3` | ||
| 203 | - a\ :sub:`2` | ||
| 204 | - a\ :sub:`1` | ||
| 205 | - a\ :sub:`0` | ||
| 206 | - b\ :sub:`3` | ||
| 207 | - b\ :sub:`2` | ||
| 208 | - b\ :sub:`1` | ||
| 209 | - b\ :sub:`0` | ||
| 210 | - | ||
| 211 | * .. _V4L2-PIX-FMT-XBGR444: | ||
| 212 | |||
| 213 | - ``V4L2_PIX_FMT_XBGR444`` | ||
| 214 | - 'XB12' | ||
| 215 | |||
| 216 | - g\ :sub:`3` | ||
| 217 | - g\ :sub:`2` | ||
| 218 | - g\ :sub:`1` | ||
| 219 | - g\ :sub:`0` | ||
| 220 | - r\ :sub:`3` | ||
| 221 | - r\ :sub:`2` | ||
| 222 | - r\ :sub:`1` | ||
| 223 | - r\ :sub:`0` | ||
| 224 | |||
| 225 | - | ||
| 226 | - | ||
| 227 | - | ||
| 228 | - | ||
| 229 | - b\ :sub:`3` | ||
| 230 | - b\ :sub:`2` | ||
| 231 | - b\ :sub:`1` | ||
| 232 | - b\ :sub:`0` | ||
| 233 | - | ||
| 234 | * .. _V4L2-PIX-FMT-BGRA444: | ||
| 235 | |||
| 236 | - ``V4L2_PIX_FMT_BGRA444`` | ||
| 237 | - 'BA12' | ||
| 238 | |||
| 239 | - r\ :sub:`3` | ||
| 240 | - r\ :sub:`2` | ||
| 241 | - r\ :sub:`1` | ||
| 242 | - r\ :sub:`0` | ||
| 243 | - a\ :sub:`3` | ||
| 244 | - a\ :sub:`2` | ||
| 245 | - a\ :sub:`1` | ||
| 246 | - a\ :sub:`0` | ||
| 247 | |||
| 248 | - b\ :sub:`3` | ||
| 249 | - b\ :sub:`2` | ||
| 250 | - b\ :sub:`1` | ||
| 251 | - b\ :sub:`0` | ||
| 252 | - g\ :sub:`3` | ||
| 253 | - g\ :sub:`2` | ||
| 254 | - g\ :sub:`1` | ||
| 255 | - g\ :sub:`0` | ||
| 256 | - | ||
| 257 | * .. _V4L2-PIX-FMT-BGRX444: | ||
| 258 | |||
| 259 | - ``V4L2_PIX_FMT_BGRX444`` | ||
| 260 | - 'BX12' | ||
| 261 | |||
| 262 | - r\ :sub:`3` | ||
| 263 | - r\ :sub:`2` | ||
| 264 | - r\ :sub:`1` | ||
| 265 | - r\ :sub:`0` | ||
| 266 | - | ||
| 267 | - | ||
| 268 | - | ||
| 269 | - | ||
| 270 | |||
| 271 | - b\ :sub:`3` | ||
| 272 | - b\ :sub:`2` | ||
| 273 | - b\ :sub:`1` | ||
| 274 | - b\ :sub:`0` | ||
| 275 | - g\ :sub:`3` | ||
| 276 | - g\ :sub:`2` | ||
| 277 | - g\ :sub:`1` | ||
| 278 | - g\ :sub:`0` | ||
| 279 | - | ||
| 142 | * .. _V4L2-PIX-FMT-ARGB555: | 280 | * .. _V4L2-PIX-FMT-ARGB555: |
| 143 | 281 | ||
| 144 | - ``V4L2_PIX_FMT_ARGB555`` | 282 | - ``V4L2_PIX_FMT_ARGB555`` |
| @@ -185,6 +323,144 @@ next to each other in memory. | |||
| 185 | - g\ :sub:`4` | 323 | - g\ :sub:`4` |
| 186 | - g\ :sub:`3` | 324 | - g\ :sub:`3` |
| 187 | - | 325 | - |
| 326 | * .. _V4L2-PIX-FMT-RGBA555: | ||
| 327 | |||
| 328 | - ``V4L2_PIX_FMT_RGBA555`` | ||
| 329 | - 'RA15' | ||
| 330 | |||
| 331 | - g\ :sub:`1` | ||
| 332 | - g\ :sub:`0` | ||
| 333 | - b\ :sub:`4` | ||
| 334 | - b\ :sub:`3` | ||
| 335 | - b\ :sub:`2` | ||
| 336 | - b\ :sub:`1` | ||
| 337 | - b\ :sub:`0` | ||
| 338 | - a | ||
| 339 | |||
| 340 | - r\ :sub:`4` | ||
| 341 | - r\ :sub:`3` | ||
| 342 | - r\ :sub:`2` | ||
| 343 | - r\ :sub:`1` | ||
| 344 | - r\ :sub:`0` | ||
| 345 | - g\ :sub:`4` | ||
| 346 | - g\ :sub:`3` | ||
| 347 | - g\ :sub:`2` | ||
| 348 | - | ||
| 349 | * .. _V4L2-PIX-FMT-RGBX555: | ||
| 350 | |||
| 351 | - ``V4L2_PIX_FMT_RGBX555`` | ||
| 352 | - 'RX15' | ||
| 353 | |||
| 354 | - g\ :sub:`1` | ||
| 355 | - g\ :sub:`0` | ||
| 356 | - b\ :sub:`4` | ||
| 357 | - b\ :sub:`3` | ||
| 358 | - b\ :sub:`2` | ||
| 359 | - b\ :sub:`1` | ||
| 360 | - b\ :sub:`0` | ||
| 361 | - | ||
| 362 | |||
| 363 | - r\ :sub:`4` | ||
| 364 | - r\ :sub:`3` | ||
| 365 | - r\ :sub:`2` | ||
| 366 | - r\ :sub:`1` | ||
| 367 | - r\ :sub:`0` | ||
| 368 | - g\ :sub:`4` | ||
| 369 | - g\ :sub:`3` | ||
| 370 | - g\ :sub:`2` | ||
| 371 | - | ||
| 372 | * .. _V4L2-PIX-FMT-ABGR555: | ||
| 373 | |||
| 374 | - ``V4L2_PIX_FMT_ABGR555`` | ||
| 375 | - 'AB15' | ||
| 376 | |||
| 377 | - g\ :sub:`2` | ||
| 378 | - g\ :sub:`1` | ||
| 379 | - g\ :sub:`0` | ||
| 380 | - r\ :sub:`4` | ||
| 381 | - r\ :sub:`3` | ||
| 382 | - r\ :sub:`2` | ||
| 383 | - r\ :sub:`1` | ||
| 384 | - r\ :sub:`0` | ||
| 385 | |||
| 386 | - a | ||
| 387 | - b\ :sub:`4` | ||
| 388 | - b\ :sub:`3` | ||
| 389 | - b\ :sub:`2` | ||
| 390 | - b\ :sub:`1` | ||
| 391 | - b\ :sub:`0` | ||
| 392 | - g\ :sub:`4` | ||
| 393 | - g\ :sub:`3` | ||
| 394 | - | ||
| 395 | * .. _V4L2-PIX-FMT-XBGR555: | ||
| 396 | |||
| 397 | - ``V4L2_PIX_FMT_XBGR555`` | ||
| 398 | - 'XB15' | ||
| 399 | |||
| 400 | - g\ :sub:`2` | ||
| 401 | - g\ :sub:`1` | ||
| 402 | - g\ :sub:`0` | ||
| 403 | - r\ :sub:`4` | ||
| 404 | - r\ :sub:`3` | ||
| 405 | - r\ :sub:`2` | ||
| 406 | - r\ :sub:`1` | ||
| 407 | - r\ :sub:`0` | ||
| 408 | |||
| 409 | - | ||
| 410 | - b\ :sub:`4` | ||
| 411 | - b\ :sub:`3` | ||
| 412 | - b\ :sub:`2` | ||
| 413 | - b\ :sub:`1` | ||
| 414 | - b\ :sub:`0` | ||
| 415 | - g\ :sub:`4` | ||
| 416 | - g\ :sub:`3` | ||
| 417 | - | ||
| 418 | * .. _V4L2-PIX-FMT-BGRA555: | ||
| 419 | |||
| 420 | - ``V4L2_PIX_FMT_BGRA555`` | ||
| 421 | - 'BA15' | ||
| 422 | |||
| 423 | - g\ :sub:`1` | ||
| 424 | - g\ :sub:`0` | ||
| 425 | - r\ :sub:`4` | ||
| 426 | - r\ :sub:`3` | ||
| 427 | - r\ :sub:`2` | ||
| 428 | - r\ :sub:`1` | ||
| 429 | - r\ :sub:`0` | ||
| 430 | - a | ||
| 431 | |||
| 432 | - b\ :sub:`4` | ||
| 433 | - b\ :sub:`3` | ||
| 434 | - b\ :sub:`2` | ||
| 435 | - b\ :sub:`1` | ||
| 436 | - b\ :sub:`0` | ||
| 437 | - g\ :sub:`4` | ||
| 438 | - g\ :sub:`3` | ||
| 439 | - g\ :sub:`2` | ||
| 440 | - | ||
| 441 | * .. _V4L2-PIX-FMT-BGRX555: | ||
| 442 | |||
| 443 | - ``V4L2_PIX_FMT_BGRX555`` | ||
| 444 | - 'BX15' | ||
| 445 | |||
| 446 | - g\ :sub:`1` | ||
| 447 | - g\ :sub:`0` | ||
| 448 | - r\ :sub:`4` | ||
| 449 | - r\ :sub:`3` | ||
| 450 | - r\ :sub:`2` | ||
| 451 | - r\ :sub:`1` | ||
| 452 | - r\ :sub:`0` | ||
| 453 | - | ||
| 454 | |||
| 455 | - b\ :sub:`4` | ||
| 456 | - b\ :sub:`3` | ||
| 457 | - b\ :sub:`2` | ||
| 458 | - b\ :sub:`1` | ||
| 459 | - b\ :sub:`0` | ||
| 460 | - g\ :sub:`4` | ||
| 461 | - g\ :sub:`3` | ||
| 462 | - g\ :sub:`2` | ||
| 463 | - | ||
| 188 | * .. _V4L2-PIX-FMT-RGB565: | 464 | * .. _V4L2-PIX-FMT-RGB565: |
| 189 | 465 | ||
| 190 | - ``V4L2_PIX_FMT_RGB565`` | 466 | - ``V4L2_PIX_FMT_RGB565`` |
| @@ -461,6 +737,166 @@ next to each other in memory. | |||
| 461 | - | 737 | - |
| 462 | - | 738 | - |
| 463 | - | 739 | - |
| 740 | * .. _V4L2-PIX-FMT-BGRA32: | ||
| 741 | |||
| 742 | - ``V4L2_PIX_FMT_BGRA32`` | ||
| 743 | - 'RA24' | ||
| 744 | |||
| 745 | - a\ :sub:`7` | ||
| 746 | - a\ :sub:`6` | ||
| 747 | - a\ :sub:`5` | ||
| 748 | - a\ :sub:`4` | ||
| 749 | - a\ :sub:`3` | ||
| 750 | - a\ :sub:`2` | ||
| 751 | - a\ :sub:`1` | ||
| 752 | - a\ :sub:`0` | ||
| 753 | |||
| 754 | - b\ :sub:`7` | ||
| 755 | - b\ :sub:`6` | ||
| 756 | - b\ :sub:`5` | ||
| 757 | - b\ :sub:`4` | ||
| 758 | - b\ :sub:`3` | ||
| 759 | - b\ :sub:`2` | ||
| 760 | - b\ :sub:`1` | ||
| 761 | - b\ :sub:`0` | ||
| 762 | |||
| 763 | - g\ :sub:`7` | ||
| 764 | - g\ :sub:`6` | ||
| 765 | - g\ :sub:`5` | ||
| 766 | - g\ :sub:`4` | ||
| 767 | - g\ :sub:`3` | ||
| 768 | - g\ :sub:`2` | ||
| 769 | - g\ :sub:`1` | ||
| 770 | - g\ :sub:`0` | ||
| 771 | |||
| 772 | - r\ :sub:`7` | ||
| 773 | - r\ :sub:`6` | ||
| 774 | - r\ :sub:`5` | ||
| 775 | - r\ :sub:`4` | ||
| 776 | - r\ :sub:`3` | ||
| 777 | - r\ :sub:`2` | ||
| 778 | - r\ :sub:`1` | ||
| 779 | - r\ :sub:`0` | ||
| 780 | * .. _V4L2-PIX-FMT-BGRX32: | ||
| 781 | |||
| 782 | - ``V4L2_PIX_FMT_BGRX32`` | ||
| 783 | - 'RX24' | ||
| 784 | |||
| 785 | - | ||
| 786 | - | ||
| 787 | - | ||
| 788 | - | ||
| 789 | - | ||
| 790 | - | ||
| 791 | - | ||
| 792 | - | ||
| 793 | |||
| 794 | - b\ :sub:`7` | ||
| 795 | - b\ :sub:`6` | ||
| 796 | - b\ :sub:`5` | ||
| 797 | - b\ :sub:`4` | ||
| 798 | - b\ :sub:`3` | ||
| 799 | - b\ :sub:`2` | ||
| 800 | - b\ :sub:`1` | ||
| 801 | - b\ :sub:`0` | ||
| 802 | |||
| 803 | - g\ :sub:`7` | ||
| 804 | - g\ :sub:`6` | ||
| 805 | - g\ :sub:`5` | ||
| 806 | - g\ :sub:`4` | ||
| 807 | - g\ :sub:`3` | ||
| 808 | - g\ :sub:`2` | ||
| 809 | - g\ :sub:`1` | ||
| 810 | - g\ :sub:`0` | ||
| 811 | |||
| 812 | - r\ :sub:`7` | ||
| 813 | - r\ :sub:`6` | ||
| 814 | - r\ :sub:`5` | ||
| 815 | - r\ :sub:`4` | ||
| 816 | - r\ :sub:`3` | ||
| 817 | - r\ :sub:`2` | ||
| 818 | - r\ :sub:`1` | ||
| 819 | - r\ :sub:`0` | ||
| 820 | * .. _V4L2-PIX-FMT-RGBA32: | ||
| 821 | |||
| 822 | - ``V4L2_PIX_FMT_RGBA32`` | ||
| 823 | - 'AB24' | ||
| 824 | |||
| 825 | - r\ :sub:`7` | ||
| 826 | - r\ :sub:`6` | ||
| 827 | - r\ :sub:`5` | ||
| 828 | - r\ :sub:`4` | ||
| 829 | - r\ :sub:`3` | ||
| 830 | - r\ :sub:`2` | ||
| 831 | - r\ :sub:`1` | ||
| 832 | - r\ :sub:`0` | ||
| 833 | |||
| 834 | - g\ :sub:`7` | ||
| 835 | - g\ :sub:`6` | ||
| 836 | - g\ :sub:`5` | ||
| 837 | - g\ :sub:`4` | ||
| 838 | - g\ :sub:`3` | ||
| 839 | - g\ :sub:`2` | ||
| 840 | - g\ :sub:`1` | ||
| 841 | - g\ :sub:`0` | ||
| 842 | |||
| 843 | - b\ :sub:`7` | ||
| 844 | - b\ :sub:`6` | ||
| 845 | - b\ :sub:`5` | ||
| 846 | - b\ :sub:`4` | ||
| 847 | - b\ :sub:`3` | ||
| 848 | - b\ :sub:`2` | ||
| 849 | - b\ :sub:`1` | ||
| 850 | - b\ :sub:`0` | ||
| 851 | |||
| 852 | - a\ :sub:`7` | ||
| 853 | - a\ :sub:`6` | ||
| 854 | - a\ :sub:`5` | ||
| 855 | - a\ :sub:`4` | ||
| 856 | - a\ :sub:`3` | ||
| 857 | - a\ :sub:`2` | ||
| 858 | - a\ :sub:`1` | ||
| 859 | - a\ :sub:`0` | ||
| 860 | * .. _V4L2-PIX-FMT-RGBX32: | ||
| 861 | |||
| 862 | - ``V4L2_PIX_FMT_RGBX32`` | ||
| 863 | - 'XB24' | ||
| 864 | |||
| 865 | - r\ :sub:`7` | ||
| 866 | - r\ :sub:`6` | ||
| 867 | - r\ :sub:`5` | ||
| 868 | - r\ :sub:`4` | ||
| 869 | - r\ :sub:`3` | ||
| 870 | - r\ :sub:`2` | ||
| 871 | - r\ :sub:`1` | ||
| 872 | - r\ :sub:`0` | ||
| 873 | |||
| 874 | - g\ :sub:`7` | ||
| 875 | - g\ :sub:`6` | ||
| 876 | - g\ :sub:`5` | ||
| 877 | - g\ :sub:`4` | ||
| 878 | - g\ :sub:`3` | ||
| 879 | - g\ :sub:`2` | ||
| 880 | - g\ :sub:`1` | ||
| 881 | - g\ :sub:`0` | ||
| 882 | |||
| 883 | - b\ :sub:`7` | ||
| 884 | - b\ :sub:`6` | ||
| 885 | - b\ :sub:`5` | ||
| 886 | - b\ :sub:`4` | ||
| 887 | - b\ :sub:`3` | ||
| 888 | - b\ :sub:`2` | ||
| 889 | - b\ :sub:`1` | ||
| 890 | - b\ :sub:`0` | ||
| 891 | |||
| 892 | - | ||
| 893 | - | ||
| 894 | - | ||
| 895 | - | ||
| 896 | - | ||
| 897 | - | ||
| 898 | - | ||
| 899 | - | ||
| 464 | * .. _V4L2-PIX-FMT-ARGB32: | 900 | * .. _V4L2-PIX-FMT-ARGB32: |
| 465 | 901 | ||
| 466 | - ``V4L2_PIX_FMT_ARGB32`` | 902 | - ``V4L2_PIX_FMT_ARGB32`` |
| @@ -656,7 +1092,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. | |||
| 656 | \tiny | 1092 | \tiny |
| 657 | \setlength{\tabcolsep}{2pt} | 1093 | \setlength{\tabcolsep}{2pt} |
| 658 | 1094 | ||
| 659 | .. tabularcolumns:: |p{2.2cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| | 1095 | .. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| |
| 660 | 1096 | ||
| 661 | .. _rgb-formats-deprecated: | 1097 | .. _rgb-formats-deprecated: |
| 662 | 1098 | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst index 7fcee1c11ac4..41b60fae703a 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst | |||
| @@ -28,7 +28,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 28 | 28 | ||
| 29 | .. _packed-yuv-formats: | 29 | .. _packed-yuv-formats: |
| 30 | 30 | ||
| 31 | .. tabularcolumns:: |p{2.0cm}|p{0.67cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}| | 31 | .. tabularcolumns:: |p{2.5cm}|p{0.69cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}|p{0.31cm}| |
| 32 | 32 | ||
| 33 | .. flat-table:: Packed YUV Image Formats | 33 | .. flat-table:: Packed YUV Image Formats |
| 34 | :header-rows: 2 | 34 | :header-rows: 2 |
| @@ -44,6 +44,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 44 | - :cspan:`7` Byte 2 | 44 | - :cspan:`7` Byte 2 |
| 45 | 45 | ||
| 46 | - :cspan:`7` Byte 3 | 46 | - :cspan:`7` Byte 3 |
| 47 | |||
| 47 | * - | 48 | * - |
| 48 | - | 49 | - |
| 49 | - 7 | 50 | - 7 |
| @@ -81,6 +82,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 81 | - 2 | 82 | - 2 |
| 82 | - 1 | 83 | - 1 |
| 83 | - 0 | 84 | - 0 |
| 85 | |||
| 84 | * .. _V4L2-PIX-FMT-YUV444: | 86 | * .. _V4L2-PIX-FMT-YUV444: |
| 85 | 87 | ||
| 86 | - ``V4L2_PIX_FMT_YUV444`` | 88 | - ``V4L2_PIX_FMT_YUV444`` |
| @@ -103,7 +105,9 @@ component of each pixel in one 16 or 32 bit word. | |||
| 103 | - Y'\ :sub:`2` | 105 | - Y'\ :sub:`2` |
| 104 | - Y'\ :sub:`1` | 106 | - Y'\ :sub:`1` |
| 105 | - Y'\ :sub:`0` | 107 | - Y'\ :sub:`0` |
| 106 | - | 108 | |
| 109 | - :cspan:`15` | ||
| 110 | |||
| 107 | * .. _V4L2-PIX-FMT-YUV555: | 111 | * .. _V4L2-PIX-FMT-YUV555: |
| 108 | 112 | ||
| 109 | - ``V4L2_PIX_FMT_YUV555`` | 113 | - ``V4L2_PIX_FMT_YUV555`` |
| @@ -126,7 +130,8 @@ component of each pixel in one 16 or 32 bit word. | |||
| 126 | - Y'\ :sub:`0` | 130 | - Y'\ :sub:`0` |
| 127 | - Cb\ :sub:`4` | 131 | - Cb\ :sub:`4` |
| 128 | - Cb\ :sub:`3` | 132 | - Cb\ :sub:`3` |
| 129 | - | 133 | |
| 134 | - :cspan:`15` | ||
| 130 | * .. _V4L2-PIX-FMT-YUV565: | 135 | * .. _V4L2-PIX-FMT-YUV565: |
| 131 | 136 | ||
| 132 | - ``V4L2_PIX_FMT_YUV565`` | 137 | - ``V4L2_PIX_FMT_YUV565`` |
| @@ -149,7 +154,9 @@ component of each pixel in one 16 or 32 bit word. | |||
| 149 | - Cb\ :sub:`5` | 154 | - Cb\ :sub:`5` |
| 150 | - Cb\ :sub:`4` | 155 | - Cb\ :sub:`4` |
| 151 | - Cb\ :sub:`3` | 156 | - Cb\ :sub:`3` |
| 152 | - | 157 | |
| 158 | - :cspan:`15` | ||
| 159 | |||
| 153 | * .. _V4L2-PIX-FMT-YUV32: | 160 | * .. _V4L2-PIX-FMT-YUV32: |
| 154 | 161 | ||
| 155 | - ``V4L2_PIX_FMT_YUV32`` | 162 | - ``V4L2_PIX_FMT_YUV32`` |
| @@ -190,7 +197,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 190 | - Cr\ :sub:`2` | 197 | - Cr\ :sub:`2` |
| 191 | - Cr\ :sub:`1` | 198 | - Cr\ :sub:`1` |
| 192 | - Cr\ :sub:`0` | 199 | - Cr\ :sub:`0` |
| 193 | - | 200 | |
| 194 | * .. _V4L2-PIX-FMT-AYUV32: | 201 | * .. _V4L2-PIX-FMT-AYUV32: |
| 195 | 202 | ||
| 196 | - ``V4L2_PIX_FMT_AYUV32`` | 203 | - ``V4L2_PIX_FMT_AYUV32`` |
| @@ -231,7 +238,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 231 | - Cr\ :sub:`2` | 238 | - Cr\ :sub:`2` |
| 232 | - Cr\ :sub:`1` | 239 | - Cr\ :sub:`1` |
| 233 | - Cr\ :sub:`0` | 240 | - Cr\ :sub:`0` |
| 234 | - | 241 | |
| 235 | * .. _V4L2-PIX-FMT-XYUV32: | 242 | * .. _V4L2-PIX-FMT-XYUV32: |
| 236 | 243 | ||
| 237 | - ``V4L2_PIX_FMT_XYUV32`` | 244 | - ``V4L2_PIX_FMT_XYUV32`` |
| @@ -272,7 +279,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 272 | - Cr\ :sub:`2` | 279 | - Cr\ :sub:`2` |
| 273 | - Cr\ :sub:`1` | 280 | - Cr\ :sub:`1` |
| 274 | - Cr\ :sub:`0` | 281 | - Cr\ :sub:`0` |
| 275 | - | 282 | |
| 276 | * .. _V4L2-PIX-FMT-VUYA32: | 283 | * .. _V4L2-PIX-FMT-VUYA32: |
| 277 | 284 | ||
| 278 | - ``V4L2_PIX_FMT_VUYA32`` | 285 | - ``V4L2_PIX_FMT_VUYA32`` |
| @@ -313,7 +320,7 @@ component of each pixel in one 16 or 32 bit word. | |||
| 313 | - a\ :sub:`2` | 320 | - a\ :sub:`2` |
| 314 | - a\ :sub:`1` | 321 | - a\ :sub:`1` |
| 315 | - a\ :sub:`0` | 322 | - a\ :sub:`0` |
| 316 | - | 323 | |
| 317 | * .. _V4L2-PIX-FMT-VUYX32: | 324 | * .. _V4L2-PIX-FMT-VUYX32: |
| 318 | 325 | ||
| 319 | - ``V4L2_PIX_FMT_VUYX32`` | 326 | - ``V4L2_PIX_FMT_VUYX32`` |
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst index cdb70ac26126..fd32660a3766 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst | |||
| @@ -40,7 +40,7 @@ of a small V4L2_PIX_FMT_SBGGR10P image: | |||
| 40 | **Byte Order.** | 40 | **Byte Order.** |
| 41 | Each cell is one byte. | 41 | Each cell is one byte. |
| 42 | 42 | ||
| 43 | .. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{5.4cm}| | 43 | .. tabularcolumns:: |p{2.4cm}|p{1.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{6.4cm}| |
| 44 | 44 | ||
| 45 | .. flat-table:: | 45 | .. flat-table:: |
| 46 | :header-rows: 0 | 46 | :header-rows: 0 |
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst index 01413be12916..960851275f23 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst | |||
| @@ -18,6 +18,7 @@ V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGB | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 12-bit packed Bayer formats | 20 | 12-bit packed Bayer formats |
| 21 | --------------------------- | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | Description | 24 | Description |
| @@ -37,7 +38,7 @@ Below is an example of a small V4L2_PIX_FMT_SBGGR12P image: | |||
| 37 | **Byte Order.** | 38 | **Byte Order.** |
| 38 | Each cell is one byte. | 39 | Each cell is one byte. |
| 39 | 40 | ||
| 40 | .. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}| | 41 | .. tabularcolumns:: |p{2.2cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}|p{1.2cm}|p{1.2cm}|p{3.1cm}| |
| 41 | 42 | ||
| 42 | 43 | ||
| 43 | .. flat-table:: | 44 | .. flat-table:: |
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst index b583531c2853..1a988d7e7ff8 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb14p.rst | |||
| @@ -41,17 +41,21 @@ of one of these formats: | |||
| 41 | **Byte Order.** | 41 | **Byte Order.** |
| 42 | Each cell is one byte. | 42 | Each cell is one byte. |
| 43 | 43 | ||
| 44 | .. raw:: latex | ||
| 44 | 45 | ||
| 46 | \footnotesize | ||
| 47 | |||
| 48 | .. tabularcolumns:: |p{1.8cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.1cm}|p{3.3cm}|p{3.3cm}|p{3.3cm}| | ||
| 45 | 49 | ||
| 46 | .. flat-table:: | 50 | .. flat-table:: |
| 47 | :header-rows: 0 | 51 | :header-rows: 0 |
| 48 | :stub-columns: 0 | 52 | :stub-columns: 0 |
| 49 | :widths: 2 1 1 1 1 1 1 1 | 53 | :widths: 2 1 1 1 1 3 3 3 |
| 50 | 54 | ||
| 51 | 55 | ||
| 52 | - .. row 1 | 56 | - .. row 1 |
| 53 | 57 | ||
| 54 | - start + 0: | 58 | - start + 0 |
| 55 | 59 | ||
| 56 | - B\ :sub:`00high` | 60 | - B\ :sub:`00high` |
| 57 | 61 | ||
| @@ -62,17 +66,20 @@ Each cell is one byte. | |||
| 62 | - G\ :sub:`03high` | 66 | - G\ :sub:`03high` |
| 63 | 67 | ||
| 64 | - G\ :sub:`01low bits 1--0`\ (bits 7--6) | 68 | - G\ :sub:`01low bits 1--0`\ (bits 7--6) |
| 69 | |||
| 65 | B\ :sub:`00low bits 5--0`\ (bits 5--0) | 70 | B\ :sub:`00low bits 5--0`\ (bits 5--0) |
| 66 | 71 | ||
| 67 | - R\ :sub:`02low bits 3--0`\ (bits 7--4) | 72 | - R\ :sub:`02low bits 3--0`\ (bits 7--4) |
| 73 | |||
| 68 | G\ :sub:`01low bits 5--2`\ (bits 3--0) | 74 | G\ :sub:`01low bits 5--2`\ (bits 3--0) |
| 69 | 75 | ||
| 70 | - G\ :sub:`03low bits 5--0`\ (bits 7--2) | 76 | - G\ :sub:`03low bits 5--0`\ (bits 7--2) |
| 77 | |||
| 71 | R\ :sub:`02low bits 5--4`\ (bits 1--0) | 78 | R\ :sub:`02low bits 5--4`\ (bits 1--0) |
| 72 | 79 | ||
| 73 | - .. row 2 | 80 | - .. row 2 |
| 74 | 81 | ||
| 75 | - start + 7: | 82 | - start + 7 |
| 76 | 83 | ||
| 77 | - G\ :sub:`00high` | 84 | - G\ :sub:`00high` |
| 78 | 85 | ||
| @@ -83,12 +90,15 @@ Each cell is one byte. | |||
| 83 | - R\ :sub:`03high` | 90 | - R\ :sub:`03high` |
| 84 | 91 | ||
| 85 | - R\ :sub:`01low bits 1--0`\ (bits 7--6) | 92 | - R\ :sub:`01low bits 1--0`\ (bits 7--6) |
| 93 | |||
| 86 | G\ :sub:`00low bits 5--0`\ (bits 5--0) | 94 | G\ :sub:`00low bits 5--0`\ (bits 5--0) |
| 87 | 95 | ||
| 88 | - G\ :sub:`02low bits 3--0`\ (bits 7--4) | 96 | - G\ :sub:`02low bits 3--0`\ (bits 7--4) |
| 97 | |||
| 89 | R\ :sub:`01low bits 5--2`\ (bits 3--0) | 98 | R\ :sub:`01low bits 5--2`\ (bits 3--0) |
| 90 | 99 | ||
| 91 | - R\ :sub:`03low bits 5--0`\ (bits 7--2) | 100 | - R\ :sub:`03low bits 5--0`\ (bits 7--2) |
| 101 | |||
| 92 | G\ :sub:`02low bits 5--4`\ (bits 1--0) | 102 | G\ :sub:`02low bits 5--4`\ (bits 1--0) |
| 93 | 103 | ||
| 94 | - .. row 3 | 104 | - .. row 3 |
| @@ -104,12 +114,15 @@ Each cell is one byte. | |||
| 104 | - G\ :sub:`23high` | 114 | - G\ :sub:`23high` |
| 105 | 115 | ||
| 106 | - G\ :sub:`21low bits 1--0`\ (bits 7--6) | 116 | - G\ :sub:`21low bits 1--0`\ (bits 7--6) |
| 117 | |||
| 107 | B\ :sub:`20low bits 5--0`\ (bits 5--0) | 118 | B\ :sub:`20low bits 5--0`\ (bits 5--0) |
| 108 | 119 | ||
| 109 | - R\ :sub:`22low bits 3--0`\ (bits 7--4) | 120 | - R\ :sub:`22low bits 3--0`\ (bits 7--4) |
| 121 | |||
| 110 | G\ :sub:`21low bits 5--2`\ (bits 3--0) | 122 | G\ :sub:`21low bits 5--2`\ (bits 3--0) |
| 111 | 123 | ||
| 112 | - G\ :sub:`23low bits 5--0`\ (bits 7--2) | 124 | - G\ :sub:`23low bits 5--0`\ (bits 7--2) |
| 125 | |||
| 113 | R\ :sub:`22low bits 5--4`\ (bits 1--0) | 126 | R\ :sub:`22low bits 5--4`\ (bits 1--0) |
| 114 | 127 | ||
| 115 | - .. row 4 | 128 | - .. row 4 |
| @@ -132,3 +145,8 @@ Each cell is one byte. | |||
| 132 | 145 | ||
| 133 | - R\ :sub:`33low bits 5--0`\ (bits 7--2) | 146 | - R\ :sub:`33low bits 5--0`\ (bits 7--2) |
| 134 | G\ :sub:`32low bits 5--4`\ (bits 1--0) | 147 | G\ :sub:`32low bits 5--4`\ (bits 1--0) |
| 148 | |||
| 149 | .. raw:: latex | ||
| 150 | |||
| 151 | \normalsize | ||
| 152 | |||
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst index 7f82dad9013a..5688c816e334 100644 --- a/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst +++ b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst | |||
| @@ -19,6 +19,7 @@ array of struct :c:type:`v4l2_plane_pix_format` structures, | |||
| 19 | describing all planes of that format. | 19 | describing all planes of that format. |
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | |||
| 22 | .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| | 23 | .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| |
| 23 | 24 | ||
| 24 | .. c:type:: v4l2_plane_pix_format | 25 | .. c:type:: v4l2_plane_pix_format |
| @@ -41,6 +42,10 @@ describing all planes of that format. | |||
| 41 | applications. | 42 | applications. |
| 42 | 43 | ||
| 43 | 44 | ||
| 45 | .. raw:: latex | ||
| 46 | |||
| 47 | \small | ||
| 48 | |||
| 44 | .. tabularcolumns:: |p{4.4cm}|p{5.6cm}|p{7.5cm}| | 49 | .. tabularcolumns:: |p{4.4cm}|p{5.6cm}|p{7.5cm}| |
| 45 | 50 | ||
| 46 | .. c:type:: v4l2_pix_format_mplane | 51 | .. c:type:: v4l2_pix_format_mplane |
| @@ -82,9 +87,7 @@ describing all planes of that format. | |||
| 82 | * - __u8 | 87 | * - __u8 |
| 83 | - ``flags`` | 88 | - ``flags`` |
| 84 | - Flags set by the application or driver, see :ref:`format-flags`. | 89 | - Flags set by the application or driver, see :ref:`format-flags`. |
| 85 | * - union { | 90 | * - :cspan:`2` union { (anonymous) |
| 86 | - (anonymous) | ||
| 87 | - | ||
| 88 | * - __u8 | 91 | * - __u8 |
| 89 | - ``ycbcr_enc`` | 92 | - ``ycbcr_enc`` |
| 90 | - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. | 93 | - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. |
| @@ -97,9 +100,7 @@ describing all planes of that format. | |||
| 97 | This information supplements the ``colorspace`` and must be set by | 100 | This information supplements the ``colorspace`` and must be set by |
| 98 | the driver for capture streams and by the application for output | 101 | the driver for capture streams and by the application for output |
| 99 | streams, see :ref:`colorspaces`. | 102 | streams, see :ref:`colorspaces`. |
| 100 | * - } | 103 | * - :cspan:`2` } |
| 101 | - | ||
| 102 | - | ||
| 103 | * - __u8 | 104 | * - __u8 |
| 104 | - ``quantization`` | 105 | - ``quantization`` |
| 105 | - Quantization range, from enum :c:type:`v4l2_quantization`. | 106 | - Quantization range, from enum :c:type:`v4l2_quantization`. |
| @@ -116,3 +117,7 @@ describing all planes of that format. | |||
| 116 | - ``reserved[7]`` | 117 | - ``reserved[7]`` |
| 117 | - Reserved for future extensions. Should be zeroed by drivers and | 118 | - Reserved for future extensions. Should be zeroed by drivers and |
| 118 | applications. | 119 | applications. |
| 120 | |||
| 121 | .. raw:: latex | ||
| 122 | |||
| 123 | \normalsize | ||
diff --git a/Documentation/media/uapi/v4l/pixfmt-y10p.rst b/Documentation/media/uapi/v4l/pixfmt-y10p.rst index 7893642faee3..39cd789dcb59 100644 --- a/Documentation/media/uapi/v4l/pixfmt-y10p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-y10p.rst | |||
| @@ -27,6 +27,12 @@ in the same order. | |||
| 27 | 27 | ||
| 28 | **Bit-packed representation.** | 28 | **Bit-packed representation.** |
| 29 | 29 | ||
| 30 | .. raw:: latex | ||
| 31 | |||
| 32 | \small | ||
| 33 | |||
| 34 | .. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}| | ||
| 35 | |||
| 30 | .. flat-table:: | 36 | .. flat-table:: |
| 31 | :header-rows: 0 | 37 | :header-rows: 0 |
| 32 | :stub-columns: 0 | 38 | :stub-columns: 0 |
| @@ -38,3 +44,7 @@ in the same order. | |||
| 38 | - Y'\ :sub:`03[9:2]` | 44 | - Y'\ :sub:`03[9:2]` |
| 39 | - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4) | 45 | - Y'\ :sub:`03[1:0]`\ (bits 7--6) Y'\ :sub:`02[1:0]`\ (bits 5--4) |
| 40 | Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0) | 46 | Y'\ :sub:`01[1:0]`\ (bits 3--2) Y'\ :sub:`00[1:0]`\ (bits 1--0) |
| 47 | |||
| 48 | .. raw:: latex | ||
| 49 | |||
| 50 | \normalsize | ||
diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index f5440d55d510..ab1a48a5ae80 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst | |||
| @@ -980,6 +980,113 @@ The following tables list existing packed RGB formats. | |||
| 980 | - r\ :sub:`2` | 980 | - r\ :sub:`2` |
| 981 | - r\ :sub:`1` | 981 | - r\ :sub:`1` |
| 982 | - r\ :sub:`0` | 982 | - r\ :sub:`0` |
| 983 | * .. _MEDIA-BUS-FMT-BGR888-3X8: | ||
| 984 | |||
| 985 | - MEDIA_BUS_FMT_BGR888_3X8 | ||
| 986 | - 0x101b | ||
| 987 | - | ||
| 988 | - | ||
| 989 | - | ||
| 990 | - | ||
| 991 | - | ||
| 992 | - | ||
| 993 | - | ||
| 994 | - | ||
| 995 | - | ||
| 996 | - | ||
| 997 | - | ||
| 998 | - | ||
| 999 | - | ||
| 1000 | - | ||
| 1001 | - | ||
| 1002 | - | ||
| 1003 | - | ||
| 1004 | - | ||
| 1005 | - | ||
| 1006 | - | ||
| 1007 | - | ||
| 1008 | - | ||
| 1009 | - | ||
| 1010 | - | ||
| 1011 | - | ||
| 1012 | - b\ :sub:`7` | ||
| 1013 | - b\ :sub:`6` | ||
| 1014 | - b\ :sub:`5` | ||
| 1015 | - b\ :sub:`4` | ||
| 1016 | - b\ :sub:`3` | ||
| 1017 | - b\ :sub:`2` | ||
| 1018 | - b\ :sub:`1` | ||
| 1019 | - b\ :sub:`0` | ||
| 1020 | * - | ||
| 1021 | - | ||
| 1022 | - | ||
| 1023 | - | ||
| 1024 | - | ||
| 1025 | - | ||
| 1026 | - | ||
| 1027 | - | ||
| 1028 | - | ||
| 1029 | - | ||
| 1030 | - | ||
| 1031 | - | ||
| 1032 | - | ||
| 1033 | - | ||
| 1034 | - | ||
| 1035 | - | ||
| 1036 | - | ||
| 1037 | - | ||
| 1038 | - | ||
| 1039 | - | ||
| 1040 | - | ||
| 1041 | - | ||
| 1042 | - | ||
| 1043 | - | ||
| 1044 | - | ||
| 1045 | - | ||
| 1046 | - | ||
| 1047 | - g\ :sub:`7` | ||
| 1048 | - g\ :sub:`6` | ||
| 1049 | - g\ :sub:`5` | ||
| 1050 | - g\ :sub:`4` | ||
| 1051 | - g\ :sub:`3` | ||
| 1052 | - g\ :sub:`2` | ||
| 1053 | - g\ :sub:`1` | ||
| 1054 | - g\ :sub:`0` | ||
| 1055 | * - | ||
| 1056 | - | ||
| 1057 | - | ||
| 1058 | - | ||
| 1059 | - | ||
| 1060 | - | ||
| 1061 | - | ||
| 1062 | - | ||
| 1063 | - | ||
| 1064 | - | ||
| 1065 | - | ||
| 1066 | - | ||
| 1067 | - | ||
| 1068 | - | ||
| 1069 | - | ||
| 1070 | - | ||
| 1071 | - | ||
| 1072 | - | ||
| 1073 | - | ||
| 1074 | - | ||
| 1075 | - | ||
| 1076 | - | ||
| 1077 | - | ||
| 1078 | - | ||
| 1079 | - | ||
| 1080 | - | ||
| 1081 | - | ||
| 1082 | - r\ :sub:`7` | ||
| 1083 | - r\ :sub:`6` | ||
| 1084 | - r\ :sub:`5` | ||
| 1085 | - r\ :sub:`4` | ||
| 1086 | - r\ :sub:`3` | ||
| 1087 | - r\ :sub:`2` | ||
| 1088 | - r\ :sub:`1` | ||
| 1089 | - r\ :sub:`0` | ||
| 983 | * .. _MEDIA-BUS-FMT-GBR888-1X24: | 1090 | * .. _MEDIA-BUS-FMT-GBR888-1X24: |
| 984 | 1091 | ||
| 985 | - MEDIA_BUS_FMT_GBR888_1X24 | 1092 | - MEDIA_BUS_FMT_GBR888_1X24 |
| @@ -7414,7 +7521,7 @@ The following table lists existing HSV/HSL formats. | |||
| 7414 | \tiny | 7521 | \tiny |
| 7415 | \setlength{\tabcolsep}{2pt} | 7522 | \setlength{\tabcolsep}{2pt} |
| 7416 | 7523 | ||
| 7417 | .. tabularcolumns:: |p{3.0cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| | 7524 | .. tabularcolumns:: |p{3.9cm}|p{0.73cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| |
| 7418 | 7525 | ||
| 7419 | .. _v4l2-mbus-pixelcode-hsv: | 7526 | .. _v4l2-mbus-pixelcode-hsv: |
| 7420 | 7527 | ||
| @@ -7524,7 +7631,7 @@ The following table lists existing JPEG compressed formats. | |||
| 7524 | 7631 | ||
| 7525 | .. _v4l2-mbus-pixelcode-jpeg: | 7632 | .. _v4l2-mbus-pixelcode-jpeg: |
| 7526 | 7633 | ||
| 7527 | .. tabularcolumns:: |p{5.4cm}|p{1.4cm}|p{10.7cm}| | 7634 | .. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{10.1cm}| |
| 7528 | 7635 | ||
| 7529 | .. flat-table:: JPEG Formats | 7636 | .. flat-table:: JPEG Formats |
| 7530 | :header-rows: 1 | 7637 | :header-rows: 1 |
| @@ -7557,7 +7664,7 @@ formats. | |||
| 7557 | 7664 | ||
| 7558 | .. _v4l2-mbus-pixelcode-vendor-specific: | 7665 | .. _v4l2-mbus-pixelcode-vendor-specific: |
| 7559 | 7666 | ||
| 7560 | .. tabularcolumns:: |p{6.8cm}|p{1.4cm}|p{9.3cm}| | 7667 | .. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}| |
| 7561 | 7668 | ||
| 7562 | .. flat-table:: Vendor and device specific formats | 7669 | .. flat-table:: Vendor and device specific formats |
| 7563 | :header-rows: 1 | 7670 | :header-rows: 1 |
diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index c138d149faea..dbf7b445a27b 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst | |||
| @@ -111,7 +111,7 @@ in use. Setting it means that the buffer will not be passed to the driver | |||
| 111 | until the request itself is queued. Also, the driver will apply any | 111 | until the request itself is queued. Also, the driver will apply any |
| 112 | settings associated with the request for this buffer. This field will | 112 | settings associated with the request for this buffer. This field will |
| 113 | be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set. | 113 | be ignored unless the ``V4L2_BUF_FLAG_REQUEST_FD`` flag is set. |
| 114 | If the device does not support requests, then ``EACCES`` will be returned. | 114 | If the device does not support requests, then ``EBADR`` will be returned. |
| 115 | If requests are supported but an invalid request file descriptor is given, | 115 | If requests are supported but an invalid request file descriptor is given, |
| 116 | then ``EINVAL`` will be returned. | 116 | then ``EINVAL`` will be returned. |
| 117 | 117 | ||
| @@ -125,7 +125,7 @@ then ``EINVAL`` will be returned. | |||
| 125 | 125 | ||
| 126 | For :ref:`memory-to-memory devices <mem2mem>` you can specify the | 126 | For :ref:`memory-to-memory devices <mem2mem>` you can specify the |
| 127 | ``request_fd`` only for output buffers, not for capture buffers. Attempting | 127 | ``request_fd`` only for output buffers, not for capture buffers. Attempting |
| 128 | to specify this for a capture buffer will result in an ``EACCES`` error. | 128 | to specify this for a capture buffer will result in an ``EBADR`` error. |
| 129 | 129 | ||
| 130 | Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled | 130 | Applications call the ``VIDIOC_DQBUF`` ioctl to dequeue a filled |
| 131 | (capturing) or displayed (output) buffer from the driver's outgoing | 131 | (capturing) or displayed (output) buffer from the driver's outgoing |
| @@ -185,9 +185,11 @@ EPIPE | |||
| 185 | codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already | 185 | codecs if a buffer with the ``V4L2_BUF_FLAG_LAST`` was already |
| 186 | dequeued and no new buffers are expected to become available. | 186 | dequeued and no new buffers are expected to become available. |
| 187 | 187 | ||
| 188 | EACCES | 188 | EBADR |
| 189 | The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not | 189 | The ``V4L2_BUF_FLAG_REQUEST_FD`` flag was set but the device does not |
| 190 | support requests for the given buffer type. | 190 | support requests for the given buffer type, or |
| 191 | the ``V4L2_BUF_FLAG_REQUEST_FD`` flag was not set but the device requires | ||
| 192 | that the buffer is part of a request. | ||
| 191 | 193 | ||
| 192 | EBUSY | 194 | EBUSY |
| 193 | The first buffer was queued via a request, but the application now tries | 195 | The first buffer was queued via a request, but the application now tries |
diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index dfd4b205937c..33a055907258 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst | |||
| @@ -65,5 +65,4 @@ For more details see the file COPYING in the source distribution of Linux. | |||
| 65 | soc-camera | 65 | soc-camera |
| 66 | uvcvideo | 66 | uvcvideo |
| 67 | vivid | 67 | vivid |
| 68 | zoran | ||
| 69 | zr364xx | 68 | zr364xx |
diff --git a/Documentation/media/v4l-drivers/zoran.rst b/Documentation/media/v4l-drivers/zoran.rst deleted file mode 100644 index d2724a863d1d..000000000000 --- a/Documentation/media/v4l-drivers/zoran.rst +++ /dev/null | |||
| @@ -1,583 +0,0 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0 | ||
| 2 | |||
| 3 | The Zoran driver | ||
| 4 | ================ | ||
| 5 | |||
| 6 | unified zoran driver (zr360x7, zoran, buz, dc10(+), dc30(+), lml33) | ||
| 7 | |||
| 8 | website: http://mjpeg.sourceforge.net/driver-zoran/ | ||
| 9 | |||
| 10 | |||
| 11 | Frequently Asked Questions | ||
| 12 | -------------------------- | ||
| 13 | |||
| 14 | What cards are supported | ||
| 15 | ------------------------ | ||
| 16 | |||
| 17 | Iomega Buz, Linux Media Labs LML33/LML33R10, Pinnacle/Miro | ||
| 18 | DC10/DC10+/DC30/DC30+ and related boards (available under various names). | ||
| 19 | |||
| 20 | Iomega Buz | ||
| 21 | ~~~~~~~~~~ | ||
| 22 | |||
| 23 | * Zoran zr36067 PCI controller | ||
| 24 | * Zoran zr36060 MJPEG codec | ||
| 25 | * Philips saa7111 TV decoder | ||
| 26 | * Philips saa7185 TV encoder | ||
| 27 | |||
| 28 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 29 | videocodec, saa7111, saa7185, zr36060, zr36067 | ||
| 30 | |||
| 31 | Inputs/outputs: Composite and S-video | ||
| 32 | |||
| 33 | Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) | ||
| 34 | |||
| 35 | Card number: 7 | ||
| 36 | |||
| 37 | AverMedia 6 Eyes AVS6EYES | ||
| 38 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 39 | |||
| 40 | * Zoran zr36067 PCI controller | ||
| 41 | * Zoran zr36060 MJPEG codec | ||
| 42 | * Samsung ks0127 TV decoder | ||
| 43 | * Conexant bt866 TV encoder | ||
| 44 | |||
| 45 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 46 | videocodec, ks0127, bt866, zr36060, zr36067 | ||
| 47 | |||
| 48 | Inputs/outputs: | ||
| 49 | Six physical inputs. 1-6 are composite, | ||
| 50 | 1-2, 3-4, 5-6 doubles as S-video, | ||
| 51 | 1-3 triples as component. | ||
| 52 | One composite output. | ||
| 53 | |||
| 54 | Norms: PAL, SECAM (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) | ||
| 55 | |||
| 56 | Card number: 8 | ||
| 57 | |||
| 58 | .. note:: | ||
| 59 | |||
| 60 | Not autodetected, card=8 is necessary. | ||
| 61 | |||
| 62 | Linux Media Labs LML33 | ||
| 63 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
| 64 | |||
| 65 | * Zoran zr36067 PCI controller | ||
| 66 | * Zoran zr36060 MJPEG codec | ||
| 67 | * Brooktree bt819 TV decoder | ||
| 68 | * Brooktree bt856 TV encoder | ||
| 69 | |||
| 70 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 71 | videocodec, bt819, bt856, zr36060, zr36067 | ||
| 72 | |||
| 73 | Inputs/outputs: Composite and S-video | ||
| 74 | |||
| 75 | Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) | ||
| 76 | |||
| 77 | Card number: 5 | ||
| 78 | |||
| 79 | Linux Media Labs LML33R10 | ||
| 80 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 81 | |||
| 82 | * Zoran zr36067 PCI controller | ||
| 83 | * Zoran zr36060 MJPEG codec | ||
| 84 | * Philips saa7114 TV decoder | ||
| 85 | * Analog Devices adv7170 TV encoder | ||
| 86 | |||
| 87 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 88 | videocodec, saa7114, adv7170, zr36060, zr36067 | ||
| 89 | |||
| 90 | Inputs/outputs: Composite and S-video | ||
| 91 | |||
| 92 | Norms: PAL (720x576 @ 25 fps), NTSC (720x480 @ 29.97 fps) | ||
| 93 | |||
| 94 | Card number: 6 | ||
| 95 | |||
| 96 | Pinnacle/Miro DC10(new) | ||
| 97 | ~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 98 | |||
| 99 | * Zoran zr36057 PCI controller | ||
| 100 | * Zoran zr36060 MJPEG codec | ||
| 101 | * Philips saa7110a TV decoder | ||
| 102 | * Analog Devices adv7176 TV encoder | ||
| 103 | |||
| 104 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 105 | videocodec, saa7110, adv7175, zr36060, zr36067 | ||
| 106 | |||
| 107 | Inputs/outputs: Composite, S-video and Internal | ||
| 108 | |||
| 109 | Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) | ||
| 110 | |||
| 111 | Card number: 1 | ||
| 112 | |||
| 113 | Pinnacle/Miro DC10+ | ||
| 114 | ~~~~~~~~~~~~~~~~~~~ | ||
| 115 | |||
| 116 | * Zoran zr36067 PCI controller | ||
| 117 | * Zoran zr36060 MJPEG codec | ||
| 118 | * Philips saa7110a TV decoder | ||
| 119 | * Analog Devices adv7176 TV encoder | ||
| 120 | |||
| 121 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 122 | videocodec, sa7110, adv7175, zr36060, zr36067 | ||
| 123 | |||
| 124 | Inputs/outputs: Composite, S-video and Internal | ||
| 125 | |||
| 126 | Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) | ||
| 127 | |||
| 128 | Card number: 2 | ||
| 129 | |||
| 130 | Pinnacle/Miro DC10(old) | ||
| 131 | ~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 132 | |||
| 133 | * Zoran zr36057 PCI controller | ||
| 134 | * Zoran zr36050 MJPEG codec | ||
| 135 | * Zoran zr36016 Video Front End or Fuji md0211 Video Front End (clone?) | ||
| 136 | * Micronas vpx3220a TV decoder | ||
| 137 | * mse3000 TV encoder or Analog Devices adv7176 TV encoder | ||
| 138 | |||
| 139 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 140 | videocodec, vpx3220, mse3000/adv7175, zr36050, zr36016, zr36067 | ||
| 141 | |||
| 142 | Inputs/outputs: Composite, S-video and Internal | ||
| 143 | |||
| 144 | Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) | ||
| 145 | |||
| 146 | Card number: 0 | ||
| 147 | |||
| 148 | Pinnacle/Miro DC30 | ||
| 149 | ~~~~~~~~~~~~~~~~~~ | ||
| 150 | |||
| 151 | * Zoran zr36057 PCI controller | ||
| 152 | * Zoran zr36050 MJPEG codec | ||
| 153 | * Zoran zr36016 Video Front End | ||
| 154 | * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder | ||
| 155 | * Analog Devices adv7176 TV encoder | ||
| 156 | |||
| 157 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 158 | videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36016, zr36067 | ||
| 159 | |||
| 160 | Inputs/outputs: Composite, S-video and Internal | ||
| 161 | |||
| 162 | Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) | ||
| 163 | |||
| 164 | Card number: 3 | ||
| 165 | |||
| 166 | Pinnacle/Miro DC30+ | ||
| 167 | ~~~~~~~~~~~~~~~~~~~ | ||
| 168 | |||
| 169 | * Zoran zr36067 PCI controller | ||
| 170 | * Zoran zr36050 MJPEG codec | ||
| 171 | * Zoran zr36016 Video Front End | ||
| 172 | * Micronas vpx3225d/vpx3220a/vpx3216b TV decoder | ||
| 173 | * Analog Devices adv7176 TV encoder | ||
| 174 | |||
| 175 | Drivers to use: videodev, i2c-core, i2c-algo-bit, | ||
| 176 | videocodec, vpx3220/vpx3224, adv7175, zr36050, zr36015, zr36067 | ||
| 177 | |||
| 178 | Inputs/outputs: Composite, S-video and Internal | ||
| 179 | |||
| 180 | Norms: PAL, SECAM (768x576 @ 25 fps), NTSC (640x480 @ 29.97 fps) | ||
| 181 | |||
| 182 | Card number: 4 | ||
| 183 | |||
| 184 | .. note:: | ||
| 185 | |||
| 186 | #) No module for the mse3000 is available yet | ||
| 187 | #) No module for the vpx3224 is available yet | ||
| 188 | |||
| 189 | 1.1 What the TV decoder can do an what not | ||
| 190 | ------------------------------------------ | ||
| 191 | |||
| 192 | The best know TV standards are NTSC/PAL/SECAM. but for decoding a frame that | ||
| 193 | information is not enough. There are several formats of the TV standards. | ||
| 194 | And not every TV decoder is able to handle every format. Also the every | ||
| 195 | combination is supported by the driver. There are currently 11 different | ||
| 196 | tv broadcast formats all aver the world. | ||
| 197 | |||
| 198 | The CCIR defines parameters needed for broadcasting the signal. | ||
| 199 | The CCIR has defined different standards: A,B,D,E,F,G,D,H,I,K,K1,L,M,N,... | ||
| 200 | The CCIR says not much about the colorsystem used !!! | ||
| 201 | And talking about a colorsystem says not to much about how it is broadcast. | ||
| 202 | |||
| 203 | The CCIR standards A,E,F are not used any more. | ||
| 204 | |||
| 205 | When you speak about NTSC, you usually mean the standard: CCIR - M using | ||
| 206 | the NTSC colorsystem which is used in the USA, Japan, Mexico, Canada | ||
| 207 | and a few others. | ||
| 208 | |||
| 209 | When you talk about PAL, you usually mean: CCIR - B/G using the PAL | ||
| 210 | colorsystem which is used in many Countries. | ||
| 211 | |||
| 212 | When you talk about SECAM, you mean: CCIR - L using the SECAM Colorsystem | ||
| 213 | which is used in France, and a few others. | ||
| 214 | |||
| 215 | There the other version of SECAM, CCIR - D/K is used in Bulgaria, China, | ||
| 216 | Slovakai, Hungary, Korea (Rep.), Poland, Rumania and a others. | ||
| 217 | |||
| 218 | The CCIR - H uses the PAL colorsystem (sometimes SECAM) and is used in | ||
| 219 | Egypt, Libya, Sri Lanka, Syrain Arab. Rep. | ||
| 220 | |||
| 221 | The CCIR - I uses the PAL colorsystem, and is used in Great Britain, Hong Kong, | ||
| 222 | Ireland, Nigeria, South Africa. | ||
| 223 | |||
| 224 | The CCIR - N uses the PAL colorsystem and PAL frame size but the NTSC framerate, | ||
| 225 | and is used in Argentinia, Uruguay, an a few others | ||
| 226 | |||
| 227 | We do not talk about how the audio is broadcast ! | ||
| 228 | |||
| 229 | A rather good sites about the TV standards are: | ||
| 230 | http://www.sony.jp/support/ | ||
| 231 | http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/ | ||
| 232 | and http://www.cabl.com/restaurant/channel.html | ||
| 233 | |||
| 234 | Other weird things around: NTSC 4.43 is a modificated NTSC, which is mainly | ||
| 235 | used in PAL VCR's that are able to play back NTSC. PAL 60 seems to be the same | ||
| 236 | as NTSC 4.43 . The Datasheets also talk about NTSC 44, It seems as if it would | ||
| 237 | be the same as NTSC 4.43. | ||
| 238 | NTSC Combs seems to be a decoder mode where the decoder uses a comb filter | ||
| 239 | to split coma and luma instead of a Delay line. | ||
| 240 | |||
| 241 | But I did not defiantly find out what NTSC Comb is. | ||
| 242 | |||
| 243 | Philips saa7111 TV decoder | ||
| 244 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 245 | |||
| 246 | - was introduced in 1997, is used in the BUZ and | ||
| 247 | - can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC N, NTSC 4.43 and SECAM | ||
| 248 | |||
| 249 | Philips saa7110a TV decoder | ||
| 250 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 251 | |||
| 252 | - was introduced in 1995, is used in the Pinnacle/Miro DC10(new), DC10+ and | ||
| 253 | - can handle: PAL B/G, NTSC M and SECAM | ||
| 254 | |||
| 255 | Philips saa7114 TV decoder | ||
| 256 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 257 | |||
| 258 | - was introduced in 2000, is used in the LML33R10 and | ||
| 259 | - can handle: PAL B/G/D/H/I/N, PAL N, PAL M, NTSC M, NTSC 4.43 and SECAM | ||
| 260 | |||
| 261 | Brooktree bt819 TV decoder | ||
| 262 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 263 | |||
| 264 | - was introduced in 1996, and is used in the LML33 and | ||
| 265 | - can handle: PAL B/D/G/H/I, NTSC M | ||
| 266 | |||
| 267 | Micronas vpx3220a TV decoder | ||
| 268 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 269 | |||
| 270 | - was introduced in 1996, is used in the DC30 and DC30+ and | ||
| 271 | - can handle: PAL B/G/H/I, PAL N, PAL M, NTSC M, NTSC 44, PAL 60, SECAM,NTSC Comb | ||
| 272 | |||
| 273 | Samsung ks0127 TV decoder | ||
| 274 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 275 | |||
| 276 | - is used in the AVS6EYES card and | ||
| 277 | - can handle: NTSC-M/N/44, PAL-M/N/B/G/H/I/D/K/L and SECAM | ||
| 278 | |||
| 279 | |||
| 280 | What the TV encoder can do an what not | ||
| 281 | -------------------------------------- | ||
| 282 | |||
| 283 | The TV encoder are doing the "same" as the decoder, but in the oder direction. | ||
| 284 | You feed them digital data and the generate a Composite or SVHS signal. | ||
| 285 | For information about the colorsystems and TV norm take a look in the | ||
| 286 | TV decoder section. | ||
| 287 | |||
| 288 | Philips saa7185 TV Encoder | ||
| 289 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 290 | |||
| 291 | - was introduced in 1996, is used in the BUZ | ||
| 292 | - can generate: PAL B/G, NTSC M | ||
| 293 | |||
| 294 | Brooktree bt856 TV Encoder | ||
| 295 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 296 | |||
| 297 | - was introduced in 1994, is used in the LML33 | ||
| 298 | - can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL-N (Argentina) | ||
| 299 | |||
| 300 | Analog Devices adv7170 TV Encoder | ||
| 301 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 302 | |||
| 303 | - was introduced in 2000, is used in the LML300R10 | ||
| 304 | - can generate: PAL B/D/G/H/I/N, PAL M, NTSC M, PAL 60 | ||
| 305 | |||
| 306 | Analog Devices adv7175 TV Encoder | ||
| 307 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 308 | |||
| 309 | - was introduced in 1996, is used in the DC10, DC10+, DC10 old, DC30, DC30+ | ||
| 310 | - can generate: PAL B/D/G/H/I/N, PAL M, NTSC M | ||
| 311 | |||
| 312 | ITT mse3000 TV encoder | ||
| 313 | ~~~~~~~~~~~~~~~~~~~~~~ | ||
| 314 | |||
| 315 | - was introduced in 1991, is used in the DC10 old | ||
| 316 | - can generate: PAL , NTSC , SECAM | ||
| 317 | |||
| 318 | Conexant bt866 TV encoder | ||
| 319 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 320 | |||
| 321 | - is used in AVS6EYES, and | ||
| 322 | - can generate: NTSC/PAL, PALÂM, PALÂN | ||
| 323 | |||
| 324 | The adv717x, should be able to produce PAL N. But you find nothing PAL N | ||
| 325 | specific in the registers. Seem that you have to reuse a other standard | ||
| 326 | to generate PAL N, maybe it would work if you use the PAL M settings. | ||
| 327 | |||
| 328 | How do I get this damn thing to work | ||
| 329 | ------------------------------------ | ||
| 330 | |||
| 331 | Load zr36067.o. If it can't autodetect your card, use the card=X insmod | ||
| 332 | option with X being the card number as given in the previous section. | ||
| 333 | To have more than one card, use card=X1[,X2[,X3,[X4[..]]]] | ||
| 334 | |||
| 335 | To automate this, add the following to your /etc/modprobe.d/zoran.conf: | ||
| 336 | |||
| 337 | options zr36067 card=X1[,X2[,X3[,X4[..]]]] | ||
| 338 | alias char-major-81-0 zr36067 | ||
| 339 | |||
| 340 | One thing to keep in mind is that this doesn't load zr36067.o itself yet. It | ||
| 341 | just automates loading. If you start using xawtv, the device won't load on | ||
| 342 | some systems, since you're trying to load modules as a user, which is not | ||
| 343 | allowed ("permission denied"). A quick workaround is to add 'Load "v4l"' to | ||
| 344 | XF86Config-4 when you use X by default, or to run 'v4l-conf -c <device>' in | ||
| 345 | one of your startup scripts (normally rc.local) if you don't use X. Both | ||
| 346 | make sure that the modules are loaded on startup, under the root account. | ||
| 347 | |||
| 348 | What mainboard should I use (or why doesn't my card work) | ||
| 349 | --------------------------------------------------------- | ||
| 350 | |||
| 351 | |||
| 352 | <insert lousy disclaimer here>. In short: good=SiS/Intel, bad=VIA. | ||
| 353 | |||
| 354 | Experience tells us that people with a Buz, on average, have more problems | ||
| 355 | than users with a DC10+/LML33. Also, it tells us that people owning a VIA- | ||
| 356 | based mainboard (ktXXX, MVP3) have more problems than users with a mainboard | ||
| 357 | based on a different chipset. Here's some notes from Andrew Stevens: | ||
| 358 | |||
| 359 | Here's my experience of using LML33 and Buz on various motherboards: | ||
| 360 | |||
| 361 | - VIA MVP3 | ||
| 362 | - Forget it. Pointless. Doesn't work. | ||
| 363 | - Intel 430FX (Pentium 200) | ||
| 364 | - LML33 perfect, Buz tolerable (3 or 4 frames dropped per movie) | ||
| 365 | - Intel 440BX (early stepping) | ||
| 366 | - LML33 tolerable. Buz starting to get annoying (6-10 frames/hour) | ||
| 367 | - Intel 440BX (late stepping) | ||
| 368 | - Buz tolerable, LML3 almost perfect (occasional single frame drops) | ||
| 369 | - SiS735 | ||
| 370 | - LML33 perfect, Buz tolerable. | ||
| 371 | - VIA KT133(*) | ||
| 372 | - LML33 starting to get annoying, Buz poor enough that I have up. | ||
| 373 | |||
| 374 | - Both 440BX boards were dual CPU versions. | ||
| 375 | |||
| 376 | Bernhard Praschinger later added: | ||
| 377 | |||
| 378 | - AMD 751 | ||
| 379 | - Buz perfect-tolerable | ||
| 380 | - AMD 760 | ||
| 381 | - Buz perfect-tolerable | ||
| 382 | |||
| 383 | In general, people on the user mailinglist won't give you much of a chance | ||
| 384 | if you have a VIA-based motherboard. They may be cheap, but sometimes, you'd | ||
| 385 | rather want to spend some more money on better boards. In general, VIA | ||
| 386 | mainboard's IDE/PCI performance will also suck badly compared to others. | ||
| 387 | You'll noticed the DC10+/DC30+ aren't mentioned anywhere in the overview. | ||
| 388 | Basically, you can assume that if the Buz works, the LML33 will work too. If | ||
| 389 | the LML33 works, the DC10+/DC30+ will work too. They're most tolerant to | ||
| 390 | different mainboard chipsets from all of the supported cards. | ||
| 391 | |||
| 392 | If you experience timeouts during capture, buy a better mainboard or lower | ||
| 393 | the quality/buffersize during capture (see 'Concerning buffer sizes, quality, | ||
| 394 | output size etc.'). If it hangs, there's little we can do as of now. Check | ||
| 395 | your IRQs and make sure the card has its own interrupts. | ||
| 396 | |||
| 397 | Programming interface | ||
| 398 | --------------------- | ||
| 399 | |||
| 400 | This driver conforms to video4linux2. Support for V4L1 and for the custom | ||
| 401 | zoran ioctls has been removed in kernel 2.6.38. | ||
| 402 | |||
| 403 | For programming example, please, look at lavrec.c and lavplay.c code in | ||
| 404 | the MJPEG-tools (http://mjpeg.sf.net/). | ||
| 405 | |||
| 406 | Additional notes for software developers: | ||
| 407 | |||
| 408 | The driver returns maxwidth and maxheight parameters according to | ||
| 409 | the current TV standard (norm). Therefore, the software which | ||
| 410 | communicates with the driver and "asks" for these parameters should | ||
| 411 | first set the correct norm. Well, it seems logically correct: TV | ||
| 412 | standard is "more constant" for current country than geometry | ||
| 413 | settings of a variety of TV capture cards which may work in ITU or | ||
| 414 | square pixel format. | ||
| 415 | |||
| 416 | Applications | ||
| 417 | ------------ | ||
| 418 | |||
| 419 | Applications known to work with this driver: | ||
| 420 | |||
| 421 | TV viewing: | ||
| 422 | |||
| 423 | * xawtv | ||
| 424 | * kwintv | ||
| 425 | * probably any TV application that supports video4linux or video4linux2. | ||
| 426 | |||
| 427 | MJPEG capture/playback: | ||
| 428 | |||
| 429 | * mjpegtools/lavtools (or Linux Video Studio) | ||
| 430 | * gstreamer | ||
| 431 | * mplayer | ||
| 432 | |||
| 433 | General raw capture: | ||
| 434 | |||
| 435 | * xawtv | ||
| 436 | * gstreamer | ||
| 437 | * probably any application that supports video4linux or video4linux2 | ||
| 438 | |||
| 439 | Video editing: | ||
| 440 | |||
| 441 | * Cinelerra | ||
| 442 | * MainActor | ||
| 443 | * mjpegtools (or Linux Video Studio) | ||
| 444 | |||
| 445 | |||
| 446 | Concerning buffer sizes, quality, output size etc. | ||
| 447 | -------------------------------------------------- | ||
| 448 | |||
| 449 | |||
| 450 | The zr36060 can do 1:2 JPEG compression. This is really the theoretical | ||
| 451 | maximum that the chipset can reach. The driver can, however, limit compression | ||
| 452 | to a maximum (size) of 1:4. The reason for this is that some cards (e.g. Buz) | ||
| 453 | can't handle 1:2 compression without stopping capture after only a few minutes. | ||
| 454 | With 1:4, it'll mostly work. If you have a Buz, use 'low_bitrate=1' to go into | ||
| 455 | 1:4 max. compression mode. | ||
| 456 | |||
| 457 | 100% JPEG quality is thus 1:2 compression in practice. So for a full PAL frame | ||
| 458 | (size 720x576). The JPEG fields are stored in YUY2 format, so the size of the | ||
| 459 | fields are 720x288x16/2 bits/field (2 fields/frame) = 207360 bytes/field x 2 = | ||
| 460 | 414720 bytes/frame (add some more bytes for headers and DHT (huffman)/DQT | ||
| 461 | (quantization) tables, and you'll get to something like 512kB per frame for | ||
| 462 | 1:2 compression. For 1:4 compression, you'd have frames of half this size. | ||
| 463 | |||
| 464 | Some additional explanation by Martin Samuelsson, which also explains the | ||
| 465 | importance of buffer sizes: | ||
| 466 | -- | ||
| 467 | > Hmm, I do not think it is really that way. With the current (downloaded | ||
| 468 | > at 18:00 Monday) driver I get that output sizes for 10 sec: | ||
| 469 | > -q 50 -b 128 : 24.283.332 Bytes | ||
| 470 | > -q 50 -b 256 : 48.442.368 | ||
| 471 | > -q 25 -b 128 : 24.655.992 | ||
| 472 | > -q 25 -b 256 : 25.859.820 | ||
| 473 | |||
| 474 | I woke up, and can't go to sleep again. I'll kill some time explaining why | ||
| 475 | this doesn't look strange to me. | ||
| 476 | |||
| 477 | Let's do some math using a width of 704 pixels. I'm not sure whether the Buz | ||
| 478 | actually use that number or not, but that's not too important right now. | ||
| 479 | |||
| 480 | 704x288 pixels, one field, is 202752 pixels. Divided by 64 pixels per block; | ||
| 481 | 3168 blocks per field. Each pixel consist of two bytes; 128 bytes per block; | ||
| 482 | 1024 bits per block. 100% in the new driver mean 1:2 compression; the maximum | ||
| 483 | output becomes 512 bits per block. Actually 510, but 512 is simpler to use | ||
| 484 | for calculations. | ||
| 485 | |||
| 486 | Let's say that we specify d1q50. We thus want 256 bits per block; times 3168 | ||
| 487 | becomes 811008 bits; 101376 bytes per field. We're talking raw bits and bytes | ||
| 488 | here, so we don't need to do any fancy corrections for bits-per-pixel or such | ||
| 489 | things. 101376 bytes per field. | ||
| 490 | |||
| 491 | d1 video contains two fields per frame. Those sum up to 202752 bytes per | ||
| 492 | frame, and one of those frames goes into each buffer. | ||
| 493 | |||
| 494 | But wait a second! -b128 gives 128kB buffers! It's not possible to cram | ||
| 495 | 202752 bytes of JPEG data into 128kB! | ||
| 496 | |||
| 497 | This is what the driver notice and automatically compensate for in your | ||
| 498 | examples. Let's do some math using this information: | ||
| 499 | |||
| 500 | 128kB is 131072 bytes. In this buffer, we want to store two fields, which | ||
| 501 | leaves 65536 bytes for each field. Using 3168 blocks per field, we get | ||
| 502 | 20.68686868... available bytes per block; 165 bits. We can't allow the | ||
| 503 | request for 256 bits per block when there's only 165 bits available! The -q50 | ||
| 504 | option is silently overridden, and the -b128 option takes precedence, leaving | ||
| 505 | us with the equivalence of -q32. | ||
| 506 | |||
| 507 | This gives us a data rate of 165 bits per block, which, times 3168, sums up | ||
| 508 | to 65340 bytes per field, out of the allowed 65536. The current driver has | ||
| 509 | another level of rate limiting; it won't accept -q values that fill more than | ||
| 510 | 6/8 of the specified buffers. (I'm not sure why. "Playing it safe" seem to be | ||
| 511 | a safe bet. Personally, I think I would have lowered requested-bits-per-block | ||
| 512 | by one, or something like that.) We can't use 165 bits per block, but have to | ||
| 513 | lower it again, to 6/8 of the available buffer space: We end up with 124 bits | ||
| 514 | per block, the equivalence of -q24. With 128kB buffers, you can't use greater | ||
| 515 | than -q24 at -d1. (And PAL, and 704 pixels width...) | ||
| 516 | |||
| 517 | The third example is limited to -q24 through the same process. The second | ||
| 518 | example, using very similar calculations, is limited to -q48. The only | ||
| 519 | example that actually grab at the specified -q value is the last one, which | ||
| 520 | is clearly visible, looking at the file size. | ||
| 521 | -- | ||
| 522 | |||
| 523 | Conclusion: the quality of the resulting movie depends on buffer size, quality, | ||
| 524 | whether or not you use 'low_bitrate=1' as insmod option for the zr36060.c | ||
| 525 | module to do 1:4 instead of 1:2 compression, etc. | ||
| 526 | |||
| 527 | If you experience timeouts, lowering the quality/buffersize or using | ||
| 528 | 'low_bitrate=1 as insmod option for zr36060.o might actually help, as is | ||
| 529 | proven by the Buz. | ||
| 530 | |||
| 531 | It hangs/crashes/fails/whatevers! Help! | ||
| 532 | --------------------------------------- | ||
| 533 | |||
| 534 | Make sure that the card has its own interrupts (see /proc/interrupts), check | ||
| 535 | the output of dmesg at high verbosity (load zr36067.o with debug=2, | ||
| 536 | load all other modules with debug=1). Check that your mainboard is favorable | ||
| 537 | (see question 2) and if not, test the card in another computer. Also see the | ||
| 538 | notes given in question 3 and try lowering quality/buffersize/capturesize | ||
| 539 | if recording fails after a period of time. | ||
| 540 | |||
| 541 | If all this doesn't help, give a clear description of the problem including | ||
| 542 | detailed hardware information (memory+brand, mainboard+chipset+brand, which | ||
| 543 | MJPEG card, processor, other PCI cards that might be of interest), give the | ||
| 544 | system PnP information (/proc/interrupts, /proc/dma, /proc/devices), and give | ||
| 545 | the kernel version, driver version, glibc version, gcc version and any other | ||
| 546 | information that might possibly be of interest. Also provide the dmesg output | ||
| 547 | at high verbosity. See 'Contacting' on how to contact the developers. | ||
| 548 | |||
| 549 | Maintainers/Contacting | ||
| 550 | ---------------------- | ||
| 551 | |||
| 552 | The driver is currently maintained by Laurent Pinchart and Ronald Bultje | ||
| 553 | (<laurent.pinchart@skynet.be> and <rbultje@ronald.bitfreak.net>). For bug | ||
| 554 | reports or questions, please contact the mailinglist instead of the developers | ||
| 555 | individually. For user questions (i.e. bug reports or how-to questions), send | ||
| 556 | an email to <mjpeg-users@lists.sf.net>, for developers (i.e. if you want to | ||
| 557 | help programming), send an email to <mjpeg-developer@lists.sf.net>. See | ||
| 558 | http://www.sf.net/projects/mjpeg/ for subscription information. | ||
| 559 | |||
| 560 | For bug reports, be sure to include all the information as described in | ||
| 561 | the section 'It hangs/crashes/fails/whatevers! Help!'. Please make sure | ||
| 562 | you're using the latest version (http://mjpeg.sf.net/driver-zoran/). | ||
| 563 | |||
| 564 | Previous maintainers/developers of this driver include Serguei Miridonov | ||
| 565 | <mirsev@cicese.mx>, Wolfgang Scherr <scherr@net4you.net>, Dave Perks | ||
| 566 | <dperks@ibm.net> and Rainer Johanni <Rainer@Johanni.de>. | ||
| 567 | |||
| 568 | Driver's License | ||
| 569 | ---------------- | ||
| 570 | |||
| 571 | This driver is distributed under the terms of the General Public License. | ||
| 572 | |||
| 573 | This program is free software; you can redistribute it and/or modify | ||
| 574 | it under the terms of the GNU General Public License as published by | ||
| 575 | the Free Software Foundation; either version 2 of the License, or | ||
| 576 | (at your option) any later version. | ||
| 577 | |||
| 578 | This program is distributed in the hope that it will be useful, | ||
| 579 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 580 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 581 | GNU General Public License for more details. | ||
| 582 | |||
| 583 | See http://www.gnu.org/ for more information. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index d58d215a7c9b..e897d9521000 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -10090,6 +10090,7 @@ L: linux-amlogic@lists.infradead.org | |||
| 10090 | W: http://linux-meson.com/ | 10090 | W: http://linux-meson.com/ |
| 10091 | S: Supported | 10091 | S: Supported |
| 10092 | F: drivers/media/platform/meson/ao-cec.c | 10092 | F: drivers/media/platform/meson/ao-cec.c |
| 10093 | F: drivers/media/platform/meson/ao-cec-g12a.c | ||
| 10093 | F: Documentation/devicetree/bindings/media/meson-ao-cec.txt | 10094 | F: Documentation/devicetree/bindings/media/meson-ao-cec.txt |
| 10094 | T: git git://linuxtv.org/media_tree.git | 10095 | T: git git://linuxtv.org/media_tree.git |
| 10095 | 10096 | ||
| @@ -14401,9 +14402,8 @@ SOC-CAMERA V4L2 SUBSYSTEM | |||
| 14401 | L: linux-media@vger.kernel.org | 14402 | L: linux-media@vger.kernel.org |
| 14402 | T: git git://linuxtv.org/media_tree.git | 14403 | T: git git://linuxtv.org/media_tree.git |
| 14403 | S: Orphan | 14404 | S: Orphan |
| 14404 | F: include/media/soc* | 14405 | F: include/media/soc_camera.h |
| 14405 | F: drivers/media/i2c/soc_camera/ | 14406 | F: drivers/staging/media/soc_camera/ |
| 14406 | F: drivers/media/platform/soc_camera/ | ||
| 14407 | 14407 | ||
| 14408 | SOCIONEXT SYNQUACER I2C DRIVER | 14408 | SOCIONEXT SYNQUACER I2C DRIVER |
| 14409 | M: Ard Biesheuvel <ard.biesheuvel@linaro.org> | 14409 | M: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| @@ -14743,6 +14743,14 @@ S: Maintained | |||
| 14743 | F: drivers/iio/imu/st_lsm6dsx/ | 14743 | F: drivers/iio/imu/st_lsm6dsx/ |
| 14744 | F: Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | 14744 | F: Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt |
| 14745 | 14745 | ||
| 14746 | ST MIPID02 CSI-2 TO PARALLEL BRIDGE DRIVER | ||
| 14747 | M: Mickael Guene <mickael.guene@st.com> | ||
| 14748 | L: linux-media@vger.kernel.org | ||
| 14749 | T: git git://linuxtv.org/media_tree.git | ||
| 14750 | S: Maintained | ||
| 14751 | F: drivers/media/i2c/st-mipid02.c | ||
| 14752 | F: Documentation/devicetree/bindings/media/i2c/st,st-mipid02.txt | ||
| 14753 | |||
| 14746 | ST STM32 I2C/SMBUS DRIVER | 14754 | ST STM32 I2C/SMBUS DRIVER |
| 14747 | M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> | 14755 | M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> |
| 14748 | L: linux-i2c@vger.kernel.org | 14756 | L: linux-i2c@vger.kernel.org |
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 102eb35fcf3f..8efaf99243e0 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
| @@ -31,14 +31,14 @@ comment "Multimedia core support" | |||
| 31 | # | 31 | # |
| 32 | config MEDIA_CAMERA_SUPPORT | 32 | config MEDIA_CAMERA_SUPPORT |
| 33 | bool "Cameras/video grabbers support" | 33 | bool "Cameras/video grabbers support" |
| 34 | ---help--- | 34 | help |
| 35 | Enable support for webcams and video grabbers. | 35 | Enable support for webcams and video grabbers. |
| 36 | 36 | ||
| 37 | Say Y when you have a webcam or a video capture grabber board. | 37 | Say Y when you have a webcam or a video capture grabber board. |
| 38 | 38 | ||
| 39 | config MEDIA_ANALOG_TV_SUPPORT | 39 | config MEDIA_ANALOG_TV_SUPPORT |
| 40 | bool "Analog TV support" | 40 | bool "Analog TV support" |
| 41 | ---help--- | 41 | help |
| 42 | Enable analog TV support. | 42 | Enable analog TV support. |
| 43 | 43 | ||
| 44 | Say Y when you have a TV board with analog support or with a | 44 | Say Y when you have a TV board with analog support or with a |
| @@ -50,7 +50,7 @@ config MEDIA_ANALOG_TV_SUPPORT | |||
| 50 | 50 | ||
| 51 | config MEDIA_DIGITAL_TV_SUPPORT | 51 | config MEDIA_DIGITAL_TV_SUPPORT |
| 52 | bool "Digital TV support" | 52 | bool "Digital TV support" |
| 53 | ---help--- | 53 | help |
| 54 | Enable digital TV support. | 54 | Enable digital TV support. |
| 55 | 55 | ||
| 56 | Say Y when you have a board with digital support or a board with | 56 | Say Y when you have a board with digital support or a board with |
| @@ -58,7 +58,7 @@ config MEDIA_DIGITAL_TV_SUPPORT | |||
| 58 | 58 | ||
| 59 | config MEDIA_RADIO_SUPPORT | 59 | config MEDIA_RADIO_SUPPORT |
| 60 | bool "AM/FM radio receivers/transmitters support" | 60 | bool "AM/FM radio receivers/transmitters support" |
| 61 | ---help--- | 61 | help |
| 62 | Enable AM/FM radio support. | 62 | Enable AM/FM radio support. |
| 63 | 63 | ||
| 64 | Additional info and docs are available on the web at | 64 | Additional info and docs are available on the web at |
| @@ -72,14 +72,14 @@ config MEDIA_RADIO_SUPPORT | |||
| 72 | 72 | ||
| 73 | config MEDIA_SDR_SUPPORT | 73 | config MEDIA_SDR_SUPPORT |
| 74 | bool "Software defined radio support" | 74 | bool "Software defined radio support" |
| 75 | ---help--- | 75 | help |
| 76 | Enable software defined radio support. | 76 | Enable software defined radio support. |
| 77 | 77 | ||
| 78 | Say Y when you have a software defined radio device. | 78 | Say Y when you have a software defined radio device. |
| 79 | 79 | ||
| 80 | config MEDIA_CEC_SUPPORT | 80 | config MEDIA_CEC_SUPPORT |
| 81 | bool "HDMI CEC support" | 81 | bool "HDMI CEC support" |
| 82 | ---help--- | 82 | help |
| 83 | Enable support for HDMI CEC (Consumer Electronics Control), | 83 | Enable support for HDMI CEC (Consumer Electronics Control), |
| 84 | which is an optional HDMI feature. | 84 | which is an optional HDMI feature. |
| 85 | 85 | ||
| @@ -96,7 +96,7 @@ source "drivers/media/cec/Kconfig" | |||
| 96 | config MEDIA_CONTROLLER | 96 | config MEDIA_CONTROLLER |
| 97 | bool "Media Controller API" | 97 | bool "Media Controller API" |
| 98 | depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT | 98 | depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT |
| 99 | ---help--- | 99 | help |
| 100 | Enable the media controller API used to query media devices internal | 100 | Enable the media controller API used to query media devices internal |
| 101 | topology and configure it dynamically. | 101 | topology and configure it dynamically. |
| 102 | 102 | ||
| @@ -105,7 +105,7 @@ config MEDIA_CONTROLLER | |||
| 105 | config MEDIA_CONTROLLER_DVB | 105 | config MEDIA_CONTROLLER_DVB |
| 106 | bool "Enable Media controller for DVB (EXPERIMENTAL)" | 106 | bool "Enable Media controller for DVB (EXPERIMENTAL)" |
| 107 | depends on MEDIA_CONTROLLER && DVB_CORE | 107 | depends on MEDIA_CONTROLLER && DVB_CORE |
| 108 | ---help--- | 108 | help |
| 109 | Enable the media controller API support for DVB. | 109 | Enable the media controller API support for DVB. |
| 110 | 110 | ||
| 111 | This is currently experimental. | 111 | This is currently experimental. |
| @@ -114,7 +114,7 @@ config MEDIA_CONTROLLER_REQUEST_API | |||
| 114 | bool "Enable Media controller Request API (EXPERIMENTAL)" | 114 | bool "Enable Media controller Request API (EXPERIMENTAL)" |
| 115 | depends on MEDIA_CONTROLLER && STAGING_MEDIA | 115 | depends on MEDIA_CONTROLLER && STAGING_MEDIA |
| 116 | default n | 116 | default n |
| 117 | ---help--- | 117 | help |
| 118 | DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING. | 118 | DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING. |
| 119 | 119 | ||
| 120 | This option enables the Request API for the Media controller and V4L2 | 120 | This option enables the Request API for the Media controller and V4L2 |
| @@ -137,7 +137,7 @@ config VIDEO_DEV | |||
| 137 | config VIDEO_V4L2_SUBDEV_API | 137 | config VIDEO_V4L2_SUBDEV_API |
| 138 | bool "V4L2 sub-device userspace API" | 138 | bool "V4L2 sub-device userspace API" |
| 139 | depends on VIDEO_DEV && MEDIA_CONTROLLER | 139 | depends on VIDEO_DEV && MEDIA_CONTROLLER |
| 140 | ---help--- | 140 | help |
| 141 | Enables the V4L2 sub-device pad-level userspace API used to configure | 141 | Enables the V4L2 sub-device pad-level userspace API used to configure |
| 142 | video format, size and frame rate between hardware blocks. | 142 | video format, size and frame rate between hardware blocks. |
| 143 | 143 | ||
diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 985d35ec6b29..4a330d0e5e40 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile | |||
| @@ -6,6 +6,12 @@ | |||
| 6 | media-objs := media-device.o media-devnode.o media-entity.o \ | 6 | media-objs := media-device.o media-devnode.o media-entity.o \ |
| 7 | media-request.o | 7 | media-request.o |
| 8 | 8 | ||
| 9 | ifeq ($(CONFIG_MEDIA_CONTROLLER),y) | ||
| 10 | ifeq ($(CONFIG_USB),y) | ||
| 11 | media-objs += media-dev-allocator.o | ||
| 12 | endif | ||
| 13 | endif | ||
| 14 | |||
| 9 | # | 15 | # |
| 10 | # I2C drivers should come before other drivers, otherwise they'll fail | 16 | # I2C drivers should come before other drivers, otherwise they'll fail |
| 11 | # when compiled as builtin drivers | 17 | # when compiled as builtin drivers |
diff --git a/drivers/media/cec/Kconfig b/drivers/media/cec/Kconfig index 9c2b108c613a..b5aadacf335a 100644 --- a/drivers/media/cec/Kconfig +++ b/drivers/media/cec/Kconfig | |||
| @@ -2,11 +2,11 @@ config MEDIA_CEC_RC | |||
| 2 | bool "HDMI CEC RC integration" | 2 | bool "HDMI CEC RC integration" |
| 3 | depends on CEC_CORE && RC_CORE | 3 | depends on CEC_CORE && RC_CORE |
| 4 | depends on CEC_CORE=m || RC_CORE=y | 4 | depends on CEC_CORE=m || RC_CORE=y |
| 5 | ---help--- | 5 | help |
| 6 | Pass on CEC remote control messages to the RC framework. | 6 | Pass on CEC remote control messages to the RC framework. |
| 7 | 7 | ||
| 8 | config CEC_PIN_ERROR_INJ | 8 | config CEC_PIN_ERROR_INJ |
| 9 | bool "Enable CEC error injection support" | 9 | bool "Enable CEC error injection support" |
| 10 | depends on CEC_PIN && DEBUG_FS | 10 | depends on CEC_PIN && DEBUG_FS |
| 11 | ---help--- | 11 | help |
| 12 | This option enables CEC error injection using debugfs. | 12 | This option enables CEC error injection using debugfs. |
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index cc875dabd765..f5d1578e256a 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c | |||
| @@ -126,6 +126,7 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode, | |||
| 126 | /* Part 2: Initialize and register the character device */ | 126 | /* Part 2: Initialize and register the character device */ |
| 127 | cdev_init(&devnode->cdev, &cec_devnode_fops); | 127 | cdev_init(&devnode->cdev, &cec_devnode_fops); |
| 128 | devnode->cdev.owner = owner; | 128 | devnode->cdev.owner = owner; |
| 129 | kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor); | ||
| 129 | 130 | ||
| 130 | ret = cdev_device_add(&devnode->cdev, &devnode->dev); | 131 | ret = cdev_device_add(&devnode->cdev, &devnode->dev); |
| 131 | if (ret) { | 132 | if (ret) { |
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c index dd2078b27a41..9598c7778871 100644 --- a/drivers/media/cec/cec-notifier.c +++ b/drivers/media/cec/cec-notifier.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
| 12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
| 13 | #include <linux/kref.h> | 13 | #include <linux/kref.h> |
| 14 | #include <linux/of_platform.h> | ||
| 14 | 15 | ||
| 15 | #include <media/cec.h> | 16 | #include <media/cec.h> |
| 16 | #include <media/cec-notifier.h> | 17 | #include <media/cec-notifier.h> |
| @@ -127,3 +128,32 @@ void cec_notifier_unregister(struct cec_notifier *n) | |||
| 127 | cec_notifier_put(n); | 128 | cec_notifier_put(n); |
| 128 | } | 129 | } |
| 129 | EXPORT_SYMBOL_GPL(cec_notifier_unregister); | 130 | EXPORT_SYMBOL_GPL(cec_notifier_unregister); |
| 131 | |||
| 132 | struct device *cec_notifier_parse_hdmi_phandle(struct device *dev) | ||
| 133 | { | ||
| 134 | struct platform_device *hdmi_pdev; | ||
| 135 | struct device *hdmi_dev = NULL; | ||
| 136 | struct device_node *np; | ||
| 137 | |||
| 138 | np = of_parse_phandle(dev->of_node, "hdmi-phandle", 0); | ||
| 139 | |||
| 140 | if (!np) { | ||
| 141 | dev_err(dev, "Failed to find HDMI node in device tree\n"); | ||
| 142 | return ERR_PTR(-ENODEV); | ||
| 143 | } | ||
| 144 | hdmi_pdev = of_find_device_by_node(np); | ||
| 145 | of_node_put(np); | ||
| 146 | if (hdmi_pdev) { | ||
| 147 | hdmi_dev = &hdmi_pdev->dev; | ||
| 148 | /* | ||
| 149 | * Note that the device struct is only used as a key into the | ||
| 150 | * cec_notifiers list, it is never actually accessed. | ||
| 151 | * So we decrement the reference here so we don't leak | ||
| 152 | * memory. | ||
| 153 | */ | ||
| 154 | put_device(hdmi_dev); | ||
| 155 | return hdmi_dev; | ||
| 156 | } | ||
| 157 | return ERR_PTR(-EPROBE_DEFER); | ||
| 158 | } | ||
| 159 | EXPORT_SYMBOL_GPL(cec_notifier_parse_hdmi_phandle); | ||
diff --git a/drivers/media/common/cx2341x.c b/drivers/media/common/cx2341x.c index 1dcc39b87bb7..121cda73ff88 100644 --- a/drivers/media/common/cx2341x.c +++ b/drivers/media/common/cx2341x.c | |||
| @@ -1028,7 +1028,7 @@ static int cx2341x_api(void *priv, cx2341x_mbox_func func, | |||
| 1028 | return func(priv, cmd, args, 0, data); | 1028 | return func(priv, cmd, args, 0, data); |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| 1031 | #define NEQ(field) (old->field != new->field) | 1031 | #define CMP_FIELD(__old, __new, __field) (__old->__field != __new->__field) |
| 1032 | 1032 | ||
| 1033 | int cx2341x_update(void *priv, cx2341x_mbox_func func, | 1033 | int cx2341x_update(void *priv, cx2341x_mbox_func func, |
| 1034 | const struct cx2341x_mpeg_params *old, | 1034 | const struct cx2341x_mpeg_params *old, |
| @@ -1042,20 +1042,22 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func, | |||
| 1042 | 11, /* VCD */ | 1042 | 11, /* VCD */ |
| 1043 | 12, /* SVCD */ | 1043 | 12, /* SVCD */ |
| 1044 | }; | 1044 | }; |
| 1045 | 1045 | int err; | |
| 1046 | int err = 0; | ||
| 1047 | int force = (old == NULL); | ||
| 1048 | u16 temporal = new->video_temporal_filter; | ||
| 1049 | 1046 | ||
| 1050 | cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0); | 1047 | cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0); |
| 1051 | 1048 | ||
| 1052 | if (force || NEQ(is_50hz)) { | 1049 | if (!old || |
| 1050 | CMP_FIELD(old, new, is_50hz)) { | ||
| 1053 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, | 1051 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, |
| 1054 | new->is_50hz); | 1052 | new->is_50hz); |
| 1055 | if (err) return err; | 1053 | if (err) |
| 1054 | return err; | ||
| 1056 | } | 1055 | } |
| 1057 | 1056 | ||
| 1058 | if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) { | 1057 | if (!old || |
| 1058 | CMP_FIELD(old, new, width) || | ||
| 1059 | CMP_FIELD(old, new, height) || | ||
| 1060 | CMP_FIELD(old, new, video_encoding)) { | ||
| 1059 | u16 w = new->width; | 1061 | u16 w = new->width; |
| 1060 | u16 h = new->height; | 1062 | u16 h = new->height; |
| 1061 | 1063 | ||
| @@ -1065,94 +1067,127 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func, | |||
| 1065 | } | 1067 | } |
| 1066 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, | 1068 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, |
| 1067 | h, w); | 1069 | h, w); |
| 1068 | if (err) return err; | 1070 | if (err) |
| 1071 | return err; | ||
| 1069 | } | 1072 | } |
| 1070 | if (force || NEQ(stream_type)) { | 1073 | if (!old || |
| 1074 | CMP_FIELD(old, new, stream_type)) { | ||
| 1071 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, | 1075 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, |
| 1072 | mpeg_stream_type[new->stream_type]); | 1076 | mpeg_stream_type[new->stream_type]); |
| 1073 | if (err) return err; | 1077 | if (err) |
| 1078 | return err; | ||
| 1074 | } | 1079 | } |
| 1075 | if (force || NEQ(video_aspect)) { | 1080 | if (!old || |
| 1081 | CMP_FIELD(old, new, video_aspect)) { | ||
| 1076 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, | 1082 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, |
| 1077 | 1 + new->video_aspect); | 1083 | 1 + new->video_aspect); |
| 1078 | if (err) return err; | 1084 | if (err) |
| 1085 | return err; | ||
| 1079 | } | 1086 | } |
| 1080 | if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) { | 1087 | if (!old || |
| 1088 | CMP_FIELD(old, new, video_b_frames) || | ||
| 1089 | CMP_FIELD(old, new, video_gop_size)) { | ||
| 1081 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2, | 1090 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2, |
| 1082 | new->video_gop_size, new->video_b_frames + 1); | 1091 | new->video_gop_size, new->video_b_frames + 1); |
| 1083 | if (err) return err; | 1092 | if (err) |
| 1093 | return err; | ||
| 1084 | } | 1094 | } |
| 1085 | if (force || NEQ(video_gop_closure)) { | 1095 | if (!old || |
| 1096 | CMP_FIELD(old, new, video_gop_closure)) { | ||
| 1086 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, | 1097 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, |
| 1087 | new->video_gop_closure); | 1098 | new->video_gop_closure); |
| 1088 | if (err) return err; | 1099 | if (err) |
| 1100 | return err; | ||
| 1089 | } | 1101 | } |
| 1090 | if (force || NEQ(audio_properties)) { | 1102 | if (!old || |
| 1103 | CMP_FIELD(old, new, audio_properties)) { | ||
| 1091 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, | 1104 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, |
| 1092 | 1, new->audio_properties); | 1105 | 1, new->audio_properties); |
| 1093 | if (err) return err; | 1106 | if (err) |
| 1107 | return err; | ||
| 1094 | } | 1108 | } |
| 1095 | if (force || NEQ(audio_mute)) { | 1109 | if (!old || |
| 1110 | CMP_FIELD(old, new, audio_mute)) { | ||
| 1096 | err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, | 1111 | err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, |
| 1097 | new->audio_mute); | 1112 | new->audio_mute); |
| 1098 | if (err) return err; | 1113 | if (err) |
| 1114 | return err; | ||
| 1099 | } | 1115 | } |
| 1100 | if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) || | 1116 | if (!old || |
| 1101 | NEQ(video_bitrate_peak)) { | 1117 | CMP_FIELD(old, new, video_bitrate_mode) || |
| 1118 | CMP_FIELD(old, new, video_bitrate) || | ||
| 1119 | CMP_FIELD(old, new, video_bitrate_peak)) { | ||
| 1102 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5, | 1120 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5, |
| 1103 | new->video_bitrate_mode, new->video_bitrate, | 1121 | new->video_bitrate_mode, new->video_bitrate, |
| 1104 | new->video_bitrate_peak / 400, 0, 0); | 1122 | new->video_bitrate_peak / 400, 0, 0); |
| 1105 | if (err) return err; | 1123 | if (err) |
| 1124 | return err; | ||
| 1106 | } | 1125 | } |
| 1107 | if (force || NEQ(video_spatial_filter_mode) || | 1126 | if (!old || |
| 1108 | NEQ(video_temporal_filter_mode) || | 1127 | CMP_FIELD(old, new, video_spatial_filter_mode) || |
| 1109 | NEQ(video_median_filter_type)) { | 1128 | CMP_FIELD(old, new, video_temporal_filter_mode) || |
| 1129 | CMP_FIELD(old, new, video_median_filter_type)) { | ||
| 1110 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, | 1130 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, |
| 1111 | 2, new->video_spatial_filter_mode | | 1131 | 2, |
| 1132 | new->video_spatial_filter_mode | | ||
| 1112 | (new->video_temporal_filter_mode << 1), | 1133 | (new->video_temporal_filter_mode << 1), |
| 1113 | new->video_median_filter_type); | 1134 | new->video_median_filter_type); |
| 1114 | if (err) return err; | 1135 | if (err) |
| 1136 | return err; | ||
| 1115 | } | 1137 | } |
| 1116 | if (force || NEQ(video_luma_median_filter_bottom) || | 1138 | if (!old || |
| 1117 | NEQ(video_luma_median_filter_top) || | 1139 | CMP_FIELD(old, new, video_luma_median_filter_bottom) || |
| 1118 | NEQ(video_chroma_median_filter_bottom) || | 1140 | CMP_FIELD(old, new, video_luma_median_filter_top) || |
| 1119 | NEQ(video_chroma_median_filter_top)) { | 1141 | CMP_FIELD(old, new, video_chroma_median_filter_bottom) || |
| 1142 | CMP_FIELD(old, new, video_chroma_median_filter_top)) { | ||
| 1120 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4, | 1143 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4, |
| 1121 | new->video_luma_median_filter_bottom, | 1144 | new->video_luma_median_filter_bottom, |
| 1122 | new->video_luma_median_filter_top, | 1145 | new->video_luma_median_filter_top, |
| 1123 | new->video_chroma_median_filter_bottom, | 1146 | new->video_chroma_median_filter_bottom, |
| 1124 | new->video_chroma_median_filter_top); | 1147 | new->video_chroma_median_filter_top); |
| 1125 | if (err) return err; | 1148 | if (err) |
| 1149 | return err; | ||
| 1126 | } | 1150 | } |
| 1127 | if (force || NEQ(video_luma_spatial_filter_type) || | 1151 | if (!old || |
| 1128 | NEQ(video_chroma_spatial_filter_type)) { | 1152 | CMP_FIELD(old, new, video_luma_spatial_filter_type) || |
| 1153 | CMP_FIELD(old, new, video_chroma_spatial_filter_type)) { | ||
| 1129 | err = cx2341x_api(priv, func, | 1154 | err = cx2341x_api(priv, func, |
| 1130 | CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, | 1155 | CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, |
| 1131 | 2, new->video_luma_spatial_filter_type, | 1156 | 2, new->video_luma_spatial_filter_type, |
| 1132 | new->video_chroma_spatial_filter_type); | 1157 | new->video_chroma_spatial_filter_type); |
| 1133 | if (err) return err; | 1158 | if (err) |
| 1159 | return err; | ||
| 1134 | } | 1160 | } |
| 1135 | if (force || NEQ(video_spatial_filter) || | 1161 | if (!old || |
| 1136 | old->video_temporal_filter != temporal) { | 1162 | CMP_FIELD(old, new, video_spatial_filter) || |
| 1163 | CMP_FIELD(old, new, video_temporal_filter)) { | ||
| 1137 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, | 1164 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, |
| 1138 | 2, new->video_spatial_filter, temporal); | 1165 | 2, new->video_spatial_filter, |
| 1139 | if (err) return err; | 1166 | new->video_temporal_filter); |
| 1167 | if (err) | ||
| 1168 | return err; | ||
| 1140 | } | 1169 | } |
| 1141 | if (force || NEQ(video_temporal_decimation)) { | 1170 | if (!old || |
| 1171 | CMP_FIELD(old, new, video_temporal_decimation)) { | ||
| 1142 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, | 1172 | err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, |
| 1143 | 1, new->video_temporal_decimation); | 1173 | 1, new->video_temporal_decimation); |
| 1144 | if (err) return err; | 1174 | if (err) |
| 1175 | return err; | ||
| 1145 | } | 1176 | } |
| 1146 | if (force || NEQ(video_mute) || | 1177 | if (!old || |
| 1147 | (new->video_mute && NEQ(video_mute_yuv))) { | 1178 | CMP_FIELD(old, new, video_mute) || |
| 1179 | (new->video_mute && CMP_FIELD(old, new, video_mute_yuv))) { | ||
| 1148 | err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, | 1180 | err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, |
| 1149 | new->video_mute | (new->video_mute_yuv << 8)); | 1181 | new->video_mute | (new->video_mute_yuv << 8)); |
| 1150 | if (err) return err; | 1182 | if (err) |
| 1183 | return err; | ||
| 1151 | } | 1184 | } |
| 1152 | if (force || NEQ(stream_insert_nav_packets)) { | 1185 | if (!old || |
| 1186 | CMP_FIELD(old, new, stream_insert_nav_packets)) { | ||
| 1153 | err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, | 1187 | err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, |
| 1154 | 7, new->stream_insert_nav_packets); | 1188 | 7, new->stream_insert_nav_packets); |
| 1155 | if (err) return err; | 1189 | if (err) |
| 1190 | return err; | ||
| 1156 | } | 1191 | } |
| 1157 | return 0; | 1192 | return 0; |
| 1158 | } | 1193 | } |
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig index 4bfbd5f463d1..577880b133eb 100644 --- a/drivers/media/common/siano/Kconfig +++ b/drivers/media/common/siano/Kconfig | |||
| @@ -15,7 +15,7 @@ config SMS_SIANO_RC | |||
| 15 | depends on SMS_USB_DRV || SMS_SDIO_DRV | 15 | depends on SMS_USB_DRV || SMS_SDIO_DRV |
| 16 | depends on MEDIA_COMMON_OPTIONS | 16 | depends on MEDIA_COMMON_OPTIONS |
| 17 | default y | 17 | default y |
| 18 | ---help--- | 18 | help |
| 19 | Choose Y to select Remote Controller support for Siano driver. | 19 | Choose Y to select Remote Controller support for Siano driver. |
| 20 | 20 | ||
| 21 | config SMS_SIANO_DEBUGFS | 21 | config SMS_SIANO_DEBUGFS |
| @@ -24,7 +24,7 @@ config SMS_SIANO_DEBUGFS | |||
| 24 | depends on DEBUG_FS | 24 | depends on DEBUG_FS |
| 25 | depends on SMS_USB_DRV = SMS_SDIO_DRV | 25 | depends on SMS_USB_DRV = SMS_SDIO_DRV |
| 26 | 26 | ||
| 27 | ---help--- | 27 | help |
| 28 | Choose Y to enable visualizing a dump of the frontend | 28 | Choose Y to enable visualizing a dump of the frontend |
| 29 | statistics response packets via debugfs. Currently, works | 29 | statistics response packets via debugfs. Currently, works |
| 30 | only with Siano USB devices. | 30 | only with Siano USB devices. |
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 15b6b9c0a2e4..7ebd58a1c431 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c | |||
| @@ -672,6 +672,11 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, | |||
| 672 | return -EBUSY; | 672 | return -EBUSY; |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | if (q->waiting_in_dqbuf && *count) { | ||
| 676 | dprintk(1, "another dup()ped fd is waiting for a buffer\n"); | ||
| 677 | return -EBUSY; | ||
| 678 | } | ||
| 679 | |||
| 675 | if (*count == 0 || q->num_buffers != 0 || | 680 | if (*count == 0 || q->num_buffers != 0 || |
| 676 | (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { | 681 | (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { |
| 677 | /* | 682 | /* |
| @@ -807,6 +812,10 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, | |||
| 807 | } | 812 | } |
| 808 | 813 | ||
| 809 | if (!q->num_buffers) { | 814 | if (!q->num_buffers) { |
| 815 | if (q->waiting_in_dqbuf && *count) { | ||
| 816 | dprintk(1, "another dup()ped fd is waiting for a buffer\n"); | ||
| 817 | return -EBUSY; | ||
| 818 | } | ||
| 810 | memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); | 819 | memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); |
| 811 | q->memory = memory; | 820 | q->memory = memory; |
| 812 | q->waiting_for_buffers = !q->is_output; | 821 | q->waiting_for_buffers = !q->is_output; |
| @@ -915,8 +924,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 915 | 924 | ||
| 916 | if (WARN_ON(state != VB2_BUF_STATE_DONE && | 925 | if (WARN_ON(state != VB2_BUF_STATE_DONE && |
| 917 | state != VB2_BUF_STATE_ERROR && | 926 | state != VB2_BUF_STATE_ERROR && |
| 918 | state != VB2_BUF_STATE_QUEUED && | 927 | state != VB2_BUF_STATE_QUEUED)) |
| 919 | state != VB2_BUF_STATE_REQUEUEING)) | ||
| 920 | state = VB2_BUF_STATE_ERROR; | 928 | state = VB2_BUF_STATE_ERROR; |
| 921 | 929 | ||
| 922 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 930 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| @@ -929,8 +937,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 929 | dprintk(4, "done processing on buffer %d, state: %d\n", | 937 | dprintk(4, "done processing on buffer %d, state: %d\n", |
| 930 | vb->index, state); | 938 | vb->index, state); |
| 931 | 939 | ||
| 932 | if (state != VB2_BUF_STATE_QUEUED && | 940 | if (state != VB2_BUF_STATE_QUEUED) { |
| 933 | state != VB2_BUF_STATE_REQUEUEING) { | ||
| 934 | /* sync buffers */ | 941 | /* sync buffers */ |
| 935 | for (plane = 0; plane < vb->num_planes; ++plane) | 942 | for (plane = 0; plane < vb->num_planes; ++plane) |
| 936 | call_void_memop(vb, finish, vb->planes[plane].mem_priv); | 943 | call_void_memop(vb, finish, vb->planes[plane].mem_priv); |
| @@ -938,8 +945,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 938 | } | 945 | } |
| 939 | 946 | ||
| 940 | spin_lock_irqsave(&q->done_lock, flags); | 947 | spin_lock_irqsave(&q->done_lock, flags); |
| 941 | if (state == VB2_BUF_STATE_QUEUED || | 948 | if (state == VB2_BUF_STATE_QUEUED) { |
| 942 | state == VB2_BUF_STATE_REQUEUEING) { | ||
| 943 | vb->state = VB2_BUF_STATE_QUEUED; | 949 | vb->state = VB2_BUF_STATE_QUEUED; |
| 944 | } else { | 950 | } else { |
| 945 | /* Add the buffer to the done buffers list */ | 951 | /* Add the buffer to the done buffers list */ |
| @@ -949,8 +955,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 949 | atomic_dec(&q->owned_by_drv_count); | 955 | atomic_dec(&q->owned_by_drv_count); |
| 950 | 956 | ||
| 951 | if (state != VB2_BUF_STATE_QUEUED && vb->req_obj.req) { | 957 | if (state != VB2_BUF_STATE_QUEUED && vb->req_obj.req) { |
| 952 | /* This is not supported at the moment */ | ||
| 953 | WARN_ON(state == VB2_BUF_STATE_REQUEUEING); | ||
| 954 | media_request_object_unbind(&vb->req_obj); | 958 | media_request_object_unbind(&vb->req_obj); |
| 955 | media_request_object_put(&vb->req_obj); | 959 | media_request_object_put(&vb->req_obj); |
| 956 | } | 960 | } |
| @@ -962,10 +966,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) | |||
| 962 | switch (state) { | 966 | switch (state) { |
| 963 | case VB2_BUF_STATE_QUEUED: | 967 | case VB2_BUF_STATE_QUEUED: |
| 964 | return; | 968 | return; |
| 965 | case VB2_BUF_STATE_REQUEUEING: | ||
| 966 | if (q->start_streaming_called) | ||
| 967 | __enqueue_in_driver(vb); | ||
| 968 | return; | ||
| 969 | default: | 969 | default: |
| 970 | /* Inform any processes that may be waiting for buffers */ | 970 | /* Inform any processes that may be waiting for buffers */ |
| 971 | wake_up(&q->done_wq); | 971 | wake_up(&q->done_wq); |
| @@ -1516,6 +1516,12 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, | |||
| 1516 | 1516 | ||
| 1517 | vb = q->bufs[index]; | 1517 | vb = q->bufs[index]; |
| 1518 | 1518 | ||
| 1519 | if (!req && vb->state != VB2_BUF_STATE_IN_REQUEST && | ||
| 1520 | q->requires_requests) { | ||
| 1521 | dprintk(1, "qbuf requires a request\n"); | ||
| 1522 | return -EBADR; | ||
| 1523 | } | ||
| 1524 | |||
| 1519 | if ((req && q->uses_qbuf) || | 1525 | if ((req && q->uses_qbuf) || |
| 1520 | (!req && vb->state != VB2_BUF_STATE_IN_REQUEST && | 1526 | (!req && vb->state != VB2_BUF_STATE_IN_REQUEST && |
| 1521 | q->uses_requests)) { | 1527 | q->uses_requests)) { |
| @@ -1659,6 +1665,11 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1659 | for (;;) { | 1665 | for (;;) { |
| 1660 | int ret; | 1666 | int ret; |
| 1661 | 1667 | ||
| 1668 | if (q->waiting_in_dqbuf) { | ||
| 1669 | dprintk(1, "another dup()ped fd is waiting for a buffer\n"); | ||
| 1670 | return -EBUSY; | ||
| 1671 | } | ||
| 1672 | |||
| 1662 | if (!q->streaming) { | 1673 | if (!q->streaming) { |
| 1663 | dprintk(1, "streaming off, will not wait for buffers\n"); | 1674 | dprintk(1, "streaming off, will not wait for buffers\n"); |
| 1664 | return -EINVAL; | 1675 | return -EINVAL; |
| @@ -1686,6 +1697,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1686 | return -EAGAIN; | 1697 | return -EAGAIN; |
| 1687 | } | 1698 | } |
| 1688 | 1699 | ||
| 1700 | q->waiting_in_dqbuf = 1; | ||
| 1689 | /* | 1701 | /* |
| 1690 | * We are streaming and blocking, wait for another buffer to | 1702 | * We are streaming and blocking, wait for another buffer to |
| 1691 | * become ready or for streamoff. Driver's lock is released to | 1703 | * become ready or for streamoff. Driver's lock is released to |
| @@ -1706,6 +1718,7 @@ static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking) | |||
| 1706 | * the locks or return an error if one occurred. | 1718 | * the locks or return an error if one occurred. |
| 1707 | */ | 1719 | */ |
| 1708 | call_void_qop(q, wait_finish, q); | 1720 | call_void_qop(q, wait_finish, q); |
| 1721 | q->waiting_in_dqbuf = 0; | ||
| 1709 | if (ret) { | 1722 | if (ret) { |
| 1710 | dprintk(1, "sleep was interrupted\n"); | 1723 | dprintk(1, "sleep was interrupted\n"); |
| 1711 | return ret; | 1724 | return ret; |
| @@ -2247,6 +2260,9 @@ int vb2_core_queue_init(struct vb2_queue *q) | |||
| 2247 | WARN_ON(!q->ops->buf_queue)) | 2260 | WARN_ON(!q->ops->buf_queue)) |
| 2248 | return -EINVAL; | 2261 | return -EINVAL; |
| 2249 | 2262 | ||
| 2263 | if (WARN_ON(q->requires_requests && !q->supports_requests)) | ||
| 2264 | return -EINVAL; | ||
| 2265 | |||
| 2250 | INIT_LIST_HEAD(&q->queued_list); | 2266 | INIT_LIST_HEAD(&q->queued_list); |
| 2251 | INIT_LIST_HEAD(&q->done_list); | 2267 | INIT_LIST_HEAD(&q->done_list); |
| 2252 | spin_lock_init(&q->done_lock); | 2268 | spin_lock_init(&q->done_lock); |
| @@ -2585,6 +2601,12 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
| 2585 | if (!data) | 2601 | if (!data) |
| 2586 | return -EINVAL; | 2602 | return -EINVAL; |
| 2587 | 2603 | ||
| 2604 | if (q->waiting_in_dqbuf) { | ||
| 2605 | dprintk(3, "another dup()ped fd is %s\n", | ||
| 2606 | read ? "reading" : "writing"); | ||
| 2607 | return -EBUSY; | ||
| 2608 | } | ||
| 2609 | |||
| 2588 | /* | 2610 | /* |
| 2589 | * Initialize emulator on first call. | 2611 | * Initialize emulator on first call. |
| 2590 | */ | 2612 | */ |
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index d09dee20e421..fb9ac7696fc6 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c | |||
| @@ -122,9 +122,9 @@ static int __verify_length(struct vb2_buffer *vb, const struct v4l2_buffer *b) | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | /* | 124 | /* |
| 125 | * __init_v4l2_vb2_buffer() - initialize the v4l2_vb2_buffer struct | 125 | * __init_vb2_v4l2_buffer() - initialize the vb2_v4l2_buffer struct |
| 126 | */ | 126 | */ |
| 127 | static void __init_v4l2_vb2_buffer(struct vb2_buffer *vb) | 127 | static void __init_vb2_v4l2_buffer(struct vb2_buffer *vb) |
| 128 | { | 128 | { |
| 129 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | 129 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
| 130 | 130 | ||
| @@ -368,6 +368,12 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md | |||
| 368 | if (ret) | 368 | if (ret) |
| 369 | return ret; | 369 | return ret; |
| 370 | 370 | ||
| 371 | if (!is_prepare && (b->flags & V4L2_BUF_FLAG_REQUEST_FD) && | ||
| 372 | vb->state != VB2_BUF_STATE_DEQUEUED) { | ||
| 373 | dprintk(1, "%s: buffer is not in dequeued state\n", opname); | ||
| 374 | return -EINVAL; | ||
| 375 | } | ||
| 376 | |||
| 371 | if (!vb->prepared) { | 377 | if (!vb->prepared) { |
| 372 | /* Copy relevant information provided by the userspace */ | 378 | /* Copy relevant information provided by the userspace */ |
| 373 | memset(vbuf->planes, 0, | 379 | memset(vbuf->planes, 0, |
| @@ -381,6 +387,10 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md | |||
| 381 | return 0; | 387 | return 0; |
| 382 | 388 | ||
| 383 | if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) { | 389 | if (!(b->flags & V4L2_BUF_FLAG_REQUEST_FD)) { |
| 390 | if (q->requires_requests) { | ||
| 391 | dprintk(1, "%s: queue requires requests\n", opname); | ||
| 392 | return -EBADR; | ||
| 393 | } | ||
| 384 | if (q->uses_requests) { | 394 | if (q->uses_requests) { |
| 385 | dprintk(1, "%s: queue uses requests\n", opname); | 395 | dprintk(1, "%s: queue uses requests\n", opname); |
| 386 | return -EBUSY; | 396 | return -EBUSY; |
| @@ -388,7 +398,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md | |||
| 388 | return 0; | 398 | return 0; |
| 389 | } else if (!q->supports_requests) { | 399 | } else if (!q->supports_requests) { |
| 390 | dprintk(1, "%s: queue does not support requests\n", opname); | 400 | dprintk(1, "%s: queue does not support requests\n", opname); |
| 391 | return -EACCES; | 401 | return -EBADR; |
| 392 | } else if (q->uses_qbuf) { | 402 | } else if (q->uses_qbuf) { |
| 393 | dprintk(1, "%s: queue does not use requests\n", opname); | 403 | dprintk(1, "%s: queue does not use requests\n", opname); |
| 394 | return -EBUSY; | 404 | return -EBUSY; |
| @@ -419,11 +429,6 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md | |||
| 419 | !q->ops->buf_out_validate)) | 429 | !q->ops->buf_out_validate)) |
| 420 | return -EINVAL; | 430 | return -EINVAL; |
| 421 | 431 | ||
| 422 | if (vb->state != VB2_BUF_STATE_DEQUEUED) { | ||
| 423 | dprintk(1, "%s: buffer is not in dequeued state\n", opname); | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (b->request_fd < 0) { | 432 | if (b->request_fd < 0) { |
| 428 | dprintk(1, "%s: request_fd < 0\n", opname); | 433 | dprintk(1, "%s: request_fd < 0\n", opname); |
| 429 | return -EINVAL; | 434 | return -EINVAL; |
| @@ -543,7 +548,6 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb) | |||
| 543 | break; | 548 | break; |
| 544 | case VB2_BUF_STATE_PREPARING: | 549 | case VB2_BUF_STATE_PREPARING: |
| 545 | case VB2_BUF_STATE_DEQUEUED: | 550 | case VB2_BUF_STATE_DEQUEUED: |
| 546 | case VB2_BUF_STATE_REQUEUEING: | ||
| 547 | /* nothing */ | 551 | /* nothing */ |
| 548 | break; | 552 | break; |
| 549 | } | 553 | } |
| @@ -592,7 +596,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes) | |||
| 592 | 596 | ||
| 593 | static const struct vb2_buf_ops v4l2_buf_ops = { | 597 | static const struct vb2_buf_ops v4l2_buf_ops = { |
| 594 | .verify_planes_array = __verify_planes_array_core, | 598 | .verify_planes_array = __verify_planes_array_core, |
| 595 | .init_buffer = __init_v4l2_vb2_buffer, | 599 | .init_buffer = __init_vb2_v4l2_buffer, |
| 596 | .fill_user_buffer = __fill_v4l2_buffer, | 600 | .fill_user_buffer = __fill_v4l2_buffer, |
| 597 | .fill_vb2_buffer = __fill_vb2_buffer, | 601 | .fill_vb2_buffer = __fill_vb2_buffer, |
| 598 | .copy_timestamp = __copy_timestamp, | 602 | .copy_timestamp = __copy_timestamp, |
diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 6dfbd5b05907..1c6659f7c394 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c | |||
| @@ -46,17 +46,17 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, | |||
| 46 | 46 | ||
| 47 | buf->size = size; | 47 | buf->size = size; |
| 48 | buf->vaddr = vmalloc_user(buf->size); | 48 | buf->vaddr = vmalloc_user(buf->size); |
| 49 | buf->dma_dir = dma_dir; | ||
| 50 | buf->handler.refcount = &buf->refcount; | ||
| 51 | buf->handler.put = vb2_vmalloc_put; | ||
| 52 | buf->handler.arg = buf; | ||
| 53 | |||
| 54 | if (!buf->vaddr) { | 49 | if (!buf->vaddr) { |
| 55 | pr_debug("vmalloc of size %ld failed\n", buf->size); | 50 | pr_debug("vmalloc of size %ld failed\n", buf->size); |
| 56 | kfree(buf); | 51 | kfree(buf); |
| 57 | return ERR_PTR(-ENOMEM); | 52 | return ERR_PTR(-ENOMEM); |
| 58 | } | 53 | } |
| 59 | 54 | ||
| 55 | buf->dma_dir = dma_dir; | ||
| 56 | buf->handler.refcount = &buf->refcount; | ||
| 57 | buf->handler.put = vb2_vmalloc_put; | ||
| 58 | buf->handler.arg = buf; | ||
| 59 | |||
| 60 | refcount_set(&buf->refcount, 1); | 60 | refcount_set(&buf->refcount, 1); |
| 61 | return buf; | 61 | return buf; |
| 62 | } | 62 | } |
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 4a5834a1c3b7..a3393cd4e584 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c | |||
| @@ -526,7 +526,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
| 526 | dvb_media_device_free(dvbdev); | 526 | dvb_media_device_free(dvbdev); |
| 527 | kfree(dvbdevfops); | 527 | kfree(dvbdevfops); |
| 528 | kfree(dvbdev); | 528 | kfree(dvbdev); |
| 529 | up_write(&minor_rwsem); | ||
| 530 | mutex_unlock(&dvbdev_register_lock); | 529 | mutex_unlock(&dvbdev_register_lock); |
| 531 | return ret; | 530 | return ret; |
| 532 | } | 531 | } |
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c index f59a102b0a64..9ba8f39fe310 100644 --- a/drivers/media/dvb-frontends/as102_fe.c +++ b/drivers/media/dvb-frontends/as102_fe.c | |||
| @@ -467,7 +467,7 @@ struct dvb_frontend *as102_attach(const char *name, | |||
| 467 | 467 | ||
| 468 | /* init frontend callback ops */ | 468 | /* init frontend callback ops */ |
| 469 | memcpy(&fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops)); | 469 | memcpy(&fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops)); |
| 470 | strncpy(fe->ops.info.name, name, sizeof(fe->ops.info.name)); | 470 | strscpy(fe->ops.info.name, name, sizeof(fe->ops.info.name)); |
| 471 | 471 | ||
| 472 | return fe; | 472 | return fe; |
| 473 | 473 | ||
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index f8040f6def62..d869029ca87d 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c | |||
| @@ -2774,7 +2774,8 @@ static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_a | |||
| 2774 | dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); | 2774 | dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); |
| 2775 | 2775 | ||
| 2776 | /* init 7090 tuner adapter */ | 2776 | /* init 7090 tuner adapter */ |
| 2777 | strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name)); | 2777 | strscpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", |
| 2778 | sizeof(st->dib7090_tuner_adap.name)); | ||
| 2778 | st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo; | 2779 | st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo; |
| 2779 | st->dib7090_tuner_adap.algo_data = NULL; | 2780 | st->dib7090_tuner_adap.algo_data = NULL; |
| 2780 | st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent; | 2781 | st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent; |
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index 85c429cce23e..564669338dc6 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c | |||
| @@ -4458,8 +4458,8 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad | |||
| 4458 | dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); | 4458 | dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); |
| 4459 | 4459 | ||
| 4460 | /* init 8096p tuner adapter */ | 4460 | /* init 8096p tuner adapter */ |
| 4461 | strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", | 4461 | strscpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", |
| 4462 | sizeof(state->dib8096p_tuner_adap.name)); | 4462 | sizeof(state->dib8096p_tuner_adap.name)); |
| 4463 | state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; | 4463 | state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; |
| 4464 | state->dib8096p_tuner_adap.algo_data = NULL; | 4464 | state->dib8096p_tuner_adap.algo_data = NULL; |
| 4465 | state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; | 4465 | state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; |
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 1875da07c150..e7838926e6bc 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c | |||
| @@ -2521,7 +2521,8 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c | |||
| 2521 | dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr); | 2521 | dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr); |
| 2522 | 2522 | ||
| 2523 | st->tuner_adap.dev.parent = i2c_adap->dev.parent; | 2523 | st->tuner_adap.dev.parent = i2c_adap->dev.parent; |
| 2524 | strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name)); | 2524 | strscpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", |
| 2525 | sizeof(st->tuner_adap.name)); | ||
| 2525 | st->tuner_adap.algo = &dib9000_tuner_algo; | 2526 | st->tuner_adap.algo = &dib9000_tuner_algo; |
| 2526 | st->tuner_adap.algo_data = NULL; | 2527 | st->tuner_adap.algo_data = NULL; |
| 2527 | i2c_set_adapdata(&st->tuner_adap, st); | 2528 | i2c_set_adapdata(&st->tuner_adap, st); |
| @@ -2529,7 +2530,8 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c | |||
| 2529 | goto error; | 2530 | goto error; |
| 2530 | 2531 | ||
| 2531 | st->component_bus.dev.parent = i2c_adap->dev.parent; | 2532 | st->component_bus.dev.parent = i2c_adap->dev.parent; |
| 2532 | strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name)); | 2533 | strscpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", |
| 2534 | sizeof(st->component_bus.name)); | ||
| 2533 | st->component_bus.algo = &dib9000_component_bus_algo; | 2535 | st->component_bus.algo = &dib9000_component_bus_algo; |
| 2534 | st->component_bus.algo_data = NULL; | 2536 | st->component_bus.algo_data = NULL; |
| 2535 | st->component_bus_speed = 340; | 2537 | st->component_bus_speed = 340; |
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 0a5b15bee1d7..c597d6fc3046 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c | |||
| @@ -2263,61 +2263,41 @@ static int DRX_Start(struct drxd_state *state, s32 off) | |||
| 2263 | case DRX_CHANNEL_LOW: | 2263 | case DRX_CHANNEL_LOW: |
| 2264 | transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO; | 2264 | transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO; |
| 2265 | status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000); | 2265 | status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000); |
| 2266 | if (status < 0) | ||
| 2267 | break; | ||
| 2268 | break; | 2266 | break; |
| 2269 | case DRX_CHANNEL_HIGH: | 2267 | case DRX_CHANNEL_HIGH: |
| 2270 | transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI; | 2268 | transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI; |
| 2271 | status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000); | 2269 | status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000); |
| 2272 | if (status < 0) | ||
| 2273 | break; | ||
| 2274 | break; | 2270 | break; |
| 2275 | |||
| 2276 | } | 2271 | } |
| 2277 | 2272 | ||
| 2278 | switch (p->code_rate_HP) { | 2273 | switch (p->code_rate_HP) { |
| 2279 | case FEC_1_2: | 2274 | case FEC_1_2: |
| 2280 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2; | 2275 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2; |
| 2281 | if (state->type_A) { | 2276 | if (state->type_A) |
| 2282 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000); | 2277 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000); |
| 2283 | if (status < 0) | ||
| 2284 | break; | ||
| 2285 | } | ||
| 2286 | break; | 2278 | break; |
| 2287 | default: | 2279 | default: |
| 2288 | operationMode |= SC_RA_RAM_OP_AUTO_RATE__M; | 2280 | operationMode |= SC_RA_RAM_OP_AUTO_RATE__M; |
| 2289 | /* fall through */ | 2281 | /* fall through */ |
| 2290 | case FEC_2_3: | 2282 | case FEC_2_3: |
| 2291 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3; | 2283 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3; |
| 2292 | if (state->type_A) { | 2284 | if (state->type_A) |
| 2293 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000); | 2285 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000); |
| 2294 | if (status < 0) | ||
| 2295 | break; | ||
| 2296 | } | ||
| 2297 | break; | 2286 | break; |
| 2298 | case FEC_3_4: | 2287 | case FEC_3_4: |
| 2299 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4; | 2288 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4; |
| 2300 | if (state->type_A) { | 2289 | if (state->type_A) |
| 2301 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000); | 2290 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000); |
| 2302 | if (status < 0) | ||
| 2303 | break; | ||
| 2304 | } | ||
| 2305 | break; | 2291 | break; |
| 2306 | case FEC_5_6: | 2292 | case FEC_5_6: |
| 2307 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6; | 2293 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6; |
| 2308 | if (state->type_A) { | 2294 | if (state->type_A) |
| 2309 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000); | 2295 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000); |
| 2310 | if (status < 0) | ||
| 2311 | break; | ||
| 2312 | } | ||
| 2313 | break; | 2296 | break; |
| 2314 | case FEC_7_8: | 2297 | case FEC_7_8: |
| 2315 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8; | 2298 | transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8; |
| 2316 | if (state->type_A) { | 2299 | if (state->type_A) |
| 2317 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000); | 2300 | status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000); |
| 2318 | if (status < 0) | ||
| 2319 | break; | ||
| 2320 | } | ||
| 2321 | break; | 2301 | break; |
| 2322 | } | 2302 | } |
| 2323 | if (status < 0) | 2303 | if (status < 0) |
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 29836c1a40e9..da1b48a18515 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c | |||
| @@ -839,7 +839,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
| 839 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, | 839 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, |
| 840 | sizeof(struct dvb_tuner_ops)); | 840 | sizeof(struct dvb_tuner_ops)); |
| 841 | 841 | ||
| 842 | strncpy(fe->ops.tuner_ops.info.name, desc->name, | 842 | strscpy(fe->ops.tuner_ops.info.name, desc->name, |
| 843 | sizeof(fe->ops.tuner_ops.info.name)); | 843 | sizeof(fe->ops.tuner_ops.info.name)); |
| 844 | 844 | ||
| 845 | fe->ops.tuner_ops.info.frequency_min_hz = desc->min; | 845 | fe->ops.tuner_ops.info.frequency_min_hz = desc->min; |
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 123f2a33738b..b543e1c4c4f9 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c | |||
| @@ -309,6 +309,9 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) | |||
| 309 | u16 u16tmp; | 309 | u16 u16tmp; |
| 310 | u32 tuner_frequency_khz, target_mclk; | 310 | u32 tuner_frequency_khz, target_mclk; |
| 311 | s32 s32tmp; | 311 | s32 s32tmp; |
| 312 | static const struct reg_sequence reset_buf[] = { | ||
| 313 | {0x07, 0x80}, {0x07, 0x00} | ||
| 314 | }; | ||
| 312 | 315 | ||
| 313 | dev_dbg(&client->dev, | 316 | dev_dbg(&client->dev, |
| 314 | "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", | 317 | "delivery_system=%d modulation=%d frequency=%u symbol_rate=%d inversion=%d pilot=%d rolloff=%d\n", |
| @@ -321,11 +324,7 @@ static int m88ds3103_set_frontend(struct dvb_frontend *fe) | |||
| 321 | } | 324 | } |
| 322 | 325 | ||
| 323 | /* reset */ | 326 | /* reset */ |
| 324 | ret = regmap_write(dev->regmap, 0x07, 0x80); | 327 | ret = regmap_multi_reg_write(dev->regmap, reset_buf, 2); |
| 325 | if (ret) | ||
| 326 | goto err; | ||
| 327 | |||
| 328 | ret = regmap_write(dev->regmap, 0x07, 0x00); | ||
| 329 | if (ret) | 328 | if (ret) |
| 330 | goto err; | 329 | goto err; |
| 331 | 330 | ||
| @@ -1470,7 +1469,7 @@ static int m88ds3103_probe(struct i2c_client *client, | |||
| 1470 | /* create dvb_frontend */ | 1469 | /* create dvb_frontend */ |
| 1471 | memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); | 1470 | memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); |
| 1472 | if (dev->chip_id == M88RS6000_CHIP_ID) | 1471 | if (dev->chip_id == M88RS6000_CHIP_ID) |
| 1473 | strncpy(dev->fe.ops.info.name, "Montage Technology M88RS6000", | 1472 | strscpy(dev->fe.ops.info.name, "Montage Technology M88RS6000", |
| 1474 | sizeof(dev->fe.ops.info.name)); | 1473 | sizeof(dev->fe.ops.info.name)); |
| 1475 | if (!pdata->attach_in_use) | 1474 | if (!pdata->attach_in_use) |
| 1476 | dev->fe.ops.release = NULL; | 1475 | dev->fe.ops.release = NULL; |
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index feacd8da421d..c9bcd2e95417 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c | |||
| @@ -275,18 +275,20 @@ static u32 si2165_get_fe_clk(struct si2165_state *state) | |||
| 275 | 275 | ||
| 276 | static int si2165_wait_init_done(struct si2165_state *state) | 276 | static int si2165_wait_init_done(struct si2165_state *state) |
| 277 | { | 277 | { |
| 278 | int ret = -EINVAL; | 278 | int ret; |
| 279 | u8 val = 0; | 279 | u8 val = 0; |
| 280 | int i; | 280 | int i; |
| 281 | 281 | ||
| 282 | for (i = 0; i < 3; ++i) { | 282 | for (i = 0; i < 3; ++i) { |
| 283 | si2165_readreg8(state, REG_INIT_DONE, &val); | 283 | ret = si2165_readreg8(state, REG_INIT_DONE, &val); |
| 284 | if (ret < 0) | ||
| 285 | return ret; | ||
| 284 | if (val == 0x01) | 286 | if (val == 0x01) |
| 285 | return 0; | 287 | return 0; |
| 286 | usleep_range(1000, 50000); | 288 | usleep_range(1000, 50000); |
| 287 | } | 289 | } |
| 288 | dev_err(&state->client->dev, "init_done was not set\n"); | 290 | dev_err(&state->client->dev, "init_done was not set\n"); |
| 289 | return ret; | 291 | return -EINVAL; |
| 290 | } | 292 | } |
| 291 | 293 | ||
| 292 | static int si2165_upload_firmware_block(struct si2165_state *state, | 294 | static int si2165_upload_firmware_block(struct si2165_state *state, |
| @@ -1299,7 +1301,6 @@ MODULE_DEVICE_TABLE(i2c, si2165_id_table); | |||
| 1299 | 1301 | ||
| 1300 | static struct i2c_driver si2165_driver = { | 1302 | static struct i2c_driver si2165_driver = { |
| 1301 | .driver = { | 1303 | .driver = { |
| 1302 | .owner = THIS_MODULE, | ||
| 1303 | .name = "si2165", | 1304 | .name = "si2165", |
| 1304 | }, | 1305 | }, |
| 1305 | .probe = si2165_probe, | 1306 | .probe = si2165_probe, |
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index e5cd2cd414f4..0af9b335be12 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c | |||
| @@ -180,6 +180,9 @@ static int ts2020_set_tuner_rf(struct dvb_frontend *fe) | |||
| 180 | unsigned int utmp; | 180 | unsigned int utmp; |
| 181 | 181 | ||
| 182 | ret = regmap_read(dev->regmap, 0x3d, &utmp); | 182 | ret = regmap_read(dev->regmap, 0x3d, &utmp); |
| 183 | if (ret) | ||
| 184 | return ret; | ||
| 185 | |||
| 183 | utmp &= 0x7f; | 186 | utmp &= 0x7f; |
| 184 | if (utmp < 0x16) | 187 | if (utmp < 0x16) |
| 185 | utmp = 0xa1; | 188 | utmp = 0xa1; |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 6d32f8dcf83b..7793358ab8b3 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
| @@ -8,7 +8,7 @@ config VIDEO_IR_I2C | |||
| 8 | tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT | 8 | tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT |
| 9 | depends on I2C && RC_CORE | 9 | depends on I2C && RC_CORE |
| 10 | default y | 10 | default y |
| 11 | ---help--- | 11 | help |
| 12 | Most boards have an IR chip directly connected via GPIO. However, | 12 | Most boards have an IR chip directly connected via GPIO. However, |
| 13 | some video boards have the IR connected via I2C bus. | 13 | some video boards have the IR connected via I2C bus. |
| 14 | 14 | ||
| @@ -29,7 +29,7 @@ comment "Audio decoders, processors and mixers" | |||
| 29 | config VIDEO_TVAUDIO | 29 | config VIDEO_TVAUDIO |
| 30 | tristate "Simple audio decoder chips" | 30 | tristate "Simple audio decoder chips" |
| 31 | depends on VIDEO_V4L2 && I2C | 31 | depends on VIDEO_V4L2 && I2C |
| 32 | ---help--- | 32 | help |
| 33 | Support for several audio decoder chips found on some bt8xx boards: | 33 | Support for several audio decoder chips found on some bt8xx boards: |
| 34 | Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300, | 34 | Philips: tda9840, tda9873h, tda9874h/a, tda9850, tda985x, tea6300, |
| 35 | tea6320, tea6420, tda8425, ta8874z. | 35 | tea6320, tea6420, tda8425, ta8874z. |
| @@ -41,7 +41,7 @@ config VIDEO_TVAUDIO | |||
| 41 | config VIDEO_TDA7432 | 41 | config VIDEO_TDA7432 |
| 42 | tristate "Philips TDA7432 audio processor" | 42 | tristate "Philips TDA7432 audio processor" |
| 43 | depends on VIDEO_V4L2 && I2C | 43 | depends on VIDEO_V4L2 && I2C |
| 44 | ---help--- | 44 | help |
| 45 | Support for tda7432 audio decoder chip found on some bt8xx boards. | 45 | Support for tda7432 audio decoder chip found on some bt8xx boards. |
| 46 | 46 | ||
| 47 | To compile this driver as a module, choose M here: the | 47 | To compile this driver as a module, choose M here: the |
| @@ -50,7 +50,7 @@ config VIDEO_TDA7432 | |||
| 50 | config VIDEO_TDA9840 | 50 | config VIDEO_TDA9840 |
| 51 | tristate "Philips TDA9840 audio processor" | 51 | tristate "Philips TDA9840 audio processor" |
| 52 | depends on I2C | 52 | depends on I2C |
| 53 | ---help--- | 53 | help |
| 54 | Support for tda9840 audio decoder chip found on some Zoran boards. | 54 | Support for tda9840 audio decoder chip found on some Zoran boards. |
| 55 | 55 | ||
| 56 | To compile this driver as a module, choose M here: the | 56 | To compile this driver as a module, choose M here: the |
| @@ -60,9 +60,10 @@ config VIDEO_TDA1997X | |||
| 60 | tristate "NXP TDA1997x HDMI receiver" | 60 | tristate "NXP TDA1997x HDMI receiver" |
| 61 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 61 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 62 | depends on SND_SOC | 62 | depends on SND_SOC |
| 63 | select SND_PCM | ||
| 64 | select HDMI | 63 | select HDMI |
| 65 | ---help--- | 64 | select SND_PCM |
| 65 | select V4L2_FWNODE | ||
| 66 | help | ||
| 66 | V4L2 subdevice driver for the NXP TDA1997x HDMI receivers. | 67 | V4L2 subdevice driver for the NXP TDA1997x HDMI receivers. |
| 67 | 68 | ||
| 68 | To compile this driver as a module, choose M here: the | 69 | To compile this driver as a module, choose M here: the |
| @@ -71,7 +72,7 @@ config VIDEO_TDA1997X | |||
| 71 | config VIDEO_TEA6415C | 72 | config VIDEO_TEA6415C |
| 72 | tristate "Philips TEA6415C audio processor" | 73 | tristate "Philips TEA6415C audio processor" |
| 73 | depends on I2C | 74 | depends on I2C |
| 74 | ---help--- | 75 | help |
| 75 | Support for tea6415c audio decoder chip found on some bt8xx boards. | 76 | Support for tea6415c audio decoder chip found on some bt8xx boards. |
| 76 | 77 | ||
| 77 | To compile this driver as a module, choose M here: the | 78 | To compile this driver as a module, choose M here: the |
| @@ -80,7 +81,7 @@ config VIDEO_TEA6415C | |||
| 80 | config VIDEO_TEA6420 | 81 | config VIDEO_TEA6420 |
| 81 | tristate "Philips TEA6420 audio processor" | 82 | tristate "Philips TEA6420 audio processor" |
| 82 | depends on I2C | 83 | depends on I2C |
| 83 | ---help--- | 84 | help |
| 84 | Support for tea6420 audio decoder chip found on some bt8xx boards. | 85 | Support for tea6420 audio decoder chip found on some bt8xx boards. |
| 85 | 86 | ||
| 86 | To compile this driver as a module, choose M here: the | 87 | To compile this driver as a module, choose M here: the |
| @@ -89,7 +90,7 @@ config VIDEO_TEA6420 | |||
| 89 | config VIDEO_MSP3400 | 90 | config VIDEO_MSP3400 |
| 90 | tristate "Micronas MSP34xx audio decoders" | 91 | tristate "Micronas MSP34xx audio decoders" |
| 91 | depends on VIDEO_V4L2 && I2C | 92 | depends on VIDEO_V4L2 && I2C |
| 92 | ---help--- | 93 | help |
| 93 | Support for the Micronas MSP34xx series of audio decoders. | 94 | Support for the Micronas MSP34xx series of audio decoders. |
| 94 | 95 | ||
| 95 | To compile this driver as a module, choose M here: the | 96 | To compile this driver as a module, choose M here: the |
| @@ -98,7 +99,7 @@ config VIDEO_MSP3400 | |||
| 98 | config VIDEO_CS3308 | 99 | config VIDEO_CS3308 |
| 99 | tristate "Cirrus Logic CS3308 audio ADC" | 100 | tristate "Cirrus Logic CS3308 audio ADC" |
| 100 | depends on VIDEO_V4L2 && I2C | 101 | depends on VIDEO_V4L2 && I2C |
| 101 | ---help--- | 102 | help |
| 102 | Support for the Cirrus Logic CS3308 High Performance 8-Channel | 103 | Support for the Cirrus Logic CS3308 High Performance 8-Channel |
| 103 | Analog Volume Control | 104 | Analog Volume Control |
| 104 | 105 | ||
| @@ -108,7 +109,7 @@ config VIDEO_CS3308 | |||
| 108 | config VIDEO_CS5345 | 109 | config VIDEO_CS5345 |
| 109 | tristate "Cirrus Logic CS5345 audio ADC" | 110 | tristate "Cirrus Logic CS5345 audio ADC" |
| 110 | depends on VIDEO_V4L2 && I2C | 111 | depends on VIDEO_V4L2 && I2C |
| 111 | ---help--- | 112 | help |
| 112 | Support for the Cirrus Logic CS5345 24-bit, 192 kHz | 113 | Support for the Cirrus Logic CS5345 24-bit, 192 kHz |
| 113 | stereo A/D converter. | 114 | stereo A/D converter. |
| 114 | 115 | ||
| @@ -118,7 +119,7 @@ config VIDEO_CS5345 | |||
| 118 | config VIDEO_CS53L32A | 119 | config VIDEO_CS53L32A |
| 119 | tristate "Cirrus Logic CS53L32A audio ADC" | 120 | tristate "Cirrus Logic CS53L32A audio ADC" |
| 120 | depends on VIDEO_V4L2 && I2C | 121 | depends on VIDEO_V4L2 && I2C |
| 121 | ---help--- | 122 | help |
| 122 | Support for the Cirrus Logic CS53L32A low voltage | 123 | Support for the Cirrus Logic CS53L32A low voltage |
| 123 | stereo A/D converter. | 124 | stereo A/D converter. |
| 124 | 125 | ||
| @@ -128,7 +129,7 @@ config VIDEO_CS53L32A | |||
| 128 | config VIDEO_TLV320AIC23B | 129 | config VIDEO_TLV320AIC23B |
| 129 | tristate "Texas Instruments TLV320AIC23B audio codec" | 130 | tristate "Texas Instruments TLV320AIC23B audio codec" |
| 130 | depends on VIDEO_V4L2 && I2C | 131 | depends on VIDEO_V4L2 && I2C |
| 131 | ---help--- | 132 | help |
| 132 | Support for the Texas Instruments TLV320AIC23B audio codec. | 133 | Support for the Texas Instruments TLV320AIC23B audio codec. |
| 133 | 134 | ||
| 134 | To compile this driver as a module, choose M here: the | 135 | To compile this driver as a module, choose M here: the |
| @@ -137,7 +138,7 @@ config VIDEO_TLV320AIC23B | |||
| 137 | config VIDEO_UDA1342 | 138 | config VIDEO_UDA1342 |
| 138 | tristate "Philips UDA1342 audio codec" | 139 | tristate "Philips UDA1342 audio codec" |
| 139 | depends on VIDEO_V4L2 && I2C | 140 | depends on VIDEO_V4L2 && I2C |
| 140 | ---help--- | 141 | help |
| 141 | Support for the Philips UDA1342 audio codec. | 142 | Support for the Philips UDA1342 audio codec. |
| 142 | 143 | ||
| 143 | To compile this driver as a module, choose M here: the | 144 | To compile this driver as a module, choose M here: the |
| @@ -146,7 +147,7 @@ config VIDEO_UDA1342 | |||
| 146 | config VIDEO_WM8775 | 147 | config VIDEO_WM8775 |
| 147 | tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" | 148 | tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer" |
| 148 | depends on VIDEO_V4L2 && I2C | 149 | depends on VIDEO_V4L2 && I2C |
| 149 | ---help--- | 150 | help |
| 150 | Support for the Wolfson Microelectronics WM8775 high | 151 | Support for the Wolfson Microelectronics WM8775 high |
| 151 | performance stereo A/D Converter with a 4 channel input mixer. | 152 | performance stereo A/D Converter with a 4 channel input mixer. |
| 152 | 153 | ||
| @@ -156,7 +157,7 @@ config VIDEO_WM8775 | |||
| 156 | config VIDEO_WM8739 | 157 | config VIDEO_WM8739 |
| 157 | tristate "Wolfson Microelectronics WM8739 stereo audio ADC" | 158 | tristate "Wolfson Microelectronics WM8739 stereo audio ADC" |
| 158 | depends on VIDEO_V4L2 && I2C | 159 | depends on VIDEO_V4L2 && I2C |
| 159 | ---help--- | 160 | help |
| 160 | Support for the Wolfson Microelectronics WM8739 | 161 | Support for the Wolfson Microelectronics WM8739 |
| 161 | stereo A/D Converter. | 162 | stereo A/D Converter. |
| 162 | 163 | ||
| @@ -166,7 +167,7 @@ config VIDEO_WM8739 | |||
| 166 | config VIDEO_VP27SMPX | 167 | config VIDEO_VP27SMPX |
| 167 | tristate "Panasonic VP27's internal MPX" | 168 | tristate "Panasonic VP27's internal MPX" |
| 168 | depends on VIDEO_V4L2 && I2C | 169 | depends on VIDEO_V4L2 && I2C |
| 169 | ---help--- | 170 | help |
| 170 | Support for the internal MPX of the Panasonic VP27s tuner. | 171 | Support for the internal MPX of the Panasonic VP27s tuner. |
| 171 | 172 | ||
| 172 | To compile this driver as a module, choose M here: the | 173 | To compile this driver as a module, choose M here: the |
| @@ -200,7 +201,7 @@ comment "Video decoders" | |||
| 200 | config VIDEO_ADV7180 | 201 | config VIDEO_ADV7180 |
| 201 | tristate "Analog Devices ADV7180 decoder" | 202 | tristate "Analog Devices ADV7180 decoder" |
| 202 | depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 203 | depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 203 | ---help--- | 204 | help |
| 204 | Support for the Analog Devices ADV7180 video decoder. | 205 | Support for the Analog Devices ADV7180 video decoder. |
| 205 | 206 | ||
| 206 | To compile this driver as a module, choose M here: the | 207 | To compile this driver as a module, choose M here: the |
| @@ -209,7 +210,7 @@ config VIDEO_ADV7180 | |||
| 209 | config VIDEO_ADV7183 | 210 | config VIDEO_ADV7183 |
| 210 | tristate "Analog Devices ADV7183 decoder" | 211 | tristate "Analog Devices ADV7183 decoder" |
| 211 | depends on VIDEO_V4L2 && I2C | 212 | depends on VIDEO_V4L2 && I2C |
| 212 | ---help--- | 213 | help |
| 213 | V4l2 subdevice driver for the Analog Devices | 214 | V4l2 subdevice driver for the Analog Devices |
| 214 | ADV7183 video decoder. | 215 | ADV7183 video decoder. |
| 215 | 216 | ||
| @@ -221,7 +222,8 @@ config VIDEO_ADV748X | |||
| 221 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 222 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 222 | depends on OF | 223 | depends on OF |
| 223 | select REGMAP_I2C | 224 | select REGMAP_I2C |
| 224 | ---help--- | 225 | select V4L2_FWNODE |
| 226 | help | ||
| 225 | V4L2 subdevice driver for the Analog Devices | 227 | V4L2 subdevice driver for the Analog Devices |
| 226 | ADV7481 and ADV7482 HDMI/Analog video decoders. | 228 | ADV7481 and ADV7482 HDMI/Analog video decoders. |
| 227 | 229 | ||
| @@ -234,7 +236,7 @@ config VIDEO_ADV7604 | |||
| 234 | depends on GPIOLIB || COMPILE_TEST | 236 | depends on GPIOLIB || COMPILE_TEST |
| 235 | select HDMI | 237 | select HDMI |
| 236 | select V4L2_FWNODE | 238 | select V4L2_FWNODE |
| 237 | ---help--- | 239 | help |
| 238 | Support for the Analog Devices ADV7604 video decoder. | 240 | Support for the Analog Devices ADV7604 video decoder. |
| 239 | 241 | ||
| 240 | This is a Analog Devices Component/Graphics Digitizer | 242 | This is a Analog Devices Component/Graphics Digitizer |
| @@ -247,7 +249,7 @@ config VIDEO_ADV7604_CEC | |||
| 247 | bool "Enable Analog Devices ADV7604 CEC support" | 249 | bool "Enable Analog Devices ADV7604 CEC support" |
| 248 | depends on VIDEO_ADV7604 | 250 | depends on VIDEO_ADV7604 |
| 249 | select CEC_CORE | 251 | select CEC_CORE |
| 250 | ---help--- | 252 | help |
| 251 | When selected the adv7604 will support the optional | 253 | When selected the adv7604 will support the optional |
| 252 | HDMI CEC feature. | 254 | HDMI CEC feature. |
| 253 | 255 | ||
| @@ -255,7 +257,7 @@ config VIDEO_ADV7842 | |||
| 255 | tristate "Analog Devices ADV7842 decoder" | 257 | tristate "Analog Devices ADV7842 decoder" |
| 256 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 258 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 257 | select HDMI | 259 | select HDMI |
| 258 | ---help--- | 260 | help |
| 259 | Support for the Analog Devices ADV7842 video decoder. | 261 | Support for the Analog Devices ADV7842 video decoder. |
| 260 | 262 | ||
| 261 | This is a Analog Devices Component/Graphics/SD Digitizer | 263 | This is a Analog Devices Component/Graphics/SD Digitizer |
| @@ -268,14 +270,14 @@ config VIDEO_ADV7842_CEC | |||
| 268 | bool "Enable Analog Devices ADV7842 CEC support" | 270 | bool "Enable Analog Devices ADV7842 CEC support" |
| 269 | depends on VIDEO_ADV7842 | 271 | depends on VIDEO_ADV7842 |
| 270 | select CEC_CORE | 272 | select CEC_CORE |
| 271 | ---help--- | 273 | help |
| 272 | When selected the adv7842 will support the optional | 274 | When selected the adv7842 will support the optional |
| 273 | HDMI CEC feature. | 275 | HDMI CEC feature. |
| 274 | 276 | ||
| 275 | config VIDEO_BT819 | 277 | config VIDEO_BT819 |
| 276 | tristate "BT819A VideoStream decoder" | 278 | tristate "BT819A VideoStream decoder" |
| 277 | depends on VIDEO_V4L2 && I2C | 279 | depends on VIDEO_V4L2 && I2C |
| 278 | ---help--- | 280 | help |
| 279 | Support for BT819A video decoder. | 281 | Support for BT819A video decoder. |
| 280 | 282 | ||
| 281 | To compile this driver as a module, choose M here: the | 283 | To compile this driver as a module, choose M here: the |
| @@ -284,7 +286,7 @@ config VIDEO_BT819 | |||
| 284 | config VIDEO_BT856 | 286 | config VIDEO_BT856 |
| 285 | tristate "BT856 VideoStream decoder" | 287 | tristate "BT856 VideoStream decoder" |
| 286 | depends on VIDEO_V4L2 && I2C | 288 | depends on VIDEO_V4L2 && I2C |
| 287 | ---help--- | 289 | help |
| 288 | Support for BT856 video decoder. | 290 | Support for BT856 video decoder. |
| 289 | 291 | ||
| 290 | To compile this driver as a module, choose M here: the | 292 | To compile this driver as a module, choose M here: the |
| @@ -293,7 +295,7 @@ config VIDEO_BT856 | |||
| 293 | config VIDEO_BT866 | 295 | config VIDEO_BT866 |
| 294 | tristate "BT866 VideoStream decoder" | 296 | tristate "BT866 VideoStream decoder" |
| 295 | depends on VIDEO_V4L2 && I2C | 297 | depends on VIDEO_V4L2 && I2C |
| 296 | ---help--- | 298 | help |
| 297 | Support for BT866 video decoder. | 299 | Support for BT866 video decoder. |
| 298 | 300 | ||
| 299 | To compile this driver as a module, choose M here: the | 301 | To compile this driver as a module, choose M here: the |
| @@ -302,7 +304,7 @@ config VIDEO_BT866 | |||
| 302 | config VIDEO_KS0127 | 304 | config VIDEO_KS0127 |
| 303 | tristate "KS0127 video decoder" | 305 | tristate "KS0127 video decoder" |
| 304 | depends on VIDEO_V4L2 && I2C | 306 | depends on VIDEO_V4L2 && I2C |
| 305 | ---help--- | 307 | help |
| 306 | Support for KS0127 video decoder. | 308 | Support for KS0127 video decoder. |
| 307 | 309 | ||
| 308 | This chip is used on AverMedia AVS6EYES Zoran-based MJPEG | 310 | This chip is used on AverMedia AVS6EYES Zoran-based MJPEG |
| @@ -314,53 +316,16 @@ config VIDEO_KS0127 | |||
| 314 | config VIDEO_ML86V7667 | 316 | config VIDEO_ML86V7667 |
| 315 | tristate "OKI ML86V7667 video decoder" | 317 | tristate "OKI ML86V7667 video decoder" |
| 316 | depends on VIDEO_V4L2 && I2C | 318 | depends on VIDEO_V4L2 && I2C |
| 317 | ---help--- | 319 | help |
| 318 | Support for the OKI Semiconductor ML86V7667 video decoder. | 320 | Support for the OKI Semiconductor ML86V7667 video decoder. |
| 319 | 321 | ||
| 320 | To compile this driver as a module, choose M here: the | 322 | To compile this driver as a module, choose M here: the |
| 321 | module will be called ml86v7667. | 323 | module will be called ml86v7667. |
| 322 | 324 | ||
| 323 | config VIDEO_AD5820 | ||
| 324 | tristate "AD5820 lens voice coil support" | ||
| 325 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 326 | ---help--- | ||
| 327 | This is a driver for the AD5820 camera lens voice coil. | ||
| 328 | It is used for example in Nokia N900 (RX-51). | ||
| 329 | |||
| 330 | config VIDEO_AK7375 | ||
| 331 | tristate "AK7375 lens voice coil support" | ||
| 332 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 333 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 334 | help | ||
| 335 | This is a driver for the AK7375 camera lens voice coil. | ||
| 336 | AK7375 is a 12 bit DAC with 120mA output current sink | ||
| 337 | capability. This is designed for linear control of | ||
| 338 | voice coil motors, controlled via I2C serial interface. | ||
| 339 | |||
| 340 | config VIDEO_DW9714 | ||
| 341 | tristate "DW9714 lens voice coil support" | ||
| 342 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 343 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 344 | ---help--- | ||
| 345 | This is a driver for the DW9714 camera lens voice coil. | ||
| 346 | DW9714 is a 10 bit DAC with 120mA output current sink | ||
| 347 | capability. This is designed for linear control of | ||
| 348 | voice coil motors, controlled via I2C serial interface. | ||
| 349 | |||
| 350 | config VIDEO_DW9807_VCM | ||
| 351 | tristate "DW9807 lens voice coil support" | ||
| 352 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 353 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 354 | ---help--- | ||
| 355 | This is a driver for the DW9807 camera lens voice coil. | ||
| 356 | DW9807 is a 10 bit DAC with 100mA output current sink | ||
| 357 | capability. This is designed for linear control of | ||
| 358 | voice coil motors, controlled via I2C serial interface. | ||
| 359 | |||
| 360 | config VIDEO_SAA7110 | 325 | config VIDEO_SAA7110 |
| 361 | tristate "Philips SAA7110 video decoder" | 326 | tristate "Philips SAA7110 video decoder" |
| 362 | depends on VIDEO_V4L2 && I2C | 327 | depends on VIDEO_V4L2 && I2C |
| 363 | ---help--- | 328 | help |
| 364 | Support for the Philips SAA7110 video decoders. | 329 | Support for the Philips SAA7110 video decoders. |
| 365 | 330 | ||
| 366 | To compile this driver as a module, choose M here: the | 331 | To compile this driver as a module, choose M here: the |
| @@ -369,7 +334,7 @@ config VIDEO_SAA7110 | |||
| 369 | config VIDEO_SAA711X | 334 | config VIDEO_SAA711X |
| 370 | tristate "Philips SAA7111/3/4/5 video decoders" | 335 | tristate "Philips SAA7111/3/4/5 video decoders" |
| 371 | depends on VIDEO_V4L2 && I2C | 336 | depends on VIDEO_V4L2 && I2C |
| 372 | ---help--- | 337 | help |
| 373 | Support for the Philips SAA7111/3/4/5 video decoders. | 338 | Support for the Philips SAA7111/3/4/5 video decoders. |
| 374 | 339 | ||
| 375 | To compile this driver as a module, choose M here: the | 340 | To compile this driver as a module, choose M here: the |
| @@ -380,7 +345,7 @@ config VIDEO_TC358743 | |||
| 380 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 345 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 381 | select HDMI | 346 | select HDMI |
| 382 | select V4L2_FWNODE | 347 | select V4L2_FWNODE |
| 383 | ---help--- | 348 | help |
| 384 | Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge. | 349 | Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge. |
| 385 | 350 | ||
| 386 | To compile this driver as a module, choose M here: the | 351 | To compile this driver as a module, choose M here: the |
| @@ -390,7 +355,7 @@ config VIDEO_TC358743_CEC | |||
| 390 | bool "Enable Toshiba TC358743 CEC support" | 355 | bool "Enable Toshiba TC358743 CEC support" |
| 391 | depends on VIDEO_TC358743 | 356 | depends on VIDEO_TC358743 |
| 392 | select CEC_CORE | 357 | select CEC_CORE |
| 393 | ---help--- | 358 | help |
| 394 | When selected the tc358743 will support the optional | 359 | When selected the tc358743 will support the optional |
| 395 | HDMI CEC feature. | 360 | HDMI CEC feature. |
| 396 | 361 | ||
| @@ -398,7 +363,7 @@ config VIDEO_TVP514X | |||
| 398 | tristate "Texas Instruments TVP514x video decoder" | 363 | tristate "Texas Instruments TVP514x video decoder" |
| 399 | depends on VIDEO_V4L2 && I2C | 364 | depends on VIDEO_V4L2 && I2C |
| 400 | select V4L2_FWNODE | 365 | select V4L2_FWNODE |
| 401 | ---help--- | 366 | help |
| 402 | This is a Video4Linux2 sensor driver for the TI TVP5146/47 | 367 | This is a Video4Linux2 sensor driver for the TI TVP5146/47 |
| 403 | decoder. It is currently working with the TI OMAP3 camera | 368 | decoder. It is currently working with the TI OMAP3 camera |
| 404 | controller. | 369 | controller. |
| @@ -410,7 +375,7 @@ config VIDEO_TVP5150 | |||
| 410 | tristate "Texas Instruments TVP5150 video decoder" | 375 | tristate "Texas Instruments TVP5150 video decoder" |
| 411 | depends on VIDEO_V4L2 && I2C | 376 | depends on VIDEO_V4L2 && I2C |
| 412 | select V4L2_FWNODE | 377 | select V4L2_FWNODE |
| 413 | ---help--- | 378 | help |
| 414 | Support for the Texas Instruments TVP5150 video decoder. | 379 | Support for the Texas Instruments TVP5150 video decoder. |
| 415 | 380 | ||
| 416 | To compile this driver as a module, choose M here: the | 381 | To compile this driver as a module, choose M here: the |
| @@ -420,7 +385,7 @@ config VIDEO_TVP7002 | |||
| 420 | tristate "Texas Instruments TVP7002 video decoder" | 385 | tristate "Texas Instruments TVP7002 video decoder" |
| 421 | depends on VIDEO_V4L2 && I2C | 386 | depends on VIDEO_V4L2 && I2C |
| 422 | select V4L2_FWNODE | 387 | select V4L2_FWNODE |
| 423 | ---help--- | 388 | help |
| 424 | Support for the Texas Instruments TVP7002 video decoder. | 389 | Support for the Texas Instruments TVP7002 video decoder. |
| 425 | 390 | ||
| 426 | To compile this driver as a module, choose M here: the | 391 | To compile this driver as a module, choose M here: the |
| @@ -429,7 +394,7 @@ config VIDEO_TVP7002 | |||
| 429 | config VIDEO_TW2804 | 394 | config VIDEO_TW2804 |
| 430 | tristate "Techwell TW2804 multiple video decoder" | 395 | tristate "Techwell TW2804 multiple video decoder" |
| 431 | depends on VIDEO_V4L2 && I2C | 396 | depends on VIDEO_V4L2 && I2C |
| 432 | ---help--- | 397 | help |
| 433 | Support for the Techwell tw2804 multiple video decoder. | 398 | Support for the Techwell tw2804 multiple video decoder. |
| 434 | 399 | ||
| 435 | To compile this driver as a module, choose M here: the | 400 | To compile this driver as a module, choose M here: the |
| @@ -438,7 +403,7 @@ config VIDEO_TW2804 | |||
| 438 | config VIDEO_TW9903 | 403 | config VIDEO_TW9903 |
| 439 | tristate "Techwell TW9903 video decoder" | 404 | tristate "Techwell TW9903 video decoder" |
| 440 | depends on VIDEO_V4L2 && I2C | 405 | depends on VIDEO_V4L2 && I2C |
| 441 | ---help--- | 406 | help |
| 442 | Support for the Techwell tw9903 multi-standard video decoder | 407 | Support for the Techwell tw9903 multi-standard video decoder |
| 443 | with high quality down scaler. | 408 | with high quality down scaler. |
| 444 | 409 | ||
| @@ -448,7 +413,7 @@ config VIDEO_TW9903 | |||
| 448 | config VIDEO_TW9906 | 413 | config VIDEO_TW9906 |
| 449 | tristate "Techwell TW9906 video decoder" | 414 | tristate "Techwell TW9906 video decoder" |
| 450 | depends on VIDEO_V4L2 && I2C | 415 | depends on VIDEO_V4L2 && I2C |
| 451 | ---help--- | 416 | help |
| 452 | Support for the Techwell tw9906 enhanced multi-standard comb filter | 417 | Support for the Techwell tw9906 enhanced multi-standard comb filter |
| 453 | video decoder with YCbCr input support. | 418 | video decoder with YCbCr input support. |
| 454 | 419 | ||
| @@ -458,7 +423,7 @@ config VIDEO_TW9906 | |||
| 458 | config VIDEO_TW9910 | 423 | config VIDEO_TW9910 |
| 459 | tristate "Techwell TW9910 video decoder" | 424 | tristate "Techwell TW9910 video decoder" |
| 460 | depends on VIDEO_V4L2 && I2C | 425 | depends on VIDEO_V4L2 && I2C |
| 461 | ---help--- | 426 | help |
| 462 | Support for Techwell TW9910 NTSC/PAL/SECAM video decoder. | 427 | Support for Techwell TW9910 NTSC/PAL/SECAM video decoder. |
| 463 | 428 | ||
| 464 | To compile this driver as a module, choose M here: the | 429 | To compile this driver as a module, choose M here: the |
| @@ -467,7 +432,7 @@ config VIDEO_TW9910 | |||
| 467 | config VIDEO_VPX3220 | 432 | config VIDEO_VPX3220 |
| 468 | tristate "vpx3220a, vpx3216b & vpx3214c video decoders" | 433 | tristate "vpx3220a, vpx3216b & vpx3214c video decoders" |
| 469 | depends on VIDEO_V4L2 && I2C | 434 | depends on VIDEO_V4L2 && I2C |
| 470 | ---help--- | 435 | help |
| 471 | Support for VPX322x video decoders. | 436 | Support for VPX322x video decoders. |
| 472 | 437 | ||
| 473 | To compile this driver as a module, choose M here: the | 438 | To compile this driver as a module, choose M here: the |
| @@ -478,7 +443,7 @@ comment "Video and audio decoders" | |||
| 478 | config VIDEO_SAA717X | 443 | config VIDEO_SAA717X |
| 479 | tristate "Philips SAA7171/3/4 audio/video decoders" | 444 | tristate "Philips SAA7171/3/4 audio/video decoders" |
| 480 | depends on VIDEO_V4L2 && I2C | 445 | depends on VIDEO_V4L2 && I2C |
| 481 | ---help--- | 446 | help |
| 482 | Support for the Philips SAA7171/3/4 audio/video decoders. | 447 | Support for the Philips SAA7171/3/4 audio/video decoders. |
| 483 | 448 | ||
| 484 | To compile this driver as a module, choose M here: the | 449 | To compile this driver as a module, choose M here: the |
| @@ -491,7 +456,7 @@ comment "Video encoders" | |||
| 491 | config VIDEO_SAA7127 | 456 | config VIDEO_SAA7127 |
| 492 | tristate "Philips SAA7127/9 digital video encoders" | 457 | tristate "Philips SAA7127/9 digital video encoders" |
| 493 | depends on VIDEO_V4L2 && I2C | 458 | depends on VIDEO_V4L2 && I2C |
| 494 | ---help--- | 459 | help |
| 495 | Support for the Philips SAA7127/9 digital video encoders. | 460 | Support for the Philips SAA7127/9 digital video encoders. |
| 496 | 461 | ||
| 497 | To compile this driver as a module, choose M here: the | 462 | To compile this driver as a module, choose M here: the |
| @@ -500,7 +465,7 @@ config VIDEO_SAA7127 | |||
| 500 | config VIDEO_SAA7185 | 465 | config VIDEO_SAA7185 |
| 501 | tristate "Philips SAA7185 video encoder" | 466 | tristate "Philips SAA7185 video encoder" |
| 502 | depends on VIDEO_V4L2 && I2C | 467 | depends on VIDEO_V4L2 && I2C |
| 503 | ---help--- | 468 | help |
| 504 | Support for the Philips SAA7185 video encoder. | 469 | Support for the Philips SAA7185 video encoder. |
| 505 | 470 | ||
| 506 | To compile this driver as a module, choose M here: the | 471 | To compile this driver as a module, choose M here: the |
| @@ -509,7 +474,7 @@ config VIDEO_SAA7185 | |||
| 509 | config VIDEO_ADV7170 | 474 | config VIDEO_ADV7170 |
| 510 | tristate "Analog Devices ADV7170 video encoder" | 475 | tristate "Analog Devices ADV7170 video encoder" |
| 511 | depends on VIDEO_V4L2 && I2C | 476 | depends on VIDEO_V4L2 && I2C |
| 512 | ---help--- | 477 | help |
| 513 | Support for the Analog Devices ADV7170 video encoder driver | 478 | Support for the Analog Devices ADV7170 video encoder driver |
| 514 | 479 | ||
| 515 | To compile this driver as a module, choose M here: the | 480 | To compile this driver as a module, choose M here: the |
| @@ -518,7 +483,7 @@ config VIDEO_ADV7170 | |||
| 518 | config VIDEO_ADV7175 | 483 | config VIDEO_ADV7175 |
| 519 | tristate "Analog Devices ADV7175 video encoder" | 484 | tristate "Analog Devices ADV7175 video encoder" |
| 520 | depends on VIDEO_V4L2 && I2C | 485 | depends on VIDEO_V4L2 && I2C |
| 521 | ---help--- | 486 | help |
| 522 | Support for the Analog Devices ADV7175 video encoder driver | 487 | Support for the Analog Devices ADV7175 video encoder driver |
| 523 | 488 | ||
| 524 | To compile this driver as a module, choose M here: the | 489 | To compile this driver as a module, choose M here: the |
| @@ -546,7 +511,7 @@ config VIDEO_ADV7511 | |||
| 546 | tristate "Analog Devices ADV7511 encoder" | 511 | tristate "Analog Devices ADV7511 encoder" |
| 547 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 512 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 548 | select HDMI | 513 | select HDMI |
| 549 | ---help--- | 514 | help |
| 550 | Support for the Analog Devices ADV7511 video encoder. | 515 | Support for the Analog Devices ADV7511 video encoder. |
| 551 | 516 | ||
| 552 | This is a Analog Devices HDMI transmitter. | 517 | This is a Analog Devices HDMI transmitter. |
| @@ -558,14 +523,14 @@ config VIDEO_ADV7511_CEC | |||
| 558 | bool "Enable Analog Devices ADV7511 CEC support" | 523 | bool "Enable Analog Devices ADV7511 CEC support" |
| 559 | depends on VIDEO_ADV7511 | 524 | depends on VIDEO_ADV7511 |
| 560 | select CEC_CORE | 525 | select CEC_CORE |
| 561 | ---help--- | 526 | help |
| 562 | When selected the adv7511 will support the optional | 527 | When selected the adv7511 will support the optional |
| 563 | HDMI CEC feature. | 528 | HDMI CEC feature. |
| 564 | 529 | ||
| 565 | config VIDEO_AD9389B | 530 | config VIDEO_AD9389B |
| 566 | tristate "Analog Devices AD9389B encoder" | 531 | tristate "Analog Devices AD9389B encoder" |
| 567 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 532 | depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 568 | ---help--- | 533 | help |
| 569 | Support for the Analog Devices AD9389B video encoder. | 534 | Support for the Analog Devices AD9389B video encoder. |
| 570 | 535 | ||
| 571 | This is a Analog Devices HDMI transmitter. | 536 | This is a Analog Devices HDMI transmitter. |
| @@ -582,7 +547,7 @@ config VIDEO_AK881X | |||
| 582 | config VIDEO_THS8200 | 547 | config VIDEO_THS8200 |
| 583 | tristate "Texas Instruments THS8200 video encoder" | 548 | tristate "Texas Instruments THS8200 video encoder" |
| 584 | depends on VIDEO_V4L2 && I2C | 549 | depends on VIDEO_V4L2 && I2C |
| 585 | ---help--- | 550 | help |
| 586 | Support for the Texas Instruments THS8200 video encoder. | 551 | Support for the Texas Instruments THS8200 video encoder. |
| 587 | 552 | ||
| 588 | To compile this driver as a module, choose M here: the | 553 | To compile this driver as a module, choose M here: the |
| @@ -612,7 +577,7 @@ config VIDEO_IMX258 | |||
| 612 | tristate "Sony IMX258 sensor support" | 577 | tristate "Sony IMX258 sensor support" |
| 613 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 578 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 614 | depends on MEDIA_CAMERA_SUPPORT | 579 | depends on MEDIA_CAMERA_SUPPORT |
| 615 | ---help--- | 580 | help |
| 616 | This is a Video4Linux2 sensor driver for the Sony | 581 | This is a Video4Linux2 sensor driver for the Sony |
| 617 | IMX258 camera. | 582 | IMX258 camera. |
| 618 | 583 | ||
| @@ -624,7 +589,7 @@ config VIDEO_IMX274 | |||
| 624 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 589 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 625 | depends on MEDIA_CAMERA_SUPPORT | 590 | depends on MEDIA_CAMERA_SUPPORT |
| 626 | select REGMAP_I2C | 591 | select REGMAP_I2C |
| 627 | ---help--- | 592 | help |
| 628 | This is a V4L2 sensor driver for the Sony IMX274 | 593 | This is a V4L2 sensor driver for the Sony IMX274 |
| 629 | CMOS image sensor. | 594 | CMOS image sensor. |
| 630 | 595 | ||
| @@ -666,7 +631,7 @@ config VIDEO_OV2659 | |||
| 666 | depends on VIDEO_V4L2 && I2C | 631 | depends on VIDEO_V4L2 && I2C |
| 667 | depends on MEDIA_CAMERA_SUPPORT | 632 | depends on MEDIA_CAMERA_SUPPORT |
| 668 | select V4L2_FWNODE | 633 | select V4L2_FWNODE |
| 669 | ---help--- | 634 | help |
| 670 | This is a Video4Linux2 sensor driver for the OmniVision | 635 | This is a Video4Linux2 sensor driver for the OmniVision |
| 671 | OV2659 camera. | 636 | OV2659 camera. |
| 672 | 637 | ||
| @@ -678,7 +643,7 @@ config VIDEO_OV2680 | |||
| 678 | depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER | 643 | depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER |
| 679 | depends on MEDIA_CAMERA_SUPPORT | 644 | depends on MEDIA_CAMERA_SUPPORT |
| 680 | select V4L2_FWNODE | 645 | select V4L2_FWNODE |
| 681 | ---help--- | 646 | help |
| 682 | This is a Video4Linux2 sensor driver for the OmniVision | 647 | This is a Video4Linux2 sensor driver for the OmniVision |
| 683 | OV2680 camera. | 648 | OV2680 camera. |
| 684 | 649 | ||
| @@ -690,7 +655,7 @@ config VIDEO_OV2685 | |||
| 690 | depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER | 655 | depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER |
| 691 | depends on MEDIA_CAMERA_SUPPORT | 656 | depends on MEDIA_CAMERA_SUPPORT |
| 692 | select V4L2_FWNODE | 657 | select V4L2_FWNODE |
| 693 | ---help--- | 658 | help |
| 694 | This is a Video4Linux2 sensor driver for the OmniVision | 659 | This is a Video4Linux2 sensor driver for the OmniVision |
| 695 | OV2685 camera. | 660 | OV2685 camera. |
| 696 | 661 | ||
| @@ -703,7 +668,7 @@ config VIDEO_OV5640 | |||
| 703 | depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API | 668 | depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API |
| 704 | depends on MEDIA_CAMERA_SUPPORT | 669 | depends on MEDIA_CAMERA_SUPPORT |
| 705 | select V4L2_FWNODE | 670 | select V4L2_FWNODE |
| 706 | ---help--- | 671 | help |
| 707 | This is a Video4Linux2 sensor driver for the Omnivision | 672 | This is a Video4Linux2 sensor driver for the Omnivision |
| 708 | OV5640 camera sensor with a MIPI CSI-2 interface. | 673 | OV5640 camera sensor with a MIPI CSI-2 interface. |
| 709 | 674 | ||
| @@ -713,7 +678,7 @@ config VIDEO_OV5645 | |||
| 713 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 678 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 714 | depends on MEDIA_CAMERA_SUPPORT | 679 | depends on MEDIA_CAMERA_SUPPORT |
| 715 | select V4L2_FWNODE | 680 | select V4L2_FWNODE |
| 716 | ---help--- | 681 | help |
| 717 | This is a Video4Linux2 sensor driver for the OmniVision | 682 | This is a Video4Linux2 sensor driver for the OmniVision |
| 718 | OV5645 camera. | 683 | OV5645 camera. |
| 719 | 684 | ||
| @@ -725,7 +690,7 @@ config VIDEO_OV5647 | |||
| 725 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 690 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 726 | depends on MEDIA_CAMERA_SUPPORT | 691 | depends on MEDIA_CAMERA_SUPPORT |
| 727 | select V4L2_FWNODE | 692 | select V4L2_FWNODE |
| 728 | ---help--- | 693 | help |
| 729 | This is a Video4Linux2 sensor driver for the OmniVision | 694 | This is a Video4Linux2 sensor driver for the OmniVision |
| 730 | OV5647 camera. | 695 | OV5647 camera. |
| 731 | 696 | ||
| @@ -736,7 +701,7 @@ config VIDEO_OV6650 | |||
| 736 | tristate "OmniVision OV6650 sensor support" | 701 | tristate "OmniVision OV6650 sensor support" |
| 737 | depends on I2C && VIDEO_V4L2 | 702 | depends on I2C && VIDEO_V4L2 |
| 738 | depends on MEDIA_CAMERA_SUPPORT | 703 | depends on MEDIA_CAMERA_SUPPORT |
| 739 | ---help--- | 704 | help |
| 740 | This is a Video4Linux2 sensor driver for the OmniVision | 705 | This is a Video4Linux2 sensor driver for the OmniVision |
| 741 | OV6650 camera. | 706 | OV6650 camera. |
| 742 | 707 | ||
| @@ -749,7 +714,7 @@ config VIDEO_OV5670 | |||
| 749 | depends on MEDIA_CAMERA_SUPPORT | 714 | depends on MEDIA_CAMERA_SUPPORT |
| 750 | depends on MEDIA_CONTROLLER | 715 | depends on MEDIA_CONTROLLER |
| 751 | select V4L2_FWNODE | 716 | select V4L2_FWNODE |
| 752 | ---help--- | 717 | help |
| 753 | This is a Video4Linux2 sensor driver for the OmniVision | 718 | This is a Video4Linux2 sensor driver for the OmniVision |
| 754 | OV5670 camera. | 719 | OV5670 camera. |
| 755 | 720 | ||
| @@ -760,7 +725,7 @@ config VIDEO_OV5695 | |||
| 760 | tristate "OmniVision OV5695 sensor support" | 725 | tristate "OmniVision OV5695 sensor support" |
| 761 | depends on I2C && VIDEO_V4L2 | 726 | depends on I2C && VIDEO_V4L2 |
| 762 | depends on MEDIA_CAMERA_SUPPORT | 727 | depends on MEDIA_CAMERA_SUPPORT |
| 763 | ---help--- | 728 | help |
| 764 | This is a Video4Linux2 sensor driver for the OmniVision | 729 | This is a Video4Linux2 sensor driver for the OmniVision |
| 765 | OV5695 camera. | 730 | OV5695 camera. |
| 766 | 731 | ||
| @@ -784,7 +749,7 @@ config VIDEO_OV772X | |||
| 784 | depends on I2C && VIDEO_V4L2 | 749 | depends on I2C && VIDEO_V4L2 |
| 785 | depends on MEDIA_CAMERA_SUPPORT | 750 | depends on MEDIA_CAMERA_SUPPORT |
| 786 | select REGMAP_SCCB | 751 | select REGMAP_SCCB |
| 787 | ---help--- | 752 | help |
| 788 | This is a Video4Linux2 sensor driver for the OmniVision | 753 | This is a Video4Linux2 sensor driver for the OmniVision |
| 789 | OV772x camera. | 754 | OV772x camera. |
| 790 | 755 | ||
| @@ -795,7 +760,7 @@ config VIDEO_OV7640 | |||
| 795 | tristate "OmniVision OV7640 sensor support" | 760 | tristate "OmniVision OV7640 sensor support" |
| 796 | depends on I2C && VIDEO_V4L2 | 761 | depends on I2C && VIDEO_V4L2 |
| 797 | depends on MEDIA_CAMERA_SUPPORT | 762 | depends on MEDIA_CAMERA_SUPPORT |
| 798 | ---help--- | 763 | help |
| 799 | This is a Video4Linux2 sensor driver for the OmniVision | 764 | This is a Video4Linux2 sensor driver for the OmniVision |
| 800 | OV7640 camera. | 765 | OV7640 camera. |
| 801 | 766 | ||
| @@ -807,7 +772,7 @@ config VIDEO_OV7670 | |||
| 807 | depends on I2C && VIDEO_V4L2 | 772 | depends on I2C && VIDEO_V4L2 |
| 808 | depends on MEDIA_CAMERA_SUPPORT | 773 | depends on MEDIA_CAMERA_SUPPORT |
| 809 | select V4L2_FWNODE | 774 | select V4L2_FWNODE |
| 810 | ---help--- | 775 | help |
| 811 | This is a Video4Linux2 sensor driver for the OmniVision | 776 | This is a Video4Linux2 sensor driver for the OmniVision |
| 812 | OV7670 VGA camera. It currently only works with the M88ALP01 | 777 | OV7670 VGA camera. It currently only works with the M88ALP01 |
| 813 | controller. | 778 | controller. |
| @@ -816,7 +781,7 @@ config VIDEO_OV7740 | |||
| 816 | tristate "OmniVision OV7740 sensor support" | 781 | tristate "OmniVision OV7740 sensor support" |
| 817 | depends on I2C && VIDEO_V4L2 | 782 | depends on I2C && VIDEO_V4L2 |
| 818 | depends on MEDIA_CAMERA_SUPPORT | 783 | depends on MEDIA_CAMERA_SUPPORT |
| 819 | ---help--- | 784 | help |
| 820 | This is a Video4Linux2 sensor driver for the OmniVision | 785 | This is a Video4Linux2 sensor driver for the OmniVision |
| 821 | OV7740 VGA camera sensor. | 786 | OV7740 VGA camera sensor. |
| 822 | 787 | ||
| @@ -843,7 +808,7 @@ config VIDEO_OV9650 | |||
| 843 | tristate "OmniVision OV9650/OV9652 sensor support" | 808 | tristate "OmniVision OV9650/OV9652 sensor support" |
| 844 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 809 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 845 | select REGMAP_SCCB | 810 | select REGMAP_SCCB |
| 846 | ---help--- | 811 | help |
| 847 | This is a V4L2 sensor driver for the Omnivision | 812 | This is a V4L2 sensor driver for the Omnivision |
| 848 | OV9650 and OV9652 camera sensors. | 813 | OV9650 and OV9652 camera sensors. |
| 849 | 814 | ||
| @@ -852,7 +817,7 @@ config VIDEO_OV13858 | |||
| 852 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 817 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 853 | depends on MEDIA_CAMERA_SUPPORT | 818 | depends on MEDIA_CAMERA_SUPPORT |
| 854 | select V4L2_FWNODE | 819 | select V4L2_FWNODE |
| 855 | ---help--- | 820 | help |
| 856 | This is a Video4Linux2 sensor driver for the OmniVision | 821 | This is a Video4Linux2 sensor driver for the OmniVision |
| 857 | OV13858 camera. | 822 | OV13858 camera. |
| 858 | 823 | ||
| @@ -860,7 +825,7 @@ config VIDEO_VS6624 | |||
| 860 | tristate "ST VS6624 sensor support" | 825 | tristate "ST VS6624 sensor support" |
| 861 | depends on VIDEO_V4L2 && I2C | 826 | depends on VIDEO_V4L2 && I2C |
| 862 | depends on MEDIA_CAMERA_SUPPORT | 827 | depends on MEDIA_CAMERA_SUPPORT |
| 863 | ---help--- | 828 | help |
| 864 | This is a Video4Linux2 sensor driver for the ST VS6624 | 829 | This is a Video4Linux2 sensor driver for the ST VS6624 |
| 865 | camera. | 830 | camera. |
| 866 | 831 | ||
| @@ -880,7 +845,7 @@ config VIDEO_MT9M032 | |||
| 880 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 845 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 881 | depends on MEDIA_CAMERA_SUPPORT | 846 | depends on MEDIA_CAMERA_SUPPORT |
| 882 | select VIDEO_APTINA_PLL | 847 | select VIDEO_APTINA_PLL |
| 883 | ---help--- | 848 | help |
| 884 | This driver supports MT9M032 camera sensors from Aptina, monochrome | 849 | This driver supports MT9M032 camera sensors from Aptina, monochrome |
| 885 | models only. | 850 | models only. |
| 886 | 851 | ||
| @@ -897,7 +862,7 @@ config VIDEO_MT9P031 | |||
| 897 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 862 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 898 | depends on MEDIA_CAMERA_SUPPORT | 863 | depends on MEDIA_CAMERA_SUPPORT |
| 899 | select VIDEO_APTINA_PLL | 864 | select VIDEO_APTINA_PLL |
| 900 | ---help--- | 865 | help |
| 901 | This is a Video4Linux2 sensor driver for the Aptina | 866 | This is a Video4Linux2 sensor driver for the Aptina |
| 902 | (Micron) mt9p031 5 Mpixel camera. | 867 | (Micron) mt9p031 5 Mpixel camera. |
| 903 | 868 | ||
| @@ -905,7 +870,7 @@ config VIDEO_MT9T001 | |||
| 905 | tristate "Aptina MT9T001 support" | 870 | tristate "Aptina MT9T001 support" |
| 906 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 871 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 907 | depends on MEDIA_CAMERA_SUPPORT | 872 | depends on MEDIA_CAMERA_SUPPORT |
| 908 | ---help--- | 873 | help |
| 909 | This is a Video4Linux2 sensor driver for the Aptina | 874 | This is a Video4Linux2 sensor driver for the Aptina |
| 910 | (Micron) mt0t001 3 Mpixel camera. | 875 | (Micron) mt0t001 3 Mpixel camera. |
| 911 | 876 | ||
| @@ -913,7 +878,7 @@ config VIDEO_MT9T112 | |||
| 913 | tristate "Aptina MT9T111/MT9T112 support" | 878 | tristate "Aptina MT9T111/MT9T112 support" |
| 914 | depends on I2C && VIDEO_V4L2 | 879 | depends on I2C && VIDEO_V4L2 |
| 915 | depends on MEDIA_CAMERA_SUPPORT | 880 | depends on MEDIA_CAMERA_SUPPORT |
| 916 | ---help--- | 881 | help |
| 917 | This is a Video4Linux2 sensor driver for the Aptina | 882 | This is a Video4Linux2 sensor driver for the Aptina |
| 918 | (Micron) MT9T111 and MT9T112 3 Mpixel camera. | 883 | (Micron) MT9T111 and MT9T112 3 Mpixel camera. |
| 919 | 884 | ||
| @@ -924,7 +889,7 @@ config VIDEO_MT9V011 | |||
| 924 | tristate "Micron mt9v011 sensor support" | 889 | tristate "Micron mt9v011 sensor support" |
| 925 | depends on I2C && VIDEO_V4L2 | 890 | depends on I2C && VIDEO_V4L2 |
| 926 | depends on MEDIA_CAMERA_SUPPORT | 891 | depends on MEDIA_CAMERA_SUPPORT |
| 927 | ---help--- | 892 | help |
| 928 | This is a Video4Linux2 sensor driver for the Micron | 893 | This is a Video4Linux2 sensor driver for the Micron |
| 929 | mt0v011 1.3 Mpixel camera. It currently only works with the | 894 | mt0v011 1.3 Mpixel camera. It currently only works with the |
| 930 | em28xx driver. | 895 | em28xx driver. |
| @@ -935,7 +900,7 @@ config VIDEO_MT9V032 | |||
| 935 | depends on MEDIA_CAMERA_SUPPORT | 900 | depends on MEDIA_CAMERA_SUPPORT |
| 936 | select REGMAP_I2C | 901 | select REGMAP_I2C |
| 937 | select V4L2_FWNODE | 902 | select V4L2_FWNODE |
| 938 | ---help--- | 903 | help |
| 939 | This is a Video4Linux2 sensor driver for the Micron | 904 | This is a Video4Linux2 sensor driver for the Micron |
| 940 | MT9V032 752x480 CMOS sensor. | 905 | MT9V032 752x480 CMOS sensor. |
| 941 | 906 | ||
| @@ -954,14 +919,14 @@ config VIDEO_SR030PC30 | |||
| 954 | tristate "Siliconfile SR030PC30 sensor support" | 919 | tristate "Siliconfile SR030PC30 sensor support" |
| 955 | depends on I2C && VIDEO_V4L2 | 920 | depends on I2C && VIDEO_V4L2 |
| 956 | depends on MEDIA_CAMERA_SUPPORT | 921 | depends on MEDIA_CAMERA_SUPPORT |
| 957 | ---help--- | 922 | help |
| 958 | This driver supports SR030PC30 VGA camera from Siliconfile | 923 | This driver supports SR030PC30 VGA camera from Siliconfile |
| 959 | 924 | ||
| 960 | config VIDEO_NOON010PC30 | 925 | config VIDEO_NOON010PC30 |
| 961 | tristate "Siliconfile NOON010PC30 sensor support" | 926 | tristate "Siliconfile NOON010PC30 sensor support" |
| 962 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 927 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 963 | depends on MEDIA_CAMERA_SUPPORT | 928 | depends on MEDIA_CAMERA_SUPPORT |
| 964 | ---help--- | 929 | help |
| 965 | This driver supports NOON010PC30 CIF camera from Siliconfile | 930 | This driver supports NOON010PC30 CIF camera from Siliconfile |
| 966 | 931 | ||
| 967 | source "drivers/media/i2c/m5mols/Kconfig" | 932 | source "drivers/media/i2c/m5mols/Kconfig" |
| @@ -981,7 +946,7 @@ config VIDEO_S5K6AA | |||
| 981 | tristate "Samsung S5K6AAFX sensor support" | 946 | tristate "Samsung S5K6AAFX sensor support" |
| 982 | depends on MEDIA_CAMERA_SUPPORT | 947 | depends on MEDIA_CAMERA_SUPPORT |
| 983 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 948 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 984 | ---help--- | 949 | help |
| 985 | This is a V4L2 sensor driver for Samsung S5K6AA(FX) 1.3M | 950 | This is a V4L2 sensor driver for Samsung S5K6AA(FX) 1.3M |
| 986 | camera sensor with an embedded SoC image signal processor. | 951 | camera sensor with an embedded SoC image signal processor. |
| 987 | 952 | ||
| @@ -989,7 +954,7 @@ config VIDEO_S5K6A3 | |||
| 989 | tristate "Samsung S5K6A3 sensor support" | 954 | tristate "Samsung S5K6A3 sensor support" |
| 990 | depends on MEDIA_CAMERA_SUPPORT | 955 | depends on MEDIA_CAMERA_SUPPORT |
| 991 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 956 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 992 | ---help--- | 957 | help |
| 993 | This is a V4L2 sensor driver for Samsung S5K6A3 raw | 958 | This is a V4L2 sensor driver for Samsung S5K6A3 raw |
| 994 | camera sensor. | 959 | camera sensor. |
| 995 | 960 | ||
| @@ -997,7 +962,7 @@ config VIDEO_S5K4ECGX | |||
| 997 | tristate "Samsung S5K4ECGX sensor support" | 962 | tristate "Samsung S5K4ECGX sensor support" |
| 998 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 963 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 999 | select CRC32 | 964 | select CRC32 |
| 1000 | ---help--- | 965 | help |
| 1001 | This is a V4L2 sensor driver for Samsung S5K4ECGX 5M | 966 | This is a V4L2 sensor driver for Samsung S5K4ECGX 5M |
| 1002 | camera sensor with an embedded SoC image signal processor. | 967 | camera sensor with an embedded SoC image signal processor. |
| 1003 | 968 | ||
| @@ -1005,7 +970,7 @@ config VIDEO_S5K5BAF | |||
| 1005 | tristate "Samsung S5K5BAF sensor support" | 970 | tristate "Samsung S5K5BAF sensor support" |
| 1006 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 971 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 1007 | select V4L2_FWNODE | 972 | select V4L2_FWNODE |
| 1008 | ---help--- | 973 | help |
| 1009 | This is a V4L2 sensor driver for Samsung S5K5BAF 2M | 974 | This is a V4L2 sensor driver for Samsung S5K5BAF 2M |
| 1010 | camera sensor with an embedded SoC image signal processor. | 975 | camera sensor with an embedded SoC image signal processor. |
| 1011 | 976 | ||
| @@ -1016,17 +981,56 @@ config VIDEO_S5C73M3 | |||
| 1016 | tristate "Samsung S5C73M3 sensor support" | 981 | tristate "Samsung S5C73M3 sensor support" |
| 1017 | depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 982 | depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 1018 | select V4L2_FWNODE | 983 | select V4L2_FWNODE |
| 1019 | ---help--- | 984 | help |
| 1020 | This is a V4L2 sensor driver for Samsung S5C73M3 | 985 | This is a V4L2 sensor driver for Samsung S5C73M3 |
| 1021 | 8 Mpixel camera. | 986 | 8 Mpixel camera. |
| 1022 | 987 | ||
| 988 | comment "Lens drivers" | ||
| 989 | |||
| 990 | config VIDEO_AD5820 | ||
| 991 | tristate "AD5820 lens voice coil support" | ||
| 992 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 993 | help | ||
| 994 | This is a driver for the AD5820 camera lens voice coil. | ||
| 995 | It is used for example in Nokia N900 (RX-51). | ||
| 996 | |||
| 997 | config VIDEO_AK7375 | ||
| 998 | tristate "AK7375 lens voice coil support" | ||
| 999 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 1000 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 1001 | help | ||
| 1002 | This is a driver for the AK7375 camera lens voice coil. | ||
| 1003 | AK7375 is a 12 bit DAC with 120mA output current sink | ||
| 1004 | capability. This is designed for linear control of | ||
| 1005 | voice coil motors, controlled via I2C serial interface. | ||
| 1006 | |||
| 1007 | config VIDEO_DW9714 | ||
| 1008 | tristate "DW9714 lens voice coil support" | ||
| 1009 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 1010 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 1011 | help | ||
| 1012 | This is a driver for the DW9714 camera lens voice coil. | ||
| 1013 | DW9714 is a 10 bit DAC with 120mA output current sink | ||
| 1014 | capability. This is designed for linear control of | ||
| 1015 | voice coil motors, controlled via I2C serial interface. | ||
| 1016 | |||
| 1017 | config VIDEO_DW9807_VCM | ||
| 1018 | tristate "DW9807 lens voice coil support" | ||
| 1019 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | ||
| 1020 | depends on VIDEO_V4L2_SUBDEV_API | ||
| 1021 | help | ||
| 1022 | This is a driver for the DW9807 camera lens voice coil. | ||
| 1023 | DW9807 is a 10 bit DAC with 100mA output current sink | ||
| 1024 | capability. This is designed for linear control of | ||
| 1025 | voice coil motors, controlled via I2C serial interface. | ||
| 1026 | |||
| 1023 | comment "Flash devices" | 1027 | comment "Flash devices" |
| 1024 | 1028 | ||
| 1025 | config VIDEO_ADP1653 | 1029 | config VIDEO_ADP1653 |
| 1026 | tristate "ADP1653 flash support" | 1030 | tristate "ADP1653 flash support" |
| 1027 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | 1031 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER |
| 1028 | depends on MEDIA_CAMERA_SUPPORT | 1032 | depends on MEDIA_CAMERA_SUPPORT |
| 1029 | ---help--- | 1033 | help |
| 1030 | This is a driver for the ADP1653 flash controller. It is used for | 1034 | This is a driver for the ADP1653 flash controller. It is used for |
| 1031 | example in Nokia N900. | 1035 | example in Nokia N900. |
| 1032 | 1036 | ||
| @@ -1035,7 +1039,7 @@ config VIDEO_LM3560 | |||
| 1035 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | 1039 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER |
| 1036 | depends on MEDIA_CAMERA_SUPPORT | 1040 | depends on MEDIA_CAMERA_SUPPORT |
| 1037 | select REGMAP_I2C | 1041 | select REGMAP_I2C |
| 1038 | ---help--- | 1042 | help |
| 1039 | This is a driver for the lm3560 dual flash controllers. It controls | 1043 | This is a driver for the lm3560 dual flash controllers. It controls |
| 1040 | flash, torch LEDs. | 1044 | flash, torch LEDs. |
| 1041 | 1045 | ||
| @@ -1044,7 +1048,7 @@ config VIDEO_LM3646 | |||
| 1044 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER | 1048 | depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER |
| 1045 | depends on MEDIA_CAMERA_SUPPORT | 1049 | depends on MEDIA_CAMERA_SUPPORT |
| 1046 | select REGMAP_I2C | 1050 | select REGMAP_I2C |
| 1047 | ---help--- | 1051 | help |
| 1048 | This is a driver for the lm3646 dual flash controllers. It controls | 1052 | This is a driver for the lm3646 dual flash controllers. It controls |
| 1049 | flash, torch LEDs. | 1053 | flash, torch LEDs. |
| 1050 | 1054 | ||
| @@ -1053,7 +1057,7 @@ comment "Video improvement chips" | |||
| 1053 | config VIDEO_UPD64031A | 1057 | config VIDEO_UPD64031A |
| 1054 | tristate "NEC Electronics uPD64031A Ghost Reduction" | 1058 | tristate "NEC Electronics uPD64031A Ghost Reduction" |
| 1055 | depends on VIDEO_V4L2 && I2C | 1059 | depends on VIDEO_V4L2 && I2C |
| 1056 | ---help--- | 1060 | help |
| 1057 | Support for the NEC Electronics uPD64031A Ghost Reduction | 1061 | Support for the NEC Electronics uPD64031A Ghost Reduction |
| 1058 | video chip. It is most often found in NTSC TV cards made for | 1062 | video chip. It is most often found in NTSC TV cards made for |
| 1059 | Japan and is used to reduce the 'ghosting' effect that can | 1063 | Japan and is used to reduce the 'ghosting' effect that can |
| @@ -1065,7 +1069,7 @@ config VIDEO_UPD64031A | |||
| 1065 | config VIDEO_UPD64083 | 1069 | config VIDEO_UPD64083 |
| 1066 | tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation" | 1070 | tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation" |
| 1067 | depends on VIDEO_V4L2 && I2C | 1071 | depends on VIDEO_V4L2 && I2C |
| 1068 | ---help--- | 1072 | help |
| 1069 | Support for the NEC Electronics uPD64083 3-Dimensional Y/C | 1073 | Support for the NEC Electronics uPD64083 3-Dimensional Y/C |
| 1070 | separation video chip. It is used to improve the quality of | 1074 | separation video chip. It is used to improve the quality of |
| 1071 | the colors of a composite signal. | 1075 | the colors of a composite signal. |
| @@ -1079,7 +1083,7 @@ config VIDEO_SAA6752HS | |||
| 1079 | tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder" | 1083 | tristate "Philips SAA6752HS MPEG-2 Audio/Video Encoder" |
| 1080 | depends on VIDEO_V4L2 && I2C | 1084 | depends on VIDEO_V4L2 && I2C |
| 1081 | select CRC32 | 1085 | select CRC32 |
| 1082 | ---help--- | 1086 | help |
| 1083 | Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3 | 1087 | Support for the Philips SAA6752HS MPEG-2 video and MPEG-audio/AC-3 |
| 1084 | audio encoder with multiplexer. | 1088 | audio encoder with multiplexer. |
| 1085 | 1089 | ||
| @@ -1091,7 +1095,7 @@ comment "SDR tuner chips" | |||
| 1091 | config SDR_MAX2175 | 1095 | config SDR_MAX2175 |
| 1092 | tristate "Maxim 2175 RF to Bits tuner" | 1096 | tristate "Maxim 2175 RF to Bits tuner" |
| 1093 | depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C | 1097 | depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C |
| 1094 | ---help--- | 1098 | help |
| 1095 | Support for Maxim 2175 tuner. It is an advanced analog/digital | 1099 | Support for Maxim 2175 tuner. It is an advanced analog/digital |
| 1096 | radio receiver with RF-to-Bits front-end designed for SDR solutions. | 1100 | radio receiver with RF-to-Bits front-end designed for SDR solutions. |
| 1097 | 1101 | ||
| @@ -1112,7 +1116,7 @@ config VIDEO_THS7303 | |||
| 1112 | config VIDEO_M52790 | 1116 | config VIDEO_M52790 |
| 1113 | tristate "Mitsubishi M52790 A/V switch" | 1117 | tristate "Mitsubishi M52790 A/V switch" |
| 1114 | depends on VIDEO_V4L2 && I2C | 1118 | depends on VIDEO_V4L2 && I2C |
| 1115 | ---help--- | 1119 | help |
| 1116 | Support for the Mitsubishi M52790 A/V switch. | 1120 | Support for the Mitsubishi M52790 A/V switch. |
| 1117 | 1121 | ||
| 1118 | To compile this driver as a module, choose M here: the | 1122 | To compile this driver as a module, choose M here: the |
| @@ -1123,7 +1127,7 @@ config VIDEO_I2C | |||
| 1123 | depends on VIDEO_V4L2 && I2C | 1127 | depends on VIDEO_V4L2 && I2C |
| 1124 | select VIDEOBUF2_VMALLOC | 1128 | select VIDEOBUF2_VMALLOC |
| 1125 | imply HWMON | 1129 | imply HWMON |
| 1126 | ---help--- | 1130 | help |
| 1127 | Enable the I2C transport video support which supports the | 1131 | Enable the I2C transport video support which supports the |
| 1128 | following: | 1132 | following: |
| 1129 | * Panasonic AMG88xx Grid-Eye Sensors | 1133 | * Panasonic AMG88xx Grid-Eye Sensors |
| @@ -1132,6 +1136,19 @@ config VIDEO_I2C | |||
| 1132 | To compile this driver as a module, choose M here: the | 1136 | To compile this driver as a module, choose M here: the |
| 1133 | module will be called video-i2c | 1137 | module will be called video-i2c |
| 1134 | 1138 | ||
| 1139 | config VIDEO_ST_MIPID02 | ||
| 1140 | tristate "STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge" | ||
| 1141 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | ||
| 1142 | depends on MEDIA_CAMERA_SUPPORT | ||
| 1143 | select V4L2_FWNODE | ||
| 1144 | help | ||
| 1145 | Support for STMicroelectronics MIPID02 CSI-2 to PARALLEL bridge. | ||
| 1146 | It is used to allow usage of CSI-2 sensor with PARALLEL port | ||
| 1147 | controller. | ||
| 1148 | |||
| 1149 | To compile this driver as a module, choose M here: the | ||
| 1150 | module will be called st-mipid02. | ||
| 1151 | |||
| 1135 | endmenu | 1152 | endmenu |
| 1136 | 1153 | ||
| 1137 | endif | 1154 | endif |
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index a64fca82e0c4..d8ad9dad495d 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile | |||
| @@ -113,5 +113,6 @@ obj-$(CONFIG_VIDEO_IMX258) += imx258.o | |||
| 113 | obj-$(CONFIG_VIDEO_IMX274) += imx274.o | 113 | obj-$(CONFIG_VIDEO_IMX274) += imx274.o |
| 114 | obj-$(CONFIG_VIDEO_IMX319) += imx319.o | 114 | obj-$(CONFIG_VIDEO_IMX319) += imx319.o |
| 115 | obj-$(CONFIG_VIDEO_IMX355) += imx355.o | 115 | obj-$(CONFIG_VIDEO_IMX355) += imx355.o |
| 116 | obj-$(CONFIG_VIDEO_ST_MIPID02) += st-mipid02.o | ||
| 116 | 117 | ||
| 117 | obj-$(CONFIG_SDR_MAX2175) += max2175.o | 118 | obj-$(CONFIG_SDR_MAX2175) += max2175.o |
diff --git a/drivers/media/i2c/cx25840/Kconfig b/drivers/media/i2c/cx25840/Kconfig index 451133ad41ff..f4b31d7cb440 100644 --- a/drivers/media/i2c/cx25840/Kconfig +++ b/drivers/media/i2c/cx25840/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config VIDEO_CX25840 | 1 | config VIDEO_CX25840 |
| 2 | tristate "Conexant CX2584x audio/video decoders" | 2 | tristate "Conexant CX2584x audio/video decoders" |
| 3 | depends on VIDEO_V4L2 && I2C | 3 | depends on VIDEO_V4L2 && I2C |
| 4 | ---help--- | 4 | help |
| 5 | Support for the Conexant CX2584x audio/video decoders. | 5 | Support for the Conexant CX2584x audio/video decoders. |
| 6 | 6 | ||
| 7 | To compile this driver as a module, choose M here: the | 7 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/i2c/et8ek8/Kconfig b/drivers/media/i2c/et8ek8/Kconfig index 9fe409e95666..ab23b41bf353 100644 --- a/drivers/media/i2c/et8ek8/Kconfig +++ b/drivers/media/i2c/et8ek8/Kconfig | |||
| @@ -2,6 +2,6 @@ config VIDEO_ET8EK8 | |||
| 2 | tristate "ET8EK8 camera sensor support" | 2 | tristate "ET8EK8 camera sensor support" |
| 3 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 3 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 4 | select V4L2_FWNODE | 4 | select V4L2_FWNODE |
| 5 | ---help--- | 5 | help |
| 6 | This is a driver for the Toshiba ET8EK8 5 MP camera sensor. | 6 | This is a driver for the Toshiba ET8EK8 5 MP camera sensor. |
| 7 | It is used for example in Nokia N900 (RX-51). | 7 | It is used for example in Nokia N900 (RX-51). |
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 9857e151db46..83e9961b0505 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c | |||
| @@ -588,12 +588,10 @@ static int imx214_set_format(struct v4l2_subdev *sd, | |||
| 588 | 588 | ||
| 589 | __crop = __imx214_get_pad_crop(imx214, cfg, format->pad, format->which); | 589 | __crop = __imx214_get_pad_crop(imx214, cfg, format->pad, format->which); |
| 590 | 590 | ||
| 591 | if (format) | 591 | mode = v4l2_find_nearest_size(imx214_modes, |
| 592 | mode = v4l2_find_nearest_size(imx214_modes, | 592 | ARRAY_SIZE(imx214_modes), width, height, |
| 593 | ARRAY_SIZE(imx214_modes), width, height, | 593 | format->format.width, |
| 594 | format->format.width, format->format.height); | 594 | format->format.height); |
| 595 | else | ||
| 596 | mode = &imx214_modes[0]; | ||
| 597 | 595 | ||
| 598 | __crop->width = mode->width; | 596 | __crop->width = mode->width; |
| 599 | __crop->height = mode->height; | 597 | __crop->height = mode->height; |
diff --git a/drivers/media/i2c/m5mols/Kconfig b/drivers/media/i2c/m5mols/Kconfig index dc8c2505907e..be0bb3f1bc22 100644 --- a/drivers/media/i2c/m5mols/Kconfig +++ b/drivers/media/i2c/m5mols/Kconfig | |||
| @@ -2,5 +2,5 @@ config VIDEO_M5MOLS | |||
| 2 | tristate "Fujitsu M-5MOLS 8MP sensor support" | 2 | tristate "Fujitsu M-5MOLS 8MP sensor support" |
| 3 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 3 | depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 4 | depends on MEDIA_CAMERA_SUPPORT | 4 | depends on MEDIA_CAMERA_SUPPORT |
| 5 | ---help--- | 5 | help |
| 6 | This driver supports Fujitsu M-5MOLS camera sensor with ISP | 6 | This driver supports Fujitsu M-5MOLS camera sensor with ISP |
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 799acce803fe..5ed2413eac8a 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c | |||
| @@ -1117,8 +1117,10 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, | |||
| 1117 | if (ov2659_formats[index].code == mf->code) | 1117 | if (ov2659_formats[index].code == mf->code) |
| 1118 | break; | 1118 | break; |
| 1119 | 1119 | ||
| 1120 | if (index < 0) | 1120 | if (index < 0) { |
| 1121 | return -EINVAL; | 1121 | index = 0; |
| 1122 | mf->code = ov2659_formats[index].code; | ||
| 1123 | } | ||
| 1122 | 1124 | ||
| 1123 | mf->colorspace = V4L2_COLORSPACE_SRGB; | 1125 | mf->colorspace = V4L2_COLORSPACE_SRGB; |
| 1124 | mf->field = V4L2_FIELD_NONE; | 1126 | mf->field = V4L2_FIELD_NONE; |
| @@ -1130,7 +1132,7 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, | |||
| 1130 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); | 1132 | mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); |
| 1131 | *mf = fmt->format; | 1133 | *mf = fmt->format; |
| 1132 | #else | 1134 | #else |
| 1133 | return -ENOTTY; | 1135 | ret = -ENOTTY; |
| 1134 | #endif | 1136 | #endif |
| 1135 | } else { | 1137 | } else { |
| 1136 | s64 val; | 1138 | s64 val; |
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index c33fd584cb44..1b972e591b48 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c | |||
| @@ -804,15 +804,25 @@ static int ov6650_prog_dflt(struct i2c_client *client) | |||
| 804 | return ret; | 804 | return ret; |
| 805 | } | 805 | } |
| 806 | 806 | ||
| 807 | static int ov6650_video_probe(struct i2c_client *client) | 807 | static int ov6650_video_probe(struct v4l2_subdev *sd) |
| 808 | { | 808 | { |
| 809 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
| 809 | struct ov6650 *priv = to_ov6650(client); | 810 | struct ov6650 *priv = to_ov6650(client); |
| 810 | u8 pidh, pidl, midh, midl; | 811 | u8 pidh, pidl, midh, midl; |
| 811 | int ret; | 812 | int ret; |
| 812 | 813 | ||
| 813 | ret = ov6650_s_power(&priv->subdev, 1); | 814 | priv->clk = v4l2_clk_get(&client->dev, NULL); |
| 814 | if (ret < 0) | 815 | if (IS_ERR(priv->clk)) { |
| 816 | ret = PTR_ERR(priv->clk); | ||
| 817 | dev_err(&client->dev, "v4l2_clk request err: %d\n", ret); | ||
| 815 | return ret; | 818 | return ret; |
| 819 | } | ||
| 820 | |||
| 821 | ret = ov6650_s_power(sd, 1); | ||
| 822 | if (ret < 0) | ||
| 823 | goto eclkput; | ||
| 824 | |||
| 825 | msleep(20); | ||
| 816 | 826 | ||
| 817 | /* | 827 | /* |
| 818 | * check and show product ID and manufacturer ID | 828 | * check and show product ID and manufacturer ID |
| @@ -846,7 +856,12 @@ static int ov6650_video_probe(struct i2c_client *client) | |||
| 846 | ret = v4l2_ctrl_handler_setup(&priv->hdl); | 856 | ret = v4l2_ctrl_handler_setup(&priv->hdl); |
| 847 | 857 | ||
| 848 | done: | 858 | done: |
| 849 | ov6650_s_power(&priv->subdev, 0); | 859 | ov6650_s_power(sd, 0); |
| 860 | if (!ret) | ||
| 861 | return 0; | ||
| 862 | eclkput: | ||
| 863 | v4l2_clk_put(priv->clk); | ||
| 864 | |||
| 850 | return ret; | 865 | return ret; |
| 851 | } | 866 | } |
| 852 | 867 | ||
| @@ -929,6 +944,10 @@ static const struct v4l2_subdev_ops ov6650_subdev_ops = { | |||
| 929 | .pad = &ov6650_pad_ops, | 944 | .pad = &ov6650_pad_ops, |
| 930 | }; | 945 | }; |
| 931 | 946 | ||
| 947 | static const struct v4l2_subdev_internal_ops ov6650_internal_ops = { | ||
| 948 | .registered = ov6650_video_probe, | ||
| 949 | }; | ||
| 950 | |||
| 932 | /* | 951 | /* |
| 933 | * i2c_driver function | 952 | * i2c_driver function |
| 934 | */ | 953 | */ |
| @@ -989,18 +1008,12 @@ static int ov6650_probe(struct i2c_client *client, | |||
| 989 | priv->code = MEDIA_BUS_FMT_YUYV8_2X8; | 1008 | priv->code = MEDIA_BUS_FMT_YUYV8_2X8; |
| 990 | priv->colorspace = V4L2_COLORSPACE_JPEG; | 1009 | priv->colorspace = V4L2_COLORSPACE_JPEG; |
| 991 | 1010 | ||
| 992 | priv->clk = v4l2_clk_get(&client->dev, NULL); | 1011 | priv->subdev.internal_ops = &ov6650_internal_ops; |
| 993 | if (IS_ERR(priv->clk)) { | 1012 | priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
| 994 | ret = PTR_ERR(priv->clk); | ||
| 995 | goto eclkget; | ||
| 996 | } | ||
| 997 | 1013 | ||
| 998 | ret = ov6650_video_probe(client); | 1014 | ret = v4l2_async_register_subdev(&priv->subdev); |
| 999 | if (ret) { | 1015 | if (ret) |
| 1000 | v4l2_clk_put(priv->clk); | ||
| 1001 | eclkget: | ||
| 1002 | v4l2_ctrl_handler_free(&priv->hdl); | 1016 | v4l2_ctrl_handler_free(&priv->hdl); |
| 1003 | } | ||
| 1004 | 1017 | ||
| 1005 | return ret; | 1018 | return ret; |
| 1006 | } | 1019 | } |
| @@ -1010,7 +1023,7 @@ static int ov6650_remove(struct i2c_client *client) | |||
| 1010 | struct ov6650 *priv = to_ov6650(client); | 1023 | struct ov6650 *priv = to_ov6650(client); |
| 1011 | 1024 | ||
| 1012 | v4l2_clk_put(priv->clk); | 1025 | v4l2_clk_put(priv->clk); |
| 1013 | v4l2_device_unregister_subdev(&priv->subdev); | 1026 | v4l2_async_unregister_subdev(&priv->subdev); |
| 1014 | v4l2_ctrl_handler_free(&priv->hdl); | 1027 | v4l2_ctrl_handler_free(&priv->hdl); |
| 1015 | return 0; | 1028 | return 0; |
| 1016 | } | 1029 | } |
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index a7d26b294eb5..44c3eed8a858 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c | |||
| @@ -864,7 +864,15 @@ static int ov7675_set_framerate(struct v4l2_subdev *sd, | |||
| 864 | /* Recalculate frame rate */ | 864 | /* Recalculate frame rate */ |
| 865 | ov7675_get_framerate(sd, tpf); | 865 | ov7675_get_framerate(sd, tpf); |
| 866 | 866 | ||
| 867 | return ov7675_apply_framerate(sd); | 867 | /* |
| 868 | * If the device is not powered up by the host driver do | ||
| 869 | * not apply any changes to H/W at this time. Instead | ||
| 870 | * the framerate will be restored right after power-up. | ||
| 871 | */ | ||
| 872 | if (info->on) | ||
| 873 | return ov7675_apply_framerate(sd); | ||
| 874 | |||
| 875 | return 0; | ||
| 868 | } | 876 | } |
| 869 | 877 | ||
| 870 | static void ov7670_get_framerate_legacy(struct v4l2_subdev *sd, | 878 | static void ov7670_get_framerate_legacy(struct v4l2_subdev *sd, |
| @@ -895,7 +903,16 @@ static int ov7670_set_framerate_legacy(struct v4l2_subdev *sd, | |||
| 895 | info->clkrc = (info->clkrc & 0x80) | div; | 903 | info->clkrc = (info->clkrc & 0x80) | div; |
| 896 | tpf->numerator = 1; | 904 | tpf->numerator = 1; |
| 897 | tpf->denominator = info->clock_speed / div; | 905 | tpf->denominator = info->clock_speed / div; |
| 898 | return ov7670_write(sd, REG_CLKRC, info->clkrc); | 906 | |
| 907 | /* | ||
| 908 | * If the device is not powered up by the host driver do | ||
| 909 | * not apply any changes to H/W at this time. Instead | ||
| 910 | * the framerate will be restored right after power-up. | ||
| 911 | */ | ||
| 912 | if (info->on) | ||
| 913 | return ov7670_write(sd, REG_CLKRC, info->clkrc); | ||
| 914 | |||
| 915 | return 0; | ||
| 899 | } | 916 | } |
| 900 | 917 | ||
| 901 | /* | 918 | /* |
| @@ -1105,9 +1122,13 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, | |||
| 1105 | if (ret) | 1122 | if (ret) |
| 1106 | return ret; | 1123 | return ret; |
| 1107 | 1124 | ||
| 1108 | ret = ov7670_apply_fmt(sd); | 1125 | /* |
| 1109 | if (ret) | 1126 | * If the device is not powered up by the host driver do |
| 1110 | return ret; | 1127 | * not apply any changes to H/W at this time. Instead |
| 1128 | * the frame format will be restored right after power-up. | ||
| 1129 | */ | ||
| 1130 | if (info->on) | ||
| 1131 | return ov7670_apply_fmt(sd); | ||
| 1111 | 1132 | ||
| 1112 | return 0; | 1133 | return 0; |
| 1113 | } | 1134 | } |
| @@ -1664,6 +1685,7 @@ static int ov7670_s_power(struct v4l2_subdev *sd, int on) | |||
| 1664 | 1685 | ||
| 1665 | if (on) { | 1686 | if (on) { |
| 1666 | ov7670_power_on (sd); | 1687 | ov7670_power_on (sd); |
| 1688 | ov7670_init(sd, 0); | ||
| 1667 | ov7670_apply_fmt(sd); | 1689 | ov7670_apply_fmt(sd); |
| 1668 | ov7675_apply_framerate(sd); | 1690 | ov7675_apply_framerate(sd); |
| 1669 | v4l2_ctrl_handler_setup(&info->hdl); | 1691 | v4l2_ctrl_handler_setup(&info->hdl); |
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index dfece91ce96b..54e80a60aa57 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c | |||
| @@ -448,6 +448,27 @@ static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl) | |||
| 448 | return 0; | 448 | return 0; |
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | static int ov7740_get_exp(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl) | ||
| 452 | { | ||
| 453 | struct regmap *regmap = ov7740->regmap; | ||
| 454 | unsigned int value0, value1; | ||
| 455 | int ret; | ||
| 456 | |||
| 457 | if (ctrl->val == V4L2_EXPOSURE_MANUAL) | ||
| 458 | return 0; | ||
| 459 | |||
| 460 | ret = regmap_read(regmap, REG_AEC, &value0); | ||
| 461 | if (ret) | ||
| 462 | return ret; | ||
| 463 | ret = regmap_read(regmap, REG_HAEC, &value1); | ||
| 464 | if (ret) | ||
| 465 | return ret; | ||
| 466 | |||
| 467 | ov7740->exposure->val = (value1 << 8) | (value0 & 0xff); | ||
| 468 | |||
| 469 | return 0; | ||
| 470 | } | ||
| 471 | |||
| 451 | static int ov7740_set_exp(struct regmap *regmap, int value) | 472 | static int ov7740_set_exp(struct regmap *regmap, int value) |
| 452 | { | 473 | { |
| 453 | int ret; | 474 | int ret; |
| @@ -494,6 +515,9 @@ static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl) | |||
| 494 | case V4L2_CID_AUTOGAIN: | 515 | case V4L2_CID_AUTOGAIN: |
| 495 | ret = ov7740_get_gain(ov7740, ctrl); | 516 | ret = ov7740_get_gain(ov7740, ctrl); |
| 496 | break; | 517 | break; |
| 518 | case V4L2_CID_EXPOSURE_AUTO: | ||
| 519 | ret = ov7740_get_exp(ov7740, ctrl); | ||
| 520 | break; | ||
| 497 | default: | 521 | default: |
| 498 | ret = -EINVAL; | 522 | ret = -EINVAL; |
| 499 | break; | 523 | break; |
| @@ -991,8 +1015,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740) | |||
| 991 | 1015 | ||
| 992 | ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops, | 1016 | ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops, |
| 993 | V4L2_CID_EXPOSURE, 0, 65535, 1, 500); | 1017 | V4L2_CID_EXPOSURE, 0, 65535, 1, 500); |
| 994 | if (ov7740->exposure) | ||
| 995 | ov7740->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; | ||
| 996 | 1018 | ||
| 997 | ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr, | 1019 | ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr, |
| 998 | &ov7740_ctrl_ops, | 1020 | &ov7740_ctrl_ops, |
| @@ -1003,7 +1025,7 @@ static int ov7740_init_controls(struct ov7740 *ov7740) | |||
| 1003 | v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false); | 1025 | v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false); |
| 1004 | v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true); | 1026 | v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true); |
| 1005 | v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure, | 1027 | v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure, |
| 1006 | V4L2_EXPOSURE_MANUAL, false); | 1028 | V4L2_EXPOSURE_MANUAL, true); |
| 1007 | v4l2_ctrl_cluster(2, &ov7740->hflip); | 1029 | v4l2_ctrl_cluster(2, &ov7740->hflip); |
| 1008 | 1030 | ||
| 1009 | if (ctrl_hdlr->error) { | 1031 | if (ctrl_hdlr->error) { |
diff --git a/drivers/media/i2c/smiapp/Kconfig b/drivers/media/i2c/smiapp/Kconfig index f59718d8e51e..26b54f2aa95b 100644 --- a/drivers/media/i2c/smiapp/Kconfig +++ b/drivers/media/i2c/smiapp/Kconfig | |||
| @@ -4,5 +4,5 @@ config VIDEO_SMIAPP | |||
| 4 | depends on MEDIA_CAMERA_SUPPORT | 4 | depends on MEDIA_CAMERA_SUPPORT |
| 5 | select VIDEO_SMIAPP_PLL | 5 | select VIDEO_SMIAPP_PLL |
| 6 | select V4L2_FWNODE | 6 | select V4L2_FWNODE |
| 7 | ---help--- | 7 | help |
| 8 | This is a generic driver for SMIA++/SMIA camera modules. | 8 | This is a generic driver for SMIA++/SMIA camera modules. |
diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c new file mode 100644 index 000000000000..9369f38dbf3d --- /dev/null +++ b/drivers/media/i2c/st-mipid02.c | |||
| @@ -0,0 +1,1033 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Driver for ST MIPID02 CSI-2 to PARALLEL bridge | ||
| 4 | * | ||
| 5 | * Copyright (C) STMicroelectronics SA 2019 | ||
| 6 | * Authors: Mickael Guene <mickael.guene@st.com> | ||
| 7 | * for STMicroelectronics. | ||
| 8 | * | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/clk.h> | ||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/gpio/consumer.h> | ||
| 15 | #include <linux/i2c.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of_graph.h> | ||
| 18 | #include <linux/regulator/consumer.h> | ||
| 19 | #include <media/v4l2-async.h> | ||
| 20 | #include <media/v4l2-ctrls.h> | ||
| 21 | #include <media/v4l2-device.h> | ||
| 22 | #include <media/v4l2-fwnode.h> | ||
| 23 | #include <media/v4l2-subdev.h> | ||
| 24 | |||
| 25 | #define MIPID02_CLK_LANE_WR_REG1 0x01 | ||
| 26 | #define MIPID02_CLK_LANE_REG1 0x02 | ||
| 27 | #define MIPID02_CLK_LANE_REG3 0x04 | ||
| 28 | #define MIPID02_DATA_LANE0_REG1 0x05 | ||
| 29 | #define MIPID02_DATA_LANE0_REG2 0x06 | ||
| 30 | #define MIPID02_DATA_LANE1_REG1 0x09 | ||
| 31 | #define MIPID02_DATA_LANE1_REG2 0x0a | ||
| 32 | #define MIPID02_MODE_REG1 0x14 | ||
| 33 | #define MIPID02_MODE_REG2 0x15 | ||
| 34 | #define MIPID02_DATA_ID_RREG 0x17 | ||
| 35 | #define MIPID02_DATA_SELECTION_CTRL 0x19 | ||
| 36 | #define MIPID02_PIX_WIDTH_CTRL 0x1e | ||
| 37 | #define MIPID02_PIX_WIDTH_CTRL_EMB 0x1f | ||
| 38 | |||
| 39 | /* Bits definition for MIPID02_CLK_LANE_REG1 */ | ||
| 40 | #define CLK_ENABLE BIT(0) | ||
| 41 | /* Bits definition for MIPID02_CLK_LANE_REG3 */ | ||
| 42 | #define CLK_MIPI_CSI BIT(1) | ||
| 43 | /* Bits definition for MIPID02_DATA_LANE0_REG1 */ | ||
| 44 | #define DATA_ENABLE BIT(0) | ||
| 45 | /* Bits definition for MIPID02_DATA_LANEx_REG2 */ | ||
| 46 | #define DATA_MIPI_CSI BIT(0) | ||
| 47 | /* Bits definition for MIPID02_MODE_REG1 */ | ||
| 48 | #define MODE_DATA_SWAP BIT(2) | ||
| 49 | #define MODE_NO_BYPASS BIT(6) | ||
| 50 | /* Bits definition for MIPID02_MODE_REG2 */ | ||
| 51 | #define MODE_HSYNC_ACTIVE_HIGH BIT(1) | ||
| 52 | #define MODE_VSYNC_ACTIVE_HIGH BIT(2) | ||
| 53 | /* Bits definition for MIPID02_DATA_SELECTION_CTRL */ | ||
| 54 | #define SELECTION_MANUAL_DATA BIT(2) | ||
| 55 | #define SELECTION_MANUAL_WIDTH BIT(3) | ||
| 56 | |||
| 57 | static const u32 mipid02_supported_fmt_codes[] = { | ||
| 58 | MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8, | ||
| 59 | MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8, | ||
| 60 | MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, | ||
| 61 | MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, | ||
| 62 | MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12, | ||
| 63 | MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SRGGB12_1X12, | ||
| 64 | MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_BGR888_1X24 | ||
| 65 | }; | ||
| 66 | |||
| 67 | /* regulator supplies */ | ||
| 68 | static const char * const mipid02_supply_name[] = { | ||
| 69 | "VDDE", /* 1.8V digital I/O supply */ | ||
| 70 | "VDDIN", /* 1V8 voltage regulator supply */ | ||
| 71 | }; | ||
| 72 | |||
| 73 | #define MIPID02_NUM_SUPPLIES ARRAY_SIZE(mipid02_supply_name) | ||
| 74 | |||
| 75 | #define MIPID02_SINK_0 0 | ||
| 76 | #define MIPID02_SINK_1 1 | ||
| 77 | #define MIPID02_SOURCE 2 | ||
| 78 | #define MIPID02_PAD_NB 3 | ||
| 79 | |||
| 80 | struct mipid02_dev { | ||
| 81 | struct i2c_client *i2c_client; | ||
| 82 | struct regulator_bulk_data supplies[MIPID02_NUM_SUPPLIES]; | ||
| 83 | struct v4l2_subdev sd; | ||
| 84 | struct media_pad pad[MIPID02_PAD_NB]; | ||
| 85 | struct clk *xclk; | ||
| 86 | struct gpio_desc *reset_gpio; | ||
| 87 | /* endpoints info */ | ||
| 88 | struct v4l2_fwnode_endpoint rx; | ||
| 89 | u64 link_frequency; | ||
| 90 | struct v4l2_fwnode_endpoint tx; | ||
| 91 | /* remote source */ | ||
| 92 | struct v4l2_async_subdev asd; | ||
| 93 | struct v4l2_async_notifier notifier; | ||
| 94 | struct v4l2_subdev *s_subdev; | ||
| 95 | /* registers */ | ||
| 96 | struct { | ||
| 97 | u8 clk_lane_reg1; | ||
| 98 | u8 data_lane0_reg1; | ||
| 99 | u8 data_lane1_reg1; | ||
| 100 | u8 mode_reg1; | ||
| 101 | u8 mode_reg2; | ||
| 102 | u8 data_id_rreg; | ||
| 103 | u8 pix_width_ctrl; | ||
| 104 | u8 pix_width_ctrl_emb; | ||
| 105 | } r; | ||
| 106 | /* lock to protect all members below */ | ||
| 107 | struct mutex lock; | ||
| 108 | bool streaming; | ||
| 109 | struct v4l2_mbus_framefmt fmt; | ||
| 110 | }; | ||
| 111 | |||
| 112 | static int bpp_from_code(__u32 code) | ||
| 113 | { | ||
| 114 | switch (code) { | ||
| 115 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
| 116 | case MEDIA_BUS_FMT_SGBRG8_1X8: | ||
| 117 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
| 118 | case MEDIA_BUS_FMT_SRGGB8_1X8: | ||
| 119 | return 8; | ||
| 120 | case MEDIA_BUS_FMT_SBGGR10_1X10: | ||
| 121 | case MEDIA_BUS_FMT_SGBRG10_1X10: | ||
| 122 | case MEDIA_BUS_FMT_SGRBG10_1X10: | ||
| 123 | case MEDIA_BUS_FMT_SRGGB10_1X10: | ||
| 124 | return 10; | ||
| 125 | case MEDIA_BUS_FMT_SBGGR12_1X12: | ||
| 126 | case MEDIA_BUS_FMT_SGBRG12_1X12: | ||
| 127 | case MEDIA_BUS_FMT_SGRBG12_1X12: | ||
| 128 | case MEDIA_BUS_FMT_SRGGB12_1X12: | ||
| 129 | return 12; | ||
| 130 | case MEDIA_BUS_FMT_UYVY8_1X16: | ||
| 131 | return 16; | ||
| 132 | case MEDIA_BUS_FMT_BGR888_1X24: | ||
| 133 | return 24; | ||
| 134 | default: | ||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | static u8 data_type_from_code(__u32 code) | ||
| 140 | { | ||
| 141 | switch (code) { | ||
| 142 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
| 143 | case MEDIA_BUS_FMT_SGBRG8_1X8: | ||
| 144 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
| 145 | case MEDIA_BUS_FMT_SRGGB8_1X8: | ||
| 146 | return 0x2a; | ||
| 147 | case MEDIA_BUS_FMT_SBGGR10_1X10: | ||
| 148 | case MEDIA_BUS_FMT_SGBRG10_1X10: | ||
| 149 | case MEDIA_BUS_FMT_SGRBG10_1X10: | ||
| 150 | case MEDIA_BUS_FMT_SRGGB10_1X10: | ||
| 151 | return 0x2b; | ||
| 152 | case MEDIA_BUS_FMT_SBGGR12_1X12: | ||
| 153 | case MEDIA_BUS_FMT_SGBRG12_1X12: | ||
| 154 | case MEDIA_BUS_FMT_SGRBG12_1X12: | ||
| 155 | case MEDIA_BUS_FMT_SRGGB12_1X12: | ||
| 156 | return 0x2c; | ||
| 157 | case MEDIA_BUS_FMT_UYVY8_1X16: | ||
| 158 | return 0x1e; | ||
| 159 | case MEDIA_BUS_FMT_BGR888_1X24: | ||
| 160 | return 0x24; | ||
| 161 | default: | ||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | static void init_format(struct v4l2_mbus_framefmt *fmt) | ||
| 167 | { | ||
| 168 | fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8; | ||
| 169 | fmt->field = V4L2_FIELD_NONE; | ||
| 170 | fmt->colorspace = V4L2_COLORSPACE_SRGB; | ||
| 171 | fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB); | ||
| 172 | fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; | ||
| 173 | fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB); | ||
| 174 | fmt->width = 640; | ||
| 175 | fmt->height = 480; | ||
| 176 | } | ||
| 177 | |||
| 178 | static __u32 get_fmt_code(__u32 code) | ||
| 179 | { | ||
| 180 | unsigned int i; | ||
| 181 | |||
| 182 | for (i = 0; i < ARRAY_SIZE(mipid02_supported_fmt_codes); i++) { | ||
| 183 | if (code == mipid02_supported_fmt_codes[i]) | ||
| 184 | return code; | ||
| 185 | } | ||
| 186 | |||
| 187 | return mipid02_supported_fmt_codes[0]; | ||
| 188 | } | ||
| 189 | |||
| 190 | static __u32 serial_to_parallel_code(__u32 serial) | ||
| 191 | { | ||
| 192 | if (serial == MEDIA_BUS_FMT_UYVY8_1X16) | ||
| 193 | return MEDIA_BUS_FMT_UYVY8_2X8; | ||
| 194 | if (serial == MEDIA_BUS_FMT_BGR888_1X24) | ||
| 195 | return MEDIA_BUS_FMT_BGR888_3X8; | ||
| 196 | |||
| 197 | return serial; | ||
| 198 | } | ||
| 199 | |||
| 200 | static inline struct mipid02_dev *to_mipid02_dev(struct v4l2_subdev *sd) | ||
| 201 | { | ||
| 202 | return container_of(sd, struct mipid02_dev, sd); | ||
| 203 | } | ||
| 204 | |||
| 205 | static int mipid02_read_reg(struct mipid02_dev *bridge, u16 reg, u8 *val) | ||
| 206 | { | ||
| 207 | struct i2c_client *client = bridge->i2c_client; | ||
| 208 | struct i2c_msg msg[2]; | ||
| 209 | u8 buf[2]; | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | buf[0] = reg >> 8; | ||
| 213 | buf[1] = reg & 0xff; | ||
| 214 | |||
| 215 | msg[0].addr = client->addr; | ||
| 216 | msg[0].flags = client->flags; | ||
| 217 | msg[0].buf = buf; | ||
| 218 | msg[0].len = sizeof(buf); | ||
| 219 | |||
| 220 | msg[1].addr = client->addr; | ||
| 221 | msg[1].flags = client->flags | I2C_M_RD; | ||
| 222 | msg[1].buf = val; | ||
| 223 | msg[1].len = 1; | ||
| 224 | |||
| 225 | ret = i2c_transfer(client->adapter, msg, 2); | ||
| 226 | if (ret < 0) { | ||
| 227 | dev_dbg(&client->dev, "%s: %x i2c_transfer, reg: %x => %d\n", | ||
| 228 | __func__, client->addr, reg, ret); | ||
| 229 | return ret; | ||
| 230 | } | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int mipid02_write_reg(struct mipid02_dev *bridge, u16 reg, u8 val) | ||
| 236 | { | ||
| 237 | struct i2c_client *client = bridge->i2c_client; | ||
| 238 | struct i2c_msg msg; | ||
| 239 | u8 buf[3]; | ||
| 240 | int ret; | ||
| 241 | |||
| 242 | buf[0] = reg >> 8; | ||
| 243 | buf[1] = reg & 0xff; | ||
| 244 | buf[2] = val; | ||
| 245 | |||
| 246 | msg.addr = client->addr; | ||
| 247 | msg.flags = client->flags; | ||
| 248 | msg.buf = buf; | ||
| 249 | msg.len = sizeof(buf); | ||
| 250 | |||
| 251 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 252 | if (ret < 0) { | ||
| 253 | dev_dbg(&client->dev, "%s: i2c_transfer, reg: %x => %d\n", | ||
| 254 | __func__, reg, ret); | ||
| 255 | return ret; | ||
| 256 | } | ||
| 257 | |||
| 258 | return 0; | ||
| 259 | } | ||
| 260 | |||
| 261 | static int mipid02_get_regulators(struct mipid02_dev *bridge) | ||
| 262 | { | ||
| 263 | unsigned int i; | ||
| 264 | |||
| 265 | for (i = 0; i < MIPID02_NUM_SUPPLIES; i++) | ||
| 266 | bridge->supplies[i].supply = mipid02_supply_name[i]; | ||
| 267 | |||
| 268 | return devm_regulator_bulk_get(&bridge->i2c_client->dev, | ||
| 269 | MIPID02_NUM_SUPPLIES, | ||
| 270 | bridge->supplies); | ||
| 271 | } | ||
| 272 | |||
| 273 | static void mipid02_apply_reset(struct mipid02_dev *bridge) | ||
| 274 | { | ||
| 275 | gpiod_set_value_cansleep(bridge->reset_gpio, 0); | ||
| 276 | usleep_range(5000, 10000); | ||
| 277 | gpiod_set_value_cansleep(bridge->reset_gpio, 1); | ||
| 278 | usleep_range(5000, 10000); | ||
| 279 | gpiod_set_value_cansleep(bridge->reset_gpio, 0); | ||
| 280 | usleep_range(5000, 10000); | ||
| 281 | } | ||
| 282 | |||
| 283 | static int mipid02_set_power_on(struct mipid02_dev *bridge) | ||
| 284 | { | ||
| 285 | struct i2c_client *client = bridge->i2c_client; | ||
| 286 | int ret; | ||
| 287 | |||
| 288 | ret = clk_prepare_enable(bridge->xclk); | ||
| 289 | if (ret) { | ||
| 290 | dev_err(&client->dev, "%s: failed to enable clock\n", __func__); | ||
| 291 | return ret; | ||
| 292 | } | ||
| 293 | |||
| 294 | ret = regulator_bulk_enable(MIPID02_NUM_SUPPLIES, | ||
| 295 | bridge->supplies); | ||
| 296 | if (ret) { | ||
| 297 | dev_err(&client->dev, "%s: failed to enable regulators\n", | ||
| 298 | __func__); | ||
| 299 | goto xclk_off; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (bridge->reset_gpio) { | ||
| 303 | dev_dbg(&client->dev, "apply reset"); | ||
| 304 | mipid02_apply_reset(bridge); | ||
| 305 | } else { | ||
| 306 | dev_dbg(&client->dev, "don't apply reset"); | ||
| 307 | usleep_range(5000, 10000); | ||
| 308 | } | ||
| 309 | |||
| 310 | return 0; | ||
| 311 | |||
| 312 | xclk_off: | ||
| 313 | clk_disable_unprepare(bridge->xclk); | ||
| 314 | return ret; | ||
| 315 | } | ||
| 316 | |||
| 317 | static void mipid02_set_power_off(struct mipid02_dev *bridge) | ||
| 318 | { | ||
| 319 | regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies); | ||
| 320 | clk_disable_unprepare(bridge->xclk); | ||
| 321 | } | ||
| 322 | |||
| 323 | static int mipid02_detect(struct mipid02_dev *bridge) | ||
| 324 | { | ||
| 325 | u8 reg; | ||
| 326 | |||
| 327 | /* | ||
| 328 | * There is no version registers. Just try to read register | ||
| 329 | * MIPID02_CLK_LANE_WR_REG1. | ||
| 330 | */ | ||
| 331 | return mipid02_read_reg(bridge, MIPID02_CLK_LANE_WR_REG1, ®); | ||
| 332 | } | ||
| 333 | |||
| 334 | static u32 mipid02_get_link_freq_from_cid_pixel_rate(struct mipid02_dev *bridge, | ||
| 335 | struct v4l2_subdev *subdev) | ||
| 336 | { | ||
| 337 | struct v4l2_fwnode_endpoint *ep = &bridge->rx; | ||
| 338 | struct v4l2_ctrl *ctrl; | ||
| 339 | u32 pixel_clock; | ||
| 340 | u32 bpp = bpp_from_code(bridge->fmt.code); | ||
| 341 | |||
| 342 | ctrl = v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); | ||
| 343 | if (!ctrl) | ||
| 344 | return 0; | ||
| 345 | pixel_clock = v4l2_ctrl_g_ctrl_int64(ctrl); | ||
| 346 | |||
| 347 | return pixel_clock * bpp / (2 * ep->bus.mipi_csi2.num_data_lanes); | ||
| 348 | } | ||
| 349 | |||
| 350 | /* | ||
| 351 | * We need to know link frequency to setup clk_lane_reg1 timings. Link frequency | ||
| 352 | * will be computed using connected device V4L2_CID_PIXEL_RATE, bit per pixel | ||
| 353 | * and number of lanes. | ||
| 354 | */ | ||
| 355 | static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge) | ||
| 356 | { | ||
| 357 | struct i2c_client *client = bridge->i2c_client; | ||
| 358 | struct v4l2_subdev *subdev = bridge->s_subdev; | ||
| 359 | u32 link_freq; | ||
| 360 | |||
| 361 | link_freq = mipid02_get_link_freq_from_cid_pixel_rate(bridge, subdev); | ||
| 362 | if (!link_freq) { | ||
| 363 | dev_err(&client->dev, "Failed to detect link frequency"); | ||
| 364 | return -EINVAL; | ||
| 365 | } | ||
| 366 | |||
| 367 | dev_dbg(&client->dev, "detect link_freq = %d Hz", link_freq); | ||
| 368 | bridge->r.clk_lane_reg1 |= (2000000000 / link_freq) << 2; | ||
| 369 | |||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | |||
| 373 | static int mipid02_configure_clk_lane(struct mipid02_dev *bridge) | ||
| 374 | { | ||
| 375 | struct i2c_client *client = bridge->i2c_client; | ||
| 376 | struct v4l2_fwnode_endpoint *ep = &bridge->rx; | ||
| 377 | bool *polarities = ep->bus.mipi_csi2.lane_polarities; | ||
| 378 | |||
| 379 | /* midid02 doesn't support clock lane remapping */ | ||
| 380 | if (ep->bus.mipi_csi2.clock_lane != 0) { | ||
| 381 | dev_err(&client->dev, "clk lane must be map to lane 0\n"); | ||
| 382 | return -EINVAL; | ||
| 383 | } | ||
| 384 | bridge->r.clk_lane_reg1 |= (polarities[0] << 1) | CLK_ENABLE; | ||
| 385 | |||
| 386 | return 0; | ||
| 387 | } | ||
| 388 | |||
| 389 | static int mipid02_configure_data0_lane(struct mipid02_dev *bridge, int nb, | ||
| 390 | bool are_lanes_swap, bool *polarities) | ||
| 391 | { | ||
| 392 | bool are_pin_swap = are_lanes_swap ? polarities[2] : polarities[1]; | ||
| 393 | |||
| 394 | if (nb == 1 && are_lanes_swap) | ||
| 395 | return 0; | ||
| 396 | |||
| 397 | /* | ||
| 398 | * data lane 0 as pin swap polarity reversed compared to clock and | ||
| 399 | * data lane 1 | ||
| 400 | */ | ||
| 401 | if (!are_pin_swap) | ||
| 402 | bridge->r.data_lane0_reg1 = 1 << 1; | ||
| 403 | bridge->r.data_lane0_reg1 |= DATA_ENABLE; | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | static int mipid02_configure_data1_lane(struct mipid02_dev *bridge, int nb, | ||
| 409 | bool are_lanes_swap, bool *polarities) | ||
| 410 | { | ||
| 411 | bool are_pin_swap = are_lanes_swap ? polarities[1] : polarities[2]; | ||
| 412 | |||
| 413 | if (nb == 1 && !are_lanes_swap) | ||
| 414 | return 0; | ||
| 415 | |||
| 416 | if (are_pin_swap) | ||
| 417 | bridge->r.data_lane1_reg1 = 1 << 1; | ||
| 418 | bridge->r.data_lane1_reg1 |= DATA_ENABLE; | ||
| 419 | |||
| 420 | return 0; | ||
| 421 | } | ||
| 422 | |||
| 423 | static int mipid02_configure_from_rx(struct mipid02_dev *bridge) | ||
| 424 | { | ||
| 425 | struct v4l2_fwnode_endpoint *ep = &bridge->rx; | ||
| 426 | bool are_lanes_swap = ep->bus.mipi_csi2.data_lanes[0] == 2; | ||
| 427 | bool *polarities = ep->bus.mipi_csi2.lane_polarities; | ||
| 428 | int nb = ep->bus.mipi_csi2.num_data_lanes; | ||
| 429 | int ret; | ||
| 430 | |||
| 431 | ret = mipid02_configure_clk_lane(bridge); | ||
| 432 | if (ret) | ||
| 433 | return ret; | ||
| 434 | |||
| 435 | ret = mipid02_configure_data0_lane(bridge, nb, are_lanes_swap, | ||
| 436 | polarities); | ||
| 437 | if (ret) | ||
| 438 | return ret; | ||
| 439 | |||
| 440 | ret = mipid02_configure_data1_lane(bridge, nb, are_lanes_swap, | ||
| 441 | polarities); | ||
| 442 | if (ret) | ||
| 443 | return ret; | ||
| 444 | |||
| 445 | bridge->r.mode_reg1 |= are_lanes_swap ? MODE_DATA_SWAP : 0; | ||
| 446 | bridge->r.mode_reg1 |= (nb - 1) << 1; | ||
| 447 | |||
| 448 | return mipid02_configure_from_rx_speed(bridge); | ||
| 449 | } | ||
| 450 | |||
| 451 | static int mipid02_configure_from_tx(struct mipid02_dev *bridge) | ||
| 452 | { | ||
| 453 | struct v4l2_fwnode_endpoint *ep = &bridge->tx; | ||
| 454 | |||
| 455 | bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width; | ||
| 456 | bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width; | ||
| 457 | if (ep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) | ||
| 458 | bridge->r.mode_reg2 |= MODE_HSYNC_ACTIVE_HIGH; | ||
| 459 | if (ep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) | ||
| 460 | bridge->r.mode_reg2 |= MODE_VSYNC_ACTIVE_HIGH; | ||
| 461 | |||
| 462 | return 0; | ||
| 463 | } | ||
| 464 | |||
| 465 | static int mipid02_configure_from_code(struct mipid02_dev *bridge) | ||
| 466 | { | ||
| 467 | u8 data_type; | ||
| 468 | |||
| 469 | bridge->r.data_id_rreg = 0; | ||
| 470 | data_type = data_type_from_code(bridge->fmt.code); | ||
| 471 | if (!data_type) | ||
| 472 | return -EINVAL; | ||
| 473 | bridge->r.data_id_rreg = data_type; | ||
| 474 | |||
| 475 | return 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | static int mipid02_stream_disable(struct mipid02_dev *bridge) | ||
| 479 | { | ||
| 480 | struct i2c_client *client = bridge->i2c_client; | ||
| 481 | int ret; | ||
| 482 | |||
| 483 | /* Disable all lanes */ | ||
| 484 | ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1, 0); | ||
| 485 | if (ret) | ||
| 486 | goto error; | ||
| 487 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1, 0); | ||
| 488 | if (ret) | ||
| 489 | goto error; | ||
| 490 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1, 0); | ||
| 491 | if (ret) | ||
| 492 | goto error; | ||
| 493 | error: | ||
| 494 | if (ret) | ||
| 495 | dev_err(&client->dev, "failed to stream off %d", ret); | ||
| 496 | |||
| 497 | return ret; | ||
| 498 | } | ||
| 499 | |||
| 500 | static int mipid02_stream_enable(struct mipid02_dev *bridge) | ||
| 501 | { | ||
| 502 | struct i2c_client *client = bridge->i2c_client; | ||
| 503 | int ret = -EINVAL; | ||
| 504 | |||
| 505 | if (!bridge->s_subdev) | ||
| 506 | goto error; | ||
| 507 | |||
| 508 | memset(&bridge->r, 0, sizeof(bridge->r)); | ||
| 509 | /* build registers content */ | ||
| 510 | ret = mipid02_configure_from_rx(bridge); | ||
| 511 | if (ret) | ||
| 512 | goto error; | ||
| 513 | ret = mipid02_configure_from_tx(bridge); | ||
| 514 | if (ret) | ||
| 515 | goto error; | ||
| 516 | ret = mipid02_configure_from_code(bridge); | ||
| 517 | if (ret) | ||
| 518 | goto error; | ||
| 519 | |||
| 520 | /* write mipi registers */ | ||
| 521 | ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1, | ||
| 522 | bridge->r.clk_lane_reg1); | ||
| 523 | if (ret) | ||
| 524 | goto error; | ||
| 525 | ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG3, CLK_MIPI_CSI); | ||
| 526 | if (ret) | ||
| 527 | goto error; | ||
| 528 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1, | ||
| 529 | bridge->r.data_lane0_reg1); | ||
| 530 | if (ret) | ||
| 531 | goto error; | ||
| 532 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG2, | ||
| 533 | DATA_MIPI_CSI); | ||
| 534 | if (ret) | ||
| 535 | goto error; | ||
| 536 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1, | ||
| 537 | bridge->r.data_lane1_reg1); | ||
| 538 | if (ret) | ||
| 539 | goto error; | ||
| 540 | ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG2, | ||
| 541 | DATA_MIPI_CSI); | ||
| 542 | if (ret) | ||
| 543 | goto error; | ||
| 544 | ret = mipid02_write_reg(bridge, MIPID02_MODE_REG1, | ||
| 545 | MODE_NO_BYPASS | bridge->r.mode_reg1); | ||
| 546 | if (ret) | ||
| 547 | goto error; | ||
| 548 | ret = mipid02_write_reg(bridge, MIPID02_MODE_REG2, | ||
| 549 | bridge->r.mode_reg2); | ||
| 550 | if (ret) | ||
| 551 | goto error; | ||
| 552 | ret = mipid02_write_reg(bridge, MIPID02_DATA_ID_RREG, | ||
| 553 | bridge->r.data_id_rreg); | ||
| 554 | if (ret) | ||
| 555 | goto error; | ||
| 556 | ret = mipid02_write_reg(bridge, MIPID02_DATA_SELECTION_CTRL, | ||
| 557 | SELECTION_MANUAL_DATA | SELECTION_MANUAL_WIDTH); | ||
| 558 | if (ret) | ||
| 559 | goto error; | ||
| 560 | ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL, | ||
| 561 | bridge->r.pix_width_ctrl); | ||
| 562 | if (ret) | ||
| 563 | goto error; | ||
| 564 | ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL_EMB, | ||
| 565 | bridge->r.pix_width_ctrl_emb); | ||
| 566 | if (ret) | ||
| 567 | goto error; | ||
| 568 | |||
| 569 | return 0; | ||
| 570 | |||
| 571 | error: | ||
| 572 | dev_err(&client->dev, "failed to stream on %d", ret); | ||
| 573 | mipid02_stream_disable(bridge); | ||
| 574 | |||
| 575 | return ret; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int mipid02_s_stream(struct v4l2_subdev *sd, int enable) | ||
| 579 | { | ||
| 580 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 581 | struct i2c_client *client = bridge->i2c_client; | ||
| 582 | int ret = 0; | ||
| 583 | |||
| 584 | dev_dbg(&client->dev, "%s : requested %d / current = %d", __func__, | ||
| 585 | enable, bridge->streaming); | ||
| 586 | mutex_lock(&bridge->lock); | ||
| 587 | |||
| 588 | if (bridge->streaming == enable) | ||
| 589 | goto out; | ||
| 590 | |||
| 591 | ret = enable ? mipid02_stream_enable(bridge) : | ||
| 592 | mipid02_stream_disable(bridge); | ||
| 593 | if (!ret) | ||
| 594 | bridge->streaming = enable; | ||
| 595 | |||
| 596 | out: | ||
| 597 | dev_dbg(&client->dev, "%s current now = %d / %d", __func__, | ||
| 598 | bridge->streaming, ret); | ||
| 599 | mutex_unlock(&bridge->lock); | ||
| 600 | |||
| 601 | return ret; | ||
| 602 | } | ||
| 603 | |||
| 604 | static int mipid02_enum_mbus_code(struct v4l2_subdev *sd, | ||
| 605 | struct v4l2_subdev_pad_config *cfg, | ||
| 606 | struct v4l2_subdev_mbus_code_enum *code) | ||
| 607 | { | ||
| 608 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 609 | int ret = 0; | ||
| 610 | |||
| 611 | switch (code->pad) { | ||
| 612 | case MIPID02_SINK_0: | ||
| 613 | if (code->index >= ARRAY_SIZE(mipid02_supported_fmt_codes)) | ||
| 614 | ret = -EINVAL; | ||
| 615 | else | ||
| 616 | code->code = mipid02_supported_fmt_codes[code->index]; | ||
| 617 | break; | ||
| 618 | case MIPID02_SOURCE: | ||
| 619 | if (code->index == 0) | ||
| 620 | code->code = serial_to_parallel_code(bridge->fmt.code); | ||
| 621 | else | ||
| 622 | ret = -EINVAL; | ||
| 623 | break; | ||
| 624 | default: | ||
| 625 | ret = -EINVAL; | ||
| 626 | } | ||
| 627 | |||
| 628 | return ret; | ||
| 629 | } | ||
| 630 | |||
| 631 | static int mipid02_get_fmt(struct v4l2_subdev *sd, | ||
| 632 | struct v4l2_subdev_pad_config *cfg, | ||
| 633 | struct v4l2_subdev_format *format) | ||
| 634 | { | ||
| 635 | struct v4l2_mbus_framefmt *mbus_fmt = &format->format; | ||
| 636 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 637 | struct i2c_client *client = bridge->i2c_client; | ||
| 638 | struct v4l2_mbus_framefmt *fmt; | ||
| 639 | |||
| 640 | dev_dbg(&client->dev, "%s probe %d", __func__, format->pad); | ||
| 641 | |||
| 642 | if (format->pad >= MIPID02_PAD_NB) | ||
| 643 | return -EINVAL; | ||
| 644 | /* second CSI-2 pad not yet supported */ | ||
| 645 | if (format->pad == MIPID02_SINK_1) | ||
| 646 | return -EINVAL; | ||
| 647 | |||
| 648 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) | ||
| 649 | fmt = v4l2_subdev_get_try_format(&bridge->sd, cfg, format->pad); | ||
| 650 | else | ||
| 651 | fmt = &bridge->fmt; | ||
| 652 | |||
| 653 | mutex_lock(&bridge->lock); | ||
| 654 | |||
| 655 | *mbus_fmt = *fmt; | ||
| 656 | /* code may need to be converted for source */ | ||
| 657 | if (format->pad == MIPID02_SOURCE) | ||
| 658 | mbus_fmt->code = serial_to_parallel_code(mbus_fmt->code); | ||
| 659 | |||
| 660 | mutex_unlock(&bridge->lock); | ||
| 661 | |||
| 662 | return 0; | ||
| 663 | } | ||
| 664 | |||
| 665 | static void mipid02_set_fmt_source(struct v4l2_subdev *sd, | ||
| 666 | struct v4l2_subdev_pad_config *cfg, | ||
| 667 | struct v4l2_subdev_format *format) | ||
| 668 | { | ||
| 669 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 670 | |||
| 671 | /* source pad mirror active sink pad */ | ||
| 672 | format->format = bridge->fmt; | ||
| 673 | /* but code may need to be converted */ | ||
| 674 | format->format.code = serial_to_parallel_code(format->format.code); | ||
| 675 | |||
| 676 | /* only apply format for V4L2_SUBDEV_FORMAT_TRY case */ | ||
| 677 | if (format->which != V4L2_SUBDEV_FORMAT_TRY) | ||
| 678 | return; | ||
| 679 | |||
| 680 | *v4l2_subdev_get_try_format(sd, cfg, format->pad) = format->format; | ||
| 681 | } | ||
| 682 | |||
| 683 | static void mipid02_set_fmt_sink(struct v4l2_subdev *sd, | ||
| 684 | struct v4l2_subdev_pad_config *cfg, | ||
| 685 | struct v4l2_subdev_format *format) | ||
| 686 | { | ||
| 687 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 688 | struct v4l2_mbus_framefmt *fmt; | ||
| 689 | |||
| 690 | format->format.code = get_fmt_code(format->format.code); | ||
| 691 | |||
| 692 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) | ||
| 693 | fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); | ||
| 694 | else | ||
| 695 | fmt = &bridge->fmt; | ||
| 696 | |||
| 697 | *fmt = format->format; | ||
| 698 | } | ||
| 699 | |||
| 700 | static int mipid02_set_fmt(struct v4l2_subdev *sd, | ||
| 701 | struct v4l2_subdev_pad_config *cfg, | ||
| 702 | struct v4l2_subdev_format *format) | ||
| 703 | { | ||
| 704 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 705 | struct i2c_client *client = bridge->i2c_client; | ||
| 706 | int ret = 0; | ||
| 707 | |||
| 708 | dev_dbg(&client->dev, "%s for %d", __func__, format->pad); | ||
| 709 | |||
| 710 | if (format->pad >= MIPID02_PAD_NB) | ||
| 711 | return -EINVAL; | ||
| 712 | /* second CSI-2 pad not yet supported */ | ||
| 713 | if (format->pad == MIPID02_SINK_1) | ||
| 714 | return -EINVAL; | ||
| 715 | |||
| 716 | mutex_lock(&bridge->lock); | ||
| 717 | |||
| 718 | if (bridge->streaming) { | ||
| 719 | ret = -EBUSY; | ||
| 720 | goto error; | ||
| 721 | } | ||
| 722 | |||
| 723 | if (format->pad == MIPID02_SOURCE) | ||
| 724 | mipid02_set_fmt_source(sd, cfg, format); | ||
| 725 | else | ||
| 726 | mipid02_set_fmt_sink(sd, cfg, format); | ||
| 727 | |||
| 728 | error: | ||
| 729 | mutex_unlock(&bridge->lock); | ||
| 730 | |||
| 731 | return ret; | ||
| 732 | } | ||
| 733 | |||
| 734 | static const struct v4l2_subdev_video_ops mipid02_video_ops = { | ||
| 735 | .s_stream = mipid02_s_stream, | ||
| 736 | }; | ||
| 737 | |||
| 738 | static const struct v4l2_subdev_pad_ops mipid02_pad_ops = { | ||
| 739 | .enum_mbus_code = mipid02_enum_mbus_code, | ||
| 740 | .get_fmt = mipid02_get_fmt, | ||
| 741 | .set_fmt = mipid02_set_fmt, | ||
| 742 | }; | ||
| 743 | |||
| 744 | static const struct v4l2_subdev_ops mipid02_subdev_ops = { | ||
| 745 | .video = &mipid02_video_ops, | ||
| 746 | .pad = &mipid02_pad_ops, | ||
| 747 | }; | ||
| 748 | |||
| 749 | static const struct media_entity_operations mipid02_subdev_entity_ops = { | ||
| 750 | .link_validate = v4l2_subdev_link_validate, | ||
| 751 | }; | ||
| 752 | |||
| 753 | static int mipid02_async_bound(struct v4l2_async_notifier *notifier, | ||
| 754 | struct v4l2_subdev *s_subdev, | ||
| 755 | struct v4l2_async_subdev *asd) | ||
| 756 | { | ||
| 757 | struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); | ||
| 758 | struct i2c_client *client = bridge->i2c_client; | ||
| 759 | int source_pad; | ||
| 760 | int ret; | ||
| 761 | |||
| 762 | dev_dbg(&client->dev, "sensor_async_bound call %p", s_subdev); | ||
| 763 | |||
| 764 | source_pad = media_entity_get_fwnode_pad(&s_subdev->entity, | ||
| 765 | s_subdev->fwnode, | ||
| 766 | MEDIA_PAD_FL_SOURCE); | ||
| 767 | if (source_pad < 0) { | ||
| 768 | dev_err(&client->dev, "Couldn't find output pad for subdev %s\n", | ||
| 769 | s_subdev->name); | ||
| 770 | return source_pad; | ||
| 771 | } | ||
| 772 | |||
| 773 | ret = media_create_pad_link(&s_subdev->entity, source_pad, | ||
| 774 | &bridge->sd.entity, 0, | ||
| 775 | MEDIA_LNK_FL_ENABLED | | ||
| 776 | MEDIA_LNK_FL_IMMUTABLE); | ||
| 777 | if (ret) { | ||
| 778 | dev_err(&client->dev, "Couldn't create media link %d", ret); | ||
| 779 | return ret; | ||
| 780 | } | ||
| 781 | |||
| 782 | bridge->s_subdev = s_subdev; | ||
| 783 | |||
| 784 | return 0; | ||
| 785 | } | ||
| 786 | |||
| 787 | static void mipid02_async_unbind(struct v4l2_async_notifier *notifier, | ||
| 788 | struct v4l2_subdev *s_subdev, | ||
| 789 | struct v4l2_async_subdev *asd) | ||
| 790 | { | ||
| 791 | struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); | ||
| 792 | |||
| 793 | bridge->s_subdev = NULL; | ||
| 794 | } | ||
| 795 | |||
| 796 | static const struct v4l2_async_notifier_operations mipid02_notifier_ops = { | ||
| 797 | .bound = mipid02_async_bound, | ||
| 798 | .unbind = mipid02_async_unbind, | ||
| 799 | }; | ||
| 800 | |||
| 801 | static int mipid02_parse_rx_ep(struct mipid02_dev *bridge) | ||
| 802 | { | ||
| 803 | struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; | ||
| 804 | struct i2c_client *client = bridge->i2c_client; | ||
| 805 | struct device_node *ep_node; | ||
| 806 | int ret; | ||
| 807 | |||
| 808 | /* parse rx (endpoint 0) */ | ||
| 809 | ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, | ||
| 810 | 0, 0); | ||
| 811 | if (!ep_node) { | ||
| 812 | dev_err(&client->dev, "unable to find port0 ep"); | ||
| 813 | ret = -EINVAL; | ||
| 814 | goto error; | ||
| 815 | } | ||
| 816 | |||
| 817 | ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep); | ||
| 818 | if (ret) { | ||
| 819 | dev_err(&client->dev, "Could not parse v4l2 endpoint %d\n", | ||
| 820 | ret); | ||
| 821 | goto error_of_node_put; | ||
| 822 | } | ||
| 823 | |||
| 824 | /* do some sanity checks */ | ||
| 825 | if (ep.bus.mipi_csi2.num_data_lanes > 2) { | ||
| 826 | dev_err(&client->dev, "max supported data lanes is 2 / got %d", | ||
| 827 | ep.bus.mipi_csi2.num_data_lanes); | ||
| 828 | ret = -EINVAL; | ||
| 829 | goto error_of_node_put; | ||
| 830 | } | ||
| 831 | |||
| 832 | /* register it for later use */ | ||
| 833 | bridge->rx = ep; | ||
| 834 | |||
| 835 | /* register async notifier so we get noticed when sensor is connected */ | ||
| 836 | bridge->asd.match.fwnode = | ||
| 837 | fwnode_graph_get_remote_port_parent(of_fwnode_handle(ep_node)); | ||
| 838 | bridge->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; | ||
| 839 | of_node_put(ep_node); | ||
| 840 | |||
| 841 | v4l2_async_notifier_init(&bridge->notifier); | ||
| 842 | ret = v4l2_async_notifier_add_subdev(&bridge->notifier, &bridge->asd); | ||
| 843 | if (ret) { | ||
| 844 | dev_err(&client->dev, "fail to register asd to notifier %d", | ||
| 845 | ret); | ||
| 846 | fwnode_handle_put(bridge->asd.match.fwnode); | ||
| 847 | return ret; | ||
| 848 | } | ||
| 849 | bridge->notifier.ops = &mipid02_notifier_ops; | ||
| 850 | |||
| 851 | ret = v4l2_async_subdev_notifier_register(&bridge->sd, | ||
| 852 | &bridge->notifier); | ||
| 853 | if (ret) | ||
| 854 | v4l2_async_notifier_cleanup(&bridge->notifier); | ||
| 855 | |||
| 856 | return ret; | ||
| 857 | |||
| 858 | error_of_node_put: | ||
| 859 | of_node_put(ep_node); | ||
| 860 | error: | ||
| 861 | |||
| 862 | return ret; | ||
| 863 | } | ||
| 864 | |||
| 865 | static int mipid02_parse_tx_ep(struct mipid02_dev *bridge) | ||
| 866 | { | ||
| 867 | struct v4l2_fwnode_endpoint ep = { .bus_type = V4L2_MBUS_PARALLEL }; | ||
| 868 | struct i2c_client *client = bridge->i2c_client; | ||
| 869 | struct device_node *ep_node; | ||
| 870 | int ret; | ||
| 871 | |||
| 872 | /* parse tx (endpoint 2) */ | ||
| 873 | ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, | ||
| 874 | 2, 0); | ||
| 875 | if (!ep_node) { | ||
| 876 | dev_err(&client->dev, "unable to find port1 ep"); | ||
| 877 | ret = -EINVAL; | ||
| 878 | goto error; | ||
| 879 | } | ||
| 880 | |||
| 881 | ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep); | ||
| 882 | if (ret) { | ||
| 883 | dev_err(&client->dev, "Could not parse v4l2 endpoint\n"); | ||
| 884 | goto error_of_node_put; | ||
| 885 | } | ||
| 886 | |||
| 887 | of_node_put(ep_node); | ||
| 888 | bridge->tx = ep; | ||
| 889 | |||
| 890 | return 0; | ||
| 891 | |||
| 892 | error_of_node_put: | ||
| 893 | of_node_put(ep_node); | ||
| 894 | error: | ||
| 895 | |||
| 896 | return -EINVAL; | ||
| 897 | } | ||
| 898 | |||
| 899 | static int mipid02_probe(struct i2c_client *client) | ||
| 900 | { | ||
| 901 | struct device *dev = &client->dev; | ||
| 902 | struct mipid02_dev *bridge; | ||
| 903 | u32 clk_freq; | ||
| 904 | int ret; | ||
| 905 | |||
| 906 | bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL); | ||
| 907 | if (!bridge) | ||
| 908 | return -ENOMEM; | ||
| 909 | |||
| 910 | init_format(&bridge->fmt); | ||
| 911 | |||
| 912 | bridge->i2c_client = client; | ||
| 913 | v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops); | ||
| 914 | |||
| 915 | /* got and check clock */ | ||
| 916 | bridge->xclk = devm_clk_get(dev, "xclk"); | ||
| 917 | if (IS_ERR(bridge->xclk)) { | ||
| 918 | dev_err(dev, "failed to get xclk\n"); | ||
| 919 | return PTR_ERR(bridge->xclk); | ||
| 920 | } | ||
| 921 | |||
| 922 | clk_freq = clk_get_rate(bridge->xclk); | ||
| 923 | if (clk_freq < 6000000 || clk_freq > 27000000) { | ||
| 924 | dev_err(dev, "xclk freq must be in 6-27 Mhz range. got %d Hz\n", | ||
| 925 | clk_freq); | ||
| 926 | return -EINVAL; | ||
| 927 | } | ||
| 928 | |||
| 929 | bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset", | ||
| 930 | GPIOD_OUT_HIGH); | ||
| 931 | |||
| 932 | ret = mipid02_get_regulators(bridge); | ||
| 933 | if (ret) { | ||
| 934 | dev_err(dev, "failed to get regulators %d", ret); | ||
| 935 | return ret; | ||
| 936 | } | ||
| 937 | |||
| 938 | mutex_init(&bridge->lock); | ||
| 939 | bridge->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
| 940 | bridge->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; | ||
| 941 | bridge->sd.entity.ops = &mipid02_subdev_entity_ops; | ||
| 942 | bridge->pad[0].flags = MEDIA_PAD_FL_SINK; | ||
| 943 | bridge->pad[1].flags = MEDIA_PAD_FL_SINK; | ||
| 944 | bridge->pad[2].flags = MEDIA_PAD_FL_SOURCE; | ||
| 945 | ret = media_entity_pads_init(&bridge->sd.entity, MIPID02_PAD_NB, | ||
| 946 | bridge->pad); | ||
| 947 | if (ret) { | ||
| 948 | dev_err(&client->dev, "pads init failed %d", ret); | ||
| 949 | goto mutex_cleanup; | ||
| 950 | } | ||
| 951 | |||
| 952 | /* enable clock, power and reset device if available */ | ||
| 953 | ret = mipid02_set_power_on(bridge); | ||
| 954 | if (ret) | ||
| 955 | goto entity_cleanup; | ||
| 956 | |||
| 957 | ret = mipid02_detect(bridge); | ||
| 958 | if (ret) { | ||
| 959 | dev_err(&client->dev, "failed to detect mipid02 %d", ret); | ||
| 960 | goto power_off; | ||
| 961 | } | ||
| 962 | |||
| 963 | ret = mipid02_parse_tx_ep(bridge); | ||
| 964 | if (ret) { | ||
| 965 | dev_err(&client->dev, "failed to parse tx %d", ret); | ||
| 966 | goto power_off; | ||
| 967 | } | ||
| 968 | |||
| 969 | ret = mipid02_parse_rx_ep(bridge); | ||
| 970 | if (ret) { | ||
| 971 | dev_err(&client->dev, "failed to parse rx %d", ret); | ||
| 972 | goto power_off; | ||
| 973 | } | ||
| 974 | |||
| 975 | ret = v4l2_async_register_subdev(&bridge->sd); | ||
| 976 | if (ret < 0) { | ||
| 977 | dev_err(&client->dev, "v4l2_async_register_subdev failed %d", | ||
| 978 | ret); | ||
| 979 | goto unregister_notifier; | ||
| 980 | } | ||
| 981 | |||
| 982 | dev_info(&client->dev, "mipid02 device probe successfully"); | ||
| 983 | |||
| 984 | return 0; | ||
| 985 | |||
| 986 | unregister_notifier: | ||
| 987 | v4l2_async_notifier_unregister(&bridge->notifier); | ||
| 988 | v4l2_async_notifier_cleanup(&bridge->notifier); | ||
| 989 | power_off: | ||
| 990 | mipid02_set_power_off(bridge); | ||
| 991 | entity_cleanup: | ||
| 992 | media_entity_cleanup(&bridge->sd.entity); | ||
| 993 | mutex_cleanup: | ||
| 994 | mutex_destroy(&bridge->lock); | ||
| 995 | |||
| 996 | return ret; | ||
| 997 | } | ||
| 998 | |||
| 999 | static int mipid02_remove(struct i2c_client *client) | ||
| 1000 | { | ||
| 1001 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | ||
| 1002 | struct mipid02_dev *bridge = to_mipid02_dev(sd); | ||
| 1003 | |||
| 1004 | v4l2_async_notifier_unregister(&bridge->notifier); | ||
| 1005 | v4l2_async_notifier_cleanup(&bridge->notifier); | ||
| 1006 | v4l2_async_unregister_subdev(&bridge->sd); | ||
| 1007 | mipid02_set_power_off(bridge); | ||
| 1008 | media_entity_cleanup(&bridge->sd.entity); | ||
| 1009 | mutex_destroy(&bridge->lock); | ||
| 1010 | |||
| 1011 | return 0; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | static const struct of_device_id mipid02_dt_ids[] = { | ||
| 1015 | { .compatible = "st,st-mipid02" }, | ||
| 1016 | { /* sentinel */ } | ||
| 1017 | }; | ||
| 1018 | MODULE_DEVICE_TABLE(of, mipid02_dt_ids); | ||
| 1019 | |||
| 1020 | static struct i2c_driver mipid02_i2c_driver = { | ||
| 1021 | .driver = { | ||
| 1022 | .name = "st-mipid02", | ||
| 1023 | .of_match_table = mipid02_dt_ids, | ||
| 1024 | }, | ||
| 1025 | .probe_new = mipid02_probe, | ||
| 1026 | .remove = mipid02_remove, | ||
| 1027 | }; | ||
| 1028 | |||
| 1029 | module_i2c_driver(mipid02_i2c_driver); | ||
| 1030 | |||
| 1031 | MODULE_AUTHOR("Mickael Guene <mickael.guene@st.com>"); | ||
| 1032 | MODULE_DESCRIPTION("STMicroelectronics MIPID02 CSI-2 bridge driver"); | ||
| 1033 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/media/media-dev-allocator.c b/drivers/media/media-dev-allocator.c new file mode 100644 index 000000000000..ae17887dec59 --- /dev/null +++ b/drivers/media/media-dev-allocator.c | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * media-dev-allocator.c - Media Controller Device Allocator API | ||
| 4 | * | ||
| 5 | * Copyright (c) 2019 Shuah Khan <shuah@kernel.org> | ||
| 6 | * | ||
| 7 | * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This file adds a global refcounted Media Controller Device Instance API. | ||
| 12 | * A system wide global media device list is managed and each media device | ||
| 13 | * includes a kref count. The last put on the media device releases the media | ||
| 14 | * device instance. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kref.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/usb.h> | ||
| 22 | |||
| 23 | #include <media/media-device.h> | ||
| 24 | #include <media/media-dev-allocator.h> | ||
| 25 | |||
| 26 | static LIST_HEAD(media_device_list); | ||
| 27 | static DEFINE_MUTEX(media_device_lock); | ||
| 28 | |||
| 29 | struct media_device_instance { | ||
| 30 | struct media_device mdev; | ||
| 31 | struct module *owner; | ||
| 32 | struct list_head list; | ||
| 33 | struct kref refcount; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static inline struct media_device_instance * | ||
| 37 | to_media_device_instance(struct media_device *mdev) | ||
| 38 | { | ||
| 39 | return container_of(mdev, struct media_device_instance, mdev); | ||
| 40 | } | ||
| 41 | |||
| 42 | static void media_device_instance_release(struct kref *kref) | ||
| 43 | { | ||
| 44 | struct media_device_instance *mdi = | ||
| 45 | container_of(kref, struct media_device_instance, refcount); | ||
| 46 | |||
| 47 | dev_dbg(mdi->mdev.dev, "%s: releasing Media Device\n", __func__); | ||
| 48 | |||
| 49 | mutex_lock(&media_device_lock); | ||
| 50 | |||
| 51 | media_device_unregister(&mdi->mdev); | ||
| 52 | media_device_cleanup(&mdi->mdev); | ||
| 53 | |||
| 54 | list_del(&mdi->list); | ||
| 55 | mutex_unlock(&media_device_lock); | ||
| 56 | |||
| 57 | kfree(mdi); | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Callers should hold media_device_lock when calling this function */ | ||
| 61 | static struct media_device *__media_device_get(struct device *dev, | ||
| 62 | const char *module_name, | ||
| 63 | struct module *owner) | ||
| 64 | { | ||
| 65 | struct media_device_instance *mdi; | ||
| 66 | |||
| 67 | list_for_each_entry(mdi, &media_device_list, list) { | ||
| 68 | if (mdi->mdev.dev != dev) | ||
| 69 | continue; | ||
| 70 | |||
| 71 | kref_get(&mdi->refcount); | ||
| 72 | |||
| 73 | /* get module reference for the media_device owner */ | ||
| 74 | if (owner != mdi->owner && !try_module_get(mdi->owner)) | ||
| 75 | dev_err(dev, | ||
| 76 | "%s: module %s get owner reference error\n", | ||
| 77 | __func__, module_name); | ||
| 78 | else | ||
| 79 | dev_dbg(dev, "%s: module %s got owner reference\n", | ||
| 80 | __func__, module_name); | ||
| 81 | return &mdi->mdev; | ||
| 82 | } | ||
| 83 | |||
| 84 | mdi = kzalloc(sizeof(*mdi), GFP_KERNEL); | ||
| 85 | if (!mdi) | ||
| 86 | return NULL; | ||
| 87 | |||
| 88 | mdi->owner = owner; | ||
| 89 | kref_init(&mdi->refcount); | ||
| 90 | list_add_tail(&mdi->list, &media_device_list); | ||
| 91 | |||
| 92 | dev_dbg(dev, "%s: Allocated media device for owner %s\n", | ||
| 93 | __func__, module_name); | ||
| 94 | return &mdi->mdev; | ||
| 95 | } | ||
| 96 | |||
| 97 | struct media_device *media_device_usb_allocate(struct usb_device *udev, | ||
| 98 | const char *module_name, | ||
| 99 | struct module *owner) | ||
| 100 | { | ||
| 101 | struct media_device *mdev; | ||
| 102 | |||
| 103 | mutex_lock(&media_device_lock); | ||
| 104 | mdev = __media_device_get(&udev->dev, module_name, owner); | ||
| 105 | if (!mdev) { | ||
| 106 | mutex_unlock(&media_device_lock); | ||
| 107 | return ERR_PTR(-ENOMEM); | ||
| 108 | } | ||
| 109 | |||
| 110 | /* check if media device is already initialized */ | ||
| 111 | if (!mdev->dev) | ||
| 112 | __media_device_usb_init(mdev, udev, udev->product, | ||
| 113 | module_name); | ||
| 114 | mutex_unlock(&media_device_lock); | ||
| 115 | return mdev; | ||
| 116 | } | ||
| 117 | EXPORT_SYMBOL_GPL(media_device_usb_allocate); | ||
| 118 | |||
| 119 | void media_device_delete(struct media_device *mdev, const char *module_name, | ||
| 120 | struct module *owner) | ||
| 121 | { | ||
| 122 | struct media_device_instance *mdi = to_media_device_instance(mdev); | ||
| 123 | |||
| 124 | mutex_lock(&media_device_lock); | ||
| 125 | /* put module reference for the media_device owner */ | ||
| 126 | if (mdi->owner != owner) { | ||
| 127 | module_put(mdi->owner); | ||
| 128 | dev_dbg(mdi->mdev.dev, | ||
| 129 | "%s: module %s put owner module reference\n", | ||
| 130 | __func__, module_name); | ||
| 131 | } | ||
| 132 | mutex_unlock(&media_device_lock); | ||
| 133 | kref_put(&mdi->refcount, media_device_instance_release); | ||
| 134 | } | ||
| 135 | EXPORT_SYMBOL_GPL(media_device_delete); | ||
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c index 6b87a721dc49..d5aa30eeff4a 100644 --- a/drivers/media/media-devnode.c +++ b/drivers/media/media-devnode.c | |||
| @@ -251,6 +251,7 @@ int __must_check media_devnode_register(struct media_device *mdev, | |||
| 251 | /* Part 2: Initialize the character device */ | 251 | /* Part 2: Initialize the character device */ |
| 252 | cdev_init(&devnode->cdev, &media_devnode_fops); | 252 | cdev_init(&devnode->cdev, &media_devnode_fops); |
| 253 | devnode->cdev.owner = owner; | 253 | devnode->cdev.owner = owner; |
| 254 | kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); | ||
| 254 | 255 | ||
| 255 | /* Part 3: Add the media and char device */ | 256 | /* Part 3: Add the media and char device */ |
| 256 | ret = cdev_device_add(&devnode->cdev, &devnode->dev); | 257 | ret = cdev_device_add(&devnode->cdev, &devnode->dev); |
| @@ -290,8 +291,9 @@ void media_devnode_unregister(struct media_devnode *devnode) | |||
| 290 | mutex_lock(&media_devnode_lock); | 291 | mutex_lock(&media_devnode_lock); |
| 291 | /* Delete the cdev on this minor as well */ | 292 | /* Delete the cdev on this minor as well */ |
| 292 | cdev_device_del(&devnode->cdev, &devnode->dev); | 293 | cdev_device_del(&devnode->cdev, &devnode->dev); |
| 293 | mutex_unlock(&media_devnode_lock); | ||
| 294 | devnode->media_dev = NULL; | 294 | devnode->media_dev = NULL; |
| 295 | mutex_unlock(&media_devnode_lock); | ||
| 296 | |||
| 295 | put_device(&devnode->dev); | 297 | put_device(&devnode->dev); |
| 296 | } | 298 | } |
| 297 | 299 | ||
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 0b1cb3559140..a998a2e0ea1d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/bitmap.h> | 19 | #include <linux/bitmap.h> |
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/property.h> | 20 | #include <linux/property.h> |
| 22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 23 | #include <media/media-entity.h> | 22 | #include <media/media-entity.h> |
| @@ -436,7 +435,10 @@ __must_check int __media_pipeline_start(struct media_entity *entity, | |||
| 436 | 435 | ||
| 437 | entity->stream_count++; | 436 | entity->stream_count++; |
| 438 | 437 | ||
| 439 | if (WARN_ON(entity->pipe && entity->pipe != pipe)) { | 438 | if (entity->pipe && entity->pipe != pipe) { |
| 439 | pr_err("Pipe active for %s. Can't start for %s\n", | ||
| 440 | entity->name, | ||
| 441 | entity_err->name); | ||
| 440 | ret = -EBUSY; | 442 | ret = -EBUSY; |
| 441 | goto error; | 443 | goto error; |
| 442 | } | 444 | } |
| @@ -588,33 +590,6 @@ void media_pipeline_stop(struct media_entity *entity) | |||
| 588 | EXPORT_SYMBOL_GPL(media_pipeline_stop); | 590 | EXPORT_SYMBOL_GPL(media_pipeline_stop); |
| 589 | 591 | ||
| 590 | /* ----------------------------------------------------------------------------- | 592 | /* ----------------------------------------------------------------------------- |
| 591 | * Module use count | ||
| 592 | */ | ||
| 593 | |||
| 594 | struct media_entity *media_entity_get(struct media_entity *entity) | ||
| 595 | { | ||
| 596 | if (entity == NULL) | ||
| 597 | return NULL; | ||
| 598 | |||
| 599 | if (entity->graph_obj.mdev->dev && | ||
| 600 | !try_module_get(entity->graph_obj.mdev->dev->driver->owner)) | ||
| 601 | return NULL; | ||
| 602 | |||
| 603 | return entity; | ||
| 604 | } | ||
| 605 | EXPORT_SYMBOL_GPL(media_entity_get); | ||
| 606 | |||
| 607 | void media_entity_put(struct media_entity *entity) | ||
| 608 | { | ||
| 609 | if (entity == NULL) | ||
| 610 | return; | ||
| 611 | |||
| 612 | if (entity->graph_obj.mdev->dev) | ||
| 613 | module_put(entity->graph_obj.mdev->dev->driver->owner); | ||
| 614 | } | ||
| 615 | EXPORT_SYMBOL_GPL(media_entity_put); | ||
| 616 | |||
| 617 | /* ----------------------------------------------------------------------------- | ||
| 618 | * Links management | 593 | * Links management |
| 619 | */ | 594 | */ |
| 620 | 595 | ||
diff --git a/drivers/media/media-request.c b/drivers/media/media-request.c index 9e5fd2ac769e..e3fca436c75b 100644 --- a/drivers/media/media-request.c +++ b/drivers/media/media-request.c | |||
| @@ -251,7 +251,7 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd) | |||
| 251 | 251 | ||
| 252 | if (!mdev || !mdev->ops || | 252 | if (!mdev || !mdev->ops || |
| 253 | !mdev->ops->req_validate || !mdev->ops->req_queue) | 253 | !mdev->ops->req_validate || !mdev->ops->req_queue) |
| 254 | return ERR_PTR(-EACCES); | 254 | return ERR_PTR(-EBADR); |
| 255 | 255 | ||
| 256 | f = fdget(request_fd); | 256 | f = fdget(request_fd); |
| 257 | if (!f.file) | 257 | if (!f.file) |
| @@ -407,7 +407,7 @@ int media_request_object_bind(struct media_request *req, | |||
| 407 | int ret = -EBUSY; | 407 | int ret = -EBUSY; |
| 408 | 408 | ||
| 409 | if (WARN_ON(!ops->release)) | 409 | if (WARN_ON(!ops->release)) |
| 410 | return -EACCES; | 410 | return -EBADR; |
| 411 | 411 | ||
| 412 | spin_lock_irqsave(&req->lock, flags); | 412 | spin_lock_irqsave(&req->lock, flags); |
| 413 | 413 | ||
diff --git a/drivers/media/mmc/siano/Kconfig b/drivers/media/mmc/siano/Kconfig index 7693487e2f63..3941ee8352bb 100644 --- a/drivers/media/mmc/siano/Kconfig +++ b/drivers/media/mmc/siano/Kconfig | |||
| @@ -9,5 +9,5 @@ config SMS_SDIO_DRV | |||
| 9 | depends on !RC_CORE || RC_CORE | 9 | depends on !RC_CORE || RC_CORE |
| 10 | select MEDIA_COMMON_OPTIONS | 10 | select MEDIA_COMMON_OPTIONS |
| 11 | select SMS_SIANO_MDTV | 11 | select SMS_SIANO_MDTV |
| 12 | ---help--- | 12 | help |
| 13 | Choose if you would like to have Siano's support for SDIO interface | 13 | Choose if you would like to have Siano's support for SDIO interface |
diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig index bc89e37608cd..0f46db7d5ffc 100644 --- a/drivers/media/pci/bt8xx/Kconfig +++ b/drivers/media/pci/bt8xx/Kconfig | |||
| @@ -13,7 +13,7 @@ config VIDEO_BT848 | |||
| 13 | select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT | 13 | select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select RADIO_ADAPTERS | 14 | select RADIO_ADAPTERS |
| 15 | select RADIO_TEA575X | 15 | select RADIO_TEA575X |
| 16 | ---help--- | 16 | help |
| 17 | Support for BT848 based frame grabber/overlay boards. This includes | 17 | Support for BT848 based frame grabber/overlay boards. This includes |
| 18 | the Miro, Hauppauge and STB boards. Please read the material in | 18 | the Miro, Hauppauge and STB boards. Please read the material in |
| 19 | <file:Documentation/media/v4l-drivers/bttv.rst> for more information. | 19 | <file:Documentation/media/v4l-drivers/bttv.rst> for more information. |
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c index c94318c71a0c..e929797206f6 100644 --- a/drivers/media/pci/bt8xx/dst.c +++ b/drivers/media/pci/bt8xx/dst.c | |||
| @@ -1100,7 +1100,8 @@ static int dst_get_device_id(struct dst_state *state) | |||
| 1100 | /* Card capabilities */ | 1100 | /* Card capabilities */ |
| 1101 | state->dst_hw_cap = p_dst_type->dst_feature; | 1101 | state->dst_hw_cap = p_dst_type->dst_feature; |
| 1102 | pr_err("Recognise [%s]\n", p_dst_type->device_id); | 1102 | pr_err("Recognise [%s]\n", p_dst_type->device_id); |
| 1103 | strncpy(&state->fw_name[0], p_dst_type->device_id, 6); | 1103 | strscpy(state->fw_name, p_dst_type->device_id, |
| 1104 | sizeof(state->fw_name)); | ||
| 1104 | /* Multiple tuners */ | 1105 | /* Multiple tuners */ |
| 1105 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { | 1106 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { |
| 1106 | switch (use_dst_type) { | 1107 | switch (use_dst_type) { |
diff --git a/drivers/media/pci/bt8xx/dst_common.h b/drivers/media/pci/bt8xx/dst_common.h index 6a2cfdd44e3e..79dec1b1722c 100644 --- a/drivers/media/pci/bt8xx/dst_common.h +++ b/drivers/media/pci/bt8xx/dst_common.h | |||
| @@ -138,7 +138,7 @@ struct dst_state { | |||
| 138 | u32 tuner_type; | 138 | u32 tuner_type; |
| 139 | char *tuner_name; | 139 | char *tuner_name; |
| 140 | struct mutex dst_mutex; | 140 | struct mutex dst_mutex; |
| 141 | u8 fw_name[8]; | 141 | char fw_name[8]; |
| 142 | struct dvb_device *dst_ca; | 142 | struct dvb_device *dst_ca; |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig index aa35cbc0a904..9a544bab3178 100644 --- a/drivers/media/pci/cobalt/Kconfig +++ b/drivers/media/pci/cobalt/Kconfig | |||
| @@ -11,7 +11,7 @@ config VIDEO_COBALT | |||
| 11 | select VIDEO_ADV7511 | 11 | select VIDEO_ADV7511 |
| 12 | select VIDEO_ADV7842 | 12 | select VIDEO_ADV7842 |
| 13 | select VIDEOBUF2_DMA_SG | 13 | select VIDEOBUF2_DMA_SG |
| 14 | ---help--- | 14 | help |
| 15 | This is a video4linux driver for the Cisco PCIe Cobalt card. | 15 | This is a video4linux driver for the Cisco PCIe Cobalt card. |
| 16 | 16 | ||
| 17 | This board is sadly not available outside of Cisco, but it is | 17 | This board is sadly not available outside of Cisco, but it is |
diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c index 04783e78cc12..a518927abae1 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.c +++ b/drivers/media/pci/cobalt/cobalt-irq.c | |||
| @@ -128,7 +128,7 @@ done: | |||
| 128 | cb->vb.sequence = s->sequence++; | 128 | cb->vb.sequence = s->sequence++; |
| 129 | vb2_buffer_done(&cb->vb.vb2_buf, | 129 | vb2_buffer_done(&cb->vb.vb2_buf, |
| 130 | (skip || s->unstable_frame) ? | 130 | (skip || s->unstable_frame) ? |
| 131 | VB2_BUF_STATE_REQUEUEING : VB2_BUF_STATE_DONE); | 131 | VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | irqreturn_t cobalt_irq_handler(int irq, void *dev_id) | 134 | irqreturn_t cobalt_irq_handler(int irq, void *dev_id) |
diff --git a/drivers/media/pci/cx18/Kconfig b/drivers/media/pci/cx18/Kconfig index c675b83c43a9..96477bba0d5c 100644 --- a/drivers/media/pci/cx18/Kconfig +++ b/drivers/media/pci/cx18/Kconfig | |||
| @@ -13,7 +13,7 @@ config VIDEO_CX18 | |||
| 13 | select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT | 13 | select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 14 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
| 15 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT | 15 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT |
| 16 | ---help--- | 16 | help |
| 17 | This is a video4linux driver for Conexant cx23418 based | 17 | This is a video4linux driver for Conexant cx23418 based |
| 18 | PCI combo video recorder devices. | 18 | PCI combo video recorder devices. |
| 19 | 19 | ||
| @@ -27,7 +27,7 @@ config VIDEO_CX18_ALSA | |||
| 27 | tristate "Conexant 23418 DMA audio support" | 27 | tristate "Conexant 23418 DMA audio support" |
| 28 | depends on VIDEO_CX18 && SND | 28 | depends on VIDEO_CX18 && SND |
| 29 | select SND_PCM | 29 | select SND_PCM |
| 30 | ---help--- | 30 | help |
| 31 | This is a video4linux driver for direct (DMA) audio on | 31 | This is a video4linux driver for direct (DMA) audio on |
| 32 | Conexant 23418 based TV cards using ALSA. | 32 | Conexant 23418 based TV cards using ALSA. |
| 33 | 33 | ||
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index f778965a2eb8..59e78fb17575 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c | |||
| @@ -484,7 +484,7 @@ static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf, | |||
| 484 | 484 | ||
| 485 | CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); | 485 | CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); |
| 486 | if (rc > 0) | 486 | if (rc > 0) |
| 487 | pos += rc; | 487 | *pos += rc; |
| 488 | return rc; | 488 | return rc; |
| 489 | } | 489 | } |
| 490 | 490 | ||
diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index 3435bbaa3167..1bba9e497915 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig | |||
| @@ -43,7 +43,7 @@ config VIDEO_CX23885 | |||
| 43 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT | 43 | select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT |
| 44 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT | 44 | select MEDIA_TUNER_M88RS6000T if MEDIA_SUBDRV_AUTOSELECT |
| 45 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT | 45 | select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT |
| 46 | ---help--- | 46 | help |
| 47 | This is a video4linux driver for Conexant 23885 based | 47 | This is a video4linux driver for Conexant 23885 based |
| 48 | TV cards. | 48 | TV cards. |
| 49 | 49 | ||
| @@ -54,7 +54,7 @@ config MEDIA_ALTERA_CI | |||
| 54 | tristate "Altera FPGA based CI module" | 54 | tristate "Altera FPGA based CI module" |
| 55 | depends on VIDEO_CX23885 && DVB_CORE | 55 | depends on VIDEO_CX23885 && DVB_CORE |
| 56 | select ALTERA_STAPL | 56 | select ALTERA_STAPL |
| 57 | ---help--- | 57 | help |
| 58 | An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card. | 58 | An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card. |
| 59 | 59 | ||
| 60 | To compile this driver as a module, choose M here: the | 60 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 0d0929c54f93..e2e63f05645e 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
| @@ -1474,8 +1474,9 @@ static int dvb_register(struct cx23885_tsport *port) | |||
| 1474 | if (fe0->dvb.frontend != NULL) { | 1474 | if (fe0->dvb.frontend != NULL) { |
| 1475 | struct i2c_adapter *tun_i2c; | 1475 | struct i2c_adapter *tun_i2c; |
| 1476 | 1476 | ||
| 1477 | fe0->dvb.frontend->sec_priv = kmalloc(sizeof(dib7000p_ops), GFP_KERNEL); | 1477 | fe0->dvb.frontend->sec_priv = kmemdup(&dib7000p_ops, sizeof(dib7000p_ops), GFP_KERNEL); |
| 1478 | memcpy(fe0->dvb.frontend->sec_priv, &dib7000p_ops, sizeof(dib7000p_ops)); | 1478 | if (!fe0->dvb.frontend->sec_priv) |
| 1479 | return -ENOMEM; | ||
| 1479 | tun_i2c = dib7000p_ops.get_i2c_master(fe0->dvb.frontend, DIBX000_I2C_INTERFACE_TUNER, 1); | 1480 | tun_i2c = dib7000p_ops.get_i2c_master(fe0->dvb.frontend, DIBX000_I2C_INTERFACE_TUNER, 1); |
| 1480 | if (!dvb_attach(dib0070_attach, fe0->dvb.frontend, tun_i2c, &dib7070p_dib0070_config)) | 1481 | if (!dvb_attach(dib0070_attach, fe0->dvb.frontend, tun_i2c, &dib7070p_dib0070_config)) |
| 1481 | return -ENODEV; | 1482 | return -ENODEV; |
diff --git a/drivers/media/pci/cx25821/Kconfig b/drivers/media/pci/cx25821/Kconfig index 1755d3d2feaa..a64fa9a6d5d5 100644 --- a/drivers/media/pci/cx25821/Kconfig +++ b/drivers/media/pci/cx25821/Kconfig | |||
| @@ -3,7 +3,7 @@ config VIDEO_CX25821 | |||
| 3 | depends on VIDEO_DEV && PCI && I2C | 3 | depends on VIDEO_DEV && PCI && I2C |
| 4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
| 5 | select VIDEOBUF2_DMA_SG | 5 | select VIDEOBUF2_DMA_SG |
| 6 | ---help--- | 6 | help |
| 7 | This is a video4linux driver for Conexant 25821 based | 7 | This is a video4linux driver for Conexant 25821 based |
| 8 | TV cards. | 8 | TV cards. |
| 9 | 9 | ||
| @@ -14,7 +14,7 @@ config VIDEO_CX25821_ALSA | |||
| 14 | tristate "Conexant 25821 DMA audio support" | 14 | tristate "Conexant 25821 DMA audio support" |
| 15 | depends on VIDEO_CX25821 && SND | 15 | depends on VIDEO_CX25821 && SND |
| 16 | select SND_PCM | 16 | select SND_PCM |
| 17 | ---help--- | 17 | help |
| 18 | This is a video4linux driver for direct (DMA) audio on | 18 | This is a video4linux driver for direct (DMA) audio on |
| 19 | Conexant 25821 based capture cards using ALSA. | 19 | Conexant 25821 based capture cards using ALSA. |
| 20 | 20 | ||
diff --git a/drivers/media/pci/cx88/Kconfig b/drivers/media/pci/cx88/Kconfig index 14b813d634a8..fbb17ddb6bc3 100644 --- a/drivers/media/pci/cx88/Kconfig +++ b/drivers/media/pci/cx88/Kconfig | |||
| @@ -6,7 +6,7 @@ config VIDEO_CX88 | |||
| 6 | select VIDEO_TUNER | 6 | select VIDEO_TUNER |
| 7 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
| 8 | select VIDEO_WM8775 if MEDIA_SUBDRV_AUTOSELECT | 8 | select VIDEO_WM8775 if MEDIA_SUBDRV_AUTOSELECT |
| 9 | ---help--- | 9 | help |
| 10 | This is a video4linux driver for Conexant 2388x based | 10 | This is a video4linux driver for Conexant 2388x based |
| 11 | TV cards. | 11 | TV cards. |
| 12 | 12 | ||
| @@ -17,7 +17,7 @@ config VIDEO_CX88_ALSA | |||
| 17 | tristate "Conexant 2388x DMA audio support" | 17 | tristate "Conexant 2388x DMA audio support" |
| 18 | depends on VIDEO_CX88 && SND | 18 | depends on VIDEO_CX88 && SND |
| 19 | select SND_PCM | 19 | select SND_PCM |
| 20 | ---help--- | 20 | help |
| 21 | This is a video4linux driver for direct (DMA) audio on | 21 | This is a video4linux driver for direct (DMA) audio on |
| 22 | Conexant 2388x based TV cards using ALSA. | 22 | Conexant 2388x based TV cards using ALSA. |
| 23 | 23 | ||
| @@ -33,7 +33,7 @@ config VIDEO_CX88_BLACKBIRD | |||
| 33 | tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" | 33 | tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" |
| 34 | depends on VIDEO_CX88 | 34 | depends on VIDEO_CX88 |
| 35 | select VIDEO_CX2341X | 35 | select VIDEO_CX2341X |
| 36 | ---help--- | 36 | help |
| 37 | This adds support for MPEG encoder cards based on the | 37 | This adds support for MPEG encoder cards based on the |
| 38 | Blackbird reference design, using the Conexant 2388x | 38 | Blackbird reference design, using the Conexant 2388x |
| 39 | and 23416 chips. | 39 | and 23416 chips. |
| @@ -64,7 +64,7 @@ config VIDEO_CX88_DVB | |||
| 64 | select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT | 64 | select DVB_DS3000 if MEDIA_SUBDRV_AUTOSELECT |
| 65 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT | 65 | select DVB_TS2020 if MEDIA_SUBDRV_AUTOSELECT |
| 66 | select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT | 66 | select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT |
| 67 | ---help--- | 67 | help |
| 68 | This adds support for DVB/ATSC cards based on the | 68 | This adds support for DVB/ATSC cards based on the |
| 69 | Conexant 2388x chip. | 69 | Conexant 2388x chip. |
| 70 | 70 | ||
| @@ -75,7 +75,7 @@ config VIDEO_CX88_ENABLE_VP3054 | |||
| 75 | bool "VP-3054 Secondary I2C Bus Support" | 75 | bool "VP-3054 Secondary I2C Bus Support" |
| 76 | default y | 76 | default y |
| 77 | depends on VIDEO_CX88_DVB && DVB_MT352 | 77 | depends on VIDEO_CX88_DVB && DVB_MT352 |
| 78 | ---help--- | 78 | help |
| 79 | This adds DVB-T support for cards based on the | 79 | This adds DVB-T support for cards based on the |
| 80 | Conexant 2388x chip and the MT352 demodulator, | 80 | Conexant 2388x chip and the MT352 demodulator, |
| 81 | which also require support for the VP-3054 | 81 | which also require support for the VP-3054 |
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig index 16faef265e97..fc98b6d575d9 100644 --- a/drivers/media/pci/ddbridge/Kconfig +++ b/drivers/media/pci/ddbridge/Kconfig | |||
| @@ -15,7 +15,7 @@ config DVB_DDBRIDGE | |||
| 15 | select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT | 15 | select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT |
| 16 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT | 16 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT |
| 17 | select DVB_DUMMY_FE if MEDIA_SUBDRV_AUTOSELECT | 17 | select DVB_DUMMY_FE if MEDIA_SUBDRV_AUTOSELECT |
| 18 | ---help--- | 18 | help |
| 19 | Support for cards with the Digital Devices PCI express bridge: | 19 | Support for cards with the Digital Devices PCI express bridge: |
| 20 | - Octopus PCIe Bridge | 20 | - Octopus PCIe Bridge |
| 21 | - Octopus mini PCIe Bridge | 21 | - Octopus mini PCIe Bridge |
| @@ -36,7 +36,7 @@ config DVB_DDBRIDGE_MSIENABLE | |||
| 36 | depends on DVB_DDBRIDGE | 36 | depends on DVB_DDBRIDGE |
| 37 | depends on PCI_MSI | 37 | depends on PCI_MSI |
| 38 | default n | 38 | default n |
| 39 | ---help--- | 39 | help |
| 40 | Use PCI MSI (Message Signaled Interrupts) per default. Enabling this | 40 | Use PCI MSI (Message Signaled Interrupts) per default. Enabling this |
| 41 | might lead to I2C errors originating from the bridge in conjunction | 41 | might lead to I2C errors originating from the bridge in conjunction |
| 42 | with certain SATA controllers, requiring a reload of the ddbridge | 42 | with certain SATA controllers, requiring a reload of the ddbridge |
diff --git a/drivers/media/pci/dt3155/Kconfig b/drivers/media/pci/dt3155/Kconfig index 858b0f2f15be..d770eec541d4 100644 --- a/drivers/media/pci/dt3155/Kconfig +++ b/drivers/media/pci/dt3155/Kconfig | |||
| @@ -3,7 +3,7 @@ config VIDEO_DT3155 | |||
| 3 | depends on PCI && VIDEO_DEV && VIDEO_V4L2 | 3 | depends on PCI && VIDEO_DEV && VIDEO_V4L2 |
| 4 | select VIDEOBUF2_DMA_CONTIG | 4 | select VIDEOBUF2_DMA_CONTIG |
| 5 | default n | 5 | default n |
| 6 | ---help--- | 6 | help |
| 7 | Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. | 7 | Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. |
| 8 | Say Y here if you have this hardware. | 8 | Say Y here if you have this hardware. |
| 9 | In doubt, say N. | 9 | In doubt, say N. |
diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig index 715f77651482..bd518bdc9f5f 100644 --- a/drivers/media/pci/intel/ipu3/Kconfig +++ b/drivers/media/pci/intel/ipu3/Kconfig | |||
| @@ -7,7 +7,7 @@ config VIDEO_IPU3_CIO2 | |||
| 7 | select V4L2_FWNODE | 7 | select V4L2_FWNODE |
| 8 | select VIDEOBUF2_DMA_SG | 8 | select VIDEOBUF2_DMA_SG |
| 9 | 9 | ||
| 10 | ---help--- | 10 | help |
| 11 | This is the Intel IPU3 CIO2 CSI-2 receiver unit, found in Intel | 11 | This is the Intel IPU3 CIO2 CSI-2 receiver unit, found in Intel |
| 12 | Skylake and Kaby Lake SoCs and used for capturing images and | 12 | Skylake and Kaby Lake SoCs and used for capturing images and |
| 13 | video from a camera sensor. | 13 | video from a camera sensor. |
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index f8020ebe9f05..2a52a393fe74 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c | |||
| @@ -1601,6 +1601,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q) | |||
| 1601 | subdev->owner = THIS_MODULE; | 1601 | subdev->owner = THIS_MODULE; |
| 1602 | snprintf(subdev->name, sizeof(subdev->name), | 1602 | snprintf(subdev->name, sizeof(subdev->name), |
| 1603 | CIO2_ENTITY_NAME " %td", q - cio2->queue); | 1603 | CIO2_ENTITY_NAME " %td", q - cio2->queue); |
| 1604 | subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; | ||
| 1604 | v4l2_set_subdevdata(subdev, cio2); | 1605 | v4l2_set_subdevdata(subdev, cio2); |
| 1605 | r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev); | 1606 | r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev); |
| 1606 | if (r) { | 1607 | if (r) { |
diff --git a/drivers/media/pci/ivtv/Kconfig b/drivers/media/pci/ivtv/Kconfig index 06ca4e23f9fb..e96b3c182a2f 100644 --- a/drivers/media/pci/ivtv/Kconfig +++ b/drivers/media/pci/ivtv/Kconfig | |||
| @@ -18,7 +18,7 @@ config VIDEO_IVTV | |||
| 18 | select VIDEO_VP27SMPX | 18 | select VIDEO_VP27SMPX |
| 19 | select VIDEO_UPD64031A | 19 | select VIDEO_UPD64031A |
| 20 | select VIDEO_UPD64083 | 20 | select VIDEO_UPD64083 |
| 21 | ---help--- | 21 | help |
| 22 | This is a video4linux driver for Conexant cx23416 or cx23415 based | 22 | This is a video4linux driver for Conexant cx23416 or cx23415 based |
| 23 | PCI personal video recorder devices. | 23 | PCI personal video recorder devices. |
| 24 | 24 | ||
| @@ -32,7 +32,7 @@ config VIDEO_IVTV_DEPRECATED_IOCTLS | |||
| 32 | bool "enable the DVB ioctls abuse on ivtv driver" | 32 | bool "enable the DVB ioctls abuse on ivtv driver" |
| 33 | depends on VIDEO_IVTV | 33 | depends on VIDEO_IVTV |
| 34 | default n | 34 | default n |
| 35 | ---help--- | 35 | help |
| 36 | Enable the usage of the a DVB set of ioctls that were abused by | 36 | Enable the usage of the a DVB set of ioctls that were abused by |
| 37 | IVTV driver for a while. | 37 | IVTV driver for a while. |
| 38 | 38 | ||
| @@ -45,7 +45,7 @@ config VIDEO_IVTV_ALSA | |||
| 45 | tristate "Conexant cx23415/cx23416 ALSA interface for PCM audio capture" | 45 | tristate "Conexant cx23415/cx23416 ALSA interface for PCM audio capture" |
| 46 | depends on VIDEO_IVTV && SND | 46 | depends on VIDEO_IVTV && SND |
| 47 | select SND_PCM | 47 | select SND_PCM |
| 48 | ---help--- | 48 | help |
| 49 | This driver provides an ALSA interface as another method for user | 49 | This driver provides an ALSA interface as another method for user |
| 50 | applications to obtain PCM audio data from Conexant cx23415/cx23416 | 50 | applications to obtain PCM audio data from Conexant cx23415/cx23416 |
| 51 | based PCI TV cards supported by the ivtv driver. | 51 | based PCI TV cards supported by the ivtv driver. |
| @@ -63,7 +63,7 @@ config VIDEO_FB_IVTV | |||
| 63 | select FB_CFB_FILLRECT | 63 | select FB_CFB_FILLRECT |
| 64 | select FB_CFB_COPYAREA | 64 | select FB_CFB_COPYAREA |
| 65 | select FB_CFB_IMAGEBLIT | 65 | select FB_CFB_IMAGEBLIT |
| 66 | ---help--- | 66 | help |
| 67 | This is a framebuffer driver for the Conexant cx23415 MPEG | 67 | This is a framebuffer driver for the Conexant cx23415 MPEG |
| 68 | encoder/decoder. | 68 | encoder/decoder. |
| 69 | 69 | ||
| @@ -77,7 +77,7 @@ config VIDEO_FB_IVTV_FORCE_PAT | |||
| 77 | bool "force cx23415 framebuffer init with x86 PAT enabled" | 77 | bool "force cx23415 framebuffer init with x86 PAT enabled" |
| 78 | depends on VIDEO_FB_IVTV && X86_PAT | 78 | depends on VIDEO_FB_IVTV && X86_PAT |
| 79 | default n | 79 | default n |
| 80 | ---help--- | 80 | help |
| 81 | With PAT enabled, the cx23415 framebuffer driver does not | 81 | With PAT enabled, the cx23415 framebuffer driver does not |
| 82 | utilize write-combined caching on the framebuffer memory. | 82 | utilize write-combined caching on the framebuffer memory. |
| 83 | For this reason, the driver will by default disable itself | 83 | For this reason, the driver will by default disable itself |
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index 6196daae4b3e..043ac0ae9ed0 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c | |||
| @@ -420,7 +420,7 @@ static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t co | |||
| 420 | 420 | ||
| 421 | IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); | 421 | IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); |
| 422 | if (rc > 0) | 422 | if (rc > 0) |
| 423 | pos += rc; | 423 | *pos += rc; |
| 424 | return rc; | 424 | return rc; |
| 425 | } | 425 | } |
| 426 | 426 | ||
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c index 6528a2180119..f8b503ef42bc 100644 --- a/drivers/media/pci/mantis/mantis_i2c.c +++ b/drivers/media/pci/mantis/mantis_i2c.c | |||
| @@ -225,7 +225,7 @@ int mantis_i2c_init(struct mantis_pci *mantis) | |||
| 225 | 225 | ||
| 226 | init_waitqueue_head(&mantis->i2c_wq); | 226 | init_waitqueue_head(&mantis->i2c_wq); |
| 227 | mutex_init(&mantis->i2c_lock); | 227 | mutex_init(&mantis->i2c_lock); |
| 228 | strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); | 228 | strscpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name)); |
| 229 | i2c_set_adapdata(i2c_adapter, mantis); | 229 | i2c_set_adapdata(i2c_adapter, mantis); |
| 230 | 230 | ||
| 231 | i2c_adapter->owner = THIS_MODULE; | 231 | i2c_adapter->owner = THIS_MODULE; |
diff --git a/drivers/media/pci/meye/Kconfig b/drivers/media/pci/meye/Kconfig index 9a50f54231ad..ce0463c81886 100644 --- a/drivers/media/pci/meye/Kconfig +++ b/drivers/media/pci/meye/Kconfig | |||
| @@ -2,7 +2,7 @@ config VIDEO_MEYE | |||
| 2 | tristate "Sony Vaio Picturebook Motion Eye Video For Linux" | 2 | tristate "Sony Vaio Picturebook Motion Eye Video For Linux" |
| 3 | depends on PCI && VIDEO_V4L2 | 3 | depends on PCI && VIDEO_V4L2 |
| 4 | depends on SONY_LAPTOP || COMPILE_TEST | 4 | depends on SONY_LAPTOP || COMPILE_TEST |
| 5 | ---help--- | 5 | help |
| 6 | This is the video4linux driver for the Motion Eye camera found | 6 | This is the video4linux driver for the Motion Eye camera found |
| 7 | in the Vaio Picturebook laptops. Please read the material in | 7 | in the Vaio Picturebook laptops. Please read the material in |
| 8 | <file:Documentation/media/v4l-drivers/meye.rst> for more information. | 8 | <file:Documentation/media/v4l-drivers/meye.rst> for more information. |
diff --git a/drivers/media/pci/netup_unidvb/Kconfig b/drivers/media/pci/netup_unidvb/Kconfig index b663154d0cc4..60057585f04c 100644 --- a/drivers/media/pci/netup_unidvb/Kconfig +++ b/drivers/media/pci/netup_unidvb/Kconfig | |||
| @@ -8,7 +8,7 @@ config DVB_NETUP_UNIDVB | |||
| 8 | select DVB_HELENE if MEDIA_SUBDRV_AUTOSELECT | 8 | select DVB_HELENE if MEDIA_SUBDRV_AUTOSELECT |
| 9 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT | 9 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT |
| 10 | select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT | 10 | select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT |
| 11 | ---help--- | 11 | help |
| 12 | Support for NetUP PCI express Universal DVB card. | 12 | Support for NetUP PCI express Universal DVB card. |
| 13 | 13 | ||
| 14 | Say Y when you want to support NetUP Dual Universal DVB card. | 14 | Say Y when you want to support NetUP Dual Universal DVB card. |
diff --git a/drivers/media/pci/ngene/Kconfig b/drivers/media/pci/ngene/Kconfig index e06d019996f3..8a80a5bab8e9 100644 --- a/drivers/media/pci/ngene/Kconfig +++ b/drivers/media/pci/ngene/Kconfig | |||
| @@ -15,6 +15,6 @@ config DVB_NGENE | |||
| 15 | select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT | 15 | select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT |
| 16 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT | 16 | select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT |
| 17 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT | 17 | select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT |
| 18 | ---help--- | 18 | help |
| 19 | Support for Micronas PCI express cards with nGene bridge. | 19 | Support for Micronas PCI express cards with nGene bridge. |
| 20 | 20 | ||
diff --git a/drivers/media/pci/saa7134/Kconfig b/drivers/media/pci/saa7134/Kconfig index b44e0d70907e..8b28783b3fcd 100644 --- a/drivers/media/pci/saa7134/Kconfig +++ b/drivers/media/pci/saa7134/Kconfig | |||
| @@ -7,7 +7,7 @@ config VIDEO_SAA7134 | |||
| 7 | select CRC32 | 7 | select CRC32 |
| 8 | select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT | 8 | select VIDEO_SAA6588 if MEDIA_SUBDRV_AUTOSELECT |
| 9 | select VIDEO_SAA6752HS if MEDIA_SUBDRV_AUTOSELECT | 9 | select VIDEO_SAA6752HS if MEDIA_SUBDRV_AUTOSELECT |
| 10 | ---help--- | 10 | help |
| 11 | This is a video4linux driver for Philips SAA713x based | 11 | This is a video4linux driver for Philips SAA713x based |
| 12 | TV cards. | 12 | TV cards. |
| 13 | 13 | ||
| @@ -18,7 +18,7 @@ config VIDEO_SAA7134_ALSA | |||
| 18 | tristate "Philips SAA7134 DMA audio support" | 18 | tristate "Philips SAA7134 DMA audio support" |
| 19 | depends on VIDEO_SAA7134 && SND | 19 | depends on VIDEO_SAA7134 && SND |
| 20 | select SND_PCM | 20 | select SND_PCM |
| 21 | ---help--- | 21 | help |
| 22 | This is a video4linux driver for direct (DMA) audio in | 22 | This is a video4linux driver for direct (DMA) audio in |
| 23 | Philips SAA713x based TV cards using ALSA | 23 | Philips SAA713x based TV cards using ALSA |
| 24 | 24 | ||
| @@ -31,7 +31,7 @@ config VIDEO_SAA7134_RC | |||
| 31 | depends on VIDEO_SAA7134 | 31 | depends on VIDEO_SAA7134 |
| 32 | depends on !(RC_CORE=m && VIDEO_SAA7134=y) | 32 | depends on !(RC_CORE=m && VIDEO_SAA7134=y) |
| 33 | default y | 33 | default y |
| 34 | ---help--- | 34 | help |
| 35 | Enables Remote Controller support on saa7134 driver. | 35 | Enables Remote Controller support on saa7134 driver. |
| 36 | 36 | ||
| 37 | config VIDEO_SAA7134_DVB | 37 | config VIDEO_SAA7134_DVB |
| @@ -57,7 +57,7 @@ config VIDEO_SAA7134_DVB | |||
| 57 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 57 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
| 58 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT | 58 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT |
| 59 | select DVB_ZL10039 if MEDIA_SUBDRV_AUTOSELECT | 59 | select DVB_ZL10039 if MEDIA_SUBDRV_AUTOSELECT |
| 60 | ---help--- | 60 | help |
| 61 | This adds support for DVB cards based on the | 61 | This adds support for DVB cards based on the |
| 62 | Philips saa7134 chip. | 62 | Philips saa7134 chip. |
| 63 | 63 | ||
| @@ -68,6 +68,6 @@ config VIDEO_SAA7134_GO7007 | |||
| 68 | tristate "go7007 support for saa7134 based TV cards" | 68 | tristate "go7007 support for saa7134 based TV cards" |
| 69 | depends on VIDEO_SAA7134 | 69 | depends on VIDEO_SAA7134 |
| 70 | depends on VIDEO_GO7007 | 70 | depends on VIDEO_GO7007 |
| 71 | ---help--- | 71 | help |
| 72 | Enables saa7134 driver support for boards with go7007 | 72 | Enables saa7134 driver support for boards with go7007 |
| 73 | MPEG encoder (WIS Voyager or compatible). | 73 | MPEG encoder (WIS Voyager or compatible). |
diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c index 275c5e151818..626e130a9770 100644 --- a/drivers/media/pci/saa7134/saa7134-go7007.c +++ b/drivers/media/pci/saa7134/saa7134-go7007.c | |||
| @@ -444,7 +444,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev) | |||
| 444 | sd = &saa->sd; | 444 | sd = &saa->sd; |
| 445 | v4l2_subdev_init(sd, &saa7134_go7007_sd_ops); | 445 | v4l2_subdev_init(sd, &saa7134_go7007_sd_ops); |
| 446 | v4l2_set_subdevdata(sd, saa); | 446 | v4l2_set_subdevdata(sd, saa); |
| 447 | strncpy(sd->name, "saa7134-go7007", sizeof(sd->name)); | 447 | strscpy(sd->name, "saa7134-go7007", sizeof(sd->name)); |
| 448 | 448 | ||
| 449 | /* Allocate a couple pages for receiving the compressed stream */ | 449 | /* Allocate a couple pages for receiving the compressed stream */ |
| 450 | saa->top = (u8 *)get_zeroed_page(GFP_KERNEL); | 450 | saa->top = (u8 *)get_zeroed_page(GFP_KERNEL); |
diff --git a/drivers/media/pci/saa7146/Kconfig b/drivers/media/pci/saa7146/Kconfig index da88b77a916c..60d9862580ff 100644 --- a/drivers/media/pci/saa7146/Kconfig +++ b/drivers/media/pci/saa7146/Kconfig | |||
| @@ -2,7 +2,7 @@ config VIDEO_HEXIUM_GEMINI | |||
| 2 | tristate "Hexium Gemini frame grabber" | 2 | tristate "Hexium Gemini frame grabber" |
| 3 | depends on PCI && VIDEO_V4L2 && I2C | 3 | depends on PCI && VIDEO_V4L2 && I2C |
| 4 | select VIDEO_SAA7146_VV | 4 | select VIDEO_SAA7146_VV |
| 5 | ---help--- | 5 | help |
| 6 | This is a video4linux driver for the Hexium Gemini frame | 6 | This is a video4linux driver for the Hexium Gemini frame |
| 7 | grabber card by Hexium. Please note that the Gemini Dual | 7 | grabber card by Hexium. Please note that the Gemini Dual |
| 8 | card is *not* fully supported. | 8 | card is *not* fully supported. |
| @@ -14,7 +14,7 @@ config VIDEO_HEXIUM_ORION | |||
| 14 | tristate "Hexium HV-PCI6 and Orion frame grabber" | 14 | tristate "Hexium HV-PCI6 and Orion frame grabber" |
| 15 | depends on PCI && VIDEO_V4L2 && I2C | 15 | depends on PCI && VIDEO_V4L2 && I2C |
| 16 | select VIDEO_SAA7146_VV | 16 | select VIDEO_SAA7146_VV |
| 17 | ---help--- | 17 | help |
| 18 | This is a video4linux driver for the Hexium HV-PCI6 and | 18 | This is a video4linux driver for the Hexium HV-PCI6 and |
| 19 | Orion frame grabber cards by Hexium. | 19 | Orion frame grabber cards by Hexium. |
| 20 | 20 | ||
| @@ -30,7 +30,7 @@ config VIDEO_MXB | |||
| 30 | select VIDEO_TDA9840 if MEDIA_SUBDRV_AUTOSELECT | 30 | select VIDEO_TDA9840 if MEDIA_SUBDRV_AUTOSELECT |
| 31 | select VIDEO_TEA6415C if MEDIA_SUBDRV_AUTOSELECT | 31 | select VIDEO_TEA6415C if MEDIA_SUBDRV_AUTOSELECT |
| 32 | select VIDEO_TEA6420 if MEDIA_SUBDRV_AUTOSELECT | 32 | select VIDEO_TEA6420 if MEDIA_SUBDRV_AUTOSELECT |
| 33 | ---help--- | 33 | help |
| 34 | This is a video4linux driver for the 'Multimedia eXtension Board' | 34 | This is a video4linux driver for the 'Multimedia eXtension Board' |
| 35 | TV card by Siemens-Nixdorf. | 35 | TV card by Siemens-Nixdorf. |
| 36 | 36 | ||
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index 5817d9cde4d0..6d8e4afe9673 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c | |||
| @@ -270,9 +270,8 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d | |||
| 270 | /* enable i2c-port pins */ | 270 | /* enable i2c-port pins */ |
| 271 | saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); | 271 | saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); |
| 272 | 272 | ||
| 273 | hexium->i2c_adapter = (struct i2c_adapter) { | 273 | strscpy(hexium->i2c_adapter.name, "hexium gemini", |
| 274 | .name = "hexium gemini", | 274 | sizeof(hexium->i2c_adapter.name)); |
| 275 | }; | ||
| 276 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); | 275 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); |
| 277 | if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { | 276 | if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { |
| 278 | DEB_S("cannot register i2c-device. skipping.\n"); | 277 | DEB_S("cannot register i2c-device. skipping.\n"); |
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index 0a05176c18ab..a794f9e5f990 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c | |||
| @@ -231,9 +231,8 @@ static int hexium_probe(struct saa7146_dev *dev) | |||
| 231 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | 231 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); |
| 232 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | 232 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); |
| 233 | 233 | ||
| 234 | hexium->i2c_adapter = (struct i2c_adapter) { | 234 | strscpy(hexium->i2c_adapter.name, "hexium orion", |
| 235 | .name = "hexium orion", | 235 | sizeof(hexium->i2c_adapter.name)); |
| 236 | }; | ||
| 237 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); | 236 | saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); |
| 238 | if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { | 237 | if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { |
| 239 | DEB_S("cannot register i2c-device. skipping.\n"); | 238 | DEB_S("cannot register i2c-device. skipping.\n"); |
diff --git a/drivers/media/pci/saa7164/Kconfig b/drivers/media/pci/saa7164/Kconfig index 9098ef5feca4..265c5a4fd823 100644 --- a/drivers/media/pci/saa7164/Kconfig +++ b/drivers/media/pci/saa7164/Kconfig | |||
| @@ -8,7 +8,7 @@ config VIDEO_SAA7164 | |||
| 8 | select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT | 8 | select DVB_TDA10048 if MEDIA_SUBDRV_AUTOSELECT |
| 9 | select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT | 9 | select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT |
| 10 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 10 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
| 11 | ---help--- | 11 | help |
| 12 | This is a video4linux driver for NXP SAA7164 based | 12 | This is a video4linux driver for NXP SAA7164 based |
| 13 | TV cards. | 13 | TV cards. |
| 14 | 14 | ||
diff --git a/drivers/media/pci/solo6x10/Kconfig b/drivers/media/pci/solo6x10/Kconfig index d9e06a6bf1eb..2061d02a82d0 100644 --- a/drivers/media/pci/solo6x10/Kconfig +++ b/drivers/media/pci/solo6x10/Kconfig | |||
| @@ -8,7 +8,7 @@ config VIDEO_SOLO6X10 | |||
| 8 | select VIDEOBUF2_DMA_CONTIG | 8 | select VIDEOBUF2_DMA_CONTIG |
| 9 | select SND_PCM | 9 | select SND_PCM |
| 10 | select FONT_8x16 | 10 | select FONT_8x16 |
| 11 | ---help--- | 11 | help |
| 12 | This driver supports the Bluecherry H.264 and MPEG-4 hardware | 12 | This driver supports the Bluecherry H.264 and MPEG-4 hardware |
| 13 | compression capture cards and other Softlogic-based ones. | 13 | compression capture cards and other Softlogic-based ones. |
| 14 | 14 | ||
diff --git a/drivers/media/pci/tw5864/Kconfig b/drivers/media/pci/tw5864/Kconfig index 760fb11dfeae..e5d52f076232 100644 --- a/drivers/media/pci/tw5864/Kconfig +++ b/drivers/media/pci/tw5864/Kconfig | |||
| @@ -2,7 +2,7 @@ config VIDEO_TW5864 | |||
| 2 | tristate "Techwell TW5864 video/audio grabber and encoder" | 2 | tristate "Techwell TW5864 video/audio grabber and encoder" |
| 3 | depends on VIDEO_DEV && PCI && VIDEO_V4L2 | 3 | depends on VIDEO_DEV && PCI && VIDEO_V4L2 |
| 4 | select VIDEOBUF2_DMA_CONTIG | 4 | select VIDEOBUF2_DMA_CONTIG |
| 5 | ---help--- | 5 | help |
| 6 | Support for boards based on Techwell TW5864 chip which provides | 6 | Support for boards based on Techwell TW5864 chip which provides |
| 7 | multichannel video & audio grabbing and encoding (H.264, MJPEG, | 7 | multichannel video & audio grabbing and encoding (H.264, MJPEG, |
| 8 | ADPCM G.726). | 8 | ADPCM G.726). |
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c index 5a1f3aa4101a..434d313a3c15 100644 --- a/drivers/media/pci/tw5864/tw5864-video.c +++ b/drivers/media/pci/tw5864/tw5864-video.c | |||
| @@ -1395,13 +1395,13 @@ static void tw5864_handle_frame(struct tw5864_h264_frame *frame) | |||
| 1395 | input->vb = NULL; | 1395 | input->vb = NULL; |
| 1396 | spin_unlock_irqrestore(&input->slock, flags); | 1396 | spin_unlock_irqrestore(&input->slock, flags); |
| 1397 | 1397 | ||
| 1398 | v4l2_buf = to_vb2_v4l2_buffer(&vb->vb.vb2_buf); | ||
| 1399 | |||
| 1400 | if (!vb) { /* Gone because of disabling */ | 1398 | if (!vb) { /* Gone because of disabling */ |
| 1401 | dev_dbg(&dev->pci->dev, "vb is empty, dropping frame\n"); | 1399 | dev_dbg(&dev->pci->dev, "vb is empty, dropping frame\n"); |
| 1402 | return; | 1400 | return; |
| 1403 | } | 1401 | } |
| 1404 | 1402 | ||
| 1403 | v4l2_buf = to_vb2_v4l2_buffer(&vb->vb.vb2_buf); | ||
| 1404 | |||
| 1405 | /* | 1405 | /* |
| 1406 | * Check for space. | 1406 | * Check for space. |
| 1407 | * Mind the overhead of startcode emulation prevention. | 1407 | * Mind the overhead of startcode emulation prevention. |
diff --git a/drivers/media/pci/tw68/Kconfig b/drivers/media/pci/tw68/Kconfig index 95d5d5202048..4bfc4fa416e5 100644 --- a/drivers/media/pci/tw68/Kconfig +++ b/drivers/media/pci/tw68/Kconfig | |||
| @@ -2,7 +2,7 @@ config VIDEO_TW68 | |||
| 2 | tristate "Techwell tw68x Video For Linux" | 2 | tristate "Techwell tw68x Video For Linux" |
| 3 | depends on VIDEO_DEV && PCI && VIDEO_V4L2 | 3 | depends on VIDEO_DEV && PCI && VIDEO_V4L2 |
| 4 | select VIDEOBUF2_DMA_SG | 4 | select VIDEOBUF2_DMA_SG |
| 5 | ---help--- | 5 | help |
| 6 | Support for Techwell tw68xx based frame grabber boards. | 6 | Support for Techwell tw68xx based frame grabber boards. |
| 7 | 7 | ||
| 8 | To compile this driver as a module, choose M here: the | 8 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 4acbed189644..011c1c2fcf19 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
| @@ -6,7 +6,7 @@ menuconfig V4L_PLATFORM_DRIVERS | |||
| 6 | bool "V4L platform devices" | 6 | bool "V4L platform devices" |
| 7 | depends on MEDIA_CAMERA_SUPPORT | 7 | depends on MEDIA_CAMERA_SUPPORT |
| 8 | default n | 8 | default n |
| 9 | ---help--- | 9 | help |
| 10 | Say Y here to enable support for platform-specific V4L drivers. | 10 | Say Y here to enable support for platform-specific V4L drivers. |
| 11 | 11 | ||
| 12 | if V4L_PLATFORM_DRIVERS | 12 | if V4L_PLATFORM_DRIVERS |
| @@ -55,7 +55,7 @@ config VIDEO_VIU | |||
| 55 | depends on VIDEO_V4L2 && (PPC_MPC512x || COMPILE_TEST) && I2C | 55 | depends on VIDEO_V4L2 && (PPC_MPC512x || COMPILE_TEST) && I2C |
| 56 | select VIDEOBUF_DMA_CONTIG | 56 | select VIDEOBUF_DMA_CONTIG |
| 57 | default y | 57 | default y |
| 58 | ---help--- | 58 | help |
| 59 | Support for Freescale VIU video driver. This device captures | 59 | Support for Freescale VIU video driver. This device captures |
| 60 | video data, or overlays video on DIU frame buffer. | 60 | video data, or overlays video on DIU frame buffer. |
| 61 | 61 | ||
| @@ -80,13 +80,13 @@ config VIDEO_OMAP3 | |||
| 80 | select VIDEOBUF2_DMA_CONTIG | 80 | select VIDEOBUF2_DMA_CONTIG |
| 81 | select MFD_SYSCON | 81 | select MFD_SYSCON |
| 82 | select V4L2_FWNODE | 82 | select V4L2_FWNODE |
| 83 | ---help--- | 83 | help |
| 84 | Driver for an OMAP 3 camera controller. | 84 | Driver for an OMAP 3 camera controller. |
| 85 | 85 | ||
| 86 | config VIDEO_OMAP3_DEBUG | 86 | config VIDEO_OMAP3_DEBUG |
| 87 | bool "OMAP 3 Camera debug messages" | 87 | bool "OMAP 3 Camera debug messages" |
| 88 | depends on VIDEO_OMAP3 | 88 | depends on VIDEO_OMAP3 |
| 89 | ---help--- | 89 | help |
| 90 | Enable debug messages on OMAP 3 camera controller driver. | 90 | Enable debug messages on OMAP 3 camera controller driver. |
| 91 | 91 | ||
| 92 | config VIDEO_PXA27x | 92 | config VIDEO_PXA27x |
| @@ -96,7 +96,7 @@ config VIDEO_PXA27x | |||
| 96 | select VIDEOBUF2_DMA_SG | 96 | select VIDEOBUF2_DMA_SG |
| 97 | select SG_SPLIT | 97 | select SG_SPLIT |
| 98 | select V4L2_FWNODE | 98 | select V4L2_FWNODE |
| 99 | ---help--- | 99 | help |
| 100 | This is a v4l2 driver for the PXA27x Quick Capture Interface | 100 | This is a v4l2 driver for the PXA27x Quick Capture Interface |
| 101 | 101 | ||
| 102 | config VIDEO_QCOM_CAMSS | 102 | config VIDEO_QCOM_CAMSS |
| @@ -112,7 +112,7 @@ config VIDEO_S3C_CAMIF | |||
| 112 | depends on PM | 112 | depends on PM |
| 113 | depends on ARCH_S3C64XX || PLAT_S3C24XX || COMPILE_TEST | 113 | depends on ARCH_S3C64XX || PLAT_S3C24XX || COMPILE_TEST |
| 114 | select VIDEOBUF2_DMA_CONTIG | 114 | select VIDEOBUF2_DMA_CONTIG |
| 115 | ---help--- | 115 | help |
| 116 | This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera | 116 | This is a v4l2 driver for s3c24xx and s3c64xx SoC series camera |
| 117 | host interface (CAMIF). | 117 | host interface (CAMIF). |
| 118 | 118 | ||
| @@ -125,7 +125,7 @@ config VIDEO_STM32_DCMI | |||
| 125 | depends on ARCH_STM32 || COMPILE_TEST | 125 | depends on ARCH_STM32 || COMPILE_TEST |
| 126 | select VIDEOBUF2_DMA_CONTIG | 126 | select VIDEOBUF2_DMA_CONTIG |
| 127 | select V4L2_FWNODE | 127 | select V4L2_FWNODE |
| 128 | ---help--- | 128 | help |
| 129 | This module makes the STM32 Digital Camera Memory Interface (DCMI) | 129 | This module makes the STM32 Digital Camera Memory Interface (DCMI) |
| 130 | available as a v4l2 device. | 130 | available as a v4l2 device. |
| 131 | 131 | ||
| @@ -138,7 +138,7 @@ config VIDEO_RENESAS_CEU | |||
| 138 | depends on ARCH_SHMOBILE || ARCH_R7S72100 || COMPILE_TEST | 138 | depends on ARCH_SHMOBILE || ARCH_R7S72100 || COMPILE_TEST |
| 139 | select VIDEOBUF2_DMA_CONTIG | 139 | select VIDEOBUF2_DMA_CONTIG |
| 140 | select V4L2_FWNODE | 140 | select V4L2_FWNODE |
| 141 | ---help--- | 141 | help |
| 142 | This is a v4l2 driver for the Renesas CEU Interface | 142 | This is a v4l2 driver for the Renesas CEU Interface |
| 143 | 143 | ||
| 144 | source "drivers/media/platform/exynos4-is/Kconfig" | 144 | source "drivers/media/platform/exynos4-is/Kconfig" |
| @@ -155,7 +155,7 @@ config VIDEO_TI_CAL | |||
| 155 | select VIDEOBUF2_DMA_CONTIG | 155 | select VIDEOBUF2_DMA_CONTIG |
| 156 | select V4L2_FWNODE | 156 | select V4L2_FWNODE |
| 157 | default n | 157 | default n |
| 158 | ---help--- | 158 | help |
| 159 | Support for the TI CAL (Camera Adaptation Layer) block | 159 | Support for the TI CAL (Camera Adaptation Layer) block |
| 160 | found on DRA72X SoC. | 160 | found on DRA72X SoC. |
| 161 | In TI Technical Reference Manual this module is referred as | 161 | In TI Technical Reference Manual this module is referred as |
| @@ -168,7 +168,7 @@ menuconfig V4L_MEM2MEM_DRIVERS | |||
| 168 | depends on VIDEO_V4L2 | 168 | depends on VIDEO_V4L2 |
| 169 | depends on MEDIA_CAMERA_SUPPORT | 169 | depends on MEDIA_CAMERA_SUPPORT |
| 170 | default n | 170 | default n |
| 171 | ---help--- | 171 | help |
| 172 | Say Y here to enable selecting drivers for V4L devices that | 172 | Say Y here to enable selecting drivers for V4L devices that |
| 173 | use system memory for both source and destination buffers, as opposed | 173 | use system memory for both source and destination buffers, as opposed |
| 174 | to capture and output drivers, which use memory buffers for just | 174 | to capture and output drivers, which use memory buffers for just |
| @@ -184,7 +184,7 @@ config VIDEO_CODA | |||
| 184 | select VIDEOBUF2_VMALLOC | 184 | select VIDEOBUF2_VMALLOC |
| 185 | select V4L2_MEM2MEM_DEV | 185 | select V4L2_MEM2MEM_DEV |
| 186 | select GENERIC_ALLOCATOR | 186 | select GENERIC_ALLOCATOR |
| 187 | ---help--- | 187 | help |
| 188 | Coda is a range of video codec IPs that supports | 188 | Coda is a range of video codec IPs that supports |
| 189 | H.264, MPEG-4, and other video formats. | 189 | H.264, MPEG-4, and other video formats. |
| 190 | 190 | ||
| @@ -207,7 +207,7 @@ config VIDEO_MEDIATEK_JPEG | |||
| 207 | depends on ARCH_MEDIATEK || COMPILE_TEST | 207 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 208 | select VIDEOBUF2_DMA_CONTIG | 208 | select VIDEOBUF2_DMA_CONTIG |
| 209 | select V4L2_MEM2MEM_DEV | 209 | select V4L2_MEM2MEM_DEV |
| 210 | ---help--- | 210 | help |
| 211 | Mediatek jpeg codec driver provides HW capability to decode | 211 | Mediatek jpeg codec driver provides HW capability to decode |
| 212 | JPEG format | 212 | JPEG format |
| 213 | 213 | ||
| @@ -218,7 +218,7 @@ config VIDEO_MEDIATEK_VPU | |||
| 218 | tristate "Mediatek Video Processor Unit" | 218 | tristate "Mediatek Video Processor Unit" |
| 219 | depends on VIDEO_DEV && VIDEO_V4L2 | 219 | depends on VIDEO_DEV && VIDEO_V4L2 |
| 220 | depends on ARCH_MEDIATEK || COMPILE_TEST | 220 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 221 | ---help--- | 221 | help |
| 222 | This driver provides downloading VPU firmware and | 222 | This driver provides downloading VPU firmware and |
| 223 | communicating with VPU. This driver for hw video | 223 | communicating with VPU. This driver for hw video |
| 224 | codec embedded in Mediatek's MT8173 SOCs. It is able | 224 | codec embedded in Mediatek's MT8173 SOCs. It is able |
| @@ -236,7 +236,7 @@ config VIDEO_MEDIATEK_MDP | |||
| 236 | select V4L2_MEM2MEM_DEV | 236 | select V4L2_MEM2MEM_DEV |
| 237 | select VIDEO_MEDIATEK_VPU | 237 | select VIDEO_MEDIATEK_VPU |
| 238 | default n | 238 | default n |
| 239 | ---help--- | 239 | help |
| 240 | It is a v4l2 driver and present in Mediatek MT8173 SoCs. | 240 | It is a v4l2 driver and present in Mediatek MT8173 SoCs. |
| 241 | The driver supports for scaling and color space conversion. | 241 | The driver supports for scaling and color space conversion. |
| 242 | 242 | ||
| @@ -252,7 +252,7 @@ config VIDEO_MEDIATEK_VCODEC | |||
| 252 | select V4L2_MEM2MEM_DEV | 252 | select V4L2_MEM2MEM_DEV |
| 253 | select VIDEO_MEDIATEK_VPU | 253 | select VIDEO_MEDIATEK_VPU |
| 254 | default n | 254 | default n |
| 255 | ---help--- | 255 | help |
| 256 | Mediatek video codec driver provides HW capability to | 256 | Mediatek video codec driver provides HW capability to |
| 257 | encode and decode in a range of video formats | 257 | encode and decode in a range of video formats |
| 258 | This driver rely on VPU driver to communicate with VPU. | 258 | This driver rely on VPU driver to communicate with VPU. |
| @@ -276,7 +276,7 @@ config VIDEO_SAMSUNG_S5P_G2D | |||
| 276 | select VIDEOBUF2_DMA_CONTIG | 276 | select VIDEOBUF2_DMA_CONTIG |
| 277 | select V4L2_MEM2MEM_DEV | 277 | select V4L2_MEM2MEM_DEV |
| 278 | default n | 278 | default n |
| 279 | ---help--- | 279 | help |
| 280 | This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D | 280 | This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D |
| 281 | 2d graphics accelerator. | 281 | 2d graphics accelerator. |
| 282 | 282 | ||
| @@ -286,7 +286,7 @@ config VIDEO_SAMSUNG_S5P_JPEG | |||
| 286 | depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST | 286 | depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST |
| 287 | select VIDEOBUF2_DMA_CONTIG | 287 | select VIDEOBUF2_DMA_CONTIG |
| 288 | select V4L2_MEM2MEM_DEV | 288 | select V4L2_MEM2MEM_DEV |
| 289 | ---help--- | 289 | help |
| 290 | This is a v4l2 driver for Samsung S5P, EXYNOS3250 | 290 | This is a v4l2 driver for Samsung S5P, EXYNOS3250 |
| 291 | and EXYNOS4 JPEG codec | 291 | and EXYNOS4 JPEG codec |
| 292 | 292 | ||
| @@ -407,7 +407,7 @@ config VIDEO_RENESAS_FDP1 | |||
| 407 | depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP | 407 | depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP |
| 408 | select VIDEOBUF2_DMA_CONTIG | 408 | select VIDEOBUF2_DMA_CONTIG |
| 409 | select V4L2_MEM2MEM_DEV | 409 | select V4L2_MEM2MEM_DEV |
| 410 | ---help--- | 410 | help |
| 411 | This is a V4L2 driver for the Renesas Fine Display Processor | 411 | This is a V4L2 driver for the Renesas Fine Display Processor |
| 412 | providing colour space conversion, and de-interlacing features. | 412 | providing colour space conversion, and de-interlacing features. |
| 413 | 413 | ||
| @@ -420,7 +420,7 @@ config VIDEO_RENESAS_JPU | |||
| 420 | depends on ARCH_RENESAS || COMPILE_TEST | 420 | depends on ARCH_RENESAS || COMPILE_TEST |
| 421 | select VIDEOBUF2_DMA_CONTIG | 421 | select VIDEOBUF2_DMA_CONTIG |
| 422 | select V4L2_MEM2MEM_DEV | 422 | select V4L2_MEM2MEM_DEV |
| 423 | ---help--- | 423 | help |
| 424 | This is a V4L2 driver for the Renesas JPEG Processing Unit. | 424 | This is a V4L2 driver for the Renesas JPEG Processing Unit. |
| 425 | 425 | ||
| 426 | To compile this driver as a module, choose M here: the module | 426 | To compile this driver as a module, choose M here: the module |
| @@ -430,7 +430,7 @@ config VIDEO_RENESAS_FCP | |||
| 430 | tristate "Renesas Frame Compression Processor" | 430 | tristate "Renesas Frame Compression Processor" |
| 431 | depends on ARCH_RENESAS || COMPILE_TEST | 431 | depends on ARCH_RENESAS || COMPILE_TEST |
| 432 | depends on OF | 432 | depends on OF |
| 433 | ---help--- | 433 | help |
| 434 | This is a driver for the Renesas Frame Compression Processor (FCP). | 434 | This is a driver for the Renesas Frame Compression Processor (FCP). |
| 435 | The FCP is a companion module of video processing modules in the | 435 | The FCP is a companion module of video processing modules in the |
| 436 | Renesas R-Car Gen3 SoCs. It handles memory access for the codec, | 436 | Renesas R-Car Gen3 SoCs. It handles memory access for the codec, |
| @@ -446,7 +446,7 @@ config VIDEO_RENESAS_VSP1 | |||
| 446 | depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP | 446 | depends on (!ARM64 && !VIDEO_RENESAS_FCP) || VIDEO_RENESAS_FCP |
| 447 | select VIDEOBUF2_DMA_CONTIG | 447 | select VIDEOBUF2_DMA_CONTIG |
| 448 | select VIDEOBUF2_VMALLOC | 448 | select VIDEOBUF2_VMALLOC |
| 449 | ---help--- | 449 | help |
| 450 | This is a V4L2 driver for the Renesas VSP1 video processing engine. | 450 | This is a V4L2 driver for the Renesas VSP1 video processing engine. |
| 451 | 451 | ||
| 452 | To compile this driver as a module, choose M here: the module | 452 | To compile this driver as a module, choose M here: the module |
| @@ -459,7 +459,7 @@ config VIDEO_ROCKCHIP_RGA | |||
| 459 | select VIDEOBUF2_DMA_SG | 459 | select VIDEOBUF2_DMA_SG |
| 460 | select V4L2_MEM2MEM_DEV | 460 | select V4L2_MEM2MEM_DEV |
| 461 | default n | 461 | default n |
| 462 | ---help--- | 462 | help |
| 463 | This is a v4l2 driver for Rockchip SOC RGA 2d graphics accelerator. | 463 | This is a v4l2 driver for Rockchip SOC RGA 2d graphics accelerator. |
| 464 | Rockchip RGA is a separate 2D raster graphic acceleration unit. | 464 | Rockchip RGA is a separate 2D raster graphic acceleration unit. |
| 465 | It accelerates 2D graphics operations, such as point/line drawing, | 465 | It accelerates 2D graphics operations, such as point/line drawing, |
| @@ -477,14 +477,14 @@ config VIDEO_TI_VPE | |||
| 477 | select VIDEO_TI_SC | 477 | select VIDEO_TI_SC |
| 478 | select VIDEO_TI_CSC | 478 | select VIDEO_TI_CSC |
| 479 | default n | 479 | default n |
| 480 | ---help--- | 480 | help |
| 481 | Support for the TI VPE(Video Processing Engine) block | 481 | Support for the TI VPE(Video Processing Engine) block |
| 482 | found on DRA7XX SoC. | 482 | found on DRA7XX SoC. |
| 483 | 483 | ||
| 484 | config VIDEO_TI_VPE_DEBUG | 484 | config VIDEO_TI_VPE_DEBUG |
| 485 | bool "VPE debug messages" | 485 | bool "VPE debug messages" |
| 486 | depends on VIDEO_TI_VPE | 486 | depends on VIDEO_TI_VPE |
| 487 | ---help--- | 487 | help |
| 488 | Enable debug messages on VPE driver. | 488 | Enable debug messages on VPE driver. |
| 489 | 489 | ||
| 490 | config VIDEO_QCOM_VENUS | 490 | config VIDEO_QCOM_VENUS |
| @@ -495,7 +495,7 @@ config VIDEO_QCOM_VENUS | |||
| 495 | select QCOM_SCM if ARCH_QCOM | 495 | select QCOM_SCM if ARCH_QCOM |
| 496 | select VIDEOBUF2_DMA_SG | 496 | select VIDEOBUF2_DMA_SG |
| 497 | select V4L2_MEM2MEM_DEV | 497 | select V4L2_MEM2MEM_DEV |
| 498 | ---help--- | 498 | help |
| 499 | This is a V4L2 driver for Qualcomm Venus video accelerator | 499 | This is a V4L2 driver for Qualcomm Venus video accelerator |
| 500 | hardware. It accelerates encoding and decoding operations | 500 | hardware. It accelerates encoding and decoding operations |
| 501 | on various Qualcomm SoCs. | 501 | on various Qualcomm SoCs. |
| @@ -530,7 +530,7 @@ config VIDEO_VIM2M | |||
| 530 | select VIDEOBUF2_VMALLOC | 530 | select VIDEOBUF2_VMALLOC |
| 531 | select V4L2_MEM2MEM_DEV | 531 | select V4L2_MEM2MEM_DEV |
| 532 | default n | 532 | default n |
| 533 | ---help--- | 533 | help |
| 534 | This is a virtual test device for the memory-to-memory driver | 534 | This is a virtual test device for the memory-to-memory driver |
| 535 | framework. | 535 | framework. |
| 536 | 536 | ||
| @@ -542,7 +542,7 @@ menuconfig DVB_PLATFORM_DRIVERS | |||
| 542 | bool "DVB platform devices" | 542 | bool "DVB platform devices" |
| 543 | depends on MEDIA_DIGITAL_TV_SUPPORT | 543 | depends on MEDIA_DIGITAL_TV_SUPPORT |
| 544 | default n | 544 | default n |
| 545 | ---help--- | 545 | help |
| 546 | Say Y here to enable support for platform-specific Digital TV drivers. | 546 | Say Y here to enable support for platform-specific Digital TV drivers. |
| 547 | 547 | ||
| 548 | if DVB_PLATFORM_DRIVERS | 548 | if DVB_PLATFORM_DRIVERS |
| @@ -562,7 +562,7 @@ config VIDEO_CROS_EC_CEC | |||
| 562 | select CEC_NOTIFIER | 562 | select CEC_NOTIFIER |
| 563 | select CHROME_PLATFORMS | 563 | select CHROME_PLATFORMS |
| 564 | select CROS_EC_PROTO | 564 | select CROS_EC_PROTO |
| 565 | ---help--- | 565 | help |
| 566 | If you say yes here you will get support for the | 566 | If you say yes here you will get support for the |
| 567 | ChromeOS Embedded Controller's CEC. | 567 | ChromeOS Embedded Controller's CEC. |
| 568 | The CEC bus is present in the HDMI connector and enables communication | 568 | The CEC bus is present in the HDMI connector and enables communication |
| @@ -573,18 +573,34 @@ config VIDEO_MESON_AO_CEC | |||
| 573 | depends on ARCH_MESON || COMPILE_TEST | 573 | depends on ARCH_MESON || COMPILE_TEST |
| 574 | select CEC_CORE | 574 | select CEC_CORE |
| 575 | select CEC_NOTIFIER | 575 | select CEC_NOTIFIER |
| 576 | ---help--- | 576 | help |
| 577 | This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the | 577 | This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the |
| 578 | generic CEC framework interface. | 578 | generic CEC framework interface. |
| 579 | CEC bus is present in the HDMI connector and enables communication | 579 | CEC bus is present in the HDMI connector and enables communication |
| 580 | 580 | ||
| 581 | config VIDEO_MESON_G12A_AO_CEC | ||
| 582 | tristate "Amlogic Meson G12A AO CEC driver" | ||
| 583 | depends on ARCH_MESON || COMPILE_TEST | ||
| 584 | depends on COMMON_CLK && OF | ||
| 585 | select REGMAP | ||
| 586 | select REGMAP_MMIO | ||
| 587 | select CEC_CORE | ||
| 588 | select CEC_NOTIFIER | ||
| 589 | ---help--- | ||
| 590 | This is a driver for Amlogic Meson G12A SoCs AO CEC interface. | ||
| 591 | This driver if for the new AO-CEC module found in G12A SoCs, | ||
| 592 | usually named AO_CEC_B in documentation. | ||
| 593 | It uses the generic CEC framework interface. | ||
| 594 | CEC bus is present in the HDMI connector and enables communication | ||
| 595 | between compatible devices. | ||
| 596 | |||
| 581 | config CEC_GPIO | 597 | config CEC_GPIO |
| 582 | tristate "Generic GPIO-based CEC driver" | 598 | tristate "Generic GPIO-based CEC driver" |
| 583 | depends on PREEMPT || COMPILE_TEST | 599 | depends on PREEMPT || COMPILE_TEST |
| 584 | select CEC_CORE | 600 | select CEC_CORE |
| 585 | select CEC_PIN | 601 | select CEC_PIN |
| 586 | select GPIOLIB | 602 | select GPIOLIB |
| 587 | ---help--- | 603 | help |
| 588 | This is a generic GPIO-based CEC driver. | 604 | This is a generic GPIO-based CEC driver. |
| 589 | The CEC bus is present in the HDMI connector and enables communication | 605 | The CEC bus is present in the HDMI connector and enables communication |
| 590 | between compatible devices. | 606 | between compatible devices. |
| @@ -594,7 +610,7 @@ config VIDEO_SAMSUNG_S5P_CEC | |||
| 594 | depends on ARCH_EXYNOS || COMPILE_TEST | 610 | depends on ARCH_EXYNOS || COMPILE_TEST |
| 595 | select CEC_CORE | 611 | select CEC_CORE |
| 596 | select CEC_NOTIFIER | 612 | select CEC_NOTIFIER |
| 597 | ---help--- | 613 | help |
| 598 | This is a driver for Samsung S5P HDMI CEC interface. It uses the | 614 | This is a driver for Samsung S5P HDMI CEC interface. It uses the |
| 599 | generic CEC framework interface. | 615 | generic CEC framework interface. |
| 600 | CEC bus is present in the HDMI connector and enables communication | 616 | CEC bus is present in the HDMI connector and enables communication |
| @@ -605,7 +621,7 @@ config VIDEO_STI_HDMI_CEC | |||
| 605 | depends on ARCH_STI || COMPILE_TEST | 621 | depends on ARCH_STI || COMPILE_TEST |
| 606 | select CEC_CORE | 622 | select CEC_CORE |
| 607 | select CEC_NOTIFIER | 623 | select CEC_NOTIFIER |
| 608 | ---help--- | 624 | help |
| 609 | This is a driver for STIH4xx HDMI CEC interface. It uses the | 625 | This is a driver for STIH4xx HDMI CEC interface. It uses the |
| 610 | generic CEC framework interface. | 626 | generic CEC framework interface. |
| 611 | CEC bus is present in the HDMI connector and enables communication | 627 | CEC bus is present in the HDMI connector and enables communication |
| @@ -617,7 +633,7 @@ config VIDEO_STM32_HDMI_CEC | |||
| 617 | select REGMAP | 633 | select REGMAP |
| 618 | select REGMAP_MMIO | 634 | select REGMAP_MMIO |
| 619 | select CEC_CORE | 635 | select CEC_CORE |
| 620 | ---help--- | 636 | help |
| 621 | This is a driver for STM32 interface. It uses the | 637 | This is a driver for STM32 interface. It uses the |
| 622 | generic CEC framework interface. | 638 | generic CEC framework interface. |
| 623 | CEC bus is present in the HDMI connector and enables communication | 639 | CEC bus is present in the HDMI connector and enables communication |
| @@ -628,7 +644,7 @@ config VIDEO_TEGRA_HDMI_CEC | |||
| 628 | depends on ARCH_TEGRA || COMPILE_TEST | 644 | depends on ARCH_TEGRA || COMPILE_TEST |
| 629 | select CEC_CORE | 645 | select CEC_CORE |
| 630 | select CEC_NOTIFIER | 646 | select CEC_NOTIFIER |
| 631 | ---help--- | 647 | help |
| 632 | This is a driver for the Tegra HDMI CEC interface. It uses the | 648 | This is a driver for the Tegra HDMI CEC interface. It uses the |
| 633 | generic CEC framework interface. | 649 | generic CEC framework interface. |
| 634 | The CEC bus is present in the HDMI connector and enables communication | 650 | The CEC bus is present in the HDMI connector and enables communication |
| @@ -649,7 +665,7 @@ config VIDEO_SECO_CEC | |||
| 649 | config VIDEO_SECO_RC | 665 | config VIDEO_SECO_RC |
| 650 | bool "SECO Boards IR RC5 support" | 666 | bool "SECO Boards IR RC5 support" |
| 651 | depends on VIDEO_SECO_CEC | 667 | depends on VIDEO_SECO_CEC |
| 652 | depends on RC_CORE | 668 | depends on RC_CORE=y || RC_CORE = VIDEO_SECO_CEC |
| 653 | help | 669 | help |
| 654 | If you say yes here you will get support for the | 670 | If you say yes here you will get support for the |
| 655 | SECO Boards Consumer-IR in seco-cec driver. | 671 | SECO Boards Consumer-IR in seco-cec driver. |
| @@ -662,7 +678,7 @@ menuconfig SDR_PLATFORM_DRIVERS | |||
| 662 | bool "SDR platform devices" | 678 | bool "SDR platform devices" |
| 663 | depends on MEDIA_SDR_SUPPORT | 679 | depends on MEDIA_SDR_SUPPORT |
| 664 | default n | 680 | default n |
| 665 | ---help--- | 681 | help |
| 666 | Say Y here to enable support for platform-specific SDR Drivers. | 682 | Say Y here to enable support for platform-specific SDR Drivers. |
| 667 | 683 | ||
| 668 | if SDR_PLATFORM_DRIVERS | 684 | if SDR_PLATFORM_DRIVERS |
| @@ -672,7 +688,7 @@ config VIDEO_RCAR_DRIF | |||
| 672 | depends on VIDEO_V4L2 | 688 | depends on VIDEO_V4L2 |
| 673 | depends on ARCH_RENESAS || COMPILE_TEST | 689 | depends on ARCH_RENESAS || COMPILE_TEST |
| 674 | select VIDEOBUF2_VMALLOC | 690 | select VIDEOBUF2_VMALLOC |
| 675 | ---help--- | 691 | help |
| 676 | Say Y if you want to enable R-Car Gen3 DRIF support. DRIF is Digital | 692 | Say Y if you want to enable R-Car Gen3 DRIF support. DRIF is Digital |
| 677 | Radio Interface that interfaces with an RF front end chip. It is a | 693 | Radio Interface that interfaces with an RF front end chip. It is a |
| 678 | receiver of digital data which uses DMA to transfer received data to | 694 | receiver of digital data which uses DMA to transfer received data to |
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 5c17624aaade..fe7b937eb5f2 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c | |||
| @@ -1540,7 +1540,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv, | |||
| 1540 | if (!fmt) | 1540 | if (!fmt) |
| 1541 | return -EINVAL; | 1541 | return -EINVAL; |
| 1542 | 1542 | ||
| 1543 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 1543 | strscpy(f->description, fmt->name, sizeof(f->description)); |
| 1544 | f->pixelformat = fmt->fourcc; | 1544 | f->pixelformat = fmt->fourcc; |
| 1545 | f->type = vpfe->fmt.type; | 1545 | f->type = vpfe->fmt.type; |
| 1546 | 1546 | ||
diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c index 692e08ef38c0..8144fe36ad48 100644 --- a/drivers/media/platform/aspeed-video.c +++ b/drivers/media/platform/aspeed-video.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/of_irq.h> | 14 | #include <linux/of_irq.h> |
| 15 | #include <linux/of_reserved_mem.h> | 15 | #include <linux/of_reserved_mem.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/reset.h> | ||
| 18 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
| 19 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 20 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| @@ -208,7 +207,6 @@ struct aspeed_video { | |||
| 208 | void __iomem *base; | 207 | void __iomem *base; |
| 209 | struct clk *eclk; | 208 | struct clk *eclk; |
| 210 | struct clk *vclk; | 209 | struct clk *vclk; |
| 211 | struct reset_control *rst; | ||
| 212 | 210 | ||
| 213 | struct device *dev; | 211 | struct device *dev; |
| 214 | struct v4l2_ctrl_handler ctrl_handler; | 212 | struct v4l2_ctrl_handler ctrl_handler; |
| @@ -483,19 +481,10 @@ static void aspeed_video_enable_mode_detect(struct aspeed_video *video) | |||
| 483 | aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET); | 481 | aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET); |
| 484 | } | 482 | } |
| 485 | 483 | ||
| 486 | static void aspeed_video_reset(struct aspeed_video *video) | ||
| 487 | { | ||
| 488 | /* Reset the engine */ | ||
| 489 | reset_control_assert(video->rst); | ||
| 490 | |||
| 491 | /* Don't usleep here; function may be called in interrupt context */ | ||
| 492 | udelay(100); | ||
| 493 | reset_control_deassert(video->rst); | ||
| 494 | } | ||
| 495 | |||
| 496 | static void aspeed_video_off(struct aspeed_video *video) | 484 | static void aspeed_video_off(struct aspeed_video *video) |
| 497 | { | 485 | { |
| 498 | aspeed_video_reset(video); | 486 | /* Disable interrupts */ |
| 487 | aspeed_video_write(video, VE_INTERRUPT_CTRL, 0); | ||
| 499 | 488 | ||
| 500 | /* Turn off the relevant clocks */ | 489 | /* Turn off the relevant clocks */ |
| 501 | clk_disable_unprepare(video->vclk); | 490 | clk_disable_unprepare(video->vclk); |
| @@ -507,8 +496,6 @@ static void aspeed_video_on(struct aspeed_video *video) | |||
| 507 | /* Turn on the relevant clocks */ | 496 | /* Turn on the relevant clocks */ |
| 508 | clk_prepare_enable(video->eclk); | 497 | clk_prepare_enable(video->eclk); |
| 509 | clk_prepare_enable(video->vclk); | 498 | clk_prepare_enable(video->vclk); |
| 510 | |||
| 511 | aspeed_video_reset(video); | ||
| 512 | } | 499 | } |
| 513 | 500 | ||
| 514 | static void aspeed_video_bufs_done(struct aspeed_video *video, | 501 | static void aspeed_video_bufs_done(struct aspeed_video *video, |
| @@ -1464,7 +1451,9 @@ static void aspeed_video_stop_streaming(struct vb2_queue *q) | |||
| 1464 | * Need to force stop any DMA and try and get HW into a good | 1451 | * Need to force stop any DMA and try and get HW into a good |
| 1465 | * state for future calls to start streaming again. | 1452 | * state for future calls to start streaming again. |
| 1466 | */ | 1453 | */ |
| 1467 | aspeed_video_reset(video); | 1454 | aspeed_video_off(video); |
| 1455 | aspeed_video_on(video); | ||
| 1456 | |||
| 1468 | aspeed_video_init_regs(video); | 1457 | aspeed_video_init_regs(video); |
| 1469 | 1458 | ||
| 1470 | aspeed_video_get_resolution(video); | 1459 | aspeed_video_get_resolution(video); |
| @@ -1619,17 +1608,7 @@ static int aspeed_video_init(struct aspeed_video *video) | |||
| 1619 | return PTR_ERR(video->vclk); | 1608 | return PTR_ERR(video->vclk); |
| 1620 | } | 1609 | } |
| 1621 | 1610 | ||
| 1622 | video->rst = devm_reset_control_get_exclusive(dev, NULL); | 1611 | of_reserved_mem_device_init(dev); |
| 1623 | if (IS_ERR(video->rst)) { | ||
| 1624 | dev_err(dev, "Unable to get VE reset\n"); | ||
| 1625 | return PTR_ERR(video->rst); | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | rc = of_reserved_mem_device_init(dev); | ||
| 1629 | if (rc) { | ||
| 1630 | dev_err(dev, "Unable to reserve memory\n"); | ||
| 1631 | return rc; | ||
| 1632 | } | ||
| 1633 | 1612 | ||
| 1634 | rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); | 1613 | rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
| 1635 | if (rc) { | 1614 | if (rc) { |
diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig index a211ef20f77e..c3f6a47cdc0e 100644 --- a/drivers/media/platform/atmel/Kconfig +++ b/drivers/media/platform/atmel/Kconfig | |||
| @@ -15,6 +15,6 @@ config VIDEO_ATMEL_ISI | |||
| 15 | depends on ARCH_AT91 || COMPILE_TEST | 15 | depends on ARCH_AT91 || COMPILE_TEST |
| 16 | select VIDEOBUF2_DMA_CONTIG | 16 | select VIDEOBUF2_DMA_CONTIG |
| 17 | select V4L2_FWNODE | 17 | select V4L2_FWNODE |
| 18 | ---help--- | 18 | help |
| 19 | This module makes the ATMEL Image Sensor Interface available | 19 | This module makes the ATMEL Image Sensor Interface available |
| 20 | as a v4l2 device. | 20 | as a v4l2 device. |
diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index 2aadc19235ea..d730693f299c 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #define ISC_PFE_CFG0_HPOL_LOW BIT(0) | 24 | #define ISC_PFE_CFG0_HPOL_LOW BIT(0) |
| 25 | #define ISC_PFE_CFG0_VPOL_LOW BIT(1) | 25 | #define ISC_PFE_CFG0_VPOL_LOW BIT(1) |
| 26 | #define ISC_PFE_CFG0_PPOL_LOW BIT(2) | 26 | #define ISC_PFE_CFG0_PPOL_LOW BIT(2) |
| 27 | #define ISC_PFE_CFG0_CCIR656 BIT(9) | ||
| 28 | #define ISC_PFE_CFG0_CCIR_CRC BIT(10) | ||
| 27 | 29 | ||
| 28 | #define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4) | 30 | #define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4) |
| 29 | #define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4) | 31 | #define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4) |
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index 50178968b8a6..4bba9da206e4 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c | |||
| @@ -89,35 +89,25 @@ struct isc_subdev_entity { | |||
| 89 | struct list_head list; | 89 | struct list_head list; |
| 90 | }; | 90 | }; |
| 91 | 91 | ||
| 92 | /* Indicate the format is generated by the sensor */ | ||
| 93 | #define FMT_FLAG_FROM_SENSOR BIT(0) | ||
| 94 | /* Indicate the format is produced by ISC itself */ | ||
| 95 | #define FMT_FLAG_FROM_CONTROLLER BIT(1) | ||
| 96 | /* Indicate a Raw Bayer format */ | ||
| 97 | #define FMT_FLAG_RAW_FORMAT BIT(2) | ||
| 98 | |||
| 99 | #define FMT_FLAG_RAW_FROM_SENSOR (FMT_FLAG_FROM_SENSOR | \ | ||
| 100 | FMT_FLAG_RAW_FORMAT) | ||
| 101 | |||
| 102 | /* | 92 | /* |
| 103 | * struct isc_format - ISC media bus format information | 93 | * struct isc_format - ISC media bus format information |
| 94 | This structure represents the interface between the ISC | ||
| 95 | and the sensor. It's the input format received by | ||
| 96 | the ISC. | ||
| 104 | * @fourcc: Fourcc code for this format | 97 | * @fourcc: Fourcc code for this format |
| 105 | * @mbus_code: V4L2 media bus format code. | 98 | * @mbus_code: V4L2 media bus format code. |
| 106 | * flags: Indicate format from sensor or converted by controller | 99 | * @cfa_baycfg: If this format is RAW BAYER, indicate the type of bayer. |
| 107 | * @bpp: Bits per pixel (when stored in memory) | 100 | this is either BGBG, RGRG, etc. |
| 108 | * (when transferred over a bus) | 101 | * @pfe_cfg0_bps: Number of hardware data lines connected to the ISC |
| 109 | * @sd_support: Subdev supports this format | ||
| 110 | * @isc_support: ISC can convert raw format to this format | ||
| 111 | */ | 102 | */ |
| 112 | 103 | ||
| 113 | struct isc_format { | 104 | struct isc_format { |
| 114 | u32 fourcc; | 105 | u32 fourcc; |
| 115 | u32 mbus_code; | 106 | u32 mbus_code; |
| 116 | u32 flags; | 107 | u32 cfa_baycfg; |
| 117 | u8 bpp; | ||
| 118 | 108 | ||
| 119 | bool sd_support; | 109 | bool sd_support; |
| 120 | bool isc_support; | 110 | u32 pfe_cfg0_bps; |
| 121 | }; | 111 | }; |
| 122 | 112 | ||
| 123 | /* Pipeline bitmap */ | 113 | /* Pipeline bitmap */ |
| @@ -135,16 +125,31 @@ struct isc_format { | |||
| 135 | 125 | ||
| 136 | #define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE) | 126 | #define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE) |
| 137 | 127 | ||
| 128 | /* | ||
| 129 | * struct fmt_config - ISC format configuration and internal pipeline | ||
| 130 | This structure represents the internal configuration | ||
| 131 | of the ISC. | ||
| 132 | It also holds the format that ISC will present to v4l2. | ||
| 133 | * @sd_format: Pointer to an isc_format struct that holds the sensor | ||
| 134 | configuration. | ||
| 135 | * @fourcc: Fourcc code for this format. | ||
| 136 | * @bpp: Bytes per pixel in the current format. | ||
| 137 | * @rlp_cfg_mode: Configuration of the RLP (rounding, limiting packaging) | ||
| 138 | * @dcfg_imode: Configuration of the input of the DMA module | ||
| 139 | * @dctrl_dview: Configuration of the output of the DMA module | ||
| 140 | * @bits_pipeline: Configuration of the pipeline, which modules are enabled | ||
| 141 | */ | ||
| 138 | struct fmt_config { | 142 | struct fmt_config { |
| 139 | u32 fourcc; | 143 | struct isc_format *sd_format; |
| 140 | 144 | ||
| 141 | u32 pfe_cfg0_bps; | 145 | u32 fourcc; |
| 142 | u32 cfa_baycfg; | 146 | u8 bpp; |
| 143 | u32 rlp_cfg_mode; | ||
| 144 | u32 dcfg_imode; | ||
| 145 | u32 dctrl_dview; | ||
| 146 | 147 | ||
| 147 | u32 bits_pipeline; | 148 | u32 rlp_cfg_mode; |
| 149 | u32 dcfg_imode; | ||
| 150 | u32 dctrl_dview; | ||
| 151 | |||
| 152 | u32 bits_pipeline; | ||
| 148 | }; | 153 | }; |
| 149 | 154 | ||
| 150 | #define HIST_ENTRIES 512 | 155 | #define HIST_ENTRIES 512 |
| @@ -196,8 +201,9 @@ struct isc_device { | |||
| 196 | struct v4l2_format fmt; | 201 | struct v4l2_format fmt; |
| 197 | struct isc_format **user_formats; | 202 | struct isc_format **user_formats; |
| 198 | unsigned int num_user_formats; | 203 | unsigned int num_user_formats; |
| 199 | const struct isc_format *current_fmt; | 204 | |
| 200 | const struct isc_format *raw_fmt; | 205 | struct fmt_config config; |
| 206 | struct fmt_config try_config; | ||
| 201 | 207 | ||
| 202 | struct isc_ctrls ctrls; | 208 | struct isc_ctrls ctrls; |
| 203 | struct work_struct awb_work; | 209 | struct work_struct awb_work; |
| @@ -210,319 +216,125 @@ struct isc_device { | |||
| 210 | struct list_head subdev_entities; | 216 | struct list_head subdev_entities; |
| 211 | }; | 217 | }; |
| 212 | 218 | ||
| 213 | static struct isc_format formats_list[] = { | 219 | /* This is a list of the formats that the ISC can *output* */ |
| 214 | { | 220 | static struct isc_format controller_formats[] = { |
| 215 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
| 216 | .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, | ||
| 217 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 218 | .bpp = 8, | ||
| 219 | }, | ||
| 220 | { | 221 | { |
| 221 | .fourcc = V4L2_PIX_FMT_SGBRG8, | 222 | .fourcc = V4L2_PIX_FMT_ARGB444, |
| 222 | .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, | ||
| 223 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 224 | .bpp = 8, | ||
| 225 | }, | ||
| 226 | { | ||
| 227 | .fourcc = V4L2_PIX_FMT_SGRBG8, | ||
| 228 | .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, | ||
| 229 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 230 | .bpp = 8, | ||
| 231 | }, | ||
| 232 | { | ||
| 233 | .fourcc = V4L2_PIX_FMT_SRGGB8, | ||
| 234 | .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, | ||
| 235 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 236 | .bpp = 8, | ||
| 237 | }, | ||
| 238 | { | ||
| 239 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
| 240 | .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, | ||
| 241 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 242 | .bpp = 16, | ||
| 243 | }, | ||
| 244 | { | ||
| 245 | .fourcc = V4L2_PIX_FMT_SGBRG10, | ||
| 246 | .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, | ||
| 247 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 248 | .bpp = 16, | ||
| 249 | }, | ||
| 250 | { | ||
| 251 | .fourcc = V4L2_PIX_FMT_SGRBG10, | ||
| 252 | .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, | ||
| 253 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 254 | .bpp = 16, | ||
| 255 | }, | 223 | }, |
| 256 | { | 224 | { |
| 257 | .fourcc = V4L2_PIX_FMT_SRGGB10, | 225 | .fourcc = V4L2_PIX_FMT_ARGB555, |
| 258 | .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, | ||
| 259 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 260 | .bpp = 16, | ||
| 261 | }, | 226 | }, |
| 262 | { | 227 | { |
| 263 | .fourcc = V4L2_PIX_FMT_SBGGR12, | 228 | .fourcc = V4L2_PIX_FMT_RGB565, |
| 264 | .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, | ||
| 265 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 266 | .bpp = 16, | ||
| 267 | }, | 229 | }, |
| 268 | { | 230 | { |
| 269 | .fourcc = V4L2_PIX_FMT_SGBRG12, | 231 | .fourcc = V4L2_PIX_FMT_ABGR32, |
| 270 | .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, | ||
| 271 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 272 | .bpp = 16, | ||
| 273 | }, | 232 | }, |
| 274 | { | 233 | { |
| 275 | .fourcc = V4L2_PIX_FMT_SGRBG12, | 234 | .fourcc = V4L2_PIX_FMT_XBGR32, |
| 276 | .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, | ||
| 277 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 278 | .bpp = 16, | ||
| 279 | }, | 235 | }, |
| 280 | { | 236 | { |
| 281 | .fourcc = V4L2_PIX_FMT_SRGGB12, | 237 | .fourcc = V4L2_PIX_FMT_YUV420, |
| 282 | .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, | ||
| 283 | .flags = FMT_FLAG_RAW_FROM_SENSOR, | ||
| 284 | .bpp = 16, | ||
| 285 | }, | 238 | }, |
| 286 | { | 239 | { |
| 287 | .fourcc = V4L2_PIX_FMT_YUV420, | 240 | .fourcc = V4L2_PIX_FMT_YUYV, |
| 288 | .mbus_code = 0x0, | ||
| 289 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 290 | .bpp = 12, | ||
| 291 | }, | 241 | }, |
| 292 | { | 242 | { |
| 293 | .fourcc = V4L2_PIX_FMT_YUV422P, | 243 | .fourcc = V4L2_PIX_FMT_YUV422P, |
| 294 | .mbus_code = 0x0, | ||
| 295 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 296 | .bpp = 16, | ||
| 297 | }, | 244 | }, |
| 298 | { | 245 | { |
| 299 | .fourcc = V4L2_PIX_FMT_GREY, | 246 | .fourcc = V4L2_PIX_FMT_GREY, |
| 300 | .mbus_code = MEDIA_BUS_FMT_Y8_1X8, | ||
| 301 | .flags = FMT_FLAG_FROM_CONTROLLER | | ||
| 302 | FMT_FLAG_FROM_SENSOR, | ||
| 303 | .bpp = 8, | ||
| 304 | }, | ||
| 305 | { | ||
| 306 | .fourcc = V4L2_PIX_FMT_ARGB444, | ||
| 307 | .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, | ||
| 308 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 309 | .bpp = 16, | ||
| 310 | }, | ||
| 311 | { | ||
| 312 | .fourcc = V4L2_PIX_FMT_ARGB555, | ||
| 313 | .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, | ||
| 314 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 315 | .bpp = 16, | ||
| 316 | }, | ||
| 317 | { | ||
| 318 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
| 319 | .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, | ||
| 320 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 321 | .bpp = 16, | ||
| 322 | }, | ||
| 323 | { | ||
| 324 | .fourcc = V4L2_PIX_FMT_ARGB32, | ||
| 325 | .mbus_code = MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 326 | .flags = FMT_FLAG_FROM_CONTROLLER, | ||
| 327 | .bpp = 32, | ||
| 328 | }, | ||
| 329 | { | ||
| 330 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
| 331 | .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, | ||
| 332 | .flags = FMT_FLAG_FROM_CONTROLLER | | ||
| 333 | FMT_FLAG_FROM_SENSOR, | ||
| 334 | .bpp = 16, | ||
| 335 | }, | 247 | }, |
| 336 | }; | 248 | }; |
| 337 | 249 | ||
| 338 | static struct fmt_config fmt_configs_list[] = { | 250 | /* This is a list of formats that the ISC can receive as *input* */ |
| 251 | static struct isc_format formats_list[] = { | ||
| 339 | { | 252 | { |
| 340 | .fourcc = V4L2_PIX_FMT_SBGGR8, | 253 | .fourcc = V4L2_PIX_FMT_SBGGR8, |
| 254 | .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, | ||
| 341 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 255 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 342 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | 256 | .cfa_baycfg = ISC_BAY_CFG_BGBG, |
| 343 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, | ||
| 344 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 345 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 346 | .bits_pipeline = 0x0, | ||
| 347 | }, | 257 | }, |
| 348 | { | 258 | { |
| 349 | .fourcc = V4L2_PIX_FMT_SGBRG8, | 259 | .fourcc = V4L2_PIX_FMT_SGBRG8, |
| 260 | .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, | ||
| 350 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 261 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 351 | .cfa_baycfg = ISC_BAY_CFG_GBGB, | 262 | .cfa_baycfg = ISC_BAY_CFG_GBGB, |
| 352 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, | ||
| 353 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 354 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 355 | .bits_pipeline = 0x0, | ||
| 356 | }, | 263 | }, |
| 357 | { | 264 | { |
| 358 | .fourcc = V4L2_PIX_FMT_SGRBG8, | 265 | .fourcc = V4L2_PIX_FMT_SGRBG8, |
| 266 | .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, | ||
| 359 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 267 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 360 | .cfa_baycfg = ISC_BAY_CFG_GRGR, | 268 | .cfa_baycfg = ISC_BAY_CFG_GRGR, |
| 361 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, | ||
| 362 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 363 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 364 | .bits_pipeline = 0x0, | ||
| 365 | }, | 269 | }, |
| 366 | { | 270 | { |
| 367 | .fourcc = V4L2_PIX_FMT_SRGGB8, | 271 | .fourcc = V4L2_PIX_FMT_SRGGB8, |
| 272 | .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, | ||
| 368 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 273 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 369 | .cfa_baycfg = ISC_BAY_CFG_RGRG, | 274 | .cfa_baycfg = ISC_BAY_CFG_RGRG, |
| 370 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, | ||
| 371 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 372 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 373 | .bits_pipeline = 0x0, | ||
| 374 | }, | 275 | }, |
| 375 | { | 276 | { |
| 376 | .fourcc = V4L2_PIX_FMT_SBGGR10, | 277 | .fourcc = V4L2_PIX_FMT_SBGGR10, |
| 278 | .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, | ||
| 377 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, | 279 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, |
| 378 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | 280 | .cfa_baycfg = ISC_BAY_CFG_RGRG, |
| 379 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, | ||
| 380 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 381 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 382 | .bits_pipeline = 0x0, | ||
| 383 | }, | 281 | }, |
| 384 | { | 282 | { |
| 385 | .fourcc = V4L2_PIX_FMT_SGBRG10, | 283 | .fourcc = V4L2_PIX_FMT_SGBRG10, |
| 284 | .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, | ||
| 386 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, | 285 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, |
| 387 | .cfa_baycfg = ISC_BAY_CFG_GBGB, | 286 | .cfa_baycfg = ISC_BAY_CFG_GBGB, |
| 388 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, | ||
| 389 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 390 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 391 | .bits_pipeline = 0x0, | ||
| 392 | }, | 287 | }, |
| 393 | { | 288 | { |
| 394 | .fourcc = V4L2_PIX_FMT_SGRBG10, | 289 | .fourcc = V4L2_PIX_FMT_SGRBG10, |
| 290 | .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, | ||
| 395 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, | 291 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, |
| 396 | .cfa_baycfg = ISC_BAY_CFG_GRGR, | 292 | .cfa_baycfg = ISC_BAY_CFG_GRGR, |
| 397 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, | ||
| 398 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 399 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 400 | .bits_pipeline = 0x0, | ||
| 401 | }, | 293 | }, |
| 402 | { | 294 | { |
| 403 | .fourcc = V4L2_PIX_FMT_SRGGB10, | 295 | .fourcc = V4L2_PIX_FMT_SRGGB10, |
| 296 | .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, | ||
| 404 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, | 297 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, |
| 405 | .cfa_baycfg = ISC_BAY_CFG_RGRG, | 298 | .cfa_baycfg = ISC_BAY_CFG_RGRG, |
| 406 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, | ||
| 407 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 408 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 409 | .bits_pipeline = 0x0, | ||
| 410 | }, | 299 | }, |
| 411 | { | 300 | { |
| 412 | .fourcc = V4L2_PIX_FMT_SBGGR12, | 301 | .fourcc = V4L2_PIX_FMT_SBGGR12, |
| 302 | .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, | ||
| 413 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, | 303 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, |
| 414 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | 304 | .cfa_baycfg = ISC_BAY_CFG_BGBG, |
| 415 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, | ||
| 416 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 417 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 418 | .bits_pipeline = 0x0, | ||
| 419 | }, | 305 | }, |
| 420 | { | 306 | { |
| 421 | .fourcc = V4L2_PIX_FMT_SGBRG12, | 307 | .fourcc = V4L2_PIX_FMT_SGBRG12, |
| 308 | .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, | ||
| 422 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, | 309 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, |
| 423 | .cfa_baycfg = ISC_BAY_CFG_GBGB, | 310 | .cfa_baycfg = ISC_BAY_CFG_GBGB, |
| 424 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, | ||
| 425 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 426 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 427 | .bits_pipeline = 0x0 | ||
| 428 | }, | 311 | }, |
| 429 | { | 312 | { |
| 430 | .fourcc = V4L2_PIX_FMT_SGRBG12, | 313 | .fourcc = V4L2_PIX_FMT_SGRBG12, |
| 314 | .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, | ||
| 431 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, | 315 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, |
| 432 | .cfa_baycfg = ISC_BAY_CFG_GRGR, | 316 | .cfa_baycfg = ISC_BAY_CFG_GRGR, |
| 433 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, | ||
| 434 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 435 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 436 | .bits_pipeline = 0x0, | ||
| 437 | }, | 317 | }, |
| 438 | { | 318 | { |
| 439 | .fourcc = V4L2_PIX_FMT_SRGGB12, | 319 | .fourcc = V4L2_PIX_FMT_SRGGB12, |
| 320 | .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, | ||
| 440 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, | 321 | .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, |
| 441 | .cfa_baycfg = ISC_BAY_CFG_RGRG, | 322 | .cfa_baycfg = ISC_BAY_CFG_RGRG, |
| 442 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, | ||
| 443 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 444 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 445 | .bits_pipeline = 0x0, | ||
| 446 | }, | ||
| 447 | { | ||
| 448 | .fourcc = V4L2_PIX_FMT_YUV420, | ||
| 449 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | ||
| 450 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 451 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC, | ||
| 452 | .dcfg_imode = ISC_DCFG_IMODE_YC420P, | ||
| 453 | .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR, | ||
| 454 | .bits_pipeline = SUB420_ENABLE | SUB422_ENABLE | | ||
| 455 | CBC_ENABLE | CSC_ENABLE | | ||
| 456 | GAM_ENABLES | | ||
| 457 | CFA_ENABLE | WB_ENABLE, | ||
| 458 | }, | ||
| 459 | { | ||
| 460 | .fourcc = V4L2_PIX_FMT_YUV422P, | ||
| 461 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | ||
| 462 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 463 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC, | ||
| 464 | .dcfg_imode = ISC_DCFG_IMODE_YC422P, | ||
| 465 | .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR, | ||
| 466 | .bits_pipeline = SUB422_ENABLE | | ||
| 467 | CBC_ENABLE | CSC_ENABLE | | ||
| 468 | GAM_ENABLES | | ||
| 469 | CFA_ENABLE | WB_ENABLE, | ||
| 470 | }, | 323 | }, |
| 471 | { | 324 | { |
| 472 | .fourcc = V4L2_PIX_FMT_GREY, | 325 | .fourcc = V4L2_PIX_FMT_GREY, |
| 326 | .mbus_code = MEDIA_BUS_FMT_Y8_1X8, | ||
| 473 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 327 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 474 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 475 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8, | ||
| 476 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 477 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 478 | .bits_pipeline = CBC_ENABLE | CSC_ENABLE | | ||
| 479 | GAM_ENABLES | | ||
| 480 | CFA_ENABLE | WB_ENABLE, | ||
| 481 | }, | ||
| 482 | { | ||
| 483 | .fourcc = V4L2_PIX_FMT_ARGB444, | ||
| 484 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | ||
| 485 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 486 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444, | ||
| 487 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 488 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 489 | .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, | ||
| 490 | }, | 328 | }, |
| 491 | { | 329 | { |
| 492 | .fourcc = V4L2_PIX_FMT_ARGB555, | 330 | .fourcc = V4L2_PIX_FMT_YUYV, |
| 331 | .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, | ||
| 493 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 332 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 494 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 495 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555, | ||
| 496 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 497 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 498 | .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, | ||
| 499 | }, | 333 | }, |
| 500 | { | 334 | { |
| 501 | .fourcc = V4L2_PIX_FMT_RGB565, | 335 | .fourcc = V4L2_PIX_FMT_RGB565, |
| 336 | .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, | ||
| 502 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | 337 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, |
| 503 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 504 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565, | ||
| 505 | .dcfg_imode = ISC_DCFG_IMODE_PACKED16, | ||
| 506 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 507 | .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, | ||
| 508 | }, | ||
| 509 | { | ||
| 510 | .fourcc = V4L2_PIX_FMT_ARGB32, | ||
| 511 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | ||
| 512 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 513 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32, | ||
| 514 | .dcfg_imode = ISC_DCFG_IMODE_PACKED32, | ||
| 515 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 516 | .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, | ||
| 517 | }, | ||
| 518 | { | ||
| 519 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
| 520 | .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, | ||
| 521 | .cfa_baycfg = ISC_BAY_CFG_BGBG, | ||
| 522 | .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, | ||
| 523 | .dcfg_imode = ISC_DCFG_IMODE_PACKED8, | ||
| 524 | .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, | ||
| 525 | .bits_pipeline = 0x0 | ||
| 526 | }, | 338 | }, |
| 527 | }; | 339 | }; |
| 528 | 340 | ||
| @@ -571,6 +383,13 @@ static const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = { | |||
| 571 | 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, | 383 | 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, |
| 572 | }; | 384 | }; |
| 573 | 385 | ||
| 386 | #define ISC_IS_FORMAT_RAW(mbus_code) \ | ||
| 387 | (((mbus_code) & 0xf000) == 0x3000) | ||
| 388 | |||
| 389 | static unsigned int debug; | ||
| 390 | module_param(debug, int, 0644); | ||
| 391 | MODULE_PARM_DESC(debug, "debug level (0-2)"); | ||
| 392 | |||
| 574 | static unsigned int sensor_preferred = 1; | 393 | static unsigned int sensor_preferred = 1; |
| 575 | module_param(sensor_preferred, uint, 0644); | 394 | module_param(sensor_preferred, uint, 0644); |
| 576 | MODULE_PARM_DESC(sensor_preferred, | 395 | MODULE_PARM_DESC(sensor_preferred, |
| @@ -896,40 +715,17 @@ static int isc_buffer_prepare(struct vb2_buffer *vb) | |||
| 896 | return 0; | 715 | return 0; |
| 897 | } | 716 | } |
| 898 | 717 | ||
| 899 | static inline bool sensor_is_preferred(const struct isc_format *isc_fmt) | ||
| 900 | { | ||
| 901 | return (sensor_preferred && isc_fmt->sd_support) || | ||
| 902 | !isc_fmt->isc_support; | ||
| 903 | } | ||
| 904 | |||
| 905 | static struct fmt_config *get_fmt_config(u32 fourcc) | ||
| 906 | { | ||
| 907 | struct fmt_config *config; | ||
| 908 | int i; | ||
| 909 | |||
| 910 | config = &fmt_configs_list[0]; | ||
| 911 | for (i = 0; i < ARRAY_SIZE(fmt_configs_list); i++) { | ||
| 912 | if (config->fourcc == fourcc) | ||
| 913 | return config; | ||
| 914 | |||
| 915 | config++; | ||
| 916 | } | ||
| 917 | return NULL; | ||
| 918 | } | ||
| 919 | |||
| 920 | static void isc_start_dma(struct isc_device *isc) | 718 | static void isc_start_dma(struct isc_device *isc) |
| 921 | { | 719 | { |
| 922 | struct regmap *regmap = isc->regmap; | 720 | struct regmap *regmap = isc->regmap; |
| 923 | struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix; | 721 | u32 sizeimage = isc->fmt.fmt.pix.sizeimage; |
| 924 | u32 sizeimage = pixfmt->sizeimage; | ||
| 925 | struct fmt_config *config = get_fmt_config(isc->current_fmt->fourcc); | ||
| 926 | u32 dctrl_dview; | 722 | u32 dctrl_dview; |
| 927 | dma_addr_t addr0; | 723 | dma_addr_t addr0; |
| 928 | 724 | ||
| 929 | addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); | 725 | addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); |
| 930 | regmap_write(regmap, ISC_DAD0, addr0); | 726 | regmap_write(regmap, ISC_DAD0, addr0); |
| 931 | 727 | ||
| 932 | switch (pixfmt->pixelformat) { | 728 | switch (isc->config.fourcc) { |
| 933 | case V4L2_PIX_FMT_YUV420: | 729 | case V4L2_PIX_FMT_YUV420: |
| 934 | regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3); | 730 | regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3); |
| 935 | regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6); | 731 | regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6); |
| @@ -942,10 +738,7 @@ static void isc_start_dma(struct isc_device *isc) | |||
| 942 | break; | 738 | break; |
| 943 | } | 739 | } |
| 944 | 740 | ||
| 945 | if (sensor_is_preferred(isc->current_fmt)) | 741 | dctrl_dview = isc->config.dctrl_dview; |
| 946 | dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 947 | else | ||
| 948 | dctrl_dview = config->dctrl_dview; | ||
| 949 | 742 | ||
| 950 | regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS); | 743 | regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS); |
| 951 | regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); | 744 | regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); |
| @@ -955,7 +748,6 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) | |||
| 955 | { | 748 | { |
| 956 | struct regmap *regmap = isc->regmap; | 749 | struct regmap *regmap = isc->regmap; |
| 957 | struct isc_ctrls *ctrls = &isc->ctrls; | 750 | struct isc_ctrls *ctrls = &isc->ctrls; |
| 958 | struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); | ||
| 959 | u32 val, bay_cfg; | 751 | u32 val, bay_cfg; |
| 960 | const u32 *gamma; | 752 | const u32 *gamma; |
| 961 | unsigned int i; | 753 | unsigned int i; |
| @@ -969,7 +761,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) | |||
| 969 | if (!pipeline) | 761 | if (!pipeline) |
| 970 | return; | 762 | return; |
| 971 | 763 | ||
| 972 | bay_cfg = config->cfa_baycfg; | 764 | bay_cfg = isc->config.sd_format->cfa_baycfg; |
| 973 | 765 | ||
| 974 | regmap_write(regmap, ISC_WB_CFG, bay_cfg); | 766 | regmap_write(regmap, ISC_WB_CFG, bay_cfg); |
| 975 | regmap_write(regmap, ISC_WB_O_RGR, 0x0); | 767 | regmap_write(regmap, ISC_WB_O_RGR, 0x0); |
| @@ -1011,24 +803,24 @@ static int isc_update_profile(struct isc_device *isc) | |||
| 1011 | } | 803 | } |
| 1012 | 804 | ||
| 1013 | if (counter < 0) { | 805 | if (counter < 0) { |
| 1014 | v4l2_warn(&isc->v4l2_dev, "Time out to update profie\n"); | 806 | v4l2_warn(&isc->v4l2_dev, "Time out to update profile\n"); |
| 1015 | return -ETIMEDOUT; | 807 | return -ETIMEDOUT; |
| 1016 | } | 808 | } |
| 1017 | 809 | ||
| 1018 | return 0; | 810 | return 0; |
| 1019 | } | 811 | } |
| 1020 | 812 | ||
| 1021 | static void isc_set_histogram(struct isc_device *isc) | 813 | static void isc_set_histogram(struct isc_device *isc, bool enable) |
| 1022 | { | 814 | { |
| 1023 | struct regmap *regmap = isc->regmap; | 815 | struct regmap *regmap = isc->regmap; |
| 1024 | struct isc_ctrls *ctrls = &isc->ctrls; | 816 | struct isc_ctrls *ctrls = &isc->ctrls; |
| 1025 | struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); | ||
| 1026 | 817 | ||
| 1027 | if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) { | 818 | if (enable) { |
| 1028 | regmap_write(regmap, ISC_HIS_CFG, | 819 | regmap_write(regmap, ISC_HIS_CFG, |
| 1029 | ISC_HIS_CFG_MODE_R | | 820 | ISC_HIS_CFG_MODE_R | |
| 1030 | (config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) | | 821 | (isc->config.sd_format->cfa_baycfg |
| 1031 | ISC_HIS_CFG_RAR); | 822 | << ISC_HIS_CFG_BAYSEL_SHIFT) | |
| 823 | ISC_HIS_CFG_RAR); | ||
| 1032 | regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN); | 824 | regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN); |
| 1033 | regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE); | 825 | regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE); |
| 1034 | ctrls->hist_id = ISC_HIS_CFG_MODE_R; | 826 | ctrls->hist_id = ISC_HIS_CFG_MODE_R; |
| @@ -1036,7 +828,7 @@ static void isc_set_histogram(struct isc_device *isc) | |||
| 1036 | regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ); | 828 | regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ); |
| 1037 | 829 | ||
| 1038 | ctrls->hist_stat = HIST_ENABLED; | 830 | ctrls->hist_stat = HIST_ENABLED; |
| 1039 | } else if (!ctrls->awb && (ctrls->hist_stat != HIST_DISABLED)) { | 831 | } else { |
| 1040 | regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE); | 832 | regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE); |
| 1041 | regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS); | 833 | regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS); |
| 1042 | 834 | ||
| @@ -1044,58 +836,24 @@ static void isc_set_histogram(struct isc_device *isc) | |||
| 1044 | } | 836 | } |
| 1045 | } | 837 | } |
| 1046 | 838 | ||
| 1047 | static inline void isc_get_param(const struct isc_format *fmt, | ||
| 1048 | u32 *rlp_mode, u32 *dcfg) | ||
| 1049 | { | ||
| 1050 | struct fmt_config *config = get_fmt_config(fmt->fourcc); | ||
| 1051 | |||
| 1052 | *dcfg = ISC_DCFG_YMBSIZE_BEATS8; | ||
| 1053 | |||
| 1054 | switch (fmt->fourcc) { | ||
| 1055 | case V4L2_PIX_FMT_SBGGR10: | ||
| 1056 | case V4L2_PIX_FMT_SGBRG10: | ||
| 1057 | case V4L2_PIX_FMT_SGRBG10: | ||
| 1058 | case V4L2_PIX_FMT_SRGGB10: | ||
| 1059 | case V4L2_PIX_FMT_SBGGR12: | ||
| 1060 | case V4L2_PIX_FMT_SGBRG12: | ||
| 1061 | case V4L2_PIX_FMT_SGRBG12: | ||
| 1062 | case V4L2_PIX_FMT_SRGGB12: | ||
| 1063 | *rlp_mode = config->rlp_cfg_mode; | ||
| 1064 | *dcfg |= config->dcfg_imode; | ||
| 1065 | break; | ||
| 1066 | default: | ||
| 1067 | *rlp_mode = ISC_RLP_CFG_MODE_DAT8; | ||
| 1068 | *dcfg |= ISC_DCFG_IMODE_PACKED8; | ||
| 1069 | break; | ||
| 1070 | } | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | static int isc_configure(struct isc_device *isc) | 839 | static int isc_configure(struct isc_device *isc) |
| 1074 | { | 840 | { |
| 1075 | struct regmap *regmap = isc->regmap; | 841 | struct regmap *regmap = isc->regmap; |
| 1076 | const struct isc_format *current_fmt = isc->current_fmt; | ||
| 1077 | struct fmt_config *curfmt_config = get_fmt_config(current_fmt->fourcc); | ||
| 1078 | struct fmt_config *rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc); | ||
| 1079 | struct isc_subdev_entity *subdev = isc->current_subdev; | ||
| 1080 | u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline; | 842 | u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline; |
| 843 | struct isc_subdev_entity *subdev = isc->current_subdev; | ||
| 1081 | 844 | ||
| 1082 | if (sensor_is_preferred(current_fmt)) { | 845 | pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps; |
| 1083 | pfe_cfg0 = curfmt_config->pfe_cfg0_bps; | 846 | rlp_mode = isc->config.rlp_cfg_mode; |
| 1084 | pipeline = 0x0; | 847 | pipeline = isc->config.bits_pipeline; |
| 1085 | isc_get_param(current_fmt, &rlp_mode, &dcfg); | 848 | |
| 1086 | isc->ctrls.hist_stat = HIST_INIT; | 849 | dcfg = isc->config.dcfg_imode | |
| 1087 | } else { | ||
| 1088 | pfe_cfg0 = rawfmt_config->pfe_cfg0_bps; | ||
| 1089 | pipeline = curfmt_config->bits_pipeline; | ||
| 1090 | rlp_mode = curfmt_config->rlp_cfg_mode; | ||
| 1091 | dcfg = curfmt_config->dcfg_imode | | ||
| 1092 | ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; | 850 | ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; |
| 1093 | } | ||
| 1094 | 851 | ||
| 1095 | pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; | 852 | pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; |
| 1096 | mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | | 853 | mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | |
| 1097 | ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | | 854 | ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | |
| 1098 | ISC_PFE_CFG0_MODE_MASK; | 855 | ISC_PFE_CFG0_MODE_MASK | ISC_PFE_CFG0_CCIR_CRC | |
| 856 | ISC_PFE_CFG0_CCIR656; | ||
| 1099 | 857 | ||
| 1100 | regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); | 858 | regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); |
| 1101 | 859 | ||
| @@ -1107,8 +865,15 @@ static int isc_configure(struct isc_device *isc) | |||
| 1107 | /* Set the pipeline */ | 865 | /* Set the pipeline */ |
| 1108 | isc_set_pipeline(isc, pipeline); | 866 | isc_set_pipeline(isc, pipeline); |
| 1109 | 867 | ||
| 1110 | if (pipeline) | 868 | /* |
| 1111 | isc_set_histogram(isc); | 869 | * The current implemented histogram is available for RAW R, B, GB |
| 870 | * channels. We need to check if sensor is outputting RAW BAYER | ||
| 871 | */ | ||
| 872 | if (isc->ctrls.awb && | ||
| 873 | ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) | ||
| 874 | isc_set_histogram(isc, true); | ||
| 875 | else | ||
| 876 | isc_set_histogram(isc, false); | ||
| 1112 | 877 | ||
| 1113 | /* Update profile */ | 878 | /* Update profile */ |
| 1114 | return isc_update_profile(isc); | 879 | return isc_update_profile(isc); |
| @@ -1125,7 +890,8 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 1125 | /* Enable stream on the sub device */ | 890 | /* Enable stream on the sub device */ |
| 1126 | ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); | 891 | ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); |
| 1127 | if (ret && ret != -ENOIOCTLCMD) { | 892 | if (ret && ret != -ENOIOCTLCMD) { |
| 1128 | v4l2_err(&isc->v4l2_dev, "stream on failed in subdev\n"); | 893 | v4l2_err(&isc->v4l2_dev, "stream on failed in subdev %d\n", |
| 894 | ret); | ||
| 1129 | goto err_start_stream; | 895 | goto err_start_stream; |
| 1130 | } | 896 | } |
| 1131 | 897 | ||
| @@ -1223,6 +989,22 @@ static void isc_buffer_queue(struct vb2_buffer *vb) | |||
| 1223 | spin_unlock_irqrestore(&isc->dma_queue_lock, flags); | 989 | spin_unlock_irqrestore(&isc->dma_queue_lock, flags); |
| 1224 | } | 990 | } |
| 1225 | 991 | ||
| 992 | static struct isc_format *find_format_by_fourcc(struct isc_device *isc, | ||
| 993 | unsigned int fourcc) | ||
| 994 | { | ||
| 995 | unsigned int num_formats = isc->num_user_formats; | ||
| 996 | struct isc_format *fmt; | ||
| 997 | unsigned int i; | ||
| 998 | |||
| 999 | for (i = 0; i < num_formats; i++) { | ||
| 1000 | fmt = isc->user_formats[i]; | ||
| 1001 | if (fmt->fourcc == fourcc) | ||
| 1002 | return fmt; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | return NULL; | ||
| 1006 | } | ||
| 1007 | |||
| 1226 | static const struct vb2_ops isc_vb2_ops = { | 1008 | static const struct vb2_ops isc_vb2_ops = { |
| 1227 | .queue_setup = isc_queue_setup, | 1009 | .queue_setup = isc_queue_setup, |
| 1228 | .wait_prepare = vb2_ops_wait_prepare, | 1010 | .wait_prepare = vb2_ops_wait_prepare, |
| @@ -1249,15 +1031,31 @@ static int isc_querycap(struct file *file, void *priv, | |||
| 1249 | static int isc_enum_fmt_vid_cap(struct file *file, void *priv, | 1031 | static int isc_enum_fmt_vid_cap(struct file *file, void *priv, |
| 1250 | struct v4l2_fmtdesc *f) | 1032 | struct v4l2_fmtdesc *f) |
| 1251 | { | 1033 | { |
| 1252 | struct isc_device *isc = video_drvdata(file); | ||
| 1253 | u32 index = f->index; | 1034 | u32 index = f->index; |
| 1035 | u32 i, supported_index; | ||
| 1254 | 1036 | ||
| 1255 | if (index >= isc->num_user_formats) | 1037 | if (index < ARRAY_SIZE(controller_formats)) { |
| 1256 | return -EINVAL; | 1038 | f->pixelformat = controller_formats[index].fourcc; |
| 1039 | return 0; | ||
| 1040 | } | ||
| 1257 | 1041 | ||
| 1258 | f->pixelformat = isc->user_formats[index]->fourcc; | 1042 | index -= ARRAY_SIZE(controller_formats); |
| 1259 | 1043 | ||
| 1260 | return 0; | 1044 | i = 0; |
| 1045 | supported_index = 0; | ||
| 1046 | |||
| 1047 | for (i = 0; i < ARRAY_SIZE(formats_list); i++) { | ||
| 1048 | if (!ISC_IS_FORMAT_RAW(formats_list[i].mbus_code) || | ||
| 1049 | !formats_list[i].sd_support) | ||
| 1050 | continue; | ||
| 1051 | if (supported_index == index) { | ||
| 1052 | f->pixelformat = formats_list[i].fourcc; | ||
| 1053 | return 0; | ||
| 1054 | } | ||
| 1055 | supported_index++; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | return -EINVAL; | ||
| 1261 | } | 1059 | } |
| 1262 | 1060 | ||
| 1263 | static int isc_g_fmt_vid_cap(struct file *file, void *priv, | 1061 | static int isc_g_fmt_vid_cap(struct file *file, void *priv, |
| @@ -1270,26 +1068,238 @@ static int isc_g_fmt_vid_cap(struct file *file, void *priv, | |||
| 1270 | return 0; | 1068 | return 0; |
| 1271 | } | 1069 | } |
| 1272 | 1070 | ||
| 1273 | static struct isc_format *find_format_by_fourcc(struct isc_device *isc, | 1071 | /* |
| 1274 | unsigned int fourcc) | 1072 | * Checks the current configured format, if ISC can output it, |
| 1073 | * considering which type of format the ISC receives from the sensor | ||
| 1074 | */ | ||
| 1075 | static int isc_try_validate_formats(struct isc_device *isc) | ||
| 1275 | { | 1076 | { |
| 1276 | unsigned int num_formats = isc->num_user_formats; | 1077 | int ret; |
| 1277 | struct isc_format *fmt; | 1078 | bool bayer = false, yuv = false, rgb = false, grey = false; |
| 1278 | unsigned int i; | 1079 | |
| 1080 | /* all formats supported by the RLP module are OK */ | ||
| 1081 | switch (isc->try_config.fourcc) { | ||
| 1082 | case V4L2_PIX_FMT_SBGGR8: | ||
| 1083 | case V4L2_PIX_FMT_SGBRG8: | ||
| 1084 | case V4L2_PIX_FMT_SGRBG8: | ||
| 1085 | case V4L2_PIX_FMT_SRGGB8: | ||
| 1086 | case V4L2_PIX_FMT_SBGGR10: | ||
| 1087 | case V4L2_PIX_FMT_SGBRG10: | ||
| 1088 | case V4L2_PIX_FMT_SGRBG10: | ||
| 1089 | case V4L2_PIX_FMT_SRGGB10: | ||
| 1090 | case V4L2_PIX_FMT_SBGGR12: | ||
| 1091 | case V4L2_PIX_FMT_SGBRG12: | ||
| 1092 | case V4L2_PIX_FMT_SGRBG12: | ||
| 1093 | case V4L2_PIX_FMT_SRGGB12: | ||
| 1094 | ret = 0; | ||
| 1095 | bayer = true; | ||
| 1096 | break; | ||
| 1279 | 1097 | ||
| 1280 | for (i = 0; i < num_formats; i++) { | 1098 | case V4L2_PIX_FMT_YUV420: |
| 1281 | fmt = isc->user_formats[i]; | 1099 | case V4L2_PIX_FMT_YUV422P: |
| 1282 | if (fmt->fourcc == fourcc) | 1100 | case V4L2_PIX_FMT_YUYV: |
| 1283 | return fmt; | 1101 | ret = 0; |
| 1102 | yuv = true; | ||
| 1103 | break; | ||
| 1104 | |||
| 1105 | case V4L2_PIX_FMT_RGB565: | ||
| 1106 | case V4L2_PIX_FMT_ABGR32: | ||
| 1107 | case V4L2_PIX_FMT_XBGR32: | ||
| 1108 | case V4L2_PIX_FMT_ARGB444: | ||
| 1109 | case V4L2_PIX_FMT_ARGB555: | ||
| 1110 | ret = 0; | ||
| 1111 | rgb = true; | ||
| 1112 | break; | ||
| 1113 | case V4L2_PIX_FMT_GREY: | ||
| 1114 | ret = 0; | ||
| 1115 | grey = true; | ||
| 1116 | break; | ||
| 1117 | default: | ||
| 1118 | /* any other different formats are not supported */ | ||
| 1119 | ret = -EINVAL; | ||
| 1284 | } | 1120 | } |
| 1285 | 1121 | ||
| 1286 | return NULL; | 1122 | /* we cannot output RAW/Grey if we do not receive RAW */ |
| 1123 | if ((bayer || grey) && | ||
| 1124 | !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) | ||
| 1125 | return -EINVAL; | ||
| 1126 | |||
| 1127 | v4l2_dbg(1, debug, &isc->v4l2_dev, | ||
| 1128 | "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n", | ||
| 1129 | rgb, yuv, grey, bayer); | ||
| 1130 | |||
| 1131 | return ret; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | /* | ||
| 1135 | * Configures the RLP and DMA modules, depending on the output format | ||
| 1136 | * configured for the ISC. | ||
| 1137 | * If direct_dump == true, just dump raw data 8 bits. | ||
| 1138 | */ | ||
| 1139 | static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) | ||
| 1140 | { | ||
| 1141 | if (direct_dump) { | ||
| 1142 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; | ||
| 1143 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; | ||
| 1144 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1145 | isc->try_config.bpp = 16; | ||
| 1146 | return 0; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | switch (isc->try_config.fourcc) { | ||
| 1150 | case V4L2_PIX_FMT_SBGGR8: | ||
| 1151 | case V4L2_PIX_FMT_SGBRG8: | ||
| 1152 | case V4L2_PIX_FMT_SGRBG8: | ||
| 1153 | case V4L2_PIX_FMT_SRGGB8: | ||
| 1154 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; | ||
| 1155 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; | ||
| 1156 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1157 | isc->try_config.bpp = 8; | ||
| 1158 | break; | ||
| 1159 | case V4L2_PIX_FMT_SBGGR10: | ||
| 1160 | case V4L2_PIX_FMT_SGBRG10: | ||
| 1161 | case V4L2_PIX_FMT_SGRBG10: | ||
| 1162 | case V4L2_PIX_FMT_SRGGB10: | ||
| 1163 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10; | ||
| 1164 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; | ||
| 1165 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1166 | isc->try_config.bpp = 16; | ||
| 1167 | break; | ||
| 1168 | case V4L2_PIX_FMT_SBGGR12: | ||
| 1169 | case V4L2_PIX_FMT_SGBRG12: | ||
| 1170 | case V4L2_PIX_FMT_SGRBG12: | ||
| 1171 | case V4L2_PIX_FMT_SRGGB12: | ||
| 1172 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12; | ||
| 1173 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; | ||
| 1174 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1175 | isc->try_config.bpp = 16; | ||
| 1176 | break; | ||
| 1177 | case V4L2_PIX_FMT_RGB565: | ||
| 1178 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565; | ||
| 1179 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; | ||
| 1180 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1181 | isc->try_config.bpp = 16; | ||
| 1182 | break; | ||
| 1183 | case V4L2_PIX_FMT_ARGB444: | ||
| 1184 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444; | ||
| 1185 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; | ||
| 1186 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1187 | isc->try_config.bpp = 16; | ||
| 1188 | break; | ||
| 1189 | case V4L2_PIX_FMT_ARGB555: | ||
| 1190 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555; | ||
| 1191 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; | ||
| 1192 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1193 | isc->try_config.bpp = 16; | ||
| 1194 | break; | ||
| 1195 | case V4L2_PIX_FMT_ABGR32: | ||
| 1196 | case V4L2_PIX_FMT_XBGR32: | ||
| 1197 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32; | ||
| 1198 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; | ||
| 1199 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1200 | isc->try_config.bpp = 32; | ||
| 1201 | break; | ||
| 1202 | case V4L2_PIX_FMT_YUV420: | ||
| 1203 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; | ||
| 1204 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P; | ||
| 1205 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; | ||
| 1206 | isc->try_config.bpp = 12; | ||
| 1207 | break; | ||
| 1208 | case V4L2_PIX_FMT_YUV422P: | ||
| 1209 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; | ||
| 1210 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P; | ||
| 1211 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; | ||
| 1212 | isc->try_config.bpp = 16; | ||
| 1213 | break; | ||
| 1214 | case V4L2_PIX_FMT_YUYV: | ||
| 1215 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; | ||
| 1216 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; | ||
| 1217 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1218 | isc->try_config.bpp = 16; | ||
| 1219 | break; | ||
| 1220 | case V4L2_PIX_FMT_GREY: | ||
| 1221 | isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8; | ||
| 1222 | isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; | ||
| 1223 | isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; | ||
| 1224 | isc->try_config.bpp = 8; | ||
| 1225 | break; | ||
| 1226 | default: | ||
| 1227 | return -EINVAL; | ||
| 1228 | } | ||
| 1229 | return 0; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | * Configuring pipeline modules, depending on which format the ISC outputs | ||
| 1234 | * and considering which format it has as input from the sensor. | ||
| 1235 | */ | ||
| 1236 | static int isc_try_configure_pipeline(struct isc_device *isc) | ||
| 1237 | { | ||
| 1238 | switch (isc->try_config.fourcc) { | ||
| 1239 | case V4L2_PIX_FMT_RGB565: | ||
| 1240 | case V4L2_PIX_FMT_ARGB555: | ||
| 1241 | case V4L2_PIX_FMT_ARGB444: | ||
| 1242 | case V4L2_PIX_FMT_ABGR32: | ||
| 1243 | case V4L2_PIX_FMT_XBGR32: | ||
| 1244 | /* if sensor format is RAW, we convert inside ISC */ | ||
| 1245 | if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { | ||
| 1246 | isc->try_config.bits_pipeline = CFA_ENABLE | | ||
| 1247 | WB_ENABLE | GAM_ENABLES; | ||
| 1248 | } else { | ||
| 1249 | isc->try_config.bits_pipeline = 0x0; | ||
| 1250 | } | ||
| 1251 | break; | ||
| 1252 | case V4L2_PIX_FMT_YUV420: | ||
| 1253 | /* if sensor format is RAW, we convert inside ISC */ | ||
| 1254 | if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { | ||
| 1255 | isc->try_config.bits_pipeline = CFA_ENABLE | | ||
| 1256 | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | | ||
| 1257 | SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE; | ||
| 1258 | } else { | ||
| 1259 | isc->try_config.bits_pipeline = 0x0; | ||
| 1260 | } | ||
| 1261 | break; | ||
| 1262 | case V4L2_PIX_FMT_YUV422P: | ||
| 1263 | /* if sensor format is RAW, we convert inside ISC */ | ||
| 1264 | if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { | ||
| 1265 | isc->try_config.bits_pipeline = CFA_ENABLE | | ||
| 1266 | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | | ||
| 1267 | SUB422_ENABLE | CBC_ENABLE; | ||
| 1268 | } else { | ||
| 1269 | isc->try_config.bits_pipeline = 0x0; | ||
| 1270 | } | ||
| 1271 | break; | ||
| 1272 | case V4L2_PIX_FMT_YUYV: | ||
| 1273 | /* if sensor format is RAW, we convert inside ISC */ | ||
| 1274 | if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { | ||
| 1275 | isc->try_config.bits_pipeline = CFA_ENABLE | | ||
| 1276 | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | | ||
| 1277 | SUB422_ENABLE | CBC_ENABLE; | ||
| 1278 | } else { | ||
| 1279 | isc->try_config.bits_pipeline = 0x0; | ||
| 1280 | } | ||
| 1281 | break; | ||
| 1282 | case V4L2_PIX_FMT_GREY: | ||
| 1283 | if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { | ||
| 1284 | /* if sensor format is RAW, we convert inside ISC */ | ||
| 1285 | isc->try_config.bits_pipeline = CFA_ENABLE | | ||
| 1286 | CSC_ENABLE | WB_ENABLE | GAM_ENABLES | | ||
| 1287 | CBC_ENABLE; | ||
| 1288 | } else { | ||
| 1289 | isc->try_config.bits_pipeline = 0x0; | ||
| 1290 | } | ||
| 1291 | break; | ||
| 1292 | default: | ||
| 1293 | isc->try_config.bits_pipeline = 0x0; | ||
| 1294 | } | ||
| 1295 | return 0; | ||
| 1287 | } | 1296 | } |
| 1288 | 1297 | ||
| 1289 | static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, | 1298 | static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, |
| 1290 | struct isc_format **current_fmt, u32 *code) | 1299 | u32 *code) |
| 1291 | { | 1300 | { |
| 1292 | struct isc_format *isc_fmt; | 1301 | int i; |
| 1302 | struct isc_format *sd_fmt = NULL, *direct_fmt = NULL; | ||
| 1293 | struct v4l2_pix_format *pixfmt = &f->fmt.pix; | 1303 | struct v4l2_pix_format *pixfmt = &f->fmt.pix; |
| 1294 | struct v4l2_subdev_pad_config pad_cfg; | 1304 | struct v4l2_subdev_pad_config pad_cfg; |
| 1295 | struct v4l2_subdev_format format = { | 1305 | struct v4l2_subdev_format format = { |
| @@ -1297,48 +1307,119 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, | |||
| 1297 | }; | 1307 | }; |
| 1298 | u32 mbus_code; | 1308 | u32 mbus_code; |
| 1299 | int ret; | 1309 | int ret; |
| 1310 | bool rlp_dma_direct_dump = false; | ||
| 1300 | 1311 | ||
| 1301 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1312 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
| 1302 | return -EINVAL; | 1313 | return -EINVAL; |
| 1303 | 1314 | ||
| 1304 | isc_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat); | 1315 | /* Step 1: find a RAW format that is supported */ |
| 1305 | if (!isc_fmt) { | 1316 | for (i = 0; i < isc->num_user_formats; i++) { |
| 1306 | v4l2_warn(&isc->v4l2_dev, "Format 0x%x not found\n", | 1317 | if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) { |
| 1307 | pixfmt->pixelformat); | 1318 | sd_fmt = isc->user_formats[i]; |
| 1308 | isc_fmt = isc->user_formats[isc->num_user_formats - 1]; | 1319 | break; |
| 1309 | pixfmt->pixelformat = isc_fmt->fourcc; | 1320 | } |
| 1321 | } | ||
| 1322 | /* Step 2: We can continue with this RAW format, or we can look | ||
| 1323 | * for better: maybe sensor supports directly what we need. | ||
| 1324 | */ | ||
| 1325 | direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat); | ||
| 1326 | |||
| 1327 | /* Step 3: We have both. We decide given the module parameter which | ||
| 1328 | * one to use. | ||
| 1329 | */ | ||
| 1330 | if (direct_fmt && sd_fmt && sensor_preferred) | ||
| 1331 | sd_fmt = direct_fmt; | ||
| 1332 | |||
| 1333 | /* Step 4: we do not have RAW but we have a direct format. Use it. */ | ||
| 1334 | if (direct_fmt && !sd_fmt) | ||
| 1335 | sd_fmt = direct_fmt; | ||
| 1336 | |||
| 1337 | /* Step 5: if we are using a direct format, we need to package | ||
| 1338 | * everything as 8 bit data and just dump it | ||
| 1339 | */ | ||
| 1340 | if (sd_fmt == direct_fmt) | ||
| 1341 | rlp_dma_direct_dump = true; | ||
| 1342 | |||
| 1343 | /* Step 6: We have no format. This can happen if the userspace | ||
| 1344 | * requests some weird/invalid format. | ||
| 1345 | * In this case, default to whatever we have | ||
| 1346 | */ | ||
| 1347 | if (!sd_fmt && !direct_fmt) { | ||
| 1348 | sd_fmt = isc->user_formats[isc->num_user_formats - 1]; | ||
| 1349 | v4l2_dbg(1, debug, &isc->v4l2_dev, | ||
| 1350 | "Sensor not supporting %.4s, using %.4s\n", | ||
| 1351 | (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc); | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | if (!sd_fmt) { | ||
| 1355 | ret = -EINVAL; | ||
| 1356 | goto isc_try_fmt_err; | ||
| 1310 | } | 1357 | } |
| 1311 | 1358 | ||
| 1359 | /* Step 7: Print out what we decided for debugging */ | ||
| 1360 | v4l2_dbg(1, debug, &isc->v4l2_dev, | ||
| 1361 | "Preferring to have sensor using format %.4s\n", | ||
| 1362 | (char *)&sd_fmt->fourcc); | ||
| 1363 | |||
| 1364 | /* Step 8: at this moment we decided which format the subdev will use */ | ||
| 1365 | isc->try_config.sd_format = sd_fmt; | ||
| 1366 | |||
| 1312 | /* Limit to Atmel ISC hardware capabilities */ | 1367 | /* Limit to Atmel ISC hardware capabilities */ |
| 1313 | if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) | 1368 | if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) |
| 1314 | pixfmt->width = ISC_MAX_SUPPORT_WIDTH; | 1369 | pixfmt->width = ISC_MAX_SUPPORT_WIDTH; |
| 1315 | if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) | 1370 | if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) |
| 1316 | pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; | 1371 | pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; |
| 1317 | 1372 | ||
| 1318 | if (sensor_is_preferred(isc_fmt)) | 1373 | /* |
| 1319 | mbus_code = isc_fmt->mbus_code; | 1374 | * The mbus format is the one the subdev outputs. |
| 1320 | else | 1375 | * The pixels will be transferred in this format Sensor -> ISC |
| 1321 | mbus_code = isc->raw_fmt->mbus_code; | 1376 | */ |
| 1377 | mbus_code = sd_fmt->mbus_code; | ||
| 1378 | |||
| 1379 | /* | ||
| 1380 | * Validate formats. If the required format is not OK, default to raw. | ||
| 1381 | */ | ||
| 1382 | |||
| 1383 | isc->try_config.fourcc = pixfmt->pixelformat; | ||
| 1384 | |||
| 1385 | if (isc_try_validate_formats(isc)) { | ||
| 1386 | pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc; | ||
| 1387 | /* Re-try to validate the new format */ | ||
| 1388 | ret = isc_try_validate_formats(isc); | ||
| 1389 | if (ret) | ||
| 1390 | goto isc_try_fmt_err; | ||
| 1391 | } | ||
| 1392 | |||
| 1393 | ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump); | ||
| 1394 | if (ret) | ||
| 1395 | goto isc_try_fmt_err; | ||
| 1396 | |||
| 1397 | ret = isc_try_configure_pipeline(isc); | ||
| 1398 | if (ret) | ||
| 1399 | goto isc_try_fmt_err; | ||
| 1322 | 1400 | ||
| 1323 | v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code); | 1401 | v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code); |
| 1324 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, | 1402 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, |
| 1325 | &pad_cfg, &format); | 1403 | &pad_cfg, &format); |
| 1326 | if (ret < 0) | 1404 | if (ret < 0) |
| 1327 | return ret; | 1405 | goto isc_try_fmt_err; |
| 1328 | 1406 | ||
| 1329 | v4l2_fill_pix_format(pixfmt, &format.format); | 1407 | v4l2_fill_pix_format(pixfmt, &format.format); |
| 1330 | 1408 | ||
| 1331 | pixfmt->field = V4L2_FIELD_NONE; | 1409 | pixfmt->field = V4L2_FIELD_NONE; |
| 1332 | pixfmt->bytesperline = (pixfmt->width * isc_fmt->bpp) >> 3; | 1410 | pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; |
| 1333 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; | 1411 | pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; |
| 1334 | 1412 | ||
| 1335 | if (current_fmt) | ||
| 1336 | *current_fmt = isc_fmt; | ||
| 1337 | |||
| 1338 | if (code) | 1413 | if (code) |
| 1339 | *code = mbus_code; | 1414 | *code = mbus_code; |
| 1340 | 1415 | ||
| 1341 | return 0; | 1416 | return 0; |
| 1417 | |||
| 1418 | isc_try_fmt_err: | ||
| 1419 | v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n"); | ||
| 1420 | memset(&isc->try_config, 0, sizeof(isc->try_config)); | ||
| 1421 | |||
| 1422 | return ret; | ||
| 1342 | } | 1423 | } |
| 1343 | 1424 | ||
| 1344 | static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) | 1425 | static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) |
| @@ -1346,11 +1427,10 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) | |||
| 1346 | struct v4l2_subdev_format format = { | 1427 | struct v4l2_subdev_format format = { |
| 1347 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | 1428 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
| 1348 | }; | 1429 | }; |
| 1349 | struct isc_format *current_fmt; | 1430 | u32 mbus_code = 0; |
| 1350 | u32 mbus_code; | ||
| 1351 | int ret; | 1431 | int ret; |
| 1352 | 1432 | ||
| 1353 | ret = isc_try_fmt(isc, f, ¤t_fmt, &mbus_code); | 1433 | ret = isc_try_fmt(isc, f, &mbus_code); |
| 1354 | if (ret) | 1434 | if (ret) |
| 1355 | return ret; | 1435 | return ret; |
| 1356 | 1436 | ||
| @@ -1361,7 +1441,10 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) | |||
| 1361 | return ret; | 1441 | return ret; |
| 1362 | 1442 | ||
| 1363 | isc->fmt = *f; | 1443 | isc->fmt = *f; |
| 1364 | isc->current_fmt = current_fmt; | 1444 | /* make the try configuration active */ |
| 1445 | isc->config = isc->try_config; | ||
| 1446 | |||
| 1447 | v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n"); | ||
| 1365 | 1448 | ||
| 1366 | return 0; | 1449 | return 0; |
| 1367 | } | 1450 | } |
| @@ -1382,7 +1465,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 1382 | { | 1465 | { |
| 1383 | struct isc_device *isc = video_drvdata(file); | 1466 | struct isc_device *isc = video_drvdata(file); |
| 1384 | 1467 | ||
| 1385 | return isc_try_fmt(isc, f, NULL, NULL); | 1468 | return isc_try_fmt(isc, f, NULL); |
| 1386 | } | 1469 | } |
| 1387 | 1470 | ||
| 1388 | static int isc_enum_input(struct file *file, void *priv, | 1471 | static int isc_enum_input(struct file *file, void *priv, |
| @@ -1431,27 +1514,31 @@ static int isc_enum_framesizes(struct file *file, void *fh, | |||
| 1431 | struct v4l2_frmsizeenum *fsize) | 1514 | struct v4l2_frmsizeenum *fsize) |
| 1432 | { | 1515 | { |
| 1433 | struct isc_device *isc = video_drvdata(file); | 1516 | struct isc_device *isc = video_drvdata(file); |
| 1434 | const struct isc_format *isc_fmt; | ||
| 1435 | struct v4l2_subdev_frame_size_enum fse = { | 1517 | struct v4l2_subdev_frame_size_enum fse = { |
| 1436 | .index = fsize->index, | 1518 | .index = fsize->index, |
| 1437 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | 1519 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
| 1438 | }; | 1520 | }; |
| 1439 | int ret; | 1521 | int ret = -EINVAL; |
| 1522 | int i; | ||
| 1440 | 1523 | ||
| 1441 | isc_fmt = find_format_by_fourcc(isc, fsize->pixel_format); | 1524 | for (i = 0; i < isc->num_user_formats; i++) |
| 1442 | if (!isc_fmt) | 1525 | if (isc->user_formats[i]->fourcc == fsize->pixel_format) |
| 1443 | return -EINVAL; | 1526 | ret = 0; |
| 1444 | 1527 | ||
| 1445 | if (sensor_is_preferred(isc_fmt)) | 1528 | for (i = 0; i < ARRAY_SIZE(controller_formats); i++) |
| 1446 | fse.code = isc_fmt->mbus_code; | 1529 | if (controller_formats[i].fourcc == fsize->pixel_format) |
| 1447 | else | 1530 | ret = 0; |
| 1448 | fse.code = isc->raw_fmt->mbus_code; | 1531 | |
| 1532 | if (ret) | ||
| 1533 | return ret; | ||
| 1449 | 1534 | ||
| 1450 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, | 1535 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, |
| 1451 | NULL, &fse); | 1536 | NULL, &fse); |
| 1452 | if (ret) | 1537 | if (ret) |
| 1453 | return ret; | 1538 | return ret; |
| 1454 | 1539 | ||
| 1540 | fse.code = isc->config.sd_format->mbus_code; | ||
| 1541 | |||
| 1455 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | 1542 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; |
| 1456 | fsize->discrete.width = fse.max_width; | 1543 | fsize->discrete.width = fse.max_width; |
| 1457 | fsize->discrete.height = fse.max_height; | 1544 | fsize->discrete.height = fse.max_height; |
| @@ -1463,29 +1550,32 @@ static int isc_enum_frameintervals(struct file *file, void *fh, | |||
| 1463 | struct v4l2_frmivalenum *fival) | 1550 | struct v4l2_frmivalenum *fival) |
| 1464 | { | 1551 | { |
| 1465 | struct isc_device *isc = video_drvdata(file); | 1552 | struct isc_device *isc = video_drvdata(file); |
| 1466 | const struct isc_format *isc_fmt; | ||
| 1467 | struct v4l2_subdev_frame_interval_enum fie = { | 1553 | struct v4l2_subdev_frame_interval_enum fie = { |
| 1468 | .index = fival->index, | 1554 | .index = fival->index, |
| 1469 | .width = fival->width, | 1555 | .width = fival->width, |
| 1470 | .height = fival->height, | 1556 | .height = fival->height, |
| 1471 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | 1557 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
| 1472 | }; | 1558 | }; |
| 1473 | int ret; | 1559 | int ret = -EINVAL; |
| 1560 | int i; | ||
| 1474 | 1561 | ||
| 1475 | isc_fmt = find_format_by_fourcc(isc, fival->pixel_format); | 1562 | for (i = 0; i < isc->num_user_formats; i++) |
| 1476 | if (!isc_fmt) | 1563 | if (isc->user_formats[i]->fourcc == fival->pixel_format) |
| 1477 | return -EINVAL; | 1564 | ret = 0; |
| 1478 | 1565 | ||
| 1479 | if (sensor_is_preferred(isc_fmt)) | 1566 | for (i = 0; i < ARRAY_SIZE(controller_formats); i++) |
| 1480 | fie.code = isc_fmt->mbus_code; | 1567 | if (controller_formats[i].fourcc == fival->pixel_format) |
| 1481 | else | 1568 | ret = 0; |
| 1482 | fie.code = isc->raw_fmt->mbus_code; | 1569 | |
| 1570 | if (ret) | ||
| 1571 | return ret; | ||
| 1483 | 1572 | ||
| 1484 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, | 1573 | ret = v4l2_subdev_call(isc->current_subdev->sd, pad, |
| 1485 | enum_frame_interval, NULL, &fie); | 1574 | enum_frame_interval, NULL, &fie); |
| 1486 | if (ret) | 1575 | if (ret) |
| 1487 | return ret; | 1576 | return ret; |
| 1488 | 1577 | ||
| 1578 | fie.code = isc->config.sd_format->mbus_code; | ||
| 1489 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; | 1579 | fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; |
| 1490 | fival->discrete = fie.interval; | 1580 | fival->discrete = fie.interval; |
| 1491 | 1581 | ||
| @@ -1668,7 +1758,6 @@ static void isc_awb_work(struct work_struct *w) | |||
| 1668 | struct isc_device *isc = | 1758 | struct isc_device *isc = |
| 1669 | container_of(w, struct isc_device, awb_work); | 1759 | container_of(w, struct isc_device, awb_work); |
| 1670 | struct regmap *regmap = isc->regmap; | 1760 | struct regmap *regmap = isc->regmap; |
| 1671 | struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); | ||
| 1672 | struct isc_ctrls *ctrls = &isc->ctrls; | 1761 | struct isc_ctrls *ctrls = &isc->ctrls; |
| 1673 | u32 hist_id = ctrls->hist_id; | 1762 | u32 hist_id = ctrls->hist_id; |
| 1674 | u32 baysel; | 1763 | u32 baysel; |
| @@ -1686,7 +1775,7 @@ static void isc_awb_work(struct work_struct *w) | |||
| 1686 | } | 1775 | } |
| 1687 | 1776 | ||
| 1688 | ctrls->hist_id = hist_id; | 1777 | ctrls->hist_id = hist_id; |
| 1689 | baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; | 1778 | baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; |
| 1690 | 1779 | ||
| 1691 | pm_runtime_get_sync(isc->dev); | 1780 | pm_runtime_get_sync(isc->dev); |
| 1692 | 1781 | ||
| @@ -1754,7 +1843,6 @@ static int isc_ctrl_init(struct isc_device *isc) | |||
| 1754 | return 0; | 1843 | return 0; |
| 1755 | } | 1844 | } |
| 1756 | 1845 | ||
| 1757 | |||
| 1758 | static int isc_async_bound(struct v4l2_async_notifier *notifier, | 1846 | static int isc_async_bound(struct v4l2_async_notifier *notifier, |
| 1759 | struct v4l2_subdev *subdev, | 1847 | struct v4l2_subdev *subdev, |
| 1760 | struct v4l2_async_subdev *asd) | 1848 | struct v4l2_async_subdev *asd) |
| @@ -1812,35 +1900,20 @@ static int isc_formats_init(struct isc_device *isc) | |||
| 1812 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, | 1900 | .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
| 1813 | }; | 1901 | }; |
| 1814 | 1902 | ||
| 1903 | num_fmts = 0; | ||
| 1815 | while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, | 1904 | while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, |
| 1816 | NULL, &mbus_code)) { | 1905 | NULL, &mbus_code)) { |
| 1817 | mbus_code.index++; | 1906 | mbus_code.index++; |
| 1818 | 1907 | ||
| 1819 | fmt = find_format_by_code(mbus_code.code, &i); | 1908 | fmt = find_format_by_code(mbus_code.code, &i); |
| 1820 | if ((!fmt) || (!(fmt->flags & FMT_FLAG_FROM_SENSOR))) | 1909 | if (!fmt) { |
| 1910 | v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n", | ||
| 1911 | mbus_code.code); | ||
| 1821 | continue; | 1912 | continue; |
| 1913 | } | ||
| 1822 | 1914 | ||
| 1823 | fmt->sd_support = true; | 1915 | fmt->sd_support = true; |
| 1824 | 1916 | num_fmts++; | |
| 1825 | if (fmt->flags & FMT_FLAG_RAW_FORMAT) | ||
| 1826 | isc->raw_fmt = fmt; | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | fmt = &formats_list[0]; | ||
| 1830 | for (i = 0; i < list_size; i++) { | ||
| 1831 | if (fmt->flags & FMT_FLAG_FROM_CONTROLLER) | ||
| 1832 | fmt->isc_support = true; | ||
| 1833 | |||
| 1834 | fmt++; | ||
| 1835 | } | ||
| 1836 | |||
| 1837 | fmt = &formats_list[0]; | ||
| 1838 | num_fmts = 0; | ||
| 1839 | for (i = 0; i < list_size; i++) { | ||
| 1840 | if (fmt->isc_support || fmt->sd_support) | ||
| 1841 | num_fmts++; | ||
| 1842 | |||
| 1843 | fmt++; | ||
| 1844 | } | 1917 | } |
| 1845 | 1918 | ||
| 1846 | if (!num_fmts) | 1919 | if (!num_fmts) |
| @@ -1855,9 +1928,8 @@ static int isc_formats_init(struct isc_device *isc) | |||
| 1855 | 1928 | ||
| 1856 | fmt = &formats_list[0]; | 1929 | fmt = &formats_list[0]; |
| 1857 | for (i = 0, j = 0; i < list_size; i++) { | 1930 | for (i = 0, j = 0; i < list_size; i++) { |
| 1858 | if (fmt->isc_support || fmt->sd_support) | 1931 | if (fmt->sd_support) |
| 1859 | isc->user_formats[j++] = fmt; | 1932 | isc->user_formats[j++] = fmt; |
| 1860 | |||
| 1861 | fmt++; | 1933 | fmt++; |
| 1862 | } | 1934 | } |
| 1863 | 1935 | ||
| @@ -1877,13 +1949,11 @@ static int isc_set_default_fmt(struct isc_device *isc) | |||
| 1877 | }; | 1949 | }; |
| 1878 | int ret; | 1950 | int ret; |
| 1879 | 1951 | ||
| 1880 | ret = isc_try_fmt(isc, &f, NULL, NULL); | 1952 | ret = isc_try_fmt(isc, &f, NULL); |
| 1881 | if (ret) | 1953 | if (ret) |
| 1882 | return ret; | 1954 | return ret; |
| 1883 | 1955 | ||
| 1884 | isc->current_fmt = isc->user_formats[0]; | ||
| 1885 | isc->fmt = f; | 1956 | isc->fmt = f; |
| 1886 | |||
| 1887 | return 0; | 1957 | return 0; |
| 1888 | } | 1958 | } |
| 1889 | 1959 | ||
| @@ -2084,6 +2154,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) | |||
| 2084 | if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) | 2154 | if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) |
| 2085 | subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; | 2155 | subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; |
| 2086 | 2156 | ||
| 2157 | if (v4l2_epn.bus_type == V4L2_MBUS_BT656) | ||
| 2158 | subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC | | ||
| 2159 | ISC_PFE_CFG0_CCIR656; | ||
| 2160 | |||
| 2087 | subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE; | 2161 | subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE; |
| 2088 | subdev_entity->asd->match.fwnode = | 2162 | subdev_entity->asd->match.fwnode = |
| 2089 | of_fwnode_handle(rem); | 2163 | of_fwnode_handle(rem); |
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index b4f396c2e72c..eaa86737fa04 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c | |||
| @@ -2010,6 +2010,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx) | |||
| 2010 | /* Clear decode success flag */ | 2010 | /* Clear decode success flag */ |
| 2011 | coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS); | 2011 | coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS); |
| 2012 | 2012 | ||
| 2013 | /* Clear error return value */ | ||
| 2014 | coda_write(dev, 0, CODA_RET_DEC_PIC_ERR_MB); | ||
| 2015 | |||
| 2013 | trace_coda_dec_pic_run(ctx, meta); | 2016 | trace_coda_dec_pic_run(ctx, meta); |
| 2014 | 2017 | ||
| 2015 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); | 2018 | coda_command_async(ctx, CODA_COMMAND_PIC_RUN); |
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index fa0b22fb7991..3ce58dee4422 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
| @@ -764,6 +764,7 @@ static int coda_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 764 | { | 764 | { |
| 765 | struct coda_ctx *ctx = fh_to_ctx(priv); | 765 | struct coda_ctx *ctx = fh_to_ctx(priv); |
| 766 | struct coda_q_data *q_data_src; | 766 | struct coda_q_data *q_data_src; |
| 767 | const struct coda_codec *codec; | ||
| 767 | struct v4l2_rect r; | 768 | struct v4l2_rect r; |
| 768 | int ret; | 769 | int ret; |
| 769 | 770 | ||
| @@ -784,6 +785,15 @@ static int coda_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 784 | if (ctx->inst_type != CODA_INST_ENCODER) | 785 | if (ctx->inst_type != CODA_INST_ENCODER) |
| 785 | return 0; | 786 | return 0; |
| 786 | 787 | ||
| 788 | /* Setting the coded format determines the selected codec */ | ||
| 789 | codec = coda_find_codec(ctx->dev, q_data_src->fourcc, | ||
| 790 | f->fmt.pix.pixelformat); | ||
| 791 | if (!codec) { | ||
| 792 | v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); | ||
| 793 | return -EINVAL; | ||
| 794 | } | ||
| 795 | ctx->codec = codec; | ||
| 796 | |||
| 787 | ctx->colorspace = f->fmt.pix.colorspace; | 797 | ctx->colorspace = f->fmt.pix.colorspace; |
| 788 | ctx->xfer_func = f->fmt.pix.xfer_func; | 798 | ctx->xfer_func = f->fmt.pix.xfer_func; |
| 789 | ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; | 799 | ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; |
| @@ -796,6 +806,7 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv, | |||
| 796 | struct v4l2_format *f) | 806 | struct v4l2_format *f) |
| 797 | { | 807 | { |
| 798 | struct coda_ctx *ctx = fh_to_ctx(priv); | 808 | struct coda_ctx *ctx = fh_to_ctx(priv); |
| 809 | const struct coda_codec *codec; | ||
| 799 | struct v4l2_format f_cap; | 810 | struct v4l2_format f_cap; |
| 800 | struct vb2_queue *dst_vq; | 811 | struct vb2_queue *dst_vq; |
| 801 | int ret; | 812 | int ret; |
| @@ -808,14 +819,23 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv, | |||
| 808 | if (ret) | 819 | if (ret) |
| 809 | return ret; | 820 | return ret; |
| 810 | 821 | ||
| 811 | if (ctx->inst_type != CODA_INST_DECODER) | ||
| 812 | return 0; | ||
| 813 | |||
| 814 | ctx->colorspace = f->fmt.pix.colorspace; | 822 | ctx->colorspace = f->fmt.pix.colorspace; |
| 815 | ctx->xfer_func = f->fmt.pix.xfer_func; | 823 | ctx->xfer_func = f->fmt.pix.xfer_func; |
| 816 | ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; | 824 | ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc; |
| 817 | ctx->quantization = f->fmt.pix.quantization; | 825 | ctx->quantization = f->fmt.pix.quantization; |
| 818 | 826 | ||
| 827 | if (ctx->inst_type != CODA_INST_DECODER) | ||
| 828 | return 0; | ||
| 829 | |||
| 830 | /* Setting the coded format determines the selected codec */ | ||
| 831 | codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat, | ||
| 832 | V4L2_PIX_FMT_YUV420); | ||
| 833 | if (!codec) { | ||
| 834 | v4l2_err(&ctx->dev->v4l2_dev, "failed to determine codec\n"); | ||
| 835 | return -EINVAL; | ||
| 836 | } | ||
| 837 | ctx->codec = codec; | ||
| 838 | |||
| 819 | dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | 839 | dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); |
| 820 | if (!dst_vq) | 840 | if (!dst_vq) |
| 821 | return -EINVAL; | 841 | return -EINVAL; |
| @@ -980,6 +1000,11 @@ static int coda_s_selection(struct file *file, void *fh, | |||
| 980 | static int coda_try_encoder_cmd(struct file *file, void *fh, | 1000 | static int coda_try_encoder_cmd(struct file *file, void *fh, |
| 981 | struct v4l2_encoder_cmd *ec) | 1001 | struct v4l2_encoder_cmd *ec) |
| 982 | { | 1002 | { |
| 1003 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
| 1004 | |||
| 1005 | if (ctx->inst_type != CODA_INST_ENCODER) | ||
| 1006 | return -ENOTTY; | ||
| 1007 | |||
| 983 | if (ec->cmd != V4L2_ENC_CMD_STOP) | 1008 | if (ec->cmd != V4L2_ENC_CMD_STOP) |
| 984 | return -EINVAL; | 1009 | return -EINVAL; |
| 985 | 1010 | ||
| @@ -1000,10 +1025,6 @@ static int coda_encoder_cmd(struct file *file, void *fh, | |||
| 1000 | if (ret < 0) | 1025 | if (ret < 0) |
| 1001 | return ret; | 1026 | return ret; |
| 1002 | 1027 | ||
| 1003 | /* Ignore encoder stop command silently in decoder context */ | ||
| 1004 | if (ctx->inst_type != CODA_INST_ENCODER) | ||
| 1005 | return 0; | ||
| 1006 | |||
| 1007 | /* Set the stream-end flag on this context */ | 1028 | /* Set the stream-end flag on this context */ |
| 1008 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; | 1029 | ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG; |
| 1009 | 1030 | ||
| @@ -1021,6 +1042,11 @@ static int coda_encoder_cmd(struct file *file, void *fh, | |||
| 1021 | static int coda_try_decoder_cmd(struct file *file, void *fh, | 1042 | static int coda_try_decoder_cmd(struct file *file, void *fh, |
| 1022 | struct v4l2_decoder_cmd *dc) | 1043 | struct v4l2_decoder_cmd *dc) |
| 1023 | { | 1044 | { |
| 1045 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
| 1046 | |||
| 1047 | if (ctx->inst_type != CODA_INST_DECODER) | ||
| 1048 | return -ENOTTY; | ||
| 1049 | |||
| 1024 | if (dc->cmd != V4L2_DEC_CMD_STOP) | 1050 | if (dc->cmd != V4L2_DEC_CMD_STOP) |
| 1025 | return -EINVAL; | 1051 | return -EINVAL; |
| 1026 | 1052 | ||
| @@ -1043,10 +1069,6 @@ static int coda_decoder_cmd(struct file *file, void *fh, | |||
| 1043 | if (ret < 0) | 1069 | if (ret < 0) |
| 1044 | return ret; | 1070 | return ret; |
| 1045 | 1071 | ||
| 1046 | /* Ignore decoder stop command silently in encoder context */ | ||
| 1047 | if (ctx->inst_type != CODA_INST_DECODER) | ||
| 1048 | return 0; | ||
| 1049 | |||
| 1050 | /* Set the stream-end flag on this context */ | 1072 | /* Set the stream-end flag on this context */ |
| 1051 | coda_bit_stream_end_flag(ctx); | 1073 | coda_bit_stream_end_flag(ctx); |
| 1052 | ctx->hold = false; | 1074 | ctx->hold = false; |
| @@ -1055,6 +1077,42 @@ static int coda_decoder_cmd(struct file *file, void *fh, | |||
| 1055 | return 0; | 1077 | return 0; |
| 1056 | } | 1078 | } |
| 1057 | 1079 | ||
| 1080 | static int coda_enum_framesizes(struct file *file, void *fh, | ||
| 1081 | struct v4l2_frmsizeenum *fsize) | ||
| 1082 | { | ||
| 1083 | struct coda_ctx *ctx = fh_to_ctx(fh); | ||
| 1084 | struct coda_q_data *q_data_dst; | ||
| 1085 | const struct coda_codec *codec; | ||
| 1086 | |||
| 1087 | if (ctx->inst_type != CODA_INST_ENCODER) | ||
| 1088 | return -ENOTTY; | ||
| 1089 | |||
| 1090 | if (fsize->index) | ||
| 1091 | return -EINVAL; | ||
| 1092 | |||
| 1093 | if (coda_format_normalize_yuv(fsize->pixel_format) == | ||
| 1094 | V4L2_PIX_FMT_YUV420) { | ||
| 1095 | q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
| 1096 | codec = coda_find_codec(ctx->dev, fsize->pixel_format, | ||
| 1097 | q_data_dst->fourcc); | ||
| 1098 | } else { | ||
| 1099 | codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, | ||
| 1100 | fsize->pixel_format); | ||
| 1101 | } | ||
| 1102 | if (!codec) | ||
| 1103 | return -EINVAL; | ||
| 1104 | |||
| 1105 | fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | ||
| 1106 | fsize->stepwise.min_width = MIN_W; | ||
| 1107 | fsize->stepwise.max_width = codec->max_w; | ||
| 1108 | fsize->stepwise.step_width = 1; | ||
| 1109 | fsize->stepwise.min_height = MIN_H; | ||
| 1110 | fsize->stepwise.max_height = codec->max_h; | ||
| 1111 | fsize->stepwise.step_height = 1; | ||
| 1112 | |||
| 1113 | return 0; | ||
| 1114 | } | ||
| 1115 | |||
| 1058 | static int coda_enum_frameintervals(struct file *file, void *fh, | 1116 | static int coda_enum_frameintervals(struct file *file, void *fh, |
| 1059 | struct v4l2_frmivalenum *f) | 1117 | struct v4l2_frmivalenum *f) |
| 1060 | { | 1118 | { |
| @@ -1233,6 +1291,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = { | |||
| 1233 | .vidioc_g_parm = coda_g_parm, | 1291 | .vidioc_g_parm = coda_g_parm, |
| 1234 | .vidioc_s_parm = coda_s_parm, | 1292 | .vidioc_s_parm = coda_s_parm, |
| 1235 | 1293 | ||
| 1294 | .vidioc_enum_framesizes = coda_enum_framesizes, | ||
| 1236 | .vidioc_enum_frameintervals = coda_enum_frameintervals, | 1295 | .vidioc_enum_frameintervals = coda_enum_frameintervals, |
| 1237 | 1296 | ||
| 1238 | .vidioc_subscribe_event = coda_subscribe_event, | 1297 | .vidioc_subscribe_event = coda_subscribe_event, |
| @@ -1442,6 +1501,9 @@ static int coda_queue_setup(struct vb2_queue *vq, | |||
| 1442 | q_data = get_q_data(ctx, vq->type); | 1501 | q_data = get_q_data(ctx, vq->type); |
| 1443 | size = q_data->sizeimage; | 1502 | size = q_data->sizeimage; |
| 1444 | 1503 | ||
| 1504 | if (*nplanes) | ||
| 1505 | return sizes[0] < size ? -EINVAL : 0; | ||
| 1506 | |||
| 1445 | *nplanes = 1; | 1507 | *nplanes = 1; |
| 1446 | sizes[0] = size; | 1508 | sizes[0] = size; |
| 1447 | 1509 | ||
| @@ -1680,14 +1742,6 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count) | |||
| 1680 | 1742 | ||
| 1681 | ctx->gopcounter = ctx->params.gop_size - 1; | 1743 | ctx->gopcounter = ctx->params.gop_size - 1; |
| 1682 | 1744 | ||
| 1683 | ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, | ||
| 1684 | q_data_dst->fourcc); | ||
| 1685 | if (!ctx->codec) { | ||
| 1686 | v4l2_err(v4l2_dev, "couldn't tell instance type.\n"); | ||
| 1687 | ret = -EINVAL; | ||
| 1688 | goto err; | ||
| 1689 | } | ||
| 1690 | |||
| 1691 | if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) | 1745 | if (q_data_dst->fourcc == V4L2_PIX_FMT_JPEG) |
| 1692 | ctx->params.gop_size = 1; | 1746 | ctx->params.gop_size = 1; |
| 1693 | ctx->gopcounter = ctx->params.gop_size - 1; | 1747 | ctx->gopcounter = ctx->params.gop_size - 1; |
| @@ -2015,7 +2069,6 @@ static void coda_jpeg_encode_ctrls(struct coda_ctx *ctx) | |||
| 2015 | 2069 | ||
| 2016 | static void coda_decode_ctrls(struct coda_ctx *ctx) | 2070 | static void coda_decode_ctrls(struct coda_ctx *ctx) |
| 2017 | { | 2071 | { |
| 2018 | u64 mask; | ||
| 2019 | u8 max; | 2072 | u8 max; |
| 2020 | 2073 | ||
| 2021 | ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, | 2074 | ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, |
| @@ -2029,27 +2082,14 @@ static void coda_decode_ctrls(struct coda_ctx *ctx) | |||
| 2029 | ctx->h264_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 2082 | ctx->h264_profile_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
| 2030 | 2083 | ||
| 2031 | if (ctx->dev->devtype->product == CODA_HX4 || | 2084 | if (ctx->dev->devtype->product == CODA_HX4 || |
| 2032 | ctx->dev->devtype->product == CODA_7541) { | 2085 | ctx->dev->devtype->product == CODA_7541) |
| 2033 | max = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; | 2086 | max = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; |
| 2034 | mask = ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | | 2087 | else if (ctx->dev->devtype->product == CODA_960) |
| 2035 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | | ||
| 2036 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | | ||
| 2037 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | | ||
| 2038 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0)); | ||
| 2039 | } else if (ctx->dev->devtype->product == CODA_960) { | ||
| 2040 | max = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; | 2088 | max = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; |
| 2041 | mask = ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | | 2089 | else |
| 2042 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | | ||
| 2043 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | | ||
| 2044 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | | ||
| 2045 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | | ||
| 2046 | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1)); | ||
| 2047 | } else { | ||
| 2048 | return; | 2090 | return; |
| 2049 | } | ||
| 2050 | ctx->h264_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, | 2091 | ctx->h264_level_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, |
| 2051 | &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, max, mask, | 2092 | &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, max, 0, max); |
| 2052 | max); | ||
| 2053 | if (ctx->h264_level_ctrl) | 2093 | if (ctx->h264_level_ctrl) |
| 2054 | ctx->h264_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 2094 | ctx->h264_level_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
| 2055 | } | 2095 | } |
| @@ -2063,11 +2103,17 @@ static int coda_ctrls_setup(struct coda_ctx *ctx) | |||
| 2063 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | 2103 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, |
| 2064 | V4L2_CID_VFLIP, 0, 1, 1, 0); | 2104 | V4L2_CID_VFLIP, 0, 1, 1, 0); |
| 2065 | if (ctx->inst_type == CODA_INST_ENCODER) { | 2105 | if (ctx->inst_type == CODA_INST_ENCODER) { |
| 2106 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | ||
| 2107 | V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, | ||
| 2108 | 1, 1, 1, 1); | ||
| 2066 | if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) | 2109 | if (ctx->cvd->dst_formats[0] == V4L2_PIX_FMT_JPEG) |
| 2067 | coda_jpeg_encode_ctrls(ctx); | 2110 | coda_jpeg_encode_ctrls(ctx); |
| 2068 | else | 2111 | else |
| 2069 | coda_encode_ctrls(ctx); | 2112 | coda_encode_ctrls(ctx); |
| 2070 | } else { | 2113 | } else { |
| 2114 | v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, | ||
| 2115 | V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, | ||
| 2116 | 1, 1, 1, 1); | ||
| 2071 | if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264) | 2117 | if (ctx->cvd->src_formats[0] == V4L2_PIX_FMT_H264) |
| 2072 | coda_decode_ctrls(ctx); | 2118 | coda_decode_ctrls(ctx); |
| 2073 | } | 2119 | } |
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c index 7bc4d8a9af28..068df9888dbf 100644 --- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c | |||
| @@ -236,6 +236,7 @@ static int cros_ec_cec_get_notifier(struct device *dev, | |||
| 236 | return -EPROBE_DEFER; | 236 | return -EPROBE_DEFER; |
| 237 | 237 | ||
| 238 | *notify = cec_notifier_get_conn(d, m->conn); | 238 | *notify = cec_notifier_get_conn(d, m->conn); |
| 239 | put_device(d); | ||
| 239 | return 0; | 240 | return 0; |
| 240 | } | 241 | } |
| 241 | } | 242 | } |
diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index 47cecd10eb9f..2dee9af6d413 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c | |||
| @@ -884,9 +884,7 @@ static int isif_set_hw_if_params(struct vpfe_hw_if_param *params) | |||
| 884 | static int isif_config_ycbcr(void) | 884 | static int isif_config_ycbcr(void) |
| 885 | { | 885 | { |
| 886 | struct isif_ycbcr_config *params = &isif_cfg.ycbcr; | 886 | struct isif_ycbcr_config *params = &isif_cfg.ycbcr; |
| 887 | struct vpss_pg_frame_size frame_size; | ||
| 888 | u32 modeset = 0, ccdcfg = 0; | 887 | u32 modeset = 0, ccdcfg = 0; |
| 889 | struct vpss_sync_pol sync; | ||
| 890 | 888 | ||
| 891 | dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr..."); | 889 | dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr..."); |
| 892 | 890 | ||
| @@ -974,13 +972,6 @@ static int isif_config_ycbcr(void) | |||
| 974 | /* two fields are interleaved in memory */ | 972 | /* two fields are interleaved in memory */ |
| 975 | regw(0x00000249, SDOFST); | 973 | regw(0x00000249, SDOFST); |
| 976 | 974 | ||
| 977 | /* Setup test pattern if enabled */ | ||
| 978 | if (isif_cfg.bayer.config_params.test_pat_gen) { | ||
| 979 | sync.ccdpg_hdpol = params->hd_pol; | ||
| 980 | sync.ccdpg_vdpol = params->vd_pol; | ||
| 981 | dm365_vpss_set_sync_pol(sync); | ||
| 982 | dm365_vpss_set_pg_frame_size(frame_size); | ||
| 983 | } | ||
| 984 | return 0; | 975 | return 0; |
| 985 | } | 976 | } |
| 986 | 977 | ||
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 26dadbba930f..1e3a13830544 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c | |||
| @@ -1759,7 +1759,7 @@ static int vpfe_probe(struct platform_device *pdev) | |||
| 1759 | 1759 | ||
| 1760 | mutex_lock(&ccdc_lock); | 1760 | mutex_lock(&ccdc_lock); |
| 1761 | 1761 | ||
| 1762 | strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32); | 1762 | strscpy(ccdc_cfg->name, vpfe_cfg->ccdc, sizeof(ccdc_cfg->name)); |
| 1763 | /* Get VINT0 irq resource */ | 1763 | /* Get VINT0 irq resource */ |
| 1764 | res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1764 | res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 1765 | if (!res1) { | 1765 | if (!res1) { |
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 6216b7ac6875..b5aacb0fb96b 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
| @@ -1254,7 +1254,8 @@ static int vpif_s_dv_timings(struct file *file, void *priv, | |||
| 1254 | } else { | 1254 | } else { |
| 1255 | std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); | 1255 | std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); |
| 1256 | } | 1256 | } |
| 1257 | strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME); | 1257 | strscpy(std_info->name, "Custom timings BT656/1120", |
| 1258 | sizeof(std_info->name)); | ||
| 1258 | std_info->width = bt->width; | 1259 | std_info->width = bt->width; |
| 1259 | std_info->height = bt->height; | 1260 | std_info->height = bt->height; |
| 1260 | std_info->frm_fmt = bt->interlaced ? 0 : 1; | 1261 | std_info->frm_fmt = bt->interlaced ? 0 : 1; |
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index f4b4f2a1dfc0..a69897c68a50 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c | |||
| @@ -987,8 +987,8 @@ static int vpif_s_dv_timings(struct file *file, void *priv, | |||
| 987 | } else { | 987 | } else { |
| 988 | std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); | 988 | std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); |
| 989 | } | 989 | } |
| 990 | strncpy(std_info->name, "Custom timings BT656/1120", | 990 | strscpy(std_info->name, "Custom timings BT656/1120", |
| 991 | VPIF_MAX_NAME); | 991 | sizeof(std_info->name)); |
| 992 | std_info->width = bt->width; | 992 | std_info->width = bt->width; |
| 993 | std_info->height = bt->height; | 993 | std_info->height = bt->height; |
| 994 | std_info->frm_fmt = bt->interlaced ? 0 : 1; | 994 | std_info->frm_fmt = bt->interlaced ? 0 : 1; |
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 3e9fcf4f8a13..de4af0357a3c 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c | |||
| @@ -742,7 +742,7 @@ static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv, | |||
| 742 | f->index); | 742 | f->index); |
| 743 | if (!fmt) | 743 | if (!fmt) |
| 744 | return -EINVAL; | 744 | return -EINVAL; |
| 745 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 745 | strscpy(f->description, fmt->name, sizeof(f->description)); |
| 746 | f->pixelformat = fmt->fourcc; | 746 | f->pixelformat = fmt->fourcc; |
| 747 | if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) | 747 | if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) |
| 748 | f->flags |= V4L2_FMT_FLAG_COMPRESSED; | 748 | f->flags |= V4L2_FMT_FLAG_COMPRESSED; |
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 61c8177409cf..1bea1ce4091e 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c | |||
| @@ -252,7 +252,7 @@ static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv, | |||
| 252 | if (!fmt) | 252 | if (!fmt) |
| 253 | return -EINVAL; | 253 | return -EINVAL; |
| 254 | 254 | ||
| 255 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 255 | strscpy(f->description, fmt->name, sizeof(f->description)); |
| 256 | f->pixelformat = fmt->fourcc; | 256 | f->pixelformat = fmt->fourcc; |
| 257 | return 0; | 257 | return 0; |
| 258 | } | 258 | } |
diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c index 0bcfc5aa8f3d..8e7ef23b9a7e 100644 --- a/drivers/media/platform/imx-pxp.c +++ b/drivers/media/platform/imx-pxp.c | |||
| @@ -1025,8 +1025,8 @@ static irqreturn_t pxp_irq_handler(int irq, void *dev_id) | |||
| 1025 | static int pxp_querycap(struct file *file, void *priv, | 1025 | static int pxp_querycap(struct file *file, void *priv, |
| 1026 | struct v4l2_capability *cap) | 1026 | struct v4l2_capability *cap) |
| 1027 | { | 1027 | { |
| 1028 | strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); | 1028 | strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); |
| 1029 | strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); | 1029 | strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); |
| 1030 | snprintf(cap->bus_info, sizeof(cap->bus_info), | 1030 | snprintf(cap->bus_info, sizeof(cap->bus_info), |
| 1031 | "platform:%s", MEM2MEM_NAME); | 1031 | "platform:%s", MEM2MEM_NAME); |
| 1032 | return 0; | 1032 | return 0; |
diff --git a/drivers/media/platform/marvell-ccic/Kconfig b/drivers/media/platform/marvell-ccic/Kconfig index cf12e077203a..cd88e2eed749 100644 --- a/drivers/media/platform/marvell-ccic/Kconfig +++ b/drivers/media/platform/marvell-ccic/Kconfig | |||
| @@ -5,7 +5,7 @@ config VIDEO_CAFE_CCIC | |||
| 5 | select VIDEOBUF2_VMALLOC | 5 | select VIDEOBUF2_VMALLOC |
| 6 | select VIDEOBUF2_DMA_CONTIG | 6 | select VIDEOBUF2_DMA_CONTIG |
| 7 | select VIDEOBUF2_DMA_SG | 7 | select VIDEOBUF2_DMA_SG |
| 8 | ---help--- | 8 | help |
| 9 | This is a video4linux2 driver for the Marvell 88ALP01 integrated | 9 | This is a video4linux2 driver for the Marvell 88ALP01 integrated |
| 10 | CMOS camera controller. This is the controller found on first- | 10 | CMOS camera controller. This is the controller found on first- |
| 11 | generation OLPC systems. | 11 | generation OLPC systems. |
| @@ -19,7 +19,7 @@ config VIDEO_MMP_CAMERA | |||
| 19 | select VIDEOBUF2_VMALLOC | 19 | select VIDEOBUF2_VMALLOC |
| 20 | select VIDEOBUF2_DMA_CONTIG | 20 | select VIDEOBUF2_DMA_CONTIG |
| 21 | select VIDEOBUF2_DMA_SG | 21 | select VIDEOBUF2_DMA_SG |
| 22 | ---help--- | 22 | help |
| 23 | This is a Video4Linux2 driver for the integrated camera | 23 | This is a Video4Linux2 driver for the integrated camera |
| 24 | controller found on Marvell Armada 610 application | 24 | controller found on Marvell Armada 610 application |
| 25 | processors (and likely beyond). This is the controller found | 25 | processors (and likely beyond). This is the controller found |
diff --git a/drivers/media/platform/meson/Makefile b/drivers/media/platform/meson/Makefile index 597beb8f34d1..f611c23c3718 100644 --- a/drivers/media/platform/meson/Makefile +++ b/drivers/media/platform/meson/Makefile | |||
| @@ -1 +1,2 @@ | |||
| 1 | obj-$(CONFIG_VIDEO_MESON_AO_CEC) += ao-cec.o | 1 | obj-$(CONFIG_VIDEO_MESON_AO_CEC) += ao-cec.o |
| 2 | obj-$(CONFIG_VIDEO_MESON_G12A_AO_CEC) += ao-cec-g12a.o | ||
diff --git a/drivers/media/platform/meson/ao-cec-g12a.c b/drivers/media/platform/meson/ao-cec-g12a.c new file mode 100644 index 000000000000..3620a1e310f5 --- /dev/null +++ b/drivers/media/platform/meson/ao-cec-g12a.c | |||
| @@ -0,0 +1,779 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Driver for Amlogic Meson AO CEC G12A Controller | ||
| 4 | * | ||
| 5 | * Copyright (C) 2017 Amlogic, Inc. All rights reserved | ||
| 6 | * Copyright (C) 2019 BayLibre, SAS | ||
| 7 | * Author: Neil Armstrong <narmstrong@baylibre.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/bitfield.h> | ||
| 11 | #include <linux/clk.h> | ||
| 12 | #include <linux/device.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/of_platform.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/types.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/reset.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/regmap.h> | ||
| 25 | #include <media/cec.h> | ||
| 26 | #include <media/cec-notifier.h> | ||
| 27 | #include <linux/clk-provider.h> | ||
| 28 | |||
| 29 | /* CEC Registers */ | ||
| 30 | |||
| 31 | #define CECB_CLK_CNTL_REG0 0x00 | ||
| 32 | |||
| 33 | #define CECB_CLK_CNTL_N1 GENMASK(11, 0) | ||
| 34 | #define CECB_CLK_CNTL_N2 GENMASK(23, 12) | ||
| 35 | #define CECB_CLK_CNTL_DUAL_EN BIT(28) | ||
| 36 | #define CECB_CLK_CNTL_OUTPUT_EN BIT(30) | ||
| 37 | #define CECB_CLK_CNTL_INPUT_EN BIT(31) | ||
| 38 | |||
| 39 | #define CECB_CLK_CNTL_REG1 0x04 | ||
| 40 | |||
| 41 | #define CECB_CLK_CNTL_M1 GENMASK(11, 0) | ||
| 42 | #define CECB_CLK_CNTL_M2 GENMASK(23, 12) | ||
| 43 | #define CECB_CLK_CNTL_BYPASS_EN BIT(24) | ||
| 44 | |||
| 45 | /* | ||
| 46 | * [14:12] Filter_del. For glitch-filtering CEC line, ignore signal | ||
| 47 | * change pulse width < filter_del * T(filter_tick) * 3. | ||
| 48 | * [9:8] Filter_tick_sel: Select which periodical pulse for | ||
| 49 | * glitch-filtering CEC line signal. | ||
| 50 | * - 0=Use T(xtal)*3 = 125ns; | ||
| 51 | * - 1=Use once-per-1us pulse; | ||
| 52 | * - 2=Use once-per-10us pulse; | ||
| 53 | * - 3=Use once-per-100us pulse. | ||
| 54 | * [3] Sysclk_en. 0=Disable system clock; 1=Enable system clock. | ||
| 55 | * [2:1] cntl_clk | ||
| 56 | * - 0 = Disable clk (Power-off mode) | ||
| 57 | * - 1 = Enable gated clock (Normal mode) | ||
| 58 | * - 2 = Enable free-run clk (Debug mode) | ||
| 59 | * [0] SW_RESET 1=Apply reset; 0=No reset. | ||
| 60 | */ | ||
| 61 | #define CECB_GEN_CNTL_REG 0x08 | ||
| 62 | |||
| 63 | #define CECB_GEN_CNTL_RESET BIT(0) | ||
| 64 | #define CECB_GEN_CNTL_CLK_DISABLE 0 | ||
| 65 | #define CECB_GEN_CNTL_CLK_ENABLE 1 | ||
| 66 | #define CECB_GEN_CNTL_CLK_ENABLE_DBG 2 | ||
| 67 | #define CECB_GEN_CNTL_CLK_CTRL_MASK GENMASK(2, 1) | ||
| 68 | #define CECB_GEN_CNTL_SYS_CLK_EN BIT(3) | ||
| 69 | #define CECB_GEN_CNTL_FILTER_TICK_125NS 0 | ||
| 70 | #define CECB_GEN_CNTL_FILTER_TICK_1US 1 | ||
| 71 | #define CECB_GEN_CNTL_FILTER_TICK_10US 2 | ||
| 72 | #define CECB_GEN_CNTL_FILTER_TICK_100US 3 | ||
| 73 | #define CECB_GEN_CNTL_FILTER_TICK_SEL GENMASK(9, 8) | ||
| 74 | #define CECB_GEN_CNTL_FILTER_DEL GENMASK(14, 12) | ||
| 75 | |||
| 76 | /* | ||
| 77 | * [7:0] cec_reg_addr | ||
| 78 | * [15:8] cec_reg_wrdata | ||
| 79 | * [16] cec_reg_wr | ||
| 80 | * - 0 = Read | ||
| 81 | * - 1 = Write | ||
| 82 | * [31:24] cec_reg_rddata | ||
| 83 | */ | ||
| 84 | #define CECB_RW_REG 0x0c | ||
| 85 | |||
| 86 | #define CECB_RW_ADDR GENMASK(7, 0) | ||
| 87 | #define CECB_RW_WR_DATA GENMASK(15, 8) | ||
| 88 | #define CECB_RW_WRITE_EN BIT(16) | ||
| 89 | #define CECB_RW_BUS_BUSY BIT(23) | ||
| 90 | #define CECB_RW_RD_DATA GENMASK(31, 24) | ||
| 91 | |||
| 92 | /* | ||
| 93 | * [0] DONE Interrupt | ||
| 94 | * [1] End Of Message Interrupt | ||
| 95 | * [2] Not Acknowlegde Interrupt | ||
| 96 | * [3] Arbitration Loss Interrupt | ||
| 97 | * [4] Initiator Error Interrupt | ||
| 98 | * [5] Follower Error Interrupt | ||
| 99 | * [6] Wake-Up Interrupt | ||
| 100 | */ | ||
| 101 | #define CECB_INTR_MASKN_REG 0x10 | ||
| 102 | #define CECB_INTR_CLR_REG 0x14 | ||
| 103 | #define CECB_INTR_STAT_REG 0x18 | ||
| 104 | |||
| 105 | #define CECB_INTR_DONE BIT(0) | ||
| 106 | #define CECB_INTR_EOM BIT(1) | ||
| 107 | #define CECB_INTR_NACK BIT(2) | ||
| 108 | #define CECB_INTR_ARB_LOSS BIT(3) | ||
| 109 | #define CECB_INTR_INITIATOR_ERR BIT(4) | ||
| 110 | #define CECB_INTR_FOLLOWER_ERR BIT(5) | ||
| 111 | #define CECB_INTR_WAKE_UP BIT(6) | ||
| 112 | |||
| 113 | /* CEC Commands */ | ||
| 114 | |||
| 115 | #define CECB_CTRL 0x00 | ||
| 116 | |||
| 117 | #define CECB_CTRL_SEND BIT(0) | ||
| 118 | #define CECB_CTRL_TYPE GENMASK(2, 1) | ||
| 119 | #define CECB_CTRL_TYPE_RETRY 0 | ||
| 120 | #define CECB_CTRL_TYPE_NEW 1 | ||
| 121 | #define CECB_CTRL_TYPE_NEXT 2 | ||
| 122 | |||
| 123 | #define CECB_CTRL2 0x01 | ||
| 124 | #define CECB_INTR_MASK 0x02 | ||
| 125 | #define CECB_LADD_LOW 0x05 | ||
| 126 | #define CECB_LADD_HIGH 0x06 | ||
| 127 | #define CECB_TX_CNT 0x07 | ||
| 128 | #define CECB_RX_CNT 0x08 | ||
| 129 | #define CECB_STAT0 0x09 | ||
| 130 | #define CECB_TX_DATA00 0x10 | ||
| 131 | #define CECB_TX_DATA01 0x11 | ||
| 132 | #define CECB_TX_DATA02 0x12 | ||
| 133 | #define CECB_TX_DATA03 0x13 | ||
| 134 | #define CECB_TX_DATA04 0x14 | ||
| 135 | #define CECB_TX_DATA05 0x15 | ||
| 136 | #define CECB_TX_DATA06 0x16 | ||
| 137 | #define CECB_TX_DATA07 0x17 | ||
| 138 | #define CECB_TX_DATA08 0x18 | ||
| 139 | #define CECB_TX_DATA09 0x19 | ||
| 140 | #define CECB_TX_DATA10 0x1A | ||
| 141 | #define CECB_TX_DATA11 0x1B | ||
| 142 | #define CECB_TX_DATA12 0x1C | ||
| 143 | #define CECB_TX_DATA13 0x1D | ||
| 144 | #define CECB_TX_DATA14 0x1E | ||
| 145 | #define CECB_TX_DATA15 0x1F | ||
| 146 | #define CECB_RX_DATA00 0x20 | ||
| 147 | #define CECB_RX_DATA01 0x21 | ||
| 148 | #define CECB_RX_DATA02 0x22 | ||
| 149 | #define CECB_RX_DATA03 0x23 | ||
| 150 | #define CECB_RX_DATA04 0x24 | ||
| 151 | #define CECB_RX_DATA05 0x25 | ||
| 152 | #define CECB_RX_DATA06 0x26 | ||
| 153 | #define CECB_RX_DATA07 0x27 | ||
| 154 | #define CECB_RX_DATA08 0x28 | ||
| 155 | #define CECB_RX_DATA09 0x29 | ||
| 156 | #define CECB_RX_DATA10 0x2A | ||
| 157 | #define CECB_RX_DATA11 0x2B | ||
| 158 | #define CECB_RX_DATA12 0x2C | ||
| 159 | #define CECB_RX_DATA13 0x2D | ||
| 160 | #define CECB_RX_DATA14 0x2E | ||
| 161 | #define CECB_RX_DATA15 0x2F | ||
| 162 | #define CECB_LOCK_BUF 0x30 | ||
| 163 | |||
| 164 | #define CECB_LOCK_BUF_EN BIT(0) | ||
| 165 | |||
| 166 | #define CECB_WAKEUPCTRL 0x31 | ||
| 167 | |||
| 168 | struct meson_ao_cec_g12a_device { | ||
| 169 | struct platform_device *pdev; | ||
| 170 | struct regmap *regmap; | ||
| 171 | struct regmap *regmap_cec; | ||
| 172 | spinlock_t cec_reg_lock; | ||
| 173 | struct cec_notifier *notify; | ||
| 174 | struct cec_adapter *adap; | ||
| 175 | struct cec_msg rx_msg; | ||
| 176 | struct clk *oscin; | ||
| 177 | struct clk *core; | ||
| 178 | }; | ||
| 179 | |||
| 180 | static const struct regmap_config meson_ao_cec_g12a_regmap_conf = { | ||
| 181 | .reg_bits = 8, | ||
| 182 | .val_bits = 32, | ||
| 183 | .reg_stride = 4, | ||
| 184 | .max_register = CECB_INTR_STAT_REG, | ||
| 185 | }; | ||
| 186 | |||
| 187 | /* | ||
| 188 | * The AO-CECB embeds a dual/divider to generate a more precise | ||
| 189 | * 32,768KHz clock for CEC core clock. | ||
| 190 | * ______ ______ | ||
| 191 | * | | | | | ||
| 192 | * ______ | Div1 |-| Cnt1 | ______ | ||
| 193 | * | | /|______| |______|\ | | | ||
| 194 | * Xtal-->| Gate |---| ______ ______ X-X--| Gate |--> | ||
| 195 | * |______| | \| | | |/ | |______| | ||
| 196 | * | | Div2 |-| Cnt2 | | | ||
| 197 | * | |______| |______| | | ||
| 198 | * |_______________________| | ||
| 199 | * | ||
| 200 | * The dividing can be switched to single or dual, with a counter | ||
| 201 | * for each divider to set when the switching is done. | ||
| 202 | * The entire dividing mechanism can be also bypassed. | ||
| 203 | */ | ||
| 204 | |||
| 205 | struct meson_ao_cec_g12a_dualdiv_clk { | ||
| 206 | struct clk_hw hw; | ||
| 207 | struct regmap *regmap; | ||
| 208 | }; | ||
| 209 | |||
| 210 | #define hw_to_meson_ao_cec_g12a_dualdiv_clk(_hw) \ | ||
| 211 | container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw) \ | ||
| 212 | |||
| 213 | static unsigned long | ||
| 214 | meson_ao_cec_g12a_dualdiv_clk_recalc_rate(struct clk_hw *hw, | ||
| 215 | unsigned long parent_rate) | ||
| 216 | { | ||
| 217 | struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = | ||
| 218 | hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); | ||
| 219 | unsigned long n1; | ||
| 220 | u32 reg0, reg1; | ||
| 221 | |||
| 222 | regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, ®0); | ||
| 223 | regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, ®1); | ||
| 224 | |||
| 225 | if (reg1 & CECB_CLK_CNTL_BYPASS_EN) | ||
| 226 | return parent_rate; | ||
| 227 | |||
| 228 | if (reg0 & CECB_CLK_CNTL_DUAL_EN) { | ||
| 229 | unsigned long n2, m1, m2, f1, f2, p1, p2; | ||
| 230 | |||
| 231 | n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1; | ||
| 232 | n2 = FIELD_GET(CECB_CLK_CNTL_N2, reg0) + 1; | ||
| 233 | |||
| 234 | m1 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1; | ||
| 235 | m2 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1; | ||
| 236 | |||
| 237 | f1 = DIV_ROUND_CLOSEST(parent_rate, n1); | ||
| 238 | f2 = DIV_ROUND_CLOSEST(parent_rate, n2); | ||
| 239 | |||
| 240 | p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2)); | ||
| 241 | p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2)); | ||
| 242 | |||
| 243 | return DIV_ROUND_UP(100000000, p1 + p2); | ||
| 244 | } | ||
| 245 | |||
| 246 | n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1; | ||
| 247 | |||
| 248 | return DIV_ROUND_CLOSEST(parent_rate, n1); | ||
| 249 | } | ||
| 250 | |||
| 251 | static int meson_ao_cec_g12a_dualdiv_clk_enable(struct clk_hw *hw) | ||
| 252 | { | ||
| 253 | struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = | ||
| 254 | hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); | ||
| 255 | |||
| 256 | |||
| 257 | /* Disable Input & Output */ | ||
| 258 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 259 | CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, | ||
| 260 | 0); | ||
| 261 | |||
| 262 | /* Set N1 & N2 */ | ||
| 263 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 264 | CECB_CLK_CNTL_N1, | ||
| 265 | FIELD_PREP(CECB_CLK_CNTL_N1, 733 - 1)); | ||
| 266 | |||
| 267 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 268 | CECB_CLK_CNTL_N2, | ||
| 269 | FIELD_PREP(CECB_CLK_CNTL_N2, 732 - 1)); | ||
| 270 | |||
| 271 | /* Set M1 & M2 */ | ||
| 272 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, | ||
| 273 | CECB_CLK_CNTL_M1, | ||
| 274 | FIELD_PREP(CECB_CLK_CNTL_M1, 8 - 1)); | ||
| 275 | |||
| 276 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, | ||
| 277 | CECB_CLK_CNTL_M2, | ||
| 278 | FIELD_PREP(CECB_CLK_CNTL_M2, 11 - 1)); | ||
| 279 | |||
| 280 | /* Enable Dual divisor */ | ||
| 281 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 282 | CECB_CLK_CNTL_DUAL_EN, CECB_CLK_CNTL_DUAL_EN); | ||
| 283 | |||
| 284 | /* Disable divisor bypass */ | ||
| 285 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1, | ||
| 286 | CECB_CLK_CNTL_BYPASS_EN, 0); | ||
| 287 | |||
| 288 | /* Enable Input & Output */ | ||
| 289 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 290 | CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, | ||
| 291 | CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN); | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void meson_ao_cec_g12a_dualdiv_clk_disable(struct clk_hw *hw) | ||
| 297 | { | ||
| 298 | struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = | ||
| 299 | hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); | ||
| 300 | |||
| 301 | regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, | ||
| 302 | CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN, | ||
| 303 | 0); | ||
| 304 | } | ||
| 305 | |||
| 306 | static int meson_ao_cec_g12a_dualdiv_clk_is_enabled(struct clk_hw *hw) | ||
| 307 | { | ||
| 308 | struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk = | ||
| 309 | hw_to_meson_ao_cec_g12a_dualdiv_clk(hw); | ||
| 310 | int val; | ||
| 311 | |||
| 312 | regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &val); | ||
| 313 | |||
| 314 | return !!(val & (CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN)); | ||
| 315 | } | ||
| 316 | |||
| 317 | static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = { | ||
| 318 | .recalc_rate = meson_ao_cec_g12a_dualdiv_clk_recalc_rate, | ||
| 319 | .is_enabled = meson_ao_cec_g12a_dualdiv_clk_is_enabled, | ||
| 320 | .enable = meson_ao_cec_g12a_dualdiv_clk_enable, | ||
| 321 | .disable = meson_ao_cec_g12a_dualdiv_clk_disable, | ||
| 322 | }; | ||
| 323 | |||
| 324 | static int meson_ao_cec_g12a_setup_clk(struct meson_ao_cec_g12a_device *ao_cec) | ||
| 325 | { | ||
| 326 | struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk; | ||
| 327 | struct device *dev = &ao_cec->pdev->dev; | ||
| 328 | struct clk_init_data init; | ||
| 329 | const char *parent_name; | ||
| 330 | struct clk *clk; | ||
| 331 | char *name; | ||
| 332 | |||
| 333 | dualdiv_clk = devm_kzalloc(dev, sizeof(*dualdiv_clk), GFP_KERNEL); | ||
| 334 | if (!dualdiv_clk) | ||
| 335 | return -ENOMEM; | ||
| 336 | |||
| 337 | name = kasprintf(GFP_KERNEL, "%s#dualdiv_clk", dev_name(dev)); | ||
| 338 | if (!name) | ||
| 339 | return -ENOMEM; | ||
| 340 | |||
| 341 | parent_name = __clk_get_name(ao_cec->oscin); | ||
| 342 | |||
| 343 | init.name = name; | ||
| 344 | init.ops = &meson_ao_cec_g12a_dualdiv_clk_ops; | ||
| 345 | init.flags = 0; | ||
| 346 | init.parent_names = &parent_name; | ||
| 347 | init.num_parents = 1; | ||
| 348 | dualdiv_clk->regmap = ao_cec->regmap; | ||
| 349 | dualdiv_clk->hw.init = &init; | ||
| 350 | |||
| 351 | clk = devm_clk_register(dev, &dualdiv_clk->hw); | ||
| 352 | kfree(name); | ||
| 353 | if (IS_ERR(clk)) { | ||
| 354 | dev_err(dev, "failed to register clock\n"); | ||
| 355 | return PTR_ERR(clk); | ||
| 356 | } | ||
| 357 | |||
| 358 | ao_cec->core = clk; | ||
| 359 | |||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static int meson_ao_cec_g12a_read(void *context, unsigned int addr, | ||
| 364 | unsigned int *data) | ||
| 365 | { | ||
| 366 | struct meson_ao_cec_g12a_device *ao_cec = context; | ||
| 367 | u32 reg = FIELD_PREP(CECB_RW_ADDR, addr); | ||
| 368 | unsigned long flags; | ||
| 369 | int ret = 0; | ||
| 370 | |||
| 371 | spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); | ||
| 372 | |||
| 373 | ret = regmap_write(ao_cec->regmap, CECB_RW_REG, reg); | ||
| 374 | if (ret) | ||
| 375 | goto read_out; | ||
| 376 | |||
| 377 | ret = regmap_read_poll_timeout(ao_cec->regmap, CECB_RW_REG, reg, | ||
| 378 | !(reg & CECB_RW_BUS_BUSY), | ||
| 379 | 5, 1000); | ||
| 380 | if (ret) | ||
| 381 | goto read_out; | ||
| 382 | |||
| 383 | ret = regmap_read(ao_cec->regmap, CECB_RW_REG, ®); | ||
| 384 | |||
| 385 | *data = FIELD_GET(CECB_RW_RD_DATA, reg); | ||
| 386 | |||
| 387 | read_out: | ||
| 388 | spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); | ||
| 389 | |||
| 390 | return ret; | ||
| 391 | } | ||
| 392 | |||
| 393 | static int meson_ao_cec_g12a_write(void *context, unsigned int addr, | ||
| 394 | unsigned int data) | ||
| 395 | { | ||
| 396 | struct meson_ao_cec_g12a_device *ao_cec = context; | ||
| 397 | unsigned long flags; | ||
| 398 | u32 reg = FIELD_PREP(CECB_RW_ADDR, addr) | | ||
| 399 | FIELD_PREP(CECB_RW_WR_DATA, data) | | ||
| 400 | CECB_RW_WRITE_EN; | ||
| 401 | int ret = 0; | ||
| 402 | |||
| 403 | spin_lock_irqsave(&ao_cec->cec_reg_lock, flags); | ||
| 404 | |||
| 405 | ret = regmap_write(ao_cec->regmap, CECB_RW_REG, reg); | ||
| 406 | |||
| 407 | spin_unlock_irqrestore(&ao_cec->cec_reg_lock, flags); | ||
| 408 | |||
| 409 | return ret; | ||
| 410 | } | ||
| 411 | |||
| 412 | static const struct regmap_config meson_ao_cec_g12a_cec_regmap_conf = { | ||
| 413 | .reg_bits = 8, | ||
| 414 | .val_bits = 8, | ||
| 415 | .reg_read = meson_ao_cec_g12a_read, | ||
| 416 | .reg_write = meson_ao_cec_g12a_write, | ||
| 417 | .max_register = 0xffff, | ||
| 418 | .fast_io = true, | ||
| 419 | }; | ||
| 420 | |||
| 421 | static inline void | ||
| 422 | meson_ao_cec_g12a_irq_setup(struct meson_ao_cec_g12a_device *ao_cec, | ||
| 423 | bool enable) | ||
| 424 | { | ||
| 425 | u32 cfg = CECB_INTR_DONE | CECB_INTR_EOM | CECB_INTR_NACK | | ||
| 426 | CECB_INTR_ARB_LOSS | CECB_INTR_INITIATOR_ERR | | ||
| 427 | CECB_INTR_FOLLOWER_ERR; | ||
| 428 | |||
| 429 | regmap_write(ao_cec->regmap, CECB_INTR_MASKN_REG, | ||
| 430 | enable ? cfg : 0); | ||
| 431 | } | ||
| 432 | |||
| 433 | static void meson_ao_cec_g12a_irq_rx(struct meson_ao_cec_g12a_device *ao_cec) | ||
| 434 | { | ||
| 435 | int i, ret = 0; | ||
| 436 | u32 val; | ||
| 437 | |||
| 438 | ret = regmap_read(ao_cec->regmap_cec, CECB_RX_CNT, &val); | ||
| 439 | |||
| 440 | ao_cec->rx_msg.len = val; | ||
| 441 | if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE) | ||
| 442 | ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE; | ||
| 443 | |||
| 444 | for (i = 0; i < ao_cec->rx_msg.len; i++) { | ||
| 445 | ret |= regmap_read(ao_cec->regmap_cec, | ||
| 446 | CECB_RX_DATA00 + i, &val); | ||
| 447 | |||
| 448 | ao_cec->rx_msg.msg[i] = val & 0xff; | ||
| 449 | } | ||
| 450 | |||
| 451 | ret |= regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0); | ||
| 452 | if (ret) | ||
| 453 | return; | ||
| 454 | |||
| 455 | cec_received_msg(ao_cec->adap, &ao_cec->rx_msg); | ||
| 456 | } | ||
| 457 | |||
| 458 | static irqreturn_t meson_ao_cec_g12a_irq(int irq, void *data) | ||
| 459 | { | ||
| 460 | struct meson_ao_cec_g12a_device *ao_cec = data; | ||
| 461 | u32 stat; | ||
| 462 | |||
| 463 | regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat); | ||
| 464 | if (stat) | ||
| 465 | return IRQ_WAKE_THREAD; | ||
| 466 | |||
| 467 | return IRQ_NONE; | ||
| 468 | } | ||
| 469 | |||
| 470 | static irqreturn_t meson_ao_cec_g12a_irq_thread(int irq, void *data) | ||
| 471 | { | ||
| 472 | struct meson_ao_cec_g12a_device *ao_cec = data; | ||
| 473 | u32 stat; | ||
| 474 | |||
| 475 | regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat); | ||
| 476 | regmap_write(ao_cec->regmap, CECB_INTR_CLR_REG, stat); | ||
| 477 | |||
| 478 | if (stat & CECB_INTR_DONE) | ||
| 479 | cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_OK); | ||
| 480 | |||
| 481 | if (stat & CECB_INTR_EOM) | ||
| 482 | meson_ao_cec_g12a_irq_rx(ao_cec); | ||
| 483 | |||
| 484 | if (stat & CECB_INTR_NACK) | ||
| 485 | cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_NACK); | ||
| 486 | |||
| 487 | if (stat & CECB_INTR_ARB_LOSS) { | ||
| 488 | regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, 0); | ||
| 489 | regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL, | ||
| 490 | CECB_CTRL_SEND | CECB_CTRL_TYPE, 0); | ||
| 491 | cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ARB_LOST); | ||
| 492 | } | ||
| 493 | |||
| 494 | /* Initiator reports an error on the CEC bus */ | ||
| 495 | if (stat & CECB_INTR_INITIATOR_ERR) | ||
| 496 | cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR); | ||
| 497 | |||
| 498 | /* Follower reports a receive error, just reset RX buffer */ | ||
| 499 | if (stat & CECB_INTR_FOLLOWER_ERR) | ||
| 500 | regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0); | ||
| 501 | |||
| 502 | return IRQ_HANDLED; | ||
| 503 | } | ||
| 504 | |||
| 505 | static int | ||
| 506 | meson_ao_cec_g12a_set_log_addr(struct cec_adapter *adap, u8 logical_addr) | ||
| 507 | { | ||
| 508 | struct meson_ao_cec_g12a_device *ao_cec = adap->priv; | ||
| 509 | int ret = 0; | ||
| 510 | |||
| 511 | if (logical_addr == CEC_LOG_ADDR_INVALID) { | ||
| 512 | /* Assume this will allways succeed */ | ||
| 513 | regmap_write(ao_cec->regmap_cec, CECB_LADD_LOW, 0); | ||
| 514 | regmap_write(ao_cec->regmap_cec, CECB_LADD_HIGH, 0); | ||
| 515 | |||
| 516 | return 0; | ||
| 517 | } else if (logical_addr < 8) { | ||
| 518 | ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_LOW, | ||
| 519 | BIT(logical_addr), | ||
| 520 | BIT(logical_addr)); | ||
| 521 | } else { | ||
| 522 | ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH, | ||
| 523 | BIT(logical_addr - 8), | ||
| 524 | BIT(logical_addr - 8)); | ||
| 525 | } | ||
| 526 | |||
| 527 | /* Always set Broadcast/Unregistered 15 address */ | ||
| 528 | ret |= regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH, | ||
| 529 | BIT(CEC_LOG_ADDR_UNREGISTERED - 8), | ||
| 530 | BIT(CEC_LOG_ADDR_UNREGISTERED - 8)); | ||
| 531 | |||
| 532 | return ret ? -EIO : 0; | ||
| 533 | } | ||
| 534 | |||
| 535 | static int meson_ao_cec_g12a_transmit(struct cec_adapter *adap, u8 attempts, | ||
| 536 | u32 signal_free_time, struct cec_msg *msg) | ||
| 537 | { | ||
| 538 | struct meson_ao_cec_g12a_device *ao_cec = adap->priv; | ||
| 539 | unsigned int type; | ||
| 540 | int ret = 0; | ||
| 541 | u32 val; | ||
| 542 | int i; | ||
| 543 | |||
| 544 | /* Check if RX is in progress */ | ||
| 545 | ret = regmap_read(ao_cec->regmap_cec, CECB_LOCK_BUF, &val); | ||
| 546 | if (ret) | ||
| 547 | return ret; | ||
| 548 | if (val & CECB_LOCK_BUF_EN) | ||
| 549 | return -EBUSY; | ||
| 550 | |||
| 551 | /* Check if TX Busy */ | ||
| 552 | ret = regmap_read(ao_cec->regmap_cec, CECB_CTRL, &val); | ||
| 553 | if (ret) | ||
| 554 | return ret; | ||
| 555 | if (val & CECB_CTRL_SEND) | ||
| 556 | return -EBUSY; | ||
| 557 | |||
| 558 | switch (signal_free_time) { | ||
| 559 | case CEC_SIGNAL_FREE_TIME_RETRY: | ||
| 560 | type = CECB_CTRL_TYPE_RETRY; | ||
| 561 | break; | ||
| 562 | case CEC_SIGNAL_FREE_TIME_NEXT_XFER: | ||
| 563 | type = CECB_CTRL_TYPE_NEXT; | ||
| 564 | break; | ||
| 565 | case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR: | ||
| 566 | default: | ||
| 567 | type = CECB_CTRL_TYPE_NEW; | ||
| 568 | break; | ||
| 569 | } | ||
| 570 | |||
| 571 | for (i = 0; i < msg->len; i++) | ||
| 572 | ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_DATA00 + i, | ||
| 573 | msg->msg[i]); | ||
| 574 | |||
| 575 | ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, msg->len); | ||
| 576 | if (ret) | ||
| 577 | return -EIO; | ||
| 578 | |||
| 579 | ret = regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL, | ||
| 580 | CECB_CTRL_SEND | | ||
| 581 | CECB_CTRL_TYPE, | ||
| 582 | CECB_CTRL_SEND | | ||
| 583 | FIELD_PREP(CECB_CTRL_TYPE, type)); | ||
| 584 | |||
| 585 | return ret; | ||
| 586 | } | ||
| 587 | |||
| 588 | static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable) | ||
| 589 | { | ||
| 590 | struct meson_ao_cec_g12a_device *ao_cec = adap->priv; | ||
| 591 | |||
| 592 | meson_ao_cec_g12a_irq_setup(ao_cec, false); | ||
| 593 | |||
| 594 | regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, | ||
| 595 | CECB_GEN_CNTL_RESET, CECB_GEN_CNTL_RESET); | ||
| 596 | |||
| 597 | if (!enable) | ||
| 598 | return 0; | ||
| 599 | |||
| 600 | /* Setup Filter */ | ||
| 601 | regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, | ||
| 602 | CECB_GEN_CNTL_FILTER_TICK_SEL | | ||
| 603 | CECB_GEN_CNTL_FILTER_DEL, | ||
| 604 | FIELD_PREP(CECB_GEN_CNTL_FILTER_TICK_SEL, | ||
| 605 | CECB_GEN_CNTL_FILTER_TICK_1US) | | ||
| 606 | FIELD_PREP(CECB_GEN_CNTL_FILTER_DEL, 7)); | ||
| 607 | |||
| 608 | /* Enable System Clock */ | ||
| 609 | regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, | ||
| 610 | CECB_GEN_CNTL_SYS_CLK_EN, | ||
| 611 | CECB_GEN_CNTL_SYS_CLK_EN); | ||
| 612 | |||
| 613 | /* Enable gated clock (Normal mode). */ | ||
| 614 | regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, | ||
| 615 | CECB_GEN_CNTL_CLK_CTRL_MASK, | ||
| 616 | FIELD_PREP(CECB_GEN_CNTL_CLK_CTRL_MASK, | ||
| 617 | CECB_GEN_CNTL_CLK_ENABLE)); | ||
| 618 | |||
| 619 | /* Release Reset */ | ||
| 620 | regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, | ||
| 621 | CECB_GEN_CNTL_RESET, 0); | ||
| 622 | |||
| 623 | meson_ao_cec_g12a_irq_setup(ao_cec, true); | ||
| 624 | |||
| 625 | return 0; | ||
| 626 | } | ||
| 627 | |||
| 628 | static const struct cec_adap_ops meson_ao_cec_g12a_ops = { | ||
| 629 | .adap_enable = meson_ao_cec_g12a_adap_enable, | ||
| 630 | .adap_log_addr = meson_ao_cec_g12a_set_log_addr, | ||
| 631 | .adap_transmit = meson_ao_cec_g12a_transmit, | ||
| 632 | }; | ||
| 633 | |||
| 634 | static int meson_ao_cec_g12a_probe(struct platform_device *pdev) | ||
| 635 | { | ||
| 636 | struct meson_ao_cec_g12a_device *ao_cec; | ||
| 637 | struct device *hdmi_dev; | ||
| 638 | struct resource *res; | ||
| 639 | void __iomem *base; | ||
| 640 | int ret, irq; | ||
| 641 | |||
| 642 | hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); | ||
| 643 | if (IS_ERR(hdmi_dev)) | ||
| 644 | return PTR_ERR(hdmi_dev); | ||
| 645 | |||
| 646 | ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL); | ||
| 647 | if (!ao_cec) | ||
| 648 | return -ENOMEM; | ||
| 649 | |||
| 650 | spin_lock_init(&ao_cec->cec_reg_lock); | ||
| 651 | ao_cec->pdev = pdev; | ||
| 652 | |||
| 653 | ao_cec->notify = cec_notifier_get(hdmi_dev); | ||
| 654 | if (!ao_cec->notify) | ||
| 655 | return -ENOMEM; | ||
| 656 | |||
| 657 | ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec, | ||
| 658 | "meson_g12a_ao_cec", | ||
| 659 | CEC_CAP_DEFAULTS, | ||
| 660 | CEC_MAX_LOG_ADDRS); | ||
| 661 | if (IS_ERR(ao_cec->adap)) { | ||
| 662 | ret = PTR_ERR(ao_cec->adap); | ||
| 663 | goto out_probe_notify; | ||
| 664 | } | ||
| 665 | |||
| 666 | ao_cec->adap->owner = THIS_MODULE; | ||
| 667 | |||
| 668 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 669 | base = devm_ioremap_resource(&pdev->dev, res); | ||
| 670 | if (IS_ERR(base)) { | ||
| 671 | ret = PTR_ERR(base); | ||
| 672 | goto out_probe_adapter; | ||
| 673 | } | ||
| 674 | |||
| 675 | ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base, | ||
| 676 | &meson_ao_cec_g12a_regmap_conf); | ||
| 677 | if (IS_ERR(ao_cec->regmap)) { | ||
| 678 | ret = PTR_ERR(ao_cec->regmap); | ||
| 679 | goto out_probe_adapter; | ||
| 680 | } | ||
| 681 | |||
| 682 | ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec, | ||
| 683 | &meson_ao_cec_g12a_cec_regmap_conf); | ||
| 684 | if (IS_ERR(ao_cec->regmap_cec)) { | ||
| 685 | ret = PTR_ERR(ao_cec->regmap_cec); | ||
| 686 | goto out_probe_adapter; | ||
| 687 | } | ||
| 688 | |||
| 689 | irq = platform_get_irq(pdev, 0); | ||
| 690 | ret = devm_request_threaded_irq(&pdev->dev, irq, | ||
| 691 | meson_ao_cec_g12a_irq, | ||
| 692 | meson_ao_cec_g12a_irq_thread, | ||
| 693 | 0, NULL, ao_cec); | ||
| 694 | if (ret) { | ||
| 695 | dev_err(&pdev->dev, "irq request failed\n"); | ||
| 696 | goto out_probe_adapter; | ||
| 697 | } | ||
| 698 | |||
| 699 | ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin"); | ||
| 700 | if (IS_ERR(ao_cec->oscin)) { | ||
| 701 | dev_err(&pdev->dev, "oscin clock request failed\n"); | ||
| 702 | ret = PTR_ERR(ao_cec->oscin); | ||
| 703 | goto out_probe_adapter; | ||
| 704 | } | ||
| 705 | |||
| 706 | ret = meson_ao_cec_g12a_setup_clk(ao_cec); | ||
| 707 | if (ret) | ||
| 708 | goto out_probe_adapter; | ||
| 709 | |||
| 710 | ret = clk_prepare_enable(ao_cec->core); | ||
| 711 | if (ret) { | ||
| 712 | dev_err(&pdev->dev, "core clock enable failed\n"); | ||
| 713 | goto out_probe_adapter; | ||
| 714 | } | ||
| 715 | |||
| 716 | device_reset_optional(&pdev->dev); | ||
| 717 | |||
| 718 | platform_set_drvdata(pdev, ao_cec); | ||
| 719 | |||
| 720 | ret = cec_register_adapter(ao_cec->adap, &pdev->dev); | ||
| 721 | if (ret < 0) { | ||
| 722 | cec_notifier_put(ao_cec->notify); | ||
| 723 | goto out_probe_core_clk; | ||
| 724 | } | ||
| 725 | |||
| 726 | /* Setup Hardware */ | ||
| 727 | regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET); | ||
| 728 | |||
| 729 | cec_register_cec_notifier(ao_cec->adap, ao_cec->notify); | ||
| 730 | |||
| 731 | return 0; | ||
| 732 | |||
| 733 | out_probe_core_clk: | ||
| 734 | clk_disable_unprepare(ao_cec->core); | ||
| 735 | |||
| 736 | out_probe_adapter: | ||
| 737 | cec_delete_adapter(ao_cec->adap); | ||
| 738 | |||
| 739 | out_probe_notify: | ||
| 740 | cec_notifier_put(ao_cec->notify); | ||
| 741 | |||
| 742 | dev_err(&pdev->dev, "CEC controller registration failed\n"); | ||
| 743 | |||
| 744 | return ret; | ||
| 745 | } | ||
| 746 | |||
| 747 | static int meson_ao_cec_g12a_remove(struct platform_device *pdev) | ||
| 748 | { | ||
| 749 | struct meson_ao_cec_g12a_device *ao_cec = platform_get_drvdata(pdev); | ||
| 750 | |||
| 751 | clk_disable_unprepare(ao_cec->core); | ||
| 752 | |||
| 753 | cec_unregister_adapter(ao_cec->adap); | ||
| 754 | |||
| 755 | cec_notifier_put(ao_cec->notify); | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | static const struct of_device_id meson_ao_cec_g12a_of_match[] = { | ||
| 761 | { .compatible = "amlogic,meson-g12a-ao-cec", }, | ||
| 762 | { /* sentinel */ } | ||
| 763 | }; | ||
| 764 | MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match); | ||
| 765 | |||
| 766 | static struct platform_driver meson_ao_cec_g12a_driver = { | ||
| 767 | .probe = meson_ao_cec_g12a_probe, | ||
| 768 | .remove = meson_ao_cec_g12a_remove, | ||
| 769 | .driver = { | ||
| 770 | .name = "meson-ao-cec-g12a", | ||
| 771 | .of_match_table = of_match_ptr(meson_ao_cec_g12a_of_match), | ||
| 772 | }, | ||
| 773 | }; | ||
| 774 | |||
| 775 | module_platform_driver(meson_ao_cec_g12a_driver); | ||
| 776 | |||
| 777 | MODULE_DESCRIPTION("Meson AO CEC G12A Controller driver"); | ||
| 778 | MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); | ||
| 779 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c index cd4be38ab5ac..facf9b029e79 100644 --- a/drivers/media/platform/meson/ao-cec.c +++ b/drivers/media/platform/meson/ao-cec.c | |||
| @@ -601,20 +601,14 @@ static const struct cec_adap_ops meson_ao_cec_ops = { | |||
| 601 | static int meson_ao_cec_probe(struct platform_device *pdev) | 601 | static int meson_ao_cec_probe(struct platform_device *pdev) |
| 602 | { | 602 | { |
| 603 | struct meson_ao_cec_device *ao_cec; | 603 | struct meson_ao_cec_device *ao_cec; |
| 604 | struct platform_device *hdmi_dev; | 604 | struct device *hdmi_dev; |
| 605 | struct device_node *np; | ||
| 606 | struct resource *res; | 605 | struct resource *res; |
| 607 | int ret, irq; | 606 | int ret, irq; |
| 608 | 607 | ||
| 609 | np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); | 608 | hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); |
| 610 | if (!np) { | ||
| 611 | dev_err(&pdev->dev, "Failed to find hdmi node\n"); | ||
| 612 | return -ENODEV; | ||
| 613 | } | ||
| 614 | 609 | ||
| 615 | hdmi_dev = of_find_device_by_node(np); | 610 | if (IS_ERR(hdmi_dev)) |
| 616 | if (hdmi_dev == NULL) | 611 | return PTR_ERR(hdmi_dev); |
| 617 | return -EPROBE_DEFER; | ||
| 618 | 612 | ||
| 619 | ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL); | 613 | ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL); |
| 620 | if (!ao_cec) | 614 | if (!ao_cec) |
| @@ -622,7 +616,7 @@ static int meson_ao_cec_probe(struct platform_device *pdev) | |||
| 622 | 616 | ||
| 623 | spin_lock_init(&ao_cec->cec_reg_lock); | 617 | spin_lock_init(&ao_cec->cec_reg_lock); |
| 624 | 618 | ||
| 625 | ao_cec->notify = cec_notifier_get(&hdmi_dev->dev); | 619 | ao_cec->notify = cec_notifier_get(hdmi_dev); |
| 626 | if (!ao_cec->notify) | 620 | if (!ao_cec->notify) |
| 627 | return -ENOMEM; | 621 | return -ENOMEM; |
| 628 | 622 | ||
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index d022c65bb34c..851903867bc9 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | |||
| @@ -129,11 +129,9 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx) | |||
| 129 | mutex_lock(&ctx->lock); | 129 | mutex_lock(&ctx->lock); |
| 130 | if (dstbuf->used) { | 130 | if (dstbuf->used) { |
| 131 | vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, | 131 | vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, |
| 132 | ctx->picinfo.y_bs_sz); | 132 | ctx->picinfo.fb_sz[0]); |
| 133 | vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, | 133 | vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1, |
| 134 | ctx->picinfo.c_bs_sz); | 134 | ctx->picinfo.fb_sz[1]); |
| 135 | |||
| 136 | dstbuf->ready_to_display = true; | ||
| 137 | 135 | ||
| 138 | mtk_v4l2_debug(2, | 136 | mtk_v4l2_debug(2, |
| 139 | "[%d]status=%x queue id=%d to done_list %d", | 137 | "[%d]status=%x queue id=%d to done_list %d", |
| @@ -278,6 +276,27 @@ static void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) | |||
| 278 | clean_free_buffer(ctx); | 276 | clean_free_buffer(ctx); |
| 279 | } | 277 | } |
| 280 | 278 | ||
| 279 | static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx, | ||
| 280 | unsigned int pixelformat) | ||
| 281 | { | ||
| 282 | struct mtk_video_fmt *fmt; | ||
| 283 | struct mtk_q_data *dst_q_data; | ||
| 284 | unsigned int k; | ||
| 285 | |||
| 286 | dst_q_data = &ctx->q_data[MTK_Q_DATA_DST]; | ||
| 287 | for (k = 0; k < NUM_FORMATS; k++) { | ||
| 288 | fmt = &mtk_video_formats[k]; | ||
| 289 | if (fmt->fourcc == pixelformat) { | ||
| 290 | mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)", | ||
| 291 | dst_q_data->fmt.fourcc, pixelformat); | ||
| 292 | dst_q_data->fmt = fmt; | ||
| 293 | return; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat); | ||
| 298 | } | ||
| 299 | |||
| 281 | static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) | 300 | static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) |
| 282 | { | 301 | { |
| 283 | unsigned int dpbsize = 0; | 302 | unsigned int dpbsize = 0; |
| @@ -299,6 +318,10 @@ static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx) | |||
| 299 | return -EINVAL; | 318 | return -EINVAL; |
| 300 | } | 319 | } |
| 301 | 320 | ||
| 321 | if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc && | ||
| 322 | ctx->picinfo.cap_fourcc != 0) | ||
| 323 | mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc); | ||
| 324 | |||
| 302 | if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) || | 325 | if ((ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w) || |
| 303 | (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)) | 326 | (ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)) |
| 304 | return 0; | 327 | return 0; |
| @@ -352,11 +375,11 @@ static void mtk_vdec_worker(struct work_struct *work) | |||
| 352 | pfb = &dst_buf_info->frame_buffer; | 375 | pfb = &dst_buf_info->frame_buffer; |
| 353 | pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); | 376 | pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); |
| 354 | pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); | 377 | pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); |
| 355 | pfb->base_y.size = ctx->picinfo.y_bs_sz + ctx->picinfo.y_len_sz; | 378 | pfb->base_y.size = ctx->picinfo.fb_sz[0]; |
| 356 | 379 | ||
| 357 | pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1); | 380 | pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1); |
| 358 | pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1); | 381 | pfb->base_c.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1); |
| 359 | pfb->base_c.size = ctx->picinfo.c_bs_sz + ctx->picinfo.c_len_sz; | 382 | pfb->base_c.size = ctx->picinfo.fb_sz[1]; |
| 360 | pfb->status = 0; | 383 | pfb->status = 0; |
| 361 | mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); | 384 | mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id); |
| 362 | 385 | ||
| @@ -388,7 +411,7 @@ static void mtk_vdec_worker(struct work_struct *work) | |||
| 388 | } | 411 | } |
| 389 | buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); | 412 | buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); |
| 390 | buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); | 413 | buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); |
| 391 | buf.size = (size_t)src_buf->planes[0].bytesused; | 414 | buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; |
| 392 | if (!buf.va) { | 415 | if (!buf.va) { |
| 393 | v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); | 416 | v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx); |
| 394 | mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", | 417 | mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", |
| @@ -976,14 +999,13 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv, | |||
| 976 | * So we just return picinfo yet, and update picinfo in | 999 | * So we just return picinfo yet, and update picinfo in |
| 977 | * stop_streaming hook function | 1000 | * stop_streaming hook function |
| 978 | */ | 1001 | */ |
| 979 | q_data->sizeimage[0] = ctx->picinfo.y_bs_sz + | 1002 | q_data->sizeimage[0] = ctx->picinfo.fb_sz[0]; |
| 980 | ctx->picinfo.y_len_sz; | 1003 | q_data->sizeimage[1] = ctx->picinfo.fb_sz[1]; |
| 981 | q_data->sizeimage[1] = ctx->picinfo.c_bs_sz + | ||
| 982 | ctx->picinfo.c_len_sz; | ||
| 983 | q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w; | 1004 | q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w; |
| 984 | q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w; | 1005 | q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w; |
| 985 | q_data->coded_width = ctx->picinfo.buf_w; | 1006 | q_data->coded_width = ctx->picinfo.buf_w; |
| 986 | q_data->coded_height = ctx->picinfo.buf_h; | 1007 | q_data->coded_height = ctx->picinfo.buf_h; |
| 1008 | ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc; | ||
| 987 | 1009 | ||
| 988 | /* | 1010 | /* |
| 989 | * Width and height are set to the dimensions | 1011 | * Width and height are set to the dimensions |
| @@ -1103,10 +1125,11 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
| 1103 | struct mtk_vcodec_mem src_mem; | 1125 | struct mtk_vcodec_mem src_mem; |
| 1104 | bool res_chg = false; | 1126 | bool res_chg = false; |
| 1105 | int ret = 0; | 1127 | int ret = 0; |
| 1106 | unsigned int dpbsize = 1; | 1128 | unsigned int dpbsize = 1, i = 0; |
| 1107 | struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | 1129 | struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); |
| 1108 | struct vb2_v4l2_buffer *vb2_v4l2 = NULL; | 1130 | struct vb2_v4l2_buffer *vb2_v4l2 = NULL; |
| 1109 | struct mtk_video_dec_buf *buf = NULL; | 1131 | struct mtk_video_dec_buf *buf = NULL; |
| 1132 | struct mtk_q_data *dst_q_data; | ||
| 1110 | 1133 | ||
| 1111 | mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", | 1134 | mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", |
| 1112 | ctx->id, vb->vb2_queue->type, | 1135 | ctx->id, vb->vb2_queue->type, |
| @@ -1122,11 +1145,9 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
| 1122 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); | 1145 | v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2); |
| 1123 | buf->queued_in_vb2 = true; | 1146 | buf->queued_in_vb2 = true; |
| 1124 | buf->queued_in_v4l2 = true; | 1147 | buf->queued_in_v4l2 = true; |
| 1125 | buf->ready_to_display = false; | ||
| 1126 | } else { | 1148 | } else { |
| 1127 | buf->queued_in_vb2 = false; | 1149 | buf->queued_in_vb2 = false; |
| 1128 | buf->queued_in_v4l2 = true; | 1150 | buf->queued_in_v4l2 = true; |
| 1129 | buf->ready_to_display = false; | ||
| 1130 | } | 1151 | } |
| 1131 | mutex_unlock(&ctx->lock); | 1152 | mutex_unlock(&ctx->lock); |
| 1132 | return; | 1153 | return; |
| @@ -1155,10 +1176,10 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
| 1155 | 1176 | ||
| 1156 | src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); | 1177 | src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0); |
| 1157 | src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); | 1178 | src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0); |
| 1158 | src_mem.size = (size_t)src_buf->planes[0].bytesused; | 1179 | src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused; |
| 1159 | mtk_v4l2_debug(2, | 1180 | mtk_v4l2_debug(2, |
| 1160 | "[%d] buf id=%d va=%p dma=%pad size=%zx", | 1181 | "[%d] buf id=%d va=%p dma=%pad size=%zx", |
| 1161 | ctx->id, src_buf->index, | 1182 | ctx->id, src_buf->vb2_buf.index, |
| 1162 | src_mem.va, &src_mem.dma_addr, | 1183 | src_mem.va, &src_mem.dma_addr, |
| 1163 | src_mem.size); | 1184 | src_mem.size); |
| 1164 | 1185 | ||
| @@ -1182,7 +1203,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
| 1182 | } | 1203 | } |
| 1183 | mtk_v4l2_debug(ret ? 0 : 1, | 1204 | mtk_v4l2_debug(ret ? 0 : 1, |
| 1184 | "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", | 1205 | "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d", |
| 1185 | ctx->id, src_buf->index, | 1206 | ctx->id, src_buf->vb2_buf.index, |
| 1186 | src_mem.size, ret, res_chg); | 1207 | src_mem.size, ret, res_chg); |
| 1187 | return; | 1208 | return; |
| 1188 | } | 1209 | } |
| @@ -1194,21 +1215,18 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) | |||
| 1194 | } | 1215 | } |
| 1195 | 1216 | ||
| 1196 | ctx->last_decoded_picinfo = ctx->picinfo; | 1217 | ctx->last_decoded_picinfo = ctx->picinfo; |
| 1197 | ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = | 1218 | dst_q_data = &ctx->q_data[MTK_Q_DATA_DST]; |
| 1198 | ctx->picinfo.y_bs_sz + | 1219 | for (i = 0; i < dst_q_data->fmt->num_planes; i++) { |
| 1199 | ctx->picinfo.y_len_sz; | 1220 | dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i]; |
| 1200 | ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = | 1221 | dst_q_data->bytesperline[i] = ctx->picinfo.buf_w; |
| 1201 | ctx->picinfo.buf_w; | 1222 | } |
| 1202 | ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] = | 1223 | |
| 1203 | ctx->picinfo.c_bs_sz + | ||
| 1204 | ctx->picinfo.c_len_sz; | ||
| 1205 | ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] = ctx->picinfo.buf_w; | ||
| 1206 | mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", | 1224 | mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x", |
| 1207 | ctx->id, | 1225 | ctx->id, |
| 1208 | ctx->picinfo.buf_w, ctx->picinfo.buf_h, | 1226 | ctx->picinfo.buf_w, ctx->picinfo.buf_h, |
| 1209 | ctx->picinfo.pic_w, ctx->picinfo.pic_h, | 1227 | ctx->picinfo.pic_w, ctx->picinfo.pic_h, |
| 1210 | ctx->q_data[MTK_Q_DATA_DST].sizeimage[0], | 1228 | dst_q_data->sizeimage[0], |
| 1211 | ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]); | 1229 | dst_q_data->sizeimage[1]); |
| 1212 | 1230 | ||
| 1213 | ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); | 1231 | ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize); |
| 1214 | if (dpbsize == 0) | 1232 | if (dpbsize == 0) |
| @@ -1253,7 +1271,6 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) | |||
| 1253 | 1271 | ||
| 1254 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 1272 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 1255 | buf->used = false; | 1273 | buf->used = false; |
| 1256 | buf->ready_to_display = false; | ||
| 1257 | buf->queued_in_v4l2 = false; | 1274 | buf->queued_in_v4l2 = false; |
| 1258 | } else { | 1275 | } else { |
| 1259 | buf->lastframe = false; | 1276 | buf->lastframe = false; |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index dc4fc1df63c5..e4984edec4f8 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h | |||
| @@ -45,7 +45,6 @@ struct vdec_fb { | |||
| 45 | * @list: link list | 45 | * @list: link list |
| 46 | * @used: Capture buffer contain decoded frame data and keep in | 46 | * @used: Capture buffer contain decoded frame data and keep in |
| 47 | * codec data structure | 47 | * codec data structure |
| 48 | * @ready_to_display: Capture buffer not display yet | ||
| 49 | * @queued_in_vb2: Capture buffer is queue in vb2 | 48 | * @queued_in_vb2: Capture buffer is queue in vb2 |
| 50 | * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 | 49 | * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 |
| 51 | * queue yet | 50 | * queue yet |
| @@ -60,7 +59,6 @@ struct mtk_video_dec_buf { | |||
| 60 | struct list_head list; | 59 | struct list_head list; |
| 61 | 60 | ||
| 62 | bool used; | 61 | bool used; |
| 63 | bool ready_to_display; | ||
| 64 | bool queued_in_vb2; | 62 | bool queued_in_vb2; |
| 65 | bool queued_in_v4l2; | 63 | bool queued_in_v4l2; |
| 66 | bool lastframe; | 64 | bool lastframe; |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index e7e2a108def9..662a84b822af 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | |||
| @@ -211,24 +211,20 @@ struct mtk_vcodec_pm { | |||
| 211 | * @pic_h: picture height | 211 | * @pic_h: picture height |
| 212 | * @buf_w: picture buffer width (64 aligned up from pic_w) | 212 | * @buf_w: picture buffer width (64 aligned up from pic_w) |
| 213 | * @buf_h: picture buffer heiht (64 aligned up from pic_h) | 213 | * @buf_h: picture buffer heiht (64 aligned up from pic_h) |
| 214 | * @y_bs_sz: Y bitstream size | 214 | * @fb_sz: bitstream size of each plane |
| 215 | * @c_bs_sz: CbCr bitstream size | ||
| 216 | * @y_len_sz: additional size required to store decompress information for y | ||
| 217 | * plane | ||
| 218 | * @c_len_sz: additional size required to store decompress information for cbcr | ||
| 219 | * plane | ||
| 220 | * E.g. suppose picture size is 176x144, | 215 | * E.g. suppose picture size is 176x144, |
| 221 | * buffer size will be aligned to 176x160. | 216 | * buffer size will be aligned to 176x160. |
| 217 | * @cap_fourcc: fourcc number(may changed when resolution change) | ||
| 218 | * @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os. | ||
| 222 | */ | 219 | */ |
| 223 | struct vdec_pic_info { | 220 | struct vdec_pic_info { |
| 224 | unsigned int pic_w; | 221 | unsigned int pic_w; |
| 225 | unsigned int pic_h; | 222 | unsigned int pic_h; |
| 226 | unsigned int buf_w; | 223 | unsigned int buf_w; |
| 227 | unsigned int buf_h; | 224 | unsigned int buf_h; |
| 228 | unsigned int y_bs_sz; | 225 | unsigned int fb_sz[VIDEO_MAX_PLANES]; |
| 229 | unsigned int c_bs_sz; | 226 | unsigned int cap_fourcc; |
| 230 | unsigned int y_len_sz; | 227 | unsigned int reserved; |
| 231 | unsigned int c_len_sz; | ||
| 232 | }; | 228 | }; |
| 233 | 229 | ||
| 234 | /** | 230 | /** |
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index c6b48b5925fb..50351adafc47 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | |||
| @@ -894,7 +894,7 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q) | |||
| 894 | 894 | ||
| 895 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 895 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
| 896 | while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { | 896 | while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { |
| 897 | dst_buf->planes[0].bytesused = 0; | 897 | dst_buf->vb2_buf.planes[0].bytesused = 0; |
| 898 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); | 898 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
| 899 | } | 899 | } |
| 900 | } else { | 900 | } else { |
| @@ -947,7 +947,7 @@ static int mtk_venc_encode_header(void *priv) | |||
| 947 | 947 | ||
| 948 | bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); | 948 | bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); |
| 949 | bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); | 949 | bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); |
| 950 | bs_buf.size = (size_t)dst_buf->planes[0].length; | 950 | bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; |
| 951 | 951 | ||
| 952 | mtk_v4l2_debug(1, | 952 | mtk_v4l2_debug(1, |
| 953 | "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", | 953 | "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", |
| @@ -976,7 +976,7 @@ static int mtk_venc_encode_header(void *priv) | |||
| 976 | } | 976 | } |
| 977 | 977 | ||
| 978 | ctx->state = MTK_STATE_HEADER; | 978 | ctx->state = MTK_STATE_HEADER; |
| 979 | dst_buf->planes[0].bytesused = enc_result.bs_size; | 979 | dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; |
| 980 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); | 980 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
| 981 | 981 | ||
| 982 | return 0; | 982 | return 0; |
| @@ -1107,12 +1107,12 @@ static void mtk_venc_worker(struct work_struct *work) | |||
| 1107 | 1107 | ||
| 1108 | if (ret) { | 1108 | if (ret) { |
| 1109 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); | 1109 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); |
| 1110 | dst_buf->planes[0].bytesused = 0; | 1110 | dst_buf->vb2_buf.planes[0].bytesused = 0; |
| 1111 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); | 1111 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
| 1112 | mtk_v4l2_err("venc_if_encode failed=%d", ret); | 1112 | mtk_v4l2_err("venc_if_encode failed=%d", ret); |
| 1113 | } else { | 1113 | } else { |
| 1114 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); | 1114 | v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
| 1115 | dst_buf->planes[0].bytesused = enc_result.bs_size; | 1115 | dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; |
| 1116 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); | 1116 | v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
| 1117 | mtk_v4l2_debug(2, "venc_if_encode bs size=%d", | 1117 | mtk_v4l2_debug(2, "venc_if_encode bs size=%d", |
| 1118 | enc_result.bs_size); | 1118 | enc_result.bs_size); |
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c index 02c960c63ac0..cdbcd6909728 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c | |||
| @@ -253,8 +253,8 @@ static void get_pic_info(struct vdec_h264_inst *inst, | |||
| 253 | *pic = inst->vsi->pic; | 253 | *pic = inst->vsi->pic; |
| 254 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", | 254 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
| 255 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); | 255 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); |
| 256 | mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, | 256 | mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
| 257 | pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); | 257 | pic->fb_sz[0], pic->fb_sz[1]); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) | 260 | static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr) |
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c index bac3723038de..ba79136421ef 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c | |||
| @@ -294,8 +294,8 @@ static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic) | |||
| 294 | 294 | ||
| 295 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", | 295 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
| 296 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); | 296 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); |
| 297 | mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, | 297 | mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
| 298 | pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); | 298 | pic->fb_sz[0], pic->fb_sz[1]); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | static void vp8_dec_finish(struct vdec_vp8_inst *inst) | 301 | static void vp8_dec_finish(struct vdec_vp8_inst *inst) |
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c index bc8349bc2e80..939ea14bf6c5 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c | |||
| @@ -481,15 +481,15 @@ static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst) | |||
| 481 | */ | 481 | */ |
| 482 | if ((frm_to_show->fb != NULL) && | 482 | if ((frm_to_show->fb != NULL) && |
| 483 | (inst->cur_fb->base_y.size >= | 483 | (inst->cur_fb->base_y.size >= |
| 484 | frm_to_show->fb->base_y.size)) { | 484 | frm_to_show->fb->base_y.size) && |
| 485 | (inst->cur_fb->base_c.size >= | ||
| 486 | frm_to_show->fb->base_c.size)) { | ||
| 485 | memcpy((void *)inst->cur_fb->base_y.va, | 487 | memcpy((void *)inst->cur_fb->base_y.va, |
| 486 | (void *)frm_to_show->fb->base_y.va, | 488 | (void *)frm_to_show->fb->base_y.va, |
| 487 | vsi->buf_w * | 489 | frm_to_show->fb->base_y.size); |
| 488 | vsi->buf_h); | ||
| 489 | memcpy((void *)inst->cur_fb->base_c.va, | 490 | memcpy((void *)inst->cur_fb->base_c.va, |
| 490 | (void *)frm_to_show->fb->base_c.va, | 491 | (void *)frm_to_show->fb->base_c.va, |
| 491 | vsi->buf_w * | 492 | frm_to_show->fb->base_c.size); |
| 492 | vsi->buf_h / 2); | ||
| 493 | } else { | 493 | } else { |
| 494 | /* After resolution change case, current CAPTURE buffer | 494 | /* After resolution change case, current CAPTURE buffer |
| 495 | * may have less buffer size than frm_to_show buffer | 495 | * may have less buffer size than frm_to_show buffer |
| @@ -702,10 +702,8 @@ static void init_all_fb_lists(struct vdec_vp9_inst *inst) | |||
| 702 | 702 | ||
| 703 | static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) | 703 | static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) |
| 704 | { | 704 | { |
| 705 | pic->y_bs_sz = inst->vsi->buf_sz_y_bs; | 705 | pic->fb_sz[0] = inst->vsi->buf_sz_y_bs + inst->vsi->buf_len_sz_y; |
| 706 | pic->c_bs_sz = inst->vsi->buf_sz_c_bs; | 706 | pic->fb_sz[1] = inst->vsi->buf_sz_c_bs + inst->vsi->buf_len_sz_c; |
| 707 | pic->y_len_sz = inst->vsi->buf_len_sz_y; | ||
| 708 | pic->c_len_sz = inst->vsi->buf_len_sz_c; | ||
| 709 | 707 | ||
| 710 | pic->pic_w = inst->vsi->pic_w; | 708 | pic->pic_w = inst->vsi->pic_w; |
| 711 | pic->pic_h = inst->vsi->pic_h; | 709 | pic->pic_h = inst->vsi->pic_h; |
| @@ -714,8 +712,9 @@ static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic) | |||
| 714 | 712 | ||
| 715 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", | 713 | mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)", |
| 716 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); | 714 | pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h); |
| 717 | mtk_vcodec_debug(inst, "Y(%d, %d), C(%d, %d)", pic->y_bs_sz, | 715 | mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)", |
| 718 | pic->y_len_sz, pic->c_bs_sz, pic->c_len_sz); | 716 | pic->fb_sz[0], |
| 717 | pic->fb_sz[1]); | ||
| 719 | } | 718 | } |
| 720 | 719 | ||
| 721 | static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) | 720 | static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb) |
| @@ -895,7 +894,7 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, | |||
| 895 | 894 | ||
| 896 | if (vsi->resolution_changed) { | 895 | if (vsi->resolution_changed) { |
| 897 | if (!vp9_alloc_work_buf(inst)) { | 896 | if (!vp9_alloc_work_buf(inst)) { |
| 898 | ret = -EINVAL; | 897 | ret = -EIO; |
| 899 | goto DECODE_ERROR; | 898 | goto DECODE_ERROR; |
| 900 | } | 899 | } |
| 901 | } | 900 | } |
| @@ -924,14 +923,12 @@ static int vdec_vp9_decode(unsigned long h_vdec, struct mtk_vcodec_mem *bs, | |||
| 924 | 923 | ||
| 925 | if (vsi->show_existing_frame && (vsi->frm_to_show_idx < | 924 | if (vsi->show_existing_frame && (vsi->frm_to_show_idx < |
| 926 | VP9_MAX_FRM_BUF_NUM)) { | 925 | VP9_MAX_FRM_BUF_NUM)) { |
| 927 | mtk_vcodec_err(inst, | 926 | mtk_vcodec_debug(inst, |
| 928 | "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", | 927 | "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d", |
| 929 | vsi->new_fb_idx, vsi->frm_to_show_idx); | 928 | vsi->new_fb_idx, vsi->frm_to_show_idx); |
| 930 | 929 | ||
| 931 | vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, | 930 | vp9_ref_cnt_fb(inst, &vsi->new_fb_idx, |
| 932 | vsi->frm_to_show_idx); | 931 | vsi->frm_to_show_idx); |
| 933 | ret = -EINVAL; | ||
| 934 | goto DECODE_ERROR; | ||
| 935 | } | 932 | } |
| 936 | 933 | ||
| 937 | /* VPU assign the buffer pointer in its address space, | 934 | /* VPU assign the buffer pointer in its address space, |
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index b6602490a247..46c45f93c977 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c | |||
| @@ -614,7 +614,7 @@ static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv) | |||
| 614 | struct vpu_run *run = (struct vpu_run *)data; | 614 | struct vpu_run *run = (struct vpu_run *)data; |
| 615 | 615 | ||
| 616 | vpu->run.signaled = run->signaled; | 616 | vpu->run.signaled = run->signaled; |
| 617 | strncpy(vpu->run.fw_ver, run->fw_ver, VPU_FW_VER_LEN); | 617 | strscpy(vpu->run.fw_ver, run->fw_ver, sizeof(vpu->run.fw_ver)); |
| 618 | vpu->run.dec_capability = run->dec_capability; | 618 | vpu->run.dec_capability = run->dec_capability; |
| 619 | vpu->run.enc_capability = run->enc_capability; | 619 | vpu->run.enc_capability = run->enc_capability; |
| 620 | wake_up_interruptible(&vpu->run.wq); | 620 | wake_up_interruptible(&vpu->run.wq); |
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index f60f499c596b..e100b30bb6f5 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c | |||
| @@ -385,8 +385,8 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data) | |||
| 385 | static int vidioc_querycap(struct file *file, void *priv, | 385 | static int vidioc_querycap(struct file *file, void *priv, |
| 386 | struct v4l2_capability *cap) | 386 | struct v4l2_capability *cap) |
| 387 | { | 387 | { |
| 388 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); | 388 | strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); |
| 389 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); | 389 | strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); |
| 390 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | 390 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; |
| 391 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 391 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
| 392 | return 0; | 392 | return 0; |
diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig index 4b5e55d41ad4..30ce2ba120a1 100644 --- a/drivers/media/platform/omap/Kconfig +++ b/drivers/media/platform/omap/Kconfig | |||
| @@ -14,5 +14,5 @@ config VIDEO_OMAP2_VOUT | |||
| 14 | select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 | 14 | select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 |
| 15 | select FRAME_VECTOR | 15 | select FRAME_VECTOR |
| 16 | default n | 16 | default n |
| 17 | ---help--- | 17 | help |
| 18 | V4L2 Display driver support for OMAP2/3 based boards. | 18 | V4L2 Display driver support for OMAP2/3 based boards. |
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 4fe228752a43..a632f06d9fff 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c | |||
| @@ -2350,7 +2350,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev, | |||
| 2350 | pcdev->platform_flags |= PXA_CAMERA_PCLK_EN; | 2350 | pcdev->platform_flags |= PXA_CAMERA_PCLK_EN; |
| 2351 | 2351 | ||
| 2352 | asd->match_type = V4L2_ASYNC_MATCH_FWNODE; | 2352 | asd->match_type = V4L2_ASYNC_MATCH_FWNODE; |
| 2353 | remote = of_graph_get_remote_port(np); | 2353 | remote = of_graph_get_remote_port_parent(np); |
| 2354 | if (remote) | 2354 | if (remote) |
| 2355 | asd->match.fwnode = of_fwnode_handle(remote); | 2355 | asd->match.fwnode = of_fwnode_handle(remote); |
| 2356 | else | 2356 | else |
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index 15804ad7e65d..34ea503a9842 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h | |||
| @@ -569,7 +569,7 @@ struct hfi_capability { | |||
| 569 | 569 | ||
| 570 | struct hfi_capabilities { | 570 | struct hfi_capabilities { |
| 571 | u32 num_capabilities; | 571 | u32 num_capabilities; |
| 572 | struct hfi_capability data[1]; | 572 | struct hfi_capability *data; |
| 573 | }; | 573 | }; |
| 574 | 574 | ||
| 575 | #define HFI_DEBUG_MSG_LOW 0x01 | 575 | #define HFI_DEBUG_MSG_LOW 0x01 |
| @@ -726,7 +726,7 @@ struct hfi_profile_level { | |||
| 726 | 726 | ||
| 727 | struct hfi_profile_level_supported { | 727 | struct hfi_profile_level_supported { |
| 728 | u32 profile_count; | 728 | u32 profile_count; |
| 729 | struct hfi_profile_level profile_level[1]; | 729 | struct hfi_profile_level *profile_level; |
| 730 | }; | 730 | }; |
| 731 | 731 | ||
| 732 | struct hfi_quality_vs_speed { | 732 | struct hfi_quality_vs_speed { |
diff --git a/drivers/media/platform/rcar-vin/Kconfig b/drivers/media/platform/rcar-vin/Kconfig index e3eb8fee2536..240ac3f3c941 100644 --- a/drivers/media/platform/rcar-vin/Kconfig +++ b/drivers/media/platform/rcar-vin/Kconfig | |||
| @@ -3,6 +3,7 @@ config VIDEO_RCAR_CSI2 | |||
| 3 | tristate "R-Car MIPI CSI-2 Receiver" | 3 | tristate "R-Car MIPI CSI-2 Receiver" |
| 4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF | 4 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF |
| 5 | depends on ARCH_RENESAS || COMPILE_TEST | 5 | depends on ARCH_RENESAS || COMPILE_TEST |
| 6 | select RESET_CONTROLLER | ||
| 6 | select V4L2_FWNODE | 7 | select V4L2_FWNODE |
| 7 | help | 8 | help |
| 8 | Support for Renesas R-Car MIPI CSI-2 receiver. | 9 | Support for Renesas R-Car MIPI CSI-2 receiver. |
| @@ -17,7 +18,7 @@ config VIDEO_RCAR_VIN | |||
| 17 | depends on ARCH_RENESAS || COMPILE_TEST | 18 | depends on ARCH_RENESAS || COMPILE_TEST |
| 18 | select VIDEOBUF2_DMA_CONTIG | 19 | select VIDEOBUF2_DMA_CONTIG |
| 19 | select V4L2_FWNODE | 20 | select V4L2_FWNODE |
| 20 | ---help--- | 21 | help |
| 21 | Support for Renesas R-Car Video Input (VIN) driver. | 22 | Support for Renesas R-Car Video Input (VIN) driver. |
| 22 | Supports R-Car Gen2 and Gen3 SoCs. | 23 | Supports R-Car Gen2 and Gen3 SoCs. |
| 23 | 24 | ||
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 594d80434004..64f9cf790445 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c | |||
| @@ -546,7 +546,9 @@ static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier, | |||
| 546 | 546 | ||
| 547 | vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name); | 547 | vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name); |
| 548 | 548 | ||
| 549 | mutex_lock(&vin->lock); | ||
| 549 | rvin_parallel_subdevice_detach(vin); | 550 | rvin_parallel_subdevice_detach(vin); |
| 551 | mutex_unlock(&vin->lock); | ||
| 550 | } | 552 | } |
| 551 | 553 | ||
| 552 | static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier, | 554 | static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier, |
| @@ -556,7 +558,9 @@ static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier, | |||
| 556 | struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); | 558 | struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); |
| 557 | int ret; | 559 | int ret; |
| 558 | 560 | ||
| 561 | mutex_lock(&vin->lock); | ||
| 559 | ret = rvin_parallel_subdevice_attach(vin, subdev); | 562 | ret = rvin_parallel_subdevice_attach(vin, subdev); |
| 563 | mutex_unlock(&vin->lock); | ||
| 560 | if (ret) | 564 | if (ret) |
| 561 | return ret; | 565 | return ret; |
| 562 | 566 | ||
| @@ -664,6 +668,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) | |||
| 664 | } | 668 | } |
| 665 | 669 | ||
| 666 | /* Create all media device links between VINs and CSI-2's. */ | 670 | /* Create all media device links between VINs and CSI-2's. */ |
| 671 | mutex_lock(&vin->group->lock); | ||
| 667 | for (route = vin->info->routes; route->mask; route++) { | 672 | for (route = vin->info->routes; route->mask; route++) { |
| 668 | struct media_pad *source_pad, *sink_pad; | 673 | struct media_pad *source_pad, *sink_pad; |
| 669 | struct media_entity *source, *sink; | 674 | struct media_entity *source, *sink; |
| @@ -699,6 +704,7 @@ static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) | |||
| 699 | break; | 704 | break; |
| 700 | } | 705 | } |
| 701 | } | 706 | } |
| 707 | mutex_unlock(&vin->group->lock); | ||
| 702 | 708 | ||
| 703 | return ret; | 709 | return ret; |
| 704 | } | 710 | } |
| @@ -714,6 +720,8 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, | |||
| 714 | if (vin->group->vin[i]) | 720 | if (vin->group->vin[i]) |
| 715 | rvin_v4l2_unregister(vin->group->vin[i]); | 721 | rvin_v4l2_unregister(vin->group->vin[i]); |
| 716 | 722 | ||
| 723 | mutex_lock(&vin->group->lock); | ||
| 724 | |||
| 717 | for (i = 0; i < RVIN_CSI_MAX; i++) { | 725 | for (i = 0; i < RVIN_CSI_MAX; i++) { |
| 718 | if (vin->group->csi[i].fwnode != asd->match.fwnode) | 726 | if (vin->group->csi[i].fwnode != asd->match.fwnode) |
| 719 | continue; | 727 | continue; |
| @@ -721,6 +729,8 @@ static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, | |||
| 721 | vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i); | 729 | vin_dbg(vin, "Unbind CSI-2 %s from slot %u\n", subdev->name, i); |
| 722 | break; | 730 | break; |
| 723 | } | 731 | } |
| 732 | |||
| 733 | mutex_unlock(&vin->group->lock); | ||
| 724 | } | 734 | } |
| 725 | 735 | ||
| 726 | static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, | 736 | static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, |
| @@ -730,6 +740,8 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, | |||
| 730 | struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); | 740 | struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); |
| 731 | unsigned int i; | 741 | unsigned int i; |
| 732 | 742 | ||
| 743 | mutex_lock(&vin->group->lock); | ||
| 744 | |||
| 733 | for (i = 0; i < RVIN_CSI_MAX; i++) { | 745 | for (i = 0; i < RVIN_CSI_MAX; i++) { |
| 734 | if (vin->group->csi[i].fwnode != asd->match.fwnode) | 746 | if (vin->group->csi[i].fwnode != asd->match.fwnode) |
| 735 | continue; | 747 | continue; |
| @@ -738,6 +750,8 @@ static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, | |||
| 738 | break; | 750 | break; |
| 739 | } | 751 | } |
| 740 | 752 | ||
| 753 | mutex_unlock(&vin->group->lock); | ||
| 754 | |||
| 741 | return 0; | 755 | return 0; |
| 742 | } | 756 | } |
| 743 | 757 | ||
| @@ -752,6 +766,7 @@ static int rvin_mc_parse_of_endpoint(struct device *dev, | |||
| 752 | struct v4l2_async_subdev *asd) | 766 | struct v4l2_async_subdev *asd) |
| 753 | { | 767 | { |
| 754 | struct rvin_dev *vin = dev_get_drvdata(dev); | 768 | struct rvin_dev *vin = dev_get_drvdata(dev); |
| 769 | int ret = 0; | ||
| 755 | 770 | ||
| 756 | if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX) | 771 | if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX) |
| 757 | return -EINVAL; | 772 | return -EINVAL; |
| @@ -762,38 +777,48 @@ static int rvin_mc_parse_of_endpoint(struct device *dev, | |||
| 762 | return -ENOTCONN; | 777 | return -ENOTCONN; |
| 763 | } | 778 | } |
| 764 | 779 | ||
| 780 | mutex_lock(&vin->group->lock); | ||
| 781 | |||
| 765 | if (vin->group->csi[vep->base.id].fwnode) { | 782 | if (vin->group->csi[vep->base.id].fwnode) { |
| 766 | vin_dbg(vin, "OF device %pOF already handled\n", | 783 | vin_dbg(vin, "OF device %pOF already handled\n", |
| 767 | to_of_node(asd->match.fwnode)); | 784 | to_of_node(asd->match.fwnode)); |
| 768 | return -ENOTCONN; | 785 | ret = -ENOTCONN; |
| 786 | goto out; | ||
| 769 | } | 787 | } |
| 770 | 788 | ||
| 771 | vin->group->csi[vep->base.id].fwnode = asd->match.fwnode; | 789 | vin->group->csi[vep->base.id].fwnode = asd->match.fwnode; |
| 772 | 790 | ||
| 773 | vin_dbg(vin, "Add group OF device %pOF to slot %u\n", | 791 | vin_dbg(vin, "Add group OF device %pOF to slot %u\n", |
| 774 | to_of_node(asd->match.fwnode), vep->base.id); | 792 | to_of_node(asd->match.fwnode), vep->base.id); |
| 793 | out: | ||
| 794 | mutex_unlock(&vin->group->lock); | ||
| 775 | 795 | ||
| 776 | return 0; | 796 | return ret; |
| 777 | } | 797 | } |
| 778 | 798 | ||
| 779 | static int rvin_mc_parse_of_graph(struct rvin_dev *vin) | 799 | static int rvin_mc_parse_of_graph(struct rvin_dev *vin) |
| 780 | { | 800 | { |
| 781 | unsigned int count = 0; | 801 | unsigned int count = 0, vin_mask = 0; |
| 782 | unsigned int i; | 802 | unsigned int i; |
| 783 | int ret; | 803 | int ret; |
| 784 | 804 | ||
| 785 | mutex_lock(&vin->group->lock); | 805 | mutex_lock(&vin->group->lock); |
| 786 | 806 | ||
| 787 | /* If not all VIN's are registered don't register the notifier. */ | 807 | /* If not all VIN's are registered don't register the notifier. */ |
| 788 | for (i = 0; i < RCAR_VIN_NUM; i++) | 808 | for (i = 0; i < RCAR_VIN_NUM; i++) { |
| 789 | if (vin->group->vin[i]) | 809 | if (vin->group->vin[i]) { |
| 790 | count++; | 810 | count++; |
| 811 | vin_mask |= BIT(i); | ||
| 812 | } | ||
| 813 | } | ||
| 791 | 814 | ||
| 792 | if (vin->group->count != count) { | 815 | if (vin->group->count != count) { |
| 793 | mutex_unlock(&vin->group->lock); | 816 | mutex_unlock(&vin->group->lock); |
| 794 | return 0; | 817 | return 0; |
| 795 | } | 818 | } |
| 796 | 819 | ||
| 820 | mutex_unlock(&vin->group->lock); | ||
| 821 | |||
| 797 | v4l2_async_notifier_init(&vin->group->notifier); | 822 | v4l2_async_notifier_init(&vin->group->notifier); |
| 798 | 823 | ||
| 799 | /* | 824 | /* |
| @@ -802,21 +827,17 @@ static int rvin_mc_parse_of_graph(struct rvin_dev *vin) | |||
| 802 | * will only be registered once with the group notifier. | 827 | * will only be registered once with the group notifier. |
| 803 | */ | 828 | */ |
| 804 | for (i = 0; i < RCAR_VIN_NUM; i++) { | 829 | for (i = 0; i < RCAR_VIN_NUM; i++) { |
| 805 | if (!vin->group->vin[i]) | 830 | if (!(vin_mask & BIT(i))) |
| 806 | continue; | 831 | continue; |
| 807 | 832 | ||
| 808 | ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( | 833 | ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( |
| 809 | vin->group->vin[i]->dev, &vin->group->notifier, | 834 | vin->group->vin[i]->dev, &vin->group->notifier, |
| 810 | sizeof(struct v4l2_async_subdev), 1, | 835 | sizeof(struct v4l2_async_subdev), 1, |
| 811 | rvin_mc_parse_of_endpoint); | 836 | rvin_mc_parse_of_endpoint); |
| 812 | if (ret) { | 837 | if (ret) |
| 813 | mutex_unlock(&vin->group->lock); | ||
| 814 | return ret; | 838 | return ret; |
| 815 | } | ||
| 816 | } | 839 | } |
| 817 | 840 | ||
| 818 | mutex_unlock(&vin->group->lock); | ||
| 819 | |||
| 820 | if (list_empty(&vin->group->notifier.asd_list)) | 841 | if (list_empty(&vin->group->notifier.asd_list)) |
| 821 | return 0; | 842 | return 0; |
| 822 | 843 | ||
| @@ -1136,6 +1157,10 @@ static const struct rvin_info rcar_info_r8a77995 = { | |||
| 1136 | 1157 | ||
| 1137 | static const struct of_device_id rvin_of_id_table[] = { | 1158 | static const struct of_device_id rvin_of_id_table[] = { |
| 1138 | { | 1159 | { |
| 1160 | .compatible = "renesas,vin-r8a774a1", | ||
| 1161 | .data = &rcar_info_r8a7796, | ||
| 1162 | }, | ||
| 1163 | { | ||
| 1139 | .compatible = "renesas,vin-r8a774c0", | 1164 | .compatible = "renesas,vin-r8a774c0", |
| 1140 | .data = &rcar_info_r8a77990, | 1165 | .data = &rcar_info_r8a77990, |
| 1141 | }, | 1166 | }, |
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index f64528d2be3c..799e526fd3df 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/of_graph.h> | 14 | #include <linux/of_graph.h> |
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
| 17 | #include <linux/reset.h> | ||
| 17 | #include <linux/sys_soc.h> | 18 | #include <linux/sys_soc.h> |
| 18 | 19 | ||
| 19 | #include <media/v4l2-ctrls.h> | 20 | #include <media/v4l2-ctrls.h> |
| @@ -350,6 +351,7 @@ struct rcar_csi2 { | |||
| 350 | struct device *dev; | 351 | struct device *dev; |
| 351 | void __iomem *base; | 352 | void __iomem *base; |
| 352 | const struct rcar_csi2_info *info; | 353 | const struct rcar_csi2_info *info; |
| 354 | struct reset_control *rstc; | ||
| 353 | 355 | ||
| 354 | struct v4l2_subdev subdev; | 356 | struct v4l2_subdev subdev; |
| 355 | struct media_pad pads[NR_OF_RCAR_CSI2_PAD]; | 357 | struct media_pad pads[NR_OF_RCAR_CSI2_PAD]; |
| @@ -387,11 +389,19 @@ static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data) | |||
| 387 | iowrite32(data, priv->base + reg); | 389 | iowrite32(data, priv->base + reg); |
| 388 | } | 390 | } |
| 389 | 391 | ||
| 390 | static void rcsi2_reset(struct rcar_csi2 *priv) | 392 | static void rcsi2_enter_standby(struct rcar_csi2 *priv) |
| 391 | { | 393 | { |
| 392 | rcsi2_write(priv, SRST_REG, SRST_SRST); | 394 | rcsi2_write(priv, PHYCNT_REG, 0); |
| 395 | rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR); | ||
| 396 | reset_control_assert(priv->rstc); | ||
| 393 | usleep_range(100, 150); | 397 | usleep_range(100, 150); |
| 394 | rcsi2_write(priv, SRST_REG, 0); | 398 | pm_runtime_put(priv->dev); |
| 399 | } | ||
| 400 | |||
| 401 | static void rcsi2_exit_standby(struct rcar_csi2 *priv) | ||
| 402 | { | ||
| 403 | pm_runtime_get_sync(priv->dev); | ||
| 404 | reset_control_deassert(priv->rstc); | ||
| 395 | } | 405 | } |
| 396 | 406 | ||
| 397 | static int rcsi2_wait_phy_start(struct rcar_csi2 *priv) | 407 | static int rcsi2_wait_phy_start(struct rcar_csi2 *priv) |
| @@ -462,7 +472,7 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp) | |||
| 462 | return mbps; | 472 | return mbps; |
| 463 | } | 473 | } |
| 464 | 474 | ||
| 465 | static int rcsi2_start(struct rcar_csi2 *priv) | 475 | static int rcsi2_start_receiver(struct rcar_csi2 *priv) |
| 466 | { | 476 | { |
| 467 | const struct rcar_csi2_format *format; | 477 | const struct rcar_csi2_format *format; |
| 468 | u32 phycnt, vcdt = 0, vcdt2 = 0; | 478 | u32 phycnt, vcdt = 0, vcdt2 = 0; |
| @@ -506,12 +516,9 @@ static int rcsi2_start(struct rcar_csi2 *priv) | |||
| 506 | 516 | ||
| 507 | /* Init */ | 517 | /* Init */ |
| 508 | rcsi2_write(priv, TREF_REG, TREF_TREF); | 518 | rcsi2_write(priv, TREF_REG, TREF_TREF); |
| 509 | rcsi2_reset(priv); | ||
| 510 | rcsi2_write(priv, PHTC_REG, 0); | 519 | rcsi2_write(priv, PHTC_REG, 0); |
| 511 | 520 | ||
| 512 | /* Configure */ | 521 | /* Configure */ |
| 513 | rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 | | ||
| 514 | FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN); | ||
| 515 | rcsi2_write(priv, VCDT_REG, vcdt); | 522 | rcsi2_write(priv, VCDT_REG, vcdt); |
| 516 | if (vcdt2) | 523 | if (vcdt2) |
| 517 | rcsi2_write(priv, VCDT2_REG, vcdt2); | 524 | rcsi2_write(priv, VCDT2_REG, vcdt2); |
| @@ -542,6 +549,8 @@ static int rcsi2_start(struct rcar_csi2 *priv) | |||
| 542 | rcsi2_write(priv, PHYCNT_REG, phycnt); | 549 | rcsi2_write(priv, PHYCNT_REG, phycnt); |
| 543 | rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN | | 550 | rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN | |
| 544 | LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP); | 551 | LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP); |
| 552 | rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 | | ||
| 553 | FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN); | ||
| 545 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); | 554 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ); |
| 546 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); | 555 | rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ); |
| 547 | 556 | ||
| @@ -564,19 +573,36 @@ static int rcsi2_start(struct rcar_csi2 *priv) | |||
| 564 | return 0; | 573 | return 0; |
| 565 | } | 574 | } |
| 566 | 575 | ||
| 567 | static void rcsi2_stop(struct rcar_csi2 *priv) | 576 | static int rcsi2_start(struct rcar_csi2 *priv) |
| 568 | { | 577 | { |
| 569 | rcsi2_write(priv, PHYCNT_REG, 0); | 578 | int ret; |
| 570 | 579 | ||
| 571 | rcsi2_reset(priv); | 580 | rcsi2_exit_standby(priv); |
| 572 | 581 | ||
| 573 | rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR); | 582 | ret = rcsi2_start_receiver(priv); |
| 583 | if (ret) { | ||
| 584 | rcsi2_enter_standby(priv); | ||
| 585 | return ret; | ||
| 586 | } | ||
| 587 | |||
| 588 | ret = v4l2_subdev_call(priv->remote, video, s_stream, 1); | ||
| 589 | if (ret) { | ||
| 590 | rcsi2_enter_standby(priv); | ||
| 591 | return ret; | ||
| 592 | } | ||
| 593 | |||
| 594 | return 0; | ||
| 595 | } | ||
| 596 | |||
| 597 | static void rcsi2_stop(struct rcar_csi2 *priv) | ||
| 598 | { | ||
| 599 | rcsi2_enter_standby(priv); | ||
| 600 | v4l2_subdev_call(priv->remote, video, s_stream, 0); | ||
| 574 | } | 601 | } |
| 575 | 602 | ||
| 576 | static int rcsi2_s_stream(struct v4l2_subdev *sd, int enable) | 603 | static int rcsi2_s_stream(struct v4l2_subdev *sd, int enable) |
| 577 | { | 604 | { |
| 578 | struct rcar_csi2 *priv = sd_to_csi2(sd); | 605 | struct rcar_csi2 *priv = sd_to_csi2(sd); |
| 579 | struct v4l2_subdev *nextsd; | ||
| 580 | int ret = 0; | 606 | int ret = 0; |
| 581 | 607 | ||
| 582 | mutex_lock(&priv->lock); | 608 | mutex_lock(&priv->lock); |
| @@ -586,27 +612,12 @@ static int rcsi2_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 586 | goto out; | 612 | goto out; |
| 587 | } | 613 | } |
| 588 | 614 | ||
| 589 | nextsd = priv->remote; | ||
| 590 | |||
| 591 | if (enable && priv->stream_count == 0) { | 615 | if (enable && priv->stream_count == 0) { |
| 592 | pm_runtime_get_sync(priv->dev); | ||
| 593 | |||
| 594 | ret = rcsi2_start(priv); | 616 | ret = rcsi2_start(priv); |
| 595 | if (ret) { | 617 | if (ret) |
| 596 | pm_runtime_put(priv->dev); | ||
| 597 | goto out; | ||
| 598 | } | ||
| 599 | |||
| 600 | ret = v4l2_subdev_call(nextsd, video, s_stream, 1); | ||
| 601 | if (ret) { | ||
| 602 | rcsi2_stop(priv); | ||
| 603 | pm_runtime_put(priv->dev); | ||
| 604 | goto out; | 618 | goto out; |
| 605 | } | ||
| 606 | } else if (!enable && priv->stream_count == 1) { | 619 | } else if (!enable && priv->stream_count == 1) { |
| 607 | rcsi2_stop(priv); | 620 | rcsi2_stop(priv); |
| 608 | v4l2_subdev_call(nextsd, video, s_stream, 0); | ||
| 609 | pm_runtime_put(priv->dev); | ||
| 610 | } | 621 | } |
| 611 | 622 | ||
| 612 | priv->stream_count += enable ? 1 : -1; | 623 | priv->stream_count += enable ? 1 : -1; |
| @@ -854,7 +865,8 @@ static int rcsi2_phtw_write_mbps(struct rcar_csi2 *priv, unsigned int mbps, | |||
| 854 | return rcsi2_phtw_write(priv, value->reg, code); | 865 | return rcsi2_phtw_write(priv, value->reg, code); |
| 855 | } | 866 | } |
| 856 | 867 | ||
| 857 | static int rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, unsigned int mbps) | 868 | static int __rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, |
| 869 | unsigned int mbps) | ||
| 858 | { | 870 | { |
| 859 | static const struct phtw_value step1[] = { | 871 | static const struct phtw_value step1[] = { |
| 860 | { .data = 0xcc, .code = 0xe2 }, | 872 | { .data = 0xcc, .code = 0xe2 }, |
| @@ -880,7 +892,7 @@ static int rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, unsigned int mbps) | |||
| 880 | if (ret) | 892 | if (ret) |
| 881 | return ret; | 893 | return ret; |
| 882 | 894 | ||
| 883 | if (mbps <= 250) { | 895 | if (mbps != 0 && mbps <= 250) { |
| 884 | ret = rcsi2_phtw_write(priv, 0x39, 0x05); | 896 | ret = rcsi2_phtw_write(priv, 0x39, 0x05); |
| 885 | if (ret) | 897 | if (ret) |
| 886 | return ret; | 898 | return ret; |
| @@ -894,6 +906,16 @@ static int rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, unsigned int mbps) | |||
| 894 | return rcsi2_phtw_write_array(priv, step2); | 906 | return rcsi2_phtw_write_array(priv, step2); |
| 895 | } | 907 | } |
| 896 | 908 | ||
| 909 | static int rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, unsigned int mbps) | ||
| 910 | { | ||
| 911 | return __rcsi2_init_phtw_h3_v3h_m3n(priv, mbps); | ||
| 912 | } | ||
| 913 | |||
| 914 | static int rcsi2_init_phtw_h3es2(struct rcar_csi2 *priv, unsigned int mbps) | ||
| 915 | { | ||
| 916 | return __rcsi2_init_phtw_h3_v3h_m3n(priv, 0); | ||
| 917 | } | ||
| 918 | |||
| 897 | static int rcsi2_init_phtw_v3m_e3(struct rcar_csi2 *priv, unsigned int mbps) | 919 | static int rcsi2_init_phtw_v3m_e3(struct rcar_csi2 *priv, unsigned int mbps) |
| 898 | { | 920 | { |
| 899 | return rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_v3m_e3, 0x44); | 921 | return rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_v3m_e3, 0x44); |
| @@ -902,11 +924,11 @@ static int rcsi2_init_phtw_v3m_e3(struct rcar_csi2 *priv, unsigned int mbps) | |||
| 902 | static int rcsi2_confirm_start_v3m_e3(struct rcar_csi2 *priv) | 924 | static int rcsi2_confirm_start_v3m_e3(struct rcar_csi2 *priv) |
| 903 | { | 925 | { |
| 904 | static const struct phtw_value step1[] = { | 926 | static const struct phtw_value step1[] = { |
| 905 | { .data = 0xed, .code = 0x34 }, | 927 | { .data = 0xee, .code = 0x34 }, |
| 906 | { .data = 0xed, .code = 0x44 }, | 928 | { .data = 0xee, .code = 0x44 }, |
| 907 | { .data = 0xed, .code = 0x54 }, | 929 | { .data = 0xee, .code = 0x54 }, |
| 908 | { .data = 0xed, .code = 0x84 }, | 930 | { .data = 0xee, .code = 0x84 }, |
| 909 | { .data = 0xed, .code = 0x94 }, | 931 | { .data = 0xee, .code = 0x94 }, |
| 910 | { /* sentinel */ }, | 932 | { /* sentinel */ }, |
| 911 | }; | 933 | }; |
| 912 | 934 | ||
| @@ -936,6 +958,10 @@ static int rcsi2_probe_resources(struct rcar_csi2 *priv, | |||
| 936 | if (irq < 0) | 958 | if (irq < 0) |
| 937 | return irq; | 959 | return irq; |
| 938 | 960 | ||
| 961 | priv->rstc = devm_reset_control_get(&pdev->dev, NULL); | ||
| 962 | if (IS_ERR(priv->rstc)) | ||
| 963 | return PTR_ERR(priv->rstc); | ||
| 964 | |||
| 939 | return 0; | 965 | return 0; |
| 940 | } | 966 | } |
| 941 | 967 | ||
| @@ -952,6 +978,14 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = { | |||
| 952 | .num_channels = 4, | 978 | .num_channels = 4, |
| 953 | }; | 979 | }; |
| 954 | 980 | ||
| 981 | static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = { | ||
| 982 | .init_phtw = rcsi2_init_phtw_h3es2, | ||
| 983 | .hsfreqrange = hsfreqrange_h3_v3h_m3n, | ||
| 984 | .csi0clkfreqrange = 0x20, | ||
| 985 | .num_channels = 4, | ||
| 986 | .clear_ulps = true, | ||
| 987 | }; | ||
| 988 | |||
| 955 | static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { | 989 | static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { |
| 956 | .hsfreqrange = hsfreqrange_m3w_h3es1, | 990 | .hsfreqrange = hsfreqrange_m3w_h3es1, |
| 957 | .num_channels = 4, | 991 | .num_channels = 4, |
| @@ -986,6 +1020,10 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { | |||
| 986 | 1020 | ||
| 987 | static const struct of_device_id rcar_csi2_of_table[] = { | 1021 | static const struct of_device_id rcar_csi2_of_table[] = { |
| 988 | { | 1022 | { |
| 1023 | .compatible = "renesas,r8a774a1-csi2", | ||
| 1024 | .data = &rcar_csi2_info_r8a7796, | ||
| 1025 | }, | ||
| 1026 | { | ||
| 989 | .compatible = "renesas,r8a774c0-csi2", | 1027 | .compatible = "renesas,r8a774c0-csi2", |
| 990 | .data = &rcar_csi2_info_r8a77990, | 1028 | .data = &rcar_csi2_info_r8a77990, |
| 991 | }, | 1029 | }, |
| @@ -1017,11 +1055,15 @@ static const struct of_device_id rcar_csi2_of_table[] = { | |||
| 1017 | }; | 1055 | }; |
| 1018 | MODULE_DEVICE_TABLE(of, rcar_csi2_of_table); | 1056 | MODULE_DEVICE_TABLE(of, rcar_csi2_of_table); |
| 1019 | 1057 | ||
| 1020 | static const struct soc_device_attribute r8a7795es1[] = { | 1058 | static const struct soc_device_attribute r8a7795[] = { |
| 1021 | { | 1059 | { |
| 1022 | .soc_id = "r8a7795", .revision = "ES1.*", | 1060 | .soc_id = "r8a7795", .revision = "ES1.*", |
| 1023 | .data = &rcar_csi2_info_r8a7795es1, | 1061 | .data = &rcar_csi2_info_r8a7795es1, |
| 1024 | }, | 1062 | }, |
| 1063 | { | ||
| 1064 | .soc_id = "r8a7795", .revision = "ES2.*", | ||
| 1065 | .data = &rcar_csi2_info_r8a7795es2, | ||
| 1066 | }, | ||
| 1025 | { /* sentinel */ }, | 1067 | { /* sentinel */ }, |
| 1026 | }; | 1068 | }; |
| 1027 | 1069 | ||
| @@ -1039,10 +1081,10 @@ static int rcsi2_probe(struct platform_device *pdev) | |||
| 1039 | priv->info = of_device_get_match_data(&pdev->dev); | 1081 | priv->info = of_device_get_match_data(&pdev->dev); |
| 1040 | 1082 | ||
| 1041 | /* | 1083 | /* |
| 1042 | * r8a7795 ES1.x behaves differently than the ES2.0+ but doesn't | 1084 | * The different ES versions of r8a7795 (H3) behave differently but |
| 1043 | * have it's own compatible string. | 1085 | * share the same compatible string. |
| 1044 | */ | 1086 | */ |
| 1045 | attr = soc_device_match(r8a7795es1); | 1087 | attr = soc_device_match(r8a7795); |
| 1046 | if (attr) | 1088 | if (attr) |
| 1047 | priv->info = attr->data; | 1089 | priv->info = attr->data; |
| 1048 | 1090 | ||
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 2207a31d355e..91ab064404a1 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c | |||
| @@ -486,7 +486,7 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs) | |||
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | /* Use previous value if its XS value is closer */ | 488 | /* Use previous value if its XS value is closer */ |
| 489 | if (p_prev_set && p_set && | 489 | if (p_prev_set && |
| 490 | xs - p_prev_set->xs_value < p_set->xs_value - xs) | 490 | xs - p_prev_set->xs_value < p_set->xs_value - xs) |
| 491 | p_set = p_prev_set; | 491 | p_set = p_prev_set; |
| 492 | 492 | ||
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c index c417ff8f6fe5..608e5217ccd5 100644 --- a/drivers/media/platform/rcar_drif.c +++ b/drivers/media/platform/rcar_drif.c | |||
| @@ -1405,11 +1405,9 @@ static int rcar_drif_probe(struct platform_device *pdev) | |||
| 1405 | /* Register map */ | 1405 | /* Register map */ |
| 1406 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1406 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1407 | ch->base = devm_ioremap_resource(&pdev->dev, res); | 1407 | ch->base = devm_ioremap_resource(&pdev->dev, res); |
| 1408 | if (IS_ERR(ch->base)) { | 1408 | if (IS_ERR(ch->base)) |
| 1409 | ret = PTR_ERR(ch->base); | 1409 | return PTR_ERR(ch->base); |
| 1410 | dev_err(&pdev->dev, "ioremap failed (%d)\n", ret); | 1410 | |
| 1411 | return ret; | ||
| 1412 | } | ||
| 1413 | ch->start = res->start; | 1411 | ch->start = res->start; |
| 1414 | platform_set_drvdata(pdev, ch); | 1412 | platform_set_drvdata(pdev, ch); |
| 1415 | 1413 | ||
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 6bda1eee9170..6a90bc4c476e 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c | |||
| @@ -945,7 +945,7 @@ static void fdp1_configure_wpf(struct fdp1_ctx *ctx, | |||
| 945 | u32 rndctl; | 945 | u32 rndctl; |
| 946 | 946 | ||
| 947 | pstride = q_data->format.plane_fmt[0].bytesperline | 947 | pstride = q_data->format.plane_fmt[0].bytesperline |
| 948 | << FD1_WPF_PSTRIDE_Y_SHIFT; | 948 | << FD1_WPF_PSTRIDE_Y_SHIFT; |
| 949 | 949 | ||
| 950 | if (q_data->format.num_planes > 1) | 950 | if (q_data->format.num_planes > 1) |
| 951 | pstride |= q_data->format.plane_fmt[1].bytesperline | 951 | pstride |= q_data->format.plane_fmt[1].bytesperline |
| @@ -1139,8 +1139,8 @@ static int fdp1_m2m_job_ready(void *priv) | |||
| 1139 | int dstbufs = 1; | 1139 | int dstbufs = 1; |
| 1140 | 1140 | ||
| 1141 | dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n", | 1141 | dprintk(ctx->fdp1, "+ Src: %d : Dst: %d\n", |
| 1142 | v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx), | 1142 | v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx), |
| 1143 | v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)); | 1143 | v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)); |
| 1144 | 1144 | ||
| 1145 | /* One output buffer is required for each field */ | 1145 | /* One output buffer is required for each field */ |
| 1146 | if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) | 1146 | if (V4L2_FIELD_HAS_BOTH(src_q_data->format.field)) |
| @@ -1278,7 +1278,7 @@ static void fdp1_m2m_device_run(void *priv) | |||
| 1278 | 1278 | ||
| 1279 | fdp1_queue_field(ctx, fbuf); | 1279 | fdp1_queue_field(ctx, fbuf); |
| 1280 | dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n", | 1280 | dprintk(fdp1, "Queued Buffer [%d] last_field:%d\n", |
| 1281 | i, fbuf->last_field); | 1281 | i, fbuf->last_field); |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | /* Queue as many jobs as our data provides for */ | 1284 | /* Queue as many jobs as our data provides for */ |
| @@ -1337,7 +1337,7 @@ static void device_frame_end(struct fdp1_dev *fdp1, | |||
| 1337 | fdp1_job_free(fdp1, job); | 1337 | fdp1_job_free(fdp1, job); |
| 1338 | 1338 | ||
| 1339 | dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n", | 1339 | dprintk(fdp1, "curr_ctx->num_processed %d curr_ctx->translen %d\n", |
| 1340 | ctx->num_processed, ctx->translen); | 1340 | ctx->num_processed, ctx->translen); |
| 1341 | 1341 | ||
| 1342 | if (ctx->num_processed == ctx->translen || | 1342 | if (ctx->num_processed == ctx->translen || |
| 1343 | ctx->aborting) { | 1343 | ctx->aborting) { |
| @@ -1362,7 +1362,7 @@ static int fdp1_vidioc_querycap(struct file *file, void *priv, | |||
| 1362 | strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); | 1362 | strscpy(cap->driver, DRIVER_NAME, sizeof(cap->driver)); |
| 1363 | strscpy(cap->card, DRIVER_NAME, sizeof(cap->card)); | 1363 | strscpy(cap->card, DRIVER_NAME, sizeof(cap->card)); |
| 1364 | snprintf(cap->bus_info, sizeof(cap->bus_info), | 1364 | snprintf(cap->bus_info, sizeof(cap->bus_info), |
| 1365 | "platform:%s", DRIVER_NAME); | 1365 | "platform:%s", DRIVER_NAME); |
| 1366 | return 0; | 1366 | return 0; |
| 1367 | } | 1367 | } |
| 1368 | 1368 | ||
| @@ -1993,13 +1993,13 @@ static void fdp1_stop_streaming(struct vb2_queue *q) | |||
| 1993 | /* Free smsk_data */ | 1993 | /* Free smsk_data */ |
| 1994 | if (ctx->smsk_cpu) { | 1994 | if (ctx->smsk_cpu) { |
| 1995 | dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size, | 1995 | dma_free_coherent(ctx->fdp1->dev, ctx->smsk_size, |
| 1996 | ctx->smsk_cpu, ctx->smsk_addr[0]); | 1996 | ctx->smsk_cpu, ctx->smsk_addr[0]); |
| 1997 | ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0; | 1997 | ctx->smsk_addr[0] = ctx->smsk_addr[1] = 0; |
| 1998 | ctx->smsk_cpu = NULL; | 1998 | ctx->smsk_cpu = NULL; |
| 1999 | } | 1999 | } |
| 2000 | 2000 | ||
| 2001 | WARN(!list_empty(&ctx->fields_queue), | 2001 | WARN(!list_empty(&ctx->fields_queue), |
| 2002 | "Buffer queue not empty"); | 2002 | "Buffer queue not empty"); |
| 2003 | } else { | 2003 | } else { |
| 2004 | /* Empty Capture queues (Jobs) */ | 2004 | /* Empty Capture queues (Jobs) */ |
| 2005 | struct fdp1_job *job; | 2005 | struct fdp1_job *job; |
| @@ -2021,10 +2021,10 @@ static void fdp1_stop_streaming(struct vb2_queue *q) | |||
| 2021 | fdp1_field_complete(ctx, ctx->previous); | 2021 | fdp1_field_complete(ctx, ctx->previous); |
| 2022 | 2022 | ||
| 2023 | WARN(!list_empty(&ctx->fdp1->queued_job_list), | 2023 | WARN(!list_empty(&ctx->fdp1->queued_job_list), |
| 2024 | "Queued Job List not empty"); | 2024 | "Queued Job List not empty"); |
| 2025 | 2025 | ||
| 2026 | WARN(!list_empty(&ctx->fdp1->hw_job_list), | 2026 | WARN(!list_empty(&ctx->fdp1->hw_job_list), |
| 2027 | "HW Job list not empty"); | 2027 | "HW Job list not empty"); |
| 2028 | } | 2028 | } |
| 2029 | } | 2029 | } |
| 2030 | 2030 | ||
| @@ -2110,7 +2110,7 @@ static int fdp1_open(struct file *file) | |||
| 2110 | fdp1_ctrl_deint_menu); | 2110 | fdp1_ctrl_deint_menu); |
| 2111 | 2111 | ||
| 2112 | ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, | 2112 | ctrl = v4l2_ctrl_new_std(&ctx->hdl, &fdp1_ctrl_ops, |
| 2113 | V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1); | 2113 | V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 2, 1, 1); |
| 2114 | if (ctrl) | 2114 | if (ctrl) |
| 2115 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; | 2115 | ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; |
| 2116 | 2116 | ||
| @@ -2347,8 +2347,8 @@ static int fdp1_probe(struct platform_device *pdev) | |||
| 2347 | goto release_m2m; | 2347 | goto release_m2m; |
| 2348 | } | 2348 | } |
| 2349 | 2349 | ||
| 2350 | v4l2_info(&fdp1->v4l2_dev, | 2350 | v4l2_info(&fdp1->v4l2_dev, "Device registered as /dev/video%d\n", |
| 2351 | "Device registered as /dev/video%d\n", vfd->num); | 2351 | vfd->num); |
| 2352 | 2352 | ||
| 2353 | /* Power up the cells to read HW */ | 2353 | /* Power up the cells to read HW */ |
| 2354 | pm_runtime_enable(&pdev->dev); | 2354 | pm_runtime_enable(&pdev->dev); |
| @@ -2367,7 +2367,7 @@ static int fdp1_probe(struct platform_device *pdev) | |||
| 2367 | break; | 2367 | break; |
| 2368 | default: | 2368 | default: |
| 2369 | dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n", | 2369 | dev_err(fdp1->dev, "FDP1 Unidentifiable (0x%08x)\n", |
| 2370 | hw_version); | 2370 | hw_version); |
| 2371 | } | 2371 | } |
| 2372 | 2372 | ||
| 2373 | /* Allow the hw to sleep until an open call puts it to use */ | 2373 | /* Allow the hw to sleep until an open call puts it to use */ |
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c index 8837e2678bde..7f62f5ef0086 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.c +++ b/drivers/media/platform/s5p-cec/s5p_cec.c | |||
| @@ -178,22 +178,16 @@ static const struct cec_adap_ops s5p_cec_adap_ops = { | |||
| 178 | static int s5p_cec_probe(struct platform_device *pdev) | 178 | static int s5p_cec_probe(struct platform_device *pdev) |
| 179 | { | 179 | { |
| 180 | struct device *dev = &pdev->dev; | 180 | struct device *dev = &pdev->dev; |
| 181 | struct device_node *np; | 181 | struct device *hdmi_dev; |
| 182 | struct platform_device *hdmi_dev; | ||
| 183 | struct resource *res; | 182 | struct resource *res; |
| 184 | struct s5p_cec_dev *cec; | 183 | struct s5p_cec_dev *cec; |
| 185 | bool needs_hpd = of_property_read_bool(pdev->dev.of_node, "needs-hpd"); | 184 | bool needs_hpd = of_property_read_bool(pdev->dev.of_node, "needs-hpd"); |
| 186 | int ret; | 185 | int ret; |
| 187 | 186 | ||
| 188 | np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); | 187 | hdmi_dev = cec_notifier_parse_hdmi_phandle(dev); |
| 189 | 188 | ||
| 190 | if (!np) { | 189 | if (IS_ERR(hdmi_dev)) |
| 191 | dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n"); | 190 | return PTR_ERR(hdmi_dev); |
| 192 | return -ENODEV; | ||
| 193 | } | ||
| 194 | hdmi_dev = of_find_device_by_node(np); | ||
| 195 | if (hdmi_dev == NULL) | ||
| 196 | return -EPROBE_DEFER; | ||
| 197 | 191 | ||
| 198 | cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL); | 192 | cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL); |
| 199 | if (!cec) | 193 | if (!cec) |
| @@ -224,7 +218,7 @@ static int s5p_cec_probe(struct platform_device *pdev) | |||
| 224 | if (IS_ERR(cec->reg)) | 218 | if (IS_ERR(cec->reg)) |
| 225 | return PTR_ERR(cec->reg); | 219 | return PTR_ERR(cec->reg); |
| 226 | 220 | ||
| 227 | cec->notifier = cec_notifier_get(&hdmi_dev->dev); | 221 | cec->notifier = cec_notifier_get(hdmi_dev); |
| 228 | if (cec->notifier == NULL) | 222 | if (cec->notifier == NULL) |
| 229 | return -ENOMEM; | 223 | return -ENOMEM; |
| 230 | 224 | ||
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 971c47165010..c8f394e1aff4 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c | |||
| @@ -297,8 +297,8 @@ static int g2d_release(struct file *file) | |||
| 297 | static int vidioc_querycap(struct file *file, void *priv, | 297 | static int vidioc_querycap(struct file *file, void *priv, |
| 298 | struct v4l2_capability *cap) | 298 | struct v4l2_capability *cap) |
| 299 | { | 299 | { |
| 300 | strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1); | 300 | strscpy(cap->driver, G2D_NAME, sizeof(cap->driver)); |
| 301 | strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1); | 301 | strscpy(cap->card, G2D_NAME, sizeof(cap->card)); |
| 302 | cap->bus_info[0] = 0; | 302 | cap->bus_info[0] = 0; |
| 303 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | 303 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; |
| 304 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 304 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
| @@ -312,7 +312,7 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) | |||
| 312 | return -EINVAL; | 312 | return -EINVAL; |
| 313 | fmt = &formats[f->index]; | 313 | fmt = &formats[f->index]; |
| 314 | f->pixelformat = fmt->fourcc; | 314 | f->pixelformat = fmt->fourcc; |
| 315 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 315 | strscpy(f->description, fmt->name, sizeof(f->description)); |
| 316 | return 0; | 316 | return 0; |
| 317 | } | 317 | } |
| 318 | 318 | ||
diff --git a/drivers/media/platform/seco-cec/seco-cec.c b/drivers/media/platform/seco-cec/seco-cec.c index a425a10540c1..e5080d6f5b2d 100644 --- a/drivers/media/platform/seco-cec/seco-cec.c +++ b/drivers/media/platform/seco-cec/seco-cec.c | |||
| @@ -536,6 +536,7 @@ static int secocec_cec_get_notifier(struct cec_notifier **notify) | |||
| 536 | return -EPROBE_DEFER; | 536 | return -EPROBE_DEFER; |
| 537 | 537 | ||
| 538 | *notify = cec_notifier_get_conn(d, m->conn); | 538 | *notify = cec_notifier_get_conn(d, m->conn); |
| 539 | put_device(d); | ||
| 539 | 540 | ||
| 540 | return 0; | 541 | return 0; |
| 541 | } | 542 | } |
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index d277cc674349..5a9ba05c996e 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c | |||
| @@ -493,9 +493,6 @@ static int sh_veu_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 493 | const struct sh_veu_format *fmt; | 493 | const struct sh_veu_format *fmt; |
| 494 | 494 | ||
| 495 | fmt = sh_veu_find_fmt(f); | 495 | fmt = sh_veu_find_fmt(f); |
| 496 | if (!fmt) | ||
| 497 | /* wrong buffer type */ | ||
| 498 | return -EINVAL; | ||
| 499 | 496 | ||
| 500 | return sh_veu_try_fmt(f, fmt); | 497 | return sh_veu_try_fmt(f, fmt); |
| 501 | } | 498 | } |
| @@ -506,9 +503,6 @@ static int sh_veu_try_fmt_vid_out(struct file *file, void *priv, | |||
| 506 | const struct sh_veu_format *fmt; | 503 | const struct sh_veu_format *fmt; |
| 507 | 504 | ||
| 508 | fmt = sh_veu_find_fmt(f); | 505 | fmt = sh_veu_find_fmt(f); |
| 509 | if (!fmt) | ||
| 510 | /* wrong buffer type */ | ||
| 511 | return -EINVAL; | ||
| 512 | 506 | ||
| 513 | return sh_veu_try_fmt(f, fmt); | 507 | return sh_veu_try_fmt(f, fmt); |
| 514 | } | 508 | } |
diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig index 7420a50572d3..93eaabfd5437 100644 --- a/drivers/media/platform/sti/c8sectpfe/Kconfig +++ b/drivers/media/platform/sti/c8sectpfe/Kconfig | |||
| @@ -12,7 +12,7 @@ config DVB_C8SECTPFE | |||
| 12 | select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT | 12 | select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT |
| 13 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT | 13 | select MEDIA_TUNER_TDA18212 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | 14 | ||
| 15 | ---help--- | 15 | help |
| 16 | This adds support for DVB front-end cards connected | 16 | This adds support for DVB front-end cards connected |
| 17 | to TS inputs of STiH407/410 SoC. | 17 | to TS inputs of STiH407/410 SoC. |
| 18 | 18 | ||
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c index d34099f75990..fc37efe1d554 100644 --- a/drivers/media/platform/sti/cec/stih-cec.c +++ b/drivers/media/platform/sti/cec/stih-cec.c | |||
| @@ -301,26 +301,19 @@ static int stih_cec_probe(struct platform_device *pdev) | |||
| 301 | struct device *dev = &pdev->dev; | 301 | struct device *dev = &pdev->dev; |
| 302 | struct resource *res; | 302 | struct resource *res; |
| 303 | struct stih_cec *cec; | 303 | struct stih_cec *cec; |
| 304 | struct device_node *np; | 304 | struct device *hdmi_dev; |
| 305 | struct platform_device *hdmi_dev; | ||
| 306 | int ret; | 305 | int ret; |
| 307 | 306 | ||
| 307 | hdmi_dev = cec_notifier_parse_hdmi_phandle(dev); | ||
| 308 | |||
| 309 | if (IS_ERR(hdmi_dev)) | ||
| 310 | return PTR_ERR(hdmi_dev); | ||
| 311 | |||
| 308 | cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL); | 312 | cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL); |
| 309 | if (!cec) | 313 | if (!cec) |
| 310 | return -ENOMEM; | 314 | return -ENOMEM; |
| 311 | 315 | ||
| 312 | np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); | 316 | cec->notifier = cec_notifier_get(hdmi_dev); |
| 313 | |||
| 314 | if (!np) { | ||
| 315 | dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n"); | ||
| 316 | return -ENODEV; | ||
| 317 | } | ||
| 318 | |||
| 319 | hdmi_dev = of_find_device_by_node(np); | ||
| 320 | if (!hdmi_dev) | ||
| 321 | return -EPROBE_DEFER; | ||
| 322 | |||
| 323 | cec->notifier = cec_notifier_get(&hdmi_dev->dev); | ||
| 324 | if (!cec->notifier) | 317 | if (!cec->notifier) |
| 325 | return -ENOMEM; | 318 | return -ENOMEM; |
| 326 | 319 | ||
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c index a4603d573c34..186d88f02ecd 100644 --- a/drivers/media/platform/sti/delta/delta-ipc.c +++ b/drivers/media/platform/sti/delta/delta-ipc.c | |||
| @@ -220,10 +220,8 @@ int delta_ipc_open(struct delta_ctx *pctx, const char *name, | |||
| 220 | 220 | ||
| 221 | err: | 221 | err: |
| 222 | pctx->sys_errors++; | 222 | pctx->sys_errors++; |
| 223 | if (ctx->ipc_buf) { | 223 | hw_free(pctx, ctx->ipc_buf); |
| 224 | hw_free(pctx, ctx->ipc_buf); | 224 | ctx->ipc_buf = NULL; |
| 225 | ctx->ipc_buf = NULL; | ||
| 226 | } | ||
| 227 | 225 | ||
| 228 | return ret; | 226 | return ret; |
| 229 | }; | 227 | }; |
diff --git a/drivers/media/platform/stm32/stm32-cec.c b/drivers/media/platform/stm32/stm32-cec.c index 7c496bc1cf38..8a86b2cc22fa 100644 --- a/drivers/media/platform/stm32/stm32-cec.c +++ b/drivers/media/platform/stm32/stm32-cec.c | |||
| @@ -56,6 +56,13 @@ | |||
| 56 | #define ALL_TX_IT (TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST) | 56 | #define ALL_TX_IT (TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST) |
| 57 | #define ALL_RX_IT (RXEND | RXBR | RXACKE | RXOVR) | 57 | #define ALL_RX_IT (RXEND | RXBR | RXACKE | RXOVR) |
| 58 | 58 | ||
| 59 | /* | ||
| 60 | * 400 ms is the time it takes for one 16 byte message to be | ||
| 61 | * transferred and 5 is the maximum number of retries. Add | ||
| 62 | * another 100 ms as a margin. | ||
| 63 | */ | ||
| 64 | #define CEC_XFER_TIMEOUT_MS (5 * 400 + 100) | ||
| 65 | |||
| 59 | struct stm32_cec { | 66 | struct stm32_cec { |
| 60 | struct cec_adapter *adap; | 67 | struct cec_adapter *adap; |
| 61 | struct device *dev; | 68 | struct device *dev; |
| @@ -188,7 +195,11 @@ static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr) | |||
| 188 | { | 195 | { |
| 189 | struct stm32_cec *cec = adap->priv; | 196 | struct stm32_cec *cec = adap->priv; |
| 190 | u32 oar = (1 << logical_addr) << 16; | 197 | u32 oar = (1 << logical_addr) << 16; |
| 198 | u32 val; | ||
| 191 | 199 | ||
| 200 | /* Poll every 100µs the register CEC_CR to wait end of transmission */ | ||
| 201 | regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM), | ||
| 202 | 100, CEC_XFER_TIMEOUT_MS * 1000); | ||
| 192 | regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0); | 203 | regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0); |
| 193 | 204 | ||
| 194 | if (logical_addr == CEC_LOG_ADDR_INVALID) | 205 | if (logical_addr == CEC_LOG_ADDR_INVALID) |
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 5fe5b38fa901..b9dad0accd1b 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c | |||
| @@ -97,6 +97,8 @@ enum state { | |||
| 97 | 97 | ||
| 98 | #define TIMEOUT_MS 1000 | 98 | #define TIMEOUT_MS 1000 |
| 99 | 99 | ||
| 100 | #define OVERRUN_ERROR_THRESHOLD 3 | ||
| 101 | |||
| 100 | struct dcmi_graph_entity { | 102 | struct dcmi_graph_entity { |
| 101 | struct device_node *node; | 103 | struct device_node *node; |
| 102 | 104 | ||
| @@ -164,6 +166,9 @@ struct stm32_dcmi { | |||
| 164 | int errors_count; | 166 | int errors_count; |
| 165 | int overrun_count; | 167 | int overrun_count; |
| 166 | int buffers_count; | 168 | int buffers_count; |
| 169 | |||
| 170 | /* Ensure DMA operations atomicity */ | ||
| 171 | struct mutex dma_lock; | ||
| 167 | }; | 172 | }; |
| 168 | 173 | ||
| 169 | static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) | 174 | static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) |
| @@ -314,6 +319,13 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, | |||
| 314 | return ret; | 319 | return ret; |
| 315 | } | 320 | } |
| 316 | 321 | ||
| 322 | /* | ||
| 323 | * Avoid call of dmaengine_terminate_all() between | ||
| 324 | * dmaengine_prep_slave_single() and dmaengine_submit() | ||
| 325 | * by locking the whole DMA submission sequence | ||
| 326 | */ | ||
| 327 | mutex_lock(&dcmi->dma_lock); | ||
| 328 | |||
| 317 | /* Prepare a DMA transaction */ | 329 | /* Prepare a DMA transaction */ |
| 318 | desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr, | 330 | desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr, |
| 319 | buf->size, | 331 | buf->size, |
| @@ -322,6 +334,7 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, | |||
| 322 | if (!desc) { | 334 | if (!desc) { |
| 323 | dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n", | 335 | dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n", |
| 324 | __func__, &buf->paddr, buf->size); | 336 | __func__, &buf->paddr, buf->size); |
| 337 | mutex_unlock(&dcmi->dma_lock); | ||
| 325 | return -EINVAL; | 338 | return -EINVAL; |
| 326 | } | 339 | } |
| 327 | 340 | ||
| @@ -333,9 +346,12 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi, | |||
| 333 | dcmi->dma_cookie = dmaengine_submit(desc); | 346 | dcmi->dma_cookie = dmaengine_submit(desc); |
| 334 | if (dma_submit_error(dcmi->dma_cookie)) { | 347 | if (dma_submit_error(dcmi->dma_cookie)) { |
| 335 | dev_err(dcmi->dev, "%s: DMA submission failed\n", __func__); | 348 | dev_err(dcmi->dev, "%s: DMA submission failed\n", __func__); |
| 349 | mutex_unlock(&dcmi->dma_lock); | ||
| 336 | return -ENXIO; | 350 | return -ENXIO; |
| 337 | } | 351 | } |
| 338 | 352 | ||
| 353 | mutex_unlock(&dcmi->dma_lock); | ||
| 354 | |||
| 339 | dma_async_issue_pending(dcmi->dma_chan); | 355 | dma_async_issue_pending(dcmi->dma_chan); |
| 340 | 356 | ||
| 341 | return 0; | 357 | return 0; |
| @@ -432,11 +448,13 @@ static irqreturn_t dcmi_irq_thread(int irq, void *arg) | |||
| 432 | 448 | ||
| 433 | spin_lock_irq(&dcmi->irqlock); | 449 | spin_lock_irq(&dcmi->irqlock); |
| 434 | 450 | ||
| 435 | if ((dcmi->misr & IT_OVR) || (dcmi->misr & IT_ERR)) { | 451 | if (dcmi->misr & IT_OVR) { |
| 436 | dcmi->errors_count++; | 452 | dcmi->overrun_count++; |
| 437 | if (dcmi->misr & IT_OVR) | 453 | if (dcmi->overrun_count > OVERRUN_ERROR_THRESHOLD) |
| 438 | dcmi->overrun_count++; | 454 | dcmi->errors_count++; |
| 439 | } | 455 | } |
| 456 | if (dcmi->misr & IT_ERR) | ||
| 457 | dcmi->errors_count++; | ||
| 440 | 458 | ||
| 441 | if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG && | 459 | if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG && |
| 442 | dcmi->misr & IT_FRAME) { | 460 | dcmi->misr & IT_FRAME) { |
| @@ -570,9 +588,9 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 570 | int ret; | 588 | int ret; |
| 571 | 589 | ||
| 572 | ret = pm_runtime_get_sync(dcmi->dev); | 590 | ret = pm_runtime_get_sync(dcmi->dev); |
| 573 | if (ret) { | 591 | if (ret < 0) { |
| 574 | dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync\n", | 592 | dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync (%d)\n", |
| 575 | __func__); | 593 | __func__, ret); |
| 576 | goto err_release_buffers; | 594 | goto err_release_buffers; |
| 577 | } | 595 | } |
| 578 | 596 | ||
| @@ -720,7 +738,9 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) | |||
| 720 | spin_unlock_irq(&dcmi->irqlock); | 738 | spin_unlock_irq(&dcmi->irqlock); |
| 721 | 739 | ||
| 722 | /* Stop all pending DMA operations */ | 740 | /* Stop all pending DMA operations */ |
| 741 | mutex_lock(&dcmi->dma_lock); | ||
| 723 | dmaengine_terminate_all(dcmi->dma_chan); | 742 | dmaengine_terminate_all(dcmi->dma_chan); |
| 743 | mutex_unlock(&dcmi->dma_lock); | ||
| 724 | 744 | ||
| 725 | pm_runtime_put(dcmi->dev); | 745 | pm_runtime_put(dcmi->dev); |
| 726 | 746 | ||
| @@ -811,6 +831,9 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, | |||
| 811 | 831 | ||
| 812 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); | 832 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); |
| 813 | if (!sd_fmt) { | 833 | if (!sd_fmt) { |
| 834 | if (!dcmi->num_of_sd_formats) | ||
| 835 | return -ENODATA; | ||
| 836 | |||
| 814 | sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; | 837 | sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; |
| 815 | pix->pixelformat = sd_fmt->fourcc; | 838 | pix->pixelformat = sd_fmt->fourcc; |
| 816 | } | 839 | } |
| @@ -989,6 +1012,9 @@ static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi, | |||
| 989 | 1012 | ||
| 990 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); | 1013 | sd_fmt = find_format_by_fourcc(dcmi, pix->pixelformat); |
| 991 | if (!sd_fmt) { | 1014 | if (!sd_fmt) { |
| 1015 | if (!dcmi->num_of_sd_formats) | ||
| 1016 | return -ENODATA; | ||
| 1017 | |||
| 992 | sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; | 1018 | sd_fmt = dcmi->sd_formats[dcmi->num_of_sd_formats - 1]; |
| 993 | pix->pixelformat = sd_fmt->fourcc; | 1019 | pix->pixelformat = sd_fmt->fourcc; |
| 994 | } | 1020 | } |
| @@ -1595,7 +1621,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) | |||
| 1595 | /* Parse the graph to extract a list of subdevice DT nodes. */ | 1621 | /* Parse the graph to extract a list of subdevice DT nodes. */ |
| 1596 | ret = dcmi_graph_parse(dcmi, dcmi->dev->of_node); | 1622 | ret = dcmi_graph_parse(dcmi, dcmi->dev->of_node); |
| 1597 | if (ret < 0) { | 1623 | if (ret < 0) { |
| 1598 | dev_err(dcmi->dev, "Graph parsing failed\n"); | 1624 | dev_err(dcmi->dev, "Failed to parse graph\n"); |
| 1599 | return ret; | 1625 | return ret; |
| 1600 | } | 1626 | } |
| 1601 | 1627 | ||
| @@ -1604,6 +1630,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) | |||
| 1604 | ret = v4l2_async_notifier_add_subdev(&dcmi->notifier, | 1630 | ret = v4l2_async_notifier_add_subdev(&dcmi->notifier, |
| 1605 | &dcmi->entity.asd); | 1631 | &dcmi->entity.asd); |
| 1606 | if (ret) { | 1632 | if (ret) { |
| 1633 | dev_err(dcmi->dev, "Failed to add subdev notifier\n"); | ||
| 1607 | of_node_put(dcmi->entity.node); | 1634 | of_node_put(dcmi->entity.node); |
| 1608 | return ret; | 1635 | return ret; |
| 1609 | } | 1636 | } |
| @@ -1612,7 +1639,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) | |||
| 1612 | 1639 | ||
| 1613 | ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier); | 1640 | ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier); |
| 1614 | if (ret < 0) { | 1641 | if (ret < 0) { |
| 1615 | dev_err(dcmi->dev, "Notifier registration failed\n"); | 1642 | dev_err(dcmi->dev, "Failed to register notifier\n"); |
| 1616 | v4l2_async_notifier_cleanup(&dcmi->notifier); | 1643 | v4l2_async_notifier_cleanup(&dcmi->notifier); |
| 1617 | return ret; | 1644 | return ret; |
| 1618 | } | 1645 | } |
| @@ -1645,7 +1672,7 @@ static int dcmi_probe(struct platform_device *pdev) | |||
| 1645 | dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); | 1672 | dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
| 1646 | if (IS_ERR(dcmi->rstc)) { | 1673 | if (IS_ERR(dcmi->rstc)) { |
| 1647 | dev_err(&pdev->dev, "Could not get reset control\n"); | 1674 | dev_err(&pdev->dev, "Could not get reset control\n"); |
| 1648 | return -ENODEV; | 1675 | return PTR_ERR(dcmi->rstc); |
| 1649 | } | 1676 | } |
| 1650 | 1677 | ||
| 1651 | /* Get bus characteristics from devicetree */ | 1678 | /* Get bus characteristics from devicetree */ |
| @@ -1660,7 +1687,7 @@ static int dcmi_probe(struct platform_device *pdev) | |||
| 1660 | of_node_put(np); | 1687 | of_node_put(np); |
| 1661 | if (ret) { | 1688 | if (ret) { |
| 1662 | dev_err(&pdev->dev, "Could not parse the endpoint\n"); | 1689 | dev_err(&pdev->dev, "Could not parse the endpoint\n"); |
| 1663 | return -ENODEV; | 1690 | return ret; |
| 1664 | } | 1691 | } |
| 1665 | 1692 | ||
| 1666 | if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) { | 1693 | if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) { |
| @@ -1673,8 +1700,9 @@ static int dcmi_probe(struct platform_device *pdev) | |||
| 1673 | 1700 | ||
| 1674 | irq = platform_get_irq(pdev, 0); | 1701 | irq = platform_get_irq(pdev, 0); |
| 1675 | if (irq <= 0) { | 1702 | if (irq <= 0) { |
| 1676 | dev_err(&pdev->dev, "Could not get irq\n"); | 1703 | if (irq != -EPROBE_DEFER) |
| 1677 | return -ENODEV; | 1704 | dev_err(&pdev->dev, "Could not get irq\n"); |
| 1705 | return irq; | ||
| 1678 | } | 1706 | } |
| 1679 | 1707 | ||
| 1680 | dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1708 | dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -1694,12 +1722,13 @@ static int dcmi_probe(struct platform_device *pdev) | |||
| 1694 | dev_name(&pdev->dev), dcmi); | 1722 | dev_name(&pdev->dev), dcmi); |
| 1695 | if (ret) { | 1723 | if (ret) { |
| 1696 | dev_err(&pdev->dev, "Unable to request irq %d\n", irq); | 1724 | dev_err(&pdev->dev, "Unable to request irq %d\n", irq); |
| 1697 | return -ENODEV; | 1725 | return ret; |
| 1698 | } | 1726 | } |
| 1699 | 1727 | ||
| 1700 | mclk = devm_clk_get(&pdev->dev, "mclk"); | 1728 | mclk = devm_clk_get(&pdev->dev, "mclk"); |
| 1701 | if (IS_ERR(mclk)) { | 1729 | if (IS_ERR(mclk)) { |
| 1702 | dev_err(&pdev->dev, "Unable to get mclk\n"); | 1730 | if (PTR_ERR(mclk) != -EPROBE_DEFER) |
| 1731 | dev_err(&pdev->dev, "Unable to get mclk\n"); | ||
| 1703 | return PTR_ERR(mclk); | 1732 | return PTR_ERR(mclk); |
| 1704 | } | 1733 | } |
| 1705 | 1734 | ||
| @@ -1711,6 +1740,7 @@ static int dcmi_probe(struct platform_device *pdev) | |||
| 1711 | 1740 | ||
| 1712 | spin_lock_init(&dcmi->irqlock); | 1741 | spin_lock_init(&dcmi->irqlock); |
| 1713 | mutex_init(&dcmi->lock); | 1742 | mutex_init(&dcmi->lock); |
| 1743 | mutex_init(&dcmi->dma_lock); | ||
| 1714 | init_completion(&dcmi->complete); | 1744 | init_completion(&dcmi->complete); |
| 1715 | INIT_LIST_HEAD(&dcmi->buffers); | 1745 | INIT_LIST_HEAD(&dcmi->buffers); |
| 1716 | 1746 | ||
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index 1fd16861f111..f0dfe68486d1 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | |||
| @@ -412,7 +412,7 @@ static int vidioc_enum_input(struct file *file, void *fh, | |||
| 412 | if (inp->index != 0) | 412 | if (inp->index != 0) |
| 413 | return -EINVAL; | 413 | return -EINVAL; |
| 414 | 414 | ||
| 415 | strlcpy(inp->name, "camera", sizeof(inp->name)); | 415 | strscpy(inp->name, "camera", sizeof(inp->name)); |
| 416 | inp->type = V4L2_INPUT_TYPE_CAMERA; | 416 | inp->type = V4L2_INPUT_TYPE_CAMERA; |
| 417 | 417 | ||
| 418 | return 0; | 418 | return 0; |
| @@ -644,7 +644,7 @@ int sun6i_video_init(struct sun6i_video *video, struct sun6i_csi *csi, | |||
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | /* Register video device */ | 646 | /* Register video device */ |
| 647 | strlcpy(vdev->name, name, sizeof(vdev->name)); | 647 | strscpy(vdev->name, name, sizeof(vdev->name)); |
| 648 | vdev->release = video_device_release_empty; | 648 | vdev->release = video_device_release_empty; |
| 649 | vdev->fops = &sun6i_video_fops; | 649 | vdev->fops = &sun6i_video_fops; |
| 650 | vdev->ioctl_ops = &sun6i_video_ioctl_ops; | 650 | vdev->ioctl_ops = &sun6i_video_ioctl_ops; |
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c index aba488cd0e64..7fb3a4fa07c1 100644 --- a/drivers/media/platform/tegra-cec/tegra_cec.c +++ b/drivers/media/platform/tegra-cec/tegra_cec.c | |||
| @@ -327,21 +327,15 @@ static const struct cec_adap_ops tegra_cec_ops = { | |||
| 327 | 327 | ||
| 328 | static int tegra_cec_probe(struct platform_device *pdev) | 328 | static int tegra_cec_probe(struct platform_device *pdev) |
| 329 | { | 329 | { |
| 330 | struct platform_device *hdmi_dev; | 330 | struct device *hdmi_dev; |
| 331 | struct device_node *np; | ||
| 332 | struct tegra_cec *cec; | 331 | struct tegra_cec *cec; |
| 333 | struct resource *res; | 332 | struct resource *res; |
| 334 | int ret = 0; | 333 | int ret = 0; |
| 335 | 334 | ||
| 336 | np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); | 335 | hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev); |
| 337 | 336 | ||
| 338 | if (!np) { | 337 | if (!hdmi_dev) |
| 339 | dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n"); | ||
| 340 | return -ENODEV; | 338 | return -ENODEV; |
| 341 | } | ||
| 342 | hdmi_dev = of_find_device_by_node(np); | ||
| 343 | if (hdmi_dev == NULL) | ||
| 344 | return -EPROBE_DEFER; | ||
| 345 | 339 | ||
| 346 | cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); | 340 | cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); |
| 347 | 341 | ||
| @@ -400,7 +394,7 @@ static int tegra_cec_probe(struct platform_device *pdev) | |||
| 400 | goto clk_error; | 394 | goto clk_error; |
| 401 | } | 395 | } |
| 402 | 396 | ||
| 403 | cec->notifier = cec_notifier_get(&hdmi_dev->dev); | 397 | cec->notifier = cec_notifier_get(hdmi_dev); |
| 404 | if (!cec->notifier) { | 398 | if (!cec->notifier) { |
| 405 | ret = -ENOMEM; | 399 | ret = -ENOMEM; |
| 406 | goto clk_error; | 400 | goto clk_error; |
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index fc3c212b96e1..8d075683e448 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c | |||
| @@ -1643,8 +1643,7 @@ of_get_next_endpoint(const struct device_node *parent, | |||
| 1643 | static int of_cal_create_instance(struct cal_ctx *ctx, int inst) | 1643 | static int of_cal_create_instance(struct cal_ctx *ctx, int inst) |
| 1644 | { | 1644 | { |
| 1645 | struct platform_device *pdev = ctx->dev->pdev; | 1645 | struct platform_device *pdev = ctx->dev->pdev; |
| 1646 | struct device_node *ep_node, *port, *remote_ep, | 1646 | struct device_node *ep_node, *port, *sensor_node, *parent; |
| 1647 | *sensor_node, *parent; | ||
| 1648 | struct v4l2_fwnode_endpoint *endpoint; | 1647 | struct v4l2_fwnode_endpoint *endpoint; |
| 1649 | struct v4l2_async_subdev *asd; | 1648 | struct v4l2_async_subdev *asd; |
| 1650 | u32 regval = 0; | 1649 | u32 regval = 0; |
| @@ -1657,7 +1656,6 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) | |||
| 1657 | 1656 | ||
| 1658 | ep_node = NULL; | 1657 | ep_node = NULL; |
| 1659 | port = NULL; | 1658 | port = NULL; |
| 1660 | remote_ep = NULL; | ||
| 1661 | sensor_node = NULL; | 1659 | sensor_node = NULL; |
| 1662 | ret = -EINVAL; | 1660 | ret = -EINVAL; |
| 1663 | 1661 | ||
| @@ -1703,12 +1701,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) | |||
| 1703 | asd->match_type = V4L2_ASYNC_MATCH_FWNODE; | 1701 | asd->match_type = V4L2_ASYNC_MATCH_FWNODE; |
| 1704 | asd->match.fwnode = of_fwnode_handle(sensor_node); | 1702 | asd->match.fwnode = of_fwnode_handle(sensor_node); |
| 1705 | 1703 | ||
| 1706 | remote_ep = of_graph_get_remote_endpoint(ep_node); | 1704 | v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint); |
| 1707 | if (!remote_ep) { | ||
| 1708 | ctx_dbg(3, ctx, "can't get remote-endpoint\n"); | ||
| 1709 | goto cleanup_exit; | ||
| 1710 | } | ||
| 1711 | v4l2_fwnode_endpoint_parse(of_fwnode_handle(remote_ep), endpoint); | ||
| 1712 | 1705 | ||
| 1713 | if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) { | 1706 | if (endpoint->bus_type != V4L2_MBUS_CSI2_DPHY) { |
| 1714 | ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n", | 1707 | ctx_err(ctx, "Port:%d sub-device %pOFn is not a CSI2 device\n", |
| @@ -1759,7 +1752,6 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) | |||
| 1759 | sensor_node = NULL; | 1752 | sensor_node = NULL; |
| 1760 | 1753 | ||
| 1761 | cleanup_exit: | 1754 | cleanup_exit: |
| 1762 | of_node_put(remote_ep); | ||
| 1763 | of_node_put(sensor_node); | 1755 | of_node_put(sensor_node); |
| 1764 | of_node_put(ep_node); | 1756 | of_node_put(ep_node); |
| 1765 | of_node_put(port); | 1757 | of_node_put(port); |
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index 207e7e76c048..1e40eafec284 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c | |||
| @@ -1491,8 +1491,8 @@ handled: | |||
| 1491 | static int vpe_querycap(struct file *file, void *priv, | 1491 | static int vpe_querycap(struct file *file, void *priv, |
| 1492 | struct v4l2_capability *cap) | 1492 | struct v4l2_capability *cap) |
| 1493 | { | 1493 | { |
| 1494 | strncpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver) - 1); | 1494 | strscpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver)); |
| 1495 | strncpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card) - 1); | 1495 | strscpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card)); |
| 1496 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", | 1496 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
| 1497 | VPE_MODULE_NAME); | 1497 | VPE_MODULE_NAME); |
| 1498 | cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; | 1498 | cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; |
| @@ -1519,7 +1519,7 @@ static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type) | |||
| 1519 | if (!fmt) | 1519 | if (!fmt) |
| 1520 | return -EINVAL; | 1520 | return -EINVAL; |
| 1521 | 1521 | ||
| 1522 | strncpy(f->description, fmt->name, sizeof(f->description) - 1); | 1522 | strscpy(f->description, fmt->name, sizeof(f->description)); |
| 1523 | f->pixelformat = fmt->fourcc; | 1523 | f->pixelformat = fmt->fourcc; |
| 1524 | return 0; | 1524 | return 0; |
| 1525 | } | 1525 | } |
diff --git a/drivers/media/platform/vicodec/codec-fwht.c b/drivers/media/platform/vicodec/codec-fwht.c index d1d6085da9f1..31faf319e508 100644 --- a/drivers/media/platform/vicodec/codec-fwht.c +++ b/drivers/media/platform/vicodec/codec-fwht.c | |||
| @@ -46,8 +46,12 @@ static const uint8_t zigzag[64] = { | |||
| 46 | 63, | 46 | 63, |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | 49 | /* | |
| 50 | static int rlc(const s16 *in, __be16 *output, int blocktype) | 50 | * noinline_for_stack to work around |
| 51 | * https://bugs.llvm.org/show_bug.cgi?id=38809 | ||
| 52 | */ | ||
| 53 | static int noinline_for_stack | ||
| 54 | rlc(const s16 *in, __be16 *output, int blocktype) | ||
| 51 | { | 55 | { |
| 52 | s16 block[8 * 8]; | 56 | s16 block[8 * 8]; |
| 53 | s16 *wp = block; | 57 | s16 *wp = block; |
| @@ -106,8 +110,8 @@ static int rlc(const s16 *in, __be16 *output, int blocktype) | |||
| 106 | * This function will worst-case increase rlc_in by 65*2 bytes: | 110 | * This function will worst-case increase rlc_in by 65*2 bytes: |
| 107 | * one s16 value for the header and 8 * 8 coefficients of type s16. | 111 | * one s16 value for the header and 8 * 8 coefficients of type s16. |
| 108 | */ | 112 | */ |
| 109 | static u16 derlc(const __be16 **rlc_in, s16 *dwht_out, | 113 | static noinline_for_stack u16 |
| 110 | const __be16 *end_of_input) | 114 | derlc(const __be16 **rlc_in, s16 *dwht_out, const __be16 *end_of_input) |
| 111 | { | 115 | { |
| 112 | /* header */ | 116 | /* header */ |
| 113 | const __be16 *input = *rlc_in; | 117 | const __be16 *input = *rlc_in; |
| @@ -240,8 +244,9 @@ static void dequantize_inter(s16 *coeff) | |||
| 240 | *coeff <<= *quant; | 244 | *coeff <<= *quant; |
| 241 | } | 245 | } |
| 242 | 246 | ||
| 243 | static void fwht(const u8 *block, s16 *output_block, unsigned int stride, | 247 | static void noinline_for_stack fwht(const u8 *block, s16 *output_block, |
| 244 | unsigned int input_step, bool intra) | 248 | unsigned int stride, |
| 249 | unsigned int input_step, bool intra) | ||
| 245 | { | 250 | { |
| 246 | /* we'll need more than 8 bits for the transformed coefficients */ | 251 | /* we'll need more than 8 bits for the transformed coefficients */ |
| 247 | s32 workspace1[8], workspace2[8]; | 252 | s32 workspace1[8], workspace2[8]; |
| @@ -373,7 +378,8 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride, | |||
| 373 | * Furthermore values can be negative... This is just a version that | 378 | * Furthermore values can be negative... This is just a version that |
| 374 | * works with 16 signed data | 379 | * works with 16 signed data |
| 375 | */ | 380 | */ |
| 376 | static void fwht16(const s16 *block, s16 *output_block, int stride, int intra) | 381 | static void noinline_for_stack |
| 382 | fwht16(const s16 *block, s16 *output_block, int stride, int intra) | ||
| 377 | { | 383 | { |
| 378 | /* we'll need more than 8 bits for the transformed coefficients */ | 384 | /* we'll need more than 8 bits for the transformed coefficients */ |
| 379 | s32 workspace1[8], workspace2[8]; | 385 | s32 workspace1[8], workspace2[8]; |
| @@ -456,7 +462,8 @@ static void fwht16(const s16 *block, s16 *output_block, int stride, int intra) | |||
| 456 | } | 462 | } |
| 457 | } | 463 | } |
| 458 | 464 | ||
| 459 | static void ifwht(const s16 *block, s16 *output_block, int intra) | 465 | static noinline_for_stack void |
| 466 | ifwht(const s16 *block, s16 *output_block, int intra) | ||
| 460 | { | 467 | { |
| 461 | /* | 468 | /* |
| 462 | * we'll need more than 8 bits for the transformed coefficients | 469 | * we'll need more than 8 bits for the transformed coefficients |
| @@ -604,9 +611,9 @@ static int var_inter(const s16 *old, const s16 *new) | |||
| 604 | return ret; | 611 | return ret; |
| 605 | } | 612 | } |
| 606 | 613 | ||
| 607 | static int decide_blocktype(const u8 *cur, const u8 *reference, | 614 | static noinline_for_stack int |
| 608 | s16 *deltablock, unsigned int stride, | 615 | decide_blocktype(const u8 *cur, const u8 *reference, s16 *deltablock, |
| 609 | unsigned int input_step) | 616 | unsigned int stride, unsigned int input_step) |
| 610 | { | 617 | { |
| 611 | s16 tmp[64]; | 618 | s16 tmp[64]; |
| 612 | s16 old[64]; | 619 | s16 old[64]; |
| @@ -632,12 +639,13 @@ static int decide_blocktype(const u8 *cur, const u8 *reference, | |||
| 632 | return vari <= vard ? IBLOCK : PBLOCK; | 639 | return vari <= vard ? IBLOCK : PBLOCK; |
| 633 | } | 640 | } |
| 634 | 641 | ||
| 635 | static void fill_decoder_block(u8 *dst, const s16 *input, int stride) | 642 | static void fill_decoder_block(u8 *dst, const s16 *input, int stride, |
| 643 | unsigned int dst_step) | ||
| 636 | { | 644 | { |
| 637 | int i, j; | 645 | int i, j; |
| 638 | 646 | ||
| 639 | for (i = 0; i < 8; i++) { | 647 | for (i = 0; i < 8; i++) { |
| 640 | for (j = 0; j < 8; j++, input++, dst++) { | 648 | for (j = 0; j < 8; j++, input++, dst += dst_step) { |
| 641 | if (*input < 0) | 649 | if (*input < 0) |
| 642 | *dst = 0; | 650 | *dst = 0; |
| 643 | else if (*input > 255) | 651 | else if (*input > 255) |
| @@ -645,17 +653,19 @@ static void fill_decoder_block(u8 *dst, const s16 *input, int stride) | |||
| 645 | else | 653 | else |
| 646 | *dst = *input; | 654 | *dst = *input; |
| 647 | } | 655 | } |
| 648 | dst += stride - 8; | 656 | dst += stride - (8 * dst_step); |
| 649 | } | 657 | } |
| 650 | } | 658 | } |
| 651 | 659 | ||
| 652 | static void add_deltas(s16 *deltas, const u8 *ref, int stride) | 660 | static void add_deltas(s16 *deltas, const u8 *ref, int stride, |
| 661 | unsigned int ref_step) | ||
| 653 | { | 662 | { |
| 654 | int k, l; | 663 | int k, l; |
| 655 | 664 | ||
| 656 | for (k = 0; k < 8; k++) { | 665 | for (k = 0; k < 8; k++) { |
| 657 | for (l = 0; l < 8; l++) { | 666 | for (l = 0; l < 8; l++) { |
| 658 | *deltas += *ref++; | 667 | *deltas += *ref; |
| 668 | ref += ref_step; | ||
| 659 | /* | 669 | /* |
| 660 | * Due to quantizing, it might possible that the | 670 | * Due to quantizing, it might possible that the |
| 661 | * decoded coefficients are slightly out of range | 671 | * decoded coefficients are slightly out of range |
| @@ -666,7 +676,7 @@ static void add_deltas(s16 *deltas, const u8 *ref, int stride) | |||
| 666 | *deltas = 255; | 676 | *deltas = 255; |
| 667 | deltas++; | 677 | deltas++; |
| 668 | } | 678 | } |
| 669 | ref += stride - 8; | 679 | ref += stride - (8 * ref_step); |
| 670 | } | 680 | } |
| 671 | } | 681 | } |
| 672 | 682 | ||
| @@ -711,8 +721,8 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, | |||
| 711 | ifwht(cf->de_coeffs, cf->de_fwht, blocktype); | 721 | ifwht(cf->de_coeffs, cf->de_fwht, blocktype); |
| 712 | 722 | ||
| 713 | if (blocktype == PBLOCK) | 723 | if (blocktype == PBLOCK) |
| 714 | add_deltas(cf->de_fwht, refp, 8); | 724 | add_deltas(cf->de_fwht, refp, 8, 1); |
| 715 | fill_decoder_block(refp, cf->de_fwht, 8); | 725 | fill_decoder_block(refp, cf->de_fwht, 8, 1); |
| 716 | } | 726 | } |
| 717 | 727 | ||
| 718 | input += 8 * input_step; | 728 | input += 8 * input_step; |
| @@ -821,23 +831,31 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm, | |||
| 821 | return encoding; | 831 | return encoding; |
| 822 | } | 832 | } |
| 823 | 833 | ||
| 824 | static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, | 834 | static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco, |
| 825 | u32 height, u32 width, u32 coded_width, | 835 | u32 height, u32 width, const u8 *ref, u32 ref_stride, |
| 836 | unsigned int ref_step, u8 *dst, | ||
| 837 | unsigned int dst_stride, unsigned int dst_step, | ||
| 826 | bool uncompressed, const __be16 *end_of_rlco_buf) | 838 | bool uncompressed, const __be16 *end_of_rlco_buf) |
| 827 | { | 839 | { |
| 828 | unsigned int copies = 0; | 840 | unsigned int copies = 0; |
| 829 | s16 copy[8 * 8]; | 841 | s16 copy[8 * 8]; |
| 830 | u16 stat; | 842 | u16 stat; |
| 831 | unsigned int i, j; | 843 | unsigned int i, j; |
| 844 | bool is_intra = !ref; | ||
| 832 | 845 | ||
| 833 | width = round_up(width, 8); | 846 | width = round_up(width, 8); |
| 834 | height = round_up(height, 8); | 847 | height = round_up(height, 8); |
| 835 | 848 | ||
| 836 | if (uncompressed) { | 849 | if (uncompressed) { |
| 850 | int i; | ||
| 851 | |||
| 837 | if (end_of_rlco_buf + 1 < *rlco + width * height / 2) | 852 | if (end_of_rlco_buf + 1 < *rlco + width * height / 2) |
| 838 | return false; | 853 | return false; |
| 839 | memcpy(ref, *rlco, width * height); | 854 | for (i = 0; i < height; i++) { |
| 840 | *rlco += width * height / 2; | 855 | memcpy(dst, *rlco, width); |
| 856 | dst += dst_stride; | ||
| 857 | *rlco += width / 2; | ||
| 858 | } | ||
| 841 | return true; | 859 | return true; |
| 842 | } | 860 | } |
| 843 | 861 | ||
| @@ -849,15 +867,17 @@ static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, | |||
| 849 | */ | 867 | */ |
| 850 | for (j = 0; j < height / 8; j++) { | 868 | for (j = 0; j < height / 8; j++) { |
| 851 | for (i = 0; i < width / 8; i++) { | 869 | for (i = 0; i < width / 8; i++) { |
| 852 | u8 *refp = ref + j * 8 * coded_width + i * 8; | 870 | const u8 *refp = ref + j * 8 * ref_stride + |
| 871 | i * 8 * ref_step; | ||
| 872 | u8 *dstp = dst + j * 8 * dst_stride + i * 8 * dst_step; | ||
| 853 | 873 | ||
| 854 | if (copies) { | 874 | if (copies) { |
| 855 | memcpy(cf->de_fwht, copy, sizeof(copy)); | 875 | memcpy(cf->de_fwht, copy, sizeof(copy)); |
| 856 | if (stat & PFRAME_BIT) | 876 | if ((stat & PFRAME_BIT) && !is_intra) |
| 857 | add_deltas(cf->de_fwht, refp, | 877 | add_deltas(cf->de_fwht, refp, |
| 858 | coded_width); | 878 | ref_stride, ref_step); |
| 859 | fill_decoder_block(refp, cf->de_fwht, | 879 | fill_decoder_block(dstp, cf->de_fwht, |
| 860 | coded_width); | 880 | dst_stride, dst_step); |
| 861 | copies--; | 881 | copies--; |
| 862 | continue; | 882 | continue; |
| 863 | } | 883 | } |
| @@ -865,35 +885,41 @@ static bool decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, | |||
| 865 | stat = derlc(rlco, cf->coeffs, end_of_rlco_buf); | 885 | stat = derlc(rlco, cf->coeffs, end_of_rlco_buf); |
| 866 | if (stat & OVERFLOW_BIT) | 886 | if (stat & OVERFLOW_BIT) |
| 867 | return false; | 887 | return false; |
| 868 | if (stat & PFRAME_BIT) | 888 | if ((stat & PFRAME_BIT) && !is_intra) |
| 869 | dequantize_inter(cf->coeffs); | 889 | dequantize_inter(cf->coeffs); |
| 870 | else | 890 | else |
| 871 | dequantize_intra(cf->coeffs); | 891 | dequantize_intra(cf->coeffs); |
| 872 | 892 | ||
| 873 | ifwht(cf->coeffs, cf->de_fwht, | 893 | ifwht(cf->coeffs, cf->de_fwht, |
| 874 | (stat & PFRAME_BIT) ? 0 : 1); | 894 | ((stat & PFRAME_BIT) && !is_intra) ? 0 : 1); |
| 875 | 895 | ||
| 876 | copies = (stat & DUPS_MASK) >> 1; | 896 | copies = (stat & DUPS_MASK) >> 1; |
| 877 | if (copies) | 897 | if (copies) |
| 878 | memcpy(copy, cf->de_fwht, sizeof(copy)); | 898 | memcpy(copy, cf->de_fwht, sizeof(copy)); |
| 879 | if (stat & PFRAME_BIT) | 899 | if ((stat & PFRAME_BIT) && !is_intra) |
| 880 | add_deltas(cf->de_fwht, refp, coded_width); | 900 | add_deltas(cf->de_fwht, refp, |
| 881 | fill_decoder_block(refp, cf->de_fwht, coded_width); | 901 | ref_stride, ref_step); |
| 902 | fill_decoder_block(dstp, cf->de_fwht, dst_stride, | ||
| 903 | dst_step); | ||
| 882 | } | 904 | } |
| 883 | } | 905 | } |
| 884 | return true; | 906 | return true; |
| 885 | } | 907 | } |
| 886 | 908 | ||
| 887 | bool fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, | 909 | bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags, |
| 888 | u32 hdr_flags, unsigned int components_num, | 910 | unsigned int components_num, unsigned int width, |
| 889 | unsigned int width, unsigned int height, | 911 | unsigned int height, const struct fwht_raw_frame *ref, |
| 890 | unsigned int coded_width) | 912 | unsigned int ref_stride, unsigned int ref_chroma_stride, |
| 913 | struct fwht_raw_frame *dst, unsigned int dst_stride, | ||
| 914 | unsigned int dst_chroma_stride) | ||
| 891 | { | 915 | { |
| 892 | const __be16 *rlco = cf->rlc_data; | 916 | const __be16 *rlco = cf->rlc_data; |
| 893 | const __be16 *end_of_rlco_buf = cf->rlc_data + | 917 | const __be16 *end_of_rlco_buf = cf->rlc_data + |
| 894 | (cf->size / sizeof(*rlco)) - 1; | 918 | (cf->size / sizeof(*rlco)) - 1; |
| 895 | 919 | ||
| 896 | if (!decode_plane(cf, &rlco, ref->luma, height, width, coded_width, | 920 | if (!decode_plane(cf, &rlco, height, width, ref->luma, ref_stride, |
| 921 | ref->luma_alpha_step, dst->luma, dst_stride, | ||
| 922 | dst->luma_alpha_step, | ||
| 897 | hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED, | 923 | hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED, |
| 898 | end_of_rlco_buf)) | 924 | end_of_rlco_buf)) |
| 899 | return false; | 925 | return false; |
| @@ -901,27 +927,30 @@ bool fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, | |||
| 901 | if (components_num >= 3) { | 927 | if (components_num >= 3) { |
| 902 | u32 h = height; | 928 | u32 h = height; |
| 903 | u32 w = width; | 929 | u32 w = width; |
| 904 | u32 c = coded_width; | ||
| 905 | 930 | ||
| 906 | if (!(hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT)) | 931 | if (!(hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT)) |
| 907 | h /= 2; | 932 | h /= 2; |
| 908 | if (!(hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH)) { | 933 | if (!(hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH)) |
| 909 | w /= 2; | 934 | w /= 2; |
| 910 | c /= 2; | 935 | |
| 911 | } | 936 | if (!decode_plane(cf, &rlco, h, w, ref->cb, ref_chroma_stride, |
| 912 | if (!decode_plane(cf, &rlco, ref->cb, h, w, c, | 937 | ref->chroma_step, dst->cb, dst_chroma_stride, |
| 938 | dst->chroma_step, | ||
| 913 | hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED, | 939 | hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED, |
| 914 | end_of_rlco_buf)) | 940 | end_of_rlco_buf)) |
| 915 | return false; | 941 | return false; |
| 916 | if (!decode_plane(cf, &rlco, ref->cr, h, w, c, | 942 | if (!decode_plane(cf, &rlco, h, w, ref->cr, ref_chroma_stride, |
| 943 | ref->chroma_step, dst->cr, dst_chroma_stride, | ||
| 944 | dst->chroma_step, | ||
| 917 | hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED, | 945 | hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED, |
| 918 | end_of_rlco_buf)) | 946 | end_of_rlco_buf)) |
| 919 | return false; | 947 | return false; |
| 920 | } | 948 | } |
| 921 | 949 | ||
| 922 | if (components_num == 4) | 950 | if (components_num == 4) |
| 923 | if (!decode_plane(cf, &rlco, ref->alpha, height, width, | 951 | if (!decode_plane(cf, &rlco, height, width, ref->alpha, ref_stride, |
| 924 | coded_width, | 952 | ref->luma_alpha_step, dst->alpha, dst_stride, |
| 953 | dst->luma_alpha_step, | ||
| 925 | hdr_flags & FWHT_FL_ALPHA_IS_UNCOMPRESSED, | 954 | hdr_flags & FWHT_FL_ALPHA_IS_UNCOMPRESSED, |
| 926 | end_of_rlco_buf)) | 955 | end_of_rlco_buf)) |
| 927 | return false; | 956 | return false; |
diff --git a/drivers/media/platform/vicodec/codec-fwht.h b/drivers/media/platform/vicodec/codec-fwht.h index c410512d47c5..b6fec2b1cbca 100644 --- a/drivers/media/platform/vicodec/codec-fwht.h +++ b/drivers/media/platform/vicodec/codec-fwht.h | |||
| @@ -124,6 +124,7 @@ struct fwht_raw_frame { | |||
| 124 | unsigned int luma_alpha_step; | 124 | unsigned int luma_alpha_step; |
| 125 | unsigned int chroma_step; | 125 | unsigned int chroma_step; |
| 126 | unsigned int components_num; | 126 | unsigned int components_num; |
| 127 | u8 *buf; | ||
| 127 | u8 *luma, *cb, *cr, *alpha; | 128 | u8 *luma, *cb, *cr, *alpha; |
| 128 | }; | 129 | }; |
| 129 | 130 | ||
| @@ -140,9 +141,10 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm, | |||
| 140 | bool is_intra, bool next_is_intra, | 141 | bool is_intra, bool next_is_intra, |
| 141 | unsigned int width, unsigned int height, | 142 | unsigned int width, unsigned int height, |
| 142 | unsigned int stride, unsigned int chroma_stride); | 143 | unsigned int stride, unsigned int chroma_stride); |
| 143 | bool fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, | 144 | bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags, |
| 144 | u32 hdr_flags, unsigned int components_num, | 145 | unsigned int components_num, unsigned int width, |
| 145 | unsigned int width, unsigned int height, | 146 | unsigned int height, const struct fwht_raw_frame *ref, |
| 146 | unsigned int coded_width); | 147 | unsigned int ref_stride, unsigned int ref_chroma_stride, |
| 147 | 148 | struct fwht_raw_frame *dst, unsigned int dst_stride, | |
| 149 | unsigned int dst_chroma_stride); | ||
| 148 | #endif | 150 | #endif |
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c index 6573a471c5ca..01e7f09efc4e 100644 --- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c | |||
| @@ -37,7 +37,19 @@ static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { | |||
| 37 | { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, | 37 | { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt(u32 width_div, | 40 | bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info, |
| 41 | u32 width_div, u32 height_div, u32 components_num, | ||
| 42 | u32 pixenc) | ||
| 43 | { | ||
| 44 | if (info->width_div == width_div && | ||
| 45 | info->height_div == height_div && | ||
| 46 | (!pixenc || info->pixenc == pixenc) && | ||
| 47 | info->components_num == components_num) | ||
| 48 | return true; | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | |||
| 52 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div, | ||
| 41 | u32 height_div, | 53 | u32 height_div, |
| 42 | u32 components_num, | 54 | u32 components_num, |
| 43 | u32 pixenc, | 55 | u32 pixenc, |
| @@ -46,10 +58,10 @@ const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt(u32 width_div, | |||
| 46 | unsigned int i; | 58 | unsigned int i; |
| 47 | 59 | ||
| 48 | for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) { | 60 | for (i = 0; i < ARRAY_SIZE(v4l2_fwht_pixfmts); i++) { |
| 49 | if (v4l2_fwht_pixfmts[i].width_div == width_div && | 61 | bool is_valid = v4l2_fwht_validate_fmt(&v4l2_fwht_pixfmts[i], |
| 50 | v4l2_fwht_pixfmts[i].height_div == height_div && | 62 | width_div, height_div, |
| 51 | (!pixenc || v4l2_fwht_pixfmts[i].pixenc == pixenc) && | 63 | components_num, pixenc); |
| 52 | v4l2_fwht_pixfmts[i].components_num == components_num) { | 64 | if (is_valid) { |
| 53 | if (start_idx == 0) | 65 | if (start_idx == 0) |
| 54 | return v4l2_fwht_pixfmts + i; | 66 | return v4l2_fwht_pixfmts + i; |
| 55 | start_idx--; | 67 | start_idx--; |
| @@ -75,117 +87,141 @@ const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx) | |||
| 75 | return v4l2_fwht_pixfmts + idx; | 87 | return v4l2_fwht_pixfmts + idx; |
| 76 | } | 88 | } |
| 77 | 89 | ||
| 78 | int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) | 90 | static int prepare_raw_frame(struct fwht_raw_frame *rf, |
| 91 | const struct v4l2_fwht_pixfmt_info *info, u8 *buf, | ||
| 92 | unsigned int size) | ||
| 79 | { | 93 | { |
| 80 | unsigned int size = state->stride * state->coded_height; | 94 | rf->luma = buf; |
| 81 | unsigned int chroma_stride = state->stride; | 95 | rf->width_div = info->width_div; |
| 82 | const struct v4l2_fwht_pixfmt_info *info = state->info; | 96 | rf->height_div = info->height_div; |
| 83 | struct fwht_cframe_hdr *p_hdr; | 97 | rf->luma_alpha_step = info->luma_alpha_step; |
| 84 | struct fwht_cframe cf; | 98 | rf->chroma_step = info->chroma_step; |
| 85 | struct fwht_raw_frame rf; | 99 | rf->alpha = NULL; |
| 86 | u32 encoding; | 100 | rf->components_num = info->components_num; |
| 87 | u32 flags = 0; | ||
| 88 | |||
| 89 | if (!info) | ||
| 90 | return -EINVAL; | ||
| 91 | |||
| 92 | rf.luma = p_in; | ||
| 93 | rf.width_div = info->width_div; | ||
| 94 | rf.height_div = info->height_div; | ||
| 95 | rf.luma_alpha_step = info->luma_alpha_step; | ||
| 96 | rf.chroma_step = info->chroma_step; | ||
| 97 | rf.alpha = NULL; | ||
| 98 | rf.components_num = info->components_num; | ||
| 99 | 101 | ||
| 102 | /* | ||
| 103 | * The buffer is NULL if it is the reference | ||
| 104 | * frame of an I-frame in the stateless decoder | ||
| 105 | */ | ||
| 106 | if (!buf) { | ||
| 107 | rf->luma = NULL; | ||
| 108 | rf->cb = NULL; | ||
| 109 | rf->cr = NULL; | ||
| 110 | rf->alpha = NULL; | ||
| 111 | return 0; | ||
| 112 | } | ||
| 100 | switch (info->id) { | 113 | switch (info->id) { |
| 101 | case V4L2_PIX_FMT_GREY: | 114 | case V4L2_PIX_FMT_GREY: |
| 102 | rf.cb = NULL; | 115 | rf->cb = NULL; |
| 103 | rf.cr = NULL; | 116 | rf->cr = NULL; |
| 104 | break; | 117 | break; |
| 105 | case V4L2_PIX_FMT_YUV420: | 118 | case V4L2_PIX_FMT_YUV420: |
| 106 | rf.cb = rf.luma + size; | 119 | rf->cb = rf->luma + size; |
| 107 | rf.cr = rf.cb + size / 4; | 120 | rf->cr = rf->cb + size / 4; |
| 108 | chroma_stride /= 2; | ||
| 109 | break; | 121 | break; |
| 110 | case V4L2_PIX_FMT_YVU420: | 122 | case V4L2_PIX_FMT_YVU420: |
| 111 | rf.cr = rf.luma + size; | 123 | rf->cr = rf->luma + size; |
| 112 | rf.cb = rf.cr + size / 4; | 124 | rf->cb = rf->cr + size / 4; |
| 113 | chroma_stride /= 2; | ||
| 114 | break; | 125 | break; |
| 115 | case V4L2_PIX_FMT_YUV422P: | 126 | case V4L2_PIX_FMT_YUV422P: |
| 116 | rf.cb = rf.luma + size; | 127 | rf->cb = rf->luma + size; |
| 117 | rf.cr = rf.cb + size / 2; | 128 | rf->cr = rf->cb + size / 2; |
| 118 | chroma_stride /= 2; | ||
| 119 | break; | 129 | break; |
| 120 | case V4L2_PIX_FMT_NV12: | 130 | case V4L2_PIX_FMT_NV12: |
| 121 | case V4L2_PIX_FMT_NV16: | 131 | case V4L2_PIX_FMT_NV16: |
| 122 | case V4L2_PIX_FMT_NV24: | 132 | case V4L2_PIX_FMT_NV24: |
| 123 | rf.cb = rf.luma + size; | 133 | rf->cb = rf->luma + size; |
| 124 | rf.cr = rf.cb + 1; | 134 | rf->cr = rf->cb + 1; |
| 125 | break; | 135 | break; |
| 126 | case V4L2_PIX_FMT_NV21: | 136 | case V4L2_PIX_FMT_NV21: |
| 127 | case V4L2_PIX_FMT_NV61: | 137 | case V4L2_PIX_FMT_NV61: |
| 128 | case V4L2_PIX_FMT_NV42: | 138 | case V4L2_PIX_FMT_NV42: |
| 129 | rf.cr = rf.luma + size; | 139 | rf->cr = rf->luma + size; |
| 130 | rf.cb = rf.cr + 1; | 140 | rf->cb = rf->cr + 1; |
| 131 | break; | 141 | break; |
| 132 | case V4L2_PIX_FMT_YUYV: | 142 | case V4L2_PIX_FMT_YUYV: |
| 133 | rf.cb = rf.luma + 1; | 143 | rf->cb = rf->luma + 1; |
| 134 | rf.cr = rf.cb + 2; | 144 | rf->cr = rf->cb + 2; |
| 135 | break; | 145 | break; |
| 136 | case V4L2_PIX_FMT_YVYU: | 146 | case V4L2_PIX_FMT_YVYU: |
| 137 | rf.cr = rf.luma + 1; | 147 | rf->cr = rf->luma + 1; |
| 138 | rf.cb = rf.cr + 2; | 148 | rf->cb = rf->cr + 2; |
| 139 | break; | 149 | break; |
| 140 | case V4L2_PIX_FMT_UYVY: | 150 | case V4L2_PIX_FMT_UYVY: |
| 141 | rf.cb = rf.luma; | 151 | rf->cb = rf->luma; |
| 142 | rf.cr = rf.cb + 2; | 152 | rf->cr = rf->cb + 2; |
| 143 | rf.luma++; | 153 | rf->luma++; |
| 144 | break; | 154 | break; |
| 145 | case V4L2_PIX_FMT_VYUY: | 155 | case V4L2_PIX_FMT_VYUY: |
| 146 | rf.cr = rf.luma; | 156 | rf->cr = rf->luma; |
| 147 | rf.cb = rf.cr + 2; | 157 | rf->cb = rf->cr + 2; |
| 148 | rf.luma++; | 158 | rf->luma++; |
| 149 | break; | 159 | break; |
| 150 | case V4L2_PIX_FMT_RGB24: | 160 | case V4L2_PIX_FMT_RGB24: |
| 151 | case V4L2_PIX_FMT_HSV24: | 161 | case V4L2_PIX_FMT_HSV24: |
| 152 | rf.cr = rf.luma; | 162 | rf->cr = rf->luma; |
| 153 | rf.cb = rf.cr + 2; | 163 | rf->cb = rf->cr + 2; |
| 154 | rf.luma++; | 164 | rf->luma++; |
| 155 | break; | 165 | break; |
| 156 | case V4L2_PIX_FMT_BGR24: | 166 | case V4L2_PIX_FMT_BGR24: |
| 157 | rf.cb = rf.luma; | 167 | rf->cb = rf->luma; |
| 158 | rf.cr = rf.cb + 2; | 168 | rf->cr = rf->cb + 2; |
| 159 | rf.luma++; | 169 | rf->luma++; |
| 160 | break; | 170 | break; |
| 161 | case V4L2_PIX_FMT_RGB32: | 171 | case V4L2_PIX_FMT_RGB32: |
| 162 | case V4L2_PIX_FMT_XRGB32: | 172 | case V4L2_PIX_FMT_XRGB32: |
| 163 | case V4L2_PIX_FMT_HSV32: | 173 | case V4L2_PIX_FMT_HSV32: |
| 164 | rf.cr = rf.luma + 1; | 174 | rf->cr = rf->luma + 1; |
| 165 | rf.cb = rf.cr + 2; | 175 | rf->cb = rf->cr + 2; |
| 166 | rf.luma += 2; | 176 | rf->luma += 2; |
| 167 | break; | 177 | break; |
| 168 | case V4L2_PIX_FMT_BGR32: | 178 | case V4L2_PIX_FMT_BGR32: |
| 169 | case V4L2_PIX_FMT_XBGR32: | 179 | case V4L2_PIX_FMT_XBGR32: |
| 170 | rf.cb = rf.luma; | 180 | rf->cb = rf->luma; |
| 171 | rf.cr = rf.cb + 2; | 181 | rf->cr = rf->cb + 2; |
| 172 | rf.luma++; | 182 | rf->luma++; |
| 173 | break; | 183 | break; |
| 174 | case V4L2_PIX_FMT_ARGB32: | 184 | case V4L2_PIX_FMT_ARGB32: |
| 175 | rf.alpha = rf.luma; | 185 | rf->alpha = rf->luma; |
| 176 | rf.cr = rf.luma + 1; | 186 | rf->cr = rf->luma + 1; |
| 177 | rf.cb = rf.cr + 2; | 187 | rf->cb = rf->cr + 2; |
| 178 | rf.luma += 2; | 188 | rf->luma += 2; |
| 179 | break; | 189 | break; |
| 180 | case V4L2_PIX_FMT_ABGR32: | 190 | case V4L2_PIX_FMT_ABGR32: |
| 181 | rf.cb = rf.luma; | 191 | rf->cb = rf->luma; |
| 182 | rf.cr = rf.cb + 2; | 192 | rf->cr = rf->cb + 2; |
| 183 | rf.luma++; | 193 | rf->luma++; |
| 184 | rf.alpha = rf.cr + 1; | 194 | rf->alpha = rf->cr + 1; |
| 185 | break; | 195 | break; |
| 186 | default: | 196 | default: |
| 187 | return -EINVAL; | 197 | return -EINVAL; |
| 188 | } | 198 | } |
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) | ||
| 203 | { | ||
| 204 | unsigned int size = state->stride * state->coded_height; | ||
| 205 | unsigned int chroma_stride = state->stride; | ||
| 206 | const struct v4l2_fwht_pixfmt_info *info = state->info; | ||
| 207 | struct fwht_cframe_hdr *p_hdr; | ||
| 208 | struct fwht_cframe cf; | ||
| 209 | struct fwht_raw_frame rf; | ||
| 210 | u32 encoding; | ||
| 211 | u32 flags = 0; | ||
| 212 | |||
| 213 | if (!info) | ||
| 214 | return -EINVAL; | ||
| 215 | |||
| 216 | if (prepare_raw_frame(&rf, info, p_in, size)) | ||
| 217 | return -EINVAL; | ||
| 218 | |||
| 219 | if (info->planes_num == 3) | ||
| 220 | chroma_stride /= 2; | ||
| 221 | |||
| 222 | if (info->id == V4L2_PIX_FMT_NV24 || | ||
| 223 | info->id == V4L2_PIX_FMT_NV42) | ||
| 224 | chroma_stride *= 2; | ||
| 189 | 225 | ||
| 190 | cf.i_frame_qp = state->i_frame_qp; | 226 | cf.i_frame_qp = state->i_frame_qp; |
| 191 | cf.p_frame_qp = state->p_frame_qp; | 227 | cf.p_frame_qp = state->p_frame_qp; |
| @@ -235,14 +271,17 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) | |||
| 235 | 271 | ||
| 236 | int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) | 272 | int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) |
| 237 | { | 273 | { |
| 238 | unsigned int i, j, k; | ||
| 239 | u32 flags; | 274 | u32 flags; |
| 240 | struct fwht_cframe cf; | 275 | struct fwht_cframe cf; |
| 241 | u8 *p, *ref_p; | ||
| 242 | unsigned int components_num = 3; | 276 | unsigned int components_num = 3; |
| 243 | unsigned int version; | 277 | unsigned int version; |
| 244 | const struct v4l2_fwht_pixfmt_info *info; | 278 | const struct v4l2_fwht_pixfmt_info *info; |
| 245 | unsigned int hdr_width_div, hdr_height_div; | 279 | unsigned int hdr_width_div, hdr_height_div; |
| 280 | struct fwht_raw_frame dst_rf; | ||
| 281 | unsigned int dst_chroma_stride = state->stride; | ||
| 282 | unsigned int ref_chroma_stride = state->ref_stride; | ||
| 283 | unsigned int dst_size = state->stride * state->coded_height; | ||
| 284 | unsigned int ref_size; | ||
| 246 | 285 | ||
| 247 | if (!state->info) | 286 | if (!state->info) |
| 248 | return -EINVAL; | 287 | return -EINVAL; |
| @@ -290,241 +329,29 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) | |||
| 290 | hdr_height_div != info->height_div) | 329 | hdr_height_div != info->height_div) |
| 291 | return -EINVAL; | 330 | return -EINVAL; |
| 292 | 331 | ||
| 293 | if (!fwht_decode_frame(&cf, &state->ref_frame, flags, components_num, | 332 | if (prepare_raw_frame(&dst_rf, info, p_out, dst_size)) |
| 294 | state->visible_width, state->visible_height, | ||
| 295 | state->coded_width)) | ||
| 296 | return -EINVAL; | 333 | return -EINVAL; |
| 334 | if (info->planes_num == 3) { | ||
| 335 | dst_chroma_stride /= 2; | ||
| 336 | ref_chroma_stride /= 2; | ||
| 337 | } | ||
| 338 | if (info->id == V4L2_PIX_FMT_NV24 || | ||
| 339 | info->id == V4L2_PIX_FMT_NV42) { | ||
| 340 | dst_chroma_stride *= 2; | ||
| 341 | ref_chroma_stride *= 2; | ||
| 342 | } | ||
| 297 | 343 | ||
| 298 | /* | ||
| 299 | * TODO - handle the case where the compressed stream encodes a | ||
| 300 | * different format than the requested decoded format. | ||
| 301 | */ | ||
| 302 | switch (state->info->id) { | ||
| 303 | case V4L2_PIX_FMT_GREY: | ||
| 304 | ref_p = state->ref_frame.luma; | ||
| 305 | for (i = 0; i < state->coded_height; i++) { | ||
| 306 | memcpy(p_out, ref_p, state->visible_width); | ||
| 307 | p_out += state->stride; | ||
| 308 | ref_p += state->coded_width; | ||
| 309 | } | ||
| 310 | break; | ||
| 311 | case V4L2_PIX_FMT_YUV420: | ||
| 312 | case V4L2_PIX_FMT_YUV422P: | ||
| 313 | ref_p = state->ref_frame.luma; | ||
| 314 | for (i = 0; i < state->coded_height; i++) { | ||
| 315 | memcpy(p_out, ref_p, state->visible_width); | ||
| 316 | p_out += state->stride; | ||
| 317 | ref_p += state->coded_width; | ||
| 318 | } | ||
| 319 | 344 | ||
| 320 | ref_p = state->ref_frame.cb; | 345 | ref_size = state->ref_stride * state->coded_height; |
| 321 | for (i = 0; i < state->coded_height / 2; i++) { | ||
| 322 | memcpy(p_out, ref_p, state->visible_width / 2); | ||
| 323 | p_out += state->stride / 2; | ||
| 324 | ref_p += state->coded_width / 2; | ||
| 325 | } | ||
| 326 | ref_p = state->ref_frame.cr; | ||
| 327 | for (i = 0; i < state->coded_height / 2; i++) { | ||
| 328 | memcpy(p_out, ref_p, state->visible_width / 2); | ||
| 329 | p_out += state->stride / 2; | ||
| 330 | ref_p += state->coded_width / 2; | ||
| 331 | } | ||
| 332 | break; | ||
| 333 | case V4L2_PIX_FMT_YVU420: | ||
| 334 | ref_p = state->ref_frame.luma; | ||
| 335 | for (i = 0; i < state->coded_height; i++) { | ||
| 336 | memcpy(p_out, ref_p, state->visible_width); | ||
| 337 | p_out += state->stride; | ||
| 338 | ref_p += state->coded_width; | ||
| 339 | } | ||
| 340 | |||
| 341 | ref_p = state->ref_frame.cr; | ||
| 342 | for (i = 0; i < state->coded_height / 2; i++) { | ||
| 343 | memcpy(p_out, ref_p, state->visible_width / 2); | ||
| 344 | p_out += state->stride / 2; | ||
| 345 | ref_p += state->coded_width / 2; | ||
| 346 | } | ||
| 347 | ref_p = state->ref_frame.cb; | ||
| 348 | for (i = 0; i < state->coded_height / 2; i++) { | ||
| 349 | memcpy(p_out, ref_p, state->visible_width / 2); | ||
| 350 | p_out += state->stride / 2; | ||
| 351 | ref_p += state->coded_width / 2; | ||
| 352 | } | ||
| 353 | break; | ||
| 354 | case V4L2_PIX_FMT_NV12: | ||
| 355 | case V4L2_PIX_FMT_NV16: | ||
| 356 | case V4L2_PIX_FMT_NV24: | ||
| 357 | ref_p = state->ref_frame.luma; | ||
| 358 | for (i = 0; i < state->coded_height; i++) { | ||
| 359 | memcpy(p_out, ref_p, state->visible_width); | ||
| 360 | p_out += state->stride; | ||
| 361 | ref_p += state->coded_width; | ||
| 362 | } | ||
| 363 | 346 | ||
| 364 | k = 0; | 347 | if (prepare_raw_frame(&state->ref_frame, info, state->ref_frame.buf, |
| 365 | for (i = 0; i < state->coded_height / 2; i++) { | 348 | ref_size)) |
| 366 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | 349 | return -EINVAL; |
| 367 | *p++ = state->ref_frame.cb[k]; | ||
| 368 | *p++ = state->ref_frame.cr[k]; | ||
| 369 | k++; | ||
| 370 | } | ||
| 371 | p_out += state->stride; | ||
| 372 | } | ||
| 373 | break; | ||
| 374 | case V4L2_PIX_FMT_NV21: | ||
| 375 | case V4L2_PIX_FMT_NV61: | ||
| 376 | case V4L2_PIX_FMT_NV42: | ||
| 377 | ref_p = state->ref_frame.luma; | ||
| 378 | for (i = 0; i < state->coded_height; i++) { | ||
| 379 | memcpy(p_out, ref_p, state->visible_width); | ||
| 380 | p_out += state->stride; | ||
| 381 | ref_p += state->coded_width; | ||
| 382 | } | ||
| 383 | 350 | ||
| 384 | k = 0; | 351 | if (!fwht_decode_frame(&cf, flags, components_num, |
| 385 | for (i = 0; i < state->coded_height / 2; i++) { | 352 | state->visible_width, state->visible_height, |
| 386 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | 353 | &state->ref_frame, state->ref_stride, ref_chroma_stride, |
| 387 | *p++ = state->ref_frame.cr[k]; | 354 | &dst_rf, state->stride, dst_chroma_stride)) |
| 388 | *p++ = state->ref_frame.cb[k]; | ||
| 389 | k++; | ||
| 390 | } | ||
| 391 | p_out += state->stride; | ||
| 392 | } | ||
| 393 | break; | ||
| 394 | case V4L2_PIX_FMT_YUYV: | ||
| 395 | k = 0; | ||
| 396 | for (i = 0; i < state->coded_height; i++) { | ||
| 397 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | ||
| 398 | *p++ = state->ref_frame.luma[k]; | ||
| 399 | *p++ = state->ref_frame.cb[k / 2]; | ||
| 400 | *p++ = state->ref_frame.luma[k + 1]; | ||
| 401 | *p++ = state->ref_frame.cr[k / 2]; | ||
| 402 | k += 2; | ||
| 403 | } | ||
| 404 | p_out += state->stride; | ||
| 405 | } | ||
| 406 | break; | ||
| 407 | case V4L2_PIX_FMT_YVYU: | ||
| 408 | k = 0; | ||
| 409 | for (i = 0; i < state->coded_height; i++) { | ||
| 410 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | ||
| 411 | *p++ = state->ref_frame.luma[k]; | ||
| 412 | *p++ = state->ref_frame.cr[k / 2]; | ||
| 413 | *p++ = state->ref_frame.luma[k + 1]; | ||
| 414 | *p++ = state->ref_frame.cb[k / 2]; | ||
| 415 | k += 2; | ||
| 416 | } | ||
| 417 | p_out += state->stride; | ||
| 418 | } | ||
| 419 | break; | ||
| 420 | case V4L2_PIX_FMT_UYVY: | ||
| 421 | k = 0; | ||
| 422 | for (i = 0; i < state->coded_height; i++) { | ||
| 423 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | ||
| 424 | *p++ = state->ref_frame.cb[k / 2]; | ||
| 425 | *p++ = state->ref_frame.luma[k]; | ||
| 426 | *p++ = state->ref_frame.cr[k / 2]; | ||
| 427 | *p++ = state->ref_frame.luma[k + 1]; | ||
| 428 | k += 2; | ||
| 429 | } | ||
| 430 | p_out += state->stride; | ||
| 431 | } | ||
| 432 | break; | ||
| 433 | case V4L2_PIX_FMT_VYUY: | ||
| 434 | k = 0; | ||
| 435 | for (i = 0; i < state->coded_height; i++) { | ||
| 436 | for (j = 0, p = p_out; j < state->coded_width / 2; j++) { | ||
| 437 | *p++ = state->ref_frame.cr[k / 2]; | ||
| 438 | *p++ = state->ref_frame.luma[k]; | ||
| 439 | *p++ = state->ref_frame.cb[k / 2]; | ||
| 440 | *p++ = state->ref_frame.luma[k + 1]; | ||
| 441 | k += 2; | ||
| 442 | } | ||
| 443 | p_out += state->stride; | ||
| 444 | } | ||
| 445 | break; | ||
| 446 | case V4L2_PIX_FMT_RGB24: | ||
| 447 | case V4L2_PIX_FMT_HSV24: | ||
| 448 | k = 0; | ||
| 449 | for (i = 0; i < state->coded_height; i++) { | ||
| 450 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 451 | *p++ = state->ref_frame.cr[k]; | ||
| 452 | *p++ = state->ref_frame.luma[k]; | ||
| 453 | *p++ = state->ref_frame.cb[k]; | ||
| 454 | k++; | ||
| 455 | } | ||
| 456 | p_out += state->stride; | ||
| 457 | } | ||
| 458 | break; | ||
| 459 | case V4L2_PIX_FMT_BGR24: | ||
| 460 | k = 0; | ||
| 461 | for (i = 0; i < state->coded_height; i++) { | ||
| 462 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 463 | *p++ = state->ref_frame.cb[k]; | ||
| 464 | *p++ = state->ref_frame.luma[k]; | ||
| 465 | *p++ = state->ref_frame.cr[k]; | ||
| 466 | k++; | ||
| 467 | } | ||
| 468 | p_out += state->stride; | ||
| 469 | } | ||
| 470 | break; | ||
| 471 | case V4L2_PIX_FMT_RGB32: | ||
| 472 | case V4L2_PIX_FMT_XRGB32: | ||
| 473 | case V4L2_PIX_FMT_HSV32: | ||
| 474 | k = 0; | ||
| 475 | for (i = 0; i < state->coded_height; i++) { | ||
| 476 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 477 | *p++ = 0; | ||
| 478 | *p++ = state->ref_frame.cr[k]; | ||
| 479 | *p++ = state->ref_frame.luma[k]; | ||
| 480 | *p++ = state->ref_frame.cb[k]; | ||
| 481 | k++; | ||
| 482 | } | ||
| 483 | p_out += state->stride; | ||
| 484 | } | ||
| 485 | break; | ||
| 486 | case V4L2_PIX_FMT_BGR32: | ||
| 487 | case V4L2_PIX_FMT_XBGR32: | ||
| 488 | k = 0; | ||
| 489 | for (i = 0; i < state->coded_height; i++) { | ||
| 490 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 491 | *p++ = state->ref_frame.cb[k]; | ||
| 492 | *p++ = state->ref_frame.luma[k]; | ||
| 493 | *p++ = state->ref_frame.cr[k]; | ||
| 494 | *p++ = 0; | ||
| 495 | k++; | ||
| 496 | } | ||
| 497 | p_out += state->stride; | ||
| 498 | } | ||
| 499 | break; | ||
| 500 | case V4L2_PIX_FMT_ARGB32: | ||
| 501 | k = 0; | ||
| 502 | for (i = 0; i < state->coded_height; i++) { | ||
| 503 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 504 | *p++ = state->ref_frame.alpha[k]; | ||
| 505 | *p++ = state->ref_frame.cr[k]; | ||
| 506 | *p++ = state->ref_frame.luma[k]; | ||
| 507 | *p++ = state->ref_frame.cb[k]; | ||
| 508 | k++; | ||
| 509 | } | ||
| 510 | p_out += state->stride; | ||
| 511 | } | ||
| 512 | break; | ||
| 513 | case V4L2_PIX_FMT_ABGR32: | ||
| 514 | k = 0; | ||
| 515 | for (i = 0; i < state->coded_height; i++) { | ||
| 516 | for (j = 0, p = p_out; j < state->coded_width; j++) { | ||
| 517 | *p++ = state->ref_frame.cb[k]; | ||
| 518 | *p++ = state->ref_frame.luma[k]; | ||
| 519 | *p++ = state->ref_frame.cr[k]; | ||
| 520 | *p++ = state->ref_frame.alpha[k]; | ||
| 521 | k++; | ||
| 522 | } | ||
| 523 | p_out += state->stride; | ||
| 524 | } | ||
| 525 | break; | ||
| 526 | default: | ||
| 527 | return -EINVAL; | 355 | return -EINVAL; |
| 528 | } | ||
| 529 | return 0; | 356 | return 0; |
| 530 | } | 357 | } |
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.h b/drivers/media/platform/vicodec/codec-v4l2-fwht.h index aa6fa90a48be..1a0d2a9f931a 100644 --- a/drivers/media/platform/vicodec/codec-v4l2-fwht.h +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.h | |||
| @@ -30,6 +30,7 @@ struct v4l2_fwht_state { | |||
| 30 | unsigned int coded_width; | 30 | unsigned int coded_width; |
| 31 | unsigned int coded_height; | 31 | unsigned int coded_height; |
| 32 | unsigned int stride; | 32 | unsigned int stride; |
| 33 | unsigned int ref_stride; | ||
| 33 | unsigned int gop_size; | 34 | unsigned int gop_size; |
| 34 | unsigned int gop_cnt; | 35 | unsigned int gop_cnt; |
| 35 | u16 i_frame_qp; | 36 | u16 i_frame_qp; |
| @@ -43,11 +44,15 @@ struct v4l2_fwht_state { | |||
| 43 | struct fwht_raw_frame ref_frame; | 44 | struct fwht_raw_frame ref_frame; |
| 44 | struct fwht_cframe_hdr header; | 45 | struct fwht_cframe_hdr header; |
| 45 | u8 *compressed_frame; | 46 | u8 *compressed_frame; |
| 47 | u64 ref_frame_ts; | ||
| 46 | }; | 48 | }; |
| 47 | 49 | ||
| 48 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat); | 50 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat); |
| 49 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx); | 51 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx); |
| 50 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt(u32 width_div, | 52 | bool v4l2_fwht_validate_fmt(const struct v4l2_fwht_pixfmt_info *info, |
| 53 | u32 width_div, u32 height_div, u32 components_num, | ||
| 54 | u32 pixenc); | ||
| 55 | const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_nth_fmt(u32 width_div, | ||
| 51 | u32 height_div, | 56 | u32 height_div, |
| 52 | u32 components_num, | 57 | u32 components_num, |
| 53 | u32 pixenc, | 58 | u32 pixenc, |
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index d7636fe9e174..bd01a9206aa6 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c | |||
| @@ -64,6 +64,10 @@ static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = { | |||
| 64 | V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1 | 64 | V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1 |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = { | ||
| 68 | V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1 | ||
| 69 | }; | ||
| 70 | |||
| 67 | static void vicodec_dev_release(struct device *dev) | 71 | static void vicodec_dev_release(struct device *dev) |
| 68 | { | 72 | { |
| 69 | } | 73 | } |
| @@ -89,27 +93,29 @@ enum { | |||
| 89 | V4L2_M2M_DST = 1, | 93 | V4L2_M2M_DST = 1, |
| 90 | }; | 94 | }; |
| 91 | 95 | ||
| 96 | struct vicodec_dev_instance { | ||
| 97 | struct video_device vfd; | ||
| 98 | struct mutex mutex; | ||
| 99 | spinlock_t lock; | ||
| 100 | struct v4l2_m2m_dev *m2m_dev; | ||
| 101 | }; | ||
| 102 | |||
| 92 | struct vicodec_dev { | 103 | struct vicodec_dev { |
| 93 | struct v4l2_device v4l2_dev; | 104 | struct v4l2_device v4l2_dev; |
| 94 | struct video_device enc_vfd; | 105 | struct vicodec_dev_instance stateful_enc; |
| 95 | struct video_device dec_vfd; | 106 | struct vicodec_dev_instance stateful_dec; |
| 107 | struct vicodec_dev_instance stateless_dec; | ||
| 96 | #ifdef CONFIG_MEDIA_CONTROLLER | 108 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 97 | struct media_device mdev; | 109 | struct media_device mdev; |
| 98 | #endif | 110 | #endif |
| 99 | 111 | ||
| 100 | struct mutex enc_mutex; | ||
| 101 | struct mutex dec_mutex; | ||
| 102 | spinlock_t enc_lock; | ||
| 103 | spinlock_t dec_lock; | ||
| 104 | |||
| 105 | struct v4l2_m2m_dev *enc_dev; | ||
| 106 | struct v4l2_m2m_dev *dec_dev; | ||
| 107 | }; | 112 | }; |
| 108 | 113 | ||
| 109 | struct vicodec_ctx { | 114 | struct vicodec_ctx { |
| 110 | struct v4l2_fh fh; | 115 | struct v4l2_fh fh; |
| 111 | struct vicodec_dev *dev; | 116 | struct vicodec_dev *dev; |
| 112 | bool is_enc; | 117 | bool is_enc; |
| 118 | bool is_stateless; | ||
| 113 | spinlock_t *lock; | 119 | spinlock_t *lock; |
| 114 | 120 | ||
| 115 | struct v4l2_ctrl_handler hdl; | 121 | struct v4l2_ctrl_handler hdl; |
| @@ -148,27 +154,149 @@ static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx, | |||
| 148 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 154 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
| 149 | return &ctx->q_data[V4L2_M2M_DST]; | 155 | return &ctx->q_data[V4L2_M2M_DST]; |
| 150 | default: | 156 | default: |
| 151 | WARN_ON(1); | ||
| 152 | break; | 157 | break; |
| 153 | } | 158 | } |
| 154 | return NULL; | 159 | return NULL; |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 162 | static void copy_cap_to_ref(const u8 *cap, const struct v4l2_fwht_pixfmt_info *info, | ||
| 163 | struct v4l2_fwht_state *state) | ||
| 164 | { | ||
| 165 | int plane_idx; | ||
| 166 | u8 *p_ref = state->ref_frame.buf; | ||
| 167 | unsigned int cap_stride = state->stride; | ||
| 168 | unsigned int ref_stride = state->ref_stride; | ||
| 169 | |||
| 170 | for (plane_idx = 0; plane_idx < info->planes_num; plane_idx++) { | ||
| 171 | int i; | ||
| 172 | unsigned int h_div = (plane_idx == 1 || plane_idx == 2) ? | ||
| 173 | info->height_div : 1; | ||
| 174 | const u8 *row_cap = cap; | ||
| 175 | u8 *row_ref = p_ref; | ||
| 176 | |||
| 177 | if (info->planes_num == 3 && plane_idx == 1) { | ||
| 178 | cap_stride /= 2; | ||
| 179 | ref_stride /= 2; | ||
| 180 | } | ||
| 181 | |||
| 182 | if (plane_idx == 1 && | ||
| 183 | (info->id == V4L2_PIX_FMT_NV24 || | ||
| 184 | info->id == V4L2_PIX_FMT_NV42)) { | ||
| 185 | cap_stride *= 2; | ||
| 186 | ref_stride *= 2; | ||
| 187 | } | ||
| 188 | |||
| 189 | for (i = 0; i < state->visible_height / h_div; i++) { | ||
| 190 | memcpy(row_ref, row_cap, ref_stride); | ||
| 191 | row_ref += ref_stride; | ||
| 192 | row_cap += cap_stride; | ||
| 193 | } | ||
| 194 | cap += cap_stride * (state->coded_height / h_div); | ||
| 195 | p_ref += ref_stride * (state->coded_height / h_div); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | static bool validate_by_version(unsigned int flags, unsigned int version) | ||
| 200 | { | ||
| 201 | if (!version || version > FWHT_VERSION) | ||
| 202 | return false; | ||
| 203 | |||
| 204 | if (version >= 2) { | ||
| 205 | unsigned int components_num = 1 + | ||
| 206 | ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >> | ||
| 207 | FWHT_FL_COMPONENTS_NUM_OFFSET); | ||
| 208 | unsigned int pixenc = flags & FWHT_FL_PIXENC_MSK; | ||
| 209 | |||
| 210 | if (components_num == 0 || components_num > 4 || !pixenc) | ||
| 211 | return false; | ||
| 212 | } | ||
| 213 | return true; | ||
| 214 | } | ||
| 215 | |||
| 216 | static bool validate_stateless_params_flags(const struct v4l2_ctrl_fwht_params *params, | ||
| 217 | const struct v4l2_fwht_pixfmt_info *cur_info) | ||
| 218 | { | ||
| 219 | unsigned int width_div = | ||
| 220 | (params->flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2; | ||
| 221 | unsigned int height_div = | ||
| 222 | (params->flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2; | ||
| 223 | unsigned int components_num = 3; | ||
| 224 | unsigned int pixenc = 0; | ||
| 225 | |||
| 226 | if (params->version < 3) | ||
| 227 | return false; | ||
| 228 | |||
| 229 | components_num = 1 + ((params->flags & FWHT_FL_COMPONENTS_NUM_MSK) >> | ||
| 230 | FWHT_FL_COMPONENTS_NUM_OFFSET); | ||
| 231 | pixenc = (params->flags & FWHT_FL_PIXENC_MSK); | ||
| 232 | if (v4l2_fwht_validate_fmt(cur_info, width_div, height_div, | ||
| 233 | components_num, pixenc)) | ||
| 234 | return true; | ||
| 235 | return false; | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | static void update_state_from_header(struct vicodec_ctx *ctx) | ||
| 240 | { | ||
| 241 | const struct fwht_cframe_hdr *p_hdr = &ctx->state.header; | ||
| 242 | |||
| 243 | ctx->state.visible_width = ntohl(p_hdr->width); | ||
| 244 | ctx->state.visible_height = ntohl(p_hdr->height); | ||
| 245 | ctx->state.colorspace = ntohl(p_hdr->colorspace); | ||
| 246 | ctx->state.xfer_func = ntohl(p_hdr->xfer_func); | ||
| 247 | ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc); | ||
| 248 | ctx->state.quantization = ntohl(p_hdr->quantization); | ||
| 249 | } | ||
| 250 | |||
| 157 | static int device_process(struct vicodec_ctx *ctx, | 251 | static int device_process(struct vicodec_ctx *ctx, |
| 158 | struct vb2_v4l2_buffer *src_vb, | 252 | struct vb2_v4l2_buffer *src_vb, |
| 159 | struct vb2_v4l2_buffer *dst_vb) | 253 | struct vb2_v4l2_buffer *dst_vb) |
| 160 | { | 254 | { |
| 161 | struct vicodec_dev *dev = ctx->dev; | 255 | struct vicodec_dev *dev = ctx->dev; |
| 162 | struct vicodec_q_data *q_dst; | ||
| 163 | struct v4l2_fwht_state *state = &ctx->state; | 256 | struct v4l2_fwht_state *state = &ctx->state; |
| 164 | u8 *p_src, *p_dst; | 257 | u8 *p_src, *p_dst; |
| 165 | int ret; | 258 | int ret = 0; |
| 166 | 259 | ||
| 167 | q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | 260 | if (ctx->is_enc || ctx->is_stateless) |
| 168 | if (ctx->is_enc) | ||
| 169 | p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0); | 261 | p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0); |
| 170 | else | 262 | else |
| 171 | p_src = state->compressed_frame; | 263 | p_src = state->compressed_frame; |
| 264 | |||
| 265 | if (ctx->is_stateless) { | ||
| 266 | struct media_request *src_req = src_vb->vb2_buf.req_obj.req; | ||
| 267 | |||
| 268 | ret = v4l2_ctrl_request_setup(src_req, &ctx->hdl); | ||
| 269 | if (ret) | ||
| 270 | return ret; | ||
| 271 | update_state_from_header(ctx); | ||
| 272 | |||
| 273 | ctx->state.header.size = | ||
| 274 | htonl(vb2_get_plane_payload(&src_vb->vb2_buf, 0)); | ||
| 275 | /* | ||
| 276 | * set the reference buffer from the reference timestamp | ||
| 277 | * only if this is a P-frame | ||
| 278 | */ | ||
| 279 | if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) { | ||
| 280 | struct vb2_buffer *ref_vb2_buf; | ||
| 281 | int ref_buf_idx; | ||
| 282 | struct vb2_queue *vq_cap = | ||
| 283 | v4l2_m2m_get_vq(ctx->fh.m2m_ctx, | ||
| 284 | V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
| 285 | |||
| 286 | ref_buf_idx = vb2_find_timestamp(vq_cap, | ||
| 287 | ctx->state.ref_frame_ts, 0); | ||
| 288 | if (ref_buf_idx < 0) | ||
| 289 | return -EINVAL; | ||
| 290 | |||
| 291 | ref_vb2_buf = vq_cap->bufs[ref_buf_idx]; | ||
| 292 | if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR) | ||
| 293 | ret = -EINVAL; | ||
| 294 | ctx->state.ref_frame.buf = | ||
| 295 | vb2_plane_vaddr(ref_vb2_buf, 0); | ||
| 296 | } else { | ||
| 297 | ctx->state.ref_frame.buf = NULL; | ||
| 298 | } | ||
| 299 | } | ||
| 172 | p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0); | 300 | p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0); |
| 173 | if (!p_src || !p_dst) { | 301 | if (!p_src || !p_dst) { |
| 174 | v4l2_err(&dev->v4l2_dev, | 302 | v4l2_err(&dev->v4l2_dev, |
| @@ -178,30 +306,31 @@ static int device_process(struct vicodec_ctx *ctx, | |||
| 178 | 306 | ||
| 179 | if (ctx->is_enc) { | 307 | if (ctx->is_enc) { |
| 180 | struct vicodec_q_data *q_src; | 308 | struct vicodec_q_data *q_src; |
| 309 | int comp_sz_or_errcode; | ||
| 181 | 310 | ||
| 182 | q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | 311 | q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
| 183 | state->info = q_src->info; | 312 | state->info = q_src->info; |
| 184 | ret = v4l2_fwht_encode(state, p_src, p_dst); | 313 | comp_sz_or_errcode = v4l2_fwht_encode(state, p_src, p_dst); |
| 185 | if (ret < 0) | 314 | if (comp_sz_or_errcode < 0) |
| 186 | return ret; | 315 | return comp_sz_or_errcode; |
| 187 | vb2_set_plane_payload(&dst_vb->vb2_buf, 0, ret); | 316 | vb2_set_plane_payload(&dst_vb->vb2_buf, 0, comp_sz_or_errcode); |
| 188 | } else { | 317 | } else { |
| 318 | struct vicodec_q_data *q_dst; | ||
| 189 | unsigned int comp_frame_size = ntohl(ctx->state.header.size); | 319 | unsigned int comp_frame_size = ntohl(ctx->state.header.size); |
| 190 | 320 | ||
| 321 | q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
| 191 | if (comp_frame_size > ctx->comp_max_size) | 322 | if (comp_frame_size > ctx->comp_max_size) |
| 192 | return -EINVAL; | 323 | return -EINVAL; |
| 193 | state->info = q_dst->info; | 324 | state->info = q_dst->info; |
| 194 | ret = v4l2_fwht_decode(state, p_src, p_dst); | 325 | ret = v4l2_fwht_decode(state, p_src, p_dst); |
| 195 | if (ret < 0) | 326 | if (ret < 0) |
| 196 | return ret; | 327 | return ret; |
| 328 | if (!ctx->is_stateless) | ||
| 329 | copy_cap_to_ref(p_dst, ctx->state.info, &ctx->state); | ||
| 330 | |||
| 197 | vb2_set_plane_payload(&dst_vb->vb2_buf, 0, q_dst->sizeimage); | 331 | vb2_set_plane_payload(&dst_vb->vb2_buf, 0, q_dst->sizeimage); |
| 198 | } | 332 | } |
| 199 | 333 | return ret; | |
| 200 | dst_vb->sequence = q_dst->sequence++; | ||
| 201 | dst_vb->flags &= ~V4L2_BUF_FLAG_LAST; | ||
| 202 | v4l2_m2m_buf_copy_metadata(src_vb, dst_vb, !ctx->is_enc); | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | } | 334 | } |
| 206 | 335 | ||
| 207 | /* | 336 | /* |
| @@ -274,16 +403,26 @@ static void device_run(void *priv) | |||
| 274 | struct vicodec_ctx *ctx = priv; | 403 | struct vicodec_ctx *ctx = priv; |
| 275 | struct vicodec_dev *dev = ctx->dev; | 404 | struct vicodec_dev *dev = ctx->dev; |
| 276 | struct vb2_v4l2_buffer *src_buf, *dst_buf; | 405 | struct vb2_v4l2_buffer *src_buf, *dst_buf; |
| 277 | struct vicodec_q_data *q_src; | 406 | struct vicodec_q_data *q_src, *q_dst; |
| 278 | u32 state; | 407 | u32 state; |
| 408 | struct media_request *src_req; | ||
| 409 | |||
| 279 | 410 | ||
| 280 | src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); | 411 | src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); |
| 281 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); | 412 | dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); |
| 413 | src_req = src_buf->vb2_buf.req_obj.req; | ||
| 414 | |||
| 282 | q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); | 415 | q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); |
| 416 | q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
| 283 | 417 | ||
| 284 | state = VB2_BUF_STATE_DONE; | 418 | state = VB2_BUF_STATE_DONE; |
| 285 | if (device_process(ctx, src_buf, dst_buf)) | 419 | if (device_process(ctx, src_buf, dst_buf)) |
| 286 | state = VB2_BUF_STATE_ERROR; | 420 | state = VB2_BUF_STATE_ERROR; |
| 421 | else | ||
| 422 | dst_buf->sequence = q_dst->sequence++; | ||
| 423 | dst_buf->flags &= ~V4L2_BUF_FLAG_LAST; | ||
| 424 | v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc); | ||
| 425 | |||
| 287 | ctx->last_dst_buf = dst_buf; | 426 | ctx->last_dst_buf = dst_buf; |
| 288 | 427 | ||
| 289 | spin_lock(ctx->lock); | 428 | spin_lock(ctx->lock); |
| @@ -291,7 +430,7 @@ static void device_run(void *priv) | |||
| 291 | dst_buf->flags |= V4L2_BUF_FLAG_LAST; | 430 | dst_buf->flags |= V4L2_BUF_FLAG_LAST; |
| 292 | v4l2_event_queue_fh(&ctx->fh, &eos_event); | 431 | v4l2_event_queue_fh(&ctx->fh, &eos_event); |
| 293 | } | 432 | } |
| 294 | if (ctx->is_enc) { | 433 | if (ctx->is_enc || ctx->is_stateless) { |
| 295 | src_buf->sequence = q_src->sequence++; | 434 | src_buf->sequence = q_src->sequence++; |
| 296 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); | 435 | src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); |
| 297 | v4l2_m2m_buf_done(src_buf, state); | 436 | v4l2_m2m_buf_done(src_buf, state); |
| @@ -303,6 +442,9 @@ static void device_run(void *priv) | |||
| 303 | ctx->comp_has_next_frame = false; | 442 | ctx->comp_has_next_frame = false; |
| 304 | } | 443 | } |
| 305 | v4l2_m2m_buf_done(dst_buf, state); | 444 | v4l2_m2m_buf_done(dst_buf, state); |
| 445 | if (ctx->is_stateless && src_req) | ||
| 446 | v4l2_ctrl_request_complete(src_req, &ctx->hdl); | ||
| 447 | |||
| 306 | ctx->comp_size = 0; | 448 | ctx->comp_size = 0; |
| 307 | ctx->header_size = 0; | 449 | ctx->header_size = 0; |
| 308 | ctx->comp_magic_cnt = 0; | 450 | ctx->comp_magic_cnt = 0; |
| @@ -310,9 +452,12 @@ static void device_run(void *priv) | |||
| 310 | spin_unlock(ctx->lock); | 452 | spin_unlock(ctx->lock); |
| 311 | 453 | ||
| 312 | if (ctx->is_enc) | 454 | if (ctx->is_enc) |
| 313 | v4l2_m2m_job_finish(dev->enc_dev, ctx->fh.m2m_ctx); | 455 | v4l2_m2m_job_finish(dev->stateful_enc.m2m_dev, ctx->fh.m2m_ctx); |
| 456 | else if (ctx->is_stateless) | ||
| 457 | v4l2_m2m_job_finish(dev->stateless_dec.m2m_dev, | ||
| 458 | ctx->fh.m2m_ctx); | ||
| 314 | else | 459 | else |
| 315 | v4l2_m2m_job_finish(dev->dec_dev, ctx->fh.m2m_ctx); | 460 | v4l2_m2m_job_finish(dev->stateful_dec.m2m_dev, ctx->fh.m2m_ctx); |
| 316 | } | 461 | } |
| 317 | 462 | ||
| 318 | static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state) | 463 | static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state) |
| @@ -344,7 +489,7 @@ info_from_header(const struct fwht_cframe_hdr *p_hdr) | |||
| 344 | FWHT_FL_COMPONENTS_NUM_OFFSET); | 489 | FWHT_FL_COMPONENTS_NUM_OFFSET); |
| 345 | pixenc = (flags & FWHT_FL_PIXENC_MSK); | 490 | pixenc = (flags & FWHT_FL_PIXENC_MSK); |
| 346 | } | 491 | } |
| 347 | return v4l2_fwht_default_fmt(width_div, height_div, | 492 | return v4l2_fwht_find_nth_fmt(width_div, height_div, |
| 348 | components_num, pixenc, 0); | 493 | components_num, pixenc, 0); |
| 349 | } | 494 | } |
| 350 | 495 | ||
| @@ -356,21 +501,11 @@ static bool is_header_valid(const struct fwht_cframe_hdr *p_hdr) | |||
| 356 | unsigned int version = ntohl(p_hdr->version); | 501 | unsigned int version = ntohl(p_hdr->version); |
| 357 | unsigned int flags = ntohl(p_hdr->flags); | 502 | unsigned int flags = ntohl(p_hdr->flags); |
| 358 | 503 | ||
| 359 | if (!version || version > FWHT_VERSION) | ||
| 360 | return false; | ||
| 361 | |||
| 362 | if (w < MIN_WIDTH || w > MAX_WIDTH || h < MIN_HEIGHT || h > MAX_HEIGHT) | 504 | if (w < MIN_WIDTH || w > MAX_WIDTH || h < MIN_HEIGHT || h > MAX_HEIGHT) |
| 363 | return false; | 505 | return false; |
| 364 | 506 | ||
| 365 | if (version >= 2) { | 507 | if (!validate_by_version(flags, version)) |
| 366 | unsigned int components_num = 1 + | 508 | return false; |
| 367 | ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >> | ||
| 368 | FWHT_FL_COMPONENTS_NUM_OFFSET); | ||
| 369 | unsigned int pixenc = flags & FWHT_FL_PIXENC_MSK; | ||
| 370 | |||
| 371 | if (components_num == 0 || components_num > 4 || !pixenc) | ||
| 372 | return false; | ||
| 373 | } | ||
| 374 | 509 | ||
| 375 | info = info_from_header(p_hdr); | 510 | info = info_from_header(p_hdr); |
| 376 | if (!info) | 511 | if (!info) |
| @@ -388,6 +523,12 @@ static void update_capture_data_from_header(struct vicodec_ctx *ctx) | |||
| 388 | unsigned int hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2; | 523 | unsigned int hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2; |
| 389 | unsigned int hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2; | 524 | unsigned int hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2; |
| 390 | 525 | ||
| 526 | /* | ||
| 527 | * This function should not be used by a stateless codec since | ||
| 528 | * it changes values in q_data that are not request specific | ||
| 529 | */ | ||
| 530 | WARN_ON(ctx->is_stateless); | ||
| 531 | |||
| 391 | q_dst->info = info; | 532 | q_dst->info = info; |
| 392 | q_dst->visible_width = ntohl(p_hdr->width); | 533 | q_dst->visible_width = ntohl(p_hdr->width); |
| 393 | q_dst->visible_height = ntohl(p_hdr->height); | 534 | q_dst->visible_height = ntohl(p_hdr->height); |
| @@ -440,7 +581,7 @@ static int job_ready(void *priv) | |||
| 440 | 581 | ||
| 441 | if (ctx->source_changed) | 582 | if (ctx->source_changed) |
| 442 | return 0; | 583 | return 0; |
| 443 | if (ctx->is_enc || ctx->comp_has_frame) | 584 | if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame) |
| 444 | return 1; | 585 | return 1; |
| 445 | 586 | ||
| 446 | restart: | 587 | restart: |
| @@ -551,8 +692,8 @@ static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt) | |||
| 551 | static int vidioc_querycap(struct file *file, void *priv, | 692 | static int vidioc_querycap(struct file *file, void *priv, |
| 552 | struct v4l2_capability *cap) | 693 | struct v4l2_capability *cap) |
| 553 | { | 694 | { |
| 554 | strncpy(cap->driver, VICODEC_NAME, sizeof(cap->driver) - 1); | 695 | strscpy(cap->driver, VICODEC_NAME, sizeof(cap->driver)); |
| 555 | strncpy(cap->card, VICODEC_NAME, sizeof(cap->card) - 1); | 696 | strscpy(cap->card, VICODEC_NAME, sizeof(cap->card)); |
| 556 | snprintf(cap->bus_info, sizeof(cap->bus_info), | 697 | snprintf(cap->bus_info, sizeof(cap->bus_info), |
| 557 | "platform:%s", VICODEC_NAME); | 698 | "platform:%s", VICODEC_NAME); |
| 558 | return 0; | 699 | return 0; |
| @@ -575,7 +716,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx, | |||
| 575 | if (!info || ctx->is_enc) | 716 | if (!info || ctx->is_enc) |
| 576 | info = v4l2_fwht_get_pixfmt(f->index); | 717 | info = v4l2_fwht_get_pixfmt(f->index); |
| 577 | else | 718 | else |
| 578 | info = v4l2_fwht_default_fmt(info->width_div, | 719 | info = v4l2_fwht_find_nth_fmt(info->width_div, |
| 579 | info->height_div, | 720 | info->height_div, |
| 580 | info->components_num, | 721 | info->components_num, |
| 581 | info->pixenc, | 722 | info->pixenc, |
| @@ -586,7 +727,8 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx, | |||
| 586 | } else { | 727 | } else { |
| 587 | if (f->index) | 728 | if (f->index) |
| 588 | return -EINVAL; | 729 | return -EINVAL; |
| 589 | f->pixelformat = V4L2_PIX_FMT_FWHT; | 730 | f->pixelformat = ctx->is_stateless ? |
| 731 | V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT; | ||
| 590 | } | 732 | } |
| 591 | return 0; | 733 | return 0; |
| 592 | } | 734 | } |
| @@ -688,13 +830,15 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) | |||
| 688 | struct v4l2_pix_format_mplane *pix_mp; | 830 | struct v4l2_pix_format_mplane *pix_mp; |
| 689 | struct v4l2_pix_format *pix; | 831 | struct v4l2_pix_format *pix; |
| 690 | struct v4l2_plane_pix_format *plane; | 832 | struct v4l2_plane_pix_format *plane; |
| 691 | const struct v4l2_fwht_pixfmt_info *info = &pixfmt_fwht; | 833 | const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ? |
| 834 | &pixfmt_stateless_fwht : &pixfmt_fwht; | ||
| 692 | 835 | ||
| 693 | switch (f->type) { | 836 | switch (f->type) { |
| 694 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 837 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
| 695 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 838 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
| 696 | pix = &f->fmt.pix; | 839 | pix = &f->fmt.pix; |
| 697 | if (pix->pixelformat != V4L2_PIX_FMT_FWHT) | 840 | if (pix->pixelformat != V4L2_PIX_FMT_FWHT && |
| 841 | pix->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS) | ||
| 698 | info = find_fmt(pix->pixelformat); | 842 | info = find_fmt(pix->pixelformat); |
| 699 | 843 | ||
| 700 | pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); | 844 | pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH); |
| @@ -715,7 +859,8 @@ static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) | |||
| 715 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 859 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
| 716 | pix_mp = &f->fmt.pix_mp; | 860 | pix_mp = &f->fmt.pix_mp; |
| 717 | plane = pix_mp->plane_fmt; | 861 | plane = pix_mp->plane_fmt; |
| 718 | if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT) | 862 | if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT && |
| 863 | pix_mp->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS) | ||
| 719 | info = find_fmt(pix_mp->pixelformat); | 864 | info = find_fmt(pix_mp->pixelformat); |
| 720 | pix_mp->num_planes = 1; | 865 | pix_mp->num_planes = 1; |
| 721 | 866 | ||
| @@ -792,8 +937,12 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | |||
| 792 | if (multiplanar) | 937 | if (multiplanar) |
| 793 | return -EINVAL; | 938 | return -EINVAL; |
| 794 | pix = &f->fmt.pix; | 939 | pix = &f->fmt.pix; |
| 795 | pix->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT : | 940 | if (ctx->is_enc) |
| 796 | find_fmt(pix->pixelformat)->id; | 941 | pix->pixelformat = find_fmt(pix->pixelformat)->id; |
| 942 | else if (ctx->is_stateless) | ||
| 943 | pix->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS; | ||
| 944 | else | ||
| 945 | pix->pixelformat = V4L2_PIX_FMT_FWHT; | ||
| 797 | if (!pix->colorspace) | 946 | if (!pix->colorspace) |
| 798 | pix->colorspace = V4L2_COLORSPACE_REC709; | 947 | pix->colorspace = V4L2_COLORSPACE_REC709; |
| 799 | break; | 948 | break; |
| @@ -801,8 +950,12 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv, | |||
| 801 | if (!multiplanar) | 950 | if (!multiplanar) |
| 802 | return -EINVAL; | 951 | return -EINVAL; |
| 803 | pix_mp = &f->fmt.pix_mp; | 952 | pix_mp = &f->fmt.pix_mp; |
| 804 | pix_mp->pixelformat = !ctx->is_enc ? V4L2_PIX_FMT_FWHT : | 953 | if (ctx->is_enc) |
| 805 | find_fmt(pix_mp->pixelformat)->id; | 954 | pix_mp->pixelformat = find_fmt(pix_mp->pixelformat)->id; |
| 955 | else if (ctx->is_stateless) | ||
| 956 | pix_mp->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS; | ||
| 957 | else | ||
| 958 | pix_mp->pixelformat = V4L2_PIX_FMT_FWHT; | ||
| 806 | if (!pix_mp->colorspace) | 959 | if (!pix_mp->colorspace) |
| 807 | pix_mp->colorspace = V4L2_COLORSPACE_REC709; | 960 | pix_mp->colorspace = V4L2_COLORSPACE_REC709; |
| 808 | break; | 961 | break; |
| @@ -845,6 +998,8 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) | |||
| 845 | 998 | ||
| 846 | if (pix->pixelformat == V4L2_PIX_FMT_FWHT) | 999 | if (pix->pixelformat == V4L2_PIX_FMT_FWHT) |
| 847 | q_data->info = &pixfmt_fwht; | 1000 | q_data->info = &pixfmt_fwht; |
| 1001 | else if (pix->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS) | ||
| 1002 | q_data->info = &pixfmt_stateless_fwht; | ||
| 848 | else | 1003 | else |
| 849 | q_data->info = find_fmt(pix->pixelformat); | 1004 | q_data->info = find_fmt(pix->pixelformat); |
| 850 | q_data->coded_width = pix->width; | 1005 | q_data->coded_width = pix->width; |
| @@ -866,6 +1021,8 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) | |||
| 866 | 1021 | ||
| 867 | if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) | 1022 | if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT) |
| 868 | q_data->info = &pixfmt_fwht; | 1023 | q_data->info = &pixfmt_fwht; |
| 1024 | else if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS) | ||
| 1025 | q_data->info = &pixfmt_stateless_fwht; | ||
| 869 | else | 1026 | else |
| 870 | q_data->info = find_fmt(pix_mp->pixelformat); | 1027 | q_data->info = find_fmt(pix_mp->pixelformat); |
| 871 | q_data->coded_width = pix_mp->width; | 1028 | q_data->coded_width = pix_mp->width; |
| @@ -945,16 +1102,6 @@ static int vidioc_g_selection(struct file *file, void *priv, | |||
| 945 | { | 1102 | { |
| 946 | struct vicodec_ctx *ctx = file2ctx(file); | 1103 | struct vicodec_ctx *ctx = file2ctx(file); |
| 947 | struct vicodec_q_data *q_data; | 1104 | struct vicodec_q_data *q_data; |
| 948 | enum v4l2_buf_type valid_cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 949 | enum v4l2_buf_type valid_out_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 950 | |||
| 951 | if (multiplanar) { | ||
| 952 | valid_cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||
| 953 | valid_out_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | ||
| 954 | } | ||
| 955 | |||
| 956 | if (s->type != valid_cap_type && s->type != valid_out_type) | ||
| 957 | return -EINVAL; | ||
| 958 | 1105 | ||
| 959 | q_data = get_q_data(ctx, s->type); | 1106 | q_data = get_q_data(ctx, s->type); |
| 960 | if (!q_data) | 1107 | if (!q_data) |
| @@ -963,18 +1110,14 @@ static int vidioc_g_selection(struct file *file, void *priv, | |||
| 963 | * encoder supports only cropping on the OUTPUT buffer | 1110 | * encoder supports only cropping on the OUTPUT buffer |
| 964 | * decoder supports only composing on the CAPTURE buffer | 1111 | * decoder supports only composing on the CAPTURE buffer |
| 965 | */ | 1112 | */ |
| 966 | if ((ctx->is_enc && s->type == valid_out_type) || | 1113 | if (ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { |
| 967 | (!ctx->is_enc && s->type == valid_cap_type)) { | ||
| 968 | switch (s->target) { | 1114 | switch (s->target) { |
| 969 | case V4L2_SEL_TGT_COMPOSE: | ||
| 970 | case V4L2_SEL_TGT_CROP: | 1115 | case V4L2_SEL_TGT_CROP: |
| 971 | s->r.left = 0; | 1116 | s->r.left = 0; |
| 972 | s->r.top = 0; | 1117 | s->r.top = 0; |
| 973 | s->r.width = q_data->visible_width; | 1118 | s->r.width = q_data->visible_width; |
| 974 | s->r.height = q_data->visible_height; | 1119 | s->r.height = q_data->visible_height; |
| 975 | return 0; | 1120 | return 0; |
| 976 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
| 977 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
| 978 | case V4L2_SEL_TGT_CROP_DEFAULT: | 1121 | case V4L2_SEL_TGT_CROP_DEFAULT: |
| 979 | case V4L2_SEL_TGT_CROP_BOUNDS: | 1122 | case V4L2_SEL_TGT_CROP_BOUNDS: |
| 980 | s->r.left = 0; | 1123 | s->r.left = 0; |
| @@ -983,6 +1126,22 @@ static int vidioc_g_selection(struct file *file, void *priv, | |||
| 983 | s->r.height = q_data->coded_height; | 1126 | s->r.height = q_data->coded_height; |
| 984 | return 0; | 1127 | return 0; |
| 985 | } | 1128 | } |
| 1129 | } else if (!ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 1130 | switch (s->target) { | ||
| 1131 | case V4L2_SEL_TGT_COMPOSE: | ||
| 1132 | s->r.left = 0; | ||
| 1133 | s->r.top = 0; | ||
| 1134 | s->r.width = q_data->visible_width; | ||
| 1135 | s->r.height = q_data->visible_height; | ||
| 1136 | return 0; | ||
| 1137 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
| 1138 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
| 1139 | s->r.left = 0; | ||
| 1140 | s->r.top = 0; | ||
| 1141 | s->r.width = q_data->coded_width; | ||
| 1142 | s->r.height = q_data->coded_height; | ||
| 1143 | return 0; | ||
| 1144 | } | ||
| 986 | } | 1145 | } |
| 987 | return -EINVAL; | 1146 | return -EINVAL; |
| 988 | } | 1147 | } |
| @@ -992,12 +1151,8 @@ static int vidioc_s_selection(struct file *file, void *priv, | |||
| 992 | { | 1151 | { |
| 993 | struct vicodec_ctx *ctx = file2ctx(file); | 1152 | struct vicodec_ctx *ctx = file2ctx(file); |
| 994 | struct vicodec_q_data *q_data; | 1153 | struct vicodec_q_data *q_data; |
| 995 | enum v4l2_buf_type out_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 996 | |||
| 997 | if (multiplanar) | ||
| 998 | out_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; | ||
| 999 | 1154 | ||
| 1000 | if (s->type != out_type) | 1155 | if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) |
| 1001 | return -EINVAL; | 1156 | return -EINVAL; |
| 1002 | 1157 | ||
| 1003 | q_data = get_q_data(ctx, s->type); | 1158 | q_data = get_q_data(ctx, s->type); |
| @@ -1092,6 +1247,8 @@ static int vicodec_enum_framesizes(struct file *file, void *fh, | |||
| 1092 | struct v4l2_frmsizeenum *fsize) | 1247 | struct v4l2_frmsizeenum *fsize) |
| 1093 | { | 1248 | { |
| 1094 | switch (fsize->pixel_format) { | 1249 | switch (fsize->pixel_format) { |
| 1250 | case V4L2_PIX_FMT_FWHT_STATELESS: | ||
| 1251 | break; | ||
| 1095 | case V4L2_PIX_FMT_FWHT: | 1252 | case V4L2_PIX_FMT_FWHT: |
| 1096 | break; | 1253 | break; |
| 1097 | default: | 1254 | default: |
| @@ -1200,6 +1357,14 @@ static int vicodec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, | |||
| 1200 | return 0; | 1357 | return 0; |
| 1201 | } | 1358 | } |
| 1202 | 1359 | ||
| 1360 | static int vicodec_buf_out_validate(struct vb2_buffer *vb) | ||
| 1361 | { | ||
| 1362 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | ||
| 1363 | |||
| 1364 | vbuf->field = V4L2_FIELD_NONE; | ||
| 1365 | return 0; | ||
| 1366 | } | ||
| 1367 | |||
| 1203 | static int vicodec_buf_prepare(struct vb2_buffer *vb) | 1368 | static int vicodec_buf_prepare(struct vb2_buffer *vb) |
| 1204 | { | 1369 | { |
| 1205 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | 1370 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
| @@ -1263,10 +1428,11 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) | |||
| 1263 | } | 1428 | } |
| 1264 | 1429 | ||
| 1265 | /* | 1430 | /* |
| 1266 | * source change event is relevant only for the decoder | 1431 | * source change event is relevant only for the stateful decoder |
| 1267 | * in the compressed stream | 1432 | * in the compressed stream |
| 1268 | */ | 1433 | */ |
| 1269 | if (ctx->is_enc || !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { | 1434 | if (ctx->is_stateless || ctx->is_enc || |
| 1435 | !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { | ||
| 1270 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); | 1436 | v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); |
| 1271 | return; | 1437 | return; |
| 1272 | } | 1438 | } |
| @@ -1314,12 +1480,33 @@ static void vicodec_return_bufs(struct vb2_queue *q, u32 state) | |||
| 1314 | vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); | 1480 | vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); |
| 1315 | if (vbuf == NULL) | 1481 | if (vbuf == NULL) |
| 1316 | return; | 1482 | return; |
| 1483 | v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, | ||
| 1484 | &ctx->hdl); | ||
| 1317 | spin_lock(ctx->lock); | 1485 | spin_lock(ctx->lock); |
| 1318 | v4l2_m2m_buf_done(vbuf, state); | 1486 | v4l2_m2m_buf_done(vbuf, state); |
| 1319 | spin_unlock(ctx->lock); | 1487 | spin_unlock(ctx->lock); |
| 1320 | } | 1488 | } |
| 1321 | } | 1489 | } |
| 1322 | 1490 | ||
| 1491 | static unsigned int total_frame_size(struct vicodec_q_data *q_data) | ||
| 1492 | { | ||
| 1493 | unsigned int size; | ||
| 1494 | unsigned int chroma_div; | ||
| 1495 | |||
| 1496 | if (!q_data->info) { | ||
| 1497 | WARN_ON(1); | ||
| 1498 | return 0; | ||
| 1499 | } | ||
| 1500 | size = q_data->coded_width * q_data->coded_height; | ||
| 1501 | chroma_div = q_data->info->width_div * q_data->info->height_div; | ||
| 1502 | |||
| 1503 | if (q_data->info->components_num == 4) | ||
| 1504 | return 2 * size + 2 * (size / chroma_div); | ||
| 1505 | else if (q_data->info->components_num == 3) | ||
| 1506 | return size + 2 * (size / chroma_div); | ||
| 1507 | return size; | ||
| 1508 | } | ||
| 1509 | |||
| 1323 | static int vicodec_start_streaming(struct vb2_queue *q, | 1510 | static int vicodec_start_streaming(struct vb2_queue *q, |
| 1324 | unsigned int count) | 1511 | unsigned int count) |
| 1325 | { | 1512 | { |
| @@ -1330,7 +1517,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, | |||
| 1330 | unsigned int size = q_data->coded_width * q_data->coded_height; | 1517 | unsigned int size = q_data->coded_width * q_data->coded_height; |
| 1331 | unsigned int chroma_div; | 1518 | unsigned int chroma_div; |
| 1332 | unsigned int total_planes_size; | 1519 | unsigned int total_planes_size; |
| 1333 | u8 *new_comp_frame; | 1520 | u8 *new_comp_frame = NULL; |
| 1334 | 1521 | ||
| 1335 | if (!info) | 1522 | if (!info) |
| 1336 | return -EINVAL; | 1523 | return -EINVAL; |
| @@ -1338,24 +1525,24 @@ static int vicodec_start_streaming(struct vb2_queue *q, | |||
| 1338 | chroma_div = info->width_div * info->height_div; | 1525 | chroma_div = info->width_div * info->height_div; |
| 1339 | q_data->sequence = 0; | 1526 | q_data->sequence = 0; |
| 1340 | 1527 | ||
| 1341 | ctx->last_src_buf = NULL; | 1528 | if (V4L2_TYPE_IS_OUTPUT(q->type)) |
| 1342 | ctx->last_dst_buf = NULL; | 1529 | ctx->last_src_buf = NULL; |
| 1530 | else | ||
| 1531 | ctx->last_dst_buf = NULL; | ||
| 1532 | |||
| 1343 | state->gop_cnt = 0; | 1533 | state->gop_cnt = 0; |
| 1344 | 1534 | ||
| 1345 | if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) || | 1535 | if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) || |
| 1346 | (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) | 1536 | (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) |
| 1347 | return 0; | 1537 | return 0; |
| 1348 | 1538 | ||
| 1349 | if (info->id == V4L2_PIX_FMT_FWHT) { | 1539 | if (info->id == V4L2_PIX_FMT_FWHT || |
| 1540 | info->id == V4L2_PIX_FMT_FWHT_STATELESS) { | ||
| 1350 | vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED); | 1541 | vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED); |
| 1351 | return -EINVAL; | 1542 | return -EINVAL; |
| 1352 | } | 1543 | } |
| 1353 | if (info->components_num == 4) | 1544 | total_planes_size = total_frame_size(q_data); |
| 1354 | total_planes_size = 2 * size + 2 * (size / chroma_div); | 1545 | ctx->comp_max_size = total_planes_size; |
| 1355 | else if (info->components_num == 3) | ||
| 1356 | total_planes_size = size + 2 * (size / chroma_div); | ||
| 1357 | else | ||
| 1358 | total_planes_size = size; | ||
| 1359 | 1546 | ||
| 1360 | state->visible_width = q_data->visible_width; | 1547 | state->visible_width = q_data->visible_width; |
| 1361 | state->visible_height = q_data->visible_height; | 1548 | state->visible_height = q_data->visible_height; |
| @@ -1364,8 +1551,14 @@ static int vicodec_start_streaming(struct vb2_queue *q, | |||
| 1364 | state->stride = q_data->coded_width * | 1551 | state->stride = q_data->coded_width * |
| 1365 | info->bytesperline_mult; | 1552 | info->bytesperline_mult; |
| 1366 | 1553 | ||
| 1367 | state->ref_frame.luma = kvmalloc(total_planes_size, GFP_KERNEL); | 1554 | if (ctx->is_stateless) { |
| 1368 | ctx->comp_max_size = total_planes_size; | 1555 | state->ref_stride = state->stride; |
| 1556 | return 0; | ||
| 1557 | } | ||
| 1558 | state->ref_stride = q_data->coded_width * info->luma_alpha_step; | ||
| 1559 | |||
| 1560 | state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL); | ||
| 1561 | state->ref_frame.luma = state->ref_frame.buf; | ||
| 1369 | new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL); | 1562 | new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL); |
| 1370 | 1563 | ||
| 1371 | if (!state->ref_frame.luma || !new_comp_frame) { | 1564 | if (!state->ref_frame.luma || !new_comp_frame) { |
| @@ -1413,7 +1606,10 @@ static void vicodec_stop_streaming(struct vb2_queue *q) | |||
| 1413 | 1606 | ||
| 1414 | if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) || | 1607 | if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) || |
| 1415 | (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) { | 1608 | (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) { |
| 1416 | kvfree(ctx->state.ref_frame.luma); | 1609 | if (!ctx->is_stateless) |
| 1610 | kvfree(ctx->state.ref_frame.buf); | ||
| 1611 | ctx->state.ref_frame.buf = NULL; | ||
| 1612 | ctx->state.ref_frame.luma = NULL; | ||
| 1417 | ctx->comp_max_size = 0; | 1613 | ctx->comp_max_size = 0; |
| 1418 | ctx->source_changed = false; | 1614 | ctx->source_changed = false; |
| 1419 | } | 1615 | } |
| @@ -1427,14 +1623,24 @@ static void vicodec_stop_streaming(struct vb2_queue *q) | |||
| 1427 | } | 1623 | } |
| 1428 | } | 1624 | } |
| 1429 | 1625 | ||
| 1626 | static void vicodec_buf_request_complete(struct vb2_buffer *vb) | ||
| 1627 | { | ||
| 1628 | struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
| 1629 | |||
| 1630 | v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl); | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | |||
| 1430 | static const struct vb2_ops vicodec_qops = { | 1634 | static const struct vb2_ops vicodec_qops = { |
| 1431 | .queue_setup = vicodec_queue_setup, | 1635 | .queue_setup = vicodec_queue_setup, |
| 1432 | .buf_prepare = vicodec_buf_prepare, | 1636 | .buf_out_validate = vicodec_buf_out_validate, |
| 1433 | .buf_queue = vicodec_buf_queue, | 1637 | .buf_prepare = vicodec_buf_prepare, |
| 1434 | .start_streaming = vicodec_start_streaming, | 1638 | .buf_queue = vicodec_buf_queue, |
| 1435 | .stop_streaming = vicodec_stop_streaming, | 1639 | .buf_request_complete = vicodec_buf_request_complete, |
| 1436 | .wait_prepare = vb2_ops_wait_prepare, | 1640 | .start_streaming = vicodec_start_streaming, |
| 1437 | .wait_finish = vb2_ops_wait_finish, | 1641 | .stop_streaming = vicodec_stop_streaming, |
| 1642 | .wait_prepare = vb2_ops_wait_prepare, | ||
| 1643 | .wait_finish = vb2_ops_wait_finish, | ||
| 1438 | }; | 1644 | }; |
| 1439 | 1645 | ||
| 1440 | static int queue_init(void *priv, struct vb2_queue *src_vq, | 1646 | static int queue_init(void *priv, struct vb2_queue *src_vq, |
| @@ -1452,9 +1658,14 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
| 1452 | src_vq->ops = &vicodec_qops; | 1658 | src_vq->ops = &vicodec_qops; |
| 1453 | src_vq->mem_ops = &vb2_vmalloc_memops; | 1659 | src_vq->mem_ops = &vb2_vmalloc_memops; |
| 1454 | src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; | 1660 | src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; |
| 1455 | src_vq->lock = ctx->is_enc ? &ctx->dev->enc_mutex : | 1661 | if (ctx->is_enc) |
| 1456 | &ctx->dev->dec_mutex; | 1662 | src_vq->lock = &ctx->dev->stateful_enc.mutex; |
| 1457 | 1663 | else if (ctx->is_stateless) | |
| 1664 | src_vq->lock = &ctx->dev->stateless_dec.mutex; | ||
| 1665 | else | ||
| 1666 | src_vq->lock = &ctx->dev->stateful_dec.mutex; | ||
| 1667 | src_vq->supports_requests = ctx->is_stateless; | ||
| 1668 | src_vq->requires_requests = ctx->is_stateless; | ||
| 1458 | ret = vb2_queue_init(src_vq); | 1669 | ret = vb2_queue_init(src_vq); |
| 1459 | if (ret) | 1670 | if (ret) |
| 1460 | return ret; | 1671 | return ret; |
| @@ -1473,53 +1684,86 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
| 1473 | return vb2_queue_init(dst_vq); | 1684 | return vb2_queue_init(dst_vq); |
| 1474 | } | 1685 | } |
| 1475 | 1686 | ||
| 1476 | #define VICODEC_CID_CUSTOM_BASE (V4L2_CID_MPEG_BASE | 0xf000) | 1687 | static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl) |
| 1477 | #define VICODEC_CID_I_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 0) | 1688 | { |
| 1478 | #define VICODEC_CID_P_FRAME_QP (VICODEC_CID_CUSTOM_BASE + 1) | 1689 | struct vicodec_ctx *ctx = container_of(ctrl->handler, |
| 1690 | struct vicodec_ctx, hdl); | ||
| 1691 | const struct v4l2_ctrl_fwht_params *params; | ||
| 1692 | struct vicodec_q_data *q_dst = get_q_data(ctx, | ||
| 1693 | V4L2_BUF_TYPE_VIDEO_CAPTURE); | ||
| 1694 | |||
| 1695 | switch (ctrl->id) { | ||
| 1696 | case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS: | ||
| 1697 | if (!q_dst->info) | ||
| 1698 | return -EINVAL; | ||
| 1699 | params = ctrl->p_new.p_fwht_params; | ||
| 1700 | if (params->width > q_dst->coded_width || | ||
| 1701 | params->width < MIN_WIDTH || | ||
| 1702 | params->height > q_dst->coded_height || | ||
| 1703 | params->height < MIN_HEIGHT) | ||
| 1704 | return -EINVAL; | ||
| 1705 | if (!validate_by_version(params->flags, params->version)) | ||
| 1706 | return -EINVAL; | ||
| 1707 | if (!validate_stateless_params_flags(params, q_dst->info)) | ||
| 1708 | return -EINVAL; | ||
| 1709 | return 0; | ||
| 1710 | default: | ||
| 1711 | return 0; | ||
| 1712 | } | ||
| 1713 | return 0; | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | static void update_header_from_stateless_params(struct vicodec_ctx *ctx, | ||
| 1717 | const struct v4l2_ctrl_fwht_params *params) | ||
| 1718 | { | ||
| 1719 | struct fwht_cframe_hdr *p_hdr = &ctx->state.header; | ||
| 1720 | |||
| 1721 | p_hdr->magic1 = FWHT_MAGIC1; | ||
| 1722 | p_hdr->magic2 = FWHT_MAGIC2; | ||
| 1723 | p_hdr->version = htonl(params->version); | ||
| 1724 | p_hdr->width = htonl(params->width); | ||
| 1725 | p_hdr->height = htonl(params->height); | ||
| 1726 | p_hdr->flags = htonl(params->flags); | ||
| 1727 | p_hdr->colorspace = htonl(params->colorspace); | ||
| 1728 | p_hdr->xfer_func = htonl(params->xfer_func); | ||
| 1729 | p_hdr->ycbcr_enc = htonl(params->ycbcr_enc); | ||
| 1730 | p_hdr->quantization = htonl(params->quantization); | ||
| 1731 | } | ||
| 1479 | 1732 | ||
| 1480 | static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl) | 1733 | static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl) |
| 1481 | { | 1734 | { |
| 1482 | struct vicodec_ctx *ctx = container_of(ctrl->handler, | 1735 | struct vicodec_ctx *ctx = container_of(ctrl->handler, |
| 1483 | struct vicodec_ctx, hdl); | 1736 | struct vicodec_ctx, hdl); |
| 1737 | const struct v4l2_ctrl_fwht_params *params; | ||
| 1484 | 1738 | ||
| 1485 | switch (ctrl->id) { | 1739 | switch (ctrl->id) { |
| 1486 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | 1740 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: |
| 1487 | ctx->state.gop_size = ctrl->val; | 1741 | ctx->state.gop_size = ctrl->val; |
| 1488 | return 0; | 1742 | return 0; |
| 1489 | case VICODEC_CID_I_FRAME_QP: | 1743 | case V4L2_CID_FWHT_I_FRAME_QP: |
| 1490 | ctx->state.i_frame_qp = ctrl->val; | 1744 | ctx->state.i_frame_qp = ctrl->val; |
| 1491 | return 0; | 1745 | return 0; |
| 1492 | case VICODEC_CID_P_FRAME_QP: | 1746 | case V4L2_CID_FWHT_P_FRAME_QP: |
| 1493 | ctx->state.p_frame_qp = ctrl->val; | 1747 | ctx->state.p_frame_qp = ctrl->val; |
| 1494 | return 0; | 1748 | return 0; |
| 1749 | case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS: | ||
| 1750 | params = ctrl->p_new.p_fwht_params; | ||
| 1751 | update_header_from_stateless_params(ctx, params); | ||
| 1752 | ctx->state.ref_frame_ts = params->backward_ref_ts; | ||
| 1753 | return 0; | ||
| 1495 | } | 1754 | } |
| 1496 | return -EINVAL; | 1755 | return -EINVAL; |
| 1497 | } | 1756 | } |
| 1498 | 1757 | ||
| 1499 | static const struct v4l2_ctrl_ops vicodec_ctrl_ops = { | 1758 | static const struct v4l2_ctrl_ops vicodec_ctrl_ops = { |
| 1500 | .s_ctrl = vicodec_s_ctrl, | 1759 | .s_ctrl = vicodec_s_ctrl, |
| 1760 | .try_ctrl = vicodec_try_ctrl, | ||
| 1501 | }; | 1761 | }; |
| 1502 | 1762 | ||
| 1503 | static const struct v4l2_ctrl_config vicodec_ctrl_i_frame = { | 1763 | static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = { |
| 1504 | .ops = &vicodec_ctrl_ops, | 1764 | .ops = &vicodec_ctrl_ops, |
| 1505 | .id = VICODEC_CID_I_FRAME_QP, | 1765 | .id = V4L2_CID_MPEG_VIDEO_FWHT_PARAMS, |
| 1506 | .name = "FWHT I-Frame QP Value", | 1766 | .elem_size = sizeof(struct v4l2_ctrl_fwht_params), |
| 1507 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 1508 | .min = 1, | ||
| 1509 | .max = 31, | ||
| 1510 | .def = 20, | ||
| 1511 | .step = 1, | ||
| 1512 | }; | ||
| 1513 | |||
| 1514 | static const struct v4l2_ctrl_config vicodec_ctrl_p_frame = { | ||
| 1515 | .ops = &vicodec_ctrl_ops, | ||
| 1516 | .id = VICODEC_CID_P_FRAME_QP, | ||
| 1517 | .name = "FWHT P-Frame QP Value", | ||
| 1518 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
| 1519 | .min = 1, | ||
| 1520 | .max = 31, | ||
| 1521 | .def = 20, | ||
| 1522 | .step = 1, | ||
| 1523 | }; | 1767 | }; |
| 1524 | 1768 | ||
| 1525 | /* | 1769 | /* |
| @@ -1542,8 +1786,10 @@ static int vicodec_open(struct file *file) | |||
| 1542 | goto open_unlock; | 1786 | goto open_unlock; |
| 1543 | } | 1787 | } |
| 1544 | 1788 | ||
| 1545 | if (vfd == &dev->enc_vfd) | 1789 | if (vfd == &dev->stateful_enc.vfd) |
| 1546 | ctx->is_enc = true; | 1790 | ctx->is_enc = true; |
| 1791 | else if (vfd == &dev->stateless_dec.vfd) | ||
| 1792 | ctx->is_stateless = true; | ||
| 1547 | 1793 | ||
| 1548 | v4l2_fh_init(&ctx->fh, video_devdata(file)); | 1794 | v4l2_fh_init(&ctx->fh, video_devdata(file)); |
| 1549 | file->private_data = &ctx->fh; | 1795 | file->private_data = &ctx->fh; |
| @@ -1552,8 +1798,12 @@ static int vicodec_open(struct file *file) | |||
| 1552 | v4l2_ctrl_handler_init(hdl, 4); | 1798 | v4l2_ctrl_handler_init(hdl, 4); |
| 1553 | v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, | 1799 | v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, |
| 1554 | 1, 16, 1, 10); | 1800 | 1, 16, 1, 10); |
| 1555 | v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_i_frame, NULL); | 1801 | v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP, |
| 1556 | v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_p_frame, NULL); | 1802 | 1, 31, 1, 20); |
| 1803 | v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP, | ||
| 1804 | 1, 31, 1, 20); | ||
| 1805 | if (ctx->is_stateless) | ||
| 1806 | v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL); | ||
| 1557 | if (hdl->error) { | 1807 | if (hdl->error) { |
| 1558 | rc = hdl->error; | 1808 | rc = hdl->error; |
| 1559 | v4l2_ctrl_handler_free(hdl); | 1809 | v4l2_ctrl_handler_free(hdl); |
| @@ -1563,15 +1813,19 @@ static int vicodec_open(struct file *file) | |||
| 1563 | ctx->fh.ctrl_handler = hdl; | 1813 | ctx->fh.ctrl_handler = hdl; |
| 1564 | v4l2_ctrl_handler_setup(hdl); | 1814 | v4l2_ctrl_handler_setup(hdl); |
| 1565 | 1815 | ||
| 1566 | ctx->q_data[V4L2_M2M_SRC].info = | 1816 | if (ctx->is_enc) |
| 1567 | ctx->is_enc ? v4l2_fwht_get_pixfmt(0) : &pixfmt_fwht; | 1817 | ctx->q_data[V4L2_M2M_SRC].info = v4l2_fwht_get_pixfmt(0); |
| 1818 | else if (ctx->is_stateless) | ||
| 1819 | ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht; | ||
| 1820 | else | ||
| 1821 | ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_fwht; | ||
| 1568 | ctx->q_data[V4L2_M2M_SRC].coded_width = 1280; | 1822 | ctx->q_data[V4L2_M2M_SRC].coded_width = 1280; |
| 1569 | ctx->q_data[V4L2_M2M_SRC].coded_height = 720; | 1823 | ctx->q_data[V4L2_M2M_SRC].coded_height = 720; |
| 1570 | ctx->q_data[V4L2_M2M_SRC].visible_width = 1280; | 1824 | ctx->q_data[V4L2_M2M_SRC].visible_width = 1280; |
| 1571 | ctx->q_data[V4L2_M2M_SRC].visible_height = 720; | 1825 | ctx->q_data[V4L2_M2M_SRC].visible_height = 720; |
| 1572 | size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult / | 1826 | size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult / |
| 1573 | ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div; | 1827 | ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div; |
| 1574 | if (ctx->is_enc) | 1828 | if (ctx->is_enc || ctx->is_stateless) |
| 1575 | ctx->q_data[V4L2_M2M_SRC].sizeimage = size; | 1829 | ctx->q_data[V4L2_M2M_SRC].sizeimage = size; |
| 1576 | else | 1830 | else |
| 1577 | ctx->q_data[V4L2_M2M_SRC].sizeimage = | 1831 | ctx->q_data[V4L2_M2M_SRC].sizeimage = |
| @@ -1590,13 +1844,17 @@ static int vicodec_open(struct file *file) | |||
| 1590 | ctx->state.colorspace = V4L2_COLORSPACE_REC709; | 1844 | ctx->state.colorspace = V4L2_COLORSPACE_REC709; |
| 1591 | 1845 | ||
| 1592 | if (ctx->is_enc) { | 1846 | if (ctx->is_enc) { |
| 1593 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->enc_dev, ctx, | 1847 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev, |
| 1594 | &queue_init); | 1848 | ctx, &queue_init); |
| 1595 | ctx->lock = &dev->enc_lock; | 1849 | ctx->lock = &dev->stateful_enc.lock; |
| 1850 | } else if (ctx->is_stateless) { | ||
| 1851 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev, | ||
| 1852 | ctx, &queue_init); | ||
| 1853 | ctx->lock = &dev->stateless_dec.lock; | ||
| 1596 | } else { | 1854 | } else { |
| 1597 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->dec_dev, ctx, | 1855 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev, |
| 1598 | &queue_init); | 1856 | ctx, &queue_init); |
| 1599 | ctx->lock = &dev->dec_lock; | 1857 | ctx->lock = &dev->stateful_dec.lock; |
| 1600 | } | 1858 | } |
| 1601 | 1859 | ||
| 1602 | if (IS_ERR(ctx->fh.m2m_ctx)) { | 1860 | if (IS_ERR(ctx->fh.m2m_ctx)) { |
| @@ -1620,17 +1878,71 @@ static int vicodec_release(struct file *file) | |||
| 1620 | struct video_device *vfd = video_devdata(file); | 1878 | struct video_device *vfd = video_devdata(file); |
| 1621 | struct vicodec_ctx *ctx = file2ctx(file); | 1879 | struct vicodec_ctx *ctx = file2ctx(file); |
| 1622 | 1880 | ||
| 1623 | v4l2_fh_del(&ctx->fh); | ||
| 1624 | v4l2_fh_exit(&ctx->fh); | ||
| 1625 | v4l2_ctrl_handler_free(&ctx->hdl); | ||
| 1626 | mutex_lock(vfd->lock); | 1881 | mutex_lock(vfd->lock); |
| 1627 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); | 1882 | v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); |
| 1628 | mutex_unlock(vfd->lock); | 1883 | mutex_unlock(vfd->lock); |
| 1884 | v4l2_fh_del(&ctx->fh); | ||
| 1885 | v4l2_fh_exit(&ctx->fh); | ||
| 1886 | v4l2_ctrl_handler_free(&ctx->hdl); | ||
| 1887 | kvfree(ctx->state.compressed_frame); | ||
| 1629 | kfree(ctx); | 1888 | kfree(ctx); |
| 1630 | 1889 | ||
| 1631 | return 0; | 1890 | return 0; |
| 1632 | } | 1891 | } |
| 1633 | 1892 | ||
| 1893 | static int vicodec_request_validate(struct media_request *req) | ||
| 1894 | { | ||
| 1895 | struct media_request_object *obj; | ||
| 1896 | struct v4l2_ctrl_handler *parent_hdl, *hdl; | ||
| 1897 | struct vicodec_ctx *ctx = NULL; | ||
| 1898 | struct v4l2_ctrl *ctrl; | ||
| 1899 | unsigned int count; | ||
| 1900 | |||
| 1901 | list_for_each_entry(obj, &req->objects, list) { | ||
| 1902 | struct vb2_buffer *vb; | ||
| 1903 | |||
| 1904 | if (vb2_request_object_is_buffer(obj)) { | ||
| 1905 | vb = container_of(obj, struct vb2_buffer, req_obj); | ||
| 1906 | ctx = vb2_get_drv_priv(vb->vb2_queue); | ||
| 1907 | |||
| 1908 | break; | ||
| 1909 | } | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | if (!ctx) { | ||
| 1913 | pr_err("No buffer was provided with the request\n"); | ||
| 1914 | return -ENOENT; | ||
| 1915 | } | ||
| 1916 | |||
| 1917 | count = vb2_request_buffer_cnt(req); | ||
| 1918 | if (!count) { | ||
| 1919 | v4l2_info(&ctx->dev->v4l2_dev, | ||
| 1920 | "No buffer was provided with the request\n"); | ||
| 1921 | return -ENOENT; | ||
| 1922 | } else if (count > 1) { | ||
| 1923 | v4l2_info(&ctx->dev->v4l2_dev, | ||
| 1924 | "More than one buffer was provided with the request\n"); | ||
| 1925 | return -EINVAL; | ||
| 1926 | } | ||
| 1927 | |||
| 1928 | parent_hdl = &ctx->hdl; | ||
| 1929 | |||
| 1930 | hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl); | ||
| 1931 | if (!hdl) { | ||
| 1932 | v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control\n"); | ||
| 1933 | return -ENOENT; | ||
| 1934 | } | ||
| 1935 | ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl, | ||
| 1936 | vicodec_ctrl_stateless_state.id); | ||
| 1937 | if (!ctrl) { | ||
| 1938 | v4l2_info(&ctx->dev->v4l2_dev, | ||
| 1939 | "Missing required codec control\n"); | ||
| 1940 | return -ENOENT; | ||
| 1941 | } | ||
| 1942 | |||
| 1943 | return vb2_request_validate(req); | ||
| 1944 | } | ||
| 1945 | |||
| 1634 | static const struct v4l2_file_operations vicodec_fops = { | 1946 | static const struct v4l2_file_operations vicodec_fops = { |
| 1635 | .owner = THIS_MODULE, | 1947 | .owner = THIS_MODULE, |
| 1636 | .open = vicodec_open, | 1948 | .open = vicodec_open, |
| @@ -1649,24 +1961,67 @@ static const struct video_device vicodec_videodev = { | |||
| 1649 | .release = video_device_release_empty, | 1961 | .release = video_device_release_empty, |
| 1650 | }; | 1962 | }; |
| 1651 | 1963 | ||
| 1964 | static const struct media_device_ops vicodec_m2m_media_ops = { | ||
| 1965 | .req_validate = vicodec_request_validate, | ||
| 1966 | .req_queue = v4l2_m2m_request_queue, | ||
| 1967 | }; | ||
| 1968 | |||
| 1652 | static const struct v4l2_m2m_ops m2m_ops = { | 1969 | static const struct v4l2_m2m_ops m2m_ops = { |
| 1653 | .device_run = device_run, | 1970 | .device_run = device_run, |
| 1654 | .job_ready = job_ready, | 1971 | .job_ready = job_ready, |
| 1655 | }; | 1972 | }; |
| 1656 | 1973 | ||
| 1974 | static int register_instance(struct vicodec_dev *dev, | ||
| 1975 | struct vicodec_dev_instance *dev_instance, | ||
| 1976 | const char *name, bool is_enc) | ||
| 1977 | { | ||
| 1978 | struct video_device *vfd; | ||
| 1979 | int ret; | ||
| 1980 | |||
| 1981 | spin_lock_init(&dev_instance->lock); | ||
| 1982 | mutex_init(&dev_instance->mutex); | ||
| 1983 | dev_instance->m2m_dev = v4l2_m2m_init(&m2m_ops); | ||
| 1984 | if (IS_ERR(dev_instance->m2m_dev)) { | ||
| 1985 | v4l2_err(&dev->v4l2_dev, "Failed to init vicodec enc device\n"); | ||
| 1986 | return PTR_ERR(dev_instance->m2m_dev); | ||
| 1987 | } | ||
| 1988 | |||
| 1989 | dev_instance->vfd = vicodec_videodev; | ||
| 1990 | vfd = &dev_instance->vfd; | ||
| 1991 | vfd->lock = &dev_instance->mutex; | ||
| 1992 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
| 1993 | strscpy(vfd->name, name, sizeof(vfd->name)); | ||
| 1994 | vfd->device_caps = V4L2_CAP_STREAMING | | ||
| 1995 | (multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M); | ||
| 1996 | if (is_enc) { | ||
| 1997 | v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); | ||
| 1998 | v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); | ||
| 1999 | } else { | ||
| 2000 | v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); | ||
| 2001 | v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); | ||
| 2002 | } | ||
| 2003 | video_set_drvdata(vfd, dev); | ||
| 2004 | |||
| 2005 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
| 2006 | if (ret) { | ||
| 2007 | v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name); | ||
| 2008 | v4l2_m2m_release(dev_instance->m2m_dev); | ||
| 2009 | return ret; | ||
| 2010 | } | ||
| 2011 | v4l2_info(&dev->v4l2_dev, "Device '%s' registered as /dev/video%d\n", | ||
| 2012 | name, vfd->num); | ||
| 2013 | return 0; | ||
| 2014 | } | ||
| 2015 | |||
| 1657 | static int vicodec_probe(struct platform_device *pdev) | 2016 | static int vicodec_probe(struct platform_device *pdev) |
| 1658 | { | 2017 | { |
| 1659 | struct vicodec_dev *dev; | 2018 | struct vicodec_dev *dev; |
| 1660 | struct video_device *vfd; | ||
| 1661 | int ret; | 2019 | int ret; |
| 1662 | 2020 | ||
| 1663 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 2021 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); |
| 1664 | if (!dev) | 2022 | if (!dev) |
| 1665 | return -ENOMEM; | 2023 | return -ENOMEM; |
| 1666 | 2024 | ||
| 1667 | spin_lock_init(&dev->enc_lock); | ||
| 1668 | spin_lock_init(&dev->dec_lock); | ||
| 1669 | |||
| 1670 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); | 2025 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); |
| 1671 | if (ret) | 2026 | if (ret) |
| 1672 | return ret; | 2027 | return ret; |
| @@ -1677,103 +2032,74 @@ static int vicodec_probe(struct platform_device *pdev) | |||
| 1677 | strscpy(dev->mdev.bus_info, "platform:vicodec", | 2032 | strscpy(dev->mdev.bus_info, "platform:vicodec", |
| 1678 | sizeof(dev->mdev.bus_info)); | 2033 | sizeof(dev->mdev.bus_info)); |
| 1679 | media_device_init(&dev->mdev); | 2034 | media_device_init(&dev->mdev); |
| 2035 | dev->mdev.ops = &vicodec_m2m_media_ops; | ||
| 1680 | dev->v4l2_dev.mdev = &dev->mdev; | 2036 | dev->v4l2_dev.mdev = &dev->mdev; |
| 1681 | #endif | 2037 | #endif |
| 1682 | 2038 | ||
| 1683 | mutex_init(&dev->enc_mutex); | ||
| 1684 | mutex_init(&dev->dec_mutex); | ||
| 1685 | |||
| 1686 | platform_set_drvdata(pdev, dev); | 2039 | platform_set_drvdata(pdev, dev); |
| 1687 | 2040 | ||
| 1688 | dev->enc_dev = v4l2_m2m_init(&m2m_ops); | 2041 | if (register_instance(dev, &dev->stateful_enc, |
| 1689 | if (IS_ERR(dev->enc_dev)) { | 2042 | "stateful-encoder", true)) |
| 1690 | v4l2_err(&dev->v4l2_dev, "Failed to init vicodec device\n"); | ||
| 1691 | ret = PTR_ERR(dev->enc_dev); | ||
| 1692 | goto unreg_dev; | 2043 | goto unreg_dev; |
| 1693 | } | ||
| 1694 | 2044 | ||
| 1695 | dev->dec_dev = v4l2_m2m_init(&m2m_ops); | 2045 | if (register_instance(dev, &dev->stateful_dec, |
| 1696 | if (IS_ERR(dev->dec_dev)) { | 2046 | "stateful-decoder", false)) |
| 1697 | v4l2_err(&dev->v4l2_dev, "Failed to init vicodec device\n"); | 2047 | goto unreg_sf_enc; |
| 1698 | ret = PTR_ERR(dev->dec_dev); | ||
| 1699 | goto err_enc_m2m; | ||
| 1700 | } | ||
| 1701 | 2048 | ||
| 1702 | dev->enc_vfd = vicodec_videodev; | 2049 | if (register_instance(dev, &dev->stateless_dec, |
| 1703 | vfd = &dev->enc_vfd; | 2050 | "stateless-decoder", false)) |
| 1704 | vfd->lock = &dev->enc_mutex; | 2051 | goto unreg_sf_dec; |
| 1705 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
| 1706 | strscpy(vfd->name, "vicodec-enc", sizeof(vfd->name)); | ||
| 1707 | vfd->device_caps = V4L2_CAP_STREAMING | | ||
| 1708 | (multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M); | ||
| 1709 | v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); | ||
| 1710 | v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); | ||
| 1711 | video_set_drvdata(vfd, dev); | ||
| 1712 | |||
| 1713 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
| 1714 | if (ret) { | ||
| 1715 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | ||
| 1716 | goto err_dec_m2m; | ||
| 1717 | } | ||
| 1718 | v4l2_info(&dev->v4l2_dev, | ||
| 1719 | "Device registered as /dev/video%d\n", vfd->num); | ||
| 1720 | 2052 | ||
| 1721 | dev->dec_vfd = vicodec_videodev; | 2053 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 1722 | vfd = &dev->dec_vfd; | 2054 | ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev, |
| 1723 | vfd->lock = &dev->dec_mutex; | 2055 | &dev->stateful_enc.vfd, |
| 1724 | vfd->v4l2_dev = &dev->v4l2_dev; | 2056 | MEDIA_ENT_F_PROC_VIDEO_ENCODER); |
| 1725 | vfd->device_caps = V4L2_CAP_STREAMING | | ||
| 1726 | (multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M); | ||
| 1727 | strscpy(vfd->name, "vicodec-dec", sizeof(vfd->name)); | ||
| 1728 | v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); | ||
| 1729 | v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); | ||
| 1730 | video_set_drvdata(vfd, dev); | ||
| 1731 | |||
| 1732 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | ||
| 1733 | if (ret) { | 2057 | if (ret) { |
| 1734 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | 2058 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for enc\n"); |
| 1735 | goto unreg_enc; | 2059 | goto unreg_m2m; |
| 1736 | } | 2060 | } |
| 1737 | v4l2_info(&dev->v4l2_dev, | ||
| 1738 | "Device registered as /dev/video%d\n", vfd->num); | ||
| 1739 | 2061 | ||
| 1740 | #ifdef CONFIG_MEDIA_CONTROLLER | 2062 | ret = v4l2_m2m_register_media_controller(dev->stateful_dec.m2m_dev, |
| 1741 | ret = v4l2_m2m_register_media_controller(dev->enc_dev, | 2063 | &dev->stateful_dec.vfd, |
| 1742 | &dev->enc_vfd, MEDIA_ENT_F_PROC_VIDEO_ENCODER); | 2064 | MEDIA_ENT_F_PROC_VIDEO_DECODER); |
| 1743 | if (ret) { | 2065 | if (ret) { |
| 1744 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); | 2066 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for dec\n"); |
| 1745 | goto unreg_m2m; | 2067 | goto unreg_m2m_sf_enc_mc; |
| 1746 | } | 2068 | } |
| 1747 | 2069 | ||
| 1748 | ret = v4l2_m2m_register_media_controller(dev->dec_dev, | 2070 | ret = v4l2_m2m_register_media_controller(dev->stateless_dec.m2m_dev, |
| 1749 | &dev->dec_vfd, MEDIA_ENT_F_PROC_VIDEO_DECODER); | 2071 | &dev->stateless_dec.vfd, |
| 2072 | MEDIA_ENT_F_PROC_VIDEO_DECODER); | ||
| 1750 | if (ret) { | 2073 | if (ret) { |
| 1751 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); | 2074 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless dec\n"); |
| 1752 | goto unreg_m2m_enc_mc; | 2075 | goto unreg_m2m_sf_dec_mc; |
| 1753 | } | 2076 | } |
| 1754 | 2077 | ||
| 1755 | ret = media_device_register(&dev->mdev); | 2078 | ret = media_device_register(&dev->mdev); |
| 1756 | if (ret) { | 2079 | if (ret) { |
| 1757 | v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); | 2080 | v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); |
| 1758 | goto unreg_m2m_dec_mc; | 2081 | goto unreg_m2m_sl_dec_mc; |
| 1759 | } | 2082 | } |
| 1760 | #endif | 2083 | #endif |
| 1761 | return 0; | 2084 | return 0; |
| 1762 | 2085 | ||
| 1763 | #ifdef CONFIG_MEDIA_CONTROLLER | 2086 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 1764 | unreg_m2m_dec_mc: | 2087 | unreg_m2m_sl_dec_mc: |
| 1765 | v4l2_m2m_unregister_media_controller(dev->dec_dev); | 2088 | v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev); |
| 1766 | unreg_m2m_enc_mc: | 2089 | unreg_m2m_sf_dec_mc: |
| 1767 | v4l2_m2m_unregister_media_controller(dev->enc_dev); | 2090 | v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev); |
| 2091 | unreg_m2m_sf_enc_mc: | ||
| 2092 | v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev); | ||
| 1768 | unreg_m2m: | 2093 | unreg_m2m: |
| 1769 | video_unregister_device(&dev->dec_vfd); | 2094 | video_unregister_device(&dev->stateless_dec.vfd); |
| 2095 | v4l2_m2m_release(dev->stateless_dec.m2m_dev); | ||
| 1770 | #endif | 2096 | #endif |
| 1771 | unreg_enc: | 2097 | unreg_sf_dec: |
| 1772 | video_unregister_device(&dev->enc_vfd); | 2098 | video_unregister_device(&dev->stateful_dec.vfd); |
| 1773 | err_dec_m2m: | 2099 | v4l2_m2m_release(dev->stateful_dec.m2m_dev); |
| 1774 | v4l2_m2m_release(dev->dec_dev); | 2100 | unreg_sf_enc: |
| 1775 | err_enc_m2m: | 2101 | video_unregister_device(&dev->stateful_enc.vfd); |
| 1776 | v4l2_m2m_release(dev->enc_dev); | 2102 | v4l2_m2m_release(dev->stateful_enc.m2m_dev); |
| 1777 | unreg_dev: | 2103 | unreg_dev: |
| 1778 | v4l2_device_unregister(&dev->v4l2_dev); | 2104 | v4l2_device_unregister(&dev->v4l2_dev); |
| 1779 | 2105 | ||
| @@ -1788,15 +2114,17 @@ static int vicodec_remove(struct platform_device *pdev) | |||
| 1788 | 2114 | ||
| 1789 | #ifdef CONFIG_MEDIA_CONTROLLER | 2115 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 1790 | media_device_unregister(&dev->mdev); | 2116 | media_device_unregister(&dev->mdev); |
| 1791 | v4l2_m2m_unregister_media_controller(dev->enc_dev); | 2117 | v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev); |
| 1792 | v4l2_m2m_unregister_media_controller(dev->dec_dev); | 2118 | v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev); |
| 2119 | v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev); | ||
| 1793 | media_device_cleanup(&dev->mdev); | 2120 | media_device_cleanup(&dev->mdev); |
| 1794 | #endif | 2121 | #endif |
| 1795 | 2122 | ||
| 1796 | v4l2_m2m_release(dev->enc_dev); | 2123 | v4l2_m2m_release(dev->stateful_enc.m2m_dev); |
| 1797 | v4l2_m2m_release(dev->dec_dev); | 2124 | v4l2_m2m_release(dev->stateful_dec.m2m_dev); |
| 1798 | video_unregister_device(&dev->enc_vfd); | 2125 | video_unregister_device(&dev->stateful_enc.vfd); |
| 1799 | video_unregister_device(&dev->dec_vfd); | 2126 | video_unregister_device(&dev->stateful_dec.vfd); |
| 2127 | video_unregister_device(&dev->stateless_dec.vfd); | ||
| 1800 | v4l2_device_unregister(&dev->v4l2_dev); | 2128 | v4l2_device_unregister(&dev->v4l2_dev); |
| 1801 | 2129 | ||
| 1802 | return 0; | 2130 | return 0; |
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 0ba30756e1e4..d8cd5f5cb10d 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c | |||
| @@ -419,9 +419,14 @@ static int video_mux_probe(struct platform_device *pdev) | |||
| 419 | vmux->active = -1; | 419 | vmux->active = -1; |
| 420 | vmux->pads = devm_kcalloc(dev, num_pads, sizeof(*vmux->pads), | 420 | vmux->pads = devm_kcalloc(dev, num_pads, sizeof(*vmux->pads), |
| 421 | GFP_KERNEL); | 421 | GFP_KERNEL); |
| 422 | if (!vmux->pads) | ||
| 423 | return -ENOMEM; | ||
| 424 | |||
| 422 | vmux->format_mbus = devm_kcalloc(dev, num_pads, | 425 | vmux->format_mbus = devm_kcalloc(dev, num_pads, |
| 423 | sizeof(*vmux->format_mbus), | 426 | sizeof(*vmux->format_mbus), |
| 424 | GFP_KERNEL); | 427 | GFP_KERNEL); |
| 428 | if (!vmux->format_mbus) | ||
| 429 | return -ENOMEM; | ||
| 425 | 430 | ||
| 426 | for (i = 0; i < num_pads; i++) { | 431 | for (i = 0; i < num_pads; i++) { |
| 427 | vmux->pads[i].flags = (i < num_pads - 1) ? MEDIA_PAD_FL_SINK | 432 | vmux->pads[i].flags = (i < num_pads - 1) ? MEDIA_PAD_FL_SINK |
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c index 34dcaca45d8b..243c82b5d537 100644 --- a/drivers/media/platform/vim2m.c +++ b/drivers/media/platform/vim2m.c | |||
| @@ -302,7 +302,7 @@ static void copy_two_pixels(struct vim2m_q_data *q_data_in, | |||
| 302 | switch (in->fourcc) { | 302 | switch (in->fourcc) { |
| 303 | case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */ | 303 | case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */ |
| 304 | for (i = 0; i < 2; i++) { | 304 | for (i = 0; i < 2; i++) { |
| 305 | u16 pix = *(u16 *)(src[i]); | 305 | u16 pix = le16_to_cpu(*(__le16 *)(src[i])); |
| 306 | 306 | ||
| 307 | *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07; | 307 | *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07; |
| 308 | *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03; | 308 | *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03; |
| @@ -311,12 +311,11 @@ static void copy_two_pixels(struct vim2m_q_data *q_data_in, | |||
| 311 | break; | 311 | break; |
| 312 | case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */ | 312 | case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */ |
| 313 | for (i = 0; i < 2; i++) { | 313 | for (i = 0; i < 2; i++) { |
| 314 | u16 pix = *(u16 *)(src[i]); | 314 | u16 pix = be16_to_cpu(*(__be16 *)(src[i])); |
| 315 | 315 | ||
| 316 | *r++ = (u8)(((0x00f8 & pix) >> 3) << 3) | 0x07; | 316 | *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07; |
| 317 | *g++ = (u8)(((pix & 0x7) << 2) | | 317 | *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03; |
| 318 | ((pix & 0xe000) >> 5)) | 0x03; | 318 | *b++ = (u8)((pix & 0x1f) << 3) | 0x07; |
| 319 | *b++ = (u8)(((pix & 0x1f00) >> 8) << 3) | 0x07; | ||
| 320 | } | 319 | } |
| 321 | break; | 320 | break; |
| 322 | default: | 321 | default: |
| @@ -345,21 +344,26 @@ static void copy_two_pixels(struct vim2m_q_data *q_data_in, | |||
| 345 | switch (out->fourcc) { | 344 | switch (out->fourcc) { |
| 346 | case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */ | 345 | case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */ |
| 347 | for (i = 0; i < 2; i++) { | 346 | for (i = 0; i < 2; i++) { |
| 348 | u16 *pix = (u16 *)*dst; | 347 | u16 pix; |
| 348 | __le16 *dst_pix = (__le16 *)*dst; | ||
| 349 | |||
| 350 | pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) | | ||
| 351 | (*b >> 3); | ||
| 349 | 352 | ||
| 350 | *pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) | | 353 | *dst_pix = cpu_to_le16(pix); |
| 351 | (*b >> 3); | ||
| 352 | 354 | ||
| 353 | *dst += 2; | 355 | *dst += 2; |
| 354 | } | 356 | } |
| 355 | return; | 357 | return; |
| 356 | case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */ | 358 | case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */ |
| 357 | for (i = 0; i < 2; i++) { | 359 | for (i = 0; i < 2; i++) { |
| 358 | u16 *pix = (u16 *)*dst; | 360 | u16 pix; |
| 359 | u8 green = *g++ >> 2; | 361 | __be16 *dst_pix = (__be16 *)*dst; |
| 360 | 362 | ||
| 361 | *pix = ((green << 8) & 0xe000) | (green & 0x07) | | 363 | pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) | |
| 362 | ((*b++ << 5) & 0x1f00) | ((*r++ & 0xf8)); | 364 | (*b >> 3); |
| 365 | |||
| 366 | *dst_pix = cpu_to_be16(pix); | ||
| 363 | 367 | ||
| 364 | *dst += 2; | 368 | *dst += 2; |
| 365 | } | 369 | } |
| @@ -655,8 +659,8 @@ static void device_work(struct work_struct *w) | |||
| 655 | static int vidioc_querycap(struct file *file, void *priv, | 659 | static int vidioc_querycap(struct file *file, void *priv, |
| 656 | struct v4l2_capability *cap) | 660 | struct v4l2_capability *cap) |
| 657 | { | 661 | { |
| 658 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); | 662 | strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); |
| 659 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); | 663 | strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); |
| 660 | snprintf(cap->bus_info, sizeof(cap->bus_info), | 664 | snprintf(cap->bus_info, sizeof(cap->bus_info), |
| 661 | "platform:%s", MEM2MEM_NAME); | 665 | "platform:%s", MEM2MEM_NAME); |
| 662 | return 0; | 666 | return 0; |
| @@ -1262,6 +1266,15 @@ static int vim2m_release(struct file *file) | |||
| 1262 | return 0; | 1266 | return 0; |
| 1263 | } | 1267 | } |
| 1264 | 1268 | ||
| 1269 | static void vim2m_device_release(struct video_device *vdev) | ||
| 1270 | { | ||
| 1271 | struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd); | ||
| 1272 | |||
| 1273 | v4l2_device_unregister(&dev->v4l2_dev); | ||
| 1274 | v4l2_m2m_release(dev->m2m_dev); | ||
| 1275 | kfree(dev); | ||
| 1276 | } | ||
| 1277 | |||
| 1265 | static const struct v4l2_file_operations vim2m_fops = { | 1278 | static const struct v4l2_file_operations vim2m_fops = { |
| 1266 | .owner = THIS_MODULE, | 1279 | .owner = THIS_MODULE, |
| 1267 | .open = vim2m_open, | 1280 | .open = vim2m_open, |
| @@ -1277,7 +1290,7 @@ static const struct video_device vim2m_videodev = { | |||
| 1277 | .fops = &vim2m_fops, | 1290 | .fops = &vim2m_fops, |
| 1278 | .ioctl_ops = &vim2m_ioctl_ops, | 1291 | .ioctl_ops = &vim2m_ioctl_ops, |
| 1279 | .minor = -1, | 1292 | .minor = -1, |
| 1280 | .release = video_device_release_empty, | 1293 | .release = vim2m_device_release, |
| 1281 | .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, | 1294 | .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, |
| 1282 | }; | 1295 | }; |
| 1283 | 1296 | ||
| @@ -1298,13 +1311,13 @@ static int vim2m_probe(struct platform_device *pdev) | |||
| 1298 | struct video_device *vfd; | 1311 | struct video_device *vfd; |
| 1299 | int ret; | 1312 | int ret; |
| 1300 | 1313 | ||
| 1301 | dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); | 1314 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 1302 | if (!dev) | 1315 | if (!dev) |
| 1303 | return -ENOMEM; | 1316 | return -ENOMEM; |
| 1304 | 1317 | ||
| 1305 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); | 1318 | ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); |
| 1306 | if (ret) | 1319 | if (ret) |
| 1307 | return ret; | 1320 | goto error_free; |
| 1308 | 1321 | ||
| 1309 | atomic_set(&dev->num_inst, 0); | 1322 | atomic_set(&dev->num_inst, 0); |
| 1310 | mutex_init(&dev->dev_mutex); | 1323 | mutex_init(&dev->dev_mutex); |
| @@ -1317,7 +1330,7 @@ static int vim2m_probe(struct platform_device *pdev) | |||
| 1317 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 1330 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
| 1318 | if (ret) { | 1331 | if (ret) { |
| 1319 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | 1332 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); |
| 1320 | goto unreg_v4l2; | 1333 | goto error_v4l2; |
| 1321 | } | 1334 | } |
| 1322 | 1335 | ||
| 1323 | video_set_drvdata(vfd, dev); | 1336 | video_set_drvdata(vfd, dev); |
| @@ -1330,7 +1343,7 @@ static int vim2m_probe(struct platform_device *pdev) | |||
| 1330 | if (IS_ERR(dev->m2m_dev)) { | 1343 | if (IS_ERR(dev->m2m_dev)) { |
| 1331 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); | 1344 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); |
| 1332 | ret = PTR_ERR(dev->m2m_dev); | 1345 | ret = PTR_ERR(dev->m2m_dev); |
| 1333 | goto unreg_dev; | 1346 | goto error_dev; |
| 1334 | } | 1347 | } |
| 1335 | 1348 | ||
| 1336 | #ifdef CONFIG_MEDIA_CONTROLLER | 1349 | #ifdef CONFIG_MEDIA_CONTROLLER |
| @@ -1346,27 +1359,29 @@ static int vim2m_probe(struct platform_device *pdev) | |||
| 1346 | MEDIA_ENT_F_PROC_VIDEO_SCALER); | 1359 | MEDIA_ENT_F_PROC_VIDEO_SCALER); |
| 1347 | if (ret) { | 1360 | if (ret) { |
| 1348 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); | 1361 | v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); |
| 1349 | goto unreg_m2m; | 1362 | goto error_m2m; |
| 1350 | } | 1363 | } |
| 1351 | 1364 | ||
| 1352 | ret = media_device_register(&dev->mdev); | 1365 | ret = media_device_register(&dev->mdev); |
| 1353 | if (ret) { | 1366 | if (ret) { |
| 1354 | v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); | 1367 | v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n"); |
| 1355 | goto unreg_m2m_mc; | 1368 | goto error_m2m_mc; |
| 1356 | } | 1369 | } |
| 1357 | #endif | 1370 | #endif |
| 1358 | return 0; | 1371 | return 0; |
| 1359 | 1372 | ||
| 1360 | #ifdef CONFIG_MEDIA_CONTROLLER | 1373 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 1361 | unreg_m2m_mc: | 1374 | error_m2m_mc: |
| 1362 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); | 1375 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); |
| 1363 | unreg_m2m: | 1376 | error_m2m: |
| 1364 | v4l2_m2m_release(dev->m2m_dev); | 1377 | v4l2_m2m_release(dev->m2m_dev); |
| 1365 | #endif | 1378 | #endif |
| 1366 | unreg_dev: | 1379 | error_dev: |
| 1367 | video_unregister_device(&dev->vfd); | 1380 | video_unregister_device(&dev->vfd); |
| 1368 | unreg_v4l2: | 1381 | error_v4l2: |
| 1369 | v4l2_device_unregister(&dev->v4l2_dev); | 1382 | v4l2_device_unregister(&dev->v4l2_dev); |
| 1383 | error_free: | ||
| 1384 | kfree(dev); | ||
| 1370 | 1385 | ||
| 1371 | return ret; | 1386 | return ret; |
| 1372 | } | 1387 | } |
| @@ -1382,9 +1397,7 @@ static int vim2m_remove(struct platform_device *pdev) | |||
| 1382 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); | 1397 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); |
| 1383 | media_device_cleanup(&dev->mdev); | 1398 | media_device_cleanup(&dev->mdev); |
| 1384 | #endif | 1399 | #endif |
| 1385 | v4l2_m2m_release(dev->m2m_dev); | ||
| 1386 | video_unregister_device(&dev->vfd); | 1400 | video_unregister_device(&dev->vfd); |
| 1387 | v4l2_device_unregister(&dev->v4l2_dev); | ||
| 1388 | 1401 | ||
| 1389 | return 0; | 1402 | return 0; |
| 1390 | } | 1403 | } |
diff --git a/drivers/media/platform/vimc/Kconfig b/drivers/media/platform/vimc/Kconfig index 71c9fe7d3370..1de9bc9aa49b 100644 --- a/drivers/media/platform/vimc/Kconfig +++ b/drivers/media/platform/vimc/Kconfig | |||
| @@ -4,7 +4,7 @@ config VIDEO_VIMC | |||
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | select VIDEO_V4L2_TPG | 5 | select VIDEO_V4L2_TPG |
| 6 | default n | 6 | default n |
| 7 | ---help--- | 7 | help |
| 8 | Skeleton driver for Virtual Media Controller | 8 | Skeleton driver for Virtual Media Controller |
| 9 | 9 | ||
| 10 | This driver can be compared to the vivid driver for emulating | 10 | This driver can be compared to the vivid driver for emulating |
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index ea869631a3f6..e7d0fc2228a6 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c | |||
| @@ -28,6 +28,32 @@ | |||
| 28 | 28 | ||
| 29 | #define VIMC_CAP_DRV_NAME "vimc-capture" | 29 | #define VIMC_CAP_DRV_NAME "vimc-capture" |
| 30 | 30 | ||
| 31 | static const u32 vimc_cap_supported_pixfmt[] = { | ||
| 32 | V4L2_PIX_FMT_BGR24, | ||
| 33 | V4L2_PIX_FMT_RGB24, | ||
| 34 | V4L2_PIX_FMT_ARGB32, | ||
| 35 | V4L2_PIX_FMT_SBGGR8, | ||
| 36 | V4L2_PIX_FMT_SGBRG8, | ||
| 37 | V4L2_PIX_FMT_SGRBG8, | ||
| 38 | V4L2_PIX_FMT_SRGGB8, | ||
| 39 | V4L2_PIX_FMT_SBGGR10, | ||
| 40 | V4L2_PIX_FMT_SGBRG10, | ||
| 41 | V4L2_PIX_FMT_SGRBG10, | ||
| 42 | V4L2_PIX_FMT_SRGGB10, | ||
| 43 | V4L2_PIX_FMT_SBGGR10ALAW8, | ||
| 44 | V4L2_PIX_FMT_SGBRG10ALAW8, | ||
| 45 | V4L2_PIX_FMT_SGRBG10ALAW8, | ||
| 46 | V4L2_PIX_FMT_SRGGB10ALAW8, | ||
| 47 | V4L2_PIX_FMT_SBGGR10DPCM8, | ||
| 48 | V4L2_PIX_FMT_SGBRG10DPCM8, | ||
| 49 | V4L2_PIX_FMT_SGRBG10DPCM8, | ||
| 50 | V4L2_PIX_FMT_SRGGB10DPCM8, | ||
| 51 | V4L2_PIX_FMT_SBGGR12, | ||
| 52 | V4L2_PIX_FMT_SGBRG12, | ||
| 53 | V4L2_PIX_FMT_SGRBG12, | ||
| 54 | V4L2_PIX_FMT_SRGGB12, | ||
| 55 | }; | ||
| 56 | |||
| 31 | struct vimc_cap_device { | 57 | struct vimc_cap_device { |
| 32 | struct vimc_ent_device ved; | 58 | struct vimc_ent_device ved; |
| 33 | struct video_device vdev; | 59 | struct video_device vdev; |
| @@ -101,29 +127,25 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv, | |||
| 101 | struct v4l2_format *f) | 127 | struct v4l2_format *f) |
| 102 | { | 128 | { |
| 103 | struct v4l2_pix_format *format = &f->fmt.pix; | 129 | struct v4l2_pix_format *format = &f->fmt.pix; |
| 104 | const struct vimc_pix_map *vpix; | ||
| 105 | 130 | ||
| 106 | format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH, | 131 | format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH, |
| 107 | VIMC_FRAME_MAX_WIDTH) & ~1; | 132 | VIMC_FRAME_MAX_WIDTH) & ~1; |
| 108 | format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT, | 133 | format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT, |
| 109 | VIMC_FRAME_MAX_HEIGHT) & ~1; | 134 | VIMC_FRAME_MAX_HEIGHT) & ~1; |
| 110 | 135 | ||
| 111 | /* Don't accept a pixelformat that is not on the table */ | 136 | vimc_colorimetry_clamp(format); |
| 112 | vpix = vimc_pix_map_by_pixelformat(format->pixelformat); | ||
| 113 | if (!vpix) { | ||
| 114 | format->pixelformat = fmt_default.pixelformat; | ||
| 115 | vpix = vimc_pix_map_by_pixelformat(format->pixelformat); | ||
| 116 | } | ||
| 117 | /* TODO: Add support for custom bytesperline values */ | ||
| 118 | format->bytesperline = format->width * vpix->bpp; | ||
| 119 | format->sizeimage = format->bytesperline * format->height; | ||
| 120 | 137 | ||
| 121 | if (format->field == V4L2_FIELD_ANY) | 138 | if (format->field == V4L2_FIELD_ANY) |
| 122 | format->field = fmt_default.field; | 139 | format->field = fmt_default.field; |
| 123 | 140 | ||
| 124 | vimc_colorimetry_clamp(format); | 141 | /* TODO: Add support for custom bytesperline values */ |
| 125 | 142 | ||
| 126 | return 0; | 143 | /* Don't accept a pixelformat that is not on the table */ |
| 144 | if (!v4l2_format_info(format->pixelformat)) | ||
| 145 | format->pixelformat = fmt_default.pixelformat; | ||
| 146 | |||
| 147 | return v4l2_fill_pixfmt(format, format->pixelformat, | ||
| 148 | format->width, format->height); | ||
| 127 | } | 149 | } |
| 128 | 150 | ||
| 129 | static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, | 151 | static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, |
| @@ -159,27 +181,31 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, | |||
| 159 | static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv, | 181 | static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv, |
| 160 | struct v4l2_fmtdesc *f) | 182 | struct v4l2_fmtdesc *f) |
| 161 | { | 183 | { |
| 162 | const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index); | 184 | if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt)) |
| 163 | |||
| 164 | if (!vpix) | ||
| 165 | return -EINVAL; | 185 | return -EINVAL; |
| 166 | 186 | ||
| 167 | f->pixelformat = vpix->pixelformat; | 187 | f->pixelformat = vimc_cap_supported_pixfmt[f->index]; |
| 168 | 188 | ||
| 169 | return 0; | 189 | return 0; |
| 170 | } | 190 | } |
| 171 | 191 | ||
| 192 | static bool vimc_cap_is_pixfmt_supported(u32 pixelformat) | ||
| 193 | { | ||
| 194 | unsigned int i; | ||
| 195 | |||
| 196 | for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixfmt); i++) | ||
| 197 | if (vimc_cap_supported_pixfmt[i] == pixelformat) | ||
| 198 | return true; | ||
| 199 | return false; | ||
| 200 | } | ||
| 201 | |||
| 172 | static int vimc_cap_enum_framesizes(struct file *file, void *fh, | 202 | static int vimc_cap_enum_framesizes(struct file *file, void *fh, |
| 173 | struct v4l2_frmsizeenum *fsize) | 203 | struct v4l2_frmsizeenum *fsize) |
| 174 | { | 204 | { |
| 175 | const struct vimc_pix_map *vpix; | ||
| 176 | |||
| 177 | if (fsize->index) | 205 | if (fsize->index) |
| 178 | return -EINVAL; | 206 | return -EINVAL; |
| 179 | 207 | ||
| 180 | /* Only accept code in the pix map table */ | 208 | if (!vimc_cap_is_pixfmt_supported(fsize->pixel_format)) |
| 181 | vpix = vimc_pix_map_by_code(fsize->pixel_format); | ||
| 182 | if (!vpix) | ||
| 183 | return -EINVAL; | 209 | return -EINVAL; |
| 184 | 210 | ||
| 185 | fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; | 211 | fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; |
| @@ -187,8 +213,8 @@ static int vimc_cap_enum_framesizes(struct file *file, void *fh, | |||
| 187 | fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH; | 213 | fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH; |
| 188 | fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT; | 214 | fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT; |
| 189 | fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT; | 215 | fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT; |
| 190 | fsize->stepwise.step_width = 2; | 216 | fsize->stepwise.step_width = 1; |
| 191 | fsize->stepwise.step_height = 2; | 217 | fsize->stepwise.step_height = 1; |
| 192 | 218 | ||
| 193 | return 0; | 219 | return 0; |
| 194 | } | 220 | } |
| @@ -253,6 +279,7 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 253 | return ret; | 279 | return ret; |
| 254 | } | 280 | } |
| 255 | 281 | ||
| 282 | vcap->stream.producer_pixfmt = vcap->format.pixelformat; | ||
| 256 | ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); | 283 | ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); |
| 257 | if (ret) { | 284 | if (ret) { |
| 258 | media_pipeline_stop(entity); | 285 | media_pipeline_stop(entity); |
| @@ -338,6 +365,15 @@ static const struct media_entity_operations vimc_cap_mops = { | |||
| 338 | .link_validate = vimc_link_validate, | 365 | .link_validate = vimc_link_validate, |
| 339 | }; | 366 | }; |
| 340 | 367 | ||
| 368 | static void vimc_cap_release(struct video_device *vdev) | ||
| 369 | { | ||
| 370 | struct vimc_cap_device *vcap = | ||
| 371 | container_of(vdev, struct vimc_cap_device, vdev); | ||
| 372 | |||
| 373 | vimc_pads_cleanup(vcap->ved.pads); | ||
| 374 | kfree(vcap); | ||
| 375 | } | ||
| 376 | |||
| 341 | static void vimc_cap_comp_unbind(struct device *comp, struct device *master, | 377 | static void vimc_cap_comp_unbind(struct device *comp, struct device *master, |
| 342 | void *master_data) | 378 | void *master_data) |
| 343 | { | 379 | { |
| @@ -348,8 +384,6 @@ static void vimc_cap_comp_unbind(struct device *comp, struct device *master, | |||
| 348 | vb2_queue_release(&vcap->queue); | 384 | vb2_queue_release(&vcap->queue); |
| 349 | media_entity_cleanup(ved->ent); | 385 | media_entity_cleanup(ved->ent); |
| 350 | video_unregister_device(&vcap->vdev); | 386 | video_unregister_device(&vcap->vdev); |
| 351 | vimc_pads_cleanup(vcap->ved.pads); | ||
| 352 | kfree(vcap); | ||
| 353 | } | 387 | } |
| 354 | 388 | ||
| 355 | static void *vimc_cap_process_frame(struct vimc_ent_device *ved, | 389 | static void *vimc_cap_process_frame(struct vimc_ent_device *ved, |
| @@ -396,7 +430,6 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, | |||
| 396 | { | 430 | { |
| 397 | struct v4l2_device *v4l2_dev = master_data; | 431 | struct v4l2_device *v4l2_dev = master_data; |
| 398 | struct vimc_platform_data *pdata = comp->platform_data; | 432 | struct vimc_platform_data *pdata = comp->platform_data; |
| 399 | const struct vimc_pix_map *vpix; | ||
| 400 | struct vimc_cap_device *vcap; | 433 | struct vimc_cap_device *vcap; |
| 401 | struct video_device *vdev; | 434 | struct video_device *vdev; |
| 402 | struct vb2_queue *q; | 435 | struct vb2_queue *q; |
| @@ -451,10 +484,8 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, | |||
| 451 | 484 | ||
| 452 | /* Set default frame format */ | 485 | /* Set default frame format */ |
| 453 | vcap->format = fmt_default; | 486 | vcap->format = fmt_default; |
| 454 | vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat); | 487 | v4l2_fill_pixfmt(&vcap->format, vcap->format.pixelformat, |
| 455 | vcap->format.bytesperline = vcap->format.width * vpix->bpp; | 488 | vcap->format.width, vcap->format.height); |
| 456 | vcap->format.sizeimage = vcap->format.bytesperline * | ||
| 457 | vcap->format.height; | ||
| 458 | 489 | ||
| 459 | /* Fill the vimc_ent_device struct */ | 490 | /* Fill the vimc_ent_device struct */ |
| 460 | vcap->ved.ent = &vcap->vdev.entity; | 491 | vcap->ved.ent = &vcap->vdev.entity; |
| @@ -467,7 +498,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, | |||
| 467 | vdev = &vcap->vdev; | 498 | vdev = &vcap->vdev; |
| 468 | vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 499 | vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
| 469 | vdev->entity.ops = &vimc_cap_mops; | 500 | vdev->entity.ops = &vimc_cap_mops; |
| 470 | vdev->release = video_device_release_empty; | 501 | vdev->release = vimc_cap_release; |
| 471 | vdev->fops = &vimc_cap_fops; | 502 | vdev->fops = &vimc_cap_fops; |
| 472 | vdev->ioctl_ops = &vimc_cap_ioctl_ops; | 503 | vdev->ioctl_ops = &vimc_cap_ioctl_ops; |
| 473 | vdev->lock = &vcap->lock; | 504 | vdev->lock = &vcap->lock; |
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index c1a74bb2df58..fad7c7c6de93 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c | |||
| @@ -20,192 +20,139 @@ | |||
| 20 | 20 | ||
| 21 | #include "vimc-common.h" | 21 | #include "vimc-common.h" |
| 22 | 22 | ||
| 23 | /* | 23 | static const __u32 vimc_mbus_list[] = { |
| 24 | * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code | 24 | MEDIA_BUS_FMT_FIXED, |
| 25 | * in the scaler) | 25 | MEDIA_BUS_FMT_RGB444_1X12, |
| 26 | */ | 26 | MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, |
| 27 | static const struct vimc_pix_map vimc_pix_map_list[] = { | 27 | MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, |
| 28 | /* TODO: add all missing formats */ | 28 | MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, |
| 29 | 29 | MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, | |
| 30 | /* RGB formats */ | 30 | MEDIA_BUS_FMT_RGB565_1X16, |
| 31 | { | 31 | MEDIA_BUS_FMT_BGR565_2X8_BE, |
| 32 | .code = MEDIA_BUS_FMT_BGR888_1X24, | 32 | MEDIA_BUS_FMT_BGR565_2X8_LE, |
| 33 | .pixelformat = V4L2_PIX_FMT_BGR24, | 33 | MEDIA_BUS_FMT_RGB565_2X8_BE, |
| 34 | .bpp = 3, | 34 | MEDIA_BUS_FMT_RGB565_2X8_LE, |
| 35 | .bayer = false, | 35 | MEDIA_BUS_FMT_RGB666_1X18, |
| 36 | }, | 36 | MEDIA_BUS_FMT_RBG888_1X24, |
| 37 | { | 37 | MEDIA_BUS_FMT_RGB666_1X24_CPADHI, |
| 38 | .code = MEDIA_BUS_FMT_RGB888_1X24, | 38 | MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, |
| 39 | .pixelformat = V4L2_PIX_FMT_RGB24, | 39 | MEDIA_BUS_FMT_BGR888_1X24, |
| 40 | .bpp = 3, | 40 | MEDIA_BUS_FMT_GBR888_1X24, |
| 41 | .bayer = false, | 41 | MEDIA_BUS_FMT_RGB888_1X24, |
| 42 | }, | 42 | MEDIA_BUS_FMT_RGB888_2X12_BE, |
| 43 | { | 43 | MEDIA_BUS_FMT_RGB888_2X12_LE, |
| 44 | .code = MEDIA_BUS_FMT_ARGB8888_1X32, | 44 | MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, |
| 45 | .pixelformat = V4L2_PIX_FMT_ARGB32, | 45 | MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, |
| 46 | .bpp = 4, | 46 | MEDIA_BUS_FMT_ARGB8888_1X32, |
| 47 | .bayer = false, | 47 | MEDIA_BUS_FMT_RGB888_1X32_PADHI, |
| 48 | }, | 48 | MEDIA_BUS_FMT_RGB101010_1X30, |
| 49 | 49 | MEDIA_BUS_FMT_RGB121212_1X36, | |
| 50 | /* Bayer formats */ | 50 | MEDIA_BUS_FMT_RGB161616_1X48, |
| 51 | { | 51 | MEDIA_BUS_FMT_Y8_1X8, |
| 52 | .code = MEDIA_BUS_FMT_SBGGR8_1X8, | 52 | MEDIA_BUS_FMT_UV8_1X8, |
| 53 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | 53 | MEDIA_BUS_FMT_UYVY8_1_5X8, |
| 54 | .bpp = 1, | 54 | MEDIA_BUS_FMT_VYUY8_1_5X8, |
| 55 | .bayer = true, | 55 | MEDIA_BUS_FMT_YUYV8_1_5X8, |
| 56 | }, | 56 | MEDIA_BUS_FMT_YVYU8_1_5X8, |
| 57 | { | 57 | MEDIA_BUS_FMT_UYVY8_2X8, |
| 58 | .code = MEDIA_BUS_FMT_SGBRG8_1X8, | 58 | MEDIA_BUS_FMT_VYUY8_2X8, |
| 59 | .pixelformat = V4L2_PIX_FMT_SGBRG8, | 59 | MEDIA_BUS_FMT_YUYV8_2X8, |
| 60 | .bpp = 1, | 60 | MEDIA_BUS_FMT_YVYU8_2X8, |
| 61 | .bayer = true, | 61 | MEDIA_BUS_FMT_Y10_1X10, |
| 62 | }, | 62 | MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, |
| 63 | { | 63 | MEDIA_BUS_FMT_UYVY10_2X10, |
| 64 | .code = MEDIA_BUS_FMT_SGRBG8_1X8, | 64 | MEDIA_BUS_FMT_VYUY10_2X10, |
| 65 | .pixelformat = V4L2_PIX_FMT_SGRBG8, | 65 | MEDIA_BUS_FMT_YUYV10_2X10, |
| 66 | .bpp = 1, | 66 | MEDIA_BUS_FMT_YVYU10_2X10, |
| 67 | .bayer = true, | 67 | MEDIA_BUS_FMT_Y12_1X12, |
| 68 | }, | 68 | MEDIA_BUS_FMT_UYVY12_2X12, |
| 69 | { | 69 | MEDIA_BUS_FMT_VYUY12_2X12, |
| 70 | .code = MEDIA_BUS_FMT_SRGGB8_1X8, | 70 | MEDIA_BUS_FMT_YUYV12_2X12, |
| 71 | .pixelformat = V4L2_PIX_FMT_SRGGB8, | 71 | MEDIA_BUS_FMT_YVYU12_2X12, |
| 72 | .bpp = 1, | 72 | MEDIA_BUS_FMT_UYVY8_1X16, |
| 73 | .bayer = true, | 73 | MEDIA_BUS_FMT_VYUY8_1X16, |
| 74 | }, | 74 | MEDIA_BUS_FMT_YUYV8_1X16, |
| 75 | { | 75 | MEDIA_BUS_FMT_YVYU8_1X16, |
| 76 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, | 76 | MEDIA_BUS_FMT_YDYUYDYV8_1X16, |
| 77 | .pixelformat = V4L2_PIX_FMT_SBGGR10, | 77 | MEDIA_BUS_FMT_UYVY10_1X20, |
| 78 | .bpp = 2, | 78 | MEDIA_BUS_FMT_VYUY10_1X20, |
| 79 | .bayer = true, | 79 | MEDIA_BUS_FMT_YUYV10_1X20, |
| 80 | }, | 80 | MEDIA_BUS_FMT_YVYU10_1X20, |
| 81 | { | 81 | MEDIA_BUS_FMT_VUY8_1X24, |
| 82 | .code = MEDIA_BUS_FMT_SGBRG10_1X10, | 82 | MEDIA_BUS_FMT_YUV8_1X24, |
| 83 | .pixelformat = V4L2_PIX_FMT_SGBRG10, | 83 | MEDIA_BUS_FMT_UYYVYY8_0_5X24, |
| 84 | .bpp = 2, | 84 | MEDIA_BUS_FMT_UYVY12_1X24, |
| 85 | .bayer = true, | 85 | MEDIA_BUS_FMT_VYUY12_1X24, |
| 86 | }, | 86 | MEDIA_BUS_FMT_YUYV12_1X24, |
| 87 | { | 87 | MEDIA_BUS_FMT_YVYU12_1X24, |
| 88 | .code = MEDIA_BUS_FMT_SGRBG10_1X10, | 88 | MEDIA_BUS_FMT_YUV10_1X30, |
| 89 | .pixelformat = V4L2_PIX_FMT_SGRBG10, | 89 | MEDIA_BUS_FMT_UYYVYY10_0_5X30, |
| 90 | .bpp = 2, | 90 | MEDIA_BUS_FMT_AYUV8_1X32, |
| 91 | .bayer = true, | 91 | MEDIA_BUS_FMT_UYYVYY12_0_5X36, |
| 92 | }, | 92 | MEDIA_BUS_FMT_YUV12_1X36, |
| 93 | { | 93 | MEDIA_BUS_FMT_YUV16_1X48, |
| 94 | .code = MEDIA_BUS_FMT_SRGGB10_1X10, | 94 | MEDIA_BUS_FMT_UYYVYY16_0_5X48, |
| 95 | .pixelformat = V4L2_PIX_FMT_SRGGB10, | 95 | MEDIA_BUS_FMT_SBGGR8_1X8, |
| 96 | .bpp = 2, | 96 | MEDIA_BUS_FMT_SGBRG8_1X8, |
| 97 | .bayer = true, | 97 | MEDIA_BUS_FMT_SGRBG8_1X8, |
| 98 | }, | 98 | MEDIA_BUS_FMT_SRGGB8_1X8, |
| 99 | 99 | MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, | |
| 100 | /* 10bit raw bayer a-law compressed to 8 bits */ | 100 | MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, |
| 101 | { | 101 | MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, |
| 102 | .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, | 102 | MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, |
| 103 | .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8, | 103 | MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, |
| 104 | .bpp = 1, | 104 | MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, |
| 105 | .bayer = true, | 105 | MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, |
| 106 | }, | 106 | MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, |
| 107 | { | 107 | MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, |
| 108 | .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, | 108 | MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, |
| 109 | .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8, | 109 | MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, |
| 110 | .bpp = 1, | 110 | MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, |
| 111 | .bayer = true, | 111 | MEDIA_BUS_FMT_SBGGR10_1X10, |
| 112 | }, | 112 | MEDIA_BUS_FMT_SGBRG10_1X10, |
| 113 | { | 113 | MEDIA_BUS_FMT_SGRBG10_1X10, |
| 114 | .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, | 114 | MEDIA_BUS_FMT_SRGGB10_1X10, |
| 115 | .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8, | 115 | MEDIA_BUS_FMT_SBGGR12_1X12, |
| 116 | .bpp = 1, | 116 | MEDIA_BUS_FMT_SGBRG12_1X12, |
| 117 | .bayer = true, | 117 | MEDIA_BUS_FMT_SGRBG12_1X12, |
| 118 | }, | 118 | MEDIA_BUS_FMT_SRGGB12_1X12, |
| 119 | { | 119 | MEDIA_BUS_FMT_SBGGR14_1X14, |
| 120 | .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, | 120 | MEDIA_BUS_FMT_SGBRG14_1X14, |
| 121 | .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8, | 121 | MEDIA_BUS_FMT_SGRBG14_1X14, |
| 122 | .bpp = 1, | 122 | MEDIA_BUS_FMT_SRGGB14_1X14, |
| 123 | .bayer = true, | 123 | MEDIA_BUS_FMT_SBGGR16_1X16, |
| 124 | }, | 124 | MEDIA_BUS_FMT_SGBRG16_1X16, |
| 125 | 125 | MEDIA_BUS_FMT_SGRBG16_1X16, | |
| 126 | /* 10bit raw bayer DPCM compressed to 8 bits */ | 126 | MEDIA_BUS_FMT_SRGGB16_1X16, |
| 127 | { | 127 | MEDIA_BUS_FMT_JPEG_1X8, |
| 128 | .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, | 128 | MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, |
| 129 | .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8, | 129 | MEDIA_BUS_FMT_AHSV8888_1X32, |
| 130 | .bpp = 1, | ||
| 131 | .bayer = true, | ||
| 132 | }, | ||
| 133 | { | ||
| 134 | .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, | ||
| 135 | .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8, | ||
| 136 | .bpp = 1, | ||
| 137 | .bayer = true, | ||
| 138 | }, | ||
| 139 | { | ||
| 140 | .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, | ||
| 141 | .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, | ||
| 142 | .bpp = 1, | ||
| 143 | .bayer = true, | ||
| 144 | }, | ||
| 145 | { | ||
| 146 | .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, | ||
| 147 | .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8, | ||
| 148 | .bpp = 1, | ||
| 149 | .bayer = true, | ||
| 150 | }, | ||
| 151 | { | ||
| 152 | .code = MEDIA_BUS_FMT_SBGGR12_1X12, | ||
| 153 | .pixelformat = V4L2_PIX_FMT_SBGGR12, | ||
| 154 | .bpp = 2, | ||
| 155 | .bayer = true, | ||
| 156 | }, | ||
| 157 | { | ||
| 158 | .code = MEDIA_BUS_FMT_SGBRG12_1X12, | ||
| 159 | .pixelformat = V4L2_PIX_FMT_SGBRG12, | ||
| 160 | .bpp = 2, | ||
| 161 | .bayer = true, | ||
| 162 | }, | ||
| 163 | { | ||
| 164 | .code = MEDIA_BUS_FMT_SGRBG12_1X12, | ||
| 165 | .pixelformat = V4L2_PIX_FMT_SGRBG12, | ||
| 166 | .bpp = 2, | ||
| 167 | .bayer = true, | ||
| 168 | }, | ||
| 169 | { | ||
| 170 | .code = MEDIA_BUS_FMT_SRGGB12_1X12, | ||
| 171 | .pixelformat = V4L2_PIX_FMT_SRGGB12, | ||
| 172 | .bpp = 2, | ||
| 173 | .bayer = true, | ||
| 174 | }, | ||
| 175 | }; | 130 | }; |
| 176 | 131 | ||
| 177 | const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i) | 132 | /* Helper function to check mbus codes */ |
| 178 | { | 133 | bool vimc_mbus_code_supported(__u32 code) |
| 179 | if (i >= ARRAY_SIZE(vimc_pix_map_list)) | ||
| 180 | return NULL; | ||
| 181 | |||
| 182 | return &vimc_pix_map_list[i]; | ||
| 183 | } | ||
| 184 | EXPORT_SYMBOL_GPL(vimc_pix_map_by_index); | ||
| 185 | |||
| 186 | const struct vimc_pix_map *vimc_pix_map_by_code(u32 code) | ||
| 187 | { | 134 | { |
| 188 | unsigned int i; | 135 | unsigned int i; |
| 189 | 136 | ||
| 190 | for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { | 137 | for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) |
| 191 | if (vimc_pix_map_list[i].code == code) | 138 | if (code == vimc_mbus_list[i]) |
| 192 | return &vimc_pix_map_list[i]; | 139 | return true; |
| 193 | } | 140 | return false; |
| 194 | return NULL; | ||
| 195 | } | 141 | } |
| 196 | EXPORT_SYMBOL_GPL(vimc_pix_map_by_code); | 142 | EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); |
| 197 | 143 | ||
| 198 | const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat) | 144 | /* Helper function to enumerate mbus codes */ |
| 145 | int vimc_enum_mbus_code(struct v4l2_subdev *sd, | ||
| 146 | struct v4l2_subdev_pad_config *cfg, | ||
| 147 | struct v4l2_subdev_mbus_code_enum *code) | ||
| 199 | { | 148 | { |
| 200 | unsigned int i; | 149 | if (code->index >= ARRAY_SIZE(vimc_mbus_list)) |
| 150 | return -EINVAL; | ||
| 201 | 151 | ||
| 202 | for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { | 152 | code->code = vimc_mbus_list[code->index]; |
| 203 | if (vimc_pix_map_list[i].pixelformat == pixelformat) | 153 | return 0; |
| 204 | return &vimc_pix_map_list[i]; | ||
| 205 | } | ||
| 206 | return NULL; | ||
| 207 | } | 154 | } |
| 208 | EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat); | 155 | EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); |
| 209 | 156 | ||
| 210 | /* Helper function to allocate and initialize pads */ | 157 | /* Helper function to allocate and initialize pads */ |
| 211 | struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) | 158 | struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) |
| @@ -277,15 +224,13 @@ static int vimc_get_mbus_format(struct media_pad *pad, | |||
| 277 | struct video_device, | 224 | struct video_device, |
| 278 | entity); | 225 | entity); |
| 279 | struct vimc_ent_device *ved = video_get_drvdata(vdev); | 226 | struct vimc_ent_device *ved = video_get_drvdata(vdev); |
| 280 | const struct vimc_pix_map *vpix; | ||
| 281 | struct v4l2_pix_format vdev_fmt; | 227 | struct v4l2_pix_format vdev_fmt; |
| 282 | 228 | ||
| 283 | if (!ved->vdev_get_format) | 229 | if (!ved->vdev_get_format) |
| 284 | return -ENOIOCTLCMD; | 230 | return -ENOIOCTLCMD; |
| 285 | 231 | ||
| 286 | ved->vdev_get_format(ved, &vdev_fmt); | 232 | ved->vdev_get_format(ved, &vdev_fmt); |
| 287 | vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat); | 233 | v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0); |
| 288 | v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code); | ||
| 289 | } else { | 234 | } else { |
| 290 | return -EINVAL; | 235 | return -EINVAL; |
| 291 | } | 236 | } |
| @@ -325,8 +270,12 @@ int vimc_link_validate(struct media_link *link) | |||
| 325 | /* The width, height and code must match. */ | 270 | /* The width, height and code must match. */ |
| 326 | if (source_fmt.format.width != sink_fmt.format.width | 271 | if (source_fmt.format.width != sink_fmt.format.width |
| 327 | || source_fmt.format.height != sink_fmt.format.height | 272 | || source_fmt.format.height != sink_fmt.format.height |
| 328 | || source_fmt.format.code != sink_fmt.format.code) | 273 | || (source_fmt.format.code && sink_fmt.format.code && |
| 274 | source_fmt.format.code != sink_fmt.format.code)) { | ||
| 275 | pr_err("vimc: format doesn't match in link %s->%s\n", | ||
| 276 | link->source->entity->name, link->sink->entity->name); | ||
| 329 | return -EPIPE; | 277 | return -EPIPE; |
| 278 | } | ||
| 330 | 279 | ||
| 331 | /* | 280 | /* |
| 332 | * The field order must match, or the sink field order must be NONE | 281 | * The field order must match, or the sink field order must be NONE |
| @@ -380,6 +329,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, | |||
| 380 | u32 function, | 329 | u32 function, |
| 381 | u16 num_pads, | 330 | u16 num_pads, |
| 382 | const unsigned long *pads_flag, | 331 | const unsigned long *pads_flag, |
| 332 | const struct v4l2_subdev_internal_ops *sd_int_ops, | ||
| 383 | const struct v4l2_subdev_ops *sd_ops) | 333 | const struct v4l2_subdev_ops *sd_ops) |
| 384 | { | 334 | { |
| 385 | int ret; | 335 | int ret; |
| @@ -394,6 +344,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, | |||
| 394 | 344 | ||
| 395 | /* Initialize the subdev */ | 345 | /* Initialize the subdev */ |
| 396 | v4l2_subdev_init(sd, sd_ops); | 346 | v4l2_subdev_init(sd, sd_ops); |
| 347 | sd->internal_ops = sd_int_ops; | ||
| 397 | sd->entity.function = function; | 348 | sd->entity.function = function; |
| 398 | sd->entity.ops = &vimc_ent_sd_mops; | 349 | sd->entity.ops = &vimc_ent_sd_mops; |
| 399 | sd->owner = THIS_MODULE; | 350 | sd->owner = THIS_MODULE; |
| @@ -431,9 +382,9 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register); | |||
| 431 | 382 | ||
| 432 | void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd) | 383 | void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd) |
| 433 | { | 384 | { |
| 434 | v4l2_device_unregister_subdev(sd); | ||
| 435 | media_entity_cleanup(ved->ent); | 385 | media_entity_cleanup(ved->ent); |
| 436 | vimc_pads_cleanup(ved->pads); | 386 | vimc_pads_cleanup(ved->pads); |
| 387 | v4l2_device_unregister_subdev(sd); | ||
| 437 | } | 388 | } |
| 438 | EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister); | 389 | EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister); |
| 439 | 390 | ||
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h index 84539430b5e7..142ddfa69b3d 100644 --- a/drivers/media/platform/vimc/vimc-common.h +++ b/drivers/media/platform/vimc/vimc-common.h | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include <media/media-device.h> | 22 | #include <media/media-device.h> |
| 23 | #include <media/v4l2-device.h> | 23 | #include <media/v4l2-device.h> |
| 24 | 24 | ||
| 25 | #include "vimc-streamer.h" | ||
| 26 | |||
| 25 | #define VIMC_PDEV_NAME "vimc" | 27 | #define VIMC_PDEV_NAME "vimc" |
| 26 | 28 | ||
| 27 | /* VIMC-specific controls */ | 29 | /* VIMC-specific controls */ |
| @@ -78,23 +80,6 @@ struct vimc_platform_data { | |||
| 78 | }; | 80 | }; |
| 79 | 81 | ||
| 80 | /** | 82 | /** |
| 81 | * struct vimc_pix_map - maps media bus code with v4l2 pixel format | ||
| 82 | * | ||
| 83 | * @code: media bus format code defined by MEDIA_BUS_FMT_* macros | ||
| 84 | * @bbp: number of bytes each pixel occupies | ||
| 85 | * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros | ||
| 86 | * | ||
| 87 | * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding | ||
| 88 | * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp) | ||
| 89 | */ | ||
| 90 | struct vimc_pix_map { | ||
| 91 | unsigned int code; | ||
| 92 | unsigned int bpp; | ||
| 93 | u32 pixelformat; | ||
| 94 | bool bayer; | ||
| 95 | }; | ||
| 96 | |||
| 97 | /** | ||
| 98 | * struct vimc_ent_device - core struct that represents a node in the topology | 83 | * struct vimc_ent_device - core struct that represents a node in the topology |
| 99 | * | 84 | * |
| 100 | * @ent: the pointer to struct media_entity for the node | 85 | * @ent: the pointer to struct media_entity for the node |
| @@ -115,6 +100,7 @@ struct vimc_pix_map { | |||
| 115 | struct vimc_ent_device { | 100 | struct vimc_ent_device { |
| 116 | struct media_entity *ent; | 101 | struct media_entity *ent; |
| 117 | struct media_pad *pads; | 102 | struct media_pad *pads; |
| 103 | struct vimc_stream *stream; | ||
| 118 | void * (*process_frame)(struct vimc_ent_device *ved, | 104 | void * (*process_frame)(struct vimc_ent_device *ved, |
| 119 | const void *frame); | 105 | const void *frame); |
| 120 | void (*vdev_get_format)(struct vimc_ent_device *ved, | 106 | void (*vdev_get_format)(struct vimc_ent_device *ved, |
| @@ -122,6 +108,23 @@ struct vimc_ent_device { | |||
| 122 | }; | 108 | }; |
| 123 | 109 | ||
| 124 | /** | 110 | /** |
| 111 | * vimc_mbus_code_supported - helper to check supported mbus codes | ||
| 112 | * | ||
| 113 | * Helper function to check if mbus code is enumerated by vimc_enum_mbus_code() | ||
| 114 | */ | ||
| 115 | bool vimc_mbus_code_supported(__u32 code); | ||
| 116 | |||
| 117 | /** | ||
| 118 | * vimc_enum_mbus_code - enumerate mbus codes | ||
| 119 | * | ||
| 120 | * Helper function to be pluged in .enum_mbus_code from | ||
| 121 | * struct v4l2_subdev_pad_ops. | ||
| 122 | */ | ||
| 123 | int vimc_enum_mbus_code(struct v4l2_subdev *sd, | ||
| 124 | struct v4l2_subdev_pad_config *cfg, | ||
| 125 | struct v4l2_subdev_mbus_code_enum *code); | ||
| 126 | |||
| 127 | /** | ||
| 125 | * vimc_pads_init - initialize pads | 128 | * vimc_pads_init - initialize pads |
| 126 | * | 129 | * |
| 127 | * @num_pads: number of pads to initialize | 130 | * @num_pads: number of pads to initialize |
| @@ -156,27 +159,6 @@ static inline void vimc_pads_cleanup(struct media_pad *pads) | |||
| 156 | int vimc_pipeline_s_stream(struct media_entity *ent, int enable); | 159 | int vimc_pipeline_s_stream(struct media_entity *ent, int enable); |
| 157 | 160 | ||
| 158 | /** | 161 | /** |
| 159 | * vimc_pix_map_by_index - get vimc_pix_map struct by its index | ||
| 160 | * | ||
| 161 | * @i: index of the vimc_pix_map struct in vimc_pix_map_list | ||
| 162 | */ | ||
| 163 | const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i); | ||
| 164 | |||
| 165 | /** | ||
| 166 | * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code | ||
| 167 | * | ||
| 168 | * @code: media bus format code defined by MEDIA_BUS_FMT_* macros | ||
| 169 | */ | ||
| 170 | const struct vimc_pix_map *vimc_pix_map_by_code(u32 code); | ||
| 171 | |||
| 172 | /** | ||
| 173 | * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format | ||
| 174 | * | ||
| 175 | * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros | ||
| 176 | */ | ||
| 177 | const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat); | ||
| 178 | |||
| 179 | /** | ||
| 180 | * vimc_ent_sd_register - initialize and register a subdev node | 162 | * vimc_ent_sd_register - initialize and register a subdev node |
| 181 | * | 163 | * |
| 182 | * @ved: the vimc_ent_device struct to be initialize | 164 | * @ved: the vimc_ent_device struct to be initialize |
| @@ -187,6 +169,7 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat); | |||
| 187 | * @function: media entity function defined by MEDIA_ENT_F_* macros | 169 | * @function: media entity function defined by MEDIA_ENT_F_* macros |
| 188 | * @num_pads: number of pads to initialize | 170 | * @num_pads: number of pads to initialize |
| 189 | * @pads_flag: flags to use in each pad | 171 | * @pads_flag: flags to use in each pad |
| 172 | * @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops | ||
| 190 | * @sd_ops: pointer to &struct v4l2_subdev_ops. | 173 | * @sd_ops: pointer to &struct v4l2_subdev_ops. |
| 191 | * | 174 | * |
| 192 | * Helper function initialize and register the struct vimc_ent_device and struct | 175 | * Helper function initialize and register the struct vimc_ent_device and struct |
| @@ -199,6 +182,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved, | |||
| 199 | u32 function, | 182 | u32 function, |
| 200 | u16 num_pads, | 183 | u16 num_pads, |
| 201 | const unsigned long *pads_flag, | 184 | const unsigned long *pads_flag, |
| 185 | const struct v4l2_subdev_internal_ops *sd_int_ops, | ||
| 202 | const struct v4l2_subdev_ops *sd_ops); | 186 | const struct v4l2_subdev_ops *sd_ops); |
| 203 | 187 | ||
| 204 | /** | 188 | /** |
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index 0fbb7914098f..3aa62d7e3d0e 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c | |||
| @@ -304,6 +304,8 @@ static int vimc_probe(struct platform_device *pdev) | |||
| 304 | 304 | ||
| 305 | dev_dbg(&pdev->dev, "probe"); | 305 | dev_dbg(&pdev->dev, "probe"); |
| 306 | 306 | ||
| 307 | memset(&vimc->mdev, 0, sizeof(vimc->mdev)); | ||
| 308 | |||
| 307 | /* Create platform_device for each entity in the topology*/ | 309 | /* Create platform_device for each entity in the topology*/ |
| 308 | vimc->subdevs = devm_kcalloc(&vimc->pdev.dev, vimc->pipe_cfg->num_ents, | 310 | vimc->subdevs = devm_kcalloc(&vimc->pdev.dev, vimc->pipe_cfg->num_ents, |
| 309 | sizeof(*vimc->subdevs), GFP_KERNEL); | 311 | sizeof(*vimc->subdevs), GFP_KERNEL); |
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 7d77c63b99d2..281f9c1a7249 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | #include "vimc-common.h" | 26 | #include "vimc-common.h" |
| 27 | 27 | ||
| 28 | #define VIMC_DEB_DRV_NAME "vimc-debayer" | 28 | #define VIMC_DEB_DRV_NAME "vimc-debayer" |
| 29 | /* This module only supports tranforming a bayer format to V4L2_PIX_FMT_RGB24 */ | ||
| 30 | #define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24 | ||
| 31 | #define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24 | ||
| 29 | 32 | ||
| 30 | static unsigned int deb_mean_win_size = 3; | 33 | static unsigned int deb_mean_win_size = 3; |
| 31 | module_param(deb_mean_win_size, uint, 0000); | 34 | module_param(deb_mean_win_size, uint, 0000); |
| @@ -44,6 +47,7 @@ enum vimc_deb_rgb_colors { | |||
| 44 | }; | 47 | }; |
| 45 | 48 | ||
| 46 | struct vimc_deb_pix_map { | 49 | struct vimc_deb_pix_map { |
| 50 | u32 pixelformat; | ||
| 47 | u32 code; | 51 | u32 code; |
| 48 | enum vimc_deb_rgb_colors order[2][2]; | 52 | enum vimc_deb_rgb_colors order[2][2]; |
| 49 | }; | 53 | }; |
| @@ -66,68 +70,80 @@ struct vimc_deb_device { | |||
| 66 | static const struct v4l2_mbus_framefmt sink_fmt_default = { | 70 | static const struct v4l2_mbus_framefmt sink_fmt_default = { |
| 67 | .width = 640, | 71 | .width = 640, |
| 68 | .height = 480, | 72 | .height = 480, |
| 69 | .code = MEDIA_BUS_FMT_RGB888_1X24, | 73 | .code = MEDIA_BUS_FMT_SRGGB8_1X8, |
| 70 | .field = V4L2_FIELD_NONE, | 74 | .field = V4L2_FIELD_NONE, |
| 71 | .colorspace = V4L2_COLORSPACE_DEFAULT, | 75 | .colorspace = V4L2_COLORSPACE_DEFAULT, |
| 72 | }; | 76 | }; |
| 73 | 77 | ||
| 74 | static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = { | 78 | static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = { |
| 75 | { | 79 | { |
| 80 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
| 76 | .code = MEDIA_BUS_FMT_SBGGR8_1X8, | 81 | .code = MEDIA_BUS_FMT_SBGGR8_1X8, |
| 77 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, | 82 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, |
| 78 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } | 83 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } |
| 79 | }, | 84 | }, |
| 80 | { | 85 | { |
| 86 | .pixelformat = V4L2_PIX_FMT_SGBRG8, | ||
| 81 | .code = MEDIA_BUS_FMT_SGBRG8_1X8, | 87 | .code = MEDIA_BUS_FMT_SGBRG8_1X8, |
| 82 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, | 88 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, |
| 83 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } | 89 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } |
| 84 | }, | 90 | }, |
| 85 | { | 91 | { |
| 92 | .pixelformat = V4L2_PIX_FMT_SGRBG8, | ||
| 86 | .code = MEDIA_BUS_FMT_SGRBG8_1X8, | 93 | .code = MEDIA_BUS_FMT_SGRBG8_1X8, |
| 87 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, | 94 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, |
| 88 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } | 95 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } |
| 89 | }, | 96 | }, |
| 90 | { | 97 | { |
| 98 | .pixelformat = V4L2_PIX_FMT_SRGGB8, | ||
| 91 | .code = MEDIA_BUS_FMT_SRGGB8_1X8, | 99 | .code = MEDIA_BUS_FMT_SRGGB8_1X8, |
| 92 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, | 100 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, |
| 93 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } | 101 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } |
| 94 | }, | 102 | }, |
| 95 | { | 103 | { |
| 104 | .pixelformat = V4L2_PIX_FMT_SBGGR10, | ||
| 96 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, | 105 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
| 97 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, | 106 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, |
| 98 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } | 107 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } |
| 99 | }, | 108 | }, |
| 100 | { | 109 | { |
| 110 | .pixelformat = V4L2_PIX_FMT_SGBRG10, | ||
| 101 | .code = MEDIA_BUS_FMT_SGBRG10_1X10, | 111 | .code = MEDIA_BUS_FMT_SGBRG10_1X10, |
| 102 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, | 112 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, |
| 103 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } | 113 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } |
| 104 | }, | 114 | }, |
| 105 | { | 115 | { |
| 116 | .pixelformat = V4L2_PIX_FMT_SGRBG10, | ||
| 106 | .code = MEDIA_BUS_FMT_SGRBG10_1X10, | 117 | .code = MEDIA_BUS_FMT_SGRBG10_1X10, |
| 107 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, | 118 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, |
| 108 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } | 119 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } |
| 109 | }, | 120 | }, |
| 110 | { | 121 | { |
| 122 | .pixelformat = V4L2_PIX_FMT_SRGGB10, | ||
| 111 | .code = MEDIA_BUS_FMT_SRGGB10_1X10, | 123 | .code = MEDIA_BUS_FMT_SRGGB10_1X10, |
| 112 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, | 124 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, |
| 113 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } | 125 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } |
| 114 | }, | 126 | }, |
| 115 | { | 127 | { |
| 128 | .pixelformat = V4L2_PIX_FMT_SBGGR12, | ||
| 116 | .code = MEDIA_BUS_FMT_SBGGR12_1X12, | 129 | .code = MEDIA_BUS_FMT_SBGGR12_1X12, |
| 117 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, | 130 | .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, |
| 118 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } | 131 | { VIMC_DEB_GREEN, VIMC_DEB_RED } } |
| 119 | }, | 132 | }, |
| 120 | { | 133 | { |
| 134 | .pixelformat = V4L2_PIX_FMT_SGBRG12, | ||
| 121 | .code = MEDIA_BUS_FMT_SGBRG12_1X12, | 135 | .code = MEDIA_BUS_FMT_SGBRG12_1X12, |
| 122 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, | 136 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, |
| 123 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } | 137 | { VIMC_DEB_RED, VIMC_DEB_GREEN } } |
| 124 | }, | 138 | }, |
| 125 | { | 139 | { |
| 140 | .pixelformat = V4L2_PIX_FMT_SGRBG12, | ||
| 126 | .code = MEDIA_BUS_FMT_SGRBG12_1X12, | 141 | .code = MEDIA_BUS_FMT_SGRBG12_1X12, |
| 127 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, | 142 | .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, |
| 128 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } | 143 | { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } |
| 129 | }, | 144 | }, |
| 130 | { | 145 | { |
| 146 | .pixelformat = V4L2_PIX_FMT_SRGGB12, | ||
| 131 | .code = MEDIA_BUS_FMT_SRGGB12_1X12, | 147 | .code = MEDIA_BUS_FMT_SRGGB12_1X12, |
| 132 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, | 148 | .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, |
| 133 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } | 149 | { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } |
| @@ -168,41 +184,32 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd, | |||
| 168 | struct v4l2_subdev_pad_config *cfg, | 184 | struct v4l2_subdev_pad_config *cfg, |
| 169 | struct v4l2_subdev_mbus_code_enum *code) | 185 | struct v4l2_subdev_mbus_code_enum *code) |
| 170 | { | 186 | { |
| 171 | /* We only support one format for source pads */ | 187 | /* For the sink pad we only support codes in the map_list */ |
| 172 | if (IS_SRC(code->pad)) { | 188 | if (IS_SINK(code->pad)) { |
| 173 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); | ||
| 174 | |||
| 175 | if (code->index) | ||
| 176 | return -EINVAL; | ||
| 177 | |||
| 178 | code->code = vdeb->src_code; | ||
| 179 | } else { | ||
| 180 | if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list)) | 189 | if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list)) |
| 181 | return -EINVAL; | 190 | return -EINVAL; |
| 182 | 191 | ||
| 183 | code->code = vimc_deb_pix_map_list[code->index].code; | 192 | code->code = vimc_deb_pix_map_list[code->index].code; |
| 193 | return 0; | ||
| 184 | } | 194 | } |
| 185 | 195 | ||
| 186 | return 0; | 196 | return vimc_enum_mbus_code(sd, cfg, code); |
| 187 | } | 197 | } |
| 188 | 198 | ||
| 189 | static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, | 199 | static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, |
| 190 | struct v4l2_subdev_pad_config *cfg, | 200 | struct v4l2_subdev_pad_config *cfg, |
| 191 | struct v4l2_subdev_frame_size_enum *fse) | 201 | struct v4l2_subdev_frame_size_enum *fse) |
| 192 | { | 202 | { |
| 193 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); | ||
| 194 | |||
| 195 | if (fse->index) | 203 | if (fse->index) |
| 196 | return -EINVAL; | 204 | return -EINVAL; |
| 197 | 205 | ||
| 206 | /* For the sink pad we only support codes in the map_list */ | ||
| 198 | if (IS_SINK(fse->pad)) { | 207 | if (IS_SINK(fse->pad)) { |
| 199 | const struct vimc_deb_pix_map *vpix = | 208 | const struct vimc_deb_pix_map *vpix = |
| 200 | vimc_deb_pix_map_by_code(fse->code); | 209 | vimc_deb_pix_map_by_code(fse->code); |
| 201 | 210 | ||
| 202 | if (!vpix) | 211 | if (!vpix) |
| 203 | return -EINVAL; | 212 | return -EINVAL; |
| 204 | } else if (fse->code != vdeb->src_code) { | ||
| 205 | return -EINVAL; | ||
| 206 | } | 213 | } |
| 207 | 214 | ||
| 208 | fse->min_width = VIMC_FRAME_MIN_WIDTH; | 215 | fse->min_width = VIMC_FRAME_MIN_WIDTH; |
| @@ -258,6 +265,9 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd, | |||
| 258 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); | 265 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); |
| 259 | struct v4l2_mbus_framefmt *sink_fmt; | 266 | struct v4l2_mbus_framefmt *sink_fmt; |
| 260 | 267 | ||
| 268 | if (!vimc_mbus_code_supported(fmt->format.code)) | ||
| 269 | fmt->format.code = sink_fmt_default.code; | ||
| 270 | |||
| 261 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 271 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
| 262 | /* Do not change the format while stream is on */ | 272 | /* Do not change the format while stream is on */ |
| 263 | if (vdeb->src_frame) | 273 | if (vdeb->src_frame) |
| @@ -270,11 +280,11 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd, | |||
| 270 | 280 | ||
| 271 | /* | 281 | /* |
| 272 | * Do not change the format of the source pad, | 282 | * Do not change the format of the source pad, |
| 273 | * it is propagated from the sink | 283 | * it is propagated from the sink (except for the code) |
| 274 | */ | 284 | */ |
| 275 | if (IS_SRC(fmt->pad)) { | 285 | if (IS_SRC(fmt->pad)) { |
| 286 | vdeb->src_code = fmt->format.code; | ||
| 276 | fmt->format = *sink_fmt; | 287 | fmt->format = *sink_fmt; |
| 277 | /* TODO: Add support for other formats */ | ||
| 278 | fmt->format.code = vdeb->src_code; | 288 | fmt->format.code = vdeb->src_code; |
| 279 | } else { | 289 | } else { |
| 280 | /* Set the new format in the sink pad */ | 290 | /* Set the new format in the sink pad */ |
| @@ -306,7 +316,7 @@ static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = { | |||
| 306 | .set_fmt = vimc_deb_set_fmt, | 316 | .set_fmt = vimc_deb_set_fmt, |
| 307 | }; | 317 | }; |
| 308 | 318 | ||
| 309 | static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb, | 319 | static void vimc_deb_set_rgb_pix_rgb24(struct vimc_deb_device *vdeb, |
| 310 | unsigned int lin, | 320 | unsigned int lin, |
| 311 | unsigned int col, | 321 | unsigned int col, |
| 312 | unsigned int rgb[3]) | 322 | unsigned int rgb[3]) |
| @@ -323,25 +333,38 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 323 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); | 333 | struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); |
| 324 | 334 | ||
| 325 | if (enable) { | 335 | if (enable) { |
| 326 | const struct vimc_pix_map *vpix; | 336 | u32 src_pixelformat = vdeb->ved.stream->producer_pixfmt; |
| 337 | const struct v4l2_format_info *pix_info; | ||
| 327 | unsigned int frame_size; | 338 | unsigned int frame_size; |
| 328 | 339 | ||
| 329 | if (vdeb->src_frame) | 340 | if (vdeb->src_frame) |
| 330 | return 0; | 341 | return 0; |
| 331 | 342 | ||
| 332 | /* Calculate the frame size of the source pad */ | 343 | /* We only support translating bayer to RGB24 */ |
| 333 | vpix = vimc_pix_map_by_code(vdeb->src_code); | 344 | if (src_pixelformat != V4L2_PIX_FMT_RGB24) { |
| 334 | frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height * | 345 | dev_err(vdeb->dev, |
| 335 | vpix->bpp; | 346 | "translating to pixfmt (0x%08x) is not supported\n", |
| 336 | 347 | src_pixelformat); | |
| 337 | /* Save the bytes per pixel of the sink */ | 348 | return -EINVAL; |
| 338 | vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code); | 349 | } |
| 339 | vdeb->sink_bpp = vpix->bpp; | ||
| 340 | 350 | ||
| 341 | /* Get the corresponding pixel map from the table */ | 351 | /* Get the corresponding pixel map from the table */ |
| 342 | vdeb->sink_pix_map = | 352 | vdeb->sink_pix_map = |
| 343 | vimc_deb_pix_map_by_code(vdeb->sink_fmt.code); | 353 | vimc_deb_pix_map_by_code(vdeb->sink_fmt.code); |
| 344 | 354 | ||
| 355 | /* Request bayer format from the pipeline for the sink pad */ | ||
| 356 | vdeb->ved.stream->producer_pixfmt = | ||
| 357 | vdeb->sink_pix_map->pixelformat; | ||
| 358 | |||
| 359 | /* Calculate frame_size of the source */ | ||
| 360 | pix_info = v4l2_format_info(src_pixelformat); | ||
| 361 | frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height * | ||
| 362 | pix_info->bpp[0]; | ||
| 363 | |||
| 364 | /* Get bpp from the sink */ | ||
| 365 | pix_info = v4l2_format_info(vdeb->sink_pix_map->pixelformat); | ||
| 366 | vdeb->sink_bpp = pix_info->bpp[0]; | ||
| 367 | |||
| 345 | /* | 368 | /* |
| 346 | * Allocate the frame buffer. Use vmalloc to be able to | 369 | * Allocate the frame buffer. Use vmalloc to be able to |
| 347 | * allocate a large amount of memory | 370 | * allocate a large amount of memory |
| @@ -489,6 +512,18 @@ static void *vimc_deb_process_frame(struct vimc_ent_device *ved, | |||
| 489 | 512 | ||
| 490 | } | 513 | } |
| 491 | 514 | ||
| 515 | static void vimc_deb_release(struct v4l2_subdev *sd) | ||
| 516 | { | ||
| 517 | struct vimc_deb_device *vdeb = | ||
| 518 | container_of(sd, struct vimc_deb_device, sd); | ||
| 519 | |||
| 520 | kfree(vdeb); | ||
| 521 | } | ||
| 522 | |||
| 523 | static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = { | ||
| 524 | .release = vimc_deb_release, | ||
| 525 | }; | ||
| 526 | |||
| 492 | static void vimc_deb_comp_unbind(struct device *comp, struct device *master, | 527 | static void vimc_deb_comp_unbind(struct device *comp, struct device *master, |
| 493 | void *master_data) | 528 | void *master_data) |
| 494 | { | 529 | { |
| @@ -497,7 +532,6 @@ static void vimc_deb_comp_unbind(struct device *comp, struct device *master, | |||
| 497 | ved); | 532 | ved); |
| 498 | 533 | ||
| 499 | vimc_ent_sd_unregister(ved, &vdeb->sd); | 534 | vimc_ent_sd_unregister(ved, &vdeb->sd); |
| 500 | kfree(vdeb); | ||
| 501 | } | 535 | } |
| 502 | 536 | ||
| 503 | static int vimc_deb_comp_bind(struct device *comp, struct device *master, | 537 | static int vimc_deb_comp_bind(struct device *comp, struct device *master, |
| @@ -519,7 +553,7 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, | |||
| 519 | MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, | 553 | MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2, |
| 520 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, | 554 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, |
| 521 | MEDIA_PAD_FL_SOURCE}, | 555 | MEDIA_PAD_FL_SOURCE}, |
| 522 | &vimc_deb_ops); | 556 | &vimc_deb_int_ops, &vimc_deb_ops); |
| 523 | if (ret) { | 557 | if (ret) { |
| 524 | kfree(vdeb); | 558 | kfree(vdeb); |
| 525 | return ret; | 559 | return ret; |
| @@ -531,14 +565,14 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, | |||
| 531 | 565 | ||
| 532 | /* Initialize the frame format */ | 566 | /* Initialize the frame format */ |
| 533 | vdeb->sink_fmt = sink_fmt_default; | 567 | vdeb->sink_fmt = sink_fmt_default; |
| 568 | vdeb->src_code = VIMC_DEB_SRC_MBUS_FMT_DEFAULT; | ||
| 534 | /* | 569 | /* |
| 535 | * TODO: Add support for more output formats, we only support | 570 | * TODO: Add support for more output formats, we only support |
| 536 | * RGB888 for now | 571 | * RGB24 for now. |
| 537 | * NOTE: the src format is always the same as the sink, except | 572 | * NOTE: the src format is always the same as the sink, except |
| 538 | * for the code | 573 | * for the code |
| 539 | */ | 574 | */ |
| 540 | vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24; | 575 | vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24; |
| 541 | vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24; | ||
| 542 | 576 | ||
| 543 | return 0; | 577 | return 0; |
| 544 | } | 578 | } |
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index 39b2a73dfcc1..8aecf8e92031 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c | |||
| @@ -35,6 +35,12 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); | |||
| 35 | #define IS_SRC(pad) (pad) | 35 | #define IS_SRC(pad) (pad) |
| 36 | #define MAX_ZOOM 8 | 36 | #define MAX_ZOOM 8 |
| 37 | 37 | ||
| 38 | static const u32 vimc_sca_supported_pixfmt[] = { | ||
| 39 | V4L2_PIX_FMT_BGR24, | ||
| 40 | V4L2_PIX_FMT_RGB24, | ||
| 41 | V4L2_PIX_FMT_ARGB32, | ||
| 42 | }; | ||
| 43 | |||
| 38 | struct vimc_sca_device { | 44 | struct vimc_sca_device { |
| 39 | struct vimc_ent_device ved; | 45 | struct vimc_ent_device ved; |
| 40 | struct v4l2_subdev sd; | 46 | struct v4l2_subdev sd; |
| @@ -57,6 +63,16 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = { | |||
| 57 | .colorspace = V4L2_COLORSPACE_DEFAULT, | 63 | .colorspace = V4L2_COLORSPACE_DEFAULT, |
| 58 | }; | 64 | }; |
| 59 | 65 | ||
| 66 | static bool vimc_sca_is_pixfmt_supported(u32 pixelformat) | ||
| 67 | { | ||
| 68 | unsigned int i; | ||
| 69 | |||
| 70 | for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++) | ||
| 71 | if (vimc_sca_supported_pixfmt[i] == pixelformat) | ||
| 72 | return true; | ||
| 73 | return false; | ||
| 74 | } | ||
| 75 | |||
| 60 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | 76 | static int vimc_sca_init_cfg(struct v4l2_subdev *sd, |
| 61 | struct v4l2_subdev_pad_config *cfg) | 77 | struct v4l2_subdev_pad_config *cfg) |
| 62 | { | 78 | { |
| @@ -76,35 +92,13 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd, | |||
| 76 | return 0; | 92 | return 0; |
| 77 | } | 93 | } |
| 78 | 94 | ||
| 79 | static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, | ||
| 80 | struct v4l2_subdev_pad_config *cfg, | ||
| 81 | struct v4l2_subdev_mbus_code_enum *code) | ||
| 82 | { | ||
| 83 | const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); | ||
| 84 | |||
| 85 | /* We don't support bayer format */ | ||
| 86 | if (!vpix || vpix->bayer) | ||
| 87 | return -EINVAL; | ||
| 88 | |||
| 89 | code->code = vpix->code; | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, | 95 | static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, |
| 95 | struct v4l2_subdev_pad_config *cfg, | 96 | struct v4l2_subdev_pad_config *cfg, |
| 96 | struct v4l2_subdev_frame_size_enum *fse) | 97 | struct v4l2_subdev_frame_size_enum *fse) |
| 97 | { | 98 | { |
| 98 | const struct vimc_pix_map *vpix; | ||
| 99 | |||
| 100 | if (fse->index) | 99 | if (fse->index) |
| 101 | return -EINVAL; | 100 | return -EINVAL; |
| 102 | 101 | ||
| 103 | /* Only accept code in the pix map table in non bayer format */ | ||
| 104 | vpix = vimc_pix_map_by_code(fse->code); | ||
| 105 | if (!vpix || vpix->bayer) | ||
| 106 | return -EINVAL; | ||
| 107 | |||
| 108 | fse->min_width = VIMC_FRAME_MIN_WIDTH; | 102 | fse->min_width = VIMC_FRAME_MIN_WIDTH; |
| 109 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; | 103 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; |
| 110 | 104 | ||
| @@ -141,13 +135,6 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd, | |||
| 141 | 135 | ||
| 142 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) | 136 | static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) |
| 143 | { | 137 | { |
| 144 | const struct vimc_pix_map *vpix; | ||
| 145 | |||
| 146 | /* Only accept code in the pix map table in non bayer format */ | ||
| 147 | vpix = vimc_pix_map_by_code(fmt->code); | ||
| 148 | if (!vpix || vpix->bayer) | ||
| 149 | fmt->code = sink_fmt_default.code; | ||
| 150 | |||
| 151 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, | 138 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, |
| 152 | VIMC_FRAME_MAX_WIDTH) & ~1; | 139 | VIMC_FRAME_MAX_WIDTH) & ~1; |
| 153 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, | 140 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, |
| @@ -166,6 +153,9 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
| 166 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 153 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
| 167 | struct v4l2_mbus_framefmt *sink_fmt; | 154 | struct v4l2_mbus_framefmt *sink_fmt; |
| 168 | 155 | ||
| 156 | if (!vimc_mbus_code_supported(fmt->format.code)) | ||
| 157 | fmt->format.code = sink_fmt_default.code; | ||
| 158 | |||
| 169 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 159 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
| 170 | /* Do not change the format while stream is on */ | 160 | /* Do not change the format while stream is on */ |
| 171 | if (vsca->src_frame) | 161 | if (vsca->src_frame) |
| @@ -208,7 +198,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, | |||
| 208 | 198 | ||
| 209 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { | 199 | static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { |
| 210 | .init_cfg = vimc_sca_init_cfg, | 200 | .init_cfg = vimc_sca_init_cfg, |
| 211 | .enum_mbus_code = vimc_sca_enum_mbus_code, | 201 | .enum_mbus_code = vimc_enum_mbus_code, |
| 212 | .enum_frame_size = vimc_sca_enum_frame_size, | 202 | .enum_frame_size = vimc_sca_enum_frame_size, |
| 213 | .get_fmt = vimc_sca_get_fmt, | 203 | .get_fmt = vimc_sca_get_fmt, |
| 214 | .set_fmt = vimc_sca_set_fmt, | 204 | .set_fmt = vimc_sca_set_fmt, |
| @@ -219,15 +209,22 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 219 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); | 209 | struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); |
| 220 | 210 | ||
| 221 | if (enable) { | 211 | if (enable) { |
| 222 | const struct vimc_pix_map *vpix; | 212 | u32 pixelformat = vsca->ved.stream->producer_pixfmt; |
| 213 | const struct v4l2_format_info *pix_info; | ||
| 223 | unsigned int frame_size; | 214 | unsigned int frame_size; |
| 224 | 215 | ||
| 225 | if (vsca->src_frame) | 216 | if (vsca->src_frame) |
| 226 | return 0; | 217 | return 0; |
| 227 | 218 | ||
| 219 | if (!vimc_sca_is_pixfmt_supported(pixelformat)) { | ||
| 220 | dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n", | ||
| 221 | pixelformat); | ||
| 222 | return -EINVAL; | ||
| 223 | } | ||
| 224 | |||
| 228 | /* Save the bytes per pixel of the sink */ | 225 | /* Save the bytes per pixel of the sink */ |
| 229 | vpix = vimc_pix_map_by_code(vsca->sink_fmt.code); | 226 | pix_info = v4l2_format_info(pixelformat); |
| 230 | vsca->bpp = vpix->bpp; | 227 | vsca->bpp = pix_info->bpp[0]; |
| 231 | 228 | ||
| 232 | /* Calculate the width in bytes of the src frame */ | 229 | /* Calculate the width in bytes of the src frame */ |
| 233 | vsca->src_line_size = vsca->sink_fmt.width * | 230 | vsca->src_line_size = vsca->sink_fmt.width * |
| @@ -348,6 +345,18 @@ static void *vimc_sca_process_frame(struct vimc_ent_device *ved, | |||
| 348 | return vsca->src_frame; | 345 | return vsca->src_frame; |
| 349 | }; | 346 | }; |
| 350 | 347 | ||
| 348 | static void vimc_sca_release(struct v4l2_subdev *sd) | ||
| 349 | { | ||
| 350 | struct vimc_sca_device *vsca = | ||
| 351 | container_of(sd, struct vimc_sca_device, sd); | ||
| 352 | |||
| 353 | kfree(vsca); | ||
| 354 | } | ||
| 355 | |||
| 356 | static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = { | ||
| 357 | .release = vimc_sca_release, | ||
| 358 | }; | ||
| 359 | |||
| 351 | static void vimc_sca_comp_unbind(struct device *comp, struct device *master, | 360 | static void vimc_sca_comp_unbind(struct device *comp, struct device *master, |
| 352 | void *master_data) | 361 | void *master_data) |
| 353 | { | 362 | { |
| @@ -356,7 +365,6 @@ static void vimc_sca_comp_unbind(struct device *comp, struct device *master, | |||
| 356 | ved); | 365 | ved); |
| 357 | 366 | ||
| 358 | vimc_ent_sd_unregister(ved, &vsca->sd); | 367 | vimc_ent_sd_unregister(ved, &vsca->sd); |
| 359 | kfree(vsca); | ||
| 360 | } | 368 | } |
| 361 | 369 | ||
| 362 | 370 | ||
| @@ -379,7 +387,7 @@ static int vimc_sca_comp_bind(struct device *comp, struct device *master, | |||
| 379 | MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, | 387 | MEDIA_ENT_F_PROC_VIDEO_SCALER, 2, |
| 380 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, | 388 | (const unsigned long[2]) {MEDIA_PAD_FL_SINK, |
| 381 | MEDIA_PAD_FL_SOURCE}, | 389 | MEDIA_PAD_FL_SOURCE}, |
| 382 | &vimc_sca_ops); | 390 | &vimc_sca_int_ops, &vimc_sca_ops); |
| 383 | if (ret) { | 391 | if (ret) { |
| 384 | kfree(vsca); | 392 | kfree(vsca); |
| 385 | return ret; | 393 | return ret; |
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 59195f262623..081e54204c9f 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c | |||
| @@ -65,34 +65,13 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd, | |||
| 65 | return 0; | 65 | return 0; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd, | ||
| 69 | struct v4l2_subdev_pad_config *cfg, | ||
| 70 | struct v4l2_subdev_mbus_code_enum *code) | ||
| 71 | { | ||
| 72 | const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); | ||
| 73 | |||
| 74 | if (!vpix) | ||
| 75 | return -EINVAL; | ||
| 76 | |||
| 77 | code->code = vpix->code; | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, | 68 | static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, |
| 83 | struct v4l2_subdev_pad_config *cfg, | 69 | struct v4l2_subdev_pad_config *cfg, |
| 84 | struct v4l2_subdev_frame_size_enum *fse) | 70 | struct v4l2_subdev_frame_size_enum *fse) |
| 85 | { | 71 | { |
| 86 | const struct vimc_pix_map *vpix; | ||
| 87 | |||
| 88 | if (fse->index) | 72 | if (fse->index) |
| 89 | return -EINVAL; | 73 | return -EINVAL; |
| 90 | 74 | ||
| 91 | /* Only accept code in the pix map table */ | ||
| 92 | vpix = vimc_pix_map_by_code(fse->code); | ||
| 93 | if (!vpix) | ||
| 94 | return -EINVAL; | ||
| 95 | |||
| 96 | fse->min_width = VIMC_FRAME_MIN_WIDTH; | 75 | fse->min_width = VIMC_FRAME_MIN_WIDTH; |
| 97 | fse->max_width = VIMC_FRAME_MAX_WIDTH; | 76 | fse->max_width = VIMC_FRAME_MAX_WIDTH; |
| 98 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; | 77 | fse->min_height = VIMC_FRAME_MIN_HEIGHT; |
| @@ -117,14 +96,17 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd, | |||
| 117 | 96 | ||
| 118 | static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) | 97 | static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) |
| 119 | { | 98 | { |
| 120 | const struct vimc_pix_map *vpix = | 99 | u32 pixelformat = vsen->ved.stream->producer_pixfmt; |
| 121 | vimc_pix_map_by_code(vsen->mbus_format.code); | 100 | const struct v4l2_format_info *pix_info; |
| 101 | |||
| 102 | pix_info = v4l2_format_info(pixelformat); | ||
| 122 | 103 | ||
| 123 | tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, | 104 | tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, |
| 124 | vsen->mbus_format.height, vsen->mbus_format.field); | 105 | vsen->mbus_format.height, vsen->mbus_format.field); |
| 125 | tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp); | 106 | tpg_s_bytesperline(&vsen->tpg, 0, |
| 107 | vsen->mbus_format.width * pix_info->bpp[0]); | ||
| 126 | tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); | 108 | tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); |
| 127 | tpg_s_fourcc(&vsen->tpg, vpix->pixelformat); | 109 | tpg_s_fourcc(&vsen->tpg, pixelformat); |
| 128 | /* TODO: add support for V4L2_FIELD_ALTERNATE */ | 110 | /* TODO: add support for V4L2_FIELD_ALTERNATE */ |
| 129 | tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); | 111 | tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); |
| 130 | tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); | 112 | tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); |
| @@ -135,13 +117,6 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) | |||
| 135 | 117 | ||
| 136 | static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) | 118 | static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) |
| 137 | { | 119 | { |
| 138 | const struct vimc_pix_map *vpix; | ||
| 139 | |||
| 140 | /* Only accept code in the pix map table */ | ||
| 141 | vpix = vimc_pix_map_by_code(fmt->code); | ||
| 142 | if (!vpix) | ||
| 143 | fmt->code = fmt_default.code; | ||
| 144 | |||
| 145 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, | 120 | fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, |
| 146 | VIMC_FRAME_MAX_WIDTH) & ~1; | 121 | VIMC_FRAME_MAX_WIDTH) & ~1; |
| 147 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, | 122 | fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, |
| @@ -161,6 +136,9 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd, | |||
| 161 | struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); | 136 | struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); |
| 162 | struct v4l2_mbus_framefmt *mf; | 137 | struct v4l2_mbus_framefmt *mf; |
| 163 | 138 | ||
| 139 | if (!vimc_mbus_code_supported(fmt->format.code)) | ||
| 140 | fmt->format.code = fmt_default.code; | ||
| 141 | |||
| 164 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 142 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
| 165 | /* Do not change the format while stream is on */ | 143 | /* Do not change the format while stream is on */ |
| 166 | if (vsen->frame) | 144 | if (vsen->frame) |
| @@ -193,7 +171,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd, | |||
| 193 | 171 | ||
| 194 | static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { | 172 | static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { |
| 195 | .init_cfg = vimc_sen_init_cfg, | 173 | .init_cfg = vimc_sen_init_cfg, |
| 196 | .enum_mbus_code = vimc_sen_enum_mbus_code, | 174 | .enum_mbus_code = vimc_enum_mbus_code, |
| 197 | .enum_frame_size = vimc_sen_enum_frame_size, | 175 | .enum_frame_size = vimc_sen_enum_frame_size, |
| 198 | .get_fmt = vimc_sen_get_fmt, | 176 | .get_fmt = vimc_sen_get_fmt, |
| 199 | .set_fmt = vimc_sen_set_fmt, | 177 | .set_fmt = vimc_sen_set_fmt, |
| @@ -215,7 +193,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 215 | container_of(sd, struct vimc_sen_device, sd); | 193 | container_of(sd, struct vimc_sen_device, sd); |
| 216 | 194 | ||
| 217 | if (enable) { | 195 | if (enable) { |
| 218 | const struct vimc_pix_map *vpix; | 196 | u32 pixelformat = vsen->ved.stream->producer_pixfmt; |
| 197 | const struct v4l2_format_info *pix_info; | ||
| 219 | unsigned int frame_size; | 198 | unsigned int frame_size; |
| 220 | 199 | ||
| 221 | if (vsen->kthread_sen) | 200 | if (vsen->kthread_sen) |
| @@ -223,8 +202,8 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 223 | return 0; | 202 | return 0; |
| 224 | 203 | ||
| 225 | /* Calculate the frame size */ | 204 | /* Calculate the frame size */ |
| 226 | vpix = vimc_pix_map_by_code(vsen->mbus_format.code); | 205 | pix_info = v4l2_format_info(pixelformat); |
| 227 | frame_size = vsen->mbus_format.width * vpix->bpp * | 206 | frame_size = vsen->mbus_format.width * pix_info->bpp[0] * |
| 228 | vsen->mbus_format.height; | 207 | vsen->mbus_format.height; |
| 229 | 208 | ||
| 230 | /* | 209 | /* |
| @@ -301,6 +280,20 @@ static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = { | |||
| 301 | .s_ctrl = vimc_sen_s_ctrl, | 280 | .s_ctrl = vimc_sen_s_ctrl, |
| 302 | }; | 281 | }; |
| 303 | 282 | ||
| 283 | static void vimc_sen_release(struct v4l2_subdev *sd) | ||
| 284 | { | ||
| 285 | struct vimc_sen_device *vsen = | ||
| 286 | container_of(sd, struct vimc_sen_device, sd); | ||
| 287 | |||
| 288 | v4l2_ctrl_handler_free(&vsen->hdl); | ||
| 289 | tpg_free(&vsen->tpg); | ||
| 290 | kfree(vsen); | ||
| 291 | } | ||
| 292 | |||
| 293 | static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = { | ||
| 294 | .release = vimc_sen_release, | ||
| 295 | }; | ||
| 296 | |||
| 304 | static void vimc_sen_comp_unbind(struct device *comp, struct device *master, | 297 | static void vimc_sen_comp_unbind(struct device *comp, struct device *master, |
| 305 | void *master_data) | 298 | void *master_data) |
| 306 | { | 299 | { |
| @@ -309,9 +302,6 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master, | |||
| 309 | container_of(ved, struct vimc_sen_device, ved); | 302 | container_of(ved, struct vimc_sen_device, ved); |
| 310 | 303 | ||
| 311 | vimc_ent_sd_unregister(ved, &vsen->sd); | 304 | vimc_ent_sd_unregister(ved, &vsen->sd); |
| 312 | v4l2_ctrl_handler_free(&vsen->hdl); | ||
| 313 | tpg_free(&vsen->tpg); | ||
| 314 | kfree(vsen); | ||
| 315 | } | 305 | } |
| 316 | 306 | ||
| 317 | /* Image Processing Controls */ | 307 | /* Image Processing Controls */ |
| @@ -371,7 +361,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master, | |||
| 371 | pdata->entity_name, | 361 | pdata->entity_name, |
| 372 | MEDIA_ENT_F_CAM_SENSOR, 1, | 362 | MEDIA_ENT_F_CAM_SENSOR, 1, |
| 373 | (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, | 363 | (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE}, |
| 374 | &vimc_sen_ops); | 364 | &vimc_sen_int_ops, &vimc_sen_ops); |
| 375 | if (ret) | 365 | if (ret) |
| 376 | goto err_free_hdl; | 366 | goto err_free_hdl; |
| 377 | 367 | ||
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c index fcc897fb247b..26b674259489 100644 --- a/drivers/media/platform/vimc/vimc-streamer.c +++ b/drivers/media/platform/vimc/vimc-streamer.c | |||
| @@ -46,19 +46,19 @@ static struct media_entity *vimc_get_source_entity(struct media_entity *ent) | |||
| 46 | */ | 46 | */ |
| 47 | static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream) | 47 | static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream) |
| 48 | { | 48 | { |
| 49 | struct media_entity *entity; | 49 | struct vimc_ent_device *ved; |
| 50 | struct v4l2_subdev *sd; | 50 | struct v4l2_subdev *sd; |
| 51 | 51 | ||
| 52 | while (stream->pipe_size) { | 52 | while (stream->pipe_size) { |
| 53 | stream->pipe_size--; | 53 | stream->pipe_size--; |
| 54 | entity = stream->ved_pipeline[stream->pipe_size]->ent; | 54 | ved = stream->ved_pipeline[stream->pipe_size]; |
| 55 | entity = vimc_get_source_entity(entity); | 55 | ved->stream = NULL; |
| 56 | stream->ved_pipeline[stream->pipe_size] = NULL; | 56 | stream->ved_pipeline[stream->pipe_size] = NULL; |
| 57 | 57 | ||
| 58 | if (!is_media_entity_v4l2_subdev(entity)) | 58 | if (!is_media_entity_v4l2_subdev(ved->ent)) |
| 59 | continue; | 59 | continue; |
| 60 | 60 | ||
| 61 | sd = media_entity_to_v4l2_subdev(entity); | 61 | sd = media_entity_to_v4l2_subdev(ved->ent); |
| 62 | v4l2_subdev_call(sd, video, s_stream, 0); | 62 | v4l2_subdev_call(sd, video, s_stream, 0); |
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| @@ -88,19 +88,27 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream, | |||
| 88 | return -EINVAL; | 88 | return -EINVAL; |
| 89 | } | 89 | } |
| 90 | stream->ved_pipeline[stream->pipe_size++] = ved; | 90 | stream->ved_pipeline[stream->pipe_size++] = ved; |
| 91 | ved->stream = stream; | ||
| 92 | |||
| 93 | if (is_media_entity_v4l2_subdev(ved->ent)) { | ||
| 94 | sd = media_entity_to_v4l2_subdev(ved->ent); | ||
| 95 | ret = v4l2_subdev_call(sd, video, s_stream, 1); | ||
| 96 | if (ret && ret != -ENOIOCTLCMD) { | ||
| 97 | pr_err("subdev_call error %s\n", | ||
| 98 | ved->ent->name); | ||
| 99 | vimc_streamer_pipeline_terminate(stream); | ||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | } | ||
| 91 | 103 | ||
| 92 | entity = vimc_get_source_entity(ved->ent); | 104 | entity = vimc_get_source_entity(ved->ent); |
| 93 | /* Check if the end of the pipeline was reached*/ | 105 | /* Check if the end of the pipeline was reached*/ |
| 94 | if (!entity) | 106 | if (!entity) |
| 95 | return 0; | 107 | return 0; |
| 96 | 108 | ||
| 109 | /* Get the next device in the pipeline */ | ||
| 97 | if (is_media_entity_v4l2_subdev(entity)) { | 110 | if (is_media_entity_v4l2_subdev(entity)) { |
| 98 | sd = media_entity_to_v4l2_subdev(entity); | 111 | sd = media_entity_to_v4l2_subdev(entity); |
| 99 | ret = v4l2_subdev_call(sd, video, s_stream, 1); | ||
| 100 | if (ret && ret != -ENOIOCTLCMD) { | ||
| 101 | vimc_streamer_pipeline_terminate(stream); | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | ved = v4l2_get_subdevdata(sd); | 112 | ved = v4l2_get_subdevdata(sd); |
| 105 | } else { | 113 | } else { |
| 106 | vdev = container_of(entity, | 114 | vdev = container_of(entity, |
| @@ -117,10 +125,10 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream, | |||
| 117 | static int vimc_streamer_thread(void *data) | 125 | static int vimc_streamer_thread(void *data) |
| 118 | { | 126 | { |
| 119 | struct vimc_stream *stream = data; | 127 | struct vimc_stream *stream = data; |
| 128 | u8 *frame = NULL; | ||
| 120 | int i; | 129 | int i; |
| 121 | 130 | ||
| 122 | set_freezable(); | 131 | set_freezable(); |
| 123 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 124 | 132 | ||
| 125 | for (;;) { | 133 | for (;;) { |
| 126 | try_to_freeze(); | 134 | try_to_freeze(); |
| @@ -128,15 +136,13 @@ static int vimc_streamer_thread(void *data) | |||
| 128 | break; | 136 | break; |
| 129 | 137 | ||
| 130 | for (i = stream->pipe_size - 1; i >= 0; i--) { | 138 | for (i = stream->pipe_size - 1; i >= 0; i--) { |
| 131 | stream->frame = stream->ved_pipeline[i]->process_frame( | 139 | frame = stream->ved_pipeline[i]->process_frame( |
| 132 | stream->ved_pipeline[i], | 140 | stream->ved_pipeline[i], frame); |
| 133 | stream->frame); | 141 | if (!frame || IS_ERR(frame)) |
| 134 | if (!stream->frame) | ||
| 135 | break; | ||
| 136 | if (IS_ERR(stream->frame)) | ||
| 137 | break; | 142 | break; |
| 138 | } | 143 | } |
| 139 | //wait for 60hz | 144 | //wait for 60hz |
| 145 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 140 | schedule_timeout(HZ / 60); | 146 | schedule_timeout(HZ / 60); |
| 141 | } | 147 | } |
| 142 | 148 | ||
diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h index 752af2e2d5a2..2b3667408794 100644 --- a/drivers/media/platform/vimc/vimc-streamer.h +++ b/drivers/media/platform/vimc/vimc-streamer.h | |||
| @@ -15,12 +15,32 @@ | |||
| 15 | 15 | ||
| 16 | #define VIMC_STREAMER_PIPELINE_MAX_SIZE 16 | 16 | #define VIMC_STREAMER_PIPELINE_MAX_SIZE 16 |
| 17 | 17 | ||
| 18 | /** | ||
| 19 | * struct vimc_stream - struct that represents a stream in the pipeline | ||
| 20 | * | ||
| 21 | * @pipe: the media pipeline object associated with this stream | ||
| 22 | * @ved_pipeline: array containing all the entities participating in the | ||
| 23 | * stream. The order is from a video device (usually a capture device) where | ||
| 24 | * stream_on was called, to the entity generating the first base image to be | ||
| 25 | * processed in the pipeline. | ||
| 26 | * @pipe_size: size of @ved_pipeline | ||
| 27 | * @kthread: thread that generates the frames of the stream. | ||
| 28 | * @producer_pixfmt: the pixel format requested from the pipeline. This must | ||
| 29 | * be set just before calling vimc_streamer_s_stream(ent, 1). This value is | ||
| 30 | * propagated up to the source of the base image (usually a sensor node) and | ||
| 31 | * can be modified by entities during s_stream callback to request a different | ||
| 32 | * format from rest of the pipeline. | ||
| 33 | * | ||
| 34 | * When the user call stream_on in a video device, struct vimc_stream is | ||
| 35 | * used to keep track of all entities and subdevices that generates and | ||
| 36 | * process frames for the stream. | ||
| 37 | */ | ||
| 18 | struct vimc_stream { | 38 | struct vimc_stream { |
| 19 | struct media_pipeline pipe; | 39 | struct media_pipeline pipe; |
| 20 | struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE]; | 40 | struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE]; |
| 21 | unsigned int pipe_size; | 41 | unsigned int pipe_size; |
| 22 | u8 *frame; | ||
| 23 | struct task_struct *kthread; | 42 | struct task_struct *kthread; |
| 43 | u32 producer_pixfmt; | ||
| 24 | }; | 44 | }; |
| 25 | 45 | ||
| 26 | /** | 46 | /** |
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig index 154de92dd809..4b51d4d6cf93 100644 --- a/drivers/media/platform/vivid/Kconfig +++ b/drivers/media/platform/vivid/Kconfig | |||
| @@ -11,7 +11,7 @@ config VIDEO_VIVID | |||
| 11 | select VIDEOBUF2_DMA_CONTIG | 11 | select VIDEOBUF2_DMA_CONTIG |
| 12 | select VIDEO_V4L2_TPG | 12 | select VIDEO_V4L2_TPG |
| 13 | default n | 13 | default n |
| 14 | ---help--- | 14 | help |
| 15 | Enables a virtual video driver. This driver emulates a webcam, | 15 | Enables a virtual video driver. This driver emulates a webcam, |
| 16 | TV, S-Video and HDMI capture hardware, including VBI support for | 16 | TV, S-Video and HDMI capture hardware, including VBI support for |
| 17 | the SDTV inputs. Also video output, VBI output, radio receivers, | 17 | the SDTV inputs. Also video output, VBI output, radio receivers, |
| @@ -28,7 +28,7 @@ config VIDEO_VIVID_CEC | |||
| 28 | bool "Enable CEC emulation support" | 28 | bool "Enable CEC emulation support" |
| 29 | depends on VIDEO_VIVID | 29 | depends on VIDEO_VIVID |
| 30 | select CEC_CORE | 30 | select CEC_CORE |
| 31 | ---help--- | 31 | help |
| 32 | When selected the vivid module will emulate the optional | 32 | When selected the vivid module will emulate the optional |
| 33 | HDMI CEC feature. | 33 | HDMI CEC feature. |
| 34 | 34 | ||
| @@ -36,6 +36,6 @@ config VIDEO_VIVID_MAX_DEVS | |||
| 36 | int "Maximum number of devices" | 36 | int "Maximum number of devices" |
| 37 | depends on VIDEO_VIVID | 37 | depends on VIDEO_VIVID |
| 38 | default "64" | 38 | default "64" |
| 39 | ---help--- | 39 | help |
| 40 | This allows you to specify the maximum number of devices supported | 40 | This allows you to specify the maximum number of devices supported |
| 41 | by the vivid driver. | 41 | by the vivid driver. |
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index 342e0e6c103b..7047df6f0e0e 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c | |||
| @@ -681,7 +681,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) | |||
| 681 | dev->v4l2_dev.mdev = &dev->mdev; | 681 | dev->v4l2_dev.mdev = &dev->mdev; |
| 682 | 682 | ||
| 683 | /* Initialize media device */ | 683 | /* Initialize media device */ |
| 684 | strlcpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model)); | 684 | strscpy(dev->mdev.model, VIVID_MODULE_NAME, sizeof(dev->mdev.model)); |
| 685 | snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info), | 685 | snprintf(dev->mdev.bus_info, sizeof(dev->mdev.bus_info), |
| 686 | "platform:%s-%03d", VIVID_MODULE_NAME, inst); | 686 | "platform:%s-%03d", VIVID_MODULE_NAME, inst); |
| 687 | dev->mdev.dev = &pdev->dev; | 687 | dev->mdev.dev = &pdev->dev; |
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index 52eeda624d7e..530ac8decb25 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c | |||
| @@ -1007,7 +1007,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection | |||
| 1007 | v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); | 1007 | v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); |
| 1008 | if (dev->bitmap_cap && (compose->width != s->r.width || | 1008 | if (dev->bitmap_cap && (compose->width != s->r.width || |
| 1009 | compose->height != s->r.height)) { | 1009 | compose->height != s->r.height)) { |
| 1010 | kfree(dev->bitmap_cap); | 1010 | vfree(dev->bitmap_cap); |
| 1011 | dev->bitmap_cap = NULL; | 1011 | dev->bitmap_cap = NULL; |
| 1012 | } | 1012 | } |
| 1013 | *compose = s->r; | 1013 | *compose = s->r; |
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index e61b91b414f9..9350ca65dd91 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c | |||
| @@ -798,7 +798,7 @@ int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection | |||
| 798 | s->r.height *= factor; | 798 | s->r.height *= factor; |
| 799 | if (dev->bitmap_out && (compose->width != s->r.width || | 799 | if (dev->bitmap_out && (compose->width != s->r.width || |
| 800 | compose->height != s->r.height)) { | 800 | compose->height != s->r.height)) { |
| 801 | kfree(dev->bitmap_out); | 801 | vfree(dev->bitmap_out); |
| 802 | dev->bitmap_out = NULL; | 802 | dev->bitmap_out = NULL; |
| 803 | } | 803 | } |
| 804 | *compose = s->r; | 804 | *compose = s->r; |
| @@ -941,15 +941,19 @@ int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, | |||
| 941 | return ret; | 941 | return ret; |
| 942 | 942 | ||
| 943 | if (win->bitmap) { | 943 | if (win->bitmap) { |
| 944 | new_bitmap = memdup_user(win->bitmap, bitmap_size); | 944 | new_bitmap = vzalloc(bitmap_size); |
| 945 | 945 | ||
| 946 | if (IS_ERR(new_bitmap)) | 946 | if (!new_bitmap) |
| 947 | return PTR_ERR(new_bitmap); | 947 | return -ENOMEM; |
| 948 | if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) { | ||
| 949 | vfree(new_bitmap); | ||
| 950 | return -EFAULT; | ||
| 951 | } | ||
| 948 | } | 952 | } |
| 949 | 953 | ||
| 950 | dev->overlay_out_top = win->w.top; | 954 | dev->overlay_out_top = win->w.top; |
| 951 | dev->overlay_out_left = win->w.left; | 955 | dev->overlay_out_left = win->w.left; |
| 952 | kfree(dev->bitmap_out); | 956 | vfree(dev->bitmap_out); |
| 953 | dev->bitmap_out = new_bitmap; | 957 | dev->bitmap_out = new_bitmap; |
| 954 | dev->clipcount_out = win->clipcount; | 958 | dev->clipcount_out = win->clipcount; |
| 955 | if (dev->clipcount_out) | 959 | if (dev->clipcount_out) |
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index 54ff539ffea0..f72ac01c21ea 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c | |||
| @@ -42,6 +42,30 @@ static const struct vsp1_format_info vsp1_video_formats[] = { | |||
| 42 | VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | 42 | VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | |
| 43 | VI6_RPF_DSWAP_P_WDS, | 43 | VI6_RPF_DSWAP_P_WDS, |
| 44 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | 44 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, |
| 45 | { V4L2_PIX_FMT_RGBA444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 46 | VI6_FMT_RGBA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 47 | VI6_RPF_DSWAP_P_WDS, | ||
| 48 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 49 | { V4L2_PIX_FMT_RGBX444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 50 | VI6_FMT_RGBX_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 51 | VI6_RPF_DSWAP_P_WDS, | ||
| 52 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 53 | { V4L2_PIX_FMT_ABGR444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 54 | VI6_FMT_ABGR_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 55 | VI6_RPF_DSWAP_P_WDS, | ||
| 56 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 57 | { V4L2_PIX_FMT_XBGR444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 58 | VI6_FMT_ABGR_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 59 | VI6_RPF_DSWAP_P_WDS, | ||
| 60 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 61 | { V4L2_PIX_FMT_BGRA444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 62 | VI6_FMT_BGRA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 63 | VI6_RPF_DSWAP_P_WDS, | ||
| 64 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 65 | { V4L2_PIX_FMT_BGRX444, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 66 | VI6_FMT_BGRA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 67 | VI6_RPF_DSWAP_P_WDS, | ||
| 68 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 45 | { V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32, | 69 | { V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32, |
| 46 | VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | 70 | VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | |
| 47 | VI6_RPF_DSWAP_P_WDS, | 71 | VI6_RPF_DSWAP_P_WDS, |
| @@ -50,6 +74,30 @@ static const struct vsp1_format_info vsp1_video_formats[] = { | |||
| 50 | VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | 74 | VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | |
| 51 | VI6_RPF_DSWAP_P_WDS, | 75 | VI6_RPF_DSWAP_P_WDS, |
| 52 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | 76 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, |
| 77 | { V4L2_PIX_FMT_RGBA555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 78 | VI6_FMT_RGBA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 79 | VI6_RPF_DSWAP_P_WDS, | ||
| 80 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 81 | { V4L2_PIX_FMT_RGBX555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 82 | VI6_FMT_RGBX_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 83 | VI6_RPF_DSWAP_P_WDS, | ||
| 84 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 85 | { V4L2_PIX_FMT_ABGR555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 86 | VI6_FMT_ABGR_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 87 | VI6_RPF_DSWAP_P_WDS, | ||
| 88 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 89 | { V4L2_PIX_FMT_XBGR555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 90 | VI6_FMT_ABGR_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 91 | VI6_RPF_DSWAP_P_WDS, | ||
| 92 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 93 | { V4L2_PIX_FMT_BGRA555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 94 | VI6_FMT_BGRA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 95 | VI6_RPF_DSWAP_P_WDS, | ||
| 96 | 1, { 16, 0, 0 }, false, false, 1, 1, true }, | ||
| 97 | { V4L2_PIX_FMT_BGRX555, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 98 | VI6_FMT_BGRA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 99 | VI6_RPF_DSWAP_P_WDS, | ||
| 100 | 1, { 16, 0, 0 }, false, false, 1, 1, false }, | ||
| 53 | { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32, | 101 | { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32, |
| 54 | VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | 102 | VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | |
| 55 | VI6_RPF_DSWAP_P_WDS, | 103 | VI6_RPF_DSWAP_P_WDS, |
| @@ -68,6 +116,20 @@ static const struct vsp1_format_info vsp1_video_formats[] = { | |||
| 68 | { V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32, | 116 | { V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32, |
| 69 | VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, | 117 | VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, |
| 70 | 1, { 32, 0, 0 }, false, false, 1, 1, false }, | 118 | 1, { 32, 0, 0 }, false, false, 1, 1, false }, |
| 119 | { V4L2_PIX_FMT_BGRA32, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 120 | VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, | ||
| 121 | 1, { 32, 0, 0 }, false, false, 1, 1, true }, | ||
| 122 | { V4L2_PIX_FMT_BGRX32, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 123 | VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, | ||
| 124 | 1, { 32, 0, 0 }, false, false, 1, 1, false }, | ||
| 125 | { V4L2_PIX_FMT_RGBA32, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 126 | VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 127 | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, | ||
| 128 | 1, { 32, 0, 0 }, false, false, 1, 1, true }, | ||
| 129 | { V4L2_PIX_FMT_RGBX32, MEDIA_BUS_FMT_ARGB8888_1X32, | ||
| 130 | VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | ||
| 131 | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, | ||
| 132 | 1, { 32, 0, 0 }, false, false, 1, 1, false }, | ||
| 71 | { V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32, | 133 | { V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32, |
| 72 | VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | | 134 | VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | |
| 73 | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, | 135 | VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, |
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig index 74ec8aaa5ae0..a2773ad7c185 100644 --- a/drivers/media/platform/xilinx/Kconfig +++ b/drivers/media/platform/xilinx/Kconfig | |||
| @@ -5,7 +5,7 @@ config VIDEO_XILINX | |||
| 5 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA | 5 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA |
| 6 | select VIDEOBUF2_DMA_CONTIG | 6 | select VIDEOBUF2_DMA_CONTIG |
| 7 | select V4L2_FWNODE | 7 | select V4L2_FWNODE |
| 8 | ---help--- | 8 | help |
| 9 | Driver for Xilinx Video IP Pipelines | 9 | Driver for Xilinx Video IP Pipelines |
| 10 | 10 | ||
| 11 | if VIDEO_XILINX | 11 | if VIDEO_XILINX |
| @@ -14,13 +14,13 @@ config VIDEO_XILINX_TPG | |||
| 14 | tristate "Xilinx Video Test Pattern Generator" | 14 | tristate "Xilinx Video Test Pattern Generator" |
| 15 | depends on VIDEO_XILINX | 15 | depends on VIDEO_XILINX |
| 16 | select VIDEO_XILINX_VTC | 16 | select VIDEO_XILINX_VTC |
| 17 | ---help--- | 17 | help |
| 18 | Driver for the Xilinx Video Test Pattern Generator | 18 | Driver for the Xilinx Video Test Pattern Generator |
| 19 | 19 | ||
| 20 | config VIDEO_XILINX_VTC | 20 | config VIDEO_XILINX_VTC |
| 21 | tristate "Xilinx Video Timing Controller" | 21 | tristate "Xilinx Video Timing Controller" |
| 22 | depends on VIDEO_XILINX | 22 | depends on VIDEO_XILINX |
| 23 | ---help--- | 23 | help |
| 24 | Driver for the Xilinx Video Timing Controller | 24 | Driver for the Xilinx Video Timing Controller |
| 25 | 25 | ||
| 26 | endif #VIDEO_XILINX | 26 | endif #VIDEO_XILINX |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 9b99dfb2d0c6..9cd00f64af32 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
| @@ -7,7 +7,7 @@ menuconfig RADIO_ADAPTERS | |||
| 7 | depends on VIDEO_V4L2 | 7 | depends on VIDEO_V4L2 |
| 8 | depends on MEDIA_RADIO_SUPPORT | 8 | depends on MEDIA_RADIO_SUPPORT |
| 9 | default y | 9 | default y |
| 10 | ---help--- | 10 | help |
| 11 | Say Y here to enable selecting AM/FM radio adapters. | 11 | Say Y here to enable selecting AM/FM radio adapters. |
| 12 | 12 | ||
| 13 | if RADIO_ADAPTERS && VIDEO_V4L2 | 13 | if RADIO_ADAPTERS && VIDEO_V4L2 |
| @@ -29,7 +29,7 @@ config RADIO_SI476X | |||
| 29 | depends on MFD_SI476X_CORE | 29 | depends on MFD_SI476X_CORE |
| 30 | depends on SND_SOC | 30 | depends on SND_SOC |
| 31 | select SND_SOC_SI476X | 31 | select SND_SOC_SI476X |
| 32 | ---help--- | 32 | help |
| 33 | Choose Y here if you have this FM radio chip. | 33 | Choose Y here if you have this FM radio chip. |
| 34 | 34 | ||
| 35 | In order to control your radio card, you will need to use programs | 35 | In order to control your radio card, you will need to use programs |
| @@ -43,7 +43,7 @@ config RADIO_SI476X | |||
| 43 | config USB_MR800 | 43 | config USB_MR800 |
| 44 | tristate "AverMedia MR 800 USB FM radio support" | 44 | tristate "AverMedia MR 800 USB FM radio support" |
| 45 | depends on USB && VIDEO_V4L2 | 45 | depends on USB && VIDEO_V4L2 |
| 46 | ---help--- | 46 | help |
| 47 | Say Y here if you want to connect this type of radio to your | 47 | Say Y here if you want to connect this type of radio to your |
| 48 | computer's USB port. Note that the audio is not digital, and | 48 | computer's USB port. Note that the audio is not digital, and |
| 49 | you must connect the line out connector to a sound card or a | 49 | you must connect the line out connector to a sound card or a |
| @@ -55,7 +55,7 @@ config USB_MR800 | |||
| 55 | config USB_DSBR | 55 | config USB_DSBR |
| 56 | tristate "D-Link/GemTek USB FM radio support" | 56 | tristate "D-Link/GemTek USB FM radio support" |
| 57 | depends on USB && VIDEO_V4L2 | 57 | depends on USB && VIDEO_V4L2 |
| 58 | ---help--- | 58 | help |
| 59 | Say Y here if you want to connect this type of radio to your | 59 | Say Y here if you want to connect this type of radio to your |
| 60 | computer's USB port. Note that the audio is not digital, and | 60 | computer's USB port. Note that the audio is not digital, and |
| 61 | you must connect the line out connector to a sound card or a | 61 | you must connect the line out connector to a sound card or a |
| @@ -68,7 +68,7 @@ config RADIO_MAXIRADIO | |||
| 68 | tristate "Guillemot MAXI Radio FM 2000 radio" | 68 | tristate "Guillemot MAXI Radio FM 2000 radio" |
| 69 | depends on VIDEO_V4L2 && PCI | 69 | depends on VIDEO_V4L2 && PCI |
| 70 | select RADIO_TEA575X | 70 | select RADIO_TEA575X |
| 71 | ---help--- | 71 | help |
| 72 | Choose Y here if you have this radio card. This card may also be | 72 | Choose Y here if you have this radio card. This card may also be |
| 73 | found as Gemtek PCI FM. | 73 | found as Gemtek PCI FM. |
| 74 | 74 | ||
| @@ -84,7 +84,7 @@ config RADIO_SHARK | |||
| 84 | tristate "Griffin radioSHARK USB radio receiver" | 84 | tristate "Griffin radioSHARK USB radio receiver" |
| 85 | depends on USB | 85 | depends on USB |
| 86 | select RADIO_TEA575X | 86 | select RADIO_TEA575X |
| 87 | ---help--- | 87 | help |
| 88 | Choose Y here if you have this radio receiver. | 88 | Choose Y here if you have this radio receiver. |
| 89 | 89 | ||
| 90 | There are 2 versions of this device, this driver is for version 1, | 90 | There are 2 versions of this device, this driver is for version 1, |
| @@ -101,7 +101,7 @@ config RADIO_SHARK | |||
| 101 | config RADIO_SHARK2 | 101 | config RADIO_SHARK2 |
| 102 | tristate "Griffin radioSHARK2 USB radio receiver" | 102 | tristate "Griffin radioSHARK2 USB radio receiver" |
| 103 | depends on USB | 103 | depends on USB |
| 104 | ---help--- | 104 | help |
| 105 | Choose Y here if you have this radio receiver. | 105 | Choose Y here if you have this radio receiver. |
| 106 | 106 | ||
| 107 | There are 2 versions of this device, this driver is for version 2, | 107 | There are 2 versions of this device, this driver is for version 2, |
| @@ -118,7 +118,7 @@ config RADIO_SHARK2 | |||
| 118 | config USB_KEENE | 118 | config USB_KEENE |
| 119 | tristate "Keene FM Transmitter USB support" | 119 | tristate "Keene FM Transmitter USB support" |
| 120 | depends on USB && VIDEO_V4L2 | 120 | depends on USB && VIDEO_V4L2 |
| 121 | ---help--- | 121 | help |
| 122 | Say Y here if you want to connect this type of FM transmitter | 122 | Say Y here if you want to connect this type of FM transmitter |
| 123 | to your computer's USB port. | 123 | to your computer's USB port. |
| 124 | 124 | ||
| @@ -128,7 +128,7 @@ config USB_KEENE | |||
| 128 | config USB_RAREMONO | 128 | config USB_RAREMONO |
| 129 | tristate "Thanko's Raremono AM/FM/SW radio support" | 129 | tristate "Thanko's Raremono AM/FM/SW radio support" |
| 130 | depends on USB && VIDEO_V4L2 | 130 | depends on USB && VIDEO_V4L2 |
| 131 | ---help--- | 131 | help |
| 132 | The 'Thanko's Raremono' device contains the Si4734 chip from Silicon Labs Inc. | 132 | The 'Thanko's Raremono' device contains the Si4734 chip from Silicon Labs Inc. |
| 133 | It is one of the very few or perhaps the only consumer USB radio device | 133 | It is one of the very few or perhaps the only consumer USB radio device |
| 134 | to receive the AM/FM/SW bands. | 134 | to receive the AM/FM/SW bands. |
| @@ -142,7 +142,7 @@ config USB_RAREMONO | |||
| 142 | config USB_MA901 | 142 | config USB_MA901 |
| 143 | tristate "Masterkit MA901 USB FM radio support" | 143 | tristate "Masterkit MA901 USB FM radio support" |
| 144 | depends on USB && VIDEO_V4L2 | 144 | depends on USB && VIDEO_V4L2 |
| 145 | ---help--- | 145 | help |
| 146 | Say Y here if you want to connect this type of radio to your | 146 | Say Y here if you want to connect this type of radio to your |
| 147 | computer's USB port. Note that the audio is not digital, and | 147 | computer's USB port. Note that the audio is not digital, and |
| 148 | you must connect the line out connector to a sound card or a | 148 | you must connect the line out connector to a sound card or a |
| @@ -154,7 +154,7 @@ config USB_MA901 | |||
| 154 | config RADIO_TEA5764 | 154 | config RADIO_TEA5764 |
| 155 | tristate "TEA5764 I2C FM radio support" | 155 | tristate "TEA5764 I2C FM radio support" |
| 156 | depends on I2C && VIDEO_V4L2 | 156 | depends on I2C && VIDEO_V4L2 |
| 157 | ---help--- | 157 | help |
| 158 | Say Y here if you want to use the TEA5764 FM chip found in | 158 | Say Y here if you want to use the TEA5764 FM chip found in |
| 159 | EZX phones. This FM chip is present in EZX phones from Motorola, | 159 | EZX phones. This FM chip is present in EZX phones from Motorola, |
| 160 | connected to internal pxa I2C bus. | 160 | connected to internal pxa I2C bus. |
| @@ -173,7 +173,7 @@ config RADIO_TEA5764_XTAL | |||
| 173 | config RADIO_SAA7706H | 173 | config RADIO_SAA7706H |
| 174 | tristate "SAA7706H Car Radio DSP" | 174 | tristate "SAA7706H Car Radio DSP" |
| 175 | depends on I2C && VIDEO_V4L2 | 175 | depends on I2C && VIDEO_V4L2 |
| 176 | ---help--- | 176 | help |
| 177 | Say Y here if you want to use the SAA7706H Car radio Digital | 177 | Say Y here if you want to use the SAA7706H Car radio Digital |
| 178 | Signal Processor, found for instance on the Russellville development | 178 | Signal Processor, found for instance on the Russellville development |
| 179 | board. On the russellville the device is connected to internal | 179 | board. On the russellville the device is connected to internal |
| @@ -185,7 +185,7 @@ config RADIO_SAA7706H | |||
| 185 | config RADIO_TEF6862 | 185 | config RADIO_TEF6862 |
| 186 | tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" | 186 | tristate "TEF6862 Car Radio Enhanced Selectivity Tuner" |
| 187 | depends on I2C && VIDEO_V4L2 | 187 | depends on I2C && VIDEO_V4L2 |
| 188 | ---help--- | 188 | help |
| 189 | Say Y here if you want to use the TEF6862 Car Radio Enhanced | 189 | Say Y here if you want to use the TEF6862 Car Radio Enhanced |
| 190 | Selectivity Tuner, found for instance on the Russellville development | 190 | Selectivity Tuner, found for instance on the Russellville development |
| 191 | board. On the russellville the device is connected to internal | 191 | board. On the russellville the device is connected to internal |
| @@ -200,7 +200,7 @@ config RADIO_TIMBERDALE | |||
| 200 | depends on I2C # for RADIO_SAA7706H | 200 | depends on I2C # for RADIO_SAA7706H |
| 201 | select RADIO_TEF6862 | 201 | select RADIO_TEF6862 |
| 202 | select RADIO_SAA7706H | 202 | select RADIO_SAA7706H |
| 203 | ---help--- | 203 | help |
| 204 | This is a kind of umbrella driver for the Radio Tuner and DSP | 204 | This is a kind of umbrella driver for the Radio Tuner and DSP |
| 205 | found behind the Timberdale FPGA on the Russellville board. | 205 | found behind the Timberdale FPGA on the Russellville board. |
| 206 | Enabling this driver will automatically select the DSP and tuner. | 206 | Enabling this driver will automatically select the DSP and tuner. |
| @@ -211,7 +211,7 @@ config RADIO_WL1273 | |||
| 211 | select MFD_CORE | 211 | select MFD_CORE |
| 212 | select MFD_WL1273_CORE | 212 | select MFD_WL1273_CORE |
| 213 | select FW_LOADER | 213 | select FW_LOADER |
| 214 | ---help--- | 214 | help |
| 215 | Choose Y here if you have this FM radio chip. | 215 | Choose Y here if you have this FM radio chip. |
| 216 | 216 | ||
| 217 | In order to control your radio card, you will need to use programs | 217 | In order to control your radio card, you will need to use programs |
| @@ -233,7 +233,7 @@ menuconfig V4L_RADIO_ISA_DRIVERS | |||
| 233 | bool "ISA radio devices" | 233 | bool "ISA radio devices" |
| 234 | depends on ISA || COMPILE_TEST | 234 | depends on ISA || COMPILE_TEST |
| 235 | default n | 235 | default n |
| 236 | ---help--- | 236 | help |
| 237 | Say Y here to enable support for these ISA drivers. | 237 | Say Y here to enable support for these ISA drivers. |
| 238 | 238 | ||
| 239 | if V4L_RADIO_ISA_DRIVERS | 239 | if V4L_RADIO_ISA_DRIVERS |
| @@ -246,7 +246,7 @@ config RADIO_CADET | |||
| 246 | tristate "ADS Cadet AM/FM Tuner" | 246 | tristate "ADS Cadet AM/FM Tuner" |
| 247 | depends on ISA || COMPILE_TEST | 247 | depends on ISA || COMPILE_TEST |
| 248 | depends on VIDEO_V4L2 | 248 | depends on VIDEO_V4L2 |
| 249 | ---help--- | 249 | help |
| 250 | Choose Y here if you have one of these AM/FM radio cards, and then | 250 | Choose Y here if you have one of these AM/FM radio cards, and then |
| 251 | fill in the port address below. | 251 | fill in the port address below. |
| 252 | 252 | ||
| @@ -258,7 +258,7 @@ config RADIO_RTRACK | |||
| 258 | depends on ISA || COMPILE_TEST | 258 | depends on ISA || COMPILE_TEST |
| 259 | depends on VIDEO_V4L2 | 259 | depends on VIDEO_V4L2 |
| 260 | select RADIO_ISA | 260 | select RADIO_ISA |
| 261 | ---help--- | 261 | help |
| 262 | Choose Y here if you have one of these FM radio cards, and then fill | 262 | Choose Y here if you have one of these FM radio cards, and then fill |
| 263 | in the port address below. | 263 | in the port address below. |
| 264 | 264 | ||
| @@ -290,7 +290,7 @@ config RADIO_RTRACK2 | |||
| 290 | depends on ISA || COMPILE_TEST | 290 | depends on ISA || COMPILE_TEST |
| 291 | depends on VIDEO_V4L2 | 291 | depends on VIDEO_V4L2 |
| 292 | select RADIO_ISA | 292 | select RADIO_ISA |
| 293 | ---help--- | 293 | help |
| 294 | Choose Y here if you have this FM radio card, and then fill in the | 294 | Choose Y here if you have this FM radio card, and then fill in the |
| 295 | port address below. | 295 | port address below. |
| 296 | 296 | ||
| @@ -314,7 +314,7 @@ config RADIO_AZTECH | |||
| 314 | depends on ISA || COMPILE_TEST | 314 | depends on ISA || COMPILE_TEST |
| 315 | depends on VIDEO_V4L2 | 315 | depends on VIDEO_V4L2 |
| 316 | select RADIO_ISA | 316 | select RADIO_ISA |
| 317 | ---help--- | 317 | help |
| 318 | Choose Y here if you have one of these FM radio cards, and then fill | 318 | Choose Y here if you have one of these FM radio cards, and then fill |
| 319 | in the port address below. | 319 | in the port address below. |
| 320 | 320 | ||
| @@ -335,7 +335,7 @@ config RADIO_GEMTEK | |||
| 335 | depends on ISA || COMPILE_TEST | 335 | depends on ISA || COMPILE_TEST |
| 336 | depends on VIDEO_V4L2 | 336 | depends on VIDEO_V4L2 |
| 337 | select RADIO_ISA | 337 | select RADIO_ISA |
| 338 | ---help--- | 338 | help |
| 339 | Choose Y here if you have this FM radio card, and then fill in the | 339 | Choose Y here if you have this FM radio card, and then fill in the |
| 340 | I/O port address and settings below. The following cards either have | 340 | I/O port address and settings below. The following cards either have |
| 341 | GemTek Radio tuner or are rebranded GemTek Radio cards: | 341 | GemTek Radio tuner or are rebranded GemTek Radio cards: |
| @@ -377,7 +377,7 @@ config RADIO_MIROPCM20 | |||
| 377 | depends on ISA_DMA_API && VIDEO_V4L2 && SND | 377 | depends on ISA_DMA_API && VIDEO_V4L2 && SND |
| 378 | select SND_ISA | 378 | select SND_ISA |
| 379 | select SND_MIRO | 379 | select SND_MIRO |
| 380 | ---help--- | 380 | help |
| 381 | Choose Y here if you have this FM radio card. You also need to enable | 381 | Choose Y here if you have this FM radio card. You also need to enable |
| 382 | the ALSA sound system. This choice automatically selects the ALSA | 382 | the ALSA sound system. This choice automatically selects the ALSA |
| 383 | sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this | 383 | sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this |
| @@ -390,7 +390,7 @@ config RADIO_SF16FMI | |||
| 390 | tristate "SF16-FMI/SF16-FMP/SF16-FMD Radio" | 390 | tristate "SF16-FMI/SF16-FMP/SF16-FMD Radio" |
| 391 | depends on ISA || COMPILE_TEST | 391 | depends on ISA || COMPILE_TEST |
| 392 | depends on VIDEO_V4L2 | 392 | depends on VIDEO_V4L2 |
| 393 | ---help--- | 393 | help |
| 394 | Choose Y here if you have one of these FM radio cards. | 394 | Choose Y here if you have one of these FM radio cards. |
| 395 | 395 | ||
| 396 | To compile this driver as a module, choose M here: the | 396 | To compile this driver as a module, choose M here: the |
| @@ -401,7 +401,7 @@ config RADIO_SF16FMR2 | |||
| 401 | depends on ISA || COMPILE_TEST | 401 | depends on ISA || COMPILE_TEST |
| 402 | depends on VIDEO_V4L2 | 402 | depends on VIDEO_V4L2 |
| 403 | select RADIO_TEA575X | 403 | select RADIO_TEA575X |
| 404 | ---help--- | 404 | help |
| 405 | Choose Y here if you have one of these FM radio cards. | 405 | Choose Y here if you have one of these FM radio cards. |
| 406 | 406 | ||
| 407 | To compile this driver as a module, choose M here: the | 407 | To compile this driver as a module, choose M here: the |
| @@ -412,7 +412,7 @@ config RADIO_TERRATEC | |||
| 412 | depends on ISA || COMPILE_TEST | 412 | depends on ISA || COMPILE_TEST |
| 413 | depends on VIDEO_V4L2 | 413 | depends on VIDEO_V4L2 |
| 414 | select RADIO_ISA | 414 | select RADIO_ISA |
| 415 | ---help--- | 415 | help |
| 416 | Choose Y here if you have this FM radio card. | 416 | Choose Y here if you have this FM radio card. |
| 417 | 417 | ||
| 418 | Note: this driver hasn't been tested since a long time due to lack | 418 | Note: this driver hasn't been tested since a long time due to lack |
| @@ -451,7 +451,7 @@ config RADIO_TYPHOON | |||
| 451 | depends on ISA || COMPILE_TEST | 451 | depends on ISA || COMPILE_TEST |
| 452 | depends on VIDEO_V4L2 | 452 | depends on VIDEO_V4L2 |
| 453 | select RADIO_ISA | 453 | select RADIO_ISA |
| 454 | ---help--- | 454 | help |
| 455 | Choose Y here if you have one of these FM radio cards, and then fill | 455 | Choose Y here if you have one of these FM radio cards, and then fill |
| 456 | in the port address and the frequency used for muting below. | 456 | in the port address and the frequency used for muting below. |
| 457 | 457 | ||
| @@ -486,7 +486,7 @@ config RADIO_ZOLTRIX | |||
| 486 | depends on ISA || COMPILE_TEST | 486 | depends on ISA || COMPILE_TEST |
| 487 | depends on VIDEO_V4L2 | 487 | depends on VIDEO_V4L2 |
| 488 | select RADIO_ISA | 488 | select RADIO_ISA |
| 489 | ---help--- | 489 | help |
| 490 | Choose Y here if you have one of these FM radio cards, and then fill | 490 | Choose Y here if you have one of these FM radio cards, and then fill |
| 491 | in the port address below. | 491 | in the port address below. |
| 492 | 492 | ||
diff --git a/drivers/media/radio/si470x/Kconfig b/drivers/media/radio/si470x/Kconfig index 6dbb158cd2a0..21026488de90 100644 --- a/drivers/media/radio/si470x/Kconfig +++ b/drivers/media/radio/si470x/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config RADIO_SI470X | 1 | config RADIO_SI470X |
| 2 | tristate "Silicon Labs Si470x FM Radio Receiver support" | 2 | tristate "Silicon Labs Si470x FM Radio Receiver support" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | ---help--- | 4 | help |
| 5 | This is a driver for devices with the Silicon Labs SI470x | 5 | This is a driver for devices with the Silicon Labs SI470x |
| 6 | chip (either via USB or I2C buses). | 6 | chip (either via USB or I2C buses). |
| 7 | 7 | ||
| @@ -15,7 +15,7 @@ config RADIO_SI470X | |||
| 15 | config USB_SI470X | 15 | config USB_SI470X |
| 16 | tristate "Silicon Labs Si470x FM Radio Receiver support with USB" | 16 | tristate "Silicon Labs Si470x FM Radio Receiver support with USB" |
| 17 | depends on USB && RADIO_SI470X | 17 | depends on USB && RADIO_SI470X |
| 18 | ---help--- | 18 | help |
| 19 | This is a driver for USB devices with the Silicon Labs SI470x | 19 | This is a driver for USB devices with the Silicon Labs SI470x |
| 20 | chip. Currently these devices are known to work: | 20 | chip. Currently these devices are known to work: |
| 21 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design | 21 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design |
| @@ -40,7 +40,7 @@ config USB_SI470X | |||
| 40 | config I2C_SI470X | 40 | config I2C_SI470X |
| 41 | tristate "Silicon Labs Si470x FM Radio Receiver support with I2C" | 41 | tristate "Silicon Labs Si470x FM Radio Receiver support with I2C" |
| 42 | depends on I2C && RADIO_SI470X | 42 | depends on I2C && RADIO_SI470X |
| 43 | ---help--- | 43 | help |
| 44 | This is a driver for I2C devices with the Silicon Labs SI470x | 44 | This is a driver for I2C devices with the Silicon Labs SI470x |
| 45 | chip. | 45 | chip. |
| 46 | 46 | ||
diff --git a/drivers/media/radio/si4713/Kconfig b/drivers/media/radio/si4713/Kconfig index 9c8b887cff75..17567c917554 100644 --- a/drivers/media/radio/si4713/Kconfig +++ b/drivers/media/radio/si4713/Kconfig | |||
| @@ -2,7 +2,7 @@ config USB_SI4713 | |||
| 2 | tristate "Silicon Labs Si4713 FM Radio Transmitter support with USB" | 2 | tristate "Silicon Labs Si4713 FM Radio Transmitter support with USB" |
| 3 | depends on USB && I2C && RADIO_SI4713 | 3 | depends on USB && I2C && RADIO_SI4713 |
| 4 | select I2C_SI4713 | 4 | select I2C_SI4713 |
| 5 | ---help--- | 5 | help |
| 6 | This is a driver for USB devices with the Silicon Labs SI4713 | 6 | This is a driver for USB devices with the Silicon Labs SI4713 |
| 7 | chip. Currently these devices are known to work. | 7 | chip. Currently these devices are known to work. |
| 8 | - 10c4:8244: Silicon Labs FM Transmitter USB device. | 8 | - 10c4:8244: Silicon Labs FM Transmitter USB device. |
| @@ -17,7 +17,7 @@ config PLATFORM_SI4713 | |||
| 17 | tristate "Silicon Labs Si4713 FM Radio Transmitter support with I2C" | 17 | tristate "Silicon Labs Si4713 FM Radio Transmitter support with I2C" |
| 18 | depends on I2C && RADIO_SI4713 | 18 | depends on I2C && RADIO_SI4713 |
| 19 | select I2C_SI4713 | 19 | select I2C_SI4713 |
| 20 | ---help--- | 20 | help |
| 21 | This is a driver for I2C devices with the Silicon Labs SI4713 | 21 | This is a driver for I2C devices with the Silicon Labs SI4713 |
| 22 | chip. | 22 | chip. |
| 23 | 23 | ||
| @@ -30,7 +30,7 @@ config PLATFORM_SI4713 | |||
| 30 | config I2C_SI4713 | 30 | config I2C_SI4713 |
| 31 | tristate "Silicon Labs Si4713 FM Radio Transmitter support" | 31 | tristate "Silicon Labs Si4713 FM Radio Transmitter support" |
| 32 | depends on I2C && RADIO_SI4713 | 32 | depends on I2C && RADIO_SI4713 |
| 33 | ---help--- | 33 | help |
| 34 | Say Y here if you want support to Si4713 FM Radio Transmitter. | 34 | Say Y here if you want support to Si4713 FM Radio Transmitter. |
| 35 | This device can transmit audio through FM. It can transmit | 35 | This device can transmit audio through FM. It can transmit |
| 36 | RDS and RBDS signals as well. This module is the v4l2 radio | 36 | RDS and RBDS signals as well. This module is the v4l2 radio |
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c index f4a53f1e856e..a8584371a32d 100644 --- a/drivers/media/radio/si4713/si4713.c +++ b/drivers/media/radio/si4713/si4713.c | |||
| @@ -1272,7 +1272,7 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm) | |||
| 1272 | if (vm->index > 0) | 1272 | if (vm->index > 0) |
| 1273 | return -EINVAL; | 1273 | return -EINVAL; |
| 1274 | 1274 | ||
| 1275 | strncpy(vm->name, "FM Modulator", 32); | 1275 | strscpy(vm->name, "FM Modulator", sizeof(vm->name)); |
| 1276 | vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | | 1276 | vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW | |
| 1277 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS; | 1277 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS; |
| 1278 | 1278 | ||
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 3c8987af3772..053d51a5890a 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c | |||
| @@ -489,7 +489,8 @@ int fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload, | |||
| 489 | return -EIO; | 489 | return -EIO; |
| 490 | } | 490 | } |
| 491 | /* Send response data to caller */ | 491 | /* Send response data to caller */ |
| 492 | if (response != NULL && response_len != NULL && evt_hdr->dlen) { | 492 | if (response != NULL && response_len != NULL && evt_hdr->dlen && |
| 493 | evt_hdr->dlen <= payload_len) { | ||
| 493 | /* Skip header info and copy only response data */ | 494 | /* Skip header info and copy only response data */ |
| 494 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); | 495 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); |
| 495 | memcpy(response, skb->data, evt_hdr->dlen); | 496 | memcpy(response, skb->data, evt_hdr->dlen); |
| @@ -583,6 +584,8 @@ static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev) | |||
| 583 | return; | 584 | return; |
| 584 | 585 | ||
| 585 | fm_evt_hdr = (void *)skb->data; | 586 | fm_evt_hdr = (void *)skb->data; |
| 587 | if (fm_evt_hdr->dlen > sizeof(fmdev->irq_info.flag)) | ||
| 588 | return; | ||
| 586 | 589 | ||
| 587 | /* Skip header info and copy only response data */ | 590 | /* Skip header info and copy only response data */ |
| 588 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); | 591 | skb_pull(skb, sizeof(struct fm_event_msg_hdr)); |
| @@ -1268,8 +1271,9 @@ static int fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name) | |||
| 1268 | 1271 | ||
| 1269 | switch (action->type) { | 1272 | switch (action->type) { |
| 1270 | case ACTION_SEND_COMMAND: /* Send */ | 1273 | case ACTION_SEND_COMMAND: /* Send */ |
| 1271 | if (fmc_send_cmd(fmdev, 0, 0, action->data, | 1274 | ret = fmc_send_cmd(fmdev, 0, 0, action->data, |
| 1272 | action->size, NULL, NULL)) | 1275 | action->size, NULL, NULL); |
| 1276 | if (ret) | ||
| 1273 | goto rel_fw; | 1277 | goto rel_fw; |
| 1274 | 1278 | ||
| 1275 | cmd_cnt++; | 1279 | cmd_cnt++; |
| @@ -1308,7 +1312,7 @@ static int load_default_rx_configuration(struct fmdev *fmdev) | |||
| 1308 | static int fm_power_up(struct fmdev *fmdev, u8 mode) | 1312 | static int fm_power_up(struct fmdev *fmdev, u8 mode) |
| 1309 | { | 1313 | { |
| 1310 | u16 payload; | 1314 | u16 payload; |
| 1311 | __be16 asic_id, asic_ver; | 1315 | __be16 asic_id = 0, asic_ver = 0; |
| 1312 | int resp_len, ret; | 1316 | int resp_len, ret; |
| 1313 | u8 fw_name[50]; | 1317 | u8 fw_name[50]; |
| 1314 | 1318 | ||
| @@ -1520,7 +1524,7 @@ int fmc_prepare(struct fmdev *fmdev) | |||
| 1520 | } | 1524 | } |
| 1521 | 1525 | ||
| 1522 | ret = 0; | 1526 | ret = 0; |
| 1523 | } else if (ret == -1) { | 1527 | } else if (ret < 0) { |
| 1524 | fmerr("st_register failed %d\n", ret); | 1528 | fmerr("st_register failed %d\n", ret); |
| 1525 | return -EAGAIN; | 1529 | return -EAGAIN; |
| 1526 | } | 1530 | } |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 96ce3e5524e0..3fc6ac15c66d 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | menuconfig RC_CORE | 2 | menuconfig RC_CORE |
| 3 | tristate "Remote Controller support" | 3 | tristate "Remote Controller support" |
| 4 | depends on INPUT | 4 | depends on INPUT |
| 5 | ---help--- | 5 | help |
| 6 | Enable support for Remote Controllers on Linux. This is | 6 | Enable support for Remote Controllers on Linux. This is |
| 7 | needed in order to support several video capture adapters, | 7 | needed in order to support several video capture adapters, |
| 8 | standalone IR receivers/transmitters, and RF receivers. | 8 | standalone IR receivers/transmitters, and RF receivers. |
| @@ -19,7 +19,7 @@ source "drivers/media/rc/keymaps/Kconfig" | |||
| 19 | config LIRC | 19 | config LIRC |
| 20 | bool "LIRC user interface" | 20 | bool "LIRC user interface" |
| 21 | depends on RC_CORE | 21 | depends on RC_CORE |
| 22 | ---help--- | 22 | help |
| 23 | Enable this option to enable the Linux Infrared Remote | 23 | Enable this option to enable the Linux Infrared Remote |
| 24 | Control user interface (e.g. /dev/lirc*). This interface | 24 | Control user interface (e.g. /dev/lirc*). This interface |
| 25 | passes raw IR to and from userspace, which is needed for | 25 | passes raw IR to and from userspace, which is needed for |
| @@ -48,7 +48,7 @@ config IR_NEC_DECODER | |||
| 48 | depends on RC_CORE | 48 | depends on RC_CORE |
| 49 | select BITREVERSE | 49 | select BITREVERSE |
| 50 | 50 | ||
| 51 | ---help--- | 51 | help |
| 52 | Enable this option if you have IR with NEC protocol, and | 52 | Enable this option if you have IR with NEC protocol, and |
| 53 | if the IR is decoded in software | 53 | if the IR is decoded in software |
| 54 | 54 | ||
| @@ -57,7 +57,7 @@ config IR_RC5_DECODER | |||
| 57 | depends on RC_CORE | 57 | depends on RC_CORE |
| 58 | select BITREVERSE | 58 | select BITREVERSE |
| 59 | 59 | ||
| 60 | ---help--- | 60 | help |
| 61 | Enable this option if you have IR with RC-5 protocol, and | 61 | Enable this option if you have IR with RC-5 protocol, and |
| 62 | if the IR is decoded in software | 62 | if the IR is decoded in software |
| 63 | 63 | ||
| @@ -66,7 +66,7 @@ config IR_RC6_DECODER | |||
| 66 | depends on RC_CORE | 66 | depends on RC_CORE |
| 67 | select BITREVERSE | 67 | select BITREVERSE |
| 68 | 68 | ||
| 69 | ---help--- | 69 | help |
| 70 | Enable this option if you have an infrared remote control which | 70 | Enable this option if you have an infrared remote control which |
| 71 | uses the RC6 protocol, and you need software decoding support. | 71 | uses the RC6 protocol, and you need software decoding support. |
| 72 | 72 | ||
| @@ -75,7 +75,7 @@ config IR_JVC_DECODER | |||
| 75 | depends on RC_CORE | 75 | depends on RC_CORE |
| 76 | select BITREVERSE | 76 | select BITREVERSE |
| 77 | 77 | ||
| 78 | ---help--- | 78 | help |
| 79 | Enable this option if you have an infrared remote control which | 79 | Enable this option if you have an infrared remote control which |
| 80 | uses the JVC protocol, and you need software decoding support. | 80 | uses the JVC protocol, and you need software decoding support. |
| 81 | 81 | ||
| @@ -84,7 +84,7 @@ config IR_SONY_DECODER | |||
| 84 | depends on RC_CORE | 84 | depends on RC_CORE |
| 85 | select BITREVERSE | 85 | select BITREVERSE |
| 86 | 86 | ||
| 87 | ---help--- | 87 | help |
| 88 | Enable this option if you have an infrared remote control which | 88 | Enable this option if you have an infrared remote control which |
| 89 | uses the Sony protocol, and you need software decoding support. | 89 | uses the Sony protocol, and you need software decoding support. |
| 90 | 90 | ||
| @@ -92,7 +92,7 @@ config IR_SANYO_DECODER | |||
| 92 | tristate "Enable IR raw decoder for the Sanyo protocol" | 92 | tristate "Enable IR raw decoder for the Sanyo protocol" |
| 93 | depends on RC_CORE | 93 | depends on RC_CORE |
| 94 | 94 | ||
| 95 | ---help--- | 95 | help |
| 96 | Enable this option if you have an infrared remote control which | 96 | Enable this option if you have an infrared remote control which |
| 97 | uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes), | 97 | uses the Sanyo protocol (Sanyo, Aiwa, Chinon remotes), |
| 98 | and you need software decoding support. | 98 | and you need software decoding support. |
| @@ -101,7 +101,7 @@ config IR_SHARP_DECODER | |||
| 101 | tristate "Enable IR raw decoder for the Sharp protocol" | 101 | tristate "Enable IR raw decoder for the Sharp protocol" |
| 102 | depends on RC_CORE | 102 | depends on RC_CORE |
| 103 | 103 | ||
| 104 | ---help--- | 104 | help |
| 105 | Enable this option if you have an infrared remote control which | 105 | Enable this option if you have an infrared remote control which |
| 106 | uses the Sharp protocol (Sharp, Denon), and you need software | 106 | uses the Sharp protocol (Sharp, Denon), and you need software |
| 107 | decoding support. | 107 | decoding support. |
| @@ -111,7 +111,7 @@ config IR_MCE_KBD_DECODER | |||
| 111 | depends on RC_CORE | 111 | depends on RC_CORE |
| 112 | select BITREVERSE | 112 | select BITREVERSE |
| 113 | 113 | ||
| 114 | ---help--- | 114 | help |
| 115 | Enable this option if you have a Microsoft Remote Keyboard for | 115 | Enable this option if you have a Microsoft Remote Keyboard for |
| 116 | Windows Media Center Edition, which you would like to use with | 116 | Windows Media Center Edition, which you would like to use with |
| 117 | a raw IR receiver in your system. | 117 | a raw IR receiver in your system. |
| @@ -121,14 +121,14 @@ config IR_XMP_DECODER | |||
| 121 | depends on RC_CORE | 121 | depends on RC_CORE |
| 122 | select BITREVERSE | 122 | select BITREVERSE |
| 123 | 123 | ||
| 124 | ---help--- | 124 | help |
| 125 | Enable this option if you have IR with XMP protocol, and | 125 | Enable this option if you have IR with XMP protocol, and |
| 126 | if the IR is decoded in software | 126 | if the IR is decoded in software |
| 127 | 127 | ||
| 128 | config IR_IMON_DECODER | 128 | config IR_IMON_DECODER |
| 129 | tristate "Enable IR raw decoder for the iMON protocol" | 129 | tristate "Enable IR raw decoder for the iMON protocol" |
| 130 | depends on RC_CORE | 130 | depends on RC_CORE |
| 131 | ---help--- | 131 | help |
| 132 | Enable this option if you have iMON PAD or Antec Veris infrared | 132 | Enable this option if you have iMON PAD or Antec Veris infrared |
| 133 | remote control and you would like to use it with a raw IR | 133 | remote control and you would like to use it with a raw IR |
| 134 | receiver, or if you wish to use an encoder to transmit this IR. | 134 | receiver, or if you wish to use an encoder to transmit this IR. |
| @@ -177,7 +177,7 @@ config IR_ENE | |||
| 177 | tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" | 177 | tristate "ENE eHome Receiver/Transceiver (pnp id: ENE0100/ENE02xxx)" |
| 178 | depends on PNP || COMPILE_TEST | 178 | depends on PNP || COMPILE_TEST |
| 179 | depends on RC_CORE | 179 | depends on RC_CORE |
| 180 | ---help--- | 180 | help |
| 181 | Say Y here to enable support for integrated infrared receiver | 181 | Say Y here to enable support for integrated infrared receiver |
| 182 | /transceiver made by ENE. | 182 | /transceiver made by ENE. |
| 183 | 183 | ||
| @@ -203,7 +203,7 @@ config IR_IMON | |||
| 203 | depends on USB_ARCH_HAS_HCD | 203 | depends on USB_ARCH_HAS_HCD |
| 204 | depends on RC_CORE | 204 | depends on RC_CORE |
| 205 | select USB | 205 | select USB |
| 206 | ---help--- | 206 | help |
| 207 | Say Y here if you want to use a SoundGraph iMON (aka Antec Veris) | 207 | Say Y here if you want to use a SoundGraph iMON (aka Antec Veris) |
| 208 | IR Receiver and/or LCD/VFD/VGA display. | 208 | IR Receiver and/or LCD/VFD/VGA display. |
| 209 | 209 | ||
| @@ -215,7 +215,7 @@ config IR_IMON_RAW | |||
| 215 | depends on USB_ARCH_HAS_HCD | 215 | depends on USB_ARCH_HAS_HCD |
| 216 | depends on RC_CORE | 216 | depends on RC_CORE |
| 217 | select USB | 217 | select USB |
| 218 | ---help--- | 218 | help |
| 219 | Say Y here if you want to use a SoundGraph iMON IR Receiver, | 219 | Say Y here if you want to use a SoundGraph iMON IR Receiver, |
| 220 | early raw models. | 220 | early raw models. |
| 221 | 221 | ||
| @@ -227,7 +227,7 @@ config IR_MCEUSB | |||
| 227 | depends on USB_ARCH_HAS_HCD | 227 | depends on USB_ARCH_HAS_HCD |
| 228 | depends on RC_CORE | 228 | depends on RC_CORE |
| 229 | select USB | 229 | select USB |
| 230 | ---help--- | 230 | help |
| 231 | Say Y here if you want to use a Windows Media Center Edition | 231 | Say Y here if you want to use a Windows Media Center Edition |
| 232 | eHome Infrared Transceiver. | 232 | eHome Infrared Transceiver. |
| 233 | 233 | ||
| @@ -238,7 +238,7 @@ config IR_ITE_CIR | |||
| 238 | tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver" | 238 | tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver" |
| 239 | depends on PNP || COMPILE_TEST | 239 | depends on PNP || COMPILE_TEST |
| 240 | depends on RC_CORE | 240 | depends on RC_CORE |
| 241 | ---help--- | 241 | help |
| 242 | Say Y here to enable support for integrated infrared receivers | 242 | Say Y here to enable support for integrated infrared receivers |
| 243 | /transceivers made by ITE Tech Inc. These are found in | 243 | /transceivers made by ITE Tech Inc. These are found in |
| 244 | several ASUS devices, like the ASUS Digimatrix or the ASUS | 244 | several ASUS devices, like the ASUS Digimatrix or the ASUS |
| @@ -251,7 +251,7 @@ config IR_FINTEK | |||
| 251 | tristate "Fintek Consumer Infrared Transceiver" | 251 | tristate "Fintek Consumer Infrared Transceiver" |
| 252 | depends on PNP || COMPILE_TEST | 252 | depends on PNP || COMPILE_TEST |
| 253 | depends on RC_CORE | 253 | depends on RC_CORE |
| 254 | ---help--- | 254 | help |
| 255 | Say Y here to enable support for integrated infrared receiver | 255 | Say Y here to enable support for integrated infrared receiver |
| 256 | /transceiver made by Fintek. This chip is found on assorted | 256 | /transceiver made by Fintek. This chip is found on assorted |
| 257 | Jetway motherboards (and of course, possibly others). | 257 | Jetway motherboards (and of course, possibly others). |
| @@ -263,7 +263,7 @@ config IR_MESON | |||
| 263 | tristate "Amlogic Meson IR remote receiver" | 263 | tristate "Amlogic Meson IR remote receiver" |
| 264 | depends on RC_CORE | 264 | depends on RC_CORE |
| 265 | depends on ARCH_MESON || COMPILE_TEST | 265 | depends on ARCH_MESON || COMPILE_TEST |
| 266 | ---help--- | 266 | help |
| 267 | Say Y if you want to use the IR remote receiver available | 267 | Say Y if you want to use the IR remote receiver available |
| 268 | on Amlogic Meson SoCs. | 268 | on Amlogic Meson SoCs. |
| 269 | 269 | ||
| @@ -274,7 +274,7 @@ config IR_MTK | |||
| 274 | tristate "Mediatek IR remote receiver" | 274 | tristate "Mediatek IR remote receiver" |
| 275 | depends on RC_CORE | 275 | depends on RC_CORE |
| 276 | depends on ARCH_MEDIATEK || COMPILE_TEST | 276 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 277 | ---help--- | 277 | help |
| 278 | Say Y if you want to use the IR remote receiver available | 278 | Say Y if you want to use the IR remote receiver available |
| 279 | on Mediatek SoCs. | 279 | on Mediatek SoCs. |
| 280 | 280 | ||
| @@ -285,7 +285,7 @@ config IR_NUVOTON | |||
| 285 | tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" | 285 | tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" |
| 286 | depends on PNP || COMPILE_TEST | 286 | depends on PNP || COMPILE_TEST |
| 287 | depends on RC_CORE | 287 | depends on RC_CORE |
| 288 | ---help--- | 288 | help |
| 289 | Say Y here to enable support for integrated infrared receiver | 289 | Say Y here to enable support for integrated infrared receiver |
| 290 | /transceiver made by Nuvoton (formerly Winbond). This chip is | 290 | /transceiver made by Nuvoton (formerly Winbond). This chip is |
| 291 | found in the ASRock ION 330HT, as well as assorted Intel | 291 | found in the ASRock ION 330HT, as well as assorted Intel |
| @@ -301,7 +301,7 @@ config IR_REDRAT3 | |||
| 301 | select NEW_LEDS | 301 | select NEW_LEDS |
| 302 | select LEDS_CLASS | 302 | select LEDS_CLASS |
| 303 | select USB | 303 | select USB |
| 304 | ---help--- | 304 | help |
| 305 | Say Y here if you want to use a RedRat3 Infrared Transceiver. | 305 | Say Y here if you want to use a RedRat3 Infrared Transceiver. |
| 306 | 306 | ||
| 307 | To compile this driver as a module, choose M here: the | 307 | To compile this driver as a module, choose M here: the |
| @@ -311,7 +311,7 @@ config IR_SPI | |||
| 311 | tristate "SPI connected IR LED" | 311 | tristate "SPI connected IR LED" |
| 312 | depends on SPI && LIRC | 312 | depends on SPI && LIRC |
| 313 | depends on OF || COMPILE_TEST | 313 | depends on OF || COMPILE_TEST |
| 314 | ---help--- | 314 | help |
| 315 | Say Y if you want to use an IR LED connected through SPI bus. | 315 | Say Y if you want to use an IR LED connected through SPI bus. |
| 316 | 316 | ||
| 317 | To compile this driver as a module, choose M here: the module will be | 317 | To compile this driver as a module, choose M here: the module will be |
| @@ -322,7 +322,7 @@ config IR_STREAMZAP | |||
| 322 | depends on USB_ARCH_HAS_HCD | 322 | depends on USB_ARCH_HAS_HCD |
| 323 | depends on RC_CORE | 323 | depends on RC_CORE |
| 324 | select USB | 324 | select USB |
| 325 | ---help--- | 325 | help |
| 326 | Say Y here if you want to use a Streamzap PC Remote | 326 | Say Y here if you want to use a Streamzap PC Remote |
| 327 | Infrared Receiver. | 327 | Infrared Receiver. |
| 328 | 328 | ||
| @@ -336,7 +336,7 @@ config IR_WINBOND_CIR | |||
| 336 | select NEW_LEDS | 336 | select NEW_LEDS |
| 337 | select LEDS_CLASS | 337 | select LEDS_CLASS |
| 338 | select BITREVERSE | 338 | select BITREVERSE |
| 339 | ---help--- | 339 | help |
| 340 | Say Y here if you want to use the IR remote functionality found | 340 | Say Y here if you want to use the IR remote functionality found |
| 341 | in some Winbond SuperI/O chips. Currently only the WPCD376I | 341 | in some Winbond SuperI/O chips. Currently only the WPCD376I |
| 342 | chip is supported (included in some Intel Media series | 342 | chip is supported (included in some Intel Media series |
| @@ -350,7 +350,7 @@ config IR_IGORPLUGUSB | |||
| 350 | depends on USB_ARCH_HAS_HCD | 350 | depends on USB_ARCH_HAS_HCD |
| 351 | depends on RC_CORE | 351 | depends on RC_CORE |
| 352 | select USB | 352 | select USB |
| 353 | ---help--- | 353 | help |
| 354 | Say Y here if you want to use the IgorPlug-USB IR Receiver by | 354 | Say Y here if you want to use the IgorPlug-USB IR Receiver by |
| 355 | Igor Cesko. This device is included on the Fit-PC2. | 355 | Igor Cesko. This device is included on the Fit-PC2. |
| 356 | 356 | ||
| @@ -365,7 +365,7 @@ config IR_IGUANA | |||
| 365 | depends on USB_ARCH_HAS_HCD | 365 | depends on USB_ARCH_HAS_HCD |
| 366 | depends on RC_CORE | 366 | depends on RC_CORE |
| 367 | select USB | 367 | select USB |
| 368 | ---help--- | 368 | help |
| 369 | Say Y here if you want to use the IguanaWorks USB IR Transceiver. | 369 | Say Y here if you want to use the IguanaWorks USB IR Transceiver. |
| 370 | Both infrared receive and send are supported. If you want to | 370 | Both infrared receive and send are supported. If you want to |
| 371 | change the ID or the pin config, use the user space driver from | 371 | change the ID or the pin config, use the user space driver from |
| @@ -383,7 +383,7 @@ config IR_TTUSBIR | |||
| 383 | select USB | 383 | select USB |
| 384 | select NEW_LEDS | 384 | select NEW_LEDS |
| 385 | select LEDS_CLASS | 385 | select LEDS_CLASS |
| 386 | ---help--- | 386 | help |
| 387 | Say Y here if you want to use the TechnoTrend USB IR Receiver. The | 387 | Say Y here if you want to use the TechnoTrend USB IR Receiver. The |
| 388 | driver can control the led. | 388 | driver can control the led. |
| 389 | 389 | ||
| @@ -393,7 +393,7 @@ config IR_TTUSBIR | |||
| 393 | config IR_RX51 | 393 | config IR_RX51 |
| 394 | tristate "Nokia N900 IR transmitter diode" | 394 | tristate "Nokia N900 IR transmitter diode" |
| 395 | depends on (OMAP_DM_TIMER && PWM_OMAP_DMTIMER && ARCH_OMAP2PLUS || COMPILE_TEST) && RC_CORE | 395 | depends on (OMAP_DM_TIMER && PWM_OMAP_DMTIMER && ARCH_OMAP2PLUS || COMPILE_TEST) && RC_CORE |
| 396 | ---help--- | 396 | help |
| 397 | Say Y or M here if you want to enable support for the IR | 397 | Say Y or M here if you want to enable support for the IR |
| 398 | transmitter diode built in the Nokia N900 (RX51) device. | 398 | transmitter diode built in the Nokia N900 (RX51) device. |
| 399 | 399 | ||
| @@ -405,7 +405,7 @@ source "drivers/media/rc/img-ir/Kconfig" | |||
| 405 | config RC_LOOPBACK | 405 | config RC_LOOPBACK |
| 406 | tristate "Remote Control Loopback Driver" | 406 | tristate "Remote Control Loopback Driver" |
| 407 | depends on RC_CORE | 407 | depends on RC_CORE |
| 408 | ---help--- | 408 | help |
| 409 | Say Y here if you want support for the remote control loopback | 409 | Say Y here if you want support for the remote control loopback |
| 410 | driver which allows TX data to be sent back as RX data. | 410 | driver which allows TX data to be sent back as RX data. |
| 411 | This is mostly useful for debugging purposes. | 411 | This is mostly useful for debugging purposes. |
| @@ -419,7 +419,7 @@ config IR_GPIO_CIR | |||
| 419 | tristate "GPIO IR remote control" | 419 | tristate "GPIO IR remote control" |
| 420 | depends on RC_CORE | 420 | depends on RC_CORE |
| 421 | depends on (OF && GPIOLIB) || COMPILE_TEST | 421 | depends on (OF && GPIOLIB) || COMPILE_TEST |
| 422 | ---help--- | 422 | help |
| 423 | Say Y if you want to use GPIO based IR Receiver. | 423 | Say Y if you want to use GPIO based IR Receiver. |
| 424 | 424 | ||
| 425 | To compile this driver as a module, choose M here: the module will | 425 | To compile this driver as a module, choose M here: the module will |
| @@ -430,7 +430,7 @@ config IR_GPIO_TX | |||
| 430 | depends on RC_CORE | 430 | depends on RC_CORE |
| 431 | depends on LIRC | 431 | depends on LIRC |
| 432 | depends on (OF && GPIOLIB) || COMPILE_TEST | 432 | depends on (OF && GPIOLIB) || COMPILE_TEST |
| 433 | ---help--- | 433 | help |
| 434 | Say Y if you want to a GPIO based IR transmitter. This is a | 434 | Say Y if you want to a GPIO based IR transmitter. This is a |
| 435 | bit banging driver. | 435 | bit banging driver. |
| 436 | 436 | ||
| @@ -443,7 +443,7 @@ config IR_PWM_TX | |||
| 443 | depends on LIRC | 443 | depends on LIRC |
| 444 | depends on PWM | 444 | depends on PWM |
| 445 | depends on OF || COMPILE_TEST | 445 | depends on OF || COMPILE_TEST |
| 446 | ---help--- | 446 | help |
| 447 | Say Y if you want to use a PWM based IR transmitter. This is | 447 | Say Y if you want to use a PWM based IR transmitter. This is |
| 448 | more power efficient than the bit banging gpio driver. | 448 | more power efficient than the bit banging gpio driver. |
| 449 | 449 | ||
| @@ -454,7 +454,7 @@ config RC_ST | |||
| 454 | tristate "ST remote control receiver" | 454 | tristate "ST remote control receiver" |
| 455 | depends on RC_CORE | 455 | depends on RC_CORE |
| 456 | depends on ARCH_STI || COMPILE_TEST | 456 | depends on ARCH_STI || COMPILE_TEST |
| 457 | ---help--- | 457 | help |
| 458 | Say Y here if you want support for ST remote control driver | 458 | Say Y here if you want support for ST remote control driver |
| 459 | which allows both IR and UHF RX. | 459 | which allows both IR and UHF RX. |
| 460 | The driver passes raw pulse and space information to the LIRC decoder. | 460 | The driver passes raw pulse and space information to the LIRC decoder. |
| @@ -465,7 +465,7 @@ config IR_SUNXI | |||
| 465 | tristate "SUNXI IR remote control" | 465 | tristate "SUNXI IR remote control" |
| 466 | depends on RC_CORE | 466 | depends on RC_CORE |
| 467 | depends on ARCH_SUNXI || COMPILE_TEST | 467 | depends on ARCH_SUNXI || COMPILE_TEST |
| 468 | ---help--- | 468 | help |
| 469 | Say Y if you want to use sunXi internal IR Controller | 469 | Say Y if you want to use sunXi internal IR Controller |
| 470 | 470 | ||
| 471 | To compile this driver as a module, choose M here: the module will | 471 | To compile this driver as a module, choose M here: the module will |
| @@ -474,7 +474,7 @@ config IR_SUNXI | |||
| 474 | config IR_SERIAL | 474 | config IR_SERIAL |
| 475 | tristate "Homebrew Serial Port Receiver" | 475 | tristate "Homebrew Serial Port Receiver" |
| 476 | depends on RC_CORE | 476 | depends on RC_CORE |
| 477 | ---help--- | 477 | help |
| 478 | Say Y if you want to use Homebrew Serial Port Receivers and | 478 | Say Y if you want to use Homebrew Serial Port Receivers and |
| 479 | Transceivers. | 479 | Transceivers. |
| 480 | 480 | ||
| @@ -484,13 +484,13 @@ config IR_SERIAL | |||
| 484 | config IR_SERIAL_TRANSMITTER | 484 | config IR_SERIAL_TRANSMITTER |
| 485 | bool "Serial Port Transmitter" | 485 | bool "Serial Port Transmitter" |
| 486 | depends on IR_SERIAL | 486 | depends on IR_SERIAL |
| 487 | ---help--- | 487 | help |
| 488 | Serial Port Transmitter support | 488 | Serial Port Transmitter support |
| 489 | 489 | ||
| 490 | config IR_SIR | 490 | config IR_SIR |
| 491 | tristate "Built-in SIR IrDA port" | 491 | tristate "Built-in SIR IrDA port" |
| 492 | depends on RC_CORE | 492 | depends on RC_CORE |
| 493 | ---help--- | 493 | help |
| 494 | Say Y if you want to use a IrDA SIR port Transceivers. | 494 | Say Y if you want to use a IrDA SIR port Transceivers. |
| 495 | 495 | ||
| 496 | To compile this driver as a module, choose M here: the module will | 496 | To compile this driver as a module, choose M here: the module will |
| @@ -500,7 +500,7 @@ config IR_TANGO | |||
| 500 | tristate "Sigma Designs SMP86xx IR decoder" | 500 | tristate "Sigma Designs SMP86xx IR decoder" |
| 501 | depends on RC_CORE | 501 | depends on RC_CORE |
| 502 | depends on ARCH_TANGO || COMPILE_TEST | 502 | depends on ARCH_TANGO || COMPILE_TEST |
| 503 | ---help--- | 503 | help |
| 504 | Adds support for the HW IR decoder embedded on Sigma Designs | 504 | Adds support for the HW IR decoder embedded on Sigma Designs |
| 505 | Tango-based systems (SMP86xx, SMP87xx). | 505 | Tango-based systems (SMP86xx, SMP87xx). |
| 506 | The HW decoder supports NEC, RC-5, RC-6 IR protocols. | 506 | The HW decoder supports NEC, RC-5, RC-6 IR protocols. |
| @@ -522,7 +522,7 @@ config IR_ZX | |||
| 522 | tristate "ZTE ZX IR remote control" | 522 | tristate "ZTE ZX IR remote control" |
| 523 | depends on RC_CORE | 523 | depends on RC_CORE |
| 524 | depends on ARCH_ZX || COMPILE_TEST | 524 | depends on ARCH_ZX || COMPILE_TEST |
| 525 | ---help--- | 525 | help |
| 526 | Say Y if you want to use the IR remote control available | 526 | Say Y if you want to use the IR remote control available |
| 527 | on ZTE ZX family SoCs. | 527 | on ZTE ZX family SoCs. |
| 528 | 528 | ||
diff --git a/drivers/media/rc/ir-rcmm-decoder.c b/drivers/media/rc/ir-rcmm-decoder.c index f1096ac1e5c5..64fb65a9a19f 100644 --- a/drivers/media/rc/ir-rcmm-decoder.c +++ b/drivers/media/rc/ir-rcmm-decoder.c | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #include "rc-core-priv.h" | 6 | #include "rc-core-priv.h" |
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/version.h> | ||
| 9 | 8 | ||
| 10 | #define RCMM_UNIT 166667 /* nanosecs */ | 9 | #define RCMM_UNIT 166667 /* nanosecs */ |
| 11 | #define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */ | 10 | #define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */ |
diff --git a/drivers/media/rc/keymaps/Kconfig b/drivers/media/rc/keymaps/Kconfig index 767423bbbdd0..f459096d8e9c 100644 --- a/drivers/media/rc/keymaps/Kconfig +++ b/drivers/media/rc/keymaps/Kconfig | |||
| @@ -3,7 +3,7 @@ config RC_MAP | |||
| 3 | depends on RC_CORE | 3 | depends on RC_CORE |
| 4 | default y | 4 | default y |
| 5 | 5 | ||
| 6 | ---help--- | 6 | help |
| 7 | This option enables the compilation of lots of Remote | 7 | This option enables the compilation of lots of Remote |
| 8 | Controller tables. They are short tables, but if you | 8 | Controller tables. They are short tables, but if you |
| 9 | don't use a remote controller, or prefer to load the | 9 | don't use a remote controller, or prefer to load the |
diff --git a/drivers/media/rc/keymaps/rc-xbox-dvd.c b/drivers/media/rc/keymaps/rc-xbox-dvd.c index af387244636b..42815ab57bff 100644 --- a/drivers/media/rc/keymaps/rc-xbox-dvd.c +++ b/drivers/media/rc/keymaps/rc-xbox-dvd.c | |||
| @@ -42,7 +42,7 @@ static struct rc_map_list xbox_dvd_map = { | |||
| 42 | .map = { | 42 | .map = { |
| 43 | .scan = xbox_dvd, | 43 | .scan = xbox_dvd, |
| 44 | .size = ARRAY_SIZE(xbox_dvd), | 44 | .size = ARRAY_SIZE(xbox_dvd), |
| 45 | .rc_proto = RC_PROTO_UNKNOWN, | 45 | .rc_proto = RC_PROTO_XBOX_DVD, |
| 46 | .name = RC_MAP_XBOX_DVD, | 46 | .name = RC_MAP_XBOX_DVD, |
| 47 | } | 47 | } |
| 48 | }; | 48 | }; |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index e8fa28e20192..be5fd129d728 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
| @@ -76,6 +76,7 @@ static const struct { | |||
| 76 | .scancode_bits = 0x00ffffff, .repeat_period = 114 }, | 76 | .scancode_bits = 0x00ffffff, .repeat_period = 114 }, |
| 77 | [RC_PROTO_RCMM32] = { .name = "rc-mm-32", | 77 | [RC_PROTO_RCMM32] = { .name = "rc-mm-32", |
| 78 | .scancode_bits = 0xffffffff, .repeat_period = 114 }, | 78 | .scancode_bits = 0xffffffff, .repeat_period = 114 }, |
| 79 | [RC_PROTO_XBOX_DVD] = { .name = "xbox-dvd", .repeat_period = 64 }, | ||
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | /* Used to keep track of known keymaps */ | 82 | /* Used to keep track of known keymaps */ |
| @@ -1027,6 +1028,7 @@ static const struct { | |||
| 1027 | { RC_PROTO_BIT_RCMM12 | | 1028 | { RC_PROTO_BIT_RCMM12 | |
| 1028 | RC_PROTO_BIT_RCMM24 | | 1029 | RC_PROTO_BIT_RCMM24 | |
| 1029 | RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, | 1030 | RC_PROTO_BIT_RCMM32, "rc-mm", "ir-rcmm-decoder" }, |
| 1031 | { RC_PROTO_BIT_XBOX_DVD, "xbox-dvd", NULL }, | ||
| 1030 | }; | 1032 | }; |
| 1031 | 1033 | ||
| 1032 | /** | 1034 | /** |
diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index ffe2c672d105..3998ba29beb6 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c | |||
| @@ -773,8 +773,6 @@ static void serial_ir_exit(void) | |||
| 773 | 773 | ||
| 774 | static int __init serial_ir_init_module(void) | 774 | static int __init serial_ir_init_module(void) |
| 775 | { | 775 | { |
| 776 | int result; | ||
| 777 | |||
| 778 | switch (type) { | 776 | switch (type) { |
| 779 | case IR_HOMEBREW: | 777 | case IR_HOMEBREW: |
| 780 | case IR_IRDEO: | 778 | case IR_IRDEO: |
| @@ -802,12 +800,7 @@ static int __init serial_ir_init_module(void) | |||
| 802 | if (sense != -1) | 800 | if (sense != -1) |
| 803 | sense = !!sense; | 801 | sense = !!sense; |
| 804 | 802 | ||
| 805 | result = serial_ir_init(); | 803 | return serial_ir_init(); |
| 806 | if (!result) | ||
| 807 | return 0; | ||
| 808 | |||
| 809 | serial_ir_exit(); | ||
| 810 | return result; | ||
| 811 | } | 804 | } |
| 812 | 805 | ||
| 813 | static void __exit serial_ir_exit_module(void) | 806 | static void __exit serial_ir_exit_module(void) |
diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c index f959cbb94744..4a3f2cc4ef18 100644 --- a/drivers/media/rc/xbox_remote.c +++ b/drivers/media/rc/xbox_remote.c | |||
| @@ -107,7 +107,7 @@ static void xbox_remote_input_report(struct urb *urb) | |||
| 107 | return; | 107 | return; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | rc_keydown(xbox_remote->rdev, RC_PROTO_UNKNOWN, | 110 | rc_keydown(xbox_remote->rdev, RC_PROTO_XBOX_DVD, |
| 111 | le16_to_cpup((__le16 *)(data + 2)), 0); | 111 | le16_to_cpup((__le16 *)(data + 2)), 0); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| @@ -148,7 +148,7 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) | |||
| 148 | struct rc_dev *rdev = xbox_remote->rdev; | 148 | struct rc_dev *rdev = xbox_remote->rdev; |
| 149 | 149 | ||
| 150 | rdev->priv = xbox_remote; | 150 | rdev->priv = xbox_remote; |
| 151 | rdev->allowed_protocols = RC_PROTO_BIT_UNKNOWN; | 151 | rdev->allowed_protocols = RC_PROTO_BIT_XBOX_DVD; |
| 152 | rdev->driver_name = "xbox_remote"; | 152 | rdev->driver_name = "xbox_remote"; |
| 153 | 153 | ||
| 154 | rdev->open = xbox_remote_rc_open; | 154 | rdev->open = xbox_remote_rc_open; |
| @@ -157,6 +157,8 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) | |||
| 157 | rdev->device_name = xbox_remote->rc_name; | 157 | rdev->device_name = xbox_remote->rc_name; |
| 158 | rdev->input_phys = xbox_remote->rc_phys; | 158 | rdev->input_phys = xbox_remote->rc_phys; |
| 159 | 159 | ||
| 160 | rdev->timeout = MS_TO_NS(10); | ||
| 161 | |||
| 160 | usb_to_input_id(xbox_remote->udev, &rdev->input_id); | 162 | usb_to_input_id(xbox_remote->udev, &rdev->input_id); |
| 161 | rdev->dev.parent = &xbox_remote->interface->dev; | 163 | rdev->dev.parent = &xbox_remote->interface->dev; |
| 162 | } | 164 | } |
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig index b07ac86fc53c..df169ecf0c27 100644 --- a/drivers/media/spi/Kconfig +++ b/drivers/media/spi/Kconfig | |||
| @@ -6,7 +6,7 @@ menu "SPI helper chips" | |||
| 6 | config VIDEO_GS1662 | 6 | config VIDEO_GS1662 |
| 7 | tristate "Gennum Serializers video" | 7 | tristate "Gennum Serializers video" |
| 8 | depends on SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 8 | depends on SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 9 | ---help--- | 9 | help |
| 10 | Enable the GS1662 driver which serializes video streams. | 10 | Enable the GS1662 driver which serializes video streams. |
| 11 | 11 | ||
| 12 | endmenu | 12 | endmenu |
diff --git a/drivers/media/usb/airspy/Kconfig b/drivers/media/usb/airspy/Kconfig index 10b204cf4dbc..67578511bb9a 100644 --- a/drivers/media/usb/airspy/Kconfig +++ b/drivers/media/usb/airspy/Kconfig | |||
| @@ -2,7 +2,7 @@ config USB_AIRSPY | |||
| 2 | tristate "AirSpy" | 2 | tristate "AirSpy" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | ---help--- | 5 | help |
| 6 | This is a video4linux2 driver for AirSpy SDR device. | 6 | This is a video4linux2 driver for AirSpy SDR device. |
| 7 | 7 | ||
| 8 | To compile this driver as a module, choose M here: the | 8 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index 65fc067eb864..0ad985542c60 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | config VIDEO_AU0828 | 2 | config VIDEO_AU0828 |
| 3 | tristate "Auvitek AU0828 support" | 3 | tristate "Auvitek AU0828 support" |
| 4 | depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 | 4 | depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 |
| 5 | select MEDIA_CONTROLLER | ||
| 6 | select MEDIA_CONTROLLER_DVB | ||
| 5 | select I2C_ALGOBIT | 7 | select I2C_ALGOBIT |
| 6 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
| 7 | select VIDEOBUF2_VMALLOC if VIDEO_V4L2 | 9 | select VIDEOBUF2_VMALLOC if VIDEO_V4L2 |
| @@ -9,7 +11,7 @@ config VIDEO_AU0828 | |||
| 9 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT | 11 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT |
| 10 | select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT | 12 | select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT |
| 11 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 13 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
| 12 | ---help--- | 14 | help |
| 13 | This is a hybrid analog/digital tv capture driver for | 15 | This is a hybrid analog/digital tv capture driver for |
| 14 | Auvitek's AU0828 USB device. | 16 | Auvitek's AU0828 USB device. |
| 15 | 17 | ||
| @@ -23,7 +25,7 @@ config VIDEO_AU0828_V4L2 | |||
| 23 | select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT | 25 | select DVB_AU8522_V4L if MEDIA_SUBDRV_AUTOSELECT |
| 24 | select VIDEO_TUNER | 26 | select VIDEO_TUNER |
| 25 | default y | 27 | default y |
| 26 | ---help--- | 28 | help |
| 27 | This is a video4linux driver for Auvitek's USB device. | 29 | This is a video4linux driver for Auvitek's USB device. |
| 28 | 30 | ||
| 29 | Choose Y here to include support for v4l2 analog video | 31 | Choose Y here to include support for v4l2 analog video |
| @@ -34,5 +36,5 @@ config VIDEO_AU0828_RC | |||
| 34 | depends on RC_CORE | 36 | depends on RC_CORE |
| 35 | depends on !(RC_CORE=m && VIDEO_AU0828=y) | 37 | depends on !(RC_CORE=m && VIDEO_AU0828=y) |
| 36 | depends on VIDEO_AU0828 | 38 | depends on VIDEO_AU0828 |
| 37 | ---help--- | 39 | help |
| 38 | Enables Remote Controller support on au0828 driver. | 40 | Enables Remote Controller support on au0828 driver. |
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 3f8c92a70116..925a80437822 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c | |||
| @@ -155,9 +155,7 @@ static void au0828_unregister_media_device(struct au0828_dev *dev) | |||
| 155 | dev->media_dev->disable_source = NULL; | 155 | dev->media_dev->disable_source = NULL; |
| 156 | mutex_unlock(&mdev->graph_mutex); | 156 | mutex_unlock(&mdev->graph_mutex); |
| 157 | 157 | ||
| 158 | media_device_unregister(dev->media_dev); | 158 | media_device_delete(dev->media_dev, KBUILD_MODNAME, THIS_MODULE); |
| 159 | media_device_cleanup(dev->media_dev); | ||
| 160 | kfree(dev->media_dev); | ||
| 161 | dev->media_dev = NULL; | 159 | dev->media_dev = NULL; |
| 162 | #endif | 160 | #endif |
| 163 | } | 161 | } |
| @@ -210,14 +208,10 @@ static int au0828_media_device_init(struct au0828_dev *dev, | |||
| 210 | #ifdef CONFIG_MEDIA_CONTROLLER | 208 | #ifdef CONFIG_MEDIA_CONTROLLER |
| 211 | struct media_device *mdev; | 209 | struct media_device *mdev; |
| 212 | 210 | ||
| 213 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | 211 | mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE); |
| 214 | if (!mdev) | 212 | if (!mdev) |
| 215 | return -ENOMEM; | 213 | return -ENOMEM; |
| 216 | 214 | ||
| 217 | /* check if media device is already initialized */ | ||
| 218 | if (!mdev->dev) | ||
| 219 | media_device_usb_init(mdev, udev, udev->product); | ||
| 220 | |||
| 221 | dev->media_dev = mdev; | 215 | dev->media_dev = mdev; |
| 222 | #endif | 216 | #endif |
| 223 | return 0; | 217 | return 0; |
| @@ -278,6 +272,28 @@ create_link: | |||
| 278 | } | 272 | } |
| 279 | } | 273 | } |
| 280 | 274 | ||
| 275 | static bool au0828_is_link_shareable(struct media_entity *owner, | ||
| 276 | struct media_entity *entity) | ||
| 277 | { | ||
| 278 | bool shareable = false; | ||
| 279 | |||
| 280 | /* Tuner link can be shared by audio, video, and VBI */ | ||
| 281 | switch (owner->function) { | ||
| 282 | case MEDIA_ENT_F_IO_V4L: | ||
| 283 | case MEDIA_ENT_F_AUDIO_CAPTURE: | ||
| 284 | case MEDIA_ENT_F_IO_VBI: | ||
| 285 | if (entity->function == MEDIA_ENT_F_IO_V4L || | ||
| 286 | entity->function == MEDIA_ENT_F_AUDIO_CAPTURE || | ||
| 287 | entity->function == MEDIA_ENT_F_IO_VBI) | ||
| 288 | shareable = true; | ||
| 289 | break; | ||
| 290 | case MEDIA_ENT_F_DTV_DEMOD: | ||
| 291 | default: | ||
| 292 | break; | ||
| 293 | } | ||
| 294 | return shareable; | ||
| 295 | } | ||
| 296 | |||
| 281 | /* Callers should hold graph_mutex */ | 297 | /* Callers should hold graph_mutex */ |
| 282 | static int au0828_enable_source(struct media_entity *entity, | 298 | static int au0828_enable_source(struct media_entity *entity, |
| 283 | struct media_pipeline *pipe) | 299 | struct media_pipeline *pipe) |
| @@ -320,18 +336,20 @@ static int au0828_enable_source(struct media_entity *entity, | |||
| 320 | /* | 336 | /* |
| 321 | * Default input is tuner and default input_type | 337 | * Default input is tuner and default input_type |
| 322 | * is AU0828_VMUX_TELEVISION. | 338 | * is AU0828_VMUX_TELEVISION. |
| 323 | * FIXME: | 339 | * |
| 324 | * There is a problem when s_input is called to | 340 | * There is a problem when s_input is called to |
| 325 | * change the default input. s_input will try to | 341 | * change the default input. s_input will try to |
| 326 | * enable_source before attempting to change the | 342 | * enable_source before attempting to change the |
| 327 | * input on the device, and will end up enabling | 343 | * input on the device, and will end up enabling |
| 328 | * default source which is tuner. | 344 | * default source which is tuner. |
| 329 | * | 345 | * |
| 330 | * Additional logic is necessary in au0828 | 346 | * Additional logic is necessary in au0828 to detect |
| 331 | * to detect that the input has changed and | 347 | * that the input has changed and enable the right |
| 332 | * enable the right source. | 348 | * source. au0828 handles this case in its s_input. |
| 349 | * It will disable the old source and enable the new | ||
| 350 | * source. | ||
| 351 | * | ||
| 333 | */ | 352 | */ |
| 334 | |||
| 335 | if (dev->input_type == AU0828_VMUX_TELEVISION) | 353 | if (dev->input_type == AU0828_VMUX_TELEVISION) |
| 336 | find_source = dev->tuner; | 354 | find_source = dev->tuner; |
| 337 | else if (dev->input_type == AU0828_VMUX_SVIDEO || | 355 | else if (dev->input_type == AU0828_VMUX_SVIDEO || |
| @@ -344,27 +362,33 @@ static int au0828_enable_source(struct media_entity *entity, | |||
| 344 | } | 362 | } |
| 345 | } | 363 | } |
| 346 | 364 | ||
| 347 | /* Is an active link between sink and source */ | 365 | /* Is there an active link between sink and source */ |
| 348 | if (dev->active_link) { | 366 | if (dev->active_link) { |
| 349 | /* | 367 | if (dev->active_link_owner == entity) { |
| 350 | * If DVB is using the tuner and calling entity is | 368 | /* This check is necessary to handle multiple |
| 351 | * audio/video, the following check will be false, | 369 | * enable_source calls from v4l_ioctls during |
| 352 | * since sink is different. Result is Busy. | 370 | * the course of video/vbi application run-time. |
| 353 | */ | ||
| 354 | if (dev->active_link->sink->entity == sink && | ||
| 355 | dev->active_link->source->entity == find_source) { | ||
| 356 | /* | ||
| 357 | * Either ALSA or Video own tuner. sink is | ||
| 358 | * the same for both. Prevent Video stepping | ||
| 359 | * on ALSA when ALSA owns the source. | ||
| 360 | */ | 371 | */ |
| 361 | if (dev->active_link_owner != entity && | 372 | pr_debug("%s already owns the tuner\n", entity->name); |
| 362 | dev->active_link_owner->function == | 373 | ret = 0; |
| 363 | MEDIA_ENT_F_AUDIO_CAPTURE) { | 374 | goto end; |
| 364 | pr_debug("ALSA has the tuner\n"); | 375 | } else if (au0828_is_link_shareable(dev->active_link_owner, |
| 365 | ret = -EBUSY; | 376 | entity)) { |
| 366 | goto end; | 377 | /* Either ALSA or Video own tuner. Sink is the same |
| 367 | } | 378 | * for both. Allow sharing the active link between |
| 379 | * their common source (tuner) and sink (decoder). | ||
| 380 | * Starting pipeline between sharing entity and sink | ||
| 381 | * will fail with pipe mismatch, while owner has an | ||
| 382 | * active pipeline. Switch pipeline ownership from | ||
| 383 | * user to owner when owner disables the source. | ||
| 384 | */ | ||
| 385 | dev->active_link_shared = true; | ||
| 386 | /* save the user info to use from disable */ | ||
| 387 | dev->active_link_user = entity; | ||
| 388 | dev->active_link_user_pipe = pipe; | ||
| 389 | pr_debug("%s owns the tuner %s can share!\n", | ||
| 390 | dev->active_link_owner->name, | ||
| 391 | entity->name); | ||
| 368 | ret = 0; | 392 | ret = 0; |
| 369 | goto end; | 393 | goto end; |
| 370 | } else { | 394 | } else { |
| @@ -391,7 +415,7 @@ static int au0828_enable_source(struct media_entity *entity, | |||
| 391 | source = found_link->source->entity; | 415 | source = found_link->source->entity; |
| 392 | ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED); | 416 | ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED); |
| 393 | if (ret) { | 417 | if (ret) { |
| 394 | pr_err("Activate tuner link %s->%s. Error %d\n", | 418 | pr_err("Activate link from %s->%s. Error %d\n", |
| 395 | source->name, sink->name, ret); | 419 | source->name, sink->name, ret); |
| 396 | goto end; | 420 | goto end; |
| 397 | } | 421 | } |
| @@ -401,25 +425,26 @@ static int au0828_enable_source(struct media_entity *entity, | |||
| 401 | pr_err("Start Pipeline: %s->%s Error %d\n", | 425 | pr_err("Start Pipeline: %s->%s Error %d\n", |
| 402 | source->name, entity->name, ret); | 426 | source->name, entity->name, ret); |
| 403 | ret = __media_entity_setup_link(found_link, 0); | 427 | ret = __media_entity_setup_link(found_link, 0); |
| 404 | pr_err("Deactivate link Error %d\n", ret); | 428 | if (ret) |
| 429 | pr_err("Deactivate link Error %d\n", ret); | ||
| 405 | goto end; | 430 | goto end; |
| 406 | } | 431 | } |
| 407 | /* | 432 | |
| 408 | * save active link and active link owner to avoid audio | 433 | /* save link state to allow audio and video share the link |
| 409 | * deactivating video owned link from disable_source and | 434 | * and not disable the link while the other is using it. |
| 410 | * vice versa | 435 | * active_link_owner is used to deactivate the link. |
| 411 | */ | 436 | */ |
| 412 | dev->active_link = found_link; | 437 | dev->active_link = found_link; |
| 413 | dev->active_link_owner = entity; | 438 | dev->active_link_owner = entity; |
| 414 | dev->active_source = source; | 439 | dev->active_source = source; |
| 415 | dev->active_sink = sink; | 440 | dev->active_sink = sink; |
| 416 | 441 | ||
| 417 | pr_debug("Enabled Source: %s->%s->%s Ret %d\n", | 442 | pr_info("Enabled Source: %s->%s->%s Ret %d\n", |
| 418 | dev->active_source->name, dev->active_sink->name, | 443 | dev->active_source->name, dev->active_sink->name, |
| 419 | dev->active_link_owner->name, ret); | 444 | dev->active_link_owner->name, ret); |
| 420 | end: | 445 | end: |
| 421 | pr_debug("au0828_enable_source() end %s %d %d\n", | 446 | pr_debug("%s end: ent:%s fnc:%d ret %d\n", |
| 422 | entity->name, entity->function, ret); | 447 | __func__, entity->name, entity->function, ret); |
| 423 | return ret; | 448 | return ret; |
| 424 | } | 449 | } |
| 425 | 450 | ||
| @@ -438,21 +463,95 @@ static void au0828_disable_source(struct media_entity *entity) | |||
| 438 | if (!dev->active_link) | 463 | if (!dev->active_link) |
| 439 | return; | 464 | return; |
| 440 | 465 | ||
| 441 | /* link is active - stop pipeline from source (tuner) */ | 466 | /* link is active - stop pipeline from source |
| 467 | * (tuner/s-video/Composite) to the entity | ||
| 468 | * When DVB/s-video/Composite owns tuner, it won't be in | ||
| 469 | * shared state. | ||
| 470 | */ | ||
| 442 | if (dev->active_link->sink->entity == dev->active_sink && | 471 | if (dev->active_link->sink->entity == dev->active_sink && |
| 443 | dev->active_link->source->entity == dev->active_source) { | 472 | dev->active_link->source->entity == dev->active_source) { |
| 444 | /* | 473 | /* |
| 445 | * prevent video from deactivating link when audio | 474 | * Prevent video from deactivating link when audio |
| 446 | * has active pipeline | 475 | * has active pipeline and vice versa. In addition |
| 476 | * handle the case when more than one video/vbi | ||
| 477 | * application is sharing the link. | ||
| 447 | */ | 478 | */ |
| 479 | bool owner_is_audio = false; | ||
| 480 | |||
| 481 | if (dev->active_link_owner->function == | ||
| 482 | MEDIA_ENT_F_AUDIO_CAPTURE) | ||
| 483 | owner_is_audio = true; | ||
| 484 | |||
| 485 | if (dev->active_link_shared) { | ||
| 486 | pr_debug("Shared link owner %s user %s %d\n", | ||
| 487 | dev->active_link_owner->name, | ||
| 488 | entity->name, dev->users); | ||
| 489 | |||
| 490 | /* Handle video device users > 1 | ||
| 491 | * When audio owns the shared link with | ||
| 492 | * more than one video users, avoid | ||
| 493 | * disabling the source and/or switching | ||
| 494 | * the owner until the last disable_source | ||
| 495 | * call from video _close(). Use dev->users to | ||
| 496 | * determine when to switch/disable. | ||
| 497 | */ | ||
| 498 | if (dev->active_link_owner != entity) { | ||
| 499 | /* video device has users > 1 */ | ||
| 500 | if (owner_is_audio && dev->users > 1) | ||
| 501 | return; | ||
| 502 | |||
| 503 | dev->active_link_user = NULL; | ||
| 504 | dev->active_link_user_pipe = NULL; | ||
| 505 | dev->active_link_shared = false; | ||
| 506 | return; | ||
| 507 | } | ||
| 508 | |||
| 509 | /* video owns the link and has users > 1 */ | ||
| 510 | if (!owner_is_audio && dev->users > 1) | ||
| 511 | return; | ||
| 512 | |||
| 513 | /* stop pipeline */ | ||
| 514 | __media_pipeline_stop(dev->active_link_owner); | ||
| 515 | pr_debug("Pipeline stop for %s\n", | ||
| 516 | dev->active_link_owner->name); | ||
| 517 | |||
| 518 | ret = __media_pipeline_start( | ||
| 519 | dev->active_link_user, | ||
| 520 | dev->active_link_user_pipe); | ||
| 521 | if (ret) { | ||
| 522 | pr_err("Start Pipeline: %s->%s %d\n", | ||
| 523 | dev->active_source->name, | ||
| 524 | dev->active_link_user->name, | ||
| 525 | ret); | ||
| 526 | goto deactivate_link; | ||
| 527 | } | ||
| 528 | /* link user is now the owner */ | ||
| 529 | dev->active_link_owner = dev->active_link_user; | ||
| 530 | dev->active_link_user = NULL; | ||
| 531 | dev->active_link_user_pipe = NULL; | ||
| 532 | dev->active_link_shared = false; | ||
| 533 | |||
| 534 | pr_debug("Pipeline started for %s\n", | ||
| 535 | dev->active_link_owner->name); | ||
| 536 | return; | ||
| 537 | } else if (!owner_is_audio && dev->users > 1) | ||
| 538 | /* video/vbi owns the link and has users > 1 */ | ||
| 539 | return; | ||
| 540 | |||
| 448 | if (dev->active_link_owner != entity) | 541 | if (dev->active_link_owner != entity) |
| 449 | return; | 542 | return; |
| 450 | __media_pipeline_stop(entity); | 543 | |
| 544 | /* stop pipeline */ | ||
| 545 | __media_pipeline_stop(dev->active_link_owner); | ||
| 546 | pr_debug("Pipeline stop for %s\n", | ||
| 547 | dev->active_link_owner->name); | ||
| 548 | |||
| 549 | deactivate_link: | ||
| 451 | ret = __media_entity_setup_link(dev->active_link, 0); | 550 | ret = __media_entity_setup_link(dev->active_link, 0); |
| 452 | if (ret) | 551 | if (ret) |
| 453 | pr_err("Deactivate link Error %d\n", ret); | 552 | pr_err("Deactivate link Error %d\n", ret); |
| 454 | 553 | ||
| 455 | pr_debug("Disabled Source: %s->%s->%s Ret %d\n", | 554 | pr_info("Disabled Source: %s->%s->%s Ret %d\n", |
| 456 | dev->active_source->name, dev->active_sink->name, | 555 | dev->active_source->name, dev->active_sink->name, |
| 457 | dev->active_link_owner->name, ret); | 556 | dev->active_link_owner->name, ret); |
| 458 | 557 | ||
| @@ -460,6 +559,8 @@ static void au0828_disable_source(struct media_entity *entity) | |||
| 460 | dev->active_link_owner = NULL; | 559 | dev->active_link_owner = NULL; |
| 461 | dev->active_source = NULL; | 560 | dev->active_source = NULL; |
| 462 | dev->active_sink = NULL; | 561 | dev->active_sink = NULL; |
| 562 | dev->active_link_shared = false; | ||
| 563 | dev->active_link_user = NULL; | ||
| 463 | } | 564 | } |
| 464 | } | 565 | } |
| 465 | #endif | 566 | #endif |
| @@ -480,6 +581,9 @@ static int au0828_media_device_register(struct au0828_dev *dev, | |||
| 480 | /* register media device */ | 581 | /* register media device */ |
| 481 | ret = media_device_register(dev->media_dev); | 582 | ret = media_device_register(dev->media_dev); |
| 482 | if (ret) { | 583 | if (ret) { |
| 584 | media_device_delete(dev->media_dev, KBUILD_MODNAME, | ||
| 585 | THIS_MODULE); | ||
| 586 | dev->media_dev = NULL; | ||
| 483 | dev_err(&udev->dev, | 587 | dev_err(&udev->dev, |
| 484 | "Media Device Register Error: %d\n", ret); | 588 | "Media Device Register Error: %d\n", ret); |
| 485 | return ret; | 589 | return ret; |
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 7876c897cc1d..4bde3db83aa2 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c | |||
| @@ -758,6 +758,9 @@ static int au0828_analog_stream_enable(struct au0828_dev *d) | |||
| 758 | 758 | ||
| 759 | dprintk(1, "au0828_analog_stream_enable called\n"); | 759 | dprintk(1, "au0828_analog_stream_enable called\n"); |
| 760 | 760 | ||
| 761 | if (test_bit(DEV_DISCONNECTED, &d->dev_state)) | ||
| 762 | return -ENODEV; | ||
| 763 | |||
| 761 | iface = usb_ifnum_to_if(d->usbdev, 0); | 764 | iface = usb_ifnum_to_if(d->usbdev, 0); |
| 762 | if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) { | 765 | if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) { |
| 763 | dprintk(1, "Changing intf#0 to alt 5\n"); | 766 | dprintk(1, "Changing intf#0 to alt 5\n"); |
| @@ -839,9 +842,9 @@ int au0828_start_analog_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 839 | return rc; | 842 | return rc; |
| 840 | } | 843 | } |
| 841 | 844 | ||
| 845 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); | ||
| 846 | |||
| 842 | if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 847 | if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
| 843 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, | ||
| 844 | s_stream, 1); | ||
| 845 | dev->vid_timeout_running = 1; | 848 | dev->vid_timeout_running = 1; |
| 846 | mod_timer(&dev->vid_timeout, jiffies + (HZ / 10)); | 849 | mod_timer(&dev->vid_timeout, jiffies + (HZ / 10)); |
| 847 | } else if (vq->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | 850 | } else if (vq->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
| @@ -861,10 +864,11 @@ static void au0828_stop_streaming(struct vb2_queue *vq) | |||
| 861 | 864 | ||
| 862 | dprintk(1, "au0828_stop_streaming called %d\n", dev->streaming_users); | 865 | dprintk(1, "au0828_stop_streaming called %d\n", dev->streaming_users); |
| 863 | 866 | ||
| 864 | if (dev->streaming_users-- == 1) | 867 | if (dev->streaming_users-- == 1) { |
| 865 | au0828_uninit_isoc(dev); | 868 | au0828_uninit_isoc(dev); |
| 869 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | ||
| 870 | } | ||
| 866 | 871 | ||
| 867 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | ||
| 868 | dev->vid_timeout_running = 0; | 872 | dev->vid_timeout_running = 0; |
| 869 | del_timer_sync(&dev->vid_timeout); | 873 | del_timer_sync(&dev->vid_timeout); |
| 870 | 874 | ||
| @@ -893,8 +897,10 @@ void au0828_stop_vbi_streaming(struct vb2_queue *vq) | |||
| 893 | dprintk(1, "au0828_stop_vbi_streaming called %d\n", | 897 | dprintk(1, "au0828_stop_vbi_streaming called %d\n", |
| 894 | dev->streaming_users); | 898 | dev->streaming_users); |
| 895 | 899 | ||
| 896 | if (dev->streaming_users-- == 1) | 900 | if (dev->streaming_users-- == 1) { |
| 897 | au0828_uninit_isoc(dev); | 901 | au0828_uninit_isoc(dev); |
| 902 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | ||
| 903 | } | ||
| 898 | 904 | ||
| 899 | spin_lock_irqsave(&dev->slock, flags); | 905 | spin_lock_irqsave(&dev->slock, flags); |
| 900 | if (dev->isoc_ctl.vbi_buf != NULL) { | 906 | if (dev->isoc_ctl.vbi_buf != NULL) { |
| @@ -1065,7 +1071,7 @@ static int au0828_v4l2_close(struct file *filp) | |||
| 1065 | * streaming. | 1071 | * streaming. |
| 1066 | * | 1072 | * |
| 1067 | * On most USB devices like au0828 the tuner can | 1073 | * On most USB devices like au0828 the tuner can |
| 1068 | * be safely put in sleep stare here if ALSA isn't | 1074 | * be safely put in sleep state here if ALSA isn't |
| 1069 | * streaming. Exceptions are some very old USB tuner | 1075 | * streaming. Exceptions are some very old USB tuner |
| 1070 | * models such as em28xx-based WinTV USB2 which have | 1076 | * models such as em28xx-based WinTV USB2 which have |
| 1071 | * a separate audio output jack. The devices that have | 1077 | * a separate audio output jack. The devices that have |
| @@ -1074,7 +1080,7 @@ static int au0828_v4l2_close(struct file *filp) | |||
| 1074 | * so the s_power callback are silently ignored. | 1080 | * so the s_power callback are silently ignored. |
| 1075 | * So, the current logic here does the following: | 1081 | * So, the current logic here does the following: |
| 1076 | * Disable (put tuner to sleep) when | 1082 | * Disable (put tuner to sleep) when |
| 1077 | * - ALSA and DVB aren't not streaming; | 1083 | * - ALSA and DVB aren't streaming. |
| 1078 | * - the last V4L2 file handler is closed. | 1084 | * - the last V4L2 file handler is closed. |
| 1079 | * | 1085 | * |
| 1080 | * FIXME: | 1086 | * FIXME: |
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 425c35d16057..b47ecc9affd8 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <media/v4l2-ctrls.h> | 31 | #include <media/v4l2-ctrls.h> |
| 32 | #include <media/v4l2-fh.h> | 32 | #include <media/v4l2-fh.h> |
| 33 | #include <media/media-device.h> | 33 | #include <media/media-device.h> |
| 34 | #include <media/media-dev-allocator.h> | ||
| 34 | 35 | ||
| 35 | /* DVB */ | 36 | /* DVB */ |
| 36 | #include <media/demux.h> | 37 | #include <media/demux.h> |
| @@ -283,9 +284,12 @@ struct au0828_dev { | |||
| 283 | struct media_entity_notify entity_notify; | 284 | struct media_entity_notify entity_notify; |
| 284 | struct media_entity *tuner; | 285 | struct media_entity *tuner; |
| 285 | struct media_link *active_link; | 286 | struct media_link *active_link; |
| 286 | struct media_entity *active_link_owner; | ||
| 287 | struct media_entity *active_source; | 287 | struct media_entity *active_source; |
| 288 | struct media_entity *active_sink; | 288 | struct media_entity *active_sink; |
| 289 | struct media_entity *active_link_owner; | ||
| 290 | struct media_entity *active_link_user; | ||
| 291 | struct media_pipeline *active_link_user_pipe; | ||
| 292 | bool active_link_shared; | ||
| 289 | #endif | 293 | #endif |
| 290 | }; | 294 | }; |
| 291 | 295 | ||
diff --git a/drivers/media/usb/cpia2/Kconfig b/drivers/media/usb/cpia2/Kconfig index 66e9283f5993..7029a04f3ffd 100644 --- a/drivers/media/usb/cpia2/Kconfig +++ b/drivers/media/usb/cpia2/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config VIDEO_CPIA2 | 1 | config VIDEO_CPIA2 |
| 2 | tristate "CPiA2 Video For Linux" | 2 | tristate "CPiA2 Video For Linux" |
| 3 | depends on VIDEO_DEV && USB && VIDEO_V4L2 | 3 | depends on VIDEO_DEV && USB && VIDEO_V4L2 |
| 4 | ---help--- | 4 | help |
| 5 | This is the video4linux driver for cameras based on Vision's CPiA2 | 5 | This is the video4linux driver for cameras based on Vision's CPiA2 |
| 6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 | 6 | (Colour Processor Interface ASIC), such as the Digital Blue QX5 |
| 7 | Microscope. If you have one of these cameras, say Y here | 7 | Microscope. If you have one of these cameras, say Y here |
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c index 95c0bd4a19dc..45caf78119c4 100644 --- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c | |||
| @@ -1240,8 +1240,7 @@ static int __init cpia2_init(void) | |||
| 1240 | LOG("%s v%s\n", | 1240 | LOG("%s v%s\n", |
| 1241 | ABOUT, CPIA_VERSION); | 1241 | ABOUT, CPIA_VERSION); |
| 1242 | check_parameters(); | 1242 | check_parameters(); |
| 1243 | cpia2_usb_init(); | 1243 | return cpia2_usb_init(); |
| 1244 | return 0; | ||
| 1245 | } | 1244 | } |
| 1246 | 1245 | ||
| 1247 | 1246 | ||
diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 9e5b3e7c3ef5..9262d0d7439a 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig | |||
| @@ -7,7 +7,7 @@ config VIDEO_CX231XX | |||
| 7 | select VIDEO_CX25840 | 7 | select VIDEO_CX25840 |
| 8 | select VIDEO_CX2341X | 8 | select VIDEO_CX2341X |
| 9 | 9 | ||
| 10 | ---help--- | 10 | help |
| 11 | This is a video4linux driver for Conexant 231xx USB based TV cards. | 11 | This is a video4linux driver for Conexant 231xx USB based TV cards. |
| 12 | 12 | ||
| 13 | To compile this driver as a module, choose M here: the | 13 | To compile this driver as a module, choose M here: the |
| @@ -18,7 +18,7 @@ config VIDEO_CX231XX_RC | |||
| 18 | depends on RC_CORE=y || RC_CORE=VIDEO_CX231XX | 18 | depends on RC_CORE=y || RC_CORE=VIDEO_CX231XX |
| 19 | depends on VIDEO_CX231XX | 19 | depends on VIDEO_CX231XX |
| 20 | default y | 20 | default y |
| 21 | ---help--- | 21 | help |
| 22 | cx231xx hardware has a builtin RX/TX support. However, a few | 22 | cx231xx hardware has a builtin RX/TX support. However, a few |
| 23 | designs opted to not use it, but, instead, some other hardware. | 23 | designs opted to not use it, but, instead, some other hardware. |
| 24 | This module enables the usage of those other hardware, like the | 24 | This module enables the usage of those other hardware, like the |
| @@ -31,7 +31,7 @@ config VIDEO_CX231XX_ALSA | |||
| 31 | depends on VIDEO_CX231XX && SND | 31 | depends on VIDEO_CX231XX && SND |
| 32 | select SND_PCM | 32 | select SND_PCM |
| 33 | 33 | ||
| 34 | ---help--- | 34 | help |
| 35 | This is an ALSA driver for Cx231xx USB based TV cards. | 35 | This is an ALSA driver for Cx231xx USB based TV cards. |
| 36 | 36 | ||
| 37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
| @@ -52,6 +52,6 @@ config VIDEO_CX231XX_DVB | |||
| 52 | select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT | 52 | select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT |
| 53 | select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT | 53 | select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT |
| 54 | 54 | ||
| 55 | ---help--- | 55 | help |
| 56 | This adds support for DVB cards based on the | 56 | This adds support for DVB cards based on the |
| 57 | Conexant cx231xx chips. | 57 | Conexant cx231xx chips. |
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 80d3bd3a0f24..1b7f1af399fb 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
| @@ -846,6 +846,7 @@ static int af9035_read_config(struct dvb_usb_device *d) | |||
| 846 | state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; | 846 | state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X; |
| 847 | state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; | 847 | state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB; |
| 848 | state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; | 848 | state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL; |
| 849 | state->it930x_addresses = 0; | ||
| 849 | 850 | ||
| 850 | if (state->chip_type == 0x9135) { | 851 | if (state->chip_type == 0x9135) { |
| 851 | /* feed clock for integrated RF tuner */ | 852 | /* feed clock for integrated RF tuner */ |
| @@ -872,6 +873,10 @@ static int af9035_read_config(struct dvb_usb_device *d) | |||
| 872 | * IT930x is an USB bridge, only single demod-single tuner | 873 | * IT930x is an USB bridge, only single demod-single tuner |
| 873 | * configurations seen so far. | 874 | * configurations seen so far. |
| 874 | */ | 875 | */ |
| 876 | if ((le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA) && | ||
| 877 | (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_AVERMEDIA_TD310)) { | ||
| 878 | state->it930x_addresses = 1; | ||
| 879 | } | ||
| 875 | return 0; | 880 | return 0; |
| 876 | } | 881 | } |
| 877 | 882 | ||
| @@ -1218,6 +1223,48 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap) | |||
| 1218 | 1223 | ||
| 1219 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); | 1224 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); |
| 1220 | 1225 | ||
| 1226 | /* I2C master bus 2 clock speed 300k */ | ||
| 1227 | ret = af9035_wr_reg(d, 0x00f6a7, 0x07); | ||
| 1228 | if (ret < 0) | ||
| 1229 | goto err; | ||
| 1230 | |||
| 1231 | /* I2C master bus 1,3 clock speed 300k */ | ||
| 1232 | ret = af9035_wr_reg(d, 0x00f103, 0x07); | ||
| 1233 | if (ret < 0) | ||
| 1234 | goto err; | ||
| 1235 | |||
| 1236 | /* set gpio11 low */ | ||
| 1237 | ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01); | ||
| 1238 | if (ret < 0) | ||
| 1239 | goto err; | ||
| 1240 | |||
| 1241 | ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01); | ||
| 1242 | if (ret < 0) | ||
| 1243 | goto err; | ||
| 1244 | |||
| 1245 | ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01); | ||
| 1246 | if (ret < 0) | ||
| 1247 | goto err; | ||
| 1248 | |||
| 1249 | /* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */ | ||
| 1250 | ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01); | ||
| 1251 | if (ret < 0) | ||
| 1252 | goto err; | ||
| 1253 | |||
| 1254 | ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01); | ||
| 1255 | if (ret < 0) | ||
| 1256 | goto err; | ||
| 1257 | |||
| 1258 | ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01); | ||
| 1259 | if (ret < 0) | ||
| 1260 | goto err; | ||
| 1261 | |||
| 1262 | msleep(200); | ||
| 1263 | |||
| 1264 | ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01); | ||
| 1265 | if (ret < 0) | ||
| 1266 | goto err; | ||
| 1267 | |||
| 1221 | memset(&si2168_config, 0, sizeof(si2168_config)); | 1268 | memset(&si2168_config, 0, sizeof(si2168_config)); |
| 1222 | si2168_config.i2c_adapter = &adapter; | 1269 | si2168_config.i2c_adapter = &adapter; |
| 1223 | si2168_config.fe = &adap->fe[0]; | 1270 | si2168_config.fe = &adap->fe[0]; |
| @@ -1225,8 +1272,9 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap) | |||
| 1225 | 1272 | ||
| 1226 | state->af9033_config[adap->id].fe = &adap->fe[0]; | 1273 | state->af9033_config[adap->id].fe = &adap->fe[0]; |
| 1227 | state->af9033_config[adap->id].ops = &state->ops; | 1274 | state->af9033_config[adap->id].ops = &state->ops; |
| 1228 | ret = af9035_add_i2c_dev(d, "si2168", 0x67, &si2168_config, | 1275 | ret = af9035_add_i2c_dev(d, "si2168", |
| 1229 | &d->i2c_adap); | 1276 | it930x_addresses_table[state->it930x_addresses].frontend_i2c_addr, |
| 1277 | &si2168_config, &d->i2c_adap); | ||
| 1230 | if (ret) | 1278 | if (ret) |
| 1231 | goto err; | 1279 | goto err; |
| 1232 | 1280 | ||
| @@ -1575,54 +1623,12 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap) | |||
| 1575 | 1623 | ||
| 1576 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); | 1624 | dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); |
| 1577 | 1625 | ||
| 1578 | /* I2C master bus 2 clock speed 300k */ | ||
| 1579 | ret = af9035_wr_reg(d, 0x00f6a7, 0x07); | ||
| 1580 | if (ret < 0) | ||
| 1581 | goto err; | ||
| 1582 | |||
| 1583 | /* I2C master bus 1,3 clock speed 300k */ | ||
| 1584 | ret = af9035_wr_reg(d, 0x00f103, 0x07); | ||
| 1585 | if (ret < 0) | ||
| 1586 | goto err; | ||
| 1587 | |||
| 1588 | /* set gpio11 low */ | ||
| 1589 | ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01); | ||
| 1590 | if (ret < 0) | ||
| 1591 | goto err; | ||
| 1592 | |||
| 1593 | ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01); | ||
| 1594 | if (ret < 0) | ||
| 1595 | goto err; | ||
| 1596 | |||
| 1597 | ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01); | ||
| 1598 | if (ret < 0) | ||
| 1599 | goto err; | ||
| 1600 | |||
| 1601 | /* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */ | ||
| 1602 | ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01); | ||
| 1603 | if (ret < 0) | ||
| 1604 | goto err; | ||
| 1605 | |||
| 1606 | ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01); | ||
| 1607 | if (ret < 0) | ||
| 1608 | goto err; | ||
| 1609 | |||
| 1610 | ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01); | ||
| 1611 | if (ret < 0) | ||
| 1612 | goto err; | ||
| 1613 | |||
| 1614 | msleep(200); | ||
| 1615 | |||
| 1616 | ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01); | ||
| 1617 | if (ret < 0) | ||
| 1618 | goto err; | ||
| 1619 | |||
| 1620 | memset(&si2157_config, 0, sizeof(si2157_config)); | 1626 | memset(&si2157_config, 0, sizeof(si2157_config)); |
| 1621 | si2157_config.fe = adap->fe[0]; | 1627 | si2157_config.fe = adap->fe[0]; |
| 1622 | si2157_config.if_port = 1; | 1628 | si2157_config.if_port = it930x_addresses_table[state->it930x_addresses].tuner_if_port; |
| 1623 | ret = af9035_add_i2c_dev(d, "si2157", 0x63, | 1629 | ret = af9035_add_i2c_dev(d, "si2157", |
| 1624 | &si2157_config, state->i2c_adapter_demod); | 1630 | it930x_addresses_table[state->it930x_addresses].tuner_i2c_addr, |
| 1625 | 1631 | &si2157_config, state->i2c_adapter_demod); | |
| 1626 | if (ret) | 1632 | if (ret) |
| 1627 | goto err; | 1633 | goto err; |
| 1628 | 1634 | ||
| @@ -2128,6 +2134,8 @@ static const struct usb_device_id af9035_id_table[] = { | |||
| 2128 | /* IT930x devices */ | 2134 | /* IT930x devices */ |
| 2129 | { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303, | 2135 | { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303, |
| 2130 | &it930x_props, "ITE 9303 Generic", NULL) }, | 2136 | &it930x_props, "ITE 9303 Generic", NULL) }, |
| 2137 | { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310, | ||
| 2138 | &it930x_props, "AVerMedia TD310 DVB-T2", NULL) }, | ||
| 2131 | { } | 2139 | { } |
| 2132 | }; | 2140 | }; |
| 2133 | MODULE_DEVICE_TABLE(usb, af9035_id_table); | 2141 | MODULE_DEVICE_TABLE(usb, af9035_id_table); |
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h index a76e6bf0ab1e..bc41c16f9727 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.h +++ b/drivers/media/usb/dvb-usb-v2/af9035.h | |||
| @@ -69,6 +69,7 @@ struct state { | |||
| 69 | u8 dual_mode:1; | 69 | u8 dual_mode:1; |
| 70 | u8 no_read:1; | 70 | u8 no_read:1; |
| 71 | u8 af9033_i2c_addr[2]; | 71 | u8 af9033_i2c_addr[2]; |
| 72 | u8 it930x_addresses; | ||
| 72 | struct af9033_config af9033_config[2]; | 73 | struct af9033_config af9033_config[2]; |
| 73 | struct af9033_ops ops; | 74 | struct af9033_ops ops; |
| 74 | #define AF9035_I2C_CLIENT_MAX 4 | 75 | #define AF9035_I2C_CLIENT_MAX 4 |
| @@ -77,6 +78,17 @@ struct state { | |||
| 77 | struct platform_device *platform_device_tuner[2]; | 78 | struct platform_device *platform_device_tuner[2]; |
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 81 | struct address_table { | ||
| 82 | u8 frontend_i2c_addr; | ||
| 83 | u8 tuner_i2c_addr; | ||
| 84 | u8 tuner_if_port; | ||
| 85 | }; | ||
| 86 | |||
| 87 | static const struct address_table it930x_addresses_table[] = { | ||
| 88 | { 0x67, 0x63, 1 }, | ||
| 89 | { 0x64, 0x60, 0 }, | ||
| 90 | }; | ||
| 91 | |||
| 80 | static const u32 clock_lut_af9035[] = { | 92 | static const u32 clock_lut_af9035[] = { |
| 81 | 20480000, /* FPGA */ | 93 | 20480000, /* FPGA */ |
| 82 | 16384000, /* 16.38 MHz */ | 94 | 16384000, /* 16.38 MHz */ |
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index e28bd8836751..ae0814dd202a 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c | |||
| @@ -615,16 +615,18 @@ static int dvbsky_init(struct dvb_usb_device *d) | |||
| 615 | return 0; | 615 | return 0; |
| 616 | } | 616 | } |
| 617 | 617 | ||
| 618 | static void dvbsky_exit(struct dvb_usb_device *d) | 618 | static int dvbsky_frontend_detach(struct dvb_usb_adapter *adap) |
| 619 | { | 619 | { |
| 620 | struct dvb_usb_device *d = adap_to_d(adap); | ||
| 620 | struct dvbsky_state *state = d_to_priv(d); | 621 | struct dvbsky_state *state = d_to_priv(d); |
| 621 | struct dvb_usb_adapter *adap = &d->adapter[0]; | 622 | |
| 623 | dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id); | ||
| 622 | 624 | ||
| 623 | dvb_module_release(state->i2c_client_tuner); | 625 | dvb_module_release(state->i2c_client_tuner); |
| 624 | dvb_module_release(state->i2c_client_demod); | 626 | dvb_module_release(state->i2c_client_demod); |
| 625 | dvb_module_release(state->i2c_client_ci); | 627 | dvb_module_release(state->i2c_client_ci); |
| 626 | 628 | ||
| 627 | adap->fe[0] = NULL; | 629 | return 0; |
| 628 | } | 630 | } |
| 629 | 631 | ||
| 630 | /* DVB USB Driver stuff */ | 632 | /* DVB USB Driver stuff */ |
| @@ -640,11 +642,11 @@ static struct dvb_usb_device_properties dvbsky_s960_props = { | |||
| 640 | 642 | ||
| 641 | .i2c_algo = &dvbsky_i2c_algo, | 643 | .i2c_algo = &dvbsky_i2c_algo, |
| 642 | .frontend_attach = dvbsky_s960_attach, | 644 | .frontend_attach = dvbsky_s960_attach, |
| 645 | .frontend_detach = dvbsky_frontend_detach, | ||
| 643 | .init = dvbsky_init, | 646 | .init = dvbsky_init, |
| 644 | .get_rc_config = dvbsky_get_rc_config, | 647 | .get_rc_config = dvbsky_get_rc_config, |
| 645 | .streaming_ctrl = dvbsky_streaming_ctrl, | 648 | .streaming_ctrl = dvbsky_streaming_ctrl, |
| 646 | .identify_state = dvbsky_identify_state, | 649 | .identify_state = dvbsky_identify_state, |
| 647 | .exit = dvbsky_exit, | ||
| 648 | .read_mac_address = dvbsky_read_mac_addr, | 650 | .read_mac_address = dvbsky_read_mac_addr, |
| 649 | 651 | ||
| 650 | .num_adapters = 1, | 652 | .num_adapters = 1, |
| @@ -667,11 +669,11 @@ static struct dvb_usb_device_properties dvbsky_s960c_props = { | |||
| 667 | 669 | ||
| 668 | .i2c_algo = &dvbsky_i2c_algo, | 670 | .i2c_algo = &dvbsky_i2c_algo, |
| 669 | .frontend_attach = dvbsky_s960c_attach, | 671 | .frontend_attach = dvbsky_s960c_attach, |
| 672 | .frontend_detach = dvbsky_frontend_detach, | ||
| 670 | .init = dvbsky_init, | 673 | .init = dvbsky_init, |
| 671 | .get_rc_config = dvbsky_get_rc_config, | 674 | .get_rc_config = dvbsky_get_rc_config, |
| 672 | .streaming_ctrl = dvbsky_streaming_ctrl, | 675 | .streaming_ctrl = dvbsky_streaming_ctrl, |
| 673 | .identify_state = dvbsky_identify_state, | 676 | .identify_state = dvbsky_identify_state, |
| 674 | .exit = dvbsky_exit, | ||
| 675 | .read_mac_address = dvbsky_read_mac_addr, | 677 | .read_mac_address = dvbsky_read_mac_addr, |
| 676 | 678 | ||
| 677 | .num_adapters = 1, | 679 | .num_adapters = 1, |
| @@ -694,11 +696,11 @@ static struct dvb_usb_device_properties dvbsky_t680c_props = { | |||
| 694 | 696 | ||
| 695 | .i2c_algo = &dvbsky_i2c_algo, | 697 | .i2c_algo = &dvbsky_i2c_algo, |
| 696 | .frontend_attach = dvbsky_t680c_attach, | 698 | .frontend_attach = dvbsky_t680c_attach, |
| 699 | .frontend_detach = dvbsky_frontend_detach, | ||
| 697 | .init = dvbsky_init, | 700 | .init = dvbsky_init, |
| 698 | .get_rc_config = dvbsky_get_rc_config, | 701 | .get_rc_config = dvbsky_get_rc_config, |
| 699 | .streaming_ctrl = dvbsky_streaming_ctrl, | 702 | .streaming_ctrl = dvbsky_streaming_ctrl, |
| 700 | .identify_state = dvbsky_identify_state, | 703 | .identify_state = dvbsky_identify_state, |
| 701 | .exit = dvbsky_exit, | ||
| 702 | .read_mac_address = dvbsky_read_mac_addr, | 704 | .read_mac_address = dvbsky_read_mac_addr, |
| 703 | 705 | ||
| 704 | .num_adapters = 1, | 706 | .num_adapters = 1, |
| @@ -721,11 +723,11 @@ static struct dvb_usb_device_properties dvbsky_t330_props = { | |||
| 721 | 723 | ||
| 722 | .i2c_algo = &dvbsky_i2c_algo, | 724 | .i2c_algo = &dvbsky_i2c_algo, |
| 723 | .frontend_attach = dvbsky_t330_attach, | 725 | .frontend_attach = dvbsky_t330_attach, |
| 726 | .frontend_detach = dvbsky_frontend_detach, | ||
| 724 | .init = dvbsky_init, | 727 | .init = dvbsky_init, |
| 725 | .get_rc_config = dvbsky_get_rc_config, | 728 | .get_rc_config = dvbsky_get_rc_config, |
| 726 | .streaming_ctrl = dvbsky_streaming_ctrl, | 729 | .streaming_ctrl = dvbsky_streaming_ctrl, |
| 727 | .identify_state = dvbsky_identify_state, | 730 | .identify_state = dvbsky_identify_state, |
| 728 | .exit = dvbsky_exit, | ||
| 729 | .read_mac_address = dvbsky_read_mac_addr, | 731 | .read_mac_address = dvbsky_read_mac_addr, |
| 730 | 732 | ||
| 731 | .num_adapters = 1, | 733 | .num_adapters = 1, |
| @@ -748,11 +750,11 @@ static struct dvb_usb_device_properties mygica_t230c_props = { | |||
| 748 | 750 | ||
| 749 | .i2c_algo = &dvbsky_i2c_algo, | 751 | .i2c_algo = &dvbsky_i2c_algo, |
| 750 | .frontend_attach = dvbsky_mygica_t230c_attach, | 752 | .frontend_attach = dvbsky_mygica_t230c_attach, |
| 753 | .frontend_detach = dvbsky_frontend_detach, | ||
| 751 | .init = dvbsky_init, | 754 | .init = dvbsky_init, |
| 752 | .get_rc_config = dvbsky_get_rc_config, | 755 | .get_rc_config = dvbsky_get_rc_config, |
| 753 | .streaming_ctrl = dvbsky_streaming_ctrl, | 756 | .streaming_ctrl = dvbsky_streaming_ctrl, |
| 754 | .identify_state = dvbsky_identify_state, | 757 | .identify_state = dvbsky_identify_state, |
| 755 | .exit = dvbsky_exit, | ||
| 756 | 758 | ||
| 757 | .num_adapters = 1, | 759 | .num_adapters = 1, |
| 758 | .adapter = { | 760 | .adapter = { |
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig index 451e076525d3..639da7e24066 100644 --- a/drivers/media/usb/em28xx/Kconfig +++ b/drivers/media/usb/em28xx/Kconfig | |||
| @@ -13,7 +13,7 @@ config VIDEO_EM28XX_V4L2 | |||
| 13 | select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT | 13 | select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | 14 | select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT |
| 15 | select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | 15 | select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT |
| 16 | ---help--- | 16 | help |
| 17 | This is a video4linux driver for Empia 28xx based TV cards. | 17 | This is a video4linux driver for Empia 28xx based TV cards. |
| 18 | 18 | ||
| 19 | To compile this driver as a module, choose M here: the | 19 | To compile this driver as a module, choose M here: the |
| @@ -23,7 +23,7 @@ config VIDEO_EM28XX_ALSA | |||
| 23 | depends on VIDEO_EM28XX && SND | 23 | depends on VIDEO_EM28XX && SND |
| 24 | select SND_PCM | 24 | select SND_PCM |
| 25 | tristate "Empia EM28xx ALSA audio module" | 25 | tristate "Empia EM28xx ALSA audio module" |
| 26 | ---help--- | 26 | help |
| 27 | This is an ALSA driver for some Empia 28xx based TV cards. | 27 | This is an ALSA driver for some Empia 28xx based TV cards. |
| 28 | 28 | ||
| 29 | This is not required for em2800/em2820/em2821 boards. However, | 29 | This is not required for em2800/em2820/em2821 boards. However, |
| @@ -66,7 +66,7 @@ config VIDEO_EM28XX_DVB | |||
| 66 | select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT | 66 | select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT |
| 67 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT | 67 | select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT |
| 68 | select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT | 68 | select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT |
| 69 | ---help--- | 69 | help |
| 70 | This adds support for DVB cards based on the | 70 | This adds support for DVB cards based on the |
| 71 | Empiatech em28xx chips. | 71 | Empiatech em28xx chips. |
| 72 | 72 | ||
| @@ -76,5 +76,5 @@ config VIDEO_EM28XX_RC | |||
| 76 | depends on VIDEO_EM28XX | 76 | depends on VIDEO_EM28XX |
| 77 | depends on !(RC_CORE=m && VIDEO_EM28XX=y) | 77 | depends on !(RC_CORE=m && VIDEO_EM28XX=y) |
| 78 | default VIDEO_EM28XX | 78 | default VIDEO_EM28XX |
| 79 | ---help--- | 79 | help |
| 80 | Enables Remote Controller support on em28xx driver. | 80 | Enables Remote Controller support on em28xx driver. |
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index f84a1208d5d3..d85ea1af6aa1 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c | |||
| @@ -499,7 +499,7 @@ static int em28xx_probe_i2c_ir(struct em28xx *dev) | |||
| 499 | * at address 0x18, so if that address is needed for another board in | 499 | * at address 0x18, so if that address is needed for another board in |
| 500 | * the future, please put it after 0x1f. | 500 | * the future, please put it after 0x1f. |
| 501 | */ | 501 | */ |
| 502 | const unsigned short addr_list[] = { | 502 | static const unsigned short addr_list[] = { |
| 503 | 0x1f, 0x30, 0x47, I2C_CLIENT_END | 503 | 0x1f, 0x30, 0x47, I2C_CLIENT_END |
| 504 | }; | 504 | }; |
| 505 | 505 | ||
diff --git a/drivers/media/usb/go7007/Kconfig b/drivers/media/usb/go7007/Kconfig index af1d02430931..beab257c092f 100644 --- a/drivers/media/usb/go7007/Kconfig +++ b/drivers/media/usb/go7007/Kconfig | |||
| @@ -13,7 +13,7 @@ config VIDEO_GO7007 | |||
| 13 | select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT | 13 | select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT |
| 14 | select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT | 14 | select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT |
| 15 | select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT | 15 | select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT |
| 16 | ---help--- | 16 | help |
| 17 | This is a video4linux driver for the WIS GO7007 MPEG | 17 | This is a video4linux driver for the WIS GO7007 MPEG |
| 18 | encoder chip. | 18 | encoder chip. |
| 19 | 19 | ||
| @@ -23,7 +23,7 @@ config VIDEO_GO7007 | |||
| 23 | config VIDEO_GO7007_USB | 23 | config VIDEO_GO7007_USB |
| 24 | tristate "WIS GO7007 USB support" | 24 | tristate "WIS GO7007 USB support" |
| 25 | depends on VIDEO_GO7007 && USB | 25 | depends on VIDEO_GO7007 && USB |
| 26 | ---help--- | 26 | help |
| 27 | This is a video4linux driver for the WIS GO7007 MPEG | 27 | This is a video4linux driver for the WIS GO7007 MPEG |
| 28 | encoder chip over USB. | 28 | encoder chip over USB. |
| 29 | 29 | ||
| @@ -34,7 +34,7 @@ config VIDEO_GO7007_LOADER | |||
| 34 | tristate "WIS GO7007 Loader support" | 34 | tristate "WIS GO7007 Loader support" |
| 35 | depends on VIDEO_GO7007 | 35 | depends on VIDEO_GO7007 |
| 36 | default y | 36 | default y |
| 37 | ---help--- | 37 | help |
| 38 | This is a go7007 firmware loader driver for the WIS GO7007 | 38 | This is a go7007 firmware loader driver for the WIS GO7007 |
| 39 | MPEG encoder chip over USB. | 39 | MPEG encoder chip over USB. |
| 40 | 40 | ||
| @@ -44,7 +44,7 @@ config VIDEO_GO7007_LOADER | |||
| 44 | config VIDEO_GO7007_USB_S2250_BOARD | 44 | config VIDEO_GO7007_USB_S2250_BOARD |
| 45 | tristate "Sensoray 2250/2251 support" | 45 | tristate "Sensoray 2250/2251 support" |
| 46 | depends on VIDEO_GO7007_USB && USB | 46 | depends on VIDEO_GO7007_USB && USB |
| 47 | ---help--- | 47 | help |
| 48 | This is a video4linux driver for the Sensoray 2250/2251 device. | 48 | This is a video4linux driver for the Sensoray 2250/2251 device. |
| 49 | 49 | ||
| 50 | To compile this driver as a module, choose M here: the | 50 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c index 24f5b615dc7a..dfa9f899d0c2 100644 --- a/drivers/media/usb/go7007/go7007-fw.c +++ b/drivers/media/usb/go7007/go7007-fw.c | |||
| @@ -1499,8 +1499,8 @@ static int modet_to_package(struct go7007 *go, __le16 *code, int space) | |||
| 1499 | return cnt; | 1499 | return cnt; |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| 1502 | static int do_special(struct go7007 *go, u16 type, __le16 *code, int space, | 1502 | static noinline_for_stack int do_special(struct go7007 *go, u16 type, |
| 1503 | int *framelen) | 1503 | __le16 *code, int space, int *framelen) |
| 1504 | { | 1504 | { |
| 1505 | switch (type) { | 1505 | switch (type) { |
| 1506 | case SPECIAL_FRM_HEAD: | 1506 | case SPECIAL_FRM_HEAD: |
diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c index 19c6a0354ce0..abe98488be23 100644 --- a/drivers/media/usb/go7007/go7007-usb.c +++ b/drivers/media/usb/go7007/go7007-usb.c | |||
| @@ -1132,7 +1132,7 @@ static int go7007_usb_probe(struct usb_interface *intf, | |||
| 1132 | usb->usbdev = usbdev; | 1132 | usb->usbdev = usbdev; |
| 1133 | usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info)); | 1133 | usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info)); |
| 1134 | go->board_id = id->driver_info; | 1134 | go->board_id = id->driver_info; |
| 1135 | strncpy(go->name, name, sizeof(go->name)); | 1135 | strscpy(go->name, name, sizeof(go->name)); |
| 1136 | if (board->flags & GO7007_USB_EZUSB) | 1136 | if (board->flags & GO7007_USB_EZUSB) |
| 1137 | go->hpi_ops = &go7007_usb_ezusb_hpi_ops; | 1137 | go->hpi_ops = &go7007_usb_ezusb_hpi_ops; |
| 1138 | else | 1138 | else |
| @@ -1198,7 +1198,7 @@ static int go7007_usb_probe(struct usb_interface *intf, | |||
| 1198 | go->board_id = GO7007_BOARDID_ENDURA; | 1198 | go->board_id = GO7007_BOARDID_ENDURA; |
| 1199 | usb->board = board = &board_endura; | 1199 | usb->board = board = &board_endura; |
| 1200 | go->board_info = &board->main_info; | 1200 | go->board_info = &board->main_info; |
| 1201 | strncpy(go->name, "Pelco Endura", | 1201 | strscpy(go->name, "Pelco Endura", |
| 1202 | sizeof(go->name)); | 1202 | sizeof(go->name)); |
| 1203 | } else { | 1203 | } else { |
| 1204 | u16 channel; | 1204 | u16 channel; |
| @@ -1232,21 +1232,21 @@ static int go7007_usb_probe(struct usb_interface *intf, | |||
| 1232 | case 1: | 1232 | case 1: |
| 1233 | go->tuner_type = TUNER_SONY_BTF_PG472Z; | 1233 | go->tuner_type = TUNER_SONY_BTF_PG472Z; |
| 1234 | go->std = V4L2_STD_PAL; | 1234 | go->std = V4L2_STD_PAL; |
| 1235 | strncpy(go->name, "Plextor PX-TV402U-EU", | 1235 | strscpy(go->name, "Plextor PX-TV402U-EU", |
| 1236 | sizeof(go->name)); | 1236 | sizeof(go->name)); |
| 1237 | break; | 1237 | break; |
| 1238 | case 2: | 1238 | case 2: |
| 1239 | go->tuner_type = TUNER_SONY_BTF_PK467Z; | 1239 | go->tuner_type = TUNER_SONY_BTF_PK467Z; |
| 1240 | go->std = V4L2_STD_NTSC_M_JP; | 1240 | go->std = V4L2_STD_NTSC_M_JP; |
| 1241 | num_i2c_devs -= 2; | 1241 | num_i2c_devs -= 2; |
| 1242 | strncpy(go->name, "Plextor PX-TV402U-JP", | 1242 | strscpy(go->name, "Plextor PX-TV402U-JP", |
| 1243 | sizeof(go->name)); | 1243 | sizeof(go->name)); |
| 1244 | break; | 1244 | break; |
| 1245 | case 3: | 1245 | case 3: |
| 1246 | go->tuner_type = TUNER_SONY_BTF_PB463Z; | 1246 | go->tuner_type = TUNER_SONY_BTF_PB463Z; |
| 1247 | num_i2c_devs -= 2; | 1247 | num_i2c_devs -= 2; |
| 1248 | strncpy(go->name, "Plextor PX-TV402U-NA", | 1248 | strscpy(go->name, "Plextor PX-TV402U-NA", |
| 1249 | sizeof(go->name)); | 1249 | sizeof(go->name)); |
| 1250 | break; | 1250 | break; |
| 1251 | default: | 1251 | default: |
| 1252 | pr_debug("unable to detect tuner type!\n"); | 1252 | pr_debug("unable to detect tuner type!\n"); |
diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index 7a2781fa83e7..bebdfcecf600 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c | |||
| @@ -327,7 +327,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | |||
| 327 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 327 | fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 328 | fmt->flags = V4L2_FMT_FLAG_COMPRESSED; | 328 | fmt->flags = V4L2_FMT_FLAG_COMPRESSED; |
| 329 | 329 | ||
| 330 | strncpy(fmt->description, desc, sizeof(fmt->description)); | 330 | strscpy(fmt->description, desc, sizeof(fmt->description)); |
| 331 | 331 | ||
| 332 | return 0; | 332 | return 0; |
| 333 | } | 333 | } |
diff --git a/drivers/media/usb/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig index 088566e88467..0e6f36cb46e6 100644 --- a/drivers/media/usb/gspca/Kconfig +++ b/drivers/media/usb/gspca/Kconfig | |||
| @@ -4,7 +4,7 @@ menuconfig USB_GSPCA | |||
| 4 | depends on INPUT || INPUT=n | 4 | depends on INPUT || INPUT=n |
| 5 | select VIDEOBUF2_VMALLOC | 5 | select VIDEOBUF2_VMALLOC |
| 6 | default m | 6 | default m |
| 7 | ---help--- | 7 | help |
| 8 | Say Y here if you want to enable selecting webcams based | 8 | Say Y here if you want to enable selecting webcams based |
| 9 | on the GSPCA framework. | 9 | on the GSPCA framework. |
| 10 | 10 | ||
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index ac70b36d67b7..4d7517411cc2 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c | |||
| @@ -294,7 +294,7 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
| 294 | /* check the packet status and length */ | 294 | /* check the packet status and length */ |
| 295 | st = urb->iso_frame_desc[i].status; | 295 | st = urb->iso_frame_desc[i].status; |
| 296 | if (st) { | 296 | if (st) { |
| 297 | pr_err("ISOC data error: [%d] len=%d, status=%d\n", | 297 | gspca_dbg(gspca_dev, D_PACK, "ISOC data error: [%d] len=%d, status=%d\n", |
| 298 | i, len, st); | 298 | i, len, st); |
| 299 | gspca_dev->last_packet_type = DISCARD_PACKET; | 299 | gspca_dev->last_packet_type = DISCARD_PACKET; |
| 300 | continue; | 300 | continue; |
| @@ -314,6 +314,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, | |||
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | resubmit: | 316 | resubmit: |
| 317 | if (!gspca_dev->streaming) | ||
| 318 | return; | ||
| 317 | /* resubmit the URB */ | 319 | /* resubmit the URB */ |
| 318 | st = usb_submit_urb(urb, GFP_ATOMIC); | 320 | st = usb_submit_urb(urb, GFP_ATOMIC); |
| 319 | if (st < 0) | 321 | if (st < 0) |
| @@ -330,7 +332,7 @@ static void isoc_irq(struct urb *urb) | |||
| 330 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; | 332 | struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; |
| 331 | 333 | ||
| 332 | gspca_dbg(gspca_dev, D_PACK, "isoc irq\n"); | 334 | gspca_dbg(gspca_dev, D_PACK, "isoc irq\n"); |
| 333 | if (!vb2_start_streaming_called(&gspca_dev->queue)) | 335 | if (!gspca_dev->streaming) |
| 334 | return; | 336 | return; |
| 335 | fill_frame(gspca_dev, urb); | 337 | fill_frame(gspca_dev, urb); |
| 336 | } | 338 | } |
| @@ -344,7 +346,7 @@ static void bulk_irq(struct urb *urb) | |||
| 344 | int st; | 346 | int st; |
| 345 | 347 | ||
| 346 | gspca_dbg(gspca_dev, D_PACK, "bulk irq\n"); | 348 | gspca_dbg(gspca_dev, D_PACK, "bulk irq\n"); |
| 347 | if (!vb2_start_streaming_called(&gspca_dev->queue)) | 349 | if (!gspca_dev->streaming) |
| 348 | return; | 350 | return; |
| 349 | switch (urb->status) { | 351 | switch (urb->status) { |
| 350 | case 0: | 352 | case 0: |
| @@ -367,6 +369,8 @@ static void bulk_irq(struct urb *urb) | |||
| 367 | urb->actual_length); | 369 | urb->actual_length); |
| 368 | 370 | ||
| 369 | resubmit: | 371 | resubmit: |
| 372 | if (!gspca_dev->streaming) | ||
| 373 | return; | ||
| 370 | /* resubmit the URB */ | 374 | /* resubmit the URB */ |
| 371 | if (gspca_dev->cam.bulk_nurbs != 0) { | 375 | if (gspca_dev->cam.bulk_nurbs != 0) { |
| 372 | st = usb_submit_urb(urb, GFP_ATOMIC); | 376 | st = usb_submit_urb(urb, GFP_ATOMIC); |
| @@ -1638,6 +1642,8 @@ void gspca_disconnect(struct usb_interface *intf) | |||
| 1638 | 1642 | ||
| 1639 | mutex_lock(&gspca_dev->usb_lock); | 1643 | mutex_lock(&gspca_dev->usb_lock); |
| 1640 | gspca_dev->present = false; | 1644 | gspca_dev->present = false; |
| 1645 | destroy_urbs(gspca_dev); | ||
| 1646 | gspca_input_destroy_urb(gspca_dev); | ||
| 1641 | 1647 | ||
| 1642 | vb2_queue_error(&gspca_dev->queue); | 1648 | vb2_queue_error(&gspca_dev->queue); |
| 1643 | 1649 | ||
diff --git a/drivers/media/usb/hackrf/Kconfig b/drivers/media/usb/hackrf/Kconfig index 937e6f5c1e8e..072e186018f5 100644 --- a/drivers/media/usb/hackrf/Kconfig +++ b/drivers/media/usb/hackrf/Kconfig | |||
| @@ -2,7 +2,7 @@ config USB_HACKRF | |||
| 2 | tristate "HackRF" | 2 | tristate "HackRF" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | ---help--- | 5 | help |
| 6 | This is a video4linux2 driver for HackRF SDR device. | 6 | This is a video4linux2 driver for HackRF SDR device. |
| 7 | 7 | ||
| 8 | To compile this driver as a module, choose M here: the | 8 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/hdpvr/Kconfig b/drivers/media/usb/hdpvr/Kconfig index d73d9a1952b4..9e78c0c32651 100644 --- a/drivers/media/usb/hdpvr/Kconfig +++ b/drivers/media/usb/hdpvr/Kconfig | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | config VIDEO_HDPVR | 2 | config VIDEO_HDPVR |
| 3 | tristate "Hauppauge HD PVR support" | 3 | tristate "Hauppauge HD PVR support" |
| 4 | depends on VIDEO_DEV && VIDEO_V4L2 | 4 | depends on VIDEO_DEV && VIDEO_V4L2 |
| 5 | ---help--- | 5 | help |
| 6 | This is a video4linux driver for Hauppauge's HD PVR USB device. | 6 | This is a video4linux driver for Hauppauge's HD PVR USB device. |
| 7 | 7 | ||
| 8 | To compile this driver as a module, choose M here: the | 8 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index e082086428a4..3804aa3fb50f 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c | |||
| @@ -769,8 +769,7 @@ static int vidioc_enum_input(struct file *file, void *_fh, struct v4l2_input *i) | |||
| 769 | 769 | ||
| 770 | i->type = V4L2_INPUT_TYPE_CAMERA; | 770 | i->type = V4L2_INPUT_TYPE_CAMERA; |
| 771 | 771 | ||
| 772 | strncpy(i->name, iname[n], sizeof(i->name) - 1); | 772 | strscpy(i->name, iname[n], sizeof(i->name)); |
| 773 | i->name[sizeof(i->name) - 1] = '\0'; | ||
| 774 | 773 | ||
| 775 | i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF; | 774 | i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF; |
| 776 | 775 | ||
| @@ -841,8 +840,7 @@ static int vidioc_enumaudio(struct file *file, void *priv, | |||
| 841 | 840 | ||
| 842 | audio->capability = V4L2_AUDCAP_STEREO; | 841 | audio->capability = V4L2_AUDCAP_STEREO; |
| 843 | 842 | ||
| 844 | strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1); | 843 | strscpy(audio->name, audio_iname[n], sizeof(audio->name)); |
| 845 | audio->name[sizeof(audio->name) - 1] = '\0'; | ||
| 846 | 844 | ||
| 847 | return 0; | 845 | return 0; |
| 848 | } | 846 | } |
| @@ -874,7 +872,6 @@ static int vidioc_g_audio(struct file *file, void *private_data, | |||
| 874 | audio->index = dev->options.audio_input; | 872 | audio->index = dev->options.audio_input; |
| 875 | audio->capability = V4L2_AUDCAP_STEREO; | 873 | audio->capability = V4L2_AUDCAP_STEREO; |
| 876 | strscpy(audio->name, audio_iname[audio->index], sizeof(audio->name)); | 874 | strscpy(audio->name, audio_iname[audio->index], sizeof(audio->name)); |
| 877 | audio->name[sizeof(audio->name) - 1] = '\0'; | ||
| 878 | return 0; | 875 | return 0; |
| 879 | } | 876 | } |
| 880 | 877 | ||
| @@ -991,7 +988,8 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, | |||
| 991 | return -EINVAL; | 988 | return -EINVAL; |
| 992 | 989 | ||
| 993 | f->flags = V4L2_FMT_FLAG_COMPRESSED; | 990 | f->flags = V4L2_FMT_FLAG_COMPRESSED; |
| 994 | strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32); | 991 | strscpy(f->description, "MPEG2-TS with AVC/AAC streams", |
| 992 | sizeof(f->description)); | ||
| 995 | f->pixelformat = V4L2_PIX_FMT_MPEG; | 993 | f->pixelformat = V4L2_PIX_FMT_MPEG; |
| 996 | 994 | ||
| 997 | return 0; | 995 | return 0; |
diff --git a/drivers/media/usb/pulse8-cec/Kconfig b/drivers/media/usb/pulse8-cec/Kconfig index 18ead44824ba..11f1b75d3efd 100644 --- a/drivers/media/usb/pulse8-cec/Kconfig +++ b/drivers/media/usb/pulse8-cec/Kconfig | |||
| @@ -4,7 +4,7 @@ config USB_PULSE8_CEC | |||
| 4 | select CEC_CORE | 4 | select CEC_CORE |
| 5 | select SERIO | 5 | select SERIO |
| 6 | select SERIO_SERPORT | 6 | select SERIO_SERPORT |
| 7 | ---help--- | 7 | help |
| 8 | This is a cec driver for the Pulse Eight HDMI CEC device. | 8 | This is a cec driver for the Pulse Eight HDMI CEC device. |
| 9 | 9 | ||
| 10 | To compile this driver as a module, choose M here: the | 10 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index b085b14f3f87..ea9ee74fa336 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c | |||
| @@ -435,7 +435,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, | |||
| 435 | err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); | 435 | err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 0); |
| 436 | if (err) | 436 | if (err) |
| 437 | return err; | 437 | return err; |
| 438 | strncpy(log_addrs->osd_name, data, 13); | 438 | strscpy(log_addrs->osd_name, data, sizeof(log_addrs->osd_name)); |
| 439 | dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); | 439 | dev_dbg(pulse8->dev, "OSD name: %s\n", log_addrs->osd_name); |
| 440 | 440 | ||
| 441 | return 0; | 441 | return 0; |
| @@ -566,7 +566,7 @@ static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) | |||
| 566 | char *osd_str = cmd + 1; | 566 | char *osd_str = cmd + 1; |
| 567 | 567 | ||
| 568 | cmd[0] = MSGCODE_SET_OSD_NAME; | 568 | cmd[0] = MSGCODE_SET_OSD_NAME; |
| 569 | strncpy(cmd + 1, adap->log_addrs.osd_name, 13); | 569 | strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1); |
| 570 | if (osd_len < 4) { | 570 | if (osd_len < 4) { |
| 571 | memset(osd_str + osd_len, ' ', 4 - osd_len); | 571 | memset(osd_str + osd_len, ' ', 4 - osd_len); |
| 572 | osd_len = 4; | 572 | osd_len = 4; |
diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig index 1ad913fc30bf..ac6612cf1bec 100644 --- a/drivers/media/usb/pvrusb2/Kconfig +++ b/drivers/media/usb/pvrusb2/Kconfig | |||
| @@ -9,7 +9,7 @@ config VIDEO_PVRUSB2 | |||
| 9 | select VIDEO_MSP3400 | 9 | select VIDEO_MSP3400 |
| 10 | select VIDEO_WM8775 | 10 | select VIDEO_WM8775 |
| 11 | select VIDEO_CS53L32A | 11 | select VIDEO_CS53L32A |
| 12 | ---help--- | 12 | help |
| 13 | This is a video4linux driver for Conexant 23416 based | 13 | This is a video4linux driver for Conexant 23416 based |
| 14 | usb2 personal video recorder devices. | 14 | usb2 personal video recorder devices. |
| 15 | 15 | ||
| @@ -20,7 +20,7 @@ config VIDEO_PVRUSB2_SYSFS | |||
| 20 | bool "pvrusb2 sysfs support" | 20 | bool "pvrusb2 sysfs support" |
| 21 | default y | 21 | default y |
| 22 | depends on VIDEO_PVRUSB2 && SYSFS | 22 | depends on VIDEO_PVRUSB2 && SYSFS |
| 23 | ---help--- | 23 | help |
| 24 | This option enables the operation of a sysfs based | 24 | This option enables the operation of a sysfs based |
| 25 | interface for query and control of the pvrusb2 driver. | 25 | interface for query and control of the pvrusb2 driver. |
| 26 | 26 | ||
| @@ -43,7 +43,7 @@ config VIDEO_PVRUSB2_DVB | |||
| 43 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT | 43 | select MEDIA_TUNER_TDA18271 if MEDIA_SUBDRV_AUTOSELECT |
| 44 | select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT | 44 | select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT |
| 45 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT | 45 | select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT |
| 46 | ---help--- | 46 | help |
| 47 | This option enables a DVB interface for the pvrusb2 driver. | 47 | This option enables a DVB interface for the pvrusb2 driver. |
| 48 | If your device does not support digital television, this | 48 | If your device does not support digital television, this |
| 49 | feature will have no affect on the driver's operation. | 49 | feature will have no affect on the driver's operation. |
| @@ -53,7 +53,7 @@ config VIDEO_PVRUSB2_DVB | |||
| 53 | config VIDEO_PVRUSB2_DEBUGIFC | 53 | config VIDEO_PVRUSB2_DEBUGIFC |
| 54 | bool "pvrusb2 debug interface" | 54 | bool "pvrusb2 debug interface" |
| 55 | depends on VIDEO_PVRUSB2_SYSFS | 55 | depends on VIDEO_PVRUSB2_SYSFS |
| 56 | ---help--- | 56 | help |
| 57 | This option enables the inclusion of a debug interface | 57 | This option enables the inclusion of a debug interface |
| 58 | in the pvrusb2 driver, hosted through sysfs. | 58 | in the pvrusb2 driver, hosted through sysfs. |
| 59 | 59 | ||
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 446a999dd2ce..816c85786c2a 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c | |||
| @@ -666,6 +666,8 @@ static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp) | |||
| 666 | 666 | ||
| 667 | static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) | 667 | static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) |
| 668 | { | 668 | { |
| 669 | if (v < 0 || v > PVR2_CVAL_INPUT_MAX) | ||
| 670 | return 0; | ||
| 669 | return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; | 671 | return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; |
| 670 | } | 672 | } |
| 671 | 673 | ||
| @@ -2459,9 +2461,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, | |||
| 2459 | if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { | 2461 | if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { |
| 2460 | ciptr->set_value = ctrl_cx2341x_set; | 2462 | ciptr->set_value = ctrl_cx2341x_set; |
| 2461 | } | 2463 | } |
| 2462 | strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, | 2464 | strscpy(hdw->mpeg_ctrl_info[idx].desc, qctrl.name, |
| 2463 | PVR2_CTLD_INFO_DESC_SIZE); | 2465 | sizeof(hdw->mpeg_ctrl_info[idx].desc)); |
| 2464 | hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; | ||
| 2465 | ciptr->default_value = qctrl.default_value; | 2466 | ciptr->default_value = qctrl.default_value; |
| 2466 | switch (qctrl.type) { | 2467 | switch (qctrl.type) { |
| 2467 | default: | 2468 | default: |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h index 25648add77e5..bd2b7a67b732 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #define PVR2_CVAL_INPUT_COMPOSITE 2 | 50 | #define PVR2_CVAL_INPUT_COMPOSITE 2 |
| 51 | #define PVR2_CVAL_INPUT_SVIDEO 3 | 51 | #define PVR2_CVAL_INPUT_SVIDEO 3 |
| 52 | #define PVR2_CVAL_INPUT_RADIO 4 | 52 | #define PVR2_CVAL_INPUT_RADIO 4 |
| 53 | #define PVR2_CVAL_INPUT_MAX PVR2_CVAL_INPUT_RADIO | ||
| 53 | 54 | ||
| 54 | enum pvr2_config { | 55 | enum pvr2_config { |
| 55 | pvr2_config_empty, /* No configuration */ | 56 | pvr2_config_empty, /* No configuration */ |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 08d5b7aa3537..cb6668580d77 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | |||
| @@ -284,7 +284,7 @@ static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin) | |||
| 284 | 284 | ||
| 285 | if (vin->index > 0) | 285 | if (vin->index > 0) |
| 286 | return -EINVAL; | 286 | return -EINVAL; |
| 287 | strncpy(vin->name, "PVRUSB2 Audio", 14); | 287 | strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name)); |
| 288 | vin->capability = V4L2_AUDCAP_STEREO; | 288 | vin->capability = V4L2_AUDCAP_STEREO; |
| 289 | return 0; | 289 | return 0; |
| 290 | } | 290 | } |
| @@ -293,7 +293,7 @@ static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin) | |||
| 293 | { | 293 | { |
| 294 | /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */ | 294 | /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */ |
| 295 | vin->index = 0; | 295 | vin->index = 0; |
| 296 | strncpy(vin->name, "PVRUSB2 Audio", 14); | 296 | strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name)); |
| 297 | vin->capability = V4L2_AUDCAP_STEREO; | 297 | vin->capability = V4L2_AUDCAP_STEREO; |
| 298 | return 0; | 298 | return 0; |
| 299 | } | 299 | } |
diff --git a/drivers/media/usb/pwc/Kconfig b/drivers/media/usb/pwc/Kconfig index d63d0a850035..5f6d91edca41 100644 --- a/drivers/media/usb/pwc/Kconfig +++ b/drivers/media/usb/pwc/Kconfig | |||
| @@ -2,7 +2,7 @@ config USB_PWC | |||
| 2 | tristate "USB Philips Cameras" | 2 | tristate "USB Philips Cameras" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | ---help--- | 5 | help |
| 6 | Say Y or M here if you want to use one of these Philips & OEM | 6 | Say Y or M here if you want to use one of these Philips & OEM |
| 7 | webcams: | 7 | webcams: |
| 8 | * Philips PCA645, PCA646 | 8 | * Philips PCA645, PCA646 |
| @@ -41,7 +41,7 @@ config USB_PWC_INPUT_EVDEV | |||
| 41 | bool "USB Philips Cameras input events device support" | 41 | bool "USB Philips Cameras input events device support" |
| 42 | default y | 42 | default y |
| 43 | depends on USB_PWC && (USB_PWC=INPUT || INPUT=y) | 43 | depends on USB_PWC && (USB_PWC=INPUT || INPUT=y) |
| 44 | ---help--- | 44 | help |
| 45 | This option makes USB Philips cameras register the snapshot button as | 45 | This option makes USB Philips cameras register the snapshot button as |
| 46 | an input device to report button events. | 46 | an input device to report button events. |
| 47 | 47 | ||
diff --git a/drivers/media/usb/pwc/pwc-ctrl.c b/drivers/media/usb/pwc/pwc-ctrl.c index 655cef39eb3d..b681a184ef87 100644 --- a/drivers/media/usb/pwc/pwc-ctrl.c +++ b/drivers/media/usb/pwc/pwc-ctrl.c | |||
| @@ -242,14 +242,14 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, | |||
| 242 | fps = (frames / 5) - 1; | 242 | fps = (frames / 5) - 1; |
| 243 | 243 | ||
| 244 | /* Find a supported framerate with progressively higher compression */ | 244 | /* Find a supported framerate with progressively higher compression */ |
| 245 | pChoose = NULL; | 245 | do { |
| 246 | while (*compression <= 3) { | ||
| 247 | pChoose = &Timon_table[size][fps][*compression]; | 246 | pChoose = &Timon_table[size][fps][*compression]; |
| 248 | if (pChoose->alternate != 0) | 247 | if (pChoose->alternate != 0) |
| 249 | break; | 248 | break; |
| 250 | (*compression)++; | 249 | (*compression)++; |
| 251 | } | 250 | } while (*compression <= 3); |
| 252 | if (pChoose == NULL || pChoose->alternate == 0) | 251 | |
| 252 | if (pChoose->alternate == 0) | ||
| 253 | return -ENOENT; /* Not supported. */ | 253 | return -ENOENT; /* Not supported. */ |
| 254 | 254 | ||
| 255 | if (send_to_cam) | 255 | if (send_to_cam) |
| @@ -279,7 +279,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int pixfmt, | |||
| 279 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt, | 279 | static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt, |
| 280 | int frames, int *compression, int send_to_cam) | 280 | int frames, int *compression, int send_to_cam) |
| 281 | { | 281 | { |
| 282 | const struct Kiara_table_entry *pChoose = NULL; | 282 | const struct Kiara_table_entry *pChoose; |
| 283 | int fps, ret = 0; | 283 | int fps, ret = 0; |
| 284 | 284 | ||
| 285 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) | 285 | if (size >= PSZ_MAX || *compression < 0 || *compression > 3) |
| @@ -293,13 +293,14 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int pixfmt, | |||
| 293 | fps = (frames / 5) - 1; | 293 | fps = (frames / 5) - 1; |
| 294 | 294 | ||
| 295 | /* Find a supported framerate with progressively higher compression */ | 295 | /* Find a supported framerate with progressively higher compression */ |
| 296 | while (*compression <= 3) { | 296 | do { |
| 297 | pChoose = &Kiara_table[size][fps][*compression]; | 297 | pChoose = &Kiara_table[size][fps][*compression]; |
| 298 | if (pChoose->alternate != 0) | 298 | if (pChoose->alternate != 0) |
| 299 | break; | 299 | break; |
| 300 | (*compression)++; | 300 | (*compression)++; |
| 301 | } | 301 | } while (*compression <= 3); |
| 302 | if (pChoose == NULL || pChoose->alternate == 0) | 302 | |
| 303 | if (pChoose->alternate == 0) | ||
| 303 | return -ENOENT; /* Not supported. */ | 304 | return -ENOENT; /* Not supported. */ |
| 304 | 305 | ||
| 305 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ | 306 | /* Firmware bug: video endpoint is 5, but commands are sent to endpoint 4 */ |
diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig index 030ef01b1ff0..6b00be618db8 100644 --- a/drivers/media/usb/rainshadow-cec/Kconfig +++ b/drivers/media/usb/rainshadow-cec/Kconfig | |||
| @@ -4,7 +4,7 @@ config USB_RAINSHADOW_CEC | |||
| 4 | select CEC_CORE | 4 | select CEC_CORE |
| 5 | select SERIO | 5 | select SERIO |
| 6 | select SERIO_SERPORT | 6 | select SERIO_SERPORT |
| 7 | ---help--- | 7 | help |
| 8 | This is a cec driver for the RainShadow Tech HDMI CEC device. | 8 | This is a cec driver for the RainShadow Tech HDMI CEC device. |
| 9 | 9 | ||
| 10 | To compile this driver as a module, choose M here: the | 10 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/siano/Kconfig b/drivers/media/usb/siano/Kconfig index d37b742d4f7a..cc5e5aa3c93a 100644 --- a/drivers/media/usb/siano/Kconfig +++ b/drivers/media/usb/siano/Kconfig | |||
| @@ -8,6 +8,6 @@ config SMS_USB_DRV | |||
| 8 | depends on !RC_CORE || RC_CORE | 8 | depends on !RC_CORE || RC_CORE |
| 9 | select MEDIA_COMMON_OPTIONS | 9 | select MEDIA_COMMON_OPTIONS |
| 10 | select SMS_SIANO_MDTV | 10 | select SMS_SIANO_MDTV |
| 11 | ---help--- | 11 | help |
| 12 | Choose if you would like to have Siano's support for USB interface | 12 | Choose if you would like to have Siano's support for USB interface |
| 13 | 13 | ||
diff --git a/drivers/media/usb/stk1160/Kconfig b/drivers/media/usb/stk1160/Kconfig index 425ed00e2599..03426e4437ea 100644 --- a/drivers/media/usb/stk1160/Kconfig +++ b/drivers/media/usb/stk1160/Kconfig | |||
| @@ -2,7 +2,7 @@ config VIDEO_STK1160_COMMON | |||
| 2 | tristate "STK1160 USB video capture support" | 2 | tristate "STK1160 USB video capture support" |
| 3 | depends on VIDEO_DEV && I2C | 3 | depends on VIDEO_DEV && I2C |
| 4 | 4 | ||
| 5 | ---help--- | 5 | help |
| 6 | This is a video4linux driver for STK1160 based video capture devices. | 6 | This is a video4linux driver for STK1160 based video capture devices. |
| 7 | 7 | ||
| 8 | To compile this driver as a module, choose M here: the | 8 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/stkwebcam/Kconfig b/drivers/media/usb/stkwebcam/Kconfig index a6a00aa4fce6..ea9e04b3caaf 100644 --- a/drivers/media/usb/stkwebcam/Kconfig +++ b/drivers/media/usb/stkwebcam/Kconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | config USB_STKWEBCAM | 1 | config USB_STKWEBCAM |
| 2 | tristate "USB Syntek DC1125 Camera support" | 2 | tristate "USB Syntek DC1125 Camera support" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | ---help--- | 4 | help |
| 5 | Say Y here if you want to use this type of camera. | 5 | Say Y here if you want to use this type of camera. |
| 6 | Supported devices are typically found in some Asus laptops, | 6 | Supported devices are typically found in some Asus laptops, |
| 7 | with USB id 174f:a311 and 05e1:0501. Other Syntek cameras | 7 | with USB id 174f:a311 and 05e1:0501. Other Syntek cameras |
diff --git a/drivers/media/usb/tm6000/Kconfig b/drivers/media/usb/tm6000/Kconfig index a43b77abd931..321ae691f4d9 100644 --- a/drivers/media/usb/tm6000/Kconfig +++ b/drivers/media/usb/tm6000/Kconfig | |||
| @@ -18,7 +18,7 @@ config VIDEO_TM6000_ALSA | |||
| 18 | tristate "TV Master TM5600/6000/6010 audio support" | 18 | tristate "TV Master TM5600/6000/6010 audio support" |
| 19 | depends on VIDEO_TM6000 && SND | 19 | depends on VIDEO_TM6000 && SND |
| 20 | select SND_PCM | 20 | select SND_PCM |
| 21 | ---help--- | 21 | help |
| 22 | This is a video4linux driver for direct (DMA) audio for | 22 | This is a video4linux driver for direct (DMA) audio for |
| 23 | TM5600/TM6000/TM6010 USB Devices. | 23 | TM5600/TM6000/TM6010 USB Devices. |
| 24 | 24 | ||
| @@ -29,5 +29,5 @@ config VIDEO_TM6000_DVB | |||
| 29 | tristate "DVB Support for tm6000 based TV cards" | 29 | tristate "DVB Support for tm6000 based TV cards" |
| 30 | depends on VIDEO_TM6000 && DVB_CORE && USB | 30 | depends on VIDEO_TM6000 && DVB_CORE && USB |
| 31 | select DVB_ZL10353 | 31 | select DVB_ZL10353 |
| 32 | ---help--- | 32 | help |
| 33 | This adds support for DVB cards based on the tm5600/tm6000 chip. | 33 | This adds support for DVB cards based on the tm5600/tm6000 chip. |
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig index 14a0941fa0d0..2b4ac0848469 100644 --- a/drivers/media/usb/usbtv/Kconfig +++ b/drivers/media/usb/usbtv/Kconfig | |||
| @@ -4,7 +4,7 @@ config VIDEO_USBTV | |||
| 4 | select SND_PCM | 4 | select SND_PCM |
| 5 | select VIDEOBUF2_VMALLOC | 5 | select VIDEOBUF2_VMALLOC |
| 6 | 6 | ||
| 7 | ---help--- | 7 | help |
| 8 | This is a video4linux2 driver for USBTV007 based video capture devices. | 8 | This is a video4linux2 driver for USBTV007 based video capture devices. |
| 9 | 9 | ||
| 10 | To compile this driver as a module, choose M here: the | 10 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/media/usb/usbvision/Kconfig b/drivers/media/usb/usbvision/Kconfig index 6b6afc5d8f7e..7aa080cb9884 100644 --- a/drivers/media/usb/usbvision/Kconfig +++ b/drivers/media/usb/usbvision/Kconfig | |||
| @@ -3,7 +3,7 @@ config VIDEO_USBVISION | |||
| 3 | depends on I2C && VIDEO_V4L2 | 3 | depends on I2C && VIDEO_V4L2 |
| 4 | select VIDEO_TUNER | 4 | select VIDEO_TUNER |
| 5 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT | 5 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT |
| 6 | ---help--- | 6 | help |
| 7 | There are more than 50 different USB video devices based on | 7 | There are more than 50 different USB video devices based on |
| 8 | NT1003/1004/1005 USB Bridges. This driver enables using those | 8 | NT1003/1004/1005 USB Bridges. This driver enables using those |
| 9 | devices. | 9 | devices. |
diff --git a/drivers/media/usb/usbvision/usbvision-core.c b/drivers/media/usb/usbvision/usbvision-core.c index 92d166bf8c12..abc4eed832a3 100644 --- a/drivers/media/usb/usbvision/usbvision-core.c +++ b/drivers/media/usb/usbvision/usbvision-core.c | |||
| @@ -2302,6 +2302,9 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) | |||
| 2302 | sb_size, | 2302 | sb_size, |
| 2303 | GFP_KERNEL, | 2303 | GFP_KERNEL, |
| 2304 | &urb->transfer_dma); | 2304 | &urb->transfer_dma); |
| 2305 | if (!usbvision->sbuf[buf_idx].data) | ||
| 2306 | return -ENOMEM; | ||
| 2307 | |||
| 2305 | urb->dev = dev; | 2308 | urb->dev = dev; |
| 2306 | urb->context = usbvision; | 2309 | urb->context = usbvision; |
| 2307 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); | 2310 | urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp); |
diff --git a/drivers/media/usb/uvc/Kconfig b/drivers/media/usb/uvc/Kconfig index 6ed85efabcaa..94937d0cc2e3 100644 --- a/drivers/media/usb/uvc/Kconfig +++ b/drivers/media/usb/uvc/Kconfig | |||
| @@ -2,7 +2,7 @@ config USB_VIDEO_CLASS | |||
| 2 | tristate "USB Video Class (UVC)" | 2 | tristate "USB Video Class (UVC)" |
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF2_VMALLOC | 4 | select VIDEOBUF2_VMALLOC |
| 5 | ---help--- | 5 | help |
| 6 | Support for the USB Video Class (UVC). Currently only video | 6 | Support for the USB Video Class (UVC). Currently only video |
| 7 | input devices, such as webcams, are supported. | 7 | input devices, such as webcams, are supported. |
| 8 | 8 | ||
| @@ -13,7 +13,7 @@ config USB_VIDEO_CLASS_INPUT_EVDEV | |||
| 13 | default y | 13 | default y |
| 14 | depends on USB_VIDEO_CLASS | 14 | depends on USB_VIDEO_CLASS |
| 15 | depends on USB_VIDEO_CLASS=INPUT || INPUT=y | 15 | depends on USB_VIDEO_CLASS=INPUT || INPUT=y |
| 16 | ---help--- | 16 | help |
| 17 | This option makes USB Video Class devices register an input device | 17 | This option makes USB Video Class devices register an input device |
| 18 | to report button events. | 18 | to report button events. |
| 19 | 19 | ||
diff --git a/drivers/media/usb/zr364xx/Kconfig b/drivers/media/usb/zr364xx/Kconfig index ac429bca70e8..979b1d4f3f68 100644 --- a/drivers/media/usb/zr364xx/Kconfig +++ b/drivers/media/usb/zr364xx/Kconfig | |||
| @@ -3,7 +3,7 @@ config USB_ZR364XX | |||
| 3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
| 4 | select VIDEOBUF_GEN | 4 | select VIDEOBUF_GEN |
| 5 | select VIDEOBUF_VMALLOC | 5 | select VIDEOBUF_VMALLOC |
| 6 | ---help--- | 6 | help |
| 7 | Say Y here if you want to connect this type of camera to your | 7 | Say Y here if you want to connect this type of camera to your |
| 8 | computer's USB port. | 8 | computer's USB port. |
| 9 | See <file:Documentation/media/v4l-drivers/zr364xx.rst> for more info | 9 | See <file:Documentation/media/v4l-drivers/zr364xx.rst> for more info |
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index c0940f5c69b4..8402096f7796 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig | |||
| @@ -13,7 +13,7 @@ config VIDEO_V4L2 | |||
| 13 | config VIDEO_ADV_DEBUG | 13 | config VIDEO_ADV_DEBUG |
| 14 | bool "Enable advanced debug functionality on V4L2 drivers" | 14 | bool "Enable advanced debug functionality on V4L2 drivers" |
| 15 | default n | 15 | default n |
| 16 | ---help--- | 16 | help |
| 17 | Say Y here to enable advanced debugging functionality on some | 17 | Say Y here to enable advanced debugging functionality on some |
| 18 | V4L devices. | 18 | V4L devices. |
| 19 | In doubt, say N. | 19 | In doubt, say N. |
| @@ -21,7 +21,7 @@ config VIDEO_ADV_DEBUG | |||
| 21 | config VIDEO_FIXED_MINOR_RANGES | 21 | config VIDEO_FIXED_MINOR_RANGES |
| 22 | bool "Enable old-style fixed minor ranges on drivers/video devices" | 22 | bool "Enable old-style fixed minor ranges on drivers/video devices" |
| 23 | default n | 23 | default n |
| 24 | ---help--- | 24 | help |
| 25 | Say Y here to enable the old-style fixed-range minor assignments. | 25 | Say Y here to enable the old-style fixed-range minor assignments. |
| 26 | Only useful if you rely on the old behavior and use mknod instead of udev. | 26 | Only useful if you rely on the old behavior and use mknod instead of udev. |
| 27 | 27 | ||
| @@ -33,7 +33,7 @@ config VIDEO_PCI_SKELETON | |||
| 33 | depends on SAMPLES | 33 | depends on SAMPLES |
| 34 | depends on VIDEO_V4L2 && VIDEOBUF2_CORE | 34 | depends on VIDEO_V4L2 && VIDEOBUF2_CORE |
| 35 | depends on VIDEOBUF2_MEMOPS && VIDEOBUF2_DMA_CONTIG | 35 | depends on VIDEOBUF2_MEMOPS && VIDEOBUF2_DMA_CONTIG |
| 36 | ---help--- | 36 | help |
| 37 | Enable build of the skeleton PCI driver, used as a reference | 37 | Enable build of the skeleton PCI driver, used as a reference |
| 38 | when developing new drivers. | 38 | when developing new drivers. |
| 39 | 39 | ||
| @@ -51,7 +51,7 @@ config V4L2_FLASH_LED_CLASS | |||
| 51 | tristate "V4L2 flash API for LED flash class devices" | 51 | tristate "V4L2 flash API for LED flash class devices" |
| 52 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API | 52 | depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API |
| 53 | depends on LEDS_CLASS_FLASH | 53 | depends on LEDS_CLASS_FLASH |
| 54 | ---help--- | 54 | help |
| 55 | Say Y here to enable V4L2 flash API support for LED flash | 55 | Say Y here to enable V4L2 flash API support for LED flash |
| 56 | class drivers. | 56 | class drivers. |
| 57 | 57 | ||
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index 663730f088cd..b5778b2ffa27 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c | |||
| @@ -445,3 +445,189 @@ int v4l2_s_parm_cap(struct video_device *vdev, | |||
| 445 | return ret; | 445 | return ret; |
| 446 | } | 446 | } |
| 447 | EXPORT_SYMBOL_GPL(v4l2_s_parm_cap); | 447 | EXPORT_SYMBOL_GPL(v4l2_s_parm_cap); |
| 448 | |||
| 449 | const struct v4l2_format_info *v4l2_format_info(u32 format) | ||
| 450 | { | ||
| 451 | static const struct v4l2_format_info formats[] = { | ||
| 452 | /* RGB formats */ | ||
| 453 | { .format = V4L2_PIX_FMT_BGR24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 454 | { .format = V4L2_PIX_FMT_RGB24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 455 | { .format = V4L2_PIX_FMT_HSV24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 456 | { .format = V4L2_PIX_FMT_BGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 457 | { .format = V4L2_PIX_FMT_XBGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 458 | { .format = V4L2_PIX_FMT_RGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 459 | { .format = V4L2_PIX_FMT_XRGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 460 | { .format = V4L2_PIX_FMT_HSV32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 461 | { .format = V4L2_PIX_FMT_ARGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 462 | { .format = V4L2_PIX_FMT_ABGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 463 | { .format = V4L2_PIX_FMT_GREY, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 464 | |||
| 465 | /* YUV packed formats */ | ||
| 466 | { .format = V4L2_PIX_FMT_YUYV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 467 | { .format = V4L2_PIX_FMT_YVYU, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 468 | { .format = V4L2_PIX_FMT_UYVY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 469 | { .format = V4L2_PIX_FMT_VYUY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 470 | |||
| 471 | /* YUV planar formats */ | ||
| 472 | { .format = V4L2_PIX_FMT_NV12, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 473 | { .format = V4L2_PIX_FMT_NV21, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 474 | { .format = V4L2_PIX_FMT_NV16, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 475 | { .format = V4L2_PIX_FMT_NV61, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 476 | { .format = V4L2_PIX_FMT_NV24, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 477 | { .format = V4L2_PIX_FMT_NV42, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 478 | |||
| 479 | { .format = V4L2_PIX_FMT_YUV410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||
| 480 | { .format = V4L2_PIX_FMT_YVU410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||
| 481 | { .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, | ||
| 482 | { .format = V4L2_PIX_FMT_YUV420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 483 | { .format = V4L2_PIX_FMT_YVU420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 484 | { .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 485 | |||
| 486 | /* YUV planar formats, non contiguous variant */ | ||
| 487 | { .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 488 | { .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 489 | { .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 490 | { .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 491 | { .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 492 | { .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 493 | |||
| 494 | { .format = V4L2_PIX_FMT_NV12M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 495 | { .format = V4L2_PIX_FMT_NV21M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||
| 496 | { .format = V4L2_PIX_FMT_NV16M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 497 | { .format = V4L2_PIX_FMT_NV61M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||
| 498 | |||
| 499 | /* Bayer RGB formats */ | ||
| 500 | { .format = V4L2_PIX_FMT_SBGGR8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 501 | { .format = V4L2_PIX_FMT_SGBRG8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 502 | { .format = V4L2_PIX_FMT_SGRBG8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 503 | { .format = V4L2_PIX_FMT_SRGGB8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 504 | { .format = V4L2_PIX_FMT_SBGGR10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 505 | { .format = V4L2_PIX_FMT_SGBRG10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 506 | { .format = V4L2_PIX_FMT_SGRBG10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 507 | { .format = V4L2_PIX_FMT_SRGGB10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 508 | { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 509 | { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 510 | { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 511 | { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 512 | { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 513 | { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 514 | { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 515 | { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 516 | { .format = V4L2_PIX_FMT_SBGGR12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 517 | { .format = V4L2_PIX_FMT_SGBRG12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 518 | { .format = V4L2_PIX_FMT_SGRBG12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 519 | { .format = V4L2_PIX_FMT_SRGGB12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||
| 520 | }; | ||
| 521 | unsigned int i; | ||
| 522 | |||
| 523 | for (i = 0; i < ARRAY_SIZE(formats); ++i) | ||
| 524 | if (formats[i].format == format) | ||
| 525 | return &formats[i]; | ||
| 526 | return NULL; | ||
| 527 | } | ||
| 528 | EXPORT_SYMBOL(v4l2_format_info); | ||
| 529 | |||
| 530 | static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane) | ||
| 531 | { | ||
| 532 | if (!info->block_w[plane]) | ||
| 533 | return 1; | ||
| 534 | return info->block_w[plane]; | ||
| 535 | } | ||
| 536 | |||
| 537 | static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane) | ||
| 538 | { | ||
| 539 | if (!info->block_h[plane]) | ||
| 540 | return 1; | ||
| 541 | return info->block_h[plane]; | ||
| 542 | } | ||
| 543 | |||
| 544 | int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, | ||
| 545 | int pixelformat, int width, int height) | ||
| 546 | { | ||
| 547 | const struct v4l2_format_info *info; | ||
| 548 | struct v4l2_plane_pix_format *plane; | ||
| 549 | int i; | ||
| 550 | |||
| 551 | info = v4l2_format_info(pixelformat); | ||
| 552 | if (!info) | ||
| 553 | return -EINVAL; | ||
| 554 | |||
| 555 | pixfmt->width = width; | ||
| 556 | pixfmt->height = height; | ||
| 557 | pixfmt->pixelformat = pixelformat; | ||
| 558 | pixfmt->num_planes = info->mem_planes; | ||
| 559 | |||
| 560 | if (info->mem_planes == 1) { | ||
| 561 | plane = &pixfmt->plane_fmt[0]; | ||
| 562 | plane->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; | ||
| 563 | plane->sizeimage = 0; | ||
| 564 | |||
| 565 | for (i = 0; i < info->comp_planes; i++) { | ||
| 566 | unsigned int hdiv = (i == 0) ? 1 : info->hdiv; | ||
| 567 | unsigned int vdiv = (i == 0) ? 1 : info->vdiv; | ||
| 568 | unsigned int aligned_width; | ||
| 569 | unsigned int aligned_height; | ||
| 570 | |||
| 571 | aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); | ||
| 572 | aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); | ||
| 573 | |||
| 574 | plane->sizeimage += info->bpp[i] * | ||
| 575 | DIV_ROUND_UP(aligned_width, hdiv) * | ||
| 576 | DIV_ROUND_UP(aligned_height, vdiv); | ||
| 577 | } | ||
| 578 | } else { | ||
| 579 | for (i = 0; i < info->comp_planes; i++) { | ||
| 580 | unsigned int hdiv = (i == 0) ? 1 : info->hdiv; | ||
| 581 | unsigned int vdiv = (i == 0) ? 1 : info->vdiv; | ||
| 582 | unsigned int aligned_width; | ||
| 583 | unsigned int aligned_height; | ||
| 584 | |||
| 585 | aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); | ||
| 586 | aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); | ||
| 587 | |||
| 588 | plane = &pixfmt->plane_fmt[i]; | ||
| 589 | plane->bytesperline = | ||
| 590 | info->bpp[i] * DIV_ROUND_UP(aligned_width, hdiv); | ||
| 591 | plane->sizeimage = | ||
| 592 | plane->bytesperline * DIV_ROUND_UP(aligned_height, vdiv); | ||
| 593 | } | ||
| 594 | } | ||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt_mp); | ||
| 598 | |||
| 599 | int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, int pixelformat, int width, int height) | ||
| 600 | { | ||
| 601 | const struct v4l2_format_info *info; | ||
| 602 | int i; | ||
| 603 | |||
| 604 | info = v4l2_format_info(pixelformat); | ||
| 605 | if (!info) | ||
| 606 | return -EINVAL; | ||
| 607 | |||
| 608 | /* Single planar API cannot be used for multi plane formats. */ | ||
| 609 | if (info->mem_planes > 1) | ||
| 610 | return -EINVAL; | ||
| 611 | |||
| 612 | pixfmt->width = width; | ||
| 613 | pixfmt->height = height; | ||
| 614 | pixfmt->pixelformat = pixelformat; | ||
| 615 | pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; | ||
| 616 | pixfmt->sizeimage = 0; | ||
| 617 | |||
| 618 | for (i = 0; i < info->comp_planes; i++) { | ||
| 619 | unsigned int hdiv = (i == 0) ? 1 : info->hdiv; | ||
| 620 | unsigned int vdiv = (i == 0) ? 1 : info->vdiv; | ||
| 621 | unsigned int aligned_width; | ||
| 622 | unsigned int aligned_height; | ||
| 623 | |||
| 624 | aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); | ||
| 625 | aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); | ||
| 626 | |||
| 627 | pixfmt->sizeimage += info->bpp[i] * | ||
| 628 | DIV_ROUND_UP(aligned_width, hdiv) * | ||
| 629 | DIV_ROUND_UP(aligned_height, vdiv); | ||
| 630 | } | ||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | EXPORT_SYMBOL_GPL(v4l2_fill_pixfmt); | ||
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index b79d3bbd8350..89a1fe564675 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | |||
| @@ -828,6 +828,10 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 828 | case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: | 828 | case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION: |
| 829 | return "H264 Constrained Intra Pred"; | 829 | return "H264 Constrained Intra Pred"; |
| 830 | case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; | 830 | case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset"; |
| 831 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP: return "H264 I-Frame Minimum QP Value"; | ||
| 832 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP: return "H264 I-Frame Maximum QP Value"; | ||
| 833 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP: return "H264 P-Frame Minimum QP Value"; | ||
| 834 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP: return "H264 P-Frame Maximum QP Value"; | ||
| 831 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; | 835 | case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; |
| 832 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; | 836 | case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value"; |
| 833 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; | 837 | case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value"; |
| @@ -849,6 +853,9 @@ const char *v4l2_ctrl_get_name(u32 id) | |||
| 849 | case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; | 853 | case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: return "Force Key Frame"; |
| 850 | case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; | 854 | case V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS: return "MPEG-2 Slice Parameters"; |
| 851 | case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; | 855 | case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: return "MPEG-2 Quantization Matrices"; |
| 856 | case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS: return "FWHT Stateless Parameters"; | ||
| 857 | case V4L2_CID_FWHT_I_FRAME_QP: return "FWHT I-Frame QP Value"; | ||
| 858 | case V4L2_CID_FWHT_P_FRAME_QP: return "FWHT P-Frame QP Value"; | ||
| 852 | 859 | ||
| 853 | /* VPX controls */ | 860 | /* VPX controls */ |
| 854 | case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; | 861 | case V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS: return "VPX Number of Partitions"; |
| @@ -1303,6 +1310,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, | |||
| 1303 | case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: | 1310 | case V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION: |
| 1304 | *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; | 1311 | *type = V4L2_CTRL_TYPE_MPEG2_QUANTIZATION; |
| 1305 | break; | 1312 | break; |
| 1313 | case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS: | ||
| 1314 | *type = V4L2_CTRL_TYPE_FWHT_PARAMS; | ||
| 1315 | break; | ||
| 1306 | default: | 1316 | default: |
| 1307 | *type = V4L2_CTRL_TYPE_INTEGER; | 1317 | *type = V4L2_CTRL_TYPE_INTEGER; |
| 1308 | break; | 1318 | break; |
| @@ -1599,7 +1609,7 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, | |||
| 1599 | case V4L2_CTRL_TYPE_INTEGER_MENU: | 1609 | case V4L2_CTRL_TYPE_INTEGER_MENU: |
| 1600 | if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) | 1610 | if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) |
| 1601 | return -ERANGE; | 1611 | return -ERANGE; |
| 1602 | if (ctrl->menu_skip_mask & (1 << ptr.p_s32[idx])) | 1612 | if (ctrl->menu_skip_mask & (1ULL << ptr.p_s32[idx])) |
| 1603 | return -EINVAL; | 1613 | return -EINVAL; |
| 1604 | if (ctrl->type == V4L2_CTRL_TYPE_MENU && | 1614 | if (ctrl->type == V4L2_CTRL_TYPE_MENU && |
| 1605 | ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') | 1615 | ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') |
| @@ -1669,6 +1679,9 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx, | |||
| 1669 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: | 1679 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: |
| 1670 | return 0; | 1680 | return 0; |
| 1671 | 1681 | ||
| 1682 | case V4L2_CTRL_TYPE_FWHT_PARAMS: | ||
| 1683 | return 0; | ||
| 1684 | |||
| 1672 | default: | 1685 | default: |
| 1673 | return -EINVAL; | 1686 | return -EINVAL; |
| 1674 | } | 1687 | } |
| @@ -2249,6 +2262,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, | |||
| 2249 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: | 2262 | case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION: |
| 2250 | elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); | 2263 | elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization); |
| 2251 | break; | 2264 | break; |
| 2265 | case V4L2_CTRL_TYPE_FWHT_PARAMS: | ||
| 2266 | elem_size = sizeof(struct v4l2_ctrl_fwht_params); | ||
| 2267 | break; | ||
| 2252 | default: | 2268 | default: |
| 2253 | if (type < V4L2_CTRL_COMPOUND_TYPES) | 2269 | if (type < V4L2_CTRL_COMPOUND_TYPES) |
| 2254 | elem_size = sizeof(s32); | 2270 | elem_size = sizeof(s32); |
| @@ -2918,7 +2934,7 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) | |||
| 2918 | return -EINVAL; | 2934 | return -EINVAL; |
| 2919 | 2935 | ||
| 2920 | /* Use mask to see if this menu item should be skipped */ | 2936 | /* Use mask to see if this menu item should be skipped */ |
| 2921 | if (ctrl->menu_skip_mask & (1 << i)) | 2937 | if (ctrl->menu_skip_mask & (1ULL << i)) |
| 2922 | return -EINVAL; | 2938 | return -EINVAL; |
| 2923 | /* Empty menu items should also be skipped */ | 2939 | /* Empty menu items should also be skipped */ |
| 2924 | if (ctrl->type == V4L2_CTRL_TYPE_MENU) { | 2940 | if (ctrl->type == V4L2_CTRL_TYPE_MENU) { |
| @@ -3899,18 +3915,19 @@ void v4l2_ctrl_request_complete(struct media_request *req, | |||
| 3899 | } | 3915 | } |
| 3900 | EXPORT_SYMBOL(v4l2_ctrl_request_complete); | 3916 | EXPORT_SYMBOL(v4l2_ctrl_request_complete); |
| 3901 | 3917 | ||
| 3902 | void v4l2_ctrl_request_setup(struct media_request *req, | 3918 | int v4l2_ctrl_request_setup(struct media_request *req, |
| 3903 | struct v4l2_ctrl_handler *main_hdl) | 3919 | struct v4l2_ctrl_handler *main_hdl) |
| 3904 | { | 3920 | { |
| 3905 | struct media_request_object *obj; | 3921 | struct media_request_object *obj; |
| 3906 | struct v4l2_ctrl_handler *hdl; | 3922 | struct v4l2_ctrl_handler *hdl; |
| 3907 | struct v4l2_ctrl_ref *ref; | 3923 | struct v4l2_ctrl_ref *ref; |
| 3924 | int ret = 0; | ||
| 3908 | 3925 | ||
| 3909 | if (!req || !main_hdl) | 3926 | if (!req || !main_hdl) |
| 3910 | return; | 3927 | return 0; |
| 3911 | 3928 | ||
| 3912 | if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) | 3929 | if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) |
| 3913 | return; | 3930 | return -EBUSY; |
| 3914 | 3931 | ||
| 3915 | /* | 3932 | /* |
| 3916 | * Note that it is valid if nothing was found. It means | 3933 | * Note that it is valid if nothing was found. It means |
| @@ -3919,10 +3936,10 @@ void v4l2_ctrl_request_setup(struct media_request *req, | |||
| 3919 | */ | 3936 | */ |
| 3920 | obj = media_request_object_find(req, &req_ops, main_hdl); | 3937 | obj = media_request_object_find(req, &req_ops, main_hdl); |
| 3921 | if (!obj) | 3938 | if (!obj) |
| 3922 | return; | 3939 | return 0; |
| 3923 | if (obj->completed) { | 3940 | if (obj->completed) { |
| 3924 | media_request_object_put(obj); | 3941 | media_request_object_put(obj); |
| 3925 | return; | 3942 | return -EBUSY; |
| 3926 | } | 3943 | } |
| 3927 | hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); | 3944 | hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); |
| 3928 | 3945 | ||
| @@ -3990,12 +4007,15 @@ void v4l2_ctrl_request_setup(struct media_request *req, | |||
| 3990 | update_from_auto_cluster(master); | 4007 | update_from_auto_cluster(master); |
| 3991 | } | 4008 | } |
| 3992 | 4009 | ||
| 3993 | try_or_set_cluster(NULL, master, true, 0); | 4010 | ret = try_or_set_cluster(NULL, master, true, 0); |
| 3994 | |||
| 3995 | v4l2_ctrl_unlock(master); | 4011 | v4l2_ctrl_unlock(master); |
| 4012 | |||
| 4013 | if (ret) | ||
| 4014 | break; | ||
| 3996 | } | 4015 | } |
| 3997 | 4016 | ||
| 3998 | media_request_object_put(obj); | 4017 | media_request_object_put(obj); |
| 4018 | return ret; | ||
| 3999 | } | 4019 | } |
| 4000 | EXPORT_SYMBOL(v4l2_ctrl_request_setup); | 4020 | EXPORT_SYMBOL(v4l2_ctrl_request_setup); |
| 4001 | 4021 | ||
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index e0ddb9a52bd1..7cca0de1b730 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c | |||
| @@ -216,10 +216,18 @@ error_module: | |||
| 216 | } | 216 | } |
| 217 | EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); | 217 | EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); |
| 218 | 218 | ||
| 219 | static void v4l2_subdev_release(struct v4l2_subdev *sd) | ||
| 220 | { | ||
| 221 | struct module *owner = !sd->owner_v4l2_dev ? sd->owner : NULL; | ||
| 222 | |||
| 223 | if (sd->internal_ops && sd->internal_ops->release) | ||
| 224 | sd->internal_ops->release(sd); | ||
| 225 | module_put(owner); | ||
| 226 | } | ||
| 227 | |||
| 219 | static void v4l2_device_release_subdev_node(struct video_device *vdev) | 228 | static void v4l2_device_release_subdev_node(struct video_device *vdev) |
| 220 | { | 229 | { |
| 221 | struct v4l2_subdev *sd = video_get_drvdata(vdev); | 230 | v4l2_subdev_release(video_get_drvdata(vdev)); |
| 222 | sd->devnode = NULL; | ||
| 223 | kfree(vdev); | 231 | kfree(vdev); |
| 224 | } | 232 | } |
| 225 | 233 | ||
| @@ -318,8 +326,9 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) | |||
| 318 | media_device_unregister_entity(&sd->entity); | 326 | media_device_unregister_entity(&sd->entity); |
| 319 | } | 327 | } |
| 320 | #endif | 328 | #endif |
| 321 | video_unregister_device(sd->devnode); | 329 | if (sd->devnode) |
| 322 | if (!sd->owner_v4l2_dev) | 330 | video_unregister_device(sd->devnode); |
| 323 | module_put(sd->owner); | 331 | else |
| 332 | v4l2_subdev_release(sd); | ||
| 324 | } | 333 | } |
| 325 | EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); | 334 | EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); |
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 20571846e636..ea1ed88f9dc8 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c | |||
| @@ -163,7 +163,7 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | if (use_default_lane_mapping) | 165 | if (use_default_lane_mapping) |
| 166 | pr_debug("using default lane mapping\n"); | 166 | pr_debug("no lane mapping given, using defaults\n"); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); | 169 | rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); |
| @@ -175,6 +175,10 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, | |||
| 175 | num_data_lanes); | 175 | num_data_lanes); |
| 176 | 176 | ||
| 177 | have_data_lanes = true; | 177 | have_data_lanes = true; |
| 178 | if (use_default_lane_mapping) { | ||
| 179 | pr_debug("data-lanes property exists; disabling default mapping\n"); | ||
| 180 | use_default_lane_mapping = false; | ||
| 181 | } | ||
| 178 | } | 182 | } |
| 179 | 183 | ||
| 180 | for (i = 0; i < num_data_lanes; i++) { | 184 | for (i = 0; i < num_data_lanes; i++) { |
| @@ -225,6 +229,10 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, | |||
| 225 | if (bus_type == V4L2_MBUS_CSI2_DPHY || | 229 | if (bus_type == V4L2_MBUS_CSI2_DPHY || |
| 226 | bus_type == V4L2_MBUS_CSI2_CPHY || lanes_used || | 230 | bus_type == V4L2_MBUS_CSI2_CPHY || lanes_used || |
| 227 | have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) { | 231 | have_clk_lane || (flags & ~V4L2_MBUS_CSI2_CONTINUOUS_CLOCK)) { |
| 232 | /* Only D-PHY has a clock lane. */ | ||
| 233 | unsigned int dfl_data_lane_index = | ||
| 234 | bus_type == V4L2_MBUS_CSI2_DPHY; | ||
| 235 | |||
| 228 | bus->flags = flags; | 236 | bus->flags = flags; |
| 229 | if (bus_type == V4L2_MBUS_UNKNOWN) | 237 | if (bus_type == V4L2_MBUS_UNKNOWN) |
| 230 | vep->bus_type = V4L2_MBUS_CSI2_DPHY; | 238 | vep->bus_type = V4L2_MBUS_CSI2_DPHY; |
| @@ -233,7 +241,7 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode, | |||
| 233 | if (use_default_lane_mapping) { | 241 | if (use_default_lane_mapping) { |
| 234 | bus->clock_lane = 0; | 242 | bus->clock_lane = 0; |
| 235 | for (i = 0; i < num_data_lanes; i++) | 243 | for (i = 0; i < num_data_lanes; i++) |
| 236 | bus->data_lanes[i] = 1 + i; | 244 | bus->data_lanes[i] = dfl_data_lane_index + i; |
| 237 | } else { | 245 | } else { |
| 238 | bus->clock_lane = clock_lane; | 246 | bus->clock_lane = clock_lane; |
| 239 | for (i = 0; i < num_data_lanes; i++) | 247 | for (i = 0; i < num_data_lanes; i++) |
| @@ -820,7 +828,10 @@ error: | |||
| 820 | * underneath the fwnode identified by the previous tuple, etc. until you | 828 | * underneath the fwnode identified by the previous tuple, etc. until you |
| 821 | * reached the fwnode you need. | 829 | * reached the fwnode you need. |
| 822 | * | 830 | * |
| 823 | * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt: | 831 | * THIS EXAMPLE EXISTS MERELY TO DOCUMENT THIS FUNCTION. DO NOT USE IT AS A |
| 832 | * REFERENCE IN HOW ACPI TABLES SHOULD BE WRITTEN!! See documentation under | ||
| 833 | * Documentation/acpi/dsd instead and especially graph.txt, | ||
| 834 | * data-node-references.txt and leds.txt . | ||
| 824 | * | 835 | * |
| 825 | * Scope (\_SB.PCI0.I2C2) | 836 | * Scope (\_SB.PCI0.I2C2) |
| 826 | * { | 837 | * { |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f6d663934648..ac87c3e37280 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
| @@ -1337,6 +1337,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) | |||
| 1337 | case V4L2_PIX_FMT_VP9: descr = "VP9"; break; | 1337 | case V4L2_PIX_FMT_VP9: descr = "VP9"; break; |
| 1338 | case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ | 1338 | case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ |
| 1339 | case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ | 1339 | case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ |
| 1340 | case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */ | ||
| 1340 | case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; | 1341 | case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; |
| 1341 | case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; | 1342 | case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; |
| 1342 | case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; | 1343 | case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; |
| @@ -1373,7 +1374,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) | |||
| 1373 | } | 1374 | } |
| 1374 | 1375 | ||
| 1375 | if (descr) | 1376 | if (descr) |
| 1376 | WARN_ON(strscpy(fmt->description, descr, sz) >= sz); | 1377 | WARN_ON(strscpy(fmt->description, descr, sz) < 0); |
| 1377 | fmt->flags = flags; | 1378 | fmt->flags = flags; |
| 1378 | } | 1379 | } |
| 1379 | 1380 | ||
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index f5f0d71ec745..d75815ab0d7b 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | #include <linux/ioctl.h> | 19 | #include <linux/ioctl.h> |
| 20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 21 | #include <linux/module.h> | ||
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 22 | #include <linux/types.h> | 23 | #include <linux/types.h> |
| 23 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
| @@ -54,9 +55,6 @@ static int subdev_open(struct file *file) | |||
| 54 | struct video_device *vdev = video_devdata(file); | 55 | struct video_device *vdev = video_devdata(file); |
| 55 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); | 56 | struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); |
| 56 | struct v4l2_subdev_fh *subdev_fh; | 57 | struct v4l2_subdev_fh *subdev_fh; |
| 57 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
| 58 | struct media_entity *entity = NULL; | ||
| 59 | #endif | ||
| 60 | int ret; | 58 | int ret; |
| 61 | 59 | ||
| 62 | subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); | 60 | subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); |
| @@ -73,12 +71,15 @@ static int subdev_open(struct file *file) | |||
| 73 | v4l2_fh_add(&subdev_fh->vfh); | 71 | v4l2_fh_add(&subdev_fh->vfh); |
| 74 | file->private_data = &subdev_fh->vfh; | 72 | file->private_data = &subdev_fh->vfh; |
| 75 | #if defined(CONFIG_MEDIA_CONTROLLER) | 73 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 76 | if (sd->v4l2_dev->mdev) { | 74 | if (sd->v4l2_dev->mdev && sd->entity.graph_obj.mdev->dev) { |
| 77 | entity = media_entity_get(&sd->entity); | 75 | struct module *owner; |
| 78 | if (!entity) { | 76 | |
| 77 | owner = sd->entity.graph_obj.mdev->dev->driver->owner; | ||
| 78 | if (!try_module_get(owner)) { | ||
| 79 | ret = -EBUSY; | 79 | ret = -EBUSY; |
| 80 | goto err; | 80 | goto err; |
| 81 | } | 81 | } |
| 82 | subdev_fh->owner = owner; | ||
| 82 | } | 83 | } |
| 83 | #endif | 84 | #endif |
| 84 | 85 | ||
| @@ -91,9 +92,7 @@ static int subdev_open(struct file *file) | |||
| 91 | return 0; | 92 | return 0; |
| 92 | 93 | ||
| 93 | err: | 94 | err: |
| 94 | #if defined(CONFIG_MEDIA_CONTROLLER) | 95 | module_put(subdev_fh->owner); |
| 95 | media_entity_put(entity); | ||
| 96 | #endif | ||
| 97 | v4l2_fh_del(&subdev_fh->vfh); | 96 | v4l2_fh_del(&subdev_fh->vfh); |
| 98 | v4l2_fh_exit(&subdev_fh->vfh); | 97 | v4l2_fh_exit(&subdev_fh->vfh); |
| 99 | subdev_fh_free(subdev_fh); | 98 | subdev_fh_free(subdev_fh); |
| @@ -111,10 +110,7 @@ static int subdev_close(struct file *file) | |||
| 111 | 110 | ||
| 112 | if (sd->internal_ops && sd->internal_ops->close) | 111 | if (sd->internal_ops && sd->internal_ops->close) |
| 113 | sd->internal_ops->close(sd, subdev_fh); | 112 | sd->internal_ops->close(sd, subdev_fh); |
| 114 | #if defined(CONFIG_MEDIA_CONTROLLER) | 113 | module_put(subdev_fh->owner); |
| 115 | if (sd->v4l2_dev->mdev) | ||
| 116 | media_entity_put(&sd->entity); | ||
| 117 | #endif | ||
| 118 | v4l2_fh_del(vfh); | 114 | v4l2_fh_del(vfh); |
| 119 | v4l2_fh_exit(vfh); | 115 | v4l2_fh_exit(vfh); |
| 120 | subdev_fh_free(subdev_fh); | 116 | subdev_fh_free(subdev_fh); |
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 44280b6c021a..f77f5eee7fc2 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | menuconfig STAGING_MEDIA | 2 | menuconfig STAGING_MEDIA |
| 3 | bool "Media staging drivers" | 3 | bool "Media staging drivers" |
| 4 | default n | 4 | default n |
| 5 | ---help--- | 5 | help |
| 6 | This option allows you to select a number of media drivers that | 6 | This option allows you to select a number of media drivers that |
| 7 | don't have the "normal" Linux kernel quality level. | 7 | don't have the "normal" Linux kernel quality level. |
| 8 | Most of them don't follow properly the V4L, DVB and/or RC API's, | 8 | Most of them don't follow properly the V4L, DVB and/or RC API's, |
| @@ -34,8 +34,6 @@ source "drivers/staging/media/sunxi/Kconfig" | |||
| 34 | 34 | ||
| 35 | source "drivers/staging/media/tegra-vde/Kconfig" | 35 | source "drivers/staging/media/tegra-vde/Kconfig" |
| 36 | 36 | ||
| 37 | source "drivers/staging/media/zoran/Kconfig" | ||
| 38 | |||
| 39 | source "drivers/staging/media/ipu3/Kconfig" | 37 | source "drivers/staging/media/ipu3/Kconfig" |
| 40 | 38 | ||
| 41 | source "drivers/staging/media/soc_camera/Kconfig" | 39 | source "drivers/staging/media/soc_camera/Kconfig" |
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 0355e3030504..99218bfc997f 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile | |||
| @@ -5,7 +5,6 @@ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/ | |||
| 5 | obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ | 5 | obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ |
| 6 | obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ | 6 | obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ |
| 7 | obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ | 7 | obj-$(CONFIG_TEGRA_VDE) += tegra-vde/ |
| 8 | obj-$(CONFIG_VIDEO_ZORAN) += zoran/ | ||
| 9 | obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/ | 8 | obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/ |
| 10 | obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ | 9 | obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/ |
| 11 | obj-$(CONFIG_SOC_CAMERA) += soc_camera/ | 10 | obj-$(CONFIG_SOC_CAMERA) += soc_camera/ |
diff --git a/drivers/staging/media/bcm2048/Kconfig b/drivers/staging/media/bcm2048/Kconfig index c93a0a848c90..ab2d50cac140 100644 --- a/drivers/staging/media/bcm2048/Kconfig +++ b/drivers/staging/media/bcm2048/Kconfig | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | config I2C_BCM2048 | 6 | config I2C_BCM2048 |
| 7 | tristate "Broadcom BCM2048 FM Radio Receiver support" | 7 | tristate "Broadcom BCM2048 FM Radio Receiver support" |
| 8 | depends on I2C && VIDEO_V4L2 && RADIO_ADAPTERS | 8 | depends on I2C && VIDEO_V4L2 && RADIO_ADAPTERS |
| 9 | ---help--- | 9 | help |
| 10 | Say Y here if you want support to BCM2048 FM Radio Receiver. | 10 | Say Y here if you want support to BCM2048 FM Radio Receiver. |
| 11 | This device driver supports only i2c bus. | 11 | This device driver supports only i2c bus. |
| 12 | 12 | ||
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index d9b02ff66259..09903ffb13ba 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c | |||
| @@ -2404,7 +2404,7 @@ static int bcm2048_vidioc_g_audio(struct file *file, void *priv, | |||
| 2404 | if (audio->index > 1) | 2404 | if (audio->index > 1) |
| 2405 | return -EINVAL; | 2405 | return -EINVAL; |
| 2406 | 2406 | ||
| 2407 | strncpy(audio->name, "Radio", 32); | 2407 | strscpy(audio->name, "Radio", sizeof(audio->name)); |
| 2408 | audio->capability = V4L2_AUDCAP_STEREO; | 2408 | audio->capability = V4L2_AUDCAP_STEREO; |
| 2409 | 2409 | ||
| 2410 | return 0; | 2410 | return 0; |
| @@ -2432,7 +2432,7 @@ static int bcm2048_vidioc_g_tuner(struct file *file, void *priv, | |||
| 2432 | if (tuner->index > 0) | 2432 | if (tuner->index > 0) |
| 2433 | return -EINVAL; | 2433 | return -EINVAL; |
| 2434 | 2434 | ||
| 2435 | strncpy(tuner->name, "FM Receiver", 32); | 2435 | strscpy(tuner->name, "FM Receiver", sizeof(tuner->name)); |
| 2436 | tuner->type = V4L2_TUNER_RADIO; | 2436 | tuner->type = V4L2_TUNER_RADIO; |
| 2437 | tuner->rangelow = | 2437 | tuner->rangelow = |
| 2438 | dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev)); | 2438 | dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev)); |
diff --git a/drivers/staging/media/davinci_vpfe/Kconfig b/drivers/staging/media/davinci_vpfe/Kconfig index eb61141b29e8..94bf6746c03f 100644 --- a/drivers/staging/media/davinci_vpfe/Kconfig +++ b/drivers/staging/media/davinci_vpfe/Kconfig | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | config VIDEO_DM365_VPFE | 2 | config VIDEO_DM365_VPFE |
| 3 | tristate "DM365 VPFE Media Controller Capture Driver" | 3 | tristate "DM365 VPFE Media Controller Capture Driver" |
| 4 | depends on VIDEO_V4L2 | 4 | depends on VIDEO_V4L2 |
| 5 | depends on (ARCH_DAVINCI_DM365 && !VIDEO_DM365_ISIF) || COMPILE_TEST | 5 | depends on (ARCH_DAVINCI_DM365 && !VIDEO_DM365_ISIF) || (COMPILE_TEST && !ARCH_OMAP1) |
| 6 | depends on VIDEO_V4L2_SUBDEV_API | 6 | depends on VIDEO_V4L2_SUBDEV_API |
| 7 | depends on VIDEO_DAVINCI_VPBE_DISPLAY | 7 | depends on VIDEO_DAVINCI_VPBE_DISPLAY |
| 8 | select VIDEOBUF2_DMA_CONTIG | 8 | select VIDEOBUF2_DMA_CONTIG |
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c index 0a6d038fcec9..46fd8184fc77 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_isif.c +++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c | |||
| @@ -433,9 +433,9 @@ static int isif_get_params(struct v4l2_subdev *sd, void *params) | |||
| 433 | return 0; | 433 | return 0; |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | static int isif_validate_df_csc_params(struct vpfe_isif_df_csc *df_csc) | 436 | static int isif_validate_df_csc_params(const struct vpfe_isif_df_csc *df_csc) |
| 437 | { | 437 | { |
| 438 | struct vpfe_isif_color_space_conv *csc; | 438 | const struct vpfe_isif_color_space_conv *csc; |
| 439 | int err = -EINVAL; | 439 | int err = -EINVAL; |
| 440 | int i; | 440 | int i; |
| 441 | 441 | ||
| @@ -481,7 +481,7 @@ static int isif_validate_df_csc_params(struct vpfe_isif_df_csc *df_csc) | |||
| 481 | #define DM365_ISIF_MAX_DFCMEM0 0x1fff | 481 | #define DM365_ISIF_MAX_DFCMEM0 0x1fff |
| 482 | #define DM365_ISIF_MAX_DFCMEM1 0x1fff | 482 | #define DM365_ISIF_MAX_DFCMEM1 0x1fff |
| 483 | 483 | ||
| 484 | static int isif_validate_dfc_params(struct vpfe_isif_dfc *dfc) | 484 | static int isif_validate_dfc_params(const struct vpfe_isif_dfc *dfc) |
| 485 | { | 485 | { |
| 486 | int err = -EINVAL; | 486 | int err = -EINVAL; |
| 487 | int i; | 487 | int i; |
| @@ -532,7 +532,7 @@ static int isif_validate_dfc_params(struct vpfe_isif_dfc *dfc) | |||
| 532 | #define DM365_ISIF_MAX_CLVSV 0x1fff | 532 | #define DM365_ISIF_MAX_CLVSV 0x1fff |
| 533 | #define DM365_ISIF_MAX_HEIGHT_BLACK_REGION 0x1fff | 533 | #define DM365_ISIF_MAX_HEIGHT_BLACK_REGION 0x1fff |
| 534 | 534 | ||
| 535 | static int isif_validate_bclamp_params(struct vpfe_isif_black_clamp *bclamp) | 535 | static int isif_validate_bclamp_params(const struct vpfe_isif_black_clamp *bclamp) |
| 536 | { | 536 | { |
| 537 | int err = -EINVAL; | 537 | int err = -EINVAL; |
| 538 | 538 | ||
| @@ -580,7 +580,7 @@ static int isif_validate_bclamp_params(struct vpfe_isif_black_clamp *bclamp) | |||
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | static int | 582 | static int |
| 583 | isif_validate_raw_params(struct vpfe_isif_raw_config *params) | 583 | isif_validate_raw_params(const struct vpfe_isif_raw_config *params) |
| 584 | { | 584 | { |
| 585 | int ret; | 585 | int ret; |
| 586 | 586 | ||
| @@ -593,20 +593,18 @@ isif_validate_raw_params(struct vpfe_isif_raw_config *params) | |||
| 593 | return isif_validate_bclamp_params(¶ms->bclamp); | 593 | return isif_validate_bclamp_params(¶ms->bclamp); |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | static int isif_set_params(struct v4l2_subdev *sd, void *params) | 596 | static int isif_set_params(struct v4l2_subdev *sd, const struct vpfe_isif_raw_config *params) |
| 597 | { | 597 | { |
| 598 | struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); | 598 | struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd); |
| 599 | struct vpfe_isif_raw_config isif_raw_params; | ||
| 600 | int ret = -EINVAL; | 599 | int ret = -EINVAL; |
| 601 | 600 | ||
| 602 | /* only raw module parameters can be set through the IOCTL */ | 601 | /* only raw module parameters can be set through the IOCTL */ |
| 603 | if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12) | 602 | if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12) |
| 604 | return ret; | 603 | return ret; |
| 605 | 604 | ||
| 606 | memcpy(&isif_raw_params, params, sizeof(isif_raw_params)); | 605 | if (!isif_validate_raw_params(params)) { |
| 607 | if (!isif_validate_raw_params(&isif_raw_params)) { | 606 | memcpy(&isif->isif_cfg.bayer.config_params, params, |
| 608 | memcpy(&isif->isif_cfg.bayer.config_params, &isif_raw_params, | 607 | sizeof(*params)); |
| 609 | sizeof(isif_raw_params)); | ||
| 610 | ret = 0; | 608 | ret = 0; |
| 611 | } | 609 | } |
| 612 | return ret; | 610 | return ret; |
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c index d460963106fa..7adf1fae43f6 100644 --- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c +++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c | |||
| @@ -1881,7 +1881,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz, | |||
| 1881 | struct v4l2_subdev *sd = &vpfe_rsz->crop_resizer.subdev; | 1881 | struct v4l2_subdev *sd = &vpfe_rsz->crop_resizer.subdev; |
| 1882 | struct media_pad *pads = &vpfe_rsz->crop_resizer.pads[0]; | 1882 | struct media_pad *pads = &vpfe_rsz->crop_resizer.pads[0]; |
| 1883 | struct media_entity *me = &sd->entity; | 1883 | struct media_entity *me = &sd->entity; |
| 1884 | static resource_size_t res_len; | 1884 | resource_size_t res_len; |
| 1885 | struct resource *res; | 1885 | struct resource *res; |
| 1886 | int ret; | 1886 | int ret; |
| 1887 | 1887 | ||
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index 6c8b69491ef0..4c726345dc25 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig | |||
| @@ -7,7 +7,7 @@ config VIDEO_IMX_MEDIA | |||
| 7 | depends on HAS_DMA | 7 | depends on HAS_DMA |
| 8 | select VIDEOBUF2_DMA_CONTIG | 8 | select VIDEOBUF2_DMA_CONTIG |
| 9 | select V4L2_FWNODE | 9 | select V4L2_FWNODE |
| 10 | ---help--- | 10 | help |
| 11 | Say yes here to enable support for video4linux media controller | 11 | Say yes here to enable support for video4linux media controller |
| 12 | driver for the i.MX5/6 SOC. | 12 | driver for the i.MX5/6 SOC. |
| 13 | 13 | ||
| @@ -18,7 +18,7 @@ config VIDEO_IMX_CSI | |||
| 18 | tristate "i.MX5/6 Camera Sensor Interface driver" | 18 | tristate "i.MX5/6 Camera Sensor Interface driver" |
| 19 | depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C | 19 | depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C |
| 20 | default y | 20 | default y |
| 21 | ---help--- | 21 | help |
| 22 | A video4linux camera sensor interface driver for i.MX5/6. | 22 | A video4linux camera sensor interface driver for i.MX5/6. |
| 23 | 23 | ||
| 24 | config VIDEO_IMX7_CSI | 24 | config VIDEO_IMX7_CSI |
diff --git a/drivers/staging/media/imx/imx-ic-common.c b/drivers/staging/media/imx/imx-ic-common.c index 7e2455097315..18cd4cb92431 100644 --- a/drivers/staging/media/imx/imx-ic-common.c +++ b/drivers/staging/media/imx/imx-ic-common.c | |||
| @@ -22,7 +22,7 @@ static struct imx_ic_ops *ic_ops[IC_NUM_OPS] = { | |||
| 22 | 22 | ||
| 23 | static int imx_ic_probe(struct platform_device *pdev) | 23 | static int imx_ic_probe(struct platform_device *pdev) |
| 24 | { | 24 | { |
| 25 | struct imx_media_internal_sd_platformdata *pdata; | 25 | struct imx_media_ipu_internal_sd_pdata *pdata; |
| 26 | struct imx_ic_priv *priv; | 26 | struct imx_ic_priv *priv; |
| 27 | int ret; | 27 | int ret; |
| 28 | 28 | ||
| @@ -59,7 +59,7 @@ static int imx_ic_probe(struct platform_device *pdev) | |||
| 59 | priv->sd.owner = THIS_MODULE; | 59 | priv->sd.owner = THIS_MODULE; |
| 60 | priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; | 60 | priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; |
| 61 | priv->sd.grp_id = pdata->grp_id; | 61 | priv->sd.grp_id = pdata->grp_id; |
| 62 | strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name)); | 62 | strscpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name)); |
| 63 | 63 | ||
| 64 | ret = ic_ops[priv->task_id]->init(priv); | 64 | ret = ic_ops[priv->task_id]->init(priv); |
| 65 | if (ret) | 65 | if (ret) |
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index edc0e9a2a90d..28fe66052cc7 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c | |||
| @@ -150,9 +150,10 @@ static inline bool requires_passthrough(struct v4l2_fwnode_endpoint *ep, | |||
| 150 | /* | 150 | /* |
| 151 | * Parses the fwnode endpoint from the source pad of the entity | 151 | * Parses the fwnode endpoint from the source pad of the entity |
| 152 | * connected to this CSI. This will either be the entity directly | 152 | * connected to this CSI. This will either be the entity directly |
| 153 | * upstream from the CSI-2 receiver, or directly upstream from the | 153 | * upstream from the CSI-2 receiver, directly upstream from the |
| 154 | * video mux. The endpoint is needed to determine the bus type and | 154 | * video mux, or directly upstream from the CSI itself. The endpoint |
| 155 | * bus config coming into the CSI. | 155 | * is needed to determine the bus type and bus config coming into |
| 156 | * the CSI. | ||
| 156 | */ | 157 | */ |
| 157 | static int csi_get_upstream_endpoint(struct csi_priv *priv, | 158 | static int csi_get_upstream_endpoint(struct csi_priv *priv, |
| 158 | struct v4l2_fwnode_endpoint *ep) | 159 | struct v4l2_fwnode_endpoint *ep) |
| @@ -168,7 +169,8 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv, | |||
| 168 | if (!priv->src_sd) | 169 | if (!priv->src_sd) |
| 169 | return -EPIPE; | 170 | return -EPIPE; |
| 170 | 171 | ||
| 171 | src = &priv->src_sd->entity; | 172 | sd = priv->src_sd; |
| 173 | src = &sd->entity; | ||
| 172 | 174 | ||
| 173 | if (src->function == MEDIA_ENT_F_VID_MUX) { | 175 | if (src->function == MEDIA_ENT_F_VID_MUX) { |
| 174 | /* | 176 | /* |
| @@ -182,6 +184,14 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv, | |||
| 182 | src = &sd->entity; | 184 | src = &sd->entity; |
| 183 | } | 185 | } |
| 184 | 186 | ||
| 187 | /* | ||
| 188 | * If the source is neither the video mux nor the CSI-2 receiver, | ||
| 189 | * get the source pad directly upstream from CSI itself. | ||
| 190 | */ | ||
| 191 | if (src->function != MEDIA_ENT_F_VID_MUX && | ||
| 192 | sd->grp_id != IMX_MEDIA_GRP_ID_CSI2) | ||
| 193 | src = &priv->sd.entity; | ||
| 194 | |||
| 185 | /* get source pad of entity directly upstream from src */ | 195 | /* get source pad of entity directly upstream from src */ |
| 186 | pad = imx_media_find_upstream_pad(priv->md, src, 0); | 196 | pad = imx_media_find_upstream_pad(priv->md, src, 0); |
| 187 | if (IS_ERR(pad)) | 197 | if (IS_ERR(pad)) |
diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c index 910594125889..6cd93419b81d 100644 --- a/drivers/staging/media/imx/imx-media-dev-common.c +++ b/drivers/staging/media/imx/imx-media-dev-common.c | |||
| @@ -30,7 +30,7 @@ struct imx_media_dev *imx_media_dev_init(struct device *dev) | |||
| 30 | 30 | ||
| 31 | dev_set_drvdata(dev, imxmd); | 31 | dev_set_drvdata(dev, imxmd); |
| 32 | 32 | ||
| 33 | strlcpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model)); | 33 | strscpy(imxmd->md.model, "imx-media", sizeof(imxmd->md.model)); |
| 34 | imxmd->md.ops = &imx_media_md_ops; | 34 | imxmd->md.ops = &imx_media_md_ops; |
| 35 | imxmd->md.dev = dev; | 35 | imxmd->md.dev = dev; |
| 36 | 36 | ||
| @@ -38,7 +38,7 @@ struct imx_media_dev *imx_media_dev_init(struct device *dev) | |||
| 38 | 38 | ||
| 39 | imxmd->v4l2_dev.mdev = &imxmd->md; | 39 | imxmd->v4l2_dev.mdev = &imxmd->md; |
| 40 | imxmd->v4l2_dev.notify = imx_media_notify; | 40 | imxmd->v4l2_dev.notify = imx_media_notify; |
| 41 | strlcpy(imxmd->v4l2_dev.name, "imx-media", | 41 | strscpy(imxmd->v4l2_dev.name, "imx-media", |
| 42 | sizeof(imxmd->v4l2_dev.name)); | 42 | sizeof(imxmd->v4l2_dev.name)); |
| 43 | 43 | ||
| 44 | media_device_init(&imxmd->md); | 44 | media_device_init(&imxmd->md); |
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index bd4ddea488f1..6be95584006d 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c | |||
| @@ -46,12 +46,14 @@ int imx_media_add_async_subdev(struct imx_media_dev *imxmd, | |||
| 46 | int ret; | 46 | int ret; |
| 47 | 47 | ||
| 48 | if (fwnode) { | 48 | if (fwnode) { |
| 49 | asd = v4l2_async_notifier_add_fwnode_subdev( | 49 | asd = v4l2_async_notifier_add_fwnode_subdev(&imxmd->notifier, |
| 50 | &imxmd->notifier, fwnode, sizeof(*imxasd)); | 50 | fwnode, |
| 51 | sizeof(*imxasd)); | ||
| 51 | } else { | 52 | } else { |
| 52 | devname = dev_name(&pdev->dev); | 53 | devname = dev_name(&pdev->dev); |
| 53 | asd = v4l2_async_notifier_add_devname_subdev( | 54 | asd = v4l2_async_notifier_add_devname_subdev(&imxmd->notifier, |
| 54 | &imxmd->notifier, devname, sizeof(*imxasd)); | 55 | devname, |
| 56 | sizeof(*imxasd)); | ||
| 55 | } | 57 | } |
| 56 | 58 | ||
| 57 | if (IS_ERR(asd)) { | 59 | if (IS_ERR(asd)) { |
| @@ -262,10 +264,9 @@ static int imx_media_alloc_pad_vdev_lists(struct imx_media_dev *imxmd) | |||
| 262 | 264 | ||
| 263 | list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { | 265 | list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) { |
| 264 | entity = &sd->entity; | 266 | entity = &sd->entity; |
| 265 | vdev_lists = devm_kcalloc( | 267 | vdev_lists = devm_kcalloc(imxmd->md.dev, |
| 266 | imxmd->md.dev, | 268 | entity->num_pads, sizeof(*vdev_lists), |
| 267 | entity->num_pads, sizeof(*vdev_lists), | 269 | GFP_KERNEL); |
| 268 | GFP_KERNEL); | ||
| 269 | if (!vdev_lists) | 270 | if (!vdev_lists) |
| 270 | return -ENOMEM; | 271 | return -ENOMEM; |
| 271 | 272 | ||
| @@ -473,13 +474,6 @@ static int imx_media_probe(struct platform_device *pdev) | |||
| 473 | goto cleanup; | 474 | goto cleanup; |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 476 | ret = imx_media_add_internal_subdevs(imxmd); | ||
| 477 | if (ret) { | ||
| 478 | v4l2_err(&imxmd->v4l2_dev, | ||
| 479 | "add_internal_subdevs failed with %d\n", ret); | ||
| 480 | goto cleanup; | ||
| 481 | } | ||
| 482 | |||
| 483 | ret = imx_media_dev_notifier_register(imxmd); | 477 | ret = imx_media_dev_notifier_register(imxmd); |
| 484 | if (ret) | 478 | if (ret) |
| 485 | goto del_int; | 479 | goto del_int; |
| @@ -487,7 +481,7 @@ static int imx_media_probe(struct platform_device *pdev) | |||
| 487 | return 0; | 481 | return 0; |
| 488 | 482 | ||
| 489 | del_int: | 483 | del_int: |
| 490 | imx_media_remove_internal_subdevs(imxmd); | 484 | imx_media_remove_ipu_internal_subdevs(imxmd); |
| 491 | cleanup: | 485 | cleanup: |
| 492 | v4l2_async_notifier_cleanup(&imxmd->notifier); | 486 | v4l2_async_notifier_cleanup(&imxmd->notifier); |
| 493 | v4l2_device_unregister(&imxmd->v4l2_dev); | 487 | v4l2_device_unregister(&imxmd->v4l2_dev); |
| @@ -504,7 +498,7 @@ static int imx_media_remove(struct platform_device *pdev) | |||
| 504 | v4l2_info(&imxmd->v4l2_dev, "Removing imx-media\n"); | 498 | v4l2_info(&imxmd->v4l2_dev, "Removing imx-media\n"); |
| 505 | 499 | ||
| 506 | v4l2_async_notifier_unregister(&imxmd->notifier); | 500 | v4l2_async_notifier_unregister(&imxmd->notifier); |
| 507 | imx_media_remove_internal_subdevs(imxmd); | 501 | imx_media_remove_ipu_internal_subdevs(imxmd); |
| 508 | v4l2_async_notifier_cleanup(&imxmd->notifier); | 502 | v4l2_async_notifier_cleanup(&imxmd->notifier); |
| 509 | media_device_unregister(&imxmd->md); | 503 | media_device_unregister(&imxmd->md); |
| 510 | v4l2_device_unregister(&imxmd->v4l2_dev); | 504 | v4l2_device_unregister(&imxmd->v4l2_dev); |
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c index c547280a309e..df49ebfbe98a 100644 --- a/drivers/staging/media/imx/imx-media-internal-sd.c +++ b/drivers/staging/media/imx/imx-media-internal-sd.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | /* | 2 | /* |
| 3 | * Media driver for Freescale i.MX5/6 SOC | 3 | * Media driver for Freescale i.MX5/6 SOC |
| 4 | * | 4 | * |
| 5 | * Adds the internal subdevices and the media links between them. | 5 | * Adds the IPU internal subdevices and the media links between them. |
| 6 | * | 6 | * |
| 7 | * Copyright (c) 2016 Mentor Graphics Inc. | 7 | * Copyright (c) 2016 Mentor Graphics Inc. |
| 8 | */ | 8 | */ |
| @@ -188,7 +188,7 @@ static struct v4l2_subdev *find_sink(struct imx_media_dev *imxmd, | |||
| 188 | 188 | ||
| 189 | /* | 189 | /* |
| 190 | * retrieve IPU id from subdev name, note: can't get this from | 190 | * retrieve IPU id from subdev name, note: can't get this from |
| 191 | * struct imx_media_internal_sd_platformdata because if src is | 191 | * struct imx_media_ipu_internal_sd_pdata because if src is |
| 192 | * a CSI, it has different struct ipu_client_platformdata which | 192 | * a CSI, it has different struct ipu_client_platformdata which |
| 193 | * does not contain IPU id. | 193 | * does not contain IPU id. |
| 194 | */ | 194 | */ |
| @@ -266,7 +266,7 @@ static int add_internal_subdev(struct imx_media_dev *imxmd, | |||
| 266 | const struct internal_subdev *isd, | 266 | const struct internal_subdev *isd, |
| 267 | int ipu_id) | 267 | int ipu_id) |
| 268 | { | 268 | { |
| 269 | struct imx_media_internal_sd_platformdata pdata; | 269 | struct imx_media_ipu_internal_sd_pdata pdata; |
| 270 | struct platform_device_info pdevinfo = {}; | 270 | struct platform_device_info pdevinfo = {}; |
| 271 | struct platform_device *pdev; | 271 | struct platform_device *pdev; |
| 272 | 272 | ||
| @@ -294,13 +294,14 @@ static int add_internal_subdev(struct imx_media_dev *imxmd, | |||
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | /* adds the internal subdevs in one ipu */ | 296 | /* adds the internal subdevs in one ipu */ |
| 297 | static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id) | 297 | int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd, |
| 298 | int ipu_id) | ||
| 298 | { | 299 | { |
| 299 | enum isd_enum i; | 300 | enum isd_enum i; |
| 301 | int ret; | ||
| 300 | 302 | ||
| 301 | for (i = 0; i < num_isd; i++) { | 303 | for (i = 0; i < num_isd; i++) { |
| 302 | const struct internal_subdev *isd = &int_subdev[i]; | 304 | const struct internal_subdev *isd = &int_subdev[i]; |
| 303 | int ret; | ||
| 304 | 305 | ||
| 305 | /* | 306 | /* |
| 306 | * the CSIs are represented in the device-tree, so those | 307 | * the CSIs are represented in the device-tree, so those |
| @@ -318,32 +319,17 @@ static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id) | |||
| 318 | } | 319 | } |
| 319 | 320 | ||
| 320 | if (ret) | 321 | if (ret) |
| 321 | return ret; | 322 | goto remove; |
| 322 | } | 323 | } |
| 323 | 324 | ||
| 324 | return 0; | 325 | return 0; |
| 325 | } | ||
| 326 | |||
| 327 | int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd) | ||
| 328 | { | ||
| 329 | int ret; | ||
| 330 | |||
| 331 | ret = add_ipu_internal_subdevs(imxmd, 0); | ||
| 332 | if (ret) | ||
| 333 | goto remove; | ||
| 334 | |||
| 335 | ret = add_ipu_internal_subdevs(imxmd, 1); | ||
| 336 | if (ret) | ||
| 337 | goto remove; | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | 326 | ||
| 341 | remove: | 327 | remove: |
| 342 | imx_media_remove_internal_subdevs(imxmd); | 328 | imx_media_remove_ipu_internal_subdevs(imxmd); |
| 343 | return ret; | 329 | return ret; |
| 344 | } | 330 | } |
| 345 | 331 | ||
| 346 | void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd) | 332 | void imx_media_remove_ipu_internal_subdevs(struct imx_media_dev *imxmd) |
| 347 | { | 333 | { |
| 348 | struct imx_media_async_subdev *imxasd; | 334 | struct imx_media_async_subdev *imxasd; |
| 349 | struct v4l2_async_subdev *asd; | 335 | struct v4l2_async_subdev *asd; |
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c index 09580d83c685..990e82aa8e42 100644 --- a/drivers/staging/media/imx/imx-media-of.c +++ b/drivers/staging/media/imx/imx-media-of.c | |||
| @@ -19,36 +19,25 @@ | |||
| 19 | int imx_media_of_add_csi(struct imx_media_dev *imxmd, | 19 | int imx_media_of_add_csi(struct imx_media_dev *imxmd, |
| 20 | struct device_node *csi_np) | 20 | struct device_node *csi_np) |
| 21 | { | 21 | { |
| 22 | int ret; | ||
| 23 | |||
| 24 | if (!of_device_is_available(csi_np)) { | 22 | if (!of_device_is_available(csi_np)) { |
| 25 | dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__, | 23 | dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__, |
| 26 | csi_np); | 24 | csi_np); |
| 27 | /* unavailable is not an error */ | 25 | return -ENODEV; |
| 28 | return 0; | ||
| 29 | } | 26 | } |
| 30 | 27 | ||
| 31 | /* add CSI fwnode to async notifier */ | 28 | /* add CSI fwnode to async notifier */ |
| 32 | ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np), NULL); | 29 | return imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np), |
| 33 | if (ret) { | 30 | NULL); |
| 34 | if (ret == -EEXIST) { | ||
| 35 | /* already added, everything is fine */ | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | /* other error, can't continue */ | ||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | |||
| 43 | return 0; | ||
| 44 | } | 31 | } |
| 45 | EXPORT_SYMBOL_GPL(imx_media_of_add_csi); | 32 | EXPORT_SYMBOL_GPL(imx_media_of_add_csi); |
| 46 | 33 | ||
| 47 | int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, | 34 | int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, |
| 48 | struct device_node *np) | 35 | struct device_node *np) |
| 49 | { | 36 | { |
| 37 | bool ipu_found[2] = {false, false}; | ||
| 50 | struct device_node *csi_np; | 38 | struct device_node *csi_np; |
| 51 | int i, ret; | 39 | int i, ret; |
| 40 | u32 ipu_id; | ||
| 52 | 41 | ||
| 53 | for (i = 0; ; i++) { | 42 | for (i = 0; ; i++) { |
| 54 | csi_np = of_parse_phandle(np, "ports", i); | 43 | csi_np = of_parse_phandle(np, "ports", i); |
| @@ -56,12 +45,43 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd, | |||
| 56 | break; | 45 | break; |
| 57 | 46 | ||
| 58 | ret = imx_media_of_add_csi(imxmd, csi_np); | 47 | ret = imx_media_of_add_csi(imxmd, csi_np); |
| 59 | of_node_put(csi_np); | 48 | if (ret) { |
| 60 | if (ret) | 49 | /* unavailable or already added is not an error */ |
| 61 | return ret; | 50 | if (ret == -ENODEV || ret == -EEXIST) { |
| 51 | of_node_put(csi_np); | ||
| 52 | continue; | ||
| 53 | } | ||
| 54 | |||
| 55 | /* other error, can't continue */ | ||
| 56 | goto err_out; | ||
| 57 | } | ||
| 58 | |||
| 59 | ret = of_alias_get_id(csi_np->parent, "ipu"); | ||
| 60 | if (ret < 0) | ||
| 61 | goto err_out; | ||
| 62 | if (ret > 1) { | ||
| 63 | ret = -EINVAL; | ||
| 64 | goto err_out; | ||
| 65 | } | ||
| 66 | |||
| 67 | ipu_id = ret; | ||
| 68 | |||
| 69 | if (!ipu_found[ipu_id]) { | ||
| 70 | ret = imx_media_add_ipu_internal_subdevs(imxmd, | ||
| 71 | ipu_id); | ||
| 72 | if (ret) | ||
| 73 | goto err_out; | ||
| 74 | } | ||
| 75 | |||
| 76 | ipu_found[ipu_id] = true; | ||
| 62 | } | 77 | } |
| 63 | 78 | ||
| 64 | return 0; | 79 | return 0; |
| 80 | |||
| 81 | err_out: | ||
| 82 | imx_media_remove_ipu_internal_subdevs(imxmd); | ||
| 83 | of_node_put(csi_np); | ||
| 84 | return ret; | ||
| 65 | } | 85 | } |
| 66 | 86 | ||
| 67 | /* | 87 | /* |
| @@ -141,15 +161,18 @@ int imx_media_create_csi_of_links(struct imx_media_dev *imxmd, | |||
| 141 | struct v4l2_subdev *csi) | 161 | struct v4l2_subdev *csi) |
| 142 | { | 162 | { |
| 143 | struct device_node *csi_np = csi->dev->of_node; | 163 | struct device_node *csi_np = csi->dev->of_node; |
| 144 | struct fwnode_handle *fwnode, *csi_ep; | ||
| 145 | struct v4l2_fwnode_link link; | ||
| 146 | struct device_node *ep; | 164 | struct device_node *ep; |
| 147 | int ret; | ||
| 148 | |||
| 149 | link.local_node = of_fwnode_handle(csi_np); | ||
| 150 | link.local_port = CSI_SINK_PAD; | ||
| 151 | 165 | ||
| 152 | for_each_child_of_node(csi_np, ep) { | 166 | for_each_child_of_node(csi_np, ep) { |
| 167 | struct fwnode_handle *fwnode, *csi_ep; | ||
| 168 | struct v4l2_fwnode_link link; | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | memset(&link, 0, sizeof(link)); | ||
| 172 | |||
| 173 | link.local_node = of_fwnode_handle(csi_np); | ||
| 174 | link.local_port = CSI_SINK_PAD; | ||
| 175 | |||
| 153 | csi_ep = of_fwnode_handle(ep); | 176 | csi_ep = of_fwnode_handle(ep); |
| 154 | 177 | ||
| 155 | fwnode = fwnode_graph_get_remote_endpoint(csi_ep); | 178 | fwnode = fwnode_graph_get_remote_endpoint(csi_ep); |
diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 3f4b5e9080d4..4487374c9435 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c | |||
| @@ -227,6 +227,12 @@ static void __maybe_unused prepare_vdi_in_buffers(struct vdic_priv *priv, | |||
| 227 | curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); | 227 | curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0); |
| 228 | next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is; | 228 | next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is; |
| 229 | break; | 229 | break; |
| 230 | default: | ||
| 231 | /* | ||
| 232 | * can't get here, priv->fieldtype can only be one of | ||
| 233 | * the above. This is to quiet smatch errors. | ||
| 234 | */ | ||
| 235 | return; | ||
| 230 | } | 236 | } |
| 231 | 237 | ||
| 232 | ipu_cpmem_set_buffer(priv->vdi_in_ch_p, 0, prev_phys); | 238 | ipu_cpmem_set_buffer(priv->vdi_in_ch_p, 0, prev_phys); |
| @@ -740,7 +746,7 @@ static int vdic_link_setup(struct media_entity *entity, | |||
| 740 | remote_sd = media_entity_to_v4l2_subdev(remote->entity); | 746 | remote_sd = media_entity_to_v4l2_subdev(remote->entity); |
| 741 | 747 | ||
| 742 | /* direct pad must connect to a CSI */ | 748 | /* direct pad must connect to a CSI */ |
| 743 | if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_CSI) || | 749 | if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) || |
| 744 | remote->index != CSI_SRC_PAD_DIRECT) { | 750 | remote->index != CSI_SRC_PAD_DIRECT) { |
| 745 | ret = -EINVAL; | 751 | ret = -EINVAL; |
| 746 | goto out; | 752 | goto out; |
| @@ -930,7 +936,7 @@ static const struct v4l2_subdev_internal_ops vdic_internal_ops = { | |||
| 930 | 936 | ||
| 931 | static int imx_vdic_probe(struct platform_device *pdev) | 937 | static int imx_vdic_probe(struct platform_device *pdev) |
| 932 | { | 938 | { |
| 933 | struct imx_media_internal_sd_platformdata *pdata; | 939 | struct imx_media_ipu_internal_sd_pdata *pdata; |
| 934 | struct vdic_priv *priv; | 940 | struct vdic_priv *priv; |
| 935 | int ret; | 941 | int ret; |
| 936 | 942 | ||
| @@ -954,7 +960,7 @@ static int imx_vdic_probe(struct platform_device *pdev) | |||
| 954 | priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; | 960 | priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; |
| 955 | /* get our group id */ | 961 | /* get our group id */ |
| 956 | priv->sd.grp_id = pdata->grp_id; | 962 | priv->sd.grp_id = pdata->grp_id; |
| 957 | strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name)); | 963 | strscpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name)); |
| 958 | 964 | ||
| 959 | mutex_init(&priv->lock); | 965 | mutex_init(&priv->lock); |
| 960 | 966 | ||
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index 1f7501d527fb..eb59ba0c3b62 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h | |||
| @@ -111,7 +111,7 @@ struct imx_media_pad_vdev { | |||
| 111 | struct list_head list; | 111 | struct list_head list; |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | struct imx_media_internal_sd_platformdata { | 114 | struct imx_media_ipu_internal_sd_pdata { |
| 115 | char sd_name[V4L2_SUBDEV_NAME_SIZE]; | 115 | char sd_name[V4L2_SUBDEV_NAME_SIZE]; |
| 116 | u32 grp_id; | 116 | u32 grp_id; |
| 117 | int ipu_id; | 117 | int ipu_id; |
| @@ -248,10 +248,11 @@ struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd); | |||
| 248 | void imx_media_fim_free(struct imx_media_fim *fim); | 248 | void imx_media_fim_free(struct imx_media_fim *fim); |
| 249 | 249 | ||
| 250 | /* imx-media-internal-sd.c */ | 250 | /* imx-media-internal-sd.c */ |
| 251 | int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd); | 251 | int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd, |
| 252 | int ipu_id); | ||
| 252 | int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd, | 253 | int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd, |
| 253 | struct v4l2_subdev *sd); | 254 | struct v4l2_subdev *sd); |
| 254 | void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd); | 255 | void imx_media_remove_ipu_internal_subdevs(struct imx_media_dev *imxmd); |
| 255 | 256 | ||
| 256 | /* imx-media-of.c */ | 257 | /* imx-media-of.c */ |
| 257 | int imx_media_add_of_subdevs(struct imx_media_dev *dev, | 258 | int imx_media_add_of_subdevs(struct imx_media_dev *dev, |
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 3fba7c27c0ec..18eb5d3ecf10 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c | |||
| @@ -1051,7 +1051,9 @@ static int imx7_csi_set_fmt(struct v4l2_subdev *sd, | |||
| 1051 | goto out_unlock; | 1051 | goto out_unlock; |
| 1052 | } | 1052 | } |
| 1053 | 1053 | ||
| 1054 | imx7_csi_try_fmt(csi, cfg, sdformat, &cc); | 1054 | ret = imx7_csi_try_fmt(csi, cfg, sdformat, &cc); |
| 1055 | if (ret < 0) | ||
| 1056 | goto out_unlock; | ||
| 1055 | 1057 | ||
| 1056 | fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); | 1058 | fmt = imx7_csi_get_format(csi, cfg, sdformat->pad, sdformat->which); |
| 1057 | if (!fmt) { | 1059 | if (!fmt) { |
| @@ -1271,7 +1273,7 @@ static int imx7_csi_probe(struct platform_device *pdev) | |||
| 1271 | platform_set_drvdata(pdev, &csi->sd); | 1273 | platform_set_drvdata(pdev, &csi->sd); |
| 1272 | 1274 | ||
| 1273 | ret = imx_media_of_add_csi(imxmd, node); | 1275 | ret = imx_media_of_add_csi(imxmd, node); |
| 1274 | if (ret < 0) | 1276 | if (ret < 0 && ret != -ENODEV && ret != -EEXIST) |
| 1275 | goto cleanup; | 1277 | goto cleanup; |
| 1276 | 1278 | ||
| 1277 | ret = imx_media_dev_notifier_register(imxmd); | 1279 | ret = imx_media_dev_notifier_register(imxmd); |
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index 2ddcc42ab8ff..19455f425416 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 12 | #include <linux/debugfs.h> | ||
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
| @@ -491,7 +492,7 @@ static int mipi_csis_clk_get(struct csi_state *state) | |||
| 491 | 492 | ||
| 492 | state->wrap_clk = devm_clk_get(dev, "wrap"); | 493 | state->wrap_clk = devm_clk_get(dev, "wrap"); |
| 493 | if (IS_ERR(state->wrap_clk)) | 494 | if (IS_ERR(state->wrap_clk)) |
| 494 | return IS_ERR(state->wrap_clk); | 495 | return PTR_ERR(state->wrap_clk); |
| 495 | 496 | ||
| 496 | /* Set clock rate */ | 497 | /* Set clock rate */ |
| 497 | ret = clk_set_rate(state->wrap_clk, state->clk_frequency); | 498 | ret = clk_set_rate(state->wrap_clk, state->clk_frequency); |
| @@ -706,7 +707,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, | |||
| 706 | fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); | 707 | fmt = mipi_csis_get_format(state, cfg, sdformat->which, sdformat->pad); |
| 707 | 708 | ||
| 708 | mutex_lock(&state->lock); | 709 | mutex_lock(&state->lock); |
| 709 | if (fmt && sdformat->pad == CSIS_PAD_SOURCE) { | 710 | if (sdformat->pad == CSIS_PAD_SOURCE) { |
| 710 | sdformat->format = *fmt; | 711 | sdformat->format = *fmt; |
| 711 | goto unlock; | 712 | goto unlock; |
| 712 | } | 713 | } |
| @@ -889,8 +890,6 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, | |||
| 889 | return ret; | 890 | return ret; |
| 890 | } | 891 | } |
| 891 | 892 | ||
| 892 | #ifdef CONFIG_DEBUG_FS | ||
| 893 | #include <linux/debugfs.h> | ||
| 894 | 893 | ||
| 895 | static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) | 894 | static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) |
| 896 | { | 895 | { |
| @@ -900,7 +899,7 @@ static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) | |||
| 900 | } | 899 | } |
| 901 | DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); | 900 | DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs); |
| 902 | 901 | ||
| 903 | static int __init_or_module mipi_csis_debugfs_init(struct csi_state *state) | 902 | static int mipi_csis_debugfs_init(struct csi_state *state) |
| 904 | { | 903 | { |
| 905 | struct dentry *d; | 904 | struct dentry *d; |
| 906 | 905 | ||
| @@ -934,17 +933,6 @@ static void mipi_csis_debugfs_exit(struct csi_state *state) | |||
| 934 | debugfs_remove_recursive(state->debugfs_root); | 933 | debugfs_remove_recursive(state->debugfs_root); |
| 935 | } | 934 | } |
| 936 | 935 | ||
| 937 | #else | ||
| 938 | static int mipi_csis_debugfs_init(struct csi_state *state __maybe_unused) | ||
| 939 | { | ||
| 940 | return 0; | ||
| 941 | } | ||
| 942 | |||
| 943 | static void mipi_csis_debugfs_exit(struct csi_state *state __maybe_unused) | ||
| 944 | { | ||
| 945 | } | ||
| 946 | #endif | ||
| 947 | |||
| 948 | static int mipi_csis_probe(struct platform_device *pdev) | 936 | static int mipi_csis_probe(struct platform_device *pdev) |
| 949 | { | 937 | { |
| 950 | struct device *dev = &pdev->dev; | 938 | struct device *dev = &pdev->dev; |
| @@ -1039,8 +1027,7 @@ disable_clock: | |||
| 1039 | 1027 | ||
| 1040 | static int mipi_csis_pm_suspend(struct device *dev, bool runtime) | 1028 | static int mipi_csis_pm_suspend(struct device *dev, bool runtime) |
| 1041 | { | 1029 | { |
| 1042 | struct platform_device *pdev = to_platform_device(dev); | 1030 | struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); |
| 1043 | struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); | ||
| 1044 | struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); | 1031 | struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); |
| 1045 | int ret = 0; | 1032 | int ret = 0; |
| 1046 | 1033 | ||
| @@ -1064,8 +1051,7 @@ unlock: | |||
| 1064 | 1051 | ||
| 1065 | static int mipi_csis_pm_resume(struct device *dev, bool runtime) | 1052 | static int mipi_csis_pm_resume(struct device *dev, bool runtime) |
| 1066 | { | 1053 | { |
| 1067 | struct platform_device *pdev = to_platform_device(dev); | 1054 | struct v4l2_subdev *mipi_sd = dev_get_drvdata(dev); |
| 1068 | struct v4l2_subdev *mipi_sd = platform_get_drvdata(pdev); | ||
| 1069 | struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); | 1055 | struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); |
| 1070 | int ret = 0; | 1056 | int ret = 0; |
| 1071 | 1057 | ||
diff --git a/drivers/staging/media/ipu3/Kconfig b/drivers/staging/media/ipu3/Kconfig index f80f3e35f431..4b51c67eac88 100644 --- a/drivers/staging/media/ipu3/Kconfig +++ b/drivers/staging/media/ipu3/Kconfig | |||
| @@ -6,7 +6,7 @@ config VIDEO_IPU3_IMGU | |||
| 6 | depends on X86 | 6 | depends on X86 |
| 7 | select IOMMU_IOVA | 7 | select IOMMU_IOVA |
| 8 | select VIDEOBUF2_DMA_SG | 8 | select VIDEOBUF2_DMA_SG |
| 9 | ---help--- | 9 | help |
| 10 | This is the Video4Linux2 driver for Intel IPU3 image processing unit, | 10 | This is the Video4Linux2 driver for Intel IPU3 image processing unit, |
| 11 | found in Intel Skylake and Kaby Lake SoCs and used for processing | 11 | found in Intel Skylake and Kaby Lake SoCs and used for processing |
| 12 | images and video. | 12 | images and video. |
diff --git a/drivers/staging/media/ipu3/ipu3-css.c b/drivers/staging/media/ipu3/ipu3-css.c index 15ab77e4b766..23cf5b2cfe8b 100644 --- a/drivers/staging/media/ipu3/ipu3-css.c +++ b/drivers/staging/media/ipu3/ipu3-css.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/device.h> | 4 | #include <linux/device.h> |
| 5 | #include <linux/iopoll.h> | 5 | #include <linux/iopoll.h> |
| 6 | #include <linux/slab.h> | ||
| 6 | 7 | ||
| 7 | #include "ipu3-css.h" | 8 | #include "ipu3-css.h" |
| 8 | #include "ipu3-css-fw.h" | 9 | #include "ipu3-css-fw.h" |
| @@ -1744,15 +1745,18 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1744 | struct v4l2_rect *const bds = &r[IPU3_CSS_RECT_BDS]; | 1745 | struct v4l2_rect *const bds = &r[IPU3_CSS_RECT_BDS]; |
| 1745 | struct v4l2_rect *const env = &r[IPU3_CSS_RECT_ENVELOPE]; | 1746 | struct v4l2_rect *const env = &r[IPU3_CSS_RECT_ENVELOPE]; |
| 1746 | struct v4l2_rect *const gdc = &r[IPU3_CSS_RECT_GDC]; | 1747 | struct v4l2_rect *const gdc = &r[IPU3_CSS_RECT_GDC]; |
| 1747 | struct imgu_css_queue q[IPU3_CSS_QUEUES]; | 1748 | struct imgu_css_queue *q; |
| 1748 | struct v4l2_pix_format_mplane *const in = | 1749 | struct v4l2_pix_format_mplane *in, *out, *vf; |
| 1749 | &q[IPU3_CSS_QUEUE_IN].fmt.mpix; | ||
| 1750 | struct v4l2_pix_format_mplane *const out = | ||
| 1751 | &q[IPU3_CSS_QUEUE_OUT].fmt.mpix; | ||
| 1752 | struct v4l2_pix_format_mplane *const vf = | ||
| 1753 | &q[IPU3_CSS_QUEUE_VF].fmt.mpix; | ||
| 1754 | int i, s, ret; | 1750 | int i, s, ret; |
| 1755 | 1751 | ||
| 1752 | q = kcalloc(IPU3_CSS_QUEUES, sizeof(struct imgu_css_queue), GFP_KERNEL); | ||
| 1753 | if (!q) | ||
| 1754 | return -ENOMEM; | ||
| 1755 | |||
| 1756 | in = &q[IPU3_CSS_QUEUE_IN].fmt.mpix; | ||
| 1757 | out = &q[IPU3_CSS_QUEUE_OUT].fmt.mpix; | ||
| 1758 | vf = &q[IPU3_CSS_QUEUE_VF].fmt.mpix; | ||
| 1759 | |||
| 1756 | /* Adjust all formats, get statistics buffer sizes and formats */ | 1760 | /* Adjust all formats, get statistics buffer sizes and formats */ |
| 1757 | for (i = 0; i < IPU3_CSS_QUEUES; i++) { | 1761 | for (i = 0; i < IPU3_CSS_QUEUES; i++) { |
| 1758 | if (fmts[i]) | 1762 | if (fmts[i]) |
| @@ -1766,7 +1770,8 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1766 | IPU3_CSS_QUEUE_TO_FLAGS(i))) { | 1770 | IPU3_CSS_QUEUE_TO_FLAGS(i))) { |
| 1767 | dev_notice(css->dev, "can not initialize queue %s\n", | 1771 | dev_notice(css->dev, "can not initialize queue %s\n", |
| 1768 | qnames[i]); | 1772 | qnames[i]); |
| 1769 | return -EINVAL; | 1773 | ret = -EINVAL; |
| 1774 | goto out; | ||
| 1770 | } | 1775 | } |
| 1771 | } | 1776 | } |
| 1772 | for (i = 0; i < IPU3_CSS_RECTS; i++) { | 1777 | for (i = 0; i < IPU3_CSS_RECTS; i++) { |
| @@ -1788,7 +1793,8 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1788 | if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) || | 1793 | if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) || |
| 1789 | !imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { | 1794 | !imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { |
| 1790 | dev_warn(css->dev, "required queues are disabled\n"); | 1795 | dev_warn(css->dev, "required queues are disabled\n"); |
| 1791 | return -EINVAL; | 1796 | ret = -EINVAL; |
| 1797 | goto out; | ||
| 1792 | } | 1798 | } |
| 1793 | 1799 | ||
| 1794 | if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { | 1800 | if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) { |
| @@ -1829,7 +1835,8 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1829 | ret = imgu_css_find_binary(css, pipe, q, r); | 1835 | ret = imgu_css_find_binary(css, pipe, q, r); |
| 1830 | if (ret < 0) { | 1836 | if (ret < 0) { |
| 1831 | dev_err(css->dev, "failed to find suitable binary\n"); | 1837 | dev_err(css->dev, "failed to find suitable binary\n"); |
| 1832 | return -EINVAL; | 1838 | ret = -EINVAL; |
| 1839 | goto out; | ||
| 1833 | } | 1840 | } |
| 1834 | css->pipes[pipe].bindex = ret; | 1841 | css->pipes[pipe].bindex = ret; |
| 1835 | 1842 | ||
| @@ -1843,7 +1850,8 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1843 | IPU3_CSS_QUEUE_TO_FLAGS(i))) { | 1850 | IPU3_CSS_QUEUE_TO_FLAGS(i))) { |
| 1844 | dev_err(css->dev, | 1851 | dev_err(css->dev, |
| 1845 | "final resolution adjustment failed\n"); | 1852 | "final resolution adjustment failed\n"); |
| 1846 | return -EINVAL; | 1853 | ret = -EINVAL; |
| 1854 | goto out; | ||
| 1847 | } | 1855 | } |
| 1848 | *fmts[i] = q[i].fmt.mpix; | 1856 | *fmts[i] = q[i].fmt.mpix; |
| 1849 | } | 1857 | } |
| @@ -1859,7 +1867,10 @@ int imgu_css_fmt_try(struct imgu_css *css, | |||
| 1859 | bds->width, bds->height, gdc->width, gdc->height, | 1867 | bds->width, bds->height, gdc->width, gdc->height, |
| 1860 | out->width, out->height, vf->width, vf->height); | 1868 | out->width, out->height, vf->width, vf->height); |
| 1861 | 1869 | ||
| 1862 | return 0; | 1870 | ret = 0; |
| 1871 | out: | ||
| 1872 | kfree(q); | ||
| 1873 | return ret; | ||
| 1863 | } | 1874 | } |
| 1864 | 1875 | ||
| 1865 | int imgu_css_fmt_set(struct imgu_css *css, | 1876 | int imgu_css_fmt_set(struct imgu_css *css, |
| @@ -2160,11 +2171,6 @@ int imgu_css_set_parameters(struct imgu_css *css, unsigned int pipe, | |||
| 2160 | obgrid_size = imgu_css_fw_obgrid_size(bi); | 2171 | obgrid_size = imgu_css_fw_obgrid_size(bi); |
| 2161 | stripes = bi->info.isp.sp.iterator.num_stripes ? : 1; | 2172 | stripes = bi->info.isp.sp.iterator.num_stripes ? : 1; |
| 2162 | 2173 | ||
| 2163 | /* | ||
| 2164 | * TODO(b/118782861): If userspace queues more than 4 buffers, the | ||
| 2165 | * parameters from previous buffers will be overwritten. Fix the driver | ||
| 2166 | * not to allow this. | ||
| 2167 | */ | ||
| 2168 | imgu_css_pool_get(&css_pipe->pool.parameter_set_info); | 2174 | imgu_css_pool_get(&css_pipe->pool.parameter_set_info); |
| 2169 | param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, | 2175 | param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, |
| 2170 | 0)->vaddr; | 2176 | 0)->vaddr; |
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 9c0352b193a7..a7bc22040ed8 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c | |||
| @@ -66,7 +66,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 66 | struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; | 66 | struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; |
| 67 | struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; | 67 | struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; |
| 68 | 68 | ||
| 69 | dev_dbg(dev, "%s %d for pipe %d", __func__, enable, pipe); | 69 | dev_dbg(dev, "%s %d for pipe %u", __func__, enable, pipe); |
| 70 | /* grab ctrl after streamon and return after off */ | 70 | /* grab ctrl after streamon and return after off */ |
| 71 | v4l2_ctrl_grab(imgu_sd->ctrl, enable); | 71 | v4l2_ctrl_grab(imgu_sd->ctrl, enable); |
| 72 | 72 | ||
| @@ -101,7 +101,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 101 | else | 101 | else |
| 102 | css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; | 102 | css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; |
| 103 | 103 | ||
| 104 | dev_dbg(dev, "IPU3 pipe %d pipe_id %d", pipe, css_pipe->pipe_id); | 104 | dev_dbg(dev, "IPU3 pipe %u pipe_id %u", pipe, css_pipe->pipe_id); |
| 105 | 105 | ||
| 106 | rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_sd->rect.eff; | 106 | rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_sd->rect.eff; |
| 107 | rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; | 107 | rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; |
| @@ -109,7 +109,7 @@ static int imgu_subdev_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 109 | 109 | ||
| 110 | r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); | 110 | r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); |
| 111 | if (r) { | 111 | if (r) { |
| 112 | dev_err(dev, "failed to set initial formats pipe %d with (%d)", | 112 | dev_err(dev, "failed to set initial formats pipe %u with (%d)", |
| 113 | pipe, r); | 113 | pipe, r); |
| 114 | return r; | 114 | return r; |
| 115 | } | 115 | } |
| @@ -157,7 +157,7 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd, | |||
| 157 | u32 pad = fmt->pad; | 157 | u32 pad = fmt->pad; |
| 158 | unsigned int pipe = imgu_sd->pipe; | 158 | unsigned int pipe = imgu_sd->pipe; |
| 159 | 159 | ||
| 160 | dev_dbg(&imgu->pci_dev->dev, "set subdev %d pad %d fmt to [%dx%d]", | 160 | dev_dbg(&imgu->pci_dev->dev, "set subdev %u pad %u fmt to [%ux%u]", |
| 161 | pipe, pad, fmt->format.width, fmt->format.height); | 161 | pipe, pad, fmt->format.width, fmt->format.height); |
| 162 | 162 | ||
| 163 | imgu_pipe = &imgu->imgu_pipe[pipe]; | 163 | imgu_pipe = &imgu->imgu_pipe[pipe]; |
| @@ -233,7 +233,7 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd, | |||
| 233 | struct v4l2_rect *rect, *try_sel; | 233 | struct v4l2_rect *rect, *try_sel; |
| 234 | 234 | ||
| 235 | dev_dbg(&imgu->pci_dev->dev, | 235 | dev_dbg(&imgu->pci_dev->dev, |
| 236 | "set subdev %d sel which %d target 0x%4x rect [%dx%d]", | 236 | "set subdev %u sel which %u target 0x%4x rect [%ux%u]", |
| 237 | imgu_sd->pipe, sel->which, sel->target, | 237 | imgu_sd->pipe, sel->which, sel->target, |
| 238 | sel->r.width, sel->r.height); | 238 | sel->r.width, sel->r.height); |
| 239 | 239 | ||
| @@ -279,7 +279,7 @@ static int imgu_link_setup(struct media_entity *entity, | |||
| 279 | 279 | ||
| 280 | WARN_ON(pad >= IMGU_NODE_NUM); | 280 | WARN_ON(pad >= IMGU_NODE_NUM); |
| 281 | 281 | ||
| 282 | dev_dbg(&imgu->pci_dev->dev, "pipe %d pad %d is %s", pipe, pad, | 282 | dev_dbg(&imgu->pci_dev->dev, "pipe %u pad %u is %s", pipe, pad, |
| 283 | flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); | 283 | flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); |
| 284 | 284 | ||
| 285 | imgu_pipe = &imgu->imgu_pipe[pipe]; | 285 | imgu_pipe = &imgu->imgu_pipe[pipe]; |
| @@ -294,7 +294,7 @@ static int imgu_link_setup(struct media_entity *entity, | |||
| 294 | else | 294 | else |
| 295 | __clear_bit(pipe, imgu->css.enabled_pipes); | 295 | __clear_bit(pipe, imgu->css.enabled_pipes); |
| 296 | 296 | ||
| 297 | dev_dbg(&imgu->pci_dev->dev, "pipe %d is %s", pipe, | 297 | dev_dbg(&imgu->pci_dev->dev, "pipe %u is %s", pipe, |
| 298 | flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); | 298 | flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); |
| 299 | 299 | ||
| 300 | return 0; | 300 | return 0; |
| @@ -341,8 +341,10 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) | |||
| 341 | struct imgu_video_device *node = | 341 | struct imgu_video_device *node = |
| 342 | container_of(vb->vb2_queue, struct imgu_video_device, vbq); | 342 | container_of(vb->vb2_queue, struct imgu_video_device, vbq); |
| 343 | unsigned int queue = imgu_node_to_queue(node->id); | 343 | unsigned int queue = imgu_node_to_queue(node->id); |
| 344 | struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, | ||
| 345 | vid_buf.vbb.vb2_buf); | ||
| 344 | unsigned long need_bytes; | 346 | unsigned long need_bytes; |
| 345 | unsigned int pipe = node->pipe; | 347 | unsigned long payload = vb2_get_plane_payload(vb, 0); |
| 346 | 348 | ||
| 347 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE || | 349 | if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE || |
| 348 | vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT) | 350 | vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT) |
| @@ -350,42 +352,26 @@ static void imgu_vb2_buf_queue(struct vb2_buffer *vb) | |||
| 350 | else | 352 | else |
| 351 | need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; | 353 | need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; |
| 352 | 354 | ||
| 353 | if (queue == IPU3_CSS_QUEUE_PARAMS) { | 355 | if (queue == IPU3_CSS_QUEUE_PARAMS && payload && payload < need_bytes) { |
| 354 | unsigned long payload = vb2_get_plane_payload(vb, 0); | 356 | dev_err(&imgu->pci_dev->dev, "invalid data size for params."); |
| 355 | struct vb2_v4l2_buffer *buf = | 357 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); |
| 356 | container_of(vb, struct vb2_v4l2_buffer, vb2_buf); | 358 | return; |
| 357 | int r = -EINVAL; | 359 | } |
| 358 | |||
| 359 | if (payload == 0) { | ||
| 360 | payload = need_bytes; | ||
| 361 | vb2_set_plane_payload(vb, 0, payload); | ||
| 362 | } | ||
| 363 | if (payload >= need_bytes) | ||
| 364 | r = imgu_css_set_parameters(&imgu->css, pipe, | ||
| 365 | vb2_plane_vaddr(vb, 0)); | ||
| 366 | buf->flags = V4L2_BUF_FLAG_DONE; | ||
| 367 | vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE | ||
| 368 | : VB2_BUF_STATE_ERROR); | ||
| 369 | |||
| 370 | } else { | ||
| 371 | struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, | ||
| 372 | vid_buf.vbb.vb2_buf); | ||
| 373 | 360 | ||
| 374 | mutex_lock(&imgu->lock); | 361 | mutex_lock(&imgu->lock); |
| 362 | if (queue != IPU3_CSS_QUEUE_PARAMS) | ||
| 375 | imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr); | 363 | imgu_css_buf_init(&buf->css_buf, queue, buf->map.daddr); |
| 376 | list_add_tail(&buf->vid_buf.list, | ||
| 377 | &node->buffers); | ||
| 378 | mutex_unlock(&imgu->lock); | ||
| 379 | 364 | ||
| 380 | vb2_set_plane_payload(&buf->vid_buf.vbb.vb2_buf, 0, need_bytes); | 365 | list_add_tail(&buf->vid_buf.list, &node->buffers); |
| 366 | mutex_unlock(&imgu->lock); | ||
| 381 | 367 | ||
| 382 | if (imgu->streaming) | 368 | vb2_set_plane_payload(vb, 0, need_bytes); |
| 383 | imgu_queue_buffers(imgu, false, pipe); | ||
| 384 | } | ||
| 385 | 369 | ||
| 386 | dev_dbg(&imgu->pci_dev->dev, "%s for pipe %d node %d", __func__, | 370 | if (imgu->streaming) |
| 387 | node->pipe, node->id); | 371 | imgu_queue_buffers(imgu, false, node->pipe); |
| 388 | 372 | ||
| 373 | dev_dbg(&imgu->pci_dev->dev, "%s for pipe %u node %u", __func__, | ||
| 374 | node->pipe, node->id); | ||
| 389 | } | 375 | } |
| 390 | 376 | ||
| 391 | static int imgu_vb2_queue_setup(struct vb2_queue *vq, | 377 | static int imgu_vb2_queue_setup(struct vb2_queue *vq, |
| @@ -435,7 +421,7 @@ static bool imgu_all_nodes_streaming(struct imgu_device *imgu, | |||
| 435 | pipe = except->pipe; | 421 | pipe = except->pipe; |
| 436 | if (!test_bit(pipe, imgu->css.enabled_pipes)) { | 422 | if (!test_bit(pipe, imgu->css.enabled_pipes)) { |
| 437 | dev_warn(&imgu->pci_dev->dev, | 423 | dev_warn(&imgu->pci_dev->dev, |
| 438 | "pipe %d link is not ready yet", pipe); | 424 | "pipe %u link is not ready yet", pipe); |
| 439 | return false; | 425 | return false; |
| 440 | } | 426 | } |
| 441 | 427 | ||
| @@ -479,7 +465,7 @@ static int imgu_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 479 | int r; | 465 | int r; |
| 480 | unsigned int pipe; | 466 | unsigned int pipe; |
| 481 | 467 | ||
| 482 | dev_dbg(dev, "%s node name %s pipe %d id %u", __func__, | 468 | dev_dbg(dev, "%s node name %s pipe %u id %u", __func__, |
| 483 | node->name, node->pipe, node->id); | 469 | node->name, node->pipe, node->id); |
| 484 | 470 | ||
| 485 | if (imgu->streaming) { | 471 | if (imgu->streaming) { |
| @@ -539,7 +525,7 @@ static void imgu_vb2_stop_streaming(struct vb2_queue *vq) | |||
| 539 | WARN_ON(!node->enabled); | 525 | WARN_ON(!node->enabled); |
| 540 | 526 | ||
| 541 | pipe = node->pipe; | 527 | pipe = node->pipe; |
| 542 | dev_dbg(dev, "Try to stream off node [%d][%d]", pipe, node->id); | 528 | dev_dbg(dev, "Try to stream off node [%u][%u]", pipe, node->id); |
| 543 | imgu_pipe = &imgu->imgu_pipe[pipe]; | 529 | imgu_pipe = &imgu->imgu_pipe[pipe]; |
| 544 | r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0); | 530 | r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0); |
| 545 | if (r) | 531 | if (r) |
| @@ -664,20 +650,19 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, | |||
| 664 | struct v4l2_format *f, bool try) | 650 | struct v4l2_format *f, bool try) |
| 665 | { | 651 | { |
| 666 | struct device *dev = &imgu->pci_dev->dev; | 652 | struct device *dev = &imgu->pci_dev->dev; |
| 667 | struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES]; | ||
| 668 | struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; | 653 | struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; |
| 669 | struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; | 654 | struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; |
| 670 | struct v4l2_mbus_framefmt pad_fmt; | 655 | struct v4l2_mbus_framefmt pad_fmt; |
| 671 | unsigned int i, css_q; | 656 | unsigned int i, css_q; |
| 672 | int r; | 657 | int ret; |
| 673 | struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; | 658 | struct imgu_css_pipe *css_pipe = &imgu->css.pipes[pipe]; |
| 674 | struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; | 659 | struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; |
| 675 | struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; | 660 | struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; |
| 676 | 661 | ||
| 677 | dev_dbg(dev, "set fmt node [%u][%u](try = %d)", pipe, node, try); | 662 | dev_dbg(dev, "set fmt node [%u][%u](try = %u)", pipe, node, try); |
| 678 | 663 | ||
| 679 | for (i = 0; i < IMGU_NODE_NUM; i++) | 664 | for (i = 0; i < IMGU_NODE_NUM; i++) |
| 680 | dev_dbg(dev, "IMGU pipe %d node %d enabled = %d", | 665 | dev_dbg(dev, "IMGU pipe %u node %u enabled = %u", |
| 681 | pipe, i, imgu_pipe->nodes[i].enabled); | 666 | pipe, i, imgu_pipe->nodes[i].enabled); |
| 682 | 667 | ||
| 683 | if (imgu_pipe->nodes[IMGU_NODE_VF].enabled) | 668 | if (imgu_pipe->nodes[IMGU_NODE_VF].enabled) |
| @@ -688,7 +673,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, | |||
| 688 | else | 673 | else |
| 689 | css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; | 674 | css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; |
| 690 | 675 | ||
| 691 | dev_dbg(dev, "IPU3 pipe %d pipe_id = %d", pipe, css_pipe->pipe_id); | 676 | dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id); |
| 692 | 677 | ||
| 693 | for (i = 0; i < IPU3_CSS_QUEUES; i++) { | 678 | for (i = 0; i < IPU3_CSS_QUEUES; i++) { |
| 694 | unsigned int inode = imgu_map_node(imgu, i); | 679 | unsigned int inode = imgu_map_node(imgu, i); |
| @@ -698,9 +683,13 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, | |||
| 698 | continue; | 683 | continue; |
| 699 | 684 | ||
| 700 | if (try) { | 685 | if (try) { |
| 701 | try_fmts[i] = | 686 | fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, |
| 702 | imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; | 687 | sizeof(struct v4l2_pix_format_mplane), |
| 703 | fmts[i] = &try_fmts[i]; | 688 | GFP_KERNEL); |
| 689 | if (!fmts[i]) { | ||
| 690 | ret = -ENOMEM; | ||
| 691 | goto out; | ||
| 692 | } | ||
| 704 | } else { | 693 | } else { |
| 705 | fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; | 694 | fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; |
| 706 | } | 695 | } |
| @@ -730,26 +719,33 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, | |||
| 730 | * before we return success from this function, so set it here. | 719 | * before we return success from this function, so set it here. |
| 731 | */ | 720 | */ |
| 732 | css_q = imgu_node_to_queue(node); | 721 | css_q = imgu_node_to_queue(node); |
| 733 | if (fmts[css_q]) | 722 | if (!fmts[css_q]) { |
| 734 | *fmts[css_q] = f->fmt.pix_mp; | 723 | ret = -EINVAL; |
| 735 | else | 724 | goto out; |
| 736 | return -EINVAL; | 725 | } |
| 726 | *fmts[css_q] = f->fmt.pix_mp; | ||
| 737 | 727 | ||
| 738 | if (try) | 728 | if (try) |
| 739 | r = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); | 729 | ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); |
| 740 | else | 730 | else |
| 741 | r = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); | 731 | ret = imgu_css_fmt_set(&imgu->css, fmts, rects, pipe); |
| 742 | 732 | ||
| 743 | /* r is the binary number in the firmware blob */ | 733 | /* ret is the binary number in the firmware blob */ |
| 744 | if (r < 0) | 734 | if (ret < 0) |
| 745 | return r; | 735 | goto out; |
| 746 | 736 | ||
| 747 | if (try) | 737 | if (try) |
| 748 | f->fmt.pix_mp = *fmts[css_q]; | 738 | f->fmt.pix_mp = *fmts[css_q]; |
| 749 | else | 739 | else |
| 750 | f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; | 740 | f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; |
| 751 | 741 | ||
| 752 | return 0; | 742 | out: |
| 743 | if (try) { | ||
| 744 | for (i = 0; i < IPU3_CSS_QUEUES; i++) | ||
| 745 | kfree(fmts[i]); | ||
| 746 | } | ||
| 747 | |||
| 748 | return ret; | ||
| 753 | } | 749 | } |
| 754 | 750 | ||
| 755 | static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f) | 751 | static int imgu_try_fmt(struct file *file, void *fh, struct v4l2_format *f) |
| @@ -781,7 +777,7 @@ static int imgu_vidioc_try_fmt(struct file *file, void *fh, | |||
| 781 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; | 777 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; |
| 782 | int r; | 778 | int r; |
| 783 | 779 | ||
| 784 | dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, | 780 | dev_dbg(dev, "%s [%ux%u] for node %u\n", __func__, |
| 785 | pix_mp->width, pix_mp->height, node->id); | 781 | pix_mp->width, pix_mp->height, node->id); |
| 786 | 782 | ||
| 787 | r = imgu_try_fmt(file, fh, f); | 783 | r = imgu_try_fmt(file, fh, f); |
| @@ -799,7 +795,7 @@ static int imgu_vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) | |||
| 799 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; | 795 | struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; |
| 800 | int r; | 796 | int r; |
| 801 | 797 | ||
| 802 | dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, | 798 | dev_dbg(dev, "%s [%ux%u] for node %u\n", __func__, |
| 803 | pix_mp->width, pix_mp->height, node->id); | 799 | pix_mp->width, pix_mp->height, node->id); |
| 804 | 800 | ||
| 805 | r = imgu_try_fmt(file, fh, f); | 801 | r = imgu_try_fmt(file, fh, f); |
| @@ -1022,7 +1018,7 @@ static int imgu_sd_s_ctrl(struct v4l2_ctrl *ctrl) | |||
| 1022 | struct imgu_device *imgu = v4l2_get_subdevdata(&imgu_sd->subdev); | 1018 | struct imgu_device *imgu = v4l2_get_subdevdata(&imgu_sd->subdev); |
| 1023 | struct device *dev = &imgu->pci_dev->dev; | 1019 | struct device *dev = &imgu->pci_dev->dev; |
| 1024 | 1020 | ||
| 1025 | dev_dbg(dev, "set val %d to ctrl 0x%8x for subdev %d", | 1021 | dev_dbg(dev, "set val %d to ctrl 0x%8x for subdev %u", |
| 1026 | ctrl->val, ctrl->id, imgu_sd->pipe); | 1022 | ctrl->val, ctrl->id, imgu_sd->pipe); |
| 1027 | 1023 | ||
| 1028 | switch (ctrl->id) { | 1024 | switch (ctrl->id) { |
| @@ -1122,7 +1118,7 @@ static int imgu_v4l2_subdev_register(struct imgu_device *imgu, | |||
| 1122 | imgu_sd->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | | 1118 | imgu_sd->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | |
| 1123 | V4L2_SUBDEV_FL_HAS_EVENTS; | 1119 | V4L2_SUBDEV_FL_HAS_EVENTS; |
| 1124 | snprintf(imgu_sd->subdev.name, sizeof(imgu_sd->subdev.name), | 1120 | snprintf(imgu_sd->subdev.name, sizeof(imgu_sd->subdev.name), |
| 1125 | "%s %d", IMGU_NAME, pipe); | 1121 | "%s %u", IMGU_NAME, pipe); |
| 1126 | v4l2_set_subdevdata(&imgu_sd->subdev, imgu); | 1122 | v4l2_set_subdevdata(&imgu_sd->subdev, imgu); |
| 1127 | atomic_set(&imgu_sd->running_mode, IPU3_RUNNING_MODE_VIDEO); | 1123 | atomic_set(&imgu_sd->running_mode, IPU3_RUNNING_MODE_VIDEO); |
| 1128 | v4l2_ctrl_handler_init(hdl, 1); | 1124 | v4l2_ctrl_handler_init(hdl, 1); |
| @@ -1240,7 +1236,7 @@ static int imgu_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, | |||
| 1240 | } | 1236 | } |
| 1241 | 1237 | ||
| 1242 | /* Initialize vdev */ | 1238 | /* Initialize vdev */ |
| 1243 | snprintf(vdev->name, sizeof(vdev->name), "%s %d %s", | 1239 | snprintf(vdev->name, sizeof(vdev->name), "%s %u %s", |
| 1244 | IMGU_NAME, pipe, node->name); | 1240 | IMGU_NAME, pipe, node->name); |
| 1245 | vdev->release = video_device_release_empty; | 1241 | vdev->release = video_device_release_empty; |
| 1246 | vdev->fops = &imgu_v4l2_fops; | 1242 | vdev->fops = &imgu_v4l2_fops; |
| @@ -1335,7 +1331,7 @@ static int imgu_v4l2_register_pipes(struct imgu_device *imgu) | |||
| 1335 | r = imgu_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); | 1331 | r = imgu_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); |
| 1336 | if (r) { | 1332 | if (r) { |
| 1337 | dev_err(&imgu->pci_dev->dev, | 1333 | dev_err(&imgu->pci_dev->dev, |
| 1338 | "failed to register subdev%d ret (%d)\n", i, r); | 1334 | "failed to register subdev%u ret (%d)\n", i, r); |
| 1339 | goto pipes_cleanup; | 1335 | goto pipes_cleanup; |
| 1340 | } | 1336 | } |
| 1341 | r = imgu_v4l2_nodes_setup_pipe(imgu, i); | 1337 | r = imgu_v4l2_nodes_setup_pipe(imgu, i); |
diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c index e0bbdad7cf5b..a7372395a101 100644 --- a/drivers/staging/media/ipu3/ipu3.c +++ b/drivers/staging/media/ipu3/ipu3.c | |||
| @@ -236,6 +236,11 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe | |||
| 236 | dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe); | 236 | dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe); |
| 237 | mutex_lock(&imgu->lock); | 237 | mutex_lock(&imgu->lock); |
| 238 | 238 | ||
| 239 | if (!imgu_css_pipe_queue_empty(&imgu->css, pipe)) { | ||
| 240 | mutex_unlock(&imgu->lock); | ||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 239 | /* Buffer set is queued to FW only when input buffer is ready */ | 244 | /* Buffer set is queued to FW only when input buffer is ready */ |
| 240 | for (node = IMGU_NODE_NUM - 1; | 245 | for (node = IMGU_NODE_NUM - 1; |
| 241 | imgu_queue_getbuf(imgu, IMGU_NODE_IN, pipe); | 246 | imgu_queue_getbuf(imgu, IMGU_NODE_IN, pipe); |
| @@ -245,6 +250,31 @@ int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe | |||
| 245 | dev_warn(&imgu->pci_dev->dev, | 250 | dev_warn(&imgu->pci_dev->dev, |
| 246 | "Vf not enabled, ignore queue"); | 251 | "Vf not enabled, ignore queue"); |
| 247 | continue; | 252 | continue; |
| 253 | } else if (node == IMGU_NODE_PARAMS && | ||
| 254 | imgu_pipe->nodes[node].enabled) { | ||
| 255 | struct vb2_buffer *vb; | ||
| 256 | struct imgu_vb2_buffer *ivb; | ||
| 257 | |||
| 258 | /* No parameters for this frame */ | ||
| 259 | if (list_empty(&imgu_pipe->nodes[node].buffers)) | ||
| 260 | continue; | ||
| 261 | |||
| 262 | ivb = list_first_entry(&imgu_pipe->nodes[node].buffers, | ||
| 263 | struct imgu_vb2_buffer, list); | ||
| 264 | vb = &ivb->vbb.vb2_buf; | ||
| 265 | r = imgu_css_set_parameters(&imgu->css, pipe, | ||
| 266 | vb2_plane_vaddr(vb, 0)); | ||
| 267 | if (r) { | ||
| 268 | vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); | ||
| 269 | dev_warn(&imgu->pci_dev->dev, | ||
| 270 | "set parameters failed."); | ||
| 271 | continue; | ||
| 272 | } | ||
| 273 | |||
| 274 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | ||
| 275 | dev_dbg(&imgu->pci_dev->dev, | ||
| 276 | "queue user parameters %d to css.", vb->index); | ||
| 277 | list_del(&ivb->list); | ||
| 248 | } else if (imgu_pipe->queue_enabled[node]) { | 278 | } else if (imgu_pipe->queue_enabled[node]) { |
| 249 | struct imgu_css_buffer *buf = | 279 | struct imgu_css_buffer *buf = |
| 250 | imgu_queue_getbuf(imgu, node, pipe); | 280 | imgu_queue_getbuf(imgu, node, pipe); |
| @@ -790,7 +820,7 @@ out: | |||
| 790 | * PCI rpm framework checks the existence of driver rpm callbacks. | 820 | * PCI rpm framework checks the existence of driver rpm callbacks. |
| 791 | * Place a dummy callback here to avoid rpm going into error state. | 821 | * Place a dummy callback here to avoid rpm going into error state. |
| 792 | */ | 822 | */ |
| 793 | static int imgu_rpm_dummy_cb(struct device *dev) | 823 | static __maybe_unused int imgu_rpm_dummy_cb(struct device *dev) |
| 794 | { | 824 | { |
| 795 | return 0; | 825 | return 0; |
| 796 | } | 826 | } |
diff --git a/drivers/staging/media/mt9t031/Kconfig b/drivers/staging/media/mt9t031/Kconfig deleted file mode 100644 index 232f0cdca68b..000000000000 --- a/drivers/staging/media/mt9t031/Kconfig +++ /dev/null | |||
| @@ -1,6 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | config SOC_CAMERA_MT9T031 | ||
| 3 | tristate "mt9t031 support (DEPRECATED)" | ||
| 4 | depends on SOC_CAMERA && I2C | ||
| 5 | help | ||
| 6 | This driver supports MT9T031 cameras from Micron. | ||
diff --git a/drivers/staging/media/mt9t031/Makefile b/drivers/staging/media/mt9t031/Makefile deleted file mode 100644 index f663f73a5474..000000000000 --- a/drivers/staging/media/mt9t031/Makefile +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o | ||
diff --git a/drivers/staging/media/mt9t031/TODO b/drivers/staging/media/mt9t031/TODO deleted file mode 100644 index 15580a4f950c..000000000000 --- a/drivers/staging/media/mt9t031/TODO +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | This sensor driver needs to be converted to a regular | ||
| 2 | v4l2 subdev driver. The soc_camera framework is deprecated and | ||
| 3 | will be removed in the future. Unless someone does this work this | ||
| 4 | sensor driver will be deleted when the soc_camera framework is | ||
| 5 | deleted. | ||
diff --git a/drivers/staging/media/omap4iss/Kconfig b/drivers/staging/media/omap4iss/Kconfig index 841cc0b3ce13..4dcbc5065821 100644 --- a/drivers/staging/media/omap4iss/Kconfig +++ b/drivers/staging/media/omap4iss/Kconfig | |||
| @@ -6,5 +6,5 @@ config VIDEO_OMAP4 | |||
| 6 | depends on ARCH_OMAP4 || COMPILE_TEST | 6 | depends on ARCH_OMAP4 || COMPILE_TEST |
| 7 | select MFD_SYSCON | 7 | select MFD_SYSCON |
| 8 | select VIDEOBUF2_DMA_CONTIG | 8 | select VIDEOBUF2_DMA_CONTIG |
| 9 | ---help--- | 9 | help |
| 10 | Driver for an OMAP 4 ISS controller. | 10 | Driver for an OMAP 4 ISS controller. |
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c index 962412c79b91..58721c46fba4 100644 --- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include <media/v4l2-event.h> | 22 | #include <media/v4l2-event.h> |
| 23 | #include <media/v4l2-mem2mem.h> | 23 | #include <media/v4l2-mem2mem.h> |
| 24 | #include <media/videobuf2-core.h> | 24 | #include <media/videobuf2-core.h> |
| 25 | #include <media/videobuf2-core.h> | ||
| 26 | #include <media/videobuf2-vmalloc.h> | 25 | #include <media/videobuf2-vmalloc.h> |
| 27 | 26 | ||
| 28 | #include "rockchip_vpu_common.h" | 27 | #include "rockchip_vpu_common.h" |
| @@ -463,7 +462,7 @@ static int rockchip_vpu_probe(struct platform_device *pdev) | |||
| 463 | } | 462 | } |
| 464 | 463 | ||
| 465 | vpu->mdev.dev = vpu->dev; | 464 | vpu->mdev.dev = vpu->dev; |
| 466 | strlcpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); | 465 | strscpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); |
| 467 | media_device_init(&vpu->mdev); | 466 | media_device_init(&vpu->mdev); |
| 468 | vpu->v4l2_dev.mdev = &vpu->mdev; | 467 | vpu->v4l2_dev.mdev = &vpu->mdev; |
| 469 | 468 | ||
diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c index ab0fb2053620..fb5e36aedd8c 100644 --- a/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | * @is_compressed: Is it a compressed format? | 41 | * @is_compressed: Is it a compressed format? |
| 42 | * @multiplanar: Is it a multiplanar variant format? (e.g. NV12M) | 42 | * @multiplanar: Is it a multiplanar variant format? (e.g. NV12M) |
| 43 | */ | 43 | */ |
| 44 | struct v4l2_format_info { | 44 | struct rockchip_vpu_v4l2_format_info { |
| 45 | u32 format; | 45 | u32 format; |
| 46 | u32 header_size; | 46 | u32 header_size; |
| 47 | u8 num_planes; | 47 | u8 num_planes; |
| @@ -52,10 +52,10 @@ struct v4l2_format_info { | |||
| 52 | u8 multiplanar; | 52 | u8 multiplanar; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | static const struct v4l2_format_info * | 55 | static const struct rockchip_vpu_v4l2_format_info * |
| 56 | v4l2_format_info(u32 format) | 56 | rockchip_vpu_v4l2_format_info(u32 format) |
| 57 | { | 57 | { |
| 58 | static const struct v4l2_format_info formats[] = { | 58 | static const struct rockchip_vpu_v4l2_format_info formats[] = { |
| 59 | { .format = V4L2_PIX_FMT_YUV420M, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, | 59 | { .format = V4L2_PIX_FMT_YUV420M, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, |
| 60 | { .format = V4L2_PIX_FMT_NV12M, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, | 60 | { .format = V4L2_PIX_FMT_NV12M, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, |
| 61 | { .format = V4L2_PIX_FMT_YUYV, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 }, | 61 | { .format = V4L2_PIX_FMT_YUYV, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 }, |
| @@ -76,11 +76,11 @@ static void | |||
| 76 | fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, | 76 | fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, |
| 77 | int pixelformat, int width, int height) | 77 | int pixelformat, int width, int height) |
| 78 | { | 78 | { |
| 79 | const struct v4l2_format_info *info; | 79 | const struct rockchip_vpu_v4l2_format_info *info; |
| 80 | struct v4l2_plane_pix_format *plane; | 80 | struct v4l2_plane_pix_format *plane; |
| 81 | int i; | 81 | int i; |
| 82 | 82 | ||
| 83 | info = v4l2_format_info(pixelformat); | 83 | info = rockchip_vpu_v4l2_format_info(pixelformat); |
| 84 | if (!info) | 84 | if (!info) |
| 85 | return; | 85 | return; |
| 86 | 86 | ||
diff --git a/drivers/staging/media/soc_camera/TODO b/drivers/staging/media/soc_camera/TODO new file mode 100644 index 000000000000..932af6443b67 --- /dev/null +++ b/drivers/staging/media/soc_camera/TODO | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | The SoC camera framework is obsolete and scheduled for removal in the near | ||
| 2 | future. Developers are encouraged to convert the drivers to use the | ||
| 3 | regular V4L2 API if these drivers are still needed (and if someone has the | ||
| 4 | hardware). | ||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index ff11cbeba205..d0429c0e6b6b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c | |||
| @@ -300,7 +300,7 @@ static int cedrus_probe(struct platform_device *pdev) | |||
| 300 | "Failed to initialize V4L2 M2M device\n"); | 300 | "Failed to initialize V4L2 M2M device\n"); |
| 301 | ret = PTR_ERR(dev->m2m_dev); | 301 | ret = PTR_ERR(dev->m2m_dev); |
| 302 | 302 | ||
| 303 | goto err_video; | 303 | goto err_v4l2; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | dev->mdev.dev = &pdev->dev; | 306 | dev->mdev.dev = &pdev->dev; |
| @@ -310,23 +310,23 @@ static int cedrus_probe(struct platform_device *pdev) | |||
| 310 | dev->mdev.ops = &cedrus_m2m_media_ops; | 310 | dev->mdev.ops = &cedrus_m2m_media_ops; |
| 311 | dev->v4l2_dev.mdev = &dev->mdev; | 311 | dev->v4l2_dev.mdev = &dev->mdev; |
| 312 | 312 | ||
| 313 | ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, | ||
| 314 | MEDIA_ENT_F_PROC_VIDEO_DECODER); | ||
| 315 | if (ret) { | ||
| 316 | v4l2_err(&dev->v4l2_dev, | ||
| 317 | "Failed to initialize V4L2 M2M media controller\n"); | ||
| 318 | goto err_m2m; | ||
| 319 | } | ||
| 320 | |||
| 321 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); | 313 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
| 322 | if (ret) { | 314 | if (ret) { |
| 323 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); | 315 | v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); |
| 324 | goto err_v4l2; | 316 | goto err_m2m; |
| 325 | } | 317 | } |
| 326 | 318 | ||
| 327 | v4l2_info(&dev->v4l2_dev, | 319 | v4l2_info(&dev->v4l2_dev, |
| 328 | "Device registered as /dev/video%d\n", vfd->num); | 320 | "Device registered as /dev/video%d\n", vfd->num); |
| 329 | 321 | ||
| 322 | ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, | ||
| 323 | MEDIA_ENT_F_PROC_VIDEO_DECODER); | ||
| 324 | if (ret) { | ||
| 325 | v4l2_err(&dev->v4l2_dev, | ||
| 326 | "Failed to initialize V4L2 M2M media controller\n"); | ||
| 327 | goto err_video; | ||
| 328 | } | ||
| 329 | |||
| 330 | ret = media_device_register(&dev->mdev); | 330 | ret = media_device_register(&dev->mdev); |
| 331 | if (ret) { | 331 | if (ret) { |
| 332 | v4l2_err(&dev->v4l2_dev, "Failed to register media device\n"); | 332 | v4l2_err(&dev->v4l2_dev, "Failed to register media device\n"); |
| @@ -339,10 +339,10 @@ static int cedrus_probe(struct platform_device *pdev) | |||
| 339 | 339 | ||
| 340 | err_m2m_mc: | 340 | err_m2m_mc: |
| 341 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); | 341 | v4l2_m2m_unregister_media_controller(dev->m2m_dev); |
| 342 | err_m2m: | ||
| 343 | v4l2_m2m_release(dev->m2m_dev); | ||
| 344 | err_video: | 342 | err_video: |
| 345 | video_unregister_device(&dev->vfd); | 343 | video_unregister_device(&dev->vfd); |
| 344 | err_m2m: | ||
| 345 | v4l2_m2m_release(dev->m2m_dev); | ||
| 346 | err_v4l2: | 346 | err_v4l2: |
| 347 | v4l2_device_unregister(&dev->v4l2_dev); | 347 | v4l2_device_unregister(&dev->v4l2_dev); |
| 348 | 348 | ||
| @@ -396,6 +396,11 @@ static const struct cedrus_variant sun50i_h5_cedrus_variant = { | |||
| 396 | .capabilities = CEDRUS_CAPABILITY_UNTILED, | 396 | .capabilities = CEDRUS_CAPABILITY_UNTILED, |
| 397 | }; | 397 | }; |
| 398 | 398 | ||
| 399 | static const struct cedrus_variant sun50i_h6_cedrus_variant = { | ||
| 400 | .capabilities = CEDRUS_CAPABILITY_UNTILED, | ||
| 401 | .quirks = CEDRUS_QUIRK_NO_DMA_OFFSET, | ||
| 402 | }; | ||
| 403 | |||
| 399 | static const struct of_device_id cedrus_dt_match[] = { | 404 | static const struct of_device_id cedrus_dt_match[] = { |
| 400 | { | 405 | { |
| 401 | .compatible = "allwinner,sun4i-a10-video-engine", | 406 | .compatible = "allwinner,sun4i-a10-video-engine", |
| @@ -425,6 +430,10 @@ static const struct of_device_id cedrus_dt_match[] = { | |||
| 425 | .compatible = "allwinner,sun50i-h5-video-engine", | 430 | .compatible = "allwinner,sun50i-h5-video-engine", |
| 426 | .data = &sun50i_h5_cedrus_variant, | 431 | .data = &sun50i_h5_cedrus_variant, |
| 427 | }, | 432 | }, |
| 433 | { | ||
| 434 | .compatible = "allwinner,sun50i-h6-video-engine", | ||
| 435 | .data = &sun50i_h6_cedrus_variant, | ||
| 436 | }, | ||
| 428 | { /* sentinel */ } | 437 | { /* sentinel */ } |
| 429 | }; | 438 | }; |
| 430 | MODULE_DEVICE_TABLE(of, cedrus_dt_match); | 439 | MODULE_DEVICE_TABLE(of, cedrus_dt_match); |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 4aedd24a9848..c57c04b41d2e 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | 28 | ||
| 29 | #define CEDRUS_CAPABILITY_UNTILED BIT(0) | 29 | #define CEDRUS_CAPABILITY_UNTILED BIT(0) |
| 30 | 30 | ||
| 31 | #define CEDRUS_QUIRK_NO_DMA_OFFSET BIT(0) | ||
| 32 | |||
| 31 | enum cedrus_codec { | 33 | enum cedrus_codec { |
| 32 | CEDRUS_CODEC_MPEG2, | 34 | CEDRUS_CODEC_MPEG2, |
| 33 | 35 | ||
| @@ -91,6 +93,7 @@ struct cedrus_dec_ops { | |||
| 91 | 93 | ||
| 92 | struct cedrus_variant { | 94 | struct cedrus_variant { |
| 93 | unsigned int capabilities; | 95 | unsigned int capabilities; |
| 96 | unsigned int quirks; | ||
| 94 | }; | 97 | }; |
| 95 | 98 | ||
| 96 | struct cedrus_dev { | 99 | struct cedrus_dev { |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index 0acf219a8c91..fbfff7c1c771 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c | |||
| @@ -177,7 +177,8 @@ int cedrus_hw_probe(struct cedrus_dev *dev) | |||
| 177 | */ | 177 | */ |
| 178 | 178 | ||
| 179 | #ifdef PHYS_PFN_OFFSET | 179 | #ifdef PHYS_PFN_OFFSET |
| 180 | dev->dev->dma_pfn_offset = PHYS_PFN_OFFSET; | 180 | if (!(variant->quirks & CEDRUS_QUIRK_NO_DMA_OFFSET)) |
| 181 | dev->dev->dma_pfn_offset = PHYS_PFN_OFFSET; | ||
| 181 | #endif | 182 | #endif |
| 182 | 183 | ||
| 183 | ret = of_reserved_mem_device_init(dev->dev); | 184 | ret = of_reserved_mem_device_init(dev->dev); |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index b47854b3bce4..9673874ece10 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c | |||
| @@ -536,6 +536,7 @@ int cedrus_queue_init(void *priv, struct vb2_queue *src_vq, | |||
| 536 | src_vq->lock = &ctx->dev->dev_mutex; | 536 | src_vq->lock = &ctx->dev->dev_mutex; |
| 537 | src_vq->dev = ctx->dev->dev; | 537 | src_vq->dev = ctx->dev->dev; |
| 538 | src_vq->supports_requests = true; | 538 | src_vq->supports_requests = true; |
| 539 | src_vq->requires_requests = true; | ||
| 539 | 540 | ||
| 540 | ret = vb2_queue_init(src_vq); | 541 | ret = vb2_queue_init(src_vq); |
| 541 | if (ret) | 542 | if (ret) |
diff --git a/drivers/staging/media/zoran/Kconfig b/drivers/staging/media/zoran/Kconfig deleted file mode 100644 index 84502b0fe48a..000000000000 --- a/drivers/staging/media/zoran/Kconfig +++ /dev/null | |||
| @@ -1,76 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | config VIDEO_ZORAN | ||
| 3 | tristate "Zoran ZR36057/36067 Video For Linux (Deprecated)" | ||
| 4 | depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS | ||
| 5 | depends on !ALPHA | ||
| 6 | help | ||
| 7 | Say Y for support for MJPEG capture cards based on the Zoran | ||
| 8 | 36057/36067 PCI controller chipset. This includes the Iomega | ||
| 9 | Buz, Pinnacle DC10+ and the Linux Media Labs LML33. There is | ||
| 10 | a driver homepage at <http://mjpeg.sf.net/driver-zoran/>. For | ||
| 11 | more information, check <file:Documentation/media/v4l-drivers/zoran.rst>. | ||
| 12 | |||
| 13 | To compile this driver as a module, choose M here: the | ||
| 14 | module will be called zr36067. | ||
| 15 | |||
| 16 | config VIDEO_ZORAN_DC30 | ||
| 17 | tristate "Pinnacle/Miro DC30(+) support" | ||
| 18 | depends on VIDEO_ZORAN | ||
| 19 | select VIDEO_ADV7175 if MEDIA_SUBDRV_AUTOSELECT | ||
| 20 | select VIDEO_VPX3220 if MEDIA_SUBDRV_AUTOSELECT | ||
| 21 | help | ||
| 22 | Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback | ||
| 23 | card. This also supports really old DC10 cards based on the | ||
| 24 | zr36050 MJPEG codec and zr36016 VFE. | ||
| 25 | |||
| 26 | config VIDEO_ZORAN_ZR36060 | ||
| 27 | tristate "Zoran ZR36060" | ||
| 28 | depends on VIDEO_ZORAN | ||
| 29 | help | ||
| 30 | Say Y to support Zoran boards based on 36060 chips. | ||
| 31 | This includes Iomega Buz, Pinnacle DC10, Linux media Labs 33 | ||
| 32 | and 33 R10 and AverMedia 6 boards. | ||
| 33 | |||
| 34 | config VIDEO_ZORAN_BUZ | ||
| 35 | tristate "Iomega Buz support" | ||
| 36 | depends on VIDEO_ZORAN_ZR36060 | ||
| 37 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT | ||
| 38 | select VIDEO_SAA7185 if MEDIA_SUBDRV_AUTOSELECT | ||
| 39 | help | ||
| 40 | Support for the Iomega Buz MJPEG capture/playback card. | ||
| 41 | |||
| 42 | config VIDEO_ZORAN_DC10 | ||
| 43 | tristate "Pinnacle/Miro DC10(+) support" | ||
| 44 | depends on VIDEO_ZORAN_ZR36060 | ||
| 45 | select VIDEO_SAA7110 if MEDIA_SUBDRV_AUTOSELECT | ||
| 46 | select VIDEO_ADV7175 if MEDIA_SUBDRV_AUTOSELECT | ||
| 47 | help | ||
| 48 | Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback | ||
| 49 | card. | ||
| 50 | |||
| 51 | config VIDEO_ZORAN_LML33 | ||
| 52 | tristate "Linux Media Labs LML33 support" | ||
| 53 | depends on VIDEO_ZORAN_ZR36060 | ||
| 54 | select VIDEO_BT819 if MEDIA_SUBDRV_AUTOSELECT | ||
| 55 | select VIDEO_BT856 if MEDIA_SUBDRV_AUTOSELECT | ||
| 56 | help | ||
| 57 | Support for the Linux Media Labs LML33 MJPEG capture/playback | ||
| 58 | card. | ||
| 59 | |||
| 60 | config VIDEO_ZORAN_LML33R10 | ||
| 61 | tristate "Linux Media Labs LML33R10 support" | ||
| 62 | depends on VIDEO_ZORAN_ZR36060 | ||
| 63 | select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT | ||
| 64 | select VIDEO_ADV7170 if MEDIA_SUBDRV_AUTOSELECT | ||
| 65 | help | ||
| 66 | support for the Linux Media Labs LML33R10 MJPEG capture/playback | ||
| 67 | card. | ||
| 68 | |||
| 69 | config VIDEO_ZORAN_AVS6EYES | ||
| 70 | tristate "AverMedia 6 Eyes support" | ||
| 71 | depends on VIDEO_ZORAN_ZR36060 | ||
| 72 | select VIDEO_BT856 if MEDIA_SUBDRV_AUTOSELECT | ||
| 73 | select VIDEO_BT866 if MEDIA_SUBDRV_AUTOSELECT | ||
| 74 | select VIDEO_KS0127 if MEDIA_SUBDRV_AUTOSELECT | ||
| 75 | help | ||
| 76 | Support for the AverMedia 6 Eyes video surveillance card. | ||
diff --git a/drivers/staging/media/zoran/Makefile b/drivers/staging/media/zoran/Makefile deleted file mode 100644 index 21ac29a71458..000000000000 --- a/drivers/staging/media/zoran/Makefile +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | zr36067-objs := zoran_procfs.o zoran_device.o \ | ||
| 3 | zoran_driver.o zoran_card.o | ||
| 4 | |||
| 5 | obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o | ||
| 6 | obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o | ||
| 7 | obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o | ||
diff --git a/drivers/staging/media/zoran/TODO b/drivers/staging/media/zoran/TODO deleted file mode 100644 index 54464095d0d7..000000000000 --- a/drivers/staging/media/zoran/TODO +++ /dev/null | |||
| @@ -1,4 +0,0 @@ | |||
| 1 | The zoran driver is marked deprecated. It will be removed | ||
| 2 | around May 2019 unless someone is willing to update this | ||
| 3 | driver to the latest V4L2 frameworks (especially the vb2 | ||
| 4 | framework). | ||
diff --git a/drivers/staging/media/zoran/videocodec.c b/drivers/staging/media/zoran/videocodec.c deleted file mode 100644 index c1ee5cb7e66b..000000000000 --- a/drivers/staging/media/zoran/videocodec.c +++ /dev/null | |||
| @@ -1,379 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * VIDEO MOTION CODECs internal API for video devices | ||
| 4 | * | ||
| 5 | * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's | ||
| 6 | * bound to a master device. | ||
| 7 | * | ||
| 8 | * (c) 2002 Wolfgang Scherr <scherr@net4you.at> | ||
| 9 | * | ||
| 10 | * $Id: videocodec.c,v 1.1.2.8 2003/03/29 07:16:04 rbultje Exp $ | ||
| 11 | * ------------------------------------------------------------------------ | ||
| 12 | */ | ||
| 13 | |||
| 14 | #define VIDEOCODEC_VERSION "v0.2" | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/types.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | |||
| 22 | // kernel config is here (procfs flag) | ||
| 23 | |||
| 24 | #ifdef CONFIG_PROC_FS | ||
| 25 | #include <linux/proc_fs.h> | ||
| 26 | #include <linux/seq_file.h> | ||
| 27 | #include <linux/uaccess.h> | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #include "videocodec.h" | ||
| 31 | |||
| 32 | static int debug; | ||
| 33 | module_param(debug, int, 0); | ||
| 34 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
| 35 | |||
| 36 | #define dprintk(num, format, args...) \ | ||
| 37 | do { \ | ||
| 38 | if (debug >= num) \ | ||
| 39 | printk(format, ##args); \ | ||
| 40 | } while (0) | ||
| 41 | |||
| 42 | struct attached_list { | ||
| 43 | struct videocodec *codec; | ||
| 44 | struct attached_list *next; | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct codec_list { | ||
| 48 | const struct videocodec *codec; | ||
| 49 | int attached; | ||
| 50 | struct attached_list *list; | ||
| 51 | struct codec_list *next; | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct codec_list *codeclist_top = NULL; | ||
| 55 | |||
| 56 | /* ================================================= */ | ||
| 57 | /* function prototypes of the master/slave interface */ | ||
| 58 | /* ================================================= */ | ||
| 59 | |||
| 60 | struct videocodec * | ||
| 61 | videocodec_attach (struct videocodec_master *master) | ||
| 62 | { | ||
| 63 | struct codec_list *h = codeclist_top; | ||
| 64 | struct attached_list *a, *ptr; | ||
| 65 | struct videocodec *codec; | ||
| 66 | int res; | ||
| 67 | |||
| 68 | if (!master) { | ||
| 69 | dprintk(1, KERN_ERR "videocodec_attach: no data\n"); | ||
| 70 | return NULL; | ||
| 71 | } | ||
| 72 | |||
| 73 | dprintk(2, | ||
| 74 | "videocodec_attach: '%s', flags %lx, magic %lx\n", | ||
| 75 | master->name, master->flags, master->magic); | ||
| 76 | |||
| 77 | if (!h) { | ||
| 78 | dprintk(1, | ||
| 79 | KERN_ERR | ||
| 80 | "videocodec_attach: no device available\n"); | ||
| 81 | return NULL; | ||
| 82 | } | ||
| 83 | |||
| 84 | while (h) { | ||
| 85 | // attach only if the slave has at least the flags | ||
| 86 | // expected by the master | ||
| 87 | if ((master->flags & h->codec->flags) == master->flags) { | ||
| 88 | dprintk(4, "videocodec_attach: try '%s'\n", | ||
| 89 | h->codec->name); | ||
| 90 | |||
| 91 | if (!try_module_get(h->codec->owner)) | ||
| 92 | return NULL; | ||
| 93 | |||
| 94 | codec = kmemdup(h->codec, sizeof(struct videocodec), | ||
| 95 | GFP_KERNEL); | ||
| 96 | if (!codec) { | ||
| 97 | dprintk(1, | ||
| 98 | KERN_ERR | ||
| 99 | "videocodec_attach: no mem\n"); | ||
| 100 | goto out_module_put; | ||
| 101 | } | ||
| 102 | |||
| 103 | res = strlen(codec->name); | ||
| 104 | snprintf(codec->name + res, sizeof(codec->name) - res, | ||
| 105 | "[%d]", h->attached); | ||
| 106 | codec->master_data = master; | ||
| 107 | res = codec->setup(codec); | ||
| 108 | if (res == 0) { | ||
| 109 | dprintk(3, "videocodec_attach '%s'\n", | ||
| 110 | codec->name); | ||
| 111 | ptr = kzalloc(sizeof(struct attached_list), GFP_KERNEL); | ||
| 112 | if (!ptr) { | ||
| 113 | dprintk(1, | ||
| 114 | KERN_ERR | ||
| 115 | "videocodec_attach: no memory\n"); | ||
| 116 | goto out_kfree; | ||
| 117 | } | ||
| 118 | ptr->codec = codec; | ||
| 119 | |||
| 120 | a = h->list; | ||
| 121 | if (!a) { | ||
| 122 | h->list = ptr; | ||
| 123 | dprintk(4, | ||
| 124 | "videocodec: first element\n"); | ||
| 125 | } else { | ||
| 126 | while (a->next) | ||
| 127 | a = a->next; // find end | ||
| 128 | a->next = ptr; | ||
| 129 | dprintk(4, | ||
| 130 | "videocodec: in after '%s'\n", | ||
| 131 | h->codec->name); | ||
| 132 | } | ||
| 133 | |||
| 134 | h->attached += 1; | ||
| 135 | return codec; | ||
| 136 | } else { | ||
| 137 | kfree(codec); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | h = h->next; | ||
| 141 | } | ||
| 142 | |||
| 143 | dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n"); | ||
| 144 | return NULL; | ||
| 145 | |||
| 146 | out_module_put: | ||
| 147 | module_put(h->codec->owner); | ||
| 148 | out_kfree: | ||
| 149 | kfree(codec); | ||
| 150 | return NULL; | ||
| 151 | } | ||
| 152 | |||
| 153 | int | ||
| 154 | videocodec_detach (struct videocodec *codec) | ||
| 155 | { | ||
| 156 | struct codec_list *h = codeclist_top; | ||
| 157 | struct attached_list *a, *prev; | ||
| 158 | int res; | ||
| 159 | |||
| 160 | if (!codec) { | ||
| 161 | dprintk(1, KERN_ERR "videocodec_detach: no data\n"); | ||
| 162 | return -EINVAL; | ||
| 163 | } | ||
| 164 | |||
| 165 | dprintk(2, | ||
| 166 | "videocodec_detach: '%s', type: %x, flags %lx, magic %lx\n", | ||
| 167 | codec->name, codec->type, codec->flags, codec->magic); | ||
| 168 | |||
| 169 | if (!h) { | ||
| 170 | dprintk(1, | ||
| 171 | KERN_ERR "videocodec_detach: no device left...\n"); | ||
| 172 | return -ENXIO; | ||
| 173 | } | ||
| 174 | |||
| 175 | while (h) { | ||
| 176 | a = h->list; | ||
| 177 | prev = NULL; | ||
| 178 | while (a) { | ||
| 179 | if (codec == a->codec) { | ||
| 180 | res = a->codec->unset(a->codec); | ||
| 181 | if (res >= 0) { | ||
| 182 | dprintk(3, | ||
| 183 | "videocodec_detach: '%s'\n", | ||
| 184 | a->codec->name); | ||
| 185 | a->codec->master_data = NULL; | ||
| 186 | } else { | ||
| 187 | dprintk(1, | ||
| 188 | KERN_ERR | ||
| 189 | "videocodec_detach: '%s'\n", | ||
| 190 | a->codec->name); | ||
| 191 | a->codec->master_data = NULL; | ||
| 192 | } | ||
| 193 | if (prev == NULL) { | ||
| 194 | h->list = a->next; | ||
| 195 | dprintk(4, | ||
| 196 | "videocodec: delete first\n"); | ||
| 197 | } else { | ||
| 198 | prev->next = a->next; | ||
| 199 | dprintk(4, | ||
| 200 | "videocodec: delete middle\n"); | ||
| 201 | } | ||
| 202 | module_put(a->codec->owner); | ||
| 203 | kfree(a->codec); | ||
| 204 | kfree(a); | ||
| 205 | h->attached -= 1; | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | prev = a; | ||
| 209 | a = a->next; | ||
| 210 | } | ||
| 211 | h = h->next; | ||
| 212 | } | ||
| 213 | |||
| 214 | dprintk(1, KERN_ERR "videocodec_detach: given codec not found!\n"); | ||
| 215 | return -EINVAL; | ||
| 216 | } | ||
| 217 | |||
| 218 | int | ||
| 219 | videocodec_register (const struct videocodec *codec) | ||
| 220 | { | ||
| 221 | struct codec_list *ptr, *h = codeclist_top; | ||
| 222 | |||
| 223 | if (!codec) { | ||
| 224 | dprintk(1, KERN_ERR "videocodec_register: no data!\n"); | ||
| 225 | return -EINVAL; | ||
| 226 | } | ||
| 227 | |||
| 228 | dprintk(2, | ||
| 229 | "videocodec: register '%s', type: %x, flags %lx, magic %lx\n", | ||
| 230 | codec->name, codec->type, codec->flags, codec->magic); | ||
| 231 | |||
| 232 | ptr = kzalloc(sizeof(struct codec_list), GFP_KERNEL); | ||
| 233 | if (!ptr) { | ||
| 234 | dprintk(1, KERN_ERR "videocodec_register: no memory\n"); | ||
| 235 | return -ENOMEM; | ||
| 236 | } | ||
| 237 | ptr->codec = codec; | ||
| 238 | |||
| 239 | if (!h) { | ||
| 240 | codeclist_top = ptr; | ||
| 241 | dprintk(4, "videocodec: hooked in as first element\n"); | ||
| 242 | } else { | ||
| 243 | while (h->next) | ||
| 244 | h = h->next; // find the end | ||
| 245 | h->next = ptr; | ||
| 246 | dprintk(4, "videocodec: hooked in after '%s'\n", | ||
| 247 | h->codec->name); | ||
| 248 | } | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | int | ||
| 254 | videocodec_unregister (const struct videocodec *codec) | ||
| 255 | { | ||
| 256 | struct codec_list *prev = NULL, *h = codeclist_top; | ||
| 257 | |||
| 258 | if (!codec) { | ||
| 259 | dprintk(1, KERN_ERR "videocodec_unregister: no data!\n"); | ||
| 260 | return -EINVAL; | ||
| 261 | } | ||
| 262 | |||
| 263 | dprintk(2, | ||
| 264 | "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n", | ||
| 265 | codec->name, codec->type, codec->flags, codec->magic); | ||
| 266 | |||
| 267 | if (!h) { | ||
| 268 | dprintk(1, | ||
| 269 | KERN_ERR | ||
| 270 | "videocodec_unregister: no device left...\n"); | ||
| 271 | return -ENXIO; | ||
| 272 | } | ||
| 273 | |||
| 274 | while (h) { | ||
| 275 | if (codec == h->codec) { | ||
| 276 | if (h->attached) { | ||
| 277 | dprintk(1, | ||
| 278 | KERN_ERR | ||
| 279 | "videocodec: '%s' is used\n", | ||
| 280 | h->codec->name); | ||
| 281 | return -EBUSY; | ||
| 282 | } | ||
| 283 | dprintk(3, "videocodec: unregister '%s' is ok.\n", | ||
| 284 | h->codec->name); | ||
| 285 | if (prev == NULL) { | ||
| 286 | codeclist_top = h->next; | ||
| 287 | dprintk(4, | ||
| 288 | "videocodec: delete first element\n"); | ||
| 289 | } else { | ||
| 290 | prev->next = h->next; | ||
| 291 | dprintk(4, | ||
| 292 | "videocodec: delete middle element\n"); | ||
| 293 | } | ||
| 294 | kfree(h); | ||
| 295 | return 0; | ||
| 296 | } | ||
| 297 | prev = h; | ||
| 298 | h = h->next; | ||
| 299 | } | ||
| 300 | |||
| 301 | dprintk(1, | ||
| 302 | KERN_ERR | ||
| 303 | "videocodec_unregister: given codec not found!\n"); | ||
| 304 | return -EINVAL; | ||
| 305 | } | ||
| 306 | |||
| 307 | #ifdef CONFIG_PROC_FS | ||
| 308 | static int proc_videocodecs_show(struct seq_file *m, void *v) | ||
| 309 | { | ||
| 310 | struct codec_list *h = codeclist_top; | ||
| 311 | struct attached_list *a; | ||
| 312 | |||
| 313 | seq_printf(m, "<S>lave or attached <M>aster name type flags magic "); | ||
| 314 | seq_printf(m, "(connected as)\n"); | ||
| 315 | |||
| 316 | while (h) { | ||
| 317 | seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n", | ||
| 318 | h->codec->name, h->codec->type, | ||
| 319 | h->codec->flags, h->codec->magic); | ||
| 320 | a = h->list; | ||
| 321 | while (a) { | ||
| 322 | seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n", | ||
| 323 | a->codec->master_data->name, | ||
| 324 | a->codec->master_data->type, | ||
| 325 | a->codec->master_data->flags, | ||
| 326 | a->codec->master_data->magic, | ||
| 327 | a->codec->name); | ||
| 328 | a = a->next; | ||
| 329 | } | ||
| 330 | h = h->next; | ||
| 331 | } | ||
| 332 | |||
| 333 | return 0; | ||
| 334 | } | ||
| 335 | #endif | ||
| 336 | |||
| 337 | /* ===================== */ | ||
| 338 | /* hook in driver module */ | ||
| 339 | /* ===================== */ | ||
| 340 | static int __init | ||
| 341 | videocodec_init (void) | ||
| 342 | { | ||
| 343 | #ifdef CONFIG_PROC_FS | ||
| 344 | static struct proc_dir_entry *videocodec_proc_entry; | ||
| 345 | #endif | ||
| 346 | |||
| 347 | printk(KERN_INFO "Linux video codec intermediate layer: %s\n", | ||
| 348 | VIDEOCODEC_VERSION); | ||
| 349 | |||
| 350 | #ifdef CONFIG_PROC_FS | ||
| 351 | videocodec_proc_entry = proc_create_single("videocodecs", 0, NULL, | ||
| 352 | proc_videocodecs_show); | ||
| 353 | if (!videocodec_proc_entry) { | ||
| 354 | dprintk(1, KERN_ERR "videocodec: can't init procfs.\n"); | ||
| 355 | } | ||
| 356 | #endif | ||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | |||
| 360 | static void __exit | ||
| 361 | videocodec_exit (void) | ||
| 362 | { | ||
| 363 | #ifdef CONFIG_PROC_FS | ||
| 364 | remove_proc_entry("videocodecs", NULL); | ||
| 365 | #endif | ||
| 366 | } | ||
| 367 | |||
| 368 | EXPORT_SYMBOL(videocodec_attach); | ||
| 369 | EXPORT_SYMBOL(videocodec_detach); | ||
| 370 | EXPORT_SYMBOL(videocodec_register); | ||
| 371 | EXPORT_SYMBOL(videocodec_unregister); | ||
| 372 | |||
| 373 | module_init(videocodec_init); | ||
| 374 | module_exit(videocodec_exit); | ||
| 375 | |||
| 376 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
| 377 | MODULE_DESCRIPTION("Intermediate API module for video codecs " | ||
| 378 | VIDEOCODEC_VERSION); | ||
| 379 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/media/zoran/videocodec.h b/drivers/staging/media/zoran/videocodec.h deleted file mode 100644 index 4946791fce0d..000000000000 --- a/drivers/staging/media/zoran/videocodec.h +++ /dev/null | |||
| @@ -1,334 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * VIDEO MOTION CODECs internal API for video devices | ||
| 4 | * | ||
| 5 | * Interface for MJPEG (and maybe later MPEG/WAVELETS) codec's | ||
| 6 | * bound to a master device. | ||
| 7 | * | ||
| 8 | * (c) 2002 Wolfgang Scherr <scherr@net4you.at> | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* =================== */ | ||
| 12 | /* general description */ | ||
| 13 | /* =================== */ | ||
| 14 | |||
| 15 | /* Should ease the (re-)usage of drivers supporting cards with (different) | ||
| 16 | video codecs. The codecs register to this module their functionality, | ||
| 17 | and the processors (masters) can attach to them if they fit. | ||
| 18 | |||
| 19 | The codecs are typically have a "strong" binding to their master - so I | ||
| 20 | don't think it makes sense to have a full blown interfacing as with e.g. | ||
| 21 | i2c. If you have an other opinion, let's discuss & implement it :-))) | ||
| 22 | |||
| 23 | Usage: | ||
| 24 | |||
| 25 | The slave has just to setup the videocodec structure and use two functions: | ||
| 26 | videocodec_register(codecdata); | ||
| 27 | videocodec_unregister(codecdata); | ||
| 28 | The best is just calling them at module (de-)initialisation. | ||
| 29 | |||
| 30 | The master sets up the structure videocodec_master and calls: | ||
| 31 | codecdata=videocodec_attach(master_codecdata); | ||
| 32 | videocodec_detach(codecdata); | ||
| 33 | |||
| 34 | The slave is called during attach/detach via functions setup previously | ||
| 35 | during register. At that time, the master_data pointer is set up | ||
| 36 | and the slave can access any io registers of the master device (in the case | ||
| 37 | the slave is bound to it). Otherwise it doesn't need this functions and | ||
| 38 | therfor they may not be initialized. | ||
| 39 | |||
| 40 | The other functions are just for convenience, as they are for sure used by | ||
| 41 | most/all of the codecs. The last ones may be omitted, too. | ||
| 42 | |||
| 43 | See the structure declaration below for more information and which data has | ||
| 44 | to be set up for the master and the slave. | ||
| 45 | |||
| 46 | ---------------------------------------------------------------------------- | ||
| 47 | The master should have "knowledge" of the slave and vice versa. So the data | ||
| 48 | structures sent to/from slave via set_data/get_data set_image/get_image are | ||
| 49 | device dependent and vary between MJPEG/MPEG/WAVELET/... devices. (!!!!) | ||
| 50 | ---------------------------------------------------------------------------- | ||
| 51 | */ | ||
| 52 | |||
| 53 | |||
| 54 | /* ========================================== */ | ||
| 55 | /* description of the videocodec_io structure */ | ||
| 56 | /* ========================================== */ | ||
| 57 | |||
| 58 | /* | ||
| 59 | ==== master setup ==== | ||
| 60 | name -> name of the device structure for reference and debugging | ||
| 61 | master_data -> data ref. for the master (e.g. the zr36055,57,67) | ||
| 62 | readreg -> ref. to read-fn from register (setup by master, used by slave) | ||
| 63 | writereg -> ref. to write-fn to register (setup by master, used by slave) | ||
| 64 | this two functions do the lowlevel I/O job | ||
| 65 | |||
| 66 | ==== slave functionality setup ==== | ||
| 67 | slave_data -> data ref. for the slave (e.g. the zr36050,60) | ||
| 68 | check -> fn-ref. checks availability of an device, returns -EIO on failure or | ||
| 69 | the type on success | ||
| 70 | this makes espcecially sense if a driver module supports more than | ||
| 71 | one codec which may be quite similar to access, nevertheless it | ||
| 72 | is good for a first functionality check | ||
| 73 | |||
| 74 | -- main functions you always need for compression/decompression -- | ||
| 75 | |||
| 76 | set_mode -> this fn-ref. resets the entire codec, and sets up the mode | ||
| 77 | with the last defined norm/size (or device default if not | ||
| 78 | available) - it returns 0 if the mode is possible | ||
| 79 | set_size -> this fn-ref. sets the norm and image size for | ||
| 80 | compression/decompression (returns 0 on success) | ||
| 81 | the norm param is defined in videodev2.h (V4L2_STD_*) | ||
| 82 | |||
| 83 | additional setup may be available, too - but the codec should work with | ||
| 84 | some default values even without this | ||
| 85 | |||
| 86 | set_data -> sets device-specific data (tables, quality etc.) | ||
| 87 | get_data -> query device-specific data (tables, quality etc.) | ||
| 88 | |||
| 89 | if the device delivers interrupts, they may be setup/handled here | ||
| 90 | setup_interrupt -> codec irq setup (not needed for 36050/60) | ||
| 91 | handle_interrupt -> codec irq handling (not needed for 36050/60) | ||
| 92 | |||
| 93 | if the device delivers pictures, they may be handled here | ||
| 94 | put_image -> puts image data to the codec (not needed for 36050/60) | ||
| 95 | get_image -> gets image data from the codec (not needed for 36050/60) | ||
| 96 | the calls include frame numbers and flags (even/odd/...) | ||
| 97 | if needed and a flag which allows blocking until its ready | ||
| 98 | */ | ||
| 99 | |||
| 100 | /* ============== */ | ||
| 101 | /* user interface */ | ||
| 102 | /* ============== */ | ||
| 103 | |||
| 104 | /* | ||
| 105 | Currently there is only a information display planned, as the layer | ||
| 106 | is not visible for the user space at all. | ||
| 107 | |||
| 108 | Information is available via procfs. The current entry is "/proc/videocodecs" | ||
| 109 | but it makes sense to "hide" it in the /proc/video tree of v4l(2) --TODO--. | ||
| 110 | |||
| 111 | A example for such an output is: | ||
| 112 | |||
| 113 | <S>lave or attached <M>aster name type flags magic (connected as) | ||
| 114 | S zr36050 0002 0000d001 00000000 (TEMPLATE) | ||
| 115 | M zr36055[0] 0001 0000c001 00000000 (zr36050[0]) | ||
| 116 | M zr36055[1] 0001 0000c001 00000000 (zr36050[1]) | ||
| 117 | |||
| 118 | */ | ||
| 119 | |||
| 120 | |||
| 121 | /* =============================================== */ | ||
| 122 | /* special defines for the videocodec_io structure */ | ||
| 123 | /* =============================================== */ | ||
| 124 | |||
| 125 | #ifndef __LINUX_VIDEOCODEC_H | ||
| 126 | #define __LINUX_VIDEOCODEC_H | ||
| 127 | |||
| 128 | #include <linux/videodev2.h> | ||
| 129 | |||
| 130 | #define CODEC_DO_COMPRESSION 0 | ||
| 131 | #define CODEC_DO_EXPANSION 1 | ||
| 132 | |||
| 133 | /* this are the current codec flags I think they are needed */ | ||
| 134 | /* -> type value in structure */ | ||
| 135 | #define CODEC_FLAG_JPEG 0x00000001L // JPEG codec | ||
| 136 | #define CODEC_FLAG_MPEG 0x00000002L // MPEG1/2/4 codec | ||
| 137 | #define CODEC_FLAG_DIVX 0x00000004L // DIVX codec | ||
| 138 | #define CODEC_FLAG_WAVELET 0x00000008L // WAVELET codec | ||
| 139 | // room for other types | ||
| 140 | |||
| 141 | #define CODEC_FLAG_MAGIC 0x00000800L // magic key must match | ||
| 142 | #define CODEC_FLAG_HARDWARE 0x00001000L // is a hardware codec | ||
| 143 | #define CODEC_FLAG_VFE 0x00002000L // has direct video frontend | ||
| 144 | #define CODEC_FLAG_ENCODER 0x00004000L // compression capability | ||
| 145 | #define CODEC_FLAG_DECODER 0x00008000L // decompression capability | ||
| 146 | #define CODEC_FLAG_NEEDIRQ 0x00010000L // needs irq handling | ||
| 147 | #define CODEC_FLAG_RDWRPIC 0x00020000L // handles picture I/O | ||
| 148 | |||
| 149 | /* a list of modes, some are just examples (is there any HW?) */ | ||
| 150 | #define CODEC_MODE_BJPG 0x0001 // Baseline JPEG | ||
| 151 | #define CODEC_MODE_LJPG 0x0002 // Lossless JPEG | ||
| 152 | #define CODEC_MODE_MPEG1 0x0003 // MPEG 1 | ||
| 153 | #define CODEC_MODE_MPEG2 0x0004 // MPEG 2 | ||
| 154 | #define CODEC_MODE_MPEG4 0x0005 // MPEG 4 | ||
| 155 | #define CODEC_MODE_MSDIVX 0x0006 // MS DivX | ||
| 156 | #define CODEC_MODE_ODIVX 0x0007 // Open DivX | ||
| 157 | #define CODEC_MODE_WAVELET 0x0008 // Wavelet | ||
| 158 | |||
| 159 | /* this are the current codec types I want to implement */ | ||
| 160 | /* -> type value in structure */ | ||
| 161 | #define CODEC_TYPE_NONE 0 | ||
| 162 | #define CODEC_TYPE_L64702 1 | ||
| 163 | #define CODEC_TYPE_ZR36050 2 | ||
| 164 | #define CODEC_TYPE_ZR36016 3 | ||
| 165 | #define CODEC_TYPE_ZR36060 4 | ||
| 166 | |||
| 167 | /* the type of data may be enhanced by future implementations (data-fn.'s) */ | ||
| 168 | /* -> used in command */ | ||
| 169 | #define CODEC_G_STATUS 0x0000 /* codec status (query only) */ | ||
| 170 | #define CODEC_S_CODEC_MODE 0x0001 /* codec mode (baseline JPEG, MPEG1,... */ | ||
| 171 | #define CODEC_G_CODEC_MODE 0x8001 | ||
| 172 | #define CODEC_S_VFE 0x0002 /* additional video frontend setup */ | ||
| 173 | #define CODEC_G_VFE 0x8002 | ||
| 174 | #define CODEC_S_MMAP 0x0003 /* MMAP setup (if available) */ | ||
| 175 | |||
| 176 | #define CODEC_S_JPEG_TDS_BYTE 0x0010 /* target data size in bytes */ | ||
| 177 | #define CODEC_G_JPEG_TDS_BYTE 0x8010 | ||
| 178 | #define CODEC_S_JPEG_SCALE 0x0011 /* scaling factor for quant. tables */ | ||
| 179 | #define CODEC_G_JPEG_SCALE 0x8011 | ||
| 180 | #define CODEC_S_JPEG_HDT_DATA 0x0018 /* huffman-tables */ | ||
| 181 | #define CODEC_G_JPEG_HDT_DATA 0x8018 | ||
| 182 | #define CODEC_S_JPEG_QDT_DATA 0x0019 /* quantizing-tables */ | ||
| 183 | #define CODEC_G_JPEG_QDT_DATA 0x8019 | ||
| 184 | #define CODEC_S_JPEG_APP_DATA 0x001A /* APP marker */ | ||
| 185 | #define CODEC_G_JPEG_APP_DATA 0x801A | ||
| 186 | #define CODEC_S_JPEG_COM_DATA 0x001B /* COM marker */ | ||
| 187 | #define CODEC_G_JPEG_COM_DATA 0x801B | ||
| 188 | |||
| 189 | #define CODEC_S_PRIVATE 0x1000 /* "private" commands start here */ | ||
| 190 | #define CODEC_G_PRIVATE 0x9000 | ||
| 191 | |||
| 192 | #define CODEC_G_FLAG 0x8000 /* this is how 'get' is detected */ | ||
| 193 | |||
| 194 | /* types of transfer, directly user space or a kernel buffer (image-fn.'s) */ | ||
| 195 | /* -> used in get_image, put_image */ | ||
| 196 | #define CODEC_TRANSFER_KERNEL 0 /* use "memcopy" */ | ||
| 197 | #define CODEC_TRANSFER_USER 1 /* use "to/from_user" */ | ||
| 198 | |||
| 199 | |||
| 200 | /* ========================= */ | ||
| 201 | /* the structures itself ... */ | ||
| 202 | /* ========================= */ | ||
| 203 | |||
| 204 | struct vfe_polarity { | ||
| 205 | unsigned int vsync_pol:1; | ||
| 206 | unsigned int hsync_pol:1; | ||
| 207 | unsigned int field_pol:1; | ||
| 208 | unsigned int blank_pol:1; | ||
| 209 | unsigned int subimg_pol:1; | ||
| 210 | unsigned int poe_pol:1; | ||
| 211 | unsigned int pvalid_pol:1; | ||
| 212 | unsigned int vclk_pol:1; | ||
| 213 | }; | ||
| 214 | |||
| 215 | struct vfe_settings { | ||
| 216 | __u32 x, y; /* Offsets into image */ | ||
| 217 | __u32 width, height; /* Area to capture */ | ||
| 218 | __u16 decimation; /* Decimation divider */ | ||
| 219 | __u16 flags; /* Flags for capture */ | ||
| 220 | __u16 quality; /* quality of the video */ | ||
| 221 | }; | ||
| 222 | |||
| 223 | struct tvnorm { | ||
| 224 | u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart; | ||
| 225 | }; | ||
| 226 | |||
| 227 | struct jpeg_com_marker { | ||
| 228 | int len; /* number of usable bytes in data */ | ||
| 229 | char data[60]; | ||
| 230 | }; | ||
| 231 | |||
| 232 | struct jpeg_app_marker { | ||
| 233 | int appn; /* number app segment */ | ||
| 234 | int len; /* number of usable bytes in data */ | ||
| 235 | char data[60]; | ||
| 236 | }; | ||
| 237 | |||
| 238 | struct videocodec { | ||
| 239 | struct module *owner; | ||
| 240 | /* -- filled in by slave device during register -- */ | ||
| 241 | char name[32]; | ||
| 242 | unsigned long magic; /* may be used for client<->master attaching */ | ||
| 243 | unsigned long flags; /* functionality flags */ | ||
| 244 | unsigned int type; /* codec type */ | ||
| 245 | |||
| 246 | /* -- these is filled in later during master device attach -- */ | ||
| 247 | |||
| 248 | struct videocodec_master *master_data; | ||
| 249 | |||
| 250 | /* -- these are filled in by the slave device during register -- */ | ||
| 251 | |||
| 252 | void *data; /* private slave data */ | ||
| 253 | |||
| 254 | /* attach/detach client functions (indirect call) */ | ||
| 255 | int (*setup) (struct videocodec * codec); | ||
| 256 | int (*unset) (struct videocodec * codec); | ||
| 257 | |||
| 258 | /* main functions, every client needs them for sure! */ | ||
| 259 | // set compression or decompression (or freeze, stop, standby, etc) | ||
| 260 | int (*set_mode) (struct videocodec * codec, | ||
| 261 | int mode); | ||
| 262 | // setup picture size and norm (for the codec's video frontend) | ||
| 263 | int (*set_video) (struct videocodec * codec, | ||
| 264 | struct tvnorm * norm, | ||
| 265 | struct vfe_settings * cap, | ||
| 266 | struct vfe_polarity * pol); | ||
| 267 | // other control commands, also mmap setup etc. | ||
| 268 | int (*control) (struct videocodec * codec, | ||
| 269 | int type, | ||
| 270 | int size, | ||
| 271 | void *data); | ||
| 272 | |||
| 273 | /* additional setup/query/processing (may be NULL pointer) */ | ||
| 274 | // interrupt setup / handling (for irq's delivered by master) | ||
| 275 | int (*setup_interrupt) (struct videocodec * codec, | ||
| 276 | long mode); | ||
| 277 | int (*handle_interrupt) (struct videocodec * codec, | ||
| 278 | int source, | ||
| 279 | long flag); | ||
| 280 | // picture interface (if any) | ||
| 281 | long (*put_image) (struct videocodec * codec, | ||
| 282 | int tr_type, | ||
| 283 | int block, | ||
| 284 | long *fr_num, | ||
| 285 | long *flag, | ||
| 286 | long size, | ||
| 287 | void *buf); | ||
| 288 | long (*get_image) (struct videocodec * codec, | ||
| 289 | int tr_type, | ||
| 290 | int block, | ||
| 291 | long *fr_num, | ||
| 292 | long *flag, | ||
| 293 | long size, | ||
| 294 | void *buf); | ||
| 295 | }; | ||
| 296 | |||
| 297 | struct videocodec_master { | ||
| 298 | /* -- filled in by master device for registration -- */ | ||
| 299 | char name[32]; | ||
| 300 | unsigned long magic; /* may be used for client<->master attaching */ | ||
| 301 | unsigned long flags; /* functionality flags */ | ||
| 302 | unsigned int type; /* master type */ | ||
| 303 | |||
| 304 | void *data; /* private master data */ | ||
| 305 | |||
| 306 | __u32(*readreg) (struct videocodec * codec, | ||
| 307 | __u16 reg); | ||
| 308 | void (*writereg) (struct videocodec * codec, | ||
| 309 | __u16 reg, | ||
| 310 | __u32 value); | ||
| 311 | }; | ||
| 312 | |||
| 313 | |||
| 314 | /* ================================================= */ | ||
| 315 | /* function prototypes of the master/slave interface */ | ||
| 316 | /* ================================================= */ | ||
| 317 | |||
| 318 | /* attach and detach commands for the master */ | ||
| 319 | // * master structure needs to be kmalloc'ed before calling attach | ||
| 320 | // and free'd after calling detach | ||
| 321 | // * returns pointer on success, NULL on failure | ||
| 322 | extern struct videocodec *videocodec_attach(struct videocodec_master *); | ||
| 323 | // * 0 on success, <0 (errno) on failure | ||
| 324 | extern int videocodec_detach(struct videocodec *); | ||
| 325 | |||
| 326 | /* register and unregister commands for the slaves */ | ||
| 327 | // * 0 on success, <0 (errno) on failure | ||
| 328 | extern int videocodec_register(const struct videocodec *); | ||
| 329 | // * 0 on success, <0 (errno) on failure | ||
| 330 | extern int videocodec_unregister(const struct videocodec *); | ||
| 331 | |||
| 332 | /* the other calls are directly done via the videocodec structure! */ | ||
| 333 | |||
| 334 | #endif /*ifndef __LINUX_VIDEOCODEC_H */ | ||
diff --git a/drivers/staging/media/zoran/zoran.h b/drivers/staging/media/zoran/zoran.h deleted file mode 100644 index 1b2e1fb3555f..000000000000 --- a/drivers/staging/media/zoran/zoran.h +++ /dev/null | |||
| @@ -1,392 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * zoran - Iomega Buz driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> | ||
| 6 | * | ||
| 7 | * based on | ||
| 8 | * | ||
| 9 | * zoran.0.0.3 Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
| 10 | * | ||
| 11 | * and | ||
| 12 | * | ||
| 13 | * bttv - Bt848 frame grabber driver | ||
| 14 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | ||
| 15 | * & Marcus Metzler (mocm@thp.uni-koeln.de) | ||
| 16 | */ | ||
| 17 | #ifndef _BUZ_H_ | ||
| 18 | #define _BUZ_H_ | ||
| 19 | |||
| 20 | #include <media/v4l2-device.h> | ||
| 21 | #include <media/v4l2-ctrls.h> | ||
| 22 | #include <media/v4l2-fh.h> | ||
| 23 | |||
| 24 | struct zoran_sync { | ||
| 25 | unsigned long frame; /* number of buffer that has been free'd */ | ||
| 26 | unsigned long length; /* number of code bytes in buffer (capture only) */ | ||
| 27 | unsigned long seq; /* frame sequence number */ | ||
| 28 | u64 ts; /* timestamp */ | ||
| 29 | }; | ||
| 30 | |||
| 31 | |||
| 32 | #define ZORAN_NAME "ZORAN" /* name of the device */ | ||
| 33 | |||
| 34 | #define ZR_DEVNAME(zr) ((zr)->name) | ||
| 35 | |||
| 36 | #define BUZ_MAX_WIDTH (zr->timing->Wa) | ||
| 37 | #define BUZ_MAX_HEIGHT (zr->timing->Ha) | ||
| 38 | #define BUZ_MIN_WIDTH 32 /* never display less than 32 pixels */ | ||
| 39 | #define BUZ_MIN_HEIGHT 24 /* never display less than 24 rows */ | ||
| 40 | |||
| 41 | #define BUZ_NUM_STAT_COM 4 | ||
| 42 | #define BUZ_MASK_STAT_COM 3 | ||
| 43 | |||
| 44 | #define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ | ||
| 45 | #define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ | ||
| 46 | |||
| 47 | #define BUZ_MAX_INPUT 16 | ||
| 48 | |||
| 49 | #if VIDEO_MAX_FRAME <= 32 | ||
| 50 | # define V4L_MAX_FRAME 32 | ||
| 51 | #elif VIDEO_MAX_FRAME <= 64 | ||
| 52 | # define V4L_MAX_FRAME 64 | ||
| 53 | #else | ||
| 54 | # error "Too many video frame buffers to handle" | ||
| 55 | #endif | ||
| 56 | #define V4L_MASK_FRAME (V4L_MAX_FRAME - 1) | ||
| 57 | |||
| 58 | #define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME) | ||
| 59 | |||
| 60 | #include "zr36057.h" | ||
| 61 | |||
| 62 | enum card_type { | ||
| 63 | UNKNOWN = -1, | ||
| 64 | |||
| 65 | /* Pinnacle/Miro */ | ||
| 66 | DC10_old, /* DC30 like */ | ||
| 67 | DC10_new, /* DC10plus like */ | ||
| 68 | DC10plus, | ||
| 69 | DC30, | ||
| 70 | DC30plus, | ||
| 71 | |||
| 72 | /* Linux Media Labs */ | ||
| 73 | LML33, | ||
| 74 | LML33R10, | ||
| 75 | |||
| 76 | /* Iomega */ | ||
| 77 | BUZ, | ||
| 78 | |||
| 79 | /* AverMedia */ | ||
| 80 | AVS6EYES, | ||
| 81 | |||
| 82 | /* total number of cards */ | ||
| 83 | NUM_CARDS | ||
| 84 | }; | ||
| 85 | |||
| 86 | enum zoran_codec_mode { | ||
| 87 | BUZ_MODE_IDLE, /* nothing going on */ | ||
| 88 | BUZ_MODE_MOTION_COMPRESS, /* grabbing frames */ | ||
| 89 | BUZ_MODE_MOTION_DECOMPRESS, /* playing frames */ | ||
| 90 | BUZ_MODE_STILL_COMPRESS, /* still frame conversion */ | ||
| 91 | BUZ_MODE_STILL_DECOMPRESS /* still frame conversion */ | ||
| 92 | }; | ||
| 93 | |||
| 94 | enum zoran_buffer_state { | ||
| 95 | BUZ_STATE_USER, /* buffer is owned by application */ | ||
| 96 | BUZ_STATE_PEND, /* buffer is queued in pend[] ready to feed to I/O */ | ||
| 97 | BUZ_STATE_DMA, /* buffer is queued in dma[] for I/O */ | ||
| 98 | BUZ_STATE_DONE /* buffer is ready to return to application */ | ||
| 99 | }; | ||
| 100 | |||
| 101 | enum zoran_map_mode { | ||
| 102 | ZORAN_MAP_MODE_RAW, | ||
| 103 | ZORAN_MAP_MODE_JPG_REC, | ||
| 104 | #define ZORAN_MAP_MODE_JPG ZORAN_MAP_MODE_JPG_REC | ||
| 105 | ZORAN_MAP_MODE_JPG_PLAY, | ||
| 106 | }; | ||
| 107 | |||
| 108 | enum gpio_type { | ||
| 109 | ZR_GPIO_JPEG_SLEEP = 0, | ||
| 110 | ZR_GPIO_JPEG_RESET, | ||
| 111 | ZR_GPIO_JPEG_FRAME, | ||
| 112 | ZR_GPIO_VID_DIR, | ||
| 113 | ZR_GPIO_VID_EN, | ||
| 114 | ZR_GPIO_VID_RESET, | ||
| 115 | ZR_GPIO_CLK_SEL1, | ||
| 116 | ZR_GPIO_CLK_SEL2, | ||
| 117 | ZR_GPIO_MAX, | ||
| 118 | }; | ||
| 119 | |||
| 120 | enum gpcs_type { | ||
| 121 | GPCS_JPEG_RESET = 0, | ||
| 122 | GPCS_JPEG_START, | ||
| 123 | GPCS_MAX, | ||
| 124 | }; | ||
| 125 | |||
| 126 | struct zoran_format { | ||
| 127 | char *name; | ||
| 128 | __u32 fourcc; | ||
| 129 | int colorspace; | ||
| 130 | int depth; | ||
| 131 | __u32 flags; | ||
| 132 | __u32 vfespfr; | ||
| 133 | }; | ||
| 134 | /* flags */ | ||
| 135 | #define ZORAN_FORMAT_COMPRESSED 1<<0 | ||
| 136 | #define ZORAN_FORMAT_OVERLAY 1<<1 | ||
| 137 | #define ZORAN_FORMAT_CAPTURE 1<<2 | ||
| 138 | #define ZORAN_FORMAT_PLAYBACK 1<<3 | ||
| 139 | |||
| 140 | /* overlay-settings */ | ||
| 141 | struct zoran_overlay_settings { | ||
| 142 | int is_set; | ||
| 143 | int x, y, width, height; /* position */ | ||
| 144 | int clipcount; /* position and number of clips */ | ||
| 145 | const struct zoran_format *format; /* overlay format */ | ||
| 146 | }; | ||
| 147 | |||
| 148 | /* v4l-capture settings */ | ||
| 149 | struct zoran_v4l_settings { | ||
| 150 | int width, height, bytesperline; /* capture size */ | ||
| 151 | const struct zoran_format *format; /* capture format */ | ||
| 152 | }; | ||
| 153 | |||
| 154 | /* jpg-capture/-playback settings */ | ||
| 155 | struct zoran_jpg_settings { | ||
| 156 | int decimation; /* this bit is used to set everything to default */ | ||
| 157 | int HorDcm, VerDcm, TmpDcm; /* capture decimation settings (TmpDcm=1 means both fields) */ | ||
| 158 | int field_per_buff, odd_even; /* field-settings (odd_even=1 (+TmpDcm=1) means top-field-first) */ | ||
| 159 | int img_x, img_y, img_width, img_height; /* crop settings (subframe capture) */ | ||
| 160 | struct v4l2_jpegcompression jpg_comp; /* JPEG-specific capture settings */ | ||
| 161 | }; | ||
| 162 | |||
| 163 | struct zoran_fh; | ||
| 164 | |||
| 165 | struct zoran_mapping { | ||
| 166 | struct zoran_fh *fh; | ||
| 167 | atomic_t count; | ||
| 168 | }; | ||
| 169 | |||
| 170 | struct zoran_buffer { | ||
| 171 | struct zoran_mapping *map; | ||
| 172 | enum zoran_buffer_state state; /* state: unused/pending/dma/done */ | ||
| 173 | struct zoran_sync bs; /* DONE: info to return to application */ | ||
| 174 | union { | ||
| 175 | struct { | ||
| 176 | __le32 *frag_tab; /* addresses of frag table */ | ||
| 177 | u32 frag_tab_bus; /* same value cached to save time in ISR */ | ||
| 178 | } jpg; | ||
| 179 | struct { | ||
| 180 | char *fbuffer; /* virtual address of frame buffer */ | ||
| 181 | unsigned long fbuffer_phys;/* physical address of frame buffer */ | ||
| 182 | unsigned long fbuffer_bus;/* bus address of frame buffer */ | ||
| 183 | } v4l; | ||
| 184 | }; | ||
| 185 | }; | ||
| 186 | |||
| 187 | enum zoran_lock_activity { | ||
| 188 | ZORAN_FREE, /* free for use */ | ||
| 189 | ZORAN_ACTIVE, /* active but unlocked */ | ||
| 190 | ZORAN_LOCKED, /* locked */ | ||
| 191 | }; | ||
| 192 | |||
| 193 | /* buffer collections */ | ||
| 194 | struct zoran_buffer_col { | ||
| 195 | enum zoran_lock_activity active; /* feature currently in use? */ | ||
| 196 | unsigned int num_buffers, buffer_size; | ||
| 197 | struct zoran_buffer buffer[MAX_FRAME]; /* buffers */ | ||
| 198 | u8 allocated; /* Flag if buffers are allocated */ | ||
| 199 | u8 need_contiguous; /* Flag if contiguous buffers are needed */ | ||
| 200 | /* only applies to jpg buffers, raw buffers are always contiguous */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | struct zoran; | ||
| 204 | |||
| 205 | /* zoran_fh contains per-open() settings */ | ||
| 206 | struct zoran_fh { | ||
| 207 | struct v4l2_fh fh; | ||
| 208 | struct zoran *zr; | ||
| 209 | |||
| 210 | enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */ | ||
| 211 | |||
| 212 | struct zoran_overlay_settings overlay_settings; | ||
| 213 | u32 *overlay_mask; /* overlay mask */ | ||
| 214 | enum zoran_lock_activity overlay_active;/* feature currently in use? */ | ||
| 215 | |||
| 216 | struct zoran_buffer_col buffers; /* buffers' info */ | ||
| 217 | |||
| 218 | struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ | ||
| 219 | struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ | ||
| 220 | }; | ||
| 221 | |||
| 222 | struct card_info { | ||
| 223 | enum card_type type; | ||
| 224 | char name[32]; | ||
| 225 | const char *i2c_decoder; /* i2c decoder device */ | ||
| 226 | const unsigned short *addrs_decoder; | ||
| 227 | const char *i2c_encoder; /* i2c encoder device */ | ||
| 228 | const unsigned short *addrs_encoder; | ||
| 229 | u16 video_vfe, video_codec; /* videocodec types */ | ||
| 230 | u16 audio_chip; /* audio type */ | ||
| 231 | |||
| 232 | int inputs; /* number of video inputs */ | ||
| 233 | struct input { | ||
| 234 | int muxsel; | ||
| 235 | char name[32]; | ||
| 236 | } input[BUZ_MAX_INPUT]; | ||
| 237 | |||
| 238 | v4l2_std_id norms; | ||
| 239 | struct tvnorm *tvn[3]; /* supported TV norms */ | ||
| 240 | |||
| 241 | u32 jpeg_int; /* JPEG interrupt */ | ||
| 242 | u32 vsync_int; /* VSYNC interrupt */ | ||
| 243 | s8 gpio[ZR_GPIO_MAX]; | ||
| 244 | u8 gpcs[GPCS_MAX]; | ||
| 245 | |||
| 246 | struct vfe_polarity vfe_pol; | ||
| 247 | u8 gpio_pol[ZR_GPIO_MAX]; | ||
| 248 | |||
| 249 | /* is the /GWS line connected? */ | ||
| 250 | u8 gws_not_connected; | ||
| 251 | |||
| 252 | /* avs6eyes mux setting */ | ||
| 253 | u8 input_mux; | ||
| 254 | |||
| 255 | void (*init) (struct zoran * zr); | ||
| 256 | }; | ||
| 257 | |||
| 258 | struct zoran { | ||
| 259 | struct v4l2_device v4l2_dev; | ||
| 260 | struct v4l2_ctrl_handler hdl; | ||
| 261 | struct video_device *video_dev; | ||
| 262 | |||
| 263 | struct i2c_adapter i2c_adapter; /* */ | ||
| 264 | struct i2c_algo_bit_data i2c_algo; /* */ | ||
| 265 | u32 i2cbr; | ||
| 266 | |||
| 267 | struct v4l2_subdev *decoder; /* video decoder sub-device */ | ||
| 268 | struct v4l2_subdev *encoder; /* video encoder sub-device */ | ||
| 269 | |||
| 270 | struct videocodec *codec; /* video codec */ | ||
| 271 | struct videocodec *vfe; /* video front end */ | ||
| 272 | |||
| 273 | struct mutex lock; /* file ops serialize lock */ | ||
| 274 | |||
| 275 | u8 initialized; /* flag if zoran has been correctly initialized */ | ||
| 276 | int user; /* number of current users */ | ||
| 277 | struct card_info card; | ||
| 278 | struct tvnorm *timing; | ||
| 279 | |||
| 280 | unsigned short id; /* number of this device */ | ||
| 281 | char name[32]; /* name of this device */ | ||
| 282 | struct pci_dev *pci_dev; /* PCI device */ | ||
| 283 | unsigned char revision; /* revision of zr36057 */ | ||
| 284 | unsigned char __iomem *zr36057_mem;/* pointer to mapped IO memory */ | ||
| 285 | |||
| 286 | spinlock_t spinlock; /* Spinlock */ | ||
| 287 | |||
| 288 | /* Video for Linux parameters */ | ||
| 289 | int input; /* card's norm and input */ | ||
| 290 | v4l2_std_id norm; | ||
| 291 | |||
| 292 | /* Current buffer params */ | ||
| 293 | void *vbuf_base; | ||
| 294 | int vbuf_height, vbuf_width; | ||
| 295 | int vbuf_depth; | ||
| 296 | int vbuf_bytesperline; | ||
| 297 | |||
| 298 | struct zoran_overlay_settings overlay_settings; | ||
| 299 | u32 *overlay_mask; /* overlay mask */ | ||
| 300 | enum zoran_lock_activity overlay_active; /* feature currently in use? */ | ||
| 301 | |||
| 302 | wait_queue_head_t v4l_capq; | ||
| 303 | |||
| 304 | int v4l_overlay_active; /* Overlay grab is activated */ | ||
| 305 | int v4l_memgrab_active; /* Memory grab is activated */ | ||
| 306 | |||
| 307 | int v4l_grab_frame; /* Frame number being currently grabbed */ | ||
| 308 | #define NO_GRAB_ACTIVE (-1) | ||
| 309 | unsigned long v4l_grab_seq; /* Number of frames grabbed */ | ||
| 310 | struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */ | ||
| 311 | |||
| 312 | /* V4L grab queue of frames pending */ | ||
| 313 | unsigned long v4l_pend_head; | ||
| 314 | unsigned long v4l_pend_tail; | ||
| 315 | unsigned long v4l_sync_tail; | ||
| 316 | int v4l_pend[V4L_MAX_FRAME]; | ||
| 317 | struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */ | ||
| 318 | |||
| 319 | /* Buz MJPEG parameters */ | ||
| 320 | enum zoran_codec_mode codec_mode; /* status of codec */ | ||
| 321 | struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */ | ||
| 322 | |||
| 323 | wait_queue_head_t jpg_capq; /* wait here for grab to finish */ | ||
| 324 | |||
| 325 | /* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */ | ||
| 326 | /* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */ | ||
| 327 | /* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */ | ||
| 328 | unsigned long jpg_que_head; /* Index where to put next buffer which is queued */ | ||
| 329 | unsigned long jpg_dma_head; /* Index of next buffer which goes into stat_com */ | ||
| 330 | unsigned long jpg_dma_tail; /* Index of last buffer in stat_com */ | ||
| 331 | unsigned long jpg_que_tail; /* Index of last buffer in queue */ | ||
| 332 | unsigned long jpg_seq_num; /* count of frames since grab/play started */ | ||
| 333 | unsigned long jpg_err_seq; /* last seq_num before error */ | ||
| 334 | unsigned long jpg_err_shift; | ||
| 335 | unsigned long jpg_queued_num; /* count of frames queued since grab/play started */ | ||
| 336 | |||
| 337 | /* zr36057's code buffer table */ | ||
| 338 | __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ | ||
| 339 | |||
| 340 | /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */ | ||
| 341 | int jpg_pend[BUZ_MAX_FRAME]; | ||
| 342 | |||
| 343 | /* array indexed by frame number */ | ||
| 344 | struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */ | ||
| 345 | |||
| 346 | /* Additional stuff for testing */ | ||
| 347 | #ifdef CONFIG_PROC_FS | ||
| 348 | struct proc_dir_entry *zoran_proc; | ||
| 349 | #else | ||
| 350 | void *zoran_proc; | ||
| 351 | #endif | ||
| 352 | int testing; | ||
| 353 | int jpeg_error; | ||
| 354 | int intr_counter_GIRQ1; | ||
| 355 | int intr_counter_GIRQ0; | ||
| 356 | int intr_counter_CodRepIRQ; | ||
| 357 | int intr_counter_JPEGRepIRQ; | ||
| 358 | int field_counter; | ||
| 359 | int IRQ1_in; | ||
| 360 | int IRQ1_out; | ||
| 361 | int JPEG_in; | ||
| 362 | int JPEG_out; | ||
| 363 | int JPEG_0; | ||
| 364 | int JPEG_1; | ||
| 365 | int END_event_missed; | ||
| 366 | int JPEG_missed; | ||
| 367 | int JPEG_error; | ||
| 368 | int num_errors; | ||
| 369 | int JPEG_max_missed; | ||
| 370 | int JPEG_min_missed; | ||
| 371 | |||
| 372 | u32 last_isr; | ||
| 373 | unsigned long frame_num; | ||
| 374 | |||
| 375 | wait_queue_head_t test_q; | ||
| 376 | }; | ||
| 377 | |||
| 378 | static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) | ||
| 379 | { | ||
| 380 | return container_of(v4l2_dev, struct zoran, v4l2_dev); | ||
| 381 | } | ||
| 382 | |||
| 383 | /* There was something called _ALPHA_BUZ that used the PCI address instead of | ||
| 384 | * the kernel iomapped address for btread/btwrite. */ | ||
| 385 | #define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr)) | ||
| 386 | #define btread(adr) readl(zr->zr36057_mem+(adr)) | ||
| 387 | |||
| 388 | #define btand(dat,adr) btwrite((dat) & btread(adr), adr) | ||
| 389 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) | ||
| 390 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) | ||
| 391 | |||
| 392 | #endif | ||
diff --git a/drivers/staging/media/zoran/zoran_card.c b/drivers/staging/media/zoran/zoran_card.c deleted file mode 100644 index 1d8cd7946bd8..000000000000 --- a/drivers/staging/media/zoran/zoran_card.c +++ /dev/null | |||
| @@ -1,1511 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles card-specific data and detection | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #include <linux/delay.h> | ||
| 17 | |||
| 18 | #include <linux/types.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/vmalloc.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | |||
| 25 | #include <linux/proc_fs.h> | ||
| 26 | #include <linux/i2c.h> | ||
| 27 | #include <linux/i2c-algo-bit.h> | ||
| 28 | #include <linux/videodev2.h> | ||
| 29 | #include <linux/spinlock.h> | ||
| 30 | #include <linux/sem.h> | ||
| 31 | #include <linux/kmod.h> | ||
| 32 | #include <linux/wait.h> | ||
| 33 | |||
| 34 | #include <linux/pci.h> | ||
| 35 | #include <linux/interrupt.h> | ||
| 36 | #include <linux/mutex.h> | ||
| 37 | #include <linux/io.h> | ||
| 38 | #include <media/v4l2-common.h> | ||
| 39 | #include <media/i2c/bt819.h> | ||
| 40 | |||
| 41 | #include "videocodec.h" | ||
| 42 | #include "zoran.h" | ||
| 43 | #include "zoran_card.h" | ||
| 44 | #include "zoran_device.h" | ||
| 45 | #include "zoran_procfs.h" | ||
| 46 | |||
| 47 | extern const struct zoran_format zoran_formats[]; | ||
| 48 | |||
| 49 | static int card[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; | ||
| 50 | module_param_array(card, int, NULL, 0444); | ||
| 51 | MODULE_PARM_DESC(card, "Card type"); | ||
| 52 | |||
| 53 | /* | ||
| 54 | The video mem address of the video card. | ||
| 55 | The driver has a little database for some videocards | ||
| 56 | to determine it from there. If your video card is not in there | ||
| 57 | you have either to give it to the driver as a parameter | ||
| 58 | or set in in a VIDIOCSFBUF ioctl | ||
| 59 | */ | ||
| 60 | |||
| 61 | static unsigned long vidmem; /* default = 0 - Video memory base address */ | ||
| 62 | module_param_hw(vidmem, ulong, iomem, 0444); | ||
| 63 | MODULE_PARM_DESC(vidmem, "Default video memory base address"); | ||
| 64 | |||
| 65 | /* | ||
| 66 | Default input and video norm at startup of the driver. | ||
| 67 | */ | ||
| 68 | |||
| 69 | static unsigned int default_input; /* default 0 = Composite, 1 = S-Video */ | ||
| 70 | module_param(default_input, uint, 0444); | ||
| 71 | MODULE_PARM_DESC(default_input, | ||
| 72 | "Default input (0=Composite, 1=S-Video, 2=Internal)"); | ||
| 73 | |||
| 74 | static int default_mux = 1; /* 6 Eyes input selection */ | ||
| 75 | module_param(default_mux, int, 0644); | ||
| 76 | MODULE_PARM_DESC(default_mux, | ||
| 77 | "Default 6 Eyes mux setting (Input selection)"); | ||
| 78 | |||
| 79 | static int default_norm; /* default 0 = PAL, 1 = NTSC 2 = SECAM */ | ||
| 80 | module_param(default_norm, int, 0444); | ||
| 81 | MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); | ||
| 82 | |||
| 83 | /* /dev/videoN, -1 for autodetect */ | ||
| 84 | static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 }; | ||
| 85 | module_param_array(video_nr, int, NULL, 0444); | ||
| 86 | MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)"); | ||
| 87 | |||
| 88 | int v4l_nbufs = 4; | ||
| 89 | int v4l_bufsize = 864; /* Everybody should be able to work with this setting */ | ||
| 90 | module_param(v4l_nbufs, int, 0644); | ||
| 91 | MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use"); | ||
| 92 | module_param(v4l_bufsize, int, 0644); | ||
| 93 | MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)"); | ||
| 94 | |||
| 95 | int jpg_nbufs = 32; | ||
| 96 | int jpg_bufsize = 512; /* max size for 100% quality full-PAL frame */ | ||
| 97 | module_param(jpg_nbufs, int, 0644); | ||
| 98 | MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use"); | ||
| 99 | module_param(jpg_bufsize, int, 0644); | ||
| 100 | MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)"); | ||
| 101 | |||
| 102 | int pass_through = 0; /* 1=Pass through TV signal when device is not used */ | ||
| 103 | /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */ | ||
| 104 | module_param(pass_through, int, 0644); | ||
| 105 | MODULE_PARM_DESC(pass_through, | ||
| 106 | "Pass TV signal through to TV-out when idling"); | ||
| 107 | |||
| 108 | int zr36067_debug = 1; | ||
| 109 | module_param_named(debug, zr36067_debug, int, 0644); | ||
| 110 | MODULE_PARM_DESC(debug, "Debug level (0-5)"); | ||
| 111 | |||
| 112 | #define ZORAN_VERSION "0.10.1" | ||
| 113 | |||
| 114 | MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); | ||
| 115 | MODULE_AUTHOR("Serguei Miridonov"); | ||
| 116 | MODULE_LICENSE("GPL"); | ||
| 117 | MODULE_VERSION(ZORAN_VERSION); | ||
| 118 | |||
| 119 | #define ZR_DEVICE(subven, subdev, data) { \ | ||
| 120 | .vendor = PCI_VENDOR_ID_ZORAN, .device = PCI_DEVICE_ID_ZORAN_36057, \ | ||
| 121 | .subvendor = (subven), .subdevice = (subdev), .driver_data = (data) } | ||
| 122 | |||
| 123 | static const struct pci_device_id zr36067_pci_tbl[] = { | ||
| 124 | ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC10PLUS, DC10plus), | ||
| 125 | ZR_DEVICE(PCI_VENDOR_ID_MIRO, PCI_DEVICE_ID_MIRO_DC30PLUS, DC30plus), | ||
| 126 | ZR_DEVICE(PCI_VENDOR_ID_ELECTRONICDESIGNGMBH, PCI_DEVICE_ID_LML_33R10, LML33R10), | ||
| 127 | ZR_DEVICE(PCI_VENDOR_ID_IOMEGA, PCI_DEVICE_ID_IOMEGA_BUZ, BUZ), | ||
| 128 | ZR_DEVICE(PCI_ANY_ID, PCI_ANY_ID, NUM_CARDS), | ||
| 129 | {0} | ||
| 130 | }; | ||
| 131 | MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); | ||
| 132 | |||
| 133 | static unsigned int zoran_num; /* number of cards found */ | ||
| 134 | |||
| 135 | /* videocodec bus functions ZR36060 */ | ||
| 136 | static u32 | ||
| 137 | zr36060_read (struct videocodec *codec, | ||
| 138 | u16 reg) | ||
| 139 | { | ||
| 140 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 141 | __u32 data; | ||
| 142 | |||
| 143 | if (post_office_wait(zr) | ||
| 144 | || post_office_write(zr, 0, 1, reg >> 8) | ||
| 145 | || post_office_write(zr, 0, 2, reg & 0xff)) { | ||
| 146 | return -1; | ||
| 147 | } | ||
| 148 | |||
| 149 | data = post_office_read(zr, 0, 3) & 0xff; | ||
| 150 | return data; | ||
| 151 | } | ||
| 152 | |||
| 153 | static void | ||
| 154 | zr36060_write (struct videocodec *codec, | ||
| 155 | u16 reg, | ||
| 156 | u32 val) | ||
| 157 | { | ||
| 158 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 159 | |||
| 160 | if (post_office_wait(zr) | ||
| 161 | || post_office_write(zr, 0, 1, reg >> 8) | ||
| 162 | || post_office_write(zr, 0, 2, reg & 0xff)) { | ||
| 163 | return; | ||
| 164 | } | ||
| 165 | |||
| 166 | post_office_write(zr, 0, 3, val & 0xff); | ||
| 167 | } | ||
| 168 | |||
| 169 | /* videocodec bus functions ZR36050 */ | ||
| 170 | static u32 | ||
| 171 | zr36050_read (struct videocodec *codec, | ||
| 172 | u16 reg) | ||
| 173 | { | ||
| 174 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 175 | __u32 data; | ||
| 176 | |||
| 177 | if (post_office_wait(zr) | ||
| 178 | || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES | ||
| 179 | return -1; | ||
| 180 | } | ||
| 181 | |||
| 182 | data = post_office_read(zr, 0, reg & 0x03) & 0xff; // reg. LOWBYTES + read | ||
| 183 | return data; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void | ||
| 187 | zr36050_write (struct videocodec *codec, | ||
| 188 | u16 reg, | ||
| 189 | u32 val) | ||
| 190 | { | ||
| 191 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 192 | |||
| 193 | if (post_office_wait(zr) | ||
| 194 | || post_office_write(zr, 1, 0, reg >> 2)) { // reg. HIGHBYTES | ||
| 195 | return; | ||
| 196 | } | ||
| 197 | |||
| 198 | post_office_write(zr, 0, reg & 0x03, val & 0xff); // reg. LOWBYTES + wr. data | ||
| 199 | } | ||
| 200 | |||
| 201 | /* videocodec bus functions ZR36016 */ | ||
| 202 | static u32 | ||
| 203 | zr36016_read (struct videocodec *codec, | ||
| 204 | u16 reg) | ||
| 205 | { | ||
| 206 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 207 | __u32 data; | ||
| 208 | |||
| 209 | if (post_office_wait(zr)) { | ||
| 210 | return -1; | ||
| 211 | } | ||
| 212 | |||
| 213 | data = post_office_read(zr, 2, reg & 0x03) & 0xff; // read | ||
| 214 | return data; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* hack for in zoran_device.c */ | ||
| 218 | void | ||
| 219 | zr36016_write (struct videocodec *codec, | ||
| 220 | u16 reg, | ||
| 221 | u32 val) | ||
| 222 | { | ||
| 223 | struct zoran *zr = (struct zoran *) codec->master_data->data; | ||
| 224 | |||
| 225 | if (post_office_wait(zr)) { | ||
| 226 | return; | ||
| 227 | } | ||
| 228 | |||
| 229 | post_office_write(zr, 2, reg & 0x03, val & 0x0ff); // wr. data | ||
| 230 | } | ||
| 231 | |||
| 232 | /* | ||
| 233 | * Board specific information | ||
| 234 | */ | ||
| 235 | |||
| 236 | static void | ||
| 237 | dc10_init (struct zoran *zr) | ||
| 238 | { | ||
| 239 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 240 | |||
| 241 | /* Pixel clock selection */ | ||
| 242 | GPIO(zr, 4, 0); | ||
| 243 | GPIO(zr, 5, 1); | ||
| 244 | /* Enable the video bus sync signals */ | ||
| 245 | GPIO(zr, 7, 0); | ||
| 246 | } | ||
| 247 | |||
| 248 | static void | ||
| 249 | dc10plus_init (struct zoran *zr) | ||
| 250 | { | ||
| 251 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 252 | } | ||
| 253 | |||
| 254 | static void | ||
| 255 | buz_init (struct zoran *zr) | ||
| 256 | { | ||
| 257 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 258 | |||
| 259 | /* some stuff from Iomega */ | ||
| 260 | pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15); | ||
| 261 | pci_write_config_dword(zr->pci_dev, 0x0c, 0x00012020); | ||
| 262 | pci_write_config_dword(zr->pci_dev, 0xe8, 0xc0200000); | ||
| 263 | } | ||
| 264 | |||
| 265 | static void | ||
| 266 | lml33_init (struct zoran *zr) | ||
| 267 | { | ||
| 268 | dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 269 | |||
| 270 | GPIO(zr, 2, 1); // Set Composite input/output | ||
| 271 | } | ||
| 272 | |||
| 273 | static void | ||
| 274 | avs6eyes_init (struct zoran *zr) | ||
| 275 | { | ||
| 276 | // AverMedia 6-Eyes original driver by Christer Weinigel | ||
| 277 | |||
| 278 | // Lifted straight from Christer's old driver and | ||
| 279 | // modified slightly by Martin Samuelsson. | ||
| 280 | |||
| 281 | int mux = default_mux; /* 1 = BT866, 7 = VID1 */ | ||
| 282 | |||
| 283 | GPIO(zr, 4, 1); /* Bt866 SLEEP on */ | ||
| 284 | udelay(2); | ||
| 285 | |||
| 286 | GPIO(zr, 0, 1); /* ZR36060 /RESET on */ | ||
| 287 | GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */ | ||
| 288 | GPIO(zr, 2, mux & 1); /* MUX S0 */ | ||
| 289 | GPIO(zr, 3, 0); /* /FRAME on */ | ||
| 290 | GPIO(zr, 4, 0); /* Bt866 SLEEP off */ | ||
| 291 | GPIO(zr, 5, mux & 2); /* MUX S1 */ | ||
| 292 | GPIO(zr, 6, 0); /* ? */ | ||
| 293 | GPIO(zr, 7, mux & 4); /* MUX S2 */ | ||
| 294 | |||
| 295 | } | ||
| 296 | |||
| 297 | static char * | ||
| 298 | codecid_to_modulename (u16 codecid) | ||
| 299 | { | ||
| 300 | char *name = NULL; | ||
| 301 | |||
| 302 | switch (codecid) { | ||
| 303 | case CODEC_TYPE_ZR36060: | ||
| 304 | name = "zr36060"; | ||
| 305 | break; | ||
| 306 | case CODEC_TYPE_ZR36050: | ||
| 307 | name = "zr36050"; | ||
| 308 | break; | ||
| 309 | case CODEC_TYPE_ZR36016: | ||
| 310 | name = "zr36016"; | ||
| 311 | break; | ||
| 312 | } | ||
| 313 | |||
| 314 | return name; | ||
| 315 | } | ||
| 316 | |||
| 317 | // struct tvnorm { | ||
| 318 | // u16 Wt, Wa, HStart, HSyncStart, Ht, Ha, VStart; | ||
| 319 | // }; | ||
| 320 | |||
| 321 | static struct tvnorm f50sqpixel = { 944, 768, 83, 880, 625, 576, 16 }; | ||
| 322 | static struct tvnorm f60sqpixel = { 780, 640, 51, 716, 525, 480, 12 }; | ||
| 323 | static struct tvnorm f50ccir601 = { 864, 720, 75, 804, 625, 576, 18 }; | ||
| 324 | static struct tvnorm f60ccir601 = { 858, 720, 57, 788, 525, 480, 16 }; | ||
| 325 | |||
| 326 | static struct tvnorm f50ccir601_lml33 = { 864, 720, 75+34, 804, 625, 576, 18 }; | ||
| 327 | static struct tvnorm f60ccir601_lml33 = { 858, 720, 57+34, 788, 525, 480, 16 }; | ||
| 328 | |||
| 329 | /* The DC10 (57/16/50) uses VActive as HSync, so HStart must be 0 */ | ||
| 330 | static struct tvnorm f50sqpixel_dc10 = { 944, 768, 0, 880, 625, 576, 0 }; | ||
| 331 | static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 }; | ||
| 332 | |||
| 333 | /* FIXME: I cannot swap U and V in saa7114, so i do one | ||
| 334 | * pixel left shift in zoran (75 -> 74) | ||
| 335 | * (Maxim Yevtyushkin <max@linuxmedialabs.com>) */ | ||
| 336 | static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; | ||
| 337 | static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; | ||
| 338 | |||
| 339 | /* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I | ||
| 340 | * copy Maxim's left shift hack for the 6 Eyes. | ||
| 341 | * | ||
| 342 | * Christer's driver used the unshifted norms, though... | ||
| 343 | * /Sam */ | ||
| 344 | static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 }; | ||
| 345 | static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 }; | ||
| 346 | |||
| 347 | static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END }; | ||
| 348 | static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END }; | ||
| 349 | static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END }; | ||
| 350 | static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END }; | ||
| 351 | static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END }; | ||
| 352 | static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END }; | ||
| 353 | static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
| 354 | static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END }; | ||
| 355 | static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
| 356 | static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END }; | ||
| 357 | |||
| 358 | static struct card_info zoran_cards[NUM_CARDS] = { | ||
| 359 | { | ||
| 360 | .type = DC10_old, | ||
| 361 | .name = "DC10(old)", | ||
| 362 | .i2c_decoder = "vpx3220a", | ||
| 363 | .addrs_decoder = vpx3220_addrs, | ||
| 364 | .video_codec = CODEC_TYPE_ZR36050, | ||
| 365 | .video_vfe = CODEC_TYPE_ZR36016, | ||
| 366 | |||
| 367 | .inputs = 3, | ||
| 368 | .input = { | ||
| 369 | { 1, "Composite" }, | ||
| 370 | { 2, "S-Video" }, | ||
| 371 | { 0, "Internal/comp" } | ||
| 372 | }, | ||
| 373 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 374 | .tvn = { | ||
| 375 | &f50sqpixel_dc10, | ||
| 376 | &f60sqpixel_dc10, | ||
| 377 | &f50sqpixel_dc10 | ||
| 378 | }, | ||
| 379 | .jpeg_int = 0, | ||
| 380 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
| 381 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
| 382 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
| 383 | .gpcs = { -1, 0 }, | ||
| 384 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 385 | .gws_not_connected = 0, | ||
| 386 | .input_mux = 0, | ||
| 387 | .init = &dc10_init, | ||
| 388 | }, { | ||
| 389 | .type = DC10_new, | ||
| 390 | .name = "DC10(new)", | ||
| 391 | .i2c_decoder = "saa7110", | ||
| 392 | .addrs_decoder = saa7110_addrs, | ||
| 393 | .i2c_encoder = "adv7175", | ||
| 394 | .addrs_encoder = adv717x_addrs, | ||
| 395 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 396 | |||
| 397 | .inputs = 3, | ||
| 398 | .input = { | ||
| 399 | { 0, "Composite" }, | ||
| 400 | { 7, "S-Video" }, | ||
| 401 | { 5, "Internal/comp" } | ||
| 402 | }, | ||
| 403 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 404 | .tvn = { | ||
| 405 | &f50sqpixel, | ||
| 406 | &f60sqpixel, | ||
| 407 | &f50sqpixel}, | ||
| 408 | .jpeg_int = ZR36057_ISR_GIRQ0, | ||
| 409 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
| 410 | .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 }, | ||
| 411 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 412 | .gpcs = { -1, 1}, | ||
| 413 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | ||
| 414 | .gws_not_connected = 0, | ||
| 415 | .input_mux = 0, | ||
| 416 | .init = &dc10plus_init, | ||
| 417 | }, { | ||
| 418 | .type = DC10plus, | ||
| 419 | .name = "DC10plus", | ||
| 420 | .i2c_decoder = "saa7110", | ||
| 421 | .addrs_decoder = saa7110_addrs, | ||
| 422 | .i2c_encoder = "adv7175", | ||
| 423 | .addrs_encoder = adv717x_addrs, | ||
| 424 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 425 | |||
| 426 | .inputs = 3, | ||
| 427 | .input = { | ||
| 428 | { 0, "Composite" }, | ||
| 429 | { 7, "S-Video" }, | ||
| 430 | { 5, "Internal/comp" } | ||
| 431 | }, | ||
| 432 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 433 | .tvn = { | ||
| 434 | &f50sqpixel, | ||
| 435 | &f60sqpixel, | ||
| 436 | &f50sqpixel | ||
| 437 | }, | ||
| 438 | .jpeg_int = ZR36057_ISR_GIRQ0, | ||
| 439 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
| 440 | .gpio = { 3, 0, 6, 1, 2, -1, 4, 5 }, | ||
| 441 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 442 | .gpcs = { -1, 1 }, | ||
| 443 | .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, | ||
| 444 | .gws_not_connected = 0, | ||
| 445 | .input_mux = 0, | ||
| 446 | .init = &dc10plus_init, | ||
| 447 | }, { | ||
| 448 | .type = DC30, | ||
| 449 | .name = "DC30", | ||
| 450 | .i2c_decoder = "vpx3220a", | ||
| 451 | .addrs_decoder = vpx3220_addrs, | ||
| 452 | .i2c_encoder = "adv7175", | ||
| 453 | .addrs_encoder = adv717x_addrs, | ||
| 454 | .video_codec = CODEC_TYPE_ZR36050, | ||
| 455 | .video_vfe = CODEC_TYPE_ZR36016, | ||
| 456 | |||
| 457 | .inputs = 3, | ||
| 458 | .input = { | ||
| 459 | { 1, "Composite" }, | ||
| 460 | { 2, "S-Video" }, | ||
| 461 | { 0, "Internal/comp" } | ||
| 462 | }, | ||
| 463 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 464 | .tvn = { | ||
| 465 | &f50sqpixel_dc10, | ||
| 466 | &f60sqpixel_dc10, | ||
| 467 | &f50sqpixel_dc10 | ||
| 468 | }, | ||
| 469 | .jpeg_int = 0, | ||
| 470 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
| 471 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
| 472 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
| 473 | .gpcs = { -1, 0 }, | ||
| 474 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 475 | .gws_not_connected = 0, | ||
| 476 | .input_mux = 0, | ||
| 477 | .init = &dc10_init, | ||
| 478 | }, { | ||
| 479 | .type = DC30plus, | ||
| 480 | .name = "DC30plus", | ||
| 481 | .i2c_decoder = "vpx3220a", | ||
| 482 | .addrs_decoder = vpx3220_addrs, | ||
| 483 | .i2c_encoder = "adv7175", | ||
| 484 | .addrs_encoder = adv717x_addrs, | ||
| 485 | .video_codec = CODEC_TYPE_ZR36050, | ||
| 486 | .video_vfe = CODEC_TYPE_ZR36016, | ||
| 487 | |||
| 488 | .inputs = 3, | ||
| 489 | .input = { | ||
| 490 | { 1, "Composite" }, | ||
| 491 | { 2, "S-Video" }, | ||
| 492 | { 0, "Internal/comp" } | ||
| 493 | }, | ||
| 494 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 495 | .tvn = { | ||
| 496 | &f50sqpixel_dc10, | ||
| 497 | &f60sqpixel_dc10, | ||
| 498 | &f50sqpixel_dc10 | ||
| 499 | }, | ||
| 500 | .jpeg_int = 0, | ||
| 501 | .vsync_int = ZR36057_ISR_GIRQ1, | ||
| 502 | .gpio = { 2, 1, -1, 3, 7, 0, 4, 5 }, | ||
| 503 | .gpio_pol = { 0, 0, 0, 1, 0, 0, 0, 0 }, | ||
| 504 | .gpcs = { -1, 0 }, | ||
| 505 | .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 506 | .gws_not_connected = 0, | ||
| 507 | .input_mux = 0, | ||
| 508 | .init = &dc10_init, | ||
| 509 | }, { | ||
| 510 | .type = LML33, | ||
| 511 | .name = "LML33", | ||
| 512 | .i2c_decoder = "bt819a", | ||
| 513 | .addrs_decoder = bt819_addrs, | ||
| 514 | .i2c_encoder = "bt856", | ||
| 515 | .addrs_encoder = bt856_addrs, | ||
| 516 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 517 | |||
| 518 | .inputs = 2, | ||
| 519 | .input = { | ||
| 520 | { 0, "Composite" }, | ||
| 521 | { 7, "S-Video" } | ||
| 522 | }, | ||
| 523 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
| 524 | .tvn = { | ||
| 525 | &f50ccir601_lml33, | ||
| 526 | &f60ccir601_lml33, | ||
| 527 | NULL | ||
| 528 | }, | ||
| 529 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
| 530 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
| 531 | .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 }, | ||
| 532 | .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 533 | .gpcs = { 3, 1 }, | ||
| 534 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
| 535 | .gws_not_connected = 1, | ||
| 536 | .input_mux = 0, | ||
| 537 | .init = &lml33_init, | ||
| 538 | }, { | ||
| 539 | .type = LML33R10, | ||
| 540 | .name = "LML33R10", | ||
| 541 | .i2c_decoder = "saa7114", | ||
| 542 | .addrs_decoder = saa7114_addrs, | ||
| 543 | .i2c_encoder = "adv7170", | ||
| 544 | .addrs_encoder = adv717x_addrs, | ||
| 545 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 546 | |||
| 547 | .inputs = 2, | ||
| 548 | .input = { | ||
| 549 | { 0, "Composite" }, | ||
| 550 | { 7, "S-Video" } | ||
| 551 | }, | ||
| 552 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
| 553 | .tvn = { | ||
| 554 | &f50ccir601_lm33r10, | ||
| 555 | &f60ccir601_lm33r10, | ||
| 556 | NULL | ||
| 557 | }, | ||
| 558 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
| 559 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
| 560 | .gpio = { 1, -1, 3, 5, 7, -1, -1, -1 }, | ||
| 561 | .gpio_pol = { 0, 0, 0, 0, 1, 0, 0, 0 }, | ||
| 562 | .gpcs = { 3, 1 }, | ||
| 563 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
| 564 | .gws_not_connected = 1, | ||
| 565 | .input_mux = 0, | ||
| 566 | .init = &lml33_init, | ||
| 567 | }, { | ||
| 568 | .type = BUZ, | ||
| 569 | .name = "Buz", | ||
| 570 | .i2c_decoder = "saa7111", | ||
| 571 | .addrs_decoder = saa7111_addrs, | ||
| 572 | .i2c_encoder = "saa7185", | ||
| 573 | .addrs_encoder = saa7185_addrs, | ||
| 574 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 575 | |||
| 576 | .inputs = 2, | ||
| 577 | .input = { | ||
| 578 | { 3, "Composite" }, | ||
| 579 | { 7, "S-Video" } | ||
| 580 | }, | ||
| 581 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM, | ||
| 582 | .tvn = { | ||
| 583 | &f50ccir601, | ||
| 584 | &f60ccir601, | ||
| 585 | &f50ccir601 | ||
| 586 | }, | ||
| 587 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
| 588 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
| 589 | .gpio = { 1, -1, 3, -1, -1, -1, -1, -1 }, | ||
| 590 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 591 | .gpcs = { 3, 1 }, | ||
| 592 | .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, | ||
| 593 | .gws_not_connected = 1, | ||
| 594 | .input_mux = 0, | ||
| 595 | .init = &buz_init, | ||
| 596 | }, { | ||
| 597 | .type = AVS6EYES, | ||
| 598 | .name = "6-Eyes", | ||
| 599 | /* AverMedia chose not to brand the 6-Eyes. Thus it | ||
| 600 | can't be autodetected, and requires card=x. */ | ||
| 601 | .i2c_decoder = "ks0127", | ||
| 602 | .addrs_decoder = ks0127_addrs, | ||
| 603 | .i2c_encoder = "bt866", | ||
| 604 | .addrs_encoder = bt866_addrs, | ||
| 605 | .video_codec = CODEC_TYPE_ZR36060, | ||
| 606 | |||
| 607 | .inputs = 10, | ||
| 608 | .input = { | ||
| 609 | { 0, "Composite 1" }, | ||
| 610 | { 1, "Composite 2" }, | ||
| 611 | { 2, "Composite 3" }, | ||
| 612 | { 4, "Composite 4" }, | ||
| 613 | { 5, "Composite 5" }, | ||
| 614 | { 6, "Composite 6" }, | ||
| 615 | { 8, "S-Video 1" }, | ||
| 616 | { 9, "S-Video 2" }, | ||
| 617 | {10, "S-Video 3" }, | ||
| 618 | {15, "YCbCr" } | ||
| 619 | }, | ||
| 620 | .norms = V4L2_STD_NTSC|V4L2_STD_PAL, | ||
| 621 | .tvn = { | ||
| 622 | &f50ccir601_avs6eyes, | ||
| 623 | &f60ccir601_avs6eyes, | ||
| 624 | NULL | ||
| 625 | }, | ||
| 626 | .jpeg_int = ZR36057_ISR_GIRQ1, | ||
| 627 | .vsync_int = ZR36057_ISR_GIRQ0, | ||
| 628 | .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam | ||
| 629 | .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam | ||
| 630 | .gpcs = { 3, 1 }, // Validity unknown /Sam | ||
| 631 | .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam | ||
| 632 | .gws_not_connected = 1, | ||
| 633 | .input_mux = 1, | ||
| 634 | .init = &avs6eyes_init, | ||
| 635 | } | ||
| 636 | |||
| 637 | }; | ||
| 638 | |||
| 639 | /* | ||
| 640 | * I2C functions | ||
| 641 | */ | ||
| 642 | /* software I2C functions */ | ||
| 643 | static int | ||
| 644 | zoran_i2c_getsda (void *data) | ||
| 645 | { | ||
| 646 | struct zoran *zr = (struct zoran *) data; | ||
| 647 | |||
| 648 | return (btread(ZR36057_I2CBR) >> 1) & 1; | ||
| 649 | } | ||
| 650 | |||
| 651 | static int | ||
| 652 | zoran_i2c_getscl (void *data) | ||
| 653 | { | ||
| 654 | struct zoran *zr = (struct zoran *) data; | ||
| 655 | |||
| 656 | return btread(ZR36057_I2CBR) & 1; | ||
| 657 | } | ||
| 658 | |||
| 659 | static void | ||
| 660 | zoran_i2c_setsda (void *data, | ||
| 661 | int state) | ||
| 662 | { | ||
| 663 | struct zoran *zr = (struct zoran *) data; | ||
| 664 | |||
| 665 | if (state) | ||
| 666 | zr->i2cbr |= 2; | ||
| 667 | else | ||
| 668 | zr->i2cbr &= ~2; | ||
| 669 | btwrite(zr->i2cbr, ZR36057_I2CBR); | ||
| 670 | } | ||
| 671 | |||
| 672 | static void | ||
| 673 | zoran_i2c_setscl (void *data, | ||
| 674 | int state) | ||
| 675 | { | ||
| 676 | struct zoran *zr = (struct zoran *) data; | ||
| 677 | |||
| 678 | if (state) | ||
| 679 | zr->i2cbr |= 1; | ||
| 680 | else | ||
| 681 | zr->i2cbr &= ~1; | ||
| 682 | btwrite(zr->i2cbr, ZR36057_I2CBR); | ||
| 683 | } | ||
| 684 | |||
| 685 | static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = { | ||
| 686 | .setsda = zoran_i2c_setsda, | ||
| 687 | .setscl = zoran_i2c_setscl, | ||
| 688 | .getsda = zoran_i2c_getsda, | ||
| 689 | .getscl = zoran_i2c_getscl, | ||
| 690 | .udelay = 10, | ||
| 691 | .timeout = 100, | ||
| 692 | }; | ||
| 693 | |||
| 694 | static int | ||
| 695 | zoran_register_i2c (struct zoran *zr) | ||
| 696 | { | ||
| 697 | zr->i2c_algo = zoran_i2c_bit_data_template; | ||
| 698 | zr->i2c_algo.data = zr; | ||
| 699 | strscpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), | ||
| 700 | sizeof(zr->i2c_adapter.name)); | ||
| 701 | i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev); | ||
| 702 | zr->i2c_adapter.algo_data = &zr->i2c_algo; | ||
| 703 | zr->i2c_adapter.dev.parent = &zr->pci_dev->dev; | ||
| 704 | return i2c_bit_add_bus(&zr->i2c_adapter); | ||
| 705 | } | ||
| 706 | |||
| 707 | static void | ||
| 708 | zoran_unregister_i2c (struct zoran *zr) | ||
| 709 | { | ||
| 710 | i2c_del_adapter(&zr->i2c_adapter); | ||
| 711 | } | ||
| 712 | |||
| 713 | /* Check a zoran_params struct for correctness, insert default params */ | ||
| 714 | |||
| 715 | int | ||
| 716 | zoran_check_jpg_settings (struct zoran *zr, | ||
| 717 | struct zoran_jpg_settings *settings, | ||
| 718 | int try) | ||
| 719 | { | ||
| 720 | int err = 0, err0 = 0; | ||
| 721 | |||
| 722 | dprintk(4, | ||
| 723 | KERN_DEBUG | ||
| 724 | "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n", | ||
| 725 | ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm, | ||
| 726 | settings->VerDcm, settings->TmpDcm); | ||
| 727 | dprintk(4, | ||
| 728 | KERN_DEBUG | ||
| 729 | "%s: %s - x: %d, y: %d, w: %d, y: %d\n", | ||
| 730 | ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y, | ||
| 731 | settings->img_width, settings->img_height); | ||
| 732 | /* Check decimation, set default values for decimation = 1, 2, 4 */ | ||
| 733 | switch (settings->decimation) { | ||
| 734 | case 1: | ||
| 735 | |||
| 736 | settings->HorDcm = 1; | ||
| 737 | settings->VerDcm = 1; | ||
| 738 | settings->TmpDcm = 1; | ||
| 739 | settings->field_per_buff = 2; | ||
| 740 | settings->img_x = 0; | ||
| 741 | settings->img_y = 0; | ||
| 742 | settings->img_width = BUZ_MAX_WIDTH; | ||
| 743 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
| 744 | break; | ||
| 745 | case 2: | ||
| 746 | |||
| 747 | settings->HorDcm = 2; | ||
| 748 | settings->VerDcm = 1; | ||
| 749 | settings->TmpDcm = 2; | ||
| 750 | settings->field_per_buff = 1; | ||
| 751 | settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
| 752 | settings->img_y = 0; | ||
| 753 | settings->img_width = | ||
| 754 | (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
| 755 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
| 756 | break; | ||
| 757 | case 4: | ||
| 758 | |||
| 759 | if (zr->card.type == DC10_new) { | ||
| 760 | dprintk(1, | ||
| 761 | KERN_DEBUG | ||
| 762 | "%s: %s - HDec by 4 is not supported on the DC10\n", | ||
| 763 | ZR_DEVNAME(zr), __func__); | ||
| 764 | err0++; | ||
| 765 | break; | ||
| 766 | } | ||
| 767 | |||
| 768 | settings->HorDcm = 4; | ||
| 769 | settings->VerDcm = 2; | ||
| 770 | settings->TmpDcm = 2; | ||
| 771 | settings->field_per_buff = 1; | ||
| 772 | settings->img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
| 773 | settings->img_y = 0; | ||
| 774 | settings->img_width = | ||
| 775 | (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
| 776 | settings->img_height = BUZ_MAX_HEIGHT / 2; | ||
| 777 | break; | ||
| 778 | case 0: | ||
| 779 | |||
| 780 | /* We have to check the data the user has set */ | ||
| 781 | |||
| 782 | if (settings->HorDcm != 1 && settings->HorDcm != 2 && | ||
| 783 | (zr->card.type == DC10_new || settings->HorDcm != 4)) { | ||
| 784 | settings->HorDcm = clamp(settings->HorDcm, 1, 2); | ||
| 785 | err0++; | ||
| 786 | } | ||
| 787 | if (settings->VerDcm != 1 && settings->VerDcm != 2) { | ||
| 788 | settings->VerDcm = clamp(settings->VerDcm, 1, 2); | ||
| 789 | err0++; | ||
| 790 | } | ||
| 791 | if (settings->TmpDcm != 1 && settings->TmpDcm != 2) { | ||
| 792 | settings->TmpDcm = clamp(settings->TmpDcm, 1, 2); | ||
| 793 | err0++; | ||
| 794 | } | ||
| 795 | if (settings->field_per_buff != 1 && | ||
| 796 | settings->field_per_buff != 2) { | ||
| 797 | settings->field_per_buff = clamp(settings->field_per_buff, 1, 2); | ||
| 798 | err0++; | ||
| 799 | } | ||
| 800 | if (settings->img_x < 0) { | ||
| 801 | settings->img_x = 0; | ||
| 802 | err0++; | ||
| 803 | } | ||
| 804 | if (settings->img_y < 0) { | ||
| 805 | settings->img_y = 0; | ||
| 806 | err0++; | ||
| 807 | } | ||
| 808 | if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) { | ||
| 809 | settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH); | ||
| 810 | err0++; | ||
| 811 | } | ||
| 812 | if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) { | ||
| 813 | settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2); | ||
| 814 | err0++; | ||
| 815 | } | ||
| 816 | if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) { | ||
| 817 | settings->img_x = BUZ_MAX_WIDTH - settings->img_width; | ||
| 818 | err0++; | ||
| 819 | } | ||
| 820 | if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) { | ||
| 821 | settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height; | ||
| 822 | err0++; | ||
| 823 | } | ||
| 824 | if (settings->img_width % (16 * settings->HorDcm) != 0) { | ||
| 825 | settings->img_width -= settings->img_width % (16 * settings->HorDcm); | ||
| 826 | if (settings->img_width == 0) | ||
| 827 | settings->img_width = 16 * settings->HorDcm; | ||
| 828 | err0++; | ||
| 829 | } | ||
| 830 | if (settings->img_height % (8 * settings->VerDcm) != 0) { | ||
| 831 | settings->img_height -= settings->img_height % (8 * settings->VerDcm); | ||
| 832 | if (settings->img_height == 0) | ||
| 833 | settings->img_height = 8 * settings->VerDcm; | ||
| 834 | err0++; | ||
| 835 | } | ||
| 836 | |||
| 837 | if (!try && err0) { | ||
| 838 | dprintk(1, | ||
| 839 | KERN_ERR | ||
| 840 | "%s: %s - error in params for decimation = 0\n", | ||
| 841 | ZR_DEVNAME(zr), __func__); | ||
| 842 | err++; | ||
| 843 | } | ||
| 844 | break; | ||
| 845 | default: | ||
| 846 | dprintk(1, | ||
| 847 | KERN_ERR | ||
| 848 | "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n", | ||
| 849 | ZR_DEVNAME(zr), __func__, settings->decimation); | ||
| 850 | err++; | ||
| 851 | break; | ||
| 852 | } | ||
| 853 | |||
| 854 | if (settings->jpg_comp.quality > 100) | ||
| 855 | settings->jpg_comp.quality = 100; | ||
| 856 | if (settings->jpg_comp.quality < 5) | ||
| 857 | settings->jpg_comp.quality = 5; | ||
| 858 | if (settings->jpg_comp.APPn < 0) | ||
| 859 | settings->jpg_comp.APPn = 0; | ||
| 860 | if (settings->jpg_comp.APPn > 15) | ||
| 861 | settings->jpg_comp.APPn = 15; | ||
| 862 | if (settings->jpg_comp.APP_len < 0) | ||
| 863 | settings->jpg_comp.APP_len = 0; | ||
| 864 | if (settings->jpg_comp.APP_len > 60) | ||
| 865 | settings->jpg_comp.APP_len = 60; | ||
| 866 | if (settings->jpg_comp.COM_len < 0) | ||
| 867 | settings->jpg_comp.COM_len = 0; | ||
| 868 | if (settings->jpg_comp.COM_len > 60) | ||
| 869 | settings->jpg_comp.COM_len = 60; | ||
| 870 | if (err) | ||
| 871 | return -EINVAL; | ||
| 872 | return 0; | ||
| 873 | } | ||
| 874 | |||
| 875 | void | ||
| 876 | zoran_open_init_params (struct zoran *zr) | ||
| 877 | { | ||
| 878 | int i; | ||
| 879 | |||
| 880 | /* User must explicitly set a window */ | ||
| 881 | zr->overlay_settings.is_set = 0; | ||
| 882 | zr->overlay_mask = NULL; | ||
| 883 | zr->overlay_active = ZORAN_FREE; | ||
| 884 | |||
| 885 | zr->v4l_memgrab_active = 0; | ||
| 886 | zr->v4l_overlay_active = 0; | ||
| 887 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
| 888 | zr->v4l_grab_seq = 0; | ||
| 889 | zr->v4l_settings.width = 192; | ||
| 890 | zr->v4l_settings.height = 144; | ||
| 891 | zr->v4l_settings.format = &zoran_formats[7]; /* YUY2 - YUV-4:2:2 packed */ | ||
| 892 | zr->v4l_settings.bytesperline = | ||
| 893 | zr->v4l_settings.width * | ||
| 894 | ((zr->v4l_settings.format->depth + 7) / 8); | ||
| 895 | |||
| 896 | /* DMA ring stuff for V4L */ | ||
| 897 | zr->v4l_pend_tail = 0; | ||
| 898 | zr->v4l_pend_head = 0; | ||
| 899 | zr->v4l_sync_tail = 0; | ||
| 900 | zr->v4l_buffers.active = ZORAN_FREE; | ||
| 901 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
| 902 | zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
| 903 | } | ||
| 904 | zr->v4l_buffers.allocated = 0; | ||
| 905 | |||
| 906 | for (i = 0; i < BUZ_MAX_FRAME; i++) { | ||
| 907 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
| 908 | } | ||
| 909 | zr->jpg_buffers.active = ZORAN_FREE; | ||
| 910 | zr->jpg_buffers.allocated = 0; | ||
| 911 | /* Set necessary params and call zoran_check_jpg_settings to set the defaults */ | ||
| 912 | zr->jpg_settings.decimation = 1; | ||
| 913 | zr->jpg_settings.jpg_comp.quality = 50; /* default compression factor 8 */ | ||
| 914 | if (zr->card.type != BUZ) | ||
| 915 | zr->jpg_settings.odd_even = 1; | ||
| 916 | else | ||
| 917 | zr->jpg_settings.odd_even = 0; | ||
| 918 | zr->jpg_settings.jpg_comp.APPn = 0; | ||
| 919 | zr->jpg_settings.jpg_comp.APP_len = 0; /* No APPn marker */ | ||
| 920 | memset(zr->jpg_settings.jpg_comp.APP_data, 0, | ||
| 921 | sizeof(zr->jpg_settings.jpg_comp.APP_data)); | ||
| 922 | zr->jpg_settings.jpg_comp.COM_len = 0; /* No COM marker */ | ||
| 923 | memset(zr->jpg_settings.jpg_comp.COM_data, 0, | ||
| 924 | sizeof(zr->jpg_settings.jpg_comp.COM_data)); | ||
| 925 | zr->jpg_settings.jpg_comp.jpeg_markers = | ||
| 926 | V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT; | ||
| 927 | i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0); | ||
| 928 | if (i) | ||
| 929 | dprintk(1, KERN_ERR "%s: %s internal error\n", | ||
| 930 | ZR_DEVNAME(zr), __func__); | ||
| 931 | |||
| 932 | clear_interrupt_counters(zr); | ||
| 933 | zr->testing = 0; | ||
| 934 | } | ||
| 935 | |||
| 936 | static void test_interrupts (struct zoran *zr) | ||
| 937 | { | ||
| 938 | DEFINE_WAIT(wait); | ||
| 939 | int timeout, icr; | ||
| 940 | |||
| 941 | clear_interrupt_counters(zr); | ||
| 942 | |||
| 943 | zr->testing = 1; | ||
| 944 | icr = btread(ZR36057_ICR); | ||
| 945 | btwrite(0x78000000 | ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
| 946 | prepare_to_wait(&zr->test_q, &wait, TASK_INTERRUPTIBLE); | ||
| 947 | timeout = schedule_timeout(HZ); | ||
| 948 | finish_wait(&zr->test_q, &wait); | ||
| 949 | btwrite(0, ZR36057_ICR); | ||
| 950 | btwrite(0x78000000, ZR36057_ISR); | ||
| 951 | zr->testing = 0; | ||
| 952 | dprintk(5, KERN_INFO "%s: Testing interrupts...\n", ZR_DEVNAME(zr)); | ||
| 953 | if (timeout) { | ||
| 954 | dprintk(1, ": time spent: %d\n", 1 * HZ - timeout); | ||
| 955 | } | ||
| 956 | if (zr36067_debug > 1) | ||
| 957 | print_interrupts(zr); | ||
| 958 | btwrite(icr, ZR36057_ICR); | ||
| 959 | } | ||
| 960 | |||
| 961 | static int zr36057_init (struct zoran *zr) | ||
| 962 | { | ||
| 963 | int j, err; | ||
| 964 | |||
| 965 | dprintk(1, | ||
| 966 | KERN_INFO | ||
| 967 | "%s: %s - initializing card[%d], zr=%p\n", | ||
| 968 | ZR_DEVNAME(zr), __func__, zr->id, zr); | ||
| 969 | |||
| 970 | /* default setup of all parameters which will persist between opens */ | ||
| 971 | zr->user = 0; | ||
| 972 | |||
| 973 | init_waitqueue_head(&zr->v4l_capq); | ||
| 974 | init_waitqueue_head(&zr->jpg_capq); | ||
| 975 | init_waitqueue_head(&zr->test_q); | ||
| 976 | zr->jpg_buffers.allocated = 0; | ||
| 977 | zr->v4l_buffers.allocated = 0; | ||
| 978 | |||
| 979 | zr->vbuf_base = (void *) vidmem; | ||
| 980 | zr->vbuf_width = 0; | ||
| 981 | zr->vbuf_height = 0; | ||
| 982 | zr->vbuf_depth = 0; | ||
| 983 | zr->vbuf_bytesperline = 0; | ||
| 984 | |||
| 985 | /* Avoid nonsense settings from user for default input/norm */ | ||
| 986 | if (default_norm < 0 || default_norm > 2) | ||
| 987 | default_norm = 0; | ||
| 988 | if (default_norm == 0) { | ||
| 989 | zr->norm = V4L2_STD_PAL; | ||
| 990 | zr->timing = zr->card.tvn[0]; | ||
| 991 | } else if (default_norm == 1) { | ||
| 992 | zr->norm = V4L2_STD_NTSC; | ||
| 993 | zr->timing = zr->card.tvn[1]; | ||
| 994 | } else { | ||
| 995 | zr->norm = V4L2_STD_SECAM; | ||
| 996 | zr->timing = zr->card.tvn[2]; | ||
| 997 | } | ||
| 998 | if (zr->timing == NULL) { | ||
| 999 | dprintk(1, | ||
| 1000 | KERN_WARNING | ||
| 1001 | "%s: %s - default TV standard not supported by hardware. PAL will be used.\n", | ||
| 1002 | ZR_DEVNAME(zr), __func__); | ||
| 1003 | zr->norm = V4L2_STD_PAL; | ||
| 1004 | zr->timing = zr->card.tvn[0]; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | if (default_input > zr->card.inputs-1) { | ||
| 1008 | dprintk(1, | ||
| 1009 | KERN_WARNING | ||
| 1010 | "%s: default_input value %d out of range (0-%d)\n", | ||
| 1011 | ZR_DEVNAME(zr), default_input, zr->card.inputs-1); | ||
| 1012 | default_input = 0; | ||
| 1013 | } | ||
| 1014 | zr->input = default_input; | ||
| 1015 | |||
| 1016 | /* default setup (will be repeated at every open) */ | ||
| 1017 | zoran_open_init_params(zr); | ||
| 1018 | |||
| 1019 | /* allocate memory *before* doing anything to the hardware | ||
| 1020 | * in case allocation fails */ | ||
| 1021 | zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL); | ||
| 1022 | zr->video_dev = video_device_alloc(); | ||
| 1023 | if (!zr->stat_com || !zr->video_dev) { | ||
| 1024 | dprintk(1, | ||
| 1025 | KERN_ERR | ||
| 1026 | "%s: %s - kmalloc (STAT_COM) failed\n", | ||
| 1027 | ZR_DEVNAME(zr), __func__); | ||
| 1028 | err = -ENOMEM; | ||
| 1029 | goto exit_free; | ||
| 1030 | } | ||
| 1031 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
| 1032 | zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | /* | ||
| 1036 | * Now add the template and register the device unit. | ||
| 1037 | */ | ||
| 1038 | *zr->video_dev = zoran_template; | ||
| 1039 | zr->video_dev->v4l2_dev = &zr->v4l2_dev; | ||
| 1040 | zr->video_dev->lock = &zr->lock; | ||
| 1041 | strscpy(zr->video_dev->name, ZR_DEVNAME(zr), sizeof(zr->video_dev->name)); | ||
| 1042 | /* It's not a mem2mem device, but you can both capture and output from | ||
| 1043 | one and the same device. This should really be split up into two | ||
| 1044 | device nodes, but that's a job for another day. */ | ||
| 1045 | zr->video_dev->vfl_dir = VFL_DIR_M2M; | ||
| 1046 | err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); | ||
| 1047 | if (err < 0) | ||
| 1048 | goto exit_free; | ||
| 1049 | video_set_drvdata(zr->video_dev, zr); | ||
| 1050 | |||
| 1051 | zoran_init_hardware(zr); | ||
| 1052 | if (zr36067_debug > 2) | ||
| 1053 | detect_guest_activity(zr); | ||
| 1054 | test_interrupts(zr); | ||
| 1055 | if (!pass_through) { | ||
| 1056 | decoder_call(zr, video, s_stream, 0); | ||
| 1057 | encoder_call(zr, video, s_routing, 2, 0, 0); | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | zr->zoran_proc = NULL; | ||
| 1061 | zr->initialized = 1; | ||
| 1062 | return 0; | ||
| 1063 | |||
| 1064 | exit_free: | ||
| 1065 | kfree(zr->stat_com); | ||
| 1066 | kfree(zr->video_dev); | ||
| 1067 | return err; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | static void zoran_remove(struct pci_dev *pdev) | ||
| 1071 | { | ||
| 1072 | struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); | ||
| 1073 | struct zoran *zr = to_zoran(v4l2_dev); | ||
| 1074 | |||
| 1075 | if (!zr->initialized) | ||
| 1076 | goto exit_free; | ||
| 1077 | |||
| 1078 | /* unregister videocodec bus */ | ||
| 1079 | if (zr->codec) { | ||
| 1080 | struct videocodec_master *master = zr->codec->master_data; | ||
| 1081 | |||
| 1082 | videocodec_detach(zr->codec); | ||
| 1083 | kfree(master); | ||
| 1084 | } | ||
| 1085 | if (zr->vfe) { | ||
| 1086 | struct videocodec_master *master = zr->vfe->master_data; | ||
| 1087 | |||
| 1088 | videocodec_detach(zr->vfe); | ||
| 1089 | kfree(master); | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | /* unregister i2c bus */ | ||
| 1093 | zoran_unregister_i2c(zr); | ||
| 1094 | /* disable PCI bus-mastering */ | ||
| 1095 | zoran_set_pci_master(zr, 0); | ||
| 1096 | /* put chip into reset */ | ||
| 1097 | btwrite(0, ZR36057_SPGPPCR); | ||
| 1098 | free_irq(zr->pci_dev->irq, zr); | ||
| 1099 | /* unmap and free memory */ | ||
| 1100 | kfree(zr->stat_com); | ||
| 1101 | zoran_proc_cleanup(zr); | ||
| 1102 | iounmap(zr->zr36057_mem); | ||
| 1103 | pci_disable_device(zr->pci_dev); | ||
| 1104 | video_unregister_device(zr->video_dev); | ||
| 1105 | exit_free: | ||
| 1106 | v4l2_ctrl_handler_free(&zr->hdl); | ||
| 1107 | v4l2_device_unregister(&zr->v4l2_dev); | ||
| 1108 | kfree(zr); | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | void | ||
| 1112 | zoran_vdev_release (struct video_device *vdev) | ||
| 1113 | { | ||
| 1114 | kfree(vdev); | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | static struct videocodec_master *zoran_setup_videocodec(struct zoran *zr, | ||
| 1118 | int type) | ||
| 1119 | { | ||
| 1120 | struct videocodec_master *m = NULL; | ||
| 1121 | |||
| 1122 | m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL); | ||
| 1123 | if (!m) { | ||
| 1124 | return m; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | /* magic and type are unused for master struct. Makes sense only at | ||
| 1128 | codec structs. | ||
| 1129 | In the past, .type were initialized to the old V4L1 .hardware | ||
| 1130 | value, as VID_HARDWARE_ZR36067 | ||
| 1131 | */ | ||
| 1132 | m->magic = 0L; | ||
| 1133 | m->type = 0; | ||
| 1134 | |||
| 1135 | m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER; | ||
| 1136 | strscpy(m->name, ZR_DEVNAME(zr), sizeof(m->name)); | ||
| 1137 | m->data = zr; | ||
| 1138 | |||
| 1139 | switch (type) { | ||
| 1140 | case CODEC_TYPE_ZR36060: | ||
| 1141 | m->readreg = zr36060_read; | ||
| 1142 | m->writereg = zr36060_write; | ||
| 1143 | m->flags |= CODEC_FLAG_JPEG | CODEC_FLAG_VFE; | ||
| 1144 | break; | ||
| 1145 | case CODEC_TYPE_ZR36050: | ||
| 1146 | m->readreg = zr36050_read; | ||
| 1147 | m->writereg = zr36050_write; | ||
| 1148 | m->flags |= CODEC_FLAG_JPEG; | ||
| 1149 | break; | ||
| 1150 | case CODEC_TYPE_ZR36016: | ||
| 1151 | m->readreg = zr36016_read; | ||
| 1152 | m->writereg = zr36016_write; | ||
| 1153 | m->flags |= CODEC_FLAG_VFE; | ||
| 1154 | break; | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | return m; | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg) | ||
| 1161 | { | ||
| 1162 | struct zoran *zr = to_zoran(sd->v4l2_dev); | ||
| 1163 | |||
| 1164 | /* Bt819 needs to reset its FIFO buffer using #FRST pin and | ||
| 1165 | LML33 card uses GPIO(7) for that. */ | ||
| 1166 | if (cmd == BT819_FIFO_RESET_LOW) | ||
| 1167 | GPIO(zr, 7, 0); | ||
| 1168 | else if (cmd == BT819_FIFO_RESET_HIGH) | ||
| 1169 | GPIO(zr, 7, 1); | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | /* | ||
| 1173 | * Scan for a Buz card (actually for the PCI controller ZR36057), | ||
| 1174 | * request the irq and map the io memory | ||
| 1175 | */ | ||
| 1176 | static int zoran_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
| 1177 | { | ||
| 1178 | unsigned char latency, need_latency; | ||
| 1179 | struct zoran *zr; | ||
| 1180 | int result; | ||
| 1181 | struct videocodec_master *master_vfe = NULL; | ||
| 1182 | struct videocodec_master *master_codec = NULL; | ||
| 1183 | int card_num; | ||
| 1184 | char *codec_name, *vfe_name; | ||
| 1185 | unsigned int nr; | ||
| 1186 | |||
| 1187 | |||
| 1188 | nr = zoran_num++; | ||
| 1189 | if (nr >= BUZ_MAX) { | ||
| 1190 | dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n", | ||
| 1191 | ZORAN_NAME, BUZ_MAX); | ||
| 1192 | return -ENOENT; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); | ||
| 1196 | if (!zr) { | ||
| 1197 | dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n", | ||
| 1198 | ZORAN_NAME, __func__); | ||
| 1199 | return -ENOMEM; | ||
| 1200 | } | ||
| 1201 | zr->v4l2_dev.notify = zoran_subdev_notify; | ||
| 1202 | if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev)) | ||
| 1203 | goto zr_free_mem; | ||
| 1204 | zr->pci_dev = pdev; | ||
| 1205 | zr->id = nr; | ||
| 1206 | snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); | ||
| 1207 | if (v4l2_ctrl_handler_init(&zr->hdl, 10)) | ||
| 1208 | goto zr_unreg; | ||
| 1209 | zr->v4l2_dev.ctrl_handler = &zr->hdl; | ||
| 1210 | spin_lock_init(&zr->spinlock); | ||
| 1211 | mutex_init(&zr->lock); | ||
| 1212 | if (pci_enable_device(pdev)) | ||
| 1213 | goto zr_unreg; | ||
| 1214 | zr->revision = zr->pci_dev->revision; | ||
| 1215 | |||
| 1216 | dprintk(1, | ||
| 1217 | KERN_INFO | ||
| 1218 | "%s: Zoran ZR360%c7 (rev %d), irq: %d, memory: 0x%08llx\n", | ||
| 1219 | ZR_DEVNAME(zr), zr->revision < 2 ? '5' : '6', zr->revision, | ||
| 1220 | zr->pci_dev->irq, (uint64_t)pci_resource_start(zr->pci_dev, 0)); | ||
| 1221 | if (zr->revision >= 2) { | ||
| 1222 | dprintk(1, | ||
| 1223 | KERN_INFO | ||
| 1224 | "%s: Subsystem vendor=0x%04x id=0x%04x\n", | ||
| 1225 | ZR_DEVNAME(zr), zr->pci_dev->subsystem_vendor, | ||
| 1226 | zr->pci_dev->subsystem_device); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /* Use auto-detected card type? */ | ||
| 1230 | if (card[nr] == -1) { | ||
| 1231 | if (zr->revision < 2) { | ||
| 1232 | dprintk(1, | ||
| 1233 | KERN_ERR | ||
| 1234 | "%s: No card type specified, please use the card=X module parameter\n", | ||
| 1235 | ZR_DEVNAME(zr)); | ||
| 1236 | dprintk(1, | ||
| 1237 | KERN_ERR | ||
| 1238 | "%s: It is not possible to auto-detect ZR36057 based cards\n", | ||
| 1239 | ZR_DEVNAME(zr)); | ||
| 1240 | goto zr_unreg; | ||
| 1241 | } | ||
| 1242 | |||
| 1243 | card_num = ent->driver_data; | ||
| 1244 | if (card_num >= NUM_CARDS) { | ||
| 1245 | dprintk(1, | ||
| 1246 | KERN_ERR | ||
| 1247 | "%s: Unknown card, try specifying card=X module parameter\n", | ||
| 1248 | ZR_DEVNAME(zr)); | ||
| 1249 | goto zr_unreg; | ||
| 1250 | } | ||
| 1251 | dprintk(3, | ||
| 1252 | KERN_DEBUG | ||
| 1253 | "%s: %s() - card %s detected\n", | ||
| 1254 | ZR_DEVNAME(zr), __func__, zoran_cards[card_num].name); | ||
| 1255 | } else { | ||
| 1256 | card_num = card[nr]; | ||
| 1257 | if (card_num >= NUM_CARDS || card_num < 0) { | ||
| 1258 | dprintk(1, | ||
| 1259 | KERN_ERR | ||
| 1260 | "%s: User specified card type %d out of range (0 .. %d)\n", | ||
| 1261 | ZR_DEVNAME(zr), card_num, NUM_CARDS - 1); | ||
| 1262 | goto zr_unreg; | ||
| 1263 | } | ||
| 1264 | } | ||
| 1265 | |||
| 1266 | /* even though we make this a non pointer and thus | ||
| 1267 | * theoretically allow for making changes to this struct | ||
| 1268 | * on a per-individual card basis at runtime, this is | ||
| 1269 | * strongly discouraged. This structure is intended to | ||
| 1270 | * keep general card information, no settings or anything */ | ||
| 1271 | zr->card = zoran_cards[card_num]; | ||
| 1272 | snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), | ||
| 1273 | "%s[%u]", zr->card.name, zr->id); | ||
| 1274 | |||
| 1275 | zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0); | ||
| 1276 | if (!zr->zr36057_mem) { | ||
| 1277 | dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n", | ||
| 1278 | ZR_DEVNAME(zr), __func__); | ||
| 1279 | goto zr_unreg; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | result = request_irq(zr->pci_dev->irq, zoran_irq, | ||
| 1283 | IRQF_SHARED, ZR_DEVNAME(zr), zr); | ||
| 1284 | if (result < 0) { | ||
| 1285 | if (result == -EINVAL) { | ||
| 1286 | dprintk(1, | ||
| 1287 | KERN_ERR | ||
| 1288 | "%s: %s - bad irq number or handler\n", | ||
| 1289 | ZR_DEVNAME(zr), __func__); | ||
| 1290 | } else if (result == -EBUSY) { | ||
| 1291 | dprintk(1, | ||
| 1292 | KERN_ERR | ||
| 1293 | "%s: %s - IRQ %d busy, change your PnP config in BIOS\n", | ||
| 1294 | ZR_DEVNAME(zr), __func__, zr->pci_dev->irq); | ||
| 1295 | } else { | ||
| 1296 | dprintk(1, | ||
| 1297 | KERN_ERR | ||
| 1298 | "%s: %s - can't assign irq, error code %d\n", | ||
| 1299 | ZR_DEVNAME(zr), __func__, result); | ||
| 1300 | } | ||
| 1301 | goto zr_unmap; | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | /* set PCI latency timer */ | ||
| 1305 | pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, | ||
| 1306 | &latency); | ||
| 1307 | need_latency = zr->revision > 1 ? 32 : 48; | ||
| 1308 | if (latency != need_latency) { | ||
| 1309 | dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n", | ||
| 1310 | ZR_DEVNAME(zr), latency, need_latency); | ||
| 1311 | pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, | ||
| 1312 | need_latency); | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | zr36057_restart(zr); | ||
| 1316 | /* i2c */ | ||
| 1317 | dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", | ||
| 1318 | ZR_DEVNAME(zr)); | ||
| 1319 | |||
| 1320 | if (zoran_register_i2c(zr) < 0) { | ||
| 1321 | dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n", | ||
| 1322 | ZR_DEVNAME(zr), __func__); | ||
| 1323 | goto zr_free_irq; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | ||
| 1327 | &zr->i2c_adapter, zr->card.i2c_decoder, | ||
| 1328 | 0, zr->card.addrs_decoder); | ||
| 1329 | |||
| 1330 | if (zr->card.i2c_encoder) | ||
| 1331 | zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev, | ||
| 1332 | &zr->i2c_adapter, zr->card.i2c_encoder, | ||
| 1333 | 0, zr->card.addrs_encoder); | ||
| 1334 | |||
| 1335 | dprintk(2, | ||
| 1336 | KERN_INFO "%s: Initializing videocodec bus...\n", | ||
| 1337 | ZR_DEVNAME(zr)); | ||
| 1338 | |||
| 1339 | if (zr->card.video_codec) { | ||
| 1340 | codec_name = codecid_to_modulename(zr->card.video_codec); | ||
| 1341 | if (codec_name) { | ||
| 1342 | result = request_module(codec_name); | ||
| 1343 | if (result) { | ||
| 1344 | dprintk(1, | ||
| 1345 | KERN_ERR | ||
| 1346 | "%s: failed to load modules %s: %d\n", | ||
| 1347 | ZR_DEVNAME(zr), codec_name, result); | ||
| 1348 | } | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | if (zr->card.video_vfe) { | ||
| 1352 | vfe_name = codecid_to_modulename(zr->card.video_vfe); | ||
| 1353 | if (vfe_name) { | ||
| 1354 | result = request_module(vfe_name); | ||
| 1355 | if (result < 0) { | ||
| 1356 | dprintk(1, | ||
| 1357 | KERN_ERR | ||
| 1358 | "%s: failed to load modules %s: %d\n", | ||
| 1359 | ZR_DEVNAME(zr), vfe_name, result); | ||
| 1360 | } | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | /* reset JPEG codec */ | ||
| 1365 | jpeg_codec_sleep(zr, 1); | ||
| 1366 | jpeg_codec_reset(zr); | ||
| 1367 | /* video bus enabled */ | ||
| 1368 | /* display codec revision */ | ||
| 1369 | if (zr->card.video_codec != 0) { | ||
| 1370 | master_codec = zoran_setup_videocodec(zr, zr->card.video_codec); | ||
| 1371 | if (!master_codec) | ||
| 1372 | goto zr_unreg_i2c; | ||
| 1373 | zr->codec = videocodec_attach(master_codec); | ||
| 1374 | if (!zr->codec) { | ||
| 1375 | dprintk(1, KERN_ERR "%s: %s - no codec found\n", | ||
| 1376 | ZR_DEVNAME(zr), __func__); | ||
| 1377 | goto zr_free_codec; | ||
| 1378 | } | ||
| 1379 | if (zr->codec->type != zr->card.video_codec) { | ||
| 1380 | dprintk(1, KERN_ERR "%s: %s - wrong codec\n", | ||
| 1381 | ZR_DEVNAME(zr), __func__); | ||
| 1382 | goto zr_detach_codec; | ||
| 1383 | } | ||
| 1384 | } | ||
| 1385 | if (zr->card.video_vfe != 0) { | ||
| 1386 | master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe); | ||
| 1387 | if (!master_vfe) | ||
| 1388 | goto zr_detach_codec; | ||
| 1389 | zr->vfe = videocodec_attach(master_vfe); | ||
| 1390 | if (!zr->vfe) { | ||
| 1391 | dprintk(1, KERN_ERR "%s: %s - no VFE found\n", | ||
| 1392 | ZR_DEVNAME(zr), __func__); | ||
| 1393 | goto zr_free_vfe; | ||
| 1394 | } | ||
| 1395 | if (zr->vfe->type != zr->card.video_vfe) { | ||
| 1396 | dprintk(1, KERN_ERR "%s: %s = wrong VFE\n", | ||
| 1397 | ZR_DEVNAME(zr), __func__); | ||
| 1398 | goto zr_detach_vfe; | ||
| 1399 | } | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | /* take care of Natoma chipset and a revision 1 zr36057 */ | ||
| 1403 | if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { | ||
| 1404 | zr->jpg_buffers.need_contiguous = 1; | ||
| 1405 | dprintk(1, KERN_INFO | ||
| 1406 | "%s: ZR36057/Natoma bug, max. buffer size is 128K\n", | ||
| 1407 | ZR_DEVNAME(zr)); | ||
| 1408 | } | ||
| 1409 | |||
| 1410 | if (zr36057_init(zr) < 0) | ||
| 1411 | goto zr_detach_vfe; | ||
| 1412 | |||
| 1413 | zoran_proc_init(zr); | ||
| 1414 | |||
| 1415 | return 0; | ||
| 1416 | |||
| 1417 | zr_detach_vfe: | ||
| 1418 | videocodec_detach(zr->vfe); | ||
| 1419 | zr_free_vfe: | ||
| 1420 | kfree(master_vfe); | ||
| 1421 | zr_detach_codec: | ||
| 1422 | videocodec_detach(zr->codec); | ||
| 1423 | zr_free_codec: | ||
| 1424 | kfree(master_codec); | ||
| 1425 | zr_unreg_i2c: | ||
| 1426 | zoran_unregister_i2c(zr); | ||
| 1427 | zr_free_irq: | ||
| 1428 | btwrite(0, ZR36057_SPGPPCR); | ||
| 1429 | free_irq(zr->pci_dev->irq, zr); | ||
| 1430 | zr_unmap: | ||
| 1431 | iounmap(zr->zr36057_mem); | ||
| 1432 | zr_unreg: | ||
| 1433 | v4l2_ctrl_handler_free(&zr->hdl); | ||
| 1434 | v4l2_device_unregister(&zr->v4l2_dev); | ||
| 1435 | zr_free_mem: | ||
| 1436 | kfree(zr); | ||
| 1437 | |||
| 1438 | return -ENODEV; | ||
| 1439 | } | ||
| 1440 | |||
| 1441 | static struct pci_driver zoran_driver = { | ||
| 1442 | .name = "zr36067", | ||
| 1443 | .id_table = zr36067_pci_tbl, | ||
| 1444 | .probe = zoran_probe, | ||
| 1445 | .remove = zoran_remove, | ||
| 1446 | }; | ||
| 1447 | |||
| 1448 | static int __init zoran_init(void) | ||
| 1449 | { | ||
| 1450 | int res; | ||
| 1451 | |||
| 1452 | printk(KERN_INFO "Zoran MJPEG board driver version %s\n", | ||
| 1453 | ZORAN_VERSION); | ||
| 1454 | |||
| 1455 | /* check the parameters we have been given, adjust if necessary */ | ||
| 1456 | if (v4l_nbufs < 2) | ||
| 1457 | v4l_nbufs = 2; | ||
| 1458 | if (v4l_nbufs > VIDEO_MAX_FRAME) | ||
| 1459 | v4l_nbufs = VIDEO_MAX_FRAME; | ||
| 1460 | /* The user specifies the in KB, we want them in byte | ||
| 1461 | * (and page aligned) */ | ||
| 1462 | v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024); | ||
| 1463 | if (v4l_bufsize < 32768) | ||
| 1464 | v4l_bufsize = 32768; | ||
| 1465 | /* 2 MB is arbitrary but sufficient for the maximum possible images */ | ||
| 1466 | if (v4l_bufsize > 2048 * 1024) | ||
| 1467 | v4l_bufsize = 2048 * 1024; | ||
| 1468 | if (jpg_nbufs < 4) | ||
| 1469 | jpg_nbufs = 4; | ||
| 1470 | if (jpg_nbufs > BUZ_MAX_FRAME) | ||
| 1471 | jpg_nbufs = BUZ_MAX_FRAME; | ||
| 1472 | jpg_bufsize = PAGE_ALIGN(jpg_bufsize * 1024); | ||
| 1473 | if (jpg_bufsize < 8192) | ||
| 1474 | jpg_bufsize = 8192; | ||
| 1475 | if (jpg_bufsize > (512 * 1024)) | ||
| 1476 | jpg_bufsize = 512 * 1024; | ||
| 1477 | /* Use parameter for vidmem or try to find a video card */ | ||
| 1478 | if (vidmem) { | ||
| 1479 | dprintk(1, | ||
| 1480 | KERN_INFO | ||
| 1481 | "%s: Using supplied video memory base address @ 0x%lx\n", | ||
| 1482 | ZORAN_NAME, vidmem); | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | /* some mainboards might not do PCI-PCI data transfer well */ | ||
| 1486 | if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) { | ||
| 1487 | dprintk(1, | ||
| 1488 | KERN_WARNING | ||
| 1489 | "%s: chipset does not support reliable PCI-PCI DMA\n", | ||
| 1490 | ZORAN_NAME); | ||
| 1491 | } | ||
| 1492 | |||
| 1493 | res = pci_register_driver(&zoran_driver); | ||
| 1494 | if (res) { | ||
| 1495 | dprintk(1, | ||
| 1496 | KERN_ERR | ||
| 1497 | "%s: Unable to register ZR36057 driver\n", | ||
| 1498 | ZORAN_NAME); | ||
| 1499 | return res; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | return 0; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | static void __exit zoran_exit(void) | ||
| 1506 | { | ||
| 1507 | pci_unregister_driver(&zoran_driver); | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | module_init(zoran_init); | ||
| 1511 | module_exit(zoran_exit); | ||
diff --git a/drivers/staging/media/zoran/zoran_card.h b/drivers/staging/media/zoran/zoran_card.h deleted file mode 100644 index 600b9a3f320c..000000000000 --- a/drivers/staging/media/zoran/zoran_card.h +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles card-specific data and detection | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #ifndef __ZORAN_CARD_H__ | ||
| 17 | #define __ZORAN_CARD_H__ | ||
| 18 | |||
| 19 | extern int zr36067_debug; | ||
| 20 | |||
| 21 | #define dprintk(num, format, args...) \ | ||
| 22 | do { \ | ||
| 23 | if (zr36067_debug >= num) \ | ||
| 24 | printk(format, ##args); \ | ||
| 25 | } while (0) | ||
| 26 | |||
| 27 | /* Anybody who uses more than four? */ | ||
| 28 | #define BUZ_MAX 4 | ||
| 29 | |||
| 30 | extern const struct video_device zoran_template; | ||
| 31 | |||
| 32 | extern int zoran_check_jpg_settings(struct zoran *zr, | ||
| 33 | struct zoran_jpg_settings *settings, | ||
| 34 | int try); | ||
| 35 | extern void zoran_open_init_params(struct zoran *zr); | ||
| 36 | extern void zoran_vdev_release(struct video_device *vdev); | ||
| 37 | |||
| 38 | void zr36016_write(struct videocodec *codec, u16 reg, u32 val); | ||
| 39 | |||
| 40 | #endif /* __ZORAN_CARD_H__ */ | ||
diff --git a/drivers/staging/media/zoran/zoran_device.c b/drivers/staging/media/zoran/zoran_device.c deleted file mode 100644 index 2191fe69b0f9..000000000000 --- a/drivers/staging/media/zoran/zoran_device.c +++ /dev/null | |||
| @@ -1,1609 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles device access (PCI/I2C/codec/...) | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/vmalloc.h> | ||
| 20 | #include <linux/ktime.h> | ||
| 21 | #include <linux/sched/signal.h> | ||
| 22 | |||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/proc_fs.h> | ||
| 25 | #include <linux/i2c.h> | ||
| 26 | #include <linux/i2c-algo-bit.h> | ||
| 27 | #include <linux/videodev2.h> | ||
| 28 | #include <media/v4l2-common.h> | ||
| 29 | #include <linux/spinlock.h> | ||
| 30 | #include <linux/sem.h> | ||
| 31 | |||
| 32 | #include <linux/pci.h> | ||
| 33 | #include <linux/delay.h> | ||
| 34 | #include <linux/wait.h> | ||
| 35 | |||
| 36 | #include <asm/byteorder.h> | ||
| 37 | #include <asm/io.h> | ||
| 38 | |||
| 39 | #include "videocodec.h" | ||
| 40 | #include "zoran.h" | ||
| 41 | #include "zoran_device.h" | ||
| 42 | #include "zoran_card.h" | ||
| 43 | |||
| 44 | #define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \ | ||
| 45 | ZR36057_ISR_GIRQ1 | \ | ||
| 46 | ZR36057_ISR_JPEGRepIRQ ) | ||
| 47 | |||
| 48 | static bool lml33dpath; /* default = 0 | ||
| 49 | * 1 will use digital path in capture | ||
| 50 | * mode instead of analog. It can be | ||
| 51 | * used for picture adjustments using | ||
| 52 | * tool like xawtv while watching image | ||
| 53 | * on TV monitor connected to the output. | ||
| 54 | * However, due to absence of 75 Ohm | ||
| 55 | * load on Bt819 input, there will be | ||
| 56 | * some image imperfections */ | ||
| 57 | |||
| 58 | module_param(lml33dpath, bool, 0644); | ||
| 59 | MODULE_PARM_DESC(lml33dpath, | ||
| 60 | "Use digital path capture mode (on LML33 cards)"); | ||
| 61 | |||
| 62 | static void | ||
| 63 | zr36057_init_vfe (struct zoran *zr); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * General Purpose I/O and Guest bus access | ||
| 67 | */ | ||
| 68 | |||
| 69 | /* | ||
| 70 | * This is a bit tricky. When a board lacks a GPIO function, the corresponding | ||
| 71 | * GPIO bit number in the card_info structure is set to 0. | ||
| 72 | */ | ||
| 73 | |||
| 74 | void | ||
| 75 | GPIO (struct zoran *zr, | ||
| 76 | int bit, | ||
| 77 | unsigned int value) | ||
| 78 | { | ||
| 79 | u32 reg; | ||
| 80 | u32 mask; | ||
| 81 | |||
| 82 | /* Make sure the bit number is legal | ||
| 83 | * A bit number of -1 (lacking) gives a mask of 0, | ||
| 84 | * making it harmless */ | ||
| 85 | mask = (1 << (24 + bit)) & 0xff000000; | ||
| 86 | reg = btread(ZR36057_GPPGCR1) & ~mask; | ||
| 87 | if (value) { | ||
| 88 | reg |= mask; | ||
| 89 | } | ||
| 90 | btwrite(reg, ZR36057_GPPGCR1); | ||
| 91 | udelay(1); | ||
| 92 | } | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Wait til post office is no longer busy | ||
| 96 | */ | ||
| 97 | |||
| 98 | int | ||
| 99 | post_office_wait (struct zoran *zr) | ||
| 100 | { | ||
| 101 | u32 por; | ||
| 102 | |||
| 103 | // while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) { | ||
| 104 | while ((por = btread(ZR36057_POR)) & ZR36057_POR_POPen) { | ||
| 105 | /* wait for something to happen */ | ||
| 106 | } | ||
| 107 | if ((por & ZR36057_POR_POTime) && !zr->card.gws_not_connected) { | ||
| 108 | /* In LML33/BUZ \GWS line is not connected, so it has always timeout set */ | ||
| 109 | dprintk(1, KERN_INFO "%s: pop timeout %08x\n", ZR_DEVNAME(zr), | ||
| 110 | por); | ||
| 111 | return -1; | ||
| 112 | } | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | int | ||
| 118 | post_office_write (struct zoran *zr, | ||
| 119 | unsigned int guest, | ||
| 120 | unsigned int reg, | ||
| 121 | unsigned int value) | ||
| 122 | { | ||
| 123 | u32 por; | ||
| 124 | |||
| 125 | por = | ||
| 126 | ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | | ||
| 127 | ((reg & 7) << 16) | (value & 0xFF); | ||
| 128 | btwrite(por, ZR36057_POR); | ||
| 129 | |||
| 130 | return post_office_wait(zr); | ||
| 131 | } | ||
| 132 | |||
| 133 | int | ||
| 134 | post_office_read (struct zoran *zr, | ||
| 135 | unsigned int guest, | ||
| 136 | unsigned int reg) | ||
| 137 | { | ||
| 138 | u32 por; | ||
| 139 | |||
| 140 | por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16); | ||
| 141 | btwrite(por, ZR36057_POR); | ||
| 142 | if (post_office_wait(zr) < 0) { | ||
| 143 | return -1; | ||
| 144 | } | ||
| 145 | |||
| 146 | return btread(ZR36057_POR) & 0xFF; | ||
| 147 | } | ||
| 148 | |||
| 149 | /* | ||
| 150 | * detect guests | ||
| 151 | */ | ||
| 152 | |||
| 153 | static void | ||
| 154 | dump_guests (struct zoran *zr) | ||
| 155 | { | ||
| 156 | if (zr36067_debug > 2) { | ||
| 157 | int i, guest[8]; | ||
| 158 | |||
| 159 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
| 160 | guest[i] = post_office_read(zr, i, 0); | ||
| 161 | } | ||
| 162 | |||
| 163 | printk(KERN_INFO "%s: Guests: %*ph\n", | ||
| 164 | ZR_DEVNAME(zr), 8, guest); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | void | ||
| 169 | detect_guest_activity (struct zoran *zr) | ||
| 170 | { | ||
| 171 | int timeout, i, j, res, guest[8], guest0[8], change[8][3]; | ||
| 172 | ktime_t t0, t1; | ||
| 173 | |||
| 174 | dump_guests(zr); | ||
| 175 | printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", | ||
| 176 | ZR_DEVNAME(zr)); | ||
| 177 | for (i = 1; i < 8; i++) { // Don't read jpeg codec here | ||
| 178 | guest0[i] = guest[i] = post_office_read(zr, i, 0); | ||
| 179 | } | ||
| 180 | |||
| 181 | timeout = 0; | ||
| 182 | j = 0; | ||
| 183 | t0 = ktime_get(); | ||
| 184 | while (timeout < 10000) { | ||
| 185 | udelay(10); | ||
| 186 | timeout++; | ||
| 187 | for (i = 1; (i < 8) && (j < 8); i++) { | ||
| 188 | res = post_office_read(zr, i, 0); | ||
| 189 | if (res != guest[i]) { | ||
| 190 | t1 = ktime_get(); | ||
| 191 | change[j][0] = ktime_to_us(ktime_sub(t1, t0)); | ||
| 192 | t0 = t1; | ||
| 193 | change[j][1] = i; | ||
| 194 | change[j][2] = res; | ||
| 195 | j++; | ||
| 196 | guest[i] = res; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | if (j >= 8) | ||
| 200 | break; | ||
| 201 | } | ||
| 202 | |||
| 203 | printk(KERN_INFO "%s: Guests: %*ph\n", ZR_DEVNAME(zr), 8, guest0); | ||
| 204 | |||
| 205 | if (j == 0) { | ||
| 206 | printk(KERN_INFO "%s: No activity detected.\n", ZR_DEVNAME(zr)); | ||
| 207 | return; | ||
| 208 | } | ||
| 209 | for (i = 0; i < j; i++) { | ||
| 210 | printk(KERN_INFO "%s: %6d: %d => 0x%02x\n", ZR_DEVNAME(zr), | ||
| 211 | change[i][0], change[i][1], change[i][2]); | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 215 | /* | ||
| 216 | * JPEG Codec access | ||
| 217 | */ | ||
| 218 | |||
| 219 | void | ||
| 220 | jpeg_codec_sleep (struct zoran *zr, | ||
| 221 | int sleep) | ||
| 222 | { | ||
| 223 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_SLEEP], !sleep); | ||
| 224 | if (!sleep) { | ||
| 225 | dprintk(3, | ||
| 226 | KERN_DEBUG | ||
| 227 | "%s: jpeg_codec_sleep() - wake GPIO=0x%08x\n", | ||
| 228 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
| 229 | udelay(500); | ||
| 230 | } else { | ||
| 231 | dprintk(3, | ||
| 232 | KERN_DEBUG | ||
| 233 | "%s: jpeg_codec_sleep() - sleep GPIO=0x%08x\n", | ||
| 234 | ZR_DEVNAME(zr), btread(ZR36057_GPPGCR1)); | ||
| 235 | udelay(2); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | int | ||
| 240 | jpeg_codec_reset (struct zoran *zr) | ||
| 241 | { | ||
| 242 | /* Take the codec out of sleep */ | ||
| 243 | jpeg_codec_sleep(zr, 0); | ||
| 244 | |||
| 245 | if (zr->card.gpcs[GPCS_JPEG_RESET] != 0xff) { | ||
| 246 | post_office_write(zr, zr->card.gpcs[GPCS_JPEG_RESET], 0, | ||
| 247 | 0); | ||
| 248 | udelay(2); | ||
| 249 | } else { | ||
| 250 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 0); | ||
| 251 | udelay(2); | ||
| 252 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_RESET], 1); | ||
| 253 | udelay(2); | ||
| 254 | } | ||
| 255 | |||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Set the registers for the size we have specified. Don't bother | ||
| 261 | * trying to understand this without the ZR36057 manual in front of | ||
| 262 | * you [AC]. | ||
| 263 | * | ||
| 264 | * PS: The manual is free for download in .pdf format from | ||
| 265 | * www.zoran.com - nicely done those folks. | ||
| 266 | */ | ||
| 267 | |||
| 268 | static void | ||
| 269 | zr36057_adjust_vfe (struct zoran *zr, | ||
| 270 | enum zoran_codec_mode mode) | ||
| 271 | { | ||
| 272 | u32 reg; | ||
| 273 | |||
| 274 | switch (mode) { | ||
| 275 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
| 276 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
| 277 | reg = btread(ZR36057_VFEHCR); | ||
| 278 | if ((reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
| 279 | reg += ((1 << 10) | 1); | ||
| 280 | } | ||
| 281 | btwrite(reg, ZR36057_VFEHCR); | ||
| 282 | break; | ||
| 283 | case BUZ_MODE_MOTION_COMPRESS: | ||
| 284 | case BUZ_MODE_IDLE: | ||
| 285 | default: | ||
| 286 | if ((zr->norm & V4L2_STD_NTSC) || | ||
| 287 | (zr->card.type == LML33R10 && | ||
| 288 | (zr->norm & V4L2_STD_PAL))) | ||
| 289 | btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
| 290 | else | ||
| 291 | btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR); | ||
| 292 | reg = btread(ZR36057_VFEHCR); | ||
| 293 | if (!(reg & (1 << 10)) && zr->card.type != LML33R10) { | ||
| 294 | reg -= ((1 << 10) | 1); | ||
| 295 | } | ||
| 296 | btwrite(reg, ZR36057_VFEHCR); | ||
| 297 | break; | ||
| 298 | } | ||
| 299 | } | ||
| 300 | |||
| 301 | /* | ||
| 302 | * set geometry | ||
| 303 | */ | ||
| 304 | |||
| 305 | static void | ||
| 306 | zr36057_set_vfe (struct zoran *zr, | ||
| 307 | int video_width, | ||
| 308 | int video_height, | ||
| 309 | const struct zoran_format *format) | ||
| 310 | { | ||
| 311 | struct tvnorm *tvn; | ||
| 312 | unsigned HStart, HEnd, VStart, VEnd; | ||
| 313 | unsigned DispMode; | ||
| 314 | unsigned VidWinWid, VidWinHt; | ||
| 315 | unsigned hcrop1, hcrop2, vcrop1, vcrop2; | ||
| 316 | unsigned Wa, We, Ha, He; | ||
| 317 | unsigned X, Y, HorDcm, VerDcm; | ||
| 318 | u32 reg; | ||
| 319 | unsigned mask_line_size; | ||
| 320 | |||
| 321 | tvn = zr->timing; | ||
| 322 | |||
| 323 | Wa = tvn->Wa; | ||
| 324 | Ha = tvn->Ha; | ||
| 325 | |||
| 326 | dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n", | ||
| 327 | ZR_DEVNAME(zr), video_width, video_height); | ||
| 328 | |||
| 329 | if (video_width < BUZ_MIN_WIDTH || | ||
| 330 | video_height < BUZ_MIN_HEIGHT || | ||
| 331 | video_width > Wa || video_height > Ha) { | ||
| 332 | dprintk(1, KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", | ||
| 333 | ZR_DEVNAME(zr), video_width, video_height); | ||
| 334 | return; | ||
| 335 | } | ||
| 336 | |||
| 337 | /**** zr36057 ****/ | ||
| 338 | |||
| 339 | /* horizontal */ | ||
| 340 | VidWinWid = video_width; | ||
| 341 | X = DIV_ROUND_UP(VidWinWid * 64, tvn->Wa); | ||
| 342 | We = (VidWinWid * 64) / X; | ||
| 343 | HorDcm = 64 - X; | ||
| 344 | hcrop1 = 2 * ((tvn->Wa - We) / 4); | ||
| 345 | hcrop2 = tvn->Wa - We - hcrop1; | ||
| 346 | HStart = tvn->HStart ? tvn->HStart : 1; | ||
| 347 | /* (Ronald) Original comment: | ||
| 348 | * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" | ||
| 349 | * this is false. It inverses chroma values on the LML33R10 (so Cr | ||
| 350 | * suddenly is shown as Cb and reverse, really cool effect if you | ||
| 351 | * want to see blue faces, not useful otherwise). So don't use |1. | ||
| 352 | * However, the DC10 has '0' as HStart, but does need |1, so we | ||
| 353 | * use a dirty check... | ||
| 354 | */ | ||
| 355 | HEnd = HStart + tvn->Wa - 1; | ||
| 356 | HStart += hcrop1; | ||
| 357 | HEnd -= hcrop2; | ||
| 358 | reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart) | ||
| 359 | | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd); | ||
| 360 | if (zr->card.vfe_pol.hsync_pol) | ||
| 361 | reg |= ZR36057_VFEHCR_HSPol; | ||
| 362 | btwrite(reg, ZR36057_VFEHCR); | ||
| 363 | |||
| 364 | /* Vertical */ | ||
| 365 | DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); | ||
| 366 | VidWinHt = DispMode ? video_height : video_height / 2; | ||
| 367 | Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->Ha); | ||
| 368 | He = (VidWinHt * 64) / Y; | ||
| 369 | VerDcm = 64 - Y; | ||
| 370 | vcrop1 = (tvn->Ha / 2 - He) / 2; | ||
| 371 | vcrop2 = tvn->Ha / 2 - He - vcrop1; | ||
| 372 | VStart = tvn->VStart; | ||
| 373 | VEnd = VStart + tvn->Ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP | ||
| 374 | VStart += vcrop1; | ||
| 375 | VEnd -= vcrop2; | ||
| 376 | reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart) | ||
| 377 | | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd); | ||
| 378 | if (zr->card.vfe_pol.vsync_pol) | ||
| 379 | reg |= ZR36057_VFEVCR_VSPol; | ||
| 380 | btwrite(reg, ZR36057_VFEVCR); | ||
| 381 | |||
| 382 | /* scaler and pixel format */ | ||
| 383 | reg = 0; | ||
| 384 | reg |= (HorDcm << ZR36057_VFESPFR_HorDcm); | ||
| 385 | reg |= (VerDcm << ZR36057_VFESPFR_VerDcm); | ||
| 386 | reg |= (DispMode << ZR36057_VFESPFR_DispMode); | ||
| 387 | /* RJ: I don't know, why the following has to be the opposite | ||
| 388 | * of the corresponding ZR36060 setting, but only this way | ||
| 389 | * we get the correct colors when uncompressing to the screen */ | ||
| 390 | //reg |= ZR36057_VFESPFR_VCLKPol; /**/ | ||
| 391 | /* RJ: Don't know if that is needed for NTSC also */ | ||
| 392 | if (!(zr->norm & V4L2_STD_NTSC)) | ||
| 393 | reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang | ||
| 394 | reg |= ZR36057_VFESPFR_TopField; | ||
| 395 | if (HorDcm >= 48) { | ||
| 396 | reg |= 3 << ZR36057_VFESPFR_HFilter; /* 5 tap filter */ | ||
| 397 | } else if (HorDcm >= 32) { | ||
| 398 | reg |= 2 << ZR36057_VFESPFR_HFilter; /* 4 tap filter */ | ||
| 399 | } else if (HorDcm >= 16) { | ||
| 400 | reg |= 1 << ZR36057_VFESPFR_HFilter; /* 3 tap filter */ | ||
| 401 | } | ||
| 402 | reg |= format->vfespfr; | ||
| 403 | btwrite(reg, ZR36057_VFESPFR); | ||
| 404 | |||
| 405 | /* display configuration */ | ||
| 406 | reg = (16 << ZR36057_VDCR_MinPix) | ||
| 407 | | (VidWinHt << ZR36057_VDCR_VidWinHt) | ||
| 408 | | (VidWinWid << ZR36057_VDCR_VidWinWid); | ||
| 409 | if (pci_pci_problems & PCIPCI_TRITON) | ||
| 410 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
| 411 | reg &= ~ZR36057_VDCR_Triton; | ||
| 412 | else | ||
| 413 | reg |= ZR36057_VDCR_Triton; | ||
| 414 | btwrite(reg, ZR36057_VDCR); | ||
| 415 | |||
| 416 | /* (Ronald) don't write this if overlay_mask = NULL */ | ||
| 417 | if (zr->overlay_mask) { | ||
| 418 | /* Write overlay clipping mask data, but don't enable overlay clipping */ | ||
| 419 | /* RJ: since this makes only sense on the screen, we use | ||
| 420 | * zr->overlay_settings.width instead of video_width */ | ||
| 421 | |||
| 422 | mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
| 423 | reg = virt_to_bus(zr->overlay_mask); | ||
| 424 | btwrite(reg, ZR36057_MMTR); | ||
| 425 | reg = virt_to_bus(zr->overlay_mask + mask_line_size); | ||
| 426 | btwrite(reg, ZR36057_MMBR); | ||
| 427 | reg = | ||
| 428 | mask_line_size - (zr->overlay_settings.width + | ||
| 429 | 31) / 32; | ||
| 430 | if (DispMode == 0) | ||
| 431 | reg += mask_line_size; | ||
| 432 | reg <<= ZR36057_OCR_MaskStride; | ||
| 433 | btwrite(reg, ZR36057_OCR); | ||
| 434 | } | ||
| 435 | |||
| 436 | zr36057_adjust_vfe(zr, zr->codec_mode); | ||
| 437 | } | ||
| 438 | |||
| 439 | /* | ||
| 440 | * Switch overlay on or off | ||
| 441 | */ | ||
| 442 | |||
| 443 | void | ||
| 444 | zr36057_overlay (struct zoran *zr, | ||
| 445 | int on) | ||
| 446 | { | ||
| 447 | u32 reg; | ||
| 448 | |||
| 449 | if (on) { | ||
| 450 | /* do the necessary settings ... */ | ||
| 451 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); /* switch it off first */ | ||
| 452 | |||
| 453 | zr36057_set_vfe(zr, | ||
| 454 | zr->overlay_settings.width, | ||
| 455 | zr->overlay_settings.height, | ||
| 456 | zr->overlay_settings.format); | ||
| 457 | |||
| 458 | /* Start and length of each line MUST be 4-byte aligned. | ||
| 459 | * This should be already checked before the call to this routine. | ||
| 460 | * All error messages are internal driver checking only! */ | ||
| 461 | |||
| 462 | /* video display top and bottom registers */ | ||
| 463 | reg = (long) zr->vbuf_base + | ||
| 464 | zr->overlay_settings.x * | ||
| 465 | ((zr->overlay_settings.format->depth + 7) / 8) + | ||
| 466 | zr->overlay_settings.y * | ||
| 467 | zr->vbuf_bytesperline; | ||
| 468 | btwrite(reg, ZR36057_VDTR); | ||
| 469 | if (reg & 3) | ||
| 470 | dprintk(1, | ||
| 471 | KERN_ERR | ||
| 472 | "%s: zr36057_overlay() - video_address not aligned\n", | ||
| 473 | ZR_DEVNAME(zr)); | ||
| 474 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
| 475 | reg += zr->vbuf_bytesperline; | ||
| 476 | btwrite(reg, ZR36057_VDBR); | ||
| 477 | |||
| 478 | /* video stride, status, and frame grab register */ | ||
| 479 | reg = zr->vbuf_bytesperline - | ||
| 480 | zr->overlay_settings.width * | ||
| 481 | ((zr->overlay_settings.format->depth + 7) / 8); | ||
| 482 | if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2) | ||
| 483 | reg += zr->vbuf_bytesperline; | ||
| 484 | if (reg & 3) | ||
| 485 | dprintk(1, | ||
| 486 | KERN_ERR | ||
| 487 | "%s: zr36057_overlay() - video_stride not aligned\n", | ||
| 488 | ZR_DEVNAME(zr)); | ||
| 489 | reg = reg << ZR36057_VSSFGR_DispStride; | ||
| 490 | reg |= ZR36057_VSSFGR_VidOvf; /* clear overflow status */ | ||
| 491 | btwrite(reg, ZR36057_VSSFGR); | ||
| 492 | |||
| 493 | /* Set overlay clipping */ | ||
| 494 | if (zr->overlay_settings.clipcount > 0) | ||
| 495 | btor(ZR36057_OCR_OvlEnable, ZR36057_OCR); | ||
| 496 | |||
| 497 | /* ... and switch it on */ | ||
| 498 | btor(ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
| 499 | } else { | ||
| 500 | /* Switch it off */ | ||
| 501 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
| 502 | } | ||
| 503 | } | ||
| 504 | |||
| 505 | /* | ||
| 506 | * The overlay mask has one bit for each pixel on a scan line, | ||
| 507 | * and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels. | ||
| 508 | */ | ||
| 509 | |||
| 510 | void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count) | ||
| 511 | { | ||
| 512 | struct zoran *zr = fh->zr; | ||
| 513 | unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32; | ||
| 514 | u32 *mask; | ||
| 515 | int x, y, width, height; | ||
| 516 | unsigned i, j, k; | ||
| 517 | |||
| 518 | /* fill mask with one bits */ | ||
| 519 | memset(fh->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT); | ||
| 520 | |||
| 521 | for (i = 0; i < count; ++i) { | ||
| 522 | /* pick up local copy of clip */ | ||
| 523 | x = vp[i].c.left; | ||
| 524 | y = vp[i].c.top; | ||
| 525 | width = vp[i].c.width; | ||
| 526 | height = vp[i].c.height; | ||
| 527 | |||
| 528 | /* trim clips that extend beyond the window */ | ||
| 529 | if (x < 0) { | ||
| 530 | width += x; | ||
| 531 | x = 0; | ||
| 532 | } | ||
| 533 | if (y < 0) { | ||
| 534 | height += y; | ||
| 535 | y = 0; | ||
| 536 | } | ||
| 537 | if (x + width > fh->overlay_settings.width) { | ||
| 538 | width = fh->overlay_settings.width - x; | ||
| 539 | } | ||
| 540 | if (y + height > fh->overlay_settings.height) { | ||
| 541 | height = fh->overlay_settings.height - y; | ||
| 542 | } | ||
| 543 | |||
| 544 | /* ignore degenerate clips */ | ||
| 545 | if (height <= 0) { | ||
| 546 | continue; | ||
| 547 | } | ||
| 548 | if (width <= 0) { | ||
| 549 | continue; | ||
| 550 | } | ||
| 551 | |||
| 552 | /* apply clip for each scan line */ | ||
| 553 | for (j = 0; j < height; ++j) { | ||
| 554 | /* reset bit for each pixel */ | ||
| 555 | /* this can be optimized later if need be */ | ||
| 556 | mask = fh->overlay_mask + (y + j) * mask_line_size; | ||
| 557 | for (k = 0; k < width; ++k) { | ||
| 558 | mask[(x + k) / 32] &= | ||
| 559 | ~((u32) 1 << (x + k) % 32); | ||
| 560 | } | ||
| 561 | } | ||
| 562 | } | ||
| 563 | } | ||
| 564 | |||
| 565 | /* Enable/Disable uncompressed memory grabbing of the 36057 */ | ||
| 566 | |||
| 567 | void | ||
| 568 | zr36057_set_memgrab (struct zoran *zr, | ||
| 569 | int mode) | ||
| 570 | { | ||
| 571 | if (mode) { | ||
| 572 | /* We only check SnapShot and not FrameGrab here. SnapShot==1 | ||
| 573 | * means a capture is already in progress, but FrameGrab==1 | ||
| 574 | * doesn't necessary mean that. It's more correct to say a 1 | ||
| 575 | * to 0 transition indicates a capture completed. If a | ||
| 576 | * capture is pending when capturing is tuned off, FrameGrab | ||
| 577 | * will be stuck at 1 until capturing is turned back on. | ||
| 578 | */ | ||
| 579 | if (btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) | ||
| 580 | dprintk(1, | ||
| 581 | KERN_WARNING | ||
| 582 | "%s: zr36057_set_memgrab(1) with SnapShot on!?\n", | ||
| 583 | ZR_DEVNAME(zr)); | ||
| 584 | |||
| 585 | /* switch on VSync interrupts */ | ||
| 586 | btwrite(IRQ_MASK, ZR36057_ISR); // Clear Interrupts | ||
| 587 | btor(zr->card.vsync_int, ZR36057_ICR); // SW | ||
| 588 | |||
| 589 | /* enable SnapShot */ | ||
| 590 | btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
| 591 | |||
| 592 | /* Set zr36057 video front end and enable video */ | ||
| 593 | zr36057_set_vfe(zr, zr->v4l_settings.width, | ||
| 594 | zr->v4l_settings.height, | ||
| 595 | zr->v4l_settings.format); | ||
| 596 | |||
| 597 | zr->v4l_memgrab_active = 1; | ||
| 598 | } else { | ||
| 599 | /* switch off VSync interrupts */ | ||
| 600 | btand(~zr->card.vsync_int, ZR36057_ICR); // SW | ||
| 601 | |||
| 602 | zr->v4l_memgrab_active = 0; | ||
| 603 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
| 604 | |||
| 605 | /* re-enable grabbing to screen if it was running */ | ||
| 606 | if (zr->v4l_overlay_active) { | ||
| 607 | zr36057_overlay(zr, 1); | ||
| 608 | } else { | ||
| 609 | btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR); | ||
| 610 | btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | } | ||
| 614 | |||
| 615 | int | ||
| 616 | wait_grab_pending (struct zoran *zr) | ||
| 617 | { | ||
| 618 | unsigned long flags; | ||
| 619 | |||
| 620 | /* wait until all pending grabs are finished */ | ||
| 621 | |||
| 622 | if (!zr->v4l_memgrab_active) | ||
| 623 | return 0; | ||
| 624 | |||
| 625 | wait_event_interruptible(zr->v4l_capq, | ||
| 626 | (zr->v4l_pend_tail == zr->v4l_pend_head)); | ||
| 627 | if (signal_pending(current)) | ||
| 628 | return -ERESTARTSYS; | ||
| 629 | |||
| 630 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 631 | zr36057_set_memgrab(zr, 0); | ||
| 632 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 633 | |||
| 634 | return 0; | ||
| 635 | } | ||
| 636 | |||
| 637 | /***************************************************************************** | ||
| 638 | * * | ||
| 639 | * Set up the Buz-specific MJPEG part * | ||
| 640 | * * | ||
| 641 | *****************************************************************************/ | ||
| 642 | |||
| 643 | static inline void | ||
| 644 | set_frame (struct zoran *zr, | ||
| 645 | int val) | ||
| 646 | { | ||
| 647 | GPIO(zr, zr->card.gpio[ZR_GPIO_JPEG_FRAME], val); | ||
| 648 | } | ||
| 649 | |||
| 650 | static void | ||
| 651 | set_videobus_dir (struct zoran *zr, | ||
| 652 | int val) | ||
| 653 | { | ||
| 654 | switch (zr->card.type) { | ||
| 655 | case LML33: | ||
| 656 | case LML33R10: | ||
| 657 | if (!lml33dpath) | ||
| 658 | GPIO(zr, 5, val); | ||
| 659 | else | ||
| 660 | GPIO(zr, 5, 1); | ||
| 661 | break; | ||
| 662 | default: | ||
| 663 | GPIO(zr, zr->card.gpio[ZR_GPIO_VID_DIR], | ||
| 664 | zr->card.gpio_pol[ZR_GPIO_VID_DIR] ? !val : val); | ||
| 665 | break; | ||
| 666 | } | ||
| 667 | } | ||
| 668 | |||
| 669 | static void | ||
| 670 | init_jpeg_queue (struct zoran *zr) | ||
| 671 | { | ||
| 672 | int i; | ||
| 673 | |||
| 674 | /* re-initialize DMA ring stuff */ | ||
| 675 | zr->jpg_que_head = 0; | ||
| 676 | zr->jpg_dma_head = 0; | ||
| 677 | zr->jpg_dma_tail = 0; | ||
| 678 | zr->jpg_que_tail = 0; | ||
| 679 | zr->jpg_seq_num = 0; | ||
| 680 | zr->JPEG_error = 0; | ||
| 681 | zr->num_errors = 0; | ||
| 682 | zr->jpg_err_seq = 0; | ||
| 683 | zr->jpg_err_shift = 0; | ||
| 684 | zr->jpg_queued_num = 0; | ||
| 685 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | ||
| 686 | zr->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
| 687 | } | ||
| 688 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) { | ||
| 689 | zr->stat_com[i] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ | ||
| 690 | } | ||
| 691 | } | ||
| 692 | |||
| 693 | static void | ||
| 694 | zr36057_set_jpg (struct zoran *zr, | ||
| 695 | enum zoran_codec_mode mode) | ||
| 696 | { | ||
| 697 | struct tvnorm *tvn; | ||
| 698 | u32 reg; | ||
| 699 | |||
| 700 | tvn = zr->timing; | ||
| 701 | |||
| 702 | /* assert P_Reset, disable code transfer, deassert Active */ | ||
| 703 | btwrite(0, ZR36057_JPC); | ||
| 704 | |||
| 705 | /* MJPEG compression mode */ | ||
| 706 | switch (mode) { | ||
| 707 | |||
| 708 | case BUZ_MODE_MOTION_COMPRESS: | ||
| 709 | default: | ||
| 710 | reg = ZR36057_JMC_MJPGCmpMode; | ||
| 711 | break; | ||
| 712 | |||
| 713 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
| 714 | reg = ZR36057_JMC_MJPGExpMode; | ||
| 715 | reg |= ZR36057_JMC_SyncMstr; | ||
| 716 | /* RJ: The following is experimental - improves the output to screen */ | ||
| 717 | //if(zr->jpg_settings.VFIFO_FB) reg |= ZR36057_JMC_VFIFO_FB; // No, it doesn't. SM | ||
| 718 | break; | ||
| 719 | |||
| 720 | case BUZ_MODE_STILL_COMPRESS: | ||
| 721 | reg = ZR36057_JMC_JPGCmpMode; | ||
| 722 | break; | ||
| 723 | |||
| 724 | case BUZ_MODE_STILL_DECOMPRESS: | ||
| 725 | reg = ZR36057_JMC_JPGExpMode; | ||
| 726 | break; | ||
| 727 | |||
| 728 | } | ||
| 729 | reg |= ZR36057_JMC_JPG; | ||
| 730 | if (zr->jpg_settings.field_per_buff == 1) | ||
| 731 | reg |= ZR36057_JMC_Fld_per_buff; | ||
| 732 | btwrite(reg, ZR36057_JMC); | ||
| 733 | |||
| 734 | /* vertical */ | ||
| 735 | btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR); | ||
| 736 | reg = (6 << ZR36057_VSP_VsyncSize) | | ||
| 737 | (tvn->Ht << ZR36057_VSP_FrmTot); | ||
| 738 | btwrite(reg, ZR36057_VSP); | ||
| 739 | reg = ((zr->jpg_settings.img_y + tvn->VStart) << ZR36057_FVAP_NAY) | | ||
| 740 | (zr->jpg_settings.img_height << ZR36057_FVAP_PAY); | ||
| 741 | btwrite(reg, ZR36057_FVAP); | ||
| 742 | |||
| 743 | /* horizontal */ | ||
| 744 | if (zr->card.vfe_pol.hsync_pol) | ||
| 745 | btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
| 746 | else | ||
| 747 | btand(~ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR); | ||
| 748 | reg = ((tvn->HSyncStart) << ZR36057_HSP_HsyncStart) | | ||
| 749 | (tvn->Wt << ZR36057_HSP_LineTot); | ||
| 750 | btwrite(reg, ZR36057_HSP); | ||
| 751 | reg = ((zr->jpg_settings.img_x + | ||
| 752 | tvn->HStart + 4) << ZR36057_FHAP_NAX) | | ||
| 753 | (zr->jpg_settings.img_width << ZR36057_FHAP_PAX); | ||
| 754 | btwrite(reg, ZR36057_FHAP); | ||
| 755 | |||
| 756 | /* field process parameters */ | ||
| 757 | if (zr->jpg_settings.odd_even) | ||
| 758 | reg = ZR36057_FPP_Odd_Even; | ||
| 759 | else | ||
| 760 | reg = 0; | ||
| 761 | |||
| 762 | btwrite(reg, ZR36057_FPP); | ||
| 763 | |||
| 764 | /* Set proper VCLK Polarity, else colors will be wrong during playback */ | ||
| 765 | //btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR); | ||
| 766 | |||
| 767 | /* code base address */ | ||
| 768 | reg = virt_to_bus(zr->stat_com); | ||
| 769 | btwrite(reg, ZR36057_JCBA); | ||
| 770 | |||
| 771 | /* FIFO threshold (FIFO is 160. double words) */ | ||
| 772 | /* NOTE: decimal values here */ | ||
| 773 | switch (mode) { | ||
| 774 | |||
| 775 | case BUZ_MODE_STILL_COMPRESS: | ||
| 776 | case BUZ_MODE_MOTION_COMPRESS: | ||
| 777 | if (zr->card.type != BUZ) | ||
| 778 | reg = 140; | ||
| 779 | else | ||
| 780 | reg = 60; | ||
| 781 | break; | ||
| 782 | |||
| 783 | case BUZ_MODE_STILL_DECOMPRESS: | ||
| 784 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
| 785 | reg = 20; | ||
| 786 | break; | ||
| 787 | |||
| 788 | default: | ||
| 789 | reg = 80; | ||
| 790 | break; | ||
| 791 | |||
| 792 | } | ||
| 793 | btwrite(reg, ZR36057_JCFT); | ||
| 794 | zr36057_adjust_vfe(zr, mode); | ||
| 795 | |||
| 796 | } | ||
| 797 | |||
| 798 | void | ||
| 799 | print_interrupts (struct zoran *zr) | ||
| 800 | { | ||
| 801 | int res, noerr = 0; | ||
| 802 | |||
| 803 | printk(KERN_INFO "%s: interrupts received:", ZR_DEVNAME(zr)); | ||
| 804 | if ((res = zr->field_counter) < -1 || res > 1) { | ||
| 805 | printk(KERN_CONT " FD:%d", res); | ||
| 806 | } | ||
| 807 | if ((res = zr->intr_counter_GIRQ1) != 0) { | ||
| 808 | printk(KERN_CONT " GIRQ1:%d", res); | ||
| 809 | noerr++; | ||
| 810 | } | ||
| 811 | if ((res = zr->intr_counter_GIRQ0) != 0) { | ||
| 812 | printk(KERN_CONT " GIRQ0:%d", res); | ||
| 813 | noerr++; | ||
| 814 | } | ||
| 815 | if ((res = zr->intr_counter_CodRepIRQ) != 0) { | ||
| 816 | printk(KERN_CONT " CodRepIRQ:%d", res); | ||
| 817 | noerr++; | ||
| 818 | } | ||
| 819 | if ((res = zr->intr_counter_JPEGRepIRQ) != 0) { | ||
| 820 | printk(KERN_CONT " JPEGRepIRQ:%d", res); | ||
| 821 | noerr++; | ||
| 822 | } | ||
| 823 | if (zr->JPEG_max_missed) { | ||
| 824 | printk(KERN_CONT " JPEG delays: max=%d min=%d", zr->JPEG_max_missed, | ||
| 825 | zr->JPEG_min_missed); | ||
| 826 | } | ||
| 827 | if (zr->END_event_missed) { | ||
| 828 | printk(KERN_CONT " ENDs missed: %d", zr->END_event_missed); | ||
| 829 | } | ||
| 830 | //if (zr->jpg_queued_num) { | ||
| 831 | printk(KERN_CONT " queue_state=%ld/%ld/%ld/%ld", zr->jpg_que_tail, | ||
| 832 | zr->jpg_dma_tail, zr->jpg_dma_head, zr->jpg_que_head); | ||
| 833 | //} | ||
| 834 | if (!noerr) { | ||
| 835 | printk(KERN_CONT ": no interrupts detected."); | ||
| 836 | } | ||
| 837 | printk(KERN_CONT "\n"); | ||
| 838 | } | ||
| 839 | |||
| 840 | void | ||
| 841 | clear_interrupt_counters (struct zoran *zr) | ||
| 842 | { | ||
| 843 | zr->intr_counter_GIRQ1 = 0; | ||
| 844 | zr->intr_counter_GIRQ0 = 0; | ||
| 845 | zr->intr_counter_CodRepIRQ = 0; | ||
| 846 | zr->intr_counter_JPEGRepIRQ = 0; | ||
| 847 | zr->field_counter = 0; | ||
| 848 | zr->IRQ1_in = 0; | ||
| 849 | zr->IRQ1_out = 0; | ||
| 850 | zr->JPEG_in = 0; | ||
| 851 | zr->JPEG_out = 0; | ||
| 852 | zr->JPEG_0 = 0; | ||
| 853 | zr->JPEG_1 = 0; | ||
| 854 | zr->END_event_missed = 0; | ||
| 855 | zr->JPEG_missed = 0; | ||
| 856 | zr->JPEG_max_missed = 0; | ||
| 857 | zr->JPEG_min_missed = 0x7fffffff; | ||
| 858 | } | ||
| 859 | |||
| 860 | static u32 | ||
| 861 | count_reset_interrupt (struct zoran *zr) | ||
| 862 | { | ||
| 863 | u32 isr; | ||
| 864 | |||
| 865 | if ((isr = btread(ZR36057_ISR) & 0x78000000)) { | ||
| 866 | if (isr & ZR36057_ISR_GIRQ1) { | ||
| 867 | btwrite(ZR36057_ISR_GIRQ1, ZR36057_ISR); | ||
| 868 | zr->intr_counter_GIRQ1++; | ||
| 869 | } | ||
| 870 | if (isr & ZR36057_ISR_GIRQ0) { | ||
| 871 | btwrite(ZR36057_ISR_GIRQ0, ZR36057_ISR); | ||
| 872 | zr->intr_counter_GIRQ0++; | ||
| 873 | } | ||
| 874 | if (isr & ZR36057_ISR_CodRepIRQ) { | ||
| 875 | btwrite(ZR36057_ISR_CodRepIRQ, ZR36057_ISR); | ||
| 876 | zr->intr_counter_CodRepIRQ++; | ||
| 877 | } | ||
| 878 | if (isr & ZR36057_ISR_JPEGRepIRQ) { | ||
| 879 | btwrite(ZR36057_ISR_JPEGRepIRQ, ZR36057_ISR); | ||
| 880 | zr->intr_counter_JPEGRepIRQ++; | ||
| 881 | } | ||
| 882 | } | ||
| 883 | return isr; | ||
| 884 | } | ||
| 885 | |||
| 886 | void | ||
| 887 | jpeg_start (struct zoran *zr) | ||
| 888 | { | ||
| 889 | int reg; | ||
| 890 | |||
| 891 | zr->frame_num = 0; | ||
| 892 | |||
| 893 | /* deassert P_reset, disable code transfer, deassert Active */ | ||
| 894 | btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC); | ||
| 895 | /* stop flushing the internal code buffer */ | ||
| 896 | btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
| 897 | /* enable code transfer */ | ||
| 898 | btor(ZR36057_JPC_CodTrnsEn, ZR36057_JPC); | ||
| 899 | |||
| 900 | /* clear IRQs */ | ||
| 901 | btwrite(IRQ_MASK, ZR36057_ISR); | ||
| 902 | /* enable the JPEG IRQs */ | ||
| 903 | btwrite(zr->card.jpeg_int | | ||
| 904 | ZR36057_ICR_JPEGRepIRQ | | ||
| 905 | ZR36057_ICR_IntPinEn, | ||
| 906 | ZR36057_ICR); | ||
| 907 | |||
| 908 | set_frame(zr, 0); // \FRAME | ||
| 909 | |||
| 910 | /* set the JPEG codec guest ID */ | ||
| 911 | reg = (zr->card.gpcs[1] << ZR36057_JCGI_JPEGuestID) | | ||
| 912 | (0 << ZR36057_JCGI_JPEGuestReg); | ||
| 913 | btwrite(reg, ZR36057_JCGI); | ||
| 914 | |||
| 915 | if (zr->card.video_vfe == CODEC_TYPE_ZR36016 && | ||
| 916 | zr->card.video_codec == CODEC_TYPE_ZR36050) { | ||
| 917 | /* Enable processing on the ZR36016 */ | ||
| 918 | if (zr->vfe) | ||
| 919 | zr36016_write(zr->vfe, 0, 1); | ||
| 920 | |||
| 921 | /* load the address of the GO register in the ZR36050 latch */ | ||
| 922 | post_office_write(zr, 0, 0, 0); | ||
| 923 | } | ||
| 924 | |||
| 925 | /* assert Active */ | ||
| 926 | btor(ZR36057_JPC_Active, ZR36057_JPC); | ||
| 927 | |||
| 928 | /* enable the Go generation */ | ||
| 929 | btor(ZR36057_JMC_Go_en, ZR36057_JMC); | ||
| 930 | udelay(30); | ||
| 931 | |||
| 932 | set_frame(zr, 1); // /FRAME | ||
| 933 | |||
| 934 | dprintk(3, KERN_DEBUG "%s: jpeg_start\n", ZR_DEVNAME(zr)); | ||
| 935 | } | ||
| 936 | |||
| 937 | void | ||
| 938 | zr36057_enable_jpg (struct zoran *zr, | ||
| 939 | enum zoran_codec_mode mode) | ||
| 940 | { | ||
| 941 | struct vfe_settings cap; | ||
| 942 | int field_size = | ||
| 943 | zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff; | ||
| 944 | |||
| 945 | zr->codec_mode = mode; | ||
| 946 | |||
| 947 | cap.x = zr->jpg_settings.img_x; | ||
| 948 | cap.y = zr->jpg_settings.img_y; | ||
| 949 | cap.width = zr->jpg_settings.img_width; | ||
| 950 | cap.height = zr->jpg_settings.img_height; | ||
| 951 | cap.decimation = | ||
| 952 | zr->jpg_settings.HorDcm | (zr->jpg_settings.VerDcm << 8); | ||
| 953 | cap.quality = zr->jpg_settings.jpg_comp.quality; | ||
| 954 | |||
| 955 | switch (mode) { | ||
| 956 | |||
| 957 | case BUZ_MODE_MOTION_COMPRESS: { | ||
| 958 | struct jpeg_app_marker app; | ||
| 959 | struct jpeg_com_marker com; | ||
| 960 | |||
| 961 | /* In motion compress mode, the decoder output must be enabled, and | ||
| 962 | * the video bus direction set to input. | ||
| 963 | */ | ||
| 964 | set_videobus_dir(zr, 0); | ||
| 965 | decoder_call(zr, video, s_stream, 1); | ||
| 966 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
| 967 | |||
| 968 | /* Take the JPEG codec and the VFE out of sleep */ | ||
| 969 | jpeg_codec_sleep(zr, 0); | ||
| 970 | |||
| 971 | /* set JPEG app/com marker */ | ||
| 972 | app.appn = zr->jpg_settings.jpg_comp.APPn; | ||
| 973 | app.len = zr->jpg_settings.jpg_comp.APP_len; | ||
| 974 | memcpy(app.data, zr->jpg_settings.jpg_comp.APP_data, 60); | ||
| 975 | zr->codec->control(zr->codec, CODEC_S_JPEG_APP_DATA, | ||
| 976 | sizeof(struct jpeg_app_marker), &app); | ||
| 977 | |||
| 978 | com.len = zr->jpg_settings.jpg_comp.COM_len; | ||
| 979 | memcpy(com.data, zr->jpg_settings.jpg_comp.COM_data, 60); | ||
| 980 | zr->codec->control(zr->codec, CODEC_S_JPEG_COM_DATA, | ||
| 981 | sizeof(struct jpeg_com_marker), &com); | ||
| 982 | |||
| 983 | /* Setup the JPEG codec */ | ||
| 984 | zr->codec->control(zr->codec, CODEC_S_JPEG_TDS_BYTE, | ||
| 985 | sizeof(int), &field_size); | ||
| 986 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
| 987 | &zr->card.vfe_pol); | ||
| 988 | zr->codec->set_mode(zr->codec, CODEC_DO_COMPRESSION); | ||
| 989 | |||
| 990 | /* Setup the VFE */ | ||
| 991 | if (zr->vfe) { | ||
| 992 | zr->vfe->control(zr->vfe, CODEC_S_JPEG_TDS_BYTE, | ||
| 993 | sizeof(int), &field_size); | ||
| 994 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
| 995 | &zr->card.vfe_pol); | ||
| 996 | zr->vfe->set_mode(zr->vfe, CODEC_DO_COMPRESSION); | ||
| 997 | } | ||
| 998 | |||
| 999 | init_jpeg_queue(zr); | ||
| 1000 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
| 1001 | |||
| 1002 | clear_interrupt_counters(zr); | ||
| 1003 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_COMPRESS)\n", | ||
| 1004 | ZR_DEVNAME(zr)); | ||
| 1005 | break; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | case BUZ_MODE_MOTION_DECOMPRESS: | ||
| 1009 | /* In motion decompression mode, the decoder output must be disabled, and | ||
| 1010 | * the video bus direction set to output. | ||
| 1011 | */ | ||
| 1012 | decoder_call(zr, video, s_stream, 0); | ||
| 1013 | set_videobus_dir(zr, 1); | ||
| 1014 | encoder_call(zr, video, s_routing, 1, 0, 0); | ||
| 1015 | |||
| 1016 | /* Take the JPEG codec and the VFE out of sleep */ | ||
| 1017 | jpeg_codec_sleep(zr, 0); | ||
| 1018 | /* Setup the VFE */ | ||
| 1019 | if (zr->vfe) { | ||
| 1020 | zr->vfe->set_video(zr->vfe, zr->timing, &cap, | ||
| 1021 | &zr->card.vfe_pol); | ||
| 1022 | zr->vfe->set_mode(zr->vfe, CODEC_DO_EXPANSION); | ||
| 1023 | } | ||
| 1024 | /* Setup the JPEG codec */ | ||
| 1025 | zr->codec->set_video(zr->codec, zr->timing, &cap, | ||
| 1026 | &zr->card.vfe_pol); | ||
| 1027 | zr->codec->set_mode(zr->codec, CODEC_DO_EXPANSION); | ||
| 1028 | |||
| 1029 | init_jpeg_queue(zr); | ||
| 1030 | zr36057_set_jpg(zr, mode); // \P_Reset, ... Video param, FIFO | ||
| 1031 | |||
| 1032 | clear_interrupt_counters(zr); | ||
| 1033 | dprintk(2, KERN_INFO "%s: enable_jpg(MOTION_DECOMPRESS)\n", | ||
| 1034 | ZR_DEVNAME(zr)); | ||
| 1035 | break; | ||
| 1036 | |||
| 1037 | case BUZ_MODE_IDLE: | ||
| 1038 | default: | ||
| 1039 | /* shut down processing */ | ||
| 1040 | btand(~(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ), | ||
| 1041 | ZR36057_ICR); | ||
| 1042 | btwrite(zr->card.jpeg_int | ZR36057_ICR_JPEGRepIRQ, | ||
| 1043 | ZR36057_ISR); | ||
| 1044 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); // \Go_en | ||
| 1045 | |||
| 1046 | msleep(50); | ||
| 1047 | |||
| 1048 | set_videobus_dir(zr, 0); | ||
| 1049 | set_frame(zr, 1); // /FRAME | ||
| 1050 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); // /CFlush | ||
| 1051 | btwrite(0, ZR36057_JPC); // \P_Reset,\CodTrnsEn,\Active | ||
| 1052 | btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC); | ||
| 1053 | btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC); | ||
| 1054 | jpeg_codec_reset(zr); | ||
| 1055 | jpeg_codec_sleep(zr, 1); | ||
| 1056 | zr36057_adjust_vfe(zr, mode); | ||
| 1057 | |||
| 1058 | decoder_call(zr, video, s_stream, 1); | ||
| 1059 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
| 1060 | |||
| 1061 | dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr)); | ||
| 1062 | break; | ||
| 1063 | |||
| 1064 | } | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | /* when this is called the spinlock must be held */ | ||
| 1068 | void | ||
| 1069 | zoran_feed_stat_com (struct zoran *zr) | ||
| 1070 | { | ||
| 1071 | /* move frames from pending queue to DMA */ | ||
| 1072 | |||
| 1073 | int frame, i, max_stat_com; | ||
| 1074 | |||
| 1075 | max_stat_com = | ||
| 1076 | (zr->jpg_settings.TmpDcm == | ||
| 1077 | 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1); | ||
| 1078 | |||
| 1079 | while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com && | ||
| 1080 | zr->jpg_dma_head < zr->jpg_que_head) { | ||
| 1081 | |||
| 1082 | frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME]; | ||
| 1083 | if (zr->jpg_settings.TmpDcm == 1) { | ||
| 1084 | /* fill 1 stat_com entry */ | ||
| 1085 | i = (zr->jpg_dma_head - | ||
| 1086 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
| 1087 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
| 1088 | break; | ||
| 1089 | zr->stat_com[i] = | ||
| 1090 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
| 1091 | } else { | ||
| 1092 | /* fill 2 stat_com entries */ | ||
| 1093 | i = ((zr->jpg_dma_head - | ||
| 1094 | zr->jpg_err_shift) & 1) * 2; | ||
| 1095 | if (!(zr->stat_com[i] & cpu_to_le32(1))) | ||
| 1096 | break; | ||
| 1097 | zr->stat_com[i] = | ||
| 1098 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
| 1099 | zr->stat_com[i + 1] = | ||
| 1100 | cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus); | ||
| 1101 | } | ||
| 1102 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA; | ||
| 1103 | zr->jpg_dma_head++; | ||
| 1104 | |||
| 1105 | } | ||
| 1106 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) | ||
| 1107 | zr->jpg_queued_num++; | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | /* when this is called the spinlock must be held */ | ||
| 1111 | static void | ||
| 1112 | zoran_reap_stat_com (struct zoran *zr) | ||
| 1113 | { | ||
| 1114 | /* move frames from DMA queue to done queue */ | ||
| 1115 | |||
| 1116 | int i; | ||
| 1117 | u32 stat_com; | ||
| 1118 | unsigned int seq; | ||
| 1119 | unsigned int dif; | ||
| 1120 | struct zoran_buffer *buffer; | ||
| 1121 | int frame; | ||
| 1122 | |||
| 1123 | /* In motion decompress we don't have a hardware frame counter, | ||
| 1124 | * we just count the interrupts here */ | ||
| 1125 | |||
| 1126 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
| 1127 | zr->jpg_seq_num++; | ||
| 1128 | } | ||
| 1129 | while (zr->jpg_dma_tail < zr->jpg_dma_head) { | ||
| 1130 | if (zr->jpg_settings.TmpDcm == 1) | ||
| 1131 | i = (zr->jpg_dma_tail - | ||
| 1132 | zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
| 1133 | else | ||
| 1134 | i = ((zr->jpg_dma_tail - | ||
| 1135 | zr->jpg_err_shift) & 1) * 2 + 1; | ||
| 1136 | |||
| 1137 | stat_com = le32_to_cpu(zr->stat_com[i]); | ||
| 1138 | |||
| 1139 | if ((stat_com & 1) == 0) { | ||
| 1140 | return; | ||
| 1141 | } | ||
| 1142 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
| 1143 | buffer = &zr->jpg_buffers.buffer[frame]; | ||
| 1144 | buffer->bs.ts = ktime_get_ns(); | ||
| 1145 | |||
| 1146 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
| 1147 | buffer->bs.length = (stat_com & 0x7fffff) >> 1; | ||
| 1148 | |||
| 1149 | /* update sequence number with the help of the counter in stat_com */ | ||
| 1150 | |||
| 1151 | seq = ((stat_com >> 24) + zr->jpg_err_seq) & 0xff; | ||
| 1152 | dif = (seq - zr->jpg_seq_num) & 0xff; | ||
| 1153 | zr->jpg_seq_num += dif; | ||
| 1154 | } else { | ||
| 1155 | buffer->bs.length = 0; | ||
| 1156 | } | ||
| 1157 | buffer->bs.seq = | ||
| 1158 | zr->jpg_settings.TmpDcm == | ||
| 1159 | 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num; | ||
| 1160 | buffer->state = BUZ_STATE_DONE; | ||
| 1161 | |||
| 1162 | zr->jpg_dma_tail++; | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | static void zoran_restart(struct zoran *zr) | ||
| 1167 | { | ||
| 1168 | /* Now the stat_comm buffer is ready for restart */ | ||
| 1169 | unsigned int status = 0; | ||
| 1170 | int mode; | ||
| 1171 | |||
| 1172 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
| 1173 | decoder_call(zr, video, g_input_status, &status); | ||
| 1174 | mode = CODEC_DO_COMPRESSION; | ||
| 1175 | } else { | ||
| 1176 | status = V4L2_IN_ST_NO_SIGNAL; | ||
| 1177 | mode = CODEC_DO_EXPANSION; | ||
| 1178 | } | ||
| 1179 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
| 1180 | !(status & V4L2_IN_ST_NO_SIGNAL)) { | ||
| 1181 | /********** RESTART code *************/ | ||
| 1182 | jpeg_codec_reset(zr); | ||
| 1183 | zr->codec->set_mode(zr->codec, mode); | ||
| 1184 | zr36057_set_jpg(zr, zr->codec_mode); | ||
| 1185 | jpeg_start(zr); | ||
| 1186 | |||
| 1187 | if (zr->num_errors <= 8) | ||
| 1188 | dprintk(2, KERN_INFO "%s: Restart\n", | ||
| 1189 | ZR_DEVNAME(zr)); | ||
| 1190 | |||
| 1191 | zr->JPEG_missed = 0; | ||
| 1192 | zr->JPEG_error = 2; | ||
| 1193 | /********** End RESTART code ***********/ | ||
| 1194 | } | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | static void | ||
| 1198 | error_handler (struct zoran *zr, | ||
| 1199 | u32 astat, | ||
| 1200 | u32 stat) | ||
| 1201 | { | ||
| 1202 | int i; | ||
| 1203 | |||
| 1204 | /* This is JPEG error handling part */ | ||
| 1205 | if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS && | ||
| 1206 | zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) { | ||
| 1207 | return; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | if ((stat & 1) == 0 && | ||
| 1211 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS && | ||
| 1212 | zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) { | ||
| 1213 | /* No free buffers... */ | ||
| 1214 | zoran_reap_stat_com(zr); | ||
| 1215 | zoran_feed_stat_com(zr); | ||
| 1216 | wake_up_interruptible(&zr->jpg_capq); | ||
| 1217 | zr->JPEG_missed = 0; | ||
| 1218 | return; | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | if (zr->JPEG_error == 1) { | ||
| 1222 | zoran_restart(zr); | ||
| 1223 | return; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | /* | ||
| 1227 | * First entry: error just happened during normal operation | ||
| 1228 | * | ||
| 1229 | * In BUZ_MODE_MOTION_COMPRESS: | ||
| 1230 | * | ||
| 1231 | * Possible glitch in TV signal. In this case we should | ||
| 1232 | * stop the codec and wait for good quality signal before | ||
| 1233 | * restarting it to avoid further problems | ||
| 1234 | * | ||
| 1235 | * In BUZ_MODE_MOTION_DECOMPRESS: | ||
| 1236 | * | ||
| 1237 | * Bad JPEG frame: we have to mark it as processed (codec crashed | ||
| 1238 | * and was not able to do it itself), and to remove it from queue. | ||
| 1239 | */ | ||
| 1240 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | ||
| 1241 | udelay(1); | ||
| 1242 | stat = stat | (post_office_read(zr, 7, 0) & 3) << 8; | ||
| 1243 | btwrite(0, ZR36057_JPC); | ||
| 1244 | btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR); | ||
| 1245 | jpeg_codec_reset(zr); | ||
| 1246 | jpeg_codec_sleep(zr, 1); | ||
| 1247 | zr->JPEG_error = 1; | ||
| 1248 | zr->num_errors++; | ||
| 1249 | |||
| 1250 | /* Report error */ | ||
| 1251 | if (zr36067_debug > 1 && zr->num_errors <= 8) { | ||
| 1252 | long frame; | ||
| 1253 | int j; | ||
| 1254 | |||
| 1255 | frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME]; | ||
| 1256 | printk(KERN_ERR | ||
| 1257 | "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ", | ||
| 1258 | ZR_DEVNAME(zr), stat, zr->last_isr, | ||
| 1259 | zr->jpg_que_tail, zr->jpg_dma_tail, | ||
| 1260 | zr->jpg_dma_head, zr->jpg_que_head, | ||
| 1261 | zr->jpg_seq_num, frame); | ||
| 1262 | printk(KERN_INFO "stat_com frames:"); | ||
| 1263 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) { | ||
| 1264 | for (i = 0; i < zr->jpg_buffers.num_buffers; i++) { | ||
| 1265 | if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus) | ||
| 1266 | printk(KERN_CONT "% d->%d", j, i); | ||
| 1267 | } | ||
| 1268 | } | ||
| 1269 | printk(KERN_CONT "\n"); | ||
| 1270 | } | ||
| 1271 | /* Find an entry in stat_com and rotate contents */ | ||
| 1272 | if (zr->jpg_settings.TmpDcm == 1) | ||
| 1273 | i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
| 1274 | else | ||
| 1275 | i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; | ||
| 1276 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) { | ||
| 1277 | /* Mimic zr36067 operation */ | ||
| 1278 | zr->stat_com[i] |= cpu_to_le32(1); | ||
| 1279 | if (zr->jpg_settings.TmpDcm != 1) | ||
| 1280 | zr->stat_com[i + 1] |= cpu_to_le32(1); | ||
| 1281 | /* Refill */ | ||
| 1282 | zoran_reap_stat_com(zr); | ||
| 1283 | zoran_feed_stat_com(zr); | ||
| 1284 | wake_up_interruptible(&zr->jpg_capq); | ||
| 1285 | /* Find an entry in stat_com again after refill */ | ||
| 1286 | if (zr->jpg_settings.TmpDcm == 1) | ||
| 1287 | i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM; | ||
| 1288 | else | ||
| 1289 | i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2; | ||
| 1290 | } | ||
| 1291 | if (i) { | ||
| 1292 | /* Rotate stat_comm entries to make current entry first */ | ||
| 1293 | int j; | ||
| 1294 | __le32 bus_addr[BUZ_NUM_STAT_COM]; | ||
| 1295 | |||
| 1296 | /* Here we are copying the stat_com array, which | ||
| 1297 | * is already in little endian format, so | ||
| 1298 | * no endian conversions here | ||
| 1299 | */ | ||
| 1300 | memcpy(bus_addr, zr->stat_com, sizeof(bus_addr)); | ||
| 1301 | |||
| 1302 | for (j = 0; j < BUZ_NUM_STAT_COM; j++) | ||
| 1303 | zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM]; | ||
| 1304 | |||
| 1305 | zr->jpg_err_shift += i; | ||
| 1306 | zr->jpg_err_shift &= BUZ_MASK_STAT_COM; | ||
| 1307 | } | ||
| 1308 | if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) | ||
| 1309 | zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */ | ||
| 1310 | zoran_restart(zr); | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | irqreturn_t | ||
| 1314 | zoran_irq (int irq, | ||
| 1315 | void *dev_id) | ||
| 1316 | { | ||
| 1317 | u32 stat, astat; | ||
| 1318 | int count; | ||
| 1319 | struct zoran *zr; | ||
| 1320 | unsigned long flags; | ||
| 1321 | |||
| 1322 | zr = dev_id; | ||
| 1323 | count = 0; | ||
| 1324 | |||
| 1325 | if (zr->testing) { | ||
| 1326 | /* Testing interrupts */ | ||
| 1327 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 1328 | while ((stat = count_reset_interrupt(zr))) { | ||
| 1329 | if (count++ > 100) { | ||
| 1330 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
| 1331 | dprintk(1, | ||
| 1332 | KERN_ERR | ||
| 1333 | "%s: IRQ lockup while testing, isr=0x%08x, cleared int mask\n", | ||
| 1334 | ZR_DEVNAME(zr), stat); | ||
| 1335 | wake_up_interruptible(&zr->test_q); | ||
| 1336 | } | ||
| 1337 | } | ||
| 1338 | zr->last_isr = stat; | ||
| 1339 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 1340 | return IRQ_HANDLED; | ||
| 1341 | } | ||
| 1342 | |||
| 1343 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 1344 | while (1) { | ||
| 1345 | /* get/clear interrupt status bits */ | ||
| 1346 | stat = count_reset_interrupt(zr); | ||
| 1347 | astat = stat & IRQ_MASK; | ||
| 1348 | if (!astat) { | ||
| 1349 | break; | ||
| 1350 | } | ||
| 1351 | dprintk(4, | ||
| 1352 | KERN_DEBUG | ||
| 1353 | "zoran_irq: astat: 0x%08x, mask: 0x%08x\n", | ||
| 1354 | astat, btread(ZR36057_ICR)); | ||
| 1355 | if (astat & zr->card.vsync_int) { // SW | ||
| 1356 | |||
| 1357 | if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
| 1358 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) { | ||
| 1359 | /* count missed interrupts */ | ||
| 1360 | zr->JPEG_missed++; | ||
| 1361 | } | ||
| 1362 | //post_office_read(zr,1,0); | ||
| 1363 | /* Interrupts may still happen when | ||
| 1364 | * zr->v4l_memgrab_active is switched off. | ||
| 1365 | * We simply ignore them */ | ||
| 1366 | |||
| 1367 | if (zr->v4l_memgrab_active) { | ||
| 1368 | /* A lot more checks should be here ... */ | ||
| 1369 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0) | ||
| 1370 | dprintk(1, | ||
| 1371 | KERN_WARNING | ||
| 1372 | "%s: BuzIRQ with SnapShot off ???\n", | ||
| 1373 | ZR_DEVNAME(zr)); | ||
| 1374 | |||
| 1375 | if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) { | ||
| 1376 | /* There is a grab on a frame going on, check if it has finished */ | ||
| 1377 | if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) { | ||
| 1378 | /* it is finished, notify the user */ | ||
| 1379 | |||
| 1380 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE; | ||
| 1381 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.seq = zr->v4l_grab_seq; | ||
| 1382 | zr->v4l_buffers.buffer[zr->v4l_grab_frame].bs.ts = ktime_get_ns(); | ||
| 1383 | zr->v4l_grab_frame = NO_GRAB_ACTIVE; | ||
| 1384 | zr->v4l_pend_tail++; | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE) | ||
| 1389 | wake_up_interruptible(&zr->v4l_capq); | ||
| 1390 | |||
| 1391 | /* Check if there is another grab queued */ | ||
| 1392 | |||
| 1393 | if (zr->v4l_grab_frame == NO_GRAB_ACTIVE && | ||
| 1394 | zr->v4l_pend_tail != zr->v4l_pend_head) { | ||
| 1395 | int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME]; | ||
| 1396 | u32 reg; | ||
| 1397 | |||
| 1398 | zr->v4l_grab_frame = frame; | ||
| 1399 | |||
| 1400 | /* Set zr36057 video front end and enable video */ | ||
| 1401 | |||
| 1402 | /* Buffer address */ | ||
| 1403 | |||
| 1404 | reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus; | ||
| 1405 | btwrite(reg, ZR36057_VDTR); | ||
| 1406 | if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) | ||
| 1407 | reg += zr->v4l_settings.bytesperline; | ||
| 1408 | btwrite(reg, ZR36057_VDBR); | ||
| 1409 | |||
| 1410 | /* video stride, status, and frame grab register */ | ||
| 1411 | reg = 0; | ||
| 1412 | if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2) | ||
| 1413 | reg += zr->v4l_settings.bytesperline; | ||
| 1414 | reg = reg << ZR36057_VSSFGR_DispStride; | ||
| 1415 | reg |= ZR36057_VSSFGR_VidOvf; | ||
| 1416 | reg |= ZR36057_VSSFGR_SnapShot; | ||
| 1417 | reg |= ZR36057_VSSFGR_FrameGrab; | ||
| 1418 | btwrite(reg, ZR36057_VSSFGR); | ||
| 1419 | |||
| 1420 | btor(ZR36057_VDCR_VidEn, | ||
| 1421 | ZR36057_VDCR); | ||
| 1422 | } | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | /* even if we don't grab, we do want to increment | ||
| 1426 | * the sequence counter to see lost frames */ | ||
| 1427 | zr->v4l_grab_seq++; | ||
| 1428 | } | ||
| 1429 | #if (IRQ_MASK & ZR36057_ISR_CodRepIRQ) | ||
| 1430 | if (astat & ZR36057_ISR_CodRepIRQ) { | ||
| 1431 | zr->intr_counter_CodRepIRQ++; | ||
| 1432 | IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", | ||
| 1433 | ZR_DEVNAME(zr))); | ||
| 1434 | btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR); | ||
| 1435 | } | ||
| 1436 | #endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */ | ||
| 1437 | |||
| 1438 | #if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) | ||
| 1439 | if ((astat & ZR36057_ISR_JPEGRepIRQ) && | ||
| 1440 | (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS || | ||
| 1441 | zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) { | ||
| 1442 | if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) { | ||
| 1443 | char sv[BUZ_NUM_STAT_COM + 1]; | ||
| 1444 | int i; | ||
| 1445 | |||
| 1446 | printk(KERN_INFO | ||
| 1447 | "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n", | ||
| 1448 | ZR_DEVNAME(zr), stat, | ||
| 1449 | zr->jpg_settings.odd_even, | ||
| 1450 | zr->jpg_settings.field_per_buff, | ||
| 1451 | zr->JPEG_missed); | ||
| 1452 | |||
| 1453 | for (i = 0; i < BUZ_NUM_STAT_COM; i++) | ||
| 1454 | sv[i] = le32_to_cpu(zr->stat_com[i]) & 1 ? '1' : '0'; | ||
| 1455 | sv[BUZ_NUM_STAT_COM] = 0; | ||
| 1456 | printk(KERN_INFO | ||
| 1457 | "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n", | ||
| 1458 | ZR_DEVNAME(zr), sv, | ||
| 1459 | zr->jpg_que_tail, | ||
| 1460 | zr->jpg_dma_tail, | ||
| 1461 | zr->jpg_dma_head, | ||
| 1462 | zr->jpg_que_head); | ||
| 1463 | } else { | ||
| 1464 | /* Get statistics */ | ||
| 1465 | if (zr->JPEG_missed > zr->JPEG_max_missed) | ||
| 1466 | zr->JPEG_max_missed = zr->JPEG_missed; | ||
| 1467 | if (zr->JPEG_missed < zr->JPEG_min_missed) | ||
| 1468 | zr->JPEG_min_missed = zr->JPEG_missed; | ||
| 1469 | } | ||
| 1470 | |||
| 1471 | if (zr36067_debug > 2 && zr->frame_num < 6) { | ||
| 1472 | int i; | ||
| 1473 | |||
| 1474 | printk(KERN_INFO "%s: seq=%ld stat_com:", | ||
| 1475 | ZR_DEVNAME(zr), zr->jpg_seq_num); | ||
| 1476 | for (i = 0; i < 4; i++) { | ||
| 1477 | printk(KERN_CONT " %08x", | ||
| 1478 | le32_to_cpu(zr->stat_com[i])); | ||
| 1479 | } | ||
| 1480 | printk(KERN_CONT "\n"); | ||
| 1481 | } | ||
| 1482 | zr->frame_num++; | ||
| 1483 | zr->JPEG_missed = 0; | ||
| 1484 | zr->JPEG_error = 0; | ||
| 1485 | zoran_reap_stat_com(zr); | ||
| 1486 | zoran_feed_stat_com(zr); | ||
| 1487 | wake_up_interruptible(&zr->jpg_capq); | ||
| 1488 | } | ||
| 1489 | #endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */ | ||
| 1490 | |||
| 1491 | /* DATERR, too many fields missed, error processing */ | ||
| 1492 | if ((astat & zr->card.jpeg_int) || | ||
| 1493 | zr->JPEG_missed > 25 || | ||
| 1494 | zr->JPEG_error == 1 || | ||
| 1495 | ((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) && | ||
| 1496 | (zr->frame_num && (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) { | ||
| 1497 | error_handler(zr, astat, stat); | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | count++; | ||
| 1501 | if (count > 10) { | ||
| 1502 | dprintk(2, KERN_WARNING "%s: irq loop %d\n", | ||
| 1503 | ZR_DEVNAME(zr), count); | ||
| 1504 | if (count > 20) { | ||
| 1505 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
| 1506 | dprintk(2, | ||
| 1507 | KERN_ERR | ||
| 1508 | "%s: IRQ lockup, cleared int mask\n", | ||
| 1509 | ZR_DEVNAME(zr)); | ||
| 1510 | break; | ||
| 1511 | } | ||
| 1512 | } | ||
| 1513 | zr->last_isr = stat; | ||
| 1514 | } | ||
| 1515 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 1516 | |||
| 1517 | return IRQ_HANDLED; | ||
| 1518 | } | ||
| 1519 | |||
| 1520 | void | ||
| 1521 | zoran_set_pci_master (struct zoran *zr, | ||
| 1522 | int set_master) | ||
| 1523 | { | ||
| 1524 | if (set_master) { | ||
| 1525 | pci_set_master(zr->pci_dev); | ||
| 1526 | } else { | ||
| 1527 | u16 command; | ||
| 1528 | |||
| 1529 | pci_read_config_word(zr->pci_dev, PCI_COMMAND, &command); | ||
| 1530 | command &= ~PCI_COMMAND_MASTER; | ||
| 1531 | pci_write_config_word(zr->pci_dev, PCI_COMMAND, command); | ||
| 1532 | } | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | void | ||
| 1536 | zoran_init_hardware (struct zoran *zr) | ||
| 1537 | { | ||
| 1538 | /* Enable bus-mastering */ | ||
| 1539 | zoran_set_pci_master(zr, 1); | ||
| 1540 | |||
| 1541 | /* Initialize the board */ | ||
| 1542 | if (zr->card.init) { | ||
| 1543 | zr->card.init(zr); | ||
| 1544 | } | ||
| 1545 | |||
| 1546 | decoder_call(zr, core, init, 0); | ||
| 1547 | decoder_call(zr, video, s_std, zr->norm); | ||
| 1548 | decoder_call(zr, video, s_routing, | ||
| 1549 | zr->card.input[zr->input].muxsel, 0, 0); | ||
| 1550 | |||
| 1551 | encoder_call(zr, core, init, 0); | ||
| 1552 | encoder_call(zr, video, s_std_output, zr->norm); | ||
| 1553 | encoder_call(zr, video, s_routing, 0, 0, 0); | ||
| 1554 | |||
| 1555 | /* toggle JPEG codec sleep to sync PLL */ | ||
| 1556 | jpeg_codec_sleep(zr, 1); | ||
| 1557 | jpeg_codec_sleep(zr, 0); | ||
| 1558 | |||
| 1559 | /* | ||
| 1560 | * set individual interrupt enables (without GIRQ1) | ||
| 1561 | * but don't global enable until zoran_open() | ||
| 1562 | */ | ||
| 1563 | zr36057_init_vfe(zr); | ||
| 1564 | |||
| 1565 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
| 1566 | |||
| 1567 | btwrite(IRQ_MASK, ZR36057_ISR); // Clears interrupts | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | void | ||
| 1571 | zr36057_restart (struct zoran *zr) | ||
| 1572 | { | ||
| 1573 | btwrite(0, ZR36057_SPGPPCR); | ||
| 1574 | mdelay(1); | ||
| 1575 | btor(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR); | ||
| 1576 | mdelay(1); | ||
| 1577 | |||
| 1578 | /* assert P_Reset */ | ||
| 1579 | btwrite(0, ZR36057_JPC); | ||
| 1580 | /* set up GPIO direction - all output */ | ||
| 1581 | btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR); | ||
| 1582 | |||
| 1583 | /* set up GPIO pins and guest bus timing */ | ||
| 1584 | btwrite((0x81 << 24) | 0x8888, ZR36057_GPPGCR1); | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | /* | ||
| 1588 | * initialize video front end | ||
| 1589 | */ | ||
| 1590 | |||
| 1591 | static void | ||
| 1592 | zr36057_init_vfe (struct zoran *zr) | ||
| 1593 | { | ||
| 1594 | u32 reg; | ||
| 1595 | |||
| 1596 | reg = btread(ZR36057_VFESPFR); | ||
| 1597 | reg |= ZR36057_VFESPFR_LittleEndian; | ||
| 1598 | reg &= ~ZR36057_VFESPFR_VCLKPol; | ||
| 1599 | reg |= ZR36057_VFESPFR_ExtFl; | ||
| 1600 | reg |= ZR36057_VFESPFR_TopField; | ||
| 1601 | btwrite(reg, ZR36057_VFESPFR); | ||
| 1602 | reg = btread(ZR36057_VDCR); | ||
| 1603 | if (pci_pci_problems & PCIPCI_TRITON) | ||
| 1604 | // || zr->revision < 1) // Revision 1 has also Triton support | ||
| 1605 | reg &= ~ZR36057_VDCR_Triton; | ||
| 1606 | else | ||
| 1607 | reg |= ZR36057_VDCR_Triton; | ||
| 1608 | btwrite(reg, ZR36057_VDCR); | ||
| 1609 | } | ||
diff --git a/drivers/staging/media/zoran/zoran_device.h b/drivers/staging/media/zoran/zoran_device.h deleted file mode 100644 index b3b8a03f2004..000000000000 --- a/drivers/staging/media/zoran/zoran_device.h +++ /dev/null | |||
| @@ -1,81 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles card-specific data and detection | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #ifndef __ZORAN_DEVICE_H__ | ||
| 17 | #define __ZORAN_DEVICE_H__ | ||
| 18 | |||
| 19 | /* general purpose I/O */ | ||
| 20 | extern void GPIO(struct zoran *zr, | ||
| 21 | int bit, | ||
| 22 | unsigned int value); | ||
| 23 | |||
| 24 | /* codec (or actually: guest bus) access */ | ||
| 25 | extern int post_office_wait(struct zoran *zr); | ||
| 26 | extern int post_office_write(struct zoran *zr, | ||
| 27 | unsigned int guest, | ||
| 28 | unsigned int reg, | ||
| 29 | unsigned int value); | ||
| 30 | extern int post_office_read(struct zoran *zr, | ||
| 31 | unsigned int guest, | ||
| 32 | unsigned int reg); | ||
| 33 | |||
| 34 | extern void detect_guest_activity(struct zoran *zr); | ||
| 35 | |||
| 36 | extern void jpeg_codec_sleep(struct zoran *zr, | ||
| 37 | int sleep); | ||
| 38 | extern int jpeg_codec_reset(struct zoran *zr); | ||
| 39 | |||
| 40 | /* zr360x7 access to raw capture */ | ||
| 41 | extern void zr36057_overlay(struct zoran *zr, | ||
| 42 | int on); | ||
| 43 | extern void write_overlay_mask(struct zoran_fh *fh, | ||
| 44 | struct v4l2_clip *vp, | ||
| 45 | int count); | ||
| 46 | extern void zr36057_set_memgrab(struct zoran *zr, | ||
| 47 | int mode); | ||
| 48 | extern int wait_grab_pending(struct zoran *zr); | ||
| 49 | |||
| 50 | /* interrupts */ | ||
| 51 | extern void print_interrupts(struct zoran *zr); | ||
| 52 | extern void clear_interrupt_counters(struct zoran *zr); | ||
| 53 | extern irqreturn_t zoran_irq(int irq, void *dev_id); | ||
| 54 | |||
| 55 | /* JPEG codec access */ | ||
| 56 | extern void jpeg_start(struct zoran *zr); | ||
| 57 | extern void zr36057_enable_jpg(struct zoran *zr, | ||
| 58 | enum zoran_codec_mode mode); | ||
| 59 | extern void zoran_feed_stat_com(struct zoran *zr); | ||
| 60 | |||
| 61 | /* general */ | ||
| 62 | extern void zoran_set_pci_master(struct zoran *zr, | ||
| 63 | int set_master); | ||
| 64 | extern void zoran_init_hardware(struct zoran *zr); | ||
| 65 | extern void zr36057_restart(struct zoran *zr); | ||
| 66 | |||
| 67 | extern const struct zoran_format zoran_formats[]; | ||
| 68 | |||
| 69 | extern int v4l_nbufs; | ||
| 70 | extern int v4l_bufsize; | ||
| 71 | extern int jpg_nbufs; | ||
| 72 | extern int jpg_bufsize; | ||
| 73 | extern int pass_through; | ||
| 74 | |||
| 75 | /* i2c */ | ||
| 76 | #define decoder_call(zr, o, f, args...) \ | ||
| 77 | v4l2_subdev_call(zr->decoder, o, f, ##args) | ||
| 78 | #define encoder_call(zr, o, f, args...) \ | ||
| 79 | v4l2_subdev_call(zr->encoder, o, f, ##args) | ||
| 80 | |||
| 81 | #endif /* __ZORAN_DEVICE_H__ */ | ||
diff --git a/drivers/staging/media/zoran/zoran_driver.c b/drivers/staging/media/zoran/zoran_driver.c deleted file mode 100644 index 03bbfb723b43..000000000000 --- a/drivers/staging/media/zoran/zoran_driver.c +++ /dev/null | |||
| @@ -1,2800 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 8 | * | ||
| 9 | * Changes for BUZ by Wolfgang Scherr <scherr@net4you.net> | ||
| 10 | * | ||
| 11 | * Changes for DC10/DC30 by Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 12 | * | ||
| 13 | * Changes for LML33R10 by Maxim Yevtyushkin <max@linuxmedialabs.com> | ||
| 14 | * | ||
| 15 | * Changes for videodev2/v4l2 by Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 16 | * | ||
| 17 | * Based on | ||
| 18 | * | ||
| 19 | * Miro DC10 driver | ||
| 20 | * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net> | ||
| 21 | * | ||
| 22 | * Iomega Buz driver version 1.0 | ||
| 23 | * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> | ||
| 24 | * | ||
| 25 | * buz.0.0.3 | ||
| 26 | * Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
| 27 | * | ||
| 28 | * bttv - Bt848 frame grabber driver | ||
| 29 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | ||
| 30 | * & Marcus Metzler (mocm@thp.uni-koeln.de) | ||
| 31 | */ | ||
| 32 | #include <linux/init.h> | ||
| 33 | #include <linux/module.h> | ||
| 34 | #include <linux/delay.h> | ||
| 35 | #include <linux/slab.h> | ||
| 36 | #include <linux/pci.h> | ||
| 37 | #include <linux/vmalloc.h> | ||
| 38 | #include <linux/wait.h> | ||
| 39 | |||
| 40 | #include <linux/interrupt.h> | ||
| 41 | #include <linux/i2c.h> | ||
| 42 | #include <linux/i2c-algo-bit.h> | ||
| 43 | |||
| 44 | #include <linux/spinlock.h> | ||
| 45 | |||
| 46 | #include <linux/videodev2.h> | ||
| 47 | #include <media/v4l2-common.h> | ||
| 48 | #include <media/v4l2-ioctl.h> | ||
| 49 | #include <media/v4l2-event.h> | ||
| 50 | #include "videocodec.h" | ||
| 51 | |||
| 52 | #include <asm/byteorder.h> | ||
| 53 | #include <asm/io.h> | ||
| 54 | #include <linux/uaccess.h> | ||
| 55 | #include <linux/proc_fs.h> | ||
| 56 | |||
| 57 | #include <linux/mutex.h> | ||
| 58 | #include "zoran.h" | ||
| 59 | #include "zoran_device.h" | ||
| 60 | #include "zoran_card.h" | ||
| 61 | |||
| 62 | |||
| 63 | const struct zoran_format zoran_formats[] = { | ||
| 64 | { | ||
| 65 | .name = "15-bit RGB LE", | ||
| 66 | .fourcc = V4L2_PIX_FMT_RGB555, | ||
| 67 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 68 | .depth = 15, | ||
| 69 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 70 | ZORAN_FORMAT_OVERLAY, | ||
| 71 | .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif| | ||
| 72 | ZR36057_VFESPFR_LittleEndian, | ||
| 73 | }, { | ||
| 74 | .name = "15-bit RGB BE", | ||
| 75 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
| 76 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 77 | .depth = 15, | ||
| 78 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 79 | ZORAN_FORMAT_OVERLAY, | ||
| 80 | .vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif, | ||
| 81 | }, { | ||
| 82 | .name = "16-bit RGB LE", | ||
| 83 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
| 84 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 85 | .depth = 16, | ||
| 86 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 87 | ZORAN_FORMAT_OVERLAY, | ||
| 88 | .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif| | ||
| 89 | ZR36057_VFESPFR_LittleEndian, | ||
| 90 | }, { | ||
| 91 | .name = "16-bit RGB BE", | ||
| 92 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
| 93 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 94 | .depth = 16, | ||
| 95 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 96 | ZORAN_FORMAT_OVERLAY, | ||
| 97 | .vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif, | ||
| 98 | }, { | ||
| 99 | .name = "24-bit RGB", | ||
| 100 | .fourcc = V4L2_PIX_FMT_BGR24, | ||
| 101 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 102 | .depth = 24, | ||
| 103 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 104 | ZORAN_FORMAT_OVERLAY, | ||
| 105 | .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24, | ||
| 106 | }, { | ||
| 107 | .name = "32-bit RGB LE", | ||
| 108 | .fourcc = V4L2_PIX_FMT_BGR32, | ||
| 109 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 110 | .depth = 32, | ||
| 111 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 112 | ZORAN_FORMAT_OVERLAY, | ||
| 113 | .vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian, | ||
| 114 | }, { | ||
| 115 | .name = "32-bit RGB BE", | ||
| 116 | .fourcc = V4L2_PIX_FMT_RGB32, | ||
| 117 | .colorspace = V4L2_COLORSPACE_SRGB, | ||
| 118 | .depth = 32, | ||
| 119 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 120 | ZORAN_FORMAT_OVERLAY, | ||
| 121 | .vfespfr = ZR36057_VFESPFR_RGB888, | ||
| 122 | }, { | ||
| 123 | .name = "4:2:2, packed, YUYV", | ||
| 124 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
| 125 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
| 126 | .depth = 16, | ||
| 127 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 128 | ZORAN_FORMAT_OVERLAY, | ||
| 129 | .vfespfr = ZR36057_VFESPFR_YUV422, | ||
| 130 | }, { | ||
| 131 | .name = "4:2:2, packed, UYVY", | ||
| 132 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
| 133 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
| 134 | .depth = 16, | ||
| 135 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 136 | ZORAN_FORMAT_OVERLAY, | ||
| 137 | .vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian, | ||
| 138 | }, { | ||
| 139 | .name = "Hardware-encoded Motion-JPEG", | ||
| 140 | .fourcc = V4L2_PIX_FMT_MJPEG, | ||
| 141 | .colorspace = V4L2_COLORSPACE_SMPTE170M, | ||
| 142 | .depth = 0, | ||
| 143 | .flags = ZORAN_FORMAT_CAPTURE | | ||
| 144 | ZORAN_FORMAT_PLAYBACK | | ||
| 145 | ZORAN_FORMAT_COMPRESSED, | ||
| 146 | } | ||
| 147 | }; | ||
| 148 | #define NUM_FORMATS ARRAY_SIZE(zoran_formats) | ||
| 149 | |||
| 150 | /* small helper function for calculating buffersizes for v4l2 | ||
| 151 | * we calculate the nearest higher power-of-two, which | ||
| 152 | * will be the recommended buffersize */ | ||
| 153 | static __u32 | ||
| 154 | zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) | ||
| 155 | { | ||
| 156 | __u8 div = settings->VerDcm * settings->HorDcm * settings->TmpDcm; | ||
| 157 | __u32 num = (1024 * 512) / (div); | ||
| 158 | __u32 result = 2; | ||
| 159 | |||
| 160 | num--; | ||
| 161 | while (num) { | ||
| 162 | num >>= 1; | ||
| 163 | result <<= 1; | ||
| 164 | } | ||
| 165 | |||
| 166 | if (result > jpg_bufsize) | ||
| 167 | return jpg_bufsize; | ||
| 168 | if (result < 8192) | ||
| 169 | return 8192; | ||
| 170 | return result; | ||
| 171 | } | ||
| 172 | |||
| 173 | /* forward references */ | ||
| 174 | static void v4l_fbuffer_free(struct zoran_fh *fh); | ||
| 175 | static void jpg_fbuffer_free(struct zoran_fh *fh); | ||
| 176 | |||
| 177 | /* Set mapping mode */ | ||
| 178 | static void map_mode_raw(struct zoran_fh *fh) | ||
| 179 | { | ||
| 180 | fh->map_mode = ZORAN_MAP_MODE_RAW; | ||
| 181 | fh->buffers.buffer_size = v4l_bufsize; | ||
| 182 | fh->buffers.num_buffers = v4l_nbufs; | ||
| 183 | } | ||
| 184 | static void map_mode_jpg(struct zoran_fh *fh, int play) | ||
| 185 | { | ||
| 186 | fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC; | ||
| 187 | fh->buffers.buffer_size = jpg_bufsize; | ||
| 188 | fh->buffers.num_buffers = jpg_nbufs; | ||
| 189 | } | ||
| 190 | static inline const char *mode_name(enum zoran_map_mode mode) | ||
| 191 | { | ||
| 192 | return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG"; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Allocate the V4L grab buffers | ||
| 197 | * | ||
| 198 | * These have to be pysically contiguous. | ||
| 199 | */ | ||
| 200 | |||
| 201 | static int v4l_fbuffer_alloc(struct zoran_fh *fh) | ||
| 202 | { | ||
| 203 | struct zoran *zr = fh->zr; | ||
| 204 | int i, off; | ||
| 205 | unsigned char *mem; | ||
| 206 | |||
| 207 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
| 208 | if (fh->buffers.buffer[i].v4l.fbuffer) | ||
| 209 | dprintk(2, | ||
| 210 | KERN_WARNING | ||
| 211 | "%s: %s - buffer %d already allocated!?\n", | ||
| 212 | ZR_DEVNAME(zr), __func__, i); | ||
| 213 | |||
| 214 | //udelay(20); | ||
| 215 | mem = kmalloc(fh->buffers.buffer_size, | ||
| 216 | GFP_KERNEL | __GFP_NOWARN); | ||
| 217 | if (!mem) { | ||
| 218 | v4l_fbuffer_free(fh); | ||
| 219 | return -ENOBUFS; | ||
| 220 | } | ||
| 221 | fh->buffers.buffer[i].v4l.fbuffer = mem; | ||
| 222 | fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem); | ||
| 223 | fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem); | ||
| 224 | for (off = 0; off < fh->buffers.buffer_size; | ||
| 225 | off += PAGE_SIZE) | ||
| 226 | SetPageReserved(virt_to_page(mem + off)); | ||
| 227 | dprintk(4, | ||
| 228 | KERN_INFO | ||
| 229 | "%s: %s - V4L frame %d mem %p (bus: 0x%llx)\n", | ||
| 230 | ZR_DEVNAME(zr), __func__, i, mem, | ||
| 231 | (unsigned long long)virt_to_bus(mem)); | ||
| 232 | } | ||
| 233 | |||
| 234 | fh->buffers.allocated = 1; | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | /* free the V4L grab buffers */ | ||
| 240 | static void v4l_fbuffer_free(struct zoran_fh *fh) | ||
| 241 | { | ||
| 242 | struct zoran *zr = fh->zr; | ||
| 243 | int i, off; | ||
| 244 | unsigned char *mem; | ||
| 245 | |||
| 246 | dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 247 | |||
| 248 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
| 249 | if (!fh->buffers.buffer[i].v4l.fbuffer) | ||
| 250 | continue; | ||
| 251 | |||
| 252 | mem = fh->buffers.buffer[i].v4l.fbuffer; | ||
| 253 | for (off = 0; off < fh->buffers.buffer_size; | ||
| 254 | off += PAGE_SIZE) | ||
| 255 | ClearPageReserved(virt_to_page(mem + off)); | ||
| 256 | kfree(fh->buffers.buffer[i].v4l.fbuffer); | ||
| 257 | fh->buffers.buffer[i].v4l.fbuffer = NULL; | ||
| 258 | } | ||
| 259 | |||
| 260 | fh->buffers.allocated = 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | /* | ||
| 264 | * Allocate the MJPEG grab buffers. | ||
| 265 | * | ||
| 266 | * If a Natoma chipset is present and this is a revision 1 zr36057, | ||
| 267 | * each MJPEG buffer needs to be physically contiguous. | ||
| 268 | * (RJ: This statement is from Dave Perks' original driver, | ||
| 269 | * I could never check it because I have a zr36067) | ||
| 270 | * | ||
| 271 | * RJ: The contents grab buffers needs never be accessed in the driver. | ||
| 272 | * Therefore there is no need to allocate them with vmalloc in order | ||
| 273 | * to get a contiguous virtual memory space. | ||
| 274 | * I don't understand why many other drivers first allocate them with | ||
| 275 | * vmalloc (which uses internally also get_zeroed_page, but delivers you | ||
| 276 | * virtual addresses) and then again have to make a lot of efforts | ||
| 277 | * to get the physical address. | ||
| 278 | * | ||
| 279 | * Ben Capper: | ||
| 280 | * On big-endian architectures (such as ppc) some extra steps | ||
| 281 | * are needed. When reading and writing to the stat_com array | ||
| 282 | * and fragment buffers, the device expects to see little- | ||
| 283 | * endian values. The use of cpu_to_le32() and le32_to_cpu() | ||
| 284 | * in this function (and one or two others in zoran_device.c) | ||
| 285 | * ensure that these values are always stored in little-endian | ||
| 286 | * form, regardless of architecture. The zr36057 does Very Bad | ||
| 287 | * Things on big endian architectures if the stat_com array | ||
| 288 | * and fragment buffers are not little-endian. | ||
| 289 | */ | ||
| 290 | |||
| 291 | static int jpg_fbuffer_alloc(struct zoran_fh *fh) | ||
| 292 | { | ||
| 293 | struct zoran *zr = fh->zr; | ||
| 294 | int i, j, off; | ||
| 295 | u8 *mem; | ||
| 296 | |||
| 297 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
| 298 | if (fh->buffers.buffer[i].jpg.frag_tab) | ||
| 299 | dprintk(2, | ||
| 300 | KERN_WARNING | ||
| 301 | "%s: %s - buffer %d already allocated!?\n", | ||
| 302 | ZR_DEVNAME(zr), __func__, i); | ||
| 303 | |||
| 304 | /* Allocate fragment table for this buffer */ | ||
| 305 | |||
| 306 | mem = (void *)get_zeroed_page(GFP_KERNEL); | ||
| 307 | if (!mem) { | ||
| 308 | dprintk(1, | ||
| 309 | KERN_ERR | ||
| 310 | "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n", | ||
| 311 | ZR_DEVNAME(zr), __func__, i); | ||
| 312 | jpg_fbuffer_free(fh); | ||
| 313 | return -ENOBUFS; | ||
| 314 | } | ||
| 315 | fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem; | ||
| 316 | fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem); | ||
| 317 | |||
| 318 | if (fh->buffers.need_contiguous) { | ||
| 319 | mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL); | ||
| 320 | if (!mem) { | ||
| 321 | dprintk(1, | ||
| 322 | KERN_ERR | ||
| 323 | "%s: %s - kmalloc failed for buffer %d\n", | ||
| 324 | ZR_DEVNAME(zr), __func__, i); | ||
| 325 | jpg_fbuffer_free(fh); | ||
| 326 | return -ENOBUFS; | ||
| 327 | } | ||
| 328 | fh->buffers.buffer[i].jpg.frag_tab[0] = | ||
| 329 | cpu_to_le32(virt_to_bus(mem)); | ||
| 330 | fh->buffers.buffer[i].jpg.frag_tab[1] = | ||
| 331 | cpu_to_le32((fh->buffers.buffer_size >> 1) | 1); | ||
| 332 | for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) | ||
| 333 | SetPageReserved(virt_to_page(mem + off)); | ||
| 334 | } else { | ||
| 335 | /* jpg_bufsize is already page aligned */ | ||
| 336 | for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { | ||
| 337 | mem = (void *)get_zeroed_page(GFP_KERNEL); | ||
| 338 | if (mem == NULL) { | ||
| 339 | dprintk(1, | ||
| 340 | KERN_ERR | ||
| 341 | "%s: %s - get_zeroed_page failed for buffer %d\n", | ||
| 342 | ZR_DEVNAME(zr), __func__, i); | ||
| 343 | jpg_fbuffer_free(fh); | ||
| 344 | return -ENOBUFS; | ||
| 345 | } | ||
| 346 | |||
| 347 | fh->buffers.buffer[i].jpg.frag_tab[2 * j] = | ||
| 348 | cpu_to_le32(virt_to_bus(mem)); | ||
| 349 | fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] = | ||
| 350 | cpu_to_le32((PAGE_SIZE >> 2) << 1); | ||
| 351 | SetPageReserved(virt_to_page(mem)); | ||
| 352 | } | ||
| 353 | |||
| 354 | fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1); | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 358 | dprintk(4, | ||
| 359 | KERN_DEBUG "%s: %s - %d KB allocated\n", | ||
| 360 | ZR_DEVNAME(zr), __func__, | ||
| 361 | (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10); | ||
| 362 | |||
| 363 | fh->buffers.allocated = 1; | ||
| 364 | |||
| 365 | return 0; | ||
| 366 | } | ||
| 367 | |||
| 368 | /* free the MJPEG grab buffers */ | ||
| 369 | static void jpg_fbuffer_free(struct zoran_fh *fh) | ||
| 370 | { | ||
| 371 | struct zoran *zr = fh->zr; | ||
| 372 | int i, j, off; | ||
| 373 | unsigned char *mem; | ||
| 374 | __le32 frag_tab; | ||
| 375 | struct zoran_buffer *buffer; | ||
| 376 | |||
| 377 | dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__); | ||
| 378 | |||
| 379 | for (i = 0, buffer = &fh->buffers.buffer[0]; | ||
| 380 | i < fh->buffers.num_buffers; i++, buffer++) { | ||
| 381 | if (!buffer->jpg.frag_tab) | ||
| 382 | continue; | ||
| 383 | |||
| 384 | if (fh->buffers.need_contiguous) { | ||
| 385 | frag_tab = buffer->jpg.frag_tab[0]; | ||
| 386 | |||
| 387 | if (frag_tab) { | ||
| 388 | mem = bus_to_virt(le32_to_cpu(frag_tab)); | ||
| 389 | for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE) | ||
| 390 | ClearPageReserved(virt_to_page(mem + off)); | ||
| 391 | kfree(mem); | ||
| 392 | buffer->jpg.frag_tab[0] = 0; | ||
| 393 | buffer->jpg.frag_tab[1] = 0; | ||
| 394 | } | ||
| 395 | } else { | ||
| 396 | for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) { | ||
| 397 | frag_tab = buffer->jpg.frag_tab[2 * j]; | ||
| 398 | |||
| 399 | if (!frag_tab) | ||
| 400 | break; | ||
| 401 | ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab)))); | ||
| 402 | free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab))); | ||
| 403 | buffer->jpg.frag_tab[2 * j] = 0; | ||
| 404 | buffer->jpg.frag_tab[2 * j + 1] = 0; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | free_page((unsigned long)buffer->jpg.frag_tab); | ||
| 409 | buffer->jpg.frag_tab = NULL; | ||
| 410 | } | ||
| 411 | |||
| 412 | fh->buffers.allocated = 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | /* | ||
| 416 | * V4L Buffer grabbing | ||
| 417 | */ | ||
| 418 | |||
| 419 | static int | ||
| 420 | zoran_v4l_set_format (struct zoran_fh *fh, | ||
| 421 | int width, | ||
| 422 | int height, | ||
| 423 | const struct zoran_format *format) | ||
| 424 | { | ||
| 425 | struct zoran *zr = fh->zr; | ||
| 426 | int bpp; | ||
| 427 | |||
| 428 | /* Check size and format of the grab wanted */ | ||
| 429 | |||
| 430 | if (height < BUZ_MIN_HEIGHT || width < BUZ_MIN_WIDTH || | ||
| 431 | height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) { | ||
| 432 | dprintk(1, | ||
| 433 | KERN_ERR | ||
| 434 | "%s: %s - wrong frame size (%dx%d)\n", | ||
| 435 | ZR_DEVNAME(zr), __func__, width, height); | ||
| 436 | return -EINVAL; | ||
| 437 | } | ||
| 438 | |||
| 439 | bpp = (format->depth + 7) / 8; | ||
| 440 | |||
| 441 | /* Check against available buffer size */ | ||
| 442 | if (height * width * bpp > fh->buffers.buffer_size) { | ||
| 443 | dprintk(1, | ||
| 444 | KERN_ERR | ||
| 445 | "%s: %s - video buffer size (%d kB) is too small\n", | ||
| 446 | ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10); | ||
| 447 | return -EINVAL; | ||
| 448 | } | ||
| 449 | |||
| 450 | /* The video front end needs 4-byte alinged line sizes */ | ||
| 451 | |||
| 452 | if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) { | ||
| 453 | dprintk(1, | ||
| 454 | KERN_ERR | ||
| 455 | "%s: %s - wrong frame alignment\n", | ||
| 456 | ZR_DEVNAME(zr), __func__); | ||
| 457 | return -EINVAL; | ||
| 458 | } | ||
| 459 | |||
| 460 | fh->v4l_settings.width = width; | ||
| 461 | fh->v4l_settings.height = height; | ||
| 462 | fh->v4l_settings.format = format; | ||
| 463 | fh->v4l_settings.bytesperline = bpp * fh->v4l_settings.width; | ||
| 464 | |||
| 465 | return 0; | ||
| 466 | } | ||
| 467 | |||
| 468 | static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num) | ||
| 469 | { | ||
| 470 | struct zoran *zr = fh->zr; | ||
| 471 | unsigned long flags; | ||
| 472 | int res = 0; | ||
| 473 | |||
| 474 | if (!fh->buffers.allocated) { | ||
| 475 | dprintk(1, | ||
| 476 | KERN_ERR | ||
| 477 | "%s: %s - buffers not yet allocated\n", | ||
| 478 | ZR_DEVNAME(zr), __func__); | ||
| 479 | res = -ENOMEM; | ||
| 480 | } | ||
| 481 | |||
| 482 | /* No grabbing outside the buffer range! */ | ||
| 483 | if (num >= fh->buffers.num_buffers || num < 0) { | ||
| 484 | dprintk(1, | ||
| 485 | KERN_ERR | ||
| 486 | "%s: %s - buffer %d is out of range\n", | ||
| 487 | ZR_DEVNAME(zr), __func__, num); | ||
| 488 | res = -EINVAL; | ||
| 489 | } | ||
| 490 | |||
| 491 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 492 | |||
| 493 | if (fh->buffers.active == ZORAN_FREE) { | ||
| 494 | if (zr->v4l_buffers.active == ZORAN_FREE) { | ||
| 495 | zr->v4l_buffers = fh->buffers; | ||
| 496 | fh->buffers.active = ZORAN_ACTIVE; | ||
| 497 | } else { | ||
| 498 | dprintk(1, | ||
| 499 | KERN_ERR | ||
| 500 | "%s: %s - another session is already capturing\n", | ||
| 501 | ZR_DEVNAME(zr), __func__); | ||
| 502 | res = -EBUSY; | ||
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 506 | /* make sure a grab isn't going on currently with this buffer */ | ||
| 507 | if (!res) { | ||
| 508 | switch (zr->v4l_buffers.buffer[num].state) { | ||
| 509 | default: | ||
| 510 | case BUZ_STATE_PEND: | ||
| 511 | if (zr->v4l_buffers.active == ZORAN_FREE) { | ||
| 512 | fh->buffers.active = ZORAN_FREE; | ||
| 513 | zr->v4l_buffers.allocated = 0; | ||
| 514 | } | ||
| 515 | res = -EBUSY; /* what are you doing? */ | ||
| 516 | break; | ||
| 517 | case BUZ_STATE_DONE: | ||
| 518 | dprintk(2, | ||
| 519 | KERN_WARNING | ||
| 520 | "%s: %s - queueing buffer %d in state DONE!?\n", | ||
| 521 | ZR_DEVNAME(zr), __func__, num); | ||
| 522 | /* fall through */ | ||
| 523 | case BUZ_STATE_USER: | ||
| 524 | /* since there is at least one unused buffer there's room for at least | ||
| 525 | * one more pend[] entry */ | ||
| 526 | zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num; | ||
| 527 | zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND; | ||
| 528 | zr->v4l_buffers.buffer[num].bs.length = | ||
| 529 | fh->v4l_settings.bytesperline * | ||
| 530 | zr->v4l_settings.height; | ||
| 531 | fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num]; | ||
| 532 | break; | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 537 | |||
| 538 | if (!res && zr->v4l_buffers.active == ZORAN_FREE) | ||
| 539 | zr->v4l_buffers.active = fh->buffers.active; | ||
| 540 | |||
| 541 | return res; | ||
| 542 | } | ||
| 543 | |||
| 544 | /* | ||
| 545 | * Sync on a V4L buffer | ||
| 546 | */ | ||
| 547 | |||
| 548 | static int v4l_sync(struct zoran_fh *fh, int frame) | ||
| 549 | { | ||
| 550 | struct zoran *zr = fh->zr; | ||
| 551 | unsigned long flags; | ||
| 552 | |||
| 553 | if (fh->buffers.active == ZORAN_FREE) { | ||
| 554 | dprintk(1, | ||
| 555 | KERN_ERR | ||
| 556 | "%s: %s - no grab active for this session\n", | ||
| 557 | ZR_DEVNAME(zr), __func__); | ||
| 558 | return -EINVAL; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* check passed-in frame number */ | ||
| 562 | if (frame >= fh->buffers.num_buffers || frame < 0) { | ||
| 563 | dprintk(1, | ||
| 564 | KERN_ERR "%s: %s - frame %d is invalid\n", | ||
| 565 | ZR_DEVNAME(zr), __func__, frame); | ||
| 566 | return -EINVAL; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* Check if is buffer was queued at all */ | ||
| 570 | if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) { | ||
| 571 | dprintk(1, | ||
| 572 | KERN_ERR | ||
| 573 | "%s: %s - attempt to sync on a buffer which was not queued?\n", | ||
| 574 | ZR_DEVNAME(zr), __func__); | ||
| 575 | return -EPROTO; | ||
| 576 | } | ||
| 577 | |||
| 578 | mutex_unlock(&zr->lock); | ||
| 579 | /* wait on this buffer to get ready */ | ||
| 580 | if (!wait_event_interruptible_timeout(zr->v4l_capq, | ||
| 581 | (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ)) { | ||
| 582 | mutex_lock(&zr->lock); | ||
| 583 | return -ETIME; | ||
| 584 | } | ||
| 585 | mutex_lock(&zr->lock); | ||
| 586 | if (signal_pending(current)) | ||
| 587 | return -ERESTARTSYS; | ||
| 588 | |||
| 589 | /* buffer should now be in BUZ_STATE_DONE */ | ||
| 590 | if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE) | ||
| 591 | dprintk(2, | ||
| 592 | KERN_ERR "%s: %s - internal state error\n", | ||
| 593 | ZR_DEVNAME(zr), __func__); | ||
| 594 | |||
| 595 | zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER; | ||
| 596 | fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame]; | ||
| 597 | |||
| 598 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 599 | |||
| 600 | /* Check if streaming capture has finished */ | ||
| 601 | if (zr->v4l_pend_tail == zr->v4l_pend_head) { | ||
| 602 | zr36057_set_memgrab(zr, 0); | ||
| 603 | if (zr->v4l_buffers.active == ZORAN_ACTIVE) { | ||
| 604 | fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE; | ||
| 605 | zr->v4l_buffers.allocated = 0; | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 610 | |||
| 611 | return 0; | ||
| 612 | } | ||
| 613 | |||
| 614 | /* | ||
| 615 | * Queue a MJPEG buffer for capture/playback | ||
| 616 | */ | ||
| 617 | |||
| 618 | static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num, | ||
| 619 | enum zoran_codec_mode mode) | ||
| 620 | { | ||
| 621 | struct zoran *zr = fh->zr; | ||
| 622 | unsigned long flags; | ||
| 623 | int res = 0; | ||
| 624 | |||
| 625 | /* Check if buffers are allocated */ | ||
| 626 | if (!fh->buffers.allocated) { | ||
| 627 | dprintk(1, | ||
| 628 | KERN_ERR | ||
| 629 | "%s: %s - buffers not yet allocated\n", | ||
| 630 | ZR_DEVNAME(zr), __func__); | ||
| 631 | return -ENOMEM; | ||
| 632 | } | ||
| 633 | |||
| 634 | /* No grabbing outside the buffer range! */ | ||
| 635 | if (num >= fh->buffers.num_buffers || num < 0) { | ||
| 636 | dprintk(1, | ||
| 637 | KERN_ERR | ||
| 638 | "%s: %s - buffer %d out of range\n", | ||
| 639 | ZR_DEVNAME(zr), __func__, num); | ||
| 640 | return -EINVAL; | ||
| 641 | } | ||
| 642 | |||
| 643 | /* what is the codec mode right now? */ | ||
| 644 | if (zr->codec_mode == BUZ_MODE_IDLE) { | ||
| 645 | zr->jpg_settings = fh->jpg_settings; | ||
| 646 | } else if (zr->codec_mode != mode) { | ||
| 647 | /* wrong codec mode active - invalid */ | ||
| 648 | dprintk(1, | ||
| 649 | KERN_ERR | ||
| 650 | "%s: %s - codec in wrong mode\n", | ||
| 651 | ZR_DEVNAME(zr), __func__); | ||
| 652 | return -EINVAL; | ||
| 653 | } | ||
| 654 | |||
| 655 | if (fh->buffers.active == ZORAN_FREE) { | ||
| 656 | if (zr->jpg_buffers.active == ZORAN_FREE) { | ||
| 657 | zr->jpg_buffers = fh->buffers; | ||
| 658 | fh->buffers.active = ZORAN_ACTIVE; | ||
| 659 | } else { | ||
| 660 | dprintk(1, | ||
| 661 | KERN_ERR | ||
| 662 | "%s: %s - another session is already capturing\n", | ||
| 663 | ZR_DEVNAME(zr), __func__); | ||
| 664 | res = -EBUSY; | ||
| 665 | } | ||
| 666 | } | ||
| 667 | |||
| 668 | if (!res && zr->codec_mode == BUZ_MODE_IDLE) { | ||
| 669 | /* Ok load up the jpeg codec */ | ||
| 670 | zr36057_enable_jpg(zr, mode); | ||
| 671 | } | ||
| 672 | |||
| 673 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 674 | |||
| 675 | if (!res) { | ||
| 676 | switch (zr->jpg_buffers.buffer[num].state) { | ||
| 677 | case BUZ_STATE_DONE: | ||
| 678 | dprintk(2, | ||
| 679 | KERN_WARNING | ||
| 680 | "%s: %s - queuing frame in BUZ_STATE_DONE state!?\n", | ||
| 681 | ZR_DEVNAME(zr), __func__); | ||
| 682 | /* fall through */ | ||
| 683 | case BUZ_STATE_USER: | ||
| 684 | /* since there is at least one unused buffer there's room for at | ||
| 685 | *least one more pend[] entry */ | ||
| 686 | zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num; | ||
| 687 | zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND; | ||
| 688 | fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num]; | ||
| 689 | zoran_feed_stat_com(zr); | ||
| 690 | break; | ||
| 691 | default: | ||
| 692 | case BUZ_STATE_DMA: | ||
| 693 | case BUZ_STATE_PEND: | ||
| 694 | if (zr->jpg_buffers.active == ZORAN_FREE) { | ||
| 695 | fh->buffers.active = ZORAN_FREE; | ||
| 696 | zr->jpg_buffers.allocated = 0; | ||
| 697 | } | ||
| 698 | res = -EBUSY; /* what are you doing? */ | ||
| 699 | break; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 703 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 704 | |||
| 705 | if (!res && zr->jpg_buffers.active == ZORAN_FREE) | ||
| 706 | zr->jpg_buffers.active = fh->buffers.active; | ||
| 707 | |||
| 708 | return res; | ||
| 709 | } | ||
| 710 | |||
| 711 | static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode) | ||
| 712 | { | ||
| 713 | struct zoran *zr = fh->zr; | ||
| 714 | int res = 0; | ||
| 715 | |||
| 716 | /* Does the user want to stop streaming? */ | ||
| 717 | if (frame < 0) { | ||
| 718 | if (zr->codec_mode == mode) { | ||
| 719 | if (fh->buffers.active == ZORAN_FREE) { | ||
| 720 | dprintk(1, | ||
| 721 | KERN_ERR | ||
| 722 | "%s: %s(-1) - session not active\n", | ||
| 723 | ZR_DEVNAME(zr), __func__); | ||
| 724 | return -EINVAL; | ||
| 725 | } | ||
| 726 | fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE; | ||
| 727 | zr->jpg_buffers.allocated = 0; | ||
| 728 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
| 729 | return 0; | ||
| 730 | } else { | ||
| 731 | dprintk(1, | ||
| 732 | KERN_ERR | ||
| 733 | "%s: %s - stop streaming but not in streaming mode\n", | ||
| 734 | ZR_DEVNAME(zr), __func__); | ||
| 735 | return -EINVAL; | ||
| 736 | } | ||
| 737 | } | ||
| 738 | |||
| 739 | if ((res = zoran_jpg_queue_frame(fh, frame, mode))) | ||
| 740 | return res; | ||
| 741 | |||
| 742 | /* Start the jpeg codec when the first frame is queued */ | ||
| 743 | if (!res && zr->jpg_que_head == 1) | ||
| 744 | jpeg_start(zr); | ||
| 745 | |||
| 746 | return res; | ||
| 747 | } | ||
| 748 | |||
| 749 | /* | ||
| 750 | * Sync on a MJPEG buffer | ||
| 751 | */ | ||
| 752 | |||
| 753 | static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs) | ||
| 754 | { | ||
| 755 | struct zoran *zr = fh->zr; | ||
| 756 | unsigned long flags; | ||
| 757 | int frame; | ||
| 758 | |||
| 759 | if (fh->buffers.active == ZORAN_FREE) { | ||
| 760 | dprintk(1, | ||
| 761 | KERN_ERR | ||
| 762 | "%s: %s - capture is not currently active\n", | ||
| 763 | ZR_DEVNAME(zr), __func__); | ||
| 764 | return -EINVAL; | ||
| 765 | } | ||
| 766 | if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS && | ||
| 767 | zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) { | ||
| 768 | dprintk(1, | ||
| 769 | KERN_ERR | ||
| 770 | "%s: %s - codec not in streaming mode\n", | ||
| 771 | ZR_DEVNAME(zr), __func__); | ||
| 772 | return -EINVAL; | ||
| 773 | } | ||
| 774 | mutex_unlock(&zr->lock); | ||
| 775 | if (!wait_event_interruptible_timeout(zr->jpg_capq, | ||
| 776 | (zr->jpg_que_tail != zr->jpg_dma_tail || | ||
| 777 | zr->jpg_dma_tail == zr->jpg_dma_head), | ||
| 778 | 10*HZ)) { | ||
| 779 | int isr; | ||
| 780 | |||
| 781 | btand(~ZR36057_JMC_Go_en, ZR36057_JMC); | ||
| 782 | udelay(1); | ||
| 783 | zr->codec->control(zr->codec, CODEC_G_STATUS, | ||
| 784 | sizeof(isr), &isr); | ||
| 785 | mutex_lock(&zr->lock); | ||
| 786 | dprintk(1, | ||
| 787 | KERN_ERR | ||
| 788 | "%s: %s - timeout: codec isr=0x%02x\n", | ||
| 789 | ZR_DEVNAME(zr), __func__, isr); | ||
| 790 | |||
| 791 | return -ETIME; | ||
| 792 | |||
| 793 | } | ||
| 794 | mutex_lock(&zr->lock); | ||
| 795 | if (signal_pending(current)) | ||
| 796 | return -ERESTARTSYS; | ||
| 797 | |||
| 798 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 799 | |||
| 800 | if (zr->jpg_dma_tail != zr->jpg_dma_head) | ||
| 801 | frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME]; | ||
| 802 | else | ||
| 803 | frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
| 804 | |||
| 805 | /* buffer should now be in BUZ_STATE_DONE */ | ||
| 806 | if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE) | ||
| 807 | dprintk(2, | ||
| 808 | KERN_ERR "%s: %s - internal state error\n", | ||
| 809 | ZR_DEVNAME(zr), __func__); | ||
| 810 | |||
| 811 | *bs = zr->jpg_buffers.buffer[frame].bs; | ||
| 812 | bs->frame = frame; | ||
| 813 | zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER; | ||
| 814 | fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame]; | ||
| 815 | |||
| 816 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 817 | |||
| 818 | return 0; | ||
| 819 | } | ||
| 820 | |||
| 821 | static void zoran_open_init_session(struct zoran_fh *fh) | ||
| 822 | { | ||
| 823 | int i; | ||
| 824 | struct zoran *zr = fh->zr; | ||
| 825 | |||
| 826 | /* Per default, map the V4L Buffers */ | ||
| 827 | map_mode_raw(fh); | ||
| 828 | |||
| 829 | /* take over the card's current settings */ | ||
| 830 | fh->overlay_settings = zr->overlay_settings; | ||
| 831 | fh->overlay_settings.is_set = 0; | ||
| 832 | fh->overlay_settings.format = zr->overlay_settings.format; | ||
| 833 | fh->overlay_active = ZORAN_FREE; | ||
| 834 | |||
| 835 | /* v4l settings */ | ||
| 836 | fh->v4l_settings = zr->v4l_settings; | ||
| 837 | /* jpg settings */ | ||
| 838 | fh->jpg_settings = zr->jpg_settings; | ||
| 839 | |||
| 840 | /* buffers */ | ||
| 841 | memset(&fh->buffers, 0, sizeof(fh->buffers)); | ||
| 842 | for (i = 0; i < MAX_FRAME; i++) { | ||
| 843 | fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */ | ||
| 844 | fh->buffers.buffer[i].bs.frame = i; | ||
| 845 | } | ||
| 846 | fh->buffers.allocated = 0; | ||
| 847 | fh->buffers.active = ZORAN_FREE; | ||
| 848 | } | ||
| 849 | |||
| 850 | static void zoran_close_end_session(struct zoran_fh *fh) | ||
| 851 | { | ||
| 852 | struct zoran *zr = fh->zr; | ||
| 853 | |||
| 854 | /* overlay */ | ||
| 855 | if (fh->overlay_active != ZORAN_FREE) { | ||
| 856 | fh->overlay_active = zr->overlay_active = ZORAN_FREE; | ||
| 857 | zr->v4l_overlay_active = 0; | ||
| 858 | if (!zr->v4l_memgrab_active) | ||
| 859 | zr36057_overlay(zr, 0); | ||
| 860 | zr->overlay_mask = NULL; | ||
| 861 | } | ||
| 862 | |||
| 863 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
| 864 | /* v4l capture */ | ||
| 865 | if (fh->buffers.active != ZORAN_FREE) { | ||
| 866 | unsigned long flags; | ||
| 867 | |||
| 868 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 869 | zr36057_set_memgrab(zr, 0); | ||
| 870 | zr->v4l_buffers.allocated = 0; | ||
| 871 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
| 872 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 873 | } | ||
| 874 | |||
| 875 | /* v4l buffers */ | ||
| 876 | if (fh->buffers.allocated) | ||
| 877 | v4l_fbuffer_free(fh); | ||
| 878 | } else { | ||
| 879 | /* jpg capture */ | ||
| 880 | if (fh->buffers.active != ZORAN_FREE) { | ||
| 881 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
| 882 | zr->jpg_buffers.allocated = 0; | ||
| 883 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
| 884 | } | ||
| 885 | |||
| 886 | /* jpg buffers */ | ||
| 887 | if (fh->buffers.allocated) | ||
| 888 | jpg_fbuffer_free(fh); | ||
| 889 | } | ||
| 890 | } | ||
| 891 | |||
| 892 | /* | ||
| 893 | * Open a zoran card. Right now the flags stuff is just playing | ||
| 894 | */ | ||
| 895 | |||
| 896 | static int zoran_open(struct file *file) | ||
| 897 | { | ||
| 898 | struct zoran *zr = video_drvdata(file); | ||
| 899 | struct zoran_fh *fh; | ||
| 900 | int res, first_open = 0; | ||
| 901 | |||
| 902 | dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", | ||
| 903 | ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); | ||
| 904 | |||
| 905 | mutex_lock(&zr->lock); | ||
| 906 | |||
| 907 | if (zr->user >= 2048) { | ||
| 908 | dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", | ||
| 909 | ZR_DEVNAME(zr), zr->user); | ||
| 910 | res = -EBUSY; | ||
| 911 | goto fail_unlock; | ||
| 912 | } | ||
| 913 | |||
| 914 | /* now, create the open()-specific file_ops struct */ | ||
| 915 | fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); | ||
| 916 | if (!fh) { | ||
| 917 | dprintk(1, | ||
| 918 | KERN_ERR | ||
| 919 | "%s: %s - allocation of zoran_fh failed\n", | ||
| 920 | ZR_DEVNAME(zr), __func__); | ||
| 921 | res = -ENOMEM; | ||
| 922 | goto fail_unlock; | ||
| 923 | } | ||
| 924 | v4l2_fh_init(&fh->fh, video_devdata(file)); | ||
| 925 | |||
| 926 | /* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows | ||
| 927 | * on norm-change! */ | ||
| 928 | fh->overlay_mask = | ||
| 929 | kmalloc(array3_size((768 + 31) / 32, 576, 4), GFP_KERNEL); | ||
| 930 | if (!fh->overlay_mask) { | ||
| 931 | dprintk(1, | ||
| 932 | KERN_ERR | ||
| 933 | "%s: %s - allocation of overlay_mask failed\n", | ||
| 934 | ZR_DEVNAME(zr), __func__); | ||
| 935 | res = -ENOMEM; | ||
| 936 | goto fail_fh; | ||
| 937 | } | ||
| 938 | |||
| 939 | if (zr->user++ == 0) | ||
| 940 | first_open = 1; | ||
| 941 | |||
| 942 | /* default setup - TODO: look at flags */ | ||
| 943 | if (first_open) { /* First device open */ | ||
| 944 | zr36057_restart(zr); | ||
| 945 | zoran_open_init_params(zr); | ||
| 946 | zoran_init_hardware(zr); | ||
| 947 | |||
| 948 | btor(ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
| 949 | } | ||
| 950 | |||
| 951 | /* set file_ops stuff */ | ||
| 952 | file->private_data = fh; | ||
| 953 | fh->zr = zr; | ||
| 954 | zoran_open_init_session(fh); | ||
| 955 | v4l2_fh_add(&fh->fh); | ||
| 956 | mutex_unlock(&zr->lock); | ||
| 957 | |||
| 958 | return 0; | ||
| 959 | |||
| 960 | fail_fh: | ||
| 961 | v4l2_fh_exit(&fh->fh); | ||
| 962 | kfree(fh); | ||
| 963 | fail_unlock: | ||
| 964 | mutex_unlock(&zr->lock); | ||
| 965 | |||
| 966 | dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", | ||
| 967 | ZR_DEVNAME(zr), res, zr->user); | ||
| 968 | |||
| 969 | return res; | ||
| 970 | } | ||
| 971 | |||
| 972 | static int | ||
| 973 | zoran_close(struct file *file) | ||
| 974 | { | ||
| 975 | struct zoran_fh *fh = file->private_data; | ||
| 976 | struct zoran *zr = fh->zr; | ||
| 977 | |||
| 978 | dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n", | ||
| 979 | ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1); | ||
| 980 | |||
| 981 | /* kernel locks (fs/device.c), so don't do that ourselves | ||
| 982 | * (prevents deadlocks) */ | ||
| 983 | mutex_lock(&zr->lock); | ||
| 984 | |||
| 985 | zoran_close_end_session(fh); | ||
| 986 | |||
| 987 | if (zr->user-- == 1) { /* Last process */ | ||
| 988 | /* Clean up JPEG process */ | ||
| 989 | wake_up_interruptible(&zr->jpg_capq); | ||
| 990 | zr36057_enable_jpg(zr, BUZ_MODE_IDLE); | ||
| 991 | zr->jpg_buffers.allocated = 0; | ||
| 992 | zr->jpg_buffers.active = ZORAN_FREE; | ||
| 993 | |||
| 994 | /* disable interrupts */ | ||
| 995 | btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR); | ||
| 996 | |||
| 997 | if (zr36067_debug > 1) | ||
| 998 | print_interrupts(zr); | ||
| 999 | |||
| 1000 | /* Overlay off */ | ||
| 1001 | zr->v4l_overlay_active = 0; | ||
| 1002 | zr36057_overlay(zr, 0); | ||
| 1003 | zr->overlay_mask = NULL; | ||
| 1004 | |||
| 1005 | /* capture off */ | ||
| 1006 | wake_up_interruptible(&zr->v4l_capq); | ||
| 1007 | zr36057_set_memgrab(zr, 0); | ||
| 1008 | zr->v4l_buffers.allocated = 0; | ||
| 1009 | zr->v4l_buffers.active = ZORAN_FREE; | ||
| 1010 | zoran_set_pci_master(zr, 0); | ||
| 1011 | |||
| 1012 | if (!pass_through) { /* Switch to color bar */ | ||
| 1013 | decoder_call(zr, video, s_stream, 0); | ||
| 1014 | encoder_call(zr, video, s_routing, 2, 0, 0); | ||
| 1015 | } | ||
| 1016 | } | ||
| 1017 | mutex_unlock(&zr->lock); | ||
| 1018 | |||
| 1019 | v4l2_fh_del(&fh->fh); | ||
| 1020 | v4l2_fh_exit(&fh->fh); | ||
| 1021 | kfree(fh->overlay_mask); | ||
| 1022 | kfree(fh); | ||
| 1023 | |||
| 1024 | dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__); | ||
| 1025 | |||
| 1026 | return 0; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | static int setup_fbuffer(struct zoran_fh *fh, | ||
| 1030 | void *base, | ||
| 1031 | const struct zoran_format *fmt, | ||
| 1032 | int width, | ||
| 1033 | int height, | ||
| 1034 | int bytesperline) | ||
| 1035 | { | ||
| 1036 | struct zoran *zr = fh->zr; | ||
| 1037 | |||
| 1038 | /* (Ronald) v4l/v4l2 guidelines */ | ||
| 1039 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) | ||
| 1040 | return -EPERM; | ||
| 1041 | |||
| 1042 | /* Don't allow frame buffer overlay if PCI or AGP is buggy, or on | ||
| 1043 | ALi Magik (that needs very low latency while the card needs a | ||
| 1044 | higher value always) */ | ||
| 1045 | |||
| 1046 | if (pci_pci_problems & (PCIPCI_FAIL | PCIAGP_FAIL | PCIPCI_ALIMAGIK)) | ||
| 1047 | return -ENXIO; | ||
| 1048 | |||
| 1049 | /* we need a bytesperline value, even if not given */ | ||
| 1050 | if (!bytesperline) | ||
| 1051 | bytesperline = width * ((fmt->depth + 7) & ~7) / 8; | ||
| 1052 | |||
| 1053 | #if 0 | ||
| 1054 | if (zr->overlay_active) { | ||
| 1055 | /* dzjee... stupid users... don't even bother to turn off | ||
| 1056 | * overlay before changing the memory location... | ||
| 1057 | * normally, we would return errors here. However, one of | ||
| 1058 | * the tools that does this is... xawtv! and since xawtv | ||
| 1059 | * is used by +/- 99% of the users, we'd rather be user- | ||
| 1060 | * friendly and silently do as if nothing went wrong */ | ||
| 1061 | dprintk(3, | ||
| 1062 | KERN_ERR | ||
| 1063 | "%s: %s - forced overlay turnoff because framebuffer changed\n", | ||
| 1064 | ZR_DEVNAME(zr), __func__); | ||
| 1065 | zr36057_overlay(zr, 0); | ||
| 1066 | } | ||
| 1067 | #endif | ||
| 1068 | |||
| 1069 | if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) { | ||
| 1070 | dprintk(1, | ||
| 1071 | KERN_ERR | ||
| 1072 | "%s: %s - no valid overlay format given\n", | ||
| 1073 | ZR_DEVNAME(zr), __func__); | ||
| 1074 | return -EINVAL; | ||
| 1075 | } | ||
| 1076 | if (height <= 0 || width <= 0 || bytesperline <= 0) { | ||
| 1077 | dprintk(1, | ||
| 1078 | KERN_ERR | ||
| 1079 | "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n", | ||
| 1080 | ZR_DEVNAME(zr), __func__, width, height, bytesperline); | ||
| 1081 | return -EINVAL; | ||
| 1082 | } | ||
| 1083 | if (bytesperline & 3) { | ||
| 1084 | dprintk(1, | ||
| 1085 | KERN_ERR | ||
| 1086 | "%s: %s - bytesperline (%d) must be 4-byte aligned\n", | ||
| 1087 | ZR_DEVNAME(zr), __func__, bytesperline); | ||
| 1088 | return -EINVAL; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | zr->vbuf_base = (void *) ((unsigned long) base & ~3); | ||
| 1092 | zr->vbuf_height = height; | ||
| 1093 | zr->vbuf_width = width; | ||
| 1094 | zr->vbuf_depth = fmt->depth; | ||
| 1095 | zr->overlay_settings.format = fmt; | ||
| 1096 | zr->vbuf_bytesperline = bytesperline; | ||
| 1097 | |||
| 1098 | /* The user should set new window parameters */ | ||
| 1099 | zr->overlay_settings.is_set = 0; | ||
| 1100 | |||
| 1101 | return 0; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | |||
| 1105 | static int setup_window(struct zoran_fh *fh, | ||
| 1106 | int x, | ||
| 1107 | int y, | ||
| 1108 | int width, | ||
| 1109 | int height, | ||
| 1110 | struct v4l2_clip __user *clips, | ||
| 1111 | unsigned int clipcount, | ||
| 1112 | void __user *bitmap) | ||
| 1113 | { | ||
| 1114 | struct zoran *zr = fh->zr; | ||
| 1115 | struct v4l2_clip *vcp = NULL; | ||
| 1116 | int on, end; | ||
| 1117 | |||
| 1118 | |||
| 1119 | if (!zr->vbuf_base) { | ||
| 1120 | dprintk(1, | ||
| 1121 | KERN_ERR | ||
| 1122 | "%s: %s - frame buffer has to be set first\n", | ||
| 1123 | ZR_DEVNAME(zr), __func__); | ||
| 1124 | return -EINVAL; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | if (!fh->overlay_settings.format) { | ||
| 1128 | dprintk(1, | ||
| 1129 | KERN_ERR | ||
| 1130 | "%s: %s - no overlay format set\n", | ||
| 1131 | ZR_DEVNAME(zr), __func__); | ||
| 1132 | return -EINVAL; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | if (clipcount > 2048) { | ||
| 1136 | dprintk(1, | ||
| 1137 | KERN_ERR | ||
| 1138 | "%s: %s - invalid clipcount\n", | ||
| 1139 | ZR_DEVNAME(zr), __func__); | ||
| 1140 | return -EINVAL; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | /* | ||
| 1144 | * The video front end needs 4-byte alinged line sizes, we correct that | ||
| 1145 | * silently here if necessary | ||
| 1146 | */ | ||
| 1147 | if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) { | ||
| 1148 | end = (x + width) & ~1; /* round down */ | ||
| 1149 | x = (x + 1) & ~1; /* round up */ | ||
| 1150 | width = end - x; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | if (zr->vbuf_depth == 24) { | ||
| 1154 | end = (x + width) & ~3; /* round down */ | ||
| 1155 | x = (x + 3) & ~3; /* round up */ | ||
| 1156 | width = end - x; | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | if (width > BUZ_MAX_WIDTH) | ||
| 1160 | width = BUZ_MAX_WIDTH; | ||
| 1161 | if (height > BUZ_MAX_HEIGHT) | ||
| 1162 | height = BUZ_MAX_HEIGHT; | ||
| 1163 | |||
| 1164 | /* Check for invalid parameters */ | ||
| 1165 | if (width < BUZ_MIN_WIDTH || height < BUZ_MIN_HEIGHT || | ||
| 1166 | width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) { | ||
| 1167 | dprintk(1, | ||
| 1168 | KERN_ERR | ||
| 1169 | "%s: %s - width = %d or height = %d invalid\n", | ||
| 1170 | ZR_DEVNAME(zr), __func__, width, height); | ||
| 1171 | return -EINVAL; | ||
| 1172 | } | ||
| 1173 | |||
| 1174 | fh->overlay_settings.x = x; | ||
| 1175 | fh->overlay_settings.y = y; | ||
| 1176 | fh->overlay_settings.width = width; | ||
| 1177 | fh->overlay_settings.height = height; | ||
| 1178 | fh->overlay_settings.clipcount = clipcount; | ||
| 1179 | |||
| 1180 | /* | ||
| 1181 | * If an overlay is running, we have to switch it off | ||
| 1182 | * and switch it on again in order to get the new settings in effect. | ||
| 1183 | * | ||
| 1184 | * We also want to avoid that the overlay mask is written | ||
| 1185 | * when an overlay is running. | ||
| 1186 | */ | ||
| 1187 | |||
| 1188 | on = zr->v4l_overlay_active && !zr->v4l_memgrab_active && | ||
| 1189 | zr->overlay_active != ZORAN_FREE && | ||
| 1190 | fh->overlay_active != ZORAN_FREE; | ||
| 1191 | if (on) | ||
| 1192 | zr36057_overlay(zr, 0); | ||
| 1193 | |||
| 1194 | /* | ||
| 1195 | * Write the overlay mask if clips are wanted. | ||
| 1196 | * We prefer a bitmap. | ||
| 1197 | */ | ||
| 1198 | if (bitmap) { | ||
| 1199 | /* fake value - it just means we want clips */ | ||
| 1200 | fh->overlay_settings.clipcount = 1; | ||
| 1201 | |||
| 1202 | if (copy_from_user(fh->overlay_mask, bitmap, | ||
| 1203 | (width * height + 7) / 8)) { | ||
| 1204 | return -EFAULT; | ||
| 1205 | } | ||
| 1206 | } else if (clipcount) { | ||
| 1207 | /* write our own bitmap from the clips */ | ||
| 1208 | vcp = vmalloc(array_size(sizeof(struct v4l2_clip), | ||
| 1209 | clipcount + 4)); | ||
| 1210 | if (vcp == NULL) { | ||
| 1211 | dprintk(1, | ||
| 1212 | KERN_ERR | ||
| 1213 | "%s: %s - Alloc of clip mask failed\n", | ||
| 1214 | ZR_DEVNAME(zr), __func__); | ||
| 1215 | return -ENOMEM; | ||
| 1216 | } | ||
| 1217 | if (copy_from_user | ||
| 1218 | (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) { | ||
| 1219 | vfree(vcp); | ||
| 1220 | return -EFAULT; | ||
| 1221 | } | ||
| 1222 | write_overlay_mask(fh, vcp, clipcount); | ||
| 1223 | vfree(vcp); | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | fh->overlay_settings.is_set = 1; | ||
| 1227 | if (fh->overlay_active != ZORAN_FREE && | ||
| 1228 | zr->overlay_active != ZORAN_FREE) | ||
| 1229 | zr->overlay_settings = fh->overlay_settings; | ||
| 1230 | |||
| 1231 | if (on) | ||
| 1232 | zr36057_overlay(zr, 1); | ||
| 1233 | |||
| 1234 | /* Make sure the changes come into effect */ | ||
| 1235 | return wait_grab_pending(zr); | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | static int setup_overlay(struct zoran_fh *fh, int on) | ||
| 1239 | { | ||
| 1240 | struct zoran *zr = fh->zr; | ||
| 1241 | |||
| 1242 | /* If there is nothing to do, return immediately */ | ||
| 1243 | if ((on && fh->overlay_active != ZORAN_FREE) || | ||
| 1244 | (!on && fh->overlay_active == ZORAN_FREE)) | ||
| 1245 | return 0; | ||
| 1246 | |||
| 1247 | /* check whether we're touching someone else's overlay */ | ||
| 1248 | if (on && zr->overlay_active != ZORAN_FREE && | ||
| 1249 | fh->overlay_active == ZORAN_FREE) { | ||
| 1250 | dprintk(1, | ||
| 1251 | KERN_ERR | ||
| 1252 | "%s: %s - overlay is already active for another session\n", | ||
| 1253 | ZR_DEVNAME(zr), __func__); | ||
| 1254 | return -EBUSY; | ||
| 1255 | } | ||
| 1256 | if (!on && zr->overlay_active != ZORAN_FREE && | ||
| 1257 | fh->overlay_active == ZORAN_FREE) { | ||
| 1258 | dprintk(1, | ||
| 1259 | KERN_ERR | ||
| 1260 | "%s: %s - you cannot cancel someone else's session\n", | ||
| 1261 | ZR_DEVNAME(zr), __func__); | ||
| 1262 | return -EPERM; | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | if (on == 0) { | ||
| 1266 | zr->overlay_active = fh->overlay_active = ZORAN_FREE; | ||
| 1267 | zr->v4l_overlay_active = 0; | ||
| 1268 | /* When a grab is running, the video simply | ||
| 1269 | * won't be switched on any more */ | ||
| 1270 | if (!zr->v4l_memgrab_active) | ||
| 1271 | zr36057_overlay(zr, 0); | ||
| 1272 | zr->overlay_mask = NULL; | ||
| 1273 | } else { | ||
| 1274 | if (!zr->vbuf_base || !fh->overlay_settings.is_set) { | ||
| 1275 | dprintk(1, | ||
| 1276 | KERN_ERR | ||
| 1277 | "%s: %s - buffer or window not set\n", | ||
| 1278 | ZR_DEVNAME(zr), __func__); | ||
| 1279 | return -EINVAL; | ||
| 1280 | } | ||
| 1281 | if (!fh->overlay_settings.format) { | ||
| 1282 | dprintk(1, | ||
| 1283 | KERN_ERR | ||
| 1284 | "%s: %s - no overlay format set\n", | ||
| 1285 | ZR_DEVNAME(zr), __func__); | ||
| 1286 | return -EINVAL; | ||
| 1287 | } | ||
| 1288 | zr->overlay_active = fh->overlay_active = ZORAN_LOCKED; | ||
| 1289 | zr->v4l_overlay_active = 1; | ||
| 1290 | zr->overlay_mask = fh->overlay_mask; | ||
| 1291 | zr->overlay_settings = fh->overlay_settings; | ||
| 1292 | if (!zr->v4l_memgrab_active) | ||
| 1293 | zr36057_overlay(zr, 1); | ||
| 1294 | /* When a grab is running, the video will be | ||
| 1295 | * switched on when grab is finished */ | ||
| 1296 | } | ||
| 1297 | |||
| 1298 | /* Make sure the changes come into effect */ | ||
| 1299 | return wait_grab_pending(zr); | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /* get the status of a buffer in the clients buffer queue */ | ||
| 1303 | static int zoran_v4l2_buffer_status(struct zoran_fh *fh, | ||
| 1304 | struct v4l2_buffer *buf, int num) | ||
| 1305 | { | ||
| 1306 | struct zoran *zr = fh->zr; | ||
| 1307 | unsigned long flags; | ||
| 1308 | |||
| 1309 | buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
| 1310 | |||
| 1311 | switch (fh->map_mode) { | ||
| 1312 | case ZORAN_MAP_MODE_RAW: | ||
| 1313 | /* check range */ | ||
| 1314 | if (num < 0 || num >= fh->buffers.num_buffers || | ||
| 1315 | !fh->buffers.allocated) { | ||
| 1316 | dprintk(1, | ||
| 1317 | KERN_ERR | ||
| 1318 | "%s: %s - wrong number or buffers not allocated\n", | ||
| 1319 | ZR_DEVNAME(zr), __func__); | ||
| 1320 | return -EINVAL; | ||
| 1321 | } | ||
| 1322 | |||
| 1323 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 1324 | dprintk(3, | ||
| 1325 | KERN_DEBUG | ||
| 1326 | "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n", | ||
| 1327 | ZR_DEVNAME(zr), __func__, | ||
| 1328 | "FAL"[fh->buffers.active], num, | ||
| 1329 | "UPMD"[zr->v4l_buffers.buffer[num].state], | ||
| 1330 | fh->buffers.buffer[num].map ? 'Y' : 'N'); | ||
| 1331 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 1332 | |||
| 1333 | buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 1334 | buf->length = fh->buffers.buffer_size; | ||
| 1335 | |||
| 1336 | /* get buffer */ | ||
| 1337 | buf->bytesused = fh->buffers.buffer[num].bs.length; | ||
| 1338 | if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || | ||
| 1339 | fh->buffers.buffer[num].state == BUZ_STATE_USER) { | ||
| 1340 | buf->sequence = fh->buffers.buffer[num].bs.seq; | ||
| 1341 | buf->flags |= V4L2_BUF_FLAG_DONE; | ||
| 1342 | buf->timestamp = ns_to_timeval(fh->buffers.buffer[num].bs.ts); | ||
| 1343 | } else { | ||
| 1344 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | if (fh->v4l_settings.height <= BUZ_MAX_HEIGHT / 2) | ||
| 1348 | buf->field = V4L2_FIELD_TOP; | ||
| 1349 | else | ||
| 1350 | buf->field = V4L2_FIELD_INTERLACED; | ||
| 1351 | |||
| 1352 | break; | ||
| 1353 | |||
| 1354 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 1355 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 1356 | |||
| 1357 | /* check range */ | ||
| 1358 | if (num < 0 || num >= fh->buffers.num_buffers || | ||
| 1359 | !fh->buffers.allocated) { | ||
| 1360 | dprintk(1, | ||
| 1361 | KERN_ERR | ||
| 1362 | "%s: %s - wrong number or buffers not allocated\n", | ||
| 1363 | ZR_DEVNAME(zr), __func__); | ||
| 1364 | return -EINVAL; | ||
| 1365 | } | ||
| 1366 | |||
| 1367 | buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? | ||
| 1368 | V4L2_BUF_TYPE_VIDEO_CAPTURE : | ||
| 1369 | V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 1370 | buf->length = fh->buffers.buffer_size; | ||
| 1371 | |||
| 1372 | /* these variables are only written after frame has been captured */ | ||
| 1373 | if (fh->buffers.buffer[num].state == BUZ_STATE_DONE || | ||
| 1374 | fh->buffers.buffer[num].state == BUZ_STATE_USER) { | ||
| 1375 | buf->sequence = fh->buffers.buffer[num].bs.seq; | ||
| 1376 | buf->timestamp = ns_to_timeval(fh->buffers.buffer[num].bs.ts); | ||
| 1377 | buf->bytesused = fh->buffers.buffer[num].bs.length; | ||
| 1378 | buf->flags |= V4L2_BUF_FLAG_DONE; | ||
| 1379 | } else { | ||
| 1380 | buf->flags |= V4L2_BUF_FLAG_QUEUED; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /* which fields are these? */ | ||
| 1384 | if (fh->jpg_settings.TmpDcm != 1) | ||
| 1385 | buf->field = fh->jpg_settings.odd_even ? | ||
| 1386 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; | ||
| 1387 | else | ||
| 1388 | buf->field = fh->jpg_settings.odd_even ? | ||
| 1389 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT; | ||
| 1390 | |||
| 1391 | break; | ||
| 1392 | |||
| 1393 | default: | ||
| 1394 | |||
| 1395 | dprintk(5, | ||
| 1396 | KERN_ERR | ||
| 1397 | "%s: %s - invalid buffer type|map_mode (%d|%d)\n", | ||
| 1398 | ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode); | ||
| 1399 | return -EINVAL; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | buf->memory = V4L2_MEMORY_MMAP; | ||
| 1403 | buf->index = num; | ||
| 1404 | buf->m.offset = buf->length * num; | ||
| 1405 | |||
| 1406 | return 0; | ||
| 1407 | } | ||
| 1408 | |||
| 1409 | static int | ||
| 1410 | zoran_set_norm (struct zoran *zr, | ||
| 1411 | v4l2_std_id norm) | ||
| 1412 | { | ||
| 1413 | int on; | ||
| 1414 | |||
| 1415 | if (zr->v4l_buffers.active != ZORAN_FREE || | ||
| 1416 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
| 1417 | dprintk(1, | ||
| 1418 | KERN_WARNING | ||
| 1419 | "%s: %s called while in playback/capture mode\n", | ||
| 1420 | ZR_DEVNAME(zr), __func__); | ||
| 1421 | return -EBUSY; | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | if (!(norm & zr->card.norms)) { | ||
| 1425 | dprintk(1, | ||
| 1426 | KERN_ERR "%s: %s - unsupported norm %llx\n", | ||
| 1427 | ZR_DEVNAME(zr), __func__, norm); | ||
| 1428 | return -EINVAL; | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | if (norm & V4L2_STD_SECAM) | ||
| 1432 | zr->timing = zr->card.tvn[2]; | ||
| 1433 | else if (norm & V4L2_STD_NTSC) | ||
| 1434 | zr->timing = zr->card.tvn[1]; | ||
| 1435 | else | ||
| 1436 | zr->timing = zr->card.tvn[0]; | ||
| 1437 | |||
| 1438 | /* We switch overlay off and on since a change in the | ||
| 1439 | * norm needs different VFE settings */ | ||
| 1440 | on = zr->overlay_active && !zr->v4l_memgrab_active; | ||
| 1441 | if (on) | ||
| 1442 | zr36057_overlay(zr, 0); | ||
| 1443 | |||
| 1444 | decoder_call(zr, video, s_std, norm); | ||
| 1445 | encoder_call(zr, video, s_std_output, norm); | ||
| 1446 | |||
| 1447 | if (on) | ||
| 1448 | zr36057_overlay(zr, 1); | ||
| 1449 | |||
| 1450 | /* Make sure the changes come into effect */ | ||
| 1451 | zr->norm = norm; | ||
| 1452 | |||
| 1453 | return 0; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | static int | ||
| 1457 | zoran_set_input (struct zoran *zr, | ||
| 1458 | int input) | ||
| 1459 | { | ||
| 1460 | if (input == zr->input) { | ||
| 1461 | return 0; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | if (zr->v4l_buffers.active != ZORAN_FREE || | ||
| 1465 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
| 1466 | dprintk(1, | ||
| 1467 | KERN_WARNING | ||
| 1468 | "%s: %s called while in playback/capture mode\n", | ||
| 1469 | ZR_DEVNAME(zr), __func__); | ||
| 1470 | return -EBUSY; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | if (input < 0 || input >= zr->card.inputs) { | ||
| 1474 | dprintk(1, | ||
| 1475 | KERN_ERR | ||
| 1476 | "%s: %s - unsupported input %d\n", | ||
| 1477 | ZR_DEVNAME(zr), __func__, input); | ||
| 1478 | return -EINVAL; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | zr->input = input; | ||
| 1482 | |||
| 1483 | decoder_call(zr, video, s_routing, | ||
| 1484 | zr->card.input[input].muxsel, 0, 0); | ||
| 1485 | |||
| 1486 | return 0; | ||
| 1487 | } | ||
| 1488 | |||
| 1489 | /* | ||
| 1490 | * ioctl routine | ||
| 1491 | */ | ||
| 1492 | |||
| 1493 | static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap) | ||
| 1494 | { | ||
| 1495 | struct zoran_fh *fh = __fh; | ||
| 1496 | struct zoran *zr = fh->zr; | ||
| 1497 | |||
| 1498 | strscpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)); | ||
| 1499 | strscpy(cap->driver, "zoran", sizeof(cap->driver)); | ||
| 1500 | snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", | ||
| 1501 | pci_name(zr->pci_dev)); | ||
| 1502 | cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | | ||
| 1503 | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY; | ||
| 1504 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
| 1505 | return 0; | ||
| 1506 | } | ||
| 1507 | |||
| 1508 | static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag) | ||
| 1509 | { | ||
| 1510 | unsigned int num, i; | ||
| 1511 | |||
| 1512 | for (num = i = 0; i < NUM_FORMATS; i++) { | ||
| 1513 | if (zoran_formats[i].flags & flag && num++ == fmt->index) { | ||
| 1514 | strncpy(fmt->description, zoran_formats[i].name, | ||
| 1515 | sizeof(fmt->description) - 1); | ||
| 1516 | /* fmt struct pre-zeroed, so adding '\0' not needed */ | ||
| 1517 | fmt->pixelformat = zoran_formats[i].fourcc; | ||
| 1518 | if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED) | ||
| 1519 | fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; | ||
| 1520 | return 0; | ||
| 1521 | } | ||
| 1522 | } | ||
| 1523 | return -EINVAL; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh, | ||
| 1527 | struct v4l2_fmtdesc *f) | ||
| 1528 | { | ||
| 1529 | struct zoran_fh *fh = __fh; | ||
| 1530 | struct zoran *zr = fh->zr; | ||
| 1531 | |||
| 1532 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE); | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | static int zoran_enum_fmt_vid_out(struct file *file, void *__fh, | ||
| 1536 | struct v4l2_fmtdesc *f) | ||
| 1537 | { | ||
| 1538 | struct zoran_fh *fh = __fh; | ||
| 1539 | struct zoran *zr = fh->zr; | ||
| 1540 | |||
| 1541 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK); | ||
| 1542 | } | ||
| 1543 | |||
| 1544 | static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh, | ||
| 1545 | struct v4l2_fmtdesc *f) | ||
| 1546 | { | ||
| 1547 | struct zoran_fh *fh = __fh; | ||
| 1548 | struct zoran *zr = fh->zr; | ||
| 1549 | |||
| 1550 | return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY); | ||
| 1551 | } | ||
| 1552 | |||
| 1553 | static int zoran_g_fmt_vid_out(struct file *file, void *__fh, | ||
| 1554 | struct v4l2_format *fmt) | ||
| 1555 | { | ||
| 1556 | struct zoran_fh *fh = __fh; | ||
| 1557 | |||
| 1558 | fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm; | ||
| 1559 | fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 / | ||
| 1560 | (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm); | ||
| 1561 | fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
| 1562 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; | ||
| 1563 | if (fh->jpg_settings.TmpDcm == 1) | ||
| 1564 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1565 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
| 1566 | else | ||
| 1567 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1568 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
| 1569 | fmt->fmt.pix.bytesperline = 0; | ||
| 1570 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 1571 | |||
| 1572 | return 0; | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | static int zoran_g_fmt_vid_cap(struct file *file, void *__fh, | ||
| 1576 | struct v4l2_format *fmt) | ||
| 1577 | { | ||
| 1578 | struct zoran_fh *fh = __fh; | ||
| 1579 | struct zoran *zr = fh->zr; | ||
| 1580 | |||
| 1581 | if (fh->map_mode != ZORAN_MAP_MODE_RAW) | ||
| 1582 | return zoran_g_fmt_vid_out(file, fh, fmt); | ||
| 1583 | |||
| 1584 | fmt->fmt.pix.width = fh->v4l_settings.width; | ||
| 1585 | fmt->fmt.pix.height = fh->v4l_settings.height; | ||
| 1586 | fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline * | ||
| 1587 | fh->v4l_settings.height; | ||
| 1588 | fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc; | ||
| 1589 | fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; | ||
| 1590 | fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; | ||
| 1591 | if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) | ||
| 1592 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
| 1593 | else | ||
| 1594 | fmt->fmt.pix.field = V4L2_FIELD_TOP; | ||
| 1595 | return 0; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh, | ||
| 1599 | struct v4l2_format *fmt) | ||
| 1600 | { | ||
| 1601 | struct zoran_fh *fh = __fh; | ||
| 1602 | struct zoran *zr = fh->zr; | ||
| 1603 | |||
| 1604 | fmt->fmt.win.w.left = fh->overlay_settings.x; | ||
| 1605 | fmt->fmt.win.w.top = fh->overlay_settings.y; | ||
| 1606 | fmt->fmt.win.w.width = fh->overlay_settings.width; | ||
| 1607 | fmt->fmt.win.w.height = fh->overlay_settings.height; | ||
| 1608 | if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT) | ||
| 1609 | fmt->fmt.win.field = V4L2_FIELD_INTERLACED; | ||
| 1610 | else | ||
| 1611 | fmt->fmt.win.field = V4L2_FIELD_TOP; | ||
| 1612 | |||
| 1613 | return 0; | ||
| 1614 | } | ||
| 1615 | |||
| 1616 | static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh, | ||
| 1617 | struct v4l2_format *fmt) | ||
| 1618 | { | ||
| 1619 | struct zoran_fh *fh = __fh; | ||
| 1620 | struct zoran *zr = fh->zr; | ||
| 1621 | |||
| 1622 | if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH) | ||
| 1623 | fmt->fmt.win.w.width = BUZ_MAX_WIDTH; | ||
| 1624 | if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH) | ||
| 1625 | fmt->fmt.win.w.width = BUZ_MIN_WIDTH; | ||
| 1626 | if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT) | ||
| 1627 | fmt->fmt.win.w.height = BUZ_MAX_HEIGHT; | ||
| 1628 | if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT) | ||
| 1629 | fmt->fmt.win.w.height = BUZ_MIN_HEIGHT; | ||
| 1630 | |||
| 1631 | return 0; | ||
| 1632 | } | ||
| 1633 | |||
| 1634 | static int zoran_try_fmt_vid_out(struct file *file, void *__fh, | ||
| 1635 | struct v4l2_format *fmt) | ||
| 1636 | { | ||
| 1637 | struct zoran_fh *fh = __fh; | ||
| 1638 | struct zoran *zr = fh->zr; | ||
| 1639 | struct zoran_jpg_settings settings; | ||
| 1640 | int res = 0; | ||
| 1641 | |||
| 1642 | if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
| 1643 | return -EINVAL; | ||
| 1644 | |||
| 1645 | settings = fh->jpg_settings; | ||
| 1646 | |||
| 1647 | /* we actually need to set 'real' parameters now */ | ||
| 1648 | if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT) | ||
| 1649 | settings.TmpDcm = 1; | ||
| 1650 | else | ||
| 1651 | settings.TmpDcm = 2; | ||
| 1652 | settings.decimation = 0; | ||
| 1653 | if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) | ||
| 1654 | settings.VerDcm = 2; | ||
| 1655 | else | ||
| 1656 | settings.VerDcm = 1; | ||
| 1657 | if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) | ||
| 1658 | settings.HorDcm = 4; | ||
| 1659 | else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) | ||
| 1660 | settings.HorDcm = 2; | ||
| 1661 | else | ||
| 1662 | settings.HorDcm = 1; | ||
| 1663 | if (settings.TmpDcm == 1) | ||
| 1664 | settings.field_per_buff = 2; | ||
| 1665 | else | ||
| 1666 | settings.field_per_buff = 1; | ||
| 1667 | |||
| 1668 | if (settings.HorDcm > 1) { | ||
| 1669 | settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
| 1670 | settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
| 1671 | } else { | ||
| 1672 | settings.img_x = 0; | ||
| 1673 | settings.img_width = BUZ_MAX_WIDTH; | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | /* check */ | ||
| 1677 | res = zoran_check_jpg_settings(zr, &settings, 1); | ||
| 1678 | if (res) | ||
| 1679 | return res; | ||
| 1680 | |||
| 1681 | /* tell the user what we actually did */ | ||
| 1682 | fmt->fmt.pix.width = settings.img_width / settings.HorDcm; | ||
| 1683 | fmt->fmt.pix.height = settings.img_height * 2 / | ||
| 1684 | (settings.TmpDcm * settings.VerDcm); | ||
| 1685 | if (settings.TmpDcm == 1) | ||
| 1686 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1687 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
| 1688 | else | ||
| 1689 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1690 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
| 1691 | |||
| 1692 | fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings); | ||
| 1693 | fmt->fmt.pix.bytesperline = 0; | ||
| 1694 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 1695 | return res; | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static int zoran_try_fmt_vid_cap(struct file *file, void *__fh, | ||
| 1699 | struct v4l2_format *fmt) | ||
| 1700 | { | ||
| 1701 | struct zoran_fh *fh = __fh; | ||
| 1702 | struct zoran *zr = fh->zr; | ||
| 1703 | int bpp; | ||
| 1704 | int i; | ||
| 1705 | |||
| 1706 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | ||
| 1707 | return zoran_try_fmt_vid_out(file, fh, fmt); | ||
| 1708 | |||
| 1709 | for (i = 0; i < NUM_FORMATS; i++) | ||
| 1710 | if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat) | ||
| 1711 | break; | ||
| 1712 | |||
| 1713 | if (i == NUM_FORMATS) | ||
| 1714 | return -EINVAL; | ||
| 1715 | |||
| 1716 | bpp = DIV_ROUND_UP(zoran_formats[i].depth, 8); | ||
| 1717 | v4l_bound_align_image( | ||
| 1718 | &fmt->fmt.pix.width, BUZ_MIN_WIDTH, BUZ_MAX_WIDTH, bpp == 2 ? 1 : 2, | ||
| 1719 | &fmt->fmt.pix.height, BUZ_MIN_HEIGHT, BUZ_MAX_HEIGHT, 0, 0); | ||
| 1720 | return 0; | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh, | ||
| 1724 | struct v4l2_format *fmt) | ||
| 1725 | { | ||
| 1726 | struct zoran_fh *fh = __fh; | ||
| 1727 | |||
| 1728 | dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n", | ||
| 1729 | fmt->fmt.win.w.left, fmt->fmt.win.w.top, | ||
| 1730 | fmt->fmt.win.w.width, | ||
| 1731 | fmt->fmt.win.w.height, | ||
| 1732 | fmt->fmt.win.clipcount, | ||
| 1733 | fmt->fmt.win.bitmap); | ||
| 1734 | return setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top, | ||
| 1735 | fmt->fmt.win.w.width, fmt->fmt.win.w.height, | ||
| 1736 | (struct v4l2_clip __user *)fmt->fmt.win.clips, | ||
| 1737 | fmt->fmt.win.clipcount, fmt->fmt.win.bitmap); | ||
| 1738 | } | ||
| 1739 | |||
| 1740 | static int zoran_s_fmt_vid_out(struct file *file, void *__fh, | ||
| 1741 | struct v4l2_format *fmt) | ||
| 1742 | { | ||
| 1743 | struct zoran_fh *fh = __fh; | ||
| 1744 | struct zoran *zr = fh->zr; | ||
| 1745 | __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat); | ||
| 1746 | struct zoran_jpg_settings settings; | ||
| 1747 | int res = 0; | ||
| 1748 | |||
| 1749 | dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n", | ||
| 1750 | fmt->fmt.pix.width, fmt->fmt.pix.height, | ||
| 1751 | fmt->fmt.pix.pixelformat, | ||
| 1752 | (char *) &printformat); | ||
| 1753 | if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) | ||
| 1754 | return -EINVAL; | ||
| 1755 | |||
| 1756 | if (fh->buffers.allocated) { | ||
| 1757 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", | ||
| 1758 | ZR_DEVNAME(zr)); | ||
| 1759 | return -EBUSY; | ||
| 1760 | } | ||
| 1761 | |||
| 1762 | settings = fh->jpg_settings; | ||
| 1763 | |||
| 1764 | /* we actually need to set 'real' parameters now */ | ||
| 1765 | if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT) | ||
| 1766 | settings.TmpDcm = 1; | ||
| 1767 | else | ||
| 1768 | settings.TmpDcm = 2; | ||
| 1769 | settings.decimation = 0; | ||
| 1770 | if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2) | ||
| 1771 | settings.VerDcm = 2; | ||
| 1772 | else | ||
| 1773 | settings.VerDcm = 1; | ||
| 1774 | if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4) | ||
| 1775 | settings.HorDcm = 4; | ||
| 1776 | else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2) | ||
| 1777 | settings.HorDcm = 2; | ||
| 1778 | else | ||
| 1779 | settings.HorDcm = 1; | ||
| 1780 | if (settings.TmpDcm == 1) | ||
| 1781 | settings.field_per_buff = 2; | ||
| 1782 | else | ||
| 1783 | settings.field_per_buff = 1; | ||
| 1784 | |||
| 1785 | if (settings.HorDcm > 1) { | ||
| 1786 | settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0; | ||
| 1787 | settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH; | ||
| 1788 | } else { | ||
| 1789 | settings.img_x = 0; | ||
| 1790 | settings.img_width = BUZ_MAX_WIDTH; | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | /* check */ | ||
| 1794 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
| 1795 | if (res) | ||
| 1796 | return res; | ||
| 1797 | |||
| 1798 | /* it's ok, so set them */ | ||
| 1799 | fh->jpg_settings = settings; | ||
| 1800 | |||
| 1801 | map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
| 1802 | fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
| 1803 | |||
| 1804 | /* tell the user what we actually did */ | ||
| 1805 | fmt->fmt.pix.width = settings.img_width / settings.HorDcm; | ||
| 1806 | fmt->fmt.pix.height = settings.img_height * 2 / | ||
| 1807 | (settings.TmpDcm * settings.VerDcm); | ||
| 1808 | if (settings.TmpDcm == 1) | ||
| 1809 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1810 | V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT); | ||
| 1811 | else | ||
| 1812 | fmt->fmt.pix.field = (fh->jpg_settings.odd_even ? | ||
| 1813 | V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); | ||
| 1814 | fmt->fmt.pix.bytesperline = 0; | ||
| 1815 | fmt->fmt.pix.sizeimage = fh->buffers.buffer_size; | ||
| 1816 | fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
| 1817 | return res; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | static int zoran_s_fmt_vid_cap(struct file *file, void *__fh, | ||
| 1821 | struct v4l2_format *fmt) | ||
| 1822 | { | ||
| 1823 | struct zoran_fh *fh = __fh; | ||
| 1824 | struct zoran *zr = fh->zr; | ||
| 1825 | int i; | ||
| 1826 | int res = 0; | ||
| 1827 | |||
| 1828 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | ||
| 1829 | return zoran_s_fmt_vid_out(file, fh, fmt); | ||
| 1830 | |||
| 1831 | for (i = 0; i < NUM_FORMATS; i++) | ||
| 1832 | if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc) | ||
| 1833 | break; | ||
| 1834 | if (i == NUM_FORMATS) { | ||
| 1835 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n", | ||
| 1836 | ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat); | ||
| 1837 | return -EINVAL; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) || | ||
| 1841 | fh->buffers.active != ZORAN_FREE) { | ||
| 1842 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n", | ||
| 1843 | ZR_DEVNAME(zr)); | ||
| 1844 | return -EBUSY; | ||
| 1845 | } | ||
| 1846 | if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT) | ||
| 1847 | fmt->fmt.pix.height = BUZ_MAX_HEIGHT; | ||
| 1848 | if (fmt->fmt.pix.width > BUZ_MAX_WIDTH) | ||
| 1849 | fmt->fmt.pix.width = BUZ_MAX_WIDTH; | ||
| 1850 | |||
| 1851 | map_mode_raw(fh); | ||
| 1852 | |||
| 1853 | res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height, | ||
| 1854 | &zoran_formats[i]); | ||
| 1855 | if (res) | ||
| 1856 | return res; | ||
| 1857 | |||
| 1858 | /* tell the user the results/missing stuff */ | ||
| 1859 | fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline; | ||
| 1860 | fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline; | ||
| 1861 | fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace; | ||
| 1862 | if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2)) | ||
| 1863 | fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
| 1864 | else | ||
| 1865 | fmt->fmt.pix.field = V4L2_FIELD_TOP; | ||
| 1866 | return res; | ||
| 1867 | } | ||
| 1868 | |||
| 1869 | static int zoran_g_fbuf(struct file *file, void *__fh, | ||
| 1870 | struct v4l2_framebuffer *fb) | ||
| 1871 | { | ||
| 1872 | struct zoran_fh *fh = __fh; | ||
| 1873 | struct zoran *zr = fh->zr; | ||
| 1874 | |||
| 1875 | memset(fb, 0, sizeof(*fb)); | ||
| 1876 | fb->base = zr->vbuf_base; | ||
| 1877 | fb->fmt.width = zr->vbuf_width; | ||
| 1878 | fb->fmt.height = zr->vbuf_height; | ||
| 1879 | if (zr->overlay_settings.format) | ||
| 1880 | fb->fmt.pixelformat = fh->overlay_settings.format->fourcc; | ||
| 1881 | fb->fmt.bytesperline = zr->vbuf_bytesperline; | ||
| 1882 | fb->fmt.colorspace = V4L2_COLORSPACE_SRGB; | ||
| 1883 | fb->fmt.field = V4L2_FIELD_INTERLACED; | ||
| 1884 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | ||
| 1885 | |||
| 1886 | return 0; | ||
| 1887 | } | ||
| 1888 | |||
| 1889 | static int zoran_s_fbuf(struct file *file, void *__fh, | ||
| 1890 | const struct v4l2_framebuffer *fb) | ||
| 1891 | { | ||
| 1892 | struct zoran_fh *fh = __fh; | ||
| 1893 | struct zoran *zr = fh->zr; | ||
| 1894 | int i; | ||
| 1895 | __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); | ||
| 1896 | |||
| 1897 | for (i = 0; i < NUM_FORMATS; i++) | ||
| 1898 | if (zoran_formats[i].fourcc == fb->fmt.pixelformat) | ||
| 1899 | break; | ||
| 1900 | if (i == NUM_FORMATS) { | ||
| 1901 | dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n", | ||
| 1902 | ZR_DEVNAME(zr), fb->fmt.pixelformat, | ||
| 1903 | (char *)&printformat); | ||
| 1904 | return -EINVAL; | ||
| 1905 | } | ||
| 1906 | |||
| 1907 | return setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width, | ||
| 1908 | fb->fmt.height, fb->fmt.bytesperline); | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | static int zoran_overlay(struct file *file, void *__fh, unsigned int on) | ||
| 1912 | { | ||
| 1913 | struct zoran_fh *fh = __fh; | ||
| 1914 | |||
| 1915 | return setup_overlay(fh, on); | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type); | ||
| 1919 | |||
| 1920 | static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req) | ||
| 1921 | { | ||
| 1922 | struct zoran_fh *fh = __fh; | ||
| 1923 | struct zoran *zr = fh->zr; | ||
| 1924 | int res = 0; | ||
| 1925 | |||
| 1926 | if (req->memory != V4L2_MEMORY_MMAP) { | ||
| 1927 | dprintk(2, | ||
| 1928 | KERN_ERR | ||
| 1929 | "%s: only MEMORY_MMAP capture is supported, not %d\n", | ||
| 1930 | ZR_DEVNAME(zr), req->memory); | ||
| 1931 | return -EINVAL; | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | if (req->count == 0) | ||
| 1935 | return zoran_streamoff(file, fh, req->type); | ||
| 1936 | |||
| 1937 | if (fh->buffers.allocated) { | ||
| 1938 | dprintk(2, | ||
| 1939 | KERN_ERR | ||
| 1940 | "%s: VIDIOC_REQBUFS - buffers already allocated\n", | ||
| 1941 | ZR_DEVNAME(zr)); | ||
| 1942 | return -EBUSY; | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | if (fh->map_mode == ZORAN_MAP_MODE_RAW && | ||
| 1946 | req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 1947 | /* control user input */ | ||
| 1948 | if (req->count < 2) | ||
| 1949 | req->count = 2; | ||
| 1950 | if (req->count > v4l_nbufs) | ||
| 1951 | req->count = v4l_nbufs; | ||
| 1952 | |||
| 1953 | /* The next mmap will map the V4L buffers */ | ||
| 1954 | map_mode_raw(fh); | ||
| 1955 | fh->buffers.num_buffers = req->count; | ||
| 1956 | |||
| 1957 | if (v4l_fbuffer_alloc(fh)) { | ||
| 1958 | return -ENOMEM; | ||
| 1959 | } | ||
| 1960 | } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC || | ||
| 1961 | fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { | ||
| 1962 | /* we need to calculate size ourselves now */ | ||
| 1963 | if (req->count < 4) | ||
| 1964 | req->count = 4; | ||
| 1965 | if (req->count > jpg_nbufs) | ||
| 1966 | req->count = jpg_nbufs; | ||
| 1967 | |||
| 1968 | /* The next mmap will map the MJPEG buffers */ | ||
| 1969 | map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT); | ||
| 1970 | fh->buffers.num_buffers = req->count; | ||
| 1971 | fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
| 1972 | |||
| 1973 | if (jpg_fbuffer_alloc(fh)) { | ||
| 1974 | return -ENOMEM; | ||
| 1975 | } | ||
| 1976 | } else { | ||
| 1977 | dprintk(1, | ||
| 1978 | KERN_ERR | ||
| 1979 | "%s: VIDIOC_REQBUFS - unknown type %d\n", | ||
| 1980 | ZR_DEVNAME(zr), req->type); | ||
| 1981 | return -EINVAL; | ||
| 1982 | } | ||
| 1983 | return res; | ||
| 1984 | } | ||
| 1985 | |||
| 1986 | static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
| 1987 | { | ||
| 1988 | struct zoran_fh *fh = __fh; | ||
| 1989 | |||
| 1990 | return zoran_v4l2_buffer_status(fh, buf, buf->index); | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
| 1994 | { | ||
| 1995 | struct zoran_fh *fh = __fh; | ||
| 1996 | struct zoran *zr = fh->zr; | ||
| 1997 | int res = 0, codec_mode, buf_type; | ||
| 1998 | |||
| 1999 | switch (fh->map_mode) { | ||
| 2000 | case ZORAN_MAP_MODE_RAW: | ||
| 2001 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 2002 | dprintk(1, KERN_ERR | ||
| 2003 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
| 2004 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
| 2005 | return -EINVAL; | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | res = zoran_v4l_queue_frame(fh, buf->index); | ||
| 2009 | if (res) | ||
| 2010 | return res; | ||
| 2011 | if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED) | ||
| 2012 | zr36057_set_memgrab(zr, 1); | ||
| 2013 | break; | ||
| 2014 | |||
| 2015 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 2016 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 2017 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) { | ||
| 2018 | buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 2019 | codec_mode = BUZ_MODE_MOTION_DECOMPRESS; | ||
| 2020 | } else { | ||
| 2021 | buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 2022 | codec_mode = BUZ_MODE_MOTION_COMPRESS; | ||
| 2023 | } | ||
| 2024 | |||
| 2025 | if (buf->type != buf_type) { | ||
| 2026 | dprintk(1, KERN_ERR | ||
| 2027 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
| 2028 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
| 2029 | return -EINVAL; | ||
| 2030 | } | ||
| 2031 | |||
| 2032 | res = zoran_jpg_queue_frame(fh, buf->index, codec_mode); | ||
| 2033 | if (res != 0) | ||
| 2034 | return res; | ||
| 2035 | if (zr->codec_mode == BUZ_MODE_IDLE && | ||
| 2036 | fh->buffers.active == ZORAN_LOCKED) | ||
| 2037 | zr36057_enable_jpg(zr, codec_mode); | ||
| 2038 | |||
| 2039 | break; | ||
| 2040 | |||
| 2041 | default: | ||
| 2042 | dprintk(1, KERN_ERR | ||
| 2043 | "%s: VIDIOC_QBUF - unsupported type %d\n", | ||
| 2044 | ZR_DEVNAME(zr), buf->type); | ||
| 2045 | res = -EINVAL; | ||
| 2046 | break; | ||
| 2047 | } | ||
| 2048 | return res; | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
| 2052 | { | ||
| 2053 | struct zoran_fh *fh = __fh; | ||
| 2054 | struct zoran *zr = fh->zr; | ||
| 2055 | int res = 0, buf_type, num = -1; /* compiler borks here (?) */ | ||
| 2056 | |||
| 2057 | switch (fh->map_mode) { | ||
| 2058 | case ZORAN_MAP_MODE_RAW: | ||
| 2059 | if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
| 2060 | dprintk(1, KERN_ERR | ||
| 2061 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
| 2062 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
| 2063 | return -EINVAL; | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; | ||
| 2067 | if (file->f_flags & O_NONBLOCK && | ||
| 2068 | zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) { | ||
| 2069 | return -EAGAIN; | ||
| 2070 | } | ||
| 2071 | res = v4l_sync(fh, num); | ||
| 2072 | if (res) | ||
| 2073 | return res; | ||
| 2074 | zr->v4l_sync_tail++; | ||
| 2075 | res = zoran_v4l2_buffer_status(fh, buf, num); | ||
| 2076 | break; | ||
| 2077 | |||
| 2078 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 2079 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 2080 | { | ||
| 2081 | struct zoran_sync bs; | ||
| 2082 | |||
| 2083 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) | ||
| 2084 | buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | ||
| 2085 | else | ||
| 2086 | buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
| 2087 | |||
| 2088 | if (buf->type != buf_type) { | ||
| 2089 | dprintk(1, KERN_ERR | ||
| 2090 | "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n", | ||
| 2091 | ZR_DEVNAME(zr), buf->type, fh->map_mode); | ||
| 2092 | return -EINVAL; | ||
| 2093 | } | ||
| 2094 | |||
| 2095 | num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
| 2096 | |||
| 2097 | if (file->f_flags & O_NONBLOCK && | ||
| 2098 | zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) { | ||
| 2099 | return -EAGAIN; | ||
| 2100 | } | ||
| 2101 | bs.frame = 0; /* suppress compiler warning */ | ||
| 2102 | res = jpg_sync(fh, &bs); | ||
| 2103 | if (res) | ||
| 2104 | return res; | ||
| 2105 | res = zoran_v4l2_buffer_status(fh, buf, bs.frame); | ||
| 2106 | break; | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | default: | ||
| 2110 | dprintk(1, KERN_ERR | ||
| 2111 | "%s: VIDIOC_DQBUF - unsupported type %d\n", | ||
| 2112 | ZR_DEVNAME(zr), buf->type); | ||
| 2113 | res = -EINVAL; | ||
| 2114 | break; | ||
| 2115 | } | ||
| 2116 | return res; | ||
| 2117 | } | ||
| 2118 | |||
| 2119 | static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
| 2120 | { | ||
| 2121 | struct zoran_fh *fh = __fh; | ||
| 2122 | struct zoran *zr = fh->zr; | ||
| 2123 | int res = 0; | ||
| 2124 | |||
| 2125 | switch (fh->map_mode) { | ||
| 2126 | case ZORAN_MAP_MODE_RAW: /* raw capture */ | ||
| 2127 | if (zr->v4l_buffers.active != ZORAN_ACTIVE || | ||
| 2128 | fh->buffers.active != ZORAN_ACTIVE) { | ||
| 2129 | return -EBUSY; | ||
| 2130 | } | ||
| 2131 | |||
| 2132 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED; | ||
| 2133 | zr->v4l_settings = fh->v4l_settings; | ||
| 2134 | |||
| 2135 | zr->v4l_sync_tail = zr->v4l_pend_tail; | ||
| 2136 | if (!zr->v4l_memgrab_active && | ||
| 2137 | zr->v4l_pend_head != zr->v4l_pend_tail) { | ||
| 2138 | zr36057_set_memgrab(zr, 1); | ||
| 2139 | } | ||
| 2140 | break; | ||
| 2141 | |||
| 2142 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 2143 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 2144 | /* what is the codec mode right now? */ | ||
| 2145 | if (zr->jpg_buffers.active != ZORAN_ACTIVE || | ||
| 2146 | fh->buffers.active != ZORAN_ACTIVE) { | ||
| 2147 | return -EBUSY; | ||
| 2148 | } | ||
| 2149 | |||
| 2150 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED; | ||
| 2151 | |||
| 2152 | if (zr->jpg_que_head != zr->jpg_que_tail) { | ||
| 2153 | /* Start the jpeg codec when the first frame is queued */ | ||
| 2154 | jpeg_start(zr); | ||
| 2155 | } | ||
| 2156 | break; | ||
| 2157 | |||
| 2158 | default: | ||
| 2159 | dprintk(1, | ||
| 2160 | KERN_ERR | ||
| 2161 | "%s: VIDIOC_STREAMON - invalid map mode %d\n", | ||
| 2162 | ZR_DEVNAME(zr), fh->map_mode); | ||
| 2163 | res = -EINVAL; | ||
| 2164 | break; | ||
| 2165 | } | ||
| 2166 | return res; | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
| 2170 | { | ||
| 2171 | struct zoran_fh *fh = __fh; | ||
| 2172 | struct zoran *zr = fh->zr; | ||
| 2173 | int i, res = 0; | ||
| 2174 | unsigned long flags; | ||
| 2175 | |||
| 2176 | switch (fh->map_mode) { | ||
| 2177 | case ZORAN_MAP_MODE_RAW: /* raw capture */ | ||
| 2178 | if (fh->buffers.active == ZORAN_FREE && | ||
| 2179 | zr->v4l_buffers.active != ZORAN_FREE) { | ||
| 2180 | return -EPERM; /* stay off other's settings! */ | ||
| 2181 | } | ||
| 2182 | if (zr->v4l_buffers.active == ZORAN_FREE) | ||
| 2183 | return res; | ||
| 2184 | |||
| 2185 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 2186 | /* unload capture */ | ||
| 2187 | if (zr->v4l_memgrab_active) { | ||
| 2188 | |||
| 2189 | zr36057_set_memgrab(zr, 0); | ||
| 2190 | } | ||
| 2191 | |||
| 2192 | for (i = 0; i < fh->buffers.num_buffers; i++) | ||
| 2193 | zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER; | ||
| 2194 | fh->buffers = zr->v4l_buffers; | ||
| 2195 | |||
| 2196 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
| 2197 | |||
| 2198 | zr->v4l_grab_seq = 0; | ||
| 2199 | zr->v4l_pend_head = zr->v4l_pend_tail = 0; | ||
| 2200 | zr->v4l_sync_tail = 0; | ||
| 2201 | |||
| 2202 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 2203 | |||
| 2204 | break; | ||
| 2205 | |||
| 2206 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 2207 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 2208 | if (fh->buffers.active == ZORAN_FREE && | ||
| 2209 | zr->jpg_buffers.active != ZORAN_FREE) { | ||
| 2210 | return -EPERM; /* stay off other's settings! */ | ||
| 2211 | } | ||
| 2212 | if (zr->jpg_buffers.active == ZORAN_FREE) | ||
| 2213 | return res; | ||
| 2214 | |||
| 2215 | res = jpg_qbuf(fh, -1, | ||
| 2216 | (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ? | ||
| 2217 | BUZ_MODE_MOTION_COMPRESS : | ||
| 2218 | BUZ_MODE_MOTION_DECOMPRESS); | ||
| 2219 | if (res) | ||
| 2220 | return res; | ||
| 2221 | break; | ||
| 2222 | default: | ||
| 2223 | dprintk(1, KERN_ERR | ||
| 2224 | "%s: VIDIOC_STREAMOFF - invalid map mode %d\n", | ||
| 2225 | ZR_DEVNAME(zr), fh->map_mode); | ||
| 2226 | res = -EINVAL; | ||
| 2227 | break; | ||
| 2228 | } | ||
| 2229 | return res; | ||
| 2230 | } | ||
| 2231 | static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std) | ||
| 2232 | { | ||
| 2233 | struct zoran_fh *fh = __fh; | ||
| 2234 | struct zoran *zr = fh->zr; | ||
| 2235 | |||
| 2236 | *std = zr->norm; | ||
| 2237 | return 0; | ||
| 2238 | } | ||
| 2239 | |||
| 2240 | static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id std) | ||
| 2241 | { | ||
| 2242 | struct zoran_fh *fh = __fh; | ||
| 2243 | struct zoran *zr = fh->zr; | ||
| 2244 | int res = 0; | ||
| 2245 | |||
| 2246 | res = zoran_set_norm(zr, std); | ||
| 2247 | if (res) | ||
| 2248 | return res; | ||
| 2249 | |||
| 2250 | return wait_grab_pending(zr); | ||
| 2251 | } | ||
| 2252 | |||
| 2253 | static int zoran_enum_input(struct file *file, void *__fh, | ||
| 2254 | struct v4l2_input *inp) | ||
| 2255 | { | ||
| 2256 | struct zoran_fh *fh = __fh; | ||
| 2257 | struct zoran *zr = fh->zr; | ||
| 2258 | |||
| 2259 | if (inp->index >= zr->card.inputs) | ||
| 2260 | return -EINVAL; | ||
| 2261 | |||
| 2262 | strncpy(inp->name, zr->card.input[inp->index].name, | ||
| 2263 | sizeof(inp->name) - 1); | ||
| 2264 | inp->type = V4L2_INPUT_TYPE_CAMERA; | ||
| 2265 | inp->std = V4L2_STD_ALL; | ||
| 2266 | |||
| 2267 | /* Get status of video decoder */ | ||
| 2268 | decoder_call(zr, video, g_input_status, &inp->status); | ||
| 2269 | return 0; | ||
| 2270 | } | ||
| 2271 | |||
| 2272 | static int zoran_g_input(struct file *file, void *__fh, unsigned int *input) | ||
| 2273 | { | ||
| 2274 | struct zoran_fh *fh = __fh; | ||
| 2275 | struct zoran *zr = fh->zr; | ||
| 2276 | |||
| 2277 | *input = zr->input; | ||
| 2278 | |||
| 2279 | return 0; | ||
| 2280 | } | ||
| 2281 | |||
| 2282 | static int zoran_s_input(struct file *file, void *__fh, unsigned int input) | ||
| 2283 | { | ||
| 2284 | struct zoran_fh *fh = __fh; | ||
| 2285 | struct zoran *zr = fh->zr; | ||
| 2286 | int res; | ||
| 2287 | |||
| 2288 | res = zoran_set_input(zr, input); | ||
| 2289 | if (res) | ||
| 2290 | return res; | ||
| 2291 | |||
| 2292 | /* Make sure the changes come into effect */ | ||
| 2293 | return wait_grab_pending(zr); | ||
| 2294 | } | ||
| 2295 | |||
| 2296 | static int zoran_enum_output(struct file *file, void *__fh, | ||
| 2297 | struct v4l2_output *outp) | ||
| 2298 | { | ||
| 2299 | if (outp->index != 0) | ||
| 2300 | return -EINVAL; | ||
| 2301 | |||
| 2302 | outp->index = 0; | ||
| 2303 | outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; | ||
| 2304 | strncpy(outp->name, "Autodetect", sizeof(outp->name)-1); | ||
| 2305 | |||
| 2306 | return 0; | ||
| 2307 | } | ||
| 2308 | |||
| 2309 | static int zoran_g_output(struct file *file, void *__fh, unsigned int *output) | ||
| 2310 | { | ||
| 2311 | *output = 0; | ||
| 2312 | |||
| 2313 | return 0; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | static int zoran_s_output(struct file *file, void *__fh, unsigned int output) | ||
| 2317 | { | ||
| 2318 | if (output != 0) | ||
| 2319 | return -EINVAL; | ||
| 2320 | |||
| 2321 | return 0; | ||
| 2322 | } | ||
| 2323 | |||
| 2324 | /* cropping (sub-frame capture) */ | ||
| 2325 | static int zoran_g_selection(struct file *file, void *__fh, struct v4l2_selection *sel) | ||
| 2326 | { | ||
| 2327 | struct zoran_fh *fh = __fh; | ||
| 2328 | struct zoran *zr = fh->zr; | ||
| 2329 | |||
| 2330 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
| 2331 | sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 2332 | return -EINVAL; | ||
| 2333 | |||
| 2334 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
| 2335 | dprintk(1, KERN_ERR | ||
| 2336 | "%s: VIDIOC_G_SELECTION - subcapture only supported for compressed capture\n", | ||
| 2337 | ZR_DEVNAME(zr)); | ||
| 2338 | return -EINVAL; | ||
| 2339 | } | ||
| 2340 | |||
| 2341 | switch (sel->target) { | ||
| 2342 | case V4L2_SEL_TGT_CROP: | ||
| 2343 | sel->r.top = fh->jpg_settings.img_y; | ||
| 2344 | sel->r.left = fh->jpg_settings.img_x; | ||
| 2345 | sel->r.width = fh->jpg_settings.img_width; | ||
| 2346 | sel->r.height = fh->jpg_settings.img_height; | ||
| 2347 | break; | ||
| 2348 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
| 2349 | sel->r.top = sel->r.left = 0; | ||
| 2350 | sel->r.width = BUZ_MIN_WIDTH; | ||
| 2351 | sel->r.height = BUZ_MIN_HEIGHT; | ||
| 2352 | break; | ||
| 2353 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
| 2354 | sel->r.top = sel->r.left = 0; | ||
| 2355 | sel->r.width = BUZ_MAX_WIDTH; | ||
| 2356 | sel->r.height = BUZ_MAX_HEIGHT; | ||
| 2357 | break; | ||
| 2358 | default: | ||
| 2359 | return -EINVAL; | ||
| 2360 | } | ||
| 2361 | return 0; | ||
| 2362 | } | ||
| 2363 | |||
| 2364 | static int zoran_s_selection(struct file *file, void *__fh, struct v4l2_selection *sel) | ||
| 2365 | { | ||
| 2366 | struct zoran_fh *fh = __fh; | ||
| 2367 | struct zoran *zr = fh->zr; | ||
| 2368 | struct zoran_jpg_settings settings; | ||
| 2369 | int res; | ||
| 2370 | |||
| 2371 | if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && | ||
| 2372 | sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
| 2373 | return -EINVAL; | ||
| 2374 | |||
| 2375 | if (sel->target != V4L2_SEL_TGT_CROP) | ||
| 2376 | return -EINVAL; | ||
| 2377 | |||
| 2378 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
| 2379 | dprintk(1, KERN_ERR | ||
| 2380 | "%s: VIDIOC_S_SELECTION - subcapture only supported for compressed capture\n", | ||
| 2381 | ZR_DEVNAME(zr)); | ||
| 2382 | return -EINVAL; | ||
| 2383 | } | ||
| 2384 | |||
| 2385 | settings = fh->jpg_settings; | ||
| 2386 | |||
| 2387 | if (fh->buffers.allocated) { | ||
| 2388 | dprintk(1, KERN_ERR | ||
| 2389 | "%s: VIDIOC_S_SELECTION - cannot change settings while active\n", | ||
| 2390 | ZR_DEVNAME(zr)); | ||
| 2391 | return -EBUSY; | ||
| 2392 | } | ||
| 2393 | |||
| 2394 | /* move into a form that we understand */ | ||
| 2395 | settings.img_x = sel->r.left; | ||
| 2396 | settings.img_y = sel->r.top; | ||
| 2397 | settings.img_width = sel->r.width; | ||
| 2398 | settings.img_height = sel->r.height; | ||
| 2399 | |||
| 2400 | /* check validity */ | ||
| 2401 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
| 2402 | if (res) | ||
| 2403 | return res; | ||
| 2404 | |||
| 2405 | /* accept */ | ||
| 2406 | fh->jpg_settings = settings; | ||
| 2407 | return res; | ||
| 2408 | } | ||
| 2409 | |||
| 2410 | static int zoran_g_jpegcomp(struct file *file, void *__fh, | ||
| 2411 | struct v4l2_jpegcompression *params) | ||
| 2412 | { | ||
| 2413 | struct zoran_fh *fh = __fh; | ||
| 2414 | memset(params, 0, sizeof(*params)); | ||
| 2415 | |||
| 2416 | params->quality = fh->jpg_settings.jpg_comp.quality; | ||
| 2417 | params->APPn = fh->jpg_settings.jpg_comp.APPn; | ||
| 2418 | memcpy(params->APP_data, | ||
| 2419 | fh->jpg_settings.jpg_comp.APP_data, | ||
| 2420 | fh->jpg_settings.jpg_comp.APP_len); | ||
| 2421 | params->APP_len = fh->jpg_settings.jpg_comp.APP_len; | ||
| 2422 | memcpy(params->COM_data, | ||
| 2423 | fh->jpg_settings.jpg_comp.COM_data, | ||
| 2424 | fh->jpg_settings.jpg_comp.COM_len); | ||
| 2425 | params->COM_len = fh->jpg_settings.jpg_comp.COM_len; | ||
| 2426 | params->jpeg_markers = | ||
| 2427 | fh->jpg_settings.jpg_comp.jpeg_markers; | ||
| 2428 | |||
| 2429 | return 0; | ||
| 2430 | } | ||
| 2431 | |||
| 2432 | static int zoran_s_jpegcomp(struct file *file, void *__fh, | ||
| 2433 | const struct v4l2_jpegcompression *params) | ||
| 2434 | { | ||
| 2435 | struct zoran_fh *fh = __fh; | ||
| 2436 | struct zoran *zr = fh->zr; | ||
| 2437 | int res = 0; | ||
| 2438 | struct zoran_jpg_settings settings; | ||
| 2439 | |||
| 2440 | settings = fh->jpg_settings; | ||
| 2441 | |||
| 2442 | settings.jpg_comp = *params; | ||
| 2443 | |||
| 2444 | if (fh->buffers.active != ZORAN_FREE) { | ||
| 2445 | dprintk(1, KERN_WARNING | ||
| 2446 | "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n", | ||
| 2447 | ZR_DEVNAME(zr)); | ||
| 2448 | return -EBUSY; | ||
| 2449 | } | ||
| 2450 | |||
| 2451 | res = zoran_check_jpg_settings(zr, &settings, 0); | ||
| 2452 | if (res) | ||
| 2453 | return res; | ||
| 2454 | if (!fh->buffers.allocated) | ||
| 2455 | fh->buffers.buffer_size = | ||
| 2456 | zoran_v4l2_calc_bufsize(&fh->jpg_settings); | ||
| 2457 | fh->jpg_settings.jpg_comp = settings.jpg_comp; | ||
| 2458 | return res; | ||
| 2459 | } | ||
| 2460 | |||
| 2461 | static __poll_t | ||
| 2462 | zoran_poll (struct file *file, | ||
| 2463 | poll_table *wait) | ||
| 2464 | { | ||
| 2465 | struct zoran_fh *fh = file->private_data; | ||
| 2466 | struct zoran *zr = fh->zr; | ||
| 2467 | __poll_t res = v4l2_ctrl_poll(file, wait); | ||
| 2468 | int frame; | ||
| 2469 | unsigned long flags; | ||
| 2470 | |||
| 2471 | /* we should check whether buffers are ready to be synced on | ||
| 2472 | * (w/o waits - O_NONBLOCK) here | ||
| 2473 | * if ready for read (sync), return EPOLLIN|EPOLLRDNORM, | ||
| 2474 | * if ready for write (sync), return EPOLLOUT|EPOLLWRNORM, | ||
| 2475 | * if error, return EPOLLERR, | ||
| 2476 | * if no buffers queued or so, return EPOLLNVAL | ||
| 2477 | */ | ||
| 2478 | |||
| 2479 | switch (fh->map_mode) { | ||
| 2480 | case ZORAN_MAP_MODE_RAW: | ||
| 2481 | poll_wait(file, &zr->v4l_capq, wait); | ||
| 2482 | frame = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME]; | ||
| 2483 | |||
| 2484 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 2485 | dprintk(3, | ||
| 2486 | KERN_DEBUG | ||
| 2487 | "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", | ||
| 2488 | ZR_DEVNAME(zr), __func__, | ||
| 2489 | "FAL"[fh->buffers.active], zr->v4l_sync_tail, | ||
| 2490 | "UPMD"[zr->v4l_buffers.buffer[frame].state], | ||
| 2491 | zr->v4l_pend_tail, zr->v4l_pend_head); | ||
| 2492 | /* Process is the one capturing? */ | ||
| 2493 | if (fh->buffers.active != ZORAN_FREE && | ||
| 2494 | /* Buffer ready to DQBUF? */ | ||
| 2495 | zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE) | ||
| 2496 | res |= EPOLLIN | EPOLLRDNORM; | ||
| 2497 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 2498 | |||
| 2499 | break; | ||
| 2500 | |||
| 2501 | case ZORAN_MAP_MODE_JPG_REC: | ||
| 2502 | case ZORAN_MAP_MODE_JPG_PLAY: | ||
| 2503 | poll_wait(file, &zr->jpg_capq, wait); | ||
| 2504 | frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME]; | ||
| 2505 | |||
| 2506 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 2507 | dprintk(3, | ||
| 2508 | KERN_DEBUG | ||
| 2509 | "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", | ||
| 2510 | ZR_DEVNAME(zr), __func__, | ||
| 2511 | "FAL"[fh->buffers.active], zr->jpg_que_tail, | ||
| 2512 | "UPMD"[zr->jpg_buffers.buffer[frame].state], | ||
| 2513 | zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); | ||
| 2514 | if (fh->buffers.active != ZORAN_FREE && | ||
| 2515 | zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) { | ||
| 2516 | if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) | ||
| 2517 | res |= EPOLLIN | EPOLLRDNORM; | ||
| 2518 | else | ||
| 2519 | res |= EPOLLOUT | EPOLLWRNORM; | ||
| 2520 | } | ||
| 2521 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 2522 | |||
| 2523 | break; | ||
| 2524 | |||
| 2525 | default: | ||
| 2526 | dprintk(1, | ||
| 2527 | KERN_ERR | ||
| 2528 | "%s: %s - internal error, unknown map_mode=%d\n", | ||
| 2529 | ZR_DEVNAME(zr), __func__, fh->map_mode); | ||
| 2530 | res |= EPOLLERR; | ||
| 2531 | } | ||
| 2532 | |||
| 2533 | return res; | ||
| 2534 | } | ||
| 2535 | |||
| 2536 | |||
| 2537 | /* | ||
| 2538 | * This maps the buffers to user space. | ||
| 2539 | * | ||
| 2540 | * Depending on the state of fh->map_mode | ||
| 2541 | * the V4L or the MJPEG buffers are mapped | ||
| 2542 | * per buffer or all together | ||
| 2543 | * | ||
| 2544 | * Note that we need to connect to some | ||
| 2545 | * unmap signal event to unmap the de-allocate | ||
| 2546 | * the buffer accordingly (zoran_vm_close()) | ||
| 2547 | */ | ||
| 2548 | |||
| 2549 | static void | ||
| 2550 | zoran_vm_open (struct vm_area_struct *vma) | ||
| 2551 | { | ||
| 2552 | struct zoran_mapping *map = vma->vm_private_data; | ||
| 2553 | atomic_inc(&map->count); | ||
| 2554 | } | ||
| 2555 | |||
| 2556 | static void | ||
| 2557 | zoran_vm_close (struct vm_area_struct *vma) | ||
| 2558 | { | ||
| 2559 | struct zoran_mapping *map = vma->vm_private_data; | ||
| 2560 | struct zoran_fh *fh = map->fh; | ||
| 2561 | struct zoran *zr = fh->zr; | ||
| 2562 | int i; | ||
| 2563 | |||
| 2564 | dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr), | ||
| 2565 | __func__, mode_name(fh->map_mode)); | ||
| 2566 | |||
| 2567 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
| 2568 | if (fh->buffers.buffer[i].map == map) | ||
| 2569 | fh->buffers.buffer[i].map = NULL; | ||
| 2570 | } | ||
| 2571 | kfree(map); | ||
| 2572 | |||
| 2573 | /* Any buffers still mapped? */ | ||
| 2574 | for (i = 0; i < fh->buffers.num_buffers; i++) { | ||
| 2575 | if (fh->buffers.buffer[i].map) { | ||
| 2576 | return; | ||
| 2577 | } | ||
| 2578 | } | ||
| 2579 | |||
| 2580 | dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr), | ||
| 2581 | __func__, mode_name(fh->map_mode)); | ||
| 2582 | |||
| 2583 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
| 2584 | if (fh->buffers.active != ZORAN_FREE) { | ||
| 2585 | unsigned long flags; | ||
| 2586 | |||
| 2587 | spin_lock_irqsave(&zr->spinlock, flags); | ||
| 2588 | zr36057_set_memgrab(zr, 0); | ||
| 2589 | zr->v4l_buffers.allocated = 0; | ||
| 2590 | zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
| 2591 | spin_unlock_irqrestore(&zr->spinlock, flags); | ||
| 2592 | } | ||
| 2593 | v4l_fbuffer_free(fh); | ||
| 2594 | } else { | ||
| 2595 | if (fh->buffers.active != ZORAN_FREE) { | ||
| 2596 | jpg_qbuf(fh, -1, zr->codec_mode); | ||
| 2597 | zr->jpg_buffers.allocated = 0; | ||
| 2598 | zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE; | ||
| 2599 | } | ||
| 2600 | jpg_fbuffer_free(fh); | ||
| 2601 | } | ||
| 2602 | } | ||
| 2603 | |||
| 2604 | static const struct vm_operations_struct zoran_vm_ops = { | ||
| 2605 | .open = zoran_vm_open, | ||
| 2606 | .close = zoran_vm_close, | ||
| 2607 | }; | ||
| 2608 | |||
| 2609 | static int | ||
| 2610 | zoran_mmap (struct file *file, | ||
| 2611 | struct vm_area_struct *vma) | ||
| 2612 | { | ||
| 2613 | struct zoran_fh *fh = file->private_data; | ||
| 2614 | struct zoran *zr = fh->zr; | ||
| 2615 | unsigned long size = (vma->vm_end - vma->vm_start); | ||
| 2616 | unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; | ||
| 2617 | int i, j; | ||
| 2618 | unsigned long page, start = vma->vm_start, todo, pos, fraglen; | ||
| 2619 | int first, last; | ||
| 2620 | struct zoran_mapping *map; | ||
| 2621 | int res = 0; | ||
| 2622 | |||
| 2623 | dprintk(3, | ||
| 2624 | KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n", | ||
| 2625 | ZR_DEVNAME(zr), __func__, | ||
| 2626 | mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size); | ||
| 2627 | |||
| 2628 | if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) || | ||
| 2629 | !(vma->vm_flags & VM_WRITE)) { | ||
| 2630 | dprintk(1, | ||
| 2631 | KERN_ERR | ||
| 2632 | "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n", | ||
| 2633 | ZR_DEVNAME(zr), __func__); | ||
| 2634 | return -EINVAL; | ||
| 2635 | } | ||
| 2636 | |||
| 2637 | if (!fh->buffers.allocated) { | ||
| 2638 | dprintk(1, | ||
| 2639 | KERN_ERR | ||
| 2640 | "%s: %s(%s) - buffers not yet allocated\n", | ||
| 2641 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode)); | ||
| 2642 | return -ENOMEM; | ||
| 2643 | } | ||
| 2644 | |||
| 2645 | first = offset / fh->buffers.buffer_size; | ||
| 2646 | last = first - 1 + size / fh->buffers.buffer_size; | ||
| 2647 | if (offset % fh->buffers.buffer_size != 0 || | ||
| 2648 | size % fh->buffers.buffer_size != 0 || first < 0 || | ||
| 2649 | last < 0 || first >= fh->buffers.num_buffers || | ||
| 2650 | last >= fh->buffers.buffer_size) { | ||
| 2651 | dprintk(1, | ||
| 2652 | KERN_ERR | ||
| 2653 | "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n", | ||
| 2654 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size, | ||
| 2655 | fh->buffers.buffer_size, | ||
| 2656 | fh->buffers.num_buffers); | ||
| 2657 | return -EINVAL; | ||
| 2658 | } | ||
| 2659 | |||
| 2660 | /* Check if any buffers are already mapped */ | ||
| 2661 | for (i = first; i <= last; i++) { | ||
| 2662 | if (fh->buffers.buffer[i].map) { | ||
| 2663 | dprintk(1, | ||
| 2664 | KERN_ERR | ||
| 2665 | "%s: %s(%s) - buffer %d already mapped\n", | ||
| 2666 | ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i); | ||
| 2667 | return -EBUSY; | ||
| 2668 | } | ||
| 2669 | } | ||
| 2670 | |||
| 2671 | /* map these buffers */ | ||
| 2672 | map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL); | ||
| 2673 | if (!map) { | ||
| 2674 | return -ENOMEM; | ||
| 2675 | } | ||
| 2676 | map->fh = fh; | ||
| 2677 | atomic_set(&map->count, 1); | ||
| 2678 | |||
| 2679 | vma->vm_ops = &zoran_vm_ops; | ||
| 2680 | vma->vm_flags |= VM_DONTEXPAND; | ||
| 2681 | vma->vm_private_data = map; | ||
| 2682 | |||
| 2683 | if (fh->map_mode == ZORAN_MAP_MODE_RAW) { | ||
| 2684 | for (i = first; i <= last; i++) { | ||
| 2685 | todo = size; | ||
| 2686 | if (todo > fh->buffers.buffer_size) | ||
| 2687 | todo = fh->buffers.buffer_size; | ||
| 2688 | page = fh->buffers.buffer[i].v4l.fbuffer_phys; | ||
| 2689 | if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, | ||
| 2690 | todo, PAGE_SHARED)) { | ||
| 2691 | dprintk(1, | ||
| 2692 | KERN_ERR | ||
| 2693 | "%s: %s(V4L) - remap_pfn_range failed\n", | ||
| 2694 | ZR_DEVNAME(zr), __func__); | ||
| 2695 | return -EAGAIN; | ||
| 2696 | } | ||
| 2697 | size -= todo; | ||
| 2698 | start += todo; | ||
| 2699 | fh->buffers.buffer[i].map = map; | ||
| 2700 | if (size == 0) | ||
| 2701 | break; | ||
| 2702 | } | ||
| 2703 | } else { | ||
| 2704 | for (i = first; i <= last; i++) { | ||
| 2705 | for (j = 0; | ||
| 2706 | j < fh->buffers.buffer_size / PAGE_SIZE; | ||
| 2707 | j++) { | ||
| 2708 | fraglen = | ||
| 2709 | (le32_to_cpu(fh->buffers.buffer[i].jpg. | ||
| 2710 | frag_tab[2 * j + 1]) & ~1) << 1; | ||
| 2711 | todo = size; | ||
| 2712 | if (todo > fraglen) | ||
| 2713 | todo = fraglen; | ||
| 2714 | pos = | ||
| 2715 | le32_to_cpu(fh->buffers. | ||
| 2716 | buffer[i].jpg.frag_tab[2 * j]); | ||
| 2717 | /* should just be pos on i386 */ | ||
| 2718 | page = virt_to_phys(bus_to_virt(pos)) | ||
| 2719 | >> PAGE_SHIFT; | ||
| 2720 | if (remap_pfn_range(vma, start, page, | ||
| 2721 | todo, PAGE_SHARED)) { | ||
| 2722 | dprintk(1, | ||
| 2723 | KERN_ERR | ||
| 2724 | "%s: %s(V4L) - remap_pfn_range failed\n", | ||
| 2725 | ZR_DEVNAME(zr), __func__); | ||
| 2726 | return -EAGAIN; | ||
| 2727 | } | ||
| 2728 | size -= todo; | ||
| 2729 | start += todo; | ||
| 2730 | if (size == 0) | ||
| 2731 | break; | ||
| 2732 | if (le32_to_cpu(fh->buffers.buffer[i].jpg. | ||
| 2733 | frag_tab[2 * j + 1]) & 1) | ||
| 2734 | break; /* was last fragment */ | ||
| 2735 | } | ||
| 2736 | fh->buffers.buffer[i].map = map; | ||
| 2737 | if (size == 0) | ||
| 2738 | break; | ||
| 2739 | |||
| 2740 | } | ||
| 2741 | } | ||
| 2742 | return res; | ||
| 2743 | } | ||
| 2744 | |||
| 2745 | static const struct v4l2_ioctl_ops zoran_ioctl_ops = { | ||
| 2746 | .vidioc_querycap = zoran_querycap, | ||
| 2747 | .vidioc_s_selection = zoran_s_selection, | ||
| 2748 | .vidioc_g_selection = zoran_g_selection, | ||
| 2749 | .vidioc_enum_input = zoran_enum_input, | ||
| 2750 | .vidioc_g_input = zoran_g_input, | ||
| 2751 | .vidioc_s_input = zoran_s_input, | ||
| 2752 | .vidioc_enum_output = zoran_enum_output, | ||
| 2753 | .vidioc_g_output = zoran_g_output, | ||
| 2754 | .vidioc_s_output = zoran_s_output, | ||
| 2755 | .vidioc_g_fbuf = zoran_g_fbuf, | ||
| 2756 | .vidioc_s_fbuf = zoran_s_fbuf, | ||
| 2757 | .vidioc_g_std = zoran_g_std, | ||
| 2758 | .vidioc_s_std = zoran_s_std, | ||
| 2759 | .vidioc_g_jpegcomp = zoran_g_jpegcomp, | ||
| 2760 | .vidioc_s_jpegcomp = zoran_s_jpegcomp, | ||
| 2761 | .vidioc_overlay = zoran_overlay, | ||
| 2762 | .vidioc_reqbufs = zoran_reqbufs, | ||
| 2763 | .vidioc_querybuf = zoran_querybuf, | ||
| 2764 | .vidioc_qbuf = zoran_qbuf, | ||
| 2765 | .vidioc_dqbuf = zoran_dqbuf, | ||
| 2766 | .vidioc_streamon = zoran_streamon, | ||
| 2767 | .vidioc_streamoff = zoran_streamoff, | ||
| 2768 | .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, | ||
| 2769 | .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, | ||
| 2770 | .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, | ||
| 2771 | .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, | ||
| 2772 | .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, | ||
| 2773 | .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, | ||
| 2774 | .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, | ||
| 2775 | .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, | ||
| 2776 | .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, | ||
| 2777 | .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, | ||
| 2778 | .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, | ||
| 2779 | .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, | ||
| 2780 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
| 2781 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
| 2782 | }; | ||
| 2783 | |||
| 2784 | static const struct v4l2_file_operations zoran_fops = { | ||
| 2785 | .owner = THIS_MODULE, | ||
| 2786 | .open = zoran_open, | ||
| 2787 | .release = zoran_close, | ||
| 2788 | .unlocked_ioctl = video_ioctl2, | ||
| 2789 | .mmap = zoran_mmap, | ||
| 2790 | .poll = zoran_poll, | ||
| 2791 | }; | ||
| 2792 | |||
| 2793 | const struct video_device zoran_template = { | ||
| 2794 | .name = ZORAN_NAME, | ||
| 2795 | .fops = &zoran_fops, | ||
| 2796 | .ioctl_ops = &zoran_ioctl_ops, | ||
| 2797 | .release = &zoran_vdev_release, | ||
| 2798 | .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, | ||
| 2799 | }; | ||
| 2800 | |||
diff --git a/drivers/staging/media/zoran/zoran_procfs.c b/drivers/staging/media/zoran/zoran_procfs.c deleted file mode 100644 index 941f73fe323b..000000000000 --- a/drivers/staging/media/zoran/zoran_procfs.c +++ /dev/null | |||
| @@ -1,211 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles the procFS entries (/proc/ZORAN[%d]) | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/vmalloc.h> | ||
| 20 | |||
| 21 | #include <linux/proc_fs.h> | ||
| 22 | #include <linux/pci.h> | ||
| 23 | #include <linux/i2c.h> | ||
| 24 | #include <linux/i2c-algo-bit.h> | ||
| 25 | #include <linux/videodev2.h> | ||
| 26 | #include <linux/spinlock.h> | ||
| 27 | #include <linux/sem.h> | ||
| 28 | #include <linux/seq_file.h> | ||
| 29 | |||
| 30 | #include <linux/ctype.h> | ||
| 31 | #include <linux/poll.h> | ||
| 32 | #include <asm/io.h> | ||
| 33 | |||
| 34 | #include "videocodec.h" | ||
| 35 | #include "zoran.h" | ||
| 36 | #include "zoran_procfs.h" | ||
| 37 | #include "zoran_card.h" | ||
| 38 | |||
| 39 | #ifdef CONFIG_PROC_FS | ||
| 40 | struct procfs_params_zr36067 { | ||
| 41 | char *name; | ||
| 42 | short reg; | ||
| 43 | u32 mask; | ||
| 44 | short bit; | ||
| 45 | }; | ||
| 46 | |||
| 47 | static const struct procfs_params_zr36067 zr67[] = { | ||
| 48 | {"HSPol", 0x000, 1, 30}, | ||
| 49 | {"HStart", 0x000, 0x3ff, 10}, | ||
| 50 | {"HEnd", 0x000, 0x3ff, 0}, | ||
| 51 | |||
| 52 | {"VSPol", 0x004, 1, 30}, | ||
| 53 | {"VStart", 0x004, 0x3ff, 10}, | ||
| 54 | {"VEnd", 0x004, 0x3ff, 0}, | ||
| 55 | |||
| 56 | {"ExtFl", 0x008, 1, 26}, | ||
| 57 | {"TopField", 0x008, 1, 25}, | ||
| 58 | {"VCLKPol", 0x008, 1, 24}, | ||
| 59 | {"DupFld", 0x008, 1, 20}, | ||
| 60 | {"LittleEndian", 0x008, 1, 0}, | ||
| 61 | |||
| 62 | {"HsyncStart", 0x10c, 0xffff, 16}, | ||
| 63 | {"LineTot", 0x10c, 0xffff, 0}, | ||
| 64 | |||
| 65 | {"NAX", 0x110, 0xffff, 16}, | ||
| 66 | {"PAX", 0x110, 0xffff, 0}, | ||
| 67 | |||
| 68 | {"NAY", 0x114, 0xffff, 16}, | ||
| 69 | {"PAY", 0x114, 0xffff, 0}, | ||
| 70 | |||
| 71 | /* {"",,,}, */ | ||
| 72 | |||
| 73 | {NULL, 0, 0, 0}, | ||
| 74 | }; | ||
| 75 | |||
| 76 | static void | ||
| 77 | setparam (struct zoran *zr, | ||
| 78 | char *name, | ||
| 79 | char *sval) | ||
| 80 | { | ||
| 81 | int i = 0, reg0, reg, val; | ||
| 82 | |||
| 83 | while (zr67[i].name != NULL) { | ||
| 84 | if (!strncmp(name, zr67[i].name, strlen(zr67[i].name))) { | ||
| 85 | reg = reg0 = btread(zr67[i].reg); | ||
| 86 | reg &= ~(zr67[i].mask << zr67[i].bit); | ||
| 87 | if (!isdigit(sval[0])) | ||
| 88 | break; | ||
| 89 | val = simple_strtoul(sval, NULL, 0); | ||
| 90 | if ((val & ~zr67[i].mask)) | ||
| 91 | break; | ||
| 92 | reg |= (val & zr67[i].mask) << zr67[i].bit; | ||
| 93 | dprintk(4, | ||
| 94 | KERN_INFO | ||
| 95 | "%s: setparam: setting ZR36067 register 0x%03x: 0x%08x=>0x%08x %s=%d\n", | ||
| 96 | ZR_DEVNAME(zr), zr67[i].reg, reg0, reg, | ||
| 97 | zr67[i].name, val); | ||
| 98 | btwrite(reg, zr67[i].reg); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | i++; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | static int zoran_show(struct seq_file *p, void *v) | ||
| 106 | { | ||
| 107 | struct zoran *zr = p->private; | ||
| 108 | int i; | ||
| 109 | |||
| 110 | seq_printf(p, "ZR36067 registers:\n"); | ||
| 111 | for (i = 0; i < 0x130; i += 16) | ||
| 112 | seq_printf(p, "%03X %08X %08X %08X %08X \n", i, | ||
| 113 | btread(i), btread(i+4), btread(i+8), btread(i+12)); | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int zoran_open(struct inode *inode, struct file *file) | ||
| 118 | { | ||
| 119 | struct zoran *data = PDE_DATA(inode); | ||
| 120 | return single_open(file, zoran_show, data); | ||
| 121 | } | ||
| 122 | |||
| 123 | static ssize_t zoran_write(struct file *file, const char __user *buffer, | ||
| 124 | size_t count, loff_t *ppos) | ||
| 125 | { | ||
| 126 | struct zoran *zr = PDE_DATA(file_inode(file)); | ||
| 127 | char *string, *sp; | ||
| 128 | char *line, *ldelim, *varname, *svar, *tdelim; | ||
| 129 | |||
| 130 | if (count > 32768) /* Stupidity filter */ | ||
| 131 | return -EINVAL; | ||
| 132 | |||
| 133 | string = sp = vmalloc(count + 1); | ||
| 134 | if (!string) { | ||
| 135 | dprintk(1, | ||
| 136 | KERN_ERR | ||
| 137 | "%s: write_proc: can not allocate memory\n", | ||
| 138 | ZR_DEVNAME(zr)); | ||
| 139 | return -ENOMEM; | ||
| 140 | } | ||
| 141 | if (copy_from_user(string, buffer, count)) { | ||
| 142 | vfree (string); | ||
| 143 | return -EFAULT; | ||
| 144 | } | ||
| 145 | string[count] = 0; | ||
| 146 | dprintk(4, KERN_INFO "%s: write_proc: name=%pD count=%zu zr=%p\n", | ||
| 147 | ZR_DEVNAME(zr), file, count, zr); | ||
| 148 | ldelim = " \t\n"; | ||
| 149 | tdelim = "="; | ||
| 150 | line = strpbrk(sp, ldelim); | ||
| 151 | while (line) { | ||
| 152 | *line = 0; | ||
| 153 | svar = strpbrk(sp, tdelim); | ||
| 154 | if (svar) { | ||
| 155 | *svar = 0; | ||
| 156 | varname = sp; | ||
| 157 | svar++; | ||
| 158 | setparam(zr, varname, svar); | ||
| 159 | } | ||
| 160 | sp = line + 1; | ||
| 161 | line = strpbrk(sp, ldelim); | ||
| 162 | } | ||
| 163 | vfree(string); | ||
| 164 | |||
| 165 | return count; | ||
| 166 | } | ||
| 167 | |||
| 168 | static const struct file_operations zoran_operations = { | ||
| 169 | .owner = THIS_MODULE, | ||
| 170 | .open = zoran_open, | ||
| 171 | .read = seq_read, | ||
| 172 | .write = zoran_write, | ||
| 173 | .llseek = seq_lseek, | ||
| 174 | .release = single_release, | ||
| 175 | }; | ||
| 176 | #endif | ||
| 177 | |||
| 178 | int | ||
| 179 | zoran_proc_init (struct zoran *zr) | ||
| 180 | { | ||
| 181 | #ifdef CONFIG_PROC_FS | ||
| 182 | char name[8]; | ||
| 183 | |||
| 184 | snprintf(name, 7, "zoran%d", zr->id); | ||
| 185 | zr->zoran_proc = proc_create_data(name, 0, NULL, &zoran_operations, zr); | ||
| 186 | if (zr->zoran_proc != NULL) { | ||
| 187 | dprintk(2, | ||
| 188 | KERN_INFO | ||
| 189 | "%s: procfs entry /proc/%s allocated. data=%p\n", | ||
| 190 | ZR_DEVNAME(zr), name, zr); | ||
| 191 | } else { | ||
| 192 | dprintk(1, KERN_ERR "%s: Unable to initialise /proc/%s\n", | ||
| 193 | ZR_DEVNAME(zr), name); | ||
| 194 | return 1; | ||
| 195 | } | ||
| 196 | #endif | ||
| 197 | return 0; | ||
| 198 | } | ||
| 199 | |||
| 200 | void | ||
| 201 | zoran_proc_cleanup (struct zoran *zr) | ||
| 202 | { | ||
| 203 | #ifdef CONFIG_PROC_FS | ||
| 204 | char name[8]; | ||
| 205 | |||
| 206 | snprintf(name, 7, "zoran%d", zr->id); | ||
| 207 | if (zr->zoran_proc) | ||
| 208 | remove_proc_entry(name, NULL); | ||
| 209 | zr->zoran_proc = NULL; | ||
| 210 | #endif | ||
| 211 | } | ||
diff --git a/drivers/staging/media/zoran/zoran_procfs.h b/drivers/staging/media/zoran/zoran_procfs.h deleted file mode 100644 index db9f642c851a..000000000000 --- a/drivers/staging/media/zoran/zoran_procfs.h +++ /dev/null | |||
| @@ -1,22 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran zr36057/zr36067 PCI controller driver, for the | ||
| 4 | * Pinnacle/Miro DC10/DC10+/DC30/DC30+, Iomega Buz, Linux | ||
| 5 | * Media Labs LML33/LML33R10. | ||
| 6 | * | ||
| 7 | * This part handles card-specific data and detection | ||
| 8 | * | ||
| 9 | * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> | ||
| 10 | * | ||
| 11 | * Currently maintained by: | ||
| 12 | * Ronald Bultje <rbultje@ronald.bitfreak.net> | ||
| 13 | * Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 14 | * Mailinglist <mjpeg-users@lists.sf.net> | ||
| 15 | */ | ||
| 16 | #ifndef __ZORAN_PROCFS_H__ | ||
| 17 | #define __ZORAN_PROCFS_H__ | ||
| 18 | |||
| 19 | extern int zoran_proc_init(struct zoran *zr); | ||
| 20 | extern void zoran_proc_cleanup(struct zoran *zr); | ||
| 21 | |||
| 22 | #endif /* __ZORAN_PROCFS_H__ */ | ||
diff --git a/drivers/staging/media/zoran/zr36016.c b/drivers/staging/media/zoran/zr36016.c deleted file mode 100644 index b300a0abe95f..000000000000 --- a/drivers/staging/media/zoran/zr36016.c +++ /dev/null | |||
| @@ -1,500 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36016 basic configuration functions | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
| 6 | */ | ||
| 7 | #define ZR016_VERSION "v0.7" | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | |||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/wait.h> | ||
| 16 | |||
| 17 | /* I/O commands, error codes */ | ||
| 18 | #include <asm/io.h> | ||
| 19 | |||
| 20 | /* v4l API */ | ||
| 21 | |||
| 22 | /* headerfile of this module */ | ||
| 23 | #include "zr36016.h" | ||
| 24 | |||
| 25 | /* codec io API */ | ||
| 26 | #include "videocodec.h" | ||
| 27 | |||
| 28 | /* it doesn't make sense to have more than 20 or so, | ||
| 29 | just to prevent some unwanted loops */ | ||
| 30 | #define MAX_CODECS 20 | ||
| 31 | |||
| 32 | /* amount of chips attached via this driver */ | ||
| 33 | static int zr36016_codecs; | ||
| 34 | |||
| 35 | /* debugging is available via module parameter */ | ||
| 36 | static int debug; | ||
| 37 | module_param(debug, int, 0); | ||
| 38 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
| 39 | |||
| 40 | #define dprintk(num, format, args...) \ | ||
| 41 | do { \ | ||
| 42 | if (debug >= num) \ | ||
| 43 | printk(format, ##args); \ | ||
| 44 | } while (0) | ||
| 45 | |||
| 46 | /* ========================================================================= | ||
| 47 | Local hardware I/O functions: | ||
| 48 | |||
| 49 | read/write via codec layer (registers are located in the master device) | ||
| 50 | ========================================================================= */ | ||
| 51 | |||
| 52 | /* read and write functions */ | ||
| 53 | static u8 | ||
| 54 | zr36016_read (struct zr36016 *ptr, | ||
| 55 | u16 reg) | ||
| 56 | { | ||
| 57 | u8 value = 0; | ||
| 58 | |||
| 59 | // just in case something is wrong... | ||
| 60 | if (ptr->codec->master_data->readreg) | ||
| 61 | value = | ||
| 62 | (ptr->codec->master_data-> | ||
| 63 | readreg(ptr->codec, reg)) & 0xFF; | ||
| 64 | else | ||
| 65 | dprintk(1, | ||
| 66 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
| 67 | ptr->name); | ||
| 68 | |||
| 69 | dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, | ||
| 70 | value); | ||
| 71 | |||
| 72 | return value; | ||
| 73 | } | ||
| 74 | |||
| 75 | static void | ||
| 76 | zr36016_write (struct zr36016 *ptr, | ||
| 77 | u16 reg, | ||
| 78 | u8 value) | ||
| 79 | { | ||
| 80 | dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, | ||
| 81 | reg); | ||
| 82 | |||
| 83 | // just in case something is wrong... | ||
| 84 | if (ptr->codec->master_data->writereg) { | ||
| 85 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
| 86 | } else | ||
| 87 | dprintk(1, | ||
| 88 | KERN_ERR | ||
| 89 | "%s: invalid I/O setup, nothing written!\n", | ||
| 90 | ptr->name); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* indirect read and write functions */ | ||
| 94 | /* the 016 supports auto-addr-increment, but | ||
| 95 | * writing it all time cost not much and is safer... */ | ||
| 96 | static u8 | ||
| 97 | zr36016_readi (struct zr36016 *ptr, | ||
| 98 | u16 reg) | ||
| 99 | { | ||
| 100 | u8 value = 0; | ||
| 101 | |||
| 102 | // just in case something is wrong... | ||
| 103 | if ((ptr->codec->master_data->writereg) && | ||
| 104 | (ptr->codec->master_data->readreg)) { | ||
| 105 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR | ||
| 106 | value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA | ||
| 107 | } else | ||
| 108 | dprintk(1, | ||
| 109 | KERN_ERR | ||
| 110 | "%s: invalid I/O setup, nothing read (i)!\n", | ||
| 111 | ptr->name); | ||
| 112 | |||
| 113 | dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name, | ||
| 114 | reg, value); | ||
| 115 | return value; | ||
| 116 | } | ||
| 117 | |||
| 118 | static void | ||
| 119 | zr36016_writei (struct zr36016 *ptr, | ||
| 120 | u16 reg, | ||
| 121 | u8 value) | ||
| 122 | { | ||
| 123 | dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name, | ||
| 124 | value, reg); | ||
| 125 | |||
| 126 | // just in case something is wrong... | ||
| 127 | if (ptr->codec->master_data->writereg) { | ||
| 128 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR | ||
| 129 | ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA | ||
| 130 | } else | ||
| 131 | dprintk(1, | ||
| 132 | KERN_ERR | ||
| 133 | "%s: invalid I/O setup, nothing written (i)!\n", | ||
| 134 | ptr->name); | ||
| 135 | } | ||
| 136 | |||
| 137 | /* ========================================================================= | ||
| 138 | Local helper function: | ||
| 139 | |||
| 140 | version read | ||
| 141 | ========================================================================= */ | ||
| 142 | |||
| 143 | /* version kept in datastructure */ | ||
| 144 | static u8 | ||
| 145 | zr36016_read_version (struct zr36016 *ptr) | ||
| 146 | { | ||
| 147 | ptr->version = zr36016_read(ptr, 0) >> 4; | ||
| 148 | return ptr->version; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* ========================================================================= | ||
| 152 | Local helper function: | ||
| 153 | |||
| 154 | basic test of "connectivity", writes/reads to/from PAX-Lo register | ||
| 155 | ========================================================================= */ | ||
| 156 | |||
| 157 | static int | ||
| 158 | zr36016_basic_test (struct zr36016 *ptr) | ||
| 159 | { | ||
| 160 | if (debug) { | ||
| 161 | int i; | ||
| 162 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x55); | ||
| 163 | dprintk(1, KERN_INFO "%s: registers: ", ptr->name); | ||
| 164 | for (i = 0; i <= 0x0b; i++) | ||
| 165 | dprintk(1, "%02x ", zr36016_readi(ptr, i)); | ||
| 166 | dprintk(1, "\n"); | ||
| 167 | } | ||
| 168 | // for testing just write 0, then the default value to a register and read | ||
| 169 | // it back in both cases | ||
| 170 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x00); | ||
| 171 | if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) { | ||
| 172 | dprintk(1, | ||
| 173 | KERN_ERR | ||
| 174 | "%s: attach failed, can't connect to vfe processor!\n", | ||
| 175 | ptr->name); | ||
| 176 | return -ENXIO; | ||
| 177 | } | ||
| 178 | zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0); | ||
| 179 | if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) { | ||
| 180 | dprintk(1, | ||
| 181 | KERN_ERR | ||
| 182 | "%s: attach failed, can't connect to vfe processor!\n", | ||
| 183 | ptr->name); | ||
| 184 | return -ENXIO; | ||
| 185 | } | ||
| 186 | // we allow version numbers from 0-3, should be enough, though | ||
| 187 | zr36016_read_version(ptr); | ||
| 188 | if (ptr->version & 0x0c) { | ||
| 189 | dprintk(1, | ||
| 190 | KERN_ERR | ||
| 191 | "%s: attach failed, suspicious version %d found...\n", | ||
| 192 | ptr->name, ptr->version); | ||
| 193 | return -ENXIO; | ||
| 194 | } | ||
| 195 | |||
| 196 | return 0; /* looks good! */ | ||
| 197 | } | ||
| 198 | |||
| 199 | /* ========================================================================= | ||
| 200 | Local helper function: | ||
| 201 | |||
| 202 | simple loop for pushing the init datasets - NO USE -- | ||
| 203 | ========================================================================= */ | ||
| 204 | |||
| 205 | #if 0 | ||
| 206 | static int zr36016_pushit (struct zr36016 *ptr, | ||
| 207 | u16 startreg, | ||
| 208 | u16 len, | ||
| 209 | const char *data) | ||
| 210 | { | ||
| 211 | int i=0; | ||
| 212 | |||
| 213 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", | ||
| 214 | ptr->name, startreg,len); | ||
| 215 | while (i<len) { | ||
| 216 | zr36016_writei(ptr, startreg++, data[i++]); | ||
| 217 | } | ||
| 218 | |||
| 219 | return i; | ||
| 220 | } | ||
| 221 | #endif | ||
| 222 | |||
| 223 | /* ========================================================================= | ||
| 224 | Basic datasets & init: | ||
| 225 | |||
| 226 | //TODO// | ||
| 227 | ========================================================================= */ | ||
| 228 | |||
| 229 | static void | ||
| 230 | zr36016_init (struct zr36016 *ptr) | ||
| 231 | { | ||
| 232 | // stop any processing | ||
| 233 | zr36016_write(ptr, ZR016_GOSTOP, 0); | ||
| 234 | |||
| 235 | // mode setup (yuv422 in and out, compression/expansuon due to mode) | ||
| 236 | zr36016_write(ptr, ZR016_MODE, | ||
| 237 | ZR016_YUV422 | ZR016_YUV422_YUV422 | | ||
| 238 | (ptr->mode == CODEC_DO_COMPRESSION ? | ||
| 239 | ZR016_COMPRESSION : ZR016_EXPANSION)); | ||
| 240 | |||
| 241 | // misc setup | ||
| 242 | zr36016_writei(ptr, ZR016I_SETUP1, | ||
| 243 | (ptr->xdec ? (ZR016_HRFL | ZR016_HORZ) : 0) | | ||
| 244 | (ptr->ydec ? ZR016_VERT : 0) | ZR016_CNTI); | ||
| 245 | zr36016_writei(ptr, ZR016I_SETUP2, ZR016_CCIR); | ||
| 246 | |||
| 247 | // Window setup | ||
| 248 | // (no extra offset for now, norm defines offset, default width height) | ||
| 249 | zr36016_writei(ptr, ZR016I_PAX_HI, ptr->width >> 8); | ||
| 250 | zr36016_writei(ptr, ZR016I_PAX_LO, ptr->width & 0xFF); | ||
| 251 | zr36016_writei(ptr, ZR016I_PAY_HI, ptr->height >> 8); | ||
| 252 | zr36016_writei(ptr, ZR016I_PAY_LO, ptr->height & 0xFF); | ||
| 253 | zr36016_writei(ptr, ZR016I_NAX_HI, ptr->xoff >> 8); | ||
| 254 | zr36016_writei(ptr, ZR016I_NAX_LO, ptr->xoff & 0xFF); | ||
| 255 | zr36016_writei(ptr, ZR016I_NAY_HI, ptr->yoff >> 8); | ||
| 256 | zr36016_writei(ptr, ZR016I_NAY_LO, ptr->yoff & 0xFF); | ||
| 257 | |||
| 258 | /* shall we continue now, please? */ | ||
| 259 | zr36016_write(ptr, ZR016_GOSTOP, 1); | ||
| 260 | } | ||
| 261 | |||
| 262 | /* ========================================================================= | ||
| 263 | CODEC API FUNCTIONS | ||
| 264 | |||
| 265 | this functions are accessed by the master via the API structure | ||
| 266 | ========================================================================= */ | ||
| 267 | |||
| 268 | /* set compression/expansion mode and launches codec - | ||
| 269 | this should be the last call from the master before starting processing */ | ||
| 270 | static int | ||
| 271 | zr36016_set_mode (struct videocodec *codec, | ||
| 272 | int mode) | ||
| 273 | { | ||
| 274 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
| 275 | |||
| 276 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
| 277 | |||
| 278 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
| 279 | return -EINVAL; | ||
| 280 | |||
| 281 | ptr->mode = mode; | ||
| 282 | zr36016_init(ptr); | ||
| 283 | |||
| 284 | return 0; | ||
| 285 | } | ||
| 286 | |||
| 287 | /* set picture size */ | ||
| 288 | static int | ||
| 289 | zr36016_set_video (struct videocodec *codec, | ||
| 290 | struct tvnorm *norm, | ||
| 291 | struct vfe_settings *cap, | ||
| 292 | struct vfe_polarity *pol) | ||
| 293 | { | ||
| 294 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
| 295 | |||
| 296 | dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n", | ||
| 297 | ptr->name, norm->HStart, norm->VStart, | ||
| 298 | cap->x, cap->y, cap->width, cap->height, | ||
| 299 | cap->decimation); | ||
| 300 | |||
| 301 | /* if () return -EINVAL; | ||
| 302 | * trust the master driver that it knows what it does - so | ||
| 303 | * we allow invalid startx/y for now ... */ | ||
| 304 | ptr->width = cap->width; | ||
| 305 | ptr->height = cap->height; | ||
| 306 | /* (Ronald) This is ugly. zoran_device.c, line 387 | ||
| 307 | * already mentions what happens if HStart is even | ||
| 308 | * (blue faces, etc., cr/cb inversed). There's probably | ||
| 309 | * some good reason why HStart is 0 instead of 1, so I'm | ||
| 310 | * leaving it to this for now, but really... This can be | ||
| 311 | * done a lot simpler */ | ||
| 312 | ptr->xoff = (norm->HStart ? norm->HStart : 1) + cap->x; | ||
| 313 | /* Something to note here (I don't understand it), setting | ||
| 314 | * VStart too high will cause the codec to 'not work'. I | ||
| 315 | * really don't get it. values of 16 (VStart) already break | ||
| 316 | * it here. Just '0' seems to work. More testing needed! */ | ||
| 317 | ptr->yoff = norm->VStart + cap->y; | ||
| 318 | /* (Ronald) dzjeeh, can't this thing do hor_decimation = 4? */ | ||
| 319 | ptr->xdec = ((cap->decimation & 0xff) == 1) ? 0 : 1; | ||
| 320 | ptr->ydec = (((cap->decimation >> 8) & 0xff) == 1) ? 0 : 1; | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | /* additional control functions */ | ||
| 326 | static int | ||
| 327 | zr36016_control (struct videocodec *codec, | ||
| 328 | int type, | ||
| 329 | int size, | ||
| 330 | void *data) | ||
| 331 | { | ||
| 332 | struct zr36016 *ptr = (struct zr36016 *) codec->data; | ||
| 333 | int *ival = (int *) data; | ||
| 334 | |||
| 335 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
| 336 | size); | ||
| 337 | |||
| 338 | switch (type) { | ||
| 339 | case CODEC_G_STATUS: /* get last status - we don't know it ... */ | ||
| 340 | if (size != sizeof(int)) | ||
| 341 | return -EFAULT; | ||
| 342 | *ival = 0; | ||
| 343 | break; | ||
| 344 | |||
| 345 | case CODEC_G_CODEC_MODE: | ||
| 346 | if (size != sizeof(int)) | ||
| 347 | return -EFAULT; | ||
| 348 | *ival = 0; | ||
| 349 | break; | ||
| 350 | |||
| 351 | case CODEC_S_CODEC_MODE: | ||
| 352 | if (size != sizeof(int)) | ||
| 353 | return -EFAULT; | ||
| 354 | if (*ival != 0) | ||
| 355 | return -EINVAL; | ||
| 356 | /* not needed, do nothing */ | ||
| 357 | return 0; | ||
| 358 | |||
| 359 | case CODEC_G_VFE: | ||
| 360 | case CODEC_S_VFE: | ||
| 361 | return 0; | ||
| 362 | |||
| 363 | case CODEC_S_MMAP: | ||
| 364 | /* not available, give an error */ | ||
| 365 | return -ENXIO; | ||
| 366 | |||
| 367 | default: | ||
| 368 | return -EINVAL; | ||
| 369 | } | ||
| 370 | |||
| 371 | return size; | ||
| 372 | } | ||
| 373 | |||
| 374 | /* ========================================================================= | ||
| 375 | Exit and unregister function: | ||
| 376 | |||
| 377 | Deinitializes Zoran's JPEG processor | ||
| 378 | ========================================================================= */ | ||
| 379 | |||
| 380 | static int | ||
| 381 | zr36016_unset (struct videocodec *codec) | ||
| 382 | { | ||
| 383 | struct zr36016 *ptr = codec->data; | ||
| 384 | |||
| 385 | if (ptr) { | ||
| 386 | /* do wee need some codec deinit here, too ???? */ | ||
| 387 | |||
| 388 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
| 389 | ptr->num); | ||
| 390 | kfree(ptr); | ||
| 391 | codec->data = NULL; | ||
| 392 | |||
| 393 | zr36016_codecs--; | ||
| 394 | return 0; | ||
| 395 | } | ||
| 396 | |||
| 397 | return -EFAULT; | ||
| 398 | } | ||
| 399 | |||
| 400 | /* ========================================================================= | ||
| 401 | Setup and registry function: | ||
| 402 | |||
| 403 | Initializes Zoran's JPEG processor | ||
| 404 | |||
| 405 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
| 406 | (the given size is determined by the processor with the video interface) | ||
| 407 | ========================================================================= */ | ||
| 408 | |||
| 409 | static int | ||
| 410 | zr36016_setup (struct videocodec *codec) | ||
| 411 | { | ||
| 412 | struct zr36016 *ptr; | ||
| 413 | int res; | ||
| 414 | |||
| 415 | dprintk(2, "zr36016: initializing VFE subsystem #%d.\n", | ||
| 416 | zr36016_codecs); | ||
| 417 | |||
| 418 | if (zr36016_codecs == MAX_CODECS) { | ||
| 419 | dprintk(1, | ||
| 420 | KERN_ERR "zr36016: Can't attach more codecs!\n"); | ||
| 421 | return -ENOSPC; | ||
| 422 | } | ||
| 423 | //mem structure init | ||
| 424 | codec->data = ptr = kzalloc(sizeof(struct zr36016), GFP_KERNEL); | ||
| 425 | if (NULL == ptr) { | ||
| 426 | dprintk(1, KERN_ERR "zr36016: Can't get enough memory!\n"); | ||
| 427 | return -ENOMEM; | ||
| 428 | } | ||
| 429 | |||
| 430 | snprintf(ptr->name, sizeof(ptr->name), "zr36016[%d]", | ||
| 431 | zr36016_codecs); | ||
| 432 | ptr->num = zr36016_codecs++; | ||
| 433 | ptr->codec = codec; | ||
| 434 | |||
| 435 | //testing | ||
| 436 | res = zr36016_basic_test(ptr); | ||
| 437 | if (res < 0) { | ||
| 438 | zr36016_unset(codec); | ||
| 439 | return res; | ||
| 440 | } | ||
| 441 | //final setup | ||
| 442 | ptr->mode = CODEC_DO_COMPRESSION; | ||
| 443 | ptr->width = 768; | ||
| 444 | ptr->height = 288; | ||
| 445 | ptr->xdec = 1; | ||
| 446 | ptr->ydec = 0; | ||
| 447 | zr36016_init(ptr); | ||
| 448 | |||
| 449 | dprintk(1, KERN_INFO "%s: codec v%d attached and running\n", | ||
| 450 | ptr->name, ptr->version); | ||
| 451 | |||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 455 | static const struct videocodec zr36016_codec = { | ||
| 456 | .owner = THIS_MODULE, | ||
| 457 | .name = "zr36016", | ||
| 458 | .magic = 0L, // magic not used | ||
| 459 | .flags = | ||
| 460 | CODEC_FLAG_HARDWARE | CODEC_FLAG_VFE | CODEC_FLAG_ENCODER | | ||
| 461 | CODEC_FLAG_DECODER, | ||
| 462 | .type = CODEC_TYPE_ZR36016, | ||
| 463 | .setup = zr36016_setup, // functionality | ||
| 464 | .unset = zr36016_unset, | ||
| 465 | .set_mode = zr36016_set_mode, | ||
| 466 | .set_video = zr36016_set_video, | ||
| 467 | .control = zr36016_control, | ||
| 468 | // others are not used | ||
| 469 | }; | ||
| 470 | |||
| 471 | /* ========================================================================= | ||
| 472 | HOOK IN DRIVER AS KERNEL MODULE | ||
| 473 | ========================================================================= */ | ||
| 474 | |||
| 475 | static int __init | ||
| 476 | zr36016_init_module (void) | ||
| 477 | { | ||
| 478 | //dprintk(1, "ZR36016 driver %s\n",ZR016_VERSION); | ||
| 479 | zr36016_codecs = 0; | ||
| 480 | return videocodec_register(&zr36016_codec); | ||
| 481 | } | ||
| 482 | |||
| 483 | static void __exit | ||
| 484 | zr36016_cleanup_module (void) | ||
| 485 | { | ||
| 486 | if (zr36016_codecs) { | ||
| 487 | dprintk(1, | ||
| 488 | "zr36016: something's wrong - %d codecs left somehow.\n", | ||
| 489 | zr36016_codecs); | ||
| 490 | } | ||
| 491 | videocodec_unregister(&zr36016_codec); | ||
| 492 | } | ||
| 493 | |||
| 494 | module_init(zr36016_init_module); | ||
| 495 | module_exit(zr36016_cleanup_module); | ||
| 496 | |||
| 497 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
| 498 | MODULE_DESCRIPTION("Driver module for ZR36016 video frontends " | ||
| 499 | ZR016_VERSION); | ||
| 500 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/media/zoran/zr36016.h b/drivers/staging/media/zoran/zr36016.h deleted file mode 100644 index 6e66581c27b2..000000000000 --- a/drivers/staging/media/zoran/zr36016.h +++ /dev/null | |||
| @@ -1,91 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36016 basic configuration functions - header file | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
| 6 | */ | ||
| 7 | #ifndef ZR36016_H | ||
| 8 | #define ZR36016_H | ||
| 9 | |||
| 10 | /* data stored for each zoran jpeg codec chip */ | ||
| 11 | struct zr36016 { | ||
| 12 | char name[32]; | ||
| 13 | int num; | ||
| 14 | /* io datastructure */ | ||
| 15 | struct videocodec *codec; | ||
| 16 | // coder status | ||
| 17 | __u8 version; | ||
| 18 | // actual coder setup | ||
| 19 | int mode; | ||
| 20 | |||
| 21 | __u16 xoff; | ||
| 22 | __u16 yoff; | ||
| 23 | __u16 width; | ||
| 24 | __u16 height; | ||
| 25 | __u16 xdec; | ||
| 26 | __u16 ydec; | ||
| 27 | }; | ||
| 28 | |||
| 29 | /* direct register addresses */ | ||
| 30 | #define ZR016_GOSTOP 0x00 | ||
| 31 | #define ZR016_MODE 0x01 | ||
| 32 | #define ZR016_IADDR 0x02 | ||
| 33 | #define ZR016_IDATA 0x03 | ||
| 34 | |||
| 35 | /* indirect register addresses */ | ||
| 36 | #define ZR016I_SETUP1 0x00 | ||
| 37 | #define ZR016I_SETUP2 0x01 | ||
| 38 | #define ZR016I_NAX_LO 0x02 | ||
| 39 | #define ZR016I_NAX_HI 0x03 | ||
| 40 | #define ZR016I_PAX_LO 0x04 | ||
| 41 | #define ZR016I_PAX_HI 0x05 | ||
| 42 | #define ZR016I_NAY_LO 0x06 | ||
| 43 | #define ZR016I_NAY_HI 0x07 | ||
| 44 | #define ZR016I_PAY_LO 0x08 | ||
| 45 | #define ZR016I_PAY_HI 0x09 | ||
| 46 | #define ZR016I_NOL_LO 0x0a | ||
| 47 | #define ZR016I_NOL_HI 0x0b | ||
| 48 | |||
| 49 | /* possible values for mode register */ | ||
| 50 | #define ZR016_RGB444_YUV444 0x00 | ||
| 51 | #define ZR016_RGB444_YUV422 0x01 | ||
| 52 | #define ZR016_RGB444_YUV411 0x02 | ||
| 53 | #define ZR016_RGB444_Y400 0x03 | ||
| 54 | #define ZR016_RGB444_RGB444 0x04 | ||
| 55 | #define ZR016_YUV444_YUV444 0x08 | ||
| 56 | #define ZR016_YUV444_YUV422 0x09 | ||
| 57 | #define ZR016_YUV444_YUV411 0x0a | ||
| 58 | #define ZR016_YUV444_Y400 0x0b | ||
| 59 | #define ZR016_YUV444_RGB444 0x0c | ||
| 60 | #define ZR016_YUV422_YUV422 0x11 | ||
| 61 | #define ZR016_YUV422_YUV411 0x12 | ||
| 62 | #define ZR016_YUV422_Y400 0x13 | ||
| 63 | #define ZR016_YUV411_YUV411 0x16 | ||
| 64 | #define ZR016_YUV411_Y400 0x17 | ||
| 65 | #define ZR016_4444_4444 0x19 | ||
| 66 | #define ZR016_100_100 0x1b | ||
| 67 | |||
| 68 | #define ZR016_RGB444 0x00 | ||
| 69 | #define ZR016_YUV444 0x20 | ||
| 70 | #define ZR016_YUV422 0x40 | ||
| 71 | |||
| 72 | #define ZR016_COMPRESSION 0x80 | ||
| 73 | #define ZR016_EXPANSION 0x80 | ||
| 74 | |||
| 75 | /* possible values for setup 1 register */ | ||
| 76 | #define ZR016_CKRT 0x80 | ||
| 77 | #define ZR016_VERT 0x40 | ||
| 78 | #define ZR016_HORZ 0x20 | ||
| 79 | #define ZR016_HRFL 0x10 | ||
| 80 | #define ZR016_DSFL 0x08 | ||
| 81 | #define ZR016_SBFL 0x04 | ||
| 82 | #define ZR016_RSTR 0x02 | ||
| 83 | #define ZR016_CNTI 0x01 | ||
| 84 | |||
| 85 | /* possible values for setup 2 register */ | ||
| 86 | #define ZR016_SYEN 0x40 | ||
| 87 | #define ZR016_CCIR 0x04 | ||
| 88 | #define ZR016_SIGN 0x02 | ||
| 89 | #define ZR016_YMCS 0x01 | ||
| 90 | |||
| 91 | #endif /*fndef ZR36016_H */ | ||
diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/staging/media/zoran/zr36050.c deleted file mode 100644 index cd58307af378..000000000000 --- a/drivers/staging/media/zoran/zr36050.c +++ /dev/null | |||
| @@ -1,880 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36050 basic configuration functions | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
| 6 | */ | ||
| 7 | #define ZR050_VERSION "v0.7.1" | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | |||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/wait.h> | ||
| 16 | |||
| 17 | /* I/O commands, error codes */ | ||
| 18 | #include <asm/io.h> | ||
| 19 | |||
| 20 | /* headerfile of this module */ | ||
| 21 | #include "zr36050.h" | ||
| 22 | |||
| 23 | /* codec io API */ | ||
| 24 | #include "videocodec.h" | ||
| 25 | |||
| 26 | /* it doesn't make sense to have more than 20 or so, | ||
| 27 | just to prevent some unwanted loops */ | ||
| 28 | #define MAX_CODECS 20 | ||
| 29 | |||
| 30 | /* amount of chips attached via this driver */ | ||
| 31 | static int zr36050_codecs; | ||
| 32 | |||
| 33 | /* debugging is available via module parameter */ | ||
| 34 | static int debug; | ||
| 35 | module_param(debug, int, 0); | ||
| 36 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
| 37 | |||
| 38 | #define dprintk(num, format, args...) \ | ||
| 39 | do { \ | ||
| 40 | if (debug >= num) \ | ||
| 41 | printk(format, ##args); \ | ||
| 42 | } while (0) | ||
| 43 | |||
| 44 | /* ========================================================================= | ||
| 45 | Local hardware I/O functions: | ||
| 46 | |||
| 47 | read/write via codec layer (registers are located in the master device) | ||
| 48 | ========================================================================= */ | ||
| 49 | |||
| 50 | /* read and write functions */ | ||
| 51 | static u8 | ||
| 52 | zr36050_read (struct zr36050 *ptr, | ||
| 53 | u16 reg) | ||
| 54 | { | ||
| 55 | u8 value = 0; | ||
| 56 | |||
| 57 | // just in case something is wrong... | ||
| 58 | if (ptr->codec->master_data->readreg) | ||
| 59 | value = (ptr->codec->master_data->readreg(ptr->codec, | ||
| 60 | reg)) & 0xFF; | ||
| 61 | else | ||
| 62 | dprintk(1, | ||
| 63 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
| 64 | ptr->name); | ||
| 65 | |||
| 66 | dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, | ||
| 67 | value); | ||
| 68 | |||
| 69 | return value; | ||
| 70 | } | ||
| 71 | |||
| 72 | static void | ||
| 73 | zr36050_write (struct zr36050 *ptr, | ||
| 74 | u16 reg, | ||
| 75 | u8 value) | ||
| 76 | { | ||
| 77 | dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, | ||
| 78 | reg); | ||
| 79 | |||
| 80 | // just in case something is wrong... | ||
| 81 | if (ptr->codec->master_data->writereg) | ||
| 82 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
| 83 | else | ||
| 84 | dprintk(1, | ||
| 85 | KERN_ERR | ||
| 86 | "%s: invalid I/O setup, nothing written!\n", | ||
| 87 | ptr->name); | ||
| 88 | } | ||
| 89 | |||
| 90 | /* ========================================================================= | ||
| 91 | Local helper function: | ||
| 92 | |||
| 93 | status read | ||
| 94 | ========================================================================= */ | ||
| 95 | |||
| 96 | /* status is kept in datastructure */ | ||
| 97 | static u8 | ||
| 98 | zr36050_read_status1 (struct zr36050 *ptr) | ||
| 99 | { | ||
| 100 | ptr->status1 = zr36050_read(ptr, ZR050_STATUS_1); | ||
| 101 | |||
| 102 | zr36050_read(ptr, 0); | ||
| 103 | return ptr->status1; | ||
| 104 | } | ||
| 105 | |||
| 106 | /* ========================================================================= | ||
| 107 | Local helper function: | ||
| 108 | |||
| 109 | scale factor read | ||
| 110 | ========================================================================= */ | ||
| 111 | |||
| 112 | /* scale factor is kept in datastructure */ | ||
| 113 | static u16 | ||
| 114 | zr36050_read_scalefactor (struct zr36050 *ptr) | ||
| 115 | { | ||
| 116 | ptr->scalefact = (zr36050_read(ptr, ZR050_SF_HI) << 8) | | ||
| 117 | (zr36050_read(ptr, ZR050_SF_LO) & 0xFF); | ||
| 118 | |||
| 119 | /* leave 0 selected for an eventually GO from master */ | ||
| 120 | zr36050_read(ptr, 0); | ||
| 121 | return ptr->scalefact; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* ========================================================================= | ||
| 125 | Local helper function: | ||
| 126 | |||
| 127 | wait if codec is ready to proceed (end of processing) or time is over | ||
| 128 | ========================================================================= */ | ||
| 129 | |||
| 130 | static void | ||
| 131 | zr36050_wait_end (struct zr36050 *ptr) | ||
| 132 | { | ||
| 133 | int i = 0; | ||
| 134 | |||
| 135 | while (!(zr36050_read_status1(ptr) & 0x4)) { | ||
| 136 | udelay(1); | ||
| 137 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! | ||
| 138 | dprintk(1, | ||
| 139 | "%s: timeout at wait_end (last status: 0x%02x)\n", | ||
| 140 | ptr->name, ptr->status1); | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | /* ========================================================================= | ||
| 147 | Local helper function: | ||
| 148 | |||
| 149 | basic test of "connectivity", writes/reads to/from memory the SOF marker | ||
| 150 | ========================================================================= */ | ||
| 151 | |||
| 152 | static int | ||
| 153 | zr36050_basic_test (struct zr36050 *ptr) | ||
| 154 | { | ||
| 155 | zr36050_write(ptr, ZR050_SOF_IDX, 0x00); | ||
| 156 | zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00); | ||
| 157 | if ((zr36050_read(ptr, ZR050_SOF_IDX) | | ||
| 158 | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) { | ||
| 159 | dprintk(1, | ||
| 160 | KERN_ERR | ||
| 161 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
| 162 | ptr->name); | ||
| 163 | return -ENXIO; | ||
| 164 | } | ||
| 165 | zr36050_write(ptr, ZR050_SOF_IDX, 0xff); | ||
| 166 | zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0); | ||
| 167 | if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) | | ||
| 168 | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) { | ||
| 169 | dprintk(1, | ||
| 170 | KERN_ERR | ||
| 171 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
| 172 | ptr->name); | ||
| 173 | return -ENXIO; | ||
| 174 | } | ||
| 175 | |||
| 176 | zr36050_wait_end(ptr); | ||
| 177 | if ((ptr->status1 & 0x4) == 0) { | ||
| 178 | dprintk(1, | ||
| 179 | KERN_ERR | ||
| 180 | "%s: attach failed, jpeg processor failed (end flag)!\n", | ||
| 181 | ptr->name); | ||
| 182 | return -EBUSY; | ||
| 183 | } | ||
| 184 | |||
| 185 | return 0; /* looks good! */ | ||
| 186 | } | ||
| 187 | |||
| 188 | /* ========================================================================= | ||
| 189 | Local helper function: | ||
| 190 | |||
| 191 | simple loop for pushing the init datasets | ||
| 192 | ========================================================================= */ | ||
| 193 | |||
| 194 | static int | ||
| 195 | zr36050_pushit (struct zr36050 *ptr, | ||
| 196 | u16 startreg, | ||
| 197 | u16 len, | ||
| 198 | const char *data) | ||
| 199 | { | ||
| 200 | int i = 0; | ||
| 201 | |||
| 202 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, | ||
| 203 | startreg, len); | ||
| 204 | while (i < len) { | ||
| 205 | zr36050_write(ptr, startreg++, data[i++]); | ||
| 206 | } | ||
| 207 | |||
| 208 | return i; | ||
| 209 | } | ||
| 210 | |||
| 211 | /* ========================================================================= | ||
| 212 | Basic datasets: | ||
| 213 | |||
| 214 | jpeg baseline setup data (you find it on lots places in internet, or just | ||
| 215 | extract it from any regular .jpg image...) | ||
| 216 | |||
| 217 | Could be variable, but until it's not needed it they are just fixed to save | ||
| 218 | memory. Otherwise expand zr36050 structure with arrays, push the values to | ||
| 219 | it and initialize from there, as e.g. the linux zr36057/60 driver does it. | ||
| 220 | ========================================================================= */ | ||
| 221 | |||
| 222 | static const char zr36050_dqt[0x86] = { | ||
| 223 | 0xff, 0xdb, //Marker: DQT | ||
| 224 | 0x00, 0x84, //Length: 2*65+2 | ||
| 225 | 0x00, //Pq,Tq first table | ||
| 226 | 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, | ||
| 227 | 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, | ||
| 228 | 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, | ||
| 229 | 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, | ||
| 230 | 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, | ||
| 231 | 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, | ||
| 232 | 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, | ||
| 233 | 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, | ||
| 234 | 0x01, //Pq,Tq second table | ||
| 235 | 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, | ||
| 236 | 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, | ||
| 237 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 238 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 239 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 240 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 241 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 242 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 | ||
| 243 | }; | ||
| 244 | |||
| 245 | static const char zr36050_dht[0x1a4] = { | ||
| 246 | 0xff, 0xc4, //Marker: DHT | ||
| 247 | 0x01, 0xa2, //Length: 2*AC, 2*DC | ||
| 248 | 0x00, //DC first table | ||
| 249 | 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
| 250 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
| 251 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
| 252 | 0x01, //DC second table | ||
| 253 | 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
| 254 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
| 255 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
| 256 | 0x10, //AC first table | ||
| 257 | 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, | ||
| 258 | 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, | ||
| 259 | 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, | ||
| 260 | 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, | ||
| 261 | 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, | ||
| 262 | 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, | ||
| 263 | 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, | ||
| 264 | 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, | ||
| 265 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
| 266 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
| 267 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
| 268 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
| 269 | 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | ||
| 270 | 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, | ||
| 271 | 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, | ||
| 272 | 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, | ||
| 273 | 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, | ||
| 274 | 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, | ||
| 275 | 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
| 276 | 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, | ||
| 277 | 0xF8, 0xF9, 0xFA, | ||
| 278 | 0x11, //AC second table | ||
| 279 | 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
| 280 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, | ||
| 281 | 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, | ||
| 282 | 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | ||
| 283 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, | ||
| 284 | 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, | ||
| 285 | 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, | ||
| 286 | 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, | ||
| 287 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
| 288 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
| 289 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
| 290 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
| 291 | 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | ||
| 292 | 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | ||
| 293 | 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, | ||
| 294 | 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, | ||
| 295 | 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, | ||
| 296 | 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, | ||
| 297 | 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
| 298 | 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, | ||
| 299 | 0xF9, 0xFA | ||
| 300 | }; | ||
| 301 | |||
| 302 | /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */ | ||
| 303 | #define NO_OF_COMPONENTS 0x3 //Y,U,V | ||
| 304 | #define BASELINE_PRECISION 0x8 //MCU size (?) | ||
| 305 | static const char zr36050_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT | ||
| 306 | static const char zr36050_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC | ||
| 307 | static const char zr36050_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC | ||
| 308 | |||
| 309 | /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ | ||
| 310 | static const char zr36050_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; | ||
| 311 | static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; | ||
| 312 | |||
| 313 | /* ========================================================================= | ||
| 314 | Local helper functions: | ||
| 315 | |||
| 316 | calculation and setup of parameter-dependent JPEG baseline segments | ||
| 317 | (needed for compression only) | ||
| 318 | ========================================================================= */ | ||
| 319 | |||
| 320 | /* ------------------------------------------------------------------------- */ | ||
| 321 | |||
| 322 | /* SOF (start of frame) segment depends on width, height and sampling ratio | ||
| 323 | of each color component */ | ||
| 324 | |||
| 325 | static int | ||
| 326 | zr36050_set_sof (struct zr36050 *ptr) | ||
| 327 | { | ||
| 328 | char sof_data[34]; // max. size of register set | ||
| 329 | int i; | ||
| 330 | |||
| 331 | dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, | ||
| 332 | ptr->width, ptr->height, NO_OF_COMPONENTS); | ||
| 333 | sof_data[0] = 0xff; | ||
| 334 | sof_data[1] = 0xc0; | ||
| 335 | sof_data[2] = 0x00; | ||
| 336 | sof_data[3] = (3 * NO_OF_COMPONENTS) + 8; | ||
| 337 | sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36050 | ||
| 338 | sof_data[5] = (ptr->height) >> 8; | ||
| 339 | sof_data[6] = (ptr->height) & 0xff; | ||
| 340 | sof_data[7] = (ptr->width) >> 8; | ||
| 341 | sof_data[8] = (ptr->width) & 0xff; | ||
| 342 | sof_data[9] = NO_OF_COMPONENTS; | ||
| 343 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
| 344 | sof_data[10 + (i * 3)] = i; // index identifier | ||
| 345 | sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | (ptr->v_samp_ratio[i]); // sampling ratios | ||
| 346 | sof_data[12 + (i * 3)] = zr36050_tq[i]; // Q table selection | ||
| 347 | } | ||
| 348 | return zr36050_pushit(ptr, ZR050_SOF_IDX, | ||
| 349 | (3 * NO_OF_COMPONENTS) + 10, sof_data); | ||
| 350 | } | ||
| 351 | |||
| 352 | /* ------------------------------------------------------------------------- */ | ||
| 353 | |||
| 354 | /* SOS (start of scan) segment depends on the used scan components | ||
| 355 | of each color component */ | ||
| 356 | |||
| 357 | static int | ||
| 358 | zr36050_set_sos (struct zr36050 *ptr) | ||
| 359 | { | ||
| 360 | char sos_data[16]; // max. size of register set | ||
| 361 | int i; | ||
| 362 | |||
| 363 | dprintk(3, "%s: write SOS\n", ptr->name); | ||
| 364 | sos_data[0] = 0xff; | ||
| 365 | sos_data[1] = 0xda; | ||
| 366 | sos_data[2] = 0x00; | ||
| 367 | sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3; | ||
| 368 | sos_data[4] = NO_OF_COMPONENTS; | ||
| 369 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
| 370 | sos_data[5 + (i * 2)] = i; // index | ||
| 371 | sos_data[6 + (i * 2)] = (zr36050_td[i] << 4) | zr36050_ta[i]; // AC/DC tbl.sel. | ||
| 372 | } | ||
| 373 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start | ||
| 374 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3F; | ||
| 375 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00; | ||
| 376 | return zr36050_pushit(ptr, ZR050_SOS1_IDX, | ||
| 377 | 4 + 1 + (2 * NO_OF_COMPONENTS) + 3, | ||
| 378 | sos_data); | ||
| 379 | } | ||
| 380 | |||
| 381 | /* ------------------------------------------------------------------------- */ | ||
| 382 | |||
| 383 | /* DRI (define restart interval) */ | ||
| 384 | |||
| 385 | static int | ||
| 386 | zr36050_set_dri (struct zr36050 *ptr) | ||
| 387 | { | ||
| 388 | char dri_data[6]; // max. size of register set | ||
| 389 | |||
| 390 | dprintk(3, "%s: write DRI\n", ptr->name); | ||
| 391 | dri_data[0] = 0xff; | ||
| 392 | dri_data[1] = 0xdd; | ||
| 393 | dri_data[2] = 0x00; | ||
| 394 | dri_data[3] = 0x04; | ||
| 395 | dri_data[4] = ptr->dri >> 8; | ||
| 396 | dri_data[5] = ptr->dri & 0xff; | ||
| 397 | return zr36050_pushit(ptr, ZR050_DRI_IDX, 6, dri_data); | ||
| 398 | } | ||
| 399 | |||
| 400 | /* ========================================================================= | ||
| 401 | Setup function: | ||
| 402 | |||
| 403 | Setup compression/decompression of Zoran's JPEG processor | ||
| 404 | ( see also zoran 36050 manual ) | ||
| 405 | |||
| 406 | ... sorry for the spaghetti code ... | ||
| 407 | ========================================================================= */ | ||
| 408 | static void | ||
| 409 | zr36050_init (struct zr36050 *ptr) | ||
| 410 | { | ||
| 411 | int sum = 0; | ||
| 412 | long bitcnt, tmp; | ||
| 413 | |||
| 414 | if (ptr->mode == CODEC_DO_COMPRESSION) { | ||
| 415 | dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); | ||
| 416 | |||
| 417 | /* 050 communicates with 057 in master mode */ | ||
| 418 | zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR); | ||
| 419 | |||
| 420 | /* encoding table preload for compression */ | ||
| 421 | zr36050_write(ptr, ZR050_MODE, | ||
| 422 | ZR050_MO_COMP | ZR050_MO_TLM); | ||
| 423 | zr36050_write(ptr, ZR050_OPTIONS, 0); | ||
| 424 | |||
| 425 | /* disable all IRQs */ | ||
| 426 | zr36050_write(ptr, ZR050_INT_REQ_0, 0); | ||
| 427 | zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1 | ||
| 428 | |||
| 429 | /* volume control settings */ | ||
| 430 | /*zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol);*/ | ||
| 431 | zr36050_write(ptr, ZR050_SF_HI, ptr->scalefact >> 8); | ||
| 432 | zr36050_write(ptr, ZR050_SF_LO, ptr->scalefact & 0xff); | ||
| 433 | |||
| 434 | zr36050_write(ptr, ZR050_AF_HI, 0xff); | ||
| 435 | zr36050_write(ptr, ZR050_AF_M, 0xff); | ||
| 436 | zr36050_write(ptr, ZR050_AF_LO, 0xff); | ||
| 437 | |||
| 438 | /* setup the variable jpeg tables */ | ||
| 439 | sum += zr36050_set_sof(ptr); | ||
| 440 | sum += zr36050_set_sos(ptr); | ||
| 441 | sum += zr36050_set_dri(ptr); | ||
| 442 | |||
| 443 | /* setup the fixed jpeg tables - maybe variable, though - | ||
| 444 | * (see table init section above) */ | ||
| 445 | dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name); | ||
| 446 | sum += zr36050_pushit(ptr, ZR050_DQT_IDX, | ||
| 447 | sizeof(zr36050_dqt), zr36050_dqt); | ||
| 448 | sum += zr36050_pushit(ptr, ZR050_DHT_IDX, | ||
| 449 | sizeof(zr36050_dht), zr36050_dht); | ||
| 450 | zr36050_write(ptr, ZR050_APP_IDX, 0xff); | ||
| 451 | zr36050_write(ptr, ZR050_APP_IDX + 1, 0xe0 + ptr->app.appn); | ||
| 452 | zr36050_write(ptr, ZR050_APP_IDX + 2, 0x00); | ||
| 453 | zr36050_write(ptr, ZR050_APP_IDX + 3, ptr->app.len + 2); | ||
| 454 | sum += zr36050_pushit(ptr, ZR050_APP_IDX + 4, 60, | ||
| 455 | ptr->app.data) + 4; | ||
| 456 | zr36050_write(ptr, ZR050_COM_IDX, 0xff); | ||
| 457 | zr36050_write(ptr, ZR050_COM_IDX + 1, 0xfe); | ||
| 458 | zr36050_write(ptr, ZR050_COM_IDX + 2, 0x00); | ||
| 459 | zr36050_write(ptr, ZR050_COM_IDX + 3, ptr->com.len + 2); | ||
| 460 | sum += zr36050_pushit(ptr, ZR050_COM_IDX + 4, 60, | ||
| 461 | ptr->com.data) + 4; | ||
| 462 | |||
| 463 | /* do the internal huffman table preload */ | ||
| 464 | zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI); | ||
| 465 | |||
| 466 | zr36050_write(ptr, ZR050_GO, 1); // launch codec | ||
| 467 | zr36050_wait_end(ptr); | ||
| 468 | dprintk(2, "%s: Status after table preload: 0x%02x\n", | ||
| 469 | ptr->name, ptr->status1); | ||
| 470 | |||
| 471 | if ((ptr->status1 & 0x4) == 0) { | ||
| 472 | dprintk(1, KERN_ERR "%s: init aborted!\n", | ||
| 473 | ptr->name); | ||
| 474 | return; // something is wrong, its timed out!!!! | ||
| 475 | } | ||
| 476 | |||
| 477 | /* setup misc. data for compression (target code sizes) */ | ||
| 478 | |||
| 479 | /* size of compressed code to reach without header data */ | ||
| 480 | sum = ptr->real_code_vol - sum; | ||
| 481 | bitcnt = sum << 3; /* need the size in bits */ | ||
| 482 | |||
| 483 | tmp = bitcnt >> 16; | ||
| 484 | dprintk(3, | ||
| 485 | "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", | ||
| 486 | ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); | ||
| 487 | zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8); | ||
| 488 | zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff); | ||
| 489 | tmp = bitcnt & 0xffff; | ||
| 490 | zr36050_write(ptr, ZR050_TCV_NET_ML, tmp >> 8); | ||
| 491 | zr36050_write(ptr, ZR050_TCV_NET_LO, tmp & 0xff); | ||
| 492 | |||
| 493 | bitcnt -= bitcnt >> 7; // bits without stuffing | ||
| 494 | bitcnt -= ((bitcnt * 5) >> 6); // bits without eob | ||
| 495 | |||
| 496 | tmp = bitcnt >> 16; | ||
| 497 | dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", | ||
| 498 | ptr->name, bitcnt, tmp); | ||
| 499 | zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8); | ||
| 500 | zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff); | ||
| 501 | tmp = bitcnt & 0xffff; | ||
| 502 | zr36050_write(ptr, ZR050_TCV_DATA_ML, tmp >> 8); | ||
| 503 | zr36050_write(ptr, ZR050_TCV_DATA_LO, tmp & 0xff); | ||
| 504 | |||
| 505 | /* compression setup with or without bitrate control */ | ||
| 506 | zr36050_write(ptr, ZR050_MODE, | ||
| 507 | ZR050_MO_COMP | ZR050_MO_PASS2 | | ||
| 508 | (ptr->bitrate_ctrl ? ZR050_MO_BRC : 0)); | ||
| 509 | |||
| 510 | /* this headers seem to deliver "valid AVI" jpeg frames */ | ||
| 511 | zr36050_write(ptr, ZR050_MARKERS_EN, | ||
| 512 | ZR050_ME_DQT | ZR050_ME_DHT | | ||
| 513 | ((ptr->app.len > 0) ? ZR050_ME_APP : 0) | | ||
| 514 | ((ptr->com.len > 0) ? ZR050_ME_COM : 0)); | ||
| 515 | } else { | ||
| 516 | dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); | ||
| 517 | |||
| 518 | /* 050 communicates with 055 in master mode */ | ||
| 519 | zr36050_write(ptr, ZR050_HARDWARE, | ||
| 520 | ZR050_HW_MSTR | ZR050_HW_CFIS_2_CLK); | ||
| 521 | |||
| 522 | /* encoding table preload */ | ||
| 523 | zr36050_write(ptr, ZR050_MODE, ZR050_MO_TLM); | ||
| 524 | |||
| 525 | /* disable all IRQs */ | ||
| 526 | zr36050_write(ptr, ZR050_INT_REQ_0, 0); | ||
| 527 | zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1 | ||
| 528 | |||
| 529 | dprintk(3, "%s: write DHT\n", ptr->name); | ||
| 530 | zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht), | ||
| 531 | zr36050_dht); | ||
| 532 | |||
| 533 | /* do the internal huffman table preload */ | ||
| 534 | zr36050_write(ptr, ZR050_MARKERS_EN, ZR050_ME_DHTI); | ||
| 535 | |||
| 536 | zr36050_write(ptr, ZR050_GO, 1); // launch codec | ||
| 537 | zr36050_wait_end(ptr); | ||
| 538 | dprintk(2, "%s: Status after table preload: 0x%02x\n", | ||
| 539 | ptr->name, ptr->status1); | ||
| 540 | |||
| 541 | if ((ptr->status1 & 0x4) == 0) { | ||
| 542 | dprintk(1, KERN_ERR "%s: init aborted!\n", | ||
| 543 | ptr->name); | ||
| 544 | return; // something is wrong, its timed out!!!! | ||
| 545 | } | ||
| 546 | |||
| 547 | /* setup misc. data for expansion */ | ||
| 548 | zr36050_write(ptr, ZR050_MODE, 0); | ||
| 549 | zr36050_write(ptr, ZR050_MARKERS_EN, 0); | ||
| 550 | } | ||
| 551 | |||
| 552 | /* adr on selected, to allow GO from master */ | ||
| 553 | zr36050_read(ptr, 0); | ||
| 554 | } | ||
| 555 | |||
| 556 | /* ========================================================================= | ||
| 557 | CODEC API FUNCTIONS | ||
| 558 | |||
| 559 | this functions are accessed by the master via the API structure | ||
| 560 | ========================================================================= */ | ||
| 561 | |||
| 562 | /* set compression/expansion mode and launches codec - | ||
| 563 | this should be the last call from the master before starting processing */ | ||
| 564 | static int | ||
| 565 | zr36050_set_mode (struct videocodec *codec, | ||
| 566 | int mode) | ||
| 567 | { | ||
| 568 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
| 569 | |||
| 570 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
| 571 | |||
| 572 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
| 573 | return -EINVAL; | ||
| 574 | |||
| 575 | ptr->mode = mode; | ||
| 576 | zr36050_init(ptr); | ||
| 577 | |||
| 578 | return 0; | ||
| 579 | } | ||
| 580 | |||
| 581 | /* set picture size (norm is ignored as the codec doesn't know about it) */ | ||
| 582 | static int | ||
| 583 | zr36050_set_video (struct videocodec *codec, | ||
| 584 | struct tvnorm *norm, | ||
| 585 | struct vfe_settings *cap, | ||
| 586 | struct vfe_polarity *pol) | ||
| 587 | { | ||
| 588 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
| 589 | int size; | ||
| 590 | |||
| 591 | dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n", | ||
| 592 | ptr->name, norm->HStart, norm->VStart, | ||
| 593 | cap->x, cap->y, cap->width, cap->height, | ||
| 594 | cap->decimation, cap->quality); | ||
| 595 | /* if () return -EINVAL; | ||
| 596 | * trust the master driver that it knows what it does - so | ||
| 597 | * we allow invalid startx/y and norm for now ... */ | ||
| 598 | ptr->width = cap->width / (cap->decimation & 0xff); | ||
| 599 | ptr->height = cap->height / ((cap->decimation >> 8) & 0xff); | ||
| 600 | |||
| 601 | /* (KM) JPEG quality */ | ||
| 602 | size = ptr->width * ptr->height; | ||
| 603 | size *= 16; /* size in bits */ | ||
| 604 | /* apply quality setting */ | ||
| 605 | size = size * cap->quality / 200; | ||
| 606 | |||
| 607 | /* Minimum: 1kb */ | ||
| 608 | if (size < 8192) | ||
| 609 | size = 8192; | ||
| 610 | /* Maximum: 7/8 of code buffer */ | ||
| 611 | if (size > ptr->total_code_vol * 7) | ||
| 612 | size = ptr->total_code_vol * 7; | ||
| 613 | |||
| 614 | ptr->real_code_vol = size >> 3; /* in bytes */ | ||
| 615 | |||
| 616 | /* Set max_block_vol here (previously in zr36050_init, moved | ||
| 617 | * here for consistency with zr36060 code */ | ||
| 618 | zr36050_write(ptr, ZR050_MBCV, ptr->max_block_vol); | ||
| 619 | |||
| 620 | return 0; | ||
| 621 | } | ||
| 622 | |||
| 623 | /* additional control functions */ | ||
| 624 | static int | ||
| 625 | zr36050_control (struct videocodec *codec, | ||
| 626 | int type, | ||
| 627 | int size, | ||
| 628 | void *data) | ||
| 629 | { | ||
| 630 | struct zr36050 *ptr = (struct zr36050 *) codec->data; | ||
| 631 | int *ival = (int *) data; | ||
| 632 | |||
| 633 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
| 634 | size); | ||
| 635 | |||
| 636 | switch (type) { | ||
| 637 | case CODEC_G_STATUS: /* get last status */ | ||
| 638 | if (size != sizeof(int)) | ||
| 639 | return -EFAULT; | ||
| 640 | zr36050_read_status1(ptr); | ||
| 641 | *ival = ptr->status1; | ||
| 642 | break; | ||
| 643 | |||
| 644 | case CODEC_G_CODEC_MODE: | ||
| 645 | if (size != sizeof(int)) | ||
| 646 | return -EFAULT; | ||
| 647 | *ival = CODEC_MODE_BJPG; | ||
| 648 | break; | ||
| 649 | |||
| 650 | case CODEC_S_CODEC_MODE: | ||
| 651 | if (size != sizeof(int)) | ||
| 652 | return -EFAULT; | ||
| 653 | if (*ival != CODEC_MODE_BJPG) | ||
| 654 | return -EINVAL; | ||
| 655 | /* not needed, do nothing */ | ||
| 656 | return 0; | ||
| 657 | |||
| 658 | case CODEC_G_VFE: | ||
| 659 | case CODEC_S_VFE: | ||
| 660 | /* not needed, do nothing */ | ||
| 661 | return 0; | ||
| 662 | |||
| 663 | case CODEC_S_MMAP: | ||
| 664 | /* not available, give an error */ | ||
| 665 | return -ENXIO; | ||
| 666 | |||
| 667 | case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
| 668 | if (size != sizeof(int)) | ||
| 669 | return -EFAULT; | ||
| 670 | *ival = ptr->total_code_vol; | ||
| 671 | break; | ||
| 672 | |||
| 673 | case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
| 674 | if (size != sizeof(int)) | ||
| 675 | return -EFAULT; | ||
| 676 | ptr->total_code_vol = *ival; | ||
| 677 | /* (Kieran Morrissey) | ||
| 678 | * code copied from zr36060.c to ensure proper bitrate */ | ||
| 679 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
| 680 | break; | ||
| 681 | |||
| 682 | case CODEC_G_JPEG_SCALE: /* get scaling factor */ | ||
| 683 | if (size != sizeof(int)) | ||
| 684 | return -EFAULT; | ||
| 685 | *ival = zr36050_read_scalefactor(ptr); | ||
| 686 | break; | ||
| 687 | |||
| 688 | case CODEC_S_JPEG_SCALE: /* set scaling factor */ | ||
| 689 | if (size != sizeof(int)) | ||
| 690 | return -EFAULT; | ||
| 691 | ptr->scalefact = *ival; | ||
| 692 | break; | ||
| 693 | |||
| 694 | case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ | ||
| 695 | struct jpeg_app_marker *app = data; | ||
| 696 | |||
| 697 | if (size != sizeof(struct jpeg_app_marker)) | ||
| 698 | return -EFAULT; | ||
| 699 | |||
| 700 | *app = ptr->app; | ||
| 701 | break; | ||
| 702 | } | ||
| 703 | |||
| 704 | case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ | ||
| 705 | struct jpeg_app_marker *app = data; | ||
| 706 | |||
| 707 | if (size != sizeof(struct jpeg_app_marker)) | ||
| 708 | return -EFAULT; | ||
| 709 | |||
| 710 | ptr->app = *app; | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | |||
| 714 | case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ | ||
| 715 | struct jpeg_com_marker *com = data; | ||
| 716 | |||
| 717 | if (size != sizeof(struct jpeg_com_marker)) | ||
| 718 | return -EFAULT; | ||
| 719 | |||
| 720 | *com = ptr->com; | ||
| 721 | break; | ||
| 722 | } | ||
| 723 | |||
| 724 | case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ | ||
| 725 | struct jpeg_com_marker *com = data; | ||
| 726 | |||
| 727 | if (size != sizeof(struct jpeg_com_marker)) | ||
| 728 | return -EFAULT; | ||
| 729 | |||
| 730 | ptr->com = *com; | ||
| 731 | break; | ||
| 732 | } | ||
| 733 | |||
| 734 | default: | ||
| 735 | return -EINVAL; | ||
| 736 | } | ||
| 737 | |||
| 738 | return size; | ||
| 739 | } | ||
| 740 | |||
| 741 | /* ========================================================================= | ||
| 742 | Exit and unregister function: | ||
| 743 | |||
| 744 | Deinitializes Zoran's JPEG processor | ||
| 745 | ========================================================================= */ | ||
| 746 | |||
| 747 | static int | ||
| 748 | zr36050_unset (struct videocodec *codec) | ||
| 749 | { | ||
| 750 | struct zr36050 *ptr = codec->data; | ||
| 751 | |||
| 752 | if (ptr) { | ||
| 753 | /* do wee need some codec deinit here, too ???? */ | ||
| 754 | |||
| 755 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
| 756 | ptr->num); | ||
| 757 | kfree(ptr); | ||
| 758 | codec->data = NULL; | ||
| 759 | |||
| 760 | zr36050_codecs--; | ||
| 761 | return 0; | ||
| 762 | } | ||
| 763 | |||
| 764 | return -EFAULT; | ||
| 765 | } | ||
| 766 | |||
| 767 | /* ========================================================================= | ||
| 768 | Setup and registry function: | ||
| 769 | |||
| 770 | Initializes Zoran's JPEG processor | ||
| 771 | |||
| 772 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
| 773 | (the given size is determined by the processor with the video interface) | ||
| 774 | ========================================================================= */ | ||
| 775 | |||
| 776 | static int | ||
| 777 | zr36050_setup (struct videocodec *codec) | ||
| 778 | { | ||
| 779 | struct zr36050 *ptr; | ||
| 780 | int res; | ||
| 781 | |||
| 782 | dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n", | ||
| 783 | zr36050_codecs); | ||
| 784 | |||
| 785 | if (zr36050_codecs == MAX_CODECS) { | ||
| 786 | dprintk(1, | ||
| 787 | KERN_ERR "zr36050: Can't attach more codecs!\n"); | ||
| 788 | return -ENOSPC; | ||
| 789 | } | ||
| 790 | //mem structure init | ||
| 791 | codec->data = ptr = kzalloc(sizeof(struct zr36050), GFP_KERNEL); | ||
| 792 | if (NULL == ptr) { | ||
| 793 | dprintk(1, KERN_ERR "zr36050: Can't get enough memory!\n"); | ||
| 794 | return -ENOMEM; | ||
| 795 | } | ||
| 796 | |||
| 797 | snprintf(ptr->name, sizeof(ptr->name), "zr36050[%d]", | ||
| 798 | zr36050_codecs); | ||
| 799 | ptr->num = zr36050_codecs++; | ||
| 800 | ptr->codec = codec; | ||
| 801 | |||
| 802 | //testing | ||
| 803 | res = zr36050_basic_test(ptr); | ||
| 804 | if (res < 0) { | ||
| 805 | zr36050_unset(codec); | ||
| 806 | return res; | ||
| 807 | } | ||
| 808 | //final setup | ||
| 809 | memcpy(ptr->h_samp_ratio, zr36050_decimation_h, 8); | ||
| 810 | memcpy(ptr->v_samp_ratio, zr36050_decimation_v, 8); | ||
| 811 | |||
| 812 | ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag | ||
| 813 | * (what is the difference?) */ | ||
| 814 | ptr->mode = CODEC_DO_COMPRESSION; | ||
| 815 | ptr->width = 384; | ||
| 816 | ptr->height = 288; | ||
| 817 | ptr->total_code_vol = 16000; | ||
| 818 | ptr->max_block_vol = 240; | ||
| 819 | ptr->scalefact = 0x100; | ||
| 820 | ptr->dri = 1; | ||
| 821 | |||
| 822 | /* no app/com marker by default */ | ||
| 823 | ptr->app.appn = 0; | ||
| 824 | ptr->app.len = 0; | ||
| 825 | ptr->com.len = 0; | ||
| 826 | |||
| 827 | zr36050_init(ptr); | ||
| 828 | |||
| 829 | dprintk(1, KERN_INFO "%s: codec attached and running\n", | ||
| 830 | ptr->name); | ||
| 831 | |||
| 832 | return 0; | ||
| 833 | } | ||
| 834 | |||
| 835 | static const struct videocodec zr36050_codec = { | ||
| 836 | .owner = THIS_MODULE, | ||
| 837 | .name = "zr36050", | ||
| 838 | .magic = 0L, // magic not used | ||
| 839 | .flags = | ||
| 840 | CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | | ||
| 841 | CODEC_FLAG_DECODER, | ||
| 842 | .type = CODEC_TYPE_ZR36050, | ||
| 843 | .setup = zr36050_setup, // functionality | ||
| 844 | .unset = zr36050_unset, | ||
| 845 | .set_mode = zr36050_set_mode, | ||
| 846 | .set_video = zr36050_set_video, | ||
| 847 | .control = zr36050_control, | ||
| 848 | // others are not used | ||
| 849 | }; | ||
| 850 | |||
| 851 | /* ========================================================================= | ||
| 852 | HOOK IN DRIVER AS KERNEL MODULE | ||
| 853 | ========================================================================= */ | ||
| 854 | |||
| 855 | static int __init | ||
| 856 | zr36050_init_module (void) | ||
| 857 | { | ||
| 858 | //dprintk(1, "ZR36050 driver %s\n",ZR050_VERSION); | ||
| 859 | zr36050_codecs = 0; | ||
| 860 | return videocodec_register(&zr36050_codec); | ||
| 861 | } | ||
| 862 | |||
| 863 | static void __exit | ||
| 864 | zr36050_cleanup_module (void) | ||
| 865 | { | ||
| 866 | if (zr36050_codecs) { | ||
| 867 | dprintk(1, | ||
| 868 | "zr36050: something's wrong - %d codecs left somehow.\n", | ||
| 869 | zr36050_codecs); | ||
| 870 | } | ||
| 871 | videocodec_unregister(&zr36050_codec); | ||
| 872 | } | ||
| 873 | |||
| 874 | module_init(zr36050_init_module); | ||
| 875 | module_exit(zr36050_cleanup_module); | ||
| 876 | |||
| 877 | MODULE_AUTHOR("Wolfgang Scherr <scherr@net4you.at>"); | ||
| 878 | MODULE_DESCRIPTION("Driver module for ZR36050 jpeg processors " | ||
| 879 | ZR050_VERSION); | ||
| 880 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/media/zoran/zr36050.h b/drivers/staging/media/zoran/zr36050.h deleted file mode 100644 index c485913dc820..000000000000 --- a/drivers/staging/media/zoran/zr36050.h +++ /dev/null | |||
| @@ -1,163 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36050 basic configuration functions - header file | ||
| 4 | * | ||
| 5 | * Copyright (C) 2001 Wolfgang Scherr <scherr@net4you.at> | ||
| 6 | */ | ||
| 7 | #ifndef ZR36050_H | ||
| 8 | #define ZR36050_H | ||
| 9 | |||
| 10 | #include "videocodec.h" | ||
| 11 | |||
| 12 | /* data stored for each zoran jpeg codec chip */ | ||
| 13 | struct zr36050 { | ||
| 14 | char name[32]; | ||
| 15 | int num; | ||
| 16 | /* io datastructure */ | ||
| 17 | struct videocodec *codec; | ||
| 18 | // last coder status | ||
| 19 | __u8 status1; | ||
| 20 | // actual coder setup | ||
| 21 | int mode; | ||
| 22 | |||
| 23 | __u16 width; | ||
| 24 | __u16 height; | ||
| 25 | |||
| 26 | __u16 bitrate_ctrl; | ||
| 27 | |||
| 28 | __u32 total_code_vol; | ||
| 29 | __u32 real_code_vol; | ||
| 30 | __u16 max_block_vol; | ||
| 31 | |||
| 32 | __u8 h_samp_ratio[8]; | ||
| 33 | __u8 v_samp_ratio[8]; | ||
| 34 | __u16 scalefact; | ||
| 35 | __u16 dri; | ||
| 36 | |||
| 37 | /* com/app marker */ | ||
| 38 | struct jpeg_com_marker com; | ||
| 39 | struct jpeg_app_marker app; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* zr36050 register addresses */ | ||
| 43 | #define ZR050_GO 0x000 | ||
| 44 | #define ZR050_HARDWARE 0x002 | ||
| 45 | #define ZR050_MODE 0x003 | ||
| 46 | #define ZR050_OPTIONS 0x004 | ||
| 47 | #define ZR050_MBCV 0x005 | ||
| 48 | #define ZR050_MARKERS_EN 0x006 | ||
| 49 | #define ZR050_INT_REQ_0 0x007 | ||
| 50 | #define ZR050_INT_REQ_1 0x008 | ||
| 51 | #define ZR050_TCV_NET_HI 0x009 | ||
| 52 | #define ZR050_TCV_NET_MH 0x00a | ||
| 53 | #define ZR050_TCV_NET_ML 0x00b | ||
| 54 | #define ZR050_TCV_NET_LO 0x00c | ||
| 55 | #define ZR050_TCV_DATA_HI 0x00d | ||
| 56 | #define ZR050_TCV_DATA_MH 0x00e | ||
| 57 | #define ZR050_TCV_DATA_ML 0x00f | ||
| 58 | #define ZR050_TCV_DATA_LO 0x010 | ||
| 59 | #define ZR050_SF_HI 0x011 | ||
| 60 | #define ZR050_SF_LO 0x012 | ||
| 61 | #define ZR050_AF_HI 0x013 | ||
| 62 | #define ZR050_AF_M 0x014 | ||
| 63 | #define ZR050_AF_LO 0x015 | ||
| 64 | #define ZR050_ACV_HI 0x016 | ||
| 65 | #define ZR050_ACV_MH 0x017 | ||
| 66 | #define ZR050_ACV_ML 0x018 | ||
| 67 | #define ZR050_ACV_LO 0x019 | ||
| 68 | #define ZR050_ACT_HI 0x01a | ||
| 69 | #define ZR050_ACT_MH 0x01b | ||
| 70 | #define ZR050_ACT_ML 0x01c | ||
| 71 | #define ZR050_ACT_LO 0x01d | ||
| 72 | #define ZR050_ACV_TRUN_HI 0x01e | ||
| 73 | #define ZR050_ACV_TRUN_MH 0x01f | ||
| 74 | #define ZR050_ACV_TRUN_ML 0x020 | ||
| 75 | #define ZR050_ACV_TRUN_LO 0x021 | ||
| 76 | #define ZR050_STATUS_0 0x02e | ||
| 77 | #define ZR050_STATUS_1 0x02f | ||
| 78 | |||
| 79 | #define ZR050_SOF_IDX 0x040 | ||
| 80 | #define ZR050_SOS1_IDX 0x07a | ||
| 81 | #define ZR050_SOS2_IDX 0x08a | ||
| 82 | #define ZR050_SOS3_IDX 0x09a | ||
| 83 | #define ZR050_SOS4_IDX 0x0aa | ||
| 84 | #define ZR050_DRI_IDX 0x0c0 | ||
| 85 | #define ZR050_DNL_IDX 0x0c6 | ||
| 86 | #define ZR050_DQT_IDX 0x0cc | ||
| 87 | #define ZR050_DHT_IDX 0x1d4 | ||
| 88 | #define ZR050_APP_IDX 0x380 | ||
| 89 | #define ZR050_COM_IDX 0x3c0 | ||
| 90 | |||
| 91 | /* zr36050 hardware register bits */ | ||
| 92 | |||
| 93 | #define ZR050_HW_BSWD 0x80 | ||
| 94 | #define ZR050_HW_MSTR 0x40 | ||
| 95 | #define ZR050_HW_DMA 0x20 | ||
| 96 | #define ZR050_HW_CFIS_1_CLK 0x00 | ||
| 97 | #define ZR050_HW_CFIS_2_CLK 0x04 | ||
| 98 | #define ZR050_HW_CFIS_3_CLK 0x08 | ||
| 99 | #define ZR050_HW_CFIS_4_CLK 0x0C | ||
| 100 | #define ZR050_HW_CFIS_5_CLK 0x10 | ||
| 101 | #define ZR050_HW_CFIS_6_CLK 0x14 | ||
| 102 | #define ZR050_HW_CFIS_7_CLK 0x18 | ||
| 103 | #define ZR050_HW_CFIS_8_CLK 0x1C | ||
| 104 | #define ZR050_HW_BELE 0x01 | ||
| 105 | |||
| 106 | /* zr36050 mode register bits */ | ||
| 107 | |||
| 108 | #define ZR050_MO_COMP 0x80 | ||
| 109 | #define ZR050_MO_ATP 0x40 | ||
| 110 | #define ZR050_MO_PASS2 0x20 | ||
| 111 | #define ZR050_MO_TLM 0x10 | ||
| 112 | #define ZR050_MO_DCONLY 0x08 | ||
| 113 | #define ZR050_MO_BRC 0x04 | ||
| 114 | |||
| 115 | #define ZR050_MO_ATP 0x40 | ||
| 116 | #define ZR050_MO_PASS2 0x20 | ||
| 117 | #define ZR050_MO_TLM 0x10 | ||
| 118 | #define ZR050_MO_DCONLY 0x08 | ||
| 119 | |||
| 120 | /* zr36050 option register bits */ | ||
| 121 | |||
| 122 | #define ZR050_OP_NSCN_1 0x00 | ||
| 123 | #define ZR050_OP_NSCN_2 0x20 | ||
| 124 | #define ZR050_OP_NSCN_3 0x40 | ||
| 125 | #define ZR050_OP_NSCN_4 0x60 | ||
| 126 | #define ZR050_OP_NSCN_5 0x80 | ||
| 127 | #define ZR050_OP_NSCN_6 0xA0 | ||
| 128 | #define ZR050_OP_NSCN_7 0xC0 | ||
| 129 | #define ZR050_OP_NSCN_8 0xE0 | ||
| 130 | #define ZR050_OP_OVF 0x10 | ||
| 131 | |||
| 132 | |||
| 133 | /* zr36050 markers-enable register bits */ | ||
| 134 | |||
| 135 | #define ZR050_ME_APP 0x80 | ||
| 136 | #define ZR050_ME_COM 0x40 | ||
| 137 | #define ZR050_ME_DRI 0x20 | ||
| 138 | #define ZR050_ME_DQT 0x10 | ||
| 139 | #define ZR050_ME_DHT 0x08 | ||
| 140 | #define ZR050_ME_DNL 0x04 | ||
| 141 | #define ZR050_ME_DQTI 0x02 | ||
| 142 | #define ZR050_ME_DHTI 0x01 | ||
| 143 | |||
| 144 | /* zr36050 status0/1 register bit masks */ | ||
| 145 | |||
| 146 | #define ZR050_ST_RST_MASK 0x20 | ||
| 147 | #define ZR050_ST_SOF_MASK 0x02 | ||
| 148 | #define ZR050_ST_SOS_MASK 0x02 | ||
| 149 | #define ZR050_ST_DATRDY_MASK 0x80 | ||
| 150 | #define ZR050_ST_MRKDET_MASK 0x40 | ||
| 151 | #define ZR050_ST_RFM_MASK 0x10 | ||
| 152 | #define ZR050_ST_RFD_MASK 0x08 | ||
| 153 | #define ZR050_ST_END_MASK 0x04 | ||
| 154 | #define ZR050_ST_TCVOVF_MASK 0x02 | ||
| 155 | #define ZR050_ST_DATOVF_MASK 0x01 | ||
| 156 | |||
| 157 | /* pixel component idx */ | ||
| 158 | |||
| 159 | #define ZR050_Y_COMPONENT 0 | ||
| 160 | #define ZR050_U_COMPONENT 1 | ||
| 161 | #define ZR050_V_COMPONENT 2 | ||
| 162 | |||
| 163 | #endif /*fndef ZR36050_H */ | ||
diff --git a/drivers/staging/media/zoran/zr36057.h b/drivers/staging/media/zoran/zr36057.h deleted file mode 100644 index c5138cef4ef5..000000000000 --- a/drivers/staging/media/zoran/zr36057.h +++ /dev/null | |||
| @@ -1,154 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * zr36057.h - zr36057 register offsets | ||
| 4 | * | ||
| 5 | * Copyright (C) 1998 Dave Perks <dperks@ibm.net> | ||
| 6 | */ | ||
| 7 | #ifndef _ZR36057_H_ | ||
| 8 | #define _ZR36057_H_ | ||
| 9 | |||
| 10 | |||
| 11 | /* Zoran ZR36057 registers */ | ||
| 12 | |||
| 13 | #define ZR36057_VFEHCR 0x000 /* Video Front End, Horizontal Configuration Register */ | ||
| 14 | #define ZR36057_VFEHCR_HSPol (1<<30) | ||
| 15 | #define ZR36057_VFEHCR_HStart 10 | ||
| 16 | #define ZR36057_VFEHCR_HEnd 0 | ||
| 17 | #define ZR36057_VFEHCR_Hmask 0x3ff | ||
| 18 | |||
| 19 | #define ZR36057_VFEVCR 0x004 /* Video Front End, Vertical Configuration Register */ | ||
| 20 | #define ZR36057_VFEVCR_VSPol (1<<30) | ||
| 21 | #define ZR36057_VFEVCR_VStart 10 | ||
| 22 | #define ZR36057_VFEVCR_VEnd 0 | ||
| 23 | #define ZR36057_VFEVCR_Vmask 0x3ff | ||
| 24 | |||
| 25 | #define ZR36057_VFESPFR 0x008 /* Video Front End, Scaler and Pixel Format Register */ | ||
| 26 | #define ZR36057_VFESPFR_ExtFl (1<<26) | ||
| 27 | #define ZR36057_VFESPFR_TopField (1<<25) | ||
| 28 | #define ZR36057_VFESPFR_VCLKPol (1<<24) | ||
| 29 | #define ZR36057_VFESPFR_HFilter 21 | ||
| 30 | #define ZR36057_VFESPFR_HorDcm 14 | ||
| 31 | #define ZR36057_VFESPFR_VerDcm 8 | ||
| 32 | #define ZR36057_VFESPFR_DispMode 6 | ||
| 33 | #define ZR36057_VFESPFR_YUV422 (0<<3) | ||
| 34 | #define ZR36057_VFESPFR_RGB888 (1<<3) | ||
| 35 | #define ZR36057_VFESPFR_RGB565 (2<<3) | ||
| 36 | #define ZR36057_VFESPFR_RGB555 (3<<3) | ||
| 37 | #define ZR36057_VFESPFR_ErrDif (1<<2) | ||
| 38 | #define ZR36057_VFESPFR_Pack24 (1<<1) | ||
| 39 | #define ZR36057_VFESPFR_LittleEndian (1<<0) | ||
| 40 | |||
| 41 | #define ZR36057_VDTR 0x00c /* Video Display "Top" Register */ | ||
| 42 | |||
| 43 | #define ZR36057_VDBR 0x010 /* Video Display "Bottom" Register */ | ||
| 44 | |||
| 45 | #define ZR36057_VSSFGR 0x014 /* Video Stride, Status, and Frame Grab Register */ | ||
| 46 | #define ZR36057_VSSFGR_DispStride 16 | ||
| 47 | #define ZR36057_VSSFGR_VidOvf (1<<8) | ||
| 48 | #define ZR36057_VSSFGR_SnapShot (1<<1) | ||
| 49 | #define ZR36057_VSSFGR_FrameGrab (1<<0) | ||
| 50 | |||
| 51 | #define ZR36057_VDCR 0x018 /* Video Display Configuration Register */ | ||
| 52 | #define ZR36057_VDCR_VidEn (1<<31) | ||
| 53 | #define ZR36057_VDCR_MinPix 24 | ||
| 54 | #define ZR36057_VDCR_Triton (1<<24) | ||
| 55 | #define ZR36057_VDCR_VidWinHt 12 | ||
| 56 | #define ZR36057_VDCR_VidWinWid 0 | ||
| 57 | |||
| 58 | #define ZR36057_MMTR 0x01c /* Masking Map "Top" Register */ | ||
| 59 | |||
| 60 | #define ZR36057_MMBR 0x020 /* Masking Map "Bottom" Register */ | ||
| 61 | |||
| 62 | #define ZR36057_OCR 0x024 /* Overlay Control Register */ | ||
| 63 | #define ZR36057_OCR_OvlEnable (1 << 15) | ||
| 64 | #define ZR36057_OCR_MaskStride 0 | ||
| 65 | |||
| 66 | #define ZR36057_SPGPPCR 0x028 /* System, PCI, and General Purpose Pins Control Register */ | ||
| 67 | #define ZR36057_SPGPPCR_SoftReset (1<<24) | ||
| 68 | |||
| 69 | #define ZR36057_GPPGCR1 0x02c /* General Purpose Pins and GuestBus Control Register (1) */ | ||
| 70 | |||
| 71 | #define ZR36057_MCSAR 0x030 /* MPEG Code Source Address Register */ | ||
| 72 | |||
| 73 | #define ZR36057_MCTCR 0x034 /* MPEG Code Transfer Control Register */ | ||
| 74 | #define ZR36057_MCTCR_CodTime (1 << 30) | ||
| 75 | #define ZR36057_MCTCR_CEmpty (1 << 29) | ||
| 76 | #define ZR36057_MCTCR_CFlush (1 << 28) | ||
| 77 | #define ZR36057_MCTCR_CodGuestID 20 | ||
| 78 | #define ZR36057_MCTCR_CodGuestReg 16 | ||
| 79 | |||
| 80 | #define ZR36057_MCMPR 0x038 /* MPEG Code Memory Pointer Register */ | ||
| 81 | |||
| 82 | #define ZR36057_ISR 0x03c /* Interrupt Status Register */ | ||
| 83 | #define ZR36057_ISR_GIRQ1 (1<<30) | ||
| 84 | #define ZR36057_ISR_GIRQ0 (1<<29) | ||
| 85 | #define ZR36057_ISR_CodRepIRQ (1<<28) | ||
| 86 | #define ZR36057_ISR_JPEGRepIRQ (1<<27) | ||
| 87 | |||
| 88 | #define ZR36057_ICR 0x040 /* Interrupt Control Register */ | ||
| 89 | #define ZR36057_ICR_GIRQ1 (1<<30) | ||
| 90 | #define ZR36057_ICR_GIRQ0 (1<<29) | ||
| 91 | #define ZR36057_ICR_CodRepIRQ (1<<28) | ||
| 92 | #define ZR36057_ICR_JPEGRepIRQ (1<<27) | ||
| 93 | #define ZR36057_ICR_IntPinEn (1<<24) | ||
| 94 | |||
| 95 | #define ZR36057_I2CBR 0x044 /* I2C Bus Register */ | ||
| 96 | #define ZR36057_I2CBR_SDA (1<<1) | ||
| 97 | #define ZR36057_I2CBR_SCL (1<<0) | ||
| 98 | |||
| 99 | #define ZR36057_JMC 0x100 /* JPEG Mode and Control */ | ||
| 100 | #define ZR36057_JMC_JPG (1 << 31) | ||
| 101 | #define ZR36057_JMC_JPGExpMode (0 << 29) | ||
| 102 | #define ZR36057_JMC_JPGCmpMode (1 << 29) | ||
| 103 | #define ZR36057_JMC_MJPGExpMode (2 << 29) | ||
| 104 | #define ZR36057_JMC_MJPGCmpMode (3 << 29) | ||
| 105 | #define ZR36057_JMC_RTBUSY_FB (1 << 6) | ||
| 106 | #define ZR36057_JMC_Go_en (1 << 5) | ||
| 107 | #define ZR36057_JMC_SyncMstr (1 << 4) | ||
| 108 | #define ZR36057_JMC_Fld_per_buff (1 << 3) | ||
| 109 | #define ZR36057_JMC_VFIFO_FB (1 << 2) | ||
| 110 | #define ZR36057_JMC_CFIFO_FB (1 << 1) | ||
| 111 | #define ZR36057_JMC_Stll_LitEndian (1 << 0) | ||
| 112 | |||
| 113 | #define ZR36057_JPC 0x104 /* JPEG Process Control */ | ||
| 114 | #define ZR36057_JPC_P_Reset (1 << 7) | ||
| 115 | #define ZR36057_JPC_CodTrnsEn (1 << 5) | ||
| 116 | #define ZR36057_JPC_Active (1 << 0) | ||
| 117 | |||
| 118 | #define ZR36057_VSP 0x108 /* Vertical Sync Parameters */ | ||
| 119 | #define ZR36057_VSP_VsyncSize 16 | ||
| 120 | #define ZR36057_VSP_FrmTot 0 | ||
| 121 | |||
| 122 | #define ZR36057_HSP 0x10c /* Horizontal Sync Parameters */ | ||
| 123 | #define ZR36057_HSP_HsyncStart 16 | ||
| 124 | #define ZR36057_HSP_LineTot 0 | ||
| 125 | |||
| 126 | #define ZR36057_FHAP 0x110 /* Field Horizontal Active Portion */ | ||
| 127 | #define ZR36057_FHAP_NAX 16 | ||
| 128 | #define ZR36057_FHAP_PAX 0 | ||
| 129 | |||
| 130 | #define ZR36057_FVAP 0x114 /* Field Vertical Active Portion */ | ||
| 131 | #define ZR36057_FVAP_NAY 16 | ||
| 132 | #define ZR36057_FVAP_PAY 0 | ||
| 133 | |||
| 134 | #define ZR36057_FPP 0x118 /* Field Process Parameters */ | ||
| 135 | #define ZR36057_FPP_Odd_Even (1 << 0) | ||
| 136 | |||
| 137 | #define ZR36057_JCBA 0x11c /* JPEG Code Base Address */ | ||
| 138 | |||
| 139 | #define ZR36057_JCFT 0x120 /* JPEG Code FIFO Threshold */ | ||
| 140 | |||
| 141 | #define ZR36057_JCGI 0x124 /* JPEG Codec Guest ID */ | ||
| 142 | #define ZR36057_JCGI_JPEGuestID 4 | ||
| 143 | #define ZR36057_JCGI_JPEGuestReg 0 | ||
| 144 | |||
| 145 | #define ZR36057_GCR2 0x12c /* GuestBus Control Register (2) */ | ||
| 146 | |||
| 147 | #define ZR36057_POR 0x200 /* Post Office Register */ | ||
| 148 | #define ZR36057_POR_POPen (1<<25) | ||
| 149 | #define ZR36057_POR_POTime (1<<24) | ||
| 150 | #define ZR36057_POR_PODir (1<<23) | ||
| 151 | |||
| 152 | #define ZR36057_STR 0x300 /* "Still" Transfer Register */ | ||
| 153 | |||
| 154 | #endif | ||
diff --git a/drivers/staging/media/zoran/zr36060.c b/drivers/staging/media/zoran/zr36060.c deleted file mode 100644 index a3c817fd5c07..000000000000 --- a/drivers/staging/media/zoran/zr36060.c +++ /dev/null | |||
| @@ -1,994 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36060 basic configuration functions | ||
| 4 | * | ||
| 5 | * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 6 | */ | ||
| 7 | #define ZR060_VERSION "v0.7" | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | |||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/wait.h> | ||
| 16 | |||
| 17 | /* I/O commands, error codes */ | ||
| 18 | #include <asm/io.h> | ||
| 19 | |||
| 20 | /* headerfile of this module */ | ||
| 21 | #include "zr36060.h" | ||
| 22 | |||
| 23 | /* codec io API */ | ||
| 24 | #include "videocodec.h" | ||
| 25 | |||
| 26 | /* it doesn't make sense to have more than 20 or so, | ||
| 27 | * just to prevent some unwanted loops | ||
| 28 | */ | ||
| 29 | #define MAX_CODECS 20 | ||
| 30 | |||
| 31 | /* amount of chips attached via this driver */ | ||
| 32 | static int zr36060_codecs; | ||
| 33 | |||
| 34 | static bool low_bitrate; | ||
| 35 | module_param(low_bitrate, bool, 0); | ||
| 36 | MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); | ||
| 37 | |||
| 38 | /* debugging is available via module parameter */ | ||
| 39 | static int debug; | ||
| 40 | module_param(debug, int, 0); | ||
| 41 | MODULE_PARM_DESC(debug, "Debug level (0-4)"); | ||
| 42 | |||
| 43 | #define dprintk(num, format, args...) \ | ||
| 44 | do { \ | ||
| 45 | if (debug >= num) \ | ||
| 46 | printk(format, ##args); \ | ||
| 47 | } while (0) | ||
| 48 | |||
| 49 | /* ========================================================================= | ||
| 50 | Local hardware I/O functions: | ||
| 51 | |||
| 52 | read/write via codec layer (registers are located in the master device) | ||
| 53 | ========================================================================= */ | ||
| 54 | |||
| 55 | /* read and write functions */ | ||
| 56 | static u8 | ||
| 57 | zr36060_read (struct zr36060 *ptr, | ||
| 58 | u16 reg) | ||
| 59 | { | ||
| 60 | u8 value = 0; | ||
| 61 | |||
| 62 | // just in case something is wrong... | ||
| 63 | if (ptr->codec->master_data->readreg) | ||
| 64 | value = (ptr->codec->master_data->readreg(ptr->codec, | ||
| 65 | reg)) & 0xff; | ||
| 66 | else | ||
| 67 | dprintk(1, | ||
| 68 | KERN_ERR "%s: invalid I/O setup, nothing read!\n", | ||
| 69 | ptr->name); | ||
| 70 | |||
| 71 | //dprintk(4, "%s: reading from 0x%04x: %02x\n",ptr->name,reg,value); | ||
| 72 | |||
| 73 | return value; | ||
| 74 | } | ||
| 75 | |||
| 76 | static void | ||
| 77 | zr36060_write(struct zr36060 *ptr, | ||
| 78 | u16 reg, | ||
| 79 | u8 value) | ||
| 80 | { | ||
| 81 | //dprintk(4, "%s: writing 0x%02x to 0x%04x\n",ptr->name,value,reg); | ||
| 82 | dprintk(4, "0x%02x @0x%04x\n", value, reg); | ||
| 83 | |||
| 84 | // just in case something is wrong... | ||
| 85 | if (ptr->codec->master_data->writereg) | ||
| 86 | ptr->codec->master_data->writereg(ptr->codec, reg, value); | ||
| 87 | else | ||
| 88 | dprintk(1, | ||
| 89 | KERN_ERR | ||
| 90 | "%s: invalid I/O setup, nothing written!\n", | ||
| 91 | ptr->name); | ||
| 92 | } | ||
| 93 | |||
| 94 | /* ========================================================================= | ||
| 95 | Local helper function: | ||
| 96 | |||
| 97 | status read | ||
| 98 | ========================================================================= */ | ||
| 99 | |||
| 100 | /* status is kept in datastructure */ | ||
| 101 | static u8 | ||
| 102 | zr36060_read_status (struct zr36060 *ptr) | ||
| 103 | { | ||
| 104 | ptr->status = zr36060_read(ptr, ZR060_CFSR); | ||
| 105 | |||
| 106 | zr36060_read(ptr, 0); | ||
| 107 | return ptr->status; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* ========================================================================= | ||
| 111 | Local helper function: | ||
| 112 | |||
| 113 | scale factor read | ||
| 114 | ========================================================================= */ | ||
| 115 | |||
| 116 | /* scale factor is kept in datastructure */ | ||
| 117 | static u16 | ||
| 118 | zr36060_read_scalefactor (struct zr36060 *ptr) | ||
| 119 | { | ||
| 120 | ptr->scalefact = (zr36060_read(ptr, ZR060_SF_HI) << 8) | | ||
| 121 | (zr36060_read(ptr, ZR060_SF_LO) & 0xFF); | ||
| 122 | |||
| 123 | /* leave 0 selected for an eventually GO from master */ | ||
| 124 | zr36060_read(ptr, 0); | ||
| 125 | return ptr->scalefact; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* ========================================================================= | ||
| 129 | Local helper function: | ||
| 130 | |||
| 131 | wait if codec is ready to proceed (end of processing) or time is over | ||
| 132 | ========================================================================= */ | ||
| 133 | |||
| 134 | static void | ||
| 135 | zr36060_wait_end (struct zr36060 *ptr) | ||
| 136 | { | ||
| 137 | int i = 0; | ||
| 138 | |||
| 139 | while (zr36060_read_status(ptr) & ZR060_CFSR_Busy) { | ||
| 140 | udelay(1); | ||
| 141 | if (i++ > 200000) { // 200ms, there is for sure something wrong!!! | ||
| 142 | dprintk(1, | ||
| 143 | "%s: timeout at wait_end (last status: 0x%02x)\n", | ||
| 144 | ptr->name, ptr->status); | ||
| 145 | break; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | /* ========================================================================= | ||
| 151 | Local helper function: | ||
| 152 | |||
| 153 | basic test of "connectivity", writes/reads to/from memory the SOF marker | ||
| 154 | ========================================================================= */ | ||
| 155 | |||
| 156 | static int | ||
| 157 | zr36060_basic_test (struct zr36060 *ptr) | ||
| 158 | { | ||
| 159 | if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) && | ||
| 160 | (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) { | ||
| 161 | dprintk(1, | ||
| 162 | KERN_ERR | ||
| 163 | "%s: attach failed, can't connect to jpeg processor!\n", | ||
| 164 | ptr->name); | ||
| 165 | return -ENXIO; | ||
| 166 | } | ||
| 167 | |||
| 168 | zr36060_wait_end(ptr); | ||
| 169 | if (ptr->status & ZR060_CFSR_Busy) { | ||
| 170 | dprintk(1, | ||
| 171 | KERN_ERR | ||
| 172 | "%s: attach failed, jpeg processor failed (end flag)!\n", | ||
| 173 | ptr->name); | ||
| 174 | return -EBUSY; | ||
| 175 | } | ||
| 176 | |||
| 177 | return 0; /* looks good! */ | ||
| 178 | } | ||
| 179 | |||
| 180 | /* ========================================================================= | ||
| 181 | Local helper function: | ||
| 182 | |||
| 183 | simple loop for pushing the init datasets | ||
| 184 | ========================================================================= */ | ||
| 185 | |||
| 186 | static int | ||
| 187 | zr36060_pushit (struct zr36060 *ptr, | ||
| 188 | u16 startreg, | ||
| 189 | u16 len, | ||
| 190 | const char *data) | ||
| 191 | { | ||
| 192 | int i = 0; | ||
| 193 | |||
| 194 | dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, | ||
| 195 | startreg, len); | ||
| 196 | while (i < len) { | ||
| 197 | zr36060_write(ptr, startreg++, data[i++]); | ||
| 198 | } | ||
| 199 | |||
| 200 | return i; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* ========================================================================= | ||
| 204 | Basic datasets: | ||
| 205 | |||
| 206 | jpeg baseline setup data (you find it on lots places in internet, or just | ||
| 207 | extract it from any regular .jpg image...) | ||
| 208 | |||
| 209 | Could be variable, but until it's not needed it they are just fixed to save | ||
| 210 | memory. Otherwise expand zr36060 structure with arrays, push the values to | ||
| 211 | it and initialize from there, as e.g. the linux zr36057/60 driver does it. | ||
| 212 | ========================================================================= */ | ||
| 213 | |||
| 214 | static const char zr36060_dqt[0x86] = { | ||
| 215 | 0xff, 0xdb, //Marker: DQT | ||
| 216 | 0x00, 0x84, //Length: 2*65+2 | ||
| 217 | 0x00, //Pq,Tq first table | ||
| 218 | 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, | ||
| 219 | 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, | ||
| 220 | 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, | ||
| 221 | 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33, | ||
| 222 | 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44, | ||
| 223 | 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, | ||
| 224 | 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, | ||
| 225 | 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63, | ||
| 226 | 0x01, //Pq,Tq second table | ||
| 227 | 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a, | ||
| 228 | 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63, | ||
| 229 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 230 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 231 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 232 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 233 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
| 234 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 | ||
| 235 | }; | ||
| 236 | |||
| 237 | static const char zr36060_dht[0x1a4] = { | ||
| 238 | 0xff, 0xc4, //Marker: DHT | ||
| 239 | 0x01, 0xa2, //Length: 2*AC, 2*DC | ||
| 240 | 0x00, //DC first table | ||
| 241 | 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
| 242 | 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
| 243 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
| 244 | 0x01, //DC second table | ||
| 245 | 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
| 246 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
| 247 | 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, | ||
| 248 | 0x10, //AC first table | ||
| 249 | 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, | ||
| 250 | 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, | ||
| 251 | 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, | ||
| 252 | 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, | ||
| 253 | 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, | ||
| 254 | 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, | ||
| 255 | 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, | ||
| 256 | 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, | ||
| 257 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
| 258 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
| 259 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
| 260 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
| 261 | 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | ||
| 262 | 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, | ||
| 263 | 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, | ||
| 264 | 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, | ||
| 265 | 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, | ||
| 266 | 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, | ||
| 267 | 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
| 268 | 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, | ||
| 269 | 0xF8, 0xF9, 0xFA, | ||
| 270 | 0x11, //AC second table | ||
| 271 | 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, | ||
| 272 | 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, | ||
| 273 | 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, | ||
| 274 | 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | ||
| 275 | 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, | ||
| 276 | 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, | ||
| 277 | 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, | ||
| 278 | 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, | ||
| 279 | 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, | ||
| 280 | 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, | ||
| 281 | 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, | ||
| 282 | 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | ||
| 283 | 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | ||
| 284 | 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | ||
| 285 | 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, | ||
| 286 | 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, | ||
| 287 | 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, | ||
| 288 | 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, | ||
| 289 | 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, | ||
| 290 | 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, | ||
| 291 | 0xF9, 0xFA | ||
| 292 | }; | ||
| 293 | |||
| 294 | /* jpeg baseline setup, this is just fixed in this driver (YUV pictures) */ | ||
| 295 | #define NO_OF_COMPONENTS 0x3 //Y,U,V | ||
| 296 | #define BASELINE_PRECISION 0x8 //MCU size (?) | ||
| 297 | static const char zr36060_tq[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's QT | ||
| 298 | static const char zr36060_td[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's DC | ||
| 299 | static const char zr36060_ta[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; //table idx's AC | ||
| 300 | |||
| 301 | /* horizontal 422 decimation setup (maybe we support 411 or so later, too) */ | ||
| 302 | static const char zr36060_decimation_h[8] = { 2, 1, 1, 0, 0, 0, 0, 0 }; | ||
| 303 | static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; | ||
| 304 | |||
| 305 | /* ========================================================================= | ||
| 306 | Local helper functions: | ||
| 307 | |||
| 308 | calculation and setup of parameter-dependent JPEG baseline segments | ||
| 309 | (needed for compression only) | ||
| 310 | ========================================================================= */ | ||
| 311 | |||
| 312 | /* ------------------------------------------------------------------------- */ | ||
| 313 | |||
| 314 | /* SOF (start of frame) segment depends on width, height and sampling ratio | ||
| 315 | of each color component */ | ||
| 316 | |||
| 317 | static int | ||
| 318 | zr36060_set_sof (struct zr36060 *ptr) | ||
| 319 | { | ||
| 320 | char sof_data[34]; // max. size of register set | ||
| 321 | int i; | ||
| 322 | |||
| 323 | dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, | ||
| 324 | ptr->width, ptr->height, NO_OF_COMPONENTS); | ||
| 325 | sof_data[0] = 0xff; | ||
| 326 | sof_data[1] = 0xc0; | ||
| 327 | sof_data[2] = 0x00; | ||
| 328 | sof_data[3] = (3 * NO_OF_COMPONENTS) + 8; | ||
| 329 | sof_data[4] = BASELINE_PRECISION; // only '8' possible with zr36060 | ||
| 330 | sof_data[5] = (ptr->height) >> 8; | ||
| 331 | sof_data[6] = (ptr->height) & 0xff; | ||
| 332 | sof_data[7] = (ptr->width) >> 8; | ||
| 333 | sof_data[8] = (ptr->width) & 0xff; | ||
| 334 | sof_data[9] = NO_OF_COMPONENTS; | ||
| 335 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
| 336 | sof_data[10 + (i * 3)] = i; // index identifier | ||
| 337 | sof_data[11 + (i * 3)] = (ptr->h_samp_ratio[i] << 4) | | ||
| 338 | (ptr->v_samp_ratio[i]); // sampling ratios | ||
| 339 | sof_data[12 + (i * 3)] = zr36060_tq[i]; // Q table selection | ||
| 340 | } | ||
| 341 | return zr36060_pushit(ptr, ZR060_SOF_IDX, | ||
| 342 | (3 * NO_OF_COMPONENTS) + 10, sof_data); | ||
| 343 | } | ||
| 344 | |||
| 345 | /* ------------------------------------------------------------------------- */ | ||
| 346 | |||
| 347 | /* SOS (start of scan) segment depends on the used scan components | ||
| 348 | of each color component */ | ||
| 349 | |||
| 350 | static int | ||
| 351 | zr36060_set_sos (struct zr36060 *ptr) | ||
| 352 | { | ||
| 353 | char sos_data[16]; // max. size of register set | ||
| 354 | int i; | ||
| 355 | |||
| 356 | dprintk(3, "%s: write SOS\n", ptr->name); | ||
| 357 | sos_data[0] = 0xff; | ||
| 358 | sos_data[1] = 0xda; | ||
| 359 | sos_data[2] = 0x00; | ||
| 360 | sos_data[3] = 2 + 1 + (2 * NO_OF_COMPONENTS) + 3; | ||
| 361 | sos_data[4] = NO_OF_COMPONENTS; | ||
| 362 | for (i = 0; i < NO_OF_COMPONENTS; i++) { | ||
| 363 | sos_data[5 + (i * 2)] = i; // index | ||
| 364 | sos_data[6 + (i * 2)] = (zr36060_td[i] << 4) | | ||
| 365 | zr36060_ta[i]; // AC/DC tbl.sel. | ||
| 366 | } | ||
| 367 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 2] = 00; // scan start | ||
| 368 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 3] = 0x3f; | ||
| 369 | sos_data[2 + 1 + (2 * NO_OF_COMPONENTS) + 4] = 00; | ||
| 370 | return zr36060_pushit(ptr, ZR060_SOS_IDX, | ||
| 371 | 4 + 1 + (2 * NO_OF_COMPONENTS) + 3, | ||
| 372 | sos_data); | ||
| 373 | } | ||
| 374 | |||
| 375 | /* ------------------------------------------------------------------------- */ | ||
| 376 | |||
| 377 | /* DRI (define restart interval) */ | ||
| 378 | |||
| 379 | static int | ||
| 380 | zr36060_set_dri (struct zr36060 *ptr) | ||
| 381 | { | ||
| 382 | char dri_data[6]; // max. size of register set | ||
| 383 | |||
| 384 | dprintk(3, "%s: write DRI\n", ptr->name); | ||
| 385 | dri_data[0] = 0xff; | ||
| 386 | dri_data[1] = 0xdd; | ||
| 387 | dri_data[2] = 0x00; | ||
| 388 | dri_data[3] = 0x04; | ||
| 389 | dri_data[4] = (ptr->dri) >> 8; | ||
| 390 | dri_data[5] = (ptr->dri) & 0xff; | ||
| 391 | return zr36060_pushit(ptr, ZR060_DRI_IDX, 6, dri_data); | ||
| 392 | } | ||
| 393 | |||
| 394 | /* ========================================================================= | ||
| 395 | Setup function: | ||
| 396 | |||
| 397 | Setup compression/decompression of Zoran's JPEG processor | ||
| 398 | ( see also zoran 36060 manual ) | ||
| 399 | |||
| 400 | ... sorry for the spaghetti code ... | ||
| 401 | ========================================================================= */ | ||
| 402 | static void | ||
| 403 | zr36060_init (struct zr36060 *ptr) | ||
| 404 | { | ||
| 405 | int sum = 0; | ||
| 406 | long bitcnt, tmp; | ||
| 407 | |||
| 408 | if (ptr->mode == CODEC_DO_COMPRESSION) { | ||
| 409 | dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); | ||
| 410 | |||
| 411 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
| 412 | |||
| 413 | /* 060 communicates with 067 in master mode */ | ||
| 414 | zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); | ||
| 415 | |||
| 416 | /* Compression with or without variable scale factor */ | ||
| 417 | /*FIXME: What about ptr->bitrate_ctrl? */ | ||
| 418 | zr36060_write(ptr, ZR060_CMR, | ||
| 419 | ZR060_CMR_Comp | ZR060_CMR_Pass2 | | ||
| 420 | ZR060_CMR_BRB); | ||
| 421 | |||
| 422 | /* Must be zero */ | ||
| 423 | zr36060_write(ptr, ZR060_MBZ, 0x00); | ||
| 424 | zr36060_write(ptr, ZR060_TCR_HI, 0x00); | ||
| 425 | zr36060_write(ptr, ZR060_TCR_LO, 0x00); | ||
| 426 | |||
| 427 | /* Disable all IRQs - no DataErr means autoreset */ | ||
| 428 | zr36060_write(ptr, ZR060_IMR, 0); | ||
| 429 | |||
| 430 | /* volume control settings */ | ||
| 431 | zr36060_write(ptr, ZR060_SF_HI, ptr->scalefact >> 8); | ||
| 432 | zr36060_write(ptr, ZR060_SF_LO, ptr->scalefact & 0xff); | ||
| 433 | |||
| 434 | zr36060_write(ptr, ZR060_AF_HI, 0xff); | ||
| 435 | zr36060_write(ptr, ZR060_AF_M, 0xff); | ||
| 436 | zr36060_write(ptr, ZR060_AF_LO, 0xff); | ||
| 437 | |||
| 438 | /* setup the variable jpeg tables */ | ||
| 439 | sum += zr36060_set_sof(ptr); | ||
| 440 | sum += zr36060_set_sos(ptr); | ||
| 441 | sum += zr36060_set_dri(ptr); | ||
| 442 | |||
| 443 | /* setup the fixed jpeg tables - maybe variable, though - | ||
| 444 | * (see table init section above) */ | ||
| 445 | sum += | ||
| 446 | zr36060_pushit(ptr, ZR060_DQT_IDX, sizeof(zr36060_dqt), | ||
| 447 | zr36060_dqt); | ||
| 448 | sum += | ||
| 449 | zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), | ||
| 450 | zr36060_dht); | ||
| 451 | zr36060_write(ptr, ZR060_APP_IDX, 0xff); | ||
| 452 | zr36060_write(ptr, ZR060_APP_IDX + 1, 0xe0 + ptr->app.appn); | ||
| 453 | zr36060_write(ptr, ZR060_APP_IDX + 2, 0x00); | ||
| 454 | zr36060_write(ptr, ZR060_APP_IDX + 3, ptr->app.len + 2); | ||
| 455 | sum += zr36060_pushit(ptr, ZR060_APP_IDX + 4, 60, | ||
| 456 | ptr->app.data) + 4; | ||
| 457 | zr36060_write(ptr, ZR060_COM_IDX, 0xff); | ||
| 458 | zr36060_write(ptr, ZR060_COM_IDX + 1, 0xfe); | ||
| 459 | zr36060_write(ptr, ZR060_COM_IDX + 2, 0x00); | ||
| 460 | zr36060_write(ptr, ZR060_COM_IDX + 3, ptr->com.len + 2); | ||
| 461 | sum += zr36060_pushit(ptr, ZR060_COM_IDX + 4, 60, | ||
| 462 | ptr->com.data) + 4; | ||
| 463 | |||
| 464 | /* setup misc. data for compression (target code sizes) */ | ||
| 465 | |||
| 466 | /* size of compressed code to reach without header data */ | ||
| 467 | sum = ptr->real_code_vol - sum; | ||
| 468 | bitcnt = sum << 3; /* need the size in bits */ | ||
| 469 | |||
| 470 | tmp = bitcnt >> 16; | ||
| 471 | dprintk(3, | ||
| 472 | "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", | ||
| 473 | ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); | ||
| 474 | zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8); | ||
| 475 | zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff); | ||
| 476 | tmp = bitcnt & 0xffff; | ||
| 477 | zr36060_write(ptr, ZR060_TCV_NET_ML, tmp >> 8); | ||
| 478 | zr36060_write(ptr, ZR060_TCV_NET_LO, tmp & 0xff); | ||
| 479 | |||
| 480 | bitcnt -= bitcnt >> 7; // bits without stuffing | ||
| 481 | bitcnt -= ((bitcnt * 5) >> 6); // bits without eob | ||
| 482 | |||
| 483 | tmp = bitcnt >> 16; | ||
| 484 | dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", | ||
| 485 | ptr->name, bitcnt, tmp); | ||
| 486 | zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8); | ||
| 487 | zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff); | ||
| 488 | tmp = bitcnt & 0xffff; | ||
| 489 | zr36060_write(ptr, ZR060_TCV_DATA_ML, tmp >> 8); | ||
| 490 | zr36060_write(ptr, ZR060_TCV_DATA_LO, tmp & 0xff); | ||
| 491 | |||
| 492 | /* JPEG markers to be included in the compressed stream */ | ||
| 493 | zr36060_write(ptr, ZR060_MER, | ||
| 494 | ZR060_MER_DQT | ZR060_MER_DHT | | ||
| 495 | ((ptr->com.len > 0) ? ZR060_MER_Com : 0) | | ||
| 496 | ((ptr->app.len > 0) ? ZR060_MER_App : 0)); | ||
| 497 | |||
| 498 | /* Setup the Video Frontend */ | ||
| 499 | /* Limit pixel range to 16..235 as per CCIR-601 */ | ||
| 500 | zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); | ||
| 501 | |||
| 502 | } else { | ||
| 503 | dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); | ||
| 504 | |||
| 505 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
| 506 | |||
| 507 | /* 060 communicates with 067 in master mode */ | ||
| 508 | zr36060_write(ptr, ZR060_CIR, ZR060_CIR_CodeMstr); | ||
| 509 | |||
| 510 | /* Decompression */ | ||
| 511 | zr36060_write(ptr, ZR060_CMR, 0); | ||
| 512 | |||
| 513 | /* Must be zero */ | ||
| 514 | zr36060_write(ptr, ZR060_MBZ, 0x00); | ||
| 515 | zr36060_write(ptr, ZR060_TCR_HI, 0x00); | ||
| 516 | zr36060_write(ptr, ZR060_TCR_LO, 0x00); | ||
| 517 | |||
| 518 | /* Disable all IRQs - no DataErr means autoreset */ | ||
| 519 | zr36060_write(ptr, ZR060_IMR, 0); | ||
| 520 | |||
| 521 | /* setup misc. data for expansion */ | ||
| 522 | zr36060_write(ptr, ZR060_MER, 0); | ||
| 523 | |||
| 524 | /* setup the fixed jpeg tables - maybe variable, though - | ||
| 525 | * (see table init section above) */ | ||
| 526 | zr36060_pushit(ptr, ZR060_DHT_IDX, sizeof(zr36060_dht), | ||
| 527 | zr36060_dht); | ||
| 528 | |||
| 529 | /* Setup the Video Frontend */ | ||
| 530 | //zr36060_write(ptr, ZR060_VCR, ZR060_VCR_FIExt); | ||
| 531 | //this doesn't seem right and doesn't work... | ||
| 532 | zr36060_write(ptr, ZR060_VCR, ZR060_VCR_Range); | ||
| 533 | } | ||
| 534 | |||
| 535 | /* Load the tables */ | ||
| 536 | zr36060_write(ptr, ZR060_LOAD, | ||
| 537 | ZR060_LOAD_SyncRst | ZR060_LOAD_Load); | ||
| 538 | zr36060_wait_end(ptr); | ||
| 539 | dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, | ||
| 540 | ptr->status); | ||
| 541 | |||
| 542 | if (ptr->status & ZR060_CFSR_Busy) { | ||
| 543 | dprintk(1, KERN_ERR "%s: init aborted!\n", ptr->name); | ||
| 544 | return; // something is wrong, its timed out!!!! | ||
| 545 | } | ||
| 546 | } | ||
| 547 | |||
| 548 | /* ========================================================================= | ||
| 549 | CODEC API FUNCTIONS | ||
| 550 | |||
| 551 | this functions are accessed by the master via the API structure | ||
| 552 | ========================================================================= */ | ||
| 553 | |||
| 554 | /* set compression/expansion mode and launches codec - | ||
| 555 | this should be the last call from the master before starting processing */ | ||
| 556 | static int | ||
| 557 | zr36060_set_mode (struct videocodec *codec, | ||
| 558 | int mode) | ||
| 559 | { | ||
| 560 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
| 561 | |||
| 562 | dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); | ||
| 563 | |||
| 564 | if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) | ||
| 565 | return -EINVAL; | ||
| 566 | |||
| 567 | ptr->mode = mode; | ||
| 568 | zr36060_init(ptr); | ||
| 569 | |||
| 570 | return 0; | ||
| 571 | } | ||
| 572 | |||
| 573 | /* set picture size (norm is ignored as the codec doesn't know about it) */ | ||
| 574 | static int | ||
| 575 | zr36060_set_video (struct videocodec *codec, | ||
| 576 | struct tvnorm *norm, | ||
| 577 | struct vfe_settings *cap, | ||
| 578 | struct vfe_polarity *pol) | ||
| 579 | { | ||
| 580 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
| 581 | u32 reg; | ||
| 582 | int size; | ||
| 583 | |||
| 584 | dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, | ||
| 585 | cap->x, cap->y, cap->width, cap->height, cap->decimation); | ||
| 586 | |||
| 587 | /* if () return -EINVAL; | ||
| 588 | * trust the master driver that it knows what it does - so | ||
| 589 | * we allow invalid startx/y and norm for now ... */ | ||
| 590 | ptr->width = cap->width / (cap->decimation & 0xff); | ||
| 591 | ptr->height = cap->height / (cap->decimation >> 8); | ||
| 592 | |||
| 593 | zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SyncRst); | ||
| 594 | |||
| 595 | /* Note that VSPol/HSPol bits in zr36060 have the opposite | ||
| 596 | * meaning of their zr360x7 counterparts with the same names | ||
| 597 | * N.b. for VSPol this is only true if FIVEdge = 0 (default, | ||
| 598 | * left unchanged here - in accordance with datasheet). | ||
| 599 | */ | ||
| 600 | reg = (!pol->vsync_pol ? ZR060_VPR_VSPol : 0) | ||
| 601 | | (!pol->hsync_pol ? ZR060_VPR_HSPol : 0) | ||
| 602 | | (pol->field_pol ? ZR060_VPR_FIPol : 0) | ||
| 603 | | (pol->blank_pol ? ZR060_VPR_BLPol : 0) | ||
| 604 | | (pol->subimg_pol ? ZR060_VPR_SImgPol : 0) | ||
| 605 | | (pol->poe_pol ? ZR060_VPR_PoePol : 0) | ||
| 606 | | (pol->pvalid_pol ? ZR060_VPR_PValPol : 0) | ||
| 607 | | (pol->vclk_pol ? ZR060_VPR_VCLKPol : 0); | ||
| 608 | zr36060_write(ptr, ZR060_VPR, reg); | ||
| 609 | |||
| 610 | reg = 0; | ||
| 611 | switch (cap->decimation & 0xff) { | ||
| 612 | default: | ||
| 613 | case 1: | ||
| 614 | break; | ||
| 615 | |||
| 616 | case 2: | ||
| 617 | reg |= ZR060_SR_HScale2; | ||
| 618 | break; | ||
| 619 | |||
| 620 | case 4: | ||
| 621 | reg |= ZR060_SR_HScale4; | ||
| 622 | break; | ||
| 623 | } | ||
| 624 | |||
| 625 | switch (cap->decimation >> 8) { | ||
| 626 | default: | ||
| 627 | case 1: | ||
| 628 | break; | ||
| 629 | |||
| 630 | case 2: | ||
| 631 | reg |= ZR060_SR_VScale; | ||
| 632 | break; | ||
| 633 | } | ||
| 634 | zr36060_write(ptr, ZR060_SR, reg); | ||
| 635 | |||
| 636 | zr36060_write(ptr, ZR060_BCR_Y, 0x00); | ||
| 637 | zr36060_write(ptr, ZR060_BCR_U, 0x80); | ||
| 638 | zr36060_write(ptr, ZR060_BCR_V, 0x80); | ||
| 639 | |||
| 640 | /* sync generator */ | ||
| 641 | |||
| 642 | reg = norm->Ht - 1; /* Vtotal */ | ||
| 643 | zr36060_write(ptr, ZR060_SGR_VTOTAL_HI, (reg >> 8) & 0xff); | ||
| 644 | zr36060_write(ptr, ZR060_SGR_VTOTAL_LO, (reg >> 0) & 0xff); | ||
| 645 | |||
| 646 | reg = norm->Wt - 1; /* Htotal */ | ||
| 647 | zr36060_write(ptr, ZR060_SGR_HTOTAL_HI, (reg >> 8) & 0xff); | ||
| 648 | zr36060_write(ptr, ZR060_SGR_HTOTAL_LO, (reg >> 0) & 0xff); | ||
| 649 | |||
| 650 | reg = 6 - 1; /* VsyncSize */ | ||
| 651 | zr36060_write(ptr, ZR060_SGR_VSYNC, reg); | ||
| 652 | |||
| 653 | //reg = 30 - 1; /* HsyncSize */ | ||
| 654 | ///*CP*/ reg = (zr->params.norm == 1 ? 57 : 68); | ||
| 655 | reg = 68; | ||
| 656 | zr36060_write(ptr, ZR060_SGR_HSYNC, reg); | ||
| 657 | |||
| 658 | reg = norm->VStart - 1; /* BVstart */ | ||
| 659 | zr36060_write(ptr, ZR060_SGR_BVSTART, reg); | ||
| 660 | |||
| 661 | reg += norm->Ha / 2; /* BVend */ | ||
| 662 | zr36060_write(ptr, ZR060_SGR_BVEND_HI, (reg >> 8) & 0xff); | ||
| 663 | zr36060_write(ptr, ZR060_SGR_BVEND_LO, (reg >> 0) & 0xff); | ||
| 664 | |||
| 665 | reg = norm->HStart - 1; /* BHstart */ | ||
| 666 | zr36060_write(ptr, ZR060_SGR_BHSTART, reg); | ||
| 667 | |||
| 668 | reg += norm->Wa; /* BHend */ | ||
| 669 | zr36060_write(ptr, ZR060_SGR_BHEND_HI, (reg >> 8) & 0xff); | ||
| 670 | zr36060_write(ptr, ZR060_SGR_BHEND_LO, (reg >> 0) & 0xff); | ||
| 671 | |||
| 672 | /* active area */ | ||
| 673 | reg = cap->y + norm->VStart; /* Vstart */ | ||
| 674 | zr36060_write(ptr, ZR060_AAR_VSTART_HI, (reg >> 8) & 0xff); | ||
| 675 | zr36060_write(ptr, ZR060_AAR_VSTART_LO, (reg >> 0) & 0xff); | ||
| 676 | |||
| 677 | reg += cap->height; /* Vend */ | ||
| 678 | zr36060_write(ptr, ZR060_AAR_VEND_HI, (reg >> 8) & 0xff); | ||
| 679 | zr36060_write(ptr, ZR060_AAR_VEND_LO, (reg >> 0) & 0xff); | ||
| 680 | |||
| 681 | reg = cap->x + norm->HStart; /* Hstart */ | ||
| 682 | zr36060_write(ptr, ZR060_AAR_HSTART_HI, (reg >> 8) & 0xff); | ||
| 683 | zr36060_write(ptr, ZR060_AAR_HSTART_LO, (reg >> 0) & 0xff); | ||
| 684 | |||
| 685 | reg += cap->width; /* Hend */ | ||
| 686 | zr36060_write(ptr, ZR060_AAR_HEND_HI, (reg >> 8) & 0xff); | ||
| 687 | zr36060_write(ptr, ZR060_AAR_HEND_LO, (reg >> 0) & 0xff); | ||
| 688 | |||
| 689 | /* subimage area */ | ||
| 690 | reg = norm->VStart - 4; /* SVstart */ | ||
| 691 | zr36060_write(ptr, ZR060_SWR_VSTART_HI, (reg >> 8) & 0xff); | ||
| 692 | zr36060_write(ptr, ZR060_SWR_VSTART_LO, (reg >> 0) & 0xff); | ||
| 693 | |||
| 694 | reg += norm->Ha / 2 + 8; /* SVend */ | ||
| 695 | zr36060_write(ptr, ZR060_SWR_VEND_HI, (reg >> 8) & 0xff); | ||
| 696 | zr36060_write(ptr, ZR060_SWR_VEND_LO, (reg >> 0) & 0xff); | ||
| 697 | |||
| 698 | reg = norm->HStart /*+ 64 */ - 4; /* SHstart */ | ||
| 699 | zr36060_write(ptr, ZR060_SWR_HSTART_HI, (reg >> 8) & 0xff); | ||
| 700 | zr36060_write(ptr, ZR060_SWR_HSTART_LO, (reg >> 0) & 0xff); | ||
| 701 | |||
| 702 | reg += norm->Wa + 8; /* SHend */ | ||
| 703 | zr36060_write(ptr, ZR060_SWR_HEND_HI, (reg >> 8) & 0xff); | ||
| 704 | zr36060_write(ptr, ZR060_SWR_HEND_LO, (reg >> 0) & 0xff); | ||
| 705 | |||
| 706 | size = ptr->width * ptr->height; | ||
| 707 | /* Target compressed field size in bits: */ | ||
| 708 | size = size * 16; /* uncompressed size in bits */ | ||
| 709 | /* (Ronald) by default, quality = 100 is a compression | ||
| 710 | * ratio 1:2. Setting low_bitrate (insmod option) sets | ||
| 711 | * it to 1:4 (instead of 1:2, zr36060 max) as limit because the | ||
| 712 | * buz can't handle more at decimation=1... Use low_bitrate if | ||
| 713 | * you have a Buz, unless you know what you're doing | ||
| 714 | */ | ||
| 715 | size = size * cap->quality / (low_bitrate ? 400 : 200); | ||
| 716 | /* Lower limit (arbitrary, 1 KB) */ | ||
| 717 | if (size < 8192) | ||
| 718 | size = 8192; | ||
| 719 | /* Upper limit: 7/8 of the code buffers */ | ||
| 720 | if (size > ptr->total_code_vol * 7) | ||
| 721 | size = ptr->total_code_vol * 7; | ||
| 722 | |||
| 723 | ptr->real_code_vol = size >> 3; /* in bytes */ | ||
| 724 | |||
| 725 | /* the MBCVR is the *maximum* block volume, according to the | ||
| 726 | * JPEG ISO specs, this shouldn't be used, since that allows | ||
| 727 | * for the best encoding quality. So set it to it's max value | ||
| 728 | */ | ||
| 729 | reg = ptr->max_block_vol; | ||
| 730 | zr36060_write(ptr, ZR060_MBCVR, reg); | ||
| 731 | |||
| 732 | return 0; | ||
| 733 | } | ||
| 734 | |||
| 735 | /* additional control functions */ | ||
| 736 | static int | ||
| 737 | zr36060_control (struct videocodec *codec, | ||
| 738 | int type, | ||
| 739 | int size, | ||
| 740 | void *data) | ||
| 741 | { | ||
| 742 | struct zr36060 *ptr = (struct zr36060 *) codec->data; | ||
| 743 | int *ival = (int *) data; | ||
| 744 | |||
| 745 | dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, | ||
| 746 | size); | ||
| 747 | |||
| 748 | switch (type) { | ||
| 749 | case CODEC_G_STATUS: /* get last status */ | ||
| 750 | if (size != sizeof(int)) | ||
| 751 | return -EFAULT; | ||
| 752 | zr36060_read_status(ptr); | ||
| 753 | *ival = ptr->status; | ||
| 754 | break; | ||
| 755 | |||
| 756 | case CODEC_G_CODEC_MODE: | ||
| 757 | if (size != sizeof(int)) | ||
| 758 | return -EFAULT; | ||
| 759 | *ival = CODEC_MODE_BJPG; | ||
| 760 | break; | ||
| 761 | |||
| 762 | case CODEC_S_CODEC_MODE: | ||
| 763 | if (size != sizeof(int)) | ||
| 764 | return -EFAULT; | ||
| 765 | if (*ival != CODEC_MODE_BJPG) | ||
| 766 | return -EINVAL; | ||
| 767 | /* not needed, do nothing */ | ||
| 768 | return 0; | ||
| 769 | |||
| 770 | case CODEC_G_VFE: | ||
| 771 | case CODEC_S_VFE: | ||
| 772 | /* not needed, do nothing */ | ||
| 773 | return 0; | ||
| 774 | |||
| 775 | case CODEC_S_MMAP: | ||
| 776 | /* not available, give an error */ | ||
| 777 | return -ENXIO; | ||
| 778 | |||
| 779 | case CODEC_G_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
| 780 | if (size != sizeof(int)) | ||
| 781 | return -EFAULT; | ||
| 782 | *ival = ptr->total_code_vol; | ||
| 783 | break; | ||
| 784 | |||
| 785 | case CODEC_S_JPEG_TDS_BYTE: /* get target volume in byte */ | ||
| 786 | if (size != sizeof(int)) | ||
| 787 | return -EFAULT; | ||
| 788 | ptr->total_code_vol = *ival; | ||
| 789 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
| 790 | break; | ||
| 791 | |||
| 792 | case CODEC_G_JPEG_SCALE: /* get scaling factor */ | ||
| 793 | if (size != sizeof(int)) | ||
| 794 | return -EFAULT; | ||
| 795 | *ival = zr36060_read_scalefactor(ptr); | ||
| 796 | break; | ||
| 797 | |||
| 798 | case CODEC_S_JPEG_SCALE: /* set scaling factor */ | ||
| 799 | if (size != sizeof(int)) | ||
| 800 | return -EFAULT; | ||
| 801 | ptr->scalefact = *ival; | ||
| 802 | break; | ||
| 803 | |||
| 804 | case CODEC_G_JPEG_APP_DATA: { /* get appn marker data */ | ||
| 805 | struct jpeg_app_marker *app = data; | ||
| 806 | |||
| 807 | if (size != sizeof(struct jpeg_app_marker)) | ||
| 808 | return -EFAULT; | ||
| 809 | |||
| 810 | *app = ptr->app; | ||
| 811 | break; | ||
| 812 | } | ||
| 813 | |||
| 814 | case CODEC_S_JPEG_APP_DATA: { /* set appn marker data */ | ||
| 815 | struct jpeg_app_marker *app = data; | ||
| 816 | |||
| 817 | if (size != sizeof(struct jpeg_app_marker)) | ||
| 818 | return -EFAULT; | ||
| 819 | |||
| 820 | ptr->app = *app; | ||
| 821 | break; | ||
| 822 | } | ||
| 823 | |||
| 824 | case CODEC_G_JPEG_COM_DATA: { /* get comment marker data */ | ||
| 825 | struct jpeg_com_marker *com = data; | ||
| 826 | |||
| 827 | if (size != sizeof(struct jpeg_com_marker)) | ||
| 828 | return -EFAULT; | ||
| 829 | |||
| 830 | *com = ptr->com; | ||
| 831 | break; | ||
| 832 | } | ||
| 833 | |||
| 834 | case CODEC_S_JPEG_COM_DATA: { /* set comment marker data */ | ||
| 835 | struct jpeg_com_marker *com = data; | ||
| 836 | |||
| 837 | if (size != sizeof(struct jpeg_com_marker)) | ||
| 838 | return -EFAULT; | ||
| 839 | |||
| 840 | ptr->com = *com; | ||
| 841 | break; | ||
| 842 | } | ||
| 843 | |||
| 844 | default: | ||
| 845 | return -EINVAL; | ||
| 846 | } | ||
| 847 | |||
| 848 | return size; | ||
| 849 | } | ||
| 850 | |||
| 851 | /* ========================================================================= | ||
| 852 | Exit and unregister function: | ||
| 853 | |||
| 854 | Deinitializes Zoran's JPEG processor | ||
| 855 | ========================================================================= */ | ||
| 856 | |||
| 857 | static int | ||
| 858 | zr36060_unset (struct videocodec *codec) | ||
| 859 | { | ||
| 860 | struct zr36060 *ptr = codec->data; | ||
| 861 | |||
| 862 | if (ptr) { | ||
| 863 | /* do wee need some codec deinit here, too ???? */ | ||
| 864 | |||
| 865 | dprintk(1, "%s: finished codec #%d\n", ptr->name, | ||
| 866 | ptr->num); | ||
| 867 | kfree(ptr); | ||
| 868 | codec->data = NULL; | ||
| 869 | |||
| 870 | zr36060_codecs--; | ||
| 871 | return 0; | ||
| 872 | } | ||
| 873 | |||
| 874 | return -EFAULT; | ||
| 875 | } | ||
| 876 | |||
| 877 | /* ========================================================================= | ||
| 878 | Setup and registry function: | ||
| 879 | |||
| 880 | Initializes Zoran's JPEG processor | ||
| 881 | |||
| 882 | Also sets pixel size, average code size, mode (compr./decompr.) | ||
| 883 | (the given size is determined by the processor with the video interface) | ||
| 884 | ========================================================================= */ | ||
| 885 | |||
| 886 | static int | ||
| 887 | zr36060_setup (struct videocodec *codec) | ||
| 888 | { | ||
| 889 | struct zr36060 *ptr; | ||
| 890 | int res; | ||
| 891 | |||
| 892 | dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", | ||
| 893 | zr36060_codecs); | ||
| 894 | |||
| 895 | if (zr36060_codecs == MAX_CODECS) { | ||
| 896 | dprintk(1, | ||
| 897 | KERN_ERR "zr36060: Can't attach more codecs!\n"); | ||
| 898 | return -ENOSPC; | ||
| 899 | } | ||
| 900 | //mem structure init | ||
| 901 | codec->data = ptr = kzalloc(sizeof(struct zr36060), GFP_KERNEL); | ||
| 902 | if (NULL == ptr) { | ||
| 903 | dprintk(1, KERN_ERR "zr36060: Can't get enough memory!\n"); | ||
| 904 | return -ENOMEM; | ||
| 905 | } | ||
| 906 | |||
| 907 | snprintf(ptr->name, sizeof(ptr->name), "zr36060[%d]", | ||
| 908 | zr36060_codecs); | ||
| 909 | ptr->num = zr36060_codecs++; | ||
| 910 | ptr->codec = codec; | ||
| 911 | |||
| 912 | //testing | ||
| 913 | res = zr36060_basic_test(ptr); | ||
| 914 | if (res < 0) { | ||
| 915 | zr36060_unset(codec); | ||
| 916 | return res; | ||
| 917 | } | ||
| 918 | //final setup | ||
| 919 | memcpy(ptr->h_samp_ratio, zr36060_decimation_h, 8); | ||
| 920 | memcpy(ptr->v_samp_ratio, zr36060_decimation_v, 8); | ||
| 921 | |||
| 922 | ptr->bitrate_ctrl = 0; /* 0 or 1 - fixed file size flag | ||
| 923 | * (what is the difference?) | ||
| 924 | */ | ||
| 925 | ptr->mode = CODEC_DO_COMPRESSION; | ||
| 926 | ptr->width = 384; | ||
| 927 | ptr->height = 288; | ||
| 928 | ptr->total_code_vol = 16000; /* CHECKME */ | ||
| 929 | ptr->real_code_vol = (ptr->total_code_vol * 6) >> 3; | ||
| 930 | ptr->max_block_vol = 240; /* CHECKME, was 120 is 240 */ | ||
| 931 | ptr->scalefact = 0x100; | ||
| 932 | ptr->dri = 1; /* CHECKME, was 8 is 1 */ | ||
| 933 | |||
| 934 | /* by default, no COM or APP markers - app should set those */ | ||
| 935 | ptr->com.len = 0; | ||
| 936 | ptr->app.appn = 0; | ||
| 937 | ptr->app.len = 0; | ||
| 938 | |||
| 939 | zr36060_init(ptr); | ||
| 940 | |||
| 941 | dprintk(1, KERN_INFO "%s: codec attached and running\n", | ||
| 942 | ptr->name); | ||
| 943 | |||
| 944 | return 0; | ||
| 945 | } | ||
| 946 | |||
| 947 | static const struct videocodec zr36060_codec = { | ||
| 948 | .owner = THIS_MODULE, | ||
| 949 | .name = "zr36060", | ||
| 950 | .magic = 0L, // magic not used | ||
| 951 | .flags = | ||
| 952 | CODEC_FLAG_JPEG | CODEC_FLAG_HARDWARE | CODEC_FLAG_ENCODER | | ||
| 953 | CODEC_FLAG_DECODER | CODEC_FLAG_VFE, | ||
| 954 | .type = CODEC_TYPE_ZR36060, | ||
| 955 | .setup = zr36060_setup, // functionality | ||
| 956 | .unset = zr36060_unset, | ||
| 957 | .set_mode = zr36060_set_mode, | ||
| 958 | .set_video = zr36060_set_video, | ||
| 959 | .control = zr36060_control, | ||
| 960 | // others are not used | ||
| 961 | }; | ||
| 962 | |||
| 963 | /* ========================================================================= | ||
| 964 | HOOK IN DRIVER AS KERNEL MODULE | ||
| 965 | ========================================================================= */ | ||
| 966 | |||
| 967 | static int __init | ||
| 968 | zr36060_init_module (void) | ||
| 969 | { | ||
| 970 | //dprintk(1, "zr36060 driver %s\n",ZR060_VERSION); | ||
| 971 | zr36060_codecs = 0; | ||
| 972 | return videocodec_register(&zr36060_codec); | ||
| 973 | } | ||
| 974 | |||
| 975 | static void __exit | ||
| 976 | zr36060_cleanup_module (void) | ||
| 977 | { | ||
| 978 | if (zr36060_codecs) { | ||
| 979 | dprintk(1, | ||
| 980 | "zr36060: something's wrong - %d codecs left somehow.\n", | ||
| 981 | zr36060_codecs); | ||
| 982 | } | ||
| 983 | |||
| 984 | /* however, we can't just stay alive */ | ||
| 985 | videocodec_unregister(&zr36060_codec); | ||
| 986 | } | ||
| 987 | |||
| 988 | module_init(zr36060_init_module); | ||
| 989 | module_exit(zr36060_cleanup_module); | ||
| 990 | |||
| 991 | MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@skynet.be>"); | ||
| 992 | MODULE_DESCRIPTION("Driver module for ZR36060 jpeg processors " | ||
| 993 | ZR060_VERSION); | ||
| 994 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/media/zoran/zr36060.h b/drivers/staging/media/zoran/zr36060.h deleted file mode 100644 index 9fa553dc475f..000000000000 --- a/drivers/staging/media/zoran/zr36060.h +++ /dev/null | |||
| @@ -1,200 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Zoran ZR36060 basic configuration functions - header file | ||
| 4 | * | ||
| 5 | * Copyright (C) 2002 Laurent Pinchart <laurent.pinchart@skynet.be> | ||
| 6 | */ | ||
| 7 | #ifndef ZR36060_H | ||
| 8 | #define ZR36060_H | ||
| 9 | |||
| 10 | #include "videocodec.h" | ||
| 11 | |||
| 12 | /* data stored for each zoran jpeg codec chip */ | ||
| 13 | struct zr36060 { | ||
| 14 | char name[32]; | ||
| 15 | int num; | ||
| 16 | /* io datastructure */ | ||
| 17 | struct videocodec *codec; | ||
| 18 | // last coder status | ||
| 19 | __u8 status; | ||
| 20 | // actual coder setup | ||
| 21 | int mode; | ||
| 22 | |||
| 23 | __u16 width; | ||
| 24 | __u16 height; | ||
| 25 | |||
| 26 | __u16 bitrate_ctrl; | ||
| 27 | |||
| 28 | __u32 total_code_vol; | ||
| 29 | __u32 real_code_vol; | ||
| 30 | __u16 max_block_vol; | ||
| 31 | |||
| 32 | __u8 h_samp_ratio[8]; | ||
| 33 | __u8 v_samp_ratio[8]; | ||
| 34 | __u16 scalefact; | ||
| 35 | __u16 dri; | ||
| 36 | |||
| 37 | /* app/com marker data */ | ||
| 38 | struct jpeg_app_marker app; | ||
| 39 | struct jpeg_com_marker com; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /* ZR36060 register addresses */ | ||
| 43 | #define ZR060_LOAD 0x000 | ||
| 44 | #define ZR060_CFSR 0x001 | ||
| 45 | #define ZR060_CIR 0x002 | ||
| 46 | #define ZR060_CMR 0x003 | ||
| 47 | #define ZR060_MBZ 0x004 | ||
| 48 | #define ZR060_MBCVR 0x005 | ||
| 49 | #define ZR060_MER 0x006 | ||
| 50 | #define ZR060_IMR 0x007 | ||
| 51 | #define ZR060_ISR 0x008 | ||
| 52 | #define ZR060_TCV_NET_HI 0x009 | ||
| 53 | #define ZR060_TCV_NET_MH 0x00a | ||
| 54 | #define ZR060_TCV_NET_ML 0x00b | ||
| 55 | #define ZR060_TCV_NET_LO 0x00c | ||
| 56 | #define ZR060_TCV_DATA_HI 0x00d | ||
| 57 | #define ZR060_TCV_DATA_MH 0x00e | ||
| 58 | #define ZR060_TCV_DATA_ML 0x00f | ||
| 59 | #define ZR060_TCV_DATA_LO 0x010 | ||
| 60 | #define ZR060_SF_HI 0x011 | ||
| 61 | #define ZR060_SF_LO 0x012 | ||
| 62 | #define ZR060_AF_HI 0x013 | ||
| 63 | #define ZR060_AF_M 0x014 | ||
| 64 | #define ZR060_AF_LO 0x015 | ||
| 65 | #define ZR060_ACV_HI 0x016 | ||
| 66 | #define ZR060_ACV_MH 0x017 | ||
| 67 | #define ZR060_ACV_ML 0x018 | ||
| 68 | #define ZR060_ACV_LO 0x019 | ||
| 69 | #define ZR060_ACT_HI 0x01a | ||
| 70 | #define ZR060_ACT_MH 0x01b | ||
| 71 | #define ZR060_ACT_ML 0x01c | ||
| 72 | #define ZR060_ACT_LO 0x01d | ||
| 73 | #define ZR060_ACV_TRUN_HI 0x01e | ||
| 74 | #define ZR060_ACV_TRUN_MH 0x01f | ||
| 75 | #define ZR060_ACV_TRUN_ML 0x020 | ||
| 76 | #define ZR060_ACV_TRUN_LO 0x021 | ||
| 77 | #define ZR060_IDR_DEV 0x022 | ||
| 78 | #define ZR060_IDR_REV 0x023 | ||
| 79 | #define ZR060_TCR_HI 0x024 | ||
| 80 | #define ZR060_TCR_LO 0x025 | ||
| 81 | #define ZR060_VCR 0x030 | ||
| 82 | #define ZR060_VPR 0x031 | ||
| 83 | #define ZR060_SR 0x032 | ||
| 84 | #define ZR060_BCR_Y 0x033 | ||
| 85 | #define ZR060_BCR_U 0x034 | ||
| 86 | #define ZR060_BCR_V 0x035 | ||
| 87 | #define ZR060_SGR_VTOTAL_HI 0x036 | ||
| 88 | #define ZR060_SGR_VTOTAL_LO 0x037 | ||
| 89 | #define ZR060_SGR_HTOTAL_HI 0x038 | ||
| 90 | #define ZR060_SGR_HTOTAL_LO 0x039 | ||
| 91 | #define ZR060_SGR_VSYNC 0x03a | ||
| 92 | #define ZR060_SGR_HSYNC 0x03b | ||
| 93 | #define ZR060_SGR_BVSTART 0x03c | ||
| 94 | #define ZR060_SGR_BHSTART 0x03d | ||
| 95 | #define ZR060_SGR_BVEND_HI 0x03e | ||
| 96 | #define ZR060_SGR_BVEND_LO 0x03f | ||
| 97 | #define ZR060_SGR_BHEND_HI 0x040 | ||
| 98 | #define ZR060_SGR_BHEND_LO 0x041 | ||
| 99 | #define ZR060_AAR_VSTART_HI 0x042 | ||
| 100 | #define ZR060_AAR_VSTART_LO 0x043 | ||
| 101 | #define ZR060_AAR_VEND_HI 0x044 | ||
| 102 | #define ZR060_AAR_VEND_LO 0x045 | ||
| 103 | #define ZR060_AAR_HSTART_HI 0x046 | ||
| 104 | #define ZR060_AAR_HSTART_LO 0x047 | ||
| 105 | #define ZR060_AAR_HEND_HI 0x048 | ||
| 106 | #define ZR060_AAR_HEND_LO 0x049 | ||
| 107 | #define ZR060_SWR_VSTART_HI 0x04a | ||
| 108 | #define ZR060_SWR_VSTART_LO 0x04b | ||
| 109 | #define ZR060_SWR_VEND_HI 0x04c | ||
| 110 | #define ZR060_SWR_VEND_LO 0x04d | ||
| 111 | #define ZR060_SWR_HSTART_HI 0x04e | ||
| 112 | #define ZR060_SWR_HSTART_LO 0x04f | ||
| 113 | #define ZR060_SWR_HEND_HI 0x050 | ||
| 114 | #define ZR060_SWR_HEND_LO 0x051 | ||
| 115 | |||
| 116 | #define ZR060_SOF_IDX 0x060 | ||
| 117 | #define ZR060_SOS_IDX 0x07a | ||
| 118 | #define ZR060_DRI_IDX 0x0c0 | ||
| 119 | #define ZR060_DQT_IDX 0x0cc | ||
| 120 | #define ZR060_DHT_IDX 0x1d4 | ||
| 121 | #define ZR060_APP_IDX 0x380 | ||
| 122 | #define ZR060_COM_IDX 0x3c0 | ||
| 123 | |||
| 124 | /* ZR36060 LOAD register bits */ | ||
| 125 | |||
| 126 | #define ZR060_LOAD_Load (1 << 7) | ||
| 127 | #define ZR060_LOAD_SyncRst (1 << 0) | ||
| 128 | |||
| 129 | /* ZR36060 Code FIFO Status register bits */ | ||
| 130 | |||
| 131 | #define ZR060_CFSR_Busy (1 << 7) | ||
| 132 | #define ZR060_CFSR_CBusy (1 << 2) | ||
| 133 | #define ZR060_CFSR_CFIFO (3 << 0) | ||
| 134 | |||
| 135 | /* ZR36060 Code Interface register */ | ||
| 136 | |||
| 137 | #define ZR060_CIR_Code16 (1 << 7) | ||
| 138 | #define ZR060_CIR_Endian (1 << 6) | ||
| 139 | #define ZR060_CIR_CFIS (1 << 2) | ||
| 140 | #define ZR060_CIR_CodeMstr (1 << 0) | ||
| 141 | |||
| 142 | /* ZR36060 Codec Mode register */ | ||
| 143 | |||
| 144 | #define ZR060_CMR_Comp (1 << 7) | ||
| 145 | #define ZR060_CMR_ATP (1 << 6) | ||
| 146 | #define ZR060_CMR_Pass2 (1 << 5) | ||
| 147 | #define ZR060_CMR_TLM (1 << 4) | ||
| 148 | #define ZR060_CMR_BRB (1 << 2) | ||
| 149 | #define ZR060_CMR_FSF (1 << 1) | ||
| 150 | |||
| 151 | /* ZR36060 Markers Enable register */ | ||
| 152 | |||
| 153 | #define ZR060_MER_App (1 << 7) | ||
| 154 | #define ZR060_MER_Com (1 << 6) | ||
| 155 | #define ZR060_MER_DRI (1 << 5) | ||
| 156 | #define ZR060_MER_DQT (1 << 4) | ||
| 157 | #define ZR060_MER_DHT (1 << 3) | ||
| 158 | |||
| 159 | /* ZR36060 Interrupt Mask register */ | ||
| 160 | |||
| 161 | #define ZR060_IMR_EOAV (1 << 3) | ||
| 162 | #define ZR060_IMR_EOI (1 << 2) | ||
| 163 | #define ZR060_IMR_End (1 << 1) | ||
| 164 | #define ZR060_IMR_DataErr (1 << 0) | ||
| 165 | |||
| 166 | /* ZR36060 Interrupt Status register */ | ||
| 167 | |||
| 168 | #define ZR060_ISR_ProCnt (3 << 6) | ||
| 169 | #define ZR060_ISR_EOAV (1 << 3) | ||
| 170 | #define ZR060_ISR_EOI (1 << 2) | ||
| 171 | #define ZR060_ISR_End (1 << 1) | ||
| 172 | #define ZR060_ISR_DataErr (1 << 0) | ||
| 173 | |||
| 174 | /* ZR36060 Video Control register */ | ||
| 175 | |||
| 176 | #define ZR060_VCR_Video8 (1 << 7) | ||
| 177 | #define ZR060_VCR_Range (1 << 6) | ||
| 178 | #define ZR060_VCR_FIDet (1 << 3) | ||
| 179 | #define ZR060_VCR_FIVedge (1 << 2) | ||
| 180 | #define ZR060_VCR_FIExt (1 << 1) | ||
| 181 | #define ZR060_VCR_SyncMstr (1 << 0) | ||
| 182 | |||
| 183 | /* ZR36060 Video Polarity register */ | ||
| 184 | |||
| 185 | #define ZR060_VPR_VCLKPol (1 << 7) | ||
| 186 | #define ZR060_VPR_PValPol (1 << 6) | ||
| 187 | #define ZR060_VPR_PoePol (1 << 5) | ||
| 188 | #define ZR060_VPR_SImgPol (1 << 4) | ||
| 189 | #define ZR060_VPR_BLPol (1 << 3) | ||
| 190 | #define ZR060_VPR_FIPol (1 << 2) | ||
| 191 | #define ZR060_VPR_HSPol (1 << 1) | ||
| 192 | #define ZR060_VPR_VSPol (1 << 0) | ||
| 193 | |||
| 194 | /* ZR36060 Scaling register */ | ||
| 195 | |||
| 196 | #define ZR060_SR_VScale (1 << 2) | ||
| 197 | #define ZR060_SR_HScale2 (1 << 0) | ||
| 198 | #define ZR060_SR_HScale4 (2 << 0) | ||
| 199 | |||
| 200 | #endif /*fndef ZR36060_H */ | ||
diff --git a/include/media/cec-notifier.h b/include/media/cec-notifier.h index 814eeef35a5c..57b3a9f6ea1d 100644 --- a/include/media/cec-notifier.h +++ b/include/media/cec-notifier.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #ifndef LINUX_CEC_NOTIFIER_H | 9 | #ifndef LINUX_CEC_NOTIFIER_H |
| 10 | #define LINUX_CEC_NOTIFIER_H | 10 | #define LINUX_CEC_NOTIFIER_H |
| 11 | 11 | ||
| 12 | #include <linux/types.h> | 12 | #include <linux/err.h> |
| 13 | #include <media/cec.h> | 13 | #include <media/cec.h> |
| 14 | 14 | ||
| 15 | struct device; | 15 | struct device; |
| @@ -87,6 +87,17 @@ void cec_notifier_unregister(struct cec_notifier *n); | |||
| 87 | void cec_register_cec_notifier(struct cec_adapter *adap, | 87 | void cec_register_cec_notifier(struct cec_adapter *adap, |
| 88 | struct cec_notifier *notifier); | 88 | struct cec_notifier *notifier); |
| 89 | 89 | ||
| 90 | /** | ||
| 91 | * cec_notifier_parse_hdmi_phandle - find the hdmi device from "hdmi-phandle" | ||
| 92 | * @dev: the device with the "hdmi-phandle" device tree property | ||
| 93 | * | ||
| 94 | * Returns the device pointer referenced by the "hdmi-phandle" property. | ||
| 95 | * Note that the refcount of the returned device is not incremented. | ||
| 96 | * This device pointer is only used as a key value in the notifier | ||
| 97 | * list, but it is never accessed by the CEC driver. | ||
| 98 | */ | ||
| 99 | struct device *cec_notifier_parse_hdmi_phandle(struct device *dev); | ||
| 100 | |||
| 90 | #else | 101 | #else |
| 91 | static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, | 102 | static inline struct cec_notifier *cec_notifier_get_conn(struct device *dev, |
| 92 | const char *conn) | 103 | const char *conn) |
| @@ -122,6 +133,12 @@ static inline void cec_register_cec_notifier(struct cec_adapter *adap, | |||
| 122 | struct cec_notifier *notifier) | 133 | struct cec_notifier *notifier) |
| 123 | { | 134 | { |
| 124 | } | 135 | } |
| 136 | |||
| 137 | static inline struct device *cec_notifier_parse_hdmi_phandle(struct device *dev) | ||
| 138 | { | ||
| 139 | return ERR_PTR(-ENODEV); | ||
| 140 | } | ||
| 141 | |||
| 125 | #endif | 142 | #endif |
| 126 | 143 | ||
| 127 | /** | 144 | /** |
diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h index f9e73b4a6e89..52875e3eee71 100644 --- a/include/media/dvb-usb-ids.h +++ b/include/media/dvb-usb-ids.h | |||
| @@ -258,6 +258,7 @@ | |||
| 258 | #define USB_PID_AVERMEDIA_A867 0xa867 | 258 | #define USB_PID_AVERMEDIA_A867 0xa867 |
| 259 | #define USB_PID_AVERMEDIA_H335 0x0335 | 259 | #define USB_PID_AVERMEDIA_H335 0x0335 |
| 260 | #define USB_PID_AVERMEDIA_TD110 0xa110 | 260 | #define USB_PID_AVERMEDIA_TD110 0xa110 |
| 261 | #define USB_PID_AVERMEDIA_TD310 0x1871 | ||
| 261 | #define USB_PID_AVERMEDIA_TWINSTAR 0x0825 | 262 | #define USB_PID_AVERMEDIA_TWINSTAR 0x0825 |
| 262 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 | 263 | #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 |
| 263 | #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 | 264 | #define USB_PID_TECHNOTREND_CONNECT_S2400_8KEEPROM 0x3009 |
diff --git a/include/media/fwht-ctrls.h b/include/media/fwht-ctrls.h new file mode 100644 index 000000000000..615027410e47 --- /dev/null +++ b/include/media/fwht-ctrls.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * These are the FWHT state controls for use with stateless FWHT | ||
| 4 | * codec drivers. | ||
| 5 | * | ||
| 6 | * It turns out that these structs are not stable yet and will undergo | ||
| 7 | * more changes. So keep them private until they are stable and ready to | ||
| 8 | * become part of the official public API. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef _FWHT_CTRLS_H_ | ||
| 12 | #define _FWHT_CTRLS_H_ | ||
| 13 | |||
| 14 | #define V4L2_CTRL_TYPE_FWHT_PARAMS 0x0105 | ||
| 15 | |||
| 16 | #define V4L2_CID_MPEG_VIDEO_FWHT_PARAMS (V4L2_CID_MPEG_BASE + 292) | ||
| 17 | |||
| 18 | struct v4l2_ctrl_fwht_params { | ||
| 19 | __u64 backward_ref_ts; | ||
| 20 | __u32 version; | ||
| 21 | __u32 width; | ||
| 22 | __u32 height; | ||
| 23 | __u32 flags; | ||
| 24 | __u32 colorspace; | ||
| 25 | __u32 xfer_func; | ||
| 26 | __u32 ycbcr_enc; | ||
| 27 | __u32 quantization; | ||
| 28 | }; | ||
| 29 | |||
| 30 | |||
| 31 | #endif | ||
diff --git a/include/media/media-dev-allocator.h b/include/media/media-dev-allocator.h new file mode 100644 index 000000000000..b35ea6062596 --- /dev/null +++ b/include/media/media-dev-allocator.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * media-dev-allocator.h - Media Controller Device Allocator API | ||
| 4 | * | ||
| 5 | * Copyright (c) 2019 Shuah Khan <shuah@kernel.org> | ||
| 6 | * | ||
| 7 | * Credits: Suggested by Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This file adds a global ref-counted Media Controller Device Instance API. | ||
| 12 | * A system wide global media device list is managed and each media device | ||
| 13 | * includes a kref count. The last put on the media device releases the media | ||
| 14 | * device instance. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _MEDIA_DEV_ALLOCATOR_H | ||
| 18 | #define _MEDIA_DEV_ALLOCATOR_H | ||
| 19 | |||
| 20 | struct usb_device; | ||
| 21 | |||
| 22 | #if defined(CONFIG_MEDIA_CONTROLLER) && defined(CONFIG_USB) | ||
| 23 | /** | ||
| 24 | * media_device_usb_allocate() - Allocate and return struct &media device | ||
| 25 | * | ||
| 26 | * @udev: struct &usb_device pointer | ||
| 27 | * @module_name: should be filled with %KBUILD_MODNAME | ||
| 28 | * @owner: struct module pointer %THIS_MODULE for the driver. | ||
| 29 | * %THIS_MODULE is null for a built-in driver. | ||
| 30 | * It is safe even when %THIS_MODULE is null. | ||
| 31 | * | ||
| 32 | * This interface should be called to allocate a Media Device when multiple | ||
| 33 | * drivers share usb_device and the media device. This interface allocates | ||
| 34 | * &media_device structure and calls media_device_usb_init() to initialize | ||
| 35 | * it. | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | struct media_device *media_device_usb_allocate(struct usb_device *udev, | ||
| 39 | const char *module_name, | ||
| 40 | struct module *owner); | ||
| 41 | /** | ||
| 42 | * media_device_delete() - Release media device. Calls kref_put(). | ||
| 43 | * | ||
| 44 | * @mdev: struct &media_device pointer | ||
| 45 | * @module_name: should be filled with %KBUILD_MODNAME | ||
| 46 | * @owner: struct module pointer %THIS_MODULE for the driver. | ||
| 47 | * %THIS_MODULE is null for a built-in driver. | ||
| 48 | * It is safe even when %THIS_MODULE is null. | ||
| 49 | * | ||
| 50 | * This interface should be called to put Media Device Instance kref. | ||
| 51 | */ | ||
| 52 | void media_device_delete(struct media_device *mdev, const char *module_name, | ||
| 53 | struct module *owner); | ||
| 54 | #else | ||
| 55 | static inline struct media_device *media_device_usb_allocate( | ||
| 56 | struct usb_device *udev, const char *module_name, | ||
| 57 | struct module *owner) | ||
| 58 | { return NULL; } | ||
| 59 | static inline void media_device_delete( | ||
| 60 | struct media_device *mdev, const char *module_name, | ||
| 61 | struct module *owner) { } | ||
| 62 | #endif /* CONFIG_MEDIA_CONTROLLER && CONFIG_USB */ | ||
| 63 | #endif /* _MEDIA_DEV_ALLOCATOR_H */ | ||
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e5f6960d92f6..3cbad42e3693 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h | |||
| @@ -865,19 +865,6 @@ struct media_link *media_entity_find_link(struct media_pad *source, | |||
| 865 | struct media_pad *media_entity_remote_pad(const struct media_pad *pad); | 865 | struct media_pad *media_entity_remote_pad(const struct media_pad *pad); |
| 866 | 866 | ||
| 867 | /** | 867 | /** |
| 868 | * media_entity_get - Get a reference to the parent module | ||
| 869 | * | ||
| 870 | * @entity: The entity | ||
| 871 | * | ||
| 872 | * Get a reference to the parent media device module. | ||
| 873 | * | ||
| 874 | * The function will return immediately if @entity is %NULL. | ||
| 875 | * | ||
| 876 | * Return: returns a pointer to the entity on success or %NULL on failure. | ||
| 877 | */ | ||
| 878 | struct media_entity *media_entity_get(struct media_entity *entity); | ||
| 879 | |||
| 880 | /** | ||
| 881 | * media_entity_get_fwnode_pad - Get pad number from fwnode | 868 | * media_entity_get_fwnode_pad - Get pad number from fwnode |
| 882 | * | 869 | * |
| 883 | * @entity: The entity | 870 | * @entity: The entity |
| @@ -917,17 +904,6 @@ __must_check int media_graph_walk_init( | |||
| 917 | void media_graph_walk_cleanup(struct media_graph *graph); | 904 | void media_graph_walk_cleanup(struct media_graph *graph); |
| 918 | 905 | ||
| 919 | /** | 906 | /** |
| 920 | * media_entity_put - Release the reference to the parent module | ||
| 921 | * | ||
| 922 | * @entity: The entity | ||
| 923 | * | ||
| 924 | * Release the reference count acquired by media_entity_get(). | ||
| 925 | * | ||
| 926 | * The function will return immediately if @entity is %NULL. | ||
| 927 | */ | ||
| 928 | void media_entity_put(struct media_entity *entity); | ||
| 929 | |||
| 930 | /** | ||
| 931 | * media_graph_walk_start - Start walking the media graph at a | 907 | * media_graph_walk_start - Start walking the media graph at a |
| 932 | * given entity | 908 | * given entity |
| 933 | * | 909 | * |
diff --git a/include/media/media-request.h b/include/media/media-request.h index bd36d7431698..3cd25a2717ce 100644 --- a/include/media/media-request.h +++ b/include/media/media-request.h | |||
| @@ -198,7 +198,7 @@ void media_request_put(struct media_request *req); | |||
| 198 | * Get the request represented by @request_fd that is owned | 198 | * Get the request represented by @request_fd that is owned |
| 199 | * by the media device. | 199 | * by the media device. |
| 200 | * | 200 | * |
| 201 | * Return a -EACCES error pointer if requests are not supported | 201 | * Return a -EBADR error pointer if requests are not supported |
| 202 | * by this driver. Return -EINVAL if the request was not found. | 202 | * by this driver. Return -EINVAL if the request was not found. |
| 203 | * Return the pointer to the request if found: the caller will | 203 | * Return the pointer to the request if found: the caller will |
| 204 | * have to call @media_request_put when it finished using the | 204 | * have to call @media_request_put when it finished using the |
| @@ -231,7 +231,7 @@ static inline void media_request_put(struct media_request *req) | |||
| 231 | static inline struct media_request * | 231 | static inline struct media_request * |
| 232 | media_request_get_by_fd(struct media_device *mdev, int request_fd) | 232 | media_request_get_by_fd(struct media_device *mdev, int request_fd) |
| 233 | { | 233 | { |
| 234 | return ERR_PTR(-EACCES); | 234 | return ERR_PTR(-EBADR); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | #endif | 237 | #endif |
diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 5e684bb0d64c..367d983188f7 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #define RC_PROTO_BIT_RCMM12 BIT_ULL(RC_PROTO_RCMM12) | 40 | #define RC_PROTO_BIT_RCMM12 BIT_ULL(RC_PROTO_RCMM12) |
| 41 | #define RC_PROTO_BIT_RCMM24 BIT_ULL(RC_PROTO_RCMM24) | 41 | #define RC_PROTO_BIT_RCMM24 BIT_ULL(RC_PROTO_RCMM24) |
| 42 | #define RC_PROTO_BIT_RCMM32 BIT_ULL(RC_PROTO_RCMM32) | 42 | #define RC_PROTO_BIT_RCMM32 BIT_ULL(RC_PROTO_RCMM32) |
| 43 | #define RC_PROTO_BIT_XBOX_DVD BIT_ULL(RC_PROTO_XBOX_DVD) | ||
| 43 | 44 | ||
| 44 | #define RC_PROTO_BIT_ALL \ | 45 | #define RC_PROTO_BIT_ALL \ |
| 45 | (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ | 46 | (RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \ |
| @@ -55,7 +56,8 @@ | |||
| 55 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ | 56 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \ |
| 56 | RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ | 57 | RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \ |
| 57 | RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ | 58 | RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \ |
| 58 | RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32) | 59 | RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32 | \ |
| 60 | RC_PROTO_BIT_XBOX_DVD) | ||
| 59 | /* All rc protocols for which we have decoders */ | 61 | /* All rc protocols for which we have decoders */ |
| 60 | #define RC_PROTO_BIT_ALL_IR_DECODER \ | 62 | #define RC_PROTO_BIT_ALL_IR_DECODER \ |
| 61 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ | 63 | (RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \ |
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 2b93cb281fa5..0a41bbecf3d3 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h | |||
| @@ -392,4 +392,37 @@ int v4l2_s_parm_cap(struct video_device *vdev, | |||
| 392 | ((u64)(a).numerator * (b).denominator OP \ | 392 | ((u64)(a).numerator * (b).denominator OP \ |
| 393 | (u64)(b).numerator * (a).denominator) | 393 | (u64)(b).numerator * (a).denominator) |
| 394 | 394 | ||
| 395 | /* ------------------------------------------------------------------------- */ | ||
| 396 | |||
| 397 | /* Pixel format and FourCC helpers */ | ||
| 398 | |||
| 399 | /** | ||
| 400 | * struct v4l2_format_info - information about a V4L2 format | ||
| 401 | * @format: 4CC format identifier (V4L2_PIX_FMT_*) | ||
| 402 | * @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4). | ||
| 403 | * @comp_planes: Number of component planes, which includes the alpha plane (1 to 4). | ||
| 404 | * @bpp: Array of per-plane bytes per pixel | ||
| 405 | * @hdiv: Horizontal chroma subsampling factor | ||
| 406 | * @vdiv: Vertical chroma subsampling factor | ||
| 407 | * @block_w: Per-plane macroblock pixel width (optional) | ||
| 408 | * @block_h: Per-plane macroblock pixel height (optional) | ||
| 409 | */ | ||
| 410 | struct v4l2_format_info { | ||
| 411 | u32 format; | ||
| 412 | u8 mem_planes; | ||
| 413 | u8 comp_planes; | ||
| 414 | u8 bpp[4]; | ||
| 415 | u8 hdiv; | ||
| 416 | u8 vdiv; | ||
| 417 | u8 block_w[4]; | ||
| 418 | u8 block_h[4]; | ||
| 419 | }; | ||
| 420 | |||
| 421 | const struct v4l2_format_info *v4l2_format_info(u32 format); | ||
| 422 | |||
| 423 | int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, int pixelformat, | ||
| 424 | int width, int height); | ||
| 425 | int v4l2_fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, int pixelformat, | ||
| 426 | int width, int height); | ||
| 427 | |||
| 395 | #endif /* V4L2_COMMON_H_ */ | 428 | #endif /* V4L2_COMMON_H_ */ |
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index e5cae37ced2d..ee026387f513 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h | |||
| @@ -23,10 +23,11 @@ | |||
| 23 | #include <media/media-request.h> | 23 | #include <media/media-request.h> |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * Include the mpeg2 stateless codec compound control definitions. | 26 | * Include the mpeg2 and fwht stateless codec compound control definitions. |
| 27 | * This will move to the public headers once this API is fully stable. | 27 | * This will move to the public headers once this API is fully stable. |
| 28 | */ | 28 | */ |
| 29 | #include <media/mpeg2-ctrls.h> | 29 | #include <media/mpeg2-ctrls.h> |
| 30 | #include <media/fwht-ctrls.h> | ||
| 30 | 31 | ||
| 31 | /* forward references */ | 32 | /* forward references */ |
| 32 | struct file; | 33 | struct file; |
| @@ -49,6 +50,7 @@ struct poll_table_struct; | |||
| 49 | * @p_char: Pointer to a string. | 50 | * @p_char: Pointer to a string. |
| 50 | * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. | 51 | * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure. |
| 51 | * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure. | 52 | * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure. |
| 53 | * @p_fwht_params: Pointer to a FWHT stateless parameters structure. | ||
| 52 | * @p: Pointer to a compound value. | 54 | * @p: Pointer to a compound value. |
| 53 | */ | 55 | */ |
| 54 | union v4l2_ctrl_ptr { | 56 | union v4l2_ctrl_ptr { |
| @@ -60,6 +62,7 @@ union v4l2_ctrl_ptr { | |||
| 60 | char *p_char; | 62 | char *p_char; |
| 61 | struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; | 63 | struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; |
| 62 | struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization; | 64 | struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization; |
| 65 | struct v4l2_ctrl_fwht_params *p_fwht_params; | ||
| 63 | void *p; | 66 | void *p; |
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| @@ -934,7 +937,7 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl); | |||
| 934 | * __v4l2_ctrl_s_ctrl() - Unlocked variant of v4l2_ctrl_s_ctrl(). | 937 | * __v4l2_ctrl_s_ctrl() - Unlocked variant of v4l2_ctrl_s_ctrl(). |
| 935 | * | 938 | * |
| 936 | * @ctrl: The control. | 939 | * @ctrl: The control. |
| 937 | * @val: TheControls name new value. | 940 | * @val: The new value. |
| 938 | * | 941 | * |
| 939 | * This sets the control's new value safely by going through the control | 942 | * This sets the control's new value safely by going through the control |
| 940 | * framework. This function assumes the control's handler is already locked, | 943 | * framework. This function assumes the control's handler is already locked, |
| @@ -1039,7 +1042,7 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s); | |||
| 1039 | * | 1042 | * |
| 1040 | * @ctrl: The control. | 1043 | * @ctrl: The control. |
| 1041 | * @s: The new string. | 1044 | * @s: The new string. |
| 1042 | *Controls name | 1045 | * |
| 1043 | * This sets the control's new string safely by going through the control | 1046 | * This sets the control's new string safely by going through the control |
| 1044 | * framework. This function will lock the control's handler, so it cannot be | 1047 | * framework. This function will lock the control's handler, so it cannot be |
| 1045 | * used from within the &v4l2_ctrl_ops functions. | 1048 | * used from within the &v4l2_ctrl_ops functions. |
| @@ -1127,7 +1130,7 @@ __poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait); | |||
| 1127 | * applying control values in a request is only applicable to memory-to-memory | 1130 | * applying control values in a request is only applicable to memory-to-memory |
| 1128 | * devices. | 1131 | * devices. |
| 1129 | */ | 1132 | */ |
| 1130 | void v4l2_ctrl_request_setup(struct media_request *req, | 1133 | int v4l2_ctrl_request_setup(struct media_request *req, |
| 1131 | struct v4l2_ctrl_handler *parent); | 1134 | struct v4l2_ctrl_handler *parent); |
| 1132 | 1135 | ||
| 1133 | /** | 1136 | /** |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 349e1c18cf48..a7fa5b80915a 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
| @@ -755,7 +755,17 @@ struct v4l2_subdev_ops { | |||
| 755 | * | 755 | * |
| 756 | * @open: called when the subdev device node is opened by an application. | 756 | * @open: called when the subdev device node is opened by an application. |
| 757 | * | 757 | * |
| 758 | * @close: called when the subdev device node is closed. | 758 | * @close: called when the subdev device node is closed. Please note that |
| 759 | * it is possible for @close to be called after @unregistered! | ||
| 760 | * | ||
| 761 | * @release: called when the last user of the subdev device is gone. This | ||
| 762 | * happens after the @unregistered callback and when the last open | ||
| 763 | * filehandle to the v4l-subdevX device node was closed. If no device | ||
| 764 | * node was created for this sub-device, then the @release callback | ||
| 765 | * is called right after the @unregistered callback. | ||
| 766 | * The @release callback is typically used to free the memory containing | ||
| 767 | * the v4l2_subdev structure. It is almost certainly required for any | ||
| 768 | * sub-device that sets the V4L2_SUBDEV_FL_HAS_DEVNODE flag. | ||
| 759 | * | 769 | * |
| 760 | * .. note:: | 770 | * .. note:: |
| 761 | * Never call this from drivers, only the v4l2 framework can call | 771 | * Never call this from drivers, only the v4l2 framework can call |
| @@ -766,6 +776,7 @@ struct v4l2_subdev_internal_ops { | |||
| 766 | void (*unregistered)(struct v4l2_subdev *sd); | 776 | void (*unregistered)(struct v4l2_subdev *sd); |
| 767 | int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); | 777 | int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); |
| 768 | int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); | 778 | int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); |
| 779 | void (*release)(struct v4l2_subdev *sd); | ||
| 769 | }; | 780 | }; |
| 770 | 781 | ||
| 771 | #define V4L2_SUBDEV_NAME_SIZE 32 | 782 | #define V4L2_SUBDEV_NAME_SIZE 32 |
| @@ -899,9 +910,11 @@ struct v4l2_subdev { | |||
| 899 | * | 910 | * |
| 900 | * @vfh: pointer to &struct v4l2_fh | 911 | * @vfh: pointer to &struct v4l2_fh |
| 901 | * @pad: pointer to &struct v4l2_subdev_pad_config | 912 | * @pad: pointer to &struct v4l2_subdev_pad_config |
| 913 | * @owner: module pointer to the owner of this file handle | ||
| 902 | */ | 914 | */ |
| 903 | struct v4l2_subdev_fh { | 915 | struct v4l2_subdev_fh { |
| 904 | struct v4l2_fh vfh; | 916 | struct v4l2_fh vfh; |
| 917 | struct module *owner; | ||
| 905 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) | 918 | #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) |
| 906 | struct v4l2_subdev_pad_config *pad; | 919 | struct v4l2_subdev_pad_config *pad; |
| 907 | #endif | 920 | #endif |
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 910f3d469005..22f3ff76a8b5 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h | |||
| @@ -207,7 +207,6 @@ enum vb2_io_modes { | |||
| 207 | * @VB2_BUF_STATE_IN_REQUEST: buffer is queued in media request. | 207 | * @VB2_BUF_STATE_IN_REQUEST: buffer is queued in media request. |
| 208 | * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf. | 208 | * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf. |
| 209 | * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver. | 209 | * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver. |
| 210 | * @VB2_BUF_STATE_REQUEUEING: re-queue a buffer to the driver. | ||
| 211 | * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used | 210 | * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used |
| 212 | * in a hardware operation. | 211 | * in a hardware operation. |
| 213 | * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but | 212 | * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but |
| @@ -221,7 +220,6 @@ enum vb2_buffer_state { | |||
| 221 | VB2_BUF_STATE_IN_REQUEST, | 220 | VB2_BUF_STATE_IN_REQUEST, |
| 222 | VB2_BUF_STATE_PREPARING, | 221 | VB2_BUF_STATE_PREPARING, |
| 223 | VB2_BUF_STATE_QUEUED, | 222 | VB2_BUF_STATE_QUEUED, |
| 224 | VB2_BUF_STATE_REQUEUEING, | ||
| 225 | VB2_BUF_STATE_ACTIVE, | 223 | VB2_BUF_STATE_ACTIVE, |
| 226 | VB2_BUF_STATE_DONE, | 224 | VB2_BUF_STATE_DONE, |
| 227 | VB2_BUF_STATE_ERROR, | 225 | VB2_BUF_STATE_ERROR, |
| @@ -384,10 +382,10 @@ struct vb2_buffer { | |||
| 384 | * driver can return an error if hardware fails, in that | 382 | * driver can return an error if hardware fails, in that |
| 385 | * case all buffers that have been already given by | 383 | * case all buffers that have been already given by |
| 386 | * the @buf_queue callback are to be returned by the driver | 384 | * the @buf_queue callback are to be returned by the driver |
| 387 | * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED | 385 | * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED. |
| 388 | * or %VB2_BUF_STATE_REQUEUEING. If you need a minimum | 386 | * If you need a minimum number of buffers before you can |
| 389 | * number of buffers before you can start streaming, then | 387 | * start streaming, then set |
| 390 | * set &vb2_queue->min_buffers_needed. If that is non-zero | 388 | * &vb2_queue->min_buffers_needed. If that is non-zero |
| 391 | * then @start_streaming won't be called until at least | 389 | * then @start_streaming won't be called until at least |
| 392 | * that many buffers have been queued up by userspace. | 390 | * that many buffers have been queued up by userspace. |
| 393 | * @stop_streaming: called when 'streaming' state must be disabled; driver | 391 | * @stop_streaming: called when 'streaming' state must be disabled; driver |
| @@ -484,6 +482,8 @@ struct vb2_buf_ops { | |||
| 484 | * has not been called. This is a vb1 idiom that has been adopted | 482 | * has not been called. This is a vb1 idiom that has been adopted |
| 485 | * also by vb2. | 483 | * also by vb2. |
| 486 | * @supports_requests: this queue supports the Request API. | 484 | * @supports_requests: this queue supports the Request API. |
| 485 | * @requires_requests: this queue requires the Request API. If this is set to 1, | ||
| 486 | * then supports_requests must be set to 1 as well. | ||
| 487 | * @uses_qbuf: qbuf was used directly for this queue. Set to 1 the first | 487 | * @uses_qbuf: qbuf was used directly for this queue. Set to 1 the first |
| 488 | * time this is called. Set to 0 when the queue is canceled. | 488 | * time this is called. Set to 0 when the queue is canceled. |
| 489 | * If this is 1, then you cannot queue buffers from a request. | 489 | * If this is 1, then you cannot queue buffers from a request. |
| @@ -558,6 +558,7 @@ struct vb2_queue { | |||
| 558 | unsigned allow_zero_bytesused:1; | 558 | unsigned allow_zero_bytesused:1; |
| 559 | unsigned quirk_poll_must_check_waiting_for_buffers:1; | 559 | unsigned quirk_poll_must_check_waiting_for_buffers:1; |
| 560 | unsigned supports_requests:1; | 560 | unsigned supports_requests:1; |
| 561 | unsigned requires_requests:1; | ||
| 561 | unsigned uses_qbuf:1; | 562 | unsigned uses_qbuf:1; |
| 562 | unsigned uses_requests:1; | 563 | unsigned uses_requests:1; |
| 563 | 564 | ||
| @@ -595,6 +596,7 @@ struct vb2_queue { | |||
| 595 | unsigned int start_streaming_called:1; | 596 | unsigned int start_streaming_called:1; |
| 596 | unsigned int error:1; | 597 | unsigned int error:1; |
| 597 | unsigned int waiting_for_buffers:1; | 598 | unsigned int waiting_for_buffers:1; |
| 599 | unsigned int waiting_in_dqbuf:1; | ||
| 598 | unsigned int is_multiplanar:1; | 600 | unsigned int is_multiplanar:1; |
| 599 | unsigned int is_output:1; | 601 | unsigned int is_output:1; |
| 600 | unsigned int copy_timestamp:1; | 602 | unsigned int copy_timestamp:1; |
| @@ -648,9 +650,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); | |||
| 648 | * @state: state of the buffer, as defined by &enum vb2_buffer_state. | 650 | * @state: state of the buffer, as defined by &enum vb2_buffer_state. |
| 649 | * Either %VB2_BUF_STATE_DONE if the operation finished | 651 | * Either %VB2_BUF_STATE_DONE if the operation finished |
| 650 | * successfully, %VB2_BUF_STATE_ERROR if the operation finished | 652 | * successfully, %VB2_BUF_STATE_ERROR if the operation finished |
| 651 | * with an error or any of %VB2_BUF_STATE_QUEUED or | 653 | * with an error or %VB2_BUF_STATE_QUEUED. |
| 652 | * %VB2_BUF_STATE_REQUEUEING if the driver wants to | ||
| 653 | * requeue buffers (see below). | ||
| 654 | * | 654 | * |
| 655 | * This function should be called by the driver after a hardware operation on | 655 | * This function should be called by the driver after a hardware operation on |
| 656 | * a buffer is finished and the buffer may be returned to userspace. The driver | 656 | * a buffer is finished and the buffer may be returned to userspace. The driver |
| @@ -661,12 +661,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); | |||
| 661 | * While streaming a buffer can only be returned in state DONE or ERROR. | 661 | * While streaming a buffer can only be returned in state DONE or ERROR. |
| 662 | * The &vb2_ops->start_streaming op can also return them in case the DMA engine | 662 | * The &vb2_ops->start_streaming op can also return them in case the DMA engine |
| 663 | * cannot be started for some reason. In that case the buffers should be | 663 | * cannot be started for some reason. In that case the buffers should be |
| 664 | * returned with state QUEUED or REQUEUEING to put them back into the queue. | 664 | * returned with state QUEUED to put them back into the queue. |
| 665 | * | ||
| 666 | * %VB2_BUF_STATE_REQUEUEING is like %VB2_BUF_STATE_QUEUED, but it also calls | ||
| 667 | * &vb2_ops->buf_queue to queue buffers back to the driver. Note that calling | ||
| 668 | * vb2_buffer_done(..., VB2_BUF_STATE_REQUEUEING) from interrupt context will | ||
| 669 | * result in &vb2_ops->buf_queue being called in interrupt context as well. | ||
| 670 | */ | 665 | */ |
| 671 | void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); | 666 | void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); |
| 672 | 667 | ||
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index 45fcbf99d72e..f99d9dcae667 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h | |||
| @@ -195,6 +195,7 @@ struct lirc_scancode { | |||
| 195 | * @RC_PROTO_RCMM12: RC-MM protocol 12 bits | 195 | * @RC_PROTO_RCMM12: RC-MM protocol 12 bits |
| 196 | * @RC_PROTO_RCMM24: RC-MM protocol 24 bits | 196 | * @RC_PROTO_RCMM24: RC-MM protocol 24 bits |
| 197 | * @RC_PROTO_RCMM32: RC-MM protocol 32 bits | 197 | * @RC_PROTO_RCMM32: RC-MM protocol 32 bits |
| 198 | * @RC_PROTO_XBOX_DVD: Xbox DVD Movie Playback Kit protocol | ||
| 198 | */ | 199 | */ |
| 199 | enum rc_proto { | 200 | enum rc_proto { |
| 200 | RC_PROTO_UNKNOWN = 0, | 201 | RC_PROTO_UNKNOWN = 0, |
| @@ -224,6 +225,7 @@ enum rc_proto { | |||
| 224 | RC_PROTO_RCMM12 = 24, | 225 | RC_PROTO_RCMM12 = 24, |
| 225 | RC_PROTO_RCMM24 = 25, | 226 | RC_PROTO_RCMM24 = 25, |
| 226 | RC_PROTO_RCMM32 = 26, | 227 | RC_PROTO_RCMM32 = 26, |
| 228 | RC_PROTO_XBOX_DVD = 27, | ||
| 227 | }; | 229 | }; |
| 228 | 230 | ||
| 229 | #endif | 231 | #endif |
diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index d6a5a3bfe6c4..2a6b253cfb05 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #define MEDIA_BUS_FMT_FIXED 0x0001 | 35 | #define MEDIA_BUS_FMT_FIXED 0x0001 |
| 36 | 36 | ||
| 37 | /* RGB - next is 0x101b */ | 37 | /* RGB - next is 0x101c */ |
| 38 | #define MEDIA_BUS_FMT_RGB444_1X12 0x1016 | 38 | #define MEDIA_BUS_FMT_RGB444_1X12 0x1016 |
| 39 | #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 | 39 | #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 |
| 40 | #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 | 40 | #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 |
| @@ -50,6 +50,7 @@ | |||
| 50 | #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015 | 50 | #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI 0x1015 |
| 51 | #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010 | 51 | #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG 0x1010 |
| 52 | #define MEDIA_BUS_FMT_BGR888_1X24 0x1013 | 52 | #define MEDIA_BUS_FMT_BGR888_1X24 0x1013 |
| 53 | #define MEDIA_BUS_FMT_BGR888_3X8 0x101b | ||
| 53 | #define MEDIA_BUS_FMT_GBR888_1X24 0x1014 | 54 | #define MEDIA_BUS_FMT_GBR888_1X24 0x1014 |
| 54 | #define MEDIA_BUS_FMT_RGB888_1X24 0x100a | 55 | #define MEDIA_BUS_FMT_RGB888_1X24 0x100a |
| 55 | #define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b | 56 | #define MEDIA_BUS_FMT_RGB888_2X12_BE 0x100b |
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index e5d0c5c611b5..9aedb187bc48 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h | |||
| @@ -262,6 +262,11 @@ struct media_links_enum { | |||
| 262 | #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) | 262 | #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) |
| 263 | #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) | 263 | #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) |
| 264 | 264 | ||
| 265 | #define MEDIA_INTF_T_ALSA_BASE 0x00000300 | ||
| 266 | #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) | ||
| 267 | #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) | ||
| 268 | #define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) | ||
| 269 | |||
| 265 | #if defined(__KERNEL__) | 270 | #if defined(__KERNEL__) |
| 266 | 271 | ||
| 267 | /* | 272 | /* |
| @@ -413,19 +418,19 @@ struct media_v2_topology { | |||
| 413 | #define MEDIA_ENT_F_DTV_DECODER MEDIA_ENT_F_DV_DECODER | 418 | #define MEDIA_ENT_F_DTV_DECODER MEDIA_ENT_F_DV_DECODER |
| 414 | 419 | ||
| 415 | /* | 420 | /* |
| 416 | * There is still no ALSA support in the media controller. These | 421 | * There is still no full ALSA support in the media controller. These |
| 417 | * defines should not have been added and we leave them here only | 422 | * defines should not have been added and we leave them here only |
| 418 | * in case some application tries to use these defines. | 423 | * in case some application tries to use these defines. |
| 424 | * | ||
| 425 | * The ALSA defines that are in use have been moved into __KERNEL__ | ||
| 426 | * scope. As support gets added to these interface types, they should | ||
| 427 | * be moved into __KERNEL__ scope with the code that uses them. | ||
| 419 | */ | 428 | */ |
| 420 | #define MEDIA_INTF_T_ALSA_BASE 0x00000300 | 429 | #define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) |
| 421 | #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) | 430 | #define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) |
| 422 | #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) | 431 | #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) |
| 423 | #define MEDIA_INTF_T_ALSA_CONTROL (MEDIA_INTF_T_ALSA_BASE + 2) | 432 | #define MEDIA_INTF_T_ALSA_SEQUENCER (MEDIA_INTF_T_ALSA_BASE + 6) |
| 424 | #define MEDIA_INTF_T_ALSA_COMPRESS (MEDIA_INTF_T_ALSA_BASE + 3) | 433 | #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7) |
| 425 | #define MEDIA_INTF_T_ALSA_RAWMIDI (MEDIA_INTF_T_ALSA_BASE + 4) | ||
| 426 | #define MEDIA_INTF_T_ALSA_HWDEP (MEDIA_INTF_T_ALSA_BASE + 5) | ||
| 427 | #define MEDIA_INTF_T_ALSA_SEQUENCER (MEDIA_INTF_T_ALSA_BASE + 6) | ||
| 428 | #define MEDIA_INTF_T_ALSA_TIMER (MEDIA_INTF_T_ALSA_BASE + 7) | ||
| 429 | 434 | ||
| 430 | /* Obsolete symbol for media_version, no longer used in the kernel */ | 435 | /* Obsolete symbol for media_version, no longer used in the kernel */ |
| 431 | #define MEDIA_API_VERSION ((0 << 16) | (1 << 8) | 0) | 436 | #define MEDIA_API_VERSION ((0 << 16) | (1 << 8) | 0) |
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 06479f2fb3ae..37807f23231e 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h | |||
| @@ -404,6 +404,10 @@ enum v4l2_mpeg_video_multi_slice_mode { | |||
| 404 | #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228) | 404 | #define V4L2_CID_MPEG_VIDEO_MV_V_SEARCH_RANGE (V4L2_CID_MPEG_BASE+228) |
| 405 | #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229) | 405 | #define V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME (V4L2_CID_MPEG_BASE+229) |
| 406 | 406 | ||
| 407 | /* CIDs for the FWHT codec as used by the vicodec driver. */ | ||
| 408 | #define V4L2_CID_FWHT_I_FRAME_QP (V4L2_CID_MPEG_BASE + 290) | ||
| 409 | #define V4L2_CID_FWHT_P_FRAME_QP (V4L2_CID_MPEG_BASE + 291) | ||
| 410 | |||
| 407 | #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) | 411 | #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) |
| 408 | #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) | 412 | #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) |
| 409 | #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) | 413 | #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) |
| @@ -535,6 +539,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type { | |||
| 535 | #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) | 539 | #define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) |
| 536 | #define V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION (V4L2_CID_MPEG_BASE+383) | 540 | #define V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION (V4L2_CID_MPEG_BASE+383) |
| 537 | #define V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET (V4L2_CID_MPEG_BASE+384) | 541 | #define V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET (V4L2_CID_MPEG_BASE+384) |
| 542 | #define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP (V4L2_CID_MPEG_BASE+385) | ||
| 543 | #define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP (V4L2_CID_MPEG_BASE+386) | ||
| 544 | #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP (V4L2_CID_MPEG_BASE+387) | ||
| 545 | #define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP (V4L2_CID_MPEG_BASE+388) | ||
| 538 | #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) | 546 | #define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) |
| 539 | #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) | 547 | #define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) |
| 540 | #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) | 548 | #define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) |
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 1db220da3bcc..1050a75fb7ef 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h | |||
| @@ -514,9 +514,21 @@ struct v4l2_pix_format { | |||
| 514 | #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ | 514 | #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ |
| 515 | #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16 aaaarrrr ggggbbbb */ | 515 | #define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16 aaaarrrr ggggbbbb */ |
| 516 | #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16 xxxxrrrr ggggbbbb */ | 516 | #define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16 xxxxrrrr ggggbbbb */ |
| 517 | #define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') /* 16 rrrrgggg bbbbaaaa */ | ||
| 518 | #define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') /* 16 rrrrgggg bbbbxxxx */ | ||
| 519 | #define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') /* 16 aaaabbbb ggggrrrr */ | ||
| 520 | #define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') /* 16 xxxxbbbb ggggrrrr */ | ||
| 521 | #define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('B', 'A', '1', '2') /* 16 bbbbgggg rrrraaaa */ | ||
| 522 | #define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') /* 16 bbbbgggg rrrrxxxx */ | ||
| 517 | #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ | 523 | #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ |
| 518 | #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16 ARGB-1-5-5-5 */ | 524 | #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16 ARGB-1-5-5-5 */ |
| 519 | #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') /* 16 XRGB-1-5-5-5 */ | 525 | #define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') /* 16 XRGB-1-5-5-5 */ |
| 526 | #define V4L2_PIX_FMT_RGBA555 v4l2_fourcc('R', 'A', '1', '5') /* 16 RGBA-5-5-5-1 */ | ||
| 527 | #define V4L2_PIX_FMT_RGBX555 v4l2_fourcc('R', 'X', '1', '5') /* 16 RGBX-5-5-5-1 */ | ||
| 528 | #define V4L2_PIX_FMT_ABGR555 v4l2_fourcc('A', 'B', '1', '5') /* 16 ABGR-1-5-5-5 */ | ||
| 529 | #define V4L2_PIX_FMT_XBGR555 v4l2_fourcc('X', 'B', '1', '5') /* 16 XBGR-1-5-5-5 */ | ||
| 530 | #define V4L2_PIX_FMT_BGRA555 v4l2_fourcc('B', 'A', '1', '5') /* 16 BGRA-5-5-5-1 */ | ||
| 531 | #define V4L2_PIX_FMT_BGRX555 v4l2_fourcc('B', 'X', '1', '5') /* 16 BGRX-5-5-5-1 */ | ||
| 520 | #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ | 532 | #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ |
| 521 | #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ | 533 | #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ |
| 522 | #define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5') /* 16 ARGB-5-5-5 BE */ | 534 | #define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5') /* 16 ARGB-5-5-5 BE */ |
| @@ -528,7 +540,11 @@ struct v4l2_pix_format { | |||
| 528 | #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ | 540 | #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ |
| 529 | #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') /* 32 BGRA-8-8-8-8 */ | 541 | #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') /* 32 BGRA-8-8-8-8 */ |
| 530 | #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') /* 32 BGRX-8-8-8-8 */ | 542 | #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') /* 32 BGRX-8-8-8-8 */ |
| 543 | #define V4L2_PIX_FMT_BGRA32 v4l2_fourcc('R', 'A', '2', '4') /* 32 ABGR-8-8-8-8 */ | ||
| 544 | #define V4L2_PIX_FMT_BGRX32 v4l2_fourcc('R', 'X', '2', '4') /* 32 XBGR-8-8-8-8 */ | ||
| 531 | #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ | 545 | #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ |
| 546 | #define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') /* 32 RGBA-8-8-8-8 */ | ||
| 547 | #define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4') /* 32 RGBX-8-8-8-8 */ | ||
| 532 | #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') /* 32 ARGB-8-8-8-8 */ | 548 | #define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') /* 32 ARGB-8-8-8-8 */ |
| 533 | #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */ | 549 | #define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */ |
| 534 | 550 | ||
| @@ -669,6 +685,7 @@ struct v4l2_pix_format { | |||
| 669 | #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ | 685 | #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */ |
| 670 | #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */ | 686 | #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */ |
| 671 | #define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */ | 687 | #define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */ |
| 688 | #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */ | ||
| 672 | 689 | ||
| 673 | /* Vendor-specific formats */ | 690 | /* Vendor-specific formats */ |
| 674 | #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ | 691 | #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index f61b5662bb89..6319b544ba3a 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
| @@ -15,6 +15,7 @@ config SND_USB_AUDIO | |||
| 15 | select SND_RAWMIDI | 15 | select SND_RAWMIDI |
| 16 | select SND_PCM | 16 | select SND_PCM |
| 17 | select BITREVERSE | 17 | select BITREVERSE |
| 18 | select SND_USB_AUDIO_USE_MEDIA_CONTROLLER if MEDIA_CONTROLLER && (MEDIA_SUPPORT=y || MEDIA_SUPPORT=SND_USB_AUDIO) | ||
| 18 | help | 19 | help |
| 19 | Say Y here to include support for USB audio and USB MIDI | 20 | Say Y here to include support for USB audio and USB MIDI |
| 20 | devices. | 21 | devices. |
| @@ -22,6 +23,9 @@ config SND_USB_AUDIO | |||
| 22 | To compile this driver as a module, choose M here: the module | 23 | To compile this driver as a module, choose M here: the module |
| 23 | will be called snd-usb-audio. | 24 | will be called snd-usb-audio. |
| 24 | 25 | ||
| 26 | config SND_USB_AUDIO_USE_MEDIA_CONTROLLER | ||
| 27 | bool | ||
| 28 | |||
| 25 | config SND_USB_UA101 | 29 | config SND_USB_UA101 |
| 26 | tristate "Edirol UA-101/UA-1000 driver" | 30 | tristate "Edirol UA-101/UA-1000 driver" |
| 27 | select SND_PCM | 31 | select SND_PCM |
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index d330f74c90e6..e1ce257ab705 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
| @@ -18,6 +18,8 @@ snd-usb-audio-objs := card.o \ | |||
| 18 | quirks.o \ | 18 | quirks.o \ |
| 19 | stream.o | 19 | stream.o |
| 20 | 20 | ||
| 21 | snd-usb-audio-$(CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER) += media.o | ||
| 22 | |||
| 21 | snd-usbmidi-lib-objs := midi.o | 23 | snd-usbmidi-lib-objs := midi.o |
| 22 | 24 | ||
| 23 | # Toplevel Module Dependency | 25 | # Toplevel Module Dependency |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 719e10034553..04465d581204 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -68,6 +68,7 @@ | |||
| 68 | #include "format.h" | 68 | #include "format.h" |
| 69 | #include "power.h" | 69 | #include "power.h" |
| 70 | #include "stream.h" | 70 | #include "stream.h" |
| 71 | #include "media.h" | ||
| 71 | 72 | ||
| 72 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 73 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
| 73 | MODULE_DESCRIPTION("USB Audio"); | 74 | MODULE_DESCRIPTION("USB Audio"); |
| @@ -673,6 +674,11 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
| 673 | if (err < 0) | 674 | if (err < 0) |
| 674 | goto __error; | 675 | goto __error; |
| 675 | 676 | ||
| 677 | if (quirk && quirk->shares_media_device) { | ||
| 678 | /* don't want to fail when snd_media_device_create() fails */ | ||
| 679 | snd_media_device_create(chip, intf); | ||
| 680 | } | ||
| 681 | |||
| 676 | usb_chip[chip->index] = chip; | 682 | usb_chip[chip->index] = chip; |
| 677 | chip->num_interfaces++; | 683 | chip->num_interfaces++; |
| 678 | usb_set_intfdata(intf, chip); | 684 | usb_set_intfdata(intf, chip); |
| @@ -732,6 +738,14 @@ static void usb_audio_disconnect(struct usb_interface *intf) | |||
| 732 | list_for_each(p, &chip->midi_list) { | 738 | list_for_each(p, &chip->midi_list) { |
| 733 | snd_usbmidi_disconnect(p); | 739 | snd_usbmidi_disconnect(p); |
| 734 | } | 740 | } |
| 741 | /* | ||
| 742 | * Nice to check quirk && quirk->shares_media_device and | ||
| 743 | * then call the snd_media_device_delete(). Don't have | ||
| 744 | * access to the quirk here. snd_media_device_delete() | ||
| 745 | * accesses mixer_list | ||
| 746 | */ | ||
| 747 | snd_media_device_delete(chip); | ||
| 748 | |||
| 735 | /* release mixer resources */ | 749 | /* release mixer resources */ |
| 736 | list_for_each_entry(mixer, &chip->mixer_list, list) { | 750 | list_for_each_entry(mixer, &chip->mixer_list, list) { |
| 737 | snd_usb_mixer_disconnect(mixer); | 751 | snd_usb_mixer_disconnect(mixer); |
diff --git a/sound/usb/card.h b/sound/usb/card.h index 79fa2a19fb7b..2991b9986f66 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
| @@ -109,6 +109,8 @@ struct snd_usb_endpoint { | |||
| 109 | struct list_head list; | 109 | struct list_head list; |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | struct media_ctl; | ||
| 113 | |||
| 112 | struct snd_usb_substream { | 114 | struct snd_usb_substream { |
| 113 | struct snd_usb_stream *stream; | 115 | struct snd_usb_stream *stream; |
| 114 | struct usb_device *dev; | 116 | struct usb_device *dev; |
| @@ -161,6 +163,7 @@ struct snd_usb_substream { | |||
| 161 | } dsd_dop; | 163 | } dsd_dop; |
| 162 | 164 | ||
| 163 | bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ | 165 | bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ |
| 166 | struct media_ctl *media_ctl; | ||
| 164 | }; | 167 | }; |
| 165 | 168 | ||
| 166 | struct snd_usb_stream { | 169 | struct snd_usb_stream { |
diff --git a/sound/usb/media.c b/sound/usb/media.c new file mode 100644 index 000000000000..812017eacbcf --- /dev/null +++ b/sound/usb/media.c | |||
| @@ -0,0 +1,327 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * media.c - Media Controller specific ALSA driver code | ||
| 4 | * | ||
| 5 | * Copyright (c) 2019 Shuah Khan <shuah@kernel.org> | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * This file adds Media Controller support to the ALSA driver | ||
| 11 | * to use the Media Controller API to share the tuner with DVB | ||
| 12 | * and V4L2 drivers that control the media device. | ||
| 13 | * | ||
| 14 | * The media device is created based on the existing quirks framework. | ||
| 15 | * Using this approach, the media controller API usage can be added for | ||
| 16 | * a specific device. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/list.h> | ||
| 21 | #include <linux/mutex.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/usb.h> | ||
| 24 | |||
| 25 | #include <sound/pcm.h> | ||
| 26 | #include <sound/core.h> | ||
| 27 | |||
| 28 | #include "usbaudio.h" | ||
| 29 | #include "card.h" | ||
| 30 | #include "mixer.h" | ||
| 31 | #include "media.h" | ||
| 32 | |||
| 33 | int snd_media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, | ||
| 34 | int stream) | ||
| 35 | { | ||
| 36 | struct media_device *mdev; | ||
| 37 | struct media_ctl *mctl; | ||
| 38 | struct device *pcm_dev = &pcm->streams[stream].dev; | ||
| 39 | u32 intf_type; | ||
| 40 | int ret = 0; | ||
| 41 | u16 mixer_pad; | ||
| 42 | struct media_entity *entity; | ||
| 43 | |||
| 44 | mdev = subs->stream->chip->media_dev; | ||
| 45 | if (!mdev) | ||
| 46 | return 0; | ||
| 47 | |||
| 48 | if (subs->media_ctl) | ||
| 49 | return 0; | ||
| 50 | |||
| 51 | /* allocate media_ctl */ | ||
| 52 | mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); | ||
| 53 | if (!mctl) | ||
| 54 | return -ENOMEM; | ||
| 55 | |||
| 56 | mctl->media_dev = mdev; | ||
| 57 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 58 | intf_type = MEDIA_INTF_T_ALSA_PCM_PLAYBACK; | ||
| 59 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_PLAYBACK; | ||
| 60 | mctl->media_pad.flags = MEDIA_PAD_FL_SOURCE; | ||
| 61 | mixer_pad = 1; | ||
| 62 | } else { | ||
| 63 | intf_type = MEDIA_INTF_T_ALSA_PCM_CAPTURE; | ||
| 64 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_CAPTURE; | ||
| 65 | mctl->media_pad.flags = MEDIA_PAD_FL_SINK; | ||
| 66 | mixer_pad = 2; | ||
| 67 | } | ||
| 68 | mctl->media_entity.name = pcm->name; | ||
| 69 | media_entity_pads_init(&mctl->media_entity, 1, &mctl->media_pad); | ||
| 70 | ret = media_device_register_entity(mctl->media_dev, | ||
| 71 | &mctl->media_entity); | ||
| 72 | if (ret) | ||
| 73 | goto free_mctl; | ||
| 74 | |||
| 75 | mctl->intf_devnode = media_devnode_create(mdev, intf_type, 0, | ||
| 76 | MAJOR(pcm_dev->devt), | ||
| 77 | MINOR(pcm_dev->devt)); | ||
| 78 | if (!mctl->intf_devnode) { | ||
| 79 | ret = -ENOMEM; | ||
| 80 | goto unregister_entity; | ||
| 81 | } | ||
| 82 | mctl->intf_link = media_create_intf_link(&mctl->media_entity, | ||
| 83 | &mctl->intf_devnode->intf, | ||
| 84 | MEDIA_LNK_FL_ENABLED); | ||
| 85 | if (!mctl->intf_link) { | ||
| 86 | ret = -ENOMEM; | ||
| 87 | goto devnode_remove; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* create link between mixer and audio */ | ||
| 91 | media_device_for_each_entity(entity, mdev) { | ||
| 92 | switch (entity->function) { | ||
| 93 | case MEDIA_ENT_F_AUDIO_MIXER: | ||
| 94 | ret = media_create_pad_link(entity, mixer_pad, | ||
| 95 | &mctl->media_entity, 0, | ||
| 96 | MEDIA_LNK_FL_ENABLED); | ||
| 97 | if (ret) | ||
| 98 | goto remove_intf_link; | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | subs->media_ctl = mctl; | ||
| 104 | return 0; | ||
| 105 | |||
| 106 | remove_intf_link: | ||
| 107 | media_remove_intf_link(mctl->intf_link); | ||
| 108 | devnode_remove: | ||
| 109 | media_devnode_remove(mctl->intf_devnode); | ||
| 110 | unregister_entity: | ||
| 111 | media_device_unregister_entity(&mctl->media_entity); | ||
| 112 | free_mctl: | ||
| 113 | kfree(mctl); | ||
| 114 | return ret; | ||
| 115 | } | ||
| 116 | |||
| 117 | void snd_media_stream_delete(struct snd_usb_substream *subs) | ||
| 118 | { | ||
| 119 | struct media_ctl *mctl = subs->media_ctl; | ||
| 120 | |||
| 121 | if (mctl) { | ||
| 122 | struct media_device *mdev; | ||
| 123 | |||
| 124 | mdev = mctl->media_dev; | ||
| 125 | if (mdev && media_devnode_is_registered(mdev->devnode)) { | ||
| 126 | media_devnode_remove(mctl->intf_devnode); | ||
| 127 | media_device_unregister_entity(&mctl->media_entity); | ||
| 128 | media_entity_cleanup(&mctl->media_entity); | ||
| 129 | } | ||
| 130 | kfree(mctl); | ||
| 131 | subs->media_ctl = NULL; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | int snd_media_start_pipeline(struct snd_usb_substream *subs) | ||
| 136 | { | ||
| 137 | struct media_ctl *mctl = subs->media_ctl; | ||
| 138 | int ret = 0; | ||
| 139 | |||
| 140 | if (!mctl) | ||
| 141 | return 0; | ||
| 142 | |||
| 143 | mutex_lock(&mctl->media_dev->graph_mutex); | ||
| 144 | if (mctl->media_dev->enable_source) | ||
| 145 | ret = mctl->media_dev->enable_source(&mctl->media_entity, | ||
| 146 | &mctl->media_pipe); | ||
| 147 | mutex_unlock(&mctl->media_dev->graph_mutex); | ||
| 148 | return ret; | ||
| 149 | } | ||
| 150 | |||
| 151 | void snd_media_stop_pipeline(struct snd_usb_substream *subs) | ||
| 152 | { | ||
| 153 | struct media_ctl *mctl = subs->media_ctl; | ||
| 154 | |||
| 155 | if (!mctl) | ||
| 156 | return; | ||
| 157 | |||
| 158 | mutex_lock(&mctl->media_dev->graph_mutex); | ||
| 159 | if (mctl->media_dev->disable_source) | ||
| 160 | mctl->media_dev->disable_source(&mctl->media_entity); | ||
| 161 | mutex_unlock(&mctl->media_dev->graph_mutex); | ||
| 162 | } | ||
| 163 | |||
| 164 | static int snd_media_mixer_init(struct snd_usb_audio *chip) | ||
| 165 | { | ||
| 166 | struct device *ctl_dev = &chip->card->ctl_dev; | ||
| 167 | struct media_intf_devnode *ctl_intf; | ||
| 168 | struct usb_mixer_interface *mixer; | ||
| 169 | struct media_device *mdev = chip->media_dev; | ||
| 170 | struct media_mixer_ctl *mctl; | ||
| 171 | u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL; | ||
| 172 | int ret; | ||
| 173 | |||
| 174 | if (!mdev) | ||
| 175 | return -ENODEV; | ||
| 176 | |||
| 177 | ctl_intf = chip->ctl_intf_media_devnode; | ||
| 178 | if (!ctl_intf) { | ||
| 179 | ctl_intf = media_devnode_create(mdev, intf_type, 0, | ||
| 180 | MAJOR(ctl_dev->devt), | ||
| 181 | MINOR(ctl_dev->devt)); | ||
| 182 | if (!ctl_intf) | ||
| 183 | return -ENOMEM; | ||
| 184 | chip->ctl_intf_media_devnode = ctl_intf; | ||
| 185 | } | ||
| 186 | |||
| 187 | list_for_each_entry(mixer, &chip->mixer_list, list) { | ||
| 188 | |||
| 189 | if (mixer->media_mixer_ctl) | ||
| 190 | continue; | ||
| 191 | |||
| 192 | /* allocate media_mixer_ctl */ | ||
| 193 | mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); | ||
| 194 | if (!mctl) | ||
| 195 | return -ENOMEM; | ||
| 196 | |||
| 197 | mctl->media_dev = mdev; | ||
| 198 | mctl->media_entity.function = MEDIA_ENT_F_AUDIO_MIXER; | ||
| 199 | mctl->media_entity.name = chip->card->mixername; | ||
| 200 | mctl->media_pad[0].flags = MEDIA_PAD_FL_SINK; | ||
| 201 | mctl->media_pad[1].flags = MEDIA_PAD_FL_SOURCE; | ||
| 202 | mctl->media_pad[2].flags = MEDIA_PAD_FL_SOURCE; | ||
| 203 | media_entity_pads_init(&mctl->media_entity, MEDIA_MIXER_PAD_MAX, | ||
| 204 | mctl->media_pad); | ||
| 205 | ret = media_device_register_entity(mctl->media_dev, | ||
| 206 | &mctl->media_entity); | ||
| 207 | if (ret) { | ||
| 208 | kfree(mctl); | ||
| 209 | return ret; | ||
| 210 | } | ||
| 211 | |||
| 212 | mctl->intf_link = media_create_intf_link(&mctl->media_entity, | ||
| 213 | &ctl_intf->intf, | ||
| 214 | MEDIA_LNK_FL_ENABLED); | ||
| 215 | if (!mctl->intf_link) { | ||
| 216 | media_device_unregister_entity(&mctl->media_entity); | ||
| 217 | media_entity_cleanup(&mctl->media_entity); | ||
| 218 | kfree(mctl); | ||
| 219 | return -ENOMEM; | ||
| 220 | } | ||
| 221 | mctl->intf_devnode = ctl_intf; | ||
| 222 | mixer->media_mixer_ctl = mctl; | ||
| 223 | } | ||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | static void snd_media_mixer_delete(struct snd_usb_audio *chip) | ||
| 228 | { | ||
| 229 | struct usb_mixer_interface *mixer; | ||
| 230 | struct media_device *mdev = chip->media_dev; | ||
| 231 | |||
| 232 | if (!mdev) | ||
| 233 | return; | ||
| 234 | |||
| 235 | list_for_each_entry(mixer, &chip->mixer_list, list) { | ||
| 236 | struct media_mixer_ctl *mctl; | ||
| 237 | |||
| 238 | mctl = mixer->media_mixer_ctl; | ||
| 239 | if (!mixer->media_mixer_ctl) | ||
| 240 | continue; | ||
| 241 | |||
| 242 | if (media_devnode_is_registered(mdev->devnode)) { | ||
| 243 | media_device_unregister_entity(&mctl->media_entity); | ||
| 244 | media_entity_cleanup(&mctl->media_entity); | ||
| 245 | } | ||
| 246 | kfree(mctl); | ||
| 247 | mixer->media_mixer_ctl = NULL; | ||
| 248 | } | ||
| 249 | if (media_devnode_is_registered(mdev->devnode)) | ||
| 250 | media_devnode_remove(chip->ctl_intf_media_devnode); | ||
| 251 | chip->ctl_intf_media_devnode = NULL; | ||
| 252 | } | ||
| 253 | |||
| 254 | int snd_media_device_create(struct snd_usb_audio *chip, | ||
| 255 | struct usb_interface *iface) | ||
| 256 | { | ||
| 257 | struct media_device *mdev; | ||
| 258 | struct usb_device *usbdev = interface_to_usbdev(iface); | ||
| 259 | int ret = 0; | ||
| 260 | |||
| 261 | /* usb-audio driver is probed for each usb interface, and | ||
| 262 | * there are multiple interfaces per device. Avoid calling | ||
| 263 | * media_device_usb_allocate() each time usb_audio_probe() | ||
| 264 | * is called. Do it only once. | ||
| 265 | */ | ||
| 266 | if (chip->media_dev) { | ||
| 267 | mdev = chip->media_dev; | ||
| 268 | goto snd_mixer_init; | ||
| 269 | } | ||
| 270 | |||
| 271 | mdev = media_device_usb_allocate(usbdev, KBUILD_MODNAME, THIS_MODULE); | ||
| 272 | if (IS_ERR(mdev)) | ||
| 273 | return -ENOMEM; | ||
| 274 | |||
| 275 | /* save media device - avoid lookups */ | ||
| 276 | chip->media_dev = mdev; | ||
| 277 | |||
| 278 | snd_mixer_init: | ||
| 279 | /* Create media entities for mixer and control dev */ | ||
| 280 | ret = snd_media_mixer_init(chip); | ||
| 281 | /* media_device might be registered, print error and continue */ | ||
| 282 | if (ret) | ||
| 283 | dev_err(&usbdev->dev, | ||
| 284 | "Couldn't create media mixer entities. Error: %d\n", | ||
| 285 | ret); | ||
| 286 | |||
| 287 | if (!media_devnode_is_registered(mdev->devnode)) { | ||
| 288 | /* dont'register if snd_media_mixer_init() failed */ | ||
| 289 | if (ret) | ||
| 290 | goto create_fail; | ||
| 291 | |||
| 292 | /* register media_device */ | ||
| 293 | ret = media_device_register(mdev); | ||
| 294 | create_fail: | ||
| 295 | if (ret) { | ||
| 296 | snd_media_mixer_delete(chip); | ||
| 297 | media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE); | ||
| 298 | /* clear saved media_dev */ | ||
| 299 | chip->media_dev = NULL; | ||
| 300 | dev_err(&usbdev->dev, | ||
| 301 | "Couldn't register media device. Error: %d\n", | ||
| 302 | ret); | ||
| 303 | return ret; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | return ret; | ||
| 308 | } | ||
| 309 | |||
| 310 | void snd_media_device_delete(struct snd_usb_audio *chip) | ||
| 311 | { | ||
| 312 | struct media_device *mdev = chip->media_dev; | ||
| 313 | struct snd_usb_stream *stream; | ||
| 314 | |||
| 315 | /* release resources */ | ||
| 316 | list_for_each_entry(stream, &chip->pcm_list, list) { | ||
| 317 | snd_media_stream_delete(&stream->substream[0]); | ||
| 318 | snd_media_stream_delete(&stream->substream[1]); | ||
| 319 | } | ||
| 320 | |||
| 321 | snd_media_mixer_delete(chip); | ||
| 322 | |||
| 323 | if (mdev) { | ||
| 324 | media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE); | ||
| 325 | chip->media_dev = NULL; | ||
| 326 | } | ||
| 327 | } | ||
diff --git a/sound/usb/media.h b/sound/usb/media.h new file mode 100644 index 000000000000..f5bdec1d602f --- /dev/null +++ b/sound/usb/media.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * media.h - Media Controller specific ALSA driver code | ||
| 4 | * | ||
| 5 | * Copyright (c) 2019 Shuah Khan <shuah@kernel.org> | ||
| 6 | * | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * This file adds Media Controller support to the ALSA driver | ||
| 11 | * to use the Media Controller API to share the tuner with DVB | ||
| 12 | * and V4L2 drivers that control the media device. | ||
| 13 | * | ||
| 14 | * The media device is created based on the existing quirks framework. | ||
| 15 | * Using this approach, the media controller API usage can be added for | ||
| 16 | * a specific device. | ||
| 17 | */ | ||
| 18 | #ifndef __MEDIA_H | ||
| 19 | |||
| 20 | #ifdef CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER | ||
| 21 | |||
| 22 | #include <linux/media.h> | ||
| 23 | #include <media/media-device.h> | ||
| 24 | #include <media/media-entity.h> | ||
| 25 | #include <media/media-dev-allocator.h> | ||
| 26 | #include <sound/asound.h> | ||
| 27 | |||
| 28 | struct media_ctl { | ||
| 29 | struct media_device *media_dev; | ||
| 30 | struct media_entity media_entity; | ||
| 31 | struct media_intf_devnode *intf_devnode; | ||
| 32 | struct media_link *intf_link; | ||
| 33 | struct media_pad media_pad; | ||
| 34 | struct media_pipeline media_pipe; | ||
| 35 | }; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * One source pad each for SNDRV_PCM_STREAM_CAPTURE and | ||
| 39 | * SNDRV_PCM_STREAM_PLAYBACK. One for sink pad to link | ||
| 40 | * to AUDIO Source | ||
| 41 | */ | ||
| 42 | #define MEDIA_MIXER_PAD_MAX (SNDRV_PCM_STREAM_LAST + 2) | ||
| 43 | |||
| 44 | struct media_mixer_ctl { | ||
| 45 | struct media_device *media_dev; | ||
| 46 | struct media_entity media_entity; | ||
| 47 | struct media_intf_devnode *intf_devnode; | ||
| 48 | struct media_link *intf_link; | ||
| 49 | struct media_pad media_pad[MEDIA_MIXER_PAD_MAX]; | ||
| 50 | struct media_pipeline media_pipe; | ||
| 51 | }; | ||
| 52 | |||
| 53 | int snd_media_device_create(struct snd_usb_audio *chip, | ||
| 54 | struct usb_interface *iface); | ||
| 55 | void snd_media_device_delete(struct snd_usb_audio *chip); | ||
| 56 | int snd_media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, | ||
| 57 | int stream); | ||
| 58 | void snd_media_stream_delete(struct snd_usb_substream *subs); | ||
| 59 | int snd_media_start_pipeline(struct snd_usb_substream *subs); | ||
| 60 | void snd_media_stop_pipeline(struct snd_usb_substream *subs); | ||
| 61 | #else | ||
| 62 | static inline int snd_media_device_create(struct snd_usb_audio *chip, | ||
| 63 | struct usb_interface *iface) | ||
| 64 | { return 0; } | ||
| 65 | static inline void snd_media_device_delete(struct snd_usb_audio *chip) { } | ||
| 66 | static inline int snd_media_stream_init(struct snd_usb_substream *subs, | ||
| 67 | struct snd_pcm *pcm, int stream) | ||
| 68 | { return 0; } | ||
| 69 | static inline void snd_media_stream_delete(struct snd_usb_substream *subs) { } | ||
| 70 | static inline int snd_media_start_pipeline(struct snd_usb_substream *subs) | ||
| 71 | { return 0; } | ||
| 72 | static inline void snd_media_stop_pipeline(struct snd_usb_substream *subs) { } | ||
| 73 | #endif | ||
| 74 | #endif /* __MEDIA_H */ | ||
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 3d12af8bf191..394cd9107507 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <sound/info.h> | 5 | #include <sound/info.h> |
| 6 | 6 | ||
| 7 | struct media_mixer_ctl; | ||
| 8 | |||
| 7 | struct usb_mixer_interface { | 9 | struct usb_mixer_interface { |
| 8 | struct snd_usb_audio *chip; | 10 | struct snd_usb_audio *chip; |
| 9 | struct usb_host_interface *hostif; | 11 | struct usb_host_interface *hostif; |
| @@ -23,6 +25,7 @@ struct usb_mixer_interface { | |||
| 23 | struct urb *rc_urb; | 25 | struct urb *rc_urb; |
| 24 | struct usb_ctrlrequest *rc_setup_packet; | 26 | struct usb_ctrlrequest *rc_setup_packet; |
| 25 | u8 rc_buffer[6]; | 27 | u8 rc_buffer[6]; |
| 28 | struct media_mixer_ctl *media_mixer_ctl; | ||
| 26 | 29 | ||
| 27 | bool disconnected; | 30 | bool disconnected; |
| 28 | }; | 31 | }; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 056af0a57b22..5d8494b2a026 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include "pcm.h" | 35 | #include "pcm.h" |
| 36 | #include "clock.h" | 36 | #include "clock.h" |
| 37 | #include "power.h" | 37 | #include "power.h" |
| 38 | #include "media.h" | ||
| 38 | 39 | ||
| 39 | #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 | 40 | #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 |
| 40 | #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 | 41 | #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 |
| @@ -787,6 +788,10 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 787 | struct audioformat *fmt; | 788 | struct audioformat *fmt; |
| 788 | int ret; | 789 | int ret; |
| 789 | 790 | ||
| 791 | ret = snd_media_start_pipeline(subs); | ||
| 792 | if (ret) | ||
| 793 | return ret; | ||
| 794 | |||
| 790 | if (snd_usb_use_vmalloc) | 795 | if (snd_usb_use_vmalloc) |
| 791 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 796 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
| 792 | params_buffer_bytes(hw_params)); | 797 | params_buffer_bytes(hw_params)); |
| @@ -794,7 +799,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 794 | ret = snd_pcm_lib_malloc_pages(substream, | 799 | ret = snd_pcm_lib_malloc_pages(substream, |
| 795 | params_buffer_bytes(hw_params)); | 800 | params_buffer_bytes(hw_params)); |
| 796 | if (ret < 0) | 801 | if (ret < 0) |
| 797 | return ret; | 802 | goto stop_pipeline; |
| 798 | 803 | ||
| 799 | subs->pcm_format = params_format(hw_params); | 804 | subs->pcm_format = params_format(hw_params); |
| 800 | subs->period_bytes = params_period_bytes(hw_params); | 805 | subs->period_bytes = params_period_bytes(hw_params); |
| @@ -808,12 +813,13 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 808 | dev_dbg(&subs->dev->dev, | 813 | dev_dbg(&subs->dev->dev, |
| 809 | "cannot set format: format = %#x, rate = %d, channels = %d\n", | 814 | "cannot set format: format = %#x, rate = %d, channels = %d\n", |
| 810 | subs->pcm_format, subs->cur_rate, subs->channels); | 815 | subs->pcm_format, subs->cur_rate, subs->channels); |
| 811 | return -EINVAL; | 816 | ret = -EINVAL; |
| 817 | goto stop_pipeline; | ||
| 812 | } | 818 | } |
| 813 | 819 | ||
| 814 | ret = snd_usb_lock_shutdown(subs->stream->chip); | 820 | ret = snd_usb_lock_shutdown(subs->stream->chip); |
| 815 | if (ret < 0) | 821 | if (ret < 0) |
| 816 | return ret; | 822 | goto stop_pipeline; |
| 817 | 823 | ||
| 818 | ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0); | 824 | ret = snd_usb_pcm_change_state(subs, UAC3_PD_STATE_D0); |
| 819 | if (ret < 0) | 825 | if (ret < 0) |
| @@ -829,6 +835,12 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
| 829 | 835 | ||
| 830 | unlock: | 836 | unlock: |
| 831 | snd_usb_unlock_shutdown(subs->stream->chip); | 837 | snd_usb_unlock_shutdown(subs->stream->chip); |
| 838 | if (ret < 0) | ||
| 839 | goto stop_pipeline; | ||
| 840 | return ret; | ||
| 841 | |||
| 842 | stop_pipeline: | ||
| 843 | snd_media_stop_pipeline(subs); | ||
| 832 | return ret; | 844 | return ret; |
| 833 | } | 845 | } |
| 834 | 846 | ||
| @@ -841,6 +853,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) | |||
| 841 | { | 853 | { |
| 842 | struct snd_usb_substream *subs = substream->runtime->private_data; | 854 | struct snd_usb_substream *subs = substream->runtime->private_data; |
| 843 | 855 | ||
| 856 | snd_media_stop_pipeline(subs); | ||
| 844 | subs->cur_audiofmt = NULL; | 857 | subs->cur_audiofmt = NULL; |
| 845 | subs->cur_rate = 0; | 858 | subs->cur_rate = 0; |
| 846 | subs->period_bytes = 0; | 859 | subs->period_bytes = 0; |
| @@ -1313,6 +1326,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream) | |||
| 1313 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 1326 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
| 1314 | struct snd_pcm_runtime *runtime = substream->runtime; | 1327 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1315 | struct snd_usb_substream *subs = &as->substream[direction]; | 1328 | struct snd_usb_substream *subs = &as->substream[direction]; |
| 1329 | int ret; | ||
| 1316 | 1330 | ||
| 1317 | subs->interface = -1; | 1331 | subs->interface = -1; |
| 1318 | subs->altset_idx = 0; | 1332 | subs->altset_idx = 0; |
| @@ -1326,7 +1340,13 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream) | |||
| 1326 | subs->dsd_dop.channel = 0; | 1340 | subs->dsd_dop.channel = 0; |
| 1327 | subs->dsd_dop.marker = 1; | 1341 | subs->dsd_dop.marker = 1; |
| 1328 | 1342 | ||
| 1329 | return setup_hw_info(runtime, subs); | 1343 | ret = setup_hw_info(runtime, subs); |
| 1344 | if (ret == 0) { | ||
| 1345 | ret = snd_media_stream_init(subs, as->pcm, direction); | ||
| 1346 | if (ret) | ||
| 1347 | snd_usb_autosuspend(subs->stream->chip); | ||
| 1348 | } | ||
| 1349 | return ret; | ||
| 1330 | } | 1350 | } |
| 1331 | 1351 | ||
| 1332 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream) | 1352 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream) |
| @@ -1337,6 +1357,7 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream) | |||
| 1337 | int ret; | 1357 | int ret; |
| 1338 | 1358 | ||
| 1339 | stop_endpoints(subs, true); | 1359 | stop_endpoints(subs, true); |
| 1360 | snd_media_stop_pipeline(subs); | ||
| 1340 | 1361 | ||
| 1341 | if (!as->chip->keep_iface && | 1362 | if (!as->chip->keep_iface && |
| 1342 | subs->interface >= 0 && | 1363 | subs->interface >= 0 && |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 86e80916a029..8cbca137ee6f 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -2887,6 +2887,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 2887 | .product_name = pname, \ | 2887 | .product_name = pname, \ |
| 2888 | .ifnum = QUIRK_ANY_INTERFACE, \ | 2888 | .ifnum = QUIRK_ANY_INTERFACE, \ |
| 2889 | .type = QUIRK_AUDIO_ALIGN_TRANSFER, \ | 2889 | .type = QUIRK_AUDIO_ALIGN_TRANSFER, \ |
| 2890 | .shares_media_device = 1, \ | ||
| 2890 | } \ | 2891 | } \ |
| 2891 | } | 2892 | } |
| 2892 | 2893 | ||
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index d9e3de495c16..9f1623e37fb3 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include "clock.h" | 38 | #include "clock.h" |
| 39 | #include "stream.h" | 39 | #include "stream.h" |
| 40 | #include "power.h" | 40 | #include "power.h" |
| 41 | #include "media.h" | ||
| 41 | 42 | ||
| 42 | /* | 43 | /* |
| 43 | * free a substream | 44 | * free a substream |
| @@ -55,6 +56,7 @@ static void free_substream(struct snd_usb_substream *subs) | |||
| 55 | } | 56 | } |
| 56 | kfree(subs->rate_list.list); | 57 | kfree(subs->rate_list.list); |
| 57 | kfree(subs->str_pd); | 58 | kfree(subs->str_pd); |
| 59 | snd_media_stream_delete(subs); | ||
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | 62 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index b9faeca645fd..0968a45c8925 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -30,6 +30,9 @@ | |||
| 30 | * | 30 | * |
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | struct media_device; | ||
| 34 | struct media_intf_devnode; | ||
| 35 | |||
| 33 | struct snd_usb_audio { | 36 | struct snd_usb_audio { |
| 34 | int index; | 37 | int index; |
| 35 | struct usb_device *dev; | 38 | struct usb_device *dev; |
| @@ -66,6 +69,8 @@ struct snd_usb_audio { | |||
| 66 | */ | 69 | */ |
| 67 | 70 | ||
| 68 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | 71 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ |
| 72 | struct media_device *media_dev; | ||
| 73 | struct media_intf_devnode *ctl_intf_media_devnode; | ||
| 69 | }; | 74 | }; |
| 70 | 75 | ||
| 71 | #define usb_audio_err(chip, fmt, args...) \ | 76 | #define usb_audio_err(chip, fmt, args...) \ |
| @@ -117,6 +122,7 @@ struct snd_usb_audio_quirk { | |||
| 117 | const char *profile_name; /* override the card->longname */ | 122 | const char *profile_name; /* override the card->longname */ |
| 118 | int16_t ifnum; | 123 | int16_t ifnum; |
| 119 | uint16_t type; | 124 | uint16_t type; |
| 125 | bool shares_media_device; | ||
| 120 | const void *data; | 126 | const void *data; |
| 121 | }; | 127 | }; |
| 122 | 128 | ||
diff --git a/tools/testing/selftests/media_tests/media_dev_allocator.sh b/tools/testing/selftests/media_tests/media_dev_allocator.sh new file mode 100755 index 000000000000..ffe00c59a483 --- /dev/null +++ b/tools/testing/selftests/media_tests/media_dev_allocator.sh | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # Media Device Allocator API test script | ||
| 4 | # Copyright (c) 2019 Shuah Khan <shuah@kernel.org> | ||
| 5 | |||
| 6 | echo "Media Device Allocator testing: unbind and bind" | ||
| 7 | echo "media driver $1 audio driver $2" | ||
| 8 | |||
| 9 | MDRIVER=/sys/bus/usb/drivers/$1 | ||
| 10 | cd $MDRIVER | ||
| 11 | MDEV=$(ls -d *\-*) | ||
| 12 | |||
| 13 | ADRIVER=/sys/bus/usb/drivers/$2 | ||
| 14 | cd $ADRIVER | ||
| 15 | ADEV=$(ls -d *\-*.1) | ||
| 16 | |||
| 17 | echo "==================================" | ||
| 18 | echo "Test unbind both devices - start" | ||
| 19 | echo "Running unbind of $MDEV from $MDRIVER" | ||
| 20 | echo $MDEV > $MDRIVER/unbind; | ||
| 21 | |||
| 22 | echo "Media device should still be present!" | ||
| 23 | ls -l /dev/media* | ||
| 24 | |||
| 25 | echo "sound driver is at: $ADRIVER" | ||
| 26 | echo "Device is: $ADEV" | ||
| 27 | |||
| 28 | echo "Running unbind of $ADEV from $ADRIVER" | ||
| 29 | echo $ADEV > $ADRIVER/unbind; | ||
| 30 | |||
| 31 | echo "Media device should have been deleted!" | ||
| 32 | ls -l /dev/media* | ||
| 33 | echo "Test unbind both devices - end" | ||
| 34 | |||
| 35 | echo "==================================" | ||
| 36 | |||
| 37 | echo "Test bind both devices - start" | ||
| 38 | echo "Running bind of $MDEV from $MDRIVER" | ||
| 39 | echo $MDEV > $MDRIVER/bind; | ||
| 40 | |||
| 41 | echo "Media device should be present!" | ||
| 42 | ls -l /dev/media* | ||
| 43 | |||
| 44 | echo "Running bind of $ADEV from $ADRIVER" | ||
| 45 | echo $ADEV > $ADRIVER/bind; | ||
| 46 | |||
| 47 | echo "Media device should be there!" | ||
| 48 | ls -l /dev/media* | ||
| 49 | |||
| 50 | echo "Test bind both devices - end" | ||
| 51 | |||
| 52 | echo "==================================" | ||
| 53 | |||
| 54 | echo "Test unbind $MDEV - bind $MDEV - unbind $ADEV - bind $ADEV start" | ||
| 55 | |||
| 56 | echo "Running unbind of $MDEV from $MDRIVER" | ||
| 57 | echo $MDEV > $MDRIVER/unbind; | ||
| 58 | |||
| 59 | echo "Media device should be there!" | ||
| 60 | ls -l /dev/media* | ||
| 61 | |||
| 62 | sleep 1 | ||
| 63 | |||
| 64 | echo "Running bind of $MDEV from $MDRIVER" | ||
| 65 | echo $MDEV > $MDRIVER/bind; | ||
| 66 | |||
| 67 | echo "Media device should be there!" | ||
| 68 | ls -l /dev/media* | ||
| 69 | |||
| 70 | echo "Running unbind of $ADEV from $ADRIVER" | ||
| 71 | echo $ADEV > $ADRIVER/unbind; | ||
| 72 | |||
| 73 | echo "Media device should be there!" | ||
| 74 | ls -l /dev/media* | ||
| 75 | |||
| 76 | sleep 1 | ||
| 77 | |||
| 78 | echo "Running bind of $ADEV from $ADRIVER" | ||
| 79 | echo $ADEV > $ADRIVER/bind; | ||
| 80 | |||
| 81 | echo "Media device should be there!" | ||
| 82 | ls -l /dev/media* | ||
| 83 | |||
| 84 | echo "Test unbind $MDEV - bind $MDEV - unbind $ADEV - bind $ADEV end" | ||
| 85 | echo "==================================" | ||
