mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
media updates for v6.3-rc1
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+QmuaPwR3wnBdVwACF8+vY7k4RUFAmP7M9AACgkQCF8+vY7k 4RVpxRAAjarn420frUo/YiMWuYiYtDCFmXj+toHgqsa9fcUOjxml9V+S5L0uY6tF D6d9KCgqKf1AO2MDzB3aR1qQmPfelMoSomQjsTm6cWaMPDobxpzL2IlcspMDBxz0 PyCz4R9cCK5kwuBiQlz3dE605/t/7JXOAFEopo5tvYWNfRt9YXFbPJ/Hdttc4cqw d6js3TN7oxHoa+t5Ox9Fq+i6MSxsMEku5RvfHVI6yUs//eWcf9H2zFfZ83vZ7+vY L8PlRzMXlvovsFwXivtiZdSkuwFloWrqIs8btHb1/psClOUxFQhpk2B4hkUixCAn wk9EN7eHWNdbaZha5//uPRmxUjjhIn4XAIXnfslsB7iiRn7uJtYryUnt+b+kD3Lt dtF2i1W7nNfUd5e7YRjipTjgjtazLpeyDGvH0TqfpwK8Wn10Acj+Az1v4bjf+cc0 GC1EVUtGeJhexYzLsHSQMQZB1IgFxUw5LNKdqsrboled3yvxfgK69Yp9FQLon9vZ R7KEDHuzt+e4Kihxq8dTp6wMV47dNrq0wpJKMjfylKhq/MPqa9uiygl1s2KlMg6n HDJQlYbQGlzrgHDDQRhYUAgxs3JeyxAmup2eLR6dWrAqBW+ULT9S2DiggOk9xxKg UkaCkodr3ZOhZti+oLRRAY2cRsGYgan7rKhscd0t7opO+CrfHxo= =0XIw -----END PGP SIGNATURE----- Merge tag 'media/v6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media Pull media updates from Mauro Carvalho Chehab: - Removal of several VB1-only deprecated drivers: cpia2, fsl-viu, meye, stkwebcam, tm6000, vpfe_capture and zr364xx - saa7146 recovered from staging/deprecated. We opted to give ti a chance, and, instead of deprecating it, the intention is to write patches migrating it from VB1 to VB2. - av7110 returned from staging/deprecated/ to staging/ as we're not planning on dropping it any time soon - media controller API has gained experimental support for G_ROUTING and streams API. No drivers use it right now. We're planning to add one after -rc1, giving some time to experience the API and eventually have changes during the next development cycle - New sensor drivers: imx296, imx415, ov8858 - Atomisp had lots of changes, specially on its sensor's interface, making atomisp sensor drivers closer to normal sensor drivers - media controller kAPI has gained some helpers to traverse pipelines - uvcvideo now better support power line control - lots of bug fixes, cleanups and driver improvements * tag 'media/v6.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (296 commits) media: imx-mipi-csis: Check csis_fmt validity before use media: v4l2-subdev.c: clear stream field media: v4l2-ctrls-api.c: move ctrl->is_new = 1 to the correct line media: Revert "media: saa7146: deprecate hexium_gemini/orion, mxb and ttpci" media: Revert "media: av7110: move to staging/media/deprecated/saa7146" media: imx-pxp: convert to regmap media: imx-pxp: Use non-threaded IRQ media: imx-pxp: Introduce pxp_read() and pxp_write() wrappers media: imx-pxp: Implement frame size enumeration media: imx-pxp: Pass pixel format value to find_format() media: imx-pxp: Add media controller support media: imx-pxp: Don't set bus_info manually in .querycap() media: imx-pxp: Sort headers alphabetically media: imx-pxp: add support for i.MX7D media: imx-pxp: make data_path_ctrl0 platform dependent media: imx-pxp: disable LUT block media: imx-pxp: explicitly disable unused blocks media: imx-pxp: extract helper function to setup data path media: imx-pxp: detect PXP version media: dt-bindings: media: fsl-pxp: convert to yaml ...
This commit is contained in:
commit
4b8c673b76
@ -190,6 +190,7 @@ ForEachMacros:
|
||||
- 'for_each_active_dev_scope'
|
||||
- 'for_each_active_drhd_unit'
|
||||
- 'for_each_active_iommu'
|
||||
- 'for_each_active_route'
|
||||
- 'for_each_aggr_pgid'
|
||||
- 'for_each_available_child_of_node'
|
||||
- 'for_each_bench'
|
||||
|
@ -340,14 +340,14 @@ and IO24. Monitoring the HPD an 5V lines is not necessary, but it is helpful.
|
||||
This kernel patch will hook up the cec-gpio driver correctly to
|
||||
e.g. ``arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts``::
|
||||
|
||||
cec-gpio@7 {
|
||||
cec@7 {
|
||||
compatible = "cec-gpio";
|
||||
cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
|
||||
hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
v5-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
cec-gpio@8 {
|
||||
cec@8 {
|
||||
compatible = "cec-gpio";
|
||||
cec-gpios = <&gpio 8 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
|
||||
hpd-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
|
||||
|
@ -1,145 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The cpia2 driver
|
||||
================
|
||||
|
||||
Authors: Peter Pregler <Peter_Pregler@email.com>,
|
||||
Scott J. Bertin <scottbertin@yahoo.com>, and
|
||||
Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
|
||||
this one was modelled from.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This is a driver for STMicroelectronics's CPiA2 (second generation
|
||||
Colour Processor Interface ASIC) based cameras. This camera outputs an MJPEG
|
||||
stream at up to vga size. It implements the Video4Linux interface as much as
|
||||
possible. Since the V4L interface does not support compressed formats, only
|
||||
an mjpeg enabled application can be used with the camera. We have modified the
|
||||
gqcam application to view this stream.
|
||||
|
||||
The driver is implemented as two kernel modules. The cpia2 module
|
||||
contains the camera functions and the V4L interface. The cpia2_usb module
|
||||
contains usb specific functions. The main reason for this was the size of the
|
||||
module was getting out of hand, so I separated them. It is not likely that
|
||||
there will be a parallel port version.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Supports cameras with the Vision stv6410 (CIF) and stv6500 (VGA) cmos
|
||||
sensors. I only have the vga sensor, so can't test the other.
|
||||
- Image formats: VGA, QVGA, CIF, QCIF, and a number of sizes in between.
|
||||
VGA and QVGA are the native image sizes for the VGA camera. CIF is done
|
||||
in the coprocessor by scaling QVGA. All other sizes are done by clipping.
|
||||
- Palette: YCrCb, compressed with MJPEG.
|
||||
- Some compression parameters are settable.
|
||||
- Sensor framerate is adjustable (up to 30 fps CIF, 15 fps VGA).
|
||||
- Adjust brightness, color, contrast while streaming.
|
||||
- Flicker control settable for 50 or 60 Hz mains frequency.
|
||||
|
||||
Making and installing the stv672 driver modules
|
||||
-----------------------------------------------
|
||||
|
||||
Requirements
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Video4Linux must be either compiled into the kernel or
|
||||
available as a module. Video4Linux2 is automatically detected and made
|
||||
available at compile time.
|
||||
|
||||
Setup
|
||||
~~~~~
|
||||
|
||||
Use ``modprobe cpia2`` to load and ``modprobe -r cpia2`` to unload. This
|
||||
may be done automatically by your distribution.
|
||||
|
||||
Driver options
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. tabularcolumns:: |p{13ex}|L|
|
||||
|
||||
|
||||
============== ========================================================
|
||||
Option Description
|
||||
============== ========================================================
|
||||
video_nr video device to register (0=/dev/video0, etc)
|
||||
range -1 to 64. default is -1 (first available)
|
||||
If you have more than 1 camera, this MUST be -1.
|
||||
buffer_size Size for each frame buffer in bytes (default 68k)
|
||||
num_buffers Number of frame buffers (1-32, default 3)
|
||||
alternate USB Alternate (2-7, default 7)
|
||||
flicker_freq Frequency for flicker reduction(50 or 60, default 60)
|
||||
flicker_mode 0 to disable, or 1 to enable flicker reduction.
|
||||
(default 0). This is only effective if the camera
|
||||
uses a stv0672 coprocessor.
|
||||
============== ========================================================
|
||||
|
||||
Setting the options
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are using modules, edit /etc/modules.conf and add an options
|
||||
line like this::
|
||||
|
||||
options cpia2 num_buffers=3 buffer_size=65535
|
||||
|
||||
If the driver is compiled into the kernel, at boot time specify them
|
||||
like this::
|
||||
|
||||
cpia2.num_buffers=3 cpia2.buffer_size=65535
|
||||
|
||||
What buffer size should I use?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The maximum image size depends on the alternate you choose, and the
|
||||
frame rate achieved by the camera. If the compression engine is able to
|
||||
keep up with the frame rate, the maximum image size is given by the table
|
||||
below.
|
||||
|
||||
The compression engine starts out at maximum compression, and will
|
||||
increase image quality until it is close to the size in the table. As long
|
||||
as the compression engine can keep up with the frame rate, after a short time
|
||||
the images will all be about the size in the table, regardless of resolution.
|
||||
|
||||
At low alternate settings, the compression engine may not be able to
|
||||
compress the image enough and will reduce the frame rate by producing larger
|
||||
images.
|
||||
|
||||
The default of 68k should be good for most users. This will handle
|
||||
any alternate at frame rates down to 15fps. For lower frame rates, it may
|
||||
be necessary to increase the buffer size to avoid having frames dropped due
|
||||
to insufficient space.
|
||||
|
||||
========== ========== ======== =====
|
||||
Alternate bytes/ms 15fps 30fps
|
||||
========== ========== ======== =====
|
||||
2 128 8533 4267
|
||||
3 384 25600 12800
|
||||
4 640 42667 21333
|
||||
5 768 51200 25600
|
||||
6 896 59733 29867
|
||||
7 1023 68200 34100
|
||||
========== ========== ======== =====
|
||||
|
||||
Table: Image size(bytes)
|
||||
|
||||
|
||||
How many buffers should I use?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For normal streaming, 3 should give the best results. With only 2,
|
||||
it is possible for the camera to finish sending one image just after a
|
||||
program has started reading the other. If this happens, the driver must drop
|
||||
a frame. The exception to this is if you have a heavily loaded machine. In
|
||||
this case use 2 buffers. You are probably not reading at the full frame rate.
|
||||
If the camera can send multiple images before a read finishes, it could
|
||||
overwrite the third buffer before the read finishes, leading to a corrupt
|
||||
image. Single and double buffering have extra checks to avoid overwriting.
|
||||
|
||||
Using the camera
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
We are providing a modified gqcam application to view the output. In
|
||||
order to avoid confusion, here it is called mview. There is also the qx5view
|
||||
program which can also control the lights on the qx5 microscope. MJPEG Tools
|
||||
(http://mjpeg.sourceforge.net) can also be used to record from the camera.
|
@ -13,4 +13,3 @@ Digital TV driver-specific documentation
|
||||
opera-firmware
|
||||
technisat
|
||||
ttusb-dec
|
||||
zr364xx
|
||||
|
@ -1,93 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
Vaio Picturebook Motion Eye Camera Driver
|
||||
=========================================
|
||||
|
||||
Copyright |copy| 2001-2004 Stelian Pop <stelian@popies.net>
|
||||
|
||||
Copyright |copy| 2001-2002 Alcôve <www.alcove.com>
|
||||
|
||||
Copyright |copy| 2000 Andrew Tridgell <tridge@samba.org>
|
||||
|
||||
This driver enable the use of video4linux compatible applications with the
|
||||
Motion Eye camera. This driver requires the "Sony Laptop Extras" driver (which
|
||||
can be found in the "Misc devices" section of the kernel configuration utility)
|
||||
to be compiled and installed (using its "camera=1" parameter).
|
||||
|
||||
It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
|
||||
|
||||
Grabbing is supported in packed YUV colorspace only.
|
||||
|
||||
MJPEG hardware grabbing is supported via a private API (see below).
|
||||
|
||||
Hardware supported
|
||||
------------------
|
||||
|
||||
This driver supports the 'second' version of the MotionEye camera :)
|
||||
|
||||
The first version was connected directly on the video bus of the Neomagic
|
||||
video card and is unsupported.
|
||||
|
||||
The second one, made by Kawasaki Steel is fully supported by this
|
||||
driver (PCI vendor/device is 0x136b/0xff01)
|
||||
|
||||
The third one, present in recent (more or less last year) Picturebooks
|
||||
(C1M* models), is not supported. The manufacturer has given the specs
|
||||
to the developers under a NDA (which allows the development of a GPL
|
||||
driver however), but things are not moving very fast (see
|
||||
http://r-engine.sourceforge.net/) (PCI vendor/device is 0x10cf/0x2011).
|
||||
|
||||
There is a forth model connected on the USB bus in TR1* Vaio laptops.
|
||||
This camera is not supported at all by the current driver, in fact
|
||||
little information if any is available for this camera
|
||||
(USB vendor/device is 0x054c/0x0107).
|
||||
|
||||
Driver options
|
||||
--------------
|
||||
|
||||
Several options can be passed to the meye driver using the standard
|
||||
module argument syntax (<param>=<value> when passing the option to the
|
||||
module or meye.<param>=<value> on the kernel boot line when meye is
|
||||
statically linked into the kernel). Those options are:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
gbuffers: number of capture buffers, default is 2 (32 max)
|
||||
|
||||
gbufsize: size of each capture buffer, default is 614400
|
||||
|
||||
video_nr: video device to register (0 = /dev/video0, etc)
|
||||
|
||||
Module use
|
||||
----------
|
||||
|
||||
In order to automatically load the meye module on use, you can put those lines
|
||||
in your /etc/modprobe.d/meye.conf file:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
alias char-major-81 videodev
|
||||
alias char-major-81-0 meye
|
||||
options meye gbuffers=32
|
||||
|
||||
Usage:
|
||||
------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
xawtv >= 3.49 (<http://bytesex.org/xawtv/>)
|
||||
for display and uncompressed video capture:
|
||||
|
||||
xawtv -c /dev/video0 -geometry 640x480
|
||||
or
|
||||
xawtv -c /dev/video0 -geometry 320x240
|
||||
|
||||
motioneye (<http://popies.net/meye/>)
|
||||
for getting ppm or jpg snapshots, mjpeg video
|
||||
|
||||
Bugs / Todo
|
||||
-----------
|
||||
|
||||
- 'motioneye' still uses the meye private v4l1 API extensions.
|
@ -14,8 +14,6 @@ dvb-as102 nBox DVB-T Dongle 0b89:0007
|
||||
dvb-as102 Sky IT Digital Key (green led) 2137:0001
|
||||
b2c2-flexcop-usb Technisat/B2C2 FlexCop II/IIb/III 0af7:0101
|
||||
Digital TV
|
||||
cpia2 Vision's CPiA2 cameras 0553:0100, 0553:0140,
|
||||
such as the Digital Blue QX5 0553:0151
|
||||
go7007 WIS GO7007 MPEG encoder 1943:a250, 093b:a002,
|
||||
093b:a004, 0eb1:6666,
|
||||
0eb1:6668
|
||||
@ -66,7 +64,6 @@ pwc Visionite VCS-UC300 0d81:1900
|
||||
pwc Visionite VCS-UM100 0d81:1910
|
||||
s2255drv Sensoray 2255 1943:2255, 1943:2257
|
||||
stk1160 STK1160 USB video capture dongle 05e1:0408
|
||||
stkwebcam Syntek DC1125 174f:a311, 05e1:0501
|
||||
dvb-ttusb-budget Technotrend/Hauppauge Nova-USB devices 0b48:1003, 0b48:1004,
|
||||
0b48:1005
|
||||
dvb-ttusb_dec Technotrend/Hauppauge MPEG decoder 0b48:1006
|
||||
@ -78,15 +75,4 @@ dvb-ttusb_dec Technotrend/Hauppauge MPEG decoder
|
||||
DEC2540-t 0b48:1009
|
||||
usbtv Fushicai USBTV007 Audio-Video Grabber 1b71:3002, 1f71:3301,
|
||||
1f71:3306
|
||||
zr364xx USB ZR364XX Camera 08ca:0109, 041e:4024,
|
||||
0d64:0108, 0546:3187,
|
||||
0d64:3108, 0595:4343,
|
||||
0bb0:500d, 0feb:2004,
|
||||
055f:b500, 08ca:2062,
|
||||
052b:1a18, 04c8:0729,
|
||||
04f2:a208, 0784:0040,
|
||||
06d6:0034, 0a17:0062,
|
||||
06d6:003b, 0a17:004e,
|
||||
041e:405d, 08ca:2102,
|
||||
06d6:003d
|
||||
================ ====================================== =====================
|
||||
|
@ -77,7 +77,6 @@ ipu3-cio2 Intel ipu3-cio2 driver
|
||||
ivtv Conexant cx23416/cx23415 MPEG encoder/decoder
|
||||
ivtvfb Conexant cx23415 framebuffer
|
||||
mantis MANTIS based cards
|
||||
meye Sony Vaio Picturebook Motion Eye
|
||||
mxb Siemens-Nixdorf 'Multimedia eXtension Board'
|
||||
netup-unidvb NetUP Universal DVB card
|
||||
ngene Micronas nGene
|
||||
|
@ -30,7 +30,6 @@ exynos-fimc-is EXYNOS4x12 FIMC-IS (Imaging Subsystem)
|
||||
exynos-fimc-lite EXYNOS FIMC-LITE camera interface
|
||||
exynos-gsc Samsung Exynos G-Scaler
|
||||
exy Samsung S5P/EXYNOS4 SoC series Camera Subsystem
|
||||
fsl-viu Freescale VIU
|
||||
imx-pxp i.MX Pixel Pipeline (PXP)
|
||||
isdf TI DM365 ISIF video capture
|
||||
mmp_camera Marvell Armada 610 integrated camera controller
|
||||
|
@ -1,83 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
TM6000 cards list
|
||||
=================
|
||||
|
||||
.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}|
|
||||
|
||||
.. flat-table::
|
||||
:header-rows: 1
|
||||
:widths: 2 19 18
|
||||
:stub-columns: 0
|
||||
|
||||
* - Card number
|
||||
- Card name
|
||||
- USB IDs
|
||||
|
||||
* - 0
|
||||
- Unknown tm6000 video grabber
|
||||
-
|
||||
|
||||
* - 1
|
||||
- Generic tm5600 board
|
||||
- 6000:0001
|
||||
|
||||
* - 2
|
||||
- Generic tm6000 board
|
||||
-
|
||||
|
||||
* - 3
|
||||
- Generic tm6010 board
|
||||
- 6000:0002
|
||||
|
||||
* - 4
|
||||
- 10Moons UT 821
|
||||
-
|
||||
|
||||
* - 5
|
||||
- 10Moons UT 330
|
||||
-
|
||||
|
||||
* - 6
|
||||
- ADSTECH Dual TV USB
|
||||
- 06e1:f332
|
||||
|
||||
* - 7
|
||||
- Freecom Hybrid Stick / Moka DVB-T Receiver Dual
|
||||
- 14aa:0620
|
||||
|
||||
* - 8
|
||||
- ADSTECH Mini Dual TV USB
|
||||
- 06e1:b339
|
||||
|
||||
* - 9
|
||||
- Hauppauge WinTV HVR-900H / WinTV USB2-Stick
|
||||
- 2040:6600, 2040:6601, 2040:6610, 2040:6611
|
||||
|
||||
* - 10
|
||||
- Beholder Wander DVB-T/TV/FM USB2.0
|
||||
- 6000:dec0
|
||||
|
||||
* - 11
|
||||
- Beholder Voyager TV/FM USB2.0
|
||||
- 6000:dec1
|
||||
|
||||
* - 12
|
||||
- Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick
|
||||
- 0ccd:0086, 0ccd:00A5
|
||||
|
||||
* - 13
|
||||
- Twinhan TU501(704D1)
|
||||
- 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264
|
||||
|
||||
* - 14
|
||||
- Beholder Wander Lite DVB-T/TV/FM USB2.0
|
||||
- 6000:dec2
|
||||
|
||||
* - 15
|
||||
- Beholder Voyager Lite TV/FM USB2.0
|
||||
- 6000:dec3
|
||||
|
||||
* - 16
|
||||
- Terratec Grabster AV 150/250 MX
|
||||
- 0ccd:0079
|
@ -43,7 +43,6 @@ Driver Name
|
||||
airspy AirSpy
|
||||
au0828 Auvitek AU0828
|
||||
b2c2-flexcop-usb Technisat/B2C2 Air/Sky/Cable2PC USB
|
||||
cpia2 CPiA2 Video For Linux
|
||||
cx231xx Conexant cx231xx USB video capture
|
||||
dvb-as102 Abilis AS102 DVB receiver
|
||||
dvb-ttusb-budget Technotrend/Hauppauge Nova - USB devices
|
||||
@ -93,15 +92,10 @@ pwc USB Philips Cameras
|
||||
s2250 Sensoray 2250/2251
|
||||
s2255drv USB Sensoray 2255 video capture device
|
||||
smsusb Siano SMS1xxx based MDTV receiver
|
||||
stkwebcam USB Syntek DC1125 Camera
|
||||
tm6000-alsa TV Master TM5600/6000/6010 audio
|
||||
tm6000-dvb DVB Support for tm6000 based TV cards
|
||||
tm6000 TV Master TM5600/6000/6010 driver
|
||||
ttusb_dec Technotrend/Hauppauge USB DEC devices
|
||||
usbtv USBTV007 video capture
|
||||
uvcvideo USB Video Class (UVC)
|
||||
zd1301 ZyDAS ZD1301
|
||||
zr364xx USB ZR364XX Camera
|
||||
====================== =========================================================
|
||||
|
||||
.. toctree::
|
||||
@ -110,7 +104,6 @@ zr364xx USB ZR364XX Camera
|
||||
au0828-cardlist
|
||||
cx231xx-cardlist
|
||||
em28xx-cardlist
|
||||
tm6000-cardlist
|
||||
siano-cardlist
|
||||
|
||||
gspca-cardlist
|
||||
|
@ -11,14 +11,12 @@ Video4Linux (V4L) driver-specific documentation
|
||||
|
||||
bttv
|
||||
cafe_ccic
|
||||
cpia2
|
||||
cx88
|
||||
fimc
|
||||
imx
|
||||
imx7
|
||||
ipu3
|
||||
ivtv
|
||||
meye
|
||||
omap3isp
|
||||
omap4_camera
|
||||
philips
|
||||
|
@ -1,102 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
Zoran 364xx based USB webcam module
|
||||
===================================
|
||||
|
||||
site: http://royale.zerezo.com/zr364xx/
|
||||
|
||||
mail: royale@zerezo.com
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
This brings support under Linux for the Aiptek PocketDV 3300 and similar
|
||||
devices in webcam mode. If you just want to get on your PC the pictures
|
||||
and movies on the camera, you should use the usb-storage module instead.
|
||||
|
||||
The driver works with several other cameras in webcam mode (see the list
|
||||
below).
|
||||
|
||||
Possible chipsets are : ZR36430 (ZR36430BGC) and
|
||||
maybe ZR36431, ZR36440, ZR36442...
|
||||
|
||||
You can try the experience changing the vendor/product ID values (look
|
||||
at the source code).
|
||||
|
||||
You can get these values by looking at /var/log/messages when you plug
|
||||
your camera, or by typing : cat /sys/kernel/debug/usb/devices.
|
||||
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
In order to use this driver, you must compile it with your kernel,
|
||||
with the following config options::
|
||||
|
||||
./scripts/config -e USB
|
||||
./scripts/config -m MEDIA_SUPPORT
|
||||
./scripts/config -e MEDIA_USB_SUPPORT
|
||||
./scripts/config -e MEDIA_CAMERA_SUPPORT
|
||||
./scripts/config -m USB_ZR364XX
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
modprobe zr364xx debug=X mode=Y
|
||||
|
||||
- debug : set to 1 to enable verbose debug messages
|
||||
- mode : 0 = 320x240, 1 = 160x120, 2 = 640x480
|
||||
|
||||
You can then use the camera with V4L2 compatible applications, for
|
||||
example Ekiga.
|
||||
|
||||
To capture a single image, try this: dd if=/dev/video0 of=test.jpg bs=1M
|
||||
count=1
|
||||
|
||||
links
|
||||
-----
|
||||
|
||||
http://mxhaard.free.fr/ (support for many others cams including some Aiptek PocketDV)
|
||||
http://www.harmwal.nl/pccam880/ (this project also supports cameras based on this chipset)
|
||||
|
||||
Supported devices
|
||||
-----------------
|
||||
|
||||
====== ======= ============== ====================
|
||||
Vendor Product Distributor Model
|
||||
====== ======= ============== ====================
|
||||
0x08ca 0x0109 Aiptek PocketDV 3300
|
||||
0x08ca 0x0109 Maxell Maxcam PRO DV3
|
||||
0x041e 0x4024 Creative PC-CAM 880
|
||||
0x0d64 0x0108 Aiptek Fidelity 3200
|
||||
0x0d64 0x0108 Praktica DCZ 1.3 S
|
||||
0x0d64 0x0108 Genius Digital Camera (?)
|
||||
0x0d64 0x0108 DXG Technology Fashion Cam
|
||||
0x0546 0x3187 Polaroid iON 230
|
||||
0x0d64 0x3108 Praktica Exakta DC 2200
|
||||
0x0d64 0x3108 Genius G-Shot D211
|
||||
0x0595 0x4343 Concord Eye-Q Duo 1300
|
||||
0x0595 0x4343 Concord Eye-Q Duo 2000
|
||||
0x0595 0x4343 Fujifilm EX-10
|
||||
0x0595 0x4343 Ricoh RDC-6000
|
||||
0x0595 0x4343 Digitrex DSC 1300
|
||||
0x0595 0x4343 Firstline FDC 2000
|
||||
0x0bb0 0x500d Concord EyeQ Go Wireless
|
||||
0x0feb 0x2004 CRS Electronic 3.3 Digital Camera
|
||||
0x0feb 0x2004 Packard Bell DSC-300
|
||||
0x055f 0xb500 Mustek MDC 3000
|
||||
0x08ca 0x2062 Aiptek PocketDV 5700
|
||||
0x052b 0x1a18 Chiphead Megapix V12
|
||||
0x04c8 0x0729 Konica Revio 2
|
||||
0x04f2 0xa208 Creative PC-CAM 850
|
||||
0x0784 0x0040 Traveler Slimline X5
|
||||
0x06d6 0x0034 Trust Powerc@m 750
|
||||
0x0a17 0x0062 Pentax Optio 50L
|
||||
0x06d6 0x003b Trust Powerc@m 970Z
|
||||
0x0a17 0x004e Pentax Optio 50
|
||||
0x041e 0x405d Creative DiVi CAM 516
|
||||
0x08ca 0x2102 Aiptek DV T300
|
||||
0x06d6 0x003d Trust Powerc@m 910Z
|
||||
====== ======= ============== ====================
|
@ -1,42 +0,0 @@
|
||||
* HDMI CEC GPIO driver
|
||||
|
||||
The HDMI CEC GPIO module supports CEC implementations where the CEC line
|
||||
is hooked up to a pull-up GPIO line and - optionally - the HPD line is
|
||||
hooked up to another GPIO line.
|
||||
|
||||
Please note: the maximum voltage for the CEC line is 3.63V, for the HPD and
|
||||
5V lines it is 5.3V. So you may need some sort of level conversion circuitry
|
||||
when connecting them to a GPIO line.
|
||||
|
||||
Required properties:
|
||||
- compatible: value must be "cec-gpio".
|
||||
- cec-gpios: gpio that the CEC line is connected to. The line should be
|
||||
tagged as open drain.
|
||||
|
||||
If the CEC line is associated with an HDMI receiver/transmitter, then the
|
||||
following property is also required:
|
||||
|
||||
- hdmi-phandle - phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
If the CEC line is not associated with an HDMI receiver/transmitter, then
|
||||
the following property is optional and can be used for debugging HPD changes:
|
||||
|
||||
- hpd-gpios: gpio that the HPD line is connected to.
|
||||
|
||||
This property is optional and can be used for debugging changes on the 5V line:
|
||||
|
||||
- v5-gpios: gpio that the 5V line is connected to.
|
||||
|
||||
Example for the Raspberry Pi 3 where the CEC line is connected to
|
||||
pin 26 aka BCM7 aka CE1 on the GPIO pin header, the HPD line is
|
||||
connected to pin 11 aka BCM17 and the 5V line is connected to pin
|
||||
15 aka BCM22 (some level shifter is needed for the HPD and 5V lines!):
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
cec-gpio {
|
||||
compatible = "cec-gpio";
|
||||
cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
|
||||
hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
v5-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -1,8 +0,0 @@
|
||||
Common bindings for HDMI CEC adapters
|
||||
|
||||
- hdmi-phandle: phandle to the HDMI controller.
|
||||
|
||||
- needs-hpd: if present the CEC support is only available when the HPD
|
||||
is high. Some boards only let the CEC pin through if the HPD is high,
|
||||
for example if there is a level converter that uses the HPD to power
|
||||
up or down.
|
@ -2,8 +2,8 @@
|
||||
# Copyright 2019 BayLibre, SAS
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/media/amlogic,meson-gx-ao-cec.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
$id: http://devicetree.org/schemas/media/cec/amlogic,meson-gx-ao-cec.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Meson AO-CEC Controller
|
||||
|
||||
@ -33,11 +33,8 @@ properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
hdmi-phandle:
|
||||
description: phandle to the HDMI controller
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -81,7 +78,7 @@ required:
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
28
Documentation/devicetree/bindings/media/cec/cec-common.yaml
Normal file
28
Documentation/devicetree/bindings/media/cec/cec-common.yaml
Normal file
@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/cec-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: HDMI CEC Adapters Common Properties
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil@xs4all.nl>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^cec(@[0-9a-f]+|-[0-9]+)?$"
|
||||
|
||||
hdmi-phandle:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the HDMI controller.
|
||||
|
||||
needs-hpd:
|
||||
type: boolean
|
||||
description:
|
||||
The CEC support is only available when the HPD is high. Some boards only
|
||||
let the CEC pin through if the HPD is high, for example if there is a
|
||||
level converter that uses the HPD to power up or down.
|
||||
|
||||
additionalProperties: true
|
74
Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
Normal file
74
Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
Normal file
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/cec-gpio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: HDMI CEC GPIO
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
|
||||
description: |
|
||||
The HDMI CEC GPIO module supports CEC implementations where the CEC line is
|
||||
hooked up to a pull-up GPIO line and - optionally - the HPD line is hooked up
|
||||
to another GPIO line.
|
||||
|
||||
Please note:: the maximum voltage for the CEC line is 3.63V, for the HPD and
|
||||
5V lines it is 5.3V. So you may need some sort of level conversion
|
||||
circuitry when connecting them to a GPIO line.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: cec-gpio
|
||||
|
||||
cec-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO that the CEC line is connected to. The line should be tagged as open
|
||||
drain.
|
||||
|
||||
hpd-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO that the HPD line is connected to. Used for debugging HPD changes
|
||||
when the CEC line is not associated with an HDMI receiver/transmitter.
|
||||
|
||||
v5-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO that the 5V line is connected to. Used for debugging changes on the
|
||||
5V line.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- cec-gpios
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
- if:
|
||||
required:
|
||||
- hdmi-phandle
|
||||
then:
|
||||
properties:
|
||||
hpd-gpios: false
|
||||
|
||||
- if:
|
||||
required:
|
||||
- hpd-gpios
|
||||
then:
|
||||
properties:
|
||||
hdmi-phandle: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
cec {
|
||||
compatible = "cec-gpio";
|
||||
cec-gpios = <&gpio 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
|
||||
hpd-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
v5-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/nvidia,tegra114-cec.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra HDMI CEC
|
||||
|
||||
maintainers:
|
||||
- Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra114-cec
|
||||
- nvidia,tegra124-cec
|
||||
- nvidia,tegra210-cec
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cec
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- hdmi-phandle
|
||||
- interrupts
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra124-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
cec@70015000 {
|
||||
compatible = "nvidia,tegra124-cec";
|
||||
reg = <0x70015000 0x00001000>;
|
||||
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_CEC>;
|
||||
clock-names = "cec";
|
||||
status = "disabled";
|
||||
hdmi-phandle = <&hdmi>;
|
||||
};
|
@ -0,0 +1,66 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/samsung,s5p-cec.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung S5PV210 and Exynos HDMI CEC
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
- Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,s5p-cec
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: hdmicec
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
samsung,syscon-phandle:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to PMU system controller interface
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- hdmi-phandle
|
||||
- interrupts
|
||||
- samsung,syscon-phandle
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/exynos5420.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
cec@101b0000 {
|
||||
compatible = "samsung,s5p-cec";
|
||||
reg = <0x101B0000 0x200>;
|
||||
|
||||
clocks = <&clock CLK_HDMI_CEC>;
|
||||
clock-names = "hdmicec";
|
||||
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
hdmi-phandle = <&hdmi>;
|
||||
needs-hpd;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_cec>;
|
||||
samsung,syscon-phandle = <&pmu_system_controller>;
|
||||
};
|
66
Documentation/devicetree/bindings/media/cec/st,stih-cec.yaml
Normal file
66
Documentation/devicetree/bindings/media/cec/st,stih-cec.yaml
Normal file
@ -0,0 +1,66 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/st,stih-cec.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STIH4xx HDMI CEC
|
||||
|
||||
maintainers:
|
||||
- Alain Volmat <alain.volmat@foss.st.com>
|
||||
|
||||
allOf:
|
||||
- $ref: cec-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stih-cec
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cec-clk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: cec-irq
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- hdmi-phandle
|
||||
- interrupts
|
||||
- resets
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/reset/stih407-resets.h>
|
||||
|
||||
cec@94a087c {
|
||||
compatible = "st,stih-cec";
|
||||
reg = <0x94a087c 0x64>;
|
||||
|
||||
clocks = <&clk_sysin>;
|
||||
clock-names = "cec-clk";
|
||||
hdmi-phandle = <&sti_hdmi>;
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "cec-irq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_cec0_default>;
|
||||
resets = <&softreset STIH407_LPM_SOFTRESET>;
|
||||
};
|
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/cec/st,stm32-cec.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 CEC
|
||||
|
||||
maintainers:
|
||||
- Yannick Fertre <yannick.fertre@foss.st.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: st,stm32-cec
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Module Clock
|
||||
- description: Bus Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cec
|
||||
- const: hdmi-cec
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/stm32mp1-clks.h>
|
||||
cec: cec@40006c00 {
|
||||
compatible = "st,stm32-cec";
|
||||
reg = <0x40006c00 0x400>;
|
||||
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&rcc CEC_K>, <&clk_lse>;
|
||||
clock-names = "cec", "hdmi-cec";
|
||||
};
|
||||
|
||||
...
|
88
Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
Normal file
88
Documentation/devicetree/bindings/media/fsl,imx6ull-pxp.yaml
Normal file
@ -0,0 +1,88 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/fsl,imx6ull-pxp.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Pixel Pipeline
|
||||
|
||||
maintainers:
|
||||
- Philipp Zabel <p.zabel@pengutronix.de>
|
||||
- Michael Tretter <m.tretter@pengutronix.de>
|
||||
|
||||
description:
|
||||
The Pixel Pipeline (PXP) is a memory-to-memory graphics processing engine
|
||||
that supports scaling, colorspace conversion, alpha blending, rotation, and
|
||||
pixel conversion via lookup table. Different versions are present on various
|
||||
i.MX SoCs from i.MX23 to i.MX7.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- fsl,imx6ul-pxp
|
||||
- fsl,imx6ull-pxp
|
||||
- fsl,imx7d-pxp
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx6sll-pxp
|
||||
- fsl,imx6sx-pxp
|
||||
- const: fsl,imx6ull-pxp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: axi
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx6sx-pxp
|
||||
- fsl,imx6ul-pxp
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx6ul-clock.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
pxp: pxp@21cc000 {
|
||||
compatible = "fsl,imx6ull-pxp";
|
||||
reg = <0x021cc000 0x4000>;
|
||||
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-names = "axi";
|
||||
clocks = <&clks IMX6UL_CLK_PXP>;
|
||||
};
|
@ -1,26 +0,0 @@
|
||||
Freescale Pixel Pipeline
|
||||
========================
|
||||
|
||||
The Pixel Pipeline (PXP) is a memory-to-memory graphics processing engine
|
||||
that supports scaling, colorspace conversion, alpha blending, rotation, and
|
||||
pixel conversion via lookup table. Different versions are present on various
|
||||
i.MX SoCs from i.MX23 to i.MX7.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "fsl,<soc>-pxp", where SoC can be one of imx23, imx28,
|
||||
imx6dl, imx6sl, imx6sll, imx6ul, imx6sx, imx6ull, or imx7d.
|
||||
- reg: the register base and size for the device registers
|
||||
- interrupts: the PXP interrupt, two interrupts for imx6ull and imx7d.
|
||||
- clock-names: should be "axi"
|
||||
- clocks: the PXP AXI clock
|
||||
|
||||
Example:
|
||||
|
||||
pxp@21cc000 {
|
||||
compatible = "fsl,imx6ull-pxp";
|
||||
reg = <0x021cc000 0x4000>;
|
||||
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-names = "axi";
|
||||
clocks = <&clks IMX6UL_CLK_PXP>;
|
||||
};
|
@ -1,8 +0,0 @@
|
||||
Asahi Kasei Microdevices AK7375 voice coil lens driver
|
||||
|
||||
AK7375 is a camera voice coil lens.
|
||||
|
||||
Mandatory properties:
|
||||
|
||||
- compatible: "asahi-kasei,ak7375"
|
||||
- reg: I2C slave address
|
@ -0,0 +1,52 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/asahi-kasei,ak7375.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Asahi Kasei Microdevices AK7375 voice coil lens actuator
|
||||
|
||||
maintainers:
|
||||
- Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
|
||||
description:
|
||||
AK7375 is a voice coil motor (VCM) camera lens actuator that
|
||||
is controlled over I2C.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: asahi-kasei,ak7375
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: VDD supply
|
||||
|
||||
vio-supply:
|
||||
description: I/O pull-up supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- vdd-supply
|
||||
- vio-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ak7375: camera-lens@c {
|
||||
compatible = "asahi-kasei,ak7375";
|
||||
reg = <0x0c>;
|
||||
|
||||
vdd-supply = <&vreg_l23a_2p8>;
|
||||
vio-supply = <&vreg_lvs1a_1p8>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -13,6 +13,9 @@ description:
|
||||
The Chrontel CH7322 is a discrete HDMI-CEC controller. It is
|
||||
programmable through I2C and drives a single CEC line.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/cec/cec-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: chrontel,ch7322
|
||||
@ -40,16 +43,12 @@ properties:
|
||||
if in auto mode.
|
||||
maxItems: 1
|
||||
|
||||
# see ../cec.txt
|
||||
hdmi-phandle:
|
||||
description: phandle to the HDMI controller
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
@ -58,7 +57,7 @@ examples:
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
ch7322@75 {
|
||||
cec@75 {
|
||||
compatible = "chrontel,ch7322";
|
||||
reg = <0x75>;
|
||||
interrupts = <47 IRQ_TYPE_EDGE_RISING>;
|
||||
|
@ -39,7 +39,7 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
poc-supply:
|
||||
description: Regulator providing Power over Coax to the cameras
|
||||
description: Regulator providing Power over Coax to all the ports
|
||||
|
||||
enable-gpios:
|
||||
description: GPIO connected to the \#PWDN pin with inverted polarity
|
||||
@ -50,6 +50,21 @@ properties:
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
maxim,bus-width:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 24, 27, 32 ]
|
||||
description: |
|
||||
The GMSL serial data bus width. This setting is normally controlled by
|
||||
the BWS pin, but may be overridden with this property. The value must
|
||||
match the configuration of the remote serializers.
|
||||
|
||||
maxim,i2c-remote-bus-hz:
|
||||
enum: [ 8470, 28300, 84700, 105000, 173000, 339000, 533000, 837000 ]
|
||||
default: 105000
|
||||
description: |
|
||||
The I2C clock frequency for the remote I2C buses. The value must match
|
||||
the configuration of the remote serializers.
|
||||
|
||||
maxim,reverse-channel-microvolt:
|
||||
minimum: 30000
|
||||
maximum: 200000
|
||||
@ -182,21 +197,36 @@ properties:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^port[0-3]-poc-supply$":
|
||||
description: Regulator providing Power over Coax for a particular port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- ports
|
||||
- i2c-mux
|
||||
|
||||
# If 'maxim,gpio-poc' is present, then 'poc-supply' and 'gpio-controller'
|
||||
# are not allowed.
|
||||
if:
|
||||
required:
|
||||
- maxim,gpio-poc
|
||||
then:
|
||||
properties:
|
||||
poc-supply: false
|
||||
gpio-controller: false
|
||||
allOf:
|
||||
# Only one way of specifying power supplies is allowed: 'maxim,gpio-poc',
|
||||
# 'poc-supply' or per-port poc-supply. Additionally, if 'maxim,gpio-poc' is
|
||||
# present, then 'gpio-controller' isn't allowed.
|
||||
- if:
|
||||
required:
|
||||
- maxim,gpio-poc
|
||||
then:
|
||||
properties:
|
||||
poc-supply: false
|
||||
gpio-controller: false
|
||||
patternProperties:
|
||||
"^port[0-3]-poc-supply$": false
|
||||
|
||||
- if:
|
||||
required:
|
||||
- poc-supply
|
||||
then:
|
||||
patternProperties:
|
||||
"^port[0-3]-poc-supply$": false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@ -219,6 +249,7 @@ examples:
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
maxim,i2c-remote-bus-hz = <339000>;
|
||||
maxim,reverse-channel-microvolt = <170000>;
|
||||
|
||||
ports {
|
||||
|
93
Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml
Normal file
93
Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml
Normal file
@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov5670.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Omnivision OV5670 5 Megapixels raw image sensor
|
||||
|
||||
maintainers:
|
||||
- Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
|
||||
description: |-
|
||||
The OV5670 is a 5 Megapixels raw image sensor which provides images in 10-bits
|
||||
RAW BGGR Bayer format on a 2 data lanes MIPI CSI-2 serial interface and is
|
||||
controlled through an I2C compatible control bus.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov5670
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: System clock. From 6 to 27 MHz.
|
||||
maxItems: 1
|
||||
|
||||
powerdown-gpios:
|
||||
description: Reference to the GPIO connected to the PWDNB pin. Active low.
|
||||
|
||||
reset-gpios:
|
||||
description: Reference to the GPIO connected to the XSHUTDOWN pin. Active low.
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analog circuit power. Typically 2.8V.
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital circuit power. Typically 1.2V.
|
||||
|
||||
dovdd-supply:
|
||||
description: Digital I/O circuit power. Typically 2.8V or 1.8V.
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum: [1, 2]
|
||||
|
||||
clock-noncontinuous: true
|
||||
remote-endpoint: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ov5670: sensor@36 {
|
||||
compatible = "ovti,ov5670";
|
||||
reg = <0x36>;
|
||||
|
||||
clocks = <&sensor_xclk>;
|
||||
|
||||
port {
|
||||
ov5670_ep: endpoint {
|
||||
remote-endpoint = <&csi_ep>;
|
||||
data-lanes = <1 2>;
|
||||
clock-noncontinuous;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
122
Documentation/devicetree/bindings/media/i2c/ovti,ov5675.yaml
Normal file
122
Documentation/devicetree/bindings/media/i2c/ovti,ov5675.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (c) 2022 Theobroma Systems Design und Consulting GmbH
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov5675.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Omnivision OV5675 CMOS Sensor
|
||||
|
||||
maintainers:
|
||||
- Quentin Schulz <quentin.schulz@theobroma-systems.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/media/video-interface-devices.yaml#
|
||||
|
||||
description: |
|
||||
The Omnivision OV5675 is a high performance, 1/5-inch, 5 megapixel, CMOS
|
||||
image sensor that delivers 2592x1944 at 30fps. It provides full-frame,
|
||||
sub-sampled, and windowed 10-bit MIPI images in various formats via the
|
||||
Serial Camera Control Bus (SCCB) interface.
|
||||
|
||||
This chip is programmable through I2C and two-wire SCCB. The sensor output
|
||||
is available via CSI-2 serial data output (up to 2-lane).
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov5675
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description:
|
||||
System input clock (aka XVCLK). From 6 to 27 MHz.
|
||||
maxItems: 1
|
||||
|
||||
dovdd-supply:
|
||||
description:
|
||||
Digital I/O voltage supply, 1.8 volts.
|
||||
|
||||
avdd-supply:
|
||||
description:
|
||||
Analog voltage supply, 2.8 volts.
|
||||
|
||||
dvdd-supply:
|
||||
description:
|
||||
Digital core voltage supply, 1.2 volts.
|
||||
|
||||
reset-gpios:
|
||||
description:
|
||||
The phandle and specifier for the GPIO that controls sensor reset.
|
||||
This corresponds to the hardware pin XSHUTDN which is physically
|
||||
active low.
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
# Supports max data transfer of 900 Mbps per lane
|
||||
link-frequencies: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- dovdd-supply
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
- port
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/px30-cru.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ov5675: camera@36 {
|
||||
compatible = "ovti,ov5675";
|
||||
reg = <0x36>;
|
||||
|
||||
reset-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&cif_clkout_m0>;
|
||||
|
||||
clocks = <&cru SCLK_CIF_OUT>;
|
||||
assigned-clocks = <&cru SCLK_CIF_OUT>;
|
||||
assigned-clock-rates = <19200000>;
|
||||
|
||||
avdd-supply = <&vcc_1v8>;
|
||||
dvdd-supply = <&vcc_1v2>;
|
||||
dovdd-supply = <&vcc_2v8>;
|
||||
|
||||
rotation = <90>;
|
||||
orientation = <0>;
|
||||
|
||||
port {
|
||||
ucam_out: endpoint {
|
||||
remote-endpoint = <&mipi_in_ucam>;
|
||||
data-lanes = <1 2>;
|
||||
link-frequencies = /bits/ 64 <450000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
106
Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml
Normal file
106
Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml
Normal file
@ -0,0 +1,106 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/ovti,ov8858.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: OmniVision OV8858 Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
- Nicholas Roth <nicholas@rothemail.net>
|
||||
|
||||
description: |
|
||||
The OmniVision OV8858 is a color CMOS 8 Megapixels (3264x2448) image sensor
|
||||
controlled through an I2C-compatible SCCB bus. The sensor transmits images
|
||||
on a MIPI CSI-2 output interface with up to 4 data lanes.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ovti,ov8858
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: XVCLK external clock
|
||||
|
||||
clock-names:
|
||||
const: xvclk
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital Domain Power Supply
|
||||
|
||||
avdd-supply:
|
||||
description: Analog Domain Power Supply
|
||||
|
||||
dovdd-supply:
|
||||
description: I/O Domain Power Supply
|
||||
|
||||
powerdown-gpios:
|
||||
description: PWDNB powerdown GPIO (active low)
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description: XSHUTDN reset GPIO (active low)
|
||||
|
||||
port:
|
||||
description: MIPI CSI-2 transmitter port
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
#include <dt-bindings/clock/rk3399-cru.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ov8858: camera@36 {
|
||||
compatible = "ovti,ov8858";
|
||||
reg = <0x36>;
|
||||
|
||||
clocks = <&cru SCLK_CIF_OUT>;
|
||||
clock-names = "xvclk";
|
||||
assigned-clocks = <&cru SCLK_CIF_OUT>;
|
||||
assigned-clock-rates = <24000000>;
|
||||
|
||||
dovdd-supply = <&vcc1v8_dvp>;
|
||||
|
||||
reset-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>;
|
||||
powerdown-gpios = <&gpio2 RK_PB4 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
ucam_out: endpoint {
|
||||
remote-endpoint = <&mipi_in_ucam>;
|
||||
data-lanes = <1 2 3 4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
106
Documentation/devicetree/bindings/media/i2c/sony,imx296.yaml
Normal file
106
Documentation/devicetree/bindings/media/i2c/sony,imx296.yaml
Normal file
@ -0,0 +1,106 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/sony,imx296.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sony IMX296 1/2.8-Inch CMOS Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
- Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
|
||||
description: |-
|
||||
The Sony IMX296 is a 1/2.9-Inch active pixel type CMOS Solid-state image
|
||||
sensor with square pixel array and 1.58 M effective pixels. This chip
|
||||
features a global shutter with variable charge-integration time. It is
|
||||
programmable through I2C and 4-wire interfaces. The sensor output is
|
||||
available via CSI-2 serial data output (1 Lane).
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- sony,imx296
|
||||
- sony,imx296ll
|
||||
- sony,imx296lq
|
||||
description:
|
||||
The IMX296 sensor exists in two different models, a colour variant
|
||||
(IMX296LQ) and a monochrome variant (IMX296LL). The device exposes the
|
||||
model through registers, allowing for auto-detection with a common
|
||||
"sony,imx296" compatible string. However, some camera modules disable the
|
||||
ability to read the sensor model register, which disables this feature.
|
||||
In those cases, the exact model needs to be specified as "sony,imx296ll"
|
||||
or "sony,imx296lq".
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
description: Input clock (37.125 MHz, 54 MHz or 74.25 MHz)
|
||||
items:
|
||||
- const: inck
|
||||
|
||||
avdd-supply:
|
||||
description: Analog power supply (3.3V)
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital power supply (1.2V)
|
||||
|
||||
ovdd-supply:
|
||||
description: Interface power supply (1.8V)
|
||||
|
||||
reset-gpios:
|
||||
description: Sensor reset (XCLR) GPIO
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
- ovdd-supply
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
imx296: camera-sensor@1a {
|
||||
compatible = "sony,imx296";
|
||||
reg = <0x1a>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&camera_rear_default>;
|
||||
|
||||
clocks = <&gcc 90>;
|
||||
clock-names = "inck";
|
||||
|
||||
avdd-supply = <&camera_vdda_3v3>;
|
||||
dvdd-supply = <&camera_vddd_1v2>;
|
||||
ovdd-supply = <&camera_vddo_1v8>;
|
||||
|
||||
reset-gpios = <&msmgpio 35 GPIO_ACTIVE_LOW>;
|
||||
|
||||
port {
|
||||
imx296_ep: endpoint {
|
||||
remote-endpoint = <&csiphy0_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
122
Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
Normal file
122
Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/sony,imx415.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sony IMX415 CMOS Image Sensor
|
||||
|
||||
maintainers:
|
||||
- Michael Riesch <michael.riesch@wolfvision.net>
|
||||
|
||||
description: |-
|
||||
The Sony IMX415 is a diagonal 6.4 mm (Type 1/2.8) CMOS active pixel type
|
||||
solid-state image sensor with a square pixel array and 8.46 M effective
|
||||
pixels. This chip operates with analog 2.9 V, digital 1.1 V, and interface
|
||||
1.8 V triple power supply, and has low power consumption.
|
||||
The IMX415 is programmable through I2C interface. The sensor output is
|
||||
available via CSI-2 serial data output (two or four lanes).
|
||||
|
||||
allOf:
|
||||
- $ref: ../video-interface-devices.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sony,imx415
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: Input clock (24 MHz, 27 MHz, 37.125 MHz, 72 MHz or 74.25 MHz)
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description: Analog power supply (2.9 V)
|
||||
|
||||
dvdd-supply:
|
||||
description: Digital power supply (1.1 V)
|
||||
|
||||
ovdd-supply:
|
||||
description: Interface power supply (1.8 V)
|
||||
|
||||
reset-gpios:
|
||||
description: Sensor reset (XCLR) GPIO
|
||||
maxItems: 1
|
||||
|
||||
flash-leds: true
|
||||
|
||||
lens-focus: true
|
||||
|
||||
orientation: true
|
||||
|
||||
rotation: true
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
|
||||
properties:
|
||||
endpoint:
|
||||
$ref: /schemas/media/video-interfaces.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
data-lanes:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
- items:
|
||||
- const: 1
|
||||
- const: 2
|
||||
- const: 3
|
||||
- const: 4
|
||||
|
||||
required:
|
||||
- data-lanes
|
||||
- link-frequencies
|
||||
|
||||
required:
|
||||
- endpoint
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- avdd-supply
|
||||
- dvdd-supply
|
||||
- ovdd-supply
|
||||
- port
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
imx415: camera-sensor@1a {
|
||||
compatible = "sony,imx415";
|
||||
reg = <0x1a>;
|
||||
avdd-supply = <&vcc2v9_cam>;
|
||||
clocks = <&clock_cam>;
|
||||
dvdd-supply = <&vcc1v1_cam>;
|
||||
lens-focus = <&vcm>;
|
||||
orientation = <2>;
|
||||
ovdd-supply = <&vcc1v8_cam>;
|
||||
reset-gpios = <&gpio_expander 14 GPIO_ACTIVE_LOW>;
|
||||
rotation = <180>;
|
||||
|
||||
port {
|
||||
imx415_ep: endpoint {
|
||||
data-lanes = <1 2 3 4>;
|
||||
link-frequencies = /bits/ 64 <445500000>;
|
||||
remote-endpoint = <&mipi_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -37,6 +37,9 @@ properties:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
|
||||
@ -50,6 +53,18 @@ required:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,imx8mq-csi
|
||||
- fsl,imx8mm-csi
|
||||
then:
|
||||
required:
|
||||
- power-domains
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx7d-clock.h>
|
||||
|
@ -1,36 +0,0 @@
|
||||
* Samsung HDMI CEC driver
|
||||
|
||||
The HDMI CEC module is present is Samsung SoCs and its purpose is to
|
||||
handle communication between HDMI connected devices over the CEC bus.
|
||||
|
||||
Required properties:
|
||||
- compatible : value should be following
|
||||
"samsung,s5p-cec"
|
||||
|
||||
- reg : Physical base address of the IP registers and length of memory
|
||||
mapped region.
|
||||
|
||||
- interrupts : HDMI CEC interrupt number to the CPU.
|
||||
- clocks : from common clock binding: handle to HDMI CEC clock.
|
||||
- clock-names : from common clock binding: must contain "hdmicec",
|
||||
corresponding to entry in the clocks property.
|
||||
- samsung,syscon-phandle - phandle to the PMU system controller
|
||||
- hdmi-phandle - phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
Optional:
|
||||
- needs-hpd : if present the CEC support is only available when the HPD
|
||||
is high. See cec.txt for more details.
|
||||
|
||||
Example:
|
||||
|
||||
hdmicec: cec@100b0000 {
|
||||
compatible = "samsung,s5p-cec";
|
||||
reg = <0x100B0000 0x200>;
|
||||
interrupts = <0 114 0>;
|
||||
clocks = <&clock CLK_HDMI_CEC>;
|
||||
clock-names = "hdmicec";
|
||||
samsung,syscon-phandle = <&pmu_system_controller>;
|
||||
hdmi-phandle = <&hdmi>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&hdmi_cec>;
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
STMicroelectronics STIH4xx HDMI CEC driver
|
||||
|
||||
Required properties:
|
||||
- compatible : value should be "st,stih-cec"
|
||||
- reg : Physical base address of the IP registers and length of memory
|
||||
mapped region.
|
||||
- clocks : from common clock binding: handle to HDMI CEC clock
|
||||
- interrupts : HDMI CEC interrupt number to the CPU.
|
||||
- pinctrl-names: Contains only one value - "default"
|
||||
- pinctrl-0: Specifies the pin control groups used for CEC hardware.
|
||||
- resets: Reference to a reset controller
|
||||
- hdmi-phandle: Phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
Example for STIH407:
|
||||
|
||||
sti-cec@94a087c {
|
||||
compatible = "st,stih-cec";
|
||||
reg = <0x94a087c 0x64>;
|
||||
clocks = <&clk_sysin>;
|
||||
clock-names = "cec-clk";
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "cec-irq";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_cec0_default>;
|
||||
resets = <&softreset STIH407_LPM_SOFTRESET>;
|
||||
hdmi-phandle = <&hdmi>;
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
* Tegra HDMI CEC hardware
|
||||
|
||||
The HDMI CEC module is present in Tegra SoCs and its purpose is to
|
||||
handle communication between HDMI connected devices over the CEC bus.
|
||||
|
||||
Required properties:
|
||||
- compatible : value should be one of the following:
|
||||
"nvidia,tegra114-cec"
|
||||
"nvidia,tegra124-cec"
|
||||
"nvidia,tegra210-cec"
|
||||
- reg : Physical base address of the IP registers and length of memory
|
||||
mapped region.
|
||||
- interrupts : HDMI CEC interrupt number to the CPU.
|
||||
- clocks : from common clock binding: handle to HDMI CEC clock.
|
||||
- clock-names : from common clock binding: must contain "cec",
|
||||
corresponding to the entry in the clocks property.
|
||||
- hdmi-phandle : phandle to the HDMI controller, see also cec.txt.
|
||||
|
||||
Example:
|
||||
|
||||
cec@70015000 {
|
||||
compatible = "nvidia,tegra124-cec";
|
||||
reg = <0x0 0x70015000 0x0 0x00001000>;
|
||||
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_CEC>;
|
||||
clock-names = "cec";
|
||||
};
|
@ -1,56 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
The cpia2 driver
|
||||
================
|
||||
|
||||
Authors: Peter Pregler <Peter_Pregler@email.com>,
|
||||
Scott J. Bertin <scottbertin@yahoo.com>, and
|
||||
Jarl Totland <Jarl.Totland@bdc.no> for the original cpia driver, which
|
||||
this one was modelled from.
|
||||
|
||||
|
||||
Notes to developers
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- This is a driver version stripped of the 2.4 back compatibility
|
||||
and old MJPEG ioctl API. See cpia2.sf.net for 2.4 support.
|
||||
|
||||
Programmer's overview of cpia2 driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Cpia2 is the second generation video coprocessor from VLSI Vision Ltd (now a
|
||||
division of ST Microelectronics). There are two versions. The first is the
|
||||
STV0672, which is capable of up to 30 frames per second (fps) in frame sizes
|
||||
up to CIF, and 15 fps for VGA frames. The STV0676 is an improved version,
|
||||
which can handle up to 30 fps VGA. Both coprocessors can be attached to two
|
||||
CMOS sensors - the vvl6410 CIF sensor and the vvl6500 VGA sensor. These will
|
||||
be referred to as the 410 and the 500 sensors, or the CIF and VGA sensors.
|
||||
|
||||
The two chipsets operate almost identically. The core is an 8051 processor,
|
||||
running two different versions of firmware. The 672 runs the VP4 video
|
||||
processor code, the 676 runs VP5. There are a few differences in register
|
||||
mappings for the two chips. In these cases, the symbols defined in the
|
||||
header files are marked with VP4 or VP5 as part of the symbol name.
|
||||
|
||||
The cameras appear externally as three sets of registers. Setting register
|
||||
values is the only way to control the camera. Some settings are
|
||||
interdependant, such as the sequence required to power up the camera. I will
|
||||
try to make note of all of these cases.
|
||||
|
||||
The register sets are called blocks. Block 0 is the system block. This
|
||||
section is always powered on when the camera is plugged in. It contains
|
||||
registers that control housekeeping functions such as powering up the video
|
||||
processor. The video processor is the VP block. These registers control
|
||||
how the video from the sensor is processed. Examples are timing registers,
|
||||
user mode (vga, qvga), scaling, cropping, framerates, and so on. The last
|
||||
block is the video compressor (VC). The video stream sent from the camera is
|
||||
compressed as Motion JPEG (JPEGA). The VC controls all of the compression
|
||||
parameters. Looking at the file cpia2_registers.h, you can get a full view
|
||||
of these registers and the possible values for most of them.
|
||||
|
||||
One or more registers can be set or read by sending a usb control message to
|
||||
the camera. There are three modes for this. Block mode requests a number
|
||||
of contiguous registers. Random mode reads or writes random registers with
|
||||
a tuple structure containing address/value pairs. The repeat mode is only
|
||||
used by VP4 to load a firmware patch. It contains a starting address and
|
||||
a sequence of bytes to be written into a gpio port.
|
@ -13,7 +13,6 @@ Video4Linux (V4L) drivers
|
||||
:maxdepth: 5
|
||||
|
||||
bttv-devel
|
||||
cpia2_devel
|
||||
cx2341x-devel
|
||||
cx88-devel
|
||||
fimc-devel
|
||||
|
@ -232,12 +232,10 @@ prevent link states from being modified during streaming by calling
|
||||
|
||||
The function will mark all the pads which are part of the pipeline as streaming.
|
||||
|
||||
The struct media_pipeline instance pointed to by
|
||||
the pipe argument will be stored in every pad in the pipeline.
|
||||
Drivers should embed the struct media_pipeline
|
||||
in higher-level pipeline structures and can then access the
|
||||
pipeline through the struct media_pad
|
||||
pipe field.
|
||||
The struct media_pipeline instance pointed to by the pipe argument will be
|
||||
stored in every pad in the pipeline. Drivers should embed the struct
|
||||
media_pipeline in higher-level pipeline structures and can then access the
|
||||
pipeline through the struct media_pad pipe field.
|
||||
|
||||
Calls to :c:func:`media_pipeline_start()` can be nested.
|
||||
The pipeline pointer must be identical for all nested calls to the function.
|
||||
|
@ -593,6 +593,14 @@ before calling v4l2_subdev_init_finalize():
|
||||
|
||||
This shares the driver's private mutex between the controls and the states.
|
||||
|
||||
Streams, multiplexed media pads and internal routing
|
||||
----------------------------------------------------
|
||||
|
||||
A subdevice driver can implement support for multiplexed streams by setting
|
||||
the V4L2_SUBDEV_FL_STREAMS subdev flag and implementing support for
|
||||
centrally managed subdev active state, routing and stream based
|
||||
configuration.
|
||||
|
||||
V4L2 sub-device functions and data structures
|
||||
---------------------------------------------
|
||||
|
||||
|
@ -23,7 +23,7 @@ proprietary mode.
|
||||
|
||||
More details on the ASPEED video hardware operations can be found in
|
||||
*chapter 6.2.16 KVM Video Driver* of SDK_User_Guide which available on
|
||||
AspeedTech-BMC/openbmc/releases.
|
||||
`github <https://github.com/AspeedTech-BMC/openbmc/releases/>`__.
|
||||
|
||||
The ASPEED video driver implements the following driver-specific control:
|
||||
|
||||
|
@ -37,7 +37,6 @@ For more details see the file COPYING in the source distribution of Linux.
|
||||
dw100
|
||||
imx-uapi
|
||||
max2175
|
||||
meye-uapi
|
||||
omap3isp-uapi
|
||||
st-vgxy61
|
||||
uvcvideo
|
||||
|
@ -1,53 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. include:: <isonum.txt>
|
||||
|
||||
Vaio Picturebook Motion Eye Camera Driver
|
||||
=========================================
|
||||
|
||||
Copyright |copy| 2001-2004 Stelian Pop <stelian@popies.net>
|
||||
|
||||
Copyright |copy| 2001-2002 Alcôve <www.alcove.com>
|
||||
|
||||
Copyright |copy| 2000 Andrew Tridgell <tridge@samba.org>
|
||||
|
||||
Private API
|
||||
-----------
|
||||
|
||||
The driver supports frame grabbing with the video4linux API,
|
||||
so all video4linux tools (like xawtv) should work with this driver.
|
||||
|
||||
Besides the video4linux interface, the driver has a private interface
|
||||
for accessing the Motion Eye extended parameters (camera sharpness,
|
||||
agc, video framerate), the snapshot and the MJPEG capture facilities.
|
||||
|
||||
This interface consists of several ioctls (prototypes and structures
|
||||
can be found in include/linux/meye.h):
|
||||
|
||||
MEYEIOC_G_PARAMS and MEYEIOC_S_PARAMS
|
||||
Get and set the extended parameters of the motion eye camera.
|
||||
The user should always query the current parameters with
|
||||
MEYEIOC_G_PARAMS, change what he likes and then issue the
|
||||
MEYEIOC_S_PARAMS call (checking for -EINVAL). The extended
|
||||
parameters are described by the meye_params structure.
|
||||
|
||||
|
||||
MEYEIOC_QBUF_CAPT
|
||||
Queue a buffer for capture (the buffers must have been
|
||||
obtained with a VIDIOCGMBUF call and mmap'ed by the
|
||||
application). The argument to MEYEIOC_QBUF_CAPT is the
|
||||
buffer number to queue (or -1 to end capture). The first
|
||||
call to MEYEIOC_QBUF_CAPT starts the streaming capture.
|
||||
|
||||
MEYEIOC_SYNC
|
||||
Takes as an argument the buffer number you want to sync.
|
||||
This ioctl blocks until the buffer is filled and ready
|
||||
for the application to use. It returns the buffer size.
|
||||
|
||||
MEYEIOC_STILLCAPT and MEYEIOC_STILLJCAPT
|
||||
Takes a snapshot in an uncompressed or compressed jpeg format.
|
||||
This ioctl blocks until the snapshot is done and returns (for
|
||||
jpeg snapshot) the size of the image. The image data is
|
||||
available from the first mmap'ed buffer.
|
||||
|
||||
Look at the 'motioneye' application code for an actual example.
|
@ -29,6 +29,8 @@ will feature a character device node on which ioctls can be called to
|
||||
|
||||
- negotiate image formats on individual pads
|
||||
|
||||
- inspect and modify internal data routing between pads of the same entity
|
||||
|
||||
Sub-device character device nodes, conventionally named
|
||||
``/dev/v4l-subdev*``, use major number 81.
|
||||
|
||||
@ -404,6 +406,8 @@ pixel array is not rectangular but cross-shaped or round. The maximum
|
||||
size may also be smaller than the BOUNDS rectangle.
|
||||
|
||||
|
||||
.. _format-propagation:
|
||||
|
||||
Order of configuration and format propagation
|
||||
---------------------------------------------
|
||||
|
||||
@ -501,3 +505,165 @@ source pads.
|
||||
:maxdepth: 1
|
||||
|
||||
subdev-formats
|
||||
|
||||
Streams, multiplexed media pads and internal routing
|
||||
----------------------------------------------------
|
||||
|
||||
Simple V4L2 sub-devices do not support multiple, unrelated video streams,
|
||||
and only a single stream can pass through a media link and a media pad.
|
||||
Thus each pad contains a format and selection configuration for that
|
||||
single stream. A subdev can do stream processing and split a stream into
|
||||
two or compose two streams into one, but the inputs and outputs for the
|
||||
subdev are still a single stream per pad.
|
||||
|
||||
Some hardware, e.g. MIPI CSI-2, support multiplexed streams, that is, multiple
|
||||
data streams are transmitted on the same bus, which is represented by a media
|
||||
link connecting a transmitter source pad with a sink pad on the receiver. For
|
||||
example, a camera sensor can produce two distinct streams, a pixel stream and a
|
||||
metadata stream, which are transmitted on the multiplexed data bus, represented
|
||||
by a media link which connects the single sensor's source pad with the receiver
|
||||
sink pad. The stream-aware receiver will de-multiplex the streams received on
|
||||
the its sink pad and allows to route them individually to one of its source
|
||||
pads.
|
||||
|
||||
Subdevice drivers that support multiplexed streams are compatible with
|
||||
non-multiplexed subdev drivers, but, of course, require a routing configuration
|
||||
where the link between those two types of drivers contains only a single
|
||||
stream.
|
||||
|
||||
Understanding streams
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A stream is a stream of content (e.g. pixel data or metadata) flowing through
|
||||
the media pipeline from a source (e.g. a sensor) towards the final sink (e.g. a
|
||||
receiver and demultiplexer in a SoC). Each media link carries all the enabled
|
||||
streams from one end of the link to the other, and sub-devices have routing
|
||||
tables which describe how the incoming streams from sink pads are routed to the
|
||||
source pads.
|
||||
|
||||
A stream ID is a media pad-local identifier for a stream. Streams IDs of
|
||||
the same stream must be equal on both ends of a link. In other words,
|
||||
a particular stream ID must exist on both sides of a media
|
||||
link, but another stream ID can be used for the same stream at the other side
|
||||
of the sub-device.
|
||||
|
||||
A stream at a specific point in the media pipeline is identified by the
|
||||
sub-device and a (pad, stream) pair. For sub-devices that do not support
|
||||
multiplexed streams the 'stream' field is always 0.
|
||||
|
||||
Interaction between routes, streams, formats and selections
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The addition of streams to the V4L2 sub-device interface moves the sub-device
|
||||
formats and selections from pads to (pad, stream) pairs. Besides the
|
||||
usual pad, also the stream ID needs to be provided for setting formats and
|
||||
selections. The order of configuring formats and selections along a stream is
|
||||
the same as without streams (see :ref:`format-propagation`).
|
||||
|
||||
Instead of the sub-device wide merging of streams from all sink pads
|
||||
towards all source pads, data flows for each route are separate from each
|
||||
other. Any number of routes from streams on sink pads towards streams on
|
||||
source pads is allowed, to the extent supported by drivers. For every
|
||||
stream on a source pad, however, only a single route is allowed.
|
||||
|
||||
Any configurations of a stream within a pad, such as format or selections,
|
||||
are independent of similar configurations on other streams. This is
|
||||
subject to change in the future.
|
||||
|
||||
Configuring streams
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The configuration of the streams is done individually for each sub-device and
|
||||
the validity of the streams between sub-devices is validated when the pipeline
|
||||
is started.
|
||||
|
||||
There are three steps in configuring the streams:
|
||||
|
||||
1) Set up links. Connect the pads between sub-devices using the :ref:`Media
|
||||
Controller API <media_controller>`
|
||||
|
||||
2) Streams. Streams are declared and their routing is configured by
|
||||
setting the routing table for the sub-device using
|
||||
:ref:`VIDIOC_SUBDEV_S_ROUTING <VIDIOC_SUBDEV_G_ROUTING>` ioctl. Note that
|
||||
setting the routing table will reset formats and selections in the
|
||||
sub-device to default values.
|
||||
|
||||
3) Configure formats and selections. Formats and selections of each stream
|
||||
are configured separately as documented for plain sub-devices in
|
||||
:ref:`format-propagation`. The stream ID is set to the same stream ID
|
||||
associated with either sink or source pads of routes configured using the
|
||||
:ref:`VIDIOC_SUBDEV_S_ROUTING <VIDIOC_SUBDEV_G_ROUTING>` ioctl.
|
||||
|
||||
Multiplexed streams setup example
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A simple example of a multiplexed stream setup might be as follows:
|
||||
|
||||
- Two identical sensors (Sensor A and Sensor B). Each sensor has a single source
|
||||
pad (pad 0) which carries a pixel data stream.
|
||||
|
||||
- Multiplexer bridge (Bridge). The bridge has two sink pads, connected to the
|
||||
sensors (pads 0, 1), and one source pad (pad 2), which outputs two streams.
|
||||
|
||||
- Receiver in the SoC (Receiver). The receiver has a single sink pad (pad 0),
|
||||
connected to the bridge, and two source pads (pads 1-2), going to the DMA
|
||||
engine. The receiver demultiplexes the incoming streams to the source pads.
|
||||
|
||||
- DMA Engines in the SoC (DMA Engine), one for each stream. Each DMA engine is
|
||||
connected to a single source pad in the receiver.
|
||||
|
||||
The sensors, the bridge and the receiver are modeled as V4L2 sub-devices,
|
||||
exposed to userspace via /dev/v4l-subdevX device nodes. The DMA engines are
|
||||
modeled as V4L2 devices, exposed to userspace via /dev/videoX nodes.
|
||||
|
||||
To configure this pipeline, the userspace must take the following steps:
|
||||
|
||||
1) Set up media links between entities: connect the sensors to the bridge,
|
||||
bridge to the receiver, and the receiver to the DMA engines. This step does
|
||||
not differ from normal non-multiplexed media controller setup.
|
||||
|
||||
2) Configure routing
|
||||
|
||||
.. flat-table:: Bridge routing table
|
||||
:header-rows: 1
|
||||
|
||||
* - Sink Pad/Stream
|
||||
- Source Pad/Stream
|
||||
- Routing Flags
|
||||
- Comments
|
||||
* - 0/0
|
||||
- 2/0
|
||||
- V4L2_SUBDEV_ROUTE_FL_ACTIVE
|
||||
- Pixel data stream from Sensor A
|
||||
* - 1/0
|
||||
- 2/1
|
||||
- V4L2_SUBDEV_ROUTE_FL_ACTIVE
|
||||
- Pixel data stream from Sensor B
|
||||
|
||||
.. flat-table:: Receiver routing table
|
||||
:header-rows: 1
|
||||
|
||||
* - Sink Pad/Stream
|
||||
- Source Pad/Stream
|
||||
- Routing Flags
|
||||
- Comments
|
||||
* - 0/0
|
||||
- 1/0
|
||||
- V4L2_SUBDEV_ROUTE_FL_ACTIVE
|
||||
- Pixel data stream from Sensor A
|
||||
* - 0/1
|
||||
- 2/0
|
||||
- V4L2_SUBDEV_ROUTE_FL_ACTIVE
|
||||
- Pixel data stream from Sensor B
|
||||
|
||||
3) Configure formats and selections
|
||||
|
||||
After configuring routing, the next step is configuring the formats and
|
||||
selections for the streams. This is similar to performing this step without
|
||||
streams, with just one exception: the ``stream`` field needs to be assigned
|
||||
to the value of the stream ID.
|
||||
|
||||
A common way to accomplish this is to start from the sensors and propagate the
|
||||
configurations along the stream towards the receiver,
|
||||
using :ref:`VIDIOC_SUBDEV_S_FMT <VIDIOC_SUBDEV_G_FMT>` ioctls to configure each
|
||||
stream endpoint in each sub-device.
|
||||
|
@ -271,7 +271,7 @@ please make a proposal on the linux-media mailing list.
|
||||
The implementation is based on AST2600 A3 datasheet, revision 0.9, which
|
||||
is not publicly available. Or you can reference Video stream data format
|
||||
– ASPEED mode compression of SDK_User_Guide which available on
|
||||
AspeedTech-BMC/openbmc/releases.
|
||||
`github <https://github.com/AspeedTech-BMC/openbmc/releases/>`__.
|
||||
|
||||
Decoder's implementation can be found here,
|
||||
`aspeed_codec <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
|
||||
|
@ -70,6 +70,7 @@ Function Reference
|
||||
vidioc-subdev-g-crop
|
||||
vidioc-subdev-g-fmt
|
||||
vidioc-subdev-g-frame-interval
|
||||
vidioc-subdev-g-routing
|
||||
vidioc-subdev-g-selection
|
||||
vidioc-subdev-querycap
|
||||
vidioc-subscribe-event
|
||||
|
@ -92,7 +92,10 @@ multiple pads of the same sub-device is not defined.
|
||||
- Frame intervals to be enumerated, from enum
|
||||
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -97,7 +97,10 @@ information about try formats.
|
||||
- Frame sizes to be enumerated, from enum
|
||||
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -73,7 +73,10 @@ information about the try formats.
|
||||
- ``flags``
|
||||
- See :ref:`v4l2-subdev-mbus-code-flags`
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [6]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -96,7 +96,10 @@ modified format should be as close as possible to the original request.
|
||||
- ``rect``
|
||||
- Crop rectangle boundaries, in pixels.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -102,7 +102,10 @@ should be as close as possible to the original request.
|
||||
- Definition of an image format, see :c:type:`v4l2_mbus_framefmt` for
|
||||
details.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -90,7 +90,10 @@ the same sub-device is not defined.
|
||||
- ``interval``
|
||||
- Period, in seconds, between consecutive video frames.
|
||||
* - __u32
|
||||
- ``reserved``\ [9]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
@ -0,0 +1,147 @@
|
||||
.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
|
||||
.. c:namespace:: V4L
|
||||
|
||||
.. _VIDIOC_SUBDEV_G_ROUTING:
|
||||
|
||||
******************************************************
|
||||
ioctl VIDIOC_SUBDEV_G_ROUTING, VIDIOC_SUBDEV_S_ROUTING
|
||||
******************************************************
|
||||
|
||||
Name
|
||||
====
|
||||
|
||||
VIDIOC_SUBDEV_G_ROUTING - VIDIOC_SUBDEV_S_ROUTING - Get or set routing between streams of media pads in a media entity.
|
||||
|
||||
|
||||
Synopsis
|
||||
========
|
||||
|
||||
.. c:macro:: VIDIOC_SUBDEV_G_ROUTING
|
||||
|
||||
``int ioctl(int fd, VIDIOC_SUBDEV_G_ROUTING, struct v4l2_subdev_routing *argp)``
|
||||
|
||||
.. c:macro:: VIDIOC_SUBDEV_S_ROUTING
|
||||
|
||||
``int ioctl(int fd, VIDIOC_SUBDEV_S_ROUTING, struct v4l2_subdev_routing *argp)``
|
||||
|
||||
Arguments
|
||||
=========
|
||||
|
||||
``fd``
|
||||
File descriptor returned by :ref:`open() <func-open>`.
|
||||
|
||||
``argp``
|
||||
Pointer to struct :c:type:`v4l2_subdev_routing`.
|
||||
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
These ioctls are used to get and set the routing in a media entity.
|
||||
The routing configuration determines the flows of data inside an entity.
|
||||
|
||||
Drivers report their current routing tables using the
|
||||
``VIDIOC_SUBDEV_G_ROUTING`` ioctl and application may enable or disable routes
|
||||
with the ``VIDIOC_SUBDEV_S_ROUTING`` ioctl, by adding or removing routes and
|
||||
setting or clearing flags of the ``flags`` field of a
|
||||
struct :c:type:`v4l2_subdev_route`.
|
||||
|
||||
All stream configurations are reset when ``VIDIOC_SUBDEV_S_ROUTING`` is called. This
|
||||
means that the userspace must reconfigure all streams after calling the ioctl
|
||||
with e.g. ``VIDIOC_SUBDEV_S_FMT``.
|
||||
|
||||
Only subdevices which have both sink and source pads can support routing.
|
||||
|
||||
When inspecting routes through ``VIDIOC_SUBDEV_G_ROUTING`` and the application
|
||||
provided ``num_routes`` is not big enough to contain all the available routes
|
||||
the subdevice exposes, drivers return the ENOSPC error code and adjust the
|
||||
value of the ``num_routes`` field. Application should then reserve enough memory
|
||||
for all the route entries and call ``VIDIOC_SUBDEV_G_ROUTING`` again.
|
||||
|
||||
.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
|
||||
|
||||
.. c:type:: v4l2_subdev_routing
|
||||
|
||||
.. flat-table:: struct v4l2_subdev_routing
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u32
|
||||
- ``which``
|
||||
- Format to modified, from enum
|
||||
:ref:`v4l2_subdev_format_whence <v4l2-subdev-format-whence>`.
|
||||
* - struct :c:type:`v4l2_subdev_route`
|
||||
- ``routes[]``
|
||||
- Array of struct :c:type:`v4l2_subdev_route` entries
|
||||
* - __u32
|
||||
- ``num_routes``
|
||||
- Number of entries of the routes array
|
||||
* - __u32
|
||||
- ``reserved``\ [5]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}|
|
||||
|
||||
.. c:type:: v4l2_subdev_route
|
||||
|
||||
.. flat-table:: struct v4l2_subdev_route
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 1 1 2
|
||||
|
||||
* - __u32
|
||||
- ``sink_pad``
|
||||
- Sink pad number.
|
||||
* - __u32
|
||||
- ``sink_stream``
|
||||
- Sink pad stream number.
|
||||
* - __u32
|
||||
- ``source_pad``
|
||||
- Source pad number.
|
||||
* - __u32
|
||||
- ``source_stream``
|
||||
- Source pad stream number.
|
||||
* - __u32
|
||||
- ``flags``
|
||||
- Route enable/disable flags
|
||||
:ref:`v4l2_subdev_routing_flags <v4l2-subdev-routing-flags>`.
|
||||
* - __u32
|
||||
- ``reserved``\ [5]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
|
||||
|
||||
.. _v4l2-subdev-routing-flags:
|
||||
|
||||
.. flat-table:: enum v4l2_subdev_routing_flags
|
||||
:header-rows: 0
|
||||
:stub-columns: 0
|
||||
:widths: 3 1 4
|
||||
|
||||
* - V4L2_SUBDEV_ROUTE_FL_ACTIVE
|
||||
- 0
|
||||
- The route is enabled. Set by applications.
|
||||
|
||||
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.
|
||||
|
||||
ENOSPC
|
||||
The application provided ``num_routes`` is not big enough to contain
|
||||
all the available routes the subdevice exposes.
|
||||
|
||||
EINVAL
|
||||
The sink or source pad identifiers reference a non-existing pad, or reference
|
||||
pads of different types (ie. the sink_pad identifiers refers to a source pad)
|
||||
or the sink or source stream identifiers reference a non-existing stream on
|
||||
the sink or source pad.
|
||||
|
||||
E2BIG
|
||||
The application provided ``num_routes`` for ``VIDIOC_SUBDEV_S_ROUTING`` is
|
||||
larger than the number of routes the driver can handle.
|
@ -94,7 +94,10 @@ Selection targets and flags are documented in
|
||||
- ``r``
|
||||
- Selection rectangle, in pixels.
|
||||
* - __u32
|
||||
- ``reserved``\ [8]
|
||||
- ``stream``
|
||||
- Stream identifier.
|
||||
* - __u32
|
||||
- ``reserved``\ [7]
|
||||
- Reserved for future extensions. Applications and drivers must set
|
||||
the array to zero.
|
||||
|
||||
|
73
MAINTAINERS
73
MAINTAINERS
@ -2739,7 +2739,7 @@ M: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
L: linux-samsung-soc@vger.kernel.org
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/s5p-cec.txt
|
||||
F: Documentation/devicetree/bindings/media/cec/samsung,s5p-cec.yaml
|
||||
F: drivers/media/cec/platform/s5p/
|
||||
|
||||
ARM/SAMSUNG S5P SERIES JPEG CODEC SUPPORT
|
||||
@ -2873,7 +2873,7 @@ M: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
||||
L: linux-tegra@vger.kernel.org
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/tegra-cec.txt
|
||||
F: Documentation/devicetree/bindings/media/cec/nvidia,tegra114-cec.yaml
|
||||
F: drivers/media/cec/platform/tegra/
|
||||
|
||||
ARM/TESLA FSD SoC SUPPORT
|
||||
@ -3073,7 +3073,7 @@ M: Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ak7375.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
|
||||
F: drivers/media/i2c/ak7375.c
|
||||
|
||||
ASAHI KASEI AK8974 DRIVER
|
||||
@ -4699,7 +4699,7 @@ S: Supported
|
||||
W: http://linuxtv.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/ABI/testing/debugfs-cec-error-inj
|
||||
F: Documentation/devicetree/bindings/media/cec.txt
|
||||
F: Documentation/devicetree/bindings/media/cec/cec-common.yaml
|
||||
F: Documentation/driver-api/media/cec-core.rst
|
||||
F: Documentation/userspace-api/media/cec
|
||||
F: drivers/media/cec/
|
||||
@ -4715,7 +4715,7 @@ L: linux-media@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://linuxtv.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/cec-gpio.txt
|
||||
F: Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
|
||||
F: drivers/media/cec/platform/cec-gpio/
|
||||
|
||||
CELL BROADBAND ENGINE ARCHITECTURE
|
||||
@ -13004,7 +13004,6 @@ F: include/media/
|
||||
F: include/uapi/linux/dvb/
|
||||
F: include/uapi/linux/ivtv*
|
||||
F: include/uapi/linux/media.h
|
||||
F: include/uapi/linux/meye.h
|
||||
F: include/uapi/linux/uvcvideo.h
|
||||
F: include/uapi/linux/v4l2-*
|
||||
F: include/uapi/linux/videodev2.h
|
||||
@ -13500,7 +13499,7 @@ L: linux-amlogic@lists.infradead.org
|
||||
S: Supported
|
||||
W: http://linux-meson.com/
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/amlogic,meson-gx-ao-cec.yaml
|
||||
F: Documentation/devicetree/bindings/media/cec/amlogic,meson-gx-ao-cec.yaml
|
||||
F: drivers/media/cec/platform/meson/ao-cec-g12a.c
|
||||
F: drivers/media/cec/platform/meson/ao-cec.c
|
||||
|
||||
@ -14116,13 +14115,6 @@ F: drivers/most/
|
||||
F: drivers/staging/most/
|
||||
F: include/linux/most.h
|
||||
|
||||
MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
|
||||
S: Orphan
|
||||
W: http://popies.net/meye/
|
||||
F: Documentation/userspace-api/media/drivers/meye*
|
||||
F: drivers/staging/media/deprecated/meye/
|
||||
F: include/uapi/linux/meye.h
|
||||
|
||||
MOTORCOMM PHY DRIVER
|
||||
M: Peter Geis <pgwipeout@gmail.com>
|
||||
M: Frank <Frank.Sae@motor-comm.com>
|
||||
@ -15442,6 +15434,7 @@ M: Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml
|
||||
F: drivers/media/i2c/ov5670.c
|
||||
|
||||
OMNIVISION OV5675 SENSOR DRIVER
|
||||
@ -15449,6 +15442,7 @@ M: Shawn Tu <shawnx.tu@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov5675.yaml
|
||||
F: drivers/media/i2c/ov5675.c
|
||||
|
||||
OMNIVISION OV5693 SENSOR DRIVER
|
||||
@ -15498,6 +15492,15 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ov8856.yaml
|
||||
F: drivers/media/i2c/ov8856.c
|
||||
|
||||
OMNIVISION OV8858 SENSOR DRIVER
|
||||
M: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
|
||||
M: Nicholas Roth <nicholas@rothemail.net>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/ovti,ov8858.yaml
|
||||
F: drivers/media/i2c/ov8858.c
|
||||
|
||||
OMNIVISION OV9282 SENSOR DRIVER
|
||||
M: Paul J. Murphy <paul.j.murphy@intel.com>
|
||||
M: Daniele Alessandrelli <daniele.alessandrelli@intel.com>
|
||||
@ -18405,7 +18408,9 @@ M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: drivers/staging/media/deprecated/saa7146/
|
||||
F: drivers/media/common/saa7146/
|
||||
F: drivers/media/pci/saa7146/
|
||||
F: include/media/drv-intf/saa7146*
|
||||
|
||||
SAFESETID SECURITY MODULE
|
||||
M: Micah Morton <mortonm@chromium.org>
|
||||
@ -19464,6 +19469,15 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx290.yaml
|
||||
F: drivers/media/i2c/imx290.c
|
||||
|
||||
SONY IMX296 SENSOR DRIVER
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx296.yaml
|
||||
F: drivers/media/i2c/imx296.c
|
||||
|
||||
SONY IMX319 SENSOR DRIVER
|
||||
M: Bingbu Cao <bingbu.cao@intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
@ -19505,6 +19519,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
|
||||
F: drivers/media/i2c/imx412.c
|
||||
|
||||
SONY IMX415 SENSOR DRIVER
|
||||
M: Michael Riesch <michael.riesch@wolfvision.net>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx415.yaml
|
||||
F: drivers/media/i2c/imx415.c
|
||||
|
||||
SONY MEMORYSTICK SUBSYSTEM
|
||||
M: Maxim Levitsky <maximlevitsky@gmail.com>
|
||||
M: Alex Dubov <oakad@yahoo.com>
|
||||
@ -19951,7 +19973,7 @@ F: sound/soc/sti/
|
||||
STI CEC DRIVER
|
||||
M: Alain Volmat <alain.volmat@foss.st.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/media/stih-cec.txt
|
||||
F: Documentation/devicetree/bindings/media/cec/st,stih-cec.yaml
|
||||
F: drivers/media/cec/platform/sti/
|
||||
|
||||
STK1160 USB VIDEO CAPTURE DRIVER
|
||||
@ -21027,15 +21049,6 @@ W: http://sourceforge.net/projects/tlan/
|
||||
F: Documentation/networking/device_drivers/ethernet/ti/tlan.rst
|
||||
F: drivers/net/ethernet/ti/tlan.*
|
||||
|
||||
TM6000 VIDEO4LINUX DRIVER
|
||||
M: Mauro Carvalho Chehab <mchehab@kernel.org>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Odd fixes
|
||||
W: https://linuxtv.org
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/admin-guide/media/tm6000*
|
||||
F: drivers/staging/media/deprecated/tm6000/
|
||||
|
||||
TMIO/SDHI MMC DRIVER
|
||||
M: Wolfram Sang <wsa+renesas@sang-engineering.com>
|
||||
L: linux-mmc@vger.kernel.org
|
||||
@ -21785,16 +21798,6 @@ S: Orphan
|
||||
W: http://linux-lc100020.sourceforge.net
|
||||
F: drivers/net/wireless/zydas/zd1201.*
|
||||
|
||||
USB ZR364XX DRIVER
|
||||
M: Antoine Jacquet <royale@zerezo.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://royale.zerezo.com/zr364xx/
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/admin-guide/media/zr364xx*
|
||||
F: drivers/staging/media/deprecated/zr364xx/
|
||||
|
||||
USER DATAGRAM PROTOCOL (UDP)
|
||||
M: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
|
||||
S: Maintained
|
||||
|
@ -25,6 +25,7 @@ config VIDEO_TVEEPROM
|
||||
depends on I2C
|
||||
|
||||
source "drivers/media/common/b2c2/Kconfig"
|
||||
source "drivers/media/common/saa7146/Kconfig"
|
||||
source "drivers/media/common/siano/Kconfig"
|
||||
source "drivers/media/common/v4l2-tpg/Kconfig"
|
||||
source "drivers/media/common/videobuf2/Kconfig"
|
||||
|
@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y += b2c2/ siano/ v4l2-tpg/ videobuf2/
|
||||
obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/ videobuf2/
|
||||
|
||||
# Please keep it alphabetically sorted by Kconfig name
|
||||
# (e. g. LC_ALL=C sort Makefile)
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <media/drv-intf/saa7146.h>
|
||||
#include <linux/module.h>
|
||||
#include "saa7146.h"
|
||||
|
||||
static int saa7146_num;
|
||||
|
@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <media/drv-intf/saa7146_vv.h>
|
||||
#include <linux/module.h>
|
||||
#include "saa7146_vv.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* resource management functions, shamelessly stolen from saa7134 driver */
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/export.h>
|
||||
#include "saa7146_vv.h"
|
||||
#include <media/drv-intf/saa7146_vv.h>
|
||||
|
||||
static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include "saa7146_vv.h"
|
||||
#include <media/drv-intf/saa7146_vv.h>
|
||||
|
||||
static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
|
||||
{
|
@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "saa7146_vv.h"
|
||||
#include <media/drv-intf/saa7146_vv.h>
|
||||
|
||||
static int vbi_pixel_to_capture = 720 * 2;
|
||||
|
@ -1,10 +1,10 @@
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <media/drv-intf/saa7146_vv.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "saa7146_vv.h"
|
||||
|
||||
static int max_memory = 32;
|
||||
|
@ -502,27 +502,11 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
|
||||
* related information, if no buffers are left return the queue to an
|
||||
* uninitialized state. Might be called even if the queue has already been freed.
|
||||
*/
|
||||
static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
||||
static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
||||
{
|
||||
unsigned int buffer;
|
||||
|
||||
/*
|
||||
* Sanity check: when preparing a buffer the queue lock is released for
|
||||
* a short while (see __buf_prepare for the details), which would allow
|
||||
* a race with a reqbufs which can call this function. Removing the
|
||||
* buffers from underneath __buf_prepare is obviously a bad idea, so we
|
||||
* check if any of the buffers is in the state PREPARING, and if so we
|
||||
* just return -EAGAIN.
|
||||
*/
|
||||
for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
|
||||
++buffer) {
|
||||
if (q->bufs[buffer] == NULL)
|
||||
continue;
|
||||
if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
|
||||
dprintk(q, 1, "preparing buffers, cannot free\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
lockdep_assert_held(&q->mmap_lock);
|
||||
|
||||
/* Call driver-provided cleanup function for each buffer, if provided */
|
||||
for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
|
||||
@ -616,7 +600,6 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
|
||||
q->memory = VB2_MEMORY_UNKNOWN;
|
||||
INIT_LIST_HEAD(&q->queued_list);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb)
|
||||
@ -798,10 +781,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
|
||||
* queued without ever calling STREAMON.
|
||||
*/
|
||||
__vb2_queue_cancel(q);
|
||||
ret = __vb2_queue_free(q, q->num_buffers);
|
||||
__vb2_queue_free(q, q->num_buffers);
|
||||
mutex_unlock(&q->mmap_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* In case of REQBUFS(0) return immediately without calling
|
||||
|
@ -2162,11 +2162,11 @@ int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
|
||||
else
|
||||
*task_completed = 0;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
if (cpu_status != 0) {
|
||||
*task_completed = 0;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status);
|
||||
|
@ -833,12 +833,12 @@ int cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sync_stat == 6) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret =
|
||||
@ -854,7 +854,7 @@ int cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd
|
||||
@ -893,15 +893,15 @@ int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ts_lock) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
|
||||
return ret;
|
||||
return 0;
|
||||
} else if (!unlock_detected) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret =
|
||||
@ -915,5 +915,5 @@ int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1024,12 +1024,12 @@ int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sync_stat == 6) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret =
|
||||
@ -1045,7 +1045,7 @@ int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd
|
||||
@ -1084,15 +1084,15 @@ int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ts_lock) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
|
||||
return ret;
|
||||
return 0;
|
||||
} else if (!unlock_detected) {
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret =
|
||||
@ -1106,7 +1106,7 @@ int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd
|
||||
else
|
||||
*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd
|
||||
|
@ -9539,7 +9539,8 @@ ctrl_get_qam_sig_quality(struct drx_demod_instance *demod)
|
||||
qam_sl_sig_power = DRXJ_QAM_SL_SIG_POWER_QAM256 << 2;
|
||||
break;
|
||||
default:
|
||||
return -EIO;
|
||||
rc = -EIO;
|
||||
goto rw_error;
|
||||
}
|
||||
|
||||
/* ------------------------------ */
|
||||
@ -10916,7 +10917,8 @@ ctrl_set_standard(struct drx_demod_instance *demod, enum drx_standard *standard)
|
||||
break;
|
||||
case DRX_STANDARD_AUTO:
|
||||
default:
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto rw_error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -11463,7 +11465,8 @@ static int drxj_open(struct drx_demod_instance *demod)
|
||||
|
||||
if (DRX_ISPOWERDOWNMODE(demod->my_common_attr->current_power_mode)) {
|
||||
pr_err("Should powerup before loading the firmware.");
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto rw_error;
|
||||
}
|
||||
|
||||
rc = drx_ctrl_u_code(demod, &ucode_info, UCODE_UPLOAD);
|
||||
|
@ -870,8 +870,9 @@ EXPORT_SYMBOL(dvb_pll_attach);
|
||||
|
||||
|
||||
static int
|
||||
dvb_pll_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
dvb_pll_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct dvb_pll_config *cfg;
|
||||
struct dvb_frontend *fe;
|
||||
unsigned int desc_id;
|
||||
@ -941,7 +942,7 @@ static struct i2c_driver dvb_pll_driver = {
|
||||
.driver = {
|
||||
.name = "dvb_pll",
|
||||
},
|
||||
.probe = dvb_pll_probe,
|
||||
.probe_new = dvb_pll_probe,
|
||||
.remove = dvb_pll_remove,
|
||||
.id_table = dvb_pll_id,
|
||||
};
|
||||
|
@ -1760,9 +1760,9 @@ static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client)
|
||||
return dev->muxc->adapter[0];
|
||||
}
|
||||
|
||||
static int m88ds3103_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int m88ds3103_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct m88ds3103_dev *dev;
|
||||
struct m88ds3103_platform_data *pdata = client->dev.platform_data;
|
||||
int ret;
|
||||
@ -1941,7 +1941,7 @@ static struct i2c_driver m88ds3103_driver = {
|
||||
.name = "m88ds3103",
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = m88ds3103_probe,
|
||||
.probe_new = m88ds3103_probe,
|
||||
.remove = m88ds3103_remove,
|
||||
.id_table = m88ds3103_id_table,
|
||||
};
|
||||
|
@ -1498,6 +1498,7 @@ static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
|
||||
struct dvb_diseqc_master_cmd *cmd)
|
||||
{
|
||||
struct mb86a16_state *state = fe->demodulator_priv;
|
||||
int ret = -EREMOTEIO;
|
||||
int i;
|
||||
u8 regs;
|
||||
|
||||
@ -1510,8 +1511,10 @@ static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
|
||||
|
||||
regs = 0x18;
|
||||
|
||||
if (cmd->msg_len > 5 || cmd->msg_len < 4)
|
||||
return -EINVAL;
|
||||
if (cmd->msg_len > 5 || cmd->msg_len < 4) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < cmd->msg_len; i++) {
|
||||
if (mb86a16_write(state, regs, cmd->msg[i]) < 0)
|
||||
@ -1532,7 +1535,7 @@ static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
|
||||
|
||||
err:
|
||||
dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
|
||||
return -EREMOTEIO;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe,
|
||||
|
@ -673,9 +673,9 @@ static const struct regmap_config regmap_config = {
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static int mn88443x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int mn88443x_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct mn88443x_config *conf = client->dev.platform_data;
|
||||
struct mn88443x_priv *chip;
|
||||
struct device *dev = &client->dev;
|
||||
@ -800,7 +800,7 @@ static struct i2c_driver mn88443x_driver = {
|
||||
.name = "mn88443x",
|
||||
.of_match_table = of_match_ptr(mn88443x_of_match),
|
||||
},
|
||||
.probe = mn88443x_probe,
|
||||
.probe_new = mn88443x_probe,
|
||||
.remove = mn88443x_remove,
|
||||
.id_table = mn88443x_i2c_id,
|
||||
};
|
||||
|
@ -779,9 +779,9 @@ static const struct dvb_frontend_ops tc90522_ops_ter = {
|
||||
};
|
||||
|
||||
|
||||
static int tc90522_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int tc90522_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct tc90522_state *state;
|
||||
struct tc90522_config *cfg;
|
||||
const struct dvb_frontend_ops *ops;
|
||||
@ -840,7 +840,7 @@ static struct i2c_driver tc90522_driver = {
|
||||
.driver = {
|
||||
.name = "tc90522",
|
||||
},
|
||||
.probe = tc90522_probe,
|
||||
.probe_new = tc90522_probe,
|
||||
.remove = tc90522_remove,
|
||||
.id_table = tc90522_id,
|
||||
};
|
||||
|
@ -162,6 +162,19 @@ config VIDEO_IMX290
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx290.
|
||||
|
||||
config VIDEO_IMX296
|
||||
tristate "Sony IMX296 sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select V4L2_FWNODE
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
IMX296 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx296.
|
||||
|
||||
config VIDEO_IMX319
|
||||
tristate "Sony IMX319 sensor support"
|
||||
depends on I2C && VIDEO_DEV
|
||||
@ -228,6 +241,20 @@ config VIDEO_IMX412
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx412.
|
||||
|
||||
config VIDEO_IMX415
|
||||
tristate "Sony IMX415 sensor support"
|
||||
depends on OF_GPIO
|
||||
depends on I2C && VIDEO_DEV
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select MEDIA_CONTROLLER
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
IMX415 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx415.
|
||||
|
||||
config VIDEO_MAX9271_LIB
|
||||
tristate
|
||||
|
||||
@ -645,6 +672,19 @@ config VIDEO_OV8856
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov8856.
|
||||
|
||||
config VIDEO_OV8858
|
||||
tristate "OmniVision OV8858 sensor support"
|
||||
depends on I2C && PM && VIDEO_DEV
|
||||
select MEDIA_CONTROLLER
|
||||
select VIDEO_V4L2_SUBDEV_API
|
||||
select V4L2_FWNODE
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for OmniVision
|
||||
OV8858 camera sensor.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov8858.
|
||||
|
||||
config VIDEO_OV8865
|
||||
tristate "OmniVision OV8865 sensor support"
|
||||
depends on I2C && PM && VIDEO_DEV
|
||||
|
@ -43,11 +43,13 @@ obj-$(CONFIG_VIDEO_IMX219) += imx219.o
|
||||
obj-$(CONFIG_VIDEO_IMX258) += imx258.o
|
||||
obj-$(CONFIG_VIDEO_IMX274) += imx274.o
|
||||
obj-$(CONFIG_VIDEO_IMX290) += imx290.o
|
||||
obj-$(CONFIG_VIDEO_IMX296) += imx296.o
|
||||
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
|
||||
obj-$(CONFIG_VIDEO_IMX334) += imx334.o
|
||||
obj-$(CONFIG_VIDEO_IMX335) += imx335.o
|
||||
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
|
||||
obj-$(CONFIG_VIDEO_IMX412) += imx412.o
|
||||
obj-$(CONFIG_VIDEO_IMX415) += imx415.o
|
||||
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
|
||||
obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
|
||||
obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
|
||||
@ -96,6 +98,7 @@ obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
|
||||
obj-$(CONFIG_VIDEO_OV772X) += ov772x.o
|
||||
obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
|
||||
obj-$(CONFIG_VIDEO_OV8856) += ov8856.o
|
||||
obj-$(CONFIG_VIDEO_OV8858) += ov8858.o
|
||||
obj-$(CONFIG_VIDEO_OV8865) += ov8865.o
|
||||
obj-$(CONFIG_VIDEO_OV9282) += ov9282.o
|
||||
obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
|
||||
|
@ -1393,9 +1393,9 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int adv7180_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int adv7180_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct device_node *np = client->dev.of_node;
|
||||
struct adv7180_state *state;
|
||||
struct v4l2_subdev *sd;
|
||||
@ -1610,7 +1610,7 @@ static struct i2c_driver adv7180_driver = {
|
||||
.pm = ADV7180_PM_OPS,
|
||||
.of_match_table = of_match_ptr(adv7180_of_id),
|
||||
},
|
||||
.probe = adv7180_probe,
|
||||
.probe_new = adv7180_probe,
|
||||
.remove = adv7180_remove,
|
||||
.id_table = adv7180_id,
|
||||
};
|
||||
|
@ -3401,9 +3401,9 @@ static void adv76xx_reset(struct adv76xx_state *state)
|
||||
}
|
||||
}
|
||||
|
||||
static int adv76xx_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int adv76xx_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
static const struct v4l2_dv_timings cea640x480 =
|
||||
V4L2_DV_BT_CEA_640X480P59_94;
|
||||
struct adv76xx_state *state;
|
||||
@ -3686,7 +3686,7 @@ static struct i2c_driver adv76xx_driver = {
|
||||
.name = "adv7604",
|
||||
.of_match_table = of_match_ptr(adv76xx_of_id),
|
||||
},
|
||||
.probe = adv76xx_probe,
|
||||
.probe_new = adv76xx_probe,
|
||||
.remove = adv76xx_remove,
|
||||
.id_table = adv76xx_i2c_id,
|
||||
};
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
|
||||
@ -23,17 +24,29 @@
|
||||
*/
|
||||
#define AK7375_CTRL_STEPS 64
|
||||
#define AK7375_CTRL_DELAY_US 1000
|
||||
/*
|
||||
* The vcm may take up 10 ms (tDELAY) to power on and start taking
|
||||
* I2C messages. Based on AK7371 datasheet.
|
||||
*/
|
||||
#define AK7375_POWER_DELAY_US 10000
|
||||
|
||||
#define AK7375_REG_POSITION 0x0
|
||||
#define AK7375_REG_CONT 0x2
|
||||
#define AK7375_MODE_ACTIVE 0x0
|
||||
#define AK7375_MODE_STANDBY 0x40
|
||||
|
||||
static const char * const ak7375_supply_names[] = {
|
||||
"vdd",
|
||||
"vio",
|
||||
};
|
||||
|
||||
/* ak7375 device structure */
|
||||
struct ak7375_device {
|
||||
struct v4l2_ctrl_handler ctrls_vcm;
|
||||
struct v4l2_subdev sd;
|
||||
struct v4l2_ctrl *focus;
|
||||
struct regulator_bulk_data supplies[ARRAY_SIZE(ak7375_supply_names)];
|
||||
|
||||
/* active or standby mode */
|
||||
bool active;
|
||||
};
|
||||
@ -133,12 +146,24 @@ static int ak7375_probe(struct i2c_client *client)
|
||||
{
|
||||
struct ak7375_device *ak7375_dev;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
ak7375_dev = devm_kzalloc(&client->dev, sizeof(*ak7375_dev),
|
||||
GFP_KERNEL);
|
||||
if (!ak7375_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ak7375_supply_names); i++)
|
||||
ak7375_dev->supplies[i].supply = ak7375_supply_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(&client->dev,
|
||||
ARRAY_SIZE(ak7375_supply_names),
|
||||
ak7375_dev->supplies);
|
||||
if (ret) {
|
||||
dev_err_probe(&client->dev, ret, "Failed to get regulators\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
v4l2_i2c_subdev_init(&ak7375_dev->sd, client, &ak7375_ops);
|
||||
ak7375_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
ak7375_dev->sd.internal_ops = &ak7375_int_ops;
|
||||
@ -208,6 +233,11 @@ static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
|
||||
if (ret)
|
||||
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
|
||||
|
||||
ret = regulator_bulk_disable(ARRAY_SIZE(ak7375_supply_names),
|
||||
ak7375_dev->supplies);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ak7375_dev->active = false;
|
||||
|
||||
return 0;
|
||||
@ -228,6 +258,14 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
|
||||
if (ak7375_dev->active)
|
||||
return 0;
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(ak7375_supply_names),
|
||||
ak7375_dev->supplies);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait for vcm to become ready */
|
||||
usleep_range(AK7375_POWER_DELAY_US, AK7375_POWER_DELAY_US + 500);
|
||||
|
||||
ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_CONT,
|
||||
AK7375_MODE_ACTIVE, 1);
|
||||
if (ret) {
|
||||
|
@ -128,9 +128,9 @@ static const struct v4l2_subdev_ops cs53l32a_ops = {
|
||||
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
|
||||
*/
|
||||
|
||||
static int cs53l32a_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int cs53l32a_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct cs53l32a_state *state;
|
||||
struct v4l2_subdev *sd;
|
||||
int i;
|
||||
@ -209,7 +209,7 @@ static struct i2c_driver cs53l32a_driver = {
|
||||
.driver = {
|
||||
.name = "cs53l32a",
|
||||
},
|
||||
.probe = cs53l32a_probe,
|
||||
.probe_new = cs53l32a_probe,
|
||||
.remove = cs53l32a_remove,
|
||||
.id_table = cs53l32a_id,
|
||||
};
|
||||
|
@ -42,10 +42,16 @@
|
||||
/* External clock frequency is 24.0M */
|
||||
#define IMX219_XCLK_FREQ 24000000
|
||||
|
||||
/* Pixel rate is fixed at 182.4M for all the modes */
|
||||
/* Pixel rate is fixed for all the modes */
|
||||
#define IMX219_PIXEL_RATE 182400000
|
||||
#define IMX219_PIXEL_RATE_4LANE 280800000
|
||||
|
||||
#define IMX219_DEFAULT_LINK_FREQ 456000000
|
||||
#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000
|
||||
|
||||
#define IMX219_REG_CSI_LANE_MODE 0x0114
|
||||
#define IMX219_CSI_2_LANE_MODE 0x01
|
||||
#define IMX219_CSI_4_LANE_MODE 0x03
|
||||
|
||||
/* V_TIMING internal */
|
||||
#define IMX219_REG_VTS 0x0160
|
||||
@ -89,6 +95,12 @@
|
||||
|
||||
#define IMX219_REG_ORIENTATION 0x0172
|
||||
|
||||
/* Binning Mode */
|
||||
#define IMX219_REG_BINNING_MODE 0x0174
|
||||
#define IMX219_BINNING_NONE 0x0000
|
||||
#define IMX219_BINNING_2X2 0x0101
|
||||
#define IMX219_BINNING_2X2_ANALOG 0x0303
|
||||
|
||||
/* Test Pattern Control */
|
||||
#define IMX219_REG_TEST_PATTERN 0x0600
|
||||
#define IMX219_TEST_PATTERN_DISABLE 0
|
||||
@ -143,6 +155,58 @@ struct imx219_mode {
|
||||
|
||||
/* Default register values */
|
||||
struct imx219_reg_list reg_list;
|
||||
|
||||
/* 2x2 binning is used */
|
||||
bool binning;
|
||||
};
|
||||
|
||||
static const struct imx219_reg imx219_common_regs[] = {
|
||||
{0x0100, 0x00}, /* Mode Select */
|
||||
|
||||
/* To Access Addresses 3000-5fff, send the following commands */
|
||||
{0x30eb, 0x0c},
|
||||
{0x30eb, 0x05},
|
||||
{0x300a, 0xff},
|
||||
{0x300b, 0xff},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x09},
|
||||
|
||||
/* PLL Clock Table */
|
||||
{0x0301, 0x05}, /* VTPXCK_DIV */
|
||||
{0x0303, 0x01}, /* VTSYSCK_DIV */
|
||||
{0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */
|
||||
{0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */
|
||||
{0x0306, 0x00}, /* PLL_VT_MPY */
|
||||
{0x0307, 0x39},
|
||||
{0x030b, 0x01}, /* OP_SYS_CLK_DIV */
|
||||
{0x030c, 0x00}, /* PLL_OP_MPY */
|
||||
{0x030d, 0x72},
|
||||
|
||||
/* Undocumented registers */
|
||||
{0x455e, 0x00},
|
||||
{0x471e, 0x4b},
|
||||
{0x4767, 0x0f},
|
||||
{0x4750, 0x14},
|
||||
{0x4540, 0x00},
|
||||
{0x47b4, 0x14},
|
||||
{0x4713, 0x30},
|
||||
{0x478b, 0x10},
|
||||
{0x478f, 0x10},
|
||||
{0x4793, 0x10},
|
||||
{0x4797, 0x0e},
|
||||
{0x479b, 0x0e},
|
||||
|
||||
/* Frame Bank Register Group "A" */
|
||||
{0x0162, 0x0d}, /* Line_Length_A */
|
||||
{0x0163, 0x78},
|
||||
{0x0170, 0x01}, /* X_ODD_INC_A */
|
||||
{0x0171, 0x01}, /* Y_ODD_INC_A */
|
||||
|
||||
/* Output setup registers */
|
||||
{0x0114, 0x01}, /* CSI 2-Lane Mode */
|
||||
{0x0128, 0x00}, /* DPHY Auto Mode */
|
||||
{0x012a, 0x18}, /* EXCK_Freq */
|
||||
{0x012b, 0x00},
|
||||
};
|
||||
|
||||
/*
|
||||
@ -151,17 +215,6 @@ struct imx219_mode {
|
||||
* 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
|
||||
*/
|
||||
static const struct imx219_reg mode_3280x2464_regs[] = {
|
||||
{0x0100, 0x00},
|
||||
{0x30eb, 0x0c},
|
||||
{0x30eb, 0x05},
|
||||
{0x300a, 0xff},
|
||||
{0x300b, 0xff},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x09},
|
||||
{0x0114, 0x01},
|
||||
{0x0128, 0x00},
|
||||
{0x012a, 0x18},
|
||||
{0x012b, 0x00},
|
||||
{0x0164, 0x00},
|
||||
{0x0165, 0x00},
|
||||
{0x0166, 0x0c},
|
||||
@ -174,53 +227,13 @@ static const struct imx219_reg mode_3280x2464_regs[] = {
|
||||
{0x016d, 0xd0},
|
||||
{0x016e, 0x09},
|
||||
{0x016f, 0xa0},
|
||||
{0x0170, 0x01},
|
||||
{0x0171, 0x01},
|
||||
{0x0174, 0x00},
|
||||
{0x0175, 0x00},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x01},
|
||||
{0x0304, 0x03},
|
||||
{0x0305, 0x03},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0x39},
|
||||
{0x030b, 0x01},
|
||||
{0x030c, 0x00},
|
||||
{0x030d, 0x72},
|
||||
{0x0624, 0x0c},
|
||||
{0x0625, 0xd0},
|
||||
{0x0626, 0x09},
|
||||
{0x0627, 0xa0},
|
||||
{0x455e, 0x00},
|
||||
{0x471e, 0x4b},
|
||||
{0x4767, 0x0f},
|
||||
{0x4750, 0x14},
|
||||
{0x4540, 0x00},
|
||||
{0x47b4, 0x14},
|
||||
{0x4713, 0x30},
|
||||
{0x478b, 0x10},
|
||||
{0x478f, 0x10},
|
||||
{0x4793, 0x10},
|
||||
{0x4797, 0x0e},
|
||||
{0x479b, 0x0e},
|
||||
{0x0162, 0x0d},
|
||||
{0x0163, 0x78},
|
||||
};
|
||||
|
||||
static const struct imx219_reg mode_1920_1080_regs[] = {
|
||||
{0x0100, 0x00},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x0c},
|
||||
{0x300a, 0xff},
|
||||
{0x300b, 0xff},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x09},
|
||||
{0x0114, 0x01},
|
||||
{0x0128, 0x00},
|
||||
{0x012a, 0x18},
|
||||
{0x012b, 0x00},
|
||||
{0x0162, 0x0d},
|
||||
{0x0163, 0x78},
|
||||
{0x0164, 0x02},
|
||||
{0x0165, 0xa8},
|
||||
{0x0166, 0x0a},
|
||||
@ -233,49 +246,13 @@ static const struct imx219_reg mode_1920_1080_regs[] = {
|
||||
{0x016d, 0x80},
|
||||
{0x016e, 0x04},
|
||||
{0x016f, 0x38},
|
||||
{0x0170, 0x01},
|
||||
{0x0171, 0x01},
|
||||
{0x0174, 0x00},
|
||||
{0x0175, 0x00},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x01},
|
||||
{0x0304, 0x03},
|
||||
{0x0305, 0x03},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0x39},
|
||||
{0x030b, 0x01},
|
||||
{0x030c, 0x00},
|
||||
{0x030d, 0x72},
|
||||
{0x0624, 0x07},
|
||||
{0x0625, 0x80},
|
||||
{0x0626, 0x04},
|
||||
{0x0627, 0x38},
|
||||
{0x455e, 0x00},
|
||||
{0x471e, 0x4b},
|
||||
{0x4767, 0x0f},
|
||||
{0x4750, 0x14},
|
||||
{0x4540, 0x00},
|
||||
{0x47b4, 0x14},
|
||||
{0x4713, 0x30},
|
||||
{0x478b, 0x10},
|
||||
{0x478f, 0x10},
|
||||
{0x4793, 0x10},
|
||||
{0x4797, 0x0e},
|
||||
{0x479b, 0x0e},
|
||||
};
|
||||
|
||||
static const struct imx219_reg mode_1640_1232_regs[] = {
|
||||
{0x0100, 0x00},
|
||||
{0x30eb, 0x0c},
|
||||
{0x30eb, 0x05},
|
||||
{0x300a, 0xff},
|
||||
{0x300b, 0xff},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x09},
|
||||
{0x0114, 0x01},
|
||||
{0x0128, 0x00},
|
||||
{0x012a, 0x18},
|
||||
{0x012b, 0x00},
|
||||
{0x0164, 0x00},
|
||||
{0x0165, 0x00},
|
||||
{0x0166, 0x0c},
|
||||
@ -288,53 +265,13 @@ static const struct imx219_reg mode_1640_1232_regs[] = {
|
||||
{0x016d, 0x68},
|
||||
{0x016e, 0x04},
|
||||
{0x016f, 0xd0},
|
||||
{0x0170, 0x01},
|
||||
{0x0171, 0x01},
|
||||
{0x0174, 0x01},
|
||||
{0x0175, 0x01},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x01},
|
||||
{0x0304, 0x03},
|
||||
{0x0305, 0x03},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0x39},
|
||||
{0x030b, 0x01},
|
||||
{0x030c, 0x00},
|
||||
{0x030d, 0x72},
|
||||
{0x0624, 0x06},
|
||||
{0x0625, 0x68},
|
||||
{0x0626, 0x04},
|
||||
{0x0627, 0xd0},
|
||||
{0x455e, 0x00},
|
||||
{0x471e, 0x4b},
|
||||
{0x4767, 0x0f},
|
||||
{0x4750, 0x14},
|
||||
{0x4540, 0x00},
|
||||
{0x47b4, 0x14},
|
||||
{0x4713, 0x30},
|
||||
{0x478b, 0x10},
|
||||
{0x478f, 0x10},
|
||||
{0x4793, 0x10},
|
||||
{0x4797, 0x0e},
|
||||
{0x479b, 0x0e},
|
||||
{0x0162, 0x0d},
|
||||
{0x0163, 0x78},
|
||||
};
|
||||
|
||||
static const struct imx219_reg mode_640_480_regs[] = {
|
||||
{0x0100, 0x00},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x0c},
|
||||
{0x300a, 0xff},
|
||||
{0x300b, 0xff},
|
||||
{0x30eb, 0x05},
|
||||
{0x30eb, 0x09},
|
||||
{0x0114, 0x01},
|
||||
{0x0128, 0x00},
|
||||
{0x012a, 0x18},
|
||||
{0x012b, 0x00},
|
||||
{0x0162, 0x0d},
|
||||
{0x0163, 0x78},
|
||||
{0x0164, 0x03},
|
||||
{0x0165, 0xe8},
|
||||
{0x0166, 0x08},
|
||||
@ -347,35 +284,10 @@ static const struct imx219_reg mode_640_480_regs[] = {
|
||||
{0x016d, 0x80},
|
||||
{0x016e, 0x01},
|
||||
{0x016f, 0xe0},
|
||||
{0x0170, 0x01},
|
||||
{0x0171, 0x01},
|
||||
{0x0174, 0x03},
|
||||
{0x0175, 0x03},
|
||||
{0x0301, 0x05},
|
||||
{0x0303, 0x01},
|
||||
{0x0304, 0x03},
|
||||
{0x0305, 0x03},
|
||||
{0x0306, 0x00},
|
||||
{0x0307, 0x39},
|
||||
{0x030b, 0x01},
|
||||
{0x030c, 0x00},
|
||||
{0x030d, 0x72},
|
||||
{0x0624, 0x06},
|
||||
{0x0625, 0x68},
|
||||
{0x0626, 0x04},
|
||||
{0x0627, 0xd0},
|
||||
{0x455e, 0x00},
|
||||
{0x471e, 0x4b},
|
||||
{0x4767, 0x0f},
|
||||
{0x4750, 0x14},
|
||||
{0x4540, 0x00},
|
||||
{0x47b4, 0x14},
|
||||
{0x4713, 0x30},
|
||||
{0x478b, 0x10},
|
||||
{0x478f, 0x10},
|
||||
{0x4793, 0x10},
|
||||
{0x4797, 0x0e},
|
||||
{0x479b, 0x0e},
|
||||
};
|
||||
|
||||
static const struct imx219_reg raw8_framefmt_regs[] = {
|
||||
@ -394,6 +306,10 @@ static const s64 imx219_link_freq_menu[] = {
|
||||
IMX219_DEFAULT_LINK_FREQ,
|
||||
};
|
||||
|
||||
static const s64 imx219_link_freq_4lane_menu[] = {
|
||||
IMX219_DEFAULT_LINK_FREQ_4LANE,
|
||||
};
|
||||
|
||||
static const char * const imx219_test_pattern_menu[] = {
|
||||
"Disabled",
|
||||
"Color Bars",
|
||||
@ -485,6 +401,7 @@ static const struct imx219_mode supported_modes[] = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
|
||||
.regs = mode_3280x2464_regs,
|
||||
},
|
||||
.binning = false,
|
||||
},
|
||||
{
|
||||
/* 1080P 30fps cropped */
|
||||
@ -501,6 +418,7 @@ static const struct imx219_mode supported_modes[] = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
|
||||
.regs = mode_1920_1080_regs,
|
||||
},
|
||||
.binning = false,
|
||||
},
|
||||
{
|
||||
/* 2x2 binned 30fps mode */
|
||||
@ -517,6 +435,7 @@ static const struct imx219_mode supported_modes[] = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
|
||||
.regs = mode_1640_1232_regs,
|
||||
},
|
||||
.binning = true,
|
||||
},
|
||||
{
|
||||
/* 640x480 30fps mode */
|
||||
@ -533,6 +452,7 @@ static const struct imx219_mode supported_modes[] = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_640_480_regs),
|
||||
.regs = mode_640_480_regs,
|
||||
},
|
||||
.binning = true,
|
||||
},
|
||||
};
|
||||
|
||||
@ -569,6 +489,9 @@ struct imx219 {
|
||||
|
||||
/* Streaming on/off */
|
||||
bool streaming;
|
||||
|
||||
/* Two or Four lanes */
|
||||
u8 lanes;
|
||||
};
|
||||
|
||||
static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd)
|
||||
@ -979,6 +902,35 @@ static int imx219_set_framefmt(struct imx219 *imx219)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int imx219_set_binning(struct imx219 *imx219)
|
||||
{
|
||||
if (!imx219->mode->binning) {
|
||||
return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
|
||||
IMX219_REG_VALUE_16BIT,
|
||||
IMX219_BINNING_NONE);
|
||||
}
|
||||
|
||||
switch (imx219->fmt.code) {
|
||||
case MEDIA_BUS_FMT_SRGGB8_1X8:
|
||||
case MEDIA_BUS_FMT_SGRBG8_1X8:
|
||||
case MEDIA_BUS_FMT_SGBRG8_1X8:
|
||||
case MEDIA_BUS_FMT_SBGGR8_1X8:
|
||||
return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
|
||||
IMX219_REG_VALUE_16BIT,
|
||||
IMX219_BINNING_2X2_ANALOG);
|
||||
|
||||
case MEDIA_BUS_FMT_SRGGB10_1X10:
|
||||
case MEDIA_BUS_FMT_SGRBG10_1X10:
|
||||
case MEDIA_BUS_FMT_SGBRG10_1X10:
|
||||
case MEDIA_BUS_FMT_SBGGR10_1X10:
|
||||
return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
|
||||
IMX219_REG_VALUE_16BIT,
|
||||
IMX219_BINNING_2X2);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct v4l2_rect *
|
||||
__imx219_get_pad_crop(struct imx219 *imx219,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
@ -1031,6 +983,13 @@ static int imx219_get_selection(struct v4l2_subdev *sd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int imx219_configure_lanes(struct imx219 *imx219)
|
||||
{
|
||||
return imx219_write_reg(imx219, IMX219_REG_CSI_LANE_MODE,
|
||||
IMX219_REG_VALUE_08BIT, (imx219->lanes == 2) ?
|
||||
IMX219_CSI_2_LANE_MODE : IMX219_CSI_4_LANE_MODE);
|
||||
};
|
||||
|
||||
static int imx219_start_streaming(struct imx219 *imx219)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
|
||||
@ -1041,6 +1000,20 @@ static int imx219_start_streaming(struct imx219 *imx219)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Send all registers that are common to all modes */
|
||||
ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs));
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to send mfg header\n", __func__);
|
||||
goto err_rpm_put;
|
||||
}
|
||||
|
||||
/* Configure two or four Lane mode */
|
||||
ret = imx219_configure_lanes(imx219);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to configure lanes\n", __func__);
|
||||
goto err_rpm_put;
|
||||
}
|
||||
|
||||
/* Apply default values of current mode */
|
||||
reg_list = &imx219->mode->reg_list;
|
||||
ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
|
||||
@ -1056,6 +1029,13 @@ static int imx219_start_streaming(struct imx219 *imx219)
|
||||
goto err_rpm_put;
|
||||
}
|
||||
|
||||
ret = imx219_set_binning(imx219);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s failed to set binning: %d\n",
|
||||
__func__, ret);
|
||||
goto err_rpm_put;
|
||||
}
|
||||
|
||||
/* Apply customized values from user */
|
||||
ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
|
||||
if (ret)
|
||||
@ -1272,6 +1252,11 @@ static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
|
||||
.open = imx219_open,
|
||||
};
|
||||
|
||||
static unsigned long imx219_get_pixel_rate(struct imx219 *imx219)
|
||||
{
|
||||
return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE;
|
||||
}
|
||||
|
||||
/* Initialize control handlers */
|
||||
static int imx219_init_controls(struct imx219 *imx219)
|
||||
{
|
||||
@ -1293,15 +1278,16 @@ static int imx219_init_controls(struct imx219 *imx219)
|
||||
/* By default, PIXEL_RATE is read only */
|
||||
imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE,
|
||||
IMX219_PIXEL_RATE,
|
||||
IMX219_PIXEL_RATE, 1,
|
||||
IMX219_PIXEL_RATE);
|
||||
imx219_get_pixel_rate(imx219),
|
||||
imx219_get_pixel_rate(imx219), 1,
|
||||
imx219_get_pixel_rate(imx219));
|
||||
|
||||
imx219->link_freq =
|
||||
v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops,
|
||||
V4L2_CID_LINK_FREQ,
|
||||
ARRAY_SIZE(imx219_link_freq_menu) - 1, 0,
|
||||
imx219_link_freq_menu);
|
||||
(imx219->lanes == 2) ? imx219_link_freq_menu :
|
||||
imx219_link_freq_4lane_menu);
|
||||
if (imx219->link_freq)
|
||||
imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
||||
|
||||
@ -1396,7 +1382,7 @@ static void imx219_free_controls(struct imx219 *imx219)
|
||||
mutex_destroy(&imx219->mutex);
|
||||
}
|
||||
|
||||
static int imx219_check_hwcfg(struct device *dev)
|
||||
static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)
|
||||
{
|
||||
struct fwnode_handle *endpoint;
|
||||
struct v4l2_fwnode_endpoint ep_cfg = {
|
||||
@ -1416,10 +1402,12 @@ static int imx219_check_hwcfg(struct device *dev)
|
||||
}
|
||||
|
||||
/* Check the number of MIPI CSI2 data lanes */
|
||||
if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2) {
|
||||
dev_err(dev, "only 2 data lanes are currently supported\n");
|
||||
if (ep_cfg.bus.mipi_csi2.num_data_lanes != 2 &&
|
||||
ep_cfg.bus.mipi_csi2.num_data_lanes != 4) {
|
||||
dev_err(dev, "only 2 or 4 data lanes are currently supported\n");
|
||||
goto error_out;
|
||||
}
|
||||
imx219->lanes = ep_cfg.bus.mipi_csi2.num_data_lanes;
|
||||
|
||||
/* Check the link frequency set in device tree */
|
||||
if (!ep_cfg.nr_of_link_frequencies) {
|
||||
@ -1428,7 +1416,8 @@ static int imx219_check_hwcfg(struct device *dev)
|
||||
}
|
||||
|
||||
if (ep_cfg.nr_of_link_frequencies != 1 ||
|
||||
ep_cfg.link_frequencies[0] != IMX219_DEFAULT_LINK_FREQ) {
|
||||
(ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ?
|
||||
IMX219_DEFAULT_LINK_FREQ : IMX219_DEFAULT_LINK_FREQ_4LANE))) {
|
||||
dev_err(dev, "Link frequency not supported: %lld\n",
|
||||
ep_cfg.link_frequencies[0]);
|
||||
goto error_out;
|
||||
@ -1456,7 +1445,7 @@ static int imx219_probe(struct i2c_client *client)
|
||||
v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
|
||||
|
||||
/* Check the hardware configuration in device tree */
|
||||
if (imx219_check_hwcfg(dev))
|
||||
if (imx219_check_hwcfg(dev, imx219))
|
||||
return -EINVAL;
|
||||
|
||||
/* Get system clock (xclk) */
|
||||
|
File diff suppressed because it is too large
Load Diff
1172
drivers/media/i2c/imx296.c
Normal file
1172
drivers/media/i2c/imx296.c
Normal file
File diff suppressed because it is too large
Load Diff
1300
drivers/media/i2c/imx415.c
Normal file
1300
drivers/media/i2c/imx415.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -757,8 +757,9 @@ static int zilog_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
static int ir_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
char *ir_codes = NULL;
|
||||
const char *name = NULL;
|
||||
u64 rc_proto = RC_PROTO_BIT_UNKNOWN;
|
||||
@ -987,7 +988,7 @@ static struct i2c_driver ir_kbd_driver = {
|
||||
.driver = {
|
||||
.name = "ir-kbd-i2c",
|
||||
},
|
||||
.probe = ir_probe,
|
||||
.probe_new = ir_probe,
|
||||
.remove = ir_remove,
|
||||
.id_table = ir_kbd_id,
|
||||
};
|
||||
|
@ -72,7 +72,7 @@
|
||||
#define MAX9286_DATATYPE_USER_YUV_12BIT (10 << 0)
|
||||
#define MAX9286_DATATYPE_USER_24BIT (9 << 0)
|
||||
#define MAX9286_DATATYPE_RAW14 (8 << 0)
|
||||
#define MAX9286_DATATYPE_RAW11 (7 << 0)
|
||||
#define MAX9286_DATATYPE_RAW12 (7 << 0)
|
||||
#define MAX9286_DATATYPE_RAW10 (6 << 0)
|
||||
#define MAX9286_DATATYPE_RAW8 (5 << 0)
|
||||
#define MAX9286_DATATYPE_YUV422_10BIT (4 << 0)
|
||||
@ -81,13 +81,21 @@
|
||||
#define MAX9286_DATATYPE_RGB565 (1 << 0)
|
||||
#define MAX9286_DATATYPE_RGB888 (0 << 0)
|
||||
/* Register 0x15 */
|
||||
#define MAX9286_CSI_IMAGE_TYP BIT(7)
|
||||
#define MAX9286_VC(n) ((n) << 5)
|
||||
#define MAX9286_VCTYPE BIT(4)
|
||||
#define MAX9286_CSIOUTEN BIT(3)
|
||||
#define MAX9286_0X15_RESV (3 << 0)
|
||||
#define MAX9286_SWP_ENDIAN BIT(2)
|
||||
#define MAX9286_EN_CCBSYB_CLK_STR BIT(1)
|
||||
#define MAX9286_EN_GPI_CCBSYB BIT(0)
|
||||
/* Register 0x1b */
|
||||
#define MAX9286_SWITCHIN(n) (1 << ((n) + 4))
|
||||
#define MAX9286_ENEQ(n) (1 << (n))
|
||||
/* Register 0x1c */
|
||||
#define MAX9286_HIGHIMM(n) BIT((n) + 4)
|
||||
#define MAX9286_I2CSEL BIT(2)
|
||||
#define MAX9286_HIBW BIT(1)
|
||||
#define MAX9286_BWS BIT(0)
|
||||
/* Register 0x27 */
|
||||
#define MAX9286_LOCKED BIT(7)
|
||||
/* Register 0x31 */
|
||||
@ -136,9 +144,20 @@
|
||||
#define MAX9286_N_PADS 5
|
||||
#define MAX9286_SRC_PAD 4
|
||||
|
||||
struct max9286_format_info {
|
||||
u32 code;
|
||||
u8 datatype;
|
||||
};
|
||||
|
||||
struct max9286_i2c_speed {
|
||||
u32 rate;
|
||||
u8 mstbt;
|
||||
};
|
||||
|
||||
struct max9286_source {
|
||||
struct v4l2_subdev *sd;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct regulator *regulator;
|
||||
};
|
||||
|
||||
struct max9286_asd {
|
||||
@ -168,13 +187,18 @@ struct max9286_priv {
|
||||
/* The initial reverse control channel amplitude. */
|
||||
u32 init_rev_chan_mv;
|
||||
u32 rev_chan_mv;
|
||||
u8 i2c_mstbt;
|
||||
u32 bus_width;
|
||||
|
||||
bool use_gpio_poc;
|
||||
u32 gpio_poc[2];
|
||||
|
||||
struct v4l2_ctrl_handler ctrls;
|
||||
struct v4l2_ctrl *pixelrate;
|
||||
struct v4l2_ctrl *pixelrate_ctrl;
|
||||
unsigned int pixelrate;
|
||||
|
||||
struct v4l2_mbus_framefmt fmt[MAX9286_N_SINKS];
|
||||
struct v4l2_fract interval;
|
||||
|
||||
/* Protects controls and fmt structures */
|
||||
struct mutex mutex;
|
||||
@ -214,6 +238,45 @@ static inline struct max9286_priv *sd_to_max9286(struct v4l2_subdev *sd)
|
||||
return container_of(sd, struct max9286_priv, sd);
|
||||
}
|
||||
|
||||
static const struct max9286_format_info max9286_formats[] = {
|
||||
{
|
||||
.code = MEDIA_BUS_FMT_UYVY8_1X16,
|
||||
.datatype = MAX9286_DATATYPE_YUV422_8BIT,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_VYUY8_1X16,
|
||||
.datatype = MAX9286_DATATYPE_YUV422_8BIT,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_YUYV8_1X16,
|
||||
.datatype = MAX9286_DATATYPE_YUV422_8BIT,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_YVYU8_1X16,
|
||||
.datatype = MAX9286_DATATYPE_YUV422_8BIT,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_SBGGR12_1X12,
|
||||
.datatype = MAX9286_DATATYPE_RAW12,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_SGBRG12_1X12,
|
||||
.datatype = MAX9286_DATATYPE_RAW12,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_SGRBG12_1X12,
|
||||
.datatype = MAX9286_DATATYPE_RAW12,
|
||||
}, {
|
||||
.code = MEDIA_BUS_FMT_SRGGB12_1X12,
|
||||
.datatype = MAX9286_DATATYPE_RAW12,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max9286_i2c_speed max9286_i2c_speeds[] = {
|
||||
{ .rate = 8470, .mstbt = MAX9286_I2CMSTBT_8KBPS },
|
||||
{ .rate = 28300, .mstbt = MAX9286_I2CMSTBT_28KBPS },
|
||||
{ .rate = 84700, .mstbt = MAX9286_I2CMSTBT_84KBPS },
|
||||
{ .rate = 105000, .mstbt = MAX9286_I2CMSTBT_105KBPS },
|
||||
{ .rate = 173000, .mstbt = MAX9286_I2CMSTBT_173KBPS },
|
||||
{ .rate = 339000, .mstbt = MAX9286_I2CMSTBT_339KBPS },
|
||||
{ .rate = 533000, .mstbt = MAX9286_I2CMSTBT_533KBPS },
|
||||
{ .rate = 837000, .mstbt = MAX9286_I2CMSTBT_837KBPS },
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* I2C IO
|
||||
*/
|
||||
@ -334,7 +397,7 @@ error:
|
||||
static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
|
||||
{
|
||||
u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |
|
||||
MAX9286_I2CMSTBT_105KBPS;
|
||||
priv->i2c_mstbt;
|
||||
|
||||
if (localack)
|
||||
config |= MAX9286_I2CLOCACK;
|
||||
@ -475,6 +538,77 @@ static int max9286_check_config_link(struct max9286_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max9286_set_video_format(struct max9286_priv *priv,
|
||||
const struct v4l2_mbus_framefmt *format)
|
||||
{
|
||||
const struct max9286_format_info *info = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
|
||||
if (max9286_formats[i].code == format->code) {
|
||||
info = &max9286_formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WARN_ON(!info))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Video format setup: disable CSI output, set VC according to Link
|
||||
* number, enable I2C clock stretching when CCBSY is low, enable CCBSY
|
||||
* in external GPI-to-GPO mode.
|
||||
*/
|
||||
max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_EN_CCBSYB_CLK_STR |
|
||||
MAX9286_EN_GPI_CCBSYB);
|
||||
|
||||
/* Enable CSI-2 Lane D0-D3 only, DBL mode. */
|
||||
max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
|
||||
MAX9286_CSILANECNT(priv->csi2_data_lanes) |
|
||||
info->datatype);
|
||||
|
||||
/*
|
||||
* Enable HS/VS encoding, use HS as line valid source, use D14/15 for
|
||||
* HS/VS, invert VS.
|
||||
*/
|
||||
max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_DESEL |
|
||||
MAX9286_INVVS | MAX9286_HVSRC_D14);
|
||||
}
|
||||
|
||||
static void max9286_set_fsync_period(struct max9286_priv *priv)
|
||||
{
|
||||
u32 fsync;
|
||||
|
||||
if (!priv->interval.numerator || !priv->interval.denominator) {
|
||||
/*
|
||||
* Special case, a null interval enables automatic FRAMESYNC
|
||||
* mode. FRAMESYNC is taken from the slowest link.
|
||||
*/
|
||||
max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
|
||||
MAX9286_FSYNCMETH_AUTO);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manual FRAMESYNC
|
||||
*
|
||||
* The FRAMESYNC generator is configured with a period expressed as a
|
||||
* number of PCLK periods.
|
||||
*/
|
||||
fsync = div_u64((u64)priv->pixelrate * priv->interval.numerator,
|
||||
priv->interval.denominator);
|
||||
|
||||
dev_dbg(&priv->client->dev, "fsync period %u (pclk %u)\n", fsync,
|
||||
priv->pixelrate);
|
||||
|
||||
max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_OUT |
|
||||
MAX9286_FSYNCMETH_MANUAL);
|
||||
|
||||
max9286_write(priv, 0x06, (fsync >> 0) & 0xff);
|
||||
max9286_write(priv, 0x07, (fsync >> 8) & 0xff);
|
||||
max9286_write(priv, 0x08, (fsync >> 16) & 0xff);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* V4L2 Subdev
|
||||
*/
|
||||
@ -513,11 +647,13 @@ static int max9286_set_pixelrate(struct max9286_priv *priv)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->pixelrate = pixelrate;
|
||||
|
||||
/*
|
||||
* The CSI-2 transmitter pixel rate is the single source rate multiplied
|
||||
* by the number of available sources.
|
||||
*/
|
||||
return v4l2_ctrl_s_ctrl_int64(priv->pixelrate,
|
||||
return v4l2_ctrl_s_ctrl_int64(priv->pixelrate_ctrl,
|
||||
pixelrate * priv->nsources);
|
||||
}
|
||||
|
||||
@ -657,6 +793,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
const struct v4l2_mbus_framefmt *format;
|
||||
|
||||
/*
|
||||
* Get the format from the first used sink pad, as all sink
|
||||
* formats must be identical.
|
||||
*/
|
||||
format = &priv->fmt[__ffs(priv->bound_sources)];
|
||||
|
||||
max9286_set_video_format(priv, format);
|
||||
max9286_set_fsync_period(priv);
|
||||
|
||||
/*
|
||||
* The frame sync between cameras is transmitted across the
|
||||
* reverse channel as GPIO. We must open all channels while
|
||||
@ -698,13 +845,17 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable CSI output, VC set according to link number.
|
||||
* Bit 7 must be set (chip manual says it's 0 and reserved).
|
||||
* Configure the CSI-2 output to line interleaved mode (W x (N
|
||||
* x H), as opposed to the (N x W) x H mode that outputs the
|
||||
* images stitched side-by-side) and enable it.
|
||||
*/
|
||||
max9286_write(priv, 0x15, 0x80 | MAX9286_VCTYPE |
|
||||
MAX9286_CSIOUTEN | MAX9286_0X15_RESV);
|
||||
max9286_write(priv, 0x15, MAX9286_CSI_IMAGE_TYP | MAX9286_VCTYPE |
|
||||
MAX9286_CSIOUTEN | MAX9286_EN_CCBSYB_CLK_STR |
|
||||
MAX9286_EN_GPI_CCBSYB);
|
||||
} else {
|
||||
max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
|
||||
max9286_write(priv, 0x15, MAX9286_VCTYPE |
|
||||
MAX9286_EN_CCBSYB_CLK_STR |
|
||||
MAX9286_EN_GPI_CCBSYB);
|
||||
|
||||
/* Stop all cameras. */
|
||||
for_each_source(priv, source)
|
||||
@ -716,6 +867,32 @@ static int max9286_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_g_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *interval)
|
||||
{
|
||||
struct max9286_priv *priv = sd_to_max9286(sd);
|
||||
|
||||
if (interval->pad != MAX9286_SRC_PAD)
|
||||
return -EINVAL;
|
||||
|
||||
interval->interval = priv->interval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_s_frame_interval(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_frame_interval *interval)
|
||||
{
|
||||
struct max9286_priv *priv = sd_to_max9286(sd);
|
||||
|
||||
if (interval->pad != MAX9286_SRC_PAD)
|
||||
return -EINVAL;
|
||||
|
||||
priv->interval = interval->interval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
@ -749,22 +926,20 @@ static int max9286_set_fmt(struct v4l2_subdev *sd,
|
||||
{
|
||||
struct max9286_priv *priv = sd_to_max9286(sd);
|
||||
struct v4l2_mbus_framefmt *cfg_fmt;
|
||||
unsigned int i;
|
||||
|
||||
if (format->pad == MAX9286_SRC_PAD)
|
||||
return -EINVAL;
|
||||
|
||||
/* Refuse non YUV422 formats as we hardcode DT to 8 bit YUV422 */
|
||||
switch (format->format.code) {
|
||||
case MEDIA_BUS_FMT_UYVY8_1X16:
|
||||
case MEDIA_BUS_FMT_VYUY8_1X16:
|
||||
case MEDIA_BUS_FMT_YUYV8_1X16:
|
||||
case MEDIA_BUS_FMT_YVYU8_1X16:
|
||||
break;
|
||||
default:
|
||||
format->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
|
||||
break;
|
||||
/* Validate the format. */
|
||||
for (i = 0; i < ARRAY_SIZE(max9286_formats); ++i) {
|
||||
if (max9286_formats[i].code == format->format.code)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(max9286_formats))
|
||||
format->format.code = max9286_formats[0].code;
|
||||
|
||||
cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad,
|
||||
format->which);
|
||||
if (!cfg_fmt)
|
||||
@ -807,6 +982,8 @@ static int max9286_get_fmt(struct v4l2_subdev *sd,
|
||||
|
||||
static const struct v4l2_subdev_video_ops max9286_video_ops = {
|
||||
.s_stream = max9286_s_stream,
|
||||
.g_frame_interval = max9286_g_frame_interval,
|
||||
.s_frame_interval = max9286_s_frame_interval,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops max9286_pad_ops = {
|
||||
@ -820,16 +997,20 @@ static const struct v4l2_subdev_ops max9286_subdev_ops = {
|
||||
.pad = &max9286_pad_ops,
|
||||
};
|
||||
|
||||
static const struct v4l2_mbus_framefmt max9286_default_format = {
|
||||
.width = 1280,
|
||||
.height = 800,
|
||||
.code = MEDIA_BUS_FMT_UYVY8_1X16,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.field = V4L2_FIELD_NONE,
|
||||
.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
|
||||
.quantization = V4L2_QUANTIZATION_DEFAULT,
|
||||
.xfer_func = V4L2_XFER_FUNC_DEFAULT,
|
||||
};
|
||||
|
||||
static void max9286_init_format(struct v4l2_mbus_framefmt *fmt)
|
||||
{
|
||||
fmt->width = 1280;
|
||||
fmt->height = 800;
|
||||
fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
|
||||
fmt->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
fmt->field = V4L2_FIELD_NONE;
|
||||
fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
|
||||
fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
|
||||
fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
|
||||
*fmt = max9286_default_format;
|
||||
}
|
||||
|
||||
static int max9286_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
|
||||
@ -891,10 +1072,10 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
|
||||
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
||||
v4l2_ctrl_handler_init(&priv->ctrls, 1);
|
||||
priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls,
|
||||
&max9286_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE,
|
||||
1, INT_MAX, 1, 50000000);
|
||||
priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls,
|
||||
&max9286_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE,
|
||||
1, INT_MAX, 1, 50000000);
|
||||
|
||||
priv->sd.ctrl_handler = &priv->ctrls;
|
||||
ret = priv->ctrls.error;
|
||||
@ -932,6 +1113,7 @@ static int max9286_v4l2_register(struct max9286_priv *priv)
|
||||
err_put_node:
|
||||
fwnode_handle_put(ep);
|
||||
err_async:
|
||||
v4l2_ctrl_handler_free(&priv->ctrls);
|
||||
max9286_v4l2_notifier_unregister(priv);
|
||||
|
||||
return ret;
|
||||
@ -975,6 +1157,7 @@ static int max9286_setup(struct max9286_priv *priv)
|
||||
(2 << 6) | (1 << 4) | (0 << 2) | (3 << 0), /* 210x */
|
||||
(3 << 6) | (2 << 4) | (1 << 2) | (0 << 0), /* 3210 */
|
||||
};
|
||||
int cfg;
|
||||
|
||||
/*
|
||||
* Set the I2C bus speed.
|
||||
@ -993,24 +1176,27 @@ static int max9286_setup(struct max9286_priv *priv)
|
||||
max9286_write(priv, 0x0b, link_order[priv->route_mask]);
|
||||
max9286_write(priv, 0x69, (0xf & ~priv->route_mask));
|
||||
|
||||
/*
|
||||
* Video format setup:
|
||||
* Disable CSI output, VC is set according to Link number.
|
||||
*/
|
||||
max9286_write(priv, 0x15, MAX9286_VCTYPE | MAX9286_0X15_RESV);
|
||||
max9286_set_video_format(priv, &max9286_default_format);
|
||||
max9286_set_fsync_period(priv);
|
||||
|
||||
/* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */
|
||||
max9286_write(priv, 0x12, MAX9286_CSIDBL | MAX9286_DBL |
|
||||
MAX9286_CSILANECNT(priv->csi2_data_lanes) |
|
||||
MAX9286_DATATYPE_YUV422_8BIT);
|
||||
cfg = max9286_read(priv, 0x1c);
|
||||
if (cfg < 0)
|
||||
return cfg;
|
||||
|
||||
/* Automatic: FRAMESYNC taken from the slowest Link. */
|
||||
max9286_write(priv, 0x01, MAX9286_FSYNCMODE_INT_HIZ |
|
||||
MAX9286_FSYNCMETH_AUTO);
|
||||
dev_dbg(&priv->client->dev, "power-up config: %s immunity, %u-bit bus\n",
|
||||
cfg & MAX9286_HIGHIMM(0) ? "high" : "legacy",
|
||||
cfg & MAX9286_BWS ? 32 : cfg & MAX9286_HIBW ? 27 : 24);
|
||||
|
||||
/* Enable HS/VS encoding, use D14/15 for HS/VS, invert VS. */
|
||||
max9286_write(priv, 0x0c, MAX9286_HVEN | MAX9286_INVVS |
|
||||
MAX9286_HVSRC_D14);
|
||||
if (priv->bus_width) {
|
||||
cfg &= ~(MAX9286_HIBW | MAX9286_BWS);
|
||||
|
||||
if (priv->bus_width == 27)
|
||||
cfg |= MAX9286_HIBW;
|
||||
else if (priv->bus_width == 32)
|
||||
cfg |= MAX9286_BWS;
|
||||
|
||||
max9286_write(priv, 0x1c, cfg);
|
||||
}
|
||||
|
||||
/*
|
||||
* The overlap window seems to provide additional validation by tracking
|
||||
@ -1088,9 +1274,6 @@ static int max9286_parse_gpios(struct max9286_priv *priv)
|
||||
struct device *dev = &priv->client->dev;
|
||||
int ret;
|
||||
|
||||
/* GPIO values default to high */
|
||||
priv->gpio_state = BIT(0) | BIT(1);
|
||||
|
||||
/*
|
||||
* Parse the "gpio-poc" vendor property. If the property is not
|
||||
* specified the camera power is controlled by a regulator.
|
||||
@ -1102,18 +1285,7 @@ static int max9286_parse_gpios(struct max9286_priv *priv)
|
||||
* If gpio lines are not used for the camera power, register
|
||||
* a gpio controller for consumers.
|
||||
*/
|
||||
ret = max9286_register_gpio(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->regulator = devm_regulator_get(dev, "poc");
|
||||
if (IS_ERR(priv->regulator)) {
|
||||
return dev_err_probe(dev, PTR_ERR(priv->regulator),
|
||||
"Unable to get PoC regulator (%ld)\n",
|
||||
PTR_ERR(priv->regulator));
|
||||
}
|
||||
|
||||
return 0;
|
||||
return max9286_register_gpio(priv);
|
||||
}
|
||||
|
||||
/* If the property is specified make sure it is well formed. */
|
||||
@ -1124,21 +1296,75 @@ static int max9286_parse_gpios(struct max9286_priv *priv)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->use_gpio_poc = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_poc_power_on(struct max9286_priv *priv)
|
||||
{
|
||||
struct max9286_source *source;
|
||||
unsigned int enabled = 0;
|
||||
int ret;
|
||||
|
||||
/* Enable the global regulator if available. */
|
||||
if (priv->regulator)
|
||||
return regulator_enable(priv->regulator);
|
||||
|
||||
if (priv->use_gpio_poc)
|
||||
return max9286_gpio_set(priv, priv->gpio_poc[0],
|
||||
!priv->gpio_poc[1]);
|
||||
|
||||
/* Otherwise use the per-port regulators. */
|
||||
for_each_source(priv, source) {
|
||||
ret = regulator_enable(source->regulator);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
enabled |= BIT(to_index(priv, source));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for_each_source(priv, source) {
|
||||
if (enabled & BIT(to_index(priv, source)))
|
||||
regulator_disable(source->regulator);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max9286_poc_power_off(struct max9286_priv *priv)
|
||||
{
|
||||
struct max9286_source *source;
|
||||
int ret = 0;
|
||||
|
||||
if (priv->regulator)
|
||||
return regulator_disable(priv->regulator);
|
||||
|
||||
if (priv->use_gpio_poc)
|
||||
return max9286_gpio_set(priv, priv->gpio_poc[0],
|
||||
priv->gpio_poc[1]);
|
||||
|
||||
for_each_source(priv, source) {
|
||||
int err;
|
||||
|
||||
err = regulator_disable(source->regulator);
|
||||
if (!ret)
|
||||
ret = err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max9286_poc_enable(struct max9286_priv *priv, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* If the regulator is not available, use gpio to control power. */
|
||||
if (!priv->regulator)
|
||||
ret = max9286_gpio_set(priv, priv->gpio_poc[0],
|
||||
enable ^ priv->gpio_poc[1]);
|
||||
else if (enable)
|
||||
ret = regulator_enable(priv->regulator);
|
||||
if (enable)
|
||||
ret = max9286_poc_power_on(priv);
|
||||
else
|
||||
ret = regulator_disable(priv->regulator);
|
||||
ret = max9286_poc_power_off(priv);
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(&priv->client->dev, "Unable to turn power %s\n",
|
||||
@ -1208,6 +1434,8 @@ static int max9286_parse_dt(struct max9286_priv *priv)
|
||||
struct device_node *node = NULL;
|
||||
unsigned int i2c_mux_mask = 0;
|
||||
u32 reverse_channel_microvolt;
|
||||
u32 i2c_clk_freq = 105000;
|
||||
unsigned int i;
|
||||
|
||||
/* Balance the of_node_put() performed by of_find_node_by_name(). */
|
||||
of_node_get(dev->of_node);
|
||||
@ -1298,6 +1526,40 @@ static int max9286_parse_dt(struct max9286_priv *priv)
|
||||
}
|
||||
of_node_put(node);
|
||||
|
||||
of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width);
|
||||
switch (priv->bus_width) {
|
||||
case 0:
|
||||
/*
|
||||
* The property isn't specified in the device tree, the driver
|
||||
* will keep the default value selected by the BWS pin.
|
||||
*/
|
||||
case 24:
|
||||
case 27:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "Invalid %s value %u\n", "maxim,bus-width",
|
||||
priv->bus_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_property_read_u32(dev->of_node, "maxim,i2c-remote-bus-hz",
|
||||
&i2c_clk_freq);
|
||||
for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
|
||||
const struct max9286_i2c_speed *speed = &max9286_i2c_speeds[i];
|
||||
|
||||
if (speed->rate == i2c_clk_freq) {
|
||||
priv->i2c_mstbt = speed->mstbt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(max9286_i2c_speeds)) {
|
||||
dev_err(dev, "Invalid %s value %u\n", "maxim,i2c-remote-bus-hz",
|
||||
i2c_clk_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the initial value of the reverse channel amplitude from
|
||||
* the firmware interface and convert it to millivolts.
|
||||
@ -1317,6 +1579,44 @@ static int max9286_parse_dt(struct max9286_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_get_poc_supplies(struct max9286_priv *priv)
|
||||
{
|
||||
struct device *dev = &priv->client->dev;
|
||||
struct max9286_source *source;
|
||||
int ret;
|
||||
|
||||
/* Start by getting the global regulator. */
|
||||
priv->regulator = devm_regulator_get_optional(dev, "poc");
|
||||
if (!IS_ERR(priv->regulator))
|
||||
return 0;
|
||||
|
||||
if (PTR_ERR(priv->regulator) != -ENODEV)
|
||||
return dev_err_probe(dev, PTR_ERR(priv->regulator),
|
||||
"Unable to get PoC regulator\n");
|
||||
|
||||
/* If there's no global regulator, get per-port regulators. */
|
||||
dev_dbg(dev,
|
||||
"No global PoC regulator, looking for per-port regulators\n");
|
||||
priv->regulator = NULL;
|
||||
|
||||
for_each_source(priv, source) {
|
||||
unsigned int index = to_index(priv, source);
|
||||
char name[10];
|
||||
|
||||
snprintf(name, sizeof(name), "port%u-poc", index);
|
||||
source->regulator = devm_regulator_get(dev, name);
|
||||
if (IS_ERR(source->regulator)) {
|
||||
ret = PTR_ERR(source->regulator);
|
||||
dev_err_probe(dev, ret,
|
||||
"Unable to get port %u PoC regulator\n",
|
||||
index);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max9286_probe(struct i2c_client *client)
|
||||
{
|
||||
struct max9286_priv *priv;
|
||||
@ -1330,10 +1630,19 @@ static int max9286_probe(struct i2c_client *client)
|
||||
|
||||
priv->client = client;
|
||||
|
||||
/* GPIO values default to high */
|
||||
priv->gpio_state = BIT(0) | BIT(1);
|
||||
|
||||
ret = max9286_parse_dt(priv);
|
||||
if (ret)
|
||||
goto err_cleanup_dt;
|
||||
|
||||
priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(priv->gpiod_pwdn))
|
||||
return PTR_ERR(priv->gpiod_pwdn);
|
||||
if (IS_ERR(priv->gpiod_pwdn)) {
|
||||
ret = PTR_ERR(priv->gpiod_pwdn);
|
||||
goto err_cleanup_dt;
|
||||
}
|
||||
|
||||
gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
|
||||
gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
|
||||
@ -1360,9 +1669,11 @@ static int max9286_probe(struct i2c_client *client)
|
||||
if (ret)
|
||||
goto err_powerdown;
|
||||
|
||||
ret = max9286_parse_dt(priv);
|
||||
if (ret)
|
||||
goto err_powerdown;
|
||||
if (!priv->use_gpio_poc) {
|
||||
ret = max9286_get_poc_supplies(priv);
|
||||
if (ret)
|
||||
goto err_cleanup_dt;
|
||||
}
|
||||
|
||||
ret = max9286_init(priv);
|
||||
if (ret < 0)
|
||||
@ -1370,10 +1681,10 @@ static int max9286_probe(struct i2c_client *client)
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_dt:
|
||||
max9286_cleanup_dt(priv);
|
||||
err_powerdown:
|
||||
gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
|
||||
err_cleanup_dt:
|
||||
max9286_cleanup_dt(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -663,8 +663,9 @@ static const char * const opmode_str[] = {
|
||||
[OPMODE_AUTOSELECT] = "autodetect and autoselect",
|
||||
};
|
||||
|
||||
static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
static int msp_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct msp_state *state;
|
||||
struct v4l2_subdev *sd;
|
||||
struct v4l2_ctrl_handler *hdl;
|
||||
@ -891,7 +892,7 @@ static struct i2c_driver msp_driver = {
|
||||
.name = "msp3400",
|
||||
.pm = &msp3400_pm_ops,
|
||||
},
|
||||
.probe = msp_probe,
|
||||
.probe_new = msp_probe,
|
||||
.remove = msp_remove,
|
||||
.id_table = msp_id,
|
||||
};
|
||||
|
@ -1102,9 +1102,9 @@ done:
|
||||
return pdata;
|
||||
}
|
||||
|
||||
static int mt9p031_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
static int mt9p031_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *did = i2c_client_get_device_id(client);
|
||||
struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct mt9p031 *mt9p031;
|
||||
@ -1248,7 +1248,7 @@ static struct i2c_driver mt9p031_i2c_driver = {
|
||||
.of_match_table = of_match_ptr(mt9p031_of_match),
|
||||
.name = "mt9p031",
|
||||
},
|
||||
.probe = mt9p031_probe,
|
||||
.probe_new = mt9p031_probe,
|
||||
.remove = mt9p031_remove,
|
||||
.id_table = mt9p031_id,
|
||||
};
|
||||
|
@ -1044,9 +1044,9 @@ done:
|
||||
return pdata;
|
||||
}
|
||||
|
||||
static int mt9v032_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
static int mt9v032_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *did = i2c_client_get_device_id(client);
|
||||
struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client);
|
||||
struct mt9v032 *mt9v032;
|
||||
unsigned int i;
|
||||
@ -1296,7 +1296,7 @@ static struct i2c_driver mt9v032_driver = {
|
||||
.name = "mt9v032",
|
||||
.of_match_table = of_match_ptr(mt9v032_of_match),
|
||||
},
|
||||
.probe = mt9v032_probe,
|
||||
.probe_new = mt9v032_probe,
|
||||
.remove = mt9v032_remove,
|
||||
.id_table = mt9v032_id,
|
||||
};
|
||||
|
@ -629,8 +629,10 @@ static int ov2740_init_controls(struct ov2740 *ov2740)
|
||||
V4L2_CID_TEST_PATTERN,
|
||||
ARRAY_SIZE(ov2740_test_pattern_menu) - 1,
|
||||
0, 0, ov2740_test_pattern_menu);
|
||||
if (ctrl_hdlr->error)
|
||||
if (ctrl_hdlr->error) {
|
||||
v4l2_ctrl_handler_free(ctrl_hdlr);
|
||||
return ctrl_hdlr->error;
|
||||
}
|
||||
|
||||
ov2740->sd.ctrl_handler = ctrl_hdlr;
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
#define OV5640_REG_SYS_CTRL0 0x3008
|
||||
#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42
|
||||
#define OV5640_REG_SYS_CTRL0_SW_PWUP 0x02
|
||||
#define OV5640_REG_SYS_CTRL0_SW_RST 0x82
|
||||
#define OV5640_REG_CHIP_ID 0x300a
|
||||
#define OV5640_REG_IO_MIPI_CTRL00 0x300e
|
||||
#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
|
||||
@ -520,7 +521,18 @@ static u32 ov5640_code_to_bpp(struct ov5640_dev *sensor, u32 code)
|
||||
*/
|
||||
/* YUV422 UYVY VGA@30fps */
|
||||
|
||||
static const struct v4l2_mbus_framefmt ov5640_default_fmt = {
|
||||
static const struct v4l2_mbus_framefmt ov5640_csi2_default_fmt = {
|
||||
.code = MEDIA_BUS_FMT_UYVY8_1X16,
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.colorspace = V4L2_COLORSPACE_SRGB,
|
||||
.ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB),
|
||||
.quantization = V4L2_QUANTIZATION_FULL_RANGE,
|
||||
.xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB),
|
||||
.field = V4L2_FIELD_NONE,
|
||||
};
|
||||
|
||||
static const struct v4l2_mbus_framefmt ov5640_dvp_default_fmt = {
|
||||
.code = MEDIA_BUS_FMT_UYVY8_2X8,
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
@ -532,7 +544,7 @@ static const struct v4l2_mbus_framefmt ov5640_default_fmt = {
|
||||
};
|
||||
|
||||
static const struct reg_value ov5640_init_setting[] = {
|
||||
{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
|
||||
{0x3103, 0x11, 0, 0},
|
||||
{0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0},
|
||||
{0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
|
||||
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
|
||||
@ -2424,24 +2436,48 @@ static void ov5640_power(struct ov5640_dev *sensor, bool enable)
|
||||
gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
|
||||
}
|
||||
|
||||
static void ov5640_reset(struct ov5640_dev *sensor)
|
||||
/*
|
||||
* From section 2.7 power up sequence:
|
||||
* t0 + t1 + t2 >= 5ms Delay from DOVDD stable to PWDN pull down
|
||||
* t3 >= 1ms Delay from PWDN pull down to RESETB pull up
|
||||
* t4 >= 20ms Delay from RESETB pull up to SCCB (i2c) stable
|
||||
*
|
||||
* Some modules don't expose RESETB/PWDN pins directly, instead providing a
|
||||
* "PWUP" GPIO which is wired through appropriate delays and inverters to the
|
||||
* pins.
|
||||
*
|
||||
* In such cases, this gpio should be mapped to pwdn_gpio in the driver, and we
|
||||
* should still toggle the pwdn_gpio below with the appropriate delays, while
|
||||
* the calls to reset_gpio will be ignored.
|
||||
*/
|
||||
static void ov5640_powerup_sequence(struct ov5640_dev *sensor)
|
||||
{
|
||||
if (!sensor->reset_gpio)
|
||||
return;
|
||||
if (sensor->pwdn_gpio) {
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 0);
|
||||
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 0);
|
||||
/* camera power cycle */
|
||||
ov5640_power(sensor, false);
|
||||
usleep_range(5000, 10000);
|
||||
ov5640_power(sensor, true);
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
/* camera power cycle */
|
||||
ov5640_power(sensor, false);
|
||||
usleep_range(5000, 10000);
|
||||
ov5640_power(sensor, true);
|
||||
usleep_range(5000, 10000);
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 1);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 1);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 0);
|
||||
gpiod_set_value_cansleep(sensor->reset_gpio, 0);
|
||||
} else {
|
||||
/* software reset */
|
||||
ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0,
|
||||
OV5640_REG_SYS_CTRL0_SW_RST);
|
||||
}
|
||||
usleep_range(20000, 25000);
|
||||
|
||||
/*
|
||||
* software standby: allows registers programming;
|
||||
* exit at restore_mode() for CSI, s_stream(1) for DVP
|
||||
*/
|
||||
ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0,
|
||||
OV5640_REG_SYS_CTRL0_SW_PWDN);
|
||||
}
|
||||
|
||||
static int ov5640_set_power_on(struct ov5640_dev *sensor)
|
||||
@ -2464,8 +2500,7 @@ static int ov5640_set_power_on(struct ov5640_dev *sensor)
|
||||
goto xclk_off;
|
||||
}
|
||||
|
||||
ov5640_reset(sensor);
|
||||
ov5640_power(sensor, true);
|
||||
ov5640_powerup_sequence(sensor);
|
||||
|
||||
ret = ov5640_init_slave_id(sensor);
|
||||
if (ret)
|
||||
@ -3316,6 +3351,7 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(&sensor->i2c_client->dev);
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
|
||||
return 0;
|
||||
@ -3391,6 +3427,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(&sensor->i2c_client->dev);
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
|
||||
return ret;
|
||||
@ -3458,7 +3495,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor)
|
||||
/* Auto/manual gain */
|
||||
ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
|
||||
0, 1, 1, 1);
|
||||
ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
|
||||
ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
|
||||
0, 1023, 1, 0);
|
||||
|
||||
ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
|
||||
@ -3710,8 +3747,10 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
out:
|
||||
mutex_unlock(&sensor->lock);
|
||||
|
||||
if (!enable || ret)
|
||||
if (!enable || ret) {
|
||||
pm_runtime_mark_last_busy(&sensor->i2c_client->dev);
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -3719,11 +3758,13 @@ out:
|
||||
static int ov5640_init_cfg(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state)
|
||||
{
|
||||
struct ov5640_dev *sensor = to_ov5640_dev(sd);
|
||||
struct v4l2_mbus_framefmt *fmt =
|
||||
v4l2_subdev_get_try_format(sd, state, 0);
|
||||
struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, state, 0);
|
||||
|
||||
*fmt = ov5640_default_fmt;
|
||||
*fmt = ov5640_is_csi2(sensor) ? ov5640_csi2_default_fmt :
|
||||
ov5640_dvp_default_fmt;
|
||||
|
||||
crop->left = OV5640_PIXEL_ARRAY_LEFT;
|
||||
crop->top = OV5640_PIXEL_ARRAY_TOP;
|
||||
@ -3812,7 +3853,6 @@ static int ov5640_probe(struct i2c_client *client)
|
||||
* default init sequence initialize sensor to
|
||||
* YUV422 UYVY VGA@30fps
|
||||
*/
|
||||
sensor->fmt = ov5640_default_fmt;
|
||||
sensor->frame_interval.numerator = 1;
|
||||
sensor->frame_interval.denominator = ov5640_framerates[OV5640_30_FPS];
|
||||
sensor->current_fr = OV5640_30_FPS;
|
||||
@ -3845,6 +3885,9 @@ static int ov5640_probe(struct i2c_client *client)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sensor->fmt = ov5640_is_csi2(sensor) ? ov5640_csi2_default_fmt :
|
||||
ov5640_dvp_default_fmt;
|
||||
|
||||
/* get system clock (xclk) */
|
||||
sensor->xclk = devm_clk_get(dev, "xclk");
|
||||
if (IS_ERR(sensor->xclk)) {
|
||||
@ -3912,6 +3955,7 @@ static int ov5640_probe(struct i2c_client *client)
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, 1000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -1,15 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2017 Intel Corporation.
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
#define OV5670_XVCLK_FREQ 19200000
|
||||
|
||||
#define OV5670_REG_CHIP_ID 0x300a
|
||||
#define OV5670_CHIP_ID 0x005670
|
||||
|
||||
@ -65,6 +74,10 @@
|
||||
#define OV5670_REG_VALUE_16BIT 2
|
||||
#define OV5670_REG_VALUE_24BIT 3
|
||||
|
||||
/* Pixel Array */
|
||||
#define OV5670_NATIVE_WIDTH 2624
|
||||
#define OV5670_NATIVE_HEIGHT 1980
|
||||
|
||||
/* Initial number of frames to skip to avoid possible garbage */
|
||||
#define OV5670_NUM_OF_SKIP_FRAMES 2
|
||||
|
||||
@ -83,6 +96,14 @@ struct ov5670_link_freq_config {
|
||||
const struct ov5670_reg_list reg_list;
|
||||
};
|
||||
|
||||
static const char * const ov5670_supply_names[] = {
|
||||
"avdd", /* Analog power */
|
||||
"dvdd", /* Digital power */
|
||||
"dovdd", /* Digital output power */
|
||||
};
|
||||
|
||||
#define OV5670_NUM_SUPPLIES ARRAY_SIZE(ov5670_supply_names)
|
||||
|
||||
struct ov5670_mode {
|
||||
/* Frame width in pixels */
|
||||
u32 width;
|
||||
@ -99,10 +120,25 @@ struct ov5670_mode {
|
||||
/* Link frequency needed for this resolution */
|
||||
u32 link_freq_index;
|
||||
|
||||
/* Analog crop rectangle */
|
||||
const struct v4l2_rect *analog_crop;
|
||||
|
||||
/* Sensor register settings for this resolution */
|
||||
const struct ov5670_reg_list reg_list;
|
||||
};
|
||||
|
||||
/*
|
||||
* All the modes supported by the driver are obtained by subsampling the
|
||||
* full pixel array. The below values are reflected in registers from
|
||||
* 0x3800-0x3807 in the modes register-value tables.
|
||||
*/
|
||||
static const struct v4l2_rect ov5670_analog_crop = {
|
||||
.left = 12,
|
||||
.top = 4,
|
||||
.width = 2600,
|
||||
.height = 1952,
|
||||
};
|
||||
|
||||
static const struct ov5670_reg mipi_data_rate_840mbps[] = {
|
||||
{0x0300, 0x04},
|
||||
{0x0301, 0x00},
|
||||
@ -1750,66 +1786,73 @@ static const struct ov5670_mode supported_modes[] = {
|
||||
.height = 1944,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = OV5670_VTS_30FPS,
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),
|
||||
.regs = mode_2592x1944_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 1296,
|
||||
.height = 972,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = 996,
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_1296x972_regs),
|
||||
.regs = mode_1296x972_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 648,
|
||||
.height = 486,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = 516,
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_648x486_regs),
|
||||
.regs = mode_648x486_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 2560,
|
||||
.height = 1440,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = OV5670_VTS_30FPS,
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_2560x1440_regs),
|
||||
.regs = mode_2560x1440_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = 1020,
|
||||
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
|
||||
.regs = mode_1280x720_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 640,
|
||||
.height = 360,
|
||||
.vts_def = OV5670_VTS_30FPS,
|
||||
.vts_min = 510,
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
.analog_crop = &ov5670_analog_crop,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_640x360_regs),
|
||||
.regs = mode_640x360_regs,
|
||||
},
|
||||
.link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX,
|
||||
}
|
||||
};
|
||||
|
||||
@ -1828,6 +1871,16 @@ struct ov5670 {
|
||||
/* Current mode */
|
||||
const struct ov5670_mode *cur_mode;
|
||||
|
||||
/* xvclk input clock */
|
||||
struct clk *xvclk;
|
||||
|
||||
/* Regulators */
|
||||
struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES];
|
||||
|
||||
/* Power-down and reset gpios. */
|
||||
struct gpio_desc *pwdn_gpio; /* PWDNB pin. */
|
||||
struct gpio_desc *reset_gpio; /* XSHUTDOWN pin. */
|
||||
|
||||
/* To serialize asynchronus callbacks */
|
||||
struct mutex mutex;
|
||||
|
||||
@ -1935,27 +1988,6 @@ static int ov5670_write_reg_list(struct ov5670 *ov5670,
|
||||
return ov5670_write_regs(ov5670, r_list->regs, r_list->num_of_regs);
|
||||
}
|
||||
|
||||
/* Open sub-device */
|
||||
static int ov5670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct ov5670 *ov5670 = to_ov5670(sd);
|
||||
struct v4l2_mbus_framefmt *try_fmt =
|
||||
v4l2_subdev_get_try_format(sd, fh->state, 0);
|
||||
|
||||
mutex_lock(&ov5670->mutex);
|
||||
|
||||
/* Initialize try_fmt */
|
||||
try_fmt->width = ov5670->cur_mode->width;
|
||||
try_fmt->height = ov5670->cur_mode->height;
|
||||
try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
try_fmt->field = V4L2_FIELD_NONE;
|
||||
|
||||
/* No crop or compose */
|
||||
mutex_unlock(&ov5670->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5670_update_digital_gain(struct ov5670 *ov5670, u32 d_gain)
|
||||
{
|
||||
int ret;
|
||||
@ -2006,7 +2038,7 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
struct ov5670, ctrl_handler);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
|
||||
s64 max;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
/* Propagate change of current control to all related controls */
|
||||
switch (ctrl->id) {
|
||||
@ -2045,7 +2077,13 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
case V4L2_CID_TEST_PATTERN:
|
||||
ret = ov5670_enable_test_pattern(ov5670, ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_HBLANK:
|
||||
case V4L2_CID_LINK_FREQ:
|
||||
case V4L2_CID_PIXEL_RATE:
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
dev_info(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
|
||||
__func__, ctrl->id, ctrl->val);
|
||||
break;
|
||||
@ -2155,6 +2193,28 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov5670_init_cfg(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state)
|
||||
{
|
||||
struct v4l2_mbus_framefmt *fmt =
|
||||
v4l2_subdev_get_try_format(sd, state, 0);
|
||||
const struct ov5670_mode *default_mode = &supported_modes[0];
|
||||
struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, state, 0);
|
||||
|
||||
fmt->width = default_mode->width;
|
||||
fmt->height = default_mode->height;
|
||||
fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
|
||||
fmt->field = V4L2_FIELD_NONE;
|
||||
fmt->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB);
|
||||
fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
|
||||
fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB);
|
||||
|
||||
*crop = *default_mode->analog_crop;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5670_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
@ -2404,6 +2464,49 @@ unlock_and_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused ov5670_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct ov5670 *ov5670 = to_ov5670(sd);
|
||||
unsigned long delay_us;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(ov5670->xvclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_bulk_enable(OV5670_NUM_SUPPLIES, ov5670->supplies);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(ov5670->xvclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(ov5670->pwdn_gpio, 0);
|
||||
gpiod_set_value_cansleep(ov5670->reset_gpio, 0);
|
||||
|
||||
/* 8192 * 2 clock pulses before the first SCCB transaction. */
|
||||
delay_us = DIV_ROUND_UP(8192 * 2 * 1000,
|
||||
DIV_ROUND_UP(OV5670_XVCLK_FREQ, 1000));
|
||||
fsleep(delay_us);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused ov5670_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct ov5670 *ov5670 = to_ov5670(sd);
|
||||
|
||||
gpiod_set_value_cansleep(ov5670->reset_gpio, 1);
|
||||
gpiod_set_value_cansleep(ov5670->pwdn_gpio, 1);
|
||||
regulator_bulk_disable(OV5670_NUM_SUPPLIES, ov5670->supplies);
|
||||
clk_disable_unprepare(ov5670->xvclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused ov5670_suspend(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
@ -2438,15 +2541,64 @@ static const struct v4l2_subdev_core_ops ov5670_core_ops = {
|
||||
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||||
};
|
||||
|
||||
static const struct v4l2_rect *
|
||||
__ov5670_get_pad_crop(struct ov5670 *sensor, struct v4l2_subdev_state *state,
|
||||
unsigned int pad, enum v4l2_subdev_format_whence which)
|
||||
{
|
||||
const struct ov5670_mode *mode = sensor->cur_mode;
|
||||
|
||||
switch (which) {
|
||||
case V4L2_SUBDEV_FORMAT_TRY:
|
||||
return v4l2_subdev_get_try_crop(&sensor->sd, state, pad);
|
||||
case V4L2_SUBDEV_FORMAT_ACTIVE:
|
||||
return mode->analog_crop;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ov5670_get_selection(struct v4l2_subdev *subdev,
|
||||
struct v4l2_subdev_state *state,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
struct ov5670 *sensor = to_ov5670(subdev);
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
mutex_lock(&sensor->mutex);
|
||||
sel->r = *__ov5670_get_pad_crop(sensor, state, sel->pad,
|
||||
sel->which);
|
||||
mutex_unlock(&sensor->mutex);
|
||||
break;
|
||||
case V4L2_SEL_TGT_NATIVE_SIZE:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.top = 0;
|
||||
sel->r.left = 0;
|
||||
sel->r.width = OV5670_NATIVE_WIDTH;
|
||||
sel->r.height = OV5670_NATIVE_HEIGHT;
|
||||
break;
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r = ov5670_analog_crop;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_video_ops ov5670_video_ops = {
|
||||
.s_stream = ov5670_set_stream,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_pad_ops ov5670_pad_ops = {
|
||||
.init_cfg = ov5670_init_cfg,
|
||||
.enum_mbus_code = ov5670_enum_mbus_code,
|
||||
.get_fmt = ov5670_get_pad_format,
|
||||
.set_fmt = ov5670_set_pad_format,
|
||||
.enum_frame_size = ov5670_enum_frame_size,
|
||||
.get_selection = ov5670_get_selection,
|
||||
.set_selection = ov5670_get_selection,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_sensor_ops ov5670_sensor_ops = {
|
||||
@ -2464,9 +2616,34 @@ static const struct media_entity_operations ov5670_subdev_entity_ops = {
|
||||
.link_validate = v4l2_subdev_link_validate,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_internal_ops ov5670_internal_ops = {
|
||||
.open = ov5670_open,
|
||||
};
|
||||
static int ov5670_regulators_probe(struct ov5670 *ov5670)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < OV5670_NUM_SUPPLIES; i++)
|
||||
ov5670->supplies[i].supply = ov5670_supply_names[i];
|
||||
|
||||
return devm_regulator_bulk_get(&client->dev, OV5670_NUM_SUPPLIES,
|
||||
ov5670->supplies);
|
||||
}
|
||||
|
||||
static int ov5670_gpio_probe(struct ov5670 *ov5670)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd);
|
||||
|
||||
ov5670->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ov5670->pwdn_gpio))
|
||||
return PTR_ERR(ov5670->pwdn_gpio);
|
||||
|
||||
ov5670->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(ov5670->reset_gpio))
|
||||
return PTR_ERR(ov5670->reset_gpio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5670_probe(struct i2c_client *client)
|
||||
{
|
||||
@ -2476,10 +2653,6 @@ static int ov5670_probe(struct i2c_client *client)
|
||||
bool full_power;
|
||||
int ret;
|
||||
|
||||
device_property_read_u32(&client->dev, "clock-frequency", &input_clk);
|
||||
if (input_clk != 19200000)
|
||||
return -EINVAL;
|
||||
|
||||
ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL);
|
||||
if (!ov5670) {
|
||||
ret = -ENOMEM;
|
||||
@ -2487,16 +2660,50 @@ static int ov5670_probe(struct i2c_client *client)
|
||||
goto error_print;
|
||||
}
|
||||
|
||||
ov5670->xvclk = devm_clk_get(&client->dev, NULL);
|
||||
if (!IS_ERR_OR_NULL(ov5670->xvclk))
|
||||
input_clk = clk_get_rate(ov5670->xvclk);
|
||||
else if (PTR_ERR(ov5670->xvclk) == -ENOENT)
|
||||
device_property_read_u32(&client->dev, "clock-frequency",
|
||||
&input_clk);
|
||||
else
|
||||
return dev_err_probe(&client->dev, PTR_ERR(ov5670->xvclk),
|
||||
"error getting clock\n");
|
||||
|
||||
if (input_clk != OV5670_XVCLK_FREQ) {
|
||||
dev_err(&client->dev,
|
||||
"Unsupported clock frequency %u\n", input_clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Initialize subdev */
|
||||
v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops);
|
||||
|
||||
ret = ov5670_regulators_probe(ov5670);
|
||||
if (ret) {
|
||||
err_msg = "Regulators probe failed";
|
||||
goto error_print;
|
||||
}
|
||||
|
||||
ret = ov5670_gpio_probe(ov5670);
|
||||
if (ret) {
|
||||
err_msg = "GPIO probe failed";
|
||||
goto error_print;
|
||||
}
|
||||
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
if (full_power) {
|
||||
ret = ov5670_runtime_resume(&client->dev);
|
||||
if (ret) {
|
||||
err_msg = "Power up failed";
|
||||
goto error_print;
|
||||
}
|
||||
|
||||
/* Check module identity */
|
||||
ret = ov5670_identify_module(ov5670);
|
||||
if (ret) {
|
||||
err_msg = "ov5670_identify_module() error";
|
||||
goto error_print;
|
||||
goto error_power_off;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2511,7 +2718,6 @@ static int ov5670_probe(struct i2c_client *client)
|
||||
goto error_mutex_destroy;
|
||||
}
|
||||
|
||||
ov5670->sd.internal_ops = &ov5670_internal_ops;
|
||||
ov5670->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
|
||||
V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
ov5670->sd.entity.ops = &ov5670_subdev_entity_ops;
|
||||
@ -2525,24 +2731,27 @@ static int ov5670_probe(struct i2c_client *client)
|
||||
goto error_handler_free;
|
||||
}
|
||||
|
||||
/* Async register for subdev */
|
||||
ret = v4l2_async_register_subdev_sensor(&ov5670->sd);
|
||||
if (ret < 0) {
|
||||
err_msg = "v4l2_async_register_subdev() error";
|
||||
goto error_entity_cleanup;
|
||||
}
|
||||
|
||||
ov5670->streaming = false;
|
||||
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
|
||||
/* Async register for subdev */
|
||||
ret = v4l2_async_register_subdev_sensor(&ov5670->sd);
|
||||
if (ret < 0) {
|
||||
err_msg = "v4l2_async_register_subdev() error";
|
||||
goto error_pm_disable;
|
||||
}
|
||||
|
||||
pm_runtime_idle(&client->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
error_entity_cleanup:
|
||||
error_pm_disable:
|
||||
pm_runtime_disable(&client->dev);
|
||||
|
||||
media_entity_cleanup(&ov5670->sd.entity);
|
||||
|
||||
error_handler_free:
|
||||
@ -2551,6 +2760,10 @@ error_handler_free:
|
||||
error_mutex_destroy:
|
||||
mutex_destroy(&ov5670->mutex);
|
||||
|
||||
error_power_off:
|
||||
if (full_power)
|
||||
ov5670_runtime_suspend(&client->dev);
|
||||
|
||||
error_print:
|
||||
dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret);
|
||||
|
||||
@ -2568,10 +2781,12 @@ static void ov5670_remove(struct i2c_client *client)
|
||||
mutex_destroy(&ov5670->mutex);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
ov5670_runtime_suspend(&client->dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ov5670_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(ov5670_suspend, ov5670_resume)
|
||||
SET_RUNTIME_PM_OPS(ov5670_runtime_suspend, ov5670_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
@ -2583,11 +2798,18 @@ static const struct acpi_device_id ov5670_acpi_ids[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, ov5670_acpi_ids);
|
||||
#endif
|
||||
|
||||
static const struct of_device_id ov5670_of_ids[] = {
|
||||
{ .compatible = "ovti,ov5670" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ov5670_of_ids);
|
||||
|
||||
static struct i2c_driver ov5670_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ov5670",
|
||||
.pm = &ov5670_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(ov5670_acpi_ids),
|
||||
.of_match_table = ov5670_of_ids,
|
||||
},
|
||||
.probe_new = ov5670_probe,
|
||||
.remove = ov5670_remove,
|
||||
|
@ -3,10 +3,14 @@
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
@ -17,7 +21,7 @@
|
||||
|
||||
#define OV5675_LINK_FREQ_450MHZ 450000000ULL
|
||||
#define OV5675_SCLK 90000000LL
|
||||
#define OV5675_MCLK 19200000
|
||||
#define OV5675_XVCLK_19_2 19200000
|
||||
#define OV5675_DATA_LANES 2
|
||||
#define OV5675_RGB_DEPTH 10
|
||||
|
||||
@ -76,6 +80,14 @@
|
||||
|
||||
#define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)
|
||||
|
||||
static const char * const ov5675_supply_names[] = {
|
||||
"avdd", /* Analog power */
|
||||
"dovdd", /* Digital I/O power */
|
||||
"dvdd", /* Digital core power */
|
||||
};
|
||||
|
||||
#define OV5675_NUM_SUPPLIES ARRAY_SIZE(ov5675_supply_names)
|
||||
|
||||
enum {
|
||||
OV5675_LINK_FREQ_900MBPS,
|
||||
};
|
||||
@ -484,6 +496,9 @@ struct ov5675 {
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct clk *xvclk;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct regulator_bulk_data supplies[OV5675_NUM_SUPPLIES];
|
||||
|
||||
/* V4L2 Controls */
|
||||
struct v4l2_ctrl *link_freq;
|
||||
@ -764,12 +779,14 @@ static const struct v4l2_ctrl_ops ov5675_ctrl_ops = {
|
||||
|
||||
static int ov5675_init_controls(struct ov5675 *ov5675)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
|
||||
struct v4l2_fwnode_device_properties props;
|
||||
struct v4l2_ctrl_handler *ctrl_hdlr;
|
||||
s64 exposure_max, h_blank;
|
||||
int ret;
|
||||
|
||||
ctrl_hdlr = &ov5675->ctrl_handler;
|
||||
ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
|
||||
ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -820,12 +837,28 @@ static int ov5675_init_controls(struct ov5675 *ov5675)
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
|
||||
if (ctrl_hdlr->error)
|
||||
if (ctrl_hdlr->error) {
|
||||
v4l2_ctrl_handler_free(ctrl_hdlr);
|
||||
return ctrl_hdlr->error;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_device_parse(&client->dev, &props);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &ov5675_ctrl_ops,
|
||||
&props);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ov5675->sd.ctrl_handler = ctrl_hdlr;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
v4l2_ctrl_handler_free(ctrl_hdlr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ov5675_update_pad_format(const struct ov5675_mode *mode,
|
||||
@ -944,6 +977,56 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov5675_power_off(struct device *dev)
|
||||
{
|
||||
/* 512 xvclk cycles after the last SCCB transation or MIPI frame end */
|
||||
u32 delay_us = DIV_ROUND_UP(512, OV5675_XVCLK_19_2 / 1000 / 1000);
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov5675 *ov5675 = to_ov5675(sd);
|
||||
|
||||
usleep_range(delay_us, delay_us * 2);
|
||||
|
||||
clk_disable_unprepare(ov5675->xvclk);
|
||||
gpiod_set_value_cansleep(ov5675->reset_gpio, 1);
|
||||
regulator_bulk_disable(OV5675_NUM_SUPPLIES, ov5675->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5675_power_on(struct device *dev)
|
||||
{
|
||||
u32 delay_us = DIV_ROUND_UP(8192, OV5675_XVCLK_19_2 / 1000 / 1000);
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov5675 *ov5675 = to_ov5675(sd);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(ov5675->xvclk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable xvclk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(ov5675->reset_gpio, 1);
|
||||
|
||||
ret = regulator_bulk_enable(OV5675_NUM_SUPPLIES, ov5675->supplies);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(ov5675->xvclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset pulse should be at least 2ms and reset gpio released only once
|
||||
* regulators are stable.
|
||||
*/
|
||||
usleep_range(2000, 2200);
|
||||
|
||||
gpiod_set_value_cansleep(ov5675->reset_gpio, 0);
|
||||
|
||||
/* 8192 xvclk cycles prior to the first SCCB transation */
|
||||
usleep_range(delay_us, delay_us * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused ov5675_suspend(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
@ -1040,6 +1123,31 @@ static int ov5675_get_format(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5675_get_selection(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *state,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
|
||||
return -EINVAL;
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.top = 0;
|
||||
sel->r.left = 0;
|
||||
sel->r.width = 2624;
|
||||
sel->r.height = 2000;
|
||||
return 0;
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.top = 16;
|
||||
sel->r.left = 16;
|
||||
sel->r.width = 2592;
|
||||
sel->r.height = 1944;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ov5675_enum_mbus_code(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_mbus_code_enum *code)
|
||||
@ -1089,6 +1197,7 @@ static const struct v4l2_subdev_video_ops ov5675_video_ops = {
|
||||
static const struct v4l2_subdev_pad_ops ov5675_pad_ops = {
|
||||
.set_fmt = ov5675_set_format,
|
||||
.get_fmt = ov5675_get_format,
|
||||
.get_selection = ov5675_get_selection,
|
||||
.enum_mbus_code = ov5675_enum_mbus_code,
|
||||
.enum_frame_size = ov5675_enum_frame_size,
|
||||
};
|
||||
@ -1106,31 +1215,59 @@ static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
|
||||
.open = ov5675_open,
|
||||
};
|
||||
|
||||
static int ov5675_check_hwcfg(struct device *dev)
|
||||
static int ov5675_get_hwcfg(struct ov5675 *ov5675, struct device *dev)
|
||||
{
|
||||
struct fwnode_handle *ep;
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
struct v4l2_fwnode_endpoint bus_cfg = {
|
||||
.bus_type = V4L2_MBUS_CSI2_DPHY
|
||||
};
|
||||
u32 mclk;
|
||||
u32 xvclk_rate;
|
||||
int ret;
|
||||
unsigned int i, j;
|
||||
|
||||
if (!fwnode)
|
||||
return -ENXIO;
|
||||
|
||||
ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
|
||||
ov5675->xvclk = devm_clk_get_optional(dev, NULL);
|
||||
if (IS_ERR(ov5675->xvclk))
|
||||
return dev_err_probe(dev, PTR_ERR(ov5675->xvclk),
|
||||
"failed to get xvclk: %ld\n",
|
||||
PTR_ERR(ov5675->xvclk));
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency");
|
||||
if (ov5675->xvclk) {
|
||||
xvclk_rate = clk_get_rate(ov5675->xvclk);
|
||||
} else {
|
||||
ret = fwnode_property_read_u32(fwnode, "clock-frequency",
|
||||
&xvclk_rate);
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "can't get clock frequency");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (xvclk_rate != OV5675_XVCLK_19_2) {
|
||||
dev_err(dev, "external clock rate %u is unsupported",
|
||||
xvclk_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ov5675->reset_gpio = devm_gpiod_get_optional(dev, "reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ov5675->reset_gpio)) {
|
||||
ret = PTR_ERR(ov5675->reset_gpio);
|
||||
dev_err(dev, "failed to get reset-gpios: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mclk != OV5675_MCLK) {
|
||||
dev_err(dev, "external clock %d is not supported", mclk);
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < OV5675_NUM_SUPPLIES; i++)
|
||||
ov5675->supplies[i].supply = ov5675_supply_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(dev, OV5675_NUM_SUPPLIES,
|
||||
ov5675->supplies);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
|
||||
if (!ep)
|
||||
@ -1185,6 +1322,10 @@ static void ov5675_remove(struct i2c_client *client)
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
pm_runtime_disable(&client->dev);
|
||||
mutex_destroy(&ov5675->mutex);
|
||||
|
||||
if (!pm_runtime_status_suspended(&client->dev))
|
||||
ov5675_power_off(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
}
|
||||
|
||||
static int ov5675_probe(struct i2c_client *client)
|
||||
@ -1193,25 +1334,31 @@ static int ov5675_probe(struct i2c_client *client)
|
||||
bool full_power;
|
||||
int ret;
|
||||
|
||||
ret = ov5675_check_hwcfg(&client->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to check HW configuration: %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ov5675 = devm_kzalloc(&client->dev, sizeof(*ov5675), GFP_KERNEL);
|
||||
if (!ov5675)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = ov5675_get_hwcfg(ov5675, &client->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to get HW configuration: %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
|
||||
|
||||
ret = ov5675_power_on(&client->dev);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to power on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
full_power = acpi_dev_state_d0(&client->dev);
|
||||
if (full_power) {
|
||||
ret = ov5675_identify_module(ov5675);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to find sensor: %d", ret);
|
||||
return ret;
|
||||
goto probe_power_off;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1241,11 +1388,6 @@ static int ov5675_probe(struct i2c_client *client)
|
||||
goto probe_error_media_entity_cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Device is already turned on by i2c-core with ACPI domain PM.
|
||||
* Enable runtime PM and turn off the device.
|
||||
*/
|
||||
|
||||
/* Set the device's state to active if it's in D0 state. */
|
||||
if (full_power)
|
||||
pm_runtime_set_active(&client->dev);
|
||||
@ -1260,12 +1402,15 @@ probe_error_media_entity_cleanup:
|
||||
probe_error_v4l2_ctrl_handler_free:
|
||||
v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler);
|
||||
mutex_destroy(&ov5675->mutex);
|
||||
probe_power_off:
|
||||
ov5675_power_off(&client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ov5675_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume)
|
||||
SET_RUNTIME_PM_OPS(ov5675_power_off, ov5675_power_on, NULL)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
@ -1277,11 +1422,18 @@ static const struct acpi_device_id ov5675_acpi_ids[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, ov5675_acpi_ids);
|
||||
#endif
|
||||
|
||||
static const struct of_device_id ov5675_of_match[] = {
|
||||
{ .compatible = "ovti,ov5675", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ov5675_of_match);
|
||||
|
||||
static struct i2c_driver ov5675_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ov5675",
|
||||
.pm = &ov5675_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(ov5675_acpi_ids),
|
||||
.of_match_table = ov5675_of_match,
|
||||
},
|
||||
.probe_new = ov5675_probe,
|
||||
.remove = ov5675_remove,
|
||||
|
@ -1840,16 +1840,16 @@ static int ov7670_parse_dt(struct device *dev,
|
||||
|
||||
if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) {
|
||||
dev_err(dev, "Unsupported media bus type\n");
|
||||
return ret;
|
||||
return -EINVAL;
|
||||
}
|
||||
info->mbus_config = bus_cfg.bus.parallel.flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov7670_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int ov7670_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(client);
|
||||
struct v4l2_fract tpf;
|
||||
struct v4l2_subdev *sd;
|
||||
struct ov7670_info *info;
|
||||
@ -2038,7 +2038,7 @@ static struct i2c_driver ov7670_driver = {
|
||||
.name = "ov7670",
|
||||
.of_match_table = of_match_ptr(ov7670_of_match),
|
||||
},
|
||||
.probe = ov7670_probe,
|
||||
.probe_new = ov7670_probe,
|
||||
.remove = ov7670_remove,
|
||||
.id_table = ov7670_id,
|
||||
};
|
||||
|
@ -1462,7 +1462,7 @@ static int ov772x_probe(struct i2c_client *client)
|
||||
priv->subdev.ctrl_handler = &priv->hdl;
|
||||
if (priv->hdl.error) {
|
||||
ret = priv->hdl.error;
|
||||
goto error_mutex_destroy;
|
||||
goto error_ctrl_free;
|
||||
}
|
||||
|
||||
priv->clk = clk_get(&client->dev, NULL);
|
||||
@ -1515,7 +1515,6 @@ error_clk_put:
|
||||
clk_put(priv->clk);
|
||||
error_ctrl_free:
|
||||
v4l2_ctrl_handler_free(&priv->hdl);
|
||||
error_mutex_destroy:
|
||||
mutex_destroy(&priv->lock);
|
||||
|
||||
return ret;
|
||||
|
2008
drivers/media/i2c/ov8858.c
Normal file
2008
drivers/media/i2c/ov8858.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -148,7 +148,6 @@ struct ov9282_mode {
|
||||
/**
|
||||
* struct ov9282 - ov9282 sensor device structure
|
||||
* @dev: Pointer to generic device
|
||||
* @client: Pointer to i2c client
|
||||
* @sd: V4L2 sub-device
|
||||
* @pad: Media pad. Only one pad supported
|
||||
* @reset_gpio: Sensor reset gpio
|
||||
@ -170,7 +169,6 @@ struct ov9282_mode {
|
||||
*/
|
||||
struct ov9282 {
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct gpio_desc *reset_gpio;
|
||||
@ -1144,10 +1142,9 @@ static int ov9282_parse_hw_config(struct ov9282 *ov9282)
|
||||
}
|
||||
|
||||
ret = ov9282_configure_regulators(ov9282);
|
||||
if (ret) {
|
||||
dev_err(ov9282->dev, "Failed to get power regulators\n");
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return dev_err_probe(ov9282->dev, ret,
|
||||
"Failed to get power regulators\n");
|
||||
|
||||
rate = clk_get_rate(ov9282->inclk);
|
||||
if (rate != OV9282_INCLK_RATE) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/i2c/s5c73m3.h>
|
||||
#include <media/v4l2-fwnode.h>
|
||||
|
||||
#include "s5c73m3.h"
|
||||
@ -436,7 +435,7 @@ static int __s5c73m3_s_stream(struct s5c73m3 *state, struct v4l2_subdev *sd,
|
||||
state->streaming = !!on;
|
||||
|
||||
if (!on)
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
if (state->apply_fiv) {
|
||||
ret = s5c73m3_set_frame_rate(state);
|
||||
@ -1522,25 +1521,16 @@ static const struct v4l2_subdev_ops oif_subdev_ops = {
|
||||
.video = &s5c73m3_oif_video_ops,
|
||||
};
|
||||
|
||||
static int s5c73m3_get_platform_data(struct s5c73m3 *state)
|
||||
static int s5c73m3_get_dt_data(struct s5c73m3 *state)
|
||||
{
|
||||
struct i2c_client *c = state->i2c_client;
|
||||
struct device *dev = &c->dev;
|
||||
const struct s5c73m3_platform_data *pdata = dev->platform_data;
|
||||
struct device *dev = &state->i2c_client->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *node_ep;
|
||||
struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
|
||||
int ret;
|
||||
|
||||
if (!node) {
|
||||
if (!pdata) {
|
||||
dev_err(dev, "Platform data not specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
state->mclk_frequency = pdata->mclk_frequency;
|
||||
return 0;
|
||||
}
|
||||
if (!node)
|
||||
return -EINVAL;
|
||||
|
||||
state->clock = devm_clk_get(dev, S5C73M3_CLK_NAME);
|
||||
if (IS_ERR(state->clock))
|
||||
@ -1603,7 +1593,7 @@ static int s5c73m3_probe(struct i2c_client *client)
|
||||
return -ENOMEM;
|
||||
|
||||
state->i2c_client = client;
|
||||
ret = s5c73m3_get_platform_data(state);
|
||||
ret = s5c73m3_get_dt_data(state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-subdev.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/i2c/s5c73m3.h>
|
||||
|
||||
#include "s5c73m3.h"
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user