media updates for v6.9-rc1

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmXz6uoACgkQCF8+vY7k
 4RX3MQ/+LOHOMkufbq9qxLtbq9/2Wrdzym0q6j2RzD4r2ou4+DPJS8kc7c4eX02M
 9G37SL5LbLVT5OjMEP7ShZtBSmbAoqqxJOPxCWII32M3PbcV0QTYrTJg4LdyLry+
 vZz1KqYqMOaCJk5oy41RrYwwB+dhYu19gXSbw73sXoxOI24m/MAErsf2WLSk/ojk
 lcz7UIOWWLOXH08im6+GoqFbMWv6j8a72J7mXdguu+k+dBou/TkPnND7dq5wC17S
 dRLzQyYUm0fRIya/Hnoj/Cd0yUn/8NVPogG8Om/Nqt8BvCLZEihvKSVc8NJukavD
 /3LlZ2oj39NzV6oRwpUdAwHFH7KXuEZM/aQX06Wl34AfXXpFleTBQD40kSo/AHIq
 Kg9GGL9Z2V7F1pHrx4VlouUpfGMS0lZig4oL70ZrFmz6jWVDE/Vg4xN9mOl6RraX
 S43fHP7abLSg8XvKDX+Gdb5/NzA3Zkom5EdIFLPEd2DBCS3n59KkFXQ3AqVm4XaK
 HV8WnIOw4qcmH4H/8yxUpLCd/s7ACNuT72pws9YWCZOGD+Wv2tHU21aFiCOiB5ol
 VlxBxttez3c3Il8UWJaaApCqM9Mn7bMMB/KMUSJzUt785cK0sS0/4D6cbYE0Zdqr
 9IancZHiKMzbN14rNAqjUX8sqNNzPtVPDISLuXsN7MvzfjlOFLE=
 =YxyV
 -----END PGP SIGNATURE-----

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

Pull media updates from Mauro Carvalho Chehab:

 - DVB budget legacy API was finally documented. It took only 20+ years
   to get some documentation about it...

 - hantro driver has gained support for STM32MP25 VDEC/VENC

 - rkisp1 has gained support for i.MX8MP

 - atomisp got rid of two items from its todo list. Still 5 items
   pending for moving it out of staging

 - lots of driver fixes, cleanups and improvements

* tag 'media/v6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (252 commits)
  media: rcar-isp: Disallow unbind of devices
  media: usbtv: Remove useless locks in usbtv_video_free()
  media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
  media: ttpci: fix two memleaks in budget_av_attach
  media: go7007: fix a memleak in go7007_load_encoder
  media: dvb-frontends: avoid stack overflow warnings with clang
  media: pvrusb2: fix uaf in pvr2_context_set_notify
  media: usb: s2255: Refactor s2255_get_fx2fw
  media: ti: j721e-csi2rx: Convert to platform remove callback returning void
  media: stm32-dcmipp: Convert to platform remove callback returning void
  media: nxp: imx8-isi: Convert to platform remove callback returning void
  media: nuvoton: Convert to platform remove callback returning void
  media: chips-media: wave5: Convert to platform remove callback returning void
  media: chips-media: wave5: Remove unnecessary semicolons
  media: i2c: imx290: Fix IMX920 typo
  media: platform: replace of_graph_get_next_endpoint()
  media: i2c: replace of_graph_get_next_endpoint()
  media: ivsc: csi: Make use of sub-device state
  media: ivsc: csi: Swap SINK and SOURCE pads
  media: ipu-bridge: Serialise calls to IPU bridge init
  ...
This commit is contained in:
Linus Torvalds 2024-03-15 11:36:54 -07:00
commit eb7cca1faf
257 changed files with 10982 additions and 3700 deletions

View File

@ -49,6 +49,10 @@ Module parameters
visl_dprintk_frame_start, visl_dprintk_nframes, but controls the dumping of
buffer data through debugfs instead.
- tpg_verbose: Write extra information on each output frame to ease debugging
the API. When set to true, the output frames are not stable for a given input
as some information like pointers or queue status will be added to them.
What is the default use case for this driver?
---------------------------------------------
@ -57,8 +61,12 @@ This assumes that a working client is run against visl and that the ftrace and
OUTPUT buffer data is subsequently used to debug a work-in-progress
implementation.
Information on reference frames, their timestamps, the status of the OUTPUT and
CAPTURE queues and more can be read directly from the CAPTURE buffers.
Even though no video decoding is actually done, the output frames can be used
against a reference for a given input, except if tpg_verbose is set to true.
Depending on the tpg_verbose parameter value, information on reference frames,
their timestamps, the status of the OUTPUT and CAPTURE queues and more can be
read directly from the CAPTURE buffers.
Supported codecs
----------------

View File

@ -60,7 +60,7 @@ all configurable using the following module options:
- node_types:
which devices should each driver instance create. An array of
hexadecimal values, one for each instance. The default is 0x1d3d.
hexadecimal values, one for each instance. The default is 0xe1d3d.
Each value is a bitmask with the following meaning:
- bit 0: Video Capture node

View File

@ -36,7 +36,7 @@ properties:
properties:
port@0:
$ref: /schemas/graph.yaml#/$defs/port-base
$ref: /schemas/graph.yaml#/properties/port
description: Analog input port
properties:

View File

@ -16,6 +16,7 @@ description: |
properties:
compatible:
enum:
- fsl,imx8mp-isp
- rockchip,px30-cif-isp
- rockchip,rk3399-cif-isp
@ -36,9 +37,9 @@ properties:
minItems: 3
items:
# isp0 and isp1
- description: ISP clock
- description: ISP AXI clock
- description: ISP AHB clock
- description: ISP clock (for imx8mp, clk)
- description: ISP AXI clock (for imx8mp, m_hclk)
- description: ISP AHB clock (for imx8mp, hclk)
# only for isp1
- description: ISP Pixel clock
@ -52,6 +53,13 @@ properties:
# only for isp1
- const: pclk
fsl,blk-ctrl:
$ref: /schemas/types.yaml#/definitions/phandle-array
maxItems: 1
description:
A phandle to the media block control for the ISP, followed by a cell
containing the index of the gasket.
iommus:
maxItems: 1
@ -113,9 +121,6 @@ required:
- interrupts
- clocks
- clock-names
- iommus
- phys
- phy-names
- power-domains
- ports
@ -143,6 +148,26 @@ allOf:
required:
- interrupt-names
- if:
properties:
compatible:
contains:
const: fsl,imx8mp-isp
then:
properties:
iommus: false
phys: false
phy-names: false
required:
- fsl,blk-ctrl
else:
properties:
fsl,blk-ctrl: false
required:
- iommus
- phys
- phy-names
additionalProperties: false
examples:

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/st,stm32mp25-video-codec.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32MP25 VDEC video decoder & VENC video encoder
maintainers:
- Hugues Fruchet <hugues.fruchet@foss.st.com>
description:
The STMicroelectronics STM32MP25 SOCs embeds a VDEC video hardware
decoder peripheral based on Verisilicon VC8000NanoD IP (former Hantro G1)
and a VENC video hardware encoder peripheral based on Verisilicon
VC8000NanoE IP (former Hantro H1).
properties:
compatible:
enum:
- st,stm32mp25-vdec
- st,stm32mp25-venc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
video-codec@580d0000 {
compatible = "st,stm32mp25-vdec";
reg = <0x580d0000 0x3c8>;
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ck_icn_p_vdec>;
};

View File

@ -2,59 +2,16 @@
.. include:: <isonum.txt>
.. _media-ccs-driver:
MIPI CCS camera sensor driver
=============================
The MIPI CCS camera sensor driver is a generic driver for `MIPI CCS
<https://www.mipi.org/specifications/camera-command-set>`_ compliant
camera sensors. It exposes three sub-devices representing the pixel array,
the binner and the scaler.
camera sensors.
As the capabilities of individual devices vary, the driver exposes
interfaces based on the capabilities that exist in hardware.
Pixel Array sub-device
----------------------
The pixel array sub-device represents the camera sensor's pixel matrix, as well
as analogue crop functionality present in many compliant devices. The analogue
crop is configured using the ``V4L2_SEL_TGT_CROP`` on the source pad (0) of the
entity. The size of the pixel matrix can be obtained by getting the
``V4L2_SEL_TGT_NATIVE_SIZE`` target.
Binner
------
The binner sub-device represents the binning functionality on the sensor. For
that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
sink pad (0).
Additionally, if a device has no scaler or digital crop functionality, the
source pad (1) exposes another digital crop selection rectangle that can only
crop at the end of the lines and frames.
Scaler
------
The scaler sub-device represents the digital crop and scaling functionality of
the sensor. The V4L2 selection target ``V4L2_SEL_TGT_CROP`` is used to
configure the digital crop on the sink pad (0) when digital crop is supported.
Scaling is configured using selection target ``V4L2_SEL_TGT_COMPOSE`` on the
sink pad (0) as well.
Additionally, if the scaler sub-device exists, its source pad (1) exposes
another digital crop selection rectangle that can only crop at the end of the
lines and frames.
Digital and analogue crop
-------------------------
Digital crop functionality is referred to as cropping that effectively works by
dropping some data on the floor. Analogue crop, on the other hand, means that
the cropped information is never retrieved. In case of camera sensors, the
analogue data is never read from the pixel matrix that are outside the
configured selection rectangle that designates crop. The difference has an
effect in device timing and likely also in power consumption.
Also see :ref:`the CCS driver UAPI documentation <media-ccs-uapi>`.
CCS static data
---------------

View File

@ -229,7 +229,7 @@ Asynchronous sub-device notifier for sub-devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A driver that registers an asynchronous sub-device may also register an
asynchronous notifier. This is called an asynchronous sub-device notifier andthe
asynchronous notifier. This is called an asynchronous sub-device notifier and the
process is similar to that of a bridge driver apart from that the notifier is
initialised using :c:func:`v4l2_async_subdev_nf_init` instead. A sub-device
notifier may complete only after the V4L2 device becomes available, i.e. there's

View File

@ -2,6 +2,8 @@
.. include:: <isonum.txt>
.. _media-ccs-uapi:
MIPI CCS camera sensor driver
=============================
@ -13,6 +15,8 @@ the binner and the scaler.
As the capabilities of individual devices vary, the driver exposes
interfaces based on the capabilities that exist in hardware.
Also see :ref:`the CCS driver kernel documentation <media-ccs-driver>`.
Pixel Array sub-device
----------------------
@ -30,7 +34,7 @@ that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the
sink pad (0).
Additionally, if a device has no scaler or digital crop functionality, the
source pad (1) expses another digital crop selection rectangle that can only
source pad (1) exposes another digital crop selection rectangle that can only
crop at the end of the lines and frames.
Scaler

View File

@ -23,3 +23,4 @@ DVB-S2, DVB-T2, ISDB, etc.
:maxdepth: 1
frontend_legacy_dvbv3_api
legacy_dvb_decoder_api

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
.. _legacy_dvb_decoder_api:
============================
Legacy DVB MPEG Decoder APIs
============================
.. _legacy_dvb_decoder_notes:
General Notes
=============
This API has originally been designed for DVB only and is therefore limited to
the :ref:`legacy_dvb_decoder_formats` used in such digital TV-broadcastsystems.
To circumvent this limitations the more versatile :ref:`V4L2 <v4l2spec>` API has
been designed. Which replaces this part of the DVB API.
Nevertheless there have been projects build around this API.
To ensure compatibility this API is kept as it is.
.. attention:: Do **not** use this API in new drivers!
For audio and video use the :ref:`V4L2 <v4l2spec>` and ALSA APIs.
Pipelines should be set up using the :ref:`Media Controller API<media_controller>`.
Practically the decoders seem to be treated differently. The application typically
knows which decoder is in use or it is specially written for one decoder type.
Querying capabilities are rarely used because they are already known.
.. _legacy_dvb_decoder_formats:
Data Formats
============
The API has been designed for DVB and compatible broadcastsystems.
Because of that fact the only supported data formats are ISO/IEC 13818-1
compatible MPEG streams. The supported payloads may vary depending on the
used decoder.
Timestamps are always MPEG PTS as defined in ITU T-REC-H.222.0 /
ISO/IEC 13818-1, if not otherwise noted.
For storing recordings typically TS streams are used, in lesser extent PES.
Both variants are commonly accepted for playback, but it may be driver dependent.
Table of Contents
=================
.. toctree::
:maxdepth: 2
legacy_dvb_video
legacy_dvb_audio
legacy_dvb_osd

View File

@ -0,0 +1,883 @@
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later OR GPL-2.0
.. c:namespace:: dtv.legacy.osd
.. _dvb_osd:
==============
DVB OSD Device
==============
.. attention:: Do **not** use in new drivers!
See: :ref:`legacy_dvb_decoder_notes`
The DVB OSD device controls the OnScreen-Display of the AV7110 based
DVB-cards with hardware MPEG2 decoder. It can be accessed through
``/dev/dvb/adapter?/osd0``.
Data types and ioctl definitions can be accessed by including
``linux/dvb/osd.h`` in your application.
The OSD is not a frame-buffer like on many other cards.
It is a kind of canvas one can draw on.
The color-depth is limited depending on the memory size installed.
An appropriate palette of colors has to be set up.
The installed memory size can be identified with the `OSD_GET_CAPABILITY`_
ioctl.
OSD Data Types
==============
OSD_Command
-----------
Synopsis
~~~~~~~~
.. code-block:: c
typedef enum {
/* All functions return -2 on "not open" */
OSD_Close = 1,
OSD_Open,
OSD_Show,
OSD_Hide,
OSD_Clear,
OSD_Fill,
OSD_SetColor,
OSD_SetPalette,
OSD_SetTrans,
OSD_SetPixel,
OSD_GetPixel,
OSD_SetRow,
OSD_SetBlock,
OSD_FillRow,
OSD_FillBlock,
OSD_Line,
OSD_Query,
OSD_Test,
OSD_Text,
OSD_SetWindow,
OSD_MoveWindow,
OSD_OpenRaw,
} OSD_Command;
Commands
~~~~~~~~
.. note:: All functions return -2 on "not open"
.. flat-table::
:header-rows: 1
:stub-columns: 0
- ..
- Command
- | Used variables of ``struct`` `osd_cmd_t`_.
| Usage{variable} if alternative use.
- :cspan:`2` Description
- ..
- ``OSD_Close``
- -
- | Disables OSD and releases the buffers.
| Returns 0 on success.
- ..
- ``OSD_Open``
- | x0,y0,x1,y1,
| BitPerPixel[2/4/8]{color&0x0F},
| mix[0..15]{color&0xF0}
- | Opens OSD with this size and bit depth
| Returns 0 on success,
| -1 on DRAM allocation error,
| -2 on "already open".
- ..
- ``OSD_Show``
- -
- | Enables OSD mode.
| Returns 0 on success.
- ..
- ``OSD_Hide``
- -
- | Disables OSD mode.
| Returns 0 on success.
- ..
- ``OSD_Clear``
- -
- | Sets all pixel to color 0.
| Returns 0 on success.
- ..
- ``OSD_Fill``
- color
- | Sets all pixel to color <color>.
| Returns 0 on success.
- ..
- ``OSD_SetColor``
- | color,
| R{x0},G{y0},B{x1},
| opacity{y1}
- | Set palette entry <num> to <r,g,b>, <mix> and <trans> apply
| R,G,B: 0..255
| R=Red, G=Green, B=Blue
| opacity=0: pixel opacity 0% (only video pixel shows)
| opacity=1..254: pixel opacity as specified in header
| opacity=255: pixel opacity 100% (only OSD pixel shows)
| Returns 0 on success, -1 on error.
- ..
- ``OSD_SetPalette``
- | firstcolor{color},
| lastcolor{x0},data
- | Set a number of entries in the palette.
| Sets the entries "firstcolor" through "lastcolor" from the
array "data".
| Data has 4 byte for each color:
| R,G,B, and a opacity value: 0->transparent, 1..254->mix,
255->pixel
- ..
- ``OSD_SetTrans``
- transparency{color}
- | Sets transparency of mixed pixel (0..15).
| Returns 0 on success.
- ..
- ``OSD_SetPixel``
- x0,y0,color
- | Sets pixel <x>,<y> to color number <color>.
| Returns 0 on success, -1 on error.
- ..
- ``OSD_GetPixel``
- x0,y0
- | Returns color number of pixel <x>,<y>, or -1.
| Command currently not supported by the AV7110!
- ..
- ``OSD_SetRow``
- x0,y0,x1,data
- | Fills pixels x0,y through x1,y with the content of data[].
| Returns 0 on success, -1 on clipping all pixel (no pixel
drawn).
- ..
- ``OSD_SetBlock``
- | x0,y0,x1,y1,
| increment{color},
| data
- | Fills pixels x0,y0 through x1,y1 with the content of data[].
| Inc contains the width of one line in the data block,
| inc<=0 uses block width as line width.
| Returns 0 on success, -1 on clipping all pixel.
- ..
- ``OSD_FillRow``
- x0,y0,x1,color
- | Fills pixels x0,y through x1,y with the color <color>.
| Returns 0 on success, -1 on clipping all pixel.
- ..
- ``OSD_FillBlock``
- x0,y0,x1,y1,color
- | Fills pixels x0,y0 through x1,y1 with the color <color>.
| Returns 0 on success, -1 on clipping all pixel.
- ..
- ``OSD_Line``
- x0,y0,x1,y1,color
- | Draw a line from x0,y0 to x1,y1 with the color <color>.
| Returns 0 on success.
- ..
- ``OSD_Query``
- | x0,y0,x1,y1,
| xasp{color}; yasp=11
- | Fills parameters with the picture dimensions and the pixel
aspect ratio.
| Returns 0 on success.
| Command currently not supported by the AV7110!
- ..
- ``OSD_Test``
- -
- | Draws a test picture.
| For debugging purposes only.
| Returns 0 on success.
- ..
- ``OSD_Text``
- x0,y0,size,color,text
- Draws a text at position x0,y0 with the color <color>.
- ..
- ``OSD_SetWindow``
- x0
- Set window with number 0<x0<8 as current.
- ..
- ``OSD_MoveWindow``
- x0,y0
- Move current window to (x0, y0).
- ..
- ``OSD_OpenRaw``
- | x0,y0,x1,y1,
| `osd_raw_window_t`_ {color}
- Open other types of OSD windows.
Description
~~~~~~~~~~~
The ``OSD_Command`` data type is used with the `OSD_SEND_CMD`_ ioctl to
tell the driver which OSD_Command to execute.
-----
osd_cmd_t
---------
Synopsis
~~~~~~~~
.. code-block:: c
typedef struct osd_cmd_s {
OSD_Command cmd;
int x0;
int y0;
int x1;
int y1;
int color;
void __user *data;
} osd_cmd_t;
Variables
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``OSD_Command cmd``
- `OSD_Command`_ to be executed.
- ..
- ``int x0``
- First horizontal position.
- ..
- ``int y0``
- First vertical position.
- ..
- ``int x1``
- Second horizontal position.
- ..
- ``int y1``
- Second vertical position.
- ..
- ``int color``
- Number of the color in the palette.
- ..
- ``void __user *data``
- Command specific Data.
Description
~~~~~~~~~~~
The ``osd_cmd_t`` data type is used with the `OSD_SEND_CMD`_ ioctl.
It contains the data for the OSD_Command and the `OSD_Command`_ itself.
The structure has to be passed to the driver and the components may be
modified by it.
-----
osd_raw_window_t
----------------
Synopsis
~~~~~~~~
.. code-block:: c
typedef enum {
OSD_BITMAP1,
OSD_BITMAP2,
OSD_BITMAP4,
OSD_BITMAP8,
OSD_BITMAP1HR,
OSD_BITMAP2HR,
OSD_BITMAP4HR,
OSD_BITMAP8HR,
OSD_YCRCB422,
OSD_YCRCB444,
OSD_YCRCB444HR,
OSD_VIDEOTSIZE,
OSD_VIDEOHSIZE,
OSD_VIDEOQSIZE,
OSD_VIDEODSIZE,
OSD_VIDEOTHSIZE,
OSD_VIDEOTQSIZE,
OSD_VIDEOTDSIZE,
OSD_VIDEONSIZE,
OSD_CURSOR
} osd_raw_window_t;
Constants
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``OSD_BITMAP1``
- :cspan:`1` 1 bit bitmap
- ..
- ``OSD_BITMAP2``
- 2 bit bitmap
- ..
- ``OSD_BITMAP4``
- 4 bit bitmap
- ..
- ``OSD_BITMAP8``
- 8 bit bitmap
- ..
- ``OSD_BITMAP1HR``
- 1 Bit bitmap half resolution
- ..
- ``OSD_BITMAP2HR``
- 2 Bit bitmap half resolution
- ..
- ``OSD_BITMAP4HR``
- 4 Bit bitmap half resolution
- ..
- ``OSD_BITMAP8HR``
- 8 Bit bitmap half resolution
- ..
- ``OSD_YCRCB422``
- 4:2:2 YCRCB Graphic Display
- ..
- ``OSD_YCRCB444``
- 4:4:4 YCRCB Graphic Display
- ..
- ``OSD_YCRCB444HR``
- 4:4:4 YCRCB graphic half resolution
- ..
- ``OSD_VIDEOTSIZE``
- True Size Normal MPEG Video Display
- ..
- ``OSD_VIDEOHSIZE``
- MPEG Video Display Half Resolution
- ..
- ``OSD_VIDEOQSIZE``
- MPEG Video Display Quarter Resolution
- ..
- ``OSD_VIDEODSIZE``
- MPEG Video Display Double Resolution
- ..
- ``OSD_VIDEOTHSIZE``
- True Size MPEG Video Display Half Resolution
- ..
- ``OSD_VIDEOTQSIZE``
- True Size MPEG Video Display Quarter Resolution
- ..
- ``OSD_VIDEOTDSIZE``
- True Size MPEG Video Display Double Resolution
- ..
- ``OSD_VIDEONSIZE``
- Full Size MPEG Video Display
- ..
- ``OSD_CURSOR``
- Cursor
Description
~~~~~~~~~~~
The ``osd_raw_window_t`` data type is used with the `OSD_Command`_
OSD_OpenRaw to tell the driver which type of OSD to open.
-----
osd_cap_t
---------
Synopsis
~~~~~~~~
.. code-block:: c
typedef struct osd_cap_s {
int cmd;
#define OSD_CAP_MEMSIZE 1
long val;
} osd_cap_t;
Variables
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``int cmd``
- Capability to query.
- ..
- ``long val``
- Used to store the Data.
Supported capabilities
~~~~~~~~~~~~~~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``OSD_CAP_MEMSIZE``
- Memory size installed on the card.
Description
~~~~~~~~~~~
This structure of data used with the `OSD_GET_CAPABILITY`_ call.
-----
OSD Function Calls
==================
OSD_SEND_CMD
------------
Synopsis
~~~~~~~~
.. c:macro:: OSD_SEND_CMD
.. code-block:: c
int ioctl(int fd, int request = OSD_SEND_CMD, enum osd_cmd_t *cmd)
Arguments
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``int fd``
- :cspan:`1` File descriptor returned by a previous call
to `open()`_.
- ..
- ``int request``
- Pointer to the location of the structure `osd_cmd_t`_ for this
command.
Description
~~~~~~~~~~~
.. attention:: Do **not** use in new drivers!
See: :ref:`legacy_dvb_decoder_notes`
This ioctl sends the `OSD_Command`_ to the card.
Return Value
~~~~~~~~~~~~
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``EINVAL``
- Command is out of range.
-----
OSD_GET_CAPABILITY
------------------
Synopsis
~~~~~~~~
.. c:macro:: OSD_GET_CAPABILITY
.. code-block:: c
int ioctl(int fd, int request = OSD_GET_CAPABILITY,
struct osd_cap_t *cap)
Arguments
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``int fd``
- :cspan:`1` File descriptor returned by a previous call
to `open()`_.
- ..
- ``int request``
- Equals ``OSD_GET_CAPABILITY`` for this command.
- ..
- ``unsigned int *cap``
- Pointer to the location of the structure `osd_cap_t`_ for this
command.
Description
~~~~~~~~~~~
.. attention:: Do **not** use in new drivers!
See: :ref:`legacy_dvb_decoder_notes`
This ioctl is used to get the capabilities of the OSD of the AV7110 based
DVB-decoder-card in use.
.. note::
The structure osd_cap_t has to be setup by the user and passed to the
driver.
Return Value
~~~~~~~~~~~~
On success 0 is returned, on error -1 and the ``errno`` variable is set
appropriately. The generic error codes are described at the
:ref:`Generic Error Codes <gen-errors>` chapter.
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``EINVAL``
- Unsupported capability.
-----
open()
------
Synopsis
~~~~~~~~
.. code-block:: c
#include <fcntl.h>
.. c:function:: int open(const char *deviceName, int flags)
Arguments
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``const char *deviceName``
- Name of specific OSD device.
- ..
- :rspan:`3` ``int flags``
- :cspan:`1` A bit-wise OR of the following flags:
- ..
- ``O_RDONLY``
- read-only access
- ..
- ``O_RDWR``
- read/write access
- ..
- ``O_NONBLOCK``
- | Open in non-blocking mode
| (blocking mode is the default)
Description
~~~~~~~~~~~
This system call opens a named OSD device (e.g.
``/dev/dvb/adapter?/osd0``) for subsequent use.
Return Value
~~~~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``ENODEV``
- Device driver not loaded/available.
- ..
- ``EINTERNAL``
- Internal error.
- ..
- ``EBUSY``
- Device or resource busy.
- ..
- ``EINVAL``
- Invalid argument.
-----
close()
-------
Synopsis
~~~~~~~~
.. c:function:: int close(int fd)
Arguments
~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``int fd``
- :cspan:`1` File descriptor returned by a previous call
to `open()`_ .
Description
~~~~~~~~~~~
This system call closes a previously opened OSD device.
Return Value
~~~~~~~~~~~~
.. flat-table::
:header-rows: 0
:stub-columns: 0
- ..
- ``EBADF``
- fd is not a valid open file descriptor.

File diff suppressed because it is too large Load Diff

View File

@ -375,12 +375,11 @@ Types and flags used to represent the media graph elements
are origins of links.
* - ``MEDIA_PAD_FL_MUST_CONNECT``
- If this flag is set and the pad is linked to any other pad, then
at least one of those links must be enabled for the entity to be
able to stream. There could be temporary reasons (e.g. device
configuration dependent) for the pad to need enabled links even
when this flag isn't set; the absence of the flag doesn't imply
there is none.
- If this flag is set, then for this pad to be able to stream, it must
be connected by at least one enabled link. There could be temporary
reasons (e.g. device configuration dependent) for the pad to need
enabled links even when this flag isn't set; the absence of the flag
doesn't imply there is none.
One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``

View File

@ -61,6 +61,21 @@ been accepted. A common case for the kernel not accepting a capability is that
the kernel is older than the headers the userspace uses, and thus the capability
is unknown to the kernel.
.. tabularcolumns:: |p{1.5cm}|p{2.9cm}|p{12.9cm}|
.. c:type:: v4l2_subdev_client_capability
.. flat-table:: struct v4l2_subdev_client_capability
:header-rows: 0
:stub-columns: 0
:widths: 3 4 20
* - __u64
- ``capabilities``
- Sub-device client capabilities of the opened device.
.. tabularcolumns:: |p{6.8cm}|p{2.4cm}|p{8.1cm}|
.. flat-table:: Client Capabilities
:header-rows: 1

View File

@ -2761,6 +2761,7 @@ M: Andrzej Hajda <andrzej.hajda@intel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-media@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/media/samsung,s5p-mfc.yaml
F: drivers/media/platform/samsung/s5p-mfc/
ARM/SOCFPGA ARCHITECTURE
@ -13630,6 +13631,7 @@ T: git git://linuxtv.org/media_tree.git
F: Documentation/devicetree/bindings/media/renesas,csi2.yaml
F: Documentation/devicetree/bindings/media/renesas,isp.yaml
F: Documentation/devicetree/bindings/media/renesas,vin.yaml
F: drivers/media/platform/renesas/rcar-csi2.c
F: drivers/media/platform/renesas/rcar-isp.c
F: drivers/media/platform/renesas/rcar-vin/

View File

@ -1151,20 +1151,6 @@ void cec_received_msg_ts(struct cec_adapter *adap,
if (valid_la && min_len) {
/* These messages have special length requirements */
switch (cmd) {
case CEC_MSG_TIMER_STATUS:
if (msg->msg[2] & 0x10) {
switch (msg->msg[2] & 0xf) {
case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
if (msg->len < 5)
valid_la = false;
break;
}
} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
if (msg->len < 5)
valid_la = false;
}
break;
case CEC_MSG_RECORD_ON:
switch (msg->msg[2]) {
case CEC_OP_RECORD_SRC_OWN:

View File

@ -93,7 +93,7 @@ static void cec_devnode_release(struct device *cd)
cec_delete_adapter(to_cec_adapter(devnode));
}
static struct bus_type cec_bus_type = {
static const struct bus_type cec_bus_type = {
.name = CEC_NAME,
};

View File

@ -326,6 +326,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
{ "Google", "Taranza", "0000:00:02.0", port_db_conns },
/* Google Dexi */
{ "Google", "Dexi", "0000:00:02.0", port_db_conns },
/* Google Dita */
{ "Google", "Dita", "0000:00:02.0", port_db_conns },
};
static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,

View File

@ -113,6 +113,7 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
{
unsigned pat;
unsigned plane;
int ret = 0;
tpg->max_line_width = max_w;
for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
@ -121,14 +122,18 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->lines[pat][plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
if (!tpg->lines[pat][plane])
return -ENOMEM;
if (!tpg->lines[pat][plane]) {
ret = -ENOMEM;
goto free_lines;
}
if (plane == 0)
continue;
tpg->downsampled_lines[pat][plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
if (!tpg->downsampled_lines[pat][plane])
return -ENOMEM;
if (!tpg->downsampled_lines[pat][plane]) {
ret = -ENOMEM;
goto free_lines;
}
}
}
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@ -136,18 +141,45 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->contrast_line[plane] =
vzalloc(array_size(pixelsz, max_w));
if (!tpg->contrast_line[plane])
return -ENOMEM;
if (!tpg->contrast_line[plane]) {
ret = -ENOMEM;
goto free_contrast_line;
}
tpg->black_line[plane] =
vzalloc(array_size(pixelsz, max_w));
if (!tpg->black_line[plane])
return -ENOMEM;
if (!tpg->black_line[plane]) {
ret = -ENOMEM;
goto free_contrast_line;
}
tpg->random_line[plane] =
vzalloc(array3_size(max_w, 2, pixelsz));
if (!tpg->random_line[plane])
return -ENOMEM;
if (!tpg->random_line[plane]) {
ret = -ENOMEM;
goto free_contrast_line;
}
}
return 0;
free_contrast_line:
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
vfree(tpg->contrast_line[plane]);
vfree(tpg->black_line[plane]);
vfree(tpg->random_line[plane]);
tpg->contrast_line[plane] = NULL;
tpg->black_line[plane] = NULL;
tpg->random_line[plane] = NULL;
}
free_lines:
for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
vfree(tpg->lines[pat][plane]);
tpg->lines[pat][plane] = NULL;
if (plane == 0)
continue;
vfree(tpg->downsampled_lines[pat][plane]);
tpg->downsampled_lines[pat][plane] = NULL;
}
return ret;
}
EXPORT_SYMBOL_GPL(tpg_alloc);

View File

@ -679,11 +679,9 @@ static int dvb_frontend_thread(void *data)
set_freezable();
while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */
restart:
wait_event_interruptible_timeout(fepriv->wait_queue,
wait_event_freezable_timeout(fepriv->wait_queue,
dvb_frontend_should_wakeup(fe) ||
kthread_should_stop() ||
freezing(current),
kthread_should_stop(),
fepriv->delay);
if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
@ -694,9 +692,6 @@ restart:
break;
}
if (try_to_freeze())
goto restart;
if (down_interruptible(&fepriv->sem))
break;
@ -2168,7 +2163,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
tvp = memdup_array_user(compat_ptr(tvps->props),
tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@ -2199,7 +2195,8 @@ static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
tvp = memdup_array_user(compat_ptr(tvps->props),
tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@ -2379,7 +2376,8 @@ static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS)
return -EINVAL;
tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
tvp = memdup_array_user((void __user *)tvps->props,
tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);
@ -2457,7 +2455,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
return -EINVAL;
tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
tvp = memdup_array_user((void __user *)tvps->props,
tvps->num, sizeof(*tvp));
if (IS_ERR(tvp))
return PTR_ERR(tvp);

View File

@ -490,6 +490,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
if (!dvbdevfops) {
kfree(dvbdev);
*pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return -ENOMEM;
}
@ -498,6 +499,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
if (!new_node) {
kfree(dvbdevfops);
kfree(dvbdev);
*pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return -ENOMEM;
}
@ -531,6 +533,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
}
list_del(&dvbdev->list_head);
kfree(dvbdev);
*pdvbdev = NULL;
up_write(&minor_rwsem);
mutex_unlock(&dvbdev_register_lock);
return -EINVAL;
@ -553,6 +556,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvb_media_device_free(dvbdev);
list_del(&dvbdev->list_head);
kfree(dvbdev);
*pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return ret;
}
@ -571,6 +575,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvb_media_device_free(dvbdev);
list_del(&dvbdev->list_head);
kfree(dvbdev);
*pdvbdev = NULL;
mutex_unlock(&dvbdev_register_lock);
return PTR_ERR(clsdev);
}

View File

@ -797,7 +797,6 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
struct i2c_adapter *i2c)
{
struct bcm3510_state* state = NULL;
int ret;
bcm3510_register_value v;
/* allocate memory for the internal state */
@ -816,7 +815,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
mutex_init(&state->hab_mutex);
if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
if (bcm3510_readB(state, 0xe0, &v) < 0)
goto error;
deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);

View File

@ -12,11 +12,11 @@
#define PACKED __attribute__((packed))
#undef err
#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg)
#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n", ## arg)
#undef info
#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg)
#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n", ## arg)
#undef warn
#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n", ## arg)
#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500

View File

@ -224,13 +224,13 @@ static enum fe_code_rate cx24110_get_fec(struct cx24110_state *state)
}
}
static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
static int cx24110_set_symbolrate (struct cx24110_state *state, u32 srate)
{
/* fixme (low): add error handling */
u32 ratio;
u32 tmp, fclk, BDRI;
static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
static const u32 bands[] = {5000000UL, 15000000UL, 90999000UL/2};
int i;
dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);

View File

@ -34,11 +34,11 @@ static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
}
#if IS_REACHABLE(CONFIG_DVB_CX24110)
extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
struct i2c_adapter* i2c);
extern struct dvb_frontend *cx24110_attach(const struct cx24110_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
struct i2c_adapter* i2c)
static inline struct dvb_frontend *cx24110_attach(const struct cx24110_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;

View File

@ -796,7 +796,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
b1[0] = 0;
msg.buf = b1;
nr = ida_simple_get(&pll_ida, 0, DVB_PLL_MAX, GFP_KERNEL);
nr = ida_alloc_max(&pll_ida, DVB_PLL_MAX - 1, GFP_KERNEL);
if (nr < 0) {
kfree(b1);
return NULL;
@ -862,7 +862,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
return fe;
out:
kfree(b1);
ida_simple_remove(&pll_ida, nr);
ida_free(&pll_ida, nr);
return NULL;
}
@ -905,7 +905,7 @@ static void dvb_pll_remove(struct i2c_client *client)
struct dvb_frontend *fe = i2c_get_clientdata(client);
struct dvb_pll_priv *priv = fe->tuner_priv;
ida_simple_remove(&pll_ida, priv->nr);
ida_free(&pll_ida, priv->nr);
dvb_pll_release(fe);
}

View File

@ -118,50 +118,32 @@ static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_S
}
};
static
int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
static noinline_for_stack
int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
{
u8 buf[MAX_XFER_SIZE];
u8 buf[3] = { MSB(reg), LSB(reg), data };
struct i2c_msg msg = {
.addr = state->config->demod_address,
.flags = 0,
.buf = buf,
.len = len + 2
.len = 3,
};
int ret;
if (2 + len > sizeof(buf)) {
printk(KERN_WARNING
"%s: i2c wr reg=%04x: len=%d is too big!\n",
KBUILD_MODNAME, reg, len);
return -EINVAL;
}
buf[0] = MSB(reg);
buf[1] = LSB(reg);
memcpy(buf + 2, data, len);
if (i2cdebug)
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
state->config->demod_address, reg, buf[2]);
state->config->demod_address, reg, data);
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
__func__, state->config->demod_address, reg, buf[2]);
__func__, state->config->demod_address, reg, data);
return (ret != 1) ? -EREMOTEIO : 0;
}
static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
{
u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
return stv0367_writeregs(state, reg, &tmp, 1);
}
static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
static noinline_for_stack
u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
{
u8 b0[] = { 0, 0 };
u8 b1[] = { 0 };

View File

@ -20,13 +20,13 @@
#define dprintk(__y, __z, format, arg...) do { \
if (__z) { \
if ((verbose > FE_ERROR) && (verbose > __y)) \
printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
printk(KERN_ERR "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_NOTICE) && (verbose > __y)) \
printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_INFO) && (verbose > __y)) \
printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
printk(KERN_INFO "%s: " format "\n", __func__, ##arg); \
else if ((verbose > FE_DEBUG) && (verbose > __y)) \
printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg); \
} else { \
if (verbose > __y) \
printk(format, ##arg); \

View File

@ -24,11 +24,11 @@ struct tda8083_config
};
#if IS_REACHABLE(CONFIG_DVB_TDA8083)
extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
struct i2c_adapter* i2c);
extern struct dvb_frontend *tda8083_attach(const struct tda8083_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
struct i2c_adapter* i2c)
static inline struct dvb_frontend *tda8083_attach(const struct tda8083_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;

View File

@ -3,7 +3,7 @@
* Driver for Zarlink zl10036 DVB-S silicon tuner
*
* Copyright (C) 2006 Tino Reichardt
* Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
* Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.org>
*
**
* The data sheet for this tuner can be found at:

View File

@ -3,7 +3,7 @@
* Driver for Zarlink ZL10036 DVB-S silicon tuner
*
* Copyright (C) 2006 Tino Reichardt
* Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
* Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.org>
*/
#ifndef DVB_ZL10036_H

View File

@ -224,6 +224,7 @@ config VIDEO_IMX412
config VIDEO_IMX415
tristate "Sony IMX415 sensor support"
depends on OF_GPIO
select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX415 camera.
@ -658,6 +659,7 @@ config VIDEO_S5K6A3
config VIDEO_ST_VGXY61
tristate "ST VGXY61 sensor support"
select V4L2_CCI_I2C
depends on OF && GPIOLIB
help
This is a Video4Linux2 sensor driver for the ST VGXY61

View File

@ -1057,11 +1057,11 @@ static int adv7182_init(struct adv7180_state *state)
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
0x17);
}
}
else
} else {
adv7180_write(state,
ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
0x07);
}
adv7180_write(state, ADV7180_REG_OUTPUT_CONTROL, 0x0c);
adv7180_write(state, ADV7180_REG_CTRL_2, 0x40);
}

View File

@ -403,7 +403,7 @@ adv7343_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;

View File

@ -173,7 +173,6 @@ struct adv748x_afe {
*
* @endpoints: parsed device node endpoints for each port
*
* @i2c_addresses: I2C Page addresses
* @i2c_clients: I2C clients for the page accesses
* @regmap: regmap configuration pages.
*

View File

@ -3204,8 +3204,8 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
/* Parse the endpoint. */
endpoint = of_graph_get_next_endpoint(np, NULL);
/* FIXME: Parse the endpoint. */
endpoint = of_graph_get_endpoint_by_regs(np, -1, -1);
if (!endpoint)
return -EINVAL;

View File

@ -1170,40 +1170,32 @@ static int alvium_set_bayer_pattern(struct alvium_dev *alvium,
return 0;
}
static int alvium_get_frame_interval(struct alvium_dev *alvium)
static int alvium_get_frame_interval(struct alvium_dev *alvium,
u64 *min_fr, u64 *max_fr)
{
u64 dft_fr, min_fr, max_fr;
int ret = 0;
alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_RW,
&dft_fr, &ret);
alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MIN_R,
&min_fr, &ret);
min_fr, &ret);
alvium_read(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_MAX_R,
&max_fr, &ret);
if (ret)
max_fr, &ret);
return ret;
alvium->dft_fr = dft_fr;
alvium->min_fr = min_fr;
alvium->max_fr = max_fr;
return 0;
}
static int alvium_set_frame_rate(struct alvium_dev *alvium)
static int alvium_set_frame_rate(struct alvium_dev *alvium, u64 fr)
{
struct device *dev = &alvium->i2c_client->dev;
int ret;
ret = alvium_write_hshake(alvium, REG_BCRM_ACQUISITION_FRAME_RATE_RW,
alvium->fr);
fr);
if (ret) {
dev_err(dev, "Fail to set frame rate lanes reg\n");
return ret;
}
dev_dbg(dev, "set frame rate: %llu us\n", alvium->fr);
dev_dbg(dev, "set frame rate: %llu us\n", fr);
return 0;
}
@ -1472,7 +1464,7 @@ static int alvium_get_hw_features_params(struct alvium_dev *alvium)
ret = alvium_get_img_height_params(alvium);
if (ret) {
dev_err(dev, "Fail to read img heigth regs\n");
dev_err(dev, "Fail to read img height regs\n");
return ret;
}
@ -1647,44 +1639,28 @@ static int alvium_hw_init(struct alvium_dev *alvium)
}
/* --------------- Subdev Operations --------------- */
static int alvium_g_frame_interval(struct v4l2_subdev *sd,
static int alvium_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct alvium_dev *alvium = sd_to_alvium(sd);
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
fi->interval = alvium->frame_interval;
return 0;
}
static int alvium_set_frame_interval(struct alvium_dev *alvium,
struct v4l2_subdev_frame_interval *fi)
{
struct device *dev = &alvium->i2c_client->dev;
u64 req_fr, min_fr, max_fr;
struct v4l2_fract *interval;
int ret;
if (alvium->streaming)
return -EBUSY;
if (fi->interval.denominator == 0)
return -EINVAL;
ret = alvium_get_frame_interval(alvium);
ret = alvium_get_frame_interval(alvium, &min_fr, &max_fr);
if (ret) {
dev_err(dev, "Fail to get frame interval\n");
return ret;
}
min_fr = alvium->min_fr;
max_fr = alvium->max_fr;
dev_dbg(dev, "fi->interval.numerator = %d\n",
fi->interval.numerator);
dev_dbg(dev, "fi->interval.denominator = %d\n",
@ -1692,39 +1668,17 @@ static int alvium_set_frame_interval(struct alvium_dev *alvium,
req_fr = (u64)((fi->interval.denominator * USEC_PER_SEC) /
fi->interval.numerator);
req_fr = clamp(req_fr, min_fr, max_fr);
if (req_fr >= max_fr && req_fr <= min_fr)
req_fr = alvium->dft_fr;
interval = v4l2_subdev_state_get_interval(sd_state, 0);
alvium->fr = req_fr;
alvium->frame_interval.numerator = fi->interval.numerator;
alvium->frame_interval.denominator = fi->interval.denominator;
interval->numerator = fi->interval.numerator;
interval->denominator = fi->interval.denominator;
return 0;
}
static int alvium_s_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_interval *fi)
{
struct alvium_dev *alvium = sd_to_alvium(sd);
int ret;
/*
* FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
* subdev active state API.
*/
if (fi->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
return 0;
if (alvium->streaming)
return -EBUSY;
ret = alvium_set_frame_interval(alvium, fi);
if (!ret)
ret = alvium_set_frame_rate(alvium);
return ret;
return alvium_set_frame_rate(alvium, req_fr);
}
static int alvium_enum_mbus_code(struct v4l2_subdev *sd,
@ -1872,6 +1826,7 @@ static int alvium_init_state(struct v4l2_subdev *sd,
{
struct alvium_dev *alvium = sd_to_alvium(sd);
struct alvium_mode *mode = &alvium->mode;
struct v4l2_fract *interval;
struct v4l2_subdev_format sd_fmt = {
.which = V4L2_SUBDEV_FORMAT_TRY,
.format = alvium_csi2_default_fmt,
@ -1889,6 +1844,11 @@ static int alvium_init_state(struct v4l2_subdev *sd,
*v4l2_subdev_state_get_crop(state, 0) = sd_crop.rect;
*v4l2_subdev_state_get_format(state, 0) = sd_fmt.format;
/* Setup initial frame interval*/
interval = v4l2_subdev_state_get_interval(state, 0);
interval->numerator = 1;
interval->denominator = ALVIUM_DEFAULT_FR_HZ;
return 0;
}
@ -2258,7 +2218,7 @@ static const struct v4l2_subdev_pad_ops alvium_pad_ops = {
.set_fmt = alvium_set_fmt,
.get_selection = alvium_get_selection,
.set_selection = alvium_set_selection,
.get_frame_interval = alvium_g_frame_interval,
.get_frame_interval = v4l2_subdev_get_frame_interval,
.set_frame_interval = alvium_s_frame_interval,
};
@ -2279,11 +2239,6 @@ static int alvium_subdev_init(struct alvium_dev *alvium)
struct v4l2_subdev *sd = &alvium->sd;
int ret;
/* Setup initial frame interval*/
alvium->frame_interval.numerator = 1;
alvium->frame_interval.denominator = ALVIUM_DEFAULT_FR_HZ;
alvium->fr = ALVIUM_DEFAULT_FR_HZ;
/* Setup the initial mode */
alvium->mode.fmt = alvium_csi2_default_fmt;
alvium->mode.width = alvium_csi2_default_fmt.width;

View File

@ -442,11 +442,6 @@ struct alvium_dev {
s32 inc_sharp;
struct alvium_mode mode;
struct v4l2_fract frame_interval;
u64 dft_fr;
u64 min_fr;
u64 max_fr;
u64 fr;
u8 h_sup_csi_lanes;
u64 link_freq;

View File

@ -314,7 +314,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor)
* In the clock tree:
* MIPI_CLK = PIXEL_CLOCK * bpp / 2 / 2
*
* Generic pixel_rate to bus clock frequencey equation:
* Generic pixel_rate to bus clock frequency equation:
* MIPI_CLK = V4L2_CID_PIXEL_RATE * bpp / lanes / 2
*
* From which we derive the PIXEL_CLOCK to use in the clock tree:
@ -327,7 +327,7 @@ static void ar0521_calc_pll(struct ar0521_dev *sensor)
*
* TODO: in case we have less data lanes we have to reduce the desired
* VCO not to exceed the limits specified by the datasheet and
* consequentially reduce the obtained pixel clock.
* consequently reduce the obtained pixel clock.
*/
pixel_clock = AR0521_PIXEL_CLOCK_RATE * 2 / sensor->lane_count;
bpp = ar0521_code_to_bpp(sensor);
@ -806,7 +806,7 @@ static const struct initial_reg {
REGS(be(0x3F00),
be(0x0017), /* 3F00: BM_T0 */
be(0x02DD), /* 3F02: BM_T1 */
/* 3F04: if Ana_gain less than 2, use noise_floor0, multipl */
/* 3F04: if Ana_gain less than 2, use noise_floor0, multiply */
be(0x0020),
/* 3F06: if Ana_gain between 4 and 7, use noise_floor2 and */
be(0x0040),

View File

@ -28,11 +28,11 @@ struct ccs_sensor;
* @reg_access: Register access quirk. The quirk may divert the access
* to another register, or no register at all.
*
* @write: Is this read (false) or write (true) access?
* @reg: Pointer to the register to access
* @value: Register value, set by the caller on write, or
* -write: Is this read (false) or write (true) access?
* -reg: Pointer to the register to access
* -val: Register value, set by the caller on write, or
* by the quirk on read
* @return: 0 on success, -ENOIOCTLCMD if no register
* -return: 0 on success, -ENOIOCTLCMD if no register
* access may be done by the caller (default read
* value is zero), else negative error code on error
* @flags: Quirk flags

View File

@ -157,6 +157,8 @@ static int dw9714_probe(struct i2c_client *client)
return rval;
}
usleep_range(1000, 2000);
v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
V4L2_SUBDEV_FL_HAS_EVENTS;

View File

@ -968,7 +968,7 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = {
static const struct regmap_config sensor_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int imx214_get_regulators(struct device *dev, struct imx214 *imx214)

View File

@ -151,7 +151,7 @@ struct reg_8 {
static const struct regmap_config imx274_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
/*

View File

@ -150,10 +150,10 @@
#define IMX290_PIXEL_ARRAY_WIDTH 1945
#define IMX290_PIXEL_ARRAY_HEIGHT 1097
#define IMX920_PIXEL_ARRAY_MARGIN_LEFT 12
#define IMX920_PIXEL_ARRAY_MARGIN_RIGHT 13
#define IMX920_PIXEL_ARRAY_MARGIN_TOP 8
#define IMX920_PIXEL_ARRAY_MARGIN_BOTTOM 9
#define IMX290_PIXEL_ARRAY_MARGIN_LEFT 12
#define IMX290_PIXEL_ARRAY_MARGIN_RIGHT 13
#define IMX290_PIXEL_ARRAY_MARGIN_TOP 8
#define IMX290_PIXEL_ARRAY_MARGIN_BOTTOM 9
#define IMX290_PIXEL_ARRAY_RECORDING_WIDTH 1920
#define IMX290_PIXEL_ARRAY_RECORDING_HEIGHT 1080
@ -1161,10 +1161,10 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
* The sensor moves the readout by 1 pixel based on flips to
* keep the Bayer order the same.
*/
sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP
sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP
+ (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2
+ imx290->vflip->val;
sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT
sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT
+ (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2
+ imx290->hflip->val;
sel->r.width = format->width;
@ -1183,8 +1183,8 @@ static int imx290_get_selection(struct v4l2_subdev *sd,
return 0;
case V4L2_SEL_TGT_CROP_DEFAULT:
sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP;
sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT;
sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP;
sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT;
sel->r.width = IMX290_PIXEL_ARRAY_RECORDING_WIDTH;
sel->r.height = IMX290_PIXEL_ARRAY_RECORDING_HEIGHT;

View File

@ -70,7 +70,7 @@
#define IMX319_REG_ORIENTATION 0x0101
/* default link frequency and external clock */
#define IMX319_LINK_FREQ_DEFAULT 482400000
#define IMX319_LINK_FREQ_DEFAULT 482400000LL
#define IMX319_EXT_CLK 19200000
#define IMX319_LINK_FREQ_INDEX 0
@ -107,8 +107,7 @@ struct imx319_mode {
struct imx319_hwcfg {
u32 ext_clk; /* sensor external clk */
s64 *link_freqs; /* CSI-2 link frequencies */
unsigned int nr_of_link_freqs;
unsigned long link_freq_bitmap;
};
struct imx319 {
@ -129,7 +128,6 @@ struct imx319 {
const struct imx319_mode *cur_mode;
struct imx319_hwcfg *hwcfg;
s64 link_def_freq; /* CSI-2 link default frequency */
/*
* Mutex for serialized access:
@ -1654,7 +1652,10 @@ static const char * const imx319_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
/* supported link frequencies */
/*
* When adding more than the one below, make sure the disallowed ones will
* actually be disabled in the LINK_FREQ control.
*/
static const s64 link_freq_menu_items[] = {
IMX319_LINK_FREQ_DEFAULT,
};
@ -2058,7 +2059,7 @@ imx319_set_pad_format(struct v4l2_subdev *sd,
*framefmt = fmt->format;
} else {
imx319->cur_mode = mode;
pixel_rate = imx319->link_def_freq * 2 * 4;
pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
__v4l2_ctrl_s_ctrl_int64(imx319->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
@ -2255,7 +2256,7 @@ static int imx319_init_controls(struct imx319 *imx319)
imx319->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
pixel_rate = imx319->link_def_freq * 2 * 4;
pixel_rate = IMX319_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
imx319->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx319_ctrl_ops,
@ -2332,7 +2333,6 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
};
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned int i;
int ret;
if (!fwnode)
@ -2364,23 +2364,13 @@ static struct imx319_hwcfg *imx319_get_hwcfg(struct device *dev)
goto out_err;
}
dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
if (!bus_cfg.nr_of_link_frequencies) {
dev_warn(dev, "no link frequencies defined");
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq_menu_items,
ARRAY_SIZE(link_freq_menu_items),
&cfg->link_freq_bitmap);
if (ret)
goto out_err;
}
cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
cfg->link_freqs = devm_kcalloc(dev,
bus_cfg.nr_of_link_frequencies + 1,
sizeof(*cfg->link_freqs), GFP_KERNEL);
if (!cfg->link_freqs)
goto out_err;
for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
}
v4l2_fwnode_endpoint_free(&bus_cfg);
fwnode_handle_put(ep);
@ -2397,7 +2387,6 @@ static int imx319_probe(struct i2c_client *client)
struct imx319 *imx319;
bool full_power;
int ret;
u32 i;
imx319 = devm_kzalloc(&client->dev, sizeof(*imx319), GFP_KERNEL);
if (!imx319)
@ -2425,20 +2414,6 @@ static int imx319_probe(struct i2c_client *client)
goto error_probe;
}
imx319->link_def_freq = link_freq_menu_items[IMX319_LINK_FREQ_INDEX];
for (i = 0; i < imx319->hwcfg->nr_of_link_freqs; i++) {
if (imx319->hwcfg->link_freqs[i] == imx319->link_def_freq) {
dev_dbg(&client->dev, "link freq index %d matched", i);
break;
}
}
if (i == imx319->hwcfg->nr_of_link_freqs) {
dev_err(&client->dev, "no link frequency supported");
ret = -EINVAL;
goto error_probe;
}
/* Set default mode to max resolution */
imx319->cur_mode = &supported_modes[0];

View File

@ -136,7 +136,7 @@ struct imx334_mode {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
* @menu_skip_mask: Menu skip mask for link_freq_ctrl
* @link_freq_bitmap: Menu bitmap for link_freq_ctrl
* @cur_code: current selected format code
*/
struct imx334 {
@ -158,7 +158,7 @@ struct imx334 {
u32 vblank;
const struct imx334_mode *cur_mode;
struct mutex mutex;
unsigned long menu_skip_mask;
unsigned long link_freq_bitmap;
u32 cur_code;
};
@ -954,9 +954,9 @@ static int imx334_init_state(struct v4l2_subdev *sd,
imx334_fill_pad_format(imx334, imx334->cur_mode, &fmt);
__v4l2_ctrl_modify_range(imx334->link_freq_ctrl, 0,
__fls(imx334->menu_skip_mask),
~(imx334->menu_skip_mask),
__ffs(imx334->menu_skip_mask));
__fls(imx334->link_freq_bitmap),
~(imx334->link_freq_bitmap),
__ffs(imx334->link_freq_bitmap));
mutex_unlock(&imx334->mutex);
@ -1112,7 +1112,6 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
};
struct fwnode_handle *ep;
unsigned long rate;
unsigned int i, j;
int ret;
if (!fwnode)
@ -1157,26 +1156,10 @@ static int imx334_parse_hw_config(struct imx334 *imx334)
goto done_endpoint_free;
}
if (!bus_cfg.nr_of_link_frequencies) {
dev_err(imx334->dev, "no link frequencies defined");
ret = -EINVAL;
goto done_endpoint_free;
}
for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
for (j = 0; j < ARRAY_SIZE(link_freq); j++) {
if (bus_cfg.link_frequencies[i] == link_freq[j]) {
set_bit(j, &imx334->menu_skip_mask);
break;
}
}
if (j == ARRAY_SIZE(link_freq)) {
ret = dev_err_probe(imx334->dev, -EINVAL,
"no supported link freq found\n");
goto done_endpoint_free;
}
}
ret = v4l2_link_freq_to_bitmap(imx334->dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq, ARRAY_SIZE(link_freq),
&imx334->link_freq_bitmap);
done_endpoint_free:
v4l2_fwnode_endpoint_free(&bus_cfg);
@ -1310,8 +1293,8 @@ static int imx334_init_controls(struct imx334 *imx334)
imx334->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx334_ctrl_ops,
V4L2_CID_LINK_FREQ,
__fls(imx334->menu_skip_mask),
__ffs(imx334->menu_skip_mask),
__fls(imx334->link_freq_bitmap),
__ffs(imx334->link_freq_bitmap),
link_freq);
if (imx334->link_freq_ctrl)
@ -1386,7 +1369,7 @@ static int imx334_probe(struct i2c_client *client)
}
/* Set default mode to max resolution */
imx334->cur_mode = &supported_modes[__ffs(imx334->menu_skip_mask)];
imx334->cur_mode = &supported_modes[__ffs(imx334->link_freq_bitmap)];
imx334->cur_code = imx334_mbus_codes[0];
imx334->vblank = imx334->cur_mode->vblank;

View File

@ -45,11 +45,28 @@
/* Group hold register */
#define IMX335_REG_HOLD 0x3001
/* Test pattern generator */
#define IMX335_REG_TPG 0x329e
#define IMX335_TPG_ALL_000 0
#define IMX335_TPG_ALL_FFF 1
#define IMX335_TPG_ALL_555 2
#define IMX335_TPG_ALL_AAA 3
#define IMX335_TPG_TOG_555_AAA 4
#define IMX335_TPG_TOG_AAA_555 5
#define IMX335_TPG_TOG_000_555 6
#define IMX335_TPG_TOG_555_000 7
#define IMX335_TPG_TOG_000_FFF 8
#define IMX335_TPG_TOG_FFF_000 9
#define IMX335_TPG_H_COLOR_BARS 10
#define IMX335_TPG_V_COLOR_BARS 11
/* Input clock rate */
#define IMX335_INCLK_RATE 24000000
/* CSI2 HW configuration */
#define IMX335_LINK_FREQ 594000000
#define IMX335_LINK_FREQ_594MHz 594000000LL
#define IMX335_LINK_FREQ_445MHz 445500000LL
#define IMX335_NUM_DATA_LANES 4
#define IMX335_REG_MIN 0x00
@ -99,7 +116,6 @@ static const char * const imx335_supply_name[] = {
* @vblank_min: Minimum vertical blanking in lines
* @vblank_max: Maximum vertical blanking in lines
* @pclk: Sensor pixel clock
* @link_freq_idx: Link frequency index
* @reg_list: Register list for sensor mode
*/
struct imx335_mode {
@ -111,7 +127,6 @@ struct imx335_mode {
u32 vblank_min;
u32 vblank_max;
u64 pclk;
u32 link_freq_idx;
struct imx335_reg_list reg_list;
};
@ -134,6 +149,7 @@ struct imx335_mode {
* @vblank: Vertical blanking in lines
* @cur_mode: Pointer to current selected sensor mode
* @mutex: Mutex for serializing sensor controls
* @link_freq_bitmap: Menu bitmap for link_freq_ctrl
* @cur_mbus_code: Currently selected media bus format code
*/
struct imx335 {
@ -157,19 +173,46 @@ struct imx335 {
u32 vblank;
const struct imx335_mode *cur_mode;
struct mutex mutex;
unsigned long link_freq_bitmap;
u32 cur_mbus_code;
};
static const s64 link_freq[] = {
IMX335_LINK_FREQ,
static const char * const imx335_tpg_menu[] = {
"Disabled",
"All 000h",
"All FFFh",
"All 555h",
"All AAAh",
"Toggle 555/AAAh",
"Toggle AAA/555h",
"Toggle 000/555h",
"Toggle 555/000h",
"Toggle 000/FFFh",
"Toggle FFF/000h",
"Horizontal color bars",
"Vertical color bars",
};
static const int imx335_tpg_val[] = {
IMX335_TPG_ALL_000,
IMX335_TPG_ALL_000,
IMX335_TPG_ALL_FFF,
IMX335_TPG_ALL_555,
IMX335_TPG_ALL_AAA,
IMX335_TPG_TOG_555_AAA,
IMX335_TPG_TOG_AAA_555,
IMX335_TPG_TOG_000_555,
IMX335_TPG_TOG_555_000,
IMX335_TPG_TOG_000_FFF,
IMX335_TPG_TOG_FFF_000,
IMX335_TPG_H_COLOR_BARS,
IMX335_TPG_V_COLOR_BARS,
};
/* Sensor mode registers */
static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3000, 0x01},
{0x3002, 0x00},
{0x300c, 0x3b},
{0x300d, 0x2a},
{0x3018, 0x04},
{0x302c, 0x3c},
{0x302e, 0x20},
@ -177,10 +220,6 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3074, 0xc8},
{0x3076, 0x28},
{0x304c, 0x00},
{0x314c, 0xc6},
{0x315a, 0x02},
{0x3168, 0xa0},
{0x316a, 0x7e},
{0x31a1, 0x00},
{0x3288, 0x21},
{0x328a, 0x02},
@ -249,7 +288,7 @@ static const struct imx335_reg mode_2592x1940_regs[] = {
{0x3794, 0x7a},
{0x3796, 0xa1},
{0x37b0, 0x36},
{0x3a00, 0x01},
{0x3a00, 0x00},
};
static const struct imx335_reg raw10_framefmt_regs[] = {
@ -266,6 +305,65 @@ static const struct imx335_reg raw12_framefmt_regs[] = {
{0x341d, 0x00},
};
static const struct imx335_reg mipi_data_rate_1188Mbps[] = {
{0x300c, 0x3b},
{0x300d, 0x2a},
{0x314c, 0xc6},
{0x314d, 0x00},
{0x315a, 0x02},
{0x3168, 0xa0},
{0x316a, 0x7e},
{0x319e, 0x01},
{0x3a18, 0x8f},
{0x3a1a, 0x4f},
{0x3a1c, 0x47},
{0x3a1e, 0x37},
{0x3a1f, 0x01},
{0x3a20, 0x4f},
{0x3a22, 0x87},
{0x3a24, 0x4f},
{0x3a26, 0x7f},
{0x3a28, 0x3f},
};
static const struct imx335_reg mipi_data_rate_891Mbps[] = {
{0x300c, 0x3b},
{0x300d, 0x2a},
{0x314c, 0x29},
{0x314d, 0x01},
{0x315a, 0x06},
{0x3168, 0xa0},
{0x316a, 0x7e},
{0x319e, 0x02},
{0x3a18, 0x7f},
{0x3a1a, 0x37},
{0x3a1c, 0x37},
{0x3a1e, 0xf7},
{0x3a20, 0x3f},
{0x3a22, 0x6f},
{0x3a24, 0x3f},
{0x3a26, 0x5f},
{0x3a28, 0x2f},
};
static const s64 link_freq[] = {
/* Corresponds to 1188Mbps data lane rate */
IMX335_LINK_FREQ_594MHz,
/* Corresponds to 891Mbps data lane rate */
IMX335_LINK_FREQ_445MHz,
};
static const struct imx335_reg_list link_freq_reglist[] = {
{
.num_of_regs = ARRAY_SIZE(mipi_data_rate_1188Mbps),
.regs = mipi_data_rate_1188Mbps,
},
{
.num_of_regs = ARRAY_SIZE(mipi_data_rate_891Mbps),
.regs = mipi_data_rate_891Mbps,
},
};
static const u32 imx335_mbus_codes[] = {
MEDIA_BUS_FMT_SRGGB12_1X12,
MEDIA_BUS_FMT_SRGGB10_1X10,
@ -280,7 +378,6 @@ static const struct imx335_mode supported_mode = {
.vblank_min = 2560,
.vblank_max = 133060,
.pclk = 396000000,
.link_freq_idx = 0,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_2592x1940_regs),
.regs = mode_2592x1940_regs,
@ -405,7 +502,8 @@ static int imx335_update_controls(struct imx335 *imx335,
{
int ret;
ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, mode->link_freq_idx);
ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl,
__ffs(imx335->link_freq_bitmap));
if (ret)
return ret;
@ -456,6 +554,49 @@ error_release_group_hold:
return ret;
}
static int imx335_update_test_pattern(struct imx335 *imx335, u32 pattern_index)
{
int ret;
if (pattern_index >= ARRAY_SIZE(imx335_tpg_val))
return -EINVAL;
if (pattern_index) {
const struct imx335_reg tpg_enable_regs[] = {
{ 0x3148, 0x10 },
{ 0x3280, 0x00 },
{ 0x329c, 0x01 },
{ 0x32a0, 0x11 },
{ 0x3302, 0x00 },
{ 0x3303, 0x00 },
{ 0x336c, 0x00 },
};
ret = imx335_write_reg(imx335, IMX335_REG_TPG, 1,
imx335_tpg_val[pattern_index]);
if (ret)
return ret;
ret = imx335_write_regs(imx335, tpg_enable_regs,
ARRAY_SIZE(tpg_enable_regs));
} else {
const struct imx335_reg tpg_disable_regs[] = {
{ 0x3148, 0x00 },
{ 0x3280, 0x01 },
{ 0x329c, 0x00 },
{ 0x32a0, 0x10 },
{ 0x3302, 0x32 },
{ 0x3303, 0x00 },
{ 0x336c, 0x01 },
};
ret = imx335_write_regs(imx335, tpg_disable_regs,
ARRAY_SIZE(tpg_disable_regs));
}
return ret;
}
/**
* imx335_set_ctrl() - Set subdevice control
* @ctrl: pointer to v4l2_ctrl structure
@ -476,26 +617,31 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
u32 exposure;
int ret;
switch (ctrl->id) {
case V4L2_CID_VBLANK:
/* Propagate change of current control to all related controls */
if (ctrl->id == V4L2_CID_VBLANK) {
imx335->vblank = imx335->vblank_ctrl->val;
dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u\n",
imx335->vblank,
imx335->vblank + imx335->cur_mode->height);
ret = __v4l2_ctrl_modify_range(imx335->exp_ctrl,
return __v4l2_ctrl_modify_range(imx335->exp_ctrl,
IMX335_EXPOSURE_MIN,
imx335->vblank +
imx335->cur_mode->height -
IMX335_EXPOSURE_OFFSET,
1, IMX335_EXPOSURE_DEFAULT);
break;
case V4L2_CID_EXPOSURE:
/* Set controls only if sensor is in power on state */
if (!pm_runtime_get_if_in_use(imx335->dev))
}
/*
* Applying V4L2 control value only happens
* when power is up for streaming.
*/
if (pm_runtime_get_if_in_use(imx335->dev) == 0)
return 0;
switch (ctrl->id) {
case V4L2_CID_EXPOSURE:
exposure = ctrl->val;
analog_gain = imx335->again_ctrl->val;
@ -504,7 +650,9 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
ret = imx335_update_exp_gain(imx335, exposure, analog_gain);
pm_runtime_put(imx335->dev);
break;
case V4L2_CID_TEST_PATTERN:
ret = imx335_update_test_pattern(imx335, ctrl->val);
break;
default:
@ -512,6 +660,8 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
ret = -EINVAL;
}
pm_runtime_put(imx335->dev);
return ret;
}
@ -691,6 +841,13 @@ static int imx335_init_state(struct v4l2_subdev *sd,
fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
imx335_fill_pad_format(imx335, &supported_mode, &fmt);
mutex_lock(&imx335->mutex);
__v4l2_ctrl_modify_range(imx335->link_freq_ctrl, 0,
__fls(imx335->link_freq_bitmap),
~(imx335->link_freq_bitmap),
__ffs(imx335->link_freq_bitmap));
mutex_unlock(&imx335->mutex);
return imx335_set_pad_format(sd, sd_state, &fmt);
}
@ -755,6 +912,14 @@ static int imx335_start_streaming(struct imx335 *imx335)
const struct imx335_reg_list *reg_list;
int ret;
/* Setup PLL */
reg_list = &link_freq_reglist[__ffs(imx335->link_freq_bitmap)];
ret = imx335_write_regs(imx335, reg_list->regs, reg_list->num_of_regs);
if (ret) {
dev_err(imx335->dev, "%s failed to set plls\n", __func__);
return ret;
}
/* Write sensor mode registers */
reg_list = &imx335->cur_mode->reg_list;
ret = imx335_write_regs(imx335, reg_list->regs,
@ -939,19 +1104,10 @@ static int imx335_parse_hw_config(struct imx335 *imx335)
goto done_endpoint_free;
}
if (!bus_cfg.nr_of_link_frequencies) {
dev_err(imx335->dev, "no link frequencies defined\n");
ret = -EINVAL;
goto done_endpoint_free;
}
for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
if (bus_cfg.link_frequencies[i] == IMX335_LINK_FREQ)
goto done_endpoint_free;
dev_err(imx335->dev, "no compatible link frequencies found\n");
ret = -EINVAL;
ret = v4l2_link_freq_to_bitmap(imx335->dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq, ARRAY_SIZE(link_freq),
&imx335->link_freq_bitmap);
done_endpoint_free:
v4l2_fwnode_endpoint_free(&bus_cfg);
@ -1055,7 +1211,7 @@ static int imx335_init_controls(struct imx335 *imx335)
u32 lpfr;
int ret;
ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6);
ret = v4l2_ctrl_handler_init(ctrl_hdlr, 7);
if (ret)
return ret;
@ -1089,6 +1245,12 @@ static int imx335_init_controls(struct imx335 *imx335)
mode->vblank_max,
1, mode->vblank);
v4l2_ctrl_new_std_menu_items(ctrl_hdlr,
&imx335_ctrl_ops,
V4L2_CID_TEST_PATTERN,
ARRAY_SIZE(imx335_tpg_menu) - 1,
0, 0, imx335_tpg_menu);
/* Read only controls */
imx335->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr,
&imx335_ctrl_ops,
@ -1099,9 +1261,8 @@ static int imx335_init_controls(struct imx335 *imx335)
imx335->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&imx335_ctrl_ops,
V4L2_CID_LINK_FREQ,
ARRAY_SIZE(link_freq) -
1,
mode->link_freq_idx,
__fls(imx335->link_freq_bitmap),
__ffs(imx335->link_freq_bitmap),
link_freq);
if (imx335->link_freq_ctrl)
imx335->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;

View File

@ -56,7 +56,7 @@
#define IMX355_REG_ORIENTATION 0x0101
/* default link frequency and external clock */
#define IMX355_LINK_FREQ_DEFAULT 360000000
#define IMX355_LINK_FREQ_DEFAULT 360000000LL
#define IMX355_EXT_CLK 19200000
#define IMX355_LINK_FREQ_INDEX 0
@ -93,8 +93,7 @@ struct imx355_mode {
struct imx355_hwcfg {
u32 ext_clk; /* sensor external clk */
s64 *link_freqs; /* CSI-2 link frequencies */
unsigned int nr_of_link_freqs;
unsigned long link_freq_bitmap;
};
struct imx355 {
@ -115,7 +114,6 @@ struct imx355 {
const struct imx355_mode *cur_mode;
struct imx355_hwcfg *hwcfg;
s64 link_def_freq; /* CSI-2 link default frequency */
/*
* Mutex for serialized access:
@ -879,7 +877,10 @@ static const char * const imx355_test_pattern_menu[] = {
"Pseudorandom Sequence (PN9)",
};
/* supported link frequencies */
/*
* When adding more than the one below, make sure the disallowed ones will
* actually be disabled in the LINK_FREQ control.
*/
static const s64 link_freq_menu_items[] = {
IMX355_LINK_FREQ_DEFAULT,
};
@ -1356,7 +1357,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
*framefmt = fmt->format;
} else {
imx355->cur_mode = mode;
pixel_rate = imx355->link_def_freq * 2 * 4;
pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
__v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
@ -1543,7 +1544,7 @@ static int imx355_init_controls(struct imx355 *imx355)
imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
/* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
pixel_rate = imx355->link_def_freq * 2 * 4;
pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
@ -1620,7 +1621,6 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
};
struct fwnode_handle *ep;
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned int i;
int ret;
if (!fwnode)
@ -1652,23 +1652,13 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
goto out_err;
}
dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
if (!bus_cfg.nr_of_link_frequencies) {
dev_warn(dev, "no link frequencies defined");
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_freq_menu_items,
ARRAY_SIZE(link_freq_menu_items),
&cfg->link_freq_bitmap);
if (ret)
goto out_err;
}
cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
cfg->link_freqs = devm_kcalloc(dev,
bus_cfg.nr_of_link_frequencies + 1,
sizeof(*cfg->link_freqs), GFP_KERNEL);
if (!cfg->link_freqs)
goto out_err;
for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
}
v4l2_fwnode_endpoint_free(&bus_cfg);
fwnode_handle_put(ep);
@ -1684,7 +1674,6 @@ static int imx355_probe(struct i2c_client *client)
{
struct imx355 *imx355;
int ret;
u32 i;
imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
if (!imx355)
@ -1709,20 +1698,6 @@ static int imx355_probe(struct i2c_client *client)
goto error_probe;
}
imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
dev_dbg(&client->dev, "link freq index %d matched", i);
break;
}
}
if (i == imx355->hwcfg->nr_of_link_freqs) {
dev_err(&client->dev, "no link frequency supported");
ret = -EINVAL;
goto error_probe;
}
/* Set default mode to max resolution */
imx355->cur_mode = &supported_modes[0];

View File

@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@ -28,76 +29,65 @@
#define IMX415_NUM_CLK_PARAM_REGS 11
#define IMX415_REG_8BIT(n) ((1 << 16) | (n))
#define IMX415_REG_16BIT(n) ((2 << 16) | (n))
#define IMX415_REG_24BIT(n) ((3 << 16) | (n))
#define IMX415_REG_SIZE_SHIFT 16
#define IMX415_REG_ADDR_MASK 0xffff
#define IMX415_MODE IMX415_REG_8BIT(0x3000)
#define IMX415_MODE CCI_REG8(0x3000)
#define IMX415_MODE_OPERATING (0)
#define IMX415_MODE_STANDBY BIT(0)
#define IMX415_REGHOLD IMX415_REG_8BIT(0x3001)
#define IMX415_REGHOLD CCI_REG8(0x3001)
#define IMX415_REGHOLD_INVALID (0)
#define IMX415_REGHOLD_VALID BIT(0)
#define IMX415_XMSTA IMX415_REG_8BIT(0x3002)
#define IMX415_XMSTA CCI_REG8(0x3002)
#define IMX415_XMSTA_START (0)
#define IMX415_XMSTA_STOP BIT(0)
#define IMX415_BCWAIT_TIME IMX415_REG_16BIT(0x3008)
#define IMX415_CPWAIT_TIME IMX415_REG_16BIT(0x300A)
#define IMX415_WINMODE IMX415_REG_8BIT(0x301C)
#define IMX415_ADDMODE IMX415_REG_8BIT(0x3022)
#define IMX415_REVERSE IMX415_REG_8BIT(0x3030)
#define IMX415_BCWAIT_TIME CCI_REG16_LE(0x3008)
#define IMX415_CPWAIT_TIME CCI_REG16_LE(0x300a)
#define IMX415_WINMODE CCI_REG8(0x301c)
#define IMX415_ADDMODE CCI_REG8(0x3022)
#define IMX415_REVERSE CCI_REG8(0x3030)
#define IMX415_HREVERSE_SHIFT (0)
#define IMX415_VREVERSE_SHIFT BIT(0)
#define IMX415_ADBIT IMX415_REG_8BIT(0x3031)
#define IMX415_MDBIT IMX415_REG_8BIT(0x3032)
#define IMX415_SYS_MODE IMX415_REG_8BIT(0x3033)
#define IMX415_OUTSEL IMX415_REG_8BIT(0x30C0)
#define IMX415_DRV IMX415_REG_8BIT(0x30C1)
#define IMX415_VMAX IMX415_REG_24BIT(0x3024)
#define IMX415_HMAX IMX415_REG_16BIT(0x3028)
#define IMX415_SHR0 IMX415_REG_24BIT(0x3050)
#define IMX415_GAIN_PCG_0 IMX415_REG_16BIT(0x3090)
#define IMX415_ADBIT CCI_REG8(0x3031)
#define IMX415_MDBIT CCI_REG8(0x3032)
#define IMX415_SYS_MODE CCI_REG8(0x3033)
#define IMX415_OUTSEL CCI_REG8(0x30c0)
#define IMX415_DRV CCI_REG8(0x30c1)
#define IMX415_VMAX CCI_REG24_LE(0x3024)
#define IMX415_HMAX CCI_REG16_LE(0x3028)
#define IMX415_SHR0 CCI_REG24_LE(0x3050)
#define IMX415_GAIN_PCG_0 CCI_REG16_LE(0x3090)
#define IMX415_AGAIN_MIN 0
#define IMX415_AGAIN_MAX 100
#define IMX415_AGAIN_STEP 1
#define IMX415_BLKLEVEL IMX415_REG_16BIT(0x30E2)
#define IMX415_BLKLEVEL CCI_REG16_LE(0x30e2)
#define IMX415_BLKLEVEL_DEFAULT 50
#define IMX415_TPG_EN_DUOUT IMX415_REG_8BIT(0x30E4)
#define IMX415_TPG_PATSEL_DUOUT IMX415_REG_8BIT(0x30E6)
#define IMX415_TPG_COLORWIDTH IMX415_REG_8BIT(0x30E8)
#define IMX415_TESTCLKEN_MIPI IMX415_REG_8BIT(0x3110)
#define IMX415_INCKSEL1 IMX415_REG_8BIT(0x3115)
#define IMX415_INCKSEL2 IMX415_REG_8BIT(0x3116)
#define IMX415_INCKSEL3 IMX415_REG_16BIT(0x3118)
#define IMX415_INCKSEL4 IMX415_REG_16BIT(0x311A)
#define IMX415_INCKSEL5 IMX415_REG_8BIT(0x311E)
#define IMX415_DIG_CLP_MODE IMX415_REG_8BIT(0x32C8)
#define IMX415_WRJ_OPEN IMX415_REG_8BIT(0x3390)
#define IMX415_SENSOR_INFO IMX415_REG_16BIT(0x3F12)
#define IMX415_SENSOR_INFO_MASK 0xFFF
#define IMX415_TPG_EN_DUOUT CCI_REG8(0x30e4)
#define IMX415_TPG_PATSEL_DUOUT CCI_REG8(0x30e6)
#define IMX415_TPG_COLORWIDTH CCI_REG8(0x30e8)
#define IMX415_TESTCLKEN_MIPI CCI_REG8(0x3110)
#define IMX415_INCKSEL1 CCI_REG8(0x3115)
#define IMX415_INCKSEL2 CCI_REG8(0x3116)
#define IMX415_INCKSEL3 CCI_REG16_LE(0x3118)
#define IMX415_INCKSEL4 CCI_REG16_LE(0x311a)
#define IMX415_INCKSEL5 CCI_REG8(0x311e)
#define IMX415_DIG_CLP_MODE CCI_REG8(0x32c8)
#define IMX415_WRJ_OPEN CCI_REG8(0x3390)
#define IMX415_SENSOR_INFO CCI_REG16_LE(0x3f12)
#define IMX415_SENSOR_INFO_MASK 0xfff
#define IMX415_CHIP_ID 0x514
#define IMX415_LANEMODE IMX415_REG_16BIT(0x4001)
#define IMX415_LANEMODE CCI_REG16_LE(0x4001)
#define IMX415_LANEMODE_2 1
#define IMX415_LANEMODE_4 3
#define IMX415_TXCLKESC_FREQ IMX415_REG_16BIT(0x4004)
#define IMX415_INCKSEL6 IMX415_REG_8BIT(0x400C)
#define IMX415_TCLKPOST IMX415_REG_16BIT(0x4018)
#define IMX415_TCLKPREPARE IMX415_REG_16BIT(0x401A)
#define IMX415_TCLKTRAIL IMX415_REG_16BIT(0x401C)
#define IMX415_TCLKZERO IMX415_REG_16BIT(0x401E)
#define IMX415_THSPREPARE IMX415_REG_16BIT(0x4020)
#define IMX415_THSZERO IMX415_REG_16BIT(0x4022)
#define IMX415_THSTRAIL IMX415_REG_16BIT(0x4024)
#define IMX415_THSEXIT IMX415_REG_16BIT(0x4026)
#define IMX415_TLPX IMX415_REG_16BIT(0x4028)
#define IMX415_INCKSEL7 IMX415_REG_8BIT(0x4074)
struct imx415_reg {
u32 address;
u32 val;
};
#define IMX415_TXCLKESC_FREQ CCI_REG16_LE(0x4004)
#define IMX415_INCKSEL6 CCI_REG8(0x400c)
#define IMX415_TCLKPOST CCI_REG16_LE(0x4018)
#define IMX415_TCLKPREPARE CCI_REG16_LE(0x401a)
#define IMX415_TCLKTRAIL CCI_REG16_LE(0x401c)
#define IMX415_TCLKZERO CCI_REG16_LE(0x401e)
#define IMX415_THSPREPARE CCI_REG16_LE(0x4020)
#define IMX415_THSZERO CCI_REG16_LE(0x4022)
#define IMX415_THSTRAIL CCI_REG16_LE(0x4024)
#define IMX415_THSEXIT CCI_REG16_LE(0x4026)
#define IMX415_TLPX CCI_REG16_LE(0x4028)
#define IMX415_INCKSEL7 CCI_REG8(0x4074)
static const char *const imx415_supply_names[] = {
"dvdd",
@ -118,13 +108,13 @@ static const s64 link_freq_menu_items[] = {
struct imx415_clk_params {
u64 lane_rate;
u64 inck;
struct imx415_reg regs[IMX415_NUM_CLK_PARAM_REGS];
struct cci_reg_sequence regs[IMX415_NUM_CLK_PARAM_REGS];
};
/* INCK Settings - includes all lane rate and INCK dependent registers */
static const struct imx415_clk_params imx415_clk_params[] = {
{
.lane_rate = 594000000,
.lane_rate = 594000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@ -139,7 +129,37 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 720000000,
.lane_rate = 594000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x7 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x080 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x0 },
.regs[9] = { IMX415_INCKSEL7, 0x1 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0984 },
},
{
.lane_rate = 594000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x7 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x080 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x0 },
.regs[9] = { IMX415_INCKSEL7, 0x1 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
{
.lane_rate = 720000000UL,
.inck = 24000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x054 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x03B },
@ -154,7 +174,22 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 },
},
{
.lane_rate = 891000000,
.lane_rate = 720000000UL,
.inck = 72000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 },
.regs[2] = { IMX415_SYS_MODE, 0x9 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0A0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x0 },
.regs[9] = { IMX415_INCKSEL7, 0x1 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 },
},
{
.lane_rate = 891000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@ -169,7 +204,37 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 1440000000,
.lane_rate = 891000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x5 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x0C0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x0 },
.regs[9] = { IMX415_INCKSEL7, 0x1 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
},
{
.lane_rate = 891000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x5 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0C0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x0 },
.regs[9] = { IMX415_INCKSEL7, 0x1 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
{
.lane_rate = 1440000000UL,
.inck = 24000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x054 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x03B },
@ -184,7 +249,22 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0600 },
},
{
.lane_rate = 1485000000,
.lane_rate = 1440000000UL,
.inck = 72000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0F8 },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B0 },
.regs[2] = { IMX415_SYS_MODE, 0x8 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0A0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1200 },
},
{
.lane_rate = 1485000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
@ -198,10 +278,175 @@ static const struct imx415_clk_params imx415_clk_params[] = {
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 1485000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x8 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x0A0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
},
{
.lane_rate = 1485000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x8 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0A0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
{
.lane_rate = 1782000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
.regs[2] = { IMX415_SYS_MODE, 0x4 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x23 },
.regs[5] = { IMX415_INCKSEL3, 0x0C6 },
.regs[6] = { IMX415_INCKSEL4, 0x0E7 },
.regs[7] = { IMX415_INCKSEL5, 0x23 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 1782000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x4 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x0C0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
},
{
.lane_rate = 1782000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x4 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0C0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
{
.lane_rate = 2079000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
.regs[2] = { IMX415_SYS_MODE, 0x2 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x23 },
.regs[5] = { IMX415_INCKSEL3, 0x0E7 },
.regs[6] = { IMX415_INCKSEL4, 0x0E7 },
.regs[7] = { IMX415_INCKSEL5, 0x23 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 2079000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x2 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x0E0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
},
{
.lane_rate = 2079000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x2 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x0E0 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
{
.lane_rate = 2376000000UL,
.inck = 27000000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x05D },
.regs[1] = { IMX415_CPWAIT_TIME, 0x042 },
.regs[2] = { IMX415_SYS_MODE, 0x0 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x23 },
.regs[5] = { IMX415_INCKSEL3, 0x108 },
.regs[6] = { IMX415_INCKSEL4, 0x0E7 },
.regs[7] = { IMX415_INCKSEL5, 0x23 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x06C0 },
},
{
.lane_rate = 2376000000UL,
.inck = 37125000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x07F },
.regs[1] = { IMX415_CPWAIT_TIME, 0x05B },
.regs[2] = { IMX415_SYS_MODE, 0x0 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x24 },
.regs[5] = { IMX415_INCKSEL3, 0x100 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x24 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x0948 },
},
{
.lane_rate = 2376000000UL,
.inck = 74250000,
.regs[0] = { IMX415_BCWAIT_TIME, 0x0FF },
.regs[1] = { IMX415_CPWAIT_TIME, 0x0B6 },
.regs[2] = { IMX415_SYS_MODE, 0x0 },
.regs[3] = { IMX415_INCKSEL1, 0x00 },
.regs[4] = { IMX415_INCKSEL2, 0x28 },
.regs[5] = { IMX415_INCKSEL3, 0x100 },
.regs[6] = { IMX415_INCKSEL4, 0x0E0 },
.regs[7] = { IMX415_INCKSEL5, 0x28 },
.regs[8] = { IMX415_INCKSEL6, 0x1 },
.regs[9] = { IMX415_INCKSEL7, 0x0 },
.regs[10] = { IMX415_TXCLKESC_FREQ, 0x1290 },
},
};
/* all-pixel 2-lane 720 Mbps 15.74 Hz mode */
static const struct imx415_reg imx415_mode_2_720[] = {
static const struct cci_reg_sequence imx415_mode_2_720[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x07F0 },
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
@ -217,7 +462,7 @@ static const struct imx415_reg imx415_mode_2_720[] = {
};
/* all-pixel 2-lane 1440 Mbps 30.01 Hz mode */
static const struct imx415_reg imx415_mode_2_1440[] = {
static const struct cci_reg_sequence imx415_mode_2_1440[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x042A },
{ IMX415_LANEMODE, IMX415_LANEMODE_2 },
@ -233,7 +478,7 @@ static const struct imx415_reg imx415_mode_2_1440[] = {
};
/* all-pixel 4-lane 891 Mbps 30 Hz mode */
static const struct imx415_reg imx415_mode_4_891[] = {
static const struct cci_reg_sequence imx415_mode_4_891[] = {
{ IMX415_VMAX, 0x08CA },
{ IMX415_HMAX, 0x044C },
{ IMX415_LANEMODE, IMX415_LANEMODE_4 },
@ -250,7 +495,7 @@ static const struct imx415_reg imx415_mode_4_891[] = {
struct imx415_mode_reg_list {
u32 num_of_regs;
const struct imx415_reg *regs;
const struct cci_reg_sequence *regs;
};
/*
@ -323,11 +568,6 @@ static const struct imx415_mode supported_modes[] = {
},
};
static const struct regmap_config imx415_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
};
static const char *const imx415_test_pattern_menu[] = {
"disabled",
"solid black",
@ -369,7 +609,7 @@ struct imx415 {
* This table includes fixed register settings and a bunch of undocumented
* registers that have to be set to another value than default.
*/
static const struct imx415_reg imx415_init_table[] = {
static const struct cci_reg_sequence imx415_init_table[] = {
/* use all-pixel readout mode, no flip */
{ IMX415_WINMODE, 0x00 },
{ IMX415_ADDMODE, 0x00 },
@ -382,77 +622,77 @@ static const struct imx415_reg imx415_init_table[] = {
{ IMX415_DRV, 0x00 },
/* SONY magic registers */
{ IMX415_REG_8BIT(0x32D4), 0x21 },
{ IMX415_REG_8BIT(0x32EC), 0xA1 },
{ IMX415_REG_8BIT(0x3452), 0x7F },
{ IMX415_REG_8BIT(0x3453), 0x03 },
{ IMX415_REG_8BIT(0x358A), 0x04 },
{ IMX415_REG_8BIT(0x35A1), 0x02 },
{ IMX415_REG_8BIT(0x36BC), 0x0C },
{ IMX415_REG_8BIT(0x36CC), 0x53 },
{ IMX415_REG_8BIT(0x36CD), 0x00 },
{ IMX415_REG_8BIT(0x36CE), 0x3C },
{ IMX415_REG_8BIT(0x36D0), 0x8C },
{ IMX415_REG_8BIT(0x36D1), 0x00 },
{ IMX415_REG_8BIT(0x36D2), 0x71 },
{ IMX415_REG_8BIT(0x36D4), 0x3C },
{ IMX415_REG_8BIT(0x36D6), 0x53 },
{ IMX415_REG_8BIT(0x36D7), 0x00 },
{ IMX415_REG_8BIT(0x36D8), 0x71 },
{ IMX415_REG_8BIT(0x36DA), 0x8C },
{ IMX415_REG_8BIT(0x36DB), 0x00 },
{ IMX415_REG_8BIT(0x3724), 0x02 },
{ IMX415_REG_8BIT(0x3726), 0x02 },
{ IMX415_REG_8BIT(0x3732), 0x02 },
{ IMX415_REG_8BIT(0x3734), 0x03 },
{ IMX415_REG_8BIT(0x3736), 0x03 },
{ IMX415_REG_8BIT(0x3742), 0x03 },
{ IMX415_REG_8BIT(0x3862), 0xE0 },
{ IMX415_REG_8BIT(0x38CC), 0x30 },
{ IMX415_REG_8BIT(0x38CD), 0x2F },
{ IMX415_REG_8BIT(0x395C), 0x0C },
{ IMX415_REG_8BIT(0x3A42), 0xD1 },
{ IMX415_REG_8BIT(0x3A4C), 0x77 },
{ IMX415_REG_8BIT(0x3AE0), 0x02 },
{ IMX415_REG_8BIT(0x3AEC), 0x0C },
{ IMX415_REG_8BIT(0x3B00), 0x2E },
{ IMX415_REG_8BIT(0x3B06), 0x29 },
{ IMX415_REG_8BIT(0x3B98), 0x25 },
{ IMX415_REG_8BIT(0x3B99), 0x21 },
{ IMX415_REG_8BIT(0x3B9B), 0x13 },
{ IMX415_REG_8BIT(0x3B9C), 0x13 },
{ IMX415_REG_8BIT(0x3B9D), 0x13 },
{ IMX415_REG_8BIT(0x3B9E), 0x13 },
{ IMX415_REG_8BIT(0x3BA1), 0x00 },
{ IMX415_REG_8BIT(0x3BA2), 0x06 },
{ IMX415_REG_8BIT(0x3BA3), 0x0B },
{ IMX415_REG_8BIT(0x3BA4), 0x10 },
{ IMX415_REG_8BIT(0x3BA5), 0x14 },
{ IMX415_REG_8BIT(0x3BA6), 0x18 },
{ IMX415_REG_8BIT(0x3BA7), 0x1A },
{ IMX415_REG_8BIT(0x3BA8), 0x1A },
{ IMX415_REG_8BIT(0x3BA9), 0x1A },
{ IMX415_REG_8BIT(0x3BAC), 0xED },
{ IMX415_REG_8BIT(0x3BAD), 0x01 },
{ IMX415_REG_8BIT(0x3BAE), 0xF6 },
{ IMX415_REG_8BIT(0x3BAF), 0x02 },
{ IMX415_REG_8BIT(0x3BB0), 0xA2 },
{ IMX415_REG_8BIT(0x3BB1), 0x03 },
{ IMX415_REG_8BIT(0x3BB2), 0xE0 },
{ IMX415_REG_8BIT(0x3BB3), 0x03 },
{ IMX415_REG_8BIT(0x3BB4), 0xE0 },
{ IMX415_REG_8BIT(0x3BB5), 0x03 },
{ IMX415_REG_8BIT(0x3BB6), 0xE0 },
{ IMX415_REG_8BIT(0x3BB7), 0x03 },
{ IMX415_REG_8BIT(0x3BB8), 0xE0 },
{ IMX415_REG_8BIT(0x3BBA), 0xE0 },
{ IMX415_REG_8BIT(0x3BBC), 0xDA },
{ IMX415_REG_8BIT(0x3BBE), 0x88 },
{ IMX415_REG_8BIT(0x3BC0), 0x44 },
{ IMX415_REG_8BIT(0x3BC2), 0x7B },
{ IMX415_REG_8BIT(0x3BC4), 0xA2 },
{ IMX415_REG_8BIT(0x3BC8), 0xBD },
{ IMX415_REG_8BIT(0x3BCA), 0xBD },
{ CCI_REG8(0x32D4), 0x21 },
{ CCI_REG8(0x32EC), 0xA1 },
{ CCI_REG8(0x3452), 0x7F },
{ CCI_REG8(0x3453), 0x03 },
{ CCI_REG8(0x358A), 0x04 },
{ CCI_REG8(0x35A1), 0x02 },
{ CCI_REG8(0x36BC), 0x0C },
{ CCI_REG8(0x36CC), 0x53 },
{ CCI_REG8(0x36CD), 0x00 },
{ CCI_REG8(0x36CE), 0x3C },
{ CCI_REG8(0x36D0), 0x8C },
{ CCI_REG8(0x36D1), 0x00 },
{ CCI_REG8(0x36D2), 0x71 },
{ CCI_REG8(0x36D4), 0x3C },
{ CCI_REG8(0x36D6), 0x53 },
{ CCI_REG8(0x36D7), 0x00 },
{ CCI_REG8(0x36D8), 0x71 },
{ CCI_REG8(0x36DA), 0x8C },
{ CCI_REG8(0x36DB), 0x00 },
{ CCI_REG8(0x3724), 0x02 },
{ CCI_REG8(0x3726), 0x02 },
{ CCI_REG8(0x3732), 0x02 },
{ CCI_REG8(0x3734), 0x03 },
{ CCI_REG8(0x3736), 0x03 },
{ CCI_REG8(0x3742), 0x03 },
{ CCI_REG8(0x3862), 0xE0 },
{ CCI_REG8(0x38CC), 0x30 },
{ CCI_REG8(0x38CD), 0x2F },
{ CCI_REG8(0x395C), 0x0C },
{ CCI_REG8(0x3A42), 0xD1 },
{ CCI_REG8(0x3A4C), 0x77 },
{ CCI_REG8(0x3AE0), 0x02 },
{ CCI_REG8(0x3AEC), 0x0C },
{ CCI_REG8(0x3B00), 0x2E },
{ CCI_REG8(0x3B06), 0x29 },
{ CCI_REG8(0x3B98), 0x25 },
{ CCI_REG8(0x3B99), 0x21 },
{ CCI_REG8(0x3B9B), 0x13 },
{ CCI_REG8(0x3B9C), 0x13 },
{ CCI_REG8(0x3B9D), 0x13 },
{ CCI_REG8(0x3B9E), 0x13 },
{ CCI_REG8(0x3BA1), 0x00 },
{ CCI_REG8(0x3BA2), 0x06 },
{ CCI_REG8(0x3BA3), 0x0B },
{ CCI_REG8(0x3BA4), 0x10 },
{ CCI_REG8(0x3BA5), 0x14 },
{ CCI_REG8(0x3BA6), 0x18 },
{ CCI_REG8(0x3BA7), 0x1A },
{ CCI_REG8(0x3BA8), 0x1A },
{ CCI_REG8(0x3BA9), 0x1A },
{ CCI_REG8(0x3BAC), 0xED },
{ CCI_REG8(0x3BAD), 0x01 },
{ CCI_REG8(0x3BAE), 0xF6 },
{ CCI_REG8(0x3BAF), 0x02 },
{ CCI_REG8(0x3BB0), 0xA2 },
{ CCI_REG8(0x3BB1), 0x03 },
{ CCI_REG8(0x3BB2), 0xE0 },
{ CCI_REG8(0x3BB3), 0x03 },
{ CCI_REG8(0x3BB4), 0xE0 },
{ CCI_REG8(0x3BB5), 0x03 },
{ CCI_REG8(0x3BB6), 0xE0 },
{ CCI_REG8(0x3BB7), 0x03 },
{ CCI_REG8(0x3BB8), 0xE0 },
{ CCI_REG8(0x3BBA), 0xE0 },
{ CCI_REG8(0x3BBC), 0xDA },
{ CCI_REG8(0x3BBE), 0x88 },
{ CCI_REG8(0x3BC0), 0x44 },
{ CCI_REG8(0x3BC2), 0x7B },
{ CCI_REG8(0x3BC4), 0xA2 },
{ CCI_REG8(0x3BC8), 0xBD },
{ CCI_REG8(0x3BCA), 0xBD },
};
static inline struct imx415 *to_imx415(struct v4l2_subdev *sd)
@ -460,74 +700,26 @@ static inline struct imx415 *to_imx415(struct v4l2_subdev *sd)
return container_of(sd, struct imx415, subdev);
}
static int imx415_read(struct imx415 *sensor, u32 addr)
{
u8 data[3] = { 0 };
int ret;
ret = regmap_raw_read(sensor->regmap, addr & IMX415_REG_ADDR_MASK, data,
(addr >> IMX415_REG_SIZE_SHIFT) & 3);
if (ret < 0)
return ret;
return (data[2] << 16) | (data[1] << 8) | data[0];
}
static int imx415_write(struct imx415 *sensor, u32 addr, u32 value)
{
u8 data[3] = { value & 0xff, (value >> 8) & 0xff, value >> 16 };
int ret;
ret = regmap_raw_write(sensor->regmap, addr & IMX415_REG_ADDR_MASK,
data, (addr >> IMX415_REG_SIZE_SHIFT) & 3);
if (ret < 0)
dev_err_ratelimited(sensor->dev,
"%u-bit write to 0x%04x failed: %d\n",
((addr >> IMX415_REG_SIZE_SHIFT) & 3) * 8,
addr & IMX415_REG_ADDR_MASK, ret);
return 0;
}
static int imx415_set_testpattern(struct imx415 *sensor, int val)
{
int ret;
int ret = 0;
if (val) {
ret = imx415_write(sensor, IMX415_BLKLEVEL, 0x00);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x01);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TPG_PATSEL_DUOUT, val - 1);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TPG_COLORWIDTH, 0x01);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x20);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x00);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x00);
cci_write(sensor->regmap, IMX415_BLKLEVEL, 0x00, &ret);
cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x01, &ret);
cci_write(sensor->regmap, IMX415_TPG_PATSEL_DUOUT,
val - 1, &ret);
cci_write(sensor->regmap, IMX415_TPG_COLORWIDTH, 0x01, &ret);
cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x20, &ret);
cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x00, &ret);
cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x00, &ret);
} else {
ret = imx415_write(sensor, IMX415_BLKLEVEL,
IMX415_BLKLEVEL_DEFAULT);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TPG_EN_DUOUT, 0x00);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_TESTCLKEN_MIPI, 0x00);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_DIG_CLP_MODE, 0x01);
if (ret)
return ret;
ret = imx415_write(sensor, IMX415_WRJ_OPEN, 0x01);
cci_write(sensor->regmap, IMX415_BLKLEVEL,
IMX415_BLKLEVEL_DEFAULT, &ret);
cci_write(sensor->regmap, IMX415_TPG_EN_DUOUT, 0x00, &ret);
cci_write(sensor->regmap, IMX415_TESTCLKEN_MIPI, 0x00, &ret);
cci_write(sensor->regmap, IMX415_DIG_CLP_MODE, 0x01, &ret);
cci_write(sensor->regmap, IMX415_WRJ_OPEN, 0x01, &ret);
}
return 0;
}
@ -553,19 +745,21 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl)
/* clamp the exposure value to VMAX. */
vmax = format->height + sensor->vblank->cur.val;
ctrl->val = min_t(int, ctrl->val, vmax);
ret = imx415_write(sensor, IMX415_SHR0, vmax - ctrl->val);
ret = cci_write(sensor->regmap, IMX415_SHR0,
vmax - ctrl->val, NULL);
break;
case V4L2_CID_ANALOGUE_GAIN:
/* analogue gain in 0.3 dB step size */
ret = imx415_write(sensor, IMX415_GAIN_PCG_0, ctrl->val);
ret = cci_write(sensor->regmap, IMX415_GAIN_PCG_0,
ctrl->val, NULL);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
flip = (sensor->hflip->val << IMX415_HREVERSE_SHIFT) |
(sensor->vflip->val << IMX415_VREVERSE_SHIFT);
ret = imx415_write(sensor, IMX415_REVERSE, flip);
ret = cci_write(sensor->regmap, IMX415_REVERSE, flip, NULL);
break;
case V4L2_CID_TEST_PATTERN:
@ -679,8 +873,6 @@ static int imx415_ctrls_init(struct imx415 *sensor)
static int imx415_set_mode(struct imx415 *sensor, int mode)
{
const struct imx415_reg *reg;
unsigned int i;
int ret = 0;
if (mode >= ARRAY_SIZE(supported_modes)) {
@ -688,34 +880,29 @@ static int imx415_set_mode(struct imx415 *sensor, int mode)
return -EINVAL;
}
for (i = 0; i < supported_modes[mode].reg_list.num_of_regs; ++i) {
reg = &supported_modes[mode].reg_list.regs[i];
ret = imx415_write(sensor, reg->address, reg->val);
if (ret)
return ret;
}
cci_multi_reg_write(sensor->regmap,
supported_modes[mode].reg_list.regs,
supported_modes[mode].reg_list.num_of_regs,
&ret);
for (i = 0; i < IMX415_NUM_CLK_PARAM_REGS; ++i) {
reg = &sensor->clk_params->regs[i];
ret = imx415_write(sensor, reg->address, reg->val);
if (ret)
return ret;
}
cci_multi_reg_write(sensor->regmap,
sensor->clk_params->regs,
IMX415_NUM_CLK_PARAM_REGS,
&ret);
return 0;
}
static int imx415_setup(struct imx415 *sensor, struct v4l2_subdev_state *state)
{
unsigned int i;
int ret;
for (i = 0; i < ARRAY_SIZE(imx415_init_table); ++i) {
ret = imx415_write(sensor, imx415_init_table[i].address,
imx415_init_table[i].val);
ret = cci_multi_reg_write(sensor->regmap,
imx415_init_table,
ARRAY_SIZE(imx415_init_table),
NULL);
if (ret)
return ret;
}
return imx415_set_mode(sensor, sensor->cur_mode);
}
@ -724,7 +911,8 @@ static int imx415_wakeup(struct imx415 *sensor)
{
int ret;
ret = imx415_write(sensor, IMX415_MODE, IMX415_MODE_OPERATING);
ret = cci_write(sensor->regmap, IMX415_MODE,
IMX415_MODE_OPERATING, NULL);
if (ret)
return ret;
@ -743,21 +931,18 @@ static int imx415_stream_on(struct imx415 *sensor)
int ret;
ret = imx415_wakeup(sensor);
if (ret)
return ret;
return imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_START);
return cci_write(sensor->regmap, IMX415_XMSTA,
IMX415_XMSTA_START, &ret);
}
static int imx415_stream_off(struct imx415 *sensor)
{
int ret;
ret = imx415_write(sensor, IMX415_XMSTA, IMX415_XMSTA_STOP);
if (ret)
return ret;
return imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY);
ret = cci_write(sensor->regmap, IMX415_XMSTA,
IMX415_XMSTA_STOP, NULL);
return cci_write(sensor->regmap, IMX415_MODE,
IMX415_MODE_STANDBY, &ret);
}
static int imx415_s_stream(struct v4l2_subdev *sd, int enable)
@ -992,6 +1177,7 @@ static void imx415_power_off(struct imx415 *sensor)
static int imx415_identify_model(struct imx415 *sensor)
{
int model, ret;
u64 chip_id;
/*
* While most registers can be read when the sensor is in standby, this
@ -1002,14 +1188,14 @@ static int imx415_identify_model(struct imx415 *sensor)
return dev_err_probe(sensor->dev, ret,
"failed to get sensor out of standby\n");
ret = imx415_read(sensor, IMX415_SENSOR_INFO);
ret = cci_read(sensor->regmap, IMX415_SENSOR_INFO, &chip_id, NULL);
if (ret < 0) {
dev_err_probe(sensor->dev, ret,
"failed to read sensor information\n");
goto done;
}
model = ret & IMX415_SENSOR_INFO_MASK;
model = chip_id & IMX415_SENSOR_INFO_MASK;
switch (model) {
case IMX415_CHIP_ID:
@ -1024,7 +1210,7 @@ static int imx415_identify_model(struct imx415 *sensor)
ret = 0;
done:
imx415_write(sensor, IMX415_MODE, IMX415_MODE_STANDBY);
cci_write(sensor->regmap, IMX415_MODE, IMX415_MODE_STANDBY, &ret);
return ret;
}
@ -1173,7 +1359,7 @@ static int imx415_probe(struct i2c_client *client)
if (ret)
return ret;
sensor->regmap = devm_regmap_init_i2c(client, &imx415_regmap_config);
sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(sensor->regmap))
return PTR_ERR(sensor->regmap);

View File

@ -1337,7 +1337,7 @@ static const struct regmap_config isl7998x_regmap = {
.rd_table = &isl7998x_readable_table,
.wr_table = &isl7998x_writeable_table,
.volatile_table = &isl7998x_volatile_table,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
static int isl7998x_mc_init(struct isl7998x *isl7998x)

View File

@ -257,7 +257,7 @@ static const struct regmap_config max2175_regmap_config = {
.reg_defaults = max2175_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(max2175_reg_defaults),
.volatile_table = &max2175_volatile_regs,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
struct max2175 {

View File

@ -309,23 +309,15 @@ static void msp_wake_thread(struct i2c_client *client)
wake_up_interruptible(&state->wq);
}
int msp_sleep(struct msp_state *state, int timeout)
int msp_sleep(struct msp_state *state, int msec)
{
DECLARE_WAITQUEUE(wait, current);
long timeout;
add_wait_queue(&state->wq, &wait);
if (!kthread_should_stop()) {
if (timeout < 0) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
} else {
schedule_timeout_interruptible
(msecs_to_jiffies(timeout));
}
}
timeout = msec < 0 ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(msec);
wait_event_freezable_timeout(state->wq, kthread_should_stop() ||
state->restart, timeout);
remove_wait_queue(&state->wq, &wait);
try_to_freeze();
return state->restart;
}

View File

@ -134,7 +134,7 @@ int msp_read_dsp(struct i2c_client *client, int addr);
int msp_reset(struct i2c_client *client);
void msp_set_scart(struct i2c_client *client, int in, int out);
void msp_update_volume(struct msp_state *state);
int msp_sleep(struct msp_state *state, int timeout);
int msp_sleep(struct msp_state *state, int msec);
/* msp3400-kthreads.c */
const char *msp_standard_std_name(int std);

View File

@ -1078,7 +1078,7 @@ mt9p031_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;

View File

@ -988,7 +988,7 @@ static const struct regmap_config mt9v032_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = 0xff,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
/* -----------------------------------------------------------------------------
@ -1006,7 +1006,7 @@ mt9v032_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!np)
return NULL;

File diff suppressed because it is too large Load Diff

View File

@ -1388,7 +1388,7 @@ ov2659_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;

View File

@ -118,7 +118,6 @@ static inline struct ov5645 *to_ov5645(struct v4l2_subdev *sd)
static const struct reg_value ov5645_global_init_setting[] = {
{ 0x3103, 0x11 },
{ 0x3008, 0x82 },
{ 0x3008, 0x42 },
{ 0x3103, 0x03 },
{ 0x3503, 0x07 },
@ -627,6 +626,10 @@ static int ov5645_set_register_array(struct ov5645 *ov5645,
ret = ov5645_write_reg(ov5645, settings->reg, settings->val);
if (ret < 0)
return ret;
if (settings->reg == OV5645_SYSTEM_CTRL0 &&
settings->val == OV5645_SYSTEM_CTRL0_START)
usleep_range(1000, 2000);
}
return 0;
@ -1056,7 +1059,7 @@ static int ov5645_probe(struct i2c_client *client)
ov5645->i2c_client = client;
ov5645->dev = dev;
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
if (!endpoint) {
dev_err(dev, "endpoint node not found\n");
return -EINVAL;

View File

@ -1363,7 +1363,7 @@ static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np)
struct device_node *ep;
int ret;
ep = of_graph_get_next_endpoint(np, NULL);
ep = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!ep)
return -EINVAL;

View File

@ -1568,7 +1568,7 @@ static int s5c73m3_get_dt_data(struct s5c73m3 *state)
"failed to request gpio S5C73M3_RST\n");
gpiod_set_consumer_name(state->reset, "S5C73M3_RST");
node_ep = of_graph_get_next_endpoint(node, NULL);
node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
dev_warn(dev, "no endpoint defined for node: %pOF\n", node);
return 0;

View File

@ -1849,7 +1849,7 @@ static int s5k5baf_parse_device_node(struct s5k5baf *state, struct device *dev)
state->mclk_frequency);
}
node_ep = of_graph_get_next_endpoint(node, NULL);
node_ep = of_graph_get_endpoint_by_regs(node, 0, -1);
if (!node_ep) {
dev_err(dev, "no endpoint defined at node %pOF\n", node);
return -EINVAL;

View File

@ -12,6 +12,7 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/units.h>
@ -19,79 +20,74 @@
#include <media/mipi-csi2.h>
#include <media/v4l2-async.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#define VGXY61_REG_8BIT(n) ((1 << 16) | (n))
#define VGXY61_REG_16BIT(n) ((2 << 16) | (n))
#define VGXY61_REG_32BIT(n) ((4 << 16) | (n))
#define VGXY61_REG_SIZE_SHIFT 16
#define VGXY61_REG_ADDR_MASK 0xffff
#define VGXY61_REG_MODEL_ID VGXY61_REG_16BIT(0x0000)
#define VGXY61_REG_MODEL_ID CCI_REG16_LE(0x0000)
#define VG5661_MODEL_ID 0x5661
#define VG5761_MODEL_ID 0x5761
#define VGXY61_REG_REVISION VGXY61_REG_16BIT(0x0002)
#define VGXY61_REG_FWPATCH_REVISION VGXY61_REG_16BIT(0x0014)
#define VGXY61_REG_FWPATCH_START_ADDR VGXY61_REG_8BIT(0x2000)
#define VGXY61_REG_SYSTEM_FSM VGXY61_REG_8BIT(0x0020)
#define VGXY61_REG_REVISION CCI_REG16_LE(0x0002)
#define VGXY61_REG_FWPATCH_REVISION CCI_REG16_LE(0x0014)
#define VGXY61_REG_FWPATCH_START_ADDR CCI_REG8(0x2000)
#define VGXY61_REG_SYSTEM_FSM CCI_REG8(0x0020)
#define VGXY61_SYSTEM_FSM_SW_STBY 0x03
#define VGXY61_SYSTEM_FSM_STREAMING 0x04
#define VGXY61_REG_NVM VGXY61_REG_8BIT(0x0023)
#define VGXY61_REG_NVM CCI_REG8(0x0023)
#define VGXY61_NVM_OK 0x04
#define VGXY61_REG_STBY VGXY61_REG_8BIT(0x0201)
#define VGXY61_REG_STBY CCI_REG8(0x0201)
#define VGXY61_STBY_NO_REQ 0
#define VGXY61_STBY_REQ_TMP_READ BIT(2)
#define VGXY61_REG_STREAMING VGXY61_REG_8BIT(0x0202)
#define VGXY61_REG_STREAMING CCI_REG8(0x0202)
#define VGXY61_STREAMING_NO_REQ 0
#define VGXY61_STREAMING_REQ_STOP BIT(0)
#define VGXY61_STREAMING_REQ_START BIT(1)
#define VGXY61_REG_EXT_CLOCK VGXY61_REG_32BIT(0x0220)
#define VGXY61_REG_CLK_PLL_PREDIV VGXY61_REG_8BIT(0x0224)
#define VGXY61_REG_CLK_SYS_PLL_MULT VGXY61_REG_8BIT(0x0225)
#define VGXY61_REG_GPIO_0_CTRL VGXY61_REG_8BIT(0x0236)
#define VGXY61_REG_GPIO_1_CTRL VGXY61_REG_8BIT(0x0237)
#define VGXY61_REG_GPIO_2_CTRL VGXY61_REG_8BIT(0x0238)
#define VGXY61_REG_GPIO_3_CTRL VGXY61_REG_8BIT(0x0239)
#define VGXY61_REG_SIGNALS_POLARITY_CTRL VGXY61_REG_8BIT(0x023b)
#define VGXY61_REG_LINE_LENGTH VGXY61_REG_16BIT(0x0300)
#define VGXY61_REG_ORIENTATION VGXY61_REG_8BIT(0x0302)
#define VGXY61_REG_VT_CTRL VGXY61_REG_8BIT(0x0304)
#define VGXY61_REG_FORMAT_CTRL VGXY61_REG_8BIT(0x0305)
#define VGXY61_REG_OIF_CTRL VGXY61_REG_16BIT(0x0306)
#define VGXY61_REG_OIF_ROI0_CTRL VGXY61_REG_8BIT(0x030a)
#define VGXY61_REG_ROI0_START_H VGXY61_REG_16BIT(0x0400)
#define VGXY61_REG_ROI0_START_V VGXY61_REG_16BIT(0x0402)
#define VGXY61_REG_ROI0_END_H VGXY61_REG_16BIT(0x0404)
#define VGXY61_REG_ROI0_END_V VGXY61_REG_16BIT(0x0406)
#define VGXY61_REG_PATGEN_CTRL VGXY61_REG_32BIT(0x0440)
#define VGXY61_REG_EXT_CLOCK CCI_REG32_LE(0x0220)
#define VGXY61_REG_CLK_PLL_PREDIV CCI_REG8(0x0224)
#define VGXY61_REG_CLK_SYS_PLL_MULT CCI_REG8(0x0225)
#define VGXY61_REG_GPIO_0_CTRL CCI_REG8(0x0236)
#define VGXY61_REG_GPIO_1_CTRL CCI_REG8(0x0237)
#define VGXY61_REG_GPIO_2_CTRL CCI_REG8(0x0238)
#define VGXY61_REG_GPIO_3_CTRL CCI_REG8(0x0239)
#define VGXY61_REG_SIGNALS_POLARITY_CTRL CCI_REG8(0x023b)
#define VGXY61_REG_LINE_LENGTH CCI_REG16_LE(0x0300)
#define VGXY61_REG_ORIENTATION CCI_REG8(0x0302)
#define VGXY61_REG_VT_CTRL CCI_REG8(0x0304)
#define VGXY61_REG_FORMAT_CTRL CCI_REG8(0x0305)
#define VGXY61_REG_OIF_CTRL CCI_REG16_LE(0x0306)
#define VGXY61_REG_OIF_ROI0_CTRL CCI_REG8(0x030a)
#define VGXY61_REG_ROI0_START_H CCI_REG16_LE(0x0400)
#define VGXY61_REG_ROI0_START_V CCI_REG16_LE(0x0402)
#define VGXY61_REG_ROI0_END_H CCI_REG16_LE(0x0404)
#define VGXY61_REG_ROI0_END_V CCI_REG16_LE(0x0406)
#define VGXY61_REG_PATGEN_CTRL CCI_REG32_LE(0x0440)
#define VGXY61_PATGEN_LONG_ENABLE BIT(16)
#define VGXY61_PATGEN_SHORT_ENABLE BIT(0)
#define VGXY61_PATGEN_LONG_TYPE_SHIFT 18
#define VGXY61_PATGEN_SHORT_TYPE_SHIFT 4
#define VGXY61_REG_FRAME_CONTENT_CTRL VGXY61_REG_8BIT(0x0478)
#define VGXY61_REG_COARSE_EXPOSURE_LONG VGXY61_REG_16BIT(0x0500)
#define VGXY61_REG_COARSE_EXPOSURE_SHORT VGXY61_REG_16BIT(0x0504)
#define VGXY61_REG_ANALOG_GAIN VGXY61_REG_8BIT(0x0508)
#define VGXY61_REG_DIGITAL_GAIN_LONG VGXY61_REG_16BIT(0x050a)
#define VGXY61_REG_DIGITAL_GAIN_SHORT VGXY61_REG_16BIT(0x0512)
#define VGXY61_REG_FRAME_LENGTH VGXY61_REG_16BIT(0x051a)
#define VGXY61_REG_SIGNALS_CTRL VGXY61_REG_16BIT(0x0522)
#define VGXY61_REG_FRAME_CONTENT_CTRL CCI_REG8(0x0478)
#define VGXY61_REG_COARSE_EXPOSURE_LONG CCI_REG16_LE(0x0500)
#define VGXY61_REG_COARSE_EXPOSURE_SHORT CCI_REG16_LE(0x0504)
#define VGXY61_REG_ANALOG_GAIN CCI_REG8(0x0508)
#define VGXY61_REG_DIGITAL_GAIN_LONG CCI_REG16_LE(0x050a)
#define VGXY61_REG_DIGITAL_GAIN_SHORT CCI_REG16_LE(0x0512)
#define VGXY61_REG_FRAME_LENGTH CCI_REG16_LE(0x051a)
#define VGXY61_REG_SIGNALS_CTRL CCI_REG16_LE(0x0522)
#define VGXY61_SIGNALS_GPIO_ID_SHIFT 4
#define VGXY61_REG_READOUT_CTRL VGXY61_REG_8BIT(0x0530)
#define VGXY61_REG_HDR_CTRL VGXY61_REG_8BIT(0x0532)
#define VGXY61_REG_PATGEN_LONG_DATA_GR VGXY61_REG_16BIT(0x092c)
#define VGXY61_REG_PATGEN_LONG_DATA_R VGXY61_REG_16BIT(0x092e)
#define VGXY61_REG_PATGEN_LONG_DATA_B VGXY61_REG_16BIT(0x0930)
#define VGXY61_REG_PATGEN_LONG_DATA_GB VGXY61_REG_16BIT(0x0932)
#define VGXY61_REG_PATGEN_SHORT_DATA_GR VGXY61_REG_16BIT(0x0950)
#define VGXY61_REG_PATGEN_SHORT_DATA_R VGXY61_REG_16BIT(0x0952)
#define VGXY61_REG_PATGEN_SHORT_DATA_B VGXY61_REG_16BIT(0x0954)
#define VGXY61_REG_PATGEN_SHORT_DATA_GB VGXY61_REG_16BIT(0x0956)
#define VGXY61_REG_BYPASS_CTRL VGXY61_REG_8BIT(0x0a60)
#define VGXY61_REG_READOUT_CTRL CCI_REG8(0x0530)
#define VGXY61_REG_HDR_CTRL CCI_REG8(0x0532)
#define VGXY61_REG_PATGEN_LONG_DATA_GR CCI_REG16_LE(0x092c)
#define VGXY61_REG_PATGEN_LONG_DATA_R CCI_REG16_LE(0x092e)
#define VGXY61_REG_PATGEN_LONG_DATA_B CCI_REG16_LE(0x0930)
#define VGXY61_REG_PATGEN_LONG_DATA_GB CCI_REG16_LE(0x0932)
#define VGXY61_REG_PATGEN_SHORT_DATA_GR CCI_REG16_LE(0x0950)
#define VGXY61_REG_PATGEN_SHORT_DATA_R CCI_REG16_LE(0x0952)
#define VGXY61_REG_PATGEN_SHORT_DATA_B CCI_REG16_LE(0x0954)
#define VGXY61_REG_PATGEN_SHORT_DATA_GB CCI_REG16_LE(0x0956)
#define VGXY61_REG_BYPASS_CTRL CCI_REG8(0x0a60)
#define VGX661_WIDTH 1464
#define VGX661_HEIGHT 1104
@ -384,6 +380,7 @@ static const struct vgxy61_mode_info vgx761_mode_data[] = {
struct vgxy61_dev {
struct i2c_client *i2c_client;
struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
struct regulator_bulk_data supplies[ARRAY_SIZE(vgxy61_supply_name)];
@ -510,82 +507,6 @@ static unsigned int get_chunk_size(struct vgxy61_dev *sensor)
return max(max_write_len, 1);
}
static int vgxy61_read_multiple(struct vgxy61_dev *sensor, u32 reg,
unsigned int len)
{
struct i2c_client *client = sensor->i2c_client;
struct i2c_msg msg[2];
u8 buf[2];
u8 val[sizeof(u32)] = {0};
int ret;
if (len > sizeof(u32))
return -EINVAL;
buf[0] = reg >> 8;
buf[1] = reg & 0xff;
msg[0].addr = client->addr;
msg[0].flags = client->flags;
msg[0].buf = buf;
msg[0].len = sizeof(buf);
msg[1].addr = client->addr;
msg[1].flags = client->flags | I2C_M_RD;
msg[1].buf = val;
msg[1].len = len;
ret = i2c_transfer(client->adapter, msg, 2);
if (ret < 0) {
dev_dbg(&client->dev, "%s: %x i2c_transfer, reg: %x => %d\n",
__func__, client->addr, reg, ret);
return ret;
}
return get_unaligned_le32(val);
}
static inline int vgxy61_read_reg(struct vgxy61_dev *sensor, u32 reg)
{
return vgxy61_read_multiple(sensor, reg & VGXY61_REG_ADDR_MASK,
(reg >> VGXY61_REG_SIZE_SHIFT) & 7);
}
static int vgxy61_write_multiple(struct vgxy61_dev *sensor, u32 reg,
const u8 *data, unsigned int len, int *err)
{
struct i2c_client *client = sensor->i2c_client;
struct i2c_msg msg;
u8 buf[VGXY61_WRITE_MULTIPLE_CHUNK_MAX + 2];
unsigned int i;
int ret;
if (err && *err)
return *err;
if (len > VGXY61_WRITE_MULTIPLE_CHUNK_MAX)
return -EINVAL;
buf[0] = reg >> 8;
buf[1] = reg & 0xff;
for (i = 0; i < len; i++)
buf[i + 2] = data[i];
msg.addr = client->addr;
msg.flags = client->flags;
msg.buf = buf;
msg.len = len + 2;
ret = i2c_transfer(client->adapter, &msg, 1);
if (ret < 0) {
dev_dbg(&client->dev, "%s: i2c_transfer, reg: %x => %d\n",
__func__, reg, ret);
if (err)
*err = ret;
return ret;
}
return 0;
}
static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
unsigned int nb, const u8 *array)
{
@ -595,7 +516,8 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
while (nb) {
sz = min(nb, chunk_size);
ret = vgxy61_write_multiple(sensor, reg, array, sz, NULL);
ret = regmap_bulk_write(sensor->regmap, CCI_REG_ADDR(reg),
array, sz);
if (ret < 0)
return ret;
nb -= sz;
@ -606,24 +528,17 @@ static int vgxy61_write_array(struct vgxy61_dev *sensor, u32 reg,
return 0;
}
static inline int vgxy61_write_reg(struct vgxy61_dev *sensor, u32 reg, u32 val,
int *err)
{
return vgxy61_write_multiple(sensor, reg & VGXY61_REG_ADDR_MASK,
(u8 *)&val,
(reg >> VGXY61_REG_SIZE_SHIFT) & 7, err);
}
static int vgxy61_poll_reg(struct vgxy61_dev *sensor, u32 reg, u8 poll_val,
unsigned int timeout_ms)
{
const unsigned int loop_delay_ms = 10;
u64 val;
int ret;
return read_poll_timeout(vgxy61_read_reg, ret,
((ret < 0) || (ret == poll_val)),
return read_poll_timeout(cci_read, ret,
((ret < 0) || (val == poll_val)),
loop_delay_ms * 1000, timeout_ms * 1000,
false, sensor, reg);
false, sensor->regmap, reg, &val, NULL);
}
static int vgxy61_wait_state(struct vgxy61_dev *sensor, int state,
@ -662,10 +577,10 @@ static int vgxy61_apply_exposure(struct vgxy61_dev *sensor)
int ret = 0;
/* We first set expo to zero to avoid forbidden parameters couple */
vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_LONG,
cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT, 0, &ret);
cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_LONG,
sensor->expo_long, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_COARSE_EXPOSURE_SHORT,
cci_write(sensor->regmap, VGXY61_REG_COARSE_EXPOSURE_SHORT,
sensor->expo_short, &ret);
return ret;
@ -714,7 +629,7 @@ static int vgxy61_try_fmt_internal(struct v4l2_subdev *sd,
const struct vgxy61_mode_info **new_mode)
{
struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
const struct vgxy61_mode_info *mode = sensor->sensor_modes;
const struct vgxy61_mode_info *mode;
unsigned int index;
for (index = 0; index < ARRAY_SIZE(vgxy61_supported_codes); index++) {
@ -827,7 +742,7 @@ static int vgxy61_update_analog_gain(struct vgxy61_dev *sensor, u32 target)
sensor->analog_gain = target;
if (sensor->streaming)
return vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN, target,
return cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN, target,
NULL);
return 0;
}
@ -842,9 +757,9 @@ static int vgxy61_apply_digital_gain(struct vgxy61_dev *sensor,
* DIGITAL_GAIN_SHORT_CH0 is enough to configure the gain of all
* four sub pixels.
*/
vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain,
cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_LONG, digital_gain,
&ret);
vgxy61_write_reg(sensor, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain,
cci_write(sensor->regmap, VGXY61_REG_DIGITAL_GAIN_SHORT, digital_gain,
&ret);
return ret;
@ -870,7 +785,7 @@ static int vgxy61_apply_patgen(struct vgxy61_dev *sensor, u32 index)
if (pattern)
reg |= VGXY61_PATGEN_LONG_ENABLE | VGXY61_PATGEN_SHORT_ENABLE;
return vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_CTRL, reg, NULL);
return cci_write(sensor->regmap, VGXY61_REG_PATGEN_CTRL, reg, NULL);
}
static int vgxy61_update_patgen(struct vgxy61_dev *sensor, u32 pattern)
@ -887,15 +802,13 @@ static int vgxy61_apply_gpiox_strobe_mode(struct vgxy61_dev *sensor,
unsigned int idx)
{
static const u8 index2val[] = {0x0, 0x1, 0x3};
int reg;
u16 mask, val;
reg = vgxy61_read_reg(sensor, VGXY61_REG_SIGNALS_CTRL);
if (reg < 0)
return reg;
reg &= ~(0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT));
reg |= index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
mask = 0xf << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
val = index2val[mode] << (idx * VGXY61_SIGNALS_GPIO_ID_SHIFT);
return vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_CTRL, reg, NULL);
return cci_update_bits(sensor->regmap, VGXY61_REG_SIGNALS_CTRL,
mask, val, NULL);
}
static int vgxy61_update_gpios_strobe_mode(struct vgxy61_dev *sensor,
@ -940,11 +853,11 @@ static int vgxy61_update_gpios_strobe_polarity(struct vgxy61_dev *sensor,
if (sensor->streaming)
return -EBUSY;
vgxy61_write_reg(sensor, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity,
cci_write(sensor->regmap, VGXY61_REG_GPIO_0_CTRL, polarity << 1, &ret);
cci_write(sensor->regmap, VGXY61_REG_GPIO_1_CTRL, polarity << 1, &ret);
cci_write(sensor->regmap, VGXY61_REG_GPIO_2_CTRL, polarity << 1, &ret);
cci_write(sensor->regmap, VGXY61_REG_GPIO_3_CTRL, polarity << 1, &ret);
cci_write(sensor->regmap, VGXY61_REG_SIGNALS_POLARITY_CTRL, polarity,
&ret);
return ret;
@ -1057,7 +970,7 @@ static int vgxy61_update_exposure(struct vgxy61_dev *sensor, u16 new_expo_long,
static int vgxy61_apply_framelength(struct vgxy61_dev *sensor)
{
return vgxy61_write_reg(sensor, VGXY61_REG_FRAME_LENGTH,
return cci_write(sensor->regmap, VGXY61_REG_FRAME_LENGTH,
sensor->frame_length, NULL);
}
@ -1086,7 +999,7 @@ static int vgxy61_apply_hdr(struct vgxy61_dev *sensor,
{
static const u8 index2val[] = {0x1, 0x4, 0xa};
return vgxy61_write_reg(sensor, VGXY61_REG_HDR_CTRL, index2val[index],
return cci_write(sensor->regmap, VGXY61_REG_HDR_CTRL, index2val[index],
NULL);
}
@ -1133,7 +1046,7 @@ static int vgxy61_apply_settings(struct vgxy61_dev *sensor)
if (ret)
return ret;
ret = vgxy61_write_reg(sensor, VGXY61_REG_ANALOG_GAIN,
ret = cci_write(sensor->regmap, VGXY61_REG_ANALOG_GAIN,
sensor->analog_gain, NULL);
if (ret)
return ret;
@ -1141,7 +1054,7 @@ static int vgxy61_apply_settings(struct vgxy61_dev *sensor)
if (ret)
return ret;
ret = vgxy61_write_reg(sensor, VGXY61_REG_ORIENTATION,
ret = cci_write(sensor->regmap, VGXY61_REG_ORIENTATION,
sensor->hflip | (sensor->vflip << 1), NULL);
if (ret)
return ret;
@ -1174,18 +1087,18 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor)
if (ret)
return ret;
vgxy61_write_reg(sensor, VGXY61_REG_FORMAT_CTRL,
cci_write(sensor->regmap, VGXY61_REG_FORMAT_CTRL,
get_bpp_by_code(sensor->fmt.code), &ret);
vgxy61_write_reg(sensor, VGXY61_REG_OIF_ROI0_CTRL,
cci_write(sensor->regmap, VGXY61_REG_OIF_ROI0_CTRL,
get_data_type_by_code(sensor->fmt.code), &ret);
vgxy61_write_reg(sensor, VGXY61_REG_READOUT_CTRL,
cci_write(sensor->regmap, VGXY61_REG_READOUT_CTRL,
sensor->current_mode->bin_mode, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_H, crop->left, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_H,
cci_write(sensor->regmap, VGXY61_REG_ROI0_START_H, crop->left, &ret);
cci_write(sensor->regmap, VGXY61_REG_ROI0_END_H,
crop->left + crop->width - 1, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_ROI0_START_V, crop->top, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_ROI0_END_V,
cci_write(sensor->regmap, VGXY61_REG_ROI0_START_V, crop->top, &ret);
cci_write(sensor->regmap, VGXY61_REG_ROI0_END_V,
crop->top + crop->height - 1, &ret);
if (ret)
goto err_rpm_put;
@ -1194,7 +1107,7 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor)
if (ret)
goto err_rpm_put;
ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING,
ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING,
VGXY61_STREAMING_REQ_START, NULL);
if (ret)
goto err_rpm_put;
@ -1225,7 +1138,7 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor)
struct i2c_client *client = v4l2_get_subdevdata(&sensor->sd);
int ret;
ret = vgxy61_write_reg(sensor, VGXY61_REG_STREAMING,
ret = cci_write(sensor->regmap, VGXY61_REG_STREAMING,
VGXY61_STREAMING_REQ_STOP, NULL);
if (ret)
goto err_str_dis;
@ -1582,7 +1495,7 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
{
u32 sensor_freq;
u8 prediv, mult;
int line_length;
u64 line_length;
int ret = 0;
compute_pll_parameters_by_freq(sensor->clk_freq, &prediv, &mult);
@ -1592,28 +1505,28 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
/* Video timing ISP path (pixel clock) requires 804/5 mhz = 160 mhz */
sensor->pclk = sensor_freq / 5;
line_length = vgxy61_read_reg(sensor, VGXY61_REG_LINE_LENGTH);
if (line_length < 0)
return line_length;
sensor->line_length = line_length;
vgxy61_write_reg(sensor, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_BYPASS_CTRL, 4, &ret);
cci_read(sensor->regmap, VGXY61_REG_LINE_LENGTH, &line_length, &ret);
if (ret < 0)
return ret;
sensor->line_length = (u16)line_length;
cci_write(sensor->regmap, VGXY61_REG_EXT_CLOCK, sensor->clk_freq, &ret);
cci_write(sensor->regmap, VGXY61_REG_CLK_PLL_PREDIV, prediv, &ret);
cci_write(sensor->regmap, VGXY61_REG_CLK_SYS_PLL_MULT, mult, &ret);
cci_write(sensor->regmap, VGXY61_REG_OIF_CTRL, sensor->oif_ctrl, &ret);
cci_write(sensor->regmap, VGXY61_REG_FRAME_CONTENT_CTRL, 0, &ret);
cci_write(sensor->regmap, VGXY61_REG_BYPASS_CTRL, 4, &ret);
if (ret)
return ret;
vgxy61_update_gpios_strobe_polarity(sensor, sensor->gpios_polarity);
/* Set pattern generator solid to middle value */
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret);
vgxy61_write_reg(sensor, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GR, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_R, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_B, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_LONG_DATA_GB, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GR, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_R, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_B, 0x800, &ret);
cci_write(sensor->regmap, VGXY61_REG_PATGEN_SHORT_DATA_GB, 0x800, &ret);
if (ret)
return ret;
@ -1623,37 +1536,33 @@ static int vgxy61_configure(struct vgxy61_dev *sensor)
static int vgxy61_patch(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
int patch, ret;
u64 patch;
int ret;
ret = vgxy61_write_array(sensor, VGXY61_REG_FWPATCH_START_ADDR,
sizeof(patch_array), patch_array);
if (ret)
return ret;
ret = vgxy61_write_reg(sensor, VGXY61_REG_STBY, 0x10, NULL);
cci_write(sensor->regmap, VGXY61_REG_STBY, 0x10, &ret);
if (ret)
return ret;
ret = vgxy61_poll_reg(sensor, VGXY61_REG_STBY, 0, VGXY61_TIMEOUT_MS);
if (ret)
cci_read(sensor->regmap, VGXY61_REG_FWPATCH_REVISION, &patch, &ret);
if (ret < 0)
return ret;
patch = vgxy61_read_reg(sensor, VGXY61_REG_FWPATCH_REVISION);
if (patch < 0)
return patch;
if (patch != (VGXY61_FWPATCH_REVISION_MAJOR << 12) +
(VGXY61_FWPATCH_REVISION_MINOR << 8) +
VGXY61_FWPATCH_REVISION_MICRO) {
dev_err(&client->dev, "bad patch version expected %d.%d.%d got %d.%d.%d\n",
dev_err(&client->dev,
"bad patch version expected %d.%d.%d got %u.%u.%u\n",
VGXY61_FWPATCH_REVISION_MAJOR,
VGXY61_FWPATCH_REVISION_MINOR,
VGXY61_FWPATCH_REVISION_MICRO,
patch >> 12, (patch >> 8) & 0x0f, patch & 0xff);
(u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff);
return -ENODEV;
}
dev_dbg(&client->dev, "patch %d.%d.%d applied\n",
patch >> 12, (patch >> 8) & 0x0f, patch & 0xff);
dev_dbg(&client->dev, "patch %u.%u.%u applied\n",
(u16)patch >> 12, ((u16)patch >> 8) & 0x0f, (u16)patch & 0xff);
return 0;
}
@ -1661,11 +1570,12 @@ static int vgxy61_patch(struct vgxy61_dev *sensor)
static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
int device_rev;
u64 device_rev;
int ret;
device_rev = vgxy61_read_reg(sensor, VGXY61_REG_REVISION);
if (device_rev < 0)
return device_rev;
ret = cci_read(sensor->regmap, VGXY61_REG_REVISION, &device_rev, NULL);
if (ret < 0)
return ret;
switch (device_rev >> 8) {
case 0xA:
@ -1687,17 +1597,17 @@ static int vgxy61_detect_cut_version(struct vgxy61_dev *sensor)
static int vgxy61_detect(struct vgxy61_dev *sensor)
{
struct i2c_client *client = sensor->i2c_client;
int id = 0;
int ret, st;
u64 st, id = 0;
int ret;
id = vgxy61_read_reg(sensor, VGXY61_REG_MODEL_ID);
if (id < 0)
return id;
ret = cci_read(sensor->regmap, VGXY61_REG_MODEL_ID, &id, NULL);
if (ret < 0)
return ret;
if (id != VG5661_MODEL_ID && id != VG5761_MODEL_ID) {
dev_warn(&client->dev, "Unsupported sensor id %x\n", id);
dev_warn(&client->dev, "Unsupported sensor id %x\n", (u16)id);
return -ENODEV;
}
dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", id);
dev_dbg(&client->dev, "detected sensor id = 0x%04x\n", (u16)id);
sensor->id = id;
ret = vgxy61_wait_state(sensor, VGXY61_SYSTEM_FSM_SW_STBY,
@ -1705,11 +1615,11 @@ static int vgxy61_detect(struct vgxy61_dev *sensor)
if (ret)
return ret;
st = vgxy61_read_reg(sensor, VGXY61_REG_NVM);
if (st < 0)
ret = cci_read(sensor->regmap, VGXY61_REG_NVM, &st, NULL);
if (ret < 0)
return st;
if (st != VGXY61_NVM_OK)
dev_warn(&client->dev, "Bad nvm state got %d\n", st);
dev_warn(&client->dev, "Bad nvm state got %u\n", (u8)st);
ret = vgxy61_detect_cut_version(sensor);
if (ret)
@ -1832,6 +1742,12 @@ static int vgxy61_probe(struct i2c_client *client)
sensor->analog_gain = 0;
sensor->digital_gain = 256;
sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
if (IS_ERR(sensor->regmap)) {
ret = PTR_ERR(sensor->regmap);
return dev_err_probe(dev, ret, "Failed to init regmap\n");
}
handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
if (!handle) {
dev_err(dev, "handle node not found\n");

View File

@ -1895,7 +1895,7 @@ static int tc358743_probe_of(struct tc358743_state *state)
return dev_err_probe(dev, PTR_ERR(refclk),
"failed to get refclk\n");
ep = of_graph_get_next_endpoint(dev->of_node, NULL);
ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
if (!ep) {
dev_err(dev, "missing endpoint node\n");
return -EINVAL;

View File

@ -843,14 +843,14 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746,
if (fin < 4 * HZ_PER_MHZ || fin > 40 * HZ_PER_MHZ)
continue;
tmp = fout * p * postdiv;
tmp = fout * postdiv;
do_div(tmp, fin);
mul = tmp;
if (mul > 511)
continue;
tmp = mul * fin;
do_div(tmp, p * postdiv);
do_div(tmp, postdiv);
delta = abs(fout - tmp);
if (delta < min_delta) {

View File

@ -2310,7 +2310,7 @@ static int tda1997x_parse_dt(struct tda1997x_state *state)
pdata->vidout_sel_de = DE_FREF_SEL_DE_VHREF;
np = state->client->dev.of_node;
ep = of_graph_get_next_endpoint(np, NULL);
ep = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!ep)
return -EINVAL;

View File

@ -987,7 +987,7 @@ tvp514x_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;

View File

@ -1817,7 +1817,7 @@ static struct regmap_config tvp5150_config = {
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.rd_table = &tvp5150_readable_table,
.volatile_reg = tvp5150_volatile_reg,

View File

@ -893,7 +893,7 @@ tvp7002_get_pdata(struct i2c_client *client)
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
return client->dev.platform_data;
endpoint = of_graph_get_next_endpoint(client->dev.of_node, NULL);
endpoint = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
if (!endpoint)
return NULL;

View File

@ -63,7 +63,7 @@ static void media_devnode_release(struct device *cd)
pr_debug("%s: Media Devnode Deallocated\n", __func__);
}
static struct bus_type media_bus_type = {
static const struct bus_type media_bus_type = {
.name = MEDIA_NAME,
};
@ -190,7 +190,6 @@ static int media_release(struct inode *inode, struct file *filp)
return value is ignored. */
put_device(&devnode->dev);
pr_debug("%s: Media Release\n", __func__);
return 0;
}

View File

@ -535,14 +535,15 @@ static int media_pipeline_walk_push(struct media_pipeline_walk *walk,
/*
* Move the top entry link cursor to the next link. If all links of the entry
* have been visited, pop the entry itself.
* have been visited, pop the entry itself. Return true if the entry has been
* popped.
*/
static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk)
{
struct media_pipeline_walk_entry *entry;
if (WARN_ON(walk->stack.top < 0))
return;
return false;
entry = media_pipeline_walk_top(walk);
@ -552,7 +553,7 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
walk->stack.top);
walk->stack.top--;
return;
return true;
}
entry->links = entry->links->next;
@ -560,6 +561,8 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
dev_dbg(walk->mdev->dev,
"media pipeline: moved entry %u to next link\n",
walk->stack.top);
return false;
}
/* Free all memory allocated while walking the pipeline. */
@ -605,30 +608,24 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
struct media_pipeline_walk *walk)
{
struct media_pipeline_walk_entry *entry = media_pipeline_walk_top(walk);
struct media_pad *pad;
struct media_pad *origin;
struct media_link *link;
struct media_pad *local;
struct media_pad *remote;
bool last_link;
int ret;
pad = entry->pad;
origin = entry->pad;
link = list_entry(entry->links, typeof(*link), list);
media_pipeline_walk_pop(walk);
last_link = media_pipeline_walk_pop(walk);
dev_dbg(walk->mdev->dev,
"media pipeline: exploring link '%s':%u -> '%s':%u\n",
link->source->entity->name, link->source->index,
link->sink->entity->name, link->sink->index);
/* Skip links that are not enabled. */
if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (disabled)\n");
return 0;
}
/* Get the local pad and remote pad. */
if (link->source->entity == pad->entity) {
if (link->source->entity == origin->entity) {
local = link->source;
remote = link->sink;
} else {
@ -640,25 +637,64 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
* Skip links that originate from a different pad than the incoming pad
* that is not connected internally in the entity to the incoming pad.
*/
if (pad != local &&
!media_entity_has_pad_interdep(pad->entity, pad->index, local->index)) {
if (origin != local &&
!media_entity_has_pad_interdep(origin->entity, origin->index,
local->index)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (no route)\n");
return 0;
goto done;
}
/*
* Add the local and remote pads of the link to the pipeline and push
* them to the stack, if they're not already present.
* Add the local pad of the link to the pipeline and push it to the
* stack, if not already present.
*/
ret = media_pipeline_add_pad(pipe, walk, local);
if (ret)
return ret;
/* Similarly, add the remote pad, but only if the link is enabled. */
if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (disabled)\n");
goto done;
}
ret = media_pipeline_add_pad(pipe, walk, remote);
if (ret)
return ret;
done:
/*
* If we're done iterating over links, iterate over pads of the entity.
* This is necessary to discover pads that are not connected with any
* link. Those are dead ends from a pipeline exploration point of view,
* but are still part of the pipeline and need to be added to enable
* proper validation.
*/
if (!last_link)
return 0;
dev_dbg(walk->mdev->dev,
"media pipeline: adding unconnected pads of '%s'\n",
local->entity->name);
media_entity_for_each_pad(origin->entity, local) {
/*
* Skip the origin pad (already handled), pad that have links
* (already discovered through iterating over links) and pads
* not internally connected.
*/
if (origin == local || !local->num_links ||
!media_entity_has_pad_interdep(origin->entity, origin->index,
local->index))
continue;
ret = media_pipeline_add_pad(pipe, walk, local);
if (ret)
return ret;
}
return 0;
}
@ -770,7 +806,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
struct media_pad *pad = ppad->pad;
struct media_entity *entity = pad->entity;
bool has_enabled_link = false;
bool has_link = false;
struct media_link *link;
dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name,
@ -800,7 +835,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
/* Record if the pad has links and enabled links. */
if (link->flags & MEDIA_LNK_FL_ENABLED)
has_enabled_link = true;
has_link = true;
/*
* Validate the link if it's enabled and has the
@ -838,7 +872,7 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
* 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set,
* ensure that it has either no link or an enabled link.
*/
if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link &&
if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) &&
!has_enabled_link) {
dev_dbg(mdev->dev,
"Pad '%s':%u must be connected by an enabled link\n",
@ -1038,6 +1072,9 @@ static void __media_entity_remove_link(struct media_entity *entity,
/* Remove the reverse links for a data link. */
if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) {
link->source->num_links--;
link->sink->num_links--;
if (link->source->entity == entity)
remote = link->sink->entity;
else
@ -1092,6 +1129,11 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
struct media_link *link;
struct media_link *backlink;
if (flags & MEDIA_LNK_FL_LINK_TYPE)
return -EINVAL;
flags |= MEDIA_LNK_FL_DATA_LINK;
if (WARN_ON(!source || !sink) ||
WARN_ON(source_pad >= source->num_pads) ||
WARN_ON(sink_pad >= sink->num_pads))
@ -1107,7 +1149,7 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
link->source = &source->pads[source_pad];
link->sink = &sink->pads[sink_pad];
link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;
link->flags = flags;
/* Initialize graph object embedded at the new link */
media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
@ -1138,6 +1180,9 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
sink->num_links++;
source->num_links++;
link->source->num_links++;
link->sink->num_links++;
return 0;
}
EXPORT_SYMBOL_GPL(media_create_pad_link);

View File

@ -55,7 +55,7 @@ static void bttv_sub_remove(struct device *dev)
sub->remove(sdev);
}
struct bus_type bttv_sub_bus_type = {
const struct bus_type bttv_sub_bus_type = {
.name = "bttv-sub",
.match = &bttv_sub_bus_match,
.probe = bttv_sub_probe,

View File

@ -234,7 +234,7 @@ int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f);
/* ---------------------------------------------------------- */
/* bttv-gpio.c */
extern struct bus_type bttv_sub_bus_type;
extern const struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core);

View File

@ -1354,6 +1354,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* register Video device */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_video_template, "video");
if (!dev->video_dev) {
err = -ENOMEM;
goto fail_unreg;
}
dev->video_dev->queue = &dev->vb2_vidq;
dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;
@ -1382,6 +1386,10 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* register VBI device */
dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
&cx23885_vbi_template, "vbi");
if (!dev->vbi_dev) {
err = -ENOMEM;
goto fail_unreg;
}
dev->vbi_dev->queue = &dev->vb2_vbiq;
dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE;

View File

@ -162,7 +162,6 @@
* @height: frame height
* @input: current input
* @sequence: frame counter
* @stats: statistics structure
* @regs: local copy of mmio base register
* @csr2: local copy of csr2 register
* @config: local copy of config register

View File

@ -2,6 +2,7 @@
/* Author: Dan Scally <djrscally@gmail.com> */
#include <linux/acpi.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/mei_cl_bus.h>
@ -60,6 +61,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = {
IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
/* GalaxyCore GC0310 */
IPU_SENSOR_CONFIG("INT0310", 0),
/* Omnivision ov01a10 */
IPU_SENSOR_CONFIG("OVTI01A0", 1, 400000000),
};
static const struct ipu_property_names prop_names = {
@ -747,6 +750,24 @@ static int ipu_bridge_ivsc_is_ready(void)
return ready;
}
static int ipu_bridge_check_fwnode_graph(struct fwnode_handle *fwnode)
{
struct fwnode_handle *endpoint;
if (IS_ERR_OR_NULL(fwnode))
return -EINVAL;
endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (endpoint) {
fwnode_handle_put(endpoint);
return 0;
}
return ipu_bridge_check_fwnode_graph(fwnode->secondary);
}
static DEFINE_MUTEX(ipu_bridge_mutex);
int ipu_bridge_init(struct device *dev,
ipu_parse_sensor_fwnode_t parse_sensor_fwnode)
{
@ -755,6 +776,11 @@ int ipu_bridge_init(struct device *dev,
unsigned int i;
int ret;
guard(mutex)(&ipu_bridge_mutex);
if (!ipu_bridge_check_fwnode_graph(dev_fwnode(dev)))
return 0;
if (!ipu_bridge_ivsc_is_ready())
return -EPROBE_DEFER;

View File

@ -28,6 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-dma-sg.h>
@ -1407,7 +1408,6 @@ static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
{
struct cio2_device *cio2 = to_cio2_device(notifier);
struct device *dev = &cio2->pci_dev->dev;
struct sensor_async_subdev *s_asd;
struct v4l2_async_connection *asd;
struct cio2_queue *q;
@ -1417,25 +1417,12 @@ static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
s_asd = to_sensor_asd(asd);
q = &cio2->queue[s_asd->csi2.port];
ret = media_entity_get_fwnode_pad(&q->sensor->entity,
s_asd->asd.match.fwnode,
MEDIA_PAD_FL_SOURCE);
if (ret < 0) {
dev_err(dev, "no pad for endpoint %pfw (%d)\n",
s_asd->asd.match.fwnode, ret);
ret = v4l2_create_fwnode_links_to_pad(asd->sd,
&q->subdev_pads[CIO2_PAD_SINK], 0);
if (ret)
return ret;
}
ret = media_create_pad_link(&q->sensor->entity, ret,
&q->subdev.entity, CIO2_PAD_SINK,
0);
if (ret) {
dev_err(dev, "failed to create link for %s (endpoint %pfw, error %d)\n",
q->sensor->name, s_asd->asd.match.fwnode, ret);
return ret;
}
}
return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
}
@ -1572,6 +1559,7 @@ static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q)
v4l2_subdev_init(subdev, &cio2_subdev_ops);
subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
subdev->owner = THIS_MODULE;
subdev->dev = dev;
snprintf(subdev->name, sizeof(subdev->name),
CIO2_ENTITY_NAME " %td", q - cio2->queue);
subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
@ -1679,29 +1667,12 @@ static void cio2_queues_exit(struct cio2_device *cio2)
cio2_queue_exit(cio2, &cio2->queue[i]);
}
static int cio2_check_fwnode_graph(struct fwnode_handle *fwnode)
{
struct fwnode_handle *endpoint;
if (IS_ERR_OR_NULL(fwnode))
return -EINVAL;
endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (endpoint) {
fwnode_handle_put(endpoint);
return 0;
}
return cio2_check_fwnode_graph(fwnode->secondary);
}
/**************** PCI interface ****************/
static int cio2_pci_probe(struct pci_dev *pci_dev,
const struct pci_device_id *id)
{
struct device *dev = &pci_dev->dev;
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct cio2_device *cio2;
int r;
@ -1710,17 +1681,9 @@ static int cio2_pci_probe(struct pci_dev *pci_dev,
* if the device has no endpoints then we can try to build those as
* software_nodes parsed from SSDB.
*/
r = cio2_check_fwnode_graph(fwnode);
if (r) {
if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) {
dev_err(dev, "fwnode graph has no endpoints connected\n");
return -EINVAL;
}
r = ipu_bridge_init(dev, ipu_bridge_parse_ssdb);
if (r)
return r;
}
cio2 = devm_kzalloc(dev, sizeof(*cio2), GFP_KERNEL);
if (!cio2)

View File

@ -71,8 +71,8 @@ enum ivsc_privacy_status {
};
enum csi_pads {
CSI_PAD_SOURCE,
CSI_PAD_SINK,
CSI_PAD_SOURCE,
CSI_NUM_PADS
};
@ -128,7 +128,6 @@ struct mei_csi {
int streaming;
struct media_pad pads[CSI_NUM_PADS];
struct v4l2_mbus_framefmt format_mbus[CSI_NUM_PADS];
/* number of data lanes used on the CSI-2 link */
u32 nr_of_lanes;
@ -329,58 +328,17 @@ err:
return ret;
}
static struct v4l2_mbus_framefmt *
mei_csi_get_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
unsigned int pad, u32 which)
{
struct mei_csi *csi = sd_to_csi(sd);
switch (which) {
case V4L2_SUBDEV_FORMAT_TRY:
return v4l2_subdev_state_get_format(sd_state, pad);
case V4L2_SUBDEV_FORMAT_ACTIVE:
return &csi->format_mbus[pad];
default:
return NULL;
}
}
static int mei_csi_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state)
{
struct v4l2_mbus_framefmt *mbusformat;
struct mei_csi *csi = sd_to_csi(sd);
unsigned int i;
mutex_lock(&csi->lock);
for (i = 0; i < sd->entity.num_pads; i++) {
mbusformat = v4l2_subdev_state_get_format(sd_state, i);
*mbusformat = mei_csi_format_mbus_default;
}
mutex_unlock(&csi->lock);
return 0;
}
static int mei_csi_get_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{
struct v4l2_mbus_framefmt *mbusformat;
struct mei_csi *csi = sd_to_csi(sd);
mutex_lock(&csi->lock);
mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
format->which);
if (mbusformat)
format->format = *mbusformat;
mutex_unlock(&csi->lock);
return 0;
}
@ -388,20 +346,17 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
{
struct v4l2_mbus_framefmt *source_mbusformat;
struct v4l2_mbus_framefmt *mbusformat;
struct mei_csi *csi = sd_to_csi(sd);
struct media_pad *pad;
struct v4l2_mbus_framefmt *source_fmt;
struct v4l2_mbus_framefmt *sink_fmt;
mbusformat = mei_csi_get_pad_format(sd, sd_state, format->pad,
format->which);
if (!mbusformat)
return -EINVAL;
sink_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SINK);
source_fmt = v4l2_subdev_state_get_format(sd_state, CSI_PAD_SOURCE);
source_mbusformat = mei_csi_get_pad_format(sd, sd_state, CSI_PAD_SOURCE,
format->which);
if (!source_mbusformat)
return -EINVAL;
if (format->pad) {
*source_fmt = *sink_fmt;
return 0;
}
v4l_bound_align_image(&format->format.width, 1, 65536, 0,
&format->format.height, 1, 65536, 0, 0);
@ -504,18 +459,8 @@ static int mei_csi_set_fmt(struct v4l2_subdev *sd,
if (format->format.field == V4L2_FIELD_ANY)
format->format.field = V4L2_FIELD_NONE;
mutex_lock(&csi->lock);
pad = &csi->pads[format->pad];
if (pad->flags & MEDIA_PAD_FL_SOURCE)
format->format = csi->format_mbus[CSI_PAD_SINK];
*mbusformat = format->format;
if (pad->flags & MEDIA_PAD_FL_SINK)
*source_mbusformat = format->format;
mutex_unlock(&csi->lock);
*sink_fmt = format->format;
*source_fmt = *sink_fmt;
return 0;
}
@ -554,7 +499,7 @@ static const struct v4l2_subdev_video_ops mei_csi_video_ops = {
};
static const struct v4l2_subdev_pad_ops mei_csi_pad_ops = {
.get_fmt = mei_csi_get_fmt,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = mei_csi_set_fmt,
};
@ -587,7 +532,7 @@ static int mei_csi_notify_bound(struct v4l2_async_notifier *notifier,
csi->remote_pad = pad;
return media_create_pad_link(&subdev->entity, pad,
&csi->subdev.entity, 1,
&csi->subdev.entity, CSI_PAD_SINK,
MEDIA_LNK_FL_ENABLED |
MEDIA_LNK_FL_IMMUTABLE);
}
@ -749,6 +694,7 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
goto err_disable;
csi->subdev.dev = &cldev->dev;
csi->subdev.state_lock = &csi->lock;
v4l2_subdev_init(&csi->subdev, &mei_csi_subdev_ops);
csi->subdev.internal_ops = &mei_csi_internal_ops;
v4l2_set_subdevdata(&csi->subdev, csi);
@ -764,9 +710,6 @@ static int mei_csi_probe(struct mei_cl_device *cldev,
if (ret)
goto err_ctrl_handler;
csi->format_mbus[CSI_PAD_SOURCE] = mei_csi_format_mbus_default;
csi->format_mbus[CSI_PAD_SINK] = mei_csi_format_mbus_default;
csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
ret = media_entity_pads_init(&csi->subdev.entity, CSI_NUM_PADS,

View File

@ -757,7 +757,7 @@ static const struct video_device video_dev_template = {
/**
* vip_irq - interrupt routine
* @irq: Number of interrupt ( not used, correct number is assumed )
* @vip: local data structure containing all information
* @data: local data structure containing all information
*
* check for both frame interrupts set ( top and bottom ).
* check FIFO overflow, but limit number of log messages after open.
@ -767,8 +767,9 @@ static const struct video_device video_dev_template = {
*
* IRQ_HANDLED, interrupt done.
*/
static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
static irqreturn_t vip_irq(int irq, void *data)
{
struct sta2x11_vip *vip = data;
unsigned int status;
status = reg_read(vip, DVP_ITS);
@ -1053,9 +1054,7 @@ static int sta2x11_vip_init_one(struct pci_dev *pdev,
spin_lock_init(&vip->slock);
ret = request_irq(pdev->irq,
(irq_handler_t) vip_irq,
IRQF_SHARED, KBUILD_MODNAME, vip);
ret = request_irq(pdev->irq, vip_irq, IRQF_SHARED, KBUILD_MODNAME, vip);
if (ret) {
dev_err(&pdev->dev, "request_irq failed\n");
ret = -ENODEV;

View File

@ -1463,7 +1463,8 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
budget_av->has_saa7113 = 1;
err = saa7146_vv_init(dev, &vv_data);
if (err != 0) {
/* fixme: proper cleanup here */
ttpci_budget_deinit(&budget_av->budget);
kfree(budget_av);
ERR("cannot init vv subsystem\n");
return err;
}
@ -1472,9 +1473,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
/* fixme: proper cleanup here */
ERR("cannot register capture v4l2 device\n");
saa7146_vv_release(dev);
ttpci_budget_deinit(&budget_av->budget);
kfree(budget_av);
ERR("cannot register capture v4l2 device\n");
return err;
}

View File

@ -1595,8 +1595,10 @@ static int vdec_stop_session(struct vpu_inst *inst, u32 type)
if (V4L2_TYPE_IS_OUTPUT(type)) {
vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
vdec->drain = 0;
vdec_abort(inst);
} else {
if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {
if (vb2_is_streaming(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx)))
vdec_abort(inst);
vdec->eos_received = 0;
}

View File

@ -834,7 +834,7 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
isi->pdata.full_mode = 1;
isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL;
np = of_graph_get_next_endpoint(np, NULL);
np = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!np) {
dev_err(&pdev->dev, "Could not find the endpoint\n");
return -EINVAL;
@ -1158,7 +1158,7 @@ static int isi_graph_init(struct atmel_isi *isi)
struct device_node *ep;
int ret;
ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
ep = of_graph_get_endpoint_by_regs(isi->dev->of_node, 0, -1);
if (!ep)
return -EINVAL;

View File

@ -114,10 +114,14 @@ static const struct csi2rx_fmt formats[] = {
{ .code = MEDIA_BUS_FMT_SGBRG8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SGRBG8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SRGGB8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_Y8_1X8, .bpp = 8, },
{ .code = MEDIA_BUS_FMT_SBGGR10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SGBRG10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SGRBG10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_SRGGB10_1X10, .bpp = 10, },
{ .code = MEDIA_BUS_FMT_RGB565_1X16, .bpp = 16, },
{ .code = MEDIA_BUS_FMT_RGB888_1X24, .bpp = 24, },
{ .code = MEDIA_BUS_FMT_BGR888_1X24, .bpp = 24, },
};
static const struct csi2rx_fmt *csi2rx_get_fmt_by_code(u32 code)
@ -389,6 +393,18 @@ out:
return ret;
}
static int csi2rx_enum_mbus_code(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_mbus_code_enum *code_enum)
{
if (code_enum->index >= ARRAY_SIZE(formats))
return -EINVAL;
code_enum->code = formats[code_enum->index].code;
return 0;
}
static int csi2rx_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
@ -439,6 +455,7 @@ static int csi2rx_init_state(struct v4l2_subdev *subdev,
}
static const struct v4l2_subdev_pad_ops csi2rx_pad_ops = {
.enum_mbus_code = csi2rx_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = csi2rx_set_fmt,
};
@ -468,7 +485,7 @@ static int csi2rx_async_bound(struct v4l2_async_notifier *notifier,
struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
s_subdev->fwnode,
asd->match.fwnode,
MEDIA_PAD_FL_SOURCE);
if (csi2rx->source_pad < 0) {
dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n",

View File

@ -2315,7 +2315,7 @@ static bool wave5_vpu_enc_check_common_param_valid(struct vpu_instance *inst,
param->intra_refresh_mode);
return false;
}
};
}
return true;
invalid_refresh_argument:

View File

@ -92,7 +92,7 @@ static int switch_state(struct vpu_instance *inst, enum vpu_instance_state state
break;
case VPU_INST_STATE_STOP:
break;
};
}
dev_dbg(inst->dev->dev, "Switch state from %s to %s.\n",
state_to_str(inst->state), state_to_str(state));

View File

@ -250,7 +250,7 @@ err_clk_dis:
return ret;
}
static int wave5_vpu_remove(struct platform_device *pdev)
static void wave5_vpu_remove(struct platform_device *pdev)
{
struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
@ -262,8 +262,6 @@ static int wave5_vpu_remove(struct platform_device *pdev)
v4l2_device_unregister(&dev->v4l2_dev);
wave5_vdi_release(&pdev->dev);
ida_destroy(&dev->inst_ida);
return 0;
}
static const struct wave5_match_data ti_wave521c_data = {
@ -283,7 +281,7 @@ static struct platform_driver wave5_vpu_driver = {
.of_match_table = of_match_ptr(wave5_dt_ids),
},
.probe = wave5_vpu_probe,
.remove = wave5_vpu_remove,
.remove_new = wave5_vpu_remove,
};
module_platform_driver(wave5_vpu_driver);

View File

@ -2207,7 +2207,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
pcdev->mclk = mclk_rate;
}
np = of_graph_get_next_endpoint(np, NULL);
np = of_graph_get_endpoint_by_regs(np, 0, -1);
if (!np) {
dev_err(dev, "could not find endpoint\n");
return -EINVAL;

View File

@ -7,6 +7,7 @@ config VIDEO_CAFE_CCIC
depends on V4L_PLATFORM_DRIVERS
depends on PCI && I2C && VIDEO_DEV
depends on COMMON_CLK
select V4L2_ASYNC
select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
@ -24,6 +25,7 @@ config VIDEO_MMP_CAMERA
depends on COMMON_CLK
select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR
select I2C_GPIO
select V4L2_ASYNC
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_DMA_SG

View File

@ -144,7 +144,6 @@ struct mtk_jpegdec_clk {
* @jpegenc_irq: jpeg encode irq num
* @job_timeout_work: encode timeout workqueue
* @hw_param: jpeg encode hw parameters
* @hw_rdy: record hw ready
* @hw_state: record hw state
* @hw_lock: spinlock protecting the hw device resource
*/

View File

@ -26,7 +26,7 @@ static void mtk_mdp_vpu_handle_init_ack(const struct mdp_ipi_comm_ack *msg)
vpu->inst_addr = msg->vpu_inst_addr;
}
static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len,
void *priv)
{
const struct mdp_ipi_comm_ack *msg = data;

View File

@ -46,18 +46,114 @@ enum mt8183_mdp_comp_id {
MT8183_MDP_COMP_WROT1, /* 25 */
};
enum mt8195_mdp_comp_id {
/* MT8195 Comp id */
/* ISP */
MT8195_MDP_COMP_WPEI = 0,
MT8195_MDP_COMP_WPEO, /* 1 */
MT8195_MDP_COMP_WPEI2, /* 2 */
MT8195_MDP_COMP_WPEO2, /* 3 */
/* MDP */
MT8195_MDP_COMP_CAMIN, /* 4 */
MT8195_MDP_COMP_CAMIN2, /* 5 */
MT8195_MDP_COMP_SPLIT, /* 6 */
MT8195_MDP_COMP_SPLIT2, /* 7 */
MT8195_MDP_COMP_RDMA0, /* 8 */
MT8195_MDP_COMP_RDMA1, /* 9 */
MT8195_MDP_COMP_RDMA2, /* 10 */
MT8195_MDP_COMP_RDMA3, /* 11 */
MT8195_MDP_COMP_STITCH, /* 12 */
MT8195_MDP_COMP_FG0, /* 13 */
MT8195_MDP_COMP_FG1, /* 14 */
MT8195_MDP_COMP_FG2, /* 15 */
MT8195_MDP_COMP_FG3, /* 16 */
MT8195_MDP_COMP_TO_SVPP2MOUT, /* 17 */
MT8195_MDP_COMP_TO_SVPP3MOUT, /* 18 */
MT8195_MDP_COMP_TO_WARP0MOUT, /* 19 */
MT8195_MDP_COMP_TO_WARP1MOUT, /* 20 */
MT8195_MDP_COMP_VPP0_SOUT, /* 21 */
MT8195_MDP_COMP_VPP1_SOUT, /* 22 */
MT8195_MDP_COMP_PQ0_SOUT, /* 23 */
MT8195_MDP_COMP_PQ1_SOUT, /* 24 */
MT8195_MDP_COMP_HDR0, /* 25 */
MT8195_MDP_COMP_HDR1, /* 26 */
MT8195_MDP_COMP_HDR2, /* 27 */
MT8195_MDP_COMP_HDR3, /* 28 */
MT8195_MDP_COMP_AAL0, /* 29 */
MT8195_MDP_COMP_AAL1, /* 30 */
MT8195_MDP_COMP_AAL2, /* 31 */
MT8195_MDP_COMP_AAL3, /* 32 */
MT8195_MDP_COMP_RSZ0, /* 33 */
MT8195_MDP_COMP_RSZ1, /* 34 */
MT8195_MDP_COMP_RSZ2, /* 35 */
MT8195_MDP_COMP_RSZ3, /* 36 */
MT8195_MDP_COMP_TDSHP0, /* 37 */
MT8195_MDP_COMP_TDSHP1, /* 38 */
MT8195_MDP_COMP_TDSHP2, /* 39 */
MT8195_MDP_COMP_TDSHP3, /* 40 */
MT8195_MDP_COMP_COLOR0, /* 41 */
MT8195_MDP_COMP_COLOR1, /* 42 */
MT8195_MDP_COMP_COLOR2, /* 43 */
MT8195_MDP_COMP_COLOR3, /* 44 */
MT8195_MDP_COMP_OVL0, /* 45 */
MT8195_MDP_COMP_OVL1, /* 46 */
MT8195_MDP_COMP_PAD0, /* 47 */
MT8195_MDP_COMP_PAD1, /* 48 */
MT8195_MDP_COMP_PAD2, /* 49 */
MT8195_MDP_COMP_PAD3, /* 50 */
MT8195_MDP_COMP_TCC0, /* 51 */
MT8195_MDP_COMP_TCC1, /* 52 */
MT8195_MDP_COMP_WROT0, /* 53 */
MT8195_MDP_COMP_WROT1, /* 54 */
MT8195_MDP_COMP_WROT2, /* 55 */
MT8195_MDP_COMP_WROT3, /* 56 */
MT8195_MDP_COMP_MERGE2, /* 57 */
MT8195_MDP_COMP_MERGE3, /* 58 */
MT8195_MDP_COMP_VDO0DL0, /* 59 */
MT8195_MDP_COMP_VDO1DL0, /* 60 */
MT8195_MDP_COMP_VDO0DL1, /* 61 */
MT8195_MDP_COMP_VDO1DL1, /* 62 */
};
static const struct of_device_id mt8183_mdp_probe_infra[MDP_INFRA_MAX] = {
[MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8183-mmsys" },
[MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8183-disp-mutex" },
[MDP_INFRA_SCP] = { .compatible = "mediatek,mt8183-scp" }
};
static const struct of_device_id mt8195_mdp_probe_infra[MDP_INFRA_MAX] = {
[MDP_INFRA_MMSYS] = { .compatible = "mediatek,mt8195-vppsys0" },
[MDP_INFRA_MMSYS2] = { .compatible = "mediatek,mt8195-vppsys1" },
[MDP_INFRA_MUTEX] = { .compatible = "mediatek,mt8195-vpp-mutex" },
[MDP_INFRA_MUTEX2] = { .compatible = "mediatek,mt8195-vpp-mutex" },
[MDP_INFRA_SCP] = { .compatible = "mediatek,mt8195-scp" }
};
static const struct mdp_platform_config mt8183_plat_cfg = {
.rdma_support_10bit = true,
.rdma_rsz1_sram_sharing = true,
.rdma_upsample_repeat_only = true,
.rdma_event_num = 1,
.rsz_disable_dcm_small_sample = false,
.wrot_filter_constraint = false,
.wrot_event_num = 1,
};
static const struct mdp_platform_config mt8195_plat_cfg = {
.rdma_support_10bit = true,
.rdma_rsz1_sram_sharing = false,
.rdma_upsample_repeat_only = false,
.rdma_esl_setting = true,
.rdma_event_num = 4,
.rsz_disable_dcm_small_sample = false,
.rsz_etc_control = true,
.wrot_filter_constraint = false,
.wrot_event_num = 4,
.tdshp_hist_num = 17,
.tdshp_constrain = true,
.tdshp_contour = true,
};
static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
@ -71,81 +167,384 @@ static const u32 mt8183_mutex_idx[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_CCORR0] = MUTEX_MOD_IDX_MDP_CCORR0,
};
static const u32 mt8195_mutex_idx[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_RDMA0] = MUTEX_MOD_IDX_MDP_RDMA0,
[MDP_COMP_RDMA1] = MUTEX_MOD_IDX_MDP_RDMA1,
[MDP_COMP_RDMA2] = MUTEX_MOD_IDX_MDP_RDMA2,
[MDP_COMP_RDMA3] = MUTEX_MOD_IDX_MDP_RDMA3,
[MDP_COMP_STITCH] = MUTEX_MOD_IDX_MDP_STITCH0,
[MDP_COMP_FG0] = MUTEX_MOD_IDX_MDP_FG0,
[MDP_COMP_FG1] = MUTEX_MOD_IDX_MDP_FG1,
[MDP_COMP_FG2] = MUTEX_MOD_IDX_MDP_FG2,
[MDP_COMP_FG3] = MUTEX_MOD_IDX_MDP_FG3,
[MDP_COMP_HDR0] = MUTEX_MOD_IDX_MDP_HDR0,
[MDP_COMP_HDR1] = MUTEX_MOD_IDX_MDP_HDR1,
[MDP_COMP_HDR2] = MUTEX_MOD_IDX_MDP_HDR2,
[MDP_COMP_HDR3] = MUTEX_MOD_IDX_MDP_HDR3,
[MDP_COMP_AAL0] = MUTEX_MOD_IDX_MDP_AAL0,
[MDP_COMP_AAL1] = MUTEX_MOD_IDX_MDP_AAL1,
[MDP_COMP_AAL2] = MUTEX_MOD_IDX_MDP_AAL2,
[MDP_COMP_AAL3] = MUTEX_MOD_IDX_MDP_AAL3,
[MDP_COMP_RSZ0] = MUTEX_MOD_IDX_MDP_RSZ0,
[MDP_COMP_RSZ1] = MUTEX_MOD_IDX_MDP_RSZ1,
[MDP_COMP_RSZ2] = MUTEX_MOD_IDX_MDP_RSZ2,
[MDP_COMP_RSZ3] = MUTEX_MOD_IDX_MDP_RSZ3,
[MDP_COMP_MERGE2] = MUTEX_MOD_IDX_MDP_MERGE2,
[MDP_COMP_MERGE3] = MUTEX_MOD_IDX_MDP_MERGE3,
[MDP_COMP_TDSHP0] = MUTEX_MOD_IDX_MDP_TDSHP0,
[MDP_COMP_TDSHP1] = MUTEX_MOD_IDX_MDP_TDSHP1,
[MDP_COMP_TDSHP2] = MUTEX_MOD_IDX_MDP_TDSHP2,
[MDP_COMP_TDSHP3] = MUTEX_MOD_IDX_MDP_TDSHP3,
[MDP_COMP_COLOR0] = MUTEX_MOD_IDX_MDP_COLOR0,
[MDP_COMP_COLOR1] = MUTEX_MOD_IDX_MDP_COLOR1,
[MDP_COMP_COLOR2] = MUTEX_MOD_IDX_MDP_COLOR2,
[MDP_COMP_COLOR3] = MUTEX_MOD_IDX_MDP_COLOR3,
[MDP_COMP_OVL0] = MUTEX_MOD_IDX_MDP_OVL0,
[MDP_COMP_OVL1] = MUTEX_MOD_IDX_MDP_OVL1,
[MDP_COMP_PAD0] = MUTEX_MOD_IDX_MDP_PAD0,
[MDP_COMP_PAD1] = MUTEX_MOD_IDX_MDP_PAD1,
[MDP_COMP_PAD2] = MUTEX_MOD_IDX_MDP_PAD2,
[MDP_COMP_PAD3] = MUTEX_MOD_IDX_MDP_PAD3,
[MDP_COMP_TCC0] = MUTEX_MOD_IDX_MDP_TCC0,
[MDP_COMP_TCC1] = MUTEX_MOD_IDX_MDP_TCC1,
[MDP_COMP_WROT0] = MUTEX_MOD_IDX_MDP_WROT0,
[MDP_COMP_WROT1] = MUTEX_MOD_IDX_MDP_WROT1,
[MDP_COMP_WROT2] = MUTEX_MOD_IDX_MDP_WROT2,
[MDP_COMP_WROT3] = MUTEX_MOD_IDX_MDP_WROT3,
};
static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_WPEI] = {
{MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI},
{MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO] = {
{MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO},
{MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEI2] = {
{MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2},
{MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO2] = {
{MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2},
{MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_ISP_IMGI] = {
{MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI},
{MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI, MDP_MM_SUBSYS_0},
{0, 0, 4}
},
[MDP_COMP_ISP_IMGO] = {
{MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO},
{MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO, MDP_MM_SUBSYS_0},
{0, 0, 4}
},
[MDP_COMP_ISP_IMG2O] = {
{MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O},
{MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_CAMIN] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN},
{MDP_COMP_TYPE_DL_PATH, 0, MT8183_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0},
{2, 2, 1}
},
[MDP_COMP_CAMIN2] = {
{MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2},
{MDP_COMP_TYPE_DL_PATH, 1, MT8183_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0},
{2, 4, 1}
},
[MDP_COMP_RDMA0] = {
{MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0},
{MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0},
{2, 0, 0}
},
[MDP_COMP_CCORR0] = {
{MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0},
{MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_RSZ0] = {
{MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0},
{MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_RSZ1] = {
{MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1},
{MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_TDSHP0] = {
{MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0},
{MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_PATH0_SOUT] = {
{MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT},
{MDP_COMP_TYPE_PATH, 0, MT8183_MDP_COMP_PATH0_SOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_PATH1_SOUT] = {
{MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT},
{MDP_COMP_TYPE_PATH, 1, MT8183_MDP_COMP_PATH1_SOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WROT0] = {
{MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0},
{MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_WDMA] = {
{MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA},
{MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
};
static const struct mdp_comp_data mt8195_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
[MDP_COMP_WPEI] = {
{MDP_COMP_TYPE_WPEI, 0, MT8195_MDP_COMP_WPEI, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO] = {
{MDP_COMP_TYPE_EXTO, 2, MT8195_MDP_COMP_WPEO, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEI2] = {
{MDP_COMP_TYPE_WPEI, 1, MT8195_MDP_COMP_WPEI2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_WPEO2] = {
{MDP_COMP_TYPE_EXTO, 3, MT8195_MDP_COMP_WPEO2, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_CAMIN] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_CAMIN, MDP_MM_SUBSYS_0},
{3, 3, 0}
},
[MDP_COMP_CAMIN2] = {
{MDP_COMP_TYPE_DL_PATH, 1, MT8195_MDP_COMP_CAMIN2, MDP_MM_SUBSYS_0},
{3, 6, 0}
},
[MDP_COMP_SPLIT] = {
{MDP_COMP_TYPE_SPLIT, 0, MT8195_MDP_COMP_SPLIT, MDP_MM_SUBSYS_1},
{7, 0, 0}
},
[MDP_COMP_SPLIT2] = {
{MDP_COMP_TYPE_SPLIT, 1, MT8195_MDP_COMP_SPLIT2, MDP_MM_SUBSYS_1},
{7, 0, 0}
},
[MDP_COMP_RDMA0] = {
{MDP_COMP_TYPE_RDMA, 0, MT8195_MDP_COMP_RDMA0, MDP_MM_SUBSYS_0},
{3, 0, 0}
},
[MDP_COMP_RDMA1] = {
{MDP_COMP_TYPE_RDMA, 1, MT8195_MDP_COMP_RDMA1, MDP_MM_SUBSYS_1},
{3, 0, 0}
},
[MDP_COMP_RDMA2] = {
{MDP_COMP_TYPE_RDMA, 2, MT8195_MDP_COMP_RDMA2, MDP_MM_SUBSYS_1},
{3, 0, 0}
},
[MDP_COMP_RDMA3] = {
{MDP_COMP_TYPE_RDMA, 3, MT8195_MDP_COMP_RDMA3, MDP_MM_SUBSYS_1},
{3, 0, 0}
},
[MDP_COMP_STITCH] = {
{MDP_COMP_TYPE_STITCH, 0, MT8195_MDP_COMP_STITCH, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_FG0] = {
{MDP_COMP_TYPE_FG, 0, MT8195_MDP_COMP_FG0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_FG1] = {
{MDP_COMP_TYPE_FG, 1, MT8195_MDP_COMP_FG1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_FG2] = {
{MDP_COMP_TYPE_FG, 2, MT8195_MDP_COMP_FG2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_FG3] = {
{MDP_COMP_TYPE_FG, 3, MT8195_MDP_COMP_FG3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_HDR0] = {
{MDP_COMP_TYPE_HDR, 0, MT8195_MDP_COMP_HDR0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_HDR1] = {
{MDP_COMP_TYPE_HDR, 1, MT8195_MDP_COMP_HDR1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_HDR2] = {
{MDP_COMP_TYPE_HDR, 2, MT8195_MDP_COMP_HDR2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_HDR3] = {
{MDP_COMP_TYPE_HDR, 3, MT8195_MDP_COMP_HDR3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_AAL0] = {
{MDP_COMP_TYPE_AAL, 0, MT8195_MDP_COMP_AAL0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_AAL1] = {
{MDP_COMP_TYPE_AAL, 1, MT8195_MDP_COMP_AAL1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_AAL2] = {
{MDP_COMP_TYPE_AAL, 2, MT8195_MDP_COMP_AAL2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_AAL3] = {
{MDP_COMP_TYPE_AAL, 3, MT8195_MDP_COMP_AAL3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_RSZ0] = {
{MDP_COMP_TYPE_RSZ, 0, MT8195_MDP_COMP_RSZ0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_RSZ1] = {
{MDP_COMP_TYPE_RSZ, 1, MT8195_MDP_COMP_RSZ1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_RSZ2] = {
{MDP_COMP_TYPE_RSZ, 2, MT8195_MDP_COMP_RSZ2, MDP_MM_SUBSYS_1},
{2, 0, 0},
{MDP_COMP_MERGE2, true, true}
},
[MDP_COMP_RSZ3] = {
{MDP_COMP_TYPE_RSZ, 3, MT8195_MDP_COMP_RSZ3, MDP_MM_SUBSYS_1},
{2, 0, 0},
{MDP_COMP_MERGE3, true, true}
},
[MDP_COMP_TDSHP0] = {
{MDP_COMP_TYPE_TDSHP, 0, MT8195_MDP_COMP_TDSHP0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_TDSHP1] = {
{MDP_COMP_TYPE_TDSHP, 1, MT8195_MDP_COMP_TDSHP1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_TDSHP2] = {
{MDP_COMP_TYPE_TDSHP, 2, MT8195_MDP_COMP_TDSHP2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_TDSHP3] = {
{MDP_COMP_TYPE_TDSHP, 3, MT8195_MDP_COMP_TDSHP3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_COLOR0] = {
{MDP_COMP_TYPE_COLOR, 0, MT8195_MDP_COMP_COLOR0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_COLOR1] = {
{MDP_COMP_TYPE_COLOR, 1, MT8195_MDP_COMP_COLOR1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_COLOR2] = {
{MDP_COMP_TYPE_COLOR, 2, MT8195_MDP_COMP_COLOR2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_COLOR3] = {
{MDP_COMP_TYPE_COLOR, 3, MT8195_MDP_COMP_COLOR3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_OVL0] = {
{MDP_COMP_TYPE_OVL, 0, MT8195_MDP_COMP_OVL0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_OVL1] = {
{MDP_COMP_TYPE_OVL, 1, MT8195_MDP_COMP_OVL1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_PAD0] = {
{MDP_COMP_TYPE_PAD, 0, MT8195_MDP_COMP_PAD0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_PAD1] = {
{MDP_COMP_TYPE_PAD, 1, MT8195_MDP_COMP_PAD1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_PAD2] = {
{MDP_COMP_TYPE_PAD, 2, MT8195_MDP_COMP_PAD2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_PAD3] = {
{MDP_COMP_TYPE_PAD, 3, MT8195_MDP_COMP_PAD3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_TCC0] = {
{MDP_COMP_TYPE_TCC, 0, MT8195_MDP_COMP_TCC0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_TCC1] = {
{MDP_COMP_TYPE_TCC, 1, MT8195_MDP_COMP_TCC1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_WROT0] = {
{MDP_COMP_TYPE_WROT, 0, MT8195_MDP_COMP_WROT0, MDP_MM_SUBSYS_0},
{1, 0, 0}
},
[MDP_COMP_WROT1] = {
{MDP_COMP_TYPE_WROT, 1, MT8195_MDP_COMP_WROT1, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_WROT2] = {
{MDP_COMP_TYPE_WROT, 2, MT8195_MDP_COMP_WROT2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_WROT3] = {
{MDP_COMP_TYPE_WROT, 3, MT8195_MDP_COMP_WROT3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_MERGE2] = {
{MDP_COMP_TYPE_MERGE, 0, MT8195_MDP_COMP_MERGE2, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_MERGE3] = {
{MDP_COMP_TYPE_MERGE, 1, MT8195_MDP_COMP_MERGE3, MDP_MM_SUBSYS_1},
{1, 0, 0}
},
[MDP_COMP_PQ0_SOUT] = {
{MDP_COMP_TYPE_DUMMY, 0, MT8195_MDP_COMP_PQ0_SOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_PQ1_SOUT] = {
{MDP_COMP_TYPE_DUMMY, 1, MT8195_MDP_COMP_PQ1_SOUT, MDP_MM_SUBSYS_1},
{0, 0, 0}
},
[MDP_COMP_TO_WARP0MOUT] = {
{MDP_COMP_TYPE_DUMMY, 2, MT8195_MDP_COMP_TO_WARP0MOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_TO_WARP1MOUT] = {
{MDP_COMP_TYPE_DUMMY, 3, MT8195_MDP_COMP_TO_WARP1MOUT, MDP_MM_SUBSYS_0},
{0, 0, 0}
},
[MDP_COMP_TO_SVPP2MOUT] = {
{MDP_COMP_TYPE_DUMMY, 4, MT8195_MDP_COMP_TO_SVPP2MOUT, MDP_MM_SUBSYS_1},
{0, 0, 0}
},
[MDP_COMP_TO_SVPP3MOUT] = {
{MDP_COMP_TYPE_DUMMY, 5, MT8195_MDP_COMP_TO_SVPP3MOUT, MDP_MM_SUBSYS_1},
{0, 0, 0}
},
[MDP_COMP_VPP0_SOUT] = {
{MDP_COMP_TYPE_PATH, 0, MT8195_MDP_COMP_VPP0_SOUT, MDP_MM_SUBSYS_1},
{4, 9, 0}
},
[MDP_COMP_VPP1_SOUT] = {
{MDP_COMP_TYPE_PATH, 1, MT8195_MDP_COMP_VPP1_SOUT, MDP_MM_SUBSYS_0},
{2, 13, 0}
},
[MDP_COMP_VDO0DL0] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL0, MDP_MM_SUBSYS_1},
{1, 15, 0}
},
[MDP_COMP_VDO1DL0] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL0, MDP_MM_SUBSYS_1},
{1, 17, 0}
},
[MDP_COMP_VDO0DL1] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO0DL1, MDP_MM_SUBSYS_1},
{1, 18, 0}
},
[MDP_COMP_VDO1DL1] = {
{MDP_COMP_TYPE_DL_PATH, 0, MT8195_MDP_COMP_VDO1DL1, MDP_MM_SUBSYS_1},
{1, 16, 0}
},
};
static const struct of_device_id mt8183_sub_comp_dt_ids[] = {
{
.compatible = "mediatek,mt8183-mdp3-wdma",
@ -157,6 +556,10 @@ static const struct of_device_id mt8183_sub_comp_dt_ids[] = {
{}
};
static const struct of_device_id mt8195_sub_comp_dt_ids[] = {
{}
};
/*
* All 10-bit related formats are not added in the basic format list,
* please add the corresponding format settings before use.
@ -382,6 +785,222 @@ static const struct mdp_format mt8183_formats[] = {
}
};
static const struct mdp_format mt8195_formats[] = {
{
.pixelformat = V4L2_PIX_FMT_GREY,
.mdp_color = MDP_COLOR_GREY,
.depth = { 8 },
.row_depth = { 8 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_RGB565X,
.mdp_color = MDP_COLOR_BGR565,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_RGB565,
.mdp_color = MDP_COLOR_RGB565,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_RGB24,
.mdp_color = MDP_COLOR_RGB888,
.depth = { 24 },
.row_depth = { 24 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_BGR24,
.mdp_color = MDP_COLOR_BGR888,
.depth = { 24 },
.row_depth = { 24 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_ABGR32,
.mdp_color = MDP_COLOR_BGRA8888,
.depth = { 32 },
.row_depth = { 32 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_ARGB32,
.mdp_color = MDP_COLOR_ARGB8888,
.depth = { 32 },
.row_depth = { 32 },
.num_planes = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_UYVY,
.mdp_color = MDP_COLOR_UYVY,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_VYUY,
.mdp_color = MDP_COLOR_VYUY,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YUYV,
.mdp_color = MDP_COLOR_YUYV,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YVYU,
.mdp_color = MDP_COLOR_YVYU,
.depth = { 16 },
.row_depth = { 16 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YUV420,
.mdp_color = MDP_COLOR_I420,
.depth = { 12 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YVU420,
.mdp_color = MDP_COLOR_YV12,
.depth = { 12 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV12,
.mdp_color = MDP_COLOR_NV12,
.depth = { 12 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV21,
.mdp_color = MDP_COLOR_NV21,
.depth = { 12 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV16,
.mdp_color = MDP_COLOR_NV16,
.depth = { 16 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV61,
.mdp_color = MDP_COLOR_NV61,
.depth = { 16 },
.row_depth = { 8 },
.num_planes = 1,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV12M,
.mdp_color = MDP_COLOR_NV12,
.depth = { 8, 4 },
.row_depth = { 8, 8 },
.num_planes = 2,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_MM21,
.mdp_color = MDP_COLOR_420_BLK,
.depth = { 8, 4 },
.row_depth = { 8, 8 },
.num_planes = 2,
.walign = 6,
.halign = 6,
.flags = MDP_FMT_FLAG_OUTPUT,
}, {
.pixelformat = V4L2_PIX_FMT_NV21M,
.mdp_color = MDP_COLOR_NV21,
.depth = { 8, 4 },
.row_depth = { 8, 8 },
.num_planes = 2,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV16M,
.mdp_color = MDP_COLOR_NV16,
.depth = { 8, 8 },
.row_depth = { 8, 8 },
.num_planes = 2,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_NV61M,
.mdp_color = MDP_COLOR_NV61,
.depth = { 8, 8 },
.row_depth = { 8, 8 },
.num_planes = 2,
.walign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YUV420M,
.mdp_color = MDP_COLOR_I420,
.depth = { 8, 2, 2 },
.row_depth = { 8, 4, 4 },
.num_planes = 3,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YVU420M,
.mdp_color = MDP_COLOR_YV12,
.depth = { 8, 2, 2 },
.row_depth = { 8, 4, 4 },
.num_planes = 3,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YUV422M,
.mdp_color = MDP_COLOR_I422,
.depth = { 8, 4, 4 },
.row_depth = { 8, 4, 4 },
.num_planes = 3,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}, {
.pixelformat = V4L2_PIX_FMT_YVU422M,
.mdp_color = MDP_COLOR_YV16,
.depth = { 8, 4, 4 },
.row_depth = { 8, 4, 4 },
.num_planes = 3,
.walign = 1,
.halign = 1,
.flags = MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
}
};
static const struct mdp_limit mt8183_mdp_def_limit = {
.out_limit = {
.wmin = 16,
@ -401,15 +1020,54 @@ static const struct mdp_limit mt8183_mdp_def_limit = {
.v_scale_down_max = 128,
};
static const struct mdp_limit mt8195_mdp_def_limit = {
.out_limit = {
.wmin = 64,
.hmin = 64,
.wmax = 8192,
.hmax = 8192,
},
.cap_limit = {
.wmin = 64,
.hmin = 64,
.wmax = 8192,
.hmax = 8192,
},
.h_scale_up_max = 64,
.v_scale_up_max = 64,
.h_scale_down_max = 128,
.v_scale_down_max = 128,
};
static const struct mdp_pipe_info mt8183_pipe_info[] = {
[MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, 0},
[MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, 1},
[MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, 2},
[MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, 3}
[MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0},
[MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1},
[MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2},
[MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3}
};
static const struct mdp_pipe_info mt8195_pipe_info[] = {
[MDP_PIPE_WPEI] = {MDP_PIPE_WPEI, MDP_MM_SUBSYS_0, 0},
[MDP_PIPE_WPEI2] = {MDP_PIPE_WPEI2, MDP_MM_SUBSYS_0, 1},
[MDP_PIPE_IMGI] = {MDP_PIPE_IMGI, MDP_MM_SUBSYS_0, 2},
[MDP_PIPE_RDMA0] = {MDP_PIPE_RDMA0, MDP_MM_SUBSYS_0, 3},
[MDP_PIPE_RDMA1] = {MDP_PIPE_RDMA1, MDP_MM_SUBSYS_1, 0},
[MDP_PIPE_RDMA2] = {MDP_PIPE_RDMA2, MDP_MM_SUBSYS_1, 1},
[MDP_PIPE_RDMA3] = {MDP_PIPE_RDMA3, MDP_MM_SUBSYS_1, 2},
[MDP_PIPE_SPLIT] = {MDP_PIPE_SPLIT, MDP_MM_SUBSYS_1, 3},
[MDP_PIPE_SPLIT2] = {MDP_PIPE_SPLIT2, MDP_MM_SUBSYS_1, 4},
[MDP_PIPE_VPP1_SOUT] = {MDP_PIPE_VPP1_SOUT, MDP_MM_SUBSYS_0, 4},
[MDP_PIPE_VPP0_SOUT] = {MDP_PIPE_VPP0_SOUT, MDP_MM_SUBSYS_1, 5},
};
static const struct v4l2_rect mt8195_mdp_pp_criteria = {
.width = 1920,
.height = 1080,
};
const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.mdp_plat_id = MT8183,
.mdp_con_res = 0x14001000,
.mdp_probe_infra = mt8183_mdp_probe_infra,
.mdp_cfg = &mt8183_plat_cfg,
.mdp_mutex_table_idx = mt8183_mutex_idx,
@ -421,6 +1079,25 @@ const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
.def_limit = &mt8183_mdp_def_limit,
.pipe_info = mt8183_pipe_info,
.pipe_info_len = ARRAY_SIZE(mt8183_pipe_info),
.pp_used = MDP_PP_USED_1,
};
const struct mtk_mdp_driver_data mt8195_mdp_driver_data = {
.mdp_plat_id = MT8195,
.mdp_con_res = 0x14001000,
.mdp_probe_infra = mt8195_mdp_probe_infra,
.mdp_sub_comp_dt_ids = mt8195_sub_comp_dt_ids,
.mdp_cfg = &mt8195_plat_cfg,
.mdp_mutex_table_idx = mt8195_mutex_idx,
.comp_data = mt8195_mdp_comp_data,
.comp_data_len = ARRAY_SIZE(mt8195_mdp_comp_data),
.format = mt8195_formats,
.format_len = ARRAY_SIZE(mt8195_formats),
.def_limit = &mt8195_mdp_def_limit,
.pipe_info = mt8195_pipe_info,
.pipe_info_len = ARRAY_SIZE(mt8195_pipe_info),
.pp_criteria = &mt8195_mdp_pp_criteria,
.pp_used = MDP_PP_USED_2,
};
s32 mdp_cfg_get_id_inner(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id)
@ -451,3 +1128,11 @@ enum mtk_mdp_comp_id mdp_cfg_get_id_public(struct mdp_dev *mdp_dev, s32 inner_id
err_public_id:
return public_id;
}
bool mdp_cfg_comp_is_dummy(struct mdp_dev *mdp_dev, s32 inner_id)
{
enum mtk_mdp_comp_id id = mdp_cfg_get_id_public(mdp_dev, inner_id);
enum mdp_comp_type type = mdp_dev->mdp_data->comp_data[id].match.type;
return (type == MDP_COMP_TYPE_DUMMY);
}

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_AAL_H__
#define __MDP_REG_AAL_H__
#define MDP_AAL_EN (0x000)
#define MDP_AAL_CFG (0x020)
#define MDP_AAL_SIZE (0x030)
#define MDP_AAL_OUTPUT_SIZE (0x034)
#define MDP_AAL_OUTPUT_OFFSET (0x038)
#define MDP_AAL_CFG_MAIN (0x200)
/* MASK */
#define MDP_AAL_EN_MASK (0x01)
#define MDP_AAL_CFG_MASK (0x70FF00B3)
#define MDP_AAL_SIZE_MASK (0x1FFF1FFF)
#define MDP_AAL_OUTPUT_SIZE_MASK (0x1FFF1FFF)
#define MDP_AAL_OUTPUT_OFFSET_MASK (0x0FF00FF)
#define MDP_AAL_CFG_MAIN_MASK (0x0FE)
#endif // __MDP_REG_AAL_H__

View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_COLOR_H__
#define __MDP_REG_COLOR_H__
#define MDP_COLOR_WIN_X_MAIN (0x40C)
#define MDP_COLOR_WIN_Y_MAIN (0x410)
#define MDP_COLOR_START (0xC00)
#define MDP_COLOR_INTEN (0xC04)
#define MDP_COLOR_OUT_SEL (0xC0C)
#define MDP_COLOR_INTERNAL_IP_WIDTH (0xC50)
#define MDP_COLOR_INTERNAL_IP_HEIGHT (0xC54)
#define MDP_COLOR_CM1_EN (0xC60)
#define MDP_COLOR_CM2_EN (0xCA0)
/* MASK */
#define MDP_COLOR_WIN_X_MAIN_MASK (0xFFFFFFFF)
#define MDP_COLOR_WIN_Y_MAIN_MASK (0xFFFFFFFF)
#define MDP_COLOR_START_MASK (0x0FF013F)
#define MDP_COLOR_INTEN_MASK (0x07)
#define MDP_COLOR_OUT_SEL_MASK (0x0777)
#define MDP_COLOR_INTERNAL_IP_WIDTH_MASK (0x03FFF)
#define MDP_COLOR_INTERNAL_IP_HEIGHT_MASK (0x03FFF)
#define MDP_COLOR_CM1_EN_MASK (0x03)
#define MDP_COLOR_CM2_EN_MASK (0x017)
#endif // __MDP_REG_COLOR_H__

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_FG_H__
#define __MDP_REG_FG_H__
#define MDP_FG_TRIGGER (0x0)
#define MDP_FG_FG_CTRL_0 (0x20)
#define MDP_FG_FG_CK_EN (0x24)
#define MDP_FG_TILE_INFO_0 (0x418)
#define MDP_FG_TILE_INFO_1 (0x41c)
/* MASK */
#define MDP_FG_TRIGGER_MASK (0x00000007)
#define MDP_FG_FG_CTRL_0_MASK (0x00000033)
#define MDP_FG_FG_CK_EN_MASK (0x0000000F)
#define MDP_FG_TILE_INFO_0_MASK (0xFFFFFFFF)
#define MDP_FG_TILE_INFO_1_MASK (0xFFFFFFFF)
#endif //__MDP_REG_FG_H__

View File

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_HDR_H__
#define __MDP_REG_HDR_H__
#define MDP_HDR_TOP (0x000)
#define MDP_HDR_RELAY (0x004)
#define MDP_HDR_SIZE_0 (0x014)
#define MDP_HDR_SIZE_1 (0x018)
#define MDP_HDR_SIZE_2 (0x01C)
#define MDP_HDR_HIST_CTRL_0 (0x020)
#define MDP_HDR_HIST_CTRL_1 (0x024)
#define MDP_HDR_HIST_ADDR (0x0DC)
#define MDP_HDR_TILE_POS (0x118)
/* MASK */
#define MDP_HDR_RELAY_MASK (0x01)
#define MDP_HDR_TOP_MASK (0xFF0FEB6D)
#define MDP_HDR_SIZE_0_MASK (0x1FFF1FFF)
#define MDP_HDR_SIZE_1_MASK (0x1FFF1FFF)
#define MDP_HDR_SIZE_2_MASK (0x1FFF1FFF)
#define MDP_HDR_HIST_CTRL_0_MASK (0x1FFF1FFF)
#define MDP_HDR_HIST_CTRL_1_MASK (0x1FFF1FFF)
#define MDP_HDR_HIST_ADDR_MASK (0xBF3F2F3F)
#define MDP_HDR_TILE_POS_MASK (0x1FFF1FFF)
#endif // __MDP_REG_HDR_H__

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_MERGE_H__
#define __MDP_REG_MERGE_H__
#define MDP_MERGE_ENABLE (0x000)
#define MDP_MERGE_CFG_0 (0x010)
#define MDP_MERGE_CFG_4 (0x020)
#define MDP_MERGE_CFG_12 (0x040)
#define MDP_MERGE_CFG_24 (0x070)
#define MDP_MERGE_CFG_25 (0x074)
/* MASK */
#define MDP_MERGE_ENABLE_MASK (0xFFFFFFFF)
#define MDP_MERGE_CFG_0_MASK (0xFFFFFFFF)
#define MDP_MERGE_CFG_4_MASK (0xFFFFFFFF)
#define MDP_MERGE_CFG_12_MASK (0xFFFFFFFF)
#define MDP_MERGE_CFG_24_MASK (0xFFFFFFFF)
#define MDP_MERGE_CFG_25_MASK (0xFFFFFFFF)
#endif //__MDP_REG_MERGE_H__

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_OVL_H__
#define __MDP_REG_OVL_H__
#define MDP_OVL_EN (0x00c)
#define MDP_OVL_ROI_SIZE (0x020)
#define MDP_OVL_DP_CON (0x024)
#define MDP_OVL_SRC_CON (0x02c)
#define MDP_OVL_L0_CON (0x030)
#define MDP_OVL_L0_SRC_SIZE (0x038)
/* MASK */
#define MDP_OVL_DP_CON_MASK (0x0FFFFFFF)
#define MDP_OVL_EN_MASK (0xB07D07B1)
#define MDP_OVL_L0_CON_MASK (0xFFFFFFFF)
#define MDP_OVL_L0_SRC_SIZE_MASK (0x1FFF1FFF)
#define MDP_OVL_ROI_SIZE_MASK (0x1FFF1FFF)
#define MDP_OVL_SRC_CON_MASK (0x0000031F)
#endif //__MDP_REG_OVL_H__

View File

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 MediaTek Inc.
* Author: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
*/
#ifndef __MDP_REG_PAD_H__
#define __MDP_REG_PAD_H__
#define MDP_PAD_CON (0x000)
#define MDP_PAD_PIC_SIZE (0x004)
#define MDP_PAD_W_SIZE (0x008)
#define MDP_PAD_H_SIZE (0x00c)
/* MASK */
#define MDP_PAD_CON_MASK (0x00000007)
#define MDP_PAD_PIC_SIZE_MASK (0xFFFFFFFF)
#define MDP_PAD_W_SIZE_MASK (0x1FFF1FFF)
#define MDP_PAD_H_SIZE_MASK (0x1FFF1FFF)
#endif // __MDP_REG_PAD_H__

View File

@ -26,6 +26,18 @@
#define MDP_RDMA_SRC_OFFSET_2 0x128
#define MDP_RDMA_SRC_OFFSET_0_P 0x148
#define MDP_RDMA_TRANSFORM_0 0x200
#define MDP_RDMA_DMABUF_CON_0 0x240
#define MDP_RDMA_ULTRA_TH_HIGH_CON_0 0x248
#define MDP_RDMA_ULTRA_TH_LOW_CON_0 0x250
#define MDP_RDMA_DMABUF_CON_1 0x258
#define MDP_RDMA_ULTRA_TH_HIGH_CON_1 0x260
#define MDP_RDMA_ULTRA_TH_LOW_CON_1 0x268
#define MDP_RDMA_DMABUF_CON_2 0x270
#define MDP_RDMA_ULTRA_TH_HIGH_CON_2 0x278
#define MDP_RDMA_ULTRA_TH_LOW_CON_2 0x280
#define MDP_RDMA_DMABUF_CON_3 0x288
#define MDP_RDMA_ULTRA_TH_HIGH_CON_3 0x290
#define MDP_RDMA_ULTRA_TH_LOW_CON_3 0x298
#define MDP_RDMA_RESV_DUMMY_0 0x2a0
#define MDP_RDMA_MON_STA_1 0x408
#define MDP_RDMA_SRC_BASE_0 0xf00
@ -54,6 +66,18 @@
#define MDP_RDMA_SRC_OFFSET_2_MASK 0xffffffff
#define MDP_RDMA_SRC_OFFSET_0_P_MASK 0xffffffff
#define MDP_RDMA_TRANSFORM_0_MASK 0xff110777
#define MDP_RDMA_DMABUF_CON_0_MASK 0x0fff00ff
#define MDP_RDMA_ULTRA_TH_HIGH_CON_0_MASK 0x3fffffff
#define MDP_RDMA_ULTRA_TH_LOW_CON_0_MASK 0x3fffffff
#define MDP_RDMA_DMABUF_CON_1_MASK 0x0f7f007f
#define MDP_RDMA_ULTRA_TH_HIGH_CON_1_MASK 0x3fffffff
#define MDP_RDMA_ULTRA_TH_LOW_CON_1_MASK 0x3fffffff
#define MDP_RDMA_DMABUF_CON_2_MASK 0x0f3f003f
#define MDP_RDMA_ULTRA_TH_HIGH_CON_2_MASK 0x3fffffff
#define MDP_RDMA_ULTRA_TH_LOW_CON_2_MASK 0x3fffffff
#define MDP_RDMA_DMABUF_CON_3_MASK 0x0f3f003f
#define MDP_RDMA_ULTRA_TH_HIGH_CON_3_MASK 0x3fffffff
#define MDP_RDMA_ULTRA_TH_LOW_CON_3_MASK 0x3fffffff
#define MDP_RDMA_RESV_DUMMY_0_MASK 0xffffffff
#define MDP_RDMA_MON_STA_1_MASK 0xffffffff
#define MDP_RDMA_SRC_BASE_0_MASK 0xffffffff

View File

@ -20,6 +20,7 @@
#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET 0x02c
#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET 0x030
#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET 0x034
#define RSZ_ETC_CONTROL 0x22c
/* MASK */
#define PRZ_ENABLE_MASK 0x00010001
@ -35,5 +36,6 @@
#define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET_MASK 0x001fffff
#define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET_MASK 0x0000ffff
#define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK 0x001fffff
#define RSZ_ETC_CONTROL_MASK 0xff770000
#endif // __MDP_REG_RSZ_H__

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