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:
Linus Torvalds 2023-02-26 11:47:26 -08:00
commit 4b8c673b76
341 changed files with 11051 additions and 26859 deletions

View file

@ -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'

View file

@ -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>;

View file

@ -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.

View file

@ -13,4 +13,3 @@ Digital TV driver-specific documentation
opera-firmware
technisat
ttusb-dec
zr364xx

View file

@ -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.

View file

@ -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
================ ====================================== =====================

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -11,14 +11,12 @@ Video4Linux (V4L) driver-specific documentation
bttv
cafe_ccic
cpia2
cx88
fimc
imx
imx7
ipu3
ivtv
meye
omap3isp
omap4_camera
philips

View file

@ -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
====== ======= ============== ====================

View file

@ -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>;
};

View file

@ -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.

View file

@ -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:
- |

View 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

View 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>;
};

View file

@ -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>;
};

View 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/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>;
};

View 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>;
};

View file

@ -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";
};
...

View 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>;
};

View file

@ -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>;
};

View file

@ -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

View file

@ -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>;
};
};
...

View file

@ -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>;

View file

@ -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 {

View 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;
};
};
};
};
...

View 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>;
};
};
};
};
...

View 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>;
};
};
};
};
...

View 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>;
};
};
};
};
...

View 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>;
};
};
};
};
...

View file

@ -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>

View file

@ -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>;
};

View file

@ -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>;
};

View file

@ -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";
};

View file

@ -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.

View file

@ -13,7 +13,6 @@ Video4Linux (V4L) drivers
:maxdepth: 5
bttv-devel
cpia2_devel
cx2341x-devel
cx88-devel
fimc-devel

View file

@ -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.

View file

@ -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
---------------------------------------------

View file

@ -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:

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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/>`__

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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"

View file

@ -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)

View file

@ -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;

View file

@ -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 */

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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,

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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

View file

@ -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

View file

@ -1393,9 +1393,9 @@ static int init_device(struct adv7180_state *state)
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,
};

View file

@ -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,
};

View file

@ -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) {

View file

@ -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,
};

View file

@ -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

File diff suppressed because it is too large Load diff

1300
drivers/media/i2c/imx415.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -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,
};

View file

@ -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 @@ static int max9286_i2c_mux_init(struct max9286_priv *priv)
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;
}

View file

@ -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,
};

View file

@ -1102,9 +1102,9 @@ mt9p031_get_pdata(struct i2c_client *client)
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,
};

View file

@ -1044,9 +1044,9 @@ mt9v032_get_pdata(struct i2c_client *client)
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,
};

View file

@ -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;

View file

@ -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 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
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;

View file

@ -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 @@ static int ov5670_init_controls(struct ov5670 *ov5670)
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 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable)
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 @@ static int ov5670_probe(struct i2c_client *client)
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,

View file

@ -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 @@ static int ov5675_probe(struct i2c_client *client)
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,

View file

@ -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,
};

View file

@ -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 @@ static int ov772x_probe(struct i2c_client *client)
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

File diff suppressed because it is too large Load diff

View file

@ -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) {

View file

@ -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;

View file

@ -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