media updates for v5.6-rc1

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAl40SYEACgkQCF8+vY7k
 4RU4TQ/8CgWj2+0uMRyIGpggB7B82vBPRqfHr4DIcZzbLSkdDkeDtrEfM5058cUc
 y3NpW9djmcqDMPvOZKFAkb03Bd+mtv89kI72RBTT2mVwCfySYa02K63RqgDg2aFU
 FScPUXlwB8hmZG6BpDlMiykJY1SVyhpb9R2f/7scgJ0ZKVwkKRMmLC5/I5A1IbFX
 WpoqNzRmT07bZJyDdm5RkzxHdM1EP0flMsqWJb3O2aWqeAw9u9+issk+Uv+cMGR+
 70+pmE/6qeurQjS9OHRhrSkf4HjybeByATfgSnONqNrWBtQXgBrHI2TjmT2NvNqV
 kWfsprM1GNPhsLveG6JYKGSNwZK6BHxuUULIjXAr1ocRrae2jVZ7/SZkAvnvzO3v
 hnb2HwgMBkQSctcl4EJDJeLIc1HgIKbZ7D/mFj7N9Mk3Kn7AqcLNHBv+GMunCPFl
 yXNq23ELfxC1HpmQPVhXNM/UaaO5MZCSvOD3MDObcjrxtv4b2bovi6ACDUTgGUNL
 sDozTurG2p1VeGupUnzia62gfb0/fjZ2WBk7RRp8E2K4/93YNEeMA9wgF0E8b4YQ
 SDQcDF1EtsAPF3msiXBC5FSFG42Ly7Ry04fl0v4lAle/0bPamEdQJ2CMVa1ux2Kp
 MRxI39CbRqtoIUbpKzTeInh/FvDDU22TimBKc5sg9d29Hk6y+Yk=
 =sGdY
 -----END PGP SIGNATURE-----

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

Pull media updates from Mauro Carvalho Chehab:

 - New staging driver for Rockship ISPv1 unit

 - New staging driver for Rockchip MIPI Synopsys DPHY RX0

 - y2038 fixes at V4L2 API (backward-compatible)

 - A dvb core fix when receiving invalid EIT sections

 - Some clang-specific warnings got fixed

 - Added support for touch V4L2 interface at vivid

 - Several drivers were converted to use the new
   i2c_new_scanned_device() kAPI

 - Added sm1 support at meson's vdec driver

 - Several other driver cleanups, fixes and improvements

* tag 'media/v5.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (207 commits)
  media: staging/intel-ipu3: remove TODO item about acronyms
  media: v4l2-fwnode: Print the node name while parsing endpoints
  media: Revert "media: staging/intel-ipu3: make imgu use fixed running mode"
  media: mt9v111: constify copied structure
  media: platform: VIDEO_MEDIATEK_JPEG can also depend on MTK_IOMMU
  media: uvcvideo: Add a quirk to force GEO GC6500 Camera bits-per-pixel value
  media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors
  media: hantro: fix post-processing NULL pointer dereference
  media: rcar-vin: Use correct pixel format when aligning format
  media: MAINTAINERS: add entry for Rockchip ISP1 driver
  media: staging: rkisp1: add TODO file for staging
  media: staging: rkisp1: add document for rkisp1 meta buffer format
  media: staging: rkisp1: add output device for parameters
  media: staging: rkisp1: add capture device for statistics
  media: staging: rkisp1: add user space ABI definitions
  media: staging: rkisp1: add streaming paths
  media: staging: rkisp1: add Rockchip ISP1 base driver
  media: staging: phy-rockchip-dphy-rx0: add Rockchip MIPI Synopsys DPHY RX0 driver
  media: staging: dt-bindings: add Rockchip MIPI RX D-PHY RX0 yaml bindings
  media: staging: dt-bindings: add Rockchip ISP1 yaml bindings
  ...
This commit is contained in:
Linus Torvalds 2020-01-31 14:43:23 -08:00
commit 846de71bed
215 changed files with 15018 additions and 2400 deletions

View File

@ -16,7 +16,15 @@ description: |-
properties:
compatible:
const: allwinner,sun7i-a20-csi0
oneOf:
- const: allwinner,sun4i-a10-csi1
- const: allwinner,sun7i-a20-csi0
- items:
- const: allwinner,sun7i-a20-csi1
- const: allwinner,sun4i-a10-csi1
- items:
- const: allwinner,sun8i-r40-csi0
- const: allwinner,sun7i-a20-csi0
reg:
maxItems: 1
@ -25,12 +33,16 @@ properties:
maxItems: 1
clocks:
minItems: 2
maxItems: 3
items:
- description: The CSI interface clock
- description: The CSI ISP clock
- description: The CSI DRAM clock
clock-names:
minItems: 2
maxItems: 3
items:
- const: bus
- const: isp

View File

@ -0,0 +1,141 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019 BayLibre, SAS
%YAML 1.2
---
$id: "http://devicetree.org/schemas/media/amlogic,gx-vdec.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Amlogic Video Decoder
maintainers:
- Neil Armstrong <narmstrong@baylibre.com>
- Maxime Jourdan <mjourdan@baylibre.com>
description: |
The video decoding IP lies within the DOS memory region,
except for the hardware bitstream parser that makes use of an undocumented
region.
It makes use of the following blocks:
- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
then feed from this VIFIFO.
- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
- VDEC_HEVC can decode HEVC and VP9.
Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
concurrently.
properties:
compatible:
oneOf:
- items:
- enum:
- amlogic,gxbb-vdec # GXBB (S905)
- amlogic,gxl-vdec # GXL (S905X, S905D)
- amlogic,gxm-vdec # GXM (S912)
- const: amlogic,gx-vdec
- enum:
- amlogic,g12a-vdec # G12A (S905X2, S905D2)
- amlogic,sm1-vdec # SM1 (S905X3, S905D3)
interrupts:
minItems: 2
interrupt-names:
items:
- const: vdec
- const: esparser
reg:
minItems: 2
reg-names:
items:
- const: dos
- const: esparser
resets:
maxItems: 1
reset-names:
items:
- const: esparser
clocks:
minItems: 4
maxItems: 5
clock-names:
minItems: 4
maxItems: 5
items:
- const: dos_parser
- const: dos
- const: vdec_1
- const: vdec_hevc
- const: vdec_hevcf
amlogic,ao-sysctrl:
description: should point to the AOBUS sysctrl node
allOf:
- $ref: /schemas/types.yaml#/definitions/phandle
amlogic,canvas:
description: should point to a canvas provider node
allOf:
- $ref: /schemas/types.yaml#/definitions/phandle
allOf:
- if:
properties:
compatible:
contains:
enum:
- amlogic,gx-vdec
then:
properties:
clock-names:
maxItems: 4
- if:
properties:
compatible:
contains:
enum:
- amlogic,g12a-vdec
- amlogic,sm1-vdec
then:
properties:
clock-names:
minItems: 5
required:
- compatible
- reg
- reg-names
- interrupts
- interrupt-names
- clocks
- clock-names
- resets
- reset-names
- amlogic,ao-sysctrl
- amlogic,canvas
examples:
- |
vdec: video-decoder@c8820000 {
compatible = "amlogic,gxl-vdec", "amlogic,gx-vdec";
reg = <0xc8820000 0x10000>, <0xc110a580 0xe4>;
reg-names = "dos", "esparser";
interrupts = <44>, <32>;
interrupt-names = "vdec", "esparser";
clocks = <&clk_dos_parser> ,<&clk_dos>, <&clk_vdec_1>, <&clk_vdec_hevc>;
clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
resets = <&reset_parser>;
reset-names = "esparser";
amlogic,ao-sysctrl = <&sysctrl_AO>;
amlogic,canvas = <&canvas>;
};

View File

@ -1,72 +0,0 @@
Amlogic Video Decoder
================================
The video decoding IP lies within the DOS memory region,
except for the hardware bitstream parser that makes use of an undocumented
region.
It makes use of the following blocks:
- ESPARSER is a bitstream parser that outputs to a VIFIFO. Further VDEC blocks
then feed from this VIFIFO.
- VDEC_1 can decode MPEG-1, MPEG-2, MPEG-4 part 2, MJPEG, H.263, H.264, VC-1.
- VDEC_HEVC can decode HEVC and VP9.
Both VDEC_1 and VDEC_HEVC share the "vdec" IRQ and as such cannot run
concurrently.
Device Tree Bindings:
---------------------
VDEC: Video Decoder
--------------------------
Required properties:
- compatible: value should be different for each SoC family as :
- GXBB (S905) : "amlogic,gxbb-vdec"
- GXL (S905X, S905D) : "amlogic,gxl-vdec"
- GXM (S912) : "amlogic,gxm-vdec"
followed by the common "amlogic,gx-vdec"
- reg: base address and size of he following memory-mapped regions :
- dos
- esparser
- reg-names: should contain the names of the previous memory regions
- interrupts: should contain the following IRQs:
- vdec
- esparser
- interrupt-names: should contain the names of the previous interrupts
- amlogic,ao-sysctrl: should point to the AOBUS sysctrl node
- amlogic,canvas: should point to a canvas provider node
- clocks: should contain the following clocks :
- dos_parser
- dos
- vdec_1
- vdec_hevc
- clock-names: should contain the names of the previous clocks
- resets: should contain the parser reset
- reset-names: should be "esparser"
Example:
vdec: video-codec@c8820000 {
compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec";
reg = <0x0 0xc8820000 0x0 0x10000>,
<0x0 0xc110a580 0x0 0xe4>;
reg-names = "dos", "esparser";
interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "vdec", "esparser";
amlogic,ao-sysctrl = <&sysctrl_AO>;
amlogic,canvas = <&canvas>;
clocks = <&clkc CLKID_DOS_PARSER>,
<&clkc CLKID_DOS>,
<&clkc CLKID_VDEC_1>,
<&clkc CLKID_VDEC_HEVC>;
clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
resets = <&reset RESET_PARSER>;
reset-names = "esparser";
};

View File

@ -1,7 +1,8 @@
Device-Tree bindings for hix5hd2 ir IP
Required properties:
- compatible: Should contain "hisilicon,hix5hd2-ir".
- compatible: Should contain "hisilicon,hix5hd2-ir", or:
- "hisilicon,hi3796cv300-ir" for Hi3796CV300 IR device.
- reg: Base physical address of the controller and length of memory
mapped region.
- interrupts: interrupt-specifier for the sole interrupt generated by

View File

@ -13,6 +13,7 @@ on Gen3 and RZ/G2 platforms to a CSI-2 receiver.
- "renesas,vin-r8a7743" for the R8A7743 device
- "renesas,vin-r8a7744" for the R8A7744 device
- "renesas,vin-r8a7745" for the R8A7745 device
- "renesas,vin-r8a77470" for the R8A77470 device
- "renesas,vin-r8a774a1" for the R8A774A1 device
- "renesas,vin-r8a774b1" for the R8A774B1 device
- "renesas,vin-r8a774c0" for the R8A774C0 device
@ -41,9 +42,6 @@ on Gen3 and RZ/G2 platforms to a CSI-2 receiver.
- interrupts: the interrupt for the device
- clocks: Reference to the parent clock
Additionally, an alias named vinX will need to be created to specify
which video input device this is.
The per-board settings for Gen2 and RZ/G1 platforms:
- port - sub-node describing a single endpoint connected to the VIN

View File

@ -0,0 +1,202 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/ti,cal.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL) Device Tree Bindings
maintainers:
- Benoit Parrot <bparrot@ti.com>
description: |-
The Camera Adaptation Layer (CAL) is a key component for image capture
applications. The capture module provides the system interface and the
processing capability to connect CSI2 image-sensor modules to the
DRA72x device.
CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes
should contain a 'port' child node with child 'endpoint' node. Please
refer to the bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
properties:
compatible:
enum:
# for DRA72 controllers
- ti,dra72-cal
# for DRA72 controllers pre ES2.0
- ti,dra72-pre-es2-cal
# for DRA76 controllers
- ti,dra76-cal
# for AM654 controllers
- ti,am654-cal
reg:
minItems: 2
items:
- description: The CAL main register region
- description: The RX Core0 (DPHY0) register region
- description: The RX Core1 (DPHY1) register region
reg-names:
minItems: 2
items:
- const: cal_top
- const: cal_rx_core0
- const: cal_rx_core1
interrupts:
maxItems: 1
ti,camerrx-control:
$ref: "/schemas/types.yaml#/definitions/phandle-array"
description:
phandle to the device control module and offset to the
control_camerarx_core register
clocks:
maxItems: 1
clock-names:
const: fck
power-domains:
description:
List of phandle and PM domain specifier as documented in
Documentation/devicetree/bindings/power/power_domain.txt
maxItems: 1
# See ./video-interfaces.txt for details
ports:
type: object
additionalProperties: false
properties:
"#address-cells":
const: 1
"#size-cells":
const: 0
port@0:
type: object
additionalProperties: false
properties:
reg:
const: 0
description: CSI2 Port #0
patternProperties:
endpoint:
type: object
additionalProperties: false
properties:
clock-lanes:
maxItems: 1
data-lanes:
minItems: 1
maxItems: 4
remote-endpoint: true
required:
- reg
port@1:
type: object
additionalProperties: false
properties:
reg:
const: 1
description: CSI2 Port #1
patternProperties:
endpoint:
type: object
additionalProperties: false
properties:
clock-lanes:
maxItems: 1
data-lanes:
minItems: 1
maxItems: 4
remote-endpoint: true
required:
- reg
required:
- "#address-cells"
- "#size-cells"
- port@0
required:
- compatible
- reg
- reg-names
- interrupts
- ti,camerrx-control
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
cal: cal@4845b000 {
compatible = "ti,dra72-cal";
reg = <0x4845B000 0x400>,
<0x4845B800 0x40>,
<0x4845B900 0x40>;
reg-names = "cal_top",
"cal_rx_core0",
"cal_rx_core1";
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
ti,camerrx-control = <&scm_conf 0xE94>;
ports {
#address-cells = <1>;
#size-cells = <0>;
csi2_0: port@0 {
reg = <0>;
csi2_phy0: endpoint {
remote-endpoint = <&csi2_cam0>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
};
i2c5: i2c@4807c000 {
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
camera-sensor@3c {
compatible = "ovti,ov5640";
reg = <0x3c>;
clocks = <&clk_ov5640_fixed>;
clock-names = "xclk";
port {
csi2_cam0: endpoint {
remote-endpoint = <&csi2_phy0>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
};
...

View File

@ -1,72 +0,0 @@
Texas Instruments DRA72x CAMERA ADAPTATION LAYER (CAL)
------------------------------------------------------
The Camera Adaptation Layer (CAL) is a key component for image capture
applications. The capture module provides the system interface and the
processing capability to connect CSI2 image-sensor modules to the
DRA72x device.
Required properties:
- compatible: must be "ti,dra72-cal"
- reg: CAL Top level, Receiver Core #0, Receiver Core #1 and Camera RX
control address space
- reg-names: cal_top, cal_rx_core0, cal_rx_core1, and camerrx_control
registers
- interrupts: should contain IRQ line for the CAL;
CAL supports 2 camera port nodes on MIPI bus. Each CSI2 camera port nodes
should contain a 'port' child node with child 'endpoint' node. Please
refer to the bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
cal: cal@4845b000 {
compatible = "ti,dra72-cal";
ti,hwmods = "cal";
reg = <0x4845B000 0x400>,
<0x4845B800 0x40>,
<0x4845B900 0x40>,
<0x4A002e94 0x4>;
reg-names = "cal_top",
"cal_rx_core0",
"cal_rx_core1",
"camerrx_control";
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
csi2_0: port@0 {
reg = <0>;
endpoint {
slave-mode;
remote-endpoint = <&ar0330_1>;
};
};
csi2_1: port@1 {
reg = <1>;
};
};
};
i2c5: i2c@4807c000 {
ar0330@10 {
compatible = "ti,ar0330";
reg = <0x10>;
port {
#address-cells = <1>;
#size-cells = <0>;
ar0330_1: endpoint {
reg = <0>;
clock-lanes = <1>;
data-lanes = <0 2 3 4>;
remote-endpoint = <&csi2_0>;
};
};
};
};

View File

@ -15,8 +15,8 @@ The header file for this API is named ``dvb_frontend.h`` and located in
Demodulator driver
^^^^^^^^^^^^^^^^^^
The demodulator driver is responsible to talk with the decoding part of the
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with
The demodulator driver is responsible for talking with the decoding part of the
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, which
tells what type of digital TV standards are supported, and points to a
series of functions that allow the DVB core to command the hardware via
the code under ``include/media/dvb_frontend.c``.
@ -120,7 +120,7 @@ Satellite TV reception is::
.. |delta| unicode:: U+00394
The ``include/media/dvb_frontend.c`` has a kernel thread with is
The ``include/media/dvb_frontend.c`` has a kernel thread which is
responsible for tuning the device. It supports multiple algorithms to
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
@ -220,11 +220,11 @@ Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
- As the gain is visible through the set of registers that adjust the gain,
typically, this statistics is always available [#f3]_.
- Drivers should try to make it available all the times, as this statistics
- Drivers should try to make it available all the times, as these statistics
can be used when adjusting an antenna position and to check for troubles
at the cabling.
.. [#f3] On a few devices, the gain keeps floating if no carrier.
.. [#f3] On a few devices, the gain keeps floating if there is no carrier.
On such devices, strength report should check first if carrier is
detected at the tuner (``FE_HAS_CARRIER``, see :c:type:`fe_status`),
and otherwise return the lowest possible value.
@ -232,7 +232,7 @@ Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
Carrier Signal to Noise ratio (:ref:`DTV-STAT-CNR`)
- Signal to Noise ratio for the main carrier.
- Signal to Noise measurement depends on the device. On some hardware, is
- Signal to Noise measurement depends on the device. On some hardware, it is
available when the main carrier is detected. On those hardware, CNR
measurement usually comes from the tuner (e. g. after ``FE_HAS_CARRIER``,
see :c:type:`fe_status`).
@ -323,8 +323,8 @@ A typical example of the logic that handle status and statistics is::
.read_status = foo_get_status_and_stats,
};
Statistics collect
^^^^^^^^^^^^^^^^^^
Statistics collection
^^^^^^^^^^^^^^^^^^^^^
On almost all frontend hardware, the bit and byte counts are stored by
the hardware after a certain amount of time or after the total bit/block

View File

@ -177,7 +177,7 @@ Available follower modes are:
- ``CEC_MODE_MONITOR``
- 0xe0
- Put the file descriptor into monitor mode. Can only be used in
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,i
combination with :ref:`CEC_MODE_NO_INITIATOR <CEC-MODE-NO-INITIATOR>`,
otherwise the ``EINVAL`` error code will be returned.
In monitor mode all messages this CEC
device transmits and all messages it receives (both broadcast

View File

@ -81,7 +81,7 @@ for this ioctl call.
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
#define VIDEO_EVENT_DECODER_STOPPED 3
#define VIDEO_EVENT_VSYNC 4
__kernel_time_t timestamp;
long timestamp;
union {
video_size_t size;
unsigned int frame_rate; /* in frames per 1000sec */

View File

@ -170,7 +170,7 @@ VIDEO_GET_EVENT call.
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
#define VIDEO_EVENT_DECODER_STOPPED 3
#define VIDEO_EVENT_VSYNC 4
__kernel_time_t timestamp;
long timestamp;
union {
video_size_t size;
unsigned int frame_rate; /* in frames per 1000sec */

View File

@ -55,8 +55,7 @@ please make a proposal on the linux-media mailing list.
- ``V4L2_PIX_FMT_HM12``
- 'HM12'
- YUV 4:2:0 format used by the IVTV driver,
`http://www.ivtvdriver.org/ <http://www.ivtvdriver.org/>`__
- YUV 4:2:0 format used by the IVTV driver.
The format is documented in the kernel sources in the file
``Documentation/media/v4l-drivers/cx2341x.rst``

View File

@ -13,7 +13,7 @@
.. _v4l2-pix-fmt-sgrbg12p:
*******************************************************************************************************************************
V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGBRG12P ('pGAA'), V4L2_PIX_FMT_SBGGR12P ('pBAA'),
V4L2_PIX_FMT_SRGGB12P ('pRCC'), V4L2_PIX_FMT_SGRBG12P ('pgCC'), V4L2_PIX_FMT_SGBRG12P ('pGCC'), V4L2_PIX_FMT_SBGGR12P ('pBCC'),
*******************************************************************************************************************************

View File

@ -13,7 +13,7 @@
.. _v4l2-pix-fmt-sgrbg14p:
*******************************************************************************************************************************
V4L2_PIX_FMT_SRGGB14P ('pRCC'), V4L2_PIX_FMT_SGRBG14P ('pgCC'), V4L2_PIX_FMT_SGBRG14P ('pGCC'), V4L2_PIX_FMT_SBGGR14P ('pBCC'),
V4L2_PIX_FMT_SRGGB14P ('pREE'), V4L2_PIX_FMT_SGRBG14P ('pgEE'), V4L2_PIX_FMT_SGBRG14P ('pGEE'), V4L2_PIX_FMT_SBGGR14P ('pBEE'),
*******************************************************************************************************************************
*man V4L2_PIX_FMT_SRGGB14P(2)*

View File

@ -15,7 +15,7 @@ V4L2_TCH_FMT_DELTA_TD16 ('TD16')
*man V4L2_TCH_FMT_DELTA_TD16(2)*
16-bit signed Touch Delta
16-bit signed little endian Touch Delta
Description
@ -37,38 +37,38 @@ Each cell is one byte.
:widths: 2 1 1 1 1 1 1 1 1
* - start + 0:
- D'\ :sub:`00high`
- D'\ :sub:`00low`
- D'\ :sub:`01high`
- D'\ :sub:`00high`
- D'\ :sub:`01low`
- D'\ :sub:`02high`
- D'\ :sub:`01high`
- D'\ :sub:`02low`
- D'\ :sub:`03high`
- D'\ :sub:`02high`
- D'\ :sub:`03low`
- D'\ :sub:`03high`
* - start + 8:
- D'\ :sub:`10high`
- D'\ :sub:`10low`
- D'\ :sub:`11high`
- D'\ :sub:`10high`
- D'\ :sub:`11low`
- D'\ :sub:`12high`
- D'\ :sub:`11high`
- D'\ :sub:`12low`
- D'\ :sub:`13high`
- D'\ :sub:`12high`
- D'\ :sub:`13low`
- D'\ :sub:`13high`
* - start + 16:
- D'\ :sub:`20high`
- D'\ :sub:`20low`
- D'\ :sub:`21high`
- D'\ :sub:`20high`
- D'\ :sub:`21low`
- D'\ :sub:`22high`
- D'\ :sub:`21high`
- D'\ :sub:`22low`
- D'\ :sub:`23high`
- D'\ :sub:`22high`
- D'\ :sub:`23low`
- D'\ :sub:`23high`
* - start + 24:
- D'\ :sub:`30high`
- D'\ :sub:`30low`
- D'\ :sub:`31high`
- D'\ :sub:`30high`
- D'\ :sub:`31low`
- D'\ :sub:`32high`
- D'\ :sub:`31high`
- D'\ :sub:`32low`
- D'\ :sub:`33high`
- D'\ :sub:`32high`
- D'\ :sub:`33low`
- D'\ :sub:`33high`

View File

@ -15,7 +15,7 @@ V4L2_TCH_FMT_TU16 ('TU16')
*man V4L2_TCH_FMT_TU16(2)*
16-bit unsigned raw touch data
16-bit unsigned little endian raw touch data
Description
@ -36,38 +36,38 @@ Each cell is one byte.
:widths: 2 1 1 1 1 1 1 1 1
* - start + 0:
- R'\ :sub:`00high`
- R'\ :sub:`00low`
- R'\ :sub:`01high`
- R'\ :sub:`00high`
- R'\ :sub:`01low`
- R'\ :sub:`02high`
- R'\ :sub:`01high`
- R'\ :sub:`02low`
- R'\ :sub:`03high`
- R'\ :sub:`02high`
- R'\ :sub:`03low`
- R'\ :sub:`03high`
* - start + 8:
- R'\ :sub:`10high`
- R'\ :sub:`10low`
- R'\ :sub:`11high`
- R'\ :sub:`10high`
- R'\ :sub:`11low`
- R'\ :sub:`12high`
- R'\ :sub:`11high`
- R'\ :sub:`12low`
- R'\ :sub:`13high`
- R'\ :sub:`12high`
- R'\ :sub:`13low`
- R'\ :sub:`13high`
* - start + 16:
- R'\ :sub:`20high`
- R'\ :sub:`20low`
- R'\ :sub:`21high`
- R'\ :sub:`20high`
- R'\ :sub:`21low`
- R'\ :sub:`22high`
- R'\ :sub:`21high`
- R'\ :sub:`22low`
- R'\ :sub:`23high`
- R'\ :sub:`22high`
- R'\ :sub:`23low`
- R'\ :sub:`23high`
* - start + 24:
- R'\ :sub:`30high`
- R'\ :sub:`30low`
- R'\ :sub:`31high`
- R'\ :sub:`30high`
- R'\ :sub:`31low`
- R'\ :sub:`32high`
- R'\ :sub:`31high`
- R'\ :sub:`32low`
- R'\ :sub:`33high`
- R'\ :sub:`32high`
- R'\ :sub:`33low`
- R'\ :sub:`33high`

View File

@ -44,7 +44,9 @@ To enumerate image formats applications initialize the ``type`` and
the :ref:`VIDIOC_ENUM_FMT` ioctl with a pointer to this structure. Drivers
fill the rest of the structure or return an ``EINVAL`` error code. All
formats are enumerable by beginning at index zero and incrementing by
one until ``EINVAL`` is returned.
one until ``EINVAL`` is returned. If applicable, drivers shall return
formats in preference order, where preferred formats are returned before
(that is, with lower ``index`` value) less-preferred formats.
.. note::

View File

@ -279,7 +279,7 @@ EBUSY
then it will set this flag to signal this to the application.
* - ``V4L2_DV_FL_HALF_LINE``
- Specific to interlaced formats: if set, then the vertical
backporch of field 1 (aka the odd field) is really one half-line
frontporch of field 1 (aka the odd field) is really one half-line
longer and the vertical backporch of field 2 (aka the even field)
is really one half-line shorter, so each field has exactly the
same number of half-lines. Whether half-lines can be detected or

View File

@ -1,39 +0,0 @@
.. SPDX-License-Identifier: GPL-2.0
The cx18 driver
===============
.. note::
This documentation is outdated.
Some notes regarding the cx18 driver for the Conexant CX23418 MPEG
encoder chip:
1) Currently supported are:
- Hauppauge HVR-1600
- Compro VideoMate H900
- Yuan MPC718
- Conexant Raptor PAL/SECAM devkit
2) Some people have problems getting the i2c bus to work.
The symptom is that the eeprom cannot be read and the card is
unusable. This is probably fixed, but if you have problems
then post to the video4linux or ivtv-users mailing list.
3) VBI (raw or sliced) has not yet been implemented.
4) MPEG indexing is not yet implemented.
5) The driver is still a bit rough around the edges, this should
improve over time.
Firmware:
You can obtain the firmware files here:
http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz
Untar and copy the .fw files to your firmware directory.

View File

@ -38,7 +38,6 @@ For more details see the file COPYING in the source distribution of Linux.
bttv
cafe_ccic
cpia2
cx18
cx2341x
cx88
davinci-vpbe

View File

@ -4478,13 +4478,10 @@ F: drivers/net/wireless/st/cw1200/
CX18 VIDEO4LINUX DRIVER
M: Andy Walls <awalls@md.metrocast.net>
L: ivtv-devel@ivtvdriver.org (subscribers-only)
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: https://linuxtv.org
W: http://www.ivtvdriver.org/index.php/Cx18
S: Maintained
F: Documentation/media/v4l-drivers/cx18*
F: drivers/media/pci/cx18/
F: include/uapi/linux/ivtv*
@ -8200,8 +8197,7 @@ F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt
F: drivers/auxdisplay/img-ascii-lcd.c
IMGTEC IR DECODER DRIVER
M: James Hogan <jhogan@kernel.org>
S: Maintained
S: Orphan
F: drivers/media/rc/img-ir/
IMON SOUNDGRAPH USB IR RECEIVER
@ -8946,10 +8942,9 @@ F: drivers/media/tuners/it913x*
IVTV VIDEO4LINUX DRIVER
M: Andy Walls <awalls@md.metrocast.net>
L: ivtv-devel@ivtvdriver.org (subscribers-only)
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://www.ivtvdriver.org
W: https://linuxtv.org
S: Maintained
F: Documentation/media/v4l-drivers/ivtv*
F: drivers/media/pci/ivtv/
@ -14297,6 +14292,12 @@ F: drivers/hid/hid-roccat*
F: include/linux/hid-roccat*
F: Documentation/ABI/*/sysfs-driver-hid-roccat*
ROCKCHIP ISP V1 DRIVER
M: Helen Koike <helen.koike@collabora.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/staging/media/rkisp1/
ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
M: Jacob Chen <jacob-chen@iotwrt.com>
M: Ezequiel Garcia <ezequiel@collabora.com>
@ -16737,6 +16738,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
F: drivers/media/platform/ti-vpe/
F: Documentation/devicetree/bindings/media/ti,vpe.yaml
Documentation/devicetree/bindings/media/ti,cal.yaml
TI WILINK WIRELESS DRIVERS
L: linux-wireless@vger.kernel.org

View File

@ -183,24 +183,6 @@ static void cec_devnode_unregister(struct cec_adapter *adap)
put_device(&devnode->dev);
}
#ifdef CONFIG_CEC_NOTIFIER
static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
{
cec_s_phys_addr(adap, pa, false);
}
void cec_register_cec_notifier(struct cec_adapter *adap,
struct cec_notifier *notifier)
{
if (WARN_ON(!cec_is_registered(adap)))
return;
adap->notifier = notifier;
cec_notifier_register(adap->notifier, adap, cec_cec_notify);
}
EXPORT_SYMBOL_GPL(cec_register_cec_notifier);
#endif
#ifdef CONFIG_DEBUG_FS
static ssize_t cec_error_inj_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
@ -416,8 +398,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
#endif
debugfs_remove_recursive(adap->cec_dir);
#ifdef CONFIG_CEC_NOTIFIER
if (adap->notifier)
cec_notifier_unregister(adap->notifier);
cec_notifier_cec_adap_unregister(adap->notifier, adap);
#endif
cec_devnode_unregister(adap);
}

View File

@ -25,7 +25,6 @@ struct cec_notifier {
struct cec_connector_info conn_info;
const char *conn_name;
struct cec_adapter *cec_adap;
void (*callback)(struct cec_adapter *adap, u16 pa);
u16 phys_addr;
};
@ -81,13 +80,12 @@ static void cec_notifier_release(struct kref *kref)
kfree(n);
}
void cec_notifier_put(struct cec_notifier *n)
static void cec_notifier_put(struct cec_notifier *n)
{
mutex_lock(&cec_notifiers_lock);
kref_put(&n->kref, cec_notifier_release);
mutex_unlock(&cec_notifiers_lock);
}
EXPORT_SYMBOL_GPL(cec_notifier_put);
struct cec_notifier *
cec_notifier_conn_register(struct device *hdmi_dev, const char *conn_name,
@ -162,7 +160,6 @@ void cec_notifier_cec_adap_unregister(struct cec_notifier *n,
mutex_lock(&n->lock);
adap->notifier = NULL;
n->cec_adap = NULL;
n->callback = NULL;
mutex_unlock(&n->lock);
cec_notifier_put(n);
}
@ -175,9 +172,7 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa)
mutex_lock(&n->lock);
n->phys_addr = pa;
if (n->callback)
n->callback(n->cec_adap, n->phys_addr);
else if (n->cec_adap)
if (n->cec_adap)
cec_s_phys_addr(n->cec_adap, n->phys_addr, false);
mutex_unlock(&n->lock);
}
@ -198,34 +193,6 @@ void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
}
EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr_from_edid);
void cec_notifier_register(struct cec_notifier *n,
struct cec_adapter *adap,
void (*callback)(struct cec_adapter *adap, u16 pa))
{
kref_get(&n->kref);
mutex_lock(&n->lock);
n->cec_adap = adap;
n->callback = callback;
n->callback(adap, n->phys_addr);
mutex_unlock(&n->lock);
}
EXPORT_SYMBOL_GPL(cec_notifier_register);
void cec_notifier_unregister(struct cec_notifier *n)
{
/* Do nothing unless cec_notifier_register was called first */
if (!n->callback)
return;
mutex_lock(&n->lock);
n->callback = NULL;
n->cec_adap->notifier = NULL;
n->cec_adap = NULL;
mutex_unlock(&n->lock);
cec_notifier_put(n);
}
EXPORT_SYMBOL_GPL(cec_notifier_unregister);
struct device *cec_notifier_parse_hdmi_phandle(struct device *dev)
{
struct platform_device *hdmi_pdev;

View File

@ -9,7 +9,7 @@
#define _CEC_PRIV_H
#include <linux/cec-funcs.h>
#include <media/cec.h>
#include <media/cec-notifier.h>
#define dprintk(lvl, fmt, arg...) \
do { \

View File

@ -345,7 +345,8 @@ static int video_begin(struct saa7146_fh *fh)
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
if (!fmt)
return -EINVAL;
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
@ -398,7 +399,8 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
if (!fmt)
return -EINVAL;
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;

View File

@ -146,7 +146,7 @@ static void __copy_timestamp(struct vb2_buffer *vb, const void *pb)
* and the timecode field and flag if needed.
*/
if (q->copy_timestamp)
vb->timestamp = v4l2_timeval_to_ns(&b->timestamp);
vb->timestamp = v4l2_buffer_get_timestamp(b);
vbuf->flags |= b->flags & V4L2_BUF_FLAG_TIMECODE;
if (b->flags & V4L2_BUF_FLAG_TIMECODE)
vbuf->timecode = b->timecode;
@ -482,7 +482,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
b->flags = vbuf->flags;
b->field = vbuf->field;
b->timestamp = ns_to_timeval(vb->timestamp);
v4l2_buffer_set_timestamp(b, vb->timestamp);
b->timecode = vbuf->timecode;
b->sequence = vbuf->sequence;
b->reserved2 = 0;

View File

@ -971,6 +971,7 @@ static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed)
dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base;
dvbdmxfeed->feed.sec.secbufp = 0;
dvbdmxfeed->feed.sec.seclen = 0;
dvbdmxfeed->pusi_seen = false;
if (!dvbdmx->start_feed) {
mutex_unlock(&dvbdmx->mutex);

View File

@ -983,8 +983,8 @@ struct i2c_client *dvb_module_probe(const char *module_name,
board_info->addr = addr;
board_info->platform_data = platform_data;
request_module(module_name);
client = i2c_new_device(adap, board_info);
if (client == NULL || client->dev.driver == NULL) {
client = i2c_new_client_device(adap, board_info);
if (!i2c_client_has_driver(client)) {
kfree(board_info);
return NULL;
}

View File

@ -290,7 +290,8 @@ static int as102_fe_get_frontend(struct dvb_frontend *fe,
}
static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *settings) {
struct dvb_frontend_tune_settings *settings)
{
settings->min_delay_ms = 1000;

View File

@ -562,7 +562,7 @@ static int au8522_s_video_routing(struct v4l2_subdev *sd,
{
struct au8522_state *state = to_state(sd);
switch(input) {
switch (input) {
case AU8522_COMPOSITE_CH1:
case AU8522_SVIDEO_CH13:
case AU8522_COMPOSITE_CH4_SIF:

View File

@ -530,8 +530,8 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config,
strscpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
board_info.addr = config->i2c_address;
board_info.platform_data = &pdata;
client = i2c_new_device(adapter, &board_info);
if (!client || !client->dev.driver)
client = i2c_new_client_device(adapter, &board_info);
if (!i2c_client_has_driver(client))
return NULL;
return pdata.get_dvb_frontend(client);

View File

@ -189,7 +189,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
adc = dib0070_read_reg(state, 0x19);
dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV\n", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
dprintk("CAPTRIM=%d; ADC = %hd (ADC) & %dmV\n", state->captrim,
adc, (u32)adc * (u32)1800 / (u32)1024);
if (adc >= 400) {
adc -= 400;
@ -200,7 +201,8 @@ static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state
}
if (adc < state->adc_diff) {
dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)\n", state->captrim, adc, state->adc_diff);
dprintk("CAPTRIM=%d is closer to target (%hd/%hd)\n",
state->captrim, adc, state->adc_diff);
state->adc_diff = adc;
state->fcaptrim = state->captrim;
}
@ -364,7 +366,7 @@ static int dib0070_tune_digital(struct dvb_frontend *fe)
}
if (*tune_state == CT_TUNER_START) {
dprintk("Tuning for Band: %hd (%d kHz)\n", band, freq);
dprintk("Tuning for Band: %d (%d kHz)\n", band, freq);
if (state->current_rf != freq) {
u8 REFDIV;
u32 FBDiv, Rest, FREF, VCOF_kHz;
@ -442,12 +444,17 @@ static int dib0070_tune_digital(struct dvb_frontend *fe)
dib0070_write_reg(state, 0x20,
0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
dprintk("REFDIV: %hd, FREF: %d\n", REFDIV, FREF);
dprintk("REFDIV: %u, FREF: %d\n", REFDIV, FREF);
dprintk("FBDIV: %d, Rest: %d\n", FBDiv, Rest);
dprintk("Num: %hd, Den: %hd, SD: %hd\n", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
dprintk("HFDIV code: %hd\n", state->current_tune_table_index->hfdiv);
dprintk("VCO = %hd\n", state->current_tune_table_index->vco_band);
dprintk("VCOF: ((%hd*%d) << 1))\n", state->current_tune_table_index->vco_multi, freq);
dprintk("Num: %u, Den: %u, SD: %d\n", (u16)Rest, Den,
(state->lo4 >> 12) & 0x1);
dprintk("HFDIV code: %u\n",
state->current_tune_table_index->hfdiv);
dprintk("VCO = %u\n",
state->current_tune_table_index->vco_band);
dprintk("VCOF: ((%u*%d) << 1))\n",
state->current_tune_table_index->vco_multi,
freq);
*tune_state = CT_TUNER_STEP_0;
} else { /* we are already tuned to this frequency - the configuration is correct */

View File

@ -1748,7 +1748,8 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
}
dib0090_set_trim(state);
dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step);
dprintk("BB Offset Cal, BBreg=%u,Offset=%d,Value Set=%d\n",
state->dc->addr, state->adc_diff, state->step);
state->dc++;
if (state->dc->addr == 0) /* done */

View File

@ -808,7 +808,7 @@ static int dib7000m_agc_startup(struct dvb_frontend *demod)
dib7000m_restart_agc(state);
dprintk("SPLIT %p: %hd\n", demod, agc_split);
dprintk("SPLIT %p: %u\n", demod, agc_split);
(*agc_state)++;
ret = 5;

View File

@ -915,7 +915,7 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
dib7000p_restart_agc(state);
dprintk("SPLIT %p: %hd\n", demod, agc_split);
dprintk("SPLIT %p: %u\n", demod, agc_split);
(*agc_state)++;
ret = 5;

View File

@ -31,25 +31,26 @@ static int dvb_dummy_fe_read_status(struct dvb_frontend *fe,
return 0;
}
static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
static int dvb_dummy_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
{
*ber = 0;
return 0;
}
static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend *fe,
u16 *strength)
{
*strength = 0;
return 0;
}
static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
static int dvb_dummy_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
{
*snr = 0;
return 0;
}
static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
*ucblocks = 0;
return 0;
@ -77,12 +78,12 @@ static int dvb_dummy_fe_set_frontend(struct dvb_frontend *fe)
return 0;
}
static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
static int dvb_dummy_fe_sleep(struct dvb_frontend *fe)
{
return 0;
}
static int dvb_dummy_fe_init(struct dvb_frontend* fe)
static int dvb_dummy_fe_init(struct dvb_frontend *fe)
{
return 0;
}
@ -99,17 +100,18 @@ static int dvb_dummy_fe_set_voltage(struct dvb_frontend *fe,
return 0;
}
static void dvb_dummy_fe_release(struct dvb_frontend* fe)
static void dvb_dummy_fe_release(struct dvb_frontend *fe)
{
struct dvb_dummy_fe_state* state = fe->demodulator_priv;
struct dvb_dummy_fe_state *state = fe->demodulator_priv;
kfree(state);
}
static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
{
struct dvb_dummy_fe_state* state = NULL;
struct dvb_dummy_fe_state *state = NULL;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
@ -117,16 +119,20 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
memcpy(&state->frontend.ops,
&dvb_dummy_fe_ofdm_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
}
EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
{
struct dvb_dummy_fe_state* state = NULL;
struct dvb_dummy_fe_state *state = NULL;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
@ -134,16 +140,20 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
memcpy(&state->frontend.ops,
&dvb_dummy_fe_qpsk_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
}
EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
{
struct dvb_dummy_fe_state* state = NULL;
struct dvb_dummy_fe_state *state = NULL;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
@ -151,10 +161,14 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
return NULL;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
memcpy(&state->frontend.ops,
&dvb_dummy_fe_qam_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
}
EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
.delsys = { SYS_DVBT },
@ -163,10 +177,18 @@ static const struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
.frequency_min_hz = 0,
.frequency_max_hz = 863250 * kHz,
.frequency_stepsize_hz = 62500,
.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_4_5 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_6_7 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_8_9 |
FE_CAN_FEC_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_64 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO,
@ -194,11 +216,16 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
.frequency_min_hz = 51 * MHz,
.frequency_max_hz = 858 * MHz,
.frequency_stepsize_hz = 62500,
.symbol_rate_min = (57840000 / 2) / 64, /* SACLK/64 == (XIN/2)/64 */
/* symbol_rate_min: SACLK/64 == (XIN/2)/64 */
.symbol_rate_min = (57840000 / 2) / 64,
.symbol_rate_max = (57840000 / 2) / 4, /* SACLK/4 */
.caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
FE_CAN_QAM_128 | FE_CAN_QAM_256 |
FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
.caps = FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_FEC_AUTO |
FE_CAN_INVERSION_AUTO
},
.release = dvb_dummy_fe_release,
@ -227,8 +254,12 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK
},
@ -253,7 +284,3 @@ static const struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
MODULE_DESCRIPTION("DVB DUMMY Frontend");
MODULE_AUTHOR("Emard");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);

View File

@ -12,23 +12,23 @@
#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_DVB_DUMMY_FE)
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void);
struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void);
struct dvb_frontend *dvb_dummy_fe_qam_attach(void);
#else
static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
pr_warn("%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_DUMMY_FE */

View File

@ -922,8 +922,8 @@ struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
board_info.addr = demod_address;
board_info.platform_data = &config;
client = i2c_new_device(i2c, &board_info);
if (!client || !client->dev.driver)
client = i2c_new_client_device(i2c, &board_info);
if (!i2c_client_has_driver(client))
return NULL;
return lgdt330x_get_dvb_frontend(client);

View File

@ -1277,8 +1277,8 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
board_info.addr = cfg->i2c_addr;
board_info.platform_data = &pdata;
client = i2c_new_device(i2c, &board_info);
if (!client || !client->dev.driver)
client = i2c_new_client_device(i2c, &board_info);
if (!i2c_client_has_driver(client))
return NULL;
*tuner_i2c_adapter = pdata.get_i2c_adapter(client);

View File

@ -519,8 +519,8 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
strscpy(board_info.type, "ts2020", I2C_NAME_SIZE);
board_info.addr = config->tuner_address;
board_info.platform_data = &pdata;
client = i2c_new_device(i2c, &board_info);
if (!client || !client->dev.driver)
client = i2c_new_client_device(i2c, &board_info);
if (!i2c_client_has_driver(client))
return NULL;
return fe;

View File

@ -394,10 +394,10 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
#define io_read(s, r) adv748x_read(s, ADV748X_PAGE_IO, r)
#define io_write(s, r, v) adv748x_write(s, ADV748X_PAGE_IO, r, v)
#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~m) | v)
#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~(m)) | (v))
#define hdmi_read(s, r) adv748x_read(s, ADV748X_PAGE_HDMI, r)
#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, r+1)) & m)
#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, (r)+1)) & (m))
#define hdmi_write(s, r, v) adv748x_write(s, ADV748X_PAGE_HDMI, r, v)
#define repeater_read(s, r) adv748x_read(s, ADV748X_PAGE_REPEATER, r)
@ -405,11 +405,11 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
#define sdp_read(s, r) adv748x_read(s, ADV748X_PAGE_SDP, r)
#define sdp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_SDP, r, v)
#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~m) | v)
#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~(m)) | (v))
#define cp_read(s, r) adv748x_read(s, ADV748X_PAGE_CP, r)
#define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v)
#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v)
#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~(m)) | (v))
#define tx_read(t, r) adv748x_read(t->state, t->page, r)
#define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v)

View File

@ -1503,23 +1503,14 @@ static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
{
unsigned int freq;
int a, b;
a = hdmi_read(sd, 0x06);
b = hdmi_read(sd, 0x3b);
if (a < 0 || b < 0)
return 0;
freq = a * 1000000 + ((b & 0x30) >> 4) * 250000;
if (is_hdmi(sd)) {
/* adjust for deep color mode */
unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
freq = freq * 8 / bits_per_channel;
}
return freq;
return a * 1000000 + ((b & 0x30) >> 4) * 250000;
}
static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
@ -1530,9 +1521,28 @@ static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
b = hdmi_read(sd, 0x52);
if (a < 0 || b < 0)
return 0;
return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128;
}
static unsigned int adv76xx_read_hdmi_pixelclock(struct v4l2_subdev *sd)
{
struct adv76xx_state *state = to_state(sd);
const struct adv76xx_chip_info *info = state->info;
unsigned int freq, bits_per_channel, pixelrepetition;
freq = info->read_hdmi_pixelclock(sd);
if (is_hdmi(sd)) {
/* adjust for deep color mode and pixel repetition */
bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
pixelrepetition = (hdmi_read(sd, 0x05) & 0x0f) + 1;
freq = freq * 8 / bits_per_channel / pixelrepetition;
}
return freq;
}
static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings)
{
@ -1579,7 +1589,7 @@ static int adv76xx_query_dv_timings(struct v4l2_subdev *sd,
bt->width = w;
bt->height = h;
bt->pixelclock = info->read_hdmi_pixelclock(sd);
bt->pixelclock = adv76xx_read_hdmi_pixelclock(sd);
bt->hfrontporch = hdmi_read16(sd, 0x20, info->hfrontporch_mask);
bt->hsync = hdmi_read16(sd, 0x22, info->hsync_mask);
bt->hbackporch = hdmi_read16(sd, 0x24, info->hbackporch_mask);

View File

@ -428,10 +428,12 @@ static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
{
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
if (code->index > 0)
return -EINVAL;
code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
code->code = mt9v032->format.code;
return 0;
}
@ -439,7 +441,11 @@ static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse)
{
if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
struct mt9v032 *mt9v032 = to_mt9v032(subdev);
if (fse->index >= 3)
return -EINVAL;
if (mt9v032->format.code != fse->code)
return -EINVAL;
fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index);

View File

@ -103,7 +103,7 @@
#define MT9V111_MAX_CLKIN 27000000
/* The default sensor configuration at startup time. */
static struct v4l2_mbus_framefmt mt9v111_def_fmt = {
static const struct v4l2_mbus_framefmt mt9v111_def_fmt = {
.width = 640,
.height = 480,
.code = MEDIA_BUS_FMT_UYVY8_2X8,

View File

@ -189,6 +189,7 @@ struct ov5640_mode_info {
u32 vtot;
const struct reg_value *reg_data;
u32 reg_data_size;
u32 max_fps;
};
struct ov5640_ctrls {
@ -544,6 +545,7 @@ static const struct ov5640_mode_info ov5640_mode_init_data = {
0, SUBSAMPLING, 640, 1896, 480, 984,
ov5640_init_setting_30fps_VGA,
ARRAY_SIZE(ov5640_init_setting_30fps_VGA),
OV5640_30_FPS,
};
static const struct ov5640_mode_info
@ -551,39 +553,48 @@ ov5640_mode_data[OV5640_NUM_MODES] = {
{OV5640_MODE_QCIF_176_144, SUBSAMPLING,
176, 1896, 144, 984,
ov5640_setting_QCIF_176_144,
ARRAY_SIZE(ov5640_setting_QCIF_176_144)},
ARRAY_SIZE(ov5640_setting_QCIF_176_144),
OV5640_30_FPS},
{OV5640_MODE_QVGA_320_240, SUBSAMPLING,
320, 1896, 240, 984,
ov5640_setting_QVGA_320_240,
ARRAY_SIZE(ov5640_setting_QVGA_320_240)},
ARRAY_SIZE(ov5640_setting_QVGA_320_240),
OV5640_30_FPS},
{OV5640_MODE_VGA_640_480, SUBSAMPLING,
640, 1896, 480, 1080,
ov5640_setting_VGA_640_480,
ARRAY_SIZE(ov5640_setting_VGA_640_480)},
ARRAY_SIZE(ov5640_setting_VGA_640_480),
OV5640_60_FPS},
{OV5640_MODE_NTSC_720_480, SUBSAMPLING,
720, 1896, 480, 984,
ov5640_setting_NTSC_720_480,
ARRAY_SIZE(ov5640_setting_NTSC_720_480)},
ARRAY_SIZE(ov5640_setting_NTSC_720_480),
OV5640_30_FPS},
{OV5640_MODE_PAL_720_576, SUBSAMPLING,
720, 1896, 576, 984,
ov5640_setting_PAL_720_576,
ARRAY_SIZE(ov5640_setting_PAL_720_576)},
ARRAY_SIZE(ov5640_setting_PAL_720_576),
OV5640_30_FPS},
{OV5640_MODE_XGA_1024_768, SUBSAMPLING,
1024, 1896, 768, 1080,
ov5640_setting_XGA_1024_768,
ARRAY_SIZE(ov5640_setting_XGA_1024_768)},
ARRAY_SIZE(ov5640_setting_XGA_1024_768),
OV5640_30_FPS},
{OV5640_MODE_720P_1280_720, SUBSAMPLING,
1280, 1892, 720, 740,
ov5640_setting_720P_1280_720,
ARRAY_SIZE(ov5640_setting_720P_1280_720)},
ARRAY_SIZE(ov5640_setting_720P_1280_720),
OV5640_30_FPS},
{OV5640_MODE_1080P_1920_1080, SCALING,
1920, 2500, 1080, 1120,
ov5640_setting_1080P_1920_1080,
ARRAY_SIZE(ov5640_setting_1080P_1920_1080)},
ARRAY_SIZE(ov5640_setting_1080P_1920_1080),
OV5640_30_FPS},
{OV5640_MODE_QSXGA_2592_1944, SCALING,
2592, 2844, 1944, 1968,
ov5640_setting_QSXGA_2592_1944,
ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944)},
ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944),
OV5640_15_FPS},
};
static int ov5640_init_slave_id(struct ov5640_dev *sensor)
@ -874,7 +885,7 @@ static unsigned long ov5640_calc_sys_clk(struct ov5640_dev *sensor,
* We have reached the maximum allowed PLL1 output,
* increase sysdiv.
*/
if (!rate)
if (!_rate)
break;
/*
@ -1606,14 +1617,8 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
(!nearest && (mode->hact != width || mode->vact != height)))
return NULL;
/* Only 640x480 can operate at 60fps (for now) */
if (fr == OV5640_60_FPS &&
!(mode->hact == 640 && mode->vact == 480))
return NULL;
/* 2592x1944 only works at 15fps max */
if ((mode->hact == 2592 && mode->vact == 1944) &&
fr > OV5640_15_FPS)
/* Check to see if the current mode exceeds the max frame rate */
if (ov5640_framerates[fr] > ov5640_framerates[mode->max_fps])
return NULL;
return mode;

View File

@ -413,21 +413,14 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
struct smiapp_sensor *sensor =
container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
->sensor;
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
int pm_status;
u32 orient = 0;
unsigned int i;
int exposure;
int rval;
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
return smiapp_write(
sensor,
SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
case V4L2_CID_EXPOSURE:
return smiapp_write(
sensor,
SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
if (sensor->streaming)
@ -440,15 +433,10 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
orient ^= sensor->hvflip_inv_mask;
rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
orient);
if (rval < 0)
return rval;
smiapp_update_mbus_formats(sensor);
return 0;
break;
case V4L2_CID_VBLANK:
exposure = sensor->exposure->val;
@ -461,59 +449,105 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
return rval;
}
return smiapp_write(
sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
+ ctrl->val);
case V4L2_CID_HBLANK:
return smiapp_write(
sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
+ ctrl->val);
break;
case V4L2_CID_LINK_FREQ:
if (sensor->streaming)
return -EBUSY;
return smiapp_pll_update(sensor);
case V4L2_CID_TEST_PATTERN: {
unsigned int i;
rval = smiapp_pll_update(sensor);
if (rval)
return rval;
return 0;
case V4L2_CID_TEST_PATTERN:
for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
v4l2_ctrl_activate(
sensor->test_data[i],
ctrl->val ==
V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
break;
}
case V4L2_CID_TEST_PATTERN_RED:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
case V4L2_CID_TEST_PATTERN_GREENR:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
case V4L2_CID_TEST_PATTERN_BLUE:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
case V4L2_CID_TEST_PATTERN_GREENB:
return smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
case V4L2_CID_PIXEL_RATE:
/* For v4l2_ctrl_s_ctrl_int64() used internally. */
pm_runtime_get_noresume(&client->dev);
pm_status = pm_runtime_get_if_in_use(&client->dev);
pm_runtime_put_noidle(&client->dev);
if (!pm_status)
return 0;
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
rval = smiapp_write(
sensor,
SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
break;
case V4L2_CID_EXPOSURE:
rval = smiapp_write(
sensor,
SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
orient);
break;
case V4L2_CID_VBLANK:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
+ ctrl->val);
break;
case V4L2_CID_HBLANK:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
+ ctrl->val);
break;
case V4L2_CID_TEST_PATTERN:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
break;
case V4L2_CID_TEST_PATTERN_RED:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
break;
case V4L2_CID_TEST_PATTERN_GREENR:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
break;
case V4L2_CID_TEST_PATTERN_BLUE:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
break;
case V4L2_CID_TEST_PATTERN_GREENB:
rval = smiapp_write(
sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
break;
case V4L2_CID_PIXEL_RATE:
/* For v4l2_ctrl_s_ctrl_int64() used internally. */
rval = 0;
break;
default:
return -EINVAL;
rval = -EINVAL;
}
if (pm_status > 0) {
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
}
return rval;
}
static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
@ -1184,10 +1218,6 @@ static int smiapp_power_on(struct device *dev)
sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
usleep_range(sleep, sleep);
mutex_lock(&sensor->mutex);
sensor->active = true;
/*
* Failures to respond to the address change command have been noticed.
* Those failures seem to be caused by the sensor requiring a longer
@ -1270,24 +1300,9 @@ static int smiapp_power_on(struct device *dev)
goto out_cci_addr_fail;
}
/* Are we still initialising...? If not, proceed with control setup. */
if (sensor->pixel_array) {
rval = __v4l2_ctrl_handler_setup(
&sensor->pixel_array->ctrl_handler);
if (rval)
goto out_cci_addr_fail;
rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
if (rval)
goto out_cci_addr_fail;
}
mutex_unlock(&sensor->mutex);
return 0;
out_cci_addr_fail:
mutex_unlock(&sensor->mutex);
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
@ -1305,8 +1320,6 @@ static int smiapp_power_off(struct device *dev)
struct smiapp_sensor *sensor =
container_of(ssd, struct smiapp_sensor, ssds[0]);
mutex_lock(&sensor->mutex);
/*
* Currently power/clock to lens are enable/disabled separately
* but they are essentially the same signals. So if the sensor is
@ -1319,10 +1332,6 @@ static int smiapp_power_off(struct device *dev)
SMIAPP_REG_U8_SOFTWARE_RESET,
SMIAPP_SOFTWARE_RESET);
sensor->active = false;
mutex_unlock(&sensor->mutex);
gpiod_set_value(sensor->xshutdown, 0);
clk_disable_unprepare(sensor->ext_clk);
usleep_range(5000, 5000);
@ -1507,6 +1516,30 @@ out:
* V4L2 subdev video operations
*/
static int smiapp_pm_get_init(struct smiapp_sensor *sensor)
{
struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
int rval;
rval = pm_runtime_get_sync(&client->dev);
if (rval < 0) {
if (rval != -EBUSY && rval != -EAGAIN)
pm_runtime_set_active(&client->dev);
pm_runtime_put_noidle(&client->dev);
return rval;
} else if (!rval) {
rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
ctrl_handler);
if (rval)
return rval;
return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
}
return 0;
}
static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
{
struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
@ -1516,22 +1549,23 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
if (sensor->streaming == enable)
return 0;
if (enable) {
rval = pm_runtime_get_sync(&client->dev);
if (rval < 0) {
if (rval != -EBUSY && rval != -EAGAIN)
pm_runtime_set_active(&client->dev);
pm_runtime_put(&client->dev);
return rval;
if (!enable) {
smiapp_stop_streaming(sensor);
sensor->streaming = false;
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
return 0;
}
rval = smiapp_pm_get_init(sensor);
if (rval)
return rval;
sensor->streaming = true;
rval = smiapp_start_streaming(sensor);
if (rval < 0)
sensor->streaming = false;
} else {
rval = smiapp_stop_streaming(sensor);
if (rval < 0) {
sensor->streaming = false;
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
@ -2291,13 +2325,9 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
if (!sensor->dev_init_done)
return -EBUSY;
rval = pm_runtime_get_sync(&client->dev);
if (rval < 0) {
if (rval != -EBUSY && rval != -EAGAIN)
pm_runtime_set_active(&client->dev);
pm_runtime_put_noidle(&client->dev);
rval = smiapp_pm_get_init(sensor);
if (rval < 0)
return -ENODEV;
}
rval = smiapp_read_nvm(sensor, buf, PAGE_SIZE);
if (rval < 0) {

View File

@ -223,9 +223,6 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
len != SMIAPP_REG_32BIT) || flags)
return -EINVAL;
if (!sensor->active)
return 0;
msg.addr = client->addr;
msg.flags = 0; /* Write */
msg.len = 2 + len;

View File

@ -198,7 +198,6 @@ struct smiapp_sensor {
u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
u8 frame_skip;
bool active; /* is the sensor powered on? */
u16 embedded_start; /* embedded data start line */
u16 embedded_end;
u16 image_start; /* image data start line */

View File

@ -386,7 +386,7 @@ void init_bttv_i2c_ir(struct bttv *btv)
if (btv->init_data.name) {
info.platform_data = &btv->init_data;
i2c_dev = i2c_new_device(&btv->c.i2c_adap, &info);
i2c_dev = i2c_new_client_device(&btv->c.i2c_adap, &info);
} else {
/*
* The external IR receiver is at i2c address 0x34 (0x35 for
@ -396,9 +396,9 @@ void init_bttv_i2c_ir(struct bttv *btv)
* internal.
* That's why we probe 0x1a (~0x34) first. CB
*/
i2c_dev = i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL);
i2c_dev = i2c_new_scanned_device(&btv->c.i2c_adap, &info, addr_list, NULL);
}
if (NULL == i2c_dev)
if (IS_ERR(i2c_dev))
return;
#if defined(CONFIG_MODULES) && defined(MODULE)

View File

@ -9,7 +9,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <media/v4l2-device.h>
@ -238,54 +237,6 @@ static int snd_cobalt_pcm_capture_close(struct snd_pcm_substream *substream)
return 0;
}
static int snd_cobalt_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
return snd_pcm_lib_ioctl(substream, cmd, arg);
}
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
size_t size)
{
struct snd_pcm_runtime *runtime = subs->runtime;
dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
vfree(runtime->dma_area);
}
runtime->dma_area = vmalloc(size);
if (!runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
return 0;
}
static int snd_cobalt_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
dprintk("%s called\n", __func__);
return snd_pcm_alloc_vmalloc_buffer(substream,
params_buffer_bytes(params));
}
static int snd_cobalt_pcm_hw_free(struct snd_pcm_substream *substream)
{
if (substream->runtime->dma_area) {
dprintk("freeing pcm capture region\n");
vfree(substream->runtime->dma_area);
substream->runtime->dma_area = NULL;
}
return 0;
}
static int snd_cobalt_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_cobalt_card *cobsc = snd_pcm_substream_chip(substream);
@ -490,36 +441,20 @@ snd_pcm_uframes_t snd_cobalt_pcm_pb_pointer(struct snd_pcm_substream *substream)
substream->runtime->buffer_size;
}
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
unsigned long offset)
{
void *pageptr = subs->runtime->dma_area + offset;
return vmalloc_to_page(pageptr);
}
static const struct snd_pcm_ops snd_cobalt_pcm_capture_ops = {
.open = snd_cobalt_pcm_capture_open,
.close = snd_cobalt_pcm_capture_close,
.ioctl = snd_cobalt_pcm_ioctl,
.hw_params = snd_cobalt_pcm_hw_params,
.hw_free = snd_cobalt_pcm_hw_free,
.prepare = snd_cobalt_pcm_prepare,
.trigger = snd_cobalt_pcm_trigger,
.pointer = snd_cobalt_pcm_pointer,
.page = snd_pcm_get_vmalloc_page,
};
static const struct snd_pcm_ops snd_cobalt_pcm_playback_ops = {
.open = snd_cobalt_pcm_playback_open,
.close = snd_cobalt_pcm_playback_close,
.ioctl = snd_cobalt_pcm_ioctl,
.hw_params = snd_cobalt_pcm_hw_params,
.hw_free = snd_cobalt_pcm_hw_free,
.prepare = snd_cobalt_pcm_pb_prepare,
.trigger = snd_cobalt_pcm_pb_trigger,
.pointer = snd_cobalt_pcm_pb_pointer,
.page = snd_pcm_get_vmalloc_page,
};
int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
@ -555,6 +490,8 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
&snd_cobalt_pcm_capture_ops);
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC,
NULL, 0, 0);
sp->info_flags = 0;
sp->private_data = cobsc;
strscpy(sp->name, "cobalt", sizeof(sp->name));
@ -579,6 +516,8 @@ int snd_cobalt_pcm_create(struct snd_cobalt_card *cobsc)
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_PLAYBACK,
&snd_cobalt_pcm_playback_ops);
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC,
NULL, 0, 0);
sp->info_flags = 0;
sp->private_data = cobsc;
strscpy(sp->name, "cobalt", sizeof(sp->name));

View File

@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <media/v4l2-device.h>
@ -201,67 +200,6 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
return 0;
}
static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
int ret;
snd_cx18_lock(cxsc);
ret = snd_pcm_lib_ioctl(substream, cmd, arg);
snd_cx18_unlock(cxsc);
return ret;
}
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
size_t size)
{
struct snd_pcm_runtime *runtime = subs->runtime;
dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
vfree(runtime->dma_area);
}
runtime->dma_area = vmalloc(size);
if (!runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
return 0;
}
static int snd_cx18_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
dprintk("%s called\n", __func__);
return snd_pcm_alloc_vmalloc_buffer(substream,
params_buffer_bytes(params));
}
static int snd_cx18_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
unsigned long flags;
unsigned char *dma_area = NULL;
spin_lock_irqsave(&cxsc->slock, flags);
if (substream->runtime->dma_area) {
dprintk("freeing pcm capture region\n");
dma_area = substream->runtime->dma_area;
substream->runtime->dma_area = NULL;
}
spin_unlock_irqrestore(&cxsc->slock, flags);
vfree(dma_area);
return 0;
}
static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
@ -291,24 +229,12 @@ snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
return hwptr_done;
}
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
unsigned long offset)
{
void *pageptr = subs->runtime->dma_area + offset;
return vmalloc_to_page(pageptr);
}
static const struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
.open = snd_cx18_pcm_capture_open,
.close = snd_cx18_pcm_capture_close,
.ioctl = snd_cx18_pcm_ioctl,
.hw_params = snd_cx18_pcm_hw_params,
.hw_free = snd_cx18_pcm_hw_free,
.prepare = snd_cx18_pcm_prepare,
.trigger = snd_cx18_pcm_trigger,
.pointer = snd_cx18_pcm_pointer,
.page = snd_pcm_get_vmalloc_page,
};
int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
@ -334,6 +260,7 @@ int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
&snd_cx18_pcm_capture_ops);
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
sp->info_flags = 0;
sp->private_data = cxsc;
strscpy(sp->name, cx->card_name, sizeof(sp->name));

View File

@ -245,7 +245,7 @@ static const struct cx18_card cx18_card_mpc718 = {
.type = CX18_CARD_YUAN_MPC718,
.name = "Yuan MPC718 MiniPCI DVB-T/Analog",
.comment = "Experimenters needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_GPIO_MUX,
@ -305,7 +305,7 @@ static const struct cx18_card cx18_card_gotview_dvd3 = {
.type = CX18_CARD_GOTVIEW_PCI_DVD3,
.name = "GoTView PCI DVD3 Hybrid",
.comment = "Experimenters needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_GPIO_MUX,
@ -419,7 +419,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
.type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
.name = "Toshiba Qosmio DVB-T/Analog",
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
@ -462,7 +462,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
.type = CX18_CARD_LEADTEK_PVR2100,
.name = "Leadtek WinFast PVR2100",
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
"\tTo help, mail the linux-media list (www.linuxtv.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
.hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_GPIO_MUX,

View File

@ -676,7 +676,7 @@ done:
cx->pci_dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
CX18_ERR("card you have to the linux-media mailinglist (www.linuxtv.org)\n");
CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n");
}
cx->v4l2_cap = cx->card->v4l2_capabilities;

View File

@ -88,7 +88,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
break;
}
return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
return IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL)) ?
-1 : 0;
}

View File

@ -495,7 +495,6 @@ static struct page *snd_cx23885_page(struct snd_pcm_substream *substream,
static const struct snd_pcm_ops snd_cx23885_pcm_ops = {
.open = snd_cx23885_pcm_open,
.close = snd_cx23885_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cx23885_hw_params,
.hw_free = snd_cx23885_hw_free,
.prepare = snd_cx23885_prepare,

View File

@ -801,6 +801,25 @@ struct cx23885_board cx23885_boards[] = {
.name = "Hauppauge WinTV-Starburst2",
.portb = CX23885_MPEG_DVB,
},
[CX23885_BOARD_AVERMEDIA_CE310B] = {
.name = "AVerMedia CE310B",
.porta = CX23885_ANALOG_VIDEO,
.force_bff = 1,
.input = {{
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_VIN1_CH1 |
CX25840_NONE_CH2 |
CX25840_NONE0_CH3,
.amux = CX25840_AUDIO7,
}, {
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_VIN8_CH1 |
CX25840_NONE_CH2 |
CX25840_VIN7_CH3 |
CX25840_SVIDEO_ON,
.amux = CX25840_AUDIO7,
} },
},
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@ -1124,6 +1143,10 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070,
.subdevice = 0xf02a,
.card = CX23885_BOARD_HAUPPAUGE_STARBURST2,
}, {
.subvendor = 0x1461,
.subdevice = 0x3100,
.card = CX23885_BOARD_AVERMEDIA_CE310B,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@ -2348,6 +2371,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_DVBSKY_T982:
case CX23885_BOARD_VIEWCAST_260E:
case CX23885_BOARD_VIEWCAST_460E:
case CX23885_BOARD_AVERMEDIA_CE310B:
dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
&dev->i2c_bus[2].i2c_adap,
"cx25840", 0x88 >> 1, NULL);

View File

@ -1159,8 +1159,8 @@ static int dvb_register_ci_mac(struct cx23885_tsport *port)
info.addr = 0x40;
info.platform_data = &sp2_config;
request_module(info.type);
client_ci = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (client_ci == NULL || client_ci->dev.driver == NULL)
client_ci = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_ci))
return -ENODEV;
if (!try_module_get(client_ci->dev.driver->owner)) {
i2c_unregister_device(client_ci);
@ -1826,8 +1826,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x05;
info.platform_data = &tda10071_pdata;
request_module("tda10071");
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -1843,8 +1843,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x0b;
info.platform_data = &a8293_pdata;
request_module("a8293");
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_sec || !client_sec->dev.driver)
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_sec))
goto frontend_detach;
if (!try_module_get(client_sec->dev.driver->owner)) {
i2c_unregister_device(client_sec);
@ -1864,9 +1864,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2165_pdata;
request_module(info.type);
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (client_demod == NULL ||
client_demod->dev.driver == NULL)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -1898,8 +1897,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x05;
info.platform_data = &tda10071_pdata;
request_module("tda10071");
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -1915,8 +1914,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x0b;
info.platform_data = &a8293_pdata;
request_module("a8293");
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_sec || !client_sec->dev.driver)
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_sec))
goto frontend_detach;
if (!try_module_get(client_sec->dev.driver->owner)) {
i2c_unregister_device(client_sec);
@ -1948,9 +1947,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &ts2020_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL ||
client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -1985,9 +1983,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2168_config;
request_module(info.type);
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (client_demod == NULL ||
client_demod->dev.driver == NULL)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2004,9 +2001,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL ||
client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
@ -2032,8 +2028,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2168_config;
request_module(info.type);
client_demod = i2c_new_device(&i2c_bus2->i2c_adap, &info);
if (client_demod == NULL || client_demod->dev.driver == NULL)
client_demod = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2050,9 +2046,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL ||
client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -2080,8 +2075,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &ts2020_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL || client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -2129,8 +2124,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x68;
info.platform_data = &m88ds3103_pdata;
request_module(info.type);
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (client_demod == NULL || client_demod->dev.driver == NULL)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2149,8 +2144,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &ts2020_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL || client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -2194,8 +2189,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2168_config;
request_module(info.type);
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (client_demod == NULL || client_demod->dev.driver == NULL)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2212,9 +2207,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module(info.type);
client_tuner = i2c_new_device(adapter, &info);
if (client_tuner == NULL ||
client_tuner->dev.driver == NULL)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -2245,8 +2239,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x0b;
info.platform_data = &a8293_pdata;
request_module("a8293");
client_sec = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_sec || !client_sec->dev.driver)
client_sec = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_sec))
goto frontend_detach;
if (!try_module_get(client_sec->dev.driver->owner)) {
i2c_unregister_device(client_sec);
@ -2262,8 +2256,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x21;
info.platform_data = &m88rs6000t_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(adapter, &info);
if (!client_tuner || !client_tuner->dev.driver)
client_tuner = i2c_new_client_device(adapter, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {
i2c_unregister_device(client_tuner);
@ -2287,8 +2281,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2168_config;
request_module("%s", info.type);
client_demod = i2c_new_device(&i2c_bus->i2c_adap, &info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&i2c_bus->i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2305,8 +2299,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&i2c_bus2->i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&i2c_bus2->i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
port->i2c_client_demod = NULL;
@ -2340,8 +2334,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x64;
info.platform_data = &si2168_config;
request_module("%s", info.type);
client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2358,8 +2352,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
port->i2c_client_demod = NULL;
@ -2387,8 +2381,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x66;
info.platform_data = &si2168_config;
request_module("%s", info.type);
client_demod = i2c_new_device(&dev->i2c_bus[0].i2c_adap, &info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
i2c_unregister_device(client_demod);
@ -2405,8 +2399,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x62;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
port->i2c_client_demod = NULL;
@ -2447,8 +2441,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
port->i2c_client_demod = NULL;
@ -2483,8 +2477,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x62;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
port->i2c_client_demod = NULL;
@ -2523,8 +2517,8 @@ static int dvb_register(struct cx23885_tsport *port)
info.addr = 0x60;
info.platform_data = &si2157_config;
request_module("%s", info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!client_tuner || !client_tuner->dev.driver)
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner))
goto frontend_detach;
if (!try_module_get(client_tuner->dev.driver->owner)) {

View File

@ -337,7 +337,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
strscpy(info.type, "ir_video", I2C_NAME_SIZE);
/* Use quick read command for probe, some IR chips don't
* support writes */
i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
i2c_new_scanned_device(&bus->i2c_adap, &info, addr_list,
i2c_probe_func_quick_read);
}

View File

@ -257,7 +257,8 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
(dev->board == CX23885_BOARD_MYGICA_X8507) ||
(dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
(dev->board == CX23885_BOARD_VIEWCAST_260E) ||
(dev->board == CX23885_BOARD_VIEWCAST_460E)) {
(dev->board == CX23885_BOARD_VIEWCAST_460E) ||
(dev->board == CX23885_BOARD_AVERMEDIA_CE310B)) {
/* Configure audio routing */
v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
INPUT(input)->amux, 0, 0);

View File

@ -101,6 +101,7 @@
#define CX23885_BOARD_HAUPPAUGE_STARBURST2 59
#define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60
#define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61
#define CX23885_BOARD_AVERMEDIA_CE310B 62
#define GPIO_0 0x00000001
#define GPIO_1 0x00000002

View File

@ -639,7 +639,6 @@ static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
static const struct snd_pcm_ops snd_cx25821_pcm_ops = {
.open = snd_cx25821_pcm_open,
.close = snd_cx25821_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cx25821_hw_params,
.hw_free = snd_cx25821_hw_free,
.prepare = snd_cx25821_prepare,

View File

@ -585,7 +585,6 @@ static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
static const struct snd_pcm_ops snd_cx88_pcm_ops = {
.open = snd_cx88_pcm_open,
.close = snd_cx88_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cx88_hw_params,
.hw_free = snd_cx88_hw_free,
.prepare = snd_cx88_prepare,

View File

@ -613,7 +613,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
}
/*
* We can't call i2c_new_probed_device() because it uses
* We can't call i2c_new_scanned_device() because it uses
* quick writes for probing and at least some RC receiver
* devices only reply to reads.
* Also, Hauppauge XVR needs to be specified, as address 0x71

View File

@ -24,7 +24,7 @@ config VIDEO_IVTV
PCI personal video recorder devices.
This is used in devices such as the Hauppauge PVR-150/250/350/500
cards. There is a driver homepage at <http://www.ivtvdriver.org>.
cards.
To compile this driver as a module, choose M here: the
module will be called ivtv.
@ -67,8 +67,7 @@ config VIDEO_FB_IVTV
This is a framebuffer driver for the Conexant cx23415 MPEG
encoder/decoder.
This is used in the Hauppauge PVR-350 card. There is a driver
homepage at <http://www.ivtvdriver.org>.
This is used in the Hauppauge PVR-350 card.
To compile this driver as a module, choose M here: the
module will be called ivtvfb.

View File

@ -16,8 +16,6 @@
#include "ivtv-alsa.h"
#include "ivtv-alsa-pcm.h"
#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/pcm.h>
@ -206,67 +204,6 @@ static int snd_ivtv_pcm_capture_close(struct snd_pcm_substream *substream)
return 0;
}
static int snd_ivtv_pcm_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
int ret;
snd_ivtv_lock(itvsc);
ret = snd_pcm_lib_ioctl(substream, cmd, arg);
snd_ivtv_unlock(itvsc);
return ret;
}
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
size_t size)
{
struct snd_pcm_runtime *runtime = subs->runtime;
dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
vfree(runtime->dma_area);
}
runtime->dma_area = vmalloc(size);
if (!runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
return 0;
}
static int snd_ivtv_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
dprintk("%s called\n", __func__);
return snd_pcm_alloc_vmalloc_buffer(substream,
params_buffer_bytes(params));
}
static int snd_ivtv_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
unsigned long flags;
unsigned char *dma_area = NULL;
spin_lock_irqsave(&itvsc->slock, flags);
if (substream->runtime->dma_area) {
dprintk("freeing pcm capture region\n");
dma_area = substream->runtime->dma_area;
substream->runtime->dma_area = NULL;
}
spin_unlock_irqrestore(&itvsc->slock, flags);
vfree(dma_area);
return 0;
}
static int snd_ivtv_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
@ -296,24 +233,12 @@ snd_pcm_uframes_t snd_ivtv_pcm_pointer(struct snd_pcm_substream *substream)
return hwptr_done;
}
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
unsigned long offset)
{
void *pageptr = subs->runtime->dma_area + offset;
return vmalloc_to_page(pageptr);
}
static const struct snd_pcm_ops snd_ivtv_pcm_capture_ops = {
.open = snd_ivtv_pcm_capture_open,
.close = snd_ivtv_pcm_capture_close,
.ioctl = snd_ivtv_pcm_ioctl,
.hw_params = snd_ivtv_pcm_hw_params,
.hw_free = snd_ivtv_pcm_hw_free,
.prepare = snd_ivtv_pcm_prepare,
.trigger = snd_ivtv_pcm_trigger,
.pointer = snd_ivtv_pcm_pointer,
.page = snd_pcm_get_vmalloc_page,
};
int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
@ -339,6 +264,7 @@ int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
snd_pcm_set_ops(sp, SNDRV_PCM_STREAM_CAPTURE,
&snd_ivtv_pcm_capture_ops);
snd_pcm_set_managed_buffer_all(sp, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
sp->info_flags = 0;
sp->private_data = itvsc;
strscpy(sp->name, itv->card_name, sizeof(sp->name));

View File

@ -23,7 +23,6 @@
* Driver for the Conexant CX23415/CX23416 chip.
* Author: Kevin Thayer (nufan_wfk at yahoo.com)
* License: GPL
* http://www.ivtvdriver.org
*
* -----
* MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>
@ -723,7 +722,7 @@ done:
IVTV_ERR(" %s based\n", chipname);
IVTV_ERR("Defaulting to %s card\n", itv->card->name);
IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
IVTV_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
IVTV_ERR("card you have to the linux-media mailinglist (www.linuxtv.org)\n");
IVTV_ERR("Prefix your subject line with [UNKNOWN IVTV CARD].\n");
}
itv->v4l2_cap = itv->card->v4l2_capabilities;

View File

@ -28,7 +28,6 @@
* Driver for the cx23415/6 chip.
* Author: Kevin Thayer (nufan_wfk at yahoo.com)
* License: GPL
* http://www.ivtvdriver.org
*
* -----
* MPG600/MPG160 support by T.Adachi <tadachi@tadachi-net.com>

View File

@ -208,12 +208,12 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
info.platform_data = init_data;
strscpy(info.type, type, I2C_NAME_SIZE);
return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
return IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL)) ?
-1 : 0;
}
/* Instantiate the IR receiver device using probing -- undesirable */
struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
void ivtv_i2c_new_ir_legacy(struct ivtv *itv)
{
struct i2c_board_info info;
/*
@ -235,7 +235,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
memset(&info, 0, sizeof(struct i2c_board_info));
strscpy(info.type, "ir_video", I2C_NAME_SIZE);
return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
i2c_new_scanned_device(&itv->i2c_adap, &info, addr_list, NULL);
}
int ivtv_i2c_register(struct ivtv *itv, unsigned idx)

View File

@ -9,7 +9,7 @@
#ifndef IVTV_I2C_H
#define IVTV_I2C_H
struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv);
void ivtv_i2c_new_ir_legacy(struct ivtv *itv);
int ivtv_i2c_register(struct ivtv *itv, unsigned idx);
struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw);

View File

@ -1266,7 +1266,7 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
buf->flags |= V4L2_BUF_FLAG_DONE;
buf->field = V4L2_FIELD_NONE;
buf->timestamp = ns_to_timeval(meye.grab_buffer[index].ts);
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[index].ts);
buf->sequence = meye.grab_buffer[index].sequence;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = index * gbufsize;
@ -1332,7 +1332,7 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
buf->bytesused = meye.grab_buffer[reqnr].size;
buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
buf->field = V4L2_FIELD_NONE;
buf->timestamp = ns_to_timeval(meye.grab_buffer[reqnr].ts);
v4l2_buffer_set_timestamp(buf, meye.grab_buffer[reqnr].ts);
buf->sequence = meye.grab_buffer[reqnr].sequence;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = reqnr * gbufsize;

View File

@ -865,7 +865,6 @@ static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream,
static const struct snd_pcm_ops snd_card_saa7134_capture_ops = {
.open = snd_card_saa7134_capture_open,
.close = snd_card_saa7134_capture_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_card_saa7134_hw_params,
.hw_free = snd_card_saa7134_hw_free,
.prepare = snd_card_saa7134_capture_prepare,

View File

@ -116,8 +116,8 @@ static int si2157_attach(struct saa7164_port *port, struct i2c_adapter *adapter,
request_module(bi.type);
tuner = i2c_new_device(adapter, &bi);
if (tuner == NULL || tuner->dev.driver == NULL)
tuner = i2c_new_client_device(adapter, &bi);
if (!i2c_client_has_driver(tuner))
return -ENODEV;
if (!try_module_get(tuner->dev.driver->owner)) {
@ -637,9 +637,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
info.addr = 0xc8 >> 1;
info.platform_data = &si2168_config;
request_module(info.type);
client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap,
&info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
@ -657,9 +656,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
info.addr = 0xc0 >> 1;
info.platform_data = &si2157_config;
request_module(info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[0].i2c_adap,
&info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[0].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
goto frontend_detach;
@ -682,9 +680,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
info.addr = 0xcc >> 1;
info.platform_data = &si2168_config;
request_module(info.type);
client_demod = i2c_new_device(&dev->i2c_bus[2].i2c_adap,
&info);
if (!client_demod || !client_demod->dev.driver)
client_demod = i2c_new_client_device(&dev->i2c_bus[2].i2c_adap, &info);
if (!i2c_client_has_driver(client_demod))
goto frontend_detach;
if (!try_module_get(client_demod->dev.driver->owner)) {
@ -702,9 +699,8 @@ int saa7164_dvb_register(struct saa7164_port *port)
info.addr = 0xc0 >> 1;
info.platform_data = &si2157_config;
request_module(info.type);
client_tuner = i2c_new_device(&dev->i2c_bus[1].i2c_adap,
&info);
if (!client_tuner || !client_tuner->dev.driver) {
client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info);
if (!i2c_client_has_driver(client_tuner)) {
module_put(client_demod->dev.driver->owner);
i2c_unregister_device(client_demod);
goto frontend_detach;

View File

@ -484,8 +484,8 @@ static struct i2c_client *smi_add_i2c_client(struct i2c_adapter *adapter,
struct i2c_client *client;
request_module(info->type);
client = i2c_new_device(adapter, info);
if (client == NULL || client->dev.driver == NULL)
client = i2c_new_client_device(adapter, info);
if (!i2c_client_has_driver(client))
goto err_add_i2c_client;
if (!try_module_get(client->dev.driver->owner)) {

View File

@ -97,17 +97,6 @@ void solo_g723_isr(struct solo_dev *solo_dev)
}
}
static int snd_solo_hw_params(struct snd_pcm_substream *ss,
struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
}
static int snd_solo_hw_free(struct snd_pcm_substream *ss)
{
return snd_pcm_lib_free_pages(ss);
}
static const struct snd_pcm_hardware snd_solo_pcm_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
@ -270,9 +259,6 @@ static int snd_solo_pcm_copy_kernel(struct snd_pcm_substream *ss, int channel,
static const struct snd_pcm_ops snd_solo_pcm_ops = {
.open = snd_solo_pcm_open,
.close = snd_solo_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_solo_hw_params,
.hw_free = snd_solo_hw_free,
.prepare = snd_solo_pcm_prepare,
.trigger = snd_solo_pcm_trigger,
.pointer = snd_solo_pcm_pointer,
@ -351,7 +337,7 @@ static int solo_snd_pcm_init(struct solo_dev *solo_dev)
ss; ss = ss->next, i++)
sprintf(ss->name, "Camera #%d Audio", i);
snd_pcm_lib_preallocate_pages_for_all(pcm,
snd_pcm_set_managed_buffer_all(pcm,
SNDRV_DMA_TYPE_CONTINUOUS,
NULL,
G723_PERIOD_BYTES * PERIODS,

View File

@ -78,17 +78,6 @@ void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
}
}
static int tw686x_pcm_hw_params(struct snd_pcm_substream *ss,
struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
}
static int tw686x_pcm_hw_free(struct snd_pcm_substream *ss)
{
return snd_pcm_lib_free_pages(ss);
}
/*
* Audio parameters are global and shared among all
* capture channels. The driver prevents changes to
@ -269,9 +258,6 @@ static snd_pcm_uframes_t tw686x_pcm_pointer(struct snd_pcm_substream *ss)
static const struct snd_pcm_ops tw686x_pcm_ops = {
.open = tw686x_pcm_open,
.close = tw686x_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = tw686x_pcm_hw_params,
.hw_free = tw686x_pcm_hw_free,
.prepare = tw686x_pcm_prepare,
.trigger = tw686x_pcm_trigger,
.pointer = tw686x_pcm_pointer,
@ -298,7 +284,7 @@ static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
ss; ss = ss->next, i++)
snprintf(ss->name, sizeof(ss->name), "vch%u audio", i);
snd_pcm_lib_preallocate_pages_for_all(pcm,
snd_pcm_set_managed_buffer_all(pcm,
SNDRV_DMA_TYPE_DEV,
&dev->pci_dev->dev,
TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,

View File

@ -151,7 +151,7 @@ source "drivers/media/platform/sunxi/Kconfig"
config VIDEO_TI_CAL
tristate "TI CAL (Camera Adaptation Layer) driver"
depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on SOC_DRA7XX || COMPILE_TEST
depends on SOC_DRA7XX || ARCH_K3 || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select V4L2_FWNODE
help
@ -200,7 +200,7 @@ config VIDEO_IMX_PXP
config VIDEO_MEDIATEK_JPEG
tristate "Mediatek JPEG Codec driver"
depends on MTK_IOMMU_V1 || COMPILE_TEST
depends on MTK_IOMMU_V1 || MTK_IOMMU || COMPILE_TEST
depends on VIDEO_DEV && VIDEO_V4L2
depends on ARCH_MEDIATEK || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG

View File

@ -73,6 +73,9 @@ const struct isc_format controller_formats[] = {
{
.fourcc = V4L2_PIX_FMT_GREY,
},
{
.fourcc = V4L2_PIX_FMT_Y10,
},
};
/* This is a list of formats that the ISC can receive as *input* */
@ -164,6 +167,12 @@ struct isc_format formats_list[] = {
.mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE,
.pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT,
},
{
.fourcc = V4L2_PIX_FMT_Y10,
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
.pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
},
};
/* Gamma table with gamma 1/2.2 */
@ -211,6 +220,10 @@ const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = {
#define ISC_IS_FORMAT_RAW(mbus_code) \
(((mbus_code) & 0xf000) == 0x3000)
#define ISC_IS_FORMAT_GREY(mbus_code) \
(((mbus_code) == MEDIA_BUS_FMT_Y10_1X10) | \
(((mbus_code) == MEDIA_BUS_FMT_Y8_1X8)))
static inline void isc_update_awb_ctrls(struct isc_device *isc)
{
struct isc_ctrls *ctrls = &isc->ctrls;
@ -1003,6 +1016,7 @@ static int isc_try_validate_formats(struct isc_device *isc)
rgb = true;
break;
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y10:
ret = 0;
grey = true;
break;
@ -1010,34 +1024,29 @@ static int isc_try_validate_formats(struct isc_device *isc)
/* any other different formats are not supported */
ret = -EINVAL;
}
/* we cannot output RAW/Grey if we do not receive RAW */
if ((bayer || grey) &&
!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
return -EINVAL;
v4l2_dbg(1, debug, &isc->v4l2_dev,
"Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
rgb, yuv, grey, bayer);
/* we cannot output RAW if we do not receive RAW */
if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
return -EINVAL;
/* we cannot output GREY if we do not receive RAW/GREY */
if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
!ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
return -EINVAL;
return ret;
}
/*
* Configures the RLP and DMA modules, depending on the output format
* configured for the ISC.
* If direct_dump == true, just dump raw data 8 bits.
* If direct_dump == true, just dump raw data 8/16 bits depending on format.
*/
static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
{
if (direct_dump) {
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
isc->try_config.bpp = 16;
return 0;
}
switch (isc->try_config.fourcc) {
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
@ -1115,9 +1124,23 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
isc->try_config.bpp = 8;
break;
case V4L2_PIX_FMT_Y10:
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10;
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
isc->try_config.bpp = 16;
break;
default:
return -EINVAL;
}
if (direct_dump) {
isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
return 0;
}
return 0;
}
@ -1187,13 +1210,44 @@ static int isc_try_configure_pipeline(struct isc_device *isc)
return 0;
}
static void isc_try_fse(struct isc_device *isc,
struct v4l2_subdev_pad_config *pad_cfg)
{
int ret;
struct v4l2_subdev_frame_size_enum fse = {};
/*
* If we do not know yet which format the subdev is using, we cannot
* do anything.
*/
if (!isc->try_config.sd_format)
return;
fse.code = isc->try_config.sd_format->mbus_code;
fse.which = V4L2_SUBDEV_FORMAT_TRY;
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
pad_cfg, &fse);
/*
* Attempt to obtain format size from subdev. If not available,
* just use the maximum ISC can receive.
*/
if (ret) {
pad_cfg->try_crop.width = ISC_MAX_SUPPORT_WIDTH;
pad_cfg->try_crop.height = ISC_MAX_SUPPORT_HEIGHT;
} else {
pad_cfg->try_crop.width = fse.max_width;
pad_cfg->try_crop.height = fse.max_height;
}
}
static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
u32 *code)
{
int i;
struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
struct v4l2_pix_format *pixfmt = &f->fmt.pix;
struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_pad_config pad_cfg = {};
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_TRY,
};
@ -1290,6 +1344,9 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
if (ret)
goto isc_try_fmt_err;
/* Obtain frame sizes if possible to have crop requirements ready */
isc_try_fse(isc, &pad_cfg);
v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
&pad_cfg, &format);
@ -1414,6 +1471,7 @@ static int isc_enum_framesizes(struct file *file, void *fh,
{
struct isc_device *isc = video_drvdata(file);
struct v4l2_subdev_frame_size_enum fse = {
.code = isc->config.sd_format->mbus_code,
.index = fsize->index,
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
@ -1436,8 +1494,6 @@ static int isc_enum_framesizes(struct file *file, void *fh,
if (ret)
return ret;
fse.code = isc->config.sd_format->mbus_code;
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fsize->discrete.width = fse.max_width;
fsize->discrete.height = fse.max_height;
@ -1450,6 +1506,7 @@ static int isc_enum_frameintervals(struct file *file, void *fh,
{
struct isc_device *isc = video_drvdata(file);
struct v4l2_subdev_frame_interval_enum fie = {
.code = isc->config.sd_format->mbus_code,
.index = fival->index,
.width = fival->width,
.height = fival->height,
@ -1474,7 +1531,6 @@ static int isc_enum_frameintervals(struct file *file, void *fh,
if (ret)
return ret;
fie.code = isc->config.sd_format->mbus_code;
fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
fival->discrete = fie.interval;

View File

@ -148,7 +148,8 @@ static void configure_geometry(struct atmel_isi *isi)
u32 fourcc = isi->current_fmt->fourcc;
isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 ||
fourcc == V4L2_PIX_FMT_RGB32;
fourcc == V4L2_PIX_FMT_RGB32 ||
fourcc == V4L2_PIX_FMT_Y16;
/* According to sensor's output format to set cfg2 */
cfg2 = isi->current_fmt->swap;
@ -554,12 +555,36 @@ static const struct isi_format *find_format_by_fourcc(struct atmel_isi *isi,
return NULL;
}
static void isi_try_fse(struct atmel_isi *isi, const struct isi_format *isi_fmt,
struct v4l2_subdev_pad_config *pad_cfg)
{
int ret;
struct v4l2_subdev_frame_size_enum fse = {
.code = isi_fmt->mbus_code,
.which = V4L2_SUBDEV_FORMAT_TRY,
};
ret = v4l2_subdev_call(isi->entity.subdev, pad, enum_frame_size,
pad_cfg, &fse);
/*
* Attempt to obtain format size from subdev. If not available,
* just use the maximum ISI can receive.
*/
if (ret) {
pad_cfg->try_crop.width = MAX_SUPPORT_WIDTH;
pad_cfg->try_crop.height = MAX_SUPPORT_HEIGHT;
} else {
pad_cfg->try_crop.width = fse.max_width;
pad_cfg->try_crop.height = fse.max_height;
}
}
static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
const struct isi_format **current_fmt)
{
const struct isi_format *isi_fmt;
struct v4l2_pix_format *pixfmt = &f->fmt.pix;
struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_pad_config pad_cfg = {};
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_TRY,
};
@ -576,6 +601,9 @@ static int isi_try_fmt(struct atmel_isi *isi, struct v4l2_format *f,
pixfmt->height = clamp(pixfmt->height, 0U, MAX_SUPPORT_HEIGHT);
v4l2_fill_mbus_format(&format.format, pixfmt, isi_fmt->mbus_code);
isi_try_fse(isi, isi_fmt, &pad_cfg);
ret = v4l2_subdev_call(isi->entity.subdev, pad, set_fmt,
&pad_cfg, &format);
if (ret < 0)
@ -990,6 +1018,16 @@ static const struct isi_format isi_formats[] = {
.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
.bpp = 2,
.swap = ISI_CFG2_YCC_SWAP_MODE_1,
}, {
.fourcc = V4L2_PIX_FMT_GREY,
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
.bpp = 1,
.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
}, {
.fourcc = V4L2_PIX_FMT_Y16,
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
.bpp = 2,
.swap = ISI_CFG2_GS_MODE_2_PIXEL | ISI_CFG2_GRAYSCALE,
},
};

View File

@ -62,6 +62,8 @@
#define ISI_CFG1_THMASK_BEATS_16 (2 << 13)
/* Bitfields in CFG2 */
#define ISI_CFG2_GS_MODE_2_PIXEL (0 << 11)
#define ISI_CFG2_GS_MODE_1_PIXEL (1 << 11)
#define ISI_CFG2_GRAYSCALE (1 << 13)
#define ISI_CFG2_COL_SPACE_YCbCr (0 << 15)
#define ISI_CFG2_COL_SPACE_RGB (1 << 15)

View File

@ -1629,6 +1629,9 @@ static void coda_finish_encode(struct coda_ctx *ctx)
struct coda_dev *dev = ctx->dev;
u32 wr_ptr, start_ptr;
if (ctx->aborting)
return;
/*
* Lock to make sure that an encoder stop command running in parallel
* will either already have marked src_buf as last, or it will wake up
@ -2165,16 +2168,21 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
} else {
if (dev->devtype->product == CODA_960) {
/*
* The CODA960 seems to have an internal list of
* buffers with 64 entries that includes the
* registered frame buffers as well as the rotator
* buffer output.
*
* ROT_INDEX needs to be < 0x40, but >
* ctx->num_internal_frames.
* It was previously assumed that the CODA960 has an
* internal list of 64 buffer entries that contains
* both the registered internal frame buffers as well
* as the rotator buffer output, and that the ROT_INDEX
* register must be set to a value between the last
* internal frame buffers' index and 64.
* At least on firmware version 3.1.1 it turns out that
* setting ROT_INDEX to any value >= 32 causes CODA
* hangups that it can not recover from with the SRC VPU
* reset.
* It does appear to work however, to just set it to a
* fixed value in the [ctx->num_internal_frames, 31]
* range, for example CODA_MAX_FRAMEBUFFERS.
*/
coda_write(dev,
CODA_MAX_FRAMEBUFFERS + dst_buf->vb2_buf.index,
coda_write(dev, CODA_MAX_FRAMEBUFFERS,
CODA9_CMD_DEC_PIC_ROT_INDEX);
reg_addr = CODA9_CMD_DEC_PIC_ROT_ADDR_Y;
@ -2266,6 +2274,9 @@ static void coda_finish_decode(struct coda_ctx *ctx)
int err_vdoa = 0;
u32 val;
if (ctx->aborting)
return;
/* Update kfifo out pointer from coda bitstream read pointer */
coda_kfifo_sync_from_device(ctx);

View File

@ -155,6 +155,7 @@ static const struct coda_codec coda7_codecs[] = {
static const struct coda_codec coda9_codecs[] = {
CODA_CODEC(CODA9_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1920, 1088),
CODA_CODEC(CODA9_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1920, 1088),
CODA_CODEC(CODA9_MODE_ENCODE_MJPG, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_JPEG, 8192, 8192),
CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1088),
CODA_CODEC(CODA9_MODE_DECODE_MP2, V4L2_PIX_FMT_MPEG2, V4L2_PIX_FMT_YUV420, 1920, 1088),
CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1088),
@ -235,6 +236,22 @@ static const struct coda_video_device coda_bit_jpeg_decoder = {
},
};
static const struct coda_video_device coda9_jpeg_encoder = {
.name = "coda-jpeg-encoder",
.type = CODA_INST_ENCODER,
.ops = &coda9_jpeg_encode_ops,
.direct = true,
.src_formats = {
V4L2_PIX_FMT_NV12,
V4L2_PIX_FMT_YUV420,
V4L2_PIX_FMT_YVU420,
V4L2_PIX_FMT_YUV422P,
},
.dst_formats = {
V4L2_PIX_FMT_JPEG,
},
};
static const struct coda_video_device *codadx6_video_devices[] = {
&coda_bit_encoder,
};
@ -252,6 +269,7 @@ static const struct coda_video_device *coda7_video_devices[] = {
};
static const struct coda_video_device *coda9_video_devices[] = {
&coda9_jpeg_encoder,
&coda_bit_encoder,
&coda_bit_decoder,
};
@ -721,7 +739,8 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
break;
case V4L2_PIX_FMT_NV12:
if (!disable_tiling && ctx->dev->devtype->product == CODA_960) {
if (!disable_tiling && ctx->use_bit &&
ctx->dev->devtype->product == CODA_960) {
ctx->tiled_map_type = GDI_TILED_FRAME_MB_RASTER_MAP;
break;
}
@ -1421,7 +1440,7 @@ static void coda_pic_run_work(struct work_struct *work)
if (ctx->ops->run_timeout)
ctx->ops->run_timeout(ctx);
} else if (!ctx->aborting) {
} else {
ctx->ops->finish_run(ctx);
}
@ -1787,7 +1806,7 @@ static void coda_buf_queue(struct vb2_buffer *vb)
coda_queue_source_change_event(ctx);
}
} else {
if (ctx->inst_type == CODA_INST_ENCODER &&
if ((ctx->inst_type == CODA_INST_ENCODER || !ctx->use_bit) &&
vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
vbuf->sequence = ctx->qsequence++;
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
@ -2984,10 +3003,8 @@ static int coda_probe(struct platform_device *pdev)
irq = platform_get_irq_byname(pdev, "bit");
if (irq < 0)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get irq resource\n");
if (irq < 0)
return irq;
}
ret = devm_request_irq(&pdev->dev, irq, coda_irq_handler, 0,
dev_name(&pdev->dev), dev);
@ -2996,6 +3013,22 @@ static int coda_probe(struct platform_device *pdev)
return ret;
}
/* JPEG IRQ */
if (dev->devtype->product == CODA_960) {
irq = platform_get_irq_byname(pdev, "jpeg");
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
coda9_jpeg_irq_handler,
IRQF_ONESHOT, CODA_NAME " jpeg",
dev);
if (ret < 0) {
dev_err(&pdev->dev, "failed to request jpeg irq\n");
return ret;
}
}
dev->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev,
NULL);
if (IS_ERR(dev->rstc)) {

View File

@ -5,46 +5,68 @@
* Copyright (C) 2014 Philipp Zabel, Pengutronix
*/
#include <asm/unaligned.h>
#include <linux/irqreturn.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/slab.h>
#include <linux/swab.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
#include "coda.h"
#include "trace.h"
#define SOI_MARKER 0xffd8
#define DRI_MARKER 0xffdd
#define DQT_MARKER 0xffdb
#define DHT_MARKER 0xffc4
#define SOF_MARKER 0xffc0
#define EOI_MARKER 0xffd9
enum {
CODA9_JPEG_FORMAT_420,
CODA9_JPEG_FORMAT_422,
CODA9_JPEG_FORMAT_224,
CODA9_JPEG_FORMAT_444,
CODA9_JPEG_FORMAT_400,
};
#define CODA9_JPEG_ENC_HUFF_DATA_SIZE (256 + 256 + 16 + 16)
/*
* Typical Huffman tables for 8-bit precision luminance and
* chrominance from JPEG ITU-T.81 (ISO/IEC 10918-1) Annex K.3
*/
static const unsigned char luma_dc_bits[16] = {
static const unsigned char luma_dc[16 + 12] = {
/* bits */
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char luma_dc_value[12] = {
/* values */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
};
static const unsigned char chroma_dc_bits[16] = {
static const unsigned char chroma_dc[16 + 12] = {
/* bits */
0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char chroma_dc_value[12] = {
/* values */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
};
static const unsigned char luma_ac_bits[16] = {
static const unsigned char luma_ac[16 + 162 + 2] = {
/* bits */
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
};
static const unsigned char luma_ac_value[162 + 2] = {
/* values */
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
@ -68,12 +90,11 @@ static const unsigned char luma_ac_value[162 + 2] = {
0xf9, 0xfa, /* padded to 32-bit */
};
static const unsigned char chroma_ac_bits[16] = {
static const unsigned char chroma_ac[16 + 162 + 2] = {
/* bits */
0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
};
static const unsigned char chroma_ac_value[162 + 2] = {
/* values */
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
@ -124,6 +145,38 @@ static unsigned char chroma_q[64] = {
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
};
static const unsigned char width_align[] = {
[CODA9_JPEG_FORMAT_420] = 16,
[CODA9_JPEG_FORMAT_422] = 16,
[CODA9_JPEG_FORMAT_224] = 8,
[CODA9_JPEG_FORMAT_444] = 8,
[CODA9_JPEG_FORMAT_400] = 8,
};
static const unsigned char height_align[] = {
[CODA9_JPEG_FORMAT_420] = 16,
[CODA9_JPEG_FORMAT_422] = 8,
[CODA9_JPEG_FORMAT_224] = 16,
[CODA9_JPEG_FORMAT_444] = 8,
[CODA9_JPEG_FORMAT_400] = 8,
};
static int coda9_jpeg_chroma_format(u32 pixfmt)
{
switch (pixfmt) {
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_NV12:
return CODA9_JPEG_FORMAT_420;
case V4L2_PIX_FMT_YUV422P:
return CODA9_JPEG_FORMAT_422;
case V4L2_PIX_FMT_YUV444:
return CODA9_JPEG_FORMAT_444;
case V4L2_PIX_FMT_GREY:
return CODA9_JPEG_FORMAT_400;
}
return -EINVAL;
}
struct coda_memcpy_desc {
int offset;
const void *src;
@ -148,14 +201,10 @@ int coda_jpeg_write_tables(struct coda_ctx *ctx)
{
int i;
static const struct coda_memcpy_desc huff[8] = {
{ 0, luma_dc_bits, sizeof(luma_dc_bits) },
{ 16, luma_dc_value, sizeof(luma_dc_value) },
{ 32, luma_ac_bits, sizeof(luma_ac_bits) },
{ 48, luma_ac_value, sizeof(luma_ac_value) },
{ 216, chroma_dc_bits, sizeof(chroma_dc_bits) },
{ 232, chroma_dc_value, sizeof(chroma_dc_value) },
{ 248, chroma_ac_bits, sizeof(chroma_ac_bits) },
{ 264, chroma_ac_value, sizeof(chroma_ac_value) },
{ 0, luma_dc, sizeof(luma_dc) },
{ 32, luma_ac, sizeof(luma_ac) },
{ 216, chroma_dc, sizeof(chroma_dc) },
{ 248, chroma_ac, sizeof(chroma_ac) },
};
struct coda_memcpy_desc qmat[3] = {
{ 512, ctx->params.jpeg_qmat_tab[0], 64 },
@ -198,6 +247,379 @@ bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb)
return false;
}
static const int bus_req_num[] = {
[CODA9_JPEG_FORMAT_420] = 2,
[CODA9_JPEG_FORMAT_422] = 3,
[CODA9_JPEG_FORMAT_224] = 3,
[CODA9_JPEG_FORMAT_444] = 4,
[CODA9_JPEG_FORMAT_400] = 4,
};
#define MCU_INFO(mcu_block_num, comp_num, comp0_info, comp1_info, comp2_info) \
(((mcu_block_num) << CODA9_JPEG_MCU_BLOCK_NUM_OFFSET) | \
((comp_num) << CODA9_JPEG_COMP_NUM_OFFSET) | \
((comp0_info) << CODA9_JPEG_COMP0_INFO_OFFSET) | \
((comp1_info) << CODA9_JPEG_COMP1_INFO_OFFSET) | \
((comp2_info) << CODA9_JPEG_COMP2_INFO_OFFSET))
static const u32 mcu_info[] = {
[CODA9_JPEG_FORMAT_420] = MCU_INFO(6, 3, 10, 5, 5),
[CODA9_JPEG_FORMAT_422] = MCU_INFO(4, 3, 9, 5, 5),
[CODA9_JPEG_FORMAT_224] = MCU_INFO(4, 3, 6, 5, 5),
[CODA9_JPEG_FORMAT_444] = MCU_INFO(3, 3, 5, 5, 5),
[CODA9_JPEG_FORMAT_400] = MCU_INFO(1, 1, 5, 0, 0),
};
/*
* Convert Huffman table specifcations to tables of codes and code lengths.
* For reference, see JPEG ITU-T.81 (ISO/IEC 10918-1) [1]
*
* [1] https://www.w3.org/Graphics/JPEG/itu-t81.pdf
*/
static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num,
int *ehufsi, int *ehufco)
{
int i, j, k, lastk, si, code, maxsymbol;
const u8 *bits, *huffval;
struct {
int size[256];
int code[256];
} *huff;
static const unsigned char *huff_tabs[4] = {
luma_dc, luma_ac, chroma_dc, chroma_ac,
};
int ret = -EINVAL;
huff = kzalloc(sizeof(*huff), GFP_KERNEL);
if (!huff)
return -ENOMEM;
bits = huff_tabs[tab_num];
huffval = huff_tabs[tab_num] + 16;
maxsymbol = tab_num & 1 ? 256 : 16;
/* Figure C.1 - Generation of table of Huffman code sizes */
k = 0;
for (i = 1; i <= 16; i++) {
j = bits[i - 1];
if (k + j > maxsymbol)
goto out;
while (j--)
huff->size[k++] = i;
}
lastk = k;
/* Figure C.2 - Generation of table of Huffman codes */
k = 0;
code = 0;
si = huff->size[0];
while (k < lastk) {
while (huff->size[k] == si) {
huff->code[k++] = code;
code++;
}
if (code >= (1 << si))
goto out;
code <<= 1;
si++;
}
/* Figure C.3 - Ordering procedure for encoding procedure code tables */
for (k = 0; k < lastk; k++) {
i = huffval[k];
if (i >= maxsymbol || ehufsi[i])
goto out;
ehufco[i] = huff->code[k];
ehufsi[i] = huff->size[k];
}
ret = 0;
out:
kfree(huff);
return ret;
}
#define DC_TABLE_INDEX0 0
#define AC_TABLE_INDEX0 1
#define DC_TABLE_INDEX1 2
#define AC_TABLE_INDEX1 3
static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx)
{
struct {
int size[4][256];
int code[4][256];
} *huff;
u32 *huff_data;
int i, j;
int ret;
huff = kzalloc(sizeof(*huff), GFP_KERNEL);
if (!huff)
return -ENOMEM;
/* Generate all four (luma/chroma DC/AC) code/size lookup tables */
for (i = 0; i < 4; i++) {
ret = coda9_jpeg_gen_enc_huff_tab(ctx, i, huff->size[i],
huff->code[i]);
if (ret)
goto out;
}
if (!ctx->params.jpeg_huff_data) {
ctx->params.jpeg_huff_data =
kzalloc(sizeof(u32) * CODA9_JPEG_ENC_HUFF_DATA_SIZE,
GFP_KERNEL);
if (!ctx->params.jpeg_huff_data) {
ret = -ENOMEM;
goto out;
}
}
huff_data = ctx->params.jpeg_huff_data;
for (j = 0; j < 4; j++) {
/* Store Huffman lookup tables in AC0, AC1, DC0, DC1 order */
int t = (j == 0) ? AC_TABLE_INDEX0 :
(j == 1) ? AC_TABLE_INDEX1 :
(j == 2) ? DC_TABLE_INDEX0 :
DC_TABLE_INDEX1;
/* DC tables only have 16 entries */
int len = (j < 2) ? 256 : 16;
for (i = 0; i < len; i++) {
if (huff->size[t][i] == 0 && huff->code[t][i] == 0)
*(huff_data++) = 0;
else
*(huff_data++) =
((huff->size[t][i] - 1) << 16) |
huff->code[t][i];
}
}
ret = 0;
out:
kfree(huff);
return ret;
}
static void coda9_jpeg_write_huff_tab(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
u32 *huff_data = ctx->params.jpeg_huff_data;
int i;
/* Write Huffman size/code lookup tables in AC0, AC1, DC0, DC1 order */
coda_write(dev, 0x3, CODA9_REG_JPEG_HUFF_CTRL);
for (i = 0; i < CODA9_JPEG_ENC_HUFF_DATA_SIZE; i++)
coda_write(dev, *(huff_data++), CODA9_REG_JPEG_HUFF_DATA);
coda_write(dev, 0x0, CODA9_REG_JPEG_HUFF_CTRL);
}
static inline void coda9_jpeg_write_qmat_quotients(struct coda_dev *dev,
u8 *qmat, int index)
{
int i;
coda_write(dev, index | 0x3, CODA9_REG_JPEG_QMAT_CTRL);
for (i = 0; i < 64; i++)
coda_write(dev, 0x80000 / qmat[i], CODA9_REG_JPEG_QMAT_DATA);
coda_write(dev, index, CODA9_REG_JPEG_QMAT_CTRL);
}
static void coda9_jpeg_load_qmat_tab(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
u8 *luma_tab;
u8 *chroma_tab;
luma_tab = ctx->params.jpeg_qmat_tab[0];
if (!luma_tab)
luma_tab = luma_q;
chroma_tab = ctx->params.jpeg_qmat_tab[1];
if (!chroma_tab)
chroma_tab = chroma_q;
coda9_jpeg_write_qmat_quotients(dev, luma_tab, 0x00);
coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x40);
coda9_jpeg_write_qmat_quotients(dev, chroma_tab, 0x80);
}
struct coda_jpeg_stream {
u8 *curr;
u8 *end;
};
static inline int coda_jpeg_put_byte(u8 byte, struct coda_jpeg_stream *stream)
{
if (stream->curr >= stream->end)
return -EINVAL;
*stream->curr++ = byte;
return 0;
}
static inline int coda_jpeg_put_word(u16 word, struct coda_jpeg_stream *stream)
{
if (stream->curr + sizeof(__be16) > stream->end)
return -EINVAL;
put_unaligned_be16(word, stream->curr);
stream->curr += sizeof(__be16);
return 0;
}
static int coda_jpeg_put_table(u16 marker, u8 index, const u8 *table,
size_t len, struct coda_jpeg_stream *stream)
{
int i, ret;
ret = coda_jpeg_put_word(marker, stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_word(3 + len, stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_byte(index, stream);
for (i = 0; i < len && ret == 0; i++)
ret = coda_jpeg_put_byte(table[i], stream);
return ret;
}
static int coda_jpeg_define_quantization_table(struct coda_ctx *ctx, u8 index,
struct coda_jpeg_stream *stream)
{
return coda_jpeg_put_table(DQT_MARKER, index,
ctx->params.jpeg_qmat_tab[index], 64,
stream);
}
static int coda_jpeg_define_huffman_table(u8 index, const u8 *table, size_t len,
struct coda_jpeg_stream *stream)
{
return coda_jpeg_put_table(DHT_MARKER, index, table, len, stream);
}
static int coda9_jpeg_encode_header(struct coda_ctx *ctx, int len, u8 *buf)
{
struct coda_jpeg_stream stream = { buf, buf + len };
struct coda_q_data *q_data_src;
int chroma_format, comp_num;
int i, ret, pad;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
if (chroma_format < 0)
return 0;
/* Start Of Image */
ret = coda_jpeg_put_word(SOI_MARKER, &stream);
if (ret < 0)
return ret;
/* Define Restart Interval */
if (ctx->params.jpeg_restart_interval) {
ret = coda_jpeg_put_word(DRI_MARKER, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_word(4, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_word(ctx->params.jpeg_restart_interval,
&stream);
if (ret < 0)
return ret;
}
/* Define Quantization Tables */
ret = coda_jpeg_define_quantization_table(ctx, 0x00, &stream);
if (ret < 0)
return ret;
if (chroma_format != CODA9_JPEG_FORMAT_400) {
ret = coda_jpeg_define_quantization_table(ctx, 0x01, &stream);
if (ret < 0)
return ret;
}
/* Define Huffman Tables */
ret = coda_jpeg_define_huffman_table(0x00, luma_dc, 16 + 12, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_define_huffman_table(0x10, luma_ac, 16 + 162, &stream);
if (ret < 0)
return ret;
if (chroma_format != CODA9_JPEG_FORMAT_400) {
ret = coda_jpeg_define_huffman_table(0x01, chroma_dc, 16 + 12,
&stream);
if (ret < 0)
return ret;
ret = coda_jpeg_define_huffman_table(0x11, chroma_ac, 16 + 162,
&stream);
if (ret < 0)
return ret;
}
/* Start Of Frame */
ret = coda_jpeg_put_word(SOF_MARKER, &stream);
if (ret < 0)
return ret;
comp_num = (chroma_format == CODA9_JPEG_FORMAT_400) ? 1 : 3;
ret = coda_jpeg_put_word(8 + comp_num * 3, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_byte(0x08, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_word(q_data_src->height, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_word(q_data_src->width, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_byte(comp_num, &stream);
if (ret < 0)
return ret;
for (i = 0; i < comp_num; i++) {
static unsigned char subsampling[5][3] = {
[CODA9_JPEG_FORMAT_420] = { 0x22, 0x11, 0x11 },
[CODA9_JPEG_FORMAT_422] = { 0x21, 0x11, 0x11 },
[CODA9_JPEG_FORMAT_224] = { 0x12, 0x11, 0x11 },
[CODA9_JPEG_FORMAT_444] = { 0x11, 0x11, 0x11 },
[CODA9_JPEG_FORMAT_400] = { 0x11 },
};
/* Component identifier, matches SOS */
ret = coda_jpeg_put_byte(i + 1, &stream);
if (ret < 0)
return ret;
ret = coda_jpeg_put_byte(subsampling[chroma_format][i],
&stream);
if (ret < 0)
return ret;
/* Chroma table index */
ret = coda_jpeg_put_byte((i == 0) ? 0 : 1, &stream);
if (ret < 0)
return ret;
}
/* Pad to multiple of 8 bytes */
pad = (stream.curr - buf) % 8;
if (pad) {
pad = 8 - pad;
while (pad--) {
ret = coda_jpeg_put_byte(0x00, &stream);
if (ret < 0)
return ret;
}
}
return stream.curr - buf;
}
/*
* Scale quantization table using nonlinear scaling factor
* u8 qtab[64], scale [50,190]
@ -247,3 +669,279 @@ void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality)
coda_scale_quant_table(ctx->params.jpeg_qmat_tab[1], scale);
}
}
/*
* Encoder context operations
*/
static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
{
struct coda_dev *dev = ctx->dev;
int ret;
ret = coda9_jpeg_load_huff_tab(ctx);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
return ret;
}
if (!ctx->params.jpeg_qmat_tab[0])
ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
if (!ctx->params.jpeg_qmat_tab[1])
ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
return 0;
}
static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx)
{
struct coda_q_data *q_data_src;
struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct coda_dev *dev = ctx->dev;
u32 start_addr, end_addr;
u16 aligned_width, aligned_height;
bool chroma_interleave;
int chroma_format;
int header_len;
int ret;
ktime_t timeout;
src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == 0)
vb2_set_plane_payload(&src_buf->vb2_buf, 0,
vb2_plane_size(&src_buf->vb2_buf, 0));
src_buf->sequence = ctx->osequence;
dst_buf->sequence = ctx->osequence;
ctx->osequence++;
src_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
src_buf->flags &= ~V4L2_BUF_FLAG_PFRAME;
coda_set_gdi_regs(ctx);
start_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
end_addr = start_addr + vb2_plane_size(&dst_buf->vb2_buf, 0);
chroma_format = coda9_jpeg_chroma_format(q_data_src->fourcc);
if (chroma_format < 0)
return chroma_format;
/* Round image dimensions to multiple of MCU size */
aligned_width = round_up(q_data_src->width, width_align[chroma_format]);
aligned_height = round_up(q_data_src->height,
height_align[chroma_format]);
if (aligned_width != q_data_src->bytesperline) {
v4l2_err(&dev->v4l2_dev, "wrong stride: %d instead of %d\n",
aligned_width, q_data_src->bytesperline);
}
header_len =
coda9_jpeg_encode_header(ctx,
vb2_plane_size(&dst_buf->vb2_buf, 0),
vb2_plane_vaddr(&dst_buf->vb2_buf, 0));
if (header_len < 0)
return header_len;
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_BAS_ADDR);
coda_write(dev, end_addr, CODA9_REG_JPEG_BBC_END_ADDR);
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_WR_PTR);
coda_write(dev, start_addr + header_len, CODA9_REG_JPEG_BBC_RD_PTR);
coda_write(dev, 0, CODA9_REG_JPEG_BBC_CUR_POS);
/* 64 words per 256-byte page */
coda_write(dev, 64, CODA9_REG_JPEG_BBC_DATA_CNT);
coda_write(dev, start_addr, CODA9_REG_JPEG_BBC_EXT_ADDR);
coda_write(dev, 0, CODA9_REG_JPEG_BBC_INT_ADDR);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR);
coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL);
coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR);
coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER);
coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBIR);
coda_write(dev, 64, CODA9_REG_JPEG_GBU_BBHR);
chroma_interleave = (q_data_src->fourcc == V4L2_PIX_FMT_NV12);
coda_write(dev, CODA9_JPEG_PIC_CTRL_TC_DIRECTION |
CODA9_JPEG_PIC_CTRL_ENCODER_EN, CODA9_REG_JPEG_PIC_CTRL);
coda_write(dev, 0, CODA9_REG_JPEG_SCL_INFO);
coda_write(dev, chroma_interleave, CODA9_REG_JPEG_DPB_CONFIG);
coda_write(dev, ctx->params.jpeg_restart_interval,
CODA9_REG_JPEG_RST_INTVAL);
coda_write(dev, 1, CODA9_REG_JPEG_BBC_CTRL);
coda_write(dev, bus_req_num[chroma_format], CODA9_REG_JPEG_OP_INFO);
coda9_jpeg_write_huff_tab(ctx);
coda9_jpeg_load_qmat_tab(ctx);
if (ctx->params.rot_mode & CODA_ROT_90) {
aligned_width = aligned_height;
aligned_height = q_data_src->bytesperline;
if (chroma_format == CODA9_JPEG_FORMAT_422)
chroma_format = CODA9_JPEG_FORMAT_224;
else if (chroma_format == CODA9_JPEG_FORMAT_224)
chroma_format = CODA9_JPEG_FORMAT_422;
}
/* These need to be multiples of MCU size */
coda_write(dev, aligned_width << 16 | aligned_height,
CODA9_REG_JPEG_PIC_SIZE);
coda_write(dev, ctx->params.rot_mode ?
(CODA_ROT_MIR_ENABLE | ctx->params.rot_mode) : 0,
CODA9_REG_JPEG_ROT_INFO);
coda_write(dev, mcu_info[chroma_format], CODA9_REG_JPEG_MCU_INFO);
coda_write(dev, 1, CODA9_GDI_CONTROL);
timeout = ktime_add_us(ktime_get(), 100000);
do {
ret = coda_read(dev, CODA9_GDI_STATUS);
if (ktime_compare(ktime_get(), timeout) > 0) {
v4l2_err(&dev->v4l2_dev, "timeout waiting for GDI\n");
return -ETIMEDOUT;
}
} while (!ret);
coda_write(dev, (chroma_format << 17) | (chroma_interleave << 16) |
q_data_src->bytesperline, CODA9_GDI_INFO_CONTROL);
/* The content of this register seems to be irrelevant: */
coda_write(dev, aligned_width << 16 | aligned_height,
CODA9_GDI_INFO_PIC_SIZE);
coda_write_base(ctx, q_data_src, src_buf, CODA9_GDI_INFO_BASE_Y);
coda_write(dev, 0, CODA9_REG_JPEG_DPB_BASE00);
coda_write(dev, 0, CODA9_GDI_CONTROL);
coda_write(dev, 1, CODA9_GDI_PIC_INIT_HOST);
coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
trace_coda_jpeg_run(ctx, src_buf);
coda_write(dev, 1, CODA9_REG_JPEG_PIC_START);
return 0;
}
static void coda9_jpeg_finish_encode(struct coda_ctx *ctx)
{
struct vb2_v4l2_buffer *src_buf, *dst_buf;
struct coda_dev *dev = ctx->dev;
u32 wr_ptr, start_ptr;
u32 err_mb;
if (ctx->aborting) {
coda_write(ctx->dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
return;
}
/*
* Lock to make sure that an encoder stop command running in parallel
* will either already have marked src_buf as last, or it will wake up
* the capture queue after the buffers are returned.
*/
mutex_lock(&ctx->wakeup_mutex);
src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
trace_coda_jpeg_done(ctx, dst_buf);
/*
* Set plane payload to the number of bytes written out
* by the JPEG processing unit
*/
start_ptr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR);
vb2_set_plane_payload(&dst_buf->vb2_buf, 0, wr_ptr - start_ptr);
err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
if (err_mb)
coda_dbg(1, ctx, "ERRMB: 0x%x\n", err_mb);
coda_write(dev, 0, CODA9_REG_JPEG_BBC_FLUSH_CMD);
dst_buf->flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_LAST);
dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
dst_buf->flags |= src_buf->flags & V4L2_BUF_FLAG_LAST;
v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, false);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
coda_m2m_buf_done(ctx, dst_buf, err_mb ? VB2_BUF_STATE_ERROR :
VB2_BUF_STATE_DONE);
mutex_unlock(&ctx->wakeup_mutex);
coda_dbg(1, ctx, "job finished: encoded frame (%u)%s\n",
dst_buf->sequence,
(dst_buf->flags & V4L2_BUF_FLAG_LAST) ? " (last)" : "");
}
static void coda9_jpeg_release(struct coda_ctx *ctx)
{
int i;
if (ctx->params.jpeg_qmat_tab[0] == luma_q)
ctx->params.jpeg_qmat_tab[0] = NULL;
if (ctx->params.jpeg_qmat_tab[1] == chroma_q)
ctx->params.jpeg_qmat_tab[1] = NULL;
for (i = 0; i < 3; i++)
kfree(ctx->params.jpeg_qmat_tab[i]);
kfree(ctx->params.jpeg_huff_data);
}
const struct coda_context_ops coda9_jpeg_encode_ops = {
.queue_init = coda_encoder_queue_init,
.start_streaming = coda9_jpeg_start_encoding,
.prepare_run = coda9_jpeg_prepare_encode,
.finish_run = coda9_jpeg_finish_encode,
.release = coda9_jpeg_release,
};
irqreturn_t coda9_jpeg_irq_handler(int irq, void *data)
{
struct coda_dev *dev = data;
struct coda_ctx *ctx;
int status;
int err_mb;
status = coda_read(dev, CODA9_REG_JPEG_PIC_STATUS);
if (status == 0)
return IRQ_HANDLED;
coda_write(dev, status, CODA9_REG_JPEG_PIC_STATUS);
if (status & CODA9_JPEG_STATUS_OVERFLOW)
v4l2_err(&dev->v4l2_dev, "JPEG overflow\n");
if (status & CODA9_JPEG_STATUS_BBC_INT)
v4l2_err(&dev->v4l2_dev, "JPEG BBC interrupt\n");
if (status & CODA9_JPEG_STATUS_ERROR) {
v4l2_err(&dev->v4l2_dev, "JPEG error\n");
err_mb = coda_read(dev, CODA9_REG_JPEG_PIC_ERRMB);
if (err_mb) {
v4l2_err(&dev->v4l2_dev,
"ERRMB: 0x%x: rst idx %d, mcu pos (%d,%d)\n",
err_mb, err_mb >> 24, (err_mb >> 12) & 0xfff,
err_mb & 0xfff);
}
}
ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
if (!ctx) {
v4l2_err(&dev->v4l2_dev,
"Instance released before the end of transaction\n");
mutex_unlock(&dev->coda_mutex);
return IRQ_HANDLED;
}
complete(&ctx->completion);
return IRQ_HANDLED;
}

View File

@ -126,6 +126,7 @@ struct coda_params {
u8 jpeg_quality;
u8 jpeg_restart_interval;
u8 *jpeg_qmat_tab[3];
u32 *jpeg_huff_data;
int codec_mode;
int codec_mode_aux;
enum v4l2_mpeg_video_multi_slice_mode slice_mode;
@ -366,7 +367,9 @@ void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality);
extern const struct coda_context_ops coda_bit_encode_ops;
extern const struct coda_context_ops coda_bit_decode_ops;
extern const struct coda_context_ops coda9_jpeg_encode_ops;
irqreturn_t coda_irq_handler(int irq, void *data);
irqreturn_t coda9_jpeg_irq_handler(int irq, void *data);
#endif /* __CODA_H__ */

View File

@ -451,12 +451,21 @@
#define CODA9_CMD_FIRMWARE_CODE_REV 0x1c4
#define CODA9_GDMA_BASE 0x1000
#define CODA9_GDI_CONTROL (CODA9_GDMA_BASE + 0x034)
#define CODA9_GDI_PIC_INIT_HOST (CODA9_GDMA_BASE + 0x038)
#define CODA9_GDI_STATUS (CODA9_GDMA_BASE + 0x080)
#define CODA9_GDI_WPROT_ERR_CLR (CODA9_GDMA_BASE + 0x0a0)
#define CODA9_GDI_WPROT_RGN_EN (CODA9_GDMA_BASE + 0x0ac)
#define CODA9_GDI_BUS_CTRL (CODA9_GDMA_BASE + 0x0f0)
#define CODA9_GDI_BUS_STATUS (CODA9_GDMA_BASE + 0x0f4)
#define CODA9_GDI_INFO_CONTROL (CODA9_GDMA_BASE + 0x400)
#define CODA9_GDI_INFO_PIC_SIZE (CODA9_GDMA_BASE + 0x404)
#define CODA9_GDI_INFO_BASE_Y (CODA9_GDMA_BASE + 0x408)
#define CODA9_GDI_INFO_BASE_CB (CODA9_GDMA_BASE + 0x40c)
#define CODA9_GDI_INFO_BASE_CR (CODA9_GDMA_BASE + 0x410)
#define CODA9_GDI_XY2_CAS_0 (CODA9_GDMA_BASE + 0x800)
#define CODA9_GDI_XY2_CAS_F (CODA9_GDMA_BASE + 0x83c)
@ -477,4 +486,78 @@
#define CODA9_GDI_RBC2_AXI_1F (CODA9_GDMA_BASE + 0x91c)
#define CODA9_GDI_TILEDBUF_BASE (CODA9_GDMA_BASE + 0x920)
#define CODA9_JPEG_BASE 0x3000
#define CODA9_REG_JPEG_PIC_START (CODA9_JPEG_BASE + 0x000)
#define CODA9_REG_JPEG_PIC_STATUS (CODA9_JPEG_BASE + 0x004)
#define CODA9_JPEG_STATUS_OVERFLOW BIT(3)
#define CODA9_JPEG_STATUS_BBC_INT BIT(2)
#define CODA9_JPEG_STATUS_ERROR BIT(1)
#define CODA9_JPEG_STATUS_DONE BIT(0)
#define CODA9_REG_JPEG_PIC_ERRMB (CODA9_JPEG_BASE + 0x008)
#define CODA9_JPEG_ERRMB_RESTART_IDX_MASK (0xf << 24)
#define CODA9_JPEG_ERRMB_MCU_POS_X_MASK (0xfff << 12)
#define CODA9_JPEG_ERRMB_MCU_POS_Y_MASK 0xfff
#define CODA9_REG_JPEG_PIC_CTRL (CODA9_JPEG_BASE + 0x010)
#define CODA9_JPEG_PIC_CTRL_USER_HUFFMAN_EN BIT(6)
#define CODA9_JPEG_PIC_CTRL_TC_DIRECTION BIT(4)
#define CODA9_JPEG_PIC_CTRL_ENCODER_EN BIT(3)
#define CODA9_REG_JPEG_PIC_SIZE (CODA9_JPEG_BASE + 0x014)
#define CODA9_REG_JPEG_MCU_INFO (CODA9_JPEG_BASE + 0x018)
#define CODA9_JPEG_MCU_BLOCK_NUM_OFFSET 16
#define CODA9_JPEG_COMP_NUM_OFFSET 12
#define CODA9_JPEG_COMP0_INFO_OFFSET 8
#define CODA9_JPEG_COMP1_INFO_OFFSET 4
#define CODA9_JPEG_COMP2_INFO_OFFSET 0
#define CODA9_REG_JPEG_ROT_INFO (CODA9_JPEG_BASE + 0x01c)
#define CODA9_JPEG_ROT_MIR_ENABLE BIT(4)
#define CODA9_JPEG_ROT_MIR_MODE_MASK 0xf
#define CODA9_REG_JPEG_SCL_INFO (CODA9_JPEG_BASE + 0x020)
#define CODA9_JPEG_SCL_ENABLE BIT(4)
#define CODA9_JPEG_SCL_HOR_MODE_MASK (0x3 << 2)
#define CODA9_JPEG_SCL_VER_MODE_MASK (0x3 << 0)
#define CODA9_REG_JPEG_IF_INFO (CODA9_JPEG_BASE + 0x024)
#define CODA9_JPEG_SENS_IF_CLR BIT(1)
#define CODA9_JPEG_DISP_IF_CLR BIT(0)
#define CODA9_REG_JPEG_OP_INFO (CODA9_JPEG_BASE + 0x02c)
#define CODA9_JPEG_BUS_REQ_NUM_OFFSET 0
#define CODA9_JPEG_BUS_REQ_NUM_MASK 0x7
#define CODA9_REG_JPEG_DPB_CONFIG (CODA9_JPEG_BASE + 0x030)
#define CODA9_REG_JPEG_DPB_BASE00 (CODA9_JPEG_BASE + 0x040)
#define CODA9_REG_JPEG_HUFF_CTRL (CODA9_JPEG_BASE + 0x080)
#define CODA9_REG_JPEG_HUFF_ADDR (CODA9_JPEG_BASE + 0x084)
#define CODA9_REG_JPEG_HUFF_DATA (CODA9_JPEG_BASE + 0x088)
#define CODA9_REG_JPEG_QMAT_CTRL (CODA9_JPEG_BASE + 0x090)
#define CODA9_REG_JPEG_QMAT_ADDR (CODA9_JPEG_BASE + 0x094)
#define CODA9_REG_JPEG_QMAT_DATA (CODA9_JPEG_BASE + 0x098)
#define CODA9_REG_JPEG_RST_INTVAL (CODA9_JPEG_BASE + 0x0b0)
#define CODA9_REG_JPEG_RST_INDEX (CODA9_JPEG_BASE + 0x0b4)
#define CODA9_REG_JPEG_RST_COUNT (CODA9_JPEG_BASE + 0x0b8)
#define CODA9_REG_JPEG_DPCM_DIFF_Y (CODA9_JPEG_BASE + 0x0f0)
#define CODA9_REG_JPEG_DPCM_DIFF_CB (CODA9_JPEG_BASE + 0x0f4)
#define CODA9_REG_JPEG_DPCM_DIFF_CR (CODA9_JPEG_BASE + 0x0f8)
#define CODA9_REG_JPEG_GBU_CTRL (CODA9_JPEG_BASE + 0x100)
#define CODA9_REG_JPEG_GBU_BT_PTR (CODA9_JPEG_BASE + 0x110)
#define CODA9_REG_JPEG_GBU_WD_PTR (CODA9_JPEG_BASE + 0x114)
#define CODA9_REG_JPEG_GBU_TT_CNT (CODA9_JPEG_BASE + 0x118)
#define CODA9_REG_JPEG_GBU_BBSR (CODA9_JPEG_BASE + 0x140)
#define CODA9_REG_JPEG_GBU_BBER (CODA9_JPEG_BASE + 0x144)
#define CODA9_REG_JPEG_GBU_BBIR (CODA9_JPEG_BASE + 0x148)
#define CODA9_REG_JPEG_GBU_BBHR (CODA9_JPEG_BASE + 0x14c)
#define CODA9_REG_JPEG_GBU_BCNT (CODA9_JPEG_BASE + 0x158)
#define CODA9_REG_JPEG_GBU_FF_RPTR (CODA9_JPEG_BASE + 0x160)
#define CODA9_REG_JPEG_GBU_FF_WPTR (CODA9_JPEG_BASE + 0x164)
#define CODA9_REG_JPEG_BBC_END_ADDR (CODA9_JPEG_BASE + 0x208)
#define CODA9_REG_JPEG_BBC_WR_PTR (CODA9_JPEG_BASE + 0x20c)
#define CODA9_REG_JPEG_BBC_RD_PTR (CODA9_JPEG_BASE + 0x210)
#define CODA9_REG_JPEG_BBC_EXT_ADDR (CODA9_JPEG_BASE + 0x214)
#define CODA9_REG_JPEG_BBC_INT_ADDR (CODA9_JPEG_BASE + 0x218)
#define CODA9_REG_JPEG_BBC_DATA_CNT (CODA9_JPEG_BASE + 0x21c)
#define CODA9_REG_JPEG_BBC_COMMAND (CODA9_JPEG_BASE + 0x220)
#define CODA9_REG_JPEG_BBC_BUSY (CODA9_JPEG_BASE + 0x224)
#define CODA9_REG_JPEG_BBC_CTRL (CODA9_JPEG_BASE + 0x228)
#define CODA9_REG_JPEG_BBC_CUR_POS (CODA9_JPEG_BASE + 0x22c)
#define CODA9_REG_JPEG_BBC_BAS_ADDR (CODA9_JPEG_BASE + 0x230)
#define CODA9_REG_JPEG_BBC_STRM_CTRL (CODA9_JPEG_BASE + 0x234)
#define CODA9_REG_JPEG_BBC_FLUSH_CMD (CODA9_JPEG_BASE + 0x238)
#endif

View File

@ -154,6 +154,16 @@ DEFINE_EVENT(coda_buf_meta_class, coda_dec_rot_done,
TP_ARGS(ctx, buf, meta)
);
DEFINE_EVENT(coda_buf_class, coda_jpeg_run,
TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
TP_ARGS(ctx, buf)
);
DEFINE_EVENT(coda_buf_class, coda_jpeg_done,
TP_PROTO(struct coda_ctx *ctx, struct vb2_v4l2_buffer *buf),
TP_ARGS(ctx, buf)
);
#endif /* __CODA_TRACE_H__ */
#undef TRACE_INCLUDE_PATH

View File

@ -168,21 +168,22 @@ int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev)
int ret = 0;
printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
BUG_ON(!dev->hw_ops.open);
BUG_ON(!dev->hw_ops.enable);
BUG_ON(!dev->hw_ops.set_hw_if_params);
BUG_ON(!dev->hw_ops.configure);
BUG_ON(!dev->hw_ops.set_buftype);
BUG_ON(!dev->hw_ops.get_buftype);
BUG_ON(!dev->hw_ops.enum_pix);
BUG_ON(!dev->hw_ops.set_frame_format);
BUG_ON(!dev->hw_ops.get_frame_format);
BUG_ON(!dev->hw_ops.get_pixel_format);
BUG_ON(!dev->hw_ops.set_pixel_format);
BUG_ON(!dev->hw_ops.set_image_window);
BUG_ON(!dev->hw_ops.get_image_window);
BUG_ON(!dev->hw_ops.get_line_length);
BUG_ON(!dev->hw_ops.getfid);
if (!dev->hw_ops.open ||
!dev->hw_ops.enable ||
!dev->hw_ops.set_hw_if_params ||
!dev->hw_ops.configure ||
!dev->hw_ops.set_buftype ||
!dev->hw_ops.get_buftype ||
!dev->hw_ops.enum_pix ||
!dev->hw_ops.set_frame_format ||
!dev->hw_ops.get_frame_format ||
!dev->hw_ops.get_pixel_format ||
!dev->hw_ops.set_pixel_format ||
!dev->hw_ops.set_image_window ||
!dev->hw_ops.get_image_window ||
!dev->hw_ops.get_line_length ||
!dev->hw_ops.getfid)
return -EINVAL;
mutex_lock(&ccdc_lock);
if (!ccdc_cfg) {

View File

@ -229,6 +229,9 @@ static int mtk_mdp_remove(struct platform_device *pdev)
mtk_mdp_unregister_m2m_device(mdp);
v4l2_device_unregister(&mdp->v4l2_dev);
flush_workqueue(mdp->wdt_wq);
destroy_workqueue(mdp->wdt_wq);
flush_workqueue(mdp->job_wq);
destroy_workqueue(mdp->job_wq);

View File

@ -104,6 +104,7 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
{
struct vdec_fb *disp_frame_buffer = NULL;
struct mtk_video_dec_buf *dstbuf;
struct vb2_v4l2_buffer *vb;
mtk_v4l2_debug(3, "[%d]", ctx->id);
if (vdec_if_get_param(ctx,
@ -121,25 +122,26 @@ static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf,
frame_buffer);
vb = &dstbuf->m2m_buf.vb;
mutex_lock(&ctx->lock);
if (dstbuf->used) {
vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0,
vb2_set_plane_payload(&vb->vb2_buf, 0,
ctx->picinfo.fb_sz[0]);
if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 1,
vb2_set_plane_payload(&vb->vb2_buf, 1,
ctx->picinfo.fb_sz[1]);
mtk_v4l2_debug(2,
"[%d]status=%x queue id=%d to done_list %d",
ctx->id, disp_frame_buffer->status,
dstbuf->vb.vb2_buf.index,
vb->vb2_buf.index,
dstbuf->queued_in_vb2);
v4l2_m2m_buf_done(&dstbuf->vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
ctx->decoded_frame_cnt++;
}
mutex_unlock(&ctx->lock);
return &dstbuf->vb.vb2_buf;
return &vb->vb2_buf;
}
/*
@ -154,6 +156,7 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
{
struct mtk_video_dec_buf *dstbuf;
struct vdec_fb *free_frame_buffer = NULL;
struct vb2_v4l2_buffer *vb;
if (vdec_if_get_param(ctx,
GET_PARAM_FREE_FRAME_BUFFER,
@ -171,6 +174,7 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf,
frame_buffer);
vb = &dstbuf->m2m_buf.vb;
mutex_lock(&ctx->lock);
if (dstbuf->used) {
@ -187,9 +191,9 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
mtk_v4l2_debug(2,
"[%d]status=%x queue id=%d to rdy_queue %d",
ctx->id, free_frame_buffer->status,
dstbuf->vb.vb2_buf.index,
vb->vb2_buf.index,
dstbuf->queued_in_vb2);
v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
} else if ((dstbuf->queued_in_vb2 == false) &&
(dstbuf->queued_in_v4l2 == true)) {
/*
@ -205,8 +209,8 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
mtk_v4l2_debug(2,
"[%d]status=%x queue id=%d to rdy_queue",
ctx->id, free_frame_buffer->status,
dstbuf->vb.vb2_buf.index);
v4l2_m2m_buf_queue(ctx->m2m_ctx, &dstbuf->vb);
vb->vb2_buf.index);
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
dstbuf->queued_in_vb2 = true;
} else {
/*
@ -219,14 +223,14 @@ static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
*/
mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d",
ctx->id, free_frame_buffer->status,
dstbuf->vb.vb2_buf.index,
vb->vb2_buf.index,
dstbuf->queued_in_vb2,
dstbuf->queued_in_v4l2);
}
dstbuf->used = false;
}
mutex_unlock(&ctx->lock);
return &dstbuf->vb.vb2_buf;
return &vb->vb2_buf;
}
static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
@ -365,8 +369,10 @@ static void mtk_vdec_worker(struct work_struct *work)
return;
}
src_buf_info = container_of(src_buf, struct mtk_video_dec_buf, vb);
dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf, vb);
src_buf_info = container_of(src_buf, struct mtk_video_dec_buf,
m2m_buf.vb);
dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf,
m2m_buf.vb);
pfb = &dst_buf_info->frame_buffer;
pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
@ -397,11 +403,11 @@ static void mtk_vdec_worker(struct work_struct *work)
vdec_if_decode(ctx, NULL, NULL, &res_chg);
clean_display_buffer(ctx);
vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 0, 0);
vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
vb2_set_plane_payload(&dst_buf_info->vb.vb2_buf, 1, 0);
vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
dst_buf->flags |= V4L2_BUF_FLAG_LAST;
v4l2_m2m_buf_done(&dst_buf_info->vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
clean_free_buffer(ctx);
v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
return;
@ -417,10 +423,8 @@ static void mtk_vdec_worker(struct work_struct *work)
}
mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
dst_buf_info->vb.vb2_buf.timestamp
= src_buf_info->vb.vb2_buf.timestamp;
dst_buf_info->vb.timecode
= src_buf_info->vb.timecode;
dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
dst_buf->timecode = src_buf->timecode;
mutex_lock(&ctx->lock);
dst_buf_info->used = true;
mutex_unlock(&ctx->lock);
@ -434,7 +438,7 @@ static void mtk_vdec_worker(struct work_struct *work)
ctx->id,
src_buf->vb2_buf.index,
buf.size,
src_buf_info->vb.vb2_buf.timestamp,
src_buf->vb2_buf.timestamp,
dst_buf->vb2_buf.index,
ret, res_chg);
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
@ -443,14 +447,14 @@ static void mtk_vdec_worker(struct work_struct *work)
src_buf_info->error = true;
mutex_unlock(&ctx->lock);
}
v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_ERROR);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
} else if (res_chg == false) {
/*
* we only return src buffer with VB2_BUF_STATE_DONE
* when decode success without resolution change
*/
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
v4l2_m2m_buf_done(&src_buf_info->vb, VB2_BUF_STATE_DONE);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
}
dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
@ -522,7 +526,8 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
return 0;
}
v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf->vb);
v4l2_m2m_buf_queue(ctx->m2m_ctx,
&ctx->empty_flush_buf->m2m_buf.vb);
v4l2_m2m_try_schedule(ctx->m2m_ctx);
break;
@ -1148,7 +1153,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
*/
if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
vb2_v4l2 = to_vb2_v4l2_buffer(vb);
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
m2m_buf.vb);
mutex_lock(&ctx->lock);
if (buf->used == false) {
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
@ -1175,7 +1181,7 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
mtk_v4l2_err("No src buffer");
return;
}
buf = container_of(src_buf, struct mtk_video_dec_buf, vb);
buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
if (buf->lastframe) {
/* This shouldn't happen. Just in case. */
mtk_v4l2_err("Invalid flush buffer.");
@ -1256,7 +1262,7 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
bool buf_error;
vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, vb);
buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
mutex_lock(&ctx->lock);
if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
buf->queued_in_v4l2 = false;
@ -1276,7 +1282,7 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
struct vb2_v4l2_buffer, vb2_buf);
struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
struct mtk_video_dec_buf, vb);
struct mtk_video_dec_buf, m2m_buf.vb);
if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
buf->used = false;
@ -1309,7 +1315,7 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
struct mtk_video_dec_buf *buf_info = container_of(
src_buf, struct mtk_video_dec_buf, vb);
src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
if (!buf_info->lastframe)
v4l2_m2m_buf_done(src_buf,
VB2_BUF_STATE_ERROR);

View File

@ -9,7 +9,7 @@
#define _MTK_VCODEC_DEC_H_
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mem2mem.h>
#define VCODEC_CAPABILITY_4K_DISABLED 0x10
#define VCODEC_DEC_4K_CODED_WIDTH 4096U
@ -33,7 +33,7 @@ struct vdec_fb {
/**
* struct mtk_video_dec_buf - Private data related to each VB2 buffer.
* @b: VB2 buffer
* @m2m_buf: M2M buffer
* @list: link list
* @used: Capture buffer contain decoded frame data and keep in
* codec data structure
@ -47,8 +47,7 @@ struct vdec_fb {
* Note : These status information help us track and debug buffer state
*/
struct mtk_video_dec_buf {
struct vb2_v4l2_buffer vb;
struct list_head list;
struct v4l2_m2m_buffer m2m_buf;
bool used;
bool queued_in_vb2;

View File

@ -137,7 +137,7 @@ static int fops_vcodec_open(struct file *file)
}
src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
ctx->empty_flush_buf->vb.vb2_buf.vb2_queue = src_vq;
ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq;
ctx->empty_flush_buf->lastframe = true;
mtk_vcodec_dec_set_default_params(ctx);

View File

@ -332,14 +332,12 @@ static int vidioc_try_fmt(struct v4l2_format *f,
pix_fmt_mp->num_planes = fmt->num_planes;
pix_fmt_mp->plane_fmt[0].sizeimage =
pix_fmt_mp->width * pix_fmt_mp->height +
((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
pix_fmt_mp->width * pix_fmt_mp->height;
pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
if (pix_fmt_mp->num_planes == 2) {
pix_fmt_mp->plane_fmt[1].sizeimage =
(pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
(ALIGN(pix_fmt_mp->width, 16) * 16);
(pix_fmt_mp->width * pix_fmt_mp->height) / 2;
pix_fmt_mp->plane_fmt[2].sizeimage = 0;
pix_fmt_mp->plane_fmt[1].bytesperline =
pix_fmt_mp->width;
@ -347,8 +345,7 @@ static int vidioc_try_fmt(struct v4l2_format *f,
} else if (pix_fmt_mp->num_planes == 3) {
pix_fmt_mp->plane_fmt[1].sizeimage =
pix_fmt_mp->plane_fmt[2].sizeimage =
(pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
(pix_fmt_mp->width * pix_fmt_mp->height) / 4;
pix_fmt_mp->plane_fmt[1].bytesperline =
pix_fmt_mp->plane_fmt[2].bytesperline =
pix_fmt_mp->width / 2;
@ -798,13 +795,14 @@ static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
struct mtk_video_enc_buf *mtk_buf =
container_of(vb2_v4l2, struct mtk_video_enc_buf, vb);
container_of(vb2_v4l2, struct mtk_video_enc_buf,
m2m_buf.vb);
if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
(ctx->param_change != MTK_ENCODE_PARAM_NONE)) {
mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
ctx->id,
mtk_buf->vb.vb2_buf.index,
vb2_v4l2->vb2_buf.index,
ctx->param_change);
mtk_buf->param_change = ctx->param_change;
mtk_buf->enc_params = ctx->enc_params;
@ -986,7 +984,8 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
struct venc_enc_param enc_prm;
struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
struct mtk_video_enc_buf *mtk_buf =
container_of(vb2_v4l2, struct mtk_video_enc_buf, vb);
container_of(vb2_v4l2, struct mtk_video_enc_buf,
m2m_buf.vb);
int ret = 0;
@ -998,7 +997,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
enc_prm.bitrate = mtk_buf->enc_params.bitrate;
mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
ctx->id,
mtk_buf->vb.vb2_buf.index,
vb2_v4l2->vb2_buf.index,
enc_prm.bitrate);
ret |= venc_if_set_param(ctx,
VENC_SET_PARAM_ADJUST_BITRATE,
@ -1009,7 +1008,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
mtk_buf->enc_params.framerate_denom;
mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
ctx->id,
mtk_buf->vb.vb2_buf.index,
vb2_v4l2->vb2_buf.index,
enc_prm.frm_rate);
ret |= venc_if_set_param(ctx,
VENC_SET_PARAM_ADJUST_FRAMERATE,
@ -1026,7 +1025,7 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) {
mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
ctx->id,
mtk_buf->vb.vb2_buf.index,
vb2_v4l2->vb2_buf.index,
mtk_buf->enc_params.force_intra);
if (mtk_buf->enc_params.force_intra)
ret |= venc_if_set_param(ctx,

View File

@ -9,7 +9,7 @@
#define _MTK_VCODEC_ENC_H_
#include <media/videobuf2-core.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-mem2mem.h>
#define MTK_VENC_IRQ_STATUS_SPS 0x1
#define MTK_VENC_IRQ_STATUS_PPS 0x2
@ -23,15 +23,15 @@
/**
* struct mtk_video_enc_buf - Private data related to each VB2 buffer.
* @vb: Pointer to related VB2 buffer.
* @m2m_buf: M2M buffer
* @list: list that buffer link to
* @param_change: Types of encode parameter change before encoding this
* buffer
* @enc_params: Encode parameters changed before encode this buffer
*/
struct mtk_video_enc_buf {
struct vb2_v4l2_buffer vb;
struct list_head list;
struct v4l2_m2m_buffer m2m_buf;
u32 param_change;
struct mtk_enc_params enc_params;
};

View File

@ -810,6 +810,10 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
ret = v4l2_subdev_call(subdev, video, s_stream, 0);
/* Stop at the first external sub-device. */
if (subdev->dev != isp->dev)
break;
if (subdev == &isp->isp_res.subdev)
ret |= isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
else if (subdev == &isp->isp_prev.subdev)
@ -837,10 +841,6 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
&subdev->entity);
failure = -ETIMEDOUT;
}
/* Stop at the first external sub-device. */
if (subdev->dev != isp->dev)
break;
}
return failure;

View File

@ -1607,6 +1607,11 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
return 0;
}
/* Don't restart CCDC if we're just about to stop streaming. */
if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
ccdc->stopping & CCDC_STOP_REQUEST)
return 0;
if (!ccdc_has_all_fields(ccdc))
return 1;
@ -1661,16 +1666,15 @@ static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
spin_unlock_irqrestore(&ccdc->lock, flags);
}
if (ccdc->output & CCDC_OUTPUT_MEMORY)
restart = ccdc_isr_buffer(ccdc);
spin_lock_irqsave(&ccdc->lock, flags);
if (ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
spin_unlock_irqrestore(&ccdc->lock, flags);
return;
}
if (ccdc->output & CCDC_OUTPUT_MEMORY)
restart = ccdc_isr_buffer(ccdc);
if (!ccdc->shadow_update)
ccdc_apply_controls(ccdc);
spin_unlock_irqrestore(&ccdc->lock, flags);

View File

@ -2530,6 +2530,7 @@ exit_free_v4l2dev:
v4l2_device_unregister(&pcdev->v4l2_dev);
exit_deactivate:
pxa_camera_deactivate(pcdev);
tasklet_kill(&pcdev->task_eof);
exit_free_dma:
dma_release_channel(pcdev->dma_chans[2]);
exit_free_dma_u:
@ -2544,6 +2545,7 @@ static int pxa_camera_remove(struct platform_device *pdev)
struct pxa_camera_dev *pcdev = dev_get_drvdata(&pdev->dev);
pxa_camera_deactivate(pcdev);
tasklet_kill(&pcdev->task_eof);
dma_release_channel(pcdev->dma_chans[0]);
dma_release_channel(pcdev->dma_chans[1]);
dma_release_channel(pcdev->dma_chans[2]);

View File

@ -144,7 +144,7 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
}
/* HW limit width to a multiple of 32 (2^5) for NV12/16 else 2 (2^1) */
switch (vin->format.pixelformat) {
switch (pix->pixelformat) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV16:
walign = 5;

View File

@ -14,8 +14,8 @@
#define MAX_SRC_WIDTH 2048
/* Reset & boot poll config */
#define POLL_RST_MAX 50
#define POLL_RST_DELAY_MS 20
#define POLL_RST_MAX 500
#define POLL_RST_DELAY_MS 2
enum bdisp_target_plan {
BDISP_RGB,
@ -382,7 +382,7 @@ int bdisp_hw_reset(struct bdisp_dev *bdisp)
for (i = 0; i < POLL_RST_MAX; i++) {
if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE)
break;
msleep(POLL_RST_DELAY_MS);
udelay(POLL_RST_DELAY_MS * 1000);
}
if (i == POLL_RST_MAX)
dev_err(bdisp->dev, "Reset timeout\n");

View File

@ -1274,6 +1274,8 @@ static int bdisp_remove(struct platform_device *pdev)
if (!IS_ERR(bdisp->clock))
clk_unprepare(bdisp->clock);
destroy_workqueue(bdisp->work_queue);
dev_dbg(&pdev->dev, "%s driver unloaded\n", pdev->name);
return 0;
@ -1317,20 +1319,22 @@ static int bdisp_probe(struct platform_device *pdev)
bdisp->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(bdisp->regs)) {
dev_err(dev, "failed to get regs\n");
return PTR_ERR(bdisp->regs);
ret = PTR_ERR(bdisp->regs);
goto err_wq;
}
bdisp->clock = devm_clk_get(dev, BDISP_NAME);
if (IS_ERR(bdisp->clock)) {
dev_err(dev, "failed to get clock\n");
return PTR_ERR(bdisp->clock);
ret = PTR_ERR(bdisp->clock);
goto err_wq;
}
ret = clk_prepare(bdisp->clock);
if (ret < 0) {
dev_err(dev, "clock prepare failed\n");
bdisp->clock = ERR_PTR(-EINVAL);
return ret;
goto err_wq;
}
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -1402,7 +1406,8 @@ err_v4l2:
err_clk:
if (!IS_ERR(bdisp->clock))
clk_unprepare(bdisp->clock);
err_wq:
destroy_workqueue(bdisp->work_queue);
return ret;
}

View File

@ -170,8 +170,9 @@ int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
/* attach tuner */
request_module("tda18212");
client = i2c_new_device(tsin->i2c_adapter, &tda18212_info);
if (!client || !client->dev.driver) {
client = i2c_new_client_device(tsin->i2c_adapter,
&tda18212_info);
if (!i2c_client_has_driver(client)) {
dvb_frontend_detach(*fe);
return -ENODEV;
}

View File

@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@ -28,6 +29,12 @@
#include "sun4i_csi.h"
struct sun4i_csi_traits {
unsigned int channels;
unsigned int max_width;
bool has_isp;
};
static const struct media_entity_operations sun4i_csi_video_entity_ops = {
.link_validate = v4l2_subdev_link_validate,
};
@ -155,6 +162,31 @@ static int sun4i_csi_probe(struct platform_device *pdev)
subdev = &csi->subdev;
vdev = &csi->vdev;
csi->traits = of_device_get_match_data(&pdev->dev);
if (!csi->traits)
return -EINVAL;
/*
* On Allwinner SoCs, some high memory bandwidth devices do DMA
* directly over the memory bus (called MBUS), instead of the
* system bus. The memory bus has a different addressing scheme
* without the DRAM starting offset.
*
* In some cases this can be described by an interconnect in
* the device tree. In other cases where the hardware is not
* fully understood and the interconnect is left out of the
* device tree, fall back to a default offset.
*/
if (of_find_property(csi->dev->of_node, "interconnects", NULL)) {
ret = of_dma_configure(csi->dev, csi->dev->of_node, true);
if (ret)
return ret;
} else {
#ifdef PHYS_PFN_OFFSET
csi->dev->dma_pfn_offset = PHYS_PFN_OFFSET;
#endif
}
csi->mdev.dev = csi->dev;
strscpy(csi->mdev.model, "Allwinner Video Capture Device",
sizeof(csi->mdev.model));
@ -177,11 +209,13 @@ static int sun4i_csi_probe(struct platform_device *pdev)
return PTR_ERR(csi->bus_clk);
}
if (csi->traits->has_isp) {
csi->isp_clk = devm_clk_get(&pdev->dev, "isp");
if (IS_ERR(csi->isp_clk)) {
dev_err(&pdev->dev, "Couldn't get our ISP clock\n");
return PTR_ERR(csi->isp_clk);
}
}
csi->ram_clk = devm_clk_get(&pdev->dev, "ram");
if (IS_ERR(csi->ram_clk)) {
@ -258,8 +292,21 @@ static int sun4i_csi_remove(struct platform_device *pdev)
return 0;
}
static const struct sun4i_csi_traits sun4i_a10_csi1_traits = {
.channels = 1,
.max_width = 24,
.has_isp = false,
};
static const struct sun4i_csi_traits sun7i_a20_csi0_traits = {
.channels = 4,
.max_width = 16,
.has_isp = true,
};
static const struct of_device_id sun4i_csi_of_match[] = {
{ .compatible = "allwinner,sun7i-a20-csi0" },
{ .compatible = "allwinner,sun4i-a10-csi1", .data = &sun4i_a10_csi1_traits },
{ .compatible = "allwinner,sun7i-a20-csi0", .data = &sun7i_a20_csi0_traits },
{ /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, sun4i_csi_of_match);

Some files were not shown because too many files have changed in this diff Show More