diff options
author | Linus Torvalds | 2017-11-15 20:30:12 -0800 |
---|---|---|
committer | Linus Torvalds | 2017-11-15 20:30:12 -0800 |
commit | 5d352e69c60e54b5f04d6e337a1d2bf0dbf3d94a (patch) | |
tree | 214e6b190715267ed02b6d415396c2bbcf2eaace | |
parent | 93ea0eb7d77afab34657715630d692a78b8cea6a (diff) | |
parent | f2ecc3d0787e05d9145722feed01d4a11ab6bec1 (diff) |
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
...
498 files changed, 12046 insertions, 22609 deletions
diff --git a/Documentation/devicetree/bindings/media/cec-gpio.txt b/Documentation/devicetree/bindings/media/cec-gpio.txt new file mode 100644 index 000000000000..46a0bac8b3b9 --- /dev/null +++ b/Documentation/devicetree/bindings/media/cec-gpio.txt @@ -0,0 +1,32 @@ +* 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>; +}; diff --git a/Documentation/devicetree/bindings/media/exynos5-gsc.txt b/Documentation/devicetree/bindings/media/exynos5-gsc.txt index 26ca25b6d264..0d4fdaedc6f1 100644 --- a/Documentation/devicetree/bindings/media/exynos5-gsc.txt +++ b/Documentation/devicetree/bindings/media/exynos5-gsc.txt @@ -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>; }; diff --git a/Documentation/devicetree/bindings/media/i2c/imx274.txt b/Documentation/devicetree/bindings/media/i2c/imx274.txt new file mode 100644 index 000000000000..80f2e89568e1 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/imx274.txt @@ -0,0 +1,33 @@ +* 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>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt index 855e1faf73e2..33f10a94c381 100644 --- a/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt +++ b/Documentation/devicetree/bindings/media/i2c/nokia,smia.txt @@ -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 diff --git a/Documentation/devicetree/bindings/media/rockchip-rga.txt b/Documentation/devicetree/bindings/media/rockchip-rga.txt new file mode 100644 index 000000000000..fd5276abfad6 --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip-rga.txt @@ -0,0 +1,33 @@ +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"; + }; diff --git a/Documentation/devicetree/bindings/media/tango-ir.txt b/Documentation/devicetree/bindings/media/tango-ir.txt new file mode 100644 index 000000000000..a9f00c2bf897 --- /dev/null +++ b/Documentation/devicetree/bindings/media/tango-ir.txt @@ -0,0 +1,21 @@ +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>; + }; diff --git a/Documentation/devicetree/bindings/media/tegra-cec.txt b/Documentation/devicetree/bindings/media/tegra-cec.txt new file mode 100644 index 000000000000..c503f06f3b84 --- /dev/null +++ b/Documentation/devicetree/bindings/media/tegra-cec.txt @@ -0,0 +1,27 @@ +* 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"; +}; diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt index 852041a7480c..3994b0143dd1 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.txt +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt @@ -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>;", diff --git a/Documentation/media/cec.h.rst.exceptions b/Documentation/media/cec.h.rst.exceptions index b1687532742f..d9fd092de6f8 100644 --- a/Documentation/media/cec.h.rst.exceptions +++ b/Documentation/media/cec.h.rst.exceptions @@ -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 diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 28866259998c..d37e107f2fde 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -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 diff --git a/Documentation/media/kapi/dtv-ca.rst b/Documentation/media/kapi/dtv-ca.rst new file mode 100644 index 000000000000..a4dd700189b0 --- /dev/null +++ b/Documentation/media/kapi/dtv-ca.rst @@ -0,0 +1,4 @@ +Digital TV Conditional Access kABI +---------------------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h diff --git a/Documentation/media/kapi/dtv-common.rst b/Documentation/media/kapi/dtv-common.rst new file mode 100644 index 000000000000..40cf1033b5e1 --- /dev/null +++ b/Documentation/media/kapi/dtv-common.rst @@ -0,0 +1,55 @@ +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 diff --git a/Documentation/media/kapi/dtv-core.rst b/Documentation/media/kapi/dtv-core.rst index de9a228aca8a..bca743dc6b43 100644 --- a/Documentation/media/kapi/dtv-core.rst +++ b/Documentation/media/kapi/dtv-core.rst @@ -26,572 +26,12 @@ I2C bus. abandoned standard, not used anymore) and ATSC version 3.0 current proposals. Currently, the DVB subsystem doesn't implement those standards. -Digital TV Common functions ---------------------------- -.. kernel-doc:: drivers/media/dvb-core/dvb_math.h +.. toctree:: + :maxdepth: 1 -.. 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 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 algoritms 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 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 -&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 ------------------- - -Demux Callback -~~~~~~~~~~~~~~ - -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. - -.. kernel-doc:: drivers/media/dvb-core/demux.h - -Digital TV Conditional Access kABI ----------------------------------- - -.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h + dtv-common + dtv-frontend + dtv-demux + dtv-ca + dtv-net diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst new file mode 100644 index 000000000000..7aa865a2b43f --- /dev/null +++ b/Documentation/media/kapi/dtv-demux.rst @@ -0,0 +1,82 @@ +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 diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst new file mode 100644 index 000000000000..f1a2fdaab5ba --- /dev/null +++ b/Documentation/media/kapi/dtv-frontend.rst @@ -0,0 +1,443 @@ +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 diff --git a/Documentation/media/kapi/dtv-net.rst b/Documentation/media/kapi/dtv-net.rst new file mode 100644 index 000000000000..ced991b73d69 --- /dev/null +++ b/Documentation/media/kapi/dtv-net.rst @@ -0,0 +1,4 @@ +Digital TV Network kABI +----------------------- + +.. kernel-doc:: drivers/media/dvb-core/dvb_net.h diff --git a/Documentation/media/kapi/v4l2-async.rst b/Documentation/media/kapi/v4l2-async.rst new file mode 100644 index 000000000000..523ff9eb09a0 --- /dev/null +++ b/Documentation/media/kapi/v4l2-async.rst @@ -0,0 +1,3 @@ +V4L2 async kAPI +^^^^^^^^^^^^^^^ +.. kernel-doc:: include/media/v4l2-async.h diff --git a/Documentation/media/kapi/v4l2-core.rst b/Documentation/media/kapi/v4l2-core.rst index c7434f38fd9c..5cf292037a48 100644 --- a/Documentation/media/kapi/v4l2-core.rst +++ b/Documentation/media/kapi/v4l2-core.rst @@ -19,6 +19,7 @@ Video4Linux devices v4l2-mc v4l2-mediabus v4l2-mem2mem + v4l2-async v4l2-fwnode v4l2-rect v4l2-tuner diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index a5c821809cc6..b6fd86424fbb 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -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 diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index 0f397c535a4c..bdad4b197bcd 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -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`` diff --git a/Documentation/media/uapi/dvb/examples.rst b/Documentation/media/uapi/dvb/examples.rst index e0f627ca2e4d..16dd90fa9e94 100644 --- a/Documentation/media/uapi/dvb/examples.rst +++ b/Documentation/media/uapi/dvb/examples.rst @@ -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. diff --git a/Documentation/media/uapi/dvb/fe-get-property.rst b/Documentation/media/uapi/dvb/fe-get-property.rst index 948d2ba84f2c..b69741d9cedf 100644 --- a/Documentation/media/uapi/dvb/fe-get-property.rst +++ b/Documentation/media/uapi/dvb/fe-get-property.rst @@ -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:`` diff --git a/Documentation/media/uapi/dvb/net-types.rst b/Documentation/media/uapi/dvb/net-types.rst index e1177bdcd623..8fa3292eaa42 100644 --- a/Documentation/media/uapi/dvb/net-types.rst +++ b/Documentation/media/uapi/dvb/net-types.rst @@ -1,6 +1,6 @@ .. -*- coding: utf-8; mode: rst -*- -.. _dmx_types: +.. _net_types: ************** Net Data Types diff --git a/MAINTAINERS b/MAINTAINERS index b0543c223f6a..1c453f9cce81 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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> diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts index b9e58c536afd..39e35f8b8206 100644 --- a/arch/arm/boot/dts/omap3-n9.dts +++ b/arch/arm/boot/dts/omap3-n9.dts @@ -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>; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index 1b0bd72945f2..12fbb3da5fce 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -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>; }; diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index 646601a3ebd8..c354a1ed1e70 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -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>; diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c index f8a808d45034..98f88c43f62c 100644 --- a/drivers/media/cec/cec-adap.c +++ b/drivers/media/cec/cec-adap.c @@ -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. * diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c index a079f7fe018c..3dba3aa34a43 100644 --- a/drivers/media/cec/cec-api.c +++ b/drivers/media/cec/cec-api.c @@ -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); diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index 648136e552d5..5870da6a567f 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -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); diff --git a/drivers/media/cec/cec-pin-priv.h b/drivers/media/cec/cec-pin-priv.h new file mode 100644 index 000000000000..7d0def199762 --- /dev/null +++ b/drivers/media/cec/cec-pin-priv.h @@ -0,0 +1,133 @@ +/* + * 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 diff --git a/drivers/media/cec/cec-pin.c b/drivers/media/cec/cec-pin.c index c003b8eac617..b48dfe844118 100644 --- a/drivers/media/cec/cec-pin.c +++ b/drivers/media/cec/cec-pin.c @@ -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; } diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c index 50e3f76d4847..8895158c1962 100644 --- a/drivers/media/common/cypress_firmware.c +++ b/drivers/media/common/cypress_firmware.c @@ -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; diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c index 930d2c94d5d3..8c87d6837c49 100644 --- a/drivers/media/common/saa7146/saa7146_fops.c +++ b/drivers/media/common/saa7146/saa7146_fops.c @@ -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; diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c index 371c6f8606de..ce8d78c137f0 100644 --- a/drivers/media/common/saa7146/saa7146_vbi.c +++ b/drivers/media/common/saa7146/saa7146_vbi.c @@ -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, diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c index 37b4654dc21c..2b631eaa65b3 100644 --- a/drivers/media/common/saa7146/saa7146_video.c +++ b/drivers/media/common/saa7146/saa7146_video.c @@ -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 @@ out: 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, diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index e7a0d7798d5b..e4ea2a0c7a24 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -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); diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index a772976cfe26..f96968c11312 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -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 diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 18e4230865be..3ddd44e1ee77 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -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++; diff --git a/drivers/media/dvb-core/dmxdev.h b/drivers/media/dvb-core/dmxdev.h index 054fd4eb6192..5e795f5f0f41 100644 --- a/drivers/media/dvb-core/dmxdev.h +++ b/drivers/media/dvb-core/dmxdev.h @@ -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_ */ diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 6628f80d184f..acade7543b82 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -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)); } diff --git a/drivers/media/dvb-core/dvb_demux.h b/drivers/media/dvb-core/dvb_demux.h index 6f572ca8d339..cc048f09aa85 100644 --- a/drivers/media/dvb-core/dvb_demux.h +++ b/drivers/media/dvb-core/dvb_demux.h @@ -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); diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 9139d01ba7ed..3ad83359098b 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -145,15 +145,13 @@ static void __dvb_frontend_free(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; - if (!fepriv) - return; - - dvb_free_device(fepriv->dvbdev); + if (fepriv) + dvb_free_device(fepriv->dvbdev); dvb_frontend_invoke_release(fe, fe->ops.release); - kfree(fepriv); - fe->frontend_priv = NULL; + if (fepriv) + kfree(fepriv); } static void dvb_frontend_free(struct kref *ref) @@ -951,8 +949,6 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) memset(c, 0, offsetof(struct dtv_frontend_properties, strength)); c->delivery_system = delsys; - c->state = DTV_CLEAR; - dev_dbg(fe->dvb->device, "%s: Clearing cache for delivery system %d\n", __func__, c->delivery_system); @@ -1109,39 +1105,6 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0), }; -static void dtv_property_dump(struct dvb_frontend *fe, - bool is_set, - struct dtv_property *tvp) -{ - int i; - - if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { - dev_warn(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x undefined\n", - __func__, - is_set ? "SET" : "GET", - tvp->cmd); - return; - } - - dev_dbg(fe->dvb->device, "%s: %s tvp.cmd = 0x%08x (%s)\n", __func__, - is_set ? "SET" : "GET", - tvp->cmd, - dtv_cmds[tvp->cmd].name); - - if (dtv_cmds[tvp->cmd].buffer) { - dev_dbg(fe->dvb->device, "%s: tvp.u.buffer.len = 0x%02x\n", - __func__, tvp->u.buffer.len); - - for(i = 0; i < tvp->u.buffer.len; i++) - dev_dbg(fe->dvb->device, - "%s: tvp.u.buffer.data[0x%02x] = 0x%02x\n", - __func__, i, tvp->u.buffer.data[i]); - } else { - dev_dbg(fe->dvb->device, "%s: tvp.u.data = 0x%08x\n", __func__, - tvp->u.data); - } -} - /* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity. @@ -1315,17 +1278,15 @@ static int dtv_get_frontend(struct dvb_frontend *fe, return 0; } -static int dvb_frontend_ioctl_legacy(struct file *file, - unsigned int cmd, void *parg); -static int dvb_frontend_ioctl_properties(struct file *file, - unsigned int cmd, void *parg); +static int dvb_frontend_handle_ioctl(struct file *file, + unsigned int cmd, void *parg); static int dtv_property_process_get(struct dvb_frontend *fe, const struct dtv_frontend_properties *c, struct dtv_property *tvp, struct file *file) { - int r, ncaps; + int ncaps; switch(tvp->cmd) { case DTV_ENUM_DELSYS: @@ -1536,14 +1497,18 @@ static int dtv_property_process_get(struct dvb_frontend *fe, return -EINVAL; } - /* Allow the frontend to override outgoing properties */ - if (fe->ops.get_property) { - r = fe->ops.get_property(fe, tvp); - if (r < 0) - return r; - } - - dtv_property_dump(fe, false, tvp); + if (!dtv_cmds[tvp->cmd].buffer) + dev_dbg(fe->dvb->device, + "%s: GET cmd 0x%08x (%s) = 0x%08x\n", + __func__, tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.data); + else + dev_dbg(fe->dvb->device, + "%s: GET cmd 0x%08x (%s) len %d: %*ph\n", + __func__, + tvp->cmd, dtv_cmds[tvp->cmd].name, + tvp->u.buffer.len, + tvp->u.buffer.len, tvp->u.buffer.data); return 0; } @@ -1766,23 +1731,36 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe) return emulate_delivery_system(fe, delsys); } +/** + * dtv_property_process_set - Sets a single DTV property + * @fe: Pointer to &struct dvb_frontend + * @file: Pointer to &struct file + * @cmd: Digital TV command + * @data: An unsigned 32-bits number + * + * This routine assigns the property + * value to the corresponding member of + * &struct dtv_frontend_properties + * + * Returns: + * Zero on success, negative errno on failure. + */ static int dtv_property_process_set(struct dvb_frontend *fe, - struct dtv_property *tvp, - struct file *file) + struct file *file, + u32 cmd, u32 data) { int r = 0; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - /* Allow the frontend to validate incoming properties */ - if (fe->ops.set_property) { - r = fe->ops.set_property(fe, tvp); - if (r < 0) - return r; - } - - dtv_property_dump(fe, true, tvp); - - switch(tvp->cmd) { + /** Dump DTV command name and value*/ + if (!cmd || cmd > DTV_MAX_COMMAND) + dev_warn(fe->dvb->device, "%s: SET cmd 0x%08x undefined\n", + __func__, cmd); + else + dev_dbg(fe->dvb->device, + "%s: SET cmd 0x%08x (%s) to 0x%08x\n", + __func__, cmd, dtv_cmds[cmd].name, data); + switch (cmd) { case DTV_CLEAR: /* * Reset a cache of data specific to the frontend here. This does @@ -1791,144 +1769,144 @@ static int dtv_property_process_set(struct dvb_frontend *fe, dvb_frontend_clear_cache(fe); break; case DTV_TUNE: - /* interpret the cache of data, build either a traditional frontend - * tunerequest so we can pass validation in the FE_SET_FRONTEND - * ioctl. + /* + * Use the cached Digital TV properties to tune the + * frontend */ - c->state = tvp->cmd; - dev_dbg(fe->dvb->device, "%s: Finalised property cache\n", - __func__); + dev_dbg(fe->dvb->device, + "%s: Setting the frontend from property cache\n", + __func__); r = dtv_set_frontend(fe); break; case DTV_FREQUENCY: - c->frequency = tvp->u.data; + c->frequency = data; break; case DTV_MODULATION: - c->modulation = tvp->u.data; + c->modulation = data; break; case DTV_BANDWIDTH_HZ: - c->bandwidth_hz = tvp->u.data; + c->bandwidth_hz = data; break; case DTV_INVERSION: - c->inversion = tvp->u.data; + c->inversion = data; break; case DTV_SYMBOL_RATE: - c->symbol_rate = tvp->u.data; + c->symbol_rate = data; break; case DTV_INNER_FEC: - c->fec_inner = tvp->u.data; + c->fec_inner = data; break; case DTV_PILOT: - c->pilot = tvp->u.data; + c->pilot = data; break; case DTV_ROLLOFF: - c->rolloff = tvp->u.data; + c->rolloff = data; break; case DTV_DELIVERY_SYSTEM: - r = dvbv5_set_delivery_system(fe, tvp->u.data); + r = dvbv5_set_delivery_system(fe, data); break; case DTV_VOLTAGE: - c->voltage = tvp->u.data; - r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE, + c->voltage = data; + r = dvb_frontend_handle_ioctl(file, FE_SET_VOLTAGE, (void *)c->voltage); break; case DTV_TONE: - c->sectone = tvp->u.data; - r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE, + c->sectone = data; + r = dvb_frontend_handle_ioctl(file, FE_SET_TONE, (void *)c->sectone); break; case DTV_CODE_RATE_HP: - c->code_rate_HP = tvp->u.data; + c->code_rate_HP = data; break; case DTV_CODE_RATE_LP: - c->code_rate_LP = tvp->u.data; + c->code_rate_LP = data; break; case DTV_GUARD_INTERVAL: - c->guard_interval = tvp->u.data; + c->guard_interval = data; break; case DTV_TRANSMISSION_MODE: - c->transmission_mode = tvp->u.data; + c->transmission_mode = data; break; case DTV_HIERARCHY: - c->hierarchy = tvp->u.data; + c->hierarchy = data; break; case DTV_INTERLEAVING: - c->interleaving = tvp->u.data; + c->interleaving = data; break; /* ISDB-T Support here */ case DTV_ISDBT_PARTIAL_RECEPTION: - c->isdbt_partial_reception = tvp->u.data; + c->isdbt_partial_reception = data; break; case DTV_ISDBT_SOUND_BROADCASTING: - c->isdbt_sb_mode = tvp->u.data; + c->isdbt_sb_mode = data; break; case DTV_ISDBT_SB_SUBCHANNEL_ID: - c->isdbt_sb_subchannel = tvp->u.data; + c->isdbt_sb_subchannel = data; break; case DTV_ISDBT_SB_SEGMENT_IDX: - c->isdbt_sb_segment_idx = tvp->u.data; + c->isdbt_sb_segment_idx = data; break; case DTV_ISDBT_SB_SEGMENT_COUNT: - c->isdbt_sb_segment_count = tvp->u.data; + c->isdbt_sb_segment_count = data; break; case DTV_ISDBT_LAYER_ENABLED: - c->isdbt_layer_enabled = tvp->u.data; + c->isdbt_layer_enabled = data; break; case DTV_ISDBT_LAYERA_FEC: - c->layer[0].fec = tvp->u.data; + c->layer[0].fec = data; break; case DTV_ISDBT_LAYERA_MODULATION: - c->layer[0].modulation = tvp->u.data; + c->layer[0].modulation = data; break; case DTV_ISDBT_LAYERA_SEGMENT_COUNT: - c->layer[0].segment_count = tvp->u.data; + c->layer[0].segment_count = data; break; case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: - c->layer[0].interleaving = tvp->u.data; + c->layer[0].interleaving = data; break; case DTV_ISDBT_LAYERB_FEC: - c->layer[1].fec = tvp->u.data; + c->layer[1].fec = data; break; case DTV_ISDBT_LAYERB_MODULATION: - c->layer[1].modulation = tvp->u.data; + c->layer[1].modulation = data; break; case DTV_ISDBT_LAYERB_SEGMENT_COUNT: - c->layer[1].segment_count = tvp->u.data; + c->layer[1].segment_count = data; break; case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: - c->layer[1].interleaving = tvp->u.data; + c->layer[1].interleaving = data; break; case DTV_ISDBT_LAYERC_FEC: - c->layer[2].fec = tvp->u.data; + c->layer[2].fec = data; break; case DTV_ISDBT_LAYERC_MODULATION: - c->layer[2].modulation = tvp->u.data; + c->layer[2].modulation = data; break; case DTV_ISDBT_LAYERC_SEGMENT_COUNT: - c->layer[2].segment_count = tvp->u.data; + c->layer[2].segment_count = data; break; case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: - c->layer[2].interleaving = tvp->u.data; + c->layer[2].interleaving = data; break; /* Multistream support */ case DTV_STREAM_ID: case DTV_DVBT2_PLP_ID_LEGACY: - c->stream_id = tvp->u.data; + c->stream_id = data; break; /* ATSC-MH */ case DTV_ATSCMH_PARADE_ID: - fe->dtv_property_cache.atscmh_parade_id = tvp->u.data; + fe->dtv_property_cache.atscmh_parade_id = data; break; case DTV_ATSCMH_RS_FRAME_ENSEMBLE: - fe->dtv_property_cache.atscmh_rs_frame_ensemble = tvp->u.data; + fe->dtv_property_cache.atscmh_rs_frame_ensemble = data; break; case DTV_LNA: - c->lna = tvp->u.data; + c->lna = data; if (fe->ops.set_lna) r = fe->ops.set_lna(fe); if (r < 0) @@ -1942,14 +1920,12 @@ static int dtv_property_process_set(struct dvb_frontend *fe, return r; } -static int dvb_frontend_ioctl(struct file *file, - unsigned int cmd, void *parg) +static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct dvb_frontend_private *fepriv = fe->frontend_priv; - int err = -EOPNOTSUPP; + int err; dev_dbg(fe->dvb->device, "%s: (%d)\n", __func__, _IOC_NR(cmd)); if (down_interruptible(&fepriv->sem)) @@ -1960,109 +1936,33 @@ static int dvb_frontend_ioctl(struct file *file, return -ENODEV; } - if ((file->f_flags & O_ACCMODE) == O_RDONLY && - (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT || - cmd == FE_DISEQC_RECV_SLAVE_REPLY)) { + /* + * If the frontend is opened in read-only mode, only the ioctls + * that don't interfere with the tune logic should be accepted. + * That allows an external application to monitor the DVB QoS and + * statistics parameters. + * + * That matches all _IOR() ioctls, except for two special cases: + * - FE_GET_EVENT is part of the tuning logic on a DVB application; + * - FE_DISEQC_RECV_SLAVE_REPLY is part of DiSEqC 2.0 + * setup + * So, those two ioctls should also return -EPERM, as otherwise + * reading from them would interfere with a DVB tune application + */ + if ((file->f_flags & O_ACCMODE) == O_RDONLY + && (_IOC_DIR(cmd) != _IOC_READ + || cmd == FE_GET_EVENT + || cmd == FE_DISEQC_RECV_SLAVE_REPLY)) { up(&fepriv->sem); return -EPERM; } - if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) - err = dvb_frontend_ioctl_properties(file, cmd, parg); - else { - c->state = DTV_UNDEFINED; - err = dvb_frontend_ioctl_legacy(file, cmd, parg); - } + err = dvb_frontend_handle_ioctl(file, cmd, parg); up(&fepriv->sem); return err; } -static int dvb_frontend_ioctl_properties(struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int err = 0; - - struct dtv_properties *tvps = parg; - struct dtv_property *tvp = NULL; - int i; - - dev_dbg(fe->dvb->device, "%s:\n", __func__); - - if (cmd == FE_SET_PROPERTY) { - dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num); - dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); - if (IS_ERR(tvp)) - return PTR_ERR(tvp); - - for (i = 0; i < tvps->num; i++) { - err = dtv_property_process_set(fe, tvp + i, file); - if (err < 0) - goto out; - (tvp + i)->result = err; - } - - if (c->state == DTV_TUNE) - dev_dbg(fe->dvb->device, "%s: Property cache is full, tuning\n", __func__); - - } else if (cmd == FE_GET_PROPERTY) { - struct dtv_frontend_properties getp = fe->dtv_property_cache; - - dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", __func__, tvps->num); - dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", __func__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); - if (IS_ERR(tvp)) - return PTR_ERR(tvp); - - /* - * Let's use our own copy of property cache, in order to - * avoid mangling with DTV zigzag logic, as drivers might - * return crap, if they don't check if the data is available - * before updating the properties cache. - */ - if (fepriv->state != FESTATE_IDLE) { - err = dtv_get_frontend(fe, &getp, NULL); - if (err < 0) - goto out; - } - for (i = 0; i < tvps->num; i++) { - err = dtv_property_process_get(fe, &getp, tvp + i, file); - if (err < 0) - goto out; - (tvp + i)->result = err; - } - - if (copy_to_user((void __user *)tvps->props, tvp, - tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - } else - err = -EOPNOTSUPP; - -out: - kfree(tvp); - return err; -} - static int dtv_set_frontend(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; @@ -2200,16 +2100,102 @@ static int dtv_set_frontend(struct dvb_frontend *fe) } -static int dvb_frontend_ioctl_legacy(struct file *file, - unsigned int cmd, void *parg) +static int dvb_frontend_handle_ioctl(struct file *file, + unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - int err = -EOPNOTSUPP; + int i, err; + + dev_dbg(fe->dvb->device, "%s:\n", __func__); switch (cmd) { + case FE_SET_PROPERTY: { + struct dtv_properties *tvps = parg; + struct dtv_property *tvp = NULL; + + dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", + __func__, tvps->num); + dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", + __func__, tvps->props); + + /* + * Put an arbitrary limit on the number of messages that can + * be sent at once + */ + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + + tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + + for (i = 0; i < tvps->num; i++) { + err = dtv_property_process_set(fe, file, + (tvp + i)->cmd, + (tvp + i)->u.data); + if (err < 0) { + kfree(tvp); + return err; + } + } + kfree(tvp); + break; + } + case FE_GET_PROPERTY: { + struct dtv_properties *tvps = parg; + struct dtv_property *tvp = NULL; + struct dtv_frontend_properties getp = fe->dtv_property_cache; + + dev_dbg(fe->dvb->device, "%s: properties.num = %d\n", + __func__, tvps->num); + dev_dbg(fe->dvb->device, "%s: properties.props = %p\n", + __func__, tvps->props); + + /* + * Put an arbitrary limit on the number of messages that can + * be sent at once + */ + if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS)) + return -EINVAL; + + tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp)); + if (IS_ERR(tvp)) + return PTR_ERR(tvp); + + /* + * Let's use our own copy of property cache, in order to + * avoid mangling with DTV zigzag logic, as drivers might + * return crap, if they don't check if the data is available + * before updating the properties cache. + */ + if (fepriv->state != FESTATE_IDLE) { + err = dtv_get_frontend(fe, &getp, NULL); + if (err < 0) { + kfree(tvp); + return err; + } + } + for (i = 0; i < tvps->num; i++) { + err = dtv_property_process_get(fe, &getp, + tvp + i, file); + if (err < 0) { + kfree(tvp); + return err; + } + } + + if (copy_to_user((void __user *)tvps->props, tvp, + tvps->num * sizeof(struct dtv_property))) { + kfree(tvp); + return -EFAULT; + } + kfree(tvp); + break; + } + case FE_GET_INFO: { struct dvb_frontend_info* info = parg; @@ -2273,42 +2259,6 @@ static int dvb_frontend_ioctl_legacy(struct file *file, break; } - case FE_READ_BER: - if (fe->ops.read_ber) { - if (fepriv->thread) - err = fe->ops.read_ber(fe, (__u32 *) parg); - else - err = -EAGAIN; - } - break; - - case FE_READ_SIGNAL_STRENGTH: - if (fe->ops.read_signal_strength) { - if (fepriv->thread) - err = fe->ops.read_signal_strength(fe, (__u16 *) parg); - else - err = -EAGAIN; - } - break; - - case FE_READ_SNR: - if (fe->ops.read_snr) { - if (fepriv->thread) - err = fe->ops.read_snr(fe, (__u16 *) parg); - else - err = -EAGAIN; - } - break; - - case FE_READ_UNCORRECTED_BLOCKS: - if (fe->ops.read_ucblocks) { - if (fepriv->thread) - err = fe->ops.read_ucblocks(fe, (__u32 *) parg); - else - err = -EAGAIN; - } - break; - case FE_DISEQC_RESET_OVERLOAD: if (fe->ops.diseqc_reset_overload) { err = fe->ops.diseqc_reset_overload(fe); @@ -2360,6 +2310,23 @@ static int dvb_frontend_ioctl_legacy(struct file *file, } break; + case FE_DISEQC_RECV_SLAVE_REPLY: + if (fe->ops.diseqc_recv_slave_reply) + err = fe->ops.diseqc_recv_slave_reply(fe, parg); + break; + + case FE_ENABLE_HIGH_LNB_VOLTAGE: + if (fe->ops.enable_high_lnb_voltage) + err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); + break; + + case FE_SET_FRONTEND_TUNE_MODE: + fepriv->tune_mode_flags = (unsigned long) parg; + err = 0; + break; + + /* DEPRECATED dish control ioctls */ + case FE_DISHNETWORK_SEND_LEGACY_CMD: if (fe->ops.dishnetwork_send_legacy_command) { err = fe->ops.dishnetwork_send_legacy_command(fe, @@ -2425,16 +2392,46 @@ static int dvb_frontend_ioctl_legacy(struct file *file, } break; - case FE_DISEQC_RECV_SLAVE_REPLY: - if (fe->ops.diseqc_recv_slave_reply) - err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); + /* DEPRECATED statistics ioctls */ + + case FE_READ_BER: + if (fe->ops.read_ber) { + if (fepriv->thread) + err = fe->ops.read_ber(fe, parg); + else + err = -EAGAIN; + } break; - case FE_ENABLE_HIGH_LNB_VOLTAGE: - if (fe->ops.enable_high_lnb_voltage) - err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); + case FE_READ_SIGNAL_STRENGTH: + if (fe->ops.read_signal_strength) { + if (fepriv->thread) + err = fe->ops.read_signal_strength(fe, parg); + else + err = -EAGAIN; + } break; + case FE_READ_SNR: + if (fe->ops.read_snr) { + if (fepriv->thread) + err = fe->ops.read_snr(fe, parg); + else + err = -EAGAIN; + } + break; + + case FE_READ_UNCORRECTED_BLOCKS: + if (fe->ops.read_ucblocks) { + if (fepriv->thread) + err = fe->ops.read_ucblocks(fe, parg); + else + err = -EAGAIN; + } + break; + + /* DEPRECATED DVBv3 ioctls */ + case FE_SET_FRONTEND: err = dvbv3_set_delivery_system(fe); if (err) @@ -2461,11 +2458,10 @@ static int dvb_frontend_ioctl_legacy(struct file *file, err = dtv_get_frontend(fe, &getp, parg); break; } - case FE_SET_FRONTEND_TUNE_MODE: - fepriv->tune_mode_flags = (unsigned long) parg; - err = 0; - break; - } + + default: + return -ENOTSUPP; + } /* switch */ return err; } diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 907a05bde162..ace0c2fb26c2 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -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 diff --git a/drivers/media/dvb-core/dvb_net.h b/drivers/media/dvb-core/dvb_net.h index e9b18aa03e02..1eae8bad7cc1 100644 --- a/drivers/media/dvb-core/dvb_net.h +++ b/drivers/media/dvb-core/dvb_net.h @@ -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 diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 41aad0f99d73..060c60ddfcc3 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -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; diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 49189392cf3b..bbc1c20c0529 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -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 diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 2631d0e0a024..d17722eb4456 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -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" diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c index 98d575f2744c..b1c84ee914f0 100644 --- a/drivers/media/dvb-frontends/as102_fe.c +++ b/drivers/media/dvb-frontends/as102_fe.c @@ -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; diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c index 0118c2658cf7..ee1f704f81f2 100644 --- a/drivers/media/dvb-frontends/cx24113.c +++ b/drivers/media/dvb-frontends/cx24113.c @@ -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; diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index e105532bfba8..8fb3f095e21c 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -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); diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 7d04400b18dd..0696bc62dcc9 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c @@ -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; diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c index 0b17a45c5640..bd4f8278c906 100644 --- a/drivers/media/dvb-frontends/ds3000.c +++ b/drivers/media/dvb-frontends/ds3000.c @@ -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); diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c index 5798079add10..9854096839ae 100644 --- a/drivers/media/dvb-frontends/lg2160.c +++ b/drivers/media/dvb-frontends/lg2160.c @@ -1048,16 +1048,6 @@ fail: 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, diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index c9b1eb38444e..724e9aac0f11 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -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, }; diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index e8ac8c3e2ec0..bdaf9d235fed 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -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); diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c index 676c96c216c3..53064e11f5f1 100644 --- a/drivers/media/dvb-frontends/mxl5xx.c +++ b/drivers/media/dvb-frontends/mxl5xx.c @@ -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; diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 172fc367ccaa..41d9c513b7e8 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -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; } diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index 43d47dfcc7b8..53e66c232d3c 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c @@ -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; } diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index 45cbc898ad25..67f91814b9f7 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -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, }; diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index e4fd9c1b0560..6aad0efa3174 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c @@ -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); diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 94153895fcd4..3c6d6428f525 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -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 diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index f104650d6000..548a9efce966 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -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 diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 3df28f2f9b38..6fb818a775db 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -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) diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c index b33ccfc08708..4aa8e45b5cd3 100644 --- a/drivers/media/i2c/adv748x/adv748x-afe.c +++ b/drivers/media/i2c/adv748x/adv748x-afe.c @@ -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); diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index f289b8aca1da..c786cd125417 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -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; diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 65f34e7e146f..136aa80a834b 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c @@ -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; diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 39f51daa7558..f38bf819d805 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -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, diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index 95af4fc99cd0..ed01e8bd4331 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -21,6 +21,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 * uniformly adjusted for gradual lens movement, with desired @@ -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", diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c index c14f0fd6ded3..e9eff9039ef5 100644 --- a/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -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; diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c new file mode 100644 index 000000000000..800b9bf9cdd3 --- /dev/null +++ b/drivers/media/i2c/imx274.c @@ -0,0 +1,1811 @@ +/* + * imx274.c - IMX274 CMOS Image Sensor driver + * + * Copyright (C) 2017, Leopard Imaging, Inc. + * + * Leon Luo <leonl@leopardimaging.com> + * Edwin Zou <edwinz@leopardimaging.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <linux/v4l2-mediabus.h> +#include <linux/videodev2.h> + +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-subdev.h> + +/* + * See "SHR, SVR Setting" in datasheet + */ +#define IMX274_DEFAULT_FRAME_LENGTH (4550) +#define IMX274_MAX_FRAME_LENGTH (0x000fffff) + +/* + * See "Frame Rate Adjustment" in datasheet + */ +#define IMX274_PIXCLK_CONST1 (72000000) +#define IMX274_PIXCLK_CONST2 (1000000) + +/* + * The input gain is shifted by IMX274_GAIN_SHIFT to get + * decimal number. The real gain is + * (float)input_gain_value / (1 << IMX274_GAIN_SHIFT) + */ +#define IMX274_GAIN_SHIFT (8) +#define IMX274_GAIN_SHIFT_MASK ((1 << IMX274_GAIN_SHIFT) - 1) + +/* + * See "Analog Gain" and "Digital Gain" in datasheet + * min gain is 1X + * max gain is calculated based on IMX274_GAIN_REG_MAX + */ +#define IMX274_GAIN_REG_MAX (1957) +#define IMX274_MIN_GAIN (0x01 << IMX274_GAIN_SHIFT) +#define IMX274_MAX_ANALOG_GAIN ((2048 << IMX274_GAIN_SHIFT)\ + / (2048 - IMX274_GAIN_REG_MAX)) +#define IMX274_MAX_DIGITAL_GAIN (8) +#define IMX274_DEF_GAIN (20 << IMX274_GAIN_SHIFT) +#define IMX274_GAIN_CONST (2048) /* for gain formula */ + +/* + * 1 line time in us = (HMAX / 72), minimal is 4 lines + */ +#define IMX274_MIN_EXPOSURE_TIME (4 * 260 / 72) + +#define IMX274_DEFAULT_MODE IMX274_MODE_3840X2160 +#define IMX274_MAX_WIDTH (3840) +#define IMX274_MAX_HEIGHT (2160) +#define IMX274_MAX_FRAME_RATE (120) +#define IMX274_MIN_FRAME_RATE (5) +#define IMX274_DEF_FRAME_RATE (60) + +/* + * register SHR is limited to (SVR value + 1) x VMAX value - 4 + */ +#define IMX274_SHR_LIMIT_CONST (4) + +/* + * Constants for sensor reset delay + */ +#define IMX274_RESET_DELAY1 (2000) +#define IMX274_RESET_DELAY2 (2200) + +/* + * shift and mask constants + */ +#define IMX274_SHIFT_8_BITS (8) +#define IMX274_SHIFT_16_BITS (16) +#define IMX274_MASK_LSB_2_BITS (0x03) +#define IMX274_MASK_LSB_3_BITS (0x07) +#define IMX274_MASK_LSB_4_BITS (0x0f) +#define IMX274_MASK_LSB_8_BITS (0x00ff) + +#define DRIVER_NAME "IMX274" + +/* + * IMX274 register definitions + */ +#define IMX274_FRAME_LENGTH_ADDR_1 0x30FA /* VMAX, MSB */ +#define IMX274_FRAME_LENGTH_ADDR_2 0x30F9 /* VMAX */ +#define IMX274_FRAME_LENGTH_ADDR_3 0x30F8 /* VMAX, LSB */ +#define IMX274_SVR_REG_MSB 0x300F /* SVR */ +#define IMX274_SVR_REG_LSB 0x300E /* SVR */ +#define IMX274_HMAX_REG_MSB 0x30F7 /* HMAX */ +#define IMX274_HMAX_REG_LSB 0x30F6 /* HMAX */ +#define IMX274_COARSE_TIME_ADDR_MSB 0x300D /* SHR */ +#define IMX274_COARSE_TIME_ADDR_LSB 0x300C /* SHR */ +#define IMX274_ANALOG_GAIN_ADDR_LSB 0x300A /* ANALOG GAIN LSB */ +#define IMX274_ANALOG_GAIN_ADDR_MSB 0x300B /* ANALOG GAIN MSB */ +#define IMX274_DIGITAL_GAIN_REG 0x3012 /* Digital Gain */ +#define IMX274_VFLIP_REG 0x301A /* VERTICAL FLIP */ +#define IMX274_TEST_PATTERN_REG 0x303D /* TEST PATTERN */ +#define IMX274_STANDBY_REG 0x3000 /* STANDBY */ + +#define IMX274_TABLE_WAIT_MS 0 +#define IMX274_TABLE_END 1 + +/* + * imx274 I2C operation related structure + */ +struct reg_8 { + u16 addr; + u8 val; +}; + +static const struct regmap_config imx274_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, +}; + +enum imx274_mode { + IMX274_MODE_3840X2160, + IMX274_MODE_1920X1080, + IMX274_MODE_1280X720, + + IMX274_MODE_START_STREAM_1, + IMX274_MODE_START_STREAM_2, + IMX274_MODE_START_STREAM_3, + IMX274_MODE_START_STREAM_4, + IMX274_MODE_STOP_STREAM +}; + +/* + * imx274 format related structure + */ +struct imx274_frmfmt { + u32 mbus_code; + enum v4l2_colorspace colorspace; + struct v4l2_frmsize_discrete size; + enum imx274_mode mode; +}; + +/* + * imx274 test pattern related structure + */ +enum { + TEST_PATTERN_DISABLED = 0, + TEST_PATTERN_ALL_000H, + TEST_PATTERN_ALL_FFFH, + TEST_PATTERN_ALL_555H, + TEST_PATTERN_ALL_AAAH, + TEST_PATTERN_VSP_5AH, /* VERTICAL STRIPE PATTERN 555H/AAAH */ + TEST_PATTERN_VSP_A5H, /* VERTICAL STRIPE PATTERN AAAH/555H */ + TEST_PATTERN_VSP_05H, /* VERTICAL STRIPE PATTERN 000H/555H */ + TEST_PATTERN_VSP_50H, /* VERTICAL STRIPE PATTERN 555H/000H */ + TEST_PATTERN_VSP_0FH, /* VERTICAL STRIPE PATTERN 000H/FFFH */ + TEST_PATTERN_VSP_F0H, /* VERTICAL STRIPE PATTERN FFFH/000H */ + TEST_PATTERN_H_COLOR_BARS, + TEST_PATTERN_V_COLOR_BARS, +}; + +static const char * const tp_qmenu[] = { + "Disabled", + "All 000h Pattern", + "All FFFh Pattern", + "All 555h Pattern", + "All AAAh Pattern", + "Vertical Stripe (555h / AAAh)", + "Vertical Stripe (AAAh / 555h)", + "Vertical Stripe (000h / 555h)", + "Vertical Stripe (555h / 000h)", + "Vertical Stripe (000h / FFFh)", + "Vertical Stripe (FFFh / 000h)", + "Horizontal Color Bars", + "Vertical Color Bars", +}; + +/* + * All-pixel scan mode (10-bit) + * imx274 mode1(refer to datasheet) register configuration with + * 3840x2160 resolution, raw10 data and mipi four lane output + */ +static const struct reg_8 imx274_mode1_3840x2160_raw10[] = { + {0x3004, 0x01}, + {0x3005, 0x01}, + {0x3006, 0x00}, + {0x3007, 0x02}, + + {0x3018, 0xA2}, /* output XVS, HVS */ + + {0x306B, 0x05}, + {0x30E2, 0x01}, + {0x30F6, 0x07}, /* HMAX, 263 */ + {0x30F7, 0x01}, /* HMAX */ + + {0x30dd, 0x01}, /* crop to 2160 */ + {0x30de, 0x06}, + {0x30df, 0x00}, + {0x30e0, 0x12}, + {0x30e1, 0x00}, + {0x3037, 0x01}, /* to crop to 3840 */ + {0x3038, 0x0c}, + {0x3039, 0x00}, + {0x303a, 0x0c}, + {0x303b, 0x0f}, + + {0x30EE, 0x01}, + {0x3130, 0x86}, + {0x3131, 0x08}, + {0x3132, 0x7E}, + {0x3133, 0x08}, + {0x3342, 0x0A}, + {0x3343, 0x00}, + {0x3344, 0x16}, + {0x3345, 0x00}, + {0x33A6, 0x01}, + {0x3528, 0x0E}, + {0x3554, 0x1F}, + {0x3555, 0x01}, + {0x3556, 0x01}, + {0x3557, 0x01}, + {0x3558, 0x01}, + {0x3559, 0x00}, + {0x355A, 0x00}, + {0x35BA, 0x0E}, + {0x366A, 0x1B}, + {0x366B, 0x1A}, + {0x366C, 0x19}, + {0x366D, 0x17}, + {0x3A41, 0x08}, + + {IMX274_TABLE_END, 0x00} +}; + +/* + * Horizontal/vertical 2/2-line binning + * (Horizontal and vertical weightedbinning, 10-bit) + * imx274 mode3(refer to datasheet) register configuration with + * 1920x1080 resolution, raw10 data and mipi four lane output + */ +static const struct reg_8 imx274_mode3_1920x1080_raw10[] = { + {0x3004, 0x02}, + {0x3005, 0x21}, + {0x3006, 0x00}, + {0x3007, 0x11}, + + {0x3018, 0xA2}, /* output XVS, HVS */ + + {0x306B, 0x05}, + {0x30E2, 0x02}, + + {0x30F6, 0x04}, /* HMAX, 260 */ + {0x30F7, 0x01}, /* HMAX */ + + {0x30dd, 0x01}, /* to crop to 1920x1080 */ + {0x30de, 0x05}, + {0x30df, 0x00}, + {0x30e0, 0x04}, + {0x30e1, 0x00}, + {0x3037, 0x01}, + {0x3038, 0x0c}, + {0x3039, 0x00}, + {0x303a, 0x0c}, + {0x303b, 0x0f}, + + {0x30EE, 0x01}, + {0x3130, 0x4E}, + {0x3131, 0x04}, + {0x3132, 0x46}, + {0x3133, 0x04}, + {0x3342, 0x0A}, + {0x3343, 0x00}, + {0x3344, 0x1A}, + {0x3345, 0x00}, + {0x33A6, 0x01}, + {0x3528, 0x0E}, + {0x3554, 0x00}, + {0x3555, 0x01}, + {0x3556, 0x01}, + {0x3557, 0x01}, + {0x3558, 0x01}, + {0x3559, 0x00}, + {0x355A, 0x00}, + {0x35BA, 0x0E}, + {0x366A, 0x1B}, + {0x366B, 0x1A}, + {0x366C, 0x19}, + {0x366D, 0x17}, + {0x3A41, 0x08}, + + {IMX274_TABLE_END, 0x00} +}; + +/* + * Vertical 2/3 subsampling binning horizontal 3 binning + * imx274 mode5(refer to datasheet) register configuration with + * 1280x720 resolution, raw10 data and mipi four lane output + */ +static const struct reg_8 imx274_mode5_1280x720_raw10[] = { + {0x3004, 0x03}, + {0x3005, 0x31}, + {0x3006, 0x00}, + {0x3007, 0x09}, + + {0x3018, 0xA2}, /* output XVS, HVS */ + + {0x306B, 0x05}, + {0x30E2, 0x03}, + + {0x30F6, 0x04}, /* HMAX, 260 */ + {0x30F7, 0x01}, /* HMAX */ + + {0x30DD, 0x01}, + {0x30DE, 0x07}, + {0x30DF, 0x00}, + {0x40E0, 0x04}, + {0x30E1, 0x00}, + {0x3030, 0xD4}, + {0x3031, 0x02}, + {0x3032, 0xD0}, + {0x3033, 0x02}, + + {0x30EE, 0x01}, + {0x3130, 0xE2}, + {0x3131, 0x02}, + {0x3132, 0xDE}, + {0x3133, 0x02}, + {0x3342, 0x0A}, + {0x3343, 0x00}, + {0x3344, 0x1B}, + {0x3345, 0x00}, + {0x33A6, 0x01}, + {0x3528, 0x0E}, + {0x3554, 0x00}, + {0x3555, 0x01}, + {0x3556, 0x01}, + {0x3557, 0x01}, + {0x3558, 0x01}, + {0x3559, 0x00}, + {0x355A, 0x00}, + {0x35BA, 0x0E}, + {0x366A, 0x1B}, + {0x366B, 0x19}, + {0x366C, 0x17}, + {0x366D, 0x17}, + {0x3A41, 0x04}, + + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 first step register configuration for + * starting stream + */ +static const struct reg_8 imx274_start_1[] = { + {IMX274_STANDBY_REG, 0x12}, + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 second step register configuration for + * starting stream + */ +static const struct reg_8 imx274_start_2[] = { + {0x3120, 0xF0}, /* clock settings */ + {0x3121, 0x00}, /* clock settings */ + {0x3122, 0x02}, /* clock settings */ + {0x3129, 0x9C}, /* clock settings */ + {0x312A, 0x02}, /* clock settings */ + {0x312D, 0x02}, /* clock settings */ + + {0x310B, 0x00}, + + /* PLSTMG */ + {0x304C, 0x00}, /* PLSTMG01 */ + {0x304D, 0x03}, + {0x331C, 0x1A}, + {0x331D, 0x00}, + {0x3502, 0x02}, + {0x3529, 0x0E}, + {0x352A, 0x0E}, + {0x352B, 0x0E}, + {0x3538, 0x0E}, + {0x3539, 0x0E}, + {0x3553, 0x00}, + {0x357D, 0x05}, + {0x357F, 0x05}, + {0x3581, 0x04}, + {0x3583, 0x76}, + {0x3587, 0x01}, + {0x35BB, 0x0E}, + {0x35BC, 0x0E}, + {0x35BD, 0x0E}, + {0x35BE, 0x0E}, + {0x35BF, 0x0E}, + {0x366E, 0x00}, + {0x366F, 0x00}, + {0x3670, 0x00}, + {0x3671, 0x00}, + + /* PSMIPI */ + {0x3304, 0x32}, /* PSMIPI1 */ + {0x3305, 0x00}, + {0x3306, 0x32}, + {0x3307, 0x00}, + {0x3590, 0x32}, + {0x3591, 0x00}, + {0x3686, 0x32}, + {0x3687, 0x00}, + + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 third step register configuration for + * starting stream + */ +static const struct reg_8 imx274_start_3[] = { + {IMX274_STANDBY_REG, 0x00}, + {0x303E, 0x02}, /* SYS_MODE = 2 */ + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 forth step register configuration for + * starting stream + */ +static const struct reg_8 imx274_start_4[] = { + {0x30F4, 0x00}, + {0x3018, 0xA2}, /* XHS VHS OUTUPT */ + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 register configuration for stoping stream + */ +static const struct reg_8 imx274_stop[] = { + {IMX274_STANDBY_REG, 0x01}, + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 disable test pattern register configuration + */ +static const struct reg_8 imx274_tp_disabled[] = { + {0x303C, 0x00}, + {0x377F, 0x00}, + {0x3781, 0x00}, + {0x370B, 0x00}, + {IMX274_TABLE_END, 0x00} +}; + +/* + * imx274 test pattern register configuration + * reg 0x303D defines the test pattern modes + */ +static const struct reg_8 imx274_tp_regs[] = { + {0x303C, 0x11}, + {0x370E, 0x01}, + {0x377F, 0x01}, + {0x3781, 0x01}, + {0x370B, 0x11}, + {IMX274_TABLE_END, 0x00} +}; + +static const struct reg_8 *mode_table[] = { + [IMX274_MODE_3840X2160] = imx274_mode1_3840x2160_raw10, + [IMX274_MODE_1920X1080] = imx274_mode3_1920x1080_raw10, + [IMX274_MODE_1280X720] = imx274_mode5_1280x720_raw10, + + [IMX274_MODE_START_STREAM_1] = imx274_start_1, + [IMX274_MODE_START_STREAM_2] = imx274_start_2, + [IMX274_MODE_START_STREAM_3] = imx274_start_3, + [IMX274_MODE_START_STREAM_4] = imx274_start_4, + [IMX274_MODE_STOP_STREAM] = imx274_stop, +}; + +/* + * imx274 format related structure + */ +static const struct imx274_frmfmt imx274_formats[] = { + {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {3840, 2160}, + IMX274_MODE_3840X2160}, + {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {1920, 1080}, + IMX274_MODE_1920X1080}, + {MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, {1280, 720}, + IMX274_MODE_1280X720}, +}; + +/* + * minimal frame length for each mode + * refer to datasheet section "Frame Rate Adjustment (CSI-2)" + */ +static const int min_frame_len[] = { + 4550, /* mode 1, 4K */ + 2310, /* mode 3, 1080p */ + 2310 /* mode 5, 720p */ +}; + +/* + * minimal numbers of SHR register + * refer to datasheet table "Shutter Setting (CSI-2)" + */ +static const int min_SHR[] = { + 12, /* mode 1, 4K */ + 8, /* mode 3, 1080p */ + 8 /* mode 5, 720p */ +}; + +static const int max_frame_rate[] = { + 60, /* mode 1 , 4K */ + 120, /* mode 3, 1080p */ + 120 /* mode 5, 720p */ +}; + +/* + * Number of clocks per internal offset period + * a constant based on mode + * refer to section "Integration Time in Each Readout Drive Mode (CSI-2)" + * in the datasheet + * for the implemented 3 modes, it happens to be the same number + */ +static const int nocpiop[] = { + 112, /* mode 1 , 4K */ + 112, /* mode 3, 1080p */ + 112 /* mode 5, 720p */ +}; + +/* + * struct imx274_ctrls - imx274 ctrl structure + * @handler: V4L2 ctrl handler structure + * @exposure: Pointer to expsure ctrl structure + * @gain: Pointer to gain ctrl structure + * @vflip: Pointer to vflip ctrl structure + * @test_pattern: Pointer to test pattern ctrl structure + */ +struct imx274_ctrls { + struct v4l2_ctrl_handler handler; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *test_pattern; +}; + +/* + * struct stim274 - imx274 device structure + * @sd: V4L2 subdevice structure + * @pd: Media pad structure + * @client: Pointer to I2C client + * @ctrls: imx274 control structure + * @format: V4L2 media bus frame format structure + * @frame_rate: V4L2 frame rate structure + * @regmap: Pointer to regmap structure + * @reset_gpio: Pointer to reset gpio + * @lock: Mutex structure + * @mode_index: Resolution mode index + */ +struct stimx274 { + struct v4l2_subdev sd; + struct media_pad pad; + struct i2c_client *client; + struct imx274_ctrls ctrls; + struct v4l2_mbus_framefmt format; + struct v4l2_fract frame_interval; + struct regmap *regmap; + struct gpio_desc *reset_gpio; + struct mutex lock; /* mutex lock for operations */ + u32 mode_index; +}; + +/* + * Function declaration + */ +static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl); +static int imx274_set_exposure(struct stimx274 *priv, int val); +static int imx274_set_vflip(struct stimx274 *priv, int val); +static int imx274_set_test_pattern(struct stimx274 *priv, int val); +static int imx274_set_frame_interval(struct stimx274 *priv, + struct v4l2_fract frame_interval); + +static inline void msleep_range(unsigned int delay_base) +{ + usleep_range(delay_base * 1000, delay_base * 1000 + 500); +} + +/* + * v4l2_ctrl and v4l2_subdev related operations + */ +static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) +{ + return &container_of(ctrl->handler, + struct stimx274, ctrls.handler)->sd; +} + +static inline struct stimx274 *to_imx274(struct v4l2_subdev *sd) +{ + return container_of(sd, struct stimx274, sd); +} + +/* + * imx274_regmap_util_write_table_8 - Function for writing register table + * @regmap: Pointer to device reg map structure + * @table: Table containing register values + * @wait_ms_addr: Flag for performing delay + * @end_addr: Flag for incating end of table + * + * This is used to write register table into sensor's reg map. + * + * Return: 0 on success, errors otherwise + */ +static int imx274_regmap_util_write_table_8(struct regmap *regmap, + const struct reg_8 table[], + u16 wait_ms_addr, u16 end_addr) +{ + int err; + const struct reg_8 *next; + u8 val; + + int range_start = -1; + int range_count = 0; + u8 range_vals[16]; + int max_range_vals = ARRAY_SIZE(range_vals); + + for (next = table;; next++) { + if ((next->addr != range_start + range_count) || + (next->addr == end_addr) || + (next->addr == wait_ms_addr) || + (range_count == max_range_vals)) { + if (range_count == 1) + err = regmap_write(regmap, + range_start, range_vals[0]); + else if (range_count > 1) + err = regmap_bulk_write(regmap, range_start, + &range_vals[0], + range_count); + + if (err) + return err; + + range_start = -1; + range_count = 0; + + /* Handle special address values */ + if (next->addr == end_addr) + break; + + if (next->addr == wait_ms_addr) { + msleep_range(next->val); + continue; + } + } + + val = next->val; + + if (range_start == -1) + range_start = next->addr; + + range_vals[range_count++] = val; + } + return 0; +} + +static inline int imx274_read_reg(struct stimx274 *priv, u16 addr, u8 *val) +{ + int err; + + err = regmap_read(priv->regmap, addr, (unsigned int *)val); + if (err) + dev_err(&priv->client->dev, + "%s : i2c read failed, addr = %x\n", __func__, addr); + else + dev_dbg(&priv->client->dev, + "%s : addr 0x%x, val=0x%x\n", __func__, + addr, *val); + return err; +} + +static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val) +{ + int err; + + err = regmap_write(priv->regmap, addr, val); + if (err) + dev_err(&priv->client->dev, + "%s : i2c write failed, %x = %x\n", __func__, + addr, val); + else + dev_dbg(&priv->client->dev, + "%s : addr 0x%x, val=0x%x\n", __func__, + addr, val); + return err; +} + +static int imx274_write_table(struct stimx274 *priv, const struct reg_8 table[]) +{ + return imx274_regmap_util_write_table_8(priv->regmap, + table, IMX274_TABLE_WAIT_MS, IMX274_TABLE_END); +} + +/* + * imx274_mode_regs - Function for set mode registers per mode index + * @priv: Pointer to device structure + * @mode: Mode index value + * + * This is used to start steam per mode index. + * mode = 0, start stream for sensor Mode 1: 4K/raw10 + * mode = 1, start stream for sensor Mode 3: 1080p/raw10 + * mode = 2, start stream for sensor Mode 5: 720p/raw10 + * + * Return: 0 on success, errors otherwise + */ +static int imx274_mode_regs(struct stimx274 *priv, int mode) +{ + int err = 0; + + err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_1]); + if (err) + return err; + + err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_2]); + if (err) + return err; + + err = imx274_write_table(priv, mode_table[mode]); + + return err; +} + +/* + * imx274_start_stream - Function for starting stream per mode index + * @priv: Pointer to device structure + * + * Return: 0 on success, errors otherwise + */ +static int imx274_start_stream(struct stimx274 *priv) +{ + int err = 0; + + /* + * Refer to "Standby Cancel Sequence when using CSI-2" in + * imx274 datasheet, it should wait 10ms or more here. + * give it 1 extra ms for margin + */ + msleep_range(11); + err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_3]); + if (err) + return err; + + /* + * Refer to "Standby Cancel Sequence when using CSI-2" in + * imx274 datasheet, it should wait 7ms or more here. + * give it 1 extra ms for margin + */ + msleep_range(8); + err = imx274_write_table(priv, mode_table[IMX274_MODE_START_STREAM_4]); + if (err) + return err; + + return 0; +} + +/* + * imx274_reset - Function called to reset the sensor + * @priv: Pointer to device structure + * @rst: Input value for determining the sensor's end state after reset + * + * Set the senor in reset and then + * if rst = 0, keep it in reset; + * if rst = 1, bring it out of reset. + * + */ +static void imx274_reset(struct stimx274 *priv, int rst) +{ + gpiod_set_value_cansleep(priv->reset_gpio, 0); + usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2); + gpiod_set_value_cansleep(priv->reset_gpio, !!rst); + usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2); +} + +/** + * imx274_s_ctrl - This is used to set the imx274 V4L2 controls + * @ctrl: V4L2 control to be set + * + * This function is used to set the V4L2 controls for the imx274 sensor. + * + * Return: 0 on success, errors otherwise + */ +static int imx274_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct v4l2_subdev *sd = ctrl_to_sd(ctrl); + struct stimx274 *imx274 = to_imx274(sd); + int ret = -EINVAL; + + dev_dbg(&imx274->client->dev, + "%s : s_ctrl: %s, value: %d\n", __func__, + ctrl->name, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + dev_dbg(&imx274->client->dev, + "%s : set V4L2_CID_EXPOSURE\n", __func__); + ret = imx274_set_exposure(imx274, ctrl->val); + break; + + case V4L2_CID_GAIN: + dev_dbg(&imx274->client->dev, + "%s : set V4L2_CID_GAIN\n", __func__); + ret = imx274_set_gain(imx274, ctrl); + break; + + case V4L2_CID_VFLIP: + dev_dbg(&imx274->client->dev, + "%s : set V4L2_CID_VFLIP\n", __func__); + ret = imx274_set_vflip(imx274, ctrl->val); + break; + + case V4L2_CID_TEST_PATTERN: + dev_dbg(&imx274->client->dev, + "%s : set V4L2_CID_TEST_PATTERN\n", __func__); + ret = imx274_set_test_pattern(imx274, ctrl->val); + break; + } + + return ret; +} + +/** + * imx274_get_fmt - Get the pad format + * @sd: Pointer to V4L2 Sub device structure + * @cfg: Pointer to sub device pad information structure + * @fmt: Pointer to pad level media bus format + * + * This function is used to get the pad format information. + * + * Return: 0 on success + */ +static int imx274_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct stimx274 *imx274 = to_imx274(sd); + + mutex_lock(&imx274->lock); + fmt->format = imx274->format; + mutex_unlock(&imx274->lock); + return 0; +} + +/** + * imx274_set_fmt - This is used to set the pad format + * @sd: Pointer to V4L2 Sub device structure + * @cfg: Pointer to sub device pad information structure + * @format: Pointer to pad level media bus format + * + * This function is used to set the pad format. + * + * Return: 0 on success + */ +static int imx274_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct v4l2_mbus_framefmt *fmt = &format->format; + struct stimx274 *imx274 = to_imx274(sd); + struct i2c_client *client = imx274->client; + int index; + + dev_dbg(&client->dev, + "%s: width = %d height = %d code = %d mbus_code = %d\n", + __func__, fmt->width, fmt->height, fmt->code, + imx274_formats[imx274->mode_index].mbus_code); + + mutex_lock(&imx274->lock); + + for (index = 0; index < ARRAY_SIZE(imx274_formats); index++) { + if (imx274_formats[index].size.width == fmt->width && + imx274_formats[index].size.height == fmt->height) + break; + } + + if (index >= ARRAY_SIZE(imx274_formats)) { + /* default to first format */ + index = 0; + } + + imx274->mode_index = index; + + if (fmt->width > IMX274_MAX_WIDTH) + fmt->width = IMX274_MAX_WIDTH; + if (fmt->height > IMX274_MAX_HEIGHT) + fmt->height = IMX274_MAX_HEIGHT; + fmt->width = fmt->width & (~IMX274_MASK_LSB_2_BITS); + fmt->height = fmt->height & (~IMX274_MASK_LSB_2_BITS); + fmt->field = V4L2_FIELD_NONE; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) + cfg->try_fmt = *fmt; + else + imx274->format = *fmt; + + mutex_unlock(&imx274->lock); + return 0; +} + +/** + * imx274_g_frame_interval - Get the frame interval + * @sd: Pointer to V4L2 Sub device structure + * @fi: Pointer to V4l2 Sub device frame interval structure + * + * This function is used to get the frame interval. + * + * Return: 0 on success + */ +static int imx274_g_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *fi) +{ + struct stimx274 *imx274 = to_imx274(sd); + + fi->interval = imx274->frame_interval; + dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n", + __func__, imx274->frame_interval.numerator, + imx274->frame_interval.denominator); + + return 0; +} + +/** + * imx274_s_frame_interval - Set the frame interval + * @sd: Pointer to V4L2 Sub device structure + * @fi: Pointer to V4l2 Sub device frame interval structure + * + * This function is used to set the frame intervavl. + * + * Return: 0 on success + */ +static int imx274_s_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *fi) +{ + struct stimx274 *imx274 = to_imx274(sd); + struct v4l2_ctrl *ctrl = imx274->ctrls.exposure; + int min, max, def; + int ret; + + mutex_lock(&imx274->lock); + ret = imx274_set_frame_interval(imx274, fi->interval); + + if (!ret) { + /* + * exposure time range is decided by frame interval + * need to update it after frame interal changes + */ + min = IMX274_MIN_EXPOSURE_TIME; + max = fi->interval.numerator * 1000000 + / fi->interval.denominator; + def = max; + if (__v4l2_ctrl_modify_range(ctrl, min, max, 1, def)) { + dev_err(&imx274->client->dev, + "Exposure ctrl range update failed\n"); + goto unlock; + } + + /* update exposure time accordingly */ + imx274_set_exposure(imx274, imx274->ctrls.exposure->val); + + dev_dbg(&imx274->client->dev, "set frame interval to %uus\n", + fi->interval.numerator * 1000000 + / fi->interval.denominator); + } + +unlock: + mutex_unlock(&imx274->lock); + + return ret; +} + +/** + * imx274_load_default - load default control values + * @priv: Pointer to device structure + * + * Return: 0 on success, errors otherwise + */ +static int imx274_load_default(struct stimx274 *priv) +{ + int ret; + + /* load default control values */ + priv->frame_interval.numerator = 1; + priv->frame_interval.denominator = IMX274_DEF_FRAME_RATE; + priv->ctrls.exposure->val = 1000000 / IMX274_DEF_FRAME_RATE; + priv->ctrls.gain->val = IMX274_DEF_GAIN; + priv->ctrls.vflip->val = 0; + priv->ctrls.test_pattern->val = TEST_PATTERN_DISABLED; + + /* update frame rate */ + ret = imx274_set_frame_interval(priv, + priv->frame_interval); + if (ret) + return ret; + + /* update exposure time */ + ret = v4l2_ctrl_s_ctrl(priv->ctrls.exposure, priv->ctrls.exposure->val); + if (ret) + return ret; + + /* update gain */ + ret = v4l2_ctrl_s_ctrl(priv->ctrls.gain, priv->ctrls.gain->val); + if (ret) + return ret; + + /* update vflip */ + ret = v4l2_ctrl_s_ctrl(priv->ctrls.vflip, priv->ctrls.vflip->val); + if (ret) + return ret; + + return 0; +} + +/** + * imx274_s_stream - It is used to start/stop the streaming. + * @sd: V4L2 Sub device + * @on: Flag (True / False) + * + * This function controls the start or stop of streaming for the + * imx274 sensor. + * + * Return: 0 on success, errors otherwise + */ +static int imx274_s_stream(struct v4l2_subdev *sd, int on) +{ + struct stimx274 *imx274 = to_imx274(sd); + int ret = 0; + + dev_dbg(&imx274->client->dev, "%s : %s, mode index = %d\n", __func__, + on ? "Stream Start" : "Stream Stop", imx274->mode_index); + + mutex_lock(&imx274->lock); + + if (on) { + /* load mode registers */ + ret = imx274_mode_regs(imx274, imx274->mode_index); + if (ret) + goto fail; + + /* + * update frame rate & expsoure. if the last mode is different, + * HMAX could be changed. As the result, frame rate & exposure + * are changed. + * gain is not affected. + */ + ret = imx274_set_frame_interval(imx274, + imx274->frame_interval); + if (ret) + goto fail; + + /* update exposure time */ + ret = __v4l2_ctrl_s_ctrl(imx274->ctrls.exposure, + imx274->ctrls.exposure->val); + if (ret) + goto fail; + + /* start stream */ + ret = imx274_start_stream(imx274); + if (ret) + goto fail; + } else { + /* stop stream */ + ret = imx274_write_table(imx274, + mode_table[IMX274_MODE_STOP_STREAM]); + if (ret) + goto fail; + } + + mutex_unlock(&imx274->lock); + dev_dbg(&imx274->client->dev, + "%s : Done: mode = %d\n", __func__, imx274->mode_index); + return 0; + +fail: + mutex_unlock(&imx274->lock); + dev_err(&imx274->client->dev, "s_stream failed\n"); + return ret; +} + +/* + * imx274_get_frame_length - Function for obtaining current frame length + * @priv: Pointer to device structure + * @val: Pointer to obainted value + * + * frame_length = vmax x (svr + 1), in unit of hmax. + * + * Return: 0 on success + */ +static int imx274_get_frame_length(struct stimx274 *priv, u32 *val) +{ + int err; + u16 svr; + u32 vmax; + u8 reg_val[3]; + + /* svr */ + err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]); + if (err) + goto fail; + + err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]); + if (err) + goto fail; + + svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; + + /* vmax */ + err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_3, ®_val[0]); + if (err) + goto fail; + + err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_2, ®_val[1]); + if (err) + goto fail; + + err = imx274_read_reg(priv, IMX274_FRAME_LENGTH_ADDR_1, ®_val[2]); + if (err) + goto fail; + + vmax = ((reg_val[2] & IMX274_MASK_LSB_3_BITS) << IMX274_SHIFT_16_BITS) + + (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; + + *val = vmax * (svr + 1); + + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + return err; +} + +static int imx274_clamp_coarse_time(struct stimx274 *priv, u32 *val, + u32 *frame_length) +{ + int err; + + err = imx274_get_frame_length(priv, frame_length); + if (err) + return err; + + if (*frame_length < min_frame_len[priv->mode_index]) + *frame_length = min_frame_len[priv->mode_index]; + + *val = *frame_length - *val; /* convert to raw shr */ + if (*val > *frame_length - IMX274_SHR_LIMIT_CONST) + *val = *frame_length - IMX274_SHR_LIMIT_CONST; + else if (*val < min_SHR[priv->mode_index]) + *val = min_SHR[priv->mode_index]; + + return 0; +} + +/* + * imx274_set_digital gain - Function called when setting digital gain + * @priv: Pointer to device structure + * @dgain: Value of digital gain. + * + * Digital gain has only 4 steps: 1x, 2x, 4x, and 8x + * + * Return: 0 on success + */ +static int imx274_set_digital_gain(struct stimx274 *priv, u32 dgain) +{ + u8 reg_val; + + reg_val = ffs(dgain); + + if (reg_val) + reg_val--; + + reg_val = clamp(reg_val, (u8)0, (u8)3); + + return imx274_write_reg(priv, IMX274_DIGITAL_GAIN_REG, + reg_val & IMX274_MASK_LSB_4_BITS); +} + +static inline void imx274_calculate_gain_regs(struct reg_8 regs[2], u16 gain) +{ + regs->addr = IMX274_ANALOG_GAIN_ADDR_MSB; + regs->val = (gain >> IMX274_SHIFT_8_BITS) & IMX274_MASK_LSB_3_BITS; + + (regs + 1)->addr = IMX274_ANALOG_GAIN_ADDR_LSB; + (regs + 1)->val = (gain) & IMX274_MASK_LSB_8_BITS; +} + +/* + * imx274_set_gain - Function called when setting gain + * @priv: Pointer to device structure + * @val: Value of gain. the real value = val << IMX274_GAIN_SHIFT; + * @ctrl: v4l2 control pointer + * + * Set the gain based on input value. + * The caller should hold the mutex lock imx274->lock if necessary + * + * Return: 0 on success + */ +static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl) +{ + struct reg_8 reg_list[2]; + int err; + u32 gain, analog_gain, digital_gain, gain_reg; + int i; + + gain = (u32)(ctrl->val); + + dev_dbg(&priv->client->dev, + "%s : input gain = %d.%d\n", __func__, + gain >> IMX274_GAIN_SHIFT, + ((gain & IMX274_GAIN_SHIFT_MASK) * 100) >> IMX274_GAIN_SHIFT); + + if (gain > IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN) + gain = IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN; + else if (gain < IMX274_MIN_GAIN) + gain = IMX274_MIN_GAIN; + + if (gain <= IMX274_MAX_ANALOG_GAIN) + digital_gain = 1; + else if (gain <= IMX274_MAX_ANALOG_GAIN * 2) + digital_gain = 2; + else if (gain <= IMX274_MAX_ANALOG_GAIN * 4) + digital_gain = 4; + else + digital_gain = IMX274_MAX_DIGITAL_GAIN; + + analog_gain = gain / digital_gain; + + dev_dbg(&priv->client->dev, + "%s : digital gain = %d, analog gain = %d.%d\n", + __func__, digital_gain, analog_gain >> IMX274_GAIN_SHIFT, + ((analog_gain & IMX274_GAIN_SHIFT_MASK) * 100) + >> IMX274_GAIN_SHIFT); + + err = imx274_set_digital_gain(priv, digital_gain); + if (err) + goto fail; + + /* convert to register value, refer to imx274 datasheet */ + gain_reg = (u32)IMX274_GAIN_CONST - + (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT) / analog_gain; + if (gain_reg > IMX274_GAIN_REG_MAX) + gain_reg = IMX274_GAIN_REG_MAX; + + imx274_calculate_gain_regs(reg_list, (u16)gain_reg); + + for (i = 0; i < ARRAY_SIZE(reg_list); i++) { + err = imx274_write_reg(priv, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + if (IMX274_GAIN_CONST - gain_reg == 0) { + err = -EINVAL; + goto fail; + } + + /* convert register value back to gain value */ + ctrl->val = (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT) + / (IMX274_GAIN_CONST - gain_reg) * digital_gain; + + dev_dbg(&priv->client->dev, + "%s : GAIN control success, gain_reg = %d, new gain = %d\n", + __func__, gain_reg, ctrl->val); + + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + return err; +} + +static inline void imx274_calculate_coarse_time_regs(struct reg_8 regs[2], + u32 coarse_time) +{ + regs->addr = IMX274_COARSE_TIME_ADDR_MSB; + regs->val = (coarse_time >> IMX274_SHIFT_8_BITS) + & IMX274_MASK_LSB_8_BITS; + (regs + 1)->addr = IMX274_COARSE_TIME_ADDR_LSB; + (regs + 1)->val = (coarse_time) & IMX274_MASK_LSB_8_BITS; +} + +/* + * imx274_set_coarse_time - Function called when setting SHR value + * @priv: Pointer to device structure + * @val: Value for exposure time in number of line_length, or [HMAX] + * + * Set SHR value based on input value. + * + * Return: 0 on success + */ +static int imx274_set_coarse_time(struct stimx274 *priv, u32 *val) +{ + struct reg_8 reg_list[2]; + int err; + u32 coarse_time, frame_length; + int i; + + coarse_time = *val; + + /* convert exposure_time to appropriate SHR value */ + err = imx274_clamp_coarse_time(priv, &coarse_time, &frame_length); + if (err) + goto fail; + + /* prepare SHR registers */ + imx274_calculate_coarse_time_regs(reg_list, coarse_time); + + /* write to SHR registers */ + for (i = 0; i < ARRAY_SIZE(reg_list); i++) { + err = imx274_write_reg(priv, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + *val = frame_length - coarse_time; + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + return err; +} + +/* + * imx274_set_exposure - Function called when setting exposure time + * @priv: Pointer to device structure + * @val: Variable for exposure time, in the unit of micro-second + * + * Set exposure time based on input value. + * The caller should hold the mutex lock imx274->lock if necessary + * + * Return: 0 on success + */ +static int imx274_set_exposure(struct stimx274 *priv, int val) +{ + int err; + u16 hmax; + u8 reg_val[2]; + u32 coarse_time; /* exposure time in unit of line (HMAX)*/ + + dev_dbg(&priv->client->dev, + "%s : EXPOSURE control input = %d\n", __func__, val); + + /* step 1: convert input exposure_time (val) into number of 1[HMAX] */ + + /* obtain HMAX value */ + err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]); + if (err) + goto fail; + err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]); + if (err) + goto fail; + hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; + if (hmax == 0) { + err = -EINVAL; + goto fail; + } + + coarse_time = (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2 * val + - nocpiop[priv->mode_index]) / hmax; + + /* step 2: convert exposure_time into SHR value */ + + /* set SHR */ + err = imx274_set_coarse_time(priv, &coarse_time); + if (err) + goto fail; + + priv->ctrls.exposure->val = + (coarse_time * hmax + nocpiop[priv->mode_index]) + / (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2); + + dev_dbg(&priv->client->dev, + "%s : EXPOSURE control success\n", __func__); + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + + return err; +} + +/* + * imx274_set_vflip - Function called when setting vertical flip + * @priv: Pointer to device structure + * @val: Value for vflip setting + * + * Set vertical flip based on input value. + * val = 0: normal, no vertical flip + * val = 1: vertical flip enabled + * The caller should hold the mutex lock imx274->lock if necessary + * + * Return: 0 on success + */ +static int imx274_set_vflip(struct stimx274 *priv, int val) +{ + int err; + + err = imx274_write_reg(priv, IMX274_VFLIP_REG, val); + if (err) { + dev_err(&priv->client->dev, "VFILP control error\n"); + return err; + } + + dev_dbg(&priv->client->dev, + "%s : VFLIP control success\n", __func__); + + return 0; +} + +/* + * imx274_set_test_pattern - Function called when setting test pattern + * @priv: Pointer to device structure + * @val: Variable for test pattern + * + * Set to different test patterns based on input value. + * + * Return: 0 on success + */ +static int imx274_set_test_pattern(struct stimx274 *priv, int val) +{ + int err = 0; + + if (val == TEST_PATTERN_DISABLED) { + err = imx274_write_table(priv, imx274_tp_disabled); + } else if (val <= TEST_PATTERN_V_COLOR_BARS) { + err = imx274_write_reg(priv, IMX274_TEST_PATTERN_REG, val - 1); + if (!err) + err = imx274_write_table(priv, imx274_tp_regs); + } else { + err = -EINVAL; + } + + if (!err) + dev_dbg(&priv->client->dev, + "%s : TEST PATTERN control success\n", __func__); + else + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + + return err; +} + +static inline void imx274_calculate_frame_length_regs(struct reg_8 regs[3], + u32 frame_length) +{ + regs->addr = IMX274_FRAME_LENGTH_ADDR_1; + regs->val = (frame_length >> IMX274_SHIFT_16_BITS) + & IMX274_MASK_LSB_4_BITS; + (regs + 1)->addr = IMX274_FRAME_LENGTH_ADDR_2; + (regs + 1)->val = (frame_length >> IMX274_SHIFT_8_BITS) + & IMX274_MASK_LSB_8_BITS; + (regs + 2)->addr = IMX274_FRAME_LENGTH_ADDR_3; + (regs + 2)->val = (frame_length) & IMX274_MASK_LSB_8_BITS; +} + +/* + * imx274_set_frame_length - Function called when setting frame length + * @priv: Pointer to device structure + * @val: Variable for frame length (= VMAX, i.e. vertical drive period length) + * + * Set frame length based on input value. + * + * Return: 0 on success + */ +static int imx274_set_frame_length(struct stimx274 *priv, u32 val) +{ + struct reg_8 reg_list[3]; + int err; + u32 frame_length; + int i; + + dev_dbg(&priv->client->dev, "%s : input length = %d\n", + __func__, val); + + frame_length = (u32)val; + + imx274_calculate_frame_length_regs(reg_list, frame_length); + for (i = 0; i < ARRAY_SIZE(reg_list); i++) { + err = imx274_write_reg(priv, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + return err; +} + +/* + * imx274_set_frame_interval - Function called when setting frame interval + * @priv: Pointer to device structure + * @frame_interval: Variable for frame interval + * + * Change frame interval by updating VMAX value + * The caller should hold the mutex lock imx274->lock if necessary + * + * Return: 0 on success + */ +static int imx274_set_frame_interval(struct stimx274 *priv, + struct v4l2_fract frame_interval) +{ + int err; + u32 frame_length, req_frame_rate; + u16 svr; + u16 hmax; + u8 reg_val[2]; + + dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d", + __func__, frame_interval.numerator, + frame_interval.denominator); + + if (frame_interval.numerator == 0) { + err = -EINVAL; + goto fail; + } + + req_frame_rate = (u32)(frame_interval.denominator + / frame_interval.numerator); + + /* boundary check */ + if (req_frame_rate > max_frame_rate[priv->mode_index]) { + frame_interval.numerator = 1; + frame_interval.denominator = + max_frame_rate[priv->mode_index]; + } else if (req_frame_rate < IMX274_MIN_FRAME_RATE) { + frame_interval.numerator = 1; + frame_interval.denominator = IMX274_MIN_FRAME_RATE; + } + + /* + * VMAX = 1/frame_rate x 72M / (SVR+1) / HMAX + * frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX + */ + + /* SVR */ + err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]); + if (err) + goto fail; + err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]); + if (err) + goto fail; + svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; + dev_dbg(&priv->client->dev, + "%s : register SVR = %d\n", __func__, svr); + + /* HMAX */ + err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]); + if (err) + goto fail; + err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]); + if (err) + goto fail; + hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; + dev_dbg(&priv->client->dev, + "%s : register HMAX = %d\n", __func__, hmax); + + if (hmax == 0 || frame_interval.denominator == 0) { + err = -EINVAL; + goto fail; + } + + frame_length = IMX274_PIXCLK_CONST1 / (svr + 1) / hmax + * frame_interval.numerator + / frame_interval.denominator; + + err = imx274_set_frame_length(priv, frame_length); + if (err) + goto fail; + + priv->frame_interval = frame_interval; + return 0; + +fail: + dev_err(&priv->client->dev, "%s error = %d\n", __func__, err); + return err; +} + +static const struct v4l2_subdev_pad_ops imx274_pad_ops = { + .get_fmt = imx274_get_fmt, + .set_fmt = imx274_set_fmt, +}; + +static const struct v4l2_subdev_video_ops imx274_video_ops = { + .g_frame_interval = imx274_g_frame_interval, + .s_frame_interval = imx274_s_frame_interval, + .s_stream = imx274_s_stream, +}; + +static const struct v4l2_subdev_ops imx274_subdev_ops = { + .pad = &imx274_pad_ops, + .video = &imx274_video_ops, +}; + +static const struct v4l2_ctrl_ops imx274_ctrl_ops = { + .s_ctrl = imx274_s_ctrl, +}; + +static const struct of_device_id imx274_of_id_table[] = { + { .compatible = "sony,imx274" }, + { } +}; +MODULE_DEVICE_TABLE(of, imx274_of_id_table); + +static const struct i2c_device_id imx274_id[] = { + { "IMX274", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, imx274_id); + +static int imx274_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct v4l2_subdev *sd; + struct stimx274 *imx274; + int ret; + + /* initialize imx274 */ + imx274 = devm_kzalloc(&client->dev, sizeof(*imx274), GFP_KERNEL); + if (!imx274) + return -ENOMEM; + + mutex_init(&imx274->lock); + + /* initialize regmap */ + imx274->regmap = devm_regmap_init_i2c(client, &imx274_regmap_config); + if (IS_ERR(imx274->regmap)) { + dev_err(&client->dev, + "regmap init failed: %ld\n", PTR_ERR(imx274->regmap)); + ret = -ENODEV; + goto err_regmap; + } + + /* initialize subdevice */ + imx274->client = client; + sd = &imx274->sd; + v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops); + strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; + + /* initialize subdev media pad */ + imx274->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&sd->entity, 1, &imx274->pad); + if (ret < 0) { + dev_err(&client->dev, + "%s : media entity init Failed %d\n", __func__, ret); + goto err_regmap; + } + + /* initialize sensor reset gpio */ + imx274->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(imx274->reset_gpio)) { + if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER) + dev_err(&client->dev, "Reset GPIO not setup in DT"); + ret = PTR_ERR(imx274->reset_gpio); + goto err_me; + } + + /* pull sensor out of reset */ + imx274_reset(imx274, 1); + + /* initialize controls */ + ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 2); + if (ret < 0) { + dev_err(&client->dev, + "%s : ctrl handler init Failed\n", __func__); + goto err_me; + } + + imx274->ctrls.handler.lock = &imx274->lock; + + /* add new controls */ + imx274->ctrls.test_pattern = v4l2_ctrl_new_std_menu_items( + &imx274->ctrls.handler, &imx274_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(tp_qmenu) - 1, 0, 0, tp_qmenu); + + imx274->ctrls.gain = v4l2_ctrl_new_std( + &imx274->ctrls.handler, + &imx274_ctrl_ops, + V4L2_CID_GAIN, IMX274_MIN_GAIN, + IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN, 1, + IMX274_DEF_GAIN); + + imx274->ctrls.exposure = v4l2_ctrl_new_std( + &imx274->ctrls.handler, + &imx274_ctrl_ops, + V4L2_CID_EXPOSURE, IMX274_MIN_EXPOSURE_TIME, + 1000000 / IMX274_DEF_FRAME_RATE, 1, + IMX274_MIN_EXPOSURE_TIME); + + imx274->ctrls.vflip = v4l2_ctrl_new_std( + &imx274->ctrls.handler, + &imx274_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + + imx274->sd.ctrl_handler = &imx274->ctrls.handler; + if (imx274->ctrls.handler.error) { + ret = imx274->ctrls.handler.error; + goto err_ctrls; + } + + /* setup default controls */ + ret = v4l2_ctrl_handler_setup(&imx274->ctrls.handler); + if (ret) { + dev_err(&client->dev, + "Error %d setup default controls\n", ret); + goto err_ctrls; + } + + /* initialize format */ + imx274->mode_index = IMX274_MODE_3840X2160; + imx274->format.width = imx274_formats[0].size.width; + imx274->format.height = imx274_formats[0].size.height; + imx274->format.field = V4L2_FIELD_NONE; + imx274->format.code = MEDIA_BUS_FMT_SRGGB10_1X10; + imx274->format.colorspace = V4L2_COLORSPACE_SRGB; + imx274->frame_interval.numerator = 1; + imx274->frame_interval.denominator = IMX274_DEF_FRAME_RATE; + + /* load default control values */ + ret = imx274_load_default(imx274); + if (ret) { + dev_err(&client->dev, + "%s : imx274_load_default failed %d\n", + __func__, ret); + goto err_ctrls; + } + + /* register subdevice */ + ret = v4l2_async_register_subdev(sd); + if (ret < 0) { + dev_err(&client->dev, + "%s : v4l2_async_register_subdev failed %d\n", + __func__, ret); + goto err_ctrls; + } + + dev_info(&client->dev, "imx274 : imx274 probe success !\n"); + return 0; + +err_ctrls: + v4l2_async_unregister_subdev(sd); + v4l2_ctrl_handler_free(sd->ctrl_handler); +err_me: + media_entity_cleanup(&sd->entity); +err_regmap: + mutex_destroy(&imx274->lock); + return ret; +} + +static int imx274_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct stimx274 *imx274 = to_imx274(sd); + + /* stop stream */ + imx274_write_table(imx274, mode_table[IMX274_MODE_STOP_STREAM]); + + v4l2_async_unregister_subdev(sd); + v4l2_ctrl_handler_free(sd->ctrl_handler); + media_entity_cleanup(&sd->entity); + mutex_destroy(&imx274->lock); + return 0; +} + +static struct i2c_driver imx274_i2c_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = imx274_of_id_table, + }, + .probe = imx274_probe, + .remove = imx274_remove, + .id_table = imx274_id, +}; + +module_i2c_driver(imx274_i2c_driver); + +MODULE_AUTHOR("Leon Luo <leonl@leopardimaging.com>"); +MODULE_DESCRIPTION("IMX274 CMOS Image Sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index a374e2a0ac3d..8b5f7d0435e4 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -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; diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c index bf0e821a2b93..2f1966bdc473 100644 --- a/drivers/media/i2c/max2175.c +++ b/drivers/media/i2c/max2175.c @@ -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; diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index 99b992e46702..b1665d97e0fd 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -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; diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index af7af0d14c69..bf7d06f3f21a 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -104,7 +104,6 @@ struct ov13858_reg_list { /* Link frequency config */ struct ov13858_link_freq_config { - u32 pixel_rate; u32 pixels_per_line; /* PLL registers for this link frequency */ @@ -238,11 +237,11 @@ static const struct ov13858_reg mode_4224x3136_regs[] = { {0x3800, 0x00}, {0x3801, 0x00}, {0x3802, 0x00}, - {0x3803, 0x00}, + {0x3803, 0x08}, {0x3804, 0x10}, {0x3805, 0x9f}, {0x3806, 0x0c}, - {0x3807, 0x5f}, + {0x3807, 0x57}, {0x3808, 0x10}, {0x3809, 0x80}, {0x380a, 0x0c}, @@ -948,6 +947,18 @@ static const char * const ov13858_test_pattern_menu[] = { #define OV13858_LINK_FREQ_INDEX_0 0 #define OV13858_LINK_FREQ_INDEX_1 1 +/* + * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample + * data rate => double data rate; number of lanes => 4; bits per pixel => 10 + */ +static u64 link_freq_to_pixel_rate(u64 f) +{ + f *= 2 * 4; + do_div(f, 10); + + return f; +} + /* Menu items for LINK_FREQ V4L2 control */ static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = { OV13858_LINK_FREQ_540MHZ, @@ -958,8 +969,6 @@ static const s64 link_freq_menu_items[OV13858_NUM_OF_LINK_FREQS] = { static const struct ov13858_link_freq_config link_freq_configs[OV13858_NUM_OF_LINK_FREQS] = { { - /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ - .pixel_rate = (OV13858_LINK_FREQ_540MHZ * 2 * 4) / 10, .pixels_per_line = OV13858_PPL_540MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_1080mbps), @@ -967,8 +976,6 @@ static const struct ov13858_link_freq_config } }, { - /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ - .pixel_rate = (OV13858_LINK_FREQ_270MHZ * 2 * 4) / 10, .pixels_per_line = OV13858_PPL_270MHZ, .reg_list = { .num_of_regs = ARRAY_SIZE(mipi_data_rate_540mbps), @@ -1385,6 +1392,8 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, s32 vblank_def; s32 vblank_min; s64 h_blank; + s64 pixel_rate; + s64 link_freq; mutex_lock(&ov13858->mutex); @@ -1400,9 +1409,10 @@ ov13858_set_pad_format(struct v4l2_subdev *sd, } else { ov13858->cur_mode = mode; __v4l2_ctrl_s_ctrl(ov13858->link_freq, mode->link_freq_index); - __v4l2_ctrl_s_ctrl_int64( - ov13858->pixel_rate, - link_freq_configs[mode->link_freq_index].pixel_rate); + link_freq = link_freq_menu_items[mode->link_freq_index]; + pixel_rate = link_freq_to_pixel_rate(link_freq); + __v4l2_ctrl_s_ctrl_int64(ov13858->pixel_rate, pixel_rate); + /* Update limits and set FPS to default */ vblank_def = ov13858->cur_mode->vts_def - ov13858->cur_mode->height; @@ -1617,6 +1627,10 @@ static int ov13858_init_controls(struct ov13858 *ov13858) s64 exposure_max; s64 vblank_def; s64 vblank_min; + s64 hblank; + s64 pixel_rate_min; + s64 pixel_rate_max; + const struct ov13858_mode *mode; int ret; ctrl_hdlr = &ov13858->ctrl_handler; @@ -1634,29 +1648,30 @@ static int ov13858_init_controls(struct ov13858 *ov13858) link_freq_menu_items); ov13858->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]); + pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]); /* By default, PIXEL_RATE is read only */ ov13858->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov13858_ctrl_ops, - V4L2_CID_PIXEL_RATE, 0, - link_freq_configs[0].pixel_rate, 1, - link_freq_configs[0].pixel_rate); + V4L2_CID_PIXEL_RATE, + pixel_rate_min, pixel_rate_max, + 1, pixel_rate_max); - vblank_def = ov13858->cur_mode->vts_def - ov13858->cur_mode->height; - vblank_min = ov13858->cur_mode->vts_min - ov13858->cur_mode->height; + mode = ov13858->cur_mode; + vblank_def = mode->vts_def - mode->height; + vblank_min = mode->vts_min - mode->height; ov13858->vblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_VBLANK, - vblank_min, - OV13858_VTS_MAX - ov13858->cur_mode->height, 1, + vblank_min, OV13858_VTS_MAX - mode->height, 1, vblank_def); + hblank = link_freq_configs[mode->link_freq_index].pixels_per_line - + mode->width; ov13858->hblank = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_HBLANK, - OV13858_PPL_540MHZ - ov13858->cur_mode->width, - OV13858_PPL_540MHZ - ov13858->cur_mode->width, - 1, - OV13858_PPL_540MHZ - ov13858->cur_mode->width); + hblank, hblank, 1, hblank); ov13858->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - exposure_max = ov13858->cur_mode->vts_def - 8; + exposure_max = mode->vts_def - 8; ov13858->exposure = v4l2_ctrl_new_std( ctrl_hdlr, &ov13858_ctrl_ops, V4L2_CID_EXPOSURE, OV13858_EXPOSURE_MIN, @@ -1746,7 +1761,7 @@ static int ov13858_probe(struct i2c_client *client, goto error_handler_free; } - ret = v4l2_async_register_subdev(&ov13858->sd); + ret = v4l2_async_register_subdev_sensor_common(&ov13858->sd); if (ret < 0) goto error_media_entity; diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index e6d0c1f64f0b..518868388d65 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -685,7 +685,7 @@ static int ov2640_mask_set(struct i2c_client *client, static int ov2640_reset(struct i2c_client *client) { int ret; - const struct regval_list reset_seq[] = { + static const struct regval_list reset_seq[] = { {BANK_SEL, BANK_SEL_SENS}, {COM7, COM7_SRST}, ENDMARKER, @@ -1097,18 +1097,17 @@ static int ov2640_probe(struct i2c_client *client, return -EIO; } - priv = devm_kzalloc(&client->dev, sizeof(struct ov2640_priv), GFP_KERNEL); - if (!priv) { - dev_err(&adapter->dev, - "Failed to allocate memory for private data!\n"); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - } if (client->dev.of_node) { priv->clk = devm_clk_get(&client->dev, "xvclk"); if (IS_ERR(priv->clk)) - return -EPROBE_DEFER; - clk_prepare_enable(priv->clk); + return PTR_ERR(priv->clk); + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; } ret = ov2640_probe_dt(client, priv); @@ -1116,7 +1115,7 @@ static int ov2640_probe(struct i2c_client *client, goto err_clk; v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); - priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; v4l2_ctrl_handler_init(&priv->hdl, 2); v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 39a2269c0bee..c89ed6609738 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -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); diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 95ce90fdb876..34179d232a35 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -35,9 +35,18 @@ #define SENSOR_NAME "ov5647" -#define OV5647_SW_RESET 0x0103 -#define OV5647_REG_CHIPID_H 0x300A -#define OV5647_REG_CHIPID_L 0x300B +#define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5) +#define MIPI_CTRL00_BUS_IDLE BIT(2) +#define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0) + +#define OV5647_SW_STANDBY 0x0100 +#define OV5647_SW_RESET 0x0103 +#define OV5647_REG_CHIPID_H 0x300A +#define OV5647_REG_CHIPID_L 0x300B +#define OV5640_REG_PAD_OUT 0x300D +#define OV5647_REG_FRAME_OFF_NUMBER 0x4202 +#define OV5647_REG_MIPI_CTRL00 0x4800 +#define OV5647_REG_MIPI_CTRL14 0x4814 #define REG_TERM 0xfffe #define VAL_TERM 0xfe @@ -241,34 +250,43 @@ static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) u8 channel_id; int ret; - ret = ov5647_read(sd, 0x4814, &channel_id); + ret = ov5647_read(sd, OV5647_REG_MIPI_CTRL14, &channel_id); if (ret < 0) return ret; channel_id &= ~(3 << 6); - return ov5647_write(sd, 0x4814, channel_id | (channel << 6)); + return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, channel_id | (channel << 6)); } static int ov5647_stream_on(struct v4l2_subdev *sd) { int ret; - ret = ov5647_write(sd, 0x4202, 0x00); + ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_BUS_IDLE); if (ret < 0) return ret; - return ov5647_write(sd, 0x300D, 0x00); + ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x00); + if (ret < 0) + return ret; + + return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x00); } static int ov5647_stream_off(struct v4l2_subdev *sd) { int ret; - ret = ov5647_write(sd, 0x4202, 0x0f); + ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, MIPI_CTRL00_CLOCK_LANE_GATE + | MIPI_CTRL00_BUS_IDLE | MIPI_CTRL00_CLOCK_LANE_DISABLE); + if (ret < 0) + return ret; + + ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, 0x0f); if (ret < 0) return ret; - return ov5647_write(sd, 0x300D, 0x01); + return ov5647_write(sd, OV5640_REG_PAD_OUT, 0x01); } static int set_sw_standby(struct v4l2_subdev *sd, bool standby) @@ -276,7 +294,7 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby) int ret; u8 rdval; - ret = ov5647_read(sd, 0x0100, &rdval); + ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); if (ret < 0) return ret; @@ -285,7 +303,7 @@ static int set_sw_standby(struct v4l2_subdev *sd, bool standby) else rdval |= 0x01; - return ov5647_write(sd, 0x0100, rdval); + return ov5647_write(sd, OV5647_SW_STANDBY, rdval); } static int __sensor_init(struct v4l2_subdev *sd) @@ -294,7 +312,7 @@ static int __sensor_init(struct v4l2_subdev *sd) u8 resetval, rdval; struct i2c_client *client = v4l2_get_subdevdata(sd); - ret = ov5647_read(sd, 0x0100, &rdval); + ret = ov5647_read(sd, OV5647_SW_STANDBY, &rdval); if (ret < 0) return ret; @@ -309,18 +327,21 @@ static int __sensor_init(struct v4l2_subdev *sd) if (ret < 0) return ret; - ret = ov5647_read(sd, 0x0100, &resetval); + ret = ov5647_read(sd, OV5647_SW_STANDBY, &resetval); if (ret < 0) return ret; if (!(resetval & 0x01)) { dev_err(&client->dev, "Device was in SW standby"); - ret = ov5647_write(sd, 0x0100, 0x01); + ret = ov5647_write(sd, OV5647_SW_STANDBY, 0x01); if (ret < 0) return ret; } - return ov5647_write(sd, 0x4800, 0x04); + /* + * stream off to make the clock lane into LP-11 state. + */ + return ov5647_stream_off(sd); } static int ov5647_sensor_power(struct v4l2_subdev *sd, int on) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 6f7a1d6d2200..9f9196568eb8 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -390,7 +390,10 @@ static const struct ov5670_reg mode_2592x1944_regs[] = { {0x5792, 0x00}, {0x5793, 0x52}, {0x5794, 0xa3}, - {0x3503, 0x00} + {0x3503, 0x00}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const struct ov5670_reg mode_1296x972_regs[] = { @@ -653,7 +656,10 @@ static const struct ov5670_reg mode_1296x972_regs[] = { {0x5792, 0x00}, {0x5793, 0x52}, {0x5794, 0xa3}, - {0x3503, 0x00} + {0x3503, 0x00}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const struct ov5670_reg mode_648x486_regs[] = { @@ -916,7 +922,10 @@ static const struct ov5670_reg mode_648x486_regs[] = { {0x5792, 0x00}, {0x5793, 0x52}, {0x5794, 0xa3}, - {0x3503, 0x00} + {0x3503, 0x00}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const struct ov5670_reg mode_2560x1440_regs[] = { @@ -1178,7 +1187,10 @@ static const struct ov5670_reg mode_2560x1440_regs[] = { {0x5791, 0x06}, {0x5792, 0x00}, {0x5793, 0x52}, - {0x5794, 0xa3} + {0x5794, 0xa3}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const struct ov5670_reg mode_1280x720_regs[] = { @@ -1441,7 +1453,10 @@ static const struct ov5670_reg mode_1280x720_regs[] = { {0x5792, 0x00}, {0x5793, 0x52}, {0x5794, 0xa3}, - {0x3503, 0x00} + {0x3503, 0x00}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const struct ov5670_reg mode_640x360_regs[] = { @@ -1704,7 +1719,10 @@ static const struct ov5670_reg mode_640x360_regs[] = { {0x5792, 0x00}, {0x5793, 0x52}, {0x5794, 0xa3}, - {0x3503, 0x00} + {0x3503, 0x00}, + {0x5045, 0x05}, + {0x4003, 0x40}, + {0x5048, 0x40} }; static const char * const ov5670_test_pattern_menu[] = { @@ -2323,8 +2341,6 @@ static int ov5670_start_streaming(struct ov5670 *ov5670) return ret; } - ov5670->streaming = true; - return 0; } @@ -2338,8 +2354,6 @@ static int ov5670_stop_streaming(struct ov5670 *ov5670) if (ret) dev_err(&client->dev, "%s failed to set stream\n", __func__); - ov5670->streaming = false; - /* Return success even if it was an error, as there is nothing the * caller can do about it. */ @@ -2370,6 +2384,7 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) ret = ov5670_stop_streaming(ov5670); pm_runtime_put(&client->dev); } + ov5670->streaming = enable; goto unlock_and_return; error: @@ -2514,7 +2529,7 @@ static int ov5670_probe(struct i2c_client *client) } /* Async register for subdev */ - ret = v4l2_async_register_subdev(&ov5670->sd); + ret = v4l2_async_register_subdev_sensor_common(&ov5670->sd); if (ret < 0) { err_msg = "v4l2_async_register_subdev() error"; goto error_entity_cleanup; diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c index 768f2950ea36..8975d16b2b24 100644 --- a/drivers/media/i2c/ov6650.c +++ b/drivers/media/i2c/ov6650.c @@ -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); diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index e88549f0e704..950a0acf85fb 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -213,6 +213,9 @@ struct ov7670_devtype { struct ov7670_format_struct; /* coming later */ struct ov7670_info { struct v4l2_subdev sd; +#if defined(CONFIG_MEDIA_CONTROLLER) + struct media_pad pad; +#endif struct v4l2_ctrl_handler hdl; struct { /* gain cluster */ @@ -229,6 +232,7 @@ struct ov7670_info { struct v4l2_ctrl *saturation; struct v4l2_ctrl *hue; }; + struct v4l2_mbus_framefmt format; struct ov7670_format_struct *fmt; /* Current format */ struct clk *clk; struct gpio_desc *resetb_gpio; @@ -972,6 +976,9 @@ static int ov7670_try_fmt_internal(struct v4l2_subdev *sd, fmt->width = wsize->width; fmt->height = wsize->height; fmt->colorspace = ov7670_formats[index].colorspace; + + info->format = *fmt; + return 0; } @@ -985,6 +992,9 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, struct ov7670_format_struct *ovfmt; struct ov7670_win_size *wsize; struct ov7670_info *info = to_state(sd); +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + struct v4l2_mbus_framefmt *mbus_fmt; +#endif unsigned char com7; int ret; @@ -995,8 +1005,13 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, ret = ov7670_try_fmt_internal(sd, &format->format, NULL, NULL); if (ret) return ret; - cfg->try_fmt = format->format; +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad); + *mbus_fmt = format->format; return 0; +#else + return -ENOTTY; +#endif } ret = ov7670_try_fmt_internal(sd, &format->format, &ovfmt, &wsize); @@ -1038,6 +1053,30 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, return 0; } +static int ov7670_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *format) +{ + struct ov7670_info *info = to_state(sd); +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + struct v4l2_mbus_framefmt *mbus_fmt; +#endif + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0); + format->format = *mbus_fmt; + return 0; +#else + return -ENOTTY; +#endif + } else { + format->format = info->format; + } + + return 0; +} + /* * Implement G/S_PARM. There is a "high quality" mode we could try * to do someday; for now, we just do the frame rate tweak. @@ -1505,6 +1544,46 @@ static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_regis } #endif +static int ov7670_s_power(struct v4l2_subdev *sd, int on) +{ + struct ov7670_info *info = to_state(sd); + + if (info->pwdn_gpio) + gpiod_set_value(info->pwdn_gpio, !on); + if (on && info->resetb_gpio) { + gpiod_set_value(info->resetb_gpio, 1); + usleep_range(500, 1000); + gpiod_set_value(info->resetb_gpio, 0); + usleep_range(3000, 5000); + } + + return 0; +} + +static void ov7670_get_default_format(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *format) +{ + struct ov7670_info *info = to_state(sd); + + format->width = info->devtype->win_sizes[0].width; + format->height = info->devtype->win_sizes[0].height; + format->colorspace = info->fmt->colorspace; + format->code = info->fmt->mbus_code; + format->field = V4L2_FIELD_NONE; +} + +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static int ov7670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct v4l2_mbus_framefmt *format = + v4l2_subdev_get_try_format(sd, fh->pad, 0); + + ov7670_get_default_format(sd, format); + + return 0; +} +#endif + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops ov7670_core_ops = { @@ -1525,6 +1604,7 @@ static const struct v4l2_subdev_pad_ops ov7670_pad_ops = { .enum_frame_interval = ov7670_enum_frame_interval, .enum_frame_size = ov7670_enum_frame_size, .enum_mbus_code = ov7670_enum_mbus_code, + .get_fmt = ov7670_get_fmt, .set_fmt = ov7670_set_fmt, }; @@ -1534,6 +1614,12 @@ static const struct v4l2_subdev_ops ov7670_ops = { .pad = &ov7670_pad_ops, }; +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API +static const struct v4l2_subdev_internal_ops ov7670_subdev_internal_ops = { + .open = ov7670_open, +}; +#endif + /* ----------------------------------------------------------------------- */ static const struct ov7670_devtype ov7670_devdata[] = { @@ -1586,6 +1672,11 @@ static int ov7670_probe(struct i2c_client *client, sd = &info->sd; v4l2_i2c_subdev_init(sd, client, &ov7670_ops); +#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + sd->internal_ops = &ov7670_subdev_internal_ops; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; +#endif + info->clock_speed = 30; /* default: a guess */ if (client->dev.platform_data) { struct ov7670_config *config = client->dev.platform_data; @@ -1619,29 +1710,34 @@ static int ov7670_probe(struct i2c_client *client, if (ret) return ret; - ret = ov7670_init_gpio(client, info); - if (ret) - goto clk_disable; - info->clock_speed = clk_get_rate(info->clk) / 1000000; if (info->clock_speed < 10 || info->clock_speed > 48) { ret = -EINVAL; goto clk_disable; } + ret = ov7670_init_gpio(client, info); + if (ret) + goto clk_disable; + + ov7670_s_power(sd, 1); + /* Make sure it's an ov7670 */ ret = ov7670_detect(sd); if (ret) { v4l_dbg(1, debug, client, "chip found @ 0x%x (%s) is not an ov7670 chip.\n", client->addr << 1, client->adapter->name); - goto clk_disable; + goto power_off; } v4l_info(client, "chip found @ 0x%02x (%s)\n", client->addr << 1, client->adapter->name); info->devtype = &ov7670_devdata[id->driver_data]; info->fmt = &ov7670_formats[0]; + + ov7670_get_default_format(sd, &info->format); + info->clkrc = 0; /* Set default frame rate to 30 fps */ @@ -1688,16 +1784,31 @@ static int ov7670_probe(struct i2c_client *client, v4l2_ctrl_auto_cluster(2, &info->auto_exposure, V4L2_EXPOSURE_MANUAL, false); v4l2_ctrl_cluster(2, &info->saturation); + +#if defined(CONFIG_MEDIA_CONTROLLER) + info->pad.flags = MEDIA_PAD_FL_SOURCE; + info->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; + ret = media_entity_pads_init(&info->sd.entity, 1, &info->pad); + if (ret < 0) + goto hdl_free; +#endif + v4l2_ctrl_handler_setup(&info->hdl); ret = v4l2_async_register_subdev(&info->sd); if (ret < 0) - goto hdl_free; + goto entity_cleanup; return 0; +entity_cleanup: +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&info->sd.entity); +#endif hdl_free: v4l2_ctrl_handler_free(&info->hdl); +power_off: + ov7670_s_power(sd, 0); clk_disable: clk_disable_unprepare(info->clk); return ret; @@ -1712,6 +1823,10 @@ static int ov7670_remove(struct i2c_client *client) v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(&info->hdl); clk_disable_unprepare(info->clk); +#if defined(CONFIG_MEDIA_CONTROLLER) + media_entity_cleanup(&info->sd.entity); +#endif + ov7670_s_power(sd, 0); return 0; } diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 6ffb460e8589..69433e1e2533 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -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) diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 700f433261d0..e6b717b83b18 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -1239,6 +1239,10 @@ static int smiapp_power_on(struct device *dev) sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk); usleep_range(sleep, sleep); + mutex_lock(&sensor->mutex); + + sensor->active = true; + /* * Failures to respond to the address change command have been noticed. * Those failures seem to be caused by the sensor requiring a longer @@ -1313,7 +1317,7 @@ static int smiapp_power_on(struct device *dev) rval = smiapp_write(sensor, SMIAPP_REG_U8_DPHY_CTRL, SMIAPP_DPHY_CTRL_UI); if (rval < 0) - return rval; + goto out_cci_addr_fail; rval = smiapp_call_quirk(sensor, post_poweron); if (rval) { @@ -1321,28 +1325,28 @@ static int smiapp_power_on(struct device *dev) goto out_cci_addr_fail; } - /* Are we still initialising...? If yes, return here. */ - if (!sensor->pixel_array) - return 0; + /* Are we still initialising...? If not, proceed with control setup. */ + if (sensor->pixel_array) { + rval = __v4l2_ctrl_handler_setup( + &sensor->pixel_array->ctrl_handler); + if (rval) + goto out_cci_addr_fail; - rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->ctrl_handler); - if (rval) - goto out_cci_addr_fail; + rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler); + if (rval) + goto out_cci_addr_fail; - rval = v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler); - if (rval) - goto out_cci_addr_fail; + rval = smiapp_update_mode(sensor); + if (rval < 0) + goto out_cci_addr_fail; + } - mutex_lock(&sensor->mutex); - rval = smiapp_update_mode(sensor); mutex_unlock(&sensor->mutex); - if (rval < 0) - goto out_cci_addr_fail; return 0; out_cci_addr_fail: - + mutex_unlock(&sensor->mutex); gpiod_set_value(sensor->xshutdown, 0); clk_disable_unprepare(sensor->ext_clk); @@ -1360,6 +1364,8 @@ static int smiapp_power_off(struct device *dev) struct smiapp_sensor *sensor = container_of(ssd, struct smiapp_sensor, ssds[0]); + mutex_lock(&sensor->mutex); + /* * Currently power/clock to lens are enable/disabled separately * but they are essentially the same signals. So if the sensor is @@ -1372,6 +1378,10 @@ static int smiapp_power_off(struct device *dev) SMIAPP_REG_U8_SOFTWARE_RESET, SMIAPP_SOFTWARE_RESET); + sensor->active = false; + + mutex_unlock(&sensor->mutex); + gpiod_set_value(sensor->xshutdown, 0); clk_disable_unprepare(sensor->ext_clk); usleep_range(5000, 5000); @@ -1381,29 +1391,6 @@ static int smiapp_power_off(struct device *dev) return 0; } -static int smiapp_set_power(struct v4l2_subdev *subdev, int on) -{ - int rval; - - if (!on) { - pm_runtime_mark_last_busy(subdev->dev); - pm_runtime_put_autosuspend(subdev->dev); - - return 0; - } - - rval = pm_runtime_get_sync(subdev->dev); - if (rval >= 0) - return 0; - - if (rval != -EBUSY && rval != -EAGAIN) - pm_runtime_set_active(subdev->dev); - - pm_runtime_put(subdev->dev); - - return rval; -} - /* ----------------------------------------------------------------------------- * Video stream management */ @@ -1560,19 +1547,31 @@ out: static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable) { struct smiapp_sensor *sensor = to_smiapp_sensor(subdev); + struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); int rval; if (sensor->streaming == enable) return 0; if (enable) { + rval = pm_runtime_get_sync(&client->dev); + if (rval < 0) { + if (rval != -EBUSY && rval != -EAGAIN) + pm_runtime_set_active(&client->dev); + pm_runtime_put(&client->dev); + return rval; + } + sensor->streaming = true; + rval = smiapp_start_streaming(sensor); if (rval < 0) sensor->streaming = false; } else { rval = smiapp_stop_streaming(sensor); sensor->streaming = false; + pm_runtime_mark_last_busy(&client->dev); + pm_runtime_put_autosuspend(&client->dev); } return rval; @@ -2650,7 +2649,6 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) struct smiapp_subdev *ssd = to_smiapp_subdev(sd); struct smiapp_sensor *sensor = ssd->sensor; unsigned int i; - int rval; mutex_lock(&sensor->mutex); @@ -2677,22 +2675,6 @@ static int smiapp_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) mutex_unlock(&sensor->mutex); - rval = pm_runtime_get_sync(sd->dev); - if (rval >= 0) - return 0; - - if (rval != -EBUSY && rval != -EAGAIN) - pm_runtime_set_active(sd->dev); - pm_runtime_put(sd->dev); - - return rval; -} - -static int smiapp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - pm_runtime_mark_last_busy(sd->dev); - pm_runtime_put_autosuspend(sd->dev); - return 0; } @@ -2700,10 +2682,6 @@ static const struct v4l2_subdev_video_ops smiapp_video_ops = { .s_stream = smiapp_set_stream, }; -static const struct v4l2_subdev_core_ops smiapp_core_ops = { - .s_power = smiapp_set_power, -}; - static const struct v4l2_subdev_pad_ops smiapp_pad_ops = { .enum_mbus_code = smiapp_enum_mbus_code, .get_fmt = smiapp_get_format, @@ -2718,7 +2696,6 @@ static const struct v4l2_subdev_sensor_ops smiapp_sensor_ops = { }; static const struct v4l2_subdev_ops smiapp_ops = { - .core = &smiapp_core_ops, .video = &smiapp_video_ops, .pad = &smiapp_pad_ops, .sensor = &smiapp_sensor_ops, @@ -2732,12 +2709,10 @@ static const struct v4l2_subdev_internal_ops smiapp_internal_src_ops = { .registered = smiapp_registered, .unregistered = smiapp_unregistered, .open = smiapp_open, - .close = smiapp_close, }; static const struct v4l2_subdev_internal_ops smiapp_internal_ops = { .open = smiapp_open, - .close = smiapp_close, }; /* ----------------------------------------------------------------------------- @@ -2829,12 +2804,10 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) /* NVM size is not mandatory */ fwnode_property_read_u32(fwnode, "nokia,nvm-size", &hwcfg->nvm_size); - rval = fwnode_property_read_u32(fwnode, "clock-frequency", + rval = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", &hwcfg->ext_clk); - if (rval) { - dev_warn(dev, "can't get clock-frequency\n"); - goto out_err; - } + if (rval) + dev_info(dev, "can't get clock-frequency\n"); dev_dbg(dev, "nvm %d, clk %d, mode %d\n", hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode); @@ -2894,18 +2867,46 @@ static int smiapp_probe(struct i2c_client *client, } sensor->ext_clk = devm_clk_get(&client->dev, NULL); - if (IS_ERR(sensor->ext_clk)) { + if (PTR_ERR(sensor->ext_clk) == -ENOENT) { + dev_info(&client->dev, "no clock defined, continuing...\n"); + sensor->ext_clk = NULL; + } else if (IS_ERR(sensor->ext_clk)) { dev_err(&client->dev, "could not get clock (%ld)\n", PTR_ERR(sensor->ext_clk)); return -EPROBE_DEFER; } - rval = clk_set_rate(sensor->ext_clk, sensor->hwcfg->ext_clk); - if (rval < 0) { - dev_err(&client->dev, - "unable to set clock freq to %u\n", + if (sensor->ext_clk) { + if (sensor->hwcfg->ext_clk) { + unsigned long rate; + + rval = clk_set_rate(sensor->ext_clk, + sensor->hwcfg->ext_clk); + if (rval < 0) { + dev_err(&client->dev, + "unable to set clock freq to %u\n", + sensor->hwcfg->ext_clk); + return rval; + } + + rate = clk_get_rate(sensor->ext_clk); + if (rate != sensor->hwcfg->ext_clk) { + dev_err(&client->dev, + "can't set clock freq, asked for %u but got %lu\n", + sensor->hwcfg->ext_clk, rate); + return rval; + } + } else { + sensor->hwcfg->ext_clk = clk_get_rate(sensor->ext_clk); + dev_dbg(&client->dev, "obtained clock freq %u\n", + sensor->hwcfg->ext_clk); + } + } else if (sensor->hwcfg->ext_clk) { + dev_dbg(&client->dev, "assuming clock freq %u\n", sensor->hwcfg->ext_clk); - return rval; + } else { + dev_err(&client->dev, "unable to obtain clock freq\n"); + return -EINVAL; } sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown", @@ -3092,7 +3093,7 @@ static int smiapp_probe(struct i2c_client *client, if (rval < 0) goto out_media_entity_cleanup; - rval = v4l2_async_register_subdev(&sensor->src->sd); + rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd); if (rval < 0) goto out_media_entity_cleanup; diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c index d6779e35d36f..145653dc81da 100644 --- a/drivers/media/i2c/smiapp/smiapp-regs.c +++ b/drivers/media/i2c/smiapp/smiapp-regs.c @@ -231,6 +231,9 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val) len != SMIAPP_REG_32BIT) || flags) return -EINVAL; + if (!sensor->active) + return 0; + msg.addr = client->addr; msg.flags = 0; /* Write */ msg.len = 2 + len; diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index f74d695018b9..e6a5ab402d7f 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -206,6 +206,7 @@ struct smiapp_sensor { u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */ u8 frame_skip; + bool active; /* is the sensor powered on? */ u16 embedded_start; /* embedded data start line */ u16 embedded_end; u16 image_start; /* image data start line */ diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index 0146d1f7aacb..c63948989688 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -335,8 +335,8 @@ static void ov9640_res_roundup(u32 *width, u32 *height) { int i; enum { QQCIF, QQVGA, QCIF, QVGA, CIF, VGA, SXGA }; - int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 }; - int res_y[] = { 72, 120, 144, 240, 288, 480, 960 }; + static const int res_x[] = { 88, 160, 176, 320, 352, 640, 1280 }; + static const int res_y[] = { 72, 120, 144, 240, 288, 480, 960 }; for (i = 0; i < ARRAY_SIZE(res_x); i++) { if (res_x[i] >= *width && res_y[i] >= *height) { @@ -675,12 +675,9 @@ static int ov9640_probe(struct i2c_client *client, return -EINVAL; } - priv = devm_kzalloc(&client->dev, sizeof(struct ov9640_priv), GFP_KERNEL); - if (!priv) { - dev_err(&client->dev, - "Failed to allocate memory for private data!\n"); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - } v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops); diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index cc07b7ae5407..755de2289c39 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -935,11 +935,9 @@ static int ov9740_probe(struct i2c_client *client, return -EINVAL; } - priv = devm_kzalloc(&client->dev, sizeof(struct ov9740_priv), GFP_KERNEL); - if (!priv) { - dev_err(&client->dev, "Failed to allocate private data!\n"); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - } v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops); v4l2_ctrl_handler_init(&priv->hdl, 13); diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index e6f5c363ccab..2b8181469b93 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -39,6 +39,7 @@ #include <linux/workqueue.h> #include <linux/v4l2-dv-timings.h> #include <linux/hdmi.h> +#include <media/cec.h> #include <media/v4l2-dv-timings.h> #include <media/v4l2-device.h> #include <media/v4l2-ctrls.h> @@ -63,6 +64,7 @@ MODULE_LICENSE("GPL"); #define I2C_MAX_XFER_SIZE (EDID_BLOCK_SIZE + 2) +#define POLL_INTERVAL_CEC_MS 10 #define POLL_INTERVAL_MS 1000 static const struct v4l2_dv_timings_cap tc358743_timings_cap = { @@ -106,6 +108,8 @@ struct tc358743_state { u8 csi_lanes_in_use; struct gpio_desc *reset_gpio; + + struct cec_adapter *cec_adap; }; static void tc358743_enable_interrupts(struct v4l2_subdev *sd, @@ -595,6 +599,7 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd) struct tc358743_platform_data *pdata = &state->pdata; u32 sys_freq; u32 lockdet_ref; + u32 cec_freq; u16 fh_min; u16 fh_max; @@ -626,6 +631,15 @@ static void tc358743_set_ref_clk(struct v4l2_subdev *sd) i2c_wr8_and_or(sd, NCO_F0_MOD, ~MASK_NCO_F0_MOD, (pdata->refclk_hz == 27000000) ? MASK_NCO_F0_MOD_27MHZ : 0x0); + + /* + * Trial and error suggests that the default register value + * of 656 is for a 42 MHz reference clock. Use that to derive + * a new value based on the actual reference clock. + */ + cec_freq = (656 * sys_freq) / 4200; + i2c_wr16(sd, CECHCLK, cec_freq); + i2c_wr16(sd, CECLCLK, cec_freq); } static void tc358743_set_csi_color_space(struct v4l2_subdev *sd) @@ -814,11 +828,17 @@ static void tc358743_initial_setup(struct v4l2_subdev *sd) struct tc358743_state *state = to_state(sd); struct tc358743_platform_data *pdata = &state->pdata; - /* CEC and IR are not supported by this driver */ - i2c_wr16_and_or(sd, SYSCTL, ~(MASK_CECRST | MASK_IRRST), - (MASK_CECRST | MASK_IRRST)); + /* + * IR is not supported by this driver. + * CEC is only enabled if needed. + */ + i2c_wr16_and_or(sd, SYSCTL, ~(MASK_IRRST | MASK_CECRST), + (MASK_IRRST | MASK_CECRST)); tc358743_reset(sd, MASK_CTXRST | MASK_HDMIRST); +#ifdef CONFIG_VIDEO_TC358743_CEC + tc358743_reset(sd, MASK_CECRST); +#endif tc358743_sleep_mode(sd, false); i2c_wr16(sd, FIFOCTL, pdata->fifo_level); @@ -842,6 +862,133 @@ static void tc358743_initial_setup(struct v4l2_subdev *sd) i2c_wr8(sd, VOUT_SET3, MASK_VOUT_EXTCNT); } +/* --------------- CEC --------------- */ + +#ifdef CONFIG_VIDEO_TC358743_CEC +static int tc358743_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct tc358743_state *state = adap->priv; + struct v4l2_subdev *sd = &state->sd; + + i2c_wr32(sd, CECIMSK, enable ? MASK_CECTIM | MASK_CECRIM : 0); + i2c_wr32(sd, CECICLR, MASK_CECTICLR | MASK_CECRICLR); + i2c_wr32(sd, CECEN, enable); + if (enable) + i2c_wr32(sd, CECREN, MASK_CECREN); + return 0; +} + +static int tc358743_cec_adap_monitor_all_enable(struct cec_adapter *adap, + bool enable) +{ + struct tc358743_state *state = adap->priv; + struct v4l2_subdev *sd = &state->sd; + u32 reg; + + reg = i2c_rd32(sd, CECRCTL1); + if (enable) + reg |= MASK_CECOTH; + else + reg &= ~MASK_CECOTH; + i2c_wr32(sd, CECRCTL1, reg); + return 0; +} + +static int tc358743_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +{ + struct tc358743_state *state = adap->priv; + struct v4l2_subdev *sd = &state->sd; + unsigned int la = 0; + + if (log_addr != CEC_LOG_ADDR_INVALID) { + la = i2c_rd32(sd, CECADD); + la |= 1 << log_addr; + } + i2c_wr32(sd, CECADD, la); + return 0; +} + +static int tc358743_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct tc358743_state *state = adap->priv; + struct v4l2_subdev *sd = &state->sd; + unsigned int i; + + i2c_wr32(sd, CECTCTL, + (cec_msg_is_broadcast(msg) ? MASK_CECBRD : 0) | + (signal_free_time - 1)); + for (i = 0; i < msg->len; i++) + i2c_wr32(sd, CECTBUF1 + i * 4, + msg->msg[i] | ((i == msg->len - 1) ? MASK_CECTEOM : 0)); + i2c_wr32(sd, CECTEN, MASK_CECTEN); + return 0; +} + +static const struct cec_adap_ops tc358743_cec_adap_ops = { + .adap_enable = tc358743_cec_adap_enable, + .adap_log_addr = tc358743_cec_adap_log_addr, + .adap_transmit = tc358743_cec_adap_transmit, + .adap_monitor_all_enable = tc358743_cec_adap_monitor_all_enable, +}; + +static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus, + bool *handled) +{ + struct tc358743_state *state = to_state(sd); + unsigned int cec_rxint, cec_txint; + unsigned int clr = 0; + + cec_rxint = i2c_rd32(sd, CECRSTAT); + cec_txint = i2c_rd32(sd, CECTSTAT); + + if (intstatus & MASK_CEC_RINT) + clr |= MASK_CECRICLR; + if (intstatus & MASK_CEC_TINT) + clr |= MASK_CECTICLR; + i2c_wr32(sd, CECICLR, clr); + + if ((intstatus & MASK_CEC_TINT) && cec_txint) { + if (cec_txint & MASK_CECTIEND) + cec_transmit_attempt_done(state->cec_adap, + CEC_TX_STATUS_OK); + else if (cec_txint & MASK_CECTIAL) + cec_transmit_attempt_done(state->cec_adap, + CEC_TX_STATUS_ARB_LOST); + else if (cec_txint & MASK_CECTIACK) + cec_transmit_attempt_done(state->cec_adap, + CEC_TX_STATUS_NACK); + else if (cec_txint & MASK_CECTIUR) { + /* + * Not sure when this bit is set. Treat + * it as an error for now. + */ + cec_transmit_attempt_done(state->cec_adap, + CEC_TX_STATUS_ERROR); + } + *handled = true; + } + if ((intstatus & MASK_CEC_RINT) && + (cec_rxint & MASK_CECRIEND)) { + struct cec_msg msg = {}; + unsigned int i; + unsigned int v; + + v = i2c_rd32(sd, CECRCTR); + msg.len = v & 0x1f; + for (i = 0; i < msg.len; i++) { + v = i2c_rd32(sd, CECRBUF1 + i * 4); + msg.msg[i] = v & 0xff; + } + cec_received_msg(state->cec_adap, &msg); + *handled = true; + } + i2c_wr16(sd, INTSTATUS, + intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)); +} + +#endif + /* --------------- IRQ --------------- */ static void tc358743_format_change(struct v4l2_subdev *sd) @@ -1296,6 +1443,15 @@ static int tc358743_isr(struct v4l2_subdev *sd, u32 status, bool *handled) intstatus &= ~MASK_HDMI_INT; } +#ifdef CONFIG_VIDEO_TC358743_CEC + if (intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)) { + tc358743_cec_isr(sd, intstatus, handled); + i2c_wr16(sd, INTSTATUS, + intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)); + intstatus &= ~(MASK_CEC_RINT | MASK_CEC_TINT); + } +#endif + if (intstatus & MASK_CSI_INT) { u32 csi_int = i2c_rd32(sd, CSI_INT); @@ -1325,13 +1481,18 @@ static irqreturn_t tc358743_irq_handler(int irq, void *dev_id) return handled ? IRQ_HANDLED : IRQ_NONE; } -static void tc358743_irq_poll_timer(unsigned long arg) +static void tc358743_irq_poll_timer(struct timer_list *t) { - struct tc358743_state *state = (struct tc358743_state *)arg; + struct tc358743_state *state = from_timer(state, t, timer); + unsigned int msecs; schedule_work(&state->work_i2c_poll); - - mod_timer(&state->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS)); + /* + * If CEC is present, then we need to poll more frequently, + * otherwise we will miss CEC messages. + */ + msecs = state->cec_adap ? POLL_INTERVAL_CEC_MS : POLL_INTERVAL_MS; + mod_timer(&state->timer, jiffies + msecs_to_jiffies(msecs)); } static void tc358743_work_i2c_poll(struct work_struct *work) @@ -1488,7 +1649,7 @@ static int tc358743_s_stream(struct v4l2_subdev *sd, int enable) { enable_stream(sd, enable); if (!enable) { - /* Put all lanes in PL-11 state (STOPSTATE) */ + /* Put all lanes in LP-11 state (STOPSTATE) */ tc358743_set_csi(sd); } @@ -1621,6 +1782,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, { struct tc358743_state *state = to_state(sd); u16 edid_len = edid->blocks * EDID_BLOCK_SIZE; + u16 pa; + int err; int i; v4l2_dbg(2, debug, sd, "%s, pad %d, start block %d, blocks %d\n", @@ -1638,6 +1801,12 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, edid->blocks = EDID_NUM_BLOCKS_MAX; return -E2BIG; } + pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, NULL); + err = cec_phys_addr_validate(pa, &pa, NULL); + if (err) + return err; + + cec_phys_addr_invalidate(state->cec_adap); tc358743_disable_edid(sd); @@ -1654,6 +1823,8 @@ static int tc358743_s_edid(struct v4l2_subdev *sd, state->edid_blocks_written = edid->blocks; + cec_s_phys_addr(state->cec_adap, pa, false); + if (tx_5v_power_present(sd)) tc358743_enable_edid(sd); @@ -1770,6 +1941,11 @@ static int tc358743_probe_of(struct tc358743_state *state) goto free_endpoint; } + if (endpoint->bus.mipi_csi2.num_data_lanes > 4) { + dev_err(dev, "invalid number of lanes\n"); + goto free_endpoint; + } + state->bus = endpoint->bus.mipi_csi2; ret = clk_prepare_enable(refclk); @@ -1867,6 +2043,7 @@ static int tc358743_probe(struct i2c_client *client, struct tc358743_state *state; struct tc358743_platform_data *pdata = client->dev.platform_data; struct v4l2_subdev *sd; + u16 irq_mask = MASK_HDMI_MSK | MASK_CSI_MSK; int err; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -1929,6 +2106,7 @@ static int tc358743_probe(struct i2c_client *client, } state->pad.flags = MEDIA_PAD_FL_SOURCE; + sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; err = media_entity_pads_init(&sd->entity, 1, &state->pad); if (err < 0) goto err_hdl; @@ -1945,6 +2123,17 @@ static int tc358743_probe(struct i2c_client *client, INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, tc358743_delayed_work_enable_hotplug); +#ifdef CONFIG_VIDEO_TC358743_CEC + state->cec_adap = cec_allocate_adapter(&tc358743_cec_adap_ops, + state, dev_name(&client->dev), + CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, CEC_MAX_LOG_ADDRS); + if (IS_ERR(state->cec_adap)) { + err = PTR_ERR(state->cec_adap); + goto err_hdl; + } + irq_mask |= MASK_CEC_RMSK | MASK_CEC_TMSK; +#endif + tc358743_initial_setup(sd); tc358743_s_dv_timings(sd, &default_timing); @@ -1964,15 +2153,22 @@ static int tc358743_probe(struct i2c_client *client, } else { INIT_WORK(&state->work_i2c_poll, tc358743_work_i2c_poll); - state->timer.data = (unsigned long)state; - state->timer.function = tc358743_irq_poll_timer; + timer_setup(&state->timer, tc358743_irq_poll_timer, 0); state->timer.expires = jiffies + msecs_to_jiffies(POLL_INTERVAL_MS); add_timer(&state->timer); } + err = cec_register_adapter(state->cec_adap, &client->dev); + if (err < 0) { + pr_err("%s: failed to register the cec device\n", __func__); + cec_delete_adapter(state->cec_adap); + state->cec_adap = NULL; + goto err_work_queues; + } + tc358743_enable_interrupts(sd, tx_5v_power_present(sd)); - i2c_wr16(sd, INTMASK, ~(MASK_HDMI_MSK | MASK_CSI_MSK) & 0xffff); + i2c_wr16(sd, INTMASK, ~irq_mask); err = v4l2_ctrl_handler_setup(sd->ctrl_handler); if (err) @@ -1984,6 +2180,7 @@ static int tc358743_probe(struct i2c_client *client, return 0; err_work_queues: + cec_unregister_adapter(state->cec_adap); if (!state->i2c_client->irq) flush_work(&state->work_i2c_poll); cancel_delayed_work(&state->delayed_work_enable_hotplug); @@ -2004,6 +2201,7 @@ static int tc358743_remove(struct i2c_client *client) flush_work(&state->work_i2c_poll); } cancel_delayed_work(&state->delayed_work_enable_hotplug); + cec_unregister_adapter(state->cec_adap); v4l2_async_unregister_subdev(sd); v4l2_device_unregister_subdev(sd); mutex_destroy(&state->confctl_mutex); diff --git a/drivers/media/i2c/tc358743_regs.h b/drivers/media/i2c/tc358743_regs.h index 657ef50f215f..227b46471793 100644 --- a/drivers/media/i2c/tc358743_regs.h +++ b/drivers/media/i2c/tc358743_regs.h @@ -193,8 +193,98 @@ #define CSI_START 0x0518 #define MASK_STRT 0x00000001 -#define CECEN 0x0600 -#define MASK_CECEN 0x0001 +/* *** CEC (32 bit) *** */ +#define CECHCLK 0x0028 /* 16 bits */ +#define MASK_CECHCLK (0x7ff << 0) + +#define CECLCLK 0x002a /* 16 bits */ +#define MASK_CECLCLK (0x7ff << 0) + +#define CECEN 0x0600 +#define MASK_CECEN 0x0001 + +#define CECADD 0x0604 +#define CECRST 0x0608 +#define MASK_CECRESET 0x0001 + +#define CECREN 0x060c +#define MASK_CECREN 0x0001 + +#define CECRCTL1 0x0614 +#define MASK_CECACKDIS (1 << 24) +#define MASK_CECHNC (3 << 20) +#define MASK_CECLNC (7 << 16) +#define MASK_CECMIN (7 << 12) +#define MASK_CECMAX (7 << 8) +#define MASK_CECDAT (7 << 4) +#define MASK_CECTOUT (3 << 2) +#define MASK_CECRIHLD (1 << 1) +#define MASK_CECOTH (1 << 0) + +#define CECRCTL2 0x0618 +#define MASK_CECSWAV3 (7 << 12) +#define MASK_CECSWAV2 (7 << 8) +#define MASK_CECSWAV1 (7 << 4) +#define MASK_CECSWAV0 (7 << 0) + +#define CECRCTL3 0x061c +#define MASK_CECWAV3 (7 << 20) +#define MASK_CECWAV2 (7 << 16) +#define MASK_CECWAV1 (7 << 12) +#define MASK_CECWAV0 (7 << 8) +#define MASK_CECACKEI (1 << 4) +#define MASK_CECMINEI (1 << 3) +#define MASK_CECMAXEI (1 << 2) +#define MASK_CECRSTEI (1 << 1) +#define MASK_CECWAVEI (1 << 0) + +#define CECTEN 0x0620 +#define MASK_CECTBUSY (1 << 1) +#define MASK_CECTEN (1 << 0) + +#define CECTCTL 0x0628 +#define MASK_CECSTRS (7 << 20) +#define MASK_CECSPRD (7 << 16) +#define MASK_CECDTRS (7 << 12) +#define MASK_CECDPRD (15 << 8) +#define MASK_CECBRD (1 << 4) +#define MASK_CECFREE (15 << 0) + +#define CECRSTAT 0x062c +#define MASK_CECRIWA (1 << 6) +#define MASK_CECRIOR (1 << 5) +#define MASK_CECRIACK (1 << 4) +#define MASK_CECRIMIN (1 << 3) +#define MASK_CECRIMAX (1 << 2) +#define MASK_CECRISTA (1 << 1) +#define MASK_CECRIEND (1 << 0) + +#define CECTSTAT 0x0630 +#define MASK_CECTIUR (1 << 4) +#define MASK_CECTIACK (1 << 3) +#define MASK_CECTIAL (1 << 2) +#define MASK_CECTIEND (1 << 1) + +#define CECRBUF1 0x0634 +#define MASK_CECRACK (1 << 9) +#define MASK_CECEOM (1 << 8) +#define MASK_CECRBYTE (0xff << 0) + +#define CECTBUF1 0x0674 +#define MASK_CECTEOM (1 << 8) +#define MASK_CECTBYTE (0xff << 0) + +#define CECRCTR 0x06b4 +#define MASK_CECRCTR (0x1f << 0) + +#define CECIMSK 0x06c0 +#define MASK_CECTIM (1 << 1) +#define MASK_CECRIM (1 << 0) + +#define CECICLR 0x06cc +#define MASK_CECTICLR (1 << 1) +#define MASK_CECRICLR (1 << 0) + #define HDMI_INT0 0x8500 #define MASK_I_KEY 0x80 diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index ce86534450ac..16a1e08ce06c 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -300,9 +300,9 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) * if available, ... */ -static void chip_thread_wake(unsigned long data) +static void chip_thread_wake(struct timer_list *t) { - struct CHIPSTATE *chip = (struct CHIPSTATE*)data; + struct CHIPSTATE *chip = from_timer(chip, t, wt); wake_up_process(chip->thread); } @@ -1995,7 +1995,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * v4l2_ctrl_handler_setup(&chip->hdl); chip->thread = NULL; - init_timer(&chip->wt); + timer_setup(&chip->wt, chip_thread_wake, 0); if (desc->flags & CHIP_NEED_CHECKMODE) { if (!desc->getrxsubchans || !desc->setaudmode) { /* This shouldn't be happen. Warn user, but keep working @@ -2005,8 +2005,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id * return 0; } /* start async thread */ - chip->wt.function = chip_thread_wake; - chip->wt.data = (unsigned long)chip; chip->thread = kthread_run(chip_thread, chip, "%s", client->name); if (IS_ERR(chip->thread)) { diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 2ace0410d277..f7c6d64e6031 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -214,12 +214,20 @@ void media_gobj_destroy(struct media_gobj *gobj) gobj->mdev = NULL; } +/* + * TODO: Get rid of this. + */ +#define MEDIA_ENTITY_MAX_PADS 512 + int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads) { struct media_device *mdev = entity->graph_obj.mdev; unsigned int i; + if (num_pads >= MEDIA_ENTITY_MAX_PADS) + return -E2BIG; + entity->num_pads = num_pads; entity->pads = pads; @@ -280,11 +288,6 @@ static struct media_entity *stack_pop(struct media_graph *graph) #define link_top(en) ((en)->stack[(en)->top].link) #define stack_top(en) ((en)->stack[(en)->top].entity) -/* - * TODO: Get rid of this. - */ -#define MEDIA_ENTITY_MAX_PADS 512 - /** * media_graph_walk_init - Allocate resources for graph walk * @graph: Media graph structure that will be used to walk the graph diff --git a/drivers/media/pci/b2c2/Kconfig b/drivers/media/pci/b2c2/Kconfig index 58761a21caa0..7b818d445f39 100644 --- a/drivers/media/pci/b2c2/Kconfig +++ b/drivers/media/pci/b2c2/Kconfig @@ -11,5 +11,5 @@ config DVB_B2C2_FLEXCOP_PCI_DEBUG depends on DVB_B2C2_FLEXCOP_PCI select DVB_B2C2_FLEXCOP_DEBUG help - Say Y if you want to enable the module option to control debug messages - of all B2C2 FlexCop drivers. + Say Y if you want to enable the module option to control debug messages + of all B2C2 FlexCop drivers. diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 227086a2e99c..b366a7e1d976 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -3652,9 +3652,9 @@ bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup, wake_up(&wakeup->vb.done); } -static void bttv_irq_timeout(unsigned long data) +static void bttv_irq_timeout(struct timer_list *t) { - struct bttv *btv = (struct bttv *)data; + struct bttv *btv = from_timer(btv, t, timeout); struct bttv_buffer_set old,new; struct bttv_buffer *ovbi; struct bttv_buffer *item; @@ -4043,7 +4043,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) INIT_LIST_HEAD(&btv->capture); INIT_LIST_HEAD(&btv->vcapture); - setup_timer(&btv->timeout, bttv_irq_timeout, (unsigned long)btv); + timer_setup(&btv->timeout, bttv_irq_timeout, 0); btv->i2c_rc = -1; btv->tuner_type = UNSET; diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 73d655d073d6..ac7674700685 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -133,10 +133,10 @@ void bttv_input_irq(struct bttv *btv) ir_handle_key(btv); } -static void bttv_input_timer(unsigned long data) +static void bttv_input_timer(struct timer_list *t) { - struct bttv *btv = (struct bttv*)data; - struct bttv_ir *ir = btv->remote; + struct bttv_ir *ir = from_timer(ir, t, timer); + struct bttv *btv = ir->btv; if (btv->c.type == BTTV_BOARD_ENLTV_FM_2) ir_enltv_handle_key(btv); @@ -189,9 +189,9 @@ static u32 bttv_rc5_decode(unsigned int code) return rc5; } -static void bttv_rc5_timer_end(unsigned long data) +static void bttv_rc5_timer_end(struct timer_list *t) { - struct bttv_ir *ir = (struct bttv_ir *)data; + struct bttv_ir *ir = from_timer(ir, t, timer); ktime_t tv; u32 gap, rc5, scancode; u8 toggle, command, system; @@ -296,15 +296,15 @@ static int bttv_rc5_irq(struct bttv *btv) /* ---------------------------------------------------------------------- */ -static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir) +static void bttv_ir_start(struct bttv_ir *ir) { if (ir->polling) { - setup_timer(&ir->timer, bttv_input_timer, (unsigned long)btv); + timer_setup(&ir->timer, bttv_input_timer, 0); ir->timer.expires = jiffies + msecs_to_jiffies(1000); add_timer(&ir->timer); } else if (ir->rc5_gpio) { /* set timer_end for code completion */ - setup_timer(&ir->timer, bttv_rc5_timer_end, (unsigned long)ir); + timer_setup(&ir->timer, bttv_rc5_timer_end, 0); ir->shift_by = 1; ir->rc5_remote_gap = ir_rc5_remote_gap; } @@ -531,6 +531,7 @@ int bttv_input_init(struct bttv *btv) /* init input device */ ir->dev = rc; + ir->btv = btv; snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", btv->c.type); @@ -553,7 +554,7 @@ int bttv_input_init(struct bttv *btv) rc->driver_name = MODULE_NAME; btv->remote = ir; - bttv_ir_start(btv, ir); + bttv_ir_start(ir); /* all done */ err = rc_register_device(rc); diff --git a/drivers/media/pci/bt8xx/bttv-vbi.c b/drivers/media/pci/bt8xx/bttv-vbi.c index e77129c92fa0..67c6583f1d79 100644 --- a/drivers/media/pci/bt8xx/bttv-vbi.c +++ b/drivers/media/pci/bt8xx/bttv-vbi.c @@ -233,7 +233,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer bttv_dma_free(q,fh->btv,buf); } -struct videobuf_queue_ops bttv_vbi_qops = { +const struct videobuf_queue_ops bttv_vbi_qops = { .buf_setup = vbi_buffer_setup, .buf_prepare = vbi_buffer_prepare, .buf_queue = vbi_buffer_queue, diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 9efc4559fa8e..cb1b5e611130 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -122,6 +122,7 @@ struct bttv_format { struct bttv_ir { struct rc_dev *dev; + struct bttv *btv; struct timer_list timer; char name[32]; @@ -281,7 +282,7 @@ int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); -extern struct videobuf_queue_ops bttv_vbi_qops; +extern const struct videobuf_queue_ops bttv_vbi_qops; /* ---------------------------------------------------------- */ /* bttv-gpio.c */ diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 98b6cb9505d1..3f16cf3f6d74 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -738,9 +738,6 @@ static int cobalt_probe(struct pci_dev *pci_dev, goto err_i2c; } - retval = v4l2_device_register_subdev_nodes(&cobalt->v4l2_dev); - if (retval) - goto err_i2c; retval = cobalt_nodes_register(cobalt); if (retval) { cobalt_err("Error %d registering device nodes\n", retval); @@ -767,8 +764,6 @@ err_pci: err_wq: destroy_workqueue(cobalt->irq_work_queues); err: - if (retval == 0) - retval = -ENODEV; cobalt_err("error %d on initialization\n", retval); v4l2_device_unregister(&cobalt->v4l2_dev); diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 8654710464cc..8f314ca320c7 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -255,7 +255,7 @@ static void request_module_async(struct work_struct *work) request_module("cx18-alsa"); /* Initialize cx18-alsa for this instance of the cx18 device */ - if (cx18_ext_init != NULL) + if (cx18_ext_init) cx18_ext_init(dev); } @@ -291,11 +291,11 @@ int cx18_msleep_timeout(unsigned int msecs, int intr) /* Release ioremapped memory */ static void cx18_iounmap(struct cx18 *cx) { - if (cx == NULL) + if (!cx) return; /* Release io memory */ - if (cx->enc_mem != NULL) { + if (cx->enc_mem) { CX18_DEBUG_INFO("releasing enc_mem\n"); iounmap(cx->enc_mem); cx->enc_mem = NULL; @@ -649,15 +649,15 @@ static void cx18_process_options(struct cx18 *cx) CX18_INFO("User specified %s card\n", cx->card->name); else if (cx->options.cardtype != 0) CX18_ERR("Unknown user specified type, trying to autodetect card\n"); - if (cx->card == NULL) { + if (!cx->card) { if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_INFO("Autodetected Hauppauge card\n"); } } - if (cx->card == NULL) { + if (!cx->card) { for (i = 0; (cx->card = cx18_get_card(i)); i++) { - if (cx->card->pci_list == NULL) + if (!cx->card->pci_list) continue; for (j = 0; cx->card->pci_list[j].device; j++) { if (cx->pci_dev->device != @@ -676,7 +676,7 @@ static void cx18_process_options(struct cx18 *cx) } done: - if (cx->card == NULL) { + if (!cx->card) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", cx->pci_dev->vendor, cx->pci_dev->device); @@ -698,7 +698,7 @@ static int cx18_create_in_workq(struct cx18 *cx) snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in", cx->v4l2_dev.name); cx->in_work_queue = alloc_ordered_workqueue("%s", 0, cx->in_workq_name); - if (cx->in_work_queue == NULL) { + if (!cx->in_work_queue) { CX18_ERR("Unable to create incoming mailbox handler thread\n"); return -ENOMEM; } @@ -909,12 +909,10 @@ static int cx18_probe(struct pci_dev *pci_dev, return -ENOMEM; } - cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (cx == NULL) { - printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n", - i); + cx = kzalloc(sizeof(*cx), GFP_ATOMIC); + if (!cx) return -ENOMEM; - } + cx->pci_dev = pci_dev; cx->instance = i; @@ -1256,7 +1254,7 @@ static void cx18_cancel_out_work_orders(struct cx18 *cx) { int i; for (i = 0; i < CX18_MAX_STREAMS; i++) - if (&cx->streams[i].video_dev != NULL) + if (&cx->streams[i].video_dev) cancel_work_sync(&cx->streams[i].out_work_order); } @@ -1301,7 +1299,7 @@ static void cx18_remove(struct pci_dev *pci_dev) pci_disable_device(cx->pci_dev); - if (cx->vbi.sliced_mpeg_data[0] != NULL) + if (cx->vbi.sliced_mpeg_data[0]) for (i = 0; i < CX18_VBI_FRAMES; i++) kfree(cx->vbi.sliced_mpeg_data[i]); diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 98467b2089fa..4f9c2395941b 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -684,9 +684,9 @@ int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; } -void cx18_vb_timeout(unsigned long data) +void cx18_vb_timeout(struct timer_list *t) { - struct cx18_stream *s = (struct cx18_stream *)data; + struct cx18_stream *s = from_timer(s, t, vb_timeout); struct cx18_videobuf_buffer *buf; unsigned long flags; diff --git a/drivers/media/pci/cx18/cx18-fileops.h b/drivers/media/pci/cx18/cx18-fileops.h index 58b00b433708..37ef34e866cb 100644 --- a/drivers/media/pci/cx18/cx18-fileops.h +++ b/drivers/media/pci/cx18/cx18-fileops.h @@ -29,7 +29,7 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end); void cx18_mute(struct cx18 *cx); void cx18_unmute(struct cx18 *cx); int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma); -void cx18_vb_timeout(unsigned long data); +void cx18_vb_timeout(struct timer_list *t); /* Shared with cx18-alsa module */ int cx18_claim_stream(struct cx18_open_id *id, int type); diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 8385411af641..f35f78d66985 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -282,7 +282,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) INIT_WORK(&s->out_work_order, cx18_out_work_handler); INIT_LIST_HEAD(&s->vb_capture); - setup_timer(&s->vb_timeout, cx18_vb_timeout, (unsigned long)s); + timer_setup(&s->vb_timeout, cx18_vb_timeout, 0); spin_lock_init(&s->vb_lock); if (type == CX18_ENC_STREAM_TYPE_YUV) { spin_lock_init(&s->vbuf_q_lock); diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 78a8836d03e4..28eab9c518c5 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -1323,7 +1323,7 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) static void tbs_card_init(struct cx23885_dev *dev) { int i; - const u8 buf[] = { + static const u8 buf[] = { 0xe0, 0x06, 0x66, 0x33, 0x65, 0x01, 0x17, 0x06, 0xde}; diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c index 0f21467ae88e..ef863492c0ac 100644 --- a/drivers/media/pci/cx23885/cx23885-i2c.c +++ b/drivers/media/pci/cx23885/cx23885-i2c.c @@ -270,7 +270,7 @@ static const struct i2c_adapter cx23885_i2c_adap_template = { .algo = &cx23885_i2c_algo_template, }; -static struct i2c_client cx23885_i2c_client_template = { +static const struct i2c_client cx23885_i2c_client_template = { .name = "cx23885 internal", }; diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c index 369e545cac04..70f9f13bded3 100644 --- a/drivers/media/pci/cx23885/cx23885-vbi.c +++ b/drivers/media/pci/cx23885/cx23885-vbi.c @@ -254,7 +254,7 @@ static void cx23885_stop_streaming(struct vb2_queue *q) } -struct vb2_ops cx23885_vbi_qops = { +const struct vb2_ops cx23885_vbi_qops = { .queue_setup = queue_setup, .buf_prepare = buffer_prepare, .buf_finish = buffer_finish, diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index cb714ab60d69..6aab713e0476 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -591,7 +591,7 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm); extern int cx23885_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f); extern void cx23885_vbi_timeout(unsigned long data); -extern struct vb2_ops cx23885_vbi_qops; +extern const struct vb2_ops cx23885_vbi_qops; extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status); /* cx23885-i2c.c */ diff --git a/drivers/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c index 000049d3c71b..31479a41f359 100644 --- a/drivers/media/pci/cx25821/cx25821-i2c.c +++ b/drivers/media/pci/cx25821/cx25821-i2c.c @@ -291,7 +291,7 @@ static const struct i2c_adapter cx25821_i2c_adap_template = { .algo = &cx25821_i2c_algo_template, }; -static struct i2c_client cx25821_i2c_client_template = { +static const struct i2c_client cx25821_i2c_client_template = { .name = "cx25821 internal", }; diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index e02449bf2041..4e9953e61a12 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -593,11 +593,11 @@ static int get_key_pvr2000(struct IR_i2c *ir, enum rc_proto *protocol, void cx88_i2c_init_ir(struct cx88_core *core) { struct i2c_board_info info; - const unsigned short default_addr_list[] = { + static const unsigned short default_addr_list[] = { 0x18, 0x6b, 0x71, I2C_CLIENT_END }; - const unsigned short pvr2000_addr_list[] = { + static const unsigned short pvr2000_addr_list[] = { 0x18, 0x1a, I2C_CLIENT_END }; diff --git a/drivers/media/pci/ddbridge/ddbridge-io.h b/drivers/media/pci/ddbridge/ddbridge-io.h index a4c6bbe09168..b3646c04f1a7 100644 --- a/drivers/media/pci/ddbridge/ddbridge-io.h +++ b/drivers/media/pci/ddbridge/ddbridge-io.h @@ -47,12 +47,12 @@ static inline void ddbwritel(struct ddb *dev, u32 val, u32 adr) static inline void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) { - return memcpy_toio(dev->regs + adr, src, count); + memcpy_toio(dev->regs + adr, src, count); } static inline void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) { - return memcpy_fromio(dst, dev->regs + adr, count); + memcpy_fromio(dst, dev->regs + adr, count); } static inline u32 safe_ddbreadl(struct ddb *dev, u32 adr) diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 54dcac4b2229..6b2ffdc96961 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -770,8 +770,7 @@ static int ivtv_init_struct1(struct ivtv *itv) init_waitqueue_head(&itv->event_waitq); init_waitqueue_head(&itv->vsync_waitq); init_waitqueue_head(&itv->dma_waitq); - setup_timer(&itv->dma_timer, ivtv_unfinished_dma, - (unsigned long)itv); + timer_setup(&itv->dma_timer, ivtv_unfinished_dma, 0); itv->cur_dma_stream = -1; itv->cur_pio_stream = -1; diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c index 5a35e366f4c0..893962ac85de 100644 --- a/drivers/media/pci/ivtv/ivtv-i2c.c +++ b/drivers/media/pci/ivtv/ivtv-i2c.c @@ -700,7 +700,7 @@ static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */ }; -static struct i2c_client ivtv_i2c_client_template = { +static const struct i2c_client ivtv_i2c_client_template = { .name = "ivtv internal", }; diff --git a/drivers/media/pci/ivtv/ivtv-irq.c b/drivers/media/pci/ivtv/ivtv-irq.c index 6efe1f71262c..63b09bf73bf0 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.c +++ b/drivers/media/pci/ivtv/ivtv-irq.c @@ -1074,9 +1074,9 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) return vsync_force ? IRQ_NONE : IRQ_HANDLED; } -void ivtv_unfinished_dma(unsigned long arg) +void ivtv_unfinished_dma(struct timer_list *t) { - struct ivtv *itv = (struct ivtv *)arg; + struct ivtv *itv = from_timer(itv, t, dma_timer); if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) return; diff --git a/drivers/media/pci/ivtv/ivtv-irq.h b/drivers/media/pci/ivtv/ivtv-irq.h index 1e84433737cc..bcab5f07d37f 100644 --- a/drivers/media/pci/ivtv/ivtv-irq.h +++ b/drivers/media/pci/ivtv/ivtv-irq.h @@ -48,6 +48,6 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id); void ivtv_irq_work_handler(struct kthread_work *work); void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); -void ivtv_unfinished_dma(unsigned long arg); +void ivtv_unfinished_dma(struct timer_list *t); #endif diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index 11e987860b23..ed855e3df558 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -72,7 +72,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) struct mantis_ca *ca; mantis = (struct mantis_pci *) dev_id; - if (unlikely(mantis == NULL)) { + if (unlikely(!mantis)) { dprintk(MANTIS_ERROR, 1, "Mantis == NULL"); return IRQ_NONE; } @@ -161,11 +161,10 @@ static int hopper_pci_probe(struct pci_dev *pdev, struct mantis_pci_drvdata *drvdata; struct mantis_pci *mantis; struct mantis_hwconfig *config; - int err = 0; + int err; - mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); - if (mantis == NULL) { - printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); + mantis = kzalloc(sizeof(*mantis), GFP_KERNEL); + if (!mantis) { err = -ENOMEM; goto fail0; } diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index adc980d33711..4ce8a90d69dc 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -171,13 +171,11 @@ static int mantis_pci_probe(struct pci_dev *pdev, struct mantis_pci_drvdata *drvdata; struct mantis_pci *mantis; struct mantis_hwconfig *config; - int err = 0; + int err; - mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL); - if (mantis == NULL) { - printk(KERN_ERR "%s ERROR: Out of memory\n", __func__); + mantis = kzalloc(sizeof(*mantis), GFP_KERNEL); + if (!mantis) return -ENOMEM; - } drvdata = (void *)pci_id->driver_data; mantis->num = devs; diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 49e047e4a81e..23999a8cef37 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1626,35 +1626,31 @@ static int meye_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) meye.mchip_dev = pcidev; meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); - if (!meye.grab_temp) { - v4l2_err(v4l2_dev, "grab buffer allocation failed\n"); + if (!meye.grab_temp) goto outvmalloc; - } spin_lock_init(&meye.grabq_lock); if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS, - GFP_KERNEL)) { - v4l2_err(v4l2_dev, "fifo allocation failed\n"); + GFP_KERNEL)) goto outkfifoalloc1; - } + spin_lock_init(&meye.doneq_lock); if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS, - GFP_KERNEL)) { - v4l2_err(v4l2_dev, "fifo allocation failed\n"); + GFP_KERNEL)) goto outkfifoalloc2; - } meye.vdev = meye_template; meye.vdev.v4l2_dev = &meye.v4l2_dev; - ret = -EIO; - if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { + ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1); + if (ret) { v4l2_err(v4l2_dev, "meye: unable to power on the camera\n"); v4l2_err(v4l2_dev, "meye: did you enable the camera in sonypi using the module options ?\n"); goto outsonypienable; } - if ((ret = pci_enable_device(meye.mchip_dev))) { + ret = pci_enable_device(meye.mchip_dev); + if (ret) { v4l2_err(v4l2_dev, "meye: pci_enable_device failed\n"); goto outenabledev; } diff --git a/drivers/media/pci/netup_unidvb/Kconfig b/drivers/media/pci/netup_unidvb/Kconfig index 0ad37714c7fd..b663154d0cc4 100644 --- a/drivers/media/pci/netup_unidvb/Kconfig +++ b/drivers/media/pci/netup_unidvb/Kconfig @@ -1,8 +1,8 @@ config DVB_NETUP_UNIDVB tristate "NetUP Universal DVB card support" depends on DVB_CORE && VIDEO_DEV && PCI && I2C && SPI_MASTER - select VIDEOBUF2_DVB - select VIDEOBUF2_VMALLOC + select VIDEOBUF2_DVB + select VIDEOBUF2_VMALLOC select DVB_HORUS3A if MEDIA_SUBDRV_AUTOSELECT select DVB_ASCOT2E if MEDIA_SUBDRV_AUTOSELECT select DVB_HELENE if MEDIA_SUBDRV_AUTOSELECT @@ -10,8 +10,8 @@ config DVB_NETUP_UNIDVB select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT ---help--- Support for NetUP PCI express Universal DVB card. - help - Say Y when you want to support NetUP Dual Universal DVB card - Card can receive two independent streams in following standards: + + Say Y when you want to support NetUP Dual Universal DVB card. + Card can receive two independent streams in following standards: DVB-S/S2, T/T2, C/C2 - Two CI slots available for CAM modules. + Two CI slots available for CAM modules. diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index 60e6cd5b3a03..11829c0fa138 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -638,9 +638,9 @@ static void netup_unidvb_queue_cleanup(struct netup_dma *dma) spin_unlock_irqrestore(&dma->lock, flags); } -static void netup_unidvb_dma_timeout(unsigned long data) +static void netup_unidvb_dma_timeout(struct timer_list *t) { - struct netup_dma *dma = (struct netup_dma *)data; + struct netup_dma *dma = from_timer(dma, t, timeout); struct netup_unidvb_dev *ndev = dma->ndev; dev_dbg(&ndev->pci_dev->dev, "%s()\n", __func__); @@ -664,8 +664,7 @@ static int netup_unidvb_dma_init(struct netup_unidvb_dev *ndev, int num) spin_lock_init(&dma->lock); INIT_WORK(&dma->work, netup_unidvb_dma_worker); INIT_LIST_HEAD(&dma->free_buffers); - setup_timer(&dma->timeout, netup_unidvb_dma_timeout, - (unsigned long)dma); + timer_setup(&dma->timeout, netup_unidvb_dma_timeout, 0); dma->ring_buffer_size = ndev->dma_size / 2; dma->addr_virt = ndev->dma_virt + dma->ring_buffer_size * num; dma->addr_phys = (dma_addr_t)((u64)ndev->dma_phys + diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 7976c5a12ca8..9e76de2411ae 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -338,9 +338,9 @@ void saa7134_buffer_next(struct saa7134_dev *dev, } } -void saa7134_buffer_timeout(unsigned long data) +void saa7134_buffer_timeout(struct timer_list *t) { - struct saa7134_dmaqueue *q = (struct saa7134_dmaqueue *)data; + struct saa7134_dmaqueue *q = from_timer(q, t, timeout); struct saa7134_dev *dev = q->dev; unsigned long flags; @@ -378,7 +378,7 @@ void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q) } } spin_unlock_irqrestore(&dev->slock, flags); - saa7134_buffer_timeout((unsigned long)q); /* also calls del_timer(&q->timeout) */ + saa7134_buffer_timeout(&q->timeout); /* also calls del_timer(&q->timeout) */ } EXPORT_SYMBOL_GPL(saa7134_stop_streaming); diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c index 8f2ed632840f..cf1e526de56a 100644 --- a/drivers/media/pci/saa7134/saa7134-i2c.c +++ b/drivers/media/pci/saa7134/saa7134-i2c.c @@ -345,7 +345,7 @@ static const struct i2c_adapter saa7134_adap_template = { .algo = &saa7134_algo, }; -static struct i2c_client saa7134_client_template = { +static const struct i2c_client saa7134_client_template = { .name = "saa7134 internal", }; diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 9337e4615519..2d5abeddc079 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -447,10 +447,10 @@ void saa7134_input_irq(struct saa7134_dev *dev) } } -static void saa7134_input_timer(unsigned long data) +static void saa7134_input_timer(struct timer_list *t) { - struct saa7134_dev *dev = (struct saa7134_dev *)data; - struct saa7134_card_ir *ir = dev->remote; + struct saa7134_card_ir *ir = from_timer(ir, t, timer); + struct saa7134_dev *dev = ir->dev->priv; build_key(dev); mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); @@ -507,8 +507,7 @@ static int __saa7134_ir_start(void *priv) ir->running = true; if (ir->polling) { - setup_timer(&ir->timer, saa7134_input_timer, - (unsigned long)dev); + timer_setup(&ir->timer, saa7134_input_timer, 0); ir->timer.expires = jiffies + HZ; add_timer(&ir->timer); } diff --git a/drivers/media/pci/saa7134/saa7134-ts.c b/drivers/media/pci/saa7134/saa7134-ts.c index 7414878af9e0..2be703617e29 100644 --- a/drivers/media/pci/saa7134/saa7134-ts.c +++ b/drivers/media/pci/saa7134/saa7134-ts.c @@ -223,8 +223,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev) dev->ts.nr_packets = ts_nr_packets; INIT_LIST_HEAD(&dev->ts_q.queue); - setup_timer(&dev->ts_q.timeout, saa7134_buffer_timeout, - (unsigned long)(&dev->ts_q)); + timer_setup(&dev->ts_q.timeout, saa7134_buffer_timeout, 0); dev->ts_q.dev = dev; dev->ts_q.need_two = 1; dev->ts_started = 0; diff --git a/drivers/media/pci/saa7134/saa7134-vbi.c b/drivers/media/pci/saa7134/saa7134-vbi.c index bcad9b2d9bb3..57bea543c39b 100644 --- a/drivers/media/pci/saa7134/saa7134-vbi.c +++ b/drivers/media/pci/saa7134/saa7134-vbi.c @@ -165,7 +165,7 @@ static int buffer_init(struct vb2_buffer *vb2) return 0; } -struct vb2_ops saa7134_vbi_qops = { +const struct vb2_ops saa7134_vbi_qops = { .queue_setup = queue_setup, .buf_init = buffer_init, .buf_prepare = buffer_prepare, @@ -181,8 +181,7 @@ struct vb2_ops saa7134_vbi_qops = { int saa7134_vbi_init1(struct saa7134_dev *dev) { INIT_LIST_HEAD(&dev->vbi_q.queue); - setup_timer(&dev->vbi_q.timeout, saa7134_buffer_timeout, - (unsigned long)(&dev->vbi_q)); + timer_setup(&dev->vbi_q.timeout, saa7134_buffer_timeout, 0); dev->vbi_q.dev = dev; if (vbibufs < 2) diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 51d42bbf969e..82d2a24644e4 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -2145,8 +2145,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) dev->automute = 0; INIT_LIST_HEAD(&dev->video_q.queue); - setup_timer(&dev->video_q.timeout, saa7134_buffer_timeout, - (unsigned long)(&dev->video_q)); + timer_setup(&dev->video_q.timeout, saa7134_buffer_timeout, 0); dev->video_q.dev = dev; dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); dev->width = 720; diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 816b5282d671..39c36e6aefbe 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -773,7 +773,7 @@ int saa7134_buffer_queue(struct saa7134_dev *dev, struct saa7134_dmaqueue *q, void saa7134_buffer_finish(struct saa7134_dev *dev, struct saa7134_dmaqueue *q, unsigned int state); void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); -void saa7134_buffer_timeout(unsigned long data); +void saa7134_buffer_timeout(struct timer_list *t); void saa7134_stop_streaming(struct saa7134_dev *dev, struct saa7134_dmaqueue *q); int saa7134_set_dmabits(struct saa7134_dev *dev); @@ -870,7 +870,7 @@ int saa7134_ts_stop(struct saa7134_dev *dev); /* ----------------------------------------------------------- */ /* saa7134-vbi.c */ -extern struct vb2_ops saa7134_vbi_qops; +extern const struct vb2_ops saa7134_vbi_qops; extern struct video_device saa7134_vbi_template; int saa7134_vbi_init1(struct saa7134_dev *dev); diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index f708cab01fef..d31a2d4494d1 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -260,11 +260,10 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d DEB_EE("\n"); - hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); - if (NULL == hexium) { - pr_err("not enough kernel memory in hexium_attach()\n"); + hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); + if (!hexium) return -ENOMEM; - } + dev->ext_priv = hexium; /* enable i2c-port pins */ diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index 01f01580c7ca..043318aa19e2 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -219,11 +219,9 @@ static int hexium_probe(struct saa7146_dev *dev) return -EFAULT; } - hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL); - if (NULL == hexium) { - pr_err("hexium_probe: not enough kernel memory\n"); + hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); + if (!hexium) return -ENOMEM; - } /* enable i2c-port pins */ saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); @@ -268,7 +266,9 @@ static int hexium_probe(struct saa7146_dev *dev) /* check if this is an old hexium Orion card by looking at a saa7110 at address 0x4e */ - if (0 == (err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, &data))) { + err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ, + 0x00, I2C_SMBUS_BYTE_DATA, &data); + if (err == 0) { pr_info("device is a Hexium HV-PCI6/Orion (old)\n"); /* we store the pointer in our private data field */ dev->ext_priv = hexium; diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c index a0d2129c6ca9..c83b2e914dcb 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -98,11 +98,9 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port, goto ret; } - buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL); - if (!buf) { - log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__); + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) goto ret; - } buf->idx = -1; buf->port = port; @@ -283,7 +281,7 @@ struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, { struct saa7164_user_buffer *buf; - buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL); + buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) return NULL; diff --git a/drivers/media/pci/saa7164/saa7164-i2c.c b/drivers/media/pci/saa7164/saa7164-i2c.c index 4bcde7c79dc3..6d13cbb9d010 100644 --- a/drivers/media/pci/saa7164/saa7164-i2c.c +++ b/drivers/media/pci/saa7164/saa7164-i2c.c @@ -84,7 +84,7 @@ static const struct i2c_adapter saa7164_i2c_adap_template = { .algo = &saa7164_i2c_algo_template, }; -static struct i2c_client saa7164_i2c_client_template = { +static const struct i2c_client saa7164_i2c_client_template = { .name = "saa7164 internal", }; diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index f46947d8adf8..6d415bdeef18 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c @@ -347,9 +347,9 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, static inline void print_time(char *s) { #ifdef DEBUG_TIMING - struct timeval tv; - do_gettimeofday(&tv); - printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec); + struct timespec64 ts; + ktime_get_real_ts64(&ts); + printk("%s: %lld.%09ld\n", s, (s64)ts.tv_sec, ts.tv_nsec); #endif } @@ -1224,7 +1224,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) dprintk(2, "av7110: %p\n", budget); spin_lock(&budget->feedlock1); - feed->pusi_seen = 0; /* have a clean section start */ + feed->pusi_seen = false; /* have a clean section start */ status = start_ts_capture(budget); spin_unlock(&budget->feedlock1); return status; diff --git a/drivers/media/pci/ttpci/budget-core.c b/drivers/media/pci/ttpci/budget-core.c index 97499b2af714..b3dc45b91101 100644 --- a/drivers/media/pci/ttpci/budget-core.c +++ b/drivers/media/pci/ttpci/budget-core.c @@ -330,7 +330,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) return -EINVAL; spin_lock(&budget->feedlock); - feed->pusi_seen = 0; /* have a clean section start */ + feed->pusi_seen = false; /* have a clean section start */ if (budget->feeding++ == 0) status = start_ts_capture(budget); spin_unlock(&budget->feedlock); diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c index b762e5f0ba1d..7fb3f07bf022 100644 --- a/drivers/media/pci/tw686x/tw686x-core.c +++ b/drivers/media/pci/tw686x/tw686x-core.c @@ -126,9 +126,9 @@ void tw686x_enable_channel(struct tw686x_dev *dev, unsigned int channel) * channels "too fast" which makes some TW686x devices very * angry and freeze the CPU (see note 1). */ -static void tw686x_dma_delay(unsigned long data) +static void tw686x_dma_delay(struct timer_list *t) { - struct tw686x_dev *dev = (struct tw686x_dev *)data; + struct tw686x_dev *dev = from_timer(dev, t, dma_delay_timer); unsigned long flags; spin_lock_irqsave(&dev->lock, flags); @@ -325,8 +325,7 @@ static int tw686x_probe(struct pci_dev *pci_dev, goto iounmap; } - setup_timer(&dev->dma_delay_timer, - tw686x_dma_delay, (unsigned long) dev); + timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0); /* * This must be set right before initializing v4l2_dev. diff --git a/drivers/media/pci/zoran/zoran_card.h b/drivers/media/pci/zoran/zoran_card.h index 81cba177cd90..0cdb7d34926d 100644 --- a/drivers/media/pci/zoran/zoran_card.h +++ b/drivers/media/pci/zoran/zoran_card.h @@ -37,7 +37,7 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 -extern struct video_device zoran_template; +extern const struct video_device zoran_template; extern int zoran_check_jpg_settings(struct zoran *zr, struct zoran_jpg_settings *settings, diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index a11cb501c550..d07840072337 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -2839,7 +2839,7 @@ static const struct v4l2_file_operations zoran_fops = { .poll = zoran_poll, }; -struct video_device zoran_template = { +const struct video_device zoran_template = { .name = ZORAN_NAME, .fops = &zoran_fops, .ioctl_ops = &zoran_ioctl_ops, diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 3c4f7fa7b9d8..fd0c99859d6f 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -458,6 +458,21 @@ config VIDEO_RENESAS_VSP1 To compile this driver as a module, choose M here: the module will be called vsp1. +config VIDEO_ROCKCHIP_RGA + tristate "Rockchip Raster 2d Graphic Acceleration Unit" + depends on VIDEO_DEV && VIDEO_V4L2 && HAS_DMA + depends on ARCH_ROCKCHIP || COMPILE_TEST + select VIDEOBUF2_DMA_SG + select V4L2_MEM2MEM_DEV + default n + ---help--- + This is a v4l2 driver for Rockchip SOC RGA 2d graphics accelerator. + Rockchip RGA is a separate 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. + + To compile this driver as a module choose m here. + config VIDEO_TI_VPE tristate "TI VPE (Video Processing Engine) driver" depends on VIDEO_DEV && VIDEO_V4L2 @@ -553,6 +568,16 @@ config VIDEO_MESON_AO_CEC This is a driver for Amlogic Meson SoCs AO CEC interface. It uses the generic CEC framework interface. CEC bus is present in the HDMI connector and enables communication + +config CEC_GPIO + tristate "Generic GPIO-based CEC driver" + depends on PREEMPT + select CEC_CORE + select CEC_PIN + select GPIOLIB + ---help--- + This is a generic GPIO-based CEC driver. + The CEC bus is present in the HDMI connector and enables communication between compatible devices. config VIDEO_SAMSUNG_S5P_CEC @@ -589,6 +614,17 @@ config VIDEO_STM32_HDMI_CEC CEC bus is present in the HDMI connector and enables communication between compatible devices. +config VIDEO_TEGRA_HDMI_CEC + tristate "Tegra HDMI CEC driver" + depends on ARCH_TEGRA || COMPILE_TEST + select CEC_CORE + select CEC_NOTIFIER + ---help--- + This is a driver for the Tegra HDMI CEC interface. It uses the + generic CEC framework interface. + The CEC bus is present in the HDMI connector and enables communication + between compatible devices. + endif #CEC_PLATFORM_DRIVERS menuconfig SDR_PLATFORM_DRIVERS diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 327f80a6f82c..003b0bb2cddf 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -27,6 +27,8 @@ obj-$(CONFIG_VIDEO_CODA) += coda/ obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o +obj-$(CONFIG_CEC_GPIO) += cec-gpio/ + obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o obj-$(CONFIG_VIDEO_MUX) += video-mux.o @@ -47,6 +49,8 @@ obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/ obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/ +obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra-cec/ + obj-y += stm32/ obj-y += blackfin/ @@ -63,6 +67,8 @@ obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ +obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/ + obj-y += omap/ obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index dfcc484cab89..0997c640191d 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -2417,6 +2417,11 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier) return vpfe_probe_complete(vpfe); } +static const struct v4l2_async_notifier_operations vpfe_async_ops = { + .bound = vpfe_async_bound, + .complete = vpfe_async_complete, +}; + static struct vpfe_config * vpfe_get_pdata(struct platform_device *pdev) { @@ -2590,8 +2595,7 @@ static int vpfe_probe(struct platform_device *pdev) vpfe->notifier.subdevs = vpfe->cfg->asd; vpfe->notifier.num_subdevs = ARRAY_SIZE(vpfe->cfg->asd); - vpfe->notifier.bound = vpfe_async_bound; - vpfe->notifier.complete = vpfe_async_complete; + vpfe->notifier.ops = &vpfe_async_ops; ret = v4l2_async_notifier_register(&vpfe->v4l2_dev, &vpfe->notifier); if (ret) { diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h index e6cef966dcbf..2aadc19235ea 100644 --- a/drivers/media/platform/atmel/atmel-isc-regs.h +++ b/drivers/media/platform/atmel/atmel-isc-regs.h @@ -43,6 +43,7 @@ /* ISC Clock Status Register */ #define ISC_CLKSR 0x00000020 +#define ISC_CLKSR_SIP BIT(31) #define ISC_CLK(n) BIT(n) diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c index d7103c5f92c3..13f1c1c797b0 100644 --- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -65,6 +65,7 @@ struct isc_clk { struct clk_hw hw; struct clk *clk; struct regmap *regmap; + spinlock_t lock; u8 id; u8 parent_id; u32 div; @@ -82,41 +83,69 @@ struct isc_subdev_entity { struct v4l2_subdev *sd; struct v4l2_async_subdev *asd; struct v4l2_async_notifier notifier; - struct v4l2_subdev_pad_config *config; u32 pfe_cfg0; struct list_head list; }; +/* Indicate the format is generated by the sensor */ +#define FMT_FLAG_FROM_SENSOR BIT(0) +/* Indicate the format is produced by ISC itself */ +#define FMT_FLAG_FROM_CONTROLLER BIT(1) +/* Indicate a Raw Bayer format */ +#define FMT_FLAG_RAW_FORMAT BIT(2) + +#define FMT_FLAG_RAW_FROM_SENSOR (FMT_FLAG_FROM_SENSOR | \ + FMT_FLAG_RAW_FORMAT) + /* * struct isc_format - ISC media bus format information * @fourcc: Fourcc code for this format * @mbus_code: V4L2 media bus format code. + * flags: Indicate format from sensor or converted by controller * @bpp: Bits per pixel (when stored in memory) - * @reg_bps: reg value for bits per sample * (when transferred over a bus) - * @pipeline: pipeline switch * @sd_support: Subdev supports this format * @isc_support: ISC can convert raw format to this format */ + struct isc_format { u32 fourcc; u32 mbus_code; + u32 flags; u8 bpp; - u32 reg_bps; - u32 reg_bay_cfg; - u32 reg_rlp_mode; - u32 reg_dcfg_imode; - u32 reg_dctrl_dview; - - u32 pipeline; - bool sd_support; bool isc_support; }; +/* Pipeline bitmap */ +#define WB_ENABLE BIT(0) +#define CFA_ENABLE BIT(1) +#define CC_ENABLE BIT(2) +#define GAM_ENABLE BIT(3) +#define GAM_BENABLE BIT(4) +#define GAM_GENABLE BIT(5) +#define GAM_RENABLE BIT(6) +#define CSC_ENABLE BIT(7) +#define CBC_ENABLE BIT(8) +#define SUB422_ENABLE BIT(9) +#define SUB420_ENABLE BIT(10) + +#define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE) + +struct fmt_config { + u32 fourcc; + + u32 pfe_cfg0_bps; + u32 cfa_baycfg; + u32 rlp_cfg_mode; + u32 dcfg_imode; + u32 dctrl_dview; + + u32 bits_pipeline; +}; #define HIST_ENTRIES 512 #define HIST_BAYER (ISC_HIS_CFG_MODE_B + 1) @@ -181,80 +210,320 @@ struct isc_device { struct list_head subdev_entities; }; -#define RAW_FMT_IND_START 0 -#define RAW_FMT_IND_END 11 -#define ISC_FMT_IND_START 12 -#define ISC_FMT_IND_END 14 - -static struct isc_format isc_formats[] = { - { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 8, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8, - ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 8, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT8, - ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 8, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT8, - ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 8, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT8, - ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - - { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 16, - ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT10, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 16, - ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT10, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 16, - ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT10, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10, 16, - ISC_PFG_CFG0_BPS_TEN, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT10, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - - { V4L2_PIX_FMT_SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12, 16, - ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT12, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12, 16, - ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GBGB, ISC_RLP_CFG_MODE_DAT12, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12, 16, - ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_GRGR, ISC_RLP_CFG_MODE_DAT12, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - { V4L2_PIX_FMT_SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12, 16, - ISC_PFG_CFG0_BPS_TWELVE, ISC_BAY_CFG_RGRG, ISC_RLP_CFG_MODE_DAT12, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, - - { V4L2_PIX_FMT_YUV420, 0x0, 12, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC, - ISC_DCFG_IMODE_YC420P, ISC_DCTRL_DVIEW_PLANAR, 0x7fb, - false, false }, - { V4L2_PIX_FMT_YUV422P, 0x0, 16, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_YYCC, - ISC_DCFG_IMODE_YC422P, ISC_DCTRL_DVIEW_PLANAR, 0x3fb, - false, false }, - { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_RGB565_2X8_LE, 16, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_RGB565, - ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, 0x7b, - false, false }, - - { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_YUYV8_2X8, 16, - ISC_PFE_CFG0_BPS_EIGHT, ISC_BAY_CFG_BGBG, ISC_RLP_CFG_MODE_DAT8, - ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, 0x0, - false, false }, +static struct isc_format formats_list[] = { + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 8, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 8, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 8, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 8, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, + .flags = FMT_FLAG_RAW_FROM_SENSOR, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_YUV420, + .mbus_code = 0x0, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 12, + }, + { + .fourcc = V4L2_PIX_FMT_YUV422P, + .mbus_code = 0x0, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + .mbus_code = MEDIA_BUS_FMT_Y8_1X8, + .flags = FMT_FLAG_FROM_CONTROLLER | + FMT_FLAG_FROM_SENSOR, + .bpp = 8, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB444, + .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + .mbus_code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 16, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB32, + .mbus_code = MEDIA_BUS_FMT_ARGB8888_1X32, + .flags = FMT_FLAG_FROM_CONTROLLER, + .bpp = 32, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + .flags = FMT_FLAG_FROM_CONTROLLER | + FMT_FLAG_FROM_SENSOR, + .bpp = 16, + }, +}; + +struct fmt_config fmt_configs_list[] = { + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GBGB, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0 + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_GRGR, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB12, + .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, + .cfa_baycfg = ISC_BAY_CFG_RGRG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0, + }, + { + .fourcc = V4L2_PIX_FMT_YUV420, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC, + .dcfg_imode = ISC_DCFG_IMODE_YC420P, + .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR, + .bits_pipeline = SUB420_ENABLE | SUB422_ENABLE | + CBC_ENABLE | CSC_ENABLE | + GAM_ENABLES | + CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_YUV422P, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC, + .dcfg_imode = ISC_DCFG_IMODE_YC422P, + .dctrl_dview = ISC_DCTRL_DVIEW_PLANAR, + .bits_pipeline = SUB422_ENABLE | + CBC_ENABLE | CSC_ENABLE | + GAM_ENABLES | + CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_GREY, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = CBC_ENABLE | CSC_ENABLE | + GAM_ENABLES | + CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB444, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565, + .dcfg_imode = ISC_DCFG_IMODE_PACKED16, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB32, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32, + .dcfg_imode = ISC_DCFG_IMODE_PACKED32, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = GAM_ENABLES | CFA_ENABLE | WB_ENABLE, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, + .cfa_baycfg = ISC_BAY_CFG_BGBG, + .rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8, + .dcfg_imode = ISC_DCFG_IMODE_PACKED8, + .dctrl_dview = ISC_DCTRL_DVIEW_PACKED, + .bits_pipeline = 0x0 + }, }; #define GAMMA_MAX 2 @@ -307,31 +576,80 @@ module_param(sensor_preferred, uint, 0644); MODULE_PARM_DESC(sensor_preferred, "Sensor is preferred to output the specified format (1-on 0-off), default 1"); +static int isc_wait_clk_stable(struct clk_hw *hw) +{ + struct isc_clk *isc_clk = to_isc_clk(hw); + struct regmap *regmap = isc_clk->regmap; + unsigned long timeout = jiffies + usecs_to_jiffies(1000); + unsigned int status; + + while (time_before(jiffies, timeout)) { + regmap_read(regmap, ISC_CLKSR, &status); + if (!(status & ISC_CLKSR_SIP)) + return 0; + + usleep_range(10, 250); + } + + return -ETIMEDOUT; +} + +static int isc_clk_prepare(struct clk_hw *hw) +{ + struct isc_clk *isc_clk = to_isc_clk(hw); + + if (isc_clk->id == ISC_ISPCK) + pm_runtime_get_sync(isc_clk->dev); + + return isc_wait_clk_stable(hw); +} + +static void isc_clk_unprepare(struct clk_hw *hw) +{ + struct isc_clk *isc_clk = to_isc_clk(hw); + + isc_wait_clk_stable(hw); + + if (isc_clk->id == ISC_ISPCK) + pm_runtime_put_sync(isc_clk->dev); +} + static int isc_clk_enable(struct clk_hw *hw) { struct isc_clk *isc_clk = to_isc_clk(hw); u32 id = isc_clk->id; struct regmap *regmap = isc_clk->regmap; + unsigned long flags; + unsigned int status; dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n", __func__, isc_clk->div, isc_clk->parent_id); + spin_lock_irqsave(&isc_clk->lock, flags); regmap_update_bits(regmap, ISC_CLKCFG, ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id), (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) | (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id))); regmap_write(regmap, ISC_CLKEN, ISC_CLK(id)); + spin_unlock_irqrestore(&isc_clk->lock, flags); - return 0; + regmap_read(regmap, ISC_CLKSR, &status); + if (status & ISC_CLK(id)) + return 0; + else + return -EINVAL; } static void isc_clk_disable(struct clk_hw *hw) { struct isc_clk *isc_clk = to_isc_clk(hw); u32 id = isc_clk->id; + unsigned long flags; + spin_lock_irqsave(&isc_clk->lock, flags); regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id)); + spin_unlock_irqrestore(&isc_clk->lock, flags); } static int isc_clk_is_enabled(struct clk_hw *hw) @@ -339,8 +657,14 @@ static int isc_clk_is_enabled(struct clk_hw *hw) struct isc_clk *isc_clk = to_isc_clk(hw); u32 status; + if (isc_clk->id == ISC_ISPCK) + pm_runtime_get_sync(isc_clk->dev); + regmap_read(isc_clk->regmap, ISC_CLKSR, &status); + if (isc_clk->id == ISC_ISPCK) + pm_runtime_put_sync(isc_clk->dev); + return status & ISC_CLK(isc_clk->id) ? 1 : 0; } @@ -447,6 +771,8 @@ static int isc_clk_set_rate(struct clk_hw *hw, } static const struct clk_ops isc_clk_ops = { + .prepare = isc_clk_prepare, + .unprepare = isc_clk_unprepare, .enable = isc_clk_enable, .disable = isc_clk_disable, .is_enabled = isc_clk_is_enabled, @@ -492,6 +818,7 @@ static int isc_clk_register(struct isc_device *isc, unsigned int id) isc_clk->regmap = regmap; isc_clk->id = id; isc_clk->dev = isc->dev; + spin_lock_init(&isc_clk->lock); isc_clk->clk = clk_register(isc->dev, &isc_clk->hw); if (IS_ERR(isc_clk->clk)) { @@ -575,11 +902,27 @@ static inline bool sensor_is_preferred(const struct isc_format *isc_fmt) !isc_fmt->isc_support; } +static struct fmt_config *get_fmt_config(u32 fourcc) +{ + struct fmt_config *config; + int i; + + config = &fmt_configs_list[0]; + for (i = 0; i < ARRAY_SIZE(fmt_configs_list); i++) { + if (config->fourcc == fourcc) + return config; + + config++; + } + return NULL; +} + static void isc_start_dma(struct isc_device *isc) { struct regmap *regmap = isc->regmap; struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix; u32 sizeimage = pixfmt->sizeimage; + struct fmt_config *config = get_fmt_config(isc->current_fmt->fourcc); u32 dctrl_dview; dma_addr_t addr0; @@ -602,7 +945,7 @@ static void isc_start_dma(struct isc_device *isc) if (sensor_is_preferred(isc->current_fmt)) dctrl_dview = ISC_DCTRL_DVIEW_PACKED; else - dctrl_dview = isc->current_fmt->reg_dctrl_dview; + dctrl_dview = config->dctrl_dview; regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS); regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); @@ -612,6 +955,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) { struct regmap *regmap = isc->regmap; struct isc_ctrls *ctrls = &isc->ctrls; + struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); u32 val, bay_cfg; const u32 *gamma; unsigned int i; @@ -625,7 +969,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) if (!pipeline) return; - bay_cfg = isc->raw_fmt->reg_bay_cfg; + bay_cfg = config->cfa_baycfg; regmap_write(regmap, ISC_WB_CFG, bay_cfg); regmap_write(regmap, ISC_WB_O_RGR, 0x0); @@ -678,11 +1022,13 @@ static void isc_set_histogram(struct isc_device *isc) { struct regmap *regmap = isc->regmap; struct isc_ctrls *ctrls = &isc->ctrls; + struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); if (ctrls->awb && (ctrls->hist_stat != HIST_ENABLED)) { - regmap_write(regmap, ISC_HIS_CFG, ISC_HIS_CFG_MODE_R | - (isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT) | - ISC_HIS_CFG_RAR); + regmap_write(regmap, ISC_HIS_CFG, + ISC_HIS_CFG_MODE_R | + (config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT) | + ISC_HIS_CFG_RAR); regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN); regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE); ctrls->hist_id = ISC_HIS_CFG_MODE_R; @@ -699,8 +1045,10 @@ static void isc_set_histogram(struct isc_device *isc) } static inline void isc_get_param(const struct isc_format *fmt, - u32 *rlp_mode, u32 *dcfg) + u32 *rlp_mode, u32 *dcfg) { + struct fmt_config *config = get_fmt_config(fmt->fourcc); + *dcfg = ISC_DCFG_YMBSIZE_BEATS8; switch (fmt->fourcc) { @@ -712,8 +1060,8 @@ static inline void isc_get_param(const struct isc_format *fmt, case V4L2_PIX_FMT_SGBRG12: case V4L2_PIX_FMT_SGRBG12: case V4L2_PIX_FMT_SRGGB12: - *rlp_mode = fmt->reg_rlp_mode; - *dcfg |= fmt->reg_dcfg_imode; + *rlp_mode = config->rlp_cfg_mode; + *dcfg |= config->dcfg_imode; break; default: *rlp_mode = ISC_RLP_CFG_MODE_DAT8; @@ -726,20 +1074,22 @@ static int isc_configure(struct isc_device *isc) { struct regmap *regmap = isc->regmap; const struct isc_format *current_fmt = isc->current_fmt; + struct fmt_config *curfmt_config = get_fmt_config(current_fmt->fourcc); + struct fmt_config *rawfmt_config = get_fmt_config(isc->raw_fmt->fourcc); struct isc_subdev_entity *subdev = isc->current_subdev; u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline; if (sensor_is_preferred(current_fmt)) { - pfe_cfg0 = current_fmt->reg_bps; + pfe_cfg0 = curfmt_config->pfe_cfg0_bps; pipeline = 0x0; isc_get_param(current_fmt, &rlp_mode, &dcfg); isc->ctrls.hist_stat = HIST_INIT; } else { - pfe_cfg0 = isc->raw_fmt->reg_bps; - pipeline = current_fmt->pipeline; - rlp_mode = current_fmt->reg_rlp_mode; - dcfg = current_fmt->reg_dcfg_imode | ISC_DCFG_YMBSIZE_BEATS8 | - ISC_DCFG_CMBSIZE_BEATS8; + pfe_cfg0 = rawfmt_config->pfe_cfg0_bps; + pipeline = curfmt_config->bits_pipeline; + rlp_mode = curfmt_config->rlp_cfg_mode; + dcfg = curfmt_config->dcfg_imode | + ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; } pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; @@ -941,6 +1291,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, { struct isc_format *isc_fmt; struct v4l2_pix_format *pixfmt = &f->fmt.pix; + struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, }; @@ -971,7 +1322,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code); ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, - isc->current_subdev->config, &format); + &pad_cfg, &format); if (ret < 0) return ret; @@ -1323,6 +1674,7 @@ static void isc_awb_work(struct work_struct *w) struct isc_device *isc = container_of(w, struct isc_device, awb_work); struct regmap *regmap = isc->regmap; + struct fmt_config *config = get_fmt_config(isc->raw_fmt->fourcc); struct isc_ctrls *ctrls = &isc->ctrls; u32 hist_id = ctrls->hist_id; u32 baysel; @@ -1340,7 +1692,7 @@ static void isc_awb_work(struct work_struct *w) } ctrls->hist_id = hist_id; - baysel = isc->raw_fmt->reg_bay_cfg << ISC_HIS_CFG_BAYSEL_SHIFT; + baysel = config->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; pm_runtime_get_sync(isc->dev); @@ -1436,17 +1788,15 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier, struct isc_device, v4l2_dev); cancel_work_sync(&isc->awb_work); video_unregister_device(&isc->video_dev); - if (isc->current_subdev->config) - v4l2_subdev_free_pad_config(isc->current_subdev->config); v4l2_ctrl_handler_free(&isc->ctrls.handler); } static struct isc_format *find_format_by_code(unsigned int code, int *index) { - struct isc_format *fmt = &isc_formats[0]; + struct isc_format *fmt = &formats_list[0]; unsigned int i; - for (i = 0; i < ARRAY_SIZE(isc_formats); i++) { + for (i = 0; i < ARRAY_SIZE(formats_list); i++) { if (fmt->mbus_code == code) { *index = i; return fmt; @@ -1463,37 +1813,36 @@ static int isc_formats_init(struct isc_device *isc) struct isc_format *fmt; struct v4l2_subdev *subdev = isc->current_subdev->sd; unsigned int num_fmts, i, j; + u32 list_size = ARRAY_SIZE(formats_list); struct v4l2_subdev_mbus_code_enum mbus_code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; - fmt = &isc_formats[0]; - for (i = 0; i < ARRAY_SIZE(isc_formats); i++) { - fmt->isc_support = false; - fmt->sd_support = false; - - fmt++; - } - while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &mbus_code)) { mbus_code.index++; + fmt = find_format_by_code(mbus_code.code, &i); - if (!fmt) + if ((!fmt) || (!(fmt->flags & FMT_FLAG_FROM_SENSOR))) continue; fmt->sd_support = true; - if (i <= RAW_FMT_IND_END) { - for (j = ISC_FMT_IND_START; j <= ISC_FMT_IND_END; j++) - isc_formats[j].isc_support = true; - + if (fmt->flags & FMT_FLAG_RAW_FORMAT) isc->raw_fmt = fmt; - } } - fmt = &isc_formats[0]; - for (i = 0, num_fmts = 0; i < ARRAY_SIZE(isc_formats); i++) { + fmt = &formats_list[0]; + for (i = 0; i < list_size; i++) { + if (fmt->flags & FMT_FLAG_FROM_CONTROLLER) + fmt->isc_support = true; + + fmt++; + } + + fmt = &formats_list[0]; + num_fmts = 0; + for (i = 0; i < list_size; i++) { if (fmt->isc_support || fmt->sd_support) num_fmts++; @@ -1505,15 +1854,13 @@ static int isc_formats_init(struct isc_device *isc) isc->num_user_formats = num_fmts; isc->user_formats = devm_kcalloc(isc->dev, - num_fmts, sizeof(struct isc_format *), + num_fmts, sizeof(*isc->user_formats), GFP_KERNEL); - if (!isc->user_formats) { - v4l2_err(&isc->v4l2_dev, "could not allocate memory\n"); + if (!isc->user_formats) return -ENOMEM; - } - fmt = &isc_formats[0]; - for (i = 0, j = 0; i < ARRAY_SIZE(isc_formats); i++) { + fmt = &formats_list[0]; + for (i = 0, j = 0; i < list_size; i++) { if (fmt->isc_support || fmt->sd_support) isc->user_formats[j++] = fmt; @@ -1550,7 +1897,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) { struct isc_device *isc = container_of(notifier->v4l2_dev, struct isc_device, v4l2_dev); - struct isc_subdev_entity *sd_entity; struct video_device *vdev = &isc->video_dev; struct vb2_queue *q = &isc->vb2_vidq; int ret; @@ -1563,8 +1909,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) isc->current_subdev = container_of(notifier, struct isc_subdev_entity, notifier); - sd_entity = isc->current_subdev; - mutex_init(&isc->lock); init_completion(&isc->comp); @@ -1591,10 +1935,6 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) INIT_LIST_HEAD(&isc->dma_queue); spin_lock_init(&isc->dma_queue_lock); - sd_entity->config = v4l2_subdev_alloc_pad_config(sd_entity->sd); - if (sd_entity->config == NULL) - return -ENOMEM; - ret = isc_formats_init(isc); if (ret < 0) { v4l2_err(&isc->v4l2_dev, @@ -1639,6 +1979,12 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) return 0; } +static const struct v4l2_async_notifier_operations isc_async_ops = { + .bound = isc_async_bound, + .unbind = isc_async_unbind, + .complete = isc_async_complete, +}; + static void isc_subdev_cleanup(struct isc_device *isc) { struct isc_subdev_entity *subdev_entity; @@ -1716,7 +2062,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity), GFP_KERNEL); - if (subdev_entity == NULL) { + if (!subdev_entity) { of_node_put(rem); ret = -ENOMEM; break; @@ -1724,7 +2070,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc) subdev_entity->asd = devm_kzalloc(dev, sizeof(*subdev_entity->asd), GFP_KERNEL); - if (subdev_entity->asd == NULL) { + if (!subdev_entity->asd) { of_node_put(rem); ret = -ENOMEM; break; @@ -1815,25 +2161,37 @@ static int atmel_isc_probe(struct platform_device *pdev) return ret; } + ret = clk_prepare_enable(isc->hclock); + if (ret) { + dev_err(dev, "failed to enable hclock: %d\n", ret); + return ret; + } + ret = isc_clk_init(isc); if (ret) { dev_err(dev, "failed to init isc clock: %d\n", ret); - goto clean_isc_clk; + goto unprepare_hclk; } isc->ispck = isc->isc_clks[ISC_ISPCK].clk; + ret = clk_prepare_enable(isc->ispck); + if (ret) { + dev_err(dev, "failed to enable ispck: %d\n", ret); + goto unprepare_hclk; + } + /* ispck should be greater or equal to hclock */ ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); if (ret) { dev_err(dev, "failed to set ispck rate: %d\n", ret); - goto clean_isc_clk; + goto unprepare_clk; } ret = v4l2_device_register(dev, &isc->v4l2_dev); if (ret) { dev_err(dev, "unable to register v4l2 device.\n"); - goto clean_isc_clk; + goto unprepare_clk; } ret = isc_parse_dt(dev, isc); @@ -1851,9 +2209,7 @@ static int atmel_isc_probe(struct platform_device *pdev) list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { subdev_entity->notifier.subdevs = &subdev_entity->asd; subdev_entity->notifier.num_subdevs = 1; - subdev_entity->notifier.bound = isc_async_bound; - subdev_entity->notifier.unbind = isc_async_unbind; - subdev_entity->notifier.complete = isc_async_complete; + subdev_entity->notifier.ops = &isc_async_ops; ret = v4l2_async_notifier_register(&isc->v4l2_dev, &subdev_entity->notifier); @@ -1866,7 +2222,9 @@ static int atmel_isc_probe(struct platform_device *pdev) break; } + pm_runtime_set_active(dev); pm_runtime_enable(dev); + pm_request_idle(dev); return 0; @@ -1876,7 +2234,11 @@ cleanup_subdev: unregister_v4l2_device: v4l2_device_unregister(&isc->v4l2_dev); -clean_isc_clk: +unprepare_clk: + clk_disable_unprepare(isc->ispck); +unprepare_hclk: + clk_disable_unprepare(isc->hclock); + isc_clk_cleanup(isc); return ret; @@ -1887,6 +2249,8 @@ static int atmel_isc_remove(struct platform_device *pdev) struct isc_device *isc = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); + clk_disable_unprepare(isc->ispck); + clk_disable_unprepare(isc->hclock); isc_subdev_cleanup(isc); diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index 891fa2505efa..e900995143a3 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -411,7 +411,7 @@ static void buffer_queue(struct vb2_buffer *vb) spin_lock_irqsave(&isi->irqlock, flags); list_add_tail(&buf->list, &isi->video_buffer_list); - if (isi->active == NULL) { + if (!isi->active) { isi->active = buf; if (vb2_is_streaming(vb->vb2_queue)) start_dma(isi, buf); @@ -1038,10 +1038,8 @@ static int isi_formats_init(struct atmel_isi *isi) isi->user_formats = devm_kcalloc(isi->dev, num_fmts, sizeof(struct isi_format *), GFP_KERNEL); - if (!isi->user_formats) { - dev_err(isi->dev, "could not allocate memory\n"); + if (!isi->user_formats) return -ENOMEM; - } memcpy(isi->user_formats, isi_fmts, num_fmts * sizeof(struct isi_format *)); @@ -1105,6 +1103,12 @@ static int isi_graph_notify_bound(struct v4l2_async_notifier *notifier, return 0; } +static const struct v4l2_async_notifier_operations isi_graph_notify_ops = { + .bound = isi_graph_notify_bound, + .unbind = isi_graph_notify_unbind, + .complete = isi_graph_notify_complete, +}; + static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node) { struct device_node *ep = NULL; @@ -1143,7 +1147,7 @@ static int isi_graph_init(struct atmel_isi *isi) /* Register the subdevices notifier. */ subdevs = devm_kzalloc(isi->dev, sizeof(*subdevs), GFP_KERNEL); - if (subdevs == NULL) { + if (!subdevs) { of_node_put(isi->entity.node); return -ENOMEM; } @@ -1152,9 +1156,7 @@ static int isi_graph_init(struct atmel_isi *isi) isi->notifier.subdevs = subdevs; isi->notifier.num_subdevs = 1; - isi->notifier.bound = isi_graph_notify_bound; - isi->notifier.unbind = isi_graph_notify_unbind; - isi->notifier.complete = isi_graph_notify_complete; + isi->notifier.ops = &isi_graph_notify_ops; ret = v4l2_async_notifier_register(&isi->v4l2_dev, &isi->notifier); if (ret < 0) { @@ -1176,10 +1178,8 @@ static int atmel_isi_probe(struct platform_device *pdev) int ret, i; isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL); - if (!isi) { - dev_err(&pdev->dev, "Can't allocate interface!\n"); + if (!isi) return -ENOMEM; - } isi->pclk = devm_clk_get(&pdev->dev, "isi_clk"); if (IS_ERR(isi->pclk)) @@ -1204,7 +1204,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return ret; isi->vdev = video_device_alloc(); - if (isi->vdev == NULL) { + if (!isi->vdev) { ret = -ENOMEM; goto err_vdev_alloc; } diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c index 37169054b828..478eb2f7d723 100644 --- a/drivers/media/platform/blackfin/ppi.c +++ b/drivers/media/platform/blackfin/ppi.c @@ -338,7 +338,6 @@ struct ppi_if *ppi_create_instance(struct platform_device *pdev, ppi = kzalloc(sizeof(*ppi), GFP_KERNEL); if (!ppi) { peripheral_free_list(info->pin_req); - dev_err(&pdev->dev, "unable to allocate memory for ppi handle\n"); return NULL; } ppi->ops = &ppi_ops; diff --git a/drivers/media/platform/cec-gpio/Makefile b/drivers/media/platform/cec-gpio/Makefile new file mode 100644 index 000000000000..e82b258afa55 --- /dev/null +++ b/drivers/media/platform/cec-gpio/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CEC_GPIO) += cec-gpio.o diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c new file mode 100644 index 000000000000..5debdf08fbe7 --- /dev/null +++ b/drivers/media/platform/cec-gpio/cec-gpio.c @@ -0,0 +1,239 @@ +/* + * 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. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/gpio/consumer.h> +#include <media/cec-pin.h> + +struct cec_gpio { + struct cec_adapter *adap; + struct device *dev; + + struct gpio_desc *cec_gpio; + int cec_irq; + bool cec_is_low; + bool cec_have_irq; + + struct gpio_desc *hpd_gpio; + int hpd_irq; + bool hpd_is_high; + ktime_t hpd_ts; +}; + +static bool cec_gpio_read(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->cec_is_low) + return false; + return gpiod_get_value(cec->cec_gpio); +} + +static void cec_gpio_high(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (!cec->cec_is_low) + return; + cec->cec_is_low = false; + gpiod_set_value(cec->cec_gpio, 1); +} + +static void cec_gpio_low(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->cec_is_low) + return; + if (WARN_ON_ONCE(cec->cec_have_irq)) + free_irq(cec->cec_irq, cec); + cec->cec_have_irq = false; + cec->cec_is_low = true; + gpiod_set_value(cec->cec_gpio, 0); +} + +static irqreturn_t cec_hpd_gpio_irq_handler_thread(int irq, void *priv) +{ + struct cec_gpio *cec = priv; + + cec_queue_pin_hpd_event(cec->adap, cec->hpd_is_high, cec->hpd_ts); + return IRQ_HANDLED; +} + +static irqreturn_t cec_hpd_gpio_irq_handler(int irq, void *priv) +{ + struct cec_gpio *cec = priv; + bool is_high = gpiod_get_value(cec->hpd_gpio); + + if (is_high == cec->hpd_is_high) + return IRQ_HANDLED; + cec->hpd_ts = ktime_get(); + cec->hpd_is_high = is_high; + return IRQ_WAKE_THREAD; +} + +static irqreturn_t cec_gpio_irq_handler(int irq, void *priv) +{ + struct cec_gpio *cec = priv; + + cec_pin_changed(cec->adap, gpiod_get_value(cec->cec_gpio)); + return IRQ_HANDLED; +} + +static bool cec_gpio_enable_irq(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->cec_have_irq) + return true; + + if (request_irq(cec->cec_irq, cec_gpio_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + adap->name, cec)) + return false; + cec->cec_have_irq = true; + return true; +} + +static void cec_gpio_disable_irq(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (cec->cec_have_irq) + free_irq(cec->cec_irq, cec); + cec->cec_have_irq = false; +} + +static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + seq_printf(file, "mode: %s\n", cec->cec_is_low ? "low-drive" : "read"); + if (cec->cec_have_irq) + seq_printf(file, "using irq: %d\n", cec->cec_irq); + if (cec->hpd_gpio) + seq_printf(file, "hpd: %s\n", + cec->hpd_is_high ? "high" : "low"); +} + +static int cec_gpio_read_hpd(struct cec_adapter *adap) +{ + struct cec_gpio *cec = cec_get_drvdata(adap); + + if (!cec->hpd_gpio) + return -ENOTTY; + return gpiod_get_value(cec->hpd_gpio); +} + +static void cec_gpio_free(struct cec_adapter *adap) +{ + cec_gpio_disable_irq(adap); +} + +static const struct cec_pin_ops cec_gpio_pin_ops = { + .read = cec_gpio_read, + .low = cec_gpio_low, + .high = cec_gpio_high, + .enable_irq = cec_gpio_enable_irq, + .disable_irq = cec_gpio_disable_irq, + .status = cec_gpio_status, + .free = cec_gpio_free, + .read_hpd = cec_gpio_read_hpd, +}; + +static int cec_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cec_gpio *cec; + int ret; + + cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL); + if (!cec) + return -ENOMEM; + + cec->dev = dev; + + cec->cec_gpio = devm_gpiod_get(dev, "cec", GPIOD_IN); + if (IS_ERR(cec->cec_gpio)) + return PTR_ERR(cec->cec_gpio); + cec->cec_irq = gpiod_to_irq(cec->cec_gpio); + + cec->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN); + if (IS_ERR(cec->hpd_gpio)) + return PTR_ERR(cec->hpd_gpio); + + cec->adap = cec_pin_allocate_adapter(&cec_gpio_pin_ops, + cec, pdev->name, CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | + CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN); + if (IS_ERR(cec->adap)) + return PTR_ERR(cec->adap); + + if (cec->hpd_gpio) { + cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio); + ret = devm_request_threaded_irq(dev, cec->hpd_irq, + cec_hpd_gpio_irq_handler, + cec_hpd_gpio_irq_handler_thread, + IRQF_ONESHOT | + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "hpd-gpio", cec); + if (ret) + return ret; + } + + ret = cec_register_adapter(cec->adap, &pdev->dev); + if (ret) { + cec_delete_adapter(cec->adap); + return ret; + } + + platform_set_drvdata(pdev, cec); + return 0; +} + +static int cec_gpio_remove(struct platform_device *pdev) +{ + struct cec_gpio *cec = platform_get_drvdata(pdev); + + cec_unregister_adapter(cec->adap); + return 0; +} + +static const struct of_device_id cec_gpio_match[] = { + { + .compatible = "cec-gpio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, cec_gpio_match); + +static struct platform_driver cec_gpio_pdrv = { + .probe = cec_gpio_probe, + .remove = cec_gpio_remove, + .driver = { + .name = "cec-gpio", + .of_match_table = cec_gpio_match, + }, +}; + +module_platform_driver(cec_gpio_pdrv); + +MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CEC GPIO driver"); diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 291c40933935..bfc4ecf6f068 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c @@ -417,6 +417,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx, dev->devtype->product != CODA_DX6) size += ysize / 4; name = kasprintf(GFP_KERNEL, "fb%d", i); + if (!name) { + coda_free_framebuffers(ctx); + return -ENOMEM; + } ret = coda_alloc_context_buf(ctx, &ctx->internal_frames[i], size, name); kfree(name); diff --git a/drivers/media/platform/davinci/ccdc_hw_device.h b/drivers/media/platform/davinci/ccdc_hw_device.h index f1b521045d64..3482178cbf01 100644 --- a/drivers/media/platform/davinci/ccdc_hw_device.h +++ b/drivers/media/platform/davinci/ccdc_hw_device.h @@ -82,8 +82,8 @@ struct ccdc_hw_device { }; /* Used by CCDC module to register & unregister with vpfe capture driver */ -int vpfe_register_ccdc_device(struct ccdc_hw_device *dev); -void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev); +int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev); +void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev); #endif #endif diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c index 6d492dc4c3a9..89cb3094d7e6 100644 --- a/drivers/media/platform/davinci/dm355_ccdc.c +++ b/drivers/media/platform/davinci/dm355_ccdc.c @@ -841,7 +841,7 @@ static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) return 0; } -static struct ccdc_hw_device ccdc_hw_dev = { +static const struct ccdc_hw_device ccdc_hw_dev = { .name = "DM355 CCDC", .owner = THIS_MODULE, .hw_ops = { diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c index 3b2d8a9317b8..5fa0a1f32536 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc.c +++ b/drivers/media/platform/davinci/dm644x_ccdc.c @@ -776,7 +776,7 @@ static void ccdc_restore_context(void) regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT); regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR); } -static struct ccdc_hw_device ccdc_hw_dev = { +static const struct ccdc_hw_device ccdc_hw_dev = { .name = "DM6446 CCDC", .owner = THIS_MODULE, .hw_ops = { diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index 5813b49391ed..d5ff58494c1e 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -1000,7 +1000,7 @@ static int isif_close(struct device *device) return 0; } -static struct ccdc_hw_device isif_hw_dev = { +static const struct ccdc_hw_device isif_hw_dev = { .name = "ISIF", .owner = THIS_MODULE, .hw_ops = { diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 13d027031ff0..6aabd21fe69f 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -122,7 +122,7 @@ static irqreturn_t venc_isr(int irq, void *arg) int fid; int i; - if ((NULL == arg) || (NULL == disp_dev->dev[0])) + if (!arg || !disp_dev->dev[0]) return IRQ_HANDLED; if (venc_is_second_field(disp_dev)) @@ -337,10 +337,10 @@ static void vpbe_stop_streaming(struct vb2_queue *vq) vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } else { - if (layer->cur_frm != NULL) + if (layer->cur_frm) vb2_buffer_done(&layer->cur_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); - if (layer->next_frm != NULL) + if (layer->next_frm) vb2_buffer_done(&layer->next_frm->vb.vb2_buf, VB2_BUF_STATE_ERROR); } @@ -947,7 +947,7 @@ static int vpbe_display_s_std(struct file *file, void *priv, if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - if (NULL != vpbe_dev->ops.s_std) { + if (vpbe_dev->ops.s_std) { ret = vpbe_dev->ops.s_std(vpbe_dev, std_id); if (ret) { v4l2_err(&vpbe_dev->v4l2_dev, @@ -1000,8 +1000,7 @@ static int vpbe_display_enum_output(struct file *file, void *priv, v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n"); /* Enumerate outputs */ - - if (NULL == vpbe_dev->ops.enum_outputs) + if (!vpbe_dev->ops.enum_outputs) return -EINVAL; ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output); @@ -1030,7 +1029,7 @@ static int vpbe_display_s_output(struct file *file, void *priv, if (vb2_is_busy(&layer->buffer_queue)) return -EBUSY; - if (NULL == vpbe_dev->ops.set_output) + if (!vpbe_dev->ops.set_output) return -EINVAL; ret = vpbe_dev->ops.set_output(vpbe_dev, i); @@ -1077,7 +1076,7 @@ vpbe_display_enum_dv_timings(struct file *file, void *priv, v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_TIMINGS\n"); /* Enumerate outputs */ - if (NULL == vpbe_dev->ops.enum_dv_timings) + if (!vpbe_dev->ops.enum_dv_timings) return -EINVAL; ret = vpbe_dev->ops.enum_dv_timings(vpbe_dev, timings); @@ -1292,7 +1291,7 @@ static int vpbe_device_get(struct device *dev, void *data) if (strcmp("vpbe_controller", pdev->name) == 0) vpbe_disp->vpbe_dev = platform_get_drvdata(pdev); - if (strstr(pdev->name, "vpbe-osd") != NULL) + if (strstr(pdev->name, "vpbe-osd")) vpbe_disp->osd_device = platform_get_drvdata(pdev); return 0; @@ -1305,15 +1304,10 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev, struct video_device *vbd = NULL; /* Allocate memory for four plane display objects */ - - disp_dev->dev[i] = - kzalloc(sizeof(struct vpbe_layer), GFP_KERNEL); - - /* If memory allocation fails, return error */ - if (!disp_dev->dev[i]) { - printk(KERN_ERR "ran out of memory\n"); + disp_dev->dev[i] = kzalloc(sizeof(*disp_dev->dev[i]), GFP_KERNEL); + if (!disp_dev->dev[i]) return -ENOMEM; - } + spin_lock_init(&disp_dev->dev[i]->irqlock); mutex_init(&disp_dev->dev[i]->opslock); @@ -1397,8 +1391,7 @@ static int vpbe_display_probe(struct platform_device *pdev) printk(KERN_DEBUG "vpbe_display_probe\n"); /* Allocate memory for vpbe_display */ - disp_dev = devm_kzalloc(&pdev->dev, sizeof(struct vpbe_display), - GFP_KERNEL); + disp_dev = devm_kzalloc(&pdev->dev, sizeof(*disp_dev), GFP_KERNEL); if (!disp_dev) return -ENOMEM; @@ -1414,7 +1407,7 @@ static int vpbe_display_probe(struct platform_device *pdev) v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev; /* Initialize the vpbe display controller */ - if (NULL != disp_dev->vpbe_dev->ops.initialize) { + if (disp_dev->vpbe_dev->ops.initialize) { err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev, disp_dev->vpbe_dev); if (err) { @@ -1482,7 +1475,7 @@ static int vpbe_display_probe(struct platform_device *pdev) probe_out: for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) { /* Unregister video device */ - if (disp_dev->dev[k] != NULL) { + if (disp_dev->dev[k]) { video_unregister_device(&disp_dev->dev[k]->video_dev); kfree(disp_dev->dev[k]); } @@ -1504,7 +1497,7 @@ static int vpbe_display_remove(struct platform_device *pdev) v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n"); /* deinitialize the vpbe display controller */ - if (NULL != vpbe_dev->ops.deinitialize) + if (vpbe_dev->ops.deinitialize) vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev); /* un-register device */ for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) { diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 6792da16d9c7..7b3f6f8e3dc8 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -115,7 +115,7 @@ static struct vpfe_config_params config_params = { }; /* ccdc device registered */ -static struct ccdc_hw_device *ccdc_dev; +static const struct ccdc_hw_device *ccdc_dev; /* lock for accessing ccdc information */ static DEFINE_MUTEX(ccdc_lock); /* ccdc configuration */ @@ -203,7 +203,7 @@ static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format) * vpfe_register_ccdc_device. CCDC module calls this to * register with vpfe capture */ -int vpfe_register_ccdc_device(struct ccdc_hw_device *dev) +int vpfe_register_ccdc_device(const struct ccdc_hw_device *dev) { int ret = 0; printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name); @@ -259,7 +259,7 @@ EXPORT_SYMBOL(vpfe_register_ccdc_device); * vpfe_unregister_ccdc_device. CCDC module calls this to * unregister with vpfe capture */ -void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev) +void vpfe_unregister_ccdc_device(const struct ccdc_hw_device *dev) { if (!dev) { printk(KERN_ERR "invalid ccdc device ptr\n"); diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 0ef36cec21d1..a89367ab1e06 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -1500,6 +1500,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier) return vpif_probe_complete(); } +static const struct v4l2_async_notifier_operations vpif_async_ops = { + .bound = vpif_async_bound, + .complete = vpif_async_complete, +}; + static struct vpif_capture_config * vpif_capture_get_pdata(struct platform_device *pdev) { @@ -1691,8 +1696,7 @@ static __init int vpif_probe(struct platform_device *pdev) } else { vpif_obj.notifier.subdevs = vpif_obj.config->asd; vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; - vpif_obj.notifier.bound = vpif_async_bound; - vpif_obj.notifier.complete = vpif_async_complete; + vpif_obj.notifier.ops = &vpif_async_ops; err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, &vpif_obj.notifier); if (err) { diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index 56fe4e5b396e..ff2f75a328c9 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1232,6 +1232,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier) return vpif_probe_complete(); } +static const struct v4l2_async_notifier_operations vpif_async_ops = { + .bound = vpif_async_bound, + .complete = vpif_async_complete, +}; + /* * vpif_probe: This function creates device entries by register itself to the * V4L2 driver and initializes fields of each channel objects @@ -1313,8 +1318,7 @@ static __init int vpif_probe(struct platform_device *pdev) } else { vpif_obj.notifier.subdevs = vpif_obj.config->asd; vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; - vpif_obj.notifier.bound = vpif_async_bound; - vpif_obj.notifier.complete = vpif_async_complete; + vpif_obj.notifier.ops = &vpif_async_ops; err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, &vpif_obj.notifier); if (err) { diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 43801509dabb..17854a379243 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -958,6 +958,51 @@ static struct gsc_pix_max gsc_v_100_max = { .target_rot_en_h = 2016, }; +static struct gsc_pix_max gsc_v_5250_max = { + .org_scaler_bypass_w = 8192, + .org_scaler_bypass_h = 8192, + .org_scaler_input_w = 4800, + .org_scaler_input_h = 3344, + .real_rot_dis_w = 4800, + .real_rot_dis_h = 3344, + .real_rot_en_w = 2016, + .real_rot_en_h = 2016, + .target_rot_dis_w = 4800, + .target_rot_dis_h = 3344, + .target_rot_en_w = 2016, + .target_rot_en_h = 2016, +}; + +static struct gsc_pix_max gsc_v_5420_max = { + .org_scaler_bypass_w = 8192, + .org_scaler_bypass_h = 8192, + .org_scaler_input_w = 4800, + .org_scaler_input_h = 3344, + .real_rot_dis_w = 4800, + .real_rot_dis_h = 3344, + .real_rot_en_w = 2048, + .real_rot_en_h = 2048, + .target_rot_dis_w = 4800, + .target_rot_dis_h = 3344, + .target_rot_en_w = 2016, + .target_rot_en_h = 2016, +}; + +static struct gsc_pix_max gsc_v_5433_max = { + .org_scaler_bypass_w = 8192, + .org_scaler_bypass_h = 8192, + .org_scaler_input_w = 4800, + .org_scaler_input_h = 3344, + .real_rot_dis_w = 4800, + .real_rot_dis_h = 3344, + .real_rot_en_w = 2047, + .real_rot_en_h = 2047, + .target_rot_dis_w = 4800, + .target_rot_dis_h = 3344, + .target_rot_en_w = 2016, + .target_rot_en_h = 2016, +}; + static struct gsc_pix_min gsc_v_100_min = { .org_w = 64, .org_h = 32, @@ -992,6 +1037,45 @@ static struct gsc_variant gsc_v_100_variant = { .local_sc_down = 2, }; +static struct gsc_variant gsc_v_5250_variant = { + .pix_max = &gsc_v_5250_max, + .pix_min = &gsc_v_100_min, + .pix_align = &gsc_v_100_align, + .in_buf_cnt = 32, + .out_buf_cnt = 32, + .sc_up_max = 8, + .sc_down_max = 16, + .poly_sc_down_max = 4, + .pre_sc_down_max = 4, + .local_sc_down = 2, +}; + +static struct gsc_variant gsc_v_5420_variant = { + .pix_max = &gsc_v_5420_max, + .pix_min = &gsc_v_100_min, + .pix_align = &gsc_v_100_align, + .in_buf_cnt = 32, + .out_buf_cnt = 32, + .sc_up_max = 8, + .sc_down_max = 16, + .poly_sc_down_max = 4, + .pre_sc_down_max = 4, + .local_sc_down = 2, +}; + +static struct gsc_variant gsc_v_5433_variant = { + .pix_max = &gsc_v_5433_max, + .pix_min = &gsc_v_100_min, + .pix_align = &gsc_v_100_align, + .in_buf_cnt = 32, + .out_buf_cnt = 32, + .sc_up_max = 8, + .sc_down_max = 16, + .poly_sc_down_max = 4, + .pre_sc_down_max = 4, + .local_sc_down = 2, +}; + static struct gsc_driverdata gsc_v_100_drvdata = { .variant = { [0] = &gsc_v_100_variant, @@ -1004,11 +1088,33 @@ static struct gsc_driverdata gsc_v_100_drvdata = { .num_clocks = 1, }; +static struct gsc_driverdata gsc_v_5250_drvdata = { + .variant = { + [0] = &gsc_v_5250_variant, + [1] = &gsc_v_5250_variant, + [2] = &gsc_v_5250_variant, + [3] = &gsc_v_5250_variant, + }, + .num_entities = 4, + .clk_names = { "gscl" }, + .num_clocks = 1, +}; + +static struct gsc_driverdata gsc_v_5420_drvdata = { + .variant = { + [0] = &gsc_v_5420_variant, + [1] = &gsc_v_5420_variant, + }, + .num_entities = 2, + .clk_names = { "gscl" }, + .num_clocks = 1, +}; + static struct gsc_driverdata gsc_5433_drvdata = { .variant = { - [0] = &gsc_v_100_variant, - [1] = &gsc_v_100_variant, - [2] = &gsc_v_100_variant, + [0] = &gsc_v_5433_variant, + [1] = &gsc_v_5433_variant, + [2] = &gsc_v_5433_variant, }, .num_entities = 3, .clk_names = { "pclk", "aclk", "aclk_xiu", "aclk_gsclbend" }, @@ -1017,13 +1123,21 @@ static struct gsc_driverdata gsc_5433_drvdata = { static const struct of_device_id exynos_gsc_match[] = { { - .compatible = "samsung,exynos5-gsc", - .data = &gsc_v_100_drvdata, + .compatible = "samsung,exynos5250-gsc", + .data = &gsc_v_5250_drvdata, + }, + { + .compatible = "samsung,exynos5420-gsc", + .data = &gsc_v_5420_drvdata, }, { .compatible = "samsung,exynos5433-gsc", .data = &gsc_5433_drvdata, }, + { + .compatible = "samsung,exynos5-gsc", + .data = &gsc_v_100_drvdata, + }, {}, }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); @@ -1045,6 +1159,9 @@ static int gsc_probe(struct platform_device *pdev) if (ret < 0) return ret; + if (drv_data == &gsc_v_100_drvdata) + dev_info(dev, "compatible 'exynos5-gsc' is deprecated\n"); + gsc->id = ret; if (gsc->id >= drv_data->num_entities) { dev_err(dev, "Invalid platform device id: %d\n", gsc->id); diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig index c480efb755f5..46a7d242a1a5 100644 --- a/drivers/media/platform/exynos4-is/Kconfig +++ b/drivers/media/platform/exynos4-is/Kconfig @@ -76,7 +76,7 @@ config VIDEO_EXYNOS4_ISP_DMA_CAPTURE depends on VIDEO_EXYNOS4_FIMC_IS select VIDEO_EXYNOS4_IS_COMMON default y - help + help This option enables an additional video device node exposing a V4L2 video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA. diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index d4656d5175d7..c15596b56dc9 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1405,6 +1405,11 @@ unlock: return media_device_register(&fmd->media_dev); } +static const struct v4l2_async_notifier_operations subdev_notifier_ops = { + .bound = subdev_notifier_bound, + .complete = subdev_notifier_complete, +}; + static int fimc_md_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1479,8 +1484,7 @@ static int fimc_md_probe(struct platform_device *pdev) if (fmd->num_sensors > 0) { fmd->subdev_notifier.subdevs = fmd->async_subdevs; fmd->subdev_notifier.num_subdevs = fmd->num_sensors; - fmd->subdev_notifier.bound = subdev_notifier_bound; - fmd->subdev_notifier.complete = subdev_notifier_complete; + fmd->subdev_notifier.ops = &subdev_notifier_ops; fmd->num_sensors = 0; ret = v4l2_async_notifier_register(&fmd->v4l2_dev, diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 4d29860d27b4..6f1b0c799e58 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -1004,11 +1004,12 @@ static int omap_vout_open(struct file *file) struct omap_vout_device *vout = NULL; vout = video_drvdata(file); - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); if (vout == NULL) return -ENODEV; + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); + /* for now, we only support single open */ if (vout->opened) return -EBUSY; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 1a428fe9f070..b7ff3842afc0 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1669,8 +1669,8 @@ static int isp_link_entity( break; } if (i == entity->num_pads) { - dev_err(isp->dev, "%s: no source pad in external entity\n", - __func__); + dev_err(isp->dev, "%s: no source pad in external entity %s\n", + __func__, entity->name); return -EINVAL; } @@ -2001,6 +2001,7 @@ static int isp_remove(struct platform_device *pdev) __omap3isp_put(isp, false); media_entity_enum_cleanup(&isp->crashed); + v4l2_async_notifier_cleanup(&isp->notifier); return 0; } @@ -2011,44 +2012,41 @@ enum isp_of_phy { ISP_OF_PHY_CSIPHY2, }; -static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, - struct isp_async_subdev *isd) +static int isp_fwnode_parse(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd) { + struct isp_async_subdev *isd = + container_of(asd, struct isp_async_subdev, asd); struct isp_bus_cfg *buscfg = &isd->bus; - struct v4l2_fwnode_endpoint vep; - unsigned int i; - int ret; bool csi1 = false; - - ret = v4l2_fwnode_endpoint_parse(fwnode, &vep); - if (ret) - return ret; + unsigned int i; dev_dbg(dev, "parsing endpoint %pOF, interface %u\n", - to_of_node(fwnode), vep.base.port); + to_of_node(vep->base.local_fwnode), vep->base.port); - switch (vep.base.port) { + switch (vep->base.port) { case ISP_OF_PHY_PARALLEL: buscfg->interface = ISP_INTERFACE_PARALLEL; buscfg->bus.parallel.data_lane_shift = - vep.bus.parallel.data_shift; + vep->bus.parallel.data_shift; buscfg->bus.parallel.clk_pol = - !!(vep.bus.parallel.flags + !!(vep->bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING); buscfg->bus.parallel.hs_pol = - !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); + !!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); buscfg->bus.parallel.vs_pol = - !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); + !!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); buscfg->bus.parallel.fld_pol = - !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); + !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); buscfg->bus.parallel.data_pol = - !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); - buscfg->bus.parallel.bt656 = vep.bus_type == V4L2_MBUS_BT656; + !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); + buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656; break; case ISP_OF_PHY_CSIPHY1: case ISP_OF_PHY_CSIPHY2: - switch (vep.bus_type) { + switch (vep->bus_type) { case V4L2_MBUS_CCP2: case V4L2_MBUS_CSI1: dev_dbg(dev, "CSI-1/CCP-2 configuration\n"); @@ -2060,11 +2058,11 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, break; default: dev_err(dev, "unsupported bus type %u\n", - vep.bus_type); + vep->bus_type); return -EINVAL; } - switch (vep.base.port) { + switch (vep->base.port) { case ISP_OF_PHY_CSIPHY1: if (csi1) buscfg->interface = ISP_INTERFACE_CCP2B_PHY1; @@ -2080,47 +2078,47 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, } if (csi1) { buscfg->bus.ccp2.lanecfg.clk.pos = - vep.bus.mipi_csi1.clock_lane; + vep->bus.mipi_csi1.clock_lane; buscfg->bus.ccp2.lanecfg.clk.pol = - vep.bus.mipi_csi1.lane_polarity[0]; + vep->bus.mipi_csi1.lane_polarity[0]; dev_dbg(dev, "clock lane polarity %u, pos %u\n", buscfg->bus.ccp2.lanecfg.clk.pol, buscfg->bus.ccp2.lanecfg.clk.pos); buscfg->bus.ccp2.lanecfg.data[0].pos = - vep.bus.mipi_csi1.data_lane; + vep->bus.mipi_csi1.data_lane; buscfg->bus.ccp2.lanecfg.data[0].pol = - vep.bus.mipi_csi1.lane_polarity[1]; + vep->bus.mipi_csi1.lane_polarity[1]; dev_dbg(dev, "data lane polarity %u, pos %u\n", buscfg->bus.ccp2.lanecfg.data[0].pol, buscfg->bus.ccp2.lanecfg.data[0].pos); buscfg->bus.ccp2.strobe_clk_pol = - vep.bus.mipi_csi1.clock_inv; - buscfg->bus.ccp2.phy_layer = vep.bus.mipi_csi1.strobe; + vep->bus.mipi_csi1.clock_inv; + buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe; buscfg->bus.ccp2.ccp2_mode = - vep.bus_type == V4L2_MBUS_CCP2; + vep->bus_type == V4L2_MBUS_CCP2; buscfg->bus.ccp2.vp_clk_pol = 1; buscfg->bus.ccp2.crc = 1; } else { buscfg->bus.csi2.lanecfg.clk.pos = - vep.bus.mipi_csi2.clock_lane; + vep->bus.mipi_csi2.clock_lane; buscfg->bus.csi2.lanecfg.clk.pol = - vep.bus.mipi_csi2.lane_polarities[0]; + vep->bus.mipi_csi2.lane_polarities[0]; dev_dbg(dev, "clock lane polarity %u, pos %u\n", buscfg->bus.csi2.lanecfg.clk.pol, buscfg->bus.csi2.lanecfg.clk.pos); buscfg->bus.csi2.num_data_lanes = - vep.bus.mipi_csi2.num_data_lanes; + vep->bus.mipi_csi2.num_data_lanes; for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { buscfg->bus.csi2.lanecfg.data[i].pos = - vep.bus.mipi_csi2.data_lanes[i]; + vep->bus.mipi_csi2.data_lanes[i]; buscfg->bus.csi2.lanecfg.data[i].pol = - vep.bus.mipi_csi2.lane_polarities[i + 1]; + vep->bus.mipi_csi2.lane_polarities[i + 1]; dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i, buscfg->bus.csi2.lanecfg.data[i].pol, @@ -2137,57 +2135,13 @@ static int isp_fwnode_parse(struct device *dev, struct fwnode_handle *fwnode, default: dev_warn(dev, "%pOF: invalid interface %u\n", - to_of_node(fwnode), vep.base.port); + to_of_node(vep->base.local_fwnode), vep->base.port); return -EINVAL; } return 0; } -static int isp_fwnodes_parse(struct device *dev, - struct v4l2_async_notifier *notifier) -{ - struct fwnode_handle *fwnode = NULL; - - notifier->subdevs = devm_kcalloc( - dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL); - if (!notifier->subdevs) - return -ENOMEM; - - while (notifier->num_subdevs < ISP_MAX_SUBDEVS && - (fwnode = fwnode_graph_get_next_endpoint( - of_fwnode_handle(dev->of_node), fwnode))) { - struct isp_async_subdev *isd; - - isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL); - if (!isd) - goto error; - - if (isp_fwnode_parse(dev, fwnode, isd)) { - devm_kfree(dev, isd); - continue; - } - - notifier->subdevs[notifier->num_subdevs] = &isd->asd; - - isd->asd.match.fwnode.fwnode = - fwnode_graph_get_remote_port_parent(fwnode); - if (!isd->asd.match.fwnode.fwnode) { - dev_warn(dev, "bad remote port parent\n"); - goto error; - } - - isd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - notifier->num_subdevs++; - } - - return notifier->num_subdevs; - -error: - fwnode_handle_put(fwnode); - return -EINVAL; -} - static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, @@ -2201,7 +2155,7 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) return ret; list_for_each_entry(sd, &v4l2_dev->subdevs, list) { - if (!sd->asd) + if (sd->notifier != &isp->notifier) continue; ret = isp_link_entity(isp, &sd->entity, @@ -2217,6 +2171,10 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) return media_device_register(&isp->media_dev); } +static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = { + .complete = isp_subdev_notifier_complete, +}; + /* * isp_probe - Probe ISP platform device * @pdev: Pointer to ISP platform device @@ -2256,15 +2214,17 @@ static int isp_probe(struct platform_device *pdev) if (ret) return ret; - ret = isp_fwnodes_parse(&pdev->dev, &isp->notifier); - if (ret < 0) - return ret; - isp->autoidle = autoidle; mutex_init(&isp->isp_mutex); spin_lock_init(&isp->stat_lock); + ret = v4l2_async_notifier_parse_fwnode_endpoints( + &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev), + isp_fwnode_parse); + if (ret < 0) + goto error; + isp->dev = &pdev->dev; isp->ref_count = 0; @@ -2385,7 +2345,7 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_register_entities; - isp->notifier.complete = isp_subdev_notifier_complete; + isp->notifier.ops = &isp_subdev_notifier_ops; ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier); if (ret) @@ -2406,6 +2366,7 @@ error_isp: isp_xclk_cleanup(isp); __omap3isp_put(isp, false); error: + v4l2_async_notifier_cleanup(&isp->notifier); mutex_destroy(&isp->isp_mutex); return ret; diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index e528df6efc09..8b9043db94b3 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -220,14 +220,11 @@ struct isp_device { unsigned int sbl_resources; unsigned int subclk_resources; - -#define ISP_MAX_SUBDEVS 8 - struct v4l2_subdev *subdevs[ISP_MAX_SUBDEVS]; }; struct isp_async_subdev { - struct isp_bus_cfg bus; struct v4l2_async_subdev asd; + struct isp_bus_cfg bus; }; #define v4l2_subdev_to_bus_cfg(sd) \ diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index edca993c2b1f..9d3f0cb1d95a 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -2221,6 +2221,11 @@ static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier, mutex_unlock(&pcdev->mlock); } +static const struct v4l2_async_notifier_operations pxa_camera_sensor_ops = { + .bound = pxa_camera_sensor_bound, + .unbind = pxa_camera_sensor_unbind, +}; + /* * Driver probe, remove, suspend and resume operations */ @@ -2489,8 +2494,7 @@ static int pxa_camera_probe(struct platform_device *pdev) pcdev->asds[0] = &pcdev->asd; pcdev->notifier.subdevs = pcdev->asds; pcdev->notifier.num_subdevs = 1; - pcdev->notifier.bound = pxa_camera_sensor_bound; - pcdev->notifier.unbind = pxa_camera_sensor_unbind; + pcdev->notifier.ops = &pxa_camera_sensor_ops; if (!of_have_populated_dt()) pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C; diff --git a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c index b22d2dfcd3c2..55232a912950 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-vfe.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-vfe.c @@ -622,6 +622,9 @@ static void vfe_set_xbar_cfg(struct vfe_device *vfe, struct vfe_output *output, reg = VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_EN; if (p == V4L2_PIX_FMT_NV12 || p == V4L2_PIX_FMT_NV16) reg |= VFE_0_BUS_XBAR_CFG_x_M_PAIR_STREAM_SWAP_INTER_INTRA; + } else { + /* On current devices output->wm_num is always <= 2 */ + break; } if (output->wm_idx[i] % 2 == 1) diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c index cf4219e871bd..ffaa2849e0c1 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss-video.c +++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c @@ -21,7 +21,6 @@ #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-mc.h> -#include <media/videobuf-core.h> #include <media/videobuf2-dma-sg.h> #include "camss-video.h" diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c index a3760b5dd1d1..390a42c17b66 100644 --- a/drivers/media/platform/qcom/camss-8x16/camss.c +++ b/drivers/media/platform/qcom/camss-8x16/camss.c @@ -601,6 +601,11 @@ static int camss_subdev_notifier_complete(struct v4l2_async_notifier *async) return media_device_register(&camss->media_dev); } +static const struct v4l2_async_notifier_operations camss_subdev_notifier_ops = { + .bound = camss_subdev_notifier_bound, + .complete = camss_subdev_notifier_complete, +}; + static const struct media_device_ops camss_media_ops = { .link_notify = v4l2_pipeline_link_notify, }; @@ -655,8 +660,7 @@ static int camss_probe(struct platform_device *pdev) goto err_register_entities; if (camss->notifier.num_subdevs) { - camss->notifier.bound = camss_subdev_notifier_bound; - camss->notifier.complete = camss_subdev_notifier_complete; + camss->notifier.ops = &camss_subdev_notifier_ops; ret = v4l2_async_notifier_register(&camss->v4l2_dev, &camss->notifier); diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index cba092bcb76d..a0fe80df0cbd 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -194,7 +194,6 @@ struct venus_buffer { * @fh: a holder of v4l file handle structure * @streamon_cap: stream on flag for capture queue * @streamon_out: stream on flag for output queue - * @cmd_stop: a flag to signal encoder/decoder commands * @width: current capture width * @height: current capture height * @out_width: current output width @@ -258,7 +257,6 @@ struct venus_inst { } controls; struct v4l2_fh fh; unsigned int streamon_cap, streamon_out; - bool cmd_stop; u32 width; u32 height; u32 out_width; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 9b2a401a4891..0ce9559a2924 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -623,13 +623,6 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb) mutex_lock(&inst->lock); - if (inst->cmd_stop) { - vbuf->flags |= V4L2_BUF_FLAG_LAST; - v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); - inst->cmd_stop = false; - goto unlock; - } - v4l2_m2m_buf_queue(m2m_ctx, vbuf); if (!(inst->streamon_out & inst->streamon_cap)) diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index c09490876516..ba29fd4d4984 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -484,6 +484,7 @@ int hfi_session_process_buf(struct venus_inst *inst, struct hfi_frame_data *fd) return -EINVAL; } +EXPORT_SYMBOL_GPL(hfi_session_process_buf); irqreturn_t hfi_isr_thread(int irq, void *dev_id) { diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index 1caae8feaa36..734ce11b0ed0 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -344,7 +344,7 @@ static int venus_alloc(struct venus_hfi_device *hdev, struct mem_desc *desc, desc->attrs = DMA_ATTR_WRITE_COMBINE; desc->size = ALIGN(size, SZ_4K); - desc->kva = dma_alloc_attrs(dev, size, &desc->da, GFP_KERNEL, + desc->kva = dma_alloc_attrs(dev, desc->size, &desc->da, GFP_KERNEL, desc->attrs); if (!desc->kva) return -ENOMEM; @@ -710,10 +710,8 @@ static int venus_interface_queues_init(struct venus_hfi_device *hdev) if (ret) return ret; - hdev->ifaceq_table.kva = desc.kva; - hdev->ifaceq_table.da = desc.da; - hdev->ifaceq_table.size = IFACEQ_TABLE_SIZE; - offset = hdev->ifaceq_table.size; + hdev->ifaceq_table = desc; + offset = IFACEQ_TABLE_SIZE; for (i = 0; i < IFACEQ_NUM; i++) { queue = &hdev->queues[i]; @@ -755,9 +753,7 @@ static int venus_interface_queues_init(struct venus_hfi_device *hdev) if (ret) { hdev->sfr.da = 0; } else { - hdev->sfr.da = desc.da; - hdev->sfr.kva = desc.kva; - hdev->sfr.size = ALIGNED_SFR_SIZE; + hdev->sfr = desc; sfr = hdev->sfr.kva; sfr->buf_size = ALIGNED_SFR_SIZE; } diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index da611a5eb670..c9e9576bb08a 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -469,8 +469,14 @@ static int vdec_subscribe_event(struct v4l2_fh *fh, static int vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) { - if (cmd->cmd != V4L2_DEC_CMD_STOP) + switch (cmd->cmd) { + case V4L2_DEC_CMD_STOP: + if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) + return -EINVAL; + break; + default: return -EINVAL; + } return 0; } @@ -479,6 +485,7 @@ static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) { struct venus_inst *inst = to_inst(file); + struct hfi_frame_data fdata = {0}; int ret; ret = vdec_try_decoder_cmd(file, fh, cmd); @@ -486,12 +493,23 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) return ret; mutex_lock(&inst->lock); - inst->cmd_stop = true; - mutex_unlock(&inst->lock); - hfi_session_flush(inst); + /* + * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder + * input to signal EOS. + */ + if (!(inst->streamon_out & inst->streamon_cap)) + goto unlock; + + fdata.buffer_type = HFI_BUFFER_INPUT; + fdata.flags |= HFI_BUFFERFLAG_EOS; + fdata.device_addr = 0xdeadbeef; - return 0; + ret = hfi_session_process_buf(inst, &fdata); + +unlock: + mutex_unlock(&inst->lock); + return ret; } static const struct v4l2_ioctl_ops vdec_ioctl_ops = { @@ -718,7 +736,6 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) inst->reconfig = false; inst->sequence_cap = 0; inst->sequence_out = 0; - inst->cmd_stop = false; ret = vdec_init_session(inst); if (ret) @@ -807,11 +824,6 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, vb->timestamp = timestamp_us * NSEC_PER_USEC; vbuf->sequence = inst->sequence_cap++; - if (inst->cmd_stop) { - vbuf->flags |= V4L2_BUF_FLAG_LAST; - inst->cmd_stop = false; - } - if (vbuf->flags & V4L2_BUF_FLAG_LAST) { const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 6f123a387cf9..3fcf0e9b7b29 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -963,13 +963,12 @@ static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type, if (!vbuf) return; - vb = &vbuf->vb2_buf; - vb->planes[0].bytesused = bytesused; - vb->planes[0].data_offset = data_offset; - vbuf->flags = flags; if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + vb = &vbuf->vb2_buf; + vb2_set_plane_payload(vb, 0, bytesused + data_offset); + vb->planes[0].data_offset = data_offset; vb->timestamp = timestamp_us * NSEC_PER_USEC; vbuf->sequence = inst->sequence_cap++; } else { diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 142de447aaaa..108d776f3265 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -21,6 +21,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <media/v4l2-async.h> #include <media/v4l2-fwnode.h> #include "rcar-vin.h" @@ -77,14 +78,14 @@ static int rvin_digital_notify_complete(struct v4l2_async_notifier *notifier) int ret; /* Verify subdevices mbus format */ - if (!rvin_mbus_supported(&vin->digital)) { + if (!rvin_mbus_supported(vin->digital)) { vin_err(vin, "Unsupported media bus format for %s\n", - vin->digital.subdev->name); + vin->digital->subdev->name); return -EINVAL; } vin_dbg(vin, "Found media bus format for %s: %d\n", - vin->digital.subdev->name, vin->digital.code); + vin->digital->subdev->name, vin->digital->code); ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); if (ret < 0) { @@ -103,7 +104,7 @@ static void rvin_digital_notify_unbind(struct v4l2_async_notifier *notifier, vin_dbg(vin, "unbind digital subdev %s\n", subdev->name); rvin_v4l2_remove(vin); - vin->digital.subdev = NULL; + vin->digital->subdev = NULL; } static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, @@ -120,117 +121,75 @@ static int rvin_digital_notify_bound(struct v4l2_async_notifier *notifier, ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); if (ret < 0) return ret; - vin->digital.source_pad = ret; + vin->digital->source_pad = ret; ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK); - vin->digital.sink_pad = ret < 0 ? 0 : ret; + vin->digital->sink_pad = ret < 0 ? 0 : ret; - vin->digital.subdev = subdev; + vin->digital->subdev = subdev; vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n", - subdev->name, vin->digital.source_pad, - vin->digital.sink_pad); + subdev->name, vin->digital->source_pad, + vin->digital->sink_pad); return 0; } +static const struct v4l2_async_notifier_operations rvin_digital_notify_ops = { + .bound = rvin_digital_notify_bound, + .unbind = rvin_digital_notify_unbind, + .complete = rvin_digital_notify_complete, +}; + -static int rvin_digitial_parse_v4l2(struct rvin_dev *vin, - struct device_node *ep, - struct v4l2_mbus_config *mbus_cfg) +static int rvin_digital_parse_v4l2(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd) { - struct v4l2_fwnode_endpoint v4l2_ep; - int ret; + struct rvin_dev *vin = dev_get_drvdata(dev); + struct rvin_graph_entity *rvge = + container_of(asd, struct rvin_graph_entity, asd); - ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep); - if (ret) { - vin_err(vin, "Could not parse v4l2 endpoint\n"); - return -EINVAL; - } + if (vep->base.port || vep->base.id) + return -ENOTCONN; - mbus_cfg->type = v4l2_ep.bus_type; + rvge->mbus_cfg.type = vep->bus_type; - switch (mbus_cfg->type) { + switch (rvge->mbus_cfg.type) { case V4L2_MBUS_PARALLEL: vin_dbg(vin, "Found PARALLEL media bus\n"); - mbus_cfg->flags = v4l2_ep.bus.parallel.flags; + rvge->mbus_cfg.flags = vep->bus.parallel.flags; break; case V4L2_MBUS_BT656: vin_dbg(vin, "Found BT656 media bus\n"); - mbus_cfg->flags = 0; + rvge->mbus_cfg.flags = 0; break; default: vin_err(vin, "Unknown media bus type\n"); return -EINVAL; } - return 0; -} - -static int rvin_digital_graph_parse(struct rvin_dev *vin) -{ - struct device_node *ep, *np; - int ret; - - vin->digital.asd.match.fwnode.fwnode = NULL; - vin->digital.subdev = NULL; - - /* - * Port 0 id 0 is local digital input, try to get it. - * Not all instances can or will have this, that is OK - */ - ep = of_graph_get_endpoint_by_regs(vin->dev->of_node, 0, 0); - if (!ep) - return 0; - - np = of_graph_get_remote_port_parent(ep); - if (!np) { - vin_err(vin, "No remote parent for digital input\n"); - of_node_put(ep); - return -EINVAL; - } - of_node_put(np); - - ret = rvin_digitial_parse_v4l2(vin, ep, &vin->digital.mbus_cfg); - of_node_put(ep); - if (ret) - return ret; - - vin->digital.asd.match.fwnode.fwnode = of_fwnode_handle(np); - vin->digital.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; + vin->digital = rvge; return 0; } static int rvin_digital_graph_init(struct rvin_dev *vin) { - struct v4l2_async_subdev **subdevs = NULL; int ret; - ret = rvin_digital_graph_parse(vin); + ret = v4l2_async_notifier_parse_fwnode_endpoints( + vin->dev, &vin->notifier, + sizeof(struct rvin_graph_entity), rvin_digital_parse_v4l2); if (ret) return ret; - if (!vin->digital.asd.match.fwnode.fwnode) { - vin_dbg(vin, "No digital subdevice found\n"); + if (!vin->digital) return -ENODEV; - } - - /* Register the subdevices notifier. */ - subdevs = devm_kzalloc(vin->dev, sizeof(*subdevs), GFP_KERNEL); - if (subdevs == NULL) - return -ENOMEM; - - subdevs[0] = &vin->digital.asd; vin_dbg(vin, "Found digital subdevice %pOF\n", - to_of_node(subdevs[0]->match.fwnode.fwnode)); - - vin->notifier.num_subdevs = 1; - vin->notifier.subdevs = subdevs; - vin->notifier.bound = rvin_digital_notify_bound; - vin->notifier.unbind = rvin_digital_notify_unbind; - vin->notifier.complete = rvin_digital_notify_complete; + to_of_node(vin->digital->asd.match.fwnode.fwnode)); + vin->notifier.ops = &rvin_digital_notify_ops; ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier); if (ret < 0) { vin_err(vin, "Notifier registration failed\n"); @@ -290,6 +249,8 @@ static int rcar_vin_probe(struct platform_device *pdev) if (ret) return ret; + platform_set_drvdata(pdev, vin); + ret = rvin_digital_graph_init(vin); if (ret < 0) goto error; @@ -297,11 +258,10 @@ static int rcar_vin_probe(struct platform_device *pdev) pm_suspend_ignore_children(&pdev->dev, true); pm_runtime_enable(&pdev->dev); - platform_set_drvdata(pdev, vin); - return 0; error: rvin_dma_remove(vin); + v4l2_async_notifier_cleanup(&vin->notifier); return ret; } @@ -313,6 +273,7 @@ static int rcar_vin_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); v4l2_async_notifier_unregister(&vin->notifier); + v4l2_async_notifier_cleanup(&vin->notifier); rvin_dma_remove(vin); diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index b136844499f6..23fdff7a7370 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -183,7 +183,7 @@ static int rvin_setup(struct rvin_dev *vin) /* * Input interface */ - switch (vin->digital.code) { + switch (vin->digital->code) { case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; @@ -191,7 +191,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ - vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; input_is_yuv = true; break; @@ -200,7 +200,7 @@ static int rvin_setup(struct rvin_dev *vin) break; case MEDIA_BUS_FMT_UYVY10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ - vnmc |= vin->digital.mbus_cfg.type == V4L2_MBUS_BT656 ? + vnmc |= vin->digital->mbus_cfg.type == V4L2_MBUS_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; input_is_yuv = true; break; @@ -212,11 +212,11 @@ static int rvin_setup(struct rvin_dev *vin) dmr2 = VNDMR2_FTEV | VNDMR2_VLV(1); /* Hsync Signal Polarity Select */ - if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) + if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) dmr2 |= VNDMR2_HPS; /* Vsync Signal Polarity Select */ - if (!(vin->digital.mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) + if (!(vin->digital->mbus_cfg.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) dmr2 |= VNDMR2_VPS; /* diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index dd37ea811680..b479b882da12 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -111,7 +111,7 @@ static int rvin_reset_format(struct rvin_dev *vin) struct v4l2_mbus_framefmt *mf = &fmt.format; int ret; - fmt.pad = vin->digital.source_pad; + fmt.pad = vin->digital->source_pad; ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt); if (ret) @@ -172,13 +172,13 @@ static int __rvin_try_format_source(struct rvin_dev *vin, sd = vin_to_source(vin); - v4l2_fill_mbus_format(&format.format, pix, vin->digital.code); + v4l2_fill_mbus_format(&format.format, pix, vin->digital->code); pad_cfg = v4l2_subdev_alloc_pad_config(sd); if (pad_cfg == NULL) return -ENOMEM; - format.pad = vin->digital.source_pad; + format.pad = vin->digital->source_pad; field = pix->field; @@ -555,7 +555,7 @@ static int rvin_enum_dv_timings(struct file *file, void *priv_fh, if (timings->pad) return -EINVAL; - timings->pad = vin->digital.sink_pad; + timings->pad = vin->digital->sink_pad; ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings); @@ -607,7 +607,7 @@ static int rvin_dv_timings_cap(struct file *file, void *priv_fh, if (cap->pad) return -EINVAL; - cap->pad = vin->digital.sink_pad; + cap->pad = vin->digital->sink_pad; ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap); @@ -625,7 +625,7 @@ static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid) if (edid->pad) return -EINVAL; - edid->pad = vin->digital.sink_pad; + edid->pad = vin->digital->sink_pad; ret = v4l2_subdev_call(sd, pad, get_edid, edid); @@ -643,7 +643,7 @@ static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid) if (edid->pad) return -EINVAL; - edid->pad = vin->digital.sink_pad; + edid->pad = vin->digital->sink_pad; ret = v4l2_subdev_call(sd, pad, set_edid, edid); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 9bfb5a7c4dc4..5382078143fb 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -126,7 +126,7 @@ struct rvin_dev { struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; struct v4l2_async_notifier notifier; - struct rvin_graph_entity digital; + struct rvin_graph_entity *digital; struct mutex lock; struct vb2_queue queue; @@ -145,7 +145,7 @@ struct rvin_dev { struct v4l2_rect compose; }; -#define vin_to_source(vin) vin->digital.subdev +#define vin_to_source(vin) ((vin)->digital->subdev) /* Debug */ #define vin_dbg(d, fmt, arg...) dev_dbg(d->dev, fmt, ##arg) diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c index 522364ff0d5d..63c94f4028a7 100644 --- a/drivers/media/platform/rcar_drif.c +++ b/drivers/media/platform/rcar_drif.c @@ -630,7 +630,7 @@ static int rcar_drif_enable_rx(struct rcar_drif_sdr *sdr) { unsigned int i; u32 ctr; - int ret; + int ret = -EINVAL; /* * When both internal channels are enabled, they can be synchronized @@ -1185,6 +1185,12 @@ error: return ret; } +static const struct v4l2_async_notifier_operations rcar_drif_notify_ops = { + .bound = rcar_drif_notify_bound, + .unbind = rcar_drif_notify_unbind, + .complete = rcar_drif_notify_complete, +}; + /* Read endpoint properties */ static void rcar_drif_get_ep_properties(struct rcar_drif_sdr *sdr, struct fwnode_handle *fwnode) @@ -1347,9 +1353,7 @@ static int rcar_drif_sdr_probe(struct rcar_drif_sdr *sdr) if (ret) goto error; - sdr->notifier.bound = rcar_drif_notify_bound; - sdr->notifier.unbind = rcar_drif_notify_unbind; - sdr->notifier.complete = rcar_drif_notify_complete; + sdr->notifier.ops = &rcar_drif_notify_ops; /* Register notifier */ ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier); diff --git a/drivers/media/platform/rockchip/rga/Makefile b/drivers/media/platform/rockchip/rga/Makefile new file mode 100644 index 000000000000..92fe25490ccd --- /dev/null +++ b/drivers/media/platform/rockchip/rga/Makefile @@ -0,0 +1,3 @@ +rockchip-rga-objs := rga.o rga-hw.o rga-buf.o + +obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip-rga.o diff --git a/drivers/media/platform/rockchip/rga/rga-buf.c b/drivers/media/platform/rockchip/rga/rga-buf.c new file mode 100644 index 000000000000..49cacc7a48d1 --- /dev/null +++ b/drivers/media/platform/rockchip/rga/rga-buf.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd + * Author: Jacob Chen <jacob-chen@iotwrt.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/pm_runtime.h> + +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-dma-sg.h> +#include <media/videobuf2-v4l2.h> + +#include "rga-hw.h" +#include "rga.h" + +static int +rga_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct rga_ctx *ctx = vb2_get_drv_priv(vq); + struct rga_frame *f = rga_get_frame(ctx, vq->type); + + if (IS_ERR(f)) + return PTR_ERR(f); + + if (*nplanes) + return sizes[0] < f->size ? -EINVAL : 0; + + sizes[0] = f->size; + *nplanes = 1; + + return 0; +} + +static int rga_buf_prepare(struct vb2_buffer *vb) +{ + struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct rga_frame *f = rga_get_frame(ctx, vb->vb2_queue->type); + + if (IS_ERR(f)) + return PTR_ERR(f); + + vb2_set_plane_payload(vb, 0, f->size); + + return 0; +} + +static void rga_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); +} + +static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct rga_ctx *ctx = vb2_get_drv_priv(q); + struct rockchip_rga *rga = ctx->rga; + int ret, i; + + ret = pm_runtime_get_sync(rga->dev); + + if (!ret) + return 0; + + for (i = 0; i < q->num_buffers; ++i) { + if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) { + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q->bufs[i]), + VB2_BUF_STATE_QUEUED); + } + } + + return ret; +} + +static void rga_buf_stop_streaming(struct vb2_queue *q) +{ + struct rga_ctx *ctx = vb2_get_drv_priv(q); + struct rockchip_rga *rga = ctx->rga; + struct vb2_v4l2_buffer *vbuf; + + for (;;) { + if (V4L2_TYPE_IS_OUTPUT(q->type)) + vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + if (!vbuf) + break; + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + } + + pm_runtime_put(rga->dev); +} + +const struct vb2_ops rga_qops = { + .queue_setup = rga_queue_setup, + .buf_prepare = rga_buf_prepare, + .buf_queue = rga_buf_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .start_streaming = rga_buf_start_streaming, + .stop_streaming = rga_buf_stop_streaming, +}; + +/* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API. + * We use it more like a scatter-gather list. + */ +void rga_buf_map(struct vb2_buffer *vb) +{ + struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct rockchip_rga *rga = ctx->rga; + struct sg_table *sgt; + struct scatterlist *sgl; + unsigned int *pages; + unsigned int address, len, i, p; + unsigned int mapped_size = 0; + + if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + pages = rga->src_mmu_pages; + else + pages = rga->dst_mmu_pages; + + /* Create local MMU table for RGA */ + sgt = vb2_plane_cookie(vb, 0); + + for_each_sg(sgt->sgl, sgl, sgt->nents, i) { + len = sg_dma_len(sgl) >> PAGE_SHIFT; + address = sg_phys(sgl); + + for (p = 0; p < len; p++) { + dma_addr_t phys = address + (p << PAGE_SHIFT); + + pages[mapped_size + p] = phys; + } + + mapped_size += len; + } + + /* sync local MMU table for RGA */ + dma_sync_single_for_device(rga->dev, virt_to_phys(pages), + 8 * PAGE_SIZE, DMA_BIDIRECTIONAL); +} diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c b/drivers/media/platform/rockchip/rga/rga-hw.c new file mode 100644 index 000000000000..96d1b1b3fe8e --- /dev/null +++ b/drivers/media/platform/rockchip/rga/rga-hw.c @@ -0,0 +1,421 @@ +/* + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Author: Jacob Chen <jacob-chen@iotwrt.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/pm_runtime.h> + +#include "rga-hw.h" +#include "rga.h" + +enum e_rga_start_pos { + LT = 0, + LB = 1, + RT = 2, + RB = 3, +}; + +struct rga_addr_offset { + unsigned int y_off; + unsigned int u_off; + unsigned int v_off; +}; + +struct rga_corners_addr_offset { + struct rga_addr_offset left_top; + struct rga_addr_offset right_top; + struct rga_addr_offset left_bottom; + struct rga_addr_offset right_bottom; +}; + +static unsigned int rga_get_scaling(unsigned int src, unsigned int dst) +{ + /* + * The rga hw scaling factor is a normalized inverse of the + * scaling factor. + * For example: When source width is 100 and destination width is 200 + * (scaling of 2x), then the hw factor is NC * 100 / 200. + * The normalization factor (NC) is 2^16 = 0x10000. + */ + + return (src > dst) ? ((dst << 16) / src) : ((src << 16) / dst); +} + +static struct rga_corners_addr_offset +rga_get_addr_offset(struct rga_frame *frm, unsigned int x, unsigned int y, + unsigned int w, unsigned int h) +{ + struct rga_corners_addr_offset offsets; + struct rga_addr_offset *lt, *lb, *rt, *rb; + unsigned int x_div = 0, + y_div = 0, uv_stride = 0, pixel_width = 0, uv_factor = 0; + + lt = &offsets.left_top; + lb = &offsets.left_bottom; + rt = &offsets.right_top; + rb = &offsets.right_bottom; + + x_div = frm->fmt->x_div; + y_div = frm->fmt->y_div; + uv_factor = frm->fmt->uv_factor; + uv_stride = frm->stride / x_div; + pixel_width = frm->stride / frm->width; + + lt->y_off = y * frm->stride + x * pixel_width; + lt->u_off = + frm->width * frm->height + (y / y_div) * uv_stride + x / x_div; + lt->v_off = lt->u_off + frm->width * frm->height / uv_factor; + + lb->y_off = lt->y_off + (h - 1) * frm->stride; + lb->u_off = lt->u_off + (h / y_div - 1) * uv_stride; + lb->v_off = lt->v_off + (h / y_div - 1) * uv_stride; + + rt->y_off = lt->y_off + (w - 1) * pixel_width; + rt->u_off = lt->u_off + w / x_div - 1; + rt->v_off = lt->v_off + w / x_div - 1; + + rb->y_off = lb->y_off + (w - 1) * pixel_width; + rb->u_off = lb->u_off + w / x_div - 1; + rb->v_off = lb->v_off + w / x_div - 1; + + return offsets; +} + +static struct rga_addr_offset *rga_lookup_draw_pos(struct + rga_corners_addr_offset + * offsets, u32 rotate_mode, + u32 mirr_mode) +{ + static enum e_rga_start_pos rot_mir_point_matrix[4][4] = { + { + LT, RT, LB, RB, + }, + { + RT, LT, RB, LB, + }, + { + RB, LB, RT, LT, + }, + { + LB, RB, LT, RT, + }, + }; + + if (!offsets) + return NULL; + + switch (rot_mir_point_matrix[rotate_mode][mirr_mode]) { + case LT: + return &offsets->left_top; + case LB: + return &offsets->left_bottom; + case RT: + return &offsets->right_top; + case RB: + return &offsets->right_bottom; + } + + return NULL; +} + +static void rga_cmd_set_src_addr(struct rga_ctx *ctx, void *mmu_pages) +{ + struct rockchip_rga *rga = ctx->rga; + u32 *dest = rga->cmdbuf_virt; + unsigned int reg; + + reg = RGA_MMU_SRC_BASE - RGA_MODE_BASE_REG; + dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4; + + reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; + dest[reg >> 2] |= 0x7; +} + +static void rga_cmd_set_src1_addr(struct rga_ctx *ctx, void *mmu_pages) +{ + struct rockchip_rga *rga = ctx->rga; + u32 *dest = rga->cmdbuf_virt; + unsigned int reg; + + reg = RGA_MMU_SRC1_BASE - RGA_MODE_BASE_REG; + dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4; + + reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; + dest[reg >> 2] |= 0x7 << 4; +} + +static void rga_cmd_set_dst_addr(struct rga_ctx *ctx, void *mmu_pages) +{ + struct rockchip_rga *rga = ctx->rga; + u32 *dest = rga->cmdbuf_virt; + unsigned int reg; + + reg = RGA_MMU_DST_BASE - RGA_MODE_BASE_REG; + dest[reg >> 2] = virt_to_phys(mmu_pages) >> 4; + + reg = RGA_MMU_CTRL1 - RGA_MODE_BASE_REG; + dest[reg >> 2] |= 0x7 << 8; +} + +static void rga_cmd_set_trans_info(struct rga_ctx *ctx) +{ + struct rockchip_rga *rga = ctx->rga; + u32 *dest = rga->cmdbuf_virt; + unsigned int scale_dst_w, scale_dst_h; + unsigned int src_h, src_w, src_x, src_y, dst_h, dst_w, dst_x, dst_y; + union rga_src_info src_info; + union rga_dst_info dst_info; + union rga_src_x_factor x_factor; + union rga_src_y_factor y_factor; + union rga_src_vir_info src_vir_info; + union rga_src_act_info src_act_info; + union rga_dst_vir_info dst_vir_info; + union rga_dst_act_info dst_act_info; + + struct rga_addr_offset *dst_offset; + struct rga_corners_addr_offset offsets; + struct rga_corners_addr_offset src_offsets; + + src_h = ctx->in.crop.height; + src_w = ctx->in.crop.width; + src_x = ctx->in.crop.left; + src_y = ctx->in.crop.top; + dst_h = ctx->out.crop.height; + dst_w = ctx->out.crop.width; + dst_x = ctx->out.crop.left; + dst_y = ctx->out.crop.top; + + src_info.val = dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2]; + dst_info.val = dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2]; + x_factor.val = dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2]; + y_factor.val = dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2]; + src_vir_info.val = dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2]; + src_act_info.val = dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2]; + dst_vir_info.val = dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2]; + dst_act_info.val = dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2]; + + src_info.data.format = ctx->in.fmt->hw_format; + src_info.data.swap = ctx->in.fmt->color_swap; + dst_info.data.format = ctx->out.fmt->hw_format; + dst_info.data.swap = ctx->out.fmt->color_swap; + + if (ctx->in.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { + if (ctx->out.fmt->hw_format < RGA_COLOR_FMT_YUV422SP) { + switch (ctx->in.colorspace) { + case V4L2_COLORSPACE_REC709: + src_info.data.csc_mode = + RGA_SRC_CSC_MODE_BT709_R0; + break; + default: + src_info.data.csc_mode = + RGA_SRC_CSC_MODE_BT601_R0; + break; + } + } + } + + if (ctx->out.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { + switch (ctx->out.colorspace) { + case V4L2_COLORSPACE_REC709: + dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; + break; + default: + dst_info.data.csc_mode = RGA_DST_CSC_MODE_BT601_R0; + break; + } + } + + if (ctx->vflip) + src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_X; + + if (ctx->hflip) + src_info.data.mir_mode |= RGA_SRC_MIRR_MODE_Y; + + switch (ctx->rotate) { + case 90: + src_info.data.rot_mode = RGA_SRC_ROT_MODE_90_DEGREE; + break; + case 180: + src_info.data.rot_mode = RGA_SRC_ROT_MODE_180_DEGREE; + break; + case 270: + src_info.data.rot_mode = RGA_SRC_ROT_MODE_270_DEGREE; + break; + default: + src_info.data.rot_mode = RGA_SRC_ROT_MODE_0_DEGREE; + break; + } + + /* + * Cacluate the up/down scaling mode/factor. + * + * RGA used to scale the picture first, and then rotate second, + * so we need to swap the w/h when rotate degree is 90/270. + */ + if (src_info.data.rot_mode == RGA_SRC_ROT_MODE_90_DEGREE || + src_info.data.rot_mode == RGA_SRC_ROT_MODE_270_DEGREE) { + if (rga->version.major == 0 || rga->version.minor == 0) { + if (dst_w == src_h) + src_h -= 8; + if (abs(src_w - dst_h) < 16) + src_w -= 16; + } + + scale_dst_h = dst_w; + scale_dst_w = dst_h; + } else { + scale_dst_w = dst_w; + scale_dst_h = dst_h; + } + + if (src_w == scale_dst_w) { + src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_NO; + x_factor.val = 0; + } else if (src_w > scale_dst_w) { + src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_DOWN; + x_factor.data.down_scale_factor = + rga_get_scaling(src_w, scale_dst_w) + 1; + } else { + src_info.data.hscl_mode = RGA_SRC_HSCL_MODE_UP; + x_factor.data.up_scale_factor = + rga_get_scaling(src_w - 1, scale_dst_w - 1); + } + + if (src_h == scale_dst_h) { + src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_NO; + y_factor.val = 0; + } else if (src_h > scale_dst_h) { + src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_DOWN; + y_factor.data.down_scale_factor = + rga_get_scaling(src_h, scale_dst_h) + 1; + } else { + src_info.data.vscl_mode = RGA_SRC_VSCL_MODE_UP; + y_factor.data.up_scale_factor = + rga_get_scaling(src_h - 1, scale_dst_h - 1); + } + + /* + * Cacluate the framebuffer virtual strides and active size, + * note that the step of vir_stride / vir_width is 4 byte words + */ + src_vir_info.data.vir_stride = ctx->in.stride >> 2; + src_vir_info.data.vir_width = ctx->in.stride >> 2; + + src_act_info.data.act_height = src_h - 1; + src_act_info.data.act_width = src_w - 1; + + dst_vir_info.data.vir_stride = ctx->out.stride >> 2; + dst_act_info.data.act_height = dst_h - 1; + dst_act_info.data.act_width = dst_w - 1; + + /* + * Cacluate the source framebuffer base address with offset pixel. + */ + src_offsets = rga_get_addr_offset(&ctx->in, src_x, src_y, + src_w, src_h); + + /* + * Configure the dest framebuffer base address with pixel offset. + */ + offsets = rga_get_addr_offset(&ctx->out, dst_x, dst_y, dst_w, dst_h); + dst_offset = rga_lookup_draw_pos(&offsets, src_info.data.rot_mode, + src_info.data.mir_mode); + + dest[(RGA_SRC_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + src_offsets.left_top.y_off; + dest[(RGA_SRC_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + src_offsets.left_top.u_off; + dest[(RGA_SRC_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + src_offsets.left_top.v_off; + + dest[(RGA_SRC_X_FACTOR - RGA_MODE_BASE_REG) >> 2] = x_factor.val; + dest[(RGA_SRC_Y_FACTOR - RGA_MODE_BASE_REG) >> 2] = y_factor.val; + dest[(RGA_SRC_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = src_vir_info.val; + dest[(RGA_SRC_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = src_act_info.val; + + dest[(RGA_SRC_INFO - RGA_MODE_BASE_REG) >> 2] = src_info.val; + + dest[(RGA_DST_Y_RGB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + dst_offset->y_off; + dest[(RGA_DST_CB_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + dst_offset->u_off; + dest[(RGA_DST_CR_BASE_ADDR - RGA_MODE_BASE_REG) >> 2] = + dst_offset->v_off; + + dest[(RGA_DST_VIR_INFO - RGA_MODE_BASE_REG) >> 2] = dst_vir_info.val; + dest[(RGA_DST_ACT_INFO - RGA_MODE_BASE_REG) >> 2] = dst_act_info.val; + + dest[(RGA_DST_INFO - RGA_MODE_BASE_REG) >> 2] = dst_info.val; +} + +static void rga_cmd_set_mode(struct rga_ctx *ctx) +{ + struct rockchip_rga *rga = ctx->rga; + u32 *dest = rga->cmdbuf_virt; + union rga_mode_ctrl mode; + union rga_alpha_ctrl0 alpha_ctrl0; + union rga_alpha_ctrl1 alpha_ctrl1; + + mode.val = 0; + alpha_ctrl0.val = 0; + alpha_ctrl1.val = 0; + + mode.data.gradient_sat = 1; + mode.data.render = RGA_MODE_RENDER_BITBLT; + mode.data.bitblt = RGA_MODE_BITBLT_MODE_SRC_TO_DST; + + /* disable alpha blending */ + dest[(RGA_ALPHA_CTRL0 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl0.val; + dest[(RGA_ALPHA_CTRL1 - RGA_MODE_BASE_REG) >> 2] = alpha_ctrl1.val; + + dest[(RGA_MODE_CTRL - RGA_MODE_BASE_REG) >> 2] = mode.val; +} + +static void rga_cmd_set(struct rga_ctx *ctx) +{ + struct rockchip_rga *rga = ctx->rga; + + memset(rga->cmdbuf_virt, 0, RGA_CMDBUF_SIZE * 4); + + rga_cmd_set_src_addr(ctx, rga->src_mmu_pages); + /* + * Due to hardware bug, + * src1 mmu also should be configured when using alpha blending. + */ + rga_cmd_set_src1_addr(ctx, rga->dst_mmu_pages); + + rga_cmd_set_dst_addr(ctx, rga->dst_mmu_pages); + rga_cmd_set_mode(ctx); + + rga_cmd_set_trans_info(ctx); + + rga_write(rga, RGA_CMD_BASE, rga->cmdbuf_phy); + + /* sync CMD buf for RGA */ + dma_sync_single_for_device(rga->dev, rga->cmdbuf_phy, + PAGE_SIZE, DMA_BIDIRECTIONAL); +} + +void rga_hw_start(struct rockchip_rga *rga) +{ + struct rga_ctx *ctx = rga->curr; + + rga_cmd_set(ctx); + + rga_write(rga, RGA_SYS_CTRL, 0x00); + + rga_write(rga, RGA_SYS_CTRL, 0x22); + + rga_write(rga, RGA_INT, 0x600); + + rga_write(rga, RGA_CMD_CTRL, 0x1); +} diff --git a/drivers/media/platform/rockchip/rga/rga-hw.h b/drivers/media/platform/rockchip/rga/rga-hw.h new file mode 100644 index 000000000000..ca3c204abe42 --- /dev/null +++ b/drivers/media/platform/rockchip/rga/rga-hw.h @@ -0,0 +1,437 @@ +/* + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Author: Jacob Chen <jacob-chen@iotwrt.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __RGA_HW_H__ +#define __RGA_HW_H__ + +#define RGA_CMDBUF_SIZE 0x20 + +/* Hardware limits */ +#define MAX_WIDTH 8192 +#define MAX_HEIGHT 8192 + +#define MIN_WIDTH 34 +#define MIN_HEIGHT 34 + +#define DEFAULT_WIDTH 100 +#define DEFAULT_HEIGHT 100 + +#define RGA_TIMEOUT 500 + +/* Registers address */ +#define RGA_SYS_CTRL 0x0000 +#define RGA_CMD_CTRL 0x0004 +#define RGA_CMD_BASE 0x0008 +#define RGA_INT 0x0010 +#define RGA_MMU_CTRL0 0x0014 +#define RGA_VERSION_INFO 0x0028 + +#define RGA_MODE_BASE_REG 0x0100 +#define RGA_MODE_MAX_REG 0x017C + +#define RGA_MODE_CTRL 0x0100 +#define RGA_SRC_INFO 0x0104 +#define RGA_SRC_Y_RGB_BASE_ADDR 0x0108 +#define RGA_SRC_CB_BASE_ADDR 0x010c +#define RGA_SRC_CR_BASE_ADDR 0x0110 +#define RGA_SRC1_RGB_BASE_ADDR 0x0114 +#define RGA_SRC_VIR_INFO 0x0118 +#define RGA_SRC_ACT_INFO 0x011c +#define RGA_SRC_X_FACTOR 0x0120 +#define RGA_SRC_Y_FACTOR 0x0124 +#define RGA_SRC_BG_COLOR 0x0128 +#define RGA_SRC_FG_COLOR 0x012c +#define RGA_SRC_TR_COLOR0 0x0130 +#define RGA_SRC_TR_COLOR1 0x0134 + +#define RGA_DST_INFO 0x0138 +#define RGA_DST_Y_RGB_BASE_ADDR 0x013c +#define RGA_DST_CB_BASE_ADDR 0x0140 +#define RGA_DST_CR_BASE_ADDR 0x0144 +#define RGA_DST_VIR_INFO 0x0148 +#define RGA_DST_ACT_INFO 0x014c + +#define RGA_ALPHA_CTRL0 0x0150 +#define RGA_ALPHA_CTRL1 0x0154 +#define RGA_FADING_CTRL 0x0158 +#define RGA_PAT_CON 0x015c +#define RGA_ROP_CON0 0x0160 +#define RGA_ROP_CON1 0x0164 +#define RGA_MASK_BASE 0x0168 + +#define RGA_MMU_CTRL1 0x016C +#define RGA_MMU_SRC_BASE 0x0170 +#define RGA_MMU_SRC1_BASE 0x0174 +#define RGA_MMU_DST_BASE 0x0178 + +/* Registers value */ +#define RGA_MODE_RENDER_BITBLT 0 +#define RGA_MODE_RENDER_COLOR_PALETTE 1 +#define RGA_MODE_RENDER_RECTANGLE_FILL 2 +#define RGA_MODE_RENDER_UPDATE_PALETTE_LUT_RAM 3 + +#define RGA_MODE_BITBLT_MODE_SRC_TO_DST 0 +#define RGA_MODE_BITBLT_MODE_SRC_SRC1_TO_DST 1 + +#define RGA_MODE_CF_ROP4_SOLID 0 +#define RGA_MODE_CF_ROP4_PATTERN 1 + +#define RGA_COLOR_FMT_ABGR8888 0 +#define RGA_COLOR_FMT_XBGR8888 1 +#define RGA_COLOR_FMT_RGB888 2 +#define RGA_COLOR_FMT_BGR565 4 +#define RGA_COLOR_FMT_ABGR1555 5 +#define RGA_COLOR_FMT_ABGR4444 6 +#define RGA_COLOR_FMT_YUV422SP 8 +#define RGA_COLOR_FMT_YUV422P 9 +#define RGA_COLOR_FMT_YUV420SP 10 +#define RGA_COLOR_FMT_YUV420P 11 +/* SRC_COLOR Palette */ +#define RGA_COLOR_FMT_CP_1BPP 12 +#define RGA_COLOR_FMT_CP_2BPP 13 +#define RGA_COLOR_FMT_CP_4BPP 14 +#define RGA_COLOR_FMT_CP_8BPP 15 +#define RGA_COLOR_FMT_MASK 15 + +#define RGA_COLOR_NONE_SWAP 0 +#define RGA_COLOR_RB_SWAP 1 +#define RGA_COLOR_ALPHA_SWAP 2 +#define RGA_COLOR_UV_SWAP 4 + +#define RGA_SRC_CSC_MODE_BYPASS 0 +#define RGA_SRC_CSC_MODE_BT601_R0 1 +#define RGA_SRC_CSC_MODE_BT601_R1 2 +#define RGA_SRC_CSC_MODE_BT709_R0 3 +#define RGA_SRC_CSC_MODE_BT709_R1 4 + +#define RGA_SRC_ROT_MODE_0_DEGREE 0 +#define RGA_SRC_ROT_MODE_90_DEGREE 1 +#define RGA_SRC_ROT_MODE_180_DEGREE 2 +#define RGA_SRC_ROT_MODE_270_DEGREE 3 + +#define RGA_SRC_MIRR_MODE_NO 0 +#define RGA_SRC_MIRR_MODE_X 1 +#define RGA_SRC_MIRR_MODE_Y 2 +#define RGA_SRC_MIRR_MODE_X_Y 3 + +#define RGA_SRC_HSCL_MODE_NO 0 +#define RGA_SRC_HSCL_MODE_DOWN 1 +#define RGA_SRC_HSCL_MODE_UP 2 + +#define RGA_SRC_VSCL_MODE_NO 0 +#define RGA_SRC_VSCL_MODE_DOWN 1 +#define RGA_SRC_VSCL_MODE_UP 2 + +#define RGA_SRC_TRANS_ENABLE_R 1 +#define RGA_SRC_TRANS_ENABLE_G 2 +#define RGA_SRC_TRANS_ENABLE_B 4 +#define RGA_SRC_TRANS_ENABLE_A 8 + +#define RGA_SRC_BIC_COE_SELEC_CATROM 0 +#define RGA_SRC_BIC_COE_SELEC_MITCHELL 1 +#define RGA_SRC_BIC_COE_SELEC_HERMITE 2 +#define RGA_SRC_BIC_COE_SELEC_BSPLINE 3 + +#define RGA_DST_DITHER_MODE_888_TO_666 0 +#define RGA_DST_DITHER_MODE_888_TO_565 1 +#define RGA_DST_DITHER_MODE_888_TO_555 2 +#define RGA_DST_DITHER_MODE_888_TO_444 3 + +#define RGA_DST_CSC_MODE_BYPASS 0 +#define RGA_DST_CSC_MODE_BT601_R0 1 +#define RGA_DST_CSC_MODE_BT601_R1 2 +#define RGA_DST_CSC_MODE_BT709_R0 3 + +#define RGA_ALPHA_ROP_MODE_2 0 +#define RGA_ALPHA_ROP_MODE_3 1 +#define RGA_ALPHA_ROP_MODE_4 2 + +#define RGA_ALPHA_SELECT_ALPHA 0 +#define RGA_ALPHA_SELECT_ROP 1 + +#define RGA_ALPHA_MASK_BIG_ENDIAN 0 +#define RGA_ALPHA_MASK_LITTLE_ENDIAN 1 + +#define RGA_ALPHA_NORMAL 0 +#define RGA_ALPHA_REVERSE 1 + +#define RGA_ALPHA_BLEND_GLOBAL 0 +#define RGA_ALPHA_BLEND_NORMAL 1 +#define RGA_ALPHA_BLEND_MULTIPLY 2 + +#define RGA_ALPHA_CAL_CUT 0 +#define RGA_ALPHA_CAL_NORMAL 1 + +#define RGA_ALPHA_FACTOR_ZERO 0 +#define RGA_ALPHA_FACTOR_ONE 1 +#define RGA_ALPHA_FACTOR_OTHER 2 +#define RGA_ALPHA_FACTOR_OTHER_REVERSE 3 +#define RGA_ALPHA_FACTOR_SELF 4 + +#define RGA_ALPHA_COLOR_NORMAL 0 +#define RGA_ALPHA_COLOR_MULTIPLY_CAL 1 + +/* Registers union */ +union rga_mode_ctrl { + unsigned int val; + struct { + /* [0:2] */ + unsigned int render:3; + /* [3:6] */ + unsigned int bitblt:1; + unsigned int cf_rop4_pat:1; + unsigned int alpha_zero_key:1; + unsigned int gradient_sat:1; + /* [7:31] */ + unsigned int reserved:25; + } data; +}; + +union rga_src_info { + unsigned int val; + struct { + /* [0:3] */ + unsigned int format:4; + /* [4:7] */ + unsigned int swap:3; + unsigned int cp_endian:1; + /* [8:17] */ + unsigned int csc_mode:2; + unsigned int rot_mode:2; + unsigned int mir_mode:2; + unsigned int hscl_mode:2; + unsigned int vscl_mode:2; + /* [18:22] */ + unsigned int trans_mode:1; + unsigned int trans_enable:4; + /* [23:25] */ + unsigned int dither_up_en:1; + unsigned int bic_coe_sel:2; + /* [26:31] */ + unsigned int reserved:6; + } data; +}; + +union rga_src_vir_info { + unsigned int val; + struct { + /* [0:15] */ + unsigned int vir_width:15; + unsigned int reserved:1; + /* [16:25] */ + unsigned int vir_stride:10; + /* [26:31] */ + unsigned int reserved1:6; + } data; +}; + +union rga_src_act_info { + unsigned int val; + struct { + /* [0:15] */ + unsigned int act_width:13; + unsigned int reserved:3; + /* [16:31] */ + unsigned int act_height:13; + unsigned int reserved1:3; + } data; +}; + +union rga_src_x_factor { + unsigned int val; + struct { + /* [0:15] */ + unsigned int down_scale_factor:16; + /* [16:31] */ + unsigned int up_scale_factor:16; + } data; +}; + +union rga_src_y_factor { + unsigned int val; + struct { + /* [0:15] */ + unsigned int down_scale_factor:16; + /* [16:31] */ + unsigned int up_scale_factor:16; + } data; +}; + +/* Alpha / Red / Green / Blue */ +union rga_src_cp_gr_color { + unsigned int val; + struct { + /* [0:15] */ + unsigned int gradient_x:16; + /* [16:31] */ + unsigned int gradient_y:16; + } data; +}; + +union rga_src_transparency_color0 { + unsigned int val; + struct { + /* [0:7] */ + unsigned int trans_rmin:8; + /* [8:15] */ + unsigned int trans_gmin:8; + /* [16:23] */ + unsigned int trans_bmin:8; + /* [24:31] */ + unsigned int trans_amin:8; + } data; +}; + +union rga_src_transparency_color1 { + unsigned int val; + struct { + /* [0:7] */ + unsigned int trans_rmax:8; + /* [8:15] */ + unsigned int trans_gmax:8; + /* [16:23] */ + unsigned int trans_bmax:8; + /* [24:31] */ + unsigned int trans_amax:8; + } data; +}; + +union rga_dst_info { + unsigned int val; + struct { + /* [0:3] */ + unsigned int format:4; + /* [4:6] */ + unsigned int swap:3; + /* [7:9] */ + unsigned int src1_format:3; + /* [10:11] */ + unsigned int src1_swap:2; + /* [12:15] */ + unsigned int dither_up_en:1; + unsigned int dither_down_en:1; + unsigned int dither_down_mode:2; + /* [16:18] */ + unsigned int csc_mode:2; + unsigned int csc_clip:1; + /* [19:31] */ + unsigned int reserved:13; + } data; +}; + +union rga_dst_vir_info { + unsigned int val; + struct { + /* [0:15] */ + unsigned int vir_stride:15; + unsigned int reserved:1; + /* [16:31] */ + unsigned int src1_vir_stride:15; + unsigned int reserved1:1; + } data; +}; + +union rga_dst_act_info { + unsigned int val; + struct { + /* [0:15] */ + unsigned int act_width:12; + unsigned int reserved:4; + /* [16:31] */ + unsigned int act_height:12; + unsigned int reserved1:4; + } data; +}; + +union rga_alpha_ctrl0 { + unsigned int val; + struct { + /* [0:3] */ + unsigned int rop_en:1; + unsigned int rop_select:1; + unsigned int rop_mode:2; + /* [4:11] */ + unsigned int src_fading_val:8; + /* [12:20] */ + unsigned int dst_fading_val:8; + unsigned int mask_endian:1; + /* [21:31] */ + unsigned int reserved:11; + } data; +}; + +union rga_alpha_ctrl1 { + unsigned int val; + struct { + /* [0:1] */ + unsigned int dst_color_m0:1; + unsigned int src_color_m0:1; + /* [2:7] */ + unsigned int dst_factor_m0:3; + unsigned int src_factor_m0:3; + /* [8:9] */ + unsigned int dst_alpha_cal_m0:1; + unsigned int src_alpha_cal_m0:1; + /* [10:13] */ + unsigned int dst_blend_m0:2; + unsigned int src_blend_m0:2; + /* [14:15] */ + unsigned int dst_alpha_m0:1; + unsigned int src_alpha_m0:1; + /* [16:21] */ + unsigned int dst_factor_m1:3; + unsigned int src_factor_m1:3; + /* [22:23] */ + unsigned int dst_alpha_cal_m1:1; + unsigned int src_alpha_cal_m1:1; + /* [24:27] */ + unsigned int dst_blend_m1:2; + unsigned int src_blend_m1:2; + /* [28:29] */ + unsigned int dst_alpha_m1:1; + unsigned int src_alpha_m1:1; + /* [30:31] */ + unsigned int reserved:2; + } data; +}; + +union rga_fading_ctrl { + unsigned int val; + struct { + /* [0:7] */ + unsigned int fading_offset_r:8; + /* [8:15] */ + unsigned int fading_offset_g:8; + /* [16:23] */ + unsigned int fading_offset_b:8; + /* [24:31] */ + unsigned int fading_en:1; + unsigned int reserved:7; + } data; +}; + +union rga_pat_con { + unsigned int val; + struct { + /* [0:7] */ + unsigned int width:8; + /* [8:15] */ + unsigned int height:8; + /* [16:23] */ + unsigned int offset_x:8; + /* [24:31] */ + unsigned int offset_y:8; + } data; +}; + +#endif diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c new file mode 100644 index 000000000000..89296de9cf4a --- /dev/null +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -0,0 +1,1010 @@ +/* + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Author: Jacob Chen <jacob-chen@iotwrt.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/debugfs.h> +#include <linux/delay.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/timer.h> + +#include <linux/platform_device.h> +#include <media/v4l2-device.h> +#include <media/v4l2-event.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-dma-sg.h> +#include <media/videobuf2-v4l2.h> + +#include "rga-hw.h" +#include "rga.h" + +static int debug; +module_param(debug, int, 0644); + +static void job_abort(void *prv) +{ + struct rga_ctx *ctx = prv; + struct rockchip_rga *rga = ctx->rga; + + if (!rga->curr) /* No job currently running */ + return; + + wait_event_timeout(rga->irq_queue, + !rga->curr, msecs_to_jiffies(RGA_TIMEOUT)); +} + +static void device_run(void *prv) +{ + struct rga_ctx *ctx = prv; + struct rockchip_rga *rga = ctx->rga; + struct vb2_buffer *src, *dst; + unsigned long flags; + + spin_lock_irqsave(&rga->ctrl_lock, flags); + + rga->curr = ctx; + + src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + rga_buf_map(src); + rga_buf_map(dst); + + rga_hw_start(rga); + + spin_unlock_irqrestore(&rga->ctrl_lock, flags); +} + +static irqreturn_t rga_isr(int irq, void *prv) +{ + struct rockchip_rga *rga = prv; + int intr; + + intr = rga_read(rga, RGA_INT) & 0xf; + + rga_mod(rga, RGA_INT, intr << 4, 0xf << 4); + + if (intr & 0x04) { + struct vb2_v4l2_buffer *src, *dst; + struct rga_ctx *ctx = rga->curr; + + WARN_ON(!ctx); + + rga->curr = NULL; + + src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + WARN_ON(!src); + WARN_ON(!dst); + + dst->timecode = src->timecode; + dst->vb2_buf.timestamp = src->vb2_buf.timestamp; + dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + dst->flags |= src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + + v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); + v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); + v4l2_m2m_job_finish(rga->m2m_dev, ctx->fh.m2m_ctx); + + wake_up(&rga->irq_queue); + } + + return IRQ_HANDLED; +} + +static struct v4l2_m2m_ops rga_m2m_ops = { + .device_run = device_run, + .job_abort = job_abort, +}; + +static int +queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) +{ + struct rga_ctx *ctx = priv; + int ret; + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->ops = &rga_qops; + src_vq->mem_ops = &vb2_dma_sg_memops; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->rga->mutex; + src_vq->dev = ctx->rga->v4l2_dev.dev; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->ops = &rga_qops; + dst_vq->mem_ops = &vb2_dma_sg_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->rga->mutex; + dst_vq->dev = ctx->rga->v4l2_dev.dev; + + return vb2_queue_init(dst_vq); +} + +static int rga_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct rga_ctx *ctx = container_of(ctrl->handler, struct rga_ctx, + ctrl_handler); + unsigned long flags; + + spin_lock_irqsave(&ctx->rga->ctrl_lock, flags); + switch (ctrl->id) { + case V4L2_CID_HFLIP: + ctx->hflip = ctrl->val; + break; + case V4L2_CID_VFLIP: + ctx->vflip = ctrl->val; + break; + case V4L2_CID_ROTATE: + ctx->rotate = ctrl->val; + break; + case V4L2_CID_BG_COLOR: + ctx->fill_color = ctrl->val; + break; + } + spin_unlock_irqrestore(&ctx->rga->ctrl_lock, flags); + return 0; +} + +static const struct v4l2_ctrl_ops rga_ctrl_ops = { + .s_ctrl = rga_s_ctrl, +}; + +static int rga_setup_ctrls(struct rga_ctx *ctx) +{ + struct rockchip_rga *rga = ctx->rga; + + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 4); + + v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + + v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + + v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, + V4L2_CID_ROTATE, 0, 270, 90, 0); + + v4l2_ctrl_new_std(&ctx->ctrl_handler, &rga_ctrl_ops, + V4L2_CID_BG_COLOR, 0, 0xffffffff, 1, 0); + + if (ctx->ctrl_handler.error) { + int err = ctx->ctrl_handler.error; + + v4l2_err(&rga->v4l2_dev, "%s failed\n", __func__); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + return err; + } + + return 0; +} + +struct rga_fmt formats[] = { + { + .fourcc = V4L2_PIX_FMT_ARGB32, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR8888, + .depth = 32, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_XRGB32, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_XBGR8888, + .depth = 32, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR32, + .color_swap = RGA_COLOR_ALPHA_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR8888, + .depth = 32, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_XBGR32, + .color_swap = RGA_COLOR_ALPHA_SWAP, + .hw_format = RGA_COLOR_FMT_XBGR8888, + .depth = 32, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_RGB24, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_RGB888, + .depth = 24, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_BGR24, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_RGB888, + .depth = 24, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB444, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR4444, + .depth = 16, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_ABGR1555, + .depth = 16, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .color_swap = RGA_COLOR_RB_SWAP, + .hw_format = RGA_COLOR_FMT_BGR565, + .depth = 16, + .uv_factor = 1, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_NV21, + .color_swap = RGA_COLOR_UV_SWAP, + .hw_format = RGA_COLOR_FMT_YUV420SP, + .depth = 12, + .uv_factor = 4, + .y_div = 2, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_NV61, + .color_swap = RGA_COLOR_UV_SWAP, + .hw_format = RGA_COLOR_FMT_YUV422SP, + .depth = 16, + .uv_factor = 2, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_NV12, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_YUV420SP, + .depth = 12, + .uv_factor = 4, + .y_div = 2, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_NV16, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_YUV422SP, + .depth = 16, + .uv_factor = 2, + .y_div = 1, + .x_div = 1, + }, + { + .fourcc = V4L2_PIX_FMT_YUV420, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_YUV420P, + .depth = 12, + .uv_factor = 4, + .y_div = 2, + .x_div = 2, + }, + { + .fourcc = V4L2_PIX_FMT_YUV422P, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_YUV422P, + .depth = 16, + .uv_factor = 2, + .y_div = 1, + .x_div = 2, + }, + { + .fourcc = V4L2_PIX_FMT_YVU420, + .color_swap = RGA_COLOR_UV_SWAP, + .hw_format = RGA_COLOR_FMT_YUV420P, + .depth = 12, + .uv_factor = 4, + .y_div = 2, + .x_div = 2, + }, +}; + +#define NUM_FORMATS ARRAY_SIZE(formats) + +static struct rga_fmt *rga_fmt_find(struct v4l2_format *f) +{ + unsigned int i; + + for (i = 0; i < NUM_FORMATS; i++) { + if (formats[i].fourcc == f->fmt.pix.pixelformat) + return &formats[i]; + } + return NULL; +} + +static struct rga_frame def_frame = { + .width = DEFAULT_WIDTH, + .height = DEFAULT_HEIGHT, + .colorspace = V4L2_COLORSPACE_DEFAULT, + .crop.left = 0, + .crop.top = 0, + .crop.width = DEFAULT_WIDTH, + .crop.height = DEFAULT_HEIGHT, + .fmt = &formats[0], +}; + +struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->in; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->out; + default: + return ERR_PTR(-EINVAL); + } +} + +static int rga_open(struct file *file) +{ + struct rockchip_rga *rga = video_drvdata(file); + struct rga_ctx *ctx = NULL; + int ret = 0; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + ctx->rga = rga; + /* Set default formats */ + ctx->in = def_frame; + ctx->out = def_frame; + + if (mutex_lock_interruptible(&rga->mutex)) { + kfree(ctx); + return -ERESTARTSYS; + } + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(rga->m2m_dev, ctx, &queue_init); + if (IS_ERR(ctx->fh.m2m_ctx)) { + ret = PTR_ERR(ctx->fh.m2m_ctx); + mutex_unlock(&rga->mutex); + kfree(ctx); + return ret; + } + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + rga_setup_ctrls(ctx); + + /* Write the default values to the ctx struct */ + v4l2_ctrl_handler_setup(&ctx->ctrl_handler); + + ctx->fh.ctrl_handler = &ctx->ctrl_handler; + mutex_unlock(&rga->mutex); + + return 0; +} + +static int rga_release(struct file *file) +{ + struct rga_ctx *ctx = + container_of(file->private_data, struct rga_ctx, fh); + struct rockchip_rga *rga = ctx->rga; + + mutex_lock(&rga->mutex); + + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + kfree(ctx); + + mutex_unlock(&rga->mutex); + + return 0; +} + +static const struct v4l2_file_operations rga_fops = { + .owner = THIS_MODULE, + .open = rga_open, + .release = rga_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static int +vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) +{ + strlcpy(cap->driver, RGA_NAME, sizeof(cap->driver)); + strlcpy(cap->card, "rockchip-rga", sizeof(cap->card)); + strlcpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); + + return 0; +} + +static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) +{ + struct rga_fmt *fmt; + + if (f->index >= NUM_FORMATS) + return -EINVAL; + + fmt = &formats[f->index]; + f->pixelformat = fmt->fourcc; + + return 0; +} + +static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct rga_ctx *ctx = prv; + struct vb2_queue *vq; + struct rga_frame *frm; + + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (!vq) + return -EINVAL; + frm = rga_get_frame(ctx, f->type); + if (IS_ERR(frm)) + return PTR_ERR(frm); + + f->fmt.pix.width = frm->width; + f->fmt.pix.height = frm->height; + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.pixelformat = frm->fmt->fourcc; + f->fmt.pix.bytesperline = frm->stride; + f->fmt.pix.sizeimage = frm->size; + f->fmt.pix.colorspace = frm->colorspace; + + return 0; +} + +static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct rga_fmt *fmt; + + fmt = rga_fmt_find(f); + if (!fmt) { + fmt = &formats[0]; + f->fmt.pix.pixelformat = fmt->fourcc; + } + + f->fmt.pix.field = V4L2_FIELD_NONE; + + if (f->fmt.pix.width > MAX_WIDTH) + f->fmt.pix.width = MAX_WIDTH; + if (f->fmt.pix.height > MAX_HEIGHT) + f->fmt.pix.height = MAX_HEIGHT; + + if (f->fmt.pix.width < MIN_WIDTH) + f->fmt.pix.width = MIN_WIDTH; + if (f->fmt.pix.height < MIN_HEIGHT) + f->fmt.pix.height = MIN_HEIGHT; + + if (fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) + f->fmt.pix.bytesperline = f->fmt.pix.width; + else + f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + + f->fmt.pix.sizeimage = + f->fmt.pix.height * (f->fmt.pix.width * fmt->depth) >> 3; + + return 0; +} + +static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) +{ + struct rga_ctx *ctx = prv; + struct rockchip_rga *rga = ctx->rga; + struct vb2_queue *vq; + struct rga_frame *frm; + struct rga_fmt *fmt; + int ret = 0; + + /* Adjust all values accordingly to the hardware capabilities + * and chosen format. + */ + ret = vidioc_try_fmt(file, prv, f); + if (ret) + return ret; + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_busy(vq)) { + v4l2_err(&rga->v4l2_dev, "queue (%d) bust\n", f->type); + return -EBUSY; + } + frm = rga_get_frame(ctx, f->type); + if (IS_ERR(frm)) + return PTR_ERR(frm); + fmt = rga_fmt_find(f); + if (!fmt) + return -EINVAL; + frm->width = f->fmt.pix.width; + frm->height = f->fmt.pix.height; + frm->size = f->fmt.pix.sizeimage; + frm->fmt = fmt; + frm->stride = f->fmt.pix.bytesperline; + frm->colorspace = f->fmt.pix.colorspace; + + /* Reset crop settings */ + frm->crop.left = 0; + frm->crop.top = 0; + frm->crop.width = frm->width; + frm->crop.height = frm->height; + + return 0; +} + +static int vidioc_g_selection(struct file *file, void *prv, + struct v4l2_selection *s) +{ + struct rga_ctx *ctx = prv; + struct rga_frame *f; + bool use_frame = false; + + f = rga_get_frame(ctx, s->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + case V4L2_SEL_TGT_COMPOSE: + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + use_frame = true; + break; + case V4L2_SEL_TGT_CROP: + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + use_frame = true; + break; + default: + return -EINVAL; + } + + if (use_frame) { + s->r = f->crop; + } else { + s->r.left = 0; + s->r.top = 0; + s->r.width = f->width; + s->r.height = f->height; + } + + return 0; +} + +static int vidioc_s_selection(struct file *file, void *prv, + struct v4l2_selection *s) +{ + struct rga_ctx *ctx = prv; + struct rockchip_rga *rga = ctx->rga; + struct rga_frame *f; + int ret = 0; + + f = rga_get_frame(ctx, s->type); + if (IS_ERR(f)) + return PTR_ERR(f); + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE: + /* + * COMPOSE target is only valid for capture buffer type, return + * error for output buffer type + */ + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + case V4L2_SEL_TGT_CROP: + /* + * CROP target is only valid for output buffer type, return + * error for capture buffer type + */ + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + /* + * bound and default crop/compose targets are invalid targets to + * try/set + */ + default: + return -EINVAL; + } + + if (s->r.top < 0 || s->r.left < 0) { + v4l2_dbg(debug, 1, &rga->v4l2_dev, + "doesn't support negative values for top & left.\n"); + return -EINVAL; + } + + if (s->r.left + s->r.width > f->width || + s->r.top + s->r.height > f->height || + s->r.width < MIN_WIDTH || s->r.height < MIN_HEIGHT) { + v4l2_dbg(debug, 1, &rga->v4l2_dev, "unsupported crop value.\n"); + return -EINVAL; + } + + f->crop = s->r; + + return ret; +} + +static const struct v4l2_ioctl_ops rga_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt, + + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, + .vidioc_g_fmt_vid_out = vidioc_g_fmt, + .vidioc_try_fmt_vid_out = vidioc_try_fmt, + .vidioc_s_fmt_vid_out = vidioc_s_fmt, + + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_g_selection = vidioc_g_selection, + .vidioc_s_selection = vidioc_s_selection, +}; + +static struct video_device rga_videodev = { + .name = "rockchip-rga", + .fops = &rga_fops, + .ioctl_ops = &rga_ioctl_ops, + .minor = -1, + .release = video_device_release, + .vfl_dir = VFL_DIR_M2M, + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, +}; + +static int rga_enable_clocks(struct rockchip_rga *rga) +{ + int ret; + + ret = clk_prepare_enable(rga->sclk); + if (ret) { + dev_err(rga->dev, "Cannot enable rga sclk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(rga->aclk); + if (ret) { + dev_err(rga->dev, "Cannot enable rga aclk: %d\n", ret); + goto err_disable_sclk; + } + + ret = clk_prepare_enable(rga->hclk); + if (ret) { + dev_err(rga->dev, "Cannot enable rga hclk: %d\n", ret); + goto err_disable_aclk; + } + + return 0; + +err_disable_sclk: + clk_disable_unprepare(rga->sclk); +err_disable_aclk: + clk_disable_unprepare(rga->aclk); + + return ret; +} + +static void rga_disable_clocks(struct rockchip_rga *rga) +{ + clk_disable_unprepare(rga->sclk); + clk_disable_unprepare(rga->hclk); + clk_disable_unprepare(rga->aclk); +} + +static int rga_parse_dt(struct rockchip_rga *rga) +{ + struct reset_control *core_rst, *axi_rst, *ahb_rst; + + core_rst = devm_reset_control_get(rga->dev, "core"); + if (IS_ERR(core_rst)) { + dev_err(rga->dev, "failed to get core reset controller\n"); + return PTR_ERR(core_rst); + } + + axi_rst = devm_reset_control_get(rga->dev, "axi"); + if (IS_ERR(axi_rst)) { + dev_err(rga->dev, "failed to get axi reset controller\n"); + return PTR_ERR(axi_rst); + } + + ahb_rst = devm_reset_control_get(rga->dev, "ahb"); + if (IS_ERR(ahb_rst)) { + dev_err(rga->dev, "failed to get ahb reset controller\n"); + return PTR_ERR(ahb_rst); + } + + reset_control_assert(core_rst); + udelay(1); + reset_control_deassert(core_rst); + + reset_control_assert(axi_rst); + udelay(1); + reset_control_deassert(axi_rst); + + reset_control_assert(ahb_rst); + udelay(1); + reset_control_deassert(ahb_rst); + + rga->sclk = devm_clk_get(rga->dev, "sclk"); + if (IS_ERR(rga->sclk)) { + dev_err(rga->dev, "failed to get sclk clock\n"); + return PTR_ERR(rga->sclk); + } + + rga->aclk = devm_clk_get(rga->dev, "aclk"); + if (IS_ERR(rga->aclk)) { + dev_err(rga->dev, "failed to get aclk clock\n"); + return PTR_ERR(rga->aclk); + } + + rga->hclk = devm_clk_get(rga->dev, "hclk"); + if (IS_ERR(rga->hclk)) { + dev_err(rga->dev, "failed to get hclk clock\n"); + return PTR_ERR(rga->hclk); + } + + return 0; +} + +static int rga_probe(struct platform_device *pdev) +{ + struct rockchip_rga *rga; + struct video_device *vfd; + struct resource *res; + int ret = 0; + int irq; + + if (!pdev->dev.of_node) + return -ENODEV; + + rga = devm_kzalloc(&pdev->dev, sizeof(*rga), GFP_KERNEL); + if (!rga) + return -ENOMEM; + + rga->dev = &pdev->dev; + spin_lock_init(&rga->ctrl_lock); + mutex_init(&rga->mutex); + + init_waitqueue_head(&rga->irq_queue); + + ret = rga_parse_dt(rga); + if (ret) + dev_err(&pdev->dev, "Unable to parse OF data\n"); + + pm_runtime_enable(rga->dev); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + rga->regs = devm_ioremap_resource(rga->dev, res); + if (IS_ERR(rga->regs)) { + ret = PTR_ERR(rga->regs); + goto err_put_clk; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(rga->dev, "failed to get irq\n"); + ret = irq; + goto err_put_clk; + } + + ret = devm_request_irq(rga->dev, irq, rga_isr, 0, + dev_name(rga->dev), rga); + if (ret < 0) { + dev_err(rga->dev, "failed to request irq\n"); + goto err_put_clk; + } + + ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev); + if (ret) + goto err_put_clk; + vfd = video_device_alloc(); + if (!vfd) { + v4l2_err(&rga->v4l2_dev, "Failed to allocate video device\n"); + ret = -ENOMEM; + goto unreg_v4l2_dev; + } + *vfd = rga_videodev; + vfd->lock = &rga->mutex; + vfd->v4l2_dev = &rga->v4l2_dev; + + video_set_drvdata(vfd, rga); + snprintf(vfd->name, sizeof(vfd->name), "%s", rga_videodev.name); + rga->vfd = vfd; + + platform_set_drvdata(pdev, rga); + rga->m2m_dev = v4l2_m2m_init(&rga_m2m_ops); + if (IS_ERR(rga->m2m_dev)) { + v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); + ret = PTR_ERR(rga->m2m_dev); + goto unreg_video_dev; + } + + pm_runtime_get_sync(rga->dev); + + rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; + rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; + + v4l2_info(&rga->v4l2_dev, "HW Version: 0x%02x.%02x\n", + rga->version.major, rga->version.minor); + + pm_runtime_put(rga->dev); + + /* Create CMD buffer */ + rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE, + &rga->cmdbuf_phy, GFP_KERNEL, + DMA_ATTR_WRITE_COMBINE); + + rga->src_mmu_pages = + (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); + rga->dst_mmu_pages = + (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); + + def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; + def_frame.size = def_frame.stride * def_frame.height; + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); + if (ret) { + v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); + goto rel_vdev; + } + + v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", + vfd->name, video_device_node_name(vfd)); + + return 0; + +rel_vdev: + video_device_release(vfd); +unreg_video_dev: + video_unregister_device(rga->vfd); +unreg_v4l2_dev: + v4l2_device_unregister(&rga->v4l2_dev); +err_put_clk: + pm_runtime_disable(rga->dev); + + return ret; +} + +static int rga_remove(struct platform_device *pdev) +{ + struct rockchip_rga *rga = platform_get_drvdata(pdev); + + dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, &rga->cmdbuf_virt, + rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); + + free_pages((unsigned long)rga->src_mmu_pages, 3); + free_pages((unsigned long)rga->dst_mmu_pages, 3); + + v4l2_info(&rga->v4l2_dev, "Removing\n"); + + v4l2_m2m_release(rga->m2m_dev); + video_unregister_device(rga->vfd); + v4l2_device_unregister(&rga->v4l2_dev); + + pm_runtime_disable(rga->dev); + + return 0; +} + +static int __maybe_unused rga_runtime_suspend(struct device *dev) +{ + struct rockchip_rga *rga = dev_get_drvdata(dev); + + rga_disable_clocks(rga); + + return 0; +} + +static int __maybe_unused rga_runtime_resume(struct device *dev) +{ + struct rockchip_rga *rga = dev_get_drvdata(dev); + + return rga_enable_clocks(rga); +} + +static const struct dev_pm_ops rga_pm = { + SET_RUNTIME_PM_OPS(rga_runtime_suspend, + rga_runtime_resume, NULL) +}; + +static const struct of_device_id rockchip_rga_match[] = { + { + .compatible = "rockchip,rk3288-rga", + }, + { + .compatible = "rockchip,rk3399-rga", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, rockchip_rga_match); + +static struct platform_driver rga_pdrv = { + .probe = rga_probe, + .remove = rga_remove, + .driver = { + .name = RGA_NAME, + .pm = &rga_pm, + .of_match_table = rockchip_rga_match, + }, +}; + +module_platform_driver(rga_pdrv); + +MODULE_AUTHOR("Jacob Chen <jacob-chen@iotwrt.com>"); +MODULE_DESCRIPTION("Rockchip Raster 2d Graphic Acceleration Unit"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h new file mode 100644 index 000000000000..5d43e7ea88af --- /dev/null +++ b/drivers/media/platform/rockchip/rga/rga.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Author: Jacob Chen <jacob-chen@iotwrt.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __RGA_H__ +#define __RGA_H__ + +#include <linux/platform_device.h> +#include <media/videobuf2-v4l2.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> + +#define RGA_NAME "rockchip-rga" + +struct rga_fmt { + u32 fourcc; + int depth; + u8 uv_factor; + u8 y_div; + u8 x_div; + u8 color_swap; + u8 hw_format; +}; + +struct rga_frame { + /* Original dimensions */ + u32 width; + u32 height; + u32 colorspace; + + /* Crop */ + struct v4l2_rect crop; + + /* Image format */ + struct rga_fmt *fmt; + + /* Variables that can calculated once and reused */ + u32 stride; + u32 size; +}; + +struct rockchip_rga_version { + u32 major; + u32 minor; +}; + +struct rga_ctx { + struct v4l2_fh fh; + struct rockchip_rga *rga; + struct rga_frame in; + struct rga_frame out; + struct v4l2_ctrl_handler ctrl_handler; + + /* Control values */ + u32 op; + u32 hflip; + u32 vflip; + u32 rotate; + u32 fill_color; +}; + +struct rockchip_rga { + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct video_device *vfd; + + struct device *dev; + struct regmap *grf; + void __iomem *regs; + struct clk *sclk; + struct clk *aclk; + struct clk *hclk; + struct rockchip_rga_version version; + + /* vfd lock */ + struct mutex mutex; + /* ctrl parm lock */ + spinlock_t ctrl_lock; + + wait_queue_head_t irq_queue; + + struct rga_ctx *curr; + dma_addr_t cmdbuf_phy; + void *cmdbuf_virt; + unsigned int *src_mmu_pages; + unsigned int *dst_mmu_pages; +}; + +struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type); + +/* RGA Buffers Manage */ +extern const struct vb2_ops rga_qops; +void rga_buf_map(struct vb2_buffer *vb); + +/* RGA Hardware */ +static inline void rga_write(struct rockchip_rga *rga, u32 reg, u32 value) +{ + writel(value, rga->regs + reg); +}; + +static inline u32 rga_read(struct rockchip_rga *rga, u32 reg) +{ + return readl(rga->regs + reg); +}; + +static inline void rga_mod(struct rockchip_rga *rga, u32 reg, u32 val, u32 mask) +{ + u32 temp = rga_read(rga, reg) & ~(mask); + + temp |= val & mask; + rga_write(rga, reg, temp); +}; + +void rga_hw_start(struct rockchip_rga *rga); + +#endif diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index 1afde5021ca6..1839a86cc2a5 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -470,7 +470,7 @@ static void s5p_mfc_handle_error(struct s5p_mfc_dev *dev, { mfc_err("Interrupt Error: %08x\n", err); - if (ctx != NULL) { + if (ctx) { /* Error recovery is dependent on the state of context */ switch (ctx->state) { case MFCINST_RES_CHANGE_INIT: @@ -508,7 +508,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, { struct s5p_mfc_dev *dev; - if (ctx == NULL) + if (!ctx) return; dev = ctx->dev; if (ctx->c_ops->post_seq_start) { @@ -562,7 +562,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf *src_buf; struct s5p_mfc_dev *dev; - if (ctx == NULL) + if (!ctx) return; dev = ctx->dev; s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev); @@ -1043,12 +1043,9 @@ end: static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma) { struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data); - struct s5p_mfc_dev *dev = ctx->dev; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; int ret; - if (mutex_lock_interruptible(&dev->mfc_mutex)) - return -ERESTARTSYS; if (offset < DST_QUEUE_OFF_BASE) { mfc_debug(2, "mmaping source\n"); ret = vb2_mmap(&ctx->vq_src, vma); @@ -1057,7 +1054,6 @@ static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT); ret = vb2_mmap(&ctx->vq_dst, vma); } - mutex_unlock(&dev->mfc_mutex); return ret; } @@ -1083,7 +1079,7 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev, struct device *child; int ret; - child = devm_kzalloc(dev, sizeof(struct device), GFP_KERNEL); + child = devm_kzalloc(dev, sizeof(*child), GFP_KERNEL); if (!child) return NULL; @@ -1270,10 +1266,8 @@ static int s5p_mfc_probe(struct platform_device *pdev) pr_debug("%s++\n", __func__); dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&pdev->dev, "Not enough memory for MFC device\n"); + if (!dev) return -ENOMEM; - } spin_lock_init(&dev->irqlock); spin_lock_init(&dev->condlock); @@ -1291,7 +1285,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) return PTR_ERR(dev->regs_base); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { + if (!res) { dev_err(&pdev->dev, "failed to get irq resource\n"); return -ENOENT; } diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 1f3c450c7a69..916ff68b73d4 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1391,6 +1391,12 @@ static int soc_camera_async_complete(struct v4l2_async_notifier *notifier) return 0; } +static const struct v4l2_async_notifier_operations soc_camera_async_ops = { + .bound = soc_camera_async_bound, + .unbind = soc_camera_async_unbind, + .complete = soc_camera_async_complete, +}; + static int scan_async_group(struct soc_camera_host *ici, struct v4l2_async_subdev **asd, unsigned int size) { @@ -1437,9 +1443,7 @@ static int scan_async_group(struct soc_camera_host *ici, sasc->notifier.subdevs = asd; sasc->notifier.num_subdevs = size; - sasc->notifier.bound = soc_camera_async_bound; - sasc->notifier.unbind = soc_camera_async_unbind; - sasc->notifier.complete = soc_camera_async_complete; + sasc->notifier.ops = &soc_camera_async_ops; icd->sasc = sasc; icd->parent = ici->v4l2_dev.dev; @@ -1537,9 +1541,7 @@ static int soc_of_bind(struct soc_camera_host *ici, sasc->notifier.subdevs = &info->subdev; sasc->notifier.num_subdevs = 1; - sasc->notifier.bound = soc_camera_async_bound; - sasc->notifier.unbind = soc_camera_async_unbind; - sasc->notifier.complete = soc_camera_async_complete; + sasc->notifier.ops = &soc_camera_async_ops; icd->sasc = sasc; icd->parent = ici->v4l2_dev.dev; diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 939da6da7644..7e9ed9c7b3e1 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -723,7 +723,7 @@ static int bdisp_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) static int bdisp_g_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct bdisp_ctx *ctx = fh_to_ctx(fh); - struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_pix_format *pix; struct bdisp_frame *frame = ctx_get_frame(ctx, f->type); if (IS_ERR(frame)) { diff --git a/drivers/media/platform/sti/hva/hva-h264.c b/drivers/media/platform/sti/hva/hva-h264.c index e6f247a983c7..a7e5eed17ada 100644 --- a/drivers/media/platform/sti/hva/hva-h264.c +++ b/drivers/media/platform/sti/hva/hva-h264.c @@ -999,7 +999,6 @@ static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame, { struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv; struct hva_h264_task *task = (struct hva_h264_task *)ctx->task->vaddr; - struct hva_buffer *tmp_frame; u32 stuffing_bytes = 0; int ret = 0; @@ -1023,9 +1022,7 @@ static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame, &stream->bytesused); /* switch reference & reconstructed frame */ - tmp_frame = ctx->ref_frame; - ctx->ref_frame = ctx->rec_frame; - ctx->rec_frame = tmp_frame; + swap(ctx->ref_frame, ctx->rec_frame); return 0; err: diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index 35ba6f211b79..ac4c450a6c7d 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -1495,6 +1495,12 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier, return 0; } +static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = { + .bound = dcmi_graph_notify_bound, + .unbind = dcmi_graph_notify_unbind, + .complete = dcmi_graph_notify_complete, +}; + static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node) { struct device_node *ep = NULL; @@ -1542,9 +1548,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) dcmi->notifier.subdevs = subdevs; dcmi->notifier.num_subdevs = 1; - dcmi->notifier.bound = dcmi_graph_notify_bound; - dcmi->notifier.unbind = dcmi_graph_notify_unbind; - dcmi->notifier.complete = dcmi_graph_notify_complete; + dcmi->notifier.ops = &dcmi_graph_notify_ops; ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier); if (ret < 0) { diff --git a/drivers/media/platform/tegra-cec/Makefile b/drivers/media/platform/tegra-cec/Makefile new file mode 100644 index 000000000000..f3d81127589f --- /dev/null +++ b/drivers/media/platform/tegra-cec/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra_cec.o diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c new file mode 100644 index 000000000000..807c94c70049 --- /dev/null +++ b/drivers/media/platform/tegra-cec/tegra_cec.c @@ -0,0 +1,495 @@ +/* + * Tegra CEC implementation + * + * The original 3.10 CEC driver using a custom API: + * + * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved. + * + * Conversion to the CEC framework and to the mainline kernel: + * + * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/clk/tegra.h> + +#include <media/cec-notifier.h> + +#include "tegra_cec.h" + +#define TEGRA_CEC_NAME "tegra-cec" + +struct tegra_cec { + struct cec_adapter *adap; + struct device *dev; + struct clk *clk; + void __iomem *cec_base; + struct cec_notifier *notifier; + int tegra_cec_irq; + bool rx_done; + bool tx_done; + int tx_status; + u8 rx_buf[CEC_MAX_MSG_SIZE]; + u8 rx_buf_cnt; + u32 tx_buf[CEC_MAX_MSG_SIZE]; + u8 tx_buf_cur; + u8 tx_buf_cnt; +}; + +static inline u32 cec_read(struct tegra_cec *cec, u32 reg) +{ + return readl(cec->cec_base + reg); +} + +static inline void cec_write(struct tegra_cec *cec, u32 reg, u32 val) +{ + writel(val, cec->cec_base + reg); +} + +static void tegra_cec_error_recovery(struct tegra_cec *cec) +{ + u32 hw_ctrl; + + hw_ctrl = cec_read(cec, TEGRA_CEC_HW_CONTROL); + cec_write(cec, TEGRA_CEC_HW_CONTROL, 0); + cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff); + cec_write(cec, TEGRA_CEC_HW_CONTROL, hw_ctrl); +} + +static irqreturn_t tegra_cec_irq_thread_handler(int irq, void *data) +{ + struct device *dev = data; + struct tegra_cec *cec = dev_get_drvdata(dev); + + if (cec->tx_done) { + cec_transmit_attempt_done(cec->adap, cec->tx_status); + cec->tx_done = false; + } + if (cec->rx_done) { + struct cec_msg msg = {}; + + msg.len = cec->rx_buf_cnt; + memcpy(msg.msg, cec->rx_buf, msg.len); + cec_received_msg(cec->adap, &msg); + cec->rx_done = false; + cec->rx_buf_cnt = 0; + } + return IRQ_HANDLED; +} + +static irqreturn_t tegra_cec_irq_handler(int irq, void *data) +{ + struct device *dev = data; + struct tegra_cec *cec = dev_get_drvdata(dev); + u32 status, mask; + + status = cec_read(cec, TEGRA_CEC_INT_STAT); + mask = cec_read(cec, TEGRA_CEC_INT_MASK); + + status &= mask; + + if (!status) + return IRQ_HANDLED; + + if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN) { + dev_err(dev, "TX underrun, interrupt timing issue!\n"); + + tegra_cec_error_recovery(cec); + cec_write(cec, TEGRA_CEC_INT_MASK, + mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY); + + cec->tx_done = true; + cec->tx_status = CEC_TX_STATUS_ERROR; + return IRQ_WAKE_THREAD; + } + + if ((status & TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED) || + (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED)) { + tegra_cec_error_recovery(cec); + cec_write(cec, TEGRA_CEC_INT_MASK, + mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY); + + cec->tx_done = true; + if (status & TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED) + cec->tx_status = CEC_TX_STATUS_LOW_DRIVE; + else + cec->tx_status = CEC_TX_STATUS_ARB_LOST; + return IRQ_WAKE_THREAD; + } + + if (status & TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED) { + cec_write(cec, TEGRA_CEC_INT_STAT, + TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED); + + if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) { + tegra_cec_error_recovery(cec); + + cec->tx_done = true; + cec->tx_status = CEC_TX_STATUS_NACK; + } else { + cec->tx_done = true; + cec->tx_status = CEC_TX_STATUS_OK; + } + return IRQ_WAKE_THREAD; + } + + if (status & TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD) + dev_warn(dev, "TX NAKed on the fly!\n"); + + if (status & TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY) { + if (cec->tx_buf_cur == cec->tx_buf_cnt) { + cec_write(cec, TEGRA_CEC_INT_MASK, + mask & ~TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY); + } else { + cec_write(cec, TEGRA_CEC_TX_REGISTER, + cec->tx_buf[cec->tx_buf_cur++]); + cec_write(cec, TEGRA_CEC_INT_STAT, + TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY); + } + } + + if (status & (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN | + TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED | + TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED | + TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)) { + cec_write(cec, TEGRA_CEC_INT_STAT, + (TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN | + TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED | + TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED | + TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED)); + } else if (status & TEGRA_CEC_INT_STAT_RX_REGISTER_FULL) { + u32 v; + + cec_write(cec, TEGRA_CEC_INT_STAT, + TEGRA_CEC_INT_STAT_RX_REGISTER_FULL); + v = cec_read(cec, TEGRA_CEC_RX_REGISTER); + if (cec->rx_buf_cnt < CEC_MAX_MSG_SIZE) + cec->rx_buf[cec->rx_buf_cnt++] = v & 0xff; + if (v & TEGRA_CEC_RX_REGISTER_EOM) { + cec->rx_done = true; + return IRQ_WAKE_THREAD; + } + } + + return IRQ_HANDLED; +} + +static int tegra_cec_adap_enable(struct cec_adapter *adap, bool enable) +{ + struct tegra_cec *cec = adap->priv; + + cec->rx_buf_cnt = 0; + cec->tx_buf_cnt = 0; + cec->tx_buf_cur = 0; + + cec_write(cec, TEGRA_CEC_HW_CONTROL, 0); + cec_write(cec, TEGRA_CEC_INT_MASK, 0); + cec_write(cec, TEGRA_CEC_INT_STAT, 0xffffffff); + cec_write(cec, TEGRA_CEC_SW_CONTROL, 0); + + if (!enable) + return 0; + + cec_write(cec, TEGRA_CEC_INPUT_FILTER, (1U << 31) | 0x20); + + cec_write(cec, TEGRA_CEC_RX_TIMING_0, + (0x7a << TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT) | + (0x6d << TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT) | + (0x93 << TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT) | + (0x86 << TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT)); + + cec_write(cec, TEGRA_CEC_RX_TIMING_1, + (0x35 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT) | + (0x21 << TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT) | + (0x56 << TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT) | + (0x40 << TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT)); + + cec_write(cec, TEGRA_CEC_RX_TIMING_2, + (0x50 << TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT)); + + cec_write(cec, TEGRA_CEC_TX_TIMING_0, + (0x74 << TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT) | + (0x8d << TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT) | + (0x08 << TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT) | + (0x71 << TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT)); + + cec_write(cec, TEGRA_CEC_TX_TIMING_1, + (0x2f << TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT) | + (0x13 << TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT) | + (0x4b << TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT) | + (0x21 << TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT)); + + cec_write(cec, TEGRA_CEC_TX_TIMING_2, + (0x07 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT) | + (0x05 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT) | + (0x03 << TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT)); + + cec_write(cec, TEGRA_CEC_INT_MASK, + TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN | + TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD | + TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED | + TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED | + TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED | + TEGRA_CEC_INT_MASK_RX_REGISTER_FULL | + TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN); + + cec_write(cec, TEGRA_CEC_HW_CONTROL, TEGRA_CEC_HWCTRL_TX_RX_MODE); + return 0; +} + +static int tegra_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr) +{ + struct tegra_cec *cec = adap->priv; + u32 state = cec_read(cec, TEGRA_CEC_HW_CONTROL); + + if (logical_addr == CEC_LOG_ADDR_INVALID) + state &= ~TEGRA_CEC_HWCTRL_RX_LADDR_MASK; + else + state |= TEGRA_CEC_HWCTRL_RX_LADDR((1 << logical_addr)); + + cec_write(cec, TEGRA_CEC_HW_CONTROL, state); + return 0; +} + +static int tegra_cec_adap_monitor_all_enable(struct cec_adapter *adap, + bool enable) +{ + struct tegra_cec *cec = adap->priv; + u32 reg = cec_read(cec, TEGRA_CEC_HW_CONTROL); + + if (enable) + reg |= TEGRA_CEC_HWCTRL_RX_SNOOP; + else + reg &= ~TEGRA_CEC_HWCTRL_RX_SNOOP; + cec_write(cec, TEGRA_CEC_HW_CONTROL, reg); + return 0; +} + +static int tegra_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time_ms, struct cec_msg *msg) +{ + bool retry_xfer = signal_free_time_ms == CEC_SIGNAL_FREE_TIME_RETRY; + struct tegra_cec *cec = adap->priv; + unsigned int i; + u32 mode = 0; + u32 mask; + + if (cec_msg_is_broadcast(msg)) + mode = TEGRA_CEC_TX_REG_BCAST; + + cec->tx_buf_cur = 0; + cec->tx_buf_cnt = msg->len; + + for (i = 0; i < msg->len; i++) { + cec->tx_buf[i] = mode | msg->msg[i]; + if (i == 0) + cec->tx_buf[i] |= TEGRA_CEC_TX_REG_START_BIT; + if (i == msg->len - 1) + cec->tx_buf[i] |= TEGRA_CEC_TX_REG_EOM; + if (i == 0 && retry_xfer) + cec->tx_buf[i] |= TEGRA_CEC_TX_REG_RETRY; + } + + mask = cec_read(cec, TEGRA_CEC_INT_MASK); + cec_write(cec, TEGRA_CEC_INT_MASK, + mask | TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY); + + return 0; +} + +static const struct cec_adap_ops tegra_cec_ops = { + .adap_enable = tegra_cec_adap_enable, + .adap_log_addr = tegra_cec_adap_log_addr, + .adap_transmit = tegra_cec_adap_transmit, + .adap_monitor_all_enable = tegra_cec_adap_monitor_all_enable, +}; + +static int tegra_cec_probe(struct platform_device *pdev) +{ + struct platform_device *hdmi_dev; + struct device_node *np; + struct tegra_cec *cec; + struct resource *res; + int ret = 0; + + np = of_parse_phandle(pdev->dev.of_node, "hdmi-phandle", 0); + + if (!np) { + dev_err(&pdev->dev, "Failed to find hdmi node in device tree\n"); + return -ENODEV; + } + hdmi_dev = of_find_device_by_node(np); + if (hdmi_dev == NULL) + return -EPROBE_DEFER; + + cec = devm_kzalloc(&pdev->dev, sizeof(struct tegra_cec), GFP_KERNEL); + + if (!cec) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!res) { + dev_err(&pdev->dev, + "Unable to allocate resources for device\n"); + return -EBUSY; + } + + if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, + "Unable to request mem region for device\n"); + return -EBUSY; + } + + cec->tegra_cec_irq = platform_get_irq(pdev, 0); + + if (cec->tegra_cec_irq <= 0) + return -EBUSY; + + cec->cec_base = devm_ioremap_nocache(&pdev->dev, res->start, + resource_size(res)); + + if (!cec->cec_base) { + dev_err(&pdev->dev, "Unable to grab IOs for device\n"); + return -EBUSY; + } + + cec->clk = devm_clk_get(&pdev->dev, "cec"); + + if (IS_ERR_OR_NULL(cec->clk)) { + dev_err(&pdev->dev, "Can't get clock for CEC\n"); + return -ENOENT; + } + + clk_prepare_enable(cec->clk); + + /* set context info. */ + cec->dev = &pdev->dev; + + platform_set_drvdata(pdev, cec); + + ret = devm_request_threaded_irq(&pdev->dev, cec->tegra_cec_irq, + tegra_cec_irq_handler, tegra_cec_irq_thread_handler, + 0, "cec_irq", &pdev->dev); + + if (ret) { + dev_err(&pdev->dev, + "Unable to request interrupt for device\n"); + goto clk_error; + } + + cec->notifier = cec_notifier_get(&hdmi_dev->dev); + if (!cec->notifier) { + ret = -ENOMEM; + goto clk_error; + } + + cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME, + CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, + CEC_MAX_LOG_ADDRS); + if (IS_ERR(cec->adap)) { + ret = -ENOMEM; + dev_err(&pdev->dev, "Couldn't create cec adapter\n"); + goto cec_error; + } + ret = cec_register_adapter(cec->adap, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Couldn't register device\n"); + goto cec_error; + } + + cec_register_cec_notifier(cec->adap, cec->notifier); + + return 0; + +cec_error: + if (cec->notifier) + cec_notifier_put(cec->notifier); + cec_delete_adapter(cec->adap); +clk_error: + clk_disable_unprepare(cec->clk); + return ret; +} + +static int tegra_cec_remove(struct platform_device *pdev) +{ + struct tegra_cec *cec = platform_get_drvdata(pdev); + + clk_disable_unprepare(cec->clk); + + cec_unregister_adapter(cec->adap); + cec_notifier_put(cec->notifier); + + return 0; +} + +#ifdef CONFIG_PM +static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tegra_cec *cec = platform_get_drvdata(pdev); + + clk_disable_unprepare(cec->clk); + + dev_notice(&pdev->dev, "suspended\n"); + return 0; +} + +static int tegra_cec_resume(struct platform_device *pdev) +{ + struct tegra_cec *cec = platform_get_drvdata(pdev); + + dev_notice(&pdev->dev, "Resuming\n"); + + clk_prepare_enable(cec->clk); + + return 0; +} +#endif + +static const struct of_device_id tegra_cec_of_match[] = { + { .compatible = "nvidia,tegra114-cec", }, + { .compatible = "nvidia,tegra124-cec", }, + { .compatible = "nvidia,tegra210-cec", }, + {}, +}; + +static struct platform_driver tegra_cec_driver = { + .driver = { + .name = TEGRA_CEC_NAME, + .of_match_table = of_match_ptr(tegra_cec_of_match), + }, + .probe = tegra_cec_probe, + .remove = tegra_cec_remove, + +#ifdef CONFIG_PM + .suspend = tegra_cec_suspend, + .resume = tegra_cec_resume, +#endif +}; + +module_platform_driver(tegra_cec_driver); diff --git a/drivers/media/platform/tegra-cec/tegra_cec.h b/drivers/media/platform/tegra-cec/tegra_cec.h new file mode 100644 index 000000000000..e301513daa87 --- /dev/null +++ b/drivers/media/platform/tegra-cec/tegra_cec.h @@ -0,0 +1,127 @@ +/* + * Tegra CEC register definitions + * + * The original 3.10 CEC driver using a custom API: + * + * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved. + * + * Conversion to the CEC framework and to the mainline kernel: + * + * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TEGRA_CEC_H +#define TEGRA_CEC_H + +/* CEC registers */ +#define TEGRA_CEC_SW_CONTROL 0x000 +#define TEGRA_CEC_HW_CONTROL 0x004 +#define TEGRA_CEC_INPUT_FILTER 0x008 +#define TEGRA_CEC_TX_REGISTER 0x010 +#define TEGRA_CEC_RX_REGISTER 0x014 +#define TEGRA_CEC_RX_TIMING_0 0x018 +#define TEGRA_CEC_RX_TIMING_1 0x01c +#define TEGRA_CEC_RX_TIMING_2 0x020 +#define TEGRA_CEC_TX_TIMING_0 0x024 +#define TEGRA_CEC_TX_TIMING_1 0x028 +#define TEGRA_CEC_TX_TIMING_2 0x02c +#define TEGRA_CEC_INT_STAT 0x030 +#define TEGRA_CEC_INT_MASK 0x034 +#define TEGRA_CEC_HW_DEBUG_RX 0x038 +#define TEGRA_CEC_HW_DEBUG_TX 0x03c + +#define TEGRA_CEC_HWCTRL_RX_LADDR_MASK 0x7fff +#define TEGRA_CEC_HWCTRL_RX_LADDR(x) \ + ((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK) +#define TEGRA_CEC_HWCTRL_RX_SNOOP (1 << 15) +#define TEGRA_CEC_HWCTRL_RX_NAK_MODE (1 << 16) +#define TEGRA_CEC_HWCTRL_TX_NAK_MODE (1 << 24) +#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE (1 << 30) +#define TEGRA_CEC_HWCTRL_TX_RX_MODE (1 << 31) + +#define TEGRA_CEC_INPUT_FILTER_MODE (1 << 31) +#define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT 0 + +#define TEGRA_CEC_TX_REG_DATA_SHIFT 0 +#define TEGRA_CEC_TX_REG_EOM (1 << 8) +#define TEGRA_CEC_TX_REG_BCAST (1 << 12) +#define TEGRA_CEC_TX_REG_START_BIT (1 << 16) +#define TEGRA_CEC_TX_REG_RETRY (1 << 17) + +#define TEGRA_CEC_RX_REGISTER_SHIFT 0 +#define TEGRA_CEC_RX_REGISTER_EOM (1 << 8) +#define TEGRA_CEC_RX_REGISTER_ACK (1 << 9) + +#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT 0 +#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT 8 +#define TEGRA_CEC_RX_TIM0_START_BIT_MAX_DURATION_SHIFT 16 +#define TEGRA_CEC_RX_TIM0_START_BIT_MIN_DURATION_SHIFT 24 + +#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_LO_TIME_SHIFT 0 +#define TEGRA_CEC_RX_TIM1_DATA_BIT_SAMPLE_TIME_SHIFT 8 +#define TEGRA_CEC_RX_TIM1_DATA_BIT_MAX_DURATION_SHIFT 16 +#define TEGRA_CEC_RX_TIM1_DATA_BIT_MIN_DURATION_SHIFT 24 + +#define TEGRA_CEC_RX_TIM2_END_OF_BLOCK_TIME_SHIFT 0 + +#define TEGRA_CEC_TX_TIM0_START_BIT_LO_TIME_SHIFT 0 +#define TEGRA_CEC_TX_TIM0_START_BIT_DURATION_SHIFT 8 +#define TEGRA_CEC_TX_TIM0_BUS_XITION_TIME_SHIFT 16 +#define TEGRA_CEC_TX_TIM0_BUS_ERROR_LO_TIME_SHIFT 24 + +#define TEGRA_CEC_TX_TIM1_LO_DATA_BIT_LO_TIME_SHIFT 0 +#define TEGRA_CEC_TX_TIM1_HI_DATA_BIT_LO_TIME_SHIFT 8 +#define TEGRA_CEC_TX_TIM1_DATA_BIT_DURATION_SHIFT 16 +#define TEGRA_CEC_TX_TIM1_ACK_NAK_BIT_SAMPLE_TIME_SHIFT 24 + +#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_ADDITIONAL_FRAME_SHIFT 0 +#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT 4 +#define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT 8 + +#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY (1 << 0) +#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN (1 << 1) +#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD (1 << 2) +#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED (1 << 3) +#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED (1 << 4) +#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED (1 << 5) +#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL (1 << 8) +#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN (1 << 9) +#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED (1 << 10) +#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED (1 << 11) +#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED (1 << 12) +#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13) +#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14) + +#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY (1 << 0) +#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN (1 << 1) +#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD (1 << 2) +#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED (1 << 3) +#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED (1 << 4) +#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED (1 << 5) +#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL (1 << 8) +#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN (1 << 9) +#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED (1 << 10) +#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED (1 << 11) +#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED (1 << 12) +#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13) +#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14) + +#define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT 0 +#define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT 17 +#define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT 21 +#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT (1 << 25) +#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER (1 << 26) + +#endif /* TEGRA_CEC_H */ diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 42e383a48ffe..8b586c864524 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -1522,6 +1522,11 @@ static int cal_async_complete(struct v4l2_async_notifier *notifier) return 0; } +static const struct v4l2_async_notifier_operations cal_async_ops = { + .bound = cal_async_bound, + .complete = cal_async_complete, +}; + static int cal_complete_ctx(struct cal_ctx *ctx) { struct video_device *vfd; @@ -1736,8 +1741,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst) ctx->asd_list[0] = asd; ctx->notifier.subdevs = ctx->asd_list; ctx->notifier.num_subdevs = 1; - ctx->notifier.bound = cal_async_bound; - ctx->notifier.complete = cal_async_complete; + ctx->notifier.ops = &cal_async_ops; ret = v4l2_async_notifier_register(&ctx->v4l2_dev, &ctx->notifier); if (ret) { diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c index 51c0eee61ca6..fe088a953860 100644 --- a/drivers/media/platform/vimc/vimc-core.c +++ b/drivers/media/platform/vimc/vimc-core.c @@ -267,11 +267,12 @@ static struct component_match *vimc_add_subdevs(struct vimc_device *vimc) PLATFORM_DEVID_AUTO, &pdata, sizeof(pdata)); - if (!vimc->subdevs[i]) { + if (IS_ERR(vimc->subdevs[i])) { + match = ERR_CAST(vimc->subdevs[i]); while (--i >= 0) platform_device_unregister(vimc->subdevs[i]); - return ERR_PTR(-ENOMEM); + return match; } component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare, diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index f0f423c7ca41..a651527d80db 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -189,6 +189,22 @@ struct vivid_fmt vivid_formats[] = { .buffers = 1, }, { + .fourcc = V4L2_PIX_FMT_Y10, + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .color_enc = TGP_COLOR_ENC_LUMA, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_Y12, + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .color_enc = TGP_COLOR_ENC_LUMA, + .planes = 1, + .buffers = 1, + }, + { .fourcc = V4L2_PIX_FMT_Y16, .vdownsampling = { 1 }, .bit_depth = { 16 }, diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index ebfdf334d99c..d881cf09876d 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -351,6 +351,11 @@ static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, return -EINVAL; } +static const struct v4l2_async_notifier_operations xvip_graph_notify_ops = { + .bound = xvip_graph_notify_bound, + .complete = xvip_graph_notify_complete, +}; + static int xvip_graph_parse_one(struct xvip_composite_device *xdev, struct device_node *node) { @@ -548,8 +553,7 @@ static int xvip_graph_init(struct xvip_composite_device *xdev) xdev->notifier.subdevs = subdevs; xdev->notifier.num_subdevs = num_subdevs; - xdev->notifier.bound = xvip_graph_notify_bound; - xdev->notifier.complete = xvip_graph_notify_complete; + xdev->notifier.ops = &xvip_graph_notify_ops; ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier); if (ret < 0) { diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 6888b7db449d..7575e5370a49 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -281,9 +281,9 @@ static bool cadet_has_rds_data(struct cadet *dev) } -static void cadet_handler(unsigned long data) +static void cadet_handler(struct timer_list *t) { - struct cadet *dev = (void *)data; + struct cadet *dev = from_timer(dev, t, readtimer); /* Service the RDS fifo */ if (mutex_trylock(&dev->lock)) { @@ -309,7 +309,6 @@ static void cadet_handler(unsigned long data) /* * Clean up and exit */ - setup_timer(&dev->readtimer, cadet_handler, data); dev->readtimer.expires = jiffies + msecs_to_jiffies(50); add_timer(&dev->readtimer); } @@ -318,7 +317,7 @@ static void cadet_start_rds(struct cadet *dev) { dev->rdsstat = 1; outb(0x80, dev->io); /* Select RDS fifo */ - setup_timer(&dev->readtimer, cadet_handler, (unsigned long)dev); + timer_setup(&dev->readtimer, cadet_handler, 0); dev->readtimer.expires = jiffies + msecs_to_jiffies(50); add_timer(&dev->readtimer); } diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c index 3c0a22a54113..70a2c86774ce 100644 --- a/drivers/media/radio/radio-raremono.c +++ b/drivers/media/radio/radio-raremono.c @@ -254,7 +254,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { struct raremono_device *radio = video_drvdata(file); - u32 freq = f->frequency; + u32 freq; unsigned band; if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index cd76facc22f5..c89a7d5b8c55 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -749,7 +749,7 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = { /* * si470x_viddev_template - video device interface */ -struct video_device si470x_viddev_template = { +const struct video_device si470x_viddev_template = { .fops = &si470x_fops, .name = DRIVER_NAME, .release = video_device_release_empty, diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h index 7d2defd9d399..eb7b834a0ae5 100644 --- a/drivers/media/radio/si470x/radio-si470x.h +++ b/drivers/media/radio/si470x/radio-si470x.h @@ -209,7 +209,7 @@ struct si470x_device { /************************************************************************** * Common Functions **************************************************************************/ -extern struct video_device si470x_viddev_template; +extern const struct video_device si470x_viddev_template; extern const struct v4l2_ctrl_ops si470x_ctrl_ops; int si470x_get_register(struct si470x_device *radio, int regnr); int si470x_set_register(struct si470x_device *radio, int regnr); diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig index c9e349b169c4..2add222ea346 100644 --- a/drivers/media/radio/wl128x/Kconfig +++ b/drivers/media/radio/wl128x/Kconfig @@ -7,11 +7,11 @@ config RADIO_WL128X depends on VIDEO_V4L2 && RFKILL && TTY && TI_ST depends on GPIOLIB || COMPILE_TEST help - Choose Y here if you have this FM radio chip. + Choose Y here if you have this FM radio chip. - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux 2 API. Information on - this API and pointers to "v4l2" programs may be found at - <file:Documentation/video4linux/API.html>. + In order to control your radio card, you will need to use programs + that are compatible with the Video For Linux 2 API. Information on + this API and pointers to "v4l2" programs may be found at + <file:Documentation/video4linux/API.html>. endmenu diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index ab3428bf63fe..800d69c3f80b 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -543,13 +543,13 @@ static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage) * interrupt process. Therefore reset stage index to re-enable default * interrupts. So that next interrupt will be processed as usual. */ -static void int_timeout_handler(unsigned long data) +static void int_timeout_handler(struct timer_list *t) { struct fmdev *fmdev; struct fm_irq *fmirq; fmdbg("irq: timeout,trying to re-enable fm interrupts\n"); - fmdev = (struct fmdev *)data; + fmdev = from_timer(fmdev, t, irq_info.timer); fmirq = &fmdev->irq_info; fmirq->retry++; @@ -1550,8 +1550,7 @@ int fmc_prepare(struct fmdev *fmdev) atomic_set(&fmdev->tx_cnt, 1); fmdev->resp_comp = NULL; - setup_timer(&fmdev->irq_info.timer, &int_timeout_handler, - (unsigned long)fmdev); + timer_setup(&fmdev->irq_info.timer, int_timeout_handler, 0); /*TODO: add FM_STIC_EVENT later */ fmdev->irq_info.mask = FM_MAL_EVENT; diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index d9ce8ff55d0c..afb3456d4e20 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -2,7 +2,6 @@ menuconfig RC_CORE tristate "Remote Controller support" depends on INPUT - default y ---help--- Enable support for Remote Controllers on Linux. This is needed in order to support several video capture adapters, @@ -179,6 +178,7 @@ config IR_ENE config IR_HIX5HD2 tristate "Hisilicon hix5hd2 IR remote control" depends on RC_CORE + depends on OF || COMPILE_TEST help Say Y here if you want to use hisilicon hix5hd2 remote control. To compile this driver as a module, choose M here: the module will be @@ -286,6 +286,7 @@ config IR_REDRAT3 config IR_SPI tristate "SPI connected IR LED" depends on SPI && LIRC + depends on OF || COMPILE_TEST ---help--- Say Y if you want to use an IR LED connected through SPI bus. @@ -393,6 +394,7 @@ config RC_LOOPBACK config IR_GPIO_CIR tristate "GPIO IR remote control" depends on RC_CORE + depends on (OF && GPIOLIB) || COMPILE_TEST ---help--- Say Y if you want to use GPIO based IR Receiver. @@ -403,6 +405,7 @@ config IR_GPIO_TX tristate "GPIO IR Bit Banging Transmitter" depends on RC_CORE depends on LIRC + depends on (OF && GPIOLIB) || COMPILE_TEST ---help--- Say Y if you want to a GPIO based IR transmitter. This is a bit banging driver. @@ -415,6 +418,7 @@ config IR_PWM_TX depends on RC_CORE depends on LIRC depends on PWM + depends on OF || COMPILE_TEST ---help--- Say Y if you want to use a PWM based IR transmitter. This is more power efficient than the bit banging gpio driver. @@ -469,6 +473,16 @@ config IR_SIR To compile this driver as a module, choose M here: the module will be called sir-ir. +config IR_TANGO + tristate "Sigma Designs SMP86xx IR decoder" + depends on RC_CORE + depends on ARCH_TANGO || COMPILE_TEST + ---help--- + Adds support for the HW IR decoder embedded on Sigma Designs + Tango-based systems (SMP86xx, SMP87xx). + The HW decoder supports NEC, RC-5, RC-6 IR protocols. + When compiled as a module, look for tango-ir. + config IR_ZX tristate "ZTE ZX IR remote control" depends on RC_CORE diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile index ab3d5a135453..10026477a677 100644 --- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -45,3 +45,4 @@ obj-$(CONFIG_IR_SERIAL) += serial_ir.o obj-$(CONFIG_IR_SIR) += sir_ir.o obj-$(CONFIG_IR_MTK) += mtk-cir.o obj-$(CONFIG_IR_ZX) += zx-irdec.o +obj-$(CONFIG_IR_TANGO) += tango-ir.o diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index d0871d60a723..8e82610ffaad 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -198,7 +198,7 @@ static const struct ati_receiver_type type_firefly = { .default_keymap = RC_MAP_SNAPSTREAM_FIREFLY }; -static struct usb_device_id ati_remote_table[] = { +static const struct usb_device_id ati_remote_table[] = { { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index af7ba23e16e1..71b8c9bbf6c4 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -670,9 +670,9 @@ exit: } /* timer to simulate tx done interrupt */ -static void ene_tx_irqsim(unsigned long data) +static void ene_tx_irqsim(struct timer_list *t) { - struct ene_device *dev = (struct ene_device *)data; + struct ene_device *dev = from_timer(dev, t, tx_sim_timer); unsigned long flags; spin_lock_irqsave(&dev->hw_lock, flags); @@ -1045,8 +1045,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (!dev->hw_learning_and_tx_capable && txsim) { dev->hw_learning_and_tx_capable = true; - setup_timer(&dev->tx_sim_timer, ene_tx_irqsim, - (long unsigned int)dev); + timer_setup(&dev->tx_sim_timer, ene_tx_irqsim, 0); pr_warn("Simulation of TX activated\n"); } diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c index 7248b3662285..3d99b51384ac 100644 --- a/drivers/media/rc/gpio-ir-recv.c +++ b/drivers/media/rc/gpio-ir-recv.c @@ -14,119 +14,64 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/irq.h> #include <media/rc-core.h> -#include <linux/platform_data/media/gpio-ir-recv.h> -#define GPIO_IR_DRIVER_NAME "gpio-rc-recv" #define GPIO_IR_DEVICE_NAME "gpio_ir_recv" struct gpio_rc_dev { struct rc_dev *rcdev; - int gpio_nr; - bool active_low; + struct gpio_desc *gpiod; + int irq; }; -#ifdef CONFIG_OF -/* - * Translate OpenFirmware node properties into platform_data - */ -static int gpio_ir_recv_get_devtree_pdata(struct device *dev, - struct gpio_ir_recv_platform_data *pdata) -{ - struct device_node *np = dev->of_node; - enum of_gpio_flags flags; - int gpio; - - gpio = of_get_gpio_flags(np, 0, &flags); - if (gpio < 0) { - if (gpio != -EPROBE_DEFER) - dev_err(dev, "Failed to get gpio flags (%d)\n", gpio); - return gpio; - } - - pdata->gpio_nr = gpio; - pdata->active_low = (flags & OF_GPIO_ACTIVE_LOW); - /* probe() takes care of map_name == NULL or allowed_protos == 0 */ - pdata->map_name = of_get_property(np, "linux,rc-map-name", NULL); - pdata->allowed_protos = 0; - - return 0; -} - -static const struct of_device_id gpio_ir_recv_of_match[] = { - { .compatible = "gpio-ir-receiver", }, - { }, -}; -MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match); - -#else /* !CONFIG_OF */ - -#define gpio_ir_recv_get_devtree_pdata(dev, pdata) (-ENOSYS) - -#endif - static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) { + int val; struct gpio_rc_dev *gpio_dev = dev_id; - int gval; - int rc = 0; - - gval = gpio_get_value(gpio_dev->gpio_nr); - - if (gval < 0) - goto err_get_value; - - if (gpio_dev->active_low) - gval = !gval; - rc = ir_raw_event_store_edge(gpio_dev->rcdev, gval == 1); - if (rc < 0) - goto err_get_value; + val = gpiod_get_value(gpio_dev->gpiod); + if (val >= 0) + ir_raw_event_store_edge(gpio_dev->rcdev, val == 1); -err_get_value: return IRQ_HANDLED; } static int gpio_ir_recv_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct gpio_rc_dev *gpio_dev; struct rc_dev *rcdev; - const struct gpio_ir_recv_platform_data *pdata = - pdev->dev.platform_data; int rc; - if (pdev->dev.of_node) { - struct gpio_ir_recv_platform_data *dtpdata = - devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL); - if (!dtpdata) - return -ENOMEM; - rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata); - if (rc) - return rc; - pdata = dtpdata; - } - - if (!pdata) - return -EINVAL; + if (!np) + return -ENODEV; - if (pdata->gpio_nr < 0) - return -EINVAL; - - gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL); + gpio_dev = devm_kzalloc(dev, sizeof(*gpio_dev), GFP_KERNEL); if (!gpio_dev) return -ENOMEM; - rcdev = rc_allocate_device(RC_DRIVER_IR_RAW); - if (!rcdev) { - rc = -ENOMEM; - goto err_allocate_device; + gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN); + if (IS_ERR(gpio_dev->gpiod)) { + rc = PTR_ERR(gpio_dev->gpiod); + /* Just try again if this happens */ + if (rc != -EPROBE_DEFER) + dev_err(dev, "error getting gpio (%d)\n", rc); + return rc; } + gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod); + if (gpio_dev->irq < 0) + return gpio_dev->irq; + + rcdev = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW); + if (!rcdev) + return -ENOMEM; rcdev->priv = gpio_dev; rcdev->device_name = GPIO_IR_DEVICE_NAME; @@ -135,92 +80,52 @@ static int gpio_ir_recv_probe(struct platform_device *pdev) rcdev->input_id.vendor = 0x0001; rcdev->input_id.product = 0x0001; rcdev->input_id.version = 0x0100; - rcdev->dev.parent = &pdev->dev; - rcdev->driver_name = GPIO_IR_DRIVER_NAME; + rcdev->dev.parent = dev; + rcdev->driver_name = KBUILD_MODNAME; rcdev->min_timeout = 1; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; - if (pdata->allowed_protos) - rcdev->allowed_protocols = pdata->allowed_protos; - else - rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; + rcdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; + rcdev->map_name = of_get_property(np, "linux,rc-map-name", NULL); + if (!rcdev->map_name) + rcdev->map_name = RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; - gpio_dev->gpio_nr = pdata->gpio_nr; - gpio_dev->active_low = pdata->active_low; - - rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); - if (rc < 0) - goto err_gpio_request; - rc = gpio_direction_input(pdata->gpio_nr); - if (rc < 0) - goto err_gpio_direction_input; - rc = rc_register_device(rcdev); + rc = devm_rc_register_device(dev, rcdev); if (rc < 0) { - dev_err(&pdev->dev, "failed to register rc device\n"); - goto err_register_rc_device; + dev_err(dev, "failed to register rc device (%d)\n", rc); + return rc; } platform_set_drvdata(pdev, gpio_dev); - rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr), - gpio_ir_recv_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "gpio-ir-recv-irq", gpio_dev); - if (rc < 0) - goto err_request_irq; - - return 0; - -err_request_irq: - rc_unregister_device(rcdev); - rcdev = NULL; -err_register_rc_device: -err_gpio_direction_input: - gpio_free(pdata->gpio_nr); -err_gpio_request: - rc_free_device(rcdev); -err_allocate_device: - kfree(gpio_dev); - return rc; -} - -static int gpio_ir_recv_remove(struct platform_device *pdev) -{ - struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); - - free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); - rc_unregister_device(gpio_dev->rcdev); - gpio_free(gpio_dev->gpio_nr); - kfree(gpio_dev); - return 0; + return devm_request_irq(dev, gpio_dev->irq, gpio_ir_recv_irq, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "gpio-ir-recv-irq", gpio_dev); } #ifdef CONFIG_PM static int gpio_ir_recv_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); + struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev); if (device_may_wakeup(dev)) - enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); + enable_irq_wake(gpio_dev->irq); else - disable_irq(gpio_to_irq(gpio_dev->gpio_nr)); + disable_irq(gpio_dev->irq); return 0; } static int gpio_ir_recv_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); + struct gpio_rc_dev *gpio_dev = dev_get_drvdata(dev); if (device_may_wakeup(dev)) - disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); + disable_irq_wake(gpio_dev->irq); else - enable_irq(gpio_to_irq(gpio_dev->gpio_nr)); + enable_irq(gpio_dev->irq); return 0; } @@ -231,11 +136,16 @@ static const struct dev_pm_ops gpio_ir_recv_pm_ops = { }; #endif +static const struct of_device_id gpio_ir_recv_of_match[] = { + { .compatible = "gpio-ir-receiver", }, + { }, +}; +MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match); + static struct platform_driver gpio_ir_recv_driver = { .probe = gpio_ir_recv_probe, - .remove = gpio_ir_recv_remove, .driver = { - .name = GPIO_IR_DRIVER_NAME, + .name = KBUILD_MODNAME, .of_match_table = of_match_ptr(gpio_ir_recv_of_match), #ifdef CONFIG_PM .pm = &gpio_ir_recv_pm_ops, diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index a5ea86be8f44..f563ddd7f739 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -137,9 +137,9 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) dev_err(ir->dev, "submit urb failed: %d", ret); } -static void igorplugusb_timer(unsigned long data) +static void igorplugusb_timer(struct timer_list *t) { - struct igorplugusb *ir = (struct igorplugusb *)data; + struct igorplugusb *ir = from_timer(ir, t, timer); igorplugusb_cmd(ir, GET_INFRACODE); } @@ -174,7 +174,7 @@ static int igorplugusb_probe(struct usb_interface *intf, ir->dev = &intf->dev; - setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir); + timer_setup(&ir->timer, igorplugusb_timer, 0); ir->request.bRequest = GET_INFRACODE; ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; @@ -245,7 +245,7 @@ static void igorplugusb_disconnect(struct usb_interface *intf) usb_free_urb(ir->urb); } -static struct usb_device_id igorplugusb_table[] = { +static const struct usb_device_id igorplugusb_table[] = { /* Igor Plug USB (Atmel's Manufact. ID) */ { USB_DEVICE(0x03eb, 0x0002) }, /* Fit PC2 Infrared Adapter */ diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c index 03fe080278df..bcbabeeab12a 100644 --- a/drivers/media/rc/img-ir/img-ir-core.c +++ b/drivers/media/rc/img-ir/img-ir-core.c @@ -92,10 +92,9 @@ static int img_ir_probe(struct platform_device *pdev) /* Private driver data */ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "cannot allocate device data\n"); + if (!priv) return -ENOMEM; - } + platform_set_drvdata(pdev, priv); priv->dev = &pdev->dev; spin_lock_init(&priv->lock); diff --git a/drivers/media/rc/img-ir/img-ir-hw.c b/drivers/media/rc/img-ir/img-ir-hw.c index 82fdf4cc0824..f54bc5d23893 100644 --- a/drivers/media/rc/img-ir/img-ir-hw.c +++ b/drivers/media/rc/img-ir/img-ir-hw.c @@ -867,9 +867,9 @@ static void img_ir_handle_data(struct img_ir_priv *priv, u32 len, u64 raw) } /* timer function to end waiting for repeat. */ -static void img_ir_end_timer(unsigned long arg) +static void img_ir_end_timer(struct timer_list *t) { - struct img_ir_priv *priv = (struct img_ir_priv *)arg; + struct img_ir_priv *priv = from_timer(priv, t, hw.end_timer); spin_lock_irq(&priv->lock); img_ir_end_repeat(priv); @@ -881,9 +881,9 @@ static void img_ir_end_timer(unsigned long arg) * cleared when invalid interrupts were generated due to a quirk in the * img-ir decoder. */ -static void img_ir_suspend_timer(unsigned long arg) +static void img_ir_suspend_timer(struct timer_list *t) { - struct img_ir_priv *priv = (struct img_ir_priv *)arg; + struct img_ir_priv *priv = from_timer(priv, t, hw.suspend_timer); spin_lock_irq(&priv->lock); /* @@ -1055,9 +1055,8 @@ int img_ir_probe_hw(struct img_ir_priv *priv) img_ir_probe_hw_caps(priv); /* Set up the end timer */ - setup_timer(&hw->end_timer, img_ir_end_timer, (unsigned long)priv); - setup_timer(&hw->suspend_timer, img_ir_suspend_timer, - (unsigned long)priv); + timer_setup(&hw->end_timer, img_ir_end_timer, 0); + timer_setup(&hw->suspend_timer, img_ir_suspend_timer, 0); /* Register a clock notifier */ if (!IS_ERR(priv->clk)) { diff --git a/drivers/media/rc/img-ir/img-ir-raw.c b/drivers/media/rc/img-ir/img-ir-raw.c index 64714efc1145..6e545680d3b6 100644 --- a/drivers/media/rc/img-ir/img-ir-raw.c +++ b/drivers/media/rc/img-ir/img-ir-raw.c @@ -67,9 +67,9 @@ void img_ir_isr_raw(struct img_ir_priv *priv, u32 irq_status) * order to be assured of the final space. If there are no edges for a certain * time we use this timer to emit a final sample to satisfy them. */ -static void img_ir_echo_timer(unsigned long arg) +static void img_ir_echo_timer(struct timer_list *t) { - struct img_ir_priv *priv = (struct img_ir_priv *)arg; + struct img_ir_priv *priv = from_timer(priv, t, raw.timer); spin_lock_irq(&priv->lock); @@ -107,7 +107,7 @@ int img_ir_probe_raw(struct img_ir_priv *priv) int error; /* Set up the echo timer */ - setup_timer(&raw->timer, img_ir_echo_timer, (unsigned long)priv); + timer_setup(&raw->timer, img_ir_echo_timer, 0); /* Allocate raw decoder */ raw->rdev = rdev = rc_allocate_device(RC_DRIVER_IR_RAW); diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 7b3f31cc63d2..b25b35b3f6da 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -346,7 +346,7 @@ static const struct imon_usb_dev_descr imon_ir_raw = { * devices use the SoundGraph vendor ID (0x15c2). This driver only supports * the ffdc and later devices, which do onboard decoding. */ -static struct usb_device_id imon_usb_id_table[] = { +static const struct usb_device_id imon_usb_id_table[] = { /* * Several devices with this same device ID, all use iMON_PAD.inf * SoundGraph iMON PAD (IR & VFD) @@ -602,8 +602,7 @@ static int send_packet(struct imon_context *ictx) ictx->tx_urb->actual_length = 0; } else { /* fill request into kmalloc'ed space: */ - control_req = kmalloc(sizeof(struct usb_ctrlrequest), - GFP_KERNEL); + control_req = kmalloc(sizeof(*control_req), GFP_KERNEL); if (control_req == NULL) return -ENOMEM; @@ -943,7 +942,7 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, int seq; int retval = 0; struct imon_context *ictx; - const unsigned char vfd_packet6[] = { + static const unsigned char vfd_packet6[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; ictx = file->private_data; @@ -1091,9 +1090,9 @@ static void usb_tx_callback(struct urb *urb) /** * report touchscreen input */ -static void imon_touch_display_timeout(unsigned long data) +static void imon_touch_display_timeout(struct timer_list *t) { - struct imon_context *ictx = (struct imon_context *)data; + struct imon_context *ictx = from_timer(ictx, t, ttimer); if (ictx->display_type != IMON_DISPLAY_TYPE_VGA) return; @@ -2047,8 +2046,8 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) { struct rc_dev *rdev; int ret; - const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x88 }; + static const unsigned char fp_packet[] = { + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88 }; rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ? RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE); @@ -2310,11 +2309,10 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, struct usb_host_interface *iface_desc; int ret = -ENOMEM; - ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL); - if (!ictx) { - dev_err(dev, "%s: kzalloc failed for context", __func__); + ictx = kzalloc(sizeof(*ictx), GFP_KERNEL); + if (!ictx) goto exit; - } + rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!rx_urb) goto rx_urb_alloc_failed; @@ -2413,8 +2411,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, mutex_lock(&ictx->lock); if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { - setup_timer(&ictx->ttimer, imon_touch_display_timeout, - (unsigned long)ictx); + timer_setup(&ictx->ttimer, imon_touch_display_timeout, 0); } ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); @@ -2517,6 +2514,11 @@ static int imon_probe(struct usb_interface *interface, mutex_lock(&driver_lock); first_if = usb_ifnum_to_if(usbdev, 0); + if (!first_if) { + ret = -ENODEV; + goto fail; + } + first_if_ctx = usb_get_intfdata(first_if); if (ifnum == 0) { diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index d2223c04e9ad..8f2f37412fc5 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -35,7 +35,7 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) struct lirc_codec *lirc = &dev->raw->lirc; int sample; - if (!dev->raw->lirc.drv || !dev->raw->lirc.drv->rbuf) + if (!dev->raw->lirc.ldev || !dev->raw->lirc.ldev->buf) return -EINVAL; /* Packet start */ @@ -84,8 +84,8 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) (u64)LIRC_VALUE_MASK); gap_sample = LIRC_SPACE(lirc->gap_duration); - lirc_buffer_write(dev->raw->lirc.drv->rbuf, - (unsigned char *) &gap_sample); + lirc_buffer_write(dev->raw->lirc.ldev->buf, + (unsigned char *)&gap_sample); lirc->gap = false; } @@ -95,9 +95,9 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) TO_US(ev.duration), TO_STR(ev.pulse)); } - lirc_buffer_write(dev->raw->lirc.drv->rbuf, + lirc_buffer_write(dev->raw->lirc.ldev->buf, (unsigned char *) &sample); - wake_up(&dev->raw->lirc.drv->rbuf->wait_poll); + wake_up(&dev->raw->lirc.ldev->buf->wait_poll); return 0; } @@ -298,11 +298,14 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, if (!dev->max_timeout) return -ENOTTY; + /* Check for multiply overflow */ + if (val > U32_MAX / 1000) + return -EINVAL; + tmp = val * 1000; - if (tmp < dev->min_timeout || - tmp > dev->max_timeout) - return -EINVAL; + if (tmp < dev->min_timeout || tmp > dev->max_timeout) + return -EINVAL; if (dev->s_timeout) ret = dev->s_timeout(dev, tmp); @@ -343,12 +346,12 @@ static const struct file_operations lirc_fops = { static int ir_lirc_register(struct rc_dev *dev) { - struct lirc_driver *drv; + struct lirc_dev *ldev; int rc = -ENOMEM; unsigned long features = 0; - drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); - if (!drv) + ldev = lirc_allocate_device(); + if (!ldev) return rc; if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { @@ -380,32 +383,29 @@ static int ir_lirc_register(struct rc_dev *dev) if (dev->max_timeout) features |= LIRC_CAN_SET_REC_TIMEOUT; - snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)", + snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)", dev->driver_name); - drv->minor = -1; - drv->features = features; - drv->data = &dev->raw->lirc; - drv->rbuf = NULL; - drv->code_length = sizeof(struct ir_raw_event) * 8; - drv->chunk_size = sizeof(int); - drv->buffer_size = LIRCBUF_SIZE; - drv->fops = &lirc_fops; - drv->dev = &dev->dev; - drv->rdev = dev; - drv->owner = THIS_MODULE; - - drv->minor = lirc_register_driver(drv); - if (drv->minor < 0) { - rc = -ENODEV; + ldev->features = features; + ldev->data = &dev->raw->lirc; + ldev->buf = NULL; + ldev->code_length = sizeof(struct ir_raw_event) * 8; + ldev->chunk_size = sizeof(int); + ldev->buffer_size = LIRCBUF_SIZE; + ldev->fops = &lirc_fops; + ldev->dev.parent = &dev->dev; + ldev->rdev = dev; + ldev->owner = THIS_MODULE; + + rc = lirc_register_device(ldev); + if (rc < 0) goto out; - } - dev->raw->lirc.drv = drv; + dev->raw->lirc.ldev = ldev; dev->raw->lirc.dev = dev; return 0; out: - kfree(drv); + lirc_free_device(ldev); return rc; } @@ -413,9 +413,8 @@ static int ir_lirc_unregister(struct rc_dev *dev) { struct lirc_codec *lirc = &dev->raw->lirc; - lirc_unregister_driver(lirc->drv->minor); - kfree(lirc->drv); - lirc->drv = NULL; + lirc_unregister_device(lirc->ldev); + lirc->ldev = NULL; return 0; } diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index 7c572a643656..69d6264d54e6 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -115,9 +115,9 @@ static unsigned char kbd_keycodes[256] = { KEY_RESERVED }; -static void mce_kbd_rx_timeout(unsigned long data) +static void mce_kbd_rx_timeout(struct timer_list *t) { - struct mce_kbd_dec *mce_kbd = (struct mce_kbd_dec *)data; + struct mce_kbd_dec *mce_kbd = from_timer(mce_kbd, t, rx_timeout); int i; unsigned char maskcode; @@ -389,8 +389,7 @@ static int ir_mce_kbd_register(struct rc_dev *dev) set_bit(EV_MSC, idev->evbit); set_bit(MSC_SCAN, idev->mscbit); - setup_timer(&mce_kbd->rx_timeout, mce_kbd_rx_timeout, - (unsigned long)mce_kbd); + timer_setup(&mce_kbd->rx_timeout, mce_kbd_rx_timeout, 0); input_set_drvdata(idev, mce_kbd); diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 817c18f2ddd1..a95d09acc22a 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -87,8 +87,6 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) data->state = STATE_BIT_PULSE; return 0; } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { - rc_repeat(dev); - IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; } @@ -151,19 +149,26 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) break; - address = bitrev8((data->bits >> 24) & 0xff); - not_address = bitrev8((data->bits >> 16) & 0xff); - command = bitrev8((data->bits >> 8) & 0xff); - not_command = bitrev8((data->bits >> 0) & 0xff); + if (data->count == NEC_NBITS) { + address = bitrev8((data->bits >> 24) & 0xff); + not_address = bitrev8((data->bits >> 16) & 0xff); + command = bitrev8((data->bits >> 8) & 0xff); + not_command = bitrev8((data->bits >> 0) & 0xff); + + scancode = ir_nec_bytes_to_scancode(address, + not_address, + command, + not_command, + &rc_proto); - scancode = ir_nec_bytes_to_scancode(address, not_address, - command, not_command, - &rc_proto); + if (data->is_nec_x) + data->necx_repeat = true; - if (data->is_nec_x) - data->necx_repeat = true; + rc_keydown(dev, rc_proto, scancode, 0); + } else { + rc_repeat(dev); + } - rc_keydown(dev, rc_proto, scancode, 0); data->state = STATE_INACTIVE; return 0; } diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile index 2d0b26bf2051..50b319355edf 100644 --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-alink-dtu-m.o \ rc-anysee.o \ rc-apac-viewcomp.o \ + rc-astrometa-t2hybrid.o \ rc-asus-pc39.o \ rc-asus-ps3-100.o \ rc-ati-tv-wonder-hd-600.o \ @@ -48,6 +49,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-geekbox.o \ rc-genius-tvgo-a11mce.o \ rc-gotview7135.o \ + rc-hisi-poplar.o \ + rc-hisi-tv-demo.o \ rc-imon-mce.o \ rc-imon-pad.o \ rc-iodata-bctv7e.o \ @@ -89,6 +92,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ rc-reddo.o \ rc-snapstream-firefly.o \ rc-streamzap.o \ + rc-tango.o \ rc-tbs-nec.o \ rc-technisat-ts35.o \ rc-technisat-usb2.o \ diff --git a/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c b/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c new file mode 100644 index 000000000000..51690960fec4 --- /dev/null +++ b/drivers/media/rc/keymaps/rc-astrometa-t2hybrid.c @@ -0,0 +1,70 @@ +/* + * Keytable for the Astrometa T2hybrid remote controller + * + * Copyright (C) 2017 Oleh Kravchenko <oleg@kaa.org.ua> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <media/rc-map.h> +#include <linux/module.h> + +static struct rc_map_table t2hybrid[] = { + { 0x4d, KEY_POWER2 }, + { 0x54, KEY_VIDEO }, /* Source */ + { 0x16, KEY_MUTE }, + + { 0x4c, KEY_RECORD }, + { 0x05, KEY_CHANNELUP }, + { 0x0c, KEY_TIME}, /* Timeshift */ + + { 0x0a, KEY_VOLUMEDOWN }, + { 0x40, KEY_ZOOM }, /* Fullscreen */ + { 0x1e, KEY_VOLUMEUP }, + + { 0x12, KEY_0 }, + { 0x02, KEY_CHANNELDOWN }, + { 0x1c, KEY_AGAIN }, /* Recall */ + + { 0x09, KEY_1 }, + { 0x1d, KEY_2 }, + { 0x1f, KEY_3 }, + + { 0x0d, KEY_4 }, + { 0x19, KEY_5 }, + { 0x1b, KEY_6 }, + + { 0x11, KEY_7 }, + { 0x15, KEY_8 }, + { 0x17, KEY_9 }, +}; + +static struct rc_map_list t2hybrid_map = { + .map = { + .scan = t2hybrid, + .size = ARRAY_SIZE(t2hybrid), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_ASTROMETA_T2HYBRID, + } +}; + +static int __init init_rc_map_t2hybrid(void) +{ + return rc_map_register(&t2hybrid_map); +} + +static void __exit exit_rc_map_t2hybrid(void) +{ + rc_map_unregister(&t2hybrid_map); +} + +module_init(init_rc_map_t2hybrid) +module_exit(exit_rc_map_t2hybrid) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>"); diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c index 9882e2cde975..6d5a73b7ccec 100644 --- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c +++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c @@ -43,7 +43,8 @@ static struct rc_map_table avermedia_m135a[] = { { 0x0213, KEY_RIGHT }, /* -> or L */ { 0x0212, KEY_LEFT }, /* <- or R */ - { 0x0217, KEY_SLEEP }, /* Capturar Imagem or Snapshot */ + { 0x0215, KEY_MENU }, + { 0x0217, KEY_CAMERA }, /* Capturar Imagem or Snapshot */ { 0x0210, KEY_SHUFFLE }, /* Amostra or 16 chan prev */ { 0x0303, KEY_CHANNELUP }, diff --git a/drivers/media/rc/keymaps/rc-hisi-poplar.c b/drivers/media/rc/keymaps/rc-hisi-poplar.c new file mode 100644 index 000000000000..78728bc7f63a --- /dev/null +++ b/drivers/media/rc/keymaps/rc-hisi-poplar.c @@ -0,0 +1,69 @@ +/* + * Keytable for remote controller of HiSilicon poplar board. + * + * Copyright (c) 2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/module.h> +#include <media/rc-map.h> + +static struct rc_map_table hisi_poplar_keymap[] = { + { 0x0000b292, KEY_1}, + { 0x0000b293, KEY_2}, + { 0x0000b2cc, KEY_3}, + { 0x0000b28e, KEY_4}, + { 0x0000b28f, KEY_5}, + { 0x0000b2c8, KEY_6}, + { 0x0000b28a, KEY_7}, + { 0x0000b28b, KEY_8}, + { 0x0000b2c4, KEY_9}, + { 0x0000b287, KEY_0}, + { 0x0000b282, KEY_HOMEPAGE}, + { 0x0000b2ca, KEY_UP}, + { 0x0000b299, KEY_LEFT}, + { 0x0000b2c1, KEY_RIGHT}, + { 0x0000b2d2, KEY_DOWN}, + { 0x0000b2c5, KEY_DELETE}, + { 0x0000b29c, KEY_MUTE}, + { 0x0000b281, KEY_VOLUMEDOWN}, + { 0x0000b280, KEY_VOLUMEUP}, + { 0x0000b2dc, KEY_POWER}, + { 0x0000b29a, KEY_MENU}, + { 0x0000b28d, KEY_SETUP}, + { 0x0000b2c5, KEY_BACK}, + { 0x0000b295, KEY_PLAYPAUSE}, + { 0x0000b2ce, KEY_ENTER}, + { 0x0000b285, KEY_CHANNELUP}, + { 0x0000b286, KEY_CHANNELDOWN}, + { 0x0000b2da, KEY_NUMERIC_STAR}, + { 0x0000b2d0, KEY_NUMERIC_POUND}, +}; + +static struct rc_map_list hisi_poplar_map = { + .map = { + .scan = hisi_poplar_keymap, + .size = ARRAY_SIZE(hisi_poplar_keymap), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_HISI_POPLAR, + } +}; + +static int __init init_rc_map_hisi_poplar(void) +{ + return rc_map_register(&hisi_poplar_map); +} + +static void __exit exit_rc_map_hisi_poplar(void) +{ + rc_map_unregister(&hisi_poplar_map); +} + +module_init(init_rc_map_hisi_poplar) +module_exit(exit_rc_map_hisi_poplar) + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/keymaps/rc-hisi-tv-demo.c b/drivers/media/rc/keymaps/rc-hisi-tv-demo.c new file mode 100644 index 000000000000..4816e3a4a18d --- /dev/null +++ b/drivers/media/rc/keymaps/rc-hisi-tv-demo.c @@ -0,0 +1,81 @@ +/* + * Keytable for remote controller of HiSilicon tv demo board. + * + * Copyright (c) 2017 HiSilicon Technologies Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/module.h> +#include <media/rc-map.h> + +static struct rc_map_table hisi_tv_demo_keymap[] = { + { 0x00000092, KEY_1}, + { 0x00000093, KEY_2}, + { 0x000000cc, KEY_3}, + { 0x0000009f, KEY_4}, + { 0x0000008e, KEY_5}, + { 0x0000008f, KEY_6}, + { 0x000000c8, KEY_7}, + { 0x00000094, KEY_8}, + { 0x0000008a, KEY_9}, + { 0x0000008b, KEY_0}, + { 0x000000ce, KEY_ENTER}, + { 0x000000ca, KEY_UP}, + { 0x00000099, KEY_LEFT}, + { 0x00000084, KEY_PAGEUP}, + { 0x000000c1, KEY_RIGHT}, + { 0x000000d2, KEY_DOWN}, + { 0x00000089, KEY_PAGEDOWN}, + { 0x000000d1, KEY_MUTE}, + { 0x00000098, KEY_VOLUMEDOWN}, + { 0x00000090, KEY_VOLUMEUP}, + { 0x0000009c, KEY_POWER}, + { 0x000000d6, KEY_STOP}, + { 0x00000097, KEY_MENU}, + { 0x000000cb, KEY_BACK}, + { 0x000000da, KEY_PLAYPAUSE}, + { 0x00000080, KEY_INFO}, + { 0x000000c3, KEY_REWIND}, + { 0x00000087, KEY_HOMEPAGE}, + { 0x000000d0, KEY_FASTFORWARD}, + { 0x000000c4, KEY_SOUND}, + { 0x00000082, BTN_1}, + { 0x000000c7, BTN_2}, + { 0x00000086, KEY_PROGRAM}, + { 0x000000d9, KEY_SUBTITLE}, + { 0x00000085, KEY_ZOOM}, + { 0x0000009b, KEY_RED}, + { 0x0000009a, KEY_GREEN}, + { 0x000000c0, KEY_YELLOW}, + { 0x000000c2, KEY_BLUE}, + { 0x0000009d, KEY_CHANNELDOWN}, + { 0x000000cf, KEY_CHANNELUP}, +}; + +static struct rc_map_list hisi_tv_demo_map = { + .map = { + .scan = hisi_tv_demo_keymap, + .size = ARRAY_SIZE(hisi_tv_demo_keymap), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_HISI_TV_DEMO, + } +}; + +static int __init init_rc_map_hisi_tv_demo(void) +{ + return rc_map_register(&hisi_tv_demo_map); +} + +static void __exit exit_rc_map_hisi_tv_demo(void) +{ + rc_map_unregister(&hisi_tv_demo_map); +} + +module_init(init_rc_map_hisi_tv_demo) +module_exit(exit_rc_map_hisi_tv_demo) + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/rc/keymaps/rc-tango.c b/drivers/media/rc/keymaps/rc-tango.c new file mode 100644 index 000000000000..1c6e8875d46f --- /dev/null +++ b/drivers/media/rc/keymaps/rc-tango.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 Sigma Designs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <media/rc-map.h> + +static struct rc_map_table tango_table[] = { + { 0x4cb4a, KEY_POWER }, + { 0x4cb48, KEY_FILE }, + { 0x4cb0f, KEY_SETUP }, + { 0x4cb4d, KEY_SUSPEND }, + { 0x4cb4e, KEY_VOLUMEUP }, + { 0x4cb44, KEY_EJECTCD }, + { 0x4cb13, KEY_TV }, + { 0x4cb51, KEY_MUTE }, + { 0x4cb52, KEY_VOLUMEDOWN }, + + { 0x4cb41, KEY_1 }, + { 0x4cb03, KEY_2 }, + { 0x4cb42, KEY_3 }, + { 0x4cb45, KEY_4 }, + { 0x4cb07, KEY_5 }, + { 0x4cb46, KEY_6 }, + { 0x4cb55, KEY_7 }, + { 0x4cb17, KEY_8 }, + { 0x4cb56, KEY_9 }, + { 0x4cb1b, KEY_0 }, + { 0x4cb59, KEY_DELETE }, + { 0x4cb5a, KEY_CAPSLOCK }, + + { 0x4cb47, KEY_BACK }, + { 0x4cb05, KEY_SWITCHVIDEOMODE }, + { 0x4cb06, KEY_UP }, + { 0x4cb43, KEY_LEFT }, + { 0x4cb01, KEY_RIGHT }, + { 0x4cb0a, KEY_DOWN }, + { 0x4cb02, KEY_ENTER }, + { 0x4cb4b, KEY_INFO }, + { 0x4cb09, KEY_HOME }, + + { 0x4cb53, KEY_MENU }, + { 0x4cb12, KEY_PREVIOUS }, + { 0x4cb50, KEY_PLAY }, + { 0x4cb11, KEY_NEXT }, + { 0x4cb4f, KEY_TITLE }, + { 0x4cb0e, KEY_REWIND }, + { 0x4cb4c, KEY_STOP }, + { 0x4cb0d, KEY_FORWARD }, + { 0x4cb57, KEY_MEDIA_REPEAT }, + { 0x4cb16, KEY_ANGLE }, + { 0x4cb54, KEY_PAUSE }, + { 0x4cb15, KEY_SLOW }, + { 0x4cb5b, KEY_TIME }, + { 0x4cb1a, KEY_AUDIO }, + { 0x4cb58, KEY_SUBTITLE }, + { 0x4cb19, KEY_ZOOM }, + + { 0x4cb5f, KEY_RED }, + { 0x4cb1e, KEY_GREEN }, + { 0x4cb5c, KEY_YELLOW }, + { 0x4cb1d, KEY_BLUE }, +}; + +static struct rc_map_list tango_map = { + .map = { + .scan = tango_table, + .size = ARRAY_SIZE(tango_table), + .rc_proto = RC_PROTO_NECX, + .name = RC_MAP_TANGO, + } +}; + +static int __init init_rc_map_tango(void) +{ + return rc_map_register(&tango_map); +} + +static void __exit exit_rc_map_tango(void) +{ + rc_map_unregister(&tango_map); +} + +module_init(init_rc_map_tango) +module_exit(exit_rc_map_tango) + +MODULE_AUTHOR("Sigma Designs"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/rc/keymaps/rc-twinhan1027.c b/drivers/media/rc/keymaps/rc-twinhan1027.c index 2275b37c61d2..78bb3143a1a8 100644 --- a/drivers/media/rc/keymaps/rc-twinhan1027.c +++ b/drivers/media/rc/keymaps/rc-twinhan1027.c @@ -66,7 +66,7 @@ static struct rc_map_list twinhan_vp1027_map = { .map = { .scan = twinhan_vp1027, .size = ARRAY_SIZE(twinhan_vp1027), - .rc_proto = RC_PROTO_UNKNOWN, /* Legacy IR type */ + .rc_proto = RC_PROTO_NEC, .name = RC_MAP_TWINHAN_VP1027_DVBS, } }; diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 9080e39ea391..e16d1138ca48 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -24,96 +24,91 @@ #include <linux/mutex.h> #include <linux/device.h> #include <linux/cdev.h> +#include <linux/idr.h> #include <media/rc-core.h> #include <media/lirc.h> #include <media/lirc_dev.h> -#define NOPLUG -1 #define LOGHEAD "lirc_dev (%s[%d]): " static dev_t lirc_base_dev; -struct irctl { - struct lirc_driver d; - int attached; - int open; +/* Used to keep track of allocated lirc devices */ +#define LIRC_MAX_DEVICES 256 +static DEFINE_IDA(lirc_ida); - struct mutex irctl_lock; - struct lirc_buffer *buf; - bool buf_internal; - unsigned int chunk_size; - - struct device dev; - struct cdev cdev; -}; +/* Only used for sysfs but defined to void otherwise */ +static struct class *lirc_class; -static DEFINE_MUTEX(lirc_dev_lock); +static void lirc_release_device(struct device *ld) +{ + struct lirc_dev *d = container_of(ld, struct lirc_dev, dev); -static struct irctl *irctls[MAX_IRCTL_DEVICES]; + put_device(d->dev.parent); -/* Only used for sysfs but defined to void otherwise */ -static struct class *lirc_class; + if (d->buf_internal) { + lirc_buffer_free(d->buf); + kfree(d->buf); + d->buf = NULL; + } + kfree(d); + module_put(THIS_MODULE); +} -static void lirc_release(struct device *ld) +static int lirc_allocate_buffer(struct lirc_dev *d) { - struct irctl *ir = container_of(ld, struct irctl, dev); + int err; - put_device(ir->dev.parent); + if (d->buf) { + d->buf_internal = false; + return 0; + } - if (ir->buf_internal) { - lirc_buffer_free(ir->buf); - kfree(ir->buf); + d->buf = kmalloc(sizeof(*d->buf), GFP_KERNEL); + if (!d->buf) + return -ENOMEM; + + err = lirc_buffer_init(d->buf, d->chunk_size, d->buffer_size); + if (err) { + kfree(d->buf); + d->buf = NULL; + return err; } - mutex_lock(&lirc_dev_lock); - irctls[ir->d.minor] = NULL; - mutex_unlock(&lirc_dev_lock); - kfree(ir); + d->buf_internal = true; + return 0; } -static int lirc_allocate_buffer(struct irctl *ir) +struct lirc_dev * +lirc_allocate_device(void) { - int err = 0; - int bytes_in_key; - unsigned int chunk_size; - unsigned int buffer_size; - struct lirc_driver *d = &ir->d; - - bytes_in_key = BITS_TO_LONGS(d->code_length) + - (d->code_length % 8 ? 1 : 0); - buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; - chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; - - if (d->rbuf) { - ir->buf = d->rbuf; - ir->buf_internal = false; - } else { - ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) { - err = -ENOMEM; - goto out; - } + struct lirc_dev *d; - err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); - if (err) { - kfree(ir->buf); - ir->buf = NULL; - goto out; - } - - ir->buf_internal = true; - d->rbuf = ir->buf; + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (d) { + mutex_init(&d->mutex); + device_initialize(&d->dev); + d->dev.class = lirc_class; + d->dev.release = lirc_release_device; + __module_get(THIS_MODULE); } - ir->chunk_size = ir->buf->chunk_size; -out: - return err; + return d; } +EXPORT_SYMBOL(lirc_allocate_device); -int lirc_register_driver(struct lirc_driver *d) +void lirc_free_device(struct lirc_dev *d) +{ + if (!d) + return; + + put_device(&d->dev); +} +EXPORT_SYMBOL(lirc_free_device); + +int lirc_register_device(struct lirc_dev *d) { - struct irctl *ir; int minor; int err; @@ -122,8 +117,8 @@ int lirc_register_driver(struct lirc_driver *d) return -EBADRQC; } - if (!d->dev) { - pr_err("dev pointer not filled in!\n"); + if (!d->dev.parent) { + pr_err("dev parent pointer not filled in!\n"); return -EINVAL; } @@ -132,226 +127,146 @@ int lirc_register_driver(struct lirc_driver *d) return -EINVAL; } - if (d->minor >= MAX_IRCTL_DEVICES) { - dev_err(d->dev, "minor must be between 0 and %d!\n", - MAX_IRCTL_DEVICES - 1); - return -EBADRQC; + if (!d->buf && d->chunk_size < 1) { + pr_err("chunk_size must be set!\n"); + return -EINVAL; } - if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { - dev_err(d->dev, "code length must be less than %d bits\n", - BUFLEN * 8); - return -EBADRQC; + if (!d->buf && d->buffer_size < 1) { + pr_err("buffer_size must be set!\n"); + return -EINVAL; } - if (!d->rbuf && !(d->fops && d->fops->read && - d->fops->poll && d->fops->unlocked_ioctl)) { - dev_err(d->dev, "undefined read, poll, ioctl\n"); + if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) { + dev_err(&d->dev, "code length must be less than %d bits\n", + BUFLEN * 8); return -EBADRQC; } - mutex_lock(&lirc_dev_lock); - - minor = d->minor; - - if (minor < 0) { - /* find first free slot for driver */ - for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) - if (!irctls[minor]) - break; - if (minor == MAX_IRCTL_DEVICES) { - dev_err(d->dev, "no free slots for drivers!\n"); - err = -ENOMEM; - goto out_lock; - } - } else if (irctls[minor]) { - dev_err(d->dev, "minor (%d) just registered!\n", minor); - err = -EBUSY; - goto out_lock; - } - - ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); - if (!ir) { - err = -ENOMEM; - goto out_lock; + if (!d->buf && !(d->fops && d->fops->read && + d->fops->poll && d->fops->unlocked_ioctl)) { + dev_err(&d->dev, "undefined read, poll, ioctl\n"); + return -EBADRQC; } - mutex_init(&ir->irctl_lock); - irctls[minor] = ir; - d->minor = minor; - /* some safety check 8-) */ - d->name[sizeof(d->name)-1] = '\0'; + d->name[sizeof(d->name) - 1] = '\0'; if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; - ir->d = *d; - if (LIRC_CAN_REC(d->features)) { - err = lirc_allocate_buffer(irctls[minor]); - if (err) { - kfree(ir); - goto out_lock; - } - d->rbuf = ir->buf; + err = lirc_allocate_buffer(d); + if (err) + return err; } - device_initialize(&ir->dev); - ir->dev.devt = MKDEV(MAJOR(lirc_base_dev), ir->d.minor); - ir->dev.class = lirc_class; - ir->dev.parent = d->dev; - ir->dev.release = lirc_release; - dev_set_name(&ir->dev, "lirc%d", ir->d.minor); + minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL); + if (minor < 0) + return minor; - cdev_init(&ir->cdev, d->fops); - ir->cdev.owner = ir->d.owner; - ir->cdev.kobj.parent = &ir->dev.kobj; - - err = cdev_add(&ir->cdev, ir->dev.devt, 1); - if (err) - goto out_free_dev; - - ir->attached = 1; - - err = device_add(&ir->dev); - if (err) - goto out_cdev; - - mutex_unlock(&lirc_dev_lock); + d->minor = minor; + d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor); + dev_set_name(&d->dev, "lirc%d", d->minor); - get_device(ir->dev.parent); + cdev_init(&d->cdev, d->fops); + d->cdev.owner = d->owner; + d->attached = true; - dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", - ir->d.name, ir->d.minor); + err = cdev_device_add(&d->cdev, &d->dev); + if (err) { + ida_simple_remove(&lirc_ida, minor); + return err; + } - return minor; + get_device(d->dev.parent); -out_cdev: - cdev_del(&ir->cdev); -out_free_dev: - put_device(&ir->dev); -out_lock: - mutex_unlock(&lirc_dev_lock); + dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n", + d->name, d->minor); - return err; + return 0; } -EXPORT_SYMBOL(lirc_register_driver); +EXPORT_SYMBOL(lirc_register_device); -int lirc_unregister_driver(int minor) +void lirc_unregister_device(struct lirc_dev *d) { - struct irctl *ir; + if (!d) + return; - if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { - pr_err("minor (%d) must be between 0 and %d!\n", - minor, MAX_IRCTL_DEVICES - 1); - return -EBADRQC; - } - - ir = irctls[minor]; - if (!ir) { - pr_err("failed to get irctl\n"); - return -ENOENT; - } + dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n", + d->name, d->minor); - mutex_lock(&lirc_dev_lock); + mutex_lock(&d->mutex); - if (ir->d.minor != minor) { - dev_err(ir->d.dev, "lirc_dev: minor %d device not registered\n", - minor); - mutex_unlock(&lirc_dev_lock); - return -ENOENT; + d->attached = false; + if (d->open) { + dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n", + d->name, d->minor); + wake_up_interruptible(&d->buf->wait_poll); } - dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", - ir->d.name, ir->d.minor); - - ir->attached = 0; - if (ir->open) { - dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", - ir->d.name, ir->d.minor); - wake_up_interruptible(&ir->buf->wait_poll); - } + mutex_unlock(&d->mutex); - mutex_unlock(&lirc_dev_lock); - - device_del(&ir->dev); - cdev_del(&ir->cdev); - put_device(&ir->dev); - - return 0; + cdev_device_del(&d->cdev, &d->dev); + ida_simple_remove(&lirc_ida, d->minor); + put_device(&d->dev); } -EXPORT_SYMBOL(lirc_unregister_driver); +EXPORT_SYMBOL(lirc_unregister_device); int lirc_dev_fop_open(struct inode *inode, struct file *file) { - struct irctl *ir; - int retval = 0; - - if (iminor(inode) >= MAX_IRCTL_DEVICES) { - pr_err("open result for %d is -ENODEV\n", iminor(inode)); - return -ENODEV; - } - - if (mutex_lock_interruptible(&lirc_dev_lock)) - return -ERESTARTSYS; - - ir = irctls[iminor(inode)]; - mutex_unlock(&lirc_dev_lock); + struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev); + int retval; - if (!ir) { - retval = -ENODEV; - goto error; - } + dev_dbg(&d->dev, LOGHEAD "open called\n", d->name, d->minor); - dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); + retval = mutex_lock_interruptible(&d->mutex); + if (retval) + return retval; - if (ir->d.minor == NOPLUG) { + if (!d->attached) { retval = -ENODEV; - goto error; + goto out; } - if (ir->open) { + if (d->open) { retval = -EBUSY; - goto error; + goto out; } - if (ir->d.rdev) { - retval = rc_open(ir->d.rdev); + if (d->rdev) { + retval = rc_open(d->rdev); if (retval) - goto error; + goto out; } - if (ir->buf) - lirc_buffer_clear(ir->buf); + if (d->buf) + lirc_buffer_clear(d->buf); - ir->open++; + d->open++; -error: + lirc_init_pdata(inode, file); nonseekable_open(inode, file); + mutex_unlock(&d->mutex); + + return 0; +out: + mutex_unlock(&d->mutex); return retval; } EXPORT_SYMBOL(lirc_dev_fop_open); int lirc_dev_fop_close(struct inode *inode, struct file *file) { - struct irctl *ir = irctls[iminor(inode)]; - int ret; - - if (!ir) { - pr_err("called with invalid irctl\n"); - return -EINVAL; - } + struct lirc_dev *d = file->private_data; - ret = mutex_lock_killable(&lirc_dev_lock); - WARN_ON(ret); + mutex_lock(&d->mutex); - rc_close(ir->d.rdev); + rc_close(d->rdev); + d->open--; - ir->open--; - if (!ret) - mutex_unlock(&lirc_dev_lock); + mutex_unlock(&d->mutex); return 0; } @@ -359,29 +274,24 @@ EXPORT_SYMBOL(lirc_dev_fop_close); unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) { - struct irctl *ir = irctls[iminor(file_inode(file))]; + struct lirc_dev *d = file->private_data; unsigned int ret; - if (!ir) { - pr_err("called with invalid irctl\n"); - return POLLERR; - } - - if (!ir->attached) + if (!d->attached) return POLLHUP | POLLERR; - if (ir->buf) { - poll_wait(file, &ir->buf->wait_poll, wait); + if (d->buf) { + poll_wait(file, &d->buf->wait_poll, wait); - if (lirc_buffer_empty(ir->buf)) + if (lirc_buffer_empty(d->buf)) ret = 0; else ret = POLLIN | POLLRDNORM; - } else + } else { ret = POLLERR; + } - dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n", - ir->d.name, ir->d.minor, ret); + dev_dbg(&d->dev, LOGHEAD "poll result = %d\n", d->name, d->minor, ret); return ret; } @@ -389,48 +299,44 @@ EXPORT_SYMBOL(lirc_dev_fop_poll); long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + struct lirc_dev *d = file->private_data; __u32 mode; - int result = 0; - struct irctl *ir = irctls[iminor(file_inode(file))]; + int result; - if (!ir) { - pr_err("no irctl found!\n"); - return -ENODEV; - } + dev_dbg(&d->dev, LOGHEAD "ioctl called (0x%x)\n", + d->name, d->minor, cmd); - dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", - ir->d.name, ir->d.minor, cmd); + result = mutex_lock_interruptible(&d->mutex); + if (result) + return result; - if (ir->d.minor == NOPLUG || !ir->attached) { - dev_err(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n", - ir->d.name, ir->d.minor); - return -ENODEV; + if (!d->attached) { + result = -ENODEV; + goto out; } - mutex_lock(&ir->irctl_lock); - switch (cmd) { case LIRC_GET_FEATURES: - result = put_user(ir->d.features, (__u32 __user *)arg); + result = put_user(d->features, (__u32 __user *)arg); break; case LIRC_GET_REC_MODE: - if (!LIRC_CAN_REC(ir->d.features)) { + if (!LIRC_CAN_REC(d->features)) { result = -ENOTTY; break; } result = put_user(LIRC_REC2MODE - (ir->d.features & LIRC_CAN_REC_MASK), + (d->features & LIRC_CAN_REC_MASK), (__u32 __user *)arg); break; case LIRC_SET_REC_MODE: - if (!LIRC_CAN_REC(ir->d.features)) { + if (!LIRC_CAN_REC(d->features)) { result = -ENOTTY; break; } result = get_user(mode, (__u32 __user *)arg); - if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) + if (!result && !(LIRC_MODE2REC(mode) & d->features)) result = -EINVAL; /* * FIXME: We should actually set the mode somehow but @@ -438,32 +344,14 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg) */ break; case LIRC_GET_LENGTH: - result = put_user(ir->d.code_length, (__u32 __user *)arg); - break; - case LIRC_GET_MIN_TIMEOUT: - if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || - ir->d.min_timeout == 0) { - result = -ENOTTY; - break; - } - - result = put_user(ir->d.min_timeout, (__u32 __user *)arg); - break; - case LIRC_GET_MAX_TIMEOUT: - if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || - ir->d.max_timeout == 0) { - result = -ENOTTY; - break; - } - - result = put_user(ir->d.max_timeout, (__u32 __user *)arg); + result = put_user(d->code_length, (__u32 __user *)arg); break; default: result = -ENOTTY; } - mutex_unlock(&ir->irctl_lock); - +out: + mutex_unlock(&d->mutex); return result; } EXPORT_SYMBOL(lirc_dev_fop_ioctl); @@ -473,35 +361,34 @@ ssize_t lirc_dev_fop_read(struct file *file, size_t length, loff_t *ppos) { - struct irctl *ir = irctls[iminor(file_inode(file))]; + struct lirc_dev *d = file->private_data; unsigned char *buf; - int ret = 0, written = 0; + int ret, written = 0; DECLARE_WAITQUEUE(wait, current); - if (!ir) { - pr_err("called with invalid irctl\n"); - return -ENODEV; - } - - if (!LIRC_CAN_REC(ir->d.features)) - return -EINVAL; - - dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); - - buf = kzalloc(ir->chunk_size, GFP_KERNEL); + buf = kzalloc(d->buf->chunk_size, GFP_KERNEL); if (!buf) return -ENOMEM; - if (mutex_lock_interruptible(&ir->irctl_lock)) { - ret = -ERESTARTSYS; - goto out_unlocked; + dev_dbg(&d->dev, LOGHEAD "read called\n", d->name, d->minor); + + ret = mutex_lock_interruptible(&d->mutex); + if (ret) { + kfree(buf); + return ret; } - if (!ir->attached) { + + if (!d->attached) { ret = -ENODEV; goto out_locked; } - if (length % ir->chunk_size) { + if (!LIRC_CAN_REC(d->features)) { + ret = -EINVAL; + goto out_locked; + } + + if (length % d->buf->chunk_size) { ret = -EINVAL; goto out_locked; } @@ -511,14 +398,14 @@ ssize_t lirc_dev_fop_read(struct file *file, * to avoid losing scan code (in case when queue is awaken somewhere * between while condition checking and scheduling) */ - add_wait_queue(&ir->buf->wait_poll, &wait); + add_wait_queue(&d->buf->wait_poll, &wait); /* * while we didn't provide 'length' bytes, device is opened in blocking * mode and 'copy_to_user' is happy, wait for data. */ while (written < length && ret == 0) { - if (lirc_buffer_empty(ir->buf)) { + if (lirc_buffer_empty(d->buf)) { /* According to the read(2) man page, 'written' can be * returned as less than 'length', instead of blocking * again, returning -EWOULDBLOCK, or returning @@ -535,36 +422,36 @@ ssize_t lirc_dev_fop_read(struct file *file, break; } - mutex_unlock(&ir->irctl_lock); + mutex_unlock(&d->mutex); set_current_state(TASK_INTERRUPTIBLE); schedule(); set_current_state(TASK_RUNNING); - if (mutex_lock_interruptible(&ir->irctl_lock)) { - ret = -ERESTARTSYS; - remove_wait_queue(&ir->buf->wait_poll, &wait); + ret = mutex_lock_interruptible(&d->mutex); + if (ret) { + remove_wait_queue(&d->buf->wait_poll, &wait); goto out_unlocked; } - if (!ir->attached) { + if (!d->attached) { ret = -ENODEV; goto out_locked; } } else { - lirc_buffer_read(ir->buf, buf); + lirc_buffer_read(d->buf, buf); ret = copy_to_user((void __user *)buffer+written, buf, - ir->buf->chunk_size); + d->buf->chunk_size); if (!ret) - written += ir->buf->chunk_size; + written += d->buf->chunk_size; else ret = -EFAULT; } } - remove_wait_queue(&ir->buf->wait_poll, &wait); + remove_wait_queue(&d->buf->wait_poll, &wait); out_locked: - mutex_unlock(&ir->irctl_lock); + mutex_unlock(&d->mutex); out_unlocked: kfree(buf); @@ -573,9 +460,19 @@ out_unlocked: } EXPORT_SYMBOL(lirc_dev_fop_read); +void lirc_init_pdata(struct inode *inode, struct file *file) +{ + struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev); + + file->private_data = d; +} +EXPORT_SYMBOL(lirc_init_pdata); + void *lirc_get_pdata(struct file *file) { - return irctls[iminor(file_inode(file))]->d.data; + struct lirc_dev *d = file->private_data; + + return d->data; } EXPORT_SYMBOL(lirc_get_pdata); @@ -590,7 +487,7 @@ static int __init lirc_dev_init(void) return PTR_ERR(lirc_class); } - retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, + retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES, "BaseRemoteCtl"); if (retval) { class_destroy(lirc_class); @@ -607,7 +504,7 @@ static int __init lirc_dev_init(void) static void __exit lirc_dev_exit(void) { class_destroy(lirc_class); - unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); + unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES); pr_info("module unloaded\n"); } diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index bf7aaff3aa37..a9187b0b46a1 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -188,6 +188,8 @@ enum mceusb_model_type { TIVO_KIT, MCE_GEN2_NO_TX, HAUPPAUGE_CX_HYBRID_TV, + EVROMEDIA_FULL_HYBRID_FULLHD, + ASTROMETA_T2HYBRID, }; struct mceusb_model { @@ -247,9 +249,19 @@ static const struct mceusb_model mceusb_model[] = { .mce_gen2 = 1, .rc_map = RC_MAP_TIVO, }, + [EVROMEDIA_FULL_HYBRID_FULLHD] = { + .name = "Evromedia USB Full Hybrid Full HD", + .no_tx = 1, + .rc_map = RC_MAP_MSI_DIGIVOX_III, + }, + [ASTROMETA_T2HYBRID] = { + .name = "Astrometa T2Hybrid", + .no_tx = 1, + .rc_map = RC_MAP_ASTROMETA_T2HYBRID, + } }; -static struct usb_device_id mceusb_dev_table[] = { +static const struct usb_device_id mceusb_dev_table[] = { /* Original Microsoft MCE IR Transceiver (often HP-branded) */ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d), .driver_info = MCE_GEN1 }, @@ -398,6 +410,12 @@ static struct usb_device_id mceusb_dev_table[] = { .driver_info = HAUPPAUGE_CX_HYBRID_TV }, /* Adaptec / HP eHome Receiver */ { USB_DEVICE(VENDOR_ADAPTEC, 0x0094) }, + /* Evromedia USB Full Hybrid Full HD */ + { USB_DEVICE(0x1b80, 0xd3b2), + .driver_info = EVROMEDIA_FULL_HYBRID_FULLHD }, + /* Astrometa T2hybrid */ + { USB_DEVICE(0x15f4, 0x0135), + .driver_info = ASTROMETA_T2HYBRID }, /* Terminating entry */ { } diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 7da9c96cb058..ae4dd0c27731 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -106,7 +106,7 @@ struct ir_raw_event_ctrl { } mce_kbd; struct lirc_codec { struct rc_dev *dev; - struct lirc_driver *drv; + struct lirc_dev *ldev; int carrier_low; ktime_t gap_start; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 503bc425a187..f6e5ba4fbb49 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -471,9 +471,10 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode, } EXPORT_SYMBOL(ir_raw_encode_scancode); -static void edge_handle(unsigned long arg) +static void edge_handle(struct timer_list *t) { - struct rc_dev *dev = (struct rc_dev *)arg; + struct ir_raw_event_ctrl *raw = from_timer(raw, t, edge_handle); + struct rc_dev *dev = raw->dev; ktime_t interval = ktime_sub(ktime_get(), dev->raw->last_event); if (ktime_to_ns(interval) >= dev->timeout) { @@ -513,8 +514,7 @@ int ir_raw_event_prepare(struct rc_dev *dev) dev->raw->dev = dev; dev->change_protocol = change_protocol; - setup_timer(&dev->raw->edge_handle, edge_handle, - (unsigned long)dev); + timer_setup(&dev->raw->edge_handle, edge_handle, 0); INIT_KFIFO(dev->raw->kfifo); return 0; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 981cccd6b988..17950e29d4e3 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -15,6 +15,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <media/rc-core.h> +#include <linux/bsearch.h> #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/input.h> @@ -439,9 +440,6 @@ static int ir_setkeytable(struct rc_dev *dev, if (rc) return rc; - IR_dprintk(1, "Allocated space for %u keycode entries (%u bytes)\n", - rc_map->size, rc_map->alloc); - for (i = 0; i < from->size; i++) { index = ir_establish_scancode(dev, rc_map, from->scan[i].scancode, false); @@ -460,6 +458,18 @@ static int ir_setkeytable(struct rc_dev *dev, return rc; } +static int rc_map_cmp(const void *key, const void *elt) +{ + const unsigned int *scancode = key; + const struct rc_map_table *e = elt; + + if (*scancode < e->scancode) + return -1; + else if (*scancode > e->scancode) + return 1; + return 0; +} + /** * ir_lookup_by_scancode() - locate mapping by scancode * @rc_map: the struct rc_map to search @@ -472,21 +482,14 @@ static int ir_setkeytable(struct rc_dev *dev, static unsigned int ir_lookup_by_scancode(const struct rc_map *rc_map, unsigned int scancode) { - int start = 0; - int end = rc_map->len - 1; - int mid; - - while (start <= end) { - mid = (start + end) / 2; - if (rc_map->scan[mid].scancode < scancode) - start = mid + 1; - else if (rc_map->scan[mid].scancode > scancode) - end = mid - 1; - else - return mid; - } + struct rc_map_table *res; - return -1U; + res = bsearch(&scancode, rc_map->scan, rc_map->len, + sizeof(struct rc_map_table), rc_map_cmp); + if (!res) + return -1U; + else + return res - rc_map->scan; } /** @@ -627,9 +630,9 @@ EXPORT_SYMBOL_GPL(rc_keyup); * This routine will generate a keyup event some time after a keydown event * is generated when no further activity has been detected. */ -static void ir_timer_keyup(unsigned long cookie) +static void ir_timer_keyup(struct timer_list *t) { - struct rc_dev *dev = (struct rc_dev *)cookie; + struct rc_dev *dev = from_timer(dev, t, timer_keyup); unsigned long flags; /* @@ -1480,6 +1483,8 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name); if (dev->driver_name) ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); + if (dev->device_name) + ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name); return 0; } @@ -1487,7 +1492,10 @@ static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) /* * Static device attribute struct with the sysfs attributes for IR's */ -static DEVICE_ATTR(protocols, 0644, show_protocols, store_protocols); +static struct device_attribute dev_attr_ro_protocols = +__ATTR(protocols, 0444, show_protocols, NULL); +static struct device_attribute dev_attr_rw_protocols = +__ATTR(protocols, 0644, show_protocols, store_protocols); static DEVICE_ATTR(wakeup_protocols, 0644, show_wakeup_protocols, store_wakeup_protocols); static RC_FILTER_ATTR(filter, S_IRUGO|S_IWUSR, @@ -1499,13 +1507,22 @@ static RC_FILTER_ATTR(wakeup_filter, S_IRUGO|S_IWUSR, static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, show_filter, store_filter, RC_FILTER_WAKEUP, true); -static struct attribute *rc_dev_protocol_attrs[] = { - &dev_attr_protocols.attr, +static struct attribute *rc_dev_rw_protocol_attrs[] = { + &dev_attr_rw_protocols.attr, + NULL, +}; + +static const struct attribute_group rc_dev_rw_protocol_attr_grp = { + .attrs = rc_dev_rw_protocol_attrs, +}; + +static struct attribute *rc_dev_ro_protocol_attrs[] = { + &dev_attr_ro_protocols.attr, NULL, }; -static const struct attribute_group rc_dev_protocol_attr_grp = { - .attrs = rc_dev_protocol_attrs, +static const struct attribute_group rc_dev_ro_protocol_attr_grp = { + .attrs = rc_dev_ro_protocol_attrs, }; static struct attribute *rc_dev_filter_attrs[] = { @@ -1529,7 +1546,7 @@ static const struct attribute_group rc_dev_wakeup_filter_attr_grp = { .attrs = rc_dev_wakeup_filter_attrs, }; -static struct device_type rc_dev_type = { +static const struct device_type rc_dev_type = { .release = rc_dev_release, .uevent = rc_dev_uevent, }; @@ -1553,8 +1570,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) dev->input_dev->setkeycode = ir_setkeycode; input_set_drvdata(dev->input_dev, dev); - setup_timer(&dev->timer_keyup, ir_timer_keyup, - (unsigned long)dev); + timer_setup(&dev->timer_keyup, ir_timer_keyup, 0); spin_lock_init(&dev->rc_map.lock); spin_lock_init(&dev->keylock); @@ -1638,6 +1654,9 @@ static int rc_prepare_rx_device(struct rc_dev *dev) rc_proto = BIT_ULL(rc_map->rc_proto); + if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol) + dev->enabled_protocols = dev->allowed_protocols; + if (dev->change_protocol) { rc = dev->change_protocol(dev, &rc_proto); if (rc < 0) @@ -1729,8 +1748,10 @@ int rc_register_device(struct rc_dev *dev) dev_set_drvdata(&dev->dev, dev); dev->dev.groups = dev->sysfs_groups; - if (dev->driver_type != RC_DRIVER_IR_RAW_TX) - dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; + if (dev->driver_type == RC_DRIVER_SCANCODE && !dev->change_protocol) + dev->sysfs_groups[attr++] = &rc_dev_ro_protocol_attr_grp; + else if (dev->driver_type != RC_DRIVER_IR_RAW_TX) + dev->sysfs_groups[attr++] = &rc_dev_rw_protocol_attr_grp; if (dev->s_filter) dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; if (dev->s_wakeup_filter) diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index 6784cb9fc4e7..6bfc24885b5c 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -186,7 +186,7 @@ struct redrat3_error { } __packed; /* table of devices that work with this driver */ -static struct usb_device_id redrat3_dev_table[] = { +static const struct usb_device_id redrat3_dev_table[] = { /* Original version of the RedRat3 */ {USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3USB_PRODUCT_ID)}, /* Second Version/release of the RedRat3 - RetRat3-II */ diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 8b66926bc16a..8bf5637b3a69 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -470,7 +470,7 @@ static int hardware_init_port(void) return 0; } -static void serial_ir_timeout(unsigned long arg) +static void serial_ir_timeout(struct timer_list *unused) { DEFINE_IR_RAW_EVENT(ev); @@ -540,8 +540,7 @@ static int serial_ir_probe(struct platform_device *dev) serial_ir.rcdev = rcdev; - setup_timer(&serial_ir.timeout_timer, serial_ir_timeout, - (unsigned long)&serial_ir); + timer_setup(&serial_ir.timeout_timer, serial_ir_timeout, 0); result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, share_irq ? IRQF_SHARED : 0, diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index bc906fb128d5..76120664b700 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -120,7 +120,7 @@ static void add_read_queue(int flag, unsigned long val) } /* SECTION: Hardware */ -static void sir_timeout(unsigned long data) +static void sir_timeout(struct timer_list *unused) { /* * if last received signal was a pulse, but receiving stopped @@ -321,7 +321,7 @@ static int sir_ir_probe(struct platform_device *dev) rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->dev.parent = &sir_ir_dev->dev; - setup_timer(&timerlist, sir_timeout, 0); + timer_setup(&timerlist, sir_timeout, 0); /* get I/O port access and IRQ line */ if (!devm_request_region(&sir_ir_dev->dev, io, 8, KBUILD_MODNAME)) { diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index f03a174ddf9d..4eebfcfc10f3 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -43,7 +43,7 @@ #define USB_STREAMZAP_PRODUCT_ID 0x0000 /* table of devices that work with this driver */ -static struct usb_device_id streamzap_table[] = { +static const struct usb_device_id streamzap_table[] = { /* Streamzap Remote Control */ { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, /* Terminating entry */ diff --git a/drivers/media/rc/tango-ir.c b/drivers/media/rc/tango-ir.c new file mode 100644 index 000000000000..9d4c17230c3a --- /dev/null +++ b/drivers/media/rc/tango-ir.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2015 Mans Rullgard <mans@mansr.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/input.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <media/rc-core.h> + +#define DRIVER_NAME "tango-ir" + +#define IR_NEC_CTRL 0x00 +#define IR_NEC_DATA 0x04 +#define IR_CTRL 0x08 +#define IR_RC5_CLK_DIV 0x0c +#define IR_RC5_DATA 0x10 +#define IR_INT 0x14 + +#define NEC_TIME_BASE 560 +#define RC5_TIME_BASE 1778 + +#define RC6_CTRL 0x00 +#define RC6_CLKDIV 0x04 +#define RC6_DATA0 0x08 +#define RC6_DATA1 0x0c +#define RC6_DATA2 0x10 +#define RC6_DATA3 0x14 +#define RC6_DATA4 0x18 + +#define RC6_CARRIER 36000 +#define RC6_TIME_BASE 16 + +#define NEC_CAP(n) ((n) << 24) +#define GPIO_SEL(n) ((n) << 16) +#define DISABLE_NEC (BIT(4) | BIT(8)) +#define ENABLE_RC5 (BIT(0) | BIT(9)) +#define ENABLE_RC6 (BIT(0) | BIT(7)) +#define ACK_IR_INT (BIT(0) | BIT(1)) +#define ACK_RC6_INT (BIT(31)) + +#define NEC_ANY (RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32) + +struct tango_ir { + void __iomem *rc5_base; + void __iomem *rc6_base; + struct rc_dev *rc; + struct clk *clk; +}; + +static void tango_ir_handle_nec(struct tango_ir *ir) +{ + u32 v, code; + enum rc_proto proto; + + v = readl_relaxed(ir->rc5_base + IR_NEC_DATA); + if (!v) { + rc_repeat(ir->rc); + return; + } + + code = ir_nec_bytes_to_scancode(v, v >> 8, v >> 16, v >> 24, &proto); + rc_keydown(ir->rc, proto, code, 0); +} + +static void tango_ir_handle_rc5(struct tango_ir *ir) +{ + u32 data, field, toggle, addr, cmd, code; + + data = readl_relaxed(ir->rc5_base + IR_RC5_DATA); + if (data & BIT(31)) + return; + + field = data >> 12 & 1; + toggle = data >> 11 & 1; + addr = data >> 6 & 0x1f; + cmd = (data & 0x3f) | (field ^ 1) << 6; + + code = RC_SCANCODE_RC5(addr, cmd); + rc_keydown(ir->rc, RC_PROTO_RC5, code, toggle); +} + +static void tango_ir_handle_rc6(struct tango_ir *ir) +{ + u32 data0, data1, toggle, mode, addr, cmd, code; + + data0 = readl_relaxed(ir->rc6_base + RC6_DATA0); + data1 = readl_relaxed(ir->rc6_base + RC6_DATA1); + + mode = data0 >> 1 & 7; + if (mode != 0) + return; + + toggle = data0 & 1; + addr = data0 >> 16; + cmd = data1; + + code = RC_SCANCODE_RC6_0(addr, cmd); + rc_keydown(ir->rc, RC_PROTO_RC6_0, code, toggle); +} + +static irqreturn_t tango_ir_irq(int irq, void *dev_id) +{ + struct tango_ir *ir = dev_id; + unsigned int rc5_stat; + unsigned int rc6_stat; + + rc5_stat = readl_relaxed(ir->rc5_base + IR_INT); + writel_relaxed(rc5_stat, ir->rc5_base + IR_INT); + + rc6_stat = readl_relaxed(ir->rc6_base + RC6_CTRL); + writel_relaxed(rc6_stat, ir->rc6_base + RC6_CTRL); + + if (!(rc5_stat & 3) && !(rc6_stat & BIT(31))) + return IRQ_NONE; + + if (rc5_stat & BIT(0)) + tango_ir_handle_rc5(ir); + + if (rc5_stat & BIT(1)) + tango_ir_handle_nec(ir); + + if (rc6_stat & BIT(31)) + tango_ir_handle_rc6(ir); + + return IRQ_HANDLED; +} + +static int tango_change_protocol(struct rc_dev *dev, u64 *rc_type) +{ + struct tango_ir *ir = dev->priv; + u32 rc5_ctrl = DISABLE_NEC; + u32 rc6_ctrl = 0; + + if (*rc_type & NEC_ANY) + rc5_ctrl = 0; + + if (*rc_type & RC_PROTO_BIT_RC5) + rc5_ctrl |= ENABLE_RC5; + + if (*rc_type & RC_PROTO_BIT_RC6_0) + rc6_ctrl = ENABLE_RC6; + + writel_relaxed(rc5_ctrl, ir->rc5_base + IR_CTRL); + writel_relaxed(rc6_ctrl, ir->rc6_base + RC6_CTRL); + + return 0; +} + +static int tango_ir_probe(struct platform_device *pdev) +{ + const char *map_name = RC_MAP_TANGO; + struct device *dev = &pdev->dev; + struct rc_dev *rc; + struct tango_ir *ir; + struct resource *rc5_res; + struct resource *rc6_res; + u64 clkrate, clkdiv; + int irq, err; + u32 val; + + rc5_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!rc5_res) + return -EINVAL; + + rc6_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!rc6_res) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) + return -EINVAL; + + ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL); + if (!ir) + return -ENOMEM; + + ir->rc5_base = devm_ioremap_resource(dev, rc5_res); + if (IS_ERR(ir->rc5_base)) + return PTR_ERR(ir->rc5_base); + + ir->rc6_base = devm_ioremap_resource(dev, rc6_res); + if (IS_ERR(ir->rc6_base)) + return PTR_ERR(ir->rc6_base); + + ir->clk = devm_clk_get(dev, NULL); + if (IS_ERR(ir->clk)) + return PTR_ERR(ir->clk); + + rc = devm_rc_allocate_device(dev, RC_DRIVER_SCANCODE); + if (!rc) + return -ENOMEM; + + of_property_read_string(dev->of_node, "linux,rc-map-name", &map_name); + + rc->device_name = DRIVER_NAME; + rc->driver_name = DRIVER_NAME; + rc->input_phys = DRIVER_NAME "/input0"; + rc->map_name = map_name; + rc->allowed_protocols = NEC_ANY | RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_0; + rc->change_protocol = tango_change_protocol; + rc->priv = ir; + ir->rc = rc; + + err = clk_prepare_enable(ir->clk); + if (err) + return err; + + clkrate = clk_get_rate(ir->clk); + + clkdiv = clkrate * NEC_TIME_BASE; + do_div(clkdiv, 1000000); + + val = NEC_CAP(31) | GPIO_SEL(12) | clkdiv; + writel_relaxed(val, ir->rc5_base + IR_NEC_CTRL); + + clkdiv = clkrate * RC5_TIME_BASE; + do_div(clkdiv, 1000000); + + writel_relaxed(DISABLE_NEC, ir->rc5_base + IR_CTRL); + writel_relaxed(clkdiv, ir->rc5_base + IR_RC5_CLK_DIV); + writel_relaxed(ACK_IR_INT, ir->rc5_base + IR_INT); + + clkdiv = clkrate * RC6_TIME_BASE; + do_div(clkdiv, RC6_CARRIER); + + writel_relaxed(ACK_RC6_INT, ir->rc6_base + RC6_CTRL); + writel_relaxed((clkdiv >> 2) << 18 | clkdiv, ir->rc6_base + RC6_CLKDIV); + + err = devm_request_irq(dev, irq, tango_ir_irq, IRQF_SHARED, + dev_name(dev), ir); + if (err) + goto err_clk; + + err = devm_rc_register_device(dev, rc); + if (err) + goto err_clk; + + platform_set_drvdata(pdev, ir); + return 0; + +err_clk: + clk_disable_unprepare(ir->clk); + return err; +} + +static int tango_ir_remove(struct platform_device *pdev) +{ + struct tango_ir *ir = platform_get_drvdata(pdev); + + clk_disable_unprepare(ir->clk); + return 0; +} + +static const struct of_device_id tango_ir_dt_ids[] = { + { .compatible = "sigma,smp8642-ir" }, + { } +}; +MODULE_DEVICE_TABLE(of, tango_ir_dt_ids); + +static struct platform_driver tango_ir_driver = { + .probe = tango_ir_probe, + .remove = tango_ir_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = tango_ir_dt_ids, + }, +}; +module_platform_driver(tango_ir_driver); + +MODULE_DESCRIPTION("SMP86xx IR decoder driver"); +MODULE_AUTHOR("Mans Rullgard <mans@mansr.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/usb/as102/as102_fw.c b/drivers/media/usb/as102/as102_fw.c index 5a28ce3a1d49..38dbc128340d 100644 --- a/drivers/media/usb/as102/as102_fw.c +++ b/drivers/media/usb/as102/as102_fw.c @@ -101,18 +101,23 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, unsigned char *cmd, const struct firmware *firmware) { - struct as10x_fw_pkt_t fw_pkt; + struct as10x_fw_pkt_t *fw_pkt; int total_read_bytes = 0, errno = 0; unsigned char addr_has_changed = 0; + fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL); + if (!fw_pkt) + return -ENOMEM; + + for (total_read_bytes = 0; total_read_bytes < firmware->size; ) { int read_bytes = 0, data_len = 0; /* parse intel hex line */ read_bytes = parse_hex_line( (u8 *) (firmware->data + total_read_bytes), - fw_pkt.raw.address, - fw_pkt.raw.data, + fw_pkt->raw.address, + fw_pkt->raw.data, &data_len, &addr_has_changed); @@ -122,28 +127,28 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, /* detect the end of file */ total_read_bytes += read_bytes; if (total_read_bytes == firmware->size) { - fw_pkt.u.request[0] = 0x00; - fw_pkt.u.request[1] = 0x03; + fw_pkt->u.request[0] = 0x00; + fw_pkt->u.request[1] = 0x03; /* send EOF command */ errno = bus_adap->ops->upload_fw_pkt(bus_adap, (uint8_t *) - &fw_pkt, 2, 0); + fw_pkt, 2, 0); if (errno < 0) goto error; } else { if (!addr_has_changed) { /* prepare command to send */ - fw_pkt.u.request[0] = 0x00; - fw_pkt.u.request[1] = 0x01; + fw_pkt->u.request[0] = 0x00; + fw_pkt->u.request[1] = 0x01; - data_len += sizeof(fw_pkt.u.request); - data_len += sizeof(fw_pkt.raw.address); + data_len += sizeof(fw_pkt->u.request); + data_len += sizeof(fw_pkt->raw.address); /* send cmd to device */ errno = bus_adap->ops->upload_fw_pkt(bus_adap, (uint8_t *) - &fw_pkt, + fw_pkt, data_len, 0); if (errno < 0) @@ -152,6 +157,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, } } error: + kfree(fw_pkt); return (errno == 0) ? total_read_bytes : errno; } diff --git a/drivers/media/usb/au0828/au0828-i2c.c b/drivers/media/usb/au0828/au0828-i2c.c index ef7d1b830ca3..1b8ec5d9e7ab 100644 --- a/drivers/media/usb/au0828/au0828-i2c.c +++ b/drivers/media/usb/au0828/au0828-i2c.c @@ -342,7 +342,7 @@ static const struct i2c_adapter au0828_i2c_adap_template = { .algo = &au0828_i2c_algo_template, }; -static struct i2c_client au0828_i2c_client_template = { +static const struct i2c_client au0828_i2c_client_template = { .name = "au0828 internal", }; diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 7996eb83a54e..af68afe085b5 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -269,7 +269,7 @@ static void au0828_rc_stop(struct rc_dev *rc) static int au0828_probe_i2c_ir(struct au0828_dev *dev) { int i = 0; - const unsigned short addr_list[] = { + static const unsigned short addr_list[] = { 0x47, I2C_CLIENT_END }; diff --git a/drivers/media/usb/au0828/au0828-vbi.c b/drivers/media/usb/au0828/au0828-vbi.c index e0930ce59b8d..9dd6bdb7304f 100644 --- a/drivers/media/usb/au0828/au0828-vbi.c +++ b/drivers/media/usb/au0828/au0828-vbi.c @@ -79,7 +79,7 @@ vbi_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&dev->slock, flags); } -struct vb2_ops au0828_vbi_qops = { +const struct vb2_ops au0828_vbi_qops = { .queue_setup = vbi_queue_setup, .buf_prepare = vbi_buffer_prepare, .buf_queue = vbi_buffer_queue, diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 9342402b92f7..654f67c25863 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -67,10 +67,10 @@ static inline void print_err_status(struct au0828_dev *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 05e445fe0b77..f6f37e8ef51d 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -358,7 +358,7 @@ void au0828_dvb_suspend(struct au0828_dev *dev); void au0828_dvb_resume(struct au0828_dev *dev); /* au0828-vbi.c */ -extern struct vb2_ops au0828_vbi_qops; +extern const struct vb2_ops au0828_vbi_qops; #define dprintk(level, fmt, arg...)\ do { if (au0828_debug & level)\ diff --git a/drivers/media/usb/b2c2/Kconfig b/drivers/media/usb/b2c2/Kconfig index 17d35833980c..a620ae42dfc8 100644 --- a/drivers/media/usb/b2c2/Kconfig +++ b/drivers/media/usb/b2c2/Kconfig @@ -10,6 +10,6 @@ config DVB_B2C2_FLEXCOP_USB_DEBUG bool "Enable debug for the B2C2 FlexCop drivers" depends on DVB_B2C2_FLEXCOP_USB select DVB_B2C2_FLEXCOP_DEBUG - help - Say Y if you want to enable the module option to control debug messages - of all B2C2 FlexCop drivers. + help + Say Y if you want to enable the module option to control debug messages + of all B2C2 FlexCop drivers. diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index e0daa9b6c2a0..54d9d0cb326f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -847,7 +847,7 @@ struct cx231xx_board cx231xx_boards[] = { .demod_addr = 0x64, /* 0xc8 >> 1 */ .demod_i2c_master = I2C_1_MUX_3, .has_dvb = 1, - .ir_i2c_master = I2C_0, + .decoder = CX231XX_AVDECODER, .norm = V4L2_STD_PAL, .output_mode = OUT_MODE_VIP11, .tuner_addr = 0x60, /* 0xc0 >> 1 */ @@ -872,6 +872,7 @@ struct cx231xx_board cx231xx_boards[] = { .name = "Astrometa T2hybrid", .tuner_type = TUNER_ABSENT, .has_dvb = 1, + .decoder = CX231XX_AVDECODER, .output_mode = OUT_MODE_VIP11, .agc_analog_digital_select_gpio = 0x01, .ctl_pin_status_mask = 0xffffffc4, @@ -1684,7 +1685,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = dev->devno; assoc_desc = udev->actconfig->intf_assoc[0]; - if (assoc_desc->bFirstInterface != ifnum) { + if (!assoc_desc || assoc_desc->bFirstInterface != ifnum) { dev_err(d, "Not found matching IAD interface\n"); retval = -ENODEV; goto err_if; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index c18bb33e060e..54abc1a7c8e1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -179,10 +179,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index 76e901920f6f..d3bfe8e23b1f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -43,10 +43,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; @@ -285,7 +285,7 @@ static void vbi_buffer_release(struct videobuf_queue *vq, free_buffer(vq, buf); } -struct videobuf_queue_ops cx231xx_vbi_qops = { +const struct videobuf_queue_ops cx231xx_vbi_qops = { .buf_setup = vbi_buffer_setup, .buf_prepare = vbi_buffer_prepare, .buf_queue = vbi_buffer_queue, diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.h b/drivers/media/usb/cx231xx/cx231xx-vbi.h index 16c7d20a22a4..b33d2bdb621c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.h +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.h @@ -22,7 +22,7 @@ #ifndef _CX231XX_VBI_H #define _CX231XX_VBI_H -extern struct videobuf_queue_ops cx231xx_vbi_qops; +extern const struct videobuf_queue_ops cx231xx_vbi_qops; #define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ #define NTSC_VBI_END_LINE 21 diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 179b8481a870..226059fc672b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -199,10 +199,10 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 096bb75a24e5..2bf3bd81280a 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -628,8 +628,7 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) } ret = dvb_usbv2_device_power_ctrl(d, 0); - if (ret < 0) - goto err; + err: if (!adap->suspend_resume_active) { adap->active_fe = -1; diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c index 0eb33e043079..a221bb8a12b4 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c @@ -516,7 +516,6 @@ static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state, data required to program */ block_len = (msg->len / 8); left_over_len = (msg->len % 8); - index = 0; mxl_i2c("block_len %d, left_over_len %d", block_len, left_over_len); diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 95a7b9123f8e..c76e78f9638a 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1598,7 +1598,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) struct rtl28xxu_dev *dev = d->priv; u8 buf[5]; u32 rc_code; - struct rtl28xxu_reg_val rc_nec_tab[] = { + static const struct rtl28xxu_reg_val rc_nec_tab[] = { { 0x3033, 0x80 }, { 0x3020, 0x43 }, { 0x3021, 0x16 }, diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c index 7ba975bea96a..540886b3bb29 100644 --- a/drivers/media/usb/dvb-usb/a800.c +++ b/drivers/media/usb/dvb-usb/a800.c @@ -37,48 +37,9 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr return 0; } -static struct rc_map_table rc_map_a800_table[] = { - { 0x0201, KEY_MODE }, /* SOURCE */ - { 0x0200, KEY_POWER2 }, /* POWER */ - { 0x0205, KEY_1 }, /* 1 */ - { 0x0206, KEY_2 }, /* 2 */ - { 0x0207, KEY_3 }, /* 3 */ - { 0x0209, KEY_4 }, /* 4 */ - { 0x020a, KEY_5 }, /* 5 */ - { 0x020b, KEY_6 }, /* 6 */ - { 0x020d, KEY_7 }, /* 7 */ - { 0x020e, KEY_8 }, /* 8 */ - { 0x020f, KEY_9 }, /* 9 */ - { 0x0212, KEY_LEFT }, /* L / DISPLAY */ - { 0x0211, KEY_0 }, /* 0 */ - { 0x0213, KEY_RIGHT }, /* R / CH RTN */ - { 0x0217, KEY_CAMERA }, /* SNAP SHOT */ - { 0x0210, KEY_LAST }, /* 16-CH PREV */ - { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ - { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ - { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ - { 0x0214, KEY_MUTE }, /* MUTE */ - { 0x0208, KEY_AUDIO }, /* AUDIO */ - { 0x0219, KEY_RECORD }, /* RECORD */ - { 0x0218, KEY_PLAY }, /* PLAY */ - { 0x021b, KEY_STOP }, /* STOP */ - { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ - { 0x021d, KEY_BACK }, /* << / RED */ - { 0x021c, KEY_FORWARD }, /* >> / YELLOW */ - { 0x0203, KEY_TEXT }, /* TELETEXT */ - { 0x0204, KEY_EPG }, /* EPG */ - { 0x0215, KEY_MENU }, /* MENU */ - - { 0x0303, KEY_CHANNELUP }, /* CH UP */ - { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */ - { 0x0301, KEY_FIRST }, /* |<< / GREEN */ - { 0x0300, KEY_LAST }, /* >>| / BLUE */ - -}; - -static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +static int a800_rc_query(struct dvb_usb_device *d) { - int ret; + int ret = 0; u8 *key = kmalloc(5, GFP_KERNEL); if (!key) return -ENOMEM; @@ -90,11 +51,12 @@ static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) goto out; } - /* call the universal NEC remote processor, to find out the key's state and event */ - dvb_usb_nec_rc_key_to_event(d,key,event,state); - if (key[0] != 0) - deb_rc("key: %*ph\n", 5, key); - ret = 0; + /* Note that extended nec and nec32 are dropped */ + if (key[0] == 1) + rc_keydown(d->rc_dev, RC_PROTO_NEC, + RC_SCANCODE_NEC(key[1], key[3]), 0); + else if (key[0] == 2) + rc_repeat(d->rc_dev); out: kfree(key); return ret; @@ -157,11 +119,12 @@ static struct dvb_usb_device_properties a800_properties = { .power_ctrl = a800_power_ctrl, .identify_state = a800_identify_state, - .rc.legacy = { - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_map_table = rc_map_a800_table, - .rc_map_size = ARRAY_SIZE(rc_map_a800_table), - .rc_query = a800_rc_query, + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_AVERMEDIA_M135A, + .module_name = KBUILD_MODNAME, + .rc_query = a800_rc_query, + .allowed_protos = RC_PROTO_BIT_NEC, }, .i2c_algo = &dibusb_i2c_algo, diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 6020170fe99a..92098c1b78e5 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -291,7 +291,7 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) stk7700d_dib7000p_mt2266_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } } @@ -325,7 +325,7 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) stk7700d_dib7000p_mt2266_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } } @@ -478,7 +478,7 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) &stk7700ph_dib7700_xc3028_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -1010,7 +1010,7 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) &dib7070p_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -1068,7 +1068,7 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) &dib7770p_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -3056,7 +3056,7 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); @@ -3109,7 +3109,7 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) /* initialize IC 0 */ if (state->dib7000p_ops.i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -3139,7 +3139,7 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) i2c = state->dib7000p_ops.get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); if (state->dib7000p_ops.i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -3214,7 +3214,7 @@ static int tfe7790p_frontend_attach(struct dvb_usb_adapter *adap) 1, 0x10, &tfe7790p_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } adap->fe_adap[0].fe = state->dib7000p_ops.init(&adap->dev->i2c_adap, @@ -3309,7 +3309,7 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) stk7070pd_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } @@ -3384,7 +3384,7 @@ static int novatd_frontend_attach(struct dvb_usb_adapter *adap) stk7070pd_dib7000p_config) != 0) { err("%s: state->dib7000p_ops.i2c_enumeration failed. Cannot continue\n", __func__); - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } } @@ -3620,7 +3620,7 @@ static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap) if (state->dib7000p_ops.dib7000pc_detection(&adap->dev->i2c_adap) == 0) { /* Demodulator not found for some reason? */ - dvb_detach(&state->dib7000p_ops); + dvb_detach(state->dib7000p_ops.set_wbd_ref); return -ENODEV; } diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c index 701c10835482..65e2c9e2cdc9 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c @@ -280,10 +280,11 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) dev->change_protocol = d->props.rc.core.change_protocol; dev->allowed_protocols = d->props.rc.core.allowed_protos; usb_to_input_id(d->udev, &dev->input_id); - dev->device_name = "IR-receiver inside an USB DVB receiver"; + dev->device_name = d->desc->name; dev->input_phys = d->rc_phys; dev->dev.parent = &d->udev->dev; dev->priv = d; + dev->scancode_mask = d->props.rc.core.scancode_mask; err = rc_register_device(dev); if (err < 0) { diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h index 6c7c4637530f..e71fc86b4fb2 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb.h +++ b/drivers/media/usb/dvb-usb/dvb-usb.h @@ -208,6 +208,7 @@ struct dvb_rc { int (*rc_query) (struct dvb_usb_device *d); int rc_interval; bool bulk_mode; /* uses bulk mode */ + u32 scancode_mask; }; /** diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c index 0251a4e91d47..41261317bd5c 100644 --- a/drivers/media/usb/dvb-usb/friio-fe.c +++ b/drivers/media/usb/dvb-usb/friio-fe.c @@ -261,28 +261,6 @@ static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe, return 0; } - -/* filter out un-supported properties to notify users */ -static int jdvbt90502_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - int r = 0; - - switch (tvp->cmd) { - case DTV_DELIVERY_SYSTEM: - if (tvp->u.data != SYS_ISDBT) - r = -EINVAL; - break; - case DTV_CLEAR: - case DTV_TUNE: - case DTV_FREQUENCY: - break; - default: - r = -EINVAL; - } - return r; -} - static int jdvbt90502_set_frontend(struct dvb_frontend *fe) { struct dtv_frontend_properties *p = &fe->dtv_property_cache; @@ -457,8 +435,6 @@ static const struct dvb_frontend_ops jdvbt90502_ops = { .init = jdvbt90502_init, .write = _jdvbt90502_write, - .set_property = jdvbt90502_set_property, - .set_frontend = jdvbt90502_set_frontend, .read_status = jdvbt90502_read_status, diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c index 13340af0d39c..2527b88beb87 100644 --- a/drivers/media/usb/dvb-usb/vp7045.c +++ b/drivers/media/usb/dvb-usb/vp7045.c @@ -97,82 +97,22 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150); } -/* remote control stuff */ - -/* The keymapping struct. Somehow this should be loaded to the driver, but - * currently it is hardcoded. */ -static struct rc_map_table rc_map_vp7045_table[] = { - { 0x0016, KEY_POWER }, - { 0x0010, KEY_MUTE }, - { 0x0003, KEY_1 }, - { 0x0001, KEY_2 }, - { 0x0006, KEY_3 }, - { 0x0009, KEY_4 }, - { 0x001d, KEY_5 }, - { 0x001f, KEY_6 }, - { 0x000d, KEY_7 }, - { 0x0019, KEY_8 }, - { 0x001b, KEY_9 }, - { 0x0015, KEY_0 }, - { 0x0005, KEY_CHANNELUP }, - { 0x0002, KEY_CHANNELDOWN }, - { 0x001e, KEY_VOLUMEUP }, - { 0x000a, KEY_VOLUMEDOWN }, - { 0x0011, KEY_RECORD }, - { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */ - { 0x0014, KEY_PLAY }, - { 0x001a, KEY_STOP }, - { 0x0040, KEY_REWIND }, - { 0x0012, KEY_FASTFORWARD }, - { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */ - { 0x004c, KEY_PAUSE }, - { 0x004d, KEY_SCREEN }, /* Full screen mode. */ - { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ - { 0x000c, KEY_CANCEL }, /* Cancel */ - { 0x001c, KEY_EPG }, /* EPG */ - { 0x0000, KEY_TAB }, /* Tab */ - { 0x0048, KEY_INFO }, /* Preview */ - { 0x0004, KEY_LIST }, /* RecordList */ - { 0x000f, KEY_TEXT }, /* Teletext */ - { 0x0041, KEY_PREVIOUSSONG }, - { 0x0042, KEY_NEXTSONG }, - { 0x004b, KEY_UP }, - { 0x0051, KEY_DOWN }, - { 0x004e, KEY_LEFT }, - { 0x0052, KEY_RIGHT }, - { 0x004f, KEY_ENTER }, - { 0x0013, KEY_CANCEL }, - { 0x004a, KEY_CLEAR }, - { 0x0054, KEY_PRINT }, /* Capture */ - { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */ - { 0x0008, KEY_VIDEO }, /* A/V */ - { 0x0007, KEY_SLEEP }, /* Hibernate */ - { 0x0045, KEY_ZOOM }, /* Zoom+ */ - { 0x0018, KEY_RED}, - { 0x0053, KEY_GREEN}, - { 0x005e, KEY_YELLOW}, - { 0x005f, KEY_BLUE} -}; - -static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +static int vp7045_rc_query(struct dvb_usb_device *d) { u8 key; - int i; vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); deb_rc("remote query key: %x %d\n",key,key); - if (key == 0x44) { - *state = REMOTE_NO_KEY_PRESSED; - return 0; + if (key != 0x44) { + /* + * The 8 bit address isn't available, but since the remote uses + * address 0 we'll use that. nec repeats are ignored too, even + * though the remote sends them. + */ + rc_keydown(d->rc_dev, RC_PROTO_NEC, RC_SCANCODE_NEC(0, key), 0); } - for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++) - if (rc5_data(&rc_map_vp7045_table[i]) == key) { - *state = REMOTE_KEY_PRESSED; - *event = rc_map_vp7045_table[i].keycode; - break; - } return 0; } @@ -265,11 +205,13 @@ static struct dvb_usb_device_properties vp7045_properties = { .power_ctrl = vp7045_power_ctrl, .read_mac_address = vp7045_read_mac_addr, - .rc.legacy = { - .rc_interval = 400, - .rc_map_table = rc_map_vp7045_table, - .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table), - .rc_query = vp7045_rc_query, + .rc.core = { + .rc_interval = 400, + .rc_codes = RC_MAP_TWINHAN_VP1027_DVBS, + .module_name = KBUILD_MODNAME, + .rc_query = vp7045_rc_query, + .allowed_protos = RC_PROTO_BIT_NEC, + .scancode_mask = 0xff, }, .num_device_descs = 2, diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 4a7db623fe29..9950a740e04e 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -112,10 +112,10 @@ static inline void print_err_status(struct em28xx *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 66c5012a628a..9bf49d666e5a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -882,7 +882,7 @@ static const struct i2c_adapter em28xx_adap_template = { .algo = &em28xx_algo, }; -static struct i2c_client em28xx_client_template = { +static const struct i2c_client em28xx_client_template = { .name = "em28xx internal", }; diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h index 8dfcb56bf4b3..9c411aac3878 100644 --- a/drivers/media/usb/em28xx/em28xx-v4l.h +++ b/drivers/media/usb/em28xx/em28xx-v4l.h @@ -16,4 +16,4 @@ int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); void em28xx_stop_vbi_streaming(struct vb2_queue *vq); -extern struct vb2_ops em28xx_vbi_qops; +extern const struct vb2_ops em28xx_vbi_qops; diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 0bac552bbe87..f5123651ef30 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -93,7 +93,7 @@ vbi_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&dev->slock, flags); } -struct vb2_ops em28xx_vbi_qops = { +const struct vb2_ops em28xx_vbi_qops = { .queue_setup = vbi_queue_setup, .buf_prepare = vbi_buffer_prepare, .buf_queue = vbi_buffer_queue, diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 8d253a5df0a9..a2ba2d905952 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -557,10 +557,10 @@ static inline void print_err_status(struct em28xx *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/gspca/Kconfig b/drivers/media/usb/gspca/Kconfig index 3fd94fe7e1eb..d214a21acff7 100644 --- a/drivers/media/usb/gspca/Kconfig +++ b/drivers/media/usb/gspca/Kconfig @@ -204,11 +204,11 @@ config USB_GSPCA_SE401 tristate "SE401 USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the - Endpoints (formerly known as AOX) se401 chip. + Say Y here if you want support for cameras based on the + Endpoints (formerly known as AOX) se401 chip. - To compile this driver as a module, choose M here: the - module will be called gspca_se401. + To compile this driver as a module, choose M here: the + module will be called gspca_se401. config USB_GSPCA_SN9C2028 tristate "SONIX Dual-Mode USB Camera Driver" @@ -224,11 +224,11 @@ config USB_GSPCA_SN9C20X tristate "SN9C20X USB Camera Driver" depends on VIDEO_V4L2 && USB_GSPCA help - Say Y here if you want support for cameras based on the - sn9c20x chips (SN9C201 and SN9C202). + Say Y here if you want support for cameras based on the + sn9c20x chips (SN9C201 and SN9C202). - To compile this driver as a module, choose M here: the - module will be called gspca_sn9c20x. + To compile this driver as a module, choose M here: the + module will be called gspca_sn9c20x. config USB_GSPCA_SONIXB tristate "SONIX Bayer USB Camera Driver" diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 0f141762abf1..961343873fd0 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1075,7 +1075,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, /* give an index to each format */ index = 0; - j = 0; for (i = gspca_dev->cam.nmodes; --i >= 0; ) { fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat; j = 0; diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index cdb79c5f0c38..f1537daf4e2e 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c @@ -2865,7 +2865,7 @@ static void sd_reset_snapshot(struct gspca_dev *gspca_dev) static void ov51x_upload_quan_tables(struct sd *sd) { - const unsigned char yQuanTable511[] = { + static const unsigned char yQuanTable511[] = { 0, 1, 1, 2, 2, 3, 3, 4, 1, 1, 1, 2, 2, 3, 4, 4, 1, 1, 2, 2, 3, 4, 4, 4, @@ -2876,7 +2876,7 @@ static void ov51x_upload_quan_tables(struct sd *sd) 4, 4, 4, 4, 5, 5, 5, 5 }; - const unsigned char uvQuanTable511[] = { + static const unsigned char uvQuanTable511[] = { 0, 2, 2, 3, 4, 4, 4, 4, 2, 2, 2, 4, 4, 4, 4, 4, 2, 2, 3, 4, 4, 4, 4, 4, @@ -2888,13 +2888,13 @@ static void ov51x_upload_quan_tables(struct sd *sd) }; /* OV518 quantization tables are 8x4 (instead of 8x8) */ - const unsigned char yQuanTable518[] = { + static const unsigned char yQuanTable518[] = { 5, 4, 5, 6, 6, 7, 7, 7, 5, 5, 5, 5, 6, 7, 7, 7, 6, 6, 6, 6, 7, 7, 7, 8, 7, 7, 6, 7, 7, 7, 8, 8 }; - const unsigned char uvQuanTable518[] = { + static const unsigned char uvQuanTable518[] = { 6, 6, 6, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 8, @@ -2943,7 +2943,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; /* For 511 and 511+ */ - const struct ov_regvals init_511[] = { + static const struct ov_regvals init_511[] = { { R51x_SYS_RESET, 0x7f }, { R51x_SYS_INIT, 0x01 }, { R51x_SYS_RESET, 0x7f }, @@ -2953,7 +2953,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev) { R51x_SYS_RESET, 0x3d }, }; - const struct ov_regvals norm_511[] = { + static const struct ov_regvals norm_511[] = { { R511_DRAM_FLOW_CTL, 0x01 }, { R51x_SYS_SNAP, 0x00 }, { R51x_SYS_SNAP, 0x02 }, @@ -2963,7 +2963,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev) { R511_COMP_LUT_EN, 0x03 }, }; - const struct ov_regvals norm_511_p[] = { + static const struct ov_regvals norm_511_p[] = { { R511_DRAM_FLOW_CTL, 0xff }, { R51x_SYS_SNAP, 0x00 }, { R51x_SYS_SNAP, 0x02 }, @@ -2973,7 +2973,7 @@ static void ov511_configure(struct gspca_dev *gspca_dev) { R511_COMP_LUT_EN, 0x03 }, }; - const struct ov_regvals compress_511[] = { + static const struct ov_regvals compress_511[] = { { 0x70, 0x1f }, { 0x71, 0x05 }, { 0x72, 0x06 }, @@ -3009,7 +3009,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; /* For 518 and 518+ */ - const struct ov_regvals init_518[] = { + static const struct ov_regvals init_518[] = { { R51x_SYS_RESET, 0x40 }, { R51x_SYS_INIT, 0xe1 }, { R51x_SYS_RESET, 0x3e }, @@ -3020,7 +3020,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev) { 0x5d, 0x03 }, }; - const struct ov_regvals norm_518[] = { + static const struct ov_regvals norm_518[] = { { R51x_SYS_SNAP, 0x02 }, /* Reset */ { R51x_SYS_SNAP, 0x01 }, /* Enable */ { 0x31, 0x0f }, @@ -3033,7 +3033,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev) { 0x2f, 0x80 }, }; - const struct ov_regvals norm_518_p[] = { + static const struct ov_regvals norm_518_p[] = { { R51x_SYS_SNAP, 0x02 }, /* Reset */ { R51x_SYS_SNAP, 0x01 }, /* Enable */ { 0x31, 0x0f }, diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index a097d3dbc141..65ef755adfdc 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -386,7 +386,7 @@ static void msi2500_isoc_handler(struct urb *urb) if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) { - dev_dbg(dev->dev, "URB (%p) unlinked %ssynchronuously\n", + dev_dbg(dev->dev, "URB (%p) unlinked %ssynchronously\n", urb, urb->status == -ENOENT ? "" : "a"); return; } diff --git a/drivers/media/usb/pvrusb2/Kconfig b/drivers/media/usb/pvrusb2/Kconfig index 60a2604e4cb3..1ad913fc30bf 100644 --- a/drivers/media/usb/pvrusb2/Kconfig +++ b/drivers/media/usb/pvrusb2/Kconfig @@ -44,7 +44,6 @@ config VIDEO_PVRUSB2_DVB select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_TDA8290 if MEDIA_SUBDRV_AUTOSELECT ---help--- - This option enables a DVB interface for the pvrusb2 driver. If your device does not support digital television, this feature will have no affect on the driver's operation. diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index eb6921d2743e..54b036d39c5b 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c @@ -262,7 +262,8 @@ static void pwc_isoc_handler(struct urb *urb) if (urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) { - PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a"); + PWC_DEBUG_OPEN("URB (%p) unlinked %ssynchronously.\n", + urb, urb->status == -ENOENT ? "" : "a"); return; } diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index b2f239c4ba42..7fee5766587a 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -485,9 +485,10 @@ static void s2255_reset_dsppower(struct s2255_dev *dev) /* kickstarts the firmware loading. from probe */ -static void s2255_timer(unsigned long user_data) +static void s2255_timer(struct timer_list *t) { - struct s2255_fw *data = (struct s2255_fw *)user_data; + struct s2255_dev *dev = from_timer(dev, t, timer); + struct s2255_fw *data = dev->fw_data; if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { pr_err("s2255: can't submit urb\n"); atomic_set(&data->fw_state, S2255_FW_FAILED); @@ -2283,7 +2284,7 @@ static int s2255_probe(struct usb_interface *interface, dev_err(&interface->dev, "Could not find bulk-in endpoint\n"); goto errorEP; } - setup_timer(&dev->timer, s2255_timer, (unsigned long)dev->fw_data); + timer_setup(&dev->timer, s2255_timer, 0); init_waitqueue_head(&dev->fw_data->wait_fw); for (i = 0; i < MAX_CHANNELS; i++) { struct s2255_vc *vc = &dev->vc[i]; diff --git a/drivers/media/usb/stk1160/stk1160-i2c.c b/drivers/media/usb/stk1160/stk1160-i2c.c index 2c70173e3c82..62a12d5356ad 100644 --- a/drivers/media/usb/stk1160/stk1160-i2c.c +++ b/drivers/media/usb/stk1160/stk1160-i2c.c @@ -246,7 +246,7 @@ static const struct i2c_adapter adap_template = { .algo = &algo, }; -static struct i2c_client client_template = { +static const struct i2c_client client_template = { .name = "stk1160 internal", }; diff --git a/drivers/media/usb/stk1160/stk1160-video.c b/drivers/media/usb/stk1160/stk1160-video.c index ce8ebbe395a6..423c03a0638d 100644 --- a/drivers/media/usb/stk1160/stk1160-video.c +++ b/drivers/media/usb/stk1160/stk1160-video.c @@ -38,10 +38,10 @@ static inline void print_err_status(struct stk1160 *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 2537643a1808..77347541904d 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c @@ -1184,7 +1184,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *usbdev; - struct tm6000_core *dev = NULL; + struct tm6000_core *dev; int i, rc = 0; int nr = 0; char *speed; @@ -1194,22 +1194,21 @@ static int tm6000_usb_probe(struct usb_interface *interface, /* Selects the proper interface */ rc = usb_set_interface(usbdev, 0, 1); if (rc < 0) - goto err; + goto report_failure; /* Check to see next free device and mark as used */ nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS); if (nr >= TM6000_MAXBOARDS) { printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS); - usb_put_dev(usbdev); - return -ENOMEM; + rc = -ENOMEM; + goto put_device; } /* Create and initialize dev struct */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "tm6000" ": out of memory!\n"); - usb_put_dev(usbdev); - return -ENOMEM; + if (!dev) { + rc = -ENOMEM; + goto put_device; } spin_lock_init(&dev->slock); mutex_init(&dev->usb_lock); @@ -1313,8 +1312,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, if (!dev->isoc_in.endp) { printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n"); rc = -ENODEV; - - goto err; + goto free_device; } /* save our data pointer in this interface device */ @@ -1324,17 +1322,18 @@ static int tm6000_usb_probe(struct usb_interface *interface, rc = tm6000_init_dev(dev); if (rc < 0) - goto err; + goto free_device; return 0; -err: +free_device: + kfree(dev); +report_failure: printk(KERN_ERR "tm6000: Error %d while registering\n", rc); clear_bit(nr, &tm6000_devused); +put_device: usb_put_dev(usbdev); - - kfree(dev); return rc; } diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c index 097ac321b7e1..c811fc6cf48a 100644 --- a/drivers/media/usb/tm6000/tm6000-dvb.c +++ b/drivers/media/usb/tm6000/tm6000-dvb.c @@ -45,10 +45,10 @@ static inline void print_err_status(struct tm6000_core *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; @@ -123,7 +123,7 @@ static int tm6000_start_stream(struct tm6000_core *dev) } dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); - if (dvb->bulk_urb == NULL) + if (!dvb->bulk_urb) return -ENOMEM; pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress @@ -133,9 +133,8 @@ static int tm6000_start_stream(struct tm6000_core *dev) size = size * 15; /* 512 x 8 or 12 or 15 */ dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); - if (dvb->bulk_urb->transfer_buffer == NULL) { + if (!dvb->bulk_urb->transfer_buffer) { usb_free_urb(dvb->bulk_urb); - printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n"); return -ENOMEM; } @@ -361,7 +360,7 @@ static void unregister_dvb(struct tm6000_core *dev) { struct tm6000_dvb *dvb = dev->dvb; - if (dvb->bulk_urb != NULL) { + if (dvb->bulk_urb) { struct urb *bulk_urb = dvb->bulk_urb; kfree(bulk_urb->transfer_buffer); @@ -400,10 +399,8 @@ static int dvb_init(struct tm6000_core *dev) } dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL); - if (!dvb) { - printk(KERN_INFO "Cannot allocate memory\n"); + if (!dvb) return -ENOMEM; - } dev->dvb = dvb; diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c index 91889ad9cdd7..397990afe00b 100644 --- a/drivers/media/usb/tm6000/tm6000-input.c +++ b/drivers/media/usb/tm6000/tm6000-input.c @@ -352,7 +352,7 @@ static int __tm6000_ir_int_start(struct rc_dev *rc) dprintk(1, "IR max size: %d\n", size); ir->int_urb->transfer_buffer = kzalloc(size, GFP_ATOMIC); - if (ir->int_urb->transfer_buffer == NULL) { + if (!ir->int_urb->transfer_buffer) { usb_free_urb(ir->int_urb); return err; } diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index ec8c4d2534dc..9fa25de6b5a9 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -342,10 +342,10 @@ static inline void print_err_status(struct tm6000_core *dev, switch (status) { case -ENOENT: - errmsg = "unlinked synchronuously"; + errmsg = "unlinked synchronously"; break; case -ECONNRESET: - errmsg = "unlinked asynchronuously"; + errmsg = "unlinked asynchronously"; break; case -ENOSR: errmsg = "Buffer error (overrun)"; @@ -470,20 +470,16 @@ static int tm6000_alloc_urb_buffers(struct tm6000_core *dev) int num_bufs = TM6000_NUM_URB_BUF; int i; - if (dev->urb_buffer != NULL) + if (dev->urb_buffer) return 0; dev->urb_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!dev->urb_buffer) { - tm6000_err("cannot allocate memory for urb buffers\n"); + if (!dev->urb_buffer) return -ENOMEM; - } dev->urb_dma = kmalloc(sizeof(dma_addr_t *)*num_bufs, GFP_KERNEL); - if (!dev->urb_dma) { - tm6000_err("cannot allocate memory for urb dma pointers\n"); + if (!dev->urb_dma) return -ENOMEM; - } for (i = 0; i < num_bufs; i++) { dev->urb_buffer[i] = usb_alloc_coherent( @@ -507,7 +503,7 @@ static int tm6000_free_urb_buffers(struct tm6000_core *dev) { int i; - if (dev->urb_buffer == NULL) + if (!dev->urb_buffer) return 0; for (i = 0; i < TM6000_NUM_URB_BUF; i++) { @@ -598,15 +594,12 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev) dev->isoc_ctl.num_bufs = num_bufs; dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!dev->isoc_ctl.urb) { - tm6000_err("cannot alloc memory for usb buffers\n"); + if (!dev->isoc_ctl.urb) return -ENOMEM; - } dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); if (!dev->isoc_ctl.transfer_buffer) { - tm6000_err("cannot allocate memory for usbtransfer\n"); kfree(dev->isoc_ctl.urb); return -ENOMEM; } diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index f06f09a0876e..b55b79b8e921 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -84,7 +84,7 @@ static int usbtv_probe(struct usb_interface *intf, /* Packet size is split into 11 bits of base size and count of * extra multiplies of it.*/ size = usb_endpoint_maxp(&ep->desc); - size = (size & 0x07ff) * usb_endpoint_maxp_mult(&ep->desc); + size = size * usb_endpoint_maxp_mult(&ep->desc); /* Device structure */ usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL); diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 95b5f4319ec2..3668a04359e8 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -718,8 +718,8 @@ static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) */ if (ctrl->id == V4L2_CID_BRIGHTNESS || ctrl->id == V4L2_CID_CONTRAST) { ret = usb_control_msg(usbtv->udev, - usb_sndctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, USBTV_BASE + 0x0244, (void *)data, 3, 0); if (ret < 0) goto error; diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 4ff8d0aed015..1d888661fd03 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -209,10 +209,8 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, int status; unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); - if (!transfer_buffer) { - dev_err(&udev->dev, "kmalloc(%d) failed\n", size); + if (!transfer_buffer) return -ENOMEM; - } memcpy(transfer_buffer, cp, size); @@ -387,9 +385,9 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, vb); int rc; - DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ? - cam->fmt->name : ""); - if (cam->fmt == NULL) + DBG("%s, field=%d, fmt name = %s\n", __func__, field, + cam->fmt ? cam->fmt->name : ""); + if (!cam->fmt) return -EINVAL; buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3); @@ -789,7 +787,7 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct zr364xx_camera *cam = video_drvdata(file); char pixelformat_name[5]; - if (cam == NULL) + if (!cam) return -ENODEV; if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) { @@ -819,7 +817,7 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, { struct zr364xx_camera *cam; - if (file == NULL) + if (!file) return -ENODEV; cam = video_drvdata(file); @@ -981,13 +979,13 @@ static void read_pipe_completion(struct urb *purb) pipe_info = purb->context; _DBG("%s %p, status %d\n", __func__, purb, purb->status); - if (pipe_info == NULL) { + if (!pipe_info) { printk(KERN_ERR KBUILD_MODNAME ": no context!\n"); return; } cam = pipe_info->cam; - if (cam == NULL) { + if (!cam) { printk(KERN_ERR KBUILD_MODNAME ": no context!\n"); return; } @@ -1071,7 +1069,7 @@ static void zr364xx_stop_readpipe(struct zr364xx_camera *cam) { struct zr364xx_pipeinfo *pipe_info; - if (cam == NULL) { + if (!cam) { printk(KERN_ERR KBUILD_MODNAME ": invalid device\n"); return; } @@ -1275,7 +1273,7 @@ static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma) struct zr364xx_camera *cam = video_drvdata(file); int ret; - if (cam == NULL) { + if (!cam) { DBG("%s: cam == NULL\n", __func__); return -ENODEV; } @@ -1359,7 +1357,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) pipe->transfer_buffer = kzalloc(pipe->transfer_size, GFP_KERNEL); - if (pipe->transfer_buffer == NULL) { + if (!pipe->transfer_buffer) { DBG("out of memory!\n"); return -ENOMEM; } @@ -1375,7 +1373,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) DBG("valloc %p, idx %lu, pdata %p\n", &cam->buffer.frame[i], i, cam->buffer.frame[i].lpvbits); - if (cam->buffer.frame[i].lpvbits == NULL) { + if (!cam->buffer.frame[i].lpvbits) { printk(KERN_INFO KBUILD_MODNAME ": out of memory. Using less frames\n"); break; } @@ -1423,11 +1421,9 @@ static int zr364xx_probe(struct usb_interface *intf, le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); - cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); - if (cam == NULL) { - dev_err(&udev->dev, "cam: out of memory !\n"); + cam = kzalloc(sizeof(*cam), GFP_KERNEL); + if (!cam) return -ENOMEM; - } cam->v4l2_dev.release = zr364xx_release; err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index d741a8e0fdac..a7c3464976f2 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -22,8 +22,37 @@ #include <media/v4l2-async.h> #include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> #include <media/v4l2-subdev.h> +static int v4l2_async_notifier_call_bound(struct v4l2_async_notifier *n, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + if (!n->ops || !n->ops->bound) + return 0; + + return n->ops->bound(n, subdev, asd); +} + +static void v4l2_async_notifier_call_unbind(struct v4l2_async_notifier *n, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + if (!n->ops || !n->ops->unbind) + return; + + n->ops->unbind(n, subdev, asd); +} + +static int v4l2_async_notifier_call_complete(struct v4l2_async_notifier *n) +{ + if (!n->ops || !n->ops->complete) + return 0; + + return n->ops->complete(n); +} + static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) { #if IS_ENABLED(CONFIG_I2C) @@ -60,8 +89,8 @@ static LIST_HEAD(subdev_list); static LIST_HEAD(notifier_list); static DEFINE_MUTEX(list_lock); -static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *sd) +static struct v4l2_async_subdev *v4l2_async_find_match( + struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd) { bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *); struct v4l2_async_subdev *asd; @@ -95,22 +124,96 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * return NULL; } -static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *sd, - struct v4l2_async_subdev *asd) +/* Find the sub-device notifier registered by a sub-device driver. */ +static struct v4l2_async_notifier *v4l2_async_find_subdev_notifier( + struct v4l2_subdev *sd) { - int ret; + struct v4l2_async_notifier *n; - if (notifier->bound) { - ret = notifier->bound(notifier, sd, asd); - if (ret < 0) - return ret; + list_for_each_entry(n, ¬ifier_list, list) + if (n->sd == sd) + return n; + + return NULL; +} + +/* Get v4l2_device related to the notifier if one can be found. */ +static struct v4l2_device *v4l2_async_notifier_find_v4l2_dev( + struct v4l2_async_notifier *notifier) +{ + while (notifier->parent) + notifier = notifier->parent; + + return notifier->v4l2_dev; +} + +/* + * Return true if all child sub-device notifiers are complete, false otherwise. + */ +static bool v4l2_async_notifier_can_complete( + struct v4l2_async_notifier *notifier) +{ + struct v4l2_subdev *sd; + + if (!list_empty(¬ifier->waiting)) + return false; + + list_for_each_entry(sd, ¬ifier->done, async_list) { + struct v4l2_async_notifier *subdev_notifier = + v4l2_async_find_subdev_notifier(sd); + + if (subdev_notifier && + !v4l2_async_notifier_can_complete(subdev_notifier)) + return false; } - ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd); + return true; +} + +/* + * Complete the master notifier if possible. This is done when all async + * sub-devices have been bound; v4l2_device is also available then. + */ +static int v4l2_async_notifier_try_complete( + struct v4l2_async_notifier *notifier) +{ + /* Quick check whether there are still more sub-devices here. */ + if (!list_empty(¬ifier->waiting)) + return 0; + + /* Check the entire notifier tree; find the root notifier first. */ + while (notifier->parent) + notifier = notifier->parent; + + /* This is root if it has v4l2_dev. */ + if (!notifier->v4l2_dev) + return 0; + + /* Is everything ready? */ + if (!v4l2_async_notifier_can_complete(notifier)) + return 0; + + return v4l2_async_notifier_call_complete(notifier); +} + +static int v4l2_async_notifier_try_all_subdevs( + struct v4l2_async_notifier *notifier); + +static int v4l2_async_match_notify(struct v4l2_async_notifier *notifier, + struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd) +{ + struct v4l2_async_notifier *subdev_notifier; + int ret; + + ret = v4l2_device_register_subdev(v4l2_dev, sd); + if (ret < 0) + return ret; + + ret = v4l2_async_notifier_call_bound(notifier, sd, asd); if (ret < 0) { - if (notifier->unbind) - notifier->unbind(notifier, sd, asd); + v4l2_device_unregister_subdev(sd); return ret; } @@ -122,8 +225,55 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, /* Move from the global subdevice list to notifier's done */ list_move(&sd->async_list, ¬ifier->done); - if (list_empty(¬ifier->waiting) && notifier->complete) - return notifier->complete(notifier); + /* + * See if the sub-device has a notifier. If not, return here. + */ + subdev_notifier = v4l2_async_find_subdev_notifier(sd); + if (!subdev_notifier || subdev_notifier->parent) + return 0; + + /* + * Proceed with checking for the sub-device notifier's async + * sub-devices, and return the result. The error will be handled by the + * caller. + */ + subdev_notifier->parent = notifier; + + return v4l2_async_notifier_try_all_subdevs(subdev_notifier); +} + +/* Test all async sub-devices in a notifier for a match. */ +static int v4l2_async_notifier_try_all_subdevs( + struct v4l2_async_notifier *notifier) +{ + struct v4l2_device *v4l2_dev = + v4l2_async_notifier_find_v4l2_dev(notifier); + struct v4l2_subdev *sd; + + if (!v4l2_dev) + return 0; + +again: + list_for_each_entry(sd, &subdev_list, async_list) { + struct v4l2_async_subdev *asd; + int ret; + + asd = v4l2_async_find_match(notifier, sd); + if (!asd) + continue; + + ret = v4l2_async_match_notify(notifier, v4l2_dev, sd, asd); + if (ret < 0) + return ret; + + /* + * v4l2_async_match_notify() may lead to registering a + * new notifier and thus changing the async subdevs + * list. In order to proceed safely from here, restart + * parsing the list from the beginning. + */ + goto again; + } return 0; } @@ -134,24 +284,107 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd) /* Subdevice driver will reprobe and put the subdev back onto the list */ list_del_init(&sd->async_list); sd->asd = NULL; - sd->dev = NULL; } -int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, - struct v4l2_async_notifier *notifier) +/* Unbind all sub-devices in the notifier tree. */ +static void v4l2_async_notifier_unbind_all_subdevs( + struct v4l2_async_notifier *notifier) { struct v4l2_subdev *sd, *tmp; + + list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) { + struct v4l2_async_notifier *subdev_notifier = + v4l2_async_find_subdev_notifier(sd); + + if (subdev_notifier) + v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); + + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + list_move(&sd->async_list, &subdev_list); + } + + notifier->parent = NULL; +} + +/* See if an fwnode can be found in a notifier's lists. */ +static bool __v4l2_async_notifier_fwnode_has_async_subdev( + struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode) +{ struct v4l2_async_subdev *asd; + struct v4l2_subdev *sd; + + list_for_each_entry(asd, ¬ifier->waiting, list) { + if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE) + continue; + + if (asd->match.fwnode.fwnode == fwnode) + return true; + } + + list_for_each_entry(sd, ¬ifier->done, async_list) { + if (WARN_ON(!sd->asd)) + continue; + + if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE) + continue; + + if (sd->asd->match.fwnode.fwnode == fwnode) + return true; + } + + return false; +} + +/* + * Find out whether an async sub-device was set up for an fwnode already or + * whether it exists in a given notifier before @this_index. + */ +static bool v4l2_async_notifier_fwnode_has_async_subdev( + struct v4l2_async_notifier *notifier, struct fwnode_handle *fwnode, + unsigned int this_index) +{ + unsigned int j; + + lockdep_assert_held(&list_lock); + + /* Check that an fwnode is not being added more than once. */ + for (j = 0; j < this_index; j++) { + struct v4l2_async_subdev *asd = notifier->subdevs[this_index]; + struct v4l2_async_subdev *other_asd = notifier->subdevs[j]; + + if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE && + asd->match.fwnode.fwnode == + other_asd->match.fwnode.fwnode) + return true; + } + + /* Check than an fwnode did not exist in other notifiers. */ + list_for_each_entry(notifier, ¬ifier_list, list) + if (__v4l2_async_notifier_fwnode_has_async_subdev( + notifier, fwnode)) + return true; + + return false; +} + +static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier) +{ + struct device *dev = + notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL; + struct v4l2_async_subdev *asd; + int ret; int i; - if (!v4l2_dev || !notifier->num_subdevs || - notifier->num_subdevs > V4L2_MAX_SUBDEVS) + if (notifier->num_subdevs > V4L2_MAX_SUBDEVS) return -EINVAL; - notifier->v4l2_dev = v4l2_dev; INIT_LIST_HEAD(¬ifier->waiting); INIT_LIST_HEAD(¬ifier->done); + mutex_lock(&list_lock); + for (i = 0; i < notifier->num_subdevs; i++) { asd = notifier->subdevs[i]; @@ -159,32 +392,32 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, case V4L2_ASYNC_MATCH_CUSTOM: case V4L2_ASYNC_MATCH_DEVNAME: case V4L2_ASYNC_MATCH_I2C: + break; case V4L2_ASYNC_MATCH_FWNODE: + if (v4l2_async_notifier_fwnode_has_async_subdev( + notifier, asd->match.fwnode.fwnode, i)) { + dev_err(dev, + "fwnode has already been registered or in notifier's subdev list\n"); + ret = -EEXIST; + goto err_unlock; + } break; default: - dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL, - "Invalid match type %u on %p\n", + dev_err(dev, "Invalid match type %u on %p\n", asd->match_type, asd); - return -EINVAL; + ret = -EINVAL; + goto err_unlock; } list_add_tail(&asd->list, ¬ifier->waiting); } - mutex_lock(&list_lock); + ret = v4l2_async_notifier_try_all_subdevs(notifier); + if (ret < 0) + goto err_unbind; - list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) { - int ret; - - asd = v4l2_async_belongs(notifier, sd); - if (!asd) - continue; - - ret = v4l2_async_test_notify(notifier, sd, asd); - if (ret < 0) { - mutex_unlock(&list_lock); - return ret; - } - } + ret = v4l2_async_notifier_try_complete(notifier); + if (ret < 0) + goto err_unbind; /* Keep also completed notifiers on the list */ list_add(¬ifier->list, ¬ifier_list); @@ -192,90 +425,114 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, mutex_unlock(&list_lock); return 0; + +err_unbind: + /* + * On failure, unbind all sub-devices registered through this notifier. + */ + v4l2_async_notifier_unbind_all_subdevs(notifier); + +err_unlock: + mutex_unlock(&list_lock); + + return ret; +} + +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, + struct v4l2_async_notifier *notifier) +{ + int ret; + + if (WARN_ON(!v4l2_dev || notifier->sd)) + return -EINVAL; + + notifier->v4l2_dev = v4l2_dev; + + ret = __v4l2_async_notifier_register(notifier); + if (ret) + notifier->v4l2_dev = NULL; + + return ret; } EXPORT_SYMBOL(v4l2_async_notifier_register); -void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) +int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, + struct v4l2_async_notifier *notifier) { - struct v4l2_subdev *sd, *tmp; - unsigned int notif_n_subdev = notifier->num_subdevs; - unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS); - struct device **dev; - int i = 0; + int ret; - if (!notifier->v4l2_dev) - return; + if (WARN_ON(!sd || notifier->v4l2_dev)) + return -EINVAL; - dev = kvmalloc_array(n_subdev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(notifier->v4l2_dev->dev, - "Failed to allocate device cache!\n"); - } + notifier->sd = sd; - mutex_lock(&list_lock); + ret = __v4l2_async_notifier_register(notifier); + if (ret) + notifier->sd = NULL; - list_del(¬ifier->list); + return ret; +} +EXPORT_SYMBOL(v4l2_async_subdev_notifier_register); - list_for_each_entry_safe(sd, tmp, ¬ifier->done, async_list) { - struct device *d; +static void __v4l2_async_notifier_unregister( + struct v4l2_async_notifier *notifier) +{ + if (!notifier || (!notifier->v4l2_dev && !notifier->sd)) + return; - d = get_device(sd->dev); + v4l2_async_notifier_unbind_all_subdevs(notifier); - v4l2_async_cleanup(sd); + notifier->sd = NULL; + notifier->v4l2_dev = NULL; - /* If we handled USB devices, we'd have to lock the parent too */ - device_release_driver(d); + list_del(¬ifier->list); +} - if (notifier->unbind) - notifier->unbind(notifier, sd, sd->asd); +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) +{ + mutex_lock(&list_lock); - /* - * Store device at the device cache, in order to call - * put_device() on the final step - */ - if (dev) - dev[i++] = d; - else - put_device(d); - } + __v4l2_async_notifier_unregister(notifier); mutex_unlock(&list_lock); +} +EXPORT_SYMBOL(v4l2_async_notifier_unregister); - /* - * Call device_attach() to reprobe devices - * - * NOTE: If dev allocation fails, i is 0, and the whole loop won't be - * executed. - */ - while (i--) { - struct device *d = dev[i]; - - if (d && device_attach(d) < 0) { - const char *name = "(none)"; - int lock = device_trylock(d); - - if (lock && d->driver) - name = d->driver->name; - dev_err(d, "Failed to re-probe to %s\n", name); - if (lock) - device_unlock(d); +void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier) +{ + unsigned int i; + + if (!notifier || !notifier->max_subdevs) + return; + + for (i = 0; i < notifier->num_subdevs; i++) { + struct v4l2_async_subdev *asd = notifier->subdevs[i]; + + switch (asd->match_type) { + case V4L2_ASYNC_MATCH_FWNODE: + fwnode_handle_put(asd->match.fwnode.fwnode); + break; + default: + WARN_ON_ONCE(true); + break; } - put_device(d); + + kfree(asd); } - kvfree(dev); - notifier->v4l2_dev = NULL; + notifier->max_subdevs = 0; + notifier->num_subdevs = 0; - /* - * Don't care about the waiting list, it is initialised and populated - * upon notifier registration. - */ + kvfree(notifier->subdevs); + notifier->subdevs = NULL; } -EXPORT_SYMBOL(v4l2_async_notifier_unregister); +EXPORT_SYMBOL_GPL(v4l2_async_notifier_cleanup); int v4l2_async_register_subdev(struct v4l2_subdev *sd) { + struct v4l2_async_notifier *subdev_notifier; struct v4l2_async_notifier *notifier; + int ret; /* * No reference taken. The reference is held by the device @@ -290,41 +547,74 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) INIT_LIST_HEAD(&sd->async_list); list_for_each_entry(notifier, ¬ifier_list, list) { - struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd); - if (asd) { - int ret = v4l2_async_test_notify(notifier, sd, asd); - mutex_unlock(&list_lock); - return ret; - } + struct v4l2_device *v4l2_dev = + v4l2_async_notifier_find_v4l2_dev(notifier); + struct v4l2_async_subdev *asd; + + if (!v4l2_dev) + continue; + + asd = v4l2_async_find_match(notifier, sd); + if (!asd) + continue; + + ret = v4l2_async_match_notify(notifier, notifier->v4l2_dev, sd, + asd); + if (ret) + goto err_unbind; + + ret = v4l2_async_notifier_try_complete(notifier); + if (ret) + goto err_unbind; + + goto out_unlock; } /* None matched, wait for hot-plugging */ list_add(&sd->async_list, &subdev_list); +out_unlock: mutex_unlock(&list_lock); return 0; + +err_unbind: + /* + * Complete failed. Unbind the sub-devices bound through registering + * this async sub-device. + */ + subdev_notifier = v4l2_async_find_subdev_notifier(sd); + if (subdev_notifier) + v4l2_async_notifier_unbind_all_subdevs(subdev_notifier); + + if (sd->asd) + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); + + mutex_unlock(&list_lock); + + return ret; } EXPORT_SYMBOL(v4l2_async_register_subdev); void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) { - struct v4l2_async_notifier *notifier = sd->notifier; + mutex_lock(&list_lock); - if (!sd->asd) { - if (!list_empty(&sd->async_list)) - v4l2_async_cleanup(sd); - return; - } + __v4l2_async_notifier_unregister(sd->subdev_notifier); + v4l2_async_notifier_cleanup(sd->subdev_notifier); + kfree(sd->subdev_notifier); + sd->subdev_notifier = NULL; - mutex_lock(&list_lock); + if (sd->asd) { + struct v4l2_async_notifier *notifier = sd->notifier; - list_add(&sd->asd->list, ¬ifier->waiting); + list_add(&sd->asd->list, ¬ifier->waiting); - v4l2_async_cleanup(sd); + v4l2_async_notifier_call_unbind(notifier, sd, sd->asd); + } - if (notifier->unbind) - notifier->unbind(notifier, sd, sd->asd); + v4l2_async_cleanup(sd); mutex_unlock(&list_lock); } diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index dd1db678718c..cbb2ef43945f 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1227,6 +1227,16 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, } EXPORT_SYMBOL(v4l2_ctrl_fill); +static u32 user_flags(const struct v4l2_ctrl *ctrl) +{ + u32 flags = ctrl->flags; + + if (ctrl->is_ptr) + flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; + + return flags; +} + static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 changes) { memset(ev->reserved, 0, sizeof(ev->reserved)); @@ -1234,7 +1244,7 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change ev->id = ctrl->id; ev->u.ctrl.changes = changes; ev->u.ctrl.type = ctrl->type; - ev->u.ctrl.flags = ctrl->flags; + ev->u.ctrl.flags = user_flags(ctrl); if (ctrl->is_ptr) ev->u.ctrl.value64 = 0; else @@ -2003,10 +2013,6 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, handler_set_err(hdl, err); return NULL; } - if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) { - handler_set_err(hdl, -ERANGE); - return NULL; - } if (is_array && (type == V4L2_CTRL_TYPE_BUTTON || type == V4L2_CTRL_TYPE_CTRL_CLASS)) { @@ -2577,10 +2583,8 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctr else qc->id = ctrl->id; strlcpy(qc->name, ctrl->name, sizeof(qc->name)); - qc->flags = ctrl->flags; + qc->flags = user_flags(ctrl); qc->type = ctrl->type; - if (ctrl->is_ptr) - qc->flags |= V4L2_CTRL_FLAG_HAS_PAYLOAD; qc->elem_size = ctrl->elem_size; qc->elems = ctrl->elems; qc->nr_of_dims = ctrl->nr_of_dims; @@ -2818,7 +2822,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl, static int class_check(struct v4l2_ctrl_handler *hdl, u32 which) { if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL) - return list_empty(&hdl->ctrl_refs) ? -EINVAL : 0; + return 0; return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL; } diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 40b2fbfe8865..681b192420d9 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -19,6 +19,7 @@ */ #include <linux/acpi.h> #include <linux/kernel.h> +#include <linux/mm.h> #include <linux/module.h> #include <linux/of.h> #include <linux/property.h> @@ -26,7 +27,9 @@ #include <linux/string.h> #include <linux/types.h> +#include <media/v4l2-async.h> #include <media/v4l2-fwnode.h> +#include <media/v4l2-subdev.h> enum v4l2_fwnode_bus_type { V4L2_FWNODE_BUS_TYPE_GUESS = 0, @@ -181,25 +184,6 @@ v4l2_fwnode_endpoint_parse_csi1_bus(struct fwnode_handle *fwnode, vep->bus_type = V4L2_MBUS_CSI1; } -/** - * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties - * @fwnode: pointer to the endpoint's fwnode handle - * @vep: pointer to the V4L2 fwnode data structure - * - * All properties are optional. If none are found, we don't set any flags. This - * means the port has a static configuration and no properties have to be - * specified explicitly. If any properties that identify the bus as parallel - * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if - * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we - * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a - * reference to @fwnode. - * - * NOTE: This function does not parse properties the size of which is variable - * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in - * new drivers instead. - * - * Return: 0 on success or a negative error code on failure. - */ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) { @@ -239,14 +223,6 @@ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_parse); -/* - * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by - * v4l2_fwnode_endpoint_alloc_parse() - * @vep - the V4L2 fwnode the resources of which are to be released - * - * It is safe to call this function with NULL argument or on a V4L2 fwnode the - * parsing of which failed. - */ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep) { if (IS_ERR_OR_NULL(vep)) @@ -257,29 +233,6 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep) } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free); -/** - * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties - * @fwnode: pointer to the endpoint's fwnode handle - * - * All properties are optional. If none are found, we don't set any flags. This - * means the port has a static configuration and no properties have to be - * specified explicitly. If any properties that identify the bus as parallel - * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if - * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we - * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a - * reference to @fwnode. - * - * v4l2_fwnode_endpoint_alloc_parse() has two important differences to - * v4l2_fwnode_endpoint_parse(): - * - * 1. It also parses variable size data. - * - * 2. The memory it has allocated to store the variable size data must be freed - * using v4l2_fwnode_endpoint_free() when no longer needed. - * - * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer - * on error. - */ struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( struct fwnode_handle *fwnode) { @@ -322,24 +275,6 @@ out_err: } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse); -/** - * v4l2_fwnode_endpoint_parse_link() - parse a link between two endpoints - * @__fwnode: pointer to the endpoint's fwnode at the local end of the link - * @link: pointer to the V4L2 fwnode link data structure - * - * Fill the link structure with the local and remote nodes and port numbers. - * The local_node and remote_node fields are set to point to the local and - * remote port's parent nodes respectively (the port parent node being the - * parent node of the port node if that node isn't a 'ports' node, or the - * grand-parent node of the port node otherwise). - * - * A reference is taken to both the local and remote nodes, the caller must use - * v4l2_fwnode_endpoint_put_link() to drop the references when done with the - * link. - * - * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be - * found. - */ int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode, struct v4l2_fwnode_link *link) { @@ -374,13 +309,6 @@ int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode, } EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link); -/** - * v4l2_fwnode_put_link() - drop references to nodes in a link - * @link: pointer to the V4L2 fwnode link data structure - * - * Drop references to the local and remote nodes in the link. This function - * must be called on every link parsed with v4l2_fwnode_parse_link(). - */ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) { fwnode_handle_put(link->local_node); @@ -388,6 +316,630 @@ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link) } EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link); +static int v4l2_async_notifier_realloc(struct v4l2_async_notifier *notifier, + unsigned int max_subdevs) +{ + struct v4l2_async_subdev **subdevs; + + if (max_subdevs <= notifier->max_subdevs) + return 0; + + subdevs = kvmalloc_array( + max_subdevs, sizeof(*notifier->subdevs), + GFP_KERNEL | __GFP_ZERO); + if (!subdevs) + return -ENOMEM; + + if (notifier->subdevs) { + memcpy(subdevs, notifier->subdevs, + sizeof(*subdevs) * notifier->num_subdevs); + + kvfree(notifier->subdevs); + } + + notifier->subdevs = subdevs; + notifier->max_subdevs = max_subdevs; + + return 0; +} + +static int v4l2_async_notifier_fwnode_parse_endpoint( + struct device *dev, struct v4l2_async_notifier *notifier, + struct fwnode_handle *endpoint, unsigned int asd_struct_size, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) +{ + struct v4l2_async_subdev *asd; + struct v4l2_fwnode_endpoint *vep; + int ret = 0; + + asd = kzalloc(asd_struct_size, GFP_KERNEL); + if (!asd) + return -ENOMEM; + + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + asd->match.fwnode.fwnode = + fwnode_graph_get_remote_port_parent(endpoint); + if (!asd->match.fwnode.fwnode) { + dev_warn(dev, "bad remote port parent\n"); + ret = -EINVAL; + goto out_err; + } + + vep = v4l2_fwnode_endpoint_alloc_parse(endpoint); + if (IS_ERR(vep)) { + ret = PTR_ERR(vep); + dev_warn(dev, "unable to parse V4L2 fwnode endpoint (%d)\n", + ret); + goto out_err; + } + + ret = parse_endpoint ? parse_endpoint(dev, vep, asd) : 0; + if (ret == -ENOTCONN) + dev_dbg(dev, "ignoring port@%u/endpoint@%u\n", vep->base.port, + vep->base.id); + else if (ret < 0) + dev_warn(dev, + "driver could not parse port@%u/endpoint@%u (%d)\n", + vep->base.port, vep->base.id, ret); + v4l2_fwnode_endpoint_free(vep); + if (ret < 0) + goto out_err; + + notifier->subdevs[notifier->num_subdevs] = asd; + notifier->num_subdevs++; + + return 0; + +out_err: + fwnode_handle_put(asd->match.fwnode.fwnode); + kfree(asd); + + return ret == -ENOTCONN ? 0 : ret; +} + +static int __v4l2_async_notifier_parse_fwnode_endpoints( + struct device *dev, struct v4l2_async_notifier *notifier, + size_t asd_struct_size, unsigned int port, bool has_port, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) +{ + struct fwnode_handle *fwnode; + unsigned int max_subdevs = notifier->max_subdevs; + int ret; + + if (WARN_ON(asd_struct_size < sizeof(struct v4l2_async_subdev))) + return -EINVAL; + + for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint( + dev_fwnode(dev), fwnode)); ) { + struct fwnode_handle *dev_fwnode; + bool is_available; + + dev_fwnode = fwnode_graph_get_port_parent(fwnode); + is_available = fwnode_device_is_available(dev_fwnode); + fwnode_handle_put(dev_fwnode); + if (!is_available) + continue; + + if (has_port) { + struct fwnode_endpoint ep; + + ret = fwnode_graph_parse_endpoint(fwnode, &ep); + if (ret) { + fwnode_handle_put(fwnode); + return ret; + } + + if (ep.port != port) + continue; + } + max_subdevs++; + } + + /* No subdevs to add? Return here. */ + if (max_subdevs == notifier->max_subdevs) + return 0; + + ret = v4l2_async_notifier_realloc(notifier, max_subdevs); + if (ret) + return ret; + + for (fwnode = NULL; (fwnode = fwnode_graph_get_next_endpoint( + dev_fwnode(dev), fwnode)); ) { + struct fwnode_handle *dev_fwnode; + bool is_available; + + dev_fwnode = fwnode_graph_get_port_parent(fwnode); + is_available = fwnode_device_is_available(dev_fwnode); + fwnode_handle_put(dev_fwnode); + if (!is_available) + continue; + + if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { + ret = -EINVAL; + break; + } + + if (has_port) { + struct fwnode_endpoint ep; + + ret = fwnode_graph_parse_endpoint(fwnode, &ep); + if (ret) + break; + + if (ep.port != port) + continue; + } + + ret = v4l2_async_notifier_fwnode_parse_endpoint( + dev, notifier, fwnode, asd_struct_size, parse_endpoint); + if (ret < 0) + break; + } + + fwnode_handle_put(fwnode); + + return ret; +} + +int v4l2_async_notifier_parse_fwnode_endpoints( + struct device *dev, struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) +{ + return __v4l2_async_notifier_parse_fwnode_endpoints( + dev, notifier, asd_struct_size, 0, false, parse_endpoint); +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints); + +int v4l2_async_notifier_parse_fwnode_endpoints_by_port( + struct device *dev, struct v4l2_async_notifier *notifier, + size_t asd_struct_size, unsigned int port, + int (*parse_endpoint)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd)) +{ + return __v4l2_async_notifier_parse_fwnode_endpoints( + dev, notifier, asd_struct_size, port, true, parse_endpoint); +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_endpoints_by_port); + +/* + * v4l2_fwnode_reference_parse - parse references for async sub-devices + * @dev: the device node the properties of which are parsed for references + * @notifier: the async notifier where the async subdevs will be added + * @prop: the name of the property + * + * Return: 0 on success + * -ENOENT if no entries were found + * -ENOMEM if memory allocation failed + * -EINVAL if property parsing failed + */ +static int v4l2_fwnode_reference_parse( + struct device *dev, struct v4l2_async_notifier *notifier, + const char *prop) +{ + struct fwnode_reference_args args; + unsigned int index; + int ret; + + for (index = 0; + !(ret = fwnode_property_get_reference_args( + dev_fwnode(dev), prop, NULL, 0, index, &args)); + index++) + fwnode_handle_put(args.fwnode); + + if (!index) + return -ENOENT; + + /* + * Note that right now both -ENODATA and -ENOENT may signal + * out-of-bounds access. Return the error in cases other than that. + */ + if (ret != -ENOENT && ret != -ENODATA) + return ret; + + ret = v4l2_async_notifier_realloc(notifier, + notifier->num_subdevs + index); + if (ret) + return ret; + + for (index = 0; !fwnode_property_get_reference_args( + dev_fwnode(dev), prop, NULL, 0, index, &args); + index++) { + struct v4l2_async_subdev *asd; + + if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { + ret = -EINVAL; + goto error; + } + + asd = kzalloc(sizeof(*asd), GFP_KERNEL); + if (!asd) { + ret = -ENOMEM; + goto error; + } + + notifier->subdevs[notifier->num_subdevs] = asd; + asd->match.fwnode.fwnode = args.fwnode; + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + notifier->num_subdevs++; + } + + return 0; + +error: + fwnode_handle_put(args.fwnode); + return ret; +} + +/* + * v4l2_fwnode_reference_get_int_prop - parse a reference with integer + * arguments + * @fwnode: fwnode to read @prop from + * @notifier: notifier for @dev + * @prop: the name of the property + * @index: the index of the reference to get + * @props: the array of integer property names + * @nprops: the number of integer property names in @nprops + * + * First find an fwnode referred to by the reference at @index in @prop. + * + * Then under that fwnode, @nprops times, for each property in @props, + * iteratively follow child nodes starting from fwnode such that they have the + * property in @props array at the index of the child node distance from the + * root node and the value of that property matching with the integer argument + * of the reference, at the same index. + * + * The child fwnode reched at the end of the iteration is then returned to the + * caller. + * + * The core reason for this is that you cannot refer to just any node in ACPI. + * So to refer to an endpoint (easy in DT) you need to refer to a device, then + * provide a list of (property name, property value) tuples where each tuple + * uniquely identifies a child node. The first tuple identifies a child directly + * underneath the device fwnode, the next tuple identifies a child node + * underneath the fwnode identified by the previous tuple, etc. until you + * reached the fwnode you need. + * + * An example with a graph, as defined in Documentation/acpi/dsd/graph.txt: + * + * Scope (\_SB.PCI0.I2C2) + * { + * Device (CAM0) + * { + * Name (_DSD, Package () { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + * Package () { + * Package () { + * "compatible", + * Package () { "nokia,smia" } + * }, + * }, + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + * Package () { + * Package () { "port0", "PRT0" }, + * } + * }) + * Name (PRT0, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + * Package () { + * Package () { "port", 0 }, + * }, + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + * Package () { + * Package () { "endpoint0", "EP00" }, + * } + * }) + * Name (EP00, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + * Package () { + * Package () { "endpoint", 0 }, + * Package () { + * "remote-endpoint", + * Package() { + * \_SB.PCI0.ISP, 4, 0 + * } + * }, + * } + * }) + * } + * } + * + * Scope (\_SB.PCI0) + * { + * Device (ISP) + * { + * Name (_DSD, Package () { + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + * Package () { + * Package () { "port4", "PRT4" }, + * } + * }) + * + * Name (PRT4, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + * Package () { + * Package () { "port", 4 }, + * }, + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + * Package () { + * Package () { "endpoint0", "EP40" }, + * } + * }) + * + * Name (EP40, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + * Package () { + * Package () { "endpoint", 0 }, + * Package () { + * "remote-endpoint", + * Package () { + * \_SB.PCI0.I2C2.CAM0, + * 0, 0 + * } + * }, + * } + * }) + * } + * } + * + * From the EP40 node under ISP device, you could parse the graph remote + * endpoint using v4l2_fwnode_reference_get_int_prop with these arguments: + * + * @fwnode: fwnode referring to EP40 under ISP. + * @prop: "remote-endpoint" + * @index: 0 + * @props: "port", "endpoint" + * @nprops: 2 + * + * And you'd get back fwnode referring to EP00 under CAM0. + * + * The same works the other way around: if you use EP00 under CAM0 as the + * fwnode, you'll get fwnode referring to EP40 under ISP. + * + * The same example in DT syntax would look like this: + * + * cam: cam0 { + * compatible = "nokia,smia"; + * + * port { + * port = <0>; + * endpoint { + * endpoint = <0>; + * remote-endpoint = <&isp 4 0>; + * }; + * }; + * }; + * + * isp: isp { + * ports { + * port@4 { + * port = <4>; + * endpoint { + * endpoint = <0>; + * remote-endpoint = <&cam 0 0>; + * }; + * }; + * }; + * }; + * + * Return: 0 on success + * -ENOENT if no entries (or the property itself) were found + * -EINVAL if property parsing otherwise failed + * -ENOMEM if memory allocation failed + */ +static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop( + struct fwnode_handle *fwnode, const char *prop, unsigned int index, + const char * const *props, unsigned int nprops) +{ + struct fwnode_reference_args fwnode_args; + unsigned int *args = fwnode_args.args; + struct fwnode_handle *child; + int ret; + + /* + * Obtain remote fwnode as well as the integer arguments. + * + * Note that right now both -ENODATA and -ENOENT may signal + * out-of-bounds access. Return -ENOENT in that case. + */ + ret = fwnode_property_get_reference_args(fwnode, prop, NULL, nprops, + index, &fwnode_args); + if (ret) + return ERR_PTR(ret == -ENODATA ? -ENOENT : ret); + + /* + * Find a node in the tree under the referred fwnode corresponding to + * the integer arguments. + */ + fwnode = fwnode_args.fwnode; + while (nprops--) { + u32 val; + + /* Loop over all child nodes under fwnode. */ + fwnode_for_each_child_node(fwnode, child) { + if (fwnode_property_read_u32(child, *props, &val)) + continue; + + /* Found property, see if its value matches. */ + if (val == *args) + break; + } + + fwnode_handle_put(fwnode); + + /* No property found; return an error here. */ + if (!child) { + fwnode = ERR_PTR(-ENOENT); + break; + } + + props++; + args++; + fwnode = child; + } + + return fwnode; +} + +/* + * v4l2_fwnode_reference_parse_int_props - parse references for async + * sub-devices + * @dev: struct device pointer + * @notifier: notifier for @dev + * @prop: the name of the property + * @props: the array of integer property names + * @nprops: the number of integer properties + * + * Use v4l2_fwnode_reference_get_int_prop to find fwnodes through reference in + * property @prop with integer arguments with child nodes matching in properties + * @props. Then, set up V4L2 async sub-devices for those fwnodes in the notifier + * accordingly. + * + * While it is technically possible to use this function on DT, it is only + * meaningful on ACPI. On Device tree you can refer to any node in the tree but + * on ACPI the references are limited to devices. + * + * Return: 0 on success + * -ENOENT if no entries (or the property itself) were found + * -EINVAL if property parsing otherwisefailed + * -ENOMEM if memory allocation failed + */ +static int v4l2_fwnode_reference_parse_int_props( + struct device *dev, struct v4l2_async_notifier *notifier, + const char *prop, const char * const *props, unsigned int nprops) +{ + struct fwnode_handle *fwnode; + unsigned int index; + int ret; + + for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop( + dev_fwnode(dev), prop, index, props, + nprops))); index++) + fwnode_handle_put(fwnode); + + /* + * Note that right now both -ENODATA and -ENOENT may signal + * out-of-bounds access. Return the error in cases other than that. + */ + if (PTR_ERR(fwnode) != -ENOENT && PTR_ERR(fwnode) != -ENODATA) + return PTR_ERR(fwnode); + + ret = v4l2_async_notifier_realloc(notifier, + notifier->num_subdevs + index); + if (ret) + return -ENOMEM; + + for (index = 0; !IS_ERR((fwnode = v4l2_fwnode_reference_get_int_prop( + dev_fwnode(dev), prop, index, props, + nprops))); index++) { + struct v4l2_async_subdev *asd; + + if (WARN_ON(notifier->num_subdevs >= notifier->max_subdevs)) { + ret = -EINVAL; + goto error; + } + + asd = kzalloc(sizeof(struct v4l2_async_subdev), GFP_KERNEL); + if (!asd) { + ret = -ENOMEM; + goto error; + } + + notifier->subdevs[notifier->num_subdevs] = asd; + asd->match.fwnode.fwnode = fwnode; + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + notifier->num_subdevs++; + } + + return PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode); + +error: + fwnode_handle_put(fwnode); + return ret; +} + +int v4l2_async_notifier_parse_fwnode_sensor_common( + struct device *dev, struct v4l2_async_notifier *notifier) +{ + static const char * const led_props[] = { "led" }; + static const struct { + const char *name; + const char * const *props; + unsigned int nprops; + } props[] = { + { "flash-leds", led_props, ARRAY_SIZE(led_props) }, + { "lens-focus", NULL, 0 }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(props); i++) { + int ret; + + if (props[i].props && is_acpi_node(dev_fwnode(dev))) + ret = v4l2_fwnode_reference_parse_int_props( + dev, notifier, props[i].name, + props[i].props, props[i].nprops); + else + ret = v4l2_fwnode_reference_parse( + dev, notifier, props[i].name); + if (ret && ret != -ENOENT) { + dev_warn(dev, "parsing property \"%s\" failed (%d)\n", + props[i].name, ret); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common); + +int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd) +{ + struct v4l2_async_notifier *notifier; + int ret; + + if (WARN_ON(!sd->dev)) + return -ENODEV; + + notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); + if (!notifier) + return -ENOMEM; + + ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev, + notifier); + if (ret < 0) + goto out_cleanup; + + ret = v4l2_async_subdev_notifier_register(sd, notifier); + if (ret < 0) + goto out_cleanup; + + ret = v4l2_async_register_subdev(sd); + if (ret < 0) + goto out_unregister; + + sd->subdev_notifier = notifier; + + return 0; + +out_unregister: + v4l2_async_notifier_unregister(notifier); + +out_cleanup: + v4l2_async_notifier_cleanup(notifier); + kfree(notifier); + + return ret; +} +EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>"); MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index b60a6b0841d1..79614992ee21 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -730,9 +730,12 @@ static void v4l_print_frmsizeenum(const void *arg, bool write_only) break; case V4L2_FRMSIZE_TYPE_STEPWISE: pr_cont(", min=%ux%u, max=%ux%u, step=%ux%u\n", - p->stepwise.min_width, p->stepwise.min_height, - p->stepwise.step_width, p->stepwise.step_height, - p->stepwise.max_width, p->stepwise.max_height); + p->stepwise.min_width, + p->stepwise.min_height, + p->stepwise.max_width, + p->stepwise.max_height, + p->stepwise.step_width, + p->stepwise.step_height); break; case V4L2_FRMSIZE_TYPE_CONTINUOUS: /* fall through */ diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig index 8eb13c3ba29c..27f078749148 100644 --- a/drivers/staging/media/atomisp/Kconfig +++ b/drivers/staging/media/atomisp/Kconfig @@ -1,9 +1,10 @@ menuconfig INTEL_ATOMISP - bool "Enable support to Intel MIPI camera drivers" - depends on X86 && EFI && MEDIA_CONTROLLER && PCI && ACPI - help - Enable support for the Intel ISP2 camera interfaces and MIPI - sensor drivers. + bool "Enable support to Intel MIPI camera drivers" + depends on X86 && EFI && MEDIA_CONTROLLER && PCI && ACPI + select COMMON_CLK + help + Enable support for the Intel ISP2 camera interfaces and MIPI + sensor drivers. if INTEL_ATOMISP source "drivers/staging/media/atomisp/pci/Kconfig" diff --git a/drivers/staging/media/atomisp/TODO b/drivers/staging/media/atomisp/TODO index 737452cbf8a0..255ce3630c2a 100644 --- a/drivers/staging/media/atomisp/TODO +++ b/drivers/staging/media/atomisp/TODO @@ -36,13 +36,23 @@ there are any specific things that can be done to fold in support for multiple firmware versions. +8. Switch to V4L2 async API to set up sensor, lens and flash devices. + Control those devices using V4L2 sub-device API without custom + extensions. -Limitations: +9. Switch to standard V4L2 sub-device API for sensor and lens. In + particular, the user space API needs to support V4L2 controls as + defined in the V4L2 spec and references to atomisp must be removed from + these drivers. + +10. Use LED flash API for flash LED drivers such as LM3554 (which already + has a LED class driver). -1. Currently the patch only support some camera sensors - gc2235/gc0310/0v2680/ov2722/ov5693/mt9m114... +11. Switch from videobuf1 to videobuf2. Videobuf1 is being removed! + +Limitations: -2. To test the patches, you also need the ISP firmware +1. To test the patches, you also need the ISP firmware for BYT:/lib/firmware/shisp_2400b0_v21.bin for CHT:/lib/firmware/shisp_2401a0_v21.bin @@ -51,14 +61,14 @@ Limitations: device but can also be extracted from the upgrade kit if you've managed to lose them somehow. -3. Without a 3A libary the capture behaviour is not very good. To take a good +2. Without a 3A libary the capture behaviour is not very good. To take a good picture, you need tune ISP parameters by IOCTL functions or use a 3A libary such as libxcam. -4. The driver is intended to drive the PCI exposed versions of the device. +3. The driver is intended to drive the PCI exposed versions of the device. It will not detect those devices enumerated via ACPI as a field of the i915 GPU driver. -5. The driver supports only v2 of the IPU/Camera. It will not work with the +4. The driver supports only v2 of the IPU/Camera. It will not work with the versions of the hardware in other SoCs. diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig index b80d29d53e65..db054d3c7ed6 100644 --- a/drivers/staging/media/atomisp/i2c/Kconfig +++ b/drivers/staging/media/atomisp/i2c/Kconfig @@ -3,104 +3,96 @@ # source "drivers/staging/media/atomisp/i2c/ov5693/Kconfig" -source "drivers/staging/media/atomisp/i2c/imx/Kconfig" -config VIDEO_OV2722 +config VIDEO_ATOMISP_OV2722 tristate "OVT ov2722 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 ---help--- - This is a Video4Linux2 sensor-level driver for the OVT - OV2722 raw camera. + This is a Video4Linux2 sensor-level driver for the OVT + OV2722 raw camera. - OVT is a 2M raw sensor. + OVT is a 2M raw sensor. - It currently only works with the atomisp driver. + It currently only works with the atomisp driver. -config VIDEO_GC2235 +config VIDEO_ATOMISP_GC2235 tristate "Galaxy gc2235 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 ---help--- - This is a Video4Linux2 sensor-level driver for the OVT - GC2235 raw camera. + This is a Video4Linux2 sensor-level driver for the OVT + GC2235 raw camera. - GC2235 is a 2M raw sensor. + GC2235 is a 2M raw sensor. - It currently only works with the atomisp driver. + It currently only works with the atomisp driver. -config VIDEO_OV8858 +config VIDEO_ATOMISP_OV8858 tristate "Omnivision ov8858 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 && VIDEO_ATOMISP ---help--- - This is a Video4Linux2 sensor-level driver for the Omnivision - ov8858 RAW sensor. + This is a Video4Linux2 sensor-level driver for the Omnivision + ov8858 RAW sensor. OV8858 is a 8M raw sensor. - It currently only works with the atomisp driver. + It currently only works with the atomisp driver. -config VIDEO_MSRLIST_HELPER +config VIDEO_ATOMISP_MSRLIST_HELPER tristate "Helper library to load, parse and apply large register lists." depends on I2C ---help--- - This is a helper library to be used from a sensor driver to load, parse - and apply large register lists. + This is a helper library to be used from a sensor driver to load, parse + and apply large register lists. - To compile this driver as a module, choose M here: the - module will be called libmsrlisthelper. + To compile this driver as a module, choose M here: the + module will be called libmsrlisthelper. -config VIDEO_MT9M114 +config VIDEO_ATOMISP_MT9M114 tristate "Aptina mt9m114 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 ---help--- - This is a Video4Linux2 sensor-level driver for the Micron - mt9m114 1.3 Mpixel camera. + This is a Video4Linux2 sensor-level driver for the Micron + mt9m114 1.3 Mpixel camera. - mt9m114 is video camera sensor. + mt9m114 is video camera sensor. - It currently only works with the atomisp driver. + It currently only works with the atomisp driver. -config VIDEO_AP1302 - tristate "AP1302 external ISP support" - depends on I2C && VIDEO_V4L2 - select REGMAP_I2C - ---help--- - This is a Video4Linux2 sensor-level driver for the external - ISP AP1302. - - AP1302 is an exteral ISP. - - It currently only works with the atomisp driver. - -config VIDEO_GC0310 +config VIDEO_ATOMISP_GC0310 tristate "GC0310 sensor support" - depends on I2C && VIDEO_V4L2 - ---help--- - This is a Video4Linux2 sensor-level driver for the Galaxycore - GC0310 0.3MP sensor. + depends on ACPI + depends on I2C && VIDEO_V4L2 + ---help--- + This is a Video4Linux2 sensor-level driver for the Galaxycore + GC0310 0.3MP sensor. -config VIDEO_OV2680 +config VIDEO_ATOMISP_OV2680 tristate "Omnivision OV2680 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 ---help--- - This is a Video4Linux2 sensor-level driver for the Omnivision - OV2680 raw camera. + This is a Video4Linux2 sensor-level driver for the Omnivision + OV2680 raw camera. - ov2680 is a 2M raw sensor. + ov2680 is a 2M raw sensor. - It currently only works with the atomisp driver. + It currently only works with the atomisp driver. # # Kconfig for flash drivers # -config VIDEO_LM3554 +config VIDEO_ATOMISP_LM3554 tristate "LM3554 flash light driver" + depends on ACPI depends on VIDEO_V4L2 && I2C ---help--- - This is a Video4Linux2 sub-dev driver for the LM3554 - flash light driver. - - To compile this driver as a module, choose M here: the - module will be called lm3554 - + This is a Video4Linux2 sub-dev driver for the LM3554 + flash light driver. + To compile this driver as a module, choose M here: the + module will be called lm3554 diff --git a/drivers/staging/media/atomisp/i2c/Makefile b/drivers/staging/media/atomisp/i2c/Makefile index 041a041718d2..99ea35c043fd 100644 --- a/drivers/staging/media/atomisp/i2c/Makefile +++ b/drivers/staging/media/atomisp/i2c/Makefile @@ -3,22 +3,19 @@ # Makefile for sensor drivers # -obj-$(CONFIG_VIDEO_IMX) += imx/ -obj-$(CONFIG_VIDEO_OV5693) += ov5693/ -obj-$(CONFIG_VIDEO_MT9M114) += mt9m114.o -obj-$(CONFIG_VIDEO_GC2235) += gc2235.o -obj-$(CONFIG_VIDEO_OV2722) += ov2722.o -obj-$(CONFIG_VIDEO_OV2680) += ov2680.o -obj-$(CONFIG_VIDEO_GC0310) += gc0310.o +obj-$(CONFIG_VIDEO_ATOMISP_OV5693) += ov5693/ +obj-$(CONFIG_VIDEO_ATOMISP_MT9M114) += atomisp-mt9m114.o +obj-$(CONFIG_VIDEO_ATOMISP_GC2235) += atomisp-gc2235.o +obj-$(CONFIG_VIDEO_ATOMISP_OV2722) += atomisp-ov2722.o +obj-$(CONFIG_VIDEO_ATOMISP_OV2680) += atomisp-ov2680.o +obj-$(CONFIG_VIDEO_ATOMISP_GC0310) += atomisp-gc0310.o -obj-$(CONFIG_VIDEO_MSRLIST_HELPER) += libmsrlisthelper.o - -obj-$(CONFIG_VIDEO_AP1302) += ap1302.o +obj-$(CONFIG_VIDEO_ATOMISP_MSRLIST_HELPER) += atomisp-libmsrlisthelper.o # Makefile for flash drivers # -obj-$(CONFIG_VIDEO_LM3554) += lm3554.o +obj-$(CONFIG_VIDEO_ATOMISP_LM3554) += atomisp-lm3554.o # HACK! While this driver is in bad shape, don't enable several warnings # that would be otherwise enabled with W=1 diff --git a/drivers/staging/media/atomisp/i2c/ap1302.c b/drivers/staging/media/atomisp/i2c/ap1302.c deleted file mode 100644 index 2f772a020c8b..000000000000 --- a/drivers/staging/media/atomisp/i2c/ap1302.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "../include/linux/atomisp.h" -#include <linux/delay.h> -#include <linux/firmware.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/types.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include "ap1302.h" - -#define to_ap1302_device(sub_dev) \ - container_of(sub_dev, struct ap1302_device, sd) - -/* Static definitions */ -static struct regmap_config ap1302_reg16_config = { - .reg_bits = 16, - .val_bits = 16, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_BIG, -}; - -static struct regmap_config ap1302_reg32_config = { - .reg_bits = 16, - .val_bits = 32, - .reg_format_endian = REGMAP_ENDIAN_BIG, - .val_format_endian = REGMAP_ENDIAN_BIG, -}; - -static enum ap1302_contexts ap1302_cntx_mapping[] = { - CONTEXT_PREVIEW, /* Invalid atomisp run mode */ - CONTEXT_VIDEO, /* ATOMISP_RUN_MODE_VIDEO */ - CONTEXT_SNAPSHOT, /* ATOMISP_RUN_MODE_STILL_CAPTURE */ - CONTEXT_SNAPSHOT, /* ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE */ - CONTEXT_PREVIEW, /* ATOMISP_RUN_MODE_PREVIEW */ -}; - -static struct ap1302_res_struct ap1302_preview_res[] = { - { - .width = 640, - .height = 480, - .fps = 30, - }, - { - .width = 720, - .height = 480, - .fps = 30, - }, - { - .width = 1280, - .height = 720, - .fps = 30, - }, - { - .width = 1920, - .height = 1080, - .fps = 30, - } -}; - -static struct ap1302_res_struct ap1302_snapshot_res[] = { - { - .width = 640, - .height = 480, - .fps = 30, - }, - { - .width = 720, - .height = 480, - .fps = 30, - }, - { - .width = 1280, - .height = 720, - .fps = 30, - }, - { - .width = 1920, - .height = 1080, - .fps = 30, - } -}; - -static struct ap1302_res_struct ap1302_video_res[] = { - { - .width = 640, - .height = 480, - .fps = 30, - }, - { - .width = 720, - .height = 480, - .fps = 30, - }, - { - .width = 1280, - .height = 720, - .fps = 30, - }, - { - .width = 1920, - .height = 1080, - .fps = 30, - } -}; - -static enum ap1302_contexts stream_to_context[] = { - CONTEXT_SNAPSHOT, - CONTEXT_PREVIEW, - CONTEXT_PREVIEW, - CONTEXT_VIDEO -}; - -static u16 aux_stream_config[CONTEXT_NUM][CONTEXT_NUM] = { - {0, 0, 0}, /* Preview: No aux streams. */ - {1, 0, 2}, /* Snapshot: 1 for postview. 2 for video */ - {1, 0, 0}, /* Video: 1 for preview. */ -}; - -static struct ap1302_context_info context_info[] = { - {CNTX_WIDTH, AP1302_REG16, "width"}, - {CNTX_HEIGHT, AP1302_REG16, "height"}, - {CNTX_ROI_X0, AP1302_REG16, "roi_x0"}, - {CNTX_ROI_X1, AP1302_REG16, "roi_x1"}, - {CNTX_ROI_Y0, AP1302_REG16, "roi_y0"}, - {CNTX_ROI_Y1, AP1302_REG16, "roi_y1"}, - {CNTX_ASPECT, AP1302_REG16, "aspect"}, - {CNTX_LOCK, AP1302_REG16, "lock"}, - {CNTX_ENABLE, AP1302_REG16, "enable"}, - {CNTX_OUT_FMT, AP1302_REG16, "out_fmt"}, - {CNTX_SENSOR_MODE, AP1302_REG16, "sensor_mode"}, - {CNTX_MIPI_CTRL, AP1302_REG16, "mipi_ctrl"}, - {CNTX_MIPI_II_CTRL, AP1302_REG16, "mipi_ii_ctrl"}, - {CNTX_LINE_TIME, AP1302_REG32, "line_time"}, - {CNTX_MAX_FPS, AP1302_REG16, "max_fps"}, - {CNTX_AE_USG, AP1302_REG16, "ae_usg"}, - {CNTX_AE_UPPER_ET, AP1302_REG32, "ae_upper_et"}, - {CNTX_AE_MAX_ET, AP1302_REG32, "ae_max_et"}, - {CNTX_SS, AP1302_REG16, "ss"}, - {CNTX_S1_SENSOR_MODE, AP1302_REG16, "s1_sensor_mode"}, - {CNTX_HINF_CTRL, AP1302_REG16, "hinf_ctrl"}, -}; - -/* This array stores the description list for metadata. - The metadata contains exposure settings and face - detection results. */ -static u16 ap1302_ss_list[] = { - 0xb01c, /* From 0x0186 with size 0x1C are exposure settings. */ - 0x0186, - 0xb002, /* 0x71c0 is for F-number */ - 0x71c0, - 0xb010, /* From 0x03dc with size 0x10 are face general infos. */ - 0x03dc, - 0xb0a0, /* From 0x03e4 with size 0xa0 are face detail infos. */ - 0x03e4, - 0xb020, /* From 0x0604 with size 0x20 are smile rate infos. */ - 0x0604, - 0x0000 -}; - -/* End of static definitions */ - -static int ap1302_i2c_read_reg(struct v4l2_subdev *sd, - u16 reg, u16 len, void *val) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (len == AP1302_REG16) - ret = regmap_read(dev->regmap16, reg, val); - else if (len == AP1302_REG32) - ret = regmap_read(dev->regmap32, reg, val); - else - ret = -EINVAL; - if (ret) { - dev_dbg(&client->dev, "Read reg failed. reg=0x%04X\n", reg); - return ret; - } - if (len == AP1302_REG16) - dev_dbg(&client->dev, "read_reg[0x%04X] = 0x%04X\n", - reg, *(u16 *)val); - else - dev_dbg(&client->dev, "read_reg[0x%04X] = 0x%08X\n", - reg, *(u32 *)val); - return ret; -} - -static int ap1302_i2c_write_reg(struct v4l2_subdev *sd, - u16 reg, u16 len, u32 val) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - if (len == AP1302_REG16) - ret = regmap_write(dev->regmap16, reg, val); - else if (len == AP1302_REG32) - ret = regmap_write(dev->regmap32, reg, val); - else - ret = -EINVAL; - if (ret) { - dev_dbg(&client->dev, "Write reg failed. reg=0x%04X\n", reg); - return ret; - } - if (len == AP1302_REG16) - dev_dbg(&client->dev, "write_reg[0x%04X] = 0x%04X\n", - reg, (u16)val); - else - dev_dbg(&client->dev, "write_reg[0x%04X] = 0x%08X\n", - reg, (u32)val); - return ret; -} - -static u16 -ap1302_calculate_context_reg_addr(enum ap1302_contexts context, u16 offset) -{ - u16 reg_addr; - /* The register offset is defined according to preview/video registers. - Preview and video context have the same register definition. - But snapshot context does not have register S1_SENSOR_MODE. - When setting snapshot registers, if the offset exceeds - S1_SENSOR_MODE, the actual offset needs to minus 2. */ - if (context == CONTEXT_SNAPSHOT) { - if (offset == CNTX_S1_SENSOR_MODE) - return 0; - if (offset > CNTX_S1_SENSOR_MODE) - offset -= 2; - } - if (context == CONTEXT_PREVIEW) - reg_addr = REG_PREVIEW_BASE + offset; - else if (context == CONTEXT_VIDEO) - reg_addr = REG_VIDEO_BASE + offset; - else - reg_addr = REG_SNAPSHOT_BASE + offset; - return reg_addr; -} - -static int ap1302_read_context_reg(struct v4l2_subdev *sd, - enum ap1302_contexts context, u16 offset, u16 len) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - u16 reg_addr = ap1302_calculate_context_reg_addr(context, offset); - if (reg_addr == 0) - return -EINVAL; - return ap1302_i2c_read_reg(sd, reg_addr, len, - ((u8 *)&dev->cntx_config[context]) + offset); -} - -static int ap1302_write_context_reg(struct v4l2_subdev *sd, - enum ap1302_contexts context, u16 offset, u16 len) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - u16 reg_addr = ap1302_calculate_context_reg_addr(context, offset); - if (reg_addr == 0) - return -EINVAL; - return ap1302_i2c_write_reg(sd, reg_addr, len, - *(u32 *)(((u8 *)&dev->cntx_config[context]) + offset)); -} - -static int ap1302_dump_context_reg(struct v4l2_subdev *sd, - enum ap1302_contexts context) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ap1302_device *dev = to_ap1302_device(sd); - int i; - dev_dbg(&client->dev, "Dump registers for context[%d]:\n", context); - for (i = 0; i < ARRAY_SIZE(context_info); i++) { - struct ap1302_context_info *info = &context_info[i]; - u8 *var = (u8 *)&dev->cntx_config[context] + info->offset; - /* Snapshot context does not have s1_sensor_mode register. */ - if (context == CONTEXT_SNAPSHOT && - info->offset == CNTX_S1_SENSOR_MODE) - continue; - ap1302_read_context_reg(sd, context, info->offset, info->len); - if (info->len == AP1302_REG16) - dev_dbg(&client->dev, "context.%s = 0x%04X (%d)\n", - info->name, *(u16 *)var, *(u16 *)var); - else - dev_dbg(&client->dev, "context.%s = 0x%08X (%d)\n", - info->name, *(u32 *)var, *(u32 *)var); - } - return 0; -} - -static int ap1302_request_firmware(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ap1302_device *dev = to_ap1302_device(sd); - int ret; - ret = request_firmware(&dev->fw, "ap1302_fw.bin", &client->dev); - if (ret) - dev_err(&client->dev, - "ap1302_request_firmware failed. ret=%d\n", ret); - return ret; -} - -/* When loading firmware, host writes firmware data from address 0x8000. - When the address reaches 0x9FFF, the next address should return to 0x8000. - This function handles this address window and load firmware data to AP1302. - win_pos indicates the offset within this window. Firmware loading procedure - may call this function several times. win_pos records the current position - that has been written to.*/ -static int ap1302_write_fw_window(struct v4l2_subdev *sd, - u16 *win_pos, const u8 *buf, u32 len) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - int ret; - u32 pos; - u32 sub_len; - for (pos = 0; pos < len; pos += sub_len) { - if (len - pos < AP1302_FW_WINDOW_SIZE - *win_pos) - sub_len = len - pos; - else - sub_len = AP1302_FW_WINDOW_SIZE - *win_pos; - ret = regmap_raw_write(dev->regmap16, - *win_pos + AP1302_FW_WINDOW_OFFSET, - buf + pos, sub_len); - if (ret) - return ret; - *win_pos += sub_len; - if (*win_pos >= AP1302_FW_WINDOW_SIZE) - *win_pos = 0; - } - return 0; -} - -static int ap1302_load_firmware(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ap1302_device *dev = to_ap1302_device(sd); - const struct ap1302_firmware *fw; - const u8 *fw_data; - u16 reg_val = 0; - u16 win_pos = 0; - int ret; - - dev_info(&client->dev, "Start to load firmware.\n"); - if (!dev->fw) { - dev_err(&client->dev, "firmware not requested.\n"); - return -EINVAL; - } - fw = (const struct ap1302_firmware *) dev->fw->data; - if (dev->fw->size != (sizeof(*fw) + fw->total_size)) { - dev_err(&client->dev, "firmware size does not match.\n"); - return -EINVAL; - } - /* The fw binary contains a header of struct ap1302_firmware. - Following the header is the bootdata of AP1302. - The bootdata pointer can be referenced as &fw[1]. */ - fw_data = (u8 *)&fw[1]; - - /* Clear crc register. */ - ret = ap1302_i2c_write_reg(sd, REG_SIP_CRC, AP1302_REG16, 0xFFFF); - if (ret) - return ret; - - /* Load FW data for PLL init stage. */ - ret = ap1302_write_fw_window(sd, &win_pos, fw_data, fw->pll_init_size); - if (ret) - return ret; - - /* Write 2 to bootdata_stage register to apply basic_init_hp - settings and enable PLL. */ - ret = ap1302_i2c_write_reg(sd, REG_BOOTDATA_STAGE, - AP1302_REG16, 0x0002); - if (ret) - return ret; - - /* Wait 1ms for PLL to lock. */ - msleep(20); - - /* Load the rest of bootdata content. */ - ret = ap1302_write_fw_window(sd, &win_pos, fw_data + fw->pll_init_size, - fw->total_size - fw->pll_init_size); - if (ret) - return ret; - - /* Check crc. */ - ret = ap1302_i2c_read_reg(sd, REG_SIP_CRC, AP1302_REG16, ®_val); - if (ret) - return ret; - if (reg_val != fw->crc) { - dev_err(&client->dev, - "crc does not match. T:0x%04X F:0x%04X\n", - fw->crc, reg_val); - return -EAGAIN; - } - - /* Write 0xFFFF to bootdata_stage register to indicate AP1302 that - the whole bootdata content has been loaded. */ - ret = ap1302_i2c_write_reg(sd, REG_BOOTDATA_STAGE, - AP1302_REG16, 0xFFFF); - if (ret) - return ret; - dev_info(&client->dev, "Load firmware successfully.\n"); - - return 0; -} - -static int __ap1302_s_power(struct v4l2_subdev *sd, int on, int load_fw) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret, i; - u16 ss_ptr; - - dev_info(&client->dev, "ap1302_s_power is called.\n"); - ret = dev->platform_data->power_ctrl(sd, on); - if (ret) { - dev_err(&client->dev, - "ap1302_s_power error. on=%d ret=%d\n", on, ret); - return ret; - } - dev->power_on = on; - if (!on || !load_fw) - return 0; - /* Load firmware after power on. */ - ret = ap1302_load_firmware(sd); - if (ret) { - dev_err(&client->dev, - "ap1302_load_firmware failed. ret=%d\n", ret); - return ret; - } - ret = ap1302_i2c_read_reg(sd, REG_SS_HEAD_PT0, AP1302_REG16, &ss_ptr); - if (ret) - return ret; - for (i = 0; i < ARRAY_SIZE(ap1302_ss_list); i++) { - ret = ap1302_i2c_write_reg(sd, ss_ptr + i * 2, - AP1302_REG16, ap1302_ss_list[i]); - if (ret) - return ret; - } - return ret; -} - -static int ap1302_s_power(struct v4l2_subdev *sd, int on) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - int ret; - - mutex_lock(&dev->input_lock); - ret = __ap1302_s_power(sd, on, 1); - dev->sys_activated = 0; - mutex_unlock(&dev->input_lock); - - return ret; -} - -static int ap1302_s_config(struct v4l2_subdev *sd, void *pdata) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct camera_mipi_info *mipi_info; - u16 reg_val = 0; - int ret; - - dev_info(&client->dev, "ap1302_s_config is called.\n"); - if (pdata == NULL) - return -ENODEV; - - dev->platform_data = pdata; - - mutex_lock(&dev->input_lock); - - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) - goto fail_power; - } - - ret = __ap1302_s_power(sd, 1, 0); - if (ret) - goto fail_power; - - /* Detect for AP1302 */ - ret = ap1302_i2c_read_reg(sd, REG_CHIP_VERSION, AP1302_REG16, ®_val); - if (ret || (reg_val != AP1302_CHIP_ID)) { - dev_err(&client->dev, - "Chip version does no match. ret=%d ver=0x%04x\n", - ret, reg_val); - goto fail_config; - } - dev_info(&client->dev, "AP1302 Chip ID is 0x%X\n", reg_val); - - /* Detect revision for AP1302 */ - ret = ap1302_i2c_read_reg(sd, REG_CHIP_REV, AP1302_REG16, ®_val); - if (ret) - goto fail_config; - dev_info(&client->dev, "AP1302 Chip Rev is 0x%X\n", reg_val); - ret = dev->platform_data->csi_cfg(sd, 1); - if (ret) - goto fail_config; - - mipi_info = v4l2_get_subdev_hostdata(sd); - if (!mipi_info) - goto fail_config; - dev->num_lanes = mipi_info->num_lanes; - - ret = __ap1302_s_power(sd, 0, 0); - if (ret) - goto fail_power; - - mutex_unlock(&dev->input_lock); - - return ret; - -fail_config: - __ap1302_s_power(sd, 0, 0); -fail_power: - mutex_unlock(&dev->input_lock); - dev_err(&client->dev, "ap1302_s_config failed\n"); - return ret; -} - -static enum ap1302_contexts ap1302_get_context(struct v4l2_subdev *sd) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - return dev->cur_context; -} - -static int ap1302_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) -{ - if (code->index) - return -EINVAL; - - code->code = MEDIA_BUS_FMT_UYVY8_1X16; - - return 0; -} - -static int ap1302_match_resolution(struct ap1302_context_res *res, - struct v4l2_mbus_framefmt *fmt) -{ - s32 w0, h0, mismatch, distance; - s32 w1 = fmt->width; - s32 h1 = fmt->height; - s32 min_distance = INT_MAX; - s32 i, idx = -1; - - if (w1 == 0 || h1 == 0) - return -1; - - for (i = 0; i < res->res_num; i++) { - w0 = res->res_table[i].width; - h0 = res->res_table[i].height; - if (w0 < w1 || h0 < h1) - continue; - mismatch = abs(w0 * h1 - w1 * h0) * 8192 / w1 / h0; - if (mismatch > 8192 * AP1302_MAX_RATIO_MISMATCH / 100) - continue; - distance = (w0 * h1 + w1 * h0) * 8192 / w1 / h1; - if (distance < min_distance) { - min_distance = distance; - idx = i; - } - } - - return idx; -} - -static s32 ap1302_try_mbus_fmt_locked(struct v4l2_subdev *sd, - enum ap1302_contexts context, - struct v4l2_mbus_framefmt *fmt) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct ap1302_res_struct *res_table; - s32 res_num, idx = -1; - - res_table = dev->cntx_res[context].res_table; - res_num = dev->cntx_res[context].res_num; - - if ((fmt->width <= res_table[res_num - 1].width) && - (fmt->height <= res_table[res_num - 1].height)) - idx = ap1302_match_resolution(&dev->cntx_res[context], fmt); - if (idx == -1) - idx = res_num - 1; - - fmt->width = res_table[idx].width; - fmt->height = res_table[idx].height; - fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; - return idx; -} - - -static int ap1302_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) - -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - struct ap1302_device *dev = to_ap1302_device(sd); - enum ap1302_contexts context; - struct ap1302_res_struct *res_table; - s32 cur_res; - if (format->pad) - return -EINVAL; - mutex_lock(&dev->input_lock); - context = ap1302_get_context(sd); - res_table = dev->cntx_res[context].res_table; - cur_res = dev->cntx_res[context].cur_res; - fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; - fmt->width = res_table[cur_res].width; - fmt->height = res_table[cur_res].height; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int ap1302_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct atomisp_input_stream_info *stream_info = - (struct atomisp_input_stream_info *)fmt->reserved; - enum ap1302_contexts context, main_context; - if (format->pad) - return -EINVAL; - if (!fmt) - return -EINVAL; - mutex_lock(&dev->input_lock); - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - context = ap1302_get_context(sd); - ap1302_try_mbus_fmt_locked(sd, context, fmt); - cfg->try_fmt = *fmt; - mutex_unlock(&dev->input_lock); - return 0; - } - context = stream_to_context[stream_info->stream]; - dev_dbg(&client->dev, "ap1302_set_mbus_fmt. stream=%d context=%d\n", - stream_info->stream, context); - dev->cntx_res[context].cur_res = - ap1302_try_mbus_fmt_locked(sd, context, fmt); - dev->cntx_config[context].width = fmt->width; - dev->cntx_config[context].height = fmt->height; - ap1302_write_context_reg(sd, context, CNTX_WIDTH, AP1302_REG16); - ap1302_write_context_reg(sd, context, CNTX_HEIGHT, AP1302_REG16); - ap1302_read_context_reg(sd, context, CNTX_OUT_FMT, AP1302_REG16); - dev->cntx_config[context].out_fmt &= ~OUT_FMT_TYPE_MASK; - dev->cntx_config[context].out_fmt |= AP1302_FMT_UYVY422; - ap1302_write_context_reg(sd, context, CNTX_OUT_FMT, AP1302_REG16); - - main_context = ap1302_get_context(sd); - if (context == main_context) { - ap1302_read_context_reg(sd, context, - CNTX_MIPI_CTRL, AP1302_REG16); - dev->cntx_config[context].mipi_ctrl &= ~MIPI_CTRL_IMGVC_MASK; - dev->cntx_config[context].mipi_ctrl |= - (context << MIPI_CTRL_IMGVC_OFFSET); - dev->cntx_config[context].mipi_ctrl &= ~MIPI_CTRL_SSVC_MASK; - dev->cntx_config[context].mipi_ctrl |= - (context << MIPI_CTRL_SSVC_OFFSET); - dev->cntx_config[context].mipi_ctrl &= ~MIPI_CTRL_SSTYPE_MASK; - dev->cntx_config[context].mipi_ctrl |= - (0x12 << MIPI_CTRL_SSTYPE_OFFSET); - ap1302_write_context_reg(sd, context, - CNTX_MIPI_CTRL, AP1302_REG16); - ap1302_read_context_reg(sd, context, - CNTX_SS, AP1302_REG16); - dev->cntx_config[context].ss = AP1302_SS_CTRL; - ap1302_write_context_reg(sd, context, - CNTX_SS, AP1302_REG16); - } else { - /* Configure aux stream */ - ap1302_read_context_reg(sd, context, - CNTX_MIPI_II_CTRL, AP1302_REG16); - dev->cntx_config[context].mipi_ii_ctrl &= ~MIPI_CTRL_IMGVC_MASK; - dev->cntx_config[context].mipi_ii_ctrl |= - (context << MIPI_CTRL_IMGVC_OFFSET); - ap1302_write_context_reg(sd, context, - CNTX_MIPI_II_CTRL, AP1302_REG16); - if (stream_info->enable) { - ap1302_read_context_reg(sd, main_context, - CNTX_OUT_FMT, AP1302_REG16); - dev->cntx_config[context].out_fmt |= - (aux_stream_config[main_context][context] - << OUT_FMT_IIS_OFFSET); - ap1302_write_context_reg(sd, main_context, - CNTX_OUT_FMT, AP1302_REG16); - } - } - stream_info->ch_id = context; - mutex_unlock(&dev->input_lock); - - return 0; -} - - -static int ap1302_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - enum ap1302_contexts context; - struct ap1302_res_struct *res_table; - u32 cur_res; - - mutex_lock(&dev->input_lock); - context = ap1302_get_context(sd); - res_table = dev->cntx_res[context].res_table; - cur_res = dev->cntx_res[context].cur_res; - interval->interval.denominator = res_table[cur_res].fps; - interval->interval.numerator = 1; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int ap1302_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_frame_size_enum *fse) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - enum ap1302_contexts context; - struct ap1302_res_struct *res_table; - int index = fse->index; - - mutex_lock(&dev->input_lock); - context = ap1302_get_context(sd); - if (index >= dev->cntx_res[context].res_num) { - mutex_unlock(&dev->input_lock); - return -EINVAL; - } - - res_table = dev->cntx_res[context].res_table; - fse->min_width = res_table[index].width; - fse->min_height = res_table[index].height; - fse->max_width = res_table[index].width; - fse->max_height = res_table[index].height; - mutex_unlock(&dev->input_lock); - - return 0; -} - - -static int ap1302_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) -{ - *frames = 0; - return 0; -} - -static int ap1302_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - enum ap1302_contexts context; - u32 reg_val; - int ret; - - mutex_lock(&dev->input_lock); - context = ap1302_get_context(sd); - dev_dbg(&client->dev, "ap1302_s_stream. context=%d enable=%d\n", - context, enable); - /* Switch context */ - ap1302_i2c_read_reg(sd, REG_CTRL, - AP1302_REG16, ®_val); - reg_val &= ~CTRL_CNTX_MASK; - reg_val |= (context<<CTRL_CNTX_OFFSET); - ap1302_i2c_write_reg(sd, REG_CTRL, - AP1302_REG16, reg_val); - /* Select sensor */ - ap1302_i2c_read_reg(sd, REG_SENSOR_SELECT, - AP1302_REG16, ®_val); - reg_val &= ~SENSOR_SELECT_MASK; - reg_val |= (AP1302_SENSOR_PRI<<SENSOR_SELECT_OFFSET); - ap1302_i2c_write_reg(sd, REG_SENSOR_SELECT, - AP1302_REG16, reg_val); - if (enable) { - dev_info(&client->dev, "Start stream. context=%d\n", context); - ap1302_dump_context_reg(sd, context); - if (!dev->sys_activated) { - reg_val = AP1302_SYS_ACTIVATE; - dev->sys_activated = 1; - } else { - reg_val = AP1302_SYS_SWITCH; - } - } else { - dev_info(&client->dev, "Stop stream. context=%d\n", context); - reg_val = AP1302_SYS_SWITCH; - } - ret = ap1302_i2c_write_reg(sd, REG_SYS_START, AP1302_REG16, reg_val); - if (ret) - dev_err(&client->dev, - "AP1302 set stream failed. enable=%d\n", enable); - mutex_unlock(&dev->input_lock); - return ret; -} - -static u16 ap1302_ev_values[] = {0xfd00, 0xfe80, 0x0, 0x180, 0x300}; - -static int ap1302_set_exposure_off(struct v4l2_subdev *sd, s32 val) -{ - val -= AP1302_MIN_EV; - return ap1302_i2c_write_reg(sd, REG_AE_BV_OFF, AP1302_REG16, - ap1302_ev_values[val]); -} - -static u16 ap1302_wb_values[] = { - 0, /* V4L2_WHITE_BALANCE_MANUAL */ - 0xf, /* V4L2_WHITE_BALANCE_AUTO */ - 0x2, /* V4L2_WHITE_BALANCE_INCANDESCENT */ - 0x4, /* V4L2_WHITE_BALANCE_FLUORESCENT */ - 0x5, /* V4L2_WHITE_BALANCE_FLUORESCENT_H */ - 0x1, /* V4L2_WHITE_BALANCE_HORIZON */ - 0x5, /* V4L2_WHITE_BALANCE_DAYLIGHT */ - 0xf, /* V4L2_WHITE_BALANCE_FLASH */ - 0x6, /* V4L2_WHITE_BALANCE_CLOUDY */ - 0x6, /* V4L2_WHITE_BALANCE_SHADE */ -}; - -static int ap1302_set_wb_mode(struct v4l2_subdev *sd, s32 val) -{ - int ret = 0; - u16 reg_val; - - ret = ap1302_i2c_read_reg(sd, REG_AWB_CTRL, AP1302_REG16, ®_val); - if (ret) - return ret; - reg_val &= ~AWB_CTRL_MODE_MASK; - reg_val |= ap1302_wb_values[val] << AWB_CTRL_MODE_OFFSET; - if (val == V4L2_WHITE_BALANCE_FLASH) - reg_val |= AWB_CTRL_FLASH_MASK; - else - reg_val &= ~AWB_CTRL_FLASH_MASK; - ret = ap1302_i2c_write_reg(sd, REG_AWB_CTRL, AP1302_REG16, reg_val); - return ret; -} - -static int ap1302_set_zoom(struct v4l2_subdev *sd, s32 val) -{ - ap1302_i2c_write_reg(sd, REG_DZ_TGT_FCT, AP1302_REG16, - val * 4 + 0x100); - return 0; -} - -static u16 ap1302_sfx_values[] = { - 0x00, /* V4L2_COLORFX_NONE */ - 0x03, /* V4L2_COLORFX_BW */ - 0x0d, /* V4L2_COLORFX_SEPIA */ - 0x07, /* V4L2_COLORFX_NEGATIVE */ - 0x04, /* V4L2_COLORFX_EMBOSS */ - 0x0f, /* V4L2_COLORFX_SKETCH */ - 0x08, /* V4L2_COLORFX_SKY_BLUE */ - 0x09, /* V4L2_COLORFX_GRASS_GREEN */ - 0x0a, /* V4L2_COLORFX_SKIN_WHITEN */ - 0x00, /* V4L2_COLORFX_VIVID */ - 0x00, /* V4L2_COLORFX_AQUA */ - 0x00, /* V4L2_COLORFX_ART_FREEZE */ - 0x00, /* V4L2_COLORFX_SILHOUETTE */ - 0x10, /* V4L2_COLORFX_SOLARIZATION */ - 0x02, /* V4L2_COLORFX_ANTIQUE */ - 0x00, /* V4L2_COLORFX_SET_CBCR */ -}; - -static int ap1302_set_special_effect(struct v4l2_subdev *sd, s32 val) -{ - ap1302_i2c_write_reg(sd, REG_SFX_MODE, AP1302_REG16, - ap1302_sfx_values[val]); - return 0; -} - -static u16 ap1302_scene_mode_values[] = { - 0x00, /* V4L2_SCENE_MODE_NONE */ - 0x07, /* V4L2_SCENE_MODE_BACKLIGHT */ - 0x0a, /* V4L2_SCENE_MODE_BEACH_SNOW */ - 0x06, /* V4L2_SCENE_MODE_CANDLE_LIGHT */ - 0x00, /* V4L2_SCENE_MODE_DAWN_DUSK */ - 0x00, /* V4L2_SCENE_MODE_FALL_COLORS */ - 0x0d, /* V4L2_SCENE_MODE_FIREWORKS */ - 0x02, /* V4L2_SCENE_MODE_LANDSCAPE */ - 0x05, /* V4L2_SCENE_MODE_NIGHT */ - 0x0c, /* V4L2_SCENE_MODE_PARTY_INDOOR */ - 0x01, /* V4L2_SCENE_MODE_PORTRAIT */ - 0x03, /* V4L2_SCENE_MODE_SPORTS */ - 0x0e, /* V4L2_SCENE_MODE_SUNSET */ - 0x0b, /* V4L2_SCENE_MODE_TEXT */ -}; - -static int ap1302_set_scene_mode(struct v4l2_subdev *sd, s32 val) -{ - ap1302_i2c_write_reg(sd, REG_SCENE_CTRL, AP1302_REG16, - ap1302_scene_mode_values[val]); - return 0; -} - -static u16 ap1302_flicker_values[] = { - 0x0, /* OFF */ - 0x3201, /* 50HZ */ - 0x3c01, /* 60HZ */ - 0x2 /* AUTO */ -}; - -static int ap1302_set_flicker_freq(struct v4l2_subdev *sd, s32 val) -{ - ap1302_i2c_write_reg(sd, REG_FLICK_CTRL, AP1302_REG16, - ap1302_flicker_values[val]); - return 0; -} - -static int ap1302_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct ap1302_device *dev = container_of( - ctrl->handler, struct ap1302_device, ctrl_handler); - - switch (ctrl->id) { - case V4L2_CID_RUN_MODE: - dev->cur_context = ap1302_cntx_mapping[ctrl->val]; - break; - case V4L2_CID_EXPOSURE: - ap1302_set_exposure_off(&dev->sd, ctrl->val); - break; - case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: - ap1302_set_wb_mode(&dev->sd, ctrl->val); - break; - case V4L2_CID_ZOOM_ABSOLUTE: - ap1302_set_zoom(&dev->sd, ctrl->val); - break; - case V4L2_CID_COLORFX: - ap1302_set_special_effect(&dev->sd, ctrl->val); - break; - case V4L2_CID_SCENE_MODE: - ap1302_set_scene_mode(&dev->sd, ctrl->val); - break; - case V4L2_CID_POWER_LINE_FREQUENCY: - ap1302_set_flicker_freq(&dev->sd, ctrl->val); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ap1302_g_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - int ret; - u32 reg_val; - - if (reg->size != AP1302_REG16 && - reg->size != AP1302_REG32) - return -EINVAL; - - mutex_lock(&dev->input_lock); - if (dev->power_on) - ret = ap1302_i2c_read_reg(sd, reg->reg, reg->size, ®_val); - else - ret = -EIO; - mutex_unlock(&dev->input_lock); - if (ret) - return ret; - - reg->val = reg_val; - - return 0; -} - -static int ap1302_s_register(struct v4l2_subdev *sd, - const struct v4l2_dbg_register *reg) -{ - struct ap1302_device *dev = to_ap1302_device(sd); - int ret; - - if (reg->size != AP1302_REG16 && - reg->size != AP1302_REG32) - return -EINVAL; - - mutex_lock(&dev->input_lock); - if (dev->power_on) - ret = ap1302_i2c_write_reg(sd, reg->reg, reg->size, reg->val); - else - ret = -EIO; - mutex_unlock(&dev->input_lock); - return ret; -} - -static long ap1302_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - long ret = 0; - switch (cmd) { - case VIDIOC_DBG_G_REGISTER: - ret = ap1302_g_register(sd, arg); - break; - case VIDIOC_DBG_S_REGISTER: - ret = ap1302_s_register(sd, arg); - break; - default: - ret = -EINVAL; - } - return ret; -} - -static const struct v4l2_ctrl_ops ctrl_ops = { - .s_ctrl = ap1302_s_ctrl, -}; - -static const char * const ctrl_run_mode_menu[] = { - NULL, - "Video", - "Still capture", - "Continuous capture", - "Preview", -}; - -static const struct v4l2_ctrl_config ctrls[] = { - { - .ops = &ctrl_ops, - .id = V4L2_CID_RUN_MODE, - .name = "Run Mode", - .type = V4L2_CTRL_TYPE_MENU, - .min = 1, - .def = 4, - .max = 4, - .qmenu = ctrl_run_mode_menu, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE, - .name = "Exposure", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = AP1302_MIN_EV, - .def = 0, - .max = AP1302_MAX_EV, - .step = 1, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, - .name = "White Balance", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .def = 0, - .max = 9, - .step = 1, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_ZOOM_ABSOLUTE, - .name = "Zoom Absolute", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .def = 0, - .max = 1024, - .step = 1, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_COLORFX, - .name = "Color Special Effect", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .def = 0, - .max = 15, - .step = 1, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_SCENE_MODE, - .name = "Scene Mode", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .def = 0, - .max = 13, - .step = 1, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .name = "Light frequency filter", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .def = 3, - .max = 3, - .step = 1, - }, -}; - -static const struct v4l2_subdev_sensor_ops ap1302_sensor_ops = { - .g_skip_frames = ap1302_g_skip_frames, -}; - -static const struct v4l2_subdev_video_ops ap1302_video_ops = { - .s_stream = ap1302_s_stream, - .g_frame_interval = ap1302_g_frame_interval, -}; - -static const struct v4l2_subdev_core_ops ap1302_core_ops = { - .s_power = ap1302_s_power, - .ioctl = ap1302_ioctl, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = ap1302_g_register, - .s_register = ap1302_s_register, -#endif -}; - -static const struct v4l2_subdev_pad_ops ap1302_pad_ops = { - .enum_mbus_code = ap1302_enum_mbus_code, - .enum_frame_size = ap1302_enum_frame_size, - .get_fmt = ap1302_get_fmt, - .set_fmt = ap1302_set_fmt, -}; - -static const struct v4l2_subdev_ops ap1302_ops = { - .core = &ap1302_core_ops, - .pad = &ap1302_pad_ops, - .video = &ap1302_video_ops, - .sensor = &ap1302_sensor_ops -}; - -static int ap1302_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ap1302_device *dev = to_ap1302_device(sd); - - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - - release_firmware(dev->fw); - - media_entity_cleanup(&dev->sd.entity); - dev->platform_data->csi_cfg(sd, 0); - v4l2_device_unregister_subdev(sd); - - return 0; -} - -static int ap1302_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct ap1302_device *dev; - int ret; - unsigned int i; - - dev_info(&client->dev, "ap1302 probe called.\n"); - - /* allocate device & init sub device */ - dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "%s: out of memory\n", __func__); - return -ENOMEM; - } - - mutex_init(&dev->input_lock); - - v4l2_i2c_subdev_init(&(dev->sd), client, &ap1302_ops); - - ret = ap1302_request_firmware(&(dev->sd)); - if (ret) { - dev_err(&client->dev, "Cannot request ap1302 firmware.\n"); - goto out_free; - } - - dev->regmap16 = devm_regmap_init_i2c(client, &ap1302_reg16_config); - if (IS_ERR(dev->regmap16)) { - ret = PTR_ERR(dev->regmap16); - dev_err(&client->dev, - "Failed to allocate 16bit register map: %d\n", ret); - return ret; - } - - dev->regmap32 = devm_regmap_init_i2c(client, &ap1302_reg32_config); - if (IS_ERR(dev->regmap32)) { - ret = PTR_ERR(dev->regmap32); - dev_err(&client->dev, - "Failed to allocate 32bit register map: %d\n", ret); - return ret; - } - - if (client->dev.platform_data) { - ret = ap1302_s_config(&dev->sd, client->dev.platform_data); - if (ret) - goto out_free; - } - - dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - dev->cntx_res[CONTEXT_PREVIEW].res_num = ARRAY_SIZE(ap1302_preview_res); - dev->cntx_res[CONTEXT_PREVIEW].res_table = ap1302_preview_res; - dev->cntx_res[CONTEXT_SNAPSHOT].res_num = - ARRAY_SIZE(ap1302_snapshot_res); - dev->cntx_res[CONTEXT_SNAPSHOT].res_table = ap1302_snapshot_res; - dev->cntx_res[CONTEXT_VIDEO].res_num = ARRAY_SIZE(ap1302_video_res); - dev->cntx_res[CONTEXT_VIDEO].res_table = ap1302_video_res; - - ret = v4l2_ctrl_handler_init(&dev->ctrl_handler, ARRAY_SIZE(ctrls)); - if (ret) { - ap1302_remove(client); - return ret; - } - - for (i = 0; i < ARRAY_SIZE(ctrls); i++) - v4l2_ctrl_new_custom(&dev->ctrl_handler, &ctrls[i], NULL); - - if (dev->ctrl_handler.error) { - ap1302_remove(client); - return dev->ctrl_handler.error; - } - - /* Use same lock for controls as for everything else. */ - dev->ctrl_handler.lock = &dev->input_lock; - dev->sd.ctrl_handler = &dev->ctrl_handler; - v4l2_ctrl_handler_setup(&dev->ctrl_handler); - - dev->run_mode = v4l2_ctrl_find(&dev->ctrl_handler, V4L2_CID_RUN_MODE); - v4l2_ctrl_s_ctrl(dev->run_mode, ATOMISP_RUN_MODE_PREVIEW); - - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); - if (ret) - ap1302_remove(client); - return ret; -out_free: - v4l2_device_unregister_subdev(&dev->sd); - return ret; -} - -static const struct i2c_device_id ap1302_id[] = { - {AP1302_NAME, 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, ap1302_id); - -static struct i2c_driver ap1302_driver = { - .driver = { - .name = AP1302_NAME, - }, - .probe = ap1302_probe, - .remove = ap1302_remove, - .id_table = ap1302_id, -}; - -module_i2c_driver(ap1302_driver); - -MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>"); -MODULE_DESCRIPTION("AP1302 Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/ap1302.h b/drivers/staging/media/atomisp/i2c/ap1302.h deleted file mode 100644 index 4d0b181a9671..000000000000 --- a/drivers/staging/media/atomisp/i2c/ap1302.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __AP1302_H__ -#define __AP1302_H__ - -#include "../include/linux/atomisp_platform.h" -#include <linux/regmap.h> -#include <linux/types.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-subdev.h> - -#define AP1302_NAME "ap1302" -#define AP1302_CHIP_ID 0x265 -#define AP1302_I2C_MAX_LEN 65534 -#define AP1302_FW_WINDOW_OFFSET 0x8000 -#define AP1302_FW_WINDOW_SIZE 0x2000 - -#define AP1302_REG16 2 -#define AP1302_REG32 4 - -#define REG_CHIP_VERSION 0x0000 -#define REG_CHIP_REV 0x0050 -#define REG_MF_ID 0x0004 -#define REG_ERROR 0x0006 -#define REG_CTRL 0x1000 -#define REG_DZ_TGT_FCT 0x1010 -#define REG_SFX_MODE 0x1016 -#define REG_SS_HEAD_PT0 0x1174 -#define REG_AE_BV_OFF 0x5014 -#define REG_AE_BV_BIAS 0x5016 -#define REG_AWB_CTRL 0x5100 -#define REG_FLICK_CTRL 0x5440 -#define REG_SCENE_CTRL 0x5454 -#define REG_BOOTDATA_STAGE 0x6002 -#define REG_SENSOR_SELECT 0x600C -#define REG_SYS_START 0x601A -#define REG_SIP_CRC 0xF052 - -#define REG_PREVIEW_BASE 0x2000 -#define REG_SNAPSHOT_BASE 0x3000 -#define REG_VIDEO_BASE 0x4000 -#define CNTX_WIDTH 0x00 -#define CNTX_HEIGHT 0x02 -#define CNTX_ROI_X0 0x04 -#define CNTX_ROI_Y0 0x06 -#define CNTX_ROI_X1 0x08 -#define CNTX_ROI_Y1 0x0A -#define CNTX_ASPECT 0x0C -#define CNTX_LOCK 0x0E -#define CNTX_ENABLE 0x10 -#define CNTX_OUT_FMT 0x12 -#define CNTX_SENSOR_MODE 0x14 -#define CNTX_MIPI_CTRL 0x16 -#define CNTX_MIPI_II_CTRL 0x18 -#define CNTX_LINE_TIME 0x1C -#define CNTX_MAX_FPS 0x20 -#define CNTX_AE_USG 0x22 -#define CNTX_AE_UPPER_ET 0x24 -#define CNTX_AE_MAX_ET 0x28 -#define CNTX_SS 0x2C -#define CNTX_S1_SENSOR_MODE 0x2E -#define CNTX_HINF_CTRL 0x30 - -#define CTRL_CNTX_MASK 0x03 -#define CTRL_CNTX_OFFSET 0x00 -#define HINF_CTRL_LANE_MASK 0x07 -#define HINF_CTRL_LANE_OFFSET 0x00 -#define MIPI_CTRL_IMGVC_MASK 0xC0 -#define MIPI_CTRL_IMGVC_OFFSET 0x06 -#define MIPI_CTRL_IMGTYPE_AUTO 0x3F -#define MIPI_CTRL_SSVC_MASK 0xC000 -#define MIPI_CTRL_SSVC_OFFSET 0x0E -#define MIPI_CTRL_SSTYPE_MASK 0x3F00 -#define MIPI_CTRL_SSTYPE_OFFSET 0x08 -#define OUT_FMT_IIS_MASK 0x30 -#define OUT_FMT_IIS_OFFSET 0x08 -#define OUT_FMT_SS_MASK 0x1000 -#define OUT_FMT_SS_OFFSET 0x12 -#define OUT_FMT_TYPE_MASK 0xFF -#define SENSOR_SELECT_MASK 0x03 -#define SENSOR_SELECT_OFFSET 0x00 -#define AWB_CTRL_MODE_MASK 0x0F -#define AWB_CTRL_MODE_OFFSET 0x00 -#define AWB_CTRL_FLASH_MASK 0x100 - -#define AP1302_FMT_UYVY422 0x50 - -#define AP1302_SYS_ACTIVATE 0x8010 -#define AP1302_SYS_SWITCH 0x8140 -#define AP1302_SENSOR_PRI 0x01 -#define AP1302_SENSOR_SEC 0x02 -#define AP1302_SS_CTRL 0x31 - -#define AP1302_MAX_RATIO_MISMATCH 10 /* Unit in percentage */ -#define AP1302_MAX_EV 2 -#define AP1302_MIN_EV -2 - -enum ap1302_contexts { - CONTEXT_PREVIEW = 0, - CONTEXT_SNAPSHOT, - CONTEXT_VIDEO, - CONTEXT_NUM -}; - -/* The context registers are defined according to preview/video registers. - Preview and video context have the same register definition. - But snapshot context does not have register S1_SENSOR_MODE. - When setting snapshot registers, if the offset exceeds - S1_SENSOR_MODE, the actual offset needs to minus 2. */ -struct ap1302_context_config { - u16 width; - u16 height; - u16 roi_x0; - u16 roi_y0; - u16 roi_x1; - u16 roi_y1; - u16 aspect_factor; - u16 lock; - u16 enable; - u16 out_fmt; - u16 sensor_mode; - u16 mipi_ctrl; - u16 mipi_ii_ctrl; - u16 padding; - u32 line_time; - u16 max_fps; - u16 ae_usg; - u32 ae_upper_et; - u32 ae_max_et; - u16 ss; - u16 s1_sensor_mode; - u16 hinf_ctrl; - u32 reserved; -}; - -struct ap1302_res_struct { - u16 width; - u16 height; - u16 fps; -}; - -struct ap1302_context_res { - u32 res_num; - u32 cur_res; - struct ap1302_res_struct *res_table; -}; - -struct ap1302_device { - struct v4l2_subdev sd; - struct media_pad pad; - struct camera_sensor_platform_data *platform_data; - const struct firmware *fw; - struct mutex input_lock; /* serialize sensor's ioctl */ - struct v4l2_mbus_framefmt format; - struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_ctrl *run_mode; - struct ap1302_context_config cntx_config[CONTEXT_NUM]; - struct ap1302_context_res cntx_res[CONTEXT_NUM]; - enum ap1302_contexts cur_context; - unsigned int num_lanes; - struct regmap *regmap16; - struct regmap *regmap32; - bool sys_activated; - bool power_on; -}; - -struct ap1302_firmware { - u32 crc; - u32 pll_init_size; - u32 total_size; - u32 reserved; -}; - -struct ap1302_context_info { - u16 offset; - u16 len; - char *name; -}; - -#endif diff --git a/drivers/staging/media/atomisp/i2c/gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 35ed51ffe944..e70d8afcc229 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -26,7 +26,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/moduleparam.h> #include <media/v4l2-device.h> #include <linux/io.h> @@ -738,10 +737,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (flag) { /* The upstream module driver (written to Crystal * Cove) had this logic to pulse the rails low first. @@ -772,10 +767,6 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - /* GPIO0 == "reset" (active low), GPIO1 == "power down" */ if (flag) { /* Pulse reset, then release power down */ @@ -1165,13 +1156,6 @@ static int gc0310_s_config(struct v4l2_subdev *sd, (struct camera_sensor_platform_data *)platform_data; mutex_lock(&dev->input_lock); - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - dev_err(&client->dev, "platform init err\n"); - goto platform_init_failed; - } - } /* power off the module, then power on it in future * as first power on by board may not fulfill the * power on sequqence needed by the module @@ -1216,9 +1200,6 @@ fail_power_on: power_down(sd); dev_err(&client->dev, "sensor power-gating failed\n"); fail_power_off: - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); -platform_init_failed: mutex_unlock(&dev->input_lock); return ret; } @@ -1362,9 +1343,6 @@ static int gc0310_remove(struct i2c_client *client) struct gc0310_device *dev = to_gc0310_sensor(sd); dev_dbg(&client->dev, "gc0310_remove...\n"); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - dev->platform_data->csi_cfg(sd, 0); v4l2_device_unregister_subdev(sd); @@ -1375,8 +1353,7 @@ static int gc0310_remove(struct i2c_client *client) return 0; } -static int gc0310_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gc0310_probe(struct i2c_client *client) { struct gc0310_device *dev; int ret; @@ -1385,10 +1362,8 @@ static int gc0310_probe(struct i2c_client *client, pr_info("%s S\n", __func__); dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); @@ -1457,33 +1432,17 @@ static const struct acpi_device_id gc0310_acpi_match[] = { {"INT0310"}, {}, }; - MODULE_DEVICE_TABLE(acpi, gc0310_acpi_match); -MODULE_DEVICE_TABLE(i2c, gc0310_id); static struct i2c_driver gc0310_driver = { .driver = { - .name = GC0310_NAME, - .acpi_match_table = ACPI_PTR(gc0310_acpi_match), + .name = "gc0310", + .acpi_match_table = gc0310_acpi_match, }, - .probe = gc0310_probe, + .probe_new = gc0310_probe, .remove = gc0310_remove, - .id_table = gc0310_id, }; - -static int init_gc0310(void) -{ - return i2c_add_driver(&gc0310_driver); -} - -static void exit_gc0310(void) -{ - - i2c_del_driver(&gc0310_driver); -} - -module_init(init_gc0310); -module_exit(exit_gc0310); +module_i2c_driver(gc0310_driver); MODULE_AUTHOR("Lai, Angie <angie.lai@intel.com>"); MODULE_DESCRIPTION("A low-level driver for GalaxyCore GC0310 sensors"); diff --git a/drivers/staging/media/atomisp/i2c/gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index e43d31ea9676..85da5fe24033 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -26,7 +26,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/moduleparam.h> #include <media/v4l2-device.h> #include "../include/linux/atomisp_gmin_platform.h" @@ -548,10 +547,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (flag) { ret = dev->platform_data->v1p8_ctrl(sd, 1); usleep_range(60, 90); @@ -572,10 +567,6 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - ret |= dev->platform_data->gpio1_ctrl(sd, !flag); usleep_range(60, 90); return dev->platform_data->gpio0_ctrl(sd, flag); @@ -906,13 +897,6 @@ static int gc2235_s_config(struct v4l2_subdev *sd, (struct camera_sensor_platform_data *)platform_data; mutex_lock(&dev->input_lock); - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - dev_err(&client->dev, "platform init err\n"); - goto platform_init_failed; - } - } /* power off the module, then power on it in future * as first power on by board may not fulfill the * power on sequqence needed by the module @@ -956,9 +940,6 @@ fail_power_on: power_down(sd); dev_err(&client->dev, "sensor power-gating failed\n"); fail_power_off: - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); -platform_init_failed: mutex_unlock(&dev->input_lock); return ret; } @@ -1101,9 +1082,6 @@ static int gc2235_remove(struct i2c_client *client) struct gc2235_device *dev = to_gc2235_sensor(sd); dev_dbg(&client->dev, "gc2235_remove...\n"); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - dev->platform_data->csi_cfg(sd, 0); v4l2_device_unregister_subdev(sd); @@ -1114,8 +1092,7 @@ static int gc2235_remove(struct i2c_client *client) return 0; } -static int gc2235_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int gc2235_probe(struct i2c_client *client) { struct gc2235_device *dev; void *gcpdev; @@ -1123,10 +1100,8 @@ static int gc2235_probe(struct i2c_client *client, unsigned int i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); @@ -1187,32 +1162,17 @@ static const struct acpi_device_id gc2235_acpi_match[] = { { "INT33F8" }, {}, }; - MODULE_DEVICE_TABLE(acpi, gc2235_acpi_match); -MODULE_DEVICE_TABLE(i2c, gc2235_id); + static struct i2c_driver gc2235_driver = { .driver = { - .name = GC2235_NAME, - .acpi_match_table = ACPI_PTR(gc2235_acpi_match), + .name = "gc2235", + .acpi_match_table = gc2235_acpi_match, }, - .probe = gc2235_probe, + .probe_new = gc2235_probe, .remove = gc2235_remove, - .id_table = gc2235_id, }; - -static int init_gc2235(void) -{ - return i2c_add_driver(&gc2235_driver); -} - -static void exit_gc2235(void) -{ - - i2c_del_driver(&gc2235_driver); -} - -module_init(init_gc2235); -module_exit(exit_gc2235); +module_i2c_driver(gc2235_driver); MODULE_AUTHOR("Shuguang Gong <Shuguang.Gong@intel.com>"); MODULE_DESCRIPTION("A low-level driver for GC2235 sensors"); diff --git a/drivers/staging/media/atomisp/i2c/libmsrlisthelper.c b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c index decb65cfd7c9..81e5ec0c2b64 100644 --- a/drivers/staging/media/atomisp/i2c/libmsrlisthelper.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-libmsrlisthelper.c @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/i2c.h> diff --git a/drivers/staging/media/atomisp/i2c/lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c index 679176f7c542..4fd9f538ac95 100644 --- a/drivers/staging/media/atomisp/i2c/lm3554.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/module.h> @@ -171,10 +167,9 @@ static int lm3554_set_config1(struct lm3554 *flash) /* ----------------------------------------------------------------------------- * Hardware trigger */ -static void lm3554_flash_off_delay(long unsigned int arg) +static void lm3554_flash_off_delay(struct timer_list *t) { - struct v4l2_subdev *sd = i2c_get_clientdata((struct i2c_client *)arg); - struct lm3554 *flash = to_lm3554(sd); + struct lm3554 *flash = from_timer(flash, t, flash_off_delay); struct lm3554_platform_data *pdata = flash->pdata; gpio_set_value(pdata->gpio_strobe, 0); @@ -862,8 +857,7 @@ static void *lm3554_platform_data_func(struct i2c_client *client) return &platform_data; } -static int lm3554_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int lm3554_probe(struct i2c_client *client) { int err = 0; struct lm3554 *flash; @@ -871,10 +865,8 @@ static int lm3554_probe(struct i2c_client *client, int ret; flash = kzalloc(sizeof(*flash), GFP_KERNEL); - if (!flash) { - dev_err(&client->dev, "out of memory\n"); + if (!flash) return -ENOMEM; - } flash->pdata = client->dev.platform_data; @@ -915,8 +907,7 @@ static int lm3554_probe(struct i2c_client *client, mutex_init(&flash->power_lock); - setup_timer(&flash->flash_off_delay, lm3554_flash_off_delay, - (unsigned long)client); + timer_setup(&flash->flash_off_delay, lm3554_flash_off_delay, 0); err = lm3554_gpio_init(client); if (err) { @@ -962,13 +953,6 @@ fail: return ret; } -static const struct i2c_device_id lm3554_id[] = { - {LM3554_NAME, 0}, - {}, -}; - -MODULE_DEVICE_TABLE(i2c, lm3554_id); - static const struct dev_pm_ops lm3554_pm_ops = { .suspend = lm3554_suspend, .resume = lm3554_resume, @@ -978,32 +962,19 @@ static const struct acpi_device_id lm3554_acpi_match[] = { { "INTCF1C" }, {}, }; - MODULE_DEVICE_TABLE(acpi, lm3554_acpi_match); static struct i2c_driver lm3554_driver = { .driver = { - .name = LM3554_NAME, + .name = "lm3554", .pm = &lm3554_pm_ops, - .acpi_match_table = ACPI_PTR(lm3554_acpi_match), + .acpi_match_table = lm3554_acpi_match, }, - .probe = lm3554_probe, + .probe_new = lm3554_probe, .remove = lm3554_remove, - .id_table = lm3554_id, }; +module_i2c_driver(lm3554_driver); -static __init int init_lm3554(void) -{ - return i2c_add_driver(&lm3554_driver); -} - -static __exit void exit_lm3554(void) -{ - i2c_del_driver(&lm3554_driver); -} - -module_init(init_lm3554); -module_exit(exit_lm3554); MODULE_AUTHOR("Jing Tao <jing.tao@intel.com>"); MODULE_DESCRIPTION("LED flash driver for LM3554"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c index 3c837cb8859c..55882bea2049 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -32,7 +28,6 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/acpi.h> #include "../include/linux/atomisp_gmin_platform.h" #include <media/v4l2-device.h> @@ -455,10 +450,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (flag) { ret = dev->platform_data->v2p8_ctrl(sd, 1); if (ret == 0) { @@ -481,10 +472,6 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - /* Note: current modules wire only one GPIO signal (RESET#), * but the schematic wires up two to the connector. BIOS * versions have been unfortunately inconsistent with which @@ -1584,13 +1571,6 @@ mt9m114_s_config(struct v4l2_subdev *sd, int irq, void *platform_data) dev->platform_data = (struct camera_sensor_platform_data *)platform_data; - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - v4l2_err(client, "mt9m114 platform init err\n"); - return ret; - } - } ret = power_up(sd); if (ret) { v4l2_err(client, "mt9m114 power-up err"); @@ -1844,8 +1824,6 @@ static int mt9m114_remove(struct i2c_client *client) dev = container_of(sd, struct mt9m114_device, sd); dev->platform_data->csi_cfg(sd, 0); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&dev->sd.entity); v4l2_ctrl_handler_free(&dev->ctrl_handler); @@ -1853,8 +1831,7 @@ static int mt9m114_remove(struct i2c_client *client) return 0; } -static int mt9m114_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int mt9m114_probe(struct i2c_client *client) { struct mt9m114_device *dev; int ret = 0; @@ -1863,10 +1840,8 @@ static int mt9m114_probe(struct i2c_client *client, /* Setup sensor configuration structure */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } v4l2_i2c_subdev_init(&dev->sd, client, &mt9m114_ops); pdata = client->dev.platform_data; @@ -1926,38 +1901,22 @@ static int mt9m114_probe(struct i2c_client *client, return 0; } -MODULE_DEVICE_TABLE(i2c, mt9m114_id); - static const struct acpi_device_id mt9m114_acpi_match[] = { { "INT33F0" }, { "CRMT1040" }, {}, }; - MODULE_DEVICE_TABLE(acpi, mt9m114_acpi_match); static struct i2c_driver mt9m114_driver = { .driver = { .name = "mt9m114", - .acpi_match_table = ACPI_PTR(mt9m114_acpi_match), + .acpi_match_table = mt9m114_acpi_match, }, - .probe = mt9m114_probe, + .probe_new = mt9m114_probe, .remove = mt9m114_remove, - .id_table = mt9m114_id, }; - -static __init int init_mt9m114(void) -{ - return i2c_add_driver(&mt9m114_driver); -} - -static __exit void exit_mt9m114(void) -{ - i2c_del_driver(&mt9m114_driver); -} - -module_init(init_mt9m114); -module_exit(exit_mt9m114); +module_i2c_driver(mt9m114_driver); MODULE_AUTHOR("Shuguang Gong <Shuguang.gong@intel.com>"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c index 51b7d61df0f5..cd67d38f183a 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c @@ -26,7 +26,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/moduleparam.h> #include <media/v4l2-device.h> #include <linux/io.h> @@ -253,8 +252,8 @@ static int ov2680_write_reg_array(struct i2c_client *client, if (!__ov2680_write_reg_is_consecutive(client, &ctrl, next)) { err = __ov2680_flush_reg_array(client, &ctrl); - if (err) - return err; + if (err) + return err; } err = __ov2680_buf_reg_array(client, &ctrl, next); if (err) { @@ -399,7 +398,9 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg, u16 vts,hts; int ret,exp_val; - dev_dbg(&client->dev, "+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",coarse_itg, gain, digitgain); + dev_dbg(&client->dev, + "+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n", + coarse_itg, gain, digitgain); hts = ov2680_res[dev->fmt_idx].pixels_per_line; vts = ov2680_res[dev->fmt_idx].lines_per_frame; @@ -847,10 +848,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (flag) { ret |= dev->platform_data->v1p8_ctrl(sd, 1); ret |= dev->platform_data->v2p8_ctrl(sd, 1); @@ -872,10 +869,6 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - /* The OV2680 documents only one GPIO input (#XSHUTDN), but * existing integrations often wire two (reset/power_down) * because that is the way other sensors work. There is no @@ -1438,8 +1431,7 @@ static int ov2680_remove(struct i2c_client *client) return 0; } -static int ov2680_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ov2680_probe(struct i2c_client *client) { struct ov2680_device *dev; int ret; @@ -1447,10 +1439,8 @@ static int ov2680_probe(struct i2c_client *client, unsigned int i; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); @@ -1523,35 +1513,16 @@ static const struct acpi_device_id ov2680_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, ov2680_acpi_match); - -MODULE_DEVICE_TABLE(i2c, ov2680_id); static struct i2c_driver ov2680_driver = { .driver = { - .owner = THIS_MODULE, - .name = OV2680_NAME, - .acpi_match_table = ACPI_PTR(ov2680_acpi_match), - + .name = "ov2680", + .acpi_match_table = ov2680_acpi_match, }, - .probe = ov2680_probe, + .probe_new = ov2680_probe, .remove = ov2680_remove, - .id_table = ov2680_id, }; - -static int init_ov2680(void) -{ - return i2c_add_driver(&ov2680_driver); -} - -static void exit_ov2680(void) -{ - - i2c_del_driver(&ov2680_driver); -} - -module_init(init_ov2680); -module_exit(exit_ov2680); +module_i2c_driver(ov2680_driver); MODULE_AUTHOR("Jacky Wang <Jacky_wang@ovt.com>"); MODULE_DESCRIPTION("A low-level driver for OmniVision 2680 sensors"); MODULE_LICENSE("GPL"); - diff --git a/drivers/staging/media/atomisp/i2c/ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index 10094ac56561..4df7eba8d375 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -26,7 +26,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/moduleparam.h> #include <media/v4l2-device.h> #include "../include/linux/atomisp_gmin_platform.h" @@ -651,10 +650,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (flag) { ret = dev->platform_data->v1p8_ctrl(sd, 1); if (ret == 0) { @@ -678,10 +673,6 @@ static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - /* Note: the GPIO order is asymmetric: always RESET# * before PWDN# when turning it on or off. */ @@ -1044,13 +1035,6 @@ static int ov2722_s_config(struct v4l2_subdev *sd, (struct camera_sensor_platform_data *)platform_data; mutex_lock(&dev->input_lock); - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - dev_err(&client->dev, "platform init err\n"); - goto platform_init_failed; - } - } /* power off the module, then power on it in future * as first power on by board may not fulfill the @@ -1095,9 +1079,6 @@ fail_power_on: power_down(sd); dev_err(&client->dev, "sensor power-gating failed\n"); fail_power_off: - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); -platform_init_failed: mutex_unlock(&dev->input_lock); return ret; } @@ -1241,9 +1222,6 @@ static int ov2722_remove(struct i2c_client *client) struct ov2722_device *dev = to_ov2722_sensor(sd); dev_dbg(&client->dev, "ov2722_remove...\n"); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - dev->platform_data->csi_cfg(sd, 0); v4l2_ctrl_handler_free(&dev->ctrl_handler); v4l2_device_unregister_subdev(sd); @@ -1276,8 +1254,7 @@ static int __ov2722_init_ctrl_handler(struct ov2722_device *dev) return 0; } -static int ov2722_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ov2722_probe(struct i2c_client *client) { struct ov2722_device *dev; void *ovpdev; @@ -1285,10 +1262,8 @@ static int ov2722_probe(struct i2c_client *client, struct acpi_device *adev; dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); @@ -1335,38 +1310,21 @@ out_free: return ret; } -MODULE_DEVICE_TABLE(i2c, ov2722_id); - static const struct acpi_device_id ov2722_acpi_match[] = { { "INT33FB" }, {}, }; - MODULE_DEVICE_TABLE(acpi, ov2722_acpi_match); static struct i2c_driver ov2722_driver = { .driver = { - .name = OV2722_NAME, - .acpi_match_table = ACPI_PTR(ov2722_acpi_match), + .name = "ov2722", + .acpi_match_table = ov2722_acpi_match, }, - .probe = ov2722_probe, + .probe_new = ov2722_probe, .remove = ov2722_remove, - .id_table = ov2722_id, }; - -static int init_ov2722(void) -{ - return i2c_add_driver(&ov2722_driver); -} - -static void exit_ov2722(void) -{ - - i2c_del_driver(&ov2722_driver); -} - -module_init(init_ov2722); -module_exit(exit_ov2722); +module_i2c_driver(ov2722_driver); MODULE_AUTHOR("Wei Liu <wei.liu@intel.com>"); MODULE_DESCRIPTION("A low-level driver for OmniVision 2722 sensors"); diff --git a/drivers/staging/media/atomisp/i2c/gc0310.h b/drivers/staging/media/atomisp/i2c/gc0310.h index 7d8a0aeecb6c..c422d0398fc7 100644 --- a/drivers/staging/media/atomisp/i2c/gc0310.h +++ b/drivers/staging/media/atomisp/i2c/gc0310.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -36,8 +32,6 @@ #include "../include/linux/atomisp_platform.h" -#define GC0310_NAME "gc0310" - /* Defines for register writes and register array processing */ #define I2C_MSG_LENGTH 1 #define I2C_RETRY_COUNT 5 @@ -196,11 +190,6 @@ struct gc0310_write_ctrl { struct gc0310_write_buffer buffer; }; -static const struct i2c_device_id gc0310_id[] = { - {GC0310_NAME, 0}, - {} -}; - /* * Register settings for various resolution */ diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index a8d6aa9c9a5d..3c30a05c3991 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h @@ -33,8 +33,6 @@ #include "../include/linux/atomisp_platform.h" -#define GC2235_NAME "gc2235" - /* Defines for register writes and register array processing */ #define I2C_MSG_LENGTH 0x2 #define I2C_RETRY_COUNT 5 @@ -200,11 +198,6 @@ struct gc2235_write_ctrl { struct gc2235_write_buffer buffer; }; -static const struct i2c_device_id gc2235_id[] = { - {GC2235_NAME, 0}, - {} -}; - static struct gc2235_reg const gc2235_stream_on[] = { { GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */ { GC2235_8BIT, 0x10, 0x91}, /* start mipi */ diff --git a/drivers/staging/media/atomisp/i2c/imx/Kconfig b/drivers/staging/media/atomisp/i2c/imx/Kconfig deleted file mode 100644 index a39eeb3b6ad4..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config VIDEO_IMX - tristate "sony imx sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_MSRLIST_HELPER && m - ---help--- - This is a Video4Linux2 sensor-level driver for the Sony - IMX RAW sensor. - - It currently depends on internal V4L2 extensions defined in - atomisp driver. diff --git a/drivers/staging/media/atomisp/i2c/imx/Makefile b/drivers/staging/media/atomisp/i2c/imx/Makefile deleted file mode 100644 index c1a85e6e27a9..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_VIDEO_IMX) += imx1x5.o - -imx1x5-objs := imx.o drv201.o ad5816g.o dw9714.o dw9719.o dw9718.o vcm.o otp.o otp_imx.o otp_brcc064_e2prom.o otp_e2prom.o - -ov8858_driver-objs := ../ov8858.o dw9718.o vcm.o -obj-$(CONFIG_VIDEO_OV8858) += ov8858_driver.o - -# HACK! While this driver is in bad shape, don't enable several warnings -# that would be otherwise enabled with W=1 -ccflags-y += $(call cc-disable-warning, unused-but-set-variable) -ccflags-y += $(call cc-disable-warning, unused-const-variable) -ccflags-y += $(call cc-disable-warning, missing-prototypes) -ccflags-y += $(call cc-disable-warning, missing-declarations) diff --git a/drivers/staging/media/atomisp/i2c/imx/ad5816g.c b/drivers/staging/media/atomisp/i2c/imx/ad5816g.c deleted file mode 100644 index fb74f14cbe5a..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/ad5816g.c +++ /dev/null @@ -1,217 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/kmod.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <media/v4l2-device.h> - -#include "ad5816g.h" - -struct ad5816g_device ad5816g_dev; - -static int ad5816g_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val) -{ - struct i2c_msg msg[2]; - u8 buf[2]; - buf[0] = reg; - buf[1] = 0; - - msg[0].addr = AD5816G_VCM_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &buf[0]; - - msg[1].addr = AD5816G_VCM_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &buf[1]; - *val = 0; - if (i2c_transfer(client->adapter, msg, 2) != 2) - return -EIO; - *val = buf[1]; - return 0; -} - -static int ad5816g_i2c_wr8(struct i2c_client *client, u8 reg, u8 val) -{ - struct i2c_msg msg; - u8 buf[2]; - buf[0] = reg; - buf[1] = val; - msg.addr = AD5816G_VCM_ADDR; - msg.flags = 0; - msg.len = 2; - msg.buf = &buf[0]; - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - return 0; -} - -static int ad5816g_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) -{ - struct i2c_msg msg; - u8 buf[3]; - buf[0] = reg; - buf[1] = (u8)(val >> 8); - buf[2] = (u8)(val & 0xff); - msg.addr = AD5816G_VCM_ADDR; - msg.flags = 0; - msg.len = 3; - msg.buf = &buf[0]; - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - return 0; -} - -static int ad5816g_set_arc_mode(struct i2c_client *client) -{ - int ret; - - ret = ad5816g_i2c_wr8(client, AD5816G_CONTROL, AD5816G_ARC_EN); - if (ret) - return ret; - - ret = ad5816g_i2c_wr8(client, AD5816G_MODE, - AD5816G_MODE_2_5M_SWITCH_CLOCK); - if (ret) - return ret; - - ret = ad5816g_i2c_wr8(client, AD5816G_VCM_FREQ, AD5816G_DEF_FREQ); - return ret; -} - -int ad5816g_vcm_power_up(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u8 ad5816g_id; - - /* Enable power */ - ret = ad5816g_dev.platform_data->power_ctrl(sd, 1); - if (ret) - return ret; - /* waiting time AD5816G(vcm) - t1 + t2 - * t1(1ms) -Time from VDD high to first i2c cmd - * t2(100us) - exit power-down mode time - */ - usleep_range(1100, 2200); - /* Detect device */ - ret = ad5816g_i2c_rd8(client, AD5816G_IC_INFO, &ad5816g_id); - if (ret < 0) - goto fail_powerdown; - if (ad5816g_id != AD5816G_ID) { - ret = -ENXIO; - goto fail_powerdown; - } - ret = ad5816g_set_arc_mode(client); - if (ret) - return ret; - - /* set the VCM_THRESHOLD */ - ret = ad5816g_i2c_wr8(client, AD5816G_VCM_THRESHOLD, - AD5816G_DEF_THRESHOLD); - - return ret; - -fail_powerdown: - ad5816g_dev.platform_data->power_ctrl(sd, 0); - return ret; -} - -int ad5816g_vcm_power_down(struct v4l2_subdev *sd) -{ - return ad5816g_dev.platform_data->power_ctrl(sd, 0); -} - - -static int ad5816g_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u16 data = val & VCM_CODE_MASK; - - return ad5816g_i2c_wr16(client, AD5816G_VCM_CODE_MSB, data); -} - -int ad5816g_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - int ret; - - value = clamp(value, 0, AD5816G_MAX_FOCUS_POS); - ret = ad5816g_t_focus_vcm(sd, value); - if (ret == 0) { - ad5816g_dev.number_of_steps = value - ad5816g_dev.focus; - ad5816g_dev.focus = value; - getnstimeofday(&(ad5816g_dev.timestamp_t_focus_abs)); - } - - return ret; -} - -int ad5816g_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - - return ad5816g_t_focus_abs(sd, ad5816g_dev.focus + value); -} - -int ad5816g_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - u32 status = 0; - struct timespec temptime; - const struct timespec timedelay = { - 0, - min_t(u32, abs(ad5816g_dev.number_of_steps) * DELAY_PER_STEP_NS, - DELAY_MAX_PER_STEP_NS), - }; - - ktime_get_ts(&temptime); - - temptime = timespec_sub(temptime, (ad5816g_dev.timestamp_t_focus_abs)); - - if (timespec_compare(&temptime, &timedelay) <= 0) { - status |= ATOMISP_FOCUS_STATUS_MOVING; - status |= ATOMISP_FOCUS_HP_IN_PROGRESS; - } else { - status |= ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; - status |= ATOMISP_FOCUS_HP_COMPLETE; - } - *value = status; - - return 0; -} - -int ad5816g_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - s32 val; - - ad5816g_q_focus_status(sd, &val); - - if (val & ATOMISP_FOCUS_STATUS_MOVING) - *value = ad5816g_dev.focus - ad5816g_dev.number_of_steps; - else - *value = ad5816g_dev.focus; - - return 0; -} - -int ad5816g_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -int ad5816g_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/ad5816g.h b/drivers/staging/media/atomisp/i2c/imx/ad5816g.h deleted file mode 100644 index e1396b00a0e1..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/ad5816g.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __AD5816G_H__ -#define __AD5816G_H__ - -#include "../../include/linux/atomisp_platform.h" -#include <linux/types.h> -#include <linux/time.h> - -#define AD5816G_VCM_ADDR 0x0e - -/* ad5816g device structure */ -struct ad5816g_device { - const struct camera_af_platform_data *platform_data; - struct timespec timestamp_t_focus_abs; - struct timespec focus_time; /* Time when focus was last time set */ - s32 focus; /* Current focus value */ - s16 number_of_steps; -}; - -#define AD5816G_INVALID_CONFIG 0xffffffff -#define AD5816G_MAX_FOCUS_POS 1023 -#define DELAY_PER_STEP_NS 1000000 -#define DELAY_MAX_PER_STEP_NS (1000000 * 1023) - -/* Register Definitions */ -#define AD5816G_IC_INFO 0x00 -#define AD5816G_IC_VERSION 0x01 -#define AD5816G_CONTROL 0x02 -#define AD5816G_VCM_CODE_MSB 0x03 -#define AD5816G_VCM_CODE_LSB 0x04 -#define AD5816G_STATUS 0x05 -#define AD5816G_MODE 0x06 -#define AD5816G_VCM_FREQ 0x07 -#define AD5816G_VCM_THRESHOLD 0x08 - -/* ARC MODE ENABLE */ -#define AD5816G_ARC_EN 0x02 -/* ARC RES2 MODE */ -#define AD5816G_ARC_RES2 0x01 -/* ARC VCM FREQ - 78.1Hz */ -#define AD5816G_DEF_FREQ 0x7a -/* ARC VCM THRESHOLD - 0x08 << 1 */ -#define AD5816G_DEF_THRESHOLD 0x64 -#define AD5816G_ID 0x24 -#define VCM_CODE_MASK 0x03ff - -#define AD5816G_MODE_2_5M_SWITCH_CLOCK 0x14 - -#endif - diff --git a/drivers/staging/media/atomisp/i2c/imx/common.h b/drivers/staging/media/atomisp/i2c/imx/common.h deleted file mode 100644 index af2e3160df95..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/common.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#define MAX_FPS_OPTIONS_SUPPORTED 3 -#define I2C_MSG_LENGTH 0x2 -#define E2PROM_2ADDR 0x80000000 -#define E2PROM_ADDR_MASK 0x7fffffff - -/* Defines for register writes and register array processing */ -#define IMX_BYTE_MAX 32 -#define IMX_SHORT_MAX 16 -#define I2C_RETRY_COUNT 5 -#define IMX_TOK_MASK 0xfff0 - -enum imx_tok_type { - IMX_8BIT = 0x0001, - IMX_16BIT = 0x0002, - IMX_TOK_TERM = 0xf000, /* terminating token for reg list */ - IMX_TOK_DELAY = 0xfe00 /* delay token for reg list */ -}; - -/** - * struct imx_reg - MI sensor register format - * @type: type of the register - * @reg: 16-bit offset to register - * @val: 8/16/32-bit register value - * - * Define a structure for sensor register initialization values - */ -struct imx_reg { - enum imx_tok_type type; - u16 sreg; - u32 val; /* @set value for read/mod/write, @mask */ -}; - -struct imx_fps_setting { - int fps; - unsigned short pixels_per_line; - unsigned short lines_per_frame; - int mipi_freq; /* MIPI lane frequency in kHz */ - const struct imx_reg *regs; /* regs that the fps setting needs */ -}; - -struct imx_resolution { - const struct imx_fps_setting fps_options[MAX_FPS_OPTIONS_SUPPORTED]; - u8 *desc; - const struct imx_reg *regs; - int res; - int width; - int height; - int fps; - unsigned short pixels_per_line; - unsigned short lines_per_frame; - int mipi_freq; /* MIPI lane frequency in kHz */ - unsigned short skip_frames; - u8 bin_factor_x; - u8 bin_factor_y; - bool used; -}; - -#define GROUPED_PARAMETER_HOLD_ENABLE {IMX_8BIT, 0x0104, 0x1} -#define GROUPED_PARAMETER_HOLD_DISABLE {IMX_8BIT, 0x0104, 0x0} - -int imx_write_reg(struct i2c_client *client, u16 data_length, u16 reg, u16 val); -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/drv201.c b/drivers/staging/media/atomisp/i2c/imx/drv201.c deleted file mode 100644 index 221e4875ac49..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/drv201.c +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/kmod.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include <asm/intel-mid.h> - -#include "drv201.h" - -static struct drv201_device drv201_dev; - -static int drv201_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val) -{ - struct i2c_msg msg[2]; - u8 buf[2]; - buf[0] = reg; - buf[1] = 0; - - msg[0].addr = DRV201_VCM_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &buf[0]; - - msg[1].addr = DRV201_VCM_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &buf[1]; - *val = 0; - if (i2c_transfer(client->adapter, msg, 2) != 2) - return -EIO; - *val = buf[1]; - return 0; -} - -static int drv201_i2c_wr8(struct i2c_client *client, u8 reg, u8 val) -{ - struct i2c_msg msg; - u8 buf[2]; - buf[0] = reg; - buf[1] = val; - msg.addr = DRV201_VCM_ADDR; - msg.flags = 0; - msg.len = 2; - msg.buf = &buf[0]; - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - return 0; -} - -static int drv201_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) -{ - struct i2c_msg msg; - u8 buf[3]; - buf[0] = reg; - buf[1] = (u8)(val >> 8); - buf[2] = (u8)(val & 0xff); - msg.addr = DRV201_VCM_ADDR; - msg.flags = 0; - msg.len = 3; - msg.buf = &buf[0]; - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - return 0; -} - -int drv201_vcm_power_up(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u8 value; - - /* Enable power */ - ret = drv201_dev.platform_data->power_ctrl(sd, 1); - if (ret) - return ret; - /* Wait for VBAT to stabilize */ - udelay(1); - /* - * Jiggle SCL pin to wake up device. - * Drv201 expect SCL from low to high to wake device up. - * So the 1st access to i2c would fail. - * Using following function to wake device up. - */ - drv201_i2c_wr8(client, DRV201_CONTROL, DRV201_RESET); - - /* Need 100us to transit from SHUTDOWN to STANDBY*/ - usleep_range(WAKEUP_DELAY_US, WAKEUP_DELAY_US * 10); - - /* Reset device */ - ret = drv201_i2c_wr8(client, DRV201_CONTROL, DRV201_RESET); - if (ret < 0) - goto fail_powerdown; - - /* Detect device */ - ret = drv201_i2c_rd8(client, DRV201_CONTROL, &value); - if (ret < 0) - goto fail_powerdown; - if (value != DEFAULT_CONTROL_VAL) { - ret = -ENXIO; - goto fail_powerdown; - } - - drv201_dev.focus = DRV201_MAX_FOCUS_POS; - drv201_dev.initialized = true; - - return 0; -fail_powerdown: - drv201_dev.platform_data->power_ctrl(sd, 0); - return ret; -} - -int drv201_vcm_power_down(struct v4l2_subdev *sd) -{ - return drv201_dev.platform_data->power_ctrl(sd, 0); -} - - -static int drv201_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u16 data = val & VCM_CODE_MASK; - - if (!drv201_dev.initialized) - return -ENODEV; - return drv201_i2c_wr16(client, DRV201_VCM_CURRENT, data); -} - -int drv201_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - int ret; - - value = clamp(value, 0, DRV201_MAX_FOCUS_POS); - ret = drv201_t_focus_vcm(sd, value); - if (ret == 0) { - drv201_dev.number_of_steps = value - drv201_dev.focus; - drv201_dev.focus = value; - getnstimeofday(&(drv201_dev.timestamp_t_focus_abs)); - } - - return ret; -} - -int drv201_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - return drv201_t_focus_abs(sd, drv201_dev.focus + value); -} - -int drv201_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - u32 status = 0; - struct timespec temptime; - const struct timespec timedelay = { - 0, - min_t(u32, abs(drv201_dev.number_of_steps)*DELAY_PER_STEP_NS, - DELAY_MAX_PER_STEP_NS), - }; - - ktime_get_ts(&temptime); - - temptime = timespec_sub(temptime, (drv201_dev.timestamp_t_focus_abs)); - - if (timespec_compare(&temptime, &timedelay) <= 0) { - status |= ATOMISP_FOCUS_STATUS_MOVING; - status |= ATOMISP_FOCUS_HP_IN_PROGRESS; - } else { - status |= ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; - status |= ATOMISP_FOCUS_HP_COMPLETE; - } - *value = status; - - return 0; -} - -int drv201_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - s32 val; - - drv201_q_focus_status(sd, &val); - - if (val & ATOMISP_FOCUS_STATUS_MOVING) - *value = drv201_dev.focus - drv201_dev.number_of_steps; - else - *value = drv201_dev.focus; - - return 0; -} - -int drv201_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -int drv201_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/drv201.h b/drivers/staging/media/atomisp/i2c/imx/drv201.h deleted file mode 100644 index 2ef8aafdf675..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/drv201.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __DRV201_H__ -#define __DRV201_H__ - -#include "../../include/linux/atomisp_platform.h" -#include <linux/types.h> -#include <linux/time.h> - -#define DRV201_VCM_ADDR 0x0e - -/* drv201 device structure */ -struct drv201_device { - const struct camera_af_platform_data *platform_data; - struct timespec timestamp_t_focus_abs; - struct timespec focus_time; /* Time when focus was last time set */ - s32 focus; /* Current focus value */ - s16 number_of_steps; - bool initialized; /* true if drv201 is detected */ -}; - -#define DRV201_INVALID_CONFIG 0xffffffff -#define DRV201_MAX_FOCUS_POS 1023 -#define DELAY_PER_STEP_NS 1000000 -#define DELAY_MAX_PER_STEP_NS (1000000 * 1023) - -#define DRV201_CONTROL 2 -#define DRV201_VCM_CURRENT 3 -#define DRV201_STATUS 5 -#define DRV201_MODE 6 -#define DRV201_VCM_FREQ 7 - -#define DEFAULT_CONTROL_VAL 2 -#define DRV201_RESET 1 -#define WAKEUP_DELAY_US 100 -#define VCM_CODE_MASK 0x03ff - -#endif - - diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9714.c b/drivers/staging/media/atomisp/i2c/imx/dw9714.c deleted file mode 100644 index f96855454313..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9714.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/kmod.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include <asm/intel-mid.h> - -#include "dw9714.h" - -static struct dw9714_device dw9714_dev; -static int dw9714_i2c_write(struct i2c_client *client, u16 data) -{ - struct i2c_msg msg; - const int num_msg = 1; - int ret; - u16 val; - - val = cpu_to_be16(data); - msg.addr = DW9714_VCM_ADDR; - msg.flags = 0; - msg.len = DW9714_16BIT; - msg.buf = (u8 *)&val; - - ret = i2c_transfer(client->adapter, &msg, 1); - - return ret == num_msg ? 0 : -EIO; -} - -int dw9714_vcm_power_up(struct v4l2_subdev *sd) -{ - int ret; - - /* Enable power */ - ret = dw9714_dev.platform_data->power_ctrl(sd, 1); - /* waiting time requested by DW9714A(vcm) */ - usleep_range(12000, 12500); - return ret; -} - -int dw9714_vcm_power_down(struct v4l2_subdev *sd) -{ - return dw9714_dev.platform_data->power_ctrl(sd, 0); -} - - -static int dw9714_t_focus_vcm(struct v4l2_subdev *sd, u16 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = -EINVAL; - u8 mclk = vcm_step_mclk(dw9714_dev.vcm_settings.step_setting); - u8 s = vcm_step_s(dw9714_dev.vcm_settings.step_setting); - - /* - * For different mode, VCM_PROTECTION_OFF/ON required by the - * control procedure. For DW9714_DIRECT/DLC mode, slew value is - * VCM_DEFAULT_S(0). - */ - switch (dw9714_dev.vcm_mode) { - case DW9714_DIRECT: - if (dw9714_dev.vcm_settings.update) { - ret = dw9714_i2c_write(client, VCM_PROTECTION_OFF); - if (ret) - return ret; - ret = dw9714_i2c_write(client, DIRECT_VCM); - if (ret) - return ret; - ret = dw9714_i2c_write(client, VCM_PROTECTION_ON); - if (ret) - return ret; - dw9714_dev.vcm_settings.update = false; - } - ret = dw9714_i2c_write(client, - vcm_val(val, VCM_DEFAULT_S)); - break; - case DW9714_LSC: - if (dw9714_dev.vcm_settings.update) { - ret = dw9714_i2c_write(client, VCM_PROTECTION_OFF); - if (ret) - return ret; - ret = dw9714_i2c_write(client, - vcm_dlc_mclk(DLC_DISABLE, mclk)); - if (ret) - return ret; - ret = dw9714_i2c_write(client, - vcm_tsrc(dw9714_dev.vcm_settings.t_src)); - if (ret) - return ret; - ret = dw9714_i2c_write(client, VCM_PROTECTION_ON); - if (ret) - return ret; - dw9714_dev.vcm_settings.update = false; - } - ret = dw9714_i2c_write(client, vcm_val(val, s)); - break; - case DW9714_DLC: - if (dw9714_dev.vcm_settings.update) { - ret = dw9714_i2c_write(client, VCM_PROTECTION_OFF); - if (ret) - return ret; - ret = dw9714_i2c_write(client, - vcm_dlc_mclk(DLC_ENABLE, mclk)); - if (ret) - return ret; - ret = dw9714_i2c_write(client, - vcm_tsrc(dw9714_dev.vcm_settings.t_src)); - if (ret) - return ret; - ret = dw9714_i2c_write(client, VCM_PROTECTION_ON); - if (ret) - return ret; - dw9714_dev.vcm_settings.update = false; - } - ret = dw9714_i2c_write(client, - vcm_val(val, VCM_DEFAULT_S)); - break; - } - return ret; -} - -int dw9714_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - int ret; - - value = clamp(value, 0, DW9714_MAX_FOCUS_POS); - ret = dw9714_t_focus_vcm(sd, value); - if (ret == 0) { - dw9714_dev.number_of_steps = value - dw9714_dev.focus; - dw9714_dev.focus = value; - getnstimeofday(&(dw9714_dev.timestamp_t_focus_abs)); - } - - return ret; -} - -int dw9714_t_focus_abs_init(struct v4l2_subdev *sd) -{ - int ret; - - ret = dw9714_t_focus_vcm(sd, DW9714_DEFAULT_FOCUS_POS); - if (ret == 0) { - dw9714_dev.number_of_steps = - DW9714_DEFAULT_FOCUS_POS - dw9714_dev.focus; - dw9714_dev.focus = DW9714_DEFAULT_FOCUS_POS; - getnstimeofday(&(dw9714_dev.timestamp_t_focus_abs)); - } - - return ret; -} - -int dw9714_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - - return dw9714_t_focus_abs(sd, dw9714_dev.focus + value); -} - -int dw9714_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - u32 status = 0; - struct timespec temptime; - const struct timespec timedelay = { - 0, - min_t(u32, abs(dw9714_dev.number_of_steps)*DELAY_PER_STEP_NS, - DELAY_MAX_PER_STEP_NS), - }; - - ktime_get_ts(&temptime); - - temptime = timespec_sub(temptime, (dw9714_dev.timestamp_t_focus_abs)); - - if (timespec_compare(&temptime, &timedelay) <= 0) { - status |= ATOMISP_FOCUS_STATUS_MOVING; - status |= ATOMISP_FOCUS_HP_IN_PROGRESS; - } else { - status |= ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; - status |= ATOMISP_FOCUS_HP_COMPLETE; - } - *value = status; - - return 0; -} - -int dw9714_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - s32 val; - - dw9714_q_focus_status(sd, &val); - - if (val & ATOMISP_FOCUS_STATUS_MOVING) - *value = dw9714_dev.focus - dw9714_dev.number_of_steps; - else - *value = dw9714_dev.focus; - - return 0; -} - -int dw9714_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - dw9714_dev.vcm_settings.step_setting = value; - dw9714_dev.vcm_settings.update = true; - - return 0; -} - -int dw9714_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - dw9714_dev.vcm_settings.t_src = value; - dw9714_dev.vcm_settings.update = true; - - return 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9714.h b/drivers/staging/media/atomisp/i2c/imx/dw9714.h deleted file mode 100644 index aee560026b56..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9714.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __DW9714_H__ -#define __DW9714_H__ - -#include "../../include/linux/atomisp_platform.h" -#include <linux/types.h> - - -#define DW9714_VCM_ADDR 0x0c - -enum dw9714_tok_type { - DW9714_8BIT = 0x0001, - DW9714_16BIT = 0x0002, -}; - -struct dw9714_vcm_settings { - u16 code; /* bit[9:0]: Data[9:0] */ - u8 t_src; /* bit[4:0]: T_SRC[4:0] */ - u8 step_setting; /* bit[3:0]: S[3:0]/bit[5:4]: MCLK[1:0] */ - bool update; -}; - -enum dw9714_vcm_mode { - DW9714_DIRECT = 0x1, /* direct control */ - DW9714_LSC = 0x2, /* linear slope control */ - DW9714_DLC = 0x3, /* dual level control */ -}; - -/* dw9714 device structure */ -struct dw9714_device { - struct dw9714_vcm_settings vcm_settings; - struct timespec timestamp_t_focus_abs; - enum dw9714_vcm_mode vcm_mode; - s16 number_of_steps; - bool initialized; /* true if dw9714 is detected */ - s32 focus; /* Current focus value */ - struct timespec focus_time; /* Time when focus was last time set */ - __u8 buffer[4]; /* Used for i2c transactions */ - const struct camera_af_platform_data *platform_data; -}; - -#define DW9714_INVALID_CONFIG 0xffffffff -#define DW9714_MAX_FOCUS_POS 1023 -#define DW9714_DEFAULT_FOCUS_POS 290 - - -/* MCLK[1:0] = 01 T_SRC[4:0] = 00001 S[3:0] = 0111 */ -#define DELAY_PER_STEP_NS 1000000 -#define DELAY_MAX_PER_STEP_NS (1000000 * 1023) - -#define DLC_ENABLE 1 -#define DLC_DISABLE 0 -#define VCM_PROTECTION_OFF 0xeca3 -#define VCM_PROTECTION_ON 0xdc51 -#define VCM_DEFAULT_S 0x0 - -#define vcm_step_s(a) (u8)(a & 0xf) -#define vcm_step_mclk(a) (u8)((a >> 4) & 0x3) -#define vcm_dlc_mclk(dlc, mclk) (u16)((dlc << 3) | mclk | 0xa104) -#define vcm_tsrc(tsrc) (u16)(tsrc << 3 | 0xf200) -#define vcm_val(data, s) (u16)(data << 4 | s) -#define DIRECT_VCM vcm_dlc_mclk(0, 0) - -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9718.c b/drivers/staging/media/atomisp/i2c/imx/dw9718.c deleted file mode 100644 index c02b9f0a2440..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9718.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Support for dw9718 vcm driver. - * - * Copyright (c) 2014 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#include <linux/delay.h> -#include "dw9718.h" - -static struct dw9718_device dw9718_dev; - -static int dw9718_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val) -{ - struct i2c_msg msg[2]; - u8 buf[2] = { reg }; - - msg[0].addr = DW9718_VCM_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf; - - msg[1].addr = DW9718_VCM_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &buf[1]; - *val = 0; - - if (i2c_transfer(client->adapter, msg, 2) != 2) - return -EIO; - *val = buf[1]; - - return 0; -} - -static int dw9718_i2c_wr8(struct i2c_client *client, u8 reg, u8 val) -{ - struct i2c_msg msg; - u8 buf[2] = { reg, val}; - - msg.addr = DW9718_VCM_ADDR; - msg.flags = 0; - msg.len = sizeof(buf); - msg.buf = buf; - - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static int dw9718_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) -{ - struct i2c_msg msg; - u8 buf[3] = { reg, (u8)(val >> 8), (u8)(val & 0xff)}; - - msg.addr = DW9718_VCM_ADDR; - msg.flags = 0; - msg.len = sizeof(buf); - msg.buf = buf; - - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - - return 0; -} - -int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - value = clamp(value, 0, DW9718_MAX_FOCUS_POS); - ret = dw9718_i2c_wr16(client, DW9718_DATA_M, value); - /*pr_info("%s: value = %d\n", __func__, value);*/ - if (ret < 0) - return ret; - - getnstimeofday(&dw9718_dev.focus_time); - dw9718_dev.focus = value; - - return 0; -} - -int dw9718_vcm_power_up(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u8 value; - - if (dw9718_dev.power_on) - return 0; - - /* Enable power */ - ret = dw9718_dev.platform_data->power_ctrl(sd, 1); - if (ret) { - dev_err(&client->dev, "DW9718_PD power_ctrl failed %d\n", ret); - return ret; - } - /* Wait for VBAT to stabilize */ - udelay(100); - - /* Detect device */ - ret = dw9718_i2c_rd8(client, DW9718_SACT, &value); - if (ret < 0) { - dev_err(&client->dev, "read DW9718_SACT failed %d\n", ret); - goto fail_powerdown; - } - /* - * WORKAROUND: for module P8V12F-203 which are used on - * Cherrytrail Refresh Davis Reef AoB, register SACT is not - * returning default value as spec. But VCM works as expected and - * root cause is still under discussion with vendor. - * workaround here to avoid aborting the power up sequence and just - * give a warning about this error. - */ - if (value != DW9718_SACT_DEFAULT_VAL) - dev_warn(&client->dev, "%s error, incorrect ID\n", __func__); - - /* Initialize according to recommended settings */ - ret = dw9718_i2c_wr8(client, DW9718_CONTROL, - DW9718_CONTROL_SW_LINEAR | - DW9718_CONTROL_S_SAC4 | - DW9718_CONTROL_OCP_DISABLE | - DW9718_CONTROL_UVLO_DISABLE); - if (ret < 0) { - dev_err(&client->dev, "write DW9718_CONTROL failed %d\n", ret); - goto fail_powerdown; - } - ret = dw9718_i2c_wr8(client, DW9718_SACT, - DW9718_SACT_MULT_TWO | - DW9718_SACT_PERIOD_8_8MS); - if (ret < 0) { - dev_err(&client->dev, "write DW9718_SACT failed %d\n", ret); - goto fail_powerdown; - } - - ret = dw9718_t_focus_abs(sd, dw9718_dev.focus); - if (ret) - return ret; - dw9718_dev.initialized = true; - dw9718_dev.power_on = 1; - - return 0; - -fail_powerdown: - dev_err(&client->dev, "%s error, powerup failed\n", __func__); - dw9718_dev.platform_data->power_ctrl(sd, 0); - return ret; -} - -int dw9718_vcm_power_down(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - if (!dw9718_dev.power_on) - return 0; - - ret = dw9718_dev.platform_data->power_ctrl(sd, 0); - if (ret) { - dev_err(&client->dev, "%s power_ctrl failed\n", - __func__); - return ret; - } - dw9718_dev.power_on = 0; - - return 0; -} - -int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - static const struct timespec move_time = { - .tv_sec = 0, - .tv_nsec = 60000000 - }; - struct timespec current_time, finish_time, delta_time; - - getnstimeofday(¤t_time); - finish_time = timespec_add(dw9718_dev.focus_time, move_time); - delta_time = timespec_sub(current_time, finish_time); - if (delta_time.tv_sec >= 0 && delta_time.tv_nsec >= 0) { - *value = ATOMISP_FOCUS_HP_COMPLETE | - ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; - } else { - *value = ATOMISP_FOCUS_STATUS_MOVING | - ATOMISP_FOCUS_HP_IN_PROGRESS; - } - - return 0; -} - -int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - return dw9718_t_focus_abs(sd, dw9718_dev.focus + value); -} - -int dw9718_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - *value = dw9718_dev.focus; - return 0; -} -int dw9718_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -int dw9718_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -int dw9718_vcm_init(struct v4l2_subdev *sd) -{ - dw9718_dev.platform_data = camera_get_af_platform_data(); - dw9718_dev.focus = DW9718_DEFAULT_FOCUS_POSITION; - dw9718_dev.power_on = 0; - return (NULL == dw9718_dev.platform_data) ? -ENODEV : 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9718.h b/drivers/staging/media/atomisp/i2c/imx/dw9718.h deleted file mode 100644 index 4a1040c3149f..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9718.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Support for dw9719 vcm driver. - * - * Copyright (c) 2014 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __DW9718_H__ -#define __DW9718_H__ - -#include "../../include/linux/atomisp_platform.h" -#include <linux/types.h> - -#define DW9718_VCM_ADDR (0x18 >> 1) - -/* dw9718 device structure */ -struct dw9718_device { - struct timespec timestamp_t_focus_abs; - s16 number_of_steps; - bool initialized; /* true if dw9718 is detected */ - s32 focus; /* Current focus value */ - struct timespec focus_time; /* Time when focus was last time set */ - __u8 buffer[4]; /* Used for i2c transactions */ - const struct camera_af_platform_data *platform_data; - __u8 power_on; -}; - -#define DW9718_MAX_FOCUS_POS 1023 - -/* Register addresses */ -#define DW9718_PD 0x00 -#define DW9718_CONTROL 0x01 -#define DW9718_DATA_M 0x02 -#define DW9718_DATA_L 0x03 -#define DW9718_SW 0x04 -#define DW9718_SACT 0x05 -#define DW9718_FLAG 0x10 - -#define DW9718_CONTROL_SW_LINEAR BIT(0) -#define DW9718_CONTROL_S_SAC4 (BIT(1) | BIT(3)) -#define DW9718_CONTROL_OCP_DISABLE BIT(4) -#define DW9718_CONTROL_UVLO_DISABLE BIT(5) - -#define DW9718_SACT_MULT_TWO 0x00 -#define DW9718_SACT_PERIOD_8_8MS 0x19 -#define DW9718_SACT_DEFAULT_VAL 0x60 - -#define DW9718_DEFAULT_FOCUS_POSITION 300 - -#endif /* __DW9718_H__ */ diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9719.c b/drivers/staging/media/atomisp/i2c/imx/dw9719.c deleted file mode 100644 index 565237796bb4..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9719.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Support for dw9719 vcm driver. - * - * Copyright (c) 2012 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#include <linux/delay.h> -#include "dw9719.h" - -static struct dw9719_device dw9719_dev; - -static int dw9719_i2c_rd8(struct i2c_client *client, u8 reg, u8 *val) -{ - struct i2c_msg msg[2]; - u8 buf[2] = { reg }; - - msg[0].addr = DW9719_VCM_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = buf; - - msg[1].addr = DW9719_VCM_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &buf[1]; - *val = 0; - - if (i2c_transfer(client->adapter, msg, 2) != 2) - return -EIO; - *val = buf[1]; - - return 0; -} - -static int dw9719_i2c_wr8(struct i2c_client *client, u8 reg, u8 val) -{ - struct i2c_msg msg; - u8 buf[2] = { reg, val }; - - msg.addr = DW9719_VCM_ADDR; - msg.flags = 0; - msg.len = sizeof(buf); - msg.buf = buf; - - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static int dw9719_i2c_wr16(struct i2c_client *client, u8 reg, u16 val) -{ - struct i2c_msg msg; - u8 buf[3] = { reg, (u8)(val >> 8), (u8)(val & 0xff)}; - - msg.addr = DW9719_VCM_ADDR; - msg.flags = 0; - msg.len = sizeof(buf); - msg.buf = buf; - - if (i2c_transfer(client->adapter, &msg, 1) != 1) - return -EIO; - - return 0; -} - -int dw9719_vcm_power_up(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u8 value; - - /* Enable power */ - ret = dw9719_dev.platform_data->power_ctrl(sd, 1); - /* waiting time requested by DW9714A(vcm) */ - if (ret) - return ret; - /* Wait for VBAT to stabilize */ - udelay(1); - - /* - * Jiggle SCL pin to wake up device. - */ - ret = dw9719_i2c_wr8(client, DW9719_CONTROL, 1); - /* Need 100us to transit from SHUTDOWN to STANDBY*/ - usleep_range(100, 1000); - - /* Enable the ringing compensation */ - ret = dw9719_i2c_wr8(client, DW9719_CONTROL, DW9719_ENABLE_RINGING); - if (ret < 0) - goto fail_powerdown; - - /* Use SAC3 mode */ - ret = dw9719_i2c_wr8(client, DW9719_MODE, DW9719_MODE_SAC3); - if (ret < 0) - goto fail_powerdown; - - /* Set the resonance frequency */ - ret = dw9719_i2c_wr8(client, DW9719_VCM_FREQ, DW9719_DEFAULT_VCM_FREQ); - if (ret < 0) - goto fail_powerdown; - - /* Detect device */ - ret = dw9719_i2c_rd8(client, DW9719_INFO, &value); - if (ret < 0) - goto fail_powerdown; - if (value != DW9719_ID) { - ret = -ENXIO; - goto fail_powerdown; - } - dw9719_dev.focus = 0; - dw9719_dev.initialized = true; - - return 0; - -fail_powerdown: - dw9719_dev.platform_data->power_ctrl(sd, 0); - return ret; -} - -int dw9719_vcm_power_down(struct v4l2_subdev *sd) -{ - return dw9719_dev.platform_data->power_ctrl(sd, 0); -} - -int dw9719_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - static const struct timespec move_time = { - - .tv_sec = 0, - .tv_nsec = 60000000 - }; - struct timespec current_time, finish_time, delta_time; - - getnstimeofday(¤t_time); - finish_time = timespec_add(dw9719_dev.focus_time, move_time); - delta_time = timespec_sub(current_time, finish_time); - if (delta_time.tv_sec >= 0 && delta_time.tv_nsec >= 0) { - *value = ATOMISP_FOCUS_HP_COMPLETE | - ATOMISP_FOCUS_STATUS_ACCEPTS_NEW_MOVE; - } else { - *value = ATOMISP_FOCUS_STATUS_MOVING | - ATOMISP_FOCUS_HP_IN_PROGRESS; - } - - return 0; -} - -int dw9719_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - value = clamp(value, 0, DW9719_MAX_FOCUS_POS); - ret = dw9719_i2c_wr16(client, DW9719_VCM_CURRENT, value); - if (ret < 0) - return ret; - - getnstimeofday(&dw9719_dev.focus_time); - dw9719_dev.focus = value; - - return 0; -} - -int dw9719_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - return dw9719_t_focus_abs(sd, dw9719_dev.focus + value); -} - -int dw9719_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - *value = dw9719_dev.focus; - return 0; -} -int dw9719_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} - -int dw9719_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - return 0; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/dw9719.h b/drivers/staging/media/atomisp/i2c/imx/dw9719.h deleted file mode 100644 index 711f412aef2a..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/dw9719.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Support for dw9719 vcm driver. - * - * Copyright (c) 2012 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __DW9719_H__ -#define __DW9719_H__ - -#include "../../include/linux/atomisp_platform.h" -#include <linux/types.h> - -#define DW9719_VCM_ADDR (0x18 >> 1) - -/* dw9719 device structure */ -struct dw9719_device { - struct timespec timestamp_t_focus_abs; - s16 number_of_steps; - bool initialized; /* true if dw9719 is detected */ - s32 focus; /* Current focus value */ - struct timespec focus_time; /* Time when focus was last time set */ - __u8 buffer[4]; /* Used for i2c transactions */ - const struct camera_af_platform_data *platform_data; -}; - -#define DW9719_INVALID_CONFIG 0xffffffff -#define DW9719_MAX_FOCUS_POS 1023 -#define DELAY_PER_STEP_NS 1000000 -#define DELAY_MAX_PER_STEP_NS (1000000 * 1023) - -#define DW9719_INFO 0 -#define DW9719_ID 0xF1 -#define DW9719_CONTROL 2 -#define DW9719_VCM_CURRENT 3 - -#define DW9719_MODE 6 -#define DW9719_VCM_FREQ 7 - -#define DW9719_MODE_SAC3 0x40 -#define DW9719_DEFAULT_VCM_FREQ 0x04 -#define DW9719_ENABLE_RINGING 0x02 - -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.c b/drivers/staging/media/atomisp/i2c/imx/imx.c deleted file mode 100644 index 49ab0af87096..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx.c +++ /dev/null @@ -1,2480 +0,0 @@ -/* - * Support for Sony imx 8MP camera sensor. - * - * Copyright (c) 2012 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <asm/intel-mid.h> -#include "../../include/linux/atomisp_platform.h" -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/gpio.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include "../../include/linux/libmsrlisthelper.h" -#include <linux/mm.h> -#include <linux/kmod.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include "imx.h" - -/* - * The imx135 embedded data info: - * embedded data line num: 2 - * line 0 effective data size(byte): 76 - * line 1 effective data size(byte): 113 - */ -static const uint32_t - imx135_embedded_effective_size[IMX135_EMBEDDED_DATA_LINE_NUM] - = {76, 113}; - -static enum atomisp_bayer_order imx_bayer_order_mapping[] = { - atomisp_bayer_order_rggb, - atomisp_bayer_order_grbg, - atomisp_bayer_order_gbrg, - atomisp_bayer_order_bggr -}; - -static const unsigned int -IMX227_BRACKETING_LUT_FRAME_ENTRY[IMX_MAX_AE_LUT_LENGTH] = { - 0x0E10, 0x0E1E, 0x0E2C, 0x0E3A, 0x0E48}; - -static int -imx_read_reg(struct i2c_client *client, u16 len, u16 reg, u16 *val) -{ - struct i2c_msg msg[2]; - u16 data[IMX_SHORT_MAX]; - int ret, i; - int retry = 0; - - if (len > IMX_BYTE_MAX) { - dev_err(&client->dev, "%s error, invalid data length\n", - __func__); - return -EINVAL; - } - - do { - memset(msg, 0 , sizeof(msg)); - memset(data, 0 , sizeof(data)); - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = I2C_MSG_LENGTH; - msg[0].buf = (u8 *)data; - /* high byte goes first */ - data[0] = cpu_to_be16(reg); - - msg[1].addr = client->addr; - msg[1].len = len; - msg[1].flags = I2C_M_RD; - msg[1].buf = (u8 *)data; - - ret = i2c_transfer(client->adapter, msg, 2); - if (ret != 2) { - dev_err(&client->dev, - "retrying i2c read from offset 0x%x error %d... %d\n", - reg, ret, retry); - msleep(20); - } - } while (ret != 2 && retry++ < I2C_RETRY_COUNT); - - if (ret != 2) - return -EIO; - - /* high byte comes first */ - if (len == IMX_8BIT) { - *val = (u8)data[0]; - } else { - /* 16-bit access is default when len > 1 */ - for (i = 0; i < (len >> 1); i++) - val[i] = be16_to_cpu(data[i]); - } - - return 0; -} - -static int imx_i2c_write(struct i2c_client *client, u16 len, u8 *data) -{ - struct i2c_msg msg; - int ret; - int retry = 0; - - do { - msg.addr = client->addr; - msg.flags = 0; - msg.len = len; - msg.buf = data; - - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret != 1) { - dev_err(&client->dev, - "retrying i2c write transfer... %d\n", retry); - msleep(20); - } - } while (ret != 1 && retry++ < I2C_RETRY_COUNT); - - return ret == 1 ? 0 : -EIO; -} - -int -imx_write_reg(struct i2c_client *client, u16 data_length, u16 reg, u16 val) -{ - int ret; - unsigned char data[4] = {0}; - u16 *wreg = (u16 *)data; - const u16 len = data_length + sizeof(u16); /* 16-bit address + data */ - - if (data_length != IMX_8BIT && data_length != IMX_16BIT) { - v4l2_err(client, "%s error, invalid data_length\n", __func__); - return -EINVAL; - } - - /* high byte goes out first */ - *wreg = cpu_to_be16(reg); - - if (data_length == IMX_8BIT) - data[2] = (u8)(val); - else { - /* IMX_16BIT */ - u16 *wdata = (u16 *)&data[2]; - *wdata = cpu_to_be16(val); - } - - ret = imx_i2c_write(client, len, data); - if (ret) - dev_err(&client->dev, - "write error: wrote 0x%x to offset 0x%x error %d", - val, reg, ret); - - return ret; -} - -/* - * imx_write_reg_array - Initializes a list of imx registers - * @client: i2c driver client structure - * @reglist: list of registers to be written - * - * This function initializes a list of registers. When consecutive addresses - * are found in a row on the list, this function creates a buffer and sends - * consecutive data in a single i2c_transfer(). - * - * __imx_flush_reg_array, __imx_buf_reg_array() and - * __imx_write_reg_is_consecutive() are internal functions to - * imx_write_reg_array_fast() and should be not used anywhere else. - * - */ - -static int __imx_flush_reg_array(struct i2c_client *client, - struct imx_write_ctrl *ctrl) -{ - u16 size; - - if (ctrl->index == 0) - return 0; - - size = sizeof(u16) + ctrl->index; /* 16-bit address + data */ - ctrl->buffer.addr = cpu_to_be16(ctrl->buffer.addr); - ctrl->index = 0; - - return imx_i2c_write(client, size, (u8 *)&ctrl->buffer); -} - -static int __imx_buf_reg_array(struct i2c_client *client, - struct imx_write_ctrl *ctrl, - const struct imx_reg *next) -{ - int size; - u16 *data16; - - switch (next->type) { - case IMX_8BIT: - size = 1; - ctrl->buffer.data[ctrl->index] = (u8)next->val; - break; - case IMX_16BIT: - size = 2; - data16 = (u16 *)&ctrl->buffer.data[ctrl->index]; - *data16 = cpu_to_be16((u16)next->val); - break; - default: - return -EINVAL; - } - - /* When first item is added, we need to store its starting address */ - if (ctrl->index == 0) - ctrl->buffer.addr = next->sreg; - - ctrl->index += size; - - /* - * Buffer cannot guarantee free space for u32? Better flush it to avoid - * possible lack of memory for next item. - */ - if (ctrl->index + sizeof(u16) >= IMX_MAX_WRITE_BUF_SIZE) - return __imx_flush_reg_array(client, ctrl); - - return 0; -} - -static int -__imx_write_reg_is_consecutive(struct i2c_client *client, - struct imx_write_ctrl *ctrl, - const struct imx_reg *next) -{ - if (ctrl->index == 0) - return 1; - - return ctrl->buffer.addr + ctrl->index == next->sreg; -} - -static int imx_write_reg_array(struct i2c_client *client, - const struct imx_reg *reglist) -{ - const struct imx_reg *next = reglist; - struct imx_write_ctrl ctrl; - int err; - - ctrl.index = 0; - for (; next->type != IMX_TOK_TERM; next++) { - switch (next->type & IMX_TOK_MASK) { - case IMX_TOK_DELAY: - err = __imx_flush_reg_array(client, &ctrl); - if (err) - return err; - msleep(next->val); - break; - - default: - /* - * If next address is not consecutive, data needs to be - * flushed before proceed. - */ - if (!__imx_write_reg_is_consecutive(client, &ctrl, - next)) { - err = __imx_flush_reg_array(client, &ctrl); - if (err) - return err; - } - err = __imx_buf_reg_array(client, &ctrl, next); - if (err) { - v4l2_err(client, "%s: write error, aborted\n", - __func__); - return err; - } - break; - } - } - - return __imx_flush_reg_array(client, &ctrl); -} - -static int __imx_min_fps_diff(int fps, const struct imx_fps_setting *fps_list) -{ - int diff = INT_MAX; - int i; - - if (fps == 0) - return 0; - - for (i = 0; i < MAX_FPS_OPTIONS_SUPPORTED; i++) { - if (!fps_list[i].fps) - break; - if (abs(fps_list[i].fps - fps) < diff) - diff = abs(fps_list[i].fps - fps); - } - - return diff; -} - -static int __imx_nearest_fps_index(int fps, - const struct imx_fps_setting *fps_list) -{ - int fps_index = 0; - int i; - - for (i = 0; i < MAX_FPS_OPTIONS_SUPPORTED; i++) { - if (!fps_list[i].fps) - break; - if (abs(fps_list[i].fps - fps) - < abs(fps_list[fps_index].fps - fps)) - fps_index = i; - } - return fps_index; -} - -/* - * This is to choose the nearest fps setting above the requested fps - * fps_list should be in ascendant order. - */ -static int __imx_above_nearest_fps_index(int fps, - const struct imx_fps_setting *fps_list) -{ - int fps_index = 0; - int i; - - for (i = 0; i < MAX_FPS_OPTIONS_SUPPORTED; i++) { - if (!fps_list[i].fps) - break; - if (fps <= fps_list[i].fps) { - fps_index = i; - break; - } - } - - return fps_index; -} - -static int imx_get_lanes(struct v4l2_subdev *sd) -{ - struct camera_mipi_info *imx_info = v4l2_get_subdev_hostdata(sd); - - if (!imx_info) - return -ENOSYS; - if (imx_info->num_lanes < 1 || imx_info->num_lanes > 4 || - imx_info->num_lanes == 3) - return -EINVAL; - - return imx_info->num_lanes; -} - -static int __imx_update_exposure_timing(struct i2c_client *client, u16 exposure, - u16 llp, u16 fll) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx_device *dev = to_imx_sensor(sd); - int ret = 0; - - if (dev->sensor_id != IMX227_ID) { - /* Increase the VTS to match exposure + margin */ - if (exposure > fll - IMX_INTEGRATION_TIME_MARGIN) - fll = exposure + IMX_INTEGRATION_TIME_MARGIN; - } - - ret = imx_write_reg(client, IMX_16BIT, - dev->reg_addr->line_length_pixels, llp); - if (ret) - return ret; - - ret = imx_write_reg(client, IMX_16BIT, - dev->reg_addr->frame_length_lines, fll); - if (ret) - return ret; - - if (exposure) - ret = imx_write_reg(client, IMX_16BIT, - dev->reg_addr->coarse_integration_time, exposure); - - return ret; -} - -static int __imx_update_gain(struct v4l2_subdev *sd, u16 gain) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - /* set global gain */ - ret = imx_write_reg(client, IMX_8BIT, dev->reg_addr->global_gain, gain); - if (ret) - return ret; - - /* set short analog gain */ - if (dev->sensor_id == IMX135_ID) - ret = imx_write_reg(client, IMX_8BIT, IMX_SHORT_AGC_GAIN, gain); - - return ret; -} - -static int __imx_update_digital_gain(struct i2c_client *client, u16 digitgain) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx_device *dev = to_imx_sensor(sd); - struct imx_write_buffer digit_gain; - - digit_gain.addr = cpu_to_be16(dev->reg_addr->dgc_adj); - digit_gain.data[0] = (digitgain >> 8) & 0xFF; - digit_gain.data[1] = digitgain & 0xFF; - - if (dev->sensor_id == IMX219_ID) { - return imx_i2c_write(client, IMX219_DGC_LEN, (u8 *)&digit_gain); - } else if (dev->sensor_id == IMX227_ID) { - return imx_i2c_write(client, IMX227_DGC_LEN, (u8 *)&digit_gain); - } else { - digit_gain.data[2] = (digitgain >> 8) & 0xFF; - digit_gain.data[3] = digitgain & 0xFF; - digit_gain.data[4] = (digitgain >> 8) & 0xFF; - digit_gain.data[5] = digitgain & 0xFF; - digit_gain.data[6] = (digitgain >> 8) & 0xFF; - digit_gain.data[7] = digitgain & 0xFF; - return imx_i2c_write(client, IMX_DGC_LEN, (u8 *)&digit_gain); - } - return 0; -} - -static int imx_set_exposure_gain(struct v4l2_subdev *sd, u16 coarse_itg, - u16 gain, u16 digitgain) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int lanes = imx_get_lanes(sd); - unsigned int digitgain_scaled; - int ret = 0; - - /* Validate exposure: cannot exceed VTS-4 where VTS is 16bit */ - coarse_itg = clamp_t(u16, coarse_itg, 0, IMX_MAX_EXPOSURE_SUPPORTED); - - /* Validate gain: must not exceed maximum 8bit value */ - gain = clamp_t(u16, gain, 0, IMX_MAX_GLOBAL_GAIN_SUPPORTED); - - mutex_lock(&dev->input_lock); - - if (dev->sensor_id == IMX227_ID) { - ret = imx_write_reg_array(client, imx_param_hold); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; - } - } - - /* For imx175, setting gain must be delayed by one */ - if ((dev->sensor_id == IMX175_ID) && dev->digital_gain) - digitgain_scaled = dev->digital_gain; - else - digitgain_scaled = digitgain; - /* imx132 with two lanes needs more gain to saturate at max */ - if (dev->sensor_id == IMX132_ID && lanes > 1) { - digitgain_scaled *= IMX132_2LANES_GAINFACT; - digitgain_scaled >>= IMX132_2LANES_GAINFACT_SHIFT; - } - /* Validate digital gain: must not exceed 12 bit value*/ - digitgain_scaled = clamp_t(unsigned int, digitgain_scaled, - 0, IMX_MAX_DIGITAL_GAIN_SUPPORTED); - - ret = __imx_update_exposure_timing(client, coarse_itg, - dev->pixels_per_line, dev->lines_per_frame); - if (ret) - goto out; - dev->coarse_itg = coarse_itg; - - if (dev->sensor_id == IMX175_ID) - ret = __imx_update_gain(sd, dev->gain); - else - ret = __imx_update_gain(sd, gain); - if (ret) - goto out; - dev->gain = gain; - - ret = __imx_update_digital_gain(client, digitgain_scaled); - if (ret) - goto out; - dev->digital_gain = digitgain; - -out: - if (dev->sensor_id == IMX227_ID) - ret = imx_write_reg_array(client, imx_param_update); - mutex_unlock(&dev->input_lock); - return ret; -} - -static long imx_s_exposure(struct v4l2_subdev *sd, - struct atomisp_exposure *exposure) -{ - return imx_set_exposure_gain(sd, exposure->integration_time[0], - exposure->gain[0], exposure->gain[1]); -} - -/* FIXME -To be updated with real OTP reading */ -static int imx_g_priv_int_data(struct v4l2_subdev *sd, - struct v4l2_private_int_data *priv) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - u8 __user *to = priv->data; - u32 read_size = priv->size; - int ret; - - /* No need to copy data if size is 0 */ - if (!read_size) - goto out; - - if (IS_ERR(dev->otp_data)) { - dev_err(&client->dev, "OTP data not available"); - return PTR_ERR(dev->otp_data); - } - /* Correct read_size value only if bigger than maximum */ - if (read_size > dev->otp_driver->size) - read_size = dev->otp_driver->size; - - ret = copy_to_user(to, dev->otp_data, read_size); - if (ret) { - dev_err(&client->dev, "%s: failed to copy OTP data to user\n", - __func__); - return -EFAULT; - } -out: - /* Return correct size */ - priv->size = dev->otp_driver->size; - - return 0; -} - -static int __imx_init(struct v4l2_subdev *sd, u32 val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - int lanes = imx_get_lanes(sd); - int ret; - - if (dev->sensor_id == IMX_ID_DEFAULT) - return 0; - - /* The default is no flip at sensor initialization */ - dev->h_flip->cur.val = 0; - dev->v_flip->cur.val = 0; - /* Sets the default FPS */ - dev->fps_index = 0; - dev->curr_res_table = dev->mode_tables->res_preview; - dev->entries_curr_table = dev->mode_tables->n_res_preview; - - ret = imx_write_reg_array(client, dev->mode_tables->init_settings); - if (ret) - return ret; - - if (dev->sensor_id == IMX132_ID && lanes > 0) { - static const u8 imx132_rglanesel[] = { - IMX132_RGLANESEL_1LANE, /* 1 lane */ - IMX132_RGLANESEL_2LANES, /* 2 lanes */ - IMX132_RGLANESEL_1LANE, /* undefined */ - IMX132_RGLANESEL_4LANES, /* 4 lanes */ - }; - ret = imx_write_reg(client, IMX_8BIT, - IMX132_RGLANESEL, imx132_rglanesel[lanes - 1]); - } - - return ret; -} - -static int imx_init(struct v4l2_subdev *sd, u32 val) -{ - struct imx_device *dev = to_imx_sensor(sd); - int ret = 0; - - mutex_lock(&dev->input_lock); - ret = __imx_init(sd, val); - mutex_unlock(&dev->input_lock); - - return ret; -} - -static long imx_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) -{ - - switch (cmd) { - case ATOMISP_IOC_S_EXPOSURE: - return imx_s_exposure(sd, arg); - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: - return imx_g_priv_int_data(sd, arg); - default: - return -EINVAL; - } - return 0; -} - -static int power_up(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - int ret; - - /* power control */ - ret = dev->platform_data->power_ctrl(sd, 1); - if (ret) - goto fail_power; - - /* flis clock control */ - ret = dev->platform_data->flisclk_ctrl(sd, 1); - if (ret) - goto fail_clk; - - /* gpio ctrl */ - ret = dev->platform_data->gpio_ctrl(sd, 1); - if (ret) { - dev_err(&client->dev, "gpio failed\n"); - goto fail_gpio; - } - - return 0; -fail_gpio: - dev->platform_data->gpio_ctrl(sd, 0); -fail_clk: - dev->platform_data->flisclk_ctrl(sd, 0); -fail_power: - dev->platform_data->power_ctrl(sd, 0); - dev_err(&client->dev, "sensor power-up failed\n"); - - return ret; -} - -static int power_down(struct v4l2_subdev *sd) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - ret = dev->platform_data->flisclk_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "flisclk failed\n"); - - /* gpio ctrl */ - ret = dev->platform_data->gpio_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "gpio failed\n"); - - /* power control */ - ret = dev->platform_data->power_ctrl(sd, 0); - if (ret) - dev_err(&client->dev, "vprog failed.\n"); - - return ret; -} - -static int __imx_s_power(struct v4l2_subdev *sd, int on) -{ - struct imx_device *dev = to_imx_sensor(sd); - int ret = 0; - int r = 0; - - if (on == 0) { - ret = power_down(sd); - if (dev->vcm_driver && dev->vcm_driver->power_down) - r = dev->vcm_driver->power_down(sd); - if (ret == 0) - ret = r; - dev->power = 0; - } else { - if (dev->vcm_driver && dev->vcm_driver->power_up) - ret = dev->vcm_driver->power_up(sd); - if (ret) - return ret; - ret = power_up(sd); - if (!ret) { - dev->power = 1; - return __imx_init(sd, 0); - } - } - - return ret; -} - -static int imx_s_power(struct v4l2_subdev *sd, int on) -{ - int ret; - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - ret = __imx_s_power(sd, on); - mutex_unlock(&dev->input_lock); - - return ret; -} - -static int imx_get_intg_factor(struct i2c_client *client, - struct camera_mipi_info *info, - const struct imx_reg *reglist) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx_device *dev = to_imx_sensor(sd); - int lanes = imx_get_lanes(sd); - u32 vt_pix_clk_div; - u32 vt_sys_clk_div; - u32 pre_pll_clk_div; - u32 pll_multiplier; - - const int ext_clk_freq_hz = 19200000; - struct atomisp_sensor_mode_data *buf = &info->data; - int ret; - u16 data[IMX_INTG_BUF_COUNT]; - - u32 vt_pix_clk_freq_mhz; - u32 coarse_integration_time_min; - u32 coarse_integration_time_max_margin; - u32 read_mode; - u32 div; - - if (info == NULL) - return -EINVAL; - - memset(data, 0, IMX_INTG_BUF_COUNT * sizeof(u16)); - ret = imx_read_reg(client, 1, IMX_VT_PIX_CLK_DIV, data); - if (ret) - return ret; - vt_pix_clk_div = data[0] & IMX_MASK_5BIT; - - if (dev->sensor_id == IMX132_ID || dev->sensor_id == IMX208_ID) { - static const int rgpltd[] = { 2, 4, 1, 1 }; - ret = imx_read_reg(client, 1, IMX132_208_VT_RGPLTD, data); - if (ret) - return ret; - vt_sys_clk_div = rgpltd[data[0] & IMX_MASK_2BIT]; - } else { - ret = imx_read_reg(client, 1, IMX_VT_SYS_CLK_DIV, data); - if (ret) - return ret; - vt_sys_clk_div = data[0] & IMX_MASK_2BIT; - } - ret = imx_read_reg(client, 1, IMX_PRE_PLL_CLK_DIV, data); - if (ret) - return ret; - pre_pll_clk_div = data[0] & IMX_MASK_4BIT; - - ret = imx_read_reg(client, 2, - (dev->sensor_id == IMX132_ID || - dev->sensor_id == IMX219_ID || - dev->sensor_id == IMX208_ID) ? - IMX132_208_219_PLL_MULTIPLIER : IMX_PLL_MULTIPLIER, data); - if (ret) - return ret; - pll_multiplier = data[0] & IMX_MASK_11BIT; - - memset(data, 0, IMX_INTG_BUF_COUNT * sizeof(u16)); - ret = imx_read_reg(client, 4, IMX_COARSE_INTG_TIME_MIN, data); - if (ret) - return ret; - coarse_integration_time_min = data[0]; - coarse_integration_time_max_margin = data[1]; - - /* Get the cropping and output resolution to ISP for this mode. */ - ret = imx_read_reg(client, 2, dev->reg_addr->horizontal_start_h, data); - if (ret) - return ret; - buf->crop_horizontal_start = data[0]; - - ret = imx_read_reg(client, 2, dev->reg_addr->vertical_start_h, data); - if (ret) - return ret; - buf->crop_vertical_start = data[0]; - - ret = imx_read_reg(client, 2, dev->reg_addr->horizontal_end_h, data); - if (ret) - return ret; - buf->crop_horizontal_end = data[0]; - - ret = imx_read_reg(client, 2, dev->reg_addr->vertical_end_h, data); - if (ret) - return ret; - buf->crop_vertical_end = data[0]; - - ret = imx_read_reg(client, 2, - dev->reg_addr->horizontal_output_size_h, data); - if (ret) - return ret; - buf->output_width = data[0]; - - ret = imx_read_reg(client, 2, - dev->reg_addr->vertical_output_size_h, data); - if (ret) - return ret; - buf->output_height = data[0]; - - memset(data, 0, IMX_INTG_BUF_COUNT * sizeof(u16)); - if (dev->sensor_id == IMX132_ID || dev->sensor_id == IMX208_ID || - dev->sensor_id == IMX219_ID) - read_mode = 0; - else { - if (dev->sensor_id == IMX227_ID) - ret = imx_read_reg(client, 1, IMX227_READ_MODE, data); - else - ret = imx_read_reg(client, 1, IMX_READ_MODE, data); - - if (ret) - return ret; - read_mode = data[0] & IMX_MASK_2BIT; - } - - div = pre_pll_clk_div*vt_sys_clk_div*vt_pix_clk_div; - if (div == 0) - return -EINVAL; - - if (dev->sensor_id == IMX132_ID || dev->sensor_id == IMX208_ID) - vt_pix_clk_freq_mhz = ext_clk_freq_hz / div; - else if (dev->sensor_id == IMX227_ID) { - /* according to IMX227 datasheet: - * vt_pix_freq_mhz = * num_of_vt_lanes(4) * ivt_pix_clk_freq_mhz - */ - vt_pix_clk_freq_mhz = - (u64)4 * ext_clk_freq_hz * pll_multiplier; - do_div(vt_pix_clk_freq_mhz, div); - } else - vt_pix_clk_freq_mhz = 2 * ext_clk_freq_hz / div; - - vt_pix_clk_freq_mhz *= pll_multiplier; - if (dev->sensor_id == IMX132_ID && lanes > 0) - vt_pix_clk_freq_mhz *= lanes; - - dev->vt_pix_clk_freq_mhz = vt_pix_clk_freq_mhz; - - buf->vt_pix_clk_freq_mhz = vt_pix_clk_freq_mhz; - buf->coarse_integration_time_min = coarse_integration_time_min; - buf->coarse_integration_time_max_margin = - coarse_integration_time_max_margin; - - buf->fine_integration_time_min = IMX_FINE_INTG_TIME; - buf->fine_integration_time_max_margin = IMX_FINE_INTG_TIME; - buf->fine_integration_time_def = IMX_FINE_INTG_TIME; - buf->frame_length_lines = dev->lines_per_frame; - buf->line_length_pck = dev->pixels_per_line; - buf->read_mode = read_mode; - - if (dev->sensor_id == IMX132_ID || dev->sensor_id == IMX208_ID || - dev->sensor_id == IMX219_ID) { - buf->binning_factor_x = 1; - buf->binning_factor_y = 1; - } else { - if (dev->sensor_id == IMX227_ID) - ret = imx_read_reg(client, 1, IMX227_BINNING_ENABLE, - data); - else - ret = imx_read_reg(client, 1, IMX_BINNING_ENABLE, data); - - if (ret) - return ret; - /* 1:binning enabled, 0:disabled */ - if (data[0] == 1) { - if (dev->sensor_id == IMX227_ID) - ret = imx_read_reg(client, 1, - IMX227_BINNING_TYPE, data); - else - ret = imx_read_reg(client, 1, - IMX_BINNING_TYPE, data); - - if (ret) - return ret; - buf->binning_factor_x = data[0] >> 4 & 0x0f; - if (!buf->binning_factor_x) - buf->binning_factor_x = 1; - buf->binning_factor_y = data[0] & 0xf; - if (!buf->binning_factor_y) - buf->binning_factor_y = 1; - /* WOWRKAROUND, NHD setting for IMX227 should have 4x4 - * binning but the register setting does not reflect - * this, I am asking vendor why this happens. this is - * workaround for INTEL BZ 216560. - */ - if (dev->sensor_id == IMX227_ID) { - if (dev->curr_res_table[dev->fmt_idx].width == - 376 && - dev->curr_res_table[dev->fmt_idx].height == - 656) { - buf->binning_factor_x = 4; - buf->binning_factor_y = 4; - } - } - } else { - buf->binning_factor_x = 1; - buf->binning_factor_y = 1; - } - } - - return 0; -} - -/* This returns the exposure time being used. This should only be used - for filling in EXIF data, not for actual image processing. */ -static int imx_q_exposure(struct v4l2_subdev *sd, s32 *value) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - u16 coarse; - int ret; - - /* the fine integration time is currently not calculated */ - ret = imx_read_reg(client, IMX_16BIT, - dev->reg_addr->coarse_integration_time, &coarse); - *value = coarse; - - return ret; -} - -static int imx_test_pattern(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - int ret; - - if (dev->power == 0) - return 0; - - ret = imx_write_reg(client, IMX_16BIT, IMX_TEST_PATTERN_COLOR_R, - (u16)(dev->tp_r->val >> 22)); - if (ret) - return ret; - - ret = imx_write_reg(client, IMX_16BIT, IMX_TEST_PATTERN_COLOR_GR, - (u16)(dev->tp_gr->val >> 22)); - if (ret) - return ret; - - ret = imx_write_reg(client, IMX_16BIT, IMX_TEST_PATTERN_COLOR_GB, - (u16)(dev->tp_gb->val >> 22)); - if (ret) - return ret; - - ret = imx_write_reg(client, IMX_16BIT, IMX_TEST_PATTERN_COLOR_B, - (u16)(dev->tp_b->val >> 22)); - if (ret) - return ret; - - return imx_write_reg(client, IMX_16BIT, IMX_TEST_PATTERN_MODE, - (u16)(dev->tp_mode->val)); -} - -static u32 imx_translate_bayer_order(enum atomisp_bayer_order code) -{ - switch (code) { - case atomisp_bayer_order_rggb: - return MEDIA_BUS_FMT_SRGGB10_1X10; - case atomisp_bayer_order_grbg: - return MEDIA_BUS_FMT_SGRBG10_1X10; - case atomisp_bayer_order_bggr: - return MEDIA_BUS_FMT_SBGGR10_1X10; - case atomisp_bayer_order_gbrg: - return MEDIA_BUS_FMT_SGBRG10_1X10; - } - return 0; -} - -static int imx_v_flip(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct camera_mipi_info *imx_info = NULL; - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u16 val; - - if (dev->power == 0) - return -EIO; - - ret = imx_write_reg_array(client, dev->param_hold); - if (ret) - return ret; - - ret = imx_read_reg(client, IMX_8BIT, - dev->reg_addr->img_orientation, &val); - if (ret) - return ret; - if (value) - val |= IMX_VFLIP_BIT; - else - val &= ~IMX_VFLIP_BIT; - - ret = imx_write_reg(client, IMX_8BIT, - dev->reg_addr->img_orientation, val); - if (ret) - return ret; - - imx_info = v4l2_get_subdev_hostdata(sd); - if (imx_info) { - val &= (IMX_VFLIP_BIT|IMX_HFLIP_BIT); - imx_info->raw_bayer_order = imx_bayer_order_mapping[val]; - dev->format.code = imx_translate_bayer_order( - imx_info->raw_bayer_order); - } - - return imx_write_reg_array(client, dev->param_update); -} - -static int imx_h_flip(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct camera_mipi_info *imx_info = NULL; - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - u16 val; - - if (dev->power == 0) - return -EIO; - - ret = imx_write_reg_array(client, dev->param_hold); - if (ret) - return ret; - ret = imx_read_reg(client, IMX_8BIT, - dev->reg_addr->img_orientation, &val); - if (ret) - return ret; - if (value) - val |= IMX_HFLIP_BIT; - else - val &= ~IMX_HFLIP_BIT; - ret = imx_write_reg(client, IMX_8BIT, - dev->reg_addr->img_orientation, val); - if (ret) - return ret; - - imx_info = v4l2_get_subdev_hostdata(sd); - if (imx_info) { - val &= (IMX_VFLIP_BIT|IMX_HFLIP_BIT); - imx_info->raw_bayer_order = imx_bayer_order_mapping[val]; - dev->format.code = imx_translate_bayer_order( - imx_info->raw_bayer_order); - } - - return imx_write_reg_array(client, dev->param_update); -} - -static int imx_g_focal(struct v4l2_subdev *sd, s32 *val) -{ - *val = (IMX_FOCAL_LENGTH_NUM << 16) | IMX_FOCAL_LENGTH_DEM; - return 0; -} - -static int imx_g_fnumber(struct v4l2_subdev *sd, s32 *val) -{ - /*const f number for imx*/ - *val = (IMX_F_NUMBER_DEFAULT_NUM << 16) | IMX_F_NUMBER_DEM; - return 0; -} - -static int imx_g_fnumber_range(struct v4l2_subdev *sd, s32 *val) -{ - *val = (IMX_F_NUMBER_DEFAULT_NUM << 24) | - (IMX_F_NUMBER_DEM << 16) | - (IMX_F_NUMBER_DEFAULT_NUM << 8) | IMX_F_NUMBER_DEM; - return 0; -} - -static int imx_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val) -{ - struct imx_device *dev = to_imx_sensor(sd); - - *val = dev->curr_res_table[dev->fmt_idx].bin_factor_x; - - return 0; -} - -static int imx_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val) -{ - struct imx_device *dev = to_imx_sensor(sd); - - *val = dev->curr_res_table[dev->fmt_idx].bin_factor_y; - - return 0; -} - -static int imx_t_focus_abs(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->t_focus_abs) - return dev->vcm_driver->t_focus_abs(sd, value); - return 0; -} - -static int imx_t_focus_rel(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->t_focus_rel) - return dev->vcm_driver->t_focus_rel(sd, value); - return 0; -} - -static int imx_q_focus_status(struct v4l2_subdev *sd, s32 *value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->q_focus_status) - return dev->vcm_driver->q_focus_status(sd, value); - return 0; -} - -static int imx_q_focus_abs(struct v4l2_subdev *sd, s32 *value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->q_focus_abs) - return dev->vcm_driver->q_focus_abs(sd, value); - return 0; -} - -static int imx_t_vcm_slew(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->t_vcm_slew) - return dev->vcm_driver->t_vcm_slew(sd, value); - return 0; -} - -static int imx_t_vcm_timing(struct v4l2_subdev *sd, s32 value) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (dev->vcm_driver && dev->vcm_driver->t_vcm_timing) - return dev->vcm_driver->t_vcm_timing(sd, value); - return 0; -} - -static int imx_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct imx_device *dev = container_of( - ctrl->handler, struct imx_device, ctrl_handler); - struct i2c_client *client = v4l2_get_subdevdata(&dev->sd); - int ret = 0; - - switch (ctrl->id) { - case V4L2_CID_TEST_PATTERN: - ret = imx_test_pattern(&dev->sd); - break; - case V4L2_CID_VFLIP: - dev_dbg(&client->dev, "%s: CID_VFLIP:%d.\n", - __func__, ctrl->val); - ret = imx_v_flip(&dev->sd, ctrl->val); - break; - case V4L2_CID_HFLIP: - dev_dbg(&client->dev, "%s: CID_HFLIP:%d.\n", - __func__, ctrl->val); - ret = imx_h_flip(&dev->sd, ctrl->val); - break; - case V4L2_CID_FOCUS_ABSOLUTE: - ret = imx_t_focus_abs(&dev->sd, ctrl->val); - break; - case V4L2_CID_FOCUS_RELATIVE: - ret = imx_t_focus_rel(&dev->sd, ctrl->val); - break; - case V4L2_CID_VCM_SLEW: - ret = imx_t_vcm_slew(&dev->sd, ctrl->val); - break; - case V4L2_CID_VCM_TIMEING: - ret = imx_t_vcm_timing(&dev->sd, ctrl->val); - break; - } - - return ret; -} - -static int imx_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct imx_device *dev = container_of( - ctrl->handler, struct imx_device, ctrl_handler); - int ret = 0; - unsigned int val; - - switch (ctrl->id) { - case V4L2_CID_EXPOSURE_ABSOLUTE: - ret = imx_q_exposure(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FOCUS_ABSOLUTE: - ret = imx_q_focus_abs(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FOCUS_STATUS: - ret = imx_q_focus_status(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FOCAL_ABSOLUTE: - ret = imx_g_focal(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FNUMBER_ABSOLUTE: - ret = imx_g_fnumber(&dev->sd, &ctrl->val); - break; - case V4L2_CID_FNUMBER_RANGE: - ret = imx_g_fnumber_range(&dev->sd, &ctrl->val); - break; - case V4L2_CID_BIN_FACTOR_HORZ: - ret = imx_g_bin_factor_x(&dev->sd, &ctrl->val); - break; - case V4L2_CID_BIN_FACTOR_VERT: - ret = imx_g_bin_factor_y(&dev->sd, &ctrl->val); - break; - case V4L2_CID_VBLANK: - ctrl->val = dev->lines_per_frame - - dev->curr_res_table[dev->fmt_idx].height; - break; - case V4L2_CID_HBLANK: - ctrl->val = dev->pixels_per_line - - dev->curr_res_table[dev->fmt_idx].width; - break; - case V4L2_CID_PIXEL_RATE: - ctrl->val = dev->vt_pix_clk_freq_mhz; - break; - case V4L2_CID_LINK_FREQ: - val = dev->curr_res_table[dev->fmt_idx]. - fps_options[dev->fps_index].mipi_freq; - if (val == 0) - val = dev->curr_res_table[dev->fmt_idx].mipi_freq; - if (val == 0) - return -EINVAL; - ctrl->val = val * 1000; /* To Hz */ - break; - default: - return -EINVAL; - } - - return ret; -} - -static const struct v4l2_ctrl_ops ctrl_ops = { - .s_ctrl = imx_s_ctrl, - .g_volatile_ctrl = imx_g_volatile_ctrl -}; - -static const struct v4l2_ctrl_config imx_controls[] = { - { - .ops = &ctrl_ops, - .id = V4L2_CID_EXPOSURE_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "exposure", - .min = 0x0, - .max = 0xffff, - .step = 0x01, - .def = 0x00, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_TEST_PATTERN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Test pattern", - .min = 0, - .max = 0xffff, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_TEST_PATTERN_COLOR_R, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Test pattern solid color R", - .min = INT_MIN, - .max = INT_MAX, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_TEST_PATTERN_COLOR_GR, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Test pattern solid color GR", - .min = INT_MIN, - .max = INT_MAX, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_TEST_PATTERN_COLOR_GB, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Test pattern solid color GB", - .min = INT_MIN, - .max = INT_MAX, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_TEST_PATTERN_COLOR_B, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Test pattern solid color B", - .min = INT_MIN, - .max = INT_MAX, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip", - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mirror", - .min = 0, - .max = 1, - .step = 1, - .def = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FOCUS_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "focus move absolute", - .min = 0, - .max = IMX_MAX_FOCUS_POS, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FOCUS_RELATIVE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "focus move relative", - .min = IMX_MAX_FOCUS_NEG, - .max = IMX_MAX_FOCUS_POS, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FOCUS_STATUS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "focus status", - .min = 0, - .max = 100, /* allow enum to grow in the future */ - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VCM_SLEW, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "vcm slew", - .min = 0, - .max = IMX_VCM_SLEW_STEP_MAX, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VCM_TIMEING, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "vcm step time", - .min = 0, - .max = IMX_VCM_SLEW_TIME_MAX, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FOCAL_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "focal length", - .min = IMX_FOCAL_LENGTH_DEFAULT, - .max = IMX_FOCAL_LENGTH_DEFAULT, - .step = 0x01, - .def = IMX_FOCAL_LENGTH_DEFAULT, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FNUMBER_ABSOLUTE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "f-number", - .min = IMX_F_NUMBER_DEFAULT, - .max = IMX_F_NUMBER_DEFAULT, - .step = 0x01, - .def = IMX_F_NUMBER_DEFAULT, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_FNUMBER_RANGE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "f-number range", - .min = IMX_F_NUMBER_RANGE, - .max = IMX_F_NUMBER_RANGE, - .step = 0x01, - .def = IMX_F_NUMBER_RANGE, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_BIN_FACTOR_HORZ, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "horizontal binning factor", - .min = 0, - .max = IMX_BIN_FACTOR_MAX, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_BIN_FACTOR_VERT, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "vertical binning factor", - .min = 0, - .max = IMX_BIN_FACTOR_MAX, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_LINK_FREQ, - .name = "Link Frequency", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 1, - .max = 1500000 * 1000, - .step = 1, - .def = 1, - .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_PIXEL_RATE, - .name = "Pixel Rate", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = INT_MAX, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_HBLANK, - .name = "Horizontal Blanking", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = SHRT_MAX, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VBLANK, - .name = "Vertical Blanking", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = SHRT_MAX, - .step = 1, - .def = 0, - .flags = V4L2_CTRL_FLAG_VOLATILE, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_HFLIP, - .name = "Horizontal Flip", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 1, - .step = 1, - .def = 0, - .flags = 0, - }, - { - .ops = &ctrl_ops, - .id = V4L2_CID_VFLIP, - .name = "Vertical Flip", - .type = V4L2_CTRL_TYPE_INTEGER, - .min = 0, - .max = 1, - .step = 1, - .def = 0, - .flags = 0, - }, -}; - -/* - * distance - calculate the distance - * @res: resolution - * @w: width - * @h: height - * - * Get the gap between resolution and w/h. - * res->width/height smaller than w/h wouldn't be considered. - * Returns the value of gap or -1 if fail. - */ -#define LARGEST_ALLOWED_RATIO_MISMATCH 600 -static int distance(struct imx_resolution const *res, u32 w, u32 h, - bool keep_ratio) -{ - unsigned int w_ratio; - unsigned int h_ratio; - int match; - unsigned int allowed_ratio_mismatch = LARGEST_ALLOWED_RATIO_MISMATCH; - - if (!keep_ratio) - allowed_ratio_mismatch = ~0; - - if (w == 0) - return -1; - w_ratio = (res->width << 13) / w; - if (h == 0) - return -1; - h_ratio = (res->height << 13) / h; - if (h_ratio == 0) - return -1; - match = abs(((w_ratio << 13) / h_ratio) - ((int)8192)); - - if ((w_ratio < (int)8192) || (h_ratio < (int)8192) || - (match > allowed_ratio_mismatch)) - return -1; - - return w_ratio + h_ratio; -} - -/* Return the nearest higher resolution index */ -static int nearest_resolution_index(struct v4l2_subdev *sd, int w, int h) -{ - int i; - int idx = -1; - int dist; - int fps_diff; - int min_fps_diff = INT_MAX; - int min_dist = INT_MAX; - const struct imx_resolution *tmp_res = NULL; - struct imx_device *dev = to_imx_sensor(sd); - bool again = 1; -retry: - for (i = 0; i < dev->entries_curr_table; i++) { - tmp_res = &dev->curr_res_table[i]; - dist = distance(tmp_res, w, h, again); - if (dist == -1) - continue; - if (dist < min_dist) { - min_dist = dist; - idx = i; - } - if (dist == min_dist) { - fps_diff = __imx_min_fps_diff(dev->targetfps, - tmp_res->fps_options); - if (fps_diff < min_fps_diff) { - min_fps_diff = fps_diff; - idx = i; - } - } - } - - /* - * FIXME! - * only IMX135 for Saltbay and IMX227 use this algorithm - */ - if (idx == -1 && again == true && dev->new_res_sel_method) { - again = false; - goto retry; - } - return idx; -} - -/* Call with ctrl_handler.lock hold */ -static int __adjust_hvblank(struct v4l2_subdev *sd) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - u16 new_frame_length_lines, new_line_length_pck; - int ret; - - /* - * No need to adjust h/v blank if not set dbg value - * Note that there is no other checking on the h/v blank value, - * as h/v blank can be set to any value above zero for debug purpose - */ - if (!dev->v_blank->val || !dev->h_blank->val) - return 0; - - new_frame_length_lines = dev->curr_res_table[dev->fmt_idx].height + - dev->v_blank->val; - new_line_length_pck = dev->curr_res_table[dev->fmt_idx].width + - dev->h_blank->val; - - ret = imx_write_reg(client, IMX_16BIT, - dev->reg_addr->line_length_pixels, new_line_length_pck); - if (ret) - return ret; - ret = imx_write_reg(client, IMX_16BIT, - dev->reg_addr->frame_length_lines, new_frame_length_lines); - if (ret) - return ret; - - dev->lines_per_frame = new_frame_length_lines; - dev->pixels_per_line = new_line_length_pck; - - return 0; -} - -static int imx_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - struct imx_device *dev = to_imx_sensor(sd); - struct camera_mipi_info *imx_info = NULL; - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct imx_resolution *res; - int lanes = imx_get_lanes(sd); - int ret; - u16 data, val; - int idx; - if (format->pad) - return -EINVAL; - if (!fmt) - return -EINVAL; - - imx_info = v4l2_get_subdev_hostdata(sd); - if (imx_info == NULL) - return -EINVAL; - if ((fmt->width > imx_max_res[dev->sensor_id].res_max_width) - || (fmt->height > imx_max_res[dev->sensor_id].res_max_height)) { - fmt->width = imx_max_res[dev->sensor_id].res_max_width; - fmt->height = imx_max_res[dev->sensor_id].res_max_height; - } else { - idx = nearest_resolution_index(sd, fmt->width, fmt->height); - - /* - * nearest_resolution_index() doesn't return smaller - * resolutions. If it fails, it means the requested - * resolution is higher than wecan support. Fallback - * to highest possible resolution in this case. - */ - if (idx == -1) - idx = dev->entries_curr_table - 1; - - fmt->width = dev->curr_res_table[idx].width; - fmt->height = dev->curr_res_table[idx].height; - } - - fmt->code = dev->format.code; - if(format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *fmt; - return 0; - } - mutex_lock(&dev->input_lock); - - dev->fmt_idx = nearest_resolution_index(sd, fmt->width, fmt->height); - if (dev->fmt_idx == -1) { - ret = -EINVAL; - goto out; - } - res = &dev->curr_res_table[dev->fmt_idx]; - - /* Adjust the FPS selection based on the resolution selected */ - dev->fps_index = __imx_nearest_fps_index(dev->targetfps, - res->fps_options); - dev->fps = res->fps_options[dev->fps_index].fps; - dev->regs = res->fps_options[dev->fps_index].regs; - if (!dev->regs) - dev->regs = res->regs; - - ret = imx_write_reg_array(client, dev->regs); - if (ret) - goto out; - - if (dev->sensor_id == IMX132_ID && lanes > 0) { - static const u8 imx132_rgpltd[] = { - 2, /* 1 lane: /1 */ - 0, /* 2 lanes: /2 */ - 0, /* undefined */ - 1, /* 4 lanes: /4 */ - }; - ret = imx_write_reg(client, IMX_8BIT, IMX132_208_VT_RGPLTD, - imx132_rgpltd[lanes - 1]); - if (ret) - goto out; - } - - dev->pixels_per_line = res->fps_options[dev->fps_index].pixels_per_line; - dev->lines_per_frame = res->fps_options[dev->fps_index].lines_per_frame; - - /* dbg h/v blank time */ - __adjust_hvblank(sd); - - ret = __imx_update_exposure_timing(client, dev->coarse_itg, - dev->pixels_per_line, dev->lines_per_frame); - if (ret) - goto out; - - ret = __imx_update_gain(sd, dev->gain); - if (ret) - goto out; - - ret = __imx_update_digital_gain(client, dev->digital_gain); - if (ret) - goto out; - - ret = imx_write_reg_array(client, dev->param_update); - if (ret) - goto out; - - ret = imx_get_intg_factor(client, imx_info, dev->regs); - if (ret) - goto out; - - ret = imx_read_reg(client, IMX_8BIT, - dev->reg_addr->img_orientation, &val); - if (ret) - goto out; - val &= (IMX_VFLIP_BIT|IMX_HFLIP_BIT); - imx_info->raw_bayer_order = imx_bayer_order_mapping[val]; - dev->format.code = imx_translate_bayer_order( - imx_info->raw_bayer_order); - - /* - * Fill meta data info. add imx135 metadata setting for RAW10 format - */ - switch (dev->sensor_id) { - case IMX135_ID: - ret = imx_read_reg(client, 2, - IMX135_OUTPUT_DATA_FORMAT_REG, &data); - if (ret) - goto out; - /* - * The IMX135 can support various resolutions like - * RAW6/8/10/12/14. - * 1.The data format is RAW10: - * matadata width = current resolution width(pixel) * 10 / 8 - * 2.The data format is RAW6 or RAW8: - * matadata width = current resolution width(pixel); - * 3.other data format(RAW12/14 etc): - * TBD. - */ - if (data == IMX135_OUTPUT_FORMAT_RAW10) - /* the data format is RAW10. */ - imx_info->metadata_width = res->width * 10 / 8; - else - /* The data format is RAW6/8/12/14/ etc. */ - imx_info->metadata_width = res->width; - - imx_info->metadata_height = IMX135_EMBEDDED_DATA_LINE_NUM; - - if (imx_info->metadata_effective_width == NULL) - imx_info->metadata_effective_width = - imx135_embedded_effective_size; - - break; - case IMX227_ID: - ret = imx_read_reg(client, 2, IMX227_OUTPUT_DATA_FORMAT_REG, - &data); - if (ret) - goto out; - if (data == IMX227_OUTPUT_FORMAT_RAW10) - /* the data format is RAW10. */ - imx_info->metadata_width = res->width * 10 / 8; - else - /* The data format is RAW6/8/12/14/ etc. */ - imx_info->metadata_width = res->width; - - imx_info->metadata_height = IMX227_EMBEDDED_DATA_LINE_NUM; - - if (imx_info->metadata_effective_width == NULL) - imx_info->metadata_effective_width = - imx227_embedded_effective_size; - - break; - default: - imx_info->metadata_width = 0; - imx_info->metadata_height = 0; - imx_info->metadata_effective_width = NULL; - break; - } - -out: - mutex_unlock(&dev->input_lock); - return ret; -} - - -static int imx_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct v4l2_mbus_framefmt *fmt = &format->format; - struct imx_device *dev = to_imx_sensor(sd); - - if (format->pad) - return -EINVAL; - if (!fmt) - return -EINVAL; - - mutex_lock(&dev->input_lock); - fmt->width = dev->curr_res_table[dev->fmt_idx].width; - fmt->height = dev->curr_res_table[dev->fmt_idx].height; - fmt->code = dev->format.code; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int imx_detect(struct i2c_client *client, u16 *id, u8 *revision) -{ - struct i2c_adapter *adapter = client->adapter; - - /* i2c check */ - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) - return -ENODEV; - - /* check sensor chip ID */ - if (imx_read_reg(client, IMX_16BIT, IMX132_175_208_219_CHIP_ID, id)) { - v4l2_err(client, "sensor_id = 0x%x\n", *id); - return -ENODEV; - } - - if (*id == IMX132_ID || *id == IMX175_ID || - *id == IMX208_ID || *id == IMX219_ID) - goto found; - - if (imx_read_reg(client, IMX_16BIT, IMX134_135_227_CHIP_ID, id)) { - v4l2_err(client, "sensor_id = 0x%x\n", *id); - return -ENODEV; - } - if (*id != IMX134_ID && *id != IMX135_ID && *id != IMX227_ID) { - v4l2_err(client, "no imx sensor found\n"); - return -ENODEV; - } -found: - v4l2_info(client, "sensor_id = 0x%x\n", *id); - - /* TODO - need to be updated */ - *revision = 0; - - return 0; -} - -static void __imx_print_timing(struct v4l2_subdev *sd) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - u16 width = dev->curr_res_table[dev->fmt_idx].width; - u16 height = dev->curr_res_table[dev->fmt_idx].height; - - dev_dbg(&client->dev, "Dump imx timing in stream on:\n"); - dev_dbg(&client->dev, "width: %d:\n", width); - dev_dbg(&client->dev, "height: %d:\n", height); - dev_dbg(&client->dev, "pixels_per_line: %d:\n", dev->pixels_per_line); - dev_dbg(&client->dev, "line per frame: %d:\n", dev->lines_per_frame); - dev_dbg(&client->dev, "pix freq: %d:\n", dev->vt_pix_clk_freq_mhz); - dev_dbg(&client->dev, "init fps: %d:\n", dev->vt_pix_clk_freq_mhz / - dev->pixels_per_line / dev->lines_per_frame); - dev_dbg(&client->dev, "HBlank: %d nS:\n", - 1000 * (dev->pixels_per_line - width) / - (dev->vt_pix_clk_freq_mhz / 1000000)); - dev_dbg(&client->dev, "VBlank: %d uS:\n", - (dev->lines_per_frame - height) * dev->pixels_per_line / - (dev->vt_pix_clk_freq_mhz / 1000000)); -} - -/* - * imx stream on/off - */ -static int imx_s_stream(struct v4l2_subdev *sd, int enable) -{ - int ret; - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - if (enable) { - /* Noise reduction & dead pixel applied before streaming */ - if (dev->fw == NULL) { - dev_warn(&client->dev, "No MSR loaded from library"); - } else { - ret = apply_msr_data(client, dev->fw); - if (ret) { - mutex_unlock(&dev->input_lock); - return ret; - } - } - ret = imx_test_pattern(sd); - if (ret) { - v4l2_err(client, "Configure test pattern failed.\n"); - mutex_unlock(&dev->input_lock); - return ret; - } - __imx_print_timing(sd); - ret = imx_write_reg_array(client, imx_streaming); - if (ret != 0) { - v4l2_err(client, "write_reg_array err\n"); - mutex_unlock(&dev->input_lock); - return ret; - } - dev->streaming = 1; - if (dev->vcm_driver && dev->vcm_driver->t_focus_abs_init) - dev->vcm_driver->t_focus_abs_init(sd); - } else { - ret = imx_write_reg_array(client, imx_soft_standby); - if (ret != 0) { - v4l2_err(client, "write_reg_array err\n"); - mutex_unlock(&dev->input_lock); - return ret; - } - dev->streaming = 0; - dev->targetfps = 0; - } - mutex_unlock(&dev->input_lock); - - return 0; -} - -static int __update_imx_device_settings(struct imx_device *dev, u16 sensor_id) -{ - /* IMX on other platform is not supported yet */ - return -EINVAL; -} - -static int imx_s_config(struct v4l2_subdev *sd, - int irq, void *pdata) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 sensor_revision; - u16 sensor_id; - int ret; - if (pdata == NULL) - return -ENODEV; - - dev->platform_data = pdata; - - mutex_lock(&dev->input_lock); - - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - mutex_unlock(&dev->input_lock); - dev_err(&client->dev, "imx platform init err\n"); - return ret; - } - } - /* - * power off the module first. - * - * As first power on by board have undecided state of power/gpio pins. - */ - ret = __imx_s_power(sd, 0); - if (ret) { - v4l2_err(client, "imx power-down err.\n"); - mutex_unlock(&dev->input_lock); - return ret; - } - - ret = __imx_s_power(sd, 1); - if (ret) { - v4l2_err(client, "imx power-up err.\n"); - mutex_unlock(&dev->input_lock); - return ret; - } - - ret = dev->platform_data->csi_cfg(sd, 1); - if (ret) - goto fail_csi_cfg; - - /* config & detect sensor */ - ret = imx_detect(client, &sensor_id, &sensor_revision); - if (ret) { - v4l2_err(client, "imx_detect err s_config.\n"); - goto fail_detect; - } - - dev->sensor_id = sensor_id; - dev->sensor_revision = sensor_revision; - - /* Resolution settings depend on sensor type and platform */ - ret = __update_imx_device_settings(dev, dev->sensor_id); - if (ret) - goto fail_detect; - /* Read sensor's OTP data */ - dev->otp_data = dev->otp_driver->otp_read(sd, - dev->otp_driver->dev_addr, dev->otp_driver->start_addr, - dev->otp_driver->size); - - /* power off sensor */ - ret = __imx_s_power(sd, 0); - - mutex_unlock(&dev->input_lock); - if (ret) - v4l2_err(client, "imx power-down err.\n"); - - return ret; - -fail_detect: - dev->platform_data->csi_cfg(sd, 0); -fail_csi_cfg: - __imx_s_power(sd, 0); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - mutex_unlock(&dev->input_lock); - dev_err(&client->dev, "sensor power-gating failed\n"); - return ret; -} - -static int -imx_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) -{ - struct imx_device *dev = to_imx_sensor(sd); - if (code->index >= MAX_FMTS) - return -EINVAL; - - mutex_lock(&dev->input_lock); - code->code = dev->format.code; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int -imx_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_frame_size_enum *fse) -{ - int index = fse->index; - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - if (index >= dev->entries_curr_table) { - mutex_unlock(&dev->input_lock); - return -EINVAL; - } - - fse->min_width = dev->curr_res_table[index].width; - fse->min_height = dev->curr_res_table[index].height; - fse->max_width = dev->curr_res_table[index].width; - fse->max_height = dev->curr_res_table[index].height; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int -imx_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *param) -{ - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - dev->run_mode = param->parm.capture.capturemode; - - switch (dev->run_mode) { - case CI_MODE_VIDEO: - dev->curr_res_table = dev->mode_tables->res_video; - dev->entries_curr_table = dev->mode_tables->n_res_video; - break; - case CI_MODE_STILL_CAPTURE: - dev->curr_res_table = dev->mode_tables->res_still; - dev->entries_curr_table = dev->mode_tables->n_res_still; - break; - default: - dev->curr_res_table = dev->mode_tables->res_preview; - dev->entries_curr_table = dev->mode_tables->n_res_preview; - } - mutex_unlock(&dev->input_lock); - return 0; -} - -static int imx_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval) -{ - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - interval->interval.denominator = dev->fps; - interval->interval.numerator = 1; - mutex_unlock(&dev->input_lock); - return 0; -} - -static int __imx_s_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval) -{ - struct imx_device *dev = to_imx_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - const struct imx_resolution *res = - &dev->curr_res_table[dev->fmt_idx]; - struct camera_mipi_info *imx_info = NULL; - unsigned short pixels_per_line; - unsigned short lines_per_frame; - unsigned int fps_index; - int fps; - int ret = 0; - - - imx_info = v4l2_get_subdev_hostdata(sd); - if (imx_info == NULL) - return -EINVAL; - - if (!interval->interval.numerator) - interval->interval.numerator = 1; - - fps = interval->interval.denominator / interval->interval.numerator; - - if (!fps) - return -EINVAL; - - dev->targetfps = fps; - /* No need to proceed further if we are not streaming */ - if (!dev->streaming) - return 0; - - /* Ignore if we are already using the required FPS. */ - if (fps == dev->fps) - return 0; - - /* - * Start here, sensor is already streaming, so adjust fps dynamically - */ - fps_index = __imx_above_nearest_fps_index(fps, res->fps_options); - if (fps > res->fps_options[fps_index].fps) { - /* - * if does not have high fps setting, not support increase fps - * by adjust lines per frame. - */ - dev_err(&client->dev, "Could not support fps: %d.\n", fps); - return -EINVAL; - } - - if (res->fps_options[fps_index].regs && - res->fps_options[fps_index].regs != dev->regs) { - /* - * if need a new setting, but the new setting has difference - * with current setting, not use this one, as may have - * unexpected result, e.g. PLL, IQ. - */ - dev_dbg(&client->dev, - "Sensor is streaming, not apply new sensor setting\n"); - if (fps > res->fps_options[dev->fps_index].fps) { - /* - * Does not support increase fps based on low fps - * setting, as the high fps setting could not be used, - * and fps requested is above current setting fps. - */ - dev_warn(&client->dev, - "Could not support fps: %d, keep current: %d.\n", - fps, dev->fps); - return 0; - } - } else { - dev->fps_index = fps_index; - dev->fps = res->fps_options[dev->fps_index].fps; - } - - /* Update the new frametimings based on FPS */ - pixels_per_line = res->fps_options[dev->fps_index].pixels_per_line; - lines_per_frame = res->fps_options[dev->fps_index].lines_per_frame; - - if (fps > res->fps_options[fps_index].fps) { - /* - * if does not have high fps setting, not support increase fps - * by adjust lines per frame. - */ - dev_warn(&client->dev, "Could not support fps: %d. Use:%d.\n", - fps, res->fps_options[fps_index].fps); - goto done; - } - - /* if the new setting does not match exactly */ - if (dev->fps != fps) { -#define MAX_LINES_PER_FRAME 0xffff - dev_dbg(&client->dev, "adjusting fps using lines_per_frame\n"); - /* - * FIXME! - * 1: check DS on max value of lines_per_frame - * 2: consider use pixel per line for more range? - */ - if (dev->lines_per_frame * dev->fps / fps > - MAX_LINES_PER_FRAME) { - dev_warn(&client->dev, - "adjust lines_per_frame out of range, try to use max value.\n"); - lines_per_frame = MAX_LINES_PER_FRAME; - } else { - lines_per_frame = lines_per_frame * dev->fps / fps; - } - } -done: - /* Update the new frametimings based on FPS */ - dev->pixels_per_line = pixels_per_line; - dev->lines_per_frame = lines_per_frame; - - /* Update the new values so that user side knows the current settings */ - ret = __imx_update_exposure_timing(client, - dev->coarse_itg, dev->pixels_per_line, dev->lines_per_frame); - if (ret) - return ret; - - dev->fps = fps; - - ret = imx_get_intg_factor(client, imx_info, dev->regs); - if (ret) - return ret; - - interval->interval.denominator = res->fps_options[dev->fps_index].fps; - interval->interval.numerator = 1; - __imx_print_timing(sd); - - return ret; -} - -static int imx_s_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval) -{ - struct imx_device *dev = to_imx_sensor(sd); - int ret; - - mutex_lock(&dev->input_lock); - ret = __imx_s_frame_interval(sd, interval); - mutex_unlock(&dev->input_lock); - - return ret; -} -static int imx_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) -{ - struct imx_device *dev = to_imx_sensor(sd); - - mutex_lock(&dev->input_lock); - *frames = dev->curr_res_table[dev->fmt_idx].skip_frames; - mutex_unlock(&dev->input_lock); - - return 0; -} - -static const struct v4l2_subdev_sensor_ops imx_sensor_ops = { - .g_skip_frames = imx_g_skip_frames, -}; - -static const struct v4l2_subdev_video_ops imx_video_ops = { - .s_stream = imx_s_stream, - .s_parm = imx_s_parm, - .g_frame_interval = imx_g_frame_interval, - .s_frame_interval = imx_s_frame_interval, -}; - -static const struct v4l2_subdev_core_ops imx_core_ops = { - .s_power = imx_s_power, - .ioctl = imx_ioctl, - .init = imx_init, -}; - -static const struct v4l2_subdev_pad_ops imx_pad_ops = { - .enum_mbus_code = imx_enum_mbus_code, - .enum_frame_size = imx_enum_frame_size, - .get_fmt = imx_get_fmt, - .set_fmt = imx_set_fmt, -}; - -static const struct v4l2_subdev_ops imx_ops = { - .core = &imx_core_ops, - .video = &imx_video_ops, - .pad = &imx_pad_ops, - .sensor = &imx_sensor_ops, -}; - -static const struct media_entity_operations imx_entity_ops = { - .link_setup = NULL, -}; - -static int imx_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx_device *dev = to_imx_sensor(sd); - - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); - - media_entity_cleanup(&dev->sd.entity); - v4l2_ctrl_handler_free(&dev->ctrl_handler); - dev->platform_data->csi_cfg(sd, 0); - v4l2_device_unregister_subdev(sd); - release_msr_list(client, dev->fw); - kfree(dev); - - return 0; -} - -static int __imx_init_ctrl_handler(struct imx_device *dev) -{ - struct v4l2_ctrl_handler *hdl; - int i; - - hdl = &dev->ctrl_handler; - - v4l2_ctrl_handler_init(&dev->ctrl_handler, ARRAY_SIZE(imx_controls)); - - for (i = 0; i < ARRAY_SIZE(imx_controls); i++) - v4l2_ctrl_new_custom(&dev->ctrl_handler, - &imx_controls[i], NULL); - - dev->pixel_rate = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_PIXEL_RATE); - dev->h_blank = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_HBLANK); - dev->v_blank = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_VBLANK); - dev->link_freq = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_LINK_FREQ); - dev->h_flip = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_HFLIP); - dev->v_flip = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_VFLIP); - dev->tp_mode = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_TEST_PATTERN); - dev->tp_r = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_TEST_PATTERN_COLOR_R); - dev->tp_gr = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_TEST_PATTERN_COLOR_GR); - dev->tp_gb = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_TEST_PATTERN_COLOR_GB); - dev->tp_b = v4l2_ctrl_find(&dev->ctrl_handler, - V4L2_CID_TEST_PATTERN_COLOR_B); - - if (dev->ctrl_handler.error || dev->pixel_rate == NULL - || dev->h_blank == NULL || dev->v_blank == NULL - || dev->h_flip == NULL || dev->v_flip == NULL - || dev->link_freq == NULL) { - return dev->ctrl_handler.error; - } - - dev->ctrl_handler.lock = &dev->input_lock; - dev->sd.ctrl_handler = hdl; - v4l2_ctrl_handler_setup(&dev->ctrl_handler); - - return 0; -} - -static void imx_update_reg_info(struct imx_device *dev) -{ - if (dev->sensor_id == IMX219_ID) { - dev->reg_addr = &imx219_addr; - dev->param_hold = imx219_param_hold; - dev->param_update = imx219_param_update; - } else { - dev->reg_addr = &imx_addr; - dev->param_hold = imx_param_hold; - dev->param_update = imx_param_update; - } -} - -static int imx_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct imx_device *dev; - struct camera_mipi_info *imx_info = NULL; - int ret; - char *msr_file_name = NULL; - - /* allocate sensor device & init sub device */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - v4l2_err(client, "%s: out of memory\n", __func__); - return -ENOMEM; - } - - mutex_init(&dev->input_lock); - - dev->i2c_id = id->driver_data; - dev->fmt_idx = 0; - dev->sensor_id = IMX_ID_DEFAULT; - dev->vcm_driver = &imx_vcms[IMX_ID_DEFAULT]; - dev->digital_gain = 256; - - v4l2_i2c_subdev_init(&(dev->sd), client, &imx_ops); - - if (client->dev.platform_data) { - ret = imx_s_config(&dev->sd, client->irq, - client->dev.platform_data); - if (ret) - goto out_free; - } - imx_info = v4l2_get_subdev_hostdata(&dev->sd); - - /* - * sd->name is updated with sensor driver name by the v4l2. - * change it to sensor name in this case. - */ - imx_update_reg_info(dev); - snprintf(dev->sd.name, sizeof(dev->sd.name), "%s%x %d-%04x", - IMX_SUBDEV_PREFIX, dev->sensor_id, - i2c_adapter_id(client->adapter), client->addr); - - ret = __imx_init_ctrl_handler(dev); - if (ret) - goto out_ctrl_handler_free; - - dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->format.code = imx_translate_bayer_order( - imx_info->raw_bayer_order); - dev->sd.entity.ops = &imx_entity_ops; - dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - - ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); - if (ret) { - imx_remove(client); - return ret; - } - - /* Load the Noise reduction, Dead pixel registers from cpf file*/ - if (dev->platform_data->msr_file_name != NULL) - msr_file_name = dev->platform_data->msr_file_name(); - if (msr_file_name) { - ret = load_msr_list(client, msr_file_name, &dev->fw); - if (ret) { - imx_remove(client); - return ret; - } - } else { - dev_warn(&client->dev, "Drvb file not present"); - } - - return ret; - -out_ctrl_handler_free: - v4l2_ctrl_handler_free(&dev->ctrl_handler); - -out_free: - v4l2_device_unregister_subdev(&dev->sd); - kfree(dev); - return ret; -} - -static const struct i2c_device_id imx_ids[] = { - {IMX_NAME_175, IMX175_ID}, - {IMX_NAME_135, IMX135_ID}, - {IMX_NAME_135_FUJI, IMX135_FUJI_ID}, - {IMX_NAME_134, IMX134_ID}, - {IMX_NAME_132, IMX132_ID}, - {IMX_NAME_208, IMX208_ID}, - {IMX_NAME_219, IMX219_ID}, - {IMX_NAME_227, IMX227_ID}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, imx_ids); - -static struct i2c_driver imx_driver = { - .driver = { - .name = IMX_DRIVER, - }, - .probe = imx_probe, - .remove = imx_remove, - .id_table = imx_ids, -}; - -static __init int init_imx(void) -{ - return i2c_add_driver(&imx_driver); -} - -static __exit void exit_imx(void) -{ - i2c_del_driver(&imx_driver); -} - -module_init(init_imx); -module_exit(exit_imx); - -MODULE_DESCRIPTION("A low-level driver for Sony IMX sensors"); -MODULE_AUTHOR("Shenbo Huang <shenbo.huang@intel.com>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/staging/media/atomisp/i2c/imx/imx.h b/drivers/staging/media/atomisp/i2c/imx/imx.h deleted file mode 100644 index 30beb2a0ed93..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx.h +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Support for Sony IMX camera sensor. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __IMX_H__ -#define __IMX_H__ -#include "../../include/linux/atomisp_platform.h" -#include "../../include/linux/atomisp.h" -#include <linux/delay.h> -#include <linux/i2c.h> -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/types.h> -#include <linux/videodev2.h> -#include <linux/v4l2-mediabus.h> -#include <media/media-entity.h> -#include <media/v4l2-ctrls.h> -#include <media/v4l2-device.h> -#include <media/v4l2-subdev.h> -#include "imx175.h" -#include "imx135.h" -#include "imx134.h" -#include "imx132.h" -#include "imx208.h" -#include "imx219.h" -#include "imx227.h" - -#define IMX_MCLK 192 - -/* TODO - This should be added into include/linux/videodev2.h */ -#ifndef V4L2_IDENT_IMX -#define V4L2_IDENT_IMX 8245 -#endif - -#define IMX_MAX_AE_LUT_LENGTH 5 -/* - * imx System control registers - */ -#define IMX_MASK_5BIT 0x1F -#define IMX_MASK_4BIT 0xF -#define IMX_MASK_3BIT 0x7 -#define IMX_MASK_2BIT 0x3 -#define IMX_MASK_8BIT 0xFF -#define IMX_MASK_11BIT 0x7FF -#define IMX_INTG_BUF_COUNT 2 - -#define IMX_FINE_INTG_TIME 0x1E8 - -#define IMX_VT_PIX_CLK_DIV 0x0301 -#define IMX_VT_SYS_CLK_DIV 0x0303 -#define IMX_PRE_PLL_CLK_DIV 0x0305 -#define IMX227_IOP_PRE_PLL_CLK_DIV 0x030D -#define IMX227_PLL_MULTIPLIER 0x0306 -#define IMX227_IOP_PLL_MULTIPLIER 0x030E -#define IMX227_PLL_MULTI_DRIVE 0x0310 -#define IMX227_OP_PIX_CLK_DIV 0x0309 -#define IMX227_OP_SYS_CLK_DIV 0x030B -#define IMX_PLL_MULTIPLIER 0x030C -#define IMX_OP_PIX_DIV 0x0309 -#define IMX_OP_SYS_DIV 0x030B -#define IMX_FRAME_LENGTH_LINES 0x0340 -#define IMX_LINE_LENGTH_PIXELS 0x0342 -#define IMX_COARSE_INTG_TIME_MIN 0x1004 -#define IMX_COARSE_INTG_TIME_MAX 0x1006 -#define IMX_BINNING_ENABLE 0x0390 -#define IMX227_BINNING_ENABLE 0x0900 -#define IMX_BINNING_TYPE 0x0391 -#define IMX227_BINNING_TYPE 0x0901 -#define IMX_READ_MODE 0x0390 -#define IMX227_READ_MODE 0x0900 - -#define IMX_HORIZONTAL_START_H 0x0344 -#define IMX_VERTICAL_START_H 0x0346 -#define IMX_HORIZONTAL_END_H 0x0348 -#define IMX_VERTICAL_END_H 0x034a -#define IMX_HORIZONTAL_OUTPUT_SIZE_H 0x034c -#define IMX_VERTICAL_OUTPUT_SIZE_H 0x034e - -/* Post Divider setting register for imx132 and imx208 */ -#define IMX132_208_VT_RGPLTD 0x30A4 - -/* Multiplier setting register for imx132, imx208, and imx219 */ -#define IMX132_208_219_PLL_MULTIPLIER 0x0306 - -#define IMX_COARSE_INTEGRATION_TIME 0x0202 -#define IMX_TEST_PATTERN_MODE 0x0600 -#define IMX_TEST_PATTERN_COLOR_R 0x0602 -#define IMX_TEST_PATTERN_COLOR_GR 0x0604 -#define IMX_TEST_PATTERN_COLOR_B 0x0606 -#define IMX_TEST_PATTERN_COLOR_GB 0x0608 -#define IMX_IMG_ORIENTATION 0x0101 -#define IMX_VFLIP_BIT 2 -#define IMX_HFLIP_BIT 1 -#define IMX_GLOBAL_GAIN 0x0205 -#define IMX_SHORT_AGC_GAIN 0x0233 -#define IMX_DGC_ADJ 0x020E -#define IMX_DGC_LEN 10 -#define IMX227_DGC_LEN 4 -#define IMX_MAX_EXPOSURE_SUPPORTED 0xfffb -#define IMX_MAX_GLOBAL_GAIN_SUPPORTED 0x00ff -#define IMX_MAX_DIGITAL_GAIN_SUPPORTED 0x0fff - -#define MAX_FMTS 1 -#define IMX_OTP_DATA_SIZE 1280 - -#define IMX_SUBDEV_PREFIX "imx" -#define IMX_DRIVER "imx1x5" - -/* Sensor ids from identification register */ -#define IMX_NAME_134 "imx134" -#define IMX_NAME_135 "imx135" -#define IMX_NAME_175 "imx175" -#define IMX_NAME_132 "imx132" -#define IMX_NAME_208 "imx208" -#define IMX_NAME_219 "imx219" -#define IMX_NAME_227 "imx227" -#define IMX175_ID 0x0175 -#define IMX135_ID 0x0135 -#define IMX134_ID 0x0134 -#define IMX132_ID 0x0132 -#define IMX208_ID 0x0208 -#define IMX219_ID 0x0219 -#define IMX227_ID 0x0227 - -/* Sensor id based on i2c_device_id table - * (Fuji module can not be detected based on sensor registers) */ -#define IMX135_FUJI_ID 0x0136 -#define IMX_NAME_135_FUJI "imx135fuji" - -/* imx175 - use dw9714 vcm */ -#define IMX175_MERRFLD 0x175 -#define IMX175_VALLEYVIEW 0x176 -#define IMX135_SALTBAY 0x135 -#define IMX135_VICTORIABAY 0x136 -#define IMX132_SALTBAY 0x132 -#define IMX134_VALLEYVIEW 0x134 -#define IMX208_MOFD_PD2 0x208 -#define IMX219_MFV0_PRH 0x219 -#define IMX227_SAND 0x227 - -/* otp - specific settings */ -#define E2PROM_ADDR 0xa0 -#define E2PROM_LITEON_12P1BA869D_ADDR 0xa0 -#define E2PROM_ABICO_SS89A839_ADDR 0xa8 -#define DEFAULT_OTP_SIZE 1280 -#define IMX135_OTP_SIZE 1280 -#define IMX219_OTP_SIZE 2048 -#define IMX227_OTP_SIZE 2560 -#define E2PROM_LITEON_12P1BA869D_SIZE 544 - -#define IMX_ID_DEFAULT 0x0000 -#define IMX132_175_208_219_CHIP_ID 0x0000 -#define IMX134_135_CHIP_ID 0x0016 -#define IMX134_135_227_CHIP_ID 0x0016 - -#define IMX175_RES_WIDTH_MAX 3280 -#define IMX175_RES_HEIGHT_MAX 2464 -#define IMX135_RES_WIDTH_MAX 4208 -#define IMX135_RES_HEIGHT_MAX 3120 -#define IMX132_RES_WIDTH_MAX 1936 -#define IMX132_RES_HEIGHT_MAX 1096 -#define IMX134_RES_WIDTH_MAX 3280 -#define IMX134_RES_HEIGHT_MAX 2464 -#define IMX208_RES_WIDTH_MAX 1936 -#define IMX208_RES_HEIGHT_MAX 1096 -#define IMX219_RES_WIDTH_MAX 3280 -#define IMX219_RES_HEIGHT_MAX 2464 -#define IMX227_RES_WIDTH_MAX 2400 -#define IMX227_RES_HEIGHT_MAX 2720 - -/* Defines for lens/VCM */ -#define IMX_FOCAL_LENGTH_NUM 369 /*3.69mm*/ -#define IMX_FOCAL_LENGTH_DEM 100 -#define IMX_F_NUMBER_DEFAULT_NUM 22 -#define IMX_F_NUMBER_DEM 10 -#define IMX_INVALID_CONFIG 0xffffffff -#define IMX_MAX_FOCUS_POS 1023 -#define IMX_MAX_FOCUS_NEG (-1023) -#define IMX_VCM_SLEW_STEP_MAX 0x3f -#define IMX_VCM_SLEW_TIME_MAX 0x1f - -#define IMX_BIN_FACTOR_MAX 4 -#define IMX_INTEGRATION_TIME_MARGIN 4 -/* - * focal length bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define IMX_FOCAL_LENGTH_DEFAULT 0x1710064 - -/* - * current f-number bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define IMX_F_NUMBER_DEFAULT 0x16000a - -/* - * f-number range bits definition: - * bits 31-24: max f-number numerator - * bits 23-16: max f-number denominator - * bits 15-8: min f-number numerator - * bits 7-0: min f-number denominator - */ -#define IMX_F_NUMBER_RANGE 0x160a160a - -struct imx_vcm { - int (*power_up)(struct v4l2_subdev *sd); - int (*power_down)(struct v4l2_subdev *sd); - int (*t_focus_abs)(struct v4l2_subdev *sd, s32 value); - int (*t_focus_abs_init)(struct v4l2_subdev *sd); - int (*t_focus_rel)(struct v4l2_subdev *sd, s32 value); - int (*q_focus_status)(struct v4l2_subdev *sd, s32 *value); - int (*q_focus_abs)(struct v4l2_subdev *sd, s32 *value); - int (*t_vcm_slew)(struct v4l2_subdev *sd, s32 value); - int (*t_vcm_timing)(struct v4l2_subdev *sd, s32 value); -}; - -struct imx_otp { - void * (*otp_read)(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); - u32 start_addr; - u32 size; - u8 dev_addr; -}; - -struct max_res { - int res_max_width; - int res_max_height; -}; - -struct max_res imx_max_res[] = { - [IMX175_ID] = { - .res_max_width = IMX175_RES_WIDTH_MAX, - .res_max_height = IMX175_RES_HEIGHT_MAX, - }, - [IMX135_ID] = { - .res_max_width = IMX135_RES_WIDTH_MAX, - .res_max_height = IMX135_RES_HEIGHT_MAX, - }, - [IMX132_ID] = { - .res_max_width = IMX132_RES_WIDTH_MAX, - .res_max_height = IMX132_RES_HEIGHT_MAX, - }, - [IMX134_ID] = { - .res_max_width = IMX134_RES_WIDTH_MAX, - .res_max_height = IMX134_RES_HEIGHT_MAX, - }, - [IMX208_ID] = { - .res_max_width = IMX208_RES_WIDTH_MAX, - .res_max_height = IMX208_RES_HEIGHT_MAX, - }, - [IMX219_ID] = { - .res_max_width = IMX219_RES_WIDTH_MAX, - .res_max_height = IMX219_RES_HEIGHT_MAX, - }, - [IMX227_ID] = { - .res_max_width = IMX227_RES_WIDTH_MAX, - .res_max_height = IMX227_RES_HEIGHT_MAX, - }, -}; - -struct imx_settings { - struct imx_reg const *init_settings; - struct imx_resolution *res_preview; - struct imx_resolution *res_still; - struct imx_resolution *res_video; - int n_res_preview; - int n_res_still; - int n_res_video; -}; - -struct imx_settings imx_sets[] = { - [IMX175_MERRFLD] = { - .init_settings = imx175_init_settings, - .res_preview = imx175_res_preview, - .res_still = imx175_res_still, - .res_video = imx175_res_video, - .n_res_preview = ARRAY_SIZE(imx175_res_preview), - .n_res_still = ARRAY_SIZE(imx175_res_still), - .n_res_video = ARRAY_SIZE(imx175_res_video), - }, - [IMX175_VALLEYVIEW] = { - .init_settings = imx175_init_settings, - .res_preview = imx175_res_preview, - .res_still = imx175_res_still, - .res_video = imx175_res_video, - .n_res_preview = ARRAY_SIZE(imx175_res_preview), - .n_res_still = ARRAY_SIZE(imx175_res_still), - .n_res_video = ARRAY_SIZE(imx175_res_video), - }, - [IMX135_SALTBAY] = { - .init_settings = imx135_init_settings, - .res_preview = imx135_res_preview, - .res_still = imx135_res_still, - .res_video = imx135_res_video, - .n_res_preview = ARRAY_SIZE(imx135_res_preview), - .n_res_still = ARRAY_SIZE(imx135_res_still), - .n_res_video = ARRAY_SIZE(imx135_res_video), - }, - [IMX135_VICTORIABAY] = { - .init_settings = imx135_init_settings, - .res_preview = imx135_res_preview_mofd, - .res_still = imx135_res_still_mofd, - .res_video = imx135_res_video, - .n_res_preview = ARRAY_SIZE(imx135_res_preview_mofd), - .n_res_still = ARRAY_SIZE(imx135_res_still_mofd), - .n_res_video = ARRAY_SIZE(imx135_res_video), - }, - [IMX132_SALTBAY] = { - .init_settings = imx132_init_settings, - .res_preview = imx132_res_preview, - .res_still = imx132_res_still, - .res_video = imx132_res_video, - .n_res_preview = ARRAY_SIZE(imx132_res_preview), - .n_res_still = ARRAY_SIZE(imx132_res_still), - .n_res_video = ARRAY_SIZE(imx132_res_video), - }, - [IMX134_VALLEYVIEW] = { - .init_settings = imx134_init_settings, - .res_preview = imx134_res_preview, - .res_still = imx134_res_still, - .res_video = imx134_res_video, - .n_res_preview = ARRAY_SIZE(imx134_res_preview), - .n_res_still = ARRAY_SIZE(imx134_res_still), - .n_res_video = ARRAY_SIZE(imx134_res_video), - }, - [IMX208_MOFD_PD2] = { - .init_settings = imx208_init_settings, - .res_preview = imx208_res_preview, - .res_still = imx208_res_still, - .res_video = imx208_res_video, - .n_res_preview = ARRAY_SIZE(imx208_res_preview), - .n_res_still = ARRAY_SIZE(imx208_res_still), - .n_res_video = ARRAY_SIZE(imx208_res_video), - }, - [IMX219_MFV0_PRH] = { - .init_settings = imx219_init_settings, - .res_preview = imx219_res_preview, - .res_still = imx219_res_still, - .res_video = imx219_res_video, - .n_res_preview = ARRAY_SIZE(imx219_res_preview), - .n_res_still = ARRAY_SIZE(imx219_res_still), - .n_res_video = ARRAY_SIZE(imx219_res_video), - }, - [IMX227_SAND] = { - .init_settings = imx227_init_settings, - .res_preview = imx227_res_preview, - .res_still = imx227_res_still, - .res_video = imx227_res_video, - .n_res_preview = ARRAY_SIZE(imx227_res_preview), - .n_res_still = ARRAY_SIZE(imx227_res_still), - .n_res_video = ARRAY_SIZE(imx227_res_video), - }, -}; - -struct imx_reg_addr { - u16 frame_length_lines; - u16 line_length_pixels; - u16 horizontal_start_h; - u16 vertical_start_h; - u16 horizontal_end_h; - u16 vertical_end_h; - u16 horizontal_output_size_h; - u16 vertical_output_size_h; - u16 coarse_integration_time; - u16 img_orientation; - u16 global_gain; - u16 dgc_adj; -}; - -struct imx_reg_addr imx_addr = { - IMX_FRAME_LENGTH_LINES, - IMX_LINE_LENGTH_PIXELS, - IMX_HORIZONTAL_START_H, - IMX_VERTICAL_START_H, - IMX_HORIZONTAL_END_H, - IMX_VERTICAL_END_H, - IMX_HORIZONTAL_OUTPUT_SIZE_H, - IMX_VERTICAL_OUTPUT_SIZE_H, - IMX_COARSE_INTEGRATION_TIME, - IMX_IMG_ORIENTATION, - IMX_GLOBAL_GAIN, - IMX_DGC_ADJ, -}; - -struct imx_reg_addr imx219_addr = { - IMX219_FRAME_LENGTH_LINES, - IMX219_LINE_LENGTH_PIXELS, - IMX219_HORIZONTAL_START_H, - IMX219_VERTICAL_START_H, - IMX219_HORIZONTAL_END_H, - IMX219_VERTICAL_END_H, - IMX219_HORIZONTAL_OUTPUT_SIZE_H, - IMX219_VERTICAL_OUTPUT_SIZE_H, - IMX219_COARSE_INTEGRATION_TIME, - IMX219_IMG_ORIENTATION, - IMX219_GLOBAL_GAIN, - IMX219_DGC_ADJ, -}; - -#define v4l2_format_capture_type_entry(_width, _height, \ - _pixelformat, _bytesperline, _colorspace) \ - {\ - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,\ - .fmt.pix.width = (_width),\ - .fmt.pix.height = (_height),\ - .fmt.pix.pixelformat = (_pixelformat),\ - .fmt.pix.bytesperline = (_bytesperline),\ - .fmt.pix.colorspace = (_colorspace),\ - .fmt.pix.sizeimage = (_height)*(_bytesperline),\ - } - -#define s_output_format_entry(_width, _height, _pixelformat, \ - _bytesperline, _colorspace, _fps) \ - {\ - .v4l2_fmt = v4l2_format_capture_type_entry(_width, \ - _height, _pixelformat, _bytesperline, \ - _colorspace),\ - .fps = (_fps),\ - } - -#define s_output_format_reg_entry(_width, _height, _pixelformat, \ - _bytesperline, _colorspace, _fps, _reg_setting) \ - {\ - .s_fmt = s_output_format_entry(_width, _height,\ - _pixelformat, _bytesperline, \ - _colorspace, _fps),\ - .reg_setting = (_reg_setting),\ - } - -/* imx device structure */ -struct imx_device { - struct v4l2_subdev sd; - struct media_pad pad; - struct v4l2_mbus_framefmt format; - struct camera_sensor_platform_data *platform_data; - struct mutex input_lock; /* serialize sensor's ioctl */ - int fmt_idx; - int status; - int streaming; - int power; - int run_mode; - int vt_pix_clk_freq_mhz; - int fps_index; - u32 focus; - u16 sensor_id; /* Sensor id from registers */ - u16 i2c_id; /* Sensor id from i2c_device_id */ - u16 coarse_itg; - u16 fine_itg; - u16 digital_gain; - u16 gain; - u16 pixels_per_line; - u16 lines_per_frame; - u8 targetfps; - u8 fps; - const struct imx_reg *regs; - u8 res; - u8 type; - u8 sensor_revision; - u8 *otp_data; - struct imx_settings *mode_tables; - struct imx_vcm *vcm_driver; - struct imx_otp *otp_driver; - const struct imx_resolution *curr_res_table; - unsigned long entries_curr_table; - const struct firmware *fw; - struct imx_reg_addr *reg_addr; - const struct imx_reg *param_hold; - const struct imx_reg *param_update; - - /* used for h/b blank tuning */ - struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_ctrl *pixel_rate; - struct v4l2_ctrl *h_blank; - struct v4l2_ctrl *v_blank; - struct v4l2_ctrl *link_freq; - struct v4l2_ctrl *h_flip; - struct v4l2_ctrl *v_flip; - - /* Test pattern control */ - struct v4l2_ctrl *tp_mode; - struct v4l2_ctrl *tp_r; - struct v4l2_ctrl *tp_gr; - struct v4l2_ctrl *tp_gb; - struct v4l2_ctrl *tp_b; - - /* FIXME! */ - bool new_res_sel_method; -}; - -#define to_imx_sensor(x) container_of(x, struct imx_device, sd) - -#define IMX_MAX_WRITE_BUF_SIZE 32 -struct imx_write_buffer { - u16 addr; - u8 data[IMX_MAX_WRITE_BUF_SIZE]; -}; - -struct imx_write_ctrl { - int index; - struct imx_write_buffer buffer; -}; - -static const struct imx_reg imx_soft_standby[] = { - {IMX_8BIT, 0x0100, 0x00}, - {IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx_streaming[] = { - {IMX_8BIT, 0x0100, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx_param_hold[] = { - {IMX_8BIT, 0x0104, 0x01}, /* GROUPED_PARAMETER_HOLD */ - {IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx_param_update[] = { - {IMX_8BIT, 0x0104, 0x00}, /* GROUPED_PARAMETER_HOLD */ - {IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx219_param_hold[] = { - {IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx219_param_update[] = { - {IMX_TOK_TERM, 0, 0} -}; - -extern int ad5816g_vcm_power_up(struct v4l2_subdev *sd); -extern int ad5816g_vcm_power_down(struct v4l2_subdev *sd); -extern int ad5816g_t_focus_abs(struct v4l2_subdev *sd, s32 value); -extern int ad5816g_t_focus_rel(struct v4l2_subdev *sd, s32 value); -extern int ad5816g_q_focus_status(struct v4l2_subdev *sd, s32 *value); -extern int ad5816g_q_focus_abs(struct v4l2_subdev *sd, s32 *value); -extern int ad5816g_t_vcm_slew(struct v4l2_subdev *sd, s32 value); -extern int ad5816g_t_vcm_timing(struct v4l2_subdev *sd, s32 value); - -extern int drv201_vcm_power_up(struct v4l2_subdev *sd); -extern int drv201_vcm_power_down(struct v4l2_subdev *sd); -extern int drv201_t_focus_abs(struct v4l2_subdev *sd, s32 value); -extern int drv201_t_focus_rel(struct v4l2_subdev *sd, s32 value); -extern int drv201_q_focus_status(struct v4l2_subdev *sd, s32 *value); -extern int drv201_q_focus_abs(struct v4l2_subdev *sd, s32 *value); -extern int drv201_t_vcm_slew(struct v4l2_subdev *sd, s32 value); -extern int drv201_t_vcm_timing(struct v4l2_subdev *sd, s32 value); - -extern int dw9714_vcm_power_up(struct v4l2_subdev *sd); -extern int dw9714_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9714_t_focus_abs(struct v4l2_subdev *sd, s32 value); -extern int dw9714_t_focus_abs_init(struct v4l2_subdev *sd); -extern int dw9714_t_focus_rel(struct v4l2_subdev *sd, s32 value); -extern int dw9714_q_focus_status(struct v4l2_subdev *sd, s32 *value); -extern int dw9714_q_focus_abs(struct v4l2_subdev *sd, s32 *value); -extern int dw9714_t_vcm_slew(struct v4l2_subdev *sd, s32 value); -extern int dw9714_t_vcm_timing(struct v4l2_subdev *sd, s32 value); - -extern int dw9719_vcm_power_up(struct v4l2_subdev *sd); -extern int dw9719_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9719_t_focus_abs(struct v4l2_subdev *sd, s32 value); -extern int dw9719_t_focus_rel(struct v4l2_subdev *sd, s32 value); -extern int dw9719_q_focus_status(struct v4l2_subdev *sd, s32 *value); -extern int dw9719_q_focus_abs(struct v4l2_subdev *sd, s32 *value); -extern int dw9719_t_vcm_slew(struct v4l2_subdev *sd, s32 value); -extern int dw9719_t_vcm_timing(struct v4l2_subdev *sd, s32 value); - -extern int dw9718_vcm_power_up(struct v4l2_subdev *sd); -extern int dw9718_vcm_power_down(struct v4l2_subdev *sd); -extern int dw9718_t_focus_abs(struct v4l2_subdev *sd, s32 value); -extern int dw9718_t_focus_rel(struct v4l2_subdev *sd, s32 value); -extern int dw9718_q_focus_status(struct v4l2_subdev *sd, s32 *value); -extern int dw9718_q_focus_abs(struct v4l2_subdev *sd, s32 *value); -extern int dw9718_t_vcm_slew(struct v4l2_subdev *sd, s32 value); -extern int dw9718_t_vcm_timing(struct v4l2_subdev *sd, s32 value); - -extern int vcm_power_up(struct v4l2_subdev *sd); -extern int vcm_power_down(struct v4l2_subdev *sd); - -struct imx_vcm imx_vcms[] = { - [IMX175_MERRFLD] = { - .power_up = drv201_vcm_power_up, - .power_down = drv201_vcm_power_down, - .t_focus_abs = drv201_t_focus_abs, - .t_focus_abs_init = NULL, - .t_focus_rel = drv201_t_focus_rel, - .q_focus_status = drv201_q_focus_status, - .q_focus_abs = drv201_q_focus_abs, - .t_vcm_slew = drv201_t_vcm_slew, - .t_vcm_timing = drv201_t_vcm_timing, - }, - [IMX175_VALLEYVIEW] = { - .power_up = dw9714_vcm_power_up, - .power_down = dw9714_vcm_power_down, - .t_focus_abs = dw9714_t_focus_abs, - .t_focus_abs_init = NULL, - .t_focus_rel = dw9714_t_focus_rel, - .q_focus_status = dw9714_q_focus_status, - .q_focus_abs = dw9714_q_focus_abs, - .t_vcm_slew = dw9714_t_vcm_slew, - .t_vcm_timing = dw9714_t_vcm_timing, - }, - [IMX135_SALTBAY] = { - .power_up = ad5816g_vcm_power_up, - .power_down = ad5816g_vcm_power_down, - .t_focus_abs = ad5816g_t_focus_abs, - .t_focus_abs_init = NULL, - .t_focus_rel = ad5816g_t_focus_rel, - .q_focus_status = ad5816g_q_focus_status, - .q_focus_abs = ad5816g_q_focus_abs, - .t_vcm_slew = ad5816g_t_vcm_slew, - .t_vcm_timing = ad5816g_t_vcm_timing, - }, - [IMX135_VICTORIABAY] = { - .power_up = dw9719_vcm_power_up, - .power_down = dw9719_vcm_power_down, - .t_focus_abs = dw9719_t_focus_abs, - .t_focus_abs_init = NULL, - .t_focus_rel = dw9719_t_focus_rel, - .q_focus_status = dw9719_q_focus_status, - .q_focus_abs = dw9719_q_focus_abs, - .t_vcm_slew = dw9719_t_vcm_slew, - .t_vcm_timing = dw9719_t_vcm_timing, - }, - [IMX134_VALLEYVIEW] = { - .power_up = dw9714_vcm_power_up, - .power_down = dw9714_vcm_power_down, - .t_focus_abs = dw9714_t_focus_abs, - .t_focus_abs_init = dw9714_t_focus_abs_init, - .t_focus_rel = dw9714_t_focus_rel, - .q_focus_status = dw9714_q_focus_status, - .q_focus_abs = dw9714_q_focus_abs, - .t_vcm_slew = dw9714_t_vcm_slew, - .t_vcm_timing = dw9714_t_vcm_timing, - }, - [IMX219_MFV0_PRH] = { - .power_up = dw9718_vcm_power_up, - .power_down = dw9718_vcm_power_down, - .t_focus_abs = dw9718_t_focus_abs, - .t_focus_abs_init = NULL, - .t_focus_rel = dw9718_t_focus_rel, - .q_focus_status = dw9718_q_focus_status, - .q_focus_abs = dw9718_q_focus_abs, - .t_vcm_slew = dw9718_t_vcm_slew, - .t_vcm_timing = dw9718_t_vcm_timing, - }, - [IMX_ID_DEFAULT] = { - .power_up = NULL, - .power_down = NULL, - .t_focus_abs_init = NULL, - }, -}; - -extern void *dummy_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -extern void *imx_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -extern void *e2prom_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -extern void *brcc064_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -extern void *imx227_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -extern void *e2prom_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size); -struct imx_otp imx_otps[] = { - [IMX175_MERRFLD] = { - .otp_read = imx_otp_read, - .dev_addr = E2PROM_ADDR, - .start_addr = 0, - .size = DEFAULT_OTP_SIZE, - }, - [IMX175_VALLEYVIEW] = { - .otp_read = e2prom_otp_read, - .dev_addr = E2PROM_ABICO_SS89A839_ADDR, - .start_addr = E2PROM_2ADDR, - .size = DEFAULT_OTP_SIZE, - }, - [IMX135_SALTBAY] = { - .otp_read = e2prom_otp_read, - .dev_addr = E2PROM_ADDR, - .start_addr = 0, - .size = DEFAULT_OTP_SIZE, - }, - [IMX135_VICTORIABAY] = { - .otp_read = imx_otp_read, - .size = DEFAULT_OTP_SIZE, - }, - [IMX134_VALLEYVIEW] = { - .otp_read = e2prom_otp_read, - .dev_addr = E2PROM_LITEON_12P1BA869D_ADDR, - .start_addr = 0, - .size = E2PROM_LITEON_12P1BA869D_SIZE, - }, - [IMX132_SALTBAY] = { - .otp_read = dummy_otp_read, - .size = DEFAULT_OTP_SIZE, - }, - [IMX208_MOFD_PD2] = { - .otp_read = dummy_otp_read, - .size = DEFAULT_OTP_SIZE, - }, - [IMX219_MFV0_PRH] = { - .otp_read = brcc064_otp_read, - .dev_addr = E2PROM_ADDR, - .start_addr = 0, - .size = IMX219_OTP_SIZE, - }, - [IMX227_SAND] = { - .otp_read = imx227_otp_read, - .size = IMX227_OTP_SIZE, - }, - [IMX_ID_DEFAULT] = { - .otp_read = dummy_otp_read, - .size = DEFAULT_OTP_SIZE, - }, -}; - -#endif - diff --git a/drivers/staging/media/atomisp/i2c/imx/imx132.h b/drivers/staging/media/atomisp/i2c/imx/imx132.h deleted file mode 100644 index 98f047b8a1ba..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx132.h +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Support for Sony IMX camera sensor. - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __IMX132_H__ -#define __IMX132_H__ -#include "common.h" - -/********************** registers define ********************************/ -#define IMX132_RGLANESEL 0x3301 /* Number of lanes */ -#define IMX132_RGLANESEL_1LANE 0x01 -#define IMX132_RGLANESEL_2LANES 0x00 -#define IMX132_RGLANESEL_4LANES 0x03 - -#define IMX132_2LANES_GAINFACT 2096 /* 524/256 * 2^10 */ -#define IMX132_2LANES_GAINFACT_SHIFT 10 - -/********************** settings for imx from vendor*********************/ -static struct imx_reg imx132_1080p_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* Global Settings */ - {IMX_8BIT, 0x3087, 0x53}, - {IMX_8BIT, 0x308B, 0x5A}, - {IMX_8BIT, 0x3094, 0x11}, - {IMX_8BIT, 0x309D, 0xA4}, - {IMX_8BIT, 0x30AA, 0x01}, - {IMX_8BIT, 0x30C6, 0x00}, - {IMX_8BIT, 0x30C7, 0x00}, - {IMX_8BIT, 0x3118, 0x2F}, - {IMX_8BIT, 0x312A, 0x00}, - {IMX_8BIT, 0x312B, 0x0B}, - {IMX_8BIT, 0x312C, 0x0B}, - {IMX_8BIT, 0x312D, 0x13}, - /* PLL setting */ - {IMX_8BIT, 0x0305, 0x02}, - {IMX_8BIT, 0x0307, 0x50}, - {IMX_8BIT, 0x30A4, 0x02}, - {IMX_8BIT, 0x303C, 0x3C}, - /* Mode setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x14}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x32}, - {IMX_8BIT, 0x0348, 0x07}, - {IMX_8BIT, 0x0349, 0xA3}, - {IMX_8BIT, 0x034A, 0x04}, - {IMX_8BIT, 0x034B, 0x79}, - {IMX_8BIT, 0x034C, 0x07}, - {IMX_8BIT, 0x034D, 0x90}, - {IMX_8BIT, 0x034E, 0x04}, - {IMX_8BIT, 0x034F, 0x48}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x303D, 0x10}, - {IMX_8BIT, 0x303E, 0x5A}, - {IMX_8BIT, 0x3040, 0x00}, - {IMX_8BIT, 0x3041, 0x00}, - {IMX_8BIT, 0x3048, 0x00}, - {IMX_8BIT, 0x304C, 0x2F}, - {IMX_8BIT, 0x304D, 0x02}, - {IMX_8BIT, 0x3064, 0x92}, - {IMX_8BIT, 0x306A, 0x10}, - {IMX_8BIT, 0x309B, 0x00}, - {IMX_8BIT, 0x309E, 0x41}, - {IMX_8BIT, 0x30A0, 0x10}, - {IMX_8BIT, 0x30A1, 0x0B}, - {IMX_8BIT, 0x30B2, 0x00}, - {IMX_8BIT, 0x30D5, 0x00}, - {IMX_8BIT, 0x30D6, 0x00}, - {IMX_8BIT, 0x30D7, 0x00}, - {IMX_8BIT, 0x30D8, 0x00}, - {IMX_8BIT, 0x30D9, 0x00}, - {IMX_8BIT, 0x30DA, 0x00}, - {IMX_8BIT, 0x30DB, 0x00}, - {IMX_8BIT, 0x30DC, 0x00}, - {IMX_8BIT, 0x30DD, 0x00}, - {IMX_8BIT, 0x30DE, 0x00}, - {IMX_8BIT, 0x3102, 0x0C}, - {IMX_8BIT, 0x3103, 0x33}, - {IMX_8BIT, 0x3104, 0x18}, - {IMX_8BIT, 0x3105, 0x00}, - {IMX_8BIT, 0x3106, 0x65}, - {IMX_8BIT, 0x3107, 0x00}, - {IMX_8BIT, 0x3108, 0x06}, - {IMX_8BIT, 0x3109, 0x04}, - {IMX_8BIT, 0x310A, 0x04}, - {IMX_8BIT, 0x315C, 0x3D}, - {IMX_8BIT, 0x315D, 0x3C}, - {IMX_8BIT, 0x316E, 0x3E}, - {IMX_8BIT, 0x316F, 0x3D}, - /* Global timing */ - {IMX_8BIT, 0x3304, 0x07}, /* RGTLPX[5:0] TLPX */ - {IMX_8BIT, 0x3305, 0x06}, /* RGTCLKPREPARE[3:0] TCLK-PREPARE */ - {IMX_8BIT, 0x3306, 0x19}, /* RGTCLKZERO[5:0] TCLK-ZERO */ - {IMX_8BIT, 0x3307, 0x03}, /* RGTCLKPRE[5:0] TCLK-PRE */ - {IMX_8BIT, 0x3308, 0x0F}, /* RGTCLKPOST[5:0] TCLK-POST */ - {IMX_8BIT, 0x3309, 0x07}, /* RGTCLKTRAIL[3:0] TCLK-TRAIL */ - {IMX_8BIT, 0x330A, 0x0C}, /* RGTHSEXIT[5:0] THS-EXIT */ - {IMX_8BIT, 0x330B, 0x06}, /* RGTHSPREPARE[3:0] THS-PREPARE */ - {IMX_8BIT, 0x330C, 0x0B}, /* RGTHSZERO[5:0] THS-ZERO */ - {IMX_8BIT, 0x330D, 0x07}, /* RGTHSTRAIL[3:0] THS-TRAIL */ - {IMX_8BIT, 0x330E, 0x03}, - {IMX_8BIT, 0x3318, 0x62}, - {IMX_8BIT, 0x3322, 0x09}, - {IMX_8BIT, 0x3342, 0x00}, - {IMX_8BIT, 0x3348, 0xE0}, - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx132_1456x1096_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* Global Settings */ - {IMX_8BIT, 0x3087, 0x53}, - {IMX_8BIT, 0x308B, 0x5A}, - {IMX_8BIT, 0x3094, 0x11}, - {IMX_8BIT, 0x309D, 0xA4}, - {IMX_8BIT, 0x30AA, 0x01}, - {IMX_8BIT, 0x30C6, 0x00}, - {IMX_8BIT, 0x30C7, 0x00}, - {IMX_8BIT, 0x3118, 0x2F}, - {IMX_8BIT, 0x312A, 0x00}, - {IMX_8BIT, 0x312B, 0x0B}, - {IMX_8BIT, 0x312C, 0x0B}, - {IMX_8BIT, 0x312D, 0x13}, - /* PLL setting */ - {IMX_8BIT, 0x0305, 0x02}, - {IMX_8BIT, 0x0307, 0x50}, - {IMX_8BIT, 0x30A4, 0x02}, - {IMX_8BIT, 0x303C, 0x3C}, - /* Mode setting */ - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0x04}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x32}, - {IMX_8BIT, 0x0348, 0x06}, - {IMX_8BIT, 0x0349, 0xB3}, - {IMX_8BIT, 0x034A, 0x04}, - {IMX_8BIT, 0x034B, 0x79}, - {IMX_8BIT, 0x034C, 0x05}, - {IMX_8BIT, 0x034D, 0xB0}, - {IMX_8BIT, 0x034E, 0x04}, - {IMX_8BIT, 0x034F, 0x48}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x303D, 0x10}, - {IMX_8BIT, 0x303E, 0x5A}, - {IMX_8BIT, 0x3040, 0x00}, - {IMX_8BIT, 0x3041, 0x00}, - {IMX_8BIT, 0x3048, 0x00}, - {IMX_8BIT, 0x304C, 0x2F}, - {IMX_8BIT, 0x304D, 0x02}, - {IMX_8BIT, 0x3064, 0x92}, - {IMX_8BIT, 0x306A, 0x10}, - {IMX_8BIT, 0x309B, 0x00}, - {IMX_8BIT, 0x309E, 0x41}, - {IMX_8BIT, 0x30A0, 0x10}, - {IMX_8BIT, 0x30A1, 0x0B}, - {IMX_8BIT, 0x30B2, 0x00}, - {IMX_8BIT, 0x30D5, 0x00}, - {IMX_8BIT, 0x30D6, 0x00}, - {IMX_8BIT, 0x30D7, 0x00}, - {IMX_8BIT, 0x30D8, 0x00}, - {IMX_8BIT, 0x30D9, 0x00}, - {IMX_8BIT, 0x30DA, 0x00}, - {IMX_8BIT, 0x30DB, 0x00}, - {IMX_8BIT, 0x30DC, 0x00}, - {IMX_8BIT, 0x30DD, 0x00}, - {IMX_8BIT, 0x30DE, 0x00}, - {IMX_8BIT, 0x3102, 0x0C}, - {IMX_8BIT, 0x3103, 0x33}, - {IMX_8BIT, 0x3104, 0x18}, - {IMX_8BIT, 0x3105, 0x00}, - {IMX_8BIT, 0x3106, 0x65}, - {IMX_8BIT, 0x3107, 0x00}, - {IMX_8BIT, 0x3108, 0x06}, - {IMX_8BIT, 0x3109, 0x04}, - {IMX_8BIT, 0x310A, 0x04}, - {IMX_8BIT, 0x315C, 0x3D}, - {IMX_8BIT, 0x315D, 0x3C}, - {IMX_8BIT, 0x316E, 0x3E}, - {IMX_8BIT, 0x316F, 0x3D}, - /* Global timing */ - {IMX_8BIT, 0x3304, 0x07}, /* RGTLPX[5:0] TLPX */ - {IMX_8BIT, 0x3305, 0x06}, /* RGTCLKPREPARE[3:0] TCLK-PREPARE */ - {IMX_8BIT, 0x3306, 0x19}, /* RGTCLKZERO[5:0] TCLK-ZERO */ - {IMX_8BIT, 0x3307, 0x03}, /* RGTCLKPRE[5:0] TCLK-PRE */ - {IMX_8BIT, 0x3308, 0x0F}, /* RGTCLKPOST[5:0] TCLK-POST */ - {IMX_8BIT, 0x3309, 0x07}, /* RGTCLKTRAIL[3:0] TCLK-TRAIL */ - {IMX_8BIT, 0x330A, 0x0C}, /* RGTHSEXIT[5:0] THS-EXIT */ - {IMX_8BIT, 0x330B, 0x06}, /* RGTHSPREPARE[3:0] THS-PREPARE */ - {IMX_8BIT, 0x330C, 0x0B}, /* RGTHSZERO[5:0] THS-ZERO */ - {IMX_8BIT, 0x330D, 0x07}, /* RGTHSTRAIL[3:0] THS-TRAIL */ - {IMX_8BIT, 0x330E, 0x03}, - {IMX_8BIT, 0x3318, 0x62}, - {IMX_8BIT, 0x3322, 0x09}, - {IMX_8BIT, 0x3342, 0x00}, - {IMX_8BIT, 0x3348, 0xE0}, - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx132_1636x1096_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* Global Settings */ - {IMX_8BIT, 0x3087, 0x53}, - {IMX_8BIT, 0x308B, 0x5A}, - {IMX_8BIT, 0x3094, 0x11}, - {IMX_8BIT, 0x309D, 0xA4}, - {IMX_8BIT, 0x30AA, 0x01}, - {IMX_8BIT, 0x30C6, 0x00}, - {IMX_8BIT, 0x30C7, 0x00}, - {IMX_8BIT, 0x3118, 0x2F}, - {IMX_8BIT, 0x312A, 0x00}, - {IMX_8BIT, 0x312B, 0x0B}, - {IMX_8BIT, 0x312C, 0x0B}, - {IMX_8BIT, 0x312D, 0x13}, - /* PLL setting */ - {IMX_8BIT, 0x0305, 0x02}, - {IMX_8BIT, 0x0307, 0x50}, - {IMX_8BIT, 0x30A4, 0x02}, - {IMX_8BIT, 0x303C, 0x3C}, - /* Mode setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0xAA}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x32}, - {IMX_8BIT, 0x0348, 0x07}, - {IMX_8BIT, 0x0349, 0x0D}, - {IMX_8BIT, 0x034A, 0x04}, - {IMX_8BIT, 0x034B, 0x79}, - {IMX_8BIT, 0x034C, 0x06}, - {IMX_8BIT, 0x034D, 0x64}, - {IMX_8BIT, 0x034E, 0x04}, - {IMX_8BIT, 0x034F, 0x48}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x303D, 0x10}, - {IMX_8BIT, 0x303E, 0x5A}, - {IMX_8BIT, 0x3040, 0x00}, - {IMX_8BIT, 0x3041, 0x00}, - {IMX_8BIT, 0x3048, 0x00}, - {IMX_8BIT, 0x304C, 0x2F}, - {IMX_8BIT, 0x304D, 0x02}, - {IMX_8BIT, 0x3064, 0x92}, - {IMX_8BIT, 0x306A, 0x10}, - {IMX_8BIT, 0x309B, 0x00}, - {IMX_8BIT, 0x309E, 0x41}, - {IMX_8BIT, 0x30A0, 0x10}, - {IMX_8BIT, 0x30A1, 0x0B}, - {IMX_8BIT, 0x30B2, 0x00}, - {IMX_8BIT, 0x30D5, 0x00}, - {IMX_8BIT, 0x30D6, 0x00}, - {IMX_8BIT, 0x30D7, 0x00}, - {IMX_8BIT, 0x30D8, 0x00}, - {IMX_8BIT, 0x30D9, 0x00}, - {IMX_8BIT, 0x30DA, 0x00}, - {IMX_8BIT, 0x30DB, 0x00}, - {IMX_8BIT, 0x30DC, 0x00}, - {IMX_8BIT, 0x30DD, 0x00}, - {IMX_8BIT, 0x30DE, 0x00}, - {IMX_8BIT, 0x3102, 0x0C}, - {IMX_8BIT, 0x3103, 0x33}, - {IMX_8BIT, 0x3104, 0x18}, - {IMX_8BIT, 0x3105, 0x00}, - {IMX_8BIT, 0x3106, 0x65}, - {IMX_8BIT, 0x3107, 0x00}, - {IMX_8BIT, 0x3108, 0x06}, - {IMX_8BIT, 0x3109, 0x04}, - {IMX_8BIT, 0x310A, 0x04}, - {IMX_8BIT, 0x315C, 0x3D}, - {IMX_8BIT, 0x315D, 0x3C}, - {IMX_8BIT, 0x316E, 0x3E}, - {IMX_8BIT, 0x316F, 0x3D}, - /* Global timing */ - {IMX_8BIT, 0x3304, 0x07}, /* RGTLPX[5:0] TLPX */ - {IMX_8BIT, 0x3305, 0x06}, /* RGTCLKPREPARE[3:0] TCLK-PREPARE */ - {IMX_8BIT, 0x3306, 0x19}, /* RGTCLKZERO[5:0] TCLK-ZERO */ - {IMX_8BIT, 0x3307, 0x03}, /* RGTCLKPRE[5:0] TCLK-PRE */ - {IMX_8BIT, 0x3308, 0x0F}, /* RGTCLKPOST[5:0] TCLK-POST */ - {IMX_8BIT, 0x3309, 0x07}, /* RGTCLKTRAIL[3:0] TCLK-TRAIL */ - {IMX_8BIT, 0x330A, 0x0C}, /* RGTHSEXIT[5:0] THS-EXIT */ - {IMX_8BIT, 0x330B, 0x06}, /* RGTHSPREPARE[3:0] THS-PREPARE */ - {IMX_8BIT, 0x330C, 0x0B}, /* RGTHSZERO[5:0] THS-ZERO */ - {IMX_8BIT, 0x330D, 0x07}, /* RGTHSTRAIL[3:0] THS-TRAIL */ - {IMX_8BIT, 0x330E, 0x03}, - {IMX_8BIT, 0x3318, 0x62}, - {IMX_8BIT, 0x3322, 0x09}, - {IMX_8BIT, 0x3342, 0x00}, - {IMX_8BIT, 0x3348, 0xE0}, - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx132_1336x1096_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* Global Settings */ - {IMX_8BIT, 0x3087, 0x53}, - {IMX_8BIT, 0x308B, 0x5A}, - {IMX_8BIT, 0x3094, 0x11}, - {IMX_8BIT, 0x309D, 0xA4}, - {IMX_8BIT, 0x30AA, 0x01}, - {IMX_8BIT, 0x30C6, 0x00}, - {IMX_8BIT, 0x30C7, 0x00}, - {IMX_8BIT, 0x3118, 0x2F}, - {IMX_8BIT, 0x312A, 0x00}, - {IMX_8BIT, 0x312B, 0x0B}, - {IMX_8BIT, 0x312C, 0x0B}, - {IMX_8BIT, 0x312D, 0x13}, - /* PLL setting */ - {IMX_8BIT, 0x0305, 0x02}, - {IMX_8BIT, 0x0307, 0x50}, - {IMX_8BIT, 0x30A4, 0x02}, - {IMX_8BIT, 0x303C, 0x3C}, - /* Mode setting */ - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0x2C}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x32}, - {IMX_8BIT, 0x0348, 0x06}, - {IMX_8BIT, 0x0349, 0x77}, - {IMX_8BIT, 0x034A, 0x04}, - {IMX_8BIT, 0x034B, 0x79}, - {IMX_8BIT, 0x034C, 0x05}, - {IMX_8BIT, 0x034D, 0x38}, - {IMX_8BIT, 0x034E, 0x04}, - {IMX_8BIT, 0x034F, 0x48}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x303D, 0x10}, - {IMX_8BIT, 0x303E, 0x5A}, - {IMX_8BIT, 0x3040, 0x00}, - {IMX_8BIT, 0x3041, 0x00}, - {IMX_8BIT, 0x3048, 0x00}, - {IMX_8BIT, 0x304C, 0x2F}, - {IMX_8BIT, 0x304D, 0x02}, - {IMX_8BIT, 0x3064, 0x92}, - {IMX_8BIT, 0x306A, 0x10}, - {IMX_8BIT, 0x309B, 0x00}, - {IMX_8BIT, 0x309E, 0x41}, - {IMX_8BIT, 0x30A0, 0x10}, - {IMX_8BIT, 0x30A1, 0x0B}, - {IMX_8BIT, 0x30B2, 0x00}, - {IMX_8BIT, 0x30D5, 0x00}, - {IMX_8BIT, 0x30D6, 0x00}, - {IMX_8BIT, 0x30D7, 0x00}, - {IMX_8BIT, 0x30D8, 0x00}, - {IMX_8BIT, 0x30D9, 0x00}, - {IMX_8BIT, 0x30DA, 0x00}, - {IMX_8BIT, 0x30DB, 0x00}, - {IMX_8BIT, 0x30DC, 0x00}, - {IMX_8BIT, 0x30DD, 0x00}, - {IMX_8BIT, 0x30DE, 0x00}, - {IMX_8BIT, 0x3102, 0x0C}, - {IMX_8BIT, 0x3103, 0x33}, - {IMX_8BIT, 0x3104, 0x18}, - {IMX_8BIT, 0x3105, 0x00}, - {IMX_8BIT, 0x3106, 0x65}, - {IMX_8BIT, 0x3107, 0x00}, - {IMX_8BIT, 0x3108, 0x06}, - {IMX_8BIT, 0x3109, 0x04}, - {IMX_8BIT, 0x310A, 0x04}, - {IMX_8BIT, 0x315C, 0x3D}, - {IMX_8BIT, 0x315D, 0x3C}, - {IMX_8BIT, 0x316E, 0x3E}, - {IMX_8BIT, 0x316F, 0x3D}, - /* Global timing */ - {IMX_8BIT, 0x3304, 0x07}, /* RGTLPX[5:0] TLPX */ - {IMX_8BIT, 0x3305, 0x06}, /* RGTCLKPREPARE[3:0] TCLK-PREPARE */ - {IMX_8BIT, 0x3306, 0x19}, /* RGTCLKZERO[5:0] TCLK-ZERO */ - {IMX_8BIT, 0x3307, 0x03}, /* RGTCLKPRE[5:0] TCLK-PRE */ - {IMX_8BIT, 0x3308, 0x0F}, /* RGTCLKPOST[5:0] TCLK-POST */ - {IMX_8BIT, 0x3309, 0x07}, /* RGTCLKTRAIL[3:0] TCLK-TRAIL */ - {IMX_8BIT, 0x330A, 0x0C}, /* RGTHSEXIT[5:0] THS-EXIT */ - {IMX_8BIT, 0x330B, 0x06}, /* RGTHSPREPARE[3:0] THS-PREPARE */ - {IMX_8BIT, 0x330C, 0x0B}, /* RGTHSZERO[5:0] THS-ZERO */ - {IMX_8BIT, 0x330D, 0x07}, /* RGTHSTRAIL[3:0] THS-TRAIL */ - {IMX_8BIT, 0x330E, 0x03}, - {IMX_8BIT, 0x3318, 0x62}, - {IMX_8BIT, 0x3322, 0x09}, - {IMX_8BIT, 0x3342, 0x00}, - {IMX_8BIT, 0x3348, 0xE0}, - - {IMX_TOK_TERM, 0, 0}, -}; - -/********************** settings for imx - reference *********************/ -static struct imx_reg const imx132_init_settings[] = { - /* sw reset */ - { IMX_8BIT, 0x0100, 0x00 }, - { IMX_8BIT, 0x0103, 0x01 }, - { IMX_TOK_DELAY, 0, 5}, - { IMX_8BIT, 0x0103, 0x00 }, - GROUPED_PARAMETER_HOLD_ENABLE, - /* Global Settings */ - {IMX_8BIT, 0x3087, 0x53}, - {IMX_8BIT, 0x308B, 0x5A}, - {IMX_8BIT, 0x3094, 0x11}, - {IMX_8BIT, 0x309D, 0xA4}, - {IMX_8BIT, 0x30AA, 0x01}, - {IMX_8BIT, 0x30C6, 0x00}, - {IMX_8BIT, 0x30C7, 0x00}, - {IMX_8BIT, 0x3118, 0x2F}, - {IMX_8BIT, 0x312A, 0x00}, - {IMX_8BIT, 0x312B, 0x0B}, - {IMX_8BIT, 0x312C, 0x0B}, - {IMX_8BIT, 0x312D, 0x13}, - GROUPED_PARAMETER_HOLD_DISABLE, - { IMX_TOK_TERM, 0, 0} -}; - -struct imx_resolution imx132_res_preview[] = { - { - .desc = "imx132_1080p_30fps", - .regs = imx132_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, -}; - -struct imx_resolution imx132_res_still[] = { - { - .desc = "imx132_1080p_30fps", - .regs = imx132_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, -}; - -struct imx_resolution imx132_res_video[] = { - { - .desc = "imx132_1336x1096_30fps", - .regs = imx132_1336x1096_30fps, - .width = 1336, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, - { - .desc = "imx132_1456x1096_30fps", - .regs = imx132_1456x1096_30fps, - .width = 1456, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, - { - .desc = "imx132_1636x1096_30fps", - .regs = imx132_1636x1096_30fps, - .width = 1636, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, - { - .desc = "imx132_1080p_30fps", - .regs = imx132_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08F2, - .lines_per_frame = 0x045C, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .skip_frames = 2, - .mipi_freq = 384000, - }, -}; -#endif - diff --git a/drivers/staging/media/atomisp/i2c/imx/imx134.h b/drivers/staging/media/atomisp/i2c/imx/imx134.h deleted file mode 100644 index 9026e8ba5679..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx134.h +++ /dev/null @@ -1,2465 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IMX134_H__ -#define __IMX134_H__ - -/********************** imx134 setting - version 1 *********************/ -static struct imx_reg const imx134_init_settings[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* Basic settings */ - { IMX_8BIT, 0x0105, 0x01 }, - { IMX_8BIT, 0x0220, 0x01 }, - { IMX_8BIT, 0x3302, 0x11 }, - { IMX_8BIT, 0x3833, 0x20 }, - { IMX_8BIT, 0x3893, 0x00 }, - { IMX_8BIT, 0x3906, 0x08 }, - { IMX_8BIT, 0x3907, 0x01 }, - { IMX_8BIT, 0x391B, 0x01 }, - { IMX_8BIT, 0x3C09, 0x01 }, - { IMX_8BIT, 0x600A, 0x00 }, - - /* Analog settings */ - { IMX_8BIT, 0x3008, 0xB0 }, - { IMX_8BIT, 0x320A, 0x01 }, - { IMX_8BIT, 0x320D, 0x10 }, - { IMX_8BIT, 0x3216, 0x2E }, - { IMX_8BIT, 0x322C, 0x02 }, - { IMX_8BIT, 0x3409, 0x0C }, - { IMX_8BIT, 0x340C, 0x2D }, - { IMX_8BIT, 0x3411, 0x39 }, - { IMX_8BIT, 0x3414, 0x1E }, - { IMX_8BIT, 0x3427, 0x04 }, - { IMX_8BIT, 0x3480, 0x1E }, - { IMX_8BIT, 0x3484, 0x1E }, - { IMX_8BIT, 0x3488, 0x1E }, - { IMX_8BIT, 0x348C, 0x1E }, - { IMX_8BIT, 0x3490, 0x1E }, - { IMX_8BIT, 0x3494, 0x1E }, - { IMX_8BIT, 0x3511, 0x8F }, - { IMX_8BIT, 0x3617, 0x2D }, - - GROUPED_PARAMETER_HOLD_DISABLE, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 3280x2464 8M 30fps, vendor provide */ -static struct imx_reg const imx134_8M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* clock setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, - { IMX_8BIT, 0x0391, 0x11 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, /* down scaling 16/16 = 1 */ - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0345, 0x00 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0347, 0x00 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3279 */ - { IMX_8BIT, 0x0349, 0xCF }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2463 */ - { IMX_8BIT, 0x034B, 0x9F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x0C }, /* x_output_size[15:8]: 3280*/ - { IMX_8BIT, 0x034D, 0xD0 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x09 }, /* y_output_size[15:8]:2464 */ - { IMX_8BIT, 0x034F, 0xA0 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x0C }, - { IMX_8BIT, 0x0355, 0xD0 }, - { IMX_8BIT, 0x0356, 0x09 }, - { IMX_8BIT, 0x0357, 0xA0 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x0C }, - { IMX_8BIT, 0x3311, 0xD0 }, - { IMX_8BIT, 0x3312, 0x09 }, - { IMX_8BIT, 0x3313, 0xA0 }, - { IMX_8BIT, 0x331C, 0x01 }, - { IMX_8BIT, 0x331D, 0xAE }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global timing setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration time setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/2 binning 30fps 1640x1232, vendor provide */ -static struct imx_reg const imx134_1640_1232_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* no resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0345, 0x00 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0347, 0x00 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3279 */ - { IMX_8BIT, 0x0349, 0xCF }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2463 */ - { IMX_8BIT, 0x034B, 0x9F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x06 }, /* x_output_size[15:8]:1640 */ - { IMX_8BIT, 0x034D, 0x68 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x04 }, /* y_output_size[15:8]:1232 */ - { IMX_8BIT, 0x034F, 0xD0 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x68 }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0xD0 }, - - { IMX_8BIT, 0x301D, 0x30 }, - - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x68 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0xD0 }, - - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x06 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/4 binning 30fps 820x616, vendor provide */ -static struct imx_reg const imx134_820_616_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x44 }, /* 4x4 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* no resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0345, 0x00 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0347, 0x00 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3279 */ - { IMX_8BIT, 0x0349, 0xCF }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2463 */ - { IMX_8BIT, 0x034B, 0x9F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x03 }, /* x_output_size[15:8]:820 */ - { IMX_8BIT, 0x034D, 0x34 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:616 */ - { IMX_8BIT, 0x034F, 0x68 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x03 }, - { IMX_8BIT, 0x0355, 0x34 }, - { IMX_8BIT, 0x0356, 0x02 }, - { IMX_8BIT, 0x0357, 0x68 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x03 }, - { IMX_8BIT, 0x3311, 0x34 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x68 }, - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/4 binning 30fps 820x552 */ -static struct imx_reg const imx134_820_552_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x44 }, /* 4x4 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* no resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0345, 0x00 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:128 */ - { IMX_8BIT, 0x0347, 0x80 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3280-1 */ - { IMX_8BIT, 0x0349, 0xCF }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2208+128-1 */ - { IMX_8BIT, 0x034B, 0x1F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x03 }, /* x_output_size[15:8]: */ - { IMX_8BIT, 0x034D, 0x34 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:616 */ - { IMX_8BIT, 0x034F, 0x28 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x03 }, - { IMX_8BIT, 0x0355, 0x34 }, - { IMX_8BIT, 0x0356, 0x02 }, - { IMX_8BIT, 0x0357, 0x28 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x03 }, - { IMX_8BIT, 0x3311, 0x34 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x28 }, - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/4 binning 30fps 720x592 */ -static struct imx_reg const imx134_720_592_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x44 }, /* 4x4 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* no resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:200 */ - { IMX_8BIT, 0x0345, 0xC8 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:40 */ - { IMX_8BIT, 0x0347, 0x28 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:2880+200-1 */ - { IMX_8BIT, 0x0349, 0x07 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2368+40-1 */ - { IMX_8BIT, 0x034B, 0x67 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x02 }, /* x_output_size[15:8]: */ - { IMX_8BIT, 0x034D, 0xD0 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:616 */ - { IMX_8BIT, 0x034F, 0x50 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x02 }, - { IMX_8BIT, 0x0355, 0xD0 }, - { IMX_8BIT, 0x0356, 0x02 }, - { IMX_8BIT, 0x0357, 0x50 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x02 }, - { IMX_8BIT, 0x3311, 0xD0 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x50 }, - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -static struct imx_reg const imx134_752_616_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x44 }, /* 4x4 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* no resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:136 */ - { IMX_8BIT, 0x0345, 0x88 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0347, 0x00 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3145+134-1 */ - { IMX_8BIT, 0x0349, 0x47 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2463 */ - { IMX_8BIT, 0x034B, 0x9F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x02 }, /* x_output_size[15:8]: 752*/ - { IMX_8BIT, 0x034D, 0xF0 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:616 */ - { IMX_8BIT, 0x034F, 0x68 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - - { IMX_8BIT, 0x0354, 0x02 }, - { IMX_8BIT, 0x0355, 0xF0 }, - { IMX_8BIT, 0x0356, 0x02 }, - { IMX_8BIT, 0x0357, 0x68 }, - - { IMX_8BIT, 0x301D, 0x30 }, - - { IMX_8BIT, 0x3310, 0x02 }, - { IMX_8BIT, 0x3311, 0xF0 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x68 }, - - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 1424x1168 */ -static struct imx_reg const imx134_1424_1168_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, /* binning */ - { IMX_8BIT, 0x0391, 0x11 }, /* no binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x22 }, /* 34/16=2.125 */ - { IMX_8BIT, 0x4082, 0x00 }, /* ?? */ - { IMX_8BIT, 0x4083, 0x00 }, /* ?? */ - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:136 */ - { IMX_8BIT, 0x0345, 0x80 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:0 */ - { IMX_8BIT, 0x0347, 0x00 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3145+134-1 */ - { IMX_8BIT, 0x0349, 0x51 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2463 */ - { IMX_8BIT, 0x034B, 0xB1 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x05 }, /* x_output_size[15:8]: 1424*/ - { IMX_8BIT, 0x034D, 0x90 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x04 }, /* y_output_size[15:8]:1168 */ - { IMX_8BIT, 0x034F, 0x90 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - - { IMX_8BIT, 0x0354, 0x0B }, - { IMX_8BIT, 0x0355, 0xD2 }, - { IMX_8BIT, 0x0356, 0x09 }, - { IMX_8BIT, 0x0357, 0xB2 }, - - { IMX_8BIT, 0x301D, 0x30 }, - - { IMX_8BIT, 0x3310, 0x05 }, - { IMX_8BIT, 0x3311, 0x90 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0x90 }, - - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - { IMX_8BIT, 0x4084, 0x05 }, - { IMX_8BIT, 0x4085, 0x90 }, - { IMX_8BIT, 0x4086, 0x04 }, - { IMX_8BIT, 0x4087, 0x90 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/4 binning, 16/35 down scaling, 30fps, dvs */ -static struct imx_reg const imx134_240_196_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /*4x4 binning */ - { IMX_8BIT, 0x0391, 0x44 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x23 }, /* down scaling = 16/35 */ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x02 }, /* x_addr_start[15:8]:590 */ - { IMX_8BIT, 0x0345, 0x4E }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:366 */ - { IMX_8BIT, 0x0347, 0x6E }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0A }, /* x_addr_end[15:8]:2104+590-1 */ - { IMX_8BIT, 0x0349, 0x85 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:1720+366-1 */ - { IMX_8BIT, 0x034B, 0x25 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x00 }, /* x_output_size[15:8]: 240*/ - { IMX_8BIT, 0x034D, 0xF0 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x00 }, /* y_output_size[15:8]:196 */ - { IMX_8BIT, 0x034F, 0xC4 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x02 }, /* crop_x: 526 */ - { IMX_8BIT, 0x0355, 0x0E }, - { IMX_8BIT, 0x0356, 0x01 }, /* crop_y: 430 */ - { IMX_8BIT, 0x0357, 0xAE }, - - { IMX_8BIT, 0x301D, 0x30 }, - - { IMX_8BIT, 0x3310, 0x00 }, - { IMX_8BIT, 0x3311, 0xF0 }, - { IMX_8BIT, 0x3312, 0x00 }, - { IMX_8BIT, 0x3313, 0xC4 }, - - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x4C }, - - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0xF0 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0xC4 }, - - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x0A }, - { IMX_8BIT, 0x0203, 0x88 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane, 1/2 binning, 16/38 downscaling, 30fps, dvs */ -static struct imx_reg const imx134_448_366_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* 2x2 binning */ - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x26 }, /* down scaling = 16/38 */ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x02 }, /* x_addr_start[15:8]:590 */ - { IMX_8BIT, 0x0345, 0x4E }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:366 */ - { IMX_8BIT, 0x0347, 0x6E }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0A }, /* x_addr_end[15:8]:2128+590-1 */ - { IMX_8BIT, 0x0349, 0x9D }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:1740+366-1 */ - { IMX_8BIT, 0x034B, 0x39 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x01 }, /* x_output_size[15:8]: 448*/ - { IMX_8BIT, 0x034D, 0xC0 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x01 }, /* y_output_size[15:8]:366 */ - { IMX_8BIT, 0x034F, 0x6E }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x04 }, /* crop_x: 1064 */ - { IMX_8BIT, 0x0355, 0x28 }, - { IMX_8BIT, 0x0356, 0x03 }, /* crop_y: 870 */ - { IMX_8BIT, 0x0357, 0x66 }, - - { IMX_8BIT, 0x301D, 0x30 }, - - { IMX_8BIT, 0x3310, 0x01 }, - { IMX_8BIT, 0x3311, 0xC0 }, - { IMX_8BIT, 0x3312, 0x01 }, - { IMX_8BIT, 0x3313, 0x6E }, - - { IMX_8BIT, 0x331C, 0x02 }, - { IMX_8BIT, 0x331D, 0xD0 }, - - { IMX_8BIT, 0x4084, 0x01 }, - { IMX_8BIT, 0x4085, 0xC0 }, - { IMX_8BIT, 0x4086, 0x01 }, - { IMX_8BIT, 0x4087, 0x6E }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 2336x1312, 30fps, for 1080p dvs, vendor provide */ -static struct imx_reg const imx134_2336_1312_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, /* disable binning */ - { IMX_8BIT, 0x0391, 0x11 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x16 }, /* down scaling = 16/22 = 8/11 */ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:34 */ - { IMX_8BIT, 0x0345, 0x22 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:332 */ - { IMX_8BIT, 0x0347, 0x4C }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3245 */ - { IMX_8BIT, 0x0349, 0xAD }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2135 */ - { IMX_8BIT, 0x034B, 0x57 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x09 }, /* x_output_size[15:8]:2336 */ - { IMX_8BIT, 0x034D, 0x20 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x05 }, /* y_output_size[15:8]:1312 */ - { IMX_8BIT, 0x034F, 0x20 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x0C }, - { IMX_8BIT, 0x0355, 0x8C }, - { IMX_8BIT, 0x0356, 0x07 }, - { IMX_8BIT, 0x0357, 0x0C }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x09 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x05 }, - { IMX_8BIT, 0x3313, 0x20 }, - { IMX_8BIT, 0x331C, 0x03 }, - { IMX_8BIT, 0x331D, 0xEB }, - { IMX_8BIT, 0x4084, 0x09 }, - { IMX_8BIT, 0x4085, 0x20 }, - { IMX_8BIT, 0x4086, 0x05 }, - { IMX_8BIT, 0x4087, 0x20 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 1920x1080, 30fps, for 720p still capture */ -static struct imx_reg const imx134_1936_1096_30fps_v1[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, /* disable binning */ - { IMX_8BIT, 0x0391, 0x11 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x1A }, /* downscaling 16/26*/ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:64 */ - { IMX_8BIT, 0x0345, 0x40 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:340 */ - { IMX_8BIT, 0x0347, 0x54 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3209 */ - { IMX_8BIT, 0x0349, 0x89 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2121 */ - { IMX_8BIT, 0x034B, 0x49 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x07 }, /* x_output_size[15:8]:1936 */ - { IMX_8BIT, 0x034D, 0x90 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x04 }, /* y_output_size[15:8]:1096 */ - { IMX_8BIT, 0x034F, 0x48 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x0C }, /* crop x:3146 */ - { IMX_8BIT, 0x0355, 0x4A }, - { IMX_8BIT, 0x0356, 0x06 }, /* xrop y:1782 */ - { IMX_8BIT, 0x0357, 0xF6 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x07 }, - { IMX_8BIT, 0x3311, 0x80 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0x38 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x1E }, - { IMX_8BIT, 0x4084, 0x07 }, - { IMX_8BIT, 0x4085, 0x80 }, - { IMX_8BIT, 0x4086, 0x04 }, - { IMX_8BIT, 0x4087, 0x38 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 1920x1080, 30fps, for 720p still capture, vendor provide */ -static struct imx_reg const imx134_1936_1096_30fps_v2[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, /* disable binning */ - { IMX_8BIT, 0x0391, 0x11 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x1B }, /* downscaling 16/27*/ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* Optionnal Function setting */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:64 */ - { IMX_8BIT, 0x0345, 0x06 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:340 */ - { IMX_8BIT, 0x0347, 0x34 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3209 */ - { IMX_8BIT, 0x0349, 0xC9 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2121 */ - { IMX_8BIT, 0x034B, 0x6F }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x07 }, /* x_output_size[15:8]:1936 */ - { IMX_8BIT, 0x034D, 0x90 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x04 }, /* y_output_size[15:8]:1096 */ - { IMX_8BIT, 0x034F, 0x48 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x0C }, /* crop x:3146 */ - { IMX_8BIT, 0x0355, 0xC4 }, - { IMX_8BIT, 0x0356, 0x07 }, /* xrop y:1782 */ - { IMX_8BIT, 0x0357, 0x3A }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x07 }, /* decide by mode and output size */ - { IMX_8BIT, 0x3311, 0x90 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0x48 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x1E }, - { IMX_8BIT, 0x4084, 0x07 }, - { IMX_8BIT, 0x4085, 0x90 }, - { IMX_8BIT, 0x4086, 0x04 }, - { IMX_8BIT, 0x4087, 0x48 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Setting */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 1296x736, 30fps, for 720p still capture, vendor provide */ -static struct imx_reg const imx134_1296_736_30fps_v2[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning */ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x14 }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:40 */ - { IMX_8BIT, 0x0345, 0x14 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:332 */ - { IMX_8BIT, 0x0347, 0x38 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3239 */ - { IMX_8BIT, 0x0349, 0xBB }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2131 */ - { IMX_8BIT, 0x034B, 0x67 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x05 }, /* x_output_size[15:8]:1280 */ - { IMX_8BIT, 0x034D, 0x10 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:720 */ - { IMX_8BIT, 0x034F, 0xE0 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x54 }, - { IMX_8BIT, 0x0356, 0x03 }, - { IMX_8BIT, 0x0357, 0x98 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x05 }, - { IMX_8BIT, 0x3311, 0x10 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0xE0 }, - { IMX_8BIT, 0x331C, 0x01 }, - { IMX_8BIT, 0x331D, 0x10 }, - { IMX_8BIT, 0x4084, 0x05 }, - { IMX_8BIT, 0x4085, 0x10 }, - { IMX_8BIT, 0x4086, 0x02 }, - { IMX_8BIT, 0x4087, 0xE0 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -/* 4 lane 1280x720, 30fps, for 720p dvs, vendor provide */ -static struct imx_reg const imx134_1568_880_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xA9 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning*/ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, /* down scaling 16/16 = 1 */ - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:72 */ - { IMX_8BIT, 0x0345, 0x48 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:356 */ - { IMX_8BIT, 0x0347, 0x64 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3207 */ - { IMX_8BIT, 0x0349, 0x87 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2115 */ - { IMX_8BIT, 0x034B, 0x43 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x06 }, /* x_output_size[15:8]:1568 */ - { IMX_8BIT, 0x034D, 0x20 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x03 }, /* y_output_size[15:8]:880 */ - { IMX_8BIT, 0x034F, 0x70 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x20 }, - { IMX_8BIT, 0x0356, 0x03 }, - { IMX_8BIT, 0x0357, 0x70 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x03 }, - { IMX_8BIT, 0x3313, 0x70 }, - { IMX_8BIT, 0x331C, 0x03 }, - { IMX_8BIT, 0x331D, 0xF2 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xAF }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -static struct imx_reg const imx134_1568_876_60fps_0625[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0x8F }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning*/ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, /* down scaling 16/16 = 1 */ - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:72 */ - { IMX_8BIT, 0x0345, 0x48 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:356 */ - { IMX_8BIT, 0x0347, 0x64 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3207 */ - { IMX_8BIT, 0x0349, 0x87 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2115 */ - { IMX_8BIT, 0x034B, 0x3B }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x06 }, /* x_output_size[15:8]:1568 */ - { IMX_8BIT, 0x034D, 0x20 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x03 }, /* y_output_size[15:8]:880 */ - { IMX_8BIT, 0x034F, 0x6C }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x20 }, - { IMX_8BIT, 0x0356, 0x03 }, - { IMX_8BIT, 0x0357, 0x6C }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x03 }, - { IMX_8BIT, 0x3313, 0x6C }, - { IMX_8BIT, 0x331C, 0x03 }, - { IMX_8BIT, 0x331D, 0xF2 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x6F }, - { IMX_8BIT, 0x0831, 0x27 }, - { IMX_8BIT, 0x0832, 0x4F }, - { IMX_8BIT, 0x0833, 0x2F }, - { IMX_8BIT, 0x0834, 0x2F }, - { IMX_8BIT, 0x0835, 0x2F }, - { IMX_8BIT, 0x0836, 0x9F }, - { IMX_8BIT, 0x0837, 0x37 }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - - -/* 4 lane for 720p dvs, vendor provide */ -static struct imx_reg const imx134_1568_880[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xC8 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning*/ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, /* down scaling 16/16 = 1 */ - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:72 */ - { IMX_8BIT, 0x0345, 0x48 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x01 }, /* y_addr_start[15:8]:356 */ - { IMX_8BIT, 0x0347, 0x64 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3207 */ - { IMX_8BIT, 0x0349, 0x87 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x08 }, /* y_addr_end[15:8]:2115 */ - { IMX_8BIT, 0x034B, 0x43 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x06 }, /* x_output_size[15:8]:1568 */ - { IMX_8BIT, 0x034D, 0x20 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x03 }, /* y_output_size[15:8]:880 */ - { IMX_8BIT, 0x034F, 0x70 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x20 }, - { IMX_8BIT, 0x0356, 0x03 }, - { IMX_8BIT, 0x0357, 0x70 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x03 }, - { IMX_8BIT, 0x3313, 0x70 }, - { IMX_8BIT, 0x331C, 0x03 }, - { IMX_8BIT, 0x331D, 0xF2 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x5F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x37 }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xBF }, - { IMX_8BIT, 0x0837, 0x3F }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x09 }, - { IMX_8BIT, 0x0203, 0xD2 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; -/* 4 lane for 480p dvs, default 60fps, vendor provide */ -static struct imx_reg const imx134_880_592[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xC8 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, /* binning*/ - { IMX_8BIT, 0x0391, 0x22 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x1D }, /* downscaling ratio = 16/29 */ - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* x_addr_start[15:8]:44 */ - { IMX_8BIT, 0x0345, 0x2C }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x00 }, /* y_addr_start[15:8]:160 */ - { IMX_8BIT, 0x0347, 0xA0 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0C }, /* x_addr_end[15:8]:3235 */ - { IMX_8BIT, 0x0349, 0xA3 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x09 }, /* y_addr_end[15:8]:2307 */ - { IMX_8BIT, 0x034B, 0x03 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x03 }, /* x_output_size[15:8]:880 */ - { IMX_8BIT, 0x034D, 0x70 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x02 }, /* y_output_size[15:8]:592 */ - { IMX_8BIT, 0x034F, 0x50 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x06 }, - { IMX_8BIT, 0x0355, 0x3C }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0x32 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x03 }, - { IMX_8BIT, 0x3311, 0x70 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x50 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x4C }, - { IMX_8BIT, 0x4084, 0x03 }, - { IMX_8BIT, 0x4085, 0x70 }, - { IMX_8BIT, 0x4086, 0x02 }, - { IMX_8BIT, 0x4087, 0x50 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x5F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x37 }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xBF }, - { IMX_8BIT, 0x0837, 0x3F }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x05 }, - { IMX_8BIT, 0x0203, 0x42 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; -static struct imx_reg const imx134_2336_1308_60fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - /* mode set clear */ - { IMX_8BIT, 0x3A43, 0x01 }, - /* Clock Setting */ - { IMX_8BIT, 0x011E, 0x13 }, - { IMX_8BIT, 0x011F, 0x33 }, - { IMX_8BIT, 0x0301, 0x05 }, - { IMX_8BIT, 0x0303, 0x01 }, - { IMX_8BIT, 0x0305, 0x0C }, - { IMX_8BIT, 0x0309, 0x05 }, - { IMX_8BIT, 0x030B, 0x01 }, - { IMX_8BIT, 0x030C, 0x01 }, - { IMX_8BIT, 0x030D, 0xC8 }, - { IMX_8BIT, 0x030E, 0x01 }, - { IMX_8BIT, 0x3A06, 0x11 }, - - /* Mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, /* binning*/ - { IMX_8BIT, 0x0391, 0x11 }, /* 2x2 binning */ - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, /* H/V resize */ - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, /* down scaling 16/16 = 1 */ - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - - /* OptionnalFunction settig */ - { IMX_8BIT, 0x0700, 0x00 }, - { IMX_8BIT, 0x3A63, 0x00 }, - { IMX_8BIT, 0x4100, 0xF8 }, - { IMX_8BIT, 0x4203, 0xFF }, - { IMX_8BIT, 0x4344, 0x00 }, - { IMX_8BIT, 0x441C, 0x01 }, - - /* Size setting */ - { IMX_8BIT, 0x0344, 0x01 }, /* x_addr_start[15:8]:72 */ - { IMX_8BIT, 0x0345, 0xD8 }, /* x_addr_start[7:0] */ - { IMX_8BIT, 0x0346, 0x02 }, /* y_addr_start[15:8]:356 */ - { IMX_8BIT, 0x0347, 0x44 }, /* y_addr_start[7:0] */ - { IMX_8BIT, 0x0348, 0x0A }, /* x_addr_end[15:8]:3207 */ - { IMX_8BIT, 0x0349, 0xF7 }, /* x_addr_end[7:0] */ - { IMX_8BIT, 0x034A, 0x07 }, /* y_addr_end[15:8]:2107 */ - { IMX_8BIT, 0x034B, 0x5F+4 }, /* y_addr_end[7:0] */ - { IMX_8BIT, 0x034C, 0x09 }, /* x_output_size[15:8]:1568 */ - { IMX_8BIT, 0x034D, 0x20 }, /* x_output_size[7:0] */ - { IMX_8BIT, 0x034E, 0x05 }, /* y_output_size[15:8]:876 */ - { IMX_8BIT, 0x034F, 0x1C+4 }, /* y_output_size[7:0] */ - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x09 }, - { IMX_8BIT, 0x0355, 0x20 }, - { IMX_8BIT, 0x0356, 0x05 }, - { IMX_8BIT, 0x0357, 0x1C+4 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x09 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x05 }, - { IMX_8BIT, 0x3313, 0x1C+4 }, - { IMX_8BIT, 0x331C, 0x03 }, - { IMX_8BIT, 0x331D, 0xE8 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - - /* Global Timing Setting */ - { IMX_8BIT, 0x0830, 0x77 }, - { IMX_8BIT, 0x0831, 0x2F }, - { IMX_8BIT, 0x0832, 0x5F }, - { IMX_8BIT, 0x0833, 0x37 }, - { IMX_8BIT, 0x0834, 0x37 }, - { IMX_8BIT, 0x0835, 0x37 }, - { IMX_8BIT, 0x0836, 0xBF }, - { IMX_8BIT, 0x0837, 0x3F }, - { IMX_8BIT, 0x0839, 0x1F }, - { IMX_8BIT, 0x083A, 0x17 }, - { IMX_8BIT, 0x083B, 0x02 }, - - /* Integration Time Settin */ - { IMX_8BIT, 0x0202, 0x05 }, - { IMX_8BIT, 0x0203, 0x42 }, - - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00 }, - { IMX_8BIT, 0x0231, 0x00 }, - { IMX_8BIT, 0x0233, 0x00 }, - { IMX_8BIT, 0x0234, 0x00 }, - { IMX_8BIT, 0x0235, 0x40 }, - { IMX_8BIT, 0x0238, 0x00 }, - { IMX_8BIT, 0x0239, 0x04 }, - { IMX_8BIT, 0x023B, 0x00 }, - { IMX_8BIT, 0x023C, 0x01 }, - { IMX_8BIT, 0x33B0, 0x04 }, - { IMX_8BIT, 0x33B1, 0x00 }, - { IMX_8BIT, 0x33B3, 0x00 }, - { IMX_8BIT, 0x33B4, 0x01 }, - { IMX_8BIT, 0x3800, 0x00 }, - { IMX_TOK_TERM, 0, 0 } -}; - -struct imx_resolution imx134_res_preview[] = { - { - .desc = "imx134_CIF_30fps", - .regs = imx134_720_592_30fps, - .width = 720, - .height = 592, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - }, - { - .desc = "imx134_820_552_30fps_preview", - .regs = imx134_820_552_30fps, - .width = 820, - .height = 552, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - }, - { - .desc = "imx134_820_616_preview_30fps", - .regs = imx134_820_616_30fps, - .width = 820, - .height = 616, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - }, - { - .desc = "imx134_1080p_preview_30fps", - .regs = imx134_1936_1096_30fps_v2, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, - { - .desc = "imx134_1640_1232_preview_30fps", - .regs = imx134_1640_1232_30fps, - .width = 1640, - .height = 1232, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_8M_preview_30fps", - .regs = imx134_8M_30fps, - .width = 3280, - .height = 2464, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, -}; - -struct imx_resolution imx134_res_still[] = { - { - .desc = "imx134_CIF_30fps", - .regs = imx134_1424_1168_30fps, - .width = 1424, - .height = 1168, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_VGA_still_30fps", - .regs = imx134_1640_1232_30fps, - .width = 1640, - .height = 1232, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_1080p_still_30fps", - .regs = imx134_1936_1096_30fps_v2, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, - { - .desc = "imx134_1640_1232_still_30fps", - .regs = imx134_1640_1232_30fps, - .width = 1640, - .height = 1232, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_8M_still_30fps", - .regs = imx134_8M_30fps, - .width = 3280, - .height = 2464, - .fps_options = { - { - /* WORKAROUND for FW performance limitation */ - .fps = 8, - .pixels_per_line = 6400, - .lines_per_frame = 5312, - }, - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, -}; - -struct imx_resolution imx134_res_video[] = { - { - .desc = "imx134_QCIF_DVS_30fps", - .regs = imx134_240_196_30fps, - .width = 240, - .height = 196, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - }, - { - .desc = "imx134_CIF_DVS_30fps", - .regs = imx134_448_366_30fps, - .width = 448, - .height = 366, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_VGA_30fps", - .regs = imx134_820_616_30fps, - .width = 820, - .height = 616, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - }, - { - .desc = "imx134_480p", - .regs = imx134_880_592, - .width = 880, - .height = 592, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2700, - }, - { - .fps = 60, - .pixels_per_line = 3600, - .lines_per_frame = 1350, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_1568_880", - .regs = imx134_1568_880, - .width = 1568, - .height = 880, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2700, - }, - { - .fps = 60, - .pixels_per_line = 3600, - .lines_per_frame = 1350, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - }, - { - .desc = "imx134_1080p_dvs_30fps", - .regs = imx134_2336_1312_30fps, - .width = 2336, - .height = 1312, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, - { - .desc = "imx134_1080p_dvs_60fps", - .regs = imx134_2336_1308_60fps, - .width = 2336, - .height = 1312, - .fps_options = { - { - .fps = 60, - .pixels_per_line = 3600, - .lines_per_frame = 1350, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, - { - /*This setting only be used for SDV mode*/ - .desc = "imx134_8M_sdv_30fps", - .regs = imx134_8M_30fps, - .width = 3280, - .height = 2464, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 3600, - .lines_per_frame = 2518, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - }, -}; - -#endif - diff --git a/drivers/staging/media/atomisp/i2c/imx/imx135.h b/drivers/staging/media/atomisp/i2c/imx/imx135.h deleted file mode 100644 index 58b43af909f2..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx135.h +++ /dev/null @@ -1,3374 +0,0 @@ -/* - * Support for Sony IMX camera sensor. - * - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __IMX135_H__ -#define __IMX135_H__ - -#include "common.h" - -#define IMX_SC_CMMN_CHIP_ID_H 0x0016 -#define IMX_SC_CMMN_CHIP_ID_L 0x0017 - -/* - * focal length bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define IMX_FOCAL_LENGTH_DEFAULT 0x1710064 - -/* - * current f-number bits definition: - * bits 31-16: numerator, bits 15-0: denominator - */ -#define IMX_F_NUMBER_DEFAULT 0x16000a - -/* - * f-number range bits definition: - * bits 31-24: max f-number numerator - * bits 23-16: max f-number denominator - * bits 15-8: min f-number numerator - * bits 7-0: min f-number denominator - */ -#define IMX_F_NUMBER_RANGE 0x160a160a - -#define GROUPED_PARAMETER_HOLD_ENABLE {IMX_8BIT, 0x0104, 0x1} -#define GROUPED_PARAMETER_HOLD_DISABLE {IMX_8BIT, 0x0104, 0x0} - -#define IMX135_EMBEDDED_DATA_LINE_NUM 2 -#define IMX135_OUTPUT_DATA_FORMAT_REG 0x0112 -#define IMX135_OUTPUT_FORMAT_RAW10 0x0a0a -/* - * We use three different MIPI rates for our modes based on the resolution and - * FPS requirements. So we have three PLL configurationa and these are based - * on the EMC friendly MIPI values. - * - * Maximum clock: Pix clock @ 360.96MHz MIPI @ 451.2MHz 902.4mbps - * Reduced clock: Pix clock @ 273.00MHz MIPI @ 342.0MHz 684.0mbps - * Binning modes: Pix clock @ 335.36MHz MIPI @ 209.6MHz 419.2mbps - * Global Timing registers are based on the data rates and these are part of - * the below clock definitions. - */ -/* MIPI 499.2MHz 998.4mbps PIXCLK: 399.36MHz */ -#define PLL_SETTINGS_FOR_MIPI_499_2MHZ_SALTBAY \ - {IMX_8BIT, 0x011e, 0x13}, \ - {IMX_8BIT, 0x011f, 0x33}, \ - {IMX_8BIT, 0x0301, 0x05}, \ - {IMX_8BIT, 0x0303, 0x01}, \ - {IMX_8BIT, 0x0305, 0x0c}, \ - {IMX_8BIT, 0x0309, 0x05}, \ - {IMX_8BIT, 0x030b, 0x01}, \ - {IMX_8BIT, 0x030c, 0x02}, \ - {IMX_8BIT, 0x030d, 0x70}, \ - {IMX_8BIT, 0x030e, 0x01}, \ - {IMX_8BIT, 0x3a06, 0x11}, \ - {IMX_8BIT, 0x0830, 0x7f}, \ - {IMX_8BIT, 0x0831, 0x37}, \ - {IMX_8BIT, 0x0832, 0x67}, \ - {IMX_8BIT, 0x0833, 0x3f}, \ - {IMX_8BIT, 0x0834, 0x3f}, \ - {IMX_8BIT, 0x0835, 0x47}, \ - {IMX_8BIT, 0x0836, 0xdf}, \ - {IMX_8BIT, 0x0837, 0x47}, \ - {IMX_8BIT, 0x0839, 0x1f}, \ - {IMX_8BIT, 0x083a, 0x17}, \ - {IMX_8BIT, 0x083b, 0x02} - -/* MIPI 451.2MHz 902.4mbps PIXCLK: 360.96MHz */ -#define PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY \ - {IMX_8BIT, 0x011e, 0x13}, \ - {IMX_8BIT, 0x011f, 0x33}, \ - {IMX_8BIT, 0x0301, 0x05}, \ - {IMX_8BIT, 0x0303, 0x01}, \ - {IMX_8BIT, 0x0305, 0x0c}, \ - {IMX_8BIT, 0x0309, 0x05}, \ - {IMX_8BIT, 0x030b, 0x01}, \ - {IMX_8BIT, 0x030c, 0x02}, \ - {IMX_8BIT, 0x030d, 0x34}, \ - {IMX_8BIT, 0x030e, 0x01}, \ - {IMX_8BIT, 0x3a06, 0x11}, \ - {IMX_8BIT, 0x0830, 0x7f}, \ - {IMX_8BIT, 0x0831, 0x37}, \ - {IMX_8BIT, 0x0832, 0x67}, \ - {IMX_8BIT, 0x0833, 0x3f}, \ - {IMX_8BIT, 0x0834, 0x3f}, \ - {IMX_8BIT, 0x0835, 0x47}, \ - {IMX_8BIT, 0x0836, 0xdf}, \ - {IMX_8BIT, 0x0837, 0x47}, \ - {IMX_8BIT, 0x0839, 0x1f}, \ - {IMX_8BIT, 0x083a, 0x17}, \ - {IMX_8BIT, 0x083b, 0x02} - -/* MIPI 209.6MHz, 419.2mbps PIXCLK: 335.36 MHz */ -#define PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY \ - {IMX_8BIT, 0x011e, 0x13}, \ - {IMX_8BIT, 0x011f, 0x33}, \ - {IMX_8BIT, 0x0301, 0x05}, \ - {IMX_8BIT, 0x0303, 0x01}, \ - {IMX_8BIT, 0x0305, 0x06}, \ - {IMX_8BIT, 0x0309, 0x05}, \ - {IMX_8BIT, 0x030b, 0x02}, \ - {IMX_8BIT, 0x030c, 0x01}, \ - {IMX_8BIT, 0x030d, 0x06}, \ - {IMX_8BIT, 0x030e, 0x01}, \ - {IMX_8BIT, 0x3a06, 0x12}, \ - {IMX_8BIT, 0x0830, 0x5f}, \ - {IMX_8BIT, 0x0831, 0x1f}, \ - {IMX_8BIT, 0x0832, 0x3f}, \ - {IMX_8BIT, 0x0833, 0x1f}, \ - {IMX_8BIT, 0x0834, 0x1f}, \ - {IMX_8BIT, 0x0835, 0x17}, \ - {IMX_8BIT, 0x0836, 0x67}, \ - {IMX_8BIT, 0x0837, 0x27}, \ - {IMX_8BIT, 0x0839, 0x1f}, \ - {IMX_8BIT, 0x083a, 0x17}, \ - {IMX_8BIT, 0x083b, 0x02} - -/* MIPI 342MHz 684mbps PIXCLK: 273.6MHz */ -#define PLL_SETTINGS_FOR_MIPI_342MHZ_SALTBAY \ - {IMX_8BIT, 0x011e, 0x13}, \ - {IMX_8BIT, 0x011f, 0x33}, \ - {IMX_8BIT, 0x0301, 0x05}, \ - {IMX_8BIT, 0x0303, 0x01}, \ - {IMX_8BIT, 0x0305, 0x08}, \ - {IMX_8BIT, 0x0309, 0x05}, \ - {IMX_8BIT, 0x030b, 0x01}, \ - {IMX_8BIT, 0x030c, 0x01}, \ - {IMX_8BIT, 0x030d, 0x1d}, \ - {IMX_8BIT, 0x030e, 0x01}, \ - {IMX_8BIT, 0x3a06, 0x11}, \ - {IMX_8BIT, 0x0830, 0x77}, \ - {IMX_8BIT, 0x0831, 0x2f}, \ - {IMX_8BIT, 0x0832, 0x4f}, \ - {IMX_8BIT, 0x0833, 0x37}, \ - {IMX_8BIT, 0x0834, 0x2f}, \ - {IMX_8BIT, 0x0835, 0x37}, \ - {IMX_8BIT, 0x0836, 0xa7}, \ - {IMX_8BIT, 0x0837, 0x37}, \ - {IMX_8BIT, 0x0839, 0x1f}, \ - {IMX_8BIT, 0x083a, 0x17}, \ - {IMX_8BIT, 0x083b, 0x02} - -/* Basic settings: Applied only once after the sensor power up */ -static struct imx_reg const imx135_init_settings[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - { IMX_8BIT, 0x0220, 0x01}, - { IMX_8BIT, 0x3008, 0xB0}, - { IMX_8BIT, 0x320A, 0x01}, - { IMX_8BIT, 0x320D, 0x10}, - { IMX_8BIT, 0x3216, 0x2E}, - { IMX_8BIT, 0x3230, 0x0A}, - { IMX_8BIT, 0x3228, 0x05}, - { IMX_8BIT, 0x3229, 0x02}, - { IMX_8BIT, 0x322C, 0x02}, - { IMX_8BIT, 0x3302, 0x10}, - { IMX_8BIT, 0x3390, 0x45}, - { IMX_8BIT, 0x3409, 0x0C}, - { IMX_8BIT, 0x340B, 0xF5}, - { IMX_8BIT, 0x340C, 0x2D}, - { IMX_8BIT, 0x3412, 0x41}, - { IMX_8BIT, 0x3413, 0xAD}, - { IMX_8BIT, 0x3414, 0x1E}, - { IMX_8BIT, 0x3427, 0x04}, - { IMX_8BIT, 0x3480, 0x1E}, - { IMX_8BIT, 0x3484, 0x1E}, - { IMX_8BIT, 0x3488, 0x1E}, - { IMX_8BIT, 0x348C, 0x1E}, - { IMX_8BIT, 0x3490, 0x1E}, - { IMX_8BIT, 0x3494, 0x1E}, - { IMX_8BIT, 0x349C, 0x38}, - { IMX_8BIT, 0x34A3, 0x38}, - { IMX_8BIT, 0x3511, 0x8F}, - { IMX_8BIT, 0x3518, 0x00}, - { IMX_8BIT, 0x3519, 0x94}, - { IMX_8BIT, 0x3833, 0x20}, - { IMX_8BIT, 0x3893, 0x01}, - { IMX_8BIT, 0x38C2, 0x08}, - { IMX_8BIT, 0x38C3, 0x08}, - { IMX_8BIT, 0x3C09, 0x01}, - { IMX_8BIT, 0x4000, 0x0E}, - { IMX_8BIT, 0x4300, 0x00}, - { IMX_8BIT, 0x4316, 0x12}, - { IMX_8BIT, 0x4317, 0x22}, - { IMX_8BIT, 0x4318, 0x00}, - { IMX_8BIT, 0x4319, 0x00}, - { IMX_8BIT, 0x431A, 0x00}, - { IMX_8BIT, 0x4324, 0x03}, - { IMX_8BIT, 0x4325, 0x20}, - { IMX_8BIT, 0x4326, 0x03}, - { IMX_8BIT, 0x4327, 0x84}, - { IMX_8BIT, 0x4328, 0x03}, - { IMX_8BIT, 0x4329, 0x20}, - { IMX_8BIT, 0x432A, 0x03}, - { IMX_8BIT, 0x432B, 0x84}, - { IMX_8BIT, 0x432C, 0x01}, - { IMX_8BIT, 0x4401, 0x3F}, - { IMX_8BIT, 0x4402, 0xFF}, - { IMX_8BIT, 0x4412, 0x3F}, - { IMX_8BIT, 0x4413, 0xFF}, - { IMX_8BIT, 0x441D, 0x28}, - { IMX_8BIT, 0x4444, 0x00}, - { IMX_8BIT, 0x4445, 0x00}, - { IMX_8BIT, 0x4446, 0x3F}, - { IMX_8BIT, 0x4447, 0xFF}, - { IMX_8BIT, 0x4452, 0x00}, - { IMX_8BIT, 0x4453, 0xA0}, - { IMX_8BIT, 0x4454, 0x08}, - { IMX_8BIT, 0x4455, 0x00}, - { IMX_8BIT, 0x4458, 0x18}, - { IMX_8BIT, 0x4459, 0x18}, - { IMX_8BIT, 0x445A, 0x3F}, - { IMX_8BIT, 0x445B, 0x3A}, - { IMX_8BIT, 0x4462, 0x00}, - { IMX_8BIT, 0x4463, 0x00}, - { IMX_8BIT, 0x4464, 0x00}, - { IMX_8BIT, 0x4465, 0x00}, - { IMX_8BIT, 0x446E, 0x01}, - { IMX_8BIT, 0x4500, 0x1F}, - { IMX_8BIT, 0x600a, 0x00}, - { IMX_8BIT, 0x380a, 0x00}, - { IMX_8BIT, 0x380b, 0x00}, - { IMX_8BIT, 0x4103, 0x00}, - { IMX_8BIT, 0x4243, 0x9a}, - { IMX_8BIT, 0x4330, 0x01}, - { IMX_8BIT, 0x4331, 0x90}, - { IMX_8BIT, 0x4332, 0x02}, - { IMX_8BIT, 0x4333, 0x58}, - { IMX_8BIT, 0x4334, 0x03}, - { IMX_8BIT, 0x4335, 0x20}, - { IMX_8BIT, 0x4336, 0x03}, - { IMX_8BIT, 0x4337, 0x84}, - { IMX_8BIT, 0x433C, 0x01}, - { IMX_8BIT, 0x4340, 0x02}, - { IMX_8BIT, 0x4341, 0x58}, - { IMX_8BIT, 0x4342, 0x03}, - { IMX_8BIT, 0x4343, 0x52}, - { IMX_8BIT, 0x4364, 0x0b}, - { IMX_8BIT, 0x4368, 0x00}, - { IMX_8BIT, 0x4369, 0x0f}, - { IMX_8BIT, 0x436a, 0x03}, - { IMX_8BIT, 0x436b, 0xa8}, - { IMX_8BIT, 0x436c, 0x00}, - { IMX_8BIT, 0x436d, 0x00}, - { IMX_8BIT, 0x436e, 0x00}, - { IMX_8BIT, 0x436f, 0x06}, - { IMX_8BIT, 0x4281, 0x21}, - { IMX_8BIT, 0x4282, 0x18}, - { IMX_8BIT, 0x4283, 0x04}, - { IMX_8BIT, 0x4284, 0x08}, - { IMX_8BIT, 0x4287, 0x7f}, - { IMX_8BIT, 0x4288, 0x08}, - { IMX_8BIT, 0x428c, 0x08}, - { IMX_8BIT, 0x4297, 0x00}, - { IMX_8BIT, 0x4299, 0x7E}, - { IMX_8BIT, 0x42A4, 0xFB}, - { IMX_8BIT, 0x42A5, 0x7E}, - { IMX_8BIT, 0x42A6, 0xDF}, - { IMX_8BIT, 0x42A7, 0xB7}, - { IMX_8BIT, 0x42AF, 0x03}, - { IMX_8BIT, 0x4207, 0x03}, - { IMX_8BIT, 0x4218, 0x00}, - { IMX_8BIT, 0x421B, 0x20}, - { IMX_8BIT, 0x421F, 0x04}, - { IMX_8BIT, 0x4222, 0x02}, - { IMX_8BIT, 0x4223, 0x22}, - { IMX_8BIT, 0x422E, 0x54}, - { IMX_8BIT, 0x422F, 0xFB}, - { IMX_8BIT, 0x4230, 0xFF}, - { IMX_8BIT, 0x4231, 0xFE}, - { IMX_8BIT, 0x4232, 0xFF}, - { IMX_8BIT, 0x4235, 0x58}, - { IMX_8BIT, 0x4236, 0xF7}, - { IMX_8BIT, 0x4237, 0xFD}, - { IMX_8BIT, 0x4239, 0x4E}, - { IMX_8BIT, 0x423A, 0xFC}, - { IMX_8BIT, 0x423B, 0xFD}, - { IMX_8BIT, 0x4300, 0x00}, - { IMX_8BIT, 0x4316, 0x12}, - { IMX_8BIT, 0x4317, 0x22}, - { IMX_8BIT, 0x4318, 0x00}, - { IMX_8BIT, 0x4319, 0x00}, - { IMX_8BIT, 0x431A, 0x00}, - { IMX_8BIT, 0x4324, 0x03}, - { IMX_8BIT, 0x4325, 0x20}, - { IMX_8BIT, 0x4326, 0x03}, - { IMX_8BIT, 0x4327, 0x84}, - { IMX_8BIT, 0x4328, 0x03}, - { IMX_8BIT, 0x4329, 0x20}, - { IMX_8BIT, 0x432A, 0x03}, - { IMX_8BIT, 0x432B, 0x20}, - { IMX_8BIT, 0x432C, 0x01}, - { IMX_8BIT, 0x432D, 0x01}, - { IMX_8BIT, 0x4338, 0x02}, - { IMX_8BIT, 0x4339, 0x00}, - { IMX_8BIT, 0x433A, 0x00}, - { IMX_8BIT, 0x433B, 0x02}, - { IMX_8BIT, 0x435A, 0x03}, - { IMX_8BIT, 0x435B, 0x84}, - { IMX_8BIT, 0x435E, 0x01}, - { IMX_8BIT, 0x435F, 0xFF}, - { IMX_8BIT, 0x4360, 0x01}, - { IMX_8BIT, 0x4361, 0xF4}, - { IMX_8BIT, 0x4362, 0x03}, - { IMX_8BIT, 0x4363, 0x84}, - { IMX_8BIT, 0x437B, 0x01}, - { IMX_8BIT, 0x4400, 0x00}, /* STATS off ISP do not support STATS*/ - { IMX_8BIT, 0x4401, 0x3F}, - { IMX_8BIT, 0x4402, 0xFF}, - { IMX_8BIT, 0x4404, 0x13}, - { IMX_8BIT, 0x4405, 0x26}, - { IMX_8BIT, 0x4406, 0x07}, - { IMX_8BIT, 0x4408, 0x20}, - { IMX_8BIT, 0x4409, 0xE5}, - { IMX_8BIT, 0x440A, 0xFB}, - { IMX_8BIT, 0x440C, 0xF6}, - { IMX_8BIT, 0x440D, 0xEA}, - { IMX_8BIT, 0x440E, 0x20}, - { IMX_8BIT, 0x4410, 0x00}, - { IMX_8BIT, 0x4411, 0x00}, - { IMX_8BIT, 0x4412, 0x3F}, - { IMX_8BIT, 0x4413, 0xFF}, - { IMX_8BIT, 0x4414, 0x1F}, - { IMX_8BIT, 0x4415, 0xFF}, - { IMX_8BIT, 0x4416, 0x20}, - { IMX_8BIT, 0x4417, 0x00}, - { IMX_8BIT, 0x4418, 0x1F}, - { IMX_8BIT, 0x4419, 0xFF}, - { IMX_8BIT, 0x441A, 0x20}, - { IMX_8BIT, 0x441B, 0x00}, - { IMX_8BIT, 0x441D, 0x40}, - { IMX_8BIT, 0x441E, 0x1E}, - { IMX_8BIT, 0x441F, 0x38}, - { IMX_8BIT, 0x4420, 0x01}, - { IMX_8BIT, 0x4444, 0x00}, - { IMX_8BIT, 0x4445, 0x00}, - { IMX_8BIT, 0x4446, 0x1D}, - { IMX_8BIT, 0x4447, 0xF9}, - { IMX_8BIT, 0x4452, 0x00}, - { IMX_8BIT, 0x4453, 0xA0}, - { IMX_8BIT, 0x4454, 0x08}, - { IMX_8BIT, 0x4455, 0x00}, - { IMX_8BIT, 0x4456, 0x0F}, - { IMX_8BIT, 0x4457, 0xFF}, - { IMX_8BIT, 0x4458, 0x18}, - { IMX_8BIT, 0x4459, 0x18}, - { IMX_8BIT, 0x445A, 0x3F}, - { IMX_8BIT, 0x445B, 0x3A}, - { IMX_8BIT, 0x445C, 0x00}, - { IMX_8BIT, 0x445D, 0x28}, - { IMX_8BIT, 0x445E, 0x01}, - { IMX_8BIT, 0x445F, 0x90}, - { IMX_8BIT, 0x4460, 0x00}, - { IMX_8BIT, 0x4461, 0x60}, - { IMX_8BIT, 0x4462, 0x00}, - { IMX_8BIT, 0x4463, 0x00}, - { IMX_8BIT, 0x4464, 0x00}, - { IMX_8BIT, 0x4465, 0x00}, - { IMX_8BIT, 0x446C, 0x00}, - { IMX_8BIT, 0x446D, 0x00}, - { IMX_8BIT, 0x446E, 0x00}, - { IMX_8BIT, 0x452A, 0x02}, - { IMX_8BIT, 0x0712, 0x01}, - { IMX_8BIT, 0x0713, 0x00}, - { IMX_8BIT, 0x0714, 0x01}, - { IMX_8BIT, 0x0715, 0x00}, - { IMX_8BIT, 0x0716, 0x01}, - { IMX_8BIT, 0x0717, 0x00}, - { IMX_8BIT, 0x0718, 0x01}, - { IMX_8BIT, 0x0719, 0x00}, - { IMX_8BIT, 0x4500, 0x1F }, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - { IMX_8BIT, 0x0205, 0x00}, - { IMX_8BIT, 0x020E, 0x01}, - { IMX_8BIT, 0x020F, 0x00}, - { IMX_8BIT, 0x0210, 0x02}, - { IMX_8BIT, 0x0211, 0x00}, - { IMX_8BIT, 0x0212, 0x02}, - { IMX_8BIT, 0x0213, 0x00}, - { IMX_8BIT, 0x0214, 0x01}, - { IMX_8BIT, 0x0215, 0x00}, - /* HDR Setting */ - { IMX_8BIT, 0x0230, 0x00}, - { IMX_8BIT, 0x0231, 0x00}, - { IMX_8BIT, 0x0233, 0x00}, - { IMX_8BIT, 0x0234, 0x00}, - { IMX_8BIT, 0x0235, 0x40}, - { IMX_8BIT, 0x0238, 0x00}, - { IMX_8BIT, 0x0239, 0x04}, - { IMX_8BIT, 0x023B, 0x00}, - { IMX_8BIT, 0x023C, 0x01}, - { IMX_8BIT, 0x33B0, 0x04}, - { IMX_8BIT, 0x33B1, 0x00}, - { IMX_8BIT, 0x33B3, 0x00}, - { IMX_8BIT, 0x33B4, 0x01}, - { IMX_8BIT, 0x3800, 0x00}, - GROUPED_PARAMETER_HOLD_DISABLE, - { IMX_TOK_TERM, 0, 0} -}; - -/********* Preview, continuous capture and still modes *****************/ - -static struct imx_reg const imx135_13m[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size Setting */ - {IMX_8BIT, 0x0344, 0x00}, /* 0, 0, 4207,3119 4208x3120 */ - {IMX_8BIT, 0x0345, 0x00}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x00}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x6F}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x2F}, - {IMX_8BIT, 0x034C, 0x10}, - {IMX_8BIT, 0x034D, 0x70}, - {IMX_8BIT, 0x034E, 0x0C}, - {IMX_8BIT, 0x034F, 0x30}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, /* 4208x3120 */ - {IMX_8BIT, 0x0355, 0x70}, - {IMX_8BIT, 0x0356, 0x0C}, - {IMX_8BIT, 0x0357, 0x30}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x10}, - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x0C}, - {IMX_8BIT, 0x3313, 0x30}, - {IMX_8BIT, 0x331C, 0x00}, - {IMX_8BIT, 0x331D, 0x10}, - {IMX_8BIT, 0x4084, 0x00}, /* If scaling, Fill this */ - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -/* 13MP reduced pixel clock MIPI 342MHz is EMC friendly*/ -static struct imx_reg const imx135_13m_for_mipi_342[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_342MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size Setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x00}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x00}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x6F}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x2F}, - {IMX_8BIT, 0x034C, 0x10}, - {IMX_8BIT, 0x034D, 0x70}, - {IMX_8BIT, 0x034E, 0x0C}, - {IMX_8BIT, 0x034F, 0x30}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, - {IMX_8BIT, 0x0355, 0x70}, - {IMX_8BIT, 0x0356, 0x0C}, - {IMX_8BIT, 0x0357, 0x30}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x10}, - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x0C}, - {IMX_8BIT, 0x3313, 0x30}, - {IMX_8BIT, 0x331C, 0x00}, - {IMX_8BIT, 0x331D, 0x10}, - {IMX_8BIT, 0x4084, 0x00}, /* If scaling, Fill this */ - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_10m[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, /* 0, 376, 4207, 2743 */ - {IMX_8BIT, 0x0345, 0x00}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x78}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x6f}, - {IMX_8BIT, 0x034A, 0x0a}, - {IMX_8BIT, 0x034B, 0xb7}, - {IMX_8BIT, 0x034C, 0x10}, /* 4208x2368 */ - {IMX_8BIT, 0x034D, 0x70}, - {IMX_8BIT, 0x034E, 0x09}, - {IMX_8BIT, 0x034F, 0x40}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, - {IMX_8BIT, 0x0355, 0x70}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0x40}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x10}, - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x09}, - {IMX_8BIT, 0x3313, 0x40}, - {IMX_8BIT, 0x331C, 0x01}, - {IMX_8BIT, 0x331D, 0x68}, - {IMX_8BIT, 0x4084, 0x00}, - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_10m_for_mipi_342[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_342MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, /* 0, 376, 4207, 2743 */ - {IMX_8BIT, 0x0345, 0x00}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x78}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x6f}, - {IMX_8BIT, 0x034A, 0x0a}, - {IMX_8BIT, 0x034B, 0xb7}, - {IMX_8BIT, 0x034C, 0x10}, /* 4208x2368 */ - {IMX_8BIT, 0x034D, 0x70}, - {IMX_8BIT, 0x034E, 0x09}, - {IMX_8BIT, 0x034F, 0x40}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, - {IMX_8BIT, 0x0355, 0x70}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0x40}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x10}, - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x09}, - {IMX_8BIT, 0x3313, 0x40}, - {IMX_8BIT, 0x331C, 0x01}, - {IMX_8BIT, 0x331D, 0x68}, - {IMX_8BIT, 0x4084, 0x00}, - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * It is 8.5 DS from (3:2)8m cropped setting. - * - * The 8m(3:2) cropped setting is 2992x2448 effective res. - * The ISP effect cropped setting should be 1408x1152 effect res. - * - * Consider ISP 16x16 padding: - * sensor outputs 368x304 - * cropped region is 3128x2584 - */ -static struct imx_reg const imx135_368x304_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, /* no binning */ - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* resize */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x88}, /* 136/16=8.5 */ - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x02}, /* X_ADD_STA */ - {IMX_8BIT, 0x0345, 0x1C}, /* 540 */ - {IMX_8BIT, 0x0346, 0x01}, /* Y_ADD_STA */ - {IMX_8BIT, 0x0347, 0x0C}, /* 268 */ - {IMX_8BIT, 0x0348, 0x0E}, /* X_ADD_END */ - {IMX_8BIT, 0x0349, 0x53}, /* 3667 */ - {IMX_8BIT, 0x034A, 0x0B}, /* Y_ADD_END */ - {IMX_8BIT, 0x034B, 0x23}, /* 2851 */ - {IMX_8BIT, 0x034C, 0x01}, /* X_OUT_SIZE */ - {IMX_8BIT, 0x034D, 0x70}, /* 368 */ - {IMX_8BIT, 0x034E, 0x01}, /* Y_OUT_SIZE */ - {IMX_8BIT, 0x034F, 0x30}, /* 304 */ - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x0C}, /* Cut out siz same as the size after crop */ - {IMX_8BIT, 0x0355, 0x38}, - {IMX_8BIT, 0x0356, 0x0A}, - {IMX_8BIT, 0x0357, 0x18}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x01}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x01}, - {IMX_8BIT, 0x3313, 0x30}, - {IMX_8BIT, 0x331C, 0x02}, /* ?? */ - {IMX_8BIT, 0x331D, 0xD0}, - {IMX_8BIT, 0x4084, 0x01}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x70}, - {IMX_8BIT, 0x4086, 0x01}, - {IMX_8BIT, 0x4087, 0x30}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * It is 1/4 binning from 8m cropped setting. - * - * The 8m cropped setting is 3264x2448 effective res. - * The xga cropped setting should be 816x612 effect res. - * - * Consider ISP 16x16 padding: - * sensor outputs 832x628 - * cropped region is 3328x2512 - */ -static struct imx_reg const imx135_xga_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, - {IMX_8BIT, 0x0391, 0x44}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, -/* {IMX_8BIT, 0x4203, 0xFF}, */ - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, /* X_ADD_STA */ - {IMX_8BIT, 0x0345, 0xB8}, /* 440 */ - {IMX_8BIT, 0x0346, 0x01}, /* Y_ADD_STA */ - {IMX_8BIT, 0x0347, 0x30}, /* 304 */ - {IMX_8BIT, 0x0348, 0x0E}, /* X_ADD_END */ - {IMX_8BIT, 0x0349, 0xB7}, /* 4207-440=3767 */ - {IMX_8BIT, 0x034A, 0x0A}, /* Y_ADD_END */ - {IMX_8BIT, 0x034B, 0xFF}, /* 3119-304=2815 */ - {IMX_8BIT, 0x034C, 0x03}, /* X_OUT_SIZE */ - {IMX_8BIT, 0x034D, 0x40}, /* 832 */ - {IMX_8BIT, 0x034E, 0x02}, /* Y_OUT_SIZE */ - {IMX_8BIT, 0x034F, 0x74}, /* 628 */ - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x03}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0x40}, - {IMX_8BIT, 0x0356, 0x02}, - {IMX_8BIT, 0x0357, 0x74}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x03}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0x40}, - {IMX_8BIT, 0x3312, 0x02}, - {IMX_8BIT, 0x3313, 0x74}, - {IMX_8BIT, 0x331C, 0x02}, /* ?? */ - {IMX_8BIT, 0x331D, 0x21}, - {IMX_8BIT, 0x4084, 0x03}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x40}, - {IMX_8BIT, 0x4086, 0x02}, - {IMX_8BIT, 0x4087, 0x74}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * It is 28/16 DS from (16:9)8m cropped setting. - * - * The 8m(16:9) cropped setting is 3360x1890 effective res. - * - this is larger then the expected 3264x1836 FOV - * - * Consider ISP 16x16 padding: - * sensor outputs 1936x1096 - * cropped region is 3388x1918 - */ -static struct imx_reg const imx135_1936x1096_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, /* no binning */ - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* resize */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x1C}, /* 28/16 */ - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, /* X_ADD_STA */ - {IMX_8BIT, 0x0345, 0x9A}, /* 410 */ - {IMX_8BIT, 0x0346, 0x02}, /* Y_ADD_STA */ - {IMX_8BIT, 0x0347, 0x58}, /* 600 */ - {IMX_8BIT, 0x0348, 0x0E}, /* X_ADD_END */ - {IMX_8BIT, 0x0349, 0xD5}, /* 3797 */ - {IMX_8BIT, 0x034A, 0x09}, /* Y_ADD_END */ - {IMX_8BIT, 0x034B, 0xD5}, /* 2517 */ - {IMX_8BIT, 0x034C, 0x07}, /* X_OUT_SIZE */ - {IMX_8BIT, 0x034D, 0x90}, /* 1936 */ - {IMX_8BIT, 0x034E, 0x04}, /* Y_OUT_SIZE */ - {IMX_8BIT, 0x034F, 0x48}, /* 1096 */ - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x0D}, /* Cut out siz same as the size after crop */ - {IMX_8BIT, 0x0355, 0x3C}, - {IMX_8BIT, 0x0356, 0x07}, - {IMX_8BIT, 0x0357, 0x7E}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x07}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0x90}, - {IMX_8BIT, 0x3312, 0x04}, - {IMX_8BIT, 0x3313, 0x48}, - {IMX_8BIT, 0x331C, 0x00}, /* ?? */ - {IMX_8BIT, 0x331D, 0xAA}, - {IMX_8BIT, 0x4084, 0x07}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x90}, - {IMX_8BIT, 0x4086, 0x04}, - {IMX_8BIT, 0x4087, 0x48}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * It is 2.125 DS from (3:2)8m cropped setting. - * - * The 8m(3:2) cropped setting is 2992x2448 effective res. - * The ISP effect cropped setting should be 1408x1152 effect res. - * - * Consider ISP 16x16 padding: - * sensor outputs 1424x1168 - * cropped region is 3026x2482 - */ -static struct imx_reg const imx135_1424x1168_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, /* no binning */ - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* resize */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x22}, /* 34/16=2.125 */ - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x02}, /* X_ADD_STA */ - {IMX_8BIT, 0x0345, 0x4E}, /* 590 */ - {IMX_8BIT, 0x0346, 0x01}, /* Y_ADD_STA */ - {IMX_8BIT, 0x0347, 0x3E}, /* 318 */ - {IMX_8BIT, 0x0348, 0x0E}, /* X_ADD_END */ - {IMX_8BIT, 0x0349, 0x1F}, /* 3615 */ - {IMX_8BIT, 0x034A, 0x0A}, /* Y_ADD_END */ - {IMX_8BIT, 0x034B, 0xEF}, /* 2799 */ - {IMX_8BIT, 0x034C, 0x05}, /* X_OUT_SIZE */ - {IMX_8BIT, 0x034D, 0x90}, /* 1424 */ - {IMX_8BIT, 0x034E, 0x04}, /* Y_OUT_SIZE */ - {IMX_8BIT, 0x034F, 0x90}, /* 1168 */ - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x0B}, /* Cut out siz same as the size after crop */ - {IMX_8BIT, 0x0355, 0xD2}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0xB2}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x05}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0x90}, - {IMX_8BIT, 0x3312, 0x04}, - {IMX_8BIT, 0x3313, 0x90}, - {IMX_8BIT, 0x331C, 0x00}, /* ?? */ - {IMX_8BIT, 0x331D, 0xAA}, - {IMX_8BIT, 0x4084, 0x05}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x90}, - {IMX_8BIT, 0x4086, 0x04}, - {IMX_8BIT, 0x4087, 0x90}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * It is 1/2 binning from 8m cropped setting. - * - * The 8m cropped setting is 3264x2448 effective res. - * The 2m cropped setting should be 1632x1224 effect res. - * - * Consider ISP 16x16 padding: - * sensor outputs 1648x1240 - * cropped region is 3296x2480 - */ -static struct imx_reg const imx135_2m_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, - {IMX_8BIT, 0x0391, 0x22}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, /* X_ADD_STA */ - {IMX_8BIT, 0x0345, 0xC8}, /* 464(1D0) -> 456(1C8)*/ - {IMX_8BIT, 0x0346, 0x01}, /* Y_ADD_STA */ - {IMX_8BIT, 0x0347, 0x40}, /* 320 */ - {IMX_8BIT, 0x0348, 0x0E}, /* X_ADD_END */ - {IMX_8BIT, 0x0349, 0xA7}, /* 4207-456=3751 */ - {IMX_8BIT, 0x034A, 0x0A}, /* Y_ADD_END */ - {IMX_8BIT, 0x034B, 0xEF}, /* 3119-320=2799 */ - {IMX_8BIT, 0x034C, 0x06}, /* X_OUT_SIZE */ - {IMX_8BIT, 0x034D, 0x70}, /* 1648 */ - {IMX_8BIT, 0x034E, 0x04}, /* Y_OUT_SIZE */ - {IMX_8BIT, 0x034F, 0xD8}, /* 1240 */ - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x06}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0x70}, - {IMX_8BIT, 0x0356, 0x04}, - {IMX_8BIT, 0x0357, 0xD8}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x06}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0x70}, - {IMX_8BIT, 0x3312, 0x04}, - {IMX_8BIT, 0x3313, 0xD8}, - {IMX_8BIT, 0x331C, 0x00}, /* ?? */ - {IMX_8BIT, 0x331D, 0xAA}, - {IMX_8BIT, 0x4084, 0x00}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * 8M Cropped 16:9 setting - * - * Effect res: 3264x1836 - * Sensor out: 3280x1852 - */ -static struct imx_reg const imx135_6m_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0xD0}, - {IMX_8BIT, 0x0346, 0x02}, /* 634 */ - {IMX_8BIT, 0x0347, 0x7A}, - {IMX_8BIT, 0x0348, 0x0E}, - {IMX_8BIT, 0x0349, 0x9F}, - {IMX_8BIT, 0x034A, 0x09}, /* 2485 */ - {IMX_8BIT, 0x034B, 0xB5}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x07}, /* 1852 */ - {IMX_8BIT, 0x034F, 0x3C}, - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x0C}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0xD0}, - {IMX_8BIT, 0x0356, 0x07}, - {IMX_8BIT, 0x0357, 0x3C}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x0C}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x07}, - {IMX_8BIT, 0x3313, 0x3C}, - {IMX_8BIT, 0x331C, 0x00}, /* ?? */ - {IMX_8BIT, 0x331D, 0x10}, - {IMX_8BIT, 0x4084, 0x00}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_8m_cropped[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0xD0}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x48}, - {IMX_8BIT, 0x0348, 0x0E}, - {IMX_8BIT, 0x0349, 0x9F}, - {IMX_8BIT, 0x034A, 0x0A}, - {IMX_8BIT, 0x034B, 0xE7}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x09}, /* 2464 */ - {IMX_8BIT, 0x034F, 0xA0}, - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x0C}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0xD0}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0xA0}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x0C}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x09}, - {IMX_8BIT, 0x3313, 0xA0}, - {IMX_8BIT, 0x331C, 0x00}, /* ?? */ - {IMX_8BIT, 0x331D, 0x10}, - {IMX_8BIT, 0x4084, 0x00}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_8m_scaled_from_12m[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* Scaling */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x14}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x36}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x14}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x39}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x1B}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280x2464 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x09}, - {IMX_8BIT, 0x034F, 0xA0}, - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0x04}, - {IMX_8BIT, 0x0356, 0x0C}, - {IMX_8BIT, 0x0357, 0x08}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x0C}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x09}, - {IMX_8BIT, 0x3313, 0xA0}, - {IMX_8BIT, 0x331C, 0x02}, /* ?? */ - {IMX_8BIT, 0x331D, 0xA0}, - {IMX_8BIT, 0x4084, 0x0C}, /* Scaling related? */ - {IMX_8BIT, 0x4085, 0xD0}, - {IMX_8BIT, 0x4086, 0x09}, - {IMX_8BIT, 0x4087, 0xA0}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_8m_scaled_from_12m_for_mipi342[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_342MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* Scaling */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x14}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x36}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x14}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x39}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x1B}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280x2464 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x09}, - {IMX_8BIT, 0x034F, 0xA0}, - {IMX_8BIT, 0x0350, 0x00}, /* No Dig crop */ - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, /* Cut out size same as the size after crop */ - {IMX_8BIT, 0x0355, 0x04}, - {IMX_8BIT, 0x0356, 0x0C}, - {IMX_8BIT, 0x0357, 0x08}, - {IMX_8BIT, 0x301D, 0x30}, /* ?? */ - {IMX_8BIT, 0x3310, 0x0C}, /* Write H and V size same as output size? */ - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x09}, - {IMX_8BIT, 0x3313, 0xA0}, - {IMX_8BIT, 0x331C, 0x02}, /* ?? */ - {IMX_8BIT, 0x331D, 0xA0}, - {IMX_8BIT, 0x4084, 0x0C}, /* Resize IMG Hand V size-> Scaling related?*/ - {IMX_8BIT, 0x4085, 0xD0}, - {IMX_8BIT, 0x4086, 0x09}, - {IMX_8BIT, 0x4087, 0xA0}, - {IMX_8BIT, 0x4400, 0x00}, /* STATS off */ - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_6m[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x14}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, /* 36, 194, 1039, a9f 4100x2316 */ - {IMX_8BIT, 0x0345, 0x36}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x94}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x39}, - {IMX_8BIT, 0x034A, 0x0A}, - {IMX_8BIT, 0x034B, 0x9F}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280x1852 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x07}, - {IMX_8BIT, 0x034F, 0x3C}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, /* 4100x2316 */ - {IMX_8BIT, 0x0355, 0x04}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0x0C}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x0C}, - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x07}, - {IMX_8BIT, 0x3313, 0x3C}, - {IMX_8BIT, 0x331C, 0x02}, - {IMX_8BIT, 0x331D, 0xA0}, - {IMX_8BIT, 0x4084, 0x0C}, - {IMX_8BIT, 0x4085, 0xD0}, - {IMX_8BIT, 0x4086, 0x07}, - {IMX_8BIT, 0x4087, 0x3C}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_6m_for_mipi_342[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_342MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x00}, - {IMX_8BIT, 0x0391, 0x11}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x14}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, /* 36, 194, 1039, a9f 4100x2316 */ - {IMX_8BIT, 0x0345, 0x36}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x94}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x39}, - {IMX_8BIT, 0x034A, 0x0A}, - {IMX_8BIT, 0x034B, 0x9F}, - {IMX_8BIT, 0x034C, 0x0C}, /* 3280x1852 */ - {IMX_8BIT, 0x034D, 0xD0}, - {IMX_8BIT, 0x034E, 0x07}, - {IMX_8BIT, 0x034F, 0x3C}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x10}, /* 4100x2316 */ - {IMX_8BIT, 0x0355, 0x04}, - {IMX_8BIT, 0x0356, 0x09}, - {IMX_8BIT, 0x0357, 0x0C}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x0C}, - {IMX_8BIT, 0x3311, 0xD0}, - {IMX_8BIT, 0x3312, 0x07}, - {IMX_8BIT, 0x3313, 0x3C}, - {IMX_8BIT, 0x331C, 0x02}, - {IMX_8BIT, 0x331D, 0xA0}, - {IMX_8BIT, 0x4084, 0x0C}, - {IMX_8BIT, 0x4085, 0xD0}, - {IMX_8BIT, 0x4086, 0x07}, - {IMX_8BIT, 0x4087, 0x3C}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -/* - * FOV is: 3280x2464, larger then 3264x2448. - * Sensor output: 336x256 - * Cropping region: 3444x2624 - */ -static struct imx_reg const imx135_336x256[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, - {IMX_8BIT, 0x0391, 0x22}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, /* 2x binning */ - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x52}, /* scaling: 82/16 */ - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01}, /* x_start: 374 */ - {IMX_8BIT, 0x0345, 0x76}, - {IMX_8BIT, 0x0346, 0x00}, /* y_start: 248 */ - {IMX_8BIT, 0x0347, 0xF8}, - {IMX_8BIT, 0x0348, 0x0E}, /* x_end: 3817 */ - {IMX_8BIT, 0x0349, 0xE9}, - {IMX_8BIT, 0x034A, 0x0B}, /* y_end: 2871 */ - {IMX_8BIT, 0x034B, 0x37}, - {IMX_8BIT, 0x034C, 0x01}, /* x_out: 336 */ - {IMX_8BIT, 0x034D, 0x50}, - {IMX_8BIT, 0x034E, 0x01}, /* y_out: 256 */ - {IMX_8BIT, 0x034F, 0x00}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x06}, /* dig x_out: 1722 */ - {IMX_8BIT, 0x0355, 0xBA}, - {IMX_8BIT, 0x0356, 0x05}, /* dig y_out: 1312 */ - {IMX_8BIT, 0x0357, 0x20}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x01}, /* ?: x_out */ - {IMX_8BIT, 0x3311, 0x50}, - {IMX_8BIT, 0x3312, 0x01}, /* ?: y_out */ - {IMX_8BIT, 0x3313, 0x00}, - {IMX_8BIT, 0x331C, 0x02}, - {IMX_8BIT, 0x331D, 0x4E}, - {IMX_8BIT, 0x4084, 0x01}, /* ?: x_out */ - {IMX_8BIT, 0x4085, 0x50}, - {IMX_8BIT, 0x4086, 0x01}, /* ?: y_out */ - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_1m[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, - {IMX_8BIT, 0x0391, 0x22}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x1F}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x58}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x28}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x17}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x07}, - {IMX_8BIT, 0x034C, 0x04}, - {IMX_8BIT, 0x034D, 0x10}, - {IMX_8BIT, 0x034E, 0x03}, - {IMX_8BIT, 0x034F, 0x10}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x07}, - {IMX_8BIT, 0x0355, 0xE0}, - {IMX_8BIT, 0x0356, 0x05}, - {IMX_8BIT, 0x0357, 0xF0}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x04}, - {IMX_8BIT, 0x3311, 0x10}, - {IMX_8BIT, 0x3312, 0x03}, - {IMX_8BIT, 0x3313, 0x10}, - {IMX_8BIT, 0x331C, 0x02}, - {IMX_8BIT, 0x331D, 0x4E}, - {IMX_8BIT, 0x4084, 0x04}, - {IMX_8BIT, 0x4085, 0x10}, - {IMX_8BIT, 0x4086, 0x03}, - {IMX_8BIT, 0x4087, 0x10}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg const imx135_3m_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, /* Binning */ - {IMX_8BIT, 0x0391, 0x22}, /* 2x2 binning */ - {IMX_8BIT, 0x0392, 0x00}, /* average */ - {IMX_8BIT, 0x0401, 0x00}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x10}, - {IMX_8BIT, 0x4082, 0x01}, - {IMX_8BIT, 0x4083, 0x01}, - {IMX_8BIT, 0x4203, 0xFF}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x28}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x08}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x47}, - {IMX_8BIT, 0x034A, 0x0C}, - {IMX_8BIT, 0x034B, 0x27}, - {IMX_8BIT, 0x034C, 0x08}, - {IMX_8BIT, 0x034D, 0x10}, - {IMX_8BIT, 0x034E, 0x06}, - {IMX_8BIT, 0x034F, 0x10}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x08}, - {IMX_8BIT, 0x0355, 0x10}, - {IMX_8BIT, 0x0356, 0x06}, - {IMX_8BIT, 0x0357, 0x10}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x08}, - {IMX_8BIT, 0x3311, 0x10}, - {IMX_8BIT, 0x3312, 0x06}, - {IMX_8BIT, 0x3313, 0x10}, - {IMX_8BIT, 0x331C, 0x00}, - {IMX_8BIT, 0x331D, 0xAA}, - {IMX_8BIT, 0x4084, 0x00}, - {IMX_8BIT, 0x4085, 0x00}, - {IMX_8BIT, 0x4086, 0x00}, - {IMX_8BIT, 0x4087, 0x00}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -/* 1080P 1936x1104 */ -static struct imx_reg const imx135_1080p_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03}, - {IMX_8BIT, 0x0112, 0x0A}, - {IMX_8BIT, 0x0113, 0x0A}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0387, 0x01}, - {IMX_8BIT, 0x0390, 0x01}, - {IMX_8BIT, 0x0391, 0x22}, - {IMX_8BIT, 0x0392, 0x00}, - {IMX_8BIT, 0x0401, 0x02}, - {IMX_8BIT, 0x0404, 0x00}, - {IMX_8BIT, 0x0405, 0x11}, - {IMX_8BIT, 0x4082, 0x00}, - {IMX_8BIT, 0x4083, 0x00}, - {IMX_8BIT, 0x7006, 0x04}, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x2E}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x84}, - {IMX_8BIT, 0x0348, 0x10}, - {IMX_8BIT, 0x0349, 0x41}, - {IMX_8BIT, 0x034A, 0x0A}, - {IMX_8BIT, 0x034B, 0xAF}, - {IMX_8BIT, 0x034C, 0x07}, - {IMX_8BIT, 0x034D, 0x90}, - {IMX_8BIT, 0x034E, 0x04}, - {IMX_8BIT, 0x034F, 0x50}, - {IMX_8BIT, 0x0350, 0x00}, - {IMX_8BIT, 0x0351, 0x00}, - {IMX_8BIT, 0x0352, 0x00}, - {IMX_8BIT, 0x0353, 0x00}, - {IMX_8BIT, 0x0354, 0x08}, - {IMX_8BIT, 0x0355, 0x0A}, - {IMX_8BIT, 0x0356, 0x04}, - {IMX_8BIT, 0x0357, 0x96}, - {IMX_8BIT, 0x301D, 0x30}, - {IMX_8BIT, 0x3310, 0x07}, - {IMX_8BIT, 0x3311, 0x90}, - {IMX_8BIT, 0x3312, 0x04}, - {IMX_8BIT, 0x3313, 0x50}, - {IMX_8BIT, 0x331C, 0x01}, - {IMX_8BIT, 0x331D, 0x00}, - {IMX_8BIT, 0x4084, 0x07}, - {IMX_8BIT, 0x4085, 0x90}, - {IMX_8BIT, 0x4086, 0x04}, - {IMX_8BIT, 0x4087, 0x50}, - {IMX_8BIT, 0x4400, 0x00}, - {IMX_TOK_TERM, 0, 0}, -}; - -static const struct imx_reg imx135_1080p_nodvs_fullfov_max_clock[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 168,464,4039,2655: 3872x2192 */ - { IMX_8BIT, 0x0345, 0xA8 }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0xD0 }, - { IMX_8BIT, 0x0348, 0x0F }, - { IMX_8BIT, 0x0349, 0xC7 }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0x5F }, - { IMX_8BIT, 0x034C, 0x07 }, /*1936 x 1096 */ - { IMX_8BIT, 0x034D, 0x90 }, - { IMX_8BIT, 0x034E, 0x04 }, - { IMX_8BIT, 0x034F, 0x48 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x07 }, /*1936 x 1096 */ - { IMX_8BIT, 0x0355, 0x90 }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0x48 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x07 }, - { IMX_8BIT, 0x3311, 0x90 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0x48 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0xB0 }, - { IMX_8BIT, 0x4084, 0x07 }, - { IMX_8BIT, 0x4085, 0x90 }, - { IMX_8BIT, 0x4086, 0x04 }, - { IMX_8BIT, 0x4087, 0x48 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* 1080P NODVS 1936x1096 */ -static const struct imx_reg imx135_1080p_nodvs_max_clock[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x11 }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 46,396,4161,2727: 4116x2332 */ - { IMX_8BIT, 0x0345, 0x2E }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0x8C }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x41 }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0xA7 }, - { IMX_8BIT, 0x034C, 0x07 }, /*1936 x 1096 */ - { IMX_8BIT, 0x034D, 0x90 }, - { IMX_8BIT, 0x034E, 0x04 }, - { IMX_8BIT, 0x034F, 0x48 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x08 }, /* 2058x1166 */ - { IMX_8BIT, 0x0355, 0x0A }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0x8E }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x07 }, - { IMX_8BIT, 0x3311, 0x90 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0x48 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0xB0 }, - { IMX_8BIT, 0x4084, 0x07 }, - { IMX_8BIT, 0x4085, 0x90 }, - { IMX_8BIT, 0x4086, 0x04 }, - { IMX_8BIT, 0x4087, 0x48 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* 1080P 10%DVS 2104x1184 */ -static const struct imx_reg imx135_1080p_10_dvs_max_clock[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x00 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x10 }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 0,376,4207,2743: 4208x2368 */ - { IMX_8BIT, 0x0345, 0x00 }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0x78 }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x6F }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0xB7 }, - { IMX_8BIT, 0x034C, 0x08 }, /* 2104 x 1184 */ - { IMX_8BIT, 0x034D, 0x38 }, - { IMX_8BIT, 0x034E, 0x04 }, - { IMX_8BIT, 0x034F, 0xA0 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x08 }, /* 2104 x 1184 */ - { IMX_8BIT, 0x0355, 0x38 }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0xA0 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x08 }, - { IMX_8BIT, 0x3311, 0x38 }, - { IMX_8BIT, 0x3312, 0x04 }, - { IMX_8BIT, 0x3313, 0xA0 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0xB0 }, - { IMX_8BIT, 0x4084, 0x00 }, - { IMX_8BIT, 0x4085, 0x00 }, - { IMX_8BIT, 0x4086, 0x00 }, - { IMX_8BIT, 0x4087, 0x00 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -static const struct imx_reg imx135_720pdvs_max_clock[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x15 }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 46,404,4161,2715: 4116x2312 */ - { IMX_8BIT, 0x0345, 0x2E }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0x94 }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x41 }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0x9B }, - { IMX_8BIT, 0x034C, 0x06 }, /*1568 x 880 */ - { IMX_8BIT, 0x034D, 0x20 }, - { IMX_8BIT, 0x034E, 0x03 }, - { IMX_8BIT, 0x034F, 0x70 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x08 }, /*2058 x 1156 */ - { IMX_8BIT, 0x0355, 0x0A }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0x84 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x03 }, - { IMX_8BIT, 0x3313, 0x70 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0x4C }, - { IMX_8BIT, 0x4084, 0x06 }, - { IMX_8BIT, 0x4085, 0x20 }, - { IMX_8BIT, 0x4086, 0x03 }, - { IMX_8BIT, 0x4087, 0x70 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/******************* Video Modes ******************/ - -/* 1080P DVS 2336x1320 */ -static const struct imx_reg imx135_2336x1320_max_clock[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_451_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, - { IMX_8BIT, 0x0391, 0x11 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x1C }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 60,404,4147,2715: 4088x2312 */ - { IMX_8BIT, 0x0345, 0x3C }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0x94 }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x33 }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0x9B }, - { IMX_8BIT, 0x034C, 0x09 }, /*2336 x 1320 */ - { IMX_8BIT, 0x034D, 0x20 }, - { IMX_8BIT, 0x034E, 0x05 }, - { IMX_8BIT, 0x034F, 0x28 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x0F }, /* 4088x2312 */ - { IMX_8BIT, 0x0355, 0xF8 }, - { IMX_8BIT, 0x0356, 0x09 }, - { IMX_8BIT, 0x0357, 0x08 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x09 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x05 }, - { IMX_8BIT, 0x3313, 0x28 }, - { IMX_8BIT, 0x331C, 0x04 }, - { IMX_8BIT, 0x331D, 0xE2 }, - { IMX_8BIT, 0x4084, 0x09 }, - { IMX_8BIT, 0x4085, 0x20 }, - { IMX_8BIT, 0x4086, 0x05 }, - { IMX_8BIT, 0x4087, 0x28 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* 1080P DVS 2336x1320 Cropped */ -static const struct imx_reg imx135_2336x1320_cropped_mipi499[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_499_2MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x00 }, - { IMX_8BIT, 0x0391, 0x11 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x1C }, - { IMX_8BIT, 0x4082, 0x01 }, - { IMX_8BIT, 0x4083, 0x01 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x03 }, /* 936,900,3271,2219: 2336x1320 */ - { IMX_8BIT, 0x0345, 0xA8 }, - { IMX_8BIT, 0x0346, 0x03 }, - { IMX_8BIT, 0x0347, 0x84 }, - { IMX_8BIT, 0x0348, 0x0C }, - { IMX_8BIT, 0x0349, 0xC7 }, - { IMX_8BIT, 0x034A, 0x08 }, - { IMX_8BIT, 0x034B, 0xAB }, - { IMX_8BIT, 0x034C, 0x09 }, /* 2336 x 1320 */ - { IMX_8BIT, 0x034D, 0x20 }, - { IMX_8BIT, 0x034E, 0x05 }, - { IMX_8BIT, 0x034F, 0x28 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x09 }, /* 2336 x 1320 */ - { IMX_8BIT, 0x0355, 0x20 }, - { IMX_8BIT, 0x0356, 0x05 }, - { IMX_8BIT, 0x0357, 0x28 }, - { IMX_8BIT, 0x301D, 0x30 }, - { IMX_8BIT, 0x3310, 0x09 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x05 }, - { IMX_8BIT, 0x3313, 0x28 }, - { IMX_8BIT, 0x331C, 0x00 }, - { IMX_8BIT, 0x331D, 0xB4 }, - { IMX_8BIT, 0x4084, 0x09 }, - { IMX_8BIT, 0x4085, 0x20 }, - { IMX_8BIT, 0x4086, 0x05 }, - { IMX_8BIT, 0x4087, 0x28 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* 720P DVS 1568 x 880 */ -static const struct imx_reg imx135_720p_dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x15 }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 46,404,4161,2715: 4116x2312 */ - { IMX_8BIT, 0x0345, 0x2e }, - { IMX_8BIT, 0x0346, 0x01 }, - { IMX_8BIT, 0x0347, 0x94 }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x41 }, - { IMX_8BIT, 0x034A, 0x0A }, - { IMX_8BIT, 0x034B, 0x9B }, - { IMX_8BIT, 0x034C, 0x06 }, /*1568 x 880 */ - { IMX_8BIT, 0x034D, 0x20 }, - { IMX_8BIT, 0x034E, 0x03 }, - { IMX_8BIT, 0x034F, 0x70 }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x08 }, /* 2058x1156 */ - { IMX_8BIT, 0x0355, 0x0a }, - { IMX_8BIT, 0x0356, 0x04 }, - { IMX_8BIT, 0x0357, 0x84 }, - { IMX_8BIT, 0x301D, 0x30 }, /* TODO! */ - { IMX_8BIT, 0x3310, 0x06 }, - { IMX_8BIT, 0x3311, 0x20 }, - { IMX_8BIT, 0x3312, 0x03 }, - { IMX_8BIT, 0x3313, 0x70 }, - { IMX_8BIT, 0x331C, 0x01 }, /* TODO! */ - { IMX_8BIT, 0x331D, 0xd6 }, /* TODO! */ - { IMX_8BIT, 0x4084, 0x06 }, - { IMX_8BIT, 0x4085, 0x20 }, - { IMX_8BIT, 0x4086, 0x03 }, - { IMX_8BIT, 0x4087, 0x70 }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* wvga: H : 1640 V : 1024 */ -static const struct imx_reg imx135_wvga_dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x22 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x14 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, - {IMX_8BIT, 0x0345, 0x36 }, - {IMX_8BIT, 0x0346, 0x01 }, - {IMX_8BIT, 0x0347, 0x18 }, - {IMX_8BIT, 0x0348, 0x10 }, - {IMX_8BIT, 0x0349, 0x39 }, - {IMX_8BIT, 0x034A, 0x0B }, - {IMX_8BIT, 0x034B, 0x17 }, - {IMX_8BIT, 0x034C, 0x06 }, - {IMX_8BIT, 0x034D, 0x68 }, - {IMX_8BIT, 0x034E, 0x04 }, - {IMX_8BIT, 0x034F, 0x00 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x08 }, - {IMX_8BIT, 0x0355, 0x02 }, - {IMX_8BIT, 0x0356, 0x05 }, - {IMX_8BIT, 0x0357, 0x00 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x06 }, - {IMX_8BIT, 0x3311, 0x68 }, - {IMX_8BIT, 0x3312, 0x04 }, - {IMX_8BIT, 0x3313, 0x00 }, - {IMX_8BIT, 0x331C, 0x01 }, - {IMX_8BIT, 0x331D, 0xBD }, - {IMX_8BIT, 0x4084, 0x06 }, - {IMX_8BIT, 0x4085, 0x68 }, - {IMX_8BIT, 0x4086, 0x04 }, - {IMX_8BIT, 0x4087, 0x00 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* 480P 1036 x 696 */ -static const struct imx_reg imx135_480p_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x00 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x10 },/* No scal */ - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 52,20,4155, 3099 4144x2784*/ - {IMX_8BIT, 0x0345, 0x20 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0xA8 }, - {IMX_8BIT, 0x0348, 0x10 }, - {IMX_8BIT, 0x0349, 0x4F }, - {IMX_8BIT, 0x034A, 0x0B }, - {IMX_8BIT, 0x034B, 0x88 }, - {IMX_8BIT, 0x034C, 0x04 }, /* 1036 * 696 */ - {IMX_8BIT, 0x034D, 0x0C }, - {IMX_8BIT, 0x034E, 0x02 }, - {IMX_8BIT, 0x034F, 0xB8 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x04 }, /* 1036x696 */ - {IMX_8BIT, 0x0355, 0x0C }, - {IMX_8BIT, 0x0356, 0x02 }, - {IMX_8BIT, 0x0357, 0xB8 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x04 }, - {IMX_8BIT, 0x3311, 0x0C }, - {IMX_8BIT, 0x3312, 0x02 }, - {IMX_8BIT, 0x3313, 0xB8 }, - {IMX_8BIT, 0x331C, 0x02 }, - {IMX_8BIT, 0x331D, 0x21 }, - {IMX_8BIT, 0x4084, 0x04 }, - {IMX_8BIT, 0x4085, 0x0C }, - {IMX_8BIT, 0x4086, 0x02 }, - {IMX_8BIT, 0x4087, 0xB8 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* 480P DVS 936 x 602 */ -static const struct imx_reg imx135_480p_dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* mode setting */ - { IMX_8BIT, 0x0108, 0x03 }, - { IMX_8BIT, 0x0112, 0x0A }, - { IMX_8BIT, 0x0113, 0x0A }, - { IMX_8BIT, 0x0381, 0x01 }, - { IMX_8BIT, 0x0383, 0x01 }, - { IMX_8BIT, 0x0385, 0x01 }, - { IMX_8BIT, 0x0387, 0x01 }, - { IMX_8BIT, 0x0390, 0x01 }, - { IMX_8BIT, 0x0391, 0x22 }, - { IMX_8BIT, 0x0392, 0x00 }, - { IMX_8BIT, 0x0401, 0x02 }, - { IMX_8BIT, 0x0404, 0x00 }, - { IMX_8BIT, 0x0405, 0x23 }, - { IMX_8BIT, 0x4082, 0x00 }, - { IMX_8BIT, 0x4083, 0x00 }, - { IMX_8BIT, 0x7006, 0x04 }, - /* size setting */ - { IMX_8BIT, 0x0344, 0x00 }, /* 56,244,4151,2877: 4096x2634 */ - { IMX_8BIT, 0x0345, 0x38 }, - { IMX_8BIT, 0x0346, 0x00 }, - { IMX_8BIT, 0x0347, 0xf4 }, - { IMX_8BIT, 0x0348, 0x10 }, - { IMX_8BIT, 0x0349, 0x37 }, - { IMX_8BIT, 0x034A, 0x0b }, - { IMX_8BIT, 0x034B, 0x3d }, - { IMX_8BIT, 0x034C, 0x03 }, /* 936 x 602 */ - { IMX_8BIT, 0x034D, 0xa8 }, - { IMX_8BIT, 0x034E, 0x02 }, - { IMX_8BIT, 0x034F, 0x5a }, - { IMX_8BIT, 0x0350, 0x00 }, - { IMX_8BIT, 0x0351, 0x00 }, - { IMX_8BIT, 0x0352, 0x00 }, - { IMX_8BIT, 0x0353, 0x00 }, - { IMX_8BIT, 0x0354, 0x08 }, /* 2058x1156 */ - { IMX_8BIT, 0x0355, 0x00 }, - { IMX_8BIT, 0x0356, 0x05 }, - { IMX_8BIT, 0x0357, 0x25 }, - { IMX_8BIT, 0x301D, 0x30 }, /* TODO! */ - { IMX_8BIT, 0x3310, 0x03 }, - { IMX_8BIT, 0x3311, 0xa8 }, - { IMX_8BIT, 0x3312, 0x02 }, - { IMX_8BIT, 0x3313, 0x5a }, - { IMX_8BIT, 0x331C, 0x01 }, /* TODO! */ - { IMX_8BIT, 0x331D, 0xd6 }, - { IMX_8BIT, 0x4084, 0x03 }, - { IMX_8BIT, 0x4085, 0xa8 }, - { IMX_8BIT, 0x4086, 0x02 }, - { IMX_8BIT, 0x4087, 0x5a }, - { IMX_8BIT, 0x4400, 0x00 }, - { IMX_TOK_TERM, 0, 0} -}; - -/* VGA: H : 1036 V : 780 */ -static const struct imx_reg imx135_vga_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x00 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x10 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 52,20,4155, 3099 4144x3120*/ - {IMX_8BIT, 0x0345, 0x20 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x00 }, - {IMX_8BIT, 0x0348, 0x10 }, - {IMX_8BIT, 0x0349, 0x4F }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x2F }, - {IMX_8BIT, 0x034C, 0x04 }, /* 1036x780 */ - {IMX_8BIT, 0x034D, 0x0C }, - {IMX_8BIT, 0x034E, 0x03 }, - {IMX_8BIT, 0x034F, 0x0C }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x04 }, /* 1036x780 */ - {IMX_8BIT, 0x0355, 0x0C }, - {IMX_8BIT, 0x0356, 0x03 }, - {IMX_8BIT, 0x0357, 0x0C }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x04 }, - {IMX_8BIT, 0x3311, 0x0C }, - {IMX_8BIT, 0x3312, 0x03 }, - {IMX_8BIT, 0x3313, 0x0C }, - {IMX_8BIT, 0x331C, 0x02 }, - {IMX_8BIT, 0x331D, 0x21 }, - {IMX_8BIT, 0x4084, 0x04 }, - {IMX_8BIT, 0x4085, 0x0C }, - {IMX_8BIT, 0x4086, 0x03 }, - {IMX_8BIT, 0x4087, 0x0C }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* VGA: H : 820 V : 616 */ -static const struct imx_reg imx135_vga_dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x14 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 52,20,4155, 3099 4104x3080*/ - {IMX_8BIT, 0x0345, 0x34 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x14 }, - {IMX_8BIT, 0x0348, 0x10 }, - {IMX_8BIT, 0x0349, 0x3B }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x1B }, - {IMX_8BIT, 0x034C, 0x03 }, /* 820x616 */ - {IMX_8BIT, 0x034D, 0x34 }, - {IMX_8BIT, 0x034E, 0x02 }, - {IMX_8BIT, 0x034F, 0x68 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x04 }, /* 1026x770 */ - {IMX_8BIT, 0x0355, 0x02 }, - {IMX_8BIT, 0x0356, 0x03 }, - {IMX_8BIT, 0x0357, 0x02 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x03 }, - {IMX_8BIT, 0x3311, 0x34 }, - {IMX_8BIT, 0x3312, 0x02 }, - {IMX_8BIT, 0x3313, 0x68 }, - {IMX_8BIT, 0x331C, 0x02 }, - {IMX_8BIT, 0x331D, 0x21 }, - {IMX_8BIT, 0x4084, 0x03 }, - {IMX_8BIT, 0x4085, 0x34 }, - {IMX_8BIT, 0x4086, 0x02 }, - {IMX_8BIT, 0x4087, 0x68 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* VGA: H : 436 V : 360 */ -static const struct imx_reg imx135_436x360_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x22 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 212,0,3995,3119 3784x3120 */ - {IMX_8BIT, 0x0345, 0xD4 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x00 }, - {IMX_8BIT, 0x0348, 0x0F }, - {IMX_8BIT, 0x0349, 0x9B }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x2F }, - - {IMX_8BIT, 0x034C, 0x01 }, /* 436x360 */ - {IMX_8BIT, 0x034D, 0xB4 }, - {IMX_8BIT, 0x034E, 0x01 }, - {IMX_8BIT, 0x034F, 0x68 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x12 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x0C }, - - {IMX_8BIT, 0x0354, 0x03 }, /* 928x768 crop from 946x780*/ - {IMX_8BIT, 0x0355, 0xA0 }, - {IMX_8BIT, 0x0356, 0x03 }, - {IMX_8BIT, 0x0357, 0x00 }, - - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x01 }, - {IMX_8BIT, 0x3311, 0xB4 }, - {IMX_8BIT, 0x3312, 0x01 }, - {IMX_8BIT, 0x3313, 0x68 }, - {IMX_8BIT, 0x331C, 0x02 }, - {IMX_8BIT, 0x331D, 0x21 }, - {IMX_8BIT, 0x4084, 0x01 }, - {IMX_8BIT, 0x4085, 0xB4 }, - {IMX_8BIT, 0x4086, 0x01 }, - {IMX_8BIT, 0x4087, 0x68 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* QVGA: H : 408 V : 308 */ -static const struct imx_reg imx135_qvga__dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x28 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 64,20,4143,3099 4080x3080 */ - {IMX_8BIT, 0x0345, 0x40 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x14 }, - {IMX_8BIT, 0x0348, 0x10 }, - {IMX_8BIT, 0x0349, 0x2F }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x1B }, - {IMX_8BIT, 0x034C, 0x01 }, /* 408x308 */ - {IMX_8BIT, 0x034D, 0x98 }, - {IMX_8BIT, 0x034E, 0x01 }, - {IMX_8BIT, 0x034F, 0x34 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x03 }, /* 1020x770 */ - {IMX_8BIT, 0x0355, 0xFC }, - {IMX_8BIT, 0x0356, 0x03 }, - {IMX_8BIT, 0x0357, 0x02 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x01 }, - {IMX_8BIT, 0x3311, 0x98 }, - {IMX_8BIT, 0x3312, 0x01 }, - {IMX_8BIT, 0x3313, 0x34 }, - {IMX_8BIT, 0x331C, 0x01 }, - {IMX_8BIT, 0x331D, 0x68 }, - {IMX_8BIT, 0x4084, 0x01 }, - {IMX_8BIT, 0x4085, 0x98 }, - {IMX_8BIT, 0x4086, 0x01 }, - {IMX_8BIT, 0x4087, 0x34 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* CIF H : 368 V : 304 */ -static const struct imx_reg imx135_cif_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x28 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x01 }, /* 264,42,3943,3081 3680x3040 */ - {IMX_8BIT, 0x0345, 0x08 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x2a }, - {IMX_8BIT, 0x0348, 0x0F }, - {IMX_8BIT, 0x0349, 0x67 }, - {IMX_8BIT, 0x034A, 0x0c }, - {IMX_8BIT, 0x034B, 0x09 }, - {IMX_8BIT, 0x034C, 0x01 }, /* 368x304 */ - {IMX_8BIT, 0x034D, 0x70 }, - {IMX_8BIT, 0x034E, 0x01 }, - {IMX_8BIT, 0x034F, 0x30 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x03 }, /* 920x760 */ - {IMX_8BIT, 0x0355, 0x98 }, - {IMX_8BIT, 0x0356, 0x02 }, - {IMX_8BIT, 0x0357, 0xf8 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x01 }, - {IMX_8BIT, 0x3311, 0x70 }, - {IMX_8BIT, 0x3312, 0x01 }, - {IMX_8BIT, 0x3313, 0x30 }, - {IMX_8BIT, 0x331C, 0x02 }, /* TODO! binning 4x4 must be 021c? */ - {IMX_8BIT, 0x331D, 0x1C }, - {IMX_8BIT, 0x4084, 0x01 }, - {IMX_8BIT, 0x4085, 0x70 }, - {IMX_8BIT, 0x4086, 0x01 }, - {IMX_8BIT, 0x4087, 0x30 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* CIF H : 1888 V : 1548 */ -static const struct imx_reg imx135_cif_binning_1888x1548[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x22 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x00 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x10 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 264,42, 3776x3096 */ - {IMX_8BIT, 0x0345, 0xD8 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x0C }, - {IMX_8BIT, 0x0348, 0x0F }, - {IMX_8BIT, 0x0349, 0x97 }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x23 }, - {IMX_8BIT, 0x034C, 0x07 }, /* 1888x1548 */ - {IMX_8BIT, 0x034D, 0x60 }, - {IMX_8BIT, 0x034E, 0x06 }, - {IMX_8BIT, 0x034F, 0x0C }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x07 }, /* 1888x1548 */ - {IMX_8BIT, 0x0355, 0x60 }, - {IMX_8BIT, 0x0356, 0x06 }, - {IMX_8BIT, 0x0357, 0x0C }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x07 }, - {IMX_8BIT, 0x3311, 0x60 }, - {IMX_8BIT, 0x3312, 0x06 }, - {IMX_8BIT, 0x3313, 0x0C }, - {IMX_8BIT, 0x331C, 0x02 }, /* TODO! binning 4x4 must be 021c? */ - {IMX_8BIT, 0x331D, 0x1C }, - {IMX_8BIT, 0x4084, 0x07 }, - {IMX_8BIT, 0x4085, 0x60 }, - {IMX_8BIT, 0x4086, 0x06 }, - {IMX_8BIT, 0x4087, 0x0C }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* QCIF H : 216 V : 176 */ -static const struct imx_reg imx135_qcif_dvs_binning[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - PLL_SETTINGS_FOR_MIPI_209_6MHZ_SALTBAY, - /* Mode setting */ - {IMX_8BIT, 0x0108, 0x03 }, - {IMX_8BIT, 0x0112, 0x0A }, - {IMX_8BIT, 0x0113, 0x0A }, - {IMX_8BIT, 0x0381, 0x01 }, - {IMX_8BIT, 0x0383, 0x01 }, - {IMX_8BIT, 0x0385, 0x01 }, - {IMX_8BIT, 0x0387, 0x01 }, - {IMX_8BIT, 0x0390, 0x01 }, - {IMX_8BIT, 0x0391, 0x44 }, - {IMX_8BIT, 0x0392, 0x00 }, - {IMX_8BIT, 0x0401, 0x02 }, - {IMX_8BIT, 0x0404, 0x00 }, - {IMX_8BIT, 0x0405, 0x46 }, - {IMX_8BIT, 0x4082, 0x00 }, - {IMX_8BIT, 0x4083, 0x00 }, - {IMX_8BIT, 0x7006, 0x04 }, - /* Size setting */ - {IMX_8BIT, 0x0344, 0x00 }, /* 212,20,3995,3099 3784x3080 */ - {IMX_8BIT, 0x0345, 0xD4 }, - {IMX_8BIT, 0x0346, 0x00 }, - {IMX_8BIT, 0x0347, 0x14 }, - {IMX_8BIT, 0x0348, 0x0F }, - {IMX_8BIT, 0x0349, 0x9B }, - {IMX_8BIT, 0x034A, 0x0C }, - {IMX_8BIT, 0x034B, 0x1B }, - {IMX_8BIT, 0x034C, 0x00 }, /* 216x176 */ - {IMX_8BIT, 0x034D, 0xD8 }, - {IMX_8BIT, 0x034E, 0x00 }, - {IMX_8BIT, 0x034F, 0xB0 }, - {IMX_8BIT, 0x0350, 0x00 }, - {IMX_8BIT, 0x0351, 0x00 }, - {IMX_8BIT, 0x0352, 0x00 }, - {IMX_8BIT, 0x0353, 0x00 }, - {IMX_8BIT, 0x0354, 0x03 }, /* 946x770 */ - {IMX_8BIT, 0x0355, 0xB2 }, - {IMX_8BIT, 0x0356, 0x03 }, - {IMX_8BIT, 0x0357, 0x02 }, - {IMX_8BIT, 0x301D, 0x30 }, - {IMX_8BIT, 0x3310, 0x00 }, - {IMX_8BIT, 0x3311, 0xD8 }, - {IMX_8BIT, 0x3312, 0x00 }, - {IMX_8BIT, 0x3313, 0xB0 }, - {IMX_8BIT, 0x331C, 0x02 }, /* TODO! binning 4x4 must be 021c */ - {IMX_8BIT, 0x331D, 0x1C }, - {IMX_8BIT, 0x4084, 0x00 }, - {IMX_8BIT, 0x4085, 0xD8 }, - {IMX_8BIT, 0x4086, 0x00 }, - {IMX_8BIT, 0x4087, 0xB0 }, - {IMX_8BIT, 0x4400, 0x00 }, - {IMX_TOK_TERM, 0, 0} -}; - -/* - * ISP Scaling is now supported in offine capture use cases. Because of that - * we need only few modes to cover the different aspect ratios from the - * sensor and the ISP will scale it based on the requested resolution from HAL. - * - * There is a performance impact when continuous view finder option is chose - * for resolutions above 8MP. So 8MP and 6MP resolution are kept, so that lower - * than these take 8MP or 6MP espectively for down scaling based on the - * aspect ratio. - */ -struct imx_resolution imx135_res_preview_mofd[] = { - { - .desc = "imx135_cif_binning_preview", - .regs = imx135_cif_binning, - .width = 368, - .height = 304, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 9114, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_vga_binning_preview", - .regs = imx135_vga_binning, - .width = 1036, - .height = 780, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_480p_preview", - .regs = imx135_480p_binning, - .width = 1036, - .height = 696, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_1080p_binning_preview", - .regs = imx135_1080p_binning, - .width = 1936, - .height = 1104, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_3m__cont_cap", - .regs = imx135_3m_binning, - .width = 2064, - .height = 1552, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_6m_cont_cap", - .regs = imx135_6m, - .width = 3280, - .height = 1852, - .fps_options = { - { /* Binning Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_8m_scaled_from_12m__cont_cap", - .regs = imx135_8m_scaled_from_12m, - .width = 3280, - .height = 2464, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 24, - .pixels_per_line = 4572, - .lines_per_frame = 3280, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_10m__cont_cap", - .regs = imx135_10m, - .width = 4208, - .height = 2368, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2632, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_13m__cont_cap", - .regs = imx135_13m, - .width = 4208, - .height = 3120, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 24, - .pixels_per_line = 4572, - .lines_per_frame = 3290, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, -}; - -struct imx_resolution imx135_res_preview[] = { - { - .desc = "imx135_xga_cropped_video", - .regs = imx135_xga_cropped, - .width = 832, - .height = 628, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_2m_cropped_video", - .regs = imx135_2m_cropped, - .width = 1648, - .height = 1240, - .fps_options = { - { /* Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_1936x1096_cropped", - .regs = imx135_1936x1096_cropped, - .width = 1936, - .height = 1096, - .fps_options = { - { /* Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_8m_cropped_video", - .regs = imx135_8m_cropped, - .width = 3280, - .height = 2464, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, -}; - -/* - * ISP Scaling is now supported in online capture use cases. Because of that - * we need only few modes to cover the different aspect ratios from the - * sensor and the ISP will scale it based on the requested resolution from HAL. - * - * There is a performance impact when continuous view finder option is chose - * for resolutions above 8MP. So 8MP and 6MP resolution are kept, so that lower - * than these take 8MP or 6MP espectively for down scaling based on the - * aspect ratio. - */ -struct imx_resolution imx135_res_still_mofd[] = { - { - .desc = "imx135_cif_binning_still", - .regs = imx135_cif_binning_1888x1548, - .width = 1888, - .height = 1548, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 209600, - }, - { - .desc = "imx135_vga_binning_preview", - .regs = imx135_vga_binning, - .width = 1036, - .height = 780, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_480p_preview", - .regs = imx135_480p_binning, - .width = 1036, - .height = 696, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_1080p_binning_still", - .regs = imx135_1080p_binning, - .width = 1936, - .height = 1104, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 15, - .pixels_per_line = 9114, - .lines_per_frame = 2453, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_3m__still", - .regs = imx135_3m_binning, - .width = 2064, - .height = 1552, - .fps_options = { - { /* Binning Pixel clock: 335.36MHz */ - .fps = 15, - .pixels_per_line = 9114, - .lines_per_frame = 2453, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 209600, - }, - { - .desc = "imx135_6m_for_mipi_342_still", - .regs = imx135_6m_for_mipi_342, - .width = 3280, - .height = 1852, - .fps_options = { - { /* Pixel clock: 273.6MHz */ - .fps = 11, - .pixels_per_line = 9114, - .lines_per_frame = 2664, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 342000, - }, - { - .desc = "imx135_8m_scaled_from_12m_for_mipi342_still", - .regs = imx135_8m_scaled_from_12m_for_mipi342, - .width = 3280, - .height = 2464, - .fps_options = { - { /* Pixel clock: 273.6MHz */ - .fps = 8, - .pixels_per_line = 7672, - .lines_per_frame = 4458, - }, - { /* Pixel clock: 273.6MHz */ - .fps = 15, - .pixels_per_line = 5500, - .lines_per_frame = 3314, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 342000, - }, - { - .desc = "imx135_10m_for_mipi_342_still", - .regs = imx135_10m_for_mipi_342, - .width = 4208, - .height = 2368, - .fps_options = { - { /* Pixel clock: 273.6MHz */ - .fps = 11, - .pixels_per_line = 9144, - .lines_per_frame = 2664, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 342000, - }, - { - .desc = "imx135_13m_still", - .regs = imx135_13m_for_mipi_342, - .width = 4208, - .height = 3120, - .fps_options = { - { /* Pixel clock: 273.6MHz */ - .fps = 5, - .pixels_per_line = 9144, - .lines_per_frame = 5990, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 342000, - }, -}; - -struct imx_resolution imx135_res_still[] = { - { - .desc = "imx135_qvga", - .regs = imx135_336x256, - .width = 336, - .height = 256, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_cif", - .regs = imx135_368x304_cropped, - .width = 368, - .height = 304, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_xga_cropped_video", - .regs = imx135_xga_cropped, - .width = 832, - .height = 628, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_2M_for_11:9", - .regs = imx135_1424x1168_cropped, - .width = 1424, - .height = 1168, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_2m_cropped_video", - .regs = imx135_2m_cropped, - .width = 1648, - .height = 1240, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 15, - .pixels_per_line = 6466, - .lines_per_frame = 3710, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_6m_cropped_video", - .regs = imx135_6m_cropped, - .width = 3280, - .height = 1852, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 8, - .pixels_per_line = 8850, - .lines_per_frame = 5080, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_8m_cropped_video", - .regs = imx135_8m_cropped, - .width = 3280, - .height = 2464, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 8, - .pixels_per_line = 8850, - .lines_per_frame = 5080, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, -}; - -/* - * ISP scaling is not supported in case of video modes. So we need to have - * separate sensor mode for video use cases - */ -struct imx_resolution imx135_res_video[] = { - /* For binning modes pix clock is 335.36 MHz. */ - { - .desc = "imx135_qcif_dvs_binning_video", - .regs = imx135_qcif_dvs_binning, - .width = 216, - .height = 176, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_cif_binning_video", - .regs = imx135_cif_binning, - .width = 368, - .height = 304, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_qvga__dvs_binning_video", - .regs = imx135_qvga__dvs_binning, - .width = 408, - .height = 308, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_436x360_binning_video", - .regs = imx135_436x360_binning, - .width = 436, - .height = 360, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_vga_dvs_binning_video", - .regs = imx135_vga_dvs_binning, - .width = 820, - .height = 616, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 9144, - .lines_per_frame = 1226, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 209600, - }, - { - .desc = "imx135_480p_dvs_binning_video", - .regs = imx135_480p_dvs_binning, - .width = 936, - .height = 602, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 209600, - }, - { - .desc = "imx135_720P_dvs_video", - .regs = imx135_720pdvs_max_clock, - .width = 1568, - .height = 880, - .fps_options = { - {/* Pixel Clock : 360.96 MHz */ - .fps = 30, - .pixels_per_line = 5850, - .lines_per_frame = 2000, - }, - {/* Pixel Clock : 360.96 MHz */ - .fps = 60, - .pixels_per_line = 4572, - .lines_per_frame = 1310, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 451200, - }, - { - .desc = "imx135_wvga_dvs_binning_video", - .regs = imx135_wvga_dvs_binning, - .width = 1640, - .height = 1024, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 5464, - .lines_per_frame = 2046, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 209600, - }, - { - .desc = "imx135_1936_1096_fullfov_max_clock", - .regs = imx135_1080p_nodvs_max_clock, - .width = 1936, - .height = 1096, - .fps_options = { - {/* Pixel Clock : 360.96 MHz */ - .fps = 30, - .pixels_per_line = 5850, - .lines_per_frame = 2000, - }, - {/* Pixel Clock : 360.96 MHz */ - .fps = 60, - .pixels_per_line = 4572, - .lines_per_frame = 1310, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 451200, - }, - { - .desc = "imx135_1080P_dvs_video", - .regs = imx135_2336x1320_max_clock, - .width = 2336, - .height = 1320, - .fps_options = { - {/* Pixel Clock : 360.96 MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2632, - .regs = imx135_2336x1320_max_clock, - .mipi_freq = 451200, - }, - {/* Pixel Clock : 399.36MHz */ - .fps = 60, - .pixels_per_line = 4754, - .lines_per_frame = 1400, - .regs = imx135_2336x1320_cropped_mipi499, - .mipi_freq = 499200, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_6m_cont_cap", - .regs = imx135_6m, - .width = 3280, - .height = 1852, - .fps_options = { - { /* Binning Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, - { - .desc = "imx135_8m_cropped_video", - .regs = imx135_8m_cropped, - .width = 3280, - .height = 2464, - .fps_options = { - { /* Pixel clock: 360.96MHz */ - .fps = 30, - .pixels_per_line = 4572, - .lines_per_frame = 2624, - }, - { - } - }, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .mipi_freq = 451200, - }, -}; - -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/imx175.h b/drivers/staging/media/atomisp/i2c/imx/imx175.h deleted file mode 100644 index 5e082088cb37..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx175.h +++ /dev/null @@ -1,1960 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IMX175_H__ -#define __IMX175_H__ -#include "common.h" - -/************************** settings for imx *************************/ -static struct imx_reg const imx_STILL_8M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xC4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x66}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0C}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0xD0}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x09}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xA0}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_8M_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0B}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xB8}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x16}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x44}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0C}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0xD0}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x09}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xA0}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_3M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xC4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x66}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x08}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x06}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x10}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x19}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_3M_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0B}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xB8}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x16}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x44}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x08}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x06}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x10}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x19}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - - -static struct imx_reg const imx_STILL_5M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xC4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x66}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0A}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x07}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x90}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x14}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_5M_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0B}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xB8}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x16}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x44}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0A}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x07}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x90}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x14}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_6M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xC4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x66}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x32}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x6D}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0C}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0xD0}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x07}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x3C}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_6M_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEF}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0B}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xB8}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x16}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x44}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x32}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x6D}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x0C}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0xD0}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x07}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x3C}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_2M_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x8C}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xC4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x66}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x68}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xD0}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_2M_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x0A}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x8C}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x2c}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0B}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xB8}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x16}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x44}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x68}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xD0}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x77}, - {IMX_8BIT, 0x3371, 0x2F}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x2F}, - {IMX_8BIT, 0x3375, 0x37}, - {IMX_8BIT, 0x3376, 0x9F}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x09}, - {IMX_8BIT, 0x33D7, 0xA0}, - - {IMX_8BIT, 0x030e, 0x01}, - {IMX_8BIT, 0x41c0, 0x01}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_PREVIEW_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x06}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x05}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x48}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x70}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x03}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x34}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x02}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x68}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x03}, - {IMX_8BIT, 0x33D5, 0x34}, - {IMX_8BIT, 0x33D6, 0x02}, - {IMX_8BIT, 0x33D7, 0x68}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_WIDE_PREVIEW_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x06}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x0D}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x70}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x10}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x00}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x14}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x8C}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x68}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x03}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xBC}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x68}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0xBC}, - {IMX_TOK_TERM, 0, 0} -}; - -/*****************************video************************/ -static struct imx_reg const imx_1080p_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x06}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x4C}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xA4}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x11}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0xC6}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x01}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0xDB}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x02}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x42}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0A}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xEA}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x07}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x61}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x09}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x05}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x20}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_1080p_no_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x08}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xD5}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x07}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xD0}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0F}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x3C}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x34}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x6B}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x07}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x94}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x44}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x1B}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_1080p_no_dvs_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x08}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xD5}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x09}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xA6}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x18}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x9C}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x34}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x6B}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x07}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x94}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x44}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x1B}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; -/*****************************video************************/ -static struct imx_reg const imx_720p_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x00}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x13}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x9C}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x01}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0xD7}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x02}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x3E}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0A}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xEE}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x07}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x65}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x03}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x70}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x00}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x18}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_480p_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x00}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x13}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x9C}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x01}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0xD4}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0xC8}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0A}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xF1}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x07}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0xDB}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x03}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x70}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x02}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x50}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x02}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x15}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_720p_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x04}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x05}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x48}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x14}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x28}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x48}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x64}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0x87}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x3B}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x20}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x03}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x6C}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x20}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0x6C}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_STILL_720p_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x04}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x08}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0xCA}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x18}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x38}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x48}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x64}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0x87}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x3B}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x20}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x03}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x6C}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x20}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0x6C}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_WVGA_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xEC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x09}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x01}, - {IMX_8BIT, 0x030D, 0x12}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x00}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x13}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x9C}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0xD0}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x08}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0xCF}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x06}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x68}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x00}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x01}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x57}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x6F}, - {IMX_8BIT, 0x3371, 0x27}, - {IMX_8BIT, 0x3372, 0x4F}, - {IMX_8BIT, 0x3373, 0x2F}, - {IMX_8BIT, 0x3374, 0x27}, - {IMX_8BIT, 0x3375, 0x2F}, - {IMX_8BIT, 0x3376, 0x97}, - {IMX_8BIT, 0x3377, 0x37}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x0C}, - {IMX_8BIT, 0x33D5, 0xD0}, - {IMX_8BIT, 0x33D6, 0x07}, - {IMX_8BIT, 0x33D7, 0x38}, - {IMX_TOK_TERM, 0, 0} -}; -static struct imx_reg const imx_CIF_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x04}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x00}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x11}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0xDB}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x01}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x70}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x01}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x30}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x20}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0x6C}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_VGA_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x04}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x06}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x00}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x11}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x94}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x03}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x34}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x02}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x68}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x20}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0x6C}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_VGA_strong_dvs_15fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0xFC}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x04}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x07}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x9E}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x1C}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0xB6}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x0C}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0xCF}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x09}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x9F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x03}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x34}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x02}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x68}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x06}, - {IMX_8BIT, 0x33D5, 0x20}, - {IMX_8BIT, 0x33D6, 0x03}, - {IMX_8BIT, 0x33D7, 0x6C}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_QVGA_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x06}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x05}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x48}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x70}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x03}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0x38}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x02}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x68}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x09}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0x97}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x07}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x37}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x01}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0x98}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x01}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0x34}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x01}, - {IMX_8BIT, 0x33D5, 0x98}, - {IMX_8BIT, 0x33D6, 0x01}, - {IMX_8BIT, 0x33D7, 0x34}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_QCIF_strong_dvs_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - /* shutter */ - {IMX_8BIT, 0x0202, 0x05}, /* coarse _integration_time[15:8] */ - {IMX_8BIT, 0x0203, 0x44}, /* coarse _integration_time[7:0] */ - /* pll */ - {IMX_8BIT, 0x0301, 0x05}, /* vt_pix_clk_div[7:0] */ - {IMX_8BIT, 0x0303, 0x01}, /* vt_sys_clk_div[7:0] */ - {IMX_8BIT, 0x0305, 0x06}, /* pre_pll_clk_div[7:0] */ - {IMX_8BIT, 0x0309, 0x05}, /* op_pix_clk_div[7:0] */ - {IMX_8BIT, 0x030B, 0x01}, /* op_sys_clk_div[7:0] */ - {IMX_8BIT, 0x030C, 0x00}, - {IMX_8BIT, 0x030D, 0x6D}, - /* image sizing */ - {IMX_8BIT, 0x0340, 0x05}, /* frame_length_lines[15:8] */ - {IMX_8BIT, 0x0341, 0x48}, /* frame_length_lines[7:0] */ - {IMX_8BIT, 0x0342, 0x0D}, /* line_length_pck[15:8] */ - {IMX_8BIT, 0x0343, 0x70}, /* line_length_pck[7:0] */ - {IMX_8BIT, 0x0344, 0x04}, /* x_addr_start[15:8] */ - {IMX_8BIT, 0x0345, 0xB8}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x03}, /* y_addr_start[15:8] */ - {IMX_8BIT, 0x0347, 0x70}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x08}, /* x_addr_end[15:8] */ - {IMX_8BIT, 0x0349, 0x17}, /* x_addr_end[7:0] */ - {IMX_8BIT, 0x034A, 0x06}, /* y_addr_end[15:8] */ - {IMX_8BIT, 0x034B, 0x2F}, /* y_addr_end[7:0] */ - {IMX_8BIT, 0x034C, 0x00}, /* x_output_size[15:8] */ - {IMX_8BIT, 0x034D, 0xD8}, /* x_output_size[7:0] */ - {IMX_8BIT, 0x034E, 0x00}, /* y_output_size[15:8] */ - {IMX_8BIT, 0x034F, 0xB0}, /* y_output_size[7:0] */ - /* binning & scaling */ - {IMX_8BIT, 0x0390, 0x02}, /* binning mode */ - {IMX_8BIT, 0x0401, 0x00}, /* scaling mode*/ - {IMX_8BIT, 0x0405, 0x10}, /* scale_m[7:0] */ - /* timer */ - {IMX_8BIT, 0x3344, 0x37}, - {IMX_8BIT, 0x3345, 0x1F}, - /* timing */ - {IMX_8BIT, 0x3370, 0x5F}, - {IMX_8BIT, 0x3371, 0x17}, - {IMX_8BIT, 0x3372, 0x37}, - {IMX_8BIT, 0x3373, 0x17}, - {IMX_8BIT, 0x3374, 0x17}, - {IMX_8BIT, 0x3375, 0x0F}, - {IMX_8BIT, 0x3376, 0x57}, - {IMX_8BIT, 0x3377, 0x27}, - {IMX_8BIT, 0x33C8, 0x01}, - {IMX_8BIT, 0x33D4, 0x00}, - {IMX_8BIT, 0x33D5, 0xD8}, - {IMX_8BIT, 0x33D6, 0x00}, - {IMX_8BIT, 0x33D7, 0xB0}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx175_init_settings[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0103, 0x01}, - /* misc control */ - {IMX_8BIT, 0x3020, 0x10}, - {IMX_8BIT, 0x302D, 0x02}, - {IMX_8BIT, 0x302F, 0x80}, - {IMX_8BIT, 0x3032, 0xA3}, - {IMX_8BIT, 0x3033, 0x20}, - {IMX_8BIT, 0x3034, 0x24}, - {IMX_8BIT, 0x3041, 0x15}, - {IMX_8BIT, 0x3042, 0x87}, - {IMX_8BIT, 0x3050, 0x35}, - {IMX_8BIT, 0x3056, 0x57}, - {IMX_8BIT, 0x305D, 0x41}, - {IMX_8BIT, 0x3097, 0x69}, - {IMX_8BIT, 0x3109, 0x41}, - {IMX_8BIT, 0x3148, 0x3F}, - {IMX_8BIT, 0x330F, 0x07}, - /* csi & inck */ - {IMX_8BIT, 0x3364, 0x00}, - {IMX_8BIT, 0x3368, 0x13}, - {IMX_8BIT, 0x3369, 0x33}, - /* znr */ - {IMX_8BIT, 0x4100, 0x0E}, - {IMX_8BIT, 0x4104, 0x32}, - {IMX_8BIT, 0x4105, 0x32}, - {IMX_8BIT, 0x4108, 0x01}, - {IMX_8BIT, 0x4109, 0x7C}, - {IMX_8BIT, 0x410A, 0x00}, - {IMX_8BIT, 0x410B, 0x00}, - GROUPED_PARAMETER_HOLD_DISABLE, - {IMX_TOK_TERM, 0, 0} -}; -/* TODO settings of preview/still/video will be updated with new use case */ -struct imx_resolution imx175_res_preview[] = { - { - .desc = "CIF_strong_dvs_30fps", - .regs = imx_CIF_strong_dvs_30fps, - .width = 368, - .height = 304, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x11DB, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 261500, - - }, - { - .desc = "VGA_strong_dvs_30fps", - .regs = imx_VGA_strong_dvs_30fps, - .width = 820, - .height = 616, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x11DB, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 261500, - }, - { - .desc = "WIDE_PREVIEW_30fps", - .regs = imx_WIDE_PREVIEW_30fps, - .width = 1640, - .height = 956, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x1000, - .lines_per_frame = 0x0D70, - }, - { - } - }, - .mipi_freq = 174500, - }, - { - .desc = "STILL_720p_30fps", - .regs = imx_STILL_720p_30fps, - .width = 1568, - .height = 876, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x1428, - .lines_per_frame = 0x0548, - }, - { - } - }, - .mipi_freq = 261500, - }, - { - .desc = "STILL_2M_30fps", - .regs = imx_STILL_2M_30fps, - .width = 1640, - .height = 1232, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D66, - .lines_per_frame = 0x09C4, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "1080p_strong_dvs_30fps", - .regs = imx_1080p_no_dvs_30fps, - .width = 1940, - .height = 1092, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0F3C, - .lines_per_frame = 0x07D0, - }, - { - } - }, - .mipi_freq = 292500, - }, - { - .desc = "STILL_3M_30fps", - .regs = imx_STILL_3M_30fps, - .width = 2064, - .height = 1552, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D66, - .lines_per_frame = 0x09C4, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_5M_30fps", - .regs = imx_STILL_5M_30fps, - .width = 2576, - .height = 1936, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D66, - .lines_per_frame = 0x09C4, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_6M_30fps", - .regs = imx_STILL_6M_30fps, - .width = 3280, - .height = 1852, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D66, - .lines_per_frame = 0x09C4, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_8M_30fps", - .regs = imx_STILL_8M_30fps, - .width = 3280, - .height = 2464, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D66, - .lines_per_frame = 0x09C4, - }, - { - } - }, - .mipi_freq = 320000, - }, -}; - -struct imx_resolution imx175_res_still[] = { - { - .desc = "CIF_strong_dvs_30fps", - .regs = imx_CIF_strong_dvs_30fps, - .width = 368, - .height = 304, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x11DB, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 261000, - }, - { - .desc = "VGA_strong_dvs_15fps", - .regs = imx_VGA_strong_dvs_15fps, - .width = 820, - .height = 616, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1C86, - .lines_per_frame = 0x079E, - }, - { - } - }, - .mipi_freq = 261500, - }, - { - .desc = "imx_STILL_720p_15fps", - .regs = imx_STILL_720p_15fps, - .width = 1568, - .height = 876, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1838, - .lines_per_frame = 0x08CA, - }, - { - } - }, - .mipi_freq = 261500, - }, - { - .desc = "STILL_2M_15fps", - .regs = imx_STILL_2M_15fps, - .width = 1640, - .height = 1232, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1646, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "1080p_strong_dvs_15fps", - .regs = imx_1080p_no_dvs_15fps, - .width = 1940, - .height = 1092, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x189C, - .lines_per_frame = 0x09A6, - }, - { - } - }, - .mipi_freq = 292500, - }, - { - .desc = "STILL_3M_15fps", - .regs = imx_STILL_3M_15fps, - .width = 2064, - .height = 1552, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1646, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_5M_15fps", - .regs = imx_STILL_5M_15fps, - .width = 2576, - .height = 1936, - .fps = 15, - .pixels_per_line = 0x1646, /* consistent with regs arrays */ - .lines_per_frame = 0x0BB8, /* consistent with regs arrays */ - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1646, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_6M_15fps", - .regs = imx_STILL_6M_15fps, - .width = 3280, - .height = 1852, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1646, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - .mipi_freq = 320000, - }, - { - .desc = "STILL_8M_15fps", - .regs = imx_STILL_8M_15fps, - .width = 3280, - .height = 2464, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 15, - .pixels_per_line = 0x1646, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - .mipi_freq = 320000, - }, -}; - -struct imx_resolution imx175_res_video[] = { - { - .desc = "QCIF_strong_dvs_30fps", - .regs = imx_QCIF_strong_dvs_30fps, - .width = 216, - .height = 176, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D70, - .lines_per_frame = 0x0548, - }, - { - } - }, - .mipi_freq = 174500, - }, - { - .desc = "QVGA_strong_dvs_30fps", - .regs = imx_QVGA_strong_dvs_30fps, - .width = 408, - .height = 308, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D70, - .lines_per_frame = 0x0548, - }, - { - } - }, - .mipi_freq = 174500, - }, - { - .desc = "VGA_strong_dvs_30fps", - .regs = imx_VGA_strong_dvs_30fps, - .width = 820, - .height = 616, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x1194, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 261500, - }, - { - .desc = "720p_strong_dvs_30fps", - .regs = imx_720p_strong_dvs_30fps, - .width = 1552, - .height = 880, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x139C, - .lines_per_frame = 0x0600, - }, - { - .fps = 60, - .pixels_per_line = 0xD70, - .lines_per_frame = 0x444, - }, - { - } - }, - .mipi_freq = 292500, - }, - { - .desc = "480p_strong_dvs_30fps", - .regs = imx_480p_strong_dvs_30fps, - .width = 880, - .height = 592, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x139C, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 292500, - }, - { - .desc = "WVGA_strong_dvs_30fps", - .regs = imx_WVGA_strong_dvs_30fps, - .width = 1640, - .height = 1024, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x139C, - .lines_per_frame = 0x0600, - }, - { - } - }, - .mipi_freq = 292500, - }, - { - .desc = "1080p_strong_dvs_30fps", - .regs = imx_1080p_strong_dvs_30fps, - .width = 2320, - .height = 1312, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x11C6, - .lines_per_frame = 0x06A4, - }, - { - } - }, - .mipi_freq = 292500, - }, -}; - -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/imx208.h b/drivers/staging/media/atomisp/i2c/imx/imx208.h deleted file mode 100644 index fed387f42f99..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx208.h +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Support for Sony IMX camera sensor. - * - * Copyright (c) 2014 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#ifndef __IMX208_H__ -#define __IMX208_H__ -#include "common.h" - -/********************** settings for imx from vendor*********************/ -static struct imx_reg imx208_1080p_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0305, 0x02}, /* PREPLLCK DIV */ - {IMX_8BIT, 0x0307, 0x54}, /* PLL MPY */ - {IMX_8BIT, 0x303C, 0x3C}, /* PLL oscillation stable wait time */ - {IMX_8BIT, 0x30A4, 0x02}, /* Default */ - {IMX_8BIT, 0x0112, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0113, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0340, 0x04}, /* frame length line [15:8] */ - {IMX_8BIT, 0x0341, 0xAA}, /* frame length line [7:0] */ - {IMX_8BIT, 0x0342, 0x08}, /* line length pck [15:8] */ - {IMX_8BIT, 0x0343, 0xC8}, /* line length pck [7:0] */ - {IMX_8BIT, 0x0344, 0x00}, /* x_addr_start[12:8] */ - {IMX_8BIT, 0x0345, 0x00}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[12:8] */ - {IMX_8BIT, 0x0347, 0x00}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x07}, /* x_addr_end [12:8] */ - {IMX_8BIT, 0x0349, 0x8F}, /* x_addr_end [7:0] */ - {IMX_8BIT, 0x034A, 0x04}, /* y_addr_end [12:8] */ - {IMX_8BIT, 0x034B, 0x47}, /* y_addr_end [7:0] */ - {IMX_8BIT, 0x034C, 0x07}, /* x_output_size [ 12:8] */ - {IMX_8BIT, 0x034D, 0x90}, /* x_output_size [7:0] */ - {IMX_8BIT, 0x034E, 0x04}, /* y_output_size [11:8] */ - {IMX_8BIT, 0x034F, 0x48}, /* y_output_size [7:0] */ - {IMX_8BIT, 0x0381, 0x01}, /* x_even_inc */ - {IMX_8BIT, 0x0383, 0x01}, /* x_odd_inc */ - {IMX_8BIT, 0x0385, 0x01}, /* y_even_inc */ - {IMX_8BIT, 0x0387, 0x01}, /* y_odd_inc */ - {IMX_8BIT, 0x3048, 0x00}, /* VMODEFDS binning operation */ - {IMX_8BIT, 0x304E, 0x0A}, /* VTPXCK_DIV */ - {IMX_8BIT, 0x3050, 0x02}, /* OPSYCK_DIV */ - {IMX_8BIT, 0x309B, 0x00}, /* RGDAFDSUMEN */ - {IMX_8BIT, 0x30D5, 0x00}, /* HADDEN ( binning ) */ - {IMX_8BIT, 0x3301, 0x01}, /* RGLANESEL */ - {IMX_8BIT, 0x3318, 0x61}, /* MIPI Global Timing */ - {IMX_8BIT, 0x0202, 0x01}, /* coarse integration time */ - {IMX_8BIT, 0x0203, 0x90}, /* coarse integration time */ - {IMX_8BIT, 0x0205, 0x00}, /* ana global gain */ - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx208_1296x736_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0305, 0x02}, /* PREPLLCK DIV */ - {IMX_8BIT, 0x0307, 0x54}, /* PLL MPY */ - {IMX_8BIT, 0x303C, 0x3C}, /* PLL oscillation stable wait time */ - {IMX_8BIT, 0x30A4, 0x02}, /* Default */ - {IMX_8BIT, 0x0112, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0113, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0340, 0x04}, /* frame length line [15:8] */ - {IMX_8BIT, 0x0341, 0xAA}, /* frame length line [7:0] */ - {IMX_8BIT, 0x0342, 0x08}, /* line length pck [15:8] */ - {IMX_8BIT, 0x0343, 0xC8}, /* line length pck [7:0] */ - {IMX_8BIT, 0x0344, 0x01}, /* x_addr_start[12:8] */ - {IMX_8BIT, 0x0345, 0x40}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[12:8] */ - {IMX_8BIT, 0x0347, 0xB4}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x06}, /* x_addr_end [12:8] */ - {IMX_8BIT, 0x0349, 0x4F}, /* x_addr_end [7:0] */ - {IMX_8BIT, 0x034A, 0x03}, /* y_addr_end [12:8] */ - {IMX_8BIT, 0x034B, 0x93}, /* y_addr_end [7:0] */ - {IMX_8BIT, 0x034C, 0x05}, /* x_output_size [ 12:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size [7:0] */ - {IMX_8BIT, 0x034E, 0x02}, /* y_output_size [11:8] */ - {IMX_8BIT, 0x034F, 0xE0}, /* y_output_size [7:0] */ - {IMX_8BIT, 0x0381, 0x01}, /* x_even_inc */ - {IMX_8BIT, 0x0383, 0x01}, /* x_odd_inc */ - {IMX_8BIT, 0x0385, 0x01}, /* y_even_inc */ - {IMX_8BIT, 0x0387, 0x01}, /* y_odd_inc */ - {IMX_8BIT, 0x3048, 0x00}, /* VMODEFDS binning operation */ - {IMX_8BIT, 0x304E, 0x0A}, /* VTPXCK_DIV */ - {IMX_8BIT, 0x3050, 0x02}, /* OPSYCK_DIV */ - {IMX_8BIT, 0x309B, 0x00}, /* RGDAFDSUMEN */ - {IMX_8BIT, 0x30D5, 0x00}, /* HADDEN ( binning ) */ - {IMX_8BIT, 0x3301, 0x01}, /* RGLANESEL */ - {IMX_8BIT, 0x3318, 0x61}, /* MIPI Global Timing */ - {IMX_8BIT, 0x0202, 0x01}, /* coarse integration time */ - {IMX_8BIT, 0x0203, 0x90}, /* coarse integration time */ - {IMX_8BIT, 0x0205, 0x00}, /* ana global gain */ - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx208_1296x976_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0305, 0x02}, /* PREPLLCK DIV */ - {IMX_8BIT, 0x0307, 0x54}, /* PLL MPY */ - {IMX_8BIT, 0x303C, 0x3C}, /* PLL oscillation stable wait time */ - {IMX_8BIT, 0x30A4, 0x02}, /* Default */ - {IMX_8BIT, 0x0112, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0113, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0340, 0x04}, /* frame length line [15:8] */ - {IMX_8BIT, 0x0341, 0xAA}, /* frame length line [7:0] */ - {IMX_8BIT, 0x0342, 0x08}, /* line length pck [15:8] */ - {IMX_8BIT, 0x0343, 0xC8}, /* line length pck [7:0] */ - {IMX_8BIT, 0x0344, 0x01}, /* x_addr_start[12:8] */ - {IMX_8BIT, 0x0345, 0x40}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[12:8] */ - {IMX_8BIT, 0x0347, 0x3C}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x06}, /* x_addr_end [12:8] */ - {IMX_8BIT, 0x0349, 0x4F}, /* x_addr_end [7:0] */ - {IMX_8BIT, 0x034A, 0x04}, /* y_addr_end [12:8] */ - {IMX_8BIT, 0x034B, 0x0B}, /* y_addr_end [7:0] */ - {IMX_8BIT, 0x034C, 0x05}, /* x_output_size [ 12:8] */ - {IMX_8BIT, 0x034D, 0x10}, /* x_output_size [7:0] */ - {IMX_8BIT, 0x034E, 0x03}, /* y_output_size [11:8] */ - {IMX_8BIT, 0x034F, 0xD0}, /* y_output_size [7:0] */ - {IMX_8BIT, 0x0381, 0x01}, /* x_even_inc */ - {IMX_8BIT, 0x0383, 0x01}, /* x_odd_inc */ - {IMX_8BIT, 0x0385, 0x01}, /* y_even_inc */ - {IMX_8BIT, 0x0387, 0x01}, /* y_odd_inc */ - {IMX_8BIT, 0x3048, 0x00}, /* VMODEFDS binning operation */ - {IMX_8BIT, 0x304E, 0x0A}, /* VTPXCK_DIV */ - {IMX_8BIT, 0x3050, 0x02}, /* OPSYCK_DIV */ - {IMX_8BIT, 0x309B, 0x00}, /* RGDAFDSUMEN */ - {IMX_8BIT, 0x30D5, 0x00}, /* HADDEN ( binning ) */ - {IMX_8BIT, 0x3301, 0x01}, /* RGLANESEL */ - {IMX_8BIT, 0x3318, 0x61}, /* MIPI Global Timing */ - {IMX_8BIT, 0x0202, 0x01}, /* coarse integration time */ - {IMX_8BIT, 0x0203, 0x90}, /* coarse integration time */ - {IMX_8BIT, 0x0205, 0x00}, /* ana global gain */ - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx208_336x256_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0305, 0x02}, /* PREPLLCK DIV */ - {IMX_8BIT, 0x0307, 0x54}, /* PLL MPY */ - {IMX_8BIT, 0x303C, 0x3C}, /* PLL oscillation stable wait time */ - {IMX_8BIT, 0x30A4, 0x02}, /* Default */ - {IMX_8BIT, 0x0112, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0113, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0340, 0x04}, /* frame length line [15:8] */ - {IMX_8BIT, 0x0341, 0xAA}, /* frame length line [7:0] */ - {IMX_8BIT, 0x0342, 0x08}, /* line length pck [15:8] */ - {IMX_8BIT, 0x0343, 0xC8}, /* line length pck [7:0] */ - {IMX_8BIT, 0x0344, 0x02}, /* x_addr_start[12:8] */ - {IMX_8BIT, 0x0345, 0x78}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x01}, /* y_addr_start[12:8] */ - {IMX_8BIT, 0x0347, 0x24}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x05}, /* x_addr_end [12:8] */ - {IMX_8BIT, 0x0349, 0x17}, /* x_addr_end [7:0] */ - {IMX_8BIT, 0x034A, 0x03}, /* y_addr_end [12:8] */ - {IMX_8BIT, 0x034B, 0x23}, /* y_addr_end [7:0] */ - {IMX_8BIT, 0x034C, 0x01}, /* x_output_size [ 12:8] */ - {IMX_8BIT, 0x034D, 0x50}, /* x_output_size [7:0] */ - {IMX_8BIT, 0x034E, 0x01}, /* y_output_size [11:8] */ - {IMX_8BIT, 0x034F, 0x00}, /* y_output_size [7:0] */ - {IMX_8BIT, 0x0381, 0x01}, /* x_even_inc */ - {IMX_8BIT, 0x0383, 0x03}, /* x_odd_inc */ - {IMX_8BIT, 0x0385, 0x01}, /* y_even_inc */ - {IMX_8BIT, 0x0387, 0x03}, /* y_odd_inc */ - {IMX_8BIT, 0x3048, 0x01}, /* VMODEFDS binning operation */ - {IMX_8BIT, 0x304E, 0x0A}, /* VTPXCK_DIV */ - {IMX_8BIT, 0x3050, 0x02}, /* OPSYCK_DIV */ - {IMX_8BIT, 0x309B, 0x00}, /* RGDAFDSUMEN */ - {IMX_8BIT, 0x30D5, 0x03}, /* HADDEN ( binning ) */ - {IMX_8BIT, 0x3301, 0x01}, /* RGLANESEL */ - {IMX_8BIT, 0x3318, 0x66}, /* MIPI Global Timing */ - {IMX_8BIT, 0x0202, 0x01}, /* coarse integration time */ - {IMX_8BIT, 0x0203, 0x90}, /* coarse integration time */ - {IMX_8BIT, 0x0205, 0x00}, /* ana global gain */ - - {IMX_TOK_TERM, 0, 0}, -}; - -static struct imx_reg imx208_192x160_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0305, 0x02}, /* PREPLLCK DIV */ - {IMX_8BIT, 0x0307, 0x54}, /* PLL MPY */ - {IMX_8BIT, 0x303C, 0x3C}, /* PLL oscillation stable wait time */ - {IMX_8BIT, 0x30A4, 0x02}, /* Default */ - {IMX_8BIT, 0x0112, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0113, 0x0A}, /* CCP_data_format : RAW 10bit */ - {IMX_8BIT, 0x0340, 0x04}, /* frame length line [15:8] */ - {IMX_8BIT, 0x0341, 0xAA}, /* frame length line [7:0] */ - {IMX_8BIT, 0x0342, 0x08}, /* line length pck [15:8] */ - {IMX_8BIT, 0x0343, 0xC8}, /* line length pck [7:0] */ - {IMX_8BIT, 0x0344, 0x02}, /* x_addr_start[12:8] */ - {IMX_8BIT, 0x0345, 0x48}, /* x_addr_start[7:0] */ - {IMX_8BIT, 0x0346, 0x00}, /* y_addr_start[12:8] */ - {IMX_8BIT, 0x0347, 0xE4}, /* y_addr_start[7:0] */ - {IMX_8BIT, 0x0348, 0x05}, /* x_addr_end [12:8] */ - {IMX_8BIT, 0x0349, 0x47}, /* x_addr_end [7:0] */ - {IMX_8BIT, 0x034A, 0x03}, /* y_addr_end [12:8] */ - {IMX_8BIT, 0x034B, 0x63}, /* y_addr_end [7:0] */ - {IMX_8BIT, 0x034C, 0x00}, /* x_output_size [ 12:8] */ - {IMX_8BIT, 0x034D, 0xC0}, /* x_output_size [7:0] */ - {IMX_8BIT, 0x034E, 0x00}, /* y_output_size [11:8] */ - {IMX_8BIT, 0x034F, 0xA0}, /* y_output_size [7:0] */ - {IMX_8BIT, 0x0381, 0x03}, /* x_even_inc */ - {IMX_8BIT, 0x0383, 0x05}, /* x_odd_inc */ - {IMX_8BIT, 0x0385, 0x03}, /* y_even_inc */ - {IMX_8BIT, 0x0387, 0x05}, /* y_odd_inc */ - {IMX_8BIT, 0x3048, 0x01}, /* VMODEFDS binning operation */ - {IMX_8BIT, 0x304E, 0x0A}, /* VTPXCK_DIV */ - {IMX_8BIT, 0x3050, 0x02}, /* OPSYCK_DIV */ - {IMX_8BIT, 0x309B, 0x00}, /* RGDAFDSUMEN */ - {IMX_8BIT, 0x30D5, 0x03}, /* HADDEN ( binning ) */ - {IMX_8BIT, 0x3301, 0x11}, /* RGLANESEL */ - {IMX_8BIT, 0x3318, 0x74}, /* MIPI Global Timing */ - {IMX_8BIT, 0x0202, 0x01}, /* coarse integration time */ - {IMX_8BIT, 0x0203, 0x90}, /* coarse integration time */ - {IMX_8BIT, 0x0205, 0x00}, /* ana global gain */ - - {IMX_TOK_TERM, 0, 0}, -}; -/********************** settings for imx - reference *********************/ -static struct imx_reg const imx208_init_settings[] = { - { IMX_TOK_TERM, 0, 0} -}; - -struct imx_resolution imx208_res_preview[] = { - { - .desc = "imx208_1080p_30fps", - .regs = imx208_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x976_30fps", - .regs = imx208_1296x976_30fps, - .width = 1296, - .height = 976, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x736_30fps", - .regs = imx208_1296x736_30fps, - .width = 1296, - .height = 736, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_336x256_30fps", - .regs = imx208_336x256_30fps, - .width = 336, - .height = 256, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .skip_frames = 2, - .mipi_freq = 201600, - }, - { - .desc = "imx208_192x160_30fps", - .regs = imx208_192x160_30fps, - .width = 192, - .height = 160, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .skip_frames = 2, - .mipi_freq = 100800, - }, -}; - -struct imx_resolution imx208_res_still[] = { - { - .desc = "imx208_1080p_30fps", - .regs = imx208_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x976_30fps", - .regs = imx208_1296x976_30fps, - .width = 1296, - .height = 976, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x736_30fps", - .regs = imx208_1296x736_30fps, - .width = 1296, - .height = 736, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_336x256_30fps", - .regs = imx208_336x256_30fps, - .width = 336, - .height = 256, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .skip_frames = 2, - .mipi_freq = 201600, - }, - { - .desc = "imx208_192x160_30fps", - .regs = imx208_192x160_30fps, - .width = 192, - .height = 160, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .skip_frames = 2, - .mipi_freq = 100800, - }, -}; - -struct imx_resolution imx208_res_video[] = { - { - .desc = "imx208_1080p_30fps", - .regs = imx208_1080p_30fps, - .width = 1936, - .height = 1096, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x976_30fps", - .regs = imx208_1296x976_30fps, - .width = 1296, - .height = 976, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_1296x736_30fps", - .regs = imx208_1296x736_30fps, - .width = 1296, - .height = 736, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 1, - .bin_factor_y = 1, - .used = 0, - .skip_frames = 2, - .mipi_freq = 403200, - }, - { - .desc = "imx208_336x256_30fps", - .regs = imx208_336x256_30fps, - .width = 336, - .height = 256, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 2, - .bin_factor_y = 2, - .used = 0, - .skip_frames = 2, - .mipi_freq = 201600, - }, - { - .desc = "imx208_192x160_30fps", - .regs = imx208_192x160_30fps, - .width = 192, - .height = 160, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x08C8, - .lines_per_frame = 0x04AA, - }, - { - } - }, - .bin_factor_x = 4, - .bin_factor_y = 4, - .used = 0, - .skip_frames = 2, - .mipi_freq = 100800, - }, -}; -#endif - diff --git a/drivers/staging/media/atomisp/i2c/imx/imx219.h b/drivers/staging/media/atomisp/i2c/imx/imx219.h deleted file mode 100644 index bbd515bf7279..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx219.h +++ /dev/null @@ -1,228 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IMX219_H__ -#define __IMX219_H__ -#include "common.h" - -#define IMX219_FRAME_LENGTH_LINES 0x0160 -#define IMX219_LINE_LENGTH_PIXELS 0x0162 -#define IMX219_HORIZONTAL_START_H 0x0164 -#define IMX219_VERTICAL_START_H 0x0168 -#define IMX219_HORIZONTAL_END_H 0x0166 -#define IMX219_VERTICAL_END_H 0x016A -#define IMX219_HORIZONTAL_OUTPUT_SIZE_H 0x016c -#define IMX219_VERTICAL_OUTPUT_SIZE_H 0x016E -#define IMX219_COARSE_INTEGRATION_TIME 0x015A -#define IMX219_IMG_ORIENTATION 0x0172 -#define IMX219_GLOBAL_GAIN 0x0157 -#define IMX219_DGC_ADJ 0x0158 - -#define IMX219_DGC_LEN 4 - -/************************** settings for imx *************************/ -static struct imx_reg const imx219_STILL_8M_30fps[] = { - {IMX_8BIT, 0x30EB, 0x05}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x0C}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x300A, 0xFF}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x300B, 0xFF}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x05}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x09}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x0114, 0x03}, /*CSI_LANE_MODE[1:0}*/ - {IMX_8BIT, 0x0128, 0x00}, /*DPHY_CNTRL*/ - {IMX_8BIT, 0x012A, 0x13}, /*EXCK_FREQ[15:8]*/ - {IMX_8BIT, 0x012B, 0x34}, /*EXCK_FREQ[7:0]*/ - {IMX_8BIT, 0x0160, 0x0A}, /*FRM_LENGTH_A[15:8]*/ - {IMX_8BIT, 0x0161, 0x94}, /*FRM_LENGTH_A[7:0]*/ - {IMX_8BIT, 0x0162, 0x0D}, /*LINE_LENGTH_A[15:8]*/ - {IMX_8BIT, 0x0163, 0x78}, /*LINE_LENGTH_A[7:0]*/ - {IMX_8BIT, 0x0164, 0x00}, /*X_ADD_STA_A[11:8]*/ - {IMX_8BIT, 0x0165, 0x00}, /*X_ADD_STA_A[7:0]*/ - {IMX_8BIT, 0x0166, 0x0C}, /*X_ADD_END_A[11:8]*/ - {IMX_8BIT, 0x0167, 0xCF}, /*X_ADD_END_A[7:0]*/ - {IMX_8BIT, 0x0168, 0x00}, /*Y_ADD_STA_A[11:8]*/ - {IMX_8BIT, 0x0169, 0x00}, /*Y_ADD_STA_A[7:0]*/ - {IMX_8BIT, 0x016A, 0x09}, /*Y_ADD_END_A[11:8]*/ - {IMX_8BIT, 0x016B, 0x9F}, /*Y_ADD_END_A[7:0]*/ - {IMX_8BIT, 0x016C, 0x0C}, /*X_OUTPUT_SIZE_A[11:8]*/ - {IMX_8BIT, 0x016D, 0xD0}, /*X_OUTPUT_SIZE_A[7:0]*/ - {IMX_8BIT, 0x016E, 0x09}, /*Y_OUTPUT_SIZE_A[11:8]*/ - {IMX_8BIT, 0x016F, 0xA0}, /*Y_OUTPUT_SIZE_A[7:0]*/ - {IMX_8BIT, 0x0170, 0x01}, /*X_ODD_INC_A[2:0]*/ - {IMX_8BIT, 0x0171, 0x01}, /*Y_ODD_INC_A[2:0]*/ - {IMX_8BIT, 0x0174, 0x00}, /*BINNING_MODE_H_A*/ - {IMX_8BIT, 0x0175, 0x00}, /*BINNING_MODE_V_A*/ - {IMX_8BIT, 0x018C, 0x0A}, /*CSI_DATA_FORMAT_A[15:8]*/ - {IMX_8BIT, 0x018D, 0x0A}, /*CSI_DATA_FORMAT_A[7:0]*/ - {IMX_8BIT, 0x0301, 0x05}, /*VTPXCK_DIV*/ - {IMX_8BIT, 0x0303, 0x01}, /*VTSYCK_DIV*/ - {IMX_8BIT, 0x0304, 0x02}, /*PREPLLCK_VT_DIV[3:0]*/ - {IMX_8BIT, 0x0305, 0x02}, /*PREPLLCK_OP_DIV[3:0]*/ - {IMX_8BIT, 0x0306, 0x00}, /*PLL_VT_MPY[10:8]*/ - {IMX_8BIT, 0x0307, 0x49}, /*PLL_VT_MPY[7:0]*/ - {IMX_8BIT, 0x0309, 0x0A}, /*OPPXCK_DIV[4:0]*/ - {IMX_8BIT, 0x030B, 0x01}, /*OPSYCK_DIV*/ - {IMX_8BIT, 0x030C, 0x00}, /*PLL_OP_MPY[10:8]*/ - {IMX_8BIT, 0x030D, 0x4C}, /*PLL_OP_MPY[7:0]*/ - {IMX_8BIT, 0x4767, 0x0F}, /*CIS Tuning*/ - {IMX_8BIT, 0x4750, 0x14}, /*CIS Tuning*/ - {IMX_8BIT, 0x47B4, 0x14}, /*CIS Tuning*/ - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx219_STILL_6M_30fps[] = { - {IMX_8BIT, 0x30EB, 0x05}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x0C}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x300A, 0xFF}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x300B, 0xFF}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x05}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x30EB, 0x09}, /*Access Code for address over 0x3000*/ - {IMX_8BIT, 0x0114, 0x03}, /*CSI_LANE_MODE[1:0}*/ - {IMX_8BIT, 0x0128, 0x00}, /*DPHY_CNTRL*/ - {IMX_8BIT, 0x012A, 0x13}, /*EXCK_FREQ[15:8]*/ - {IMX_8BIT, 0x012B, 0x34}, /*EXCK_FREQ[7:0]*/ - {IMX_8BIT, 0x0160, 0x07}, /*FRM_LENGTH_A[15:8]*/ - {IMX_8BIT, 0x0161, 0x64}, /*FRM_LENGTH_A[7:0]*/ - {IMX_8BIT, 0x0162, 0x0D}, /*LINE_LENGTH_A[15:8]*/ - {IMX_8BIT, 0x0163, 0x78}, /*LINE_LENGTH_A[7:0]*/ - {IMX_8BIT, 0x0164, 0x00}, /*X_ADD_STA_A[11:8]*/ - {IMX_8BIT, 0x0165, 0x00}, /*X_ADD_STA_A[7:0]*/ - {IMX_8BIT, 0x0166, 0x0C}, /*X_ADD_END_A[11:8]*/ - {IMX_8BIT, 0x0167, 0xCF}, /*X_ADD_END_A[7:0]*/ - {IMX_8BIT, 0x0168, 0x01}, /*Y_ADD_STA_A[11:8]*/ - {IMX_8BIT, 0x0169, 0x32}, /*Y_ADD_STA_A[7:0]*/ - {IMX_8BIT, 0x016A, 0x08}, /*Y_ADD_END_A[11:8]*/ - {IMX_8BIT, 0x016B, 0x6D}, /*Y_ADD_END_A[7:0]*/ - {IMX_8BIT, 0x016C, 0x0C}, /*X_OUTPUT_SIZE_A[11:8]*/ - {IMX_8BIT, 0x016D, 0xD0}, /*X_OUTPUT_SIZE_A[7:0]*/ - {IMX_8BIT, 0x016E, 0x07}, /*Y_OUTPUT_SIZE_A[11:8]*/ - {IMX_8BIT, 0x016F, 0x3C}, /*Y_OUTPUT_SIZE_A[7:0]*/ - {IMX_8BIT, 0x0170, 0x01}, /*X_ODD_INC_A[2:0]*/ - {IMX_8BIT, 0x0171, 0x01}, /*Y_ODD_INC_A[2:0]*/ - {IMX_8BIT, 0x0174, 0x00}, /*BINNING_MODE_H_A*/ - {IMX_8BIT, 0x0175, 0x00}, /*BINNING_MODE_V_A*/ - {IMX_8BIT, 0x018C, 0x0A}, /*CSI_DATA_FORMAT_A[15:8]*/ - {IMX_8BIT, 0x018D, 0x0A}, /*CSI_DATA_FORMAT_A[7:0]*/ - {IMX_8BIT, 0x0301, 0x05}, /*VTPXCK_DIV*/ - {IMX_8BIT, 0x0303, 0x01}, /*VTSYCK_DIV*/ - {IMX_8BIT, 0x0304, 0x02}, /*PREPLLCK_VT_DIV[3:0]*/ - {IMX_8BIT, 0x0305, 0x02}, /*PREPLLCK_OP_DIV[3:0]*/ - {IMX_8BIT, 0x0306, 0x00}, /*PLL_VT_MPY[10:8]*/ - {IMX_8BIT, 0x0307, 0x33}, /*PLL_VT_MPY[7:0]*/ - {IMX_8BIT, 0x0309, 0x0A}, /*OPPXCK_DIV[4:0]*/ - {IMX_8BIT, 0x030B, 0x01}, /*OPSYCK_DIV*/ - {IMX_8BIT, 0x030C, 0x00}, /*PLL_OP_MPY[10:8]*/ - {IMX_8BIT, 0x030D, 0x36}, /*PLL_OP_MPY[7:0]*/ - {IMX_8BIT, 0x4767, 0x0F}, /*CIS Tuning*/ - {IMX_8BIT, 0x4750, 0x14}, /*CIS Tuning*/ - {IMX_8BIT, 0x47B4, 0x14}, /*CIS Tuning*/ - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx219_init_settings[] = { - {IMX_TOK_TERM, 0, 0} -}; - -struct imx_resolution imx219_res_preview[] = { - { - .desc = "STILL_6M_30fps", - .regs = imx219_STILL_6M_30fps, - .width = 3280, - .height = 1852, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D78, - .lines_per_frame = 0x0764, - }, - { - } - }, - .mipi_freq = 259000, - }, - { - .desc = "STILL_8M_30fps", - .regs = imx219_STILL_8M_30fps, - .width = 3280, - .height = 2464, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D78, - .lines_per_frame = 0x0A94, - }, - { - } - }, - .mipi_freq = 365000, - }, -}; - -struct imx_resolution imx219_res_still[] = { - { - .desc = "STILL_6M_30fps", - .regs = imx219_STILL_6M_30fps, - .width = 3280, - .height = 1852, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D78, - .lines_per_frame = 0x0764, - }, - { - } - }, - .mipi_freq = 259000, - }, - { - .desc = "STILL_8M_30fps", - .regs = imx219_STILL_8M_30fps, - .width = 3280, - .height = 2464, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D78, - .lines_per_frame = 0x0A94, - }, - { - } - }, - .mipi_freq = 365000, - }, -}; - -struct imx_resolution imx219_res_video[] = { - { - .desc = "STILL_6M_30fps", - .regs = imx219_STILL_6M_30fps, - .width = 3280, - .height = 1852, - .bin_factor_x = 0, - .bin_factor_y = 0, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0D78, - .lines_per_frame = 0x0764, - }, - { - } - }, - .mipi_freq = 259000, - }, -}; - -#endif diff --git a/drivers/staging/media/atomisp/i2c/imx/imx227.h b/drivers/staging/media/atomisp/i2c/imx/imx227.h deleted file mode 100644 index 795fe017d01b..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/imx227.h +++ /dev/null @@ -1,727 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __IMX227_H__ -#define __IMX227_H__ - -#include "common.h" - -#define IMX227_EMBEDDED_DATA_LINE_NUM 2 -#define IMX227_OUTPUT_DATA_FORMAT_REG 0x0112 -#define IMX227_OUTPUT_FORMAT_RAW10 0x0a0a - -/* AE Bracketing Registers */ -#define IMX227_BRACKETING_LUT_MODE_BIT_CONTINUE_STREAMING 0x1 -#define IMX227_BRACKETING_LUT_MODE_BIT_LOOP_MODE 0x2 - -#define IMX227_BRACKETING_LUT_CONTROL 0x0E00 -#define IMX227_BRACKETING_LUT_MODE 0x0E01 -#define IMX227_BRACKETING_LUT_ENTRY_CONTROL 0x0E02 - -/* - * The imx135 embedded data info: - * embedded data line num: 2 - * line 0 effective data size(byte): 76 - * line 1 effective data size(byte): 113 - */ -static const uint32_t -imx227_embedded_effective_size[IMX227_EMBEDDED_DATA_LINE_NUM] = {160, 62}; - -/************************** settings for imx *************************/ -/* Full Output Mode */ -static struct imx_reg const imx_STILL_6_5M_25fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x6259, 0x06}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xd0}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* 4:3 Output Mode */ -static struct imx_reg const imx_STILL_5_5M_3X4_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0xb0}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x00}, - {IMX_8BIT, 0x0348, 0x08}, - {IMX_8BIT, 0x0349, 0xaf}, - {IMX_8BIT, 0x034a, 0x0a}, - {IMX_8BIT, 0x034b, 0x9f}, - {IMX_8BIT, 0x034c, 0x08}, - {IMX_8BIT, 0x034d, 0x00}, - {IMX_8BIT, 0x034e, 0x0a}, - {IMX_8BIT, 0x034f, 0xa0}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xd8}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* Square Output Mode */ -static struct imx_reg const imx_STILL_5_7M_1X1_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0344, 0x00}, - {IMX_8BIT, 0x0345, 0x00}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0xa0}, - {IMX_8BIT, 0x0348, 0x09}, - {IMX_8BIT, 0x0349, 0x5f}, - {IMX_8BIT, 0x034a, 0x09}, - {IMX_8BIT, 0x034b, 0xff}, - {IMX_8BIT, 0x034c, 0x09}, - {IMX_8BIT, 0x034d, 0x60}, - {IMX_8BIT, 0x034e, 0x09}, - {IMX_8BIT, 0x034f, 0x60}, - - {IMX_8BIT, 0x6259, 0x06}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xd4}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* Full Frame 1080P Mode (use ISP scaler)*/ -static struct imx_reg const imx_VIDEO_4M_9X16_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xdc}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* Cropped 1080P Mode */ -static struct imx_reg const imx_VIDEO_2M_9X16_45fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0112, 0x0a}, - {IMX_8BIT, 0x0113, 0x0a}, - {IMX_8BIT, 0x0344, 0x02}, - {IMX_8BIT, 0x0345, 0x8a}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0x88}, - {IMX_8BIT, 0x0348, 0x06}, - {IMX_8BIT, 0x0349, 0xd1}, - {IMX_8BIT, 0x034a, 0x09}, - {IMX_8BIT, 0x034b, 0x17}, - {IMX_8BIT, 0x034c, 0x04}, - {IMX_8BIT, 0x034d, 0x48}, - {IMX_8BIT, 0x034e, 0x07}, - {IMX_8BIT, 0x034f, 0x90}, - - {IMX_8BIT, 0x0380, 0x00}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0382, 0x00}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0384, 0x00}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0386, 0x00}, - {IMX_8BIT, 0x0387, 0x01}, - - {IMX_8BIT, 0x0408, 0x00}, - {IMX_8BIT, 0x0409, 0x00}, - {IMX_8BIT, 0x040a, 0x00}, - {IMX_8BIT, 0x040b, 0x00}, - {IMX_8BIT, 0x040c, 0x04}, - {IMX_8BIT, 0x040d, 0x48}, - {IMX_8BIT, 0x040e, 0x07}, - {IMX_8BIT, 0x040f, 0x90}, - - {IMX_8BIT, 0x0900, 0x00}, - {IMX_8BIT, 0x0901, 0x00}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xdc}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3c}, /* preset_en */ - - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* Moment mode */ -static struct imx_reg const imx_VIDEO_1_3M_3X4_60fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xd9}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* High Speed 3:4 mode */ -static struct imx_reg const imx_VIDEO_VGA_3X4_120fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x9004, 0xca}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3f}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - - -/* Binned 720P mode */ -static struct imx_reg const imx_VIDEO_1M_9X16_60fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0112, 0x0a}, - {IMX_8BIT, 0x0113, 0x0a}, - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0xd0}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x40}, - {IMX_8BIT, 0x0348, 0x07}, - {IMX_8BIT, 0x0349, 0x8f}, - {IMX_8BIT, 0x034a, 0x0a}, - {IMX_8BIT, 0x034b, 0x5f}, - {IMX_8BIT, 0x034c, 0x02}, - {IMX_8BIT, 0x034d, 0xe0}, - {IMX_8BIT, 0x034e, 0x05}, - {IMX_8BIT, 0x034f, 0x10}, - - {IMX_8BIT, 0x0380, 0x00}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0382, 0x00}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0384, 0x00}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0386, 0x00}, - {IMX_8BIT, 0x0387, 0x01}, - - {IMX_8BIT, 0x0408, 0x00}, - {IMX_8BIT, 0x0409, 0x00}, - {IMX_8BIT, 0x040a, 0x00}, - {IMX_8BIT, 0x040b, 0x00}, - {IMX_8BIT, 0x040c, 0x02}, - {IMX_8BIT, 0x040d, 0xe0}, - {IMX_8BIT, 0x040e, 0x05}, - {IMX_8BIT, 0x040f, 0x10}, - - {IMX_8BIT, 0x0900, 0x01}, - {IMX_8BIT, 0x0901, 0x22}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xdd}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3c}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -/* Binned 496x868 mode */ -static struct imx_reg const imx_VIDEO_496x868_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0112, 0x0a}, - {IMX_8BIT, 0x0113, 0x0a}, - {IMX_8BIT, 0x0344, 0x02}, - {IMX_8BIT, 0x0345, 0xc0}, - {IMX_8BIT, 0x0346, 0x01}, - {IMX_8BIT, 0x0347, 0xec}, - {IMX_8BIT, 0x0348, 0x06}, - {IMX_8BIT, 0x0349, 0x9f}, - {IMX_8BIT, 0x034a, 0x08}, - {IMX_8BIT, 0x034b, 0xb3}, - {IMX_8BIT, 0x034c, 0x01}, - {IMX_8BIT, 0x034d, 0xf0}, - {IMX_8BIT, 0x034e, 0x03}, - {IMX_8BIT, 0x034f, 0x64}, - - {IMX_8BIT, 0x0380, 0x00}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0382, 0x00}, - {IMX_8BIT, 0x0383, 0x01}, - {IMX_8BIT, 0x0384, 0x00}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0386, 0x00}, - {IMX_8BIT, 0x0387, 0x01}, - - {IMX_8BIT, 0x0408, 0x00}, - {IMX_8BIT, 0x0409, 0x00}, - {IMX_8BIT, 0x040a, 0x00}, - {IMX_8BIT, 0x040b, 0x00}, - {IMX_8BIT, 0x040c, 0x01}, - {IMX_8BIT, 0x040d, 0xf0}, - {IMX_8BIT, 0x040e, 0x03}, - {IMX_8BIT, 0x040f, 0x64}, - - {IMX_8BIT, 0x0900, 0x01}, - {IMX_8BIT, 0x0901, 0x22}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xdd}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3c}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - - -/* Hangout mode */ -static struct imx_reg const imx_PREVIEW_374X652_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0112, 0x0a}, - {IMX_8BIT, 0x0113, 0x0a}, - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0xc0}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x30}, - {IMX_8BIT, 0x0348, 0x07}, - {IMX_8BIT, 0x0349, 0x9f}, - {IMX_8BIT, 0x034a, 0x0a}, - {IMX_8BIT, 0x034b, 0x6f}, - {IMX_8BIT, 0x034c, 0x01}, - {IMX_8BIT, 0x034d, 0x78}, - {IMX_8BIT, 0x034e, 0x02}, - {IMX_8BIT, 0x034f, 0x90}, - - {IMX_8BIT, 0x0380, 0x00}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0382, 0x00}, - {IMX_8BIT, 0x0383, 0x03}, - {IMX_8BIT, 0x0384, 0x00}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0386, 0x00}, - {IMX_8BIT, 0x0387, 0x03}, - - {IMX_8BIT, 0x0408, 0x00}, - {IMX_8BIT, 0x0409, 0x00}, - {IMX_8BIT, 0x040a, 0x00}, - {IMX_8BIT, 0x040b, 0x02}, - {IMX_8BIT, 0x040c, 0x01}, - {IMX_8BIT, 0x040d, 0x76}, - {IMX_8BIT, 0x040e, 0x02}, - {IMX_8BIT, 0x040f, 0x8c}, - - {IMX_8BIT, 0x0900, 0x01}, - {IMX_8BIT, 0x0901, 0x22}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xde}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3c}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - -static struct imx_reg const imx_VIDEO_NHD_9X16_30fps[] = { - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0112, 0x0a}, - {IMX_8BIT, 0x0113, 0x0a}, - {IMX_8BIT, 0x0344, 0x01}, - {IMX_8BIT, 0x0345, 0xc0}, - {IMX_8BIT, 0x0346, 0x00}, - {IMX_8BIT, 0x0347, 0x30}, - {IMX_8BIT, 0x0348, 0x07}, - {IMX_8BIT, 0x0349, 0x9f}, - {IMX_8BIT, 0x034a, 0x0a}, - {IMX_8BIT, 0x034b, 0x6f}, - {IMX_8BIT, 0x034c, 0x01}, - {IMX_8BIT, 0x034d, 0x78}, - {IMX_8BIT, 0x034e, 0x02}, - {IMX_8BIT, 0x034f, 0x90}, - - {IMX_8BIT, 0x0380, 0x00}, - {IMX_8BIT, 0x0381, 0x01}, - {IMX_8BIT, 0x0382, 0x00}, - {IMX_8BIT, 0x0383, 0x03}, - {IMX_8BIT, 0x0384, 0x00}, - {IMX_8BIT, 0x0385, 0x01}, - {IMX_8BIT, 0x0386, 0x00}, - {IMX_8BIT, 0x0387, 0x03}, - - {IMX_8BIT, 0x0408, 0x00}, - {IMX_8BIT, 0x0409, 0x00}, - {IMX_8BIT, 0x040a, 0x00}, - {IMX_8BIT, 0x040b, 0x00}, - {IMX_8BIT, 0x040c, 0x01}, - {IMX_8BIT, 0x040d, 0x78}, - {IMX_8BIT, 0x040e, 0x02}, - {IMX_8BIT, 0x040f, 0x90}, - - {IMX_8BIT, 0x0900, 0x01}, - {IMX_8BIT, 0x0901, 0x22}, - - {IMX_8BIT, 0x6259, 0x05}, /* latency ctrl */ - {IMX_8BIT, 0x9004, 0xde}, /* preset_sel */ - {IMX_8BIT, 0x9005, 0x3c}, /* preset_en */ - {IMX_8BIT, 0x0136, 0x13}, - {IMX_8BIT, 0x0137, 0x33}, - {IMX_TOK_TERM, 0, 0} -}; - - -static struct imx_reg const imx227_init_settings[] = { - {IMX_8BIT, 0x0100, 0x00}, /* mode_select */ - GROUPED_PARAMETER_HOLD_ENABLE, - {IMX_8BIT, 0x0306, 0x00}, - {IMX_8BIT, 0x0307, 0xBB}, - {IMX_8BIT, 0x030E, 0x03}, - {IMX_8BIT, 0x030F, 0x0D}, - {IMX_8BIT, 0x463b, 0x30}, - {IMX_8BIT, 0x463e, 0x05}, - {IMX_8BIT, 0x4612, 0x66}, - {IMX_8BIT, 0x4815, 0x65}, - {IMX_8BIT, 0x4991, 0x00}, - {IMX_8BIT, 0x4992, 0x01}, - {IMX_8BIT, 0x4993, 0xff}, - {IMX_8BIT, 0x458b, 0x00}, - {IMX_8BIT, 0x452a, 0x02}, - {IMX_8BIT, 0x4a7c, 0x00}, - {IMX_8BIT, 0x4a7d, 0x1c}, - {IMX_8BIT, 0x4a7e, 0x00}, - {IMX_8BIT, 0x4a7f, 0x17}, - {IMX_8BIT, 0x462C, 0x2E}, - {IMX_8BIT, 0x461B, 0x28}, - {IMX_8BIT, 0x4663, 0x29}, - {IMX_8BIT, 0x461A, 0x7C}, - {IMX_8BIT, 0x4619, 0x28}, - {IMX_8BIT, 0x4667, 0x22}, - {IMX_8BIT, 0x466B, 0x23}, - {IMX_8BIT, 0x40AD, 0xFF}, - {IMX_8BIT, 0x40BE, 0x00}, - {IMX_8BIT, 0x40BF, 0x6E}, - {IMX_8BIT, 0x40CE, 0x00}, - {IMX_8BIT, 0x40CF, 0x0A}, - {IMX_8BIT, 0x40CA, 0x00}, - {IMX_8BIT, 0x40CB, 0x1F}, - {IMX_8BIT, 0x4D16, 0x00}, - {IMX_8BIT, 0x6204, 0x01}, - {IMX_8BIT, 0x6209, 0x00}, - {IMX_8BIT, 0x621F, 0x01}, - {IMX_8BIT, 0x621E, 0x10}, - GROUPED_PARAMETER_HOLD_DISABLE, - {IMX_TOK_TERM, 0, 0} -}; - -/* TODO settings of preview/still/video will be updated with new use case */ -struct imx_resolution imx227_res_preview[] = { - { - .desc = "imx_PREVIEW_374X652_30fps", - .regs = imx_PREVIEW_374X652_30fps, - .width = 374, - .height = 652, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C0A, - }, - { - } - }, - }, - { - .desc = "imx_VIDEO_496x868_30fps", - .regs = imx_VIDEO_496x868_30fps, - .width = 496, - .height = 868, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C08, - }, - { - } - }, - }, - { - .desc = "imx_STILL_5_5M_3X4_30fps", - .regs = imx_STILL_5_5M_3X4_30fps, - .width = 2048, - .height = 2720, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0ED8, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - - }, - { - .desc = "imx_STILL_5_7M_1X1_30fps", - .regs = imx_STILL_5_7M_1X1_30fps, - .width = 2400, - .height = 2400, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x1130, - .lines_per_frame = 0x0A1E, - }, - { - } - }, - - }, - { - .desc = "imx_STILL_6_5M_25fps", - .regs = imx_STILL_6_5M_25fps, - .width = 2400, - .height = 2720, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 25, - .pixels_per_line = 0x1130, - .lines_per_frame = 0x0C24, - }, - { - } - }, - } -}; - -struct imx_resolution imx227_res_still[] = { - { - .desc = "imx_STILL_5_5M_3X4_30fps", - .regs = imx_STILL_5_5M_3X4_30fps, - .width = 2048, - .height = 2720, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 6, - .pixels_per_line = 0x2130, - .lines_per_frame = 0x1A22, - }, - { - .fps = 30, - .pixels_per_line = 0x0ED8, - .lines_per_frame = 0x0BB8, - }, - { - } - }, - - }, - { - .desc = "imx_STILL_5_7M_1X1_30fps", - .regs = imx_STILL_5_7M_1X1_30fps, - .width = 2400, - .height = 2400, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 6, - .pixels_per_line = 0x266E, - .lines_per_frame = 0x1704, - }, - { - .fps = 30, - .pixels_per_line = 0x1130, - .lines_per_frame = 0x0A1E, - }, - { - } - }, - - }, - { - .desc = "imx_STILL_6_5M_25fps", - .regs = imx_STILL_6_5M_25fps, - .width = 2400, - .height = 2720, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 25, - .pixels_per_line = 0x1130, - .lines_per_frame = 0x0C24, - }, - { - } - }, - }, -}; - -struct imx_resolution imx227_res_video[] = { - { - .desc = "imx_VIDEO_4M_9X16_30fps", - .regs = imx_VIDEO_4M_9X16_30fps, - .width = 1536, - .height = 2720, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C08, - }, - { - } - }, - - }, - { - .desc = "imx_VIDEO_2M_9X16_45fps", - .regs = imx_VIDEO_2M_9X16_45fps, - .width = 1096, - .height = 1936, - .bin_factor_x = 0, - .bin_factor_y = 0, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C08, - }, - { - .fps = 45, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0800, - }, - { - } - }, - - }, - { - .desc = "imx_VIDEO_1_3M_3X4_60fps", - .regs = imx_VIDEO_1_3M_3X4_60fps, - .width = 1024, - .height = 1360, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 60, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0604, - }, - { - } - }, - }, - { - .desc = "imx_VIDEO_496x868_30fps", - .regs = imx_VIDEO_496x868_30fps, - .width = 496, - .height = 868, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C08, - }, - { - } - }, - }, - { - .desc = "imx_VIDEO_1M_9X16_60fps", - .regs = imx_VIDEO_1M_9X16_60fps, - .width = 736, - .height = 1296, - .bin_factor_x = 1, - .bin_factor_y = 1, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 60, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0604, - }, - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C10, - }, - { - } - }, - }, - { - .desc = "imx_VIDEO_VGA_3X4_120fps", - .regs = imx_VIDEO_VGA_3X4_120fps, - .width = 512, - .height = 680, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 120, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0302, - }, - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C08, - }, - { - } - }, - }, - { - .desc = "imx_VIDEO_NHD_9X16_30fps", - .regs = imx_VIDEO_NHD_9X16_30fps, - .width = 376, - .height = 656, - .bin_factor_x = 2, - .bin_factor_y = 2, - .mipi_freq = 499000, - .used = 0, - .fps_options = { - { - .fps = 30, - .pixels_per_line = 0x0E70, - .lines_per_frame = 0x0C0A, - }, - { - } - }, - }, -}; - -#endif /* __IMX227_H__ */ diff --git a/drivers/staging/media/atomisp/i2c/imx/otp.c b/drivers/staging/media/atomisp/i2c/imx/otp.c deleted file mode 100644 index 462275038046..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/otp.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/i2c.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/types.h> -#include <media/v4l2-device.h> - -void *dummy_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 *buf; - - buf = devm_kzalloc(&client->dev, size, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - return buf; -} diff --git a/drivers/staging/media/atomisp/i2c/imx/otp_brcc064_e2prom.c b/drivers/staging/media/atomisp/i2c/imx/otp_brcc064_e2prom.c deleted file mode 100644 index b11f90c5960c..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/otp_brcc064_e2prom.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include "common.h" - -/* - * Read EEPROM data from brcc064 and store - * it into a kmalloced buffer. On error return NULL. - * @size: set to the size of the returned EEPROM data. - */ -void *brcc064_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - unsigned int e2prom_i2c_addr = dev_addr >> 1; - static const unsigned int max_read_size = 30; - int addr; - u32 s_addr = start_addr & E2PROM_ADDR_MASK; - unsigned char *buffer; - - buffer = devm_kzalloc(&client->dev, size, GFP_KERNEL); - if (!buffer) - return NULL; - - for (addr = s_addr; addr < size; addr += max_read_size) { - struct i2c_msg msg[2]; - unsigned int i2c_addr = e2prom_i2c_addr; - u16 addr_buf; - int r; - - msg[0].flags = 0; - msg[0].addr = i2c_addr; - addr_buf = cpu_to_be16(addr & 0xFFFF); - msg[0].len = 2; - msg[0].buf = (u8 *)&addr_buf; - - msg[1].addr = i2c_addr; - msg[1].flags = I2C_M_RD; - msg[1].len = min(max_read_size, size - addr); - msg[1].buf = &buffer[addr]; - - r = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); - if (r != ARRAY_SIZE(msg)) { - dev_err(&client->dev, "read failed at 0x%03x\n", addr); - return NULL; - } - } - return buffer; - -} - - diff --git a/drivers/staging/media/atomisp/i2c/imx/otp_e2prom.c b/drivers/staging/media/atomisp/i2c/imx/otp_e2prom.c deleted file mode 100644 index 73d041f97811..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/otp_e2prom.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include "common.h" - -/* - * Read EEPROM data from the gerneral e2prom chip(eg. - * CAT24C08, CAT24C128, le24l042cs, and store - * it into a kmalloced buffer. On error return NULL. - * @size: set to the size of the returned EEPROM data. - */ -void *e2prom_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - unsigned int e2prom_i2c_addr = dev_addr >> 1; - static const unsigned int max_read_size = 30; - int addr; - u32 s_addr = start_addr & E2PROM_ADDR_MASK; - bool two_addr = (start_addr & E2PROM_2ADDR) >> 31; - char *buffer; - - buffer = devm_kzalloc(&client->dev, size, GFP_KERNEL); - if (!buffer) - return NULL; - - for (addr = s_addr; addr < size; addr += max_read_size) { - struct i2c_msg msg[2]; - unsigned int i2c_addr = e2prom_i2c_addr; - u16 addr_buf; - int r; - - msg[0].flags = 0; - if (two_addr) { - msg[0].addr = i2c_addr; - addr_buf = cpu_to_be16(addr & 0xFFFF); - msg[0].len = 2; - msg[0].buf = (u8 *)&addr_buf; - } else { - i2c_addr |= (addr >> 8) & 0x7; - msg[0].addr = i2c_addr; - addr_buf = addr & 0xFF; - msg[0].len = 1; - msg[0].buf = (u8 *)&addr_buf; - } - - msg[1].addr = i2c_addr; - msg[1].flags = I2C_M_RD; - msg[1].len = min(max_read_size, size - addr); - msg[1].buf = &buffer[addr]; - - r = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); - if (r != ARRAY_SIZE(msg)) { - dev_err(&client->dev, "read failed at 0x%03x\n", addr); - return NULL; - } - } - return buffer; -} - - diff --git a/drivers/staging/media/atomisp/i2c/imx/otp_imx.c b/drivers/staging/media/atomisp/i2c/imx/otp_imx.c deleted file mode 100644 index 1ca27c26ef75..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/otp_imx.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <linux/bitops.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/i2c.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include <asm/intel-mid.h> -#include "common.h" - -/* Defines for OTP Data Registers */ -#define IMX_OTP_START_ADDR 0x3B04 -#define IMX_OTP_PAGE_SIZE 64 -#define IMX_OTP_READY_REG 0x3B01 -#define IMX_OTP_PAGE_REG 0x3B02 -#define IMX_OTP_MODE_REG 0x3B00 -#define IMX_OTP_PAGE_MAX 20 -#define IMX_OTP_READY_REG_DONE 1 -#define IMX_OTP_READ_ONETIME 32 -#define IMX_OTP_MODE_READ 1 -#define IMX227_OTP_START_ADDR 0x0A04 -#define IMX227_OTP_ENABLE_REG 0x0A00 -#define IMX227_OTP_READY_REG 0x0A01 -#define IMX227_OTP_PAGE_REG 0x0A02 -#define IMX227_OTP_READY_REG_DONE 1 -#define IMX227_OTP_MODE_READ 1 - -static int -imx_read_otp_data(struct i2c_client *client, u16 len, u16 reg, void *val) -{ - struct i2c_msg msg[2]; - u16 data[IMX_SHORT_MAX] = { 0 }; - int err; - - if (len > IMX_BYTE_MAX) { - dev_err(&client->dev, "%s error, invalid data length\n", - __func__); - return -EINVAL; - } - - memset(msg, 0 , sizeof(msg)); - memset(data, 0 , sizeof(data)); - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = I2C_MSG_LENGTH; - msg[0].buf = (u8 *)data; - /* high byte goes first */ - data[0] = cpu_to_be16(reg); - - msg[1].addr = client->addr; - msg[1].len = len; - msg[1].flags = I2C_M_RD; - msg[1].buf = (u8 *)data; - - err = i2c_transfer(client->adapter, msg, 2); - if (err != 2) { - if (err >= 0) - err = -EIO; - goto error; - } - - memcpy(val, data, len); - return 0; - -error: - dev_err(&client->dev, "read from offset 0x%x error %d", reg, err); - return err; -} - -static int imx_read_otp_reg_array(struct i2c_client *client, u16 size, u16 addr, - u8 *buf) -{ - u16 index; - int ret; - - for (index = 0; index + IMX_OTP_READ_ONETIME <= size; - index += IMX_OTP_READ_ONETIME) { - ret = imx_read_otp_data(client, IMX_OTP_READ_ONETIME, - addr + index, &buf[index]); - if (ret) - return ret; - } - return 0; -} - -void *imx_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 *buf; - int ret; - int i; - - buf = devm_kzalloc(&client->dev, size, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - for (i = 0; i < IMX_OTP_PAGE_MAX; i++) { - - /*set page NO.*/ - ret = imx_write_reg(client, IMX_8BIT, - IMX_OTP_PAGE_REG, i & 0xff); - if (ret) - goto fail; - - /*set read mode*/ - ret = imx_write_reg(client, IMX_8BIT, - IMX_OTP_MODE_REG, IMX_OTP_MODE_READ); - if (ret) - goto fail; - - /* Reading the OTP data array */ - ret = imx_read_otp_reg_array(client, IMX_OTP_PAGE_SIZE, - IMX_OTP_START_ADDR, buf + i * IMX_OTP_PAGE_SIZE); - if (ret) - goto fail; - } - - return buf; -fail: - /* Driver has failed to find valid data */ - dev_err(&client->dev, "sensor found no valid OTP data\n"); - return ERR_PTR(ret); -} - -void *imx227_otp_read(struct v4l2_subdev *sd, u8 dev_addr, - u32 start_addr, u32 size) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - u8 *buf; - int ret; - int i; - - buf = devm_kzalloc(&client->dev, size, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - - for (i = 0; i < IMX_OTP_PAGE_MAX; i++) { - - /*set page NO.*/ - ret = imx_write_reg(client, IMX_8BIT, - IMX227_OTP_PAGE_REG, i & 0xff); - if (ret) - goto fail; - - /*set read mode*/ - ret = imx_write_reg(client, IMX_8BIT, - IMX227_OTP_ENABLE_REG, IMX227_OTP_MODE_READ); - if (ret) - goto fail; - - /* Reading the OTP data array */ - ret = imx_read_otp_reg_array(client, IMX_OTP_PAGE_SIZE, - IMX227_OTP_START_ADDR, buf + i * IMX_OTP_PAGE_SIZE); - if (ret) - goto fail; - } - - return buf; -fail: - /* Driver has failed to find valid data */ - dev_err(&client->dev, "sensor found no valid OTP data\n"); - return ERR_PTR(ret); -} - diff --git a/drivers/staging/media/atomisp/i2c/imx/vcm.c b/drivers/staging/media/atomisp/i2c/imx/vcm.c deleted file mode 100644 index 2d2df04c800a..000000000000 --- a/drivers/staging/media/atomisp/i2c/imx/vcm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2012 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <media/v4l2-device.h> -#include "../../include/linux/atomisp_platform.h" - -int vcm_power_up(struct v4l2_subdev *sd) -{ - const struct camera_af_platform_data *vcm_platform_data; - - vcm_platform_data = camera_get_af_platform_data(); - if (NULL == vcm_platform_data) - return -ENODEV; - /* Enable power */ - return vcm_platform_data->power_ctrl(sd, 1); -} - -int vcm_power_down(struct v4l2_subdev *sd) -{ - const struct camera_af_platform_data *vcm_platform_data; - - vcm_platform_data = camera_get_af_platform_data(); - if (NULL == vcm_platform_data) - return -ENODEV; - return vcm_platform_data->power_ctrl(sd, 0); -} - diff --git a/drivers/staging/media/atomisp/i2c/mt9m114.h b/drivers/staging/media/atomisp/i2c/mt9m114.h index 5e7d79d2e01b..0af79d77a404 100644 --- a/drivers/staging/media/atomisp/i2c/mt9m114.h +++ b/drivers/staging/media/atomisp/i2c/mt9m114.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -394,11 +390,6 @@ static struct mt9m114_res_struct mt9m114_res[] = { }; #define N_RES (ARRAY_SIZE(mt9m114_res)) -static const struct i2c_device_id mt9m114_id[] = { - {"mt9m114", 0}, - {} -}; - static struct misensor_reg const mt9m114_exitstandby[] = { {MISENSOR_16BIT, 0x098E, 0xDC00}, /* exit-standby */ diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h index ab8907e6c9ef..bf4897347df7 100644 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ b/drivers/staging/media/atomisp/i2c/ov2680.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -35,10 +31,6 @@ #include "../include/linux/atomisp_platform.h" -#define OV2680_NAME "ov2680" -#define OV2680B_NAME "ov2680b" -#define OV2680F_NAME "ov2680f" - /* Defines for register writes and register array processing */ #define I2C_MSG_LENGTH 0x2 #define I2C_RETRY_COUNT 5 @@ -227,12 +219,6 @@ struct ov2680_format { struct ov2680_write_buffer buffer; }; - static const struct i2c_device_id ov2680_id[] = { - {OV2680B_NAME, 0}, - {OV2680F_NAME, 0}, - {} - }; - static struct ov2680_reg const ov2680_global_setting[] = { {OV2680_8BIT, 0x0103, 0x01}, {OV2680_8BIT, 0x3002, 0x00}, diff --git a/drivers/staging/media/atomisp/i2c/ov2722.h b/drivers/staging/media/atomisp/i2c/ov2722.h index 73ecb1679718..d8a973d71699 100644 --- a/drivers/staging/media/atomisp/i2c/ov2722.h +++ b/drivers/staging/media/atomisp/i2c/ov2722.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -35,8 +31,6 @@ #include "../include/linux/atomisp_platform.h" -#define OV2722_NAME "ov2722" - #define OV2722_POWER_UP_RETRY_NUM 5 /* Defines for register writes and register array processing */ @@ -257,11 +251,6 @@ struct ov2722_write_ctrl { struct ov2722_write_buffer buffer; }; -static const struct i2c_device_id ov2722_id[] = { - {OV2722_NAME, 0}, - {} -}; - /* * Register settings for various resolution */ diff --git a/drivers/staging/media/atomisp/i2c/ov5693/Kconfig b/drivers/staging/media/atomisp/i2c/ov5693/Kconfig index 9fb1bffbe9b3..3f527f2047a7 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/Kconfig +++ b/drivers/staging/media/atomisp/i2c/ov5693/Kconfig @@ -1,11 +1,11 @@ -config VIDEO_OV5693 +config VIDEO_ATOMISP_OV5693 tristate "Omnivision ov5693 sensor support" + depends on ACPI depends on I2C && VIDEO_V4L2 ---help--- - This is a Video4Linux2 sensor-level driver for the Micron - ov5693 5 Mpixel camera. + This is a Video4Linux2 sensor-level driver for the Micron + ov5693 5 Mpixel camera. - ov5693 is video camera sensor. - - It currently only works with the atomisp driver. + ov5693 is video camera sensor. + It currently only works with the atomisp driver. diff --git a/drivers/staging/media/atomisp/i2c/ov5693/Makefile b/drivers/staging/media/atomisp/i2c/ov5693/Makefile index facb70e6a93e..aa6be85c5a60 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/Makefile +++ b/drivers/staging/media/atomisp/i2c/ov5693/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_VIDEO_OV5693) += ov5693.o +obj-$(CONFIG_VIDEO_ATOMISP_OV5693) += atomisp-ov5693.o # HACK! While this driver is in bad shape, don't enable several warnings # that would be otherwise enabled with W=1 diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h b/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h index 2dd894989cd9..4de44569fe54 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h +++ b/drivers/staging/media/atomisp/i2c/ov5693/ad5823.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c index 123642557aa8..3e7c3851280f 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.c +++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -31,7 +27,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/i2c.h> -#include <linux/gpio.h> #include <linux/moduleparam.h> #include <media/v4l2-device.h> #include <linux/io.h> @@ -391,8 +386,8 @@ static int ov5693_write_reg_array(struct i2c_client *client, if (!__ov5693_write_reg_is_consecutive(client, &ctrl, next)) { err = __ov5693_flush_reg_array(client, &ctrl); - if (err) - return err; + if (err) + return err; } err = __ov5693_buf_reg_array(client, &ctrl, next); if (err) { @@ -945,12 +940,8 @@ static int ad5823_t_focus_vcm(struct v4l2_subdev *sd, u16 val) int ad5823_t_focus_abs(struct v4l2_subdev *sd, s32 value) { - int ret; - value = min(value, AD5823_MAX_FOCUS_POS); - ret = ad5823_t_focus_vcm(sd, value); - - return ret; + return ad5823_t_focus_vcm(sd, value); } static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value) @@ -1302,10 +1293,6 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - /* This driver assumes "internal DVDD, PWDNB tied to DOVDD". * In this set up only gpio0 (XSHUTDN) should be available * but in some products (for example ECS) gpio1 (PWDNB) is @@ -1332,19 +1319,12 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag) static int gpio_ctrl(struct v4l2_subdev *sd, bool flag) { - int ret; struct ov5693_device *dev = to_ov5693_sensor(sd); if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - - ret = dev->platform_data->gpio0_ctrl(sd, flag); - - return ret; + return dev->platform_data->gpio0_ctrl(sd, flag); } static int __power_up(struct v4l2_subdev *sd) @@ -1942,8 +1922,7 @@ static int ov5693_remove(struct i2c_client *client) return 0; } -static int ov5693_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ov5693_probe(struct i2c_client *client) { struct ov5693_device *dev; int i2c; @@ -1965,10 +1944,8 @@ static int ov5693_probe(struct i2c_client *client, } dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "out of memory\n"); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); @@ -2030,8 +2007,6 @@ out_free: return ret; } -MODULE_DEVICE_TABLE(i2c, ov5693_id); - static const struct acpi_device_id ov5693_acpi_match[] = { {"INT33BE"}, {}, @@ -2040,27 +2015,13 @@ MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match); static struct i2c_driver ov5693_driver = { .driver = { - .name = OV5693_NAME, - .acpi_match_table = ACPI_PTR(ov5693_acpi_match), + .name = "ov5693", + .acpi_match_table = ov5693_acpi_match, }, - .probe = ov5693_probe, + .probe_new = ov5693_probe, .remove = ov5693_remove, - .id_table = ov5693_id, }; - -static int init_ov5693(void) -{ - return i2c_add_driver(&ov5693_driver); -} - -static void exit_ov5693(void) -{ - - i2c_del_driver(&ov5693_driver); -} - -module_init(init_ov5693); -module_exit(exit_ov5693); +module_i2c_driver(ov5693_driver); MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h index 8c2e6794463b..2ea63807c56d 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -35,8 +31,6 @@ #include "../../include/linux/atomisp_platform.h" -#define OV5693_NAME "ov5693" - #define OV5693_POWER_UP_RETRY_NUM 5 /* Defines for register writes and register array processing */ @@ -278,11 +272,6 @@ struct ov5693_write_ctrl { struct ov5693_write_buffer buffer; }; -static const struct i2c_device_id ov5693_id[] = { - {OV5693_NAME, 0}, - {} -}; - static struct ov5693_reg const ov5693_global_setting[] = { {OV5693_8BIT, 0x0103, 0x01}, {OV5693_8BIT, 0x3001, 0x0a}, diff --git a/drivers/staging/media/atomisp/i2c/ov8858.c b/drivers/staging/media/atomisp/i2c/ov8858.c index 43e1638fd674..ba147ac2e36f 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858.c +++ b/drivers/staging/media/atomisp/i2c/ov8858.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -480,8 +476,6 @@ static int ov8858_priv_int_data_init(struct v4l2_subdev *sd) if (!dev->otp_data) { dev->otp_data = devm_kzalloc(&client->dev, size, GFP_KERNEL); if (!dev->otp_data) { - dev_err(&client->dev, "%s: can't allocate memory", - __func__); r = -ENOMEM; goto error3; } @@ -714,10 +708,6 @@ static int __power_ctrl(struct v4l2_subdev *sd, bool flag) if (!dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->power_ctrl) - return dev->platform_data->power_ctrl(sd, flag); - if (dev->platform_data->v1p2_ctrl) { ret = dev->platform_data->v1p2_ctrl(sd, flag); if (ret) { @@ -769,10 +759,6 @@ static int __gpio_ctrl(struct v4l2_subdev *sd, bool flag) if (!client || !dev || !dev->platform_data) return -ENODEV; - /* Non-gmin platforms use the legacy callback */ - if (dev->platform_data->gpio_ctrl) - return dev->platform_data->gpio_ctrl(sd, flag); - if (dev->platform_data->gpio0_ctrl) return dev->platform_data->gpio0_ctrl(sd, flag); @@ -1575,15 +1561,6 @@ static int ov8858_s_config(struct v4l2_subdev *sd, mutex_lock(&dev->input_lock); - if (dev->platform_data->platform_init) { - ret = dev->platform_data->platform_init(client); - if (ret) { - mutex_unlock(&dev->input_lock); - dev_err(&client->dev, "platform init error %d!\n", ret); - return ret; - } - } - ret = __ov8858_s_power(sd, 1); if (ret) { dev_err(&client->dev, "power-up error %d!\n", ret); @@ -1628,8 +1605,6 @@ fail_detect: fail_csi_cfg: __ov8858_s_power(sd, 0); fail_update: - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); mutex_unlock(&dev->input_lock); dev_err(&client->dev, "sensor power-gating failed\n"); return ret; @@ -1930,8 +1905,6 @@ static int ov8858_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct ov8858_device *dev = to_ov8858_sensor(sd); - if (dev->platform_data->platform_deinit) - dev->platform_data->platform_deinit(); media_entity_cleanup(&dev->sd.entity); v4l2_ctrl_handler_free(&dev->ctrl_handler); @@ -2082,8 +2055,7 @@ static const struct v4l2_ctrl_config ctrls[] = { } }; -static int ov8858_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int ov8858_probe(struct i2c_client *client) { struct ov8858_device *dev; unsigned int i; @@ -2094,15 +2066,11 @@ static int ov8858_probe(struct i2c_client *client, /* allocate sensor device & init sub device */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_err(&client->dev, "%s: out of memory\n", __func__); + if (!dev) return -ENOMEM; - } mutex_init(&dev->input_lock); - if (id) - dev->i2c_id = id->driver_data; dev->fmt_idx = 0; dev->sensor_id = OV_ID_DEFAULT; dev->vcm_driver = &ov8858_vcms[OV8858_ID_DEFAULT]; @@ -2182,40 +2150,21 @@ out_free: return ret; } -static const struct i2c_device_id ov8858_id[] = { - {OV8858_NAME, 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ov8858_id); - static const struct acpi_device_id ov8858_acpi_match[] = { {"INT3477"}, {}, }; +MODULE_DEVICE_TABLE(acpi, ov8858_acpi_match); static struct i2c_driver ov8858_driver = { .driver = { - .name = OV8858_NAME, - .acpi_match_table = ACPI_PTR(ov8858_acpi_match), + .name = "ov8858", + .acpi_match_table = ov8858_acpi_match, }, - .probe = ov8858_probe, + .probe_new = ov8858_probe, .remove = ov8858_remove, - .id_table = ov8858_id, }; - -static __init int ov8858_init_mod(void) -{ - return i2c_add_driver(&ov8858_driver); -} - -static __exit void ov8858_exit_mod(void) -{ - i2c_del_driver(&ov8858_driver); -} - -module_init(ov8858_init_mod); -module_exit(ov8858_exit_mod); +module_i2c_driver(ov8858_driver); MODULE_DESCRIPTION("A low-level driver for Omnivision OV8858 sensors"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/ov8858.h b/drivers/staging/media/atomisp/i2c/ov8858.h index 638d1a803a2b..6c89568bb44e 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858.h +++ b/drivers/staging/media/atomisp/i2c/ov8858.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -113,7 +109,6 @@ #define OV_SUBDEV_PREFIX "ov" #define OV_ID_DEFAULT 0x0000 -#define OV8858_NAME "ov8858" #define OV8858_CHIP_ID 0x8858 #define OV8858_LONG_EXPO 0x3500 diff --git a/drivers/staging/media/atomisp/i2c/ov8858_btns.h b/drivers/staging/media/atomisp/i2c/ov8858_btns.h index 7d74a8899fae..f81851306832 100644 --- a/drivers/staging/media/atomisp/i2c/ov8858_btns.h +++ b/drivers/staging/media/atomisp/i2c/ov8858_btns.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -113,7 +109,6 @@ #define OV_SUBDEV_PREFIX "ov" #define OV_ID_DEFAULT 0x0000 -#define OV8858_NAME "ov8858" #define OV8858_CHIP_ID 0x8858 #define OV8858_LONG_EXPO 0x3500 diff --git a/drivers/staging/media/atomisp/include/asm/intel_mid_pcihelpers.h b/drivers/staging/media/atomisp/include/asm/intel_mid_pcihelpers.h deleted file mode 100644 index dc7104470f5c..000000000000 --- a/drivers/staging/media/atomisp/include/asm/intel_mid_pcihelpers.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Access to message bus through three registers - * in CUNIT(0:0:0) PCI configuration space. - * MSGBUS_CTRL_REG(0xD0): - * 31:24 = message bus opcode - * 23:16 = message bus port - * 15:8 = message bus address, low 8 bits. - * 7:4 = message bus byte enables - * MSGBUS_CTRL_EXT_REG(0xD8): - * 31:8 = message bus address, high 24 bits. - * MSGBUS_DATA_REG(0xD4): - * hold the data for write or read - */ -#define PCI_ROOT_MSGBUS_CTRL_REG 0xD0 -#define PCI_ROOT_MSGBUS_DATA_REG 0xD4 -#define PCI_ROOT_MSGBUS_CTRL_EXT_REG 0xD8 -#define PCI_ROOT_MSGBUS_READ 0x10 -#define PCI_ROOT_MSGBUS_WRITE 0x11 -#define PCI_ROOT_MSGBUS_DWORD_ENABLE 0xf0 - -/* In BYT platform for all internal PCI devices d3 delay - * of 3 ms is sufficient. Default value of 10 ms is overkill. - */ -#define INTERNAL_PCI_PM_D3_WAIT 3 - -#define ISP_SUB_CLASS 0x80 -#define SUB_CLASS_MASK 0xFF00 - -u32 intel_mid_msgbus_read32_raw(u32 cmd); -u32 intel_mid_msgbus_read32(u8 port, u32 addr); -void intel_mid_msgbus_write32_raw(u32 cmd, u32 data); -void intel_mid_msgbus_write32(u8 port, u32 addr, u32 data); -u32 intel_mid_msgbus_read32_raw_ext(u32 cmd, u32 cmd_ext); -void intel_mid_msgbus_write32_raw_ext(u32 cmd, u32 cmd_ext, u32 data); -u32 intel_mid_soc_stepping(void); -int intel_mid_dw_i2c_acquire_ownership(void); -int intel_mid_dw_i2c_release_ownership(void); diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h index d67dd658cff9..b5533197226d 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifdef CSS15 diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h index 5390b97ac6e7..7e3ca12dd4e9 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h @@ -17,9 +17,6 @@ #include "atomisp_platform.h" -const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void); -const struct atomisp_platform_data *atomisp_get_platform_data(void); -const struct camera_af_platform_data *camera_get_af_platform_data(void); int atomisp_register_i2c_module(struct v4l2_subdev *subdev, struct camera_sensor_platform_data *plat_data, enum intel_v4l2_subdev_type type); diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h index dbac2b777dad..e0f0c379e7ce 100644 --- a/drivers/staging/media/atomisp/include/linux/atomisp_platform.h +++ b/drivers/staging/media/atomisp/include/linux/atomisp_platform.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef ATOMISP_PLATFORM_H_ @@ -205,20 +201,13 @@ struct camera_vcm_control { }; struct camera_sensor_platform_data { - int (*gpio_ctrl)(struct v4l2_subdev *subdev, int flag); int (*flisclk_ctrl)(struct v4l2_subdev *subdev, int flag); - int (*power_ctrl)(struct v4l2_subdev *subdev, int flag); int (*csi_cfg)(struct v4l2_subdev *subdev, int flag); - bool (*low_fps)(void); - int (*platform_init)(struct i2c_client *); - int (*platform_deinit)(void); - char *(*msr_file_name)(void); - struct atomisp_camera_caps *(*get_camera_caps)(void); - int (*gpio_intr_ctrl)(struct v4l2_subdev *subdev); - /* New G-Min power and GPIO interface, replaces - * power/gpio_ctrl with methods to control individual - * lines as implemented on all known camera modules. */ + /* + * New G-Min power and GPIO interface to control individual + * lines as implemented on all known camera modules. + */ int (*gpio0_ctrl)(struct v4l2_subdev *subdev, int on); int (*gpio1_ctrl)(struct v4l2_subdev *subdev, int on); int (*v1p8_ctrl)(struct v4l2_subdev *subdev, int on); @@ -228,12 +217,6 @@ struct camera_sensor_platform_data { char *module_id); }; -struct camera_af_platform_data { - int (*power_ctrl)(struct v4l2_subdev *subdev, int flag); -}; - -const struct camera_af_platform_data *camera_get_af_platform_data(void); - struct camera_mipi_info { enum atomisp_camera_port port; unsigned int num_lanes; diff --git a/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h b/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h index 589f4eae38ca..8988b37943b3 100644 --- a/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h +++ b/drivers/staging/media/atomisp/include/linux/libmsrlisthelper.h @@ -10,10 +10,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __LIBMSRLISTHELPER_H__ diff --git a/drivers/staging/media/atomisp/include/media/lm3554.h b/drivers/staging/media/atomisp/include/media/lm3554.h index 7d6a8c05dd52..9276ce44d907 100644 --- a/drivers/staging/media/atomisp/include/media/lm3554.h +++ b/drivers/staging/media/atomisp/include/media/lm3554.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef _LM3554_H_ @@ -24,7 +20,6 @@ #include <linux/videodev2.h> #include <media/v4l2-subdev.h> -#define LM3554_NAME "lm3554" #define LM3554_ID 3554 #define v4l2_queryctrl_entry_integer(_id, _name,\ diff --git a/drivers/staging/media/atomisp/include/media/lm3642.h b/drivers/staging/media/atomisp/include/media/lm3642.h deleted file mode 100644 index 545d95763335..000000000000 --- a/drivers/staging/media/atomisp/include/media/lm3642.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * include/media/lm3642.h - * - * Copyright (c) 2010-2012 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. - */ - -#ifndef _LM3642_H_ -#define _LM3642_H_ - -#include <linux/videodev2.h> -#include <media/v4l2-subdev.h> - -#define LM3642_NAME "lm3642" -#define LM3642_ID 3642 - -#define v4l2_queryctrl_entry_integer(_id, _name,\ - _minimum, _maximum, _step, \ - _default_value, _flags) \ - {\ - .id = (_id), \ - .type = V4L2_CTRL_TYPE_INTEGER, \ - .name = _name, \ - .minimum = (_minimum), \ - .maximum = (_maximum), \ - .step = (_step), \ - .default_value = (_default_value),\ - .flags = (_flags),\ - } -#define v4l2_queryctrl_entry_boolean(_id, _name,\ - _default_value, _flags) \ - {\ - .id = (_id), \ - .type = V4L2_CTRL_TYPE_BOOLEAN, \ - .name = _name, \ - .minimum = 0, \ - .maximum = 1, \ - .step = 1, \ - .default_value = (_default_value),\ - .flags = (_flags),\ - } - -#define s_ctrl_id_entry_integer(_id, _name, \ - _minimum, _maximum, _step, \ - _default_value, _flags, \ - _s_ctrl, _g_ctrl) \ - {\ - .qc = v4l2_queryctrl_entry_integer(_id, _name,\ - _minimum, _maximum, _step,\ - _default_value, _flags), \ - .s_ctrl = _s_ctrl, \ - .g_ctrl = _g_ctrl, \ - } - -#define s_ctrl_id_entry_boolean(_id, _name, \ - _default_value, _flags, \ - _s_ctrl, _g_ctrl) \ - {\ - .qc = v4l2_queryctrl_entry_boolean(_id, _name,\ - _default_value, _flags), \ - .s_ctrl = _s_ctrl, \ - .g_ctrl = _g_ctrl, \ - } - - -/* Default Values */ -#define LM3642_DEFAULT_TIMEOUT 300U -#define LM3642_DEFAULT_RAMP_TIME 0x10 /* 1.024ms */ -#define LM3642_DEFAULT_INDICATOR_CURRENT 0x01 /* 1.88A */ -#define LM3642_DEFAULT_FLASH_CURRENT 0x0f /* 1500mA */ - -/* Value settings for Flash Time-out Duration*/ -#define LM3642_MIN_TIMEOUT 100U -#define LM3642_MAX_TIMEOUT 800U -#define LM3642_TIMEOUT_STEPSIZE 100U - -/* Flash modes */ -#define LM3642_MODE_SHUTDOWN 0 -#define LM3642_MODE_INDICATOR 1 -#define LM3642_MODE_TORCH 2 -#define LM3642_MODE_FLASH 3 - -/* timer delay time */ -#define LM3642_TIMER_DELAY 5 - -/* Percentage <-> value macros */ -#define LM3642_MIN_PERCENT 0U -#define LM3642_MAX_PERCENT 100U -#define LM3642_CLAMP_PERCENTAGE(val) \ - clamp(val, LM3642_MIN_PERCENT, LM3642_MAX_PERCENT) - -#define LM3642_VALUE_TO_PERCENT(v, step) \ - (((((unsigned long)((v)+1))*(step))+50)/100) -#define LM3642_PERCENT_TO_VALUE(p, step) \ - (((((unsigned long)(p))*100)+((step)>>1))/(step)-1) - -/* Product specific limits - * TODO: get these from platform data */ -#define LM3642_FLASH_MAX_LVL 0x0F /* 1500mA */ -#define LM3642_TORCH_MAX_LVL 0x07 /* 187mA */ -#define LM3642_INDICATOR_MAX_LVL 0x01 /* 1.88A */ - -/* Flash brightness, input is percentage, output is [0..15] */ -#define LM3642_FLASH_STEP \ - ((100ul*(LM3642_MAX_PERCENT) \ - +((LM3642_FLASH_MAX_LVL+1)>>1)) \ - /((LM3642_FLASH_MAX_LVL+1))) -#define LM3642_FLASH_DEFAULT_BRIGHTNESS \ - LM3642_VALUE_TO_PERCENT(15, LM3642_FLASH_STEP) - -/* Torch brightness, input is percentage, output is [0..7] */ -#define LM3642_TORCH_STEP \ - ((100ul*(LM3642_MAX_PERCENT) \ - +((LM3642_TORCH_MAX_LVL+1)>>1)) \ - /((LM3642_TORCH_MAX_LVL+1))) -#define LM3642_TORCH_DEFAULT_BRIGHTNESS \ - LM3642_VALUE_TO_PERCENT(0, LM3642_TORCH_STEP) - -/* Indicator brightness, input is percentage, output is [0..1] */ -#define LM3642_INDICATOR_STEP \ - ((100ul*(LM3642_MAX_PERCENT) \ - +((LM3642_INDICATOR_MAX_LVL+1)>>1)) \ - /((LM3642_INDICATOR_MAX_LVL+1))) -#define LM3642_INDICATOR_DEFAULT_BRIGHTNESS \ - LM3642_VALUE_TO_PERCENT(1, LM3642_INDICATOR_STEP) - -/* - * lm3642_platform_data - Flash controller platform data - */ -struct lm3642_platform_data { - int gpio_torch; - int gpio_strobe; - int (*power_ctrl)(struct v4l2_subdev *subdev, int on); - - unsigned int torch_en; - unsigned int flash_en; - unsigned int tx_en; - unsigned int ivfm_en; -}; - -#endif /* _LM3642_H_ */ - diff --git a/drivers/staging/media/atomisp/pci/Kconfig b/drivers/staging/media/atomisp/pci/Kconfig index a72421431c7a..41f116d52060 100644 --- a/drivers/staging/media/atomisp/pci/Kconfig +++ b/drivers/staging/media/atomisp/pci/Kconfig @@ -3,11 +3,12 @@ # config VIDEO_ATOMISP - tristate "Intel Atom Image Signal Processor Driver" - depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API - select VIDEOBUF_VMALLOC - ---help--- - Say Y here if your platform supports Intel Atom SoC - camera imaging subsystem. - To compile this driver as a module, choose M here: the - module will be called atomisp + tristate "Intel Atom Image Signal Processor Driver" + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + select IOSF_MBI + select VIDEOBUF_VMALLOC + ---help--- + Say Y here if your platform supports Intel Atom SoC + camera imaging subsystem. + To compile this driver as a module, choose M here: the + module will be called atomisp diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp-regs.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp-regs.h index 513a430ee01a..5d102a4f8aff 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp-regs.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp-regs.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.c index 1eac329339b7..a6638edee360 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.h index 5b58e7d9ca5b..56386154643b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_acc.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c index f48bf451c1f5..8a18c528cad4 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/firmware.h> @@ -27,7 +23,8 @@ #include <linux/kfifo.h> #include <linux/pm_runtime.h> #include <linux/timer.h> -#include <asm/intel-mid.h> + +#include <asm/iosf_mbi.h> #include <media/v4l2-event.h> #include <media/videobuf-vmalloc.h> @@ -143,36 +140,36 @@ static int write_target_freq_to_hw(struct atomisp_device *isp, unsigned int ratio, timeout, guar_ratio; u32 isp_sspm1 = 0; int i; + if (!isp->hpll_freq) { dev_err(isp->dev, "failed to get hpll_freq. no change to freq\n"); return -EINVAL; } - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); if (isp_sspm1 & ISP_FREQ_VALID_MASK) { dev_dbg(isp->dev, "clearing ISPSSPM1 valid bit.\n"); - intel_mid_msgbus_write32(PUNIT_PORT, ISPSSPM1, + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, ISPSSPM1, isp_sspm1 & ~(1 << ISP_FREQ_VALID_OFFSET)); } ratio = (2 * isp->hpll_freq + new_freq / 2) / new_freq - 1; guar_ratio = (2 * isp->hpll_freq + 200 / 2) / 200 - 1; - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); isp_sspm1 &= ~(0x1F << ISP_REQ_FREQ_OFFSET); for (i = 0; i < ISP_DFS_TRY_TIMES; i++) { - intel_mid_msgbus_write32(PUNIT_PORT, ISPSSPM1, + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, ISPSSPM1, isp_sspm1 | ratio << ISP_REQ_FREQ_OFFSET | 1 << ISP_FREQ_VALID_OFFSET | guar_ratio << ISP_REQ_GUAR_FREQ_OFFSET); - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); - + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); timeout = 20; while ((isp_sspm1 & ISP_FREQ_VALID_MASK) && timeout) { - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); dev_dbg(isp->dev, "waiting for ISPSSPM1 valid bit to be 0.\n"); udelay(100); timeout--; @@ -187,10 +184,10 @@ static int write_target_freq_to_hw(struct atomisp_device *isp, return -EINVAL; } - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); timeout = 10; while (((isp_sspm1 >> ISP_FREQ_STAT_OFFSET) != ratio) && timeout) { - isp_sspm1 = intel_mid_msgbus_read32(PUNIT_PORT, ISPSSPM1); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM1, &isp_sspm1); dev_dbg(isp->dev, "waiting for ISPSSPM1 status bit to be 0x%x.\n", new_freq); udelay(100); @@ -1660,20 +1657,15 @@ void atomisp_css_flush(struct atomisp_device *isp) dev_dbg(isp->dev, "atomisp css flush done\n"); } -#ifndef ISP2401 -void atomisp_wdt(unsigned long isp_addr) -#else -void atomisp_wdt(unsigned long pipe_addr) -#endif +void atomisp_wdt(struct timer_list *t) { #ifndef ISP2401 - struct atomisp_device *isp = (struct atomisp_device *)isp_addr; + struct atomisp_sub_device *asd = from_timer(asd, t, wdt); #else - struct atomisp_video_pipe *pipe = - (struct atomisp_video_pipe *)pipe_addr; + struct atomisp_video_pipe *pipe = from_timer(pipe, t, wdt); struct atomisp_sub_device *asd = pipe->asd; - struct atomisp_device *isp = asd->isp; #endif + struct atomisp_device *isp = asd->isp; #ifdef ISP2401 atomic_inc(&pipe->wdt_count); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h index 31ba4e613d13..bdc73862fb79 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_cmd.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -85,11 +81,7 @@ static inline void __iomem *atomisp_get_io_virt_addr(unsigned int address) void atomisp_msi_irq_init(struct atomisp_device *isp, struct pci_dev *dev); void atomisp_msi_irq_uninit(struct atomisp_device *isp, struct pci_dev *dev); void atomisp_wdt_work(struct work_struct *work); -#ifndef ISP2401 -void atomisp_wdt(unsigned long isp_addr); -#else -void atomisp_wdt(unsigned long pipe_addr); -#endif +void atomisp_wdt(struct timer_list *t); void atomisp_setup_flash(struct atomisp_sub_device *asd); irqreturn_t atomisp_isr(int irq, void *dev); irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_common.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_common.h index 69d1526da362..2558193045a6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_common.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_common.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat.h index fb8b8fab4e92..3ef850cd25bd 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c index 5027fd20d966..6e87aa5aab4c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -4526,7 +4522,7 @@ int atomisp_css_isr_thread(struct atomisp_device *isp, for (i = 0; i < isp->num_of_streams; i++) atomisp_wdt_stop(&isp->asd[i], 0); #ifndef ISP2401 - atomisp_wdt((unsigned long)isp); + atomisp_wdt(&isp->asd[0].wdt); #else queue_work(isp->wdt_work_queue, &isp->wdt_work); #endif diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.h index b62ad9082018..b03711668eda 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_css20.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.c index 0592ac1f2832..44c21813a06e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifdef CONFIG_COMPAT diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.h index 750478f614d6..685da0f48bab 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_compat_ioctl32.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_COMPAT_IOCTL32_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c index 2c5036685447..fa03b78c3580 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.h index faa9cf7e05c0..0191d28a55bc 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_csi2.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_CSI2_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_dfs_tables.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_dfs_tables.h index 204d941cdb6c..54e28605b5de 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_dfs_tables.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_dfs_tables.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_DFS_TABLES_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c index 1ae2358de8d4..7129b88456cb 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -162,7 +158,7 @@ static ssize_t iunit_dbgopt_store(struct device_driver *drv, const char *buf, return size; } -static struct driver_attribute iunit_drvfs_attrs[] = { +static const struct driver_attribute iunit_drvfs_attrs[] = { __ATTR(dbglvl, 0644, iunit_dbglvl_show, iunit_dbglvl_store), __ATTR(dbgfun, 0644, iunit_dbgfun_show, iunit_dbgfun_store), __ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store), diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h index 5cb717b0c1c2..b91bfef21639 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c index c766119bf798..377ec2a9fa6d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.h index 1b86abd35c38..61fdeb5ee60a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_file.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c index d8cfed358d55..dd7596d8763d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ @@ -1137,10 +1133,8 @@ static int remove_pad_from_frame(struct atomisp_device *isp, ia_css_ptr store = load; buffer = kmalloc(width*sizeof(load), GFP_KERNEL); - if (!buffer) { - dev_err(isp->dev, "out of memory.\n"); + if (!buffer) return -ENOMEM; - } load += ISP_LEFT_PAD; for (i = 0; i < height; i++) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.h index 8471e391501a..2faab3429d43 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_fops.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_helper.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_helper.h index e9650cb75ba5..55ba185b43a0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_helper.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_helper.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef _atomisp_helper_h_ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h index 7542a72f1d0f..52a6f8002048 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_INTERNAL_H__ @@ -29,9 +25,6 @@ #include <linux/pm_qos.h> #include <linux/idr.h> -#include <asm/intel-mid.h> -#include "../../include/asm/intel_mid_pcihelpers.h" - #include <media/media-device.h> #include <media/v4l2-subdev.h> diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c index 717647951fb6..339b5d31e1f1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c @@ -14,17 +14,12 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/delay.h> #include <linux/pci.h> -#include <asm/intel-mid.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-event.h> @@ -943,10 +938,8 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, dev_dbg(isp->dev, "allocating %d 3a buffers\n", count); while (count--) { s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL); - if (!s3a_buf) { - dev_err(isp->dev, "s3a stat buf alloc failed\n"); + if (!s3a_buf) goto error; - } if (atomisp_css_allocate_stat_buffers( asd, stream_id, s3a_buf, NULL, NULL)) { @@ -965,7 +958,6 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, while (count--) { dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL); if (!dis_buf) { - dev_err(isp->dev, "dis stat buf alloc failed\n"); kfree(s3a_buf); goto error; } @@ -990,10 +982,8 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, while (count--) { md_buf = kzalloc(sizeof(struct atomisp_metadata_buf), GFP_KERNEL); - if (!md_buf) { - dev_err(isp->dev, "metadata buf alloc failed\n"); + if (!md_buf) goto error; - } if (atomisp_css_allocate_stat_buffers( asd, stream_id, NULL, NULL, md_buf)) { @@ -2943,13 +2933,15 @@ static long atomisp_vidioc_default(struct file *file, void *fh, #else if (isp->motor) #endif - err = v4l2_subdev_call( #ifndef ISP2401 + err = v4l2_subdev_call( isp->inputs[asd->input_curr].motor, + core, ioctl, cmd, arg); #else + err = v4l2_subdev_call( isp->motor, -#endif core, ioctl, cmd, arg); +#endif else err = v4l2_subdev_call( isp->inputs[asd->input_curr].camera, diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.h index fb5fadb5332b..0d2785b9ef99 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c index 744ab6eb42a0..70b53988553c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/module.h> @@ -25,7 +21,6 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/slab.h> -#include <asm/intel-mid.h> #include <media/v4l2-event.h> #include <media/v4l2-mediabus.h> diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.h index ba5c2ab14253..f3d61827ae8c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_SUBDEV_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tables.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tables.h index af09218d8b71..319ded6a96da 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tables.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tables.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __ATOMISP_TABLES_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c index 48b96048cab4..b71cc7bcdbab 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.h index 64ab60f02e85..af354c4bfd3e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_tpg.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_trace_event.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_trace_event.h index 5ce282d6c939..462b296554c7 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_trace_event.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_trace_event.h @@ -12,10 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #undef TRACE_SYSTEM diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c index 663aa916e3ca..3c260f8b52e2 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include <linux/module.h> @@ -28,6 +24,8 @@ #include <linux/delay.h> #include <linux/interrupt.h> +#include <asm/iosf_mbi.h> + #include "../../include/linux/atomisp_gmin_platform.h" #include "atomisp_cmd.h" @@ -46,7 +44,6 @@ #include "hrt/hive_isp_css_mm_hrt.h" #include "device_access.h" -#include <asm/intel-mid.h> /* G-Min addition: pull this in from intel_mid_pm.h */ #define CSTATE_EXIT_LATENCY_C1 1 @@ -386,28 +383,23 @@ done: */ static void punit_ddr_dvfs_enable(bool enable) { - int reg = intel_mid_msgbus_read32(PUNIT_PORT, MRFLD_ISPSSDVFS); int door_bell = 1 << 8; int max_wait = 30; + int reg; + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSDVFS, ®); if (enable) { reg &= ~(MRFLD_BIT0 | MRFLD_BIT1); } else { reg |= (MRFLD_BIT1 | door_bell); reg &= ~(MRFLD_BIT0); } + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, MRFLD_ISPSSDVFS, reg); - intel_mid_msgbus_write32(PUNIT_PORT, MRFLD_ISPSSDVFS, reg); - - /*Check Req_ACK to see freq status, wait until door_bell is cleared*/ - if (reg & door_bell) { - while (max_wait--) { - if (0 == (intel_mid_msgbus_read32(PUNIT_PORT, - MRFLD_ISPSSDVFS) & door_bell)) - break; - - usleep_range(100, 500); - } + /* Check Req_ACK to see freq status, wait until door_bell is cleared */ + while ((reg & door_bell) && max_wait--) { + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSDVFS, ®); + usleep_range(100, 500); } if (max_wait == -1) @@ -421,10 +413,10 @@ int atomisp_mrfld_power_down(struct atomisp_device *isp) u32 reg_value; /* writing 0x3 to ISPSSPM0 bit[1:0] to power off the IUNIT */ - reg_value = intel_mid_msgbus_read32(PUNIT_PORT, MRFLD_ISPSSPM0); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, ®_value); reg_value &= ~MRFLD_ISPSSPM0_ISPSSC_MASK; reg_value |= MRFLD_ISPSSPM0_IUNIT_POWER_OFF; - intel_mid_msgbus_write32(PUNIT_PORT, MRFLD_ISPSSPM0, reg_value); + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, MRFLD_ISPSSPM0, reg_value); /*WA:Enable DVFS*/ if (IS_CHT) @@ -437,8 +429,7 @@ int atomisp_mrfld_power_down(struct atomisp_device *isp) */ timeout = jiffies + msecs_to_jiffies(50); while (1) { - reg_value = intel_mid_msgbus_read32(PUNIT_PORT, - MRFLD_ISPSSPM0); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, ®_value); dev_dbg(isp->dev, "power-off in progress, ISPSSPM0: 0x%x\n", reg_value); /* wait until ISPSSPM0 bit[25:24] shows 0x3 */ @@ -477,14 +468,14 @@ int atomisp_mrfld_power_up(struct atomisp_device *isp) msleep(10); /* writing 0x0 to ISPSSPM0 bit[1:0] to power off the IUNIT */ - reg_value = intel_mid_msgbus_read32(PUNIT_PORT, MRFLD_ISPSSPM0); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, ®_value); reg_value &= ~MRFLD_ISPSSPM0_ISPSSC_MASK; - intel_mid_msgbus_write32(PUNIT_PORT, MRFLD_ISPSSPM0, reg_value); + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE, MRFLD_ISPSSPM0, reg_value); /* FIXME: experienced value for delay */ timeout = jiffies + msecs_to_jiffies(50); while (1) { - reg_value = intel_mid_msgbus_read32(PUNIT_PORT, MRFLD_ISPSSPM0); + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, ®_value); dev_dbg(isp->dev, "power-on in progress, ISPSSPM0: 0x%x\n", reg_value); /* wait until ISPSSPM0 bit[25:24] shows 0x0 */ @@ -755,7 +746,6 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) &subdevs->v4l2_subdev.board_info; struct i2c_adapter *adapter = i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id); - struct camera_sensor_platform_data *sensor_pdata; int sensor_num, i; if (adapter == NULL) { @@ -807,13 +797,7 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) * pixel_format. */ isp->inputs[isp->input_cnt].frame_size.pixel_format = 0; - sensor_pdata = (struct camera_sensor_platform_data *) - board_info->platform_data; - if (sensor_pdata->get_camera_caps) - isp->inputs[isp->input_cnt].camera_caps = - sensor_pdata->get_camera_caps(); - else - isp->inputs[isp->input_cnt].camera_caps = + isp->inputs[isp->input_cnt].camera_caps = atomisp_get_default_camera_caps(); sensor_num = isp->inputs[isp->input_cnt] .camera_caps->sensor_num; @@ -1020,7 +1004,7 @@ csi_and_subdev_probe_failed: v4l2_device_unregister(&isp->v4l2_dev); v4l2_device_failed: media_device_unregister(&isp->media_dev); - media_device_cleanup(&isp->media_dev); + media_device_cleanup(&isp->media_dev); return ret; } @@ -1155,17 +1139,12 @@ static int init_atomisp_wdts(struct atomisp_device *isp) struct atomisp_sub_device *asd = &isp->asd[i]; asd = &isp->asd[i]; #ifndef ISP2401 - setup_timer(&asd->wdt, atomisp_wdt, (unsigned long)isp); + timer_setup(&asd->wdt, atomisp_wdt, 0); #else - setup_timer(&asd->video_out_capture.wdt, - atomisp_wdt, (unsigned long)&asd->video_out_capture); - setup_timer(&asd->video_out_preview.wdt, - atomisp_wdt, (unsigned long)&asd->video_out_preview); - setup_timer(&asd->video_out_vf.wdt, - atomisp_wdt, (unsigned long)&asd->video_out_vf); - setup_timer(&asd->video_out_video_capture.wdt, - atomisp_wdt, - (unsigned long)&asd->video_out_video_capture); + timer_setup(&asd->video_out_capture.wdt, atomisp_wdt, 0); + timer_setup(&asd->video_out_preview.wdt, atomisp_wdt, 0); + timer_setup(&asd->video_out_vf.wdt, atomisp_wdt, 0); + timer_setup(&asd->video_out_video_capture.wdt, atomisp_wdt, 0); #endif } return 0; @@ -1323,7 +1302,7 @@ static int atomisp_pci_probe(struct pci_dev *dev, isp->dfs = &dfs_config_cht; isp->pdev->d3cold_delay = 0; - val = intel_mid_msgbus_read32(CCK_PORT, CCK_FUSE_REG_0); + iosf_mbi_read(CCK_PORT, MBI_REG_READ, CCK_FUSE_REG_0, &val); switch (val & CCK_FUSE_HPLL_FREQ_MASK) { case 0x00: isp->hpll_freq = HPLL_FREQ_800MHZ; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.h index 191b2e57a810..944a6cf40a2f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf.h index 766218ed3649..914aa7f98700 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf.h @@ -18,7 +18,6 @@ #include <sp.h> #include <type_support.h> #include <math_support.h> -#include <storage_class.h> #include <assert_support.h> #include <platform_support.h> #include "ia_css_circbuf_comm.h" @@ -45,7 +44,7 @@ struct ia_css_circbuf_s { * @param elems An array of elements. * @param desc The descriptor set to the size using ia_css_circbuf_desc_init(). */ -STORAGE_CLASS_EXTERN void ia_css_circbuf_create( +extern void ia_css_circbuf_create( ia_css_circbuf_t *cb, ia_css_circbuf_elem_t *elems, ia_css_circbuf_desc_t *desc); @@ -55,7 +54,7 @@ STORAGE_CLASS_EXTERN void ia_css_circbuf_create( * * @param cb The pointer to the circular buffer. */ -STORAGE_CLASS_EXTERN void ia_css_circbuf_destroy( +extern void ia_css_circbuf_destroy( ia_css_circbuf_t *cb); /** @@ -68,7 +67,7 @@ STORAGE_CLASS_EXTERN void ia_css_circbuf_destroy( * * @return the pop-out value. */ -STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_pop( +extern uint32_t ia_css_circbuf_pop( ia_css_circbuf_t *cb); /** @@ -82,7 +81,7 @@ STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_pop( * * @return the extracted value. */ -STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_extract( +extern uint32_t ia_css_circbuf_extract( ia_css_circbuf_t *cb, int offset); @@ -97,7 +96,7 @@ STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_extract( * @param elem The pointer to the element. * @param val The value to be set. */ -STORAGE_CLASS_INLINE void ia_css_circbuf_elem_set_val( +static inline void ia_css_circbuf_elem_set_val( ia_css_circbuf_elem_t *elem, uint32_t val) { @@ -111,7 +110,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_elem_set_val( * * @param elem The pointer to the element. */ -STORAGE_CLASS_INLINE void ia_css_circbuf_elem_init( +static inline void ia_css_circbuf_elem_init( ia_css_circbuf_elem_t *elem) { OP___assert(elem != NULL); @@ -124,7 +123,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_elem_init( * @param src The element as the copy source. * @param dest The element as the copy destination. */ -STORAGE_CLASS_INLINE void ia_css_circbuf_elem_cpy( +static inline void ia_css_circbuf_elem_cpy( ia_css_circbuf_elem_t *src, ia_css_circbuf_elem_t *dest) { @@ -143,7 +142,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_elem_cpy( * * @return the position at offset. */ -STORAGE_CLASS_INLINE uint8_t ia_css_circbuf_get_pos_at_offset( +static inline uint8_t ia_css_circbuf_get_pos_at_offset( ia_css_circbuf_t *cb, uint32_t base, int offset) @@ -176,7 +175,7 @@ STORAGE_CLASS_INLINE uint8_t ia_css_circbuf_get_pos_at_offset( * * @return the offset. */ -STORAGE_CLASS_INLINE int ia_css_circbuf_get_offset( +static inline int ia_css_circbuf_get_offset( ia_css_circbuf_t *cb, uint32_t src_pos, uint32_t dest_pos) @@ -201,7 +200,7 @@ STORAGE_CLASS_INLINE int ia_css_circbuf_get_offset( * * TODO: Test this API. */ -STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_size( +static inline uint32_t ia_css_circbuf_get_size( ia_css_circbuf_t *cb) { OP___assert(cb != NULL); @@ -217,7 +216,7 @@ STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_size( * * @return the number of available elements. */ -STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_num_elems( +static inline uint32_t ia_css_circbuf_get_num_elems( ia_css_circbuf_t *cb) { int num; @@ -239,7 +238,7 @@ STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_num_elems( * - true when it is empty. * - false when it is not empty. */ -STORAGE_CLASS_INLINE bool ia_css_circbuf_is_empty( +static inline bool ia_css_circbuf_is_empty( ia_css_circbuf_t *cb) { OP___assert(cb != NULL); @@ -257,7 +256,7 @@ STORAGE_CLASS_INLINE bool ia_css_circbuf_is_empty( * - true when it is full. * - false when it is not full. */ -STORAGE_CLASS_INLINE bool ia_css_circbuf_is_full(ia_css_circbuf_t *cb) +static inline bool ia_css_circbuf_is_full(ia_css_circbuf_t *cb) { OP___assert(cb != NULL); OP___assert(cb->desc != NULL); @@ -274,7 +273,7 @@ STORAGE_CLASS_INLINE bool ia_css_circbuf_is_full(ia_css_circbuf_t *cb) * @param cb The pointer to the circular buffer. * @param elem The new element. */ -STORAGE_CLASS_INLINE void ia_css_circbuf_write( +static inline void ia_css_circbuf_write( ia_css_circbuf_t *cb, ia_css_circbuf_elem_t elem) { @@ -298,7 +297,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_write( * @param cb The pointer to the circular buffer. * @param val The value to be pushed in. */ -STORAGE_CLASS_INLINE void ia_css_circbuf_push( +static inline void ia_css_circbuf_push( ia_css_circbuf_t *cb, uint32_t val) { @@ -321,7 +320,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_push( * * @return: The number of free elements. */ -STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_free_elems( +static inline uint32_t ia_css_circbuf_get_free_elems( ia_css_circbuf_t *cb) { OP___assert(cb != NULL); @@ -338,7 +337,7 @@ STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_get_free_elems( * * @return the elements value. */ -STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek( +extern uint32_t ia_css_circbuf_peek( ia_css_circbuf_t *cb, int offset); @@ -350,7 +349,7 @@ STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek( * * @return the elements value. */ -STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek_from_start( +extern uint32_t ia_css_circbuf_peek_from_start( ia_css_circbuf_t *cb, int offset); @@ -369,7 +368,7 @@ STORAGE_CLASS_EXTERN uint32_t ia_css_circbuf_peek_from_start( * @return true on succesfully increasing the size * false on failure */ -STORAGE_CLASS_EXTERN bool ia_css_circbuf_increase_size( +extern bool ia_css_circbuf_increase_size( ia_css_circbuf_t *cb, unsigned int sz_delta, ia_css_circbuf_elem_t *elems); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf_desc.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf_desc.h index a8447d409c31..8dd7cd6cd3d8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf_desc.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/base/circbuf/interface/ia_css_circbuf_desc.h @@ -17,7 +17,6 @@ #include <type_support.h> #include <math_support.h> -#include <storage_class.h> #include <platform_support.h> #include <sp.h> #include "ia_css_circbuf_comm.h" @@ -35,7 +34,7 @@ * - true when it is empty. * - false when it is not empty. */ -STORAGE_CLASS_INLINE bool ia_css_circbuf_desc_is_empty( +static inline bool ia_css_circbuf_desc_is_empty( ia_css_circbuf_desc_t *cb_desc) { OP___assert(cb_desc != NULL); @@ -52,7 +51,7 @@ STORAGE_CLASS_INLINE bool ia_css_circbuf_desc_is_empty( * - true when it is full. * - false when it is not full. */ -STORAGE_CLASS_INLINE bool ia_css_circbuf_desc_is_full( +static inline bool ia_css_circbuf_desc_is_full( ia_css_circbuf_desc_t *cb_desc) { OP___assert(cb_desc != NULL); @@ -65,7 +64,7 @@ STORAGE_CLASS_INLINE bool ia_css_circbuf_desc_is_full( * @param cb_desc The pointer circular buffer descriptor * @param size The size of the circular buffer */ -STORAGE_CLASS_INLINE void ia_css_circbuf_desc_init( +static inline void ia_css_circbuf_desc_init( ia_css_circbuf_desc_t *cb_desc, int8_t size) { @@ -82,7 +81,7 @@ STORAGE_CLASS_INLINE void ia_css_circbuf_desc_init( * * @return the position in the circular buffer descriptor. */ -STORAGE_CLASS_INLINE uint8_t ia_css_circbuf_desc_get_pos_at_offset( +static inline uint8_t ia_css_circbuf_desc_get_pos_at_offset( ia_css_circbuf_desc_t *cb_desc, uint32_t base, int offset) @@ -114,7 +113,7 @@ STORAGE_CLASS_INLINE uint8_t ia_css_circbuf_desc_get_pos_at_offset( * * @return the offset. */ -STORAGE_CLASS_INLINE int ia_css_circbuf_desc_get_offset( +static inline int ia_css_circbuf_desc_get_offset( ia_css_circbuf_desc_t *cb_desc, uint32_t src_pos, uint32_t dest_pos) @@ -135,7 +134,7 @@ STORAGE_CLASS_INLINE int ia_css_circbuf_desc_get_offset( * * @return The number of available elements. */ -STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_desc_get_num_elems( +static inline uint32_t ia_css_circbuf_desc_get_num_elems( ia_css_circbuf_desc_t *cb_desc) { int num; @@ -155,7 +154,7 @@ STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_desc_get_num_elems( * * @return: The number of free elements. */ -STORAGE_CLASS_INLINE uint32_t ia_css_circbuf_desc_get_free_elems( +static inline uint32_t ia_css_circbuf_desc_get_free_elems( ia_css_circbuf_desc_t *cb_desc) { uint32_t num; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c index 17d3b7de93ba..98a2a3e9b3e6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/pipe/src/pipe_binarydesc.c @@ -22,6 +22,7 @@ #include <assert_support.h> /* HRT_GDC_N */ #include "gdc_device.h" +#include <linux/kernel.h> /* This module provides a binary descriptions to used to find a binary. Since, * every stage is associated with a binary, it implicity helps stage @@ -147,11 +148,9 @@ enum ia_css_err sh_css_bds_factor_get_numerator_denominator( unsigned int *bds_factor_denominator) { unsigned int i; - unsigned int bds_list_size = sizeof(bds_factors_list) / - sizeof(struct sh_css_bds_factor); /* Loop over all bds factors until a match is found */ - for (i = 0; i < bds_list_size; i++) { + for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) { if (bds_factors_list[i].bds_factor == bds_factor) { *bds_factor_numerator = bds_factors_list[i].numerator; *bds_factor_denominator = bds_factors_list[i].denominator; @@ -170,8 +169,6 @@ enum ia_css_err binarydesc_calculate_bds_factor( unsigned int *bds_factor) { unsigned int i; - unsigned int bds_list_size = sizeof(bds_factors_list) / - sizeof(struct sh_css_bds_factor); unsigned int in_w = input_res.width, in_h = input_res.height, out_w = output_res.width, out_h = output_res.height; @@ -186,7 +183,7 @@ enum ia_css_err binarydesc_calculate_bds_factor( assert(out_w != 0 && out_h != 0); /* Loop over all bds factors until a match is found */ - for (i = 0; i < bds_list_size; i++) { + for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) { unsigned num = bds_factors_list[i].numerator; unsigned den = bds_factors_list[i].denominator; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/util/src/util.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/util/src/util.c index 08f486e20a65..54193789a809 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/util/src/util.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/camera/util/src/util.c @@ -111,7 +111,7 @@ unsigned int ia_css_util_input_format_bpp( break; } -return rval; + return rval; } enum ia_css_err ia_css_util_check_vf_info( diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/input_formatter_subsystem_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/input_formatter_subsystem_defs.h index 16bfe1d80bc9..7766f78cd123 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/input_formatter_subsystem_defs.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2400_system/hrt/input_formatter_subsystem_defs.h @@ -12,7 +12,7 @@ * more details. */ -#ifndef _if_subsystem_defs_h +#ifndef _if_subsystem_defs_h__ #define _if_subsystem_defs_h__ #define HIVE_IFMT_GP_REGS_INPUT_SWITCH_LUT_REG_0 0 diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/host/csi_rx_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/host/csi_rx_private.h index 5819bcff5e55..6720ab55d6f5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/host/csi_rx_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/host/csi_rx_private.h @@ -34,7 +34,7 @@ * @brief Get the csi rx fe state. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_get_state( +static inline void csi_rx_fe_ctrl_get_state( const csi_rx_frontend_ID_t ID, csi_rx_fe_ctrl_state_t *state) { @@ -73,7 +73,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_get_state( * @brief Get the state of the csi rx fe dlane process. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_get_dlane_state( +static inline void csi_rx_fe_ctrl_get_dlane_state( const csi_rx_frontend_ID_t ID, const uint32_t lane, csi_rx_fe_ctrl_lane_t *dlane_state) @@ -89,7 +89,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_get_dlane_state( * @brief dump the csi rx fe state. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_dump_state( +static inline void csi_rx_fe_ctrl_dump_state( const csi_rx_frontend_ID_t ID, csi_rx_fe_ctrl_state_t *state) { @@ -118,7 +118,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_dump_state( * @brief Get the csi rx be state. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_be_ctrl_get_state( +static inline void csi_rx_be_ctrl_get_state( const csi_rx_backend_ID_t ID, csi_rx_be_ctrl_state_t *state) { @@ -181,7 +181,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_be_ctrl_get_state( * @brief Dump the csi rx be state. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_be_ctrl_dump_state( +static inline void csi_rx_be_ctrl_dump_state( const csi_rx_backend_ID_t ID, csi_rx_be_ctrl_state_t *state) { @@ -225,7 +225,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_be_ctrl_dump_state( * @brief Load the register value. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C hrt_data csi_rx_fe_ctrl_reg_load( +static inline hrt_data csi_rx_fe_ctrl_reg_load( const csi_rx_frontend_ID_t ID, const hrt_address reg) { @@ -239,7 +239,7 @@ STORAGE_CLASS_CSI_RX_C hrt_data csi_rx_fe_ctrl_reg_load( * @brief Store a value to the register. * Refer to "ibuf_ctrl_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_reg_store( +static inline void csi_rx_fe_ctrl_reg_store( const csi_rx_frontend_ID_t ID, const hrt_address reg, const hrt_data value) @@ -253,7 +253,7 @@ STORAGE_CLASS_CSI_RX_C void csi_rx_fe_ctrl_reg_store( * @brief Load the register value. * Refer to "csi_rx_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C hrt_data csi_rx_be_ctrl_reg_load( +static inline hrt_data csi_rx_be_ctrl_reg_load( const csi_rx_backend_ID_t ID, const hrt_address reg) { @@ -267,7 +267,7 @@ STORAGE_CLASS_CSI_RX_C hrt_data csi_rx_be_ctrl_reg_load( * @brief Store a value to the register. * Refer to "ibuf_ctrl_public.h" for details. */ -STORAGE_CLASS_CSI_RX_C void csi_rx_be_ctrl_reg_store( +static inline void csi_rx_be_ctrl_reg_store( const csi_rx_backend_ID_t ID, const hrt_address reg, const hrt_data value) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/input_formatter_subsystem_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/input_formatter_subsystem_defs.h index 16bfe1d80bc9..7766f78cd123 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/input_formatter_subsystem_defs.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_csi2p_system/hrt/input_formatter_subsystem_defs.h @@ -12,7 +12,7 @@ * more details. */ -#ifndef _if_subsystem_defs_h +#ifndef _if_subsystem_defs_h__ #define _if_subsystem_defs_h__ #define HIVE_IFMT_GP_REGS_INPUT_SWITCH_LUT_REG_0 0 diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/input_formatter_subsystem_defs.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/input_formatter_subsystem_defs.h index 16bfe1d80bc9..7766f78cd123 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/input_formatter_subsystem_defs.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/css_2401_system/hrt/input_formatter_subsystem_defs.h @@ -12,7 +12,7 @@ * more details. */ -#ifndef _if_subsystem_defs_h +#ifndef _if_subsystem_defs_h__ #define _if_subsystem_defs_h__ #define HIVE_IFMT_GP_REGS_INPUT_SWITCH_LUT_REG_0 0 diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/dma.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/dma.c index 87a25d4289ec..770db7dff5d3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/dma.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/dma.c @@ -12,7 +12,7 @@ * more details. */ -#include <stddef.h> /* NULL */ +#include <linux/kernel.h> #include "dma.h" diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/event_fifo_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/event_fifo_private.h index 9d3a29696094..bcfb734c2ed3 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/event_fifo_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/event_fifo_private.h @@ -28,7 +28,7 @@ STORAGE_CLASS_EVENT_C void event_wait_for(const event_ID_t ID) assert(ID < N_EVENT_ID); assert(event_source_addr[ID] != ((hrt_address)-1)); (void)ia_css_device_load_uint32(event_source_addr[ID]); -return; + return; } STORAGE_CLASS_EVENT_C void cnd_event_wait_for(const event_ID_t ID, diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor.c index 1087944d637f..1bf292401adc 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor.c @@ -38,12 +38,12 @@ STORAGE_CLASS_FIFO_MONITOR_DATA unsigned int FIFO_SWITCH_ADDR[N_FIFO_SWITCH] = { #include "fifo_monitor_private.h" #endif /* __INLINE_FIFO_MONITOR__ */ -STORAGE_CLASS_INLINE bool fifo_monitor_status_valid ( +static inline bool fifo_monitor_status_valid ( const fifo_monitor_ID_t ID, const unsigned int reg, const unsigned int port_id); -STORAGE_CLASS_INLINE bool fifo_monitor_status_accept( +static inline bool fifo_monitor_status_accept( const fifo_monitor_ID_t ID, const unsigned int reg, const unsigned int port_id); @@ -546,7 +546,7 @@ void fifo_monitor_get_state( return; } -STORAGE_CLASS_INLINE bool fifo_monitor_status_valid ( +static inline bool fifo_monitor_status_valid ( const fifo_monitor_ID_t ID, const unsigned int reg, const unsigned int port_id) @@ -556,7 +556,7 @@ STORAGE_CLASS_INLINE bool fifo_monitor_status_valid ( return (data >> (((port_id * 2) + _hive_str_mon_valid_offset))) & 0x1; } -STORAGE_CLASS_INLINE bool fifo_monitor_status_accept( +static inline bool fifo_monitor_status_accept( const fifo_monitor_ID_t ID, const unsigned int reg, const unsigned int port_id) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor_private.h index 618b2f7e9c75..d58cd7d1828d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/fifo_monitor_private.h @@ -33,26 +33,26 @@ STORAGE_CLASS_FIFO_MONITOR_C void fifo_switch_set( const fifo_switch_t switch_id, const hrt_data sel) { -assert(ID == FIFO_MONITOR0_ID); -assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); -assert(switch_id < N_FIFO_SWITCH); + assert(ID == FIFO_MONITOR0_ID); + assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); + assert(switch_id < N_FIFO_SWITCH); (void)ID; gp_device_reg_store(GP_DEVICE0_ID, FIFO_SWITCH_ADDR[switch_id], sel); -return; + return; } STORAGE_CLASS_FIFO_MONITOR_C hrt_data fifo_switch_get( const fifo_monitor_ID_t ID, const fifo_switch_t switch_id) { -assert(ID == FIFO_MONITOR0_ID); -assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); -assert(switch_id < N_FIFO_SWITCH); + assert(ID == FIFO_MONITOR0_ID); + assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); + assert(switch_id < N_FIFO_SWITCH); (void)ID; -return gp_device_reg_load(GP_DEVICE0_ID, FIFO_SWITCH_ADDR[switch_id]); + return gp_device_reg_load(GP_DEVICE0_ID, FIFO_SWITCH_ADDR[switch_id]); } @@ -61,19 +61,19 @@ STORAGE_CLASS_FIFO_MONITOR_C void fifo_monitor_reg_store( const unsigned int reg, const hrt_data value) { -assert(ID < N_FIFO_MONITOR_ID); -assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); + assert(ID < N_FIFO_MONITOR_ID); + assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(FIFO_MONITOR_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_FIFO_MONITOR_C hrt_data fifo_monitor_reg_load( const fifo_monitor_ID_t ID, const unsigned int reg) { -assert(ID < N_FIFO_MONITOR_ID); -assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(FIFO_MONITOR_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_FIFO_MONITOR_ID); + assert(FIFO_MONITOR_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(FIFO_MONITOR_BASE[ID] + reg*sizeof(hrt_data)); } #endif /* __FIFO_MONITOR_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gdc.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gdc.c index 69fa616889b1..1966b147f8ab 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gdc.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gdc.c @@ -22,12 +22,12 @@ /* * Local function declarations */ -STORAGE_CLASS_INLINE void gdc_reg_store( +static inline void gdc_reg_store( const gdc_ID_t ID, const unsigned int reg, const hrt_data value); -STORAGE_CLASS_INLINE hrt_data gdc_reg_load( +static inline hrt_data gdc_reg_load( const gdc_ID_t ID, const unsigned int reg); @@ -62,7 +62,7 @@ void gdc_lut_store( gdc_reg_store(ID, lut_offset++, word_0); gdc_reg_store(ID, lut_offset++, word_1); } -return; + return; } /* @@ -103,25 +103,25 @@ int gdc_get_unity( { assert(ID < N_GDC_ID); (void)ID; -return (int)(1UL << HRT_GDC_FRAC_BITS); + return (int)(1UL << HRT_GDC_FRAC_BITS); } /* * Local function implementations */ -STORAGE_CLASS_INLINE void gdc_reg_store( +static inline void gdc_reg_store( const gdc_ID_t ID, const unsigned int reg, const hrt_data value) { ia_css_device_store_uint32(GDC_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } -STORAGE_CLASS_INLINE hrt_data gdc_reg_load( +static inline hrt_data gdc_reg_load( const gdc_ID_t ID, const unsigned int reg) { -return ia_css_device_load_uint32(GDC_BASE[ID] + reg*sizeof(hrt_data)); + return ia_css_device_load_uint32(GDC_BASE[ID] + reg*sizeof(hrt_data)); } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device.c index 9a34ac052adf..da88aa3af664 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device.c @@ -104,5 +104,5 @@ void gp_device_get_state( _REG_GP_SYNCGEN_FRAME_CNT_ADDR); state->soft_reset = gp_device_reg_load(ID, _REG_GP_SOFT_RESET_ADDR); -return; + return; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device_private.h index bce1fdf79114..7c0362c29411 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gp_device_private.h @@ -26,21 +26,21 @@ STORAGE_CLASS_GP_DEVICE_C void gp_device_reg_store( const unsigned int reg_addr, const hrt_data value) { -assert(ID < N_GP_DEVICE_ID); -assert(GP_DEVICE_BASE[ID] != (hrt_address)-1); -assert((reg_addr % sizeof(hrt_data)) == 0); + assert(ID < N_GP_DEVICE_ID); + assert(GP_DEVICE_BASE[ID] != (hrt_address)-1); + assert((reg_addr % sizeof(hrt_data)) == 0); ia_css_device_store_uint32(GP_DEVICE_BASE[ID] + reg_addr, value); -return; + return; } STORAGE_CLASS_GP_DEVICE_C hrt_data gp_device_reg_load( const gp_device_ID_t ID, const hrt_address reg_addr) { -assert(ID < N_GP_DEVICE_ID); -assert(GP_DEVICE_BASE[ID] != (hrt_address)-1); -assert((reg_addr % sizeof(hrt_data)) == 0); -return ia_css_device_load_uint32(GP_DEVICE_BASE[ID] + reg_addr); + assert(ID < N_GP_DEVICE_ID); + assert(GP_DEVICE_BASE[ID] != (hrt_address)-1); + assert((reg_addr % sizeof(hrt_data)) == 0); + return ia_css_device_load_uint32(GP_DEVICE_BASE[ID] + reg_addr); } #endif /* __GP_DEVICE_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gpio_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gpio_private.h index 6ace2184b522..b6ebf34eaa9d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gpio_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gpio_private.h @@ -29,7 +29,7 @@ STORAGE_CLASS_GPIO_C void gpio_reg_store( OP___assert(ID < N_GPIO_ID); OP___assert(GPIO_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(GPIO_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_GPIO_C hrt_data gpio_reg_load( @@ -38,7 +38,7 @@ STORAGE_CLASS_GPIO_C hrt_data gpio_reg_load( { OP___assert(ID < N_GPIO_ID); OP___assert(GPIO_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(GPIO_BASE[ID] + reg*sizeof(hrt_data)); + return ia_css_device_load_uint32(GPIO_BASE[ID] + reg*sizeof(hrt_data)); } #endif /* __GPIO_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hmem_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hmem_private.h index 2b636e0e6482..32a780380e11 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hmem_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/hmem_private.h @@ -22,9 +22,9 @@ STORAGE_CLASS_HMEM_C size_t sizeof_hmem( const hmem_ID_t ID) { -assert(ID < N_HMEM_ID); + assert(ID < N_HMEM_ID); (void)ID; -return HMEM_SIZE*sizeof(hmem_data_t); + return HMEM_SIZE*sizeof(hmem_data_t); } #endif /* __HMEM_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_formatter_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_formatter_private.h index d34933e44aa9..2f42a9c2771c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_formatter_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_formatter_private.h @@ -26,21 +26,21 @@ STORAGE_CLASS_INPUT_FORMATTER_C void input_formatter_reg_store( const hrt_address reg_addr, const hrt_data value) { -assert(ID < N_INPUT_FORMATTER_ID); -assert(INPUT_FORMATTER_BASE[ID] != (hrt_address)-1); -assert((reg_addr % sizeof(hrt_data)) == 0); + assert(ID < N_INPUT_FORMATTER_ID); + assert(INPUT_FORMATTER_BASE[ID] != (hrt_address)-1); + assert((reg_addr % sizeof(hrt_data)) == 0); ia_css_device_store_uint32(INPUT_FORMATTER_BASE[ID] + reg_addr, value); -return; + return; } STORAGE_CLASS_INPUT_FORMATTER_C hrt_data input_formatter_reg_load( const input_formatter_ID_t ID, const unsigned int reg_addr) { -assert(ID < N_INPUT_FORMATTER_ID); -assert(INPUT_FORMATTER_BASE[ID] != (hrt_address)-1); -assert((reg_addr % sizeof(hrt_data)) == 0); -return ia_css_device_load_uint32(INPUT_FORMATTER_BASE[ID] + reg_addr); + assert(ID < N_INPUT_FORMATTER_ID); + assert(INPUT_FORMATTER_BASE[ID] != (hrt_address)-1); + assert((reg_addr % sizeof(hrt_data)) == 0); + return ia_css_device_load_uint32(INPUT_FORMATTER_BASE[ID] + reg_addr); } #endif /* __INPUT_FORMATTER_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system.c index f35e18987b67..bd6821e436b2 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system.c @@ -81,27 +81,27 @@ static input_system_error_t input_system_multiplexer_cfg( -STORAGE_CLASS_INLINE void capture_unit_get_state( +static inline void capture_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, capture_unit_state_t *state); -STORAGE_CLASS_INLINE void acquisition_unit_get_state( +static inline void acquisition_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, acquisition_unit_state_t *state); -STORAGE_CLASS_INLINE void ctrl_unit_get_state( +static inline void ctrl_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, ctrl_unit_state_t *state); -STORAGE_CLASS_INLINE void mipi_port_get_state( +static inline void mipi_port_get_state( const rx_ID_t ID, const mipi_port_ID_t port_ID, mipi_port_state_t *state); -STORAGE_CLASS_INLINE void rx_channel_get_state( +static inline void rx_channel_get_state( const rx_ID_t ID, const unsigned int ch_id, rx_channel_state_t *state); @@ -173,7 +173,7 @@ void input_system_get_state( &(state->ctrl_unit_state[sub_id - CTRL_UNIT0_ID])); } -return; + return; } void receiver_get_state( @@ -245,7 +245,7 @@ void receiver_get_state( state->be_irq_clear = receiver_reg_load(ID, _HRT_CSS_RECEIVER_BE_IRQ_CLEAR_REG_IDX); -return; + return; } bool is_mipi_format_yuv420( @@ -258,7 +258,7 @@ bool is_mipi_format_yuv420( (mipi_format == MIPI_FORMAT_YUV420_10_SHIFT)); /* MIPI_FORMAT_YUV420_8_LEGACY is not YUV420 */ -return is_yuv420; + return is_yuv420; } void receiver_set_compression( @@ -300,7 +300,7 @@ void receiver_set_compression( reg = ((field_id < 6)?(val << (field_id * 5)):(val << ((field_id - 6) * 5))); receiver_reg_store(ID, addr, reg); -return; + return; } void receiver_port_enable( @@ -319,7 +319,7 @@ void receiver_port_enable( receiver_port_reg_store(ID, port_ID, _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, reg); -return; + return; } bool is_receiver_port_enabled( @@ -328,7 +328,7 @@ bool is_receiver_port_enabled( { hrt_data reg = receiver_port_reg_load(ID, port_ID, _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX); -return ((reg & 0x01) != 0); + return ((reg & 0x01) != 0); } void receiver_irq_enable( @@ -338,14 +338,14 @@ void receiver_irq_enable( { receiver_port_reg_store(ID, port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, irq_info); -return; + return; } rx_irq_info_t receiver_get_irq_info( const rx_ID_t ID, const mipi_port_ID_t port_ID) { -return receiver_port_reg_load(ID, + return receiver_port_reg_load(ID, port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX); } @@ -356,10 +356,10 @@ void receiver_irq_clear( { receiver_port_reg_store(ID, port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX, irq_info); -return; + return; } -STORAGE_CLASS_INLINE void capture_unit_get_state( +static inline void capture_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, capture_unit_state_t *state) @@ -418,10 +418,10 @@ STORAGE_CLASS_INLINE void capture_unit_get_state( sub_id, CAPT_FSM_STATE_INFO_REG_ID); -return; + return; } -STORAGE_CLASS_INLINE void acquisition_unit_get_state( +static inline void acquisition_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, acquisition_unit_state_t *state) @@ -468,10 +468,10 @@ STORAGE_CLASS_INLINE void acquisition_unit_get_state( sub_id, ACQ_INT_CNTR_INFO_REG_ID); -return; + return; } -STORAGE_CLASS_INLINE void ctrl_unit_get_state( +static inline void ctrl_unit_get_state( const input_system_ID_t ID, const sub_system_ID_t sub_id, ctrl_unit_state_t *state) @@ -551,10 +551,10 @@ STORAGE_CLASS_INLINE void ctrl_unit_get_state( sub_id, ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID); -return; + return; } -STORAGE_CLASS_INLINE void mipi_port_get_state( +static inline void mipi_port_get_state( const rx_ID_t ID, const mipi_port_ID_t port_ID, mipi_port_state_t *state) @@ -587,10 +587,10 @@ STORAGE_CLASS_INLINE void mipi_port_get_state( state->lane_rx_count[i] = (uint8_t)((state->rx_count)>>(i*8)); } -return; + return; } -STORAGE_CLASS_INLINE void rx_channel_get_state( +static inline void rx_channel_get_state( const rx_ID_t ID, const unsigned int ch_id, rx_channel_state_t *state) @@ -602,30 +602,30 @@ STORAGE_CLASS_INLINE void rx_channel_get_state( assert(state != NULL); switch (ch_id) { - case 0: - state->comp_scheme0 = receiver_reg_load(ID, + case 0: + state->comp_scheme0 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX); - state->comp_scheme1 = receiver_reg_load(ID, + state->comp_scheme1 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX); - break; - case 1: - state->comp_scheme0 = receiver_reg_load(ID, + break; + case 1: + state->comp_scheme0 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX); - state->comp_scheme1 = receiver_reg_load(ID, + state->comp_scheme1 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX); - break; - case 2: - state->comp_scheme0 = receiver_reg_load(ID, + break; + case 2: + state->comp_scheme0 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX); - state->comp_scheme1 = receiver_reg_load(ID, + state->comp_scheme1 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX); - break; - case 3: - state->comp_scheme0 = receiver_reg_load(ID, + break; + case 3: + state->comp_scheme0 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX); - state->comp_scheme1 = receiver_reg_load(ID, + state->comp_scheme1 = receiver_reg_load(ID, _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX); - break; + break; } /* See Table 7.1.17,..., 7.1.24 */ @@ -640,7 +640,7 @@ STORAGE_CLASS_INLINE void rx_channel_get_state( state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3); } -return; + return; } // MW: "2400" in the name is not good, but this is to avoid a naming conflict diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system_private.h index ed1b947b00f9..118185eb86e9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/input_system_private.h @@ -26,19 +26,19 @@ STORAGE_CLASS_INPUT_SYSTEM_C void input_system_reg_store( const hrt_address reg, const hrt_data value) { -assert(ID < N_INPUT_SYSTEM_ID); -assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_INPUT_SYSTEM_ID); + assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(INPUT_SYSTEM_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_INPUT_SYSTEM_C hrt_data input_system_reg_load( const input_system_ID_t ID, const hrt_address reg) { -assert(ID < N_INPUT_SYSTEM_ID); -assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(INPUT_SYSTEM_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_INPUT_SYSTEM_ID); + assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(INPUT_SYSTEM_BASE[ID] + reg*sizeof(hrt_data)); } STORAGE_CLASS_INPUT_SYSTEM_C void receiver_reg_store( @@ -46,19 +46,19 @@ STORAGE_CLASS_INPUT_SYSTEM_C void receiver_reg_store( const hrt_address reg, const hrt_data value) { -assert(ID < N_RX_ID); -assert(RX_BASE[ID] != (hrt_address)-1); + assert(ID < N_RX_ID); + assert(RX_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(RX_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_INPUT_SYSTEM_C hrt_data receiver_reg_load( const rx_ID_t ID, const hrt_address reg) { -assert(ID < N_RX_ID); -assert(RX_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(RX_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_RX_ID); + assert(RX_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(RX_BASE[ID] + reg*sizeof(hrt_data)); } STORAGE_CLASS_INPUT_SYSTEM_C void receiver_port_reg_store( @@ -67,12 +67,12 @@ STORAGE_CLASS_INPUT_SYSTEM_C void receiver_port_reg_store( const hrt_address reg, const hrt_data value) { -assert(ID < N_RX_ID); -assert(port_ID < N_MIPI_PORT_ID); -assert(RX_BASE[ID] != (hrt_address)-1); -assert(MIPI_PORT_OFFSET[port_ID] != (hrt_address)-1); + assert(ID < N_RX_ID); + assert(port_ID < N_MIPI_PORT_ID); + assert(RX_BASE[ID] != (hrt_address)-1); + assert(MIPI_PORT_OFFSET[port_ID] != (hrt_address)-1); ia_css_device_store_uint32(RX_BASE[ID] + MIPI_PORT_OFFSET[port_ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_INPUT_SYSTEM_C hrt_data receiver_port_reg_load( @@ -80,11 +80,11 @@ STORAGE_CLASS_INPUT_SYSTEM_C hrt_data receiver_port_reg_load( const mipi_port_ID_t port_ID, const hrt_address reg) { -assert(ID < N_RX_ID); -assert(port_ID < N_MIPI_PORT_ID); -assert(RX_BASE[ID] != (hrt_address)-1); -assert(MIPI_PORT_OFFSET[port_ID] != (hrt_address)-1); -return ia_css_device_load_uint32(RX_BASE[ID] + MIPI_PORT_OFFSET[port_ID] + reg*sizeof(hrt_data)); + assert(ID < N_RX_ID); + assert(port_ID < N_MIPI_PORT_ID); + assert(RX_BASE[ID] != (hrt_address)-1); + assert(MIPI_PORT_OFFSET[port_ID] != (hrt_address)-1); + return ia_css_device_load_uint32(RX_BASE[ID] + MIPI_PORT_OFFSET[port_ID] + reg*sizeof(hrt_data)); } STORAGE_CLASS_INPUT_SYSTEM_C void input_system_sub_system_reg_store( @@ -93,12 +93,12 @@ STORAGE_CLASS_INPUT_SYSTEM_C void input_system_sub_system_reg_store( const hrt_address reg, const hrt_data value) { -assert(ID < N_INPUT_SYSTEM_ID); -assert(sub_ID < N_SUB_SYSTEM_ID); -assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); -assert(SUB_SYSTEM_OFFSET[sub_ID] != (hrt_address)-1); + assert(ID < N_INPUT_SYSTEM_ID); + assert(sub_ID < N_SUB_SYSTEM_ID); + assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); + assert(SUB_SYSTEM_OFFSET[sub_ID] != (hrt_address)-1); ia_css_device_store_uint32(INPUT_SYSTEM_BASE[ID] + SUB_SYSTEM_OFFSET[sub_ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_INPUT_SYSTEM_C hrt_data input_system_sub_system_reg_load( @@ -106,11 +106,11 @@ STORAGE_CLASS_INPUT_SYSTEM_C hrt_data input_system_sub_system_reg_load( const sub_system_ID_t sub_ID, const hrt_address reg) { -assert(ID < N_INPUT_SYSTEM_ID); -assert(sub_ID < N_SUB_SYSTEM_ID); -assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); -assert(SUB_SYSTEM_OFFSET[sub_ID] != (hrt_address)-1); -return ia_css_device_load_uint32(INPUT_SYSTEM_BASE[ID] + SUB_SYSTEM_OFFSET[sub_ID] + reg*sizeof(hrt_data)); + assert(ID < N_INPUT_SYSTEM_ID); + assert(sub_ID < N_SUB_SYSTEM_ID); + assert(INPUT_SYSTEM_BASE[ID] != (hrt_address)-1); + assert(SUB_SYSTEM_OFFSET[sub_ID] != (hrt_address)-1); + return ia_css_device_load_uint32(INPUT_SYSTEM_BASE[ID] + SUB_SYSTEM_OFFSET[sub_ID] + reg*sizeof(hrt_data)); } #endif /* __INPUT_SYSTEM_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq.c index 6b58bc13dc1b..51daf76c2aea 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq.c @@ -22,13 +22,13 @@ #include "platform_support.h" /* hrt_sleep() */ -STORAGE_CLASS_INLINE void irq_wait_for_write_complete( +static inline void irq_wait_for_write_complete( const irq_ID_t ID); -STORAGE_CLASS_INLINE bool any_irq_channel_enabled( +static inline bool any_irq_channel_enabled( const irq_ID_t ID); -STORAGE_CLASS_INLINE irq_ID_t virq_get_irq_id( +static inline irq_ID_t virq_get_irq_id( const virq_id_t irq_ID, unsigned int *channel_ID); @@ -69,7 +69,7 @@ void irq_clear_all( irq_reg_store(ID, _HRT_IRQ_CONTROLLER_CLEAR_REG_IDX, mask); -return; + return; } /* @@ -114,7 +114,7 @@ void irq_enable_channel( irq_wait_for_write_complete(ID); -return; + return; } void irq_enable_pulse( @@ -129,7 +129,7 @@ void irq_enable_pulse( /* output is given as edge, not pulse */ irq_reg_store(ID, _HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX, edge_out); -return; + return; } void irq_disable_channel( @@ -160,7 +160,7 @@ void irq_disable_channel( irq_wait_for_write_complete(ID); -return; + return; } enum hrt_isp_css_irq_status irq_get_channel_id( @@ -195,7 +195,7 @@ enum hrt_isp_css_irq_status irq_get_channel_id( if (irq_id != NULL) *irq_id = (unsigned int)idx; -return status; + return status; } static const hrt_address IRQ_REQUEST_ADDR[N_IRQ_SW_CHANNEL_ID] = { @@ -220,7 +220,7 @@ void irq_raise( (unsigned int)addr, 1); gp_device_reg_store(GP_DEVICE0_ID, (unsigned int)addr, 0); -return; + return; } void irq_controller_get_state( @@ -240,7 +240,7 @@ void irq_controller_get_state( _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); state->irq_level_not_pulse = irq_reg_load(ID, _HRT_IRQ_CONTROLLER_EDGE_NOT_PULSE_REG_IDX); -return; + return; } bool any_virq_signal(void) @@ -248,7 +248,7 @@ bool any_virq_signal(void) unsigned int irq_status = irq_reg_load(IRQ0_ID, _HRT_IRQ_CONTROLLER_STATUS_REG_IDX); -return (irq_status != 0); + return (irq_status != 0); } void cnd_virq_enable_channel( @@ -279,7 +279,7 @@ void cnd_virq_enable_channel( irq_disable_channel(IRQ0_ID, IRQ_NESTING_ID[ID]); } } -return; + return; } @@ -290,7 +290,7 @@ void virq_clear_all(void) for (irq_id = (irq_ID_t)0; irq_id < N_IRQ_ID; irq_id++) { irq_clear_all(irq_id); } -return; + return; } enum hrt_isp_css_irq_status virq_get_channel_signals( @@ -320,7 +320,7 @@ enum hrt_isp_css_irq_status virq_get_channel_signals( } } -return irq_status; + return irq_status; } void virq_clear_info( @@ -333,7 +333,7 @@ void virq_clear_info( for (ID = (irq_ID_t)0 ; ID < N_IRQ_ID; ID++) { irq_info->irq_status_reg[ID] = 0; } -return; + return; } enum hrt_isp_css_irq_status virq_get_channel_id( @@ -403,10 +403,10 @@ enum hrt_isp_css_irq_status virq_get_channel_id( if (irq_id != NULL) *irq_id = (virq_id_t)idx; -return status; + return status; } -STORAGE_CLASS_INLINE void irq_wait_for_write_complete( +static inline void irq_wait_for_write_complete( const irq_ID_t ID) { assert(ID < N_IRQ_ID); @@ -415,7 +415,7 @@ STORAGE_CLASS_INLINE void irq_wait_for_write_complete( _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX*sizeof(hrt_data)); } -STORAGE_CLASS_INLINE bool any_irq_channel_enabled( +static inline bool any_irq_channel_enabled( const irq_ID_t ID) { hrt_data en_reg; @@ -425,10 +425,10 @@ STORAGE_CLASS_INLINE bool any_irq_channel_enabled( en_reg = irq_reg_load(ID, _HRT_IRQ_CONTROLLER_ENABLE_REG_IDX); -return (en_reg != 0); + return (en_reg != 0); } -STORAGE_CLASS_INLINE irq_ID_t virq_get_irq_id( +static inline irq_ID_t virq_get_irq_id( const virq_id_t irq_ID, unsigned int *channel_ID) { @@ -444,5 +444,5 @@ STORAGE_CLASS_INLINE irq_ID_t virq_get_irq_id( *channel_ID = (unsigned int)irq_ID - IRQ_N_ID_OFFSET[ID]; -return ID; + return ID; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq_private.h index eb325e870e88..23a13ac696c2 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/irq_private.h @@ -26,19 +26,19 @@ STORAGE_CLASS_IRQ_C void irq_reg_store( const unsigned int reg, const hrt_data value) { -assert(ID < N_IRQ_ID); -assert(IRQ_BASE[ID] != (hrt_address)-1); + assert(ID < N_IRQ_ID); + assert(IRQ_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(IRQ_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_IRQ_C hrt_data irq_reg_load( const irq_ID_t ID, const unsigned int reg) { -assert(ID < N_IRQ_ID); -assert(IRQ_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(IRQ_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_IRQ_ID); + assert(IRQ_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(IRQ_BASE[ID] + reg*sizeof(hrt_data)); } #endif /* __IRQ_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/isp.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/isp.c index 47c21e486c25..531c932a48f5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/isp.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/isp.c @@ -34,7 +34,7 @@ void cnd_isp_irq_enable( isp_ctrl_clearbit(ID, ISP_IRQ_READY_REG, ISP_IRQ_READY_BIT); } -return; + return; } void isp_get_state( @@ -94,7 +94,7 @@ void isp_get_state( !isp_ctrl_getbit(ID, ISP_ICACHE_MT_SINK_REG, ISP_ICACHE_MT_SINK_BIT); */ -return; + return; } /* ISP functions to control the ISP state from the host, even in crun. */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu.c index b75d0f85d524..a28b67eb66ea 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu.c @@ -24,20 +24,20 @@ void mmu_set_page_table_base_index( const hrt_data base_index) { mmu_reg_store(ID, _HRT_MMU_PAGE_TABLE_BASE_ADDRESS_REG_IDX, base_index); -return; + return; } hrt_data mmu_get_page_table_base_index( const mmu_ID_t ID) { -return mmu_reg_load(ID, _HRT_MMU_PAGE_TABLE_BASE_ADDRESS_REG_IDX); + return mmu_reg_load(ID, _HRT_MMU_PAGE_TABLE_BASE_ADDRESS_REG_IDX); } void mmu_invalidate_cache( const mmu_ID_t ID) { mmu_reg_store(ID, _HRT_MMU_INVALIDATE_TLB_REG_IDX, 1); -return; + return; } void mmu_invalidate_cache_all(void) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu_private.h index 392b6cc24e8f..7377666f6eb7 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/mmu_private.h @@ -26,19 +26,19 @@ STORAGE_CLASS_MMU_H void mmu_reg_store( const unsigned int reg, const hrt_data value) { -assert(ID < N_MMU_ID); -assert(MMU_BASE[ID] != (hrt_address)-1); + assert(ID < N_MMU_ID); + assert(MMU_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(MMU_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_MMU_H hrt_data mmu_reg_load( const mmu_ID_t ID, const unsigned int reg) { -assert(ID < N_MMU_ID); -assert(MMU_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(MMU_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_MMU_ID); + assert(MMU_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(MMU_BASE[ID] + reg*sizeof(hrt_data)); } #endif /* __MMU_PRIVATE_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/sp_private.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/sp_private.h index e6283bf67ad3..5ea81c0e82d1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/sp_private.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/sp_private.h @@ -26,19 +26,19 @@ STORAGE_CLASS_SP_C void sp_ctrl_store( const hrt_address reg, const hrt_data value) { -assert(ID < N_SP_ID); -assert(SP_CTRL_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_CTRL_BASE[ID] != (hrt_address)-1); ia_css_device_store_uint32(SP_CTRL_BASE[ID] + reg*sizeof(hrt_data), value); -return; + return; } STORAGE_CLASS_SP_C hrt_data sp_ctrl_load( const sp_ID_t ID, const hrt_address reg) { -assert(ID < N_SP_ID); -assert(SP_CTRL_BASE[ID] != (hrt_address)-1); -return ia_css_device_load_uint32(SP_CTRL_BASE[ID] + reg*sizeof(hrt_data)); + assert(ID < N_SP_ID); + assert(SP_CTRL_BASE[ID] != (hrt_address)-1); + return ia_css_device_load_uint32(SP_CTRL_BASE[ID] + reg*sizeof(hrt_data)); } STORAGE_CLASS_SP_C bool sp_ctrl_getbit( @@ -47,7 +47,7 @@ STORAGE_CLASS_SP_C bool sp_ctrl_getbit( const unsigned int bit) { hrt_data val = sp_ctrl_load(ID, reg); -return (val & (1UL << bit)) != 0; + return (val & (1UL << bit)) != 0; } STORAGE_CLASS_SP_C void sp_ctrl_setbit( @@ -57,7 +57,7 @@ STORAGE_CLASS_SP_C void sp_ctrl_setbit( { hrt_data data = sp_ctrl_load(ID, reg); sp_ctrl_store(ID, reg, (data | (1UL << bit))); -return; + return; } STORAGE_CLASS_SP_C void sp_ctrl_clearbit( @@ -67,7 +67,7 @@ STORAGE_CLASS_SP_C void sp_ctrl_clearbit( { hrt_data data = sp_ctrl_load(ID, reg); sp_ctrl_store(ID, reg, (data & ~(1UL << bit))); -return; + return; } STORAGE_CLASS_SP_C void sp_dmem_store( @@ -76,10 +76,10 @@ STORAGE_CLASS_SP_C void sp_dmem_store( const void *data, const size_t size) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); ia_css_device_store(SP_DMEM_BASE[ID] + addr, data, size); -return; + return; } STORAGE_CLASS_SP_C void sp_dmem_load( @@ -88,10 +88,10 @@ STORAGE_CLASS_SP_C void sp_dmem_load( void *data, const size_t size) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); ia_css_device_load(SP_DMEM_BASE[ID] + addr, data, size); -return; + return; } STORAGE_CLASS_SP_C void sp_dmem_store_uint8( @@ -99,11 +99,11 @@ STORAGE_CLASS_SP_C void sp_dmem_store_uint8( hrt_address addr, const uint8_t data) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; ia_css_device_store_uint8(SP_DMEM_BASE[SP0_ID] + addr, data); -return; + return; } STORAGE_CLASS_SP_C void sp_dmem_store_uint16( @@ -111,11 +111,11 @@ STORAGE_CLASS_SP_C void sp_dmem_store_uint16( hrt_address addr, const uint16_t data) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; ia_css_device_store_uint16(SP_DMEM_BASE[SP0_ID] + addr, data); -return; + return; } STORAGE_CLASS_SP_C void sp_dmem_store_uint32( @@ -123,19 +123,19 @@ STORAGE_CLASS_SP_C void sp_dmem_store_uint32( hrt_address addr, const uint32_t data) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; ia_css_device_store_uint32(SP_DMEM_BASE[SP0_ID] + addr, data); -return; + return; } STORAGE_CLASS_SP_C uint8_t sp_dmem_load_uint8( const sp_ID_t ID, const hrt_address addr) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; return ia_css_device_load_uint8(SP_DMEM_BASE[SP0_ID] + addr); } @@ -144,8 +144,8 @@ STORAGE_CLASS_SP_C uint16_t sp_dmem_load_uint16( const sp_ID_t ID, const hrt_address addr) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; return ia_css_device_load_uint16(SP_DMEM_BASE[SP0_ID] + addr); } @@ -154,8 +154,8 @@ STORAGE_CLASS_SP_C uint32_t sp_dmem_load_uint32( const sp_ID_t ID, const hrt_address addr) { -assert(ID < N_SP_ID); -assert(SP_DMEM_BASE[ID] != (hrt_address)-1); + assert(ID < N_SP_ID); + assert(SP_DMEM_BASE[ID] != (hrt_address)-1); (void)ID; return ia_css_device_load_uint32(SP_DMEM_BASE[SP0_ID] + addr); } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/assert_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/assert_support.h index 92fb15d04703..fd0d92e87c36 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/assert_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/assert_support.h @@ -15,7 +15,6 @@ #ifndef __ASSERT_SUPPORT_H_INCLUDED__ #define __ASSERT_SUPPORT_H_INCLUDED__ -#include "storage_class.h" /** * The following macro can help to test the size of a struct at compile @@ -92,7 +91,7 @@ * The implemenation for the pipe generation tool is in see support.isp.h */ #define OP___assert(cnd) assert(cnd) -STORAGE_CLASS_INLINE void compile_time_assert (unsigned cond) +static inline void compile_time_assert (unsigned cond) { /* Call undefined function if cond is false */ extern void _compile_time_assert (void); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h index d71e08f27a42..6928965cf513 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/bamem.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "bamem_local.h" #ifndef __INLINE_BAMEM__ -#define STORAGE_CLASS_BAMEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_BAMEM_H extern #define STORAGE_CLASS_BAMEM_C #include "bamem_public.h" #else /* __INLINE_BAMEM__ */ -#define STORAGE_CLASS_BAMEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_BAMEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_BAMEM_H static inline +#define STORAGE_CLASS_BAMEM_C static inline #include "bamem_private.h" #endif /* __INLINE_BAMEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/csi_rx.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/csi_rx.h index 0398f5802f05..917ee8cdb1d9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/csi_rx.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/csi_rx.h @@ -30,18 +30,13 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "csi_rx_local.h" #ifndef __INLINE_CSI_RX__ -#define STORAGE_CLASS_CSI_RX_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_CSI_RX_C #include "csi_rx_public.h" #else /* __INLINE_CSI_RX__ */ -#define STORAGE_CLASS_CSI_RX_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_CSI_RX_C STORAGE_CLASS_INLINE #include "csi_rx_private.h" #endif /* __INLINE_CSI_RX__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/debug.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/debug.h index 7d8011735033..0aa22446e27e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/debug.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/debug.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "debug_local.h" #ifndef __INLINE_DEBUG__ -#define STORAGE_CLASS_DEBUG_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_DEBUG_H extern #define STORAGE_CLASS_DEBUG_C #include "debug_public.h" #else /* __INLINE_DEBUG__ */ -#define STORAGE_CLASS_DEBUG_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_DEBUG_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_DEBUG_H static inline +#define STORAGE_CLASS_DEBUG_C static inline #include "debug_private.h" #endif /* __INLINE_DEBUG__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/dma.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/dma.h index b266191f21ef..d9dee691e3f8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/dma.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/dma.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "dma_local.h" #ifndef __INLINE_DMA__ -#define STORAGE_CLASS_DMA_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_DMA_H extern #define STORAGE_CLASS_DMA_C #include "dma_public.h" #else /* __INLINE_DMA__ */ -#define STORAGE_CLASS_DMA_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_DMA_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_DMA_H static inline +#define STORAGE_CLASS_DMA_C static inline #include "dma_private.h" #endif /* __INLINE_DMA__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/event_fifo.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/event_fifo.h index 78827c554cc3..df579e902796 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/event_fifo.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/event_fifo.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "event_fifo_local.h" #ifndef __INLINE_EVENT__ -#define STORAGE_CLASS_EVENT_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_EVENT_H extern #define STORAGE_CLASS_EVENT_C #include "event_fifo_public.h" #else /* __INLINE_EVENT__ */ -#define STORAGE_CLASS_EVENT_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_EVENT_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_EVENT_H static inline +#define STORAGE_CLASS_EVENT_C static inline #include "event_fifo_private.h" #endif /* __INLINE_EVENT__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/fifo_monitor.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/fifo_monitor.h index 3bdd260bcaa5..f10c4fa2e32b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/fifo_monitor.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/fifo_monitor.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "fifo_monitor_local.h" #ifndef __INLINE_FIFO_MONITOR__ -#define STORAGE_CLASS_FIFO_MONITOR_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_FIFO_MONITOR_H extern #define STORAGE_CLASS_FIFO_MONITOR_C #include "fifo_monitor_public.h" #else /* __INLINE_FIFO_MONITOR__ */ -#define STORAGE_CLASS_FIFO_MONITOR_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_FIFO_MONITOR_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_FIFO_MONITOR_H static inline +#define STORAGE_CLASS_FIFO_MONITOR_C static inline #include "fifo_monitor_private.h" #endif /* __INLINE_FIFO_MONITOR__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gdc_device.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gdc_device.h index 016132ba0b7f..75c6854c8e7b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gdc_device.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gdc_device.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "gdc_local.h" #ifndef __INLINE_GDC__ -#define STORAGE_CLASS_GDC_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_GDC_H extern #define STORAGE_CLASS_GDC_C #include "gdc_public.h" #else /* __INLINE_GDC__ */ -#define STORAGE_CLASS_GDC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_GDC_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_GDC_H static inline +#define STORAGE_CLASS_GDC_C static inline #include "gdc_private.h" #endif /* __INLINE_GDC__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_device.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_device.h index 766d2532d8f9..aba94e623043 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_device.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_device.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "gp_device_local.h" #ifndef __INLINE_GP_DEVICE__ -#define STORAGE_CLASS_GP_DEVICE_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_GP_DEVICE_H extern #define STORAGE_CLASS_GP_DEVICE_C #include "gp_device_public.h" #else /* __INLINE_GP_DEVICE__ */ -#define STORAGE_CLASS_GP_DEVICE_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_GP_DEVICE_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_GP_DEVICE_H static inline +#define STORAGE_CLASS_GP_DEVICE_C static inline #include "gp_device_private.h" #endif /* __INLINE_GP_DEVICE__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_timer.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_timer.h index ca70f5603bf8..d5d2df24e11a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_timer.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gp_timer.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" /*GP_TIMER_BASE address */ #include "gp_timer_local.h" /*GP_TIMER register offsets */ #ifndef __INLINE_GP_TIMER__ -#define STORAGE_CLASS_GP_TIMER_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_GP_TIMER_H extern #define STORAGE_CLASS_GP_TIMER_C #include "gp_timer_public.h" /* functions*/ #else /* __INLINE_GP_TIMER__ */ -#define STORAGE_CLASS_GP_TIMER_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_GP_TIMER_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_GP_TIMER_H static inline +#define STORAGE_CLASS_GP_TIMER_C static inline #include "gp_timer_private.h" /* inline functions*/ #endif /* __INLINE_GP_TIMER__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gpio.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gpio.h index dec21bcb6f47..d37f7166aa4a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gpio.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/gpio.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "gpio_local.h" #ifndef __INLINE_GPIO__ -#define STORAGE_CLASS_GPIO_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_GPIO_H extern #define STORAGE_CLASS_GPIO_C #include "gpio_public.h" #else /* __INLINE_GPIO__ */ -#define STORAGE_CLASS_GPIO_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_GPIO_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_GPIO_H static inline +#define STORAGE_CLASS_GPIO_C static inline #include "gpio_private.h" #endif /* __INLINE_GPIO__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/hmem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/hmem.h index 671dd5b5fca6..a82fd3a21e98 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/hmem.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/hmem.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "hmem_local.h" #ifndef __INLINE_HMEM__ -#define STORAGE_CLASS_HMEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_HMEM_H extern #define STORAGE_CLASS_HMEM_C #include "hmem_public.h" #else /* __INLINE_HMEM__ */ -#define STORAGE_CLASS_HMEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_HMEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_HMEM_H static inline +#define STORAGE_CLASS_HMEM_C static inline #include "hmem_private.h" #endif /* __INLINE_HMEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/csi_rx_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/csi_rx_public.h index 396240954bed..3b5df85fc510 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/csi_rx_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/csi_rx_public.h @@ -28,7 +28,7 @@ * @param[in] id The global unique ID of the csi rx fe controller. * @param[out] state Point to the register-state. */ -STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_get_state( +extern void csi_rx_fe_ctrl_get_state( const csi_rx_frontend_ID_t ID, csi_rx_fe_ctrl_state_t *state); /** @@ -38,7 +38,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_get_state( * @param[in] id The global unique ID of the csi rx fe controller. * @param[in] state Point to the register-state. */ -STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_dump_state( +extern void csi_rx_fe_ctrl_dump_state( const csi_rx_frontend_ID_t ID, csi_rx_fe_ctrl_state_t *state); /** @@ -49,7 +49,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_dump_state( * @param[in] lane The lane ID. * @param[out] state Point to the dlane state. */ -STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_get_dlane_state( +extern void csi_rx_fe_ctrl_get_dlane_state( const csi_rx_frontend_ID_t ID, const uint32_t lane, csi_rx_fe_ctrl_lane_t *dlane_state); @@ -60,7 +60,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_get_dlane_state( * @param[in] id The global unique ID of the csi rx be controller. * @param[out] state Point to the register-state. */ -STORAGE_CLASS_CSI_RX_H void csi_rx_be_ctrl_get_state( +extern void csi_rx_be_ctrl_get_state( const csi_rx_backend_ID_t ID, csi_rx_be_ctrl_state_t *state); /** @@ -70,7 +70,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_be_ctrl_get_state( * @param[in] id The global unique ID of the csi rx be controller. * @param[in] state Point to the register-state. */ -STORAGE_CLASS_CSI_RX_H void csi_rx_be_ctrl_dump_state( +extern void csi_rx_be_ctrl_dump_state( const csi_rx_backend_ID_t ID, csi_rx_be_ctrl_state_t *state); /** end of NCI */ @@ -89,7 +89,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_be_ctrl_dump_state( * * @return the value of the register. */ -STORAGE_CLASS_CSI_RX_H hrt_data csi_rx_fe_ctrl_reg_load( +extern hrt_data csi_rx_fe_ctrl_reg_load( const csi_rx_frontend_ID_t ID, const hrt_address reg); /** @@ -101,7 +101,7 @@ STORAGE_CLASS_CSI_RX_H hrt_data csi_rx_fe_ctrl_reg_load( * @param[in] value The value to be stored. * */ -STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_reg_store( +extern void csi_rx_fe_ctrl_reg_store( const csi_rx_frontend_ID_t ID, const hrt_address reg, const hrt_data value); @@ -114,7 +114,7 @@ STORAGE_CLASS_CSI_RX_H void csi_rx_fe_ctrl_reg_store( * * @return the value of the register. */ -STORAGE_CLASS_CSI_RX_H hrt_data csi_rx_be_ctrl_reg_load( +extern hrt_data csi_rx_be_ctrl_reg_load( const csi_rx_backend_ID_t ID, const hrt_address reg); /** @@ -126,7 +126,7 @@ STORAGE_CLASS_CSI_RX_H hrt_data csi_rx_be_ctrl_reg_load( * @param[in] value The value to be stored. * */ -STORAGE_CLASS_CSI_RX_H void csi_rx_be_ctrl_reg_store( +extern void csi_rx_be_ctrl_reg_store( const csi_rx_backend_ID_t ID, const hrt_address reg, const hrt_data value); diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/gdc_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/gdc_public.h index d27f87a719db..d09d1e320306 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/gdc_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/gdc_public.h @@ -33,7 +33,7 @@ \return none, GDC[ID].lut[0...3][0...HRT_GDC_N-1] = data */ -STORAGE_CLASS_EXTERN void gdc_lut_store( +extern void gdc_lut_store( const gdc_ID_t ID, const int data[4][HRT_GDC_N]); @@ -43,7 +43,7 @@ STORAGE_CLASS_EXTERN void gdc_lut_store( \param in_lut[in] The data matrix to be converted \param out_lut[out] The data matrix as the output of conversion */ -STORAGE_CLASS_EXTERN void gdc_lut_convert_to_isp_format( +extern void gdc_lut_convert_to_isp_format( const int in_lut[4][HRT_GDC_N], int out_lut[4][HRT_GDC_N]); @@ -53,7 +53,7 @@ STORAGE_CLASS_EXTERN void gdc_lut_convert_to_isp_format( \return unity */ -STORAGE_CLASS_EXTERN int gdc_get_unity( +extern int gdc_get_unity( const gdc_ID_t ID); #endif /* __GDC_PUBLIC_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/hmem_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/hmem_public.h index 9b8e7c92442d..8538f86ab5e6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/hmem_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/hmem_public.h @@ -15,10 +15,10 @@ #ifndef __HMEM_PUBLIC_H_INCLUDED__ #define __HMEM_PUBLIC_H_INCLUDED__ -#include <stddef.h> /* size_t */ +#include <linux/types.h> /* size_t */ /*! Return the size of HMEM[ID] - + \param ID[in] HMEM identifier \Note: The size is the byte size of the area it occupies diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h index 2251f372145b..a025ad562bd2 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op1w.h @@ -27,14 +27,13 @@ * Prerequisites: * */ -#include "storage_class.h" #ifdef INLINE_ISP_OP1W -#define STORAGE_CLASS_ISP_OP1W_FUNC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_ISP_OP1W_DATA_H STORAGE_CLASS_INLINE_DATA +#define STORAGE_CLASS_ISP_OP1W_FUNC_H static inline +#define STORAGE_CLASS_ISP_OP1W_DATA_H static inline_DATA #else /* INLINE_ISP_OP1W */ -#define STORAGE_CLASS_ISP_OP1W_FUNC_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_ISP_OP1W_DATA_H STORAGE_CLASS_EXTERN_DATA +#define STORAGE_CLASS_ISP_OP1W_FUNC_H extern +#define STORAGE_CLASS_ISP_OP1W_DATA_H extern_DATA #endif /* INLINE_ISP_OP1W */ /* diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h index 1cfe6d717283..cf7e7314842d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/isp_op2w.h @@ -27,14 +27,13 @@ * Prerequisites: * */ -#include "storage_class.h" #ifdef INLINE_ISP_OP2W -#define STORAGE_CLASS_ISP_OP2W_FUNC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_ISP_OP2W_DATA_H STORAGE_CLASS_INLINE_DATA +#define STORAGE_CLASS_ISP_OP2W_FUNC_H static inline +#define STORAGE_CLASS_ISP_OP2W_DATA_H static inline_DATA #else /* INLINE_ISP_OP2W */ -#define STORAGE_CLASS_ISP_OP2W_FUNC_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_ISP_OP2W_DATA_H STORAGE_CLASS_EXTERN_DATA +#define STORAGE_CLASS_ISP_OP2W_FUNC_H extern +#define STORAGE_CLASS_ISP_OP2W_DATA_H extern_DATA #endif /* INLINE_ISP_OP2W */ /* diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/mmu_public.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/mmu_public.h index 4258fa872087..0a13eda73607 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/mmu_public.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/mmu_public.h @@ -24,7 +24,7 @@ \return none, MMU[ID].page_table_base_index = base_index */ -STORAGE_CLASS_EXTERN void mmu_set_page_table_base_index( +extern void mmu_set_page_table_base_index( const mmu_ID_t ID, const hrt_data base_index); @@ -35,7 +35,7 @@ STORAGE_CLASS_EXTERN void mmu_set_page_table_base_index( \return MMU[ID].page_table_base_index */ -STORAGE_CLASS_EXTERN hrt_data mmu_get_page_table_base_index( +extern hrt_data mmu_get_page_table_base_index( const mmu_ID_t ID); /*! Invalidate the page table cache of MMU[ID] @@ -44,7 +44,7 @@ STORAGE_CLASS_EXTERN hrt_data mmu_get_page_table_base_index( \return none */ -STORAGE_CLASS_EXTERN void mmu_invalidate_cache( +extern void mmu_invalidate_cache( const mmu_ID_t ID); @@ -52,7 +52,7 @@ STORAGE_CLASS_EXTERN void mmu_invalidate_cache( \return none */ -STORAGE_CLASS_EXTERN void mmu_invalidate_cache_all(void); +extern void mmu_invalidate_cache_all(void); /*! Write to a control register of MMU[ID] diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h index 3e955fca2a94..a202d6dce106 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/host/ref_vector_func.h @@ -15,14 +15,13 @@ #ifndef _REF_VECTOR_FUNC_H_INCLUDED_ #define _REF_VECTOR_FUNC_H_INCLUDED_ -#include "storage_class.h" #ifdef INLINE_VECTOR_FUNC -#define STORAGE_CLASS_REF_VECTOR_FUNC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_REF_VECTOR_DATA_H STORAGE_CLASS_INLINE_DATA +#define STORAGE_CLASS_REF_VECTOR_FUNC_H static inline +#define STORAGE_CLASS_REF_VECTOR_DATA_H static inline_DATA #else /* INLINE_VECTOR_FUNC */ -#define STORAGE_CLASS_REF_VECTOR_FUNC_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_REF_VECTOR_DATA_H STORAGE_CLASS_EXTERN_DATA +#define STORAGE_CLASS_REF_VECTOR_FUNC_H extern +#define STORAGE_CLASS_REF_VECTOR_DATA_H extern_DATA #endif /* INLINE_VECTOR_FUNC */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/ibuf_ctrl.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/ibuf_ctrl.h index f5de0df7981e..c7d9095472b1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/ibuf_ctrl.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/ibuf_ctrl.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "ibuf_ctrl_local.h" #ifndef __INLINE_IBUF_CTRL__ -#define STORAGE_CLASS_IBUF_CTRL_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_IBUF_CTRL_H extern #define STORAGE_CLASS_IBUF_CTRL_C #include "ibuf_ctrl_public.h" #else /* __INLINE_IBUF_CTRL__ */ -#define STORAGE_CLASS_IBUF_CTRL_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_IBUF_CTRL_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_IBUF_CTRL_H static inline +#define STORAGE_CLASS_IBUF_CTRL_C static inline #include "ibuf_ctrl_private.h" #endif /* __INLINE_IBUF_CTRL__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_formatter.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_formatter.h index 041c8b660aa4..eeaaecdd57ba 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_formatter.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_formatter.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "input_formatter_local.h" #ifndef __INLINE_INPUT_FORMATTER__ -#define STORAGE_CLASS_INPUT_FORMATTER_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_INPUT_FORMATTER_H extern #define STORAGE_CLASS_INPUT_FORMATTER_C #include "input_formatter_public.h" #else /* __INLINE_INPUT_FORMATTER__ */ -#define STORAGE_CLASS_INPUT_FORMATTER_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_INPUT_FORMATTER_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_INPUT_FORMATTER_H static inline +#define STORAGE_CLASS_INPUT_FORMATTER_C static inline #include "input_formatter_private.h" #endif /* __INLINE_INPUT_FORMATTER__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_system.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_system.h index 182867367b48..3f02d9ec9588 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_system.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/input_system.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "input_system_local.h" #ifndef __INLINE_INPUT_SYSTEM__ -#define STORAGE_CLASS_INPUT_SYSTEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_INPUT_SYSTEM_H extern #define STORAGE_CLASS_INPUT_SYSTEM_C #include "input_system_public.h" #else /* __INLINE_INPUT_SYSTEM__ */ -#define STORAGE_CLASS_INPUT_SYSTEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_INPUT_SYSTEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_INPUT_SYSTEM_H static inline +#define STORAGE_CLASS_INPUT_SYSTEM_C static inline #include "input_system_private.h" #endif /* __INLINE_INPUT_SYSTEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/irq.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/irq.h index 1dc443892cc5..e1446388dee5 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/irq.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/irq.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "irq_local.h" #ifndef __INLINE_IRQ__ -#define STORAGE_CLASS_IRQ_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_IRQ_H extern #define STORAGE_CLASS_IRQ_C #include "irq_public.h" #else /* __INLINE_IRQ__ */ -#define STORAGE_CLASS_IRQ_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_IRQ_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_IRQ_H static inline +#define STORAGE_CLASS_IRQ_C static inline #include "irq_private.h" #endif /* __INLINE_IRQ__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isp.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isp.h index 49190d0abc30..b916953e7f47 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isp.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isp.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "isp_local.h" #ifndef __INLINE_ISP__ -#define STORAGE_CLASS_ISP_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_ISP_H extern #define STORAGE_CLASS_ISP_C #include "isp_public.h" #else /* __INLINE_iSP__ */ -#define STORAGE_CLASS_ISP_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_ISP_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_ISP_H static inline +#define STORAGE_CLASS_ISP_C static inline #include "isp_private.h" #endif /* __INLINE_ISP__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_dma.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_dma.h index 9a608f07adcb..76aba114a5c1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_dma.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_dma.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "isys_dma_local.h" #ifndef __INLINE_ISYS2401_DMA__ -#define STORAGE_CLASS_ISYS2401_DMA_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_ISYS2401_DMA_H extern #define STORAGE_CLASS_ISYS2401_DMA_C #include "isys_dma_public.h" #else /* __INLINE_ISYS2401_DMA__ */ -#define STORAGE_CLASS_ISYS2401_DMA_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_ISYS2401_DMA_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_ISYS2401_DMA_H static inline +#define STORAGE_CLASS_ISYS2401_DMA_C static inline #include "isys_dma_private.h" #endif /* __INLINE_ISYS2401_DMA__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_irq.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_irq.h index cf858bcc8e45..d3f64cfd0b7d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_irq.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_irq.h @@ -16,21 +16,20 @@ #define __IA_CSS_ISYS_IRQ_H__ #include <type_support.h> -#include <storage_class.h> #include <system_local.h> #if defined(USE_INPUT_SYSTEM_VERSION_2401) #ifndef __INLINE_ISYS2401_IRQ__ -#define STORAGE_CLASS_ISYS2401_IRQ_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_ISYS2401_IRQ_C STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_ISYS2401_IRQ_H extern +#define STORAGE_CLASS_ISYS2401_IRQ_C extern #include "isys_irq_public.h" #else /* __INLINE_ISYS2401_IRQ__ */ -#define STORAGE_CLASS_ISYS2401_IRQ_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_ISYS2401_IRQ_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_ISYS2401_IRQ_H static inline +#define STORAGE_CLASS_ISYS2401_IRQ_C static inline #include "isys_irq_private.h" #endif /* __INLINE_ISYS2401_IRQ__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_stream2mmio.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_stream2mmio.h index 3e8cfe555ad5..16fbf9d25eba 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_stream2mmio.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/isys_stream2mmio.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "isys_stream2mmio_local.h" #ifndef __INLINE_STREAM2MMIO__ -#define STORAGE_CLASS_STREAM2MMIO_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_STREAM2MMIO_H extern #define STORAGE_CLASS_STREAM2MMIO_C #include "isys_stream2mmio_public.h" #else /* __INLINE_STREAM2MMIO__ */ -#define STORAGE_CLASS_STREAM2MMIO_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_STREAM2MMIO_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_STREAM2MMIO_H static inline +#define STORAGE_CLASS_STREAM2MMIO_C static inline #include "isys_stream2mmio_private.h" #endif /* __INLINE_STREAM2MMIO__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/math_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/math_support.h index f74b405b0f39..e85e5c889c15 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/math_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/math_support.h @@ -15,7 +15,6 @@ #ifndef __MATH_SUPPORT_H #define __MATH_SUPPORT_H -#include "storage_class.h" /* for STORAGE_CLASS_INLINE */ #if defined(__KERNEL__) #include <linux/kernel.h> /* Override the definition of max/min from linux kernel*/ #endif /*__KERNEL__*/ @@ -110,60 +109,60 @@ Leaving out the other math utility functions as they are newly added #else /* !defined(INLINE_MATH_SUPPORT_UTILS) */ -STORAGE_CLASS_INLINE int max(int a, int b) +static inline int max(int a, int b) { return MAX(a, b); } -STORAGE_CLASS_INLINE int min(int a, int b) +static inline int min(int a, int b) { return MIN(a, b); } -STORAGE_CLASS_INLINE unsigned int ceil_div(unsigned int a, unsigned int b) +static inline unsigned int ceil_div(unsigned int a, unsigned int b) { return CEIL_DIV(a, b); } #endif /* !defined(INLINE_MATH_SUPPORT_UTILS) */ -STORAGE_CLASS_INLINE unsigned int umax(unsigned int a, unsigned int b) +static inline unsigned int umax(unsigned int a, unsigned int b) { return MAX(a, b); } -STORAGE_CLASS_INLINE unsigned int umin(unsigned int a, unsigned int b) +static inline unsigned int umin(unsigned int a, unsigned int b) { return MIN(a, b); } -STORAGE_CLASS_INLINE unsigned int ceil_mul(unsigned int a, unsigned int b) +static inline unsigned int ceil_mul(unsigned int a, unsigned int b) { return CEIL_MUL(a, b); } -STORAGE_CLASS_INLINE unsigned int ceil_mul2(unsigned int a, unsigned int b) +static inline unsigned int ceil_mul2(unsigned int a, unsigned int b) { return CEIL_MUL2(a, b); } -STORAGE_CLASS_INLINE unsigned int ceil_shift(unsigned int a, unsigned int b) +static inline unsigned int ceil_shift(unsigned int a, unsigned int b) { return CEIL_SHIFT(a, b); } -STORAGE_CLASS_INLINE unsigned int ceil_shift_mul(unsigned int a, unsigned int b) +static inline unsigned int ceil_shift_mul(unsigned int a, unsigned int b) { return CEIL_SHIFT_MUL(a, b); } #ifdef ISP2401 -STORAGE_CLASS_INLINE unsigned int round_half_down_div(unsigned int a, unsigned int b) +static inline unsigned int round_half_down_div(unsigned int a, unsigned int b) { return ROUND_HALF_DOWN_DIV(a, b); } -STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, unsigned int b) +static inline unsigned int round_half_down_mul(unsigned int a, unsigned int b) { return ROUND_HALF_DOWN_MUL(a, b); } @@ -187,7 +186,7 @@ STORAGE_CLASS_INLINE unsigned int round_half_down_mul(unsigned int a, unsigned i * */ -STORAGE_CLASS_INLINE unsigned int ceil_pow2(unsigned int a) +static inline unsigned int ceil_pow2(unsigned int a) { if (a == 0) { return 1; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mmu_device.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mmu_device.h index 1b2017b029f2..519e850ec390 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mmu_device.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mmu_device.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "mmu_local.h" #ifndef __INLINE_MMU__ -#define STORAGE_CLASS_MMU_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_MMU_H extern #define STORAGE_CLASS_MMU_C #include "mmu_public.h" #else /* __INLINE_MMU__ */ -#define STORAGE_CLASS_MMU_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_MMU_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_MMU_H static inline +#define STORAGE_CLASS_MMU_C static inline #include "mmu_private.h" #endif /* __INLINE_MMU__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h index 565983aafa4d..cd938375e02e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/mpmath.h @@ -15,14 +15,13 @@ #ifndef __MPMATH_H_INCLUDED__ #define __MPMATH_H_INCLUDED__ -#include "storage_class.h" #ifdef INLINE_MPMATH -#define STORAGE_CLASS_MPMATH_FUNC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_MPMATH_DATA_H STORAGE_CLASS_INLINE_DATA +#define STORAGE_CLASS_MPMATH_FUNC_H static inline +#define STORAGE_CLASS_MPMATH_DATA_H static inline_DATA #else /* INLINE_MPMATH */ -#define STORAGE_CLASS_MPMATH_FUNC_H STORAGE_CLASS_EXTERN -#define STORAGE_CLASS_MPMATH_DATA_H STORAGE_CLASS_EXTERN_DATA +#define STORAGE_CLASS_MPMATH_FUNC_H extern +#define STORAGE_CLASS_MPMATH_DATA_H extern_DATA #endif /* INLINE_MPMATH */ #include <type_support.h> diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h index 6e48ea9afc29..a607242c5f1a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/osys.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "osys_local.h" #ifndef __INLINE_OSYS__ -#define STORAGE_CLASS_OSYS_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_OSYS_H extern #define STORAGE_CLASS_OSYS_C #include "osys_public.h" #else /* __INLINE_OSYS__ */ -#define STORAGE_CLASS_OSYS_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_OSYS_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_OSYS_H static inline +#define STORAGE_CLASS_OSYS_C static inline #include "osys_private.h" #endif /* __INLINE_OSYS__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/pixelgen.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/pixelgen.h index 67f7f3a14231..418d02382d76 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/pixelgen.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/pixelgen.h @@ -31,18 +31,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "pixelgen_local.h" #ifndef __INLINE_PIXELGEN__ -#define STORAGE_CLASS_PIXELGEN_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_PIXELGEN_H extern #define STORAGE_CLASS_PIXELGEN_C #include "pixelgen_public.h" #else /* __INLINE_PIXELGEN__ */ -#define STORAGE_CLASS_PIXELGEN_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_PIXELGEN_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_PIXELGEN_H static inline +#define STORAGE_CLASS_PIXELGEN_C static inline #include "pixelgen_private.h" #endif /* __INLINE_PIXELGEN__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/platform_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/platform_support.h index 02f9eee67ff3..39a125ba563d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/platform_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/platform_support.h @@ -20,7 +20,6 @@ * Platform specific includes and functionality. */ -#include "storage_class.h" #include <linux/delay.h> #include <linux/kernel.h> #include <linux/string.h> diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/print_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/print_support.h index cfbc222ea0c1..ca0fbbb57788 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/print_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/print_support.h @@ -15,7 +15,6 @@ #ifndef __PRINT_SUPPORT_H_INCLUDED__ #define __PRINT_SUPPORT_H_INCLUDED__ -#include "storage_class.h" #include <stdarg.h> #if !defined(__KERNEL__) @@ -24,7 +23,7 @@ extern int (*sh_css_printf) (const char *fmt, va_list args); /* depends on host supplied print function in ia_css_init() */ -STORAGE_CLASS_INLINE void ia_css_print(const char *fmt, ...) +static inline void ia_css_print(const char *fmt, ...) { va_list ap; if (sh_css_printf) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/queue.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/queue.h index a3d874b9516a..aa5fadf5aadb 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/queue.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/queue.h @@ -29,18 +29,17 @@ * */ -#include <storage_class.h> #include "queue_local.h" #ifndef __INLINE_QUEUE__ -#define STORAGE_CLASS_QUEUE_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_QUEUE_H extern #define STORAGE_CLASS_QUEUE_C /* #include "queue_public.h" */ #include "ia_css_queue.h" #else /* __INLINE_QUEUE__ */ -#define STORAGE_CLASS_QUEUE_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_QUEUE_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_QUEUE_H static inline +#define STORAGE_CLASS_QUEUE_C static inline #include "queue_private.h" #endif /* __INLINE_QUEUE__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/resource.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/resource.h index 82c55acd0380..bd9f53e6b680 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/resource.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/resource.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "resource_local.h" #ifndef __INLINE_RESOURCE__ -#define STORAGE_CLASS_RESOURCE_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_RESOURCE_H extern #define STORAGE_CLASS_RESOURCE_C #include "resource_public.h" #else /* __INLINE_RESOURCE__ */ -#define STORAGE_CLASS_RESOURCE_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_RESOURCE_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_RESOURCE_H static inline +#define STORAGE_CLASS_RESOURCE_C static inline #include "resource_private.h" #endif /* __INLINE_RESOURCE__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/socket.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/socket.h index c34c2e75c51f..43cfb0cb4aa8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/socket.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/socket.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "socket_local.h" #ifndef __INLINE_SOCKET__ -#define STORAGE_CLASS_SOCKET_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_SOCKET_H extern #define STORAGE_CLASS_SOCKET_C #include "socket_public.h" #else /* __INLINE_SOCKET__ */ -#define STORAGE_CLASS_SOCKET_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_SOCKET_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_SOCKET_H static inline +#define STORAGE_CLASS_SOCKET_C static inline #include "socket_private.h" #endif /* __INLINE_SOCKET__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/sp.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/sp.h index 150fc2f6129b..8f57f2060791 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/sp.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/sp.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "sp_local.h" #ifndef __INLINE_SP__ -#define STORAGE_CLASS_SP_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_SP_H extern #define STORAGE_CLASS_SP_C #include "sp_public.h" #else /* __INLINE_SP__ */ -#define STORAGE_CLASS_SP_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_SP_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_SP_H static inline +#define STORAGE_CLASS_SP_C static inline #include "sp_private.h" #endif /* __INLINE_SP__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/storage_class.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/storage_class.h deleted file mode 100644 index 3908e668dacd..000000000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/storage_class.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Support for Intel Camera Imaging ISP subsystem. - * Copyright (c) 2015, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#ifndef __STORAGE_CLASS_H_INCLUDED__ -#define __STORAGE_CLASS_H_INCLUDED__ - -/** -* @file -* Platform specific includes and functionality. -*/ - -#define STORAGE_CLASS_EXTERN extern - -#if defined(_MSC_VER) -#define STORAGE_CLASS_INLINE static __inline -#else -#define STORAGE_CLASS_INLINE static inline -#endif - -#define STORAGE_CLASS_EXTERN_DATA extern const -#define STORAGE_CLASS_INLINE_DATA static const - -#endif /* __STORAGE_CLASS_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h index 8e41f60b5d39..53d535e4f2ae 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/stream_buffer.h @@ -30,18 +30,17 @@ * */ -#include "storage_class.h" #include "system_local.h" #include "stream_buffer_local.h" #ifndef __INLINE_STREAM_BUFFER__ -#define STORAGE_CLASS_STREAM_BUFFER_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_STREAM_BUFFER_H extern #define STORAGE_CLASS_STREAM_BUFFER_C #include "stream_buffer_public.h" #else /* __INLINE_STREAM_BUFFER__ */ -#define STORAGE_CLASS_STREAM_BUFFER_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_STREAM_BUFFER_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_STREAM_BUFFER_H static inline +#define STORAGE_CLASS_STREAM_BUFFER_C static inline #include "stream_buffer_private.h" #endif /* __INLINE_STREAM_BUFFER__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/string_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/string_support.h index c53241a7a281..d80437c58bde 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/string_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/string_support.h @@ -16,7 +16,6 @@ #define __STRING_SUPPORT_H_INCLUDED__ #include <platform_support.h> #include <type_support.h> -#include <storage_class.h> #if !defined(_MSC_VER) /* @@ -34,7 +33,7 @@ * @return EINVAL on Invalid arguments * @return ERANGE on Destination size too small */ -STORAGE_CLASS_INLINE int memcpy_s( +static inline int memcpy_s( void* dest_buf, size_t dest_size, const void* src_buf, @@ -89,7 +88,7 @@ static size_t strnlen_s( * @return Returns EINVAL on invalid arguments * @return Returns ERANGE on destination size too small */ -STORAGE_CLASS_INLINE int strncpy_s( +static inline int strncpy_s( char* dest_str, size_t dest_size, const char* src_str, @@ -130,7 +129,7 @@ STORAGE_CLASS_INLINE int strncpy_s( * @return Returns EINVAL on invalid arguments * @return Returns ERANGE on destination size too small */ -STORAGE_CLASS_INLINE int strcpy_s( +static inline int strcpy_s( char* dest_str, size_t dest_size, const char* src_str) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/tag.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/tag.h index 7385fd11c95f..ace695643369 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/tag.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/tag.h @@ -29,17 +29,16 @@ * */ -#include "storage_class.h" #include "tag_local.h" #ifndef __INLINE_TAG__ -#define STORAGE_CLASS_TAG_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_TAG_H extern #define STORAGE_CLASS_TAG_C #include "tag_public.h" #else /* __INLINE_TAG__ */ -#define STORAGE_CLASS_TAG_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_TAG_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_TAG_H static inline +#define STORAGE_CLASS_TAG_C static inline #include "tag_private.h" #endif /* __INLINE_TAG__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/timed_ctrl.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/timed_ctrl.h index ed13451c9261..f6bc1c47553f 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/timed_ctrl.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/timed_ctrl.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "timed_ctrl_local.h" #ifndef __INLINE_TIMED_CTRL__ -#define STORAGE_CLASS_TIMED_CTRL_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_TIMED_CTRL_H extern #define STORAGE_CLASS_TIMED_CTRL_C #include "timed_ctrl_public.h" #else /* __INLINE_TIMED_CTRL__ */ -#define STORAGE_CLASS_TIMED_CTRL_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_TIMED_CTRL_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_TIMED_CTRL_H static inline +#define STORAGE_CLASS_TIMED_CTRL_C static inline #include "timed_ctrl_private.h" #endif /* __INLINE_TIMED_CTRL__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/type_support.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/type_support.h index b82fa3eba79f..bc77537fa73a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/type_support.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/type_support.h @@ -30,27 +30,6 @@ #define IA_CSS_INT32_T_BITS 32 #define IA_CSS_UINT64_T_BITS 64 -#if defined(_MSC_VER) -#include <stdint.h> -/* For ATE compilation define the bool */ -#if defined(_ATE_) -#define bool int -#define true 1 -#define false 0 -#else -#include <stdbool.h> -#endif -#include <stddef.h> -#include <limits.h> -#include <errno.h> -#if defined(_M_X64) -#define HOST_ADDRESS(x) (unsigned long long)(x) -#else -#define HOST_ADDRESS(x) (unsigned long)(x) -#endif - -#elif defined(__KERNEL__) - #define CHAR_BIT (8) #include <linux/types.h> @@ -58,25 +37,4 @@ #include <linux/errno.h> #define HOST_ADDRESS(x) (unsigned long)(x) -#elif defined(__GNUC__) -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif -#include <stdint.h> -#include <stdbool.h> -#include <stddef.h> -#include <limits.h> -#include <errno.h> -#define HOST_ADDRESS(x) (unsigned long)(x) - -#else /* default is for the FIST environment */ -#include <stdint.h> -#include <stdbool.h> -#include <stddef.h> -#include <limits.h> -#include <errno.h> -#define HOST_ADDRESS(x) (unsigned long)(x) - -#endif - #endif /* __TYPE_SUPPORT_H_INCLUDED__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vamem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vamem.h index acf932e1f563..82d447bf9704 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vamem.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vamem.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "vamem_local.h" #ifndef __INLINE_VAMEM__ -#define STORAGE_CLASS_VAMEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_VAMEM_H extern #define STORAGE_CLASS_VAMEM_C #include "vamem_public.h" #else /* __INLINE_VAMEM__ */ -#define STORAGE_CLASS_VAMEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_VAMEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_VAMEM_H static inline +#define STORAGE_CLASS_VAMEM_C static inline #include "vamem_private.h" #endif /* __INLINE_VAMEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h index 5d3be31759e4..5368b9062897 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_func.h @@ -15,7 +15,6 @@ #ifndef __VECTOR_FUNC_H_INCLUDED__ #define __VECTOR_FUNC_H_INCLUDED__ -#include "storage_class.h" /* TODO: Later filters will be moved to types directory, * and we should only include matrix_MxN types */ @@ -27,12 +26,12 @@ #include "vector_func_local.h" #ifndef __INLINE_VECTOR_FUNC__ -#define STORAGE_CLASS_VECTOR_FUNC_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_VECTOR_FUNC_H extern #define STORAGE_CLASS_VECTOR_FUNC_C #include "vector_func_public.h" #else /* __INLINE_VECTOR_FUNC__ */ -#define STORAGE_CLASS_VECTOR_FUNC_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_VECTOR_FUNC_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_VECTOR_FUNC_H static inline +#define STORAGE_CLASS_VECTOR_FUNC_C static inline #include "vector_func_private.h" #endif /* __INLINE_VECTOR_FUNC__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h index 261f87378ce5..4923f2d5518b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vector_ops.h @@ -15,17 +15,16 @@ #ifndef __VECTOR_OPS_H_INCLUDED__ #define __VECTOR_OPS_H_INCLUDED__ -#include "storage_class.h" #include "vector_ops_local.h" #ifndef __INLINE_VECTOR_OPS__ -#define STORAGE_CLASS_VECTOR_OPS_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_VECTOR_OPS_H extern #define STORAGE_CLASS_VECTOR_OPS_C #include "vector_ops_public.h" #else /* __INLINE_VECTOR_OPS__ */ -#define STORAGE_CLASS_VECTOR_OPS_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_VECTOR_OPS_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_VECTOR_OPS_H static inline +#define STORAGE_CLASS_VECTOR_OPS_C static inline #include "vector_ops_private.h" #endif /* __INLINE_VECTOR_OPS__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vmem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vmem.h index 79a36755bfd9..d3375729c441 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vmem.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/vmem.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "vmem_local.h" #ifndef __INLINE_VMEM__ -#define STORAGE_CLASS_VMEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_VMEM_H extern #define STORAGE_CLASS_VMEM_C #include "vmem_public.h" #else /* __INLINE_VMEM__ */ -#define STORAGE_CLASS_VMEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_VMEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_VMEM_H static inline +#define STORAGE_CLASS_VMEM_C static inline #include "vmem_private.h" #endif /* __INLINE_VMEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h index 9169e04f9b4b..13083fe55141 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_include/xmem.h @@ -29,18 +29,17 @@ * - local: system and cell specific constants and identifiers */ -#include "storage_class.h" #include "system_local.h" #include "xmem_local.h" #ifndef __INLINE_XMEM__ -#define STORAGE_CLASS_XMEM_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_XMEM_H extern #define STORAGE_CLASS_XMEM_C #include "xmem_public.h" #else /* __INLINE_XMEM__ */ -#define STORAGE_CLASS_XMEM_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_XMEM_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_XMEM_H static inline +#define STORAGE_CLASS_XMEM_C static inline #include "xmem_private.h" #endif /* __INLINE_XMEM__ */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c index 8ef6c54ee813..aa733674f42b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/s3a/s3a_1.0/ia_css_s3a.host.c @@ -321,7 +321,7 @@ ia_css_s3a_dmem_decode( } /* MW: this is an ISP function */ -STORAGE_CLASS_INLINE int +static inline int merge_hi_lo_14(unsigned short hi, unsigned short lo) { int val = (int) ((((unsigned int) hi << 14) & 0xfffc000) | diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c index 9f8a125f0d74..e028e460ae4c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c @@ -1697,11 +1697,11 @@ ia_css_binary_find(struct ia_css_binary_descr *descr, } #endif if (xcandidate->num_output_pins > 1 && /* in case we have a second output pin, */ - req_vf_info && /* and we need vf output. */ + req_vf_info && /* and we need vf output. */ /* check if the required vf format is supported. */ - !binary_supports_output_format(xcandidate, req_vf_info->format)) { - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, + !binary_supports_output_format(xcandidate, req_vf_info->format)) { + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n", __LINE__, xcandidate->num_output_pins, 1, req_vf_info, @@ -1711,8 +1711,8 @@ ia_css_binary_find(struct ia_css_binary_descr *descr, /* Check if vf_veceven supports the requested vf format */ if (xcandidate->num_output_pins == 1 && - req_vf_info && candidate->enable.vf_veceven && - !binary_supports_vf_format(xcandidate, req_vf_info->format)) { + req_vf_info && candidate->enable.vf_veceven && + !binary_supports_vf_format(xcandidate, req_vf_info->format)) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n", __LINE__, xcandidate->num_output_pins, 1, @@ -1723,7 +1723,7 @@ ia_css_binary_find(struct ia_css_binary_descr *descr, /* Check if vf_veceven supports the requested vf width */ if (xcandidate->num_output_pins == 1 && - req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */ + req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */ if (req_vf_info->res.width > candidate->output.max_width) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_binary_find() [%d] continue: (%d < %d)\n", diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/bufq/src/bufq.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/bufq/src/bufq.c index 5d40afd482f5..42d9a8508858 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/bufq/src/bufq.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/bufq/src/bufq.c @@ -280,7 +280,7 @@ static ia_css_queue_t *bufq_get_qhandle( /* Local function to initialize a buffer queue. This reduces * the chances of copy-paste errors or typos. */ -STORAGE_CLASS_INLINE void +static inline void init_bufq(unsigned int desc_offset, unsigned int elems_offset, ia_css_queue_t *handle) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/interface/ia_css_debug.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/interface/ia_css_debug.h index 91c105cc6204..3c8dcfd4bbc6 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/interface/ia_css_debug.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/interface/ia_css_debug.h @@ -130,7 +130,7 @@ enum ia_css_debug_enable_param_dump { * @param[in] fmt printf like format string * @param[in] args arguments for the format string */ -STORAGE_CLASS_INLINE void +static inline void ia_css_debug_vdtrace(unsigned int level, const char *fmt, va_list args) { if (ia_css_debug_trace_level >= level) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/ifmtr/src/ifmtr.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/ifmtr/src/ifmtr.c index a7c6bba7e094..11d3995ba0db 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/ifmtr/src/ifmtr.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/ifmtr/src/ifmtr.c @@ -29,6 +29,7 @@ more details. #endif #include "system_global.h" +#include <linux/kernel.h> #ifdef USE_INPUT_SYSTEM_VERSION_2 @@ -487,7 +488,7 @@ static void ifmtr_set_if_blocking_mode( { int i; bool block[] = { false, false, false, false }; - assert(N_INPUT_FORMATTER_ID <= (sizeof(block) / sizeof(block[0]))); + assert(N_INPUT_FORMATTER_ID <= (ARRAY_SIZE(block))); #if !defined(IS_ISP_2400_SYSTEM) #error "ifmtr_set_if_blocking_mode: ISP_SYSTEM must be one of {IS_ISP_2400_SYSTEM}" diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/inputfifo/src/inputfifo.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/inputfifo/src/inputfifo.c index cf02970d4f59..d9a5f3e9283a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/inputfifo/src/inputfifo.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/inputfifo/src/inputfifo.c @@ -105,7 +105,7 @@ static struct inputfifo_instance /* Streaming to MIPI */ static unsigned inputfifo_wrap_marker( -/* STORAGE_CLASS_INLINE unsigned inputfifo_wrap_marker( */ +/* static inline unsigned inputfifo_wrap_marker( */ unsigned marker) { return marker | @@ -113,7 +113,7 @@ static unsigned inputfifo_wrap_marker( (inputfifo_curr_fmt_type << _HIVE_STR_TO_MIPI_FMT_TYPE_LSB); } -STORAGE_CLASS_INLINE void +static inline void _sh_css_fifo_snd(unsigned token) { while (!can_event_send_token(STR2MIPI_EVENT_ID)) @@ -123,7 +123,7 @@ _sh_css_fifo_snd(unsigned token) } static void inputfifo_send_data_a( -/* STORAGE_CLASS_INLINE void inputfifo_send_data_a( */ +/* static inline void inputfifo_send_data_a( */ unsigned int data) { unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_A_BIT) | @@ -135,7 +135,7 @@ unsigned int data) static void inputfifo_send_data_b( -/* STORAGE_CLASS_INLINE void inputfifo_send_data_b( */ +/* static inline void inputfifo_send_data_b( */ unsigned int data) { unsigned int token = (1 << HIVE_STR_TO_MIPI_VALID_B_BIT) | @@ -147,7 +147,7 @@ static void inputfifo_send_data_b( static void inputfifo_send_data( -/* STORAGE_CLASS_INLINE void inputfifo_send_data( */ +/* static inline void inputfifo_send_data( */ unsigned int a, unsigned int b) { @@ -162,7 +162,7 @@ static void inputfifo_send_data( static void inputfifo_send_sol(void) -/* STORAGE_CLASS_INLINE void inputfifo_send_sol(void) */ +/* static inline void inputfifo_send_sol(void) */ { hrt_data token = inputfifo_wrap_marker( 1 << HIVE_STR_TO_MIPI_SOL_BIT); @@ -174,7 +174,7 @@ static void inputfifo_send_sol(void) static void inputfifo_send_eol(void) -/* STORAGE_CLASS_INLINE void inputfifo_send_eol(void) */ +/* static inline void inputfifo_send_eol(void) */ { hrt_data token = inputfifo_wrap_marker( 1 << HIVE_STR_TO_MIPI_EOL_BIT); @@ -185,7 +185,7 @@ static void inputfifo_send_eol(void) static void inputfifo_send_sof(void) -/* STORAGE_CLASS_INLINE void inputfifo_send_sof(void) */ +/* static inline void inputfifo_send_sof(void) */ { hrt_data token = inputfifo_wrap_marker( 1 << HIVE_STR_TO_MIPI_SOF_BIT); @@ -197,7 +197,7 @@ static void inputfifo_send_sof(void) static void inputfifo_send_eof(void) -/* STORAGE_CLASS_INLINE void inputfifo_send_eof(void) */ +/* static inline void inputfifo_send_eof(void) */ { hrt_data token = inputfifo_wrap_marker( 1 << HIVE_STR_TO_MIPI_EOF_BIT); @@ -209,7 +209,7 @@ static void inputfifo_send_eof(void) #ifdef __ON__ static void inputfifo_send_ch_id( -/* STORAGE_CLASS_INLINE void inputfifo_send_ch_id( */ +/* static inline void inputfifo_send_ch_id( */ unsigned int ch_id) { hrt_data token; @@ -223,7 +223,7 @@ static void inputfifo_send_ch_id( } static void inputfifo_send_fmt_type( -/* STORAGE_CLASS_INLINE void inputfifo_send_fmt_type( */ +/* static inline void inputfifo_send_fmt_type( */ unsigned int fmt_type) { hrt_data token; @@ -240,7 +240,7 @@ static void inputfifo_send_fmt_type( static void inputfifo_send_ch_id_and_fmt_type( -/* STORAGE_CLASS_INLINE +/* static inline void inputfifo_send_ch_id_and_fmt_type( */ unsigned int ch_id, unsigned int fmt_type) @@ -259,7 +259,7 @@ void inputfifo_send_ch_id_and_fmt_type( */ static void inputfifo_send_empty_token(void) -/* STORAGE_CLASS_INLINE void inputfifo_send_empty_token(void) */ +/* static inline void inputfifo_send_empty_token(void) */ { hrt_data token = inputfifo_wrap_marker(0); _sh_css_fifo_snd(token); @@ -269,7 +269,7 @@ static void inputfifo_send_empty_token(void) static void inputfifo_start_frame( -/* STORAGE_CLASS_INLINE void inputfifo_start_frame( */ +/* static inline void inputfifo_start_frame( */ unsigned int ch_id, unsigned int fmt_type) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c index 95542fc82217..62d13978475d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/pipeline/src/pipeline.c @@ -603,7 +603,7 @@ static enum ia_css_err pipeline_stage_create( /* Verify input parameters*/ if (!(stage_desc->in_frame) && !(stage_desc->firmware) && (stage_desc->binary) && !(stage_desc->binary->online)) { - err = IA_CSS_ERR_INTERNAL_ERROR; + err = IA_CSS_ERR_INTERNAL_ERROR; goto ERR; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/interface/ia_css_rmgr.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/interface/ia_css_rmgr.h index a0bb9f663ce6..9f78e709b3d0 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/interface/ia_css_rmgr.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/interface/ia_css_rmgr.h @@ -31,15 +31,14 @@ more details. #ifndef _IA_CSS_RMGR_H #define _IA_CSS_RMGR_H -#include "storage_class.h" #include <ia_css_err.h> #ifndef __INLINE_RMGR__ -#define STORAGE_CLASS_RMGR_H STORAGE_CLASS_EXTERN +#define STORAGE_CLASS_RMGR_H extern #define STORAGE_CLASS_RMGR_C #else /* __INLINE_RMGR__ */ -#define STORAGE_CLASS_RMGR_H STORAGE_CLASS_INLINE -#define STORAGE_CLASS_RMGR_C STORAGE_CLASS_INLINE +#define STORAGE_CLASS_RMGR_H static inline +#define STORAGE_CLASS_RMGR_C static inline #endif /* __INLINE_RMGR__ */ /** diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/src/rmgr_vbuf.c index fa92d8da8f1c..e56006c07ee8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/src/rmgr_vbuf.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/rmgr/src/rmgr_vbuf.c @@ -174,7 +174,7 @@ void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool) ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_rmgr_uninit_vbuf()\n"); if (pool == NULL) { ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "ia_css_rmgr_uninit_vbuf(): NULL argument\n"); - return; + return; } if (pool->handles != NULL) { /* free the hmm buffers */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/spctrl/src/spctrl.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/spctrl/src/spctrl.c index d9178e80dab2..6d9bceb60196 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/spctrl/src/spctrl.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/spctrl/src/spctrl.c @@ -37,7 +37,7 @@ more details. #include "ia_css_spctrl.h" #include "ia_css_debug.h" -typedef struct { +struct spctrl_context_info { struct ia_css_sp_init_dmem_cfg dmem_config; uint32_t spctrl_config_dmem_addr; /** location of dmem_cfg in SP dmem */ uint32_t spctrl_state_dmem_addr; @@ -45,9 +45,9 @@ typedef struct { hrt_vaddress code_addr; /* sp firmware location in host mem-DDR*/ uint32_t code_size; char *program_name; /* used in case of PLATFORM_SIM */ -} spctrl_context_info; +}; -static spctrl_context_info spctrl_cofig_info[N_SP_ID]; +static struct spctrl_context_info spctrl_cofig_info[N_SP_ID]; static bool spctrl_loaded[N_SP_ID] = {0}; /* Load firmware */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c index e882b5596813..f92b6a9f77eb 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css.c @@ -451,8 +451,6 @@ static enum ia_css_frame_format yuv422_copy_formats[] = { IA_CSS_FRAME_FORMAT_YUYV }; -#define array_length(array) (sizeof(array)/sizeof(array[0])) - /* Verify whether the selected output format is can be produced * by the copy binary given the stream format. * */ @@ -468,7 +466,7 @@ verify_copy_out_frame_format(struct ia_css_pipe *pipe) switch (pipe->stream->config.input_config.format) { case IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY: case IA_CSS_STREAM_FORMAT_YUV420_8: - for (i=0; i<array_length(yuv420_copy_formats) && !found; i++) + for (i=0; i<ARRAY_SIZE(yuv420_copy_formats) && !found; i++) found = (out_fmt == yuv420_copy_formats[i]); break; case IA_CSS_STREAM_FORMAT_YUV420_10: @@ -476,7 +474,7 @@ verify_copy_out_frame_format(struct ia_css_pipe *pipe) found = (out_fmt == IA_CSS_FRAME_FORMAT_YUV420_16); break; case IA_CSS_STREAM_FORMAT_YUV422_8: - for (i=0; i<array_length(yuv422_copy_formats) && !found; i++) + for (i=0; i<ARRAY_SIZE(yuv422_copy_formats) && !found; i++) found = (out_fmt == yuv422_copy_formats[i]); break; case IA_CSS_STREAM_FORMAT_YUV422_10: @@ -3781,6 +3779,7 @@ static enum ia_css_err create_host_acc_pipeline(struct ia_css_pipe *pipe) { enum ia_css_err err = IA_CSS_SUCCESS; + const struct ia_css_fw_info *fw; unsigned int i; IA_CSS_ENTER_PRIVATE("pipe = %p", pipe); @@ -3794,14 +3793,12 @@ create_host_acc_pipeline(struct ia_css_pipe *pipe) if (pipe->config.acc_extension) pipe->pipeline.pipe_qos_config = 0; -{ - const struct ia_css_fw_info *fw = pipe->vf_stage; + fw = pipe->vf_stage; for (i = 0; fw; fw = fw->next){ err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw); if (err != IA_CSS_SUCCESS) goto ERR; } -} for (i=0; i<pipe->config.num_acc_stages; i++) { struct ia_css_fw_info *fw = pipe->config.acc_stages[i]; @@ -4333,12 +4330,13 @@ ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe, } } } else if ((buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME) - || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) { - return_err = ia_css_bufq_enqueue_buffer(thread_id, + || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) + || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) + || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME) + || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME) + || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) { + + return_err = ia_css_bufq_enqueue_buffer(thread_id, queue_id, (uint32_t)h_vbuf->vptr); #if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS) @@ -5607,13 +5605,13 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe) mycs->num_yuv_scaler = cas_scaler_descr.num_stage; mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage * sizeof(struct ia_css_binary), GFP_KERNEL); - if (mycs->yuv_scaler_binary == NULL) { + if (!mycs->yuv_scaler_binary) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; return err; } mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage * sizeof(bool), GFP_KERNEL); - if (mycs->is_output_stage == NULL) { + if (!mycs->is_output_stage) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; return err; } @@ -5797,13 +5795,15 @@ static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe) #endif /* Make tnr reference buffers output block height align */ - tnr_info.res.height = #ifndef ISP2401 + tnr_info.res.height = CEIL_MUL(tnr_info.res.height, + mycs->video_binary.info->sp.block.output_block_height); #else + tnr_info.res.height = CEIL_MUL(tnr_height, + mycs->video_binary.info->sp.block.output_block_height); #endif - mycs->video_binary.info->sp.block.output_block_height); } else { tnr_info = mycs->video_binary.internal_frame_info; } @@ -6027,7 +6027,7 @@ sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width, err = ia_css_util_check_res(width, height); if (err != IA_CSS_SUCCESS) { - IA_CSS_LEAVE_ERR_PRIVATE(err); + IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } if (pipe->vf_output_info[idx].res.width != width || @@ -6258,14 +6258,14 @@ static enum ia_css_err load_primary_binaries( mycs->num_yuv_scaler = cas_scaler_descr.num_stage; mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage * sizeof(struct ia_css_binary), GFP_KERNEL); - if (mycs->yuv_scaler_binary == NULL) { + if (!mycs->yuv_scaler_binary) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage * sizeof(bool), GFP_KERNEL); - if (mycs->is_output_stage == NULL) { + if (!mycs->is_output_stage) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; @@ -6982,27 +6982,27 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output( } descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->in_info == NULL) { + if (!descr->in_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->internal_out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->internal_out_info == NULL) { + if (!descr->internal_out_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->out_info == NULL) { + if (!descr->out_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->vf_info == NULL) { + if (!descr->vf_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL); - if (descr->is_output_stage == NULL) { + if (!descr->is_output_stage) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } @@ -7118,22 +7118,22 @@ static enum ia_css_err ia_css_pipe_create_cas_scaler_desc(struct ia_css_pipe *pi descr->num_stage = num_stages; descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->in_info == NULL) { + if (!descr->in_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->internal_out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->internal_out_info == NULL) { + if (!descr->internal_out_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->out_info == NULL) { + if (!descr->out_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL); - if (descr->vf_info == NULL) { + if (!descr->vf_info) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } @@ -7276,13 +7276,13 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) mycs->num_yuv_scaler = cas_scaler_descr.num_stage; mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage * sizeof(struct ia_css_binary), GFP_KERNEL); - if (mycs->yuv_scaler_binary == NULL) { + if (!mycs->yuv_scaler_binary) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage * sizeof(bool), GFP_KERNEL); - if (mycs->is_output_stage == NULL) { + if (!mycs->is_output_stage) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } @@ -7383,7 +7383,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) } mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary), GFP_KERNEL); - if (mycs->vf_pp_binary == NULL) { + if (!mycs->vf_pp_binary) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; goto ERR; } @@ -8689,9 +8689,9 @@ enum ia_css_err ia_css_stream_capture( /* Check if the tag descriptor is valid */ if (num_captures < SH_CSS_MINIMUM_TAG_ID) { - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, - "ia_css_stream_capture() leave: return_err=%d\n", - IA_CSS_ERR_INVALID_ARGUMENTS); + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, + "ia_css_stream_capture() leave: return_err=%d\n", + IA_CSS_ERR_INVALID_ARGUMENTS); return IA_CSS_ERR_INVALID_ARGUMENTS; } @@ -9445,7 +9445,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* allocate the stream instance */ curr_stream = kmalloc(sizeof(struct ia_css_stream), GFP_KERNEL); - if (curr_stream == NULL) { + if (!curr_stream) { err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; IA_CSS_LEAVE_ERR(err); return err; @@ -9457,7 +9457,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* allocate pipes */ curr_stream->num_pipes = num_pipes; curr_stream->pipes = kzalloc(num_pipes * sizeof(struct ia_css_pipe *), GFP_KERNEL); - if (curr_stream->pipes == NULL) { + if (!curr_stream->pipes) { curr_stream->num_pipes = 0; kfree(curr_stream); curr_stream = NULL; @@ -9780,23 +9780,22 @@ ERR: if (err == IA_CSS_SUCCESS) { /* working mode: enter into the seed list */ - if (my_css_save.mode == sh_css_mode_working) - for(i = 0; i < MAX_ACTIVE_STREAMS; i++) - if (my_css_save.stream_seeds[i].stream == NULL) - { - IA_CSS_LOG("entered stream into loc=%d", i); - my_css_save.stream_seeds[i].orig_stream = stream; - my_css_save.stream_seeds[i].stream = curr_stream; - my_css_save.stream_seeds[i].num_pipes = num_pipes; - my_css_save.stream_seeds[i].stream_config = *stream_config; - for(j = 0; j < num_pipes; j++) - { - my_css_save.stream_seeds[i].pipe_config[j] = pipes[j]->config; - my_css_save.stream_seeds[i].pipes[j] = pipes[j]; - my_css_save.stream_seeds[i].orig_pipes[j] = &pipes[j]; - } - break; + if (my_css_save.mode == sh_css_mode_working) { + for (i = 0; i < MAX_ACTIVE_STREAMS; i++) + if (!my_css_save.stream_seeds[i].stream) { + IA_CSS_LOG("entered stream into loc=%d", i); + my_css_save.stream_seeds[i].orig_stream = stream; + my_css_save.stream_seeds[i].stream = curr_stream; + my_css_save.stream_seeds[i].num_pipes = num_pipes; + my_css_save.stream_seeds[i].stream_config = *stream_config; + for (j = 0; j < num_pipes; j++) { + my_css_save.stream_seeds[i].pipe_config[j] = pipes[j]->config; + my_css_save.stream_seeds[i].pipes[j] = pipes[j]; + my_css_save.stream_seeds[i].orig_pipes[j] = &pipes[j]; + } + break; } + } #else if (err == IA_CSS_SUCCESS) { err = ia_css_save_stream(curr_stream); @@ -9970,32 +9969,32 @@ ia_css_stream_load(struct ia_css_stream *stream) enum ia_css_err err; assert(stream != NULL); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter, \n"); - for(i=0;i<MAX_ACTIVE_STREAMS;i++) - if (my_css_save.stream_seeds[i].stream == stream) - { + for (i = 0; i < MAX_ACTIVE_STREAMS; i++) { + if (my_css_save.stream_seeds[i].stream == stream) { int j; - for(j=0;j<my_css_save.stream_seeds[i].num_pipes;j++) - if ((err = ia_css_pipe_create(&(my_css_save.stream_seeds[i].pipe_config[j]), &my_css_save.stream_seeds[i].pipes[j])) != IA_CSS_SUCCESS) - { - if (j) - { + for ( j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) { + if ((err = ia_css_pipe_create(&(my_css_save.stream_seeds[i].pipe_config[j]), &my_css_save.stream_seeds[i].pipes[j])) != IA_CSS_SUCCESS) { + if (j) { int k; for(k=0;k<j;k++) ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[k]); } return err; } - err = ia_css_stream_create(&(my_css_save.stream_seeds[i].stream_config), my_css_save.stream_seeds[i].num_pipes, - my_css_save.stream_seeds[i].pipes, &(my_css_save.stream_seeds[i].stream)); - if (err != IA_CSS_SUCCESS) - { + } + err = ia_css_stream_create(&(my_css_save.stream_seeds[i].stream_config), + my_css_save.stream_seeds[i].num_pipes, + my_css_save.stream_seeds[i].pipes, + &(my_css_save.stream_seeds[i].stream)); + if (err != IA_CSS_SUCCESS) { ia_css_stream_destroy(stream); - for(j=0;j<my_css_save.stream_seeds[i].num_pipes;j++) + for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]); return err; } break; } + } ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit, \n"); return IA_CSS_SUCCESS; #else @@ -10524,7 +10523,7 @@ ia_css_update_continuous_frames(struct ia_css_stream *stream) ia_css_debug_dtrace( IA_CSS_DEBUG_TRACE, "sh_css_update_continuous_frames() leave: invalid stream, return_void\n"); - return IA_CSS_ERR_INVALID_ARGUMENTS; + return IA_CSS_ERR_INVALID_ARGUMENTS; } pipe = stream->continuous_pipe; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c index 53a7891111f9..8158ea40d069 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_firmware.c @@ -147,7 +147,7 @@ sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi, struct ia char *parambuf = kmalloc(paramstruct_size + configstruct_size + statestruct_size, GFP_KERNEL); - if (parambuf == NULL) + if (!parambuf) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = NULL; @@ -229,14 +229,15 @@ sh_css_load_firmware(const char *fw_data, sh_css_blob_info = kmalloc( (sh_css_num_binaries - NUM_OF_SPS) * sizeof(*sh_css_blob_info), GFP_KERNEL); - if (sh_css_blob_info == NULL) + if (!sh_css_blob_info) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; } else { sh_css_blob_info = NULL; } - fw_minibuffer = kzalloc(sh_css_num_binaries * sizeof(struct fw_param), GFP_KERNEL); - if (fw_minibuffer == NULL) + fw_minibuffer = kcalloc(sh_css_num_binaries, sizeof(struct fw_param), + GFP_KERNEL); + if (!fw_minibuffer) return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY; for (i = 0; i < sh_css_num_binaries; i++) { @@ -295,10 +296,8 @@ void sh_css_unload_firmware(void) } memset(&sh_css_sp_fw, 0, sizeof(sh_css_sp_fw)); - if (sh_css_blob_info) { - kfree(sh_css_blob_info); - sh_css_blob_info = NULL; - } + kfree(sh_css_blob_info); + sh_css_blob_info = NULL; sh_css_num_binaries = 0; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_hrt.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_hrt.c index 0bfebced63af..716d808d56db 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_hrt.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_hrt.c @@ -80,5 +80,5 @@ enum ia_css_err sh_css_hrt_sp_wait(void) hrt_sleep(); } -return IA_CSS_SUCCESS; + return IA_CSS_SUCCESS; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_internal.h index 5b2b78f96dc5..0910021286a4 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_internal.h @@ -961,7 +961,7 @@ struct host_sp_queues { extern int (*sh_css_printf)(const char *fmt, va_list args); -STORAGE_CLASS_INLINE void +static inline void sh_css_print(const char *fmt, ...) { va_list ap; @@ -973,7 +973,7 @@ sh_css_print(const char *fmt, ...) } } -STORAGE_CLASS_INLINE void +static inline void sh_css_vprint(const char *fmt, va_list args) { if (sh_css_printf) diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c index eaf60e7b2dac..e6ebd1b08f0d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c @@ -365,10 +365,8 @@ ia_css_shading_table_alloc( IA_CSS_ENTER(""); me = kmalloc(sizeof(*me), GFP_KERNEL); - if (me == NULL) { - IA_CSS_ERROR("out of memory"); + if (!me) return me; - } me->width = width; me->height = height; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_params.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_params.c index 48224370b8bf..fbb36112fe3c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_params.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_params.c @@ -4266,33 +4266,33 @@ sh_css_params_write_to_ddr_internal( size_t *virt_size_tetra_y[ IA_CSS_MORPH_TABLE_NUM_PLANES]; - virt_addr_tetra_x[0] = &ddr_map->tetra_r_x; - virt_addr_tetra_x[1] = &ddr_map->tetra_gr_x; - virt_addr_tetra_x[2] = &ddr_map->tetra_gb_x; - virt_addr_tetra_x[3] = &ddr_map->tetra_b_x; - virt_addr_tetra_x[4] = &ddr_map->tetra_ratb_x; - virt_addr_tetra_x[5] = &ddr_map->tetra_batr_x; - - virt_size_tetra_x[0] = &ddr_map_size->tetra_r_x; - virt_size_tetra_x[1] = &ddr_map_size->tetra_gr_x; - virt_size_tetra_x[2] = &ddr_map_size->tetra_gb_x; - virt_size_tetra_x[3] = &ddr_map_size->tetra_b_x; - virt_size_tetra_x[4] = &ddr_map_size->tetra_ratb_x; - virt_size_tetra_x[5] = &ddr_map_size->tetra_batr_x; - - virt_addr_tetra_y[0] = &ddr_map->tetra_r_y; - virt_addr_tetra_y[1] = &ddr_map->tetra_gr_y; - virt_addr_tetra_y[2] = &ddr_map->tetra_gb_y; - virt_addr_tetra_y[3] = &ddr_map->tetra_b_y; - virt_addr_tetra_y[4] = &ddr_map->tetra_ratb_y; - virt_addr_tetra_y[5] = &ddr_map->tetra_batr_y; - - virt_size_tetra_y[0] = &ddr_map_size->tetra_r_y; - virt_size_tetra_y[1] = &ddr_map_size->tetra_gr_y; - virt_size_tetra_y[2] = &ddr_map_size->tetra_gb_y; - virt_size_tetra_y[3] = &ddr_map_size->tetra_b_y; - virt_size_tetra_y[4] = &ddr_map_size->tetra_ratb_y; - virt_size_tetra_y[5] = &ddr_map_size->tetra_batr_y; + virt_addr_tetra_x[0] = &ddr_map->tetra_r_x; + virt_addr_tetra_x[1] = &ddr_map->tetra_gr_x; + virt_addr_tetra_x[2] = &ddr_map->tetra_gb_x; + virt_addr_tetra_x[3] = &ddr_map->tetra_b_x; + virt_addr_tetra_x[4] = &ddr_map->tetra_ratb_x; + virt_addr_tetra_x[5] = &ddr_map->tetra_batr_x; + + virt_size_tetra_x[0] = &ddr_map_size->tetra_r_x; + virt_size_tetra_x[1] = &ddr_map_size->tetra_gr_x; + virt_size_tetra_x[2] = &ddr_map_size->tetra_gb_x; + virt_size_tetra_x[3] = &ddr_map_size->tetra_b_x; + virt_size_tetra_x[4] = &ddr_map_size->tetra_ratb_x; + virt_size_tetra_x[5] = &ddr_map_size->tetra_batr_x; + + virt_addr_tetra_y[0] = &ddr_map->tetra_r_y; + virt_addr_tetra_y[1] = &ddr_map->tetra_gr_y; + virt_addr_tetra_y[2] = &ddr_map->tetra_gb_y; + virt_addr_tetra_y[3] = &ddr_map->tetra_b_y; + virt_addr_tetra_y[4] = &ddr_map->tetra_ratb_y; + virt_addr_tetra_y[5] = &ddr_map->tetra_batr_y; + + virt_size_tetra_y[0] = &ddr_map_size->tetra_r_y; + virt_size_tetra_y[1] = &ddr_map_size->tetra_gr_y; + virt_size_tetra_y[2] = &ddr_map_size->tetra_gb_y; + virt_size_tetra_y[3] = &ddr_map_size->tetra_b_y; + virt_size_tetra_y[4] = &ddr_map_size->tetra_ratb_y; + virt_size_tetra_y[5] = &ddr_map_size->tetra_batr_y; buff_realloced = false; for (i = 0; i < IA_CSS_MORPH_TABLE_NUM_PLANES; i++) { diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c index b8aae4ba5a78..a1c81c12718c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c index 5232327f5d9c..6e2dce7a5a2d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_bo.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* @@ -58,7 +54,7 @@ static unsigned int nr_to_order_bottom(unsigned int nr) return fls(nr) - 1; } -struct hmm_buffer_object *__bo_alloc(struct kmem_cache *bo_cache) +static struct hmm_buffer_object *__bo_alloc(struct kmem_cache *bo_cache) { struct hmm_buffer_object *bo; @@ -99,7 +95,7 @@ static int __bo_init(struct hmm_bo_device *bdev, struct hmm_buffer_object *bo, return 0; } -struct hmm_buffer_object *__bo_search_and_remove_from_free_rbtree( +static struct hmm_buffer_object *__bo_search_and_remove_from_free_rbtree( struct rb_node *node, unsigned int pgnr) { struct hmm_buffer_object *this, *ret_bo, *temp_bo; @@ -150,7 +146,7 @@ remove_bo_and_return: return temp_bo; } -struct hmm_buffer_object *__bo_search_by_addr(struct rb_root *root, +static struct hmm_buffer_object *__bo_search_by_addr(struct rb_root *root, ia_css_ptr start) { struct rb_node *n = root->rb_node; @@ -175,8 +171,8 @@ struct hmm_buffer_object *__bo_search_by_addr(struct rb_root *root, return NULL; } -struct hmm_buffer_object *__bo_search_by_addr_in_range(struct rb_root *root, - unsigned int start) +static struct hmm_buffer_object *__bo_search_by_addr_in_range( + struct rb_root *root, unsigned int start) { struct rb_node *n = root->rb_node; struct hmm_buffer_object *bo; @@ -258,7 +254,7 @@ static void __bo_insert_to_alloc_rbtree(struct rb_root *root, rb_insert_color(&bo->node, root); } -struct hmm_buffer_object *__bo_break_up(struct hmm_bo_device *bdev, +static struct hmm_buffer_object *__bo_break_up(struct hmm_bo_device *bdev, struct hmm_buffer_object *bo, unsigned int pgnr) { @@ -331,7 +327,7 @@ static void __bo_take_off_handling(struct hmm_buffer_object *bo) } } -struct hmm_buffer_object *__bo_merge(struct hmm_buffer_object *bo, +static struct hmm_buffer_object *__bo_merge(struct hmm_buffer_object *bo, struct hmm_buffer_object *next_bo) { struct hmm_bo_device *bdev; @@ -727,10 +723,8 @@ static int alloc_private_pages(struct hmm_buffer_object *bo, bo->page_obj = kmalloc_array(pgnr, sizeof(struct hmm_page_object), GFP_KERNEL); - if (unlikely(!bo->page_obj)) { - dev_err(atomisp_dev, "out of memory for bo->page_obj\n"); + if (unlikely(!bo->page_obj)) return -ENOMEM; - } i = 0; alloc_pgnr = 0; @@ -991,15 +985,12 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, struct page **pages; pages = kmalloc_array(bo->pgnr, sizeof(struct page *), GFP_KERNEL); - if (unlikely(!pages)) { - dev_err(atomisp_dev, "out of memory for pages...\n"); + if (unlikely(!pages)) return -ENOMEM; - } bo->page_obj = kmalloc_array(bo->pgnr, sizeof(struct hmm_page_object), GFP_KERNEL); if (unlikely(!bo->page_obj)) { - dev_err(atomisp_dev, "out of memory for bo->page_obj...\n"); kfree(pages); return -ENOMEM; } @@ -1168,13 +1159,9 @@ status_err2: int hmm_bo_page_allocated(struct hmm_buffer_object *bo) { - int ret; - check_bo_null_return(bo, 0); - ret = bo->status & HMM_BO_PAGE_ALLOCED; - - return ret; + return bo->status & HMM_BO_PAGE_ALLOCED; } /* @@ -1366,7 +1353,6 @@ void *hmm_bo_vmap(struct hmm_buffer_object *bo, bool cached) pages = kmalloc_array(bo->pgnr, sizeof(*pages), GFP_KERNEL); if (unlikely(!pages)) { mutex_unlock(&bo->mutex); - dev_err(atomisp_dev, "out of memory for pages...\n"); return NULL; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c index 19e0e9ee37de..f59fd9908257 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_dynamic_pool.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* @@ -116,8 +112,6 @@ static void free_pages_to_dynamic_pool(void *pool, hmm_page = kmem_cache_zalloc(dypool_info->pgptr_cache, GFP_KERNEL); if (!hmm_page) { - dev_err(atomisp_dev, "out of memory for hmm_page.\n"); - /* free page directly */ ret = set_pages_wb(page_obj->page, 1); if (ret) @@ -151,10 +145,8 @@ static int hmm_dynamic_pool_init(void **pool, unsigned int pool_size) dypool_info = kmalloc(sizeof(struct hmm_dynamic_pool_info), GFP_KERNEL); - if (unlikely(!dypool_info)) { - dev_err(atomisp_dev, "out of memory for repool_info.\n"); + if (unlikely(!dypool_info)) return -ENOMEM; - } dypool_info->pgptr_cache = kmem_cache_create("pgptr_cache", sizeof(struct hmm_page), 0, diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c index bf6586805f7f..f300e7547997 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_reserved_pool.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* @@ -92,15 +88,12 @@ static int hmm_reserved_pool_setup(struct hmm_reserved_pool_info **repool_info, pool_info = kmalloc(sizeof(struct hmm_reserved_pool_info), GFP_KERNEL); - if (unlikely(!pool_info)) { - dev_err(atomisp_dev, "out of memory for repool_info.\n"); + if (unlikely(!pool_info)) return -ENOMEM; - } pool_info->pages = kmalloc(sizeof(struct page *) * pool_size, GFP_KERNEL); if (unlikely(!pool_info->pages)) { - dev_err(atomisp_dev, "out of memory for repool_info->pages.\n"); kfree(pool_info); return -ENOMEM; } diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_vm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_vm.c index 0722a68a49e7..0df96e661983 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_vm.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm_vm.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* @@ -89,10 +85,8 @@ static struct hmm_vm_node *alloc_hmm_vm_node(unsigned int pgnr, struct hmm_vm_node *node; node = kmem_cache_alloc(vm->cache, GFP_KERNEL); - if (!node) { - dev_err(atomisp_dev, "out of memory.\n"); + if (!node) return NULL; - } INIT_LIST_HEAD(&node->list); node->pgnr = pgnr; diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_custom_host_hrt.h b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_custom_host_hrt.h index 46a5d29e2d3a..fb38fc540b81 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_custom_host_hrt.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_custom_host_hrt.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef _hive_isp_css_custom_host_hrt_h_ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.c b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.c index 2e78976bb2ac..a94958bde718 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.h b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.h index 1328944a7afd..15c2dfb6794e 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/hrt/hive_isp_css_mm_hrt.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm.h index 6b9fb1b2caaf..1e135c7c6d9b 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h index dffd6e9cf693..bd44ebbc427c 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h index a9446adb4c70..9e51a657ece4 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_bo_dev.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_common.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_common.h index f1593aa38ce1..00885203fb14 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_common.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_common.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_pool.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_pool.h index 1ba360433d88..bf24e44462bc 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_pool.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_pool.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef __HMM_POOL_H__ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_vm.h b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_vm.h index 07d40662de32..52098161082d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_vm.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/hmm/hmm_vm.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/isp_mmu.h b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/isp_mmu.h index 6b4eefc929e2..560014add005 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/isp_mmu.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/isp_mmu.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h index 06041e94cbb2..031c0398bf65 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #ifndef SH_MMU_H_ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu_mrfld.h b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu_mrfld.h index b9bad9f06235..662e98f41da2 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu_mrfld.h +++ b/drivers/staging/media/atomisp/pci/atomisp2/include/mmu/sh_mmu_mrfld.h @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ diff --git a/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c b/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c index 706bd43e8b1b..e36c2a33b41a 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/mmu/isp_mmu.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ /* diff --git a/drivers/staging/media/atomisp/pci/atomisp2/mmu/sh_mmu_mrfld.c b/drivers/staging/media/atomisp/pci/atomisp2/mmu/sh_mmu_mrfld.c index 97546bd124cd..c59bcc982966 100644 --- a/drivers/staging/media/atomisp/pci/atomisp2/mmu/sh_mmu_mrfld.c +++ b/drivers/staging/media/atomisp/pci/atomisp2/mmu/sh_mmu_mrfld.c @@ -14,10 +14,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. * */ #include "type_support.h" diff --git a/drivers/staging/media/atomisp/platform/Makefile b/drivers/staging/media/atomisp/platform/Makefile index df157630bda9..0e3b7e1c81c6 100644 --- a/drivers/staging/media/atomisp/platform/Makefile +++ b/drivers/staging/media/atomisp/platform/Makefile @@ -2,5 +2,4 @@ # Makefile for camera drivers. # -obj-$(CONFIG_INTEL_ATOMISP) += clock/ obj-$(CONFIG_INTEL_ATOMISP) += intel-mid/ diff --git a/drivers/staging/media/atomisp/platform/clock/Makefile b/drivers/staging/media/atomisp/platform/clock/Makefile deleted file mode 100644 index 82fbe8b6968a..000000000000 --- a/drivers/staging/media/atomisp/platform/clock/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for clock devices. -# - -obj-$(CONFIG_INTEL_ATOMISP) += vlv2_plat_clock.o -obj-$(CONFIG_INTEL_ATOMISP) += platform_vlv2_plat_clk.o diff --git a/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.c b/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.c deleted file mode 100644 index 0aae9b0283bb..000000000000 --- a/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * platform_vlv2_plat_clk.c - VLV2 platform clock driver - * Copyright (C) 2013 Intel Corporation - * - * Author: Asutosh Pathak <asutosh.pathak@intel.com> - * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com> - * Author: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com> - * - * This program is free software; you can 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - */ - -#include <linux/device.h> -#include <linux/err.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/printk.h> - -static int __init vlv2_plat_clk_init(void) -{ - struct platform_device *pdev; - - pdev = platform_device_register_simple("vlv2_plat_clk", -1, NULL, 0); - if (IS_ERR(pdev)) { - pr_err("platform_vlv2_plat_clk:register failed: %ld\n", - PTR_ERR(pdev)); - return PTR_ERR(pdev); - } - - return 0; -} - -device_initcall(vlv2_plat_clk_init); diff --git a/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.h b/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.h deleted file mode 100644 index b730ab0e8223..000000000000 --- a/drivers/staging/media/atomisp/platform/clock/platform_vlv2_plat_clk.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * platform_vlv2_plat_clk.h: platform clock driver library header file - * Copyright (C) 2013 Intel Corporation - * - * Author: Asutosh Pathak <asutosh.pathak@intel.com> - * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com> - * Author: Sergio Aguirre <sergio.a.aguirre.rodriguez@intel.com> - * - * This program is free software; you can 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - */ -#ifndef _PLATFORM_VLV2_PLAT_CLK_H_ -#define _PLATFORM_VLV2_PLAT_CLK_H_ - -#include <linux/sfi.h> -#include <asm/intel-mid.h> - -extern void __init *vlv2_plat_clk_device_platform_data( - void *info) __attribute__((weak)); -#endif diff --git a/drivers/staging/media/atomisp/platform/clock/vlv2_plat_clock.c b/drivers/staging/media/atomisp/platform/clock/vlv2_plat_clock.c deleted file mode 100644 index f96789a31819..000000000000 --- a/drivers/staging/media/atomisp/platform/clock/vlv2_plat_clock.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * vlv2_plat_clock.c - VLV2 platform clock driver - * Copyright (C) 2013 Intel Corporation - * - * Author: Asutosh Pathak <asutosh.pathak@intel.com> - * Author: Chandra Sekhar Anagani <chandra.sekhar.anagani@intel.com> - * - * This program is free software; you can 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - */ - -#include <linux/err.h> -#include <linux/io.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include "../../include/linux/vlv2_plat_clock.h" - -/* NOTE: Most of below constants could come from platform data. - * To be fixed when appropriate ACPI support comes. - */ -#define VLV2_PMC_CLK_BASE_ADDRESS 0xfed03060 -#define PLT_CLK_CTL_OFFSET(x) (0x04 * (x)) - -#define CLK_CONFG_BIT_POS 0 -#define CLK_CONFG_BIT_LEN 2 -#define CLK_CONFG_D3_GATED 0 -#define CLK_CONFG_FORCE_ON 1 -#define CLK_CONFG_FORCE_OFF 2 - -#define CLK_FREQ_TYPE_BIT_POS 2 -#define CLK_FREQ_TYPE_BIT_LEN 1 -#define CLK_FREQ_TYPE_XTAL 0 /* 25 MHz */ -#define CLK_FREQ_TYPE_PLL 1 /* 19.2 MHz */ - -#define MAX_CLK_COUNT 5 - -/* Helper macros to manipulate bitfields */ -#define REG_MASK(n) (((1 << (n##_BIT_LEN)) - 1) << (n##_BIT_POS)) -#define REG_SET_FIELD(r, n, v) (((r) & ~REG_MASK(n)) | \ - (((v) << (n##_BIT_POS)) & REG_MASK(n))) -#define REG_GET_FIELD(r, n) (((r) & REG_MASK(n)) >> n##_BIT_POS) -/* - * vlv2 platform has 6 platform clocks, controlled by 4 byte registers - * Total size required for mapping is 6*4 = 24 bytes - */ -#define PMC_MAP_SIZE 24 - -static DEFINE_MUTEX(clk_mutex); -static void __iomem *pmc_base; - -/* - * vlv2_plat_set_clock_freq - Set clock frequency to a specified platform clock - * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5) - * @freq_type: Clock frequency (0-25 MHz(XTAL), 1-19.2 MHz(PLL) ) - */ -int vlv2_plat_set_clock_freq(int clk_num, int freq_type) -{ - void __iomem *addr; - - if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) { - pr_err("Clock number out of range (%d)\n", clk_num); - return -EINVAL; - } - - if (freq_type != CLK_FREQ_TYPE_XTAL && - freq_type != CLK_FREQ_TYPE_PLL) { - pr_err("wrong clock type\n"); - return -EINVAL; - } - - if (!pmc_base) { - pr_err("memio map is not set\n"); - return -EINVAL; - } - - addr = pmc_base + PLT_CLK_CTL_OFFSET(clk_num); - - mutex_lock(&clk_mutex); - writel(REG_SET_FIELD(readl(addr), CLK_FREQ_TYPE, freq_type), addr); - mutex_unlock(&clk_mutex); - - return 0; -} -EXPORT_SYMBOL_GPL(vlv2_plat_set_clock_freq); - -/* - * vlv2_plat_get_clock_freq - Get the status of specified platform clock - * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5) - * - * Returns 0 for 25 MHz(XTAL) and 1 for 19.2 MHz(PLL) - */ -int vlv2_plat_get_clock_freq(int clk_num) -{ - u32 ret; - - if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) { - pr_err("Clock number out of range (%d)\n", clk_num); - return -EINVAL; - } - - if (!pmc_base) { - pr_err("memio map is not set\n"); - return -EINVAL; - } - - mutex_lock(&clk_mutex); - ret = REG_GET_FIELD(readl(pmc_base + PLT_CLK_CTL_OFFSET(clk_num)), - CLK_FREQ_TYPE); - mutex_unlock(&clk_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(vlv2_plat_get_clock_freq); - -/* - * vlv2_plat_configure_clock - Configure the specified platform clock - * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5) - * @conf: Clock gating: - * 0 - Clock gated on D3 state - * 1 - Force on - * 2,3 - Force off - */ -int vlv2_plat_configure_clock(int clk_num, u32 conf) -{ - void __iomem *addr; - - if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) { - pr_err("Clock number out of range (%d)\n", clk_num); - return -EINVAL; - } - - if (conf != CLK_CONFG_D3_GATED && - conf != CLK_CONFG_FORCE_ON && - conf != CLK_CONFG_FORCE_OFF) { - pr_err("Invalid clock configuration requested\n"); - return -EINVAL; - } - - if (!pmc_base) { - pr_err("memio map is not set\n"); - return -EINVAL; - } - - addr = pmc_base + PLT_CLK_CTL_OFFSET(clk_num); - - mutex_lock(&clk_mutex); - writel(REG_SET_FIELD(readl(addr), CLK_CONFG, conf), addr); - mutex_unlock(&clk_mutex); - return 0; -} -EXPORT_SYMBOL_GPL(vlv2_plat_configure_clock); - -/* - * vlv2_plat_get_clock_status - Get the status of specified platform clock - * @clk_num: Platform clock number (i.e. 0, 1, 2, ...,5) - * - * Returns 1 - On, 0 - Off - */ -int vlv2_plat_get_clock_status(int clk_num) -{ - int ret; - - if (clk_num < 0 || clk_num >= MAX_CLK_COUNT) { - pr_err("Clock number out of range (%d)\n", clk_num); - return -EINVAL; - } - - if (!pmc_base) { - pr_err("memio map is not set\n"); - return -EINVAL; - } - - mutex_lock(&clk_mutex); - ret = (int)REG_GET_FIELD(readl(pmc_base + PLT_CLK_CTL_OFFSET(clk_num)), - CLK_CONFG); - mutex_unlock(&clk_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(vlv2_plat_get_clock_status); - -static int vlv2_plat_clk_probe(struct platform_device *pdev) -{ - int i = 0; - - pmc_base = ioremap_nocache(VLV2_PMC_CLK_BASE_ADDRESS, PMC_MAP_SIZE); - if (!pmc_base) { - dev_err(&pdev->dev, "I/O memory remapping failed\n"); - return -ENOMEM; - } - - /* Initialize all clocks as disabled */ - for (i = 0; i < MAX_CLK_COUNT; i++) - vlv2_plat_configure_clock(i, CLK_CONFG_FORCE_OFF); - - dev_info(&pdev->dev, "vlv2_plat_clk initialized\n"); - return 0; -} - -static const struct platform_device_id vlv2_plat_clk_id[] = { - {"vlv2_plat_clk", 0}, - {} -}; - -static int vlv2_resume(struct device *device) -{ - int i; - - /* Initialize all clocks as disabled */ - for (i = 0; i < MAX_CLK_COUNT; i++) - vlv2_plat_configure_clock(i, CLK_CONFG_FORCE_OFF); - - return 0; -} - -static int vlv2_suspend(struct device *device) -{ - return 0; -} - -static const struct dev_pm_ops vlv2_pm_ops = { - .suspend = vlv2_suspend, - .resume = vlv2_resume, -}; - -static struct platform_driver vlv2_plat_clk_driver = { - .probe = vlv2_plat_clk_probe, - .id_table = vlv2_plat_clk_id, - .driver = { - .name = "vlv2_plat_clk", - .pm = &vlv2_pm_ops, - }, -}; - -static int __init vlv2_plat_clk_init(void) -{ - return platform_driver_register(&vlv2_plat_clk_driver); -} -arch_initcall(vlv2_plat_clk_init); diff --git a/drivers/staging/media/atomisp/platform/intel-mid/Makefile b/drivers/staging/media/atomisp/platform/intel-mid/Makefile index 4621261c35db..c53db1364e21 100644 --- a/drivers/staging/media/atomisp/platform/intel-mid/Makefile +++ b/drivers/staging/media/atomisp/platform/intel-mid/Makefile @@ -1,5 +1,4 @@ # # Makefile for intel-mid devices. # -obj-$(CONFIG_INTEL_ATOMISP) += intel_mid_pcihelpers.o obj-$(CONFIG_INTEL_ATOMISP) += atomisp_gmin_platform.o diff --git a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c index edaae93af8f9..bf9f34b7ad72 100644 --- a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c @@ -4,10 +4,10 @@ #include <linux/efi.h> #include <linux/pci.h> #include <linux/acpi.h> +#include <linux/clk.h> #include <linux/delay.h> #include <media/v4l2-subdev.h> #include <linux/mfd/intel_soc_pmic.h> -#include "../../include/linux/vlv2_plat_clock.h" #include <linux/regulator/consumer.h> #include <linux/gpio/consumer.h> #include <linux/gpio.h> @@ -17,11 +17,7 @@ #define MAX_SUBDEVS 8 -/* Should be defined in vlv2_plat_clock API, isn't: */ -#define VLV2_CLK_PLL_19P2MHZ 1 -#define VLV2_CLK_XTAL_19P2MHZ 0 -#define VLV2_CLK_ON 1 -#define VLV2_CLK_OFF 2 +#define VLV2_CLK_PLL_19P2MHZ 1 /* XTAL on CHT */ #define ELDO1_SEL_REG 0x19 #define ELDO1_1P8V 0x16 #define ELDO1_CTRL_SHIFT 0x00 @@ -33,6 +29,8 @@ struct gmin_subdev { struct v4l2_subdev *subdev; int clock_num; int clock_src; + bool clock_on; + struct clk *pmc_clk; struct gpio_desc *gpio0; struct gpio_desc *gpio1; struct regulator *v1p8_reg; @@ -108,49 +106,6 @@ const struct atomisp_platform_data *atomisp_get_platform_data(void) } EXPORT_SYMBOL_GPL(atomisp_get_platform_data); -static int af_power_ctrl(struct v4l2_subdev *subdev, int flag) -{ - struct gmin_subdev *gs = find_gmin_subdev(subdev); - - if (gs && gs->v2p8_vcm_on == flag) - return 0; - gs->v2p8_vcm_on = flag; - - /* - * The power here is used for dw9817, - * regulator is from rear sensor - */ - if (gs->v2p8_vcm_reg) { - if (flag) - return regulator_enable(gs->v2p8_vcm_reg); - else - return regulator_disable(gs->v2p8_vcm_reg); - } - return 0; -} - -/* - * Used in a handful of modules. Focus motor control, I think. Note - * that there is no configurability in the API, so this needs to be - * fixed where it is used. - * - * struct camera_af_platform_data { - * int (*power_ctrl)(struct v4l2_subdev *subdev, int flag); - * }; - * - * Note that the implementation in MCG platform_camera.c is stubbed - * out anyway (i.e. returns zero from the callback) on BYT. So - * neither needed on gmin platforms or supported upstream. - */ -const struct camera_af_platform_data *camera_get_af_platform_data(void) -{ - static struct camera_af_platform_data afpd = { - .power_ctrl = af_power_ctrl, - }; - return &afpd; -} -EXPORT_SYMBOL_GPL(camera_get_af_platform_data); - int atomisp_register_i2c_module(struct v4l2_subdev *subdev, struct camera_sensor_platform_data *plat_data, enum intel_v4l2_subdev_type type) @@ -334,15 +289,8 @@ static const struct { #define CFG_VAR_NAME_MAX 64 -static int gmin_platform_init(struct i2c_client *client) -{ - return 0; -} - -static int gmin_platform_deinit(void) -{ - return 0; -} +#define GMIN_PMC_CLK_NAME 14 /* "pmc_plt_clk_[0..5]" */ +static char gmin_pmc_clk_name[GMIN_PMC_CLK_NAME]; static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) { @@ -377,21 +325,42 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev) gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW); gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW); - if (!IS_ERR(gmin_subdevs[i].gpio0)) { - ret = gpiod_direction_output(gmin_subdevs[i].gpio0, 0); - if (ret) - dev_err(dev, "gpio0 set output failed: %d\n", ret); - } else { - gmin_subdevs[i].gpio0 = NULL; + /* get PMC clock with clock framework */ + snprintf(gmin_pmc_clk_name, + sizeof(gmin_pmc_clk_name), + "%s_%d", "pmc_plt_clk", gmin_subdevs[i].clock_num); + + gmin_subdevs[i].pmc_clk = devm_clk_get(dev, gmin_pmc_clk_name); + if (IS_ERR(gmin_subdevs[i].pmc_clk)) { + ret = PTR_ERR(gmin_subdevs[i].pmc_clk); + + dev_err(dev, + "Failed to get clk from %s : %d\n", + gmin_pmc_clk_name, + ret); + + return NULL; } - if (!IS_ERR(gmin_subdevs[i].gpio1)) { - ret = gpiod_direction_output(gmin_subdevs[i].gpio1, 0); - if (ret) - dev_err(dev, "gpio1 set output failed: %d\n", ret); - } else { + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(gmin_subdevs[i].pmc_clk); + if (!ret) + clk_disable_unprepare(gmin_subdevs[i].pmc_clk); + + if (IS_ERR(gmin_subdevs[i].gpio0)) + gmin_subdevs[i].gpio0 = NULL; + + if (IS_ERR(gmin_subdevs[i].gpio1)) gmin_subdevs[i].gpio1 = NULL; - } if (pmic_id == PMIC_REGULATOR) { gmin_subdevs[i].v1p8_reg = regulator_get(dev, "V1P8SX"); @@ -539,13 +508,27 @@ static int gmin_flisclk_ctrl(struct v4l2_subdev *subdev, int on) { int ret = 0; struct gmin_subdev *gs = find_gmin_subdev(subdev); + struct i2c_client *client = v4l2_get_subdevdata(subdev); + + if (gs->clock_on == !!on) + return 0; + + if (on) { + ret = clk_set_rate(gs->pmc_clk, gs->clock_src); + + if (ret) + dev_err(&client->dev, "unable to set PMC rate %d\n", + gs->clock_src); + + ret = clk_prepare_enable(gs->pmc_clk); + if (ret == 0) + gs->clock_on = true; + } else { + clk_disable_unprepare(gs->pmc_clk); + gs->clock_on = false; + } - if (on) - ret = vlv2_plat_set_clock_freq(gs->clock_num, gs->clock_src); - if (ret) - return ret; - return vlv2_plat_configure_clock(gs->clock_num, - on ? VLV2_CLK_ON : VLV2_CLK_OFF); + return ret; } static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag) @@ -592,8 +575,6 @@ static struct camera_sensor_platform_data gmin_plat = { .v2p8_ctrl = gmin_v2p8_ctrl, .v1p2_ctrl = gmin_v1p2_ctrl, .flisclk_ctrl = gmin_flisclk_ctrl, - .platform_init = gmin_platform_init, - .platform_deinit = gmin_platform_deinit, .csi_cfg = gmin_csi_cfg, .get_vcm_ctrl = gmin_get_vcm_ctrl, }; @@ -739,10 +720,8 @@ int camera_sensor_csi(struct v4l2_subdev *sd, u32 port, if (flag) { csi = kzalloc(sizeof(*csi), GFP_KERNEL); - if (!csi) { - dev_err(&client->dev, "out of memory\n"); + if (!csi) return -ENOMEM; - } csi->port = port; csi->num_lanes = lanes; csi->input_format = format; diff --git a/drivers/staging/media/atomisp/platform/intel-mid/intel_mid_pcihelpers.c b/drivers/staging/media/atomisp/platform/intel-mid/intel_mid_pcihelpers.c deleted file mode 100644 index 4631b1d39bb4..000000000000 --- a/drivers/staging/media/atomisp/platform/intel-mid/intel_mid_pcihelpers.c +++ /dev/null @@ -1,298 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/export.h> -#include <linux/pci.h> -#include <linux/pm_qos.h> -#include <linux/delay.h> - -/* G-Min addition: "platform_is()" lives in intel_mid_pm.h in the MCG - * tree, but it's just platform ID info and we don't want to pull in - * the whole SFI-based PM architecture. - */ -#define INTEL_ATOM_MRST 0x26 -#define INTEL_ATOM_MFLD 0x27 -#define INTEL_ATOM_CLV 0x35 -#define INTEL_ATOM_MRFLD 0x4a -#define INTEL_ATOM_BYT 0x37 -#define INTEL_ATOM_MOORFLD 0x5a -#define INTEL_ATOM_CHT 0x4c -/* synchronization for sharing the I2C controller */ -#define PUNIT_PORT 0x04 -#define PUNIT_DOORBELL_OPCODE (0xE0) -#define PUNIT_DOORBELL_REG (0x0) -#ifndef CSTATE_EXIT_LATENCY -#define CSTATE_EXIT_LATENCY_C1 1 -#endif -static inline int platform_is(u8 model) -{ - return (boot_cpu_data.x86_model == model); -} - -#include "../../include/asm/intel_mid_pcihelpers.h" - -/* Unified message bus read/write operation */ -static DEFINE_SPINLOCK(msgbus_lock); - -static struct pci_dev *pci_root; -static struct pm_qos_request pm_qos; - -#define DW_I2C_NEED_QOS (platform_is(INTEL_ATOM_BYT)) - -static int intel_mid_msgbus_init(void) -{ - pci_root = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); - if (!pci_root) { - pr_err("%s: Error: msgbus PCI handle NULL\n", __func__); - return -ENODEV; - } - - if (DW_I2C_NEED_QOS) { - pm_qos_add_request(&pm_qos, - PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); - } - return 0; -} -fs_initcall(intel_mid_msgbus_init); - -u32 intel_mid_msgbus_read32_raw(u32 cmd) -{ - unsigned long irq_flags; - u32 data; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); - - return data; -} -EXPORT_SYMBOL(intel_mid_msgbus_read32_raw); - -/* - * GU: this function is only used by the VISA and 'VXD' drivers. - */ -u32 intel_mid_msgbus_read32_raw_ext(u32 cmd, u32 cmd_ext) -{ - unsigned long irq_flags; - u32 data; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, cmd_ext); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); - - return data; -} -EXPORT_SYMBOL(intel_mid_msgbus_read32_raw_ext); - -void intel_mid_msgbus_write32_raw(u32 cmd, u32 data) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); -} -EXPORT_SYMBOL(intel_mid_msgbus_write32_raw); - -/* - * GU: this function is only used by the VISA and 'VXD' drivers. - */ -void intel_mid_msgbus_write32_raw_ext(u32 cmd, u32 cmd_ext, u32 data) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, cmd_ext); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); -} -EXPORT_SYMBOL(intel_mid_msgbus_write32_raw_ext); - -u32 intel_mid_msgbus_read32(u8 port, u32 addr) -{ - unsigned long irq_flags; - u32 data; - u32 cmd; - u32 cmdext; - - cmd = (PCI_ROOT_MSGBUS_READ << 24) | (port << 16) | - ((addr & 0xff) << 8) | PCI_ROOT_MSGBUS_DWORD_ENABLE; - cmdext = addr & 0xffffff00; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - - if (cmdext) { - /* This resets to 0 automatically, no need to write 0 */ - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, - cmdext); - } - - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); - - return data; -} -EXPORT_SYMBOL(intel_mid_msgbus_read32); - -void intel_mid_msgbus_write32(u8 port, u32 addr, u32 data) -{ - unsigned long irq_flags; - u32 cmd; - u32 cmdext; - - cmd = (PCI_ROOT_MSGBUS_WRITE << 24) | (port << 16) | - ((addr & 0xFF) << 8) | PCI_ROOT_MSGBUS_DWORD_ENABLE; - cmdext = addr & 0xffffff00; - - spin_lock_irqsave(&msgbus_lock, irq_flags); - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data); - - if (cmdext) { - /* This resets to 0 automatically, no need to write 0 */ - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, - cmdext); - } - - pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd); - spin_unlock_irqrestore(&msgbus_lock, irq_flags); -} -EXPORT_SYMBOL(intel_mid_msgbus_write32); - -/* called only from where is later then fs_initcall */ -u32 intel_mid_soc_stepping(void) -{ - return pci_root->revision; -} -EXPORT_SYMBOL(intel_mid_soc_stepping); - -static bool is_south_complex_device(struct pci_dev *dev) -{ - unsigned int base_class = dev->class >> 16; - unsigned int sub_class = (dev->class & SUB_CLASS_MASK) >> 8; - - /* other than camera, pci bridges and display, - * everything else are south complex devices. - */ - if (((base_class == PCI_BASE_CLASS_MULTIMEDIA) && - (sub_class == ISP_SUB_CLASS)) || - (base_class == PCI_BASE_CLASS_BRIDGE) || - ((base_class == PCI_BASE_CLASS_DISPLAY) && !sub_class)) - return false; - else - return true; -} - -/* In BYT platform, d3_delay for internal south complex devices, - * they are not subject to 10 ms d3 to d0 delay required by pci spec. - */ -static void pci_d3_delay_fixup(struct pci_dev *dev) -{ - if (platform_is(INTEL_ATOM_BYT) || - platform_is(INTEL_ATOM_CHT)) { - /* All internal devices are in bus 0. */ - if (dev->bus->number == 0 && is_south_complex_device(dev)) { - dev->d3_delay = INTERNAL_PCI_PM_D3_WAIT; - dev->d3cold_delay = INTERNAL_PCI_PM_D3_WAIT; - } - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3_delay_fixup); - -#define PUNIT_SEMAPHORE (platform_is(INTEL_ATOM_BYT) ? 0x7 : 0x10E) -#define GET_SEM() (intel_mid_msgbus_read32(PUNIT_PORT, PUNIT_SEMAPHORE) & 0x1) - -static void reset_semaphore(void) -{ - u32 data; - - data = intel_mid_msgbus_read32(PUNIT_PORT, PUNIT_SEMAPHORE); - smp_mb(); - data = data & 0xfffffffc; - intel_mid_msgbus_write32(PUNIT_PORT, PUNIT_SEMAPHORE, data); - smp_mb(); - -} - -int intel_mid_dw_i2c_acquire_ownership(void) -{ - u32 ret = 0; - u32 data = 0; /* data sent to PUNIT */ - u32 cmd; - u32 cmdext; - int timeout = 1000; - - if (DW_I2C_NEED_QOS) - pm_qos_update_request(&pm_qos, CSTATE_EXIT_LATENCY_C1 - 1); - - /* - * We need disable irq. Otherwise, the main thread - * might be preempted and the other thread jumps to - * disable irq for a long time. Another case is - * some irq handlers might trigger power voltage change - */ - BUG_ON(irqs_disabled()); - local_irq_disable(); - - /* host driver writes 0x2 to side band register 0x7 */ - intel_mid_msgbus_write32(PUNIT_PORT, PUNIT_SEMAPHORE, 0x2); - smp_mb(); - - /* host driver sends 0xE0 opcode to PUNIT and writes 0 register */ - cmd = (PUNIT_DOORBELL_OPCODE << 24) | (PUNIT_PORT << 16) | - ((PUNIT_DOORBELL_REG & 0xFF) << 8) | PCI_ROOT_MSGBUS_DWORD_ENABLE; - cmdext = PUNIT_DOORBELL_REG & 0xffffff00; - - if (cmdext) - intel_mid_msgbus_write32_raw_ext(cmd, cmdext, data); - else - intel_mid_msgbus_write32_raw(cmd, data); - - /* host driver waits for bit 0 to be set in side band 0x7 */ - while (GET_SEM() != 0x1) { - udelay(100); - timeout--; - if (timeout <= 0) { - pr_err("Timeout: semaphore timed out, reset sem\n"); - ret = -ETIMEDOUT; - reset_semaphore(); - /*Delay 1ms in case race with punit*/ - udelay(1000); - if (GET_SEM() != 0) { - /*Reset again as kernel might race with punit*/ - reset_semaphore(); - } - pr_err("PUNIT SEM: %d\n", - intel_mid_msgbus_read32(PUNIT_PORT, - PUNIT_SEMAPHORE)); - local_irq_enable(); - - if (DW_I2C_NEED_QOS) { - pm_qos_update_request(&pm_qos, - PM_QOS_DEFAULT_VALUE); - } - - return ret; - } - } - smp_mb(); - - return ret; -} -EXPORT_SYMBOL(intel_mid_dw_i2c_acquire_ownership); - -int intel_mid_dw_i2c_release_ownership(void) -{ - reset_semaphore(); - local_irq_enable(); - - if (DW_I2C_NEED_QOS) - pm_qos_update_request(&pm_qos, PM_QOS_DEFAULT_VALUE); - - return 0; -} -EXPORT_SYMBOL(intel_mid_dw_i2c_release_ownership); diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index c2bb5ef2acb4..9e41987f9884 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -320,9 +320,10 @@ static int prp_link_validate(struct v4l2_subdev *sd, * the ->PRPENC link cannot be enabled if the source * is the VDIC */ - if (priv->sink_sd_prpenc) + if (priv->sink_sd_prpenc) { ret = -EINVAL; - goto out; + goto out; + } } else { /* the source is a CSI */ if (!csi) { diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c index b55e5ebba8b4..47c4c954fed5 100644 --- a/drivers/staging/media/imx/imx-media-dev.c +++ b/drivers/staging/media/imx/imx-media-dev.c @@ -440,6 +440,11 @@ unlock: return media_device_register(&imxmd->md); } +static const struct v4l2_async_notifier_operations imx_media_subdev_ops = { + .bound = imx_media_subdev_bound, + .complete = imx_media_probe_complete, +}; + /* * adds controls to a video device from an entity subdevice. * Continues upstream from the entity's sink pads. @@ -608,8 +613,7 @@ static int imx_media_probe(struct platform_device *pdev) /* prepare the async subdev notifier and register it */ imxmd->subdev_notifier.subdevs = imxmd->async_ptrs; - imxmd->subdev_notifier.bound = imx_media_subdev_bound; - imxmd->subdev_notifier.complete = imx_media_probe_complete; + imxmd->subdev_notifier.ops = &imx_media_subdev_ops; ret = v4l2_async_notifier_register(&imxmd->v4l2_dev, &imxmd->subdev_notifier); if (ret) { diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c index 71af13bd0ebd..6bd0717bf76e 100644 --- a/drivers/staging/media/lirc/lirc_zilog.c +++ b/drivers/staging/media/lirc/lirc_zilog.c @@ -99,13 +99,14 @@ struct IR { struct kref ref; struct list_head list; - /* FIXME spinlock access to l.features */ - struct lirc_driver l; + /* FIXME spinlock access to l->features */ + struct lirc_dev *l; struct lirc_buffer rbuf; struct mutex ir_lock; atomic_t open_count; + struct device *dev; struct i2c_adapter *adapter; spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */ @@ -183,10 +184,8 @@ static void release_ir_device(struct kref *ref) * ir->open_count == 0 - happens on final close() * ir_lock, tx_ref_lock, rx_ref_lock, all released */ - if (ir->l.minor >= 0) { - lirc_unregister_driver(ir->l.minor); - ir->l.minor = -1; - } + if (ir->l) + lirc_unregister_device(ir->l); if (kfifo_initialized(&ir->rbuf.fifo)) lirc_buffer_free(&ir->rbuf); @@ -243,7 +242,7 @@ static void release_ir_rx(struct kref *ref) * and releasing the ir reference can cause a sleep. That work is * performed by put_ir_rx() */ - ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; + ir->l->features &= ~LIRC_CAN_REC_LIRCCODE; /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */ ir->rx = NULL; /* Don't do the kfree(rx) here; we still need to kill the poll thread */ @@ -288,7 +287,7 @@ static void release_ir_tx(struct kref *ref) struct IR_tx *tx = container_of(ref, struct IR_tx, ref); struct IR *ir = tx->ir; - ir->l.features &= ~LIRC_CAN_SEND_LIRCCODE; + ir->l->features &= ~LIRC_CAN_SEND_LIRCCODE; /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */ ir->tx = NULL; kfree(tx); @@ -317,12 +316,12 @@ static int add_to_buf(struct IR *ir) int ret; int failures = 0; unsigned char sendbuf[1] = { 0 }; - struct lirc_buffer *rbuf = ir->l.rbuf; + struct lirc_buffer *rbuf = ir->l->buf; struct IR_rx *rx; struct IR_tx *tx; if (lirc_buffer_full(rbuf)) { - dev_dbg(ir->l.dev, "buffer overflow\n"); + dev_dbg(ir->dev, "buffer overflow\n"); return -EOVERFLOW; } @@ -368,17 +367,17 @@ static int add_to_buf(struct IR *ir) */ ret = i2c_master_send(rx->c, sendbuf, 1); if (ret != 1) { - dev_err(ir->l.dev, "i2c_master_send failed with %d\n", + dev_err(ir->dev, "i2c_master_send failed with %d\n", ret); if (failures >= 3) { mutex_unlock(&ir->ir_lock); - dev_err(ir->l.dev, + dev_err(ir->dev, "unable to read from the IR chip after 3 resets, giving up\n"); break; } /* Looks like the chip crashed, reset it */ - dev_err(ir->l.dev, + dev_err(ir->dev, "polling the IR receiver chip failed, trying reset\n"); set_current_state(TASK_UNINTERRUPTIBLE); @@ -405,14 +404,14 @@ static int add_to_buf(struct IR *ir) ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); mutex_unlock(&ir->ir_lock); if (ret != sizeof(keybuf)) { - dev_err(ir->l.dev, + dev_err(ir->dev, "i2c_master_recv failed with %d -- keeping last read buffer\n", ret); } else { rx->b[0] = keybuf[3]; rx->b[1] = keybuf[4]; rx->b[2] = keybuf[5]; - dev_dbg(ir->l.dev, + dev_dbg(ir->dev, "key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]); } @@ -463,9 +462,9 @@ static int add_to_buf(struct IR *ir) static int lirc_thread(void *arg) { struct IR *ir = arg; - struct lirc_buffer *rbuf = ir->l.rbuf; + struct lirc_buffer *rbuf = ir->l->buf; - dev_dbg(ir->l.dev, "poll thread started\n"); + dev_dbg(ir->dev, "poll thread started\n"); while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); @@ -493,7 +492,7 @@ static int lirc_thread(void *arg) wake_up_interruptible(&rbuf->wait_poll); } - dev_dbg(ir->l.dev, "poll thread ended\n"); + dev_dbg(ir->dev, "poll thread ended\n"); return 0; } @@ -646,10 +645,10 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block) buf[0] = (unsigned char)(i + 1); for (j = 0; j < tosend; ++j) buf[1 + j] = data_block[i + j]; - dev_dbg(tx->ir->l.dev, "%*ph", 5, buf); + dev_dbg(tx->ir->dev, "%*ph", 5, buf); ret = i2c_master_send(tx->c, buf, tosend + 1); if (ret != tosend + 1) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -674,7 +673,7 @@ static int send_boot_data(struct IR_tx *tx) buf[1] = 0x20; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -691,22 +690,22 @@ static int send_boot_data(struct IR_tx *tx) } if (ret != 1) { - dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Here comes the firmware version... (hopefully) */ ret = i2c_master_recv(tx->c, buf, 4); if (ret != 4) { - dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret); return 0; } if ((buf[0] != 0x80) && (buf[0] != 0xa0)) { - dev_err(tx->ir->l.dev, "unexpected IR TX init response: %02x\n", + dev_err(tx->ir->dev, "unexpected IR TX init response: %02x\n", buf[0]); return 0; } - dev_notice(tx->ir->l.dev, + dev_notice(tx->ir->dev, "Zilog/Hauppauge IR blaster firmware version %d.%d.%d loaded\n", buf[1], buf[2], buf[3]); @@ -751,15 +750,15 @@ static int fw_load(struct IR_tx *tx) } /* Request codeset data file */ - ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev); + ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->dev); if (ret != 0) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "firmware haup-ir-blaster.bin not available (%d)\n", ret); ret = ret < 0 ? ret : -EFAULT; goto out; } - dev_dbg(tx->ir->l.dev, "firmware of size %zu loaded\n", fw_entry->size); + dev_dbg(tx->ir->dev, "firmware of size %zu loaded\n", fw_entry->size); /* Parse the file */ tx_data = vmalloc(sizeof(*tx_data)); @@ -787,7 +786,7 @@ static int fw_load(struct IR_tx *tx) if (!read_uint8(&data, tx_data->endp, &version)) goto corrupt; if (version != 1) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "unsupported code set file version (%u, expected 1) -- please upgrade to a newer driver\n", version); fw_unload_locked(); @@ -804,7 +803,7 @@ static int fw_load(struct IR_tx *tx) &tx_data->num_code_sets)) goto corrupt; - dev_dbg(tx->ir->l.dev, "%u IR blaster codesets loaded\n", + dev_dbg(tx->ir->dev, "%u IR blaster codesets loaded\n", tx_data->num_code_sets); tx_data->code_sets = vmalloc( @@ -869,7 +868,7 @@ static int fw_load(struct IR_tx *tx) goto out; corrupt: - dev_err(tx->ir->l.dev, "firmware is corrupt\n"); + dev_err(tx->ir->dev, "firmware is corrupt\n"); fw_unload_locked(); ret = -EFAULT; @@ -882,16 +881,16 @@ out: static ssize_t read(struct file *filep, char __user *outbuf, size_t n, loff_t *ppos) { - struct IR *ir = filep->private_data; + struct IR *ir = lirc_get_pdata(filep); struct IR_rx *rx; - struct lirc_buffer *rbuf = ir->l.rbuf; + struct lirc_buffer *rbuf = ir->l->buf; int ret = 0, written = 0, retries = 0; unsigned int m; DECLARE_WAITQUEUE(wait, current); - dev_dbg(ir->l.dev, "read called\n"); + dev_dbg(ir->dev, "read called\n"); if (n % rbuf->chunk_size) { - dev_dbg(ir->l.dev, "read result = -EINVAL\n"); + dev_dbg(ir->dev, "read result = -EINVAL\n"); return -EINVAL; } @@ -935,7 +934,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, unsigned char buf[MAX_XFER_SIZE]; if (rbuf->chunk_size > sizeof(buf)) { - dev_err(ir->l.dev, + dev_err(ir->dev, "chunk_size is too big (%d)!\n", rbuf->chunk_size); ret = -EINVAL; @@ -950,7 +949,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, retries++; } if (retries >= 5) { - dev_err(ir->l.dev, "Buffer read failed!\n"); + dev_err(ir->dev, "Buffer read failed!\n"); ret = -EIO; } } @@ -960,7 +959,7 @@ static ssize_t read(struct file *filep, char __user *outbuf, size_t n, put_ir_rx(rx, false); set_current_state(TASK_RUNNING); - dev_dbg(ir->l.dev, "read result = %d (%s)\n", ret, + dev_dbg(ir->dev, "read result = %d (%s)\n", ret, ret ? "Error" : "OK"); return ret ? ret : written; @@ -977,7 +976,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = get_key_data(data_block, code, key); if (ret == -EPROTO) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "failed to get data for code %u, key %u -- check lircd.conf entries\n", code, key); return ret; @@ -995,7 +994,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x40; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1008,18 +1007,18 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) } if (ret != 1) { - dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Send finished download? */ ret = i2c_master_recv(tx->c, buf, 1); if (ret != 1) { - dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } if (buf[0] != 0xA0) { - dev_err(tx->ir->l.dev, "unexpected IR TX response #1: %02x\n", + dev_err(tx->ir->dev, "unexpected IR TX response #1: %02x\n", buf[0]); return -EFAULT; } @@ -1029,7 +1028,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) buf[1] = 0x80; ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { - dev_err(tx->ir->l.dev, "i2c_master_send failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } @@ -1039,7 +1038,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) * going to skip this whole mess and say we're done on the HD PVR */ if (!tx->post_tx_ready_poll) { - dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1055,12 +1054,12 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) ret = i2c_master_send(tx->c, buf, 1); if (ret == 1) break; - dev_dbg(tx->ir->l.dev, + dev_dbg(tx->ir->dev, "NAK expected: i2c_master_send failed with %d (try %d)\n", ret, i + 1); } if (ret != 1) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "IR TX chip never got ready: last i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; @@ -1069,17 +1068,17 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) /* Seems to be an 'ok' response */ i = i2c_master_recv(tx->c, buf, 1); if (i != 1) { - dev_err(tx->ir->l.dev, "i2c_master_recv failed with %d\n", ret); + dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret); return -EFAULT; } if (buf[0] != 0x80) { - dev_err(tx->ir->l.dev, "unexpected IR TX response #2: %02x\n", + dev_err(tx->ir->dev, "unexpected IR TX response #2: %02x\n", buf[0]); return -EFAULT; } /* Oh good, it worked */ - dev_dbg(tx->ir->l.dev, "sent code %u, key %u\n", code, key); + dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key); return 0; } @@ -1092,7 +1091,7 @@ static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) static ssize_t write(struct file *filep, const char __user *buf, size_t n, loff_t *ppos) { - struct IR *ir = filep->private_data; + struct IR *ir = lirc_get_pdata(filep); struct IR_tx *tx; size_t i; int failures = 0; @@ -1165,11 +1164,11 @@ static ssize_t write(struct file *filep, const char __user *buf, size_t n, */ if (ret != 0) { /* Looks like the chip crashed, reset it */ - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "sending to the IR transmitter chip failed, trying reset\n"); if (failures >= 3) { - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "unable to send to the IR chip after 3 resets, giving up\n"); mutex_unlock(&ir->ir_lock); mutex_unlock(&tx->client_lock); @@ -1200,12 +1199,12 @@ static ssize_t write(struct file *filep, const char __user *buf, size_t n, /* copied from lirc_dev */ static unsigned int poll(struct file *filep, poll_table *wait) { - struct IR *ir = filep->private_data; + struct IR *ir = lirc_get_pdata(filep); struct IR_rx *rx; - struct lirc_buffer *rbuf = ir->l.rbuf; + struct lirc_buffer *rbuf = ir->l->buf; unsigned int ret; - dev_dbg(ir->l.dev, "%s called\n", __func__); + dev_dbg(ir->dev, "%s called\n", __func__); rx = get_ir_rx(ir); if (!rx) { @@ -1213,7 +1212,7 @@ static unsigned int poll(struct file *filep, poll_table *wait) * Revisit this, if our poll function ever reports writeable * status for Tx */ - dev_dbg(ir->l.dev, "%s result = POLLERR\n", __func__); + dev_dbg(ir->dev, "%s result = POLLERR\n", __func__); return POLLERR; } @@ -1226,19 +1225,19 @@ static unsigned int poll(struct file *filep, poll_table *wait) /* Indicate what ops could happen immediately without blocking */ ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN | POLLRDNORM); - dev_dbg(ir->l.dev, "%s result = %s\n", __func__, + dev_dbg(ir->dev, "%s result = %s\n", __func__, ret ? "POLLIN|POLLRDNORM" : "none"); return ret; } static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) { - struct IR *ir = filep->private_data; + struct IR *ir = lirc_get_pdata(filep); unsigned long __user *uptr = (unsigned long __user *)arg; int result; unsigned long mode, features; - features = ir->l.features; + features = ir->l->features; switch (cmd) { case LIRC_GET_LENGTH: @@ -1283,46 +1282,18 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return result; } -static struct IR *get_ir_device_by_minor(unsigned int minor) -{ - struct IR *ir; - struct IR *ret = NULL; - - mutex_lock(&ir_devices_lock); - - if (!list_empty(&ir_devices_list)) { - list_for_each_entry(ir, &ir_devices_list, list) { - if (ir->l.minor == minor) { - ret = get_ir_device(ir, true); - break; - } - } - } - - mutex_unlock(&ir_devices_lock); - return ret; -} - /* - * Open the IR device. Get hold of our IR structure and - * stash it in private_data for the file + * Open the IR device. */ static int open(struct inode *node, struct file *filep) { struct IR *ir; - unsigned int minor = MINOR(node->i_rdev); - /* find our IR struct */ - ir = get_ir_device_by_minor(minor); - - if (!ir) - return -ENODEV; + lirc_init_pdata(node, filep); + ir = lirc_get_pdata(filep); atomic_inc(&ir->open_count); - /* stash our IR struct */ - filep->private_data = ir; - nonseekable_open(node, filep); return 0; } @@ -1330,14 +1301,7 @@ static int open(struct inode *node, struct file *filep) /* Close the IR device */ static int close(struct inode *node, struct file *filep) { - /* find our IR struct */ - struct IR *ir = filep->private_data; - - if (!ir) { - pr_err("ir: %s: no private_data attached to the file!\n", - __func__); - return -ENODEV; - } + struct IR *ir = lirc_get_pdata(filep); atomic_dec(&ir->open_count); @@ -1383,16 +1347,6 @@ static const struct file_operations lirc_fops = { .release = close }; -static struct lirc_driver lirc_template = { - .name = "lirc_zilog", - .minor = -1, - .code_length = 13, - .buffer_size = BUFLEN / 2, - .chunk_size = 2, - .fops = &lirc_fops, - .owner = THIS_MODULE, -}; - static int ir_remove(struct i2c_client *client) { if (strncmp("ir_tx_z8", client->name, 8) == 0) { @@ -1476,27 +1430,42 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) list_add_tail(&ir->list, &ir_devices_list); ir->adapter = adap; + ir->dev = &adap->dev; mutex_init(&ir->ir_lock); atomic_set(&ir->open_count, 0); spin_lock_init(&ir->tx_ref_lock); spin_lock_init(&ir->rx_ref_lock); /* set lirc_dev stuff */ - memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); + ir->l = lirc_allocate_device(); + if (!ir->l) { + ret = -ENOMEM; + goto out_put_ir; + } + + snprintf(ir->l->name, sizeof(ir->l->name), "lirc_zilog"); + ir->l->code_length = 13; + ir->l->fops = &lirc_fops; + ir->l->owner = THIS_MODULE; + ir->l->dev.parent = &adap->dev; + /* * FIXME this is a pointer reference to us, but no refcount. * * This OK for now, since lirc_dev currently won't touch this * buffer as we provide our own lirc_fops. * - * Currently our own lirc_fops rely on this ir->l.rbuf pointer + * Currently our own lirc_fops rely on this ir->l->buf pointer */ - ir->l.rbuf = &ir->rbuf; - ir->l.dev = &adap->dev; - ret = lirc_buffer_init(ir->l.rbuf, - ir->l.chunk_size, ir->l.buffer_size); - if (ret) + ir->l->buf = &ir->rbuf; + /* This will be returned by lirc_get_pdata() */ + ir->l->data = ir; + ret = lirc_buffer_init(ir->l->buf, 2, BUFLEN / 2); + if (ret) { + lirc_free_device(ir->l); + ir->l = NULL; goto out_put_ir; + } } if (tx_probe) { @@ -1512,7 +1481,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) kref_init(&tx->ref); ir->tx = tx; - ir->l.features |= LIRC_CAN_SEND_LIRCCODE; + ir->l->features |= LIRC_CAN_SEND_LIRCCODE; mutex_init(&tx->client_lock); tx->c = client; tx->need_boot = 1; @@ -1538,7 +1507,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Proceed only if the Rx client is also ready or not needed */ if (!rx && !tx_only) { - dev_info(tx->ir->l.dev, + dev_info(tx->ir->dev, "probe of IR Tx on %s (i2c-%d) done. Waiting on IR Rx.\n", adap->name, adap->nr); goto out_ok; @@ -1556,7 +1525,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) kref_init(&rx->ref); ir->rx = rx; - ir->l.features |= LIRC_CAN_REC_LIRCCODE; + ir->l->features |= LIRC_CAN_REC_LIRCCODE; mutex_init(&rx->client_lock); rx->c = client; rx->hdpvr_data_fmt = @@ -1578,7 +1547,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) "zilog-rx-i2c-%d", adap->nr); if (IS_ERR(rx->task)) { ret = PTR_ERR(rx->task); - dev_err(tx->ir->l.dev, + dev_err(tx->ir->dev, "%s: could not start IR Rx polling thread\n", __func__); /* Failed kthread, so put back the ir ref */ @@ -1586,7 +1555,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Failure exit, so put back rx ref from i2c_client */ i2c_set_clientdata(client, NULL); put_ir_rx(rx, true); - ir->l.features &= ~LIRC_CAN_REC_LIRCCODE; + ir->l->features &= ~LIRC_CAN_REC_LIRCCODE; goto out_put_tx; } @@ -1599,17 +1568,19 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) } /* register with lirc */ - ir->l.minor = lirc_register_driver(&ir->l); - if (ir->l.minor < 0) { - dev_err(tx->ir->l.dev, - "%s: lirc_register_driver() failed: %i\n", - __func__, ir->l.minor); - ret = -EBADRQC; + ret = lirc_register_device(ir->l); + if (ret < 0) { + dev_err(tx->ir->dev, + "%s: lirc_register_device() failed: %i\n", + __func__, ret); + lirc_free_device(ir->l); + ir->l = NULL; goto out_put_xx; } - dev_info(ir->l.dev, + + dev_info(ir->dev, "IR unit on %s (i2c-%d) registered as lirc%d and ready\n", - adap->name, adap->nr, ir->l.minor); + adap->name, adap->nr, ir->l->minor); out_ok: if (rx) @@ -1617,7 +1588,7 @@ out_ok: if (tx) put_ir_tx(tx, true); put_ir_device(ir, true); - dev_info(ir->l.dev, + dev_info(ir->dev, "probe of IR %s on %s (i2c-%d) done\n", tx_probe ? "Tx" : "Rx", adap->name, adap->nr); mutex_unlock(&ir_devices_lock); diff --git a/include/linux/platform_data/media/gpio-ir-recv.h b/include/linux/platform_data/media/gpio-ir-recv.h deleted file mode 100644 index 0c298f569d5a..000000000000 --- a/include/linux/platform_data/media/gpio-ir-recv.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2012, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __GPIO_IR_RECV_H__ -#define __GPIO_IR_RECV_H__ - -struct gpio_ir_recv_platform_data { - int gpio_nr; - bool active_low; - u64 allowed_protos; - const char *map_name; -}; - -#endif /* __GPIO_IR_RECV_H__ */ diff --git a/include/media/cec-pin.h b/include/media/cec-pin.h index f09cc9579d53..83b3e17e0a07 100644 --- a/include/media/cec-pin.h +++ b/include/media/cec-pin.h @@ -21,71 +21,8 @@ #define LINUX_CEC_PIN_H #include <linux/types.h> -#include <linux/atomic.h> #include <media/cec.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 -}; - /** * struct cec_pin_ops - low-level CEC pin operations * @read: read the CEC pin. Return true if high, false if low. @@ -97,6 +34,9 @@ enum cec_pin_state { * @free: optional. Free any allocated resources. Called when the * adapter is deleted. * @status: optional, log status information. + * @read_hpd: read the HPD pin. Return true if high, false if low or + * an error if negative. If NULL or -ENOTTY is returned, + * then this is not supported. * * These operations are used by the cec pin framework to manipulate * the CEC pin. @@ -109,50 +49,7 @@ struct cec_pin_ops { void (*disable_irq)(struct cec_adapter *adap); void (*free)(struct cec_adapter *adap); void (*status)(struct cec_adapter *adap, struct seq_file *file); -}; - -#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; + int (*read_hpd)(struct cec_adapter *adap); }; /** diff --git a/include/media/cec.h b/include/media/cec.h index df6b3bd31284..16341210d3ba 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -91,7 +91,7 @@ struct cec_event_entry { }; #define CEC_NUM_CORE_EVENTS 2 -#define CEC_NUM_EVENTS CEC_EVENT_PIN_CEC_HIGH +#define CEC_NUM_EVENTS CEC_EVENT_PIN_HPD_HIGH struct cec_fh { struct list_head list; @@ -297,6 +297,16 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, ktime_t ts); /** + * cec_queue_pin_hpd_event() - queue a pin event with a given timestamp. + * + * @adap: pointer to the cec adapter + * @is_high: when true the HPD pin is high, otherwise it is low + * @ts: the timestamp for this event + * + */ +void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts); + +/** * cec_get_edid_phys_addr() - find and return the physical address * * @edid: pointer to the EDID data @@ -417,6 +427,10 @@ static inline u16 cec_phys_addr_for_input(u16 phys_addr, u8 input) static inline int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port) { + if (parent) + *parent = phys_addr; + if (port) + *port = 0; return 0; } diff --git a/include/media/drv-intf/saa7146_vv.h b/include/media/drv-intf/saa7146_vv.h index 4e89e9f12a1e..6f80fb7f31a5 100644 --- a/include/media/drv-intf/saa7146_vv.h +++ b/include/media/drv-intf/saa7146_vv.h @@ -108,6 +108,7 @@ struct saa7146_vv struct saa7146_dmaqueue vbi_dmaq; struct v4l2_vbi_format vbi_fmt; struct timer_list vbi_read_timeout; + struct file *vbi_read_timeout_file; /* vbi workaround interrupt queue */ wait_queue_head_t vbi_wq; int vbi_fieldcount; @@ -184,7 +185,7 @@ int saa7146_unregister_device(struct video_device *vid, struct saa7146_dev *dev) void saa7146_buffer_finish(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, int state); void saa7146_buffer_next(struct saa7146_dev *dev, struct saa7146_dmaqueue *q,int vbi); int saa7146_buffer_queue(struct saa7146_dev *dev, struct saa7146_dmaqueue *q, struct saa7146_buf *buf); -void saa7146_buffer_timeout(unsigned long data); +void saa7146_buffer_timeout(struct timer_list *t); void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q, struct saa7146_buf *buf); @@ -203,14 +204,14 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data); /* from saa7146_video.c */ extern const struct v4l2_ioctl_ops saa7146_video_ioctl_ops; extern const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops; -extern struct saa7146_use_ops saa7146_video_uops; +extern const struct saa7146_use_ops saa7146_video_uops; int saa7146_start_preview(struct saa7146_fh *fh); int saa7146_stop_preview(struct saa7146_fh *fh); long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); int saa7146_s_ctrl(struct v4l2_ctrl *ctrl); /* from saa7146_vbi.c */ -extern struct saa7146_use_ops saa7146_vbi_uops; +extern const struct saa7146_use_ops saa7146_vbi_uops; /* resource management functions */ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit); diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index 86d15a9b6c01..857da67bd931 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h @@ -9,7 +9,6 @@ #ifndef _LINUX_LIRC_DEV_H #define _LINUX_LIRC_DEV_H -#define MAX_IRCTL_DEVICES 8 #define BUFLEN 16 #include <linux/slab.h> @@ -18,6 +17,8 @@ #include <linux/poll.h> #include <linux/kfifo.h> #include <media/lirc.h> +#include <linux/device.h> +#include <linux/cdev.h> struct lirc_buffer { wait_queue_head_t wait_poll; @@ -112,84 +113,69 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, } /** - * struct lirc_driver - Defines the parameters on a LIRC driver - * - * @name: this string will be used for logs - * - * @minor: indicates minor device (/dev/lirc) number for - * registered driver if caller fills it with negative - * value, then the first free minor number will be used - * (if available). - * - * @code_length: length of the remote control key code expressed in bits. - * - * @buffer_size: Number of FIFO buffers with @chunk_size size. If zero, - * creates a buffer with BUFLEN size (16 bytes). + * struct lirc_dev - represents a LIRC device * + * @name: used for logging + * @minor: the minor device (/dev/lircX) number for the device + * @code_length: length of a remote control key code expressed in bits * @features: lirc compatible hardware features, like LIRC_MODE_RAW, * LIRC_CAN\_\*, as defined at include/media/lirc.h. - * + * @buffer_size: Number of FIFO buffers with @chunk_size size. + * Only used if @rbuf is NULL. * @chunk_size: Size of each FIFO buffer. - * - * @data: it may point to any driver data and this pointer will - * be passed to all callback functions. - * - * @min_timeout: Minimum timeout for record. Valid only if - * LIRC_CAN_SET_REC_TIMEOUT is defined. - * - * @max_timeout: Maximum timeout for record. Valid only if - * LIRC_CAN_SET_REC_TIMEOUT is defined. - * - * @rbuf: if not NULL, it will be used as a read buffer, you will + * Only used if @rbuf is NULL. + * @data: private per-driver data + * @buf: if %NULL, lirc_dev will allocate and manage the buffer, + * otherwise allocated by the caller which will * have to write to the buffer by other means, like irq's * (see also lirc_serial.c). - * - * @rdev: Pointed to struct rc_dev associated with the LIRC - * device. - * - * @fops: file_operations for drivers which don't fit the current - * driver model. - * Some ioctl's can be directly handled by lirc_dev if the - * driver's ioctl function is NULL or if it returns - * -ENOIOCTLCMD (see also lirc_serial.c). - * - * @dev: pointer to the struct device associated with the LIRC - * device. - * + * @buf_internal: whether lirc_dev has allocated the read buffer or not + * @rdev: &struct rc_dev associated with the device + * @fops: &struct file_operations for the device * @owner: the module owning this struct + * @attached: if the device is still live + * @open: open count for the device's chardev + * @mutex: serialises file_operations calls + * @dev: &struct device assigned to the device + * @cdev: &struct cdev assigned to the device */ -struct lirc_driver { +struct lirc_dev { char name[40]; - int minor; + unsigned int minor; __u32 code_length; - unsigned int buffer_size; /* in chunks holding one code each */ __u32 features; + unsigned int buffer_size; /* in chunks holding one code each */ unsigned int chunk_size; + struct lirc_buffer *buf; + bool buf_internal; void *data; - int min_timeout; - int max_timeout; - struct lirc_buffer *rbuf; struct rc_dev *rdev; const struct file_operations *fops; - struct device *dev; struct module *owner; + + bool attached; + int open; + + struct mutex mutex; /* protect from simultaneous accesses */ + + struct device dev; + struct cdev cdev; }; -/* following functions can be called ONLY from user context - * - * returns negative value on error or minor number - * of the registered device if success - * contents of the structure pointed by p is copied - */ -extern int lirc_register_driver(struct lirc_driver *d); +struct lirc_dev *lirc_allocate_device(void); + +void lirc_free_device(struct lirc_dev *d); + +int lirc_register_device(struct lirc_dev *d); + +void lirc_unregister_device(struct lirc_dev *d); -/* returns negative value on error or 0 if success -*/ -extern int lirc_unregister_driver(int minor); +/* Must be called in the open fop before lirc_get_pdata() can be used */ +void lirc_init_pdata(struct inode *inode, struct file *file); -/* Returns the private data stored in the lirc_driver +/* Returns the private data stored in the lirc_dev * associated with the given device file pointer. */ void *lirc_get_pdata(struct file *file); diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 2a160e6e823c..72197cb43781 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -211,6 +211,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_ALINK_DTU_M "rc-alink-dtu-m" #define RC_MAP_ANYSEE "rc-anysee" #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" +#define RC_MAP_ASTROMETA_T2HYBRID "rc-astrometa-t2hybrid" #define RC_MAP_ASUS_PC39 "rc-asus-pc39" #define RC_MAP_ASUS_PS3_100 "rc-asus-ps3-100" #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" @@ -258,6 +259,8 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce" #define RC_MAP_GOTVIEW7135 "rc-gotview7135" #define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge" +#define RC_MAP_HISI_POPLAR "rc-hisi-poplar" +#define RC_MAP_HISI_TV_DEMO "rc-hisi-tv-demo" #define RC_MAP_IMON_MCE "rc-imon-mce" #define RC_MAP_IMON_PAD "rc-imon-pad" #define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" @@ -300,6 +303,7 @@ struct rc_map *rc_map_get(const char *name); #define RC_MAP_REDDO "rc-reddo" #define RC_MAP_SNAPSTREAM_FIREFLY "rc-snapstream-firefly" #define RC_MAP_STREAMZAP "rc-streamzap" +#define RC_MAP_TANGO "rc-tango" #define RC_MAP_TBS_NEC "rc-tbs-nec" #define RC_MAP_TECHNISAT_TS35 "rc-technisat-ts35" #define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2" diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index c69d8c8a66d0..6152434cbe82 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -50,6 +50,10 @@ enum v4l2_async_match_type { * @match: union of per-bus type matching data sets * @list: used to link struct v4l2_async_subdev objects, waiting to be * probed, to a notifier->waiting list + * + * When this struct is used as a member in a driver specific struct, + * the driver specific struct shall contain the &struct + * v4l2_async_subdev as its first member. */ struct v4l2_async_subdev { enum v4l2_async_match_type match_type; @@ -76,32 +80,47 @@ struct v4l2_async_subdev { }; /** + * struct v4l2_async_notifier_operations - Asynchronous V4L2 notifier operations + * @bound: a subdevice driver has successfully probed one of the subdevices + * @complete: All subdevices have been probed successfully. The complete + * callback is only executed for the root notifier. + * @unbind: a subdevice is leaving + */ +struct v4l2_async_notifier_operations { + int (*bound)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); + int (*complete)(struct v4l2_async_notifier *notifier); + void (*unbind)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); +}; + +/** * struct v4l2_async_notifier - v4l2_device notifier data * - * @num_subdevs: number of subdevices + * @ops: notifier operations + * @num_subdevs: number of subdevices used in the subdevs array + * @max_subdevs: number of subdevices allocated in the subdevs array * @subdevs: array of pointers to subdevice descriptors - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: v4l2_device of the root notifier, NULL otherwise + * @sd: sub-device that registered the notifier, NULL otherwise + * @parent: parent notifier * @waiting: list of struct v4l2_async_subdev, waiting for their drivers * @done: list of struct v4l2_subdev, already probed * @list: member in a global list of notifiers - * @bound: a subdevice driver has successfully probed one of subdevices - * @complete: all subdevices have been probed successfully - * @unbind: a subdevice is leaving */ struct v4l2_async_notifier { + const struct v4l2_async_notifier_operations *ops; unsigned int num_subdevs; + unsigned int max_subdevs; struct v4l2_async_subdev **subdevs; struct v4l2_device *v4l2_dev; + struct v4l2_subdev *sd; + struct v4l2_async_notifier *parent; struct list_head waiting; struct list_head done; struct list_head list; - int (*bound)(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd); - int (*complete)(struct v4l2_async_notifier *notifier); - void (*unbind)(struct v4l2_async_notifier *notifier, - struct v4l2_subdev *subdev, - struct v4l2_async_subdev *asd); }; /** @@ -114,6 +133,16 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, struct v4l2_async_notifier *notifier); /** + * v4l2_async_subdev_notifier_register - registers a subdevice asynchronous + * notifier for a sub-device + * + * @sd: pointer to &struct v4l2_subdev + * @notifier: pointer to &struct v4l2_async_notifier + */ +int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, + struct v4l2_async_notifier *notifier); + +/** * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier * * @notifier: pointer to &struct v4l2_async_notifier @@ -121,6 +150,22 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); /** + * v4l2_async_notifier_cleanup - clean up notifier resources + * @notifier: the notifier the resources of which are to be cleaned up + * + * Release memory resources related to a notifier, including the async + * sub-devices allocated for the purposes of the notifier but not the notifier + * itself. The user is responsible for calling this function to clean up the + * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or + * @v4l2_fwnode_reference_parse_sensor_common. + * + * There is no harm from calling v4l2_async_notifier_cleanup in other + * cases as long as its memory has been zeroed after it has been + * allocated. + */ +void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); + +/** * v4l2_async_register_subdev - registers a sub-device to the asynchronous * subdevice framework * @@ -129,6 +174,28 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); int v4l2_async_register_subdev(struct v4l2_subdev *sd); /** + * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to + * the asynchronous sub-device + * framework and parse set up common + * sensor related devices + * + * @sd: pointer to struct &v4l2_subdev + * + * This function is just like v4l2_async_register_subdev() with the exception + * that calling it will also parse firmware interfaces for remote references + * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the + * async sub-devices. The sub-device is similarly unregistered by calling + * v4l2_async_unregister_subdev(). + * + * While registered, the subdev module is marked as in-use. + * + * An error is returned if the module is no longer loaded on any attempts + * to register it. + */ +int __must_check v4l2_async_register_subdev_sensor_common( + struct v4l2_subdev *sd); + +/** * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous * subdevice framework * diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 7adec9851d9e..b5b465677d28 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -25,6 +25,8 @@ #include <media/v4l2-mediabus.h> struct fwnode_handle; +struct v4l2_async_notifier; +struct v4l2_async_subdev; #define V4L2_FWNODE_CSI2_MAX_DATA_LANES 4 @@ -113,13 +115,237 @@ struct v4l2_fwnode_link { unsigned int remote_port; }; +/** + * v4l2_fwnode_endpoint_parse() - parse all fwnode node properties + * @fwnode: pointer to the endpoint's fwnode handle + * @vep: pointer to the V4L2 fwnode data structure + * + * All properties are optional. If none are found, we don't set any flags. This + * means the port has a static configuration and no properties have to be + * specified explicitly. If any properties that identify the bus as parallel + * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if + * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we + * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a + * reference to @fwnode. + * + * NOTE: This function does not parse properties the size of which is variable + * without a low fixed limit. Please use v4l2_fwnode_endpoint_alloc_parse() in + * new drivers instead. + * + * Return: 0 on success or a negative error code on failure. + */ int v4l2_fwnode_endpoint_parse(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep); + +/** + * v4l2_fwnode_endpoint_free() - free the V4L2 fwnode acquired by + * v4l2_fwnode_endpoint_alloc_parse() + * @vep: the V4L2 fwnode the resources of which are to be released + * + * It is safe to call this function with NULL argument or on a V4L2 fwnode the + * parsing of which failed. + */ +void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); + +/** + * v4l2_fwnode_endpoint_alloc_parse() - parse all fwnode node properties + * @fwnode: pointer to the endpoint's fwnode handle + * + * All properties are optional. If none are found, we don't set any flags. This + * means the port has a static configuration and no properties have to be + * specified explicitly. If any properties that identify the bus as parallel + * are found and slave-mode isn't set, we set V4L2_MBUS_MASTER. Similarly, if + * we recognise the bus as serial CSI-2 and clock-noncontinuous isn't set, we + * set the V4L2_MBUS_CSI2_CONTINUOUS_CLOCK flag. The caller should hold a + * reference to @fwnode. + * + * v4l2_fwnode_endpoint_alloc_parse() has two important differences to + * v4l2_fwnode_endpoint_parse(): + * + * 1. It also parses variable size data. + * + * 2. The memory it has allocated to store the variable size data must be freed + * using v4l2_fwnode_endpoint_free() when no longer needed. + * + * Return: Pointer to v4l2_fwnode_endpoint if successful, on an error pointer + * on error. + */ struct v4l2_fwnode_endpoint *v4l2_fwnode_endpoint_alloc_parse( struct fwnode_handle *fwnode); -void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); + +/** + * v4l2_fwnode_parse_link() - parse a link between two endpoints + * @fwnode: pointer to the endpoint's fwnode at the local end of the link + * @link: pointer to the V4L2 fwnode link data structure + * + * Fill the link structure with the local and remote nodes and port numbers. + * The local_node and remote_node fields are set to point to the local and + * remote port's parent nodes respectively (the port parent node being the + * parent node of the port node if that node isn't a 'ports' node, or the + * grand-parent node of the port node otherwise). + * + * A reference is taken to both the local and remote nodes, the caller must use + * v4l2_fwnode_put_link() to drop the references when done with the + * link. + * + * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be + * found. + */ int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode, struct v4l2_fwnode_link *link); + +/** + * v4l2_fwnode_put_link() - drop references to nodes in a link + * @link: pointer to the V4L2 fwnode link data structure + * + * Drop references to the local and remote nodes in the link. This function + * must be called on every link parsed with v4l2_fwnode_parse_link(). + */ void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link); + +/** + * typedef parse_endpoint_func - Driver's callback function to be called on + * each V4L2 fwnode endpoint. + * + * @dev: pointer to &struct device + * @vep: pointer to &struct v4l2_fwnode_endpoint + * @asd: pointer to &struct v4l2_async_subdev + * + * Return: + * * %0 on success + * * %-ENOTCONN if the endpoint is to be skipped but this + * should not be considered as an error + * * %-EINVAL if the endpoint configuration is invalid + */ +typedef int (*parse_endpoint_func)(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct v4l2_async_subdev *asd); + + +/** + * v4l2_async_notifier_parse_fwnode_endpoints - Parse V4L2 fwnode endpoints in a + * device node + * @dev: the device the endpoints of which are to be parsed + * @notifier: notifier for @dev + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode + * endpoint. Optional. + * + * Parse the fwnode endpoints of the @dev device and populate the async sub- + * devices array of the notifier. The @parse_endpoint callback function is + * called for each endpoint with the corresponding async sub-device pointer to + * let the caller initialize the driver-specific part of the async sub-device + * structure. + * + * The notifier memory shall be zeroed before this function is called on the + * notifier. + * + * This function may not be called on a registered notifier and may be called on + * a notifier only once. + * + * Do not change the notifier's subdevs array, take references to the subdevs + * array itself or change the notifier's num_subdevs field. This is because this + * function allocates and reallocates the subdevs array based on parsing + * endpoints. + * + * The &struct v4l2_fwnode_endpoint passed to the callback function + * @parse_endpoint is released once the function is finished. If there is a need + * to retain that configuration, the user needs to allocate memory for it. + * + * Any notifier populated using this function must be released with a call to + * v4l2_async_notifier_cleanup() after it has been unregistered and the async + * sub-devices are no longer in use, even if the function returned an error. + * + * Return: %0 on success, including when no async sub-devices are found + * %-ENOMEM if memory allocation failed + * %-EINVAL if graph or endpoint parsing failed + * Other error codes as returned by @parse_endpoint + */ +int v4l2_async_notifier_parse_fwnode_endpoints( + struct device *dev, struct v4l2_async_notifier *notifier, + size_t asd_struct_size, + parse_endpoint_func parse_endpoint); + +/** + * v4l2_async_notifier_parse_fwnode_endpoints_by_port - Parse V4L2 fwnode + * endpoints of a port in a + * device node + * @dev: the device the endpoints of which are to be parsed + * @notifier: notifier for @dev + * @asd_struct_size: size of the driver's async sub-device struct, including + * sizeof(struct v4l2_async_subdev). The &struct + * v4l2_async_subdev shall be the first member of + * the driver's async sub-device struct, i.e. both + * begin at the same memory address. + * @port: port number where endpoints are to be parsed + * @parse_endpoint: Driver's callback function called on each V4L2 fwnode + * endpoint. Optional. + * + * This function is just like v4l2_async_notifier_parse_fwnode_endpoints() with + * the exception that it only parses endpoints in a given port. This is useful + * on devices that have both sinks and sources: the async sub-devices connected + * to sources have already been configured by another driver (on capture + * devices). In this case the driver must know which ports to parse. + * + * Parse the fwnode endpoints of the @dev device on a given @port and populate + * the async sub-devices array of the notifier. The @parse_endpoint callback + * function is called for each endpoint with the corresponding async sub-device + * pointer to let the caller initialize the driver-specific part of the async + * sub-device structure. + * + * The notifier memory shall be zeroed before this function is called on the + * notifier the first time. + * + * This function may not be called on a registered notifier and may be called on + * a notifier only once per port. + * + * Do not change the notifier's subdevs array, take references to the subdevs + * array itself or change the notifier's num_subdevs field. This is because this + * function allocates and reallocates the subdevs array based on parsing + * endpoints. + * + * The &struct v4l2_fwnode_endpoint passed to the callback function + * @parse_endpoint is released once the function is finished. If there is a need + * to retain that configuration, the user needs to allocate memory for it. + * + * Any notifier populated using this function must be released with a call to + * v4l2_async_notifier_cleanup() after it has been unregistered and the async + * sub-devices are no longer in use, even if the function returned an error. + * + * Return: %0 on success, including when no async sub-devices are found + * %-ENOMEM if memory allocation failed + * %-EINVAL if graph or endpoint parsing failed + * Other error codes as returned by @parse_endpoint + */ +int v4l2_async_notifier_parse_fwnode_endpoints_by_port( + struct device *dev, struct v4l2_async_notifier *notifier, + size_t asd_struct_size, unsigned int port, + parse_endpoint_func parse_endpoint); + +/** + * v4l2_fwnode_reference_parse_sensor_common - parse common references on + * sensors for async sub-devices + * @dev: the device node the properties of which are parsed for references + * @notifier: the async notifier where the async subdevs will be added + * + * Parse common sensor properties for remote devices related to the + * sensor and set up async sub-devices for them. + * + * Any notifier populated using this function must be released with a call to + * v4l2_async_notifier_release() after it has been unregistered and the async + * sub-devices are no longer in use, even in the case the function returned an + * error. + * + * Return: 0 on success + * -ENOMEM if memory allocation failed + * -EINVAL if property parsing failed + */ +int v4l2_async_notifier_parse_fwnode_sensor_common( + struct device *dev, struct v4l2_async_notifier *notifier); + #endif /* _V4L2_FWNODE_H */ diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index e83872078376..ec399c770301 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -793,6 +793,8 @@ struct v4l2_subdev_platform_data { * list. * @asd: Pointer to respective &struct v4l2_async_subdev. * @notifier: Pointer to the managing notifier. + * @subdev_notifier: A sub-device notifier implicitly registered for the sub- + * device using v4l2_device_register_sensor_subdev(). * @pdata: common part of subdevice platform data * * Each instance of a subdev driver should create this struct, either @@ -823,6 +825,7 @@ struct v4l2_subdev { struct list_head async_list; struct v4l2_async_subdev *asd; struct v4l2_async_notifier *notifier; + struct v4l2_async_notifier *subdev_notifier; struct v4l2_subdev_platform_data *pdata; }; diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h index c3114c989e91..b51fbe1941a7 100644 --- a/include/uapi/linux/cec.h +++ b/include/uapi/linux/cec.h @@ -411,6 +411,8 @@ struct cec_log_addrs { #define CEC_EVENT_LOST_MSGS 2 #define CEC_EVENT_PIN_CEC_LOW 3 #define CEC_EVENT_PIN_CEC_HIGH 4 +#define CEC_EVENT_PIN_HPD_LOW 5 +#define CEC_EVENT_PIN_HPD_HIGH 6 #define CEC_EVENT_FL_INITIAL_STATE (1 << 0) #define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1) diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index f46de499b51b..b297b65845d6 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -831,7 +831,7 @@ struct dtv_fe_stats { * @cmd: Digital TV command. * @reserved: Not used. * @u: Union with the values for the command. - * @result: Result of the command set (currently unused). + * @result: Unused * * The @u union may have either one of the values below: * diff --git a/samples/v4l/v4l2-pci-skeleton.c b/samples/v4l/v4l2-pci-skeleton.c index 483e9bca9444..f520e3aef9c6 100644 --- a/samples/v4l/v4l2-pci-skeleton.c +++ b/samples/v4l/v4l2-pci-skeleton.c @@ -772,8 +772,10 @@ static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Allocate a new instance */ skel = devm_kzalloc(&pdev->dev, sizeof(struct skeleton), GFP_KERNEL); - if (!skel) - return -ENOMEM; + if (!skel) { + ret = -ENOMEM; + goto disable_pci; + } /* Allocate the interrupt */ ret = devm_request_irq(&pdev->dev, pdev->irq, |