提交 5d352e69 编写于 作者: L Linus Torvalds

Merge tag 'media/v4.15-1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - Documentation for digital TV (both kAPI and uAPI) are now in sync
   with the implementation (except for legacy/deprecated ioctls). This
   is a major step, as there were always a gap there

 - New sensor driver: imx274

 - New cec driver: cec-gpio

 - New platform driver for rockship rga and tegra CEC

 - New RC driver: tango-ir

 - Several cleanups at atomisp driver

 - Core improvements for RC, CEC, V4L2 async probing support and DVB

 - Lots of drivers cleanup, fixes and improvements.

* tag 'media/v4.15-1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (332 commits)
  dvb_frontend: don't use-after-free the frontend struct
  media: dib0700: fix invalid dvb_detach argument
  media: v4l2-ctrls: Don't validate BITMASK twice
  media: s5p-mfc: fix lockdep warning
  media: dvb-core: always call invoke_release() in fe_free()
  media: usb: dvb-usb-v2: dvb_usb_core: remove redundant code in dvb_usb_fe_sleep
  media: au0828: make const array addr_list static
  media: cx88: make const arrays default_addr_list and pvr2000_addr_list static
  media: drxd: make const array fastIncrDecLUT static
  media: usb: fix spelling mistake: "synchronuously" -> "synchronously"
  media: ddbridge: fix build warnings
  media: av7110: avoid 2038 overflow in debug print
  media: Don't do DMA on stack for firmware upload in the AS102 driver
  media: v4l: async: fix unregister for implicitly registered sub-device notifiers
  media: v4l: async: fix return of unitialized variable ret
  media: imx274: fix missing return assignment from call to imx274_mode_regs
  media: camss-vfe: always initialize reg at vfe_set_xbar_cfg()
  media: atomisp: make function calls cleaner
  media: atomisp: get rid of storage_class.h
  media: atomisp: get rid of wrong stddef.h include
  ...
* HDMI CEC GPIO driver
The HDMI CEC GPIO module supports CEC implementations where the CEC line
is hooked up to a pull-up GPIO line and - optionally - the HPD line is
hooked up to another GPIO line.
Required properties:
- compatible: value must be "cec-gpio".
- cec-gpios: gpio that the CEC line is connected to. The line should be
tagged as open drain.
If the CEC line is associated with an HDMI receiver/transmitter, then the
following property is also required:
- hdmi-phandle - phandle to the HDMI controller, see also cec.txt.
If the CEC line is not associated with an HDMI receiver/transmitter, then
the following property is optional:
- hpd-gpios: gpio that the HPD line is connected to.
Example for the Raspberry Pi 3 where the CEC line is connected to
pin 26 aka BCM7 aka CE1 on the GPIO pin header and the HPD line is
connected to pin 11 aka BCM17:
#include <dt-bindings/gpio/gpio.h>
cec-gpio {
compatible = "cec-gpio";
cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
};
......@@ -3,8 +3,11 @@
G-Scaler is used for scaling and color space conversion on EXYNOS5 SoCs.
Required properties:
- compatible: should be "samsung,exynos5-gsc" (for Exynos 5250, 5420 and
5422 SoCs) or "samsung,exynos5433-gsc" (Exynos 5433)
- compatible: should be one of
"samsung,exynos5250-gsc"
"samsung,exynos5420-gsc"
"samsung,exynos5433-gsc"
"samsung,exynos5-gsc" (deprecated)
- reg: should contain G-Scaler physical address location and length.
- interrupts: should contain G-Scaler interrupt number
......@@ -15,7 +18,7 @@ Optional properties:
Example:
gsc_0: gsc@0x13e00000 {
compatible = "samsung,exynos5-gsc";
compatible = "samsung,exynos5250-gsc";
reg = <0x13e00000 0x1000>;
interrupts = <0 85 0>;
};
......
* Sony 1/2.5-Inch 8.51Mp CMOS Digital Image Sensor
The Sony imx274 is a 1/2.5-inch CMOS active pixel digital image sensor with
an active array size of 3864H x 2202V. It is programmable through I2C
interface. The I2C address is fixed to 0x1a as per sensor data sheet.
Image data is sent through MIPI CSI-2, which is configured as 4 lanes
at 1440 Mbps.
Required Properties:
- compatible: value should be "sony,imx274" for imx274 sensor
- reg: I2C bus address of the device
Optional Properties:
- reset-gpios: Sensor reset GPIO
The imx274 device node should contain one 'port' child node with
an 'endpoint' subnode. For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
sensor@1a {
compatible = "sony,imx274";
reg = <0x1a>;
#address-cells = <1>;
#size-cells = <0>;
reset-gpios = <&gpio_sensor 0 0>;
port {
sensor_out: endpoint {
remote-endpoint = <&csiss_in>;
};
};
};
......@@ -27,6 +27,8 @@ Optional properties
- nokia,nvm-size: The size of the NVM, in bytes. If the size is not given,
the NVM contents will not be read.
- reset-gpios: XSHUTDOWN GPIO
- flash-leds: See ../video-interfaces.txt
- lens-focus: See ../video-interfaces.txt
Endpoint node mandatory properties
......
device-tree bindings for rockchip 2D raster graphic acceleration controller (RGA)
RGA is a standalone 2D raster graphic acceleration unit. It accelerates 2D
graphics operations, such as point/line drawing, image scaling, rotation,
BitBLT, alpha blending and image blur/sharpness.
Required properties:
- compatible: value should be one of the following
"rockchip,rk3288-rga";
"rockchip,rk3399-rga";
- interrupts: RGA interrupt specifier.
- clocks: phandle to RGA sclk/hclk/aclk clocks
- clock-names: should be "aclk", "hclk" and "sclk"
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names: should be "core", "axi" and "ahb"
Example:
SoC-specific DT entry:
rga: rga@ff680000 {
compatible = "rockchip,rk3399-rga";
reg = <0xff680000 0x10000>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>, <&cru SCLK_RGA_CORE>;
clock-names = "aclk", "hclk", "sclk";
resets = <&cru SRST_RGA_CORE>, <&cru SRST_A_RGA>, <&cru SRST_H_RGA>;
reset-names = "core, "axi", "ahb";
};
Sigma Designs Tango IR NEC/RC-5/RC-6 decoder (SMP86xx and SMP87xx)
Required properties:
- compatible: "sigma,smp8642-ir"
- reg: address/size of NEC+RC5 area, address/size of RC6 area
- interrupts: spec for IR IRQ
- clocks: spec for IR clock (typically the crystal oscillator)
Optional properties:
- linux,rc-map-name: see Documentation/devicetree/bindings/media/rc.txt
Example:
ir@10518 {
compatible = "sigma,smp8642-ir";
reg = <0x10518 0x18>, <0x105e0 0x1c>;
interrupts = <21 IRQ_TYPE_EDGE_RISING>;
clocks = <&xtal>;
};
* Tegra HDMI CEC hardware
The HDMI CEC module is present in Tegra SoCs and its purpose is to
handle communication between HDMI connected devices over the CEC bus.
Required properties:
- compatible : value should be one of the following:
"nvidia,tegra114-cec"
"nvidia,tegra124-cec"
"nvidia,tegra210-cec"
- reg : Physical base address of the IP registers and length of memory
mapped region.
- interrupts : HDMI CEC interrupt number to the CPU.
- clocks : from common clock binding: handle to HDMI CEC clock.
- clock-names : from common clock binding: must contain "cec",
corresponding to the entry in the clocks property.
- hdmi-phandle : phandle to the HDMI controller, see also cec.txt.
Example:
cec@70015000 {
compatible = "nvidia,tegra124-cec";
reg = <0x0 0x70015000 0x0 0x00001000>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_CEC>;
clock-names = "cec";
};
......@@ -55,6 +55,15 @@ divided into two separate ITU-R BT.656 8-bit busses. In such case bus-width
and data-shift properties can be used to assign physical data lines to each
endpoint node (logical bus).
Documenting bindings for devices
--------------------------------
All required and optional bindings the device supports shall be explicitly
documented in device DT binding documentation. This also includes port and
endpoint nodes for the device, including unit-addresses and reg properties where
relevant.
Please also see Documentation/devicetree/bindings/graph.txt .
Required properties
-------------------
......@@ -67,6 +76,16 @@ are required in a relevant parent node:
identifier, should be 1.
- #size-cells : should be zero.
Optional properties
-------------------
- flash-leds: An array of phandles, each referring to a flash LED, a sub-node
of the LED driver device node.
- lens-focus: A phandle to the node of the focus lens controller.
Optional endpoint properties
----------------------------
......@@ -99,7 +118,10 @@ Optional endpoint properties
determines the logical lane number, while the value of an entry indicates
physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have
"data-lanes = <1 2>;", assuming the clock lane is on hardware lane 0.
This property is valid for serial busses only (e.g. MIPI CSI-2).
If the hardware does not support lane reordering, monotonically
incremented values shall be used from 0 or 1 onwards, depending on
whether or not there is also a clock lane. This property is valid for
serial busses only (e.g. MIPI CSI-2).
- clock-lanes: an array of physical clock lane indexes. Position of an entry
determines the logical lane number, while the value of an entry indicates
physical lane, e.g. for a MIPI CSI-2 bus we could have "clock-lanes = <0>;",
......
......@@ -24,8 +24,6 @@ ignore define CEC_VENDOR_ID_NONE
ignore define CEC_MODE_INITIATOR_MSK
ignore define CEC_MODE_FOLLOWER_MSK
ignore define CEC_EVENT_FL_INITIAL_STATE
# Part of CEC 2.0 spec - shouldn't be documented too?
ignore define CEC_LOG_ADDR_TV
ignore define CEC_LOG_ADDR_RECORD_1
......
......@@ -227,8 +227,8 @@ CEC_TX_STATUS_LOW_DRIVE:
retransmission.
CEC_TX_STATUS_ERROR:
some unspecified error occurred: this can be one of
the previous two if the hardware cannot differentiate or something
some unspecified error occurred: this can be one of ARB_LOST
or LOW_DRIVE if the hardware cannot differentiate or something
else entirely.
CEC_TX_STATUS_MAX_RETRIES:
......@@ -238,6 +238,9 @@ CEC_TX_STATUS_MAX_RETRIES:
doesn't have to make another attempt to transmit the message
since the hardware did that already.
The hardware must be able to differentiate between OK, NACK and 'something
else'.
The \*_cnt arguments are the number of error conditions that were seen.
This may be 0 if no information is available. Drivers that do not support
hardware retry can just set the counter corresponding to the transmit error
......
Digital TV Conditional Access kABI
----------------------------------
.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h
Digital TV Common functions
---------------------------
Math functions
~~~~~~~~~~~~~~
Provide some commonly-used math functions, usually required in order to
estimate signal strength and signal to noise measurements in dB.
.. kernel-doc:: drivers/media/dvb-core/dvb_math.h
DVB devices
~~~~~~~~~~~
Those functions are responsible for handling the DVB device nodes.
.. kernel-doc:: drivers/media/dvb-core/dvbdev.h
Digital TV Ring buffer
~~~~~~~~~~~~~~~~~~~~~~
Those routines implement ring buffers used to handle digital TV data and
copy it from/to userspace.
.. note::
1) For performance reasons read and write routines don't check buffer sizes
and/or number of bytes free/available. This has to be done before these
routines are called. For example:
.. code-block:: c
/* write @buflen: bytes */
free = dvb_ringbuffer_free(rbuf);
if (free >= buflen)
count = dvb_ringbuffer_write(rbuf, buffer, buflen);
else
/* do something */
/* read min. 1000, max. @bufsize: bytes */
avail = dvb_ringbuffer_avail(rbuf);
if (avail >= 1000)
count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
else
/* do something */
2) If there is exactly one reader and one writer, there is no need
to lock read or write operations.
Two or more readers must be locked against each other.
Flushing the buffer counts as a read operation.
Resetting the buffer counts as a read and write operation.
Two or more writers must be locked against each other.
.. kernel-doc:: drivers/media/dvb-core/dvb_ringbuffer.h
Digital TV Demux kABI
---------------------
Digital TV Demux
~~~~~~~~~~~~~~~~
The Kernel Digital TV Demux kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
demux layer. It is only of interest for Digital TV device driver writers.
The header file for this kABI is named ``demux.h`` and located in
``drivers/media/dvb-core``.
The demux kABI should be implemented for each demux in the system. It is
used to select the TS source of a demux and to manage the demux resources.
When the demux client allocates a resource via the demux kABI, it receives
a pointer to the kABI of that resource.
Each demux receives its TS input from a DVB front-end or from memory, as
set via this demux kABI. In a system with more than one front-end, the kABI
can be used to select one of the DVB front-ends as a TS source for a demux,
unless this is fixed in the HW platform.
The demux kABI only controls front-ends regarding to their connections with
demuxes; the kABI used to set the other front-end parameters, such as
tuning, are devined via the Digital TV Frontend kABI.
The functions that implement the abstract interface demux should be defined
static or module private and registered to the Demux core for external
access. It is not necessary to implement every function in the struct
:c:type:`dmx_demux`. For example, a demux interface might support Section filtering,
but not PES filtering. The kABI client is expected to check the value of any
function pointer before calling the function: the value of ``NULL`` means
that the function is not available.
Whenever the functions of the demux API modify shared data, the
possibilities of lost update and race condition problems should be
addressed, e.g. by protecting parts of code with mutexes.
Note that functions called from a bottom half context must not sleep.
Even a simple memory allocation without using ``GFP_ATOMIC`` can result in a
kernel thread being put to sleep if swapping is needed. For example, the
Linux Kernel calls the functions of a network device interface from a
bottom half context. Thus, if a demux kABI function is called from network
device code, the function must not sleep.
Demux Callback API
~~~~~~~~~~~~~~~~~~
This kernel-space API comprises the callback functions that deliver filtered
data to the demux client. Unlike the other DVB kABIs, these functions are
provided by the client and called from the demux code.
The function pointers of this abstract interface are not packed into a
structure as in the other demux APIs, because the callback functions are
registered and used independent of each other. As an example, it is possible
for the API client to provide several callback functions for receiving TS
packets and no callbacks for PES packets or sections.
The functions that implement the callback API need not be re-entrant: when
a demux driver calls one of these functions, the driver is not allowed to
call the function again before the original call returns. If a callback is
triggered by a hardware interrupt, it is recommended to use the Linux
bottom half mechanism or start a tasklet instead of making the callback
function call directly from a hardware interrupt.
This mechanism is implemented by :c:func:`dmx_ts_cb()` and :c:func:`dmx_section_cb()`
callbacks.
Digital TV Demux device registration functions and data structures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: drivers/media/dvb-core/dmxdev.h
High-level Digital TV demux interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: drivers/media/dvb-core/dvb_demux.h
Driver-internal low-level hardware specific driver demux interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: drivers/media/dvb-core/demux.h
Digital TV Frontend kABI
------------------------
Digital TV Frontend
~~~~~~~~~~~~~~~~~~~
The Digital TV Frontend kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
frontend layer. It is only of interest for Digital TV device driver writers.
The header file for this API is named ``dvb_frontend.h`` and located in
``drivers/media/dvb-core``.
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
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 ``drivers/media/dvb-core/dvb_frontend.c``.
A typical example of such struct in a driver ``foo`` is::
static struct dvb_frontend_ops foo_ops = {
.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
.info = {
.name = "foo DVB-T/T2/C driver",
.caps = 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 |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
FE_CAN_2G_MODULATION,
.frequency_min = 42000000, /* Hz */
.frequency_max = 1002000000, /* Hz */
.symbol_rate_min = 870000,
.symbol_rate_max = 11700000
},
.init = foo_init,
.sleep = foo_sleep,
.release = foo_release,
.set_frontend = foo_set_frontend,
.get_frontend = foo_get_frontend,
.read_status = foo_get_status_and_stats,
.tune = foo_tune,
.i2c_gate_ctrl = foo_i2c_gate_ctrl,
.get_frontend_algo = foo_get_algo,
};
A typical example of such struct in a driver ``bar`` meant to be used on
Satellite TV reception is::
static const struct dvb_frontend_ops bar_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2 },
.info = {
.name = "Bar DVB-S/S2 demodulator",
.frequency_min = 500000, /* KHz */
.frequency_max = 2500000, /* KHz */
.frequency_stepsize = 0,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
.symbol_rate_tolerance = 500,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK,
},
.init = bar_init,
.sleep = bar_sleep,
.release = bar_release,
.set_frontend = bar_set_frontend,
.get_frontend = bar_get_frontend,
.read_status = bar_get_status_and_stats,
.i2c_gate_ctrl = bar_i2c_gate_ctrl,
.get_frontend_algo = bar_get_algo,
.tune = bar_tune,
/* Satellite-specific */
.diseqc_send_master_cmd = bar_send_diseqc_msg,
.diseqc_send_burst = bar_send_burst,
.set_tone = bar_set_tone,
.set_voltage = bar_set_voltage,
};
.. note::
#) For satellite digital TV standards (DVB-S, DVB-S2, ISDB-S), the
frequencies are specified in kHz, while, for terrestrial and cable
standards, they're specified in Hz. Due to that, if the same frontend
supports both types, you'll need to have two separate
:c:type:`dvb_frontend_ops` structures, one for each standard.
#) The ``.i2c_gate_ctrl`` field is present only when the hardware has
allows controlling an I2C gate (either directly of via some GPIO pin),
in order to remove the tuner from the I2C bus after a channel is
tuned.
#) All new drivers should implement the
:ref:`DVBv5 statistics <dvbv5_stats>` via ``.read_status``.
Yet, there are a number of callbacks meant to get statistics for
signal strength, S/N and UCB. Those are there to provide backward
compatibility with legacy applications that don't support the DVBv5
API. Implementing those callbacks are optional. Those callbacks may be
removed in the future, after we have all existing drivers supporting
DVBv5 stats.
#) Other callbacks are required for satellite TV standards, in order to
control LNBf and DiSEqC: ``.diseqc_send_master_cmd``,
``.diseqc_send_burst``, ``.set_tone``, ``.set_voltage``.
.. |delta| unicode:: U+00394
The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is
responsible for tuning the device. It supports multiple algorithms to
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
The algorithm to be used is obtained via ``.get_frontend_algo``. If the driver
doesn't fill its field at struct :c:type:`dvb_frontend_ops`, it will default to
``DVBFE_ALGO_SW``, meaning that the dvb-core will do a zigzag when tuning,
e. g. it will try first to use the specified center frequency ``f``,
then, it will do ``f`` + |delta|, ``f`` - |delta|, ``f`` + 2 x |delta|,
``f`` - 2 x |delta| and so on.
If the hardware has internally a some sort of zigzag algorithm, you should
define a ``.get_frontend_algo`` function that would return ``DVBFE_ALGO_HW``.
.. note::
The core frontend support also supports
a third type (``DVBFE_ALGO_CUSTOM``), in order to allow the driver to
define its own hardware-assisted algorithm. Very few hardware need to
use it nowadays. Using ``DVBFE_ALGO_CUSTOM`` require to provide other
function callbacks at struct :c:type:`dvb_frontend_ops`.
Attaching frontend driver to the bridge driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Before using the Digital TV frontend core, the bridge driver should attach
the frontend demod, tuner and SEC devices and call
:c:func:`dvb_register_frontend()`,
in order to register the new frontend at the subsystem. At device
detach/removal, the bridge driver should call
:c:func:`dvb_unregister_frontend()` to
remove the frontend from the core and then :c:func:`dvb_frontend_detach()`
to free the memory allocated by the frontend drivers.
The drivers should also call :c:func:`dvb_frontend_suspend()` as part of
their handler for the :c:type:`device_driver`.\ ``suspend()``, and
:c:func:`dvb_frontend_resume()` as
part of their handler for :c:type:`device_driver`.\ ``resume()``.
A few other optional functions are provided to handle some special cases.
.. _dvbv5_stats:
Digital TV Frontend statistics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Introduction
^^^^^^^^^^^^
Digital TV frontends provide a range of
:ref:`statistics <frontend-stat-properties>` meant to help tuning the device
and measuring the quality of service.
For each statistics measurement, the driver should set the type of scale used,
or ``FE_SCALE_NOT_AVAILABLE`` if the statistics is not available on a given
time. Drivers should also provide the number of statistics for each type.
that's usually 1 for most video standards [#f2]_.
Drivers should initialize each statistic counters with length and
scale at its init code. For example, if the frontend provides signal
strength, it should have, on its init code::
struct dtv_frontend_properties *c = &state->fe.dtv_property_cache;
c->strength.len = 1;
c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
And, when the statistics got updated, set the scale::
c->strength.stat[0].scale = FE_SCALE_DECIBEL;
c->strength.stat[0].uvalue = strength;
.. [#f2] For ISDB-T, it may provide both a global statistics and a per-layer
set of statistics. On such cases, len should be equal to 4. The first
value corresponds to the global stat; the other ones to each layer, e. g.:
- c->cnr.stat[0] for global S/N carrier ratio,
- c->cnr.stat[1] for Layer A S/N carrier ratio,
- c->cnr.stat[2] for layer B S/N carrier ratio,
- c->cnr.stat[3] for layer C S/N carrier ratio.
.. note:: Please prefer to use ``FE_SCALE_DECIBEL`` instead of
``FE_SCALE_RELATIVE`` for signal strength and CNR measurements.
Groups of statistics
^^^^^^^^^^^^^^^^^^^^
There are several groups of statistics currently supported:
Signal strength (:ref:`DTV-STAT-SIGNAL-STRENGTH`)
- Measures the signal strength level at the analog part of the tuner or
demod.
- Typically obtained from the gain applied to the tuner and/or frontend
in order to detect the carrier. When no carrier is detected, the gain is
at the maximum value (so, strength is on its minimal).
- 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
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.
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.
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
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`).
On other devices, it requires inner FEC decoding,
as the frontend measures it indirectly from other parameters (e. g. after
``FE_HAS_VITERBI``, see :c:type:`fe_status`).
Having it available after inner FEC is more common.
Bit counts post-FEC (:ref:`DTV-STAT-POST-ERROR-BIT-COUNT` and :ref:`DTV-STAT-POST-TOTAL-BIT-COUNT`)
- Those counters measure the number of bits and bit errors errors after
the forward error correction (FEC) on the inner coding block
(after Viterbi, LDPC or other inner code).
- Due to its nature, those statistics depend on full coding lock
(e. g. after ``FE_HAS_SYNC`` or after ``FE_HAS_LOCK``,
see :c:type:`fe_status`).
Bit counts pre-FEC (:ref:`DTV-STAT-PRE-ERROR-BIT-COUNT` and :ref:`DTV-STAT-PRE-TOTAL-BIT-COUNT`)
- Those counters measure the number of bits and bit errors errors before
the forward error correction (FEC) on the inner coding block
(before Viterbi, LDPC or other inner code).
- Not all frontends provide this kind of statistics.
- Due to its nature, those statistics depend on inner coding lock (e. g.
after ``FE_HAS_VITERBI``, see :c:type:`fe_status`).
Block counts (:ref:`DTV-STAT-ERROR-BLOCK-COUNT` and :ref:`DTV-STAT-TOTAL-BLOCK-COUNT`)
- Those counters measure the number of blocks and block errors errors after
the forward error correction (FEC) on the inner coding block
(before Viterbi, LDPC or other inner code).
- Due to its nature, those statistics depend on full coding lock
(e. g. after ``FE_HAS_SYNC`` or after
``FE_HAS_LOCK``, see :c:type:`fe_status`).
.. note:: All counters should be monotonically increased as they're
collected from the hardware.
A typical example of the logic that handle status and statistics is::
static int foo_get_status_and_stats(struct dvb_frontend *fe)
{
struct foo_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int rc;
enum fe_status *status;
/* Both status and strength are always available */
rc = foo_read_status(fe, &status);
if (rc < 0)
return rc;
rc = foo_read_strength(fe);
if (rc < 0)
return rc;
/* Check if CNR is available */
if (!(fe->status & FE_HAS_CARRIER))
return 0;
rc = foo_read_cnr(fe);
if (rc < 0)
return rc;
/* Check if pre-BER stats are available */
if (!(fe->status & FE_HAS_VITERBI))
return 0;
rc = foo_get_pre_ber(fe);
if (rc < 0)
return rc;
/* Check if post-BER stats are available */
if (!(fe->status & FE_HAS_SYNC))
return 0;
rc = foo_get_post_ber(fe);
if (rc < 0)
return rc;
}
static const struct dvb_frontend_ops ops = {
/* ... */
.read_status = foo_get_status_and_stats,
};
Statistics collect
^^^^^^^^^^^^^^^^^^
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
counter reaches a certain value (usually programable), for example, on
every 1000 ms or after receiving 1,000,000 bits.
So, if you read the registers too soon, you'll end by reading the same
value as in the previous reading, causing the monotonic value to be
incremented too often.
Drivers should take the responsibility to avoid too often reads. That
can be done using two approaches:
if the driver have a bit that indicates when a collected data is ready
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Driver should check such bit before making the statistics available.
An example of such behavior can be found at this code snippet (adapted
from mb86a20s driver's logic)::
static int foo_get_pre_ber(struct dvb_frontend *fe)
{
struct foo_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int rc, bit_error;
/* Check if the BER measures are already available */
rc = foo_read_u8(state, 0x54);
if (rc < 0)
return rc;
if (!rc)
return 0;
/* Read Bit Error Count */
bit_error = foo_read_u32(state, 0x55);
if (bit_error < 0)
return bit_error;
/* Read Total Bit Count */
rc = foo_read_u32(state, 0x51);
if (rc < 0)
return rc;
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_error.stat[0].uvalue += bit_error;
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_count.stat[0].uvalue += rc;
return 0;
}
If the driver doesn't provide a statistics available check bit
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A few devices, however, may not provide a way to check if the stats are
available (or the way to check it is unknown). They may not even provide
a way to directly read the total number of bits or blocks.
On those devices, the driver need to ensure that it won't be reading from
the register too often and/or estimate the total number of bits/blocks.
On such drivers, a typical routine to get statistics would be like
(adapted from dib8000 driver's logic)::
struct foo_state {
/* ... */
unsigned long per_jiffies_stats;
}
static int foo_get_pre_ber(struct dvb_frontend *fe)
{
struct foo_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int rc, bit_error;
u64 bits;
/* Check if time for stats was elapsed */
if (!time_after(jiffies, state->per_jiffies_stats))
return 0;
/* Next stat should be collected in 1000 ms */
state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
/* Read Bit Error Count */
bit_error = foo_read_u32(state, 0x55);
if (bit_error < 0)
return bit_error;
/*
* On this particular frontend, there's no register that
* would provide the number of bits per 1000ms sample. So,
* some function would calculate it based on DTV properties
*/
bits = get_number_of_bits_per_1000ms(fe);
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_error.stat[0].uvalue += bit_error;
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
c->pre_bit_count.stat[0].uvalue += bits;
return 0;
}
Please notice that, on both cases, we're getting the statistics using the
:c:type:`dvb_frontend_ops` ``.read_status`` callback. The rationale is that
the frontend core will automatically call this function periodically
(usually, 3 times per second, when the frontend is locked).
That warrants that we won't miss to collect a counter and increment the
monotonic stats at the right time.
Digital TV Frontend functions and types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. kernel-doc:: drivers/media/dvb-core/dvb_frontend.h
Digital TV Network kABI
-----------------------
.. kernel-doc:: drivers/media/dvb-core/dvb_net.h
V4L2 async kAPI
^^^^^^^^^^^^^^^
.. kernel-doc:: include/media/v4l2-async.h
......@@ -19,6 +19,7 @@ Video4Linux devices
v4l2-mc
v4l2-mediabus
v4l2-mem2mem
v4l2-async
v4l2-fwnode
v4l2-rect
v4l2-tuner
......
......@@ -161,6 +161,24 @@ it is guaranteed that the state did change in between the two events.
- Generated if the CEC pin goes from a low voltage to a high voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set.
* .. _`CEC-EVENT-PIN-HPD-LOW`:
- ``CEC_EVENT_PIN_HPD_LOW``
- 5
- Generated if the HPD pin goes from a high voltage to a low voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the HPD pin can be read and
if the HPD is low, then an initial event will be generated for that
filehandle.
* .. _`CEC-EVENT-PIN-HPD-HIGH`:
- ``CEC_EVENT_PIN_HPD_HIGH``
- 6
- Generated if the HPD pin goes from a low voltage to a high voltage.
Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN``
capability set. When open() is called, the HPD pin can be read and
if the HPD is high, then an initial event will be generated for that
filehandle.
.. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}|
......@@ -172,9 +190,9 @@ it is guaranteed that the state did change in between the two events.
:stub-columns: 0
:widths: 3 1 8
* .. _`CEC-EVENT-FL-INITIAL-VALUE`:
* .. _`CEC-EVENT-FL-INITIAL-STATE`:
- ``CEC_EVENT_FL_INITIAL_VALUE``
- ``CEC_EVENT_FL_INITIAL_STATE``
- 1
- Set for the initial events that are generated when the device is
opened. See the table above for which events do this. This allows
......
......@@ -131,7 +131,7 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
- ``tx_status``
- The status bits of the transmitted message. See
:ref:`cec-tx-status` for the possible status values. It is 0 if
this messages was received, not transmitted.
this message was received, not transmitted.
* - __u8
- ``msg[16]``
- The message payload. For :ref:`ioctl CEC_TRANSMIT <CEC_TRANSMIT>` this is filled in by the
......@@ -168,7 +168,7 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
- ``tx_status``
- The status bits of the transmitted message. See
:ref:`cec-tx-status` for the possible status values. It is 0 if
this messages was received, not transmitted.
this message was received, not transmitted.
* - __u8
- ``tx_arb_lost_cnt``
- A counter of the number of transmit attempts that resulted in the
......@@ -256,9 +256,9 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV').
- ``CEC_TX_STATUS_ERROR``
- 0x10
- Some error occurred. This is used for any errors that do not fit
the previous two, either because the hardware could not tell which
error occurred, or because the hardware tested for other
conditions besides those two.
``CEC_TX_STATUS_ARB_LOST`` or ``CEC_TX_STATUS_LOW_DRIVE``, either because
the hardware could not tell which error occurred, or because the hardware
tested for other conditions besides those two.
* .. _`CEC-TX-STATUS-MAX-RETRIES`:
- ``CEC_TX_STATUS_MAX_RETRIES``
......
......@@ -6,377 +6,11 @@
Examples
********
In this section we would like to present some examples for using the Digital
TV API.
In the past, we used to have a set of examples here. However, those
examples got out of date and doesn't even compile nowadays.
.. note::
Also, nowadays, the best is to use the libdvbv5 DVB API nowadays,
with is fully documented.
This section is out of date, and the code below won't even
compile. Please refer to the
`libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__ for
updated/recommended examples.
.. _tuning:
Example: Tuning
===============
We will start with a generic tuning subroutine that uses the frontend
and SEC, as well as the demux devices. The example is given for QPSK
tuners, but can easily be adjusted for QAM.
.. code-block:: c
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/sec.h>
#include <sys/poll.h>
#define DMX "/dev/dvb/adapter0/demux1"
#define FRONT "/dev/dvb/adapter0/frontend1"
#define SEC "/dev/dvb/adapter0/sec1"
/* routine for checking if we have a signal and other status information*/
int FEReadStatus(int fd, fe_status_t *stat)
{
int ans;
if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
perror("FE READ STATUS: ");
return -1;
}
if (*stat & FE_HAS_POWER)
printf("FE HAS POWER\\n");
if (*stat & FE_HAS_SIGNAL)
printf("FE HAS SIGNAL\\n");
if (*stat & FE_SPECTRUM_INV)
printf("SPEKTRUM INV\\n");
return 0;
}
/* tune qpsk */
/* freq: frequency of transponder */
/* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */
/* diseqc: DiSEqC address of the used LNB */
/* pol: Polarisation */
/* srate: Symbol Rate */
/* fec. FEC */
/* lnb_lof1: local frequency of lower LNB band */
/* lnb_lof2: local frequency of upper LNB band */
/* lnb_slof: switch frequency of LNB */
int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
int diseqc, int pol, int srate, int fec, int lnb_lof1,
int lnb_lof2, int lnb_slof)
{
struct secCommand scmd;
struct secCmdSequence scmds;
struct dmx_pes_filter_params pesFilterParams;
FrontendParameters frp;
struct pollfd pfd[1];
FrontendEvent event;
int demux1, demux2, demux3, front;
frequency = (uint32_t) freq;
symbolrate = (uint32_t) srate;
if((front = open(FRONT,O_RDWR)) < 0){
perror("FRONTEND DEVICE: ");
return -1;
}
if((sec = open(SEC,O_RDWR)) < 0){
perror("SEC DEVICE: ");
return -1;
}
if (demux1 < 0){
if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux2 < 0){
if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux3 < 0){
if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (freq < lnb_slof) {
frp.Frequency = (freq - lnb_lof1);
scmds.continuousTone = SEC_TONE_OFF;
} else {
frp.Frequency = (freq - lnb_lof2);
scmds.continuousTone = SEC_TONE_ON;
}
frp.Inversion = INVERSION_AUTO;
if (pol) scmds.voltage = SEC_VOLTAGE_18;
else scmds.voltage = SEC_VOLTAGE_13;
scmd.type=0;
scmd.u.diseqc.addr=0x10;
scmd.u.diseqc.cmd=0x38;
scmd.u.diseqc.numParams=1;
scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) |
(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
scmds.miniCommand=SEC_MINI_NONE;
scmds.numCommands=1;
scmds.commands=&scmd;
if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
perror("SEC SEND: ");
return -1;
}
if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
perror("SEC SEND: ");
return -1;
}
frp.u.qpsk.SymbolRate = srate;
frp.u.qpsk.FEC_inner = fec;
if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){
perror("QPSK TUNE: ");
return -1;
}
pfd[0].fd = front;
pfd[0].events = POLLIN;
if (poll(pfd,1,3000)){
if (pfd[0].revents & POLLIN){
printf("Getting QPSK event\\n");
if ( ioctl(front, FE_GET_EVENT, &event)
== -EOVERFLOW){
perror("qpsk get event");
return -1;
}
printf("Received ");
switch(event.type){
case FE_UNEXPECTED_EV:
printf("unexpected event\\n");
return -1;
case FE_FAILURE_EV:
printf("failure event\\n");
return -1;
case FE_COMPLETION_EV:
printf("completion event\\n");
}
}
}
pesFilterParams.pid = vpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
perror("set_vpid");
return -1;
}
pesFilterParams.pid = apid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
perror("set_apid");
return -1;
}
pesFilterParams.pid = tpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_DECODER;
pesFilterParams.pes_type = DMX_PES_TELETEXT;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
perror("set_tpid");
return -1;
}
return has_signal(fds);
}
The program assumes that you are using a universal LNB and a standard
DiSEqC switch with up to 4 addresses. Of course, you could build in some
more checking if tuning was successful and maybe try to repeat the
tuning process. Depending on the external hardware, i.e. LNB and DiSEqC
switch, and weather conditions this may be necessary.
.. _the_dvr_device:
Example: The DVR device
========================
The following program code shows how to use the DVR device for
recording.
.. code-block:: c
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/video.h>
#include <sys/poll.h>
#define DVR "/dev/dvb/adapter0/dvr1"
#define AUDIO "/dev/dvb/adapter0/audio1"
#define VIDEO "/dev/dvb/adapter0/video1"
#define BUFFY (188*20)
#define MAX_LENGTH (1024*1024*5) /* record 5MB */
/* switch the demuxes to recording, assuming the transponder is tuned */
/* demux1, demux2: file descriptor of video and audio filters */
/* vpid, apid: PIDs of video and audio channels */
int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
{
struct dmx_pes_filter_params pesFilterParams;
if (demux1 < 0){
if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
if (demux2 < 0){
if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
< 0){
perror("DEMUX DEVICE: ");
return -1;
}
}
pesFilterParams.pid = vpid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TS_TAP;
pesFilterParams.pes_type = DMX_PES_VIDEO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
perror("DEMUX DEVICE");
return -1;
}
pesFilterParams.pid = apid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TS_TAP;
pesFilterParams.pes_type = DMX_PES_AUDIO;
pesFilterParams.flags = DMX_IMMEDIATE_START;
if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
perror("DEMUX DEVICE");
return -1;
}
return 0;
}
/* start recording MAX_LENGTH , assuming the transponder is tuned */
/* demux1, demux2: file descriptor of video and audio filters */
/* vpid, apid: PIDs of video and audio channels */
int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
{
int i;
int len;
int written;
uint8_t buf[BUFFY];
uint64_t length;
struct pollfd pfd[1];
int dvr, dvr_out;
/* open dvr device */
if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
perror("DVR DEVICE");
return -1;
}
/* switch video and audio demuxes to dvr */
printf ("Switching dvr on\\n");
i = switch_to_record(demux1, demux2, vpid, apid);
printf("finished: ");
printf("Recording %2.0f MB of test file in TS format\\n",
MAX_LENGTH/(1024.0*1024.0));
length = 0;
/* open output file */
if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
|O_TRUNC, S_IRUSR|S_IWUSR
|S_IRGRP|S_IWGRP|S_IROTH|
S_IWOTH)) < 0){
perror("Can't open file for dvr test");
return -1;
}
pfd[0].fd = dvr;
pfd[0].events = POLLIN;
/* poll for dvr data and write to file */
while (length < MAX_LENGTH ) {
if (poll(pfd,1,1)){
if (pfd[0].revents & POLLIN){
len = read(dvr, buf, BUFFY);
if (len < 0){
perror("recording");
return -1;
}
if (len > 0){
written = 0;
while (written < len)
written +=
write (dvr_out,
buf, len);
length += len;
printf("written %2.0f MB\\r",
length/1024./1024.);
}
}
}
}
return 0;
}
Please refer to the `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__
for updated/recommended examples.
......@@ -48,8 +48,11 @@ depends on the delivery system and on the device:
- This call requires read/write access to the device.
- At return, the values are updated to reflect the actual parameters
used.
.. note::
At return, the values aren't updated to reflect the actual
parameters used. If the actual parameters are needed, an explicit
call to ``FE_GET_PROPERTY`` is needed.
- ``FE_GET_PROPERTY:``
......
.. -*- coding: utf-8; mode: rst -*-
.. _dmx_types:
.. _net_types:
**************
Net Data Types
......
......@@ -1956,6 +1956,14 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
ARM/TEGRA HDMI CEC SUBSYSTEM SUPPORT
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-tegra@vger.kernel.org
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/tegra-cec/
F: Documentation/devicetree/bindings/media/tegra-cec.txt
ARM/TETON BGA MACHINE SUPPORT
M: "Mark F. Brown" <mark.brown314@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......@@ -3264,6 +3272,15 @@ F: include/uapi/linux/cec.h
F: include/uapi/linux/cec-funcs.h
F: Documentation/devicetree/bindings/media/cec.txt
CEC GPIO DRIVER
M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
W: http://linuxtv.org
S: Supported
F: drivers/media/platform/cec-gpio/
F: Documentation/devicetree/bindings/media/cec-gpio.txt
CELL BROADBAND ENGINE ARCHITECTURE
M: Arnd Bergmann <arnd@arndb.de>
L: linuxppc-dev@lists.ozlabs.org
......@@ -11572,6 +11589,13 @@ F: drivers/hid/hid-roccat*
F: include/linux/hid-roccat*
F: Documentation/ABI/*/sysfs-driver-hid-roccat*
ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
M: Jacob chen <jacob2.chen@rock-chips.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/media/platform/rockchip/rga/
F: Documentation/devicetree/bindings/media/rockchip-rga.txt
ROCKER DRIVER
M: Jiri Pirko <jiri@resnulli.us>
L: netdev@vger.kernel.org
......@@ -12721,6 +12745,13 @@ L: stable@vger.kernel.org
S: Supported
F: Documentation/process/stable-kernel-rules.rst
STAGING - ATOMISP DRIVER
M: Alan Cox <alan@linux.intel.com>
M: Sakari Ailus <sakari.ailus@linux.intel.com>
L: linux-media@vger.kernel.org
S: Maintained
F: drivers/staging/media/atomisp/
STAGING - COMEDI
M: Ian Abbott <abbotti@mev.co.uk>
M: H Hartley Sweeten <hsweeten@visionengravers.com>
......
......@@ -26,6 +26,7 @@
clocks = <&isp 0>;
clock-frequency = <9600000>;
nokia,nvm-size = <(16 * 64)>;
flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <199200000 210000000 499200000>;
......
......@@ -271,14 +271,14 @@
#size-cells = <0>;
reg = <0x30>;
compatible = "ams,as3645a";
flash@0 {
as3645a_flash: flash@0 {
reg = <0x0>;
flash-timeout-us = <150000>;
flash-max-microamp = <320000>;
led-max-microamp = <60000>;
ams,input-max-microamp = <1750000>;
};
indicator@1 {
as3645a_indicator: indicator@1 {
reg = <0x1>;
led-max-microamp = <10000>;
};
......
......@@ -60,6 +60,7 @@
clocks = <&isp 0>;
clock-frequency = <9600000>;
nokia,nvm-size = <(16 * 64)>;
flash-leds = <&as3645a_flash &as3645a_indicator>;
port {
smia_1_1: endpoint {
link-frequencies = /bits/ 64 <210000000 333600000 398400000>;
......
......@@ -86,7 +86,7 @@ void cec_queue_event_fh(struct cec_fh *fh,
const struct cec_event *new_ev, u64 ts)
{
static const u8 max_events[CEC_NUM_EVENTS] = {
1, 1, 64, 64,
1, 1, 64, 64, 8, 8,
};
struct cec_event_entry *entry;
unsigned int ev_idx = new_ev->event - 1;
......@@ -170,6 +170,22 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
}
EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event);
/* Notify userspace that the HPD pin changed state at the given time. */
void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts)
{
struct cec_event ev = {
.event = is_high ? CEC_EVENT_PIN_HPD_HIGH :
CEC_EVENT_PIN_HPD_LOW,
};
struct cec_fh *fh;
mutex_lock(&adap->devnode.lock);
list_for_each_entry(fh, &adap->devnode.fhs, list)
cec_queue_event_fh(fh, &ev, ktime_to_ns(ts));
mutex_unlock(&adap->devnode.lock);
}
EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event);
/*
* Queue a new message for this filehandle.
*
......
......@@ -32,6 +32,7 @@
#include <media/cec-pin.h>
#include "cec-priv.h"
#include "cec-pin-priv.h"
static inline struct cec_devnode *cec_devnode_data(struct file *filp)
{
......@@ -529,7 +530,7 @@ static int cec_open(struct inode *inode, struct file *filp)
* Initial events that are automatically sent when the cec device is
* opened.
*/
struct cec_event ev_state = {
struct cec_event ev = {
.event = CEC_EVENT_STATE_CHANGE,
.flags = CEC_EVENT_FL_INITIAL_STATE,
};
......@@ -569,9 +570,19 @@ static int cec_open(struct inode *inode, struct file *filp)
filp->private_data = fh;
/* Queue up initial state events */
ev_state.state_change.phys_addr = adap->phys_addr;
ev_state.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
cec_queue_event_fh(fh, &ev_state, 0);
ev.state_change.phys_addr = adap->phys_addr;
ev.state_change.log_addr_mask = adap->log_addrs.log_addr_mask;
cec_queue_event_fh(fh, &ev, 0);
#ifdef CONFIG_CEC_PIN
if (adap->pin && adap->pin->ops->read_hpd) {
err = adap->pin->ops->read_hpd(adap);
if (err >= 0) {
ev.event = err ? CEC_EVENT_PIN_HPD_HIGH :
CEC_EVENT_PIN_HPD_LOW;
cec_queue_event_fh(fh, &ev, 0);
}
}
#endif
list_add(&fh->list, &devnode->fhs);
mutex_unlock(&devnode->lock);
......
......@@ -112,10 +112,6 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
int minor;
int ret;
/* Initialization */
INIT_LIST_HEAD(&devnode->fhs);
mutex_init(&devnode->lock);
/* Part 1: Find a free minor number */
mutex_lock(&cec_devnode_lock);
minor = find_next_zero_bit(cec_devnode_nums, CEC_NUM_DEVICES, 0);
......@@ -242,6 +238,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
INIT_LIST_HEAD(&adap->wait_queue);
init_waitqueue_head(&adap->kthread_waitq);
/* adap->devnode initialization */
INIT_LIST_HEAD(&adap->devnode.fhs);
mutex_init(&adap->devnode.lock);
adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name);
if (IS_ERR(adap->kthread)) {
pr_err("cec-%s: kernel_thread() failed\n", name);
......@@ -277,7 +277,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
adap->rc->input_id.version = 1;
adap->rc->driver_name = CEC_NAME;
adap->rc->allowed_protocols = RC_PROTO_BIT_CEC;
adap->rc->enabled_protocols = RC_PROTO_BIT_CEC;
adap->rc->priv = adap;
adap->rc->map_name = RC_MAP_CEC;
adap->rc->timeout = MS_TO_NS(100);
......
/*
* cec-pin-priv.h - internal cec-pin header
*
* Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
*
* This program is free software; you may redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef LINUX_CEC_PIN_PRIV_H
#define LINUX_CEC_PIN_PRIV_H
#include <linux/types.h>
#include <linux/atomic.h>
#include <media/cec-pin.h>
enum cec_pin_state {
/* CEC is off */
CEC_ST_OFF,
/* CEC is idle, waiting for Rx or Tx */
CEC_ST_IDLE,
/* Tx states */
/* Pending Tx, waiting for Signal Free Time to expire */
CEC_ST_TX_WAIT,
/* Low-drive was detected, wait for bus to go high */
CEC_ST_TX_WAIT_FOR_HIGH,
/* Drive CEC low for the start bit */
CEC_ST_TX_START_BIT_LOW,
/* Drive CEC high for the start bit */
CEC_ST_TX_START_BIT_HIGH,
/* Drive CEC low for the 0 bit */
CEC_ST_TX_DATA_BIT_0_LOW,
/* Drive CEC high for the 0 bit */
CEC_ST_TX_DATA_BIT_0_HIGH,
/* Drive CEC low for the 1 bit */
CEC_ST_TX_DATA_BIT_1_LOW,
/* Drive CEC high for the 1 bit */
CEC_ST_TX_DATA_BIT_1_HIGH,
/*
* Wait for start of sample time to check for Ack bit or first
* four initiator bits to check for Arbitration Lost.
*/
CEC_ST_TX_DATA_BIT_1_HIGH_PRE_SAMPLE,
/* Wait for end of bit period after sampling */
CEC_ST_TX_DATA_BIT_1_HIGH_POST_SAMPLE,
/* Rx states */
/* Start bit low detected */
CEC_ST_RX_START_BIT_LOW,
/* Start bit high detected */
CEC_ST_RX_START_BIT_HIGH,
/* Wait for bit sample time */
CEC_ST_RX_DATA_SAMPLE,
/* Wait for earliest end of bit period after sampling */
CEC_ST_RX_DATA_POST_SAMPLE,
/* Wait for CEC to go high (i.e. end of bit period */
CEC_ST_RX_DATA_HIGH,
/* Drive CEC low to send 0 Ack bit */
CEC_ST_RX_ACK_LOW,
/* End of 0 Ack time, wait for earliest end of bit period */
CEC_ST_RX_ACK_LOW_POST,
/* Wait for CEC to go high (i.e. end of bit period */
CEC_ST_RX_ACK_HIGH_POST,
/* Wait for earliest end of bit period and end of message */
CEC_ST_RX_ACK_FINISH,
/* Start low drive */
CEC_ST_LOW_DRIVE,
/* Monitor pin using interrupts */
CEC_ST_RX_IRQ,
/* Total number of pin states */
CEC_PIN_STATES
};
#define CEC_NUM_PIN_EVENTS 128
#define CEC_PIN_IRQ_UNCHANGED 0
#define CEC_PIN_IRQ_DISABLE 1
#define CEC_PIN_IRQ_ENABLE 2
struct cec_pin {
struct cec_adapter *adap;
const struct cec_pin_ops *ops;
struct task_struct *kthread;
wait_queue_head_t kthread_waitq;
struct hrtimer timer;
ktime_t ts;
unsigned int wait_usecs;
u16 la_mask;
bool enabled;
bool monitor_all;
bool rx_eom;
bool enable_irq_failed;
enum cec_pin_state state;
struct cec_msg tx_msg;
u32 tx_bit;
bool tx_nacked;
u32 tx_signal_free_time;
struct cec_msg rx_msg;
u32 rx_bit;
struct cec_msg work_rx_msg;
u8 work_tx_status;
ktime_t work_tx_ts;
atomic_t work_irq_change;
atomic_t work_pin_events;
unsigned int work_pin_events_wr;
unsigned int work_pin_events_rd;
ktime_t work_pin_ts[CEC_NUM_PIN_EVENTS];
bool work_pin_is_high[CEC_NUM_PIN_EVENTS];
ktime_t timer_ts;
u32 timer_cnt;
u32 timer_100ms_overruns;
u32 timer_300ms_overruns;
u32 timer_max_overrun;
u32 timer_sum_overrun;
};
#endif
......@@ -20,6 +20,7 @@
#include <linux/sched/types.h>
#include <media/cec-pin.h>
#include "cec-pin-priv.h"
/* All timings are in microseconds */
......@@ -132,7 +133,7 @@ static void cec_pin_to_idle(struct cec_pin *pin)
pin->rx_msg.len = 0;
memset(pin->rx_msg.msg, 0, sizeof(pin->rx_msg.msg));
pin->state = CEC_ST_IDLE;
pin->ts = 0;
pin->ts = ns_to_ktime(0);
}
/*
......@@ -426,7 +427,7 @@ static void cec_pin_rx_states(struct cec_pin *pin, ktime_t ts)
v = cec_pin_read(pin);
if (v && pin->rx_eom) {
pin->work_rx_msg = pin->rx_msg;
pin->work_rx_msg.rx_ts = ts;
pin->work_rx_msg.rx_ts = ktime_to_ns(ts);
wake_up_interruptible(&pin->kthread_waitq);
pin->ts = ts;
pin->state = CEC_ST_RX_ACK_FINISH;
......@@ -457,7 +458,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
s32 delta;
ts = ktime_get();
if (pin->timer_ts) {
if (ktime_to_ns(pin->timer_ts)) {
delta = ktime_us_delta(ts, pin->timer_ts);
pin->timer_cnt++;
if (delta > 100 && pin->state != CEC_ST_IDLE) {
......@@ -481,17 +482,19 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
if (pin->wait_usecs > 150) {
pin->wait_usecs -= 100;
pin->timer_ts = ktime_add_us(ts, 100);
hrtimer_forward_now(timer, 100000);
hrtimer_forward_now(timer, ns_to_ktime(100000));
return HRTIMER_RESTART;
}
if (pin->wait_usecs > 100) {
pin->wait_usecs /= 2;
pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
hrtimer_forward_now(timer, pin->wait_usecs * 1000);
hrtimer_forward_now(timer,
ns_to_ktime(pin->wait_usecs * 1000));
return HRTIMER_RESTART;
}
pin->timer_ts = ktime_add_us(ts, pin->wait_usecs);
hrtimer_forward_now(timer, pin->wait_usecs * 1000);
hrtimer_forward_now(timer,
ns_to_ktime(pin->wait_usecs * 1000));
pin->wait_usecs = 0;
return HRTIMER_RESTART;
}
......@@ -531,7 +534,7 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
pin->state = CEC_ST_RX_START_BIT_LOW;
break;
}
if (pin->ts == 0)
if (ktime_to_ns(pin->ts) == 0)
pin->ts = ts;
if (pin->tx_msg.len) {
/*
......@@ -572,12 +575,13 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
if (!adap->monitor_pin_cnt || states[pin->state].usecs <= 150) {
pin->wait_usecs = 0;
pin->timer_ts = ktime_add_us(ts, states[pin->state].usecs);
hrtimer_forward_now(timer, states[pin->state].usecs * 1000);
hrtimer_forward_now(timer,
ns_to_ktime(states[pin->state].usecs * 1000));
return HRTIMER_RESTART;
}
pin->wait_usecs = states[pin->state].usecs - 100;
pin->timer_ts = ktime_add_us(ts, 100);
hrtimer_forward_now(timer, 100000);
hrtimer_forward_now(timer, ns_to_ktime(100000));
return HRTIMER_RESTART;
}
......@@ -596,7 +600,7 @@ static int cec_pin_thread_func(void *_adap)
if (pin->work_rx_msg.len) {
cec_received_msg_ts(adap, &pin->work_rx_msg,
pin->work_rx_msg.rx_ts);
ns_to_ktime(pin->work_rx_msg.rx_ts));
pin->work_rx_msg.len = 0;
}
if (pin->work_tx_status) {
......@@ -623,13 +627,15 @@ static int cec_pin_thread_func(void *_adap)
pin->ops->disable_irq(adap);
cec_pin_high(pin);
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
break;
case CEC_PIN_IRQ_ENABLE:
pin->enable_irq_failed = !pin->ops->enable_irq(adap);
if (pin->enable_irq_failed) {
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
}
break;
default:
......@@ -653,7 +659,7 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
cec_pin_read(pin);
cec_pin_to_idle(pin);
pin->tx_msg.len = 0;
pin->timer_ts = 0;
pin->timer_ts = ns_to_ktime(0);
atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED);
pin->kthread = kthread_run(cec_pin_thread_func, adap,
"cec-pin");
......@@ -661,7 +667,8 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable)
pr_err("cec-pin: kernel_thread() failed\n");
return PTR_ERR(pin->kthread);
}
hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
} else {
if (pin->ops->disable_irq)
pin->ops->disable_irq(adap);
......@@ -699,7 +706,8 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
pin->ops->disable_irq(adap);
cec_pin_high(pin);
cec_pin_to_idle(pin);
hrtimer_start(&pin->timer, 0, HRTIMER_MODE_REL);
hrtimer_start(&pin->timer, ns_to_ktime(0),
HRTIMER_MODE_REL);
}
return 0;
}
......@@ -789,7 +797,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops,
caps | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN,
CEC_MAX_LOG_ADDRS);
if (PTR_ERR_OR_ZERO(adap)) {
if (IS_ERR(adap)) {
kfree(pin);
return adap;
}
......
......@@ -74,11 +74,9 @@ int cypress_load_firmware(struct usb_device *udev,
struct hexline *hx;
int ret, pos = 0;
hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
if (!hx) {
dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
hx = kmalloc(sizeof(*hx), GFP_KERNEL);
if (!hx)
return -ENOMEM;
}
/* stop the CPU */
hx->data[0] = 1;
......
......@@ -163,9 +163,9 @@ void saa7146_buffer_next(struct saa7146_dev *dev,
}
}
void saa7146_buffer_timeout(unsigned long data)
void saa7146_buffer_timeout(struct timer_list *t)
{
struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
struct saa7146_dmaqueue *q = from_timer(q, t, timeout);
struct saa7146_dev *dev = q->dev;
unsigned long flags;
......@@ -559,7 +559,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
vbi->start[1] = 312;
vbi->count[1] = 16;
init_timer(&vv->vbi_read_timeout);
timer_setup(&vv->vbi_read_timeout, NULL, 0);
vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
......
......@@ -349,9 +349,10 @@ static void vbi_stop(struct saa7146_fh *fh, struct file *file)
spin_unlock_irqrestore(&dev->slock, flags);
}
static void vbi_read_timeout(unsigned long data)
static void vbi_read_timeout(struct timer_list *t)
{
struct file *file = (struct file*)data;
struct saa7146_vv *vv = from_timer(vv, t, vbi_read_timeout);
struct file *file = vv->vbi_read_timeout_file;
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
......@@ -366,8 +367,7 @@ static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
setup_timer(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout,
(unsigned long)(&vv->vbi_dmaq));
timer_setup(&vv->vbi_dmaq.timeout, saa7146_buffer_timeout, 0);
vv->vbi_dmaq.dev = dev;
init_waitqueue_head(&vv->vbi_wq);
......@@ -402,8 +402,8 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
sizeof(struct saa7146_buf),
file, &dev->v4l2_lock);
vv->vbi_read_timeout.function = vbi_read_timeout;
vv->vbi_read_timeout.data = (unsigned long)file;
vv->vbi_read_timeout.function = (TIMER_FUNC_TYPE)vbi_read_timeout;
vv->vbi_read_timeout_file = file;
/* initialize the brs */
if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
......@@ -489,7 +489,7 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff
return ret;
}
struct saa7146_use_ops saa7146_vbi_uops = {
const struct saa7146_use_ops saa7146_vbi_uops = {
.init = vbi_init,
.open = vbi_open,
.release = vbi_close,
......
......@@ -1201,8 +1201,7 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
{
INIT_LIST_HEAD(&vv->video_dmaq.queue);
setup_timer(&vv->video_dmaq.timeout, saa7146_buffer_timeout,
(unsigned long)(&vv->video_dmaq));
timer_setup(&vv->video_dmaq.timeout, saa7146_buffer_timeout, 0);
vv->video_dmaq.dev = dev;
/* set some default values */
......@@ -1303,7 +1302,7 @@ static ssize_t video_read(struct file *file, char __user *data, size_t count, lo
return ret;
}
struct saa7146_use_ops saa7146_video_uops = {
const struct saa7146_use_ops saa7146_video_uops = {
.init = video_init,
.open = video_open,
.release = video_close,
......
......@@ -447,7 +447,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
return entry;
}
}
entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (entry) {
entry->mode = default_mode;
strcpy(entry->devpath, devpath);
......@@ -536,9 +536,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
int rc = 0;
kmutex_lock(&g_smscore_deviceslock);
notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
GFP_KERNEL);
notifyee = kmalloc(sizeof(*notifyee), GFP_KERNEL);
if (notifyee) {
/* now notify callback about existing devices */
first = &g_smscore_devices;
......@@ -627,7 +625,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
{
struct smscore_buffer_t *cb;
cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
cb = kzalloc(sizeof(*cb), GFP_KERNEL);
if (!cb)
return NULL;
......@@ -655,7 +653,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
struct smscore_device_t *dev;
u8 *buffer;
dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
......@@ -751,7 +749,7 @@ static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size, struct completion *completion) {
int rc;
if (completion == NULL)
if (!completion)
return -EINVAL;
init_completion(completion);
......@@ -1153,8 +1151,8 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
}
pr_debug("Firmware name: %s\n", fw_filename);
if (loadfirmware_handler == NULL && !(coredev->device_flags
& SMS_DEVICE_FAMILY2))
if (!loadfirmware_handler &&
!(coredev->device_flags & SMS_DEVICE_FAMILY2))
return -EINVAL;
rc = request_firmware(&fw, fw_filename, coredev->device);
......@@ -1301,10 +1299,8 @@ static int smscore_init_device(struct smscore_device_t *coredev, int mode)
buffer = kmalloc(sizeof(struct sms_msg_data) +
SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
if (!buffer) {
pr_err("Could not allocate buffer for init device message.\n");
if (!buffer)
return -ENOMEM;
}
msg = (struct sms_msg_data *)SMS_ALIGN_ADDRESS(buffer);
SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
......@@ -1686,11 +1682,10 @@ static int smscore_validate_client(struct smscore_device_t *coredev,
pr_err("The msg ID already registered to another client.\n");
return -EEXIST;
}
listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
if (!listentry) {
pr_err("Can't allocate memory for client id.\n");
listentry = kzalloc(sizeof(*listentry), GFP_KERNEL);
if (!listentry)
return -ENOMEM;
}
listentry->id = id;
listentry->data_type = data_type;
list_add_locked(&listentry->entry, &client->idlist,
......@@ -1724,11 +1719,9 @@ int smscore_register_client(struct smscore_device_t *coredev,
return -EEXIST;
}
newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
if (!newclient) {
pr_err("Failed to allocate memory for client.\n");
newclient = kzalloc(sizeof(*newclient), GFP_KERNEL);
if (!newclient)
return -ENOMEM;
}
INIT_LIST_HEAD(&newclient->idlist);
newclient->coredev = coredev;
......@@ -1796,7 +1789,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer;
int rc;
if (client == NULL) {
if (!client) {
pr_err("Got NULL client\n");
return -EINVAL;
}
......@@ -1804,7 +1797,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
coredev = client->coredev;
/* check that no other channel with same id exists */
if (coredev == NULL) {
if (!coredev) {
pr_err("Got NULL coredev\n");
return -EINVAL;
}
......@@ -1961,7 +1954,7 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
if (pin_num > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
if (p_gpio_config == NULL)
if (!p_gpio_config)
return -EINVAL;
total_len = sizeof(struct sms_msg_hdr) + (sizeof(u32) * 6);
......
......@@ -238,6 +238,8 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
tpg->color_enc = TGP_COLOR_ENC_RGB;
break;
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_Y10:
case V4L2_PIX_FMT_Y12:
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
tpg->color_enc = TGP_COLOR_ENC_LUMA;
......@@ -352,6 +354,8 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
case V4L2_PIX_FMT_YUV444:
case V4L2_PIX_FMT_YUV555:
case V4L2_PIX_FMT_YUV565:
case V4L2_PIX_FMT_Y10:
case V4L2_PIX_FMT_Y12:
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y16_BE:
tpg->twopixelsize[0] = 2 * 2;
......@@ -1056,6 +1060,14 @@ static void gen_twopix(struct tpg_data *tpg,
case V4L2_PIX_FMT_GREY:
buf[0][offset] = r_y_h;
break;
case V4L2_PIX_FMT_Y10:
buf[0][offset] = (r_y_h << 2) & 0xff;
buf[0][offset+1] = r_y_h >> 6;
break;
case V4L2_PIX_FMT_Y12:
buf[0][offset] = (r_y_h << 4) & 0xff;
buf[0][offset+1] = r_y_h >> 4;
break;
case V4L2_PIX_FMT_Y16:
/*
* Ideally both bytes should be set to r_y_h, but then you won't
......
......@@ -329,9 +329,9 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
return 0;
}
static void dvb_dmxdev_filter_timeout(unsigned long data)
static void dvb_dmxdev_filter_timeout(struct timer_list *t)
{
struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data;
struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);
dmxdevfilter->buffer.error = -ETIMEDOUT;
spin_lock_irq(&dmxdevfilter->dev->lock);
......@@ -346,8 +346,6 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
del_timer(&dmxdevfilter->timer);
if (para->timeout) {
dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout;
dmxdevfilter->timer.data = (unsigned long)dmxdevfilter;
dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
add_timer(&dmxdevfilter->timer);
......@@ -754,7 +752,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
init_timer(&dmxdevfilter->timer);
timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);
dvbdev->users++;
......
......@@ -36,12 +36,33 @@
#include "demux.h"
#include "dvb_ringbuffer.h"
/**
* enum dmxdev_type - type of demux filter type.
*
* @DMXDEV_TYPE_NONE: no filter set.
* @DMXDEV_TYPE_SEC: section filter.
* @DMXDEV_TYPE_PES: Program Elementary Stream (PES) filter.
*/
enum dmxdev_type {
DMXDEV_TYPE_NONE,
DMXDEV_TYPE_SEC,
DMXDEV_TYPE_PES,
};
/**
* enum dmxdev_state - state machine for the dmxdev.
*
* @DMXDEV_STATE_FREE: indicates that the filter is freed.
* @DMXDEV_STATE_ALLOCATED: indicates that the filter was allocated
* to be used.
* @DMXDEV_STATE_SET: indicates that the filter parameters are set.
* @DMXDEV_STATE_GO: indicates that the filter is running.
* @DMXDEV_STATE_DONE: indicates that a packet was already filtered
* and the filter is now disabled.
* Set only if %DMX_ONESHOT. See
* &dmx_sct_filter_params.
* @DMXDEV_STATE_TIMEDOUT: Indicates a timeout condition.
*/
enum dmxdev_state {
DMXDEV_STATE_FREE,
DMXDEV_STATE_ALLOCATED,
......@@ -51,12 +72,49 @@ enum dmxdev_state {
DMXDEV_STATE_TIMEDOUT
};
/**
* struct dmxdev_feed - digital TV dmxdev feed
*
* @pid: Program ID to be filtered
* @ts: pointer to &struct dmx_ts_feed
* @next: &struct list_head pointing to the next feed.
*/
struct dmxdev_feed {
u16 pid;
struct dmx_ts_feed *ts;
struct list_head next;
};
/**
* struct dmxdev_filter - digital TV dmxdev filter
*
* @filter: a dmxdev filter. Currently used only for section filter:
* if the filter is Section, it contains a
* &struct dmx_section_filter @sec pointer.
* @feed: a dmxdev feed. Depending on the feed type, it can be:
* for TS feed: a &struct list_head @ts list of TS and PES
* feeds;
* for section feed: a &struct dmx_section_feed @sec pointer.
* @params: dmxdev filter parameters. Depending on the feed type, it
* can be:
* for section filter: a &struct dmx_sct_filter_params @sec
* embedded struct;
* for a TS filter: a &struct dmx_pes_filter_params @pes
* embedded struct.
* @type: type of the dmxdev filter, as defined by &enum dmxdev_type.
* @state: state of the dmxdev filter, as defined by &enum dmxdev_state.
* @dev: pointer to &struct dmxdev.
* @buffer: an embedded &struct dvb_ringbuffer buffer.
* @mutex: protects the access to &struct dmxdev_filter.
* @timer: &struct timer_list embedded timer, used to check for
* feed timeouts.
* Only for section filter.
* @todo: index for the @secheader.
* Only for section filter.
* @secheader: buffer cache to parse the section header.
* Only for section filter.
*/
struct dmxdev_filter {
union {
struct dmx_section_filter *sec;
......@@ -86,7 +144,23 @@ struct dmxdev_filter {
u8 secheader[3];
};
/**
* struct dmxdev - Describes a digital TV demux device.
*
* @dvbdev: pointer to &struct dvb_device associated with
* the demux device node.
* @dvr_dvbdev: pointer to &struct dvb_device associated with
* the dvr device node.
* @filter: pointer to &struct dmxdev_filter.
* @demux: pointer to &struct dmx_demux.
* @filternum: number of filters.
* @capabilities: demux capabilities as defined by &enum dmx_demux_caps.
* @exit: flag to indicate that the demux is being released.
* @dvr_orig_fe: pointer to &struct dmx_frontend.
* @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output.
* @mutex: protects the usage of this structure.
* @lock: protects access to &dmxdev->filter->data.
*/
struct dmxdev {
struct dvb_device *dvbdev;
struct dvb_device *dvr_dvbdev;
......@@ -108,8 +182,20 @@ struct dmxdev {
spinlock_t lock;
};
/**
* dvb_dmxdev_init - initializes a digital TV demux and registers both demux
* and DVR devices.
*
* @dmxdev: pointer to &struct dmxdev.
* @adap: pointer to &struct dvb_adapter.
*/
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *adap);
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
/**
* dvb_dmxdev_release - releases a digital TV demux and unregisters it.
*
* @dmxdev: pointer to &struct dmxdev.
*/
void dvb_dmxdev_release(struct dmxdev *dmxdev);
#endif /* _DMXDEV_H_ */
......@@ -223,10 +223,10 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
* when the second packet arrives.
*
* Fix:
* when demux is started, let feed->pusi_seen = 0 to
* when demux is started, let feed->pusi_seen = false to
* prevent initial feeding of garbage from the end of
* previous section. When you for the first time see PUSI=1
* then set feed->pusi_seen = 1
* then set feed->pusi_seen = true
*/
static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
const u8 *buf, u8 len)
......@@ -318,10 +318,10 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
*/
#endif
/*
* Discontinuity detected. Reset pusi_seen = 0 to
* Discontinuity detected. Reset pusi_seen to
* stop feeding of suspicious data until next PUSI=1 arrives
*/
feed->pusi_seen = 0;
feed->pusi_seen = false;
dvb_dmx_swfilter_section_new(feed);
}
......@@ -335,8 +335,8 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
dvb_dmx_swfilter_section_copy_dump(feed, before,
before_len);
/* before start of new section, set pusi_seen = 1 */
feed->pusi_seen = 1;
/* before start of new section, set pusi_seen */
feed->pusi_seen = true;
dvb_dmx_swfilter_section_new(feed);
dvb_dmx_swfilter_section_copy_dump(feed, after,
after_len);
......@@ -367,6 +367,7 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
else
feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts);
}
/* Used only on full-featured devices */
if (feed->ts_type & TS_DECODER)
if (feed->demux->write_to_decoder)
feed->demux->write_to_decoder(feed, buf, 188);
......@@ -898,14 +899,14 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed)
return;
do {
sf = &f->filter;
doneq = 0;
doneq = false;
for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) {
mode = sf->filter_mode[i];
mask = sf->filter_mask[i];
f->maskandmode[i] = mask & mode;
doneq |= f->maskandnotmode[i] = mask & ~mode;
}
f->doneq = doneq ? 1 : 0;
f->doneq = doneq ? true : false;
} while ((f = f->next));
}
......
......@@ -26,15 +26,33 @@
#include "demux.h"
#define DMX_TYPE_TS 0
#define DMX_TYPE_SEC 1
#define DMX_TYPE_PES 2
/**
* enum dvb_dmx_filter_type - type of demux feed.
*
* @DMX_TYPE_TS: feed is in TS mode.
* @DMX_TYPE_SEC: feed is in Section mode.
*/
enum dvb_dmx_filter_type {
DMX_TYPE_TS,
DMX_TYPE_SEC,
};
#define DMX_STATE_FREE 0
#define DMX_STATE_ALLOCATED 1
#define DMX_STATE_SET 2
#define DMX_STATE_READY 3
#define DMX_STATE_GO 4
/**
* enum dvb_dmx_state - state machine for a demux filter.
*
* @DMX_STATE_FREE: indicates that the filter is freed.
* @DMX_STATE_ALLOCATED: indicates that the filter was allocated
* to be used.
* @DMX_STATE_READY: indicates that the filter is ready
* to be used.
* @DMX_STATE_GO: indicates that the filter is running.
*/
enum dvb_dmx_state {
DMX_STATE_FREE,
DMX_STATE_ALLOCATED,
DMX_STATE_READY,
DMX_STATE_GO,
};
#define DVB_DEMUX_MASK_MAX 18
......@@ -42,24 +60,66 @@
#define SPEED_PKTS_INTERVAL 50000
/**
* struct dvb_demux_filter - Describes a DVB demux section filter.
*
* @filter: Section filter as defined by &struct dmx_section_filter.
* @maskandmode: logical ``and`` bit mask.
* @maskandnotmode: logical ``and not`` bit mask.
* @doneq: flag that indicates when a filter is ready.
* @next: pointer to the next section filter.
* @feed: &struct dvb_demux_feed pointer.
* @index: index of the used demux filter.
* @state: state of the filter as described by &enum dvb_dmx_state.
* @type: type of the filter as described
* by &enum dvb_dmx_filter_type.
*/
struct dvb_demux_filter {
struct dmx_section_filter filter;
u8 maskandmode[DMX_MAX_FILTER_SIZE];
u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
int doneq;
bool doneq;
struct dvb_demux_filter *next;
struct dvb_demux_feed *feed;
int index;
int state;
int type;
enum dvb_dmx_state state;
enum dvb_dmx_filter_type type;
/* private: used only by av7110 */
u16 hw_handle;
struct timer_list timer;
};
#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
/**
* struct dvb_demux_feed - describes a DVB field
*
* @feed: a digital TV feed. It can either be a TS or a section feed:
* if the feed is TS, it contains &struct dvb_ts_feed @ts;
* if the feed is section, it contains
* &struct dmx_section_feed @sec.
* @cb: digital TV callbacks. depending on the feed type, it can be:
* if the feed is TS, it contains a dmx_ts_cb() @ts callback;
* if the feed is section, it contains a dmx_section_cb() @sec
* callback.
*
* @demux: pointer to &struct dvb_demux.
* @priv: private data that can optionally be used by a DVB driver.
* @type: type of the filter, as defined by &enum dvb_dmx_filter_type.
* @state: state of the filter as defined by &enum dvb_dmx_state.
* @pid: PID to be filtered.
* @timeout: feed timeout.
* @filter: pointer to &struct dvb_demux_filter.
* @ts_type: type of TS, as defined by &enum ts_filter_type.
* @pes_type: type of PES, as defined by &enum dmx_ts_pes.
* @cc: MPEG-TS packet continuity counter
* @pusi_seen: if true, indicates that a discontinuity was detected.
* it is used to prevent feeding of garbage from previous section.
* @peslen: length of the PES (Packet Elementary Stream).
* @list_head: head for the list of digital TV demux feeds.
* @index: a unique index for each feed. Can be used as hardware
* pid filter index.
*/
struct dvb_demux_feed {
union {
struct dmx_ts_feed ts;
......@@ -73,25 +133,63 @@ struct dvb_demux_feed {
struct dvb_demux *demux;
void *priv;
int type;
int state;
enum dvb_dmx_filter_type type;
enum dvb_dmx_state state;
u16 pid;
ktime_t timeout;
struct dvb_demux_filter *filter;
int ts_type;
enum ts_filter_type ts_type;
enum dmx_ts_pes pes_type;
int cc;
int pusi_seen; /* prevents feeding of garbage from previous section */
bool pusi_seen;
u16 peslen;
struct list_head list_head;
unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
unsigned int index;
};
/**
* struct dvb_demux - represents a digital TV demux
* @dmx: embedded &struct dmx_demux with demux capabilities
* and callbacks.
* @priv: private data that can optionally be used by
* a DVB driver.
* @filternum: maximum amount of DVB filters.
* @feednum: maximum amount of DVB feeds.
* @start_feed: callback routine to be called in order to start
* a DVB feed.
* @stop_feed: callback routine to be called in order to stop
* a DVB feed.
* @write_to_decoder: callback routine to be called if the feed is TS and
* it is routed to an A/V decoder, when a new TS packet
* is received.
* Used only on av7110-av.c.
* @check_crc32: callback routine to check CRC. If not initialized,
* dvb_demux will use an internal one.
* @memcopy: callback routine to memcopy received data.
* If not initialized, dvb_demux will default to memcpy().
* @users: counter for the number of demux opened file descriptors.
* Currently, it is limited to 10 users.
* @filter: pointer to &struct dvb_demux_filter.
* @feed: pointer to &struct dvb_demux_feed.
* @frontend_list: &struct list_head with frontends used by the demux.
* @pesfilter: array of &struct dvb_demux_feed with the PES types
* that will be filtered.
* @pids: list of filtered program IDs.
* @feed_list: &struct list_head with feeds.
* @tsbuf: temporary buffer used internally to store TS packets.
* @tsbufp: temporary buffer index used internally.
* @mutex: pointer to &struct mutex used to protect feed set
* logic.
* @lock: pointer to &spinlock_t, used to protect buffer handling.
* @cnt_storage: buffer used for TS/TEI continuity check.
* @speed_last_time: &ktime_t used for TS speed check.
* @speed_pkts_cnt: packets count used for TS speed check.
*/
struct dvb_demux {
struct dmx_demux dmx;
void *priv;
......@@ -115,8 +213,6 @@ struct dvb_demux {
struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
u16 pids[DMX_PES_OTHER];
int playing;
int recording;
#define DMX_MAX_PID 0x2000
struct list_head feed_list;
......@@ -130,15 +226,119 @@ struct dvb_demux {
ktime_t speed_last_time; /* for TS speed check */
uint32_t speed_pkts_cnt; /* for TS speed check */
/* private: used only on av7110 */
int playing;
int recording;
};
int dvb_dmx_init(struct dvb_demux *dvbdemux);
void dvb_dmx_release(struct dvb_demux *dvbdemux);
void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
/**
* dvb_dmx_init - initialize a digital TV demux struct.
*
* @demux: &struct dvb_demux to be initialized.
*
* Before being able to register a digital TV demux struct, drivers
* should call this routine. On its typical usage, some fields should
* be initialized at the driver before calling it.
*
* A typical usecase is::
*
* dvb->demux.dmx.capabilities =
* DMX_TS_FILTERING | DMX_SECTION_FILTERING |
* DMX_MEMORY_BASED_FILTERING;
* dvb->demux.priv = dvb;
* dvb->demux.filternum = 256;
* dvb->demux.feednum = 256;
* dvb->demux.start_feed = driver_start_feed;
* dvb->demux.stop_feed = driver_stop_feed;
* ret = dvb_dmx_init(&dvb->demux);
* if (ret < 0)
* return ret;
*/
int dvb_dmx_init(struct dvb_demux *demux);
/**
* dvb_dmx_release - releases a digital TV demux internal buffers.
*
* @demux: &struct dvb_demux to be released.
*
* The DVB core internally allocates data at @demux. This routine
* releases those data. Please notice that the struct itelf is not
* released, as it can be embedded on other structs.
*/
void dvb_dmx_release(struct dvb_demux *demux);
/**
* dvb_dmx_swfilter_packets - use dvb software filter for a buffer with
* multiple MPEG-TS packets with 188 bytes each.
*
* @demux: pointer to &struct dvb_demux
* @buf: buffer with data to be filtered
* @count: number of MPEG-TS packets with size of 188.
*
* The routine will discard a DVB packet that don't start with 0x47.
*
* Use this routine if the DVB demux fills MPEG-TS buffers that are
* already aligned.
*
* NOTE: The @buf size should have size equal to ``count * 188``.
*/
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count);
/**
* dvb_dmx_swfilter - use dvb software filter for a buffer with
* multiple MPEG-TS packets with 188 bytes each.
*
* @demux: pointer to &struct dvb_demux
* @buf: buffer with data to be filtered
* @count: number of MPEG-TS packets with size of 188.
*
* If a DVB packet doesn't start with 0x47, it will seek for the first
* byte that starts with 0x47.
*
* Use this routine if the DVB demux fill buffers that may not start with
* a packet start mark (0x47).
*
* NOTE: The @buf size should have size equal to ``count * 188``.
*/
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
/**
* dvb_dmx_swfilter_204 - use dvb software filter for a buffer with
* multiple MPEG-TS packets with 204 bytes each.
*
* @demux: pointer to &struct dvb_demux
* @buf: buffer with data to be filtered
* @count: number of MPEG-TS packets with size of 204.
*
* If a DVB packet doesn't start with 0x47, it will seek for the first
* byte that starts with 0x47.
*
* Use this routine if the DVB demux fill buffers that may not start with
* a packet start mark (0x47).
*
* NOTE: The @buf size should have size equal to ``count * 204``.
*/
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
size_t count);
/**
* dvb_dmx_swfilter_raw - make the raw data available to userspace without
* filtering
*
* @demux: pointer to &struct dvb_demux
* @buf: buffer with data
* @count: number of packets to be passed. The actual size of each packet
* depends on the &dvb_demux->feed->cb.ts logic.
*
* Use it if the driver needs to deliver the raw payload to userspace without
* passing through the kernel demux. That is meant to support some
* delivery systems that aren't based on MPEG-TS.
*
* This function relies on &dvb_demux->feed->cb.ts to actually handle the
* buffer.
*/
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
size_t count);
......
......@@ -180,8 +180,8 @@ enum dvbfe_search {
/**
* struct dvb_tuner_ops - Tuner information and callbacks
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @release: callback function called when frontend is dettached.
* @info: embedded &struct dvb_tuner_info with tuner properties
* @release: callback function called when frontend is detached.
* drivers should free any allocated memory.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
......@@ -191,14 +191,14 @@ enum dvbfe_search {
* resuming from suspend.
* @set_params: callback function used to inform the tuner to tune
* into a digital TV channel. The properties to be used
* are stored at @dvb_frontend.dtv_property_cache;. The
* tuner demod can change the parameters to reflect the
* changes needed for the channel to be tuned, and
* are stored at &struct dvb_frontend.dtv_property_cache.
* The tuner demod can change the parameters to reflect
* the changes needed for the channel to be tuned, and
* update statistics. This is the recommended way to set
* the tuner parameters and should be used on newer
* drivers.
* @set_analog_params: callback function used to tune into an analog TV
* channel on hybrid tuners. It passes @analog_parameters;
* channel on hybrid tuners. It passes @analog_parameters
* to the driver.
* @set_config: callback function used to send some tuner-specific
* parameters.
......@@ -207,9 +207,9 @@ enum dvbfe_search {
* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband,
* should return 0.
* @get_status: returns the frontend lock status
* @get_rf_strength: returns the RF signal strengh. Used mostly to support
* @get_rf_strength: returns the RF signal strength. Used mostly to support
* analog TV and radio. Digital TV should report, instead,
* via DVBv5 API (@dvb_frontend.dtv_property_cache;).
* via DVBv5 API (&struct dvb_frontend.dtv_property_cache).
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @calc_regs: callback function used to pass register data settings
......@@ -217,7 +217,7 @@ enum dvbfe_search {
* @set_frequency: Set a new frequency. Shouldn't be used on newer drivers.
* @set_bandwidth: Set a new frequency. Shouldn't be used on newer drivers.
*
* NOTE: frequencies used on get_frequency and set_frequency are in Hz for
* NOTE: frequencies used on @get_frequency and @set_frequency are in Hz for
* terrestrial/cable or kHz for satellite.
*
*/
......@@ -283,14 +283,14 @@ struct analog_demod_info {
* @set_params: callback function used to inform the demod to set the
* demodulator parameters needed to decode an analog or
* radio channel. The properties are passed via
* struct @analog_params;.
* &struct analog_params.
* @has_signal: returns 0xffff if has signal, or 0 if it doesn't.
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @tuner_status: callback function that returns tuner status bits, e. g.
* TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO.
* %TUNER_STATUS_LOCKED and %TUNER_STATUS_STEREO.
* @standby: set the tuner to standby mode.
* @release: callback function called when frontend is dettached.
* @release: callback function called when frontend is detached.
* drivers should free any allocated memory.
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
......@@ -321,10 +321,10 @@ struct dtv_frontend_properties;
* struct dvb_frontend_ops - Demodulation information and callbacks for
* ditialt TV
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @info: embedded &struct dvb_tuner_info with tuner properties
* @delsys: Delivery systems supported by the frontend
* @detach: callback function called when frontend is detached.
* drivers should clean up, but not yet free the struct
* drivers should clean up, but not yet free the &struct
* dvb_frontend allocation.
* @release: callback function called when frontend is ready to be
* freed.
......@@ -338,57 +338,57 @@ struct dtv_frontend_properties;
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
* @tune: callback function used by demod drivers that use
* @DVBFE_ALGO_HW; to tune into a frequency.
* @DVBFE_ALGO_HW to tune into a frequency.
* @get_frontend_algo: returns the desired hardware algorithm.
* @set_frontend: callback function used to inform the demod to set the
* parameters for demodulating a digital TV channel.
* The properties to be used are stored at
* @dvb_frontend.dtv_property_cache;. The demod can change
* The properties to be used are stored at &struct
* dvb_frontend.dtv_property_cache. The demod can change
* the parameters to reflect the changes needed for the
* channel to be decoded, and update statistics.
* @get_tune_settings: callback function
* @get_frontend: callback function used to inform the parameters
* actuall in use. The properties to be used are stored at
* @dvb_frontend.dtv_property_cache; and update
* &struct dvb_frontend.dtv_property_cache and update
* statistics. Please notice that it should not return
* an error code if the statistics are not available
* because the demog is not locked.
* @read_status: returns the locking status of the frontend.
* @read_ber: legacy callback function to return the bit error rate.
* Newer drivers should provide such info via DVBv5 API,
* e. g. @set_frontend;/@get_frontend;, implementing this
* e. g. @set_frontend;/@get_frontend, implementing this
* callback only if DVBv3 API compatibility is wanted.
* @read_signal_strength: legacy callback function to return the signal
* strength. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_snr: legacy callback function to return the Signal/Noise
* rate. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_ucblocks: legacy callback function to return the Uncorrected Error
* Blocks. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @diseqc_reset_overload: callback function to implement the
* FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite)
* FE_DISEQC_RESET_OVERLOAD() ioctl (only Satellite)
* @diseqc_send_master_cmd: callback function to implement the
* FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite).
* FE_DISEQC_SEND_MASTER_CMD() ioctl (only Satellite).
* @diseqc_recv_slave_reply: callback function to implement the
* FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite)
* FE_DISEQC_RECV_SLAVE_REPLY() ioctl (only Satellite)
* @diseqc_send_burst: callback function to implement the
* FE_DISEQC_SEND_BURST ioctl (only Satellite).
* FE_DISEQC_SEND_BURST() ioctl (only Satellite).
* @set_tone: callback function to implement the
* FE_SET_TONE ioctl (only Satellite).
* FE_SET_TONE() ioctl (only Satellite).
* @set_voltage: callback function to implement the
* FE_SET_VOLTAGE ioctl (only Satellite).
* FE_SET_VOLTAGE() ioctl (only Satellite).
* @enable_high_lnb_voltage: callback function to implement the
* FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite).
* FE_ENABLE_HIGH_LNB_VOLTAGE() ioctl (only Satellite).
* @dishnetwork_send_legacy_command: callback function to implement the
* FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite).
* FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl (only Satellite).
* Drivers should not use this, except when the DVB
* core emulation fails to provide proper support (e.g.
* if @set_voltage takes more than 8ms to work), and
......@@ -399,15 +399,10 @@ struct dtv_frontend_properties;
* @ts_bus_ctrl: callback function used to take control of the TS bus.
* @set_lna: callback function to power on/off/auto the LNA.
* @search: callback function used on some custom algo search algos.
* @tuner_ops: pointer to struct dvb_tuner_ops
* @analog_ops: pointer to struct analog_demod_ops
* @set_property: callback function to allow the frontend to validade
* incoming properties. Should not be used on new drivers.
* @get_property: callback function to allow the frontend to override
* outcoming properties. Should not be used on new drivers.
* @tuner_ops: pointer to &struct dvb_tuner_ops
* @analog_ops: pointer to &struct analog_demod_ops
*/
struct dvb_frontend_ops {
struct dvb_frontend_info info;
u8 delsys[MAX_DELSYS];
......@@ -466,9 +461,6 @@ struct dvb_frontend_ops {
struct dvb_tuner_ops tuner_ops;
struct analog_demod_ops analog_ops;
int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
};
#ifdef __DVB_CORE__
......@@ -565,15 +557,15 @@ struct dtv_frontend_properties {
enum fe_sec_voltage voltage;
enum fe_sec_tone_mode sectone;
enum fe_spectral_inversion inversion;
enum fe_code_rate fec_inner;
enum fe_spectral_inversion inversion;
enum fe_code_rate fec_inner;
enum fe_transmit_mode transmission_mode;
u32 bandwidth_hz; /* 0 = AUTO */
enum fe_guard_interval guard_interval;
enum fe_hierarchy hierarchy;
enum fe_hierarchy hierarchy;
u32 symbol_rate;
enum fe_code_rate code_rate_HP;
enum fe_code_rate code_rate_LP;
enum fe_code_rate code_rate_HP;
enum fe_code_rate code_rate_LP;
enum fe_pilot pilot;
enum fe_rolloff rolloff;
......@@ -628,11 +620,6 @@ struct dtv_frontend_properties {
struct dtv_fe_stats post_bit_count;
struct dtv_fe_stats block_error;
struct dtv_fe_stats block_count;
/* private: */
/* Cache State */
u32 state;
};
#define DVB_FE_NO_EXIT 0
......@@ -643,16 +630,16 @@ struct dtv_frontend_properties {
/**
* struct dvb_frontend - Frontend structure to be used on drivers.
*
* @refcount: refcount to keep track of struct dvb_frontend
* @refcount: refcount to keep track of &struct dvb_frontend
* references
* @ops: embedded struct dvb_frontend_ops
* @dvb: pointer to struct dvb_adapter
* @ops: embedded &struct dvb_frontend_ops
* @dvb: pointer to &struct dvb_adapter
* @demodulator_priv: demod private data
* @tuner_priv: tuner private data
* @frontend_priv: frontend private data
* @sec_priv: SEC private data
* @analog_demod_priv: Analog demod private data
* @dtv_property_cache: embedded struct dtv_frontend_properties
* @dtv_property_cache: embedded &struct dtv_frontend_properties
* @callback: callback function used on some drivers to call
* either the tuner or the demodulator.
* @id: Frontend ID
......@@ -681,8 +668,8 @@ struct dvb_frontend {
/**
* dvb_register_frontend() - Registers a DVB frontend at the adapter
*
* @dvb: pointer to the dvb adapter
* @fe: pointer to the frontend struct
* @dvb: pointer to &struct dvb_adapter
* @fe: pointer to &struct dvb_frontend
*
* Allocate and initialize the private data needed by the frontend core to
* manage the frontend and calls dvb_register_device() to register a new
......@@ -695,7 +682,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
/**
* dvb_unregister_frontend() - Unregisters a DVB frontend
*
* @fe: pointer to the frontend struct
* @fe: pointer to &struct dvb_frontend
*
* Stops the frontend kthread, calls dvb_unregister_device() and frees the
* private frontend data allocated by dvb_register_frontend().
......@@ -709,14 +696,14 @@ int dvb_unregister_frontend(struct dvb_frontend *fe);
/**
* dvb_frontend_detach() - Detaches and frees frontend specific data
*
* @fe: pointer to the frontend struct
* @fe: pointer to &struct dvb_frontend
*
* This function should be called after dvb_unregister_frontend(). It
* calls the SEC, tuner and demod release functions:
* &dvb_frontend_ops.release_sec, &dvb_frontend_ops.tuner_ops.release,
* &dvb_frontend_ops.analog_ops.release and &dvb_frontend_ops.release.
*
* If the driver is compiled with CONFIG_MEDIA_ATTACH, it also decreases
* If the driver is compiled with %CONFIG_MEDIA_ATTACH, it also decreases
* the module reference count, needed to allow userspace to remove the
* previously used DVB frontend modules.
*/
......@@ -725,7 +712,7 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
/**
* dvb_frontend_suspend() - Suspends a Digital TV frontend
*
* @fe: pointer to the frontend struct
* @fe: pointer to &struct dvb_frontend
*
* This function prepares a Digital TV frontend to suspend.
*
......@@ -743,7 +730,7 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
/**
* dvb_frontend_resume() - Resumes a Digital TV frontend
*
* @fe: pointer to the frontend struct
* @fe: pointer to &struct dvb_frontend
*
* This function resumes the usual operation of the tuner after resume.
*
......@@ -764,7 +751,7 @@ int dvb_frontend_resume(struct dvb_frontend *fe);
/**
* dvb_frontend_reinitialise() - forces a reinitialisation at the frontend
*
* @fe: pointer to the frontend struct
* @fe: pointer to &struct dvb_frontend
*
* Calls &dvb_frontend_ops.init\(\) and &dvb_frontend_ops.tuner_ops.init\(\),
* and resets SEC tone and voltage (for Satellite systems).
......@@ -779,16 +766,16 @@ void dvb_frontend_reinitialise(struct dvb_frontend *fe);
* dvb_frontend_sleep_until() - Sleep for the amount of time given by
* add_usec parameter
*
* @waketime: pointer to a struct ktime_t
* @waketime: pointer to &struct ktime_t
* @add_usec: time to sleep, in microseconds
*
* This function is used to measure the time required for the
* %FE_DISHNETWORK_SEND_LEGACY_CMD ioctl to work. It needs to be as precise
* FE_DISHNETWORK_SEND_LEGACY_CMD() ioctl to work. It needs to be as precise
* as possible, as it affects the detection of the dish tone command at the
* satellite subsystem.
*
* Its used internally by the DVB frontend core, in order to emulate
* %FE_DISHNETWORK_SEND_LEGACY_CMD using the &dvb_frontend_ops.set_voltage\(\)
* FE_DISHNETWORK_SEND_LEGACY_CMD() using the &dvb_frontend_ops.set_voltage\(\)
* callback.
*
* NOTE: it should not be used at the drivers, as the emulation for the
......
......@@ -30,6 +30,22 @@
#ifdef CONFIG_DVB_NET
/**
* struct dvb_net - describes a DVB network interface
*
* @dvbdev: pointer to &struct dvb_device.
* @device: array of pointers to &struct net_device.
* @state: array of integers to each net device. A value
* different than zero means that the interface is
* in usage.
* @exit: flag to indicate when the device is being removed.
* @demux: pointer to &struct dmx_demux.
* @ioctl_mutex: protect access to this struct.
*
* Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
* devices.
*/
struct dvb_net {
struct dvb_device *dvbdev;
struct net_device *device[DVB_NET_DEVICES_MAX];
......@@ -39,8 +55,22 @@ struct dvb_net {
struct mutex ioctl_mutex;
};
void dvb_net_release(struct dvb_net *);
int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
/**
* dvb_net_init - nitializes a digital TV network device and registers it.
*
* @adap: pointer to &struct dvb_adapter.
* @dvbnet: pointer to &struct dvb_net.
* @dmxdemux: pointer to &struct dmx_demux.
*/
int dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet,
struct dmx_demux *dmxdemux);
/**
* dvb_net_release - releases a digital TV network device and unregisters it.
*
* @dvbnet: pointer to &struct dvb_net.
*/
void dvb_net_release(struct dvb_net *dvbnet);
#else
......
......@@ -51,8 +51,15 @@ static LIST_HEAD(dvb_adapter_list);
static DEFINE_MUTEX(dvbdev_register_lock);
static const char * const dnames[] = {
"video", "audio", "sec", "frontend", "demux", "dvr", "ca",
"net", "osd"
[DVB_DEVICE_VIDEO] = "video",
[DVB_DEVICE_AUDIO] = "audio",
[DVB_DEVICE_SEC] = "sec",
[DVB_DEVICE_FRONTEND] = "frontend",
[DVB_DEVICE_DEMUX] = "demux",
[DVB_DEVICE_DVR] = "dvr",
[DVB_DEVICE_CA] = "ca",
[DVB_DEVICE_NET] = "net",
[DVB_DEVICE_OSD] = "osd"
};
#ifdef CONFIG_DVB_DYNAMIC_MINORS
......@@ -60,7 +67,22 @@ static const char * const dnames[] = {
#define DVB_MAX_IDS MAX_DVB_MINORS
#else
#define DVB_MAX_IDS 4
#define nums2minor(num, type, id) ((num << 6) | (id << 4) | type)
static const u8 minor_type[] = {
[DVB_DEVICE_VIDEO] = 0,
[DVB_DEVICE_AUDIO] = 1,
[DVB_DEVICE_SEC] = 2,
[DVB_DEVICE_FRONTEND] = 3,
[DVB_DEVICE_DEMUX] = 4,
[DVB_DEVICE_DVR] = 5,
[DVB_DEVICE_CA] = 6,
[DVB_DEVICE_NET] = 7,
[DVB_DEVICE_OSD] = 8,
};
#define nums2minor(num, type, id) \
(((num) << 6) | ((id) << 4) | minor_type[type])
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
#endif
......@@ -426,8 +448,8 @@ static int dvb_register_media_device(struct dvb_device *dvbdev,
}
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
const struct dvb_device *template, void *priv, int type,
int demux_sink_pads)
const struct dvb_device *template, void *priv,
enum dvb_device_type type, int demux_sink_pads)
{
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
......
......@@ -35,15 +35,37 @@
#define DVB_UNSET (-1)
#define DVB_DEVICE_VIDEO 0
#define DVB_DEVICE_AUDIO 1
#define DVB_DEVICE_SEC 2
#define DVB_DEVICE_FRONTEND 3
#define DVB_DEVICE_DEMUX 4
#define DVB_DEVICE_DVR 5
#define DVB_DEVICE_CA 6
#define DVB_DEVICE_NET 7
#define DVB_DEVICE_OSD 8
/* List of DVB device types */
/**
* enum dvb_device_type - type of the Digital TV device
*
* @DVB_DEVICE_SEC: Digital TV standalone Common Interface (CI)
* @DVB_DEVICE_FRONTEND: Digital TV frontend.
* @DVB_DEVICE_DEMUX: Digital TV demux.
* @DVB_DEVICE_DVR: Digital TV digital video record (DVR).
* @DVB_DEVICE_CA: Digital TV Conditional Access (CA).
* @DVB_DEVICE_NET: Digital TV network.
*
* @DVB_DEVICE_VIDEO: Digital TV video decoder.
* Deprecated. Used only on av7110-av.
* @DVB_DEVICE_AUDIO: Digital TV audio decoder.
* Deprecated. Used only on av7110-av.
* @DVB_DEVICE_OSD: Digital TV On Screen Display (OSD).
* Deprecated. Used only on av7110.
*/
enum dvb_device_type {
DVB_DEVICE_SEC,
DVB_DEVICE_FRONTEND,
DVB_DEVICE_DEMUX,
DVB_DEVICE_DVR,
DVB_DEVICE_CA,
DVB_DEVICE_NET,
DVB_DEVICE_VIDEO,
DVB_DEVICE_AUDIO,
DVB_DEVICE_OSD,
};
#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
static short adapter_nr[] = \
......@@ -104,8 +126,7 @@ struct dvb_adapter {
* @list_head: List head with all DVB devices
* @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
* @type: type of the device, as defined by &enum dvb_device_type.
* @minor: devnode minor number. Major number is always DVB_MAJOR.
* @id: device ID number, inside the adapter
* @readers: Initialized by the caller. Each call to open() in Read Only mode
......@@ -135,7 +156,7 @@ struct dvb_device {
struct list_head list_head;
const struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
enum dvb_device_type type;
int minor;
u32 id;
......@@ -194,9 +215,7 @@ int dvb_unregister_adapter(struct dvb_adapter *adap);
* stored
* @template: Template used to create &pdvbdev;
* @priv: private data
* @type: type of the device: %DVB_DEVICE_SEC, %DVB_DEVICE_FRONTEND,
* %DVB_DEVICE_DEMUX, %DVB_DEVICE_DVR, %DVB_DEVICE_CA,
* %DVB_DEVICE_NET
* @type: type of the device, as defined by &enum dvb_device_type.
* @demux_sink_pads: Number of demux outputs, to be used to create the TS
* outputs via the Media Controller.
*/
......@@ -204,7 +223,7 @@ int dvb_register_device(struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
int type,
enum dvb_device_type type,
int demux_sink_pads);
/**
......@@ -242,7 +261,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
* dvb_create_media_graph - Creates media graph for the Digital TV part of the
* device.
*
* @adap: pointer to struct dvb_adapter
* @adap: pointer to &struct dvb_adapter
* @create_rf_connector: if true, it creates the RF connector too
*
* This function checks all DVB-related functions at the media controller
......@@ -255,12 +274,23 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
__must_check int dvb_create_media_graph(struct dvb_adapter *adap,
bool create_rf_connector);
/**
* dvb_register_media_controller - registers a media controller at DVB adapter
*
* @adap: pointer to &struct dvb_adapter
* @mdev: pointer to &struct media_device
*/
static inline void dvb_register_media_controller(struct dvb_adapter *adap,
struct media_device *mdev)
{
adap->mdev = mdev;
}
/**
* dvb_get_media_controller - gets the associated media controller
*
* @adap: pointer to &struct dvb_adapter
*/
static inline struct media_device
*dvb_get_media_controller(struct dvb_adapter *adap)
{
......@@ -277,20 +307,71 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
#define dvb_get_media_controller(a) NULL
#endif
int dvb_generic_open (struct inode *inode, struct file *file);
int dvb_generic_release (struct inode *inode, struct file *file);
long dvb_generic_ioctl (struct file *file,
unsigned int cmd, unsigned long arg);
/**
* dvb_generic_open - Digital TV open function, used by DVB devices
*
* @inode: pointer to &struct inode.
* @file: pointer to &struct file.
*
* Checks if a DVB devnode is still valid, and if the permissions are
* OK and increment negative use count.
*/
int dvb_generic_open(struct inode *inode, struct file *file);
/* we don't mess with video_usercopy() any more,
we simply define out own dvb_usercopy(), which will hopefully become
generic_usercopy() someday... */
/**
* dvb_generic_close - Digital TV close function, used by DVB devices
*
* @inode: pointer to &struct inode.
* @file: pointer to &struct file.
*
* Checks if a DVB devnode is still valid, and if the permissions are
* OK and decrement negative use count.
*/
int dvb_generic_release(struct inode *inode, struct file *file);
/**
* dvb_generic_ioctl - Digital TV close function, used by DVB devices
*
* @file: pointer to &struct file.
* @cmd: Ioctl name.
* @arg: Ioctl argument.
*
* Checks if a DVB devnode and struct dvbdev.kernel_ioctl is still valid.
* If so, calls dvb_usercopy().
*/
long dvb_generic_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
/**
* dvb_usercopy - copies data from/to userspace memory when an ioctl is
* issued.
*
* @file: Pointer to struct &file.
* @cmd: Ioctl name.
* @arg: Ioctl argument.
* @func: function that will actually handle the ioctl
*
* Ancillary function that uses ioctl direction and size to copy from
* userspace. Then, it calls @func, and, if needed, data is copied back
* to userspace.
*/
int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
/** generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH
/**
* dvb_attach - attaches a DVB frontend into the DVB core.
*
* @FUNCTION: function on a frontend module to be called.
* @ARGS...: @FUNCTION arguments.
*
* This ancillary function loads a frontend module in runtime and runs
* the @FUNCTION function there, with @ARGS.
* As it increments symbol usage cont, at unregister, dvb_detach()
* should be called.
*/
#define dvb_attach(FUNCTION, ARGS...) ({ \
void *__r = NULL; \
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
......@@ -304,6 +385,14 @@ int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
__r; \
})
/**
* dvb_detach - detaches a DVB frontend loaded via dvb_attach()
*
* @FUNC: attach function
*
* Decrements usage count for a function previously called via dvb_attach().
*/
#define dvb_detach(FUNC) symbol_put_addr(FUNC)
#else
......
......@@ -173,7 +173,7 @@ config DVB_STB6000
tristate "ST STB6000 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0299
......@@ -187,7 +187,7 @@ config DVB_STV6110
tristate "ST STV6110 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0900
......@@ -902,7 +902,7 @@ config DVB_HELENE
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
Say Y when you want to support this frontend.
comment "Tools to develop new frontends"
......
......@@ -455,11 +455,10 @@ struct dvb_frontend *as102_attach(const char *name,
struct as102_state *state;
struct dvb_frontend *fe;
state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
if (state == NULL) {
pr_err("%s: unable to allocate memory for state\n", __func__);
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
}
fe = &state->frontend;
fe->demodulator_priv = state;
state->ops = ops;
......
......@@ -552,13 +552,11 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
const struct cx24113_config *config, struct i2c_adapter *i2c)
{
/* allocate memory for the internal state */
struct cx24113_state *state =
kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
struct cx24113_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
int rc;
if (state == NULL) {
cx_err("Unable to kzalloc\n");
goto error;
}
if (!state)
return NULL;
/* setup the state */
state->config = config;
......
......@@ -221,16 +221,13 @@ static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
static int cx24116_writeregN(struct cx24116_state *state, int reg,
const u8 *data, u16 len)
{
int ret = -EREMOTEIO;
int ret;
struct i2c_msg msg;
u8 *buf;
buf = kmalloc(len + 1, GFP_KERNEL);
if (buf == NULL) {
printk("Unable to kmalloc\n");
ret = -ENOMEM;
goto error;
}
if (!buf)
return -ENOMEM;
*(buf) = reg;
memcpy(buf + 1, data, len);
......@@ -251,7 +248,6 @@ static int cx24116_writeregN(struct cx24116_state *state, int reg,
ret = -EREMOTEIO;
}
error:
kfree(buf);
return ret;
......@@ -1121,15 +1117,15 @@ static const struct dvb_frontend_ops cx24116_ops;
struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
struct i2c_adapter *i2c)
{
struct cx24116_state *state = NULL;
struct cx24116_state *state;
int ret;
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL)
goto error1;
return NULL;
state->config = config;
state->i2c = i2c;
......@@ -1138,8 +1134,9 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
ret = (cx24116_readreg(state, 0xFF) << 8) |
cx24116_readreg(state, 0xFE);
if (ret != 0x0501) {
kfree(state);
printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
goto error2;
return NULL;
}
/* create dvb_frontend */
......@@ -1147,9 +1144,6 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
error2: kfree(state);
error1: return NULL;
}
EXPORT_SYMBOL(cx24116_attach);
......
......@@ -328,7 +328,7 @@ static int WriteTable(struct drxd_state *state, u8 * pTable)
{
int status = 0;
if (pTable == NULL)
if (!pTable)
return 0;
while (!status) {
......@@ -640,7 +640,7 @@ static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
const u16 maxRur = 8;
static const u16 slowIncrDecLUT[] = {
3, 4, 4, 5, 6 };
const u16 fastIncrDecLUT[] = {
static const u16 fastIncrDecLUT[] = {
14, 15, 15, 16,
17, 18, 18, 19,
20, 21, 22, 23,
......@@ -909,9 +909,8 @@ static int load_firmware(struct drxd_state *state, const char *fw_name)
}
state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
if (state->microcode == NULL) {
if (!state->microcode) {
release_firmware(fw);
printk(KERN_ERR "drxd: firmware load failure: no memory\n");
return -ENOMEM;
}
......@@ -2630,7 +2629,7 @@ static int DRXD_init(struct drxd_state *state, const u8 *fw, u32 fw_size)
break;
/* Apply I2c address patch to B1 */
if (!state->type_A && state->m_HiI2cPatch != NULL) {
if (!state->type_A && state->m_HiI2cPatch) {
status = WriteTable(state, state->m_HiI2cPatch);
if (status < 0)
break;
......
......@@ -277,10 +277,8 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
u8 *buf;
buf = kmalloc(33, GFP_KERNEL);
if (buf == NULL) {
printk(KERN_ERR "Unable to kmalloc\n");
if (!buf)
return -ENOMEM;
}
*(buf) = reg;
......@@ -835,17 +833,15 @@ static const struct dvb_frontend_ops ds3000_ops;
struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
struct i2c_adapter *i2c)
{
struct ds3000_state *state = NULL;
struct ds3000_state *state;
int ret;
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
if (state == NULL) {
printk(KERN_ERR "Unable to kmalloc\n");
goto error2;
}
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
state->config = config;
state->i2c = i2c;
......@@ -854,8 +850,9 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
/* check if the demod is present */
ret = ds3000_readreg(state, 0x00) & 0xfe;
if (ret != 0xe0) {
kfree(state);
printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
goto error3;
return NULL;
}
printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
......@@ -873,11 +870,6 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
*/
ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF);
return &state->frontend;
error3:
kfree(state);
error2:
return NULL;
}
EXPORT_SYMBOL(ds3000_attach);
......
......@@ -1048,16 +1048,6 @@ static int lg216x_get_frontend(struct dvb_frontend *fe,
return ret;
}
static int lg216x_get_property(struct dvb_frontend *fe,
struct dtv_property *tvp)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
return (DTV_ATSCMH_FIC_VER == tvp->cmd) ?
lg216x_get_frontend(fe, c) : 0;
}
static int lg2160_set_frontend(struct dvb_frontend *fe)
{
struct lg216x_state *state = fe->demodulator_priv;
......@@ -1368,8 +1358,6 @@ static const struct dvb_frontend_ops lg2160_ops = {
.init = lg216x_init,
.sleep = lg216x_sleep,
#endif
.get_property = lg216x_get_property,
.set_frontend = lg2160_set_frontend,
.get_frontend = lg216x_get_frontend,
.get_tune_settings = lg216x_get_tune_settings,
......@@ -1396,8 +1384,6 @@ static const struct dvb_frontend_ops lg2161_ops = {
.init = lg216x_init,
.sleep = lg216x_sleep,
#endif
.get_property = lg216x_get_property,
.set_frontend = lg2160_set_frontend,
.get_frontend = lg216x_get_frontend,
.get_tune_settings = lg216x_get_tune_settings,
......
......@@ -19,6 +19,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <asm/div64.h>
#include <linux/kernel.h>
#include <linux/dvb/frontend.h>
#include "dvb_math.h"
#include "lgdt3306a.h"
......@@ -2072,7 +2073,7 @@ static const short regtab[] = {
0x30aa, /* MPEGLOCK */
};
#define numDumpRegs (sizeof(regtab)/sizeof(regtab[0]))
#define numDumpRegs (ARRAY_SIZE(regtab))
static u8 regval1[numDumpRegs] = {0, };
static u8 regval2[numDumpRegs] = {0, };
......
......@@ -2071,12 +2071,9 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
dev_dbg(&i2c->dev, "%s called.\n", __func__);
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
if (state == NULL) {
dev_err(&i2c->dev,
"%s: unable to allocate memory for state\n", __func__);
goto error;
}
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
return NULL;
/* setup the state */
state->config = config;
......@@ -2089,22 +2086,16 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
/* Check if it is a mb86a20s frontend */
rev = mb86a20s_readreg(state, 0);
if (rev == 0x13) {
dev_info(&i2c->dev,
"Detected a Fujitsu mb86a20s frontend\n");
} else {
if (rev != 0x13) {
kfree(state);
dev_dbg(&i2c->dev,
"Frontend revision %d is unknown - aborting.\n",
rev);
goto error;
return NULL;
}
dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n");
return &state->frontend;
error:
kfree(state);
return NULL;
}
EXPORT_SYMBOL(mb86a20s_attach);
......
......@@ -43,7 +43,7 @@
#define BYTE2(v) ((v >> 16) & 0xff)
#define BYTE3(v) ((v >> 24) & 0xff)
LIST_HEAD(mxllist);
static LIST_HEAD(mxllist);
struct mxl_base {
struct list_head mxllist;
......
......@@ -696,7 +696,6 @@ static int si2168_probe(struct i2c_client *client,
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
ret = -ENOMEM;
dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
......
......@@ -357,14 +357,14 @@ static int sp2_exit(struct i2c_client *client)
dev_dbg(&client->dev, "\n");
if (client == NULL)
if (!client)
return 0;
s = i2c_get_clientdata(client);
if (s == NULL)
if (!s)
return 0;
if (s->ca.data == NULL)
if (!s->ca.data)
return 0;
dvb_ca_en50221_release(&s->ca);
......@@ -381,10 +381,9 @@ static int sp2_probe(struct i2c_client *client,
dev_dbg(&client->dev, "\n");
s = kzalloc(sizeof(struct sp2), GFP_KERNEL);
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
ret = -ENOMEM;
dev_err(&client->dev, "kzalloc() failed\n");
goto err;
}
......
......@@ -447,12 +447,6 @@ static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
return 0;
}
static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
{
dprintk("%s(..)\n", __func__);
return 0;
}
static int stv0288_set_frontend(struct dvb_frontend *fe)
{
struct stv0288_state *state = fe->demodulator_priv;
......@@ -567,7 +561,6 @@ static const struct dvb_frontend_ops stv0288_ops = {
.set_tone = stv0288_set_tone,
.set_voltage = stv0288_set_voltage,
.set_property = stv0288_set_property,
.set_frontend = stv0288_set_frontend,
};
......
......@@ -258,11 +258,9 @@ static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct stv6110_priv *priv = fe->tuner_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u8 ret = 0x04;
u32 divider, ref, p, presc, i, result_freq, vco_freq;
s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
s32 srate;
dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
frequency, priv->mclk);
......@@ -273,13 +271,6 @@ static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
/* BB_GAIN = db/2 */
if (fe->ops.set_property && fe->ops.get_property) {
srate = c->symbol_rate;
dprintk("%s: Get Frontend parameters: srate=%d\n",
__func__, srate);
} else
srate = 15000000;
priv->regs[RSTV6110_CTRL2] &= ~0x0f;
priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
......
......@@ -354,6 +354,14 @@ config VIDEO_TC358743
To compile this driver as a module, choose M here: the
module will be called tc358743.
config VIDEO_TC358743_CEC
bool "Enable Toshiba TC358743 CEC support"
depends on VIDEO_TC358743
select CEC_CORE
---help---
When selected the tc358743 will support the optional
HDMI CEC feature.
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C
......@@ -547,6 +555,14 @@ config VIDEO_APTINA_PLL
config VIDEO_SMIAPP_PLL
tristate
config VIDEO_IMX274
tristate "Sony IMX274 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
depends on MEDIA_CAMERA_SUPPORT
---help---
This is a V4L2 sensor-level driver for the Sony IMX274
CMOS image sensor.
config VIDEO_OV2640
tristate "OmniVision OV2640 sensor support"
depends on VIDEO_V4L2 && I2C
......
......@@ -93,5 +93,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
obj-$(CONFIG_VIDEO_IMX274) += imx274.o
obj-$(CONFIG_SDR_MAX2175) += max2175.o
......@@ -1328,7 +1328,7 @@ static int adv7180_probe(struct i2c_client *client,
state->input = 0;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
ret = adv7180_init_controls(state);
if (ret)
......
......@@ -217,6 +217,7 @@ static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct adv748x_afe *afe = adv748x_sd_to_afe(sd);
struct adv748x_state *state = adv748x_afe_to_state(afe);
int afe_std;
int ret;
mutex_lock(&state->mutex);
......@@ -235,8 +236,12 @@ static int adv748x_afe_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
/* Read detected standard */
ret = adv748x_afe_status(afe, NULL, std);
afe_std = adv748x_afe_std(afe->curr_norm);
if (afe_std < 0)
goto unlock;
/* Restore original state */
adv748x_afe_set_video_standard(state, afe->curr_norm);
adv748x_afe_set_video_standard(state, afe_std);
unlock:
mutex_unlock(&state->mutex);
......
......@@ -1948,7 +1948,7 @@ static int adv76xx_set_format(struct v4l2_subdev *sd,
return -EINVAL;
info = adv76xx_format_info(state, format->format.code);
if (info == NULL)
if (!info)
info = adv76xx_format_info(state, MEDIA_BUS_FMT_YUYV8_2X8);
adv76xx_fill_format(state, &format->format);
......@@ -2256,7 +2256,7 @@ static int adv76xx_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return 0;
}
if (data == NULL)
if (!data)
return -ENODATA;
if (edid->start_block >= state->edid.blocks)
......@@ -3316,10 +3316,8 @@ static int adv76xx_probe(struct i2c_client *client,
client->addr << 1);
state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state) {
v4l_err(client, "Could not allocate adv76xx_state memory!\n");
if (!state)
return -ENOMEM;
}
state->i2c_clients[ADV76XX_PAGE_IO] = client;
......@@ -3482,7 +3480,7 @@ static int adv76xx_probe(struct i2c_client *client,
state->i2c_clients[i] =
adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i],
0xf2 + i);
if (state->i2c_clients[i] == NULL) {
if (!state->i2c_clients[i]) {
err = -ENOMEM;
v4l2_err(sd, "failed to create i2c client %u\n", i);
goto err_i2c;
......
......@@ -3467,11 +3467,9 @@ static int adv7842_probe(struct i2c_client *client,
return -ENODEV;
}
state = devm_kzalloc(&client->dev, sizeof(struct adv7842_state), GFP_KERNEL);
if (!state) {
v4l_err(client, "Could not allocate adv7842_state memory!\n");
state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state)
return -ENOMEM;
}
/* platform data */
state->pdata = *pdata;
......
......@@ -1745,7 +1745,7 @@ static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
v4l2_std_id stds[] = {
static const v4l2_std_id stds[] = {
/* 0000 */ V4L2_STD_UNKNOWN,
/* 0001 */ V4L2_STD_NTSC_M,
......
......@@ -20,6 +20,11 @@
#define DW9714_NAME "dw9714"
#define DW9714_MAX_FOCUS_POS 1023
/*
* This sets the minimum granularity for the focus positions.
* A value of 1 gives maximum accuracy for a desired focus position
*/
#define DW9714_FOCUS_STEPS 1
/*
* This acts as the minimum granularity of lens movement.
* Keep this value power of 2, so the control steps can be
......@@ -137,7 +142,7 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
v4l2_ctrl_handler_init(hdl, 1);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
0, DW9714_MAX_FOCUS_POS, DW9714_CTRL_STEPS, 0);
0, DW9714_MAX_FOCUS_POS, DW9714_FOCUS_STEPS, 0);
if (hdl->error)
dev_err(&client->dev, "%s fail error: 0x%x\n",
......
......@@ -1453,7 +1453,7 @@ static int et8ek8_probe(struct i2c_client *client,
goto err_mutex;
}
ret = v4l2_async_register_subdev(&sensor->subdev);
ret = v4l2_async_register_subdev_sensor_common(&sensor->subdev);
if (ret < 0)
goto err_entity;
......
此差异已折叠。
......@@ -460,7 +460,6 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
rc->map_name = ir->ir_codes;
rc->allowed_protocols = rc_proto;
rc->enabled_protocols = rc_proto;
if (!rc->driver_name)
rc->driver_name = MODULE_NAME;
......
......@@ -1345,7 +1345,7 @@ static int max2175_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &max2175_ops);
ctx->client = client;
sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
/* Controls */
hdl = &ctx->ctrl_hdl;
......
......@@ -945,7 +945,7 @@ static int mt9m111_probe(struct i2c_client *client,
mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
if (IS_ERR(mt9m111->clk))
return -EPROBE_DEFER;
return PTR_ERR(mt9m111->clk);
/* Default HIGHPOWER context */
mt9m111->ctx = &context_b;
......
此差异已折叠。
此差异已折叠。
......@@ -2271,7 +2271,7 @@ static int ov5640_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&sensor->sd, client, &ov5640_subdev_ops);
sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
......
此差异已折叠。
此差异已折叠。
......@@ -951,11 +951,8 @@ static int ov6650_probe(struct i2c_client *client,
int ret;
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(&client->dev,
"Failed to allocate memory for private data!\n");
if (!priv)
return -ENOMEM;
}
v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
v4l2_ctrl_handler_init(&priv->hdl, 13);
......
此差异已折叠。
......@@ -985,7 +985,6 @@ static const struct v4l2_ctrl_ops ov965x_ctrl_ops = {
static const char * const test_pattern_menu[] = {
"Disabled",
"Color bars",
NULL
};
static int ov965x_initialize_controls(struct ov965x *ov965x)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册